diff --git a/sdks/typescript/examples/quickstart/src/module_bindings/index.ts b/sdks/typescript/examples/quickstart/src/module_bindings/index.ts index dbd274415..87ed391de 100644 --- a/sdks/typescript/examples/quickstart/src/module_bindings/index.ts +++ b/sdks/typescript/examples/quickstart/src/module_bindings/index.ts @@ -6,26 +6,47 @@ import { STDBEvent, type CallbackInit, } from '@clockworklabs/spacetimedb-sdk'; -import { MessageTable } from './message.ts'; -import { User } from './user.ts'; - +import { MessageTableHandle } from './message.ts'; import { SendMessageReducer } from './send_message_reducer.ts'; import { SetNameReducer } from './set_name_reducer.ts'; +import { UserTableHandle } from './user.ts'; +// AUTOGENERATED class EventContext extends DbContext { - event: STDBEvent; + event: STDBEvent>; constructor( client: DBConnectionBase, db: RemoteTables, reducers: RemoteReducers, - event: STDBEvent + event: STDBEvent> ) { super(client, db, reducers); this.event = event; } } +// AUTOGENERATED +type ReducerEnum = + | { + tag: 'SendMessage'; + value: SendMessageReducer< + EventContext, + RemoteTables, + RemoteReducers, + ReducerEnum + >; + } + | { + tag: 'SetName'; + value: SetNameReducer< + EventContext, + RemoteTables, + RemoteReducers, + ReducerEnum + >; + }; + class RemoteTables { #client: DBConnectionBase; @@ -34,11 +55,11 @@ class RemoteTables { } get user() { - return User; + return new UserTableHandle(this.#client); } get message() { - return new MessageTable(this.#client); + return new MessageTableHandle(this.#client); } } @@ -47,7 +68,8 @@ class RemoteReducers { #sendMessageReducer: SendMessageReducer< EventContext, RemoteTables, - RemoteReducers + RemoteReducers, + any >; constructor(client: DBConnectionBase) { @@ -86,7 +108,7 @@ export class DbConnection { static builder() { const base = new DBConnectionBase(); - const tables = new RemoteTables(); + const tables = new RemoteTables(base); const reducers = new RemoteReducers(base); const builder = new DBConnectionBuilder(base, tables, reducers); diff --git a/sdks/typescript/examples/quickstart/src/module_bindings/message.ts b/sdks/typescript/examples/quickstart/src/module_bindings/message.ts index 57c23e282..eab794c9b 100644 --- a/sdks/typescript/examples/quickstart/src/module_bindings/message.ts +++ b/sdks/typescript/examples/quickstart/src/module_bindings/message.ts @@ -16,7 +16,7 @@ type Message = { text: string; }; -export class MessageTable< +export class MessageTableHandle< DbView, ReducerView, ReducerEnum, @@ -31,14 +31,14 @@ export class MessageTable< constructor( client: DBConnectionBase, - sender: Identity, - sent: bigint, - text: string + sender?: Identity, + sent?: bigint, + text?: string ) { this.#client = client; - this.sender = sender; - this.sent = sent; - this.text = text; + this.sender = sender!; + this.sent = sent!; + this.text = text!; } public static serialize(value: Message): object { @@ -69,7 +69,7 @@ export class MessageTable< >( client: DBConnectionBase, value: AlgebraicValue - ): MessageTable { + ): MessageTableHandle { let productValue = value.asProductValue(); let __sender = productValue.elements[0].asIdentity(); let __sent = productValue.elements[1].asBigInt(); diff --git a/sdks/typescript/examples/quickstart/src/module_bindings/set_name_reducer.ts b/sdks/typescript/examples/quickstart/src/module_bindings/set_name_reducer.ts index 94c01e5d4..7c16fa503 100644 --- a/sdks/typescript/examples/quickstart/src/module_bindings/set_name_reducer.ts +++ b/sdks/typescript/examples/quickstart/src/module_bindings/set_name_reducer.ts @@ -8,11 +8,17 @@ import { ReducerArgsAdapter, } from '@clockworklabs/spacetimedb-sdk'; -export class SetNameReducer extends Reducer< +export class SetNameReducer< + EventContext, + DBView, + ReducerView, + ReducerEnum, +> extends Reducer< [name: string], DBView, ReducerView, - EventContext + EventContext, + ReducerEnum > { constructor(client: DBConnectionBase) { super(client, 'SetName'); diff --git a/sdks/typescript/examples/quickstart/src/module_bindings/user.ts b/sdks/typescript/examples/quickstart/src/module_bindings/user.ts index 1c81ffb2c..be9154173 100644 --- a/sdks/typescript/examples/quickstart/src/module_bindings/user.ts +++ b/sdks/typescript/examples/quickstart/src/module_bindings/user.ts @@ -2,81 +2,117 @@ // WILL NOT BE SAVED. MODIFY TABLES IN RUST INSTEAD. // @ts-ignore -import { __SPACETIMEDB__, AlgebraicType, ProductType, ProductTypeElement, SumType, SumTypeVariant, DatabaseTable, AlgebraicValue, ReducerEvent, Identity, Address, ClientDB, SpacetimeDBClient } from "@clockworklabs/spacetimedb-sdk"; +import { + AlgebraicType, + AlgebraicValue, + DBConnectionBase, + DbContext, + Identity, + ProductTypeElement, + SumTypeVariant, +} from '@clockworklabs/spacetimedb-sdk'; -export class User extends DatabaseTable -{ - public static db: ClientDB = __SPACETIMEDB__.clientDB; - public static tableName = "User"; - public identity: Identity; - public name: string | null; - public online: boolean; +export type User = { + identity: Identity; + name: string | null; + online: boolean; +}; - public static primaryKey: string | undefined = "identity"; +export class UserTableHandle< + DbView, + ReducerView, + ReducerEnum, + EventContext extends DbContext, +> { + #client: DBConnectionBase; + tableName = 'User'; - constructor(identity: Identity, name: string | null, online: boolean) { - super(); - this.identity = identity; - this.name = name; - this.online = online; - } + identity: Identity; + name: string | null; + online: boolean; - public static serialize(value: User): object { - return [ - Array.from(value.identity.toUint8Array()), value.name ? { "some": value.name } : { "none": [] }, value.online - ]; - } + primaryKey?: string = 'identity'; - public static getAlgebraicType(): AlgebraicType - { - return AlgebraicType.createProductType([ - new ProductTypeElement("identity", AlgebraicType.createProductType([ - new ProductTypeElement("__identity_bytes", AlgebraicType.createArrayType(AlgebraicType.createU8Type())), - ])), - new ProductTypeElement("name", AlgebraicType.createSumType([ - new SumTypeVariant("some", AlgebraicType.createStringType()), - new SumTypeVariant("none", AlgebraicType.createProductType([ - ])), - ])), - new ProductTypeElement("online", AlgebraicType.createBoolType()), - ]); - } + constructor( + client: DBConnectionBase, + identity?: Identity, + name?: string | null, + online?: boolean + ) { + this.#client = client; + this.identity = identity!; + this.name = name!; + this.online = online!; + } - public static fromValue(value: AlgebraicValue): User - { - let productValue = value.asProductValue(); - let __identity = productValue.elements[0].asIdentity(); - let __name = productValue.elements[1].asSumValue().tag == 1 ? null : productValue.elements[1].asSumValue().value.asString(); - let __online = productValue.elements[2].asBoolean(); - return new this(__identity, __name, __online); - } + static serialize(value: User): object { + return [ + Array.from(value.identity.toUint8Array()), + value.name ? { some: value.name } : { none: [] }, + value.online, + ]; + } - public static *filterByIdentity(value: Identity): IterableIterator - { - for (let instance of this.db.getTable("User").getInstances()) - { - if (instance.identity.isEqual(value)) { - yield instance; - } - } - } + static getAlgebraicType(): AlgebraicType { + return AlgebraicType.createProductType([ + new ProductTypeElement( + 'identity', + AlgebraicType.createProductType([ + new ProductTypeElement( + '__identity_bytes', + AlgebraicType.createArrayType(AlgebraicType.createU8Type()) + ), + ]) + ), + new ProductTypeElement( + 'name', + AlgebraicType.createSumType([ + new SumTypeVariant('some', AlgebraicType.createStringType()), + new SumTypeVariant('none', AlgebraicType.createProductType([])), + ]) + ), + new ProductTypeElement('online', AlgebraicType.createBoolType()), + ]); + } - public static findByIdentity(value: Identity): User | undefined - { - return this.filterByIdentity(value).next().value; - } + static fromValue< + DbView, + ReducerView, + ReducerEnum, + EventContext extends DbContext, + >( + client: DBConnectionBase, + value: AlgebraicValue + ): UserTableHandle { + let productValue = value.asProductValue(); + let __identity = productValue.elements[0].asIdentity(); + let __name = + productValue.elements[1].asSumValue().tag == 1 + ? null + : productValue.elements[1].asSumValue().value.asString(); + let __online = productValue.elements[2].asBoolean(); + return new this(client, __identity, __name, __online); + } - public static *filterByOnline(value: boolean): IterableIterator - { - for (let instance of this.db.getTable("User").getInstances()) - { - if (instance.online === value) { - yield instance; - } - } - } + *filterByIdentity(value: Identity): IterableIterator { + for (let instance of this.#client.db.getTable('User').getInstances()) { + if (instance.identity.isEqual(value)) { + yield instance; + } + } + } + findByIdentity(value: Identity): User | undefined { + return this.filterByIdentity(value).next().value; + } + *filterByOnline(value: boolean): IterableIterator { + for (let instance of this.#client.db.getTable('User').getInstances()) { + if (instance.online === value) { + yield instance; + } + } + } } export default User; diff --git a/sdks/typescript/packages/sdk/src/reducer_event.ts b/sdks/typescript/packages/sdk/src/reducer_event.ts index 985771f26..bc289746b 100644 --- a/sdks/typescript/packages/sdk/src/reducer_event.ts +++ b/sdks/typescript/packages/sdk/src/reducer_event.ts @@ -2,7 +2,7 @@ import { Address } from './address.ts'; import type { Timestamp, UpdateStatus } from './client_api.ts'; import { Identity } from './identity.ts'; -export class ReducerEvent { +export class ReducerEvent { /** * The time when the reducer started running. * diff --git a/sdks/typescript/packages/sdk/src/spacetimedb.ts b/sdks/typescript/packages/sdk/src/spacetimedb.ts index 1a0d6dbc7..c79cbecac 100644 --- a/sdks/typescript/packages/sdk/src/spacetimedb.ts +++ b/sdks/typescript/packages/sdk/src/spacetimedb.ts @@ -335,12 +335,6 @@ export class DBConnectionBuilder< } } -// class DBConnection extends DbConnectionBase {} - -// const ctxz = new DbConnection() - -// ctxz. - export class DBConnectionBase< ReducerEnum = {}, EventContext extends DbContext = any, diff --git a/sdks/typescript/packages/sdk/src/table.ts b/sdks/typescript/packages/sdk/src/table.ts index 3cfc038f5..c18e19920 100644 --- a/sdks/typescript/packages/sdk/src/table.ts +++ b/sdks/typescript/packages/sdk/src/table.ts @@ -3,20 +3,13 @@ import BinaryReader from './binary_reader.ts'; import { EventEmitter } from './event_emitter.ts'; import OperationsMap from './operations_map.ts'; import { ReducerEvent } from './reducer_event.ts'; -import { AlgebraicValue, DbContext, type CallbackInit } from './spacetimedb.ts'; +import { AlgebraicValue, type CallbackInit } from './spacetimedb.ts'; -class DBOp { +type DBOp = { type: 'insert' | 'delete'; - instance: any; rowPk: string; - - constructor(type: 'insert' | 'delete', rowPk: string, instance: any) { - this.type = type; - this.rowPk = rowPk; - this.instance = instance; - } -} - + row: any; +}; export class TableOperation { /** * The type of CRUD operation. @@ -94,9 +87,13 @@ export class Table { this.#entityClass.getAlgebraicType(), adapter ); - const instance = this.#entityClass.fromValue(entry); + const row = this.#entityClass.fromValue(entry); - dbOps.push(new DBOp(operation.type, pk, instance)); + dbOps.push({ + type: operation.type, + rowPk: pk, + row: row, + }); } if (this.#entityClass.primaryKey !== undefined) { @@ -107,7 +104,7 @@ export class Table { if (dbOp.type === 'insert') { inserts.push(dbOp); } else { - deleteMap.set(dbOp.instance[pkName], dbOp); + deleteMap.set(dbOp.row[pkName], dbOp); } } for (const dbOp of inserts) { @@ -140,21 +137,21 @@ export class Table { oldDbOp: DBOp, reducerEvent: ReducerEvent | undefined ): void => { - const newInstance = newDbOp.instance; - const oldInstance = oldDbOp.instance; + const newInstance = newDbOp.row; + const oldInstance = oldDbOp.row; this.rows.delete(oldDbOp.rowPk); this.rows.set(newDbOp.rowPk, newInstance); this.emitter.emit('update', oldInstance, newInstance, reducerEvent); }; insert = (dbOp: DBOp, reducerEvent: ReducerEvent | undefined): void => { - this.rows.set(dbOp.rowPk, dbOp.instance); - this.emitter.emit('insert', dbOp.instance, reducerEvent); + this.rows.set(dbOp.rowPk, dbOp.row); + this.emitter.emit('insert', dbOp.row, reducerEvent); }; delete = (dbOp: DBOp, reducerEvent: ReducerEvent | undefined): void => { this.rows.delete(dbOp.rowPk); - this.emitter.emit('delete', dbOp.instance, reducerEvent); + this.emitter.emit('delete', dbOp.row, reducerEvent); }; /**