@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.
- package/README.md +1 -2
- package/dist/core/kokimoki-client.d.ts +4 -4
- package/dist/core/kokimoki-client.js +4 -4
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/utils/valtio.d.ts +2 -5
- package/dist/utils/valtio.js +4 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/kokimoki-ai.instructions.md +4 -2
- package/docs/kokimoki-dynamic-stores.instructions.md +3 -3
- package/docs/kokimoki-i18n.instructions.md +1 -1
- package/docs/kokimoki-sdk.instructions.md +46 -7
- package/package.json +15 -2
- package/dist/fields.d.ts +0 -110
- package/dist/fields.js +0 -158
- package/dist/kokimoki-ai.d.ts +0 -153
- package/dist/kokimoki-ai.js +0 -164
- package/dist/kokimoki-awareness.d.ts +0 -21
- package/dist/kokimoki-awareness.js +0 -48
- package/dist/kokimoki-client-refactored.d.ts +0 -80
- package/dist/kokimoki-client-refactored.js +0 -400
- package/dist/kokimoki-client.d.ts +0 -362
- package/dist/kokimoki-client.js +0 -823
- package/dist/kokimoki-leaderboard.d.ts +0 -175
- package/dist/kokimoki-leaderboard.js +0 -203
- package/dist/kokimoki-local-store.d.ts +0 -11
- package/dist/kokimoki-local-store.js +0 -40
- package/dist/kokimoki-queue.d.ts +0 -0
- package/dist/kokimoki-queue.js +0 -38
- package/dist/kokimoki-req-res.d.ts +0 -0
- package/dist/kokimoki-req-res.js +0 -198
- package/dist/kokimoki-schema.d.ts +0 -113
- package/dist/kokimoki-schema.js +0 -162
- package/dist/kokimoki-storage.d.ts +0 -156
- package/dist/kokimoki-storage.js +0 -208
- package/dist/kokimoki-store.d.ts +0 -23
- package/dist/kokimoki-store.js +0 -117
- package/dist/kokimoki-transaction.d.ts +0 -18
- package/dist/kokimoki-transaction.js +0 -143
- package/dist/kokimoki.min.d.ts +0 -1244
- package/dist/kokimoki.min.js +0 -19108
- package/dist/kokimoki.min.js.map +0 -1
- package/dist/llms.txt +0 -665
- package/dist/message-queue.d.ts +0 -8
- package/dist/message-queue.js +0 -19
- package/dist/room-subscription-mode.d.ts +0 -5
- package/dist/room-subscription-mode.js +0 -6
- package/dist/room-subscription.d.ts +0 -15
- package/dist/room-subscription.js +0 -52
- package/dist/synced-schema.d.ts +0 -74
- package/dist/synced-schema.js +0 -83
- package/dist/synced-store.d.ts +0 -10
- package/dist/synced-store.js +0 -9
- package/dist/synced-types.d.ts +0 -47
- package/dist/synced-types.js +0 -67
- package/dist/ws-message-reader.d.ts +0 -11
- package/dist/ws-message-reader.js +0 -36
- package/dist/ws-message-type copy.d.ts +0 -6
- package/dist/ws-message-type copy.js +0 -7
- package/dist/ws-message-type.d.ts +0 -11
- package/dist/ws-message-type.js +0 -12
- package/dist/ws-message-writer.d.ts +0 -9
- package/dist/ws-message-writer.js +0 -45
package/dist/kokimoki-store.js
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import * as Y from "yjs";
|
|
2
|
-
import { snapshot, proxy, subscribe } from "valtio/vanilla";
|
|
3
|
-
import { bind as yjsBind } from "valtio-yjs";
|
|
4
|
-
import { RoomSubscriptionMode } from "./room-subscription-mode";
|
|
5
|
-
export class KokimokiStore {
|
|
6
|
-
roomName;
|
|
7
|
-
defaultValue;
|
|
8
|
-
mode;
|
|
9
|
-
doc;
|
|
10
|
-
proxy;
|
|
11
|
-
docRoot;
|
|
12
|
-
connections;
|
|
13
|
-
_unsubscribeConnectionsHandler = () => { };
|
|
14
|
-
constructor(roomName, defaultValue, mode = RoomSubscriptionMode.ReadWrite) {
|
|
15
|
-
this.roomName = roomName;
|
|
16
|
-
this.defaultValue = defaultValue;
|
|
17
|
-
this.mode = mode;
|
|
18
|
-
// "_connections" is a reserved key for tracking connections
|
|
19
|
-
if ("_connections" in defaultValue) {
|
|
20
|
-
throw new Error(`"_connections" is a reserved key in KokimokiStore`);
|
|
21
|
-
}
|
|
22
|
-
// Construct Y doc
|
|
23
|
-
this.doc = new Y.Doc();
|
|
24
|
-
this.docRoot = this.doc.getMap("root");
|
|
25
|
-
// Construct proxy object
|
|
26
|
-
this.proxy = proxy();
|
|
27
|
-
// @ts-ignore
|
|
28
|
-
yjsBind(this.proxy, this.docRoot);
|
|
29
|
-
// Construct connections proxy
|
|
30
|
-
this.connections = proxy({
|
|
31
|
-
connectionIds: new Set(),
|
|
32
|
-
clientIds: new Set(),
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
get() {
|
|
36
|
-
return snapshot(this.proxy);
|
|
37
|
-
}
|
|
38
|
-
subscribe(set) {
|
|
39
|
-
const handler = () => set(this.get());
|
|
40
|
-
this.doc.on("update", handler);
|
|
41
|
-
set(this.get());
|
|
42
|
-
return () => this.doc.off("update", handler);
|
|
43
|
-
}
|
|
44
|
-
async onJoin(client) {
|
|
45
|
-
// Update connections whenever _connections changes
|
|
46
|
-
let prevConnectionIds = new Set();
|
|
47
|
-
let prevClientIds = new Set();
|
|
48
|
-
this._unsubscribeConnectionsHandler = subscribe(this.proxy, () => {
|
|
49
|
-
// @ts-ignore
|
|
50
|
-
const newConnectionIds = new Set(
|
|
51
|
-
// @ts-ignore
|
|
52
|
-
Object.keys(this.proxy._connections || {}));
|
|
53
|
-
// Update only if there are changes
|
|
54
|
-
let connectionIdsChanged = false;
|
|
55
|
-
if (newConnectionIds.size !== prevConnectionIds.size) {
|
|
56
|
-
connectionIdsChanged = true;
|
|
57
|
-
}
|
|
58
|
-
if (!connectionIdsChanged) {
|
|
59
|
-
for (const id of newConnectionIds) {
|
|
60
|
-
if (!prevConnectionIds.has(id)) {
|
|
61
|
-
connectionIdsChanged = true;
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
if (!connectionIdsChanged) {
|
|
67
|
-
for (const id of prevConnectionIds) {
|
|
68
|
-
if (!newConnectionIds.has(id)) {
|
|
69
|
-
connectionIdsChanged = true;
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
if (connectionIdsChanged) {
|
|
75
|
-
this.connections.connectionIds = newConnectionIds;
|
|
76
|
-
prevConnectionIds = new Set(newConnectionIds);
|
|
77
|
-
}
|
|
78
|
-
// @ts-ignore
|
|
79
|
-
const newClientIds = new Set(
|
|
80
|
-
// @ts-ignore
|
|
81
|
-
Object.values(this.proxy._connections || {}));
|
|
82
|
-
// Update only if there are changes
|
|
83
|
-
let clientIdsChanged = false;
|
|
84
|
-
if (newClientIds.size !== prevClientIds.size) {
|
|
85
|
-
clientIdsChanged = true;
|
|
86
|
-
}
|
|
87
|
-
if (!clientIdsChanged) {
|
|
88
|
-
for (const id of newClientIds) {
|
|
89
|
-
if (!prevClientIds.has(id)) {
|
|
90
|
-
clientIdsChanged = true;
|
|
91
|
-
break;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
if (!clientIdsChanged) {
|
|
96
|
-
for (const id of prevClientIds) {
|
|
97
|
-
if (!newClientIds.has(id)) {
|
|
98
|
-
clientIdsChanged = true;
|
|
99
|
-
break;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (clientIdsChanged) {
|
|
104
|
-
this.connections.clientIds = newClientIds;
|
|
105
|
-
prevClientIds = new Set(newClientIds);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
// Add client to _connections map
|
|
109
|
-
await client.transact([this], ([state]) => {
|
|
110
|
-
state._connections[client.connectionId] = client.id;
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
async onBeforeLeave(client) { }
|
|
114
|
-
async onLeave(client) {
|
|
115
|
-
this._unsubscribeConnectionsHandler();
|
|
116
|
-
}
|
|
117
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { KokimokiStore } from "./kokimoki-store";
|
|
2
|
-
export declare class KokimokiTransaction<T extends object[]> {
|
|
3
|
-
private _updates;
|
|
4
|
-
private _consumeMessagesInRooms;
|
|
5
|
-
private _proxies;
|
|
6
|
-
private _unbindProxies;
|
|
7
|
-
constructor(stores: {
|
|
8
|
-
[K in keyof T]: KokimokiStore<T[K]>;
|
|
9
|
-
});
|
|
10
|
-
getProxies(): T;
|
|
11
|
-
getUpdates(): Promise<{
|
|
12
|
-
updates: {
|
|
13
|
-
roomName: string;
|
|
14
|
-
update: Uint8Array;
|
|
15
|
-
}[];
|
|
16
|
-
consumedMessages: Set<string>;
|
|
17
|
-
}>;
|
|
18
|
-
}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import * as Y from "yjs";
|
|
2
|
-
import { proxy as yjsProxy } from "valtio/vanilla";
|
|
3
|
-
import { bind as yjsBind } from "valtio-yjs";
|
|
4
|
-
export class KokimokiTransaction {
|
|
5
|
-
// private _clones = new Map<
|
|
6
|
-
// string,
|
|
7
|
-
// { docClone: Y.Doc; proxyClone: any; unbindProxy: () => void }
|
|
8
|
-
// >();
|
|
9
|
-
_updates = new Map();
|
|
10
|
-
_consumeMessagesInRooms = new Set();
|
|
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
|
|
18
|
-
const docClone = new Y.Doc();
|
|
19
|
-
const docRoot = docClone.getMap("root");
|
|
20
|
-
Y.applyUpdate(docClone, Y.encodeStateAsUpdate(store.doc));
|
|
21
|
-
// Set up proxy
|
|
22
|
-
const proxyClone = yjsProxy();
|
|
23
|
-
const unbindProxy = yjsBind(proxyClone, docRoot);
|
|
24
|
-
this._proxies.push(proxyClone);
|
|
25
|
-
this._unbindProxies.push(unbindProxy);
|
|
26
|
-
// Listen for updates
|
|
27
|
-
docClone.on("update", (update) => {
|
|
28
|
-
if (this._updates.has(store.roomName)) {
|
|
29
|
-
const prevUpdate = this._updates.get(store.roomName);
|
|
30
|
-
const nextUpdate = Y.mergeUpdates([prevUpdate, update]);
|
|
31
|
-
this._updates.set(store.roomName, nextUpdate);
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
this._updates.set(store.roomName, update);
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
// this._clones.set(store.roomName, { docClone, proxyClone, unbindProxy });
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
getProxies() {
|
|
41
|
-
// @ts-ignore
|
|
42
|
-
return this._proxies;
|
|
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
|
-
// }
|
|
127
|
-
async getUpdates() {
|
|
128
|
-
// Wait for doc update handling to finish
|
|
129
|
-
return await new Promise((resolve) => setTimeout(() => {
|
|
130
|
-
// Clean up
|
|
131
|
-
for (const unbindProxy of this._unbindProxies) {
|
|
132
|
-
unbindProxy();
|
|
133
|
-
}
|
|
134
|
-
// Generates updates
|
|
135
|
-
const updates = Array.from(this._updates.entries()).map(([roomName, update]) => ({
|
|
136
|
-
roomName,
|
|
137
|
-
update,
|
|
138
|
-
}));
|
|
139
|
-
// Done
|
|
140
|
-
resolve({ updates, consumedMessages: this._consumeMessagesInRooms });
|
|
141
|
-
}));
|
|
142
|
-
}
|
|
143
|
-
}
|