@vennbase/react 0.1.8

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 ADDED
@@ -0,0 +1,694 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { VENNBASE_INVITE_TARGET_PARAM } from "@vennbase/core";
3
+ import { createContext, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore, } from "react";
4
+ import { getDefaultRuntime, getIdleSnapshot, makeShareLinkKey, makeIncomingInviteKey, makeMembersKey, makeSavedRowKey, makeParentsKey, makeQueryKey, makeRowKey, snapshots, } from "./runtime";
5
+ import { VennbaseReactRuntime as Runtime } from "./runtime";
6
+ const RuntimeContext = createContext(null);
7
+ const noopSubscribe = () => () => undefined;
8
+ const noopRefresh = async () => undefined;
9
+ const noopFlush = async () => undefined;
10
+ function makeResourceResult(snapshot, refresh = noopRefresh) {
11
+ return {
12
+ data: snapshot.data,
13
+ error: snapshot.error,
14
+ refreshError: snapshot.refreshError,
15
+ isRefreshing: snapshot.isRefreshing ?? false,
16
+ status: snapshot.status,
17
+ refresh,
18
+ };
19
+ }
20
+ function useRuntime(db) {
21
+ const contextRuntime = useContext(RuntimeContext);
22
+ if (db) {
23
+ if (contextRuntime && contextRuntime.client === db) {
24
+ return contextRuntime;
25
+ }
26
+ return getDefaultRuntime(db);
27
+ }
28
+ if (!contextRuntime) {
29
+ throw new Error("VennbaseProvider is missing.");
30
+ }
31
+ return contextRuntime;
32
+ }
33
+ function useResource(resource) {
34
+ const snapshot = useSyncExternalStore(resource ? resource.subscribe : noopSubscribe, resource ? resource.getSnapshot : () => getIdleSnapshot(), () => getIdleSnapshot());
35
+ return {
36
+ ...snapshot,
37
+ refresh: resource ? resource.refresh : noopRefresh,
38
+ };
39
+ }
40
+ function useOptionalResource(enabled, resourceKey, resourceOwner, resolve) {
41
+ const resource = useMemo(() => (enabled ? resolve() : null), [enabled, resourceKey, resourceOwner]);
42
+ return useResource(resource);
43
+ }
44
+ function useSessionResource(runtime, enabled) {
45
+ return useOptionalResource(enabled, "session", runtime, () => runtime.getLoadOnce("session", () => runtime.client.getSession(), snapshots.session));
46
+ }
47
+ function blockedResourceResult(session) {
48
+ if (session.status === "error") {
49
+ return makeResourceResult({
50
+ error: session.error,
51
+ status: "error",
52
+ }, session.refresh);
53
+ }
54
+ if (session.status !== "success" || !session.data?.signedIn) {
55
+ return makeResourceResult({
56
+ status: "idle",
57
+ }, session.refresh);
58
+ }
59
+ return null;
60
+ }
61
+ function getInviteInputFromUrl() {
62
+ if (typeof window === "undefined") {
63
+ return null;
64
+ }
65
+ const url = new URL(window.location.href);
66
+ if (url.searchParams.has(VENNBASE_INVITE_TARGET_PARAM)) {
67
+ return url.toString();
68
+ }
69
+ return null;
70
+ }
71
+ function clearInviteUrl(clearInviteParams, inviteInput) {
72
+ if (typeof window === "undefined") {
73
+ return;
74
+ }
75
+ const current = new URL(window.location.href);
76
+ if (current.toString() !== inviteInput) {
77
+ return;
78
+ }
79
+ if (typeof clearInviteParams === "function") {
80
+ window.history.replaceState({}, "", clearInviteParams(current));
81
+ return;
82
+ }
83
+ current.search = "";
84
+ window.history.replaceState({}, "", `${current.pathname}${current.hash}`);
85
+ }
86
+ function hasRowRef(value) {
87
+ if (!value || typeof value !== "object") {
88
+ return false;
89
+ }
90
+ const candidate = value;
91
+ return !!candidate.ref
92
+ && typeof candidate.ref === "object"
93
+ && typeof candidate.ref.id === "string"
94
+ && typeof candidate.ref.collection === "string"
95
+ && typeof candidate.ref.baseUrl === "string";
96
+ }
97
+ function resolveRowInput(row) {
98
+ return hasRowRef(row) ? row.ref : row;
99
+ }
100
+ function getRowFromResult(result, getRow) {
101
+ const row = getRow
102
+ ? getRow(result)
103
+ : hasRowRef(result)
104
+ ? result.ref
105
+ : null;
106
+ if (!row) {
107
+ throw new Error("useSavedRow could not resolve a row. Pass getRow when returning non-row data.");
108
+ }
109
+ return row;
110
+ }
111
+ export function VennbaseProvider({ children, db, subscribeToActivity, }) {
112
+ const runtimeRef = useRef(null);
113
+ if (runtimeRef.current === null ||
114
+ runtimeRef.current.client !== db ||
115
+ runtimeRef.current.externalSubscribeToActivity !== subscribeToActivity) {
116
+ runtimeRef.current = new Runtime(db, subscribeToActivity);
117
+ }
118
+ return (_jsx(RuntimeContext.Provider, { value: runtimeRef.current, children: children }));
119
+ }
120
+ export function useVennbase() {
121
+ return useRuntime().client;
122
+ }
123
+ export function useCrdt(row, adapter) {
124
+ const connectionRef = useRef(null);
125
+ const rowKeyRef = useRef(null);
126
+ const snapshotRef = useRef(null);
127
+ const getSnapshot = () => {
128
+ const nextValue = adapter.getValue();
129
+ const nextVersion = adapter.getVersion();
130
+ const cached = snapshotRef.current;
131
+ if (cached && cached.version === nextVersion && cached.value === nextValue) {
132
+ return cached;
133
+ }
134
+ const nextSnapshot = {
135
+ value: nextValue,
136
+ version: nextVersion,
137
+ };
138
+ snapshotRef.current = nextSnapshot;
139
+ return nextSnapshot;
140
+ };
141
+ const snapshot = useSyncExternalStore(adapter.subscribe, getSnapshot, getSnapshot);
142
+ useEffect(() => {
143
+ if (!row) {
144
+ if (rowKeyRef.current !== null) {
145
+ adapter.reset();
146
+ rowKeyRef.current = null;
147
+ }
148
+ connectionRef.current = null;
149
+ return;
150
+ }
151
+ const nextRowKey = `${row.ref.baseUrl}:${row.ref.id}`;
152
+ if (rowKeyRef.current !== null && rowKeyRef.current !== nextRowKey) {
153
+ adapter.reset();
154
+ }
155
+ const connection = row.connectCrdt(adapter.callbacks);
156
+ connectionRef.current = connection;
157
+ rowKeyRef.current = nextRowKey;
158
+ return () => {
159
+ connection.disconnect();
160
+ if (connectionRef.current === connection) {
161
+ connectionRef.current = null;
162
+ }
163
+ };
164
+ }, [adapter, row]);
165
+ return {
166
+ ...snapshot,
167
+ status: row ? "connected" : "idle",
168
+ async flush() {
169
+ if (!connectionRef.current) {
170
+ await noopFlush();
171
+ return;
172
+ }
173
+ await connectionRef.current.flush();
174
+ },
175
+ };
176
+ }
177
+ export function useVennbaseReady(db, options = {}) {
178
+ const runtime = useRuntime(db);
179
+ const session = useSessionResource(runtime, options.enabled ?? true);
180
+ const blocked = blockedResourceResult(session);
181
+ const resource = useOptionalResource((options.enabled ?? true) && !blocked, "ready", runtime, () => runtime.getLoadOnce("ready", () => runtime.client.ensureReady()));
182
+ return blocked ?? resource;
183
+ }
184
+ export function useSession(db, options = {}) {
185
+ const runtime = useRuntime(db);
186
+ const resource = useSessionResource(runtime, options.enabled ?? true);
187
+ return {
188
+ ...resource,
189
+ session: resource.status === "success" ? resource.data : undefined,
190
+ async signIn() {
191
+ const user = await runtime.client.signIn();
192
+ await resource.refresh();
193
+ return user;
194
+ },
195
+ };
196
+ }
197
+ export function useCurrentUser(db, options = {}) {
198
+ const runtime = useRuntime(db);
199
+ const session = useSessionResource(runtime, options.enabled ?? true);
200
+ if (session.status === "error") {
201
+ return makeResourceResult({
202
+ error: session.error,
203
+ status: "error",
204
+ }, session.refresh);
205
+ }
206
+ if (session.status !== "success" || !session.data?.signedIn) {
207
+ return makeResourceResult({
208
+ status: "idle",
209
+ }, session.refresh);
210
+ }
211
+ return makeResourceResult({
212
+ data: session.data.user,
213
+ status: "success",
214
+ }, session.refresh);
215
+ }
216
+ export function useQuery(db, collection, options, hookOptions = {}) {
217
+ const runtime = useRuntime(db);
218
+ const session = useSessionResource(runtime, hookOptions.enabled ?? true);
219
+ const resourceKey = options ? makeQueryKey(collection, options) : null;
220
+ const blocked = blockedResourceResult(session);
221
+ const resource = useOptionalResource((hookOptions.enabled ?? true) && !!options && !blocked, resourceKey, runtime, () => runtime.getLive(resourceKey, () => runtime.client.query(collection, options), snapshots.queryRows));
222
+ return {
223
+ ...(blocked ?? resource),
224
+ rows: (blocked ?? resource).data ?? [],
225
+ };
226
+ }
227
+ export function useRow(db, row, options = {}) {
228
+ const runtime = useRuntime(db);
229
+ const session = useSessionResource(runtime, options.enabled ?? true);
230
+ const rowRef = row ? resolveRowInput(row) : null;
231
+ const resourceKey = rowRef ? makeRowKey(rowRef.collection, rowRef) : null;
232
+ const blocked = blockedResourceResult(session);
233
+ const resource = useOptionalResource((options.enabled ?? true) && !!rowRef && !blocked, resourceKey, runtime, () => runtime.getLive(resourceKey, () => runtime.client.getRow(rowRef), snapshots.row));
234
+ return blocked ?? resource;
235
+ }
236
+ export function useParents(db, row, options = {}) {
237
+ const runtime = useRuntime(db);
238
+ const session = useSessionResource(runtime, options.enabled ?? true);
239
+ const rowRef = row ? resolveRowInput(row) : null;
240
+ const resourceKey = rowRef ? makeParentsKey(rowRef) : null;
241
+ const blocked = blockedResourceResult(session);
242
+ const resource = useOptionalResource((options.enabled ?? true) && !!rowRef && !blocked, resourceKey, runtime, () => runtime.getLive(resourceKey, () => runtime.client.listParents(rowRef), snapshots.rowRefs));
243
+ return blocked ?? resource;
244
+ }
245
+ export function useMemberUsernames(db, row, options = {}) {
246
+ const runtime = useRuntime(db);
247
+ const session = useSessionResource(runtime, options.enabled ?? true);
248
+ const rowRef = row ? resolveRowInput(row) : null;
249
+ const resourceKey = rowRef ? makeMembersKey("usernames", rowRef) : null;
250
+ const blocked = blockedResourceResult(session);
251
+ const resource = useOptionalResource((options.enabled ?? true) && !!rowRef && !blocked, resourceKey, runtime, () => runtime.getLive(resourceKey, () => runtime.client.listMembers(rowRef), snapshots.memberUsernames));
252
+ return blocked ?? resource;
253
+ }
254
+ export function useDirectMembers(db, row, options = {}) {
255
+ const runtime = useRuntime(db);
256
+ const session = useSessionResource(runtime, options.enabled ?? true);
257
+ const rowRef = row ? resolveRowInput(row) : null;
258
+ const resourceKey = rowRef ? makeMembersKey("direct", rowRef) : null;
259
+ const blocked = blockedResourceResult(session);
260
+ const resource = useOptionalResource((options.enabled ?? true) && !!rowRef && !blocked, resourceKey, runtime, () => runtime.getLive(resourceKey, () => runtime.client.listDirectMembers(rowRef), snapshots.directMembers));
261
+ return blocked ?? resource;
262
+ }
263
+ export function useEffectiveMembers(db, row, options = {}) {
264
+ const runtime = useRuntime(db);
265
+ const session = useSessionResource(runtime, options.enabled ?? true);
266
+ const rowRef = row ? resolveRowInput(row) : null;
267
+ const resourceKey = rowRef ? makeMembersKey("effective", rowRef) : null;
268
+ const blocked = blockedResourceResult(session);
269
+ const resource = useOptionalResource((options.enabled ?? true) && !!rowRef && !blocked, resourceKey, runtime, () => runtime.getLive(resourceKey, () => runtime.client.listEffectiveMembers(rowRef), snapshots.effectiveMembers));
270
+ return blocked ?? resource;
271
+ }
272
+ export function useShareLink(db, row, options = {}) {
273
+ const runtime = useRuntime(db);
274
+ const session = useSessionResource(runtime, options.enabled ?? true);
275
+ const rowRef = row ? resolveRowInput(row) : null;
276
+ const resourceKey = rowRef ? makeShareLinkKey(rowRef) : null;
277
+ const blocked = blockedResourceResult(session);
278
+ const resource = useOptionalResource((options.enabled ?? true) && !!rowRef && !blocked, resourceKey, runtime, () => runtime.getLoadOnce(resourceKey, async () => {
279
+ const existing = await runtime.client.getExistingInviteToken(rowRef);
280
+ const invite = existing ?? runtime.client.createInviteToken(rowRef).value;
281
+ return runtime.client.createShareLink(rowRef, invite.token);
282
+ }));
283
+ const result = blocked ?? resource;
284
+ return {
285
+ shareLink: result.data,
286
+ error: result.error,
287
+ refreshError: result.refreshError,
288
+ isRefreshing: result.isRefreshing,
289
+ status: result.status,
290
+ refresh: result.refresh,
291
+ };
292
+ }
293
+ export function useAcceptInviteFromUrl(db, options = {}) {
294
+ const runtime = useRuntime(db);
295
+ const enabled = options.enabled ?? true;
296
+ const session = useSessionResource(runtime, options.enabled ?? true);
297
+ const detectedInviteInput = options.url ?? getInviteInputFromUrl();
298
+ const [latchedInviteInput, setLatchedInviteInput] = useState(detectedInviteInput);
299
+ const inviteInput = enabled
300
+ ? detectedInviteInput ?? latchedInviteInput
301
+ : null;
302
+ const resourceKey = inviteInput ? makeIncomingInviteKey(inviteInput) : null;
303
+ const clearInviteParamsOption = options.clearInviteParams ?? true;
304
+ const deliveryKey = inviteInput ?? null;
305
+ const onOpenRef = useRef(options.onOpen);
306
+ const acceptRef = useRef(options.accept);
307
+ const clearInviteParamsRef = useRef(clearInviteParamsOption);
308
+ const [deliveryEpoch, setDeliveryEpoch] = useState(0);
309
+ const currentDeliveryKey = deliveryKey ? `${deliveryKey}:${deliveryEpoch}` : null;
310
+ const deliveryStateRef = useRef({
311
+ key: null,
312
+ status: "idle",
313
+ error: undefined,
314
+ });
315
+ const [deliveryState, setDeliveryState] = useState(deliveryStateRef.current);
316
+ onOpenRef.current = options.onOpen;
317
+ acceptRef.current = options.accept;
318
+ clearInviteParamsRef.current = clearInviteParamsOption;
319
+ useEffect(() => {
320
+ if (!enabled) {
321
+ if (latchedInviteInput !== null) {
322
+ setLatchedInviteInput(null);
323
+ }
324
+ return;
325
+ }
326
+ if (detectedInviteInput && detectedInviteInput !== latchedInviteInput) {
327
+ setLatchedInviteInput(detectedInviteInput);
328
+ return;
329
+ }
330
+ if (!detectedInviteInput
331
+ && latchedInviteInput !== null
332
+ && deliveryState.status === "success") {
333
+ setLatchedInviteInput(null);
334
+ }
335
+ }, [deliveryState.status, detectedInviteInput, enabled, latchedInviteInput]);
336
+ const resource = useOptionalResource((options.enabled ?? true)
337
+ && !!inviteInput
338
+ && session.status === "success"
339
+ && !!session.data?.signedIn, resourceKey, runtime, () => runtime.getLoadOnce(resourceKey, () => {
340
+ const acceptInvite = acceptRef.current;
341
+ if (acceptInvite) {
342
+ return acceptInvite(inviteInput, runtime.client);
343
+ }
344
+ return runtime.client.acceptInvite(inviteInput);
345
+ }));
346
+ useEffect(() => {
347
+ if (!currentDeliveryKey) {
348
+ const nextState = {
349
+ key: null,
350
+ status: "idle",
351
+ error: undefined,
352
+ };
353
+ if (deliveryStateRef.current.key !== nextState.key
354
+ || deliveryStateRef.current.status !== nextState.status
355
+ || deliveryStateRef.current.error !== nextState.error) {
356
+ deliveryStateRef.current = nextState;
357
+ setDeliveryState(nextState);
358
+ }
359
+ return;
360
+ }
361
+ if (resource.status !== "success" || resource.data === undefined) {
362
+ const nextState = {
363
+ key: currentDeliveryKey,
364
+ status: "idle",
365
+ error: undefined,
366
+ };
367
+ if (deliveryStateRef.current.key !== nextState.key
368
+ || deliveryStateRef.current.status !== nextState.status
369
+ || deliveryStateRef.current.error !== nextState.error) {
370
+ deliveryStateRef.current = nextState;
371
+ setDeliveryState(nextState);
372
+ }
373
+ return;
374
+ }
375
+ if (deliveryStateRef.current.key === currentDeliveryKey
376
+ && (deliveryStateRef.current.status === "loading"
377
+ || deliveryStateRef.current.status === "success"
378
+ || deliveryStateRef.current.status === "error")) {
379
+ return;
380
+ }
381
+ let cancelled = false;
382
+ const openedResult = resource.data;
383
+ const nextLoadingState = {
384
+ key: currentDeliveryKey,
385
+ status: "loading",
386
+ error: undefined,
387
+ };
388
+ deliveryStateRef.current = nextLoadingState;
389
+ setDeliveryState(nextLoadingState);
390
+ void (async () => {
391
+ try {
392
+ await onOpenRef.current?.(openedResult);
393
+ if (cancelled) {
394
+ return;
395
+ }
396
+ const nextSuccessState = {
397
+ key: currentDeliveryKey,
398
+ status: "success",
399
+ error: undefined,
400
+ };
401
+ deliveryStateRef.current = nextSuccessState;
402
+ setDeliveryState(nextSuccessState);
403
+ if (clearInviteParamsRef.current) {
404
+ clearInviteUrl(clearInviteParamsRef.current, inviteInput);
405
+ }
406
+ }
407
+ catch (error) {
408
+ if (cancelled) {
409
+ return;
410
+ }
411
+ const nextErrorState = {
412
+ key: currentDeliveryKey,
413
+ status: "error",
414
+ error,
415
+ };
416
+ deliveryStateRef.current = nextErrorState;
417
+ setDeliveryState(nextErrorState);
418
+ }
419
+ })();
420
+ return () => {
421
+ cancelled = true;
422
+ };
423
+ }, [currentDeliveryKey, inviteInput, resource.data, resource.status]);
424
+ const refresh = async () => {
425
+ if (session.status !== "success" || !session.data?.signedIn) {
426
+ await session.refresh();
427
+ return;
428
+ }
429
+ await resource.refresh();
430
+ setDeliveryEpoch((epoch) => epoch + 1);
431
+ };
432
+ if (!enabled || !inviteInput) {
433
+ return {
434
+ hasInvite: false,
435
+ inviteInput: null,
436
+ ...makeResourceResult({
437
+ status: "idle",
438
+ }, noopRefresh),
439
+ };
440
+ }
441
+ if (session.status === "error") {
442
+ return {
443
+ hasInvite: true,
444
+ inviteInput,
445
+ ...makeResourceResult({
446
+ error: session.error,
447
+ status: "error",
448
+ }, refresh),
449
+ };
450
+ }
451
+ if (session.status !== "success") {
452
+ return {
453
+ hasInvite: true,
454
+ inviteInput,
455
+ ...makeResourceResult({
456
+ status: "loading",
457
+ }, refresh),
458
+ };
459
+ }
460
+ if (!session.data?.signedIn) {
461
+ return {
462
+ hasInvite: true,
463
+ inviteInput,
464
+ ...makeResourceResult({
465
+ status: "idle",
466
+ }, refresh),
467
+ };
468
+ }
469
+ if (resource.status !== "success" || resource.data === undefined) {
470
+ return {
471
+ ...resource,
472
+ hasInvite: true,
473
+ inviteInput,
474
+ refresh,
475
+ };
476
+ }
477
+ if (deliveryState.key !== currentDeliveryKey
478
+ || deliveryState.status === "idle"
479
+ || deliveryState.status === "loading") {
480
+ return {
481
+ hasInvite: true,
482
+ inviteInput,
483
+ ...makeResourceResult({
484
+ isRefreshing: resource.isRefreshing,
485
+ refreshError: resource.refreshError,
486
+ status: "loading",
487
+ }, refresh),
488
+ };
489
+ }
490
+ if (deliveryState.status === "error") {
491
+ return {
492
+ hasInvite: true,
493
+ inviteInput,
494
+ ...makeResourceResult({
495
+ error: deliveryState.error,
496
+ isRefreshing: resource.isRefreshing,
497
+ refreshError: resource.refreshError,
498
+ status: "error",
499
+ }, refresh),
500
+ };
501
+ }
502
+ return {
503
+ ...resource,
504
+ hasInvite: true,
505
+ inviteInput,
506
+ refresh,
507
+ };
508
+ }
509
+ export function useSavedRow(db, options) {
510
+ const runtime = useRuntime(db);
511
+ const session = useSessionResource(runtime, options.enabled ?? true);
512
+ const inviteInput = options.url ?? getInviteInputFromUrl();
513
+ const clearInviteParamsOption = options.clearInviteParams ?? true;
514
+ const sessionUser = session.status === "success" && session.data?.signedIn
515
+ ? session.data.user
516
+ : null;
517
+ const scopeKey = sessionUser ? `${sessionUser.username}:${options.key}` : null;
518
+ const resourceKey = sessionUser
519
+ ? makeSavedRowKey(sessionUser.username, options.key, inviteInput)
520
+ : null;
521
+ const [localData, setLocalData] = useState(null);
522
+ const clearedInviteRef = useRef(null);
523
+ const resource = useOptionalResource((options.enabled ?? true)
524
+ && !!resourceKey
525
+ && session.status === "success"
526
+ && !!session.data?.signedIn, resourceKey, runtime, () => runtime.getLoadOnce(resourceKey, async () => {
527
+ if (inviteInput) {
528
+ const opened = options.acceptInvite
529
+ ? await options.acceptInvite(inviteInput, runtime.client)
530
+ : await runtime.client.acceptInvite(inviteInput);
531
+ await runtime.client.saveRow(options.key, getRowFromResult(opened, options.getRow));
532
+ return opened;
533
+ }
534
+ try {
535
+ const savedRow = await runtime.client.openSavedRow(options.key);
536
+ if (!savedRow) {
537
+ return null;
538
+ }
539
+ return options.loadSavedRow
540
+ ? await options.loadSavedRow(savedRow, runtime.client)
541
+ : savedRow;
542
+ }
543
+ catch (error) {
544
+ await runtime.client.clearSavedRow(options.key);
545
+ throw error;
546
+ }
547
+ }));
548
+ useEffect(() => {
549
+ if (!inviteInput || resource.status !== "success") {
550
+ return;
551
+ }
552
+ if (clearInviteParamsOption && clearedInviteRef.current !== inviteInput) {
553
+ clearedInviteRef.current = inviteInput;
554
+ clearInviteUrl(clearInviteParamsOption, inviteInput);
555
+ }
556
+ }, [clearInviteParamsOption, inviteInput, resource.status]);
557
+ const localOverride = localData && localData.scopeKey === scopeKey
558
+ ? localData
559
+ : null;
560
+ const effective = localOverride
561
+ ? makeResourceResult({
562
+ data: localOverride.data,
563
+ status: "success",
564
+ })
565
+ : resource;
566
+ const refresh = async () => {
567
+ if (localOverride) {
568
+ setLocalData(null);
569
+ }
570
+ if (!(options.enabled ?? true)) {
571
+ return;
572
+ }
573
+ if (session.status !== "success" || !session.data?.signedIn) {
574
+ await session.refresh();
575
+ return;
576
+ }
577
+ await resource.refresh();
578
+ };
579
+ const save = async (result) => {
580
+ await runtime.client.saveRow(options.key, getRowFromResult(result, options.getRow));
581
+ if (scopeKey) {
582
+ setLocalData({ scopeKey, data: result });
583
+ }
584
+ };
585
+ const clear = async () => {
586
+ await runtime.client.clearSavedRow(options.key);
587
+ if (scopeKey) {
588
+ setLocalData({ scopeKey, data: null });
589
+ return;
590
+ }
591
+ setLocalData(null);
592
+ };
593
+ if (!(options.enabled ?? true)) {
594
+ return {
595
+ ...makeResourceResult({
596
+ status: "idle",
597
+ }, refresh),
598
+ clear,
599
+ hasInvite: !!inviteInput,
600
+ inviteInput,
601
+ save,
602
+ refresh,
603
+ };
604
+ }
605
+ if (session.status === "error") {
606
+ return {
607
+ ...makeResourceResult({
608
+ error: session.error,
609
+ status: "error",
610
+ }, refresh),
611
+ clear,
612
+ hasInvite: !!inviteInput,
613
+ inviteInput,
614
+ save,
615
+ refresh,
616
+ };
617
+ }
618
+ if (session.status !== "success") {
619
+ return {
620
+ ...makeResourceResult({
621
+ status: "loading",
622
+ }, refresh),
623
+ clear,
624
+ hasInvite: !!inviteInput,
625
+ inviteInput,
626
+ save,
627
+ refresh,
628
+ };
629
+ }
630
+ if (!session.data?.signedIn) {
631
+ return {
632
+ ...makeResourceResult({
633
+ status: "idle",
634
+ }, refresh),
635
+ clear,
636
+ hasInvite: !!inviteInput,
637
+ inviteInput,
638
+ save,
639
+ refresh,
640
+ };
641
+ }
642
+ return {
643
+ ...effective,
644
+ clear,
645
+ hasInvite: !!inviteInput,
646
+ inviteInput,
647
+ save,
648
+ refresh,
649
+ };
650
+ }
651
+ export function useMutation(mutation) {
652
+ const mutationRef = useRef(mutation);
653
+ mutationRef.current = mutation;
654
+ const [state, setState] = useState({
655
+ data: undefined,
656
+ error: undefined,
657
+ status: "idle",
658
+ });
659
+ return {
660
+ ...state,
661
+ async mutate(...args) {
662
+ setState((current) => ({
663
+ data: current.data,
664
+ error: undefined,
665
+ status: "loading",
666
+ }));
667
+ try {
668
+ const result = await mutationRef.current(...args);
669
+ setState({
670
+ data: result,
671
+ error: undefined,
672
+ status: "success",
673
+ });
674
+ return result;
675
+ }
676
+ catch (error) {
677
+ setState((current) => ({
678
+ data: current.data,
679
+ error,
680
+ status: "error",
681
+ }));
682
+ throw error;
683
+ }
684
+ },
685
+ reset() {
686
+ setState({
687
+ data: undefined,
688
+ error: undefined,
689
+ status: "idle",
690
+ });
691
+ },
692
+ };
693
+ }
694
+ //# sourceMappingURL=index.js.map