Skip to content

feat: add useModels hook #420

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 1 commit into from
Mar 14, 2025
Merged

feat: add useModels hook #420

merged 1 commit into from
Mar 14, 2025

Conversation

MartianGreed
Copy link
Collaborator

@MartianGreed MartianGreed commented Mar 14, 2025

Closes #

Introduced changes

Checklist

  • Linked relevant issue
  • Updated relevant documentation
  • Added relevant tests
  • Add a dedicated CI job for new examples
  • Performed self-review of the code

Summary by CodeRabbit

  • Documentation

    • Added an updated changelog summarizing recent patch updates across packages.
  • New Features

    • Introduced an enhanced mechanism for retrieving model data to improve application interaction.
    • Added utility functions for converting network URIs with default protocol support.
    • Streamlined client configuration with sensible defaults and improved error reporting.
    • Added a new custom hook for retrieving multiple entities based on model.
  • Bug Fixes

    • Improved address processing for more reliable operations.
    • Resolved issues with optional value handling and data merging for increased stability.
    • Fixed the handling of Cairo options and enum ignore functionality during data processing.
    • Removed deprecated build script from the @dojoengine/torii-wasm package.

Copy link

coderabbitai bot commented Mar 14, 2025

Walkthrough

This pull request introduces a new changelog file documenting patch updates for multiple Dojo Engine packages and fixes related to Cairo options and enum handling. It updates example app logic by modifying address handling and importing a new useModels hook. The SDK has enhancements including updated type imports, default client configuration merging, improved error handling, and merging functions for Cairo types. Additionally, utility functions for URI conversion and their corresponding tests have been added, and the development script has switched to watch mode.

Changes

File(s) Change Summary
.changeset/brave-kiwis-explode.md New markdown file documenting patch updates and fixes for various Dojo Engine packages.
examples/example-vite-react-sdk/src/App.tsx, examples/example-vite-react-sdk/src/main.tsx Modified address handling in App.tsx; removed toriiUrl and relayUrl from client configuration in main.tsx.
package.json Updated dev script from "turbo dev --concurrency 15" to "turbo watch dev --concurrency 15" and added a new "docs" script.
packages/sdk/src/index.ts, packages/sdk/src/parseEntities.ts, packages/sdk/src/react/hooks.ts, packages/sdk/src/state/zustand.ts, packages/sdk/src/types.ts Enhanced SDK with type import adjustments, added default client configuration, merged configurations, refined error handling, introduced a new useModels hook and merging functions for Cairo types, and updated type definitions.
packages/utils/src/_test_/utils/index.test.ts, packages/utils/src/utils/index.ts Added new utility functions (getDefaultPortForProtocol, convertToRelayUri) for URI conversion and corresponding tests.
packages/torii-wasm/package.json Removed "build" script from the @dojoengine/torii-wasm package.
turbo.json Updated dependsOn in task build to include both ^build and ^build:deps.

Sequence Diagram(s)

sequenceDiagram
    participant App as Application
    participant SDK as SDK.init Function
    participant DC as Default Config
    participant Store as State Store
    App->>SDK: Call init(options)
    SDK->>DC: Retrieve defaultClientConfig
    SDK->>SDK: Merge options.client with default config
    SDK->>Store: Initialize subscriptions & error handling
    Store-->>SDK: Return event data/errors
Loading
sequenceDiagram
    participant Comp as Component
    participant UM as useModels Hook
    participant Dojo as useDojoStore
    participant GE as getEntitiesByModel
    Comp->>UM: Invoke useModels("namespace-modelName")
    UM->>Dojo: Access global store
    Dojo->>GE: Fetch entities by model
    GE-->>Dojo: Return entity map
    Dojo-->>UM: Provide entities
    UM-->>Comp: Return mapped entities
Loading

Possibly related PRs

Poem

I'm a rabbit in the code field,
Hopping through patches with a gleam.
New hooks and fixes light my way,
In SDK and utils, I happily play.
With tweaks and tests, my world is bright—
Leaping forward under the moonlight! 🐇🌙


🪧 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: 1

🧹 Nitpick comments (5)
examples/example-vite-react-sdk/src/App.tsx (1)

13-13: Import added but not used

The useModels hook is imported but never used in this component. Consider either removing the unused import or implementing it where needed.

-    useModels,
packages/sdk/src/react/hooks.ts (1)

75-75: Avoid using 'any' type

The any type disables TypeScript's type checking features. Consider using a more specific type or a generic constraint for better type safety.

-    Client extends (...args: any) => any,
+    Client extends (...args: unknown[]) => unknown,
🧰 Tools
🪛 Biome (1.9.4)

[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

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

382-391: Well-implemented default port helper function

The getDefaultPortForProtocol function provides a clean way to determine default ports for different protocols. Consider adding more protocols like http: and ws: for completeness.

function getDefaultPortForProtocol(protocol: string): number {
    switch (protocol) {
        case "https:":
            return 443;
        case "wss:":
            return 443;
+       case "http:":
+           return 80;
+       case "ws:":
+           return 80;
        default:
            return 80;
    }
}

436-442: Special protocol handling could use a comment

The special handling for wss protocol (converting to x-parity-wss) might not be obvious to users. Consider adding a comment explaining why this transformation is necessary.

        // Append protocol if it's not http or https
        if (!["http", "https"].includes(protocol)) {
+           // Convert wss to x-parity-wss for compatibility with multiaddr protocol naming conventions
            // Replace wss with x-parity-wss
            const protocolToAppend =
                protocol === "wss" ? "x-parity-wss" : protocol;
            multiaddr += `/${protocolToAppend}`;
        }
packages/sdk/src/state/zustand.ts (1)

77-133: Fix the any type usage in enum handling.

The implementation uses any type for newEnumContent which could be more strictly typed to improve type safety.

- const newEnumContent: Record<string, any> = {};
+ const newEnumContent: Record<string, unknown> = {};

Also apply this change for the second newEnumContent declaration in this function.

🧰 Tools
🪛 Biome (1.9.4)

[error] 96-96: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 116-116: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 80bee03 and e71507e.

📒 Files selected for processing (11)
  • .changeset/brave-kiwis-explode.md (1 hunks)
  • examples/example-vite-react-sdk/src/App.tsx (2 hunks)
  • examples/example-vite-react-sdk/src/main.tsx (0 hunks)
  • package.json (1 hunks)
  • packages/sdk/src/index.ts (5 hunks)
  • packages/sdk/src/parseEntities.ts (1 hunks)
  • packages/sdk/src/react/hooks.ts (2 hunks)
  • packages/sdk/src/state/zustand.ts (6 hunks)
  • packages/sdk/src/types.ts (2 hunks)
  • packages/utils/src/_test_/utils/index.test.ts (2 hunks)
  • packages/utils/src/utils/index.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • examples/example-vite-react-sdk/src/main.tsx
🧰 Additional context used
🪛 Biome (1.9.4)
packages/sdk/src/state/zustand.ts

[error] 96-96: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 116-116: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

packages/sdk/src/react/hooks.ts

[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

🔇 Additional comments (26)
.changeset/brave-kiwis-explode.md (1)

1-15: Well-structured changeset file for version management

This changeset file properly documents patch updates for multiple Dojo Engine packages and specifically mentions a fix for "cairo option and enum ignore in zustand merge". This corresponds to the code changes we see in the parseEntities.ts file.

Using changesets is a good practice for versioning in monorepos, ensuring changes are properly tracked and documented before release.

package.json (1)

14-14: Development environment enhancement

Adding the "watch" parameter to the dev script enables automatic rebuilding when files change during development, which improves developer experience by providing faster feedback during the implementation of features like the new useModels hook mentioned in the PR title.

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

79-80: Cairo Option handling fix

This change corrects the control flow for handling Cairo enum values by decoupling the checks for "Some" and "None" options. Previously, the "None" check was only evaluated if the "Some" check failed, which could lead to incorrect behavior in certain scenarios.

This aligns with the changeset description mentioning a fix for "cairo option and enum ignore in zustand merge".

packages/utils/src/_test_/utils/index.test.ts (2)

6-6: Adding new utility import

The import statement is updated to include the new convertToRelayUri function that will be tested later in the file.


109-128: Comprehensive test coverage for URI conversion utility

This test case verifies the convertToRelayUri function's behavior with four different input URI formats:

  1. Standard HTTP with localhost
  2. HTTP with IP address
  3. HTTPS with path segments
  4. WSS with path segments

The test ensures that each URI is correctly converted to its multiaddr representation, which is important for properly configuring network connections in the Dojo ecosystem.

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

39-43: Improved address handling

This change enhances the clarity of address handling by explicitly using undefined when the address is not available, rather than defaulting to a placeholder value. This approach makes the intent clearer and prevents potential issues with using "0" as a fallback.

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

458-460: Good type refinement for client configuration

The new SDKClientConfig type enhances type safety by ensuring that worldAddress is always provided while making other properties from torii.ClientConfig optional. This is a good practice for configuration objects, allowing flexibility while guaranteeing required properties.


470-470: Improved client property type

Updating the client property to use the new SDKClientConfig type ensures consistent typing throughout the SDK and prevents configuration errors at compile time.

packages/sdk/src/react/hooks.ts (1)

66-89: Good implementation of the useModels hook

The addition of the useModels hook complements the existing useModel hook by providing a way to retrieve all entities with a specific model. This is a valuable addition for components that need to display collections of entities.

🧰 Tools
🪛 Biome (1.9.4)

[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

packages/utils/src/utils/index.ts (1)

404-454: Comprehensive URI conversion utility

The convertToRelayUri function is well-implemented with thorough handling of different URI formats (IPv4, IPv6, domain names) and good error handling. The detailed comments and examples make it very clear how to use this function.

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

2-2: Good type import optimization.

Changing the import to a type import ensures these types are only used for type checking and not at runtime, which can lead to more efficient bundling.


4-14: Good type safety improvement.

Converting regular imports to type imports for type-only dependencies helps with cleaner code separation between runtime values and type information.


18-18: Type import is properly implemented.

The ToriiQueryBuilder is correctly imported as a type since it's only used for type annotations.


38-41: Default client configuration is a good practice.

Adding default values for configuration parameters is a good practice as it improves usability by requiring less boilerplate from users.


52-56: Good fallback configuration implementation.

This creates a client configuration by merging default values with user-provided options, allowing users to override only the values they need to customize while maintaining sensible defaults for the rest.


95-98: Improved error handling.

The error check ensures that errors are always wrapped in an Error object, which provides more consistent error handling behavior.


162-164: Consistent error handling pattern.

This follows the same error handling pattern as implemented elsewhere in the codebase, ensuring errors are always proper Error objects with stack traces.

packages/sdk/src/state/zustand.ts (9)

9-9: Appropriate import for Cairo-specific types.

Adding imports for CairoCustomEnum, CairoOption, and CairoOptionVariant is necessary for the new type-specific handling functions.


24-31: Good type guard implementation.

The isCairoOption type guard function is well-implemented using the instanceof check, which enables TypeScript to narrow types in conditional blocks.


33-66: Well-structured Cairo option merge function.

The mergeCairoOption function correctly handles merging CairoOption instances with appropriate priority logic, preferring "Some" values from the source when available.


68-75: Consistent type guard implementation.

The isCairoCustomEnum type guard follows the same pattern as isCairoOption, providing consistent type narrowing capabilities.


147-152: Good extension of the deepMerge function.

The updated deepMerge function now handles Cairo-specific types correctly by delegating to specialized merge functions, which is a clean approach to extending functionality.


197-201: Improved loop syntax.

Changing from forEach to for...of loops provides better readability and is generally more idiomatic in modern JavaScript/TypeScript.


216-217: Good flow control improvement.

Using continue instead of a return statement maintains the loop flow more clearly, making the code more maintainable.


223-244: Enhanced entity merging logic.

The updated entity merging logic correctly uses the deepMerge function to handle Cairo types, ensuring proper merging of complex nested structures.


272-292: Consistent application of the merging pattern.

The same merging pattern is applied consistently in the updateEntity method, which is good for maintainability and predictable behavior.

Comment on lines +82 to +86
const modelData = useDojoStore((state) =>
state.getEntitiesByModel(namespace, modelName).map((entity) => ({
[entity.entityId]: entity.models?.[namespace]?.[modelName],
}))
) as unknown as { [entityId: string]: SchemaType[N][M] | undefined };
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Potential issue with return value mapping

The current implementation is mapping entities to an array of objects (each with a single key-value pair) but then casting it to a single object. This might not work as intended.

-    const modelData = useDojoStore((state) =>
-        state.getEntitiesByModel(namespace, modelName).map((entity) => ({
-            [entity.entityId]: entity.models?.[namespace]?.[modelName],
-        }))
-    ) as unknown as { [entityId: string]: SchemaType[N][M] | undefined };
+    const modelData = useDojoStore((state) =>
+        state.getEntitiesByModel(namespace, modelName).reduce((acc, entity) => ({
+            ...acc,
+            [entity.entityId]: entity.models?.[namespace]?.[modelName],
+        }), {})
+    ) as { [entityId: string]: SchemaType[N][M] | undefined };
📝 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
const modelData = useDojoStore((state) =>
state.getEntitiesByModel(namespace, modelName).map((entity) => ({
[entity.entityId]: entity.models?.[namespace]?.[modelName],
}))
) as unknown as { [entityId: string]: SchemaType[N][M] | undefined };
const modelData = useDojoStore((state) =>
state.getEntitiesByModel(namespace, modelName).reduce((acc, entity) => ({
...acc,
[entity.entityId]: entity.models?.[namespace]?.[modelName],
}), {})
) as { [entityId: string]: SchemaType[N][M] | undefined };

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

♻️ Duplicate comments (1)
packages/sdk/src/react/hooks.ts (1)

66-89: ⚠️ Potential issue

Fix the return value mapping in useModels hook.

The current implementation has a logic error. It maps entities to an array of objects (each with a single key-value pair) and then incorrectly casts it to a single object, which won't work as expected at runtime.

Apply this correction to properly accumulate entities into a single object:

const modelData = useDojoStore((state) =>
-    state.getEntitiesByModel(namespace, modelName).map((entity) => ({
-        [entity.entityId]: entity.models?.[namespace]?.[modelName],
-    }))
-) as unknown as { [entityId: string]: SchemaType[N][M] | undefined };
+    state.getEntitiesByModel(namespace, modelName).reduce((acc, entity) => ({
+        ...acc,
+        [entity.entityId]: entity.models?.[namespace]?.[modelName],
+    }), {})
+) as { [entityId: string]: SchemaType[N][M] | undefined };
🧰 Tools
🪛 Biome (1.9.4)

[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

🧹 Nitpick comments (4)
packages/sdk/src/react/hooks.ts (2)

75-75: Consider adding a more specific type than 'any'.

The Client extends (...args: any) => any type parameter uses any, which reduces type safety. If possible, define a more specific interface for the client function.

🧰 Tools
🪛 Biome (1.9.4)

[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


251-251: Remove unnecessary empty line.

There's an extra blank line here that doesn't serve any purpose.

packages/utils/src/utils/index.ts (1)

393-454: Good implementation of URI conversion with complete error handling

The convertToRelayUri function is well-documented with examples and includes proper error handling. The implementation correctly handles different address types (IPv4, IPv6, domain names) and includes special case handling for protocol conversion.

A few minor suggestions for improvement:

  1. The IPv4 regex pattern (/^\d+\.\d+\.\d+\.\d+$/) is simplistic and might not validate all IPv4 addresses correctly.
  2. Consider adding more robust validation for IPv6 addresses.
-        if (hostname.match(/^\d+\.\d+\.\d+\.\d+$/)) {
+        // More robust IPv4 validation with octet range check (0-255)
+        if (hostname.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/) && 
+            hostname.split('.').every(octet => parseInt(octet, 10) <= 255)) {
packages/sdk/src/state/zustand.ts (1)

68-133: Type-safe implementation for CairoCustomEnum handling with minor typing issues

The functions for checking and merging CairoCustomEnum types are well-implemented with appropriate fallbacks. The code correctly handles active variants and maintains type safety.

However, there's a static analysis warning about using any types at lines 96 and 116:

-        const newEnumContent: Record<string, any> = {};
+        const newEnumContent: Record<string, unknown> = {};

This would improve type safety while still allowing for the dynamic property assignment pattern you're using.

🧰 Tools
🪛 Biome (1.9.4)

[error] 96-96: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 116-116: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between e71507e and e282c5b.

📒 Files selected for processing (14)
  • .changeset/brave-kiwis-explode.md (1 hunks)
  • examples/example-vite-react-sdk/src/App.tsx (1 hunks)
  • examples/example-vite-react-sdk/src/main.tsx (0 hunks)
  • package.json (1 hunks)
  • packages/sdk/src/experimental/index.ts (1 hunks)
  • packages/sdk/src/index.ts (5 hunks)
  • packages/sdk/src/parseEntities.ts (1 hunks)
  • packages/sdk/src/react/hooks.ts (2 hunks)
  • packages/sdk/src/state/zustand.ts (6 hunks)
  • packages/sdk/src/types.ts (2 hunks)
  • packages/torii-wasm/package.json (0 hunks)
  • packages/utils/src/_test_/utils/index.test.ts (2 hunks)
  • packages/utils/src/utils/index.ts (1 hunks)
  • turbo.json (1 hunks)
💤 Files with no reviewable changes (2)
  • packages/torii-wasm/package.json
  • examples/example-vite-react-sdk/src/main.tsx
🚧 Files skipped from review as they are similar to previous changes (6)
  • packages/utils/src/test/utils/index.test.ts
  • package.json
  • packages/sdk/src/parseEntities.ts
  • examples/example-vite-react-sdk/src/App.tsx
  • .changeset/brave-kiwis-explode.md
  • packages/sdk/src/index.ts
🧰 Additional context used
🪛 Biome (1.9.4)
packages/sdk/src/react/hooks.ts

[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

packages/sdk/src/state/zustand.ts

[error] 96-96: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 116-116: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (9)
turbo.json (1)

19-19: Build dependency chain update looks good.

The addition of ^build:deps to the build task's dependencies ensures that all dependency builds are completed before the main build runs, which improves build reliability and correctness.

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

458-460: Improved type definition for client configuration.

The new SDKClientConfig type provides better type safety by making worldAddress required while keeping other client config properties optional. This enables more flexible configuration with defaults.


470-470: LGTM! Client type updated correctly.

The client property now uses the new SDKClientConfig type, which aligns with the client configuration merging implementation.

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

6-6: Added import for default client configuration.

This import is necessary for the client configuration merging implemented below.


14-19: Improved client configuration with defaults.

The implementation now properly merges default client configuration with user-provided options, allowing for sensible defaults while still enabling overrides. This is a standard pattern for configuration management.

packages/utils/src/utils/index.ts (1)

376-391: Well-implemented utility function with clear purpose

The getDefaultPortForProtocol function is correctly implemented to return default ports for different protocols, with appropriate JSDoc documentation. The implementation is straightforward and handles the common cases correctly.

packages/sdk/src/state/zustand.ts (3)

24-66: Good implementation of CairoOption handling

The isCairoOption and mergeCairoOption functions are well-documented and correctly implement type checking and merging logic for CairoOption instances. The merge logic appropriately prioritizes "Some" values over "None" values.


147-152: Good integration with deepMerge function

The special case handling for Cairo types in the deepMerge function is well-implemented, correctly delegating to the appropriate merge functions based on type checks.


197-200: Improved loop structure and merging logic

Changing from forEach to for...of loops improves readability and the use of continue instead of return statements maintains proper loop flow. The updated merging logic correctly leverages the new type-specific merge functions.

Also applies to: 205-244, 272-292

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

♻️ Duplicate comments (1)
packages/sdk/src/react/hooks.ts (1)

66-89: ⚠️ Potential issue

Good addition of the useModels hook, but mapping implementation needs correction

The new useModels hook is a valuable addition that complements the existing useModel function. However, the implementation has an issue in how it's transforming the data.

The current implementation maps entities to an array of objects (each with a single key-value pair) but then casts it to a single object. This won't work as intended because it will result in an array structure rather than the expected object structure.

-    const modelData = useDojoStore((state) =>
-        state.getEntitiesByModel(namespace, modelName).map((entity) => ({
-            [entity.entityId]: entity.models?.[namespace]?.[modelName],
-        }))
-    ) as unknown as { [entityId: string]: SchemaType[N][M] | undefined };
+    const modelData = useDojoStore((state) =>
+        state.getEntitiesByModel(namespace, modelName).reduce((acc, entity) => ({
+            ...acc,
+            [entity.entityId]: entity.models?.[namespace]?.[modelName],
+        }), {})
+    ) as { [entityId: string]: SchemaType[N][M] | undefined };

This implementation uses reduce to properly combine all entity data into a single object, creating the expected return type structure.

🧰 Tools
🪛 Biome (1.9.4)

[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

🧹 Nitpick comments (2)
packages/sdk/src/react/hooks.ts (1)

72-76: Type safety improvement needed for generic parameters

The Client generic parameter is using the any type, which bypasses type safety checks.

Consider using a more specific type for the Client parameter:

export function useModels<
    N extends keyof SchemaType,
    M extends keyof SchemaType[N] & string,
-    Client extends (...args: any) => any,
+    Client extends (...args: unknown[]) => unknown,
    Schema extends SchemaType
>(model: `${N}-${M}`): { [entityId: string]: SchemaType[N][M] | undefined } {

This provides better type safety while maintaining the flexibility needed for different client implementations.

🧰 Tools
🪛 Biome (1.9.4)

[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

packages/sdk/src/state/zustand.ts (1)

83-133: Well-implemented mergeCairoCustomEnum function with type improvement needed

The mergeCairoCustomEnum function appropriately handles the merging of CairoCustomEnum instances by prioritizing the source's active variant. However, there's a use of any that should be addressed.

Replace the any type with a more specific type:

-        const newEnumContent: Record<string, any> = {};
+        const newEnumContent: Record<string, unknown> = {};

Same change should be applied to the similar declaration on line 116.

This change maintains the flexibility needed while improving type safety.

🧰 Tools
🪛 Biome (1.9.4)

[error] 96-96: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 116-116: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between e282c5b and 0e64e57.

📒 Files selected for processing (14)
  • .changeset/brave-kiwis-explode.md (1 hunks)
  • examples/example-vite-react-sdk/src/App.tsx (1 hunks)
  • examples/example-vite-react-sdk/src/main.tsx (0 hunks)
  • package.json (1 hunks)
  • packages/sdk/src/experimental/index.ts (1 hunks)
  • packages/sdk/src/index.ts (5 hunks)
  • packages/sdk/src/parseEntities.ts (1 hunks)
  • packages/sdk/src/react/hooks.ts (2 hunks)
  • packages/sdk/src/state/zustand.ts (6 hunks)
  • packages/sdk/src/types.ts (2 hunks)
  • packages/torii-wasm/package.json (0 hunks)
  • packages/utils/src/_test_/utils/index.test.ts (2 hunks)
  • packages/utils/src/utils/index.ts (1 hunks)
  • turbo.json (1 hunks)
💤 Files with no reviewable changes (2)
  • packages/torii-wasm/package.json
  • examples/example-vite-react-sdk/src/main.tsx
🚧 Files skipped from review as they are similar to previous changes (9)
  • packages/sdk/src/parseEntities.ts
  • packages/sdk/src/types.ts
  • examples/example-vite-react-sdk/src/App.tsx
  • packages/utils/src/test/utils/index.test.ts
  • packages/sdk/src/experimental/index.ts
  • turbo.json
  • .changeset/brave-kiwis-explode.md
  • package.json
  • packages/sdk/src/index.ts
🧰 Additional context used
🪛 Biome (1.9.4)
packages/sdk/src/react/hooks.ts

[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

packages/sdk/src/state/zustand.ts

[error] 96-96: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 116-116: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build
  • GitHub Check: check
🔇 Additional comments (7)
packages/utils/src/utils/index.ts (2)

377-391: Well-structured helper function for determining default ports.

The function logic correctly assigns port 443 to secure protocols (HTTPS, WSS) and 80 to other protocols, which is appropriate for web and WebSocket services. The function is properly scoped as internal (not exported) and includes good JSDoc documentation.


393-454:

❓ Verification inconclusive

Good implementation of URI to multiaddr conversion with comprehensive documentation.

The function properly handles different address types (IPv4, IPv6, domain) and includes appropriate error handling. The examples in the documentation are particularly helpful.

There are a couple of points to consider:

  1. The URL pathname encoding in line 447 might cause double-encoding if the path already contains encoded components.
  2. The function has special handling for the "wss" protocol, converting it to "x-parity-wss", which suggests this utility was created with specific use cases in mind.

Let's verify the behavior with some examples:


🏁 Script executed:

#!/bin/bash
# Create a small test script to verify the behavior of convertToRelayUri
cat > test-uri-conversion.js << 'EOF'
const { convertToRelayUri } = require('./packages/utils/src/utils/index.ts');

// Test cases
const testCases = [
  "http://example.com",
  "https://example.com:8443",
  "http://127.0.0.1:8080",
  "http://[::1]:8080",
  "wss://relay.dojo.io",
  "http://example.com/path%20with%20spaces"
];

for (const uri of testCases) {
  console.log(`${uri} → ${convertToRelayUri(uri)}`);
}
EOF

# Check if ts-node is available for running TypeScript directly
if command -v npx &> /dev/null && npx ts-node -v &> /dev/null; then
  echo "Running URI conversion tests..."
  npx ts-node test-uri-conversion.js
else
  echo "ts-node not available. Cannot run the test directly."
  echo "The test would verify convertToRelayUri for various URI formats."
fi

Length of output: 1828


Attention: Manual verification required for test harness compatibility with ES Modules

The implementation of convertToRelayUri looks robust—it handles various address types (IPv4, IPv6, domain names), applies proper default port logic, and includes special handling for protocols (including the intended conversion of "wss" to "x-parity-wss"). The thorough inline documentation and examples are very helpful.

However, please note the following points:

  • URL Pathname Encoding: The use of encodeURIComponent on url.pathname (line 447) might lead to double encoding if the path is already encoded. Please verify that this behavior is intended.
  • Test Harness ES Module Issue: The provided test script fails because it uses require() to load index.ts, which is an ES module (as indicated by "type": "module" in the package config). To proceed:
    • Update the test script to use ES module syntax (e.g., replacing require() with a dynamic import() or converting the test file to a .mjs file).
    • Re-run tests to validate the conversion outputs against the example cases.

Please adjust the testing approach accordingly and manually verify the functionality.

packages/sdk/src/state/zustand.ts (5)

29-31: Good implementation of the CairoOption type guard

This type guard is well implemented and will help with type safety when working with CairoOption instances.


39-66: Good implementation of the mergeCairoOption function

The mergeCairoOption function correctly prioritizes the source value if it's a Some variant, which is a logical merging strategy.


73-75: Good implementation of the CairoCustomEnum type guard

This type guard is well implemented and will help with type safety when working with CairoCustomEnum instances.


147-152: Good enhancements to the deepMerge function

The additions to the deepMerge function properly handle the Cairo-specific types by delegating to the specialized merge functions.


197-201: Improved readability with for...of loops and proper deep merging

The code changes from using forEach to for...of loops and properly implements deep merging for Cairo types. This is a good improvement for readability and correctness.

Also applies to: 205-217, 223-244, 272-292

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

♻️ Duplicate comments (1)
packages/sdk/src/react/hooks.ts (1)

82-86: ⚠️ Potential issue

Fix the return value mapping implementation

The current implementation is mapping entities to an array of objects (each with a single key-value pair) but then casting it to a single object with string keys. This will not work correctly at runtime.

Apply this fix to correctly convert the array of entities into a single object:

-    const modelData = useDojoStore((state) =>
-        state.getEntitiesByModel(namespace, modelName).map((entity) => ({
-            [entity.entityId]: entity.models?.[namespace]?.[modelName],
-        }))
-    ) as unknown as { [entityId: string]: SchemaType[N][M] | undefined };
+    const modelData = useDojoStore((state) =>
+        state.getEntitiesByModel(namespace, modelName).reduce((acc, entity) => ({
+            ...acc,
+            [entity.entityId]: entity.models?.[namespace]?.[modelName],
+        }), {})
+    ) as { [entityId: string]: SchemaType[N][M] | undefined };

This uses reduce() to properly accumulate the entities into a single object, eliminating the need for the unknown cast.

🧹 Nitpick comments (3)
packages/sdk/src/react/hooks.ts (2)

72-81: Type definitions match the existing pattern

The type parameters follow the same pattern as other hooks in the file, maintaining consistency. However, consider replacing the any type with more specific types if possible to improve type safety.

-    Client extends (...args: any) => any,
+    Client extends (...args: unknown[]) => unknown,
🧰 Tools
🪛 Biome (1.9.4)

[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


251-251: Remove unnecessary blank line

There's an extra blank line that doesn't serve any purpose.

-
packages/sdk/src/state/zustand.ts (1)

96-96: Consider replacing 'any' with more specific types.

The static analysis tools flagged the use of any type in the code. While it's acceptable in some cases, consider using more specific types or interface definitions where possible to improve type safety.

You could replace these with more specific types or use a generic parameter constrained to the expected structure.

Also applies to: 116-116

🧰 Tools
🪛 Biome (1.9.4)

[error] 96-96: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 0e64e57 and 811ae57.

📒 Files selected for processing (14)
  • .changeset/brave-kiwis-explode.md (1 hunks)
  • examples/example-vite-react-sdk/src/App.tsx (1 hunks)
  • examples/example-vite-react-sdk/src/main.tsx (0 hunks)
  • package.json (1 hunks)
  • packages/sdk/src/experimental/index.ts (1 hunks)
  • packages/sdk/src/index.ts (5 hunks)
  • packages/sdk/src/parseEntities.ts (1 hunks)
  • packages/sdk/src/react/hooks.ts (2 hunks)
  • packages/sdk/src/state/zustand.ts (6 hunks)
  • packages/sdk/src/types.ts (2 hunks)
  • packages/torii-wasm/package.json (0 hunks)
  • packages/utils/src/_test_/utils/index.test.ts (2 hunks)
  • packages/utils/src/utils/index.ts (1 hunks)
  • turbo.json (1 hunks)
💤 Files with no reviewable changes (2)
  • examples/example-vite-react-sdk/src/main.tsx
  • packages/torii-wasm/package.json
🚧 Files skipped from review as they are similar to previous changes (8)
  • examples/example-vite-react-sdk/src/App.tsx
  • packages/sdk/src/parseEntities.ts
  • packages/sdk/src/experimental/index.ts
  • turbo.json
  • packages/utils/src/test/utils/index.test.ts
  • packages/sdk/src/types.ts
  • package.json
  • .changeset/brave-kiwis-explode.md
🧰 Additional context used
🪛 Biome (1.9.4)
packages/sdk/src/state/zustand.ts

[error] 96-96: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 116-116: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

packages/sdk/src/react/hooks.ts

[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 75-75: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build
  • GitHub Check: check
🔇 Additional comments (16)
packages/sdk/src/react/hooks.ts (1)

66-71: Great addition of the useModels hook with clear documentation

The JSDoc comments clearly explain the purpose of the hook and its parameters. This is a useful addition that complements the existing useModel hook by allowing retrieval of all entities of a specific model type.

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

376-391: Well-implemented utility function for port determination.

The getDefaultPortForProtocol function provides a clean way to determine default ports for various protocols. The function handles the common secure protocols (https, wss) and provides a sensible default for other protocols.


393-454:

❓ Verification inconclusive

Good implementation of URI to multiaddr conversion with comprehensive error handling.

The convertToRelayUri function is well-documented with examples and handles various URI formats (IPv4, IPv6, domain names). The logic is clear and follows a logical flow with proper error handling.

A few observations:

  • The function properly handles special cases like IPv6 addresses
  • Including error handling with try/catch is a good practice
  • The commented examples provide clarity on expected behavior

🏁 Script executed:

#!/bin/bash
# Test the convertToRelayUri function with various URI formats

# Create a simple test file to verify the function
cat > test.js << 'EOF'
const { convertToRelayUri } = require('./packages/utils/src/utils/index');

// Test cases
const testCases = [
  { input: 'http://example.com', expected: '/dns4/example.com/tcp/80' },
  { input: 'https://example.com', expected: '/dns4/example.com/tcp/443' },
  { input: 'http://127.0.0.1:8080', expected: '/ip4/127.0.0.1/tcp/8080' },
  { input: 'http://[::1]:8080', expected: '/ip6/::1/tcp/8080' },
  { input: 'wss://example.com', expected: '/dns4/example.com/tcp/443/x-parity-wss' },
  { input: 'invalid-uri', expected: '' }
];

testCases.forEach(({ input, expected }) => {
  const result = convertToRelayUri(input);
  console.log(`Input: ${input}`);
  console.log(`Result: ${result}`);
  console.log(`Expected: ${expected}`);
  console.log(`Matches: ${result.includes(expected)}`);
  console.log('---');
});
EOF

# Run the test
node test.js

Length of output: 926


Action Required: Verify Test Environment Setup for TypeScript Module Resolution

The implementation of the convertToRelayUri function remains well-documented and robust with comprehensive URI handling and proper error management. However, note that the test script failed due to a module resolution error when attempting to require the TypeScript file directly. This issue typically arises because Node.js needs the file to be compiled (or run via a TypeScript-compatible runner such as ts-node).

Please verify and adjust the test environment accordingly:

  • Confirm that the file at packages/utils/src/utils/index.ts is either compiled to JavaScript or run with a TypeScript runner (e.g., ts-node).
  • Update the test script or build process to ensure proper module resolution for TypeScript files.
packages/sdk/src/index.ts (4)

2-2: Improved type imports for better code organization.

Converting regular imports to type imports for types that are only used for type checking (not at runtime) is a good practice. This helps with tree-shaking and clarifies the intent of these imports.

Also applies to: 4-17


37-40: Good addition of default client configuration.

Adding default configuration values improves the developer experience by providing sensible defaults while still allowing customization. This change aligns with modern JavaScript practices of providing default values that can be overridden.


51-55: Improved client configuration with defaults.

The implementation properly merges default configuration with user-provided options, using the spread operator. This ensures defaults are applied only when values aren't explicitly provided.


158-165: Enhanced error handling in callback.

The error handling improvement ensures that callbacks always receive a proper Error instance, making error handling more consistent for consumers of this API.

packages/sdk/src/state/zustand.ts (9)

24-31: Well-documented type guard function for CairoOption.

The isCairoOption function provides a clear type guard that follows TypeScript best practices. The function is properly documented with JSDoc comments.


33-66: Proper implementation of CairoOption merging with clear logic.

The mergeCairoOption function handles the merging of Cairo options with appropriate priority rules (prefers source's value if it's "Some", keeps target otherwise). The function handles edge cases well.


68-75: Well-documented type guard function for CairoCustomEnum.

The isCairoCustomEnum type guard follows the same pattern as isCairoOption, providing a consistent API for type checking. The function is well-documented with JSDoc comments.


77-133: Comprehensive implementation of CairoCustomEnum merging.

The mergeCairoCustomEnum function handles complex merging of Cairo custom enums by:

  • Checking if both values are CairoCustomEnum instances
  • Prioritizing the source's active variant if available
  • Falling back to the target's active variant
  • Creating a new enum with the appropriate active variant

The implementation is thorough and handles edge cases appropriately.

🧰 Tools
🪛 Biome (1.9.4)

[error] 96-96: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


[error] 116-116: Unexpected any. Specify a different type.

any disables many type checking rules. Its use should be avoided.

(lint/suspicious/noExplicitAny)


147-152: Enhanced deepMerge function to support Cairo types.

The modification to deepMerge properly integrates the new Cairo type support while maintaining compatibility with existing code. The implementation follows a clear pattern of checking types before applying specialized merging logic.


197-201: Improved loop structure for better readability.

Changing from forEach to a for...of loop improves readability and makes the code structure more consistent with the other loops in the file.


205-217: Enhanced entity merging with better control flow.

The loop structure has been improved by using for...of and replacing the return statement with continue, which makes the control flow more intuitive and maintains consistency throughout the loop.


223-246: Improved deep merging of namespace models.

The implementation now properly handles deep merging of models with nested structures and Cairo types. The loop has been restructured for better readability and the type assertions have been updated for consistency.


274-296: Consistent implementation of deep merging in updateEntity.

The changes to the updateEntity function mirror those in the mergeEntities function, ensuring consistent behavior between the two. The use of for...of loops and proper deep merging improves the reliability of model updates.

@MartianGreed MartianGreed merged commit 666e8ca into main Mar 14, 2025
6 checks passed
@MartianGreed MartianGreed deleted the feat/sdk-hooks branch March 14, 2025 20:17
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