From f71cddee95c41e4999f1d4a5ce9cb4da1b79239f Mon Sep 17 00:00:00 2001 From: Derek Brinkmann Date: Fri, 21 Jul 2023 12:10:17 -0400 Subject: [PATCH 1/2] Change Identity from UInt8Array to Identity to match other SDKs --- src/identity.ts | 40 ++++++++++++++++++++++++++++++++++++++++ src/index.ts | 1 + src/spacetimedb.ts | 30 ++++++++++++++---------------- 3 files changed, 55 insertions(+), 16 deletions(-) create mode 100644 src/identity.ts diff --git a/src/identity.ts b/src/identity.ts new file mode 100644 index 0000000..4170ffd --- /dev/null +++ b/src/identity.ts @@ -0,0 +1,40 @@ +export class Identity { + private data: Uint8Array; + + constructor(data: Uint8Array) { + this.data = data; + } + + // Method to compare two identities + isEqual(other: Identity): boolean { + if (this.data.length !== other.data.length) { + return false; + } + for (let i = 0; i < this.data.length; i++) { + if (this.data[i] !== other.data[i]) { + return false; + } + } + return true; + } + + // Method to convert the Uint8Array to a hex string + toHexString(): string { + return Array.prototype.map + .call(this.data, (x) => ("00" + x.toString(16)).slice(-2)) + .join(""); + } + + toUint8Array(): Uint8Array { + return this.data; + } + + // Static method to create an Identity from a hex string + static fromString(str: string): Identity { + let matches = str.match(/.{1,2}/g) || []; + let data = Uint8Array.from( + matches.map((byte: string) => parseInt(byte, 16)) + ); + return new Identity(data); + } +} diff --git a/src/index.ts b/src/index.ts index 0e5af11..772c4f0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,2 @@ export * from "./spacetimedb"; +export * from "./identity"; diff --git a/src/spacetimedb.ts b/src/spacetimedb.ts index 1c6d800..9f23508 100644 --- a/src/spacetimedb.ts +++ b/src/spacetimedb.ts @@ -24,6 +24,7 @@ import { BuiltinType, } from "./algebraic_type"; import { EventType } from "./types"; +import { Identity } from "./identity"; import { Message as ProtobufMessage, event_StatusToJSON, @@ -73,14 +74,14 @@ export class Reducer {} export class IDatabaseTable {} export class ReducerEvent { - public callerIdentity: Uint8Array; + public callerIdentity: Identity; public reducerName: string; public status: string; public message: string; public args: any; constructor( - callerIdentity: Uint8Array, + callerIdentity: Identity, reducerName: string, status: string, message: string, @@ -357,7 +358,7 @@ class SubscriptionUpdateMessage { } class TransactionUpdateEvent { - public identity: Uint8Array; + public identity: Identity; public originalReducerName: string; public reducerName: string; public args: any[] | Uint8Array; @@ -365,7 +366,7 @@ class TransactionUpdateEvent { public message: string; constructor( - identity: Uint8Array, + identity: Identity, originalReducerName: string, reducerName: string, args: any[] | Uint8Array, @@ -392,10 +393,10 @@ class TransactionUpdateMessage { } class IdentityTokenMessage { - public identity: Uint8Array; + public identity: Identity; public token: string; - constructor(identity: Uint8Array, token: string) { + constructor(identity: Identity, token: string) { this.identity = identity; this.token = token; } @@ -422,7 +423,7 @@ export class SpacetimeDBClient { /** * The identity of the user. */ - identity?: Uint8Array = undefined; + identity?: Identity = undefined; /** * The token of the user. */ @@ -630,8 +631,7 @@ export class SpacetimeDBClient { if (reducer) { this.emitter.emit( "reducer:" + reducerName, - message.event.status, - message.event.identity, + reducerEvent, reducerArgs ); } @@ -813,7 +813,7 @@ export class SpacetimeDBClient { const event = message["transactionUpdate"]["event"] as any; const functionCall = event["functionCall"] as any; - const identity: Uint8Array = event["callerIdentity"]; + const identity: Identity = new Identity(event["callerIdentity"]); const originalReducerName: string = functionCall["reducer"]; const reducerName: string = toPascalCase(originalReducerName); const args = functionCall["argBytes"]; @@ -837,7 +837,7 @@ export class SpacetimeDBClient { callback(transactionUpdate); } else if (message["identityToken"]) { const identityToken = message["identityToken"] as any; - const identity = identityToken["identity"]; + const identity = new Identity(identityToken["identity"]); const token = identityToken["token"]; const identityTokenMessage: IdentityTokenMessage = new IdentityTokenMessage(identity, token); @@ -890,10 +890,8 @@ export class SpacetimeDBClient { const event = txUpdate["event"] as any; const functionCall = event["function_call"] as any; - const identity: Uint8Array = Uint8Array.from( + const identity: Identity = Identity.fromString( event["caller_identity"] - .match(/.{1,2}/g) - .map((byte: string) => parseInt(byte, 16)) ); const originalReducerName: string = functionCall["reducer"]; const reducerName: string = toPascalCase(originalReducerName); @@ -918,7 +916,7 @@ export class SpacetimeDBClient { callback(transactionUpdate); } else if (data["IdentityToken"]) { const identityToken = data["IdentityToken"]; - const identity = identityToken["identity"]; + const identity = new Identity(identityToken["identity"]); const token = identityToken["token"]; const identityTokenMessage: IdentityTokenMessage = new IdentityTokenMessage(identity, token); @@ -1014,7 +1012,7 @@ export class SpacetimeDBClient { this.emitter.off(eventName, callback); } - onConnect(callback: (token: string, identity: Uint8Array) => void) { + onConnect(callback: (token: string, identity: Identity) => void) { this.on("connected", callback); } From cf76480b601d5e23af91a16db00a7ee28abe8037 Mon Sep 17 00:00:00 2001 From: Derek Brinkmann Date: Wed, 26 Jul 2023 14:47:09 -0400 Subject: [PATCH 2/2] Fix typescript test --- tests/spacetimedb_client.test.ts | 19 +++++++++---------- tests/types/create_player_reducer.ts | 4 +++- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/tests/spacetimedb_client.test.ts b/tests/spacetimedb_client.test.ts index 7ba63c1..32abb05 100644 --- a/tests/spacetimedb_client.test.ts +++ b/tests/spacetimedb_client.test.ts @@ -1,4 +1,5 @@ import { SpacetimeDBClient, ReducerEvent } from "../src/spacetimedb"; +import { Identity } from "../src/identity"; import WebsocketTestAdapter from "../src/websocket_test_adapter"; import Player from "./types/player"; import Point from "./types/point"; @@ -112,15 +113,12 @@ describe("SpacetimeDBClient", () => { ); let reducerCallbackLog: { - status: string; - identity: Uint8Array; + reducerEvent: ReducerEvent; reducerArgs: any[]; }[] = []; - CreatePlayerReducer.on( - (status: string, identity: Uint8Array, reducerArgs: any[]) => { - reducerCallbackLog.push({ status, identity, reducerArgs }); - } - ); + CreatePlayerReducer.on((reducerEvent: ReducerEvent, reducerArgs: any[]) => { + reducerCallbackLog.push({ reducerEvent, reducerArgs }); + }); const subscriptionMessage = { SubscriptionUpdate: { @@ -183,7 +181,7 @@ describe("SpacetimeDBClient", () => { expect(inserts[1].reducerEvent?.status).toBe("committed"); expect(inserts[1].reducerEvent?.message).toBe("a message"); expect(inserts[1].reducerEvent?.callerIdentity).toEqual( - Uint8Array.from([0, 255, 1]) + Identity.fromString("00FF01") ); expect(inserts[1].reducerEvent?.args).toEqual([ "A Player", @@ -191,8 +189,9 @@ describe("SpacetimeDBClient", () => { ]); expect(reducerCallbackLog).toHaveLength(1); - expect(reducerCallbackLog[0]["identity"]).toEqual( - Uint8Array.from([0, 255, 1]) + + expect(reducerCallbackLog[0]["reducerEvent"]["callerIdentity"]).toEqual( + Identity.fromString("00FF01") ); }); diff --git a/tests/types/create_player_reducer.ts b/tests/types/create_player_reducer.ts index 20bfe84..b4250d2 100644 --- a/tests/types/create_player_reducer.ts +++ b/tests/types/create_player_reducer.ts @@ -11,6 +11,8 @@ import { IDatabaseTable, AlgebraicValue, ReducerArgsAdapter, + ReducerEvent, + Identity, } from "../../src/index"; // @ts-ignore import { Point } from "./point"; @@ -32,7 +34,7 @@ export class CreatePlayerReducer { } public static on( - callback: (status: string, identity: Uint8Array, reducerArgs: any[]) => void + callback: (reducerEvent: ReducerEvent, reducerArgs: any[]) => void ) { if (__SPACETIMEDB__.spacetimeDBClient) { __SPACETIMEDB__.spacetimeDBClient.on("reducer:CreatePlayer", callback);