Skip to content

Refactor load layer to use storage as the main interface for reading data - #631

Merged
DZakh merged 3 commits into
mainfrom
dz/use-storage-interface
Jul 9, 2025
Merged

Refactor load layer to use storage as the main interface for reading data#631
DZakh merged 3 commits into
mainfrom
dz/use-storage-interface

Conversation

@DZakh

@DZakh DZakh commented Jul 9, 2025

Copy link
Copy Markdown
Member

The goal of the PR is to simplify the development and testing of the persistence layer. It moves more code from codegen to the library by starting to fully utilize the newly created Storage abstraction (as an injectable interface)

There are also some traces of effect caching, but it's not usable yet.

Summary by CodeRabbit

  • New Features

    • Added support for effect caching with new options and persistence metadata.
    • Introduced methods to load effect caches and query by arbitrary fields in storage.
  • Refactor

    • Removed the load layer abstraction, requiring explicit load manager and storage parameters.
    • Renamed SQL generation functions for clearer naming.
    • Replaced mock load layer with a more flexible mock storage interface.
    • Updated event processing and user context to use load manager and storage explicitly.
    • Simplified in-memory store access and unified internal entity casting.
  • Bug Fixes

    • Improved error messages and type safety in storage initialization and event processing.
  • Tests

    • Updated tests to align with new mock storage and load manager usage.
    • Adjusted test setups to remove load layer dependencies and use updated interfaces.

@coderabbitai

coderabbitai Bot commented Jul 9, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

This change refactors the loading and persistence infrastructure, introducing explicit separation between load manager and storage interfaces, and enhances effect caching support. It updates type definitions, restructures function signatures, removes indirection layers, and standardizes naming conventions for SQL query generation. Test and mock infrastructure are also updated to match the new abstractions.

Changes

File(s) Change Summary
codegenerator/cli/npm/envio/index.d.ts, src/Envio.gen.ts, src/Envio.res, src/Internal.res Added optional cache property to effect options/types and updated effect creation to include cache status.
src/Persistence.res, src/PgStorage.res Introduced effect cache tracking/types, added methods for loading effect caches and querying by arbitrary fields, improved table name handling, and renamed SQL generator functions to *Query.
templates/dynamic/codegen/src/TestHelpers_MockDb.res.hbs Refactored mock DB operations to use entity name keys and a mock storage layer, standardizing data access and loading logic.
templates/static/codegen/src/EventProcessing.res, src/UserContext.res Replaced loadLayer parameter with explicit loadManager and storage parameters throughout event processing and user context code.
templates/static/codegen/src/IO.res Switched in-memory table access to use a getter function on the in-memory store.
templates/static/codegen/src/InMemoryStore.res Changed entity table retrieval to use entity names, updated internal casting for entity storage.
templates/static/codegen/src/Index.res, src/globalState/GlobalState.res Removed loadLayer from global state and main entrypoint, initializing loadManager internally instead.
templates/static/codegen/src/LoadLayer.res, src/LoadLayer.resi Removed LoadLayer abstraction and types, refactored loading functions to accept loadManager and storage explicitly.
templates/static/codegen/src/db/DbFunctionsEntities.res, src/db/DbFunctionsImplementation.js Removed query-by-condition functions and related code, leaving only batch delete logic.
templates/static/codegen/src/db/TablesStatic.res Added identity cast function for converting dynamic contract registry types to internal entities.
scenarios/test_codegen/test/LoadLayer_test.res, test/lib_tests/Persistence_test.res, test/Mock_test.res Updated tests to use new mock storage, load manager, and effect cache tracking; replaced LoadLayer mocks with explicit storage mocks.
scenarios/test_codegen/test/lib_tests/PgStorage_test.res, test/SerDe_Test.res, test/lib_tests/EntityHistory_test.res Renamed SQL generator function calls and variables from *Sql to *Query in tests.
scenarios/test_codegen/test/E2EEthNode_test.res, test/Integration_ts_helpers.res, test/rollback/Rollback_test.res, test/schema_types/BigDecimal_test.res, test/schema_types/Timestamp_test.res Removed creation and passing of loadLayer in test setup, updated context construction to use loadManager and storage as needed.
scenarios/test_codegen/test/helpers/Mock.res Replaced LoadLayer mock with a comprehensive Storage mock supporting multiple methods and call tracking.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant EventProcessing
    participant LoadManager
    participant Storage

    User->>EventProcessing: processEventBatch(...)
    EventProcessing->>LoadManager: runBatchHandlersOrThrow(~loadManager, ~storage, ...)
    LoadManager->>Storage: loadByIdsOrThrow / loadByFieldOrThrow(...)
    Storage-->>LoadManager: Promise<entities>
    LoadManager-->>EventProcessing: entities
    EventProcessing-->>User: Processing complete
Loading

Possibly related PRs

  • Just clean up, no changes #609: Modifies effect caching support by removing cacheStorage and related cache schema handling, directly related to this PR's enhancement of effect cache tracking and persistence.

Suggested reviewers

  • JasoonS
  • JonoPrest

Poem

In the warren where code bunnies dwell,
We hopped through the layers and tidied up well.
No more loadLayer, just storage and friends,
With caching for effects and new query trends.
Now our carrots (and queries) are easy to find—
Hooray for refactors, of the thoughtful kind!
🥕🐇


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ad6e1c8 and 1256af4.

⛔ Files ignored due to path filters (1)
  • scenarios/erc20_multichain_factory/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • scenarios/erc20_multichain_factory/test/DynamicContractRecovery_test.res (1 hunks)
  • scenarios/erc20_multichain_factory/test/TestDeleteEntity.res (1 hunks)
  • scenarios/erc20_multichain_factory/test/TestWhereQuery.res (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
`**/*.res`: Never use `[| item |]` to create an array. Use `[ item ]` instead. M...

**/*.res: Never use [| item |] to create an array. Use [ item ] instead.
Must always use = for setting value to a field. Use := only for ref values created using ref function.
It's also possible to define an inline object, it'll have quoted fields in this case.
Never use %raw to access object fields if you know the type.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/rescript.mdc)

List of files the instruction was applied to:

  • scenarios/erc20_multichain_factory/test/TestWhereQuery.res
  • scenarios/erc20_multichain_factory/test/TestDeleteEntity.res
  • scenarios/erc20_multichain_factory/test/DynamicContractRecovery_test.res
`**/*.{res,resi}`: ReScript has record types which require a type definition bef...

**/*.{res,resi}: ReScript has record types which require a type definition beforehand. You can access record fields by dot like foo.myField.
Use records when working with structured data, and objects to conveniently pass payload data between functions.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/rescript.mdc)

List of files the instruction was applied to:

  • scenarios/erc20_multichain_factory/test/TestWhereQuery.res
  • scenarios/erc20_multichain_factory/test/TestDeleteEntity.res
  • scenarios/erc20_multichain_factory/test/DynamicContractRecovery_test.res
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (3)
scenarios/erc20_multichain_factory/test/TestWhereQuery.res (1)

124-124: LGTM! Clean refactor aligns with architectural improvements.

The removal of the loadLayer parameter from GlobalState.make is consistent with the broader refactor to eliminate the loadLayer abstraction and use explicit loadManager and storage parameters instead. This simplifies initialization and improves modularity.

scenarios/erc20_multichain_factory/test/TestDeleteEntity.res (1)

130-130: LGTM! Consistent with the loadLayer abstraction removal.

The simplification of GlobalState.make initialization by removing the loadLayer parameter is consistent with the architectural refactor across the codebase. This change maintains test functionality while aligning with the new storage abstraction pattern.

scenarios/erc20_multichain_factory/test/DynamicContractRecovery_test.res (1)

166-166: LGTM! Completes the consistent refactor pattern.

The removal of the loadLayer parameter from GlobalState.make is consistent with the same change in the other test files. This architectural improvement enhances modularity by centralizing load functionality within the storage abstraction while maintaining all test functionality.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this 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.

@DZakh
DZakh requested a review from moose-code July 9, 2025 12:51
Comment on lines -5 to -43
type t = {
loadManager: LoadManager.t,
loadEntitiesByIds: (
array<Types.id>,
~entityConfig: Internal.entityConfig,
) => promise<array<Internal.entity>>,
loadEntitiesByField: (
~operator: TableIndices.Operator.t,
~entityConfig: Internal.entityConfig,
~fieldName: string,
~fieldValue: fieldValue,
~fieldValueSchema: S.t<fieldValue>,
~logger: Pino.t=?,
) => promise<array<Internal.entity>>,
}

let make = (~loadEntitiesByIds, ~loadEntitiesByField) => {
{
loadManager: LoadManager.make(),
loadEntitiesByIds,
loadEntitiesByField,
}
}

// Ideally it shouldn't be here, but it'll make writing tests easier,
// until we have a proper mocking solution.
let makeWithDbConnection = (~persistence=Config.codegenPersistence) => {
let storage = Persistence.getInitializedStorageOrThrow(persistence)
{
loadManager: LoadManager.make(),
loadEntitiesByIds: (ids, ~entityConfig) =>
storage.loadByIdsOrThrow(
~table=entityConfig.table,
~rowsSchema=entityConfig.rowsSchema,
~ids,
),
loadEntitiesByField: DbFunctionsEntities.makeWhereQuery(Db.sql),
}
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This was bad and it was removed.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (2)
codegenerator/cli/templates/dynamic/codegen/src/TestHelpers_MockDb.res.hbs (2)

417-465: Add TODO comments for unimplemented storage methods.

Several methods throw "Not used yet" errors without explanation. Consider adding TODO comments or implementing these methods to avoid confusion during testing.

 and makeMockStorage = (mockDb: t): Persistence.storage => {
   {
-    isInitialized: () => Js.Exn.raiseError("Not used yet"),
+    // TODO: Implement when needed for testing initialization state
+    isInitialized: () => Js.Exn.raiseError("Not implemented yet"),
-    initialize: (~entities as _=?, ~generalTables as _=?, ~enums as _=?) =>
-      Js.Exn.raiseError("Not used yet"),
+    // TODO: Implement when needed for testing initialization flow
+    initialize: (~entities as _=?, ~generalTables as _=?, ~enums as _=?) =>
+      Js.Exn.raiseError("Not implemented yet"),
-    loadEffectCaches: () => Js.Exn.raiseError("Not used yet"),
+    // TODO: Implement when effect caching is fully functional
+    loadEffectCaches: () => Js.Exn.raiseError("Not implemented yet"),

441-462: Consider performance implications of index evaluation.

The current implementation iterates through all entities for field-based queries. While acceptable for testing, consider adding a comment about the O(n) performance characteristic.

For larger test datasets, you might want to consider maintaining indexes for frequently queried fields to improve lookup performance.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 0f5acf5 and ad6e1c8.

📒 Files selected for processing (30)
  • codegenerator/cli/npm/envio/index.d.ts (1 hunks)
  • codegenerator/cli/npm/envio/src/Envio.gen.ts (1 hunks)
  • codegenerator/cli/npm/envio/src/Envio.res (2 hunks)
  • codegenerator/cli/npm/envio/src/Internal.res (1 hunks)
  • codegenerator/cli/npm/envio/src/Persistence.res (4 hunks)
  • codegenerator/cli/npm/envio/src/PgStorage.res (17 hunks)
  • codegenerator/cli/templates/dynamic/codegen/src/TestHelpers_MockDb.res.hbs (7 hunks)
  • codegenerator/cli/templates/static/codegen/src/EventProcessing.res (11 hunks)
  • codegenerator/cli/templates/static/codegen/src/IO.res (3 hunks)
  • codegenerator/cli/templates/static/codegen/src/InMemoryStore.res (5 hunks)
  • codegenerator/cli/templates/static/codegen/src/Index.res (3 hunks)
  • codegenerator/cli/templates/static/codegen/src/LoadLayer.res (9 hunks)
  • codegenerator/cli/templates/static/codegen/src/LoadLayer.resi (3 hunks)
  • codegenerator/cli/templates/static/codegen/src/UserContext.res (11 hunks)
  • codegenerator/cli/templates/static/codegen/src/db/DbFunctionsEntities.res (1 hunks)
  • codegenerator/cli/templates/static/codegen/src/db/DbFunctionsImplementation.js (0 hunks)
  • codegenerator/cli/templates/static/codegen/src/db/TablesStatic.res (1 hunks)
  • codegenerator/cli/templates/static/codegen/src/globalState/GlobalState.res (4 hunks)
  • scenarios/test_codegen/test/E2EEthNode_test.res (1 hunks)
  • scenarios/test_codegen/test/Integration_ts_helpers.res (0 hunks)
  • scenarios/test_codegen/test/LoadLayer_test.res (21 hunks)
  • scenarios/test_codegen/test/Mock_test.res (1 hunks)
  • scenarios/test_codegen/test/SerDe_Test.res (1 hunks)
  • scenarios/test_codegen/test/helpers/Mock.res (1 hunks)
  • scenarios/test_codegen/test/lib_tests/EntityHistory_test.res (2 hunks)
  • scenarios/test_codegen/test/lib_tests/Persistence_test.res (4 hunks)
  • scenarios/test_codegen/test/lib_tests/PgStorage_test.res (6 hunks)
  • scenarios/test_codegen/test/rollback/Rollback_test.res (2 hunks)
  • scenarios/test_codegen/test/schema_types/BigDecimal_test.res (2 hunks)
  • scenarios/test_codegen/test/schema_types/Timestamp_test.res (2 hunks)
💤 Files with no reviewable changes (2)
  • scenarios/test_codegen/test/Integration_ts_helpers.res
  • codegenerator/cli/templates/static/codegen/src/db/DbFunctionsImplementation.js
🧰 Additional context used
📓 Path-based instructions (2)
`**/*.res`: Never use `[| item |]` to create an array. Use `[ item ]` instead. M...

**/*.res: Never use [| item |] to create an array. Use [ item ] instead.
Must always use = for setting value to a field. Use := only for ref values created using ref function.
It's also possible to define an inline object, it'll have quoted fields in this case.
Never use %raw to access object fields if you know the type.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/rescript.mdc)

List of files the instruction was applied to:

  • scenarios/test_codegen/test/rollback/Rollback_test.res
  • codegenerator/cli/templates/static/codegen/src/db/TablesStatic.res
  • scenarios/test_codegen/test/SerDe_Test.res
  • scenarios/test_codegen/test/schema_types/BigDecimal_test.res
  • scenarios/test_codegen/test/schema_types/Timestamp_test.res
  • scenarios/test_codegen/test/Mock_test.res
  • scenarios/test_codegen/test/lib_tests/EntityHistory_test.res
  • codegenerator/cli/templates/static/codegen/src/IO.res
  • codegenerator/cli/npm/envio/src/Internal.res
  • codegenerator/cli/npm/envio/src/Envio.res
  • scenarios/test_codegen/test/E2EEthNode_test.res
  • codegenerator/cli/templates/static/codegen/src/db/DbFunctionsEntities.res
  • scenarios/test_codegen/test/lib_tests/PgStorage_test.res
  • scenarios/test_codegen/test/lib_tests/Persistence_test.res
  • codegenerator/cli/templates/static/codegen/src/Index.res
  • codegenerator/cli/templates/static/codegen/src/globalState/GlobalState.res
  • scenarios/test_codegen/test/LoadLayer_test.res
  • codegenerator/cli/templates/static/codegen/src/UserContext.res
  • codegenerator/cli/templates/static/codegen/src/InMemoryStore.res
  • codegenerator/cli/templates/static/codegen/src/EventProcessing.res
  • scenarios/test_codegen/test/helpers/Mock.res
  • codegenerator/cli/templates/static/codegen/src/LoadLayer.res
  • codegenerator/cli/npm/envio/src/Persistence.res
  • codegenerator/cli/npm/envio/src/PgStorage.res
`**/*.{res,resi}`: ReScript has record types which require a type definition bef...

**/*.{res,resi}: ReScript has record types which require a type definition beforehand. You can access record fields by dot like foo.myField.
Use records when working with structured data, and objects to conveniently pass payload data between functions.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/rescript.mdc)

List of files the instruction was applied to:

  • scenarios/test_codegen/test/rollback/Rollback_test.res
  • codegenerator/cli/templates/static/codegen/src/db/TablesStatic.res
  • scenarios/test_codegen/test/SerDe_Test.res
  • scenarios/test_codegen/test/schema_types/BigDecimal_test.res
  • scenarios/test_codegen/test/schema_types/Timestamp_test.res
  • scenarios/test_codegen/test/Mock_test.res
  • scenarios/test_codegen/test/lib_tests/EntityHistory_test.res
  • codegenerator/cli/templates/static/codegen/src/IO.res
  • codegenerator/cli/npm/envio/src/Internal.res
  • codegenerator/cli/npm/envio/src/Envio.res
  • scenarios/test_codegen/test/E2EEthNode_test.res
  • codegenerator/cli/templates/static/codegen/src/db/DbFunctionsEntities.res
  • scenarios/test_codegen/test/lib_tests/PgStorage_test.res
  • scenarios/test_codegen/test/lib_tests/Persistence_test.res
  • codegenerator/cli/templates/static/codegen/src/Index.res
  • codegenerator/cli/templates/static/codegen/src/globalState/GlobalState.res
  • scenarios/test_codegen/test/LoadLayer_test.res
  • codegenerator/cli/templates/static/codegen/src/UserContext.res
  • codegenerator/cli/templates/static/codegen/src/InMemoryStore.res
  • codegenerator/cli/templates/static/codegen/src/EventProcessing.res
  • scenarios/test_codegen/test/helpers/Mock.res
  • codegenerator/cli/templates/static/codegen/src/LoadLayer.res
  • codegenerator/cli/npm/envio/src/Persistence.res
  • codegenerator/cli/templates/static/codegen/src/LoadLayer.resi
  • codegenerator/cli/npm/envio/src/PgStorage.res
🧠 Learnings (10)
scenarios/test_codegen/test/SerDe_Test.res (1)
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:631-659
Timestamp: 2025-05-27T17:07:12.878Z
Learning: In isolated tests for EntityHistory rollbacks with controlled mock data setup, the ordering of getRollbackDiff results is deterministic and doesn't require sorting before comparison with deepStrictEqual.
scenarios/test_codegen/test/lib_tests/EntityHistory_test.res (1)
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:631-659
Timestamp: 2025-05-27T17:07:12.878Z
Learning: In isolated tests for EntityHistory rollbacks with controlled mock data setup, the ordering of getRollbackDiff results is deterministic and doesn't require sorting before comparison with deepStrictEqual.
codegenerator/cli/templates/static/codegen/src/IO.res (1)
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:631-659
Timestamp: 2025-05-27T17:07:12.878Z
Learning: In isolated tests for EntityHistory rollbacks with controlled mock data setup, the ordering of getRollbackDiff results is deterministic and doesn't require sorting before comparison with deepStrictEqual.
codegenerator/cli/templates/static/codegen/src/db/DbFunctionsEntities.res (2)
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:582-629
Timestamp: 2025-05-27T17:07:04.699Z
Learning: In ReScript test files using DbHelpers.resetPostgresClient(), this function is synchronous with signature `unit => unit` and should not be awaited. It performs a raw JavaScript reassignment of the postgres client and does not return a promise.
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:582-629
Timestamp: 2025-05-27T17:07:04.699Z
Learning: In ReScript test files using DbHelpers.resetPostgresClient(), this function is synchronous with signature `unit => unit` and should not be awaited. It performs a raw JavaScript reassignment of the postgres client and does not return a promise.
scenarios/test_codegen/test/lib_tests/PgStorage_test.res (3)
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:582-629
Timestamp: 2025-05-27T17:07:04.699Z
Learning: In ReScript test files using DbHelpers.resetPostgresClient(), this function is synchronous with signature `unit => unit` and should not be awaited. It performs a raw JavaScript reassignment of the postgres client and does not return a promise.
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:582-629
Timestamp: 2025-05-27T17:07:04.699Z
Learning: In ReScript test files using DbHelpers.resetPostgresClient(), this function is synchronous with signature `unit => unit` and should not be awaited. It performs a raw JavaScript reassignment of the postgres client and does not return a promise.
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:631-659
Timestamp: 2025-05-27T17:07:12.878Z
Learning: In isolated tests for EntityHistory rollbacks with controlled mock data setup, the ordering of getRollbackDiff results is deterministic and doesn't require sorting before comparison with deepStrictEqual.
scenarios/test_codegen/test/lib_tests/Persistence_test.res (3)
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:631-659
Timestamp: 2025-05-27T17:07:12.878Z
Learning: In isolated tests for EntityHistory rollbacks with controlled mock data setup, the ordering of getRollbackDiff results is deterministic and doesn't require sorting before comparison with deepStrictEqual.
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:582-629
Timestamp: 2025-05-27T17:07:04.699Z
Learning: In ReScript test files using DbHelpers.resetPostgresClient(), this function is synchronous with signature `unit => unit` and should not be awaited. It performs a raw JavaScript reassignment of the postgres client and does not return a promise.
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:582-629
Timestamp: 2025-05-27T17:07:04.699Z
Learning: In ReScript test files using DbHelpers.resetPostgresClient(), this function is synchronous with signature `unit => unit` and should not be awaited. It performs a raw JavaScript reassignment of the postgres client and does not return a promise.
scenarios/test_codegen/test/LoadLayer_test.res (3)
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:631-659
Timestamp: 2025-05-27T17:07:12.878Z
Learning: In isolated tests for EntityHistory rollbacks with controlled mock data setup, the ordering of getRollbackDiff results is deterministic and doesn't require sorting before comparison with deepStrictEqual.
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:582-629
Timestamp: 2025-05-27T17:07:04.699Z
Learning: In ReScript test files using DbHelpers.resetPostgresClient(), this function is synchronous with signature `unit => unit` and should not be awaited. It performs a raw JavaScript reassignment of the postgres client and does not return a promise.
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:582-629
Timestamp: 2025-05-27T17:07:04.699Z
Learning: In ReScript test files using DbHelpers.resetPostgresClient(), this function is synchronous with signature `unit => unit` and should not be awaited. It performs a raw JavaScript reassignment of the postgres client and does not return a promise.
codegenerator/cli/templates/static/codegen/src/InMemoryStore.res (1)
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:631-659
Timestamp: 2025-05-27T17:07:12.878Z
Learning: In isolated tests for EntityHistory rollbacks with controlled mock data setup, the ordering of getRollbackDiff results is deterministic and doesn't require sorting before comparison with deepStrictEqual.
codegenerator/cli/templates/dynamic/codegen/src/TestHelpers_MockDb.res.hbs (3)
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:631-659
Timestamp: 2025-05-27T17:07:12.878Z
Learning: In isolated tests for EntityHistory rollbacks with controlled mock data setup, the ordering of getRollbackDiff results is deterministic and doesn't require sorting before comparison with deepStrictEqual.
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:582-629
Timestamp: 2025-05-27T17:07:04.699Z
Learning: In ReScript test files using DbHelpers.resetPostgresClient(), this function is synchronous with signature `unit => unit` and should not be awaited. It performs a raw JavaScript reassignment of the postgres client and does not return a promise.
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:582-629
Timestamp: 2025-05-27T17:07:04.699Z
Learning: In ReScript test files using DbHelpers.resetPostgresClient(), this function is synchronous with signature `unit => unit` and should not be awaited. It performs a raw JavaScript reassignment of the postgres client and does not return a promise.
codegenerator/cli/npm/envio/src/PgStorage.res (2)
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:582-629
Timestamp: 2025-05-27T17:07:04.699Z
Learning: In ReScript test files using DbHelpers.resetPostgresClient(), this function is synchronous with signature `unit => unit` and should not be awaited. It performs a raw JavaScript reassignment of the postgres client and does not return a promise.
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:582-629
Timestamp: 2025-05-27T17:07:04.699Z
Learning: In ReScript test files using DbHelpers.resetPostgresClient(), this function is synchronous with signature `unit => unit` and should not be awaited. It performs a raw JavaScript reassignment of the postgres client and does not return a promise.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (61)
codegenerator/cli/templates/static/codegen/src/db/TablesStatic.res (1)

247-247: LGTM! Clean type casting implementation.

The external function using %identity provides a type-safe, zero-cost conversion from DynamicContractRegistry.t to Internal.entity, which aligns well with the refactoring to centralize data handling through the Storage abstraction.

codegenerator/cli/npm/envio/src/Internal.res (1)

200-200: LGTM! Clean addition for effect caching support.

The cache: bool field is a straightforward addition that supports the new effect caching functionality. The field placement and typing follow ReScript conventions correctly.

scenarios/test_codegen/test/E2EEthNode_test.res (1)

73-73: LGTM! Simplified test setup aligns with refactoring goals.

The removal of loadLayer creation and the simplified GlobalState.make call effectively moves complexity from test setup into the library, which improves testability and aligns with the PR's goal of centralizing data operations through the Storage abstraction.

codegenerator/cli/npm/envio/index.d.ts (1)

108-109: LGTM! Well-documented optional property for effect caching.

The addition of the optional cache?: boolean property is properly typed and documented. The interface extension cleanly supports the new effect caching functionality while maintaining backward compatibility.

codegenerator/cli/npm/envio/src/Envio.gen.ts (1)

24-26: LGTM! Generated TypeScript properly reflects ReScript implementation.

The addition of the optional cache?: boolean property to the effectOptions type is correctly generated and properly documented. The generated TypeScript maintains consistency with the manual TypeScript declarations and the underlying ReScript implementation.

scenarios/test_codegen/test/SerDe_Test.res (2)

118-118: LGTM: Function name updated for consistency.

The function name change from makeCreateTableSql to makeCreateTableQuery aligns with the broader refactoring to standardize SQL generation function naming conventions.


123-123: LGTM: Function name updated for consistency.

The function name change from makeInsertUnnestSetSql to makeInsertUnnestSetQuery maintains consistency with the updated naming convention for SQL generation functions.

scenarios/test_codegen/test/rollback/Rollback_test.res (2)

144-144: LGTM: Removed loadLayer parameter as part of refactoring.

The removal of the ~loadLayer parameter from GlobalState.make() aligns with the refactoring to eliminate the loadLayer abstraction in favor of explicit loadManager and storage parameters. This change is consistent with the broader architectural improvements.


210-210: LGTM: Consistent removal of loadLayer parameter.

The removal of the ~loadLayer parameter maintains consistency with the refactoring changes throughout the codebase.

scenarios/test_codegen/test/Mock_test.res (2)

11-12: LGTM: Updated to use explicit loadManager and storage.

The replacement of LoadLayer.makeWithDbConnection() with explicit LoadManager.make() and Config.codegenPersistence.storage aligns with the refactoring to remove the loadLayer abstraction and use separate loadManager and storage components.


17-18: LGTM: Function call updated to use new parameters.

The update to pass ~loadManager and ~storage instead of ~loadLayer is consistent with the refactored function signature and the broader architectural changes.

scenarios/test_codegen/test/schema_types/BigDecimal_test.res (3)

38-39: LGTM: Consistent refactoring to explicit components.

The replacement of LoadLayer.makeWithDbConnection() with LoadManager.make() and Config.codegenPersistence.storage follows the same pattern as other test files and aligns with the architectural refactoring.


45-46: LGTM: Updated loader context parameters.

The update to pass ~loadManager and ~storage to UserContext.getLoaderContext is consistent with the refactored function signature.


58-59: LGTM: Updated handler context parameters.

The update to pass ~loadManager and ~storage to UserContext.getHandlerContext maintains consistency with the refactored interfaces.

scenarios/test_codegen/test/lib_tests/EntityHistory_test.res (2)

6-7: LGTM: Improved comment clarity.

The updated comment provides better clarity about the purpose of mandatory tables in Envio-managed schemas and specifically highlights the role of event_sync_state in identifying Envio-controlled schemas.


230-230: LGTM: Function name updated for consistency.

The function name change from makeCreateTableSql to makeCreateTableQuery maintains consistency with the updated naming convention for SQL generation functions across the codebase.

codegenerator/cli/npm/envio/src/Envio.res (2)

25-26: LGTM: Effect caching support added correctly.

The optional cache field follows proper ReScript conventions for optional record fields.


53-53: LGTM: Safe handling of optional cache field.

The use of Belt.Option.getWithDefault(false) correctly handles the optional cache field, providing a sensible default value when not specified.

scenarios/test_codegen/test/schema_types/Timestamp_test.res (2)

30-31: LGTM: Refactoring aligns with architectural changes.

The transition from LoadLayer.makeWithDbConnection() to separate LoadManager.make() and storage variables is consistent with the PR's objective to use storage as the main interface.


37-38: LGTM: Context construction updated consistently.

Both loader and handler contexts are updated to use the new loadManager and storage parameters, maintaining consistency across the codebase.

Also applies to: 49-50

codegenerator/cli/templates/static/codegen/src/IO.res (3)

57-58: LGTM: Improved abstraction with accessor function.

The change from direct dictionary access to using getInMemTable accessor function improves abstraction and type safety for in-memory entity table access.


137-138: LGTM: Consistent use of accessor function.

The refactoring to use getInMemTable is applied consistently across functions that access in-memory tables.


276-276: LGTM: Rollback function updated consistently.

The rollback functionality also uses the new accessor pattern, maintaining consistency with the refactoring.

scenarios/test_codegen/test/lib_tests/PgStorage_test.res (2)

4-4: LGTM: Consistent naming convention update.

The renaming from *Sql to *Query is applied consistently across all test functions and variables, aligning with the implementation changes in PgStorage.res.

Also applies to: 8-8, 15-15, 25-25, 32-32, 40-40, 44-44, 47-47, 54-54, 57-57, 62-62, 66-66, 69-69, 76-76, 79-79, 86-86, 90-90


239-239: LGTM: Comprehensive test suite naming update.

The extensive renaming maintains consistency with the new naming convention while preserving all test logic and expected SQL strings.

Also applies to: 243-243, 246-246, 256-256, 259-259, 267-267, 271-271, 274-274, 284-284, 287-287, 295-295, 299-299, 306-306, 309-309, 316-316, 323-323, 327-327, 328-328, 335-335, 339-339, 346-346, 350-350, 351-351, 361-361, 368-368, 372-372, 373-373

codegenerator/cli/templates/static/codegen/src/db/DbFunctionsEntities.res (1)

22-22: LGTM: Query-by-condition logic removed as part of architectural refactor.

The removal of query-by-condition functions aligns with the broader refactoring to use storage as the main interface for data loading operations. The remaining batchDelete functionality is appropriately preserved.

codegenerator/cli/templates/static/codegen/src/globalState/GlobalState.res (4)

60-60: LGTM! Field rename aligns with LoadLayer abstraction removal.

The field rename from loadLayer to loadManager is consistent with the architectural refactoring described in the PR objectives.


67-67: LGTM! Function signature simplified appropriately.

Removing the loadLayer parameter aligns with the internal initialization approach.


87-87: LGTM! Internal initialization follows the new pattern.

The internal initialization of loadManager via LoadManager.make() is consistent with the refactoring to remove the LoadLayer abstraction.


961-961: LGTM! Parameter update aligns with the refactoring.

Passing loadManager to EventProcessing.processEventBatch is consistent with the removal of the LoadLayer abstraction.

codegenerator/cli/templates/static/codegen/src/Index.res (3)

167-167: LGTM! Type definition simplified appropriately.

The simplified args type definition improves readability and maintainability.


181-184: LGTM! Code formatting improved.

The improved formatting of the Pervasives.max call enhances readability.


351-351: LGTM! Function call updated correctly.

The simplified GlobalState.make call aligns with the removed loadLayer parameter in the function signature.

scenarios/test_codegen/test/lib_tests/Persistence_test.res (4)

5-5: LGTM! Mock storage approach improved.

The new Mock.Storage.make with explicit capabilities provides better test clarity and maintainability compared to the previous approach.


88-88: LGTM! Test assertion updated for new persistence interface.

The addition of effectCaches in the Ready state assertion correctly reflects the expanded persistence layer interface.


124-124: LGTM! Mock capabilities updated for new storage interface.

Adding #loadEffectCaches capability correctly reflects the new storage interface method for loading effect cache metadata.


151-159: LGTM! Test assertions verify new effect cache loading behavior.

The updated assertions correctly validate that loadEffectCaches is called exactly once when storage is already initialized, which aligns with the new persistence layer behavior.

codegenerator/cli/templates/static/codegen/src/InMemoryStore.res (5)

21-22: LGTM! Interface improved with string-based entity names.

The change from ~entityConfig to ~entityName: string improves the interface abstraction by removing the need to pass entire config objects.


31-31: LGTM! Error message updated consistently.

The error message update to use entityName is consistent with the function signature change and maintains clear error reporting.


87-87: LGTM! Function adapted to new interface correctly.

The update to pass ~entityName=entityConfig.name correctly adapts to the new string-based interface while maintaining functionality.


98-98: LGTM! Improved abstraction with getInMemTable.

Using getInMemTable instead of direct EntityTables.get improves abstraction and follows the established pattern.


128-131: LGTM! Explicit entity casting ensures type safety.

The addition of TablesStatic.DynamicContractRegistry.castToInternal casting ensures entities are stored in the correct internal form, improving type safety.

scenarios/test_codegen/test/LoadLayer_test.res (4)

5-7: LGTM! Mock setup improved with explicit capabilities.

The new Mock.Storage.make approach with explicit capabilities (#loadByIdsOrThrow) and separate loadManager instantiation provides better test clarity and aligns with the new architecture.


10-18: LGTM! Function call updated to use explicit parameters.

The updated LoadLayer.loadById call with explicit ~loadManager and ~storage parameters correctly implements the new architecture while maintaining the same functionality.


24-31: LGTM! Assertion updated for new storage interface.

The updated assertion using storageMock.loadByIdsOrThrowCalls correctly validates the new storage interface calls with proper field validation (ids, tableName).


348-372: LGTM! LoadLayer.loadByField calls updated consistently.

The updated LoadLayer.loadByField calls with explicit ~loadManager and ~storage parameters follow the same pattern as the loadById updates and correctly implement the new architecture.

codegenerator/cli/templates/static/codegen/src/UserContext.res (1)

17-24: LGTM! Clean separation of concerns.

The refactoring from a single loadLayer to explicit loadManager and storage parameters improves modularity and makes the dependencies more explicit.

codegenerator/cli/templates/static/codegen/src/EventProcessing.res (1)

300-301: Good approach for obtaining storage instance.

Getting storage from config.persistence maintains backward compatibility while supporting the new architecture.

codegenerator/cli/templates/dynamic/codegen/src/TestHelpers_MockDb.res.hbs (1)

188-195: LGTM! Improved abstraction with string-based entity lookups.

Using entity names as strings instead of entity configs provides better flexibility and decoupling.

codegenerator/cli/npm/envio/src/Persistence.res (2)

125-149: Well-structured initialization with proper race condition handling.

The effect cache loading logic correctly handles initialization states and race conditions, ensuring caches are loaded only once during non-clean runs.


9-17: Dismiss thread-safety warning: single‐threaded, sequential access

In this CLI/Node context all effectCache instances are created and consumed through a single‐threaded event loop (the only async call is awaited before use), so there’s no concurrent mutation at runtime. You can safely leave the mutable fields as is.

Likely an incorrect or invalid review comment.

scenarios/test_codegen/test/helpers/Mock.res (1)

36-80: Excellent mock design with selective method implementation.

The new Storage mock provides comprehensive call tracking and selective method implementation, which greatly improves testability.

codegenerator/cli/templates/static/codegen/src/LoadLayer.res (3)

3-55: LGTM! Clean refactoring to explicit dependencies.

The function correctly replaces the loadLayer abstraction with explicit loadManager and storage parameters, maintaining all functionality including error handling.


57-89: LGTM! Straightforward parameter update.

The function correctly accepts the explicit loadManager parameter. No storage parameter is needed since this function handles effects without database interaction.


91-177: Well-executed refactoring with improved error context.

The function correctly implements the new explicit parameter pattern. The operator string conversion for cache keys improves readability, and the enhanced error logging with additional context (operator, table, field, value) will aid in debugging.

codegenerator/cli/templates/static/codegen/src/LoadLayer.resi (1)

1-31: Interface correctly updated to match implementation.

The removal of the abstract t type and factory functions, along with the updated function signatures to accept explicit loadManager and storage parameters, properly reflects the simplified architecture.

codegenerator/cli/npm/envio/src/PgStorage.res (5)

1-5: Excellent naming improvements for clarity.

The consistent renaming from *Sql to *Query better reflects that these functions generate SQL query strings. The cache object key update from "sql" to "query" maintains this consistency.

Also applies to: 7-13, 23-23, 55-168, 236-252, 311-321


344-351: Clean helper for schema introspection.

Good addition of the typed schemaTableName and corresponding query function for safe schema introspection.


389-408: Effect cache discovery looks good.

The function correctly identifies effect cache tables by prefix. Since this returns caches with size: 0 and table: None, I assume this is part of the "preliminary traces of effect caching" mentioned in the PR description?

Are there plans to populate the size and table fields in a follow-up PR?


444-489: Robust implementation of field-based loading.

Excellent error handling with descriptive messages for both serialization and query execution failures. The operator type conversion is clean and type-safe.


362-380: Excellent safety improvements in initialization.

The enhanced validation preventing accidental data loss is a great addition. The error message is particularly well-crafted with clear, actionable resolution steps.

Comment thread scenarios/test_codegen/test/helpers/Mock.res
@DZakh
DZakh enabled auto-merge (squash) July 9, 2025 13:30

@moose-code moose-code left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good improvements 💪

@DZakh
DZakh merged commit 6c7c321 into main Jul 9, 2025
2 checks passed
@DZakh
DZakh deleted the dz/use-storage-interface branch July 9, 2025 14:39
@coderabbitai coderabbitai Bot mentioned this pull request Jul 24, 2025
17 tasks
@coderabbitai coderabbitai Bot mentioned this pull request Oct 21, 2025
@coderabbitai coderabbitai Bot mentioned this pull request Nov 14, 2025
This was referenced Jan 9, 2026
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.

2 participants