@marktiderman/genesis-core 1.5.0 → 1.5.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.
Files changed (34) hide show
  1. package/README.md +31 -10
  2. package/dist/{chunk-IZT2O57C.js → chunk-3JSFTLDV.js} +35 -15
  3. package/dist/chunk-3JSFTLDV.js.map +1 -0
  4. package/dist/{chunk-DVW5GXWZ.js → chunk-6Q477CHB.js} +13 -11
  5. package/dist/chunk-6Q477CHB.js.map +1 -0
  6. package/dist/{chunk-RLY7TZUY.js → chunk-E5VYFAQO.js} +47 -13
  7. package/dist/chunk-E5VYFAQO.js.map +1 -0
  8. package/dist/chunk-F3BE7NGM.js +520 -0
  9. package/dist/chunk-F3BE7NGM.js.map +1 -0
  10. package/dist/hooks/index.d.ts +2 -2
  11. package/dist/hooks/index.js +3 -3
  12. package/dist/hooks/mutation-mode.d.ts +40 -30
  13. package/dist/hooks/mutation-mode.js +4 -1
  14. package/dist/hooks/related-keys.d.ts +2 -2
  15. package/dist/hooks/use-capabilities.d.ts +1 -1
  16. package/dist/hooks/use-one.d.ts +2 -2
  17. package/dist/hooks/use-resource-form.d.ts +10 -2
  18. package/dist/hooks/use-resource-form.js +3 -2
  19. package/dist/hooks/use-resource.d.ts +2 -2
  20. package/dist/hooks/use-resource.js +3 -2
  21. package/dist/index.d.ts +3 -3
  22. package/dist/index.js +4 -4
  23. package/dist/provider/index.d.ts +10 -6
  24. package/dist/provider/index.js +1 -1
  25. package/dist/{read-outcome-BQkYcV4t.d.ts → read-outcome-kgNhfuST.d.ts} +1 -1
  26. package/dist/schema/index.d.ts +4 -4
  27. package/dist/{types-C5bjsbxz.d.ts → types-5cuflvha.d.ts} +8 -0
  28. package/dist/{types-Dsqqr9s7.d.ts → types-DDOmG9hj.d.ts} +12 -1
  29. package/package.json +1 -1
  30. package/dist/chunk-DVW5GXWZ.js.map +0 -1
  31. package/dist/chunk-IZT2O57C.js.map +0 -1
  32. package/dist/chunk-QH4P5MI2.js +0 -278
  33. package/dist/chunk-QH4P5MI2.js.map +0 -1
  34. package/dist/chunk-RLY7TZUY.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/mutation-mode.ts"],"names":[],"mappings":"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","file":"chunk-F3BE7NGM.js","sourcesContent":["// ---------------------------------------------------------------------------\n// Mutation modes — when a write reaches the cache, and when the provider.\n//\n// - `pessimistic` (default): wait for the provider, then refetch. Today's\n// behaviour.\n// - `optimistic`: patch the TanStack Query cache at once, send the write, and\n// put the cache back (and report the error) if it fails.\n// - `undoable`: patch the cache at once and offer an undo (`onUndoable`);\n// the write is sent after a delay unless undone. A provider that serves\n// `undo` (capabilities `undo: true`) gets the write at once instead, and\n// the undo asks the provider to reverse it.\n//\n// Core has no UI: the undo toast is the caller's (`onUndoable`). genesis-ui's\n// ResourceForm and ResourcePage show a sonner toast.\n//\n// Pending writes belong to the QueryClient, not to the hook that started\n// them: a form that closes on success can still be undone from its toast.\n// ---------------------------------------------------------------------------\n\nimport type { QueryClient, QueryKey } from \"@tanstack/react-query\";\nimport type { BaseRecord, DataProvider, Identifier, ListResult } from \"../provider/types\";\nimport type { AuditEntry, ProviderCapabilities } from \"../schema/types\";\nimport { capabilitiesQueryKey } from \"./use-capabilities\";\n\nexport type MutationMode = \"pessimistic\" | \"optimistic\" | \"undoable\";\n\n/** How long an `undoable` write waits for an undo before it is sent. */\nexport const DEFAULT_UNDO_DELAY_MS = 5000;\n\n/** An undoable write, as handed to `onUndoable` so a UI can offer the undo. */\nexport interface UndoableWrite {\n resource: string;\n kind: \"create\" | \"update\" | \"delete\";\n /** The record's id; absent for a create (it has none until it is sent). */\n id?: Identifier;\n /**\n * - `delay`: the write has not been sent. `undo()` discards it; `commit()`\n * sends it now instead of waiting.\n * - `provider`: the write was sent at once, because the provider serves\n * `undo`. `undo()` asks the provider to reverse it; `commit()` does\n * nothing.\n */\n strategy: \"delay\" | \"provider\";\n /** How long the undo is offered, in ms (the toast's duration). */\n delayMs: number;\n /**\n * Take the write back. Resolves true when it was undone (or will never be\n * sent), false when it could not be: already sent under `delay` (the\n * window closed, it was committed, a later write on the same record sent\n * it first, or the page unloaded), already undone, or the provider's undo\n * failed (reported through `onError`). Works after the hook that made the\n * write has unmounted. Safe to call more than once.\n */\n undo: () => Promise<boolean>;\n /** Send a `delay` write now. */\n commit: () => void;\n}\n\nexport interface MutationModeOptions {\n /** Default `\"pessimistic\"`. */\n mutationMode?: MutationMode;\n /** How long an `undoable` write waits, in ms. Default 5000. */\n undoDelayMs?: number;\n /** Called with every `undoable` write, to show an undo control. */\n onUndoable?: (write: UndoableWrite) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Small helpers\n// ---------------------------------------------------------------------------\n\nfunction sameId(a: unknown, b: unknown): boolean {\n return a != null && b != null && String(a) === String(b);\n}\n\nfunction isListResult(value: unknown): value is ListResult<BaseRecord> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n Array.isArray((value as { data?: unknown }).data)\n );\n}\n\nfunction isDetailKeyFor(key: QueryKey, resource: string, id: Identifier): boolean {\n return key[0] === resource && key[1] === \"detail\" && sameId(key[2], id);\n}\n\n/** Structural equality for row values (JSON-like data, Dates). */\nexport function sameValue(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime();\n if (typeof a !== \"object\" || typeof b !== \"object\" || a === null || b === null) return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n if (Array.isArray(a)) {\n const other = b as unknown[];\n return a.length === other.length && a.every((item, i) => sameValue(item, other[i]));\n }\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (aKeys.length !== bKeys.length) return false;\n return aKeys.every(\n (k) => Object.prototype.hasOwnProperty.call(b, k) &&\n sameValue((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k]),\n );\n}\n\nfunction asError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\n/** The record as the cache has it now, from a detail entry or any list. */\nexport function cachedRecord(\n queryClient: QueryClient,\n resource: string,\n id: Identifier,\n): BaseRecord | undefined {\n for (const [key, value] of queryClient.getQueriesData<unknown>({ queryKey: [resource, \"detail\"] })) {\n if (isDetailKeyFor(key, resource, id) && value && typeof value === \"object\") return value as BaseRecord;\n }\n for (const [, value] of queryClient.getQueriesData<unknown>({ queryKey: [resource, \"list\"] })) {\n if (!isListResult(value)) continue;\n const found = value.data.find((row) => sameId(row.id, id));\n if (found) return found;\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// The registry — one per QueryClient\n//\n// Holds every optimistic/undoable write not yet settled, and the cache\n// patches they made. Patches are re-applied to any `[resource, \"list\" |\n// \"detail\", …]` data that arrives while they are pending (a refetch, a new\n// page, filter or search), so a deleted row stays gone and an edit stays\n// shown until the write settles. Because of that, refetching is always safe\n// and nothing waits for pending writes before invalidating.\n// ---------------------------------------------------------------------------\n\n/** One record's change, kept applied to the cache while its write is pending. */\ninterface Patch {\n resource: string;\n id: Identifier;\n kind: \"update\" | \"delete\";\n /** An update's values; the same object its write sends, so a rebase changes both. */\n data?: Record<string, unknown>;\n /** Per cache entry (query hash): the row just before this patch, and its list index. */\n before: Map<string, { row: BaseRecord; index: number }>;\n}\n\n/** One optimistic or undoable write that has not settled. */\ninterface Tracked {\n seq: number;\n queryClient: QueryClient;\n provider: DataProvider;\n resource: string;\n kind: \"create\" | \"update\" | \"delete\";\n /** `resource` + id: writes on the same record are sent in order. */\n rowKey?: string;\n patch?: Patch;\n /** Row-shaped values it will send (update); undefined when not row-shaped. */\n data?: Record<string, unknown>;\n /** The cached row just before this write's patch. */\n baseline?: BaseRecord;\n /**\n * - waiting: an undoable write in its delay\n * - queued: to be sent, behind earlier writes on the same record\n * - sending / done\n */\n state: \"waiting\" | \"queued\" | \"sending\" | \"done\";\n /** Sent with `keepalive` (because the page was unloading). */\n keepalive: boolean;\n /** Set when it was dropped because an earlier write it built on was taken back. */\n dropped: boolean;\n /** Send now: a waiting write skips its delay; `unloading` also skips the row queue. */\n flush: (unloading?: boolean) => void;\n /** Drop a waiting or queued write (see `dropped`). */\n drop: () => void;\n}\n\ninterface Registry {\n pending: Map<string, number>;\n patches: Patch[];\n writes: Tracked[];\n rowTails: Map<string, Promise<void>>;\n /** Cache data this module wrote, so the cache listener does not re-patch it. */\n produced: WeakSet<object>;\n /** True while this module is writing to the cache. */\n writing: boolean;\n unsubscribe?: () => void;\n}\n\nconst registries = new WeakMap<QueryClient, Registry>();\nlet nextSeq = 0;\n\nfunction registryFor(queryClient: QueryClient): Registry {\n let reg = registries.get(queryClient);\n if (!reg) {\n reg = {\n pending: new Map(),\n patches: [],\n writes: [],\n rowTails: new Map(),\n produced: new WeakSet(),\n writing: false,\n };\n registries.set(queryClient, reg);\n }\n return reg;\n}\n\n/** Optimistic or undoable writes on `resource` not yet settled. */\nexport function pendingWriteCount(queryClient: QueryClient, resource: string): number {\n return registries.get(queryClient)?.pending.get(resource) ?? 0;\n}\n\nfunction beginPending(reg: Registry, resource: string): void {\n reg.pending.set(resource, (reg.pending.get(resource) ?? 0) + 1);\n}\n\nfunction endPending(reg: Registry, resource: string): void {\n const left = Math.max(0, (reg.pending.get(resource) ?? 0) - 1);\n if (left === 0) reg.pending.delete(resource);\n else reg.pending.set(resource, left);\n}\n\n/**\n * Invalidate `[resource]`. Safe while optimistic/undoable writes on it are\n * pending: their patches are re-applied to whatever the refetch brings.\n */\nexport function invalidateResource(queryClient: QueryClient, resource: string): Promise<void> {\n return queryClient.invalidateQueries({ queryKey: [resource] });\n}\n\nfunction setProduced(reg: Registry, queryClient: QueryClient, key: QueryKey, value: unknown): void {\n const wasWriting = reg.writing;\n reg.writing = true;\n try {\n queryClient.setQueryData(key, value);\n } finally {\n reg.writing = wasWriting;\n }\n // Structural sharing may store a different object than `value`.\n const stored: unknown = queryClient.getQueryData(key);\n if (stored && typeof stored === \"object\") reg.produced.add(stored);\n}\n\nfunction applyUpdate(row: BaseRecord, data: Record<string, unknown>): BaseRecord {\n return { ...row, ...data, id: row.id };\n}\n\n/** `row` with `data`'s fields put back to what they were in `before`. */\nfunction revertFields(row: BaseRecord, data: Record<string, unknown>, before: BaseRecord): BaseRecord {\n const out: Record<string, unknown> = { ...row };\n for (const k of Object.keys(data)) {\n if (k === \"id\") continue;\n if (k in before) out[k] = before[k];\n else delete out[k];\n }\n return out as BaseRecord;\n}\n\n/**\n * Applies `patches`, in order, to one cache entry's data, recording each\n * patch's before-row for that entry. Returns the same object when nothing\n * applied.\n */\nfunction applyPatches(key: QueryKey, hash: string, value: unknown, patches: Patch[]): unknown {\n if (key[1] === \"list\" && isListResult(value)) {\n let rows = value.data;\n let total = value.total;\n let changed = false;\n for (const p of patches) {\n const index = rows.findIndex((row) => sameId(row.id, p.id));\n if (index < 0) continue;\n p.before.set(hash, { row: rows[index]!, index });\n if (p.kind === \"update\") {\n rows = rows.slice();\n rows[index] = applyUpdate(rows[index]!, p.data ?? {});\n } else {\n rows = rows.filter((_, i) => i !== index);\n if (typeof total === \"number\") total = Math.max(0, total - 1);\n }\n changed = true;\n }\n if (!changed) return value;\n return typeof total === \"number\" ? { ...value, data: rows, total } : { ...value, data: rows };\n }\n if (key[1] === \"detail\" && value && typeof value === \"object\") {\n let row = value as BaseRecord;\n let changed = false;\n for (const p of patches) {\n if (p.kind !== \"update\" || !sameId(key[2], p.id)) continue;\n p.before.set(hash, { row, index: -1 });\n row = applyUpdate(row, p.data ?? {});\n changed = true;\n }\n return changed ? row : value;\n }\n return value;\n}\n\n/** Re-applies pending patches to data that just landed in the cache. */\nfunction ensureListener(reg: Registry, queryClient: QueryClient): void {\n if (reg.unsubscribe) return;\n reg.unsubscribe = queryClient.getQueryCache().subscribe((event) => {\n if (reg.writing || event.type !== \"updated\" || event.action.type !== \"success\") return;\n const { queryKey: key, queryHash: hash } = event.query;\n const resource = key[0];\n if (typeof resource !== \"string\") return;\n const data: unknown = event.query.state.data;\n if (!data || typeof data !== \"object\" || reg.produced.has(data)) return;\n const patches = reg.patches.filter((p) => p.resource === resource);\n if (patches.length === 0) return;\n const next = applyPatches(key, hash, data, patches);\n if (next !== data) setProduced(reg, queryClient, key, next);\n });\n}\n\nfunction addPatch(reg: Registry, queryClient: QueryClient, patch: Patch): void {\n reg.patches.push(patch);\n ensureListener(reg, queryClient);\n for (const query of queryClient.getQueryCache().findAll({ queryKey: [patch.resource] })) {\n const value: unknown = query.state.data;\n const next = applyPatches(query.queryKey, query.queryHash, value, [patch]);\n if (next !== value) setProduced(reg, queryClient, query.queryKey, next);\n }\n}\n\nfunction dropPatchRecord(reg: Registry, patch: Patch): number {\n const index = reg.patches.indexOf(patch);\n if (index >= 0) reg.patches.splice(index, 1);\n if (reg.patches.length === 0 && reg.unsubscribe) {\n reg.unsubscribe();\n reg.unsubscribe = undefined;\n }\n return index;\n}\n\nfunction firstBefore(patch: Patch): { row: BaseRecord; index: number } | undefined {\n for (const value of patch.before.values()) return value;\n return undefined;\n}\n\n/**\n * Takes a patch back out of the cache, keeping every other pending patch on\n * the same record applied (field by field, not by restoring a whole saved\n * row).\n */\nfunction retractPatch(reg: Registry, queryClient: QueryClient, patch: Patch): void {\n const index = dropPatchRecord(reg, patch);\n if (index < 0) return;\n const onRow = (p: Patch) => p.resource === patch.resource && sameId(p.id, patch.id);\n const remaining = reg.patches.filter(onRow);\n\n // Later patches on the record recorded their before-rows on top of this\n // one: take its values out of them too.\n if (patch.kind === \"update\" && patch.data) {\n for (const later of reg.patches.slice(index).filter(onRow)) {\n for (const [hash, b] of later.before) {\n const src = patch.before.get(hash) ?? firstBefore(patch);\n if (src) later.before.set(hash, { ...b, row: revertFields(b.row, patch.data, src.row) });\n }\n }\n }\n\n const reapply = (row: BaseRecord) =>\n remaining.reduce((r, p) => (p.kind === \"update\" ? applyUpdate(r, p.data ?? {}) : r), row);\n\n for (const query of queryClient.getQueryCache().findAll({ queryKey: [patch.resource] })) {\n const key = query.queryKey;\n const value: unknown = query.state.data;\n const b = patch.before.get(query.queryHash);\n let next: unknown = value;\n if (key[1] === \"list\" && isListResult(value)) {\n const at = value.data.findIndex((row) => sameId(row.id, patch.id));\n if (patch.kind === \"update\") {\n const src = b ?? firstBefore(patch);\n if (at < 0 || !src || !patch.data) continue;\n const rows = value.data.slice();\n rows[at] = reapply(revertFields(rows[at]!, patch.data, src.row));\n next = { ...value, data: rows };\n } else {\n // A delete puts the row back where it was, unless a later delete of\n // the same record still hides it.\n if (at >= 0 || !b || remaining.some((p) => p.kind === \"delete\")) continue;\n const rows = value.data.slice();\n rows.splice(Math.min(b.index, rows.length), 0, reapply(b.row));\n next = {\n ...value,\n data: rows,\n ...(typeof value.total === \"number\" ? { total: value.total + 1 } : {}),\n };\n }\n } else if (\n key[1] === \"detail\" &&\n patch.kind === \"update\" &&\n patch.data &&\n sameId(key[2], patch.id) &&\n value &&\n typeof value === \"object\"\n ) {\n const src = b ?? firstBefore(patch);\n if (!src) continue;\n next = reapply(revertFields(value as BaseRecord, patch.data, src.row));\n }\n if (next !== value) setProduced(reg, queryClient, key, next);\n }\n}\n\n/**\n * A write was taken back (undone, or it failed): retract its patch, and fix\n * the later writes on the same record that have not been sent. A later\n * update that kept this write's values unchanged (its form opened from the\n * patched cache) gets them put back to what they were before; one whose\n * values are not row-shaped cannot be fixed, so it is dropped.\n */\nfunction takeBack(reg: Registry, write: Tracked): void {\n if (write.patch) retractPatch(reg, write.queryClient, write.patch);\n if (!write.rowKey || write.kind !== \"update\" || !write.patch?.data) return;\n const undone = write.patch.data;\n const before = write.baseline ?? firstBefore(write.patch)?.row ?? ({} as BaseRecord);\n const later = reg.writes.filter(\n (w) =>\n w.seq > write.seq &&\n w.rowKey === write.rowKey &&\n w.kind === \"update\" &&\n (w.state === \"waiting\" || w.state === \"queued\"),\n );\n for (const w of later) {\n if (!w.data) {\n w.drop();\n continue;\n }\n const rebased: Record<string, unknown> = {};\n const removed: string[] = [];\n for (const k of Object.keys(undone)) {\n if (k === \"id\" || !(k in w.data)) continue;\n const kept = sameValue(w.data[k], undone[k]) && w.baseline != null && sameValue(w.baseline[k], undone[k]);\n if (!kept) continue;\n if (k in before) rebased[k] = before[k];\n else removed.push(k);\n }\n if (Object.keys(rebased).length === 0 && removed.length === 0) continue;\n // w.data is also w.patch.data: rebase it in place, then show it.\n Object.assign(w.data, rebased);\n for (const k of removed) delete w.data[k];\n if (w.baseline) w.baseline = revertFields(w.baseline, undone, before);\n if (w.patch) refreshFields(reg, w.queryClient, w.patch, [...Object.keys(rebased), ...removed]);\n }\n}\n\n/**\n * After a patch's values changed in place: shows its new values for `keys`\n * in every cached copy of the record, except where a later patch on the\n * record sets the same field.\n */\nfunction refreshFields(reg: Registry, queryClient: QueryClient, patch: Patch, keys: string[]): void {\n const index = reg.patches.indexOf(patch);\n if (index < 0 || !patch.data) return;\n const data = patch.data;\n const overridden = new Set<string>();\n for (const p of reg.patches.slice(index + 1)) {\n if (p.resource === patch.resource && sameId(p.id, patch.id) && p.data) {\n for (const k of Object.keys(p.data)) overridden.add(k);\n }\n }\n const fields = keys.filter((k) => !overridden.has(k));\n if (fields.length === 0) return;\n const fix = (row: BaseRecord, hash: string): BaseRecord => {\n const out: Record<string, unknown> = { ...row };\n const before = (patch.before.get(hash) ?? firstBefore(patch))?.row;\n for (const k of fields) {\n if (k in data) out[k] = data[k];\n else if (before && k in before) out[k] = before[k];\n else delete out[k];\n }\n return out as BaseRecord;\n };\n for (const query of queryClient.getQueryCache().findAll({ queryKey: [patch.resource] })) {\n const key = query.queryKey;\n const value: unknown = query.state.data;\n let next: unknown = value;\n if (key[1] === \"list\" && isListResult(value)) {\n const at = value.data.findIndex((row) => sameId(row.id, patch.id));\n if (at < 0) continue;\n const rows = value.data.slice();\n rows[at] = fix(rows[at]!, query.queryHash);\n next = { ...value, data: rows };\n } else if (key[1] === \"detail\" && sameId(key[2], patch.id) && value && typeof value === \"object\") {\n next = fix(value as BaseRecord, query.queryHash);\n }\n if (next !== value) setProduced(reg, queryClient, key, next);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Page unload\n//\n// Waiting writes are sent when the page goes away (`beforeunload`, and\n// `pagehide` for mobile tab kills and bfcache), with `keepalive: true` in\n// their params so a fetch-based provider can let them outlive the page. The\n// \"Leave site?\" prompt shows only while a write is being sent without that\n// guarantee: its provider does not report `keepaliveWrites`, or it was\n// already on its way without keepalive.\n// ---------------------------------------------------------------------------\n\nconst allWrites = new Set<Tracked>();\n\nfunction servesKeepalive(write: Tracked): boolean {\n const caps = write.queryClient.getQueryData<ProviderCapabilities>(\n capabilitiesQueryKey(write.provider, write.resource),\n );\n return caps?.keepaliveWrites === true;\n}\n\nfunction flushForUnload(): void {\n const writes = [...allWrites].sort((a, b) => a.seq - b.seq);\n for (const write of writes) {\n if (write.state === \"waiting\" || write.state === \"queued\") write.flush(true);\n }\n}\n\nfunction onBeforeUnload(event: BeforeUnloadEvent): void {\n flushForUnload();\n const atRisk = [...allWrites].some((w) => w.state === \"sending\" && !(w.keepalive && servesKeepalive(w)));\n if (!atRisk) return;\n event.preventDefault();\n // Older browsers need returnValue set to show the prompt.\n event.returnValue = \"\";\n}\n\nfunction onPageHide(): void {\n flushForUnload();\n}\n\nfunction track(write: Tracked): void {\n allWrites.add(write);\n if (allWrites.size === 1 && typeof window !== \"undefined\") {\n window.addEventListener(\"beforeunload\", onBeforeUnload);\n window.addEventListener(\"pagehide\", onPageHide);\n }\n}\n\nfunction untrack(write: Tracked): void {\n if (!allWrites.delete(write)) return;\n if (allWrites.size === 0 && typeof window !== \"undefined\") {\n window.removeEventListener(\"beforeunload\", onBeforeUnload);\n window.removeEventListener(\"pagehide\", onPageHide);\n }\n}\n\n// ---------------------------------------------------------------------------\n// The engine\n// ---------------------------------------------------------------------------\n\n/** What `send` is given when the write goes out. */\nexport interface SendContext {\n /**\n * The row-shaped values to send, when `data` was given. They can differ\n * from `data`: an earlier write on the record that this one built on was\n * taken back, and its values were put back. Send these.\n */\n data?: Record<string, unknown>;\n /** The page is unloading: pass `keepalive: true` to the provider. */\n keepalive: boolean;\n}\n\nexport interface ExecuteWriteArgs<R extends BaseRecord | void> {\n queryClient: QueryClient;\n provider: DataProvider;\n resource: string;\n kind: \"create\" | \"update\" | \"delete\";\n id?: Identifier;\n /**\n * The values to merge into the cached row (update). Leave out to patch\n * nothing, e.g. when the values are form-shaped and the row is not.\n */\n data?: Record<string, unknown>;\n mode: MutationMode;\n undoDelayMs?: number;\n onUndoable?: (write: UndoableWrite) => void;\n /** Sends the write. */\n send: (context: SendContext) => Promise<{ record: R; audit?: AuditEntry }>;\n /** After the write committed. Invalidates and calls success callbacks. */\n committed: (record: R) => Promise<void> | void;\n /** A write that failed (or was dropped) after the caller was told it went through. */\n failedLater: (error: Error) => void;\n}\n\nexport type ExecuteWriteResult<R> =\n | { status: \"committed\"; record: R }\n | { status: \"applied\" };\n\nconst CAPABILITIES_QUERY = (provider: DataProvider, resource: string) => ({\n // The same key as useCapabilities, so the answer is shared.\n queryKey: capabilitiesQueryKey(provider, resource),\n queryFn: () => provider.capabilities!(resource),\n staleTime: Infinity,\n // A write may wait on this answer; an app's default retries would hold\n // it for seconds.\n retry: false as const,\n});\n\n/**\n * Whether `provider` serves `undo` for `resource`, from its capabilities\n * (useCapabilities' key, so the answer is shared, and scoped to this\n * provider: a swapped-out provider's capabilities never offer undo).\n * @internal Exported for tests.\n */\nexport async function providerServesUndo(\n queryClient: QueryClient,\n provider: DataProvider,\n resource: string,\n): Promise<boolean> {\n if (!provider.undo || !provider.capabilities) return false;\n try {\n const caps = await queryClient.fetchQuery<ProviderCapabilities>(CAPABILITIES_QUERY(provider, resource));\n return caps?.undo === true;\n } catch {\n return false;\n }\n}\n\n/** A later write that built on one that was taken back. */\nexport const DROPPED_WRITE_MESSAGE =\n \"This change was not saved: it was made on top of an earlier change that was undone or failed. Please make it again.\";\n\n/**\n * Runs one write in the given mode.\n *\n * - `pessimistic`: sends it and waits; a failure rejects.\n * - `optimistic` / `undoable`: resolves `{ status: \"applied\" }` as soon as\n * the cache is patched. A later failure rolls the patch back and goes to\n * `failedLater`, never to the returned promise.\n *\n * Writes on the same record are sent one after another, in the order they\n * were made; sending one first sends the earlier ones still waiting.\n */\nexport async function executeWrite<R extends BaseRecord | void>(\n args: ExecuteWriteArgs<R>,\n): Promise<ExecuteWriteResult<R>> {\n const { queryClient, provider, resource, kind, id, mode, send, committed, failedLater } = args;\n\n if (mode === \"pessimistic\") {\n const { record } = await send({ data: args.data, keepalive: false });\n await committed(record);\n return { status: \"committed\", record };\n }\n\n const viaProviderUndo = mode === \"undoable\" && (await providerServesUndo(queryClient, provider, resource));\n // Warm the capabilities answer, so the unload handler can tell (without\n // waiting) whether this provider keeps writes alive.\n if (provider.capabilities && !queryClient.getQueryData(capabilitiesQueryKey(provider, resource))) {\n void queryClient.prefetchQuery(CAPABILITIES_QUERY(provider, resource));\n }\n\n const reg = registryFor(queryClient);\n const hasRow = kind !== \"create\" && id != null;\n const data = args.data ? { ...args.data } : undefined;\n let patch: Patch | undefined;\n if (hasRow && kind === \"update\" && data) patch = { resource, id: id!, kind: \"update\", data, before: new Map() };\n else if (hasRow && kind === \"delete\") patch = { resource, id: id!, kind: \"delete\", before: new Map() };\n // A create has no cache entry yet: its id and its place in each sorted,\n // filtered list are the server's to say.\n\n const delayMs = Math.max(0, args.undoDelayMs ?? DEFAULT_UNDO_DELAY_MS);\n let timer: ReturnType<typeof setTimeout> | undefined;\n let resolveSent: (result: { record: R; audit?: AuditEntry } | undefined) => void = () => {};\n const sent = new Promise<{ record: R; audit?: AuditEntry } | undefined>((resolve) => {\n resolveSent = resolve;\n });\n\n const write: Tracked = {\n seq: ++nextSeq,\n queryClient,\n provider,\n resource,\n kind,\n rowKey: hasRow ? `${resource}\\u0000${String(id)}` : undefined,\n patch,\n data: kind === \"update\" ? data : undefined,\n baseline: hasRow ? cachedRecord(queryClient, resource, id!) : undefined,\n state: \"queued\",\n keepalive: false,\n dropped: false,\n flush: () => {},\n drop: () => {},\n };\n\n const settle = () => {\n write.state = \"done\";\n clearTimeout(timer);\n const at = reg.writes.indexOf(write);\n if (at >= 0) reg.writes.splice(at, 1);\n untrack(write);\n endPending(reg, resource);\n };\n\n const sendNow = async (keepalive: boolean): Promise<void> => {\n if (write.state !== \"queued\") return;\n write.state = \"sending\";\n write.keepalive = keepalive;\n let result: { record: R; audit?: AuditEntry };\n try {\n result = await send({ data: write.data, keepalive });\n } catch (error) {\n settle();\n takeBack(reg, write);\n void invalidateResource(queryClient, resource);\n failedLater(asError(error));\n resolveSent(undefined);\n return;\n }\n // The server has it now; the refetch `committed` starts replaces the patch.\n if (patch) dropPatchRecord(reg, patch);\n settle();\n try {\n await committed(result.record);\n } catch (error) {\n // The write did commit; only a callback failed.\n console.error(`[genesis] after-write callback failed for \"${resource}\":`, error);\n }\n resolveSent(result);\n };\n\n const enqueue = () => {\n if (!write.rowKey) {\n void sendNow(false);\n return;\n }\n const key = write.rowKey;\n const previous = reg.rowTails.get(key);\n const run = () => sendNow(false);\n const next = previous ? previous.then(run, run) : run();\n reg.rowTails.set(key, next);\n void next.finally(() => {\n if (reg.rowTails.get(key) === next) reg.rowTails.delete(key);\n });\n };\n\n write.flush = (unloading = false) => {\n if (write.state === \"waiting\") {\n clearTimeout(timer);\n // Earlier writes on the record go first, so the server sees them in order.\n if (!unloading) {\n for (const earlier of reg.writes) {\n if (earlier.seq < write.seq && earlier.rowKey === write.rowKey && earlier.rowKey && earlier.state === \"waiting\") {\n earlier.flush();\n }\n }\n }\n write.state = \"queued\";\n if (unloading) void sendNow(true);\n else enqueue();\n } else if (write.state === \"queued\" && unloading) {\n // Behind an earlier write on the record; the page will not wait for it.\n void sendNow(true);\n }\n };\n\n write.drop = () => {\n if (write.state !== \"waiting\" && write.state !== \"queued\") return;\n write.dropped = true;\n settle();\n takeBack(reg, write);\n void invalidateResource(queryClient, resource);\n failedLater(new Error(DROPPED_WRITE_MESSAGE));\n resolveSent(undefined);\n };\n\n beginPending(reg, resource);\n reg.writes.push(write);\n track(write);\n if (patch) addPatch(reg, queryClient, patch);\n\n if (mode === \"optimistic\") {\n enqueue();\n return { status: \"applied\" };\n }\n\n if (viaProviderUndo) {\n enqueue();\n void sent.then((result) => {\n const auditId = result?.audit?.id;\n if (!result || !args.onUndoable) return;\n if (!auditId) {\n console.warn(\n `[genesis] \"${resource}\" serves undo, but its ${kind} returned no audit entry; no undo offered.`,\n );\n return;\n }\n let undone = false;\n args.onUndoable({\n resource,\n kind,\n id: id ?? (result.record as BaseRecord | undefined)?.id,\n strategy: \"provider\",\n delayMs,\n commit: () => {},\n undo: async () => {\n if (undone) return false;\n undone = true;\n let ok = true;\n try {\n await provider.undo!(resource, { auditId });\n } catch (error) {\n ok = false;\n failedLater(asError(error));\n }\n await invalidateResource(queryClient, resource);\n return ok;\n },\n });\n });\n return { status: \"applied\" };\n }\n\n // Delayed: wait, then send unless undone or flushed first.\n write.state = \"waiting\";\n timer = setTimeout(() => write.flush(), delayMs);\n\n args.onUndoable?.({\n resource,\n kind,\n id,\n strategy: \"delay\",\n delayMs,\n commit: () => write.flush(),\n undo: async () => {\n if (write.dropped) return true;\n if (write.state !== \"waiting\") return false;\n settle();\n takeBack(reg, write);\n void invalidateResource(queryClient, resource);\n resolveSent(undefined);\n return true;\n },\n });\n\n return { status: \"applied\" };\n}\n"]}
@@ -6,7 +6,7 @@ export { UseWizardReturn, WizardStep, useWizard } from './use-wizard.js';
6
6
  export { DEFAULT_UNDO_DELAY_MS, MutationMode, MutationModeOptions, UndoableWrite, pendingWriteCount } from './mutation-mode.js';
7
7
  export { DEFAULT_UNSAVED_CHANGES_MESSAGE, UseUnsavedChangesGuardOptions, UseUnsavedChangesGuardReturn, useUnsavedChangesGuard } from './use-unsaved-changes-guard.js';
8
8
  import '@tanstack/react-query';
9
- import '../types-Dsqqr9s7.js';
10
- import '../types-C5bjsbxz.js';
9
+ import '../types-DDOmG9hj.js';
10
+ import '../types-5cuflvha.js';
11
11
  import '../form-types.js';
12
12
  import 'react-hook-form';
@@ -1,11 +1,11 @@
1
1
  import '../chunk-HT43MPKW.js';
2
- export { buildArrayItemDefaults, useResourceForm } from '../chunk-IZT2O57C.js';
3
- export { useResource } from '../chunk-DVW5GXWZ.js';
2
+ export { buildArrayItemDefaults, useResourceForm } from '../chunk-3JSFTLDV.js';
3
+ export { useResource } from '../chunk-6Q477CHB.js';
4
4
  export { DEFAULT_UNSAVED_CHANGES_MESSAGE, useUnsavedChangesGuard } from '../chunk-XQO4OH2N.js';
5
5
  export { useWizard } from '../chunk-7KOLYF27.js';
6
6
  import '../chunk-5NHR6ZXS.js';
7
7
  import '../chunk-RYEXWQFD.js';
8
- export { DEFAULT_UNDO_DELAY_MS, pendingWriteCount } from '../chunk-QH4P5MI2.js';
8
+ export { DEFAULT_UNDO_DELAY_MS, pendingWriteCount } from '../chunk-F3BE7NGM.js';
9
9
  import '../chunk-7NUL32W7.js';
10
10
  export { useCapabilities } from '../chunk-BQOJX67X.js';
11
11
  export { useOne } from '../chunk-ZK5C3OOT.js';
@@ -1,6 +1,6 @@
1
1
  import { QueryClient } from '@tanstack/react-query';
2
- import { I as Identifier, B as BaseRecord, D as DataProvider } from '../types-Dsqqr9s7.js';
3
- import { A as AuditEntry } from '../types-C5bjsbxz.js';
2
+ import { I as Identifier, B as BaseRecord, D as DataProvider } from '../types-DDOmG9hj.js';
3
+ import { A as AuditEntry } from '../types-5cuflvha.js';
4
4
  import '../form-types.js';
5
5
 
6
6
  type MutationMode = "pessimistic" | "optimistic" | "undoable";
@@ -23,10 +23,12 @@ interface UndoableWrite {
23
23
  /** How long the undo is offered, in ms (the toast's duration). */
24
24
  delayMs: number;
25
25
  /**
26
- * Take the write back. Resolves true when it was undone, false when it
27
- * could not be: already sent under `delay` (the window closed, or the hook
28
- * unmounted), already undone, or the provider's undo failed (reported
29
- * through `onError`). Safe to call more than once.
26
+ * Take the write back. Resolves true when it was undone (or will never be
27
+ * sent), false when it could not be: already sent under `delay` (the
28
+ * window closed, it was committed, a later write on the same record sent
29
+ * it first, or the page unloaded), already undone, or the provider's undo
30
+ * failed (reported through `onError`). Works after the hook that made the
31
+ * write has unmounted. Safe to call more than once.
30
32
  */
31
33
  undo: () => Promise<boolean>;
32
34
  /** Send a `delay` write now. */
@@ -40,27 +42,28 @@ interface MutationModeOptions {
40
42
  /** Called with every `undoable` write, to show an undo control. */
41
43
  onUndoable?: (write: UndoableWrite) => void;
42
44
  }
45
+ /** Structural equality for row values (JSON-like data, Dates). */
46
+ declare function sameValue(a: unknown, b: unknown): boolean;
47
+ /** The record as the cache has it now, from a detail entry or any list. */
48
+ declare function cachedRecord(queryClient: QueryClient, resource: string, id: Identifier): BaseRecord | undefined;
43
49
  /** Optimistic or undoable writes on `resource` not yet settled. */
44
50
  declare function pendingWriteCount(queryClient: QueryClient, resource: string): number;
45
51
  /**
46
- * Invalidate `[resource]`, unless a patched write on it is still pending
47
- * (the last one to settle refetches).
52
+ * Invalidate `[resource]`. Safe while optimistic/undoable writes on it are
53
+ * pending: their patches are re-applied to whatever the refetch brings.
48
54
  */
49
55
  declare function invalidateResource(queryClient: QueryClient, resource: string): Promise<void>;
50
- /** The record as the cache has it now, from a detail entry or any list. */
51
- declare function cachedRecord(queryClient: QueryClient, resource: string, id: Identifier): BaseRecord | undefined;
52
- interface DelayedWrite {
53
- /** Sends it now, if it is still waiting. */
54
- flush: () => void;
56
+ /** What `send` is given when the write goes out. */
57
+ interface SendContext {
58
+ /**
59
+ * The row-shaped values to send, when `data` was given. They can differ
60
+ * from `data`: an earlier write on the record that this one built on was
61
+ * taken back, and its values were put back. Send these.
62
+ */
63
+ data?: Record<string, unknown>;
64
+ /** The page is unloading: pass `keepalive: true` to the provider. */
65
+ keepalive: boolean;
55
66
  }
56
- /** The delayed writes one hook instance started, flushed when it unmounts. */
57
- type DelayedWrites = Set<DelayedWrite>;
58
- /**
59
- * A hook's own set of delayed writes. When the hook unmounts (the form
60
- * closes, the route changes) every write still waiting is sent at once,
61
- * as React Admin does: leaving is not undoing.
62
- */
63
- declare function useDelayedWrites(): DelayedWrites;
64
67
  interface ExecuteWriteArgs<R extends BaseRecord | void> {
65
68
  queryClient: QueryClient;
66
69
  provider: DataProvider;
@@ -75,19 +78,14 @@ interface ExecuteWriteArgs<R extends BaseRecord | void> {
75
78
  mode: MutationMode;
76
79
  undoDelayMs?: number;
77
80
  onUndoable?: (write: UndoableWrite) => void;
78
- /** The delayed writes of the calling hook instance. */
79
- delayed: DelayedWrites;
80
81
  /** Sends the write. */
81
- send: () => Promise<{
82
+ send: (context: SendContext) => Promise<{
82
83
  record: R;
83
84
  audit?: AuditEntry;
84
85
  }>;
85
- /**
86
- * After the write committed. Invalidates and calls success callbacks; its
87
- * `[resource]` invalidation should go through `invalidateResource`.
88
- */
86
+ /** After the write committed. Invalidates and calls success callbacks. */
89
87
  committed: (record: R) => Promise<void> | void;
90
- /** A write that failed after the caller was already told it went through. */
88
+ /** A write that failed (or was dropped) after the caller was told it went through. */
91
89
  failedLater: (error: Error) => void;
92
90
  }
93
91
  type ExecuteWriteResult<R> = {
@@ -96,6 +94,15 @@ type ExecuteWriteResult<R> = {
96
94
  } | {
97
95
  status: "applied";
98
96
  };
97
+ /**
98
+ * Whether `provider` serves `undo` for `resource`, from its capabilities
99
+ * (useCapabilities' key, so the answer is shared, and scoped to this
100
+ * provider: a swapped-out provider's capabilities never offer undo).
101
+ * @internal Exported for tests.
102
+ */
103
+ declare function providerServesUndo(queryClient: QueryClient, provider: DataProvider, resource: string): Promise<boolean>;
104
+ /** A later write that built on one that was taken back. */
105
+ declare const DROPPED_WRITE_MESSAGE = "This change was not saved: it was made on top of an earlier change that was undone or failed. Please make it again.";
99
106
  /**
100
107
  * Runs one write in the given mode.
101
108
  *
@@ -103,7 +110,10 @@ type ExecuteWriteResult<R> = {
103
110
  * - `optimistic` / `undoable`: resolves `{ status: "applied" }` as soon as
104
111
  * the cache is patched. A later failure rolls the patch back and goes to
105
112
  * `failedLater`, never to the returned promise.
113
+ *
114
+ * Writes on the same record are sent one after another, in the order they
115
+ * were made; sending one first sends the earlier ones still waiting.
106
116
  */
107
117
  declare function executeWrite<R extends BaseRecord | void>(args: ExecuteWriteArgs<R>): Promise<ExecuteWriteResult<R>>;
108
118
 
109
- export { DEFAULT_UNDO_DELAY_MS, type DelayedWrites, type ExecuteWriteArgs, type ExecuteWriteResult, type MutationMode, type MutationModeOptions, type UndoableWrite, cachedRecord, executeWrite, invalidateResource, pendingWriteCount, useDelayedWrites };
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 };
@@ -1,3 +1,6 @@
1
- export { DEFAULT_UNDO_DELAY_MS, cachedRecord, executeWrite, invalidateResource, pendingWriteCount, useDelayedWrites } from '../chunk-QH4P5MI2.js';
1
+ export { DEFAULT_UNDO_DELAY_MS, DROPPED_WRITE_MESSAGE, cachedRecord, executeWrite, invalidateResource, pendingWriteCount, providerServesUndo, sameValue } from '../chunk-F3BE7NGM.js';
2
+ import '../chunk-BQOJX67X.js';
3
+ import '../chunk-GGSXSI6Z.js';
4
+ import '../chunk-ZYJUEJ4Z.js';
2
5
  //# sourceMappingURL=mutation-mode.js.map
3
6
  //# sourceMappingURL=mutation-mode.js.map
@@ -1,5 +1,5 @@
1
- import { D as DataProvider, W as WriteEvent, j as InvalidationKey } from '../types-Dsqqr9s7.js';
2
- import '../types-C5bjsbxz.js';
1
+ import { D as DataProvider, W as WriteEvent, j as InvalidationKey } from '../types-DDOmG9hj.js';
2
+ import '../types-5cuflvha.js';
3
3
  import '../form-types.js';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { UseQueryResult } from '@tanstack/react-query';
2
- import { P as ProviderCapabilities } from '../types-C5bjsbxz.js';
2
+ import { P as ProviderCapabilities } from '../types-5cuflvha.js';
3
3
  import '../form-types.js';
4
4
 
5
5
  /**
@@ -1,6 +1,6 @@
1
1
  import { UseQueryResult } from '@tanstack/react-query';
2
- import { B as BaseRecord, I as Identifier } from '../types-Dsqqr9s7.js';
3
- import '../types-C5bjsbxz.js';
2
+ import { B as BaseRecord, I as Identifier } from '../types-DDOmG9hj.js';
3
+ import '../types-5cuflvha.js';
4
4
  import '../form-types.js';
5
5
 
6
6
  interface UseOneOptions {
@@ -1,8 +1,8 @@
1
1
  import { UseFormReturn } from 'react-hook-form';
2
2
  import { ResourceFormFieldDef } from '../form-types.js';
3
- import { j as InvalidationKey } from '../types-Dsqqr9s7.js';
3
+ import { j as InvalidationKey } from '../types-DDOmG9hj.js';
4
4
  import { MutationModeOptions } from './mutation-mode.js';
5
- import '../types-C5bjsbxz.js';
5
+ import '../types-5cuflvha.js';
6
6
  import '@tanstack/react-query';
7
7
 
8
8
  interface UseResourceFormOptions extends MutationModeOptions {
@@ -34,6 +34,14 @@ interface UseResourceFormOptions extends MutationModeOptions {
34
34
  warnWhenUnsaved?: boolean | {
35
35
  message?: string;
36
36
  };
37
+ /**
38
+ * Whether the form is on screen. Default true. Pass false while it is
39
+ * hidden but still mounted (a closed dialog). An optimistic or undoable
40
+ * save that fails later is put back on the form (field errors, unsaved
41
+ * again) only while the form is mounted, visible and still holds the
42
+ * values it saved; otherwise the failure only reaches `onError`.
43
+ */
44
+ visible?: boolean;
37
45
  /**
38
46
  * Pre-fill create form defaults from URL query params: a param named like a
39
47
  * field (`?status=draft`) becomes that field's starting value. Default true.
@@ -1,9 +1,10 @@
1
- export { buildArrayItemDefaults, useResourceForm } from '../chunk-IZT2O57C.js';
1
+ export { buildArrayItemDefaults, useResourceForm } from '../chunk-3JSFTLDV.js';
2
2
  import '../chunk-XQO4OH2N.js';
3
3
  import '../chunk-5NHR6ZXS.js';
4
4
  import '../chunk-RYEXWQFD.js';
5
- import '../chunk-QH4P5MI2.js';
5
+ import '../chunk-F3BE7NGM.js';
6
6
  import '../chunk-7NUL32W7.js';
7
+ import '../chunk-BQOJX67X.js';
7
8
  import '../chunk-ZK5C3OOT.js';
8
9
  import '../chunk-GGSXSI6Z.js';
9
10
  import '../chunk-ZYJUEJ4Z.js';
@@ -1,7 +1,7 @@
1
1
  import { UseQueryResult, UseMutationResult } from '@tanstack/react-query';
2
- import { m as SortParam, F as FilterParam, j as InvalidationKey, k as ListResult, L as ListParams, I as Identifier, B as BaseRecord } from '../types-Dsqqr9s7.js';
2
+ import { m as SortParam, F as FilterParam, j as InvalidationKey, k as ListResult, L as ListParams, I as Identifier, B as BaseRecord } from '../types-DDOmG9hj.js';
3
3
  import { MutationModeOptions } from './mutation-mode.js';
4
- import '../types-C5bjsbxz.js';
4
+ import '../types-5cuflvha.js';
5
5
  import '../form-types.js';
6
6
 
7
7
  interface UseResourceOptions<T> extends MutationModeOptions {
@@ -1,6 +1,7 @@
1
- export { useResource } from '../chunk-DVW5GXWZ.js';
2
- import '../chunk-QH4P5MI2.js';
1
+ export { useResource } from '../chunk-6Q477CHB.js';
2
+ import '../chunk-F3BE7NGM.js';
3
3
  import '../chunk-7NUL32W7.js';
4
+ import '../chunk-BQOJX67X.js';
4
5
  import '../chunk-GGSXSI6Z.js';
5
6
  import '../chunk-ZYJUEJ4Z.js';
6
7
  //# sourceMappingURL=use-resource.js.map
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
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 RowFailure, S as ScalarFilter, m as SortParam, U as UpdateParams, n as UpdateResult, W as WriteEvent } from './types-Dsqqr9s7.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-BQkYcV4t.js';
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 RowFailure, S as ScalarFilter, m as SortParam, U as UpdateParams, n as UpdateResult, W as WriteEvent } from './types-DDOmG9hj.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-kgNhfuST.js';
3
3
  export { DataProviderRoot, DataProviderRootProps, GenesisProvider, GenesisProviderProps, MockProviderOptions, PostgrestFieldErrors, SupabaseClient, SupabaseClientInput, SupabaseProviderOptions, SupabaseResourceConfig, SupabaseWriteContext, createMockProvider, createSupabaseProvider, fieldErrorsFromPostgrest, readOutcomeFromCode, toDataWriteError, useDataProvider, useStorage, writeOutcomeFromCode } from './provider/index.js';
4
4
  export { S as StorageAdapter } from './types-DKcxHXxq.js';
5
5
  export { createLocalStorageAdapter, createMemoryStorageAdapter, createNoopStorageAdapter } from './storage/index.js';
@@ -11,7 +11,7 @@ export { UseWizardReturn, WizardStep, useWizard } from './hooks/use-wizard.js';
11
11
  export { DEFAULT_UNDO_DELAY_MS, MutationMode, MutationModeOptions, UndoableWrite, pendingWriteCount } from './hooks/mutation-mode.js';
12
12
  export { DEFAULT_UNSAVED_CHANGES_MESSAGE, UseUnsavedChangesGuardOptions, UseUnsavedChangesGuardReturn, useUnsavedChangesGuard } from './hooks/use-unsaved-changes-guard.js';
13
13
  export { FieldType, ResourceFormFieldDef, SelectOption, FieldType as WidgetHint } from './form-types.js';
14
- 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-C5bjsbxz.js';
14
+ 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-5cuflvha.js';
15
15
  export { decodeRecordKey, encodeRecordKey, keyFields } from './schema/index.js';
16
16
  export { titleCase } from './utils.js';
17
17
  import 'react';
package/dist/index.js CHANGED
@@ -1,16 +1,16 @@
1
- export { createSupabaseProvider, fieldErrorsFromPostgrest, readOutcomeFromCode, toDataWriteError, writeOutcomeFromCode } from './chunk-RLY7TZUY.js';
1
+ export { createSupabaseProvider, fieldErrorsFromPostgrest, readOutcomeFromCode, toDataWriteError, writeOutcomeFromCode } from './chunk-E5VYFAQO.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
6
  import './chunk-HT43MPKW.js';
7
- export { buildArrayItemDefaults, useResourceForm } from './chunk-IZT2O57C.js';
8
- export { useResource } from './chunk-DVW5GXWZ.js';
7
+ export { buildArrayItemDefaults, useResourceForm } from './chunk-3JSFTLDV.js';
8
+ export { useResource } from './chunk-6Q477CHB.js';
9
9
  export { DEFAULT_UNSAVED_CHANGES_MESSAGE, useUnsavedChangesGuard } from './chunk-XQO4OH2N.js';
10
10
  export { useWizard } from './chunk-7KOLYF27.js';
11
11
  export { DataWriteError, isDataWriteError } from './chunk-5NHR6ZXS.js';
12
12
  export { titleCase } from './chunk-RYEXWQFD.js';
13
- export { DEFAULT_UNDO_DELAY_MS, pendingWriteCount } from './chunk-QH4P5MI2.js';
13
+ export { DEFAULT_UNDO_DELAY_MS, pendingWriteCount } from './chunk-F3BE7NGM.js';
14
14
  import './chunk-7NUL32W7.js';
15
15
  export { useCapabilities } from './chunk-BQOJX67X.js';
16
16
  export { useOne } from './chunk-ZK5C3OOT.js';
@@ -1,12 +1,12 @@
1
- import { D as DataProvider, I as Identifier, B as BaseRecord, j as InvalidationKey, W as WriteEvent } from '../types-Dsqqr9s7.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 RowFailure, S as ScalarFilter, m as SortParam, U as UpdateParams, n as UpdateResult } from '../types-Dsqqr9s7.js';
3
- import { D as DataReadError, R as ReadOutcome, b as DataWriteError, W as WriteOutcome } from '../read-outcome-BQkYcV4t.js';
4
- export { a as DataReadErrorOptions, c as DataWriteErrorOptions, i as isDataReadError, d as isDataWriteError, r as readFailureMessage } from '../read-outcome-BQkYcV4t.js';
1
+ import { D as DataProvider, I as Identifier, B as BaseRecord, j as InvalidationKey, W as WriteEvent } from '../types-DDOmG9hj.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 RowFailure, S as ScalarFilter, m as SortParam, U as UpdateParams, n as UpdateResult } from '../types-DDOmG9hj.js';
3
+ import { D as DataReadError, R as ReadOutcome, b as DataWriteError, W as WriteOutcome } from '../read-outcome-kgNhfuST.js';
4
+ export { a as DataReadErrorOptions, c as DataWriteErrorOptions, i as isDataReadError, d as isDataWriteError, r as readFailureMessage } from '../read-outcome-kgNhfuST.js';
5
5
  import * as react from 'react';
6
6
  import { ReactNode } from 'react';
7
7
  import { QueryClient } from '@tanstack/react-query';
8
8
  import { S as StorageAdapter } from '../types-DKcxHXxq.js';
9
- import '../types-C5bjsbxz.js';
9
+ import '../types-5cuflvha.js';
10
10
  import '../form-types.js';
11
11
 
12
12
  interface MockProviderOptions {
@@ -227,7 +227,11 @@ interface PostgrestFieldErrors {
227
227
  * Reads which columns a Postgres constraint error is about, from PostgREST's
228
228
  * `message` / `details`, and gives safe messages for them. Only plain column
229
229
  * names are taken from the store's text; the values it echoes are never
230
- * used. Returns `undefined` when nothing can be mapped safely.
230
+ * used. A unique violation whose columns cannot be read (a complex
231
+ * expression index, no details), or an insert/update foreign-key violation
232
+ * whose key is an expression, gets the safe sentence with no `fields`, so the
233
+ * store's raw text (constraint name, echoed value) never reaches the user.
234
+ * Returns `undefined` for anything else.
231
235
  *
232
236
  * - `23505` unique violation, `Key (email)=(…) already exists.` → each
233
237
  * column: "This value is already in use." (several columns: "This
@@ -1,4 +1,4 @@
1
- export { createSupabaseProvider, fieldErrorsFromPostgrest, readOutcomeFromCode, toDataWriteError, writeOutcomeFromCode } from '../chunk-RLY7TZUY.js';
1
+ export { createSupabaseProvider, fieldErrorsFromPostgrest, readOutcomeFromCode, toDataWriteError, writeOutcomeFromCode } from '../chunk-E5VYFAQO.js';
2
2
  export { DataReadError, isDataReadError, readFailureMessage } from '../chunk-HUNGCTRA.js';
3
3
  export { DataWriteError, isDataWriteError } from '../chunk-5NHR6ZXS.js';
4
4
  import '../chunk-RYEXWQFD.js';
@@ -1,4 +1,4 @@
1
- import { D as DataRow } from './types-C5bjsbxz.js';
1
+ import { D as DataRow } from './types-5cuflvha.js';
2
2
 
3
3
  /**
4
4
  * - `conflict`: someone else changed the row since it was read. `current`
@@ -1,7 +1,7 @@
1
- import { e as ResourceContract, D as DataRow } from '../types-C5bjsbxz.js';
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-C5bjsbxz.js';
3
- import { I as Identifier } from '../types-Dsqqr9s7.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-BQkYcV4t.js';
1
+ import { e as ResourceContract, D as DataRow } from '../types-5cuflvha.js';
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-5cuflvha.js';
3
+ import { I as Identifier } from '../types-DDOmG9hj.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-kgNhfuST.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. */
@@ -250,6 +250,14 @@ interface ProviderCapabilities {
250
250
  * of removing it. Asked per resource: `capabilities(resource)`.
251
251
  */
252
252
  readonly softDelete?: boolean;
253
+ /**
254
+ * `create`, `update` and `deleteOne` honour `keepalive: true` in their
255
+ * params (e.g. `fetch(url, { keepalive: true })`), so a write sent while
256
+ * the page unloads still reaches the server. Without it, closing the tab
257
+ * while an optimistic or undoable write is being sent shows the browser's
258
+ * "Leave site?" prompt.
259
+ */
260
+ readonly keepaliveWrites?: boolean;
253
261
  }
254
262
  /** One audit record, as committed alongside the edit it describes. */
255
263
  interface AuditEntry {
@@ -1,4 +1,4 @@
1
- import { A as AuditEntry, g as ResourceSchema, h as ResourceSummary, P as ProviderCapabilities, R as RecordComment } from './types-C5bjsbxz.js';
1
+ import { A as AuditEntry, g as ResourceSchema, h as ResourceSummary, P as ProviderCapabilities, R as RecordComment } from './types-5cuflvha.js';
2
2
 
3
3
  /** Record identifier — supports both string UUIDs and numeric auto-increment IDs. */
4
4
  type Identifier = string | number;
@@ -90,6 +90,13 @@ interface GetManyResult<T> {
90
90
  /** Parameters for `create`. */
91
91
  interface CreateParams<T> {
92
92
  data: Partial<T>;
93
+ /**
94
+ * Sent while the page unloads (an `undoable` write flushed on close or
95
+ * reload). A fetch-based provider should pass `keepalive: true` to `fetch`
96
+ * so the request outlives the page, and report `keepaliveWrites` in its
97
+ * capabilities. Others ignore it.
98
+ */
99
+ keepalive?: boolean;
93
100
  }
94
101
  /** Result of `create`. */
95
102
  interface CreateResult<T> {
@@ -113,6 +120,8 @@ interface UpdateParams<T> {
113
120
  * ignore it.
114
121
  */
115
122
  expectedVersion?: string | null;
123
+ /** See `CreateParams.keepalive`. */
124
+ keepalive?: boolean;
116
125
  }
117
126
  /** Result of `update`. */
118
127
  interface UpdateResult<T> {
@@ -127,6 +136,8 @@ interface DeleteParams {
127
136
  id: Identifier;
128
137
  /** The version token the row was read at; see `UpdateParams.expectedVersion`. */
129
138
  expectedVersion?: string | null;
139
+ /** See `CreateParams.keepalive`. */
140
+ keepalive?: boolean;
130
141
  }
131
142
  /** Result of `deleteOne`. */
132
143
  interface DeleteResult {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marktiderman/genesis-core",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/hooks/use-resource.ts"],"names":["keepPreviousData","keepPreviousPlaceholder"],"mappings":"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","file":"chunk-DVW5GXWZ.js","sourcesContent":["import { useState, useCallback, useMemo } from \"react\";\nimport {\n keepPreviousData as keepPreviousPlaceholder,\n useQuery,\n useMutation,\n useQueryClient,\n type UseQueryResult,\n type UseMutationResult,\n} from \"@tanstack/react-query\";\nimport { useDataProvider } from \"../provider/context\";\nimport type {\n BaseRecord,\n Identifier,\n SortParam,\n FilterParam,\n ListParams,\n ListResult,\n InvalidationKey,\n WriteEvent,\n} from \"../provider/types\";\nimport { relatedKeys } from \"./related-keys\";\nimport {\n cachedRecord,\n executeWrite,\n invalidateResource,\n useDelayedWrites,\n type MutationModeOptions,\n} from \"./mutation-mode\";\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface UseResourceOptions<T> extends MutationModeOptions {\n defaultSort?: SortParam;\n /**\n * Re-synced whenever its value changes (deep-equal, order-independent),\n * not just its identity — safe to pass a scope/audience-derived array that\n * changes across renders. This only covers CHANGES on an already-mounted\n * hook, though: if this starts `undefined` while the real value resolves\n * asynchronously, gate `enabled` on that same readiness signal too — the\n * hook cannot tell \"no defaultFilters intended\" apart from \"not resolved\n * yet,\" so an ungated hook's very first fetch can still run unscoped.\n */\n defaultFilters?: FilterParam[];\n defaultPerPage?: number;\n /** The page to start on (from 1), e.g. restored from the URL. Default 1. */\n defaultPage?: number;\n /** The search to start with, e.g. restored from the URL. Default \"\". */\n defaultSearch?: string;\n /** Supabase select/join syntax, e.g. \"*, author:profiles(name)\". */\n select?: string;\n /** Fields to search across when setSearch is called. Required for server-side search. */\n searchFields?: string[];\n /** Disable auto-fetching. */\n enabled?: boolean;\n /**\n * Other query keys to invalidate after a create, update or delete, on top\n * of `[resource]` and the provider's own `invalidates` (e.g. `[[\"me\"]]`\n * when a write changes the signed-in user's roles).\n */\n invalidates?: InvalidationKey[];\n /**\n * While the next page / sort / search is loading, keep returning the\n * previous result (`list.isPlaceholderData` is true meanwhile) instead of\n * dropping to `undefined`. A paged list then stays on screen between pages\n * rather than flashing a skeleton. Default false.\n */\n keepPreviousData?: boolean;\n /**\n * After the write commits, with the provider's row. In `optimistic` and\n * `undoable` modes that is after `create` / `update` / `remove` have\n * already resolved.\n */\n onCreateSuccess?: (data: T) => void;\n onUpdateSuccess?: (data: T) => void;\n onDeleteSuccess?: () => void;\n /**\n * A write failed. In `optimistic` and `undoable` modes this is the only\n * place a failure is reported (the cache has already been put back), so\n * show it to the user here.\n */\n onError?: (error: Error) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Return type\n// ---------------------------------------------------------------------------\n\nexport interface UseResourceReturn<T> {\n /** TanStack Query result for the list query. */\n list: UseQueryResult<ListResult<T>>;\n /** Current list params (pagination, sort, filters, search). */\n params: ListParams;\n setSort: (sort: SortParam | undefined) => void;\n setFilters: (filters: FilterParam[]) => void;\n setPage: (page: number) => void;\n setPerPage: (perPage: number) => void;\n setSearch: (query: string) => void;\n /**\n * Create a new record. Returns the created item. In `optimistic` and\n * `undoable` modes it resolves at once with the values given (no `id` yet;\n * `onCreateSuccess` gets the stored row).\n */\n create: (data: Partial<T>) => Promise<T>;\n /**\n * Update an existing record by id. Returns the updated item. In\n * `optimistic` and `undoable` modes it resolves at once with the cached\n * row merged with `data`.\n */\n update: (id: Identifier, data: Partial<T>) => Promise<T>;\n /** Delete a record by id. Resolves at once in `optimistic` / `undoable` modes. */\n remove: (id: Identifier) => Promise<void>;\n /** True when any mutation is in-flight. */\n isMutating: boolean;\n createMutation: UseMutationResult<T, Error, Partial<T>>;\n updateMutation: UseMutationResult<T, Error, { id: Identifier; data: Partial<T> }>;\n deleteMutation: UseMutationResult<void, Error, Identifier>;\n}\n\n// ---------------------------------------------------------------------------\n// Filter identity — a deep-equality key independent of object-key order, so\n// a caller that rebuilds the same logical filters via a differently-ordered\n// spread (e.g. `{...base, operator: \"eq\"}` vs `{operator: \"eq\", ...base}`)\n// doesn't trip a spurious resync + pagination reset on an unrelated rerender.\n// ---------------------------------------------------------------------------\n\nfunction stableFilterKey(filters: FilterParam[] | undefined): string | undefined {\n if (!filters) return undefined;\n return JSON.stringify(\n filters.map((f) => {\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(f).sort()) {\n sorted[key] = (f as unknown as Record<string, unknown>)[key];\n }\n return sorted;\n }),\n );\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\nexport function useResource<T extends BaseRecord = BaseRecord>(\n resource: string,\n options: UseResourceOptions<T> = {},\n): UseResourceReturn<T> {\n const {\n defaultSort,\n defaultFilters,\n defaultPerPage = 25,\n defaultPage = 1,\n defaultSearch = \"\",\n select,\n searchFields: searchFieldsOption,\n enabled = true,\n invalidates,\n keepPreviousData = false,\n onCreateSuccess,\n onUpdateSuccess,\n onDeleteSuccess,\n onError,\n mutationMode = \"pessimistic\",\n undoDelayMs,\n onUndoable,\n } = options;\n\n const provider = useDataProvider();\n const queryClient = useQueryClient();\n\n // -------------------------------------------------------------------------\n // State\n // -------------------------------------------------------------------------\n\n const [sort, setSortRaw] = useState<SortParam | undefined>(defaultSort);\n const [filters, setFiltersRaw] = useState<FilterParam[]>(defaultFilters ?? []);\n const [page, setPage] = useState(Math.max(1, Math.floor(defaultPage)));\n const [perPage, setPerPageRaw] = useState(defaultPerPage);\n const [searchQuery, setSearchQuery] = useState(defaultSearch);\n\n // `defaultFilters` often resolves asynchronously — a caller's scope/audience\n // (team, project, ...) can still be loading on first render, so the array\n // it passes in changes value (not just identity) after mount, and may later\n // clear back to undefined (e.g. the scope itself is cleared). Re-syncing\n // here, during render rather than in an effect, means `filters` is already\n // correct by the time `params`/`list` below compute for this pass — no\n // stray unscoped fetch on the frame before an effect would have caught up.\n //\n // This only closes the gap for `defaultFilters` CHANGING across renders on\n // an already-mounted, already-enabled hook (e.g. a scope switch). It cannot\n // help the very first render: `filters` still seeds from whatever\n // `defaultFilters` is on mount, and `undefined` here is genuinely ambiguous\n // between \"this caller never uses defaultFilters\" (in which case forcing a\n // fetch to wait would break it forever) and \"the real value hasn't resolved\n // yet.\" A caller in the second case MUST also gate `enabled` on that same\n // readiness signal for its very first fetch to be correctly scoped — this\n // hook has no way to tell the two cases apart on its own.\n const defaultFiltersKey = stableFilterKey(defaultFilters);\n const [syncedFiltersKey, setSyncedFiltersKey] = useState(defaultFiltersKey);\n if (defaultFiltersKey !== syncedFiltersKey) {\n setSyncedFiltersKey(defaultFiltersKey);\n setFiltersRaw(defaultFilters ?? []);\n setPage(1);\n }\n\n const setSort = useCallback((s: SortParam | undefined) => {\n setSortRaw(s);\n setPage(1);\n }, []);\n\n const setFilters = useCallback((f: FilterParam[]) => {\n setFiltersRaw(f);\n setPage(1);\n }, []);\n\n const setPerPage = useCallback((value: number) => {\n setPerPageRaw(value);\n setPage(1);\n }, []);\n\n const setSearch = useCallback((query: string) => {\n setSearchQuery(query);\n setPage(1);\n }, []);\n\n // -------------------------------------------------------------------------\n // Params\n // -------------------------------------------------------------------------\n\n const params = useMemo<ListParams>(() => {\n const p: ListParams = {\n pagination: { page, perPage },\n sort,\n filters: filters.length > 0 ? filters : undefined,\n select,\n };\n if (searchQuery && searchFieldsOption && searchFieldsOption.length > 0) {\n p.search = { query: searchQuery, fields: searchFieldsOption };\n }\n return p;\n }, [page, perPage, sort, filters, select, searchQuery, searchFieldsOption]);\n\n // -------------------------------------------------------------------------\n // List query\n // -------------------------------------------------------------------------\n\n const listQueryKey = useMemo(\n () => [resource, \"list\", params] as const,\n [resource, params],\n );\n\n const list = useQuery<ListResult<T>>({\n queryKey: listQueryKey,\n queryFn: () => provider.getList<T>(resource, params),\n enabled,\n placeholderData: keepPreviousData ? keepPreviousPlaceholder : undefined,\n });\n\n // -------------------------------------------------------------------------\n // Mutations\n // -------------------------------------------------------------------------\n\n const invalidateAfter = useCallback(\n (event: WriteEvent) => {\n // Waits while an optimistic/undoable write on the resource is pending.\n void invalidateResource(queryClient, resource);\n for (const queryKey of relatedKeys(provider, event, invalidates)) {\n void queryClient.invalidateQueries({ queryKey: [...queryKey] });\n }\n },\n [queryClient, resource, provider, invalidates],\n );\n\n const defaultOnError = useCallback(\n (error: Error) => {\n console.error(`[useResource] ${resource} mutation failed:`, error.message);\n },\n [resource],\n );\n const reportError = onError ?? defaultOnError;\n\n const delayed = useDelayedWrites();\n const modeArgs = {\n queryClient,\n provider,\n resource,\n mode: mutationMode,\n undoDelayMs,\n onUndoable,\n delayed,\n failedLater: reportError,\n };\n\n const createMutation = useMutation<T, Error, Partial<T>>({\n mutationFn: async (data) => {\n const outcome = await executeWrite<T>({\n ...modeArgs,\n kind: \"create\",\n data: data as Record<string, unknown>,\n send: async () => {\n const result = await provider.create<T>(resource, { data });\n return { record: result.data, audit: result.audit };\n },\n committed: (record) => {\n invalidateAfter({ resource, kind: \"create\", id: record.id, record });\n onCreateSuccess?.(record);\n },\n });\n return outcome.status === \"committed\" ? outcome.record : (data as T);\n },\n onError: reportError,\n });\n\n const updateMutation = useMutation<\n T,\n Error,\n { id: Identifier; data: Partial<T> }\n >({\n mutationFn: async ({ id, data }) => {\n const before = cachedRecord(queryClient, resource, id);\n const outcome = await executeWrite<T>({\n ...modeArgs,\n kind: \"update\",\n id,\n data: data as Record<string, unknown>,\n send: async () => {\n const result = await provider.update<T>(resource, { id, data });\n return { record: result.data, audit: result.audit };\n },\n committed: (record) => {\n invalidateAfter({ resource, kind: \"update\", id, record });\n onUpdateSuccess?.(record);\n },\n });\n return outcome.status === \"committed\"\n ? outcome.record\n : ({ ...(before ?? {}), ...data, id: before?.id ?? id } as T);\n },\n onError: reportError,\n });\n\n const deleteMutation = useMutation<void, Error, Identifier>({\n mutationFn: async (id) => {\n await executeWrite<void>({\n ...modeArgs,\n kind: \"delete\",\n id,\n send: async () => {\n const result = await provider.deleteOne(resource, { id });\n return { record: undefined, audit: result?.audit };\n },\n committed: () => {\n invalidateAfter({ resource, kind: \"delete\", id });\n onDeleteSuccess?.();\n },\n });\n },\n onError: reportError,\n });\n\n // -------------------------------------------------------------------------\n // Convenience wrappers\n // -------------------------------------------------------------------------\n\n const create = useCallback(\n (data: Partial<T>) => createMutation.mutateAsync(data),\n [createMutation],\n );\n\n const update = useCallback(\n (id: Identifier, data: Partial<T>) =>\n updateMutation.mutateAsync({ id, data }),\n [updateMutation],\n );\n\n const remove = useCallback(\n (id: Identifier) => deleteMutation.mutateAsync(id),\n [deleteMutation],\n );\n\n const isMutating =\n createMutation.isPending ||\n updateMutation.isPending ||\n deleteMutation.isPending;\n\n return {\n list,\n params,\n setSort,\n setFilters,\n setPage,\n setPerPage,\n setSearch,\n create,\n update,\n remove,\n isMutating,\n createMutation,\n updateMutation,\n deleteMutation,\n };\n}\n"]}