@kokimoki/app 1.16.1 → 1.17.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.
@@ -145,5 +145,12 @@ export declare class KokimokiClient<ClientContextT = any> extends KokimokiClient
145
145
  * Use AI to apply prompt to an image
146
146
  */
147
147
  transformImage(baseImageUrl: string, prompt: string, tags?: string[]): Promise<Upload>;
148
+ /**
149
+ * Load app config - optionally translated to any language
150
+ */
151
+ getConfig<T>(language?: string): Promise<{
152
+ status: "processing" | "failed" | "completed";
153
+ config: T;
154
+ }>;
148
155
  }
149
156
  export {};
@@ -744,4 +744,17 @@ export class KokimokiClient extends EventEmitter {
744
744
  }
745
745
  return await res.json();
746
746
  }
747
+ /**
748
+ * Load app config - optionally translated to any language
749
+ */
750
+ async getConfig(language = "") {
751
+ const res = await fetch(`${this._apiUrl}/app/config?language=${encodeURIComponent(language)}`, {
752
+ headers: this.apiHeaders,
753
+ });
754
+ if (!res.ok) {
755
+ throw await res.json();
756
+ }
757
+ const { status, config } = await res.json();
758
+ return { status, config };
759
+ }
747
760
  }
@@ -10,8 +10,10 @@ export declare class KokimokiStore<T extends object> {
10
10
  readonly proxy: T;
11
11
  readonly docRoot: Y.Map<unknown>;
12
12
  readonly connections: {
13
+ connectionIds: Set<string>;
13
14
  clientIds: Set<string>;
14
15
  };
16
+ private _unsubscribeConnectionsHandler;
15
17
  constructor(roomName: string, defaultValue: T, mode?: RoomSubscriptionMode);
16
18
  get(): Snapshot<T>;
17
19
  subscribe(set: (value: Snapshot<T>) => void): () => void;
@@ -10,6 +10,7 @@ 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;
@@ -26,55 +27,91 @@ export class KokimokiStore {
26
27
  // @ts-ignore
27
28
  yjsBind(this.proxy, this.docRoot);
28
29
  // Construct connections proxy
29
- this.connections = proxy({ clientIds: new Set() });
30
- // Update connections.clientIds whenever _connections changes
31
- let prevConnections = new Set();
32
- subscribe(this.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, () => {
33
49
  // @ts-ignore
34
- const newConnections = new Set(
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(
35
80
  // @ts-ignore
36
81
  Object.values(this.proxy._connections || {}));
37
82
  // Update only if there are changes
38
- let changed = false;
39
- if (newConnections.size !== prevConnections.size) {
40
- changed = true;
83
+ let clientIdsChanged = false;
84
+ if (newClientIds.size !== prevClientIds.size) {
85
+ clientIdsChanged = true;
41
86
  }
42
- if (!changed) {
43
- for (const id of newConnections) {
44
- if (!prevConnections.has(id)) {
45
- changed = true;
87
+ if (!clientIdsChanged) {
88
+ for (const id of newClientIds) {
89
+ if (!prevClientIds.has(id)) {
90
+ clientIdsChanged = true;
46
91
  break;
47
92
  }
48
93
  }
49
94
  }
50
- if (!changed) {
51
- for (const id of prevConnections) {
52
- if (!newConnections.has(id)) {
53
- changed = true;
95
+ if (!clientIdsChanged) {
96
+ for (const id of prevClientIds) {
97
+ if (!newClientIds.has(id)) {
98
+ clientIdsChanged = true;
54
99
  break;
55
100
  }
56
101
  }
57
102
  }
58
- if (changed) {
59
- this.connections.clientIds = newConnections;
60
- prevConnections = new Set(newConnections);
103
+ if (clientIdsChanged) {
104
+ this.connections.clientIds = newClientIds;
105
+ prevClientIds = new Set(newClientIds);
61
106
  }
62
107
  });
63
- }
64
- get() {
65
- return snapshot(this.proxy);
66
- }
67
- subscribe(set) {
68
- const handler = () => set(this.get());
69
- this.doc.on("update", handler);
70
- set(this.get());
71
- return () => this.doc.off("update", handler);
72
- }
73
- async onJoin(client) {
108
+ // Add client to _connections map
74
109
  await client.transact([this], ([state]) => {
75
110
  state._connections[client.connectionId] = client.id;
76
111
  });
77
112
  }
78
113
  async onBeforeLeave(client) { }
79
- async onLeave(client) { }
114
+ async onLeave(client) {
115
+ this._unsubscribeConnectionsHandler();
116
+ }
80
117
  }
@@ -39,8 +39,10 @@ declare class KokimokiStore<T extends object> {
39
39
  readonly proxy: T;
40
40
  readonly docRoot: Y.Map<unknown>;
41
41
  readonly connections: {
42
+ connectionIds: Set<string>;
42
43
  clientIds: Set<string>;
43
44
  };
45
+ private _unsubscribeConnectionsHandler;
44
46
  constructor(roomName: string, defaultValue: T, mode?: RoomSubscriptionMode);
45
47
  get(): Snapshot<T>;
46
48
  subscribe(set: (value: Snapshot<T>) => void): () => void;
@@ -217,6 +219,13 @@ declare class KokimokiClient<ClientContextT = any> extends KokimokiClient_base {
217
219
  * Use AI to apply prompt to an image
218
220
  */
219
221
  transformImage(baseImageUrl: string, prompt: string, tags?: string[]): Promise<Upload>;
222
+ /**
223
+ * Load app config - optionally translated to any language
224
+ */
225
+ getConfig<T>(language?: string): Promise<{
226
+ status: "processing" | "failed" | "completed";
227
+ config: T;
228
+ }>;
220
229
  }
221
230
 
222
231
  declare class RoomSubscription {
@@ -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.16.1";
489
+ const KOKIMOKI_APP_VERSION = "1.17.0";
490
490
 
491
491
  /**
492
492
  * Utility module to work with key-value stores.
@@ -12005,6 +12005,7 @@ 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;
@@ -12021,57 +12022,93 @@ class KokimokiStore {
12021
12022
  // @ts-ignore
12022
12023
  bind$1(this.proxy, this.docRoot);
12023
12024
  // Construct connections proxy
12024
- this.connections = proxy({ clientIds: new Set() });
12025
- // Update connections.clientIds whenever _connections changes
12026
- let prevConnections = new Set();
12027
- subscribe(this.proxy, () => {
12025
+ this.connections = proxy({
12026
+ connectionIds: new Set(),
12027
+ clientIds: new Set(),
12028
+ });
12029
+ }
12030
+ get() {
12031
+ return snapshot(this.proxy);
12032
+ }
12033
+ subscribe(set) {
12034
+ const handler = () => set(this.get());
12035
+ this.doc.on("update", handler);
12036
+ set(this.get());
12037
+ return () => this.doc.off("update", handler);
12038
+ }
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
+ }
12028
12073
  // @ts-ignore
12029
- const newConnections = new Set(
12074
+ const newClientIds = new Set(
12030
12075
  // @ts-ignore
12031
12076
  Object.values(this.proxy._connections || {}));
12032
12077
  // Update only if there are changes
12033
- let changed = false;
12034
- if (newConnections.size !== prevConnections.size) {
12035
- changed = true;
12078
+ let clientIdsChanged = false;
12079
+ if (newClientIds.size !== prevClientIds.size) {
12080
+ clientIdsChanged = true;
12036
12081
  }
12037
- if (!changed) {
12038
- for (const id of newConnections) {
12039
- if (!prevConnections.has(id)) {
12040
- changed = true;
12082
+ if (!clientIdsChanged) {
12083
+ for (const id of newClientIds) {
12084
+ if (!prevClientIds.has(id)) {
12085
+ clientIdsChanged = true;
12041
12086
  break;
12042
12087
  }
12043
12088
  }
12044
12089
  }
12045
- if (!changed) {
12046
- for (const id of prevConnections) {
12047
- if (!newConnections.has(id)) {
12048
- changed = true;
12090
+ if (!clientIdsChanged) {
12091
+ for (const id of prevClientIds) {
12092
+ if (!newClientIds.has(id)) {
12093
+ clientIdsChanged = true;
12049
12094
  break;
12050
12095
  }
12051
12096
  }
12052
12097
  }
12053
- if (changed) {
12054
- this.connections.clientIds = newConnections;
12055
- prevConnections = new Set(newConnections);
12098
+ if (clientIdsChanged) {
12099
+ this.connections.clientIds = newClientIds;
12100
+ prevClientIds = new Set(newClientIds);
12056
12101
  }
12057
12102
  });
12058
- }
12059
- get() {
12060
- return snapshot(this.proxy);
12061
- }
12062
- subscribe(set) {
12063
- const handler = () => set(this.get());
12064
- this.doc.on("update", handler);
12065
- set(this.get());
12066
- return () => this.doc.off("update", handler);
12067
- }
12068
- async onJoin(client) {
12103
+ // Add client to _connections map
12069
12104
  await client.transact([this], ([state]) => {
12070
12105
  state._connections[client.connectionId] = client.id;
12071
12106
  });
12072
12107
  }
12073
12108
  async onBeforeLeave(client) { }
12074
- async onLeave(client) { }
12109
+ async onLeave(client) {
12110
+ this._unsubscribeConnectionsHandler();
12111
+ }
12075
12112
  }
12076
12113
 
12077
12114
  var WsMessageType;
@@ -15559,6 +15596,19 @@ class KokimokiClient extends EventEmitter$1 {
15559
15596
  }
15560
15597
  return await res.json();
15561
15598
  }
15599
+ /**
15600
+ * Load app config - optionally translated to any language
15601
+ */
15602
+ async getConfig(language = "") {
15603
+ const res = await fetch(`${this._apiUrl}/app/config?language=${encodeURIComponent(language)}`, {
15604
+ headers: this.apiHeaders,
15605
+ });
15606
+ if (!res.ok) {
15607
+ throw await res.json();
15608
+ }
15609
+ const { status, config } = await res.json();
15610
+ return { status, config };
15611
+ }
15562
15612
  }
15563
15613
 
15564
15614
  export { KokimokiAwareness, KokimokiClient, KokimokiStore, RoomSubscription, RoomSubscriptionMode };