Skip to content

feat: sdk v2 #266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 0 commits into from
Sep 24, 2024
Merged

feat: sdk v2 #266

merged 0 commits into from
Sep 24, 2024

Conversation

ponderingdemocritus
Copy link
Contributor

@ponderingdemocritus ponderingdemocritus commented Sep 2, 2024

WIP

still todo:

  • execution client with typed endpoints
  • implement other wrappers of the ToriiClient
  • testing
  • practical example

Attempts to implement a typed query lang ontop of torii client. Very experimental. Discussion needed.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced a client interface for robust interactions with the Dojo Engine's Torii client.
    • Added functionality for subscribing to real-time updates on entities and events, including player positions and moves.
    • Enhanced querying capabilities with new functions for converting queries and managing entity keys.
    • Implemented comprehensive type definitions to improve type safety within the SDK.
    • Established a foundational structure for managing game-related entities and data.
    • Added documentation for SDK initialization, usage, and examples for subscribing to entity updates.
    • Introduced a new configuration file for setting up the Dojo application.
    • Added a new enumeration for movement directions to standardize representation.
  • Bug Fixes

    • Streamlined movement logic for button interactions to improve clarity and maintainability.
  • Chores

    • Improved development setup with TypeScript and bundler configuration files.
    • Updated dependencies in the project configuration to enhance documentation generation tools.

@ponderingdemocritus ponderingdemocritus changed the title feat: init feat: sdk v2 Sep 2, 2024
Copy link

coderabbitai bot commented Sep 2, 2024

Walkthrough

The recent changes introduce several enhancements to the Dojo Engine SDK, focusing on improved management of game-related entities and real-time updates. Key updates include the introduction of a new enumeration for movement directions, a React component for connecting to a Dojo Engine database, and the establishment of TypeScript interfaces for structured data handling. These modifications enhance the SDK's capabilities for real-time data management and entity subscriptions, creating a more robust framework for game state management.

Changes

Files Change Summary
clients/react/react-app/src/App.tsx Introduced DirectionEnum for movement actions, improving code clarity and maintainability.
clients/react/react-app/src/dojo/createSystemCalls.ts Simplified direction handling in createSystemCalls, enhancing clarity.
clients/react/react-app/src/dojo/DojoContext.tsx Minor reorganization of import statements for clarity.
clients/react/react-app/src/main.tsx Reordered import statements for better readability.
clients/react/react-sdk/src/App.tsx New component for managing game entities and real-time updates.
clients/react/react-sdk/src/bindings.ts Introduced TypeScript interfaces and enums for managing game-related data.
clients/vue/vue-app/dojoConfig.ts New configuration file for setting up Dojo resources.
examples/example-nodejs-bot/dojoConfig.ts Updated import path for the manifest JSON file.
examples/example-vite-react-app-recs/dojoConfig.ts Updated import path for the manifest JSON file.
examples/example-vite-react-sdk/dojoConfig.ts Updated import path for the manifest JSON file.
examples/example-vite-react-threejs-recs/dojoConfig.ts New configuration file for Dojo setup.
examples/example-vue-app-recs/dojoConfig.ts New configuration file for Dojo setup.
package.json Updated dependencies related to TypeScript documentation generation.

Possibly related PRs

  • fix: sync #264: The modifications in the main PR regarding the structure of movement commands are related to the changes in the App.tsx file of this PR, which also updates how movement directions are passed to the move function, reflecting a similar shift in data structure.
  • fix: utils - change way to compute selector hash #250: This PR simplifies the move function by directly passing the direction parameter, which relates to the main PR's focus on enhancing clarity and maintainability in movement logic.
  • feat: add vanillajs + phaser example #249: The introduction of a new example that demonstrates character movement aligns with the main PR's changes to movement direction handling, indicating a shared focus on improving movement functionality.
  • fix: docs and example #231: The removal of a console log statement related to directions in the App.tsx file suggests a connection to the main PR's efforts to enhance code clarity and maintainability regarding movement direction handling.

Poem

🐇 In the meadow of code, we leap and bound,
With new tools and features, joy can be found.
Real-time updates dance in the light,
Game states evolving, oh what a sight!
Let's hop with delight, for changes are here,
In our coding adventure, we have nothing to fear! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    -- I pushed a fix in commit <commit_id>, please review it.
    -- Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    -- @coderabbitai generate unit testing code for this file.
    -- @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    -- @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    -- @coderabbitai read src/utils.ts and generate unit testing code.
    -- @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    -- @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Outside diff range, codebase verification and nitpick comments (6)
packages/sdk/src/convertQueryToClauses.ts (1)

1-42: LGTM! The function correctly converts the query to clauses.

The code changes are approved with some suggestions for improvement:

  1. Consider adding JSDoc comments to describe the purpose and behavior of the function.
  2. Consider adding type checks or type guards to ensure that the input object and its properties have the expected types.
  3. Consider extracting the logic for constructing torii.EntityKeysClause objects into separate functions to improve readability and maintainability.
  4. Consider adding unit tests to verify the behavior of the function with different input scenarios.
packages/sdk/src/convertQuerytoClause.ts (2)

10-10: Consider adding type safety for the conditions object.

To improve type safety, you can define a type for the conditions object based on the generic type parameter T. This will ensure that the conditions object has the expected structure and properties.

-if (conditions && typeof conditions === "object") {
+if (conditions && isValidConditions<T>(conditions)) {

Then, define the isValidConditions type guard function:

function isValidConditions<T extends SchemaType>(
  conditions: any
): conditions is Partial<Record<keyof T, string | undefined>> {
  return (
    typeof conditions === "object" &&
    Object.values(conditions).every(
      (value) => typeof value === "string" || value === undefined
    )
  );
}

4-47: Handle potential errors or edge cases.

Consider adding error handling or validation to cover potential edge cases or unexpected input. For example:

  • Validate that the query object has at least one property.
  • Handle the case when query is an empty object.
  • Ensure that the model and key values are valid and exist in the schema.

You can add validation checks at the beginning of the function:

if (Object.keys(query).length === 0) {
  throw new Error("Query object cannot be empty");
}

And add validation for model and key values:

if (!isValidModel(model)) {
  throw new Error(`Invalid model: ${model}`);
}

if (!isValidKey(key)) {
  throw new Error(`Invalid key: ${key}`);
}

Define the isValidModel and isValidKey functions based on your schema validation logic.

packages/sdk/src/index.ts (3)

12-39: Consider simplifying the init function.

The init function is the main entry point of the SDK and sets up the client and returns an object with methods to interact with the data. The implementation looks good, but there are a few areas that could be improved:

  1. The torii.ClientConfig object is created by manually assigning the properties from the options object. This could be simplified by using the spread operator.
  2. The subscribeQuery and getEntities functions are called with the client as the first argument. This could be simplified by using the bind method to partially apply the client argument.

Here's a suggested refactoring:

-    const config: torii.ClientConfig = {
-        rpcUrl: options.rpcUrl,
-        toriiUrl: options.toriiUrl,
-        relayUrl: options.relayUrl,
-        worldAddress: options.worldAddress,
-    };
+    const config: torii.ClientConfig = { ...options };

     const client = await createClient(config);

     return {
         client,
-        subscribeQuery: (query, callback) =>
-            subscribeQuery(client, query, callback),
-        getEntities: (query) => getEntities(client, query),
+        subscribeQuery: subscribeQuery.bind(null, client),
+        getEntities: getEntities.bind(null, client),
     };

43-108: Consider moving the example usage to a separate file or directory.

The example schema and usage provide a good starting point for users of the SDK to understand how to use it. The implementation looks good, but there are a few areas that could be improved:

  1. The example usage could be moved to a separate file or directory, such as examples/, to keep the main file focused on the SDK implementation.
  2. The example usage could be expanded to cover more use cases and edge cases, such as error handling and unsubscribing from subscriptions.

64-67: Consider more robust error handling in a real-world application.

The error handling in the example usage is sufficient for demonstration purposes. However, in a real-world application, more robust error handling would be needed, such as:

  1. Retrying failed requests with exponential backoff.
  2. Logging errors to a centralized error tracking system.
  3. Displaying user-friendly error messages to the end user.

Also applies to: 75-78, 86-92, 102-104

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between c656e95 and 65cf745.

Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
Files selected for processing (13)
  • packages/sdk/.gitignore (1 hunks)
  • packages/sdk/.npmignore (1 hunks)
  • packages/sdk/CHANGELOG.md (1 hunks)
  • packages/sdk/package.json (1 hunks)
  • packages/sdk/src/tests/client.test.ts (1 hunks)
  • packages/sdk/src/convertQueryToClauses.ts (1 hunks)
  • packages/sdk/src/convertQuerytoClause.ts (1 hunks)
  • packages/sdk/src/getEntities.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/subscribeQuery.ts (1 hunks)
  • packages/sdk/src/types.ts (1 hunks)
  • packages/sdk/tsconfig.json (1 hunks)
  • packages/sdk/tsup.config.ts (1 hunks)
Files skipped from review due to trivial changes (4)
  • packages/sdk/.gitignore
  • packages/sdk/.npmignore
  • packages/sdk/tsconfig.json
  • packages/sdk/tsup.config.ts
Additional context used
Biome
packages/sdk/src/types.ts

[error] 1-1: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)

Markdownlint
packages/sdk/CHANGELOG.md

63-63: Expected: h2; Actual: h3
Heading levels should only increment by one level at a time

(MD001, heading-increment)


85-85: Expected: h2; Actual: h3
Heading levels should only increment by one level at a time

(MD001, heading-increment)


82-82: null
Multiple headings with the same content

(MD024, no-duplicate-heading)

Additional comments not posted (9)
packages/sdk/src/types.ts (1)

1-1: Use a type alias instead of an empty interface or add properties.

The SchemaType interface is empty, which is equivalent to {} and doesn't provide any type safety.

If the interface is intended to be empty, use a type alias instead:

-export interface SchemaType {}
+export type SchemaType = {};

Is the empty interface a placeholder for future properties? If yes, consider adding a TODO comment to indicate the planned properties.

Tools
Biome

[error] 1-1: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)

packages/sdk/src/subscribeQuery.ts (1)

1-21: LGTM!

The subscribeQuery function is well-implemented and follows best practices:

  • It uses generics to provide type safety for the query object and the schema type.
  • It separates the conversion of the query object to clauses into a separate utility function, promoting modularity and separation of concerns.
  • It subscribes to entity updates using the Torii client's onEntityUpdated method and invokes the provided callback with the updated entities and data.
  • It returns the subscription object, allowing the caller to manage the subscription lifecycle.

The code changes are approved.

packages/sdk/src/getEntities.ts (1)

1-23: LGTM!

The code changes are approved. The function is correctly implemented and uses the Torii client to get entities. The function signature and return type are correctly defined. The function uses default values for limit and offset, which is a good practice. The function uses generic types to allow it to be used with any schema type and any subset of the schema type's keys.

packages/sdk/package.json (1)

1-37: LGTM!

The package.json file for the new @dojoengine/utils SDK package looks good:

  • The package metadata (name, version, description, author, license) is specified correctly.
  • The main entry point and exports are defined.
  • The dependencies and devDependencies are specified.
  • The build and test scripts are defined.

The code changes are approved.

packages/sdk/src/convertQuerytoClause.ts (1)

4-47: Overall, the implementation looks good!

The function convertQueryToClause is well-structured and follows a clear logic flow. It effectively converts a query object to a Torii clause based on the provided conditions.

packages/sdk/src/__tests__/client.test.ts (2)

21-30: LGTM!

The test case correctly verifies the behavior of the init function by checking if the createClient function is called with the correct options and if the returned client is the same as the mocked client.


32-51: LGTM!

The test case correctly verifies the behavior of the subscribeQuery function by checking if the onEntityUpdated function is called, if the callback is called with the correct data, and if the returned subscription is the same as the mock subscription.

packages/sdk/src/index.ts (2)

1-5: LGTM!

The import statements and type definitions are correctly set up.


6-10: LGTM!

The createClient function is a simple wrapper around the torii.createClient function. The implementation looks good.

# [0.6.0-alpha.0](https://github.com/dojoengine/dojo.js/compare/v0.5.9...v0.6.0-alpha.0) (2024-03-07)


### Bug Fixes
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix heading levels to maintain consistency.

Markdownlint has flagged the following issues:

  • Line 63: Expected: h2; Actual: h3
  • Line 85: Expected: h2; Actual: h3

Heading levels should only increment by one level at a time to maintain a consistent and readable structure.

To fix this, adjust the heading levels to increment by one level at a time:

-### Bug Fixes
+## Bug Fixes

Also applies to: 85-85

Tools
Markdownlint

63-63: Expected: h2; Actual: h3
Heading levels should only increment by one level at a time

(MD001, heading-increment)




# [0.6.0-alpha.0](https://github.com/dojoengine/dojo.js/compare/v0.5.9...v0.6.0-alpha.0) (2024-03-07)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove or rename duplicate heading.

Markdownlint has flagged that there are multiple headings with the same content:

  • Line 82: # [0.6.0-alpha.0](https://github.com/dojoengine/dojo.js/compare/v0.5.9...v0.6.0-alpha.0) (2024-03-07)

Having duplicate headings can be confusing for readers.

To fix this, either remove the duplicate heading if it's not needed, or rename it to be unique:

-# [0.6.0-alpha.0](https://github.com/dojoengine/dojo.js/compare/v0.5.9...v0.6.0-alpha.0) (2024-03-07)
+# [0.6.0-alpha.0-duplicate](https://github.com/dojoengine/dojo.js/compare/v0.5.9...v0.6.0-alpha.0) (2024-03-07)

Committable suggestion was skipped due to low confidence.

Tools
Markdownlint

82-82: null
Multiple headings with the same content

(MD024, no-duplicate-heading)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 65cf745 and 63d297c.

Files ignored due to path filters (1)
  • packages/create-dojo/bin/index.js.map is excluded by !**/*.map
Files selected for processing (3)
  • packages/create-dojo/bin/index.js (2 hunks)
  • packages/sdk/src/getEntities.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
Files skipped from review due to trivial changes (1)
  • packages/create-dojo/bin/index.js
Files skipped from review as they are similar to previous changes (1)
  • packages/sdk/src/index.ts
Additional context used
Biome
packages/sdk/src/getEntities.ts

[error] 33-33: The catch clause that only rethrows the original error is redundant.

These unnecessary catch clauses can be confusing. It is recommended to remove them.

(lint/complexity/noUselessCatch)

Additional comments not posted (3)
packages/sdk/src/getEntities.ts (3)

5-15: LGTM!

The function signature and parameters are well-defined, providing flexibility and type safety.


16-34: LGTM!

The function body is well-structured and follows a clear sequence of steps to retrieve entities based on the provided query.

Tools
Biome

[error] 33-33: The catch clause that only rethrows the original error is redundant.

These unnecessary catch clauses can be confusing. It is recommended to remove them.

(lint/complexity/noUselessCatch)


1-1: LGTM!

The usage of the convertQueryToClause utility function is appropriate and promotes code reusability and maintainability.

Also applies to: 16-16

Comment on lines 32 to 84
} catch (error) {
throw error;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the redundant catch clause.

The catch clause on line 33 that only rethrows the original error is redundant and can be confusing. It is recommended to remove it.

Apply this diff to remove the redundant catch clause:

-    } catch (error) {
-        throw error;
-    }
+    }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (error) {
throw error;
}
}
Tools
Biome

[error] 33-33: The catch clause that only rethrows the original error is redundant.

These unnecessary catch clauses can be confusing. It is recommended to remove them.

(lint/complexity/noUselessCatch)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 63d297c and 5b0170a.

Files selected for processing (6)
  • packages/sdk/src/tests/convertQueryToClause.test.ts (1 hunks)
  • packages/sdk/src/tests/convertQueryToClauses.test.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/state/src/tests/zustand.test.ts (1 hunks)
  • packages/state/src/index.ts (1 hunks)
  • packages/state/src/zustand/index.ts (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • packages/sdk/src/index.ts
Additional comments not posted (14)
packages/state/src/__tests__/zustand.test.ts (5)

21-27: LGTM!

The test case is correctly testing the set and get methods of the store.


29-33: LGTM!

The test case is correctly testing that setting a value in the store does not affect other properties.


35-40: LGTM!

The test case is correctly testing that the getState method returns the current state of the store.


42-47: LGTM!

The test case is correctly testing that the setState method updates the state of the store.


49-62: LGTM!

The test case is correctly testing that the subscribe method subscribes to state changes and the unsubscribe method unsubscribes from state changes.

packages/sdk/src/__tests__/convertQueryToClauses.test.ts (4)

7-31: LGTM!

The test case is well-structured and covers a valid scenario. The expected output is correctly defined.


33-57: LGTM!

The test case is well-structured and covers a valid scenario. The expected output is correctly defined.


59-77: LGTM!

The test case is well-structured and covers a valid scenario. The expected output is correctly defined.


79-85: LGTM!

The test case is well-structured and covers a valid scenario. The expected output is correctly defined.

packages/sdk/src/__tests__/convertQueryToClause.test.ts (5)

5-19: LGTM!

The test case is well-written and covers the expected behavior of the convertQueryToClause function for a single model query with conditions.


21-35: LGTM!

The test case is well-written and covers the expected behavior of the convertQueryToClause function for a single model query without conditions.


37-66: LGTM!

The test case is well-written and covers the expected behavior of the convertQueryToClause function for multiple model queries.


68-105: LGTM!

The test case is well-written and covers the expected behavior of the convertQueryToClause function for mixed queries with and without conditions.


107-118: LGTM!

The test case is well-written and covers the expected behavior of the convertQueryToClause function for an empty query.

Comment on lines 3 to 17
export const createTypedStore = <T extends object>() => {
return create<
T & {
set: <K extends keyof T>(key: K, value: T[K]) => void;
get: <K extends keyof T>(key: K) => T[K];
}
>(
(set, get) =>
({
set: <K extends keyof T>(key: K, value: T[K]) =>
set((state) => ({ ...state, [key]: value }) as T),
get: <K extends keyof T>(key: K) => get()[key],
}) as T & { set: any; get: any }
);
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve the implementation of the createTypedStore function.

Consider the following suggestions:

  1. Use Zustand's setState function in the set method for better performance.
  2. Remove the get method as it's redundant. The store already provides a getState method to retrieve the current state.
  3. Fix the return type of the function. The set and get methods should not be part of the store type.

Apply this diff to implement the suggestions:

-export const createTypedStore = <T extends object>() => {
+export const createTypedStore = <T extends object>(): T => {
     return create<
         T & {
-            set: <K extends keyof T>(key: K, value: T[K]) => void;
-            get: <K extends keyof T>(key: K) => T[K];
+            set: (partial: Partial<T>) => void;
         }
     >(
-        (set, get) =>
+        (set) =>
             ({
-                set: <K extends keyof T>(key: K, value: T[K]) =>
-                    set((state) => ({ ...state, [key]: value }) as T),
-                get: <K extends keyof T>(key: K) => get()[key],
-            }) as T & { set: any; get: any }
+                set: (partial: Partial<T>) => set(partial),
+            }) as T & { set: (partial: Partial<T>) => void }
     );
 };
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const createTypedStore = <T extends object>() => {
return create<
T & {
set: <K extends keyof T>(key: K, value: T[K]) => void;
get: <K extends keyof T>(key: K) => T[K];
}
>(
(set, get) =>
({
set: <K extends keyof T>(key: K, value: T[K]) =>
set((state) => ({ ...state, [key]: value }) as T),
get: <K extends keyof T>(key: K) => get()[key],
}) as T & { set: any; get: any }
);
};
export const createTypedStore = <T extends object>(): T => {
return create<
T & {
set: (partial: Partial<T>) => void;
}
>(
(set) =>
({
set: (partial: Partial<T>) => set(partial),
}) as T & { set: (partial: Partial<T>) => void }
);
};

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 5b0170a and 71d62ea.

Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
Files selected for processing (1)
  • packages/sdk/package.json (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • packages/sdk/package.json

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 71d62ea and c8eef83.

Files selected for processing (3)
  • packages/sdk/src/getEntities.ts (1 hunks)
  • packages/sdk/src/subscribeQuery.ts (1 hunks)
  • packages/torii-client/src/index.ts (1 hunks)
Files skipped from review due to trivial changes (1)
  • packages/torii-client/src/index.ts
Additional context used
Biome
packages/sdk/src/getEntities.ts

[error] 40-40: The catch clause that only rethrows the original error is redundant.

These unnecessary catch clauses can be confusing. It is recommended to remove them.

(lint/complexity/noUselessCatch)

Additional comments not posted (2)
packages/sdk/src/subscribeQuery.ts (1)

1-17: LGTM!

The subscribeQuery function is well-implemented and follows best practices:

  • The function uses appropriate type annotations to ensure type safety.
  • The function handles errors by passing them to the callback function.
  • The function uses object destructuring to extract the relevant data from the response.
  • The function uses a computed property name to dynamically set the key of the response object.

Some additional insights:

  • The function leverages the convertQueryToClauses function to convert the query object to clauses, which is a good separation of concerns.
  • The function subscribes to entity updates using the onEntityUpdated method of the client, which is a common pattern in real-time applications.
  • The function returns a promise that resolves to a subscription object, which can be used to unsubscribe from the updates if needed.
packages/sdk/src/getEntities.ts (1)

5-45: LGTM!

The function is well-structured, correctly typed, and uses appropriate techniques to fetch entities in batches and process them in real-time.

Tools
Biome

[error] 40-40: The catch clause that only rethrows the original error is redundant.

These unnecessary catch clauses can be confusing. It is recommended to remove them.

(lint/complexity/noUselessCatch)

Comment on lines 39 to 79
} catch (error) {
throw error;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the redundant catch clause.

The catch clause on line 40 that only rethrows the original error is redundant and can be confusing. It is recommended to remove it.

Apply this diff to remove the redundant catch clause:

-    } catch (error) {
-        throw error;
-    }
+    }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (error) {
throw error;
}
}
Tools
Biome

[error] 40-40: The catch clause that only rethrows the original error is redundant.

These unnecessary catch clauses can be confusing. It is recommended to remove them.

(lint/complexity/noUselessCatch)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between c8eef83 and 6880087.

Files selected for processing (2)
  • packages/sdk/src/tests/client.test.ts (1 hunks)
  • packages/sdk/src/subscribeQuery.ts (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • packages/sdk/src/tests/client.test.ts
  • packages/sdk/src/subscribeQuery.ts

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range, codebase verification and nitpick comments (1)
packages/sdk/src/subscribeQuery.ts (1)

1-28: LGTM!

The code changes are approved.

Consider adding documentation for the function.

The subscribeQuery function is well-structured and uses appropriate type annotations to ensure type safety. The use of generic type parameters allows the function to be reusable for different schema types and keys.

To improve the maintainability and readability of the code, consider adding documentation for the function to explain its purpose and usage. This could include:

  • A brief description of what the function does.
  • An explanation of the generic type parameters T and K.
  • A description of the function parameters client, query, and callback.
  • An explanation of the return value.
  • An example of how to use the function.
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 6880087 and ae875c8.

Files selected for processing (4)
  • packages/sdk/src/tests/parseEntities.test.ts (1 hunks)
  • packages/sdk/src/getEntities.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/subscribeQuery.ts (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • packages/sdk/src/index.ts
Additional comments not posted (6)
packages/sdk/src/getEntities.ts (2)

5-36: LGTM!

The code changes are approved.


38-83: LGTM!

The code changes are approved.

Skipping the existing comments on the redundant catch clauses as they are still valid.

packages/sdk/src/__tests__/parseEntities.test.ts (4)

21-106: LGTM!

The test case is well-structured and covers the basic functionality of parsing entities correctly.


108-124: LGTM!

The test case is well-structured and covers the edge case of handling empty entities.


126-164: LGTM!

The test case is well-structured and covers the scenario of handling partial queries.


166-199: LGTM!

The test case is well-structured and covers the scenario of handling entities with missing fields.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range, codebase verification and nitpick comments (3)
packages/sdk/src/parseEntities.ts (3)

4-15: Consider using a switch statement for improved readability.

The function can be simplified by using a switch statement instead of multiple if-else statements.

Apply this diff to refactor the function:

-function parseValue(value: torii.Ty): any {
-    if (value.type === "primitive") {
-        return value.value;
-    } else if (value.type === "struct") {
-        return parseStruct(value.value as Record<string, torii.Ty>);
-    } else if (value.type === "enum") {
-        return (value.value as torii.EnumValue).option;
-    } else if (value.type === "array") {
-        return (value.value as torii.Ty[]).map(parseValue);
-    }
-    return value.value;
-}
+function parseValue(value: torii.Ty): any {
+    switch (value.type) {
+        case "primitive":
+            return value.value;
+        case "struct":
+            return parseStruct(value.value as Record<string, torii.Ty>);
+        case "enum":
+            return (value.value as torii.EnumValue).option;
+        case "array":
+            return (value.value as torii.Ty[]).map(parseValue);
+        default:
+            return value.value;
+    }
+}

17-23: Consider using Object.fromEntries for improved readability.

The function can be simplified by using Object.fromEntries instead of manually creating the object.

Apply this diff to refactor the function:

-function parseStruct(struct: Record<string, torii.Ty>): any {
-    const result: any = {};
-    for (const key in struct) {
-        result[key] = parseValue(struct[key]);
-    }
-    return result;
-}
+function parseStruct(struct: Record<string, torii.Ty>): any {
+    return Object.fromEntries(
+        Object.entries(struct).map(([key, value]) => [key, parseValue(value)])
+    );
+}

25-44: Consider using Object.entries and Object.fromEntries for improved readability.

The function can be simplified by using Object.entries and Object.fromEntries instead of manually creating the result object.

Apply this diff to refactor the function:

-export function parseEntities<T extends SchemaType, K extends keyof T>(
-    entities: torii.Entities,
-    query: { [P in K]?: Partial<T[P]> }
-): { [P in K]: T[P][] } {
-    const result = {} as { [P in K]: T[P][] };
-
-    for (const modelName in query) {
-        if (entities[modelName]) {
-            result[modelName as K] = Object.values(entities[modelName]).map(
-                (entity) => {
-                    return parseStruct(entity) as T[K];
-                }
-            );
-        } else {
-            result[modelName as K] = [];
-        }
-    }
-
-    return result;
-}
+export function parseEntities<T extends SchemaType, K extends keyof T>(
+    entities: torii.Entities,
+    query: { [P in K]?: Partial<T[P]> }
+): { [P in K]: T[P][] } {
+    return Object.fromEntries(
+        Object.entries(query).map(([modelName, _]) => [
+            modelName,
+            entities[modelName]
+                ? Object.values(entities[modelName]).map((entity) =>
+                      parseStruct(entity)
+                  )
+                : [],
+        ])
+    ) as { [P in K]: T[P][] };
+}
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between ae875c8 and ee9a44b.

Files selected for processing (4)
  • packages/sdk/src/tests/parseEntities.test.ts (1 hunks)
  • packages/sdk/src/getEntities.ts (1 hunks)
  • packages/sdk/src/parseEntities.ts (1 hunks)
  • packages/sdk/src/subscribeQuery.ts (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • packages/sdk/src/subscribeQuery.ts
Additional comments not posted (10)
packages/sdk/src/getEntities.ts (1)

6-51: LGTM!

The code changes are approved.

packages/sdk/src/__tests__/parseEntities.test.ts (9)

1-4: LGTM!

The imports are correctly set up for testing the parseEntities function.


7-18: LGTM!

The TestSchema interface is correctly defined and will be useful for testing the parseEntities function.


20-106: LGTM!

The test case is well-structured and covers the basic functionality of the parseEntities function.


108-124: LGTM!

The test case is well-structured and covers an important edge case of the parseEntities function.


126-164: LGTM!

The test case is well-structured and covers an important scenario of the parseEntities function.


166-199: LGTM!

The test case is well-structured and covers an important edge case of the parseEntities function.


201-268: LGTM!

The test case is well-structured and covers an important scenario of the parseEntities function.


270-334: LGTM!

The test case is well-structured and covers an important scenario of the parseEntities function.


336-396: LGTM!

The test case is well-structured and covers an important scenario of the parseEntities function.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between ee9a44b and 896fc0a.

Files selected for processing (1)
  • packages/sdk/src/convertQuerytoClause.ts (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • packages/sdk/src/convertQuerytoClause.ts

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 896fc0a and 7a86365.

Files selected for processing (9)
  • packages/sdk/src/tests/convertQueryToClause.test.ts (1 hunks)
  • packages/sdk/src/tests/convertQueryToClauses.test.ts (1 hunks)
  • packages/sdk/src/tests/parseEntities.test.ts (1 hunks)
  • packages/sdk/src/convertQueryToClauses.ts (1 hunks)
  • packages/sdk/src/convertQuerytoClause.ts (1 hunks)
  • packages/sdk/src/getEntities.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/parseEntities.ts (1 hunks)
  • packages/sdk/src/subscribeQuery.ts (1 hunks)
Files skipped from review as they are similar to previous changes (6)
  • packages/sdk/src/tests/convertQueryToClause.test.ts
  • packages/sdk/src/tests/convertQueryToClauses.test.ts
  • packages/sdk/src/tests/parseEntities.test.ts
  • packages/sdk/src/convertQuerytoClause.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/parseEntities.ts
Additional comments not posted (1)
packages/sdk/src/convertQueryToClauses.ts (1)

9-67: Review of convertQueryToClauses function:

  1. Function Logic:

    • The function effectively translates a query object into an array of clauses suitable for the Torii client. This is crucial for ensuring that the queries are executed correctly on the backend.
    • The handling of entityIds and the exclusion of nested queries from the keys array are well-implemented, ensuring that only relevant data is included in the clauses.
  2. Handling of Query Conditions:

    • The function's approach to iterating over the query object and selectively adding conditions to the clauses array is efficient and clear.
    • The decision to skip the entityIds key and handle nested queries separately helps maintain clarity and focus on the primary query parameters.

Suggested Improvements:

  • Consider adding more detailed handling for the where conditions as noted in the comments within the code. This could enhance the function's capability to deal with complex queries.

Comment on lines 7 to 31
export async function subscribeQuery<T extends SchemaType, K extends keyof T>(
client: torii.ToriiClient,
query: QueryType<T, K>,
callback?: (response: { data?: QueryResult<T, K>; error?: Error }) => void
): Promise<torii.Subscription> {
return client.onEntityUpdated(
convertQueryToClauses(query),
(_entities: string, data: torii.Entities) => {
try {
if (callback) {
callback({ data: parseEntities<T, K>(data, query) });
}
} catch (error) {
if (callback) {
callback({
error:
error instanceof Error
? error
: new Error(String(error)),
});
}
}
}
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider modernizing the callback pattern.

The function subscribeQuery is well-implemented with proper error handling and use of TypeScript for type safety. However, consider using Promises or async/await instead of callbacks to simplify error handling and improve control flow. This change could make the function easier to use and integrate with other async functions.

Here's a suggested refactor to use async/await:

-export async function subscribeQuery<T extends SchemaType, K extends keyof T>(
+export function subscribeQuery<T extends SchemaType, K extends keyof T>(
     client: torii.ToriiClient,
     query: QueryType<T, K>,
-    callback?: (response: { data?: QueryResult<T, K>; error?: Error }) => void
+): Promise<QueryResult<T, K>>
 ): Promise<torii.Subscription> {
     return client.onEntityUpdated(
         convertQueryToClauses(query),
         async (_entities: string, data: torii.Entities) => {
             try {
                 const parsedData = parseEntities<T, K>(data, query);
-                if (callback) {
-                    callback({ data: parsedData });
-                }
+                return parsedData;
             } catch (error) {
                 const normalizedError = error instanceof Error
                     ? error
                     : new Error(String(error));
-                if (callback) {
-                    callback({ error: normalizedError });
-                }
+                throw normalizedError;
             }
         }
     );
 }

Committable suggestion was skipped due to low confidence.

Comment on lines 7 to 86
export async function getEntities<T extends SchemaType, K extends keyof T>(
client: torii.ToriiClient,
query: QueryType<T, K>,
callback: (response: { data?: QueryResult<T, K>; error?: Error }) => void,
limit: number = 100, // Default limit
offset: number = 0 // Default offset
): Promise<QueryResult<T, K>> {
const clause = convertQueryToClause(query);
let cursor = offset;
let continueFetching = true;
let allEntities: torii.Entities = {};

while (continueFetching) {
const toriiQuery: torii.Query = {
limit: limit,
offset: cursor,
clause: clause,
};

try {
const entities = await client.getEntities(toriiQuery);
Object.assign(allEntities, entities);
const parsedEntities = parseEntities<T, K>(entities, query);
callback({ data: parsedEntities });

if (Object.keys(entities).length < limit) {
continueFetching = false;
} else {
cursor += limit;
}
} catch (error) {
callback({ error: error as Error });
throw error;
}
}

return parseEntities<T, K>(allEntities, query);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review of getEntities function:

  1. Function Logic:

    • The function efficiently paginates through results using a while loop and cursor management. This is a good approach for handling large datasets in manageable chunks.
    • The use of Object.assign to merge entities is appropriate for accumulating results across multiple fetches.
  2. Error Handling:

    • The function correctly uses a callback to report errors, which is consistent with Node.js conventions.
    • However, the use of throw error; after invoking the callback with the error might not be necessary or desirable, as it could lead to unhandled promise rejections if not properly caught by the caller.
  3. Redundant Catch Clauses:

    • As previously noted by the bot, the catch clauses that merely rethrow the caught error are redundant. This pattern does not add any value and could be removed to simplify the error handling.

Suggested Changes:

  • Consider removing the throw error; to prevent potential unhandled promise rejections, especially since the error is already being handled via the callback.
-            throw error;
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export async function getEntities<T extends SchemaType, K extends keyof T>(
client: torii.ToriiClient,
query: QueryType<T, K>,
callback: (response: { data?: QueryResult<T, K>; error?: Error }) => void,
limit: number = 100, // Default limit
offset: number = 0 // Default offset
): Promise<QueryResult<T, K>> {
const clause = convertQueryToClause(query);
let cursor = offset;
let continueFetching = true;
let allEntities: torii.Entities = {};
while (continueFetching) {
const toriiQuery: torii.Query = {
limit: limit,
offset: cursor,
clause: clause,
};
try {
const entities = await client.getEntities(toriiQuery);
Object.assign(allEntities, entities);
const parsedEntities = parseEntities<T, K>(entities, query);
callback({ data: parsedEntities });
if (Object.keys(entities).length < limit) {
continueFetching = false;
} else {
cursor += limit;
}
} catch (error) {
callback({ error: error as Error });
throw error;
}
}
return parseEntities<T, K>(allEntities, query);
}
export async function getEntities<T extends SchemaType, K extends keyof T>(
client: torii.ToriiClient,
query: QueryType<T, K>,
callback: (response: { data?: QueryResult<T, K>; error?: Error }) => void,
limit: number = 100, // Default limit
offset: number = 0 // Default offset
): Promise<QueryResult<T, K>> {
const clause = convertQueryToClause(query);
let cursor = offset;
let continueFetching = true;
let allEntities: torii.Entities = {};
while (continueFetching) {
const toriiQuery: torii.Query = {
limit: limit,
offset: cursor,
clause: clause,
};
try {
const entities = await client.getEntities(toriiQuery);
Object.assign(allEntities, entities);
const parsedEntities = parseEntities<T, K>(entities, query);
callback({ data: parsedEntities });
if (Object.keys(entities).length < limit) {
continueFetching = false;
} else {
cursor += limit;
}
} catch (error) {
callback({ error: error as Error });
}
}
return parseEntities<T, K>(allEntities, query);
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 7a86365 and 82465cb.

Files selected for processing (3)
  • packages/sdk/src/convertQueryToClauses.ts (1 hunks)
  • packages/sdk/src/parseEntities.ts (1 hunks)
  • packages/sdk/src/subscribeQuery.ts (1 hunks)
Files skipped from review due to trivial changes (1)
  • packages/sdk/src/subscribeQuery.ts
Files skipped from review as they are similar to previous changes (1)
  • packages/sdk/src/parseEntities.ts

Comment on lines 9 to 71
export function convertQueryToClauses<T extends SchemaType>(
query?: QueryType<T>
): torii.EntityKeysClause[] {
if (!query) {
return [];
}

const clauses: torii.EntityKeysClause[] = [];

// Handle entityIds
if (
query.entityIds &&
Array.isArray(query.entityIds) &&
query.entityIds.length > 0
) {
clauses.push({ HashedKeys: query.entityIds });
}

for (const [model, conditions] of Object.entries(query)) {
if (model === "entityIds") continue; // Skip the entityIds key

if (conditions && typeof conditions === "object") {
const keys: (string | undefined)[] = [];

for (const [key, value] of Object.entries(conditions)) {
if (key === "$") {
// Handle query options
const queryOptions = value as QueryOptions;
if (queryOptions.where) {
// Handle 'where' conditions if needed
// For now, we're not doing anything with 'where'
}
continue;
}
if (typeof value === "object" && value !== null) {
// This is a nested query, we don't include it in the keys
continue;
}
keys.push(value as string | undefined);
}

if (keys.length > 0) {
clauses.push({
Keys: {
keys,
pattern_matching: "FixedLen",
models: [model],
},
});
} else {
clauses.push({
Keys: {
keys: [],
pattern_matching: "VariableLen",
models: [model],
},
});
}
}
}

return clauses;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review of convertQueryToClauses Function

The function convertQueryToClauses is well-structured and uses TypeScript effectively to ensure type safety. Here are some observations and suggestions:

  1. Type Safety and Error Handling:

    • The function handles optional query parameter gracefully by returning an empty array if not provided. This is good practice for robust error handling.
    • Consider adding more explicit type checks or using TypeScript's utility types for better type inference and safety, especially before type assertions.
  2. Performance Considerations:

    • The function iterates over all entries in the query object, which is efficient for the intended use case. However, consider potential performance implications if query contains a large number of entries.
    • The use of Array.isArray and checking length > 0 is appropriate to ensure that non-empty arrays are processed.
  3. Code Readability and Maintainability:

    • The separation of handling entityIds from other keys is clear and maintains readability.
    • The nested loops and conditions are necessary for the function's logic but consider refactoring into smaller functions if the logic becomes more complex in the future.
  4. Future Enhancements:

    • The placeholder comment in lines 39 indicates future implementation for 'where' conditions. Ensure that this is addressed or tracked in project management tools to avoid forgotten code.

Overall, the implementation meets the requirements and provides a good foundation for the typed query language feature. Further optimization and enhancements can be considered based on future requirements and performance metrics.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Outside diff range and nitpick comments (3)
examples/clients/react/react-sdk/src/App.tsx (1)

1-139: LGTM! Here are some suggestions to improve the code.

The code looks good and follows best practices. Here are some suggestions to make it even better:

  1. Add error boundaries to handle errors in the component and prevent the entire app from crashing.
  2. Add loading and error states to the component to improve the user experience.
  3. Add type annotations to the fetchEntities function to improve type safety.
  4. Add a return type to the App component to improve type safety.
  5. Move the schema interfaces and enums to a separate file to improve code organization.
  6. Move the SDK initialization to a separate file to improve code organization.
  7. Add comments to explain the purpose of the component and its functions to improve code readability.
packages/sdk/src/convertQuerytoClause.ts (2)

4-95: Consider refactoring the function to improve readability and maintainability.

The convertQueryToClause function is quite complex and heavily nested, which could affect readability and maintainability. Consider breaking it down into smaller, more focused functions to handle different parts of the query object processing.

For example, you could extract the logic for handling the where conditions into a separate function, and the logic for constructing clauses based on member values into another function. This would make the main function more concise and easier to understand.

Additionally, consider adding more comments to explain the purpose and behavior of each section of the code, especially for complex conditionals and loops.


96-108: LGTM, but consider adding a type guard for unsupported types.

The convertToPrimitive function looks good and correctly handles the conversion of supported primitive types to their corresponding Torii primitive types. The error handling for unsupported types is also helpful for debugging.

As a minor improvement, consider adding a type guard to narrow down the type of value before the throw statement. This would provide better type safety and catch potential issues at compile time.

For example:

function convertToPrimitive(value: any): torii.Primitive {
  // ...
  
  if (typeof value !== "number" && typeof value !== "boolean" && typeof value !== "string" && typeof value !== "bigint") {
    throw new Error(`Unsupported primitive type: ${typeof value}`);
  }
  
  throw new Error("Unexpected error: reached end of convertToPrimitive function.");
}
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 82465cb and a8dc7c1.

Files ignored due to path filters (4)
  • examples/clients/react/react-sdk/public/vite.svg is excluded by !**/*.svg
  • examples/clients/react/react-sdk/src/assets/react.svg is excluded by !**/*.svg
  • examples/dojo/dojo-starter/Scarb.lock is excluded by !**/*.lock
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
Files selected for processing (35)
  • examples/clients/react/react-sdk/.gitignore (1 hunks)
  • examples/clients/react/react-sdk/README.md (1 hunks)
  • examples/clients/react/react-sdk/dojoConfig.ts (1 hunks)
  • examples/clients/react/react-sdk/eslint.config.js (1 hunks)
  • examples/clients/react/react-sdk/index.html (1 hunks)
  • examples/clients/react/react-sdk/package.json (1 hunks)
  • examples/clients/react/react-sdk/src/App.css (1 hunks)
  • examples/clients/react/react-sdk/src/App.tsx (1 hunks)
  • examples/clients/react/react-sdk/src/index.css (1 hunks)
  • examples/clients/react/react-sdk/src/main.tsx (1 hunks)
  • examples/clients/react/react-sdk/src/vite-env.d.ts (1 hunks)
  • examples/clients/react/react-sdk/tsconfig.app.json (1 hunks)
  • examples/clients/react/react-sdk/tsconfig.json (1 hunks)
  • examples/clients/react/react-sdk/tsconfig.node.json (1 hunks)
  • examples/clients/react/react-sdk/vite.config.ts (1 hunks)
  • examples/dojo/dojo-starter/.github/workflows/test.yaml (1 hunks)
  • examples/dojo/dojo-starter/README.md (1 hunks)
  • examples/dojo/dojo-starter/Scarb.toml (1 hunks)
  • examples/dojo/dojo-starter/dojo_dev.toml (1 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/abis/dojo-world.json (1 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/contracts/dojo_starter-actions-7a1c7102.toml (1 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/dojo-world.toml (1 hunks)
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/dojo-world.json (1 hunks)
  • examples/dojo/dojo-starter/manifests/dev/deployment/manifest.json (4 hunks)
  • examples/dojo/dojo-starter/manifests/dev/deployment/manifest.toml (2 hunks)
  • packages/sdk/src/tests/convertQueryToClause.test.ts (1 hunks)
  • packages/sdk/src/tests/convertQueryToClauses.test.ts (1 hunks)
  • packages/sdk/src/tests/parseEntities.test.ts (1 hunks)
  • packages/sdk/src/convertQueryToClauses.ts (1 hunks)
  • packages/sdk/src/convertQuerytoClause.ts (1 hunks)
  • packages/sdk/src/getEntities.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/parseEntities.ts (1 hunks)
  • packages/sdk/src/subscribeQuery.ts (1 hunks)
  • packages/sdk/src/types.ts (1 hunks)
Files skipped from review due to trivial changes (3)
  • examples/clients/react/react-sdk/.gitignore
  • examples/clients/react/react-sdk/src/vite-env.d.ts
  • examples/clients/react/react-sdk/tsconfig.json
Files skipped from review as they are similar to previous changes (5)
  • packages/sdk/src/tests/convertQueryToClause.test.ts
  • packages/sdk/src/tests/convertQueryToClauses.test.ts
  • packages/sdk/src/tests/parseEntities.test.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/parseEntities.ts
Additional context used
Biome
examples/clients/react/react-sdk/tsconfig.node.json

[error] 8-8: JSON standard does not allow comments.

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

examples/clients/react/react-sdk/tsconfig.app.json

[error] 9-9: JSON standard does not allow comments.

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

Additional comments not posted (32)
examples/clients/react/react-sdk/dojoConfig.ts (1)

1-7: LGTM!

The code changes look good:

  • The file structure and naming conventions follow best practices.
  • The imports are used correctly to create the Dojo configuration object.
  • There are no obvious issues or errors in the code.

The code changes are approved.

examples/clients/react/react-sdk/src/main.tsx (1)

1-10: LGTM!

The code follows the standard structure for a React entry point file and there are no issues. Using StrictMode is a good practice for identifying potential issues.

examples/dojo/dojo-starter/manifests/dev/base/dojo-world.toml (1)

2-3: LGTM, but verify the class implementation matches the updated hash values.

The changes to the class_hash and original_class_hash values seem to be intentional updates, likely reflecting changes in the underlying class implementation or its associated metadata. The rest of the manifest remains unchanged, suggesting that the core functionality and structure of the dojo-world class are preserved.

However, it's important to ensure that the corresponding class implementation has been updated to match these new hash values. Please run the following script to verify:

The script searches for the DojoWorld class implementation in Solidity files and calculates its hash using the Solidity compiler. Compare the calculated hash with the updated class_hash value in the manifest to ensure they match.

examples/clients/react/react-sdk/vite.config.ts (1)

1-9: LGTM!

The Vite configuration file for the React project is well-structured and follows best practices:

  • The necessary plugins for React, WebAssembly, and top-level await are imported and included in the plugins array.
  • The defineConfig function is used to define the configuration object, providing type inference and IDE support.
  • The commented URL is a helpful reference to the Vite configuration documentation.

The code changes are approved.

examples/dojo/dojo-starter/Scarb.toml (1)

15-15: LGTM, but verify compatibility.

Updating the dojo dependency to a newer version is a good practice to leverage the latest features and bug fixes. The code changes are approved.

However, ensure that the version v1.0.0-alpha.11 is compatible with the existing codebase and doesn't introduce any breaking changes. Run the following script to verify compatibility:

If any of the above tests fail, it indicates that the updated version might have introduced breaking changes. In such cases, carefully review the release notes of the dojo library and make necessary changes to adapt to the new version.

examples/clients/react/react-sdk/index.html (1)

1-13: LGTM!

The index.html file follows the standard structure of an HTML document and is properly configured:

  • The <!doctype html> declaration is present.
  • The <html> tag includes the lang attribute set to "en".
  • The <head> section includes relevant metadata:
    • Character encoding is set to UTF-8.
    • Favicon is correctly linked.
    • Viewport is set for responsive design.
    • Title is provided.
  • The <body> section correctly sets up the root <div> for the React application to mount.
  • The <script> tag correctly references the application's main TypeScript file.

The code changes are approved.

examples/dojo/dojo-starter/manifests/dev/base/contracts/dojo_starter-actions-7a1c7102.toml (1)

2-3: Provide more context for the hash updates.

The class_hash and original_class_hash values have been updated, which may affect how this contract interacts with other components. While the rest of the configuration remains unchanged, suggesting that the core functionality is preserved, it's important to understand the reason behind these hash updates.

Please provide more information about what changes were made to the contract implementation that necessitated these hash updates. Also, verify that the updated hashes correspond to the intended version of the contract to ensure compatibility isn't broken.

examples/clients/react/react-sdk/tsconfig.node.json (1)

1-22: LGTM!

The TypeScript configuration file for the Node.js environment is set up correctly with appropriate compiler options and includes. The comments in the file, although not valid JSON, are commonly used for better readability and organization in configuration files. The file is good to merge.

Tools
Biome

[error] 8-8: JSON standard does not allow comments.

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

examples/dojo/dojo-starter/.github/workflows/test.yaml (1)

13-13: LGTM! Verify compatibility with the updated Dojo engine version.

The change looks good. Updating the Dojo engine version to v1.0.0-alpha.9 is a reasonable step forward.

Just make sure to verify that the project is compatible with the updated Dojo engine version and that all the expected features and improvements are working as intended.

examples/clients/react/react-sdk/tsconfig.app.json (1)

1-24: LGTM!

The TypeScript configuration file looks good. It has the standard configuration options for a React application using TypeScript.

The comments in the file are fine and can be ignored. JSON with comments is allowed in tsconfig files.

Tools
Biome

[error] 9-9: JSON standard does not allow comments.

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

examples/clients/react/react-sdk/src/App.css (1)

1-42: LGTM!

The CSS styles in App.css are implemented correctly and follow a clean structure. The selectors, properties, and values used are valid and serve their intended purpose. The logo-spin animation and its usage in the media query is also implemented properly.

Great job with the styles! The code changes are approved.

packages/sdk/src/types.ts (5)

1-1: LGTM!

The code changes are approved.


3-7: LGTM!

The code changes are approved.


9-13: LGTM!

The code changes are approved.


15-23: LGTM!

The code changes are approved.


25-33: LGTM!

The code changes are approved.

examples/clients/react/react-sdk/eslint.config.js (1)

1-28: LGTM!

The ESLint configuration looks good and follows best practices:

  • Extends recommended configs from @eslint/js and typescript-eslint for a solid foundation.
  • Uses the react-hooks plugin to enforce the rules of hooks.
  • Enables the react-refresh plugin for fast refresh in development.
  • Sets ecmaVersion to 2020 to support modern JavaScript features.
  • Specifies browser globals, which is appropriate for a client-side React project.
  • Configures the react-refresh/only-export-components rule with allowConstantExport option to ensure that only React components are exported, while allowing constant exports.

The code changes are approved.

examples/clients/react/react-sdk/package.json (1)

1-34: LGTM!

The package.json file follows the standard structure and fields, properly defining the project metadata, dependencies, and scripts. The dependencies are specified with appropriate version ranges, and the project is correctly configured to use ECMAScript modules. The included scripts cover essential tasks such as development, building, linting, and previewing.

Great job on setting up a solid foundation for the React SDK project! The code changes are approved.

examples/clients/react/react-sdk/src/index.css (1)

1-68: LGTM!

The CSS file follows best practices and has a clean structure. The styles are properly scoped, and the use of CSS variables and media queries allows for easy customization and responsiveness. No issues or improvements needed.

The code changes are approved.

examples/clients/react/react-sdk/README.md (1)

1-50: Excellent README.md file! 👍

The README.md file provides a clear and concise overview of the project template and its setup. The instructions for expanding the ESLint configuration are well-structured, easy to follow, and include helpful code examples. This file will be valuable for developers using this template, especially when setting up the project for production use.

Great job on creating a comprehensive and informative README.md file! 🌟

examples/dojo/dojo-starter/README.md (1)

44-44: LGTM!

The change to the world identifier in the command to start the Torii service is approved. It does not introduce any new functionality or modify the behavior of the service.

packages/sdk/src/getEntities.ts (1)

7-66: LGTM, but address the past review comments.

The code changes are approved. However, the past review comments are still valid and applicable to the current code. Please address them by:

  1. Removing the redundant catch clauses that merely rethrow the caught error.
  2. Removing the throw error; statement to prevent potential unhandled promise rejections.
packages/sdk/src/convertQueryToClauses.ts (1)

4-63: The past review comments are still valid and applicable.

I have reviewed the convertQueryToClauses function and determined that the past review comments provided are still valid and applicable to the current implementation. The comments cover important aspects such as type safety, error handling, performance considerations, code readability, maintainability, and future enhancements. They provide a thorough review of the function and do not require any additional comments at this time.

examples/dojo/dojo-starter/manifests/dev/deployment/manifest.toml (4)

Line range hint 1-102: Skipping the review of the remaining code segments.

The remaining code segments define the models used in the Dojo project, and there are no changes to these segments. Therefore, no further review is necessary.


6-7: LGTM, but verify the contract address and transaction hash.

The changes to the address and transaction_hash for the WorldContract are approved. However, it's crucial to ensure that these values are valid and that they match the deployed contract on the associated blockchain network.

To verify the validity of the contract address and transaction hash, you can query the associated blockchain network using the provided values. Here's a script to help with the verification process:

Ensure that the contract address and transaction hash exist on the associated blockchain network and that they correspond to the expected WorldContract deployment.


3-4: LGTM, but verify the consistency of the class hashes.

The changes to the class_hash and original_class_hash for the WorldContract are approved. However, it's important to ensure that these hashes are consistent with the contract's bytecode and that they match the values in the associated blockchain network.

To verify the consistency of the class hashes, you can generate and compare the hash of the contract's bytecode with the provided values. Here's a script to help with the verification process:

Ensure that the generated hash matches the class_hash and original_class_hash values in the manifest file. Additionally, verify that these hashes are consistent with the deployed contract on the associated blockchain network.


26-28: LGTM, but verify the contract address and class hashes.

The changes to the address, class_hash, and original_class_hash for the DojoContract are approved. However, it's essential to ensure that the contract address is valid and that the class hashes are consistent with the contract's bytecode and the associated blockchain network.

To verify the validity of the contract address and the consistency of the class hashes, you can perform the following steps:

  1. Query the associated blockchain network using the provided contract address to ensure that it exists and corresponds to the expected DojoContract deployment.

  2. Generate and compare the hash of the DojoContract's bytecode with the provided class hash values. Here's a script to help with the verification process:

Ensure that the generated hash matches the class_hash and original_class_hash values in the manifest file. Additionally, verify that these hashes are consistent with the deployed contract on the associated blockchain network.

packages/sdk/src/convertQuerytoClause.ts (1)

110-122: LGTM!

The convertOperator function looks good and correctly maps the supported string operators to their corresponding Torii comparison operators. The error handling for unsupported operators is also helpful for debugging.

examples/dojo/dojo-starter/manifests/dev/base/abis/dojo-world.json (1)

942-946: LGTM!

The addition of the entity_id field to the StoreSetRecord event looks good. It expands the event data structure and potentially allows for better identification or categorization of entities, as mentioned in the summary.

[consistent_summary]

examples/dojo/dojo-starter/manifests/dev/deployment/abis/dojo-world.json (1)

942-946: LGTM! The addition of the entity_id field to the StoreSetRecord event looks good.

The entity_id field has the potential to enhance entity management and tracking capabilities within the system. However, please ensure that this field is being appropriately set and utilized in the relevant parts of the codebase to fully leverage its benefits.

To verify the usage of the entity_id field, run the following script:

examples/dojo/dojo-starter/manifests/dev/deployment/manifest.json (2)

947-951: LGTM!

The addition of the entity_id field to the StoreSetRecord event is approved. This change enhances the data model by allowing for the identification of entities.


4-5: LGTM, but verify the impact of the changes.

The changes to the class_hash and original_class_hash for the world are approved. However, as these changes indicate an update to the underlying contract implementation, it's important to verify that:

  • The new implementation has been thoroughly tested.
  • All the interactions with the world contract have been updated to match the new implementation.

To verify the impact of the changes, run the following script:

Comment on lines 6 to 38
export async function subscribeQuery<T extends SchemaType>(
client: torii.ToriiClient,
query?: QueryType<T>,
callback?: (response: { data?: QueryResult<T>; error?: Error }) => void,
options?: { logging?: boolean }
): Promise<torii.Subscription> {
return client.onEntityUpdated(
convertQueryToClauses(query),
(_entities: string, data: torii.Entities) => {
try {
if (callback) {
const parsedData = parseEntities<T>(data, query);
if (options?.logging) {
console.log("Parsed entity data:", parsedData);
}
callback({ data: parsedData });
}
} catch (error) {
if (callback) {
if (options?.logging) {
console.error("Error parsing entity data:", error);
}
callback({
error:
error instanceof Error
? error
: new Error(String(error)),
});
}
}
}
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modernize the API, improve error handling, and enhance logging flexibility.

Consider making the following improvements to the subscribeQuery function:

  1. API Modernization:

    • Fully embrace Promises or async/await and remove the callback parameter.
    • This will simplify the function's usage and make it more consistent with modern asynchronous programming practices.
  2. Error Handling:

    • Reject the returned Promise with any caught errors to ensure proper error propagation.
    • This will prevent errors from being silently swallowed if the callback is not provided.
  3. Logging:

    • Allow injecting a custom logger or use a logging library for more flexible logging.
    • This will make the logging adaptable to different environments and logging requirements.

Here's a suggested refactor:

-export async function subscribeQuery<T extends SchemaType>(
+export function subscribeQuery<T extends SchemaType>(
     client: torii.ToriiClient,
     query?: QueryType<T>,
-    callback?: (response: { data?: QueryResult<T>; error?: Error }) => void,
-    options?: { logging?: boolean }
+    options?: { logger?: (message: string, ...args: any[]) => void }
 ): Promise<torii.Subscription> {
     return client.onEntityUpdated(
         convertQueryToClauses(query),
-        (_entities: string, data: torii.Entities) => {
+        async (_entities: string, data: torii.Entities) => {
             try {
-                if (callback) {
-                    const parsedData = parseEntities<T>(data, query);
-                    if (options?.logging) {
-                        console.log("Parsed entity data:", parsedData);
-                    }
-                    callback({ data: parsedData });
+                const parsedData = parseEntities<T>(data, query);
+                options?.logger?.("Parsed entity data:", parsedData);
+                return parsedData;
+            } catch (error) {
+                const normalizedError =
+                    error instanceof Error ? error : new Error(String(error));
+                options?.logger?.("Error parsing entity data:", normalizedError);
+                throw normalizedError;
             }
-            } catch (error) {
-                if (callback) {
-                    if (options?.logging) {
-                        console.error("Error parsing entity data:", error);
-                    }
-                    callback({
-                        error:
-                            error instanceof Error
-                                ? error
-                                : new Error(String(error)),
-                    });
-                }
-            }
         }
     );
 }

These changes will modernize the function's API, ensure proper error handling, and provide more flexibility for logging.

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export async function subscribeQuery<T extends SchemaType>(
client: torii.ToriiClient,
query?: QueryType<T>,
callback?: (response: { data?: QueryResult<T>; error?: Error }) => void,
options?: { logging?: boolean }
): Promise<torii.Subscription> {
return client.onEntityUpdated(
convertQueryToClauses(query),
(_entities: string, data: torii.Entities) => {
try {
if (callback) {
const parsedData = parseEntities<T>(data, query);
if (options?.logging) {
console.log("Parsed entity data:", parsedData);
}
callback({ data: parsedData });
}
} catch (error) {
if (callback) {
if (options?.logging) {
console.error("Error parsing entity data:", error);
}
callback({
error:
error instanceof Error
? error
: new Error(String(error)),
});
}
}
}
);
}
export function subscribeQuery<T extends SchemaType>(
client: torii.ToriiClient,
query?: QueryType<T>,
options?: { logger?: (message: string, ...args: any[]) => void }
): Promise<torii.Subscription> {
return client.onEntityUpdated(
convertQueryToClauses(query),
async (_entities: string, data: torii.Entities) => {
try {
const parsedData = parseEntities<T>(data, query);
options?.logger?.("Parsed entity data:", parsedData);
return parsedData;
} catch (error) {
const normalizedError =
error instanceof Error ? error : new Error(String(error));
options?.logger?.("Error parsing entity data:", normalizedError);
throw normalizedError;
}
}
);
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range and nitpick comments (1)
packages/sdk/src/execute.ts (1)

71-75: Consider using undefined instead of void for the empty output case.

The static analysis tool suggests using undefined instead of void for the empty output case in the MapOutputType type. While void is technically correct, using undefined aligns better with TypeScript conventions and avoids potential confusion.

Apply this diff to replace void with undefined:

-type MapOutputType<T extends OutputsType> = T extends []
-    ? void
+type MapOutputType<T extends OutputsType> = T extends []
+    ? undefined
     : T["length"] extends 1
       ? MapAbiType<T[0]["type"]>
       : { [K in keyof T]: MapAbiType<T[K]["type"]> };
Tools
Biome

[error] 72-72: void is confusing outside a return type or a type parameter.

Unsafe fix: Use undefined instead.

(lint/suspicious/noConfusingVoidType)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 27f5b4f and ffc6c29.

Files selected for processing (5)
  • examples/clients/react/react-sdk/src/App.tsx (1 hunks)
  • packages/sdk/src/tests/client.test.ts (1 hunks)
  • packages/sdk/src/tests/convertQueryToClause.test.ts (1 hunks)
  • packages/sdk/src/execute.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
Files skipped from review as they are similar to previous changes (4)
  • examples/clients/react/react-sdk/src/App.tsx
  • packages/sdk/src/tests/client.test.ts
  • packages/sdk/src/tests/convertQueryToClause.test.ts
  • packages/sdk/src/index.ts
Additional context used
Biome
packages/sdk/src/execute.ts

[error] 72-72: void is confusing outside a return type or a type parameter.

Unsafe fix: Use undefined instead.

(lint/suspicious/noConfusingVoidType)

Additional comments not posted (2)
packages/sdk/src/execute.ts (2)

3-15: LGTM!

The AbiType type is well-defined and covers a comprehensive set of data types used in smart contract ABIs. The inclusion of a string literal type for custom types allows for extensibility.


17-31: LGTM!

The TypeMapping interface is well-structured and provides a clear mapping between AbiType values and their corresponding TypeScript types. This mapping is essential for ensuring type safety when interacting with smart contracts. The interface is easily extensible with custom type mappings.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range and nitpick comments (2)
packages/sdk/src/parseEntities.ts (2)

19-21: Consider removing the unnecessary default case.

The default case in the switch statement is not necessary as all possible types of torii.Ty are already handled in the previous cases. You can remove it to simplify the function.

Apply this diff to remove the default case:

-       default:
-           return value.value;

30-74: LGTM!

The parseEntities function is well-implemented and provides a flexible and type-safe way to parse entities based on a query and schema type. The use of TypeScript generics ensures type safety, and the optional logging is a useful feature for debugging and tracing the parsing process.

Consider adding more detailed comments to explain the behavior of the function and the structure of the result object. This will make it easier for other developers to understand and use the function.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between ffc6c29 and 5ab108d.

Files selected for processing (6)
  • packages/sdk/src/tests/convertQueryToEntityKeyClauses.test.ts (1 hunks)
  • packages/sdk/src/convertQueryToEntityKeyClauses.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/parseEntities.ts (1 hunks)
  • packages/sdk/src/subscribeQuery.ts (1 hunks)
  • packages/sdk/src/types.ts (1 hunks)
Files skipped from review due to trivial changes (1)
  • packages/sdk/src/subscribeQuery.ts
Files skipped from review as they are similar to previous changes (2)
  • packages/sdk/src/index.ts
  • packages/sdk/src/types.ts
Additional comments not posted (12)
packages/sdk/src/convertQueryToEntityKeyClauses.ts (2)

10-39: LGTM!

The convertQueryToEntityKeyClauses function is well-structured and follows good practices:

  1. It correctly handles the case when the query is not provided by returning an empty array.
  2. It separates the handling of entityIds and namespaces by destructuring the query.
  3. It creates a clause with HashedKeys when entityIds exists and has elements.
  4. It iterates over the namespaces and creates clauses for each namespace-model pair using the createClause helper function.
  5. It uses the createClause helper function to encapsulate the logic for creating the EntityKeysClause based on the value type, which keeps the main function clean and readable.
  6. It returns the array of clauses, which is the expected output.

48-70: LGTM!

The createClause function is well-implemented and follows good practices:

  1. It correctly creates a clause with an empty keys array and a variable-length pattern matching when the value is true.
  2. It correctly creates a clause with the keys populated by the array and fixed-length pattern matching when the value is an array.
  3. It returns undefined when the value does not meet these criteria, which is a good practice to handle unsupported value types.
  4. It uses the namespaceModel parameter to set the models property of the clause, which is correct.
  5. It returns the created clause, which is the expected output.
packages/sdk/src/parseEntities.ts (1)

24-28: LGTM!

The function logic is correct, and the implementation is accurate.

packages/sdk/src/__tests__/convertQueryToEntityKeyClauses.test.ts (9)

26-31: LGTM!

The test case correctly verifies that the function returns an empty array when the query is undefined.


33-37: LGTM!

The test case correctly verifies that the function returns an empty array when the query is an empty object.


39-48: LGTM!

The test case correctly verifies that the function converts a query with entityIds to a HashedKeys clause.


50-67: LGTM!

The test case correctly verifies that the function converts a query with a namespace and a model set to true to a Keys clause with pattern_matching set to VariableLen and the corresponding models.


69-86: LGTM!

The test case correctly verifies that the function converts a query with a namespace and a model with an array of keys to a Keys clause with pattern_matching set to FixedLen, the provided keys, and the corresponding models.


88-115: LGTM!

The test case correctly verifies that the function handles multiple namespaces and models by returning multiple clauses, including a HashedKeys clause for entityIds and Keys clauses for each namespace and model combination.


117-137: LGTM!

The test case correctly verifies that the function ignores non-object entries except for entityIds and returns a HashedKeys clause for entityIds and a Keys clause for the valid namespace and model combination.


139-157: LGTM!

The test case correctly verifies that the function gracefully handles an empty entityIds array and returns a Keys clause for the valid namespace and model combination.


159-184: LGTM!

The test case correctly verifies that the function handles multiple models within a single namespace by returning multiple Keys clauses, one for each model within the namespace.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Outside diff range and nitpick comments (5)
packages/sdk/src/subscribeEventQuery.ts (1)

1-38: Overall, the implementation looks good! Here are a few suggestions:

  1. Consider adding JSDoc comments to document the function signature and behavior. This will make it easier for other developers to understand and use the function.

  2. It would be beneficial to add a test suite that covers the various scenarios, such as:

    • Subscribing with and without a query
    • Providing a callback and not providing one
    • Enabling and disabling logging through options
    • Handling errors during parsing

This will help ensure the robustness and correctness of the function.

packages/sdk/src/getEventMessages.ts (2)

17-17: Consistently use the provided logging option for logging.

The function uses a mix of console.log and the provided logging option for logging. It would be better to consistently use the provided logging option throughout the function. This would make the logging behavior more predictable and easier to control.

Also applies to: 30-30, 35-38, 54-56, 62-64


7-14: Add more detailed JSDoc comments.

The function could benefit from more detailed JSDoc comments explaining the parameters, return value, and behavior of the function. This would make it easier for other developers to understand and use the function correctly.

packages/sdk/src/index.ts (2)

93-123: Address the TODO comment.

The TODO comment indicates that the contract definitions should be generated at build time instead of being imported from a JSON file.

Please update the code to generate the contract definitions at build time, and remove the import of the JSON file.


125-305: LGTM, but consider adding more examples.

The exampleUsage function provides a good overview of how to use the SDK client for querying data, with examples covering a range of scenarios.

To further improve the example, consider adding more examples for the subscribeEventQuery and getEventMessages methods, to demonstrate how to query and handle event data.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 5ab108d and de370ab.

Files selected for processing (4)
  • packages/sdk/src/getEventMessages.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/subscribeEntityQuery.ts (1 hunks)
  • packages/sdk/src/subscribeEventQuery.ts (1 hunks)
Additional comments not posted (6)
packages/sdk/src/subscribeEntityQuery.ts (1)

6-38: LGTM!

The subscribeEntityQuery function is well-implemented and follows a clear and logical structure. Here are some key points:

  1. The use of a generic type parameter T allows for flexibility in handling different entity schemas.
  2. The function effectively converts the query into entity key clauses using the convertQueryToEntityKeyClauses utility function.
  3. The subscription to the onEntityUpdated event ensures that the function is notified whenever relevant entities are updated.
  4. The function appropriately parses the incoming data using the parseEntities function and invokes the callback with the parsed data.
  5. The optional logging functionality provides useful debugging information when enabled.
  6. The error handling mechanism ensures that any parsing errors are caught and propagated to the callback, along with optional logging.

Overall, the function is robust, flexible, and provides a convenient way to subscribe to entity updates based on a specified query.

packages/sdk/src/index.ts (5)

20-24: LGTM!

The createClient function is correctly implemented and follows the expected pattern for creating a Torii client using the provided configuration.


70-75: LGTM!

The Todo interface is correctly defined and includes all the necessary properties for a todo item.


77-82: LGTM!

The Goals interface is correctly defined and includes all the necessary properties for a goal item.


84-87: LGTM!

The Schema type alias is correctly defined and includes the necessary entity types for the example usage function.


89-91: LGTM!

The SchemaNamed type alias is correctly defined and wraps the Schema type with a world property, as expected by the SDK.

Comment on lines 7 to 85
export async function getEventMessages<T extends SchemaType>(
client: torii.ToriiClient,
query: QueryType<T>,
callback: (response: { data?: QueryResult<T>; error?: Error }) => void,
limit: number = 100, // Default limit
offset: number = 0, // Default offset
options?: { logging?: boolean } // Logging option
): Promise<QueryResult<T>> {
const clause = convertQueryToClause(query);

console.log(clause);

let cursor = offset;
let continueFetching = true;
let allEntities: torii.Entities = {};

while (continueFetching) {
const toriiQuery: torii.Query = {
limit: limit,
offset: cursor,
clause,
};

console.log(toriiQuery);

try {
const entities = await client.getEventMessages(toriiQuery);

console.log("entities", entities);
if (options?.logging) {
console.log(`Fetched entities at offset ${cursor}:`, entities);
}

Object.assign(allEntities, entities);

const parsedEntities = parseEntities<T>(allEntities, query);

console.log("parsedEntities", parsedEntities);

callback({ data: parsedEntities });

if (Object.keys(entities).length < limit) {
continueFetching = false;
} else {
cursor += limit;
}
} catch (error) {
if (options?.logging) {
console.error("Error fetching entities:", error);
}
callback({ error: error as Error });
throw error;
}
}

if (options?.logging) {
console.log("All fetched entities:", allEntities);
}
return parseEntities<T>(allEntities, query);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider breaking down the function into smaller, more focused functions.

The getEventMessages function is quite large and could benefit from being broken down into smaller, more focused functions. This would improve readability, maintainability, and testability. For example, you could extract the logic for constructing the toriiQuery object and the logic for parsing the fetched entities into separate functions.

Comment on lines 23 to 79
while (continueFetching) {
const toriiQuery: torii.Query = {
limit: limit,
offset: cursor,
clause,
};

console.log(toriiQuery);

try {
const entities = await client.getEventMessages(toriiQuery);

console.log("entities", entities);
if (options?.logging) {
console.log(`Fetched entities at offset ${cursor}:`, entities);
}

Object.assign(allEntities, entities);

const parsedEntities = parseEntities<T>(allEntities, query);

console.log("parsedEntities", parsedEntities);

callback({ data: parsedEntities });

if (Object.keys(entities).length < limit) {
continueFetching = false;
} else {
cursor += limit;
}
} catch (error) {
if (options?.logging) {
console.error("Error fetching entities:", error);
}
callback({ error: error as Error });
throw error;
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a safeguard against infinite loops.

The while loop used to fetch messages in batches could potentially lead to an infinite loop if the server always returns the limit number of entities. Consider adding a maximum number of iterations or a timeout mechanism as a safeguard to prevent this from happening.

Comment on lines 53 to 78
} catch (error) {
if (options?.logging) {
console.error("Error fetching entities:", error);
}
callback({ error: error as Error });
throw error;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve error handling.

The error handling in the function could be improved. Currently, the function logs the error (if logging is enabled), invokes the callback with the error information, and then rethrows the error. It would be better to have a more consistent error handling approach, either by always rethrowing the error or by always handling it within the function. This would make the error handling behavior more predictable and easier to reason about.

Comment on lines 47 to 50
getEventMessages: (
query: QueryType<T>,
callback: (response: { data?: QueryResult<T>; error?: Error }) => void
) => Promise<QueryResult<T>>;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix the getEventMessages method implementation.

The getEventMessages method is incorrectly implemented, as it calls getEntities instead of a separate getEventMessages function.

Apply this diff to fix the implementation:

-    getEventMessages: (query, callback) =>
-        getEntities(client, query, callback),
+    getEventMessages: (query, callback) =>
+        getEventMessages(client, query, callback),

Ensure that a separate getEventMessages function is implemented in a separate file and imported at the top of this file.

Also applies to: 63-64

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Outside diff range and nitpick comments (1)
packages/sdk/readme.md (1)

1-4: Great start with the TODO section!

It's crucial to have a clear understanding of the use cases before starting the implementation. This will help ensure that the library meets the needs of the developers who will be using it.

If you need any help in brainstorming or defining the use cases, feel free to reach out. I'd be happy to collaborate and provide insights based on my experience with similar libraries.

Tools
Markdownlint

1-1: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between de370ab and 87e08cc.

Files selected for processing (5)
  • packages/sdk/readme.md (1 hunks)
  • packages/sdk/src/tests/convertQueryToClause.test.ts (1 hunks)
  • packages/sdk/src/convertQuerytoClause.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/types.ts (1 hunks)
Files skipped from review as they are similar to previous changes (3)
  • packages/sdk/src/tests/convertQueryToClause.test.ts
  • packages/sdk/src/convertQuerytoClause.ts
  • packages/sdk/src/types.ts
Additional context used
Markdownlint
packages/sdk/readme.md

1-1: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


7-7: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)


33-33: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)

Additional comments not posted (6)
packages/sdk/readme.md (2)

9-32: Excellent job defining the query types!

The 5 query types cover a wide range of use cases for fetching entities and their associated data. The descriptions provide a clear understanding of what each query type should do, making it easy for developers to choose the appropriate query for their needs.


35-42: Great work defining the subscription types!

The 2 subscription types cover the essential use cases for subscribing to updates on entities. The descriptions provide a clear understanding of what each subscription type should do, making it easy for developers to choose the appropriate subscription for their needs.

packages/sdk/src/index.ts (4)

25-66: LGTM!

The init function is well-structured and correctly initializes the client with the provided configuration options, contract definitions, and account. It returns an object containing the necessary methods for data interaction.


19-23: LGTM!

The createClient function correctly creates a client using the provided configuration options.


124-303: LGTM!

The exampleUsage function provides a comprehensive demonstration of how to use the initialized client for various queries and subscriptions. It covers different scenarios, including fetching all entities, querying specific entities by ID, filtering entities based on conditions, and handling errors. The examples are well-structured and easy to understand.


46-49: Fix the getEventMessages method implementation.

The getEventMessages method is incorrectly implemented, as it calls getEntities instead of a separate getEventMessages function.

Apply this diff to fix the implementation:

-    getEventMessages: (query, callback) =>
-        getEntities(client, query, callback),
+    getEventMessages: (query, callback) =>
+        getEventMessages(client, query, callback),

Ensure that a separate getEventMessages function is implemented in a separate file and imported at the top of this file.

Likely invalid or redundant comment.


It should be the go-to library for building onchain applications, from games to simple NFT websites. The library should provide comprehensive querying and subscription capabilities to interact with onchain data efficiently.

### Queries:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the trailing punctuation in the heading.

The static analysis tool Markdownlint has flagged the trailing punctuation in the heading. To adhere to the Markdown best practices, please remove the colon (:) at the end of the heading.

Apply this diff to fix the heading:

-### Queries:
+### Queries
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Queries:
### Queries
Tools
Markdownlint

7-7: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)

- Retrieves entities based on their hashed keys.
- This method is efficient for fetching entities when the hashed keys are known.

### Subscriptions:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the trailing punctuation in the heading.

The static analysis tool Markdownlint has flagged the trailing punctuation in the heading. To adhere to the Markdown best practices, please remove the colon (:) at the end of the heading.

Apply this diff to fix the heading:

-### Subscriptions:
+### Subscriptions
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Subscriptions:
### Subscriptions
Tools
Markdownlint

33-33: Punctuation: ':'
Trailing punctuation in heading

(MD026, no-trailing-punctuation)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range and nitpick comments (3)
examples/clients/react/react-sdk/src/App.tsx (2)

48-54: Consider moving the worldAddress to the configuration file or environment variables.

The database connection is correctly initialized using the init function from the SDK, and the configuration values are correctly imported from the dojoConfig.ts file.

However, the worldAddress is hardcoded, which may not be ideal for production use. Consider moving the worldAddress to the configuration file or environment variables for better maintainability and security.


91-98: Consider removing the placeholder button and implementing the actual game UI.

The JSX is correctly defined, and the App component is correctly exported as the default export.

However, the button currently logs a placeholder message to the console. Consider removing the placeholder button and implementing the actual game UI.

packages/sdk/src/execute.ts (1)

143-190: Remove commented-out code before merging.

The example usage code demonstrates the type-checking capabilities of the createWorldProxy function and serves as a good reference for developers. It showcases how to define contract definitions, create a world proxy, and invoke contract functions with type safety.

However, it's generally recommended to remove commented-out code before merging to keep the codebase clean and maintainable. Consider moving the example usage to documentation or a separate example file.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 87e08cc and d053a0e.

Files ignored due to path filters (1)
  • examples/dojo/dojo-starter/Scarb.lock is excluded by !**/*.lock
Files selected for processing (15)
  • examples/clients/react/react-sdk/src/App.tsx (1 hunks)
  • examples/dojo/dojo-starter/Scarb.toml (1 hunks)
  • examples/dojo/dojo-starter/manifests/dev/deployment/manifest.json (4 hunks)
  • examples/dojo/dojo-starter/manifests/dev/deployment/manifest.toml (2 hunks)
  • packages/sdk/src/tests/convertQueryToClause.test.ts (1 hunks)
  • packages/sdk/src/tests/convertQueryToEntityKeyClauses.test.ts (1 hunks)
  • packages/sdk/src/tests/parseEntities.test.ts (1 hunks)
  • packages/sdk/src/convertQueryToEntityKeyClauses.ts (1 hunks)
  • packages/sdk/src/convertQuerytoClause.ts (1 hunks)
  • packages/sdk/src/execute.ts (1 hunks)
  • packages/sdk/src/getEntities.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/parseEntities.ts (1 hunks)
  • packages/sdk/src/types.ts (1 hunks)
  • packages/torii-wasm/build.sh (1 hunks)
Files skipped from review as they are similar to previous changes (8)
  • examples/dojo/dojo-starter/Scarb.toml
  • packages/sdk/src/tests/convertQueryToClause.test.ts
  • packages/sdk/src/tests/convertQueryToEntityKeyClauses.test.ts
  • packages/sdk/src/tests/parseEntities.test.ts
  • packages/sdk/src/convertQueryToEntityKeyClauses.ts
  • packages/sdk/src/convertQuerytoClause.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/parseEntities.ts
Additional context used
Biome
packages/sdk/src/execute.ts

[error] 72-72: void is confusing outside a return type or a type parameter.

Unsafe fix: Use undefined instead.

(lint/suspicious/noConfusingVoidType)

Additional comments not posted (27)
packages/torii-wasm/build.sh (1)

7-7: LGTM!

Locking the build to a specific version of the dojo.c repository is a good practice for reproducibility. This change ensures that the build process retrieves a particular version, making it more deterministic and less prone to unexpected changes in the main branch.

packages/sdk/src/types.ts (8)

2-4: LGTM!

The AtLeastOne utility type is a clever way to create a union of all possible combinations where one property is required and the rest are optional. This can be very useful for creating more flexible interfaces.


6-6: LGTM!

The PrimitiveType is a simple and clear union of primitive types. It can be used effectively to restrict values to only these types.


8-12: LGTM!

The SchemaType provides a flexible structure for defining schemas with arbitrary nested properties. The use of indexed signatures allows for any string keys at both the top level and nested levels.


14-18: LGTM!

The QueryOptions type clearly defines the available options for controlling a query, with helpful comments explaining each property. The use of optional properties allows for flexibility in specifying these options.


20-33: LGTM!

The WhereOptions interface effectively extends QueryOptions to add support for specifying filter conditions. The use of a record with string keys allows for dynamic property names, and the defined comparison operators provide a good starting set for common filtering needs. The comment about adding more operators is a helpful note for future extensibility.


36-44: LGTM!

The QueryType is a powerful and flexible way to define the structure of a query based on a given SchemaType. The use of mapped types allows for creating a query object that mirrors the schema structure, with optional properties for each field. The $ property with WhereOptions enables specifying filter conditions on each field, and the AtLeastOne utility type ensures that at least one condition is provided. The optional entityIds property is a nice addition for querying specific entities directly.


46-52: LGTM!

The SubscriptionQueryType provides a clean way to define the structure of a subscription query based on a SchemaType. The use of mapped types to mirror the schema structure is consistent with QueryType, making it intuitive to use. Allowing either true or an array of strings for each property is a good approach for subscribing to either all changes or specific nested properties. The entityIds property is also useful for subscribing to specific entities.


54-62: LGTM!

The QueryResult type is a robust way to define the structure of a query result based on a SchemaType. The recursive nature of the type allows for handling deeply nested schemas, with QueryResult being applied to properties that are themselves SchemaTypes. The use of mapped types and arrays ensures that the result structure matches the schema, with each property being an array of objects corresponding to the nested schema. This type provides a strong foundation for working with query results in a type-safe manner.

packages/sdk/src/getEntities.ts (5)

1-5: LGTM!

The imports are relevant and required for the functionality of the getEntities function.


7-17: LGTM!

The getEntities function is well-defined with appropriate parameters and types. The use of a generic type parameter enhances its flexibility to work with different schema types.


18-63: LGTM!

The core logic of the getEntities function is well-implemented. It efficiently fetches entities in batches, handles pagination, and provides appropriate error handling and logging. The code segment aligns with the past review comments and addresses the redundant catch clauses.

The past review comments about redundant catch clauses are no longer applicable as the code has been updated to remove them.


65-67: LGTM!

Logging all fetched entities conditionally based on the logging option is a good practice for debugging purposes.


68-68: LGTM!

Returning the parsed entities using the parseEntities utility is appropriate and ensures consistent parsing of the fetched entities.

examples/clients/react/react-sdk/src/App.tsx (3)

1-9: LGTM!

The imports are correctly specified, and the import paths are valid.


10-46: LGTM!

The TypeScript interfaces and enums are correctly defined, and the naming conventions are consistent and descriptive. The Schema type is correctly defined to match the structure of the database.


56-90: LGTM!

The App component correctly utilizes the useEffect hook to asynchronously retrieve entities from the database, specifically querying for moves where the can_move property is true. The fetched data is correctly logged to the console, providing insights into the current game state. The error handling is correctly implemented to log any errors that occur during the query.

examples/dojo/dojo-starter/manifests/dev/deployment/manifest.toml (4)

26-26: Update references to the new DojoContract address.

The address for the DojoContract has been updated, indicating that the contract has been redeployed to a new address.

Ensure that any references to the DojoContract address in other parts of the system, such as configuration files or dependent contracts, are updated to use the new address.

To verify the references to the DojoContract address, run the following script:

Verification successful

Contract address successfully updated across the codebase

The verification process has confirmed that the DojoContract address has been successfully updated throughout the codebase. The new address (0x25d128c5fe89696e7e15390ea58927bbed4290ae46b538b28cfc7c2190e378b) is correctly reflected in the following files:

  • examples/dojo/dojo-starter/manifests/dev/deployment/manifest.toml
  • examples/dojo/dojo-starter/manifests/dev/deployment/manifest.json
  • packages/sdk/src/index.ts
  • packages/sdk/src/execute.ts

The old address was not found in any files, indicating a complete update. No further action is required.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify references to the `DojoContract` address in the codebase.

# Test: Search for occurrences of the old `DojoContract` address. 
# Expect: No occurrences of the old address.
rg --type cairo '0x36e4506b35e6dfb301d437c95f74b3e1f4f82da5d8841bec894bb8de29ec13'

Length of output: 112


Script:

#!/bin/bash
# Description: Search for both old and new `DojoContract` addresses in the codebase.

# Search for the old address
echo "Searching for the old address:"
rg '0x36e4506b35e6dfb301d437c95f74b3e1f4f82da5d8841bec894bb8de29ec13'

# Search for the new address
echo "Searching for the new address:"
rg '0x25d128c5fe89696e7e15390ea58927bbed4290ae46b538b28cfc7c2190e378b'

# Find all files with '.cairo' extension and search within them
echo "Searching in .cairo files:"
fd -e cairo -x grep -Hn '0x36e4506b35e6dfb301d437c95f74b3e1f4f82da5d8841bec894bb8de29ec13' {} \;
fd -e cairo -x grep -Hn '0x25d128c5fe89696e7e15390ea58927bbed4290ae46b538b28cfc7c2190e378b' {} \;

Length of output: 1070


6-7: Update references to the new WorldContract address.

The address and transaction_hash for the WorldContract have been updated, confirming that the contract has been redeployed to a new address.

Ensure that any references to the WorldContract address in other parts of the system, such as configuration files or dependent contracts, are updated to use the new address.

To verify the references to the WorldContract address, run the following script:

Verification successful

Contract address successfully updated throughout the codebase

The verification process has confirmed that the WorldContract address has been successfully updated across all relevant files in the codebase. The old contract address is no longer present, and the new address (0x5d475a9221f6cbf1a016b12400a01b9a89935069aecd57e9876fcb2a7bb29da) has been properly updated in the following locations:

  • Configuration files (manifest.toml, manifest.json)
  • README documentation
  • Client-side code (React component)

The new transaction hash is also correctly reflected in the manifest files. No further action is required regarding the contract address update.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash 
# Description: Verify references to the `WorldContract` address in the codebase.

# Test: Search for occurrences of the old `WorldContract` address.
# Expect: No occurrences of the old address.
rg --type cairo '0x403b5f047b8c4797139e30801e310473d99ca6877d19e0f27506f353f8f70f7'

Length of output: 113


Script:

#!/bin/bash
# Description: Search for old and new WorldContract addresses and transaction hashes

# Search for the old contract address
echo "Searching for old contract address:"
rg '0x403b5f047b8c4797139e30801e310473d99ca6877d19e0f27506f353f8f70f7'

# Search for the new contract address
echo "Searching for new contract address:"
rg '0x5d475a9221f6cbf1a016b12400a01b9a89935069aecd57e9876fcb2a7bb29da'

# Search for the new transaction hash
echo "Searching for new transaction hash:"
rg '0x7a14c0bc82a029b58e91ae4616d7a44056149036e7d535e2f3b6a5945a59efe'

# Find potentially relevant files and search within them
echo "Searching in potentially relevant files:"
fd -e cairo -e toml -e json | xargs rg '0x403b5f047b8c4797139e30801e310473d99ca6877d19e0f27506f353f8f70f7|0x5d475a9221f6cbf1a016b12400a01b9a89935069aecd57e9876fcb2a7bb29da'

Length of output: 1894


3-4: Review the WorldContract changes and their impact on the system.

The class_hash and original_class_hash for the WorldContract have been updated, suggesting that the contract has been modified or redeployed. This may introduce new functionality or fix issues in the previous version.

Ensure that any dependent contracts or systems interacting with the WorldContract are updated to accommodate any changes in the contract's interface or behavior.

To verify the impact of the WorldContract changes, run the following script:

Verification successful

The WorldContract changes appear to have limited impact on the smart contract code.

Based on the search results, the WorldContract is primarily referenced in SDK files and manifest configurations, rather than directly in the Cairo smart contract files. The changes to the class_hash and original_class_hash in the manifest file are likely related to deployment configuration updates.

Key observations:

  • No direct mentions of WorldContract were found in .cairo files.
  • No function calls or interactions with WorldContract were detected in the smart contract code.
  • References to WorldContract exist in TypeScript SDK files and manifest configurations.

While the smart contract logic doesn't seem to be directly affected, be aware that these changes may impact:

  1. The deployment process
  2. SDK interactions with the contract

The changes to the WorldContract in the manifest file appear to be isolated to deployment configuration and SDK interactions, with no direct impact on the Cairo smart contract code. However, ensure that the SDK and deployment scripts are updated accordingly if necessary.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the impact of the `WorldContract` changes on the system.

# Test 1: Search for imports or usage of the `WorldContract` in other contracts. 
# Expect: Occurrences of the `WorldContract` usage, if any.
rg --type cairo 'WorldContract'

# Test 2: Search for calls to the `WorldContract` functions in other contracts.
# Expect: Occurrences of the `WorldContract` function calls, if any.
ast-grep --lang cairo --pattern $'${WorldContract}.$_'

Length of output: 228


Script:

#!/bin/bash
# Description: Verify the impact of the `WorldContract` changes on the system using generic search methods.

# Test 1: Search for 'WorldContract' in all files
echo "Searching for 'WorldContract' in all files:"
rg 'WorldContract'

# Test 2: Find .cairo files and search for 'WorldContract' within them
echo -e "\nSearching for 'WorldContract' in .cairo files:"
find . -name "*.cairo" -type f | xargs grep -n 'WorldContract'

# Test 3: Search for potential function calls or interactions with 'WorldContract'
echo -e "\nSearching for potential 'WorldContract' function calls or interactions:"
rg '\bWorldContract\s*\.\s*\w+' --type-add 'cairo:*.cairo'

# Test 4: List all .cairo files for manual review if needed
echo -e "\nListing all .cairo files:"
find . -name "*.cairo" -type f

Length of output: 1521


27-28: Review the DojoContract changes and their impact on the system.

The class_hash and original_class_hash for the DojoContract have been updated, suggesting that the contract has been modified or redeployed. This may introduce new functionality or fix issues in the previous version.

Ensure that any dependent contracts or systems interacting with the DojoContract are updated to accommodate any changes in the contract's interface or behavior.

To verify the impact of the DojoContract changes, run the following script:

packages/sdk/src/execute.ts (4)

1-35: LGTM!

The type definitions and mappings provide a robust foundation for type-safe interaction with smart contract ABIs. The use of conditional types and mapped types ensures that the correct TypeScript types are inferred based on the ABI types.


37-91: LGTM!

The type definitions for contract definitions, function ABIs, and input/output mappings are well-structured and provide a type-safe representation of the contract's interface. The use of mapped types and conditional types ensures that the correct function types are inferred based on the contract's ABI.

Tools
Biome

[error] 72-72: void is confusing outside a return type or a type parameter.

Unsafe fix: Use undefined instead.

(lint/suspicious/noConfusingVoidType)


93-142: LGTM!

The createWorldProxy function is well-implemented and provides a convenient way to interact with smart contracts using a type-safe proxy object. The use of TypeScript's advanced type inference capabilities ensures that the correct input and output types are enforced when invoking contract functions.

The function iterates over the contract definitions, creates contract instances, and dynamically generates functions for each contract function based on its ABI. The resulting proxy object allows invoking contract functions using a clean and type-safe syntax.

Overall, the implementation is robust, maintainable, and provides a great developer experience for interacting with smart contracts.


72-72: Skipping static analysis hint.

The use of void at line 72 is appropriate in this context. It represents the absence of a return value when the output type is an empty array. Changing it to undefined would alter the semantics and could lead to unintended behavior.

The static analysis hint is a false positive and can be safely ignored.

Tools
Biome

[error] 72-72: void is confusing outside a return type or a type parameter.

Unsafe fix: Use undefined instead.

(lint/suspicious/noConfusingVoidType)

examples/dojo/dojo-starter/manifests/dev/deployment/manifest.json (2)

4-5: Verify the changes to the world contract.

The class_hash and original_class_hash for the world have been updated, indicating a change in the underlying contract implementation.

Please review the modifications to the world contract and ensure they align with the expected behavior and interactions within the system.


947-951: Update the event handling logic for the new entity_id field.

The StoreSetRecord event now includes a new entity_id field of type core::felt252. This field allows for the identification of entities in the event.

Please ensure that the event handling logic is updated to correctly process and utilize this new field as needed.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Outside diff range and nitpick comments (5)
packages/sdk/src/parseEntities.ts (1)

38-86: LGTM with a minor suggestion!

The parseEntities function correctly parses entities based on the provided schema type, handles invalid modelName formats gracefully, and ensures type safety using TypeScript generics. The implementation looks solid.

Consider extracting the modelName parsing logic into a separate function for better readability and reusability:

function parseModelName(modelName: string): [string, string] | null {
  const [schemaKey, modelKey] = modelName.split("-");
  return schemaKey && modelKey ? [schemaKey, modelKey] : null;
}

Then, you can use it like this:

- const [schemaKey, modelKey] = modelName.split("-") as [
-   keyof T,
-   string,
- ];
+ const parsedModelName = parseModelName(modelName);
+ if (!parsedModelName) {
+   if (options?.logging) {
+     console.warn(`Invalid modelName format: ${modelName}`);
+   }
+   continue;
+ }
+ const [schemaKey, modelKey] = parsedModelName as [keyof T, string];
examples/clients/react/react-sdk/src/App.tsx (3)

46-52: Consider making the worldAddress configurable.

The database connection is correctly initialized using the provided configuration. However, the worldAddress is currently hardcoded. Consider making it configurable to allow for flexibility and reusability of the component.


90-122: Consider storing the fetched entities in the component state.

The entity fetching logic is properly implemented using the useEffect hook, and the getEntities function is called with the appropriate query object. Error handling is in place to log any errors that occur during the process.

However, the fetched entities are not being used or stored in the component state. Consider storing them in the state using the useState hook for further usage in the component.


123-128: Update the button with actual functionality.

The button is correctly rendered using JSX syntax, and the onClick event is properly handled by logging a placeholder message to the console.

However, the button currently serves as a placeholder. Consider updating it with actual functionality based on the requirements of the component.

packages/sdk/src/convertQuerytoClause.ts (1)

99-116: LGTM with a minor suggestion.

The convertToPrimitive function correctly converts different types to their corresponding Torii primitives. It also throws an error for unsupported types, which is a good practice.

Consider the following minor improvements:

  1. Extend the function to handle more types as needed.
  2. Include the actual value in the error message for unsupported types to provide more context.
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between d053a0e and 7b58cd2.

Files ignored due to path filters (2)
  • packages/create-dojo/bin/index.js.map is excluded by !**/*.map
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
Files selected for processing (14)
  • examples/clients/react/react-sdk/src/App.tsx (1 hunks)
  • examples/dojo/dojo-starter/.github/workflows/test.yaml (1 hunks)
  • packages/create-dojo/bin/index.js (2 hunks)
  • packages/sdk/package.json (1 hunks)
  • packages/sdk/src/tests/convertQueryToClause.test.ts (1 hunks)
  • packages/sdk/src/tests/parseEntities.test.ts (1 hunks)
  • packages/sdk/src/convertQuerytoClause.ts (1 hunks)
  • packages/sdk/src/getEntities.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/parseEntities.ts (1 hunks)
  • packages/sdk/src/subscribeEntityQuery.ts (1 hunks)
  • packages/sdk/src/subscribeEventQuery.ts (1 hunks)
  • packages/sdk/src/types.ts (1 hunks)
  • packages/sdk/vitest.config.ts (1 hunks)
Files skipped from review due to trivial changes (1)
  • packages/create-dojo/bin/index.js
Files skipped from review as they are similar to previous changes (8)
  • examples/dojo/dojo-starter/.github/workflows/test.yaml
  • packages/sdk/package.json
  • packages/sdk/src/tests/convertQueryToClause.test.ts
  • packages/sdk/src/tests/parseEntities.test.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/subscribeEntityQuery.ts
  • packages/sdk/src/subscribeEventQuery.ts
  • packages/sdk/src/types.ts
Additional comments not posted (9)
packages/sdk/vitest.config.ts (1)

1-6: LGTM! This configuration file sets up the testing environment for the project.

The vitest.config.ts file is responsible for configuring the Vitest testing framework for the project. It utilizes the defineConfig function from vitest/config to create a configuration object and includes the wasm plugin from vite-plugin-wasm.

By including the wasm plugin in the configuration, the setup enables seamless integration and testing of WebAssembly modules alongside standard JavaScript code. This is particularly beneficial for projects that leverage WebAssembly for performance-critical tasks or functionalities.

The configuration is exported as the default export, allowing it to be easily consumed by the testing framework.

Overall, this configuration file is essential for setting up a robust testing environment and ensuring proper code coverage for the project.

packages/sdk/src/getEntities.ts (1)

52-58: Remove the redundant catch clause.

The catch clause on line 57 that rethrows the original error after invoking the callback is redundant and can lead to unhandled promise rejections. It is recommended to remove it.

Apply this diff to remove the redundant catch clause:

-            throw error;

This aligns with the previous review comments that flagged similar redundant catch clauses. Please ensure that the feedback is addressed to improve the error handling and code quality.

packages/sdk/src/parseEntities.ts (1)

26-36: LGTM!

The parseStruct function correctly handles both objects and maps as input, and it recursively parses nested structures by calling parseValue on each value. The implementation looks good.

examples/clients/react/react-sdk/src/App.tsx (5)

1-3: LGTM!

The imports are correct and necessary for the component.


5-6: LGTM!

The imports are correct and necessary for the component.


8-44: LGTM!

The TypeScript interfaces and enum are correctly defined and provide a clear structure for the game data.


54-88: LGTM!

The subscription logic is properly implemented using the useEffect hook, and the response is logged to the console. Error handling is in place to log any errors that occur during the subscription setup.


130-130: LGTM!

The App component is correctly exported as the default export.

packages/sdk/src/convertQuerytoClause.ts (1)

118-135: LGTM!

The convertOperator function is simple and easy to understand. It correctly maps the string operators to their corresponding Torii comparison operators and throws an error for unsupported operators.

Comment on lines 21 to 23
default:
return value.value;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handle unsupported types explicitly.

The default case in the switch statement returns the value.value directly, which could lead to unexpected behavior if an unsupported type is passed to the function.

Consider throwing an error in the default case to catch potential issues early:

  default:
-   return value.value;
+   throw new Error(`Unsupported type: ${value.type}`);
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
default:
return value.value;
}
default:
throw new Error(`Unsupported type: ${value.type}`);
}

Comment on lines 4 to 274
export function convertQueryToClause<T extends SchemaType>(
query: QueryType<T>,
operator: torii.LogicalOperator = "And"
): torii.Clause {
const clauses: torii.Clause[] = [];

for (const [namespace, models] of Object.entries(query)) {
if (namespace === "entityIds") continue; // Skip entityIds

if (models && typeof models === "object") {
for (const [model, modelData] of Object.entries(models)) {
const namespaceModel = `${namespace}-${model}`;

if (
modelData &&
typeof modelData === "object" &&
"$" in modelData
) {
const conditions = modelData.$;
if (
conditions &&
typeof conditions === "object" &&
"where" in conditions
) {
const whereClause = conditions.where;
if (whereClause && typeof whereClause === "object") {
for (const [member, memberValue] of Object.entries(
whereClause
)) {
if (
typeof memberValue === "object" &&
memberValue !== null
) {
for (const [op, val] of Object.entries(
memberValue
)) {
clauses.push({
Member: {
model: namespaceModel,
member,
operator: convertOperator(op),
value: convertToPrimitive(val),
},
});
}
} else {
clauses.push({
Member: {
model: namespaceModel,
member,
operator: "Eq", // Default to Eq
value: convertToPrimitive(
memberValue
),
},
});
}
}
}
}
} else {
// Handle the case where there are no conditions

return {
Keys: {
keys: [undefined],
pattern_matching: "FixedLen",
models: [namespaceModel],
},
};
}
}
}
}

// If there are clauses, combine them under a single Composite clause
if (clauses.length > 0) {
return {
Composite: {
operator: operator,
clauses: clauses,
},
};
}

// If there are no clauses, return an empty Composite
return {
Composite: {
operator: operator,
clauses: [],
},
};
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor the function to improve readability and maintainability.

The convertQueryToClause function is quite large and complex. Consider the following improvements:

  1. Refactor the function into smaller, more focused functions to improve readability and maintainability.
  2. Simplify the nested loops and conditionals by extracting them into separate functions.
  3. Improve error handling by throwing more specific errors with clear messages.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Outside diff range and nitpick comments (1)
examples/clients/react/react-sdk/src/App.tsx (1)

30-35: Improve error handling to provide more informative messages to the user.

Consider enhancing the error handling logic to provide more informative messages to the user. Instead of just logging the error to the console, you could display a user-friendly error message within the UI. This would help users understand what went wrong and potentially guide them towards resolving the issue.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 7b58cd2 and eb0fc22.

Files selected for processing (4)
  • examples/clients/react/react-sdk/src/App.tsx (1 hunks)
  • examples/clients/react/react-sdk/src/bindings.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/parseEntities.ts (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • packages/sdk/src/parseEntities.ts
Additional comments not posted (10)
examples/clients/react/react-sdk/src/bindings.ts (7)

1-6: LGTM!

The Moves interface is well-defined with appropriate property names and types. It effectively represents the player movement details.


8-11: LGTM!

The DirectionsAvailable interface is well-defined with appropriate property names and types. It effectively represents the available directions for a player.


13-16: LGTM!

The Position interface is well-defined with appropriate property names and types. It effectively represents a player's position using a Vec2 object.


18-24: LGTM!

The Direction enum is well-defined with appropriate values covering all the necessary movement directions.


26-29: LGTM!

The Vec2 interface is well-defined with appropriate property names and types for representing a 2D vector.


31-37: LGTM!

The Schema type provides a clear and organized structure for the game schema by grouping the game-related interfaces under the dojo_starter namespace.


38-39: LGTM!

The exports are consistent with the defined entities in the file, allowing them to be used in other files that import this module.

examples/clients/react/react-sdk/src/App.tsx (1)

1-147: LGTM!

The App component establishes a solid foundation for interacting with a game state managed by the Dojo Engine. It demonstrates how to set up real-time subscriptions and fetch initial data. The overall structure and functionality of the component are well-implemented.

packages/sdk/src/index.ts (2)

15-19: LGTM!

The createClient function is implemented correctly, creating a Torii client using the provided configuration.


21-74: Comprehensive initialization function.

The init function provides a robust initialization process for the SDK, setting up the Torii client and exposing various methods for data interaction. The use of TypeScript generics ensures type safety for the schema definition.

Comment on lines 110 to 143
return (
<div>
<h1>Game State</h1>
{entities.map((entity) => (
<div key={entity.entityId}>
<h2>Entity {entity.entityId}</h2>
<h3>Position</h3>
<p>
Player:{" "}
{entity.models.dojo_starter.Position?.player ?? "N/A"}
<br />
X: {entity.models.dojo_starter.Position?.vec.x ?? "N/A"}
<br />
Y: {entity.models.dojo_starter.Position?.vec.y ?? "N/A"}
</p>
<h3>Moves</h3>
<p>
Player:{" "}
{entity.models.dojo_starter.Moves?.player ?? "N/A"}
<br />
Can Move:{" "}
{entity.models.dojo_starter.Moves?.can_move?.toString() ??
"N/A"}
<br />
Last Direction:{" "}
{entity.models.dojo_starter.Moves?.last_direction ??
"N/A"}
<br />
Remaining:{" "}
{entity.models.dojo_starter.Moves?.remaining ?? "N/A"}
</p>
</div>
))}
</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider extracting the rendering logic into separate components.

To improve the readability and maintainability of the App component, consider extracting the rendering logic for individual entities into separate components. This would help keep the App component focused on managing the overall game state and subscriptions, while delegating the rendering responsibilities to dedicated components.

For example, you could create an EntityDetails component that receives an entity as a prop and renders its position and moves:

interface EntityDetailsProps {
  entity: ParsedEntity<Schema>;
}

function EntityDetails({ entity }: EntityDetailsProps) {
  return (
    <div>
      <h2>Entity {entity.entityId}</h2>
      {/* Render position */}
      {/* Render moves */}
    </div>
  );
}

Then, in the App component, you can simplify the rendering logic to:

return (
  <div>
    <h1>Game State</h1>
    {entities.map((entity) => (
      <EntityDetails key={entity.entityId} entity={entity} />
    ))}
  </div>
);

This separation of concerns would make the code more modular and easier to understand and maintain.

Comment on lines 70 to 71
getEventMessages: (query, callback) =>
getEntities(client, query, callback),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix the getEventMessages method implementation.

The getEventMessages method is incorrectly implemented, as it calls getEntities instead of a separate getEventMessages function.

Apply this diff to fix the implementation:

-    getEventMessages: (query, callback) =>
-        getEntities(client, query, callback),
+    getEventMessages: (query, callback) =>
+        getEventMessages(client, query, callback),

Ensure that a separate getEventMessages function is implemented in a separate file and imported at the top of this file.

Committable suggestion was skipped due to low confidence.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between eb0fc22 and 0abea55.

Files selected for processing (10)
  • examples/clients/react/react-sdk/src/App.tsx (1 hunks)
  • examples/clients/react/react-sdk/src/bindings.ts (1 hunks)
  • packages/sdk/src/tests/convertQueryToEntityKeyClauses.test.ts (1 hunks)
  • packages/sdk/src/convertQuerytoClause.ts (1 hunks)
  • packages/sdk/src/getEntities.ts (1 hunks)
  • packages/sdk/src/getEventMessages.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/subscribeEntityQuery.ts (1 hunks)
  • packages/sdk/src/subscribeEventQuery.ts (1 hunks)
  • packages/sdk/src/types.ts (1 hunks)
Files skipped from review as they are similar to previous changes (9)
  • examples/clients/react/react-sdk/src/App.tsx
  • examples/clients/react/react-sdk/src/bindings.ts
  • packages/sdk/src/tests/convertQueryToEntityKeyClauses.test.ts
  • packages/sdk/src/convertQuerytoClause.ts
  • packages/sdk/src/getEventMessages.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/subscribeEntityQuery.ts
  • packages/sdk/src/subscribeEventQuery.ts
  • packages/sdk/src/types.ts
Additional comments not posted (1)
packages/sdk/src/getEntities.ts (1)

74-80: Remove the redundant catch clause.

The catch clause on lines 74-80 that only rethrows the original error is redundant and can be confusing. It is recommended to remove it as per the past review comment.

Apply this diff to remove the redundant catch clause:

-        } catch (error) {
-            if (options?.logging) {
-                console.error("Error fetching entities:", error);
-            }
-            callback({ error: error as Error });
-            throw error;
-        }
+        }

console.error("Error fetching entities:", error);
}
callback({ error: error as Error });
throw error;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider removing the throw error statement.

The throw error statement on line 79 after invoking the callback with the error might not be necessary or desirable, as it could lead to unhandled promise rejections if not properly caught by the caller. Since the error is already being handled via the callback, consider removing this statement.

Apply this diff to remove the throw error statement:

-            throw error;
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
throw error;

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range and nitpick comments (1)
packages/sdk/src/types.ts (1)

36-49: LGTM!

The WhereOptions interface is correctly defined, extending QueryOptions and adding an optional where property. The where property is of type Record<string, {...}>, where the nested object type defines comparison operators like $eq, $neq, $gt, etc., with values of type PrimitiveType.

As mentioned in the comment, feel free to add more operators to the interface as needed for your specific use case.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 0abea55 and fc221a1.

Files selected for processing (8)
  • examples/clients/react/react-sdk/src/App.tsx (1 hunks)
  • packages/sdk/src/tests/convertQueryToEntityKeyClauses.test.ts (1 hunks)
  • packages/sdk/src/convertQueryToEntityKeyClauses.ts (1 hunks)
  • packages/sdk/src/getEntities.ts (1 hunks)
  • packages/sdk/src/getEventMessages.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/subscribeEntityQuery.ts (1 hunks)
  • packages/sdk/src/types.ts (1 hunks)
Files skipped from review as they are similar to previous changes (6)
  • examples/clients/react/react-sdk/src/App.tsx
  • packages/sdk/src/tests/convertQueryToEntityKeyClauses.test.ts
  • packages/sdk/src/convertQueryToEntityKeyClauses.ts
  • packages/sdk/src/getEventMessages.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/subscribeEntityQuery.ts
Additional comments not posted (9)
packages/sdk/src/getEntities.ts (3)

72-78: ** Remove the redundant catch clause.**

The catch clause on lines 72-78 that only rethrows the original error is redundant and can be confusing. It is recommended to remove it.

Apply this diff to remove the redundant catch clause:

-        } catch (error) {
-            if (options?.logging) {
-                console.error("Error fetching entities:", error);
-            }
-            callback({ error: error as Error });
-            throw error;
-        }
+        }

77-77: ** Consider removing the throw error statement.**

The throw error statement on line 77 after invoking the callback with the error might not be necessary or desirable, as it could lead to unhandled promise rejections if not properly caught by the caller. Since the error is already being handled via the callback, consider removing this statement.

Apply this diff to remove the throw error statement:

-            throw error;

29-85: LGTM!

The getEntities function is well-implemented and follows good practices:

  • It efficiently paginates through results using a while loop and cursor management.
  • It correctly uses a callback to report errors and data.
  • It logs the query and fetched entities if logging is enabled.
  • It parses the entities using the parseEntities utility before invoking the callback with the results.
  • It returns a promise that resolves to the standardized query result.
  • The function is well-documented with JSDoc comments.

Great job!

packages/sdk/src/types.ts (6)

1-2: LGTM!

The import statement is syntactically correct and necessary for using the ToriiClient type in the SDK interface.


6-8: LGTM!

The AtLeastOne utility type is correctly defined using mapped types and indexed access types. It can be useful for enforcing the presence of at least one property in an object type.


13-13: LGTM!

The PrimitiveType type alias is correctly defined as a union of string, number, and boolean, representing the primitive types that can be used in queries.


18-22: LGTM!

The SchemaType type alias is correctly defined as an object type with string keys and nested object types. It represents the structure of the schema and allows for any level of nesting and any value type in the nested objects.


27-31: LGTM!

The QueryOptions type alias is correctly defined with optional properties limit, offset, and entityId. It represents the options for querying the database, with limit and offset being of type number and entityId being of type string.


54-62: LGTM!

The QueryType type alias is correctly defined and represents complex queries for fetching data. It takes a generic type parameter T that extends SchemaType and is an intersection of an object type with an optional entityIds property of type string[] and a mapped type that maps over the keys of T and allows specifying WhereOptions for each nested property.

The use of the AtLeastOne utility type ensures that at least one property is specified in the WhereOptions object, providing flexibility in constructing queries.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between fc221a1 and 4d2d6e1.

Files selected for processing (2)
  • packages/sdk/src/example/index.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • packages/sdk/src/index.ts
Additional comments not posted (4)
packages/sdk/src/__example__/index.ts (4)

5-10: LGTM!

The Todo interface is well-defined with appropriate properties and types.


19-26: LGTM!

The Schema and SchemaNamed types are well-defined and match the structure of the data used in the example.


28-97: LGTM!

The exampleUsage function provides a clear and well-structured example of how to use the database API. It demonstrates initializing a connection, subscribing to entity queries, retrieving entities with a where clause, and includes appropriate error handling.


99-100: LGTM!

The exampleUsage function is invoked correctly, and any errors thrown by the function are caught and logged to the console.

Comment on lines 12 to 17
interface Goals {
id: string;
text: string;
done: boolean;
createdAt: number;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider refactoring to avoid duplication.

The Goals interface is identical to the Todo interface. Consider refactoring to avoid duplication.

One possible refactor is to define a base interface and extend it for Todo and Goals:

interface BaseItem {
  id: string;
  text: string;
  done: boolean;
  createdAt: number;
}

interface Todo extends BaseItem {}

interface Goals extends BaseItem {}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Outside diff range and nitpick comments (4)
packages/sdk/src/__example__/index.ts (1)

73-73: Remove the unnecessary comment.

The comment on line 73 mentions "done does not exist and no warning is thrown", but there is no done field in the PlayerModel interface. This comment seems irrelevant and can be removed to avoid confusion.

packages/sdk/src/convertQueryToEntityKeyClauses.ts (1)

1-168: Consider adding error handling and input validation.

While the code is well-structured and follows a clear logic flow, it could benefit from additional error handling and input validation. Consider the following suggestions:

  1. Validate the input parameters (query, schema) to ensure they are of the expected types and contain the required properties.
  2. Handle potential errors that may occur during the conversion process, such as missing or invalid data in the query or schema objects.
  3. Provide meaningful error messages or throw exceptions when encountering invalid or unexpected input.

Adding error handling and input validation will make the code more robust and help identify and diagnose issues more easily.

packages/sdk/src/types.ts (2)

8-10: Consider adding a test case for the AtLeastOne utility type.

To ensure the correctness and maintainability of the AtLeastOne utility type, consider adding a test case that verifies its behavior. The test case should cover scenarios where at least one property is present and ensure that the resulting type is as expected.

Here's an example test case using Jest:

// atLeastOne.test.ts

describe('AtLeastOne', () => {
  it('should ensure at least one property is present', () => {
    type TestType = {
      a?: string;
      b?: number;
      c?: boolean;
    };

    type TestResult = AtLeastOne<TestType>;

    // Valid usage
    const validObj1: TestResult = { a: 'hello' };
    const validObj2: TestResult = { b: 42 };
    const validObj3: TestResult = { c: true };
    const validObj4: TestResult = { a: 'hello', b: 42, c: true };

    // @ts-expect-error
    const invalidObj: TestResult = {}; // Should raise a type error
  });
});

This test case checks that the AtLeastOne type correctly enforces the presence of at least one property in the resulting type. It also includes an invalid usage scenario that should raise a type error.


122-205: Consider adding a method to the SDK interface for executing raw queries.

To provide more flexibility and cover advanced use cases, consider adding a method to the SDK interface that allows executing raw queries. This method would accept a raw query string and return the corresponding result.

Here's an example of how the method could be defined:

export interface SDK<T extends SchemaType> {
  // ...existing methods...

  /**
   * Executes a raw query and returns the result.
   *
   * @param {string} query - The raw query string to execute.
   * @param {Record<string, any>} [variables] - Optional variables to be used in the query.
   * @returns {Promise<any>} - A promise that resolves to the query result.
   */
  executeRawQuery: (query: string, variables?: Record<string, any>) => Promise<any>;
}

This executeRawQuery method takes a raw query string and an optional variables object for parameterized queries. It returns a promise that resolves to the query result.

Adding this method provides more control and flexibility to developers who need to execute complex or custom queries that may not be covered by the existing methods in the SDK interface.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 4d2d6e1 and c4c6d0c.

Files selected for processing (9)
  • packages/sdk/src/example/index.ts (1 hunks)
  • packages/sdk/src/tests/convertQueryToClause.test.ts (1 hunks)
  • packages/sdk/src/tests/convertQueryToEntityKeyClauses.test.ts (1 hunks)
  • packages/sdk/src/tests/parseEntities.test.ts (1 hunks)
  • packages/sdk/src/convertQueryToEntityKeyClauses.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/subscribeEntityQuery.ts (1 hunks)
  • packages/sdk/src/subscribeEventQuery.ts (1 hunks)
  • packages/sdk/src/types.ts (1 hunks)
Files skipped from review as they are similar to previous changes (6)
  • packages/sdk/src/tests/convertQueryToClause.test.ts
  • packages/sdk/src/tests/convertQueryToEntityKeyClauses.test.ts
  • packages/sdk/src/tests/parseEntities.test.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/subscribeEntityQuery.ts
  • packages/sdk/src/subscribeEventQuery.ts
Additional comments not posted (7)
packages/sdk/src/__example__/index.ts (2)

34-54: LGTM!

The schema constant is correctly typed and initialized with default values for each entity in the world object.


56-65: Verify the configuration values before using them.

The exampleUsage function takes configuration values like rpcUrl, toriiUrl, relayUrl, and worldAddress as strings. It's a good practice to verify these values before using them to ensure they are valid and properly formatted.

Consider adding validation checks for these configuration values, such as checking for non-empty strings, valid URL formats, etc.

packages/sdk/src/convertQueryToEntityKeyClauses.ts (4)

1-2: LGTM!

The imports are correctly specified and follow the expected naming conventions.


4-61: Excellent work on the convertQueryToEntityKeyClauses function!

The function is well-structured, follows a clear logic flow, and effectively converts the subscription query to an array of EntityKeysClause objects. The code is readable, modular, and handles various scenarios appropriately.

Some key highlights:

  • Destructuring of entityIds and handling its presence correctly.
  • Iterating over namespaces and models to create clauses.
  • Invoking helper functions createClause and createClauseFromWhere based on the value type.
  • Comprehensive JSDoc comments providing clear documentation.

Overall, this function is a solid implementation that achieves its intended purpose efficiently.


63-92: The createClause function is implemented effectively.

The function handles the creation of EntityKeysClause objects based on the provided namespaceModel and value parameters. It correctly distinguishes between empty and non-empty arrays, setting the appropriate pattern_matching property.

The use of a ternary operator or if-else statement could potentially simplify the logic, but the current implementation is clear and readable.


94-168: The createClauseFromWhere function is well-structured and handles the creation of EntityKeysClause objects based on the provided where conditions.

Some notable aspects of the implementation:

  • Initializing the keys array with undefined placeholders based on the fieldOrder length.
  • Iterating over the whereOptions and populating the keys array based on the field index.
  • Handling various condition operators ($eq, $neq, $gt, $gte, $lt, $lte) and assigning the corresponding values to the keys array.
  • Returning the EntityKeysClause object with the populated keys array and appropriate pattern_matching property.

The function effectively combines the where conditions with the fieldOrder to create the desired EntityKeysClause object.

packages/sdk/src/types.ts (1)

1-205: Comprehensive and well-structured type definitions!

The file introduces a robust set of type definitions that enhance type safety and provide a structured approach to defining schemas, queries, and results within the SDK. The types are well-documented with clear explanations of their purpose and usage.

Key highlights:

  • PrimitiveType and ModelDefinition establish a foundation for defining basic data types and model structures.
  • SchemaType allows for the creation of complex, nested schemas.
  • QueryOptions and WhereOptions provide flexibility in specifying query parameters and conditional filters.
  • QueryType enables the construction of type-safe queries based on the defined schema.
  • QueryResult and StandardizedQueryResult ensure structured and consistent representation of query results.
  • The SDK interface outlines essential methods for interacting with the DojoEngine, including entity subscriptions, event queries, and data retrieval.

The type definitions are comprehensive and cover a wide range of scenarios, promoting a type-safe and structured approach to data management within the SDK.

Comment on lines 6 to 11
export interface PlayerModel {
fieldOrder: string[];
id: string;
name: string;
score: number;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider extracting common fields into a base interface.

The PlayerModel, GameModel, and ItemModel interfaces share common fields like fieldOrder and id. Consider extracting these common fields into a base interface to avoid duplication and improve maintainability.

For example:

interface BaseModel {
  fieldOrder: string[];
  id: string;
}

export interface PlayerModel extends BaseModel {
  name: string;
  score: number;
}

export interface GameModel extends BaseModel {
  status: string;
}

export interface ItemModel extends BaseModel {
  type: string;
  durability: number;
}

Also applies to: 13-17, 19-24

Comment on lines 98 to 181
try {
const entities = await db.getEntities(
{
world: {
item: {
$: {
where: {
type: { $eq: "sword" },
durability: { $lt: 5 },
},
},
},
game: {
$: {
where: {
status: { $eq: "completed" },
},
},
},
},
},
(resp) => {
if (resp.error) {
console.error(
"Error querying completed important todos:",
resp.error.message
);
return;
}
if (resp.data) {
console.log(
"Completed important todos:",
resp.data.map((a) => a.models)
);
}
}
);
console.log("Queried entities:", entities);
} catch (error) {
console.error("Error querying entities:", error);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handle the case when no entities are found.

The getEntities function is used to retrieve entities based on the provided query. However, the code doesn't handle the case when no entities are found matching the query criteria.

Consider adding a check to handle the scenario when resp.data is an empty array. You can log a message indicating that no entities were found or take any other appropriate action.

if (resp.data) {
  if (resp.data.length === 0) {
    console.log("No entities found matching the query criteria.");
  } else {
    console.log("Queried entities:", resp.data.map((a) => a.models));
  }
}

}

// Call the example usage function
exampleUsage().catch(console.error);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add error handling for the exampleUsage function.

The exampleUsage function is called at the end of the file, and any errors thrown by it are caught and logged using console.error. However, it's a good practice to handle errors within the exampleUsage function itself to provide more specific error messages and handle different error scenarios appropriately.

Consider adding a try-catch block inside the exampleUsage function to catch and handle any errors that may occur during its execution.

async function exampleUsage() {
  try {
    // Existing code...
  } catch (error) {
    console.error("Error in exampleUsage:", error);
    // Handle the error appropriately
  }
}

Comment on lines 122 to 166
"Error querying completed important todos:",
resp.error.message
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix the inconsistency in the error message.

The error message in the console.error statement on lines 122-123 mentions "completed important todos", but the query is actually for items and games. Update the error message to accurately reflect the queried entities.

- console.error("Error querying completed important todos:", resp.error.message);
+ console.error("Error querying items and games:", resp.error.message);
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"Error querying completed important todos:",
resp.error.message
"Error querying items and games:",
resp.error.message

Comment on lines 67 to 139
db.subscribeEntityQuery(
{
world: {
player: {
$: {
where: {
// done does not exisst and no warning is thrown
name: { $eq: "Alice" },
score: { $gt: 10 },
},
},
},
},
},
(resp) => {
if (resp.error) {
console.error(
"Error querying todos and goals:",
resp.error.message
);
return;
}
if (resp.data) {
console.log(
"Queried todos and goals:",
resp.data.map((a) => a.models.world)
);
}
}
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix the typo in the error message.

The error message in the console.error statement on line 83 mentions "todos and goals", but the query is actually for players. Update the error message to accurately reflect the queried entity.

- console.error("Error querying todos and goals:", resp.error.message);
+ console.error("Error querying players:", resp.error.message);
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
db.subscribeEntityQuery(
{
world: {
player: {
$: {
where: {
// done does not exisst and no warning is thrown
name: { $eq: "Alice" },
score: { $gt: 10 },
},
},
},
},
},
(resp) => {
if (resp.error) {
console.error(
"Error querying todos and goals:",
resp.error.message
);
return;
}
if (resp.data) {
console.log(
"Queried todos and goals:",
resp.data.map((a) => a.models.world)
);
}
}
);
db.subscribeEntityQuery(
{
world: {
player: {
$: {
where: {
// done does not exisst and no warning is thrown
name: { $eq: "Alice" },
score: { $gt: 10 },
},
},
},
},
},
(resp) => {
if (resp.error) {
console.error(
"Error querying players:",
resp.error.message
);
return;
}
if (resp.data) {
console.log(
"Queried todos and goals:",
resp.data.map((a) => a.models.world)
);
}
}
);

Comment on lines 1 to 194
*/
function createClause(
namespaceModel: string,
value: string[]
): torii.EntityKeysClause | undefined {
if (Array.isArray(value) && value.length === 0) {
return {
Keys: {
keys: [undefined],
pattern_matching: "VariableLen",
models: [namespaceModel],
},
};
} else if (Array.isArray(value)) {
return {
Keys: {
keys: value,
pattern_matching: "FixedLen",
models: [namespaceModel],
},
};
}
return undefined;
}

/**
* Creates an EntityKeysClause based on the provided where conditions.
* Orders the keys array based on the fieldOrder from the schema,
* inserting undefined placeholders where necessary.
*
* @param namespaceModel - The combined namespace and model string.
* @param whereOptions - The where conditions from the query.
* @param fieldOrder - The defined order of fields for the model.
* @returns An EntityKeysClause or undefined.
*/
function createClauseFromWhere(
namespaceModel: string,
whereOptions?: Record<
string,
{
$eq?: any;
$neq?: any;
$gt?: any;
$gte?: any;
$lt?: any;
$lte?: any;
}
>,
fieldOrder: string[] = []
): torii.EntityKeysClause | undefined {
if (!whereOptions || Object.keys(whereOptions).length === 0) {
return {
Keys: {
keys: Array(fieldOrder.length).fill(undefined),
pattern_matching: "VariableLen",
models: [namespaceModel],
},
};
}

// Initialize keys array with undefined placeholders
const keys: (string | undefined)[] = Array(fieldOrder.length).fill(
undefined
);

Object.entries(whereOptions).forEach(([field, condition]) => {
// Find the index of the field in the fieldOrder
const index = fieldOrder.indexOf(field);
if (index !== -1) {
// Assign value without operator prefixes
if (condition.$eq !== undefined) {
keys[index] = condition.$eq.toString();
}
if (condition.$neq !== undefined) {
keys[index] = condition.$neq.toString();
}
if (condition.$gt !== undefined) {
keys[index] = condition.$gt.toString();
}
if (condition.$gte !== undefined) {
keys[index] = condition.$gte.toString();
}
if (condition.$lt !== undefined) {
keys[index] = condition.$lt.toString();
}
if (condition.$lte !== undefined) {
keys[index] = condition.$lte.toString();
}
// Add more operators as needed
}
});

return {
Keys: {
keys: keys,
pattern_matching: "VariableLen",
models: [namespaceModel],
},
};
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding unit tests to ensure the correctness of the conversion logic.

To maintain the reliability and correctness of the convertQueryToEntityKeyClauses function and its helper functions, it is recommended to add unit tests. Unit tests will help verify the expected behavior of the functions under different scenarios and input combinations.

Some test cases to consider:

  • Test with various query structures and verify the generated EntityKeysClause array.
  • Test edge cases, such as empty queries, queries with missing or invalid properties, and queries with complex nested structures.
  • Test the handling of different value types (entityIds, arrays, objects with where conditions) and ensure the correct clauses are generated.
  • Test the ordering of keys based on the provided fieldOrder in the createClauseFromWhere function.

By adding comprehensive unit tests, you can ensure the stability and correctness of the conversion logic and catch any potential bugs or regressions early in the development process.

Do you want me to generate some example unit test cases to get you started?

Comment on lines 54 to 117
export interface WhereOptions<TModel> extends QueryOptions {
where?: {
[P in keyof TModel]?: {
$eq?: TModel[P];
$neq?: TModel[P];
$gt?: TModel[P];
$gte?: TModel[P];
$lt?: TModel[P];
$lte?: TModel[P];
};
};
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enhance the WhereOptions type to support nested conditions.

Consider extending the WhereOptions type to allow for nested conditions, enabling more complex querying scenarios. This can be achieved by recursively applying the WhereOptions type to nested properties.

Here's an updated version of the WhereOptions type that supports nested conditions:

export type NestedValue<T> = T extends object ? WhereOptions<T> : T;

export interface WhereOptions<TModel> extends QueryOptions {
  where?: {
    [P in keyof TModel]?: {
      $eq?: NestedValue<TModel[P]>;
      $neq?: NestedValue<TModel[P]>;
      $gt?: NestedValue<TModel[P]>;
      $gte?: NestedValue<TModel[P]>;
      $lt?: NestedValue<TModel[P]>;
      $lte?: NestedValue<TModel[P]>;
    };
  };
}

In this updated version, the NestedValue utility type is introduced to recursively apply the WhereOptions type to nested properties. If a property is an object, it will be wrapped with WhereOptions, allowing for nested conditions. Otherwise, the original property type is used.

This enhancement enables more flexible and powerful querying capabilities, as it supports conditions on nested properties within the data model.

@@ -0,0 +1,205 @@
// packages/sdk/src/types.ts

import * as torii from "@dojoengine/torii-client";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

Add "@dojoengine/torii-client" to package.json and create a lock file

The import statement import * as torii from "@dojoengine/torii-client"; is correct and widely used across the codebase. However, there are some important issues to address:

  • "@dojoengine/torii-client" is not listed in package.json as a dependency.
  • No lock file (yarn.lock or package-lock.json) was found in the project.

To ensure proper dependency management and consistent installations:

  1. Add "@dojoengine/torii-client" to package.json as a dependency.
  2. Run npm install or yarn install to create a lock file.
  3. Commit both the updated package.json and the new lock file to version control.

Additionally, please review your team's dependency management practices to prevent similar issues in the future.

Analysis chain

Verify the import statement for the Torii client.

Please ensure that the import statement import * as torii from "@dojoengine/torii-client"; correctly references the Torii client package. Double-check the package name and version to avoid any potential issues.

Run the following script to verify the import statement:

If the script execution is successful, the import statement is valid. If it fails, please address the reported issues.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash

# Check if the "@dojoengine/torii-client" package is installed
if ! npm ls @dojoengine/torii-client >/dev/null 2>&1; then
  echo "The '@dojoengine/torii-client' package is not installed."
  exit 1
fi

# Check if the imported package version matches the installed version
installed_version=$(npm ls @dojoengine/torii-client | grep @dojoengine/torii-client | awk '{print $2}')
imported_version=$(rg --type typescript -o -U --pcre2 'import \* as torii from "@dojoengine/torii-client";\s+//\s+@version\s+(\S+)' | awk '{print $NF}')

if [[ "$installed_version" != "$imported_version" ]]; then
  echo "The imported version ($imported_version) does not match the installed version ($installed_version) of the '@dojoengine/torii-client' package."
  exit 1
fi

echo "The import statement for the Torii client is valid."

Length of output: 171


Script:

#!/bin/bash

# Check package.json for the dependency
echo "Checking package.json for @dojoengine/torii-client:"
rg -i "@dojoengine/torii-client" package.json

# Look for lock files and check for the package
echo -e "\nChecking lock files for @dojoengine/torii-client:"
if [ -f "yarn.lock" ]; then
  echo "Found yarn.lock:"
  rg -i "@dojoengine/torii-client" yarn.lock
elif [ -f "package-lock.json" ]; then
  echo "Found package-lock.json:"
  rg -i "@dojoengine/torii-client" package-lock.json
else
  echo "No lock file found."
fi

# Search for uses of the package in the codebase
echo -e "\nSearching for uses of @dojoengine/torii-client in the codebase:"
rg -i "@dojoengine/torii-client" --type ts --type js

Length of output: 2650

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range and nitpick comments (1)
packages/sdk/src/convertQuerytoClause.ts (1)

1-267: Consider adding unit tests.

To ensure the correctness and reliability of the convertQueryToClause, convertToPrimitive, and convertOperator functions, it is recommended to add unit tests that cover various scenarios and edge cases. This will help catch any potential bugs and regressions in the future.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between c4c6d0c and f1b0d97.

Files selected for processing (10)
  • packages/sdk/src/example/index.ts (1 hunks)
  • packages/sdk/src/tests/convertQueryToClause.test.ts (1 hunks)
  • packages/sdk/src/tests/convertQueryToEntityKeyClauses.test.ts (1 hunks)
  • packages/sdk/src/convertQueryToEntityKeyClauses.ts (1 hunks)
  • packages/sdk/src/convertQuerytoClause.ts (1 hunks)
  • packages/sdk/src/getEntities.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/subscribeEntityQuery.ts (1 hunks)
  • packages/sdk/src/subscribeEventQuery.ts (1 hunks)
  • packages/sdk/src/types.ts (1 hunks)
Files skipped from review as they are similar to previous changes (7)
  • packages/sdk/src/example/index.ts
  • packages/sdk/src/tests/convertQueryToClause.test.ts
  • packages/sdk/src/tests/convertQueryToEntityKeyClauses.test.ts
  • packages/sdk/src/convertQueryToEntityKeyClauses.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/subscribeEntityQuery.ts
  • packages/sdk/src/subscribeEventQuery.ts
Additional comments not posted (11)
packages/sdk/src/getEntities.ts (3)

1-86: Comprehensive review of the getEntities function:

  1. Function Signature and Documentation:

    • The function is well-documented with JSDoc comments, clearly explaining the purpose, parameters, return value, and providing an example of usage.
    • The use of TypeScript generics and types enhances the type safety and readability of the code.
  2. Pagination and Entity Fetching:

    • The function efficiently handles pagination by using a while loop and cursor management, allowing it to fetch entities in manageable chunks.
    • The use of Object.assign to merge entities is appropriate for accumulating results across multiple fetches.
    • The function correctly checks if the number of fetched entities is less than the limit to determine when to stop fetching.
  3. Error Handling and Callbacks:

    • The function uses a callback to report the fetched entities or any errors encountered, which is consistent with Node.js conventions.
    • Errors are caught and passed to the callback, providing a standardized way to handle errors.
    • The use of optional chaining (options?.logging) is a good practice to safely access the logging option.
  4. Logging and Debugging:

    • The function includes logging statements to output the fetched entities and any errors encountered, which can be helpful for debugging purposes.
    • The logging is controlled by an optional logging flag, allowing the caller to enable or disable logging as needed.
  5. Code Organization and Readability:

    • The code is well-structured and follows a logical flow, making it easy to understand and maintain.
    • The use of meaningful variable names and consistent formatting enhances the readability of the code.

Suggestions:

  1. Consider removing the throw error statement on line 78 after invoking the callback with the error. Since the error is already being handled via the callback, rethrowing it could lead to unhandled promise rejections if not properly caught by the caller.

  2. If the parseEntities function is expensive or has side effects, you might want to consider moving the call on line 85 inside the if (options?.logging) block to avoid unnecessary parsing when logging is disabled.

Overall, the getEntities function is well-implemented, follows best practices, and provides a robust way to fetch entities from the Torii client based on a provided query. The suggestions mentioned above are minor optimizations and can be considered based on the specific requirements and constraints of the project.


73-79: ** Remove the redundant catch clause.**

The catch clause on lines 73-79 that only rethrows the original error is redundant and can be confusing. It is recommended to remove it.

Apply this diff to remove the redundant catch clause:

-        } catch (error) {
-            if (options?.logging) {
-                console.error("Error fetching entities:", error);
-            }
-            callback({ error: error as Error });
-            throw error;
-        }
+        }

78-78: ** Consider removing the throw error statement.**

The throw error statement on line 78 after invoking the callback with the error might not be necessary or desirable, as it could lead to unhandled promise rejections if not properly caught by the caller. Since the error is already being handled via the callback, consider removing this statement.

Apply this diff to remove the throw error statement:

-            throw error;
packages/sdk/src/types.ts (3)

3-3: ****

The import statement for the Torii client is correct. However, please ensure that "@dojoengine/torii-client" is listed as a dependency in package.json and a lock file is created by running npm install or yarn install. This will prevent potential issues with dependency management and ensure consistent installations across different environments.


5-138: LGTM!

The type definitions are comprehensive and well-structured. They cover the essential aspects of the schema, queries, and results, providing a solid foundation for type safety and data integrity within the SDK.

Some key highlights:

  • The PrimitiveType and ModelDefinition types ensure that the schema adheres to a consistent structure.
  • The SchemaType allows for defining complex, nested schemas.
  • The QueryOptions, SubscriptionWhereOptions, and QueryWhereOptions interfaces provide flexibility in specifying query parameters and conditions.
  • The SubscriptionQueryType and QueryType enable the construction of type-safe queries based on the schema.
  • The QueryResult, StandardizedQueryResult, and ParsedEntity types ensure that the query results conform to the expected structure and types.

Overall, these type definitions demonstrate a well-thought-out design that promotes type safety, maintainability, and ease of use for developers working with the SDK.


140-228: LGTM!

The SDK interface is well-defined and provides a clear contract for interacting with the DojoEngine. It encapsulates the essential functionality required for subscribing to entity updates, fetching entities, and retrieving event messages.

Some notable aspects:

  • The interface is generic, allowing it to be parameterized with a specific schema type, ensuring type safety throughout the SDK.
  • The subscribeEntityQuery and subscribeEventQuery methods enable real-time updates by subscribing to entity and event queries, respectively. They return a promise that resolves to a Torii subscription, providing flexibility for managing the subscription lifecycle.
  • The getEntities and getEventMessages methods allow for fetching entities and event messages based on the provided query. They support pagination through the limit and offset parameters and provide an optional options parameter for enabling logging.
  • The callback parameter in the methods ensures that the response, including data and potential errors, can be handled asynchronously.
  • The return types of the methods are well-defined, leveraging the StandardizedQueryResult type to provide a consistent and predictable structure for the returned data.

The interface is well-documented with JSDoc comments, providing clear explanations of each method's purpose, parameters, and return types. This enhances the usability and maintainability of the SDK.

Overall, the SDK interface is a solid foundation for building a robust and type-safe SDK for interacting with the DojoEngine.

packages/sdk/src/convertQuerytoClause.ts (5)

1-3: LGTM!

The imports are correctly specified and follow the proper syntax.


5-27: Excellent documentation!

The JSDoc comment provides a clear and comprehensive explanation of the convertQueryToClause function, including its purpose, parameters, return value, and a usage example. This level of documentation enhances the code's readability and maintainability.


209-237: LGTM!

The convertToPrimitive function correctly converts values to Torii primitive types based on their JavaScript types. The function is well-documented with JSDoc comments, providing clear explanations of its purpose, parameters, return value, and a usage example.


239-267: LGTM!

The convertOperator function correctly maps query operators to their corresponding Torii comparison operators. The function is well-documented with JSDoc comments, providing clear explanations of its purpose, parameters, return value, and a usage example.


28-207: Consider refactoring the function to improve readability and maintainability.

The convertQueryToClause function is quite large and complex. Consider the following improvements:

  1. Extract the logic for handling $is conditions and other conditions into separate functions to reduce the function's complexity and improve readability.
  2. Use more descriptive variable names to enhance code clarity. For example, op could be renamed to operator, and val could be renamed to value.
  3. Add comments to explain the purpose of each major code block within the function to improve code comprehension.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range and nitpick comments (1)
packages/sdk/src/types.ts (1)

140-230: Excellent work on the SDK interface!

The SDK interface provides a clean and intuitive API for interacting with the DojoEngine. The methods for subscribing to entity updates and event messages, as well as fetching entities and event messages, are well-defined and include appropriate type annotations. The use of generic types ensures type safety and allows for seamless integration with the schema type.

A few minor suggestions for further improvement:

  1. Consider adding JSDoc comments to the options parameter in the getEntities and getEventMessages methods to clarify the purpose of the logging option.

  2. Consider adding a dispose method to the SDK interface to allow for proper cleanup of resources when the SDK is no longer needed.

Overall, the SDK interface is well-designed and provides a solid foundation for building a robust and type-safe SDK for the DojoEngine.

Apply this diff to implement the suggestions:

/**
 * SDK interface for interacting with the DojoEngine.
 *
 * @template T - The schema type.
 */
export interface SDK<T extends SchemaType> {
  // ...

  /**
   * Fetches entities from the Torii client based on the provided query.
   *
   * @template T - The schema type.
   * @param {SubscriptionQueryType<T>} query - The query object used to filter entities.
   * @param {(response: { data?: StandardizedQueryResult<T>; error?: Error }) => void} callback - The callback function to handle the response.
   * @param {number} [limit=100] - The maximum number of entities to fetch per request. Default is 100.
   * @param {number} [offset=0] - The offset to start fetching entities from. Default is 0.
+  * @param {{ logging?: boolean }} [options] - Optional settings.
+  * @param {boolean} [options.logging] - If true, enables logging of the fetching process. Default is false.
   * @returns {Promise<StandardizedQueryResult<T>>} - A promise that resolves to the standardized query result.
   */
  getEntities: (
    query: QueryType<T>,
    callback: (response: {
      data?: StandardizedQueryResult<T>;
      error?: Error;
    }) => void,
    limit?: number,
    offset?: number,
    options?: { logging?: boolean }
  ) => Promise<StandardizedQueryResult<T>>;

  /**
   * Fetches event messages from the Torii client based on the provided query.
   *
   * @template T - The schema type.
   * @param {QueryType<T>} query - The query object used to filter event messages.
   * @param {(response: { data?: StandardizedQueryResult<T>; error?: Error }) => void} callback - The callback function to handle the response.
   * @param {number} [limit=100] - The maximum number of event messages to fetch per request. Default is 100.
   * @param {number} [offset=0] - The offset to start fetching event messages from. Default is 0.
+  * @param {{ logging?: boolean }} [options] - Optional settings.
+  * @param {boolean} [options.logging] - If true, enables logging of the fetching process. Default is false.
   * @returns {Promise<StandardizedQueryResult<T>>} - A promise that resolves to the standardized query result.
   */
  getEventMessages: (
    query: QueryType<T>,
    callback: (response: {
      data?: StandardizedQueryResult<T>;
      error?: Error;
    }) => void,
    limit?: number,
    offset?: number,
    options?: { logging?: boolean }
  ) => Promise<StandardizedQueryResult<T>>;

+ /**
+  * Disposes the SDK and cleans up any resources.
+  */
+ dispose: () => void;
}
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between f1b0d97 and b373dd0.

Files selected for processing (6)
  • examples/clients/react/react-sdk/src/App.tsx (1 hunks)
  • examples/clients/react/react-sdk/src/bindings.ts (1 hunks)
  • packages/sdk/src/convertQueryToEntityKeyClauses.ts (1 hunks)
  • packages/sdk/src/index.ts (1 hunks)
  • packages/sdk/src/subscribeEntityQuery.ts (1 hunks)
  • packages/sdk/src/types.ts (1 hunks)
Files skipped from review as they are similar to previous changes (5)
  • examples/clients/react/react-sdk/src/App.tsx
  • examples/clients/react/react-sdk/src/bindings.ts
  • packages/sdk/src/convertQueryToEntityKeyClauses.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/subscribeEntityQuery.ts
Additional comments not posted (2)
packages/sdk/src/types.ts (2)

3-3: ****

The import statement for the Torii client is correct. However, please ensure that "@dojoengine/torii-client" is listed as a dependency in package.json and a lock file is created by running npm install or yarn install. This will prevent potential issues with dependency management and ensure consistent installations across different environments.


5-138: LGTM!

The type definitions are comprehensive and well-structured. They provide a solid foundation for building a type-safe SDK. The use of utility types like AtLeastOne and PrimitiveType enhances the flexibility and robustness of the type system. The separation of SubscriptionQueryType and QueryType allows for fine-grained control over subscription and query operations. The ParsedEntity type ensures that the data adheres to the schema's field types, promoting type safety throughout the SDK.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range and nitpick comments (1)
examples/dojo/dojo-starter/manifests/dev/deployment/manifest.json (1)

947-951: Consider the implications of adding the entity_id field to the StoreSetRecord event.

The addition of the entity_id field to the StoreSetRecord event suggests that the event now includes more granular information about the specific entity being set. This change may impact how event data is processed and consumed by downstream systems.

Verify that any existing event handlers, indexers, or analytics pipelines are updated to accommodate this new field. Ensure that the inclusion of entity_id aligns with the intended use cases and doesn't introduce any unintended side effects or performance overhead.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between b373dd0 and 4effc6b.

Files selected for processing (3)
  • examples/clients/react/react-sdk/src/App.tsx (1 hunks)
  • examples/dojo/dojo-starter/manifests/dev/deployment/manifest.json (4 hunks)
  • packages/sdk/src/convertQueryToEntityKeyClauses.ts (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • examples/clients/react/react-sdk/src/App.tsx
  • packages/sdk/src/convertQueryToEntityKeyClauses.ts
Additional comments not posted (3)
examples/dojo/dojo-starter/manifests/dev/deployment/manifest.json (3)

1237-1238: Assess the impact of the address change on the system's integrations and dependencies.

The address of the world contract has been modified, which may have implications for other parts of the system that interact with or depend on this contract.

Review the codebase to identify any hardcoded references to the previous address and update them to use the new address. Additionally, verify that any external systems or off-chain processes that communicate with the world contract are properly configured with the updated address.

Run the following script to identify references to the old and new address values:

Verification successful

This script will search for both the old and new addresses in all files, providing context lines for any matches found. It will help us identify any remaining references to the old address and verify the usage of the new address.


Address change has been properly implemented across the codebase

The verification process has confirmed that the address change for the world contract has been correctly implemented:

  • No occurrences of the old address (0x36e4506b35e6dfb301d437c95f74b3e1f4f82da5d8841bec894bb8de29ec13) were found in the codebase.
  • The new address (0x5d475a9221f6cbf1a016b12400a01b9a89935069aecd57e9876fcb2a7bb29da) is present only in appropriate configuration and deployment-related files.
  • There are no hardcoded references to the contract address in application code.

This suggests that the change has been consistently applied and there are no apparent issues or inconsistencies in the codebase related to this address update.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify references to the old and new `address` values in the codebase.

# Test 1: Search for references to the old `address`. Expect: No occurrences.
rg --type cairo --type javascript --type typescript --type json $'0x36e4506b35e6dfb301d437c95f74b3e1f4f82da5d8841bec894bb8de29ec13' 

# Test 2: Search for references to the new `address`. Expect: Only occurrences in relevant configuration or deployment files.
rg --type cairo --type javascript --type typescript --type json $'0x5d475a9221f6cbf1a016b12400a01b9a89935069aecd57e9876fcb2a7bb29da'

Length of output: 322


Script:

#!/bin/bash
# Description: Search for old and new addresses in all files

# Function to search for an address
search_address() {
    local address="$1"
    local description="$2"
    echo "Searching for $description: $address"
    fd . -t f -x grep -n -C 2 "$address" {} || true
    echo "----------------------------------------"
}

# Search for old address (without '0x' prefix to catch variations)
search_address "36e4506b35e6dfb301d437c95f74b3e1f4f82da5d8841bec894bb8de29ec13" "old address"

# Search for new address (without '0x' prefix to catch variations)
search_address "5d475a9221f6cbf1a016b12400a01b9a89935069aecd57e9876fcb2a7bb29da" "new address"

Length of output: 2090


1258-1260: Verify the usage of the updated contract address and class_hash values.

The address, class_hash, and original_class_hash for a specific contract have been modified, indicating a potential redeployment or update of the contract.

Ensure that all references to the previous address and class_hash values have been updated across the codebase, including any configuration files, deployment scripts, or on-chain interactions. This will help maintain consistency and avoid any potential issues arising from using outdated contract references.

Run the following script to verify the usage of the old and new address and class_hash values:

Verification successful

Contract references updated successfully, with one point of attention

The verification process confirms that the contract address and class_hash values have been successfully updated across the codebase. No references to the old values were found, indicating a consistent update. The new values are present in the expected configuration and deployment files.

However, please note:

  • The new contract address (0x25d128c5fe89696e7e15390ea58927bbed4290ae46b538b28cfc7c2190e378b) is also present in packages/sdk/src/execute.ts. Ensure this is intentional and doesn't introduce any unintended side effects in the SDK.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify references to the old and new contract `address` and `class_hash` values.

# Test 1: Search for references to the old `address`. Expect: No occurrences.
rg --type cairo --type javascript --type typescript --type json $'0x36e4506b35e6dfb301d437c95f74b3e1f4f82da5d8841bec894bb8de29ec13'

# Test 2: Search for references to the new `address`. Expect: Only occurrences in relevant configuration or deployment files.
rg --type cairo --type javascript --type typescript --type json $'0x25d128c5fe89696e7e15390ea58927bbed4290ae46b538b28cfc7c2190e378b'

# Test 3: Search for references to the old `class_hash`. Expect: No occurrences.
rg --type cairo --type javascript --type typescript --type json $'0x4f10da1ba615523c1a4b9e2ad40df134edbcf2d971a1074efbd9772c86c2173'

# Test 4: Search for references to the new `class_hash`. Expect: Only occurrences in relevant configuration or deployment files.
rg --type cairo --type javascript --type typescript --type json $'0x7304354bfea03508e0a8beaca98c9580c852a0e350b74dcafb55192c62fa3f4'  

Length of output: 646


Script:

#!/bin/bash
# Description: Verify references to the old and new contract `address` and `class_hash` values.

# Search for references to the old `address`
echo "Searching for old address:"
rg -i --type javascript --type typescript --type json "0x36e4506b35e6dfb301d437c95f74b3e1f4f82da5d8841bec894bb8de29ec13"
echo "Searching for old address in all files:"
rg -i "0x36e4506b35e6dfb301d437c95f74b3e1f4f82da5d8841bec894bb8de29ec13"

# Search for references to the new `address`
echo "Searching for new address:"
rg -i --type javascript --type typescript --type json "0x25d128c5fe89696e7e15390ea58927bbed4290ae46b538b28cfc7c2190e378b"
echo "Searching for new address in all files:"
rg -i "0x25d128c5fe89696e7e15390ea58927bbed4290ae46b538b28cfc7c2190e378b"

# Search for references to the old `class_hash`
echo "Searching for old class_hash:"
rg -i --type javascript --type typescript --type json "0x4f10da1ba615523c1a4b9e2ad40df134edbcf2d971a1074efbd9772c86c2173"
echo "Searching for old class_hash in all files:"
rg -i "0x4f10da1ba615523c1a4b9e2ad40df134edbcf2d971a1074efbd9772c86c2173"

# Search for references to the new `class_hash`
echo "Searching for new class_hash:"
rg -i --type javascript --type typescript --type json "0x7304354bfea03508e0a8beaca98c9580c852a0e350b74dcafb55192c62fa3f4"
echo "Searching for new class_hash in all files:"
rg -i "0x7304354bfea03508e0a8beaca98c9580c852a0e350b74dcafb55192c62fa3f4"

Length of output: 2954


4-5: Verify the impact of the class_hash and original_class_hash changes on the codebase.

The class_hash and original_class_hash for the world have been updated, indicating a change in the underlying contract implementation. Ensure that all references to the previous hash values have been updated accordingly across the codebase to maintain consistency and avoid any potential issues.

Run the following script to verify the usage of the old and new class_hash values:

Verification successful

Class hash update has been successfully applied across the codebase.

The verification process confirms that the class_hash and original_class_hash for the world have been updated consistently. The new value (0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e) is present in all relevant configuration files, while the old value is not found anywhere in the codebase. This indicates a thorough and consistent update.

Key findings:

  • New class_hash is present in deployment manifests and configuration files.
  • Old class_hash is not found anywhere in the codebase.
  • No inconsistencies or missed updates were detected.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify references to the old and new `class_hash` values in the codebase.

# Test 1: Search for references to the old `class_hash`. Expect: No occurrences.
rg --type cairo --type javascript --type typescript --type json $'0x458d0ce5b14a4844092bdb62050f462d53362304a13febbac6d973691d61be2'

# Test 2: Search for references to the new `class_hash`. Expect: Only occurrences in relevant configuration or deployment files.
rg --type cairo --type javascript --type typescript --type json $'0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e'

Length of output: 323


Script:

#!/bin/bash
# Description: Verify references to the old and new `class_hash` values in the codebase.

# Test 1: Search for references to the old `class_hash`. Expect: No occurrences.
echo "Searching for old class_hash:"
rg --type javascript --type typescript --type json -n -C 2 '0x458d0ce5b14a4844092bdb62050f462d53362304a13febbac6d973691d61be2'

# Test 2: Search for references to the new `class_hash`. Expect: Only occurrences in relevant configuration or deployment files.
echo "Searching for new class_hash:"
rg --type javascript --type typescript --type json -n -C 2 '0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e'

# Test 3: Search for any 'class_hash' occurrences to ensure we're not missing anything.
echo "Searching for 'class_hash' occurrences:"
rg --type javascript --type typescript --type json -n -C 2 'class_hash'

Length of output: 663


Script:

#!/bin/bash
# Description: Verify references to the old and new `class_hash` values in the codebase.

# Test 1: Search for references to the old `class_hash`. Expect: No occurrences.
echo "Searching for old class_hash:"
rg -i -n -C 2 '0x458d0ce5b14a4844092bdb62050f462d53362304a13febbac6d973691d61be2'

# Test 2: Search for references to the new `class_hash`. Expect: Only occurrences in relevant configuration or deployment files.
echo "Searching for new class_hash:"
rg -i -n -C 2 '0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e'

# Test 3: Search for any 'class_hash' occurrences to ensure we're not missing anything.
echo "Searching for 'class_hash' occurrences:"
rg -i -n -C 2 'class_hash'

Length of output: 58432

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Outside diff range and nitpick comments (3)
clients/react/react-sdk/package.json (1)

1-34: Consider adding a README file to provide documentation and setup instructions.

To enhance the usability and maintainability of the project, it's recommended to include a README file that provides an overview of the project, installation instructions, and any other relevant information for developers who may work on or use this SDK.

clients/react/react-sdk/src/App.tsx (2)

24-64: Consider improving error handling and subscription management.

The subscription setup can be improved in the following ways:

  1. Instead of logging errors to the console, consider displaying user-friendly error messages in the UI to inform the user about any issues.
  2. Store the unsubscribe function returned by db.subscribeEntityQuery in a ref using the useRef hook. This ensures that the latest unsubscribe function is always available and can be called when the component unmounts.

76-118: Consider handling loading state and error scenarios.

The initial data fetching can be improved by:

  1. Introducing a loading state to indicate that data is being fetched. This can be done by using the useState hook to manage a loading state variable and updating it accordingly.
  2. Handling error scenarios more gracefully. Instead of logging errors to the console, consider displaying user-friendly error messages in the UI to inform the user about any issues encountered during data fetching.
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 9d90ca3 and 5459960.

Files ignored due to path filters (45)
  • clients/react/react-phaser-example/public/assets/atlases/atlas.png is excluded by !**/*.png
  • clients/react/react-phaser-example/public/assets/paper.png is excluded by !**/*.png
  • clients/react/react-phaser-example/public/assets/rock.png is excluded by !**/*.png
  • clients/react/react-phaser-example/public/assets/scissors.png is excluded by !**/*.png
  • clients/react/react-phaser-example/public/assets/texture.png is excluded by !**/*.png
  • clients/react/react-phaser-example/public/assets/tilesets/land.png is excluded by !**/*.png
  • clients/react/react-phaser-example/public/assets/tilesets/world.png is excluded by !**/*.png
  • clients/react/react-phaser-example/public/paper.png is excluded by !**/*.png
  • clients/react/react-phaser-example/public/rock.png is excluded by !**/*.png
  • clients/react/react-phaser-example/public/scissors.png is excluded by !**/*.png
  • clients/react/react-phaser-example/public/texture.png is excluded by !**/*.png
  • clients/react/react-phaser-example/public/vite.svg is excluded by !**/*.svg
  • clients/react/react-phaser-example/src/assets/paper.png is excluded by !**/*.png
  • clients/react/react-phaser-example/src/assets/rock.png is excluded by !**/*.png
  • clients/react/react-phaser-example/src/assets/scissors.png is excluded by !**/*.png
  • clients/react/react-phaser-example/src/assets/texture.png is excluded by !**/*.png
  • clients/react/react-phaser-example/src/assets/tilesets/land.png is excluded by !**/*.png
  • clients/react/react-pwa-app/public/apple-touch-icon.png is excluded by !**/*.png
  • clients/react/react-pwa-app/public/desktop-app-screenshot.png is excluded by !**/*.png
  • clients/react/react-pwa-app/public/favicon.ico is excluded by !**/*.ico
  • clients/react/react-pwa-app/public/favicon.svg is excluded by !**/*.svg
  • clients/react/react-pwa-app/public/pwa-192x192.png is excluded by !**/*.png
  • clients/react/react-pwa-app/public/pwa-512x512.png is excluded by !**/*.png
  • clients/react/react-pwa-app/public/pwa-maskable-192x192.png is excluded by !**/*.png
  • clients/react/react-pwa-app/public/pwa-maskable-512x512.png is excluded by !**/*.png
  • clients/react/react-pwa-app/src/assets/dojo.svg is excluded by !**/*.svg
  • clients/react/react-sdk/public/vite.svg is excluded by !**/*.svg
  • clients/react/react-sdk/src/assets/react.svg is excluded by !**/*.svg
  • clients/torii-bot/images/Step 1.png is excluded by !**/*.png
  • clients/torii-bot/images/Step 2.png is excluded by !**/*.png
  • clients/torii-bot/images/Step 3.png is excluded by !**/*.png
  • clients/torii-bot/images/Step 4.png is excluded by !**/*.png
  • clients/torii-bot/images/Step 5.png is excluded by !**/*.png
  • clients/torii-bot/images/Step 6.png is excluded by !**/*.png
  • clients/torii-bot/images/Step 7.png is excluded by !**/*.png
  • clients/torii-bot/images/railway.png is excluded by !**/*.png
  • clients/vanilla/phaser/assets/sprGrass.png is excluded by !**/*.png
  • clients/vanilla/phaser/assets/sprSand.png is excluded by !**/*.png
  • clients/vanilla/phaser/assets/sprWater.png is excluded by !**/*.png
  • clients/vanilla/phaser/public/favicon.ico is excluded by !**/*.ico
  • clients/vue/vue-app/public/vite.svg is excluded by !**/*.svg
  • clients/vue/vue-app/src/assets/vue.svg is excluded by !**/*.svg
  • examples/dojo/dojo-starter/Scarb.lock is excluded by !**/*.lock
  • examples/dojo/dojo-starter/assets/cover.png is excluded by !**/*.png
  • examples/dojo/dojo-starter/assets/icon.png is excluded by !**/*.png
Files selected for processing (62)
  • clients/react/react-app/src/App.tsx (3 hunks)
  • clients/react/react-app/src/dojo/createSystemCalls.ts (2 hunks)
  • clients/react/react-sdk/README.md (1 hunks)
  • clients/react/react-sdk/dojoConfig.ts (1 hunks)
  • clients/react/react-sdk/eslint.config.js (1 hunks)
  • clients/react/react-sdk/index.html (1 hunks)
  • clients/react/react-sdk/package.json (1 hunks)
  • clients/react/react-sdk/src/App.css (1 hunks)
  • clients/react/react-sdk/src/App.tsx (1 hunks)
  • clients/react/react-sdk/src/bindings.ts (1 hunks)
  • clients/react/react-sdk/src/index.css (1 hunks)
  • clients/react/react-sdk/src/main.tsx (1 hunks)
  • clients/react/react-sdk/tsconfig.app.json (1 hunks)
  • clients/react/react-sdk/tsconfig.json (1 hunks)
  • clients/react/react-sdk/tsconfig.node.json (1 hunks)
  • clients/react/react-sdk/vite.config.ts (1 hunks)
  • clients/torii-bot/dojoConfig.ts (1 hunks)
  • clients/vanilla/phaser/dojoConfig.ts (1 hunks)
  • clients/vue/vue-app/.gitignore (1 hunks)
  • clients/vue/vue-app/dojoConfig.ts (1 hunks)
  • clients/vue/vue-app/src/App.vue (1 hunks)
  • clients/vue/vue-app/src/vite-env.d.ts (1 hunks)
  • examples/dojo/dojo-starter/.github/mark-dark.svg (0 hunks)
  • examples/dojo/dojo-starter/.github/mark-light.svg (0 hunks)
  • examples/dojo/dojo-starter/.github/workflows/test.yaml (0 hunks)
  • examples/dojo/dojo-starter/.gitignore (0 hunks)
  • examples/dojo/dojo-starter/.vscode/settings.json (0 hunks)
  • examples/dojo/dojo-starter/LICENSE (0 hunks)
  • examples/dojo/dojo-starter/README.md (0 hunks)
  • examples/dojo/dojo-starter/Scarb.toml (0 hunks)
  • examples/dojo/dojo-starter/dojo_dev.toml (0 hunks)
  • examples/dojo/dojo-starter/dojo_release.toml (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/abis/contracts/dojo_starter-actions-7a1c7102.json (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/abis/dojo-base.json (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/abis/dojo-world.json (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/abis/models/dojo_starter-DirectionsAvailable-77844f1f.json (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/abis/models/dojo_starter-Moved-504403e5.json (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/abis/models/dojo_starter-Moves-2a29373f.json (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/abis/models/dojo_starter-Position-2ac8b4c1.json (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/contracts/dojo_starter-actions-7a1c7102.toml (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/dojo-base.toml (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/dojo-world.toml (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/models/dojo_starter-DirectionsAvailable-77844f1f.toml (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/models/dojo_starter-Moved-504403e5.toml (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/models/dojo_starter-Moves-2a29373f.toml (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/base/models/dojo_starter-Position-2ac8b4c1.toml (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/contracts/dojo_starter-actions-7a1c7102.json (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/dojo-base.json (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/dojo-world.json (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/models/dojo_starter-DirectionsAvailable-77844f1f.json (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/models/dojo_starter-Moved-504403e5.json (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/models/dojo_starter-Moves-2a29373f.json (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/models/dojo_starter-Position-2ac8b4c1.json (0 hunks)
  • examples/dojo/dojo-starter/manifests/dev/deployment/manifest.toml (0 hunks)
  • examples/dojo/dojo-starter/overlays/dev/actions.toml (0 hunks)
  • examples/dojo/dojo-starter/scripts/move.sh (0 hunks)
  • examples/dojo/dojo-starter/scripts/spawn.sh (0 hunks)
  • examples/dojo/dojo-starter/src/lib.cairo (0 hunks)
  • examples/dojo/dojo-starter/src/models.cairo (0 hunks)
  • examples/dojo/dojo-starter/src/systems/actions.cairo (0 hunks)
  • examples/dojo/dojo-starter/src/tests/test_world.cairo (0 hunks)
  • packages/create-burner/tsconfig.json (1 hunks)
Files not reviewed due to no reviewable changes (39)
  • examples/dojo/dojo-starter/.github/mark-dark.svg
  • examples/dojo/dojo-starter/.github/mark-light.svg
  • examples/dojo/dojo-starter/.github/workflows/test.yaml
  • examples/dojo/dojo-starter/.gitignore
  • examples/dojo/dojo-starter/.vscode/settings.json
  • examples/dojo/dojo-starter/LICENSE
  • examples/dojo/dojo-starter/README.md
  • examples/dojo/dojo-starter/Scarb.toml
  • examples/dojo/dojo-starter/dojo_dev.toml
  • examples/dojo/dojo-starter/dojo_release.toml
  • examples/dojo/dojo-starter/manifests/dev/base/abis/contracts/dojo_starter-actions-7a1c7102.json
  • examples/dojo/dojo-starter/manifests/dev/base/abis/dojo-base.json
  • examples/dojo/dojo-starter/manifests/dev/base/abis/dojo-world.json
  • examples/dojo/dojo-starter/manifests/dev/base/abis/models/dojo_starter-DirectionsAvailable-77844f1f.json
  • examples/dojo/dojo-starter/manifests/dev/base/abis/models/dojo_starter-Moved-504403e5.json
  • examples/dojo/dojo-starter/manifests/dev/base/abis/models/dojo_starter-Moves-2a29373f.json
  • examples/dojo/dojo-starter/manifests/dev/base/abis/models/dojo_starter-Position-2ac8b4c1.json
  • examples/dojo/dojo-starter/manifests/dev/base/contracts/dojo_starter-actions-7a1c7102.toml
  • examples/dojo/dojo-starter/manifests/dev/base/dojo-base.toml
  • examples/dojo/dojo-starter/manifests/dev/base/dojo-world.toml
  • examples/dojo/dojo-starter/manifests/dev/base/models/dojo_starter-DirectionsAvailable-77844f1f.toml
  • examples/dojo/dojo-starter/manifests/dev/base/models/dojo_starter-Moved-504403e5.toml
  • examples/dojo/dojo-starter/manifests/dev/base/models/dojo_starter-Moves-2a29373f.toml
  • examples/dojo/dojo-starter/manifests/dev/base/models/dojo_starter-Position-2ac8b4c1.toml
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/contracts/dojo_starter-actions-7a1c7102.json
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/dojo-base.json
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/dojo-world.json
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/models/dojo_starter-DirectionsAvailable-77844f1f.json
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/models/dojo_starter-Moved-504403e5.json
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/models/dojo_starter-Moves-2a29373f.json
  • examples/dojo/dojo-starter/manifests/dev/deployment/abis/models/dojo_starter-Position-2ac8b4c1.json
  • examples/dojo/dojo-starter/manifests/dev/deployment/manifest.toml
  • examples/dojo/dojo-starter/overlays/dev/actions.toml
  • examples/dojo/dojo-starter/scripts/move.sh
  • examples/dojo/dojo-starter/scripts/spawn.sh
  • examples/dojo/dojo-starter/src/lib.cairo
  • examples/dojo/dojo-starter/src/models.cairo
  • examples/dojo/dojo-starter/src/systems/actions.cairo
  • examples/dojo/dojo-starter/src/tests/test_world.cairo
Files skipped from review due to trivial changes (7)
  • clients/react/react-sdk/dojoConfig.ts
  • clients/react/react-sdk/index.html
  • clients/react/react-sdk/tsconfig.json
  • clients/vanilla/phaser/dojoConfig.ts
  • clients/vue/vue-app/.gitignore
  • clients/vue/vue-app/src/App.vue
  • clients/vue/vue-app/src/vite-env.d.ts
Additional context used
Biome
clients/react/react-sdk/tsconfig.app.json

[error] 9-9: JSON standard does not allow comments.

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

clients/react/react-sdk/tsconfig.node.json

[error] 8-8: JSON standard does not allow comments.

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

Additional comments not posted (36)
clients/vue/vue-app/dojoConfig.ts (1)

1-1: LGTM!

The update to the import path for the JSON manifest looks good. The new location seems to be a better fit within the examples directory structure.

The removal of the JSON type assertion should not cause any issues, as long as the imported file is still a valid JSON.

clients/torii-bot/dojoConfig.ts (1)

1-7: LGTM!

The code follows best practices and sets up a structured configuration for the Dojo framework. Here's a breakdown:

  • The import statement correctly uses the assert { type: "json" } syntax to ensure type safety when importing the JSON manifest file.
  • The createDojoConfig function is used to create a validated configuration object by passing the imported manifest.
  • The created configuration is exported as a constant named dojoConfig, making it available for use in other parts of the application.

This setup allows for easy management of deployment settings and resources, which is essential for the application to function correctly.

clients/react/react-sdk/src/main.tsx (1)

1-10: LGTM!

The code follows best practices for setting up a React application:

  • It imports essential modules, including StrictMode from React and createRoot from react-dom/client.
  • It imports the main application component, App, from App.tsx.
  • It includes a CSS file for styling.
  • It uses the createRoot function to create a root for the React application, targeting an HTML element with the ID "root".
  • It renders the application within the StrictMode wrapper, which helps in identifying potential issues during development by activating additional checks and warnings.

The code sets up a solid foundation for the React application, ensuring that it adheres to best practices.

clients/react/react-sdk/vite.config.ts (1)

1-9: Excellent choice of plugins for the Vite configuration!

The selected plugins provide valuable enhancements to the development experience:

  1. vite-plugin-wasm: Enables seamless integration and usage of WebAssembly modules in the application, opening up possibilities for performance-critical tasks and interoperability with other languages.

  2. @vitejs/plugin-react: Optimizes the development workflow for React applications by enabling React Fast Refresh and other React-specific improvements, resulting in a more efficient and enjoyable development process.

  3. vite-plugin-top-level-await: Simplifies asynchronous code management by allowing the use of top-level await syntax, leading to cleaner and more readable code.

These plugins collectively contribute to a robust and feature-rich development environment for building React applications with advanced capabilities.

clients/react/react-sdk/tsconfig.node.json (1)

1-22: The TypeScript configuration settings look good!

The compiler options enforce modern JavaScript standards and best practices, which will enhance the development experience and maintainability of the codebase. The configuration is also tailored for a Vite-based project, ensuring compatibility with the build system.

Tools
Biome

[error] 8-8: JSON standard does not allow comments.

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

clients/react/react-sdk/tsconfig.app.json (2)

2-22: The compiler options are well-configured for a modern React application.

The compiler options are set up appropriately for a React application targeting modern JavaScript features and ensuring code quality:

  • target and lib options enable modern ECMAScript features.
  • module and moduleResolution options are suitable for a bundler-based workflow.
  • strict and related options enforce strict type-checking and best practices.
  • jsx option is set to react-jsx for React applications.
Tools
Biome

[error] 9-9: JSON standard does not allow comments.

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


9-9: Ignore the JSON syntax errors reported by static analysis tools.

The comments in the JSON file, while not strictly valid JSON syntax, are commonly used for readability in configuration files. Many tools, including the TypeScript compiler, support comments in JSON files.

The reported errors about comments and end of file are false positives and can be safely ignored.

Also applies to: 17-17

Tools
Biome

[error] 9-9: JSON standard does not allow comments.

(parse)

clients/react/react-sdk/src/App.css (5)

1-6: LGTM!

The styles for the #root selector are correctly defined and appropriate for a main application container. The maximum width, centering, padding, and text alignment styles are suitable for a top-level container.


8-19: LGTM!

The styles for the .logo and .logo.react classes are correctly defined and provide engaging visual effects for the logo element. The specific height, padding, and hover effects with drop shadows enhance the user experience. The use of will-change and transition properties is a good practice for optimizing animation performance.


21-28: LGTM!

The @keyframes logo-spin rule is correctly defined and creates a spinning animation by rotating an element from 0 to 360 degrees. This animation can be applied to elements to create engaging visual effects.


30-34: LGTM!

The media query is correctly defined and applies the logo-spin animation to the second anchor element's logo when the user's system preference allows for motion. This is a good practice for respecting accessibility preferences and providing an inclusive user experience.


36-42: LGTM!

The styles for the .card and .read-the-docs classes are correctly defined and provide appropriate visual enhancements for card elements and text. The padding for cards and the muted color for text improve the readability and aesthetics of the user interface.

packages/create-burner/tsconfig.json (1)

23-23: Verify the impact of changing rootDir on project structure and compilation.

Modifying the rootDir from "src" to "." allows the TypeScript compiler to consider all files in the current directory as part of the project structure. This change provides more flexibility in file organization.

Please ensure that:

  1. The new file structure aligns with the intended project organization.
  2. The TypeScript compiler doesn't inadvertently include unintended files in the compilation process.

You can verify the compilation output by running the TypeScript compiler and reviewing the generated files in the outDir.

clients/react/react-sdk/eslint.config.js (1)

1-28: Excellent ESLint configuration for React with TypeScript!

The ESLint configuration in this file is comprehensive and follows best practices for React development with TypeScript. It includes:

  • Relevant and widely used modules and plugins from the React ecosystem.
  • Appropriate target files, ECMAScript version, and browser globals.
  • Recommended rules from the imported plugins to ensure code quality and adherence to best practices.
  • A custom rule for component exports that allows for flexibility while still enforcing good practices.

This configuration will help maintain code quality and consistency throughout the project by catching potential issues and enforcing best practices during development. The well-structured and easy-to-understand configuration makes it maintainable and extensible.

Great job setting up a solid foundation for the project's code quality!

clients/react/react-sdk/package.json (1)

1-34: LGTM! The package.json configuration is well-structured and includes essential dependencies and scripts.

The file sets up a solid foundation for a modern React application with a focus on type safety and modular development practices. The inclusion of Dojo Engine packages indicates seamless integration with the Dojo ecosystem.

clients/react/react-sdk/src/index.css (5)

1-14: LGTM!

The :root selector is used effectively to define global CSS variables. The chosen font family, color scheme, and vendor prefixes ensure good readability, contrast, and cross-browser compatibility.


16-23: LGTM!

The styles for anchor tags enhance the visual appearance and provide good user feedback on hover. The styles are consistent with the overall color scheme.


25-31: LGTM!

The styles for the <body> element effectively center the content and ensure it is always visible. The use of flexbox provides a modern layout technique.


33-55: LGTM!

The styles for h1 and button elements enhance the visual hierarchy, provide consistent styling, and improve user experience with hover effects and focus styles.


57-68: LGTM!

The styles defined within the media query for light mode ensure good contrast, readability, and consistency with the overall design. The use of the prefers-color-scheme media feature enhances the user experience by adapting to their color scheme preference.

clients/react/react-sdk/src/bindings.ts (7)

1-7: LGTM!

The Moves interface correctly represents the player's moves with appropriate properties and types.


9-13: LGTM!

The DirectionsAvailable interface correctly represents the available directions for the player with appropriate properties and types.


15-19: LGTM!

The Position interface correctly represents the player's position with appropriate properties and types.


29-32: LGTM!

The Vec2 interface correctly represents a 2D vector with appropriate properties and types.


21-27: LGTM!

The Direction enum correctly represents the possible directions with appropriate values.


34-40: LGTM!

The Schema type correctly represents the schema of the game state with appropriate properties and types.


42-62: LGTM!

The schema constant correctly represents an instance of the Schema type with appropriate default values.

clients/react/react-sdk/README.md (2)

1-9: LGTM!

The introduction section provides a clear and concise overview of the purpose of the document and the technologies covered. It also lists the two official Vite plugins for React, along with their respective Fast Refresh mechanisms.


10-50: LGTM!

The "Expanding the ESLint configuration" section provides clear and detailed instructions for updating the ESLint configuration for production applications. It covers important aspects such as configuring the parserOptions property, replacing default ESLint configurations with type-checked variants, and adding stylistic rules. The instructions for integrating the eslint-plugin-react are also well-explained and essential for React development. The code examples provided are clear and well-formatted, making it easy for developers to follow along and implement the recommended changes.

clients/react/react-app/src/dojo/createSystemCalls.ts (2)

14-14: LGTM!

The import statement is necessary for the code to compile and function correctly. The Direction enum is likely used in the move function to specify the direction of movement.


87-87: LGTM!

Passing the direction parameter directly to the client.actions.move function is a valid simplification that enhances clarity and maintainability by removing unnecessary complexity.

clients/react/react-sdk/src/App.tsx (2)

7-16: LGTM!

The initialization of the Dojo Engine database connection using the init function from the SDK is correctly implemented.


18-156: LGTM!

The implementation of the App component is well-structured and follows best practices. It effectively manages the state of game entities, sets up subscriptions for real-time updates, fetches initial data, and renders the entities in the UI.

clients/react/react-app/src/App.tsx (3)

9-15: LGTM!

The DirectionEnum is a great addition that provides a structured way to represent movement directions. Using an enum improves code clarity and maintainability. The string constants for the enum values enhance readability.


150-152: Great refactoring!

Updating the onClick handlers to use the DirectionEnum standardizes how movement directions are represented. The move function now expects an object with a type property set to the corresponding DirectionEnum value, which improves the semantic clarity of the code. This change enhances the overall readability and maintainability of the movement logic.

Also applies to: 163-165, 172-174, 181-183


Line range hint 1-192: Excellent work on the React component and overall architecture!

The App component follows a modular structure by separating concerns into custom hooks and utilities from the @dojoengine packages. This indicates a well-defined architecture for game development. The component effectively manages the game state using the useComponentValue hook and the toriiClient, demonstrating a solid understanding of React best practices.

The code is well-organized, readable, and maintainable. The recent changes, such as the introduction of the DirectionEnum, further enhance the clarity and structure of the codebase.

Keep up the great work!

"module": "ESNext",
"skipLibCheck": true,

/* Bundler mode */
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove comments to fix JSON parsing errors.

The static analysis tool has correctly identified that JSON does not allow comments. Remove the comments on lines 8 and 15 to ensure that the configuration file is valid JSON.

Apply this diff to fix the JSON parsing errors:

-        /* Bundler mode */
+        
-        /* Linting */
+        

Also applies to: 15-15

Tools
Biome

[error] 8-8: JSON standard does not allow comments.

(parse)

Comment on lines 1 to 34
{
"name": "react-sdk",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@dojoengine/core": "1.0.0-alpha.12",
"@dojoengine/sdk": "workspace:*",
"@dojoengine/torii-wasm": "1.0.0-alpha.12",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"vite-plugin-top-level-await": "^1.4.4",
"vite-plugin-wasm": "^3.3.0"
},
"devDependencies": {
"@eslint/js": "^9.9.0",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.1",
"eslint": "^9.9.0",
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
"eslint-plugin-react-refresh": "^0.4.9",
"globals": "^15.9.0",
"typescript": "^5.5.3",
"typescript-eslint": "^8.0.1",
"vite": "^5.4.1"
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommend adding testing libraries and scripts for comprehensive testing.

To ensure the reliability and stability of the SDK, it's crucial to implement a robust testing strategy. Consider adding testing libraries such as Jest or React Testing Library to the devDependencies and include corresponding scripts in the package.json file to run tests and generate coverage reports.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 5459960 and 69964b7.

Files selected for processing (68)
  • clients/react/react-app/dojoConfig.ts (1 hunks)
  • clients/react/react-app/src/App.tsx (3 hunks)
  • clients/react/react-app/src/dojo/DojoContext.tsx (1 hunks)
  • clients/react/react-app/src/dojo/createClientComponents.ts (1 hunks)
  • clients/react/react-app/src/dojo/createSystemCalls.ts (2 hunks)
  • clients/react/react-app/src/dojo/setup.ts (1 hunks)
  • clients/react/react-app/src/dojo/typescript/contracts.gen.ts (1 hunks)
  • clients/react/react-app/src/dojo/useDojo.tsx (1 hunks)
  • clients/react/react-app/src/main.tsx (1 hunks)
  • clients/react/react-app/vite.config.ts (1 hunks)
  • clients/react/react-pwa-app/dojoConfig.ts (1 hunks)
  • clients/react/react-pwa-app/src/App.tsx (1 hunks)
  • clients/react/react-pwa-app/src/dojo/DojoContext.tsx (1 hunks)
  • clients/react/react-pwa-app/src/dojo/createClientComponents.ts (1 hunks)
  • clients/react/react-pwa-app/src/dojo/createSystemCalls.ts (1 hunks)
  • clients/react/react-pwa-app/src/dojo/generated/generated.ts (1 hunks)
  • clients/react/react-pwa-app/src/dojo/generated/setup.ts (1 hunks)
  • clients/react/react-pwa-app/src/dojo/useDojo.tsx (1 hunks)
  • clients/react/react-pwa-app/src/main.tsx (1 hunks)
  • clients/react/react-pwa-app/vite.config.ts (1 hunks)
  • clients/react/react-sdk/dojoConfig.ts (1 hunks)
  • clients/react/react-sdk/eslint.config.js (1 hunks)
  • clients/react/react-sdk/src/App.tsx (1 hunks)
  • clients/react/react-sdk/src/main.tsx (1 hunks)
  • clients/react/react-sdk/vite.config.ts (1 hunks)
  • clients/react/react-threejs/dojoConfig.ts (1 hunks)
  • clients/react/react-threejs/src/App.tsx (1 hunks)
  • clients/react/react-threejs/src/dojo/DojoContext.tsx (1 hunks)
  • clients/react/react-threejs/src/dojo/createClientComponents.ts (1 hunks)
  • clients/react/react-threejs/src/dojo/createSystemCalls.ts (1 hunks)
  • clients/react/react-threejs/src/dojo/generated/generated.ts (1 hunks)
  • clients/react/react-threejs/src/dojo/generated/setup.ts (2 hunks)
  • clients/react/react-threejs/src/dojo/useDojo.tsx (1 hunks)
  • clients/react/react-threejs/src/gameComponents/Player.tsx (1 hunks)
  • clients/react/react-threejs/src/gameComponents/Players.tsx (1 hunks)
  • clients/react/react-threejs/src/gameComponents/Three.tsx (1 hunks)
  • clients/react/react-threejs/src/gameComponents/Tile.tsx (1 hunks)
  • clients/react/react-threejs/src/gameComponents/TileGrid.tsx (1 hunks)
  • clients/react/react-threejs/src/gameComponents/UIContainer.tsx (1 hunks)
  • clients/react/react-threejs/src/lib/utils.ts (1 hunks)
  • clients/react/react-threejs/src/main.tsx (1 hunks)
  • clients/react/react-threejs/vite.config.ts (1 hunks)
  • clients/torii-bot/src/commands/getMoves.ts (1 hunks)
  • clients/torii-bot/src/config.ts (1 hunks)
  • clients/torii-bot/src/generated/graphql.ts (1 hunks)
  • clients/torii-bot/src/index.ts (1 hunks)
  • clients/vanilla/phaser/dojoConfig.ts (1 hunks)
  • clients/vanilla/phaser/src/dojo/createClientComponent.ts (1 hunks)
  • clients/vanilla/phaser/src/dojo/defineContractSystems.ts (1 hunks)
  • clients/vanilla/phaser/src/dojo/setup.ts (1 hunks)
  • clients/vanilla/phaser/src/dojo/systems.ts (1 hunks)
  • clients/vanilla/phaser/src/entities.ts (1 hunks)
  • clients/vanilla/phaser/src/main.ts (1 hunks)
  • clients/vanilla/phaser/src/scenes/scene-main.ts (1 hunks)
  • clients/vanilla/phaser/vite.config.ts (1 hunks)
  • clients/vue/vue-app/dojoConfig.ts (1 hunks)
  • clients/vue/vue-app/src/App.vue (1 hunks)
  • clients/vue/vue-app/src/dojo/createClientComponents.ts (1 hunks)
  • clients/vue/vue-app/src/dojo/createSystemCalls.ts (1 hunks)
  • clients/vue/vue-app/src/dojo/generated/generated.ts (1 hunks)
  • clients/vue/vue-app/src/dojo/generated/setup.ts (1 hunks)
  • clients/vue/vue-app/src/main.ts (1 hunks)
  • clients/vue/vue-app/src/utils/index.ts (1 hunks)
  • clients/vue/vue-app/vite.config.ts (1 hunks)
  • package.json (1 hunks)
  • packages/core/src/test/config/config.test.ts (1 hunks)
  • packages/core/src/config/index.ts (1 hunks)
  • packages/core/src/provider/DojoProvider.ts (1 hunks)
Files skipped from review due to trivial changes (51)
  • clients/react/react-app/dojoConfig.ts
  • clients/react/react-app/src/dojo/DojoContext.tsx
  • clients/react/react-app/src/dojo/createClientComponents.ts
  • clients/react/react-app/src/dojo/setup.ts
  • clients/react/react-app/src/dojo/typescript/contracts.gen.ts
  • clients/react/react-app/src/dojo/useDojo.tsx
  • clients/react/react-app/src/main.tsx
  • clients/react/react-app/vite.config.ts
  • clients/react/react-pwa-app/dojoConfig.ts
  • clients/react/react-pwa-app/src/App.tsx
  • clients/react/react-pwa-app/src/dojo/DojoContext.tsx
  • clients/react/react-pwa-app/src/dojo/createClientComponents.ts
  • clients/react/react-pwa-app/src/dojo/createSystemCalls.ts
  • clients/react/react-pwa-app/src/dojo/generated/setup.ts
  • clients/react/react-pwa-app/src/dojo/useDojo.tsx
  • clients/react/react-pwa-app/src/main.tsx
  • clients/react/react-pwa-app/vite.config.ts
  • clients/react/react-threejs/dojoConfig.ts
  • clients/react/react-threejs/src/App.tsx
  • clients/react/react-threejs/src/dojo/DojoContext.tsx
  • clients/react/react-threejs/src/dojo/createClientComponents.ts
  • clients/react/react-threejs/src/dojo/createSystemCalls.ts
  • clients/react/react-threejs/src/dojo/generated/setup.ts
  • clients/react/react-threejs/src/dojo/useDojo.tsx
  • clients/react/react-threejs/src/gameComponents/Player.tsx
  • clients/react/react-threejs/src/gameComponents/Players.tsx
  • clients/react/react-threejs/src/gameComponents/Three.tsx
  • clients/react/react-threejs/src/gameComponents/TileGrid.tsx
  • clients/react/react-threejs/src/gameComponents/UIContainer.tsx
  • clients/react/react-threejs/src/lib/utils.ts
  • clients/react/react-threejs/src/main.tsx
  • clients/react/react-threejs/vite.config.ts
  • clients/torii-bot/src/commands/getMoves.ts
  • clients/torii-bot/src/config.ts
  • clients/torii-bot/src/generated/graphql.ts
  • clients/torii-bot/src/index.ts
  • clients/vanilla/phaser/src/dojo/createClientComponent.ts
  • clients/vanilla/phaser/src/dojo/setup.ts
  • clients/vanilla/phaser/src/dojo/systems.ts
  • clients/vanilla/phaser/src/entities.ts
  • clients/vanilla/phaser/src/main.ts
  • clients/vanilla/phaser/src/scenes/scene-main.ts
  • clients/vue/vue-app/src/dojo/createClientComponents.ts
  • clients/vue/vue-app/src/dojo/createSystemCalls.ts
  • clients/vue/vue-app/src/dojo/generated/setup.ts
  • clients/vue/vue-app/src/main.ts
  • clients/vue/vue-app/src/utils/index.ts
  • clients/vue/vue-app/vite.config.ts
  • packages/core/src/test/config/config.test.ts
  • packages/core/src/config/index.ts
  • packages/core/src/provider/DojoProvider.ts
Files skipped from review as they are similar to previous changes (10)
  • clients/react/react-app/src/dojo/createSystemCalls.ts
  • clients/react/react-sdk/dojoConfig.ts
  • clients/react/react-sdk/eslint.config.js
  • clients/react/react-sdk/src/App.tsx
  • clients/react/react-sdk/src/main.tsx
  • clients/react/react-sdk/vite.config.ts
  • clients/vanilla/phaser/dojoConfig.ts
  • clients/vue/vue-app/dojoConfig.ts
  • clients/vue/vue-app/src/App.vue
  • package.json
Additional comments not posted (9)
clients/vanilla/phaser/vite.config.ts (1)

4-4: LGTM!

The vite-plugin-wasm plugin is correctly imported and added to the Vite configuration. This change enables WebAssembly support in the build process, which could potentially improve performance or enable new capabilities in the application.

clients/react/react-threejs/src/gameComponents/Tile.tsx (1)

3-3: LGTM!

The import of the THREE library is necessary for the Tile component to leverage 3D graphics capabilities. The use of useMemo to optimize the creation of geometries is a good practice.

clients/vanilla/phaser/src/dojo/defineContractSystems.ts (1)

2-3: Verify the usage of the imported types in the codebase.

The addition of the import statement for Account and AccountInterface from the "starknet" module is a good change, as it enables the usage of these types in the file.

To ensure consistency and correctness, please verify that the usage of these imported types aligns with the intended functionality throughout the codebase. Run the following script to analyze the usage:

Verification successful

Uncommented import is correct and necessary

The import statement import { Account, AccountInterface } from "starknet"; in clients/vanilla/phaser/src/dojo/defineContractSystems.ts is correct and necessary. Both Account and AccountInterface are used appropriately within the file:

  • They are used in a union type Account | AccountInterface in an interface definition.
  • AccountInterface is used as a parameter type in an async function.

This usage is consistent with best practices, allowing for flexibility in account types and maintaining proper abstraction.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of `Account` and `AccountInterface` types in the codebase.

# Test 1: Search for the usage of `Account` type. Expect: Relevant usage in the codebase.
rg --type typescript -A 5 $'Account'

# Test 2: Search for the usage of `AccountInterface` type. Expect: Relevant usage in the codebase.
rg --type typescript -A 5 $'AccountInterface'

Length of output: 150


Script:

#!/bin/bash
# Description: Verify the usage of `Account` and `AccountInterface` types in the codebase.

# Find TypeScript files
echo "TypeScript files in the codebase:"
fd '\.(ts|tsx)$'

# Search for Account usage
echo -e "\nUsage of Account:"
fd '\.(ts|tsx)$' | xargs rg 'Account' -C 3

# Search for AccountInterface usage
echo -e "\nUsage of AccountInterface:"
fd '\.(ts|tsx)$' | xargs rg 'AccountInterface' -C 3

Length of output: 146922


Script:

#!/bin/bash
# Description: Verify the usage of `Account` and `AccountInterface` in the specific file

echo "Usage of Account and AccountInterface in defineContractSystems.ts:"
rg -n 'Account|AccountInterface' clients/vanilla/phaser/src/dojo/defineContractSystems.ts

Length of output: 408

clients/react/react-pwa-app/src/dojo/generated/generated.ts (1)

2-2: Uncommented import statement is necessary for the code to function correctly.

The uncommented import statement for Account and AccountInterface from the starknet module is required for the code to compile and work as intended. The imported types are being used in the setupWorld function, MoveProps interface, and related code.

This change itself does not introduce any new features or functionalities but rather enables the existing code to utilize the necessary types from the starknet module.

clients/react/react-threejs/src/dojo/generated/generated.ts (1)

2-3: Verify the usage of Account and AccountInterface.

The import statement for Account and AccountInterface from the "starknet" module looks good. However, please ensure that these imports are being utilized correctly in the code that is not part of this diff.

clients/vue/vue-app/src/dojo/generated/generated.ts (1)

2-2: LGTM!

The uncommented import statement for Account and AccountInterface from the starknet package aligns with the existing code and provides type safety in the usage of these types.

clients/react/react-app/src/App.tsx (3)

11-17: LGTM!

The introduction of the DirectionEnum enum is a good refactoring that improves code clarity and maintainability. Using string constants as enum values is a valid approach in TypeScript.


152-154: LGTM!

The code segment correctly checks the current position and calls the move function with the appropriate direction using the DirectionEnum.Up value. The logic is sound and the usage of the enum improves code clarity.


165-167: LGTM!

The code segment correctly checks the current position and calls the move function with the appropriate direction using the DirectionEnum.Left value. The logic is sound and the usage of the enum improves code clarity.

import { getEntityIdFromKeys } from "@dojoengine/utils";

import { Direction } from "./dojo/typescript/models.gen";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the unused Direction import.

The Direction import from "./dojo/typescript/models.gen" is no longer used in the code after the introduction of the DirectionEnum enum. To keep the code clean and maintainable, consider removing this unused import.

-import { Direction } from "./dojo/typescript/models.gen";
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { Direction } from "./dojo/typescript/models.gen";

Comment on lines 183 to 185
onClick={() =>
move(account.account, { type: DirectionEnum.Down })
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a position check before allowing downward movement.

The code segment calls the move function with the DirectionEnum.Down value, but it doesn't check if the current position is valid and allows downward movement. To maintain consistency with the other movement directions and prevent potential out-of-bounds movement, consider adding a position check similar to the ones for moving up and left.

-onClick={() =>
-  move(account.account, { type: DirectionEnum.Down })
-}
+onClick={() =>
+  position && position.vec.y < MAX_Y
+    ? move(account.account, { type: DirectionEnum.Down })
+    : console.log("Reach the borders of the world.")
+}

Committable suggestion was skipped due to low confidence.

Comment on lines 174 to 176
onClick={() =>
move(account.account, { type: DirectionEnum.Right })
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a position check before allowing movement to the right.

The code segment calls the move function with the DirectionEnum.Right value, but it doesn't check if the current position is valid and allows movement to the right. To maintain consistency with the other movement directions and prevent potential out-of-bounds movement, consider adding a position check similar to the ones for moving up and left.

-onClick={() =>
-  move(account.account, { type: DirectionEnum.Right })
-}
+onClick={() =>
+  position && position.vec.x < MAX_X
+    ? move(account.account, { type: DirectionEnum.Right })
+    : console.log("Reach the borders of the world.")
+}

Committable suggestion was skipped due to low confidence.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Outside diff range and nitpick comments (44)
examples/example-vite-react-sdk/tsconfig.json (1)

1-7: LGTM! Consider adding a "compilerOptions" field for shared options.

The TypeScript configuration looks good. It's using project references, which is great for managing larger codebases. This setup allows for better organization and potentially faster build times.

Consider adding a "compilerOptions" field to this root tsconfig.json file for any shared compiler options. This can help ensure consistency across your referenced projects. For example:

 {
+    "compilerOptions": {
+        "strict": true,
+        "esModuleInterop": true
+    },
     "files": [],
     "references": [
         { "path": "./tsconfig.app.json" },
         { "path": "./tsconfig.node.json" }
     ]
 }

This way, you can define common options here and override them in the individual tsconfig files if needed.

examples/example-nodejs-bot/dojoConfig.ts (1)

1-3: Consider simplifying the manifest import path.

The import statements look good overall. The use of assert { type: "json" } for importing the JSON manifest is a modern and type-safe approach.

However, the relative path for the manifest import is quite long. Consider moving the manifest file closer to this configuration file or using path aliases to simplify imports across the project.

examples/example-vite-react-sdk/src/main.tsx (2)

8-12: Approved: Correct usage of React 18 API with a minor suggestion.

The application rendering is implemented correctly using the createRoot API for React 18. Wrapping the App component in StrictMode is a good practice for identifying potential problems in the application.

Consider improving type safety by checking if the root element exists before rendering:

-createRoot(document.getElementById("root")!).render(
+const rootElement = document.getElementById("root");
+if (rootElement) {
+  createRoot(rootElement).render(
     <StrictMode>
         <App />
     </StrictMode>
-);
+  );
+} else {
+  console.error("Root element not found");
+}

This change will provide better error handling and avoid potential runtime errors if the root element is not found.


1-12: Overall: Well-structured React 18 application setup.

This file provides a solid foundation for a React 18 application. It correctly sets up the application using modern React APIs and follows best practices. The code is concise, focused, and accomplishes its primary goal of initializing the React application effectively.

As the application grows, consider:

  1. Implementing error boundaries to catch and handle runtime errors gracefully.
  2. Setting up a custom ErrorBoundary component to wrap around <App /> for better error handling in production.
  3. If using TypeScript (as implied by the .tsx extension), ensure strict mode is enabled in the tsconfig.json for maximum type safety across the project.
examples/example-vite-react-sdk/vite.config.ts (1)

7-9: Configuration looks good, consider additional options if needed.

The Vite configuration is correctly structured:

  • It uses defineConfig for type checking.
  • The plugins are included in an appropriate order: React, WASM, and top-level await.

Depending on your project requirements, you might want to consider adding more configuration options. Some common additions include:

  1. Base URL configuration:
base: '/your-base-path/',
  1. Build options:
build: {
  outDir: 'dist',
  minify: 'terser',
  sourcemap: true,
},
  1. Server options for development:
server: {
  port: 3000,
  open: true,
},
  1. Resolve aliases for cleaner imports:
resolve: {
  alias: {
    '@': '/src',
  },
},

These are just suggestions; add them only if they align with your project needs.

examples/example-vite-react-sdk/index.html (1)

3-8: Head section looks good, consider updating the title.

The head section is well-structured with proper meta tags, favicon, and viewport settings. However, the title "Vite + React + TS" is generic and should be updated to reflect the actual name or purpose of your application.

Consider updating the title to something more specific, for example:

-        <title>Vite + React + TS</title>
+        <title>Dojo Engine SDK Example</title>
examples/example-vite-react-pwa-recs/src/dojo/createClientComponents.ts (1)

Line range hint 1-16: Consider documenting the implications of using overridableComponent.

While the changes look good, it might be beneficial to add a comment explaining the purpose and potential implications of using overridableComponent for Position and Moves. This can help other developers understand the design decision and how it might affect the behavior of these components.

Consider adding a comment like this before the return statement:

// Position and Moves components are made overridable to allow for runtime modifications
// This can be useful for implementing custom game logic or state management
examples/example-vite-react-threejs-recs/src/App.tsx (2)

Line range hint 11-20: LGTM: New components integrated correctly. Consider adding aria-label for accessibility.

The UIContainer and ThreeGrid components are correctly integrated into the App component structure. The layout appears to be designed for a full-screen application with a UI overlay and a 3D canvas, which aligns with the experimental nature of the PR.

Consider adding an aria-label to the div containing ThreeGrid to improve accessibility:

 <div
     id="canvas-container"
     className="z-10 left-0 relative top-0 overflow-hidden grow"
+    aria-label="3D Game Canvas"
 >
     <ThreeGrid />
 </div>

Line range hint 7-24: LGTM: Well-structured component. Consider using Tailwind's container class for consistency.

The overall structure of the App component is well-organized and follows React and Tailwind CSS best practices. The use of semantic HTML (main tag) is good for accessibility, and the layout is appropriate for a game application with UI and 3D canvas.

For consistency with Tailwind CSS conventions, consider using the container class on the outermost div:

-<div className="relative w-screen h-screen flex flex-col">
+<div className="container relative w-screen h-screen flex flex-col">

This change can help maintain consistency across the application if the container class is used elsewhere.

examples/example-vite-react-sdk/tsconfig.app.json (2)

1-8: LGTM! Consider the trade-offs of skipLibCheck.

The target and module settings are well-configured for a modern web application using Vite and React. The ES2020 target and ESNext module setting are appropriate choices.

While "skipLibCheck": true can improve compilation speed, it may miss some type errors in dependencies. Consider setting it to false if thorough type checking of dependencies is crucial for your project.


17-21: Great linting configuration! Consider adding forceConsistentCasingInFileNames.

The linting options are well-configured to enforce strict type checking and catch common errors. This will help maintain a high-quality codebase.

Consider adding "forceConsistentCasingInFileNames": true to prevent issues on case-insensitive file systems:

 {
     "compilerOptions": {
         // ... existing options ...
         "strict": true,
         "noUnusedLocals": true,
         "noUnusedParameters": true,
-        "noFallthroughCasesInSwitch": true
+        "noFallthroughCasesInSwitch": true,
+        "forceConsistentCasingInFileNames": true
     },
     // ... rest of the config ...
 }
examples/example-vite-react-pwa-recs/src/main.tsx (1)

3-10: Import statements have been reordered.

The changes involve reordering of import statements. The DojoProvider and setup imports have been moved below the index.css import. While this change doesn't affect functionality, it's worth noting a few points:

  1. The reordering follows a common practice of grouping imports (third-party libraries, local modules, and styles).
  2. Placing the CSS import before component imports ensures styles are loaded first, which can be beneficial for initial rendering.

Consider further organizing imports for better readability:

// Third-party imports
import React from "react";
import ReactDOM from "react-dom/client";

// Styles
import "./index.css";

// Local imports
import App from "./App.tsx";
import { dojoConfig } from "../dojoConfig.ts";
import { DojoProvider } from "./dojo/DojoContext.tsx";
import { setup } from "./dojo/generated/setup.ts";

This organization clearly separates third-party, style, and local imports, enhancing code readability.

examples/example-vite-react-app-recs/src/main.tsx (1)

3-10: LGTM! Consider grouping related imports.

The reordering of import statements improves the organization of the code. However, for even better readability and consistency, consider grouping related imports together.

You might want to consider the following grouping:

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";

import App from "./App.tsx";

import { dojoConfig } from "../dojoConfig.ts";
import { DojoProvider } from "./dojo/DojoContext.tsx";
import { setup } from "./dojo/setup.ts";

This groups React-related imports, the main App import, and Dojo-related imports together.

examples/example-vite-react-sdk/src/App.css (4)

8-19: Consider removing will-change property.

The logo styles and hover effects are well-implemented, providing a smooth transition and allowing for technology-specific customization (e.g., React). However, the will-change: filter property on line 11 might be unnecessary unless you're experiencing performance issues specifically related to the filter transitions.

Consider removing the will-change: filter property unless it's addressing a specific performance problem. Overuse of will-change can cause the browser to create unnecessary layers, potentially harming performance instead of improving it.

 .logo {
     height: 6em;
     padding: 1.5em;
-    will-change: filter;
     transition: filter 300ms;
 }

21-34: Consider using a more robust selector for the animated logo.

The keyframe animation for logo rotation and its application are well-implemented. The use of a media query to respect the user's motion preferences is an excellent accessibility practice.

The selector a:nth-of-type(2) .logo on line 31 is very specific and might be fragile if the HTML structure changes. Consider using a more robust selector, such as a specific class for the animated logo. For example:

 @media (prefers-reduced-motion: no-preference) {
-    a:nth-of-type(2) .logo {
+    .logo.animate {
         animation: logo-spin infinite 20s linear;
     }
 }

Then, in your HTML or JSX, you can add the animate class to the logo you want to animate:

<a href="...">
  <img src="..." class="logo animate" alt="..." />
</a>

This approach makes the code more maintainable and less dependent on the specific structure of your HTML.


36-38: Consider enhancing card styles for better visual separation.

The padding for the card class is appropriately set. However, cards typically have additional styles to visually separate them from surrounding content.

Consider adding more styles to enhance the visual appearance of the card, such as a background color, border, or box-shadow. For example:

 .card {
     padding: 2em;
+    background-color: #f8f8f8;
+    border: 1px solid #e0e0e0;
+    border-radius: 8px;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
 }

These additional styles will help the card stand out and provide a clearer visual hierarchy in your layout.


40-42: Consider enhancing readability for .read-the-docs class.

The color choice for the .read-the-docs class is appropriate for secondary or less emphasized text. However, depending on the background color and the importance of this text, you might want to consider adjusting the contrast or adding additional styles.

Consider the following suggestions to enhance readability:

  1. Ensure sufficient color contrast with the background for accessibility.
  2. Add additional styles like font-size or font-weight if this text needs more emphasis.

For example:

 .read-the-docs {
-    color: #888;
+    color: #666; /* Slightly darker for better contrast */
+    font-size: 0.9em;
+    line-height: 1.5;
 }

Remember to test these changes with your actual content and background to ensure optimal readability and accessibility.

examples/example-vite-react-sdk/eslint.config.js (2)

8-20: Configuration options are well-chosen, with a minor suggestion.

The configuration options are appropriate for a TypeScript React project:

  • Ignoring the "dist" directory is a good practice.
  • Extending recommended configs provides a solid foundation.
  • Targeting .ts and .tsx files is correct for TypeScript.
  • Including browser globals and relevant React plugins is appropriate.

Consider updating the ECMAScript version to a more recent one, such as 2021 or later, to take advantage of newer language features. You can do this by changing line 13 to:

-            ecmaVersion: 2020,
+            ecmaVersion: 2021, // or 'latest' for the most recent version

21-26: Rules configuration is good, with room for future expansion.

The rules configuration is appropriate for a starting point:

  • Including recommended rules from react-hooks is a good practice.
  • The react-refresh rule is well-configured for development, allowing for constant exports.

As the project grows, consider adding custom rules or overrides to tailor the linting to your team's specific coding standards. For example, you might want to add rules for consistent naming conventions, import order, or other project-specific requirements.

examples/example-vite-react-threejs-recs/src/gameComponents/Tile.tsx (2)

3-3: Approve THREE import and suggest improvement

The uncommented import of THREE is now correctly aligned with its usage in the component. This change is appropriate and necessary for the component to function properly.

Consider using a more specific import to only include the necessary parts of THREE, which can potentially improve performance and reduce bundle size. For example:

import { BoxGeometry, MeshPhongMaterial, EdgesGeometry, LineBasicMaterial } from 'three';

Line range hint 5-35: Component implementation looks good

The Tile component's implementation is sound and now correctly utilizes the imported THREE library. The use of useMemo for the squareGeometry is a good optimization. The component renders a mesh with a phong material and adds edge lines, which should create a visually distinct tile effect.

Consider adding prop types or TypeScript interfaces for the position prop to improve type safety and code clarity. For example:

interface TileProps {
  position: { x: number; y: number };
}

export const Tile = ({ position }: TileProps) => {
  // ... rest of the component
};
examples/example-vite-react-sdk/package.json (1)

6-11: LGTM: Scripts are well-defined, with a minor suggestion.

The scripts cover all essential development tasks. The build script correctly compiles TypeScript before building with Vite.

Consider adding a type-check script to run TypeScript type checking separately:

 "scripts": {
     "dev": "vite",
     "build": "tsc -b && vite build",
     "lint": "eslint .",
-    "preview": "vite preview"
+    "preview": "vite preview",
+    "type-check": "tsc --noEmit"
 },

This allows developers to check types without a full build, which can be useful during development.

examples/example-vite-react-sdk/src/index.css (3)

1-14: LGTM! Consider adding a custom property for improved accessibility.

The root styles are well-structured and follow best practices. The use of system fonts, color scheme setup, and font rendering optimizations are all good choices.

Consider adding a custom property for the base font size to improve accessibility and make it easier to adjust the overall text size:

 :root {
+    --base-font-size: 16px;
+    font-size: var(--base-font-size);
     font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
     line-height: 1.5;
     font-weight: 400;
     /* ... other properties ... */
 }

33-55: LGTM! Consider using custom properties for consistency.

The heading and button styles are well-defined, including proper interactive states for buttons. The use of em units for button padding is good for scalability.

For better consistency and easier maintenance, consider using custom properties for colors and dimensions:

 :root {
+    --primary-color: #646cff;
+    --primary-hover-color: #535bf2;
+    --button-border-radius: 8px;
     /* ... other properties ... */
 }

 button {
-    border-radius: 8px;
+    border-radius: var(--button-border-radius);
     /* ... other properties ... */
 }
 button:hover {
-    border-color: #646cff;
+    border-color: var(--primary-color);
 }

57-68: LGTM! Consider using custom properties for theme colors.

The media query correctly handles the light color scheme preference, providing appropriate color adjustments for a light theme.

To improve maintainability and make it easier to add or modify theme colors, consider using custom properties for theme-specific colors:

 :root {
+    --text-color: rgba(255, 255, 255, 0.87);
+    --background-color: #242424;
+    --button-background: #1a1a1a;
     /* ... other properties ... */
 }

 body {
-    color: rgba(255, 255, 255, 0.87);
-    background-color: #242424;
+    color: var(--text-color);
+    background-color: var(--background-color);
 }

 button {
-    background-color: #1a1a1a;
+    background-color: var(--button-background);
 }

 @media (prefers-color-scheme: light) {
     :root {
-        color: #213547;
-        background-color: #ffffff;
+        --text-color: #213547;
+        --background-color: #ffffff;
+        --button-background: #f9f9f9;
     }
-    button {
-        background-color: #f9f9f9;
-    }
 }

This approach centralizes color definitions and makes it easier to maintain consistent theming throughout the application.

examples/example-vite-react-sdk/src/bindings.ts (3)

1-7: LGTM! Consider adding JSDoc comments.

The Moves interface is well-structured and includes relevant properties for tracking a player's moves. The use of fieldOrder suggests that the order of fields might be important for serialization or deserialization.

Consider adding JSDoc comments to describe the purpose of each property, especially for fieldOrder and can_move, to improve code readability and maintainability. For example:

interface Moves {
    /** Defines the order of fields, possibly for serialization purposes */
    fieldOrder: string[];
    /** Unique identifier for the player */
    player: string;
    /** Number of moves remaining for the player */
    remaining: number;
    /** The direction of the player's last move */
    last_direction: Direction;
    /** Indicates whether the player is allowed to move */
    can_move: boolean;
}

21-27: LGTM! Consider using numeric values for enum.

The Direction enum provides a clear set of possible directions, including a "None" option for no movement.

Consider using numeric values instead of string values for the enum members, unless there's a specific reason for using strings. This would make the enum more conventional and potentially more efficient:

enum Direction {
    None = 0,
    Left = 1,
    Right = 2,
    Up = 3,
    Down = 4,
}

If string values are necessary, consider adding a comment explaining the rationale behind this choice.


34-40: LGTM! Consider making the schema more flexible.

The Schema type effectively organizes the game-related interfaces under a common namespace, which is good for maintaining a clear structure.

To make the schema more flexible and reusable, consider parameterizing it:

type Schema<T extends string = 'dojo_starter'> = {
    [K in T]: {
        Moves: Moves;
        DirectionsAvailable: DirectionsAvailable;
        Position: Position;
    };
};

This allows for easy creation of similar schemas with different top-level keys, if needed in the future.

examples/example-vite-react-pwa-recs/vite.config.ts (1)

1-5: LGTM! Consider grouping related imports.

The reordering of import statements doesn't affect the functionality and is acceptable. However, for better organization, consider grouping related imports together.

You could group the Vite-related imports together for improved readability:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { VitePWA } from "vite-plugin-pwa";
import wasm from "vite-plugin-wasm";
import topLevelAwait from "vite-plugin-top-level-await";
examples/example-vite-react-sdk/README.md (1)

10-50: Improve clarity and consistency in ESLint configuration instructions

The ESLint configuration expansion section provides valuable information, but there are a few areas that could be improved for clarity and consistency:

  1. The parserOptions code snippet (lines 16-26) uses a different syntax (tseslint.config) compared to the full configuration example (lines 32-50). Consider using consistent syntax across examples to avoid confusion.

  2. The instructions for replacing the ESLint configuration (line 28) don't specify where these changes should be made. Consider adding context, such as "In your eslint.config.js file, replace...".

  3. The final code snippet (lines 32-50) doesn't include the type-aware configurations mentioned earlier (lines 28-29). Consider updating the example to include these configurations for completeness.

To address these points, consider updating the final code snippet as follows:

// eslint.config.js
import tseslint from "@typescript-eslint/eslint-plugin";
import react from "eslint-plugin-react";

export default tseslint.config({
    // Set the react version
    settings: { react: { version: "18.3" } },
    plugins: {
        // Add the react plugin
        react,
    },
    extends: [
        tseslint.configs.recommendedTypeChecked, // or strictTypeChecked
        tseslint.configs.stylisticTypeChecked,
    ],
    languageOptions: {
        parserOptions: {
            project: ["./tsconfig.node.json", "./tsconfig.app.json"],
            tsconfigRootDir: import.meta.dirname,
        },
    },
    rules: {
        // other rules...
        // Enable react recommended rules
        ...react.configs.recommended.rules,
        ...react.configs["jsx-runtime"].rules,
    },
});

This updated example incorporates all the mentioned configurations and uses consistent syntax throughout.

examples/example-vite-react-app-recs/src/dojo/setup.ts (1)

1-6: LGTM! Consider grouping related imports.

The reorganization of import statements improves the overall structure of the file. However, to further enhance readability, consider grouping related imports together. For example:

import { DojoConfig, DojoProvider } from "@dojoengine/core";
import { BurnerManager } from "@dojoengine/create-burner";
import { getSyncEvents } from "@dojoengine/state";
import * as torii from "@dojoengine/torii-client";

import { Account, ArraySignatureType } from "starknet";

import { createClientComponents } from "./createClientComponents";
import { createSystemCalls } from "./createSystemCalls";
import { setupWorld } from "./typescript/contracts.gen";
import { defineContractComponents } from "./typescript/models.gen";
import { world } from "./world";

This grouping separates external dependencies from local imports, making the import structure more clear.

examples/example-vanillajs-phaser-recs/src/dojo/setup.ts (1)

1-5: LGTM! Import statements reorganized for better readability.

The reorganization of import statements improves the code's readability by grouping related imports together. This change doesn't affect the functionality of the code.

Consider adding a blank line between external library imports and local module imports to further improve readability:

 import { Account, RpcProvider } from "starknet";
+
 import { Config } from "../../dojoConfig.ts";
 import {
     ClientComponents,
     createClientComponents,
 } from "./createClientComponent.ts";

Also applies to: 12-16

examples/example-vite-react-app-recs/src/dojo/createSystemCalls.ts (3)

88-88: Good improvement: Dynamic direction parameter.

The change from a hardcoded direction to a dynamic direction parameter improves flexibility and type safety. This aligns well with the newly imported Direction enum.

Consider adding a type annotation to the direction parameter in the function signature for extra clarity:

const move = async (account: Account, direction: Direction) => {
  // ... rest of the function
}

Line range hint 107-114: Address commented-out code in error handling.

The commented-out code in the catch and finally blocks suggests that error handling and cleanup logic for Position and Moves overrides have been disabled. This could lead to potential issues if errors occur or if overrides are not properly managed.

Consider one of the following approaches:

  1. If the code is no longer needed, remove it entirely instead of commenting it out.
  2. If the functionality is still required but needs revision, update the code to handle errors and cleanup appropriately.
  3. If this is a temporary change for testing purposes, add a TODO comment explaining the reason and the plan for addressing it.

Example of option 3:

catch (e) {
  console.log(e);
  // TODO: Revisit error handling for Position and Moves overrides
  // Position.removeOverride(positionId);
  // Moves.removeOverride(movesId);
}

Line range hint 1-124: Overall assessment: Good improvements with some areas for attention.

The changes in this file generally improve code organization and flexibility, particularly with the reorganized imports and the more dynamic handling of the direction parameter in the move function. However, there are a few areas that could benefit from further attention:

  1. Consider adding type annotations to function parameters for improved clarity.
  2. Address the commented-out code in the error handling section of the move function to ensure proper error management and resource cleanup.

These adjustments will enhance the overall quality and maintainability of the code.

examples/example-vue-app-recs/src/dojo/createSystemCalls.ts (1)

7-11: LGTM! Consider further organizing imports.

The reordering of import statements improves readability by grouping related imports together. This change doesn't affect the functionality of the code.

For even better organization, consider grouping imports from external libraries first, followed by local imports. For example:

import { uuid } from "@latticexyz/utils";
import { Account } from "starknet";

import { Direction, updatePositionWithDirection } from "../utils";
import { ClientComponents } from "./createClientComponents";

This ordering makes it easier to distinguish between external dependencies and local modules at a glance.

examples/example-vite-react-threejs-recs/src/dojo/createSystemCalls.ts (1)

7-11: LGTM! Consider grouping related imports.

The reordering of import statements improves code organization without affecting functionality. For even better readability, consider grouping related imports together. For example:

import { uuid } from "@latticexyz/utils";
import { AccountInterface } from "starknet";

import { Direction, updatePositionWithDirection } from "../utils";
import { ClientComponents } from "./createClientComponents";

This groups external library imports separately from local imports.

examples/example-vite-react-pwa-recs/src/dojo/createSystemCalls.ts (1)

7-11: LGTM! Consider further optimizing import order.

The reordering of import statements improves the organization of the code without affecting its functionality. The new grouping is more logical, with related imports placed together.

For even better organization, consider grouping the imports as follows:

  1. External library imports (e.g., from "@dojoengine/recs", "@latticexyz/utils", "starknet")
  2. Local imports (e.g., from "../utils")
  3. Generated or type imports (e.g., from "./generated/contractComponents", "./generated/generated")

This ordering can make it easier to distinguish between different types of imports at a glance.

examples/example-vanillajs-phaser-recs/src/dojo/systems.ts (1)

7-13: LGTM! Consider grouping related imports.

The changes to the import statements are correct and don't introduce any issues. All imported entities are used in the file, justifying their presence.

For better organization, consider grouping related imports together. For example:

import { Entity, getComponentValue } from "@dojoengine/recs";
import { getEntityIdFromKeys, getEvents, setComponentsFromEvents } from "@dojoengine/utils";
import { uuid } from "@latticexyz/utils";
import { AccountInterface } from "starknet";

import { ClientComponents } from "./createClientComponent";
import { ContractComponents } from "./defineContractComponents";
import type { IWorld } from "./defineContractSystems";
import { Direction, updatePositionWithDirection } from "./utils";

This groups external library imports together, followed by local imports.

examples/example-vite-react-app-recs/src/App.tsx (3)

11-17: Approve the introduction of DirectionEnum with a minor suggestion.

The addition of DirectionEnum improves type safety and clarity in representing directions. However, consider adjusting the None value for consistency:

 enum DirectionEnum {
-    None = "0",
+    None = "None",
     Left = "Left",
     Right = "Right",
     Up = "Up",
     Down = "Down",
 }

This change would make all enum values consistent string representations.


152-154: Approve the updated move logic with a suggestion for consistency.

The use of DirectionEnum.Up improves type safety and aligns with the new enum. Good job on retaining the boundary check.

Consider extracting the boundary check logic into a separate function for consistency and reusability across all directions. For example:

const canMove = (direction: DirectionEnum) => {
  if (!position) return false;
  switch (direction) {
    case DirectionEnum.Up: return position.vec.y > 0;
    case DirectionEnum.Down: return true; // Assuming no lower bound
    case DirectionEnum.Left: return position.vec.x > 0;
    case DirectionEnum.Right: return true; // Assuming no right bound
    default: return false;
  }
};

// Usage
onClick={() => canMove(DirectionEnum.Up)
  ? move(account.account, { type: DirectionEnum.Up })
  : console.log("Reached the border of the world.")}

This approach would centralize the boundary logic and make it easier to maintain and extend in the future.


Line range hint 1-194: Overall assessment: Improvements with room for refinement

The introduction of DirectionEnum and its usage in movement logic significantly enhances type safety and code clarity. These changes are a step in the right direction for maintaining a robust codebase.

However, there are a few areas that could benefit from further refinement:

  1. Consistency in enum values (particularly the None value).
  2. Uniform boundary checking across all directions.
  3. Potential refactoring to centralize movement logic and boundary checks.

Addressing these points will further improve the code's maintainability and reduce the likelihood of bugs related to movement and game boundaries.

Consider implementing a MovementManager class or a custom hook (e.g., useMovement) to encapsulate all movement-related logic, including boundary checks and direction management. This would centralize the logic, making it easier to maintain and extend in the future.

Example structure:

const useMovement = (position, account) => {
  const canMove = (direction: DirectionEnum) => {
    // Implement boundary checks here
  };

  const move = (direction: DirectionEnum) => {
    if (canMove(direction)) {
      // Call the actual move function
    } else {
      console.log("Cannot move in that direction");
    }
  };

  return { move };
};

// Usage in component
const { move } = useMovement(position, account);

// In JSX
<button onClick={() => move(DirectionEnum.Up)}>Move Up</button>

This approach would simplify the component code and provide a single point of control for all movement-related functionality.

examples/example-vite-react-sdk/src/App.tsx (2)

81-117: Consistent error handling in entity fetching

In the fetchEntities function, errors are logged to the console but not communicated to the user interface. Consider providing user feedback or error messages in the UI to enhance user experience, especially if fetching entities is critical to the application's functionality.


145-146: Simplify boolean rendering without toString()

The can_move property is likely a boolean. Using toString() to convert it to a string is unnecessary when rendering. You can directly render it using JavaScript expressions.

Apply this diff to simplify the code:

-{entity.models.dojo_starter.Moves?.can_move?.toString() ?? "N/A"}
+{entity.models.dojo_starter.Moves?.can_move ? 'True' : 'False'}

Alternatively, handle the undefined case:

-{entity.models.dojo_starter.Moves?.can_move?.toString() ?? "N/A"}
+{entity.models.dojo_starter.Moves?.can_move !== undefined
+    ? entity.models.dojo_starter.Moves.can_move ? 'True' : 'False'
+    : "N/A"}
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 69964b7 and cf7387b.

Files ignored due to path filters (62)
  • examples/example-nodejs-bot/images/Step 1.png is excluded by !**/*.png
  • examples/example-nodejs-bot/images/Step 2.png is excluded by !**/*.png
  • examples/example-nodejs-bot/images/Step 3.png is excluded by !**/*.png
  • examples/example-nodejs-bot/images/Step 4.png is excluded by !**/*.png
  • examples/example-nodejs-bot/images/Step 5.png is excluded by !**/*.png
  • examples/example-nodejs-bot/images/Step 6.png is excluded by !**/*.png
  • examples/example-nodejs-bot/images/Step 7.png is excluded by !**/*.png
  • examples/example-nodejs-bot/images/railway.png is excluded by !**/*.png
  • examples/example-nodejs-bot/src/generated/graphql.ts is excluded by !**/generated/**
  • examples/example-vanillajs-phaser-recs/assets/sprGrass.png is excluded by !**/*.png
  • examples/example-vanillajs-phaser-recs/assets/sprSand.png is excluded by !**/*.png
  • examples/example-vanillajs-phaser-recs/assets/sprWater.png is excluded by !**/*.png
  • examples/example-vanillajs-phaser-recs/public/favicon.ico is excluded by !**/*.ico
  • examples/example-vite-react-phaser-recs/public/assets/atlases/atlas.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/public/assets/paper.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/public/assets/rock.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/public/assets/scissors.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/public/assets/texture.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/public/assets/tilesets/land.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/public/assets/tilesets/world.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/public/paper.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/public/rock.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/public/scissors.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/public/texture.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/public/vite.svg is excluded by !**/*.svg
  • examples/example-vite-react-phaser-recs/src/assets/paper.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/src/assets/rock.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/src/assets/scissors.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/src/assets/texture.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/src/assets/tilesets/land.png is excluded by !**/*.png
  • examples/example-vite-react-phaser-recs/src/dojo/generated/contractComponents.ts is excluded by !**/generated/**
  • examples/example-vite-react-phaser-recs/src/dojo/generated/generated.ts is excluded by !**/generated/**
  • examples/example-vite-react-phaser-recs/src/dojo/generated/setup.ts is excluded by !**/generated/**
  • examples/example-vite-react-phaser-recs/src/dojo/generated/world.ts is excluded by !**/generated/**
  • examples/example-vite-react-pwa-recs/public/apple-touch-icon.png is excluded by !**/*.png
  • examples/example-vite-react-pwa-recs/public/desktop-app-screenshot.png is excluded by !**/*.png
  • examples/example-vite-react-pwa-recs/public/favicon.ico is excluded by !**/*.ico
  • examples/example-vite-react-pwa-recs/public/favicon.svg is excluded by !**/*.svg
  • examples/example-vite-react-pwa-recs/public/pwa-192x192.png is excluded by !**/*.png
  • examples/example-vite-react-pwa-recs/public/pwa-512x512.png is excluded by !**/*.png
  • examples/example-vite-react-pwa-recs/public/pwa-maskable-192x192.png is excluded by !**/*.png
  • examples/example-vite-react-pwa-recs/public/pwa-maskable-512x512.png is excluded by !**/*.png
  • examples/example-vite-react-pwa-recs/src/assets/dojo.svg is excluded by !**/*.svg
  • examples/example-vite-react-pwa-recs/src/dojo/generated/contractComponents.ts is excluded by !**/generated/**
  • examples/example-vite-react-pwa-recs/src/dojo/generated/generated.ts is excluded by !**/generated/**
  • examples/example-vite-react-pwa-recs/src/dojo/generated/setup.ts is excluded by !**/generated/**
  • examples/example-vite-react-pwa-recs/src/dojo/generated/world.ts is excluded by !**/generated/**
  • examples/example-vite-react-sdk/public/vite.svg is excluded by !**/*.svg
  • examples/example-vite-react-sdk/src/assets/react.svg is excluded by !**/*.svg
  • examples/example-vite-react-threejs-recs/src/dojo/generated/contractComponents.ts is excluded by !**/generated/**
  • examples/example-vite-react-threejs-recs/src/dojo/generated/generated.ts is excluded by !**/generated/**
  • examples/example-vite-react-threejs-recs/src/dojo/generated/setup.ts is excluded by !**/generated/**
  • examples/example-vite-react-threejs-recs/src/dojo/generated/world.ts is excluded by !**/generated/**
  • examples/example-vue-app-recs/public/vite.svg is excluded by !**/*.svg
  • examples/example-vue-app-recs/src/assets/vue.svg is excluded by !**/*.svg
  • examples/example-vue-app-recs/src/dojo/generated/contractComponents.ts is excluded by !**/generated/**
  • examples/example-vue-app-recs/src/dojo/generated/generated.ts is excluded by !**/generated/**
  • examples/example-vue-app-recs/src/dojo/generated/setup.ts is excluded by !**/generated/**
  • examples/example-vue-app-recs/src/dojo/generated/world.ts is excluded by !**/generated/**
  • media/dojo-init.mov is excluded by !**/*.mov
  • media/dojo-mark-full-dark.svg is excluded by !**/*.svg
  • media/screen-grab.png is excluded by !**/*.png
Files selected for processing (69)
  • examples/example-nodejs-bot/dojoConfig.ts (1 hunks)
  • examples/example-nodejs-bot/src/commands/getMoves.ts (1 hunks)
  • examples/example-nodejs-bot/src/config.ts (1 hunks)
  • examples/example-nodejs-bot/src/index.ts (1 hunks)
  • examples/example-vanillajs-phaser-recs/dojoConfig.ts (1 hunks)
  • examples/example-vanillajs-phaser-recs/src/dojo/createClientComponent.ts (1 hunks)
  • examples/example-vanillajs-phaser-recs/src/dojo/defineContractSystems.ts (1 hunks)
  • examples/example-vanillajs-phaser-recs/src/dojo/setup.ts (1 hunks)
  • examples/example-vanillajs-phaser-recs/src/dojo/systems.ts (1 hunks)
  • examples/example-vanillajs-phaser-recs/src/entities.ts (1 hunks)
  • examples/example-vanillajs-phaser-recs/src/main.ts (1 hunks)
  • examples/example-vanillajs-phaser-recs/src/scenes/scene-main.ts (1 hunks)
  • examples/example-vanillajs-phaser-recs/vite.config.ts (1 hunks)
  • examples/example-vite-react-app-recs/dojoConfig.ts (1 hunks)
  • examples/example-vite-react-app-recs/src/App.tsx (3 hunks)
  • examples/example-vite-react-app-recs/src/dojo/DojoContext.tsx (1 hunks)
  • examples/example-vite-react-app-recs/src/dojo/createClientComponents.ts (1 hunks)
  • examples/example-vite-react-app-recs/src/dojo/createSystemCalls.ts (2 hunks)
  • examples/example-vite-react-app-recs/src/dojo/setup.ts (1 hunks)
  • examples/example-vite-react-app-recs/src/dojo/typescript/contracts.gen.ts (1 hunks)
  • examples/example-vite-react-app-recs/src/dojo/useDojo.tsx (1 hunks)
  • examples/example-vite-react-app-recs/src/main.tsx (1 hunks)
  • examples/example-vite-react-app-recs/vite.config.ts (1 hunks)
  • examples/example-vite-react-pwa-recs/dojoConfig.ts (1 hunks)
  • examples/example-vite-react-pwa-recs/src/App.tsx (1 hunks)
  • examples/example-vite-react-pwa-recs/src/dojo/DojoContext.tsx (1 hunks)
  • examples/example-vite-react-pwa-recs/src/dojo/createClientComponents.ts (1 hunks)
  • examples/example-vite-react-pwa-recs/src/dojo/createSystemCalls.ts (1 hunks)
  • examples/example-vite-react-pwa-recs/src/dojo/useDojo.tsx (1 hunks)
  • examples/example-vite-react-pwa-recs/src/main.tsx (1 hunks)
  • examples/example-vite-react-pwa-recs/vite.config.ts (1 hunks)
  • examples/example-vite-react-sdk/README.md (1 hunks)
  • examples/example-vite-react-sdk/dojoConfig.ts (1 hunks)
  • examples/example-vite-react-sdk/eslint.config.js (1 hunks)
  • examples/example-vite-react-sdk/index.html (1 hunks)
  • examples/example-vite-react-sdk/package.json (1 hunks)
  • examples/example-vite-react-sdk/src/App.css (1 hunks)
  • examples/example-vite-react-sdk/src/App.tsx (1 hunks)
  • examples/example-vite-react-sdk/src/bindings.ts (1 hunks)
  • examples/example-vite-react-sdk/src/index.css (1 hunks)
  • examples/example-vite-react-sdk/src/main.tsx (1 hunks)
  • examples/example-vite-react-sdk/tsconfig.app.json (1 hunks)
  • examples/example-vite-react-sdk/tsconfig.json (1 hunks)
  • examples/example-vite-react-sdk/tsconfig.node.json (1 hunks)
  • examples/example-vite-react-sdk/vite.config.ts (1 hunks)
  • examples/example-vite-react-threejs-recs/dojoConfig.ts (1 hunks)
  • examples/example-vite-react-threejs-recs/src/App.tsx (1 hunks)
  • examples/example-vite-react-threejs-recs/src/dojo/DojoContext.tsx (1 hunks)
  • examples/example-vite-react-threejs-recs/src/dojo/createClientComponents.ts (1 hunks)
  • examples/example-vite-react-threejs-recs/src/dojo/createSystemCalls.ts (1 hunks)
  • examples/example-vite-react-threejs-recs/src/dojo/useDojo.tsx (1 hunks)
  • examples/example-vite-react-threejs-recs/src/gameComponents/Player.tsx (1 hunks)
  • examples/example-vite-react-threejs-recs/src/gameComponents/Players.tsx (1 hunks)
  • examples/example-vite-react-threejs-recs/src/gameComponents/Three.tsx (1 hunks)
  • examples/example-vite-react-threejs-recs/src/gameComponents/Tile.tsx (1 hunks)
  • examples/example-vite-react-threejs-recs/src/gameComponents/TileGrid.tsx (1 hunks)
  • examples/example-vite-react-threejs-recs/src/gameComponents/UIContainer.tsx (1 hunks)
  • examples/example-vite-react-threejs-recs/src/lib/utils.ts (1 hunks)
  • examples/example-vite-react-threejs-recs/src/main.tsx (1 hunks)
  • examples/example-vite-react-threejs-recs/vite.config.ts (1 hunks)
  • examples/example-vue-app-recs/.gitignore (1 hunks)
  • examples/example-vue-app-recs/dojoConfig.ts (1 hunks)
  • examples/example-vue-app-recs/src/App.vue (1 hunks)
  • examples/example-vue-app-recs/src/dojo/createClientComponents.ts (1 hunks)
  • examples/example-vue-app-recs/src/dojo/createSystemCalls.ts (1 hunks)
  • examples/example-vue-app-recs/src/main.ts (1 hunks)
  • examples/example-vue-app-recs/src/utils/index.ts (1 hunks)
  • examples/example-vue-app-recs/src/vite-env.d.ts (1 hunks)
  • examples/example-vue-app-recs/vite.config.ts (1 hunks)
Files skipped from review due to trivial changes (30)
  • examples/example-nodejs-bot/src/commands/getMoves.ts
  • examples/example-nodejs-bot/src/config.ts
  • examples/example-nodejs-bot/src/index.ts
  • examples/example-vanillajs-phaser-recs/src/dojo/createClientComponent.ts
  • examples/example-vanillajs-phaser-recs/src/entities.ts
  • examples/example-vanillajs-phaser-recs/src/main.ts
  • examples/example-vanillajs-phaser-recs/src/scenes/scene-main.ts
  • examples/example-vite-react-app-recs/dojoConfig.ts
  • examples/example-vite-react-app-recs/src/dojo/DojoContext.tsx
  • examples/example-vite-react-app-recs/src/dojo/createClientComponents.ts
  • examples/example-vite-react-app-recs/src/dojo/typescript/contracts.gen.ts
  • examples/example-vite-react-app-recs/src/dojo/useDojo.tsx
  • examples/example-vite-react-pwa-recs/src/dojo/DojoContext.tsx
  • examples/example-vite-react-pwa-recs/src/dojo/useDojo.tsx
  • examples/example-vite-react-threejs-recs/dojoConfig.ts
  • examples/example-vite-react-threejs-recs/src/dojo/DojoContext.tsx
  • examples/example-vite-react-threejs-recs/src/dojo/createClientComponents.ts
  • examples/example-vite-react-threejs-recs/src/dojo/useDojo.tsx
  • examples/example-vite-react-threejs-recs/src/gameComponents/Player.tsx
  • examples/example-vite-react-threejs-recs/src/gameComponents/Players.tsx
  • examples/example-vite-react-threejs-recs/src/gameComponents/Three.tsx
  • examples/example-vite-react-threejs-recs/src/gameComponents/TileGrid.tsx
  • examples/example-vite-react-threejs-recs/src/gameComponents/UIContainer.tsx
  • examples/example-vite-react-threejs-recs/src/lib/utils.ts
  • examples/example-vite-react-threejs-recs/src/main.tsx
  • examples/example-vite-react-threejs-recs/vite.config.ts
  • examples/example-vue-app-recs/src/dojo/createClientComponents.ts
  • examples/example-vue-app-recs/src/main.ts
  • examples/example-vue-app-recs/src/utils/index.ts
  • examples/example-vue-app-recs/vite.config.ts
Additional context used
Biome
examples/example-vite-react-sdk/tsconfig.app.json

[error] 9-9: JSON standard does not allow comments.

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

examples/example-vite-react-sdk/tsconfig.node.json

[error] 8-8: JSON standard does not allow comments.

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

Additional comments not posted (59)
examples/example-vue-app-recs/src/vite-env.d.ts (1)

1-1: LGTM! Proper setup for Vite with TypeScript.

This file correctly sets up the TypeScript environment for a Vite project. The triple-slash directive /// <reference types="vite/client" /> ensures that TypeScript is aware of Vite-specific types, enabling better autocomplete and type checking for Vite's client-side APIs.

This is a best practice for Vite projects using TypeScript, as it enhances the development experience by providing proper type information for Vite-specific features.

examples/example-vite-react-pwa-recs/dojoConfig.ts (1)

3-3: Verify the manifest file path and consider using a relative import.

The new import statement introduces a dependency on a specific manifest file located outside the current directory structure. This might affect the portability of the code.

To ensure the manifest file exists and is accessible, run the following script:

#!/bin/bash
# Description: Verify the existence and accessibility of the manifest file.

# Test: Check if the manifest file exists
if [ -f "dojo/dojo-starter/manifests/dev/deployment/manifest.json" ]; then
    echo "Manifest file exists."
    # Display the first few lines of the manifest file
    head -n 5 "dojo/dojo-starter/manifests/dev/deployment/manifest.json"
else
    echo "Error: Manifest file not found."
fi

# Test: Check if there are any other manifest files in the project
echo "Other manifest files in the project:"
fd -e json -p "manifest.*\.json$"

Consider using a relative import path if possible, to improve code portability.

examples/example-vue-app-recs/dojoConfig.ts (2)

1-1: LGTM: Correct import for Dojo configuration.

The import of createDojoConfig from "@dojoengine/core" is appropriate for setting up the Dojo configuration.


5-7: LGTM: Dojo configuration created and exported correctly.

The creation and export of dojoConfig using createDojoConfig with the imported manifest is correct.

Please verify if any additional configuration options are required for your specific project needs. The current setup is minimal, which might be intentional, but it's worth confirming.

To check for available configuration options, you can run:

#!/bin/bash
# Check for available configuration options in the @dojoengine/core package
rg --type typescript -A 10 "interface.*Config" $(fd -t d node_modules/@dojoengine/core)

This will help you identify if there are other configuration options you might want to consider including.

examples/example-nodejs-bot/dojoConfig.ts (3)

5-5: LGTM: Proper export of configuration.

The dojoConfig is correctly exported as a constant. This is a good practice for configuration objects, ensuring they cannot be accidentally modified elsewhere in the codebase.


1-7: Overall assessment: Well-structured configuration setup.

This file effectively sets up the Dojo configuration using modern JavaScript features and good practices. It imports necessary dependencies, creates the configuration object, and exports it properly. The code is concise and serves its purpose well.

Consider the earlier suggestions about simplifying the import path and verifying additional configuration options, but these are minor optimizations. The current implementation is solid and ready for use in the project.


5-7: Verify if additional configuration options are needed.

The usage of createDojoConfig looks correct. The manifest is properly passed as an argument.

However, it's worth checking if createDojoConfig accepts any additional optional parameters that might be beneficial for your use case. Run the following script to verify the function signature:

Verification successful

Usage of createDojoConfig is correct.

The manifest is properly passed as an argument. Additional configuration options are available and can be utilized as needed.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the signature of createDojoConfig function

# Test: Search for the createDojoConfig function definition
ast-grep --lang typescript --pattern 'function createDojoConfig($_) { $$$ }'

Length of output: 1144

examples/example-vanillajs-phaser-recs/dojoConfig.ts (1)

3-3: Verify the new import path and update other occurrences if necessary.

The updated import path looks correct, assuming the project structure has been reorganized to include an "examples" directory. However, please ensure that:

  1. The new path "../../../examples/dojo/dojo-starter/manifests/dev/deployment/manifest.json" is correct and the file exists at this location.
  2. This change is consistent with the project's new structure and conventions.

To ensure all occurrences of the old import path have been updated, please run the following script:

If the first command returns any results, those files may need to be updated as well. The second command should confirm the existence of the new manifest file.

examples/example-vite-react-sdk/src/main.tsx (1)

1-6: LGTM: Import statements are correct and follow best practices.

The import statements are well-structured and appropriate for a React 18 application. The use of named imports for React components and the placement of the CSS import at the end are in line with current best practices.

examples/example-vite-react-app-recs/vite.config.ts (2)

1-5: LGTM! Import statements reordered logically.

The reordering of import statements improves the organization of the file:

  1. Core Vite import (defineConfig) is now at the top.
  2. Plugin imports follow, maintaining a consistent order.

This change enhances readability without affecting functionality.


Line range hint 7-10: Configuration remains correct and consistent.

The configuration object correctly uses all imported plugins (react, wasm, topLevelAwait) in the same order as they are imported. The reordering of imports hasn't introduced any inconsistencies or issues in the configuration.

examples/example-vite-react-sdk/vite.config.ts (2)

1-4: Imports look good and are appropriate for the project.

The imports are well-chosen for a Vite project using React with WebAssembly support:

  1. @vitejs/plugin-react: Enables React support in Vite.
  2. defineConfig from Vite: Provides type checking for the Vite configuration.
  3. vite-plugin-top-level-await: Allows the use of top-level await in the project.
  4. vite-plugin-wasm: Adds WebAssembly support to the Vite build process.

These imports set up a robust development environment for a React application with advanced features.


1-9: Overall, the Vite configuration aligns well with the PR objectives.

This configuration file sets up a solid foundation for the "feat: sdk v2" pull request. It enables key features that will support the implementation of a typed query language on top of the Torii client:

  1. React support for building the user interface.
  2. WebAssembly support, which might be crucial for performance-critical operations.
  3. Top-level await support, which can simplify asynchronous code handling.

These features align well with the experimental nature of the implementation and provide a flexible environment for further development and testing of the SDK v2 features.

As the PR progresses, you may need to adjust this configuration to accommodate additional build requirements or optimizations specific to the typed query language implementation.

examples/example-vue-app-recs/.gitignore (1)

1-24: LGTM! Well-structured .gitignore file.

The .gitignore file is well-organized and covers the standard ignore patterns for a Vue.js project. It effectively excludes logs, build artifacts, and editor-specific files from version control.

examples/example-vanillajs-phaser-recs/vite.config.ts (2)

Line range hint 8-8: LGTM: WASM plugin correctly applied

The wasm() plugin is correctly applied in the Vite configuration. This ensures that WebAssembly modules will be properly handled during the build process.


4-4: WASM plugin enabled: Verify WebAssembly usage

The wasm plugin from vite-plugin-wasm has been uncommented and is now actively imported. This change enables WebAssembly support in the Vite build process.

To ensure this change is intentional and necessary, please run the following script to check for WebAssembly usage in the project:

If the script doesn't find any WebAssembly usage, consider removing the WASM plugin to keep the configuration lean.

Verification successful

WASM plugin usage verified

The wasm plugin from vite-plugin-wasm is actively used across multiple configuration files and is necessary for dependencies like @dojoengine/torii-wasm. No unnecessary WASM configurations detected.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for WebAssembly usage in the project

# Test: Search for WebAssembly-related imports or usage
rg --type-add 'web:*.{js,ts,jsx,tsx}' --type web -i '(webassembly|wasm)'

# Test: Check for .wasm files in the project
fd -e wasm

Length of output: 1562

examples/example-vite-react-sdk/index.html (3)

1-2: LGTM: Proper HTML5 and language declaration.

The HTML5 doctype and language declaration are correctly implemented, following best practices for modern web development and accessibility.


9-12: LGTM: Body section is correctly set up for a React application.

The body section is properly structured for a React application:

  • The root div is correctly placed as the mounting point for the React components.
  • The script tag is properly set to load the main TypeScript file as a module, using the correct relative path for Vite's default configuration.

1-13: Overall, the HTML structure is well-implemented for a Vite + React + TypeScript application.

This index.html file provides a solid foundation for your Dojo Engine SDK example application. It includes all necessary elements and follows best practices for modern web development. The only suggested improvement is to update the title to better reflect your specific application.

Great job on setting up a clean and efficient entry point for your React application!

examples/example-vite-react-pwa-recs/src/dojo/createClientComponents.ts (2)

1-1: New import added for overridableComponent.

The addition of overridableComponent from @dojoengine/recs introduces new functionality to the file. This import allows for the creation of overridable components, which can be useful for runtime modifications or extensions of component behavior.


Line range hint 12-16: Usage of overridableComponent for Position and Moves components.

The Position and Moves components are now wrapped with overridableComponent. This change allows these components to be potentially overridden at runtime, which can provide more flexibility in game logic or state management.

To ensure this change doesn't introduce unexpected behavior, please verify the following:

This script will help identify any potential areas that might need adjustment due to the new overridable nature of these components.

Verification successful

Adjusting Shell Scripts to Verify Component Usages


Component Override Verification Successful

The Position and Moves components are consistently wrapped with overridableComponent in all relevant createClientComponents.ts files. No unexpected usages were found outside these areas, ensuring that the components remain overridable without introducing unintended behavior.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any other usages of Position and Moves components that might be affected by this change.

# Test: Search for usages of Position and Moves components
echo "Searching for Position component usage:"
rg --type typescript "Position" -g '!**/createClientComponents.ts'

echo "Searching for Moves component usage:"
rg --type typescript "Moves" -g '!**/createClientComponents.ts'

# Test: Check if overridableComponent is used consistently
echo "Checking for other uses of overridableComponent:"
rg --type typescript "overridableComponent"

Length of output: 558


Script:

#!/bin/bash
# Description: Check for any other usages of Position and Moves components that might be affected by this change.

# Test: Search for usages of Position and Moves components
echo "Searching for Position component usage:"
rg "Position" --glob '!**/createClientComponents.ts' --glob '*.ts' --glob '*.tsx'

echo "Searching for Moves component usage:"
rg "Moves" --glob '!**/createClientComponents.ts' --glob '*.ts' --glob '*.tsx'

# Test: Check if overridableComponent is used consistently
echo "Checking for other uses of overridableComponent:"
rg "overridableComponent" --glob '*.ts' --glob '*.tsx'

Length of output: 33089

examples/example-vite-react-sdk/tsconfig.node.json (3)

2-7: Compiler options look good, with a note on skipLibCheck.

The compiler options are well-configured for a modern TypeScript project:

  • Target ES2022 and ES2023 library ensure access to recent JavaScript features.
  • ESNext module setting is suitable for the latest module syntax.

Note: skipLibCheck is enabled, which can speed up compilation but may hide type errors in dependencies. Ensure your development process includes thorough testing to catch any issues that might be missed due to this setting.


8-13: Bundler mode settings are well-configured.

The bundler mode settings are appropriate for a modern TypeScript project using a bundler like Vite:

  • "bundler" moduleResolution is ideal for use with tools like Vite.
  • isolatedModules and forced moduleDetection improve compatibility and help catch potential issues.
  • noEmit is correctly set for projects where the bundler handles output.

Note: allowImportingTsExtensions is enabled, which allows for convenient imports with .ts extensions. However, be aware that this might cause issues with some tools or when migrating to different build systems. Consider using path aliases as an alternative if you encounter any compatibility problems.

Tools
Biome

[error] 8-8: JSON standard does not allow comments.

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


1-22: Overall, excellent TypeScript configuration for a Vite project.

This tsconfig.node.json file is well-crafted for a modern TypeScript project using Vite:

  • It leverages recent ECMAScript features (ES2022/ES2023).
  • The bundler mode settings are optimized for tools like Vite.
  • Strict type-checking and linting options are enabled, promoting code quality.

The configuration strikes a good balance between leveraging modern TypeScript features and maintaining type safety. It's clear that this setup is tailored specifically for the Vite environment, which is appropriate for the project structure.

Tools
Biome

[error] 8-8: JSON standard does not allow comments.

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 9-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

examples/example-vite-react-threejs-recs/src/App.tsx (1)

1-1: LGTM: New component imports added correctly.

The new imports for ThreeGrid and UIContainer are correctly added and follow React best practices. These components seem to be part of the game-related functionality, which aligns with the PR objectives of implementing a typed query language on top of the Torii client.

Also applies to: 5-5

examples/example-vite-react-sdk/tsconfig.app.json (3)

9-15: Excellent bundler mode configuration!

The bundler mode settings are well-optimized for use with modern bundlers like Vite. The "moduleResolution": "bundler" and related options ensure smooth integration with the build process.

The "jsx": "react-jsx" setting is perfect for modern React projects, enabling the new JSX transform.

Tools
Biome

[error] 9-9: JSON standard does not allow comments.

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


23-23: Appropriate include directive.

The "include": ["src"] setting is correct for a typical project structure, ensuring that TypeScript only processes files within the src directory.

This helps maintain a clean separation between source code and other project files.


1-24: Overall, excellent TypeScript configuration for a Vite React project!

This tsconfig.app.json file is well-structured and follows best practices. It provides a solid foundation for your project with appropriate settings for modern web development using Vite and React.

The configuration enables strict type checking, optimizes for bundler usage, and sets up the correct environment for React development. The minor suggestions provided earlier (considering skipLibCheck trade-offs and adding forceConsistentCasingInFileNames) are optional improvements to an already strong configuration.

Tools
Biome

[error] 9-9: JSON standard does not allow comments.

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 10-10: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 11-11: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 12-12: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 13-13: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

examples/example-vite-react-pwa-recs/src/main.tsx (2)

Line range hint 12-30: The overall structure and implementation look good.

The init function is well-structured and follows good practices:

  1. It checks for the existence of the root element and throws an error if not found.
  2. The asynchronous setup function is called before rendering.
  3. React Strict Mode is used, which helps identify potential problems in the application.
  4. The DojoProvider correctly wraps the main App component, providing the setup result to the app.

Line range hint 1-32: Overall, the changes and existing code look good.

The file maintains a clean structure with proper setup for a React application using the Dojo framework. The changes to import ordering don't affect functionality and follow common practices. The implementation of the init function is solid, with good error handling and proper use of async/await.

Keep up the good work, and consider the minor suggestion for import organization to further improve code readability.

examples/example-vite-react-sdk/src/App.css (1)

1-6: LGTM: Root element styles are well-defined.

The styles for the root element are appropriate for centering and constraining the main content of the application. The use of max-width allows for responsiveness while maintaining a readable width on larger screens.

examples/example-vite-react-sdk/eslint.config.js (3)

1-5: LGTM: Imports are appropriate for the project.

The imports are well-chosen for a TypeScript React project using Vite. The use of @eslint/js indicates that this configuration is using the new flat config format for ESLint, which is a good modern practice.


7-28: LGTM: Configuration structure is well-organized.

The configuration uses the tseslint.config() function, which is correct for TypeScript ESLint setup. The structure follows the modern flat config format, split into two main objects: one for ignores and one for the main configuration. This organization is clear and maintainable.


1-28: Overall, this ESLint configuration is well-crafted and appropriate for the project.

This new eslint.config.js file provides a solid foundation for linting a TypeScript React project using Vite. It follows modern ESLint configuration practices, including the use of the flat config format and appropriate plugins. The configuration is well-structured, easy to understand, and maintainable.

Key strengths:

  1. Use of TypeScript-specific ESLint configuration
  2. Inclusion of relevant React plugins
  3. Well-chosen basic rules and extensions

Areas for potential future enhancement:

  1. Updating to a more recent ECMAScript version
  2. Adding custom rules as the project evolves

Great job on setting up this configuration! It will help maintain code quality and consistency as the project grows.

examples/example-vite-react-sdk/package.json (3)

1-5: LGTM: Project metadata is well-defined.

The project metadata is correctly set up for a React SDK project. The use of "private: true" prevents accidental publishing, and "type: "module"" ensures ES module usage.


21-33: LGTM: DevDependencies are comprehensive, but version compatibility should be verified.

The devDependencies include all necessary tools for development, including TypeScript, ESLint, and Vite with their related plugins.

The versions of TypeScript (5.5.3) and ESLint (9.9.0) are very recent. While using the latest versions is generally good, it may lead to compatibility issues with other packages or existing code. Please verify that these versions are compatible with your project requirements and other dependencies.

You can check for any compatibility warnings or errors by running:

#!/bin/bash
# Description: Check for compatibility issues with TypeScript and ESLint

echo "Checking TypeScript compatibility:"
npx tsc --version
npx tsc --noEmit

echo "Checking ESLint compatibility:"
npx eslint --version
npx eslint .

If you encounter any issues, consider pinning these dependencies to slightly older, stable versions.


12-20: LGTM: Dependencies are appropriate, with a note on workspace reference.

The dependencies include all necessary packages for a Dojo Engine React SDK project, with up-to-date versions for React and related libraries.

The @dojoengine/sdk dependency uses a workspace reference (workspace:*). This is typically used in monorepo setups. Please verify that this is the intended configuration for your project structure.

To check if other packages in the monorepo are using similar workspace references, you can run:

This will help ensure consistency across your project structure.

Verification successful

Verified: Workspace references are consistently used across the repository.

The @dojoengine/sdk dependency utilizes a workspace reference (workspace:*), and this pattern is consistently applied across multiple package.json files in the repository, confirming the intended monorepo setup.

  • Example paths with workspace references:
    • ./examples/example-vanillajs-phaser-recs/package.json
    • ./packages/sdk/package.json
    • ./packages/torii-client/package.json
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for workspace references in package.json files

# Find all package.json files and grep for workspace references
fd package.json --exec grep -H '"workspace:\*"' {} \;

Length of output: 511


Script:

#!/bin/bash
# Description: Search for workspace references in all package.json files using ripgrep

rg '"workspace:\*"' -g 'package.json' .

Length of output: 4408

examples/example-vite-react-sdk/src/index.css (2)

25-31: LGTM! Body styles are well-structured.

The body styles effectively use flexbox for centering content and ensure the layout takes up the full viewport. The minimum dimensions help prevent layout issues on small screens.


16-23: LGTM! Verify color contrast for accessibility.

The anchor styles are simple and effective. The hover state provides good user feedback.

Please verify the color contrast between the default state (#646cff) and the hover state (#535bf2) against the background color to ensure they meet WCAG 2.1 Level AA standards for accessibility. You can use a tool like the WebAIM Contrast Checker (https://webaim.org/resources/contrastchecker/) for this purpose.

examples/example-vite-react-sdk/src/bindings.ts (5)

9-13: LGTM! Well-structured interface.

The DirectionsAvailable interface is concise and effectively represents the available directions for a player. The use of the Direction enum for the directions array ensures type safety.


15-19: LGTM! Clear and concise position representation.

The Position interface effectively represents a player's position using a 2D vector. The use of a separate Vec2 interface for the position is a good practice for reusability and maintainability.


29-32: LGTM! Standard 2D vector representation.

The Vec2 interface is a simple and effective representation of a 2D vector, suitable for positions or directions in a 2D space.


42-62: LGTM! Well-structured default schema.

The schema constant provides a good starting point for the game state, initializing all properties with sensible default values. The use of Direction.None as the default for last_direction is appropriate.


64-65: LGTM! Comprehensive exports.

The export statement makes all necessary entities available for use in other files. The use of named exports allows for selective imports, which is a good practice for managing dependencies.

examples/example-vanillajs-phaser-recs/src/dojo/defineContractSystems.ts (1)

2-2: Verify the necessity of the uncommented import.

The import of Account and AccountInterface from "starknet" has been uncommented. This change appears to be necessary as these types are used in the file (e.g., in the MoveProps interface and function parameters).

To ensure this change doesn't introduce any conflicts or redundancies, please run the following script:

Verification successful

The import of Account and AccountInterface from "starknet" is necessary and correctly implemented. No conflicts or redundancies detected.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any other imports of Account or AccountInterface
# and verify their usage in the file.

# Search for other imports of Account or AccountInterface
echo "Searching for other imports of Account or AccountInterface:"
rg --type typescript 'import.*\{.*(?:Account|AccountInterface).*\}.*from' --glob '!**/defineContractSystems.ts'

# Check usage of Account and AccountInterface in the file
echo "Checking usage of Account and AccountInterface in defineContractSystems.ts:"
rg --type typescript '(?:Account|AccountInterface)' examples/example-vanillajs-phaser-recs/src/dojo/defineContractSystems.ts

Length of output: 600


Script:

#!/bin/bash
# Description: Check for any other imports of Account or AccountInterface
# and verify their usage in the file without relying on the 'typescript' filetype.

# Search for other imports of Account or AccountInterface excluding defineContractSystems.ts
echo "Searching for other imports of Account or AccountInterface:"
rg 'import.*\{.*(?:Account|AccountInterface).*\}.*from' --glob '!**/defineContractSystems.ts' --glob '*.ts' --glob '*.tsx'

# Check usage of Account and AccountInterface in defineContractSystems.ts
echo "Checking usage of Account and AccountInterface in defineContractSystems.ts:"
rg '(?:Account|AccountInterface)' examples/example-vanillajs-phaser-recs/src/dojo/defineContractSystems.ts --glob '*.ts' --glob '*.tsx'

Length of output: 4745

examples/example-vite-react-pwa-recs/vite.config.ts (1)

Line range hint 8-53: Verify plugin order for consistency.

The configuration object is well-structured and comprehensive. However, for consistency, consider aligning the order of plugins in the configuration with the order of imports.

Consider reordering the plugins array to match the import order:

plugins: [
    react(),
    VitePWA({
        // ... existing PWA configuration ...
    }),
    topLevelAwait(),
    wasm(),
],

This change would improve code readability and maintain consistency between imports and usage.

examples/example-vite-react-sdk/README.md (2)

1-8: LGTM: Clear and informative introduction

The introduction effectively summarizes the purpose of the template and provides accurate information about the available official plugins for React integration with Vite.


1-50: Overall assessment: Good starting point with room for improvement

This README.md file provides valuable information for developers working with the React + TypeScript + Vite template. The introduction is clear and concise, and the ESLint configuration expansion section offers useful guidance for enhancing the project setup.

However, there are opportunities to improve the clarity and consistency of the ESLint configuration instructions, as noted in the previous comment. Addressing these points will make the document more user-friendly and reduce potential confusion for developers following these instructions.

Despite these minor issues, the file serves its purpose well as an introductory guide for the project template.

examples/example-vite-react-app-recs/src/dojo/setup.ts (1)

Line range hint 13-85: Setup function remains unchanged and correctly uses imports.

The setup function has not been modified in this change. It correctly utilizes the imported modules to initialize various components and managers for the Dojo engine. This consistency is good, as it maintains the existing functionality while allowing for the import reorganization.

examples/example-vite-react-app-recs/src/dojo/createSystemCalls.ts (1)

2-15: LGTM: Import statements reorganized and new import added.

The reorganization of import statements and the addition of the Direction import from the generated models improve code organization and suggest proper usage of typed direction in the move function.

examples/example-vue-app-recs/src/dojo/createSystemCalls.ts (1)

Line range hint 12-137: Confirmed: No impact on the rest of the file.

The reordering of import statements doesn't affect the functionality or structure of the createSystemCalls function or its usage of the imported entities. The rest of the file remains unchanged and continues to work as expected.

examples/example-vite-react-threejs-recs/src/dojo/createSystemCalls.ts (1)

Line range hint 1-138: Verify existing code functionality and consider potential improvements.

While the changes in this PR are limited to import reordering, it's a good opportunity to review the existing code for potential improvements:

  1. Error Handling: The spawn and move functions use try-catch blocks, but they only log errors. Consider implementing more robust error handling or propagating errors to the caller.

  2. Code Duplication: There's some duplication in the spawn and move functions, particularly in error handling and cleanup. Consider extracting common patterns into helper functions.

  3. Magic Numbers: The spawn function uses magic numbers (10, 10) for initial position and 100 for initial moves. Consider defining these as constants for better maintainability.

  4. Type Safety: The as any cast in the move function could be avoided by properly typing the getComponentValue return.

  5. Async/Await: The functions are using async/await correctly, but ensure that any calling code is prepared to handle the returned promises appropriately.

To ensure the existing functionality hasn't been inadvertently affected, run the following verification:

This will help identify any potential issues with function calls that might need updating.

Verification successful

Verified: The spawn and move functions are correctly invoked throughout the codebase, and the import reordering has not affected their functionality.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify that the spawn and move functions are being called correctly throughout the codebase
rg --type typescript 'spawn\(' -A 5
rg --type typescript 'move\(' -A 5

Length of output: 144


Script:

#!/bin/bash
# Verify that the spawn and move functions are being called correctly throughout the codebase
rg --glob '*.ts' 'spawn\(' -A 5
rg --glob '*.tsx' 'spawn\(' -A 5
rg --glob '*.ts' 'move\(' -A 5
rg --glob '*.tsx' 'move\(' -A 5

Length of output: 26359

examples/example-vite-react-pwa-recs/src/dojo/createSystemCalls.ts (1)

Line range hint 1-138: LGTM! No functional changes, imports correctly used.

The changes in the import statements have been correctly implemented and don't affect the functionality of the code. All imported entities are present and properly used throughout the file. The createSystemCalls function and its internal logic remain unchanged, maintaining the existing functionality for spawning and moving entities.

examples/example-vanillajs-phaser-recs/src/dojo/systems.ts (1)

Line range hint 15-134: LGTM! Changes integrate well with existing code.

The modifications to the import statements have been correctly integrated with the rest of the file. All imported entities are used appropriately, and the functionality of the code remains intact.

examples/example-vue-app-recs/src/App.vue (1)

2-4: Approve import changes and verify usage

The reorganization of imports and addition of new ones from @dojoengine/recs, @dojoengine/utils, and local utilities improve code structure and suggest enhanced functionality. These changes look good and align with best practices.

To ensure these new imports are properly utilized, please run the following verification script:

This script will help confirm that the newly imported entities and functions are being used appropriately within the component.

Also applies to: 13-13

examples/example-vite-react-pwa-recs/src/App.tsx (3)

1-10: LGTM: Import statements reorganized and new import added.

The import statements have been reorganized, which improves readability. The addition of getEntityIdFromKeys from @dojoengine/utils is noted.


7-7: Verify usage of newly imported function.

The getEntityIdFromKeys function has been imported, but its usage is not visible in the provided diff. Please ensure that this function is being used in the component, possibly in a part of the file that wasn't included in the diff.

To verify the usage of getEntityIdFromKeys, run the following script:

#!/bin/bash
# Description: Verify the usage of getEntityIdFromKeys in the App.tsx file

# Test: Search for the usage of getEntityIdFromKeys
rg --type typescript 'getEntityIdFromKeys' examples/example-vite-react-pwa-recs/src/App.tsx

Line range hint 1-165: Verify implementation of newly imported function.

The import of getEntityIdFromKeys has been added, but there are no visible changes in the component logic to utilize this function. Please ensure that the function is being used appropriately in the component, possibly in a part of the file that wasn't included in the diff.

To verify the implementation of getEntityIdFromKeys, run the following script:

If the function is indeed being used, consider adding a comment explaining its purpose and how it relates to the component's functionality.

examples/example-vite-react-app-recs/src/App.tsx (1)

165-167: Approve the updated move logic for left direction.

The changes correctly implement the use of DirectionEnum.Left and maintain the necessary boundary check.

This implementation is consistent with the "Move Up" handler. Please refer to the previous comment about extracting the boundary check logic for a more unified approach across all directions.

Comment on lines 5 to 7
export const dojoConfig = createDojoConfig({
manifest,
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

Error: Manifest file not found.

The dojoConfig setup references a manifest file that does not exist at the specified path. Please ensure that the manifest file exists or update the configuration to point to the correct manifest location.

Analysis chain

LGTM: Configuration setup looks correct.

The createDojoConfig function is correctly called with the manifest as an argument. This setup ensures that the Dojo configuration is created using the specified manifest file.

To verify the usage of the manifest in other parts of the codebase, run the following script:

This will help ensure consistent usage across the project.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for other usages of createDojoConfig and manifest imports

# Test: Search for other usages of createDojoConfig
echo "Other usages of createDojoConfig:"
rg "createDojoConfig" --type ts

# Test: Search for other manifest imports
echo "Other manifest imports:"
rg "import.*manifest.*from" --type ts

Length of output: 261

import { createDojoConfig } from "@dojoengine/core";

import manifest from "../../../dojo/dojo-starter/manifests/dev/deployment/manifest.json";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a more robust import method for the manifest.

The addition of the manifest import is necessary for the createDojoConfig function. However, the current relative path (../../../dojo/dojo-starter/manifests/dev/deployment/manifest.json) might be brittle if the project structure changes.

Consider the following improvements:

  1. Use an environment variable or a configuration file to specify the path to the manifest, making it easier to change in different environments.
  2. If possible, move the manifest file closer to where it's used to reduce the number of directory traversals.
  3. Use a path alias in your TypeScript configuration to create a more stable import path.

Example using a path alias:

  1. In your tsconfig.json, add:
    {
      "compilerOptions": {
        "paths": {
          "@manifests/*": ["./dojo/dojo-starter/manifests/*"]
        }
      }
    }
  2. Then update the import to:
    import manifest from "@manifests/dev/deployment/manifest.json";

This approach would make the import more resistant to structural changes in the project.

@@ -0,0 +1,7 @@
import { createDojoConfig } from "@dojoengine/core";

import manifest from "../../../examples/dojo/dojo-starter/manifests/dev/deployment/manifest.json";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

Invalid manifest import path.

The specified manifest file is not found at the given path:

import manifest from "../../../examples/dojo/dojo-starter/manifests/dev/deployment/manifest.json";

Please verify the correct path or ensure the manifest.json file exists at the specified location.

Analysis chain

Verify the manifest import path.

The current import path for the manifest file is quite long and complex:

import manifest from "../../../examples/dojo/dojo-starter/manifests/dev/deployment/manifest.json";

This could potentially lead to issues with file resolution or indicate a need for project restructuring.

Please confirm that:

  1. This path correctly resolves to the intended manifest file.
  2. The project structure necessitates this deep nesting.

Consider simplifying the project structure or using path aliases to make imports more manageable if possible.

To verify the existence and content of the manifest file, you can run:

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the existence and content of the manifest file
manifest_path=$(fd -t f manifest.json | grep "examples/dojo/dojo-starter/manifests/dev/deployment/manifest.json")
if [ -n "$manifest_path" ]; then
    echo "Manifest file found at: $manifest_path"
    echo "First few lines of the manifest file:"
    head -n 5 "$manifest_path"
else
    echo "Manifest file not found at the specified path."
fi

Length of output: 219


Script:

#!/bin/bash
# Verify the existence and content of the manifest file
manifest_path=$(fd -t f manifest.json | grep "examples/dojo/dojo-starter/manifests/dev/deployment/manifest.json")
if [ -n "$manifest_path" ]; then
    echo "Manifest file found at: $manifest_path"
    echo "First few lines of the manifest file:"
    head -n 5 "$manifest_path"
else
    echo "Manifest file not found at the specified path."
fi

Length of output: 234


Script:

#!/bin/bash
# List all instances of manifest.json in the repository
fd -t f manifest.json

Length of output: 23

Comment on lines 16 to 17
.vscode/*
!.vscode/extensions.json
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding Vue.js specific ignores and refining .vscode pattern.

While the current .gitignore file is good, consider the following improvements:

  1. The .vscode ignore pattern could be more specific. Instead of ignoring everything except extensions.json, you might want to explicitly ignore settings.json if it contains sensitive information.

  2. Add some Vue.js specific ignores. For example:

    • .cache/ for build caches
    • coverage/ for test coverage reports

Here's a suggested diff for these changes:

 .vscode/*
 !.vscode/extensions.json
+!.vscode/settings.json
 .idea
 .DS_Store
 *.suo
 *.ntvs*
 *.njsproj
 *.sln
 *.sw?
+
+# Vue.js specific
+.cache/
+coverage/

Also applies to: 24-24

Comment on lines 15 to 21
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["vite.config.ts"]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linting options are strict and appropriate. Consider expanding file inclusion.

The linting options are well-configured for maintaining high code quality:

  • strict mode and checks for unused variables will help prevent common errors.
  • Checking for fallthrough cases in switch statements is a good safety measure.

The file inclusion is currently set to only vite.config.ts. This is suitable if the intention is to have a separate TypeScript configuration specifically for Vite-related files. However, consider the following suggestion:

If there are other configuration or script files in your project root that should use these Node.js-specific settings, you might want to expand the include array. For example:

"include": ["vite.config.ts", "*.config.ts", "scripts/**/*.ts"]

This would include all config files and any TypeScript files in a scripts directory, if applicable to your project structure.

Comment on lines 126 to 158
return (
<div>
<h1>Game State</h1>
{entities.map((entity) => (
<div key={entity.entityId}>
<h2>Entity {entity.entityId}</h2>
<h3>Position</h3>
<p>
Player:{" "}
{entity.models.dojo_starter.Position?.player ?? "N/A"}
<br />
X: {entity.models.dojo_starter.Position?.vec.x ?? "N/A"}
<br />
Y: {entity.models.dojo_starter.Position?.vec.y ?? "N/A"}
</p>
<h3>Moves</h3>
<p>
<br />
Can Move:{" "}
{entity.models.dojo_starter.Moves?.can_move?.toString() ??
"N/A"}
<br />
Last Direction:{" "}
{entity.models.dojo_starter.Moves?.last_direction ??
"N/A"}
<br />
Remaining:{" "}
{entity.models.dojo_starter.Moves?.remaining ?? "N/A"}
</p>
</div>
))}
</div>
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enhance user interface with better formatting and error messages

The current rendering of the game state is functional but could be improved for better user experience. Consider adding loading states, handling cases when there are no entities, and styling the output for clarity.

Comment on lines 53 to 60
setEntities((prevEntities) => {
return prevEntities.map((entity) => {
const newEntity = response.data?.find(
(e) => e.entityId === entity.entityId
);
return newEntity ? newEntity : entity;
});
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optimize state update logic in subscription callback

The current state update maps over prevEntities and replaces existing entities with new ones if they match. However, it doesn't account for new entities that are not in prevEntities. This might lead to missing updates for entities that weren't previously in the state. Consider updating the logic to include new entities as well.

Here's a refactored version that handles both existing and new entities:

-setEntities((prevEntities) => {
-    return prevEntities.map((entity) => {
-        const newEntity = response.data?.find(
-            (e) => e.entityId === entity.entityId
-        );
-        return newEntity ? newEntity : entity;
-    });
-});
+setEntities((prevEntities) => {
+    const entityMap = new Map(
+        prevEntities.map((entity) => [entity.entityId, entity])
+    );
+    response.data?.forEach((newEntity) => {
+        entityMap.set(newEntity.entityId, newEntity);
+    });
+    return Array.from(entityMap.values());
+});

This approach updates existing entities and adds new ones to the state.

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
setEntities((prevEntities) => {
return prevEntities.map((entity) => {
const newEntity = response.data?.find(
(e) => e.entityId === entity.entityId
);
return newEntity ? newEntity : entity;
});
});
setEntities((prevEntities) => {
const entityMap = new Map(
prevEntities.map((entity) => [entity.entityId, entity])
);
response.data?.forEach((newEntity) => {
entityMap.set(newEntity.entityId, newEntity);
});
return Array.from(entityMap.values());
});

Comment on lines 49 to 51
response.data &&
response.data[0].entityId !== "0x0"
) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure proper handling of empty subscription data

The condition response.data[0].entityId !== "0x0" assumes that response.data is an array with at least one element. If response.data is an empty array, accessing response.data[0] will be undefined, which could lead to runtime errors. To prevent this, check that response.data has elements before accessing them.

Apply this diff to safely handle empty response.data:

-} else if (
-    response.data &&
-    response.data[0].entityId !== "0x0"
-) {
+} else if (
+    response.data &&
+    response.data.length > 0 &&
+    response.data[0].entityId !== "0x0"
+) {
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
response.data &&
response.data[0].entityId !== "0x0"
) {
} else if (
response.data &&
response.data.length > 0 &&
response.data[0].entityId !== "0x0"
) {

Comment on lines 35 to 36
$is: "0x3628a39cc6bd2347e79967e9458ac41ab65bac6949f2aa311b311aff0d7334d",
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider making the player address configurable

The hard-coded player address in the query limits flexibility and maintainability. If the player address changes or if you need to support multiple players, you'll need to modify the source code. Consider externalizing the player address to a configuration file, environment variable, or component state to make it easily adjustable without code changes.

For example, you can introduce a state variable or prop:

-function App() {
+function App({ playerAddress }) {
     // ...
-    const subscription = await db.subscribeEntityQuery(
+    const subscription = await db.subscribeEntityQuery(
         {
             // ...
                                     player: {
-                                        $is: "0x3628a39cc6bd2347e79967e9458ac41ab65bac6949f2aa311b311aff0d7334d",
+                                        $is: playerAddress,
                                     },
             // ...

Committable suggestion was skipped due to low confidence.

Comment on lines 10 to 19
const db = await init<Schema>(
{
rpcUrl: dojoConfig.rpcUrl,
toriiUrl: dojoConfig.toriiUrl,
relayUrl: dojoConfig.relayUrl,
worldAddress:
"0x5d475a9221f6cbf1a016b12400a01b9a89935069aecd57e9876fcb2a7bb29da",
},
schema
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid using top-level await outside of an async function

The use of await at the top level may cause issues in environments that do not support top-level await. This can lead to syntax errors or unexpected behavior, especially in older browsers or bundlers that do not handle asynchronous module execution. It's recommended to initialize db within an async function or inside a useEffect hook to ensure compatibility.

Apply this diff to move the initialization inside the App component:

-const db = await init<Schema>(
-    {
-        rpcUrl: dojoConfig.rpcUrl,
-        toriiUrl: dojoConfig.toriiUrl,
-        relayUrl: dojoConfig.relayUrl,
-        worldAddress:
-            "0x5d475a9221f6cbf1a016b12400a01b9a89935069aecd57e9876fcb2a7bb29da",
-    },
-    schema
-);
+function App() {
+    const [db, setDb] = useState<ReturnType<typeof init<Schema>> | null>(null);
+
+    useEffect(() => {
+        const initDb = async () => {
+            const initializedDb = await init<Schema>(
+                {
+                    rpcUrl: dojoConfig.rpcUrl,
+                    toriiUrl: dojoConfig.toriiUrl,
+                    relayUrl: dojoConfig.relayUrl,
+                    worldAddress:
+                        "0x5d475a9221f6cbf1a016b12400a01b9a89935069aecd57e9876fcb2a7bb29da",
+                },
+                schema
+            );
+            setDb(initializedDb);
+        };
+        initDb();
+    }, []);
+
+    // Ensure `db` is initialized before using it
+    if (!db) {
+        return <div>Loading...</div>;
+    }
+
+    // Rest of your component code

Committable suggestion was skipped due to low confidence.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Outside diff range and nitpick comments (3)
examples/example-vite-react-threejs-recs/dojoConfig.ts (1)

3-3: Consider using a more robust import path for the manifest.

The current import uses a relative path that traverses multiple directory levels. This approach might be fragile if the project structure changes in the future.

Consider using a more robust method to import the manifest, such as:

  1. Using an environment variable to specify the path to the manifest.
  2. Creating a central configuration file that exports the correct path based on the current environment.

Example of using an environment variable:

import manifest from process.env.DOJO_MANIFEST_PATH;

This approach would require setting the DOJO_MANIFEST_PATH environment variable in your build or run scripts.

examples/example-nodejs-bot/src/queries/getMoves.ts (2)

Line range hint 4-4: Fix typo in function name

The function name getTransations is misspelled. It should be getTransactions.

Apply this diff to fix the typo:

-export const getTransations = async () => {
+export const getTransactions = async () => {

Line range hint 6-7: Consider removing or utilizing the unused data variable

The data variable from sdk.getTransations() is logged but not used further in the function. If this is intended for debugging purposes, consider adding a comment explaining its purpose or remove the console.log if it's no longer needed.

If the logging is for debugging, consider adding a comment:

 await sdk.getTransations().then((data) => {
-    console.log(data);
+    // Log transaction data for debugging purposes
+    console.log('Transaction data:', data);

Alternatively, if the logging is no longer needed, remove it:

-await sdk.getTransations().then((data) => {
-    console.log(data);
+await sdk.getTransations().then(() => {
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between cf7387b and 903b915.

Files selected for processing (13)
  • examples/example-nodejs-bot/dojoConfig.ts (1 hunks)
  • examples/example-nodejs-bot/package.json (3 hunks)
  • examples/example-nodejs-bot/src/queries/getMoves.ts (1 hunks)
  • examples/example-vanillajs-phaser-recs/dojoConfig.ts (1 hunks)
  • examples/example-vite-react-app-recs/dojoConfig.ts (1 hunks)
  • examples/example-vite-react-phaser-recs/dojoConfig.ts (1 hunks)
  • examples/example-vite-react-pwa-recs/dojoConfig.ts (1 hunks)
  • examples/example-vite-react-sdk/dojoConfig.ts (1 hunks)
  • examples/example-vite-react-sdk/src/App.tsx (1 hunks)
  • examples/example-vite-react-sdk/tsconfig.app.tsbuildinfo (1 hunks)
  • examples/example-vite-react-sdk/tsconfig.node.tsbuildinfo (1 hunks)
  • examples/example-vite-react-threejs-recs/dojoConfig.ts (1 hunks)
  • examples/example-vue-app-recs/dojoConfig.ts (1 hunks)
Files skipped from review due to trivial changes (2)
  • examples/example-vite-react-sdk/tsconfig.app.tsbuildinfo
  • examples/example-vite-react-sdk/tsconfig.node.tsbuildinfo
Files skipped from review as they are similar to previous changes (7)
  • examples/example-nodejs-bot/dojoConfig.ts
  • examples/example-vanillajs-phaser-recs/dojoConfig.ts
  • examples/example-vite-react-app-recs/dojoConfig.ts
  • examples/example-vite-react-pwa-recs/dojoConfig.ts
  • examples/example-vite-react-sdk/dojoConfig.ts
  • examples/example-vite-react-sdk/src/App.tsx
  • examples/example-vue-app-recs/dojoConfig.ts
Additional comments not posted (5)
examples/example-vite-react-threejs-recs/dojoConfig.ts (1)

5-7: LGTM! Good use of configuration management.

The creation and export of dojoConfig using createDojoConfig and the imported manifest is a clean and maintainable approach. It centralizes the configuration and allows for easy updates when the manifest changes.

examples/example-nodejs-bot/package.json (3)

35-35: Verify the necessity and functionality of the "codegen" script.

The "codegen" script has been retained, which is fine if the project still requires GraphQL code generation.

Please verify that this script is still necessary and functional. Run the following script to check its functionality:

#!/bin/bash
# Description: Verify the functionality of the "codegen" script

# Test: Run the codegen script. Expect: Successful execution without errors.
npm run codegen

If the script is no longer needed, consider removing it to keep the package.json clean and up-to-date.


21-23: Dependency updates look good, but be cautious of breaking changes.

The dependency updates are generally good practice to keep the project up-to-date. However, please note:

  1. The update to @sapphire/framework (4.6.0 -> 5.2.1) is a major version change, which might introduce breaking changes.
  2. The updates to @sapphire/decorators and discord.js are minor and should be backwards compatible.

Please ensure that the project still builds and functions correctly after these updates, especially considering the major version change of @sapphire/framework. Run the following script to check for any deprecation warnings or errors:

#!/bin/bash
# Description: Build the project and check for deprecation warnings or errors

# Test: Run npm install and build. Expect: No errors or deprecation warnings.
npm install && npm run build

2-2: Project name change looks good.

The project name change from "torii-bo" to "torii-bot" is an improvement. It's more descriptive and complete.

Please verify that this name change doesn't break any existing imports or references to the project. Run the following script to check for any occurrences of the old name:

Verification successful

Project name change verified successfully.

All references to the old project name "torii-bo" have been removed from the codebase. No remaining instances were found that could impact imports or references.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for occurrences of the old project name "torii-bo"

# Test: Search for "torii-bo" in all files. Expect: No results if all references have been updated.
rg --type-not json "torii-bo"

Length of output: 171


Script:

#!/bin/bash
# Description: Search for occurrences of the old project name "torii-bo" in all files except JSON.

# Test: Ensure that "torii-bo" is no longer referenced in the codebase.
rg --type-not json "torii-bo"

Length of output: 263

examples/example-nodejs-bot/src/queries/getMoves.ts (1)

Line range hint 32-42: LGTM: getMoves function is well-implemented

The getMoves function is well-structured, uses proper error handling, and maintains type safety. It correctly fetches and returns the moves data for a given player.

@@ -1,4 +1,4 @@
import manifest from "../../../dojo/dojo-starter/manifests/dev/deployment/manifest.json";
import manifest from "../../worlds/dojo-starter/manifests/dev/deployment/manifest.json";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

Manifest file not found at the updated import path.

The import path "../../worlds/dojo-starter/manifests/dev/deployment/manifest.json" does not exist, which will cause import failures in the following files:

  • examples/example-vite-react-app-recs/dojoConfig.ts
  • examples/example-vite-react-sdk/dojoConfig.ts
  • examples/example-vite-react-threejs-recs/dojoConfig.ts
  • examples/example-vue-app-recs/dojoConfig.ts
  • examples/example-vanillajs-phaser-recs/dojoConfig.ts
  • examples/example-vite-react-pwa-recs/dojoConfig.ts
  • examples/example-nodejs-bot/dojoConfig.ts
  • examples/example-vite-react-phaser-recs/dojoConfig.ts

Please ensure that the manifest file exists at the specified location or revert the import path changes to maintain project integrity.

Analysis chain

Verify the updated manifest import path.

The import path for the manifest file has been changed, which suggests a project directory restructuring. While this change appears to be intentional, please ensure:

  1. The new path "../../worlds/dojo-starter/manifests/dev/deployment/manifest.json" is correct and the file exists at this location.
  2. This change is consistent with other parts of the project that might be using the same manifest file.
  3. The move from "dojo" to "worlds" in the path aligns with the project's new structure and naming conventions.

To verify the existence of the manifest file and check for any other occurrences that might need updating, you can run the following script:

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the existence of the new manifest file
if [ -f "worlds/dojo-starter/manifests/dev/deployment/manifest.json" ]; then
    echo "New manifest file exists."
else
    echo "Warning: New manifest file not found at the specified location."
fi

# Search for any remaining occurrences of the old path
echo "Checking for any remaining occurrences of the old path:"
rg "dojo/dojo-starter/manifests/dev/deployment/manifest.json"

# Search for other occurrences of the new path to ensure consistency
echo "Checking for other occurrences of the new path:"
rg "worlds/dojo-starter/manifests/dev/deployment/manifest.json"

Length of output: 1692

@@ -32,6 +32,7 @@
"scripts": {
"build": "tsc",
"serve": "tsc && node dist/node/torii-bot/src/index.js",
"codegen": "graphql-codegen"
"codegen": "graphql-codegen",
"test": "echo \"Error: no test specified\""
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implement actual tests for the "test" script.

While adding a "test" script is a good practice, the current implementation doesn't run any tests. It only outputs an error message.

Consider implementing actual tests for your project. This could involve setting up a testing framework like Jest or Mocha and writing some basic unit tests. For example:

"scripts": {
  "test": "jest"
}

Then, create a __tests__ directory and add some test files. This will help ensure the reliability and maintainability of your code.

Comment on lines 12 to 21
// channel({
// embeds: [
// {
// color: 0x00ff3c,
// title: "Transactions",
// description: "new transactions",
// timestamp: new Date().toISOString(),
// },
// ],
// });
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented-out code and empty if block

The commented-out code for sending a Discord message is no longer in use. It's generally better to remove unused code rather than commenting it out to maintain code cleanliness and readability.

Consider removing the commented-out code and the now-empty if block. Apply this diff:

-    client.channels
-        .fetch(process.env.DISCORD_CHANNEL_ID || "")
-        .then((channel) => {
-            if (channel?.isTextBased()) {
-                // channel({
-                //     embeds: [
-                //         {
-                //             color: 0x00ff3c,
-                //             title: "Transactions",
-                //             description: "new transactions",
-                //             timestamp: new Date().toISOString(),
-                //         },
-                //     ],
-                // });
-            }
-        });

If you need to keep this code for future reference, consider moving it to a separate document or adding a clear TODO comment explaining why it's kept and when it might be reintroduced.

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// channel({
// embeds: [
// {
// color: 0x00ff3c,
// title: "Transactions",
// description: "new transactions",
// timestamp: new Date().toISOString(),
// },
// ],
// });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant