@marktiderman/genesis-core 1.7.0 → 1.9.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.
Files changed (68) hide show
  1. package/README.md +182 -0
  2. package/dist/chunk-52T2EYXH.js +52 -0
  3. package/dist/chunk-52T2EYXH.js.map +1 -0
  4. package/dist/chunk-5ORRAXIV.js +30 -0
  5. package/dist/chunk-5ORRAXIV.js.map +1 -0
  6. package/dist/{chunk-ZKMAU6NN.js → chunk-BGTXN2E6.js} +5 -4
  7. package/dist/chunk-BGTXN2E6.js.map +1 -0
  8. package/dist/chunk-DF2UWEEB.js +38 -0
  9. package/dist/chunk-DF2UWEEB.js.map +1 -0
  10. package/dist/{chunk-Y475Z7BM.js → chunk-EF5BKT4B.js} +99 -21
  11. package/dist/chunk-EF5BKT4B.js.map +1 -0
  12. package/dist/chunk-HBAPYA5K.js +257 -0
  13. package/dist/chunk-HBAPYA5K.js.map +1 -0
  14. package/dist/{chunk-5NHR6ZXS.js → chunk-LG6TUBVM.js} +2 -2
  15. package/dist/chunk-LG6TUBVM.js.map +1 -0
  16. package/dist/{chunk-QFR6YJ3R.js → chunk-NMFABW4Y.js} +6 -5
  17. package/dist/chunk-NMFABW4Y.js.map +1 -0
  18. package/dist/{chunk-ADD2RIGA.js → chunk-NZPJI7FC.js} +4 -3
  19. package/dist/chunk-NZPJI7FC.js.map +1 -0
  20. package/dist/{chunk-Y3SCYMNN.js → chunk-OSPLIKSH.js} +7 -7
  21. package/dist/{chunk-Y3SCYMNN.js.map → chunk-OSPLIKSH.js.map} +1 -1
  22. package/dist/chunk-RCAP3Q4T.js +75 -0
  23. package/dist/chunk-RCAP3Q4T.js.map +1 -0
  24. package/dist/{chunk-OBUBP4BY.js → chunk-S2ZXUNXB.js} +30 -6
  25. package/dist/chunk-S2ZXUNXB.js.map +1 -0
  26. package/dist/dates.d.ts +84 -0
  27. package/dist/dates.js +117 -0
  28. package/dist/dates.js.map +1 -0
  29. package/dist/hooks/draft-controller.d.ts +158 -0
  30. package/dist/hooks/draft-controller.js +4 -0
  31. package/dist/hooks/draft-controller.js.map +1 -0
  32. package/dist/hooks/index.d.ts +45 -3
  33. package/dist/hooks/index.js +15 -11
  34. package/dist/hooks/mutation-mode.d.ts +14 -2
  35. package/dist/hooks/mutation-mode.js +2 -1
  36. package/dist/hooks/related-keys.d.ts +1 -1
  37. package/dist/hooks/use-draft.d.ts +33 -0
  38. package/dist/hooks/use-draft.js +5 -0
  39. package/dist/hooks/use-draft.js.map +1 -0
  40. package/dist/hooks/use-infinite-resource.d.ts +1 -1
  41. package/dist/hooks/use-infinite-resource.js +2 -1
  42. package/dist/hooks/use-live.d.ts +1 -1
  43. package/dist/hooks/use-one.d.ts +1 -1
  44. package/dist/hooks/use-one.js +2 -1
  45. package/dist/hooks/use-resource-form.d.ts +1 -1
  46. package/dist/hooks/use-resource-form.js +8 -7
  47. package/dist/hooks/use-resource.d.ts +1 -1
  48. package/dist/hooks/use-resource.js +5 -4
  49. package/dist/hooks/use-write.d.ts +45 -0
  50. package/dist/hooks/use-write.js +4 -0
  51. package/dist/hooks/use-write.js.map +1 -0
  52. package/dist/index.d.ts +77 -5
  53. package/dist/index.js +16 -12
  54. package/dist/provider/index.d.ts +87 -8
  55. package/dist/provider/index.js +3 -3
  56. package/dist/{read-outcome-C_9HbXvb.d.ts → read-outcome-B6nACXZ7.d.ts} +4 -1
  57. package/dist/schema/index.d.ts +2 -2
  58. package/dist/schema/index.js +1 -1
  59. package/dist/{types-CS9UpxQS.d.ts → types-B9DDfvWa.d.ts} +1 -1
  60. package/package.json +11 -2
  61. package/dist/chunk-5NHR6ZXS.js.map +0 -1
  62. package/dist/chunk-ADD2RIGA.js.map +0 -1
  63. package/dist/chunk-OBUBP4BY.js.map +0 -1
  64. package/dist/chunk-QFR6YJ3R.js.map +0 -1
  65. package/dist/chunk-V3GDAELU.js +0 -3
  66. package/dist/chunk-V3GDAELU.js.map +0 -1
  67. package/dist/chunk-Y475Z7BM.js.map +0 -1
  68. package/dist/chunk-ZKMAU6NN.js.map +0 -1
@@ -1,17 +1,21 @@
1
- import '../chunk-V3GDAELU.js';
2
- export { useInfiniteResource } from '../chunk-ADD2RIGA.js';
3
- export { buildArrayItemDefaults, useResourceForm } from '../chunk-Y3SCYMNN.js';
4
- import '../chunk-5NHR6ZXS.js';
5
- export { useOne } from '../chunk-ZKMAU6NN.js';
6
- export { useResource } from '../chunk-QFR6YJ3R.js';
7
- export { DEFAULT_LIVE_DEBOUNCE_MS } from '../chunk-KXVHDK3Q.js';
8
- export { DEFAULT_UNSAVED_CHANGES_MESSAGE, useUnsavedChangesGuard } from '../chunk-XQO4OH2N.js';
1
+ export { ViewerScope, clearViewerCache } from '../chunk-5ORRAXIV.js';
2
+ export { useResource } from '../chunk-NMFABW4Y.js';
9
3
  export { useWizard } from '../chunk-7KOLYF27.js';
10
- import '../chunk-RYEXWQFD.js';
11
- export { DEFAULT_UNDO_DELAY_MS, pendingWriteCount } from '../chunk-OBUBP4BY.js';
4
+ export { WRITE_FAILED, useWrite } from '../chunk-52T2EYXH.js';
5
+ export { useDraft } from '../chunk-DF2UWEEB.js';
6
+ export { useInfiniteResource } from '../chunk-NZPJI7FC.js';
7
+ export { buildArrayItemDefaults, useResourceForm } from '../chunk-OSPLIKSH.js';
8
+ export { DEFAULT_UNSAVED_CHANGES_MESSAGE, useUnsavedChangesGuard } from '../chunk-XQO4OH2N.js';
9
+ export { DEFAULT_UNDO_DELAY_MS, dropPendingWrites, flushPendingWrites, pendingWriteCount } from '../chunk-S2ZXUNXB.js';
10
+ import '../chunk-7NUL32W7.js';
12
11
  export { useCapabilities } from '../chunk-BQOJX67X.js';
12
+ export { useOne } from '../chunk-BGTXN2E6.js';
13
+ import '../chunk-RCAP3Q4T.js';
14
+ export { DEFAULT_LIVE_DEBOUNCE_MS } from '../chunk-KXVHDK3Q.js';
13
15
  import '../chunk-GGSXSI6Z.js';
14
16
  import '../chunk-ZYJUEJ4Z.js';
15
- import '../chunk-7NUL32W7.js';
17
+ import '../chunk-RYEXWQFD.js';
18
+ export { DEFAULT_DRAFT_DELAY_MS, DRAFT_NOT_SAVED, DraftController, isNetworkFailure, stableJson } from '../chunk-HBAPYA5K.js';
19
+ import '../chunk-LG6TUBVM.js';
16
20
  //# sourceMappingURL=index.js.map
17
21
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
1
  import { QueryClient } from '@tanstack/react-query';
2
- import { I as Identifier, B as BaseRecord, D as DataProvider } from '../types-CS9UpxQS.js';
2
+ import { a as Identifier, B as BaseRecord, D as DataProvider } from '../types-B9DDfvWa.js';
3
3
  import { A as AuditEntry } from '../types-C7FJtFXV.js';
4
4
  import '../form-types.js';
5
5
 
@@ -46,6 +46,18 @@ interface MutationModeOptions {
46
46
  declare function sameValue(a: unknown, b: unknown): boolean;
47
47
  /** The record as the cache has it now, from a detail entry or any list. */
48
48
  declare function cachedRecord(queryClient: QueryClient, resource: string, id: Identifier): BaseRecord | undefined;
49
+ /**
50
+ * Sends every optimistic or undoable write still waiting on this client now,
51
+ * and resolves once all have settled. Call it while the session that made
52
+ * them still holds (a sign-out action, before signing out).
53
+ */
54
+ declare function flushPendingWrites(queryClient: QueryClient): Promise<void>;
55
+ /**
56
+ * Drops every write on this client not yet sent, without reporting them: the
57
+ * viewer who made them is gone, so they must never be sent (or re-applied)
58
+ * under the next one. Writes already sending finish under the old session.
59
+ */
60
+ declare function dropPendingWrites(queryClient: QueryClient): void;
49
61
  /** Optimistic or undoable writes on `resource` not yet settled. */
50
62
  declare function pendingWriteCount(queryClient: QueryClient, resource: string): number;
51
63
  /**
@@ -116,4 +128,4 @@ declare const DROPPED_WRITE_MESSAGE = "This change was not saved: it was made on
116
128
  */
117
129
  declare function executeWrite<R extends BaseRecord | void>(args: ExecuteWriteArgs<R>): Promise<ExecuteWriteResult<R>>;
118
130
 
119
- export { DEFAULT_UNDO_DELAY_MS, DROPPED_WRITE_MESSAGE, type ExecuteWriteArgs, type ExecuteWriteResult, type MutationMode, type MutationModeOptions, type SendContext, type UndoableWrite, cachedRecord, executeWrite, invalidateResource, pendingWriteCount, providerServesUndo, sameValue };
131
+ export { DEFAULT_UNDO_DELAY_MS, DROPPED_WRITE_MESSAGE, type ExecuteWriteArgs, type ExecuteWriteResult, type MutationMode, type MutationModeOptions, type SendContext, type UndoableWrite, cachedRecord, dropPendingWrites, executeWrite, flushPendingWrites, invalidateResource, pendingWriteCount, providerServesUndo, sameValue };
@@ -1,5 +1,6 @@
1
- export { DEFAULT_UNDO_DELAY_MS, DROPPED_WRITE_MESSAGE, cachedRecord, executeWrite, invalidateResource, pendingWriteCount, providerServesUndo, sameValue } from '../chunk-OBUBP4BY.js';
1
+ export { DEFAULT_UNDO_DELAY_MS, DROPPED_WRITE_MESSAGE, cachedRecord, dropPendingWrites, executeWrite, flushPendingWrites, invalidateResource, pendingWriteCount, providerServesUndo, sameValue } from '../chunk-S2ZXUNXB.js';
2
2
  import '../chunk-BQOJX67X.js';
3
+ import '../chunk-RCAP3Q4T.js';
3
4
  import '../chunk-GGSXSI6Z.js';
4
5
  import '../chunk-ZYJUEJ4Z.js';
5
6
  //# sourceMappingURL=mutation-mode.js.map
@@ -1,4 +1,4 @@
1
- import { D as DataProvider, W as WriteEvent, j as InvalidationKey } from '../types-CS9UpxQS.js';
1
+ import { D as DataProvider, W as WriteEvent, I as InvalidationKey } from '../types-B9DDfvWa.js';
2
2
  import '../types-C7FJtFXV.js';
3
3
  import '../form-types.js';
4
4
 
@@ -0,0 +1,33 @@
1
+ import { DraftValue, DraftState, DraftController, DraftOptions } from './draft-controller.js';
2
+
3
+ interface UseDraftReturn<V extends DraftValue, R> extends DraftState<V, R> {
4
+ /** The editor's new value; saved a moment after the last change. */
5
+ set: (value: V) => void;
6
+ /** Save now. Never rejects; a failure shows in `status` and `error`. */
7
+ flush: () => Promise<void>;
8
+ /** The final write (a submit); see `DraftController.commit`. */
9
+ commit: DraftController<V, R>["commit"];
10
+ }
11
+ /**
12
+ * Autosave one draft row: saved a moment after each change, one write at a
13
+ * time, added on the first save that has something in it, merged into a row
14
+ * another tab started (`adopt`), and started again when the server's copy wins
15
+ * (`revision`). Leaving the page saves what's pending (and warns while it
16
+ * can't), and `commit` makes the final write. The app supplies the writes.
17
+ *
18
+ * ```tsx
19
+ * const draft = useDraft({
20
+ * seed: { row: entry, value: entry?.answers ?? {} },
21
+ * revision: `${entry?.id}:${entry?.status}`,
22
+ * enabled: entry?.status !== "sent",
23
+ * create: (answers) => api.addEntry(answers),
24
+ * update: (row, answers) => api.saveEntry(row.id, answers),
25
+ * toValue: (row) => row.answers,
26
+ * onSaved: (row) => queryClient.setQueryData(["entry", row.id], row),
27
+ * });
28
+ * <Editor key={draft.key} value={draft.value} onChange={draft.set} />
29
+ * ```
30
+ */
31
+ declare function useDraft<V extends DraftValue, R>(options: DraftOptions<V, R>): UseDraftReturn<V, R>;
32
+
33
+ export { type UseDraftReturn, useDraft };
@@ -0,0 +1,5 @@
1
+ export { useDraft } from '../chunk-DF2UWEEB.js';
2
+ import '../chunk-HBAPYA5K.js';
3
+ import '../chunk-LG6TUBVM.js';
4
+ //# sourceMappingURL=use-draft.js.map
5
+ //# sourceMappingURL=use-draft.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"use-draft.js"}
@@ -1,5 +1,5 @@
1
1
  import { UseInfiniteQueryResult, InfiniteData } from '@tanstack/react-query';
2
- import { n as SortParam, F as FilterParam, k as ListResult, L as ListParams, B as BaseRecord } from '../types-CS9UpxQS.js';
2
+ import { n as SortParam, F as FilterParam, k as ListResult, L as ListParams, B as BaseRecord } from '../types-B9DDfvWa.js';
3
3
  import { LiveOptions } from './use-live.js';
4
4
  import '../types-C7FJtFXV.js';
5
5
  import '../form-types.js';
@@ -1,4 +1,5 @@
1
- export { useInfiniteResource } from '../chunk-ADD2RIGA.js';
1
+ export { useInfiniteResource } from '../chunk-NZPJI7FC.js';
2
+ import '../chunk-RCAP3Q4T.js';
2
3
  import '../chunk-KXVHDK3Q.js';
3
4
  import '../chunk-GGSXSI6Z.js';
4
5
  import '../chunk-ZYJUEJ4Z.js';
@@ -1,5 +1,5 @@
1
1
  import { QueryKey } from '@tanstack/react-query';
2
- import { o as SubscribeParams, l as ResourceChangeEvent } from '../types-CS9UpxQS.js';
2
+ import { o as SubscribeParams, l as ResourceChangeEvent } from '../types-B9DDfvWa.js';
3
3
  import '../types-C7FJtFXV.js';
4
4
  import '../form-types.js';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { UseQueryResult } from '@tanstack/react-query';
2
- import { B as BaseRecord, I as Identifier } from '../types-CS9UpxQS.js';
2
+ import { B as BaseRecord, a as Identifier } from '../types-B9DDfvWa.js';
3
3
  import { LiveOptions } from './use-live.js';
4
4
  import '../types-C7FJtFXV.js';
5
5
  import '../form-types.js';
@@ -1,4 +1,5 @@
1
- export { useOne } from '../chunk-ZKMAU6NN.js';
1
+ export { useOne } from '../chunk-BGTXN2E6.js';
2
+ import '../chunk-RCAP3Q4T.js';
2
3
  import '../chunk-KXVHDK3Q.js';
3
4
  import '../chunk-GGSXSI6Z.js';
4
5
  import '../chunk-ZYJUEJ4Z.js';
@@ -1,6 +1,6 @@
1
1
  import { UseFormReturn } from 'react-hook-form';
2
2
  import { ResourceFormFieldDef } from '../form-types.js';
3
- import { j as InvalidationKey } from '../types-CS9UpxQS.js';
3
+ import { I as InvalidationKey } from '../types-B9DDfvWa.js';
4
4
  import { MutationModeOptions } from './mutation-mode.js';
5
5
  import '../types-C7FJtFXV.js';
6
6
  import '@tanstack/react-query';
@@ -1,13 +1,14 @@
1
- export { buildArrayItemDefaults, useResourceForm } from '../chunk-Y3SCYMNN.js';
2
- import '../chunk-5NHR6ZXS.js';
3
- import '../chunk-ZKMAU6NN.js';
4
- import '../chunk-KXVHDK3Q.js';
1
+ export { buildArrayItemDefaults, useResourceForm } from '../chunk-OSPLIKSH.js';
5
2
  import '../chunk-XQO4OH2N.js';
6
- import '../chunk-RYEXWQFD.js';
7
- import '../chunk-OBUBP4BY.js';
3
+ import '../chunk-S2ZXUNXB.js';
4
+ import '../chunk-7NUL32W7.js';
8
5
  import '../chunk-BQOJX67X.js';
6
+ import '../chunk-BGTXN2E6.js';
7
+ import '../chunk-RCAP3Q4T.js';
8
+ import '../chunk-KXVHDK3Q.js';
9
9
  import '../chunk-GGSXSI6Z.js';
10
10
  import '../chunk-ZYJUEJ4Z.js';
11
- import '../chunk-7NUL32W7.js';
11
+ import '../chunk-RYEXWQFD.js';
12
+ import '../chunk-LG6TUBVM.js';
12
13
  //# sourceMappingURL=use-resource-form.js.map
13
14
  //# sourceMappingURL=use-resource-form.js.map
@@ -1,5 +1,5 @@
1
1
  import { UseQueryResult, UseMutationResult } from '@tanstack/react-query';
2
- import { n as SortParam, F as FilterParam, j as InvalidationKey, k as ListResult, L as ListParams, I as Identifier, B as BaseRecord } from '../types-CS9UpxQS.js';
2
+ import { n as SortParam, F as FilterParam, I as InvalidationKey, k as ListResult, L as ListParams, a as Identifier, B as BaseRecord } from '../types-B9DDfvWa.js';
3
3
  import { MutationModeOptions } from './mutation-mode.js';
4
4
  import { LiveOptions } from './use-live.js';
5
5
  import '../types-C7FJtFXV.js';
@@ -1,9 +1,10 @@
1
- export { useResource } from '../chunk-QFR6YJ3R.js';
2
- import '../chunk-KXVHDK3Q.js';
3
- import '../chunk-OBUBP4BY.js';
1
+ export { useResource } from '../chunk-NMFABW4Y.js';
2
+ import '../chunk-S2ZXUNXB.js';
3
+ import '../chunk-7NUL32W7.js';
4
4
  import '../chunk-BQOJX67X.js';
5
+ import '../chunk-RCAP3Q4T.js';
6
+ import '../chunk-KXVHDK3Q.js';
5
7
  import '../chunk-GGSXSI6Z.js';
6
8
  import '../chunk-ZYJUEJ4Z.js';
7
- import '../chunk-7NUL32W7.js';
8
9
  //# sourceMappingURL=use-resource.js.map
9
10
  //# sourceMappingURL=use-resource.js.map
@@ -0,0 +1,45 @@
1
+ import { QueryClient, MutationOptions } from '@tanstack/react-query';
2
+ import { I as InvalidationKey } from '../types-B9DDfvWa.js';
3
+ import '../types-C7FJtFXV.js';
4
+ import '../form-types.js';
5
+
6
+ declare const WRITE_FAILED = "That didn't work. Try again.";
7
+ interface UseWriteOptions<A, R> {
8
+ /** Keys made stale once the write succeeds (matched by prefix), or a function of its result. */
9
+ invalidates?: InvalidationKey[] | ((result: R, args: A) => InvalidationKey[]);
10
+ onSuccess?: (result: R, args: A) => void;
11
+ /** The words shown for a failure. Default: a write error's own plain message. */
12
+ messageOf?: (error: unknown) => string;
13
+ }
14
+ interface UseWriteReturn<A, R> {
15
+ /**
16
+ * Runs the write. Resolves with its result; rejects with the error (also
17
+ * shown in `error`). While one runs, another call returns the same promise.
18
+ */
19
+ run: (args: A) => Promise<R>;
20
+ /** Runs the write and never rejects: resolves with the result, or undefined when it failed. */
21
+ fire: (args: A) => Promise<R | undefined>;
22
+ pending: boolean;
23
+ /** Why the last run failed, in plain words; null after a success or `reset`. */
24
+ error: string | null;
25
+ reset: () => void;
26
+ }
27
+ /**
28
+ * A one-off write that isn't a resource page's create, update or remove: a
29
+ * database function, `createOrAdopt`, several writes in a row. It invalidates
30
+ * what it made stale and reports failures in plain words.
31
+ *
32
+ * ```ts
33
+ * const sendLesson = useWrite(
34
+ * (lessonId: string) => callRpc(supabase, "send_lesson", { lesson_id: lessonId }),
35
+ * { invalidates: [["tasks"], lessonKeys.all] },
36
+ * );
37
+ * <Button onClick={() => sendLesson.fire(id)} disabled={sendLesson.pending}>Send</Button>
38
+ * {sendLesson.error && <InlineError>{sendLesson.error}</InlineError>}
39
+ * ```
40
+ */
41
+ declare function useWrite<A = void, R = unknown>(write: (args: A) => Promise<R>, options?: UseWriteOptions<A, R>): UseWriteReturn<A, R>;
42
+ /** useWrite's mutation: run the write, then invalidate and call `onSuccess`. */
43
+ declare function writeMutation<A, R>(queryClient: QueryClient, write: (args: A) => Promise<R>, options: UseWriteOptions<A, R>): MutationOptions<R, unknown, A>;
44
+
45
+ export { type UseWriteOptions, type UseWriteReturn, WRITE_FAILED, useWrite, writeMutation };
@@ -0,0 +1,4 @@
1
+ export { WRITE_FAILED, useWrite, writeMutation } from '../chunk-52T2EYXH.js';
2
+ import '../chunk-LG6TUBVM.js';
3
+ //# sourceMappingURL=use-write.js.map
4
+ //# sourceMappingURL=use-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"use-write.js"}
package/dist/index.d.ts CHANGED
@@ -1,21 +1,93 @@
1
- export { A as ArrayFilter, B as BaseRecord, a as BulkChange, b as BulkResult, C as CreateParams, c as CreateResult, D as DataProvider, d as DeleteParams, e as DeleteResult, F as FilterParam, G as GetManyParams, f as GetManyResult, g as GetOneParams, h as GetOneResult, H as HistoryParams, I as Identifier, i as ImportParams, j as InvalidationKey, L as ListParams, k as ListResult, N as NullFilter, P as PaginationParam, R as RangeFilter, l as ResourceChangeEvent, m as RowFailure, S as ScalarFilter, n as SortParam, o as SubscribeParams, U as UpdateParams, p as UpdateResult, W as WriteEvent } from './types-CS9UpxQS.js';
2
- export { D as DataReadError, a as DataReadErrorOptions, b as DataWriteError, c as DataWriteErrorOptions, R as ReadOutcome, W as WriteOutcome, i as isDataReadError, d as isDataWriteError, r as readFailureMessage } from './read-outcome-C_9HbXvb.js';
3
- export { DataProviderRoot, DataProviderRootProps, GenesisProvider, GenesisProviderProps, MockProviderOptions, PostgrestFieldErrors, SupabaseClient, SupabaseClientInput, SupabaseProviderOptions, SupabaseRealtimeChannel, SupabaseRealtimePayload, SupabaseResourceConfig, SupabaseWriteContext, createMockProvider, createSupabaseProvider, fieldErrorsFromPostgrest, readOutcomeFromCode, toDataWriteError, useDataProvider, useStorage, writeOutcomeFromCode } from './provider/index.js';
1
+ import { L as ListParams, a as Identifier } from './types-B9DDfvWa.js';
2
+ export { A as ArrayFilter, B as BaseRecord, b as BulkChange, c as BulkResult, C as CreateParams, d as CreateResult, D as DataProvider, e as DeleteParams, f as DeleteResult, F as FilterParam, G as GetManyParams, g as GetManyResult, h as GetOneParams, i as GetOneResult, H as HistoryParams, j as ImportParams, I as InvalidationKey, k as ListResult, N as NullFilter, P as PaginationParam, R as RangeFilter, l as ResourceChangeEvent, m as RowFailure, S as ScalarFilter, n as SortParam, o as SubscribeParams, U as UpdateParams, p as UpdateResult, W as WriteEvent } from './types-B9DDfvWa.js';
3
+ export { D as DataReadError, a as DataReadErrorOptions, b as DataWriteError, c as DataWriteErrorOptions, R as ReadOutcome, W as WriteOutcome, i as isDataReadError, d as isDataWriteError, r as readFailureMessage } from './read-outcome-B6nACXZ7.js';
4
+ export { CallRpcOptions, CreateOrAdoptOptions, DEFAULT_RPC_MESSAGES, DataProviderRoot, DataProviderRootProps, GenesisProvider, GenesisProviderProps, MockProviderOptions, PostgrestFieldErrors, RPC_FAILED, RpcClient, SupabaseClient, SupabaseClientInput, SupabaseProviderOptions, SupabaseRealtimeChannel, SupabaseRealtimePayload, SupabaseResourceConfig, SupabaseWriteContext, callRpc, createMockProvider, createOrAdopt, createSupabaseProvider, fieldErrorsFromPostgrest, readOutcomeFromCode, toDataWriteError, useDataProvider, useStorage, writeOutcomeFromCode } from './provider/index.js';
4
5
  export { S as StorageAdapter } from './types-DKcxHXxq.js';
5
6
  export { createLocalStorageAdapter, createMemoryStorageAdapter, createNoopStorageAdapter } from './storage/index.js';
6
7
  export { UseResourceOptions, UseResourceReturn, useResource } from './hooks/use-resource.js';
7
8
  export { UseOneOptions, useOne } from './hooks/use-one.js';
8
9
  export { InfinitePageParam, UseInfiniteResourceOptions, UseInfiniteResourceReturn, useInfiniteResource } from './hooks/use-infinite-resource.js';
9
10
  export { useCapabilities } from './hooks/use-capabilities.js';
11
+ export { UseWriteOptions, UseWriteReturn, WRITE_FAILED, useWrite } from './hooks/use-write.js';
12
+ export { UseDraftReturn, useDraft } from './hooks/use-draft.js';
13
+ export { DEFAULT_DRAFT_DELAY_MS, DRAFT_NOT_SAVED, DraftAdoption, DraftController, DraftOptions, DraftSeed, DraftState, DraftStatus, DraftValue, isNetworkFailure, stableJson } from './hooks/draft-controller.js';
14
+ export { ViewerScope, ViewerScopeProps, clearViewerCache } from './hooks/index.js';
10
15
  export { DEFAULT_LIVE_DEBOUNCE_MS, LiveOptions } from './hooks/use-live.js';
11
16
  export { UseResourceFormOptions, UseResourceFormReturn, buildArrayItemDefaults, useResourceForm } from './hooks/use-resource-form.js';
12
17
  export { UseWizardReturn, WizardStep, useWizard } from './hooks/use-wizard.js';
13
- export { DEFAULT_UNDO_DELAY_MS, MutationMode, MutationModeOptions, UndoableWrite, pendingWriteCount } from './hooks/mutation-mode.js';
18
+ export { DEFAULT_UNDO_DELAY_MS, MutationMode, MutationModeOptions, UndoableWrite, dropPendingWrites, flushPendingWrites, pendingWriteCount } from './hooks/mutation-mode.js';
14
19
  export { DEFAULT_UNSAVED_CHANGES_MESSAGE, UseUnsavedChangesGuardOptions, UseUnsavedChangesGuardReturn, useUnsavedChangesGuard } from './hooks/use-unsaved-changes-guard.js';
15
20
  export { FieldType, ResourceFormFieldDef, SelectOption, FieldType as WidgetHint } from './form-types.js';
16
21
  export { A as AuditEntry, D as DataRow, F as FieldPermissions, a as FieldReference, b as FieldSchema, c as FilterOperator, P as ProviderCapabilities, R as RecordComment, d as ResourceAccess, e as ResourceContract, f as ResourceRelation, g as ResourceSchema, h as ResourceSummary, i as RowAction, S as StorageType, V as VersionField } from './types-C7FJtFXV.js';
17
22
  export { decodeRecordKey, encodeRecordKey, keyFields } from './schema/index.js';
23
+ import { Query } from '@tanstack/react-query';
18
24
  export { titleCase } from './utils.js';
19
25
  import 'react';
20
- import '@tanstack/react-query';
21
26
  import 'react-hook-form';
27
+
28
+ /** Who and when a key is for. `viewer` is required; null means signed out. */
29
+ interface KeyScope {
30
+ viewer: string | null;
31
+ /** The group, practice or space the screen is filtered to. */
32
+ group?: string | null;
33
+ /** The person-day (YYYY-MM-DD) a "today" read is for. */
34
+ day?: string | null;
35
+ }
36
+ type Fields = Record<string, unknown>;
37
+ type QueryDefs = Record<string, (...args: never[]) => Fields>;
38
+ type ScopedKey<D extends string, K> = readonly [D, K, Fields];
39
+ /** A filter for `invalidateQueries` / `removeQueries` / `getQueriesData`. */
40
+ interface KeyFilter {
41
+ predicate: (query: Query) => boolean;
42
+ }
43
+ type QueryKeys<D extends string, Q extends QueryDefs> = {
44
+ /** Every key in the domain: `[domain]`. */
45
+ readonly all: readonly [D];
46
+ /** Builds keys for one scope. */
47
+ for(scope: KeyScope): {
48
+ [K in keyof Q]: (...args: Parameters<Q[K]>) => ScopedKey<D, K>;
49
+ };
50
+ /**
51
+ * Keys whose fields match `fields`: an equal value (`1` matches `"1"`,
52
+ * objects whatever their key order), an array field containing the value,
53
+ * or, for an array value, an array field containing every item. `kind`
54
+ * narrows it to one query.
55
+ */
56
+ where(fields: Fields, kind?: keyof Q): KeyFilter;
57
+ } & {
58
+ readonly [K in keyof Q]: {
59
+ readonly all: readonly [D, K];
60
+ };
61
+ };
62
+ /**
63
+ * The keys of one domain. Each query maps its arguments to the fields that
64
+ * make it distinct (sort arrays so order never makes two keys):
65
+ *
66
+ * ```ts
67
+ * export const worksheetKeys = defineQueryKeys("worksheet-items", {
68
+ * lessonParts: (people: string[]) => ({ people: [...people].sort() }),
69
+ * byEntry: (entryId: string) => ({ entryId }),
70
+ * });
71
+ * useQuery({ queryKey: worksheetKeys.for({ viewer }).lessonParts(people), … });
72
+ * queryClient.invalidateQueries(worksheetKeys.where({ people: personId }));
73
+ * queryClient.invalidateQueries(worksheetKeys.where({ entryId }, "byEntry"));
74
+ * queryClient.invalidateQueries({ queryKey: worksheetKeys.lessonParts.all });
75
+ * ```
76
+ */
77
+ declare function defineQueryKeys<const D extends string, Q extends QueryDefs>(domain: D, queries: Q): QueryKeys<D, Q>;
78
+ /**
79
+ * The keys Genesis's own hooks cache a resource under, for writing into or
80
+ * invalidating them by hand: `[resource]` covers them all.
81
+ */
82
+ declare function resourceKeys(resource: string): {
83
+ all: readonly [string];
84
+ lists: readonly [string, "list"];
85
+ list: (params: ListParams) => readonly [string, "list", ListParams];
86
+ details: readonly [string, "detail"];
87
+ /** Every projection of one record: `detail(id, select)` for any `select`. */
88
+ detailsOf: (id: Identifier | null | undefined) => readonly [string, "detail", Identifier | null | undefined];
89
+ detail: (id: Identifier | null | undefined, select?: string) => readonly [string, "detail", Identifier | null | undefined, string | undefined];
90
+ infinite: (params: unknown) => readonly [string, "infinite", unknown];
91
+ };
92
+
93
+ export { Identifier, type KeyFilter, type KeyScope, ListParams, type QueryKeys, type ScopedKey, defineQueryKeys, resourceKeys };
package/dist/index.js CHANGED
@@ -1,22 +1,26 @@
1
- export { createSupabaseProvider, fieldErrorsFromPostgrest, readOutcomeFromCode, toDataWriteError, writeOutcomeFromCode } from './chunk-Y475Z7BM.js';
1
+ export { DEFAULT_RPC_MESSAGES, RPC_FAILED, callRpc, createOrAdopt, createSupabaseProvider, fieldErrorsFromPostgrest, readOutcomeFromCode, toDataWriteError, writeOutcomeFromCode } from './chunk-EF5BKT4B.js';
2
2
  export { decodeRecordKey, encodeRecordKey, keyFields } from './chunk-KV2HW4G4.js';
3
3
  export { DataReadError, isDataReadError, readFailureMessage } from './chunk-HUNGCTRA.js';
4
4
  import './chunk-XCX2TRBL.js';
5
5
  import './chunk-65SXNHWE.js';
6
- import './chunk-V3GDAELU.js';
7
- export { useInfiniteResource } from './chunk-ADD2RIGA.js';
8
- export { buildArrayItemDefaults, useResourceForm } from './chunk-Y3SCYMNN.js';
9
- export { DataWriteError, isDataWriteError } from './chunk-5NHR6ZXS.js';
10
- export { useOne } from './chunk-ZKMAU6NN.js';
11
- export { useResource } from './chunk-QFR6YJ3R.js';
12
- export { DEFAULT_LIVE_DEBOUNCE_MS } from './chunk-KXVHDK3Q.js';
13
- export { DEFAULT_UNSAVED_CHANGES_MESSAGE, useUnsavedChangesGuard } from './chunk-XQO4OH2N.js';
6
+ export { ViewerScope, clearViewerCache } from './chunk-5ORRAXIV.js';
7
+ export { useResource } from './chunk-NMFABW4Y.js';
14
8
  export { useWizard } from './chunk-7KOLYF27.js';
15
- export { titleCase } from './chunk-RYEXWQFD.js';
16
- export { DEFAULT_UNDO_DELAY_MS, pendingWriteCount } from './chunk-OBUBP4BY.js';
9
+ export { WRITE_FAILED, useWrite } from './chunk-52T2EYXH.js';
10
+ export { useDraft } from './chunk-DF2UWEEB.js';
11
+ export { useInfiniteResource } from './chunk-NZPJI7FC.js';
12
+ export { buildArrayItemDefaults, useResourceForm } from './chunk-OSPLIKSH.js';
13
+ export { DEFAULT_UNSAVED_CHANGES_MESSAGE, useUnsavedChangesGuard } from './chunk-XQO4OH2N.js';
14
+ export { DEFAULT_UNDO_DELAY_MS, dropPendingWrites, flushPendingWrites, pendingWriteCount } from './chunk-S2ZXUNXB.js';
15
+ import './chunk-7NUL32W7.js';
17
16
  export { useCapabilities } from './chunk-BQOJX67X.js';
17
+ export { useOne } from './chunk-BGTXN2E6.js';
18
+ export { defineQueryKeys, resourceKeys } from './chunk-RCAP3Q4T.js';
19
+ export { DEFAULT_LIVE_DEBOUNCE_MS } from './chunk-KXVHDK3Q.js';
18
20
  export { DataProviderRoot, GenesisProvider, createMockProvider, useDataProvider, useStorage } from './chunk-GGSXSI6Z.js';
19
21
  export { createLocalStorageAdapter, createMemoryStorageAdapter, createNoopStorageAdapter } from './chunk-ZYJUEJ4Z.js';
20
- import './chunk-7NUL32W7.js';
22
+ export { titleCase } from './chunk-RYEXWQFD.js';
23
+ export { DEFAULT_DRAFT_DELAY_MS, DRAFT_NOT_SAVED, DraftController, isNetworkFailure, stableJson } from './chunk-HBAPYA5K.js';
24
+ export { DataWriteError, isDataWriteError } from './chunk-LG6TUBVM.js';
21
25
  //# sourceMappingURL=index.js.map
22
26
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
- import { D as DataProvider, I as Identifier, B as BaseRecord, j as InvalidationKey, W as WriteEvent } from '../types-CS9UpxQS.js';
2
- export { A as ArrayFilter, a as BulkChange, b as BulkResult, C as CreateParams, c as CreateResult, d as DeleteParams, e as DeleteResult, F as FilterParam, G as GetManyParams, f as GetManyResult, g as GetOneParams, h as GetOneResult, H as HistoryParams, i as ImportParams, L as ListParams, k as ListResult, N as NullFilter, P as PaginationParam, R as RangeFilter, l as ResourceChangeEvent, m as RowFailure, S as ScalarFilter, n as SortParam, o as SubscribeParams, U as UpdateParams, p as UpdateResult } from '../types-CS9UpxQS.js';
3
- import { D as DataReadError, R as ReadOutcome, b as DataWriteError, W as WriteOutcome } from '../read-outcome-C_9HbXvb.js';
4
- export { a as DataReadErrorOptions, c as DataWriteErrorOptions, i as isDataReadError, d as isDataWriteError, r as readFailureMessage } from '../read-outcome-C_9HbXvb.js';
1
+ import { D as DataProvider, a as Identifier, B as BaseRecord, I as InvalidationKey, W as WriteEvent } from '../types-B9DDfvWa.js';
2
+ export { A as ArrayFilter, b as BulkChange, c as BulkResult, C as CreateParams, d as CreateResult, e as DeleteParams, f as DeleteResult, F as FilterParam, G as GetManyParams, g as GetManyResult, h as GetOneParams, i as GetOneResult, H as HistoryParams, j as ImportParams, L as ListParams, k as ListResult, N as NullFilter, P as PaginationParam, R as RangeFilter, l as ResourceChangeEvent, m as RowFailure, S as ScalarFilter, n as SortParam, o as SubscribeParams, U as UpdateParams, p as UpdateResult } from '../types-B9DDfvWa.js';
3
+ import { D as DataReadError, R as ReadOutcome, b as DataWriteError, W as WriteOutcome } from '../read-outcome-B6nACXZ7.js';
4
+ export { a as DataReadErrorOptions, c as DataWriteErrorOptions, i as isDataReadError, d as isDataWriteError, r as readFailureMessage } from '../read-outcome-B6nACXZ7.js';
5
5
  import * as react from 'react';
6
6
  import { ReactNode } from 'react';
7
7
  import { QueryClient } from '@tanstack/react-query';
@@ -102,6 +102,10 @@ interface SupabaseRealtimeChannel {
102
102
  */
103
103
  interface SupabaseClientInput {
104
104
  from(table: string): unknown;
105
+ /** Database functions, for a resource whose `source` is an `rpc`. Any real client's `rpc` fits. */
106
+ rpc?(fn: string, args?: Record<string, unknown>, options?: {
107
+ count?: "exact" | "planned" | "estimated";
108
+ }): unknown;
105
109
  /** Supabase Realtime, for `subscribe`. Any real client's `channel` fits. */
106
110
  channel?(name: string): unknown;
107
111
  removeChannel?(channel: unknown): unknown;
@@ -179,6 +183,38 @@ interface SupabaseResourceConfig {
179
183
  * covers the resource.
180
184
  */
181
185
  realtime?: boolean;
186
+ /**
187
+ * Read this resource from somewhere else than its table: a view (joins,
188
+ * counts, aggregations) or a database function that returns rows. Writes
189
+ * still go to the table. Lists keep paging, filters, search, sort, totals
190
+ * and cursors, because PostgREST filters a view or a set-returning function
191
+ * like a table. Realtime still watches the table.
192
+ *
193
+ * Row-level security: a plain view runs as its owner and a SECURITY DEFINER
194
+ * function as its definer, so either one reads past RLS. Create the view
195
+ * `with (security_invoker = true)` and the function `security invoker` (or
196
+ * have it filter by `auth.uid()` itself), or this exposes every row.
197
+ *
198
+ * ```ts
199
+ * resources: {
200
+ * tasks: { source: "tasks_with_people" },
201
+ * course_progress: { source: { rpc: "group_progress", args: () => ({ group_id: currentGroup() }) } },
202
+ * }
203
+ * ```
204
+ */
205
+ source?: string | {
206
+ rpc: string;
207
+ args?: () => Record<string, unknown>;
208
+ };
209
+ /** The columns read when the caller names none, e.g. embedded joins: `"*, person:people(full_name)"`. Default `"*"`. */
210
+ select?: string;
211
+ /**
212
+ * With a `source` (or a `select` that embeds other tables), the table's own
213
+ * columns: creates and updates write only these, so a form built from the
214
+ * richer read row never sends its joined or computed columns to the table.
215
+ * Without it, an update writes only the columns the table's row has.
216
+ */
217
+ writeColumns?: readonly string[];
182
218
  }
183
219
  /** Options for `createSupabaseProvider`. All optional; none changes reads. */
184
220
  interface SupabaseProviderOptions {
@@ -256,9 +292,10 @@ declare function readOutcomeFromCode(code: string | null | undefined): ReadOutco
256
292
  *
257
293
  * - `42501` (insufficient privilege, including "new row violates row-level
258
294
  * security policy") → `forbidden`
259
- * - `22***` (data exception: bad type, out of range) and `23***` (integrity
260
- * constraint: `23505` unique, `23503` foreign key, `23502` not null,
261
- * `23514` check) → `invalid`
295
+ * - `23505` (unique violation) → `duplicate`
296
+ * - `22***` (data exception: bad type, out of range) and the other `23***`
297
+ * (integrity constraint: `23503` foreign key, `23502` not null, `23514`
298
+ * check) → `invalid`
262
299
  * - `PGRST301`–`PGRST303` (JWT missing, expired or rejected), `28000`,
263
300
  * `28P01` → `unauthenticated`
264
301
  * - `PGRST116` (one row was asked for and none came back) → `gone`
@@ -307,6 +344,48 @@ declare function fieldErrorsFromPostgrest(error: {
307
344
  */
308
345
  declare function toDataWriteError(error: unknown): DataWriteError;
309
346
 
347
+ /** Anything with Supabase's `rpc`. */
348
+ interface RpcClient {
349
+ rpc(fn: string, args?: Record<string, unknown>): PromiseLike<{
350
+ data: unknown;
351
+ error: unknown;
352
+ }>;
353
+ }
354
+ /** The words shown for a code when the caller gives none. A guard's own `raise exception` (P0001) keeps its words. */
355
+ declare const DEFAULT_RPC_MESSAGES: Readonly<Record<string, string>>;
356
+ declare const RPC_FAILED = "That didn't work. Try again.";
357
+ interface CallRpcOptions {
358
+ /** Words per error code, e.g. `{ "55000": "This course has already started." }`; these win over the defaults. */
359
+ messages?: Record<string, string>;
360
+ }
361
+ /**
362
+ * Calls a database function and returns its result. A failure throws a
363
+ * DataWriteError with the usual outcome and code, and words a person can
364
+ * read: yours for the code, a guard's own message (P0001), the defaults
365
+ * above, or a generic sentence. The raw error stays on `cause`.
366
+ */
367
+ declare function callRpc<T = unknown>(client: RpcClient, fn: string, args?: Record<string, unknown>, options?: CallRpcOptions): Promise<T>;
368
+ interface CreateOrAdoptOptions<T extends BaseRecord> {
369
+ /** The fields that make a row unique (its unique index), read from `data`. */
370
+ key: readonly (keyof T & string)[];
371
+ /**
372
+ * Changes to write over a row that was already there; return null to keep it
373
+ * as it is. It runs on the row as read just now, and the update isn't
374
+ * conditional: two callers merging into one row at once can each overwrite
375
+ * the other. Where that matters, merge in a database function instead.
376
+ */
377
+ merge?: (existing: T) => Partial<T> | null;
378
+ }
379
+ /**
380
+ * "One live row per key": creates the row, or, when one with the same key is
381
+ * already there (a `duplicate`), adopts it, optionally merging changes in.
382
+ * `adopted` says which. A duplicate you can't see is still an error.
383
+ */
384
+ declare function createOrAdopt<T extends BaseRecord>(provider: DataProvider, resource: string, data: Partial<T>, options: CreateOrAdoptOptions<T>): Promise<{
385
+ row: T;
386
+ adopted: boolean;
387
+ }>;
388
+
310
389
  /**
311
390
  * Puts a `DataProvider` in context, and nothing else. Mount it inside your
312
391
  * app's own `QueryClientProvider` and the Genesis hooks share that cache:
@@ -358,4 +437,4 @@ type GenesisProviderProps = {
358
437
  */
359
438
  declare function GenesisProvider({ children, provider, mock, storage, queryClient: queryClientProp, }: GenesisProviderProps): react.JSX.Element;
360
439
 
361
- export { BaseRecord, DataProvider, DataProviderRoot, type DataProviderRootProps, DataReadError, DataWriteError, GenesisProvider, type GenesisProviderProps, Identifier, InvalidationKey, type MockProviderOptions, type PostgrestFieldErrors, ReadOutcome, type SupabaseClient, type SupabaseClientInput, type SupabaseProviderOptions, type SupabaseRealtimeChannel, type SupabaseRealtimePayload, type SupabaseResourceConfig, type SupabaseWriteContext, WriteEvent, WriteOutcome, createMockProvider, createSupabaseProvider, fieldErrorsFromPostgrest, readOutcomeFromCode, toDataWriteError, useDataProvider, useStorage, writeOutcomeFromCode };
440
+ export { BaseRecord, type CallRpcOptions, type CreateOrAdoptOptions, DEFAULT_RPC_MESSAGES, DataProvider, DataProviderRoot, type DataProviderRootProps, DataReadError, DataWriteError, GenesisProvider, type GenesisProviderProps, Identifier, InvalidationKey, type MockProviderOptions, type PostgrestFieldErrors, RPC_FAILED, ReadOutcome, type RpcClient, type SupabaseClient, type SupabaseClientInput, type SupabaseProviderOptions, type SupabaseRealtimeChannel, type SupabaseRealtimePayload, type SupabaseResourceConfig, type SupabaseWriteContext, WriteEvent, WriteOutcome, callRpc, createMockProvider, createOrAdopt, createSupabaseProvider, fieldErrorsFromPostgrest, readOutcomeFromCode, toDataWriteError, useDataProvider, useStorage, writeOutcomeFromCode };
@@ -1,8 +1,8 @@
1
- export { createSupabaseProvider, fieldErrorsFromPostgrest, readOutcomeFromCode, toDataWriteError, writeOutcomeFromCode } from '../chunk-Y475Z7BM.js';
1
+ export { DEFAULT_RPC_MESSAGES, RPC_FAILED, callRpc, createOrAdopt, createSupabaseProvider, fieldErrorsFromPostgrest, readOutcomeFromCode, toDataWriteError, writeOutcomeFromCode } from '../chunk-EF5BKT4B.js';
2
2
  export { DataReadError, isDataReadError, readFailureMessage } from '../chunk-HUNGCTRA.js';
3
- export { DataWriteError, isDataWriteError } from '../chunk-5NHR6ZXS.js';
4
- import '../chunk-RYEXWQFD.js';
5
3
  export { DataProviderRoot, GenesisProvider, createMockProvider, useDataProvider, useStorage } from '../chunk-GGSXSI6Z.js';
6
4
  import '../chunk-ZYJUEJ4Z.js';
5
+ import '../chunk-RYEXWQFD.js';
6
+ export { DataWriteError, isDataWriteError } from '../chunk-LG6TUBVM.js';
7
7
  //# sourceMappingURL=index.js.map
8
8
  //# sourceMappingURL=index.js.map
@@ -9,13 +9,16 @@ import { D as DataRow } from './types-C7FJtFXV.js';
9
9
  * - `forbidden`: the row is visible and unchanged, but the app or the
10
10
  * database does not let this user make this change. Only reported when
11
11
  * that is proven, never assumed from "zero rows changed".
12
+ * - `duplicate`: a row with the same unique key already exists (`23505`).
13
+ * A caller keeping "one live row per key" (a draft, a natural-key upsert)
14
+ * adopts the existing row instead; `fields` still names the clashing field.
12
15
  * - `invalid`: the store rejected the value (type, constraint, not-null).
13
16
  * - `audit_failed`: the audit entry could not be written, so the edit was
14
17
  * rolled back with it.
15
18
  * - `unauthenticated`: no signed-in user, or the session expired.
16
19
  * - `error`: anything else. The edit did not commit.
17
20
  */
18
- type WriteOutcome = "conflict" | "gone" | "forbidden" | "invalid" | "audit_failed" | "unauthenticated" | "error";
21
+ type WriteOutcome = "conflict" | "gone" | "forbidden" | "duplicate" | "invalid" | "audit_failed" | "unauthenticated" | "error";
19
22
  interface DataWriteErrorOptions {
20
23
  /** The row as it is now, for a `conflict`. Only fields the user may read. */
21
24
  current?: DataRow;
@@ -1,7 +1,7 @@
1
1
  import { e as ResourceContract, D as DataRow } from '../types-C7FJtFXV.js';
2
2
  export { A as AuditEntry, F as FieldPermissions, a as FieldReference, b as FieldSchema, c as FilterOperator, P as ProviderCapabilities, R as RecordComment, d as ResourceAccess, f as ResourceRelation, g as ResourceSchema, h as ResourceSummary, i as RowAction, S as StorageType, V as VersionField } from '../types-C7FJtFXV.js';
3
- import { I as Identifier } from '../types-CS9UpxQS.js';
4
- export { D as DataReadError, a as DataReadErrorOptions, b as DataWriteError, c as DataWriteErrorOptions, R as ReadOutcome, W as WriteOutcome, i as isDataReadError, d as isDataWriteError, r as readFailureMessage } from '../read-outcome-C_9HbXvb.js';
3
+ import { a as Identifier } from '../types-B9DDfvWa.js';
4
+ export { D as DataReadError, a as DataReadErrorOptions, b as DataWriteError, c as DataWriteErrorOptions, R as ReadOutcome, W as WriteOutcome, i as isDataReadError, d as isDataWriteError, r as readFailureMessage } from '../read-outcome-B6nACXZ7.js';
5
5
  export { FieldType as WidgetHint } from '../form-types.js';
6
6
 
7
7
  /** The key of a contract as a list, whichever form `key` was declared in. */
@@ -1,5 +1,5 @@
1
1
  export { decodeRecordKey, encodeRecordKey, keyFields } from '../chunk-KV2HW4G4.js';
2
2
  export { DataReadError, isDataReadError, readFailureMessage } from '../chunk-HUNGCTRA.js';
3
- export { DataWriteError, isDataWriteError } from '../chunk-5NHR6ZXS.js';
3
+ export { DataWriteError, isDataWriteError } from '../chunk-LG6TUBVM.js';
4
4
  //# sourceMappingURL=index.js.map
5
5
  //# sourceMappingURL=index.js.map
@@ -347,4 +347,4 @@ interface DataProvider {
347
347
  invalidates?(event: WriteEvent): InvalidationKey[];
348
348
  }
349
349
 
350
- export type { ArrayFilter as A, BaseRecord as B, CreateParams as C, DataProvider as D, FilterParam as F, GetManyParams as G, HistoryParams as H, Identifier as I, ListParams as L, NullFilter as N, PaginationParam as P, RangeFilter as R, ScalarFilter as S, UpdateParams as U, WriteEvent as W, BulkChange as a, BulkResult as b, CreateResult as c, DeleteParams as d, DeleteResult as e, GetManyResult as f, GetOneParams as g, GetOneResult as h, ImportParams as i, InvalidationKey as j, ListResult as k, ResourceChangeEvent as l, RowFailure as m, SortParam as n, SubscribeParams as o, UpdateResult as p };
350
+ export type { ArrayFilter as A, BaseRecord as B, CreateParams as C, DataProvider as D, FilterParam as F, GetManyParams as G, HistoryParams as H, InvalidationKey as I, ListParams as L, NullFilter as N, PaginationParam as P, RangeFilter as R, ScalarFilter as S, UpdateParams as U, WriteEvent as W, Identifier as a, BulkChange as b, BulkResult as c, CreateResult as d, DeleteParams as e, DeleteResult as f, GetManyResult as g, GetOneParams as h, GetOneResult as i, ImportParams as j, ListResult as k, ResourceChangeEvent as l, RowFailure as m, SortParam as n, SubscribeParams as o, UpdateResult as p };