@korajs/vue 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,26 +1,434 @@
1
1
  // src/index.ts
2
+ import { KoraError as KoraError2 } from "@korajs/core";
3
+ import { inject as inject2 } from "vue";
4
+
5
+ // src/context.ts
2
6
  import { KoraError } from "@korajs/core";
3
7
  import { inject } from "vue";
8
+ var koraContextKey = /* @__PURE__ */ Symbol("korajs-context");
4
9
  var koraAppInjectionKey = /* @__PURE__ */ Symbol("korajs-app");
10
+ function useKoraContext() {
11
+ const contextRef = inject(koraContextKey);
12
+ if (!contextRef?.value) {
13
+ throw new KoraError(
14
+ "useKoraContext() requires <KoraProvider>. Wrap your app root with KoraProvider.",
15
+ "KORA_NOT_PROVIDED",
16
+ { fix: '<KoraProvider :app="app"><App /></KoraProvider>' }
17
+ );
18
+ }
19
+ return contextRef.value;
20
+ }
21
+
22
+ // src/components/kora-provider.ts
23
+ import { QueryStoreCache as QueryStoreCache2 } from "@korajs/store";
24
+ import {
25
+ defineComponent,
26
+ h,
27
+ onScopeDispose,
28
+ provide,
29
+ ref,
30
+ shallowRef,
31
+ watch
32
+ } from "vue";
33
+
34
+ // src/resolve-query-store-cache.ts
35
+ import "@korajs/store";
36
+ function resolveQueryStoreCache(app, fallback) {
37
+ if (app && typeof app.getQueryStoreCache === "function") {
38
+ return app.getQueryStoreCache();
39
+ }
40
+ return fallback;
41
+ }
42
+
43
+ // src/components/kora-provider.ts
44
+ var KoraProvider = defineComponent({
45
+ name: "KoraProvider",
46
+ props: {
47
+ app: {
48
+ type: Object,
49
+ default: void 0
50
+ },
51
+ store: {
52
+ type: Object,
53
+ default: void 0
54
+ },
55
+ syncEngine: {
56
+ type: Object,
57
+ default: void 0
58
+ },
59
+ fallback: {
60
+ type: [Object, String],
61
+ default: null
62
+ }
63
+ },
64
+ setup(props, { slots }) {
65
+ const resolvedStore = ref(null);
66
+ const resolvedSync = ref(null);
67
+ const ready = ref(!props.app && Boolean(props.store));
68
+ const initError = ref(null);
69
+ const fallbackQueryStoreCache = new QueryStoreCache2();
70
+ const contextRef = shallowRef(null);
71
+ provide(koraContextKey, contextRef);
72
+ if (props.app) {
73
+ provide(koraAppInjectionKey, props.app);
74
+ }
75
+ watch(
76
+ () => props.app,
77
+ (app, _previous, onCleanup) => {
78
+ if (!app) {
79
+ if (props.store) {
80
+ resolvedStore.value = props.store;
81
+ resolvedSync.value = props.syncEngine ?? null;
82
+ ready.value = true;
83
+ }
84
+ return;
85
+ }
86
+ ready.value = false;
87
+ initError.value = null;
88
+ let cancelled = false;
89
+ app.ready.then(() => {
90
+ if (cancelled) return;
91
+ resolvedStore.value = app.getStore();
92
+ resolvedSync.value = app.getSyncEngine();
93
+ ready.value = true;
94
+ }).catch((error) => {
95
+ if (cancelled) return;
96
+ const err = error instanceof Error ? error : new Error(String(error));
97
+ console.error("[Kora] Initialization failed:", err);
98
+ initError.value = err;
99
+ });
100
+ onCleanup(() => {
101
+ cancelled = true;
102
+ });
103
+ },
104
+ { immediate: true }
105
+ );
106
+ watch(
107
+ () => props.store,
108
+ (store) => {
109
+ if (store && !props.app) {
110
+ resolvedStore.value = store;
111
+ resolvedSync.value = props.syncEngine ?? null;
112
+ ready.value = true;
113
+ }
114
+ },
115
+ { immediate: true }
116
+ );
117
+ watch(
118
+ () => [resolvedStore.value, resolvedSync.value, props.app],
119
+ ([store, syncEngine, app]) => {
120
+ if (!store) {
121
+ contextRef.value = null;
122
+ return;
123
+ }
124
+ contextRef.value = {
125
+ store,
126
+ syncEngine: syncEngine ?? null,
127
+ app: app ?? null,
128
+ events: app?.events ?? null,
129
+ subscribeSyncStatus: app?.sync?.subscribeStatus ?? null,
130
+ queryStoreCache: resolveQueryStoreCache(app, fallbackQueryStoreCache)
131
+ };
132
+ },
133
+ { immediate: true }
134
+ );
135
+ onScopeDispose(() => {
136
+ if (!props.app) {
137
+ fallbackQueryStoreCache.clear();
138
+ }
139
+ });
140
+ return () => {
141
+ if (initError.value) {
142
+ return h(
143
+ "div",
144
+ { style: { color: "red", padding: "1rem", fontFamily: "monospace" } },
145
+ [h("strong", null, "Kora initialization error: "), initError.value.message]
146
+ );
147
+ }
148
+ if (!ready.value) {
149
+ return props.fallback ?? null;
150
+ }
151
+ if (!resolvedStore.value) {
152
+ throw new Error(
153
+ 'KoraProvider requires either an "app" or "store" prop. Pass createApp() or a Store instance.'
154
+ );
155
+ }
156
+ return slots.default?.();
157
+ };
158
+ }
159
+ });
160
+
161
+ // src/composables/use-query.ts
162
+ import { assertQueryReady } from "@korajs/store";
163
+ import { readonly, shallowRef as shallowRef2, watch as watch2 } from "vue";
164
+ var EMPTY_ARRAY = Object.freeze([]);
165
+ function useQuery(query, options) {
166
+ const { queryStoreCache } = useKoraContext();
167
+ const enabled = options?.enabled !== false;
168
+ const snapshot = shallowRef2(EMPTY_ARRAY);
169
+ watch2(
170
+ () => enabled ? JSON.stringify(query.getDescriptor()) : null,
171
+ (key, _previous, onCleanup) => {
172
+ if (!key) {
173
+ snapshot.value = EMPTY_ARRAY;
174
+ return;
175
+ }
176
+ assertQueryReady(query);
177
+ const queryStore = queryStoreCache.getOrCreate(query);
178
+ const unsubscribe = queryStore.subscribe(() => {
179
+ snapshot.value = queryStore.getSnapshot();
180
+ });
181
+ snapshot.value = queryStore.getSnapshot();
182
+ onCleanup(() => {
183
+ unsubscribe();
184
+ queryStoreCache.release(query);
185
+ });
186
+ },
187
+ { immediate: true }
188
+ );
189
+ return readonly(snapshot);
190
+ }
191
+
192
+ // src/composables/use-mutation.ts
193
+ import { createMutationController } from "@korajs/core/bindings";
194
+ import { onScopeDispose as onScopeDispose2, ref as ref2, shallowReadonly } from "vue";
195
+ function useMutation(mutationFn, options) {
196
+ const fnRef = { current: mutationFn };
197
+ fnRef.current = mutationFn;
198
+ const optionsRef = { current: options };
199
+ optionsRef.current = options;
200
+ const isLoading = ref2(false);
201
+ const error = ref2(null);
202
+ let mounted = true;
203
+ onScopeDispose2(() => {
204
+ mounted = false;
205
+ });
206
+ const controller = createMutationController({
207
+ mutationFn: (...args) => fnRef.current(...args),
208
+ resolveOptions: () => optionsRef.current,
209
+ onStateChange: (state) => {
210
+ if (!mounted) return;
211
+ isLoading.value = state.isLoading;
212
+ error.value = state.error;
213
+ }
214
+ });
215
+ isLoading.value = controller.getSnapshot().isLoading;
216
+ error.value = controller.getSnapshot().error;
217
+ onScopeDispose2(() => {
218
+ controller.destroy();
219
+ });
220
+ return {
221
+ mutate: (...args) => controller.mutate(...args),
222
+ mutateAsync: (...args) => controller.mutateAsync(...args),
223
+ isLoading: shallowReadonly(isLoading),
224
+ error: shallowReadonly(error),
225
+ reset: () => controller.reset()
226
+ };
227
+ }
228
+
229
+ // src/composables/use-sync-status.ts
230
+ import { OFFLINE_SYNC_STATUS, createSyncStatusController } from "@korajs/sync";
231
+ import { readonly as readonly2, shallowRef as shallowRef3, watchEffect } from "vue";
232
+ function useSyncStatus() {
233
+ const { syncEngine, subscribeSyncStatus, events } = useKoraContext();
234
+ const status = shallowRef3(OFFLINE_SYNC_STATUS);
235
+ watchEffect((onCleanup) => {
236
+ const controller = createSyncStatusController({
237
+ syncEngine,
238
+ subscribeSyncStatus,
239
+ events: subscribeSyncStatus ? null : events
240
+ });
241
+ status.value = controller.getSnapshot();
242
+ const unsubscribe = controller.subscribe(() => {
243
+ status.value = controller.getSnapshot();
244
+ });
245
+ onCleanup(() => {
246
+ unsubscribe();
247
+ controller.destroy();
248
+ });
249
+ });
250
+ return readonly2(status);
251
+ }
252
+
253
+ // src/composables/use-app.ts
254
+ function useApp() {
255
+ const { app } = useKoraContext();
256
+ if (!app) {
257
+ throw new Error(
258
+ 'useApp() requires <KoraProvider :app="app">. Pass your createApp() result to the provider.'
259
+ );
260
+ }
261
+ return app;
262
+ }
263
+
264
+ // src/composables/use-collection.ts
265
+ function useCollection(name) {
266
+ const { store } = useKoraContext();
267
+ return store.collection(name);
268
+ }
269
+
270
+ // src/composables/use-rich-text.ts
271
+ import { asRichTextSyncEngine, createRichTextController } from "@korajs/store";
272
+ import { reactive, shallowRef as shallowRef4, watch as watch3 } from "vue";
273
+ function useRichText(collectionName, recordId, fieldName, options) {
274
+ const { store, syncEngine } = useKoraContext();
275
+ const controllerRef = shallowRef4(null);
276
+ const state = reactive({
277
+ ready: false,
278
+ error: null,
279
+ canUndo: false,
280
+ canRedo: false,
281
+ cursors: []
282
+ });
283
+ watch3(
284
+ () => [collectionName, recordId, fieldName, options?.useDocChannel],
285
+ ([name, id, field, useDocChannel], _previous, onCleanup) => {
286
+ controllerRef.value?.destroy();
287
+ const controller2 = createRichTextController({
288
+ collection: store.collection(name),
289
+ collectionName: name,
290
+ recordId: id,
291
+ fieldName: field,
292
+ store,
293
+ syncEngine: asRichTextSyncEngine(syncEngine),
294
+ useDocChannel,
295
+ user: options?.user
296
+ });
297
+ const syncState = () => {
298
+ const snapshot = controller2.getSnapshot();
299
+ state.ready = snapshot.ready;
300
+ state.error = snapshot.error;
301
+ state.canUndo = snapshot.canUndo;
302
+ state.canRedo = snapshot.canRedo;
303
+ state.cursors = [...snapshot.cursors];
304
+ };
305
+ syncState();
306
+ const unsubscribe = controller2.subscribe(syncState);
307
+ controllerRef.value = controller2;
308
+ onCleanup(() => {
309
+ unsubscribe();
310
+ controller2.destroy();
311
+ if (controllerRef.value === controller2) {
312
+ controllerRef.value = null;
313
+ }
314
+ });
315
+ },
316
+ { immediate: true }
317
+ );
318
+ watch3(
319
+ () => options?.user,
320
+ (user) => {
321
+ controllerRef.value?.setUser(user);
322
+ }
323
+ );
324
+ const controller = () => {
325
+ if (!controllerRef.value) {
326
+ throw new Error("useRichText controller is not initialized");
327
+ }
328
+ return controllerRef.value;
329
+ };
330
+ return {
331
+ get doc() {
332
+ return controller().doc;
333
+ },
334
+ get text() {
335
+ return controller().text;
336
+ },
337
+ undo: () => controller().undo(),
338
+ redo: () => controller().redo(),
339
+ get ready() {
340
+ return state.ready;
341
+ },
342
+ get error() {
343
+ return state.error;
344
+ },
345
+ get canUndo() {
346
+ return state.canUndo;
347
+ },
348
+ get canRedo() {
349
+ return state.canRedo;
350
+ },
351
+ get cursors() {
352
+ return state.cursors;
353
+ },
354
+ setCursor: (anchor, head) => controller().setCursor(anchor, head),
355
+ clearCursor: () => controller().clearCursor()
356
+ };
357
+ }
358
+
359
+ // src/composables/use-presence.ts
360
+ import { subscribeRemoteAwarenessStates } from "@korajs/sync";
361
+ import { onScopeDispose as onScopeDispose4, shallowRef as shallowRef5, watch as watch4, watchEffect as watchEffect2 } from "vue";
362
+ function usePresence(user) {
363
+ const { syncEngine } = useKoraContext();
364
+ watch4(
365
+ () => [syncEngine, user?.name, user?.color, user?.avatar],
366
+ ([engine, name, color, avatar], _prev, onCleanup) => {
367
+ if (!engine || !name || !color) return;
368
+ const awareness = engine.getAwarenessManager();
369
+ awareness.setLocalState({
370
+ user: {
371
+ name,
372
+ color,
373
+ avatar
374
+ }
375
+ });
376
+ onCleanup(() => {
377
+ awareness.setLocalState(null);
378
+ });
379
+ },
380
+ { immediate: true }
381
+ );
382
+ }
383
+ function useCollaborators() {
384
+ const { syncEngine } = useKoraContext();
385
+ const collaborators = shallowRef5([]);
386
+ watchEffect2((onCleanup) => {
387
+ if (!syncEngine) {
388
+ collaborators.value = [];
389
+ return;
390
+ }
391
+ const awareness = syncEngine.getAwarenessManager();
392
+ const unsubscribe = subscribeRemoteAwarenessStates(awareness, (states) => {
393
+ collaborators.value = states;
394
+ });
395
+ onCleanup(unsubscribe);
396
+ });
397
+ onScopeDispose4(() => {
398
+ collaborators.value = [];
399
+ });
400
+ return collaborators;
401
+ }
402
+
403
+ // src/index.ts
5
404
  function installKora(vueApp, koraApp) {
6
405
  vueApp.provide(koraAppInjectionKey, koraApp);
7
406
  }
8
407
  function useKoraApp() {
9
- const app = inject(koraAppInjectionKey);
408
+ const app = inject2(koraAppInjectionKey);
10
409
  if (!app) {
11
- throw new KoraError(
12
- "useKoraApp() requires installKora(vueApp, koraApp) on the Vue application.",
410
+ throw new KoraError2(
411
+ 'useKoraApp() requires installKora(vueApp, koraApp) or <KoraProvider :app="app">.',
13
412
  "KORA_NOT_PROVIDED",
14
- {
15
- fix: "In main.ts: const kora = createApp({ schema }); installKora(vueApp, kora); await kora.ready"
16
- }
413
+ { fix: 'Use <KoraProvider :app="app"> and useApp() for full bindings.' }
17
414
  );
18
415
  }
19
416
  return app;
20
417
  }
21
418
  export {
419
+ KoraProvider,
22
420
  installKora,
23
421
  koraAppInjectionKey,
24
- useKoraApp
422
+ koraContextKey,
423
+ useApp,
424
+ useCollaborators,
425
+ useCollection,
426
+ useKoraApp,
427
+ useKoraContext,
428
+ useMutation,
429
+ usePresence,
430
+ useQuery,
431
+ useRichText,
432
+ useSyncStatus
25
433
  };
26
434
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { KoraError } from '@korajs/core'\nimport { type App, type InjectionKey, inject } from 'vue'\nimport type { KoraAppHandle } from './types'\n\nexport type { KoraAppHandle } from './types'\n\n/** Vue injection key for the root Kora app instance. */\nexport const koraAppInjectionKey: InjectionKey<KoraAppHandle> = Symbol('korajs-app')\n\n/**\n * Register a Kora app on a Vue application instance.\n * Call once after `createApp()` from korajs, typically in `main.ts`.\n */\nexport function installKora(vueApp: App, koraApp: KoraAppHandle): void {\n\tvueApp.provide(koraAppInjectionKey, koraApp)\n}\n\n/**\n * Access the Kora app from a component setup function.\n * Pair with {@link installKora} and `app.ready` before running queries.\n */\nexport function useKoraApp(): KoraAppHandle {\n\tconst app = inject(koraAppInjectionKey)\n\tif (!app) {\n\t\tthrow new KoraError(\n\t\t\t'useKoraApp() requires installKora(vueApp, koraApp) on the Vue application.',\n\t\t\t'KORA_NOT_PROVIDED',\n\t\t\t{\n\t\t\t\tfix: 'In main.ts: const kora = createApp({ schema }); installKora(vueApp, kora); await kora.ready',\n\t\t\t},\n\t\t)\n\t}\n\treturn app\n}\n"],"mappings":";AAAA,SAAS,iBAAiB;AAC1B,SAAsC,cAAc;AAM7C,IAAM,sBAAmD,uBAAO,YAAY;AAM5E,SAAS,YAAY,QAAa,SAA8B;AACtE,SAAO,QAAQ,qBAAqB,OAAO;AAC5C;AAMO,SAAS,aAA4B;AAC3C,QAAM,MAAM,OAAO,mBAAmB;AACtC,MAAI,CAAC,KAAK;AACT,UAAM,IAAI;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,QACC,KAAK;AAAA,MACN;AAAA,IACD;AAAA,EACD;AACA,SAAO;AACR;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/context.ts","../src/components/kora-provider.ts","../src/resolve-query-store-cache.ts","../src/composables/use-query.ts","../src/composables/use-mutation.ts","../src/composables/use-sync-status.ts","../src/composables/use-app.ts","../src/composables/use-collection.ts","../src/composables/use-rich-text.ts","../src/composables/use-presence.ts"],"sourcesContent":["import { KoraError } from '@korajs/core'\nimport { type App, inject } from 'vue'\nimport { koraAppInjectionKey } from './context'\nimport type { KoraAppLike } from './types'\n\nexport type { KoraAppHandle, KoraAppLike, KoraContextValue, KoraProviderProps } from './types'\nexport type { UseMutationOptions, UseMutationResult, UseQueryOptions, UseRichTextResult } from './types'\n\nexport { koraAppInjectionKey, koraContextKey, useKoraContext } from './context'\nexport { KoraProvider } from './components/kora-provider'\nexport { useQuery } from './composables/use-query'\nexport { useMutation } from './composables/use-mutation'\nexport { useSyncStatus } from './composables/use-sync-status'\nexport { useApp } from './composables/use-app'\nexport { useCollection } from './composables/use-collection'\nexport { useRichText } from './composables/use-rich-text'\nexport type { UseRichTextOptions } from './composables/use-rich-text'\nexport { usePresence, useCollaborators } from './composables/use-presence'\n\n/**\n * Register a Kora app on a Vue application instance.\n *\n * @deprecated Prefer {@link KoraProvider} — `installKora` does not provide reactive\n * hook context (`useQuery`, `useSyncStatus`, etc.) until you migrate to `KoraProvider`.\n */\nexport function installKora(vueApp: App, koraApp: KoraAppLike): void {\n\tvueApp.provide(koraAppInjectionKey, koraApp)\n}\n\n/**\n * Access the Kora app from a component when using {@link installKora} only.\n * For reactive hooks, use {@link useApp} inside {@link KoraProvider}.\n */\nexport function useKoraApp(): KoraAppLike {\n\tconst app = inject(koraAppInjectionKey)\n\tif (!app) {\n\t\tthrow new KoraError(\n\t\t\t'useKoraApp() requires installKora(vueApp, koraApp) or <KoraProvider :app=\"app\">.',\n\t\t\t'KORA_NOT_PROVIDED',\n\t\t\t{ fix: 'Use <KoraProvider :app=\"app\"> and useApp() for full bindings.' },\n\t\t)\n\t}\n\treturn app\n}\n","import { KoraError } from '@korajs/core'\nimport { type InjectionKey, inject, type ShallowRef } from 'vue'\nimport type { KoraAppLike, KoraContextValue } from './types'\n\nexport const koraContextKey: InjectionKey<ShallowRef<KoraContextValue | null>> =\n\tSymbol('korajs-context')\n\n/** @deprecated Use {@link koraContextKey} with {@link KoraProvider}. */\nexport const koraAppInjectionKey: InjectionKey<KoraAppLike> = Symbol('korajs-app')\n\nexport function useKoraContext(): KoraContextValue {\n\tconst contextRef = inject(koraContextKey)\n\tif (!contextRef?.value) {\n\t\tthrow new KoraError(\n\t\t\t'useKoraContext() requires <KoraProvider>. Wrap your app root with KoraProvider.',\n\t\t\t'KORA_NOT_PROVIDED',\n\t\t\t{ fix: '<KoraProvider :app=\"app\"><App /></KoraProvider>' },\n\t\t)\n\t}\n\treturn contextRef.value\n}\n","import { QueryStoreCache } from '@korajs/store'\nimport type { Store } from '@korajs/store'\nimport type { SyncEngine } from '@korajs/sync'\nimport {\n\ttype PropType,\n\ttype VNode,\n\tdefineComponent,\n\th,\n\tonScopeDispose,\n\tprovide,\n\tref,\n\tshallowRef,\n\twatch,\n} from 'vue'\nimport { koraContextKey, koraAppInjectionKey } from '../context'\nimport type { KoraAppLike, KoraContextValue } from '../types'\nimport { resolveQueryStoreCache } from '../resolve-query-store-cache'\n\nexport const KoraProvider = defineComponent({\n\tname: 'KoraProvider',\n\tprops: {\n\t\tapp: {\n\t\t\ttype: Object as PropType<KoraAppLike>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tstore: {\n\t\t\ttype: Object as PropType<Store>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tsyncEngine: {\n\t\t\ttype: Object as PropType<SyncEngine | null>,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tfallback: {\n\t\t\ttype: [Object, String] as PropType<VNode | string | null>,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\tsetup(props, { slots }) {\n\t\tconst resolvedStore = ref<Store | null>(null)\n\t\tconst resolvedSync = ref<SyncEngine | null>(null)\n\t\tconst ready = ref(!props.app && Boolean(props.store))\n\t\tconst initError = ref<Error | null>(null)\n\t\tconst fallbackQueryStoreCache = new QueryStoreCache()\n\t\tconst contextRef = shallowRef<KoraContextValue | null>(null)\n\n\t\tprovide(koraContextKey, contextRef)\n\t\tif (props.app) {\n\t\t\tprovide(koraAppInjectionKey, props.app)\n\t\t}\n\n\t\twatch(\n\t\t\t() => props.app,\n\t\t\t(app, _previous, onCleanup) => {\n\t\t\t\tif (!app) {\n\t\t\t\t\tif (props.store) {\n\t\t\t\t\t\tresolvedStore.value = props.store as Store\n\t\t\t\t\t\tresolvedSync.value = (props.syncEngine ?? null) as SyncEngine | null\n\t\t\t\t\t\tready.value = true\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tready.value = false\n\t\t\t\tinitError.value = null\n\t\t\t\tlet cancelled = false\n\n\t\t\t\tapp.ready\n\t\t\t\t\t.then(() => {\n\t\t\t\t\t\tif (cancelled) return\n\t\t\t\t\t\tresolvedStore.value = app.getStore() as Store\n\t\t\t\t\t\tresolvedSync.value = app.getSyncEngine() as SyncEngine | null\n\t\t\t\t\t\tready.value = true\n\t\t\t\t\t})\n\t\t\t\t\t.catch((error: unknown) => {\n\t\t\t\t\t\tif (cancelled) return\n\t\t\t\t\t\tconst err = error instanceof Error ? error : new Error(String(error))\n\t\t\t\t\t\tconsole.error('[Kora] Initialization failed:', err)\n\t\t\t\t\t\tinitError.value = err\n\t\t\t\t\t})\n\n\t\t\t\tonCleanup(() => {\n\t\t\t\t\tcancelled = true\n\t\t\t\t})\n\t\t\t},\n\t\t\t{ immediate: true },\n\t\t)\n\n\t\twatch(\n\t\t\t() => props.store,\n\t\t\t(store) => {\n\t\t\t\tif (store && !props.app) {\n\t\t\t\t\tresolvedStore.value = store as Store\n\t\t\t\t\tresolvedSync.value = (props.syncEngine ?? null) as SyncEngine | null\n\t\t\t\t\tready.value = true\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ immediate: true },\n\t\t)\n\n\t\twatch(\n\t\t\t() => [resolvedStore.value, resolvedSync.value, props.app] as const,\n\t\t\t([store, syncEngine, app]) => {\n\t\t\t\tif (!store) {\n\t\t\t\t\tcontextRef.value = null\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tcontextRef.value = {\n\t\t\t\t\tstore: store as Store,\n\t\t\t\t\tsyncEngine: (syncEngine ?? null) as SyncEngine | null,\n\t\t\t\t\tapp: app ?? null,\n\t\t\t\t\tevents: app?.events ?? null,\n\t\t\t\t\tsubscribeSyncStatus: app?.sync?.subscribeStatus ?? null,\n\t\t\t\t\tqueryStoreCache: resolveQueryStoreCache(app, fallbackQueryStoreCache),\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ immediate: true },\n\t\t)\n\n\t\tonScopeDispose(() => {\n\t\t\tif (!props.app) {\n\t\t\t\tfallbackQueryStoreCache.clear()\n\t\t\t}\n\t\t})\n\n\t\treturn () => {\n\t\t\tif (initError.value) {\n\t\t\t\treturn h(\n\t\t\t\t\t'div',\n\t\t\t\t\t{ style: { color: 'red', padding: '1rem', fontFamily: 'monospace' } },\n\t\t\t\t\t[h('strong', null, 'Kora initialization error: '), initError.value.message],\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (!ready.value) {\n\t\t\t\treturn props.fallback ?? null\n\t\t\t}\n\n\t\t\tif (!resolvedStore.value) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'KoraProvider requires either an \"app\" or \"store\" prop. Pass createApp() or a Store instance.',\n\t\t\t\t)\n\t\t\t}\n\n\t\t\treturn slots.default?.()\n\t\t}\n\t},\n})\n","import { QueryStoreCache } from '@korajs/store'\nimport type { KoraAppLike } from '../types'\n\n/**\n * Resolves the per-app query cache when available, otherwise a provider-local fallback.\n */\nexport function resolveQueryStoreCache(\n\tapp: KoraAppLike | null | undefined,\n\tfallback: QueryStoreCache,\n): QueryStoreCache {\n\tif (app && typeof app.getQueryStoreCache === 'function') {\n\t\treturn app.getQueryStoreCache()\n\t}\n\treturn fallback\n}\n","import type { CollectionRecord, QueryBuilder } from '@korajs/store'\nimport { assertQueryReady } from '@korajs/store'\nimport { type DeepReadonly, readonly, shallowRef, watch } from 'vue'\nimport { useKoraContext } from '../context'\nimport type { UseQueryOptions } from '../types'\n\nconst EMPTY_ARRAY: readonly unknown[] = Object.freeze([])\n\n/**\n * Reactive query composable backed by the local Kora store.\n */\nexport function useQuery<T = CollectionRecord>(\n\tquery: QueryBuilder<T>,\n\toptions?: UseQueryOptions,\n): DeepReadonly<ReturnType<typeof shallowRef<readonly T[]>>> {\n\tconst { queryStoreCache } = useKoraContext()\n\tconst enabled = options?.enabled !== false\n\tconst snapshot = shallowRef<readonly T[]>(EMPTY_ARRAY as readonly T[])\n\n\twatch(\n\t\t() => (enabled ? JSON.stringify(query.getDescriptor()) : null),\n\t\t(key, _previous, onCleanup) => {\n\t\t\tif (!key) {\n\t\t\t\tsnapshot.value = EMPTY_ARRAY as readonly T[]\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tassertQueryReady(query as QueryBuilder<unknown>)\n\t\t\tconst queryStore = queryStoreCache.getOrCreate(query)\n\t\t\tconst unsubscribe = queryStore.subscribe(() => {\n\t\t\t\tsnapshot.value = queryStore.getSnapshot()\n\t\t\t})\n\t\t\tsnapshot.value = queryStore.getSnapshot()\n\n\t\t\tonCleanup(() => {\n\t\t\t\tunsubscribe()\n\t\t\t\tqueryStoreCache.release(query as QueryBuilder<unknown>)\n\t\t\t})\n\t\t},\n\t\t{ immediate: true },\n\t)\n\n\treturn readonly(snapshot)\n}\n","import { createMutationController } from '@korajs/core/bindings'\nimport { onScopeDispose, ref, shallowReadonly } from 'vue'\nimport type { UseMutationOptions, UseMutationResult } from '../types'\n\n/**\n * Mutation composable with optional optimistic update and rollback hooks.\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 = { current: mutationFn }\n\tfnRef.current = mutationFn\n\n\tconst optionsRef = { current: options }\n\toptionsRef.current = options\n\n\tconst isLoading = ref(false)\n\tconst error = ref<Error | null>(null)\n\tlet mounted = true\n\n\tonScopeDispose(() => {\n\t\tmounted = false\n\t})\n\n\tconst controller = createMutationController<TData, TArgs, TContext>({\n\t\tmutationFn: (...args) => fnRef.current(...args),\n\t\tresolveOptions: () => optionsRef.current,\n\t\tonStateChange: (state) => {\n\t\t\tif (!mounted) return\n\t\t\tisLoading.value = state.isLoading\n\t\t\terror.value = state.error\n\t\t},\n\t})\n\n\tisLoading.value = controller.getSnapshot().isLoading\n\terror.value = controller.getSnapshot().error\n\n\tonScopeDispose(() => {\n\t\tcontroller.destroy()\n\t})\n\n\treturn {\n\t\tmutate: (...args: TArgs) => controller.mutate(...args),\n\t\tmutateAsync: (...args: TArgs) => controller.mutateAsync(...args),\n\t\tisLoading: shallowReadonly(isLoading),\n\t\terror: shallowReadonly(error),\n\t\treset: () => controller.reset(),\n\t}\n}\n","import { OFFLINE_SYNC_STATUS, createSyncStatusController } from '@korajs/sync'\nimport { onScopeDispose, readonly, shallowRef, watchEffect } from 'vue'\nimport { useKoraContext } from '../context'\n\n/**\n * Reactive sync engine status. Updates only when status payload changes.\n */\nexport function useSyncStatus() {\n\tconst { syncEngine, subscribeSyncStatus, events } = useKoraContext()\n\tconst status = shallowRef(OFFLINE_SYNC_STATUS)\n\n\twatchEffect((onCleanup) => {\n\t\tconst controller = createSyncStatusController({\n\t\t\tsyncEngine,\n\t\t\tsubscribeSyncStatus,\n\t\t\tevents: subscribeSyncStatus ? null : events,\n\t\t})\n\t\tstatus.value = controller.getSnapshot()\n\t\tconst unsubscribe = controller.subscribe(() => {\n\t\t\tstatus.value = controller.getSnapshot()\n\t\t})\n\t\tonCleanup(() => {\n\t\t\tunsubscribe()\n\t\t\tcontroller.destroy()\n\t\t})\n\t})\n\n\treturn readonly(status)\n}\n","import { useKoraContext } from '../context'\nimport type { KoraAppLike } from '../types'\n\n/**\n * Returns the typed Kora app from {@link KoraProvider}'s `app` prop.\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 :app=\"app\">. Pass your createApp() result to the provider.',\n\t\t)\n\t}\n\treturn app as T\n}\n","import type { CollectionAccessor } from '@korajs/store'\nimport { useKoraContext } from '../context'\n\n/**\n * Returns a collection accessor for the given schema collection name.\n */\nexport function useCollection(name: string): CollectionAccessor {\n\tconst { store } = useKoraContext()\n\treturn store.collection(name)\n}\n","import { asRichTextSyncEngine, createRichTextController } from '@korajs/store'\nimport type { AwarenessUser } from '@korajs/sync'\nimport { reactive, shallowRef, watch } from 'vue'\nimport { useKoraContext } from '../context'\nimport type { UseRichTextResult } from '../types'\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 controllerRef = shallowRef<ReturnType<typeof createRichTextController> | null>(null)\n\n\tconst state = reactive({\n\t\tready: false,\n\t\terror: null as Error | null,\n\t\tcanUndo: false,\n\t\tcanRedo: false,\n\t\tcursors: [] as UseRichTextResult['cursors'],\n\t})\n\n\twatch(\n\t\t() => [collectionName, recordId, fieldName, options?.useDocChannel] as const,\n\t\t([name, id, field, useDocChannel], _previous, onCleanup) => {\n\t\t\tcontrollerRef.value?.destroy()\n\n\t\t\tconst controller = createRichTextController({\n\t\t\t\tcollection: store.collection(name),\n\t\t\t\tcollectionName: name,\n\t\t\t\trecordId: id,\n\t\t\t\tfieldName: field,\n\t\t\t\tstore,\n\t\t\t\tsyncEngine: asRichTextSyncEngine(syncEngine),\n\t\t\t\tuseDocChannel,\n\t\t\t\tuser: options?.user,\n\t\t\t})\n\n\t\t\tconst syncState = (): void => {\n\t\t\t\tconst snapshot = controller.getSnapshot()\n\t\t\t\tstate.ready = snapshot.ready\n\t\t\t\tstate.error = snapshot.error\n\t\t\t\tstate.canUndo = snapshot.canUndo\n\t\t\t\tstate.canRedo = snapshot.canRedo\n\t\t\t\tstate.cursors = [...snapshot.cursors]\n\t\t\t}\n\n\t\t\tsyncState()\n\t\t\tconst unsubscribe = controller.subscribe(syncState)\n\t\t\tcontrollerRef.value = controller\n\n\t\t\tonCleanup(() => {\n\t\t\t\tunsubscribe()\n\t\t\t\tcontroller.destroy()\n\t\t\t\tif (controllerRef.value === controller) {\n\t\t\t\t\tcontrollerRef.value = null\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\t\t{ immediate: true },\n\t)\n\n\twatch(\n\t\t() => options?.user,\n\t\t(user) => {\n\t\t\tcontrollerRef.value?.setUser(user)\n\t\t},\n\t)\n\n\tconst controller = (): NonNullable<typeof controllerRef.value> => {\n\t\tif (!controllerRef.value) {\n\t\t\tthrow new Error('useRichText controller is not initialized')\n\t\t}\n\t\treturn controllerRef.value\n\t}\n\n\treturn {\n\t\tget doc() {\n\t\t\treturn controller().doc\n\t\t},\n\t\tget text() {\n\t\t\treturn controller().text\n\t\t},\n\t\tundo: () => controller().undo(),\n\t\tredo: () => controller().redo(),\n\t\tget ready() {\n\t\t\treturn state.ready\n\t\t},\n\t\tget error() {\n\t\t\treturn state.error\n\t\t},\n\t\tget canUndo() {\n\t\t\treturn state.canUndo\n\t\t},\n\t\tget canRedo() {\n\t\t\treturn state.canRedo\n\t\t},\n\t\tget cursors() {\n\t\t\treturn state.cursors\n\t\t},\n\t\tsetCursor: (anchor: number, head: number) => controller().setCursor(anchor, head),\n\t\tclearCursor: () => controller().clearCursor(),\n\t}\n}\n","import type { AwarenessState } from '@korajs/sync'\nimport { subscribeRemoteAwarenessStates } from '@korajs/sync'\nimport { onScopeDispose, shallowRef, watch, watchEffect, type ShallowRef } from 'vue'\nimport { useKoraContext } from '../context'\n\n/**\n * Sets the local user's collaborative presence state.\n */\nexport function usePresence(user: { name: string; color: string; avatar?: string } | null): void {\n\tconst { syncEngine } = useKoraContext()\n\n\twatch(\n\t\t() => [syncEngine, user?.name, user?.color, user?.avatar] as const,\n\t\t([engine, name, color, avatar], _prev, onCleanup) => {\n\t\t\tif (!engine || !name || !color) return\n\n\t\t\tconst awareness = engine.getAwarenessManager()\n\t\t\tawareness.setLocalState({\n\t\t\t\tuser: {\n\t\t\t\t\tname,\n\t\t\t\t\tcolor,\n\t\t\t\t\tavatar,\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tonCleanup(() => {\n\t\t\t\tawareness.setLocalState(null)\n\t\t\t})\n\t\t},\n\t\t{ immediate: true },\n\t)\n}\n\n/**\n * Reactive list of remote collaborators' awareness states.\n */\nexport function useCollaborators(): ShallowRef<AwarenessState[]> {\n\tconst { syncEngine } = useKoraContext()\n\tconst collaborators = shallowRef<AwarenessState[]>([])\n\n\twatchEffect((onCleanup) => {\n\t\tif (!syncEngine) {\n\t\t\tcollaborators.value = []\n\t\t\treturn\n\t\t}\n\n\t\tconst awareness = syncEngine.getAwarenessManager()\n\t\tconst unsubscribe = subscribeRemoteAwarenessStates(awareness, (states) => {\n\t\t\tcollaborators.value = states\n\t\t})\n\t\tonCleanup(unsubscribe)\n\t})\n\n\tonScopeDispose(() => {\n\t\tcollaborators.value = []\n\t})\n\n\treturn collaborators\n}\n"],"mappings":"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","names":["KoraError","inject","QueryStoreCache","QueryStoreCache","shallowRef","watch","shallowRef","watch","onScopeDispose","ref","readonly","shallowRef","shallowRef","readonly","shallowRef","watch","shallowRef","watch","controller","onScopeDispose","shallowRef","watch","watchEffect","watch","shallowRef","watchEffect","onScopeDispose","inject","KoraError"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@korajs/vue",
3
- "version": "0.5.0",
4
- "description": "Experimental Vue bindings stub for Kora.js (provide/inject app context)",
3
+ "version": "0.6.1",
4
+ "description": "Kora.js Vue 3 composables for offline-first applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",
@@ -25,20 +25,27 @@
25
25
  "vue": "^3.4.0"
26
26
  },
27
27
  "dependencies": {
28
- "@korajs/store": "0.5.0",
29
- "@korajs/core": "0.5.0"
28
+ "yjs": "^13.6.30",
29
+ "@korajs/core": "0.6.0",
30
+ "@korajs/store": "0.6.0",
31
+ "@korajs/sync": "0.6.1"
30
32
  },
31
33
  "devDependencies": {
34
+ "@vue/test-utils": "^2.4.6",
35
+ "happy-dom": "^17.4.4",
32
36
  "tsup": "^8.3.6",
33
37
  "typescript": "^5.7.3",
38
+ "vitest": "^3.0.4",
34
39
  "vue": "^3.5.13"
35
40
  },
36
41
  "license": "MIT",
37
42
  "scripts": {
38
43
  "build": "tsup",
39
44
  "dev": "tsup --watch",
45
+ "test": "vitest run",
46
+ "test:watch": "vitest",
40
47
  "typecheck": "tsc --noEmit",
41
48
  "lint": "biome check src/",
42
- "clean": "rm -rf dist .turbo"
49
+ "clean": "rm -rf dist .turbo coverage"
43
50
  }
44
51
  }