@kokimoki/app 1.1.0 → 1.2.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/kokimoki-awareness.d.ts +12 -3
- package/dist/kokimoki-awareness.js +52 -18
- package/dist/kokimoki-store.d.ts +1 -0
- package/dist/kokimoki-store.js +3 -0
- package/dist/kokimoki.min.d.ts +13 -3
- package/dist/kokimoki.min.js +56 -19
- package/dist/kokimoki.min.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -2,14 +2,23 @@ import { KokimokiStore } from "./kokimoki-store";
|
|
|
2
2
|
import { KokimokiSchema as S } from "./kokimoki-schema";
|
|
3
3
|
import { RoomSubscriptionMode } from "./room-subscription-mode";
|
|
4
4
|
import type { KokimokiClient } from "./kokimoki-client";
|
|
5
|
-
export declare class KokimokiAwareness extends KokimokiStore<S.Dict<S.Struct<{
|
|
5
|
+
export declare class KokimokiAwareness<Data extends S.Generic<unknown>> extends KokimokiStore<S.Dict<S.Struct<{
|
|
6
6
|
clientId: S.String;
|
|
7
7
|
lastPing: S.Number;
|
|
8
|
-
|
|
8
|
+
data: Data;
|
|
9
|
+
}>>, {
|
|
10
|
+
[clientId: string]: Data["defaultValue"];
|
|
11
|
+
}> {
|
|
12
|
+
readonly dataSchema: Data;
|
|
13
|
+
readonly data: Data["defaultValue"];
|
|
9
14
|
private _pingInterval;
|
|
10
15
|
private _kmClients;
|
|
11
|
-
constructor(roomName: string, mode?: RoomSubscriptionMode, pingTimeout?: number);
|
|
16
|
+
constructor(roomName: string, dataSchema: Data, data: Data["defaultValue"], mode?: RoomSubscriptionMode, pingTimeout?: number);
|
|
12
17
|
onJoin(client: KokimokiClient<any>): Promise<void>;
|
|
13
18
|
onBeforeLeave(client: KokimokiClient<any>): Promise<void>;
|
|
14
19
|
onLeave(client: KokimokiClient<any>): Promise<void>;
|
|
20
|
+
private getConnectedClients;
|
|
21
|
+
subscribe(set: (value: {
|
|
22
|
+
[clientId: string]: Data["defaultValue"];
|
|
23
|
+
}) => void): () => void;
|
|
15
24
|
}
|
|
@@ -1,35 +1,36 @@
|
|
|
1
1
|
import { KokimokiStore } from "./kokimoki-store";
|
|
2
2
|
import { KokimokiSchema as S } from "./kokimoki-schema";
|
|
3
3
|
import { RoomSubscriptionMode } from "./room-subscription-mode";
|
|
4
|
-
export class KokimokiAwareness
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
export class KokimokiAwareness extends KokimokiStore {
|
|
5
|
+
dataSchema;
|
|
6
|
+
data;
|
|
7
7
|
_pingInterval = null;
|
|
8
8
|
_kmClients = new Set();
|
|
9
|
-
|
|
10
|
-
constructor(roomName,
|
|
11
|
-
// public readonly dataSchema: Data,
|
|
12
|
-
// initialData: Data["defaultValue"],
|
|
13
|
-
mode = RoomSubscriptionMode.ReadWrite, pingTimeout = 2500) {
|
|
9
|
+
constructor(roomName, dataSchema, data, mode = RoomSubscriptionMode.ReadWrite, pingTimeout = 2500) {
|
|
14
10
|
super(`/a/${roomName}`, S.dict(S.struct({
|
|
15
11
|
clientId: S.string(),
|
|
16
12
|
lastPing: S.number(),
|
|
17
|
-
|
|
13
|
+
data: dataSchema,
|
|
18
14
|
})), mode);
|
|
19
|
-
|
|
15
|
+
this.dataSchema = dataSchema;
|
|
16
|
+
this.data = data;
|
|
20
17
|
this._pingInterval = setInterval(async () => {
|
|
21
18
|
const kmClients = Array.from(this._kmClients);
|
|
22
19
|
await Promise.all(kmClients.map(async (client) => {
|
|
23
20
|
try {
|
|
24
21
|
await client.transact((t) => {
|
|
25
22
|
const timestamp = client.serverTimestamp();
|
|
26
|
-
// Update self
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
// Update self
|
|
24
|
+
if (this.proxy[client.connectionId]) {
|
|
25
|
+
t.set(this.root[client.connectionId].lastPing, timestamp);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
t.set(this.root[client.connectionId], {
|
|
29
|
+
clientId: client.id,
|
|
30
|
+
lastPing: timestamp,
|
|
31
|
+
data: this.data,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
33
34
|
// Delete clients that haven't pinged in a while
|
|
34
35
|
for (const connectionId in this.proxy) {
|
|
35
36
|
const { lastPing } = this.proxy[connectionId];
|
|
@@ -49,7 +50,7 @@ export class KokimokiAwareness
|
|
|
49
50
|
t.set(this.root[client.connectionId], {
|
|
50
51
|
clientId: client.id,
|
|
51
52
|
lastPing: client.serverTimestamp(),
|
|
52
|
-
|
|
53
|
+
data: this.data,
|
|
53
54
|
});
|
|
54
55
|
});
|
|
55
56
|
}
|
|
@@ -61,4 +62,37 @@ export class KokimokiAwareness
|
|
|
61
62
|
async onLeave(client) {
|
|
62
63
|
this._kmClients.delete(client);
|
|
63
64
|
}
|
|
65
|
+
getConnectedClients() {
|
|
66
|
+
const clients = {};
|
|
67
|
+
for (const clientId in this.proxy) {
|
|
68
|
+
clients[clientId] = this.proxy[clientId].data;
|
|
69
|
+
}
|
|
70
|
+
return clients;
|
|
71
|
+
}
|
|
72
|
+
subscribe(set) {
|
|
73
|
+
let prevConnectionIds = {};
|
|
74
|
+
const handler = () => {
|
|
75
|
+
// Do nothing if only pings have changed
|
|
76
|
+
let changed = false;
|
|
77
|
+
const newConnectionIds = {};
|
|
78
|
+
for (const connectionId in this.proxy) {
|
|
79
|
+
newConnectionIds[connectionId] = true;
|
|
80
|
+
if (!prevConnectionIds[connectionId]) {
|
|
81
|
+
changed = true;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
for (const connectionId in prevConnectionIds) {
|
|
85
|
+
if (!newConnectionIds[connectionId]) {
|
|
86
|
+
changed = true;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (changed) {
|
|
90
|
+
set(this.getConnectedClients());
|
|
91
|
+
prevConnectionIds = newConnectionIds;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
this.doc.on("update", handler);
|
|
95
|
+
set(this.getConnectedClients());
|
|
96
|
+
return () => this.doc.off("update", handler);
|
|
97
|
+
}
|
|
64
98
|
}
|
package/dist/kokimoki-store.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export declare class KokimokiStore<T extends S.Generic<unknown>, SubscribeT = T[
|
|
|
11
11
|
readonly defaultValue: T["defaultValue"];
|
|
12
12
|
readonly docRoot: Y.Map<unknown>;
|
|
13
13
|
constructor(roomName: string, schema: T, mode?: RoomSubscriptionMode);
|
|
14
|
+
get(): T["defaultValue"];
|
|
14
15
|
subscribe(set: (value: SubscribeT) => void): () => void;
|
|
15
16
|
onJoin(client: KokimokiClient): Promise<void>;
|
|
16
17
|
onBeforeLeave(client: KokimokiClient): Promise<void>;
|
package/dist/kokimoki-store.js
CHANGED
package/dist/kokimoki.min.d.ts
CHANGED
|
@@ -220,6 +220,7 @@ declare class KokimokiStore<T extends KokimokiSchema.Generic<unknown>, Subscribe
|
|
|
220
220
|
readonly defaultValue: T["defaultValue"];
|
|
221
221
|
readonly docRoot: Y.Map<unknown>;
|
|
222
222
|
constructor(roomName: string, schema: T, mode?: RoomSubscriptionMode);
|
|
223
|
+
get(): T["defaultValue"];
|
|
223
224
|
subscribe(set: (value: SubscribeT) => void): () => void;
|
|
224
225
|
onJoin(client: KokimokiClient): Promise<void>;
|
|
225
226
|
onBeforeLeave(client: KokimokiClient): Promise<void>;
|
|
@@ -363,16 +364,25 @@ declare class RoomSubscription {
|
|
|
363
364
|
close(): void;
|
|
364
365
|
}
|
|
365
366
|
|
|
366
|
-
declare class KokimokiAwareness extends KokimokiStore<KokimokiSchema.Dict<KokimokiSchema.Struct<{
|
|
367
|
+
declare class KokimokiAwareness<Data extends KokimokiSchema.Generic<unknown>> extends KokimokiStore<KokimokiSchema.Dict<KokimokiSchema.Struct<{
|
|
367
368
|
clientId: KokimokiSchema.String;
|
|
368
369
|
lastPing: KokimokiSchema.Number;
|
|
369
|
-
|
|
370
|
+
data: Data;
|
|
371
|
+
}>>, {
|
|
372
|
+
[clientId: string]: Data["defaultValue"];
|
|
373
|
+
}> {
|
|
374
|
+
readonly dataSchema: Data;
|
|
375
|
+
readonly data: Data["defaultValue"];
|
|
370
376
|
private _pingInterval;
|
|
371
377
|
private _kmClients;
|
|
372
|
-
constructor(roomName: string, mode?: RoomSubscriptionMode, pingTimeout?: number);
|
|
378
|
+
constructor(roomName: string, dataSchema: Data, data: Data["defaultValue"], mode?: RoomSubscriptionMode, pingTimeout?: number);
|
|
373
379
|
onJoin(client: KokimokiClient<any>): Promise<void>;
|
|
374
380
|
onBeforeLeave(client: KokimokiClient<any>): Promise<void>;
|
|
375
381
|
onLeave(client: KokimokiClient<any>): Promise<void>;
|
|
382
|
+
private getConnectedClients;
|
|
383
|
+
subscribe(set: (value: {
|
|
384
|
+
[clientId: string]: Data["defaultValue"];
|
|
385
|
+
}) => void): () => void;
|
|
376
386
|
}
|
|
377
387
|
|
|
378
388
|
export { BooleanField, ConstField, EnumField, Field, type FieldOptions, FloatField, Form, FormArray, FormGroup, ImageField, IntegerField, KokimokiAwareness, KokimokiClient, type KokimokiClientEvents, KokimokiQueue, KokimokiSchema, KokimokiStore, type Paginated, RoomSubscription, RoomSubscriptionMode, TextField, type Upload };
|
package/dist/kokimoki.min.js
CHANGED
|
@@ -634,7 +634,7 @@ function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
|
|
|
634
634
|
var eventsExports = events.exports;
|
|
635
635
|
var EventEmitter$1 = /*@__PURE__*/getDefaultExportFromCjs(eventsExports);
|
|
636
636
|
|
|
637
|
-
const KOKIMOKI_APP_VERSION = "1.
|
|
637
|
+
const KOKIMOKI_APP_VERSION = "1.2.0";
|
|
638
638
|
|
|
639
639
|
/**
|
|
640
640
|
* Utility module to work with key-value stores.
|
|
@@ -12448,6 +12448,9 @@ class KokimokiStore {
|
|
|
12448
12448
|
// Set default value
|
|
12449
12449
|
this.defaultValue = schema.defaultValue;
|
|
12450
12450
|
}
|
|
12451
|
+
get() {
|
|
12452
|
+
return this.proxy;
|
|
12453
|
+
}
|
|
12451
12454
|
subscribe(set) {
|
|
12452
12455
|
// @ts-ignore
|
|
12453
12456
|
const handler = () => set(this.proxy);
|
|
@@ -12489,35 +12492,36 @@ class KokimokiQueue extends KokimokiStore {
|
|
|
12489
12492
|
}
|
|
12490
12493
|
}
|
|
12491
12494
|
|
|
12492
|
-
class KokimokiAwareness
|
|
12493
|
-
|
|
12494
|
-
|
|
12495
|
+
class KokimokiAwareness extends KokimokiStore {
|
|
12496
|
+
dataSchema;
|
|
12497
|
+
data;
|
|
12495
12498
|
_pingInterval = null;
|
|
12496
12499
|
_kmClients = new Set();
|
|
12497
|
-
|
|
12498
|
-
constructor(roomName,
|
|
12499
|
-
// public readonly dataSchema: Data,
|
|
12500
|
-
// initialData: Data["defaultValue"],
|
|
12501
|
-
mode = RoomSubscriptionMode.ReadWrite, pingTimeout = 2500) {
|
|
12500
|
+
constructor(roomName, dataSchema, data, mode = RoomSubscriptionMode.ReadWrite, pingTimeout = 2500) {
|
|
12502
12501
|
super(`/a/${roomName}`, KokimokiSchema.dict(KokimokiSchema.struct({
|
|
12503
12502
|
clientId: KokimokiSchema.string(),
|
|
12504
12503
|
lastPing: KokimokiSchema.number(),
|
|
12505
|
-
|
|
12504
|
+
data: dataSchema,
|
|
12506
12505
|
})), mode);
|
|
12507
|
-
|
|
12506
|
+
this.dataSchema = dataSchema;
|
|
12507
|
+
this.data = data;
|
|
12508
12508
|
this._pingInterval = setInterval(async () => {
|
|
12509
12509
|
const kmClients = Array.from(this._kmClients);
|
|
12510
12510
|
await Promise.all(kmClients.map(async (client) => {
|
|
12511
12511
|
try {
|
|
12512
12512
|
await client.transact((t) => {
|
|
12513
12513
|
const timestamp = client.serverTimestamp();
|
|
12514
|
-
// Update self
|
|
12515
|
-
|
|
12516
|
-
|
|
12517
|
-
|
|
12518
|
-
|
|
12519
|
-
|
|
12520
|
-
|
|
12514
|
+
// Update self
|
|
12515
|
+
if (this.proxy[client.connectionId]) {
|
|
12516
|
+
t.set(this.root[client.connectionId].lastPing, timestamp);
|
|
12517
|
+
}
|
|
12518
|
+
else {
|
|
12519
|
+
t.set(this.root[client.connectionId], {
|
|
12520
|
+
clientId: client.id,
|
|
12521
|
+
lastPing: timestamp,
|
|
12522
|
+
data: this.data,
|
|
12523
|
+
});
|
|
12524
|
+
}
|
|
12521
12525
|
// Delete clients that haven't pinged in a while
|
|
12522
12526
|
for (const connectionId in this.proxy) {
|
|
12523
12527
|
const { lastPing } = this.proxy[connectionId];
|
|
@@ -12537,7 +12541,7 @@ class KokimokiAwareness
|
|
|
12537
12541
|
t.set(this.root[client.connectionId], {
|
|
12538
12542
|
clientId: client.id,
|
|
12539
12543
|
lastPing: client.serverTimestamp(),
|
|
12540
|
-
|
|
12544
|
+
data: this.data,
|
|
12541
12545
|
});
|
|
12542
12546
|
});
|
|
12543
12547
|
}
|
|
@@ -12549,6 +12553,39 @@ class KokimokiAwareness
|
|
|
12549
12553
|
async onLeave(client) {
|
|
12550
12554
|
this._kmClients.delete(client);
|
|
12551
12555
|
}
|
|
12556
|
+
getConnectedClients() {
|
|
12557
|
+
const clients = {};
|
|
12558
|
+
for (const clientId in this.proxy) {
|
|
12559
|
+
clients[clientId] = this.proxy[clientId].data;
|
|
12560
|
+
}
|
|
12561
|
+
return clients;
|
|
12562
|
+
}
|
|
12563
|
+
subscribe(set) {
|
|
12564
|
+
let prevConnectionIds = {};
|
|
12565
|
+
const handler = () => {
|
|
12566
|
+
// Do nothing if only pings have changed
|
|
12567
|
+
let changed = false;
|
|
12568
|
+
const newConnectionIds = {};
|
|
12569
|
+
for (const connectionId in this.proxy) {
|
|
12570
|
+
newConnectionIds[connectionId] = true;
|
|
12571
|
+
if (!prevConnectionIds[connectionId]) {
|
|
12572
|
+
changed = true;
|
|
12573
|
+
}
|
|
12574
|
+
}
|
|
12575
|
+
for (const connectionId in prevConnectionIds) {
|
|
12576
|
+
if (!newConnectionIds[connectionId]) {
|
|
12577
|
+
changed = true;
|
|
12578
|
+
}
|
|
12579
|
+
}
|
|
12580
|
+
if (changed) {
|
|
12581
|
+
set(this.getConnectedClients());
|
|
12582
|
+
prevConnectionIds = newConnectionIds;
|
|
12583
|
+
}
|
|
12584
|
+
};
|
|
12585
|
+
this.doc.on("update", handler);
|
|
12586
|
+
set(this.getConnectedClients());
|
|
12587
|
+
return () => this.doc.off("update", handler);
|
|
12588
|
+
}
|
|
12552
12589
|
}
|
|
12553
12590
|
|
|
12554
12591
|
export { BooleanField, ConstField, EnumField, Field, FloatField, Form, FormArray, FormGroup, ImageField, IntegerField, KokimokiAwareness, KokimokiClient, KokimokiQueue, KokimokiSchema, KokimokiStore, RoomSubscription, RoomSubscriptionMode, TextField };
|