From 56e00e9f4e22bb5fe91ed501c03c5241cf6f7a52 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 23 Oct 2024 19:21:38 +0200 Subject: [PATCH] websocket: receive ids, not names --- .../src/client_api/after_connecting_type.ts | 83 ++++++++++++++++++ .../sdk/src/client_api/bsatn_row_list_type.ts | 2 + .../sdk/src/client_api/call_reducer_type.ts | 6 +- .../sdk/src/client_api/client_message_type.ts | 2 + .../compressable_query_update_type.ts | 2 + .../src/client_api/database_update_type.ts | 2 + .../sdk/src/client_api/energy_quanta_type.ts | 2 + .../sdk/src/client_api/identity_token_type.ts | 2 + .../sdk/src/client_api/ids_to_names_type.ts | 85 +++++++++++++++++++ packages/sdk/src/client_api/index.ts | 4 + .../client_api/initial_subscription_type.ts | 2 + .../client_api/one_off_query_response_type.ts | 2 + .../sdk/src/client_api/one_off_query_type.ts | 2 + .../sdk/src/client_api/one_off_table_type.ts | 6 +- .../sdk/src/client_api/query_update_type.ts | 2 + .../src/client_api/reducer_call_info_type.ts | 9 +- .../sdk/src/client_api/row_size_hint_type.ts | 2 + .../sdk/src/client_api/server_message_type.ts | 19 +++-- packages/sdk/src/client_api/subscribe_type.ts | 2 + .../sdk/src/client_api/table_update_type.ts | 6 +- packages/sdk/src/client_api/timestamp_type.ts | 2 + .../transaction_update_light_type.ts | 2 + .../src/client_api/transaction_update_type.ts | 2 + .../sdk/src/client_api/update_status_type.ts | 2 + packages/sdk/src/db_connection_impl.ts | 64 +++++++++----- packages/sdk/src/message_types.ts | 21 +++-- packages/sdk/tests/spacetimedb_client.test.ts | 80 ++++++++--------- 27 files changed, 330 insertions(+), 85 deletions(-) create mode 100644 packages/sdk/src/client_api/after_connecting_type.ts create mode 100644 packages/sdk/src/client_api/ids_to_names_type.ts diff --git a/packages/sdk/src/client_api/after_connecting_type.ts b/packages/sdk/src/client_api/after_connecting_type.ts new file mode 100644 index 0000000..1776387 --- /dev/null +++ b/packages/sdk/src/client_api/after_connecting_type.ts @@ -0,0 +1,83 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN RUST INSTEAD. + +import { + // @ts-ignore + Address, + // @ts-ignore + AlgebraicType, + // @ts-ignore + AlgebraicValue, + // @ts-ignore + BinaryReader, + // @ts-ignore + BinaryWriter, + // @ts-ignore + CallReducerFlags, + // @ts-ignore + DBConnectionBuilder, + // @ts-ignore + DBConnectionImpl, + // @ts-ignore + DBContext, + // @ts-ignore + Event, + // @ts-ignore + EventContextInterface, + // @ts-ignore + Identity, + // @ts-ignore + ProductType, + // @ts-ignore + ProductTypeElement, + // @ts-ignore + SumType, + // @ts-ignore + SumTypeVariant, + // @ts-ignore + TableCache, + // @ts-ignore + deepEqual, +} from '..'; +// @ts-ignore +import { IdentityToken as __IdentityToken } from './identity_token_type'; +// @ts-ignore +import { IdsToNames as __IdsToNames } from './ids_to_names_type'; + +export type AfterConnecting = { + identityToken: __IdentityToken; + idsToNames: __IdsToNames; +}; + +/** + * A namespace for generated helper functions. + */ +export namespace AfterConnecting { + /** + * A function which returns this type represented as an AlgebraicType. + * This function is derived from the AlgebraicType used to generate this type. + */ + export function getTypeScriptAlgebraicType(): AlgebraicType { + return AlgebraicType.createProductType([ + new ProductTypeElement( + 'identityToken', + __IdentityToken.getTypeScriptAlgebraicType() + ), + new ProductTypeElement( + 'idsToNames', + __IdsToNames.getTypeScriptAlgebraicType() + ), + ]); + } + + export function serialize( + writer: BinaryWriter, + value: AfterConnecting + ): void { + AfterConnecting.getTypeScriptAlgebraicType().serialize(writer, value); + } + + export function deserialize(reader: BinaryReader): AfterConnecting { + return AfterConnecting.getTypeScriptAlgebraicType().deserialize(reader); + } +} diff --git a/packages/sdk/src/client_api/bsatn_row_list_type.ts b/packages/sdk/src/client_api/bsatn_row_list_type.ts index cf4b2df..6f51a0c 100644 --- a/packages/sdk/src/client_api/bsatn_row_list_type.ts +++ b/packages/sdk/src/client_api/bsatn_row_list_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/call_reducer_type.ts b/packages/sdk/src/client_api/call_reducer_type.ts index 887f3eb..1707b1c 100644 --- a/packages/sdk/src/client_api/call_reducer_type.ts +++ b/packages/sdk/src/client_api/call_reducer_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, @@ -38,7 +40,7 @@ import { deepEqual, } from '..'; export type CallReducer = { - reducer: string; + reducerId: number; args: Uint8Array; requestId: number; flags: number; @@ -54,7 +56,7 @@ export namespace CallReducer { */ export function getTypeScriptAlgebraicType(): AlgebraicType { return AlgebraicType.createProductType([ - new ProductTypeElement('reducer', AlgebraicType.createStringType()), + new ProductTypeElement('reducerId', AlgebraicType.createU32Type()), new ProductTypeElement( 'args', AlgebraicType.createArrayType(AlgebraicType.createU8Type()) diff --git a/packages/sdk/src/client_api/client_message_type.ts b/packages/sdk/src/client_api/client_message_type.ts index 5935dff..bcf0c36 100644 --- a/packages/sdk/src/client_api/client_message_type.ts +++ b/packages/sdk/src/client_api/client_message_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/compressable_query_update_type.ts b/packages/sdk/src/client_api/compressable_query_update_type.ts index 3a24364..2b2d818 100644 --- a/packages/sdk/src/client_api/compressable_query_update_type.ts +++ b/packages/sdk/src/client_api/compressable_query_update_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/database_update_type.ts b/packages/sdk/src/client_api/database_update_type.ts index f0ff9d6..471a48c 100644 --- a/packages/sdk/src/client_api/database_update_type.ts +++ b/packages/sdk/src/client_api/database_update_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/energy_quanta_type.ts b/packages/sdk/src/client_api/energy_quanta_type.ts index 7556883..e8e8858 100644 --- a/packages/sdk/src/client_api/energy_quanta_type.ts +++ b/packages/sdk/src/client_api/energy_quanta_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/identity_token_type.ts b/packages/sdk/src/client_api/identity_token_type.ts index cc42522..9ad2c7e 100644 --- a/packages/sdk/src/client_api/identity_token_type.ts +++ b/packages/sdk/src/client_api/identity_token_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/ids_to_names_type.ts b/packages/sdk/src/client_api/ids_to_names_type.ts new file mode 100644 index 0000000..bc881b8 --- /dev/null +++ b/packages/sdk/src/client_api/ids_to_names_type.ts @@ -0,0 +1,85 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN RUST INSTEAD. + +import { + // @ts-ignore + Address, + // @ts-ignore + AlgebraicType, + // @ts-ignore + AlgebraicValue, + // @ts-ignore + BinaryReader, + // @ts-ignore + BinaryWriter, + // @ts-ignore + CallReducerFlags, + // @ts-ignore + DBConnectionBuilder, + // @ts-ignore + DBConnectionImpl, + // @ts-ignore + DBContext, + // @ts-ignore + Event, + // @ts-ignore + EventContextInterface, + // @ts-ignore + Identity, + // @ts-ignore + ProductType, + // @ts-ignore + ProductTypeElement, + // @ts-ignore + SumType, + // @ts-ignore + SumTypeVariant, + // @ts-ignore + TableCache, + // @ts-ignore + deepEqual, +} from '..'; +export type IdsToNames = { + reducerIds: number[]; + reducerNames: string[]; + tableIds: number[]; + tableNames: string[]; +}; + +/** + * A namespace for generated helper functions. + */ +export namespace IdsToNames { + /** + * A function which returns this type represented as an AlgebraicType. + * This function is derived from the AlgebraicType used to generate this type. + */ + export function getTypeScriptAlgebraicType(): AlgebraicType { + return AlgebraicType.createProductType([ + new ProductTypeElement( + 'reducerIds', + AlgebraicType.createArrayType(AlgebraicType.createU32Type()) + ), + new ProductTypeElement( + 'reducerNames', + AlgebraicType.createArrayType(AlgebraicType.createStringType()) + ), + new ProductTypeElement( + 'tableIds', + AlgebraicType.createArrayType(AlgebraicType.createU32Type()) + ), + new ProductTypeElement( + 'tableNames', + AlgebraicType.createArrayType(AlgebraicType.createStringType()) + ), + ]); + } + + export function serialize(writer: BinaryWriter, value: IdsToNames): void { + IdsToNames.getTypeScriptAlgebraicType().serialize(writer, value); + } + + export function deserialize(reader: BinaryReader): IdsToNames { + return IdsToNames.getTypeScriptAlgebraicType().deserialize(reader); + } +} diff --git a/packages/sdk/src/client_api/index.ts b/packages/sdk/src/client_api/index.ts index 1e16e88..488f28b 100644 --- a/packages/sdk/src/client_api/index.ts +++ b/packages/sdk/src/client_api/index.ts @@ -45,6 +45,8 @@ import { // Import and reexport all table handle types // Import and reexport all types +import { AfterConnecting } from './after_connecting_type.ts'; +export { AfterConnecting }; import { BsatnRowList } from './bsatn_row_list_type.ts'; export { BsatnRowList }; import { CallReducer } from './call_reducer_type.ts'; @@ -59,6 +61,8 @@ import { EnergyQuanta } from './energy_quanta_type.ts'; export { EnergyQuanta }; import { IdentityToken } from './identity_token_type.ts'; export { IdentityToken }; +import { IdsToNames } from './ids_to_names_type.ts'; +export { IdsToNames }; import { InitialSubscription } from './initial_subscription_type.ts'; export { InitialSubscription }; import { OneOffQuery } from './one_off_query_type.ts'; diff --git a/packages/sdk/src/client_api/initial_subscription_type.ts b/packages/sdk/src/client_api/initial_subscription_type.ts index 4a3196c..1119b41 100644 --- a/packages/sdk/src/client_api/initial_subscription_type.ts +++ b/packages/sdk/src/client_api/initial_subscription_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/one_off_query_response_type.ts b/packages/sdk/src/client_api/one_off_query_response_type.ts index f72d9ff..794f33b 100644 --- a/packages/sdk/src/client_api/one_off_query_response_type.ts +++ b/packages/sdk/src/client_api/one_off_query_response_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/one_off_query_type.ts b/packages/sdk/src/client_api/one_off_query_type.ts index 4f81811..3d032a8 100644 --- a/packages/sdk/src/client_api/one_off_query_type.ts +++ b/packages/sdk/src/client_api/one_off_query_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/one_off_table_type.ts b/packages/sdk/src/client_api/one_off_table_type.ts index 4fb6cb2..10c9737 100644 --- a/packages/sdk/src/client_api/one_off_table_type.ts +++ b/packages/sdk/src/client_api/one_off_table_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, @@ -41,7 +43,7 @@ import { import { BsatnRowList as __BsatnRowList } from './bsatn_row_list_type'; export type OneOffTable = { - tableName: string; + tableId: number; rows: __BsatnRowList; }; @@ -55,7 +57,7 @@ export namespace OneOffTable { */ export function getTypeScriptAlgebraicType(): AlgebraicType { return AlgebraicType.createProductType([ - new ProductTypeElement('tableName', AlgebraicType.createStringType()), + new ProductTypeElement('tableId', AlgebraicType.createU32Type()), new ProductTypeElement( 'rows', __BsatnRowList.getTypeScriptAlgebraicType() diff --git a/packages/sdk/src/client_api/query_update_type.ts b/packages/sdk/src/client_api/query_update_type.ts index 8813286..a4672f2 100644 --- a/packages/sdk/src/client_api/query_update_type.ts +++ b/packages/sdk/src/client_api/query_update_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/reducer_call_info_type.ts b/packages/sdk/src/client_api/reducer_call_info_type.ts index 1dc295e..2e21a1a 100644 --- a/packages/sdk/src/client_api/reducer_call_info_type.ts +++ b/packages/sdk/src/client_api/reducer_call_info_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, @@ -38,8 +40,8 @@ import { deepEqual, } from '..'; export type ReducerCallInfo = { - reducerName: string; reducerId: number; + reducerName: void; args: Uint8Array; requestId: number; }; @@ -54,8 +56,11 @@ export namespace ReducerCallInfo { */ export function getTypeScriptAlgebraicType(): AlgebraicType { return AlgebraicType.createProductType([ - new ProductTypeElement('reducerName', AlgebraicType.createStringType()), new ProductTypeElement('reducerId', AlgebraicType.createU32Type()), + new ProductTypeElement( + 'reducerName', + AlgebraicType.createProductType([]) + ), new ProductTypeElement( 'args', AlgebraicType.createArrayType(AlgebraicType.createU8Type()) diff --git a/packages/sdk/src/client_api/row_size_hint_type.ts b/packages/sdk/src/client_api/row_size_hint_type.ts index 15abc5b..3a4867a 100644 --- a/packages/sdk/src/client_api/row_size_hint_type.ts +++ b/packages/sdk/src/client_api/row_size_hint_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/server_message_type.ts b/packages/sdk/src/client_api/server_message_type.ts index 54d83cc..4cad6e4 100644 --- a/packages/sdk/src/client_api/server_message_type.ts +++ b/packages/sdk/src/client_api/server_message_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, @@ -44,7 +46,7 @@ import { TransactionUpdate as __TransactionUpdate } from './transaction_update_t // @ts-ignore import { TransactionUpdateLight as __TransactionUpdateLight } from './transaction_update_light_type'; // @ts-ignore -import { IdentityToken as __IdentityToken } from './identity_token_type'; +import { AfterConnecting as __AfterConnecting } from './after_connecting_type'; // @ts-ignore import { OneOffQueryResponse as __OneOffQueryResponse } from './one_off_query_response_type'; @@ -65,7 +67,10 @@ export namespace ServerMessage { tag: 'TransactionUpdateLight'; value: __TransactionUpdateLight; }; - export type IdentityToken = { tag: 'IdentityToken'; value: __IdentityToken }; + export type AfterConnecting = { + tag: 'AfterConnecting'; + value: __AfterConnecting; + }; export type OneOffQueryResponse = { tag: 'OneOffQueryResponse'; value: __OneOffQueryResponse; @@ -86,8 +91,8 @@ export namespace ServerMessage { export const TransactionUpdateLight = ( value: __TransactionUpdateLight ): ServerMessage => ({ tag: 'TransactionUpdateLight', value }); - export const IdentityToken = (value: __IdentityToken): ServerMessage => ({ - tag: 'IdentityToken', + export const AfterConnecting = (value: __AfterConnecting): ServerMessage => ({ + tag: 'AfterConnecting', value, }); export const OneOffQueryResponse = ( @@ -109,8 +114,8 @@ export namespace ServerMessage { __TransactionUpdateLight.getTypeScriptAlgebraicType() ), new SumTypeVariant( - 'IdentityToken', - __IdentityToken.getTypeScriptAlgebraicType() + 'AfterConnecting', + __AfterConnecting.getTypeScriptAlgebraicType() ), new SumTypeVariant( 'OneOffQueryResponse', @@ -133,7 +138,7 @@ export type ServerMessage = | ServerMessage.InitialSubscription | ServerMessage.TransactionUpdate | ServerMessage.TransactionUpdateLight - | ServerMessage.IdentityToken + | ServerMessage.AfterConnecting | ServerMessage.OneOffQueryResponse; export default ServerMessage; diff --git a/packages/sdk/src/client_api/subscribe_type.ts b/packages/sdk/src/client_api/subscribe_type.ts index 7637646..2bbcbc9 100644 --- a/packages/sdk/src/client_api/subscribe_type.ts +++ b/packages/sdk/src/client_api/subscribe_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/table_update_type.ts b/packages/sdk/src/client_api/table_update_type.ts index 5aacae3..b52e9b5 100644 --- a/packages/sdk/src/client_api/table_update_type.ts +++ b/packages/sdk/src/client_api/table_update_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, @@ -42,7 +44,7 @@ import { CompressableQueryUpdate as __CompressableQueryUpdate } from './compress export type TableUpdate = { tableId: number; - tableName: string; + tableName: void; numRows: bigint; updates: __CompressableQueryUpdate[]; }; @@ -58,7 +60,7 @@ export namespace TableUpdate { export function getTypeScriptAlgebraicType(): AlgebraicType { return AlgebraicType.createProductType([ new ProductTypeElement('tableId', AlgebraicType.createU32Type()), - new ProductTypeElement('tableName', AlgebraicType.createStringType()), + new ProductTypeElement('tableName', AlgebraicType.createProductType([])), new ProductTypeElement('numRows', AlgebraicType.createU64Type()), new ProductTypeElement( 'updates', diff --git a/packages/sdk/src/client_api/timestamp_type.ts b/packages/sdk/src/client_api/timestamp_type.ts index e9c5e74..018d85c 100644 --- a/packages/sdk/src/client_api/timestamp_type.ts +++ b/packages/sdk/src/client_api/timestamp_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/transaction_update_light_type.ts b/packages/sdk/src/client_api/transaction_update_light_type.ts index d8c4e2a..7946f67 100644 --- a/packages/sdk/src/client_api/transaction_update_light_type.ts +++ b/packages/sdk/src/client_api/transaction_update_light_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/transaction_update_type.ts b/packages/sdk/src/client_api/transaction_update_type.ts index 3a4808b..aa7da4c 100644 --- a/packages/sdk/src/client_api/transaction_update_type.ts +++ b/packages/sdk/src/client_api/transaction_update_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/client_api/update_status_type.ts b/packages/sdk/src/client_api/update_status_type.ts index cc8fc90..7e8a591 100644 --- a/packages/sdk/src/client_api/update_status_type.ts +++ b/packages/sdk/src/client_api/update_status_type.ts @@ -13,6 +13,8 @@ import { // @ts-ignore BinaryWriter, // @ts-ignore + CallReducerFlags, + // @ts-ignore DBConnectionBuilder, // @ts-ignore DBConnectionImpl, diff --git a/packages/sdk/src/db_connection_impl.ts b/packages/sdk/src/db_connection_impl.ts index 8998ef3..6a3bb6e 100644 --- a/packages/sdk/src/db_connection_impl.ts +++ b/packages/sdk/src/db_connection_impl.ts @@ -24,7 +24,7 @@ import { type EventContextInterface } from './event_context.ts'; import { EventEmitter } from './event_emitter.ts'; import { decompress } from './decompress.ts'; import type { Identity } from './identity.ts'; -import type { IdentityTokenMessage, Message } from './message_types.ts'; +import type { AfterConnectingMessage, Message } from './message_types.ts'; import type { ReducerEvent } from './reducer_event.ts'; import type SpacetimeModule from './spacetime_module.ts'; import { TableCache, type Operation, type TableUpdate } from './table_cache.ts'; @@ -101,6 +101,10 @@ export class DBConnectionImpl< #messageQueue = Promise.resolve(); + #tableIdToName: { [tableId: number]: string } = {}; + #reducerIdToName: { [reducerId: number]: string } = {}; + #reducerNameToId: { [reducerName: string]: number } = {}; + constructor(remoteModule: SpacetimeModule, emitter: EventEmitter) { this.clientCache = new ClientCache(); this.#emitter = emitter; @@ -164,7 +168,7 @@ export class DBConnectionImpl< const parseTableUpdate = async ( rawTableUpdate: ws.TableUpdate ): Promise => { - const tableName = rawTableUpdate.tableName; + const tableName = this.#tableIdToName[rawTableUpdate.tableId]; let operations: Operation[] = []; for (const update of rawTableUpdate.updates) { let decompressed: ws.QueryUpdate; @@ -229,8 +233,7 @@ export class DBConnectionImpl< const txUpdate = message.value; const identity = txUpdate.callerIdentity; const address = Address.nullIfZero(txUpdate.callerAddress); - const originalReducerName = txUpdate.reducerCall.reducerName; - const reducerName: string = toPascalCase(originalReducerName); + const reducerId = txUpdate.reducerCall.reducerId; const args = txUpdate.reducerCall.args; const energyQuantaUsed = txUpdate.energyQuantaUsed; @@ -253,8 +256,7 @@ export class DBConnectionImpl< tableUpdates, identity, address, - originalReducerName, - reducerName, + reducerId, args, status: txUpdate.status, energyConsumed: energyQuantaUsed.quanta, @@ -265,14 +267,15 @@ export class DBConnectionImpl< break; } - case 'IdentityToken': { - const identityTokenMessage: IdentityTokenMessage = { - tag: 'IdentityToken', - identity: message.value.identity, - token: message.value.token, - address: message.value.address, + case 'AfterConnecting': { + const identityToken = message.value.identityToken; + const idsToNames = message.value.idsToNames; + const afterConnectingMessage: AfterConnectingMessage = { + tag: 'AfterConnecting', + idsToNames: idsToNames, + identityToken: identityToken, }; - callback(identityTokenMessage); + callback(afterConnectingMessage); break; } @@ -347,7 +350,7 @@ export class DBConnectionImpl< flags: CallReducerFlags ): void { const message = ws.ClientMessage.CallReducer({ - reducer: reducerName, + reducerId: this.#reducerNameToId[reducerName], args: argsBuffer, // The TypeScript SDK doesn't currently track `request_id`s, // so always use 0. @@ -357,7 +360,7 @@ export class DBConnectionImpl< this.#sendMessage(message); } - /**s + /** * Handles WebSocket onOpen event. */ handleOnOpen(): void { @@ -403,10 +406,11 @@ export class DBConnectionImpl< ); this.#applyTableUpdates(message.tableUpdates, eventContext); } else if (message.tag === 'TransactionUpdate') { - const reducerName = message.originalReducerName; + const reducerId = message.reducerId; + const reducerName = this.#reducerIdToName[reducerId]; const reducerTypeInfo = this.remoteModule.reducers[reducerName]!; - if (reducerName == '') { + if (reducerId == 4294967295 /* u32::MAX */) { let errorMessage = message.message; console.error( `Received an error from the database: ${errorMessage}` @@ -441,12 +445,28 @@ export class DBConnectionImpl< ); this.#reducerEmitter.emit(reducerName, eventContext, ...argsArray); } - } else if (message.tag === 'IdentityToken') { - this.identity = message.identity; - if (!this.token && message.token) { - this.token = message.token; + } else if (message.tag === 'AfterConnecting') { + const idsToNames = message.idsToNames; + // TODO: validate that table and reducer names match with actual. + for (let index = 0; index < idsToNames.reducerIds.length; index++) { + const id = idsToNames.reducerIds[index]; + const name = idsToNames.reducerNames[index]; + this.#reducerIdToName[id] = name; + this.#reducerNameToId[name] = id; + } + for (let index = 0; index < idsToNames.tableIds.length; index++) { + const id = idsToNames.tableIds[index]; + const name = idsToNames.tableNames[index]; + this.#tableIdToName[id] = name; } - this.clientAddress = message.address; + + const identityToken = message.identityToken; + this.identity = identityToken.identity; + if (!this.token && identityToken.token) { + this.token = identityToken.token; + } + this.clientAddress = identityToken.address; + this.#emitter.emit('connect', this, this.identity, this.token); } }) diff --git a/packages/sdk/src/message_types.ts b/packages/sdk/src/message_types.ts index 13f5fb2..d392d57 100644 --- a/packages/sdk/src/message_types.ts +++ b/packages/sdk/src/message_types.ts @@ -1,5 +1,10 @@ import { Address } from './address.ts'; -import type { Timestamp, UpdateStatus } from './client_api/index.ts'; +import type { + Timestamp, + UpdateStatus, + IdentityToken, + IdsToNames, +} from './client_api/index.ts'; import { Identity } from './identity.ts'; import type { TableUpdate } from './table_cache.ts'; @@ -13,8 +18,7 @@ export type TransactionUpdateMessage = { tableUpdates: TableUpdate[]; identity: Identity; address: Address | null; - originalReducerName: string; - reducerName: string; + reducerId: number; args: Uint8Array; status: UpdateStatus; message: string; @@ -27,15 +31,14 @@ export type TransactionUpdateLightMessage = { tableUpdates: TableUpdate[]; }; -export type IdentityTokenMessage = { - tag: 'IdentityToken'; - identity: Identity; - token: string; - address: Address; +export type AfterConnectingMessage = { + tag: 'AfterConnecting'; + identityToken: IdentityToken; + idsToNames: IdsToNames; }; export type Message = | InitialSubscriptionMessage | TransactionUpdateMessage | TransactionUpdateLightMessage - | IdentityTokenMessage; + | AfterConnectingMessage; diff --git a/packages/sdk/tests/spacetimedb_client.test.ts b/packages/sdk/tests/spacetimedb_client.test.ts index 81c3c33..c8d2c97 100644 --- a/packages/sdk/tests/spacetimedb_client.test.ts +++ b/packages/sdk/tests/spacetimedb_client.test.ts @@ -87,6 +87,24 @@ function encodeCreatePlayerArgs(name: string, location: Point): Uint8Array { return writer.getBuffer(); } +function after_connecting_msg(identity: Identity): ws.ServerMessage { + const identityToken = { + identity, + token: 'a-token', + address: Address.random(), + }; + const idsToNames = { + reducerIds: [0], + reducerNames: ['create_player'], + tableIds: [35, 36, 37], + tableNames: ['Player', 'Point', 'User'], + }; + return ws.ServerMessage.AfterConnecting({ + identityToken, + idsToNames, + }); +} + describe('SpacetimeDBClient', () => { test('auto subscribe on connect', async () => { const wsAdapter = new WebsocketTestAdapter(); @@ -147,12 +165,7 @@ describe('SpacetimeDBClient', () => { await client.wsPromise; wsAdapter.acceptConnection(); - const tokenMessage = ws.ServerMessage.IdentityToken({ - identity: anIdentity, - token: 'a-token', - address: Address.random(), - }); - wsAdapter.sendToClient(tokenMessage); + wsAdapter.sendToClient(after_connecting_msg(anIdentity)); await onConnectPromise.promise; @@ -174,12 +187,7 @@ describe('SpacetimeDBClient', () => { await client.wsPromise; wsAdapter.acceptConnection(); - const tokenMessage = ws.ServerMessage.IdentityToken({ - identity: anIdentity, - token: 'a-token', - address: Address.random(), - }); - wsAdapter.sendToClient(tokenMessage); + wsAdapter.sendToClient(after_connecting_msg(anIdentity)); const inserts: { reducerEvent: @@ -225,7 +233,7 @@ describe('SpacetimeDBClient', () => { tables: [ { tableId: 35, - tableName: 'player', + tableName: undefined, numRows: BigInt(1), updates: [ ws.CompressableQueryUpdate.Uncompressed({ @@ -263,7 +271,7 @@ describe('SpacetimeDBClient', () => { tables: [ { tableId: 35, - tableName: 'player', + tableName: undefined, numRows: BigInt(2), updates: [ ws.CompressableQueryUpdate.Uncompressed({ @@ -288,7 +296,7 @@ describe('SpacetimeDBClient', () => { callerIdentity: anIdentity, callerAddress: Address.random(), reducerCall: { - reducerName: 'create_player', + reducerName: undefined, reducerId: 0, args: encodeCreatePlayerArgs('A Player', { x: 2, y: 3 }), requestId: 0, @@ -332,12 +340,7 @@ describe('SpacetimeDBClient', () => { await client.wsPromise; wsAdapter.acceptConnection(); - const tokenMessage = ws.ServerMessage.IdentityToken({ - identity: anIdentity, - token: 'a-token', - address: Address.random(), - }); - wsAdapter.sendToClient(tokenMessage); + wsAdapter.sendToClient(after_connecting_msg(anIdentity)); const update1Promise = new Deferred(); const update2Promise = new Deferred(); @@ -361,7 +364,7 @@ describe('SpacetimeDBClient', () => { tables: [ { tableId: 35, - tableName: 'player', + tableName: undefined, numRows: BigInt(2), updates: [ ws.CompressableQueryUpdate.Uncompressed({ @@ -407,7 +410,7 @@ describe('SpacetimeDBClient', () => { tables: [ { tableId: 35, - tableName: 'player', + tableName: undefined, numRows: BigInt(2), updates: [ ws.CompressableQueryUpdate.Uncompressed({ @@ -436,7 +439,7 @@ describe('SpacetimeDBClient', () => { callerIdentity: anIdentity, callerAddress: Address.random(), reducerCall: { - reducerName: 'create_player', + reducerName: undefined, reducerId: 0, args: encodeCreatePlayerArgs('A Player', { x: 2, y: 3 }), requestId: 0, @@ -490,7 +493,7 @@ describe('SpacetimeDBClient', () => { tables: [ { tableId: 35, - tableName: 'player', + tableName: undefined, numRows: BigInt(1), updates: [ ws.CompressableQueryUpdate.Uncompressed({ @@ -518,7 +521,7 @@ describe('SpacetimeDBClient', () => { callerIdentity: anIdentity, callerAddress: Address.random(), reducerCall: { - reducerName: 'create_player', + reducerName: undefined, reducerId: 0, args: encodeCreatePlayerArgs('A Player', { x: 2, y: 3 }), requestId: 0, @@ -548,14 +551,13 @@ describe('SpacetimeDBClient', () => { await client.wsPromise; wsAdapter.acceptConnection(); - const tokenMessage = ws.ServerMessage.IdentityToken({ - identity: Identity.fromString( - '0000000000000000000000000000000000000000000000000000000000000069' - ), - token: 'a-token', - address: Address.random(), - }); - wsAdapter.sendToClient(tokenMessage); + wsAdapter.sendToClient( + after_connecting_msg( + Identity.fromString( + '0000000000000000000000000000000000000000000000000000000000000069' + ) + ) + ); const update1Promise = new Deferred(); const update2Promise = new Deferred(); @@ -578,8 +580,8 @@ describe('SpacetimeDBClient', () => { databaseUpdate: { tables: [ { - tableId: 35, - tableName: 'user', + tableId: 37, + tableName: undefined, numRows: BigInt(1), updates: [ // pgoldman 2024-06-25: This is weird, `InitialSubscription`s aren't supposed to contain deletes or updates. @@ -628,8 +630,8 @@ describe('SpacetimeDBClient', () => { status: ws.UpdateStatus.Committed({ tables: [ { - tableId: 35, - tableName: 'user', + tableId: 37, + tableName: undefined, numRows: BigInt(1), updates: [ ws.CompressableQueryUpdate.Uncompressed({ @@ -665,7 +667,7 @@ describe('SpacetimeDBClient', () => { callerIdentity: anIdentity, callerAddress: Address.random(), reducerCall: { - reducerName: 'create_player', + reducerName: undefined, reducerId: 0, args: encodeCreatePlayerArgs('A Player', { x: 2, y: 3 }), requestId: 0,