From 169296bb92a1cd8e6bdb62dd7de9216e953b6224 Mon Sep 17 00:00:00 2001 From: Tyler Cloutier Date: Sun, 23 Nov 2025 23:03:41 -0500 Subject: [PATCH 01/11] Ran code gen --- .../examples/basic-react/package.json | 2 +- .../src/module_bindings/add_type.ts | 15 +++++ .../module_bindings/client_connected_type.ts | 13 +++++ .../client_disconnected_type.ts | 13 +++++ .../basic-react/src/module_bindings/index.ts | 37 +++++++++++- .../src/module_bindings/init_type.ts | 13 +++++ .../src/module_bindings/say_hello_type.ts | 13 +++++ .../empty/src/module_bindings/add_type.ts | 15 +++++ .../module_bindings/client_connected_type.ts | 13 +++++ .../client_disconnected_type.ts | 13 +++++ .../empty/src/module_bindings/index.ts | 37 +++++++++++- .../empty/src/module_bindings/init_type.ts | 13 +++++ .../src/module_bindings/say_hello_type.ts | 13 +++++ .../src/module_bindings/index.ts | 25 +++++++- crates/bindings-typescript/src/lib/table.ts | 3 +- .../bindings-typescript/src/lib/type_util.ts | 10 ++++ crates/bindings-typescript/src/lib/util.ts | 13 ++++- .../src/sdk/client_api/index.ts | 27 ++++++++- .../src/sdk/db_connection_impl.ts | 1 + .../test-app/src/module_bindings/index.ts | 27 ++++++++- .../basic-typescript/server/package.json | 2 +- .../basic-typescript/server/pnpm-lock.yaml | 51 ++++++++++++++++ crates/codegen/src/typescript.rs | 58 ++++++++++++------- 23 files changed, 389 insertions(+), 38 deletions(-) create mode 100644 crates/bindings-typescript/examples/basic-react/src/module_bindings/add_type.ts create mode 100644 crates/bindings-typescript/examples/basic-react/src/module_bindings/client_connected_type.ts create mode 100644 crates/bindings-typescript/examples/basic-react/src/module_bindings/client_disconnected_type.ts create mode 100644 crates/bindings-typescript/examples/basic-react/src/module_bindings/init_type.ts create mode 100644 crates/bindings-typescript/examples/basic-react/src/module_bindings/say_hello_type.ts create mode 100644 crates/bindings-typescript/examples/empty/src/module_bindings/add_type.ts create mode 100644 crates/bindings-typescript/examples/empty/src/module_bindings/client_connected_type.ts create mode 100644 crates/bindings-typescript/examples/empty/src/module_bindings/client_disconnected_type.ts create mode 100644 crates/bindings-typescript/examples/empty/src/module_bindings/init_type.ts create mode 100644 crates/bindings-typescript/examples/empty/src/module_bindings/say_hello_type.ts create mode 100644 crates/cli/templates/basic-typescript/server/pnpm-lock.yaml diff --git a/crates/bindings-typescript/examples/basic-react/package.json b/crates/bindings-typescript/examples/basic-react/package.json index 1c1d3d18f8f..5f33ad363f1 100644 --- a/crates/bindings-typescript/examples/basic-react/package.json +++ b/crates/bindings-typescript/examples/basic-react/package.json @@ -7,7 +7,7 @@ "dev": "vite", "build": "tsc -b && vite build", "preview": "vite preview", - "generate": "cargo run -p gen-bindings -- --out-dir src/module_bindings --project-path ../../../cli/templates/basic-typescript/server && prettier --write src/module_bindings", + "generate": "pnpm --dir ../../../cli/templates/basic-typescript/server install --ignore-workspace && cargo run -p gen-bindings -- --out-dir src/module_bindings --project-path ../../../cli/templates/basic-typescript/server && prettier --write src/module_bindings", "spacetime:generate": "spacetime generate --lang typescript --out-dir src/module_bindings --project-path spacetimedb", "spacetime:publish:local": "spacetime publish --project-path server --server local", "spacetime:publish": "spacetime publish --project-path server --server maincloud" diff --git a/crates/bindings-typescript/examples/basic-react/src/module_bindings/add_type.ts b/crates/bindings-typescript/examples/basic-react/src/module_bindings/add_type.ts new file mode 100644 index 00000000000..638f62cea39 --- /dev/null +++ b/crates/bindings-typescript/examples/basic-react/src/module_bindings/add_type.ts @@ -0,0 +1,15 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('Add', { + name: __t.string(), +}); diff --git a/crates/bindings-typescript/examples/basic-react/src/module_bindings/client_connected_type.ts b/crates/bindings-typescript/examples/basic-react/src/module_bindings/client_connected_type.ts new file mode 100644 index 00000000000..93bb49d17d2 --- /dev/null +++ b/crates/bindings-typescript/examples/basic-react/src/module_bindings/client_connected_type.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('ClientConnected', {}); diff --git a/crates/bindings-typescript/examples/basic-react/src/module_bindings/client_disconnected_type.ts b/crates/bindings-typescript/examples/basic-react/src/module_bindings/client_disconnected_type.ts new file mode 100644 index 00000000000..ce2ee54edde --- /dev/null +++ b/crates/bindings-typescript/examples/basic-react/src/module_bindings/client_disconnected_type.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('ClientDisconnected', {}); diff --git a/crates/bindings-typescript/examples/basic-react/src/module_bindings/index.ts b/crates/bindings-typescript/examples/basic-react/src/module_bindings/index.ts index 76310c73395..4e87d307ef4 100644 --- a/crates/bindings-typescript/examples/basic-react/src/module_bindings/index.ts +++ b/crates/bindings-typescript/examples/basic-react/src/module_bindings/index.ts @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.8.0 (commit 3f1ec77822a11345de517e72dbcefe06cc9277d4). +// This was generated using spacetimedb cli version 1.9.0 (commit 582c846c11c5fbe8b2447e8e4d0182a10439ec83). /* eslint-disable */ /* tslint:disable */ @@ -25,6 +25,7 @@ import { type ReducerEventContextInterface as __ReducerEventContextInterface, type RemoteModule as __RemoteModule, type SubscriptionEventContextInterface as __SubscriptionEventContextInterface, + type SubscriptionHandleImpl as __SubscriptionHandleImpl, } from 'spacetimedb'; // Import and reexport all reducer arg types @@ -44,9 +45,20 @@ import PersonRow from './person_table'; export { PersonRow }; // Import and reexport all types +import Add from './add_type'; +export { Add }; +import ClientConnected from './client_connected_type'; +export { ClientConnected }; +import ClientDisconnected from './client_disconnected_type'; +export { ClientDisconnected }; +import Init from './init_type'; +export { Init }; import Person from './person_type'; export { Person }; +import SayHello from './say_hello_type'; +export { SayHello }; +/** The schema information for all tables in this module. This is defined the same was as the tables would have been defined in the server. */ const tablesSchema = __schema( __table( { @@ -58,6 +70,7 @@ const tablesSchema = __schema( ) ); +/** The schema information for all reducers in this module. This is defined the same way as the reducers would have been defined in the server, except the body of the reducer is omitted in code generation. */ const reducersSchema = __reducers( __reducerSchema('init', Init), __reducerSchema('client_connected', ClientConnected), @@ -66,9 +79,10 @@ const reducersSchema = __reducers( __reducerSchema('say_hello', SayHello) ); +/** The remote SpacetimeDB module schema, both runtime and type information. */ const REMOTE_MODULE = { versionInfo: { - cliVersion: '1.8.0' as const, + cliVersion: '1.9.0' as const, }, tables: tablesSchema.schemaType.tables, reducers: reducersSchema.reducersType.reducers, @@ -77,27 +91,42 @@ const REMOTE_MODULE = { typeof reducersSchema.reducersType >; +/** The tables available in this remote SpacetimeDB module. */ export const tables = __convertToAccessorMap(tablesSchema.schemaType.tables); + +/** The reducers available in this remote SpacetimeDB module. */ export const reducers = __convertToAccessorMap( reducersSchema.reducersType.reducers ); +/** The context type returned in callbacks for all possible events. */ export type EventContext = __EventContextInterface; +/** The context type returned in callbacks for reducer events. */ export type ReducerEventContext = __ReducerEventContextInterface< typeof REMOTE_MODULE >; +/** The context type returned in callbacks for subscription events. */ export type SubscriptionEventContext = __SubscriptionEventContextInterface< typeof REMOTE_MODULE >; +/** The context type returned in callbacks for error events. */ export type ErrorContext = __ErrorContextInterface; +/** The subscription handle type to manage active subscriptions created from a {@link SubscriptionBuilder}. */ +export type SubscriptionHandle = __SubscriptionHandleImpl; +/** Builder class to configure a new subscription to the remote SpacetimeDB instance. */ export class SubscriptionBuilder extends __SubscriptionBuilderImpl< typeof REMOTE_MODULE > {} -export class DbConnectionBuilder extends __DbConnectionBuilder {} +/** Builder class to configure a new database connection to the remote SpacetimeDB instance. */ +export class DbConnectionBuilder extends __DbConnectionBuilder< + typeof REMOTE_MODULE +> {} +/** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */ export class DbConnection extends __DbConnectionImpl { + /** Creates a new {@link DbConnectionBuilder} to configure and connect to the remote SpacetimeDB instance. */ static builder = (): DbConnectionBuilder => { return new DbConnectionBuilder( REMOTE_MODULE, @@ -105,6 +134,8 @@ export class DbConnection extends __DbConnectionImpl { new DbConnection(config) ); }; + + /** Creates a new {@link SubscriptionBuilder} to configure a subscription to the remote SpacetimeDB instance. */ subscriptionBuilder = (): SubscriptionBuilder => { return new SubscriptionBuilder(this); }; diff --git a/crates/bindings-typescript/examples/basic-react/src/module_bindings/init_type.ts b/crates/bindings-typescript/examples/basic-react/src/module_bindings/init_type.ts new file mode 100644 index 00000000000..52ed691ed94 --- /dev/null +++ b/crates/bindings-typescript/examples/basic-react/src/module_bindings/init_type.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('Init', {}); diff --git a/crates/bindings-typescript/examples/basic-react/src/module_bindings/say_hello_type.ts b/crates/bindings-typescript/examples/basic-react/src/module_bindings/say_hello_type.ts new file mode 100644 index 00000000000..6293ca6bd09 --- /dev/null +++ b/crates/bindings-typescript/examples/basic-react/src/module_bindings/say_hello_type.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('SayHello', {}); diff --git a/crates/bindings-typescript/examples/empty/src/module_bindings/add_type.ts b/crates/bindings-typescript/examples/empty/src/module_bindings/add_type.ts new file mode 100644 index 00000000000..638f62cea39 --- /dev/null +++ b/crates/bindings-typescript/examples/empty/src/module_bindings/add_type.ts @@ -0,0 +1,15 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('Add', { + name: __t.string(), +}); diff --git a/crates/bindings-typescript/examples/empty/src/module_bindings/client_connected_type.ts b/crates/bindings-typescript/examples/empty/src/module_bindings/client_connected_type.ts new file mode 100644 index 00000000000..93bb49d17d2 --- /dev/null +++ b/crates/bindings-typescript/examples/empty/src/module_bindings/client_connected_type.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('ClientConnected', {}); diff --git a/crates/bindings-typescript/examples/empty/src/module_bindings/client_disconnected_type.ts b/crates/bindings-typescript/examples/empty/src/module_bindings/client_disconnected_type.ts new file mode 100644 index 00000000000..ce2ee54edde --- /dev/null +++ b/crates/bindings-typescript/examples/empty/src/module_bindings/client_disconnected_type.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('ClientDisconnected', {}); diff --git a/crates/bindings-typescript/examples/empty/src/module_bindings/index.ts b/crates/bindings-typescript/examples/empty/src/module_bindings/index.ts index 76310c73395..4e87d307ef4 100644 --- a/crates/bindings-typescript/examples/empty/src/module_bindings/index.ts +++ b/crates/bindings-typescript/examples/empty/src/module_bindings/index.ts @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.8.0 (commit 3f1ec77822a11345de517e72dbcefe06cc9277d4). +// This was generated using spacetimedb cli version 1.9.0 (commit 582c846c11c5fbe8b2447e8e4d0182a10439ec83). /* eslint-disable */ /* tslint:disable */ @@ -25,6 +25,7 @@ import { type ReducerEventContextInterface as __ReducerEventContextInterface, type RemoteModule as __RemoteModule, type SubscriptionEventContextInterface as __SubscriptionEventContextInterface, + type SubscriptionHandleImpl as __SubscriptionHandleImpl, } from 'spacetimedb'; // Import and reexport all reducer arg types @@ -44,9 +45,20 @@ import PersonRow from './person_table'; export { PersonRow }; // Import and reexport all types +import Add from './add_type'; +export { Add }; +import ClientConnected from './client_connected_type'; +export { ClientConnected }; +import ClientDisconnected from './client_disconnected_type'; +export { ClientDisconnected }; +import Init from './init_type'; +export { Init }; import Person from './person_type'; export { Person }; +import SayHello from './say_hello_type'; +export { SayHello }; +/** The schema information for all tables in this module. This is defined the same was as the tables would have been defined in the server. */ const tablesSchema = __schema( __table( { @@ -58,6 +70,7 @@ const tablesSchema = __schema( ) ); +/** The schema information for all reducers in this module. This is defined the same way as the reducers would have been defined in the server, except the body of the reducer is omitted in code generation. */ const reducersSchema = __reducers( __reducerSchema('init', Init), __reducerSchema('client_connected', ClientConnected), @@ -66,9 +79,10 @@ const reducersSchema = __reducers( __reducerSchema('say_hello', SayHello) ); +/** The remote SpacetimeDB module schema, both runtime and type information. */ const REMOTE_MODULE = { versionInfo: { - cliVersion: '1.8.0' as const, + cliVersion: '1.9.0' as const, }, tables: tablesSchema.schemaType.tables, reducers: reducersSchema.reducersType.reducers, @@ -77,27 +91,42 @@ const REMOTE_MODULE = { typeof reducersSchema.reducersType >; +/** The tables available in this remote SpacetimeDB module. */ export const tables = __convertToAccessorMap(tablesSchema.schemaType.tables); + +/** The reducers available in this remote SpacetimeDB module. */ export const reducers = __convertToAccessorMap( reducersSchema.reducersType.reducers ); +/** The context type returned in callbacks for all possible events. */ export type EventContext = __EventContextInterface; +/** The context type returned in callbacks for reducer events. */ export type ReducerEventContext = __ReducerEventContextInterface< typeof REMOTE_MODULE >; +/** The context type returned in callbacks for subscription events. */ export type SubscriptionEventContext = __SubscriptionEventContextInterface< typeof REMOTE_MODULE >; +/** The context type returned in callbacks for error events. */ export type ErrorContext = __ErrorContextInterface; +/** The subscription handle type to manage active subscriptions created from a {@link SubscriptionBuilder}. */ +export type SubscriptionHandle = __SubscriptionHandleImpl; +/** Builder class to configure a new subscription to the remote SpacetimeDB instance. */ export class SubscriptionBuilder extends __SubscriptionBuilderImpl< typeof REMOTE_MODULE > {} -export class DbConnectionBuilder extends __DbConnectionBuilder {} +/** Builder class to configure a new database connection to the remote SpacetimeDB instance. */ +export class DbConnectionBuilder extends __DbConnectionBuilder< + typeof REMOTE_MODULE +> {} +/** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */ export class DbConnection extends __DbConnectionImpl { + /** Creates a new {@link DbConnectionBuilder} to configure and connect to the remote SpacetimeDB instance. */ static builder = (): DbConnectionBuilder => { return new DbConnectionBuilder( REMOTE_MODULE, @@ -105,6 +134,8 @@ export class DbConnection extends __DbConnectionImpl { new DbConnection(config) ); }; + + /** Creates a new {@link SubscriptionBuilder} to configure a subscription to the remote SpacetimeDB instance. */ subscriptionBuilder = (): SubscriptionBuilder => { return new SubscriptionBuilder(this); }; diff --git a/crates/bindings-typescript/examples/empty/src/module_bindings/init_type.ts b/crates/bindings-typescript/examples/empty/src/module_bindings/init_type.ts new file mode 100644 index 00000000000..52ed691ed94 --- /dev/null +++ b/crates/bindings-typescript/examples/empty/src/module_bindings/init_type.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('Init', {}); diff --git a/crates/bindings-typescript/examples/empty/src/module_bindings/say_hello_type.ts b/crates/bindings-typescript/examples/empty/src/module_bindings/say_hello_type.ts new file mode 100644 index 00000000000..6293ca6bd09 --- /dev/null +++ b/crates/bindings-typescript/examples/empty/src/module_bindings/say_hello_type.ts @@ -0,0 +1,13 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +/* eslint-disable */ +/* tslint:disable */ +import { + TypeBuilder as __TypeBuilder, + t as __t, + type AlgebraicTypeType as __AlgebraicTypeType, + type Infer as __Infer, +} from 'spacetimedb'; + +export default __t.object('SayHello', {}); diff --git a/crates/bindings-typescript/examples/quickstart-chat/src/module_bindings/index.ts b/crates/bindings-typescript/examples/quickstart-chat/src/module_bindings/index.ts index 1f2a8a8b9c5..a6eabf3d121 100644 --- a/crates/bindings-typescript/examples/quickstart-chat/src/module_bindings/index.ts +++ b/crates/bindings-typescript/examples/quickstart-chat/src/module_bindings/index.ts @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.9.0 (commit 2417e05ccad32aed3d7c94821e0522e00c24d1ef). +// This was generated using spacetimedb cli version 1.9.0 (commit 582c846c11c5fbe8b2447e8e4d0182a10439ec83). /* eslint-disable */ /* tslint:disable */ @@ -25,6 +25,7 @@ import { type ReducerEventContextInterface as __ReducerEventContextInterface, type RemoteModule as __RemoteModule, type SubscriptionEventContextInterface as __SubscriptionEventContextInterface, + type SubscriptionHandleImpl as __SubscriptionHandleImpl, } from 'spacetimedb'; // Import and reexport all reducer arg types @@ -49,6 +50,7 @@ export { Message }; import User from './user_type'; export { User }; +/** The schema information for all tables in this module. This is defined the same was as the tables would have been defined in the server. */ const tablesSchema = __schema( __table( { @@ -76,11 +78,13 @@ const tablesSchema = __schema( ) ); +/** The schema information for all reducers in this module. This is defined the same way as the reducers would have been defined in the server, except the body of the reducer is omitted in code generation. */ const reducersSchema = __reducers( __reducerSchema('send_message', SendMessage), __reducerSchema('set_name', SetName) ); +/** The remote SpacetimeDB module schema, both runtime and type information. */ const REMOTE_MODULE = { versionInfo: { cliVersion: '1.9.0' as const, @@ -92,27 +96,42 @@ const REMOTE_MODULE = { typeof reducersSchema.reducersType >; +/** The tables available in this remote SpacetimeDB module. */ export const tables = __convertToAccessorMap(tablesSchema.schemaType.tables); + +/** The reducers available in this remote SpacetimeDB module. */ export const reducers = __convertToAccessorMap( reducersSchema.reducersType.reducers ); +/** The context type returned in callbacks for all possible events. */ export type EventContext = __EventContextInterface; +/** The context type returned in callbacks for reducer events. */ export type ReducerEventContext = __ReducerEventContextInterface< typeof REMOTE_MODULE >; +/** The context type returned in callbacks for subscription events. */ export type SubscriptionEventContext = __SubscriptionEventContextInterface< typeof REMOTE_MODULE >; +/** The context type returned in callbacks for error events. */ export type ErrorContext = __ErrorContextInterface; +/** The subscription handle type to manage active subscriptions created from a {@link SubscriptionBuilder}. */ +export type SubscriptionHandle = __SubscriptionHandleImpl; +/** Builder class to configure a new subscription to the remote SpacetimeDB instance. */ export class SubscriptionBuilder extends __SubscriptionBuilderImpl< typeof REMOTE_MODULE > {} -export class DbConnectionBuilder extends __DbConnectionBuilder {} +/** Builder class to configure a new database connection to the remote SpacetimeDB instance. */ +export class DbConnectionBuilder extends __DbConnectionBuilder< + typeof REMOTE_MODULE +> {} +/** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */ export class DbConnection extends __DbConnectionImpl { + /** Creates a new {@link DbConnectionBuilder} to configure and connect to the remote SpacetimeDB instance. */ static builder = (): DbConnectionBuilder => { return new DbConnectionBuilder( REMOTE_MODULE, @@ -120,6 +139,8 @@ export class DbConnection extends __DbConnectionImpl { new DbConnection(config) ); }; + + /** Creates a new {@link SubscriptionBuilder} to configure a subscription to the remote SpacetimeDB instance. */ subscriptionBuilder = (): SubscriptionBuilder => { return new SubscriptionBuilder(this); }; diff --git a/crates/bindings-typescript/src/lib/table.ts b/crates/bindings-typescript/src/lib/table.ts index 803f1585851..3fb83f63432 100644 --- a/crates/bindings-typescript/src/lib/table.ts +++ b/crates/bindings-typescript/src/lib/table.ts @@ -116,6 +116,7 @@ type NormalizeIndexColumns< * - `name`: The name of the table. * - `public`: Whether the table is publicly accessible. Defaults to `false`. * - `indexes`: An array of index configurations for the table. + * - `constraints`: An array of constraint configurations for the table. * - `scheduled`: The name of the reducer to be executed based on the scheduled rows in this table. */ export type TableOpts = { @@ -197,7 +198,7 @@ export interface TableMethods * const playerTable = table( * { name: 'player', public: true }, * t.object({ - * id: t.u32().primary_key(), + * id: t.u32().primaryKey(), * name: t.string().index('btree') * }) * ); diff --git a/crates/bindings-typescript/src/lib/type_util.ts b/crates/bindings-typescript/src/lib/type_util.ts index 35efb5740d8..915bcd8c5a7 100644 --- a/crates/bindings-typescript/src/lib/type_util.ts +++ b/crates/bindings-typescript/src/lib/type_util.ts @@ -61,6 +61,16 @@ type CamelCaseImpl = S extends `${infer Head}_${infer Tail}` */ export type CamelCase = Uncapitalize>; +/** Type safe conversion from "some_identifier-name" to "some_identifier_name" + * - No spaces; allowed separators: "_" and "-" + * - Normalizes the *first* character to lowercase (e.g. "User_Name" -> "user_name") + */ +export type SnakeCase = S extends `${infer Head}${infer Tail}` + ? Tail extends Uncapitalize + ? `${Lowercase}${SnakeCase}` + : `${Lowercase}_${SnakeCase}` + : Lowercase; + type PascalCaseImpl = S extends `${infer Head}_${infer Tail}` ? `${Capitalize}${PascalCaseImpl}` : S extends `${infer Head}-${infer Tail}` diff --git a/crates/bindings-typescript/src/lib/util.ts b/crates/bindings-typescript/src/lib/util.ts index 47974fff6d5..09fff1a676d 100644 --- a/crates/bindings-typescript/src/lib/util.ts +++ b/crates/bindings-typescript/src/lib/util.ts @@ -1,6 +1,6 @@ import BinaryReader from './binary_reader'; import BinaryWriter from './binary_writer'; -import type { CamelCase } from './type_util'; +import type { CamelCase, SnakeCase } from './type_util'; /** * Converts a string to PascalCase (UpperCamelCase). @@ -116,6 +116,17 @@ export function toCamelCase(str: T): CamelCase { .replace(/_([a-zA-Z0-9])/g, (_, c) => c.toUpperCase()) as CamelCase; } +/** Type safe conversion from a string like "some_Identifier-name" to "some_identifier_name". + * @param str The string to convert + * @returns The converted string + */ +export function toSnakeCase(str: T): SnakeCase { + return str + .replace(/([A-Z])/g, '_$1') // insert underscores before capitals + .replace(/[-\s]+/g, '_') // replace spaces and dashes with underscores + .toLowerCase() as SnakeCase; +} + import type { AlgebraicType } from './algebraic_type'; import type Typespace from './autogen/typespace_type'; import type { Infer } from './type_builders'; diff --git a/crates/bindings-typescript/src/sdk/client_api/index.ts b/crates/bindings-typescript/src/sdk/client_api/index.ts index 44df46a6154..dc11b511ab5 100644 --- a/crates/bindings-typescript/src/sdk/client_api/index.ts +++ b/crates/bindings-typescript/src/sdk/client_api/index.ts @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.8.0 (commit 3f1ec77822a11345de517e72dbcefe06cc9277d4). +// This was generated using spacetimedb cli version 1.9.0 (commit 582c846c11c5fbe8b2447e8e4d0182a10439ec83). /* eslint-disable */ /* tslint:disable */ @@ -25,6 +25,7 @@ import { type ReducerEventContextInterface as __ReducerEventContextInterface, type RemoteModule as __RemoteModule, type SubscriptionEventContextInterface as __SubscriptionEventContextInterface, + type SubscriptionHandleImpl as __SubscriptionHandleImpl, } from '../../index'; // Import and reexport all reducer arg types @@ -101,13 +102,16 @@ export { UnsubscribeMultiApplied }; import UpdateStatus from './update_status_type'; export { UpdateStatus }; +/** The schema information for all tables in this module. This is defined the same was as the tables would have been defined in the server. */ const tablesSchema = __schema(); +/** The schema information for all reducers in this module. This is defined the same way as the reducers would have been defined in the server, except the body of the reducer is omitted in code generation. */ const reducersSchema = __reducers(); +/** The remote SpacetimeDB module schema, both runtime and type information. */ const REMOTE_MODULE = { versionInfo: { - cliVersion: '1.8.0' as const, + cliVersion: '1.9.0' as const, }, tables: tablesSchema.schemaType.tables, reducers: reducersSchema.reducersType.reducers, @@ -116,27 +120,42 @@ const REMOTE_MODULE = { typeof reducersSchema.reducersType >; +/** The tables available in this remote SpacetimeDB module. */ export const tables = __convertToAccessorMap(tablesSchema.schemaType.tables); + +/** The reducers available in this remote SpacetimeDB module. */ export const reducers = __convertToAccessorMap( reducersSchema.reducersType.reducers ); +/** The context type returned in callbacks for all possible events. */ export type EventContext = __EventContextInterface; +/** The context type returned in callbacks for reducer events. */ export type ReducerEventContext = __ReducerEventContextInterface< typeof REMOTE_MODULE >; +/** The context type returned in callbacks for subscription events. */ export type SubscriptionEventContext = __SubscriptionEventContextInterface< typeof REMOTE_MODULE >; +/** The context type returned in callbacks for error events. */ export type ErrorContext = __ErrorContextInterface; +/** The subscription handle type to manage active subscriptions created from a {@link SubscriptionBuilder}. */ +export type SubscriptionHandle = __SubscriptionHandleImpl; +/** Builder class to configure a new subscription to the remote SpacetimeDB instance. */ export class SubscriptionBuilder extends __SubscriptionBuilderImpl< typeof REMOTE_MODULE > {} -export class DbConnectionBuilder extends __DbConnectionBuilder {} +/** Builder class to configure a new database connection to the remote SpacetimeDB instance. */ +export class DbConnectionBuilder extends __DbConnectionBuilder< + typeof REMOTE_MODULE +> {} +/** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */ export class DbConnection extends __DbConnectionImpl { + /** Creates a new {@link DbConnectionBuilder} to configure and connect to the remote SpacetimeDB instance. */ static builder = (): DbConnectionBuilder => { return new DbConnectionBuilder( REMOTE_MODULE, @@ -144,6 +163,8 @@ export class DbConnection extends __DbConnectionImpl { new DbConnection(config) ); }; + + /** Creates a new {@link SubscriptionBuilder} to configure a subscription to the remote SpacetimeDB instance. */ subscriptionBuilder = (): SubscriptionBuilder => { return new SubscriptionBuilder(this); }; diff --git a/crates/bindings-typescript/src/sdk/db_connection_impl.ts b/crates/bindings-typescript/src/sdk/db_connection_impl.ts index b04d6fdfabf..3095f6ce92d 100644 --- a/crates/bindings-typescript/src/sdk/db_connection_impl.ts +++ b/crates/bindings-typescript/src/sdk/db_connection_impl.ts @@ -59,6 +59,7 @@ import { toCamelCase, toPascalCase } from '../lib/util.ts'; export { DbConnectionBuilder, SubscriptionBuilderImpl, + SubscriptionHandleImpl, type TableCache, type Event, }; diff --git a/crates/bindings-typescript/test-app/src/module_bindings/index.ts b/crates/bindings-typescript/test-app/src/module_bindings/index.ts index 6937e805325..73eeb549b92 100644 --- a/crates/bindings-typescript/test-app/src/module_bindings/index.ts +++ b/crates/bindings-typescript/test-app/src/module_bindings/index.ts @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.8.0 (commit 3f1ec77822a11345de517e72dbcefe06cc9277d4). +// This was generated using spacetimedb cli version 1.9.0 (commit 582c846c11c5fbe8b2447e8e4d0182a10439ec83). /* eslint-disable */ /* tslint:disable */ @@ -25,6 +25,7 @@ import { type ReducerEventContextInterface as __ReducerEventContextInterface, type RemoteModule as __RemoteModule, type SubscriptionEventContextInterface as __SubscriptionEventContextInterface, + type SubscriptionHandleImpl as __SubscriptionHandleImpl, } from '../../../src/index'; // Import and reexport all reducer arg types @@ -49,6 +50,7 @@ export { UnindexedPlayer }; import User from './user_type'; export { User }; +/** The schema information for all tables in this module. This is defined the same was as the tables would have been defined in the server. */ const tablesSchema = __schema( __table( { @@ -92,13 +94,15 @@ const tablesSchema = __schema( ) ); +/** The schema information for all reducers in this module. This is defined the same way as the reducers would have been defined in the server, except the body of the reducer is omitted in code generation. */ const reducersSchema = __reducers( __reducerSchema('create_player', CreatePlayer) ); +/** The remote SpacetimeDB module schema, both runtime and type information. */ const REMOTE_MODULE = { versionInfo: { - cliVersion: '1.8.0' as const, + cliVersion: '1.9.0' as const, }, tables: tablesSchema.schemaType.tables, reducers: reducersSchema.reducersType.reducers, @@ -107,27 +111,42 @@ const REMOTE_MODULE = { typeof reducersSchema.reducersType >; +/** The tables available in this remote SpacetimeDB module. */ export const tables = __convertToAccessorMap(tablesSchema.schemaType.tables); + +/** The reducers available in this remote SpacetimeDB module. */ export const reducers = __convertToAccessorMap( reducersSchema.reducersType.reducers ); +/** The context type returned in callbacks for all possible events. */ export type EventContext = __EventContextInterface; +/** The context type returned in callbacks for reducer events. */ export type ReducerEventContext = __ReducerEventContextInterface< typeof REMOTE_MODULE >; +/** The context type returned in callbacks for subscription events. */ export type SubscriptionEventContext = __SubscriptionEventContextInterface< typeof REMOTE_MODULE >; +/** The context type returned in callbacks for error events. */ export type ErrorContext = __ErrorContextInterface; +/** The subscription handle type to manage active subscriptions created from a {@link SubscriptionBuilder}. */ +export type SubscriptionHandle = __SubscriptionHandleImpl; +/** Builder class to configure a new subscription to the remote SpacetimeDB instance. */ export class SubscriptionBuilder extends __SubscriptionBuilderImpl< typeof REMOTE_MODULE > {} -export class DbConnectionBuilder extends __DbConnectionBuilder {} +/** Builder class to configure a new database connection to the remote SpacetimeDB instance. */ +export class DbConnectionBuilder extends __DbConnectionBuilder< + typeof REMOTE_MODULE +> {} +/** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */ export class DbConnection extends __DbConnectionImpl { + /** Creates a new {@link DbConnectionBuilder} to configure and connect to the remote SpacetimeDB instance. */ static builder = (): DbConnectionBuilder => { return new DbConnectionBuilder( REMOTE_MODULE, @@ -135,6 +154,8 @@ export class DbConnection extends __DbConnectionImpl { new DbConnection(config) ); }; + + /** Creates a new {@link SubscriptionBuilder} to configure a subscription to the remote SpacetimeDB instance. */ subscriptionBuilder = (): SubscriptionBuilder => { return new SubscriptionBuilder(this); }; diff --git a/crates/cli/templates/basic-typescript/server/package.json b/crates/cli/templates/basic-typescript/server/package.json index 47be347a920..06410a60af6 100644 --- a/crates/cli/templates/basic-typescript/server/package.json +++ b/crates/cli/templates/basic-typescript/server/package.json @@ -10,6 +10,6 @@ "author": "", "license": "ISC", "dependencies": { - "spacetimedb": "1.6.*" + "spacetimedb": "1.*" } } \ No newline at end of file diff --git a/crates/cli/templates/basic-typescript/server/pnpm-lock.yaml b/crates/cli/templates/basic-typescript/server/pnpm-lock.yaml new file mode 100644 index 00000000000..b8b7739cda8 --- /dev/null +++ b/crates/cli/templates/basic-typescript/server/pnpm-lock.yaml @@ -0,0 +1,51 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + spacetimedb: + specifier: 1.* + version: 1.9.0 + +packages: + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + fast-text-encoding@1.0.6: + resolution: {integrity: sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==} + + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + engines: {node: '>=14'} + hasBin: true + + spacetimedb@1.9.0: + resolution: {integrity: sha512-cl/HeO50A1z6JgUZpA7pJcTspBE4IfH1SJJU8f1DpZ4hYHvQesbbYFHPPIC181s8zexdVAj5NnvFOPwQnSrcXg==} + peerDependencies: + react: ^18.0.0 || ^19.0.0-0 || ^19.0.0 + undici: ^6.19.2 + peerDependenciesMeta: + react: + optional: true + undici: + optional: true + +snapshots: + + base64-js@1.5.1: {} + + fast-text-encoding@1.0.6: {} + + prettier@3.6.2: {} + + spacetimedb@1.9.0: + dependencies: + base64-js: 1.5.1 + fast-text-encoding: 1.0.6 + prettier: 3.6.2 diff --git a/crates/codegen/src/typescript.rs b/crates/codegen/src/typescript.rs index 157939c08f1..18dc611e8ba 100644 --- a/crates/codegen/src/typescript.rs +++ b/crates/codegen/src/typescript.rs @@ -182,8 +182,7 @@ impl Lang for TypeScript { print_file_header(out, true, false); - out.newline(); - + writeln!(out); writeln!(out, "// Import and reexport all reducer arg types"); for reducer in iter_reducers(module) { let reducer_name = &reducer.name; @@ -213,9 +212,8 @@ impl Lang for TypeScript { writeln!(out, "export {{ {type_name} }};"); } - out.newline(); - writeln!(out); + writeln!(out, "/** The schema information for all tables in this module. This is defined the same was as the tables would have been defined in the server. */"); writeln!(out, "const tablesSchema = __schema("); out.indent(1); for table in iter_tables(module) { @@ -247,7 +245,7 @@ impl Lang for TypeScript { writeln!(out, ");"); writeln!(out); - + writeln!(out, "/** The schema information for all reducers in this module. This is defined the same way as the reducers would have been defined in the server, except the body of the reducer is omitted in code generation. */"); writeln!(out, "const reducersSchema = __reducers("); out.indent(1); for reducer in iter_reducers(module) { @@ -263,7 +261,7 @@ impl Lang for TypeScript { writeln!(out, ");"); writeln!(out); - + writeln!(out, "/** The remote SpacetimeDB module schema, both runtime and type information. */"); writeln!(out, "const REMOTE_MODULE = {{"); out.indent(1); writeln!(out, "versionInfo: {{"); @@ -283,60 +281,75 @@ impl Lang for TypeScript { out.dedent(1); writeln!(out); + writeln!( + out, + "/** The tables available in this remote SpacetimeDB module. */" + ); writeln!( out, "export const tables = __convertToAccessorMap(tablesSchema.schemaType.tables);" ); + writeln!(out); + writeln!( + out, + "/** The reducers available in this remote SpacetimeDB module. */" + ); writeln!( out, "export const reducers = __convertToAccessorMap(reducersSchema.reducersType.reducers);" ); - writeln!(out); - - out.newline(); // Write type aliases for EventContext, ReducerEventContext, SubscriptionEventContext, ErrorContext + writeln!(out); + writeln!(out, "/** The context type returned in callbacks for all possible events. */"); writeln!( out, "export type EventContext = __EventContextInterface;" ); + + writeln!(out, "/** The context type returned in callbacks for reducer events. */"); writeln!( out, "export type ReducerEventContext = __ReducerEventContextInterface;" ); + + writeln!(out, "/** The context type returned in callbacks for subscription events. */"); writeln!( out, "export type SubscriptionEventContext = __SubscriptionEventContextInterface;" ); + + writeln!(out, "/** The context type returned in callbacks for error events. */"); writeln!( out, "export type ErrorContext = __ErrorContextInterface;" ); - writeln!(out); + writeln!(out, "/** The subscription handle type to manage active subscriptions created from a {{@link SubscriptionBuilder}}. */"); + writeln!( + out, + "export type SubscriptionHandle = __SubscriptionHandleImpl;" + ); + writeln!(out); + writeln!(out, "/** Builder class to configure a new subscription to the remote SpacetimeDB instance. */"); writeln!( out, - "export class SubscriptionBuilder extends __SubscriptionBuilderImpl<" + "export class SubscriptionBuilder extends __SubscriptionBuilderImpl {{}}" ); - out.indent(1); - writeln!(out, "typeof REMOTE_MODULE"); - out.dedent(1); - writeln!(out, "> {{}}"); writeln!(out); - writeln!(out, "export class DbConnectionBuilder extends __DbConnectionBuilder<"); - out.indent(1); - writeln!(out, "DbConnection"); - out.dedent(1); - writeln!(out, "> {{}}"); + writeln!(out, "/** Builder class to configure a new database connection to the remote SpacetimeDB instance. */"); + writeln!(out, "export class DbConnectionBuilder extends __DbConnectionBuilder {{}}"); writeln!(out); + writeln!(out, "/** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */"); writeln!( out, "export class DbConnection extends __DbConnectionImpl {{" ); out.indent(1); + writeln!(out, "/** Creates a new {{@link DbConnectionBuilder}} to configure and connect to the remote SpacetimeDB instance. */"); writeln!(out, "static builder = (): DbConnectionBuilder => {{"); out.indent(1); writeln!( @@ -345,6 +358,9 @@ impl Lang for TypeScript { ); out.dedent(1); writeln!(out, "}};"); + + writeln!(out); + writeln!(out, "/** Creates a new {{@link SubscriptionBuilder}} to configure a subscription to the remote SpacetimeDB instance. */"); writeln!(out, "subscriptionBuilder = (): SubscriptionBuilder => {{"); out.indent(1); writeln!(out, "return new SubscriptionBuilder(this);"); @@ -373,6 +389,7 @@ fn print_index_imports(out: &mut Indenter) { "type EventContextInterface as __EventContextInterface", "type ReducerEventContextInterface as __ReducerEventContextInterface", "type SubscriptionEventContextInterface as __SubscriptionEventContextInterface", + "type SubscriptionHandleImpl as __SubscriptionHandleImpl", "type ErrorContextInterface as __ErrorContextInterface", "type RemoteModule as __RemoteModule", "SubscriptionBuilderImpl as __SubscriptionBuilderImpl", @@ -540,6 +557,7 @@ fn write_table_opts<'a>( .flat_map(|cs| cs.iter()) // Iterator over the ColIds inside the set .map(|col_id| { let (field_name, _field_type) = &product_def.elements[col_id.idx()]; + let field_name = field_name.deref().to_case(Case::Camel); format!("'{}'", field_name) }) .collect(); From 149e7b74211f86b0e20da206dd9826dc12585de2 Mon Sep 17 00:00:00 2001 From: Tyler Cloutier Date: Sun, 23 Nov 2025 23:37:07 -0500 Subject: [PATCH 02/11] cargo fmt --- crates/codegen/src/typescript.rs | 40 +++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/crates/codegen/src/typescript.rs b/crates/codegen/src/typescript.rs index 18dc611e8ba..d3e37758529 100644 --- a/crates/codegen/src/typescript.rs +++ b/crates/codegen/src/typescript.rs @@ -261,7 +261,10 @@ impl Lang for TypeScript { writeln!(out, ");"); writeln!(out); - writeln!(out, "/** The remote SpacetimeDB module schema, both runtime and type information. */"); + writeln!( + out, + "/** The remote SpacetimeDB module schema, both runtime and type information. */" + ); writeln!(out, "const REMOTE_MODULE = {{"); out.indent(1); writeln!(out, "versionInfo: {{"); @@ -281,19 +284,13 @@ impl Lang for TypeScript { out.dedent(1); writeln!(out); - writeln!( - out, - "/** The tables available in this remote SpacetimeDB module. */" - ); + writeln!(out, "/** The tables available in this remote SpacetimeDB module. */"); writeln!( out, "export const tables = __convertToAccessorMap(tablesSchema.schemaType.tables);" ); writeln!(out); - writeln!( - out, - "/** The reducers available in this remote SpacetimeDB module. */" - ); + writeln!(out, "/** The reducers available in this remote SpacetimeDB module. */"); writeln!( out, "export const reducers = __convertToAccessorMap(reducersSchema.reducersType.reducers);" @@ -301,7 +298,10 @@ impl Lang for TypeScript { // Write type aliases for EventContext, ReducerEventContext, SubscriptionEventContext, ErrorContext writeln!(out); - writeln!(out, "/** The context type returned in callbacks for all possible events. */"); + writeln!( + out, + "/** The context type returned in callbacks for all possible events. */" + ); writeln!( out, "export type EventContext = __EventContextInterface;" @@ -313,7 +313,10 @@ impl Lang for TypeScript { "export type ReducerEventContext = __ReducerEventContextInterface;" ); - writeln!(out, "/** The context type returned in callbacks for subscription events. */"); + writeln!( + out, + "/** The context type returned in callbacks for subscription events. */" + ); writeln!( out, "export type SubscriptionEventContext = __SubscriptionEventContextInterface;" @@ -332,15 +335,24 @@ impl Lang for TypeScript { ); writeln!(out); - writeln!(out, "/** Builder class to configure a new subscription to the remote SpacetimeDB instance. */"); + writeln!( + out, + "/** Builder class to configure a new subscription to the remote SpacetimeDB instance. */" + ); writeln!( out, "export class SubscriptionBuilder extends __SubscriptionBuilderImpl {{}}" ); writeln!(out); - writeln!(out, "/** Builder class to configure a new database connection to the remote SpacetimeDB instance. */"); - writeln!(out, "export class DbConnectionBuilder extends __DbConnectionBuilder {{}}"); + writeln!( + out, + "/** Builder class to configure a new database connection to the remote SpacetimeDB instance. */" + ); + writeln!( + out, + "export class DbConnectionBuilder extends __DbConnectionBuilder {{}}" + ); writeln!(out); writeln!(out, "/** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */"); From 6a1539ccc9d8357f275fdabdab11819e6f163a57 Mon Sep 17 00:00:00 2001 From: Tyler Cloutier Date: Tue, 25 Nov 2025 12:41:41 -0500 Subject: [PATCH 03/11] Fixed reducer callback bug, fixed table name code gen issue --- crates/bindings-typescript/src/sdk/db_connection_impl.ts | 6 +----- crates/codegen/src/typescript.rs | 8 ++++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/crates/bindings-typescript/src/sdk/db_connection_impl.ts b/crates/bindings-typescript/src/sdk/db_connection_impl.ts index 3095f6ce92d..0ad145fabc0 100644 --- a/crates/bindings-typescript/src/sdk/db_connection_impl.ts +++ b/crates/bindings-typescript/src/sdk/db_connection_impl.ts @@ -761,14 +761,10 @@ export class DbConnectionImpl eventContext ); - const argsArray: any[] = []; - reducer.paramsType.elements.forEach(element => { - argsArray.push(reducerArgs[element.name!]); - }); this.#reducerEmitter.emit( reducerInfo.reducerName, reducerEventContext, - ...argsArray + reducerArgs ); for (const callback of callbacks) { callback.cb(); diff --git a/crates/codegen/src/typescript.rs b/crates/codegen/src/typescript.rs index d3e37758529..fd4dce96d22 100644 --- a/crates/codegen/src/typescript.rs +++ b/crates/codegen/src/typescript.rs @@ -218,7 +218,7 @@ impl Lang for TypeScript { out.indent(1); for table in iter_tables(module) { let type_ref = table.product_type_ref; - let row_type_name = type_ref_name(module, type_ref); + let table_name_pascalcase = table.name.deref().to_case(Case::Pascal); writeln!(out, "__table({{"); out.indent(1); write_table_opts( @@ -230,16 +230,16 @@ impl Lang for TypeScript { iter_constraints(table), ); out.dedent(1); - writeln!(out, "}}, {}Row),", row_type_name); + writeln!(out, "}}, {}Row),", table_name_pascalcase); } for view in iter_views(module) { let type_ref = view.product_type_ref; - let row_type_name = type_ref_name(module, type_ref); + let view_name_pascalcase = view.name.deref().to_case(Case::Pascal); writeln!(out, "__table({{"); out.indent(1); write_table_opts(module, out, type_ref, &view.name, iter::empty(), iter::empty()); out.dedent(1); - writeln!(out, "}}, {}Row),", row_type_name); + writeln!(out, "}}, {}Row),", view_name_pascalcase); } out.dedent(1); writeln!(out, ");"); From e9e1d3ac9c421b73364f5bf11c970f2846e38883 Mon Sep 17 00:00:00 2001 From: Tyler Cloutier Date: Tue, 25 Nov 2025 18:21:07 -0500 Subject: [PATCH 04/11] Make it possible to add ScheduleAt in regular objects, not just rows. --- crates/bindings-typescript/src/lib/table.ts | 14 ++++- .../src/lib/type_builders.ts | 51 +++++++++++++++---- 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/crates/bindings-typescript/src/lib/table.ts b/crates/bindings-typescript/src/lib/table.ts index 3fb83f63432..bab56b48391 100644 --- a/crates/bindings-typescript/src/lib/table.ts +++ b/crates/bindings-typescript/src/lib/table.ts @@ -289,9 +289,19 @@ export function table>( }); } - if (meta.isScheduleAt) { - scheduleAtCol = colIds.get(name)!; + // If this column is shaped like ScheduleAtAlgebraicType, mark it as the schedule‑at column + if (scheduled) { + const algebraicType = builder.typeBuilder.algebraicType; + if ( + algebraicType.tag === 'Sum' && + algebraicType.value.variants.length === 2 && + algebraicType.value.variants[0].name === 'Interval' && + algebraicType.value.variants[1].name === 'Time' + ) { + scheduleAtCol = colIds.get(name)!; + } } + } // convert explicit multi‑column indexes coming from options.indexes diff --git a/crates/bindings-typescript/src/lib/type_builders.ts b/crates/bindings-typescript/src/lib/type_builders.ts index 77246981264..37c868d0101 100644 --- a/crates/bindings-typescript/src/lib/type_builders.ts +++ b/crates/bindings-typescript/src/lib/type_builders.ts @@ -4,7 +4,7 @@ import type BinaryWriter from './binary_writer'; import { ConnectionId, type ConnectionIdAlgebraicType } from './connection_id'; import { Identity, type IdentityAlgebraicType } from './identity'; import { Option, type OptionAlgebraicType } from './option'; -import ScheduleAt from './schedule_at'; +import ScheduleAt, { type ScheduleAtAlgebraicType } from './schedule_at'; import type { CoerceRow } from './table'; import { TimeDuration, type TimeDurationAlgebraicType } from './time_duration'; import { Timestamp, type TimestampAlgebraicType } from './timestamp'; @@ -1487,6 +1487,26 @@ export const SimpleSumBuilder: { export type SimpleSumBuilder = SimpleSumBuilderImpl & SumBuilderVariantConstructors; +export class ScheduleAtBuilder + extends TypeBuilder + implements + Defaultable +{ + constructor() { + super(ScheduleAt.getAlgebraicType()); + } + default( + value: ScheduleAt + ): ScheduleAtColumnBuilder< + SetField + > { + return new ScheduleAtColumnBuilder( + this, + set(defaultMetadata, { defaultValue: value }) + ); + } +} + export class IdentityBuilder extends TypeBuilder implements @@ -1748,7 +1768,6 @@ export type ColumnMetadata = { isPrimaryKey?: true; isUnique?: true; isAutoIncrement?: true; - isScheduleAt?: true; indexType?: IndexTypes; defaultValue?: Type; }; @@ -2727,6 +2746,23 @@ export class SimpleSumColumnBuilder< } } +export class ScheduleAtColumnBuilder< + M extends ColumnMetadata = DefaultMetadata, + > + extends ColumnBuilder + implements + Defaultable +{ + default( + value: ScheduleAt + ): ScheduleAtColumnBuilder> { + return new ScheduleAtColumnBuilder( + this.typeBuilder, + set(this.columnMetadata, { defaultValue: value }) + ); + } +} + export class IdentityColumnBuilder< M extends ColumnMetadata = DefaultMetadata, > @@ -3241,15 +3277,8 @@ export const t = { * This is a special helper function for conveniently creating {@link ScheduleAt} type columns. * @returns A new ColumnBuilder instance with the {@link ScheduleAt} type. */ - scheduleAt: (): ColumnBuilder< - ScheduleAt, - ReturnType, - Omit, 'isScheduleAt'> & { isScheduleAt: true } - > => { - return new ColumnBuilder( - new TypeBuilder(ScheduleAt.getAlgebraicType()), - set(defaultMetadata, { isScheduleAt: true }) - ); + scheduleAt: (): ScheduleAtBuilder => { + return new ScheduleAtBuilder(); }, /** From b2c3ff8b6bc3eb12fecffeb99621254421f47084 Mon Sep 17 00:00:00 2001 From: Tyler Cloutier Date: Tue, 25 Nov 2025 18:27:18 -0500 Subject: [PATCH 05/11] Regenerated and formatted --- .../examples/basic-react/src/module_bindings/index.ts | 2 +- .../examples/empty/src/module_bindings/index.ts | 2 +- .../examples/quickstart-chat/src/module_bindings/index.ts | 2 +- crates/bindings-typescript/src/lib/table.ts | 1 - crates/bindings-typescript/src/lib/type_builders.ts | 6 ++---- crates/bindings-typescript/src/sdk/client_api/index.ts | 2 +- .../test-app/src/module_bindings/index.ts | 2 +- 7 files changed, 7 insertions(+), 10 deletions(-) diff --git a/crates/bindings-typescript/examples/basic-react/src/module_bindings/index.ts b/crates/bindings-typescript/examples/basic-react/src/module_bindings/index.ts index 4e87d307ef4..556c584b344 100644 --- a/crates/bindings-typescript/examples/basic-react/src/module_bindings/index.ts +++ b/crates/bindings-typescript/examples/basic-react/src/module_bindings/index.ts @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.9.0 (commit 582c846c11c5fbe8b2447e8e4d0182a10439ec83). +// This was generated using spacetimedb cli version 1.9.0 (commit e9e1d3ac9c421b73364f5bf11c970f2846e38883). /* eslint-disable */ /* tslint:disable */ diff --git a/crates/bindings-typescript/examples/empty/src/module_bindings/index.ts b/crates/bindings-typescript/examples/empty/src/module_bindings/index.ts index 4e87d307ef4..556c584b344 100644 --- a/crates/bindings-typescript/examples/empty/src/module_bindings/index.ts +++ b/crates/bindings-typescript/examples/empty/src/module_bindings/index.ts @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.9.0 (commit 582c846c11c5fbe8b2447e8e4d0182a10439ec83). +// This was generated using spacetimedb cli version 1.9.0 (commit e9e1d3ac9c421b73364f5bf11c970f2846e38883). /* eslint-disable */ /* tslint:disable */ diff --git a/crates/bindings-typescript/examples/quickstart-chat/src/module_bindings/index.ts b/crates/bindings-typescript/examples/quickstart-chat/src/module_bindings/index.ts index a6eabf3d121..70c64ea380c 100644 --- a/crates/bindings-typescript/examples/quickstart-chat/src/module_bindings/index.ts +++ b/crates/bindings-typescript/examples/quickstart-chat/src/module_bindings/index.ts @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.9.0 (commit 582c846c11c5fbe8b2447e8e4d0182a10439ec83). +// This was generated using spacetimedb cli version 1.9.0 (commit e9e1d3ac9c421b73364f5bf11c970f2846e38883). /* eslint-disable */ /* tslint:disable */ diff --git a/crates/bindings-typescript/src/lib/table.ts b/crates/bindings-typescript/src/lib/table.ts index bab56b48391..deb16dd4b45 100644 --- a/crates/bindings-typescript/src/lib/table.ts +++ b/crates/bindings-typescript/src/lib/table.ts @@ -301,7 +301,6 @@ export function table>( scheduleAtCol = colIds.get(name)!; } } - } // convert explicit multi‑column indexes coming from options.indexes diff --git a/crates/bindings-typescript/src/lib/type_builders.ts b/crates/bindings-typescript/src/lib/type_builders.ts index 37c868d0101..371b7ee8942 100644 --- a/crates/bindings-typescript/src/lib/type_builders.ts +++ b/crates/bindings-typescript/src/lib/type_builders.ts @@ -1489,8 +1489,7 @@ export type SimpleSumBuilder = export class ScheduleAtBuilder extends TypeBuilder - implements - Defaultable + implements Defaultable { constructor() { super(ScheduleAt.getAlgebraicType()); @@ -2750,8 +2749,7 @@ export class ScheduleAtColumnBuilder< M extends ColumnMetadata = DefaultMetadata, > extends ColumnBuilder - implements - Defaultable + implements Defaultable { default( value: ScheduleAt diff --git a/crates/bindings-typescript/src/sdk/client_api/index.ts b/crates/bindings-typescript/src/sdk/client_api/index.ts index dc11b511ab5..407df32a06a 100644 --- a/crates/bindings-typescript/src/sdk/client_api/index.ts +++ b/crates/bindings-typescript/src/sdk/client_api/index.ts @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.9.0 (commit 582c846c11c5fbe8b2447e8e4d0182a10439ec83). +// This was generated using spacetimedb cli version 1.9.0 (commit e9e1d3ac9c421b73364f5bf11c970f2846e38883). /* eslint-disable */ /* tslint:disable */ diff --git a/crates/bindings-typescript/test-app/src/module_bindings/index.ts b/crates/bindings-typescript/test-app/src/module_bindings/index.ts index 73eeb549b92..8c5c274f27c 100644 --- a/crates/bindings-typescript/test-app/src/module_bindings/index.ts +++ b/crates/bindings-typescript/test-app/src/module_bindings/index.ts @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.9.0 (commit 582c846c11c5fbe8b2447e8e4d0182a10439ec83). +// This was generated using spacetimedb cli version 1.9.0 (commit e9e1d3ac9c421b73364f5bf11c970f2846e38883). /* eslint-disable */ /* tslint:disable */ From 984cc887b758bf7601828c6538b5d254986550b7 Mon Sep 17 00:00:00 2001 From: Tyler Cloutier Date: Tue, 25 Nov 2025 18:56:17 -0500 Subject: [PATCH 06/11] Fixed build errors --- .../examples/basic-react/src/module_bindings/index.ts | 4 +--- .../examples/empty/src/module_bindings/index.ts | 4 +--- .../examples/quickstart-chat/src/module_bindings/index.ts | 4 +--- crates/bindings-typescript/src/sdk/client_api/index.ts | 4 +--- .../bindings-typescript/test-app/src/module_bindings/index.ts | 4 +--- crates/codegen/src/typescript.rs | 2 +- 6 files changed, 6 insertions(+), 16 deletions(-) diff --git a/crates/bindings-typescript/examples/basic-react/src/module_bindings/index.ts b/crates/bindings-typescript/examples/basic-react/src/module_bindings/index.ts index 556c584b344..347993cc188 100644 --- a/crates/bindings-typescript/examples/basic-react/src/module_bindings/index.ts +++ b/crates/bindings-typescript/examples/basic-react/src/module_bindings/index.ts @@ -120,9 +120,7 @@ export class SubscriptionBuilder extends __SubscriptionBuilderImpl< > {} /** Builder class to configure a new database connection to the remote SpacetimeDB instance. */ -export class DbConnectionBuilder extends __DbConnectionBuilder< - typeof REMOTE_MODULE -> {} +export class DbConnectionBuilder extends __DbConnectionBuilder {} /** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */ export class DbConnection extends __DbConnectionImpl { diff --git a/crates/bindings-typescript/examples/empty/src/module_bindings/index.ts b/crates/bindings-typescript/examples/empty/src/module_bindings/index.ts index 556c584b344..347993cc188 100644 --- a/crates/bindings-typescript/examples/empty/src/module_bindings/index.ts +++ b/crates/bindings-typescript/examples/empty/src/module_bindings/index.ts @@ -120,9 +120,7 @@ export class SubscriptionBuilder extends __SubscriptionBuilderImpl< > {} /** Builder class to configure a new database connection to the remote SpacetimeDB instance. */ -export class DbConnectionBuilder extends __DbConnectionBuilder< - typeof REMOTE_MODULE -> {} +export class DbConnectionBuilder extends __DbConnectionBuilder {} /** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */ export class DbConnection extends __DbConnectionImpl { diff --git a/crates/bindings-typescript/examples/quickstart-chat/src/module_bindings/index.ts b/crates/bindings-typescript/examples/quickstart-chat/src/module_bindings/index.ts index 70c64ea380c..b7c257cdd0f 100644 --- a/crates/bindings-typescript/examples/quickstart-chat/src/module_bindings/index.ts +++ b/crates/bindings-typescript/examples/quickstart-chat/src/module_bindings/index.ts @@ -125,9 +125,7 @@ export class SubscriptionBuilder extends __SubscriptionBuilderImpl< > {} /** Builder class to configure a new database connection to the remote SpacetimeDB instance. */ -export class DbConnectionBuilder extends __DbConnectionBuilder< - typeof REMOTE_MODULE -> {} +export class DbConnectionBuilder extends __DbConnectionBuilder {} /** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */ export class DbConnection extends __DbConnectionImpl { diff --git a/crates/bindings-typescript/src/sdk/client_api/index.ts b/crates/bindings-typescript/src/sdk/client_api/index.ts index 407df32a06a..17a45845129 100644 --- a/crates/bindings-typescript/src/sdk/client_api/index.ts +++ b/crates/bindings-typescript/src/sdk/client_api/index.ts @@ -149,9 +149,7 @@ export class SubscriptionBuilder extends __SubscriptionBuilderImpl< > {} /** Builder class to configure a new database connection to the remote SpacetimeDB instance. */ -export class DbConnectionBuilder extends __DbConnectionBuilder< - typeof REMOTE_MODULE -> {} +export class DbConnectionBuilder extends __DbConnectionBuilder {} /** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */ export class DbConnection extends __DbConnectionImpl { diff --git a/crates/bindings-typescript/test-app/src/module_bindings/index.ts b/crates/bindings-typescript/test-app/src/module_bindings/index.ts index 8c5c274f27c..558474bd8b6 100644 --- a/crates/bindings-typescript/test-app/src/module_bindings/index.ts +++ b/crates/bindings-typescript/test-app/src/module_bindings/index.ts @@ -140,9 +140,7 @@ export class SubscriptionBuilder extends __SubscriptionBuilderImpl< > {} /** Builder class to configure a new database connection to the remote SpacetimeDB instance. */ -export class DbConnectionBuilder extends __DbConnectionBuilder< - typeof REMOTE_MODULE -> {} +export class DbConnectionBuilder extends __DbConnectionBuilder {} /** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */ export class DbConnection extends __DbConnectionImpl { diff --git a/crates/codegen/src/typescript.rs b/crates/codegen/src/typescript.rs index fd4dce96d22..a7b95925e9a 100644 --- a/crates/codegen/src/typescript.rs +++ b/crates/codegen/src/typescript.rs @@ -351,7 +351,7 @@ impl Lang for TypeScript { ); writeln!( out, - "export class DbConnectionBuilder extends __DbConnectionBuilder {{}}" + "export class DbConnectionBuilder extends __DbConnectionBuilder {{}}" ); writeln!(out); From f2abbb96d38bd87f42b87aa9889570b2659f4ed3 Mon Sep 17 00:00:00 2001 From: Tyler Cloutier Date: Tue, 25 Nov 2025 19:32:05 -0500 Subject: [PATCH 07/11] Fixed failing test --- .../src/lib/schedule_at.ts | 23 +++++++++++++++++++ crates/bindings-typescript/src/lib/table.ts | 8 ++----- .../src/lib/time_duration.ts | 17 ++++++++++++++ .../bindings-typescript/src/lib/timestamp.ts | 17 ++++++++++++++ .../bindings-typescript/tests/index.test.ts | 5 ++-- 5 files changed, 62 insertions(+), 8 deletions(-) diff --git a/crates/bindings-typescript/src/lib/schedule_at.ts b/crates/bindings-typescript/src/lib/schedule_at.ts index 4fb185e7ea2..61d263b8a35 100644 --- a/crates/bindings-typescript/src/lib/schedule_at.ts +++ b/crates/bindings-typescript/src/lib/schedule_at.ts @@ -22,6 +22,9 @@ export const ScheduleAt: { * @returns The algebraic type representation of the type. */ getAlgebraicType(): ScheduleAtAlgebraicType; + isScheduleAt( + algebraicType: AlgebraicType + ): algebraicType is ScheduleAtAlgebraicType; } = { interval(value: bigint): ScheduleAtType { return Interval(value); @@ -40,6 +43,26 @@ export const ScheduleAt: { ], }); }, + isScheduleAt( + algebraicType: AlgebraicType + ): algebraicType is ScheduleAtAlgebraicType { + if (algebraicType.tag !== 'Sum') { + return false; + } + const variants = algebraicType.value.variants; + if (variants.length !== 2) { + return false; + } + const intervalVariant = variants.find(v => v.name === 'Interval'); + const timeVariant = variants.find(v => v.name === 'Time'); + if (!intervalVariant || !timeVariant) { + return false; + } + return ( + TimeDuration.isTimeDuration(intervalVariant.algebraicType) && + Timestamp.isTimestamp(timeVariant.algebraicType) + ); + }, }; export type Interval = { diff --git a/crates/bindings-typescript/src/lib/table.ts b/crates/bindings-typescript/src/lib/table.ts index deb16dd4b45..1b61646f1dd 100644 --- a/crates/bindings-typescript/src/lib/table.ts +++ b/crates/bindings-typescript/src/lib/table.ts @@ -12,6 +12,7 @@ import type { IndexOpts, ReadonlyIndexes, } from './indexes'; +import ScheduleAt from './schedule_at'; import { registerTypesRecursively } from './schema'; import type { TableSchema } from './table_schema'; import { @@ -292,12 +293,7 @@ export function table>( // If this column is shaped like ScheduleAtAlgebraicType, mark it as the schedule‑at column if (scheduled) { const algebraicType = builder.typeBuilder.algebraicType; - if ( - algebraicType.tag === 'Sum' && - algebraicType.value.variants.length === 2 && - algebraicType.value.variants[0].name === 'Interval' && - algebraicType.value.variants[1].name === 'Time' - ) { + if (ScheduleAt.isScheduleAt(algebraicType)) { scheduleAtCol = colIds.get(name)!; } } diff --git a/crates/bindings-typescript/src/lib/time_duration.ts b/crates/bindings-typescript/src/lib/time_duration.ts index c8ccc5d64af..15d6141300e 100644 --- a/crates/bindings-typescript/src/lib/time_duration.ts +++ b/crates/bindings-typescript/src/lib/time_duration.ts @@ -32,6 +32,23 @@ export class TimeDuration { }); } + static isTimeDuration( + algebraicType: AlgebraicType + ): algebraicType is TimeDurationAlgebraicType { + if (algebraicType.tag !== 'Product') { + return false; + } + const elements = algebraicType.value.elements; + if (elements.length !== 1) { + return false; + } + const microsElement = elements[0]; + return ( + microsElement.name === '__time_duration_micros__' && + microsElement.algebraicType.tag === 'I64' + ); + } + get micros(): bigint { return this.__time_duration_micros__; } diff --git a/crates/bindings-typescript/src/lib/timestamp.ts b/crates/bindings-typescript/src/lib/timestamp.ts index e97fca90de8..e4067d61ecc 100644 --- a/crates/bindings-typescript/src/lib/timestamp.ts +++ b/crates/bindings-typescript/src/lib/timestamp.ts @@ -44,6 +44,23 @@ export class Timestamp { }); } + static isTimestamp( + algebraicType: AlgebraicType + ): algebraicType is TimestampAlgebraicType { + if (algebraicType.tag !== 'Product') { + return false; + } + const elements = algebraicType.value.elements; + if (elements.length !== 1) { + return false; + } + const microsElement = elements[0]; + return ( + microsElement.name === '__timestamp_micros_since_unix_epoch__' && + microsElement.algebraicType.tag === 'I64' + ); + } + /** * The Unix epoch, the midnight at the beginning of January 1, 1970, UTC. */ diff --git a/crates/bindings-typescript/tests/index.test.ts b/crates/bindings-typescript/tests/index.test.ts index 5e009d7d75b..c0800a33919 100644 --- a/crates/bindings-typescript/tests/index.test.ts +++ b/crates/bindings-typescript/tests/index.test.ts @@ -3,6 +3,7 @@ import { AlgebraicType, ConnectionId, Identity, + ScheduleAt, type IdentityTokenMessage, } from '../src/index'; import type { ColumnBuilder } from '../src/server'; @@ -104,7 +105,7 @@ describe('TypeBuilder', () => { it('builds a ScheduleAt column with the correct type and metadata', () => { const col = t.scheduleAt(); - expect(col.typeBuilder.algebraicType).toEqual({ + expect(col.algebraicType).toEqual({ tag: 'Sum', value: { variants: [ @@ -139,7 +140,7 @@ describe('TypeBuilder', () => { ], }, }); - expect(col.columnMetadata.isScheduleAt).toEqual(true); + expect(ScheduleAt.isScheduleAt(col.algebraicType)).toEqual(true); }); }); From 7aa991df7cb8fa47766ae0862453469a93731437 Mon Sep 17 00:00:00 2001 From: Tyler Cloutier Date: Tue, 25 Nov 2025 19:37:44 -0500 Subject: [PATCH 08/11] Fixes https://github.com/clockworklabs/SpacetimeDBPrivate/issues/2168 --- crates/cli/templates/basic-typescript/server/src/index.ts | 6 +++--- modules/module-test-ts/src/index.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/cli/templates/basic-typescript/server/src/index.ts b/crates/cli/templates/basic-typescript/server/src/index.ts index 0142eefd44f..5ee50cb263b 100644 --- a/crates/cli/templates/basic-typescript/server/src/index.ts +++ b/crates/cli/templates/basic-typescript/server/src/index.ts @@ -9,15 +9,15 @@ export const spacetimedb = schema( ) ); -spacetimedb.reducer('init', (_ctx) => { +spacetimedb.init((_ctx) => { // Called when the module is initially published }); -spacetimedb.reducer('client_connected', (_ctx) => { +spacetimedb.clientConnected((_ctx) => { // Called every time a new client connects }); -spacetimedb.reducer('client_disconnected', (_ctx) => { +spacetimedb.clientDisconnected((_ctx) => { // Called every time a client disconnects }); diff --git a/modules/module-test-ts/src/index.ts b/modules/module-test-ts/src/index.ts index 659bde643eb..60d6336cdd6 100644 --- a/modules/module-test-ts/src/index.ts +++ b/modules/module-test-ts/src/index.ts @@ -230,7 +230,7 @@ spacetimedb.view( // ───────────────────────────────────────────────────────────────────────────── // init -spacetimedb.reducer('init', {}, ctx => { +spacetimedb.init(ctx => { ctx.db.repeating_test_arg.insert({ prev_time: ctx.timestamp, scheduled_id: 0n, // u64 autoInc placeholder (engine will assign) From c7e6423cd7307f6678776658abbc947ef3ffc447 Mon Sep 17 00:00:00 2001 From: Tyler Cloutier Date: Tue, 25 Nov 2025 19:48:01 -0500 Subject: [PATCH 09/11] Fix cargo insta tests --- .../codegen__codegen_typescript.snap | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/crates/codegen/tests/snapshots/codegen__codegen_typescript.snap b/crates/codegen/tests/snapshots/codegen__codegen_typescript.snap index 404c7e4fe82..da8de24de81 100644 --- a/crates/codegen/tests/snapshots/codegen__codegen_typescript.snap +++ b/crates/codegen/tests/snapshots/codegen__codegen_typescript.snap @@ -231,6 +231,7 @@ import { type ReducerEventContextInterface as __ReducerEventContextInterface, type RemoteModule as __RemoteModule, type SubscriptionEventContextInterface as __SubscriptionEventContextInterface, + type SubscriptionHandleImpl as __SubscriptionHandleImpl, } from "spacetimedb"; // Import and reexport all reducer arg types @@ -325,7 +326,7 @@ export { NamespaceTestC }; import NamespaceTestF from "./namespace_test_f_type"; export { NamespaceTestF }; - +/** The schema information for all tables in this module. This is defined the same was as the tables would have been defined in the server. */ const tablesSchema = __schema( __table({ name: 'has_special_stuff', @@ -350,9 +351,9 @@ const tablesSchema = __schema( constraints: [ { name: 'logged_out_player_identity_key', constraint: 'unique', columns: ['identity'] }, { name: 'logged_out_player_name_key', constraint: 'unique', columns: ['name'] }, - { name: 'logged_out_player_player_id_key', constraint: 'unique', columns: ['player_id'] }, + { name: 'logged_out_player_player_id_key', constraint: 'unique', columns: ['playerId'] }, ], - }, PlayerRow), + }, LoggedOutPlayerRow), __table({ name: 'person', indexes: [ @@ -398,7 +399,7 @@ const tablesSchema = __schema( constraints: [ { name: 'player_identity_key', constraint: 'unique', columns: ['identity'] }, { name: 'player_name_key', constraint: 'unique', columns: ['name'] }, - { name: 'player_player_id_key', constraint: 'unique', columns: ['player_id'] }, + { name: 'player_player_id_key', constraint: 'unique', columns: ['playerId'] }, ], }, PlayerRow), __table({ @@ -411,7 +412,7 @@ const tablesSchema = __schema( ], constraints: [ ], - }, PointRow), + }, PointsRow), __table({ name: 'private_table', indexes: [ @@ -427,7 +428,7 @@ const tablesSchema = __schema( ] }, ], constraints: [ - { name: 'repeating_test_arg_scheduled_id_key', constraint: 'unique', columns: ['scheduled_id'] }, + { name: 'repeating_test_arg_scheduled_id_key', constraint: 'unique', columns: ['scheduledId'] }, ], }, RepeatingTestArgRow), __table({ @@ -467,16 +468,17 @@ const tablesSchema = __schema( ], constraints: [ ], - }, TestFoobarRow), + }, TestFRow), __table({ name: 'my_player', indexes: [ ], constraints: [ ], - }, PlayerRow), + }, MyPlayerRow), ); +/** The schema information for all reducers in this module. This is defined the same way as the reducers would have been defined in the server, except the body of the reducer is omitted in code generation. */ const reducersSchema = __reducers( __reducerSchema("add", Add), __reducerSchema("add_player", AddPlayer), @@ -493,6 +495,7 @@ const reducersSchema = __reducers( __reducerSchema("test_btree_index_args", TestBtreeIndexArgs), ); +/** The remote SpacetimeDB module schema, both runtime and type information. */ const REMOTE_MODULE = { versionInfo: { cliVersion: "1.9.0" as const, @@ -504,27 +507,37 @@ const REMOTE_MODULE = { typeof reducersSchema.reducersType >; +/** The tables available in this remote SpacetimeDB module. */ export const tables = __convertToAccessorMap(tablesSchema.schemaType.tables); -export const reducers = __convertToAccessorMap(reducersSchema.reducersType.reducers); +/** The reducers available in this remote SpacetimeDB module. */ +export const reducers = __convertToAccessorMap(reducersSchema.reducersType.reducers); +/** The context type returned in callbacks for all possible events. */ export type EventContext = __EventContextInterface; +/** The context type returned in callbacks for reducer events. */ export type ReducerEventContext = __ReducerEventContextInterface; +/** The context type returned in callbacks for subscription events. */ export type SubscriptionEventContext = __SubscriptionEventContextInterface; +/** The context type returned in callbacks for error events. */ export type ErrorContext = __ErrorContextInterface; +/** The subscription handle type to manage active subscriptions created from a {@link SubscriptionBuilder}. */ +export type SubscriptionHandle = __SubscriptionHandleImpl; -export class SubscriptionBuilder extends __SubscriptionBuilderImpl< - typeof REMOTE_MODULE -> {} +/** Builder class to configure a new subscription to the remote SpacetimeDB instance. */ +export class SubscriptionBuilder extends __SubscriptionBuilderImpl {} -export class DbConnectionBuilder extends __DbConnectionBuilder< - DbConnection -> {} +/** Builder class to configure a new database connection to the remote SpacetimeDB instance. */ +export class DbConnectionBuilder extends __DbConnectionBuilder {} +/** The typed database connection to manage connections to the remote SpacetimeDB instance. This class has type information specific to the generated module. */ export class DbConnection extends __DbConnectionImpl { + /** Creates a new {@link DbConnectionBuilder} to configure and connect to the remote SpacetimeDB instance. */ static builder = (): DbConnectionBuilder => { return new DbConnectionBuilder(REMOTE_MODULE, (config: __DbConnectionConfig) => new DbConnection(config)); }; + + /** Creates a new {@link SubscriptionBuilder} to configure a subscription to the remote SpacetimeDB instance. */ subscriptionBuilder = (): SubscriptionBuilder => { return new SubscriptionBuilder(this); }; From a4bb137e53d55517e0b3f031be6a7453f7ba2b1e Mon Sep 17 00:00:00 2001 From: Tyler Cloutier Date: Tue, 25 Nov 2025 20:29:52 -0500 Subject: [PATCH 10/11] Fixes uncovered issue with module-test-ts --- modules/module-test-ts/src/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/module-test-ts/src/index.ts b/modules/module-test-ts/src/index.ts index 60d6336cdd6..dc8f88cfa94 100644 --- a/modules/module-test-ts/src/index.ts +++ b/modules/module-test-ts/src/index.ts @@ -202,7 +202,7 @@ const spacetimedb = schema( // repeating_test_arg table with scheduled(repeating_test) table( - { name: 'repeating_test_arg', scheduled: 'repeating_test' } as any, + { name: 'repeating_test_arg', scheduled: 'repeating_test' }, repeatingTestArg ), @@ -231,7 +231,7 @@ spacetimedb.view( // init spacetimedb.init(ctx => { - ctx.db.repeating_test_arg.insert({ + ctx.db.repeatingTestArg.insert({ prev_time: ctx.timestamp, scheduled_id: 0n, // u64 autoInc placeholder (engine will assign) scheduled_at: ScheduleAt.interval(1000000n), // 1000ms @@ -308,7 +308,7 @@ spacetimedb.reducer( }); } - const rowCountBefore = ctx.db.test_a.count(); + const rowCountBefore = ctx.db.testA.count(); console.info(`Row count before delete: ${rowCountBefore}`); // Delete rows by the indexed column `x` in [5,10) @@ -339,7 +339,7 @@ spacetimedb.reducer( console.info(`Row count after delete: ${rowCountAfter}`); - const otherRowCount = ctx.db.test_a.count(); + const otherRowCount = ctx.db.testA.count(); console.info(`Row count filtered by condition: ${otherRowCount}`); console.info('MultiColumn'); From 63e9c33708c30098d462ccd90f0f2ece58d1066c Mon Sep 17 00:00:00 2001 From: Tyler Cloutier Date: Tue, 25 Nov 2025 21:18:00 -0500 Subject: [PATCH 11/11] Cargo fmt --- crates/codegen/src/typescript.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/codegen/src/typescript.rs b/crates/codegen/src/typescript.rs index ee917f02a58..254506a8f98 100644 --- a/crates/codegen/src/typescript.rs +++ b/crates/codegen/src/typescript.rs @@ -315,7 +315,6 @@ impl Lang for TypeScript { out.dedent(1); writeln!(out, ");"); - writeln!(out); writeln!( out,