@korajs/react 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +243 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -13
- package/dist/index.d.ts +61 -13
- package/dist/index.js +247 -58
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { KoraEventEmitter } from '@korajs/core';
|
|
1
2
|
import { Store, CollectionRecord, QueryBuilder, CollectionAccessor } from '@korajs/store';
|
|
2
|
-
import { SyncEngine, CursorInfo,
|
|
3
|
+
import { SyncStatusInfo, SyncEngine, CursorInfo, AwarenessUser } from '@korajs/sync';
|
|
3
4
|
import { ReactNode } from 'react';
|
|
4
5
|
import * as Y from 'yjs';
|
|
5
6
|
|
|
@@ -10,6 +11,12 @@ import * as Y from 'yjs';
|
|
|
10
11
|
interface KoraAppLike {
|
|
11
12
|
/** Resolves when the store is open and collections are ready. */
|
|
12
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;
|
|
13
20
|
/** Get the underlying Store instance. */
|
|
14
21
|
getStore(): Store;
|
|
15
22
|
/** Get the underlying SyncEngine instance. Null if sync not configured. */
|
|
@@ -25,6 +32,10 @@ interface KoraContextValue {
|
|
|
25
32
|
syncEngine: SyncEngine | null;
|
|
26
33
|
/** The KoraApp instance (when provided via app prop). */
|
|
27
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;
|
|
28
39
|
}
|
|
29
40
|
/**
|
|
30
41
|
* Props for the KoraProvider component.
|
|
@@ -51,6 +62,25 @@ interface UseQueryOptions {
|
|
|
51
62
|
/** Set to false to disable the subscription (query won't execute). Defaults to true. */
|
|
52
63
|
enabled?: boolean;
|
|
53
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
|
+
}
|
|
54
84
|
/**
|
|
55
85
|
* Result from the useMutation hook.
|
|
56
86
|
*/
|
|
@@ -88,6 +118,10 @@ interface UseRichTextResult {
|
|
|
88
118
|
error: Error | null;
|
|
89
119
|
/** Remote collaborators' cursor positions in this field. Empty if no sync engine. */
|
|
90
120
|
cursors: CursorInfo[];
|
|
121
|
+
/** Publish local cursor/selection to connected collaborators. No-op without sync. */
|
|
122
|
+
setCursor: (anchor: number, head: number) => void;
|
|
123
|
+
/** Clear local cursor presence for this field. */
|
|
124
|
+
clearCursor: () => void;
|
|
91
125
|
}
|
|
92
126
|
|
|
93
127
|
/**
|
|
@@ -159,26 +193,33 @@ declare function useQuery<T = CollectionRecord>(query: QueryBuilder<T>, options?
|
|
|
159
193
|
/**
|
|
160
194
|
* React hook for performing mutations against the local Kora store.
|
|
161
195
|
*
|
|
162
|
-
* Returns `mutate` for fire-and-forget usage
|
|
163
|
-
*
|
|
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.
|
|
164
199
|
*
|
|
165
200
|
* @param mutationFn - An async function to execute (e.g., `app.todos.insert`)
|
|
201
|
+
* @param options - Optional optimistic/rollback and lifecycle callbacks
|
|
166
202
|
* @returns Object with mutate, mutateAsync, isLoading, error, and reset
|
|
167
203
|
*
|
|
168
204
|
* @example
|
|
169
205
|
* ```typescript
|
|
170
|
-
* const { mutate } = useMutation(app.todos.insert
|
|
171
|
-
*
|
|
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
|
+
* })
|
|
172
214
|
* ```
|
|
173
215
|
*/
|
|
174
|
-
declare function useMutation<TData, TArgs extends unknown[]>(mutationFn: (...args: TArgs) => Promise<TData>): UseMutationResult<TData, TArgs>;
|
|
216
|
+
declare function useMutation<TData, TArgs extends unknown[], TContext = void>(mutationFn: (...args: TArgs) => Promise<TData>, options?: UseMutationOptions<TData, TArgs, TContext>): UseMutationResult<TData, TArgs>;
|
|
175
217
|
|
|
176
218
|
/**
|
|
177
219
|
* React hook for monitoring the sync engine's connection status.
|
|
178
220
|
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* no sync engine is configured.
|
|
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.
|
|
182
223
|
*
|
|
183
224
|
* @returns Current sync status information
|
|
184
225
|
*
|
|
@@ -186,8 +227,6 @@ declare function useMutation<TData, TArgs extends unknown[]>(mutationFn: (...arg
|
|
|
186
227
|
* ```typescript
|
|
187
228
|
* const status = useSyncStatus()
|
|
188
229
|
* // status.status: 'connected' | 'syncing' | 'synced' | 'offline' | 'error'
|
|
189
|
-
* // status.pendingOperations: number
|
|
190
|
-
* // status.lastSyncedAt: number | null
|
|
191
230
|
* ```
|
|
192
231
|
*/
|
|
193
232
|
declare function useSyncStatus(): SyncStatusInfo;
|
|
@@ -207,9 +246,18 @@ declare function useSyncStatus(): SyncStatusInfo;
|
|
|
207
246
|
*/
|
|
208
247
|
declare function useCollection(name: string): CollectionAccessor;
|
|
209
248
|
|
|
249
|
+
interface UseRichTextOptions {
|
|
250
|
+
/** Presence identity broadcast with cursor updates. */
|
|
251
|
+
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
|
+
useDocChannel?: boolean;
|
|
257
|
+
}
|
|
210
258
|
/**
|
|
211
259
|
* Binds a richtext field to a shared Yjs document for editor integration.
|
|
212
260
|
*/
|
|
213
|
-
declare function useRichText(collectionName: string, recordId: string, fieldName: string): UseRichTextResult;
|
|
261
|
+
declare function useRichText(collectionName: string, recordId: string, fieldName: string, options?: UseRichTextOptions): UseRichTextResult;
|
|
214
262
|
|
|
215
|
-
export { type KoraAppLike, type KoraContextValue, KoraProvider, type KoraProviderProps, type UseMutationResult, type UseQueryOptions, type UseRichTextResult, useApp, useCollection, useMutation, useQuery, useRichText, useSyncStatus };
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { KoraEventEmitter } from '@korajs/core';
|
|
1
2
|
import { Store, CollectionRecord, QueryBuilder, CollectionAccessor } from '@korajs/store';
|
|
2
|
-
import { SyncEngine, CursorInfo,
|
|
3
|
+
import { SyncStatusInfo, SyncEngine, CursorInfo, AwarenessUser } from '@korajs/sync';
|
|
3
4
|
import { ReactNode } from 'react';
|
|
4
5
|
import * as Y from 'yjs';
|
|
5
6
|
|
|
@@ -10,6 +11,12 @@ import * as Y from 'yjs';
|
|
|
10
11
|
interface KoraAppLike {
|
|
11
12
|
/** Resolves when the store is open and collections are ready. */
|
|
12
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;
|
|
13
20
|
/** Get the underlying Store instance. */
|
|
14
21
|
getStore(): Store;
|
|
15
22
|
/** Get the underlying SyncEngine instance. Null if sync not configured. */
|
|
@@ -25,6 +32,10 @@ interface KoraContextValue {
|
|
|
25
32
|
syncEngine: SyncEngine | null;
|
|
26
33
|
/** The KoraApp instance (when provided via app prop). */
|
|
27
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;
|
|
28
39
|
}
|
|
29
40
|
/**
|
|
30
41
|
* Props for the KoraProvider component.
|
|
@@ -51,6 +62,25 @@ interface UseQueryOptions {
|
|
|
51
62
|
/** Set to false to disable the subscription (query won't execute). Defaults to true. */
|
|
52
63
|
enabled?: boolean;
|
|
53
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
|
+
}
|
|
54
84
|
/**
|
|
55
85
|
* Result from the useMutation hook.
|
|
56
86
|
*/
|
|
@@ -88,6 +118,10 @@ interface UseRichTextResult {
|
|
|
88
118
|
error: Error | null;
|
|
89
119
|
/** Remote collaborators' cursor positions in this field. Empty if no sync engine. */
|
|
90
120
|
cursors: CursorInfo[];
|
|
121
|
+
/** Publish local cursor/selection to connected collaborators. No-op without sync. */
|
|
122
|
+
setCursor: (anchor: number, head: number) => void;
|
|
123
|
+
/** Clear local cursor presence for this field. */
|
|
124
|
+
clearCursor: () => void;
|
|
91
125
|
}
|
|
92
126
|
|
|
93
127
|
/**
|
|
@@ -159,26 +193,33 @@ declare function useQuery<T = CollectionRecord>(query: QueryBuilder<T>, options?
|
|
|
159
193
|
/**
|
|
160
194
|
* React hook for performing mutations against the local Kora store.
|
|
161
195
|
*
|
|
162
|
-
* Returns `mutate` for fire-and-forget usage
|
|
163
|
-
*
|
|
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.
|
|
164
199
|
*
|
|
165
200
|
* @param mutationFn - An async function to execute (e.g., `app.todos.insert`)
|
|
201
|
+
* @param options - Optional optimistic/rollback and lifecycle callbacks
|
|
166
202
|
* @returns Object with mutate, mutateAsync, isLoading, error, and reset
|
|
167
203
|
*
|
|
168
204
|
* @example
|
|
169
205
|
* ```typescript
|
|
170
|
-
* const { mutate } = useMutation(app.todos.insert
|
|
171
|
-
*
|
|
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
|
+
* })
|
|
172
214
|
* ```
|
|
173
215
|
*/
|
|
174
|
-
declare function useMutation<TData, TArgs extends unknown[]>(mutationFn: (...args: TArgs) => Promise<TData>): UseMutationResult<TData, TArgs>;
|
|
216
|
+
declare function useMutation<TData, TArgs extends unknown[], TContext = void>(mutationFn: (...args: TArgs) => Promise<TData>, options?: UseMutationOptions<TData, TArgs, TContext>): UseMutationResult<TData, TArgs>;
|
|
175
217
|
|
|
176
218
|
/**
|
|
177
219
|
* React hook for monitoring the sync engine's connection status.
|
|
178
220
|
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* no sync engine is configured.
|
|
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.
|
|
182
223
|
*
|
|
183
224
|
* @returns Current sync status information
|
|
184
225
|
*
|
|
@@ -186,8 +227,6 @@ declare function useMutation<TData, TArgs extends unknown[]>(mutationFn: (...arg
|
|
|
186
227
|
* ```typescript
|
|
187
228
|
* const status = useSyncStatus()
|
|
188
229
|
* // status.status: 'connected' | 'syncing' | 'synced' | 'offline' | 'error'
|
|
189
|
-
* // status.pendingOperations: number
|
|
190
|
-
* // status.lastSyncedAt: number | null
|
|
191
230
|
* ```
|
|
192
231
|
*/
|
|
193
232
|
declare function useSyncStatus(): SyncStatusInfo;
|
|
@@ -207,9 +246,18 @@ declare function useSyncStatus(): SyncStatusInfo;
|
|
|
207
246
|
*/
|
|
208
247
|
declare function useCollection(name: string): CollectionAccessor;
|
|
209
248
|
|
|
249
|
+
interface UseRichTextOptions {
|
|
250
|
+
/** Presence identity broadcast with cursor updates. */
|
|
251
|
+
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
|
+
useDocChannel?: boolean;
|
|
257
|
+
}
|
|
210
258
|
/**
|
|
211
259
|
* Binds a richtext field to a shared Yjs document for editor integration.
|
|
212
260
|
*/
|
|
213
|
-
declare function useRichText(collectionName: string, recordId: string, fieldName: string): UseRichTextResult;
|
|
261
|
+
declare function useRichText(collectionName: string, recordId: string, fieldName: string, options?: UseRichTextOptions): UseRichTextResult;
|
|
214
262
|
|
|
215
|
-
export { type KoraAppLike, type KoraContextValue, KoraProvider, type KoraProviderProps, type UseMutationResult, type UseQueryOptions, type UseRichTextResult, useApp, useCollection, useMutation, useQuery, useRichText, useSyncStatus };
|
|
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 };
|