@kokimoki/app 1.16.0 → 1.16.2
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/kokimoki-client.js +1 -1
- package/dist/kokimoki-store.d.ts +5 -11
- package/dist/kokimoki-store.js +81 -13
- package/dist/kokimoki.min.d.ts +5 -11
- package/dist/kokimoki.min.js +85 -14
- package/dist/kokimoki.min.js.map +1 -1
- package/dist/room-subscription.js +3 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/kokimoki-client.js
CHANGED
|
@@ -461,7 +461,7 @@ export class KokimokiClient extends EventEmitter {
|
|
|
461
461
|
this._subscriptionsByHash.set(res.roomHash, subscription);
|
|
462
462
|
await subscription.applyInitialResponse(res.roomHash, res.initialUpdate);
|
|
463
463
|
// Trigger onJoin event
|
|
464
|
-
store.onJoin(this);
|
|
464
|
+
await store.onJoin(this);
|
|
465
465
|
}
|
|
466
466
|
}
|
|
467
467
|
async leave(store) {
|
package/dist/kokimoki-store.d.ts
CHANGED
|
@@ -7,23 +7,17 @@ export declare class KokimokiStore<T extends object> {
|
|
|
7
7
|
readonly defaultValue: T;
|
|
8
8
|
readonly mode: RoomSubscriptionMode;
|
|
9
9
|
readonly doc: Y.Doc;
|
|
10
|
-
readonly proxy: T
|
|
11
|
-
_km_connections?: {
|
|
12
|
-
[connectionId: string]: string;
|
|
13
|
-
};
|
|
14
|
-
};
|
|
10
|
+
readonly proxy: T;
|
|
15
11
|
readonly docRoot: Y.Map<unknown>;
|
|
16
12
|
readonly connections: {
|
|
13
|
+
connectionIds: Set<string>;
|
|
17
14
|
clientIds: Set<string>;
|
|
18
15
|
};
|
|
16
|
+
private _unsubscribeConnectionsHandler;
|
|
19
17
|
constructor(roomName: string, defaultValue: T, mode?: RoomSubscriptionMode);
|
|
20
|
-
get(): Snapshot<T
|
|
21
|
-
_km_connections?: {
|
|
22
|
-
[connectionId: string]: string;
|
|
23
|
-
} | undefined;
|
|
24
|
-
}>;
|
|
18
|
+
get(): Snapshot<T>;
|
|
25
19
|
subscribe(set: (value: Snapshot<T>) => void): () => void;
|
|
26
|
-
onJoin(client: KokimokiClient): Promise<void>;
|
|
20
|
+
onJoin(client: KokimokiClient<any>): Promise<void>;
|
|
27
21
|
onBeforeLeave(client: KokimokiClient): Promise<void>;
|
|
28
22
|
onLeave(client: KokimokiClient): Promise<void>;
|
|
29
23
|
}
|
package/dist/kokimoki-store.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Y from "yjs";
|
|
2
|
-
import {
|
|
2
|
+
import { snapshot, proxy, subscribe } from "valtio/vanilla";
|
|
3
3
|
import { bind as yjsBind } from "valtio-yjs";
|
|
4
4
|
import { RoomSubscriptionMode } from "./room-subscription-mode";
|
|
5
5
|
export class KokimokiStore {
|
|
@@ -10,10 +10,15 @@ export class KokimokiStore {
|
|
|
10
10
|
proxy;
|
|
11
11
|
docRoot;
|
|
12
12
|
connections;
|
|
13
|
+
_unsubscribeConnectionsHandler = () => { };
|
|
13
14
|
constructor(roomName, defaultValue, mode = RoomSubscriptionMode.ReadWrite) {
|
|
14
15
|
this.roomName = roomName;
|
|
15
16
|
this.defaultValue = defaultValue;
|
|
16
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
|
+
}
|
|
17
22
|
// Construct Y doc
|
|
18
23
|
this.doc = new Y.Doc();
|
|
19
24
|
this.docRoot = this.doc.getMap("root");
|
|
@@ -22,16 +27,9 @@ export class KokimokiStore {
|
|
|
22
27
|
// @ts-ignore
|
|
23
28
|
yjsBind(this.proxy, this.docRoot);
|
|
24
29
|
// Construct connections proxy
|
|
25
|
-
this.connections = proxy({
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const kmConnections = this.proxy._km_connections;
|
|
29
|
-
if (kmConnections) {
|
|
30
|
-
this.connections.clientIds = new Set(Object.values(kmConnections));
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
this.connections.clientIds = new Set();
|
|
34
|
-
}
|
|
30
|
+
this.connections = proxy({
|
|
31
|
+
connectionIds: new Set(),
|
|
32
|
+
clientIds: new Set(),
|
|
35
33
|
});
|
|
36
34
|
}
|
|
37
35
|
get() {
|
|
@@ -43,7 +41,77 @@ export class KokimokiStore {
|
|
|
43
41
|
set(this.get());
|
|
44
42
|
return () => this.doc.off("update", handler);
|
|
45
43
|
}
|
|
46
|
-
async onJoin(client) {
|
|
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
|
+
}
|
|
47
113
|
async onBeforeLeave(client) { }
|
|
48
|
-
async onLeave(client) {
|
|
114
|
+
async onLeave(client) {
|
|
115
|
+
this._unsubscribeConnectionsHandler();
|
|
116
|
+
}
|
|
49
117
|
}
|
package/dist/kokimoki.min.d.ts
CHANGED
|
@@ -36,23 +36,17 @@ declare class KokimokiStore<T extends object> {
|
|
|
36
36
|
readonly defaultValue: T;
|
|
37
37
|
readonly mode: RoomSubscriptionMode;
|
|
38
38
|
readonly doc: Y.Doc;
|
|
39
|
-
readonly proxy: T
|
|
40
|
-
_km_connections?: {
|
|
41
|
-
[connectionId: string]: string;
|
|
42
|
-
};
|
|
43
|
-
};
|
|
39
|
+
readonly proxy: T;
|
|
44
40
|
readonly docRoot: Y.Map<unknown>;
|
|
45
41
|
readonly connections: {
|
|
42
|
+
connectionIds: Set<string>;
|
|
46
43
|
clientIds: Set<string>;
|
|
47
44
|
};
|
|
45
|
+
private _unsubscribeConnectionsHandler;
|
|
48
46
|
constructor(roomName: string, defaultValue: T, mode?: RoomSubscriptionMode);
|
|
49
|
-
get(): Snapshot<T
|
|
50
|
-
_km_connections?: {
|
|
51
|
-
[connectionId: string]: string;
|
|
52
|
-
} | undefined;
|
|
53
|
-
}>;
|
|
47
|
+
get(): Snapshot<T>;
|
|
54
48
|
subscribe(set: (value: Snapshot<T>) => void): () => void;
|
|
55
|
-
onJoin(client: KokimokiClient): Promise<void>;
|
|
49
|
+
onJoin(client: KokimokiClient<any>): Promise<void>;
|
|
56
50
|
onBeforeLeave(client: KokimokiClient): Promise<void>;
|
|
57
51
|
onLeave(client: KokimokiClient): Promise<void>;
|
|
58
52
|
}
|
package/dist/kokimoki.min.js
CHANGED
|
@@ -486,7 +486,7 @@ function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
|
|
|
486
486
|
var eventsExports = events.exports;
|
|
487
487
|
var EventEmitter$1 = /*@__PURE__*/getDefaultExportFromCjs(eventsExports);
|
|
488
488
|
|
|
489
|
-
const KOKIMOKI_APP_VERSION = "1.
|
|
489
|
+
const KOKIMOKI_APP_VERSION = "1.16.1";
|
|
490
490
|
|
|
491
491
|
/**
|
|
492
492
|
* Utility module to work with key-value stores.
|
|
@@ -12005,10 +12005,15 @@ class KokimokiStore {
|
|
|
12005
12005
|
proxy;
|
|
12006
12006
|
docRoot;
|
|
12007
12007
|
connections;
|
|
12008
|
+
_unsubscribeConnectionsHandler = () => { };
|
|
12008
12009
|
constructor(roomName, defaultValue, mode = RoomSubscriptionMode.ReadWrite) {
|
|
12009
12010
|
this.roomName = roomName;
|
|
12010
12011
|
this.defaultValue = defaultValue;
|
|
12011
12012
|
this.mode = mode;
|
|
12013
|
+
// "_connections" is a reserved key for tracking connections
|
|
12014
|
+
if ("_connections" in defaultValue) {
|
|
12015
|
+
throw new Error(`"_connections" is a reserved key in KokimokiStore`);
|
|
12016
|
+
}
|
|
12012
12017
|
// Construct Y doc
|
|
12013
12018
|
this.doc = new Doc();
|
|
12014
12019
|
this.docRoot = this.doc.getMap("root");
|
|
@@ -12017,16 +12022,9 @@ class KokimokiStore {
|
|
|
12017
12022
|
// @ts-ignore
|
|
12018
12023
|
bind$1(this.proxy, this.docRoot);
|
|
12019
12024
|
// Construct connections proxy
|
|
12020
|
-
this.connections = proxy({
|
|
12021
|
-
|
|
12022
|
-
|
|
12023
|
-
const kmConnections = this.proxy._km_connections;
|
|
12024
|
-
if (kmConnections) {
|
|
12025
|
-
this.connections.clientIds = new Set(Object.values(kmConnections));
|
|
12026
|
-
}
|
|
12027
|
-
else {
|
|
12028
|
-
this.connections.clientIds = new Set();
|
|
12029
|
-
}
|
|
12025
|
+
this.connections = proxy({
|
|
12026
|
+
connectionIds: new Set(),
|
|
12027
|
+
clientIds: new Set(),
|
|
12030
12028
|
});
|
|
12031
12029
|
}
|
|
12032
12030
|
get() {
|
|
@@ -12038,9 +12036,79 @@ class KokimokiStore {
|
|
|
12038
12036
|
set(this.get());
|
|
12039
12037
|
return () => this.doc.off("update", handler);
|
|
12040
12038
|
}
|
|
12041
|
-
async onJoin(client) {
|
|
12039
|
+
async onJoin(client) {
|
|
12040
|
+
// Update connections whenever _connections changes
|
|
12041
|
+
let prevConnectionIds = new Set();
|
|
12042
|
+
let prevClientIds = new Set();
|
|
12043
|
+
this._unsubscribeConnectionsHandler = subscribe(this.proxy, () => {
|
|
12044
|
+
// @ts-ignore
|
|
12045
|
+
const newConnectionIds = new Set(
|
|
12046
|
+
// @ts-ignore
|
|
12047
|
+
Object.keys(this.proxy._connections || {}));
|
|
12048
|
+
// Update only if there are changes
|
|
12049
|
+
let connectionIdsChanged = false;
|
|
12050
|
+
if (newConnectionIds.size !== prevConnectionIds.size) {
|
|
12051
|
+
connectionIdsChanged = true;
|
|
12052
|
+
}
|
|
12053
|
+
if (!connectionIdsChanged) {
|
|
12054
|
+
for (const id of newConnectionIds) {
|
|
12055
|
+
if (!prevConnectionIds.has(id)) {
|
|
12056
|
+
connectionIdsChanged = true;
|
|
12057
|
+
break;
|
|
12058
|
+
}
|
|
12059
|
+
}
|
|
12060
|
+
}
|
|
12061
|
+
if (!connectionIdsChanged) {
|
|
12062
|
+
for (const id of prevConnectionIds) {
|
|
12063
|
+
if (!newConnectionIds.has(id)) {
|
|
12064
|
+
connectionIdsChanged = true;
|
|
12065
|
+
break;
|
|
12066
|
+
}
|
|
12067
|
+
}
|
|
12068
|
+
}
|
|
12069
|
+
if (connectionIdsChanged) {
|
|
12070
|
+
this.connections.connectionIds = newConnectionIds;
|
|
12071
|
+
prevConnectionIds = new Set(newConnectionIds);
|
|
12072
|
+
}
|
|
12073
|
+
// @ts-ignore
|
|
12074
|
+
const newClientIds = new Set(
|
|
12075
|
+
// @ts-ignore
|
|
12076
|
+
Object.values(this.proxy._connections || {}));
|
|
12077
|
+
// Update only if there are changes
|
|
12078
|
+
let clientIdsChanged = false;
|
|
12079
|
+
if (newClientIds.size !== prevClientIds.size) {
|
|
12080
|
+
clientIdsChanged = true;
|
|
12081
|
+
}
|
|
12082
|
+
if (!clientIdsChanged) {
|
|
12083
|
+
for (const id of newClientIds) {
|
|
12084
|
+
if (!prevClientIds.has(id)) {
|
|
12085
|
+
clientIdsChanged = true;
|
|
12086
|
+
break;
|
|
12087
|
+
}
|
|
12088
|
+
}
|
|
12089
|
+
}
|
|
12090
|
+
if (!clientIdsChanged) {
|
|
12091
|
+
for (const id of prevClientIds) {
|
|
12092
|
+
if (!newClientIds.has(id)) {
|
|
12093
|
+
clientIdsChanged = true;
|
|
12094
|
+
break;
|
|
12095
|
+
}
|
|
12096
|
+
}
|
|
12097
|
+
}
|
|
12098
|
+
if (clientIdsChanged) {
|
|
12099
|
+
this.connections.clientIds = newClientIds;
|
|
12100
|
+
prevClientIds = new Set(newClientIds);
|
|
12101
|
+
}
|
|
12102
|
+
});
|
|
12103
|
+
// Add client to _connections map
|
|
12104
|
+
await client.transact([this], ([state]) => {
|
|
12105
|
+
state._connections[client.connectionId] = client.id;
|
|
12106
|
+
});
|
|
12107
|
+
}
|
|
12042
12108
|
async onBeforeLeave(client) { }
|
|
12043
|
-
async onLeave(client) {
|
|
12109
|
+
async onLeave(client) {
|
|
12110
|
+
this._unsubscribeConnectionsHandler();
|
|
12111
|
+
}
|
|
12044
12112
|
}
|
|
12045
12113
|
|
|
12046
12114
|
var WsMessageType;
|
|
@@ -12173,6 +12241,9 @@ class RoomSubscription {
|
|
|
12173
12241
|
// Set defaults if doc is empty after sync (only possible in ReadWrite mode)
|
|
12174
12242
|
if (this.store.mode === RoomSubscriptionMode.ReadWrite) {
|
|
12175
12243
|
await this.kmClient.transact([this.store], ([state]) => {
|
|
12244
|
+
if (!("_connections" in state)) {
|
|
12245
|
+
state._connections = {};
|
|
12246
|
+
}
|
|
12176
12247
|
for (const key in this.store.defaultValue) {
|
|
12177
12248
|
if (!state.hasOwnProperty(key)) {
|
|
12178
12249
|
state[key] = this.store.defaultValue[key];
|
|
@@ -15242,7 +15313,7 @@ class KokimokiClient extends EventEmitter$1 {
|
|
|
15242
15313
|
this._subscriptionsByHash.set(res.roomHash, subscription);
|
|
15243
15314
|
await subscription.applyInitialResponse(res.roomHash, res.initialUpdate);
|
|
15244
15315
|
// Trigger onJoin event
|
|
15245
|
-
store.onJoin(this);
|
|
15316
|
+
await store.onJoin(this);
|
|
15246
15317
|
}
|
|
15247
15318
|
}
|
|
15248
15319
|
async leave(store) {
|