@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.
- package/dist/index.d.ts +0 -2
- package/dist/index.js +1 -2
- package/dist/kokimoki-awareness.d.ts +12 -10
- package/dist/kokimoki-awareness.js +21 -19
- package/dist/kokimoki-client.d.ts +10 -14
- package/dist/kokimoki-client.js +39 -20
- package/dist/kokimoki-local-store.d.ts +3 -3
- package/dist/kokimoki-queue.d.ts +0 -31
- package/dist/kokimoki-queue.js +38 -27
- package/dist/kokimoki-req-res.d.ts +0 -20
- package/dist/kokimoki-req-res.js +198 -143
- package/dist/kokimoki-store.d.ts +8 -8
- package/dist/kokimoki-store.js +5 -5
- package/dist/kokimoki-transaction.d.ts +8 -17
- package/dist/kokimoki-transaction.js +106 -68
- package/dist/kokimoki.min.d.ts +33 -187
- package/dist/kokimoki.min.js +4608 -476
- package/dist/kokimoki.min.js.map +1 -1
- package/dist/room-subscription.js +3 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -2
package/dist/kokimoki-req-res.js
CHANGED
|
@@ -1,143 +1,198 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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
|
+
// }
|
package/dist/kokimoki-store.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
10
|
-
readonly root: T
|
|
11
|
-
readonly defaultValue: T
|
|
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
|
|
14
|
-
get(): T
|
|
15
|
-
subscribe(set: (value:
|
|
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>;
|
package/dist/kokimoki-store.js
CHANGED
|
@@ -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
|
|
2
|
-
|
|
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
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
6
|
-
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
|
131
|
+
for (const unbindProxy of this._unbindProxies) {
|
|
94
132
|
unbindProxy();
|
|
95
133
|
}
|
|
96
134
|
// Generates updates
|