@kokimoki/app 2.1.0 → 3.0.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/README.md +72 -0
- package/dist/core/kokimoki-client.d.ts +75 -15
- package/dist/core/kokimoki-client.js +137 -22
- package/dist/index.d.ts +6 -1
- package/dist/index.js +4 -0
- package/dist/kokimoki.min.d.ts +322 -2
- package/dist/kokimoki.min.js +1884 -72
- package/dist/kokimoki.min.js.map +1 -1
- package/dist/llms.txt +6 -0
- package/dist/protocol/ws-message/reader.d.ts +1 -1
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/kokimoki-ai.d.ts +185 -122
- package/dist/services/kokimoki-ai.js +201 -109
- package/dist/services/kokimoki-i18n.d.ts +259 -0
- package/dist/services/kokimoki-i18n.js +325 -0
- package/dist/stores/kokimoki-local-store.d.ts +1 -1
- package/dist/types/common.d.ts +9 -0
- package/dist/types/env.d.ts +36 -0
- package/dist/types/env.js +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/kokimoki-client.d.ts +31 -0
- package/dist/utils/kokimoki-client.js +38 -0
- package/dist/utils/kokimoki-dev.d.ts +30 -0
- package/dist/utils/kokimoki-dev.js +75 -0
- package/dist/utils/kokimoki-env.d.ts +20 -0
- package/dist/utils/kokimoki-env.js +30 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/kokimoki-ai.instructions.md +316 -0
- package/docs/kokimoki-dynamic-stores.instructions.md +439 -0
- package/docs/kokimoki-i18n.instructions.md +285 -0
- package/docs/kokimoki-leaderboard.instructions.md +189 -0
- package/docs/kokimoki-sdk.instructions.md +221 -0
- package/docs/kokimoki-storage.instructions.md +162 -0
- package/llms.txt +43 -0
- package/package.json +9 -13
package/README.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# @kokimoki/app
|
|
2
|
+
|
|
3
|
+
The core SDK for building real-time multiplayer games with Kokimoki.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @kokimoki/app
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { getKmClient } from "@kokimoki/app";
|
|
15
|
+
|
|
16
|
+
const kmClient = getKmClient();
|
|
17
|
+
|
|
18
|
+
// Create a synchronized store
|
|
19
|
+
const gameStore = kmClient.store("game", {
|
|
20
|
+
players: {},
|
|
21
|
+
status: "waiting",
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Update state with transactions
|
|
25
|
+
await kmClient.transact([gameStore], ([state]) => {
|
|
26
|
+
state.players[kmClient.id] = { name: "Player 1", score: 0 };
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Features
|
|
31
|
+
|
|
32
|
+
- **Real-time State Sync** - Synchronized stores across all connected clients
|
|
33
|
+
- **Dynamic Stores** - Room-based state isolation for teams, chat, breakout rooms
|
|
34
|
+
- **AI Services** - Text and image generation
|
|
35
|
+
- **Storage** - File uploads to CDN
|
|
36
|
+
- **i18n** - Internationalization with AI-powered translation
|
|
37
|
+
- **Leaderboards** - Player rankings and scores
|
|
38
|
+
|
|
39
|
+
## Documentation
|
|
40
|
+
|
|
41
|
+
See the [docs](./docs/) folder for detailed instructions:
|
|
42
|
+
|
|
43
|
+
| File | Description |
|
|
44
|
+
| ----------------------------------------------------------------------------------------- | --------------------------------------------- |
|
|
45
|
+
| [kokimoki-sdk.instructions.md](./docs/kokimoki-sdk.instructions.md) | Core SDK usage (client, stores, transactions) |
|
|
46
|
+
| [kokimoki-dynamic-stores.instructions.md](./docs/kokimoki-dynamic-stores.instructions.md) | Room-based state isolation |
|
|
47
|
+
| [kokimoki-ai.instructions.md](./docs/kokimoki-ai.instructions.md) | AI text and image generation |
|
|
48
|
+
| [kokimoki-storage.instructions.md](./docs/kokimoki-storage.instructions.md) | File storage and CDN uploads |
|
|
49
|
+
| [kokimoki-i18n.instructions.md](./docs/kokimoki-i18n.instructions.md) | Internationalization |
|
|
50
|
+
| [kokimoki-leaderboard.instructions.md](./docs/kokimoki-leaderboard.instructions.md) | Player rankings |
|
|
51
|
+
|
|
52
|
+
## Usage with React
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { useSnapshot } from "valtio";
|
|
56
|
+
import { getKmClient } from "@kokimoki/app";
|
|
57
|
+
|
|
58
|
+
const kmClient = getKmClient();
|
|
59
|
+
const gameStore = kmClient.store("game", { count: 0 });
|
|
60
|
+
|
|
61
|
+
function Counter() {
|
|
62
|
+
const { count } = useSnapshot(gameStore.proxy);
|
|
63
|
+
|
|
64
|
+
const increment = () => {
|
|
65
|
+
kmClient.transact([gameStore], ([state]) => {
|
|
66
|
+
state.count++;
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
return <button onClick={increment}>Count: {count}</button>;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import type TypedEmitter from "typed-emitter";
|
|
2
|
-
import { KokimokiAiService, KokimokiLeaderboardService, KokimokiStorageService } from "../services";
|
|
2
|
+
import { KokimokiAiService, KokimokiI18nService, KokimokiLeaderboardService, KokimokiStorageService } from "../services";
|
|
3
3
|
import { KokimokiLocalStore, KokimokiStore } from "../stores";
|
|
4
|
-
import type { KokimokiClientEvents } from "../types";
|
|
4
|
+
import type { KokimokiClientEvents, KokimokiEnv } from "../types";
|
|
5
5
|
type Mutable<T> = {
|
|
6
6
|
-readonly [K in keyof T]: T[K] extends object ? Mutable<T[K]> : T[K];
|
|
7
7
|
};
|
|
8
8
|
type StoreValue<S> = S extends KokimokiStore<infer U> ? Mutable<U> : never;
|
|
9
|
-
declare const KokimokiClient_base:
|
|
10
|
-
new (): TypedEmitter<KokimokiClientEvents>;
|
|
11
|
-
};
|
|
9
|
+
declare const KokimokiClient_base: new () => TypedEmitter<KokimokiClientEvents>;
|
|
12
10
|
/**
|
|
13
11
|
* Kokimoki Client - Real-time Collaborative Game Development SDK
|
|
14
12
|
*
|
|
@@ -30,12 +28,8 @@ declare const KokimokiClient_base: {
|
|
|
30
28
|
* ```typescript
|
|
31
29
|
* import { KokimokiClient } from '@kokimoki/app';
|
|
32
30
|
*
|
|
33
|
-
* // Initialize the client
|
|
34
|
-
* const kmClient = new KokimokiClient(
|
|
35
|
-
* 'your-host.kokimoki.com',
|
|
36
|
-
* 'your-app-id',
|
|
37
|
-
* 'optional-access-code'
|
|
38
|
-
* );
|
|
31
|
+
* // Initialize the client (uses environment config from @kokimoki/kit)
|
|
32
|
+
* const kmClient = new KokimokiClient();
|
|
39
33
|
*
|
|
40
34
|
* // Connect to the server
|
|
41
35
|
* await kmClient.connect();
|
|
@@ -163,9 +157,6 @@ declare const KokimokiClient_base: {
|
|
|
163
157
|
* ```
|
|
164
158
|
*/
|
|
165
159
|
export declare class KokimokiClient<ClientContextT = any> extends KokimokiClient_base {
|
|
166
|
-
readonly host: string;
|
|
167
|
-
readonly appId: string;
|
|
168
|
-
readonly code: string;
|
|
169
160
|
private _wsUrl;
|
|
170
161
|
private _apiUrl;
|
|
171
162
|
private _id?;
|
|
@@ -189,9 +180,30 @@ export declare class KokimokiClient<ClientContextT = any> extends KokimokiClient
|
|
|
189
180
|
private _clientTokenKey;
|
|
190
181
|
private _editorContext;
|
|
191
182
|
private _ai?;
|
|
183
|
+
private _i18n?;
|
|
192
184
|
private _storage?;
|
|
193
185
|
private _leaderboard?;
|
|
194
|
-
|
|
186
|
+
/**
|
|
187
|
+
* Dev mode config - set when running in dev frame with ?key= param
|
|
188
|
+
*/
|
|
189
|
+
private _devModeConfig?;
|
|
190
|
+
/**
|
|
191
|
+
* Environment configuration
|
|
192
|
+
*/
|
|
193
|
+
private _env;
|
|
194
|
+
/**
|
|
195
|
+
* The WebSocket server host.
|
|
196
|
+
*/
|
|
197
|
+
readonly host: string;
|
|
198
|
+
/**
|
|
199
|
+
* The application identifier.
|
|
200
|
+
*/
|
|
201
|
+
readonly appId: string;
|
|
202
|
+
/**
|
|
203
|
+
* The deploy code slug.
|
|
204
|
+
*/
|
|
205
|
+
readonly code: string;
|
|
206
|
+
constructor(env?: KokimokiEnv);
|
|
195
207
|
get id(): string;
|
|
196
208
|
get connectionId(): string;
|
|
197
209
|
get token(): string;
|
|
@@ -207,6 +219,32 @@ export declare class KokimokiClient<ClientContextT = any> extends KokimokiClient
|
|
|
207
219
|
* Indicates whether the client is running in editor/development mode.
|
|
208
220
|
*/
|
|
209
221
|
get isEditor(): boolean;
|
|
222
|
+
/**
|
|
223
|
+
* Generates a link for joining the app via URL or QR code.
|
|
224
|
+
*
|
|
225
|
+
* In dev mode, the link includes the code and context as URL parameters
|
|
226
|
+
* for local testing. In production, it generates a clean path-based URL.
|
|
227
|
+
*
|
|
228
|
+
* @param code - The join code (e.g., playerCode or presenterCode from clientContext)
|
|
229
|
+
* @param context - The client context to embed in the link (used in dev mode only)
|
|
230
|
+
* @returns The generated URL string
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* ```typescript
|
|
234
|
+
* // Generate a player join link
|
|
235
|
+
* const playerLink = kmClient.generateLink(
|
|
236
|
+
* kmClient.clientContext.playerCode,
|
|
237
|
+
* { mode: 'player' }
|
|
238
|
+
* );
|
|
239
|
+
*
|
|
240
|
+
* // Generate a presenter link with player code
|
|
241
|
+
* const presenterLink = kmClient.generateLink(
|
|
242
|
+
* kmClient.clientContext.presenterCode,
|
|
243
|
+
* { mode: 'presenter', playerCode: kmClient.clientContext.playerCode }
|
|
244
|
+
* );
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
generateLink(code: string, context: object): string;
|
|
210
248
|
/**
|
|
211
249
|
* Establishes a connection to the Kokimoki server.
|
|
212
250
|
*
|
|
@@ -288,6 +326,24 @@ export declare class KokimokiClient<ClientContextT = any> extends KokimokiClient
|
|
|
288
326
|
* Disables automatic reconnection, closes the WebSocket, and clears all intervals.
|
|
289
327
|
*/
|
|
290
328
|
close(): Promise<void>;
|
|
329
|
+
/**
|
|
330
|
+
* Waits for all subscriptions to be fully joined and notifies the loading screen.
|
|
331
|
+
*
|
|
332
|
+
* This should be called before rendering the app. It will:
|
|
333
|
+
* 1. Wait for all stores to complete initial synchronization
|
|
334
|
+
* 2. Post a 'km:ready' message to trigger loading screen fade
|
|
335
|
+
* 3. Post a 'km:ready' message to the parent window (for dev frame coordination)
|
|
336
|
+
*
|
|
337
|
+
* @param timeout - Maximum time to wait for subscriptions in milliseconds (default: 5000ms).
|
|
338
|
+
* @returns A promise that resolves when ready to render.
|
|
339
|
+
*
|
|
340
|
+
* @example
|
|
341
|
+
* ```ts
|
|
342
|
+
* await kmClient.waitForReady();
|
|
343
|
+
* renderApp(<App />);
|
|
344
|
+
* ```
|
|
345
|
+
*/
|
|
346
|
+
waitForReady(timeout?: number): Promise<void>;
|
|
291
347
|
/**
|
|
292
348
|
* Gets the internal room hash identifier for a store.
|
|
293
349
|
*
|
|
@@ -349,6 +405,10 @@ export declare class KokimokiClient<ClientContextT = any> extends KokimokiClient
|
|
|
349
405
|
* Access AI capabilities including text generation, structured JSON output, and image modification.
|
|
350
406
|
*/
|
|
351
407
|
get ai(): KokimokiAiService;
|
|
408
|
+
/**
|
|
409
|
+
* Access i18n URL resolution and translation loading utilities.
|
|
410
|
+
*/
|
|
411
|
+
get i18n(): KokimokiI18nService;
|
|
352
412
|
/**
|
|
353
413
|
* Access file upload and management for media files, images, and user-generated content.
|
|
354
414
|
*/
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import EventEmitter from "events";
|
|
2
2
|
import * as Y from "yjs";
|
|
3
3
|
import { WsMessageReader, WsMessageType, WsMessageWriter, } from "../protocol/ws-message";
|
|
4
|
-
import { KokimokiAiService, KokimokiLeaderboardService, KokimokiStorageService, } from "../services";
|
|
4
|
+
import { KokimokiAiService, KokimokiI18nService, KokimokiLeaderboardService, KokimokiStorageService, } from "../services";
|
|
5
5
|
import { KokimokiLocalStore, KokimokiStore, KokimokiTransaction, } from "../stores";
|
|
6
|
+
import { initDevMode } from "../utils/kokimoki-dev";
|
|
7
|
+
import { getKmEnv } from "../utils/kokimoki-env";
|
|
6
8
|
import { KOKIMOKI_APP_VERSION } from "../version";
|
|
7
9
|
import { RoomSubscription } from "./room-subscription";
|
|
8
10
|
/**
|
|
@@ -26,12 +28,8 @@ import { RoomSubscription } from "./room-subscription";
|
|
|
26
28
|
* ```typescript
|
|
27
29
|
* import { KokimokiClient } from '@kokimoki/app';
|
|
28
30
|
*
|
|
29
|
-
* // Initialize the client
|
|
30
|
-
* const kmClient = new KokimokiClient(
|
|
31
|
-
* 'your-host.kokimoki.com',
|
|
32
|
-
* 'your-app-id',
|
|
33
|
-
* 'optional-access-code'
|
|
34
|
-
* );
|
|
31
|
+
* // Initialize the client (uses environment config from @kokimoki/kit)
|
|
32
|
+
* const kmClient = new KokimokiClient();
|
|
35
33
|
*
|
|
36
34
|
* // Connect to the server
|
|
37
35
|
* await kmClient.connect();
|
|
@@ -159,9 +157,6 @@ import { RoomSubscription } from "./room-subscription";
|
|
|
159
157
|
* ```
|
|
160
158
|
*/
|
|
161
159
|
export class KokimokiClient extends EventEmitter {
|
|
162
|
-
host;
|
|
163
|
-
appId;
|
|
164
|
-
code;
|
|
165
160
|
_wsUrl;
|
|
166
161
|
_apiUrl;
|
|
167
162
|
_id;
|
|
@@ -185,19 +180,49 @@ export class KokimokiClient extends EventEmitter {
|
|
|
185
180
|
_clientTokenKey = "KM_TOKEN";
|
|
186
181
|
_editorContext;
|
|
187
182
|
_ai;
|
|
183
|
+
_i18n;
|
|
188
184
|
_storage;
|
|
189
185
|
_leaderboard;
|
|
190
|
-
|
|
186
|
+
/**
|
|
187
|
+
* Dev mode config - set when running in dev frame with ?key= param
|
|
188
|
+
*/
|
|
189
|
+
_devModeConfig;
|
|
190
|
+
/**
|
|
191
|
+
* Environment configuration
|
|
192
|
+
*/
|
|
193
|
+
_env;
|
|
194
|
+
/**
|
|
195
|
+
* The WebSocket server host.
|
|
196
|
+
*/
|
|
197
|
+
host;
|
|
198
|
+
/**
|
|
199
|
+
* The application identifier.
|
|
200
|
+
*/
|
|
201
|
+
appId;
|
|
202
|
+
/**
|
|
203
|
+
* The deploy code slug.
|
|
204
|
+
*/
|
|
205
|
+
code;
|
|
206
|
+
constructor(env = getKmEnv()) {
|
|
191
207
|
super();
|
|
192
|
-
this.
|
|
193
|
-
this.
|
|
194
|
-
this.
|
|
208
|
+
this._env = env;
|
|
209
|
+
this.host = env.host;
|
|
210
|
+
this.appId = env.appId;
|
|
211
|
+
this.code = env.code ?? "";
|
|
212
|
+
// Initialize dev mode from URL params if running in dev environment
|
|
213
|
+
if (env.dev) {
|
|
214
|
+
this._devModeConfig = initDevMode();
|
|
215
|
+
if (this._devModeConfig) {
|
|
216
|
+
this._clientTokenKey = this._devModeConfig.tokenKey;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
195
219
|
// Set up the URLs
|
|
196
220
|
const secure = this.host.indexOf(":") === -1;
|
|
197
221
|
this._wsUrl = `ws${secure ? "s" : ""}://${this.host}`;
|
|
198
222
|
this._apiUrl = `http${secure ? "s" : ""}://${this.host}`;
|
|
199
223
|
// Initialize modules
|
|
200
224
|
this._ai = new KokimokiAiService(this);
|
|
225
|
+
this._i18n = new KokimokiI18nService(this);
|
|
201
226
|
this._storage = new KokimokiStorageService(this);
|
|
202
227
|
this._leaderboard = new KokimokiLeaderboardService(this);
|
|
203
228
|
// Set up ping interval
|
|
@@ -278,6 +303,37 @@ export class KokimokiClient extends EventEmitter {
|
|
|
278
303
|
get isEditor() {
|
|
279
304
|
return !!this._editorContext;
|
|
280
305
|
}
|
|
306
|
+
/**
|
|
307
|
+
* Generates a link for joining the app via URL or QR code.
|
|
308
|
+
*
|
|
309
|
+
* In dev mode, the link includes the code and context as URL parameters
|
|
310
|
+
* for local testing. In production, it generates a clean path-based URL.
|
|
311
|
+
*
|
|
312
|
+
* @param code - The join code (e.g., playerCode or presenterCode from clientContext)
|
|
313
|
+
* @param context - The client context to embed in the link (used in dev mode only)
|
|
314
|
+
* @returns The generated URL string
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* ```typescript
|
|
318
|
+
* // Generate a player join link
|
|
319
|
+
* const playerLink = kmClient.generateLink(
|
|
320
|
+
* kmClient.clientContext.playerCode,
|
|
321
|
+
* { mode: 'player' }
|
|
322
|
+
* );
|
|
323
|
+
*
|
|
324
|
+
* // Generate a presenter link with player code
|
|
325
|
+
* const presenterLink = kmClient.generateLink(
|
|
326
|
+
* kmClient.clientContext.presenterCode,
|
|
327
|
+
* { mode: 'presenter', playerCode: kmClient.clientContext.playerCode }
|
|
328
|
+
* );
|
|
329
|
+
* ```
|
|
330
|
+
*/
|
|
331
|
+
generateLink(code, context) {
|
|
332
|
+
if (this._env.dev) {
|
|
333
|
+
return `${window.location.origin}?key=${code}&context=${btoa(JSON.stringify(context))}`;
|
|
334
|
+
}
|
|
335
|
+
return `${window.location.origin}/${code}`;
|
|
336
|
+
}
|
|
281
337
|
/**
|
|
282
338
|
* Establishes a connection to the Kokimoki server.
|
|
283
339
|
*
|
|
@@ -291,14 +347,11 @@ export class KokimokiClient extends EventEmitter {
|
|
|
291
347
|
if (this._connectPromise) {
|
|
292
348
|
return await this._connectPromise;
|
|
293
349
|
}
|
|
294
|
-
// Detect devtools
|
|
295
|
-
if (
|
|
350
|
+
// Detect devtools (editor)
|
|
351
|
+
if (!this._devModeConfig &&
|
|
352
|
+
window.parent &&
|
|
353
|
+
window.self !== window.parent) {
|
|
296
354
|
await new Promise((resolve) => {
|
|
297
|
-
/* // Wait up to 500ms for parent to respond
|
|
298
|
-
const timeout = setTimeout(() => {
|
|
299
|
-
window.removeEventListener("message", onMessage);
|
|
300
|
-
resolve();
|
|
301
|
-
}, 500); */
|
|
302
355
|
// Listen for parent response
|
|
303
356
|
const onMessage = (e) => {
|
|
304
357
|
// clearTimeout(timeout);
|
|
@@ -399,7 +452,20 @@ export class KokimokiClient extends EventEmitter {
|
|
|
399
452
|
this._id = message.clientId;
|
|
400
453
|
this._connectionId = message.id;
|
|
401
454
|
this._token = message.appToken;
|
|
402
|
-
|
|
455
|
+
// Context priority: dev mode URL params > test mode env > server context
|
|
456
|
+
if (this._devModeConfig?.context !== undefined) {
|
|
457
|
+
this._clientContext = this._devModeConfig.context;
|
|
458
|
+
}
|
|
459
|
+
else if (this._env.test && this._env.clientContext) {
|
|
460
|
+
this._clientContext = JSON.parse(this._env.clientContext);
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
this._clientContext = message.clientContext;
|
|
464
|
+
}
|
|
465
|
+
// Notify parent window in test mode (editor)
|
|
466
|
+
if (this._env.test) {
|
|
467
|
+
setTimeout(() => window.postMessage({ clientKey: "test" }, "*"));
|
|
468
|
+
}
|
|
403
469
|
// Set up the auth headers
|
|
404
470
|
this._apiHeaders = new Headers({
|
|
405
471
|
Authorization: `Bearer ${this.token}`,
|
|
@@ -707,6 +773,46 @@ export class KokimokiClient extends EventEmitter {
|
|
|
707
773
|
clearInterval(this._pingInterval);
|
|
708
774
|
}
|
|
709
775
|
}
|
|
776
|
+
/**
|
|
777
|
+
* Waits for all subscriptions to be fully joined and notifies the loading screen.
|
|
778
|
+
*
|
|
779
|
+
* This should be called before rendering the app. It will:
|
|
780
|
+
* 1. Wait for all stores to complete initial synchronization
|
|
781
|
+
* 2. Post a 'km:ready' message to trigger loading screen fade
|
|
782
|
+
* 3. Post a 'km:ready' message to the parent window (for dev frame coordination)
|
|
783
|
+
*
|
|
784
|
+
* @param timeout - Maximum time to wait for subscriptions in milliseconds (default: 5000ms).
|
|
785
|
+
* @returns A promise that resolves when ready to render.
|
|
786
|
+
*
|
|
787
|
+
* @example
|
|
788
|
+
* ```ts
|
|
789
|
+
* await kmClient.waitForReady();
|
|
790
|
+
* renderApp(<App />);
|
|
791
|
+
* ```
|
|
792
|
+
*/
|
|
793
|
+
async waitForReady(timeout = 5000) {
|
|
794
|
+
const checkInterval = 10;
|
|
795
|
+
const maxChecks = Math.ceil(timeout / checkInterval);
|
|
796
|
+
await new Promise((resolve) => {
|
|
797
|
+
let checks = 0;
|
|
798
|
+
const intervalId = setInterval(() => {
|
|
799
|
+
let allJoined = true;
|
|
800
|
+
for (const subscription of this._subscriptionsByName.values()) {
|
|
801
|
+
if (!subscription.joined) {
|
|
802
|
+
allJoined = false;
|
|
803
|
+
break;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
if (allJoined || ++checks >= maxChecks) {
|
|
807
|
+
clearInterval(intervalId);
|
|
808
|
+
resolve();
|
|
809
|
+
}
|
|
810
|
+
}, checkInterval);
|
|
811
|
+
});
|
|
812
|
+
// Post to both parent (for dev frame) and self (for loading screen)
|
|
813
|
+
window.parent.postMessage("km:ready", "*");
|
|
814
|
+
window.postMessage("km:ready", "*");
|
|
815
|
+
}
|
|
710
816
|
/**
|
|
711
817
|
* Gets the internal room hash identifier for a store.
|
|
712
818
|
*
|
|
@@ -798,6 +904,15 @@ export class KokimokiClient extends EventEmitter {
|
|
|
798
904
|
}
|
|
799
905
|
return this._ai;
|
|
800
906
|
}
|
|
907
|
+
/**
|
|
908
|
+
* Access i18n URL resolution and translation loading utilities.
|
|
909
|
+
*/
|
|
910
|
+
get i18n() {
|
|
911
|
+
if (!this._i18n) {
|
|
912
|
+
throw new Error("I18n client not initialized");
|
|
913
|
+
}
|
|
914
|
+
return this._i18n;
|
|
915
|
+
}
|
|
801
916
|
/**
|
|
802
917
|
* Access file upload and management for media files, images, and user-generated content.
|
|
803
918
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export { KokimokiClient } from "./core";
|
|
2
2
|
export { KokimokiStore } from "./stores";
|
|
3
|
-
export type { KokimokiClientEvents, Paginated, Upload } from "./types";
|
|
3
|
+
export type { KokimokiClientEvents, KokimokiEnv, Paginated, PollOptions, Upload, } from "./types";
|
|
4
|
+
export type { AllLanguagesStatus, I18nOptions, LanguageStatus, NamespaceStatus, RequestTranslationResult, TranslationStatus, } from "./services/kokimoki-i18n";
|
|
5
|
+
export type { AiJob, AiJobStatus, AiJobType } from "./services/kokimoki-ai";
|
|
6
|
+
export { getKmClient } from "./utils/kokimoki-client";
|
|
7
|
+
export { getKmEnv } from "./utils/kokimoki-env";
|
|
4
8
|
export * from "./utils/valtio";
|
|
9
|
+
export { z, type ZodType } from "zod/v4";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export { KokimokiClient } from "./core";
|
|
2
2
|
export { KokimokiStore } from "./stores";
|
|
3
|
+
export { getKmClient } from "./utils/kokimoki-client";
|
|
4
|
+
export { getKmEnv } from "./utils/kokimoki-env";
|
|
3
5
|
// Re-export Valtio utilities
|
|
4
6
|
export * from "./utils/valtio";
|
|
7
|
+
// Re-export Zod for schema definitions
|
|
8
|
+
export { z } from "zod/v4";
|