@_linked/core 2.36.1 → 2.36.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +19 -0
  3. package/lib/esm/collections/CoreSet.js +2 -0
  4. package/lib/esm/collections/CoreSet.js.map +1 -1
  5. package/lib/esm/collections/ShapeSet.js +2 -0
  6. package/lib/esm/collections/ShapeSet.js.map +1 -1
  7. package/lib/esm/expressions/Expr.js +3 -2
  8. package/lib/esm/expressions/Expr.js.map +1 -1
  9. package/lib/esm/expressions/ExpressionNode.js +10 -7
  10. package/lib/esm/expressions/ExpressionNode.js.map +1 -1
  11. package/lib/esm/index.d.ts +1 -1
  12. package/lib/esm/index.js +1 -1
  13. package/lib/esm/index.js.map +1 -1
  14. package/lib/esm/queries/AskBuilder.js +5 -3
  15. package/lib/esm/queries/AskBuilder.js.map +1 -1
  16. package/lib/esm/queries/CountBuilder.js +4 -2
  17. package/lib/esm/queries/CountBuilder.js.map +1 -1
  18. package/lib/esm/queries/CreateBuilder.js +2 -0
  19. package/lib/esm/queries/CreateBuilder.js.map +1 -1
  20. package/lib/esm/queries/DeleteBuilder.js +3 -1
  21. package/lib/esm/queries/DeleteBuilder.js.map +1 -1
  22. package/lib/esm/queries/DslJsonExpression.js +7 -6
  23. package/lib/esm/queries/DslJsonExpression.js.map +1 -1
  24. package/lib/esm/queries/FieldSet.js +10 -8
  25. package/lib/esm/queries/FieldSet.js.map +1 -1
  26. package/lib/esm/queries/IRLower.js +2 -1
  27. package/lib/esm/queries/IRLower.js.map +1 -1
  28. package/lib/esm/queries/MutationSerialization.js +2 -1
  29. package/lib/esm/queries/MutationSerialization.js.map +1 -1
  30. package/lib/esm/queries/PropertyPath.js +2 -0
  31. package/lib/esm/queries/PropertyPath.js.map +1 -1
  32. package/lib/esm/queries/ProxiedPathBuilder.js +2 -1
  33. package/lib/esm/queries/ProxiedPathBuilder.js.map +1 -1
  34. package/lib/esm/queries/QueryBuilder.js +5 -4
  35. package/lib/esm/queries/QueryBuilder.js.map +1 -1
  36. package/lib/esm/queries/QueryContext.js +17 -6
  37. package/lib/esm/queries/QueryContext.js.map +1 -1
  38. package/lib/esm/queries/SelectQuery.js +18 -12
  39. package/lib/esm/queries/SelectQuery.js.map +1 -1
  40. package/lib/esm/queries/UpdateBuilder.js +3 -1
  41. package/lib/esm/queries/UpdateBuilder.js.map +1 -1
  42. package/lib/esm/queries/lower.js +5 -4
  43. package/lib/esm/queries/lower.js.map +1 -1
  44. package/lib/esm/shapes/SHACL.js +6 -3
  45. package/lib/esm/shapes/SHACL.js.map +1 -1
  46. package/lib/esm/shapes/Shape.d.ts +3 -1
  47. package/lib/esm/shapes/Shape.js +20 -2
  48. package/lib/esm/shapes/Shape.js.map +1 -1
  49. package/lib/esm/utils/LinkedErrorLogging.d.ts +2 -1
  50. package/lib/esm/utils/LinkedErrorLogging.js +11 -0
  51. package/lib/esm/utils/LinkedErrorLogging.js.map +1 -1
  52. package/lib/esm/utils/LinkedFileStorage.d.ts +6 -4
  53. package/lib/esm/utils/LinkedFileStorage.js +34 -4
  54. package/lib/esm/utils/LinkedFileStorage.js.map +1 -1
  55. package/lib/esm/utils/Package.d.ts +6 -0
  56. package/lib/esm/utils/Package.js +35 -7
  57. package/lib/esm/utils/Package.js.map +1 -1
  58. package/lib/esm/utils/Prefix.d.ts +4 -2
  59. package/lib/esm/utils/Prefix.js +18 -2
  60. package/lib/esm/utils/Prefix.js.map +1 -1
  61. package/lib/esm/utils/ShapeClass.js +11 -6
  62. package/lib/esm/utils/ShapeClass.js.map +1 -1
  63. package/lib/esm/utils/cached.js +2 -1
  64. package/lib/esm/utils/cached.js.map +1 -1
  65. package/lib/esm/utils/linkedError.d.ts +32 -0
  66. package/lib/esm/utils/linkedError.js +63 -0
  67. package/lib/esm/utils/linkedError.js.map +1 -1
  68. package/lib/esm/utils/unresolvedShape.d.ts +3 -1
  69. package/lib/esm/utils/unresolvedShape.js +5 -1
  70. package/lib/esm/utils/unresolvedShape.js.map +1 -1
  71. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AskBuilder.js","sourceRoot":"","sources":["../../../src/queries/AskBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\n\n/**\n * `AskBuilder` — a query whose answer is a boolean.\n *\n * A small sibling of `SelectBuilder` rather than a mode of it. It can only hold a\n * pattern (shape, subject(s), where, minus), so the normalisation an existence\n * check needs is a property of the *type*: there is no projection, sorting or\n * pagination to drop, because none can be set.\n */\nimport {Shape, type ShapeConstructor} from '../shapes/Shape.js';\nimport {resolveShape} from './resolveShape.js';\nimport type {WherePath, WhereClause} from './SelectQuery.js';\nimport {processWhereClause} from './SelectQuery.js';\nimport type {RawMinusEntry} from './IRDesugar.js';\nimport type {NodeShapeData} from '../shapes/SHACL.js';\nimport type {NodeReferenceValue} from './QueryFactory.js';\nimport type {IDataset} from '../interfaces/IDataset.js';\nimport {PendingQueryContext} from './QueryContext.js';\nimport {encodeContextRef, isContextRefJSON} from './ContextRef.js';\nimport {WIRE_VERSION, assertWireVersion} from './wireVersion.js';\nimport {getQueryDispatch, resolveExistence} from './queryDispatch.js';\nimport {resolveUriOrThrow} from '../utils/NodeReference.js';\nimport {\n serializeWherePath,\n serializeRawMinusEntry,\n deserializeWherePath,\n deserializeRawMinusEntry,\n} from './QueryBuilderSerialization.js';\nimport type {AskQuery, AskQueryJSON, RawAskInput} from './AskQuery.js';\nimport {requireLiveQueryStore} from '../live/registry.js';\nimport {captureCatalog, getActiveShapeCatalog, withShapeCatalog} from '../utils/ShapeClass.js';\nimport type {ShapeCatalog} from '../utils/ShapeCatalog.js';\nimport type {LiveListener, LiveQuery, LiveQueryOptions} from '../live/LiveQueryStore.js';\n\n/** Everything an ask can carry. Assembled by `.exists()` or by `Shape.exists()`. */\nexport type AskSpec = {\n /** The catalog the builder resolves in; absent = captured from the active one. */\n catalog?: ShapeCatalog;\n /** The shape class whose instances are asked about; omitted = shapeless. */\n shapeClass?: ShapeConstructor<any>;\n subject?: NodeReferenceValue | PendingQueryContext;\n subjects?: NodeReferenceValue[];\n where?: WherePath;\n minusEntries?: RawMinusEntry[];\n /** `.for(null)` was called — there is no subject to ask about. */\n nullSubject?: boolean;\n};\n\nexport class AskBuilder implements PromiseLike<boolean>, Promise<boolean> {\n private readonly _spec: AskSpec;\n private readonly _catalog: ShapeCatalog | undefined;\n\n private constructor(spec: AskSpec) {\n this._spec = spec;\n this._catalog = 'catalog' in spec ? spec.catalog : captureCatalog(spec.shapeClass);\n }\n\n /** The catalog this builder resolves shapes in (undefined = the global registry). */\n get catalog(): ShapeCatalog | undefined {\n return this._catalog;\n }\n\n /** Build from an assembled spec — used by `.exists()` and `Shape.exists()`. */\n static of(spec: AskSpec): AskBuilder {\n return new AskBuilder(spec);\n }\n\n /**\n * A shapeless ask: does a node with this IRI exist at all, under any type or\n * none? Lowers to `ASK { <iri> ?p ?o }`.\n */\n static forNode(\n id: string | NodeReferenceValue | PendingQueryContext | null | undefined,\n ): AskBuilder {\n if (id === null || id === undefined) {\n return new AskBuilder({nullSubject: true});\n }\n if (id instanceof PendingQueryContext) {\n return new AskBuilder({subject: id});\n }\n const ref =\n typeof id === 'string' ? {id: resolveUriOrThrow(id)} : id;\n return new AskBuilder({subject: ref});\n }\n\n /** Discriminator for the free `lower()` function and dataset routing. */\n readonly __queryKind = 'ask' as const;\n\n /** The shape asked about — `undefined` for a shapeless ask. */\n get shape(): NodeShapeData | undefined {\n return this._spec.shapeClass?.shape;\n }\n\n toRawInput(): RawAskInput {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this.toRawInput());\n }\n const {shapeClass, subject, subjects, where, minusEntries, nullSubject} =\n this._spec;\n const input: RawAskInput = {};\n // Carried so lowering can reject it. `exec()` answers `false` before\n // dispatching, but a store handed the builder directly (e.g. after\n // `fromJSON`) would otherwise lower a subject-less query that matches every\n // instance of the shape and answer `true`.\n if (nullSubject) input.nullSubject = true;\n if (shapeClass) input.shape = shapeClass as any;\n if (subject) input.subject = subject;\n if (subjects && subjects.length > 0) input.subjects = subjects;\n if (where) input.where = where;\n if (minusEntries && minusEntries.length > 0) input.minusEntries = minusEntries;\n return input;\n }\n\n toJSON(): AskQueryJSON {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this.toJSON());\n }\n const {shapeClass, subject, subjects, where, minusEntries, nullSubject} =\n this._spec;\n const json: AskQueryJSON = {v: WIRE_VERSION, op: 'ask'};\n\n if (shapeClass) {\n json.shape = shapeClass.shape?.id || '';\n }\n if (subject instanceof PendingQueryContext) {\n // Carry the reference, not its (possibly unresolved) id, so the receiver\n // resolves it against its own context map at lowering time.\n json.subject = encodeContextRef(subject.contextName);\n } else if (subject && typeof subject === 'object' && 'id' in subject) {\n json.subject = (subject as NodeReferenceValue).id;\n }\n if (subjects && subjects.length > 0) {\n json.subjects = subjects.map((s) => s.id);\n }\n // A shapeless ask carries neither — both name properties, which only a shape\n // can resolve — so `shapeClass` is present whenever these are.\n if (where && shapeClass) {\n json.where = serializeWherePath(where, shapeClass.shape);\n }\n if (minusEntries && minusEntries.length > 0 && shapeClass) {\n json.minusEntries = minusEntries.map((e) =>\n serializeRawMinusEntry(e, shapeClass.shape),\n );\n }\n if (nullSubject) {\n json.nullSubject = true;\n }\n return json;\n }\n\n static fromJSON(json: AskQueryJSON): AskBuilder {\n assertWireVersion(json.v);\n const shapeClass = json.shape\n ? (resolveShape(json.shape as any) as ShapeConstructor<any>)\n : undefined;\n const spec: AskSpec = {};\n if (shapeClass) spec.shapeClass = shapeClass;\n\n if (json.subject !== undefined) {\n spec.subject = isContextRefJSON(json.subject)\n ? new PendingQueryContext(json.subject['@ctx'])\n : {id: json.subject as string};\n }\n if (json.subjects && json.subjects.length > 0) {\n spec.subjects = json.subjects.map((id) => ({id}));\n }\n if (json.where || json.minusEntries?.length) {\n // A where clause or minus entry names properties, and a property is only\n // resolvable through a shape. A shapeless ask cannot carry either.\n if (!shapeClass) {\n throw new Error(\n 'An ask envelope with a `where` or `minusEntries` must name a `shape`: ' +\n 'the clause references properties, which are resolved through the shape.',\n );\n }\n if (json.where) {\n spec.where = deserializeWherePath(shapeClass.shape, json.where);\n }\n if (json.minusEntries?.length) {\n spec.minusEntries = json.minusEntries.map((e) =>\n deserializeRawMinusEntry(shapeClass.shape, e),\n );\n }\n }\n if (json.nullSubject) spec.nullSubject = true;\n return new AskBuilder(spec);\n }\n\n /**\n * Execute and resolve to a real boolean.\n *\n * Never `null`, never a row. A store, transport or lowering failure **rejects**;\n * it is never reported as `false`. The one case that resolves `false` without\n * querying is a query with no subject to ask about — `.for(null)`, or a\n * `PendingQueryContext` as the subject that has not landed: \"does the node with\n * no id exist?\" has a correct total answer, and it is `false`.\n */\n async exec(target?: IDataset): Promise<boolean> {\n const {nullSubject, subject} = this._spec;\n if (nullSubject) return false;\n if (subject instanceof PendingQueryContext && !subject.id) return false;\n // `async` ensures a missing global dispatch rejects rather than throwing\n // synchronously past the caller's `.catch()`.\n const dispatch = target ?? getQueryDispatch();\n return resolveExistence(dispatch as any, this);\n }\n\n\n /**\n * Go live: subscribe to this query and keep its result current.\n *\n * Returns a {@link LiveQuery} handle. `await` it for the first result,\n * `subscribe()` for every later one, `close()` when done. A listener may be\n * passed directly as the first argument. Requires the live-query store to be\n * loaded, which importing `@_linked/core` (the package root) does.\n */\n live<R = boolean>(listenerOrOptions?: LiveListener<R> | LiveQueryOptions, options?: LiveQueryOptions): LiveQuery<R> {\n const listener = typeof listenerOrOptions === 'function' ? listenerOrOptions : undefined;\n const opts = typeof listenerOrOptions === 'function' ? options : listenerOrOptions;\n return requireLiveQueryStore().subscribe<R>(this as any, listener, opts);\n }\n\n /** `await` triggers execution. */\n then<TResult1 = boolean, TResult2 = never>(\n onfulfilled?: ((value: boolean) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,\n ): Promise<TResult1 | TResult2> {\n return this.exec().then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null,\n ): Promise<boolean | TResult> {\n return this.then().catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<boolean> {\n return this.then().finally(onfinally);\n }\n\n get [Symbol.toStringTag](): string {\n return 'AskBuilder';\n }\n}\n\n/** Narrow an unknown query object to an ask. */\nexport function isAskQuery(query: unknown): query is AskQuery {\n return (\n !!query && (query as {__queryKind?: string}).__queryKind === 'ask'\n );\n}\n"]}
1
+ {"version":3,"file":"AskBuilder.js","sourceRoot":"","sources":["../../../src/queries/AskBuilder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;;;;;;;;;AAWH,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAO/C,OAAO,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAC,YAAY,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAC,iBAAiB,EAAC,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAC,qBAAqB,EAAC,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAC,cAAc,EAAE,qBAAqB,EAAE,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AAG/F,OAAO,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAgB3E,MAAM,OAAO,UAAU;IAIrB,YAAoB,IAAa;QAiCjC,yEAAyE;QAChE,gBAAW,GAAG,KAAc,CAAC;QAjCpC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrF,CAAC;IAED,qFAAqF;IACrF,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,+EAA+E;IAC/E,MAAM,CAAC,EAAE,CAAC,IAAa;QACrB,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,OAAO,CACZ,EAAwE;QAExE,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACpC,OAAO,IAAI,UAAU,CAAC,EAAC,WAAW,EAAE,IAAI,EAAC,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,gBAAgB,CAAC,EAAE,EAAE,mBAAmB,CAAC,EAAE,CAAC;YAC9C,OAAO,IAAI,UAAU,CAAC,EAAC,OAAO,EAAE,EAAE,EAAC,CAAC,CAAC;QACvC,CAAC;QACD,MAAM,GAAG,GACP,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAC,EAAE,EAAE,iBAAiB,CAAC,EAAE,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,OAAO,IAAI,UAAU,CAAC,EAAC,OAAO,EAAE,GAAG,EAAC,CAAC,CAAC;IACxC,CAAC;IAKD,+DAA+D;IAC/D,IAAI,KAAK;;QACP,OAAO,MAAA,IAAI,CAAC,KAAK,CAAC,UAAU,0CAAE,KAAK,CAAC;IACtC,CAAC;IAED,UAAU;QACR,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,OAAO,KAAK,qBAAqB,EAAE,EAAE,CAAC;YACxC,OAAO,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,EAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAC,GACrE,IAAI,CAAC,KAAK,CAAC;QACb,MAAM,KAAK,GAAgB,EAAE,CAAC;QAC9B,qEAAqE;QACrE,mEAAmE;QACnE,4EAA4E;QAC5E,2CAA2C;QAC3C,IAAI,WAAW;YAAE,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1C,IAAI,UAAU;YAAE,KAAK,CAAC,KAAK,GAAG,UAAiB,CAAC;QAChD,IAAI,OAAO;YAAE,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;QACrC,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC/D,IAAI,KAAK;YAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;QAC/B,IAAI,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,YAAY,GAAG,YAAY,CAAC;QAC/E,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM;;QACJ,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,OAAO,KAAK,qBAAqB,EAAE,EAAE,CAAC;YACxC,OAAO,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,MAAM,EAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAC,GACrE,IAAI,CAAC,KAAK,CAAC;QACb,MAAM,IAAI,GAAiB,EAAC,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,KAAK,EAAC,CAAC;QAExD,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,GAAG,CAAA,MAAA,UAAU,CAAC,KAAK,0CAAE,EAAE,KAAI,EAAE,CAAC;QAC1C,CAAC;QACD,IAAI,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,CAAC,EAAE,CAAC;YACnD,yEAAyE;YACzE,4DAA4D;YAC5D,IAAI,CAAC,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACvD,CAAC;aAAM,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,IAAI,IAAI,OAAO,EAAE,CAAC;YACrE,IAAI,CAAC,OAAO,GAAI,OAA8B,CAAC,EAAE,CAAC;QACpD,CAAC;QACD,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,6EAA6E;QAC7E,+DAA+D;QAC/D,IAAI,KAAK,IAAI,UAAU,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,GAAG,kBAAkB,CAAC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,EAAE,CAAC;YAC1D,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACzC,sBAAsB,CAAC,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,CAC5C,CAAC;QACJ,CAAC;QACD,IAAI,WAAW,EAAE,CAAC;YAChB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,IAAkB;;QAChC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK;YAC3B,CAAC,CAAE,YAAY,CAAC,IAAI,CAAC,KAAY,CAA2B;YAC5D,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,IAAI,GAAY,EAAE,CAAC;QACzB,IAAI,UAAU;YAAE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAE7C,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC;gBAC3C,CAAC,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC/C,CAAC,CAAC,EAAC,EAAE,EAAE,IAAI,CAAC,OAAiB,EAAC,CAAC;QACnC,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAC,EAAE,EAAC,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,KAAI,MAAA,IAAI,CAAC,YAAY,0CAAE,MAAM,CAAA,EAAE,CAAC;YAC5C,yEAAyE;YACzE,mEAAmE;YACnE,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,IAAI,KAAK,CACb,wEAAwE;oBACxE,yEAAyE,CAC1E,CAAC;YACJ,CAAC;YACD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,KAAK,GAAG,oBAAoB,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAClE,CAAC;YACD,IAAI,MAAA,IAAI,CAAC,YAAY,0CAAE,MAAM,EAAE,CAAC;gBAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9C,wBAAwB,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,CAC9C,CAAC;YACJ,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,WAAW;YAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC9C,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED;;;;;;;;OAQG;IACG,IAAI,CAAC,MAAiB;;YAC1B,MAAM,EAAC,WAAW,EAAE,OAAO,EAAC,GAAG,IAAI,CAAC,KAAK,CAAC;YAC1C,IAAI,WAAW;gBAAE,OAAO,KAAK,CAAC;YAC9B,IAAI,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;gBAAE,OAAO,KAAK,CAAC;YAChF,yEAAyE;YACzE,8CAA8C;YAC9C,MAAM,QAAQ,GAAG,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,gBAAgB,EAAE,CAAC;YAC9C,OAAO,gBAAgB,CAAC,QAAe,EAAE,IAAI,CAAC,CAAC;QACjD,CAAC;KAAA;IAGD;;;;;;;OAOG;IACH,IAAI,CAAc,iBAAsD,EAAE,OAA0B;QAClG,MAAM,QAAQ,GAAG,OAAO,iBAAiB,KAAK,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;QACzF,MAAM,IAAI,GAAG,OAAO,iBAAiB,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC;QACnF,OAAO,qBAAqB,EAAE,CAAC,SAAS,CAAI,IAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC3E,CAAC;IAED,kCAAkC;IAClC,IAAI,CACF,WAA2E,EAC3E,UAAuE;QAEvE,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CACH,UAAqE;QAErE,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,SAA+B;QACrC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;QACtB,OAAO,YAAY,CAAC;IACtB,CAAC;CACF;AACD,gBAAgB,CAAC,UAAU,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC;AAG5D,gDAAgD;AAChD,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,CACL,CAAC,CAAC,KAAK,IAAK,KAAgC,CAAC,WAAW,KAAK,KAAK,CACnE,CAAC;AACJ,CAAC","sourcesContent":["/*\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\n\n/**\n * `AskBuilder` — a query whose answer is a boolean.\n *\n * A small sibling of `SelectBuilder` rather than a mode of it. It can only hold a\n * pattern (shape, subject(s), where, minus), so the normalisation an existence\n * check needs is a property of the *type*: there is no projection, sorting or\n * pagination to drop, because none can be set.\n */\nimport {Shape, type ShapeConstructor} from '../shapes/Shape.js';\nimport {resolveShape} from './resolveShape.js';\nimport type {WherePath, WhereClause} from './SelectQuery.js';\nimport {processWhereClause} from './SelectQuery.js';\nimport type {RawMinusEntry} from './IRDesugar.js';\nimport type {NodeShapeData} from '../shapes/SHACL.js';\nimport type {NodeReferenceValue} from './QueryFactory.js';\nimport type {IDataset} from '../interfaces/IDataset.js';\nimport {PendingQueryContext} from './QueryContext.js';\nimport {encodeContextRef, isContextRefJSON} from './ContextRef.js';\nimport {WIRE_VERSION, assertWireVersion} from './wireVersion.js';\nimport {getQueryDispatch, resolveExistence} from './queryDispatch.js';\nimport {resolveUriOrThrow} from '../utils/NodeReference.js';\nimport {\n serializeWherePath,\n serializeRawMinusEntry,\n deserializeWherePath,\n deserializeRawMinusEntry,\n} from './QueryBuilderSerialization.js';\nimport type {AskQuery, AskQueryJSON, RawAskInput} from './AskQuery.js';\nimport {requireLiveQueryStore} from '../live/registry.js';\nimport {captureCatalog, getActiveShapeCatalog, withShapeCatalog} from '../utils/ShapeClass.js';\nimport type {ShapeCatalog} from '../utils/ShapeCatalog.js';\nimport type {LiveListener, LiveQuery, LiveQueryOptions} from '../live/LiveQueryStore.js';\nimport {brandLinkedClass, isLinkedInstance} from '../utils/linkedError.js';\n\n/** Everything an ask can carry. Assembled by `.exists()` or by `Shape.exists()`. */\nexport type AskSpec = {\n /** The catalog the builder resolves in; absent = captured from the active one. */\n catalog?: ShapeCatalog;\n /** The shape class whose instances are asked about; omitted = shapeless. */\n shapeClass?: ShapeConstructor<any>;\n subject?: NodeReferenceValue | PendingQueryContext;\n subjects?: NodeReferenceValue[];\n where?: WherePath;\n minusEntries?: RawMinusEntry[];\n /** `.for(null)` was called — there is no subject to ask about. */\n nullSubject?: boolean;\n};\n\nexport class AskBuilder implements PromiseLike<boolean>, Promise<boolean> {\n private readonly _spec: AskSpec;\n private readonly _catalog: ShapeCatalog | undefined;\n\n private constructor(spec: AskSpec) {\n this._spec = spec;\n this._catalog = 'catalog' in spec ? spec.catalog : captureCatalog(spec.shapeClass);\n }\n\n /** The catalog this builder resolves shapes in (undefined = the global registry). */\n get catalog(): ShapeCatalog | undefined {\n return this._catalog;\n }\n\n /** Build from an assembled spec — used by `.exists()` and `Shape.exists()`. */\n static of(spec: AskSpec): AskBuilder {\n return new AskBuilder(spec);\n }\n\n /**\n * A shapeless ask: does a node with this IRI exist at all, under any type or\n * none? Lowers to `ASK { <iri> ?p ?o }`.\n */\n static forNode(\n id: string | NodeReferenceValue | PendingQueryContext | null | undefined,\n ): AskBuilder {\n if (id === null || id === undefined) {\n return new AskBuilder({nullSubject: true});\n }\n if (isLinkedInstance(id, PendingQueryContext)) {\n return new AskBuilder({subject: id});\n }\n const ref =\n typeof id === 'string' ? {id: resolveUriOrThrow(id)} : id;\n return new AskBuilder({subject: ref});\n }\n\n /** Discriminator for the free `lower()` function and dataset routing. */\n readonly __queryKind = 'ask' as const;\n\n /** The shape asked about — `undefined` for a shapeless ask. */\n get shape(): NodeShapeData | undefined {\n return this._spec.shapeClass?.shape;\n }\n\n toRawInput(): RawAskInput {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this.toRawInput());\n }\n const {shapeClass, subject, subjects, where, minusEntries, nullSubject} =\n this._spec;\n const input: RawAskInput = {};\n // Carried so lowering can reject it. `exec()` answers `false` before\n // dispatching, but a store handed the builder directly (e.g. after\n // `fromJSON`) would otherwise lower a subject-less query that matches every\n // instance of the shape and answer `true`.\n if (nullSubject) input.nullSubject = true;\n if (shapeClass) input.shape = shapeClass as any;\n if (subject) input.subject = subject;\n if (subjects && subjects.length > 0) input.subjects = subjects;\n if (where) input.where = where;\n if (minusEntries && minusEntries.length > 0) input.minusEntries = minusEntries;\n return input;\n }\n\n toJSON(): AskQueryJSON {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this.toJSON());\n }\n const {shapeClass, subject, subjects, where, minusEntries, nullSubject} =\n this._spec;\n const json: AskQueryJSON = {v: WIRE_VERSION, op: 'ask'};\n\n if (shapeClass) {\n json.shape = shapeClass.shape?.id || '';\n }\n if (isLinkedInstance(subject, PendingQueryContext)) {\n // Carry the reference, not its (possibly unresolved) id, so the receiver\n // resolves it against its own context map at lowering time.\n json.subject = encodeContextRef(subject.contextName);\n } else if (subject && typeof subject === 'object' && 'id' in subject) {\n json.subject = (subject as NodeReferenceValue).id;\n }\n if (subjects && subjects.length > 0) {\n json.subjects = subjects.map((s) => s.id);\n }\n // A shapeless ask carries neither — both name properties, which only a shape\n // can resolve — so `shapeClass` is present whenever these are.\n if (where && shapeClass) {\n json.where = serializeWherePath(where, shapeClass.shape);\n }\n if (minusEntries && minusEntries.length > 0 && shapeClass) {\n json.minusEntries = minusEntries.map((e) =>\n serializeRawMinusEntry(e, shapeClass.shape),\n );\n }\n if (nullSubject) {\n json.nullSubject = true;\n }\n return json;\n }\n\n static fromJSON(json: AskQueryJSON): AskBuilder {\n assertWireVersion(json.v);\n const shapeClass = json.shape\n ? (resolveShape(json.shape as any) as ShapeConstructor<any>)\n : undefined;\n const spec: AskSpec = {};\n if (shapeClass) spec.shapeClass = shapeClass;\n\n if (json.subject !== undefined) {\n spec.subject = isContextRefJSON(json.subject)\n ? new PendingQueryContext(json.subject['@ctx'])\n : {id: json.subject as string};\n }\n if (json.subjects && json.subjects.length > 0) {\n spec.subjects = json.subjects.map((id) => ({id}));\n }\n if (json.where || json.minusEntries?.length) {\n // A where clause or minus entry names properties, and a property is only\n // resolvable through a shape. A shapeless ask cannot carry either.\n if (!shapeClass) {\n throw new Error(\n 'An ask envelope with a `where` or `minusEntries` must name a `shape`: ' +\n 'the clause references properties, which are resolved through the shape.',\n );\n }\n if (json.where) {\n spec.where = deserializeWherePath(shapeClass.shape, json.where);\n }\n if (json.minusEntries?.length) {\n spec.minusEntries = json.minusEntries.map((e) =>\n deserializeRawMinusEntry(shapeClass.shape, e),\n );\n }\n }\n if (json.nullSubject) spec.nullSubject = true;\n return new AskBuilder(spec);\n }\n\n /**\n * Execute and resolve to a real boolean.\n *\n * Never `null`, never a row. A store, transport or lowering failure **rejects**;\n * it is never reported as `false`. The one case that resolves `false` without\n * querying is a query with no subject to ask about — `.for(null)`, or a\n * `PendingQueryContext` as the subject that has not landed: \"does the node with\n * no id exist?\" has a correct total answer, and it is `false`.\n */\n async exec(target?: IDataset): Promise<boolean> {\n const {nullSubject, subject} = this._spec;\n if (nullSubject) return false;\n if (isLinkedInstance(subject, PendingQueryContext) && !subject.id) return false;\n // `async` ensures a missing global dispatch rejects rather than throwing\n // synchronously past the caller's `.catch()`.\n const dispatch = target ?? getQueryDispatch();\n return resolveExistence(dispatch as any, this);\n }\n\n\n /**\n * Go live: subscribe to this query and keep its result current.\n *\n * Returns a {@link LiveQuery} handle. `await` it for the first result,\n * `subscribe()` for every later one, `close()` when done. A listener may be\n * passed directly as the first argument. Requires the live-query store to be\n * loaded, which importing `@_linked/core` (the package root) does.\n */\n live<R = boolean>(listenerOrOptions?: LiveListener<R> | LiveQueryOptions, options?: LiveQueryOptions): LiveQuery<R> {\n const listener = typeof listenerOrOptions === 'function' ? listenerOrOptions : undefined;\n const opts = typeof listenerOrOptions === 'function' ? options : listenerOrOptions;\n return requireLiveQueryStore().subscribe<R>(this as any, listener, opts);\n }\n\n /** `await` triggers execution. */\n then<TResult1 = boolean, TResult2 = never>(\n onfulfilled?: ((value: boolean) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,\n ): Promise<TResult1 | TResult2> {\n return this.exec().then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null,\n ): Promise<boolean | TResult> {\n return this.then().catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<boolean> {\n return this.then().finally(onfinally);\n }\n\n get [Symbol.toStringTag](): string {\n return 'AskBuilder';\n }\n}\nbrandLinkedClass(AskBuilder, '@_linked/core', 'AskBuilder');\n\n\n/** Narrow an unknown query object to an ask. */\nexport function isAskQuery(query: unknown): query is AskQuery {\n return (\n !!query && (query as {__queryKind?: string}).__queryKind === 'ask'\n );\n}\n"]}
@@ -20,6 +20,7 @@ import { getQueryDispatch, resolveCount } from './queryDispatch.js';
20
20
  import { serializeWherePath, serializeRawMinusEntry, deserializeWherePath, deserializeRawMinusEntry, } from './QueryBuilderSerialization.js';
21
21
  import { requireLiveQueryStore } from '../live/registry.js';
22
22
  import { captureCatalog, getActiveShapeCatalog, withShapeCatalog } from '../utils/ShapeClass.js';
23
+ import { brandLinkedClass, isLinkedInstance } from '../utils/linkedError.js';
23
24
  export class CountBuilder {
24
25
  constructor(spec) {
25
26
  /** Discriminator for the free `lower()` function and dataset routing. */
@@ -82,7 +83,7 @@ export class CountBuilder {
82
83
  op: 'count',
83
84
  shape: shapeId,
84
85
  };
85
- if (subject instanceof PendingQueryContext) {
86
+ if (isLinkedInstance(subject, PendingQueryContext)) {
86
87
  // Carry the reference, not its (possibly unresolved) id, so the receiver
87
88
  // resolves it against its own context map at lowering time.
88
89
  json.subject = encodeContextRef(subject.contextName);
@@ -148,7 +149,7 @@ export class CountBuilder {
148
149
  const { nullSubject, subject } = this._spec;
149
150
  if (nullSubject)
150
151
  return 0;
151
- if (subject instanceof PendingQueryContext && !subject.id)
152
+ if (isLinkedInstance(subject, PendingQueryContext) && !subject.id)
152
153
  return 0;
153
154
  // `async` ensures a missing global dispatch rejects rather than throwing
154
155
  // synchronously past the caller's `.catch()`.
@@ -186,6 +187,7 @@ export class CountBuilder {
186
187
  return 'CountBuilder';
187
188
  }
188
189
  }
190
+ brandLinkedClass(CountBuilder, '@_linked/core', 'CountBuilder');
189
191
  /** Narrow an unknown query object to a count. */
190
192
  export function isCountQuery(query) {
191
193
  return !!query && query.__queryKind === 'count';
@@ -1 +1 @@
1
- {"version":3,"file":"CountBuilder.js","sourceRoot":"","sources":["../../../src/queries/CountBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\n\n/**\n * `CountBuilder` — a query whose answer is a number.\n *\n * A small sibling of `SelectBuilder` rather than a mode of it, for the same reason\n * {@link AskBuilder} is: it can only hold a pattern (shape, subject(s), where,\n * minus), so the normalisation a count needs is a property of the *type*. There is\n * no projection, ordering or **pagination** to drop, because none can be set — and\n * a count of a windowed query is meaningless, so that is the point.\n *\n * Deliberately **non-generic**. `SelectBuilder<S, R, Result>` is heavily inferred;\n * a count answers `number` no matter what the select's projection was, so this type\n * takes part in none of that inference and cannot perturb it.\n */\nimport type {ShapeConstructor} from '../shapes/Shape.js';\nimport {resolveShape} from './resolveShape.js';\nimport type {WherePath} from './SelectQuery.js';\nimport type {RawMinusEntry} from './IRDesugar.js';\nimport type {NodeShapeData} from '../shapes/SHACL.js';\nimport type {NodeReferenceValue} from './QueryFactory.js';\nimport type {IDataset} from '../interfaces/IDataset.js';\nimport {PendingQueryContext} from './QueryContext.js';\nimport {encodeContextRef, isContextRefJSON} from './ContextRef.js';\nimport {WIRE_VERSION, assertWireVersion} from './wireVersion.js';\nimport {getQueryDispatch, resolveCount} from './queryDispatch.js';\nimport {\n serializeWherePath,\n serializeRawMinusEntry,\n deserializeWherePath,\n deserializeRawMinusEntry,\n} from './QueryBuilderSerialization.js';\nimport type {CountQuery, CountQueryJSON, RawCountInput} from './CountQuery.js';\nimport {requireLiveQueryStore} from '../live/registry.js';\nimport {captureCatalog, getActiveShapeCatalog, withShapeCatalog} from '../utils/ShapeClass.js';\nimport type {ShapeCatalog} from '../utils/ShapeCatalog.js';\nimport type {LiveListener, LiveQuery, LiveQueryOptions} from '../live/LiveQueryStore.js';\n\n/**\n * Everything a count can carry. Assembled by `SelectBuilder.toCount()` or\n * `Shape.count()`.\n *\n * `shapeClass` is required — a shapeless count would count every node in the store.\n */\nexport type CountSpec = {\n /** The catalog the builder resolves in; absent = captured from the active one. */\n catalog?: ShapeCatalog;\n shapeClass: ShapeConstructor<any>;\n subject?: NodeReferenceValue | PendingQueryContext;\n subjects?: NodeReferenceValue[];\n where?: WherePath;\n minusEntries?: RawMinusEntry[];\n /** `.for(null)` was called — there is no subject to count. */\n nullSubject?: boolean;\n};\n\nexport class CountBuilder implements PromiseLike<number>, Promise<number> {\n private readonly _spec: CountSpec;\n private readonly _catalog: ShapeCatalog | undefined;\n\n private constructor(spec: CountSpec) {\n this._spec = spec;\n this._catalog = 'catalog' in spec ? spec.catalog : captureCatalog(spec.shapeClass);\n }\n\n /** The catalog this builder resolves shapes in (undefined = the global registry). */\n get catalog(): ShapeCatalog | undefined {\n return this._catalog;\n }\n\n /** Build from an assembled spec — used by `.toCount()` and `Shape.count()`. */\n static of(spec: CountSpec): CountBuilder {\n return new CountBuilder(spec);\n }\n\n /** Discriminator for the free `lower()` function and dataset routing. */\n readonly __queryKind = 'count' as const;\n\n /** The shape whose matching instances are counted — also the routing key. */\n get shape(): NodeShapeData {\n return this._spec.shapeClass.shape;\n }\n\n toRawInput(): RawCountInput {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this.toRawInput());\n }\n const {shapeClass, subject, subjects, where, minusEntries, nullSubject} =\n this._spec;\n const input: RawCountInput = {shape: shapeClass as any};\n // Carried so lowering can reject it. `exec()` answers `0` before dispatching,\n // but a store handed the builder directly (e.g. after `fromJSON`) would\n // otherwise lower a subject-less query that matches every instance of the\n // shape and report that as the count of one node.\n if (nullSubject) input.nullSubject = true;\n if (subject) input.subject = subject;\n if (subjects && subjects.length > 0) input.subjects = subjects;\n if (where) input.where = where;\n if (minusEntries && minusEntries.length > 0) input.minusEntries = minusEntries;\n return input;\n }\n\n toJSON(): CountQueryJSON {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this.toJSON());\n }\n const {shapeClass, subject, subjects, where, minusEntries, nullSubject} =\n this._spec;\n const shapeId = shapeClass.shape?.id;\n if (!shapeId) {\n // Refuse here rather than emitting `shape: ''` for the receiver's `fromJSON`\n // to reject: the caller who holds the shape can act on this, and a peer\n // across a wire cannot.\n throw new Error(\n 'Cannot serialize a count query whose shape has no id. A count envelope must ' +\n 'name a shape — a shapeless count would count every node in the store.',\n );\n }\n const json: CountQueryJSON = {\n v: WIRE_VERSION,\n op: 'count',\n shape: shapeId,\n };\n\n if (subject instanceof PendingQueryContext) {\n // Carry the reference, not its (possibly unresolved) id, so the receiver\n // resolves it against its own context map at lowering time.\n json.subject = encodeContextRef(subject.contextName);\n } else if (subject && typeof subject === 'object' && 'id' in subject) {\n json.subject = (subject as NodeReferenceValue).id;\n }\n if (subjects && subjects.length > 0) {\n json.subjects = subjects.map((s) => s.id);\n }\n if (where) {\n json.where = serializeWherePath(where, shapeClass.shape);\n }\n if (minusEntries && minusEntries.length > 0) {\n json.minusEntries = minusEntries.map((e) =>\n serializeRawMinusEntry(e, shapeClass.shape),\n );\n }\n if (nullSubject) {\n json.nullSubject = true;\n }\n return json;\n }\n\n static fromJSON(json: CountQueryJSON): CountBuilder {\n assertWireVersion(json.v);\n if (!json.shape) {\n throw new Error(\n 'A count envelope must name a `shape`. A shapeless count would count every ' +\n 'node in the store, under any type or none.',\n );\n }\n const shapeClass = resolveShape(json.shape as any) as ShapeConstructor<any>;\n const spec: CountSpec = {shapeClass};\n\n if (json.subject !== undefined) {\n spec.subject = isContextRefJSON(json.subject)\n ? new PendingQueryContext(json.subject['@ctx'])\n : {id: json.subject as string};\n }\n if (json.subjects && json.subjects.length > 0) {\n spec.subjects = json.subjects.map((id) => ({id}));\n }\n if (json.where) {\n spec.where = deserializeWherePath(shapeClass.shape, json.where);\n }\n if (json.minusEntries?.length) {\n spec.minusEntries = json.minusEntries.map((e) =>\n deserializeRawMinusEntry(shapeClass.shape, e),\n );\n }\n if (json.nullSubject) spec.nullSubject = true;\n return new CountBuilder(spec);\n }\n\n /**\n * Execute and resolve to a real number.\n *\n * **A failure rejects — it is never reported as `0`.** A count of `0` renders an\n * empty table and is indistinguishable from real data, so a broken count that\n * answered `0` would hide rather than fail. Do not wrap this in `.catch(() => 0)`.\n *\n * The one case that resolves `0` without querying is a query with no subject to\n * count — `.for(null)`, or a `PendingQueryContext` as the subject that has not\n * landed: \"how many nodes with no id match?\" has a correct total answer, and it\n * is `0`.\n */\n async exec(target?: IDataset): Promise<number> {\n const {nullSubject, subject} = this._spec;\n if (nullSubject) return 0;\n if (subject instanceof PendingQueryContext && !subject.id) return 0;\n // `async` ensures a missing global dispatch rejects rather than throwing\n // synchronously past the caller's `.catch()`.\n const dispatch = target ?? getQueryDispatch();\n // `resolveCount` dispatches over the SELECT channel — a count is a select with\n // an aggregate projection, not a query form of its own — and checks the answer\n // is a real non-negative integer before it reaches the caller.\n return resolveCount(dispatch as any, this);\n }\n\n\n /**\n * Go live: subscribe to this query and keep its result current.\n *\n * Returns a {@link LiveQuery} handle. `await` it for the first result,\n * `subscribe()` for every later one, `close()` when done. A listener may be\n * passed directly as the first argument. Requires the live-query store to be\n * loaded, which importing `@_linked/core` (the package root) does.\n */\n live<R = number>(listenerOrOptions?: LiveListener<R> | LiveQueryOptions, options?: LiveQueryOptions): LiveQuery<R> {\n const listener = typeof listenerOrOptions === 'function' ? listenerOrOptions : undefined;\n const opts = typeof listenerOrOptions === 'function' ? options : listenerOrOptions;\n return requireLiveQueryStore().subscribe<R>(this as any, listener, opts);\n }\n\n /** `await` triggers execution. */\n then<TResult1 = number, TResult2 = never>(\n onfulfilled?: ((value: number) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,\n ): Promise<TResult1 | TResult2> {\n return this.exec().then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null,\n ): Promise<number | TResult> {\n return this.then().catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<number> {\n return this.then().finally(onfinally);\n }\n\n get [Symbol.toStringTag](): string {\n return 'CountBuilder';\n }\n}\n\n/** Narrow an unknown query object to a count. */\nexport function isCountQuery(query: unknown): query is CountQuery {\n return !!query && (query as {__queryKind?: string}).__queryKind === 'count';\n}\n"]}
1
+ {"version":3,"file":"CountBuilder.js","sourceRoot":"","sources":["../../../src/queries/CountBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\n\n/**\n * `CountBuilder` — a query whose answer is a number.\n *\n * A small sibling of `SelectBuilder` rather than a mode of it, for the same reason\n * {@link AskBuilder} is: it can only hold a pattern (shape, subject(s), where,\n * minus), so the normalisation a count needs is a property of the *type*. There is\n * no projection, ordering or **pagination** to drop, because none can be set — and\n * a count of a windowed query is meaningless, so that is the point.\n *\n * Deliberately **non-generic**. `SelectBuilder<S, R, Result>` is heavily inferred;\n * a count answers `number` no matter what the select's projection was, so this type\n * takes part in none of that inference and cannot perturb it.\n */\nimport type {ShapeConstructor} from '../shapes/Shape.js';\nimport {resolveShape} from './resolveShape.js';\nimport type {WherePath} from './SelectQuery.js';\nimport type {RawMinusEntry} from './IRDesugar.js';\nimport type {NodeShapeData} from '../shapes/SHACL.js';\nimport type {NodeReferenceValue} from './QueryFactory.js';\nimport type {IDataset} from '../interfaces/IDataset.js';\nimport {PendingQueryContext} from './QueryContext.js';\nimport {encodeContextRef, isContextRefJSON} from './ContextRef.js';\nimport {WIRE_VERSION, assertWireVersion} from './wireVersion.js';\nimport {getQueryDispatch, resolveCount} from './queryDispatch.js';\nimport {\n serializeWherePath,\n serializeRawMinusEntry,\n deserializeWherePath,\n deserializeRawMinusEntry,\n} from './QueryBuilderSerialization.js';\nimport type {CountQuery, CountQueryJSON, RawCountInput} from './CountQuery.js';\nimport {requireLiveQueryStore} from '../live/registry.js';\nimport {captureCatalog, getActiveShapeCatalog, withShapeCatalog} from '../utils/ShapeClass.js';\nimport type {ShapeCatalog} from '../utils/ShapeCatalog.js';\nimport type {LiveListener, LiveQuery, LiveQueryOptions} from '../live/LiveQueryStore.js';\nimport {brandLinkedClass, isLinkedInstance} from '../utils/linkedError.js';\n\n/**\n * Everything a count can carry. Assembled by `SelectBuilder.toCount()` or\n * `Shape.count()`.\n *\n * `shapeClass` is required — a shapeless count would count every node in the store.\n */\nexport type CountSpec = {\n /** The catalog the builder resolves in; absent = captured from the active one. */\n catalog?: ShapeCatalog;\n shapeClass: ShapeConstructor<any>;\n subject?: NodeReferenceValue | PendingQueryContext;\n subjects?: NodeReferenceValue[];\n where?: WherePath;\n minusEntries?: RawMinusEntry[];\n /** `.for(null)` was called — there is no subject to count. */\n nullSubject?: boolean;\n};\n\nexport class CountBuilder implements PromiseLike<number>, Promise<number> {\n private readonly _spec: CountSpec;\n private readonly _catalog: ShapeCatalog | undefined;\n\n private constructor(spec: CountSpec) {\n this._spec = spec;\n this._catalog = 'catalog' in spec ? spec.catalog : captureCatalog(spec.shapeClass);\n }\n\n /** The catalog this builder resolves shapes in (undefined = the global registry). */\n get catalog(): ShapeCatalog | undefined {\n return this._catalog;\n }\n\n /** Build from an assembled spec — used by `.toCount()` and `Shape.count()`. */\n static of(spec: CountSpec): CountBuilder {\n return new CountBuilder(spec);\n }\n\n /** Discriminator for the free `lower()` function and dataset routing. */\n readonly __queryKind = 'count' as const;\n\n /** The shape whose matching instances are counted — also the routing key. */\n get shape(): NodeShapeData {\n return this._spec.shapeClass.shape;\n }\n\n toRawInput(): RawCountInput {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this.toRawInput());\n }\n const {shapeClass, subject, subjects, where, minusEntries, nullSubject} =\n this._spec;\n const input: RawCountInput = {shape: shapeClass as any};\n // Carried so lowering can reject it. `exec()` answers `0` before dispatching,\n // but a store handed the builder directly (e.g. after `fromJSON`) would\n // otherwise lower a subject-less query that matches every instance of the\n // shape and report that as the count of one node.\n if (nullSubject) input.nullSubject = true;\n if (subject) input.subject = subject;\n if (subjects && subjects.length > 0) input.subjects = subjects;\n if (where) input.where = where;\n if (minusEntries && minusEntries.length > 0) input.minusEntries = minusEntries;\n return input;\n }\n\n toJSON(): CountQueryJSON {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this.toJSON());\n }\n const {shapeClass, subject, subjects, where, minusEntries, nullSubject} =\n this._spec;\n const shapeId = shapeClass.shape?.id;\n if (!shapeId) {\n // Refuse here rather than emitting `shape: ''` for the receiver's `fromJSON`\n // to reject: the caller who holds the shape can act on this, and a peer\n // across a wire cannot.\n throw new Error(\n 'Cannot serialize a count query whose shape has no id. A count envelope must ' +\n 'name a shape — a shapeless count would count every node in the store.',\n );\n }\n const json: CountQueryJSON = {\n v: WIRE_VERSION,\n op: 'count',\n shape: shapeId,\n };\n\n if (isLinkedInstance(subject, PendingQueryContext)) {\n // Carry the reference, not its (possibly unresolved) id, so the receiver\n // resolves it against its own context map at lowering time.\n json.subject = encodeContextRef(subject.contextName);\n } else if (subject && typeof subject === 'object' && 'id' in subject) {\n json.subject = (subject as NodeReferenceValue).id;\n }\n if (subjects && subjects.length > 0) {\n json.subjects = subjects.map((s) => s.id);\n }\n if (where) {\n json.where = serializeWherePath(where, shapeClass.shape);\n }\n if (minusEntries && minusEntries.length > 0) {\n json.minusEntries = minusEntries.map((e) =>\n serializeRawMinusEntry(e, shapeClass.shape),\n );\n }\n if (nullSubject) {\n json.nullSubject = true;\n }\n return json;\n }\n\n static fromJSON(json: CountQueryJSON): CountBuilder {\n assertWireVersion(json.v);\n if (!json.shape) {\n throw new Error(\n 'A count envelope must name a `shape`. A shapeless count would count every ' +\n 'node in the store, under any type or none.',\n );\n }\n const shapeClass = resolveShape(json.shape as any) as ShapeConstructor<any>;\n const spec: CountSpec = {shapeClass};\n\n if (json.subject !== undefined) {\n spec.subject = isContextRefJSON(json.subject)\n ? new PendingQueryContext(json.subject['@ctx'])\n : {id: json.subject as string};\n }\n if (json.subjects && json.subjects.length > 0) {\n spec.subjects = json.subjects.map((id) => ({id}));\n }\n if (json.where) {\n spec.where = deserializeWherePath(shapeClass.shape, json.where);\n }\n if (json.minusEntries?.length) {\n spec.minusEntries = json.minusEntries.map((e) =>\n deserializeRawMinusEntry(shapeClass.shape, e),\n );\n }\n if (json.nullSubject) spec.nullSubject = true;\n return new CountBuilder(spec);\n }\n\n /**\n * Execute and resolve to a real number.\n *\n * **A failure rejects — it is never reported as `0`.** A count of `0` renders an\n * empty table and is indistinguishable from real data, so a broken count that\n * answered `0` would hide rather than fail. Do not wrap this in `.catch(() => 0)`.\n *\n * The one case that resolves `0` without querying is a query with no subject to\n * count — `.for(null)`, or a `PendingQueryContext` as the subject that has not\n * landed: \"how many nodes with no id match?\" has a correct total answer, and it\n * is `0`.\n */\n async exec(target?: IDataset): Promise<number> {\n const {nullSubject, subject} = this._spec;\n if (nullSubject) return 0;\n if (isLinkedInstance(subject, PendingQueryContext) && !subject.id) return 0;\n // `async` ensures a missing global dispatch rejects rather than throwing\n // synchronously past the caller's `.catch()`.\n const dispatch = target ?? getQueryDispatch();\n // `resolveCount` dispatches over the SELECT channel — a count is a select with\n // an aggregate projection, not a query form of its own — and checks the answer\n // is a real non-negative integer before it reaches the caller.\n return resolveCount(dispatch as any, this);\n }\n\n\n /**\n * Go live: subscribe to this query and keep its result current.\n *\n * Returns a {@link LiveQuery} handle. `await` it for the first result,\n * `subscribe()` for every later one, `close()` when done. A listener may be\n * passed directly as the first argument. Requires the live-query store to be\n * loaded, which importing `@_linked/core` (the package root) does.\n */\n live<R = number>(listenerOrOptions?: LiveListener<R> | LiveQueryOptions, options?: LiveQueryOptions): LiveQuery<R> {\n const listener = typeof listenerOrOptions === 'function' ? listenerOrOptions : undefined;\n const opts = typeof listenerOrOptions === 'function' ? options : listenerOrOptions;\n return requireLiveQueryStore().subscribe<R>(this as any, listener, opts);\n }\n\n /** `await` triggers execution. */\n then<TResult1 = number, TResult2 = never>(\n onfulfilled?: ((value: number) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,\n ): Promise<TResult1 | TResult2> {\n return this.exec().then(onfulfilled, onrejected);\n }\n\n catch<TResult = never>(\n onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null,\n ): Promise<number | TResult> {\n return this.then().catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<number> {\n return this.then().finally(onfinally);\n }\n\n get [Symbol.toStringTag](): string {\n return 'CountBuilder';\n }\n}\nbrandLinkedClass(CountBuilder, '@_linked/core', 'CountBuilder');\n\n\n/** Narrow an unknown query object to a count. */\nexport function isCountQuery(query: unknown): query is CountQuery {\n return !!query && (query as {__queryKind?: string}).__queryKind === 'count';\n}\n"]}
@@ -14,6 +14,7 @@ import { MutationThenable } from './MutationThenable.js';
14
14
  import { resolveMutationDispatch } from './queryDispatch.js';
15
15
  import { WIRE_VERSION, assertWireVersion } from './wireVersion.js';
16
16
  import { encodeNodeData, decodeNodeDataToRaw } from './MutationSerialization.js';
17
+ import { brandLinkedClass } from '../utils/linkedError.js';
17
18
  /**
18
19
  * An immutable, fluent builder for create mutations.
19
20
  *
@@ -132,4 +133,5 @@ export class CreateBuilder extends MutationThenable {
132
133
  });
133
134
  }
134
135
  }
136
+ brandLinkedClass(CreateBuilder, '@_linked/core', 'CreateBuilder');
135
137
  //# sourceMappingURL=CreateBuilder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CreateBuilder.js","sourceRoot":"","sources":["../../../src/queries/CreateBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["import {Shape, type ShapeConstructor} from '../shapes/Shape.js';\nimport {captureCatalog, getActiveShapeCatalog, withShapeCatalog} from '../utils/ShapeClass.js';\nimport type {ShapeCatalog} from '../utils/ShapeCatalog.js';\nimport {resolveShape} from './resolveShape.js';\nimport type {UpdatePartial} from './QueryFactory.js';\nimport type {CreateResponse} from './CreateQuery.js';\nimport {MutationQueryFactory} from './MutationQuery.js';\nimport {MutationThenable} from './MutationThenable.js';\nimport {resolveMutationDispatch} from './queryDispatch.js';\nimport type {IDataset} from '../interfaces/IDataset.js';\nimport {WIRE_VERSION, assertWireVersion} from './wireVersion.js';\nimport type {NodeShapeData} from '../shapes/SHACL.js';\nimport {encodeNodeData, decodeNodeDataToRaw, type CreateMutationJSON} from './MutationSerialization.js';\nimport type {CreateLowerSpec} from './mutationLowerSpec.js';\n\n/**\n * Internal state bag for CreateBuilder.\n */\ninterface CreateBuilderInit<S extends Shape> {\n shape: ShapeConstructor<S>;\n /** The catalog the builder resolves in; absent = captured from the active one. */\n catalog?: ShapeCatalog;\n data?: UpdatePartial<S>;\n fixedId?: string;\n}\n\n/**\n * An immutable, fluent builder for create mutations.\n *\n * Every mutation method returns a new CreateBuilder — the original is never modified.\n *\n * Implements PromiseLike so mutations execute on `await`:\n * ```ts\n * const result = await CreateBuilder.from(Person).set({name: 'Alice'});\n * ```\n *\n * Serialization normalizes through the IR-free factory base; IR is produced by\n * the free `lower()` function (the builder itself imports no IR).\n */\nexport class CreateBuilder<S extends Shape = Shape, U extends UpdatePartial<S> = UpdatePartial<S>>\n extends MutationThenable<CreateResponse<U>>\n{\n protected readonly _tag = 'CreateBuilder';\n private readonly _shape: ShapeConstructor<S>;\n private readonly _data?: UpdatePartial<S>;\n private readonly _fixedId?: string;\n\n private readonly _catalog: ShapeCatalog | undefined;\n\n private constructor(init: CreateBuilderInit<S>) {\n super();\n this._shape = init.shape;\n this._catalog = 'catalog' in init ? init.catalog : captureCatalog(init.shape);\n this._data = init.data;\n this._fixedId = init.fixedId;\n }\n\n private clone(overrides: Partial<CreateBuilderInit<S>> = {}): CreateBuilder<S, any> {\n return new CreateBuilder<S, any>({\n shape: this._shape,\n data: this._data,\n fixedId: this._fixedId,\n catalog: this._catalog,\n ...overrides,\n });\n }\n\n // ---------------------------------------------------------------------------\n // Static constructors\n // ---------------------------------------------------------------------------\n\n /**\n * Create a CreateBuilder for the given shape.\n */\n static from<S extends Shape>(shape: ShapeConstructor<S> | string): CreateBuilder<S> {\n const resolved = resolveShape<S>(shape);\n return new CreateBuilder<S>({shape: resolved});\n }\n\n /** Reconstruct a CreateBuilder from its DSL-JSON (inverse of `toJSON`). */\n static fromJSON(json: CreateMutationJSON): CreateBuilder {\n assertWireVersion(json.v);\n const builder = CreateBuilder.from(json.shape);\n return builder.set(decodeNodeDataToRaw(json.data, builder._shape.shape) as any);\n }\n\n // ---------------------------------------------------------------------------\n // Fluent API\n // ---------------------------------------------------------------------------\n\n /** Set the data for the entity to create. */\n set<NewU extends UpdatePartial<S>>(data: NewU): CreateBuilder<S, NewU> {\n return this.clone({data}) as unknown as CreateBuilder<S, NewU>;\n }\n\n /** Pre-assign a node ID for the created entity. */\n withId(id: string): CreateBuilder<S, U> {\n return this.clone({fixedId: id}) as unknown as CreateBuilder<S, U>;\n }\n\n // ---------------------------------------------------------------------------\n // Build & execute\n // ---------------------------------------------------------------------------\n\n /** Discriminator for the free `lower()` function and dataset routing. */\n readonly __queryKind = 'create' as const;\n\n /** The shape this query targets — the routing key datasets/`LinkedStorage` use. */\n get shape(): NodeShapeData {\n return this._shape.shape;\n }\n\n /** The catalog this builder resolves shapes in (undefined = the global registry). */\n get catalog(): ShapeCatalog | undefined {\n return this._catalog;\n }\n\n /** @internal The IR-free lowering spec consumed by `lower()`. Validates inputs. */\n _lowerSpec(): CreateLowerSpec<S> {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this._lowerSpec());\n }\n if (!this._data) {\n throw new Error(\n 'CreateBuilder requires .set(data) before it can be lowered. Specify what to create.',\n );\n }\n const data = this._data;\n\n // No validation here: `describe()` is the single gate, so lowering and\n // `toJSON()` reject exactly the same input. See `shapes/validation`.\n\n // Inject __id if fixedId is set\n const dataWithId = this._fixedId\n ? {...(data as any), __id: this._fixedId}\n : data;\n return {shapeClass: this._shape, data: dataWithId as UpdatePartial<S>};\n }\n\n /**\n * Serialize this create mutation to lightweight DSL-JSON. Normalizes the create\n * data through the IR-free factory base (the same normalization `lower()` runs)\n * so the result is concrete and JSON-safe, then encodes the node description.\n */\n toJSON(): CreateMutationJSON {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this.toJSON());\n }\n if (!this._data) {\n throw new Error('CreateBuilder requires .set(data) before .toJSON().');\n }\n const dataWithId = this._fixedId\n ? {...(this._data as any), __id: this._fixedId}\n : this._data;\n const description = new MutationQueryFactory().describe(\n this._shape.shape,\n dataWithId,\n {allowTopLevelId: true, validate: 'complete'},\n );\n return {\n v: WIRE_VERSION,\n op: 'create',\n shape: this._shape.shape.id,\n data: encodeNodeData(description, this._shape.shape),\n };\n }\n\n /**\n * Execute the mutation.\n *\n * @param target Optional explicit dataset (a store or a router) to run against. Omitted →\n * the global query dispatch. A `target` runs on that dataset only; the global router is\n * untouched. Rejects if the target dataset doesn't implement create.\n */\n async exec(target?: IDataset): Promise<CreateResponse<U>> {\n return resolveMutationDispatch('create', target).createQuery(this) as Promise<CreateResponse<U>>;\n }\n}\n"]}
1
+ {"version":3,"file":"CreateBuilder.js","sourceRoot":"","sources":["../../../src/queries/CreateBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["import {Shape, type ShapeConstructor} from '../shapes/Shape.js';\nimport {captureCatalog, getActiveShapeCatalog, withShapeCatalog} from '../utils/ShapeClass.js';\nimport type {ShapeCatalog} from '../utils/ShapeCatalog.js';\nimport {resolveShape} from './resolveShape.js';\nimport type {UpdatePartial} from './QueryFactory.js';\nimport type {CreateResponse} from './CreateQuery.js';\nimport {MutationQueryFactory} from './MutationQuery.js';\nimport {MutationThenable} from './MutationThenable.js';\nimport {resolveMutationDispatch} from './queryDispatch.js';\nimport type {IDataset} from '../interfaces/IDataset.js';\nimport {WIRE_VERSION, assertWireVersion} from './wireVersion.js';\nimport type {NodeShapeData} from '../shapes/SHACL.js';\nimport {encodeNodeData, decodeNodeDataToRaw, type CreateMutationJSON} from './MutationSerialization.js';\nimport type {CreateLowerSpec} from './mutationLowerSpec.js';\nimport {brandLinkedClass} from '../utils/linkedError.js';\n\n/**\n * Internal state bag for CreateBuilder.\n */\ninterface CreateBuilderInit<S extends Shape> {\n shape: ShapeConstructor<S>;\n /** The catalog the builder resolves in; absent = captured from the active one. */\n catalog?: ShapeCatalog;\n data?: UpdatePartial<S>;\n fixedId?: string;\n}\n\n/**\n * An immutable, fluent builder for create mutations.\n *\n * Every mutation method returns a new CreateBuilder — the original is never modified.\n *\n * Implements PromiseLike so mutations execute on `await`:\n * ```ts\n * const result = await CreateBuilder.from(Person).set({name: 'Alice'});\n * ```\n *\n * Serialization normalizes through the IR-free factory base; IR is produced by\n * the free `lower()` function (the builder itself imports no IR).\n */\nexport class CreateBuilder<S extends Shape = Shape, U extends UpdatePartial<S> = UpdatePartial<S>>\n extends MutationThenable<CreateResponse<U>>\n{\n protected readonly _tag = 'CreateBuilder';\n private readonly _shape: ShapeConstructor<S>;\n private readonly _data?: UpdatePartial<S>;\n private readonly _fixedId?: string;\n\n private readonly _catalog: ShapeCatalog | undefined;\n\n private constructor(init: CreateBuilderInit<S>) {\n super();\n this._shape = init.shape;\n this._catalog = 'catalog' in init ? init.catalog : captureCatalog(init.shape);\n this._data = init.data;\n this._fixedId = init.fixedId;\n }\n\n private clone(overrides: Partial<CreateBuilderInit<S>> = {}): CreateBuilder<S, any> {\n return new CreateBuilder<S, any>({\n shape: this._shape,\n data: this._data,\n fixedId: this._fixedId,\n catalog: this._catalog,\n ...overrides,\n });\n }\n\n // ---------------------------------------------------------------------------\n // Static constructors\n // ---------------------------------------------------------------------------\n\n /**\n * Create a CreateBuilder for the given shape.\n */\n static from<S extends Shape>(shape: ShapeConstructor<S> | string): CreateBuilder<S> {\n const resolved = resolveShape<S>(shape);\n return new CreateBuilder<S>({shape: resolved});\n }\n\n /** Reconstruct a CreateBuilder from its DSL-JSON (inverse of `toJSON`). */\n static fromJSON(json: CreateMutationJSON): CreateBuilder {\n assertWireVersion(json.v);\n const builder = CreateBuilder.from(json.shape);\n return builder.set(decodeNodeDataToRaw(json.data, builder._shape.shape) as any);\n }\n\n // ---------------------------------------------------------------------------\n // Fluent API\n // ---------------------------------------------------------------------------\n\n /** Set the data for the entity to create. */\n set<NewU extends UpdatePartial<S>>(data: NewU): CreateBuilder<S, NewU> {\n return this.clone({data}) as unknown as CreateBuilder<S, NewU>;\n }\n\n /** Pre-assign a node ID for the created entity. */\n withId(id: string): CreateBuilder<S, U> {\n return this.clone({fixedId: id}) as unknown as CreateBuilder<S, U>;\n }\n\n // ---------------------------------------------------------------------------\n // Build & execute\n // ---------------------------------------------------------------------------\n\n /** Discriminator for the free `lower()` function and dataset routing. */\n readonly __queryKind = 'create' as const;\n\n /** The shape this query targets — the routing key datasets/`LinkedStorage` use. */\n get shape(): NodeShapeData {\n return this._shape.shape;\n }\n\n /** The catalog this builder resolves shapes in (undefined = the global registry). */\n get catalog(): ShapeCatalog | undefined {\n return this._catalog;\n }\n\n /** @internal The IR-free lowering spec consumed by `lower()`. Validates inputs. */\n _lowerSpec(): CreateLowerSpec<S> {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this._lowerSpec());\n }\n if (!this._data) {\n throw new Error(\n 'CreateBuilder requires .set(data) before it can be lowered. Specify what to create.',\n );\n }\n const data = this._data;\n\n // No validation here: `describe()` is the single gate, so lowering and\n // `toJSON()` reject exactly the same input. See `shapes/validation`.\n\n // Inject __id if fixedId is set\n const dataWithId = this._fixedId\n ? {...(data as any), __id: this._fixedId}\n : data;\n return {shapeClass: this._shape, data: dataWithId as UpdatePartial<S>};\n }\n\n /**\n * Serialize this create mutation to lightweight DSL-JSON. Normalizes the create\n * data through the IR-free factory base (the same normalization `lower()` runs)\n * so the result is concrete and JSON-safe, then encodes the node description.\n */\n toJSON(): CreateMutationJSON {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this.toJSON());\n }\n if (!this._data) {\n throw new Error('CreateBuilder requires .set(data) before .toJSON().');\n }\n const dataWithId = this._fixedId\n ? {...(this._data as any), __id: this._fixedId}\n : this._data;\n const description = new MutationQueryFactory().describe(\n this._shape.shape,\n dataWithId,\n {allowTopLevelId: true, validate: 'complete'},\n );\n return {\n v: WIRE_VERSION,\n op: 'create',\n shape: this._shape.shape.id,\n data: encodeNodeData(description, this._shape.shape),\n };\n }\n\n /**\n * Execute the mutation.\n *\n * @param target Optional explicit dataset (a store or a router) to run against. Omitted →\n * the global query dispatch. A `target` runs on that dataset only; the global router is\n * untouched. Rejects if the target dataset doesn't implement create.\n */\n async exec(target?: IDataset): Promise<CreateResponse<U>> {\n return resolveMutationDispatch('create', target).createQuery(this) as Promise<CreateResponse<U>>;\n }\n}\nbrandLinkedClass(CreateBuilder, '@_linked/core', 'CreateBuilder');\n\n"]}
@@ -16,6 +16,7 @@ import { processWhereClause } from './SelectQuery.js';
16
16
  import { serializeWherePath, deserializeWherePath } from './QueryBuilderSerialization.js';
17
17
  import { PendingQueryContext, asContextRef } from './QueryContext.js';
18
18
  import { encodeContextRef, isContextRefJSON } from './ContextRef.js';
19
+ import { brandLinkedClass, isLinkedInstance } from '../utils/linkedError.js';
19
20
  /**
20
21
  * An immutable, fluent builder for delete mutations.
21
22
  *
@@ -153,7 +154,7 @@ export class DeleteBuilder extends MutationThenable {
153
154
  ids: this._ids.map((id) =>
154
155
  // An unresolved context ref travels as a `{@ctx}` marker; a concrete id
155
156
  // (string or `{id}`, incl. a resolved context shape) as a plain string.
156
- id instanceof PendingQueryContext
157
+ isLinkedInstance(id, PendingQueryContext)
157
158
  ? encodeContextRef(id.contextName)
158
159
  : typeof id === 'string'
159
160
  ? id
@@ -179,4 +180,5 @@ export class DeleteBuilder extends MutationThenable {
179
180
  });
180
181
  }
181
182
  }
183
+ brandLinkedClass(DeleteBuilder, '@_linked/core', 'DeleteBuilder');
182
184
  //# sourceMappingURL=DeleteBuilder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DeleteBuilder.js","sourceRoot":"","sources":["../../../src/queries/DeleteBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["import {Shape, type ShapeConstructor} from '../shapes/Shape.js';\nimport {captureCatalog, getActiveShapeCatalog, withShapeCatalog} from '../utils/ShapeClass.js';\nimport type {ShapeCatalog} from '../utils/ShapeCatalog.js';\nimport {resolveShape} from './resolveShape.js';\nimport type {DeleteResponse} from './DeleteQuery.js';\nimport type {NodeId} from './MutationQuery.js';\nimport {MutationThenable} from './MutationThenable.js';\nimport {resolveMutationDispatch} from './queryDispatch.js';\nimport type {IDataset} from '../interfaces/IDataset.js';\nimport {WIRE_VERSION, assertWireVersion} from './wireVersion.js';\nimport type {NodeShapeData} from '../shapes/SHACL.js';\nimport {type WhereClause, type WherePath, processWhereClause} from './SelectQuery.js';\nimport {type DeleteMutationJSON} from './MutationSerialization.js';\nimport {serializeWherePath, deserializeWherePath} from './QueryBuilderSerialization.js';\nimport type {DeleteLowerSpec} from './mutationLowerSpec.js';\nimport {PendingQueryContext, asContextRef} from './QueryContext.js';\nimport {encodeContextRef, isContextRefJSON} from './ContextRef.js';\n\ntype DeleteMode = 'ids' | 'all' | 'where';\n\n/** A node to delete: a concrete id, a `{id}` ref, or a live query-context reference. */\nexport type DeleteId = NodeId | PendingQueryContext;\n\n/**\n * Internal state bag for DeleteBuilder.\n */\ninterface DeleteBuilderInit<S extends Shape> {\n shape: ShapeConstructor<S>;\n /** The catalog the builder resolves in; absent = captured from the active one. */\n catalog?: ShapeCatalog;\n ids?: DeleteId[];\n mode?: DeleteMode;\n whereFn?: WhereClause<S>;\n /** A pre-resolved where path (used by fromJSON; no live callback). */\n where?: WherePath;\n}\n\n/**\n * An immutable, fluent builder for delete mutations.\n *\n * Implements PromiseLike so mutations execute on `await`:\n * ```ts\n * const result = await DeleteBuilder.from(Person, {id: '...'});\n * await DeleteBuilder.from(Person).all(); // returns void\n * ```\n *\n * R is the resolved type: DeleteResponse for ID-based, void for bulk operations.\n */\nexport class DeleteBuilder<S extends Shape = Shape, R = DeleteResponse>\n extends MutationThenable<R>\n{\n protected readonly _tag = 'DeleteBuilder';\n private readonly _shape: ShapeConstructor<S>;\n private readonly _ids?: DeleteId[];\n private readonly _mode?: DeleteMode;\n private readonly _whereFn?: WhereClause<S>;\n private readonly _where?: WherePath;\n\n private readonly _catalog: ShapeCatalog | undefined;\n\n private constructor(init: DeleteBuilderInit<S>) {\n super();\n this._shape = init.shape;\n this._catalog = 'catalog' in init ? init.catalog : captureCatalog(init.shape);\n this._ids = init.ids;\n this._mode = init.mode;\n this._whereFn = init.whereFn;\n this._where = init.where;\n }\n\n private clone(overrides: Partial<DeleteBuilderInit<S>> = {}): DeleteBuilder<S, any> {\n return new DeleteBuilder<S>({\n shape: this._shape,\n ids: this._ids,\n mode: this._mode,\n whereFn: this._whereFn,\n where: this._where,\n catalog: this._catalog,\n ...overrides,\n });\n }\n\n // ---------------------------------------------------------------------------\n // Static constructors\n // ---------------------------------------------------------------------------\n\n static from<S extends Shape>(\n shape: ShapeConstructor<S> | string,\n ids?: DeleteId | DeleteId[],\n ): DeleteBuilder<S, DeleteResponse> {\n const resolved = resolveShape<S>(shape);\n if (ids !== undefined) {\n // Normalize any context reference (unset PendingQueryContext or a resolved\n // context shape) to a {@ctx} marker so set/unset behave identically.\n const idsArray = (Array.isArray(ids) ? ids : [ids]).map(\n (id) => asContextRef(id) ?? id,\n );\n return new DeleteBuilder<S>({shape: resolved, ids: idsArray, mode: 'ids'});\n }\n return new DeleteBuilder<S>({shape: resolved});\n }\n\n /** Reconstruct a DeleteBuilder from its DSL-JSON (inverse of `toJSON`). */\n static fromJSON(json: DeleteMutationJSON): DeleteBuilder {\n assertWireVersion(json.v);\n const resolved = resolveShape(json.shape);\n if (json.mode === 'ids') {\n // A `{@ctx}` id rehydrates as a live context ref (resolved at lower).\n const ids: DeleteId[] = json.ids.map((id) =>\n isContextRefJSON(id) ? new PendingQueryContext(id['@ctx']) : {id},\n );\n return new DeleteBuilder({shape: resolved, ids, mode: 'ids'});\n }\n if (json.mode === 'all') {\n return new DeleteBuilder({shape: resolved, mode: 'all'});\n }\n const where = deserializeWherePath(resolved.shape, json.where);\n return new DeleteBuilder({shape: resolved, mode: 'where', where});\n }\n\n // ---------------------------------------------------------------------------\n // Fluent API\n // ---------------------------------------------------------------------------\n\n /** Delete all instances of this shape type. Returns void. */\n all(): DeleteBuilder<S, void> {\n return this.clone({mode: 'all', ids: undefined, whereFn: undefined}) as DeleteBuilder<S, void>;\n }\n\n /** Delete instances matching a condition. Returns void. */\n where(fn: WhereClause<S>): DeleteBuilder<S, void> {\n return this.clone({mode: 'where', whereFn: fn, ids: undefined}) as DeleteBuilder<S, void>;\n }\n\n // ---------------------------------------------------------------------------\n // Build & execute\n // ---------------------------------------------------------------------------\n\n /** Discriminator for the free `lower()` function and dataset routing. */\n readonly __queryKind = 'delete' as const;\n\n /** The shape this query targets — the routing key datasets/`LinkedStorage` use. */\n get shape(): NodeShapeData {\n return this._shape.shape;\n }\n\n /** The catalog this builder resolves shapes in (undefined = the global registry). */\n get catalog(): ShapeCatalog | undefined {\n return this._catalog;\n }\n\n /** @internal The IR-free lowering spec consumed by `lower()`. Validates inputs. */\n _lowerSpec(): DeleteLowerSpec<S> {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this._lowerSpec());\n }\n const mode = this._mode || (this._ids ? 'ids' : undefined);\n\n if (mode === 'all') {\n return {shapeClass: this._shape, mode: 'all'};\n }\n\n if (mode === 'where') {\n const wherePath =\n this._where ?? (this._whereFn ? processWhereClause(this._whereFn, this._shape) : undefined);\n if (!wherePath) {\n throw new Error('DeleteBuilder.where() requires a condition callback.');\n }\n return {shapeClass: this._shape, mode: 'where', wherePath};\n }\n\n // Default: ID-based delete\n if (!this._ids || this._ids.length === 0) {\n throw new Error(\n 'DeleteBuilder requires at least one ID to delete. Use DeleteBuilder.from(shape, ids), .all(), or .where().',\n );\n }\n return {shapeClass: this._shape, mode: 'ids', ids: this._ids};\n }\n\n /** Serialize this delete mutation to lightweight DSL-JSON. */\n toJSON(): DeleteMutationJSON {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this.toJSON());\n }\n const shape = this._shape.shape.id;\n const mode = this._mode || (this._ids ? 'ids' : undefined);\n if (mode === 'all') {\n return {v: WIRE_VERSION, op: 'delete', shape, mode: 'all'};\n }\n if (mode === 'where') {\n const wherePath = this._where ?? (this._whereFn ? processWhereClause(this._whereFn, this._shape) : undefined);\n if (!wherePath) {\n throw new Error('DeleteBuilder.where() requires a condition callback.');\n }\n return {\n v: WIRE_VERSION,\n op: 'delete',\n shape,\n mode: 'where',\n where: serializeWherePath(wherePath, this._shape.shape),\n };\n }\n if (!this._ids || this._ids.length === 0) {\n throw new Error(\n 'DeleteBuilder requires at least one ID, .all(), or .where() before .toJSON().',\n );\n }\n return {\n v: WIRE_VERSION,\n op: 'delete',\n shape,\n mode: 'ids',\n ids: this._ids.map((id) =>\n // An unresolved context ref travels as a `{@ctx}` marker; a concrete id\n // (string or `{id}`, incl. a resolved context shape) as a plain string.\n id instanceof PendingQueryContext\n ? encodeContextRef(id.contextName)\n : typeof id === 'string'\n ? id\n : id.id,\n ),\n };\n }\n\n /**\n * Execute the mutation.\n *\n * @param target Optional explicit dataset (a store or a router) to run against. Omitted →\n * the global query dispatch. A `target` runs on that dataset only; the global router is\n * untouched. Rejects if the target dataset doesn't implement delete.\n */\n async exec(target?: IDataset): Promise<R> {\n const mode = this._mode || (this._ids ? 'ids' : undefined);\n const result = resolveMutationDispatch('delete', target).deleteQuery(this);\n // Bulk (all/where) resolves to void; id-based resolves to the DeleteResponse.\n if (mode === 'all' || mode === 'where') {\n return result.then(() => undefined) as Promise<R>;\n }\n return result as Promise<R>;\n }\n\n}\n"]}
1
+ {"version":3,"file":"DeleteBuilder.js","sourceRoot":"","sources":["../../../src/queries/DeleteBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["import {Shape, type ShapeConstructor} from '../shapes/Shape.js';\nimport {captureCatalog, getActiveShapeCatalog, withShapeCatalog} from '../utils/ShapeClass.js';\nimport type {ShapeCatalog} from '../utils/ShapeCatalog.js';\nimport {resolveShape} from './resolveShape.js';\nimport type {DeleteResponse} from './DeleteQuery.js';\nimport type {NodeId} from './MutationQuery.js';\nimport {MutationThenable} from './MutationThenable.js';\nimport {resolveMutationDispatch} from './queryDispatch.js';\nimport type {IDataset} from '../interfaces/IDataset.js';\nimport {WIRE_VERSION, assertWireVersion} from './wireVersion.js';\nimport type {NodeShapeData} from '../shapes/SHACL.js';\nimport {type WhereClause, type WherePath, processWhereClause} from './SelectQuery.js';\nimport {type DeleteMutationJSON} from './MutationSerialization.js';\nimport {serializeWherePath, deserializeWherePath} from './QueryBuilderSerialization.js';\nimport type {DeleteLowerSpec} from './mutationLowerSpec.js';\nimport {PendingQueryContext, asContextRef} from './QueryContext.js';\nimport {encodeContextRef, isContextRefJSON} from './ContextRef.js';\nimport {brandLinkedClass, isLinkedInstance} from '../utils/linkedError.js';\n\ntype DeleteMode = 'ids' | 'all' | 'where';\n\n/** A node to delete: a concrete id, a `{id}` ref, or a live query-context reference. */\nexport type DeleteId = NodeId | PendingQueryContext;\n\n/**\n * Internal state bag for DeleteBuilder.\n */\ninterface DeleteBuilderInit<S extends Shape> {\n shape: ShapeConstructor<S>;\n /** The catalog the builder resolves in; absent = captured from the active one. */\n catalog?: ShapeCatalog;\n ids?: DeleteId[];\n mode?: DeleteMode;\n whereFn?: WhereClause<S>;\n /** A pre-resolved where path (used by fromJSON; no live callback). */\n where?: WherePath;\n}\n\n/**\n * An immutable, fluent builder for delete mutations.\n *\n * Implements PromiseLike so mutations execute on `await`:\n * ```ts\n * const result = await DeleteBuilder.from(Person, {id: '...'});\n * await DeleteBuilder.from(Person).all(); // returns void\n * ```\n *\n * R is the resolved type: DeleteResponse for ID-based, void for bulk operations.\n */\nexport class DeleteBuilder<S extends Shape = Shape, R = DeleteResponse>\n extends MutationThenable<R>\n{\n protected readonly _tag = 'DeleteBuilder';\n private readonly _shape: ShapeConstructor<S>;\n private readonly _ids?: DeleteId[];\n private readonly _mode?: DeleteMode;\n private readonly _whereFn?: WhereClause<S>;\n private readonly _where?: WherePath;\n\n private readonly _catalog: ShapeCatalog | undefined;\n\n private constructor(init: DeleteBuilderInit<S>) {\n super();\n this._shape = init.shape;\n this._catalog = 'catalog' in init ? init.catalog : captureCatalog(init.shape);\n this._ids = init.ids;\n this._mode = init.mode;\n this._whereFn = init.whereFn;\n this._where = init.where;\n }\n\n private clone(overrides: Partial<DeleteBuilderInit<S>> = {}): DeleteBuilder<S, any> {\n return new DeleteBuilder<S>({\n shape: this._shape,\n ids: this._ids,\n mode: this._mode,\n whereFn: this._whereFn,\n where: this._where,\n catalog: this._catalog,\n ...overrides,\n });\n }\n\n // ---------------------------------------------------------------------------\n // Static constructors\n // ---------------------------------------------------------------------------\n\n static from<S extends Shape>(\n shape: ShapeConstructor<S> | string,\n ids?: DeleteId | DeleteId[],\n ): DeleteBuilder<S, DeleteResponse> {\n const resolved = resolveShape<S>(shape);\n if (ids !== undefined) {\n // Normalize any context reference (unset PendingQueryContext or a resolved\n // context shape) to a {@ctx} marker so set/unset behave identically.\n const idsArray = (Array.isArray(ids) ? ids : [ids]).map(\n (id) => asContextRef(id) ?? id,\n );\n return new DeleteBuilder<S>({shape: resolved, ids: idsArray, mode: 'ids'});\n }\n return new DeleteBuilder<S>({shape: resolved});\n }\n\n /** Reconstruct a DeleteBuilder from its DSL-JSON (inverse of `toJSON`). */\n static fromJSON(json: DeleteMutationJSON): DeleteBuilder {\n assertWireVersion(json.v);\n const resolved = resolveShape(json.shape);\n if (json.mode === 'ids') {\n // A `{@ctx}` id rehydrates as a live context ref (resolved at lower).\n const ids: DeleteId[] = json.ids.map((id) =>\n isContextRefJSON(id) ? new PendingQueryContext(id['@ctx']) : {id},\n );\n return new DeleteBuilder({shape: resolved, ids, mode: 'ids'});\n }\n if (json.mode === 'all') {\n return new DeleteBuilder({shape: resolved, mode: 'all'});\n }\n const where = deserializeWherePath(resolved.shape, json.where);\n return new DeleteBuilder({shape: resolved, mode: 'where', where});\n }\n\n // ---------------------------------------------------------------------------\n // Fluent API\n // ---------------------------------------------------------------------------\n\n /** Delete all instances of this shape type. Returns void. */\n all(): DeleteBuilder<S, void> {\n return this.clone({mode: 'all', ids: undefined, whereFn: undefined}) as DeleteBuilder<S, void>;\n }\n\n /** Delete instances matching a condition. Returns void. */\n where(fn: WhereClause<S>): DeleteBuilder<S, void> {\n return this.clone({mode: 'where', whereFn: fn, ids: undefined}) as DeleteBuilder<S, void>;\n }\n\n // ---------------------------------------------------------------------------\n // Build & execute\n // ---------------------------------------------------------------------------\n\n /** Discriminator for the free `lower()` function and dataset routing. */\n readonly __queryKind = 'delete' as const;\n\n /** The shape this query targets — the routing key datasets/`LinkedStorage` use. */\n get shape(): NodeShapeData {\n return this._shape.shape;\n }\n\n /** The catalog this builder resolves shapes in (undefined = the global registry). */\n get catalog(): ShapeCatalog | undefined {\n return this._catalog;\n }\n\n /** @internal The IR-free lowering spec consumed by `lower()`. Validates inputs. */\n _lowerSpec(): DeleteLowerSpec<S> {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this._lowerSpec());\n }\n const mode = this._mode || (this._ids ? 'ids' : undefined);\n\n if (mode === 'all') {\n return {shapeClass: this._shape, mode: 'all'};\n }\n\n if (mode === 'where') {\n const wherePath =\n this._where ?? (this._whereFn ? processWhereClause(this._whereFn, this._shape) : undefined);\n if (!wherePath) {\n throw new Error('DeleteBuilder.where() requires a condition callback.');\n }\n return {shapeClass: this._shape, mode: 'where', wherePath};\n }\n\n // Default: ID-based delete\n if (!this._ids || this._ids.length === 0) {\n throw new Error(\n 'DeleteBuilder requires at least one ID to delete. Use DeleteBuilder.from(shape, ids), .all(), or .where().',\n );\n }\n return {shapeClass: this._shape, mode: 'ids', ids: this._ids};\n }\n\n /** Serialize this delete mutation to lightweight DSL-JSON. */\n toJSON(): DeleteMutationJSON {\n const catalog = this._catalog;\n if (catalog !== getActiveShapeCatalog()) {\n return withShapeCatalog(catalog, () => this.toJSON());\n }\n const shape = this._shape.shape.id;\n const mode = this._mode || (this._ids ? 'ids' : undefined);\n if (mode === 'all') {\n return {v: WIRE_VERSION, op: 'delete', shape, mode: 'all'};\n }\n if (mode === 'where') {\n const wherePath = this._where ?? (this._whereFn ? processWhereClause(this._whereFn, this._shape) : undefined);\n if (!wherePath) {\n throw new Error('DeleteBuilder.where() requires a condition callback.');\n }\n return {\n v: WIRE_VERSION,\n op: 'delete',\n shape,\n mode: 'where',\n where: serializeWherePath(wherePath, this._shape.shape),\n };\n }\n if (!this._ids || this._ids.length === 0) {\n throw new Error(\n 'DeleteBuilder requires at least one ID, .all(), or .where() before .toJSON().',\n );\n }\n return {\n v: WIRE_VERSION,\n op: 'delete',\n shape,\n mode: 'ids',\n ids: this._ids.map((id) =>\n // An unresolved context ref travels as a `{@ctx}` marker; a concrete id\n // (string or `{id}`, incl. a resolved context shape) as a plain string.\n isLinkedInstance(id, PendingQueryContext)\n ? encodeContextRef(id.contextName)\n : typeof id === 'string'\n ? id\n : id.id,\n ),\n };\n }\n\n /**\n * Execute the mutation.\n *\n * @param target Optional explicit dataset (a store or a router) to run against. Omitted →\n * the global query dispatch. A `target` runs on that dataset only; the global router is\n * untouched. Rejects if the target dataset doesn't implement delete.\n */\n async exec(target?: IDataset): Promise<R> {\n const mode = this._mode || (this._ids ? 'ids' : undefined);\n const result = resolveMutationDispatch('delete', target).deleteQuery(this);\n // Bulk (all/where) resolves to void; id-based resolves to the DeleteResponse.\n if (mode === 'all' || mode === 'where') {\n return result.then(() => undefined) as Promise<R>;\n }\n return result as Promise<R>;\n }\n\n}\nbrandLinkedClass(DeleteBuilder, '@_linked/core', 'DeleteBuilder');\n\n"]}
@@ -1,5 +1,6 @@
1
1
  import { ExpressionNode, ExistsCondition, tracedPropertyExpression, tracedAliasExpression, } from '../expressions/ExpressionNode.js';
2
2
  import { walkPropertyPath } from './PropertyPath.js';
3
+ import { isLinkedInstance } from '../utils/linkedError.js';
3
4
  const COMPARISON_OPS = new Set([
4
5
  '=',
5
6
  '!=',
@@ -190,7 +191,7 @@ const AGGREGATES = new Set(['count', 'sum', 'avg', 'min', 'max']);
190
191
  // ---------------------------------------------------------------------------
191
192
  /** Encode a where-clause node (boolean) into a DSL-JSON condition. */
192
193
  export function encodeCondition(node, shape) {
193
- if (node instanceof ExistsCondition) {
194
+ if (isLinkedInstance(node, ExistsCondition)) {
194
195
  return encodeExists(node, shape);
195
196
  }
196
197
  return encodeBoolExpr(node.ir, node._refs, shape);
@@ -216,7 +217,7 @@ function encodeExists(ec, shape) {
216
217
  };
217
218
  // Fold any chained and/or conditions into nested logical combinators.
218
219
  for (const { op, condition } of ec.chain) {
219
- const c = encodeCondition(condition instanceof ExistsCondition ? condition : condition, shape);
220
+ const c = encodeCondition(isLinkedInstance(condition, ExistsCondition) ? condition : condition, shape);
220
221
  base = { [op]: [base, c] };
221
222
  }
222
223
  return base;
@@ -288,7 +289,7 @@ function tryMergeAnd(parts) {
288
289
  /** Decode a DSL-JSON condition into a runtime WherePath (`{expressionNode}` | `{existsCondition}`). */
289
290
  export function decodeCondition(json, shape) {
290
291
  const node = decodeConditionNode(json, shape);
291
- return node instanceof ExistsCondition
292
+ return isLinkedInstance(node, ExistsCondition)
292
293
  ? { existsCondition: node }
293
294
  : { expressionNode: node };
294
295
  }
@@ -305,14 +306,14 @@ function decodeConditionNode(json, shape) {
305
306
  const k = keys[0];
306
307
  if (k === 'not') {
307
308
  const inner = decodeConditionNode(o.not, shape);
308
- if (inner instanceof ExistsCondition)
309
+ if (isLinkedInstance(inner, ExistsCondition))
309
310
  return inner.not();
310
311
  return new ExpressionNode({ kind: 'not_expr', expression: inner.ir }, inner._refs);
311
312
  }
312
313
  // and / or
313
314
  const elems = o[k].map((c) => decodeConditionNode(c, shape));
314
315
  // An exists-chain: first operand is an ExistsCondition → fold the rest as its chain.
315
- if (elems[0] instanceof ExistsCondition) {
316
+ if (isLinkedInstance(elems[0], ExistsCondition)) {
316
317
  let ec = elems[0];
317
318
  for (let i = 1; i < elems.length; i++) {
318
319
  ec = (k === 'and' ? ec.and(elems[i]) : ec.or(elems[i]));
@@ -410,7 +411,7 @@ function matchQuantifier(key) {
410
411
  /** A quantifier predicate decodes to an ExpressionNode (its inner boolean). */
411
412
  function expressionNodeFromCondition(json, shape) {
412
413
  const node = decodeConditionNode(json, shape);
413
- if (node instanceof ExistsCondition) {
414
+ if (isLinkedInstance(node, ExistsCondition)) {
414
415
  // Nested exists as a predicate is uncommon; wrap is not representable here.
415
416
  throw new Error('Nested exists inside a quantifier predicate is not supported');
416
417
  }