@kokimoki/app 1.1.1 → 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.min.d.ts +12 -3
- package/dist/kokimoki.min.js +53 -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.min.d.ts
CHANGED
|
@@ -364,16 +364,25 @@ declare class RoomSubscription {
|
|
|
364
364
|
close(): void;
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
-
declare class KokimokiAwareness extends KokimokiStore<KokimokiSchema.Dict<KokimokiSchema.Struct<{
|
|
367
|
+
declare class KokimokiAwareness<Data extends KokimokiSchema.Generic<unknown>> extends KokimokiStore<KokimokiSchema.Dict<KokimokiSchema.Struct<{
|
|
368
368
|
clientId: KokimokiSchema.String;
|
|
369
369
|
lastPing: KokimokiSchema.Number;
|
|
370
|
-
|
|
370
|
+
data: Data;
|
|
371
|
+
}>>, {
|
|
372
|
+
[clientId: string]: Data["defaultValue"];
|
|
373
|
+
}> {
|
|
374
|
+
readonly dataSchema: Data;
|
|
375
|
+
readonly data: Data["defaultValue"];
|
|
371
376
|
private _pingInterval;
|
|
372
377
|
private _kmClients;
|
|
373
|
-
constructor(roomName: string, mode?: RoomSubscriptionMode, pingTimeout?: number);
|
|
378
|
+
constructor(roomName: string, dataSchema: Data, data: Data["defaultValue"], mode?: RoomSubscriptionMode, pingTimeout?: number);
|
|
374
379
|
onJoin(client: KokimokiClient<any>): Promise<void>;
|
|
375
380
|
onBeforeLeave(client: KokimokiClient<any>): Promise<void>;
|
|
376
381
|
onLeave(client: KokimokiClient<any>): Promise<void>;
|
|
382
|
+
private getConnectedClients;
|
|
383
|
+
subscribe(set: (value: {
|
|
384
|
+
[clientId: string]: Data["defaultValue"];
|
|
385
|
+
}) => void): () => void;
|
|
377
386
|
}
|
|
378
387
|
|
|
379
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.
|
|
@@ -12492,35 +12492,36 @@ class KokimokiQueue extends KokimokiStore {
|
|
|
12492
12492
|
}
|
|
12493
12493
|
}
|
|
12494
12494
|
|
|
12495
|
-
class KokimokiAwareness
|
|
12496
|
-
|
|
12497
|
-
|
|
12495
|
+
class KokimokiAwareness extends KokimokiStore {
|
|
12496
|
+
dataSchema;
|
|
12497
|
+
data;
|
|
12498
12498
|
_pingInterval = null;
|
|
12499
12499
|
_kmClients = new Set();
|
|
12500
|
-
|
|
12501
|
-
constructor(roomName,
|
|
12502
|
-
// public readonly dataSchema: Data,
|
|
12503
|
-
// initialData: Data["defaultValue"],
|
|
12504
|
-
mode = RoomSubscriptionMode.ReadWrite, pingTimeout = 2500) {
|
|
12500
|
+
constructor(roomName, dataSchema, data, mode = RoomSubscriptionMode.ReadWrite, pingTimeout = 2500) {
|
|
12505
12501
|
super(`/a/${roomName}`, KokimokiSchema.dict(KokimokiSchema.struct({
|
|
12506
12502
|
clientId: KokimokiSchema.string(),
|
|
12507
12503
|
lastPing: KokimokiSchema.number(),
|
|
12508
|
-
|
|
12504
|
+
data: dataSchema,
|
|
12509
12505
|
})), mode);
|
|
12510
|
-
|
|
12506
|
+
this.dataSchema = dataSchema;
|
|
12507
|
+
this.data = data;
|
|
12511
12508
|
this._pingInterval = setInterval(async () => {
|
|
12512
12509
|
const kmClients = Array.from(this._kmClients);
|
|
12513
12510
|
await Promise.all(kmClients.map(async (client) => {
|
|
12514
12511
|
try {
|
|
12515
12512
|
await client.transact((t) => {
|
|
12516
12513
|
const timestamp = client.serverTimestamp();
|
|
12517
|
-
// Update self
|
|
12518
|
-
|
|
12519
|
-
|
|
12520
|
-
|
|
12521
|
-
|
|
12522
|
-
|
|
12523
|
-
|
|
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
|
+
}
|
|
12524
12525
|
// Delete clients that haven't pinged in a while
|
|
12525
12526
|
for (const connectionId in this.proxy) {
|
|
12526
12527
|
const { lastPing } = this.proxy[connectionId];
|
|
@@ -12540,7 +12541,7 @@ class KokimokiAwareness
|
|
|
12540
12541
|
t.set(this.root[client.connectionId], {
|
|
12541
12542
|
clientId: client.id,
|
|
12542
12543
|
lastPing: client.serverTimestamp(),
|
|
12543
|
-
|
|
12544
|
+
data: this.data,
|
|
12544
12545
|
});
|
|
12545
12546
|
});
|
|
12546
12547
|
}
|
|
@@ -12552,6 +12553,39 @@ class KokimokiAwareness
|
|
|
12552
12553
|
async onLeave(client) {
|
|
12553
12554
|
this._kmClients.delete(client);
|
|
12554
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
|
+
}
|
|
12555
12589
|
}
|
|
12556
12590
|
|
|
12557
12591
|
export { BooleanField, ConstField, EnumField, Field, FloatField, Form, FormArray, FormGroup, ImageField, IntegerField, KokimokiAwareness, KokimokiClient, KokimokiQueue, KokimokiSchema, KokimokiStore, RoomSubscription, RoomSubscriptionMode, TextField };
|