@korajs/vue 0.0.0-canary-20261008174129
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/LICENSE +21 -0
- package/README.md +95 -0
- package/dist/index.cjs +506 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +292 -0
- package/dist/index.d.ts +292 -0
- package/dist/index.js +480 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dr. Obed Ehoneah
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# @korajs/vue
|
|
2
|
+
|
|
3
|
+
Vue 3 composables for [Kora.js](https://korajs.dev) offline-first applications.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add korajs@beta @korajs/vue@beta
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
Create the Kora app once at module scope, connect sync after `ready`, then wrap your tree with providers (matches the CLI `vue-tailwind-sync` template):
|
|
14
|
+
|
|
15
|
+
<!-- docs-check: skip template excerpt: imports the project's own auth and schema modules -->
|
|
16
|
+
```typescript
|
|
17
|
+
import { createKoraAuthSync } from '@korajs/auth'
|
|
18
|
+
import { AuthProvider } from '@korajs/auth/vue'
|
|
19
|
+
import { KoraProvider } from '@korajs/vue'
|
|
20
|
+
import { createApp as createKoraApp } from 'korajs'
|
|
21
|
+
import { createApp, h } from 'vue'
|
|
22
|
+
import App from './App.vue'
|
|
23
|
+
import { authClient } from './auth'
|
|
24
|
+
import schema from './schema'
|
|
25
|
+
import koraWorkerUrl from './kora-worker.ts?worker&url'
|
|
26
|
+
|
|
27
|
+
const kora = createKoraApp({
|
|
28
|
+
schema,
|
|
29
|
+
sync: { url: 'ws://localhost:3001/kora-sync', authClient: createKoraAuthSync({ authClient, schema }) },
|
|
30
|
+
store: { workerUrl: koraWorkerUrl },
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
kora.ready.then(() => kora.sync?.connect())
|
|
34
|
+
|
|
35
|
+
createApp({
|
|
36
|
+
render: () =>
|
|
37
|
+
h(AuthProvider, { client: authClient }, () =>
|
|
38
|
+
h(KoraProvider, { app: kora }, () => h(App)),
|
|
39
|
+
),
|
|
40
|
+
}).mount('#app')
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or use SFC wrappers:
|
|
44
|
+
|
|
45
|
+
```vue
|
|
46
|
+
<AuthProvider :client="authClient">
|
|
47
|
+
<KoraProvider :app="kora">
|
|
48
|
+
<TodoList />
|
|
49
|
+
</KoraProvider>
|
|
50
|
+
</AuthProvider>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Composables
|
|
54
|
+
|
|
55
|
+
| Composable | Purpose |
|
|
56
|
+
|------------|---------|
|
|
57
|
+
| `useQuery(query)` | Reactive local query results |
|
|
58
|
+
| `useMutation(fn)` | Optimistic mutations with rollback |
|
|
59
|
+
| `useSyncStatus()` | Connection / sync state |
|
|
60
|
+
| `useApp()` | Typed `createApp()` instance |
|
|
61
|
+
| `useCollection(name)` | Collection accessor |
|
|
62
|
+
| `useRichText(name, id, field)` | Yjs richtext editor binding |
|
|
63
|
+
| `usePresence(user)` | Publish collaborative presence |
|
|
64
|
+
| `useCollaborators()` | Remote collaborator awareness states |
|
|
65
|
+
|
|
66
|
+
```vue
|
|
67
|
+
<script setup lang="ts">
|
|
68
|
+
import { useApp, useQuery, useMutation } from '@korajs/vue'
|
|
69
|
+
|
|
70
|
+
const app = useApp()
|
|
71
|
+
const todos = useQuery(app.todos.where({ completed: false }))
|
|
72
|
+
const { mutate: addTodo } = useMutation(app.todos.insert)
|
|
73
|
+
</script>
|
|
74
|
+
|
|
75
|
+
<template>
|
|
76
|
+
<ul>
|
|
77
|
+
<li v-for="todo in todos" :key="todo.id">{{ todo.title }}</li>
|
|
78
|
+
</ul>
|
|
79
|
+
<button @click="addTodo({ title: 'New' })">Add</button>
|
|
80
|
+
</template>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Organization auth
|
|
84
|
+
|
|
85
|
+
When using `@korajs/auth` organizations, wrap with `OrgProvider` and use org composables from `@korajs/auth/vue`:
|
|
86
|
+
|
|
87
|
+
```vue
|
|
88
|
+
<OrgProvider :client="orgClient">
|
|
89
|
+
<AdminPanel />
|
|
90
|
+
</OrgProvider>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Legacy helpers
|
|
94
|
+
|
|
95
|
+
`installKora()` and `useKoraApp()` remain for app-context only. Prefer `KoraProvider` + composables for reactive data.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
KoraProvider: () => KoraProvider,
|
|
24
|
+
installKora: () => installKora,
|
|
25
|
+
koraAppInjectionKey: () => koraAppInjectionKey,
|
|
26
|
+
koraContextKey: () => koraContextKey,
|
|
27
|
+
useApp: () => useApp,
|
|
28
|
+
useCollaborators: () => useCollaborators,
|
|
29
|
+
useCollection: () => useCollection,
|
|
30
|
+
useKoraApp: () => useKoraApp,
|
|
31
|
+
useKoraContext: () => useKoraContext,
|
|
32
|
+
useMutation: () => useMutation,
|
|
33
|
+
usePresence: () => usePresence,
|
|
34
|
+
useQuery: () => useQuery,
|
|
35
|
+
useQueryState: () => useQueryState,
|
|
36
|
+
useRichText: () => useRichText,
|
|
37
|
+
useSyncStatus: () => useSyncStatus
|
|
38
|
+
});
|
|
39
|
+
module.exports = __toCommonJS(index_exports);
|
|
40
|
+
var import_core2 = require("@korajs/core");
|
|
41
|
+
var import_vue8 = require("vue");
|
|
42
|
+
|
|
43
|
+
// src/context.ts
|
|
44
|
+
var import_core = require("@korajs/core");
|
|
45
|
+
var import_vue = require("vue");
|
|
46
|
+
var koraContextKey = /* @__PURE__ */ Symbol("korajs-context");
|
|
47
|
+
var koraAppInjectionKey = /* @__PURE__ */ Symbol("korajs-app");
|
|
48
|
+
function useKoraContext() {
|
|
49
|
+
const contextRef = (0, import_vue.inject)(koraContextKey);
|
|
50
|
+
if (!contextRef?.value) {
|
|
51
|
+
throw new import_core.KoraError(
|
|
52
|
+
"useKoraContext() requires <KoraProvider>. Wrap your app root with KoraProvider.",
|
|
53
|
+
"KORA_NOT_PROVIDED",
|
|
54
|
+
{ fix: '<KoraProvider :app="app"><App /></KoraProvider>' }
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
return contextRef.value;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/components/kora-provider.ts
|
|
61
|
+
var import_store = require("@korajs/store");
|
|
62
|
+
var import_vue2 = require("vue");
|
|
63
|
+
|
|
64
|
+
// src/resolve-query-store-cache.ts
|
|
65
|
+
function resolveQueryStoreCache(app, fallback) {
|
|
66
|
+
if (app && typeof app.getQueryStoreCache === "function") {
|
|
67
|
+
return app.getQueryStoreCache();
|
|
68
|
+
}
|
|
69
|
+
return fallback;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/components/kora-provider.ts
|
|
73
|
+
var KoraProvider = (0, import_vue2.defineComponent)({
|
|
74
|
+
name: "KoraProvider",
|
|
75
|
+
props: {
|
|
76
|
+
app: {
|
|
77
|
+
type: Object,
|
|
78
|
+
default: void 0
|
|
79
|
+
},
|
|
80
|
+
store: {
|
|
81
|
+
type: Object,
|
|
82
|
+
default: void 0
|
|
83
|
+
},
|
|
84
|
+
syncEngine: {
|
|
85
|
+
type: Object,
|
|
86
|
+
default: void 0
|
|
87
|
+
},
|
|
88
|
+
fallback: {
|
|
89
|
+
type: [Object, String],
|
|
90
|
+
default: null
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
setup(props, { slots }) {
|
|
94
|
+
const resolvedStore = (0, import_vue2.ref)(null);
|
|
95
|
+
const resolvedSync = (0, import_vue2.ref)(null);
|
|
96
|
+
const ready = (0, import_vue2.ref)(!props.app && Boolean(props.store));
|
|
97
|
+
const initError = (0, import_vue2.ref)(null);
|
|
98
|
+
const fallbackQueryStoreCache = new import_store.QueryStoreCache();
|
|
99
|
+
const contextRef = (0, import_vue2.shallowRef)(null);
|
|
100
|
+
(0, import_vue2.provide)(koraContextKey, contextRef);
|
|
101
|
+
if (props.app) {
|
|
102
|
+
(0, import_vue2.provide)(koraAppInjectionKey, props.app);
|
|
103
|
+
}
|
|
104
|
+
(0, import_vue2.watch)(
|
|
105
|
+
() => props.app,
|
|
106
|
+
(app, _previous, onCleanup) => {
|
|
107
|
+
if (!app) {
|
|
108
|
+
if (props.store) {
|
|
109
|
+
resolvedStore.value = props.store;
|
|
110
|
+
resolvedSync.value = props.syncEngine ?? null;
|
|
111
|
+
ready.value = true;
|
|
112
|
+
}
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
ready.value = false;
|
|
116
|
+
initError.value = null;
|
|
117
|
+
let cancelled = false;
|
|
118
|
+
app.ready.then(() => {
|
|
119
|
+
if (cancelled) return;
|
|
120
|
+
resolvedStore.value = app.getStore();
|
|
121
|
+
resolvedSync.value = app.getSyncEngine();
|
|
122
|
+
ready.value = true;
|
|
123
|
+
}).catch((error) => {
|
|
124
|
+
if (cancelled) return;
|
|
125
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
126
|
+
console.error("[Kora] Initialization failed:", err);
|
|
127
|
+
initError.value = err;
|
|
128
|
+
});
|
|
129
|
+
onCleanup(() => {
|
|
130
|
+
cancelled = true;
|
|
131
|
+
});
|
|
132
|
+
},
|
|
133
|
+
{ immediate: true }
|
|
134
|
+
);
|
|
135
|
+
(0, import_vue2.watch)(
|
|
136
|
+
() => props.store,
|
|
137
|
+
(store) => {
|
|
138
|
+
if (store && !props.app) {
|
|
139
|
+
resolvedStore.value = store;
|
|
140
|
+
resolvedSync.value = props.syncEngine ?? null;
|
|
141
|
+
ready.value = true;
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
{ immediate: true }
|
|
145
|
+
);
|
|
146
|
+
(0, import_vue2.watch)(
|
|
147
|
+
() => [resolvedStore.value, resolvedSync.value, props.app],
|
|
148
|
+
([store, syncEngine, app]) => {
|
|
149
|
+
if (!store) {
|
|
150
|
+
contextRef.value = null;
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
contextRef.value = {
|
|
154
|
+
store,
|
|
155
|
+
syncEngine: syncEngine ?? null,
|
|
156
|
+
app: app ?? null,
|
|
157
|
+
events: app?.events ?? null,
|
|
158
|
+
subscribeSyncStatus: app?.sync?.subscribeStatus ?? null,
|
|
159
|
+
queryStoreCache: resolveQueryStoreCache(app, fallbackQueryStoreCache)
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
{ immediate: true }
|
|
163
|
+
);
|
|
164
|
+
(0, import_vue2.onScopeDispose)(() => {
|
|
165
|
+
if (!props.app) {
|
|
166
|
+
fallbackQueryStoreCache.clear();
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
return () => {
|
|
170
|
+
if (initError.value) {
|
|
171
|
+
return (0, import_vue2.h)("div", { style: { color: "red", padding: "1rem", fontFamily: "monospace" } }, [
|
|
172
|
+
(0, import_vue2.h)("strong", null, "Kora initialization error: "),
|
|
173
|
+
initError.value.message
|
|
174
|
+
]);
|
|
175
|
+
}
|
|
176
|
+
if (!ready.value) {
|
|
177
|
+
return props.fallback ?? null;
|
|
178
|
+
}
|
|
179
|
+
if (!resolvedStore.value) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
'KoraProvider requires either an "app" or "store" prop. Pass createApp() or a Store instance.'
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
return slots.default?.();
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// src/composables/use-query.ts
|
|
190
|
+
var import_store2 = require("@korajs/store");
|
|
191
|
+
var import_vue3 = require("vue");
|
|
192
|
+
var EMPTY_ARRAY = Object.freeze([]);
|
|
193
|
+
function readQueryError(queryStore) {
|
|
194
|
+
const channel = queryStore;
|
|
195
|
+
return typeof channel.getError === "function" ? channel.getError() : null;
|
|
196
|
+
}
|
|
197
|
+
function useQuerySubscription(query, options) {
|
|
198
|
+
const { queryStoreCache } = useKoraContext();
|
|
199
|
+
const data = (0, import_vue3.shallowRef)(EMPTY_ARRAY);
|
|
200
|
+
const error = (0, import_vue3.shallowRef)(null);
|
|
201
|
+
const ready = (0, import_vue3.shallowRef)(false);
|
|
202
|
+
(0, import_vue3.watch)(
|
|
203
|
+
() => {
|
|
204
|
+
const enabled = (0, import_vue3.toValue)(options?.enabled) !== false;
|
|
205
|
+
const current = enabled ? (0, import_vue3.toValue)(query) : null;
|
|
206
|
+
return current ? (0, import_store2.queryKey)(current.getDescriptor()) : null;
|
|
207
|
+
},
|
|
208
|
+
(key, _previous, onCleanup) => {
|
|
209
|
+
const current = key ? (0, import_vue3.toValue)(query) : null;
|
|
210
|
+
if (!current) {
|
|
211
|
+
data.value = EMPTY_ARRAY;
|
|
212
|
+
error.value = null;
|
|
213
|
+
ready.value = false;
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
(0, import_store2.assertQueryReady)(current);
|
|
217
|
+
const queryStore = queryStoreCache.getOrCreate(current);
|
|
218
|
+
const sync = () => {
|
|
219
|
+
const failure = readQueryError(queryStore);
|
|
220
|
+
if (failure !== error.value) {
|
|
221
|
+
error.value = failure;
|
|
222
|
+
if (failure) options?.onError?.(failure);
|
|
223
|
+
}
|
|
224
|
+
if (queryStore.hasSnapshot()) {
|
|
225
|
+
data.value = queryStore.getSnapshot();
|
|
226
|
+
ready.value = true;
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
const unsubscribe = queryStore.subscribe(sync);
|
|
230
|
+
ready.value = false;
|
|
231
|
+
sync();
|
|
232
|
+
onCleanup(() => {
|
|
233
|
+
unsubscribe();
|
|
234
|
+
queryStoreCache.release(current);
|
|
235
|
+
});
|
|
236
|
+
},
|
|
237
|
+
{ immediate: true }
|
|
238
|
+
);
|
|
239
|
+
return { data, error, ready };
|
|
240
|
+
}
|
|
241
|
+
function useQuery(query, options) {
|
|
242
|
+
const reporting = {
|
|
243
|
+
...options,
|
|
244
|
+
onError: options?.onError ?? ((failure) => {
|
|
245
|
+
console.error("[Kora] useQuery failed:", failure);
|
|
246
|
+
})
|
|
247
|
+
};
|
|
248
|
+
return (0, import_vue3.readonly)(useQuerySubscription(query, reporting).data);
|
|
249
|
+
}
|
|
250
|
+
function useQueryState(query, options) {
|
|
251
|
+
const { data, error, ready } = useQuerySubscription(query, options);
|
|
252
|
+
return { data: (0, import_vue3.readonly)(data), error: (0, import_vue3.readonly)(error), ready: (0, import_vue3.readonly)(ready) };
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// src/composables/use-mutation.ts
|
|
256
|
+
var import_bindings = require("@korajs/core/bindings");
|
|
257
|
+
var import_vue4 = require("vue");
|
|
258
|
+
function useMutation(mutationFn, options) {
|
|
259
|
+
const fnRef = { current: mutationFn };
|
|
260
|
+
fnRef.current = mutationFn;
|
|
261
|
+
const optionsRef = { current: options };
|
|
262
|
+
optionsRef.current = options;
|
|
263
|
+
const isLoading = (0, import_vue4.ref)(false);
|
|
264
|
+
const error = (0, import_vue4.ref)(null);
|
|
265
|
+
let mounted = true;
|
|
266
|
+
(0, import_vue4.onScopeDispose)(() => {
|
|
267
|
+
mounted = false;
|
|
268
|
+
});
|
|
269
|
+
const controller = (0, import_bindings.createMutationController)({
|
|
270
|
+
mutationFn: (...args) => fnRef.current(...args),
|
|
271
|
+
resolveOptions: () => optionsRef.current,
|
|
272
|
+
onStateChange: (state) => {
|
|
273
|
+
if (!mounted) return;
|
|
274
|
+
isLoading.value = state.isLoading;
|
|
275
|
+
error.value = state.error;
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
isLoading.value = controller.getSnapshot().isLoading;
|
|
279
|
+
error.value = controller.getSnapshot().error;
|
|
280
|
+
(0, import_vue4.onScopeDispose)(() => {
|
|
281
|
+
controller.destroy();
|
|
282
|
+
});
|
|
283
|
+
return {
|
|
284
|
+
mutate: (...args) => controller.mutate(...args),
|
|
285
|
+
mutateAsync: (...args) => controller.mutateAsync(...args),
|
|
286
|
+
isLoading: (0, import_vue4.shallowReadonly)(isLoading),
|
|
287
|
+
error: (0, import_vue4.shallowReadonly)(error),
|
|
288
|
+
reset: () => controller.reset()
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// src/composables/use-sync-status.ts
|
|
293
|
+
var import_sync = require("@korajs/sync");
|
|
294
|
+
var import_vue5 = require("vue");
|
|
295
|
+
function useSyncStatus() {
|
|
296
|
+
const { syncEngine, subscribeSyncStatus, events } = useKoraContext();
|
|
297
|
+
const status = (0, import_vue5.shallowRef)(import_sync.OFFLINE_SYNC_STATUS);
|
|
298
|
+
(0, import_vue5.watchEffect)((onCleanup) => {
|
|
299
|
+
const controller = (0, import_sync.createSyncStatusController)({
|
|
300
|
+
syncEngine,
|
|
301
|
+
subscribeSyncStatus,
|
|
302
|
+
events: subscribeSyncStatus ? null : events
|
|
303
|
+
});
|
|
304
|
+
status.value = controller.getSnapshot();
|
|
305
|
+
const unsubscribe = controller.subscribe(() => {
|
|
306
|
+
status.value = controller.getSnapshot();
|
|
307
|
+
});
|
|
308
|
+
onCleanup(() => {
|
|
309
|
+
unsubscribe();
|
|
310
|
+
controller.destroy();
|
|
311
|
+
});
|
|
312
|
+
});
|
|
313
|
+
return (0, import_vue5.readonly)(status);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// src/composables/use-app.ts
|
|
317
|
+
function useApp() {
|
|
318
|
+
const { app } = useKoraContext();
|
|
319
|
+
if (!app) {
|
|
320
|
+
throw new Error(
|
|
321
|
+
'useApp() requires <KoraProvider :app="app">. Pass your createApp() result to the provider.'
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
return app;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// src/composables/use-collection.ts
|
|
328
|
+
function useCollection(name) {
|
|
329
|
+
const { store } = useKoraContext();
|
|
330
|
+
return store.collection(name);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// src/composables/use-rich-text.ts
|
|
334
|
+
var import_store3 = require("@korajs/store");
|
|
335
|
+
var import_vue6 = require("vue");
|
|
336
|
+
function useRichText(collectionName, recordId, fieldName, options) {
|
|
337
|
+
const { store, syncEngine } = useKoraContext();
|
|
338
|
+
const controllerRef = (0, import_vue6.shallowRef)(null);
|
|
339
|
+
const state = (0, import_vue6.reactive)({
|
|
340
|
+
ready: false,
|
|
341
|
+
error: null,
|
|
342
|
+
canUndo: false,
|
|
343
|
+
canRedo: false,
|
|
344
|
+
cursors: [],
|
|
345
|
+
hasUnsavedChanges: false
|
|
346
|
+
});
|
|
347
|
+
(0, import_vue6.watch)(
|
|
348
|
+
() => [collectionName, recordId, fieldName, options?.useDocChannel],
|
|
349
|
+
([name, id, field, useDocChannel], _previous, onCleanup) => {
|
|
350
|
+
controllerRef.value?.destroy();
|
|
351
|
+
const controller2 = (0, import_store3.createRichTextController)({
|
|
352
|
+
collection: store.collection(name),
|
|
353
|
+
collectionName: name,
|
|
354
|
+
recordId: id,
|
|
355
|
+
fieldName: field,
|
|
356
|
+
store,
|
|
357
|
+
syncEngine: (0, import_store3.asRichTextSyncEngine)(syncEngine),
|
|
358
|
+
useDocChannel,
|
|
359
|
+
user: options?.user
|
|
360
|
+
});
|
|
361
|
+
const syncState = () => {
|
|
362
|
+
const snapshot = controller2.getSnapshot();
|
|
363
|
+
state.ready = snapshot.ready;
|
|
364
|
+
state.error = snapshot.error;
|
|
365
|
+
state.canUndo = snapshot.canUndo;
|
|
366
|
+
state.canRedo = snapshot.canRedo;
|
|
367
|
+
state.cursors = [...snapshot.cursors];
|
|
368
|
+
state.hasUnsavedChanges = snapshot.hasUnsavedChanges;
|
|
369
|
+
};
|
|
370
|
+
syncState();
|
|
371
|
+
const unsubscribe = controller2.subscribe(syncState);
|
|
372
|
+
controllerRef.value = controller2;
|
|
373
|
+
onCleanup(() => {
|
|
374
|
+
unsubscribe();
|
|
375
|
+
controller2.destroy();
|
|
376
|
+
if (controllerRef.value === controller2) {
|
|
377
|
+
controllerRef.value = null;
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
},
|
|
381
|
+
{ immediate: true }
|
|
382
|
+
);
|
|
383
|
+
(0, import_vue6.watch)(
|
|
384
|
+
() => options?.user,
|
|
385
|
+
(user) => {
|
|
386
|
+
controllerRef.value?.setUser(user);
|
|
387
|
+
}
|
|
388
|
+
);
|
|
389
|
+
const controller = () => {
|
|
390
|
+
if (!controllerRef.value) {
|
|
391
|
+
throw new Error("useRichText controller is not initialized");
|
|
392
|
+
}
|
|
393
|
+
return controllerRef.value;
|
|
394
|
+
};
|
|
395
|
+
return {
|
|
396
|
+
get doc() {
|
|
397
|
+
return controller().doc;
|
|
398
|
+
},
|
|
399
|
+
get text() {
|
|
400
|
+
return controller().text;
|
|
401
|
+
},
|
|
402
|
+
undo: () => controller().undo(),
|
|
403
|
+
redo: () => controller().redo(),
|
|
404
|
+
get ready() {
|
|
405
|
+
return state.ready;
|
|
406
|
+
},
|
|
407
|
+
get error() {
|
|
408
|
+
return state.error;
|
|
409
|
+
},
|
|
410
|
+
get canUndo() {
|
|
411
|
+
return state.canUndo;
|
|
412
|
+
},
|
|
413
|
+
get canRedo() {
|
|
414
|
+
return state.canRedo;
|
|
415
|
+
},
|
|
416
|
+
get cursors() {
|
|
417
|
+
return state.cursors;
|
|
418
|
+
},
|
|
419
|
+
setCursor: (anchor, head) => controller().setCursor(anchor, head),
|
|
420
|
+
clearCursor: () => controller().clearCursor(),
|
|
421
|
+
get hasUnsavedChanges() {
|
|
422
|
+
return state.hasUnsavedChanges;
|
|
423
|
+
},
|
|
424
|
+
retrySave: () => controller().retrySave(),
|
|
425
|
+
getUnsavedState: () => controller().getUnsavedState()
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// src/composables/use-presence.ts
|
|
430
|
+
var import_sync2 = require("@korajs/sync");
|
|
431
|
+
var import_vue7 = require("vue");
|
|
432
|
+
function usePresence(user) {
|
|
433
|
+
const { syncEngine } = useKoraContext();
|
|
434
|
+
(0, import_vue7.watch)(
|
|
435
|
+
() => [syncEngine, user?.name, user?.color, user?.avatar],
|
|
436
|
+
([engine, name, color, avatar], _prev, onCleanup) => {
|
|
437
|
+
if (!engine || !name || !color) return;
|
|
438
|
+
const awareness = engine.getAwarenessManager();
|
|
439
|
+
awareness.setLocalState({
|
|
440
|
+
user: {
|
|
441
|
+
name,
|
|
442
|
+
color,
|
|
443
|
+
avatar
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
onCleanup(() => {
|
|
447
|
+
awareness.setLocalState(null);
|
|
448
|
+
});
|
|
449
|
+
},
|
|
450
|
+
{ immediate: true }
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
function useCollaborators() {
|
|
454
|
+
const { syncEngine } = useKoraContext();
|
|
455
|
+
const collaborators = (0, import_vue7.shallowRef)([]);
|
|
456
|
+
(0, import_vue7.watchEffect)((onCleanup) => {
|
|
457
|
+
if (!syncEngine) {
|
|
458
|
+
collaborators.value = [];
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
const awareness = syncEngine.getAwarenessManager();
|
|
462
|
+
const unsubscribe = (0, import_sync2.subscribeRemoteAwarenessStates)(awareness, (states) => {
|
|
463
|
+
collaborators.value = states;
|
|
464
|
+
});
|
|
465
|
+
onCleanup(unsubscribe);
|
|
466
|
+
});
|
|
467
|
+
(0, import_vue7.onScopeDispose)(() => {
|
|
468
|
+
collaborators.value = [];
|
|
469
|
+
});
|
|
470
|
+
return collaborators;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// src/index.ts
|
|
474
|
+
function installKora(vueApp, koraApp) {
|
|
475
|
+
vueApp.provide(koraAppInjectionKey, koraApp);
|
|
476
|
+
}
|
|
477
|
+
function useKoraApp() {
|
|
478
|
+
const app = (0, import_vue8.inject)(koraAppInjectionKey);
|
|
479
|
+
if (!app) {
|
|
480
|
+
throw new import_core2.KoraError(
|
|
481
|
+
'useKoraApp() requires installKora(vueApp, koraApp) or <KoraProvider :app="app">.',
|
|
482
|
+
"KORA_NOT_PROVIDED",
|
|
483
|
+
{ fix: 'Use <KoraProvider :app="app"> and useApp() for full bindings.' }
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
return app;
|
|
487
|
+
}
|
|
488
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
489
|
+
0 && (module.exports = {
|
|
490
|
+
KoraProvider,
|
|
491
|
+
installKora,
|
|
492
|
+
koraAppInjectionKey,
|
|
493
|
+
koraContextKey,
|
|
494
|
+
useApp,
|
|
495
|
+
useCollaborators,
|
|
496
|
+
useCollection,
|
|
497
|
+
useKoraApp,
|
|
498
|
+
useKoraContext,
|
|
499
|
+
useMutation,
|
|
500
|
+
usePresence,
|
|
501
|
+
useQuery,
|
|
502
|
+
useQueryState,
|
|
503
|
+
useRichText,
|
|
504
|
+
useSyncStatus
|
|
505
|
+
});
|
|
506
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
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 {\n\tUseMutationOptions,\n\tUseMutationResult,\n\tUseQueryOptions,\n\tUseQueryStateResult,\n\tUseRichTextResult,\n} from './types'\n\nexport { koraAppInjectionKey, koraContextKey, useKoraContext } from './context'\nexport { KoraProvider } from './components/kora-provider'\nexport { useQuery, useQueryState } from './composables/use-query'\nexport type { QueryInput } 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, type ShallowRef, inject } 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 { koraAppInjectionKey, koraContextKey } from '../context'\nimport { resolveQueryStoreCache } from '../resolve-query-store-cache'\nimport type { KoraAppLike, KoraContextValue } from '../types'\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('div', { style: { color: 'red', padding: '1rem', fontFamily: 'monospace' } }, [\n\t\t\t\t\th('strong', null, 'Kora initialization error: '),\n\t\t\t\t\tinitError.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 type { 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, QueryStore } from '@korajs/store'\nimport { assertQueryReady, queryKey } from '@korajs/store'\nimport {\n\ttype DeepReadonly,\n\ttype MaybeRefOrGetter,\n\ttype ShallowRef,\n\treadonly,\n\tshallowRef,\n\ttoValue,\n\twatch,\n} from 'vue'\nimport { useKoraContext } from '../context'\nimport type { UseQueryOptions, UseQueryStateResult } from '../types'\n\nconst EMPTY_ARRAY: readonly unknown[] = Object.freeze([])\n\n/** A query input: a builder, a ref to one, or a getter (`() => app.todos.where(...)`). */\nexport type QueryInput<T> = MaybeRefOrGetter<QueryBuilder<T> | null | undefined>\n\n/** The STORE-12 error channel of a QueryStore, read structurally (older store builds lack it). */\nfunction readQueryError(queryStore: QueryStore<unknown>): Error | null {\n\tconst channel = queryStore as unknown as { getError?: () => Error | null }\n\treturn typeof channel.getError === 'function' ? channel.getError() : null\n}\n\n/**\n * Shared engine of {@link useQuery} and {@link useQueryState}: tracks the query and\n * `enabled` reactively (refs, getters, props), subscribes to one ref-counted\n * QueryStore per descriptor, and releases it when the descriptor changes or the\n * scope is disposed (DX-7).\n */\nfunction useQuerySubscription<T>(\n\tquery: QueryInput<T>,\n\toptions: UseQueryOptions | undefined,\n): {\n\tdata: ShallowRef<readonly T[]>\n\terror: ShallowRef<Error | null>\n\tready: ShallowRef<boolean>\n} {\n\tconst { queryStoreCache } = useKoraContext()\n\tconst data = shallowRef<readonly T[]>(EMPTY_ARRAY as readonly T[])\n\tconst error = shallowRef<Error | null>(null)\n\tconst ready = shallowRef(false)\n\n\twatch(\n\t\t() => {\n\t\t\tconst enabled = toValue(options?.enabled) !== false\n\t\t\tconst current = enabled ? toValue(query) : null\n\t\t\treturn current ? queryKey(current.getDescriptor()) : null\n\t\t},\n\t\t(key, _previous, onCleanup) => {\n\t\t\tconst current = key ? toValue(query) : null\n\t\t\tif (!current) {\n\t\t\t\tdata.value = EMPTY_ARRAY as readonly T[]\n\t\t\t\terror.value = null\n\t\t\t\tready.value = false\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tassertQueryReady(current as QueryBuilder<unknown>)\n\t\t\tconst queryStore = queryStoreCache.getOrCreate(current)\n\t\t\tconst sync = (): void => {\n\t\t\t\tconst failure = readQueryError(queryStore as QueryStore<unknown>)\n\t\t\t\tif (failure !== error.value) {\n\t\t\t\t\terror.value = failure\n\t\t\t\t\tif (failure) options?.onError?.(failure)\n\t\t\t\t}\n\t\t\t\tif (queryStore.hasSnapshot()) {\n\t\t\t\t\tdata.value = queryStore.getSnapshot()\n\t\t\t\t\tready.value = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst unsubscribe = queryStore.subscribe(sync)\n\t\t\t// A descriptor switch keeps the previous rows until the new query answers.\n\t\t\tready.value = false\n\t\t\tsync()\n\n\t\t\tonCleanup(() => {\n\t\t\t\tunsubscribe()\n\t\t\t\tqueryStoreCache.release(current as QueryBuilder<unknown>)\n\t\t\t})\n\t\t},\n\t\t{ immediate: true },\n\t)\n\n\treturn { data, error, ready }\n}\n\n/**\n * Reactive query composable backed by the local Kora store.\n *\n * The query and `enabled` may be plain values, refs or getters: pass a getter to\n * follow props or refs, and the composable re-subscribes when the query's descriptor\n * changes (and releases the old subscription). A failed query is reported through\n * `options.onError`, or `console.error` without one; use {@link useQueryState} to\n * render the error.\n *\n * @param query - A query builder, a ref to one, or a getter returning one (null disables)\n * @param options - `enabled` (value, ref or getter; default true) and `onError`\n * @returns A readonly shallow ref of the current rows\n *\n * @example\n * ```ts\n * const props = defineProps<{ done: boolean }>()\n * const todos = useQuery(() => app.todos.where({ completed: props.done }))\n * ```\n */\nexport function useQuery<T = CollectionRecord>(\n\tquery: QueryInput<T>,\n\toptions?: UseQueryOptions,\n): DeepReadonly<ShallowRef<readonly T[]>> {\n\tconst reporting: UseQueryOptions = {\n\t\t...options,\n\t\tonError:\n\t\t\toptions?.onError ??\n\t\t\t((failure: Error) => {\n\t\t\t\t// Never swallowed: without a handler the failure is at least logged.\n\t\t\t\tconsole.error('[Kora] useQuery failed:', failure)\n\t\t\t}),\n\t}\n\treturn readonly(useQuerySubscription(query, reporting).data)\n}\n\n/**\n * Like {@link useQuery}, but also returns the query's error and whether the first\n * result has arrived.\n *\n * @param query - A query builder, a ref to one, or a getter returning one\n * @param options - `enabled` and `onError`\n * @returns `{ data, error, ready }` as readonly refs\n */\nexport function useQueryState<T = CollectionRecord>(\n\tquery: QueryInput<T>,\n\toptions?: UseQueryOptions,\n): UseQueryStateResult<T> {\n\tconst { data, error, ready } = useQuerySubscription(query, options)\n\treturn { data: readonly(data), error: readonly(error), ready: readonly(ready) }\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\thasUnsavedChanges: false,\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\tstate.hasUnsavedChanges = snapshot.hasUnsavedChanges\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\tget hasUnsavedChanges() {\n\t\t\treturn state.hasUnsavedChanges\n\t\t},\n\t\tretrySave: () => controller().retrySave(),\n\t\tgetUnsavedState: () => controller().getUnsavedState(),\n\t}\n}\n","import type { AwarenessState } from '@korajs/sync'\nimport { subscribeRemoteAwarenessStates } from '@korajs/sync'\nimport { type ShallowRef, onScopeDispose, shallowRef, watch, watchEffect } 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":["import_core","import_vue","import_vue","import_store","import_vue","import_vue","import_vue","import_store","import_vue","controller","import_sync","import_vue"]}
|