@rocicorp/zero 0.25.0-canary.10 → 0.25.0-canary.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/analyze-query/src/run-ast.d.ts.map +1 -1
- package/out/analyze-query/src/run-ast.js +3 -7
- package/out/analyze-query/src/run-ast.js.map +1 -1
- package/out/shared/src/iterables.d.ts +0 -1
- package/out/shared/src/iterables.d.ts.map +1 -1
- package/out/shared/src/iterables.js +0 -34
- package/out/shared/src/iterables.js.map +1 -1
- package/out/zero/package.json.js +1 -1
- package/out/zero-cache/src/db/transaction-pool.d.ts.map +1 -1
- package/out/zero-cache/src/db/transaction-pool.js +3 -6
- package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
- package/out/zero-cache/src/services/analyze.d.ts +1 -1
- package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
- package/out/zero-cache/src/services/analyze.js +50 -37
- package/out/zero-cache/src/services/analyze.js.map +1 -1
- package/out/zero-cache/src/services/run-ast.d.ts +1 -1
- package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
- package/out/zero-cache/src/services/run-ast.js +5 -1
- package/out/zero-cache/src/services/run-ast.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +6 -4
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +71 -23
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +10 -6
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-client/src/client/bindings.d.ts +2 -3
- package/out/zero-client/src/client/bindings.d.ts.map +1 -1
- package/out/zero-client/src/client/bindings.js.map +1 -1
- package/out/zero-client/src/client/make-mutate-property.d.ts +2 -2
- package/out/zero-client/src/client/make-mutate-property.d.ts.map +1 -1
- package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +3 -3
- package/out/zero-client/src/client/options.d.ts.map +1 -1
- package/out/zero-client/src/client/options.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero.d.ts +1 -2
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +6 -2
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/mod.d.ts +5 -7
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-react/src/components/inspector.d.ts +1 -2
- package/out/zero-react/src/components/inspector.d.ts.map +1 -1
- package/out/zero-react/src/components/inspector.js.map +1 -1
- package/out/zero-react/src/components/zero-inspector.d.ts +1 -2
- package/out/zero-react/src/components/zero-inspector.d.ts.map +1 -1
- package/out/zero-react/src/components/zero-inspector.js.map +1 -1
- package/out/zero-react/src/use-query.d.ts +1 -2
- package/out/zero-react/src/use-query.d.ts.map +1 -1
- package/out/zero-react/src/use-query.js.map +1 -1
- package/out/zero-react/src/zero-provider.d.ts +4 -5
- package/out/zero-react/src/zero-provider.d.ts.map +1 -1
- package/out/zero-react/src/zero-provider.js.map +1 -1
- package/out/zero-solid/src/solid-view.d.ts.map +1 -1
- package/out/zero-solid/src/solid-view.js +4 -3
- package/out/zero-solid/src/solid-view.js.map +1 -1
- package/out/zero-solid/src/use-zero.d.ts +4 -5
- package/out/zero-solid/src/use-zero.d.ts.map +1 -1
- package/out/zero-solid/src/use-zero.js.map +1 -1
- package/out/zero-types/src/default-types.d.ts +2 -2
- package/out/zero-types/src/default-types.d.ts.map +1 -1
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js +0 -1
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/ivm/array-view.d.ts +1 -1
- package/out/zql/src/ivm/array-view.d.ts.map +1 -1
- package/out/zql/src/ivm/array-view.js +2 -1
- package/out/zql/src/ivm/array-view.js.map +1 -1
- package/out/zql/src/ivm/data.d.ts +7 -2
- package/out/zql/src/ivm/data.d.ts.map +1 -1
- package/out/zql/src/ivm/data.js +3 -0
- package/out/zql/src/ivm/data.js.map +1 -1
- package/out/zql/src/ivm/exists.d.ts +3 -2
- package/out/zql/src/ivm/exists.d.ts.map +1 -1
- package/out/zql/src/ivm/exists.js +29 -76
- package/out/zql/src/ivm/exists.js.map +1 -1
- package/out/zql/src/ivm/fan-in.d.ts +2 -0
- package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-in.js +4 -0
- package/out/zql/src/ivm/fan-in.js.map +1 -1
- package/out/zql/src/ivm/fan-out.d.ts +2 -0
- package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-out.js +4 -0
- package/out/zql/src/ivm/fan-out.js.map +1 -1
- package/out/zql/src/ivm/filter-operators.d.ts +6 -2
- package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-operators.js +16 -0
- package/out/zql/src/ivm/filter-operators.js.map +1 -1
- package/out/zql/src/ivm/filter.d.ts +2 -0
- package/out/zql/src/ivm/filter.d.ts.map +1 -1
- package/out/zql/src/ivm/filter.js +4 -0
- package/out/zql/src/ivm/filter.js.map +1 -1
- package/out/zql/src/ivm/flipped-join.d.ts +1 -1
- package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
- package/out/zql/src/ivm/flipped-join.js +26 -13
- package/out/zql/src/ivm/flipped-join.js.map +1 -1
- package/out/zql/src/ivm/join-utils.d.ts +2 -1
- package/out/zql/src/ivm/join-utils.d.ts.map +1 -1
- package/out/zql/src/ivm/join-utils.js +8 -0
- package/out/zql/src/ivm/join-utils.js.map +1 -1
- package/out/zql/src/ivm/join.d.ts +1 -1
- package/out/zql/src/ivm/join.d.ts.map +1 -1
- package/out/zql/src/ivm/join.js +15 -6
- package/out/zql/src/ivm/join.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +1 -1
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +8 -1
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/operator.d.ts +9 -1
- package/out/zql/src/ivm/operator.d.ts.map +1 -1
- package/out/zql/src/ivm/operator.js +8 -0
- package/out/zql/src/ivm/operator.js.map +1 -1
- package/out/zql/src/ivm/push-accumulated.d.ts +1 -1
- package/out/zql/src/ivm/push-accumulated.d.ts.map +1 -1
- package/out/zql/src/ivm/push-accumulated.js.map +1 -1
- package/out/zql/src/ivm/skip.d.ts +1 -1
- package/out/zql/src/ivm/skip.d.ts.map +1 -1
- package/out/zql/src/ivm/skip.js +7 -1
- package/out/zql/src/ivm/skip.js.map +1 -1
- package/out/zql/src/ivm/take.d.ts +1 -1
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +87 -59
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts +2 -1
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +67 -5
- package/out/zql/src/ivm/union-fan-in.js.map +1 -1
- package/out/zql/src/ivm/union-fan-out.d.ts +1 -1
- package/out/zql/src/ivm/union-fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-out.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +3 -2
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/mutate/custom.d.ts +2 -2
- package/out/zql/src/mutate/custom.d.ts.map +1 -1
- package/out/zql/src/mutate/custom.js.map +1 -1
- package/out/zql/src/mutate/mutator-registry.d.ts +33 -15
- package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator-registry.js +2 -8
- package/out/zql/src/mutate/mutator-registry.js.map +1 -1
- package/out/zql/src/mutate/mutator.d.ts +50 -25
- package/out/zql/src/mutate/mutator.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator.js +2 -3
- package/out/zql/src/mutate/mutator.js.map +1 -1
- package/out/zql/src/query/abstract-query.d.ts +43 -0
- package/out/zql/src/query/abstract-query.d.ts.map +1 -0
- package/out/zql/src/query/abstract-query.js +408 -0
- package/out/zql/src/query/abstract-query.js.map +1 -0
- package/out/zql/src/query/create-builder.d.ts +2 -0
- package/out/zql/src/query/create-builder.d.ts.map +1 -1
- package/out/zql/src/query/create-builder.js +7 -2
- package/out/zql/src/query/create-builder.js.map +1 -1
- package/out/zql/src/query/measure-push-operator.d.ts +1 -1
- package/out/zql/src/query/measure-push-operator.d.ts.map +1 -1
- package/out/zql/src/query/measure-push-operator.js.map +1 -1
- package/out/zql/src/query/query-delegate-base.d.ts +7 -1
- package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
- package/out/zql/src/query/query-delegate-base.js +132 -2
- package/out/zql/src/query/query-delegate-base.js.map +1 -1
- package/out/zql/src/query/query-impl.d.ts +5 -39
- package/out/zql/src/query/query-impl.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.js +3 -521
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query-internals.d.ts.map +1 -1
- package/out/zql/src/query/query-internals.js +2 -2
- package/out/zql/src/query/query-internals.js.map +1 -1
- package/out/zql/src/query/query-registry.d.ts +126 -58
- package/out/zql/src/query/query-registry.d.ts.map +1 -1
- package/out/zql/src/query/query-registry.js +13 -21
- package/out/zql/src/query/query-registry.js.map +1 -1
- package/out/zql/src/query/query.d.ts +21 -0
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.d.ts +22 -0
- package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -0
- package/out/zql/src/query/runnable-query-impl.js +60 -0
- package/out/zql/src/query/runnable-query-impl.js.map +1 -0
- package/out/zql/src/query/static-query.d.ts +1 -1
- package/out/zql/src/query/static-query.d.ts.map +1 -1
- package/out/zql/src/query/static-query.js +1 -1
- package/out/zql/src/query/static-query.js.map +1 -1
- package/out/zqlite/src/table-source.d.ts +7 -1
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +34 -14
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-apply-change.js","sources":["../../../../../zql/src/ivm/view-apply-change.ts"],"sourcesContent":["import {\n assert,\n assertArray,\n assertNumber,\n unreachable,\n} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport type {Writable} from '../../../shared/src/writable.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport {drainStreams, type Comparator, type Node} from './data.ts';\nimport type {SourceSchema} from './schema.ts';\nimport type {Entry, Format} from './view.ts';\n\nexport const refCountSymbol = Symbol('rc');\nexport const idSymbol = Symbol('id');\n\ntype MetaEntry = Writable<Entry> & {\n [refCountSymbol]: number;\n [idSymbol]?: string | undefined;\n};\ntype MetaEntryList = MetaEntry[];\n\n/**\n * `applyChange` does not consume the `relationships` of `ChildChange#node`,\n * `EditChange#node` and `EditChange#oldNode`. The `ViewChange` type\n * documents and enforces this via the type system.\n */\nexport type ViewChange =\n | AddViewChange\n | RemoveViewChange\n | ChildViewChange\n | EditViewChange;\n\nexport type RowOnlyNode = {row: Row};\n\nexport type AddViewChange = {\n type: 'add';\n node: Node;\n};\n\nexport type RemoveViewChange = {\n type: 'remove';\n node: Node;\n};\n\ntype ChildViewChange = {\n type: 'child';\n node: RowOnlyNode;\n child: {\n relationshipName: string;\n change: ViewChange;\n };\n};\n\ntype EditViewChange = {\n type: 'edit';\n node: RowOnlyNode;\n oldNode: RowOnlyNode;\n};\n\n/**\n * This is a subset of WeakMap but restricted to what we need.\n * @deprecated Not used anymore. This will be removed in the future.\n */\nexport interface RefCountMap {\n get(entry: Entry): number | undefined;\n set(entry: Entry, refCount: number): void;\n delete(entry: Entry): boolean;\n}\n\nexport function applyChange(\n parentEntry: Entry,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs = false,\n): void {\n if (schema.isHidden) {\n switch (change.type) {\n case 'add':\n case 'remove':\n for (const [relationship, children] of Object.entries(\n change.node.relationships,\n )) {\n const childSchema = must(schema.relationships[relationship]);\n for (const node of children()) {\n applyChange(\n parentEntry,\n {type: change.type, node},\n childSchema,\n relationship,\n format,\n withIDs,\n );\n }\n }\n return;\n case 'edit':\n // If hidden at this level it means that the hidden row was changed. If\n // the row was changed in such a way that it would change the\n // relationships then the edit would have been split into remove and\n // add.\n return;\n case 'child': {\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n applyChange(\n parentEntry,\n change.child.change,\n childSchema,\n relationship,\n format,\n withIDs,\n );\n return;\n }\n default:\n unreachable(change);\n }\n }\n\n const {singular, relationships: childFormats} = format;\n switch (change.type) {\n case 'add': {\n let newEntry: MetaEntry | undefined;\n\n if (singular) {\n const oldEntry = parentEntry[relationship] as MetaEntry | undefined;\n if (oldEntry !== undefined) {\n assert(\n schema.compareRows(oldEntry, change.node.row) === 0,\n `Singular relationship '${relationship}' should not have multiple rows. You may need to declare this relationship with the \\`many\\` helper instead of the \\`one\\` helper in your schema.`,\n );\n // adding same again.\n oldEntry[refCountSymbol]++;\n } else {\n newEntry = makeNewMetaEntry(change.node.row, schema, withIDs, 1);\n\n (parentEntry as Writable<Entry>)[relationship] = newEntry;\n }\n } else {\n newEntry = add(\n change.node.row,\n getChildEntryList(parentEntry, relationship),\n schema,\n withIDs,\n );\n }\n\n if (newEntry) {\n for (const [relationship, children] of Object.entries(\n change.node.relationships,\n )) {\n // TODO: Is there a flag to make TypeScript complain that dictionary access might be undefined?\n const childSchema = must(schema.relationships[relationship]);\n const childFormat = childFormats[relationship];\n if (childFormat === undefined) {\n continue;\n }\n\n const newView = childFormat.singular\n ? undefined\n : ([] as MetaEntryList);\n newEntry[relationship] = newView;\n\n for (const node of children()) {\n applyChange(\n newEntry,\n {type: 'add', node},\n childSchema,\n relationship,\n childFormat,\n withIDs,\n );\n }\n }\n }\n break;\n }\n case 'remove': {\n if (singular) {\n const oldEntry = parentEntry[relationship] as MetaEntry | undefined;\n assert(oldEntry !== undefined, 'node does not exist');\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n (parentEntry as Writable<Entry>)[relationship] = undefined;\n }\n oldEntry[refCountSymbol]--;\n } else {\n removeAndUpdateRefCount(\n getChildEntryList(parentEntry, relationship),\n change.node.row,\n schema.compareRows,\n );\n }\n // Needed to ensure cleanup of operator state is fully done.\n drainStreams(change.node);\n break;\n }\n case 'child': {\n let existing: MetaEntry;\n if (singular) {\n existing = getSingularEntry(parentEntry, relationship);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n const {pos, found} = binarySearch(\n view,\n change.node.row,\n schema.compareRows,\n );\n assert(found, 'node does not exist');\n existing = view[pos];\n }\n\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n const childFormat = format.relationships[change.child.relationshipName];\n if (childFormat !== undefined) {\n applyChange(\n existing,\n change.child.change,\n childSchema,\n change.child.relationshipName,\n childFormat,\n withIDs,\n );\n }\n break;\n }\n case 'edit': {\n if (singular) {\n const existing = parentEntry[relationship];\n assertMetaEntry(existing);\n applyEdit(existing, change, schema, withIDs);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n // The position of the row in the list may have changed due to the edit.\n if (schema.compareRows(change.oldNode.row, change.node.row) !== 0) {\n const {pos: oldPos, found: oldFound} = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(oldFound, 'old node does not exist');\n const oldEntry = view[oldPos];\n const {pos, found} = binarySearch(\n view,\n change.node.row,\n schema.compareRows,\n );\n // A special case:\n // when refCount is 1 (so the row is being moved\n // without leaving a placeholder behind), and the new pos is\n // the same as the old, or directly after the old (so after the remove\n // of the old it would be in the same pos):\n // the row does not need to be moved, it can just be edited in place.\n if (\n oldEntry[refCountSymbol] === 1 &&\n (pos === oldPos || pos - 1 === oldPos)\n ) {\n applyEdit(oldEntry, change, schema, withIDs);\n } else {\n // Move the row. If the row has > 1 ref count, an edit should\n // be received for each ref count. On the first edit, the original\n // row is moved, the edit is applied to it and its ref count is set\n // to 1. A shallow copy of the row is left at the old pos for\n // processing of the remaining edit, and the copy's ref count\n // is decremented. As each edit is received the ref count of the\n // copy is decrement, and the ref count of the row at the new\n // position is incremented. When the copy's ref count goes to 0,\n // it is removed.\n oldEntry[refCountSymbol]--;\n let adjustedPos = pos;\n if (oldEntry[refCountSymbol] === 0) {\n view.splice(oldPos, 1);\n adjustedPos = oldPos < pos ? pos - 1 : pos;\n }\n\n let entryToEdit;\n if (found) {\n entryToEdit = view[adjustedPos];\n } else {\n view.splice(adjustedPos, 0, oldEntry);\n entryToEdit = oldEntry;\n if (oldEntry[refCountSymbol] > 0) {\n const oldEntryCopy = {...oldEntry};\n view[oldPos] = oldEntryCopy;\n }\n }\n entryToEdit[refCountSymbol]++;\n applyEdit(entryToEdit, change, schema, withIDs);\n }\n } else {\n // Position could not have changed, so simply edit in place.\n const {pos, found} = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(found, 'node does not exist');\n applyEdit(view[pos], change, schema, withIDs);\n }\n }\n\n break;\n }\n default:\n unreachable(change);\n }\n}\n\nfunction applyEdit(\n existing: MetaEntry,\n change: EditViewChange,\n schema: SourceSchema,\n withIDs: boolean,\n) {\n Object.assign(existing, change.node.row);\n if (withIDs) {\n existing[idSymbol] = makeID(change.node.row, schema);\n }\n}\n\nfunction add(\n row: Row,\n view: MetaEntryList,\n schema: SourceSchema,\n withIDs: boolean,\n): MetaEntry | undefined {\n const {pos, found} = binarySearch(view, row, schema.compareRows);\n\n if (found) {\n view[pos][refCountSymbol]++;\n return undefined;\n }\n const newEntry = makeNewMetaEntry(row, schema, withIDs, 1);\n view.splice(pos, 0, newEntry);\n return newEntry;\n}\n\nfunction removeAndUpdateRefCount(\n view: MetaEntryList,\n row: Row,\n compareRows: Comparator,\n): MetaEntry {\n const {pos, found} = binarySearch(view, row, compareRows);\n assert(found, 'node does not exist');\n const oldEntry = view[pos];\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n view.splice(pos, 1);\n }\n oldEntry[refCountSymbol]--;\n\n return oldEntry;\n}\n\n// TODO: Do not return an object. It puts unnecessary pressure on the GC.\nfunction binarySearch(\n view: MetaEntryList,\n target: Row,\n comparator: Comparator,\n) {\n let low = 0;\n let high = view.length - 1;\n while (low <= high) {\n const mid = (low + high) >>> 1;\n const comparison = comparator(view[mid] as Row, target as Row);\n if (comparison < 0) {\n low = mid + 1;\n } else if (comparison > 0) {\n high = mid - 1;\n } else {\n return {pos: mid, found: true};\n }\n }\n return {pos: low, found: false};\n}\n\nfunction getChildEntryList(\n parentEntry: Entry,\n relationship: string,\n): MetaEntryList {\n const view = parentEntry[relationship];\n assertArray(view);\n return view as MetaEntryList;\n}\n\nfunction assertMetaEntry(v: unknown): asserts v is MetaEntry {\n assertNumber((v as Partial<MetaEntry>)[refCountSymbol]);\n}\n\nfunction getSingularEntry(parentEntry: Entry, relationship: string): MetaEntry {\n const e = parentEntry[relationship];\n assertNumber((e as Partial<MetaEntry>)[refCountSymbol]);\n return e as MetaEntry;\n}\n\nfunction makeNewMetaEntry(\n row: Row,\n schema: SourceSchema,\n withIDs: boolean,\n rc: number,\n): MetaEntry {\n if (withIDs) {\n return {...row, [refCountSymbol]: rc, [idSymbol]: makeID(row, schema)};\n }\n return {...row, [refCountSymbol]: rc};\n}\nfunction makeID(row: Row, schema: SourceSchema) {\n // optimization for case of non-compound primary key\n if (schema.primaryKey.length === 1) {\n return JSON.stringify(row[schema.primaryKey[0]]);\n }\n return JSON.stringify(schema.primaryKey.map(k => row[k]));\n}\n"],"names":["relationship"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"view-apply-change.js","sources":["../../../../../zql/src/ivm/view-apply-change.ts"],"sourcesContent":["import {\n assert,\n assertArray,\n assertNumber,\n unreachable,\n} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport type {Writable} from '../../../shared/src/writable.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport {drainStreams, type Comparator, type Node} from './data.ts';\nimport {skipYields} from './operator.ts';\nimport type {SourceSchema} from './schema.ts';\nimport type {Entry, Format} from './view.ts';\n\nexport const refCountSymbol = Symbol('rc');\nexport const idSymbol = Symbol('id');\n\ntype MetaEntry = Writable<Entry> & {\n [refCountSymbol]: number;\n [idSymbol]?: string | undefined;\n};\ntype MetaEntryList = MetaEntry[];\n\n/**\n * `applyChange` does not consume the `relationships` of `ChildChange#node`,\n * `EditChange#node` and `EditChange#oldNode`. The `ViewChange` type\n * documents and enforces this via the type system.\n */\nexport type ViewChange =\n | AddViewChange\n | RemoveViewChange\n | ChildViewChange\n | EditViewChange;\n\nexport type RowOnlyNode = {row: Row};\n\nexport type AddViewChange = {\n type: 'add';\n node: Node;\n};\n\nexport type RemoveViewChange = {\n type: 'remove';\n node: Node;\n};\n\ntype ChildViewChange = {\n type: 'child';\n node: RowOnlyNode;\n child: {\n relationshipName: string;\n change: ViewChange;\n };\n};\n\ntype EditViewChange = {\n type: 'edit';\n node: RowOnlyNode;\n oldNode: RowOnlyNode;\n};\n\n/**\n * This is a subset of WeakMap but restricted to what we need.\n * @deprecated Not used anymore. This will be removed in the future.\n */\nexport interface RefCountMap {\n get(entry: Entry): number | undefined;\n set(entry: Entry, refCount: number): void;\n delete(entry: Entry): boolean;\n}\n\nexport function applyChange(\n parentEntry: Entry,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs = false,\n): void {\n if (schema.isHidden) {\n switch (change.type) {\n case 'add':\n case 'remove':\n for (const [relationship, children] of Object.entries(\n change.node.relationships,\n )) {\n const childSchema = must(schema.relationships[relationship]);\n for (const node of skipYields(children())) {\n applyChange(\n parentEntry,\n {type: change.type, node},\n childSchema,\n relationship,\n format,\n withIDs,\n );\n }\n }\n return;\n case 'edit':\n // If hidden at this level it means that the hidden row was changed. If\n // the row was changed in such a way that it would change the\n // relationships then the edit would have been split into remove and\n // add.\n return;\n case 'child': {\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n applyChange(\n parentEntry,\n change.child.change,\n childSchema,\n relationship,\n format,\n withIDs,\n );\n return;\n }\n default:\n unreachable(change);\n }\n }\n\n const {singular, relationships: childFormats} = format;\n switch (change.type) {\n case 'add': {\n let newEntry: MetaEntry | undefined;\n\n if (singular) {\n const oldEntry = parentEntry[relationship] as MetaEntry | undefined;\n if (oldEntry !== undefined) {\n assert(\n schema.compareRows(oldEntry, change.node.row) === 0,\n `Singular relationship '${relationship}' should not have multiple rows. You may need to declare this relationship with the \\`many\\` helper instead of the \\`one\\` helper in your schema.`,\n );\n // adding same again.\n oldEntry[refCountSymbol]++;\n } else {\n newEntry = makeNewMetaEntry(change.node.row, schema, withIDs, 1);\n\n (parentEntry as Writable<Entry>)[relationship] = newEntry;\n }\n } else {\n newEntry = add(\n change.node.row,\n getChildEntryList(parentEntry, relationship),\n schema,\n withIDs,\n );\n }\n\n if (newEntry) {\n for (const [relationship, children] of Object.entries(\n change.node.relationships,\n )) {\n // TODO: Is there a flag to make TypeScript complain that dictionary access might be undefined?\n const childSchema = must(schema.relationships[relationship]);\n const childFormat = childFormats[relationship];\n if (childFormat === undefined) {\n continue;\n }\n\n const newView = childFormat.singular\n ? undefined\n : ([] as MetaEntryList);\n newEntry[relationship] = newView;\n\n for (const node of skipYields(children())) {\n applyChange(\n newEntry,\n {type: 'add', node},\n childSchema,\n relationship,\n childFormat,\n withIDs,\n );\n }\n }\n }\n break;\n }\n case 'remove': {\n if (singular) {\n const oldEntry = parentEntry[relationship] as MetaEntry | undefined;\n assert(oldEntry !== undefined, 'node does not exist');\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n (parentEntry as Writable<Entry>)[relationship] = undefined;\n }\n oldEntry[refCountSymbol]--;\n } else {\n removeAndUpdateRefCount(\n getChildEntryList(parentEntry, relationship),\n change.node.row,\n schema.compareRows,\n );\n }\n // Needed to ensure cleanup of operator state is fully done.\n drainStreams(change.node);\n break;\n }\n case 'child': {\n let existing: MetaEntry;\n if (singular) {\n existing = getSingularEntry(parentEntry, relationship);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n const {pos, found} = binarySearch(\n view,\n change.node.row,\n schema.compareRows,\n );\n assert(found, 'node does not exist');\n existing = view[pos];\n }\n\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n const childFormat = format.relationships[change.child.relationshipName];\n if (childFormat !== undefined) {\n applyChange(\n existing,\n change.child.change,\n childSchema,\n change.child.relationshipName,\n childFormat,\n withIDs,\n );\n }\n break;\n }\n case 'edit': {\n if (singular) {\n const existing = parentEntry[relationship];\n assertMetaEntry(existing);\n applyEdit(existing, change, schema, withIDs);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n // The position of the row in the list may have changed due to the edit.\n if (schema.compareRows(change.oldNode.row, change.node.row) !== 0) {\n const {pos: oldPos, found: oldFound} = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(oldFound, 'old node does not exist');\n const oldEntry = view[oldPos];\n const {pos, found} = binarySearch(\n view,\n change.node.row,\n schema.compareRows,\n );\n // A special case:\n // when refCount is 1 (so the row is being moved\n // without leaving a placeholder behind), and the new pos is\n // the same as the old, or directly after the old (so after the remove\n // of the old it would be in the same pos):\n // the row does not need to be moved, it can just be edited in place.\n if (\n oldEntry[refCountSymbol] === 1 &&\n (pos === oldPos || pos - 1 === oldPos)\n ) {\n applyEdit(oldEntry, change, schema, withIDs);\n } else {\n // Move the row. If the row has > 1 ref count, an edit should\n // be received for each ref count. On the first edit, the original\n // row is moved, the edit is applied to it and its ref count is set\n // to 1. A shallow copy of the row is left at the old pos for\n // processing of the remaining edit, and the copy's ref count\n // is decremented. As each edit is received the ref count of the\n // copy is decrement, and the ref count of the row at the new\n // position is incremented. When the copy's ref count goes to 0,\n // it is removed.\n oldEntry[refCountSymbol]--;\n let adjustedPos = pos;\n if (oldEntry[refCountSymbol] === 0) {\n view.splice(oldPos, 1);\n adjustedPos = oldPos < pos ? pos - 1 : pos;\n }\n\n let entryToEdit;\n if (found) {\n entryToEdit = view[adjustedPos];\n } else {\n view.splice(adjustedPos, 0, oldEntry);\n entryToEdit = oldEntry;\n if (oldEntry[refCountSymbol] > 0) {\n const oldEntryCopy = {...oldEntry};\n view[oldPos] = oldEntryCopy;\n }\n }\n entryToEdit[refCountSymbol]++;\n applyEdit(entryToEdit, change, schema, withIDs);\n }\n } else {\n // Position could not have changed, so simply edit in place.\n const {pos, found} = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(found, 'node does not exist');\n applyEdit(view[pos], change, schema, withIDs);\n }\n }\n\n break;\n }\n default:\n unreachable(change);\n }\n}\n\nfunction applyEdit(\n existing: MetaEntry,\n change: EditViewChange,\n schema: SourceSchema,\n withIDs: boolean,\n) {\n Object.assign(existing, change.node.row);\n if (withIDs) {\n existing[idSymbol] = makeID(change.node.row, schema);\n }\n}\n\nfunction add(\n row: Row,\n view: MetaEntryList,\n schema: SourceSchema,\n withIDs: boolean,\n): MetaEntry | undefined {\n const {pos, found} = binarySearch(view, row, schema.compareRows);\n\n if (found) {\n view[pos][refCountSymbol]++;\n return undefined;\n }\n const newEntry = makeNewMetaEntry(row, schema, withIDs, 1);\n view.splice(pos, 0, newEntry);\n return newEntry;\n}\n\nfunction removeAndUpdateRefCount(\n view: MetaEntryList,\n row: Row,\n compareRows: Comparator,\n): MetaEntry {\n const {pos, found} = binarySearch(view, row, compareRows);\n assert(found, 'node does not exist');\n const oldEntry = view[pos];\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n view.splice(pos, 1);\n }\n oldEntry[refCountSymbol]--;\n\n return oldEntry;\n}\n\n// TODO: Do not return an object. It puts unnecessary pressure on the GC.\nfunction binarySearch(\n view: MetaEntryList,\n target: Row,\n comparator: Comparator,\n) {\n let low = 0;\n let high = view.length - 1;\n while (low <= high) {\n const mid = (low + high) >>> 1;\n const comparison = comparator(view[mid] as Row, target as Row);\n if (comparison < 0) {\n low = mid + 1;\n } else if (comparison > 0) {\n high = mid - 1;\n } else {\n return {pos: mid, found: true};\n }\n }\n return {pos: low, found: false};\n}\n\nfunction getChildEntryList(\n parentEntry: Entry,\n relationship: string,\n): MetaEntryList {\n const view = parentEntry[relationship];\n assertArray(view);\n return view as MetaEntryList;\n}\n\nfunction assertMetaEntry(v: unknown): asserts v is MetaEntry {\n assertNumber((v as Partial<MetaEntry>)[refCountSymbol]);\n}\n\nfunction getSingularEntry(parentEntry: Entry, relationship: string): MetaEntry {\n const e = parentEntry[relationship];\n assertNumber((e as Partial<MetaEntry>)[refCountSymbol]);\n return e as MetaEntry;\n}\n\nfunction makeNewMetaEntry(\n row: Row,\n schema: SourceSchema,\n withIDs: boolean,\n rc: number,\n): MetaEntry {\n if (withIDs) {\n return {...row, [refCountSymbol]: rc, [idSymbol]: makeID(row, schema)};\n }\n return {...row, [refCountSymbol]: rc};\n}\nfunction makeID(row: Row, schema: SourceSchema) {\n // optimization for case of non-compound primary key\n if (schema.primaryKey.length === 1) {\n return JSON.stringify(row[schema.primaryKey[0]]);\n }\n return JSON.stringify(schema.primaryKey.map(k => row[k]));\n}\n"],"names":["relationship"],"mappings":"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"}
|
|
@@ -8,8 +8,6 @@ import type { Format } from '../ivm/view.ts';
|
|
|
8
8
|
import type { HumanReadable, Query, RunOptions } from '../query/query.ts';
|
|
9
9
|
import type { SchemaQuery } from '../query/schema-query.ts';
|
|
10
10
|
type ClientID = string;
|
|
11
|
-
export type Location = 'client' | 'server';
|
|
12
|
-
export type TransactionReason = 'optimistic' | 'rebase' | 'authoritative';
|
|
13
11
|
/**
|
|
14
12
|
* A base transaction interface that any Transaction<S, T> is assignable to.
|
|
15
13
|
* Used in places where the schema type doesn't need to be preserved,
|
|
@@ -21,6 +19,8 @@ export interface AnyTransaction {
|
|
|
21
19
|
readonly mutationID: number;
|
|
22
20
|
readonly reason: TransactionReason;
|
|
23
21
|
}
|
|
22
|
+
export type Location = 'client' | 'server';
|
|
23
|
+
export type TransactionReason = 'optimistic' | 'rebase' | 'authoritative';
|
|
24
24
|
export interface TransactionBase<S extends Schema> {
|
|
25
25
|
readonly location: Location;
|
|
26
26
|
readonly clientID: ClientID;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/custom.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,+BAA+B,CAAC;AAC1D,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,mCAAmC,CAAC;AAC3D,OAAO,KAAK,EACV,aAAa,EACb,yBAAyB,EAC1B,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,yCAAyC,CAAC;AACjF,OAAO,KAAK,EAAC,MAAM,EAAE,WAAW,EAAC,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,0CAA0C,CAAC;AAC3E,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAC,aAAa,EAAE,KAAK,EAAE,UAAU,EAAC,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,0BAA0B,CAAC;AAE1D,KAAK,QAAQ,GAAG,MAAM,CAAC;AAEvB
|
|
1
|
+
{"version":3,"file":"custom.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/custom.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,+BAA+B,CAAC;AAC1D,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,mCAAmC,CAAC;AAC3D,OAAO,KAAK,EACV,aAAa,EACb,yBAAyB,EAC1B,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,yCAAyC,CAAC;AACjF,OAAO,KAAK,EAAC,MAAM,EAAE,WAAW,EAAC,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,0CAA0C,CAAC;AAC3E,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAC,aAAa,EAAE,KAAK,EAAE,UAAU,EAAC,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,0BAA0B,CAAC;AAE1D,KAAK,QAAQ,GAAG,MAAM,CAAC;AAEvB;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;CACpC;AAED,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC3C,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,QAAQ,GAAG,eAAe,CAAC;AAE1E,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,MAAM;IAC/C,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAEnC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAE/B,GAAG,CAAC,MAAM,SAAS,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,OAAO,EACpD,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,EAChC,OAAO,CAAC,EAAE,UAAU,GACnB,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;CACpC;AAED,MAAM,MAAM,WAAW,CACrB,CAAC,SAAS,MAAM,GAAG,aAAa,EAChC,mBAAmB,GAAG,yBAAyB,IAC7C,iBAAiB,CAAC,CAAC,EAAE,mBAAmB,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;AAErE,MAAM,WAAW,iBAAiB,CAChC,CAAC,SAAS,MAAM,GAAG,aAAa,EAChC,mBAAmB,GAAG,yBAAyB,CAC/C,SAAQ,eAAe,CAAC,CAAC,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;CAC5D;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS,MAAM,GAAG,aAAa,CACjE,SAAQ,eAAe,CAAC,CAAC,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,QAAQ,CAAC;CAC1C;AAED,MAAM,WAAW,GAAG;IAClB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY,CAAC,mBAAmB;IAC/C,WAAW,EAAE,CAAC,CAAC,EACb,EAAE,EAAE,CAAC,EAAE,EAAE,aAAa,CAAC,mBAAmB,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,KACvD,OAAO,CAAC,CAAC,CAAC,CAAC;CACjB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,CAAE,SAAQ,SAAS;IACjD,QAAQ,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC/B,QAAQ,CAAC,OAAO,EACd,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;CACpC;AAED,UAAU,SAAS;IACjB,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;CACnE;AAED,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,MAAM,IAAI;KACxC,KAAK,IAAI,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC;CAC5D,CAAC;AAEF,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,WAAW,IAAI;IAC7C;;;;;OAKG;IACH,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjD;;;;;OAKG;IACH,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjD;;;;OAIG;IACH,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjD;;;OAGG;IACH,MAAM,EAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,WAAW,IAAI,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;AAE1E,KAAK,gBAAgB,CAAC,CAAC,SAAS,WAAW,IAAI;KAC5C,CAAC,IAAI,OAAO,CACX,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,EACvB,MAAM,CAAC,CAAC,SAAS,CAAC,CACnB,GAAG,mBAAmB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,WAAW,IAAI,MAAM,CACrD,gBAAgB,CAAC,CAAC,CAAC,GAAG;KACnB,CAAC,IAAI,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAC,GAChE,CAAC,GACD,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS;CAC9D,GAAG;KACD,CAAC,IAAI,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAC,GAChE,KAAK,GACL,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;CAC7C,CACF,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,WAAW,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;AAEhE,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,WAAW,IAAI,MAAM,CACrD,gBAAgB,CAAC,CAAC,CAAC,GAAG;KACnB,CAAC,IAAI,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EACtB,mBAAmB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GACpC,SAAS;CACd,CACF,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAQ5D;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAE3E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom.js","sources":["../../../../../zql/src/mutate/custom.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport type {Expand} from '../../../shared/src/expand.ts';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {\n DefaultSchema,\n DefaultWrappedTransaction,\n} from '../../../zero-types/src/default-types.ts';\nimport type {SchemaValueToTSType} from '../../../zero-types/src/schema-value.ts';\nimport type {Schema, TableSchema} from '../../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../../zero-types/src/server-schema.ts';\nimport type {Format} from '../ivm/view.ts';\nimport type {HumanReadable, Query, RunOptions} from '../query/query.ts';\nimport type {SchemaQuery} from '../query/schema-query.ts';\n\ntype ClientID = string;\n\
|
|
1
|
+
{"version":3,"file":"custom.js","sources":["../../../../../zql/src/mutate/custom.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport type {Expand} from '../../../shared/src/expand.ts';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {\n DefaultSchema,\n DefaultWrappedTransaction,\n} from '../../../zero-types/src/default-types.ts';\nimport type {SchemaValueToTSType} from '../../../zero-types/src/schema-value.ts';\nimport type {Schema, TableSchema} from '../../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../../zero-types/src/server-schema.ts';\nimport type {Format} from '../ivm/view.ts';\nimport type {HumanReadable, Query, RunOptions} from '../query/query.ts';\nimport type {SchemaQuery} from '../query/schema-query.ts';\n\ntype ClientID = string;\n\n/**\n * A base transaction interface that any Transaction<S, T> is assignable to.\n * Used in places where the schema type doesn't need to be preserved,\n * like the public signature of Mutator.fn.\n */\nexport interface AnyTransaction {\n readonly location: Location;\n readonly clientID: string;\n readonly mutationID: number;\n readonly reason: TransactionReason;\n}\n\nexport type Location = 'client' | 'server';\nexport type TransactionReason = 'optimistic' | 'rebase' | 'authoritative';\n\nexport interface TransactionBase<S extends Schema> {\n readonly location: Location;\n readonly clientID: ClientID;\n /**\n * The ID of the mutation that is being applied.\n */\n readonly mutationID: number;\n\n /**\n * The reason for the transaction.\n */\n readonly reason: TransactionReason;\n\n readonly mutate: SchemaCRUD<S>;\n readonly query: SchemaQuery<S>;\n\n run<TTable extends keyof S['tables'] & string, TReturn>(\n query: Query<TTable, S, TReturn>,\n options?: RunOptions,\n ): Promise<HumanReadable<TReturn>>;\n}\n\nexport type Transaction<\n S extends Schema = DefaultSchema,\n TWrappedTransaction = DefaultWrappedTransaction,\n> = ServerTransaction<S, TWrappedTransaction> | ClientTransaction<S>;\n\nexport interface ServerTransaction<\n S extends Schema = DefaultSchema,\n TWrappedTransaction = DefaultWrappedTransaction,\n> extends TransactionBase<S> {\n readonly location: 'server';\n readonly reason: 'authoritative';\n readonly dbTransaction: DBTransaction<TWrappedTransaction>;\n}\n\n/**\n * An instance of this is passed to custom mutator implementations and\n * allows reading and writing to the database and IVM at the head at which the\n * mutator is being applied.\n */\nexport interface ClientTransaction<S extends Schema = DefaultSchema>\n extends TransactionBase<S> {\n readonly location: 'client';\n readonly reason: 'optimistic' | 'rebase';\n}\n\nexport interface Row {\n [column: string]: unknown;\n}\n\nexport interface DBConnection<TWrappedTransaction> {\n transaction: <T>(\n cb: (tx: DBTransaction<TWrappedTransaction>) => Promise<T>,\n ) => Promise<T>;\n}\n\nexport interface DBTransaction<T> extends Queryable {\n readonly wrappedTransaction: T;\n runQuery<TReturn>(\n ast: AST,\n format: Format,\n schema: Schema,\n serverSchema: ServerSchema,\n ): Promise<HumanReadable<TReturn>>;\n}\n\ninterface Queryable {\n query: (query: string, args: unknown[]) => Promise<Iterable<Row>>;\n}\n\nexport type SchemaCRUD<S extends Schema> = {\n [Table in keyof S['tables']]: TableCRUD<S['tables'][Table]>;\n};\n\nexport type TableCRUD<S extends TableSchema> = {\n /**\n * Writes a row if a row with the same primary key doesn't already exists.\n * Non-primary-key fields that are 'optional' can be omitted or set to\n * `undefined`. Such fields will be assigned the value `null` optimistically\n * and then the default value as defined by the server.\n */\n insert: (value: InsertValue<S>) => Promise<void>;\n\n /**\n * Writes a row unconditionally, overwriting any existing row with the same\n * primary key. Non-primary-key fields that are 'optional' can be omitted or\n * set to `undefined`. Such fields will be assigned the value `null`\n * optimistically and then the default value as defined by the server.\n */\n upsert: (value: UpsertValue<S>) => Promise<void>;\n\n /**\n * Updates a row with the same primary key. If no such row exists, this\n * function does nothing. All non-primary-key fields can be omitted or set to\n * `undefined`. Such fields will be left unchanged from previous value.\n */\n update: (value: UpdateValue<S>) => Promise<void>;\n\n /**\n * Deletes the row with the specified primary key. If no such row exists, this\n * function does nothing.\n */\n delete: (id: DeleteID<S>) => Promise<void>;\n};\n\nexport type DeleteID<S extends TableSchema> = Expand<PrimaryKeyFields<S>>;\n\ntype PrimaryKeyFields<S extends TableSchema> = {\n [K in Extract<\n S['primaryKey'][number],\n keyof S['columns']\n >]: SchemaValueToTSType<S['columns'][K]>;\n};\n\nexport type InsertValue<S extends TableSchema> = Expand<\n PrimaryKeyFields<S> & {\n [K in keyof S['columns'] as S['columns'][K] extends {optional: true}\n ? K\n : never]?: SchemaValueToTSType<S['columns'][K]> | undefined;\n } & {\n [K in keyof S['columns'] as S['columns'][K] extends {optional: true}\n ? never\n : K]: SchemaValueToTSType<S['columns'][K]>;\n }\n>;\n\nexport type UpsertValue<S extends TableSchema> = InsertValue<S>;\n\nexport type UpdateValue<S extends TableSchema> = Expand<\n PrimaryKeyFields<S> & {\n [K in keyof S['columns']]?:\n | SchemaValueToTSType<S['columns'][K]>\n | undefined;\n }\n>;\n\nexport function customMutatorKey(sep: string, parts: string[]) {\n for (const part of parts) {\n assert(\n !part.includes(sep),\n `mutator names/namespaces must not include a ${sep}`,\n );\n }\n return parts.join(sep);\n}\n\nexport function splitMutatorKey(key: string, sep: string | RegExp): string[] {\n return key.split(sep);\n}\n"],"names":[],"mappings":";AAwKO,SAAS,iBAAiB,KAAa,OAAiB;AAC7D,aAAW,QAAQ,OAAO;AACxB;AAAA,MACE,CAAC,KAAK,SAAS,GAAG;AAAA,MAClB,+CAA+C,GAAG;AAAA,IAAA;AAAA,EAEtD;AACA,SAAO,MAAM,KAAK,GAAG;AACvB;AAEO,SAAS,gBAAgB,KAAa,KAAgC;AAC3E,SAAO,IAAI,MAAM,GAAG;AACtB;"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type DeepMerge } from '../../../shared/src/deep-merge.ts';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ReadonlyJSONValue } from '../../../shared/src/json.ts';
|
|
3
|
+
import type { DefaultSchema } from '../../../zero-types/src/default-types.ts';
|
|
3
4
|
import type { Schema } from '../../../zero-types/src/schema.ts';
|
|
4
5
|
import { type AnyMutator, type Mutator, type MutatorDefinition } from './mutator.ts';
|
|
5
6
|
/**
|
|
@@ -40,34 +41,47 @@ import { type AnyMutator, type Mutator, type MutatorDefinition } from './mutator
|
|
|
40
41
|
* const mutator = getMutator(mutators, 'user.create');
|
|
41
42
|
* ```
|
|
42
43
|
*/
|
|
43
|
-
export declare function defineMutators<
|
|
44
|
-
export declare function defineMutators<TBase
|
|
45
|
-
export declare function defineMutators<TBase extends MutatorDefinitions<S, C>, TOverrides extends MutatorDefinitions<S, C>, S extends Schema = DefaultSchema, C = DefaultContext>(base: TBase, overrides: TOverrides): MutatorRegistry<S, C, DeepMerge<TBase, TOverrides>>;
|
|
44
|
+
export declare function defineMutators<const MD, S extends Schema = DefaultSchema>(definitions: MD & AssertMutatorDefinitions<MD>): MutatorRegistry<EnsureMutatorDefinitions<MD>, S>;
|
|
45
|
+
export declare function defineMutators<const TBase, const TOverrides, S extends Schema = DefaultSchema>(base: MutatorRegistry<EnsureMutatorDefinitions<TBase>, S> | (TBase & AssertMutatorDefinitions<TBase>), overrides: TOverrides & AssertMutatorDefinitions<TOverrides>): MutatorRegistry<DeepMerge<EnsureMutatorDefinitions<TBase>, EnsureMutatorDefinitions<TOverrides>>, S>;
|
|
46
46
|
/**
|
|
47
47
|
* Gets a Mutator by its dot-separated name from a MutatorRegistry.
|
|
48
48
|
* Returns undefined if not found.
|
|
49
49
|
*/
|
|
50
|
-
export declare function getMutator(registry:
|
|
50
|
+
export declare function getMutator<MD extends AnyMutatorDefinitions, TSchema extends Schema = DefaultSchema>(registry: MutatorRegistry<MD, TSchema>, name: string): FromMutatorTree<MD, TSchema> | undefined;
|
|
51
51
|
/**
|
|
52
52
|
* Gets a Mutator by its dot-separated name from a MutatorRegistry.
|
|
53
53
|
* Throws if not found.
|
|
54
54
|
*/
|
|
55
|
-
export declare function mustGetMutator(registry:
|
|
55
|
+
export declare function mustGetMutator<MD extends AnyMutatorDefinitions, TSchema extends Schema = DefaultSchema>(registry: MutatorRegistry<MD, TSchema>, name: string): FromMutatorTree<MD, TSchema>;
|
|
56
56
|
/**
|
|
57
57
|
* Checks if a value is a MutatorRegistry.
|
|
58
58
|
*/
|
|
59
|
-
export declare function isMutatorRegistry<
|
|
59
|
+
export declare function isMutatorRegistry<MD extends AnyMutatorDefinitions, TSchema extends Schema = DefaultSchema>(value: unknown): value is MutatorRegistry<MD, TSchema>;
|
|
60
|
+
/**
|
|
61
|
+
* Creates a function that can be used to define mutators with a specific schema.
|
|
62
|
+
*/
|
|
63
|
+
export declare function defineMutatorsWithType<TSchema extends Schema>(): TypedDefineMutators<TSchema>;
|
|
64
|
+
/**
|
|
65
|
+
* The return type of defineMutatorsWithType. A function matching the
|
|
66
|
+
* defineMutators overloads but with Schema pre-bound.
|
|
67
|
+
*/
|
|
68
|
+
type TypedDefineMutators<S extends Schema> = {
|
|
69
|
+
<MD>(definitions: MD & AssertMutatorDefinitions<MD>): MutatorRegistry<EnsureMutatorDefinitions<MD>, S>;
|
|
70
|
+
<TBase, TOverrides>(base: MutatorRegistry<EnsureMutatorDefinitions<TBase>, S> | (TBase & AssertMutatorDefinitions<TBase>), overrides: TOverrides): MutatorRegistry<DeepMerge<EnsureMutatorDefinitions<TBase>, EnsureMutatorDefinitions<TOverrides>>, S>;
|
|
71
|
+
};
|
|
60
72
|
/**
|
|
61
73
|
* A tree of MutatorDefinitions, possibly nested.
|
|
62
74
|
*/
|
|
63
|
-
export type MutatorDefinitions<
|
|
64
|
-
readonly [key: string]:
|
|
65
|
-
MutatorDefinition<any, any, S, C, any> | MutatorDefinitions<S, C>;
|
|
75
|
+
export type MutatorDefinitions<Context, WrappedTransaction> = {
|
|
76
|
+
readonly [key: string]: MutatorDefinition<any, any, Context, WrappedTransaction> | MutatorDefinitions<Context, WrappedTransaction>;
|
|
66
77
|
};
|
|
78
|
+
export type AnyMutatorDefinitions = MutatorDefinitions<any, any>;
|
|
79
|
+
export type AssertMutatorDefinitions<MD> = MD extends AnyMutatorDefinitions ? unknown : never;
|
|
80
|
+
export type EnsureMutatorDefinitions<MD> = MD extends AnyMutatorDefinitions ? MD : never;
|
|
67
81
|
/**
|
|
68
82
|
* The result of defineMutators(). A tree of Mutators with a tag for detection.
|
|
69
83
|
*/
|
|
70
|
-
export type MutatorRegistry<
|
|
84
|
+
export type MutatorRegistry<MD extends AnyMutatorDefinitions, TSchema extends Schema> = ToMutatorTree<MD, TSchema> & {
|
|
71
85
|
[mutatorRegistryTag]: true;
|
|
72
86
|
};
|
|
73
87
|
/**
|
|
@@ -77,17 +91,21 @@ export type MutatorRegistry<S extends Schema, C, T extends MutatorDefinitions<S,
|
|
|
77
91
|
*/
|
|
78
92
|
export type AnyMutatorRegistry = {
|
|
79
93
|
[mutatorRegistryTag]: true;
|
|
80
|
-
|
|
94
|
+
[key: string]: unknown;
|
|
95
|
+
};
|
|
81
96
|
declare const mutatorRegistryTag: unique symbol;
|
|
82
97
|
/**
|
|
83
98
|
* Transforms a MutatorDefinitions into a tree of Mutators.
|
|
84
99
|
* Each MutatorDefinition becomes a Mutator at the same path.
|
|
85
100
|
* Uses TInput for the callable args (TOutput is only used internally for validation).
|
|
86
101
|
*/
|
|
87
|
-
type ToMutatorTree<
|
|
88
|
-
readonly [K in keyof
|
|
89
|
-
S, C, infer TWrappedTransaction> ? Mutator<TInput, S, C, TWrappedTransaction> : T[K] extends MutatorDefinitions<S, C> ? ToMutatorTree<S, C, T[K]> : never;
|
|
102
|
+
export type ToMutatorTree<MD extends AnyMutatorDefinitions, TSchema extends Schema> = {
|
|
103
|
+
readonly [K in keyof MD]: MD[K] extends MutatorDefinition<any, any, any, any> ? Mutator<MD[K]['~']['$input'], TSchema, MD[K]['~']['$context'], MD[K]['~']['$wrappedTransaction']> : MD[K] extends AnyMutatorDefinitions ? ToMutatorTree<MD[K], TSchema> : never;
|
|
90
104
|
};
|
|
105
|
+
export type FromMutatorTree<MD extends AnyMutatorDefinitions, TSchema extends Schema> = {
|
|
106
|
+
readonly [K in keyof MD]: MD[K] extends MutatorDefinition<any, any, any, any> ? Mutator<ReadonlyJSONValue | undefined, // intentionally left as generic to avoid variance issues
|
|
107
|
+
TSchema, MD[K]['~']['$context'], MD[K]['~']['$wrappedTransaction']> : MD[K] extends AnyMutatorDefinitions ? FromMutatorTree<MD[K], TSchema> : never;
|
|
108
|
+
}[keyof MD];
|
|
91
109
|
export declare function iterateMutators(registry: AnyMutatorRegistry): Iterable<AnyMutator>;
|
|
92
110
|
export {};
|
|
93
111
|
//# sourceMappingURL=mutator-registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutator-registry.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/mutator-registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mutator-registry.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/mutator-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,10 +13,7 @@ function defineMutators(definitionsOrBase, maybeOverrides) {
|
|
|
13
13
|
if (isMutatorDefinition(value)) {
|
|
14
14
|
result[key] = createMutator(name, value);
|
|
15
15
|
} else {
|
|
16
|
-
result[key] = processDefinitions(
|
|
17
|
-
value,
|
|
18
|
-
path
|
|
19
|
-
);
|
|
16
|
+
result[key] = processDefinitions(value, path);
|
|
20
17
|
}
|
|
21
18
|
path.pop();
|
|
22
19
|
}
|
|
@@ -25,10 +22,7 @@ function defineMutators(definitionsOrBase, maybeOverrides) {
|
|
|
25
22
|
if (maybeOverrides !== void 0) {
|
|
26
23
|
let base;
|
|
27
24
|
if (!isMutatorRegistry(definitionsOrBase)) {
|
|
28
|
-
base = processDefinitions(
|
|
29
|
-
definitionsOrBase,
|
|
30
|
-
[]
|
|
31
|
-
);
|
|
25
|
+
base = processDefinitions(definitionsOrBase, []);
|
|
32
26
|
} else {
|
|
33
27
|
base = definitionsOrBase;
|
|
34
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutator-registry.js","sources":["../../../../../zql/src/mutate/mutator-registry.ts"],"sourcesContent":["import {deepMerge, type DeepMerge} from '../../../shared/src/deep-merge.ts';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {\n getValueAtPath,\n iterateLeaves,\n} from '../../../shared/src/object-traversal.ts';\nimport type {\n DefaultContext,\n DefaultSchema,\n} from '../../../zero-types/src/default-types.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport {validateInput} from '../query/validate-input.ts';\nimport type {Transaction} from './custom.ts';\nimport {\n isMutator,\n isMutatorDefinition,\n type AnyMutator,\n type MutationRequest,\n type Mutator,\n type MutatorDefinition,\n} from './mutator.ts';\n\n/**\n * Creates a MutatorRegistry from a tree of MutatorDefinitions,\n * optionally extending a base MutatorRegistry.\n *\n * @example\n * ```ts\n * // Create a new registry\n * const mutators = defineMutators({\n * user: {\n * create: defineMutator(...),\n * delete: defineMutator(...),\n * },\n * post: {\n * publish: defineMutator(...),\n * },\n * });\n *\n * // Extend an existing registry (e.g., for server-side overrides)\n * const serverMutators = defineMutators(mutators, {\n * user: {\n * create: defineMutator(...), // overrides mutators.user.create\n * },\n * // post.publish is inherited from mutators\n * });\n *\n * // Access mutators by path\n * const mr = mutators.user.create({name: 'Alice'});\n *\n * // Execute on client\n * zero.mutate(mr);\n *\n * // Execute on server\n * mr.mutator.fn({tx, ctx, args: mr.args});\n *\n * // Lookup by name (for server-side dispatch)\n * const mutator = getMutator(mutators, 'user.create');\n * ```\n */\nexport function defineMutators<\n T extends MutatorDefinitions<S, C>,\n S extends Schema = DefaultSchema,\n C = DefaultContext,\n>(definitions: T): MutatorRegistry<S, C, T>;\n\nexport function defineMutators<\n TBase extends MutatorDefinitions<S, C>,\n TOverrides extends MutatorDefinitions<S, C>,\n S extends Schema = DefaultSchema,\n C = DefaultContext,\n>(\n base: MutatorRegistry<S, C, TBase>,\n overrides: TOverrides,\n): MutatorRegistry<S, C, DeepMerge<TBase, TOverrides>>;\n\nexport function defineMutators<\n TBase extends MutatorDefinitions<S, C>,\n TOverrides extends MutatorDefinitions<S, C>,\n S extends Schema = DefaultSchema,\n C = DefaultContext,\n>(\n base: TBase,\n overrides: TOverrides,\n): MutatorRegistry<S, C, DeepMerge<TBase, TOverrides>>;\n\nexport function defineMutators<S extends Schema, C>(\n definitionsOrBase: MutatorDefinitions<S, C> | AnyMutatorRegistry,\n maybeOverrides?: MutatorDefinitions<S, C>,\n): AnyMutatorRegistry {\n function processDefinitions(\n definitions: MutatorDefinitions<S, C>,\n path: string[],\n ): Record<string | symbol, unknown> {\n const result: Record<string | symbol, unknown> = {\n [mutatorRegistryTag]: true,\n };\n\n for (const [key, value] of Object.entries(definitions)) {\n path.push(key);\n const name = path.join('.');\n\n if (isMutatorDefinition(value)) {\n result[key] = createMutator(name, value);\n } else {\n // Nested definitions\n result[key] = processDefinitions(\n value as MutatorDefinitions<S, C>,\n path,\n );\n }\n path.pop();\n }\n\n return result;\n }\n\n if (maybeOverrides !== undefined) {\n // Merge base and overrides\n let base: Record<string | symbol, unknown>;\n if (!isMutatorRegistry(definitionsOrBase)) {\n base = processDefinitions(\n definitionsOrBase as MutatorDefinitions<S, C>,\n [],\n );\n } else {\n base = definitionsOrBase;\n }\n\n const processed = processDefinitions(maybeOverrides, []);\n\n const merged = deepMerge(base, processed, isMutator) as Record<\n string | symbol,\n unknown\n >;\n // deepMerge doesn't copy symbols, so we need to add the tag\n merged[mutatorRegistryTag] = true;\n return merged as AnyMutatorRegistry;\n }\n\n return processDefinitions(\n definitionsOrBase as MutatorDefinitions<S, C>,\n [],\n ) as AnyMutatorRegistry;\n}\n\n/**\n * Gets a Mutator by its dot-separated name from a MutatorRegistry.\n * Returns undefined if not found.\n */\nexport function getMutator(\n registry: AnyMutatorRegistry,\n name: string,\n): AnyMutator | undefined {\n const m = getValueAtPath(registry, name, '.');\n return m as AnyMutator | undefined;\n}\n\n/**\n * Gets a Mutator by its dot-separated name from a MutatorRegistry.\n * Throws if not found.\n */\nexport function mustGetMutator(\n registry: AnyMutatorRegistry,\n name: string,\n): AnyMutator {\n const mutator = getMutator(registry, name);\n if (mutator === undefined) {\n throw new Error(`Mutator not found: ${name}`);\n }\n return mutator;\n}\n\n/**\n * Checks if a value is a MutatorRegistry.\n */\nexport function isMutatorRegistry<S extends Schema, C>(\n value: unknown,\n): value is MutatorRegistry<S, C, MutatorDefinitions<S, C>> {\n return (\n typeof value === 'object' && value !== null && mutatorRegistryTag in value\n );\n}\n\n// ----------------------------------------------------------------------------\n// Types\n// ----------------------------------------------------------------------------\n\n/**\n * A tree of MutatorDefinitions, possibly nested.\n */\nexport type MutatorDefinitions<S extends Schema, C> = {\n readonly [key: string]: // oxlint-disable-next-line no-explicit-any\n MutatorDefinition<any, any, S, C, any> | MutatorDefinitions<S, C>;\n};\n\n/**\n * The result of defineMutators(). A tree of Mutators with a tag for detection.\n */\nexport type MutatorRegistry<\n S extends Schema,\n C,\n T extends MutatorDefinitions<S, C>,\n> = ToMutatorTree<S, C, T> & {\n [mutatorRegistryTag]: true;\n};\n\n/**\n * A branded type for use in type constraints. Use this instead of\n * `MutatorRegistry<S, C, any>` to avoid TypeScript drilling into\n * the complex ToMutatorTree structure and hitting variance issues.\n */\nexport type AnyMutatorRegistry = {[mutatorRegistryTag]: true} & Record<\n string,\n unknown\n>;\n\n// ----------------------------------------------------------------------------\n// Internal\n// ----------------------------------------------------------------------------\n\nconst mutatorRegistryTag = Symbol('mutatorRegistry');\n\n/**\n * Transforms a MutatorDefinitions into a tree of Mutators.\n * Each MutatorDefinition becomes a Mutator at the same path.\n * Uses TInput for the callable args (TOutput is only used internally for validation).\n */\ntype ToMutatorTree<S extends Schema, C, T extends MutatorDefinitions<S, C>> = {\n readonly [K in keyof T]: T[K] extends MutatorDefinition<\n infer TInput,\n // oxlint-disable-next-line no-explicit-any\n any, // TOutput - only used internally for validation\n S,\n C,\n infer TWrappedTransaction\n >\n ? Mutator<TInput, S, C, TWrappedTransaction>\n : T[K] extends MutatorDefinitions<S, C>\n ? ToMutatorTree<S, C, T[K]>\n : never;\n};\n\nfunction createMutator<\n S extends Schema,\n C,\n ArgsInput extends ReadonlyJSONValue | undefined,\n ArgsOutput extends ReadonlyJSONValue | undefined,\n TWrappedTransaction,\n>(\n name: string,\n definition: MutatorDefinition<\n ArgsInput,\n ArgsOutput,\n S,\n C,\n TWrappedTransaction\n >,\n): Mutator<ArgsInput, S, C, TWrappedTransaction> {\n const {validator} = definition;\n\n // fn takes ReadonlyJSONValue args because it's called during rebase (from\n // stored JSON) and on the server (from wire format). Validation happens here.\n const fn = async (options: {\n args: ArgsInput;\n ctx: C;\n tx: Transaction<S, TWrappedTransaction>;\n }): Promise<void> => {\n const validatedArgs = validator\n ? validateInput<ArgsInput, ArgsOutput>(\n name,\n options.args,\n validator,\n 'mutator',\n )\n : (options.args as unknown as ArgsOutput);\n await definition({\n args: validatedArgs,\n ctx: options.ctx,\n tx: options.tx,\n });\n };\n\n // Create the callable mutator\n const mutator = (\n args: ArgsInput,\n ): MutationRequest<ArgsInput, S, C, Transaction<S, TWrappedTransaction>> => ({\n mutator: mutator as unknown as Mutator<\n ArgsInput,\n S,\n C,\n Transaction<S, TWrappedTransaction>\n >,\n args,\n });\n mutator.mutatorName = name;\n mutator.fn = fn;\n\n return mutator as unknown as Mutator<\n ArgsInput,\n S,\n C,\n Transaction<S, TWrappedTransaction>\n >;\n}\n\nexport function* iterateMutators(\n registry: AnyMutatorRegistry,\n): Iterable<AnyMutator> {\n yield* iterateLeaves(registry, isMutator);\n}\n"],"names":[],"mappings":";;;;AAsFO,SAAS,eACd,mBACA,gBACoB;AACpB,WAAS,mBACP,aACA,MACkC;AAClC,UAAM,SAA2C;AAAA,MAC/C,CAAC,kBAAkB,GAAG;AAAA,IAAA;AAGxB,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,WAAW,GAAG;AACtD,WAAK,KAAK,GAAG;AACb,YAAM,OAAO,KAAK,KAAK,GAAG;AAE1B,UAAI,oBAAoB,KAAK,GAAG;AAC9B,eAAO,GAAG,IAAI,cAAc,MAAM,KAAK;AAAA,MACzC,OAAO;AAEL,eAAO,GAAG,IAAI;AAAA,UACZ;AAAA,UACA;AAAA,QAAA;AAAA,MAEJ;AACA,WAAK,IAAA;AAAA,IACP;AAEA,WAAO;AAAA,EACT;AAEA,MAAI,mBAAmB,QAAW;AAEhC,QAAI;AACJ,QAAI,CAAC,kBAAkB,iBAAiB,GAAG;AACzC,aAAO;AAAA,QACL;AAAA,QACA,CAAA;AAAA,MAAC;AAAA,IAEL,OAAO;AACL,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,mBAAmB,gBAAgB,EAAE;AAEvD,UAAM,SAAS,UAAU,MAAM,WAAW,SAAS;AAKnD,WAAO,kBAAkB,IAAI;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA,CAAA;AAAA,EAAC;AAEL;AAMO,SAAS,WACd,UACA,MACwB;AACxB,QAAM,IAAI,eAAe,UAAU,MAAM,GAAG;AAC5C,SAAO;AACT;AAMO,SAAS,eACd,UACA,MACY;AACZ,QAAM,UAAU,WAAW,UAAU,IAAI;AACzC,MAAI,YAAY,QAAW;AACzB,UAAM,IAAI,MAAM,sBAAsB,IAAI,EAAE;AAAA,EAC9C;AACA,SAAO;AACT;AAKO,SAAS,kBACd,OAC0D;AAC1D,SACE,OAAO,UAAU,YAAY,UAAU,QAAQ,sBAAsB;AAEzE;AAuCA,MAAM,qBAAqB,OAAO,iBAAiB;AAsBnD,SAAS,cAOP,MACA,YAO+C;AAC/C,QAAM,EAAC,cAAa;AAIpB,QAAM,KAAK,OAAO,YAIG;AACnB,UAAM,gBAAgB,YAClB;AAAA,MACE;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IAAA,IAED,QAAQ;AACb,UAAM,WAAW;AAAA,MACf,MAAM;AAAA,MACN,KAAK,QAAQ;AAAA,MACb,IAAI,QAAQ;AAAA,IAAA,CACb;AAAA,EACH;AAGA,QAAM,UAAU,CACd,UAC2E;AAAA,IAC3E;AAAA,IAMA;AAAA,EAAA;AAEF,UAAQ,cAAc;AACtB,UAAQ,KAAK;AAEb,SAAO;AAMT;AAEO,UAAU,gBACf,UACsB;AACtB,SAAO,cAAc,UAAU,SAAS;AAC1C;"}
|
|
1
|
+
{"version":3,"file":"mutator-registry.js","sources":["../../../../../zql/src/mutate/mutator-registry.ts"],"sourcesContent":["// oxlint-disable no-explicit-any\nimport {deepMerge, type DeepMerge} from '../../../shared/src/deep-merge.ts';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {\n getValueAtPath,\n iterateLeaves,\n} from '../../../shared/src/object-traversal.ts';\nimport type {DefaultSchema} from '../../../zero-types/src/default-types.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport {validateInput} from '../query/validate-input.ts';\nimport type {AnyTransaction} from './custom.ts';\nimport {\n isMutator,\n isMutatorDefinition,\n type AnyMutator,\n type MutationRequest,\n type Mutator,\n type MutatorDefinition,\n} from './mutator.ts';\n\n/**\n * Creates a MutatorRegistry from a tree of MutatorDefinitions,\n * optionally extending a base MutatorRegistry.\n *\n * @example\n * ```ts\n * // Create a new registry\n * const mutators = defineMutators({\n * user: {\n * create: defineMutator(...),\n * delete: defineMutator(...),\n * },\n * post: {\n * publish: defineMutator(...),\n * },\n * });\n *\n * // Extend an existing registry (e.g., for server-side overrides)\n * const serverMutators = defineMutators(mutators, {\n * user: {\n * create: defineMutator(...), // overrides mutators.user.create\n * },\n * // post.publish is inherited from mutators\n * });\n *\n * // Access mutators by path\n * const mr = mutators.user.create({name: 'Alice'});\n *\n * // Execute on client\n * zero.mutate(mr);\n *\n * // Execute on server\n * mr.mutator.fn({tx, ctx, args: mr.args});\n *\n * // Lookup by name (for server-side dispatch)\n * const mutator = getMutator(mutators, 'user.create');\n * ```\n */\nexport function defineMutators<\n // let MD infer freely so defaults aren't erased by a AnyMutatorDefinitions constraint\n const MD,\n S extends Schema = DefaultSchema,\n>(\n // we assert types here for clear error messages\n definitions: MD & AssertMutatorDefinitions<MD>,\n): MutatorRegistry<EnsureMutatorDefinitions<MD>, S>;\n\nexport function defineMutators<\n // same as MD above, but for TBase and TOverrides\n const TBase,\n const TOverrides,\n S extends Schema = DefaultSchema,\n>(\n base:\n | MutatorRegistry<EnsureMutatorDefinitions<TBase>, S>\n | (TBase & AssertMutatorDefinitions<TBase>),\n overrides: TOverrides & AssertMutatorDefinitions<TOverrides>,\n): MutatorRegistry<\n DeepMerge<\n EnsureMutatorDefinitions<TBase>,\n EnsureMutatorDefinitions<TOverrides>\n >,\n S\n>;\n\nexport function defineMutators(\n definitionsOrBase: AnyMutatorDefinitions | AnyMutatorRegistry,\n maybeOverrides?: AnyMutatorDefinitions,\n): AnyMutatorRegistry {\n function processDefinitions(\n definitions: AnyMutatorDefinitions,\n path: string[],\n ): Record<string | symbol, unknown> {\n const result: Record<string | symbol, unknown> = {\n [mutatorRegistryTag]: true,\n };\n\n for (const [key, value] of Object.entries(definitions)) {\n path.push(key);\n const name = path.join('.');\n\n if (isMutatorDefinition(value)) {\n result[key] = createMutator(name, value);\n } else {\n // Nested definitions\n result[key] = processDefinitions(value as AnyMutatorDefinitions, path);\n }\n path.pop();\n }\n\n return result;\n }\n\n if (maybeOverrides !== undefined) {\n // Merge base and overrides\n let base: Record<string | symbol, unknown>;\n if (!isMutatorRegistry(definitionsOrBase)) {\n base = processDefinitions(definitionsOrBase as AnyMutatorDefinitions, []);\n } else {\n base = definitionsOrBase;\n }\n\n const processed = processDefinitions(maybeOverrides, []);\n\n const merged = deepMerge(base, processed, isMutator) as Record<\n string | symbol,\n unknown\n >;\n // deepMerge doesn't copy symbols, so we need to add the tag\n merged[mutatorRegistryTag] = true;\n return merged as AnyMutatorRegistry;\n }\n\n return processDefinitions(\n definitionsOrBase as AnyMutatorDefinitions,\n [],\n ) as AnyMutatorRegistry;\n}\n\n/**\n * Gets a Mutator by its dot-separated name from a MutatorRegistry.\n * Returns undefined if not found.\n */\nexport function getMutator<\n MD extends AnyMutatorDefinitions,\n TSchema extends Schema = DefaultSchema,\n>(\n registry: MutatorRegistry<MD, TSchema>,\n name: string,\n): FromMutatorTree<MD, TSchema> | undefined {\n const m = getValueAtPath(registry, name, '.');\n return m as FromMutatorTree<MD, TSchema> | undefined;\n}\n\n/**\n * Gets a Mutator by its dot-separated name from a MutatorRegistry.\n * Throws if not found.\n */\nexport function mustGetMutator<\n MD extends AnyMutatorDefinitions,\n TSchema extends Schema = DefaultSchema,\n>(\n registry: MutatorRegistry<MD, TSchema>,\n name: string,\n): FromMutatorTree<MD, TSchema> {\n const mutator = getMutator(registry, name);\n if (mutator === undefined) {\n throw new Error(`Mutator not found: ${name}`);\n }\n return mutator;\n}\n\n/**\n * Checks if a value is a MutatorRegistry.\n */\nexport function isMutatorRegistry<\n MD extends AnyMutatorDefinitions,\n TSchema extends Schema = DefaultSchema,\n>(value: unknown): value is MutatorRegistry<MD, TSchema> {\n return (\n typeof value === 'object' && value !== null && mutatorRegistryTag in value\n );\n}\n\n/**\n * Creates a function that can be used to define mutators with a specific schema.\n */\nexport function defineMutatorsWithType<\n TSchema extends Schema,\n>(): TypedDefineMutators<TSchema> {\n return defineMutators;\n}\n\n/**\n * The return type of defineMutatorsWithType. A function matching the\n * defineMutators overloads but with Schema pre-bound.\n */\ntype TypedDefineMutators<S extends Schema> = {\n // Single definitions\n <MD>(\n definitions: MD & AssertMutatorDefinitions<MD>,\n ): MutatorRegistry<EnsureMutatorDefinitions<MD>, S>;\n\n // Base and overrides\n <TBase, TOverrides>(\n base:\n | MutatorRegistry<EnsureMutatorDefinitions<TBase>, S>\n | (TBase & AssertMutatorDefinitions<TBase>),\n overrides: TOverrides,\n ): MutatorRegistry<\n DeepMerge<\n EnsureMutatorDefinitions<TBase>,\n EnsureMutatorDefinitions<TOverrides>\n >,\n S\n >;\n};\n\n// ----------------------------------------------------------------------------\n// Types\n// ----------------------------------------------------------------------------\n\n/**\n * A tree of MutatorDefinitions, possibly nested.\n */\nexport type MutatorDefinitions<Context, WrappedTransaction> = {\n readonly [key: string]:\n | MutatorDefinition<any, any, Context, WrappedTransaction>\n | MutatorDefinitions<Context, WrappedTransaction>;\n};\n\nexport type AnyMutatorDefinitions = MutatorDefinitions<any, any>;\n\nexport type AssertMutatorDefinitions<MD> = MD extends AnyMutatorDefinitions\n ? unknown\n : never;\n\nexport type EnsureMutatorDefinitions<MD> = MD extends AnyMutatorDefinitions\n ? MD\n : never;\n\n/**\n * The result of defineMutators(). A tree of Mutators with a tag for detection.\n */\nexport type MutatorRegistry<\n MD extends AnyMutatorDefinitions,\n TSchema extends Schema,\n> = ToMutatorTree<MD, TSchema> & {\n [mutatorRegistryTag]: true;\n};\n\n/**\n * A branded type for use in type constraints. Use this instead of\n * `MutatorRegistry<S, C, any>` to avoid TypeScript drilling into\n * the complex ToMutatorTree structure and hitting variance issues.\n */\nexport type AnyMutatorRegistry = {\n [mutatorRegistryTag]: true;\n [key: string]: unknown;\n};\n\n// ----------------------------------------------------------------------------\n// Internal\n// ----------------------------------------------------------------------------\n\nconst mutatorRegistryTag = Symbol('mutatorRegistry');\n\n/**\n * Transforms a MutatorDefinitions into a tree of Mutators.\n * Each MutatorDefinition becomes a Mutator at the same path.\n * Uses TInput for the callable args (TOutput is only used internally for validation).\n */\nexport type ToMutatorTree<\n MD extends AnyMutatorDefinitions,\n TSchema extends Schema,\n> = {\n readonly [K in keyof MD]: MD[K] extends MutatorDefinition<any, any, any, any>\n ? // pull types from the phantom property\n Mutator<\n MD[K]['~']['$input'],\n TSchema,\n MD[K]['~']['$context'],\n MD[K]['~']['$wrappedTransaction']\n >\n : MD[K] extends AnyMutatorDefinitions\n ? ToMutatorTree<MD[K], TSchema>\n : never;\n};\n\nexport type FromMutatorTree<\n MD extends AnyMutatorDefinitions,\n TSchema extends Schema,\n> = {\n readonly [K in keyof MD]: MD[K] extends MutatorDefinition<any, any, any, any>\n ? // pull types from the phantom property\n Mutator<\n ReadonlyJSONValue | undefined, // intentionally left as generic to avoid variance issues\n TSchema,\n MD[K]['~']['$context'],\n MD[K]['~']['$wrappedTransaction']\n >\n : MD[K] extends AnyMutatorDefinitions\n ? FromMutatorTree<MD[K], TSchema>\n : never;\n}[keyof MD];\n\nfunction createMutator<\n ArgsInput extends ReadonlyJSONValue | undefined,\n ArgsOutput extends ReadonlyJSONValue | undefined,\n TSchema extends Schema,\n C,\n TWrappedTransaction,\n>(\n name: string,\n definition: MutatorDefinition<ArgsInput, ArgsOutput, C, TWrappedTransaction>,\n): Mutator<ArgsInput, TSchema, C, TWrappedTransaction> {\n const {validator} = definition;\n\n // fn takes ReadonlyJSONValue args because it's called during rebase (from\n // stored JSON) and on the server (from wire format). Validation happens here.\n const fn = async (options: {\n args: ArgsInput;\n ctx: C;\n tx: AnyTransaction;\n }): Promise<void> => {\n const validatedArgs = validator\n ? validateInput<ArgsInput, ArgsOutput>(\n name,\n options.args,\n validator,\n 'mutator',\n )\n : (options.args as unknown as ArgsOutput);\n await definition({\n args: validatedArgs,\n ctx: options.ctx,\n tx: options.tx,\n });\n };\n\n // Create the callable mutator\n const mutator = (\n args: ArgsInput,\n ): MutationRequest<ArgsInput, TSchema, C, TWrappedTransaction> => ({\n mutator: mutator as unknown as Mutator<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >,\n args,\n });\n mutator.mutatorName = name;\n mutator.fn = fn;\n\n return mutator as unknown as Mutator<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >;\n}\n\nexport function* iterateMutators(\n registry: AnyMutatorRegistry,\n): Iterable<AnyMutator> {\n yield* iterateLeaves(registry, isMutator);\n}\n"],"names":[],"mappings":";;;;AAqFO,SAAS,eACd,mBACA,gBACoB;AACpB,WAAS,mBACP,aACA,MACkC;AAClC,UAAM,SAA2C;AAAA,MAC/C,CAAC,kBAAkB,GAAG;AAAA,IAAA;AAGxB,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,WAAW,GAAG;AACtD,WAAK,KAAK,GAAG;AACb,YAAM,OAAO,KAAK,KAAK,GAAG;AAE1B,UAAI,oBAAoB,KAAK,GAAG;AAC9B,eAAO,GAAG,IAAI,cAAc,MAAM,KAAK;AAAA,MACzC,OAAO;AAEL,eAAO,GAAG,IAAI,mBAAmB,OAAgC,IAAI;AAAA,MACvE;AACA,WAAK,IAAA;AAAA,IACP;AAEA,WAAO;AAAA,EACT;AAEA,MAAI,mBAAmB,QAAW;AAEhC,QAAI;AACJ,QAAI,CAAC,kBAAkB,iBAAiB,GAAG;AACzC,aAAO,mBAAmB,mBAA4C,EAAE;AAAA,IAC1E,OAAO;AACL,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,mBAAmB,gBAAgB,EAAE;AAEvD,UAAM,SAAS,UAAU,MAAM,WAAW,SAAS;AAKnD,WAAO,kBAAkB,IAAI;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL;AAAA,IACA,CAAA;AAAA,EAAC;AAEL;AAMO,SAAS,WAId,UACA,MAC0C;AAC1C,QAAM,IAAI,eAAe,UAAU,MAAM,GAAG;AAC5C,SAAO;AACT;AAMO,SAAS,eAId,UACA,MAC8B;AAC9B,QAAM,UAAU,WAAW,UAAU,IAAI;AACzC,MAAI,YAAY,QAAW;AACzB,UAAM,IAAI,MAAM,sBAAsB,IAAI,EAAE;AAAA,EAC9C;AACA,SAAO;AACT;AAKO,SAAS,kBAGd,OAAuD;AACvD,SACE,OAAO,UAAU,YAAY,UAAU,QAAQ,sBAAsB;AAEzE;AAmFA,MAAM,qBAAqB,OAAO,iBAAiB;AAyCnD,SAAS,cAOP,MACA,YACqD;AACrD,QAAM,EAAC,cAAa;AAIpB,QAAM,KAAK,OAAO,YAIG;AACnB,UAAM,gBAAgB,YAClB;AAAA,MACE;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IAAA,IAED,QAAQ;AACb,UAAM,WAAW;AAAA,MACf,MAAM;AAAA,MACN,KAAK,QAAQ;AAAA,MACb,IAAI,QAAQ;AAAA,IAAA,CACb;AAAA,EACH;AAGA,QAAM,UAAU,CACd,UACiE;AAAA,IACjE;AAAA,IAMA;AAAA,EAAA;AAEF,UAAQ,cAAc;AACtB,UAAQ,KAAK;AAEb,SAAO;AAMT;AAEO,UAAU,gBACf,UACsB;AACtB,SAAO,cAAc,UAAU,SAAS;AAC1C;"}
|
|
@@ -1,28 +1,58 @@
|
|
|
1
1
|
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
+
import type { Expand } from '../../../shared/src/expand.ts';
|
|
2
3
|
import type { ReadonlyJSONValue } from '../../../shared/src/json.ts';
|
|
3
4
|
import type { DefaultContext, DefaultSchema, DefaultWrappedTransaction } from '../../../zero-types/src/default-types.ts';
|
|
4
5
|
import type { Schema } from '../../../zero-types/src/schema.ts';
|
|
5
6
|
import type { AnyTransaction, Transaction } from './custom.ts';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
export type MutatorDefinitionTypes<TInput extends ReadonlyJSONValue | undefined, TOutput, TContext, TWrappedTransaction> = 'MutatorDefinition' & {
|
|
8
|
+
readonly $input: TInput;
|
|
9
|
+
readonly $output: TOutput;
|
|
10
|
+
readonly $context: TContext;
|
|
11
|
+
readonly $wrappedTransaction: TWrappedTransaction;
|
|
12
|
+
};
|
|
13
|
+
export declare function isMutatorDefinition<TInput extends ReadonlyJSONValue | undefined, TOutput extends ReadonlyJSONValue | undefined, TContext = DefaultContext, TWrappedTransaction = DefaultWrappedTransaction>(f: unknown): f is MutatorDefinition<TInput, TOutput, TContext, TWrappedTransaction>;
|
|
14
|
+
export type MutatorDefinition<TInput extends ReadonlyJSONValue | undefined, TOutput extends ReadonlyJSONValue | undefined, TContext = DefaultContext, TWrappedTransaction = DefaultWrappedTransaction> = ((options: {
|
|
9
15
|
args: TOutput;
|
|
10
16
|
ctx: TContext;
|
|
11
|
-
tx:
|
|
17
|
+
tx: AnyTransaction;
|
|
12
18
|
}) => Promise<void>) & {
|
|
13
|
-
[defineMutatorTag]: true;
|
|
14
19
|
validator: StandardSchemaV1<TInput, TOutput> | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Type-only phantom property to surface mutator types in a covariant position.
|
|
22
|
+
*/
|
|
23
|
+
['~']: Expand<MutatorDefinitionTypes<TInput, TOutput, TContext, TWrappedTransaction>>;
|
|
15
24
|
};
|
|
16
|
-
export declare function defineMutator<TInput extends ReadonlyJSONValue | undefined, TOutput extends ReadonlyJSONValue | undefined, TSchema extends Schema = DefaultSchema, TContext = DefaultContext, TWrappedTransaction = DefaultWrappedTransaction>(validator: StandardSchemaV1<TInput, TOutput>, mutator: (options: {
|
|
25
|
+
export declare function defineMutator<TInput extends ReadonlyJSONValue | undefined = undefined, TOutput extends ReadonlyJSONValue | undefined = TInput, TSchema extends Schema = DefaultSchema, TContext = DefaultContext, TWrappedTransaction = DefaultWrappedTransaction>(validator: StandardSchemaV1<TInput, TOutput>, mutator: (options: {
|
|
17
26
|
args: TOutput;
|
|
18
27
|
ctx: TContext;
|
|
19
28
|
tx: Transaction<TSchema, TWrappedTransaction>;
|
|
20
|
-
}) => Promise<void>): MutatorDefinition<TInput, TOutput,
|
|
21
|
-
export declare function defineMutator<
|
|
22
|
-
args:
|
|
29
|
+
}) => Promise<void>): MutatorDefinition<TInput, TOutput, TContext, TWrappedTransaction> & {};
|
|
30
|
+
export declare function defineMutator<TInput extends ReadonlyJSONValue | undefined = ReadonlyJSONValue | undefined, TSchema extends Schema = DefaultSchema, TContext = DefaultContext, TWrappedTransaction = DefaultWrappedTransaction>(mutator: (options: {
|
|
31
|
+
args: TInput;
|
|
23
32
|
ctx: TContext;
|
|
24
33
|
tx: Transaction<TSchema, TWrappedTransaction>;
|
|
25
|
-
}) => Promise<void>): MutatorDefinition<
|
|
34
|
+
}) => Promise<void>): MutatorDefinition<TInput, TInput, TContext, TWrappedTransaction> & {};
|
|
35
|
+
export declare function defineMutatorWithType<TSchema extends Schema, TContext = unknown, TWrappedTransaction = unknown>(): TypedDefineMutator<TSchema, TContext, TWrappedTransaction>;
|
|
36
|
+
/**
|
|
37
|
+
* The return type of defineMutatorWithType. A function matching the
|
|
38
|
+
* defineMutator overloads but with Schema, Context, and WrappedTransaction
|
|
39
|
+
* pre-bound.
|
|
40
|
+
*
|
|
41
|
+
* This is used as a workaround to using DefaultTypes (e.g. when using
|
|
42
|
+
* multiple Zero instances).
|
|
43
|
+
*/
|
|
44
|
+
type TypedDefineMutator<TSchema extends Schema, TContext, TWrappedTransaction> = {
|
|
45
|
+
<TArgs extends ReadonlyJSONValue | undefined>(mutator: (options: {
|
|
46
|
+
args: TArgs;
|
|
47
|
+
ctx: TContext;
|
|
48
|
+
tx: Transaction<TSchema, TWrappedTransaction>;
|
|
49
|
+
}) => Promise<void>): MutatorDefinition<TArgs, TArgs, TContext, TWrappedTransaction>;
|
|
50
|
+
<TInput extends ReadonlyJSONValue | undefined, TOutput extends ReadonlyJSONValue | undefined>(validator: StandardSchemaV1<TInput, TOutput>, mutator: (options: {
|
|
51
|
+
args: TOutput;
|
|
52
|
+
ctx: TContext;
|
|
53
|
+
tx: Transaction<TSchema, TWrappedTransaction>;
|
|
54
|
+
}) => Promise<void>): MutatorDefinition<TInput, TOutput, TContext, TWrappedTransaction>;
|
|
55
|
+
};
|
|
26
56
|
/**
|
|
27
57
|
* A callable wrapper around a MutatorDefinition, created by `defineMutators()`.
|
|
28
58
|
*
|
|
@@ -32,43 +62,38 @@ export declare function defineMutator<TArgs extends ReadonlyJSONValue | undefine
|
|
|
32
62
|
* The `fn` property is used for execution and takes raw JSON args (for rebase
|
|
33
63
|
* and server wire format cases) that are validated internally.
|
|
34
64
|
*
|
|
35
|
-
* @template
|
|
36
|
-
* @template TSchema - The schema type
|
|
65
|
+
* @template TInput - The argument type accepted by the callable (before validation)
|
|
37
66
|
* @template TContext - The context type available during mutation execution
|
|
38
67
|
* @template TWrappedTransaction - The wrapped transaction type
|
|
39
68
|
*/
|
|
40
|
-
export type Mutator<
|
|
69
|
+
export type Mutator<TInput extends ReadonlyJSONValue | undefined, TSchema extends Schema = DefaultSchema, TContext = DefaultContext, TWrappedTransaction = DefaultWrappedTransaction> = MutatorCallable<TInput, TSchema, TContext, TWrappedTransaction> & {
|
|
41
70
|
readonly mutatorName: string;
|
|
42
71
|
/**
|
|
43
72
|
* Execute the mutation. Args are ReadonlyJSONValue because this is called
|
|
44
73
|
* during rebase (from stored JSON) and on the server (from wire format).
|
|
45
74
|
* Validation happens internally before the recipe function runs.
|
|
46
|
-
*
|
|
47
|
-
* The tx parameter uses AnyTransaction to avoid contravariance issues when
|
|
48
|
-
* calling from generic code. The implementation casts to the specific type.
|
|
49
75
|
*/
|
|
50
76
|
readonly fn: (options: {
|
|
51
|
-
args:
|
|
77
|
+
args: TInput;
|
|
52
78
|
ctx: TContext;
|
|
53
|
-
tx:
|
|
79
|
+
tx: Transaction<TSchema, TWrappedTransaction>;
|
|
54
80
|
}) => Promise<void>;
|
|
55
81
|
};
|
|
56
|
-
type MutatorCallable<
|
|
57
|
-
export type AnyMutator = Mutator<any,
|
|
82
|
+
type MutatorCallable<TInput extends ReadonlyJSONValue | undefined, TSchema extends Schema, TContext, TWrappedTransaction> = [TInput] extends [undefined] ? () => MutationRequest<TInput, TSchema, TContext, TWrappedTransaction> : undefined extends TInput ? (args?: TInput) => MutationRequest<TInput, TSchema, TContext, TWrappedTransaction> : (args: TInput) => MutationRequest<TInput, TSchema, TContext, TWrappedTransaction>;
|
|
83
|
+
export type AnyMutator = Mutator<any, any, any, any>;
|
|
58
84
|
/**
|
|
59
85
|
* The result of calling a Mutator with arguments.
|
|
60
86
|
*
|
|
61
87
|
* Created by `mutators.foo.bar(42)`, executed by `zero.mutate(mr)` on the client
|
|
62
88
|
* or `mr.mutator.fn({tx, ctx, args: mr.args})` on the server.
|
|
63
89
|
*
|
|
64
|
-
* @template
|
|
65
|
-
* @template TSchema - The schema type
|
|
90
|
+
* @template TInput - The argument type (before validation, sent to server)
|
|
66
91
|
* @template TContext - The context type available during mutation execution
|
|
67
92
|
* @template TWrappedTransaction - The wrapped transaction type
|
|
68
93
|
*/
|
|
69
|
-
export type MutationRequest<
|
|
70
|
-
readonly mutator: Mutator<
|
|
71
|
-
readonly args:
|
|
94
|
+
export type MutationRequest<TInput extends ReadonlyJSONValue | undefined, TSchema extends Schema = DefaultSchema, TContext = DefaultContext, TWrappedTransaction = DefaultWrappedTransaction> = {
|
|
95
|
+
readonly mutator: Mutator<TInput, TSchema, TContext, TWrappedTransaction>;
|
|
96
|
+
readonly args: TInput;
|
|
72
97
|
};
|
|
73
98
|
/**
|
|
74
99
|
* Checks if a value is a Mutator (the result of processing a MutatorDefinition
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutator.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/mutator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,6BAA6B,CAAC;AAEnE,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,yBAAyB,EAC1B,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,cAAc,EAAE,WAAW,EAAC,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"mutator.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/mutator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { must } from "../../../shared/src/must.js";
|
|
2
|
-
const defineMutatorTag = Symbol();
|
|
3
2
|
function isMutatorDefinition(f) {
|
|
4
|
-
return typeof f === "function" &&
|
|
3
|
+
return typeof f === "function" && f["~"] === "MutatorDefinition";
|
|
5
4
|
}
|
|
6
5
|
function defineMutator(validatorOrMutator, mutator) {
|
|
7
6
|
let validator;
|
|
@@ -14,7 +13,7 @@ function defineMutator(validatorOrMutator, mutator) {
|
|
|
14
13
|
actualMutator = must(mutator);
|
|
15
14
|
}
|
|
16
15
|
const f = actualMutator;
|
|
17
|
-
f[
|
|
16
|
+
f["~"] = "MutatorDefinition";
|
|
18
17
|
f.validator = validator;
|
|
19
18
|
return f;
|
|
20
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutator.js","sources":["../../../../../zql/src/mutate/mutator.ts"],"sourcesContent":["import type {StandardSchemaV1} from '@standard-schema/spec';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport type {\n DefaultContext,\n DefaultSchema,\n DefaultWrappedTransaction,\n} from '../../../zero-types/src/default-types.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {AnyTransaction, Transaction} from './custom.ts';\n\n// ----------------------------------------------------------------------------\n// defineMutator\n// ----------------------------------------------------------------------------\n\nconst defineMutatorTag = Symbol();\n\nexport function isMutatorDefinition<\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends Schema,\n TContext,\n TWrappedTransaction = unknown,\n>(\n f: unknown,\n): f is MutatorDefinition<\n TInput,\n TOutput,\n TSchema,\n TContext,\n TWrappedTransaction\n> {\n // oxlint-disable-next-line no-explicit-any\n return typeof f === 'function' && !!(f as any)[defineMutatorTag];\n}\n\nexport type MutatorDefinition<\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends Schema = DefaultSchema,\n TContext = DefaultContext,\n TWrappedTransaction = DefaultWrappedTransaction,\n> = ((options: {\n args: TOutput;\n ctx: TContext;\n tx: Transaction<TSchema, TWrappedTransaction>;\n}) => Promise<void>) & {\n [defineMutatorTag]: true;\n validator: StandardSchemaV1<TInput, TOutput> | undefined;\n};\n\n// Overload 1: Call with validator\nexport function defineMutator<\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends Schema = DefaultSchema,\n TContext = DefaultContext,\n TWrappedTransaction = DefaultWrappedTransaction,\n>(\n validator: StandardSchemaV1<TInput, TOutput>,\n mutator: (options: {\n args: TOutput;\n ctx: TContext;\n tx: Transaction<TSchema, TWrappedTransaction>;\n }) => Promise<void>,\n): MutatorDefinition<TInput, TOutput, TSchema, TContext, TWrappedTransaction>;\n\n// Overload 2: Call without validator\nexport function defineMutator<\n TArgs extends ReadonlyJSONValue | undefined,\n TSchema extends Schema = DefaultSchema,\n TContext = DefaultContext,\n TWrappedTransaction = DefaultWrappedTransaction,\n>(\n mutator: (options: {\n args: TArgs;\n ctx: TContext;\n tx: Transaction<TSchema, TWrappedTransaction>;\n }) => Promise<void>,\n): MutatorDefinition<TArgs, TArgs, TSchema, TContext, TWrappedTransaction>;\n\n// Implementation\nexport function defineMutator<\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends Schema = DefaultSchema,\n TContext = DefaultContext,\n TWrappedTransaction = DefaultWrappedTransaction,\n>(\n validatorOrMutator:\n | StandardSchemaV1<TInput, TOutput>\n | ((options: {\n args: TOutput;\n ctx: TContext;\n tx: Transaction<TSchema, TWrappedTransaction>;\n }) => Promise<void>),\n mutator?: (options: {\n args: TOutput;\n ctx: TContext;\n tx: Transaction<TSchema, TWrappedTransaction>;\n }) => Promise<void>,\n): MutatorDefinition<TInput, TOutput, TSchema, TContext, TWrappedTransaction> {\n let validator: StandardSchemaV1<TInput, TOutput> | undefined;\n let actualMutator: (options: {\n args: TOutput;\n ctx: TContext;\n tx: Transaction<TSchema, TWrappedTransaction>;\n }) => Promise<void>;\n\n if (typeof validatorOrMutator === 'function') {\n // defineMutator(mutator) - no validator\n validator = undefined;\n actualMutator = validatorOrMutator;\n } else {\n // defineMutator(validator, mutator)\n validator = validatorOrMutator;\n actualMutator = must(mutator);\n }\n\n const f = actualMutator as MutatorDefinition<\n TInput,\n TOutput,\n TSchema,\n TContext,\n TWrappedTransaction\n >;\n f[defineMutatorTag] = true;\n f.validator = validator;\n return f;\n}\n\n// ----------------------------------------------------------------------------\n// Mutator and MutationRequest types\n// ----------------------------------------------------------------------------\n\n/**\n * A callable wrapper around a MutatorDefinition, created by `defineMutators()`.\n *\n * Accessed like `mutators.foo.bar`, and called to create a MutationRequest:\n * `mutators.foo.bar(42)` returns a `MutationRequest`.\n *\n * The `fn` property is used for execution and takes raw JSON args (for rebase\n * and server wire format cases) that are validated internally.\n *\n * @template TArgsInput - The argument type accepted by the callable (before validation)\n * @template TSchema - The schema type\n * @template TContext - The context type available during mutation execution\n * @template TWrappedTransaction - The wrapped transaction type\n */\nexport type Mutator<\n TArgsInput extends ReadonlyJSONValue | undefined,\n TSchema extends Schema = DefaultSchema,\n TContext = DefaultContext,\n TWrappedTransaction = DefaultWrappedTransaction,\n> = MutatorCallable<TSchema, TContext, TArgsInput, TWrappedTransaction> & {\n readonly mutatorName: string;\n /**\n * Execute the mutation. Args are ReadonlyJSONValue because this is called\n * during rebase (from stored JSON) and on the server (from wire format).\n * Validation happens internally before the recipe function runs.\n *\n * The tx parameter uses AnyTransaction to avoid contravariance issues when\n * calling from generic code. The implementation casts to the specific type.\n */\n readonly fn: (options: {\n args: TArgsInput;\n ctx: TContext;\n tx: AnyTransaction;\n }) => Promise<void>;\n};\n\n// Helper type for the callable part of Mutator\n// When TArgsInput is undefined, the function is callable with 0 args\n// When TArgsInput includes undefined (optional), args is optional\n// Otherwise, args is required\ntype MutatorCallable<\n TSchema extends Schema,\n TContext,\n TArgsInput extends ReadonlyJSONValue | undefined,\n TWrappedTransaction,\n> = [TArgsInput] extends [undefined]\n ? () => MutationRequest<TArgsInput, TSchema, TContext, TWrappedTransaction>\n : undefined extends TArgsInput\n ? (\n args?: TArgsInput,\n ) => MutationRequest<TArgsInput, TSchema, TContext, TWrappedTransaction>\n : (\n args: TArgsInput,\n ) => MutationRequest<TArgsInput, TSchema, TContext, TWrappedTransaction>;\n\n// oxlint-disable-next-line no-explicit-any\nexport type AnyMutator = Mutator<any, Schema, any, any>;\n\n/**\n * The result of calling a Mutator with arguments.\n *\n * Created by `mutators.foo.bar(42)`, executed by `zero.mutate(mr)` on the client\n * or `mr.mutator.fn({tx, ctx, args: mr.args})` on the server.\n *\n * @template TArgsInput - The argument type (before validation, sent to server)\n * @template TSchema - The schema type\n * @template TContext - The context type available during mutation execution\n * @template TWrappedTransaction - The wrapped transaction type\n */\nexport type MutationRequest<\n TArgsInput extends ReadonlyJSONValue | undefined,\n TSchema extends Schema,\n TContext,\n TWrappedTransaction,\n> = {\n readonly mutator: Mutator<TArgsInput, TSchema, TContext, TWrappedTransaction>;\n readonly args: TArgsInput;\n};\n\n/**\n * Checks if a value is a Mutator (the result of processing a MutatorDefinition\n * through defineMutators).\n */\nexport function isMutator(value: unknown): value is AnyMutator {\n return (\n typeof value === 'function' &&\n // oxlint-disable-next-line no-explicit-any\n typeof (value as any).mutatorName === 'string' &&\n // oxlint-disable-next-line no-explicit-any\n typeof (value as any).fn === 'function'\n );\n}\n"],"names":[],"mappings":";AAeA,MAAM,mBAAmB,OAAA;AAElB,SAAS,oBAOd,GAOA;AAEA,SAAO,OAAO,MAAM,cAAc,CAAC,CAAE,EAAU,gBAAgB;AACjE;AAgDO,SAAS,cAOd,oBAOA,SAK4E;AAC5E,MAAI;AACJ,MAAI;AAMJ,MAAI,OAAO,uBAAuB,YAAY;AAE5C,gBAAY;AACZ,oBAAgB;AAAA,EAClB,OAAO;AAEL,gBAAY;AACZ,oBAAgB,KAAK,OAAO;AAAA,EAC9B;AAEA,QAAM,IAAI;AAOV,IAAE,gBAAgB,IAAI;AACtB,IAAE,YAAY;AACd,SAAO;AACT;AAyFO,SAAS,UAAU,OAAqC;AAC7D,SACE,OAAO,UAAU;AAAA,EAEjB,OAAQ,MAAc,gBAAgB;AAAA,EAEtC,OAAQ,MAAc,OAAO;AAEjC;"}
|
|
1
|
+
{"version":3,"file":"mutator.js","sources":["../../../../../zql/src/mutate/mutator.ts"],"sourcesContent":["import type {StandardSchemaV1} from '@standard-schema/spec';\nimport type {Expand} from '../../../shared/src/expand.ts';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport type {\n DefaultContext,\n DefaultSchema,\n DefaultWrappedTransaction,\n} from '../../../zero-types/src/default-types.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {AnyTransaction, Transaction} from './custom.ts';\n\n// oxlint-disable no-explicit-any\n\n// ----------------------------------------------------------------------------\n// defineMutator\n// ----------------------------------------------------------------------------\n\nexport type MutatorDefinitionTypes<\n TInput extends ReadonlyJSONValue | undefined,\n TOutput,\n TContext,\n TWrappedTransaction,\n> = 'MutatorDefinition' & {\n readonly $input: TInput;\n readonly $output: TOutput;\n readonly $context: TContext;\n readonly $wrappedTransaction: TWrappedTransaction;\n};\n\nexport function isMutatorDefinition<\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TContext = DefaultContext,\n TWrappedTransaction = DefaultWrappedTransaction,\n>(\n f: unknown,\n): f is MutatorDefinition<TInput, TOutput, TContext, TWrappedTransaction> {\n return typeof f === 'function' && (f as any)['~'] === 'MutatorDefinition';\n}\n\nexport type MutatorDefinition<\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TContext = DefaultContext,\n TWrappedTransaction = DefaultWrappedTransaction,\n> = ((options: {\n args: TOutput;\n ctx: TContext;\n tx: AnyTransaction;\n}) => Promise<void>) & {\n validator: StandardSchemaV1<TInput, TOutput> | undefined;\n\n /**\n * Type-only phantom property to surface mutator types in a covariant position.\n */\n ['~']: Expand<\n MutatorDefinitionTypes<TInput, TOutput, TContext, TWrappedTransaction>\n >;\n};\n\n// Overload 1: Call with validator\nexport function defineMutator<\n TInput extends ReadonlyJSONValue | undefined = undefined,\n TOutput extends ReadonlyJSONValue | undefined = TInput,\n TSchema extends Schema = DefaultSchema,\n TContext = DefaultContext,\n TWrappedTransaction = DefaultWrappedTransaction,\n>(\n validator: StandardSchemaV1<TInput, TOutput>,\n mutator: (options: {\n args: TOutput;\n ctx: TContext;\n tx: Transaction<TSchema, TWrappedTransaction>;\n }) => Promise<void>,\n): MutatorDefinition<TInput, TOutput, TContext, TWrappedTransaction> & {};\n\n// Overload 2: Call without validator\nexport function defineMutator<\n TInput extends ReadonlyJSONValue | undefined = ReadonlyJSONValue | undefined,\n TSchema extends Schema = DefaultSchema,\n TContext = DefaultContext,\n TWrappedTransaction = DefaultWrappedTransaction,\n>(\n mutator: (options: {\n args: TInput;\n ctx: TContext;\n tx: Transaction<TSchema, TWrappedTransaction>;\n }) => Promise<void>,\n): MutatorDefinition<TInput, TInput, TContext, TWrappedTransaction> & {};\n\n// Implementation\nexport function defineMutator<\n TInput extends ReadonlyJSONValue | undefined = undefined,\n TOutput extends ReadonlyJSONValue | undefined = TInput,\n TSchema extends Schema = DefaultSchema,\n TContext = DefaultContext,\n TWrappedTransaction = DefaultWrappedTransaction,\n>(\n validatorOrMutator:\n | StandardSchemaV1<TInput, TOutput>\n | ((options: {\n args: TOutput;\n ctx: TContext;\n tx: Transaction<TSchema, TWrappedTransaction>;\n }) => Promise<void>),\n mutator?: (options: {\n args: TOutput;\n ctx: TContext;\n tx: Transaction<TSchema, TWrappedTransaction>;\n }) => Promise<void>,\n): MutatorDefinition<TInput, TOutput, TContext, TWrappedTransaction> {\n let validator: StandardSchemaV1<TInput, TOutput> | undefined;\n let actualMutator: (options: {\n args: TOutput;\n ctx: TContext;\n tx: Transaction<TSchema, TWrappedTransaction>;\n }) => Promise<void>;\n\n if (typeof validatorOrMutator === 'function') {\n // defineMutator(mutator) - no validator\n validator = undefined;\n actualMutator = validatorOrMutator;\n } else {\n // defineMutator(validator, mutator)\n validator = validatorOrMutator;\n actualMutator = must(mutator);\n }\n\n const f = actualMutator as MutatorDefinition<\n TInput,\n TOutput,\n TContext,\n TWrappedTransaction\n >;\n f['~'] = 'MutatorDefinition' as unknown as MutatorDefinitionTypes<\n TInput,\n TOutput,\n TContext,\n TWrappedTransaction\n >;\n\n f.validator = validator;\n return f;\n}\n\n// intentionally not using DefaultSchema, DefaultContext, or DefaultWrappedTransaction\nexport function defineMutatorWithType<\n TSchema extends Schema,\n TContext = unknown,\n TWrappedTransaction = unknown,\n>(): TypedDefineMutator<TSchema, TContext, TWrappedTransaction> {\n return defineMutator;\n}\n\n/**\n * The return type of defineMutatorWithType. A function matching the\n * defineMutator overloads but with Schema, Context, and WrappedTransaction\n * pre-bound.\n *\n * This is used as a workaround to using DefaultTypes (e.g. when using\n * multiple Zero instances).\n */\ntype TypedDefineMutator<\n TSchema extends Schema,\n TContext,\n TWrappedTransaction,\n> = {\n // Without validator\n <TArgs extends ReadonlyJSONValue | undefined>(\n mutator: (options: {\n args: TArgs;\n ctx: TContext;\n tx: Transaction<TSchema, TWrappedTransaction>;\n }) => Promise<void>,\n ): MutatorDefinition<TArgs, TArgs, TContext, TWrappedTransaction>;\n\n // With validator\n <\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n >(\n validator: StandardSchemaV1<TInput, TOutput>,\n mutator: (options: {\n args: TOutput;\n ctx: TContext;\n tx: Transaction<TSchema, TWrappedTransaction>;\n }) => Promise<void>,\n ): MutatorDefinition<TInput, TOutput, TContext, TWrappedTransaction>;\n};\n\n// ----------------------------------------------------------------------------\n// Mutator and MutationRequest types\n// ----------------------------------------------------------------------------\n\n/**\n * A callable wrapper around a MutatorDefinition, created by `defineMutators()`.\n *\n * Accessed like `mutators.foo.bar`, and called to create a MutationRequest:\n * `mutators.foo.bar(42)` returns a `MutationRequest`.\n *\n * The `fn` property is used for execution and takes raw JSON args (for rebase\n * and server wire format cases) that are validated internally.\n *\n * @template TInput - The argument type accepted by the callable (before validation)\n * @template TContext - The context type available during mutation execution\n * @template TWrappedTransaction - The wrapped transaction type\n */\nexport type Mutator<\n TInput extends ReadonlyJSONValue | undefined,\n TSchema extends Schema = DefaultSchema,\n TContext = DefaultContext,\n TWrappedTransaction = DefaultWrappedTransaction,\n> = MutatorCallable<TInput, TSchema, TContext, TWrappedTransaction> & {\n readonly mutatorName: string;\n /**\n * Execute the mutation. Args are ReadonlyJSONValue because this is called\n * during rebase (from stored JSON) and on the server (from wire format).\n * Validation happens internally before the recipe function runs.\n */\n readonly fn: (options: {\n args: TInput;\n ctx: TContext;\n tx: Transaction<TSchema, TWrappedTransaction>;\n }) => Promise<void>;\n};\n\n// Helper type for the callable part of Mutator\n// When TInput is undefined, the function is callable with 0 args\n// When TInput includes undefined (optional), args is optional\n// Otherwise, args is required\ntype MutatorCallable<\n TInput extends ReadonlyJSONValue | undefined,\n TSchema extends Schema,\n TContext,\n TWrappedTransaction,\n> = [TInput] extends [undefined]\n ? () => MutationRequest<TInput, TSchema, TContext, TWrappedTransaction>\n : undefined extends TInput\n ? (\n args?: TInput,\n ) => MutationRequest<TInput, TSchema, TContext, TWrappedTransaction>\n : (\n args: TInput,\n ) => MutationRequest<TInput, TSchema, TContext, TWrappedTransaction>;\n\n// oxlint-disable-next-line no-explicit-any\nexport type AnyMutator = Mutator<any, any, any, any>;\n\n/**\n * The result of calling a Mutator with arguments.\n *\n * Created by `mutators.foo.bar(42)`, executed by `zero.mutate(mr)` on the client\n * or `mr.mutator.fn({tx, ctx, args: mr.args})` on the server.\n *\n * @template TInput - The argument type (before validation, sent to server)\n * @template TContext - The context type available during mutation execution\n * @template TWrappedTransaction - The wrapped transaction type\n */\nexport type MutationRequest<\n TInput extends ReadonlyJSONValue | undefined,\n TSchema extends Schema = DefaultSchema,\n TContext = DefaultContext,\n TWrappedTransaction = DefaultWrappedTransaction,\n> = {\n readonly mutator: Mutator<TInput, TSchema, TContext, TWrappedTransaction>;\n readonly args: TInput;\n};\n\n/**\n * Checks if a value is a Mutator (the result of processing a MutatorDefinition\n * through defineMutators).\n */\nexport function isMutator(value: unknown): value is AnyMutator {\n return (\n typeof value === 'function' &&\n // oxlint-disable-next-line no-explicit-any\n typeof (value as any).mutatorName === 'string' &&\n // oxlint-disable-next-line no-explicit-any\n typeof (value as any).fn === 'function'\n );\n}\n"],"names":[],"mappings":";AA8BO,SAAS,oBAMd,GACwE;AACxE,SAAO,OAAO,MAAM,cAAe,EAAU,GAAG,MAAM;AACxD;AAqDO,SAAS,cAOd,oBAOA,SAKmE;AACnE,MAAI;AACJ,MAAI;AAMJ,MAAI,OAAO,uBAAuB,YAAY;AAE5C,gBAAY;AACZ,oBAAgB;AAAA,EAClB,OAAO;AAEL,gBAAY;AACZ,oBAAgB,KAAK,OAAO;AAAA,EAC9B;AAEA,QAAM,IAAI;AAMV,IAAE,GAAG,IAAI;AAOT,IAAE,YAAY;AACd,SAAO;AACT;AAiIO,SAAS,UAAU,OAAqC;AAC7D,SACE,OAAO,UAAU;AAAA,EAEjB,OAAQ,MAAc,gBAAgB;AAAA,EAEtC,OAAQ,MAAc,OAAO;AAEjC;"}
|