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/index.ts b/crates/bindings-typescript/examples/basic-react/src/module_bindings/index.ts index 236984d22c3..afaacdde18c 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 ed2a18cff7c996f28bd3b6ae0223ceb564fc2a58). +// This was generated using spacetimedb cli version 1.9.0 (commit a4bb137e53d55517e0b3f031be6a7453f7ba2b1e). /* eslint-disable */ /* tslint:disable */ @@ -27,15 +27,14 @@ 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 -import Init from './init_reducer'; -export { Init }; -import ClientConnected from './client_connected_reducer'; -export { ClientConnected }; -import ClientDisconnected from './client_disconnected_reducer'; -export { ClientDisconnected }; +import OnConnect from './on_connect_reducer'; +export { OnConnect }; +import OnDisconnect from './on_disconnect_reducer'; +export { OnDisconnect }; import Add from './add_reducer'; export { Add }; import SayHello from './say_hello_reducer'; @@ -50,17 +49,18 @@ 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 OnConnect from './on_connect_type'; +export { OnConnect }; +import OnDisconnect from './on_disconnect_type'; +export { OnDisconnect }; 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( { @@ -72,16 +72,16 @@ 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), - __reducerSchema('client_disconnected', ClientDisconnected), __reducerSchema('add', Add), __reducerSchema('say_hello', SayHello) ); +/** The schema information for all procedures in this module. This is defined the same way as the procedures would have been defined in the server. */ const proceduresSchema = __procedures(); +/** The remote SpacetimeDB module schema, both runtime and type information. */ const REMOTE_MODULE = { versionInfo: { cliVersion: '1.9.0' as const, @@ -95,27 +95,40 @@ const REMOTE_MODULE = { typeof proceduresSchema >; +/** 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 > {} +/** 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, @@ -123,6 +136,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/on_connect_reducer.ts b/crates/bindings-typescript/examples/basic-react/src/module_bindings/on_connect_reducer.ts new file mode 100644 index 00000000000..2ca99c88fea --- /dev/null +++ b/crates/bindings-typescript/examples/basic-react/src/module_bindings/on_connect_reducer.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 {}; diff --git a/crates/bindings-typescript/examples/basic-react/src/module_bindings/on_connect_type.ts b/crates/bindings-typescript/examples/basic-react/src/module_bindings/on_connect_type.ts new file mode 100644 index 00000000000..d36362515de --- /dev/null +++ b/crates/bindings-typescript/examples/basic-react/src/module_bindings/on_connect_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('OnConnect', {}); diff --git a/crates/bindings-typescript/examples/basic-react/src/module_bindings/on_disconnect_reducer.ts b/crates/bindings-typescript/examples/basic-react/src/module_bindings/on_disconnect_reducer.ts new file mode 100644 index 00000000000..2ca99c88fea --- /dev/null +++ b/crates/bindings-typescript/examples/basic-react/src/module_bindings/on_disconnect_reducer.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 {}; diff --git a/crates/bindings-typescript/examples/basic-react/src/module_bindings/on_disconnect_type.ts b/crates/bindings-typescript/examples/basic-react/src/module_bindings/on_disconnect_type.ts new file mode 100644 index 00000000000..efda71ebcfd --- /dev/null +++ b/crates/bindings-typescript/examples/basic-react/src/module_bindings/on_disconnect_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('OnDisconnect', {}); 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 236984d22c3..afaacdde18c 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 ed2a18cff7c996f28bd3b6ae0223ceb564fc2a58). +// This was generated using spacetimedb cli version 1.9.0 (commit a4bb137e53d55517e0b3f031be6a7453f7ba2b1e). /* eslint-disable */ /* tslint:disable */ @@ -27,15 +27,14 @@ 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 -import Init from './init_reducer'; -export { Init }; -import ClientConnected from './client_connected_reducer'; -export { ClientConnected }; -import ClientDisconnected from './client_disconnected_reducer'; -export { ClientDisconnected }; +import OnConnect from './on_connect_reducer'; +export { OnConnect }; +import OnDisconnect from './on_disconnect_reducer'; +export { OnDisconnect }; import Add from './add_reducer'; export { Add }; import SayHello from './say_hello_reducer'; @@ -50,17 +49,18 @@ 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 OnConnect from './on_connect_type'; +export { OnConnect }; +import OnDisconnect from './on_disconnect_type'; +export { OnDisconnect }; 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( { @@ -72,16 +72,16 @@ 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), - __reducerSchema('client_disconnected', ClientDisconnected), __reducerSchema('add', Add), __reducerSchema('say_hello', SayHello) ); +/** The schema information for all procedures in this module. This is defined the same way as the procedures would have been defined in the server. */ const proceduresSchema = __procedures(); +/** The remote SpacetimeDB module schema, both runtime and type information. */ const REMOTE_MODULE = { versionInfo: { cliVersion: '1.9.0' as const, @@ -95,27 +95,40 @@ const REMOTE_MODULE = { typeof proceduresSchema >; +/** 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 > {} +/** 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, @@ -123,6 +136,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/on_connect_reducer.ts b/crates/bindings-typescript/examples/empty/src/module_bindings/on_connect_reducer.ts new file mode 100644 index 00000000000..2ca99c88fea --- /dev/null +++ b/crates/bindings-typescript/examples/empty/src/module_bindings/on_connect_reducer.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 {}; diff --git a/crates/bindings-typescript/examples/empty/src/module_bindings/on_connect_type.ts b/crates/bindings-typescript/examples/empty/src/module_bindings/on_connect_type.ts new file mode 100644 index 00000000000..d36362515de --- /dev/null +++ b/crates/bindings-typescript/examples/empty/src/module_bindings/on_connect_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('OnConnect', {}); diff --git a/crates/bindings-typescript/examples/empty/src/module_bindings/on_disconnect_reducer.ts b/crates/bindings-typescript/examples/empty/src/module_bindings/on_disconnect_reducer.ts new file mode 100644 index 00000000000..2ca99c88fea --- /dev/null +++ b/crates/bindings-typescript/examples/empty/src/module_bindings/on_disconnect_reducer.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 {}; diff --git a/crates/bindings-typescript/examples/empty/src/module_bindings/on_disconnect_type.ts b/crates/bindings-typescript/examples/empty/src/module_bindings/on_disconnect_type.ts new file mode 100644 index 00000000000..efda71ebcfd --- /dev/null +++ b/crates/bindings-typescript/examples/empty/src/module_bindings/on_disconnect_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('OnDisconnect', {}); 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 664379e52ef..1fb1fff56bc 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 @@ -27,6 +27,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 @@ -53,6 +54,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( { @@ -80,13 +82,16 @@ 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 schema information for all procedures in this module. This is defined the same way as the procedures would have been defined in the server. */ const proceduresSchema = __procedures(); +/** The remote SpacetimeDB module schema, both runtime and type information. */ const REMOTE_MODULE = { versionInfo: { cliVersion: '1.10.0' as const, @@ -100,27 +105,40 @@ const REMOTE_MODULE = { typeof proceduresSchema >; +/** 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 > {} +/** 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, @@ -128,6 +146,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/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 803f1585851..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 { @@ -116,6 +117,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 +199,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') * }) * ); @@ -288,8 +290,12 @@ 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 (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/src/lib/type_builders.ts b/crates/bindings-typescript/src/lib/type_builders.ts index 77246981264..371b7ee8942 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,25 @@ 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 +1767,6 @@ export type ColumnMetadata = { isPrimaryKey?: true; isUnique?: true; isAutoIncrement?: true; - isScheduleAt?: true; indexType?: IndexTypes; defaultValue?: Type; }; @@ -2727,6 +2745,22 @@ 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 +3275,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(); }, /** 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 80b74317048..e9a13b198cc 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 { ColumnBuilder, Infer, TypeBuilder } 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 78b530f888c..bfa84abe720 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 ed2a18cff7c996f28bd3b6ae0223ceb564fc2a58). +// This was generated using spacetimedb cli version 1.9.0 (commit a4bb137e53d55517e0b3f031be6a7453f7ba2b1e). /* eslint-disable */ /* tslint:disable */ @@ -27,6 +27,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 @@ -105,12 +106,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 schema information for all procedures in this module. This is defined the same way as the procedures would have been defined in the server. */ const proceduresSchema = __procedures(); +/** The remote SpacetimeDB module schema, both runtime and type information. */ const REMOTE_MODULE = { versionInfo: { cliVersion: '1.9.0' as const, @@ -124,27 +129,40 @@ const REMOTE_MODULE = { typeof proceduresSchema >; +/** 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 > {} +/** 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, @@ -152,6 +170,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 97a63c2b4a2..62cdbced532 100644 --- a/crates/bindings-typescript/src/sdk/db_connection_impl.ts +++ b/crates/bindings-typescript/src/sdk/db_connection_impl.ts @@ -61,6 +61,7 @@ import type { ProceduresView } from './procedures.ts'; export { DbConnectionBuilder, SubscriptionBuilderImpl, + SubscriptionHandleImpl, type TableCache, type Event, }; @@ -818,14 +819,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/bindings-typescript/test-app/src/module_bindings/index.ts b/crates/bindings-typescript/test-app/src/module_bindings/index.ts index 89651a1d4cb..9bddca88456 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 ed2a18cff7c996f28bd3b6ae0223ceb564fc2a58). +// This was generated using spacetimedb cli version 1.9.0 (commit a4bb137e53d55517e0b3f031be6a7453f7ba2b1e). /* eslint-disable */ /* tslint:disable */ @@ -27,6 +27,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 @@ -53,6 +54,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( { @@ -96,12 +98,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 schema information for all procedures in this module. This is defined the same way as the procedures would have been defined in the server. */ const proceduresSchema = __procedures(); +/** The remote SpacetimeDB module schema, both runtime and type information. */ const REMOTE_MODULE = { versionInfo: { cliVersion: '1.9.0' as const, @@ -115,27 +120,40 @@ const REMOTE_MODULE = { typeof proceduresSchema >; +/** 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 > {} +/** 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, @@ -143,6 +161,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/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); }); }); 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/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/crates/codegen/src/typescript.rs b/crates/codegen/src/typescript.rs index 57595e2c9da..254506a8f98 100644 --- a/crates/codegen/src/typescript.rs +++ b/crates/codegen/src/typescript.rs @@ -209,8 +209,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; @@ -250,14 +249,13 @@ 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) { 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( @@ -269,22 +267,22 @@ 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, ");"); 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) { @@ -300,7 +298,10 @@ impl Lang for TypeScript { writeln!(out, ");"); writeln!(out); - + writeln!( + out, + "/** The schema information for all procedures in this module. This is defined the same way as the procedures would have been defined in the server. */" + ); writeln!(out, "const proceduresSchema = __procedures("); out.indent(1); for procedure in iter_procedures(module) { @@ -315,7 +316,10 @@ 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: {{"); @@ -337,60 +341,84 @@ 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, - "export class SubscriptionBuilder extends __SubscriptionBuilderImpl<" + "/** Builder class to configure a new subscription to the remote SpacetimeDB instance. */" + ); + writeln!( + out, + "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!( @@ -399,6 +427,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);"); @@ -427,6 +458,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", @@ -596,6 +628,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(); diff --git a/crates/codegen/tests/snapshots/codegen__codegen_typescript.snap b/crates/codegen/tests/snapshots/codegen__codegen_typescript.snap index dc5b79c1417..33403b2849d 100644 --- a/crates/codegen/tests/snapshots/codegen__codegen_typescript.snap +++ b/crates/codegen/tests/snapshots/codegen__codegen_typescript.snap @@ -248,6 +248,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 @@ -352,7 +353,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', @@ -377,9 +378,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: [ @@ -425,7 +426,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({ @@ -438,7 +439,7 @@ const tablesSchema = __schema( ], constraints: [ ], - }, PointRow), + }, PointsRow), __table({ name: 'private_table', indexes: [ @@ -454,7 +455,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({ @@ -494,16 +495,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), @@ -520,6 +522,7 @@ const reducersSchema = __reducers( __reducerSchema("test_btree_index_args", TestBtreeIndexArgs), ); +/** The schema information for all procedures in this module. This is defined the same way as the procedures would have been defined in the server. */ const proceduresSchema = __procedures( __procedureSchema("get_my_schema_via_http", GetMySchemaViaHttpProcedure.params, GetMySchemaViaHttpProcedure.returnType), __procedureSchema("return_value", ReturnValueProcedure.params, ReturnValueProcedure.returnType), @@ -527,6 +530,7 @@ const proceduresSchema = __procedures( __procedureSchema("with_tx", WithTxProcedure.params, WithTxProcedure.returnType), ); +/** The remote SpacetimeDB module schema, both runtime and type information. */ const REMOTE_MODULE = { versionInfo: { cliVersion: "1.10.0" as const, @@ -540,27 +544,37 @@ const REMOTE_MODULE = { typeof proceduresSchema >; +/** 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); }; diff --git a/modules/module-test-ts/src/index.ts b/modules/module-test-ts/src/index.ts index a16eb528339..52c386f4e29 100644 --- a/modules/module-test-ts/src/index.ts +++ b/modules/module-test-ts/src/index.ts @@ -203,7 +203,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,8 +231,8 @@ spacetimedb.view( // ───────────────────────────────────────────────────────────────────────────── // init -spacetimedb.reducer('init', {}, ctx => { - ctx.db.repeating_test_arg.insert({ +spacetimedb.init(ctx => { + ctx.db.repeatingTestArg.insert({ prev_time: ctx.timestamp, scheduled_id: 0n, // u64 autoInc placeholder (engine will assign) scheduled_at: ScheduleAt.interval(1000000n), // 1000ms @@ -309,7 +309,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) @@ -340,7 +340,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');