@kokimoki/app 1.9.0 → 1.10.0

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.
@@ -1,143 +1,198 @@
1
- import { KokimokiSchema as S } from "./kokimoki-schema";
2
- import { RoomSubscriptionMode } from "./room-subscription-mode";
3
- export class KokimokiReqRes {
4
- kmClient;
5
- serviceName;
6
- reqSchema;
7
- resSchema;
8
- handleRequest;
9
- _reqQueueSchema;
10
- _resQueueSchema;
11
- // Request queues are linked to client ids
12
- _reqQueues = {};
13
- // Response queues are linked to specific connection ids
14
- _resQueues = {};
15
- _reqPromises = {};
16
- async _getReqQueue(clientId, mode = RoomSubscriptionMode.Write) {
17
- if (!this._reqQueues.hasOwnProperty(clientId)) {
18
- this._reqQueues[clientId] = this.kmClient.queue(`/r/${clientId}/req/${this.serviceName}`, this._reqQueueSchema, mode, false);
19
- await this.kmClient.join(this._reqQueues[clientId]);
20
- }
21
- return this._reqQueues[clientId];
22
- }
23
- async _getResQueue(connectionId, mode = RoomSubscriptionMode.Write) {
24
- if (!this._resQueues.hasOwnProperty(connectionId)) {
25
- this._resQueues[connectionId] = this.kmClient.queue(`/r/${connectionId}/res/${this.serviceName}`, this._resQueueSchema, mode, false);
26
- await this.kmClient.join(this._resQueues[connectionId]);
27
- }
28
- return this._resQueues[connectionId];
29
- }
30
- constructor(kmClient, serviceName, reqSchema, resSchema, handleRequest) {
31
- this.kmClient = kmClient;
32
- this.serviceName = serviceName;
33
- this.reqSchema = reqSchema;
34
- this.resSchema = resSchema;
35
- this.handleRequest = handleRequest;
36
- this._reqQueueSchema = S.struct({
37
- connectionId: S.string(),
38
- // roomHash: S.number(),
39
- payload: reqSchema,
40
- });
41
- this._resQueueSchema = S.struct({
42
- reqId: S.string(),
43
- error: S.optional(S.string()),
44
- payload: resSchema,
45
- });
46
- // Set up queues on connect
47
- kmClient.on("connected", async () => {
48
- // Handle responses to self
49
- const resQueue = await this._getResQueue(kmClient.connectionId, RoomSubscriptionMode.ReadWrite);
50
- let handlingResponses = false;
51
- let rehandleResponses = false;
52
- resQueue.subscribe(async (messages) => {
53
- // console.log("RES", Object.keys(messages));
54
- if (handlingResponses) {
55
- rehandleResponses = true;
56
- return;
57
- }
58
- handlingResponses = true;
59
- await this.handleResponses(resQueue, messages);
60
- if (rehandleResponses) {
61
- rehandleResponses = false;
62
- await this.handleResponses(resQueue, messages);
63
- }
64
- handlingResponses = false;
65
- });
66
- // Handle requests to self
67
- const reqQueue = await this._getReqQueue(kmClient.id, RoomSubscriptionMode.ReadWrite);
68
- let handlingRequests = false;
69
- let rehandleRequests = false;
70
- reqQueue.subscribe(async (messages) => {
71
- // console.log("REQ", Object.keys(messages));
72
- if (handlingRequests) {
73
- rehandleRequests = true;
74
- return;
75
- }
76
- handlingRequests = true;
77
- await this.handleRequests(reqQueue, messages);
78
- if (rehandleRequests) {
79
- rehandleRequests = false;
80
- await this.handleRequests(reqQueue, messages);
81
- }
82
- handlingRequests = false;
83
- });
84
- });
85
- }
86
- async handleRequests(reqQueue, messages) {
87
- // Send responses
88
- await this.kmClient.transact(async (t) => {
89
- for (const reqId in messages) {
90
- const { connectionId, payload } = messages[reqId];
91
- const resQueue = await this._getResQueue(connectionId);
92
- t.consumeMessage(reqQueue, reqId);
93
- try {
94
- t.queueMessage(resQueue, {
95
- reqId,
96
- error: undefined,
97
- payload: await this.handleRequest(payload),
98
- });
99
- }
100
- catch (e) {
101
- t.queueMessage(resQueue, {
102
- reqId,
103
- error: e.toString(),
104
- payload: null,
105
- });
106
- }
107
- }
108
- });
109
- }
110
- async handleResponses(resQueue, messages) {
111
- // Handle responses
112
- await this.kmClient.transact(async (t) => {
113
- for (const resId in messages) {
114
- const { reqId, error, payload } = messages[resId];
115
- const promise = this._reqPromises[reqId];
116
- t.consumeMessage(resQueue, resId);
117
- if (promise) {
118
- if (error) {
119
- promise.reject(error);
120
- }
121
- else {
122
- promise.resolve(payload);
123
- }
124
- delete this._reqPromises[reqId];
125
- }
126
- }
127
- });
128
- }
129
- async send(toClientId, payload, timeout) {
130
- const toReqQueue = await this._getReqQueue(toClientId);
131
- // Create a promise for the response
132
- return await new Promise(async (resolve, reject) => {
133
- await this.kmClient.transact((t) => {
134
- const reqId = t.queueMessage(toReqQueue, {
135
- connectionId: this.kmClient.connectionId,
136
- payload,
137
- // roomHash,
138
- });
139
- this._reqPromises[reqId] = { resolve, reject };
140
- });
141
- });
142
- }
143
- }
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
+ // }
@@ -1,18 +1,18 @@
1
1
  import * as Y from "yjs";
2
- import type { KokimokiSchema as S } from "./kokimoki-schema";
3
2
  import { RoomSubscriptionMode } from "./room-subscription-mode";
4
3
  import type { KokimokiClient } from "./kokimoki-client";
5
- export declare class KokimokiStore<T extends S.Generic<unknown>, SubscribeT = T["defaultValue"]> {
4
+ import { ZodType } from "zod";
5
+ export declare class KokimokiStore<T> {
6
6
  readonly roomName: string;
7
7
  readonly mode: RoomSubscriptionMode;
8
8
  readonly doc: Y.Doc;
9
- readonly proxy: T["defaultValue"];
10
- readonly root: T["defaultValue"];
11
- readonly defaultValue: T["defaultValue"];
9
+ readonly proxy: T;
10
+ readonly root: T;
11
+ readonly defaultValue: T;
12
12
  readonly docRoot: Y.Map<unknown>;
13
- constructor(roomName: string, schema: T, mode?: RoomSubscriptionMode);
14
- get(): T["defaultValue"];
15
- subscribe(set: (value: SubscribeT) => void): () => void;
13
+ constructor(roomName: string, schema: ZodType<T>, mode?: RoomSubscriptionMode);
14
+ get(): T;
15
+ subscribe(set: (value: T) => void): () => void;
16
16
  onJoin(client: KokimokiClient): Promise<void>;
17
17
  onBeforeLeave(client: KokimokiClient): Promise<void>;
18
18
  onLeave(client: KokimokiClient): Promise<void>;
@@ -7,9 +7,9 @@ export class KokimokiStore {
7
7
  roomName;
8
8
  mode;
9
9
  doc;
10
- proxy;
11
- root;
12
- defaultValue;
10
+ proxy; //T["defaultValue"];
11
+ root; //T["defaultValue"];
12
+ defaultValue; //T["defaultValue"];
13
13
  docRoot;
14
14
  constructor(roomName, schema, mode = RoomSubscriptionMode.ReadWrite) {
15
15
  this.roomName = roomName;
@@ -18,7 +18,7 @@ export class KokimokiStore {
18
18
  this.doc = new Y.Doc();
19
19
  this.docRoot = this.doc.getMap("root");
20
20
  // Construct proxy object
21
- this.proxy = yjsProxy();
21
+ this.proxy = yjsProxy(); //T["defaultValue"];
22
22
  // @ts-ignore
23
23
  yjsBind(this.proxy, this.docRoot);
24
24
  // Create root proxy
@@ -43,7 +43,7 @@ export class KokimokiStore {
43
43
  },
44
44
  });
45
45
  // Set default value
46
- this.defaultValue = schema.defaultValue;
46
+ this.defaultValue = schema.parse({}); //schema.defaultValue;
47
47
  }
48
48
  get() {
49
49
  return this.proxy;
@@ -1,22 +1,13 @@
1
- import type { KokimokiQueue } from "./kokimoki-queue";
2
- import type { KokimokiSchema as S } from "./kokimoki-schema";
3
- import type { KokimokiClient } from "./kokimoki-client";
4
- export declare class KokimokiTransaction {
5
- private kmClient;
6
- private _clones;
1
+ import { KokimokiStore } from "./kokimoki-store";
2
+ export declare class KokimokiTransaction<T extends unknown[]> {
7
3
  private _updates;
8
4
  private _consumeMessagesInRooms;
9
- private _queueMessageCounter;
10
- constructor(kmClient: KokimokiClient<any>);
11
- private _parseTarget;
12
- private _parsePath;
13
- private _getClone;
14
- get<T>(target: T): T;
15
- set<T>(target: T, value: T): void;
16
- delete<T>(target: T): void;
17
- push<T>(target: T[], value: T): void;
18
- queueMessage<T>(queue: KokimokiQueue<S.Generic<T>>, payload: T): string;
19
- consumeMessage<T>(queue: KokimokiQueue<S.Generic<T>>, messageId: string): void;
5
+ private _proxies;
6
+ private _unbindProxies;
7
+ constructor(stores: {
8
+ [K in keyof T]: KokimokiStore<T[K]>;
9
+ });
10
+ getProxies(): T;
20
11
  getUpdates(): Promise<{
21
12
  updates: {
22
13
  roomName: string;
@@ -2,95 +2,133 @@ import * as Y from "yjs";
2
2
  import { proxy as yjsProxy } from "valtio";
3
3
  import { bind as yjsBind } from "valtio-yjs";
4
4
  export class KokimokiTransaction {
5
- kmClient;
6
- _clones = new Map();
5
+ // private _clones = new Map<
6
+ // string,
7
+ // { docClone: Y.Doc; proxyClone: any; unbindProxy: () => void }
8
+ // >();
7
9
  _updates = new Map();
8
10
  _consumeMessagesInRooms = new Set();
9
- _queueMessageCounter = 0;
10
- constructor(kmClient) {
11
- this.kmClient = kmClient;
12
- }
13
- _parseTarget(target) {
14
- return target();
15
- }
16
- _parsePath(obj, path) {
17
- for (let i = 0; i < path.length - 1; i++) {
18
- if (!(path[i] in obj)) {
19
- obj[path[i]] = {};
20
- }
21
- obj = obj[path[i]];
22
- }
23
- return { obj, key: path[path.length - 1] };
24
- }
25
- _getClone(roomName, doc) {
26
- if (!this._clones.has(roomName)) {
27
- // Clone doc
11
+ // private _queueMessageCounter = 0;
12
+ _proxies = [];
13
+ _unbindProxies = [];
14
+ constructor(stores) {
15
+ // Create a proxy for each store
16
+ for (const store of stores) {
17
+ // Clone initial state
28
18
  const docClone = new Y.Doc();
29
19
  const docRoot = docClone.getMap("root");
30
- Y.applyUpdate(docClone, Y.encodeStateAsUpdate(doc));
20
+ Y.applyUpdate(docClone, Y.encodeStateAsUpdate(store.doc));
31
21
  // Set up proxy
32
22
  const proxyClone = yjsProxy();
33
23
  const unbindProxy = yjsBind(proxyClone, docRoot);
24
+ this._proxies.push(proxyClone);
25
+ this._unbindProxies.push(unbindProxy);
34
26
  // Listen for updates
35
27
  docClone.on("update", (update) => {
36
- if (this._updates.has(roomName)) {
37
- const prevUpdate = this._updates.get(roomName);
28
+ if (this._updates.has(store.roomName)) {
29
+ const prevUpdate = this._updates.get(store.roomName);
38
30
  const nextUpdate = Y.mergeUpdates([prevUpdate, update]);
39
- this._updates.set(roomName, nextUpdate);
31
+ this._updates.set(store.roomName, nextUpdate);
40
32
  }
41
33
  else {
42
- this._updates.set(roomName, update);
34
+ this._updates.set(store.roomName, update);
43
35
  }
44
36
  });
45
- this._clones.set(roomName, { docClone, proxyClone, unbindProxy });
46
- }
47
- return this._clones.get(roomName);
48
- }
49
- get(target) {
50
- const { roomName, doc, path } = this._parseTarget(target);
51
- const { proxyClone } = this._getClone(roomName, doc);
52
- const { obj, key } = this._parsePath(proxyClone, path);
53
- return obj[key];
54
- }
55
- set(target, value) {
56
- const { roomName, doc, path } = this._parseTarget(target);
57
- const { proxyClone } = this._getClone(roomName, doc);
58
- const { obj, key } = this._parsePath(proxyClone, path);
59
- obj[key] = value;
60
- }
61
- delete(target) {
62
- const { roomName, doc, path } = this._parseTarget(target);
63
- const { proxyClone } = this._getClone(roomName, doc);
64
- const { obj, key } = this._parsePath(proxyClone, path);
65
- delete obj[key];
66
- }
67
- push(target, value) {
68
- const { roomName, doc, path } = this._parseTarget(target);
69
- const { proxyClone } = this._getClone(roomName, doc);
70
- const { obj, key } = this._parsePath(proxyClone, path);
71
- if (!(key in obj)) {
72
- obj[key] = [];
37
+ // this._clones.set(store.roomName, { docClone, proxyClone, unbindProxy });
73
38
  }
74
- obj[key].push(value);
75
- }
76
- queueMessage(queue, payload) {
77
- const messageId = `${this.kmClient.serverTimestamp()}/${this
78
- ._queueMessageCounter++}/${Math.random().toString(36).slice(2)}`;
79
- this.set(queue.root[messageId], payload);
80
- return messageId;
81
39
  }
82
- consumeMessage(queue, messageId) {
83
- if (!queue.proxy[messageId]) {
84
- throw new Error(`Message ${messageId} does not exist or has already been consumed`);
85
- }
86
- this.delete(queue.root[messageId]);
87
- this._consumeMessagesInRooms.add(queue.roomName);
40
+ getProxies() {
41
+ // @ts-ignore
42
+ return this._proxies;
88
43
  }
44
+ // private _parseTarget(target: any): {
45
+ // roomName: string;
46
+ // doc: Y.Doc;
47
+ // obj: any;
48
+ // key: string;
49
+ // path: string[];
50
+ // } {
51
+ // return target();
52
+ // }
53
+ // private _parsePath(obj: any, path: string[]) {
54
+ // for (let i = 0; i < path.length - 1; i++) {
55
+ // if (!(path[i] in obj)) {
56
+ // obj[path[i]] = {};
57
+ // }
58
+ // obj = obj[path[i]];
59
+ // }
60
+ // return { obj, key: path[path.length - 1] };
61
+ // }
62
+ // private _getClone(roomName: string, doc: Y.Doc) {
63
+ // if (!this._clones.has(roomName)) {
64
+ // // Clone doc
65
+ // const docClone = new Y.Doc();
66
+ // const docRoot = docClone.getMap("root");
67
+ // Y.applyUpdate(docClone, Y.encodeStateAsUpdate(doc));
68
+ // // Set up proxy
69
+ // const proxyClone = yjsProxy() as any;
70
+ // const unbindProxy = yjsBind(proxyClone, docRoot);
71
+ // // Listen for updates
72
+ // docClone.on("update", (update) => {
73
+ // if (this._updates.has(roomName)) {
74
+ // const prevUpdate = this._updates.get(roomName)!;
75
+ // const nextUpdate = Y.mergeUpdates([prevUpdate, update]);
76
+ // this._updates.set(roomName, nextUpdate);
77
+ // } else {
78
+ // this._updates.set(roomName, update);
79
+ // }
80
+ // });
81
+ // this._clones.set(roomName, { docClone, proxyClone, unbindProxy });
82
+ // }
83
+ // return this._clones.get(roomName)!;
84
+ // }
85
+ // get<T>(target: T): T {
86
+ // const { roomName, doc, path } = this._parseTarget(target);
87
+ // const { proxyClone } = this._getClone(roomName, doc);
88
+ // const { obj, key } = this._parsePath(proxyClone, path);
89
+ // return obj[key];
90
+ // }
91
+ // set<T>(target: T, value: T) {
92
+ // const { roomName, doc, path } = this._parseTarget(target);
93
+ // const { proxyClone } = this._getClone(roomName, doc);
94
+ // const { obj, key } = this._parsePath(proxyClone, path);
95
+ // obj[key] = value;
96
+ // }
97
+ // delete<T>(target: T) {
98
+ // const { roomName, doc, path } = this._parseTarget(target);
99
+ // const { proxyClone } = this._getClone(roomName, doc);
100
+ // const { obj, key } = this._parsePath(proxyClone, path);
101
+ // delete obj[key];
102
+ // }
103
+ // push<T>(target: T[], value: T) {
104
+ // const { roomName, doc, path } = this._parseTarget(target);
105
+ // const { proxyClone } = this._getClone(roomName, doc);
106
+ // const { obj, key } = this._parsePath(proxyClone, path);
107
+ // if (!(key in obj)) {
108
+ // obj[key] = [];
109
+ // }
110
+ // obj[key].push(value);
111
+ // }
112
+ // queueMessage<T>(queue: KokimokiQueue<S.Generic<T>>, payload: T) {
113
+ // const messageId = `${this.kmClient.serverTimestamp()}/${this
114
+ // ._queueMessageCounter++}/${Math.random().toString(36).slice(2)}`;
115
+ // this.set(queue.root[messageId], payload);
116
+ // return messageId;
117
+ // }
118
+ // consumeMessage<T>(queue: KokimokiQueue<S.Generic<T>>, messageId: string) {
119
+ // if (!queue.proxy[messageId]) {
120
+ // throw new Error(
121
+ // `Message ${messageId} does not exist or has already been consumed`
122
+ // );
123
+ // }
124
+ // this.delete(queue.root[messageId]);
125
+ // this._consumeMessagesInRooms.add(queue.roomName);
126
+ // }
89
127
  async getUpdates() {
90
128
  // Wait for doc update handling to finish
91
129
  return await new Promise((resolve) => setTimeout(() => {
92
130
  // Clean up
93
- for (const { unbindProxy } of this._clones.values()) {
131
+ for (const unbindProxy of this._unbindProxies) {
94
132
  unbindProxy();
95
133
  }
96
134
  // Generates updates