-
Notifications
You must be signed in to change notification settings - Fork 663
Code generate filter function for non-unique indexes #3447
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
Open
aasoni
wants to merge
6
commits into
master
Choose a base branch
from
alessandro/typescript/generate-filter-function-for-non-unique-indexes
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Code generate filter function for non-unique indexes #3447
aasoni
wants to merge
6
commits into
master
from
alessandro/typescript/generate-filter-function-for-non-unique-indexes
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 tasks
github-merge-queue bot
pushed a commit
that referenced
this pull request
Nov 19, 2025
…s several bugs) (#3559) # Description of Changes This PR is a very large change to the workings of the TypeScript SDK and as such requires a higher bar of testing than other PRs. However, it does several important things: 1. Unifies the API of the server and client so they not only have the same API, but they actually implement it with the same TypeScript types. This fixes several inconsistencies between them and fixes several small bugs as well. 2. Closes #3365 3. Closes #3431 4. Closes #3435 5. Subsumes the work done in #3447 6. Derives all type information on the client from a single `RemoteModule` type which vastly cleans up the correctness of type checking on the client and helped me to find several small bugs It accomplishes this by changing code generation of TypeScript on the client to code generation approximately what a developer would manually write in their module. The ultimate goal would be to allow the developer to use the types and functions that they define on in their module directly on the client without needing to do any code generation at all, provided they are using TypeScript on the server and client. #3365 is resolved by `.build()`ing the `DbConnection` inside a React `useEffect` rather than doing it directly in line with the render of the provider. In order to do that we needed to not expose the `DbConnection` directly to developers by returning a different type from `useSpacetimeDB`. `useSpacetimeDB` now returns a `ConnectionState` object which is stored as React state and updates when any of the fields change. This change also resolves #3431. #3435 was the issue that initially lead me down the rabbit hole of unifying the server and the client because it was nearly impossible to track down all the various type functions and how they connect to the values that we code generate on the server. After several hours of attempting this, I decided to clean up the types a bit to be more uniform. Implementing the unification between the client and the server also necessitated fully implemented parts of the API that were fully implemented on the server, but were broken or missing on the client. # API and ABI breaking changes [Unification] -> Means that this is breaking behavior for the client SDK, but that the new behavior is identical to the server's existing behavior ## Breaking changes: - Table accessor names and index accessor names are converted to camelCase on the `ctx`, so `ctx.db.foo_bar` is now `ctx.db.fooBar` - [Unification] On the client `my_table.iter()` returns `IterableIterator` instead of an `Array` - [Unification] `module_bindings` now export `TypeBuilder`s for all types instead of a `type MyType` and object `MyType`, so instead of using `MyType` as a type directly, you need to infer the type `MyType` -> `Infer<typeof MyType>`. - [Unification] We no longer generate and export `MyTypeVariants` for sum types (these are now accessed by `Infer<typeof MyType.variants.myVariant>`) - [Unification] `MyType.getTypeScriptAlgebraicType()` has been replaced with `MyType.algebraicType` - `useSpacetimeDB()` no longer takes type parameters - `useTable()` now takes a `TableDef` parameter and type params are inferred - `useTable()` now just returns an `Array` directly instead of a object with `{ rows }` - [Unification] `ctx.reducers.createPlayer(argA, argB)` -> `ctx.reducers.createPlayer({ argA, argB })` - [Unification] `ctx.reducers.onCreatePlayer(ctx, argA, argB)` -> `ctx.reducers.onCreatePlayer(ctx, { argA, argB })` - [Unification] `ctx.reducers.removeOnCreatePlayer(ctx, argA, argB)` -> `ctx.reducers.removeOnCreatePlayer(ctx, { argA, argB })` - [Unification] `myTable.count(): number` -> `myTable.count(): bigint` ## Additive changes: - `Infer<>` now also does `InferTypeOfRow<>` if applicable - Added a `useReducer()` React hook - `module_bindings` now exports a `tables` object with references to all the `TableDef`s - `module_bindings` now exports a `reducers` object with references to all the `ReducerDef`s - Added a new `MyType.create('MyVariant', ...)` function in addition to the `MyType.MyVariant(...)` constructors (this is private) ## Notable things that did not change: - `MyType.serialize(writer: BinaryWriter, value: Infer<typeof MyType>)` and `MyType.deserialize(reader: BinaryReader): Infer<typeof MyType>` are still supported exactly as before. - The `MyType.MyVariant(...)` constructor function on sum types is still present, but implemented with the private `MyType.create('MyVariant', ...)`. We could choose to move away from this API later if we didn't like the variants polluting the namespace # Expected complexity level and risk 4 - This is a deep reaching an complex change for the SDK. For the server, it is much less deep reaching since it reuses much of the same machinery, although it does require thorough testing there as some of the code was modified. This change is fully localized to TypeScript and does not touch the host (or other languages) at all, and therefore only impacts a beta aspect of SpacetimeDB. # Testing <!-- Describe any testing you've done, and any testing you'd like your reviewers to do, so that you're confident that all the changes work as expected! --> - [ ] Added regression test for #3435 - [x] Manually tested `test-app` and `test-react-router-app` - [ ] Add test cases for camelCase-ing --------- Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com> Co-authored-by: Noa <coolreader18@gmail.com>
jdetter
pushed a commit
to clockworklabs/com.clockworklabs.spacetimedbsdk
that referenced
this pull request
Nov 21, 2025
…s several bugs) (#3559) # Description of Changes This PR is a very large change to the workings of the TypeScript SDK and as such requires a higher bar of testing than other PRs. However, it does several important things: 1. Unifies the API of the server and client so they not only have the same API, but they actually implement it with the same TypeScript types. This fixes several inconsistencies between them and fixes several small bugs as well. 2. Closes clockworklabs/SpacetimeDB#3365 3. Closes clockworklabs/SpacetimeDB#3431 4. Closes clockworklabs/SpacetimeDB#3435 5. Subsumes the work done in clockworklabs/SpacetimeDB#3447 6. Derives all type information on the client from a single `RemoteModule` type which vastly cleans up the correctness of type checking on the client and helped me to find several small bugs It accomplishes this by changing code generation of TypeScript on the client to code generation approximately what a developer would manually write in their module. The ultimate goal would be to allow the developer to use the types and functions that they define on in their module directly on the client without needing to do any code generation at all, provided they are using TypeScript on the server and client. clockworklabs/SpacetimeDB#3365 is resolved by `.build()`ing the `DbConnection` inside a React `useEffect` rather than doing it directly in line with the render of the provider. In order to do that we needed to not expose the `DbConnection` directly to developers by returning a different type from `useSpacetimeDB`. `useSpacetimeDB` now returns a `ConnectionState` object which is stored as React state and updates when any of the fields change. This change also resolves clockworklabs/SpacetimeDB#3431. clockworklabs/SpacetimeDB#3435 was the issue that initially lead me down the rabbit hole of unifying the server and the client because it was nearly impossible to track down all the various type functions and how they connect to the values that we code generate on the server. After several hours of attempting this, I decided to clean up the types a bit to be more uniform. Implementing the unification between the client and the server also necessitated fully implemented parts of the API that were fully implemented on the server, but were broken or missing on the client. # API and ABI breaking changes [Unification] -> Means that this is breaking behavior for the client SDK, but that the new behavior is identical to the server's existing behavior ## Breaking changes: - Table accessor names and index accessor names are converted to camelCase on the `ctx`, so `ctx.db.foo_bar` is now `ctx.db.fooBar` - [Unification] On the client `my_table.iter()` returns `IterableIterator` instead of an `Array` - [Unification] `module_bindings` now export `TypeBuilder`s for all types instead of a `type MyType` and object `MyType`, so instead of using `MyType` as a type directly, you need to infer the type `MyType` -> `Infer<typeof MyType>`. - [Unification] We no longer generate and export `MyTypeVariants` for sum types (these are now accessed by `Infer<typeof MyType.variants.myVariant>`) - [Unification] `MyType.getTypeScriptAlgebraicType()` has been replaced with `MyType.algebraicType` - `useSpacetimeDB()` no longer takes type parameters - `useTable()` now takes a `TableDef` parameter and type params are inferred - `useTable()` now just returns an `Array` directly instead of a object with `{ rows }` - [Unification] `ctx.reducers.createPlayer(argA, argB)` -> `ctx.reducers.createPlayer({ argA, argB })` - [Unification] `ctx.reducers.onCreatePlayer(ctx, argA, argB)` -> `ctx.reducers.onCreatePlayer(ctx, { argA, argB })` - [Unification] `ctx.reducers.removeOnCreatePlayer(ctx, argA, argB)` -> `ctx.reducers.removeOnCreatePlayer(ctx, { argA, argB })` - [Unification] `myTable.count(): number` -> `myTable.count(): bigint` ## Additive changes: - `Infer<>` now also does `InferTypeOfRow<>` if applicable - Added a `useReducer()` React hook - `module_bindings` now exports a `tables` object with references to all the `TableDef`s - `module_bindings` now exports a `reducers` object with references to all the `ReducerDef`s - Added a new `MyType.create('MyVariant', ...)` function in addition to the `MyType.MyVariant(...)` constructors (this is private) ## Notable things that did not change: - `MyType.serialize(writer: BinaryWriter, value: Infer<typeof MyType>)` and `MyType.deserialize(reader: BinaryReader): Infer<typeof MyType>` are still supported exactly as before. - The `MyType.MyVariant(...)` constructor function on sum types is still present, but implemented with the private `MyType.create('MyVariant', ...)`. We could choose to move away from this API later if we didn't like the variants polluting the namespace # Expected complexity level and risk 4 - This is a deep reaching an complex change for the SDK. For the server, it is much less deep reaching since it reuses much of the same machinery, although it does require thorough testing there as some of the code was modified. This change is fully localized to TypeScript and does not touch the host (or other languages) at all, and therefore only impacts a beta aspect of SpacetimeDB. # Testing <!-- Describe any testing you've done, and any testing you'd like your reviewers to do, so that you're confident that all the changes work as expected! --> - [ ] Added regression test for clockworklabs/SpacetimeDB#3435 - [x] Manually tested `test-app` and `test-react-router-app` - [ ] Add test cases for camelCase-ing --------- Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com> Co-authored-by: Noa <coolreader18@gmail.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description of Changes
Update typescript code generation to generate accessors on non unique indexes. These will use the
filterfunction as is the convention in C# and module api.Related to #1387 but doesn't close it.
API and ABI breaking changes
Expected complexity level and risk
2
Testing
Generated the following table:
Into typescript which resulted in the following code for index lookups:
I then manually inserted values into the test_index table and checked that calling the new filter and find functions returned the expected values.