@korajs/react 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.d.ts CHANGED
@@ -1,42 +1,13 @@
1
- import { KoraEventEmitter } from '@korajs/core';
2
- import { Store, CollectionRecord, QueryBuilder, CollectionAccessor } from '@korajs/store';
3
- import { SyncStatusInfo, SyncEngine, CursorInfo, AwarenessUser } from '@korajs/sync';
1
+ import { KoraAppLike as KoraAppLike$1, KoraContextValue as KoraContextValue$1, UseMutationOptions as UseMutationOptions$1, UseMutationResultBase, UseQueryOptions as UseQueryOptions$1 } from '@korajs/core/bindings';
2
+ import { Store, QueryStoreCache, CollectionRecord, QueryBuilder, CollectionAccessor } from '@korajs/store';
3
+ import { SyncEngine, CursorInfo, SyncStatusInfo, AwarenessUser, AwarenessState } from '@korajs/sync';
4
4
  import { ReactNode } from 'react';
5
5
  import * as Y from 'yjs';
6
6
 
7
- /**
8
- * A Kora application instance returned by createApp().
9
- * Defined here to avoid a hard dependency on the kora meta-package.
10
- */
11
- interface KoraAppLike {
12
- /** Resolves when the store is open and collections are ready. */
13
- ready: Promise<void>;
14
- /** Framework event emitter (sync, store, merge, query). */
15
- events?: KoraEventEmitter;
16
- /** Sync control when sync is configured. */
17
- sync?: {
18
- subscribeStatus(listener: (status: SyncStatusInfo) => void): () => void;
19
- } | null;
20
- /** Get the underlying Store instance. */
21
- getStore(): Store;
22
- /** Get the underlying SyncEngine instance. Null if sync not configured. */
23
- getSyncEngine(): SyncEngine | null;
24
- }
25
- /**
26
- * Value provided by KoraProvider via React context.
27
- */
28
- interface KoraContextValue {
29
- /** The local Kora store instance */
30
- store: Store;
31
- /** Optional sync engine for remote synchronization */
32
- syncEngine: SyncEngine | null;
33
- /** The KoraApp instance (when provided via app prop). */
34
- app: KoraAppLike | null;
35
- /** App event emitter (when using app prop). */
36
- events: KoraEventEmitter | null;
37
- /** Event-driven sync status subscription from app.sync. */
38
- subscribeSyncStatus: ((listener: (status: SyncStatusInfo) => void) => () => void) | null;
39
- }
7
+ type KoraAppLike = KoraAppLike$1<Store, SyncEngine, QueryStoreCache>;
8
+ type KoraContextValue = KoraContextValue$1<Store, SyncEngine, QueryStoreCache>;
9
+ type UseQueryOptions = UseQueryOptions$1;
10
+ type UseMutationOptions<TData, TArgs extends unknown[], TContext = void> = UseMutationOptions$1<TData, TArgs, TContext>;
40
11
  /**
41
12
  * Props for the KoraProvider component.
42
13
  *
@@ -44,104 +15,33 @@ interface KoraContextValue {
44
15
  * explicit `store` + `syncEngine` props (advanced use case).
45
16
  */
46
17
  interface KoraProviderProps {
47
- /** A KoraApp instance from createApp(). Extracts store and syncEngine automatically. */
48
18
  app?: KoraAppLike;
49
- /** The local Kora store instance (alternative to app prop). */
50
19
  store?: Store;
51
- /** Optional sync engine for remote synchronization (used with store prop). */
52
20
  syncEngine?: SyncEngine | null;
53
- /** Fallback content to render while app.ready is resolving. Defaults to null. */
54
21
  fallback?: ReactNode;
55
- /** Child components */
56
22
  children?: ReactNode;
57
23
  }
58
- /**
59
- * Options for the useQuery hook.
60
- */
61
- interface UseQueryOptions {
62
- /** Set to false to disable the subscription (query won't execute). Defaults to true. */
63
- enabled?: boolean;
64
- }
65
- /**
66
- * Options for optimistic updates and rollback in {@link useMutation}.
67
- */
68
- interface UseMutationOptions<TData, TArgs extends unknown[], TContext = void> {
69
- /**
70
- * Runs before the mutation. Return a context value for rollback.
71
- */
72
- onMutate?: (...args: TArgs) => TContext | Promise<TContext>;
73
- /**
74
- * Reverts optimistic changes when the mutation fails.
75
- */
76
- onRollback?: (context: TContext, ...args: TArgs) => void | Promise<void>;
77
- /** Called when the mutation succeeds. */
78
- onSuccess?: (data: TData, ...args: TArgs) => void;
79
- /** Called when the mutation fails (after optional rollback). */
80
- onError?: (error: Error, ...args: TArgs) => void;
81
- /** Called after success or failure. */
82
- onSettled?: (data: TData | undefined, error: Error | null, ...args: TArgs) => void;
83
- }
84
- /**
85
- * Result from the useMutation hook.
86
- */
87
- interface UseMutationResult<TData, TArgs extends unknown[]> {
88
- /** Fire-and-forget mutation. Catches errors silently (sets error state). */
89
- mutate: (...args: TArgs) => void;
90
- /** Promise-returning mutation. Throws on error. */
91
- mutateAsync: (...args: TArgs) => Promise<TData>;
92
- /** Whether a mutation is currently in progress */
24
+ interface UseMutationResult<TData, TArgs extends unknown[]> extends UseMutationResultBase<TData, TArgs> {
93
25
  isLoading: boolean;
94
- /** The last error that occurred, or null */
95
26
  error: Error | null;
96
- /** Reset isLoading and error state */
97
- reset: () => void;
98
27
  }
99
- /**
100
- * Result from the useRichText hook.
101
- */
102
28
  interface UseRichTextResult {
103
- /** Shared Yjs document backing this field. */
104
29
  doc: Y.Doc;
105
- /** Y.Text instance to bind to editor integrations. */
106
30
  text: Y.Text;
107
- /** Undo local changes made to this richtext field. */
108
31
  undo: () => void;
109
- /** Redo previously undone local changes. */
110
32
  redo: () => void;
111
- /** True when undo can be applied. */
112
33
  canUndo: boolean;
113
- /** True when redo can be applied. */
114
34
  canRedo: boolean;
115
- /** True once the record field has been loaded into the Y.Doc. */
116
35
  ready: boolean;
117
- /** Last hook error (load/persist), if any. */
118
36
  error: Error | null;
119
- /** Remote collaborators' cursor positions in this field. Empty if no sync engine. */
120
37
  cursors: CursorInfo[];
121
- /** Publish local cursor/selection to connected collaborators. No-op without sync. */
122
38
  setCursor: (anchor: number, head: number) => void;
123
- /** Clear local cursor presence for this field. */
124
39
  clearCursor: () => void;
125
40
  }
126
41
 
127
42
  /**
128
43
  * Provides Kora store and optional sync engine to all child components.
129
44
  * Must wrap any component that uses Kora hooks (useQuery, useMutation, etc.).
130
- *
131
- * Accepts either an `app` prop (recommended) or explicit `store` + `syncEngine` props.
132
- *
133
- * When using the `app` prop, KoraProvider waits for `app.ready` before rendering
134
- * children. A `fallback` prop can be provided to show content while initializing.
135
- *
136
- * @example
137
- * ```typescript
138
- * // Recommended: pass the app object directly
139
- * const app = createApp({ schema })
140
- * <KoraProvider app={app}><App /></KoraProvider>
141
- *
142
- * // Advanced: pass store and syncEngine explicitly
143
- * <KoraProvider store={store} syncEngine={syncEngine}><App /></KoraProvider>
144
- * ```
145
45
  */
146
46
  declare function KoraProvider({ app, store, syncEngine, fallback, children, }: KoraProviderProps): ReactNode;
147
47
 
@@ -170,64 +70,16 @@ declare function useApp<T extends KoraAppLike = KoraAppLike>(): T;
170
70
 
171
71
  /**
172
72
  * React hook for reactive queries against the local Kora store.
173
- *
174
- * Returns data synchronously from the local store — no loading spinners needed.
175
- * Re-renders automatically when the query results change due to mutations.
176
- * Uses `useSyncExternalStore` for React 18+ concurrent mode safety.
177
- *
178
- * The generic parameter `T` is inferred from the QueryBuilder, providing
179
- * full type safety when used with typed collection accessors.
180
- *
181
- * @param query - A QueryBuilder instance (e.g., `app.todos.where({ done: false })`)
182
- * @param options - Optional configuration (e.g., `{ enabled: false }` to skip the query)
183
- * @returns Readonly array of matching records
184
- *
185
- * @example
186
- * ```typescript
187
- * const todos = useQuery(app.todos.where({ completed: false }).orderBy('createdAt'))
188
- * // todos is typed as readonly InferRecord<typeof todoFields>[]
189
- * ```
190
73
  */
191
74
  declare function useQuery<T = CollectionRecord>(query: QueryBuilder<T>, options?: UseQueryOptions): readonly T[];
192
75
 
193
76
  /**
194
77
  * React hook for performing mutations against the local Kora store.
195
- *
196
- * Returns `mutate` for fire-and-forget usage and `mutateAsync` when you need
197
- * to await the result. Optional `onMutate` / `onRollback` support optimistic
198
- * UI updates that revert if the mutation throws.
199
- *
200
- * @param mutationFn - An async function to execute (e.g., `app.todos.insert`)
201
- * @param options - Optional optimistic/rollback and lifecycle callbacks
202
- * @returns Object with mutate, mutateAsync, isLoading, error, and reset
203
- *
204
- * @example
205
- * ```typescript
206
- * const { mutate } = useMutation(app.todos.insert, {
207
- * onMutate: (data) => {
208
- * const previous = todos
209
- * setTodos((list) => [...list, { id: 'temp', ...data }])
210
- * return previous
211
- * },
212
- * onRollback: (previous) => setTodos(previous),
213
- * })
214
- * ```
215
78
  */
216
79
  declare function useMutation<TData, TArgs extends unknown[], TContext = void>(mutationFn: (...args: TArgs) => Promise<TData>, options?: UseMutationOptions<TData, TArgs, TContext>): UseMutationResult<TData, TArgs>;
217
80
 
218
81
  /**
219
82
  * React hook for monitoring the sync engine's connection status.
220
- *
221
- * Subscribes to sync events via `app.sync.subscribeStatus` (or the sync engine
222
- * emitter when using store-only mode) and re-renders only when status changes.
223
- *
224
- * @returns Current sync status information
225
- *
226
- * @example
227
- * ```typescript
228
- * const status = useSyncStatus()
229
- * // status.status: 'connected' | 'syncing' | 'synced' | 'offline' | 'error'
230
- * ```
231
83
  */
232
84
  declare function useSyncStatus(): SyncStatusInfo;
233
85
 
@@ -247,12 +99,7 @@ declare function useSyncStatus(): SyncStatusInfo;
247
99
  declare function useCollection(name: string): CollectionAccessor;
248
100
 
249
101
  interface UseRichTextOptions {
250
- /** Presence identity broadcast with cursor updates. */
251
102
  user?: AwarenessUser;
252
- /**
253
- * Use the incremental Yjs doc channel for live edits (recommended for large documents).
254
- * When omitted, the channel activates automatically once the snapshot exceeds the sync threshold.
255
- */
256
103
  useDocChannel?: boolean;
257
104
  }
258
105
  /**
@@ -260,4 +107,22 @@ interface UseRichTextOptions {
260
107
  */
261
108
  declare function useRichText(collectionName: string, recordId: string, fieldName: string, options?: UseRichTextOptions): UseRichTextResult;
262
109
 
263
- export { type KoraAppLike, type KoraContextValue, KoraProvider, type KoraProviderProps, type UseMutationOptions, type UseMutationResult, type UseQueryOptions, type UseRichTextOptions, type UseRichTextResult, useApp, useCollection, useMutation, useQuery, useRichText, useSyncStatus };
110
+ /**
111
+ * Sets the local user's collaborative presence state.
112
+ *
113
+ * Automatically cleans up presence on unmount.
114
+ */
115
+ declare function usePresence(user: {
116
+ name: string;
117
+ color: string;
118
+ avatar?: string;
119
+ } | null): void;
120
+
121
+ /**
122
+ * Returns all currently connected collaborators' awareness states.
123
+ *
124
+ * Excludes the local user — only returns remote peers.
125
+ */
126
+ declare function useCollaborators(): AwarenessState[];
127
+
128
+ export { type KoraAppLike, type KoraContextValue, KoraProvider, type KoraProviderProps, type UseMutationOptions, type UseMutationResult, type UseQueryOptions, type UseRichTextOptions, type UseRichTextResult, useApp, useCollaborators, useCollection, useMutation, usePresence, useQuery, useRichText, useSyncStatus };