@korajs/react 1.0.0-beta.12 → 1.0.0-beta.13
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 +48 -40
- package/dist/index.cjs +165 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +150 -5
- package/dist/index.d.ts +150 -5
- package/dist/index.js +163 -62
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -123,6 +123,7 @@ function AuthBoundKoraProvider({
|
|
|
123
123
|
authClient,
|
|
124
124
|
createApp,
|
|
125
125
|
signedOut = null,
|
|
126
|
+
locked,
|
|
126
127
|
fallback = null,
|
|
127
128
|
error: renderError,
|
|
128
129
|
children
|
|
@@ -216,6 +217,7 @@ function AuthBoundKoraProvider({
|
|
|
216
217
|
);
|
|
217
218
|
}
|
|
218
219
|
if (state.state === "signed-out" || state.state === "anonymous") return signedOut;
|
|
220
|
+
if (state.state === "authenticated" && state.locked) return locked ?? signedOut;
|
|
219
221
|
if (!app) return fallback;
|
|
220
222
|
return createElement2(KoraProvider, { app, fallback }, children);
|
|
221
223
|
}
|
|
@@ -232,17 +234,24 @@ function useApp() {
|
|
|
232
234
|
}
|
|
233
235
|
|
|
234
236
|
// src/hooks/use-query.ts
|
|
235
|
-
import { assertQueryReady } from "@korajs/store";
|
|
236
|
-
import { useCallback, useEffect as useEffect3, useRef as useRef3, useState as useState3, useSyncExternalStore } from "react";
|
|
237
|
+
import { assertQueryReady, queryKey } from "@korajs/store";
|
|
238
|
+
import { useCallback, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef3, useState as useState3, useSyncExternalStore } from "react";
|
|
237
239
|
var EMPTY_ARRAY = Object.freeze([]);
|
|
238
240
|
var noopSubscribe = (_onStoreChange) => {
|
|
239
241
|
return () => {
|
|
240
242
|
};
|
|
241
243
|
};
|
|
242
|
-
|
|
244
|
+
var getServerSnapshot = () => EMPTY_ARRAY;
|
|
245
|
+
var getNoError = () => null;
|
|
246
|
+
function readQueryError(queryStore) {
|
|
247
|
+
if (!queryStore) return null;
|
|
248
|
+
const channel = queryStore;
|
|
249
|
+
return typeof channel.getError === "function" ? channel.getError() : null;
|
|
250
|
+
}
|
|
251
|
+
function useQuerySubscription(query, options) {
|
|
243
252
|
const { queryStoreCache } = useKoraContext();
|
|
244
253
|
const enabled = options?.enabled !== false;
|
|
245
|
-
const descriptorKey =
|
|
254
|
+
const descriptorKey = queryKey(query.getDescriptor());
|
|
246
255
|
const queryRef = useRef3(query);
|
|
247
256
|
queryRef.current = query;
|
|
248
257
|
const lastSnapshotRef = useRef3(EMPTY_ARRAY);
|
|
@@ -260,122 +269,204 @@ function useQuery(query, options) {
|
|
|
260
269
|
queryStoreCache.release(currentQuery);
|
|
261
270
|
};
|
|
262
271
|
}, [descriptorKey, enabled, queryStoreCache]);
|
|
272
|
+
const subscribe = enabled && queryStore ? queryStore.subscribe : noopSubscribe;
|
|
263
273
|
const getSnapshot = useCallback(() => {
|
|
264
274
|
if (!enabled) {
|
|
265
275
|
lastSnapshotRef.current = EMPTY_ARRAY;
|
|
266
276
|
return lastSnapshotRef.current;
|
|
267
277
|
}
|
|
268
|
-
if (!queryStore) {
|
|
269
|
-
return lastSnapshotRef.current;
|
|
270
|
-
}
|
|
271
|
-
if (!queryStore.hasSnapshot()) {
|
|
278
|
+
if (!queryStore || !queryStore.hasSnapshot()) {
|
|
272
279
|
return lastSnapshotRef.current;
|
|
273
280
|
}
|
|
274
281
|
const snapshot = queryStore.getSnapshot();
|
|
275
282
|
lastSnapshotRef.current = snapshot;
|
|
276
283
|
return snapshot;
|
|
277
284
|
}, [enabled, queryStore]);
|
|
278
|
-
|
|
285
|
+
const getError = useCallback(
|
|
286
|
+
() => enabled ? readQueryError(queryStore) : null,
|
|
287
|
+
[enabled, queryStore]
|
|
288
|
+
);
|
|
289
|
+
const data = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
290
|
+
const error = useSyncExternalStore(subscribe, getError, getNoError);
|
|
291
|
+
const ready = enabled && queryStore !== null && queryStore.hasSnapshot();
|
|
292
|
+
return { data, error, ready };
|
|
293
|
+
}
|
|
294
|
+
function useQuery(query, options) {
|
|
295
|
+
const { data, error } = useQuerySubscription(query, options);
|
|
296
|
+
if (error && options?.throwOnError !== false) {
|
|
297
|
+
throw error;
|
|
298
|
+
}
|
|
299
|
+
return data;
|
|
279
300
|
}
|
|
301
|
+
function useQueryState(query, options) {
|
|
302
|
+
const { data, error, ready } = useQuerySubscription(query, options);
|
|
303
|
+
return useMemo2(() => ({ data, error, ready }), [data, error, ready]);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// src/hooks/create-kora-hooks.ts
|
|
307
|
+
import { useMemo as useMemo4 } from "react";
|
|
280
308
|
|
|
281
309
|
// src/hooks/use-mutation.ts
|
|
282
310
|
import { createMutationController } from "@korajs/core/bindings";
|
|
283
|
-
import { useRef as useRef5, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
311
|
+
import { useCallback as useCallback2, useMemo as useMemo3, useRef as useRef5, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
284
312
|
|
|
285
313
|
// src/hooks/use-controller.ts
|
|
286
314
|
import { useEffect as useEffect4, useReducer, useRef as useRef4 } from "react";
|
|
315
|
+
var ORPHAN_REAP_MS = 1e3;
|
|
287
316
|
function useController(create, destroy, deps) {
|
|
288
|
-
const
|
|
317
|
+
const entryRef = useRef4(null);
|
|
289
318
|
const createRef = useRef4(create);
|
|
290
319
|
createRef.current = create;
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
320
|
+
const destroyRef = useRef4(destroy);
|
|
321
|
+
destroyRef.current = destroy;
|
|
322
|
+
const [version, bumpVersion] = useReducer((count) => count + 1, 0);
|
|
323
|
+
const handle = useRef4({
|
|
324
|
+
get: () => {
|
|
325
|
+
const current = entryRef.current;
|
|
326
|
+
if (current !== null && !current.reaped) {
|
|
327
|
+
return current.controller;
|
|
328
|
+
}
|
|
329
|
+
const entry = {
|
|
330
|
+
controller: createRef.current(),
|
|
331
|
+
claimed: false,
|
|
332
|
+
reaped: false
|
|
333
|
+
};
|
|
334
|
+
entryRef.current = entry;
|
|
335
|
+
setTimeout(() => {
|
|
336
|
+
if (!entry.claimed && !entry.reaped) {
|
|
337
|
+
entry.reaped = true;
|
|
338
|
+
destroyRef.current(entry.controller);
|
|
339
|
+
}
|
|
340
|
+
}, ORPHAN_REAP_MS);
|
|
341
|
+
return entry.controller;
|
|
342
|
+
},
|
|
343
|
+
peek: () => {
|
|
344
|
+
const current = entryRef.current;
|
|
345
|
+
return current?.claimed && !current.reaped ? current.controller : null;
|
|
295
346
|
}
|
|
296
|
-
return controllerRef.current;
|
|
297
347
|
}).current;
|
|
298
348
|
useEffect4(() => {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
349
|
+
const current = entryRef.current;
|
|
350
|
+
if (current !== null && !current.reaped && !current.claimed) {
|
|
351
|
+
current.claimed = true;
|
|
352
|
+
} else if (current === null || current.reaped) {
|
|
353
|
+
entryRef.current = { controller: createRef.current(), claimed: true, reaped: false };
|
|
354
|
+
bumpVersion();
|
|
302
355
|
}
|
|
303
356
|
return () => {
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
if (
|
|
307
|
-
|
|
357
|
+
const entry = entryRef.current;
|
|
358
|
+
entryRef.current = null;
|
|
359
|
+
if (entry !== null && !entry.reaped) {
|
|
360
|
+
entry.reaped = true;
|
|
361
|
+
destroyRef.current(entry.controller);
|
|
308
362
|
}
|
|
309
363
|
};
|
|
310
364
|
}, deps);
|
|
311
|
-
return
|
|
365
|
+
return { get: handle.get, peek: handle.peek, version };
|
|
312
366
|
}
|
|
313
367
|
|
|
314
368
|
// src/hooks/use-mutation.ts
|
|
369
|
+
var IDLE = Object.freeze({ isLoading: false, error: null });
|
|
370
|
+
var getServerSnapshot2 = () => IDLE;
|
|
315
371
|
function useMutation(mutationFn, options) {
|
|
316
372
|
const fnRef = useRef5(mutationFn);
|
|
317
373
|
fnRef.current = mutationFn;
|
|
318
374
|
const optionsRef = useRef5(options);
|
|
319
375
|
optionsRef.current = options;
|
|
320
|
-
const
|
|
376
|
+
const controller = useController(
|
|
321
377
|
() => createMutationController({
|
|
322
378
|
mutationFn: (...args) => fnRef.current(...args),
|
|
323
379
|
resolveOptions: () => optionsRef.current
|
|
324
380
|
}),
|
|
325
|
-
(
|
|
381
|
+
(instance) => instance.destroy(),
|
|
326
382
|
[]
|
|
327
383
|
);
|
|
328
|
-
const
|
|
384
|
+
const getController = controller.get;
|
|
385
|
+
const subscribe = useCallback2(
|
|
329
386
|
(onStoreChange) => getController().subscribe(onStoreChange),
|
|
330
|
-
|
|
331
|
-
|
|
387
|
+
[getController, controller.version]
|
|
388
|
+
);
|
|
389
|
+
const getSnapshot = useCallback2(() => getController().getSnapshot(), [getController]);
|
|
390
|
+
const state = useSyncExternalStore2(subscribe, getSnapshot, getServerSnapshot2);
|
|
391
|
+
const mutate = useCallback2((...args) => getController().mutate(...args), [getController]);
|
|
392
|
+
const mutateAsync = useCallback2(
|
|
393
|
+
(...args) => getController().mutateAsync(...args),
|
|
394
|
+
[getController]
|
|
395
|
+
);
|
|
396
|
+
const reset = useCallback2(() => getController().reset(), [getController]);
|
|
397
|
+
return useMemo3(
|
|
398
|
+
() => ({ mutate, mutateAsync, isLoading: state.isLoading, error: state.error, reset }),
|
|
399
|
+
[mutate, mutateAsync, reset, state.isLoading, state.error]
|
|
332
400
|
);
|
|
333
|
-
return {
|
|
334
|
-
mutate: (...args) => getController().mutate(...args),
|
|
335
|
-
mutateAsync: (...args) => getController().mutateAsync(...args),
|
|
336
|
-
isLoading: state.isLoading,
|
|
337
|
-
error: state.error,
|
|
338
|
-
reset: () => getController().reset()
|
|
339
|
-
};
|
|
340
401
|
}
|
|
341
402
|
|
|
342
403
|
// src/hooks/use-sync-status.ts
|
|
343
|
-
import { createSyncStatusController } from "@korajs/sync";
|
|
344
|
-
import { useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
404
|
+
import { OFFLINE_SYNC_STATUS, createSyncStatusController } from "@korajs/sync";
|
|
405
|
+
import { useCallback as useCallback3, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
406
|
+
var getServerSnapshot3 = () => OFFLINE_SYNC_STATUS;
|
|
345
407
|
function useSyncStatus() {
|
|
346
408
|
const { syncEngine, subscribeSyncStatus, events } = useKoraContext();
|
|
347
|
-
const
|
|
409
|
+
const controller = useController(
|
|
348
410
|
() => createSyncStatusController({
|
|
349
411
|
syncEngine,
|
|
350
412
|
subscribeSyncStatus,
|
|
351
413
|
events: subscribeSyncStatus ? null : events
|
|
352
414
|
}),
|
|
353
|
-
(
|
|
415
|
+
(instance) => instance.destroy(),
|
|
354
416
|
[syncEngine, subscribeSyncStatus, events]
|
|
355
417
|
);
|
|
356
|
-
|
|
418
|
+
const getController = controller.get;
|
|
419
|
+
const subscribe = useCallback3(
|
|
357
420
|
(onStoreChange) => getController().subscribe(onStoreChange),
|
|
358
|
-
|
|
359
|
-
() => getController().getSnapshot()
|
|
421
|
+
[getController, controller.version]
|
|
360
422
|
);
|
|
423
|
+
const peek = controller.peek;
|
|
424
|
+
const getSnapshot = useCallback3(
|
|
425
|
+
() => peek()?.getSnapshot() ?? OFFLINE_SYNC_STATUS,
|
|
426
|
+
[peek]
|
|
427
|
+
);
|
|
428
|
+
return useSyncExternalStore3(subscribe, getSnapshot, getServerSnapshot3);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// src/hooks/create-kora-hooks.ts
|
|
432
|
+
function createKoraHooks() {
|
|
433
|
+
function useTypedApp() {
|
|
434
|
+
return useApp();
|
|
435
|
+
}
|
|
436
|
+
function useTypedCollection(name) {
|
|
437
|
+
const { app, store } = useKoraContext();
|
|
438
|
+
return useMemo4(() => {
|
|
439
|
+
const collections = app?.collections;
|
|
440
|
+
const accessor = collections && name in collections ? collections[name] : store.collection(name);
|
|
441
|
+
return accessor;
|
|
442
|
+
}, [app, store, name]);
|
|
443
|
+
}
|
|
444
|
+
return {
|
|
445
|
+
useApp: useTypedApp,
|
|
446
|
+
useCollection: useTypedCollection,
|
|
447
|
+
useQuery,
|
|
448
|
+
useQueryState,
|
|
449
|
+
useMutation,
|
|
450
|
+
useSyncStatus
|
|
451
|
+
};
|
|
361
452
|
}
|
|
362
453
|
|
|
363
454
|
// src/hooks/use-collection.ts
|
|
364
|
-
import { useMemo as
|
|
455
|
+
import { useMemo as useMemo5 } from "react";
|
|
365
456
|
function useCollection(name) {
|
|
366
457
|
const { store } = useKoraContext();
|
|
367
|
-
return
|
|
458
|
+
return useMemo5(() => {
|
|
368
459
|
return store.collection(name);
|
|
369
460
|
}, [store, name]);
|
|
370
461
|
}
|
|
371
462
|
|
|
372
463
|
// src/hooks/use-rich-text.ts
|
|
373
464
|
import { asRichTextSyncEngine, createRichTextController } from "@korajs/store";
|
|
374
|
-
import { useCallback as
|
|
465
|
+
import { useCallback as useCallback4, useEffect as useEffect5, useMemo as useMemo6, useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
375
466
|
function useRichText(collectionName, recordId, fieldName, options) {
|
|
376
467
|
const { store, syncEngine } = useKoraContext();
|
|
377
|
-
const collection =
|
|
378
|
-
const
|
|
468
|
+
const collection = useMemo6(() => store.collection(collectionName), [store, collectionName]);
|
|
469
|
+
const controller = useController(
|
|
379
470
|
() => createRichTextController({
|
|
380
471
|
collection,
|
|
381
472
|
collectionName,
|
|
@@ -386,29 +477,35 @@ function useRichText(collectionName, recordId, fieldName, options) {
|
|
|
386
477
|
useDocChannel: options?.useDocChannel,
|
|
387
478
|
user: options?.user
|
|
388
479
|
}),
|
|
389
|
-
(
|
|
480
|
+
(instance) => instance.destroy(),
|
|
390
481
|
[collection, collectionName, fieldName, options?.useDocChannel, recordId, store, syncEngine]
|
|
391
482
|
);
|
|
483
|
+
const getController = controller.get;
|
|
392
484
|
useEffect5(() => {
|
|
393
485
|
getController().setUser(options?.user);
|
|
394
|
-
}, [getController, options?.user]);
|
|
395
|
-
const
|
|
486
|
+
}, [getController, options?.user, controller.version]);
|
|
487
|
+
const subscribe = useCallback4(
|
|
396
488
|
(onStoreChange) => getController().subscribe(onStoreChange),
|
|
397
|
-
|
|
398
|
-
() => getController().getSnapshot()
|
|
489
|
+
[getController, controller.version]
|
|
399
490
|
);
|
|
400
|
-
const
|
|
491
|
+
const getSnapshot = useCallback4(() => getController().getSnapshot(), [getController]);
|
|
492
|
+
const snapshot = useSyncExternalStore4(subscribe, getSnapshot, getSnapshot);
|
|
493
|
+
const undo = useCallback4(() => {
|
|
401
494
|
getController().undo();
|
|
402
495
|
}, [getController]);
|
|
403
|
-
const redo =
|
|
496
|
+
const redo = useCallback4(() => {
|
|
404
497
|
getController().redo();
|
|
405
498
|
}, [getController]);
|
|
406
|
-
const setCursor =
|
|
499
|
+
const setCursor = useCallback4(
|
|
407
500
|
(anchor, head) => getController().setCursor(anchor, head),
|
|
408
501
|
[getController]
|
|
409
502
|
);
|
|
410
|
-
const clearCursor =
|
|
411
|
-
|
|
503
|
+
const clearCursor = useCallback4(() => getController().clearCursor(), [getController]);
|
|
504
|
+
const live = getController();
|
|
505
|
+
return useMemo6(
|
|
506
|
+
() => buildResult(live, snapshot, undo, redo, setCursor, clearCursor),
|
|
507
|
+
[live, snapshot, undo, redo, setCursor, clearCursor, controller.version]
|
|
508
|
+
);
|
|
412
509
|
}
|
|
413
510
|
function buildResult(controller, snapshot, undo, redo, setCursor, clearCursor) {
|
|
414
511
|
return {
|
|
@@ -447,12 +544,13 @@ function usePresence(user) {
|
|
|
447
544
|
|
|
448
545
|
// src/hooks/use-collaborators.ts
|
|
449
546
|
import { subscribeRemoteAwarenessStates } from "@korajs/sync";
|
|
450
|
-
import { useCallback as
|
|
547
|
+
import { useCallback as useCallback5, useEffect as useEffect7, useRef as useRef6, useSyncExternalStore as useSyncExternalStore5 } from "react";
|
|
451
548
|
var EMPTY_ARRAY2 = [];
|
|
549
|
+
var getServerSnapshot4 = () => EMPTY_ARRAY2;
|
|
452
550
|
function useCollaborators() {
|
|
453
551
|
const { syncEngine } = useKoraContext();
|
|
454
552
|
const snapshotRef = useRef6(EMPTY_ARRAY2);
|
|
455
|
-
const subscribe =
|
|
553
|
+
const subscribe = useCallback5(
|
|
456
554
|
(onStoreChange) => {
|
|
457
555
|
if (!syncEngine) {
|
|
458
556
|
snapshotRef.current = EMPTY_ARRAY2;
|
|
@@ -460,6 +558,7 @@ function useCollaborators() {
|
|
|
460
558
|
};
|
|
461
559
|
}
|
|
462
560
|
const awareness = syncEngine.getAwarenessManager();
|
|
561
|
+
snapshotRef.current = EMPTY_ARRAY2;
|
|
463
562
|
return subscribeRemoteAwarenessStates(awareness, (states) => {
|
|
464
563
|
snapshotRef.current = states;
|
|
465
564
|
onStoreChange();
|
|
@@ -467,24 +566,26 @@ function useCollaborators() {
|
|
|
467
566
|
},
|
|
468
567
|
[syncEngine]
|
|
469
568
|
);
|
|
470
|
-
const getSnapshot =
|
|
569
|
+
const getSnapshot = useCallback5(() => snapshotRef.current, []);
|
|
471
570
|
useEffect7(() => {
|
|
472
571
|
if (!syncEngine) {
|
|
473
572
|
snapshotRef.current = EMPTY_ARRAY2;
|
|
474
573
|
}
|
|
475
574
|
}, [syncEngine]);
|
|
476
|
-
return useSyncExternalStore5(subscribe, getSnapshot);
|
|
575
|
+
return useSyncExternalStore5(subscribe, getSnapshot, getServerSnapshot4);
|
|
477
576
|
}
|
|
478
577
|
export {
|
|
479
578
|
AuthBoundKoraProvider,
|
|
480
579
|
KoraProvider,
|
|
481
580
|
classifyKoraInitializationError,
|
|
581
|
+
createKoraHooks,
|
|
482
582
|
useApp,
|
|
483
583
|
useCollaborators,
|
|
484
584
|
useCollection,
|
|
485
585
|
useMutation,
|
|
486
586
|
usePresence,
|
|
487
587
|
useQuery,
|
|
588
|
+
useQueryState,
|
|
488
589
|
useRichText,
|
|
489
590
|
useSyncStatus
|
|
490
591
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context/kora-context.ts","../src/context/auth-bound-kora-provider.ts","../src/hooks/use-app.ts","../src/hooks/use-query.ts","../src/hooks/use-mutation.ts","../src/hooks/use-controller.ts","../src/hooks/use-sync-status.ts","../src/hooks/use-collection.ts","../src/hooks/use-rich-text.ts","../src/hooks/use-presence.ts","../src/hooks/use-collaborators.ts"],"sourcesContent":["import type { Store } from '@korajs/store'\nimport { QueryStoreCache } from '@korajs/store'\nimport type { SyncEngine } from '@korajs/sync'\nimport {\n\tcreateContext,\n\tcreateElement,\n\tuseContext,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react'\nimport type { ReactNode } from 'react'\nimport type { KoraContextValue, KoraProviderProps } from '../types'\n\nconst KoraContext = createContext<KoraContextValue | null>(null)\n\n/**\n * Provides Kora store and optional sync engine to all child components.\n * Must wrap any component that uses Kora hooks (useQuery, useMutation, etc.).\n */\nfunction KoraProvider({\n\tapp,\n\tstore,\n\tsyncEngine,\n\tfallback,\n\tchildren,\n}: KoraProviderProps): ReactNode {\n\tconst [resolvedStore, setResolvedStore] = useState<Store | null>(store ?? null)\n\tconst [resolvedSync, setResolvedSync] = useState<SyncEngine | null>(syncEngine ?? null)\n\tconst [ready, setReady] = useState(!app)\n\tconst [initError, setInitError] = useState<Error | null>(null)\n\tconst fallbackQueryStoreCache = useRef<QueryStoreCache | null>(null)\n\n\tif (!fallbackQueryStoreCache.current) {\n\t\tfallbackQueryStoreCache.current = new QueryStoreCache()\n\t}\n\n\tuseEffect(() => {\n\t\tif (!app) return\n\t\tlet cancelled = false\n\t\tapp.ready\n\t\t\t.then(() => {\n\t\t\t\tif (cancelled) return\n\t\t\t\tsetResolvedStore(app.getStore())\n\t\t\t\tsetResolvedSync(app.getSyncEngine())\n\t\t\t\tsetReady(true)\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (cancelled) return\n\t\t\t\tconst err = error instanceof Error ? error : new Error(String(error))\n\t\t\t\tconsole.error('[Kora] Initialization failed:', err)\n\t\t\t\tsetInitError(err)\n\t\t\t})\n\t\treturn () => {\n\t\t\tcancelled = true\n\t\t}\n\t}, [app])\n\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tif (!app) {\n\t\t\t\tfallbackQueryStoreCache.current?.clear()\n\t\t\t}\n\t\t}\n\t}, [app])\n\n\tconst contextValue = useMemo<KoraContextValue | null>(() => {\n\t\tif (!resolvedStore) {\n\t\t\treturn null\n\t\t}\n\t\tif (fallbackQueryStoreCache.current === null) {\n\t\t\tfallbackQueryStoreCache.current = new QueryStoreCache()\n\t\t}\n\t\treturn {\n\t\t\tstore: resolvedStore,\n\t\t\tsyncEngine: resolvedSync,\n\t\t\tapp: app ?? null,\n\t\t\tevents: app?.events ?? null,\n\t\t\tsubscribeSyncStatus: app?.sync?.subscribeStatus ?? null,\n\t\t\tqueryStoreCache:\n\t\t\t\tapp && typeof app.getQueryStoreCache === 'function'\n\t\t\t\t\t? app.getQueryStoreCache()\n\t\t\t\t\t: fallbackQueryStoreCache.current,\n\t\t}\n\t}, [resolvedStore, resolvedSync, app])\n\n\tif (initError) {\n\t\treturn createElement(\n\t\t\t'div',\n\t\t\t{ style: { color: 'red', padding: '1rem', fontFamily: 'monospace' } },\n\t\t\tcreateElement('strong', null, 'Kora initialization error: '),\n\t\t\tinitError.message,\n\t\t)\n\t}\n\n\tif (!ready) {\n\t\treturn (fallback ?? null) as ReactNode\n\t}\n\n\tif (!contextValue) {\n\t\tthrow new Error(\n\t\t\t'KoraProvider requires either an \"app\" or \"store\" prop. ' +\n\t\t\t\t'Pass a KoraApp from createApp() or a Store instance.',\n\t\t)\n\t}\n\n\treturn createElement(KoraContext.Provider, { value: contextValue }, children)\n}\n\nfunction useKoraContext(): KoraContextValue {\n\tconst context = useContext(KoraContext)\n\tif (context === null) {\n\t\tthrow new Error(\n\t\t\t'useKoraContext must be used within a <KoraProvider>. ' +\n\t\t\t\t'Wrap your component tree with <KoraProvider store={store}>.',\n\t\t)\n\t}\n\treturn context\n}\n\nexport { KoraProvider, useKoraContext }\n","import type { AuthSyncBinding, AuthSyncState } from '@korajs/core/bindings'\nimport { createElement, useEffect, useRef, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { KoraAppLike } from '../types'\nimport { KoraProvider } from './kora-context'\n\nexport interface AuthBoundKoraProviderProps {\n\tauthClient: AuthSyncBinding\n\tcreateApp: (\n\t\tsession: Extract<AuthSyncState, { state: 'authenticated' }>,\n\t) => KoraAppLike & { close(): Promise<void> }\n\tsignedOut?: ReactNode\n\tfallback?: ReactNode\n\terror?: (context: AuthBoundKoraErrorContext) => ReactNode\n\tchildren?: ReactNode\n}\n\nexport interface AuthBoundKoraSession {\n\t/** The authenticated identity only. Access tokens are deliberately omitted. */\n\tuserId: string\n}\n\nexport interface AuthBoundKoraInitializationError {\n\t/** Stable Kora/DOM error code suitable for application-owned copy and recovery UI. */\n\tcode: string\n\tname: string\n\tmessage: string\n\t/** Sanitized primitive metadata. Credential-shaped keys are always removed. */\n\tmetadata: Readonly<Record<string, string | number | boolean | null>>\n\t/** Sanitized Error for logging; custom credential-bearing properties are omitted. */\n\tcause: Error\n}\n\nexport interface AuthBoundKoraErrorContext {\n\terror: AuthBoundKoraInitializationError\n\tretry(): void\n\tsession: AuthBoundKoraSession\n}\n\nconst SENSITIVE_METADATA_KEY = /token|secret|password|authorization|cookie/i\n\n/** Classify initialization failures without requiring applications to parse copy. */\nexport function classifyKoraInitializationError(error: unknown): AuthBoundKoraInitializationError {\n\tconst candidate = error as {\n\t\tcode?: unknown\n\t\tcontext?: unknown\n\t\tmessage?: unknown\n\t\tname?: unknown\n\t\tstack?: unknown\n\t}\n\tconst message = typeof candidate?.message === 'string' ? candidate.message : String(error)\n\tconst name = typeof candidate?.name === 'string' ? candidate.name : 'Error'\n\tconst cause = new Error(message)\n\tcause.name = name\n\tif (typeof candidate?.stack === 'string') cause.stack = candidate.stack\n\tlet code = typeof candidate?.code === 'string' ? candidate.code : 'INITIALIZATION_FAILED'\n\tif (code === 'INITIALIZATION_FAILED' && cause.name === 'QuotaExceededError') {\n\t\tcode = 'STORAGE_QUOTA_EXCEEDED'\n\t}\n\tconst metadata: Record<string, string | number | boolean | null> = {}\n\tif (candidate?.context && typeof candidate.context === 'object') {\n\t\tfor (const [key, value] of Object.entries(candidate.context)) {\n\t\t\tif (SENSITIVE_METADATA_KEY.test(key)) continue\n\t\t\tif (\n\t\t\t\ttypeof value === 'string' ||\n\t\t\t\ttypeof value === 'number' ||\n\t\t\t\ttypeof value === 'boolean' ||\n\t\t\t\tvalue === null\n\t\t\t) {\n\t\t\t\tmetadata[key] = value\n\t\t\t}\n\t\t}\n\t}\n\treturn { code, name: cause.name, message: cause.message, metadata, cause }\n}\n\n/**\n * Owns the security-sensitive app lifetime for shared-browser applications.\n * The previous app is fully closed before a different user's app is created,\n * and no stale provider tree is rendered across that boundary.\n */\nexport function AuthBoundKoraProvider({\n\tauthClient,\n\tcreateApp,\n\tsignedOut = null,\n\tfallback = null,\n\terror: renderError,\n\tchildren,\n}: AuthBoundKoraProviderProps): ReactNode {\n\tconst [app, setApp] = useState<(KoraAppLike & { close(): Promise<void> }) | null>(null)\n\tconst [state, setState] = useState<AuthSyncState>({ state: 'loading' })\n\tconst [initError, setInitError] = useState<{\n\t\terror: AuthBoundKoraInitializationError\n\t\tsession: AuthBoundKoraSession\n\t} | null>(null)\n\tconst active = useRef<(KoraAppLike & { close(): Promise<void> }) | null>(null)\n\tconst createAppRef = useRef(createApp)\n\tcreateAppRef.current = createApp\n\tconst activeUserId = useRef<string | null>(null)\n\tconst generation = useRef(0)\n\tconst transition = useRef(Promise.resolve())\n\tconst reconcileRef = useRef<() => void>(() => {})\n\n\tuseEffect(() => {\n\t\tlet disposed = false\n\t\tconst reconcile = (): void => {\n\t\t\tconst currentGeneration = ++generation.current\n\t\t\ttransition.current = transition.current\n\t\t\t\t.catch(() => {})\n\t\t\t\t.then(async () => {\n\t\t\t\t\tsetInitError(null)\n\t\t\t\t\tconst next =\n\t\t\t\t\t\t(await authClient.resolveSyncState?.()) ??\n\t\t\t\t\t\t({ state: 'signed-out', mayConnectAnonymously: false } as const)\n\t\t\t\t\tif (disposed || currentGeneration !== generation.current) return\n\t\t\t\t\tconst previous = active.current\n\t\t\t\t\t// Same-user token/role refreshes stay on the same database and app instance.\n\t\t\t\t\tif (next.state === 'authenticated' && next.userId === activeUserId.current && previous) {\n\t\t\t\t\t\tsetState(next)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tsetApp(null)\n\t\t\t\t\tactive.current = null\n\t\t\t\t\tactiveUserId.current = null\n\t\t\t\t\tif (previous) await previous.close()\n\t\t\t\t\tif (disposed || currentGeneration !== generation.current) return\n\t\t\t\t\tsetState(next)\n\t\t\t\t\tif (next.state !== 'authenticated') return\n\t\t\t\t\tconst created = createAppRef.current(next)\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait created.ready\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tawait created.close()\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t\tif (disposed || currentGeneration !== generation.current) {\n\t\t\t\t\t\tawait created.close()\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tactive.current = created\n\t\t\t\t\tactiveUserId.current = next.userId\n\t\t\t\t\tsetApp(created)\n\t\t\t\t})\n\t\t\t\t.catch((error: unknown) => {\n\t\t\t\t\tif (!disposed && currentGeneration === generation.current) {\n\t\t\t\t\t\tvoid authClient.resolveSyncState?.().then((failedSession) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!disposed &&\n\t\t\t\t\t\t\t\tcurrentGeneration === generation.current &&\n\t\t\t\t\t\t\t\tfailedSession?.state === 'authenticated'\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tsetInitError({\n\t\t\t\t\t\t\t\t\terror: classifyKoraInitializationError(error),\n\t\t\t\t\t\t\t\t\tsession: { userId: failedSession.userId },\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t}\n\t\treconcileRef.current = reconcile\n\t\treconcile()\n\t\tconst unsubscribe = authClient.subscribe?.(reconcile) ?? (() => {})\n\t\treturn () => {\n\t\t\tdisposed = true\n\t\t\tgeneration.current++\n\t\t\tunsubscribe()\n\t\t\tconst previous = active.current\n\t\t\tactive.current = null\n\t\t\tactiveUserId.current = null\n\t\t\tif (previous) void previous.close()\n\t\t}\n\t}, [authClient])\n\n\tif (initError) {\n\t\tif (renderError) {\n\t\t\treturn renderError({\n\t\t\t\terror: initError.error,\n\t\t\t\tsession: initError.session,\n\t\t\t\tretry: () => reconcileRef.current(),\n\t\t\t})\n\t\t}\n\t\treturn createElement(\n\t\t\t'div',\n\t\t\t{ style: { color: 'red', padding: '1rem', fontFamily: 'monospace' } },\n\t\t\tcreateElement('strong', null, 'Kora initialization error: '),\n\t\t\tinitError.error.message,\n\t\t)\n\t}\n\tif (state.state === 'signed-out' || state.state === 'anonymous') return signedOut\n\tif (!app) return fallback\n\treturn createElement(KoraProvider, { app, fallback }, children)\n}\n","import { useKoraContext } from '../context/kora-context'\nimport type { KoraAppLike } from '../types'\n\n/**\n * React hook that returns the Kora app instance from context.\n *\n * Use the generic parameter to cast to your typed app for full type inference:\n *\n * ```typescript\n * // In your app setup:\n * export const app = createApp({ schema: mySchema })\n * export type App = typeof app\n *\n * // In components:\n * const app = useApp<App>()\n * app.todos.insert({ title: 'Hello' }) // fully typed\n * const todos = useQuery(app.todos.where({ completed: false }))\n * ```\n *\n * Requires `KoraProvider` to be initialized with the `app` prop.\n * Throws if used outside of `KoraProvider` or without an `app` prop.\n *\n * @returns The KoraApp instance, typed as `T`\n */\nexport function useApp<T extends KoraAppLike = KoraAppLike>(): T {\n\tconst { app } = useKoraContext()\n\tif (!app) {\n\t\tthrow new Error(\n\t\t\t'useApp() requires KoraProvider to be initialized with an \"app\" prop. ' +\n\t\t\t\t'Pass your createApp() result to <KoraProvider app={app}>.',\n\t\t)\n\t}\n\treturn app as T\n}\n","import type { CollectionRecord, QueryBuilder } from '@korajs/store'\nimport { assertQueryReady } from '@korajs/store'\nimport { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react'\nimport { useKoraContext } from '../context/kora-context'\nimport type { UseQueryOptions } from '../types'\n\nconst EMPTY_ARRAY: readonly unknown[] = Object.freeze([])\n\nconst noopSubscribe = (_onStoreChange: () => void): (() => void) => {\n\treturn () => {}\n}\n\n/**\n * React hook for reactive queries against the local Kora store.\n */\nexport function useQuery<T = CollectionRecord>(\n\tquery: QueryBuilder<T>,\n\toptions?: UseQueryOptions,\n): readonly T[] {\n\tconst { queryStoreCache } = useKoraContext()\n\tconst enabled = options?.enabled !== false\n\tconst descriptorKey = JSON.stringify(query.getDescriptor())\n\tconst queryRef = useRef(query)\n\tqueryRef.current = query\n\tconst lastSnapshotRef = useRef<readonly T[]>(EMPTY_ARRAY as readonly T[])\n\n\tconst [queryStore, setQueryStore] = useState<import('@korajs/store').QueryStore<T> | null>(null)\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: descriptorKey intentionally re-runs the effect when the query descriptor changes, even though the effect reads the query via queryRef\n\tuseEffect(() => {\n\t\tif (!enabled) {\n\t\t\tsetQueryStore(null)\n\t\t\treturn\n\t\t}\n\n\t\tconst currentQuery = queryRef.current\n\t\tassertQueryReady(currentQuery)\n\t\tconst store = queryStoreCache.getOrCreate(currentQuery)\n\t\tsetQueryStore(store)\n\n\t\treturn () => {\n\t\t\tqueryStoreCache.release(currentQuery as QueryBuilder<unknown>)\n\t\t}\n\t}, [descriptorKey, enabled, queryStoreCache])\n\n\tconst getSnapshot = useCallback((): readonly T[] => {\n\t\tif (!enabled) {\n\t\t\tlastSnapshotRef.current = EMPTY_ARRAY as readonly T[]\n\t\t\treturn lastSnapshotRef.current\n\t\t}\n\t\tif (!queryStore) {\n\t\t\treturn lastSnapshotRef.current\n\t\t}\n\t\tif (!queryStore.hasSnapshot()) {\n\t\t\treturn lastSnapshotRef.current\n\t\t}\n\t\tconst snapshot = queryStore.getSnapshot()\n\t\tlastSnapshotRef.current = snapshot\n\t\treturn snapshot\n\t}, [enabled, queryStore])\n\n\treturn useSyncExternalStore(queryStore ? queryStore.subscribe : noopSubscribe, getSnapshot)\n}\n","import { createMutationController } from '@korajs/core/bindings'\nimport { useRef, useSyncExternalStore } from 'react'\nimport type { UseMutationOptions, UseMutationResult } from '../types'\nimport { useController } from './use-controller'\n\n/**\n * React hook for performing mutations against the local Kora store.\n */\nexport function useMutation<TData, TArgs extends unknown[], TContext = void>(\n\tmutationFn: (...args: TArgs) => Promise<TData>,\n\toptions?: UseMutationOptions<TData, TArgs, TContext>,\n): UseMutationResult<TData, TArgs> {\n\tconst fnRef = useRef(mutationFn)\n\tfnRef.current = mutationFn\n\n\tconst optionsRef = useRef(options)\n\toptionsRef.current = options\n\n\tconst getController = useController(\n\t\t() =>\n\t\t\tcreateMutationController<TData, TArgs, TContext>({\n\t\t\t\tmutationFn: (...args) => fnRef.current(...args),\n\t\t\t\tresolveOptions: () => optionsRef.current,\n\t\t\t}),\n\t\t(controller) => controller.destroy(),\n\t\t[],\n\t)\n\n\tconst state = useSyncExternalStore(\n\t\t(onStoreChange) => getController().subscribe(onStoreChange),\n\t\t() => getController().getSnapshot(),\n\t\t() => getController().getSnapshot(),\n\t)\n\n\treturn {\n\t\tmutate: (...args: TArgs) => getController().mutate(...args),\n\t\tmutateAsync: (...args: TArgs) => getController().mutateAsync(...args),\n\t\tisLoading: state.isLoading,\n\t\terror: state.error,\n\t\treset: () => getController().reset(),\n\t}\n}\n","import { useEffect, useReducer, useRef } from 'react'\n\n/**\n * Manages the lifecycle of an external controller in a StrictMode-safe way.\n *\n * React 18+ StrictMode mounts, unmounts, and remounts components in development.\n * The previous pattern (create in `useMemo`, destroy in effect cleanup) permanently\n * destroyed the memoized controller on the simulated unmount, leaving every\n * subsequent interaction against a disposed controller.\n *\n * This hook instead keeps the controller in a ref and recreates it lazily\n * whenever it has been destroyed, so the effect cleanup / re-run cycle is safe.\n *\n * Returns a getter so subscribe/getSnapshot closures always reach a live controller.\n */\nexport function useController<C>(\n\tcreate: () => C,\n\tdestroy: (controller: C) => void,\n\tdeps: readonly unknown[],\n): () => C {\n\tconst controllerRef = useRef<C | null>(null)\n\tconst createRef = useRef(create)\n\tcreateRef.current = create\n\n\tconst [, forceRender] = useReducer((count: number) => count + 1, 0)\n\n\tconst getController = useRef((): C => {\n\t\tif (controllerRef.current === null) {\n\t\t\tcontrollerRef.current = createRef.current()\n\t\t}\n\t\treturn controllerRef.current\n\t}).current\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: deps are the caller's create() inputs\n\tuseEffect(() => {\n\t\tif (controllerRef.current === null) {\n\t\t\tcontrollerRef.current = createRef.current()\n\t\t\t// A destroyed controller was recreated (StrictMode remount or deps\n\t\t\t// change): re-render so useSyncExternalStore rebinds to the new one.\n\t\t\tforceRender()\n\t\t}\n\t\treturn () => {\n\t\t\tconst controller = controllerRef.current\n\t\t\tcontrollerRef.current = null\n\t\t\tif (controller !== null) {\n\t\t\t\tdestroy(controller)\n\t\t\t}\n\t\t}\n\t}, deps)\n\n\treturn getController\n}\n","import type { SyncStatusInfo } from '@korajs/sync'\nimport { createSyncStatusController } from '@korajs/sync'\nimport { useSyncExternalStore } from 'react'\nimport { useKoraContext } from '../context/kora-context'\nimport { useController } from './use-controller'\n\n/**\n * React hook for monitoring the sync engine's connection status.\n */\nexport function useSyncStatus(): SyncStatusInfo {\n\tconst { syncEngine, subscribeSyncStatus, events } = useKoraContext()\n\n\tconst getController = useController(\n\t\t() =>\n\t\t\tcreateSyncStatusController({\n\t\t\t\tsyncEngine,\n\t\t\t\tsubscribeSyncStatus,\n\t\t\t\tevents: subscribeSyncStatus ? null : events,\n\t\t\t}),\n\t\t(controller) => controller.destroy(),\n\t\t[syncEngine, subscribeSyncStatus, events],\n\t)\n\n\treturn useSyncExternalStore(\n\t\t(onStoreChange) => getController().subscribe(onStoreChange),\n\t\t() => getController().getSnapshot(),\n\t\t() => getController().getSnapshot(),\n\t)\n}\n","import type { CollectionAccessor } from '@korajs/store'\nimport { useMemo } from 'react'\nimport { useKoraContext } from '../context/kora-context'\n\n/**\n * React hook that returns a CollectionAccessor for the given collection name.\n * Convenience hook for accessing a collection without going through the store directly.\n *\n * @param name - The collection name (must match a collection in the schema)\n * @returns CollectionAccessor with insert, findById, update, delete, and where methods\n *\n * @example\n * ```typescript\n * const todos = useCollection('todos')\n * await todos.insert({ title: 'New todo' })\n * ```\n */\nexport function useCollection(name: string): CollectionAccessor {\n\tconst { store } = useKoraContext()\n\n\treturn useMemo(() => {\n\t\treturn store.collection(name)\n\t}, [store, name])\n}\n","import { asRichTextSyncEngine, createRichTextController } from '@korajs/store'\nimport type { RichTextControllerSnapshot } from '@korajs/store'\nimport type { AwarenessUser } from '@korajs/sync'\nimport { useCallback, useEffect, useMemo, useSyncExternalStore } from 'react'\nimport { useKoraContext } from '../context/kora-context'\nimport type { UseRichTextResult } from '../types'\nimport { useController } from './use-controller'\n\nexport interface UseRichTextOptions {\n\tuser?: AwarenessUser\n\tuseDocChannel?: boolean\n}\n\n/**\n * Binds a richtext field to a shared Yjs document for editor integration.\n */\nexport function useRichText(\n\tcollectionName: string,\n\trecordId: string,\n\tfieldName: string,\n\toptions?: UseRichTextOptions,\n): UseRichTextResult {\n\tconst { store, syncEngine } = useKoraContext()\n\tconst collection = useMemo(() => store.collection(collectionName), [store, collectionName])\n\n\tconst getController = useController(\n\t\t() =>\n\t\t\tcreateRichTextController({\n\t\t\t\tcollection,\n\t\t\t\tcollectionName,\n\t\t\t\trecordId,\n\t\t\t\tfieldName,\n\t\t\t\tstore,\n\t\t\t\tsyncEngine: asRichTextSyncEngine(syncEngine),\n\t\t\t\tuseDocChannel: options?.useDocChannel,\n\t\t\t\tuser: options?.user,\n\t\t\t}),\n\t\t(controller) => controller.destroy(),\n\t\t[collection, collectionName, fieldName, options?.useDocChannel, recordId, store, syncEngine],\n\t)\n\n\tuseEffect(() => {\n\t\tgetController().setUser(options?.user)\n\t}, [getController, options?.user])\n\n\tconst snapshot = useSyncExternalStore(\n\t\t(onStoreChange) => getController().subscribe(onStoreChange),\n\t\t() => getController().getSnapshot(),\n\t\t() => getController().getSnapshot(),\n\t)\n\n\tconst undo = useCallback(() => {\n\t\tgetController().undo()\n\t}, [getController])\n\tconst redo = useCallback(() => {\n\t\tgetController().redo()\n\t}, [getController])\n\tconst setCursor = useCallback(\n\t\t(anchor: number, head: number) => getController().setCursor(anchor, head),\n\t\t[getController],\n\t)\n\tconst clearCursor = useCallback(() => getController().clearCursor(), [getController])\n\n\treturn buildResult(getController(), snapshot, undo, redo, setCursor, clearCursor)\n}\n\nfunction buildResult(\n\tcontroller: ReturnType<typeof createRichTextController>,\n\tsnapshot: RichTextControllerSnapshot,\n\tundo: () => void,\n\tredo: () => void,\n\tsetCursor: (anchor: number, head: number) => void,\n\tclearCursor: () => void,\n): UseRichTextResult {\n\treturn {\n\t\tdoc: controller.doc,\n\t\ttext: controller.text,\n\t\tundo,\n\t\tredo,\n\t\tcanUndo: snapshot.canUndo,\n\t\tcanRedo: snapshot.canRedo,\n\t\tready: snapshot.ready,\n\t\terror: snapshot.error,\n\t\tcursors: [...snapshot.cursors],\n\t\tsetCursor,\n\t\tclearCursor,\n\t}\n}\n","import { useEffect } from 'react'\nimport { useKoraContext } from '../context/kora-context'\n\n/**\n * Sets the local user's collaborative presence state.\n *\n * Automatically cleans up presence on unmount.\n */\nexport function usePresence(user: { name: string; color: string; avatar?: string } | null): void {\n\tconst { syncEngine } = useKoraContext()\n\tconst name = user?.name ?? null\n\tconst color = user?.color ?? null\n\tconst avatar = user?.avatar ?? null\n\n\tuseEffect(() => {\n\t\tif (!syncEngine || !name || !color) return\n\n\t\tconst awareness = syncEngine.getAwarenessManager()\n\t\tawareness.setLocalState({\n\t\t\tuser: { name, color, avatar: avatar ?? undefined },\n\t\t})\n\n\t\treturn () => {\n\t\t\tawareness.setLocalState(null)\n\t\t}\n\t}, [syncEngine, name, color, avatar])\n}\n","import type { AwarenessState } from '@korajs/sync'\nimport { subscribeRemoteAwarenessStates } from '@korajs/sync'\nimport { useCallback, useEffect, useRef, useSyncExternalStore } from 'react'\nimport { useKoraContext } from '../context/kora-context'\n\nconst EMPTY_ARRAY: AwarenessState[] = []\n\n/**\n * Returns all currently connected collaborators' awareness states.\n *\n * Excludes the local user — only returns remote peers.\n */\nexport function useCollaborators(): AwarenessState[] {\n\tconst { syncEngine } = useKoraContext()\n\n\tconst snapshotRef = useRef<AwarenessState[]>(EMPTY_ARRAY)\n\n\tconst subscribe = useCallback(\n\t\t(onStoreChange: () => void): (() => void) => {\n\t\t\tif (!syncEngine) {\n\t\t\t\tsnapshotRef.current = EMPTY_ARRAY\n\t\t\t\treturn () => {}\n\t\t\t}\n\n\t\t\tconst awareness = syncEngine.getAwarenessManager()\n\t\t\treturn subscribeRemoteAwarenessStates(awareness, (states) => {\n\t\t\t\tsnapshotRef.current = states\n\t\t\t\tonStoreChange()\n\t\t\t})\n\t\t},\n\t\t[syncEngine],\n\t)\n\n\tconst getSnapshot = useCallback((): AwarenessState[] => snapshotRef.current, [])\n\n\tuseEffect(() => {\n\t\tif (!syncEngine) {\n\t\t\tsnapshotRef.current = EMPTY_ARRAY\n\t\t}\n\t}, [syncEngine])\n\n\treturn useSyncExternalStore(subscribe, getSnapshot)\n}\n"],"mappings":"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","names":["createElement","useEffect","useRef","useState","useState","useRef","useEffect","createElement","useEffect","useRef","useState","useRef","useState","useEffect","useRef","useSyncExternalStore","useEffect","useRef","useRef","useSyncExternalStore","useSyncExternalStore","useSyncExternalStore","useMemo","useMemo","useCallback","useEffect","useMemo","useSyncExternalStore","useMemo","useEffect","useSyncExternalStore","useCallback","useEffect","useEffect","useCallback","useEffect","useRef","useSyncExternalStore","EMPTY_ARRAY","useRef","useCallback","useEffect","useSyncExternalStore"]}
|
|
1
|
+
{"version":3,"sources":["../src/context/kora-context.ts","../src/context/auth-bound-kora-provider.ts","../src/hooks/use-app.ts","../src/hooks/use-query.ts","../src/hooks/create-kora-hooks.ts","../src/hooks/use-mutation.ts","../src/hooks/use-controller.ts","../src/hooks/use-sync-status.ts","../src/hooks/use-collection.ts","../src/hooks/use-rich-text.ts","../src/hooks/use-presence.ts","../src/hooks/use-collaborators.ts"],"sourcesContent":["import type { Store } from '@korajs/store'\nimport { QueryStoreCache } from '@korajs/store'\nimport type { SyncEngine } from '@korajs/sync'\nimport {\n\tcreateContext,\n\tcreateElement,\n\tuseContext,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react'\nimport type { ReactNode } from 'react'\nimport type { KoraContextValue, KoraProviderProps } from '../types'\n\nconst KoraContext = createContext<KoraContextValue | null>(null)\n\n/**\n * Provides Kora store and optional sync engine to all child components.\n * Must wrap any component that uses Kora hooks (useQuery, useMutation, etc.).\n */\nfunction KoraProvider({\n\tapp,\n\tstore,\n\tsyncEngine,\n\tfallback,\n\tchildren,\n}: KoraProviderProps): ReactNode {\n\tconst [resolvedStore, setResolvedStore] = useState<Store | null>(store ?? null)\n\tconst [resolvedSync, setResolvedSync] = useState<SyncEngine | null>(syncEngine ?? null)\n\tconst [ready, setReady] = useState(!app)\n\tconst [initError, setInitError] = useState<Error | null>(null)\n\tconst fallbackQueryStoreCache = useRef<QueryStoreCache | null>(null)\n\n\tif (!fallbackQueryStoreCache.current) {\n\t\tfallbackQueryStoreCache.current = new QueryStoreCache()\n\t}\n\n\tuseEffect(() => {\n\t\tif (!app) return\n\t\tlet cancelled = false\n\t\tapp.ready\n\t\t\t.then(() => {\n\t\t\t\tif (cancelled) return\n\t\t\t\tsetResolvedStore(app.getStore())\n\t\t\t\tsetResolvedSync(app.getSyncEngine())\n\t\t\t\tsetReady(true)\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (cancelled) return\n\t\t\t\tconst err = error instanceof Error ? error : new Error(String(error))\n\t\t\t\tconsole.error('[Kora] Initialization failed:', err)\n\t\t\t\tsetInitError(err)\n\t\t\t})\n\t\treturn () => {\n\t\t\tcancelled = true\n\t\t}\n\t}, [app])\n\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tif (!app) {\n\t\t\t\tfallbackQueryStoreCache.current?.clear()\n\t\t\t}\n\t\t}\n\t}, [app])\n\n\tconst contextValue = useMemo<KoraContextValue | null>(() => {\n\t\tif (!resolvedStore) {\n\t\t\treturn null\n\t\t}\n\t\tif (fallbackQueryStoreCache.current === null) {\n\t\t\tfallbackQueryStoreCache.current = new QueryStoreCache()\n\t\t}\n\t\treturn {\n\t\t\tstore: resolvedStore,\n\t\t\tsyncEngine: resolvedSync,\n\t\t\tapp: app ?? null,\n\t\t\tevents: app?.events ?? null,\n\t\t\tsubscribeSyncStatus: app?.sync?.subscribeStatus ?? null,\n\t\t\tqueryStoreCache:\n\t\t\t\tapp && typeof app.getQueryStoreCache === 'function'\n\t\t\t\t\t? app.getQueryStoreCache()\n\t\t\t\t\t: fallbackQueryStoreCache.current,\n\t\t}\n\t}, [resolvedStore, resolvedSync, app])\n\n\tif (initError) {\n\t\treturn createElement(\n\t\t\t'div',\n\t\t\t{ style: { color: 'red', padding: '1rem', fontFamily: 'monospace' } },\n\t\t\tcreateElement('strong', null, 'Kora initialization error: '),\n\t\t\tinitError.message,\n\t\t)\n\t}\n\n\tif (!ready) {\n\t\treturn (fallback ?? null) as ReactNode\n\t}\n\n\tif (!contextValue) {\n\t\tthrow new Error(\n\t\t\t'KoraProvider requires either an \"app\" or \"store\" prop. ' +\n\t\t\t\t'Pass a KoraApp from createApp() or a Store instance.',\n\t\t)\n\t}\n\n\treturn createElement(KoraContext.Provider, { value: contextValue }, children)\n}\n\nfunction useKoraContext(): KoraContextValue {\n\tconst context = useContext(KoraContext)\n\tif (context === null) {\n\t\tthrow new Error(\n\t\t\t'useKoraContext must be used within a <KoraProvider>. ' +\n\t\t\t\t'Wrap your component tree with <KoraProvider store={store}>.',\n\t\t)\n\t}\n\treturn context\n}\n\nexport { KoraProvider, useKoraContext }\n","import type { AuthSyncBinding, AuthSyncState } from '@korajs/core/bindings'\nimport { createElement, useEffect, useRef, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { KoraAppLike } from '../types'\nimport { KoraProvider } from './kora-context'\n\nexport interface AuthBoundKoraProviderProps {\n\tauthClient: AuthSyncBinding\n\tcreateApp: (\n\t\tsession: Extract<AuthSyncState, { state: 'authenticated' }>,\n\t) => KoraAppLike & { close(): Promise<void> }\n\tsignedOut?: ReactNode\n\t/**\n\t * Rendered instead of the app while the session is locked (offline longer\n\t * than the auth client's `maxOfflineGraceMs`, or the device clock moved\n\t * backwards). The app and its local data stay open underneath; nothing is\n\t * wiped. Defaults to `signedOut`.\n\t */\n\tlocked?: ReactNode\n\tfallback?: ReactNode\n\terror?: (context: AuthBoundKoraErrorContext) => ReactNode\n\tchildren?: ReactNode\n}\n\nexport interface AuthBoundKoraSession {\n\t/** The authenticated identity only. Access tokens are deliberately omitted. */\n\tuserId: string\n}\n\nexport interface AuthBoundKoraInitializationError {\n\t/** Stable Kora/DOM error code suitable for application-owned copy and recovery UI. */\n\tcode: string\n\tname: string\n\tmessage: string\n\t/** Sanitized primitive metadata. Credential-shaped keys are always removed. */\n\tmetadata: Readonly<Record<string, string | number | boolean | null>>\n\t/** Sanitized Error for logging; custom credential-bearing properties are omitted. */\n\tcause: Error\n}\n\nexport interface AuthBoundKoraErrorContext {\n\terror: AuthBoundKoraInitializationError\n\tretry(): void\n\tsession: AuthBoundKoraSession\n}\n\nconst SENSITIVE_METADATA_KEY = /token|secret|password|authorization|cookie/i\n\n/** Classify initialization failures without requiring applications to parse copy. */\nexport function classifyKoraInitializationError(error: unknown): AuthBoundKoraInitializationError {\n\tconst candidate = error as {\n\t\tcode?: unknown\n\t\tcontext?: unknown\n\t\tmessage?: unknown\n\t\tname?: unknown\n\t\tstack?: unknown\n\t}\n\tconst message = typeof candidate?.message === 'string' ? candidate.message : String(error)\n\tconst name = typeof candidate?.name === 'string' ? candidate.name : 'Error'\n\tconst cause = new Error(message)\n\tcause.name = name\n\tif (typeof candidate?.stack === 'string') cause.stack = candidate.stack\n\tlet code = typeof candidate?.code === 'string' ? candidate.code : 'INITIALIZATION_FAILED'\n\tif (code === 'INITIALIZATION_FAILED' && cause.name === 'QuotaExceededError') {\n\t\tcode = 'STORAGE_QUOTA_EXCEEDED'\n\t}\n\tconst metadata: Record<string, string | number | boolean | null> = {}\n\tif (candidate?.context && typeof candidate.context === 'object') {\n\t\tfor (const [key, value] of Object.entries(candidate.context)) {\n\t\t\tif (SENSITIVE_METADATA_KEY.test(key)) continue\n\t\t\tif (\n\t\t\t\ttypeof value === 'string' ||\n\t\t\t\ttypeof value === 'number' ||\n\t\t\t\ttypeof value === 'boolean' ||\n\t\t\t\tvalue === null\n\t\t\t) {\n\t\t\t\tmetadata[key] = value\n\t\t\t}\n\t\t}\n\t}\n\treturn { code, name: cause.name, message: cause.message, metadata, cause }\n}\n\n/**\n * Owns the security-sensitive app lifetime for shared-browser applications.\n * The previous app is fully closed before a different user's app is created,\n * and no stale provider tree is rendered across that boundary.\n */\nexport function AuthBoundKoraProvider({\n\tauthClient,\n\tcreateApp,\n\tsignedOut = null,\n\tlocked,\n\tfallback = null,\n\terror: renderError,\n\tchildren,\n}: AuthBoundKoraProviderProps): ReactNode {\n\tconst [app, setApp] = useState<(KoraAppLike & { close(): Promise<void> }) | null>(null)\n\tconst [state, setState] = useState<AuthSyncState>({ state: 'loading' })\n\tconst [initError, setInitError] = useState<{\n\t\terror: AuthBoundKoraInitializationError\n\t\tsession: AuthBoundKoraSession\n\t} | null>(null)\n\tconst active = useRef<(KoraAppLike & { close(): Promise<void> }) | null>(null)\n\tconst createAppRef = useRef(createApp)\n\tcreateAppRef.current = createApp\n\tconst activeUserId = useRef<string | null>(null)\n\tconst generation = useRef(0)\n\tconst transition = useRef(Promise.resolve())\n\tconst reconcileRef = useRef<() => void>(() => {})\n\n\tuseEffect(() => {\n\t\tlet disposed = false\n\t\tconst reconcile = (): void => {\n\t\t\tconst currentGeneration = ++generation.current\n\t\t\ttransition.current = transition.current\n\t\t\t\t.catch(() => {})\n\t\t\t\t.then(async () => {\n\t\t\t\t\tsetInitError(null)\n\t\t\t\t\tconst next =\n\t\t\t\t\t\t(await authClient.resolveSyncState?.()) ??\n\t\t\t\t\t\t({ state: 'signed-out', mayConnectAnonymously: false } as const)\n\t\t\t\t\tif (disposed || currentGeneration !== generation.current) return\n\t\t\t\t\tconst previous = active.current\n\t\t\t\t\t// Same-user token/role refreshes stay on the same database and app instance.\n\t\t\t\t\tif (next.state === 'authenticated' && next.userId === activeUserId.current && previous) {\n\t\t\t\t\t\tsetState(next)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tsetApp(null)\n\t\t\t\t\tactive.current = null\n\t\t\t\t\tactiveUserId.current = null\n\t\t\t\t\tif (previous) await previous.close()\n\t\t\t\t\tif (disposed || currentGeneration !== generation.current) return\n\t\t\t\t\tsetState(next)\n\t\t\t\t\tif (next.state !== 'authenticated') return\n\t\t\t\t\tconst created = createAppRef.current(next)\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait created.ready\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tawait created.close()\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t\tif (disposed || currentGeneration !== generation.current) {\n\t\t\t\t\t\tawait created.close()\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tactive.current = created\n\t\t\t\t\tactiveUserId.current = next.userId\n\t\t\t\t\tsetApp(created)\n\t\t\t\t})\n\t\t\t\t.catch((error: unknown) => {\n\t\t\t\t\tif (!disposed && currentGeneration === generation.current) {\n\t\t\t\t\t\tvoid authClient.resolveSyncState?.().then((failedSession) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t!disposed &&\n\t\t\t\t\t\t\t\tcurrentGeneration === generation.current &&\n\t\t\t\t\t\t\t\tfailedSession?.state === 'authenticated'\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tsetInitError({\n\t\t\t\t\t\t\t\t\terror: classifyKoraInitializationError(error),\n\t\t\t\t\t\t\t\t\tsession: { userId: failedSession.userId },\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t}\n\t\treconcileRef.current = reconcile\n\t\treconcile()\n\t\tconst unsubscribe = authClient.subscribe?.(reconcile) ?? (() => {})\n\t\treturn () => {\n\t\t\tdisposed = true\n\t\t\tgeneration.current++\n\t\t\tunsubscribe()\n\t\t\tconst previous = active.current\n\t\t\tactive.current = null\n\t\t\tactiveUserId.current = null\n\t\t\tif (previous) void previous.close()\n\t\t}\n\t}, [authClient])\n\n\tif (initError) {\n\t\tif (renderError) {\n\t\t\treturn renderError({\n\t\t\t\terror: initError.error,\n\t\t\t\tsession: initError.session,\n\t\t\t\tretry: () => reconcileRef.current(),\n\t\t\t})\n\t\t}\n\t\treturn createElement(\n\t\t\t'div',\n\t\t\t{ style: { color: 'red', padding: '1rem', fontFamily: 'monospace' } },\n\t\t\tcreateElement('strong', null, 'Kora initialization error: '),\n\t\t\tinitError.error.message,\n\t\t)\n\t}\n\tif (state.state === 'signed-out' || state.state === 'anonymous') return signedOut\n\t// Authenticated-offline sessions (token: null) mount the user's own local\n\t// database like fresh ones; only a locked session is hidden behind `locked`.\n\tif (state.state === 'authenticated' && state.locked) return locked ?? signedOut\n\tif (!app) return fallback\n\treturn createElement(KoraProvider, { app, fallback }, children)\n}\n","import { useKoraContext } from '../context/kora-context'\nimport type { KoraAppLike } from '../types'\n\n/**\n * React hook that returns the Kora app instance from context.\n *\n * Use the generic parameter to cast to your typed app for full type inference:\n *\n * ```typescript\n * // In your app setup:\n * export const app = createApp({ schema: mySchema })\n * export type App = typeof app\n *\n * // In components:\n * const app = useApp<App>()\n * app.todos.insert({ title: 'Hello' }) // fully typed\n * const todos = useQuery(app.todos.where({ completed: false }))\n * ```\n *\n * Requires `KoraProvider` to be initialized with the `app` prop.\n * Throws if used outside of `KoraProvider` or without an `app` prop.\n *\n * @returns The KoraApp instance, typed as `T`\n */\nexport function useApp<T extends KoraAppLike = KoraAppLike>(): T {\n\tconst { app } = useKoraContext()\n\tif (!app) {\n\t\tthrow new Error(\n\t\t\t'useApp() requires KoraProvider to be initialized with an \"app\" prop. ' +\n\t\t\t\t'Pass your createApp() result to <KoraProvider app={app}>.',\n\t\t)\n\t}\n\treturn app as T\n}\n","import type { CollectionRecord, QueryBuilder, QueryStore } from '@korajs/store'\nimport { assertQueryReady, queryKey } from '@korajs/store'\nimport { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'\nimport { useKoraContext } from '../context/kora-context'\nimport type { UseQueryOptions, UseQueryStateResult } from '../types'\n\nconst EMPTY_ARRAY: readonly unknown[] = Object.freeze([])\n\nconst noopSubscribe = (_onStoreChange: () => void): (() => void) => {\n\treturn () => {}\n}\n\n// Server renders and the hydration pass have no local database: they render the\n// empty list, and the client fills it in after hydration (DX-6).\nconst getServerSnapshot = (): readonly never[] => EMPTY_ARRAY as readonly never[]\nconst getNoError = (): Error | null => null\n\n/**\n * The error channel a QueryStore exposes (STORE-12). Read structurally so this\n * binding works against a store build that predates it (no error state, as before).\n */\ninterface QueryStoreErrorChannel {\n\tgetError?: () => Error | null\n}\n\nfunction readQueryError(queryStore: QueryStore<unknown> | null): Error | null {\n\tif (!queryStore) return null\n\tconst channel = queryStore as unknown as QueryStoreErrorChannel\n\treturn typeof channel.getError === 'function' ? channel.getError() : null\n}\n\ninterface QuerySubscription<T> {\n\tdata: readonly T[]\n\terror: Error | null\n\tready: boolean\n}\n\n/**\n * Shared engine of {@link useQuery} and {@link useQueryState}: one ref-counted\n * QueryStore per query descriptor, read through useSyncExternalStore with stable\n * subscribe/getSnapshot, so a render never tears and an unchanged result never\n * re-renders.\n */\nfunction useQuerySubscription<T>(\n\tquery: QueryBuilder<T>,\n\toptions: UseQueryOptions | undefined,\n): QuerySubscription<T> {\n\tconst { queryStoreCache } = useKoraContext()\n\tconst enabled = options?.enabled !== false\n\tconst descriptorKey = queryKey(query.getDescriptor())\n\tconst queryRef = useRef(query)\n\tqueryRef.current = query\n\tconst lastSnapshotRef = useRef<readonly T[]>(EMPTY_ARRAY as readonly T[])\n\n\tconst [queryStore, setQueryStore] = useState<QueryStore<T> | null>(null)\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: descriptorKey intentionally re-runs the effect when the query descriptor changes, even though the effect reads the query via queryRef\n\tuseEffect(() => {\n\t\tif (!enabled) {\n\t\t\tsetQueryStore(null)\n\t\t\treturn\n\t\t}\n\n\t\tconst currentQuery = queryRef.current\n\t\tassertQueryReady(currentQuery)\n\t\tconst store = queryStoreCache.getOrCreate(currentQuery)\n\t\tsetQueryStore(store)\n\n\t\treturn () => {\n\t\t\tqueryStoreCache.release(currentQuery as QueryBuilder<unknown>)\n\t\t}\n\t}, [descriptorKey, enabled, queryStoreCache])\n\n\t// The store's own subscribe is a stable arrow per QueryStore, so React subscribes\n\t// once per store, not once per render.\n\tconst subscribe = enabled && queryStore ? queryStore.subscribe : noopSubscribe\n\n\tconst getSnapshot = useCallback((): readonly T[] => {\n\t\tif (!enabled) {\n\t\t\tlastSnapshotRef.current = EMPTY_ARRAY as readonly T[]\n\t\t\treturn lastSnapshotRef.current\n\t\t}\n\t\tif (!queryStore || !queryStore.hasSnapshot()) {\n\t\t\t// Keep the previous result while a new descriptor loads: no flash of empty.\n\t\t\treturn lastSnapshotRef.current\n\t\t}\n\t\tconst snapshot = queryStore.getSnapshot()\n\t\tlastSnapshotRef.current = snapshot\n\t\treturn snapshot\n\t}, [enabled, queryStore])\n\n\tconst getError = useCallback(\n\t\t(): Error | null => (enabled ? readQueryError(queryStore as QueryStore<unknown> | null) : null),\n\t\t[enabled, queryStore],\n\t)\n\n\tconst data = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot as () => readonly T[])\n\tconst error = useSyncExternalStore(subscribe, getError, getNoError)\n\tconst ready = enabled && queryStore !== null && queryStore.hasSnapshot()\n\n\treturn { data, error, ready }\n}\n\n/**\n * React hook for reactive queries against the local Kora store.\n *\n * Returns the current rows synchronously (no loading state for local data) and\n * re-renders only when the result set changes. The array keeps its identity while\n * the result is unchanged. On the server (`renderToString`, Next.js App Router) and\n * during hydration it returns `[]`; the rows arrive right after hydration.\n *\n * A query that fails (for example a where/orderBy on an unknown field) is thrown to\n * the nearest React error boundary, so the failure is visible instead of an empty\n * list. Pass `throwOnError: false`, or use {@link useQueryState}, to handle it inline.\n *\n * @param query - A query builder, for example `app.todos.where({ completed: false })`\n * @param options - `enabled` (default true) and `throwOnError` (default true)\n * @returns The current result rows\n *\n * @example\n * ```tsx\n * const todos = useQuery(app.todos.where({ completed: false }).orderBy('createdAt'))\n * ```\n */\nexport function useQuery<T = CollectionRecord>(\n\tquery: QueryBuilder<T>,\n\toptions?: UseQueryOptions,\n): readonly T[] {\n\tconst { data, error } = useQuerySubscription(query, options)\n\tif (error && options?.throwOnError !== false) {\n\t\tthrow error\n\t}\n\treturn data\n}\n\n/**\n * Like {@link useQuery}, but returns the error instead of throwing it.\n *\n * @param query - A query builder\n * @param options - `enabled` (default true); `throwOnError` is ignored\n * @returns `{ data, error, ready }`, the same object until one of them changes.\n * `ready` is false until the first result for the current query has arrived.\n *\n * @example\n * ```tsx\n * const { data: todos, error } = useQueryState(app.todos.where({ completed: false }))\n * if (error) return <p role=\"alert\">{error.message}</p>\n * ```\n */\nexport function useQueryState<T = CollectionRecord>(\n\tquery: QueryBuilder<T>,\n\toptions?: UseQueryOptions,\n): UseQueryStateResult<T> {\n\tconst { data, error, ready } = useQuerySubscription(query, options)\n\treturn useMemo(() => ({ data, error, ready }), [data, error, ready])\n}\n","import type { CollectionRecord, QueryBuilder } from '@korajs/store'\nimport { useMemo } from 'react'\nimport { useKoraContext } from '../context/kora-context'\nimport type { KoraAppLike } from '../types'\nimport { useApp } from './use-app'\nimport { useMutation } from './use-mutation'\nimport { useQuery, useQueryState } from './use-query'\nimport { useSyncStatus } from './use-sync-status'\n\n/**\n * The collections an app exposes, read from its `collections` namespace. Purely\n * structural, so it follows whatever accessor types `createApp` infers from the schema.\n */\nexport type AppCollections<TApp> = TApp extends { collections: infer C } ? C : never\n\n/** The collection names of an app, as string literals. */\nexport type AppCollectionName<TApp> = Extract<keyof AppCollections<TApp>, string>\n\n/** The record type of a collection accessor, inferred from what its queries return. */\nexport type AccessorRecord<TAccessor> = TAccessor extends {\n\twhere(...args: never[]): QueryBuilder<infer R>\n}\n\t? R\n\t: CollectionRecord\n\n/** The record type of collection `N` of an app. */\nexport type AppRecord<TApp, N extends AppCollectionName<TApp>> = AccessorRecord<\n\tAppCollections<TApp>[N]\n>\n\n/**\n * Hooks bound to one app type, returned by {@link createKoraHooks}.\n */\nexport interface KoraHooks<TApp> {\n\t/** The app from the nearest `<KoraProvider app={app}>`, typed as `TApp`. */\n\tuseApp: () => TApp\n\t/**\n\t * The typed accessor of one collection: `insert`, `update` and `where` are checked\n\t * against the schema. The accessor keeps its identity across renders.\n\t */\n\tuseCollection: <N extends AppCollectionName<TApp>>(name: N) => AppCollections<TApp>[N]\n\t/** {@link useQuery}: rows are typed from the query builder. */\n\tuseQuery: typeof useQuery\n\t/** {@link useQueryState}: rows are typed from the query builder. */\n\tuseQueryState: typeof useQueryState\n\t/** {@link useMutation}. */\n\tuseMutation: typeof useMutation\n\t/** {@link useSyncStatus}. */\n\tuseSyncStatus: typeof useSyncStatus\n}\n\n/**\n * Creates React hooks typed for one app, so components get schema-checked\n * collection names, inserts, updates and rows without passing generics around.\n * Call it once next to `createApp` and import the hooks from there. Nothing runs at\n * call time; the hooks read the app from `<KoraProvider app={app}>`.\n *\n * @returns {@link KoraHooks} for `TApp`\n *\n * @example\n * ```typescript\n * // kora.ts\n * export const app = createApp({ schema })\n * export const { useCollection, useQuery, useMutation } = createKoraHooks<typeof app>()\n *\n * // TodoList.tsx\n * const todos = useCollection('todos') // 'todoz' is a type error\n * const rows = useQuery(todos.where({ completed: false }))\n * const { mutate: add } = useMutation(todos.insert)\n * ```\n */\nexport function createKoraHooks<TApp extends KoraAppLike>(): KoraHooks<TApp> {\n\tfunction useTypedApp(): TApp {\n\t\treturn useApp<TApp>()\n\t}\n\n\tfunction useTypedCollection<N extends AppCollectionName<TApp>>(name: N): AppCollections<TApp>[N] {\n\t\tconst { app, store } = useKoraContext()\n\t\treturn useMemo(() => {\n\t\t\tconst collections = (app as { collections?: Record<string, unknown> } | null)?.collections\n\t\t\t// The app's `collections` getters build a fresh accessor on every read: read once\n\t\t\t// per (app, name) so the accessor and the functions on it stay stable.\n\t\t\tconst accessor: unknown =\n\t\t\t\tcollections && name in collections ? collections[name] : store.collection(name)\n\t\t\treturn accessor as AppCollections<TApp>[N]\n\t\t}, [app, store, name])\n\t}\n\n\treturn {\n\t\tuseApp: useTypedApp,\n\t\tuseCollection: useTypedCollection,\n\t\tuseQuery,\n\t\tuseQueryState,\n\t\tuseMutation,\n\t\tuseSyncStatus,\n\t}\n}\n","import { createMutationController } from '@korajs/core/bindings'\nimport type { MutationControllerState } from '@korajs/core/bindings'\nimport { useCallback, useMemo, useRef, useSyncExternalStore } from 'react'\nimport type { UseMutationOptions, UseMutationResult } from '../types'\nimport { useController } from './use-controller'\n\n// What a server render (and the hydration pass) shows: nothing is running.\nconst IDLE: MutationControllerState = Object.freeze({ isLoading: false, error: null })\nconst getServerSnapshot = (): MutationControllerState => IDLE\n\n/**\n * React hook for performing mutations against the local Kora store.\n *\n * `mutate`, `mutateAsync` and `reset` keep their identity for the component's lifetime\n * (safe in effect deps and as memoized props), and the result object only changes when\n * `isLoading` or `error` does. The latest `mutationFn` and `options` are always used.\n *\n * @param mutationFn - The mutation to run, for example `app.todos.insert`\n * @param options - Optional lifecycle callbacks (`onMutate`, `onSuccess`, `onError`, `onSettled`)\n * @returns `{ mutate, mutateAsync, isLoading, error, reset }`\n *\n * @example\n * ```tsx\n * const { mutate: addTodo, isLoading } = useMutation(app.todos.insert)\n * return <button disabled={isLoading} onClick={() => addTodo({ title: 'New' })}>Add</button>\n * ```\n */\nexport function useMutation<TData, TArgs extends unknown[], TContext = void>(\n\tmutationFn: (...args: TArgs) => Promise<TData>,\n\toptions?: UseMutationOptions<TData, TArgs, TContext>,\n): UseMutationResult<TData, TArgs> {\n\tconst fnRef = useRef(mutationFn)\n\tfnRef.current = mutationFn\n\n\tconst optionsRef = useRef(options)\n\toptionsRef.current = options\n\n\tconst controller = useController(\n\t\t() =>\n\t\t\tcreateMutationController<TData, TArgs, TContext>({\n\t\t\t\tmutationFn: (...args) => fnRef.current(...args),\n\t\t\t\tresolveOptions: () => optionsRef.current,\n\t\t\t}),\n\t\t(instance) => instance.destroy(),\n\t\t[],\n\t)\n\tconst getController = controller.get\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: version re-keys subscribe when the controller is replaced\n\tconst subscribe = useCallback(\n\t\t(onStoreChange: () => void) => getController().subscribe(onStoreChange),\n\t\t[getController, controller.version],\n\t)\n\tconst getSnapshot = useCallback(() => getController().getSnapshot(), [getController])\n\n\tconst state = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n\n\tconst mutate = useCallback((...args: TArgs) => getController().mutate(...args), [getController])\n\tconst mutateAsync = useCallback(\n\t\t(...args: TArgs) => getController().mutateAsync(...args),\n\t\t[getController],\n\t)\n\tconst reset = useCallback(() => getController().reset(), [getController])\n\n\treturn useMemo(\n\t\t() => ({ mutate, mutateAsync, isLoading: state.isLoading, error: state.error, reset }),\n\t\t[mutate, mutateAsync, reset, state.isLoading, state.error],\n\t)\n}\n","import { useEffect, useReducer, useRef } from 'react'\n\n/**\n * How long a controller created during a render may wait for its component to commit\n * before it is destroyed as an orphan. Reaping one that does commit later is safe (the\n * commit recreates it), so this only bounds how long a discarded render's controller\n * lives, never correctness.\n */\nconst ORPHAN_REAP_MS = 1000\n\ninterface ControllerEntry<C> {\n\tcontroller: C\n\t/** Set by the commit-phase effect: this component owns the controller. */\n\tclaimed: boolean\n\t/** Destroyed as an orphan before any commit claimed it. */\n\treaped: boolean\n}\n\n/**\n * A controller owned by a component, as returned by {@link useController}.\n */\nexport interface ControllerHandle<C> {\n\t/**\n\t * Returns the live controller, creating it if needed. Its identity never changes, so\n\t * callbacks built on it (mutate, undo, ...) can be memoized forever.\n\t */\n\tget: () => C\n\t/**\n\t * Returns the live controller, or null before the component committed. Never creates\n\t * one, so render paths that must not subscribe anything (a server render, a render\n\t * React may discard) read through it.\n\t */\n\tpeek: () => C | null\n\t/**\n\t * Increments every time the controller is replaced (deps change, or the StrictMode\n\t * remount recreated it). Key `useSyncExternalStore`'s `subscribe` on it so React\n\t * resubscribes to the new controller, and only then (DX-5).\n\t */\n\tversion: number\n}\n\n/**\n * Manages the lifecycle of an external controller in a StrictMode-safe way.\n *\n * React 18+ StrictMode mounts, unmounts, and remounts components in development, and\n * concurrent rendering may discard a render before it commits. The controller lives in\n * a ref, is (re)created by the commit-phase effect, and is destroyed by its cleanup. A\n * controller created lazily during a render that never commits (the discarded first\n * pass of a StrictMode mount, an interrupted transition) is destroyed as an orphan, so\n * its subscriptions do not leak.\n */\nexport function useController<C>(\n\tcreate: () => C,\n\tdestroy: (controller: C) => void,\n\tdeps: readonly unknown[],\n): ControllerHandle<C> {\n\tconst entryRef = useRef<ControllerEntry<C> | null>(null)\n\tconst createRef = useRef(create)\n\tcreateRef.current = create\n\tconst destroyRef = useRef(destroy)\n\tdestroyRef.current = destroy\n\n\tconst [version, bumpVersion] = useReducer((count: number) => count + 1, 0)\n\n\tconst handle = useRef<Omit<ControllerHandle<C>, 'version'>>({\n\t\tget: (): C => {\n\t\t\tconst current = entryRef.current\n\t\t\tif (current !== null && !current.reaped) {\n\t\t\t\treturn current.controller\n\t\t\t}\n\t\t\tconst entry: ControllerEntry<C> = {\n\t\t\t\tcontroller: createRef.current(),\n\t\t\t\tclaimed: false,\n\t\t\t\treaped: false,\n\t\t\t}\n\t\t\tentryRef.current = entry\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (!entry.claimed && !entry.reaped) {\n\t\t\t\t\tentry.reaped = true\n\t\t\t\t\tdestroyRef.current(entry.controller)\n\t\t\t\t}\n\t\t\t}, ORPHAN_REAP_MS)\n\t\t\treturn entry.controller\n\t\t},\n\t\tpeek: (): C | null => {\n\t\t\tconst current = entryRef.current\n\t\t\treturn current?.claimed && !current.reaped ? current.controller : null\n\t\t},\n\t}).current\n\n\t// Re-runs when the caller's create() inputs (deps) change.\n\tuseEffect(() => {\n\t\tconst current = entryRef.current\n\t\tif (current !== null && !current.reaped && !current.claimed) {\n\t\t\t// Created by this component's committed render: take ownership.\n\t\t\tcurrent.claimed = true\n\t\t} else if (current === null || current.reaped) {\n\t\t\tentryRef.current = { controller: createRef.current(), claimed: true, reaped: false }\n\t\t\t// A destroyed controller was recreated (StrictMode remount, deps change, or a\n\t\t\t// late commit after an orphan reap): re-render so bindings rebind to it.\n\t\t\tbumpVersion()\n\t\t}\n\t\treturn () => {\n\t\t\tconst entry = entryRef.current\n\t\t\tentryRef.current = null\n\t\t\tif (entry !== null && !entry.reaped) {\n\t\t\t\tentry.reaped = true\n\t\t\t\tdestroyRef.current(entry.controller)\n\t\t\t}\n\t\t}\n\t}, deps)\n\n\treturn { get: handle.get, peek: handle.peek, version }\n}\n","import type { SyncStatusInfo } from '@korajs/sync'\nimport { OFFLINE_SYNC_STATUS, createSyncStatusController } from '@korajs/sync'\nimport { useCallback, useSyncExternalStore } from 'react'\nimport { useKoraContext } from '../context/kora-context'\nimport { useController } from './use-controller'\n\nconst getServerSnapshot = (): SyncStatusInfo => OFFLINE_SYNC_STATUS\n\n/**\n * React hook for monitoring the sync engine's connection status.\n *\n * Re-renders only when the status payload changes. The returned object, and its nested\n * `heldNodes`, `initialSync` and `blockedFailure` values, keep their identity while\n * unchanged, so they are safe as effect or memo dependencies. Beyond `status` and\n * `pendingOperations` it reports `heldOperations` / `heldNodes` (writes of another\n * user waiting on this device), `localDurability` (`'degraded'` when the local\n * database cannot persist) and `serverProtocolVersion` / `protocolDeprecated`.\n *\n * @returns The current {@link SyncStatusInfo}\n *\n * @example\n * ```tsx\n * const { status, pendingOperations, localDurability } = useSyncStatus()\n * ```\n */\nexport function useSyncStatus(): SyncStatusInfo {\n\tconst { syncEngine, subscribeSyncStatus, events } = useKoraContext()\n\n\tconst controller = useController(\n\t\t() =>\n\t\t\tcreateSyncStatusController({\n\t\t\t\tsyncEngine,\n\t\t\t\tsubscribeSyncStatus,\n\t\t\t\tevents: subscribeSyncStatus ? null : events,\n\t\t\t}),\n\t\t(instance) => instance.destroy(),\n\t\t[syncEngine, subscribeSyncStatus, events],\n\t)\n\tconst getController = controller.get\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: version re-keys subscribe when the controller is replaced\n\tconst subscribe = useCallback(\n\t\t(onStoreChange: () => void) => getController().subscribe(onStoreChange),\n\t\t[getController, controller.version],\n\t)\n\t// Creating the controller subscribes to the engine, so a render never creates one:\n\t// until the component commits (and always on the server) the status is offline.\n\tconst peek = controller.peek\n\tconst getSnapshot = useCallback(\n\t\t(): SyncStatusInfo => peek()?.getSnapshot() ?? OFFLINE_SYNC_STATUS,\n\t\t[peek],\n\t)\n\n\treturn useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n}\n","import type { CollectionAccessor } from '@korajs/store'\nimport { useMemo } from 'react'\nimport { useKoraContext } from '../context/kora-context'\n\n/**\n * React hook that returns a CollectionAccessor for the given collection name.\n * Convenience hook for accessing a collection without going through the store directly.\n *\n * @param name - The collection name (must match a collection in the schema)\n * @returns CollectionAccessor with insert, findById, update, delete, and where methods\n *\n * @example\n * ```typescript\n * const todos = useCollection('todos')\n * await todos.insert({ title: 'New todo' })\n * ```\n */\nexport function useCollection(name: string): CollectionAccessor {\n\tconst { store } = useKoraContext()\n\n\treturn useMemo(() => {\n\t\treturn store.collection(name)\n\t}, [store, name])\n}\n","import { asRichTextSyncEngine, createRichTextController } from '@korajs/store'\nimport type { RichTextControllerSnapshot } from '@korajs/store'\nimport type { AwarenessUser } from '@korajs/sync'\nimport { useCallback, useEffect, useMemo, useSyncExternalStore } from 'react'\nimport { useKoraContext } from '../context/kora-context'\nimport type { UseRichTextResult } from '../types'\nimport { useController } from './use-controller'\n\nexport interface UseRichTextOptions {\n\tuser?: AwarenessUser\n\tuseDocChannel?: boolean\n}\n\n/**\n * Binds a richtext field to a shared Yjs document for editor integration.\n */\nexport function useRichText(\n\tcollectionName: string,\n\trecordId: string,\n\tfieldName: string,\n\toptions?: UseRichTextOptions,\n): UseRichTextResult {\n\tconst { store, syncEngine } = useKoraContext()\n\tconst collection = useMemo(() => store.collection(collectionName), [store, collectionName])\n\n\tconst controller = useController(\n\t\t() =>\n\t\t\tcreateRichTextController({\n\t\t\t\tcollection,\n\t\t\t\tcollectionName,\n\t\t\t\trecordId,\n\t\t\t\tfieldName,\n\t\t\t\tstore,\n\t\t\t\tsyncEngine: asRichTextSyncEngine(syncEngine),\n\t\t\t\tuseDocChannel: options?.useDocChannel,\n\t\t\t\tuser: options?.user,\n\t\t\t}),\n\t\t(instance) => instance.destroy(),\n\t\t[collection, collectionName, fieldName, options?.useDocChannel, recordId, store, syncEngine],\n\t)\n\tconst getController = controller.get\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: a replaced controller (version) needs the user again\n\tuseEffect(() => {\n\t\tgetController().setUser(options?.user)\n\t}, [getController, options?.user, controller.version])\n\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: version re-keys subscribe when the controller is replaced\n\tconst subscribe = useCallback(\n\t\t(onStoreChange: () => void) => getController().subscribe(onStoreChange),\n\t\t[getController, controller.version],\n\t)\n\tconst getSnapshot = useCallback(() => getController().getSnapshot(), [getController])\n\tconst snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot)\n\n\tconst undo = useCallback(() => {\n\t\tgetController().undo()\n\t}, [getController])\n\tconst redo = useCallback(() => {\n\t\tgetController().redo()\n\t}, [getController])\n\tconst setCursor = useCallback(\n\t\t(anchor: number, head: number) => getController().setCursor(anchor, head),\n\t\t[getController],\n\t)\n\tconst clearCursor = useCallback(() => getController().clearCursor(), [getController])\n\n\tconst live = getController()\n\t// The result keeps its identity until the snapshot or the controller changes (DX-5).\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: version marks a replaced controller\n\treturn useMemo(\n\t\t() => buildResult(live, snapshot, undo, redo, setCursor, clearCursor),\n\t\t[live, snapshot, undo, redo, setCursor, clearCursor, controller.version],\n\t)\n}\n\nfunction buildResult(\n\tcontroller: ReturnType<typeof createRichTextController>,\n\tsnapshot: RichTextControllerSnapshot,\n\tundo: () => void,\n\tredo: () => void,\n\tsetCursor: (anchor: number, head: number) => void,\n\tclearCursor: () => void,\n): UseRichTextResult {\n\treturn {\n\t\tdoc: controller.doc,\n\t\ttext: controller.text,\n\t\tundo,\n\t\tredo,\n\t\tcanUndo: snapshot.canUndo,\n\t\tcanRedo: snapshot.canRedo,\n\t\tready: snapshot.ready,\n\t\terror: snapshot.error,\n\t\tcursors: [...snapshot.cursors],\n\t\tsetCursor,\n\t\tclearCursor,\n\t}\n}\n","import { useEffect } from 'react'\nimport { useKoraContext } from '../context/kora-context'\n\n/**\n * Sets the local user's collaborative presence state.\n *\n * Automatically cleans up presence on unmount.\n */\nexport function usePresence(user: { name: string; color: string; avatar?: string } | null): void {\n\tconst { syncEngine } = useKoraContext()\n\tconst name = user?.name ?? null\n\tconst color = user?.color ?? null\n\tconst avatar = user?.avatar ?? null\n\n\tuseEffect(() => {\n\t\tif (!syncEngine || !name || !color) return\n\n\t\tconst awareness = syncEngine.getAwarenessManager()\n\t\tawareness.setLocalState({\n\t\t\tuser: { name, color, avatar: avatar ?? undefined },\n\t\t})\n\n\t\treturn () => {\n\t\t\tawareness.setLocalState(null)\n\t\t}\n\t}, [syncEngine, name, color, avatar])\n}\n","import type { AwarenessState } from '@korajs/sync'\nimport { subscribeRemoteAwarenessStates } from '@korajs/sync'\nimport { useCallback, useEffect, useRef, useSyncExternalStore } from 'react'\nimport { useKoraContext } from '../context/kora-context'\n\nconst EMPTY_ARRAY: AwarenessState[] = []\n\n// Server renders (and the hydration pass) have no peers: one shared empty list.\nconst getServerSnapshot = (): AwarenessState[] => EMPTY_ARRAY\n\n/**\n * Returns all currently connected collaborators' awareness states.\n *\n * Excludes the local user — only returns remote peers. Safe under server rendering\n * (`renderToString`, Next.js App Router): the server and the hydration pass see `[]`.\n *\n * @returns The remote peers' awareness states; the same array until they change\n */\nexport function useCollaborators(): AwarenessState[] {\n\tconst { syncEngine } = useKoraContext()\n\n\tconst snapshotRef = useRef<AwarenessState[]>(EMPTY_ARRAY)\n\n\tconst subscribe = useCallback(\n\t\t(onStoreChange: () => void): (() => void) => {\n\t\t\tif (!syncEngine) {\n\t\t\t\tsnapshotRef.current = EMPTY_ARRAY\n\t\t\t\treturn () => {}\n\t\t\t}\n\n\t\t\tconst awareness = syncEngine.getAwarenessManager()\n\t\t\t// A fresh subscription starts from empty and emits the current peers at once, so a\n\t\t\t// resubscribe (StrictMode remount, engine swap) never keeps a stale list.\n\t\t\tsnapshotRef.current = EMPTY_ARRAY\n\t\t\treturn subscribeRemoteAwarenessStates(awareness, (states) => {\n\t\t\t\tsnapshotRef.current = states\n\t\t\t\tonStoreChange()\n\t\t\t})\n\t\t},\n\t\t[syncEngine],\n\t)\n\n\tconst getSnapshot = useCallback((): AwarenessState[] => snapshotRef.current, [])\n\n\tuseEffect(() => {\n\t\tif (!syncEngine) {\n\t\t\tsnapshotRef.current = EMPTY_ARRAY\n\t\t}\n\t}, [syncEngine])\n\n\treturn useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n}\n"],"mappings":"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","names":["createElement","useEffect","useRef","useState","useState","useRef","useEffect","createElement","useEffect","useMemo","useRef","useState","useRef","useState","useEffect","useMemo","useMemo","useCallback","useMemo","useRef","useSyncExternalStore","useEffect","useRef","getServerSnapshot","useRef","useCallback","useSyncExternalStore","useMemo","useCallback","useSyncExternalStore","getServerSnapshot","useCallback","useSyncExternalStore","useMemo","useMemo","useMemo","useCallback","useEffect","useMemo","useSyncExternalStore","useMemo","useEffect","useCallback","useSyncExternalStore","useEffect","useEffect","useCallback","useEffect","useRef","useSyncExternalStore","EMPTY_ARRAY","getServerSnapshot","useRef","useCallback","useEffect","useSyncExternalStore"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@korajs/react",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.13",
|
|
4
4
|
"description": "Kora.js React hooks and bindings for offline-first applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"yjs": "^13.6.30",
|
|
35
|
-
"@korajs/core": "1.0.0-beta.
|
|
36
|
-
"@korajs/
|
|
37
|
-
"@korajs/
|
|
35
|
+
"@korajs/core": "1.0.0-beta.13",
|
|
36
|
+
"@korajs/store": "1.0.0-beta.13",
|
|
37
|
+
"@korajs/sync": "1.0.0-beta.13"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@testing-library/jest-dom": "^6.0.0",
|