@kokimoki/app 3.1.3 → 3.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +1 -2
  2. package/dist/core/kokimoki-client.d.ts +4 -4
  3. package/dist/core/kokimoki-client.js +4 -4
  4. package/dist/index.d.ts +1 -2
  5. package/dist/index.js +1 -2
  6. package/dist/utils/valtio.d.ts +2 -5
  7. package/dist/utils/valtio.js +4 -2
  8. package/dist/version.d.ts +1 -1
  9. package/dist/version.js +1 -1
  10. package/docs/kokimoki-ai.instructions.md +4 -2
  11. package/docs/kokimoki-dynamic-stores.instructions.md +3 -3
  12. package/docs/kokimoki-i18n.instructions.md +1 -1
  13. package/docs/kokimoki-sdk.instructions.md +46 -7
  14. package/package.json +15 -2
  15. package/dist/fields.d.ts +0 -110
  16. package/dist/fields.js +0 -158
  17. package/dist/kokimoki-ai.d.ts +0 -153
  18. package/dist/kokimoki-ai.js +0 -164
  19. package/dist/kokimoki-awareness.d.ts +0 -21
  20. package/dist/kokimoki-awareness.js +0 -48
  21. package/dist/kokimoki-client-refactored.d.ts +0 -80
  22. package/dist/kokimoki-client-refactored.js +0 -400
  23. package/dist/kokimoki-client.d.ts +0 -362
  24. package/dist/kokimoki-client.js +0 -823
  25. package/dist/kokimoki-leaderboard.d.ts +0 -175
  26. package/dist/kokimoki-leaderboard.js +0 -203
  27. package/dist/kokimoki-local-store.d.ts +0 -11
  28. package/dist/kokimoki-local-store.js +0 -40
  29. package/dist/kokimoki-queue.d.ts +0 -0
  30. package/dist/kokimoki-queue.js +0 -38
  31. package/dist/kokimoki-req-res.d.ts +0 -0
  32. package/dist/kokimoki-req-res.js +0 -198
  33. package/dist/kokimoki-schema.d.ts +0 -113
  34. package/dist/kokimoki-schema.js +0 -162
  35. package/dist/kokimoki-storage.d.ts +0 -156
  36. package/dist/kokimoki-storage.js +0 -208
  37. package/dist/kokimoki-store.d.ts +0 -23
  38. package/dist/kokimoki-store.js +0 -117
  39. package/dist/kokimoki-transaction.d.ts +0 -18
  40. package/dist/kokimoki-transaction.js +0 -143
  41. package/dist/kokimoki.min.d.ts +0 -1244
  42. package/dist/kokimoki.min.js +0 -19108
  43. package/dist/kokimoki.min.js.map +0 -1
  44. package/dist/llms.txt +0 -665
  45. package/dist/message-queue.d.ts +0 -8
  46. package/dist/message-queue.js +0 -19
  47. package/dist/room-subscription-mode.d.ts +0 -5
  48. package/dist/room-subscription-mode.js +0 -6
  49. package/dist/room-subscription.d.ts +0 -15
  50. package/dist/room-subscription.js +0 -52
  51. package/dist/synced-schema.d.ts +0 -74
  52. package/dist/synced-schema.js +0 -83
  53. package/dist/synced-store.d.ts +0 -10
  54. package/dist/synced-store.js +0 -9
  55. package/dist/synced-types.d.ts +0 -47
  56. package/dist/synced-types.js +0 -67
  57. package/dist/ws-message-reader.d.ts +0 -11
  58. package/dist/ws-message-reader.js +0 -36
  59. package/dist/ws-message-type copy.d.ts +0 -6
  60. package/dist/ws-message-type copy.js +0 -7
  61. package/dist/ws-message-type.d.ts +0 -11
  62. package/dist/ws-message-type.js +0 -12
  63. package/dist/ws-message-writer.d.ts +0 -9
  64. package/dist/ws-message-writer.js +0 -45
@@ -1,175 +0,0 @@
1
- import { KokimokiClient } from "./kokimoki-client";
2
- import { Paginated } from "./types/common";
3
- /**
4
- * Kokimoki Leaderboard Service
5
- *
6
- * Provides efficient player ranking and score tracking with database indexes and optimized queries.
7
- * Ideal for games with large numbers of players and competitive scoring.
8
- *
9
- * **Key Features:**
10
- * - Efficient ranking with database indexes
11
- * - Support for ascending (lowest-is-best) and descending (highest-is-best) sorting
12
- * - Pagination for large leaderboards
13
- * - Public and private metadata for entries
14
- * - Insert (preserve all attempts) or upsert (keep latest only) modes
15
- *
16
- * **When to use Leaderboard API vs Global Store:**
17
- *
18
- * Use the **Leaderboard API** when:
19
- * - You have a large number of entries (hundreds to thousands of players)
20
- * - You need efficient ranking and sorting with database indexes
21
- * - You want pagination and optimized queries for top scores
22
- * - Memory and network efficiency are important
23
- *
24
- * Use a **Global Store** when:
25
- * - You have a small number of players (typically under 100)
26
- * - You need real-time updates and live leaderboard changes
27
- * - You want to combine player scores with other game state
28
- * - The leaderboard is temporary (session-based or reset frequently)
29
- *
30
- * Access via `kmClient.leaderboard`
31
- *
32
- * @example
33
- * ```typescript
34
- * // Submit a high score
35
- * const { rank } = await kmClient.leaderboard.upsertEntry(
36
- * 'high-scores',
37
- * 'desc',
38
- * 1500,
39
- * { playerName: 'Alice' },
40
- * {}
41
- * );
42
- *
43
- * // Get top 10
44
- * const { items } = await kmClient.leaderboard.listEntries('high-scores', 'desc', 0, 10);
45
- *
46
- * // Get player's best
47
- * const best = await kmClient.leaderboard.getBestEntry('high-scores', 'desc');
48
- * ```
49
- */
50
- export declare class KokimokiLeaderboard {
51
- private readonly client;
52
- constructor(client: KokimokiClient);
53
- /**
54
- * Add a new entry to a leaderboard.
55
- *
56
- * Creates a new entry each time it's called, preserving all attempts. Use this when you want
57
- * to track every score submission (e.g., all game attempts).
58
- *
59
- * @param leaderboardName The name of the leaderboard to add the entry to
60
- * @param sortDir Sort direction: "asc" for lowest-is-best (e.g., completion time),
61
- * "desc" for highest-is-best (e.g., points)
62
- * @param score The numeric score value
63
- * @param metadata Public metadata visible to all players (e.g., player name, level)
64
- * @param privateMetadata Private metadata only accessible via API calls (e.g., session ID)
65
- * @returns A promise resolving to an object with the entry's rank
66
- *
67
- * @example
68
- * ```typescript
69
- * const { rank } = await kmClient.leaderboard.insertEntry(
70
- * 'high-scores',
71
- * 'desc',
72
- * 1500,
73
- * { playerName: 'Alice', level: 10 },
74
- * { sessionId: 'abc123' }
75
- * );
76
- * console.log(`New rank: ${rank}`);
77
- * ```
78
- */
79
- insertEntry<MetadataT, PrivateMetadataT>(leaderboardName: string, sortDir: "asc" | "desc", score: number, metadata: MetadataT, privateMetadata: PrivateMetadataT): Promise<{
80
- rank: number;
81
- }>;
82
- /**
83
- * Add or update the latest entry for the current client in a leaderboard.
84
- *
85
- * Replaces the previous entry if one exists for this client. Use this when you only want
86
- * to keep the latest or best score per player (e.g., daily high score).
87
- *
88
- * @param leaderboardName The name of the leaderboard to upsert the entry in
89
- * @param sortDir Sort direction: "asc" for lowest-is-best (e.g., completion time),
90
- * "desc" for highest-is-best (e.g., points)
91
- * @param score The numeric score value
92
- * @param metadata Public metadata visible to all players (e.g., player name, completion time)
93
- * @param privateMetadata Private metadata only accessible via API calls (e.g., device ID)
94
- * @returns A promise resolving to an object with the entry's updated rank
95
- *
96
- * @example
97
- * ```typescript
98
- * const { rank } = await kmClient.leaderboard.upsertEntry(
99
- * 'daily-scores',
100
- * 'desc',
101
- * 2000,
102
- * { playerName: 'Bob', completionTime: 120 },
103
- * { deviceId: 'xyz789' }
104
- * );
105
- * console.log(`Updated rank: ${rank}`);
106
- * ```
107
- */
108
- upsertEntry<MetadataT, PrivateMetadataT>(leaderboardName: string, sortDir: "asc" | "desc", score: number, metadata: MetadataT, privateMetadata: PrivateMetadataT): Promise<{
109
- rank: number;
110
- }>;
111
- /**
112
- * List entries in a leaderboard with pagination.
113
- *
114
- * Retrieves a sorted list of leaderboard entries. Use skip and limit parameters for
115
- * pagination (e.g., showing top 10, or implementing "load more" functionality).
116
- *
117
- * @param leaderboardName The name of the leaderboard to query
118
- * @param sortDir Sort direction: "asc" for lowest-is-best (e.g., completion time),
119
- * "desc" for highest-is-best (e.g., points)
120
- * @param skip Number of entries to skip for pagination (default: 0)
121
- * @param limit Maximum number of entries to return (default: 100)
122
- * @returns A promise resolving to a paginated list of entries with rank, score, and metadata
123
- *
124
- * @example
125
- * ```typescript
126
- * // Get top 10 scores
127
- * const { items, total } = await kmClient.leaderboard.listEntries(
128
- * 'weekly-scores',
129
- * 'desc',
130
- * 0,
131
- * 10
132
- * );
133
- *
134
- * items.forEach(entry => {
135
- * console.log(`Rank ${entry.rank}: ${entry.metadata.playerName} - ${entry.score}`);
136
- * });
137
- * ```
138
- */
139
- listEntries<MetadataT>(leaderboardName: string, sortDir: "asc" | "desc", skip?: number, limit?: number): Promise<Paginated<{
140
- rank: number;
141
- score: number;
142
- metadata: MetadataT;
143
- }>>;
144
- /**
145
- * Get the best entry for a specific client in a leaderboard.
146
- *
147
- * Retrieves the highest-ranked entry for a client based on the sort direction.
148
- * Defaults to the current client if no clientId is provided.
149
- *
150
- * @param leaderboardName The name of the leaderboard to query
151
- * @param sortDir Sort direction: "asc" for lowest-is-best (e.g., completion time),
152
- * "desc" for highest-is-best (e.g., points)
153
- * @param clientId The client ID to get the best entry for (optional, defaults to current client)
154
- * @returns A promise resolving to the best entry with rank, score, and metadata
155
- *
156
- * @example
157
- * ```typescript
158
- * // Get current client's best entry
159
- * const myBest = await kmClient.leaderboard.getBestEntry('all-time-high', 'desc');
160
- * console.log(`My best: Rank ${myBest.rank}, Score ${myBest.score}`);
161
- *
162
- * // Get another player's best entry
163
- * const otherBest = await kmClient.leaderboard.getBestEntry(
164
- * 'all-time-high',
165
- * 'desc',
166
- * 'other-client-id'
167
- * );
168
- * ```
169
- */
170
- getBestEntry<MetadataT>(leaderboardName: string, sortDir: "asc" | "desc", clientId?: string): Promise<{
171
- rank: number;
172
- score: number;
173
- metadata: MetadataT;
174
- }>;
175
- }
@@ -1,203 +0,0 @@
1
- /**
2
- * Kokimoki Leaderboard Service
3
- *
4
- * Provides efficient player ranking and score tracking with database indexes and optimized queries.
5
- * Ideal for games with large numbers of players and competitive scoring.
6
- *
7
- * **Key Features:**
8
- * - Efficient ranking with database indexes
9
- * - Support for ascending (lowest-is-best) and descending (highest-is-best) sorting
10
- * - Pagination for large leaderboards
11
- * - Public and private metadata for entries
12
- * - Insert (preserve all attempts) or upsert (keep latest only) modes
13
- *
14
- * **When to use Leaderboard API vs Global Store:**
15
- *
16
- * Use the **Leaderboard API** when:
17
- * - You have a large number of entries (hundreds to thousands of players)
18
- * - You need efficient ranking and sorting with database indexes
19
- * - You want pagination and optimized queries for top scores
20
- * - Memory and network efficiency are important
21
- *
22
- * Use a **Global Store** when:
23
- * - You have a small number of players (typically under 100)
24
- * - You need real-time updates and live leaderboard changes
25
- * - You want to combine player scores with other game state
26
- * - The leaderboard is temporary (session-based or reset frequently)
27
- *
28
- * Access via `kmClient.leaderboard`
29
- *
30
- * @example
31
- * ```typescript
32
- * // Submit a high score
33
- * const { rank } = await kmClient.leaderboard.upsertEntry(
34
- * 'high-scores',
35
- * 'desc',
36
- * 1500,
37
- * { playerName: 'Alice' },
38
- * {}
39
- * );
40
- *
41
- * // Get top 10
42
- * const { items } = await kmClient.leaderboard.listEntries('high-scores', 'desc', 0, 10);
43
- *
44
- * // Get player's best
45
- * const best = await kmClient.leaderboard.getBestEntry('high-scores', 'desc');
46
- * ```
47
- */
48
- export class KokimokiLeaderboard {
49
- client;
50
- constructor(client) {
51
- this.client = client;
52
- }
53
- /**
54
- * Add a new entry to a leaderboard.
55
- *
56
- * Creates a new entry each time it's called, preserving all attempts. Use this when you want
57
- * to track every score submission (e.g., all game attempts).
58
- *
59
- * @param leaderboardName The name of the leaderboard to add the entry to
60
- * @param sortDir Sort direction: "asc" for lowest-is-best (e.g., completion time),
61
- * "desc" for highest-is-best (e.g., points)
62
- * @param score The numeric score value
63
- * @param metadata Public metadata visible to all players (e.g., player name, level)
64
- * @param privateMetadata Private metadata only accessible via API calls (e.g., session ID)
65
- * @returns A promise resolving to an object with the entry's rank
66
- *
67
- * @example
68
- * ```typescript
69
- * const { rank } = await kmClient.leaderboard.insertEntry(
70
- * 'high-scores',
71
- * 'desc',
72
- * 1500,
73
- * { playerName: 'Alice', level: 10 },
74
- * { sessionId: 'abc123' }
75
- * );
76
- * console.log(`New rank: ${rank}`);
77
- * ```
78
- */
79
- async insertEntry(leaderboardName, sortDir, score, metadata, privateMetadata) {
80
- const res = await fetch(`${this.client.apiUrl}/leaderboard-entries`, {
81
- method: "POST",
82
- headers: this.client.apiHeaders,
83
- body: JSON.stringify({
84
- leaderboardName,
85
- sortDir,
86
- score,
87
- metadata,
88
- privateMetadata,
89
- upsert: false,
90
- }),
91
- });
92
- return await res.json();
93
- }
94
- /**
95
- * Add or update the latest entry for the current client in a leaderboard.
96
- *
97
- * Replaces the previous entry if one exists for this client. Use this when you only want
98
- * to keep the latest or best score per player (e.g., daily high score).
99
- *
100
- * @param leaderboardName The name of the leaderboard to upsert the entry in
101
- * @param sortDir Sort direction: "asc" for lowest-is-best (e.g., completion time),
102
- * "desc" for highest-is-best (e.g., points)
103
- * @param score The numeric score value
104
- * @param metadata Public metadata visible to all players (e.g., player name, completion time)
105
- * @param privateMetadata Private metadata only accessible via API calls (e.g., device ID)
106
- * @returns A promise resolving to an object with the entry's updated rank
107
- *
108
- * @example
109
- * ```typescript
110
- * const { rank } = await kmClient.leaderboard.upsertEntry(
111
- * 'daily-scores',
112
- * 'desc',
113
- * 2000,
114
- * { playerName: 'Bob', completionTime: 120 },
115
- * { deviceId: 'xyz789' }
116
- * );
117
- * console.log(`Updated rank: ${rank}`);
118
- * ```
119
- */
120
- async upsertEntry(leaderboardName, sortDir, score, metadata, privateMetadata) {
121
- const res = await fetch(`${this.client.apiUrl}/leaderboard-entries`, {
122
- method: "POST",
123
- headers: this.client.apiHeaders,
124
- body: JSON.stringify({
125
- leaderboardName,
126
- sortDir,
127
- score,
128
- metadata,
129
- privateMetadata,
130
- upsert: true,
131
- }),
132
- });
133
- return await res.json();
134
- }
135
- /**
136
- * List entries in a leaderboard with pagination.
137
- *
138
- * Retrieves a sorted list of leaderboard entries. Use skip and limit parameters for
139
- * pagination (e.g., showing top 10, or implementing "load more" functionality).
140
- *
141
- * @param leaderboardName The name of the leaderboard to query
142
- * @param sortDir Sort direction: "asc" for lowest-is-best (e.g., completion time),
143
- * "desc" for highest-is-best (e.g., points)
144
- * @param skip Number of entries to skip for pagination (default: 0)
145
- * @param limit Maximum number of entries to return (default: 100)
146
- * @returns A promise resolving to a paginated list of entries with rank, score, and metadata
147
- *
148
- * @example
149
- * ```typescript
150
- * // Get top 10 scores
151
- * const { items, total } = await kmClient.leaderboard.listEntries(
152
- * 'weekly-scores',
153
- * 'desc',
154
- * 0,
155
- * 10
156
- * );
157
- *
158
- * items.forEach(entry => {
159
- * console.log(`Rank ${entry.rank}: ${entry.metadata.playerName} - ${entry.score}`);
160
- * });
161
- * ```
162
- */
163
- async listEntries(leaderboardName, sortDir, skip = 0, limit = 100) {
164
- const encodedLeaderboardName = encodeURIComponent(leaderboardName);
165
- const res = await fetch(`${this.client.apiUrl}/leaderboard-entries?leaderboardName=${encodedLeaderboardName}&sortDir=${sortDir}&skip=${skip}&limit=${limit}`, {
166
- headers: this.client.apiHeaders,
167
- });
168
- return await res.json();
169
- }
170
- /**
171
- * Get the best entry for a specific client in a leaderboard.
172
- *
173
- * Retrieves the highest-ranked entry for a client based on the sort direction.
174
- * Defaults to the current client if no clientId is provided.
175
- *
176
- * @param leaderboardName The name of the leaderboard to query
177
- * @param sortDir Sort direction: "asc" for lowest-is-best (e.g., completion time),
178
- * "desc" for highest-is-best (e.g., points)
179
- * @param clientId The client ID to get the best entry for (optional, defaults to current client)
180
- * @returns A promise resolving to the best entry with rank, score, and metadata
181
- *
182
- * @example
183
- * ```typescript
184
- * // Get current client's best entry
185
- * const myBest = await kmClient.leaderboard.getBestEntry('all-time-high', 'desc');
186
- * console.log(`My best: Rank ${myBest.rank}, Score ${myBest.score}`);
187
- *
188
- * // Get another player's best entry
189
- * const otherBest = await kmClient.leaderboard.getBestEntry(
190
- * 'all-time-high',
191
- * 'desc',
192
- * 'other-client-id'
193
- * );
194
- * ```
195
- */
196
- async getBestEntry(leaderboardName, sortDir, clientId) {
197
- const encodedLeaderboardName = encodeURIComponent(leaderboardName);
198
- const res = await fetch(`${this.client.apiUrl}/leaderboard-entries/best?leaderboardName=${encodedLeaderboardName}&sortDir=${sortDir}&clientId=${clientId || this.client.id}`, {
199
- headers: this.client.apiHeaders,
200
- });
201
- return await res.json();
202
- }
203
- }
@@ -1,11 +0,0 @@
1
- import { KokimokiStore } from "./kokimoki-store";
2
- export declare class KokimokiLocalStore<T extends object> extends KokimokiStore<T> {
3
- private readonly localRoomName;
4
- private _stateKey?;
5
- private get stateKey();
6
- constructor(localRoomName: string, defaultState: T);
7
- getInitialUpdate(appId: string, clientId: string): {
8
- roomHash: number;
9
- initialUpdate: Uint8Array | undefined;
10
- };
11
- }
@@ -1,40 +0,0 @@
1
- import { KokimokiStore } from "./kokimoki-store";
2
- import { RoomSubscriptionMode } from "./room-subscription-mode";
3
- import { fingerprint32 } from "farmhash-modern";
4
- import * as Y from "yjs";
5
- export class KokimokiLocalStore extends KokimokiStore {
6
- localRoomName;
7
- _stateKey;
8
- get stateKey() {
9
- if (!this._stateKey) {
10
- throw new Error("Not initialized");
11
- }
12
- return this._stateKey;
13
- }
14
- constructor(localRoomName, defaultState) {
15
- super(`/l/${localRoomName}`, defaultState, RoomSubscriptionMode.ReadWrite);
16
- this.localRoomName = localRoomName;
17
- // Synchronize doc changes to local storage
18
- // TODO: maybe do not serialize full state every time
19
- this.doc.on("update", () => {
20
- const value = Y.encodeStateAsUpdate(this.doc);
21
- const valueString = String.fromCharCode(...value);
22
- const valueBase64 = btoa(valueString);
23
- localStorage.setItem(this.stateKey, valueBase64);
24
- });
25
- }
26
- getInitialUpdate(appId, clientId) {
27
- this._stateKey = `${appId}/${clientId}/${this.localRoomName}`;
28
- // get initial update from local storage
29
- let initialUpdate = undefined;
30
- const state = localStorage.getItem(this.stateKey);
31
- if (state) {
32
- const valueString = atob(state);
33
- initialUpdate = Uint8Array.from(valueString, (c) => c.charCodeAt(0));
34
- }
35
- return {
36
- roomHash: fingerprint32(this.roomName),
37
- initialUpdate,
38
- };
39
- }
40
- }
File without changes
@@ -1,38 +0,0 @@
1
- "use strict";
2
- // import EventEmitter from "events";
3
- // import { KokimokiStore } from "./kokimoki-store";
4
- // import { KokimokiSchema as S } from "./kokimoki-schema";
5
- // import type TypedEventEmitter from "typed-emitter";
6
- // import type { RoomSubscriptionMode } from "./room-subscription-mode";
7
- // export class KokimokiQueue<
8
- // Req extends S.Generic<unknown>
9
- // > extends KokimokiStore<S.Dict<Req>> {
10
- // private _emitter = new EventEmitter() as TypedEventEmitter<{
11
- // messages: (
12
- // messages: { id: string; payload: Req["defaultValue"] }[]
13
- // ) => void;
14
- // }>;
15
- // public readonly on = this._emitter.on.bind(this._emitter);
16
- // public readonly off = this._emitter.off.bind(this._emitter);
17
- // constructor(
18
- // roomName: string,
19
- // public readonly payloadSchema: Req,
20
- // mode: RoomSubscriptionMode
21
- // ) {
22
- // super(`/q/${roomName}`, S.dict(payloadSchema), mode);
23
- // const emittedMessageIds = new Set<string>();
24
- // this.doc.on("update", () => {
25
- // const newMessages: { id: string; payload: Req["defaultValue"] }[] = [];
26
- // for (const id in this.proxy) {
27
- // if (emittedMessageIds.has(id)) {
28
- // continue;
29
- // }
30
- // emittedMessageIds.add(id);
31
- // newMessages.push({ id, payload: this.proxy[id] });
32
- // }
33
- // if (newMessages.length > 0) {
34
- // this._emitter.emit("messages", newMessages);
35
- // }
36
- // });
37
- // }
38
- // }
File without changes
@@ -1,198 +0,0 @@
1
- "use strict";
2
- // import type { KokimokiClient } from "./kokimoki-client";
3
- // import type { KokimokiQueue } from "./kokimoki-queue";
4
- // import { KokimokiSchema as S } from "./kokimoki-schema";
5
- // import { RoomSubscriptionMode } from "./room-subscription-mode";
6
- // export class KokimokiReqRes<
7
- // Req extends S.Generic<unknown>,
8
- // Res extends S.Generic<unknown>
9
- // > {
10
- // private _reqQueueSchema;
11
- // private _resQueueSchema;
12
- // // Request queues are linked to client ids
13
- // private _reqQueues: {
14
- // [clientId: string]: KokimokiQueue<
15
- // S.Struct<{ connectionId: S.String; payload: Req }>
16
- // >;
17
- // } = {};
18
- // // Response queues are linked to specific connection ids
19
- // private _resQueues: {
20
- // [connectionId: string]: KokimokiQueue<
21
- // S.Struct<{ reqId: S.String; error: S.Optional<S.String>; payload: Res }>
22
- // >;
23
- // } = {};
24
- // private _reqPromises: {
25
- // [reqId: string]: {
26
- // resolve: (value: Res["defaultValue"]) => void;
27
- // reject: (error: string) => void;
28
- // };
29
- // } = {};
30
- // private async _getReqQueue(
31
- // clientId: string,
32
- // mode: RoomSubscriptionMode = RoomSubscriptionMode.Write
33
- // ) {
34
- // if (!this._reqQueues.hasOwnProperty(clientId)) {
35
- // this._reqQueues[clientId] = this.kmClient.queue(
36
- // `/r/${clientId}/req/${this.serviceName}`,
37
- // this._reqQueueSchema,
38
- // mode,
39
- // false
40
- // );
41
- // await this.kmClient.join(this._reqQueues[clientId]);
42
- // }
43
- // return this._reqQueues[clientId];
44
- // }
45
- // private async _getResQueue(
46
- // connectionId: string,
47
- // mode: RoomSubscriptionMode = RoomSubscriptionMode.Write
48
- // ) {
49
- // if (!this._resQueues.hasOwnProperty(connectionId)) {
50
- // this._resQueues[connectionId] = this.kmClient.queue(
51
- // `/r/${connectionId}/res/${this.serviceName}`,
52
- // this._resQueueSchema,
53
- // mode,
54
- // false
55
- // );
56
- // await this.kmClient.join(this._resQueues[connectionId]);
57
- // }
58
- // return this._resQueues[connectionId];
59
- // }
60
- // constructor(
61
- // private kmClient: KokimokiClient,
62
- // public readonly serviceName: string,
63
- // public readonly reqSchema: Req,
64
- // public readonly resSchema: Res,
65
- // private handleRequest: (
66
- // payload: Req["defaultValue"]
67
- // ) => Promise<Res["defaultValue"]>
68
- // ) {
69
- // this._reqQueueSchema = S.struct({
70
- // connectionId: S.string(),
71
- // // roomHash: S.number(),
72
- // payload: reqSchema,
73
- // });
74
- // this._resQueueSchema = S.struct({
75
- // reqId: S.string(),
76
- // error: S.optional(S.string()),
77
- // payload: resSchema,
78
- // });
79
- // // Set up queues on connect
80
- // kmClient.on("connected", async () => {
81
- // // Handle responses to self
82
- // const resQueue = await this._getResQueue(
83
- // kmClient.connectionId,
84
- // RoomSubscriptionMode.ReadWrite
85
- // );
86
- // let handlingResponses = false;
87
- // let rehandleResponses = false;
88
- // resQueue.subscribe(async (messages) => {
89
- // // console.log("RES", Object.keys(messages));
90
- // if (handlingResponses) {
91
- // rehandleResponses = true;
92
- // return;
93
- // }
94
- // handlingResponses = true;
95
- // await this.handleResponses(resQueue, messages);
96
- // if (rehandleResponses) {
97
- // rehandleResponses = false;
98
- // await this.handleResponses(resQueue, messages);
99
- // }
100
- // handlingResponses = false;
101
- // });
102
- // // Handle requests to self
103
- // const reqQueue = await this._getReqQueue(
104
- // kmClient.id,
105
- // RoomSubscriptionMode.ReadWrite
106
- // );
107
- // let handlingRequests = false;
108
- // let rehandleRequests = false;
109
- // reqQueue.subscribe(async (messages) => {
110
- // // console.log("REQ", Object.keys(messages));
111
- // if (handlingRequests) {
112
- // rehandleRequests = true;
113
- // return;
114
- // }
115
- // handlingRequests = true;
116
- // await this.handleRequests(reqQueue, messages);
117
- // if (rehandleRequests) {
118
- // rehandleRequests = false;
119
- // await this.handleRequests(reqQueue, messages);
120
- // }
121
- // handlingRequests = false;
122
- // });
123
- // });
124
- // }
125
- // private async handleRequests(
126
- // reqQueue: KokimokiQueue<any>,
127
- // messages: {
128
- // [reqId: string]: { connectionId: string; payload: Req["defaultValue"] };
129
- // }
130
- // ) {
131
- // // Send responses
132
- // await this.kmClient.transact(async (t) => {
133
- // for (const reqId in messages) {
134
- // const { connectionId, payload } = messages[reqId];
135
- // const resQueue = await this._getResQueue(connectionId);
136
- // t.consumeMessage(reqQueue, reqId);
137
- // try {
138
- // t.queueMessage(resQueue, {
139
- // reqId,
140
- // error: undefined,
141
- // payload: await this.handleRequest(payload),
142
- // });
143
- // } catch (e: any) {
144
- // t.queueMessage(resQueue, {
145
- // reqId,
146
- // error: e.toString(),
147
- // payload: null,
148
- // });
149
- // }
150
- // }
151
- // });
152
- // }
153
- // private async handleResponses(
154
- // resQueue: KokimokiQueue<any>,
155
- // messages: {
156
- // [resId: string]: {
157
- // reqId: string;
158
- // error?: string;
159
- // payload: Res["defaultValue"];
160
- // };
161
- // }
162
- // ) {
163
- // // Handle responses
164
- // await this.kmClient.transact(async (t) => {
165
- // for (const resId in messages) {
166
- // const { reqId, error, payload } = messages[resId];
167
- // const promise = this._reqPromises[reqId];
168
- // t.consumeMessage(resQueue, resId);
169
- // if (promise) {
170
- // if (error) {
171
- // promise.reject(error);
172
- // } else {
173
- // promise.resolve(payload);
174
- // }
175
- // delete this._reqPromises[reqId];
176
- // }
177
- // }
178
- // });
179
- // }
180
- // async send(
181
- // toClientId: string,
182
- // payload: Req["defaultValue"],
183
- // timeout?: number
184
- // ) {
185
- // const toReqQueue = await this._getReqQueue(toClientId);
186
- // // Create a promise for the response
187
- // return await new Promise<Res["defaultValue"]>(async (resolve, reject) => {
188
- // await this.kmClient.transact((t) => {
189
- // const reqId = t.queueMessage(toReqQueue, {
190
- // connectionId: this.kmClient.connectionId,
191
- // payload,
192
- // // roomHash,
193
- // });
194
- // this._reqPromises[reqId] = { resolve, reject };
195
- // });
196
- // });
197
- // }
198
- // }