@routier/core 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +1 -1
  2. package/dist/index.cjs +88 -438
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +0 -1
  5. package/dist/index.js +94 -443
  6. package/dist/index.js.map +1 -1
  7. package/dist/plugins/TelemetryDbPlugin.d.ts +43 -0
  8. package/dist/plugins/index.cjs +82 -1
  9. package/dist/plugins/index.cjs.map +1 -1
  10. package/dist/plugins/index.d.ts +2 -0
  11. package/dist/plugins/index.js +88 -3
  12. package/dist/plugins/index.js.map +1 -1
  13. package/dist/plugins/resultShape.d.ts +35 -0
  14. package/dist/transfer/ChunkEncoder.d.ts +60 -0
  15. package/dist/transfer/decoder.d.ts +29 -0
  16. package/dist/transfer/fillers.d.ts +36 -0
  17. package/dist/transfer/index.cjs +873 -0
  18. package/dist/transfer/index.cjs.map +1 -0
  19. package/dist/transfer/index.d.ts +47 -0
  20. package/dist/transfer/index.js +872 -0
  21. package/dist/transfer/index.js.map +1 -0
  22. package/dist/transfer/plan.d.ts +94 -0
  23. package/dist/transfer/types.d.ts +138 -0
  24. package/package.json +9 -9
  25. package/dist/capabilities/Capability.d.ts +0 -11
  26. package/dist/capabilities/PerformanceCapability.d.ts +0 -13
  27. package/dist/capabilities/TracingCapability.d.ts +0 -11
  28. package/dist/capabilities/index.cjs +0 -820
  29. package/dist/capabilities/index.cjs.map +0 -1
  30. package/dist/capabilities/index.d.ts +0 -4
  31. package/dist/capabilities/index.js +0 -808
  32. package/dist/capabilities/index.js.map +0 -1
  33. package/dist/capabilities/performance/PerformanceTracker.d.ts +0 -11
  34. package/dist/capabilities/tracing/CallTraceManager.d.ts +0 -12
  35. package/dist/capabilities/types.d.ts +0 -17
@@ -1 +1 @@
1
- {"version":3,"file":"plugins/index.cjs","sources":["webpack://@routier/core/./src/assertions/index.ts","webpack://@routier/core/./src/collections/Changes.ts","webpack://@routier/core/./src/collections/ReadonlySchemaCollection.ts","webpack://@routier/core/./src/collections/SchemaCollection.ts","webpack://@routier/core/./src/collections/TagCollection.ts","webpack://@routier/core/./src/errors/OptimisticConcurrencyError.ts","webpack://@routier/core/./src/errors/PluginDestroyedError.ts","webpack://@routier/core/./src/expressions/evaluate.ts","webpack://@routier/core/./src/expressions/parser.ts","webpack://@routier/core/./src/expressions/types.ts","webpack://@routier/core/./src/expressions/utils.ts","webpack://@routier/core/./src/pipeline/TrampolinePipeline.ts","webpack://@routier/core/./src/plugins/query/QueryOptionsCollection.ts","webpack://@routier/core/./src/results/Result.ts","webpack://@routier/core/./src/schema/types.ts","webpack://@routier/core/./src/utilities/dates.ts","webpack://@routier/core/./src/utilities/logger.ts","webpack://@routier/core/./src/utilities/uuid.ts","webpack://@routier/core/webpack/runtime/define_property_getters","webpack://@routier/core/webpack/runtime/has_own_property","webpack://@routier/core/webpack/runtime/make_namespace_object","webpack://@routier/core/./src/plugins/translators/TranslatedArrayValue.ts","webpack://@routier/core/./src/plugins/translators/TranslatedGroupValue.ts","webpack://@routier/core/./src/plugins/translators/TranslatedSingleValue.ts","webpack://@routier/core/./src/plugins/translators/DataTranslator.ts","webpack://@routier/core/./src/plugins/query/similarity.ts","webpack://@routier/core/./src/plugins/query/Query.ts","webpack://@routier/core/./src/plugins/query/join.ts","webpack://@routier/core/./src/plugins/translators/JsonTranslator.ts","webpack://@routier/core/./src/plugins/translators/SqlTranslator.ts","webpack://@routier/core/./src/plugins/translators/TupleTranslator.ts","webpack://@routier/core/./src/plugins/translators/index.ts","webpack://@routier/core/./src/plugins/query/explain.ts","webpack://@routier/core/./src/plugins/query/formatExplanation.ts","webpack://@routier/core/./src/plugins/query/types.ts","webpack://@routier/core/./src/plugins/query/index.ts","webpack://@routier/core/./src/plugins/wire/query.ts","webpack://@routier/core/./src/plugins/wire/persist.ts","webpack://@routier/core/./src/plugins/wire/handler.ts","webpack://@routier/core/./src/plugins/wire/index.ts","webpack://@routier/core/./src/plugins/ConcurrencyDbPlugin.ts","webpack://@routier/core/./src/plugins/EphemeralDataPlugin.ts","webpack://@routier/core/./src/plugins/RetryDbPlugin.ts","webpack://@routier/core/./src/plugins/CacheDbPlugin.ts","webpack://@routier/core/./src/plugins/BatchingDbPlugin.ts","webpack://@routier/core/./src/plugins/index.ts"],"sourcesContent":["import { EXPRESSION_TYPES } from \"../expressions/constants\";\nimport { ComparatorExpression, EmptyExpression, Expression, ExpressionType, NotParsableExpression, OperatorExpression, PropertyExpression, ValueExpression } from \"../expressions/types\";\nimport { isDate } from \"../utilities\";\n\nexport function assertDate(data: unknown): asserts data is Date {\n if (isDate(data) === false) {\n throw new TypeError('Value is not a Date');\n }\n}\n\nexport function assertIsNotNull<T>(data: T | null | undefined, message?: string | (() => string)): asserts data is NonNullable<T> {\n if (data == null) {\n if (message == null) {\n throw new TypeError('Assertion failed, data is null');\n }\n\n if (typeof message === \"string\") {\n throw new TypeError(message);\n }\n\n throw new TypeError(message());\n }\n}\n\nexport function assertIsArray<T>(data: unknown, message?: string): asserts data is T[] {\n if (!Array.isArray(data)) {\n throw new TypeError(message ?? 'Assertion failed, data is not of type Array');\n }\n}\n\nexport function assertString(data: unknown, message?: string): asserts data is string {\n if (typeof data !== \"string\") {\n throw new TypeError(message ?? 'Assertion failed, data is not of type String');\n }\n}\n\nexport function assertInstanceOf<T extends new (...args: any[]) => any>(value: unknown, Instance: T): asserts value is T {\n if (value instanceof Instance) {\n return;\n }\n\n if (value != null && typeof value === \"object\" && \"constructor\" in value) {\n throw new TypeError(`value is not instance of type. Type: ${value.constructor.name}`);\n }\n\n throw new TypeError(`value is not instance of type`);\n}\n\nexport function assertIsNumber(value: unknown): asserts value is number {\n if (typeof value !== \"number\") {\n throw new TypeError(\"value is not of type `number`\");\n }\n}\n\n\nfunction isObjectWithType(value: unknown): value is Record<\"type\", unknown> {\n return typeof value === \"object\" && value !== null && \"type\" in value;\n}\n\n/**\n * Type guard: narrows `value` to `Expression` when it is an object with a valid `type` property.\n */\nexport function isExpression(value: unknown): value is Expression {\n return isObjectWithType(value) && EXPRESSION_TYPES.includes(value.type as ExpressionType);\n}\n\n/**\n * Type guard: narrows `value` to `OperatorExpression` when it is an object with `type === \"operator\"`.\n */\nexport function isOperatorExpression(value: unknown): value is OperatorExpression {\n return isObjectWithType(value) && value.type === \"operator\";\n}\n\n/**\n * Type guard: narrows `value` to `ComparatorExpression` when it is an object with `type === \"comparator\"`.\n */\nexport function isComparatorExpression(value: unknown): value is ComparatorExpression {\n return isObjectWithType(value) && value.type === \"comparator\";\n}\n\n/**\n * Type guard: narrows `value` to `PropertyExpression` when it is an object with `type === \"property\"`.\n */\nexport function isPropertyExpression(value: unknown): value is PropertyExpression {\n return isObjectWithType(value) && value.type === \"property\";\n}\n\n/**\n * Type guard: narrows `value` to `ValueExpression` when it is an object with `type === \"value\"`.\n */\nexport function isValueExpression(value: unknown): value is ValueExpression {\n return isObjectWithType(value) && value.type === \"value\";\n}\n\n/**\n * Type guard: narrows `value` to `EmptyExpression` when it is an object with `type === \"empty\"`.\n */\nexport function isEmptyExpression(value: unknown): value is EmptyExpression {\n return isObjectWithType(value) && value.type === \"empty\";\n}\n\n/**\n * Type guard: narrows `value` to `NotParsableExpression` when it is an object with `type === \"not-parsable\"`.\n */\nexport function isNotParsableExpression(value: unknown): value is NotParsableExpression {\n return isObjectWithType(value) && value.type === \"not-parsable\";\n}","import { EntityUpdateInfo } from \"../plugins/types\";\nimport { InferCreateType, InferType, SchemaId } from \"../schema\";\nimport { TagCollection } from \"./TagCollection\";\nexport class BulkPersistResult extends Map<SchemaId, SchemaPersistResult> {\n\n resolve<T extends {} = Record<string, unknown>>(schemaId: SchemaId): SchemaPersistResult<T> {\n if (this.has(schemaId)) {\n return this.get(schemaId);\n }\n\n this.set(schemaId, new SchemaPersistResult<T>());\n\n return this.get(schemaId);\n }\n\n override get<T extends {} = Record<string, unknown>>(schemaId: SchemaId) {\n return super.get(schemaId) as SchemaPersistResult<T>\n }\n\n get aggregate() {\n return {\n size: this.aggregateSize,\n adds: this.aggregateAddsSize,\n updates: this.aggregateUpdatesSize,\n removes: this.aggregateRemovesSize\n }\n }\n\n private get aggregateSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.total;\n }\n\n return count;\n }\n\n private get aggregateAddsSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.adds.length;\n }\n\n return count;\n }\n\n private get aggregateUpdatesSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.updates.length;\n }\n\n return count;\n }\n\n private get aggregateRemovesSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.removes.length;\n }\n\n return count;\n }\n}\n\nexport class BulkPersistChanges extends Map<SchemaId, SchemaPersistChanges> {\n\n resolve<T extends {} = Record<string, unknown>>(schemaId: SchemaId): SchemaPersistChanges<T> {\n if (this.has(schemaId)) {\n return this.get(schemaId);\n }\n\n this.set(schemaId, new SchemaPersistChanges<T>());\n\n return this.get(schemaId);\n }\n\n override get<T extends {} = Record<string, unknown>>(schemaId: SchemaId) {\n return super.get(schemaId) as SchemaPersistChanges<T>\n }\n\n get aggregate() {\n return {\n size: this.aggregateSize,\n adds: this.aggregateAddsSize,\n updates: this.aggregateUpdatesSize,\n removes: this.aggregateRemovesSize\n }\n }\n\n private get aggregateSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.total;\n }\n\n return count;\n }\n\n private get aggregateAddsSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.adds.length;\n }\n\n return count;\n }\n\n private get aggregateUpdatesSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.updates.length;\n }\n\n return count;\n }\n\n private get aggregateRemovesSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.removes.length;\n }\n\n return count;\n }\n\n /**\n * Ensures the result has the same result sets as the change sets\n * @returns \n */\n toResult() {\n const result = new BulkPersistResult();\n\n for (const [schemaId] of this) {\n result.set(schemaId, new SchemaPersistResult());\n }\n\n return result;\n }\n}\n\nexport class SchemaPersistChanges<T extends {} = Record<string, unknown>> {\n adds: InferCreateType<T>[] = [];\n updates: EntityUpdateInfo<T>[] = [];\n removes: InferType<T>[] = [];\n tags: TagCollection = new TagCollection();\n\n get hasItems() {\n return this.total > 0;\n }\n\n get total() {\n return this.adds.length + this.updates.length + this.removes.length;\n }\n}\n\nexport class SchemaPersistResult<T extends {} = Record<string, unknown>> {\n adds: InferType<T>[] = [];\n updates: InferType<T>[] = [];\n removes: InferType<T>[] = [];\n\n get hasItems() {\n return this.total > 0;\n }\n\n get total() {\n return this.adds.length + this.updates.length + this.removes.length;\n }\n}","import { CompiledSchema, SchemaId } from \"../schema\";\n\n/**\n * Collection of schemas with generic typing for type-safe schema retrieval\n */\nexport class ReadonlySchemaCollection {\n\n protected data: Map<SchemaId, CompiledSchema<Record<string, unknown>>>;\n\n constructor(data?: [SchemaId, CompiledSchema<Record<string, unknown>>][]) {\n this.data = new Map<SchemaId, CompiledSchema<Record<string, unknown>>>(data);\n }\n\n get<T>(schemaId: SchemaId): CompiledSchema<T> | undefined {\n return this.data.get(schemaId) as CompiledSchema<T> | undefined;\n }\n\n has(schemaId: SchemaId): boolean {\n return this.data.has(schemaId);\n }\n\n get size(): number {\n return this.data.size;\n }\n\n keys(): IterableIterator<SchemaId> {\n return this.data.keys();\n }\n\n values(): IterableIterator<CompiledSchema<Record<string, unknown>>> {\n return this.data.values();\n }\n\n entries(): IterableIterator<[SchemaId, CompiledSchema<Record<string, unknown>>]> {\n return this.data.entries();\n }\n\n forEach(callbackfn: (value: CompiledSchema<Record<string, unknown>>, key: SchemaId, map: Map<SchemaId, CompiledSchema<Record<string, unknown>>>) => void, thisArg?: any): void {\n this.data.forEach(callbackfn, thisArg);\n }\n\n [Symbol.iterator](): IterableIterator<[SchemaId, CompiledSchema<Record<string, unknown>>]> {\n return this.data[Symbol.iterator]();\n }\n\n getByName<T>(collectionName: string): CompiledSchema<T> | undefined {\n const found = [...this.data].find(x => x[1].collectionName === collectionName);\n\n if (found != null) {\n return found[1] as CompiledSchema<T>;\n }\n\n return undefined;\n }\n}","import { CompiledSchema, SchemaId } from \"../schema\";\nimport { ReadonlySchemaCollection } from \"./ReadonlySchemaCollection\";\n\n/**\n * Collection of schemas with generic typing for type-safe schema retrieval\n */\nexport class SchemaCollection extends ReadonlySchemaCollection {\n\n set<T>(schemaId: SchemaId, schema: CompiledSchema<T>): this {\n this.data.set(schemaId, schema as CompiledSchema<Record<string, unknown>>);\n return this;\n }\n\n delete(schemaId: SchemaId): boolean {\n return this.data.delete(schemaId);\n }\n\n clear(): void {\n this.data.clear();\n }\n}","export class TagCollection implements Disposable {\n\n private data: Map<object, unknown> = new Map<object, unknown>();\n\n // Delegated to the map rather than tracked in a counter field: every mutation path\n // (set, setMany, combine, delete, dispose) would otherwise have to maintain it, and\n // a missed path silently reports a size that disagrees with the contents.\n get size() {\n return this.data.size;\n }\n\n get(key: object) {\n return this.data.get(key);\n }\n\n has(key: object) {\n return this.data.has(key);\n }\n\n set(key: object, tag: unknown) {\n return this.data.set(key, tag);\n }\n\n delete(key: object) {\n return this.data.delete(key);\n }\n\n setMany(keys: object[], tag: unknown) {\n for (let i = 0, length = keys.length; i < length; i++) {\n const key = keys[i];\n this.set(key, tag);\n }\n }\n\n combine(tags: TagCollection) {\n for (const [key, value] of tags) {\n this.set(key, value);\n }\n }\n\n values() {\n return this.data.values();\n }\n\n keys() {\n return this.data.keys();\n }\n\n [Symbol.dispose]() {\n this.data.clear();\n }\n\n [Symbol.iterator]() {\n return this.data[Symbol.iterator]();\n }\n}","import { IdType } from \"../schema\";\n\n/**\n * A save was rejected because another writer changed one of its rows first.\n *\n * Raised when a schema declares a `.concurrency()` token and an update's expected token\n * no longer matches the stored row. The whole save is rolled back — nothing was applied.\n * The caller's recovery is always the same: re-read the conflicted rows (the re-read\n * merges fresh values into the canonical instances), reapply the intent, and save again.\n */\nexport class OptimisticConcurrencyError extends Error {\n\n /** The collection whose rows conflicted. */\n readonly collectionName: string;\n /** Ids of the rows whose stored token no longer matched the writer's read. */\n readonly conflicts: IdType[];\n\n constructor(collectionName: string, conflicts: IdType[]) {\n super(\n `Optimistic concurrency conflict on '${collectionName}': ${conflicts.length} row(s) were changed by another writer after they were read. ` +\n `Nothing was saved. Re-read the rows, reapply the changes, and save again. Conflicted ids: ${conflicts.map(String).join(\", \")}`\n );\n this.name = \"OptimisticConcurrencyError\";\n this.collectionName = collectionName;\n this.conflicts = conflicts;\n }\n\n /** Type guard that survives errors crossing realm/serialization boundaries. */\n static is(error: unknown): error is OptimisticConcurrencyError {\n return error instanceof OptimisticConcurrencyError\n || (error != null && typeof error === \"object\" && (error as Error).name === \"OptimisticConcurrencyError\");\n }\n}\n","/**\n * A write that was accepted but never reached the database, because the plugin holding it was\n * destroyed first — or one submitted after the destroy.\n *\n * Distinct from a backend failure on purpose: nothing was attempted, so a caller that retries\n * on transient errors must not retry this one. There is no database left to retry against.\n */\nexport class PluginDestroyedError extends Error {\n\n constructor(reason: string) {\n super(`The plugin was destroyed: ${reason}`);\n this.name = \"PluginDestroyedError\";\n }\n}\n","import { isComparatorExpression, isOperatorExpression, isPropertyExpression, isValueExpression } from \"../assertions\";\nimport { UnknownRecord } from \"../utilities\";\nimport { Comparator, Expression, Transformer } from \"./types\";\n\n/**\n * Runs a parsed expression against a row.\n *\n * The counterpart to `toSql` and `toMql`: those turn a tree into a backend's language, and this\n * turns it into an answer. Needed wherever a tree exists but the closure that produced it does\n * not — a filter split out of a larger predicate, an option rebuilt from a serialized query.\n *\n * ## It fails OPEN, and that is the whole safety argument\n *\n * `undefined` means \"this tree cannot be evaluated here\" — an unknown node, a transformer with no\n * implementation, a comparison between shapes that do not compare. Callers must read that as KEEP\n * THE ROW, never as exclude it.\n *\n * The reason is asymmetric cost. Every caller today uses this to NARROW something that a\n * subsequent, authoritative predicate will check again: a semi-join prefilter, a split conjunct.\n * Keeping a row this cannot judge costs one wasted comparison downstream. Dropping one loses data\n * from a query result and nothing anywhere reports it. So every uncertain path returns `undefined`,\n * and no path guesses `false`.\n *\n * ## Why not just reuse the caller's closure\n *\n * Because there often isn't one. A conjunct pulled out of `([p, m]) => p.a === 1 && m.b === 2` is\n * source TEXT; turning it back into a callable needs `new Function`, which a\n * Content-Security-Policy blocks — the same constraint that makes `softDeleteScope` build its tree\n * by hand. The tree is the only representation that survives.\n */\nexport type EvaluationResult = boolean | undefined;\n\n/** Reads a property or literal operand, or `UNRESOLVED` when the node is not one. */\nconst UNRESOLVED = Symbol(\"unresolved\");\n\nconst applyTransformer = (value: unknown, transformer: Transformer | null): unknown | typeof UNRESOLVED => {\n if (transformer == null) {\n return value;\n }\n\n // A transformer applied to an absent value has no answer, and inventing one (\"\" for a missing\n // string) is how a filter starts matching rows it should not.\n if (value == null) {\n return UNRESOLVED;\n }\n\n if (transformer === \"to-lower-case\") {\n return typeof value === \"string\" ? value.toLowerCase() : UNRESOLVED;\n }\n\n if (transformer === \"to-upper-case\") {\n return typeof value === \"string\" ? value.toUpperCase() : UNRESOLVED;\n }\n\n if (transformer === \"length\") {\n return typeof value === \"string\" || Array.isArray(value) ? value.length : UNRESOLVED;\n }\n\n return UNRESOLVED;\n};\n\nconst operand = (expression: Expression | undefined, row: UnknownRecord): unknown | typeof UNRESOLVED => {\n if (expression == null) {\n return UNRESOLVED;\n }\n\n if (isValueExpression(expression)) {\n return applyTransformer(expression.value, expression.transformer);\n }\n\n if (isPropertyExpression(expression)) {\n // Through the PropertyInfo, so a nested path and a `from`-renamed segment resolve the same\n // way every other consumer of the tree resolves them.\n return applyTransformer(expression.property.getValue(row), expression.transformer);\n }\n\n return UNRESOLVED;\n};\n\n/**\n * `a === b` for the comparators, with Dates compared by VALUE.\n *\n * A Date compares by reference under `===`, so two Dates holding the same instant would be\n * unequal — which is not what a filter on a date means, and not what any backend does.\n */\nconst equals = (left: unknown, right: unknown, strict: boolean): boolean => {\n if (left instanceof Date && right instanceof Date) {\n return left.getTime() === right.getTime();\n }\n\n // oxlint-disable-next-line eqeqeq\n return strict ? left === right : left == right;\n};\n\n/** Ordered comparison, only for shapes that have an order. */\nconst compare = (left: unknown, right: unknown, comparator: Comparator): EvaluationResult => {\n const asComparable = (value: unknown) => value instanceof Date ? value.getTime() : value;\n\n const a = asComparable(left);\n const b = asComparable(right);\n\n const comparable = (typeof a === \"number\" && typeof b === \"number\")\n || (typeof a === \"string\" && typeof b === \"string\");\n\n if (comparable === false) {\n return undefined;\n }\n\n if (comparator === \"greater-than\") {\n return a > b;\n }\n\n if (comparator === \"greater-than-equals\") {\n return a >= b;\n }\n\n if (comparator === \"less-than\") {\n return a < b;\n }\n\n return a <= b;\n};\n\nconst evaluateComparator = (comparator: Comparator, left: unknown, right: unknown, strict: boolean): EvaluationResult => {\n\n if (comparator === \"equals\") {\n return equals(left, right, strict);\n }\n\n if (comparator === \"includes\") {\n // Two shapes, and the tree does not distinguish them: `array.includes(value)` and\n // `string.includes(substring)`. Whichever side is the container decides.\n if (Array.isArray(left)) {\n return left.some(item => equals(item, right, strict));\n }\n\n if (Array.isArray(right)) {\n return right.some(item => equals(item, left, strict));\n }\n\n return typeof left === \"string\" && typeof right === \"string\" ? left.includes(right) : undefined;\n }\n\n if (comparator === \"starts-with\") {\n return typeof left === \"string\" && typeof right === \"string\" ? left.startsWith(right) : undefined;\n }\n\n if (comparator === \"ends-with\") {\n return typeof left === \"string\" && typeof right === \"string\" ? left.endsWith(right) : undefined;\n }\n\n return compare(left, right, comparator);\n};\n\n/**\n * Evaluates `expression` against `row`, or returns `undefined` when it cannot.\n *\n * See the note at the top of this file: `undefined` means KEEP the row.\n */\nexport const evaluate = (expression: Expression, row: UnknownRecord): EvaluationResult => {\n\n if (isOperatorExpression(expression)) {\n const left = expression.left == null ? undefined : evaluate(expression.left, row);\n const right = expression.right == null ? undefined : evaluate(expression.right, row);\n\n /**\n * One unevaluable side does not have to sink the whole tree.\n *\n * `a && b` where `a` is definitely false is false whatever `b` is, and `a || b` where `a`\n * is definitely true is true. That short-circuiting is what lets a mostly-understood\n * predicate still narrow anything at all — without it, one unfamiliar sub-expression makes\n * the entire filter a no-op.\n */\n if (expression.operator === \"&&\") {\n if (left === false || right === false) {\n return false;\n }\n\n return left === true && right === true ? true : undefined;\n }\n\n if (left === true || right === true) {\n return true;\n }\n\n return left === false && right === false ? false : undefined;\n }\n\n if (isComparatorExpression(expression)) {\n const left = operand(expression.left, row);\n const right = operand(expression.right, row);\n\n if (left === UNRESOLVED || right === UNRESOLVED) {\n return undefined;\n }\n\n const result = evaluateComparator(expression.comparator, left, right, expression.strict);\n\n if (result === undefined) {\n return undefined;\n }\n\n return expression.negated ? result === false : result;\n }\n\n // A tautology excludes nothing, which is exactly `true`. Anything else — a bare property, a\n // literal, `not-parsable` — is not a predicate this can judge.\n return expression.type === \"empty\" ? true : undefined;\n};\n\n/**\n * `evaluate`, as a predicate that keeps whatever it cannot judge.\n *\n * The form every narrowing caller wants, with the fail-open rule applied once here rather than\n * remembered at each call site.\n */\nexport const toPredicate = (expression: Expression) => (row: UnknownRecord): boolean =>\n evaluate(expression, row) !== false;\n\n/**\n * `evaluate`, as a predicate that THROWS on anything it cannot judge.\n *\n * The opposite default to `toPredicate`, and the right one when the predicate is the only thing\n * standing between a caller and rows they asked to exclude — a filter that arrived over a wire and\n * is being applied by the receiver. Failing open there does not cost a wasted comparison; it returns\n * data the requester filtered out, and reports nothing.\n *\n * Use `toPredicate` when something authoritative re-checks the result, and this when nothing does.\n */\nexport const toStrictPredicate = (expression: Expression) => (row: UnknownRecord): boolean => {\n const result = evaluate(expression, row);\n\n if (result === undefined) {\n throw new Error(\n \"Cannot apply this filter: its expression cannot be evaluated in memory, and applying it partially would \" +\n \"return rows the filter excludes. This happens when a filter arrives without a runnable predicate — over a \" +\n \"wire, or rebuilt from a serialized query — and names something the evaluator does not understand.\"\n );\n }\n\n return result;\n};\n","import { logger } from \"../utilities\";\nimport { assertString } from \"../assertions\";\nimport { CompiledSchema, PropertyInfo, SchemaTypes } from \"../schema\";\nimport { Expression, OperatorExpression, ComparatorExpression, ValueExpression, PropertyExpression, Filter, ParamsFilter, Comparator, Transformer } from \"./types\";\n\n// Error message constants\nconst ERROR_MESSAGES = {\n PROPERTY_NOT_FOUND: (path: string) => `Error parsing query, could not find PropertyInfo for path: ${path}`,\n PARAM_PATH_NOT_FOUND: (value: string, params: unknown) => `Cannot find path in params for .where(). Make sure parameters are not used inline.\\r\\nPath: ${value}, Params: ${JSON.stringify(params)}`,\n VARIABLE_VALUE: (value: string) => `Cannot derive value from variable, please pass parameters into the expression.\n\nExample: .where(([x, params]) => x.id === params.id, { id: someVar.id })\nIssue At: ${value}`,\n UNSUPPORTED: (value: string) => `Unsupported expression format: ${value}`\n};\n\nconst parseUnknown = (value: unknown) => {\n assertString(value);\n return JSON.parse(value);\n}\n\n/**\n * A parse failure caused by the params VALUES rather than the filter source.\n * These must never poison the template cache — the same source can succeed\n * with different params.\n */\nclass ParamDependentParseError extends Error { }\n\nconst converters: Record<SchemaTypes, (value: unknown) => unknown> = {\n Array: v => v,\n Boolean: v => v == null ? v : Boolean(v),\n // Stryker disable next-line ArrowFunction: filters on computed properties route to\n // in-memory execution, so this entry cannot be reached through a parsable filter.\n Computed: v => v,\n Date: v => v,\n // A file is a reference, and a filter can legitimately compare its fields — content type\n // and size are ordinary columns. The value passes through unconverted like an object.\n File: v => v,\n // Stryker disable next-line ArrowFunction: SchemaTypes.Definition is handled as a\n // generic primitive everywhere (specs/known-defects.md) and never pairs in a filter.\n Definition: v => v,\n // Stryker disable next-line ArrowFunction: filters on function properties route to\n // in-memory execution, so this entry cannot be reached through a parsable filter.\n Function: v => v,\n Number: v => v == null ? v : Number(v),\n Object: v => v,\n String: v => v == null ? v : String(v),\n // A vector is a list of numbers and passes through like any other array. Nothing\n // converts it because nothing compares it: similarity is `.nearest()`, not a filter.\n Vector: v => v\n};\n\n// #region Tokenizer\n\ntype TokenKind = \"identifier\" | \"string\" | \"number\" | \"punctuation\";\n\ntype Token = {\n kind: TokenKind;\n value: string;\n}\n\n// Longest first so multi-character punctuation wins over its prefixes\nconst MULTI_CHARACTER_PUNCTUATION = [\"===\", \"!==\", \"?.\", \"&&\", \"||\", \"==\", \"!=\", \">=\", \"<=\", \"=>\"] as const;\n// Stryker disable next-line all: documented equivalent cluster (see\n// docs/mutation-backlog.md) — dropping an entry only affects source the parser rejects\n// either way, and the rejection message names the character from the source rather than\n// from this set, so no observable boundary distinguishes the mutant. Established\n// experimentally: 30 message-asserting tests killed 1 of 12.\nconst SINGLE_CHARACTER_PUNCTUATION = new Set([\"(\", \")\", \"[\", \"]\", \"{\", \"}\", \".\", \",\", \";\", \"!\", \">\", \"<\", \"-\", \"+\", \"*\", \"/\", \"%\", \"=\", \"?\", \":\", \"&\", \"|\"]);\n\nconst STRING_ESCAPES: Record<string, string> = {\n \"n\": \"\\n\",\n \"r\": \"\\r\",\n \"t\": \"\\t\",\n \"b\": \"\\b\",\n \"f\": \"\\f\",\n \"v\": \"\\v\",\n \"0\": \"\\0\"\n};\n\nconst isIdentifierStart = (char: string) => /[a-zA-Z_$]/.test(char);\nconst isIdentifierPart = (char: string) => /[a-zA-Z0-9_$]/.test(char);\nconst isDigit = (char: string) => char >= \"0\" && char <= \"9\";\nconst isHexDigit = (char: string) => isDigit(char) || (char >= \"a\" && char <= \"f\") || (char >= \"A\" && char <= \"F\");\n\n/**\n * Decodes a `\\uXXXX`, `\\u{...}` or `\\xXX` escape starting at the backslash.\n * Returns the decoded character and the index just past the escape. These\n * escapes carry a computed character, so mapping them through STRING_ESCAPES\n * (which would yield the literal \"u\"/\"x\") silently corrupts the value.\n */\nconst decodeCodeEscape = (source: string, backslashIndex: number): { value: string, nextIndex: number } => {\n const kind = source[backslashIndex + 1];\n let start = backslashIndex + 2;\n\n if (kind === \"u\" && source[start] === \"{\") {\n const end = source.indexOf(\"}\", start + 1);\n\n if (end === -1) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"unterminated unicode escape\"));\n }\n\n return { value: String.fromCodePoint(parseInt(source.slice(start + 1, end), 16)), nextIndex: end + 1 };\n }\n\n const length = kind === \"u\" ? 4 : 2;\n const digits = source.slice(start, start + length);\n\n if (digits.length < length || [...digits].some(d => !isHexDigit(d))) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`'\\\\${kind}' escape`));\n }\n\n return { value: String.fromCharCode(parseInt(digits, 16)), nextIndex: start + length };\n}\n\n/**\n * Converts filter source text into a flat token stream. Strings and comments are\n * consumed here so operator characters inside literals can never be mistaken for\n * real operators.\n */\nconst tokenize = (source: string): Token[] => {\n\n const tokens: Token[] = [];\n let i = 0;\n\n while (i < source.length) {\n const char = source[i];\n\n // Whitespace\n if (char === \" \" || char === \"\\t\" || char === \"\\r\" || char === \"\\n\") {\n i++;\n continue;\n }\n\n // Comments\n if (char === \"/\" && source[i + 1] === \"/\") {\n while (i < source.length && source[i] !== \"\\n\") {\n i++;\n }\n continue;\n }\n\n if (char === \"/\" && source[i + 1] === \"*\") {\n i += 2;\n while (i < source.length && !(source[i] === \"*\" && source[i + 1] === \"/\")) {\n i++;\n }\n i += 2;\n continue;\n }\n\n // String literals\n if (char === \"'\" || char === \"\\\"\" || char === \"`\") {\n const quote = char;\n let value = \"\";\n i++;\n\n while (i < source.length && source[i] !== quote) {\n if (source[i] === \"\\\\\") {\n const escaped = source[i + 1];\n\n if (escaped === \"u\" || escaped === \"x\") {\n const decoded = decodeCodeEscape(source, i);\n value += decoded.value;\n i = decoded.nextIndex;\n continue;\n }\n\n value += STRING_ESCAPES[escaped] ?? escaped;\n i += 2;\n continue;\n }\n\n if (quote === \"`\" && source[i] === \"$\" && source[i + 1] === \"{\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"template literal interpolation\"));\n }\n\n value += source[i];\n i++;\n }\n\n if (i >= source.length) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"unterminated string literal\"));\n }\n\n i++; // consume closing quote\n tokens.push({ kind: \"string\", value });\n continue;\n }\n\n // Numbers — covers decimals, exponents (1e6), hex/octal/binary (0xFF),\n // and numeric separators (1_000_000). Values are normalized here (the\n // separator stripped) so the parser can hand them straight to Number()\n if (isDigit(char)) {\n let value = \"\";\n\n const nextChar = source[i + 1];\n const radixPrefix = char === \"0\" && nextChar != null && \"xXoObB\".includes(nextChar);\n\n if (radixPrefix) {\n value = source[i] + source[i + 1];\n i += 2;\n\n while (i < source.length && (isHexDigit(source[i]) || source[i] === \"_\")) {\n value += source[i];\n i++;\n }\n } else {\n while (i < source.length && (isDigit(source[i]) || source[i] === \".\" || source[i] === \"_\")) {\n value += source[i];\n i++;\n }\n\n // Exponent part: e/E, optional sign, then digits. Only consumed when\n // digits follow, so a stray identifier after a number still errors\n if ((source[i] === \"e\" || source[i] === \"E\")) {\n const signLength = source[i + 1] === \"+\" || source[i + 1] === \"-\" ? 1 : 0;\n\n if (isDigit(source[i + 1 + signLength])) {\n value += source[i];\n i++;\n\n if (signLength === 1) {\n value += source[i];\n i++;\n }\n\n while (i < source.length && isDigit(source[i])) {\n value += source[i];\n i++;\n }\n }\n }\n }\n\n tokens.push({ kind: \"number\", value: value.replace(/_/g, \"\") });\n continue;\n }\n\n // Identifiers / keywords\n if (isIdentifierStart(char)) {\n let value = \"\";\n\n while (i < source.length && isIdentifierPart(source[i])) {\n value += source[i];\n i++;\n }\n\n tokens.push({ kind: \"identifier\", value });\n continue;\n }\n\n // Multi-character punctuation (longest match first)\n const multi = MULTI_CHARACTER_PUNCTUATION.find(w => source.startsWith(w, i));\n\n if (multi != null) {\n tokens.push({ kind: \"punctuation\", value: multi });\n i += multi.length;\n continue;\n }\n\n if (SINGLE_CHARACTER_PUNCTUATION.has(char)) {\n tokens.push({ kind: \"punctuation\", value: char });\n i++;\n continue;\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`unexpected character '${char}'`));\n }\n\n return tokens;\n}\n\n/**\n * Cursor over the token stream with the small set of lookahead operations the\n * parser needs.\n */\nclass TokenStream {\n\n private readonly tokens: Token[];\n private index: number = 0;\n\n constructor(tokens: Token[]) {\n this.tokens = tokens;\n }\n\n get isAtEnd() {\n return this.index >= this.tokens.length;\n }\n\n peek(offset: number = 0): Token | null {\n return this.tokens[this.index + offset] ?? null;\n }\n\n next(): Token {\n const token = this.tokens[this.index];\n\n if (token == null) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"unexpected end of expression\"));\n }\n\n this.index++;\n return token;\n }\n\n isPunctuation(value: string, offset: number = 0): boolean {\n const token = this.peek(offset);\n return token != null && token.kind === \"punctuation\" && token.value === value;\n }\n\n matchPunctuation(value: string): boolean {\n if (this.isPunctuation(value)) {\n this.index++;\n return true;\n }\n\n return false;\n }\n\n expectPunctuation(value: string) {\n if (!this.matchPunctuation(value)) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`expected '${value}'`));\n }\n }\n}\n\n// #endregion\n\n// #region Operands\n\n// Discriminated union so a condition builder can only ever see the operand\n// shapes the grammar allows\ntype PropertyOperand = {\n kind: \"property\";\n property: PropertyInfo<any>;\n transformer: Transformer | null;\n locale: string | null;\n}\n\ntype ValueOperand = {\n kind: \"value\";\n value: unknown;\n transformer: Transformer | null;\n locale: string | null;\n}\n\ntype ParamOperand = {\n kind: \"param\";\n path: string[];\n transformer: Transformer | null;\n locale: string | null;\n}\n\ntype MethodCallOperand = {\n kind: \"method-call\";\n target: PropertyOperand | ParamOperand | ValueOperand;\n method: \"startsWith\" | \"endsWith\" | \"includes\";\n argument: PropertyOperand | ValueOperand | ParamOperand;\n}\n\ntype Operand = PropertyOperand | ValueOperand | ParamOperand | MethodCallOperand;\n\nconst COMPARATOR_METHODS: Record<string, Comparator> = {\n startsWith: \"starts-with\",\n endsWith: \"ends-with\",\n includes: \"includes\"\n};\n\nconst TRANSFORM_METHODS: Record<string, { transformer: Transformer, locale: string | null }> = {\n toLowerCase: { transformer: \"to-lower-case\", locale: null },\n toUpperCase: { transformer: \"to-upper-case\", locale: null },\n toLocaleLowerCase: { transformer: \"to-lower-case\", locale: \"en-US\" },\n toLocaleUpperCase: { transformer: \"to-upper-case\", locale: \"en-US\" }\n};\n\nconst COMPARISON_OPERATORS: Record<string, { comparator: Comparator, negated: boolean, strict: boolean }> = {\n \"==\": { comparator: \"equals\", negated: false, strict: false },\n \"===\": { comparator: \"equals\", negated: false, strict: true },\n \"!=\": { comparator: \"equals\", negated: true, strict: false },\n \"!==\": { comparator: \"equals\", negated: true, strict: true },\n \">\": { comparator: \"greater-than\", negated: false, strict: false },\n \">=\": { comparator: \"greater-than-equals\", negated: false, strict: false },\n \"<\": { comparator: \"less-than\", negated: false, strict: false },\n \"<=\": { comparator: \"less-than-equals\", negated: false, strict: false }\n};\n\nconst SWAPPED_COMPARATORS: Record<Comparator, Comparator> = {\n \"equals\": \"equals\",\n \"greater-than\": \"less-than\",\n \"greater-than-equals\": \"less-than-equals\",\n \"less-than\": \"greater-than\",\n \"less-than-equals\": \"greater-than-equals\",\n \"starts-with\": \"starts-with\",\n \"ends-with\": \"ends-with\",\n \"includes\": \"includes\"\n};\n\n// #endregion\n\n// #region Param references\n\n/**\n * Placeholder for a parameter value inside a cached expression template. Never\n * escapes this module — binding replaces it with a plain ValueExpression that\n * holds the resolved value.\n */\nclass ParamReferenceExpression extends ValueExpression {\n\n /** Path into the params object, excluding the params root name. */\n readonly paramPath: string[];\n /** The property this value is compared against; drives serialization/conversion at bind time. */\n readonly pairedProperty: PropertyInfo<any> | null;\n /** Whether the paired property's type converter applies (equality/relational comparisons only). */\n readonly applyConverter: boolean;\n\n constructor(options: {\n paramPath: string[],\n pairedProperty: PropertyInfo<any> | null,\n applyConverter: boolean\n }) {\n super({ value: undefined });\n this.paramPath = options.paramPath;\n this.pairedProperty = options.pairedProperty;\n this.applyConverter = options.applyConverter;\n }\n}\n\nconst resolveParamPath = (paramsName: string, path: string[], data: unknown) => {\n\n let result = data as Record<string, unknown>;\n\n for (let i = 0; i < path.length; i++) {\n const name = path[i];\n\n if (result != null && typeof result === \"object\" && name in result) {\n result = result[name] as Record<string, unknown>;\n continue;\n }\n\n throw new ParamDependentParseError(ERROR_MESSAGES.PARAM_PATH_NOT_FOUND([paramsName, ...path].join(\".\"), data));\n }\n\n return result as unknown;\n}\n\n/**\n * Applies the paired property's value serializer and (optionally) its schema\n * type converter, matching how literal values are treated at parse time.\n */\nconst resolvePairedValue = (value: unknown, pairedProperty: PropertyInfo<any> | null, applyConverter: boolean) => {\n\n if (pairedProperty == null) {\n return value;\n }\n\n let result = value;\n\n if (pairedProperty.valueSerializer != null) {\n result = String(pairedProperty.valueSerializer(parseUnknown(result)));\n }\n\n if (applyConverter) {\n result = converters[pairedProperty.type](result);\n }\n\n return result;\n}\n\n// #endregion\n\n// #region Parser\n\n/**\n * Recursive descent parser over the token stream. Produces an expression\n * template: literal values are fully resolved, parameter values are represented\n * as ParamReferenceExpression placeholders so the template can be cached and\n * re-bound with different params.\n */\nclass ExpressionParser {\n\n private readonly schema: CompiledSchema<any>;\n private readonly stream: TokenStream;\n private readonly entityName: string;\n private readonly paramsName: string | null;\n private readonly params: unknown;\n\n /** Set when a param value shaped the tree itself (e.g. x[p.name]) — such templates cannot be cached. */\n structurallyDependsOnParams: boolean = false;\n\n constructor(schema: CompiledSchema<any>, stream: TokenStream, entityName: string, paramsName: string | null, params: unknown) {\n this.schema = schema;\n this.stream = stream;\n this.entityName = entityName;\n this.paramsName = paramsName;\n this.params = params;\n }\n\n parse(): Expression {\n const expression = this.parseOr();\n\n if (!this.stream.isAtEnd) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`unexpected token '${this.stream.peek()?.value}'`));\n }\n\n return expression;\n }\n\n // || binds loosest, so it sits at the root of the parse\n private parseOr(): Expression {\n let left = this.parseAnd();\n\n while (this.stream.matchPunctuation(\"||\")) {\n const right = this.parseAnd();\n\n // A tautology (`true`) absorbs the whole disjunction\n if (Expression.isEmpty(left) || Expression.isEmpty(right)) {\n left = Expression.EMPTY;\n continue;\n }\n\n left = new OperatorExpression({ operator: \"||\", left, right });\n }\n\n return left;\n }\n\n private parseAnd(): Expression {\n let left = this.parseUnary();\n\n while (this.stream.matchPunctuation(\"&&\")) {\n const right = this.parseUnary();\n\n // A tautology (`true`) is the identity of a conjunction\n if (Expression.isEmpty(left)) {\n left = right;\n continue;\n }\n\n if (Expression.isEmpty(right)) {\n continue;\n }\n\n left = new OperatorExpression({ operator: \"&&\", left, right });\n }\n\n return left;\n }\n\n private parseUnary(): Expression {\n if (this.stream.matchPunctuation(\"!\")) {\n return this.negateExpression(this.parseUnary());\n }\n\n return this.parseComparison();\n }\n\n /**\n * Applies `!` to an already-parsed expression: comparators flip their\n * negated flag, compound expressions distribute via De Morgan's laws.\n */\n private negateExpression(expression: Expression): Expression {\n if (expression instanceof ComparatorExpression) {\n expression.negated = !expression.negated;\n return expression;\n }\n\n if (expression instanceof OperatorExpression && expression.left != null && expression.right != null) {\n return new OperatorExpression({\n operator: expression.operator === \"&&\" ? \"||\" : \"&&\",\n left: this.negateExpression(expression.left),\n right: this.negateExpression(expression.right)\n });\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"'!' on this expression\"));\n }\n\n private parseComparison(): Expression {\n\n // Parenthesized group\n if (this.stream.matchPunctuation(\"(\")) {\n const expression = this.parseOr();\n this.stream.expectPunctuation(\")\");\n\n const trailing = this.stream.peek();\n if (trailing != null && trailing.kind === \"punctuation\" && COMPARISON_OPERATORS[trailing.value] != null) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"comparison against a parenthesized expression\"));\n }\n\n return expression;\n }\n\n const left = this.parseOperand();\n const operatorToken = this.stream.peek();\n\n if (operatorToken != null && operatorToken.kind === \"punctuation\" && COMPARISON_OPERATORS[operatorToken.value] != null) {\n this.stream.next();\n const right = this.parseOperand();\n return this.buildComparison(left, COMPARISON_OPERATORS[operatorToken.value], right);\n }\n\n return this.buildStandalone(left);\n }\n\n private parseOperand(): Operand {\n const token = this.stream.peek();\n\n if (token == null) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"unexpected end of expression\"));\n }\n\n if (token.kind === \"string\") {\n this.stream.next();\n return this.withValueTransformer({ kind: \"value\", value: token.value, transformer: null, locale: null });\n }\n\n if (token.kind === \"number\") {\n this.stream.next();\n return { kind: \"value\", value: Number(token.value), transformer: null, locale: null };\n }\n\n if (token.kind === \"punctuation\" && token.value === \"-\") {\n this.stream.next();\n const numberToken = this.stream.next();\n\n if (numberToken.kind !== \"number\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"unary '-' on a non-number\"));\n }\n\n return { kind: \"value\", value: -Number(numberToken.value), transformer: null, locale: null };\n }\n\n if (token.kind === \"punctuation\" && token.value === \"[\") {\n return this.parseArrayLiteralOperand();\n }\n\n if (token.kind === \"identifier\") {\n return this.parseIdentifierOperand();\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(String(token.value)));\n }\n\n /**\n * Parses an inline array of literals, e.g. `[\"active\", \"pending\"]`, and the\n * membership test that follows it: `[...].includes(entity.property)`.\n */\n private parseArrayLiteralOperand(): Operand {\n this.stream.expectPunctuation(\"[\");\n const elements: unknown[] = [];\n\n while (!this.stream.isPunctuation(\"]\")) {\n const element = this.parseOperand();\n\n if (element.kind !== \"value\" || element.transformer != null) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"a non-literal element in an array literal\"));\n }\n\n elements.push(element.value);\n\n if (!this.stream.matchPunctuation(\",\")) {\n break;\n }\n }\n\n this.stream.expectPunctuation(\"]\");\n\n const array: ValueOperand = { kind: \"value\", value: elements, transformer: null, locale: null };\n\n // The only supported use is a membership test on a schema property\n if (this.stream.isPunctuation(\".\") || this.stream.isPunctuation(\"?.\")) {\n this.stream.next();\n const method = this.stream.next();\n\n if (method.kind !== \"identifier\" || method.value !== \"includes\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`'.${method.value}' on an array literal`));\n }\n\n this.stream.expectPunctuation(\"(\");\n const argument = this.parseOperand();\n this.stream.expectPunctuation(\")\");\n\n if (argument.kind === \"method-call\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"nested method call inside .includes()\"));\n }\n\n return { kind: \"method-call\", target: array, method: \"includes\", argument };\n }\n\n return array;\n }\n\n private parseIdentifierOperand(): Operand {\n const root = this.stream.next().value;\n\n // Keyword literals\n if (root === \"true\" || root === \"false\") {\n return { kind: \"value\", value: root === \"true\", transformer: null, locale: null };\n }\n\n if (root === \"null\") {\n return { kind: \"value\", value: null, transformer: null, locale: null };\n }\n\n if (root === \"undefined\") {\n return { kind: \"value\", value: undefined, transformer: null, locale: null };\n }\n\n if (root === \"void\") {\n this.stream.next(); // the '0'\n return { kind: \"value\", value: undefined, transformer: null, locale: null };\n }\n\n if (root === this.entityName) {\n return this.parseChain({ kind: \"property\", root });\n }\n\n if (this.paramsName != null && root === this.paramsName) {\n return this.parseChain({ kind: \"param\", root });\n }\n\n // A bare variable from the outer scope — its value cannot be derived from source text\n throw new Error(ERROR_MESSAGES.VARIABLE_VALUE(root));\n }\n\n /**\n * Parses the segments after an entity/params root: dot access, bracket\n * access, transform methods and comparator methods.\n */\n private parseChain(options: { kind: \"property\" | \"param\", root: string }): Operand {\n const path: string[] = [];\n let transformer: Transformer | null = null;\n let locale: string | null = null;\n\n while (true) {\n if (this.stream.matchPunctuation(\".\") || this.stream.matchPunctuation(\"?.\")) {\n const segment = this.stream.next();\n\n if (segment.kind !== \"identifier\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`'.${segment.value}'`));\n }\n\n // Method call\n if (this.stream.isPunctuation(\"(\")) {\n const method = segment.value;\n\n if (TRANSFORM_METHODS[method] != null) {\n this.stream.expectPunctuation(\"(\");\n this.stream.expectPunctuation(\")\");\n transformer = TRANSFORM_METHODS[method].transformer;\n locale = TRANSFORM_METHODS[method].locale;\n continue;\n }\n\n if (COMPARATOR_METHODS[method] != null) {\n this.stream.expectPunctuation(\"(\");\n const argument = this.parseOperand();\n this.stream.expectPunctuation(\")\");\n\n if (argument.kind === \"method-call\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`nested method call inside .${method}()`));\n }\n\n return {\n kind: \"method-call\",\n target: this.resolveChain(options.kind, path, transformer, locale),\n method: method as MethodCallOperand[\"method\"],\n argument\n };\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`method '.${method}()'`));\n }\n\n if (transformer != null) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"property access after a transform method\"));\n }\n\n path.push(segment.value);\n continue;\n }\n\n if (this.stream.matchPunctuation(\"[\")) {\n path.push(this.parseBracketSegment(options.kind));\n this.stream.expectPunctuation(\"]\");\n continue;\n }\n\n break;\n }\n\n return this.resolveChain(options.kind, path, transformer, locale);\n }\n\n private parseBracketSegment(kind: \"property\" | \"param\"): string {\n const token = this.stream.next();\n\n // Literal segment: entity[\"name\"]\n if (token.kind === \"string\") {\n return token.value;\n }\n\n // Param-driven segment: entity[p.name] — the property depends on the\n // param VALUE, so the resulting template is tied to these params.\n // Stryker disable next-line all: documented equivalent cluster (see\n // docs/mutation-backlog.md) — every mutation of this four-conjunct guard reroutes\n // bracket access between two paths that both collapse to NOT_PARSABLE; the\n // experiment recorded there aimed 30 tests at this line and killed none.\n if (kind === \"property\" && token.kind === \"identifier\" && this.paramsName != null && token.value === this.paramsName) {\n const paramPath: string[] = [];\n\n while (this.stream.matchPunctuation(\".\") || this.stream.matchPunctuation(\"?.\")) {\n paramPath.push(this.stream.next().value);\n }\n\n const resolved = resolveParamPath(this.paramsName, paramPath, this.params);\n\n if (typeof resolved !== \"string\") {\n throw new ParamDependentParseError(ERROR_MESSAGES.PROPERTY_NOT_FOUND(paramPath.join(\".\")));\n }\n\n this.structurallyDependsOnParams = true;\n return resolved;\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`bracket access '[${token.value}]'`));\n }\n\n private resolveChain(kind: \"property\" | \"param\", path: string[], transformer: Transformer | null, locale: string | null): PropertyOperand | ParamOperand {\n\n if (kind === \"param\") {\n if (path.length === 0) {\n // `params` alone is a variable, not a value we can resolve\n throw new Error(ERROR_MESSAGES.PARAM_PATH_NOT_FOUND(this.paramsName ?? \"params\", this.params));\n }\n\n return { kind: \"param\", path, transformer, locale };\n }\n\n const pathString = path.join(\".\");\n const property = this.schema.properties.find(w => w.getAssignmentPath() == pathString);\n\n if (property == null) {\n // `.length` on a string/array property — a real schema property named\n // `length` wins (checked above); otherwise treat it as a transformer\n if (path.length > 1 && path[path.length - 1] === \"length\" && transformer == null) {\n const parentPath = path.slice(0, -1).join(\".\");\n const parent = this.schema.properties.find(w => w.getAssignmentPath() == parentPath);\n\n // Vector is deliberately absent. Its length is the dimension count declared\n // in the schema — a constant, not data — so a filter on it answers a question\n // nobody asks, and pushing it down would need `json_array_length` on a\n // backend storing JSON and something else entirely on one with a native\n // vector column. Not parsing it leaves a clear error instead of a dialect gap.\n if (parent != null && (parent.type === SchemaTypes.String || parent.type === SchemaTypes.Array)) {\n return { kind: \"property\", property: parent, transformer: \"length\", locale: null };\n }\n }\n\n throw new Error(ERROR_MESSAGES.PROPERTY_NOT_FOUND(pathString));\n }\n\n return { kind: \"property\", property, transformer, locale };\n }\n\n private withValueTransformer(operand: ValueOperand): ValueOperand {\n if (this.stream.isPunctuation(\".\")) {\n const method = this.stream.peek(1);\n\n // Stryker disable next-line all: documented equivalent cluster (see\n // docs/mutation-backlog.md) — the guard's conjuncts each route to a rejection that\n // collapses to NOT_PARSABLE with an indistinguishable message; 18 targeted tests\n // killed none of these.\n if (method != null && method.kind === \"identifier\" && TRANSFORM_METHODS[method.value] != null) {\n this.stream.next(); // .\n this.stream.next(); // method name\n this.stream.expectPunctuation(\"(\");\n this.stream.expectPunctuation(\")\");\n\n operand.transformer = TRANSFORM_METHODS[method.value].transformer;\n operand.locale = TRANSFORM_METHODS[method.value].locale;\n }\n }\n\n return operand;\n }\n\n // #region Condition building\n\n private buildComparison(left: Operand, operator: { comparator: Comparator, negated: boolean, strict: boolean }, right: Operand): Expression {\n\n // methodCall == true/false — fold the boolean into negation\n if (left.kind === \"method-call\") {\n if (operator.comparator === \"equals\" && right.kind === \"value\" && typeof right.value === \"boolean\") {\n const comparator = this.buildMethodComparator(left);\n const comparedToFalse = right.value === false;\n comparator.negated = comparator.negated !== (operator.negated !== comparedToFalse);\n return comparator;\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"comparing a method call to a non-boolean\"));\n }\n\n if (right.kind === \"method-call\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"method call on the right side of a comparison\"));\n }\n\n if (left.kind === \"property\" && right.kind === \"property\") {\n // Casing transformers are only valid with string-matching comparators,\n // which cannot produce a property-to-property comparison\n if (left.transformer === \"to-lower-case\" || left.transformer === \"to-upper-case\" ||\n right.transformer === \"to-lower-case\" || right.transformer === \"to-upper-case\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"transform method outside of startsWith/endsWith/includes\"));\n }\n\n return new ComparatorExpression({\n comparator: operator.comparator,\n negated: operator.negated,\n strict: operator.strict,\n left: this.createPropertyExpression(left),\n right: this.createPropertyExpression(right)\n });\n }\n\n if (left.kind === \"property\" && right.kind !== \"property\") {\n return this.buildPropertyComparator(left, operator, right, /* applyConverter */ true);\n }\n\n if (right.kind === \"property\" && left.kind !== \"property\") {\n const swapped = { ...operator, comparator: SWAPPED_COMPARATORS[operator.comparator] };\n return this.buildPropertyComparator(right, swapped, left, /* applyConverter */ true);\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"comparison requires a schema property on at least one side\"));\n }\n\n private buildStandalone(operand: Operand): Expression {\n\n if (operand.kind === \"method-call\") {\n return this.buildMethodComparator(operand);\n }\n\n if (operand.kind === \"property\") {\n // Truthy shorthand on `.length`: a length is truthy exactly when > 0\n if (operand.transformer === \"length\") {\n return this.buildPropertyComparator(operand, COMPARISON_OPERATORS[\">\"], { kind: \"value\", value: 0, transformer: null, locale: null }, /* applyConverter */ true);\n }\n\n // Truthy shorthand: `w.isActive` → isActive === true\n return this.buildPropertyComparator(operand, COMPARISON_OPERATORS[\"===\"], { kind: \"value\", value: true, transformer: null, locale: null }, /* applyConverter */ true);\n }\n\n // Constant `true` — a tautology, which parseAnd/parseOr simplify away\n if (operand.kind === \"value\" && operand.value === true && operand.transformer == null) {\n return Expression.EMPTY;\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"a filter condition must reference a schema property\"));\n }\n\n private buildMethodComparator(operand: MethodCallOperand): ComparatorExpression {\n const { target, method, argument } = operand;\n\n if (target.kind === \"property\") {\n if (argument.kind === \"property\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`.${method}() comparing two schema properties`));\n }\n\n // Method arguments skip type conversion — only the value serializer applies\n return this.buildPropertyComparator(target, { comparator: COMPARATOR_METHODS[method], negated: false, strict: false }, argument, /* applyConverter */ false);\n }\n\n // [\"a\", \"b\"].includes(x.prop) / params.list.includes(x.prop) —\n // membership test with the collection on the left\n if (method === \"includes\" && argument.kind === \"property\") {\n if (target.transformer != null) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"transform method on a collection used with .includes()\"));\n }\n\n return new ComparatorExpression({\n comparator: \"includes\",\n negated: false,\n strict: false,\n left: this.createValueExpression(target, argument.property, /* applyConverter */ false),\n right: this.createPropertyExpression(argument)\n });\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`.${method}() on a non-property target`));\n }\n\n private buildPropertyComparator(property: PropertyOperand, operator: { comparator: Comparator, negated: boolean, strict: boolean }, value: ValueOperand | ParamOperand, applyConverter: boolean): ComparatorExpression {\n\n const isStringMatch = operator.comparator === \"starts-with\" || operator.comparator === \"ends-with\" || operator.comparator === \"includes\";\n\n // `.length` compares a NUMBER, so the paired property's serializer and\n // type converter must not touch the value; and a length has no meaning\n // inside a string-matching comparator\n if (property.transformer === \"length\") {\n if (isStringMatch) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"'.length' with startsWith/endsWith/includes\"));\n }\n\n return new ComparatorExpression({\n comparator: operator.comparator,\n negated: operator.negated,\n strict: operator.strict,\n left: this.createPropertyExpression(property),\n right: this.createValueExpression(value, null, /* applyConverter */ false)\n });\n }\n\n // Casing transformers on a property are only meaningful with string-matching\n // comparators; on relational comparators the plugins would silently\n // ignore them and return wrong data\n if (property.transformer != null && !isStringMatch) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"transform method outside of startsWith/endsWith/includes\"));\n }\n\n return new ComparatorExpression({\n comparator: operator.comparator,\n negated: operator.negated,\n strict: operator.strict,\n left: this.createPropertyExpression(property),\n right: this.createValueExpression(value, property.property, applyConverter)\n });\n }\n\n private createPropertyExpression(operand: PropertyOperand): PropertyExpression {\n const expression = new PropertyExpression({ property: operand.property });\n expression.transformer = operand.transformer;\n expression.locale = operand.locale;\n return expression;\n }\n\n private createValueExpression(operand: ValueOperand | ParamOperand, pairedProperty: PropertyInfo<any> | null, applyConverter: boolean): ValueExpression {\n\n if (operand.kind === \"param\") {\n const expression = new ParamReferenceExpression({ paramPath: operand.path, pairedProperty, applyConverter });\n expression.transformer = operand.transformer;\n expression.locale = operand.locale;\n return expression;\n }\n\n const expression = new ValueExpression({ value: resolvePairedValue(operand.value, pairedProperty, applyConverter) });\n expression.transformer = operand.transformer;\n expression.locale = operand.locale;\n return expression;\n }\n\n // #endregion\n}\n\n// #endregion\n\n// #region Template binding\n\n/**\n * Deep-clones a template into a consumer-facing tree, resolving parameter\n * placeholders against the supplied params. Always clones so cached templates\n * can never be mutated by consumers.\n */\nconst bindExpression = (expression: Expression, paramsName: string | null, params: unknown): Expression => {\n\n if (expression instanceof ParamReferenceExpression) {\n const raw = resolveParamPath(paramsName ?? \"params\", expression.paramPath, params);\n const bound = new ValueExpression({ value: resolvePairedValue(raw, expression.pairedProperty, expression.applyConverter) });\n bound.transformer = expression.transformer;\n bound.locale = expression.locale;\n return bound;\n }\n\n if (expression instanceof ValueExpression) {\n const clone = new ValueExpression({ value: expression.value });\n clone.transformer = expression.transformer;\n clone.locale = expression.locale;\n return clone;\n }\n\n if (expression instanceof PropertyExpression) {\n const clone = new PropertyExpression({ property: expression.property });\n clone.transformer = expression.transformer;\n clone.locale = expression.locale;\n return clone;\n }\n\n if (expression instanceof ComparatorExpression) {\n return new ComparatorExpression({\n comparator: expression.comparator,\n negated: expression.negated,\n strict: expression.strict,\n left: expression.left ? bindExpression(expression.left, paramsName, params) : undefined,\n right: expression.right ? bindExpression(expression.right, paramsName, params) : undefined\n });\n }\n\n if (expression instanceof OperatorExpression) {\n return new OperatorExpression({\n operator: expression.operator,\n left: expression.left ? bindExpression(expression.left, paramsName, params) : undefined,\n right: expression.right ? bindExpression(expression.right, paramsName, params) : undefined\n });\n }\n\n return expression;\n}\n\n// #endregion\n\n// #region Function source handling\n\ntype FunctionShape = {\n entityName: string;\n paramsName: string | null;\n body: string;\n}\n\n/**\n * Splits stringified filter source into parameter names and the expression\n * body, unwrapping single-return block bodies.\n */\nconst resolveFunctionShape = (stringifiedFunction: string, hasParams: boolean): FunctionShape => {\n\n const source = stringifiedFunction.trim();\n\n let parameterNames: string;\n let body: string;\n\n // `function (x) { ... }` / `function name(x) { ... }` — what ES5-targeting\n // transpilers rewrite every arrow filter into\n const functionHead = /^function\\b[^(]*\\(/.exec(source);\n\n if (functionHead != null) {\n const parametersEnd = source.indexOf(\")\", functionHead[0].length);\n\n if (parametersEnd === -1) {\n throw new Error(\"Invalid Function\");\n }\n\n parameterNames = source.slice(functionHead[0].length, parametersEnd).trim();\n body = source.slice(parametersEnd + 1).trim();\n } else {\n const arrowIndex = source.indexOf(\"=>\");\n\n if (arrowIndex === -1) {\n throw new Error(\"Invalid Function\");\n }\n\n parameterNames = source.substring(0, arrowIndex).trim();\n body = source.substring(arrowIndex + 2).trim();\n\n // Strip wrapping parens: (entity) or ([x, p])\n if (parameterNames.startsWith(\"(\") && parameterNames.endsWith(\")\")) {\n parameterNames = parameterNames.slice(1, -1).trim();\n }\n }\n\n let entityName: string;\n let paramsName: string | null = null;\n\n if (parameterNames.startsWith(\"[\") && parameterNames.endsWith(\"]\")) {\n const destructured = parameterNames.slice(1, -1).split(\",\").map(w => w.trim());\n entityName = destructured[0];\n\n if (hasParams) {\n paramsName = destructured[1] ?? null;\n }\n } else {\n entityName = parameterNames;\n }\n\n if (entityName == null || entityName.length === 0) {\n throw new Error(\"Invalid Function\");\n }\n\n // Unwrap a single-return block body: { return <expression>; }\n if (body.startsWith(\"{\")) {\n const inner = body.slice(1, body.lastIndexOf(\"}\")).trim();\n\n if (!inner.startsWith(\"return\")) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"block body without a single return statement\"));\n }\n\n body = inner.slice(\"return\".length).trim();\n\n if (body.endsWith(\";\")) {\n body = body.slice(0, -1).trim();\n }\n }\n\n return { entityName, paramsName, body };\n}\n\n// #endregion\n\n// #region Cache\n\ntype ParsedTemplate = {\n template: Expression;\n paramsName: string | null;\n}\n\n// Keyed by schema instance so identical filter source on different schemas can\n// never collide; entries live only as long as the schema does\nconst templateCache = new WeakMap<CompiledSchema<any>, Map<string, ParsedTemplate>>();\nconst MAX_CACHED_TEMPLATES_PER_SCHEMA = 1024;\n\nconst getCachedTemplate = (schema: CompiledSchema<any>, source: string): ParsedTemplate | null => {\n return templateCache.get(schema)?.get(source) ?? null;\n}\n\nconst setCachedTemplate = (schema: CompiledSchema<any>, source: string, entry: ParsedTemplate) => {\n let bySource = templateCache.get(schema);\n\n if (bySource == null) {\n bySource = new Map<string, ParsedTemplate>();\n templateCache.set(schema, bySource);\n }\n\n // Filter source strings come from static code, so this cap should never be\n // hit in practice — it only guards against unbounded dynamic generation.\n // Stryker disable next-line all: the cap is a pure resource bound — every mutation of\n // it (never clear, always clear, off-by-one) parses identically and differs only in\n // memory growth, which no observable boundary can assert.\n if (bySource.size >= MAX_CACHED_TEMPLATES_PER_SCHEMA) {\n bySource.clear();\n }\n\n bySource.set(source, entry);\n}\n\n// #endregion\n\nexport const combineExpressions = (...expressions: Expression[]): Expression => {\n\n if (expressions.length === 0) {\n throw new Error(\"combineExpressions requires at least 1 expression\");\n }\n\n\n if (expressions.length === 1) {\n return expressions[0];\n }\n\n // Start with the first expression\n let result = expressions[0];\n\n // Loop through remaining expressions and combine them\n for (let i = 1; i < expressions.length; i++) {\n result = new OperatorExpression({\n operator: \"&&\",\n left: result,\n right: expressions[i]\n });\n }\n\n return result;\n};\n\n/**\n * Parses an expression SOURCE FRAGMENT against one schema and one root name.\n *\n * `toExpression` starts from a function and works out its own roots. This starts from text, which\n * is what a caller has when it has split a larger predicate apart — `p.rank > 10` lifted out of\n * `([p, m]) => p.rank > 10 && m.won === true`.\n *\n * **A fragment naming anything other than `rootName` returns `NOT_PARSABLE`, and that is the\n * point.** It is how a caller discovers which side of a join a conjunct belongs to: parse it\n * against each side in turn, and exactly one succeeds for a single-side condition. A condition\n * spanning both fails against both, which is the correct answer — it cannot be pushed to either.\n *\n * No params: a fragment carrying a params reference has no bag to resolve it against here, so it\n * fails rather than binding to nothing.\n *\n * Deliberately NOT cached. The cache is keyed by function source, and a fragment is not a function\n * — two different lambdas can contain the same fragment text against different schemas.\n */\nexport const parseFragment = (schema: CompiledSchema<any>, body: string, rootName: string): Expression => {\n try {\n const stream = new TokenStream(tokenize(body));\n const parser = new ExpressionParser(schema, stream, rootName, null, undefined);\n\n return parser.parse();\n } catch {\n // The failure is expected and informative — see above — so it is not logged. A caller that\n // parses one conjunct against two schemas would otherwise warn on every successful split.\n return Expression.NOT_PARSABLE;\n }\n};\n\nexport const toExpression = <T extends any, P extends any>(schema: CompiledSchema<any>, fn: Filter<T> | ParamsFilter<T, P>, params?: P) => {\n const stringifiedFunction = fn.toString();\n\n const warn = (error: unknown) => logger.warn(\"Error parsing expression\", {\n error,\n collectionName: schema.collectionName,\n params,\n selector: stringifiedFunction\n });\n\n const cached = getCachedTemplate(schema, stringifiedFunction);\n\n if (cached != null) {\n // A cached failure — the warning was already logged when it was discovered\n if (Expression.isNotParsable(cached.template)) {\n return Expression.NOT_PARSABLE;\n }\n\n try {\n return bindExpression(cached.template, cached.paramsName, params);\n } catch (error) {\n // Binding failures are param-dependent by nature — never cached\n warn(error);\n return Expression.NOT_PARSABLE;\n }\n }\n\n let paramsName: string | null = null;\n let template: Expression;\n let structurallyDependsOnParams: boolean;\n\n try {\n const shape = resolveFunctionShape(stringifiedFunction, params != null);\n const stream = new TokenStream(tokenize(shape.body));\n const parser = new ExpressionParser(schema, stream, shape.entityName, shape.paramsName, params);\n paramsName = shape.paramsName;\n template = parser.parse();\n structurallyDependsOnParams = parser.structurallyDependsOnParams;\n } catch (error) {\n // Cache the failure so a hot query on an unsupported filter doesn't\n // re-parse and re-warn on every execution. Param-dependent failures are\n // exempt: the same source can succeed with different params.\n if (!(error instanceof ParamDependentParseError)) {\n setCachedTemplate(schema, stringifiedFunction, { template: Expression.NOT_PARSABLE, paramsName: null });\n }\n\n warn(error);\n return Expression.NOT_PARSABLE;\n }\n\n // Templates whose structure was resolved from param values are only\n // valid for this exact params object — parse those fresh every time\n if (!structurallyDependsOnParams) {\n setCachedTemplate(schema, stringifiedFunction, { template, paramsName });\n }\n\n try {\n return bindExpression(template, paramsName, params);\n } catch (error) {\n warn(error);\n return Expression.NOT_PARSABLE;\n }\n}\n","import { QueryOptionExecutionTarget } from \"../plugins\";\nimport { CompiledSchemaCore, PropertyInfo } from \"../schema\";\n\n/**\n * JSON-safe form of a literal. Tagged only where JSON cannot carry the value as it is.\n *\n * See `Expression.toJson`.\n */\nexport type SerializedValue =\n | { k: \"raw\"; v: string | number | boolean | null }\n | { k: \"date\"; v: string }\n | { k: \"undefined\" }\n | { k: \"number\"; v: \"NaN\" | \"Infinity\" | \"-Infinity\" }\n | { k: \"array\"; v: SerializedValue[] };\n\n/** JSON-safe form of an expression tree. See `Expression.toJson`. */\nexport type SerializedExpression =\n | { t: \"empty\" }\n | { t: \"not-parsable\" }\n | { t: \"operator\"; operator: Operator; left?: SerializedExpression; right?: SerializedExpression }\n | {\n t: \"comparator\";\n comparator: Comparator;\n negated: boolean;\n strict: boolean;\n left?: SerializedExpression;\n right?: SerializedExpression;\n }\n | { t: \"property\"; path: string; transformer: Transformer | null; locale: string | null }\n | { t: \"value\"; value: SerializedValue; transformer: Transformer | null; locale: string | null };\n\nconst valueToJson = (value: unknown): SerializedValue => {\n if (value === undefined) {\n return { k: \"undefined\" };\n }\n\n if (value === null) {\n return { k: \"raw\", v: null };\n }\n\n if (value instanceof Date) {\n // ISO rather than epoch millis: it survives a human reading the payload, and an invalid\n // Date has no ISO form — so it is caught here rather than becoming a silent `null`.\n return { k: \"date\", v: value.toISOString() };\n }\n\n if (Array.isArray(value)) {\n return { k: \"array\", v: value.map(valueToJson) };\n }\n\n if (typeof value === \"number\" && Number.isFinite(value) === false) {\n // `JSON.stringify` turns all three of these into `null`, which would compare as a different\n // value entirely rather than failing.\n return { k: \"number\", v: Number.isNaN(value) ? \"NaN\" : value > 0 ? \"Infinity\" : \"-Infinity\" };\n }\n\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return { k: \"raw\", v: value };\n }\n\n throw new Error(\n `Cannot serialize this filter value: only strings, numbers, booleans, null, undefined, Dates and arrays of those can cross a wire. ` +\n `Received: ${Object.prototype.toString.call(value)}`\n );\n};\n\nconst valueFromJson = (value: SerializedValue): unknown => {\n if (value.k === \"undefined\") {\n return undefined;\n }\n\n if (value.k === \"date\") {\n return new Date(value.v);\n }\n\n if (value.k === \"array\") {\n return value.v.map(valueFromJson);\n }\n\n if (value.k === \"number\") {\n return value.v === \"NaN\" ? Number.NaN : value.v === \"Infinity\" ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\n }\n\n return value.v;\n};\n\nexport type ParsedExpression = {\n expression: Expression;\n // Will be memory when trying to query on an untracked computed property or on a function\n executionTarget: QueryOptionExecutionTarget;\n}\n\n/**\n * The base class for all expression types.\n */\nexport abstract class Expression {\n /** The type of the expression. */\n abstract readonly type: ExpressionType;\n /** The left-hand side of the expression (if applicable). */\n left?: Expression;\n /** The right-hand side of the expression (if applicable). */\n right?: Expression;\n\n constructor(left?: Expression, right?: Expression) {\n this.left = left;\n this.right = right;\n }\n\n static get EMPTY() {\n return new EmptyExpression();\n }\n\n static get NOT_PARSABLE() {\n return new NotParsableExpression();\n }\n\n static isEmpty(expression: Expression) {\n return expression.type === \"empty\" || expression instanceof EmptyExpression;\n }\n\n static isNotParsable(expression: Expression) {\n return expression.type === \"not-parsable\" || expression instanceof NotParsableExpression;\n }\n\n /**\n * Turns a tree into plain JSON, so a whole query can cross a wire.\n *\n * On the class rather than beside it, because this is the type's own REPRESENTATION — there is one\n * right answer and it belongs with the thing being represented, next to `EMPTY` and `isEmpty`.\n * Rendering a tree into some other language (`toSql`, `toMql`, `evaluate`) is a different kind of\n * thing: there are many, each belongs to its consumer, and none of them is canonical.\n *\n * ## Why it is this small\n *\n * Of the six node types a bound tree can contain, exactly one holds anything JSON cannot carry:\n * `PropertyExpression`, whose live `PropertyInfo` has functions, a parent chain and caches. It\n * reduces to a property PATH — `PropertyInfo.id` IS the dotted path, and `getProperty` is keyed by\n * exactly that — so rebinding is one lookup.\n *\n * `ParamReferenceExpression` never appears: it is a parse-time placeholder that binding replaces\n * with a plain `ValueExpression` holding the resolved value. A serialized tree is always already\n * bound, so there is no params object to send alongside it.\n *\n * Switches on `type` rather than using the `isXExpression` guards, which live in `../assertions`\n * and import this module — the guards test the same discriminant, so nothing is lost.\n */\n static toJson(expression: Expression): SerializedExpression {\n\n if (expression.type === \"operator\") {\n const operator = expression as OperatorExpression;\n\n return {\n t: \"operator\",\n operator: operator.operator,\n ...(operator.left != null && { left: Expression.toJson(operator.left) }),\n ...(operator.right != null && { right: Expression.toJson(operator.right) }),\n };\n }\n\n if (expression.type === \"comparator\") {\n const comparator = expression as ComparatorExpression;\n\n return {\n t: \"comparator\",\n comparator: comparator.comparator,\n negated: comparator.negated,\n strict: comparator.strict,\n ...(comparator.left != null && { left: Expression.toJson(comparator.left) }),\n ...(comparator.right != null && { right: Expression.toJson(comparator.right) }),\n };\n }\n\n if (expression.type === \"property\") {\n const property = expression as PropertyExpression;\n\n return {\n t: \"property\",\n // The dotted path, which is exactly the key `getProperty` is looking up\n path: property.property.id,\n transformer: property.transformer,\n locale: property.locale,\n };\n }\n\n if (expression.type === \"value\") {\n const value = expression as ValueExpression;\n\n return {\n t: \"value\",\n value: valueToJson(value.value),\n transformer: value.transformer,\n locale: value.locale,\n };\n }\n\n return expression.type === \"empty\" ? { t: \"empty\" } : { t: \"not-parsable\" };\n }\n\n /**\n * Rebuilds a tree from JSON, rebinding every property against `schema`.\n *\n * The schema is SUPPLIED rather than read out of the payload. A filter always belongs to a known\n * collection, and the RECEIVER's schema is the authority on what its properties are — taking an\n * id from the payload would mean rebinding against a schema the sender chose, which is backwards\n * for anything crossing a trust boundary.\n *\n * @throws when a property path is not declared by `schema`. Not `NOT_PARSABLE`: on a receiver, a\n * filter that silently stops filtering returns rows the requester excluded, which is the one\n * failure here worse than an error.\n */\n static fromJson(json: SerializedExpression, schema: CompiledSchemaCore<any>): Expression {\n\n const child = (node: SerializedExpression | undefined) => node == null ? undefined : Expression.fromJson(node, schema);\n\n if (json.t === \"operator\") {\n return new OperatorExpression({ operator: json.operator, left: child(json.left), right: child(json.right) });\n }\n\n if (json.t === \"comparator\") {\n return new ComparatorExpression({\n comparator: json.comparator,\n negated: json.negated,\n strict: json.strict,\n left: child(json.left),\n right: child(json.right),\n });\n }\n\n if (json.t === \"property\") {\n const property = schema.getProperty(json.path);\n\n if (property == null) {\n throw new Error(\n `Cannot deserialize a filter: this schema does not declare the property it names. ` +\n `Property: ${json.path}, Collection: ${schema.collectionName}. ` +\n `The two sides disagree about the shape of the data, so the filter cannot be applied.`\n );\n }\n\n const rebuilt = new PropertyExpression({ property });\n rebuilt.transformer = json.transformer;\n rebuilt.locale = json.locale;\n\n return rebuilt;\n }\n\n if (json.t === \"value\") {\n const rebuilt = new ValueExpression({ value: valueFromJson(json.value) });\n rebuilt.transformer = json.transformer;\n rebuilt.locale = json.locale;\n\n return rebuilt;\n }\n\n return json.t === \"empty\" ? Expression.EMPTY : Expression.NOT_PARSABLE;\n }\n}\n\nexport class EmptyExpression extends Expression {\n readonly type = \"empty\" as const;\n}\n\nexport class NotParsableExpression extends Expression {\n readonly type = \"not-parsable\" as const;\n}\n\n/**\n * A class representing a comparison operation (e.g., equals, greater-than).\n */\nexport class ComparatorExpression extends Expression {\n /** The type of the expression (always 'comparator'). */\n readonly type = \"comparator\" as const;\n /** The comparator operation (e.g., equals, greater-than). */\n comparator: Comparator;\n /** Whether the comparison is negated (e.g., not equals). */\n negated: boolean;\n /** Whether the comparison is strict (type-sensitive). */\n strict: boolean;\n\n constructor(\n options: {\n comparator: Comparator,\n negated: boolean,\n strict: boolean,\n left?: Expression,\n right?: Expression\n }\n ) {\n super(options.left, options.right);\n this.comparator = options.comparator;\n this.negated = options.negated;\n this.strict = options.strict;\n }\n}\n\n/**\n * A class representing a logical operator (e.g., &&, ||).\n */\nexport class OperatorExpression extends Expression {\n /** The type of the expression (always 'operator'). */\n readonly type = \"operator\" as const;\n /** The logical operator. */\n operator: Operator;\n\n constructor(options: { operator: Operator, left?: Expression, right?: Expression }) {\n super(options.left, options.right);\n this.operator = options.operator;\n }\n}\n\n/**\n * A class representing a property path.\n */\nexport class PropertyExpression extends Expression {\n /** The type of the expression (always 'property'). */\n readonly type = \"property\" as const;\n /** The property info for the path. */\n property: PropertyInfo<any>;\n transformer: Transformer | null = null;\n locale: string | null = null;\n\n constructor(options: { property: PropertyInfo<any> }) {\n super();\n this.property = options.property;\n }\n}\n\n/**\n * A class representing a literal value.\n */\nexport class ValueExpression extends Expression {\n /** The type of the expression (always 'value'). */\n readonly type = \"value\" as const;\n /** The literal value. */\n value: unknown;\n\n transformer: Transformer | null = null;\n locale: string | null = null;\n\n constructor(options: {\n value: unknown\n }) {\n super();\n this.value = options.value;\n }\n}\n\n\n/**\n * The set of possible expression types.\n */\nexport type ExpressionType = \"operator\" | \"comparator\" | \"property\" | \"value\" | \"empty\" | \"not-parsable\";\n\n/**\n * Supported value transformations that can be applied to values.\n * `length` reads the length of a string or array property.\n */\nexport type Transformer = \"to-lower-case\" | \"to-upper-case\" | \"length\";\n\n/**\n * Supported comparator operations for expressions.\n */\nexport type Comparator =\n | \"equals\"\n | \"starts-with\"\n | \"includes\"\n | \"ends-with\"\n | \"greater-than\"\n | \"greater-than-equals\"\n | \"less-than\"\n | \"less-than-equals\";\n\n/**\n * Supported logical operators for expressions.\n */\nexport type Operator = \"&&\" | \"||\";\n\n/**\n * A function that filters a value of type T and returns a boolean.\n */\nexport type Filter<T extends any> = (value: T) => boolean;\n\n/**\n * A function that filters a value of type T with additional parameters P.\n */\nexport type ParamsFilter<T extends any, P> = (payload: [T, P]) => boolean;\n\n/**\n * A filter that can be either a simple filter or a parameterized filter.\n */\nexport type CompositeFilter<T extends any, P = never> = Filter<T> | ParamsFilter<T, P>;\n\n/**\n * An object that can be filtered using a composite filter and optional parameters.\n */\nexport type Filterable<T extends any, P = any> = {\n /** The filter function. */\n filter: CompositeFilter<T, P>;\n /** Optional parameters for the filter. */\n params?: P;\n};","import { PropertyInfo } from \"../schema\";\nimport { Expression, PropertyExpression } from \"./types\";\n\n/**\n * Extracts all properties referenced in an expression\n * @param expression The expression to analyze\n * @returns Array of PropertyInfo objects referenced in the expression\n */\nexport function getProperties(expression: Expression): PropertyInfo<any>[] {\n const properties: PropertyInfo<any>[] = [];\n\n function traverse(expr: Expression) {\n // If this is a property expression, add it to our collection\n if (expr.type === \"property\") {\n properties.push((expr as PropertyExpression).property);\n }\n\n // Traverse left and right expressions if they exist\n if (expr.left) {\n traverse(expr.left);\n }\n if (expr.right) {\n traverse(expr.right);\n }\n }\n\n traverse(expression);\n return properties;\n}\n\nexport function forEach(expression: Expression, callback: (expression: Expression) => boolean) {\n function traverse(expr: Expression): boolean {\n // Call the callback for this expression\n // If callback returns false, stop traversing\n if (!callback(expr)) {\n return false;\n }\n\n // Traverse left and right expressions if they exist\n if (expr.left) {\n if (!traverse(expr.left)) {\n return false;\n }\n }\n if (expr.right) {\n if (!traverse(expr.right)) {\n return false;\n }\n }\n\n return true;\n }\n\n traverse(expression);\n}","import { logger } from \"../utilities\";\nimport { CallbackResult, Result, ResultType } from \"../results\";\n\n/**\n * Type definition for an asynchronous function that takes data and a callback.\n * TIn: The input data type.\n * TOut: The output data type (passed to the callback).\n */\nexport type Processor<TIn, TOut> = (data: TIn, callback: (result: TOut, error?: any) => void) => void;\n\n// Return type for a step execution: Either the next step function or null if waiting/done.\ntype StepResult<TData> = TrampolineStep<TData> | null;\ntype TrampolineStep<TData> = () => StepResult<TData>;\n\nexport class TrampolinePipeline<TInitial, TCurrent = TInitial> {\n private _list: Processor<any, any>[] = [];\n private _hasErrored: boolean = false; // Flag to prevent calling done on error\n\n filter<TFinal>(initialData: TInitial, done: (data: TFinal, error?: any) => void) {\n\n this._hasErrored = false; // Reset error flag on new execution\n\n if (this._list.length === 0) {\n done(initialData as unknown as TFinal);\n return;\n }\n\n let index = 0;\n let currentData: any = initialData;\n let isRunning = false; // Guard against overlapping trampoline calls\n\n try {\n // --- Revised Completion Logic --- (Moved up for clarity)\n const finalStepSentinel = (): StepResult<any> => { // A special step function for the very end\n // Only call done if no error has occurred\n if (!this._hasErrored) {\n done(currentData as TFinal);\n }\n return null; // Stop the trampoline\n };\n\n const createStepRevised = (idx: number): TrampolineStep<any> => {\n return () => {\n if (this._hasErrored) return null; // Stop if an error occurred elsewhere\n\n if (idx >= this._list.length) {\n return finalStepSentinel(); // Execute the dedicated final step\n }\n\n const processor = this._list[idx];\n // Initialize syncCallbackResult to null to satisfy StepResult type\n let syncCallbackResult: StepResult<any> = null;\n let calledSync = false;\n\n try {\n processor(currentData, (result, error) => {\n // --- Error Handling ---\n if (error) {\n logger.error(`Error reported by processor at index ${idx}:`, error);\n this._hasErrored = true; // Set flag\n // Throw the error to be caught by outer try...catch blocks\n throw error;\n }\n // --- /Error Handling ---\n\n // If no error, proceed as before\n currentData = result;\n index = idx + 1; // Update index for the next step\n const nextStep = createStepRevised(index); // Use updated index\n\n if (isRunning) {\n // Callback was synchronous\n syncCallbackResult = nextStep; // Store next step function\n calledSync = true;\n } else {\n // Callback was asynchronous, restart trampoline\n trampoline(nextStep);\n }\n });\n } catch (error) {\n if (!this._hasErrored) { // Check flag to avoid double logging if error was from callback\n logger.error(`Error thrown by processor at index ${idx} or its callback:`, error);\n this._hasErrored = true;\n }\n // Rethrow to be caught by the trampoline's catch block\n throw error;\n }\n\n if (calledSync) {\n // Return the next step function for the sync loop\n return syncCallbackResult;\n } else {\n // Pause trampoline for async, loop will stop as step returns null\n return null;\n }\n };\n };\n\n // The trampoline loop\n const trampoline = (step: TrampolineStep<any> | null) => {\n\n if (isRunning) {\n return;\n }\n\n isRunning = true;\n let currentStep = step;\n\n while (currentStep !== null) {\n try {\n // Stop immediately if an error was flagged elsewhere\n if (this._hasErrored) {\n currentStep = null;\n break;\n }\n currentStep = currentStep(); // Execute step, get next step or null\n } catch (trampolineError) {\n // Catch errors propagated from step execution (processor or callback errors)\n if (!this._hasErrored) { // Avoid double logging\n logger.error(\"Error during trampoline step execution:\", trampolineError);\n this._hasErrored = true;\n }\n currentStep = null; // Stop the loop\n\n // Report the failure to the caller.\n //\n // This used to break without calling `done`, on the reasoning that\n // the application should handle the uncaught exception. It cannot:\n // the error is caught right here, so nothing escapes to be handled,\n // and every caller awaiting the callback waits forever. A hang is\n // strictly worse than an error — it gives the caller nothing to act\n // on and no way to time out.\n //\n // `done` runs exactly once per execution: this path returns\n // immediately, and finalStepSentinel checks `_hasErrored` before\n // reporting success, so the two are mutually exclusive.\n isRunning = false;\n done(currentData as TFinal, trampolineError);\n return;\n }\n }\n // Loop ends when currentStep is null or loop is broken by error\n isRunning = false;\n\n // Completion check is now handled by finalStepSentinel ensuring `done` isn't called on error.\n };\n\n // --- Start the process ---\n index = 0; // Reset index\n currentData = initialData; // Reset data\n trampoline(createStepRevised(0)); // Start with the revised step creator\n } catch (error: any) {\n done(currentData, error);\n }\n }\n\n pipe<TNext>(processor: Processor<TCurrent, TNext>) {\n this._list.push(processor);\n return this as unknown as TrampolinePipeline<TInitial, TNext>;\n }\n\n pipeEach(items: TCurrent[], fn: (payload: ResultType<TCurrent>, done: CallbackResult<TCurrent>) => void, map: (previous: ResultType<TCurrent>, current: ResultType<TCurrent>) => ResultType<TCurrent>) {\n for (let i = 0, length = items.length; i < length; i++) {\n\n this.pipe<ResultType<TCurrent>>((previous, done) => {\n\n fn(map(previous as ResultType<TCurrent>, Result.success(items[i])), done);\n });\n }\n }\n}\n\nexport type UnitOfWork = (done: CallbackResult<never>) => void;\n\n/**\n * Processes functions with callbacks asynchronously.\n * \n * This pipeline handles work items that contain callback functions,\n * executing them in an asynchronous manner while maintaining proper\n * flow control and error handling.\n */\nexport class WorkPipeline {\n private unitsOfWork: UnitOfWork[] = [];\n private _hasErrored: boolean = false; // Flag to prevent calling done on error\n\n filter(done: CallbackResult<never>) {\n\n this._hasErrored = false; // Reset error flag on new execution\n\n if (this.unitsOfWork.length === 0) {\n done(Result.success());\n return;\n }\n\n let index = 0;\n let isRunning = false; // Guard against overlapping trampoline calls\n\n try {\n // --- Revised Completion Logic --- (Moved up for clarity)\n const finalStepSentinel = (): StepResult<never> => { // A special step function for the very end\n // Only call done if no error has occurred\n if (!this._hasErrored) {\n done(Result.success());\n }\n return null; // Stop the trampoline\n };\n\n const createStepRevised = (idx: number): TrampolineStep<any> => {\n return () => {\n if (this._hasErrored) return null; // Stop if an error occurred elsewhere\n\n if (idx >= this.unitsOfWork.length) {\n return finalStepSentinel(); // Execute the dedicated final step\n }\n\n const processor = this.unitsOfWork[idx];\n // Initialize syncCallbackResult to null to satisfy StepResult type\n let syncCallbackResult: StepResult<any> = null;\n let calledSync = false;\n\n try {\n processor((result) => {\n // --- Error Handling ---\n if (result.ok === Result.ERROR) {\n logger.error(`Error reported by AsyncPipeline at index ${idx}:`, result.error);\n this._hasErrored = true; // Set flag\n // Throw the error to be caught by outer try...catch blocks\n throw result.error;\n }\n // --- /Error Handling ---\n\n // If no error, proceed as before\n index = idx + 1; // Update index for the next step\n const nextStep = createStepRevised(index); // Use updated index\n\n if (isRunning) {\n // Callback was synchronous\n syncCallbackResult = nextStep; // Store next step function\n calledSync = true;\n } else {\n // Callback was asynchronous, restart trampoline\n trampoline(nextStep);\n }\n });\n } catch (error) {\n if (!this._hasErrored) { // Check flag to avoid double logging if error was from callback\n logger.error(`Error thrown by processor at index ${idx} or its callback:`, error);\n this._hasErrored = true;\n }\n // Rethrow to be caught by the trampoline's catch block\n throw error;\n }\n\n if (calledSync) {\n // Return the next step function for the sync loop\n return syncCallbackResult;\n } else {\n // Pause trampoline for async, loop will stop as step returns null\n return null;\n }\n };\n };\n\n // The trampoline loop\n const trampoline = (step: TrampolineStep<any> | null) => {\n\n if (isRunning) {\n return;\n }\n\n isRunning = true;\n let currentStep = step;\n\n while (currentStep !== null) {\n try {\n // Stop immediately if an error was flagged elsewhere\n if (this._hasErrored) {\n currentStep = null;\n break;\n }\n currentStep = currentStep(); // Execute step, get next step or null\n } catch (trampolineError) {\n // Catch errors propagated from step execution (processor or callback errors)\n if (!this._hasErrored) { // Avoid double logging\n logger.error(\"Error during trampoline step execution:\", trampolineError);\n this._hasErrored = true;\n }\n currentStep = null; // Stop the loop\n\n // Report the failure to the caller. See the note on the same path in\n // TrampolinePipeline: swallowing the error here left every caller\n // awaiting `done` hanging instead of receiving a failure.\n isRunning = false;\n done(Result.error(trampolineError));\n return;\n }\n }\n // Loop ends when currentStep is null or loop is broken by error\n isRunning = false;\n\n // Completion check is now handled by finalStepSentinel ensuring `done` isn't called on error.\n };\n\n // --- Start the process ---\n index = 0; // Reset index\n trampoline(createStepRevised(0)); // Start with the revised step creator\n } catch (error: any) {\n done(Result.error(error));\n }\n }\n\n pipe(work: UnitOfWork) {\n this.unitsOfWork.push(work);\n }\n}","import { isPropertyExpression } from \"../../assertions\";\nimport { forEach } from \"../../expressions/utils\";\nimport { MemoryExecutionReason, QueryOption, QueryOptionName, QueryOptionExecutionTarget, QueryOptionValueMap } from \"./types\";\n\nexport type QueryCollectionItem<T, K extends QueryOptionName> = { index: number, option: QueryOption<T, K> };\n\nexport class QueryOptionsCollection<T> {\n\n private options: Map<QueryOptionName, QueryCollectionItem<any, any>[]> = new Map<QueryOptionName, QueryCollectionItem<any, any>[]>();\n private nextExecutionTarget: QueryOptionExecutionTarget = \"database\";\n private nextExecutionReason: MemoryExecutionReason | null = null;\n private nextIndex: number = 0;\n private enumeratedItems: QueryCollectionItem<any, any>[] = [];\n\n /** Cuts over to memory execution, keeping the first cause. See `MemoryExecutionReason`. */\n private cutOverToMemory(reason: MemoryExecutionReason) {\n this.nextExecutionTarget = \"memory\";\n\n if (this.nextExecutionReason == null) {\n this.nextExecutionReason = reason;\n }\n }\n\n /**\n * True when `split()` or `splitAt()` produced this collection.\n *\n * Those rebuild each half by re-adding its options, which re-derives execution targets\n * without the options that caused them — a post-join filter alone in the memory half\n * derives back to `\"database\"`. Anything reading `target` as a report of where work runs\n * has to reject a derived collection; see `explainQuery`.\n */\n private derived: boolean = false;\n\n get isDerived() {\n return this.derived;\n }\n\n get items() {\n return this.options;\n }\n\n get isEmpty() {\n return this.items.size === 0;\n }\n\n static EMPTY<R>() {\n return new QueryOptionsCollection<R>();\n }\n\n static isEmpty<T>(options: QueryOptionsCollection<T>) {\n return options.isEmpty;\n }\n\n add<K extends QueryOptionName>(name: K, value: QueryOption<T, K>[\"value\"]) {\n\n if (name === \"map\") {\n const mapValue = value as QueryOptionValueMap<T>[\"map\"];\n\n // Evaluate the map value to see if we are renaming properties, \n // if we are we need to perform everything after in memory\n if (mapValue.fields.some(x => x.isRename === true) || mapValue.fields.some(x => x.property?.isUnmapped === true)) {\n // Cut over to memory execution since we are renaming a property with .map\n // We do not want to figure out how the new name flows through the entire query\n this.cutOverToMemory(\"map-rename\");\n }\n }\n\n if (name === \"filter\") {\n // Need to check for unmapped and renamed properties\n const filterValue = value as QueryOptionValueMap<T>[\"filter\"];\n\n // A tautology (`x => true`) filters nothing — skip it entirely so\n // plugins never see it\n if (filterValue.expression.type === \"empty\") {\n return;\n }\n\n if (filterValue.expression.type === \"not-parsable\") {\n this.cutOverToMemory(\"not-parsable\");\n } else {\n forEach(filterValue.expression, (expression) => {\n\n if (isPropertyExpression(expression) && expression.property.isUnmapped) {\n // Cut over to memory execution, unmapped properties are not in the database and\n // cannot be queried\n this.cutOverToMemory(\"unmapped-property\");\n return false;\n }\n\n if (isPropertyExpression(expression) && expression.property.hasRenamedSegments) {\n // Cut over to memory execution: the plugin stores data under the\n // `from` (storage) names, but filter selectors reference the\n // in-memory names. Memory execution runs after deserialization,\n // where the in-memory names exist\n this.cutOverToMemory(\"renamed-property\");\n return false;\n }\n\n return true;\n });\n }\n }\n\n if (name === \"sort\") {\n const sortValue = value as QueryOptionValueMap<T>[\"sort\"];\n\n // Same rule as filters: sort selectors reference in-memory names, which\n // only exist after deserialization when the property is renamed or unmapped\n if (sortValue.property != null && sortValue.property.isUnmapped) {\n this.cutOverToMemory(\"unmapped-property\");\n } else if (sortValue.property != null && sortValue.property.hasRenamedSegments) {\n this.cutOverToMemory(\"renamed-property\");\n }\n }\n\n if (name === \"nearest\") {\n const nearestValue = value as QueryOptionValueMap<T>[\"nearest\"];\n\n // Same rule as sort, and for the same reason: the plugin stores the vector under\n // the `from` name, and an unmapped property is not stored at all. Both are only\n // readable after deserialization, which is where memory execution runs.\n //\n // This is also what lets every translator's in-memory fallback read the column by\n // its resolved name — anything whose storage name differs never reaches them.\n if (nearestValue.property != null && nearestValue.property.isUnmapped) {\n this.cutOverToMemory(\"unmapped-property\");\n } else if (nearestValue.property != null && nearestValue.property.hasRenamedSegments) {\n this.cutOverToMemory(\"renamed-property\");\n }\n }\n\n if (name === \"join\") {\n const joinValue = value as QueryOptionValueMap<T>[\"join\"];\n\n // A join whose two sides live on different plugins cannot be sent to EITHER of\n // them — neither can read the other's rows — so the option itself belongs to the\n // memory half, where the datastore interprets it.\n //\n // Set BEFORE the item is created, unlike `nearest`'s ratchet below, because this\n // moves the join option itself rather than everything after it.\n if (joinValue.crossPlugin === true) {\n this.cutOverToMemory(\"cross-plugin-join\");\n }\n }\n\n const item: QueryCollectionItem<T, K> = {\n index: this.nextIndex,\n option: {\n name,\n target: this.nextExecutionTarget,\n value,\n ...(this.nextExecutionReason == null ? {} : { reason: this.nextExecutionReason })\n }\n }\n\n this.nextIndex++;\n\n const found = this.options.get(name);\n\n this.options.set(name, [...found ?? [], item]);\n\n if (name === \"nearest\") {\n // Everything AFTER a similarity search runs in memory, whatever the backend.\n //\n // Whether the search was pushed down is a fact about the plugin, which this\n // collection cannot see — so a later option is only safe if it runs after the\n // scoring definitely happened, and in memory is the only place that is true of.\n //\n // The failure this prevents is silent. `.nearest(x => x.embedding, v, 10).take(3)`\n // sends `LIMIT 3` to a backend that ignored the ordering, so three arbitrary rows\n // come back and get scored — three real rows, in a plausible order, and not the\n // three nearest. Nothing errors.\n //\n // A plugin that DID push the search down loses nothing but the chance to also\n // push down what follows it, which is a limit over ten rows.\n this.cutOverToMemory(\"after-nearest\");\n }\n\n if (name === \"join\") {\n // Everything AFTER a join runs in memory, for the same reason as `nearest`: this\n // collection cannot see HOW the plugin executed the join, and the rows it produced\n // are TUPLES rather than entities of the root schema.\n //\n // A `take` sent to a backend that hash-joined in its translator would limit the\n // OUTER rows read, not the pairs produced — a plausible-looking result with the\n // wrong number of rows in it. Conjuncts that can safely run earlier are split off\n // by the query builder BEFORE dispatch, which is the only exception.\n this.cutOverToMemory(\"after-join\");\n }\n }\n\n /**\n * Splits the collection around the FIRST occurrence of `name`, preserving order.\n *\n * For a join: the options recorded before it operate on entity rows, the option itself\n * produces tuples, and the ones after it operate on tuples. Three different shapes, so the\n * caller has to run them in three steps rather than one pass.\n */\n splitAt<K extends QueryOptionName>(name: K): { before: QueryOptionsCollection<T>, at: QueryOption<T, K> | null, after: QueryOptionsCollection<T> } {\n this.resolveEnumeration();\n\n const sortedItems = this.enumeratedItems.toSorted((a, b) => a.index - b.index);\n const before = new QueryOptionsCollection<T>();\n const after = new QueryOptionsCollection<T>();\n\n before.derived = true;\n after.derived = true;\n let at: QueryOption<T, K> | null = null;\n\n for (let i = 0, length = sortedItems.length; i < length; i++) {\n const { option } = sortedItems[i];\n\n if (at == null && option.name === name) {\n at = option as QueryOption<T, K>;\n continue;\n }\n\n const destination = at == null ? before : after;\n destination.add(option.name, option.value);\n }\n\n return { before, at, after };\n }\n\n /**\n * Captures the collection's current state and returns a function that restores it.\n *\n * Terminal queryable operations (count, first, aggregates, …) record their option on\n * the shared collection before executing. Without restoring, a re-executed terminal —\n * the whole point of a subscribed queryable — stacks its option a second time and\n * runs it over the first execution's scalar result.\n */\n snapshot(): () => void {\n const options = new Map([...this.options.entries()].map(([key, items]): [QueryOptionName, QueryCollectionItem<any, any>[]] => [key, [...items]]));\n const nextExecutionTarget = this.nextExecutionTarget;\n const nextExecutionReason = this.nextExecutionReason;\n const nextIndex = this.nextIndex;\n\n return () => {\n this.options = new Map(options);\n this.nextExecutionTarget = nextExecutionTarget;\n this.nextExecutionReason = nextExecutionReason;\n this.nextIndex = nextIndex;\n this.enumeratedItems = [];\n };\n }\n\n split(): { memory: QueryOptionsCollection<T>, database: QueryOptionsCollection<T> } {\n this.resolveEnumeration();\n\n const sortedItems = this.enumeratedItems.toSorted((a, b) => a.index - b.index);\n const memoryQueryOptionsCollection = new QueryOptionsCollection<T>();\n const databaseQueryOptionsCollection = new QueryOptionsCollection<T>();\n\n memoryQueryOptionsCollection.derived = true;\n databaseQueryOptionsCollection.derived = true;\n\n for (let i = 0, length = sortedItems.length; i < length; i++) {\n const sortedItem = sortedItems[i];\n\n if (sortedItem.option.target === \"database\") {\n databaseQueryOptionsCollection.add(sortedItem.option.name, sortedItem.option.value);\n continue;\n }\n\n memoryQueryOptionsCollection.add(sortedItem.option.name, sortedItem.option.value);\n }\n\n return {\n memory: memoryQueryOptionsCollection,\n database: databaseQueryOptionsCollection\n }\n }\n\n hasTransformations(): boolean {\n const transformationOptions: QueryOptionName[] = [\"map\", \"group\", \"min\", \"max\", \"count\", \"sum\"];\n return transformationOptions.some((name) => this.options.has(name));\n }\n\n has<K extends QueryOptionName>(name: K): boolean {\n return this.options.has(name);\n }\n\n get<K extends QueryOptionName>(name: K): QueryCollectionItem<T, K>[] {\n return this.options.get(name) ?? [] as QueryCollectionItem<T, K>[];\n }\n\n getLast<K extends QueryOptionName>(name: K): QueryOption<T, K> | null {\n this.resolveEnumeration();\n\n for (let i = this.enumeratedItems.length - 1; i >= 0; i--) {\n const item = this.enumeratedItems[i];\n\n if (item.option.name === name) {\n return item.option;\n }\n }\n\n return null\n }\n\n getValues<K extends QueryOptionName>(name: K): QueryCollectionItem<T, K>[\"option\"][\"value\"][] | undefined {\n\n const found = this.options.get(name);\n\n if (found == null) {\n return [];\n }\n\n return found.map(w => w.option.value) as QueryCollectionItem<T, K>[\"option\"][\"value\"][];\n }\n\n private getEnumeration() {\n return [...this.options.values()].flat().toSorted((a, b) => a.index - b.index);\n }\n\n private resolveEnumeration() {\n if (this.enumeratedItems.length != this.nextIndex) {\n this.enumeratedItems = this.getEnumeration();\n }\n }\n\n forEach(iterator: (item: QueryCollectionItem<T, any>[\"option\"]) => void) {\n this.resolveEnumeration();\n\n for (let i = 0, length = this.enumeratedItems.length; i < length; i++) {\n iterator(this.enumeratedItems[i].option);\n }\n }\n}","import { PartialResultType, PluginEventPartialResultType, PluginEventResultType, ResultType } from \"./types\";\n\nabstract class BaseResult {\n static ERROR = \"error\" as const;\n static SUCCESS = \"success\" as const;\n static PARTIAL = \"partial\" as const;\n\n static resolve<T>(result: ResultType<T> | PartialResultType<T>, resolve: (data: T) => void, reject: (error?: any) => void) {\n if (result.ok === BaseResult.SUCCESS) {\n resolve(result.data);\n return;\n }\n\n if (result.ok === BaseResult.PARTIAL) {\n reject({\n partial: result.data,\n error: result.error\n });\n return;\n }\n\n reject(result.error);\n }\n\n static assertSuccess<T>(result: any): asserts result is { ok: \"success\"; data: T } {\n if (result.ok !== BaseResult.SUCCESS) {\n throw new Error(`Expected success result, but got ${result.ok}: ${result.error}`);\n }\n }\n}\n\nexport class Result extends BaseResult {\n static success<T>(data: T): ResultType<T>;\n static success(): ResultType<never>;\n static success<T>(data?: T): ResultType<T> {\n return {\n ok: Result.SUCCESS,\n data\n }\n }\n\n static error<T>(error: any): ResultType<T> {\n return {\n ok: Result.ERROR,\n error\n }\n }\n\n static partial<T>(data: T, error: any): PartialResultType<T> {\n return {\n ok: Result.PARTIAL,\n data,\n error\n }\n }\n}\n\nexport class PluginEventResult extends BaseResult {\n static success<T>(id: string, data: T): PluginEventResultType<T>;\n static success(id: string): PluginEventResultType<never>;\n static success<T>(id: string, data?: T): PluginEventResultType<T> {\n return {\n id,\n ok: Result.SUCCESS,\n data\n }\n }\n\n static error<T>(id: string, error: any): PluginEventResultType<T> {\n return {\n id,\n ok: Result.ERROR,\n error\n }\n }\n\n static partial<T>(id: string, data: T, error: any): PluginEventPartialResultType<T> {\n return {\n id,\n ok: Result.PARTIAL,\n data,\n error\n }\n }\n\n static assertSuccess<T>(result: PluginEventResultType<T>): asserts result is { ok: \"success\"; data: T; id: string } {\n if (result.ok !== Result.SUCCESS) {\n throw new Error(`Expected success result, but got ${result.ok}: ${result.error}`);\n }\n }\n}\n","import type { SchemaDefinition } from \"./SchemaDefinition\";\nimport type { SchemaBase } from \"./property/base/SchemaBase\";\nimport type { SchemaArray } from \"./property/types/SchemaArray\";\nimport type { SchemaVector } from \"./property/types/SchemaVector\";\nimport type { SchemaObject } from \"./property/types/SchemaObject\";\nimport type { PropertyInfo } from \"./PropertyInfo\";\nimport type { DeepPartial } from \"../types\";\nimport type { SchemaFunction } from \"./table\";\nimport type { SchemaOptional, SchemaTag } from \"./property/modifiers\";\nimport type { Branded } from \"../utilities/types\";\nimport type { SchemaSubscriptionOptions } from \"./communication/broadcast\";\n\nexport type DefaultValue<T, I = never> = T | ((injected: I) => T);\nexport type FunctionBody<TEntity, TResult> = (entity: TEntity, collectionName: CollectionName) => TResult;\nexport type IdType = string | number;\nexport type ForeignKey<T extends {}> = { \n schema: CompiledSchema<T>, \n property: PropertyInfo<T> \n};\n\nexport enum SchemaTypes {\n Array = \"Array\",\n Boolean = \"Boolean\",\n Date = \"Date\",\n Number = \"Number\",\n Object = \"Object\",\n String = \"String\",\n Definition = \"Definition\",\n Function = \"Function\",\n Computed = \"Computed\",\n /**\n * Content in, reference out. The only type whose write shape differs from its stored\n * shape, and a leaf on purpose — see `SchemaFile`.\n */\n File = \"File\",\n /**\n * A fixed-length list of numbers, carrying its dimension count — see `SchemaVector`.\n *\n * Value-shaped exactly like `s.array(s.number())`, which is why every array codegen\n * handler accepts it. It is a distinct type only so a backend can recognise it and store\n * it natively; nothing else needs to tell the two apart.\n */\n Vector = \"Vector\"\n}\n\nexport type ArrayShape = string | number | Date | {};\n\n\n/**\n * What a file property gives back: where the bytes are and what they are.\n *\n * Declared in core so `InferType` can name it. Core never reads or writes the bytes — it only\n * carries this shape — and `@routier/blob-plugin` is what puts one here.\n */\nexport type FileReferenceValue = {\n /** Where the bytes live, content-addressed by the blob plugin. */\n key: string;\n /** Byte length. */\n size: number;\n /** Media type as supplied at upload. */\n contentType: string;\n /** SHA-256 of the bytes, lowercase hex. */\n checksum: string;\n /** The name to show a user. Not part of the key. */\n fileName: string;\n};\n\n/**\n * What a file property ACCEPTS: content, or a reference you already have.\n *\n * `Blob` covers `File`, which is what an `<input type=\"file\">` yields. A reference is accepted\n * too, so re-saving an entity that was read from the database does not have to re-upload it.\n */\nexport type FileContentValue =\n | FileReferenceValue\n | Uint8Array\n | ArrayBuffer\n | Blob\n | string;\n\n/**\n * What a vector property holds, in and out: a plain list of numbers.\n *\n * Named rather than written inline because the inference rules have to recognise it after a\n * modifier has erased which class produced it — the same problem `FileReferenceValue` solves\n * above, and for the same reason.\n */\nexport type VectorValue = number[];\n\n/**\n * What `s.string({ ... })` accepts.\n *\n * Declarations only. Core stores them and never acts on them; a backend that can use one does.\n */\nexport type StringOptions = {\n /**\n * The longest value the property is declared to hold.\n *\n * MySQL uses it for `VARCHAR(maxLength)`; without it every string column is\n * `VARCHAR(255)`, which silently truncates longer values. Other backends ignore it. Core\n * never validates a value against it — see `SchemaBase.maxLength`.\n */\n maxLength?: number;\n};\n\nexport type ExpandedProperty = ExpandedChildProperty & {\n assignmentPath: string;\n selectorPath: string;\n properties: Map<string, ExpandedChildProperty>;\n childDegree: number;\n};\n\nexport type ExpandedChildProperty = {\n propertyName: string;\n type: SchemaTypes;\n isNullableOrOptional: boolean;\n isReadonly: boolean;\n isIdentity: boolean;\n isUnmapped: boolean;\n}\n\nexport enum HashType {\n Ids = \"Ids\",\n Object = \"Object\"\n}\n\nexport type HashFunction<TEntity extends {}> = {\n (entity: InferCreateType<TEntity>, type: HashType.Object): string;\n (entity: InferType<TEntity>, type: HashType.Ids): string;\n}\n\nexport type GetHashTypeFunction<TEntity extends {}> = {\n (entity: InferCreateType<TEntity>): HashType.Object;\n (entity: InferType<TEntity>): HashType.Ids;\n}\n\nexport type ChangeTrackingType = \"proxy\" | \"diff\" | \"immutable\";\n\nexport type IndexType = \"single\" | \"compound\" | \"unique\" | \"primary-key\"\nexport type Index = {\n properties: PropertyInfo<any>[],\n type: IndexType;\n name: string;\n}\n\n/**\n * Represents changes to subscriptions, categorizing them by modifications to\n * entities (additions, updates, removals) or query-driven removals.\n * @template T - The type of the entities in the subscription.\n */\nexport type SubscriptionChanges<T extends {}> = {\n /**\n * Entities that have been added to the subscription.\n */\n adds: InferType<T>[];\n /**\n * Entities that have been updated within the subscription.\n */\n updates: InferType<T>[];\n /**\n * Entities that have been removed from the subscription.\n */\n removals: InferType<T>[];\n /**\n * Entities that have been added/updated/removed from the subscription and it is unknown \n * if the entities have been added/updated/removed.\n */\n unknown: InferType<T>[];\n}\n\nexport interface ISchemaSubscription<T extends {}> extends Disposable {\n send(changes: SubscriptionChanges<T>): void;\n onMessage(callback: (changes: SubscriptionChanges<T>) => void): void;\n}\n\nexport type Enrich<TEntity extends {}> = {\n (entity: InferType<TEntity>, changeTrackingType: ChangeTrackingType): InferType<TEntity>;\n (entity: InferCreateType<TEntity>, changeTrackingType: ChangeTrackingType): InferCreateType<TEntity>;\n}\nexport type Prepare<TEntity extends {}> = {\n (entity: InferCreateType<TEntity>): InferCreateType<TEntity>;\n (entity: InferType<TEntity>): InferType<TEntity>;\n}\nexport type Preprocess<TEntity extends {}> = {\n (entity: InferCreateType<TEntity>): InferType<TEntity>;\n (entity: InferType<TEntity>): InferType<TEntity>;\n}\n\nexport type SetProperties<TEntity extends {}> = (destination: DeepPartial<InferType<TEntity> | InferCreateType<TEntity>>, source: DeepPartial<InferType<TEntity> | InferCreateType<TEntity>>) => void;\n\nexport type CompiledSchemaCore<TEntity extends {}> = Omit<CompiledSchema<TEntity>, \"createSubscription\">;\n\nexport type CompiledSchemaWithMetadata<TEntity extends {}, TMetadata> = {\n readonly metadata: TMetadata;\n} & CompiledSchema<TEntity>;\n\n/**\n * Represents a fully compiled schema with all utilities and metadata for an entity type.\n */\nexport type CompiledSchema<TEntity extends {}> = {\n\n deserializePartial: (item: Record<string, unknown>, properties: PropertyInfo<TEntity>[]) => DeepPartial<InferType<TEntity>>;\n\n createSubscription: (abortSignal?: AbortSignal, scope?: string, options?: SchemaSubscriptionOptions) => ISchemaSubscription<TEntity>;\n /** Returns the property info for a given id (full path) */\n getProperty: (id: string) => PropertyInfo<TEntity>;\n /** Returns the ID of the given entity. */\n getId: (entity: InferType<TEntity>) => IdType;\n /** Returns a deep clone of the given entity. */\n clone: (entity: InferType<TEntity>) => InferType<TEntity>;\n /**\n * Returns a deep clone of a record that is still in the STORAGE shape — renamed properties\n * under their `from` names rather than their in-memory names.\n *\n * `clone` reads in-memory names, so it returns `undefined` for every renamed property of a\n * stored record. Use this when copying rows a store holds before they have been deserialized.\n * Generated on first call; schemas that are never cloned in storage shape never build it.\n */\n cloneStorage: (entity: InferType<TEntity>) => InferType<TEntity>;\n /** Removes unmapped or extraneous properties from the entity. */\n strip: (entity: InferType<TEntity>) => InferType<TEntity>;\n /** Prepares a new entity for creation, applying defaults and transformations. */\n prepare: Prepare<TEntity>;\n /** Merges the source entity into the destination entity. */\n merge: (destination: InferType<TEntity> | InferCreateType<TEntity>, source: InferType<TEntity>) => InferType<TEntity>;\n /** Indicates if the schema has identity properties. */\n hasIdentities: boolean;\n /** List of properties that are identity keys. */\n idProperties: PropertyInfo<TEntity>[];\n /** All property metadata for the schema. */\n properties: PropertyInfo<TEntity>[],\n /** The hash type used for this schema. */\n hashType: HashType;\n /** Computes a hash for the given entity. */\n hash: HashFunction<TEntity>;\n /** Returns the hash type for the given entity. */\n getHashType: GetHashTypeFunction<TEntity>;\n /** Compares two entities for equality. */\n compare: (a: InferType<TEntity>, fromDb: InferType<TEntity>) => boolean;\n /** Deserializes an entity from storage format. */\n deserialize: (entity: InferType<TEntity>) => InferType<TEntity>;\n /** Sets 1 or many properties from the source object onto the destination object with change tracking. */\n set: SetProperties<TEntity>;\n /** Combines serializing and preparing an entity for saving. */\n preprocess: Preprocess<TEntity>;\n /** Combines deserializing and enriching an entity for selection. */\n postprocess: Enrich<TEntity>;\n\n /** Serializes an entity to storage format. */\n serialize: (entity: InferType<TEntity>) => InferType<TEntity>;\n /** Unique id for the schema. */\n id: SchemaId,\n /** The name of the collection for this schema. */\n collectionName: CollectionName;\n /** Returns all IDs for the given entity (usually a single-element tuple). */\n getIds: (entity: InferType<TEntity>) => [IdType];\n /** Enriches the entity with change tracking or other metadata. */\n enrich: Enrich<TEntity>;\n /** Indicates if the schema has identity keys. */\n hasIdentityKeys: boolean;\n /** Returns a deeply frozen (immutable) version of the entity. */\n freeze: (entity: InferType<TEntity>) => InferType<TEntity>;\n /** Enables change tracking on the entity. */\n enableChangeTracking: (entity: InferType<TEntity>) => InferType<TEntity>;\n /** The schema definition object. */\n definition: SchemaDefinition<TEntity>;\n /** Returns all indexes defined for this schema. */\n getIndexes: () => Index[];\n /** Compares two entities for Id equality. */\n compareIds: (a: InferType<TEntity>, b: InferType<TEntity>) => boolean;\n}\n\nexport type PropertySerializer<T extends any> = (value: T) => string | number;\nexport type PropertyDeserializer<T extends any> = (value: string | number) => T;\n\n/**\n * A two-way transform between the application value and the stored value.\n *\n * Both directions may be async. Held as a live reference rather than stringified, so a\n * closure works and `injected` is a convenience rather than the only way in.\n */\nexport type PropertyTransform<T extends any> = {\n /**\n * Application value to stored value. Runs before the plugin sees it. May be async.\n *\n * `entity` is there for the one-way case: a transform with no `from` derives a value\n * rather than converting one, which is what `computed` does.\n */\n to: (value: T, entity: Record<string, unknown>) => unknown | Promise<unknown>;\n\n /**\n * Stored value back to application value. Runs after the plugin returns it.\n *\n * Optional. Leave it out and the transform is one-way: the stored value is the value.\n */\n from?: (value: unknown) => T | Promise<T>;\n\n /**\n * What the column becomes, when the stored form is not the property's own type.\n *\n * Defaults to the property's own type, so nothing changes unless you say it does. A\n * library that always produces text — a cipher, a compressor — sets this once, and the\n * caller who uses that library never writes it.\n */\n stores?: SchemaTypes;\n\n /**\n * Whether a filter on this property can still run in the database.\n *\n * Defaults to `none`, which rejects the filter rather than returning wrong rows. Set\n * `equality` only when `to` is deterministic.\n */\n comparable?: 'equality' | 'none';\n};\n\nexport type SchemaId = Branded<number, \"SchemaId\">;\nexport type CollectionName = Branded<string, \"CollectionName\">;\n\nexport type SchemaModifiers = \"default\" | \"deserialize\" |\n \"identity\" | \"key\" |\n \"nullable\" | \"optional\" |\n \"readonly\" | \"serialize\" |\n \"unmapped\" | \"computed\" |\n \"distinct\" | \"searchable\";\n\n/**\n * What a tagged property infers to.\n *\n * `tag()` is metadata and must not change a type, but `SchemaTag<T>` carries the same `T` as\n * whatever it wrapped without carrying which class that was. For a string `T` is already\n * `string`; for an object `T` is the map of child schemas, which only the `SchemaObject`\n * branch below knows how to unwrap. Falling through to the generic `SchemaBase` branch\n * therefore handed the raw map back, so `s.object({ key: s.string() }).tag('x')` typed\n * `key` as `SchemaString` instead of `string` — everything ran, and only the types lied.\n *\n * An array is distinguishable because `SchemaArray`'s parameter is the ELEMENT schema, so a\n * tagged array arrives here as a `SchemaBase` rather than a plain map.\n */\ntype InferTagged<C> = ResolveWrapped<C>;\n\n/**\n * What a wrapping modifier's inner type resolves to.\n *\n * `SchemaOptional`, `SchemaNullable` and `SchemaTag` all carry the same `C` as whatever they\n * wrapped, without carrying which class that was, so each has to work out what it is holding.\n * Three shapes are possible:\n *\n * - an already-resolved value (`string` from `s.string()`, a file reference from `s.file()`)\n * - an ELEMENT schema, which is what `SchemaArray` parameterises on\n * - a map of child schemas, which is what `SchemaObject` parameterises on\n *\n * Getting this wrong is silent. The map branch applied to an already-resolved object walks\n * its keys and infers `never` for each, so `s.file().optional()` typed as\n * `{ key: never, size: never, ... }` — which no value can satisfy and no test would catch at\n * runtime.\n */\ntype ResolveWrapped<C> =\n C extends string | number | boolean | Date | FileReferenceValue ? C :\n C extends VectorValue ? C :\n C extends SchemaBase<any, any> ? InferPrimitive<C>[] :\n { [K in keyof C]: InferPrimitive<C[K]> };\n\ntype InferPrimitive<T> =\n T extends SchemaOptional<infer C, infer __> ? ResolveWrapped<C> :\n T extends SchemaTag<infer C, infer __> ? InferTagged<C> :\n // Before the generic `SchemaBase` branch below, which would see `X = number[]` and map\n // the element through `InferPrimitive<number>` — no branch matches a bare `number`, so a\n // vector would type as `never[]`: assignable from nothing, and invisible at runtime.\n T extends SchemaVector<infer __, infer ___> ? VectorValue :\n T extends SchemaArray<infer Y, infer __> ? InferPrimitive<Y>[]\n : T extends SchemaObject<infer Obj, infer _> ?\n { [K in keyof Obj]: InferPrimitive<Obj[K]> } : // Process nested objects\n T extends SchemaFunction<infer F, infer __> ? F : T extends SchemaBase<infer X, infer _> ?\n X extends Array<infer A> ? InferPrimitive<A>[] : X : // Extract the primitive type\n never;\n\nexport type InferType<T> = T extends CompiledSchema<infer R> ? InferCompiledSchema<R> : T extends {} ? InferCompiledSchema<T> : T;\nexport type InferCreateType<T> = T extends CompiledSchema<infer R> ? InferCompiledCreateSchema<R> : T extends {} ? InferCompiledCreateSchema<T> : unknown;\nexport type InferMappedType<T> = T extends SchemaBase<infer K, infer __> ? InferType<K> : InferCompiledSchema<T>;\nexport type InferRoot<T> = T extends CompiledSchema<infer R> ? R : never;\n\ntype HasModifier<T, K extends keyof T, M extends SchemaModifiers> =\n T[K] extends SchemaBase<any, infer Mods> ?\n M extends Mods ? true : false :\n false;\n\ntype IsPlainProperty<T, K extends keyof T> =\n [\n HasModifier<T, K, \"readonly\">,\n HasModifier<T, K, \"optional\">,\n HasModifier<T, K, \"nullable\">\n ] extends [\n false,\n false,\n false\n ] ? true : false;\n\ntype IsCreateExcluded<T, K extends keyof T> =\n [\n HasModifier<T, K, \"identity\">,\n HasModifier<T, K, \"computed\">,\n HasModifier<T, K, \"unmapped\">\n ] extends [\n false,\n false,\n false\n ] ? false : true;\n\ntype IsCreateOptional<T, K extends keyof T> =\n [\n HasModifier<T, K, \"optional\">,\n HasModifier<T, K, \"default\">\n ] extends [\n false,\n false\n ] ? false : true;\n\ntype IsCreateNullable<T, K extends keyof T> =\n HasModifier<T, K, \"nullable\"> extends true ? true : false;\n\n/**\n * What a property ACCEPTS on the way in, which is not always what it gives back.\n *\n * Only a file differs today: you assign content and read a reference. Matching on the read\n * type rather than on `SchemaFile` itself is deliberate — it keeps working through every\n * modifier. `s.file().optional()` is a `SchemaOptional`, `s.file().tag('x')` is a\n * `SchemaTag`, and neither carries the original class, so a check against the class alone\n * would silently stop accepting content the moment anyone added a modifier.\n *\n * Assignability is required in BOTH directions, and the tuple wrappers are load-bearing.\n * One-way `extends` matches `never` — which is assignable to everything — so a generic\n * property over `Record<string, unknown>` resolved to file content and broke the Dexie\n * plugin's types. It also matched any object that merely happens to have these five fields\n * plus more. Mutual assignability admits the reference shape and nothing else, and the\n * tuples stop the conditional distributing over a union.\n */\ntype InferWritePrimitive<T> =\n [InferPrimitive<T>] extends [FileReferenceValue]\n ? [FileReferenceValue] extends [InferPrimitive<T>] ? FileContentValue : InferPrimitive<T>\n : InferPrimitive<T>;\n\ntype InferCreateProperty<T, K extends keyof T> =\n IsCreateNullable<T, K> extends true ? null | InferWritePrimitive<T[K]> : InferWritePrimitive<T[K]>;\n\ntype InferCompiledSchema<T> = CoalesceEmpty<{\n [K in keyof T as IsPlainProperty<T, K> extends true ? K : never]: InferPrimitive<T[K]>\n}, {\n readonly [K in keyof T as HasModifier<T, K, \"readonly\"> extends true ? K : never]: InferPrimitive<T[K]>\n }, {\n [K in keyof T as HasModifier<T, K, \"optional\"> extends true ? K : never]?: InferPrimitive<T[K]>\n }, {\n [K in keyof T as HasModifier<T, K, \"nullable\"> extends true ? K : never]: null | InferPrimitive<T[K]>\n}>;\n\ntype InferCompiledCreateSchema<T> = {\n [K in keyof T as IsCreateExcluded<T, K> extends true ? never\n : IsCreateOptional<T, K> extends true ? K : never]?: InferCreateProperty<T, K>\n} & {\n [K in keyof T as IsCreateExcluded<T, K> extends true ? never\n : IsCreateOptional<T, K> extends true ? never : K]: InferCreateProperty<T, K>\n};\n\ntype IsEmptyObject<T> = keyof T extends never ? true : false;\ntype CoalesceEmpty<T1 extends {}, T2 extends {}, T3 extends {}, T4 extends {}> = (IsEmptyObject<T1> extends true ? {} : T1) & (IsEmptyObject<T2> extends true ? {} : T2) & (IsEmptyObject<T3> extends true ? {} : T3) & (IsEmptyObject<T4> extends true ? {} : T4);\n","export const isDate = (data: unknown): data is Date => {\n if (data == null) {\n return false;\n }\n\n if (typeof data !== \"object\") {\n return false;\n }\n\n return data instanceof Date;\n}","/**\n * Levelled logging, resolved once.\n *\n * Three things about the previous implementation drove this shape:\n *\n * - **There was no way to turn logging off.** `globalThis.__ROUTIER_DEBUG__` was only ever\n * compared against `true`, so setting it to `false` did nothing — while\n * `docs/how-to/debug-logging.md` documented exactly that as the way to force logging off.\n * A documented switch that silently does nothing is worse than no switch.\n * - **`NODE_ENV === 'test'` enabled it.** Every Jest run therefore logged, because Jest always\n * sets `NODE_ENV=test`. Measured on the S7 stress scenario, which drives ~2,000 saves through\n * a plugin that logs three lines per query: 12.4s with logging, ~6s without. Test runners also\n * capture console output by snapshotting a stack trace per call, so the cost is far above what\n * writing to a terminal would suggest — and the output buries whatever the failure was.\n * - **It was all-or-nothing, and re-resolved per call.** An error could not be kept while debug\n * was dropped, and every one of the ~97 call sites re-read `globalThis` and `process.env`.\n *\n * Levels are compared numerically against a value cached at module load. Measured against a\n * no-op console at 200k calls: an enabled call costs ~70ns, a call rejected by the gate ~3ns.\n * Building the arguments the call site passes in accounts for ~0.2ns of that 3ns, which is why\n * this keeps the ordinary `logger.debug(msg, payload)` signature instead of taking a thunk —\n * a lazy API would recover 0.3% of an enabled call's cost and would have to change every call\n * site to do it.\n */\n\n/** Ordered from most severe to most verbose. `silent` discards everything. */\nexport const LOG_LEVELS = ['silent', 'error', 'warn', 'info', 'debug'] as const;\n\nexport type LogLevel = (typeof LOG_LEVELS)[number];\n\n/** Numeric rank, so a gate is one integer comparison. */\nconst RANK: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n};\n\nconst isLogLevel = (value: unknown): value is LogLevel =>\n typeof value === 'string' && (LOG_LEVELS as readonly string[]).includes(value);\n\n/**\n * Resolves the configured level, in precedence order.\n *\n * Ordered most specific first: an explicit level beats a boolean flag, a boolean flag beats an\n * environment variable, and an environment variable beats an inference from `NODE_ENV`. Anything\n * unrecognised is ignored rather than treated as an error — a typo'd level should not take down\n * an application, and `silent` is the safe direction to fall back to.\n */\nconst resolveLevel = (): LogLevel => {\n if (typeof globalThis !== 'undefined') {\n const g = globalThis as { __ROUTIER_LOG_LEVEL__?: unknown; __ROUTIER_DEBUG__?: unknown };\n\n if (isLogLevel(g.__ROUTIER_LOG_LEVEL__)) {\n return g.__ROUTIER_LOG_LEVEL__;\n }\n\n // Both directions honoured. `=== false` used to fall through to the NODE_ENV checks\n // below and re-enable the logging it was asked to suppress.\n if (g.__ROUTIER_DEBUG__ === true) return 'debug';\n if (g.__ROUTIER_DEBUG__ === false) return 'silent';\n }\n\n // There is deliberately no `import.meta.env` branch, although the documentation used to\n // promise one. It could never work: this package is bundled with rspack, which replaces\n // `import.meta` with `undefined`, so the check would read the *library's* build-time\n // environment rather than the application's — and referencing `import.meta` at all is a parse\n // error under a CommonJS build target, which is how the test suite loads this file. Vite and\n // similar apps set `__ROUTIER_LOG_LEVEL__` or `__ROUTIER_DEBUG__` from their own\n // `import.meta.env`, which is what the docs now describe.\n if (typeof process !== 'undefined' && process.env != null) {\n if (isLogLevel(process.env.ROUTIER_LOG_LEVEL)) {\n return process.env.ROUTIER_LOG_LEVEL as LogLevel;\n }\n\n const debug = process.env.DEBUG;\n if (debug === 'routier' || debug === '*') return 'debug';\n\n const env = process.env.NODE_ENV?.toLowerCase();\n\n // `test` is deliberately absent. It used to be here, which meant no test suite anywhere\n // could run Routier quietly. Opt in with DEBUG=routier or ROUTIER_LOG_LEVEL when a test\n // needs the output.\n if (env === 'dev' || env === 'development') return 'debug';\n }\n\n return 'silent';\n};\n\nlet level: LogLevel = resolveLevel();\nlet rank = RANK[level];\n\n/**\n * Overrides the level for the rest of the process.\n *\n * The configuration above is read once, at import, which is what makes the gate cheap — but it\n * also means an application that decides its verbosity after startup, or a test that wants to\n * assert on output, has no way in. This is that way in.\n */\nexport const setLogLevel = (next: LogLevel): void => {\n if (isLogLevel(next) === false) {\n throw new Error(`Unknown log level \"${next}\". Expected one of: ${LOG_LEVELS.join(', ')}`);\n }\n\n level = next;\n rank = RANK[next];\n};\n\nexport const getLogLevel = (): LogLevel => level;\n\n/** Re-reads the environment. For tests that change it after this module was imported. */\nexport const resetLogLevel = (): void => {\n level = resolveLevel();\n rank = RANK[level];\n};\n\n/**\n * Whether a message at this level would be emitted.\n *\n * For the rare call site whose *arguments* are expensive to build — a serialization, a deep\n * clone, a join over a large collection. An ordinary payload object is not worth guarding; see\n * the measurement in the header.\n */\nexport const isLogLevelEnabled = (at: LogLevel): boolean => rank >= RANK[at];\n\ntype ConsoleMethod = 'log' | 'info' | 'warn' | 'error' | 'debug' | 'table';\n\nconst emit = (at: LogLevel, method: ConsoleMethod, args: unknown[]) => {\n if (rank < RANK[at]) {\n return;\n }\n\n // Resolved at call time rather than captured once: test harnesses and browser devtools both\n // replace console methods after modules have loaded, and a captured reference would keep\n // writing past the replacement.\n (console[method] as (...a: unknown[]) => void)(...args);\n};\n\nexport const logger = {\n /** General-purpose output. Carried at `info`, since `log` names a console method, not a level. */\n log: (...args: unknown[]): void => emit('info', 'log', args),\n info: (...args: unknown[]): void => emit('info', 'info', args),\n warn: (...args: unknown[]): void => emit('warn', 'warn', args),\n error: (...args: unknown[]): void => emit('error', 'error', args),\n debug: (...args: unknown[]): void => emit('debug', 'debug', args),\n /** Diagnostic tabular output; verbose by nature, so it sits at `debug`. */\n table: (...args: unknown[]): void => emit('debug', 'table', args),\n};\n","export const uuid = (length: number = 16): string => {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n const charLength = chars.length;\n let result = '';\n\n for (let i = 0; i < length; i++) {\n result += chars[Math.random() * charLength | 0];\n }\n return result;\n}\n\nconst HEX_CHARS = '0123456789abcdef';\nconst UUID_TEMPLATE = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';\n\nconst hasCrypto =\n typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function';\n\nconst hasRandomUUID =\n typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function';\n\nexport const uuidv4 = (): string => {\n if (hasRandomUUID) {\n return crypto.randomUUID();\n }\n\n return uuidv4Fallback();\n};\n\nconst uuidv4Fallback = (): string => {\n let randomBytes: Uint8Array | null = null;\n if (hasCrypto) {\n randomBytes = crypto.getRandomValues(new Uint8Array(16));\n }\n\n let byteIndex = 0;\n let uuid = '';\n\n for (let i = 0; i < UUID_TEMPLATE.length; i++) {\n const c = UUID_TEMPLATE[i];\n if (c === '-') {\n uuid += '-';\n continue;\n }\n\n let r: number;\n if (hasCrypto && randomBytes) {\n // Each byte gives two hex digits (nibbles)\n r =\n (i % 2 === 0\n ? randomBytes[byteIndex] >> 4\n : randomBytes[byteIndex++] & 0x0f);\n } else {\n r = Math.floor(Math.random() * 16);\n }\n\n if (c === 'x') {\n uuid += HEX_CHARS[r];\n } else if (c === 'y') {\n // Variant bits: 8, 9, A, or B\n uuid += HEX_CHARS[(r & 0x3) | 0x8];\n } else if (c === '4') {\n uuid += '4';\n }\n }\n\n return uuid;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { ITranslatedValue } from './types';\n\nexport class TranslatedArrayValue<T> implements ITranslatedValue<T> {\n\n readonly value: T;\n readonly isTransformed: boolean;\n readonly isEmpty: boolean;\n\n constructor(value: unknown, isTransformed: boolean) {\n this.value = value as T;\n this.isEmpty = value == null || (Array.isArray(value) && value.length === 0);\n this.isTransformed = isTransformed;\n }\n\n forEach(callback: (item: unknown) => unknown): void {\n const data = this.value as unknown[];\n for (let i = 0, length = data.length; i < length; i++) {\n const result = callback(data[i]);\n\n if (result) {\n // reassign if the callback returns a result\n data[i] = result;\n }\n }\n }\n}","import { ITranslatedValue } from './types';\n\nexport class TranslatedGroupValue<T> implements ITranslatedValue<T> {\n\n readonly value: T;\n readonly isTransformed: boolean;\n readonly isEmpty: boolean;\n\n constructor(value: unknown, isTransformed: boolean) {\n this.value = value as T;\n this.isEmpty = value == null;\n this.isTransformed = isTransformed;\n }\n\n forEach(callback: (item: unknown) => unknown): void {\n const group = this.value as Record<string, unknown[]>;\n const keys = Object.keys(group);\n for (let i = 0, length = keys.length; i < length; i++) {\n const key = keys[i];\n const data = group[key];\n\n for (let j = 0, len = data.length; j < len; j++) {\n\n const result = callback(data[j]);\n\n if (result) {\n // reassign if the callback returns a result\n data[j] = result;\n }\n }\n }\n }\n}","import { ITranslatedValue } from './types';\n\nexport class TranslatedSingleValue<T> implements ITranslatedValue<T> {\n\n value: T;\n readonly isTransformed: boolean;\n readonly isEmpty: boolean;\n\n constructor(value: unknown, isTransformed: boolean) {\n this.value = value as T;\n this.isEmpty = value == null;\n this.isTransformed = isTransformed;\n }\n\n forEach(callback: (item: unknown) => unknown): void {\n const result = callback(this.value) as T;\n\n if (result) {\n this.value = result;\n }\n }\n}","import { QueryOption, QueryOptionName } from \"../query/types\";\nimport { IQuery } from \"../types\";\nimport { TranslatedArrayValue } from \"./TranslatedArrayValue\";\nimport { TranslatedGroupValue } from \"./TranslatedGroupValue\";\nimport { TranslatedSingleValue } from \"./TranslatedSingleValue\";\nimport { ITranslatedValue } from \"./types\";\n\nexport abstract class DataTranslator<TRoot extends {}, TShape> {\n\n protected query: IQuery<TRoot, TShape>;\n private functionMap: Record<QueryOptionName, (data: unknown, option: QueryOption<any, any>) => TShape> = {\n count: (data: unknown, option: QueryOption<TShape, \"count\">) => this.count<any>(data, option),\n distinct: (data: unknown, option: QueryOption<TShape, \"distinct\">) => this.distinct(data, option),\n filter: (data: unknown, option: QueryOption<TShape, \"filter\">) => this.filter(data, option),\n map: (data: unknown, option: QueryOption<TShape, \"map\">) => this.map(data, option),\n max: (data: unknown, option: QueryOption<TShape, \"max\">) => this.max<any>(data, option),\n min: (data: unknown, option: QueryOption<TShape, \"min\">) => this.min<any>(data, option),\n skip: (data: unknown, option: QueryOption<TShape, \"skip\">) => this.skip(data, option),\n sort: (data: unknown, option: QueryOption<TShape, \"sort\">) => this.sort(data, option),\n sum: (data: unknown, option: QueryOption<TShape, \"sum\">) => this.sum<any>(data, option),\n take: (data: unknown, option: QueryOption<TShape, \"take\">) => this.take(data, option),\n group: (data: unknown, option: QueryOption<TShape, \"group\">) => this.group(data, option),\n nearest: (data: unknown, option: QueryOption<TShape, \"nearest\">) => this.nearest(data, option),\n join: (data: unknown, option: QueryOption<TShape, \"join\">) => this.join(data, option)\n };\n\n constructor(query: IQuery<TRoot, TShape>) {\n this.query = query;\n }\n\n // Terminators\n abstract count<TResult extends number>(data: unknown, option: QueryOption<TShape, \"count\">): TResult;\n abstract min<TResult extends string | number | Date>(data: unknown, option: QueryOption<TShape, \"min\">): TResult;\n abstract max<TResult extends string | number | Date>(data: unknown, option: QueryOption<TShape, \"max\">): TResult;\n abstract sum<TResult extends number>(data: unknown, option: QueryOption<TShape, \"sum\">): TResult;\n abstract distinct<TResult>(data: unknown, option: QueryOption<TShape, \"distinct\">): TResult;\n\n // Shapers\n abstract filter<TResult>(data: unknown, option: QueryOption<TShape, \"filter\">): TResult;\n abstract skip(data: unknown, option: QueryOption<TShape, \"skip\">): TShape;\n abstract take(data: unknown, option: QueryOption<TShape, \"take\">): TShape;\n abstract sort(data: unknown, option: QueryOption<TShape, \"sort\">): TShape;\n abstract map(data: unknown, option: QueryOption<TShape, \"map\">): TShape;\n abstract group(data: unknown, option: QueryOption<TShape, \"group\">): TShape;\n /**\n * Abstract on purpose, unlike the pass-throughs a storage translator can usually inherit.\n *\n * Every other shaper degrades safely when a backend ignores it — an unsorted result is\n * still the right rows. A similarity search is not: it is the only option whose value is\n * ENTIRELY in the ordering and the limit, so a translator that quietly passes the data\n * through returns every row in insertion order and calls it the ten nearest.\n *\n * Requiring an answer here means a new translator cannot be written without deciding\n * whether its backend performed the search, and the compiler asks the question.\n */\n abstract nearest(data: unknown, option: QueryOption<TShape, \"nearest\">): TShape;\n\n /**\n * Abstract for the same reason as `nearest`, one step further.\n *\n * A translator that quietly passed a join through would not return an unsorted or unlimited\n * result — it would return the OUTER rows, one object each where the contract says tuples,\n * and every `([outer, inner]) => ...` lambda downstream would destructure the outer entity\n * instead. Nothing errors; the answer is simply a different query's answer.\n *\n * So the compiler asks the question. Every translator must state how its backend joins:\n * natively (pass through the rows the SQL already paired), in memory (the shared hash join\n * over rows the plugin supplies), or not at all (throw, loudly, naming the backend).\n *\n * The output contract, whichever answer: an array of `[outer, inner]` tuples, each half\n * fully deserialized into its OWN schema's entity shape.\n */\n abstract join(data: unknown, option: QueryOption<TShape, \"join\">): TShape;\n\n translate(data: unknown): ITranslatedValue<TShape> {\n\n const isTransformed = this.query.options.hasTransformations();\n\n this.query.options.forEach(item => {\n data = this.functionMap[item.name](data, item);\n });\n\n if (Array.isArray(data)) {\n return new TranslatedArrayValue<TShape>(data, isTransformed);\n }\n\n if (this.query.options.has(\"group\")) {\n return new TranslatedGroupValue<TShape>(data, isTransformed);\n }\n\n return new TranslatedSingleValue<TShape>(data, isTransformed);\n }\n}","import { logger } from \"../../utilities\";\n\n/**\n * Cosine distance, and the ordering rules that go with it.\n *\n * One implementation, shared by every in-memory path, because the promise the feature makes\n * is that a backend with no vector support returns the SAME ROWS IN THE SAME ORDER as one\n * that pushes the search down. Two copies of this arithmetic would drift, and the drift would\n * only ever show up as a conformance failure nobody could localise.\n *\n * The tie-breaking and degenerate cases below are chosen to match pgvector rather than to be\n * independently reasonable — parity is the point.\n */\n\n/**\n * Distance in `[0, 2]`, or `Infinity` for a value that cannot be compared.\n *\n * `Infinity` covers three cases, and they all sort LAST, which is what PostgreSQL does too:\n * a missing value (`NULL` sorts last under `ASC` by default), a zero-magnitude vector\n * (pgvector's `<=>` yields `NaN`, which PostgreSQL orders after every real number), and a\n * stored vector of the wrong width.\n *\n * The width case cannot happen on a native `vector(n)` column — the engine rejects the write —\n * so it only arises on a backend storing JSON, where the data was written by something other\n * than this schema. Sorting it last rather than throwing keeps one corrupt row from failing a\n * query that is otherwise answerable.\n */\nexport const cosineDistance = (left: readonly number[] | null | undefined, right: readonly number[]): number => {\n if (left == null || left.length !== right.length) {\n return Infinity;\n }\n\n let dot = 0;\n let leftMagnitude = 0;\n let rightMagnitude = 0;\n\n for (let i = 0, length = right.length; i < length; i++) {\n const l = left[i];\n const r = right[i];\n\n dot += l * r;\n leftMagnitude += l * l;\n rightMagnitude += r * r;\n }\n\n if (leftMagnitude === 0 || rightMagnitude === 0) {\n return Infinity;\n }\n\n return 1 - (dot / (Math.sqrt(leftMagnitude) * Math.sqrt(rightMagnitude)));\n};\n\n/**\n * The `count` rows closest to `vector`, nearest first.\n *\n * Distances are computed once per row rather than inside the comparator: a comparison-time\n * computation runs O(n log n) times over vectors that are commonly 1536 wide, which turns an\n * ordering into the dominant cost of the query.\n *\n * The sort is stable, so rows at equal distance keep the order the backend returned them in.\n * That is not a guarantee worth relying on across backends — two engines can hand back the\n * same rows in different orders — but it does mean this function never introduces a\n * difference of its own.\n */\nexport const nearestBy = <T>(\n rows: readonly T[],\n vector: number[],\n count: number,\n select: (row: T) => readonly number[] | null | undefined\n): T[] => {\n if (count <= 0) {\n return [];\n }\n\n /**\n * Rows whose stored vector is the wrong width, counted so the query can say so once.\n *\n * `cosineDistance` already handles them safely — they score `Infinity` and sort last, the\n * way PostgreSQL orders `NULL` — and that is deliberately not an error, because one corrupt\n * row must not fail a query that is otherwise answerable.\n *\n * The problem is that it is also SILENT. A row written at the wrong width is never returned\n * by any search and never reported by one, so an embedding model that changed its output\n * size degrades results steadily with nothing to notice. Counting costs a length comparison\n * per row against a vector that is commonly 1536 wide, and the warning is emitted once per\n * query rather than once per row.\n */\n let mismatched = 0;\n\n const scored = rows.map((row, index) => {\n const stored = select(row);\n\n if (stored != null && stored.length !== vector.length) {\n mismatched++;\n }\n\n return { row, index, distance: cosineDistance(stored, vector) };\n });\n\n if (mismatched > 0) {\n logger.warn(\n `nearest(): ${mismatched} of ${rows.length} stored vectors are not ${vector.length} wide, ` +\n `so they cannot be scored and sort last. They will never be returned by a search. ` +\n `This usually means the rows were written with a different embedding model.`\n );\n }\n\n scored.sort((a, b) => {\n if (a.distance === b.distance) {\n // Infinity === Infinity, so unscoreable rows fall through to insertion order\n // rather than to `Infinity - Infinity`, which is NaN and would leave the\n // comparator inconsistent — V8 is free to produce any permutation from that.\n return a.index - b.index;\n }\n\n return a.distance - b.distance;\n });\n\n return scored.slice(0, count).map(x => x.row);\n};\n","\nimport { CompiledSchema } from '../../schema';\nimport { IQuery } from '../types';\nimport { QueryOptionsCollection } from './QueryOptionsCollection';\n\nexport class Query<TRoot extends {}, TShape> implements IQuery<TRoot, TShape> {\n\n readonly options: QueryOptionsCollection<TShape>;\n readonly schema: CompiledSchema<TRoot>;\n private enableChangeTrackingOverride?: boolean\n\n constructor(\n options: QueryOptionsCollection<TShape>,\n schema: CompiledSchema<TRoot>,\n enableChangeTrackingOverride?: boolean,\n ) {\n this.schema = schema;\n this.options = options;\n this.enableChangeTrackingOverride = enableChangeTrackingOverride;\n }\n\n // boolean value whether or not change tracking can be enabled on the query result\n get changeTracking(): boolean {\n\n if (this.enableChangeTrackingOverride != null) {\n return this.enableChangeTrackingOverride;\n }\n\n const map = this.options.getValues(\"map\");\n const count = this.options.has(\"count\");\n const max = this.options.has(\"max\");\n const min = this.options.has(\"min\");\n const sum = this.options.has(\"sum\");\n\n if (map.some(x => x.fields.length > 0)) {\n return false\n }\n\n // A join returns TUPLES, not entities of this query's root schema. Attaching one would\n // hand the change tracker a two-element array to find an id on, and freezing or\n // membership-capturing it means reading the root schema's id off something that has no\n // properties at all. Join results are read-only projections, like `.map()` results.\n if (this.options.has(\"join\")) {\n return false;\n }\n\n if (count === true ||\n max === true ||\n min === true ||\n sum === true) {\n return false\n }\n\n return true;\n }\n\n static EMPTY<T extends {}, S>(schema: CompiledSchema<T>) {\n return new Query<T, S>(QueryOptionsCollection.EMPTY<S>(), schema);\n }\n\n static isEmpty<T extends {}, S>(query: IQuery<T, S>) {\n return QueryOptionsCollection.isEmpty(query.options);\n }\n\n static toString<TRoot extends {}, TShape>(query: IQuery<TRoot, TShape>) {\n return JSON.stringify({\n options: query.options.items,\n schema: {\n id: query.schema.id,\n collectionName: query.schema.collectionName\n },\n changeTracking: query.changeTracking\n })\n }\n}","import { CompiledSchemaCore, InferType, PropertyInfo } from \"../../schema\";\nimport { ComparatorExpression, Expression, ParamsFilter, PropertyExpression, ValueExpression } from \"../../expressions\";\nimport { UnknownRecord } from \"../../utilities\";\nimport { PluginEventCallbackResult, PluginEventResult } from \"../../results\";\nimport type { DbPluginQueryEvent } from \"../types\";\nimport type { ITranslatedValue } from \"../translators/types\";\nimport { TranslatedArrayValue } from \"../translators/TranslatedArrayValue\";\nimport { Query } from \"./Query\";\nimport { QueryOptionsCollection } from \"./QueryOptionsCollection\";\nimport { QueryOptionValueMap } from \"./types\";\n\nexport type JoinKind = \"inner\" | \"left\";\n\n/**\n * One side's join key, as a property path plus the resolved property.\n *\n * The path is what survives serialization; the `PropertyInfo` is the live handle that reads\n * the value and resolves a `from`-renamed storage name. Both, because a key read has to work\n * on either side of the wire.\n */\nexport type JoinKeyReference = {\n propertyName: string;\n property: PropertyInfo<any> | null;\n};\n\nexport type JoinQueryOptionValue = QueryOptionValueMap<any>[\"join\"];\n\n/**\n * The inner side of a join, as the PLUGIN sees it.\n *\n * Supplied by the plugin rather than fetched by the translator, because loading rows is the one\n * part of a join that is backend-specific: a memory plugin resolves a collection, Dexie opens a\n * store, Mongo reads a collection. Everything after that — deserializing, applying the inner\n * scopes, pairing — is identical, so it lives here and runs once.\n *\n * Rows arrive in STORAGE shape, exactly as the plugin holds them; the translator deserializes\n * them with `innerSchema`, which the outer query's own deserialization would never do.\n */\nexport type JoinInnerSide = {\n innerSchema: CompiledSchemaCore<any>;\n innerRows: readonly unknown[];\n};\n\n/**\n * `undefined` when the query has no join at all, which is the common case and not an error.\n */\nexport type JoinInnerSideResult =\n | { ok: \"success\"; innerSide?: JoinInnerSide }\n | { ok: \"error\"; error: unknown };\n\n/**\n * A joined pair, each half fully deserialized into its own schema's ENTITY shape.\n *\n * The wire contract for every interpretation of a join: a native SQL join, an in-plugin hash\n * join, and the datastore's cross-plugin join all produce exactly this. Flat combined rows\n * never leave a translator — see `specs/joins.md`.\n */\nexport type JoinTuple = [UnknownRecord, UnknownRecord | undefined];\n\n/**\n * Turns storage-shape records into entity-shape values, one side of a join at a time.\n *\n * The inner side does NOT pass through the outer query's normal deserialization —\n * `DatabaseDataAccessStrategy.query` transforms against the outer schema only — so each side\n * is deserialized with its own schema here, which is what makes the two halves of a tuple\n * readable by the same property names the caller wrote in the selectors.\n *\n * `\"diff\"` rather than `\"proxy\"`: join results are read-only projections and never attach to\n * the change tracker, so there is nothing for a tracking proxy to record.\n */\nexport const toEntityShape = (schema: CompiledSchemaCore<any>, rows: readonly unknown[]): UnknownRecord[] => {\n const result: UnknownRecord[] = Array.from({ length: rows.length });\n\n for (let i = 0, length = rows.length; i < length; i++) {\n result[i] = schema.postprocess(rows[i] as InferType<any>, \"diff\") as UnknownRecord;\n }\n\n return result;\n};\n\n/**\n * Reads a join key off an entity-shape row.\n *\n * Through the `PropertyInfo` when there is one, so a nested path (`a.b.id`) resolves the same\n * way every other option resolves it. The string fallback exists for an option that crossed a\n * wire without its schema; it walks the same path by name.\n */\nexport const readJoinKey = (row: UnknownRecord | undefined, reference: JoinKeyReference): unknown => {\n if (row == null) {\n return null;\n }\n\n if (reference.property != null) {\n return reference.property.getValue(row);\n }\n\n const path = reference.propertyName.split(\".\");\n let current: unknown = row;\n\n for (let i = 0, length = path.length; i < length; i++) {\n if (current == null) {\n return null;\n }\n\n current = (current as UnknownRecord)[path[i]];\n }\n\n return current;\n};\n\n/**\n * Whether a key value can participate in a match at all.\n *\n * `null`/`undefined` never match anything (semantics table in `specs/joins.md`), and `NaN` is\n * excluded for a subtler reason: a `Map` compares keys by SameValueZero, under which `NaN`\n * equals itself, while the specified comparison is strict `===`, under which it does not. A\n * `NaN` key that matched here would be the one value where the in-memory hash join and a SQL\n * join disagree.\n */\nconst isMatchableKey = (value: unknown): boolean => {\n if (value == null) {\n return false;\n }\n\n return typeof value !== \"number\" || Number.isNaN(value) === false;\n};\n\n/**\n * Applies an inner side's own filters to its rows.\n *\n * **This is the correctness trap of the whole feature.** Every interpretation of a join\n * bypasses the inner collection's normal datastore read path, so the inner side's soft-delete\n * scope and `.scope()` filters exist ONLY because `innerOptions` carries them. An interpreter\n * that skips this returns soft-deleted rows.\n *\n * Filters only. Nothing else reaches `innerOptions` today — scopes are filters — and applying\n * a `skip`/`take` recorded against the inner collection to the rows feeding a join would\n * change which pairs exist rather than which rows are visible.\n */\nexport const applyInnerOptions = (rows: UnknownRecord[], innerOptions: QueryOptionsCollection<any>): UnknownRecord[] => {\n let filtered = rows;\n\n for (const { option } of innerOptions.get(\"filter\")) {\n const { filter, params } = option.value;\n\n if (filter == null) {\n continue;\n }\n\n if (params == null) {\n filtered = filtered.filter(filter as (row: unknown) => boolean);\n continue;\n }\n\n const selector = filter as ParamsFilter<unknown, {}>;\n filtered = filtered.filter(row => selector([row, params]));\n }\n\n return filtered;\n};\n\n/**\n * The join itself: one hash join, written once, called from every interpreter.\n *\n * O(n + m) rather than a nested loop, which is the whole reason the API takes explicit key\n * selectors instead of a free-form predicate. Both key properties are `string` or `number` by\n * a build-time rule, so the keys are hashable and compare the same way in JS and in SQL.\n *\n * Semantics, exactly as `specs/joins.md` states them:\n *\n * - **Null keys** never match. Under `left` the outer row still appears, paired with\n * `undefined`.\n * - **Duplicates** produce every pair: the full cross product per key group.\n * - **Ordering** is outer order, then inner order within a key group. Undefined by contract —\n * a caller who cares sorts.\n */\nexport const hashJoin = (options: {\n kind: JoinKind;\n outerRows: UnknownRecord[];\n innerRows: UnknownRecord[];\n outerKey: JoinKeyReference;\n innerKey: JoinKeyReference;\n}): JoinTuple[] => {\n const { kind, outerRows, innerRows, outerKey, innerKey } = options;\n const isLeft = kind === \"left\";\n\n const buckets = new Map<unknown, UnknownRecord[]>();\n\n for (let i = 0, length = innerRows.length; i < length; i++) {\n const row = innerRows[i];\n const key = readJoinKey(row, innerKey);\n\n if (isMatchableKey(key) === false) {\n continue;\n }\n\n const bucket = buckets.get(key);\n\n if (bucket == null) {\n buckets.set(key, [row]);\n continue;\n }\n\n bucket.push(row);\n }\n\n const tuples: JoinTuple[] = [];\n\n for (let i = 0, length = outerRows.length; i < length; i++) {\n const outer = outerRows[i];\n const key = readJoinKey(outer, outerKey);\n const matches = isMatchableKey(key) ? buckets.get(key) : undefined;\n\n if (matches == null) {\n if (isLeft) {\n tuples.push([outer, undefined]);\n }\n\n continue;\n }\n\n for (let j = 0, matchLength = matches.length; j < matchLength; j++) {\n tuples.push([outer, matches[j]]);\n }\n }\n\n return tuples;\n};\n\n/**\n * How many distinct outer keys are still worth turning into an `IN (...)` prefilter.\n *\n * A cost decision, never a correctness one: above the threshold the inner side is read under its\n * own scopes and the hash join discards the surplus, which is the same answer by a slower route.\n * 500 because a bound-parameter list is cheap in the hundreds and starts costing more than the\n * scan it saves in the thousands — and some engines refuse a list that long outright.\n */\nexport const DEFAULT_SEMI_JOIN_KEY_THRESHOLD = 500;\n\n/**\n * The distinct join keys of the outer rows, or `null` when there are too many to be worth sending.\n *\n * `null` means \"do not prefilter\", not \"no keys\" — an empty SET is a real answer meaning the inner\n * side cannot match anything.\n *\n * @param column The key's STORAGE column name when `rows` are storage-shaped, or its property name\n * when they are entity-shaped. The caller knows which it holds.\n */\nexport const distinctJoinKeys = (\n rows: readonly UnknownRecord[],\n reference: JoinKeyReference,\n threshold: number = DEFAULT_SEMI_JOIN_KEY_THRESHOLD,\n options?: { storageShape?: boolean }\n): Set<unknown> | null => {\n const keys = new Set<unknown>();\n\n const read = options?.storageShape === true\n ? (row: UnknownRecord) => row[reference.property?.getResolvedName() ?? reference.propertyName]\n : (row: UnknownRecord) => readJoinKey(row, reference);\n\n for (const row of rows) {\n const key = read(row);\n\n // A null key matches nothing, so it never belongs in the prefilter — and including it\n // would widen the inner read to rows that cannot pair.\n if (isMatchableKey(key) === false) {\n continue;\n }\n\n keys.add(key);\n\n if (keys.size > threshold) {\n return null;\n }\n }\n\n return keys;\n};\n\n/**\n * A filter restricting the inner side to rows whose key is one the outer side actually has.\n *\n * Built as an expression tree by hand rather than parsed from generated source, for the reason\n * `softDeleteScope` gives: generating source needs `new Function`, which a Content-Security-Policy\n * blocks, and the shape is known here so there is nothing to parse. An `includes` comparator over\n * an array value is what every translator already turns into `IN (...)` or `$in`, so this pushes\n * down on the backends that can take it and runs as the closure on the ones that cannot.\n *\n * Cost only. Every pair it removes from the inner read is one the hash join would have discarded.\n */\nexport const semiJoinFilter = (\n reference: JoinKeyReference,\n keys: ReadonlySet<unknown>\n): QueryOptionValueMap<any>[\"filter\"] => {\n const values = [...keys];\n const propertyName = reference.propertyName;\n\n const expression = reference.property == null\n ? Expression.NOT_PARSABLE\n : new ComparatorExpression({\n comparator: \"includes\",\n negated: false,\n strict: true,\n left: new ValueExpression({ value: values }),\n right: new PropertyExpression({ property: reference.property }),\n });\n\n // Read through the PropertyInfo when there is one so a nested path resolves; the Set is closed\n // over rather than rebuilt per row.\n const read = reference.property != null\n ? (row: UnknownRecord) => reference.property!.getValue(row)\n : (row: UnknownRecord) => readJoinKey(row, { propertyName, property: null });\n\n return {\n filter: ((row: UnknownRecord) => keys.has(read(row))) as never,\n expression,\n params: undefined\n };\n};\n\n/**\n * Loads a join's inner side by asking the plugin to run an ORDINARY query for it.\n *\n * The generic way for a plugin to interpret a join — one call, no join-specific reading code.\n * The inner side is just \"this collection, under these filters\", which is a query every plugin\n * already knows how to answer, through whatever indexes and scoping it normally applies.\n *\n * Only the DATABASE half of `innerOptions` is sent. The memory half would mean nothing to the\n * plugin, and `executeJoin` re-applies every filter regardless — filters are pure, so the second\n * pass costs a walk over the survivors and guarantees the inner scopes are honoured even if the\n * plugin silently ignored them.\n *\n * The inner query carries no `join` option of its own, so this cannot recurse.\n *\n * @param query How this plugin runs a query. **Not necessarily `plugin.query`**: a plugin that\n * serializes queries through a work queue must pass its UN-QUEUED path, or this call waits behind\n * the outer query that is still holding the queue and the plugin deadlocks.\n */\nexport const loadJoinInnerSide = <TRoot extends {}, TShape>(\n event: DbPluginQueryEvent<TRoot, TShape>,\n query: (innerEvent: DbPluginQueryEvent<UnknownRecord, UnknownRecord>, done: PluginEventCallbackResult<ITranslatedValue<UnknownRecord>>) => void,\n done: (result: JoinInnerSideResult) => void,\n /**\n * The outer side's distinct keys, when the caller already has them.\n *\n * Only a plugin that runs its outer query FIRST can supply these, and most run this loader\n * before anything else — so it is optional, and its absence costs a wider inner read rather\n * than a wrong one.\n */\n outerKeys?: ReadonlySet<unknown> | null\n): void => {\n\n const joinOption = event.operation.options.getLast(\"join\");\n\n if (joinOption == null) {\n done({ ok: \"success\" });\n return;\n }\n\n const innerSchema = event.schemas.get(joinOption.value.innerSchemaId);\n\n if (innerSchema == null) {\n done({\n ok: \"error\",\n error: new Error(`Cannot join: the inner collection's schema is not registered in this store. SchemaId: ${joinOption.value.innerSchemaId}`)\n });\n return;\n }\n\n const innerOptions = joinOption.value.innerOptions.split().database;\n\n if (outerKeys != null) {\n innerOptions.add(\"filter\", semiJoinFilter(joinOption.value.innerKey, outerKeys));\n }\n\n const innerEvent: DbPluginQueryEvent<UnknownRecord, UnknownRecord> = {\n operation: new Query(innerOptions, innerSchema) as unknown as DbPluginQueryEvent<UnknownRecord, UnknownRecord>[\"operation\"],\n schemas: event.schemas,\n id: `${event.id}-inner`,\n source: event.source,\n action: \"query\",\n reason: \"join inner side\",\n explain: event.explain,\n // The same array the outer read pushes into, so a join reports BOTH reads in execution\n // order. Built fresh rather than spread, so this has to be carried explicitly.\n executedQueries: event.executedQueries\n };\n\n query(innerEvent, result => {\n if (result.ok === PluginEventResult.ERROR) {\n done({ ok: \"error\", error: result.error });\n return;\n }\n\n done({ ok: \"success\", innerSide: { innerSchema, innerRows: result.data.value as unknown as unknown[] } });\n });\n};\n\n/**\n * Interprets a join by running TWO ordinary queries through the plugin's own read path.\n *\n * The whole of interpretation 2 for a plugin that has no reason to do anything cleverer, and the\n * shape every non-SQL backend should prefer:\n *\n * ```ts\n * query(event, done) {\n * if (event.operation.options.has(\"join\")) {\n * joinInPlugin(event, (e, d) => this.query(e, d), done);\n * return;\n * }\n * // ...the ordinary single-collection path\n * }\n * ```\n *\n * **The outer side runs FIRST, and that ordering is the optimization.** Its keys are what narrow\n * the inner read to rows that can actually pair — and they do not exist until the outer filters\n * have run. Loading the inner side first, which is what a naive implementation does, means reading\n * and materializing a whole collection to pair it with three rows.\n *\n * Neither query carries the join option, so both take the plugin's normal path: its indexes, its\n * pushdown decisions, its retries. Nothing recurses, because the option is stripped before either\n * goes out.\n *\n * @param query How this plugin runs a query. NOT necessarily `plugin.query` — a plugin that\n * serializes queries through a work queue must pass its UN-QUEUED path, or the two reads below\n * wait on the slot this one is holding.\n */\nexport const joinInPlugin = <TRoot extends {}, TShape>(\n event: DbPluginQueryEvent<TRoot, TShape>,\n query: (innerEvent: DbPluginQueryEvent<UnknownRecord, UnknownRecord>, done: PluginEventCallbackResult<ITranslatedValue<UnknownRecord>>) => void,\n done: PluginEventCallbackResult<ITranslatedValue<TShape>>\n): void => {\n\n const { before, at } = event.operation.options.splitAt(\"join\");\n\n if (at == null) {\n done(PluginEventResult.error(event.id, new Error(\"joinInPlugin was called for a query with no join option.\")));\n return;\n }\n\n const innerSchema = event.schemas.get(at.value.innerSchemaId);\n\n if (innerSchema == null) {\n done(PluginEventResult.error(event.id, new Error(\n `Cannot join: the inner collection's schema is not registered in this store. SchemaId: ${at.value.innerSchemaId}`\n )));\n return;\n }\n\n /**\n * The outer side, as the ordinary query it would have been without the join.\n *\n * `before` is everything recorded ahead of the join — the outer filters, and any sort or\n * window. Those belong to the outer ROWS, and running them here rather than around a joined\n * result is what makes `.take(2).join(...)` pair the first two rows on every backend.\n */\n const outerEvent = {\n ...event,\n id: `${event.id}-outer`,\n reason: \"join outer side\",\n operation: new Query(before, event.operation.schema)\n } as unknown as DbPluginQueryEvent<UnknownRecord, UnknownRecord>;\n\n query(outerEvent, outerResult => {\n try {\n if (outerResult.ok === PluginEventResult.ERROR) {\n done(PluginEventResult.error(event.id, outerResult.error));\n return;\n }\n\n const outerRows = (outerResult.data.value ?? []) as unknown as UnknownRecord[];\n\n // Storage shape: the plugin returns rows as it holds them, and deserialization is what\n // `executeJoin` does per side below.\n const outerKeys = distinctJoinKeys(outerRows, at.value.outerKey, at.value.semiJoinKeyThreshold, { storageShape: true });\n\n loadJoinInnerSide(event, query, innerResult => {\n try {\n if (innerResult.ok === \"error\") {\n done(PluginEventResult.error(event.id, innerResult.error));\n return;\n }\n\n const tuples = executeJoin({\n option: at.value,\n outerRows: toEntityShape(event.operation.schema, outerRows),\n innerRows: toEntityShape(innerSchema, innerResult.innerSide?.innerRows ?? [])\n });\n\n // Nothing else can be in the database half — everything after a join ratchets\n // to memory — so these tuples are the whole of this plugin's answer.\n done(PluginEventResult.success(event.id, new TranslatedArrayValue<TShape>(tuples as never[], false)));\n } catch (e) {\n done(PluginEventResult.error(event.id, e));\n }\n }, outerKeys);\n } catch (e) {\n done(PluginEventResult.error(event.id, e));\n }\n });\n};\n\n/**\n * A join over rows both sides have already deserialized, with the inner side's scopes applied.\n *\n * The one entry point every interpreter uses: `JsonTranslator.join` inside a plugin, and the\n * datastore's own memory half for a cross-plugin join. Callers hand over ENTITY-shape rows —\n * `toEntityShape` is separate because a caller may already have paid for it.\n */\nexport const executeJoin = (options: {\n option: JoinQueryOptionValue;\n outerRows: UnknownRecord[];\n innerRows: UnknownRecord[];\n}): JoinTuple[] => {\n const { option, outerRows, innerRows } = options;\n\n return hashJoin({\n kind: option.kind,\n outerRows,\n innerRows: applyInnerOptions(innerRows, option.innerOptions),\n outerKey: option.outerKey,\n innerKey: option.innerKey\n });\n};\n","import { DataTranslator } from \"./DataTranslator\";\nimport { QueryOption } from \"../query/types\";\nimport { nearestBy } from \"../query/similarity\";\nimport { executeJoin, JoinInnerSide, toEntityShape } from \"../query/join\";\nimport { assertIsArray } from \"../../assertions\";\nimport { ParamsFilter } from \"../../expressions\";\nimport { isDate, UnknownRecord } from \"../../utilities\";\nimport { IdType } from \"../../schema\";\nimport { IQuery } from \"../types\";\n\nexport class JsonTranslator<TRoot extends {}, TShape> extends DataTranslator<TRoot, TShape> {\n\n private readonly innerSide?: JoinInnerSide;\n\n /**\n * @param innerSide The inner collection's rows, when this query carries a `join` option.\n * A plugin that omits it for a query that HAS a join gets a throw from `join()` rather than\n * a silently un-joined result.\n */\n constructor(query: IQuery<TRoot, TShape>, innerSide?: JoinInnerSide) {\n super(query);\n this.innerSide = innerSide;\n }\n\n /**\n * The hash join itself, over rows already in memory — the floor every non-SQL backend\n * stands on.\n *\n * Both halves are deserialized here, each with its own schema, because that is where the\n * `===` on key values is specified to happen: in entity shape, by the property names the\n * caller wrote in the key selectors. A `from`-renamed column reads correctly for free.\n */\n override join<TResult>(data: unknown, option: QueryOption<TShape, \"join\">): TResult {\n\n if (Array.isArray(data) === false) {\n return data as TResult;\n }\n\n if (this.innerSide == null) {\n throw new Error(\n `Cannot join: this plugin did not supply the inner collection's rows. ` +\n `A plugin whose translator inherits JsonTranslator.join must construct it with the inner side ` +\n `(new JsonTranslator(operation, { innerSchema, innerRows })) when the query carries a join option.`\n );\n }\n\n const { innerSchema, innerRows } = this.innerSide;\n\n return executeJoin({\n option: option.value,\n outerRows: toEntityShape(this.query.schema, data),\n innerRows: toEntityShape(innerSchema, innerRows)\n }) as TResult;\n }\n\n override filter<TResult>(data: unknown, option: QueryOption<TShape, \"filter\">): TResult {\n\n assertIsArray(data);\n\n if (option.value.filter) {\n\n if (option.value.params == null) {\n // standard filtering\n return data.filter(option.value.filter) as TResult;\n }\n\n // params filtering\n const selector = option.value.filter as ParamsFilter<unknown, {}>\n return data.filter(w => selector([w, option.value.params])) as TResult;\n }\n\n return data as TResult;\n }\n\n override map<T>(data: unknown, option: QueryOption<T, \"map\">): T {\n\n if (Array.isArray(data) == false) {\n throw new Error(\"Can only map an array of data\");\n }\n\n const response = Array.from({ length: data.length });\n\n for (let i = 0, length = data.length; i < length; i++) {\n\n for (let j = 0, l = option.value.fields.length; j < l; j++) {\n const field = option.value.fields[j];\n\n if (field.property != null) {\n const value = field.property.getValue(data[i]);\n\n if (value != null) {\n // Some types do not support deserialization (Array, Function, Computed, etc), just directly set the incoming value\n const resolvedValue = field.property.supportsDeserialization ? field.property.deserialize(value) : value;\n field.property.setValue(data[i], resolvedValue);\n }\n }\n }\n\n response[i] = option.value.selector(data[i]);\n }\n\n return response as T;\n }\n\n override group<T>(data: unknown, option: QueryOption<T, \"group\">): T {\n\n if (Array.isArray(data) == false) {\n throw new Error(\"Can only group an array of data\");\n }\n\n const group: Record<IdType, unknown[]> = {};\n\n for (let i = 0, length = data.length; i < length; i++) {\n\n const keyValue = option.value.selector(data[i]) as IdType;\n\n if (!group[keyValue]) {\n group[keyValue] = [];\n }\n\n const item: UnknownRecord = {};\n\n for (let j = 0, l = option.value.fields.length; j < l; j++) {\n const field = option.value.fields[j];\n\n if (field.property != null) {\n const value = field.property.getValue(data[i]);\n\n if (value != null) {\n // Some types do not support deserialization (Array, Function, Computed, etc), just directly set the incoming value\n const resolvedValue = field.property.supportsDeserialization ? field.property.deserialize(value) : value;\n field.property.setValue(item, resolvedValue);\n continue;\n }\n\n // The property exists, lets set it to the value (null/undefined)\n if (Object.hasOwn(data[i], field.destinationName)) {\n field.property.setValue(item, value);\n }\n }\n }\n\n group[keyValue].push(item);\n }\n\n return group as T;\n }\n\n override count<TResult extends number>(data: unknown, _: QueryOption<TShape, \"count\">): TResult {\n\n if (Array.isArray(data)) {\n return data.length as TResult;\n }\n\n throw new Error(\"Cannot count resulting data, it must be an array. Please return array of data for function: count()\");\n }\n\n // Relational comparison instead of subtraction, for the same reason as sort():\n // subtraction is NaN for strings, which made min()/max() return an arbitrary element.\n // Nulls order first ascending — min() of a column with nulls is null, max() is the\n // largest value — matching what sort() does with the same data.\n override min<TResult extends string | number | Date>(data: unknown, _: QueryOption<TShape, \"min\">): TResult {\n return this._minMax(data, \"min\", (a: any, b: any) => {\n if (a === b) {\n return 0;\n }\n\n if (a == null) {\n return -1;\n }\n\n if (b == null) {\n return 1;\n }\n\n return a < b ? -1 : 1;\n });\n }\n\n override max<TResult extends string | number | Date>(data: unknown, _: QueryOption<TShape, \"max\">): TResult {\n return this._minMax(data, \"max\", (a: any, b: any) => {\n if (a === b) {\n return 0;\n }\n\n if (a == null) {\n return 1;\n }\n\n if (b == null) {\n return -1;\n }\n\n return a < b ? 1 : -1;\n });\n }\n\n override sort<TResult>(data: unknown, option: QueryOption<TShape, \"sort\">): TResult {\n\n if (Array.isArray(data)) {\n const direction = option.value.direction === \"asc\" ? 1 : -1;\n\n // Relational comparison instead of subtraction — subtraction is NaN\n // for strings, which leaves the array unsorted\n data.sort((x, y) => {\n const a = option.value.selector(x) as any;\n const b = option.value.selector(y) as any;\n\n if (a === b) {\n return 0;\n }\n\n if (a == null) {\n return -1 * direction;\n }\n\n if (b == null) {\n return 1 * direction;\n }\n\n return (a < b ? -1 : 1) * direction;\n });\n }\n\n return data as TResult;\n }\n\n /**\n * The similarity search itself, over values already in memory.\n *\n * This is the floor the whole feature stands on: it is reached whenever the backend did\n * not do the search, which is every backend except the ones with a native vector index.\n * It reads the property through the option's selector, so it works on any shape the rows\n * arrive in.\n */\n override nearest<TResult>(data: unknown, option: QueryOption<TShape, \"nearest\">): TResult {\n\n if (Array.isArray(data) === false) {\n return data as TResult;\n }\n\n const { selector, vector, count } = option.value;\n\n return nearestBy(data, vector, count, row => selector(row) as unknown as number[] | null) as TResult;\n }\n\n override sum<TResult extends number>(data: unknown, _: QueryOption<TShape, \"sum\">): TResult {\n\n assertIsArray(data, this._formatDataNotArrayError(\"sum\"));\n\n if (data.length === 0) {\n throw new Error(\"Cannot perform operation on empty array, result query contains no data\")\n }\n\n const map = this.query.options.getLast(\"map\");\n\n let sum = 0;\n const field = this._getSelectionField(\"sum\", map);\n\n for (let i = 0, length = data.length; i < length; i++) {\n const value = data[i];\n\n if (typeof value !== \"number\") {\n throw new Error(`Cannot sum, property is not a number. Property: ${field.sourceName}`);\n }\n\n sum += value;\n }\n\n return sum as TResult;\n }\n\n override distinct<TResult>(data: unknown, _: QueryOption<TShape, \"distinct\">): TResult {\n\n assertIsArray(data, this._formatDataNotArrayError(\"distinct\"));\n\n const result = new Set<string | number | Date>();\n\n // would be nice to have property info here for type detection\n let needsDateConversion = false;\n\n for (let i = 0, length = data.length; i < length; i++) {\n const value = data[i];\n\n if (typeof value === \"number\" || typeof value === \"string\") {\n result.add(value);\n continue;\n }\n\n if (isDate(value)) {\n needsDateConversion = true;\n result.add(value.toISOString());\n continue;\n }\n\n }\n\n if (needsDateConversion) {\n return [...result].map(w => new Date(w)) as TResult;\n }\n\n return [...result] as TResult\n }\n\n override skip<TResult>(data: unknown, option: QueryOption<TShape, \"skip\">): TResult {\n\n if (Array.isArray(data)) {\n\n if (option.value > 0) {\n\n if (data.length < option.value) {\n // We don't have enough data to skip, return an empty array\n return [] as TResult;\n }\n\n return data.slice(option.value) as TResult;\n }\n\n return data as TResult;\n }\n\n return data as TResult;\n }\n\n override take<TResult>(data: unknown, option: QueryOption<TShape, \"take\">): TResult {\n if (Array.isArray(data)) {\n\n if (option.value > 0) {\n\n if (data.length < option.value) {\n return data as TResult;\n }\n\n return data.slice(0, option.value) as TResult;\n }\n\n return data as TResult;\n }\n\n return data as TResult;\n }\n\n private _getSelectionField(name: string, mapOption: QueryOption<TShape, \"map\"> | null) {\n\n if (mapOption == null ||\n mapOption.value.fields.length === 0 ||\n mapOption.value.fields.length > 1) {\n throw new Error(`${name}() operation can only be performed when one field is mapped for a result. Ex. myset.map(x => x.someNumberOrDateOrString).${name}()`)\n }\n\n return mapOption.value.fields[0];\n }\n\n private _minMax<T extends string | number | Date>(data: unknown, name: string, sort: (a: any, b: any) => any): T {\n\n assertIsArray(data, this._formatDataNotArrayError(name));\n\n if (data.length === 0) {\n throw new Error(\"Cannot perform operation on empty array, result query contains no data\")\n }\n\n // A single pass, not sort-and-take-first: O(n) for an O(n) question, and it does not\n // MUTATE the array the caller handed us — the sort did. The caller's comparator is\n // reused so min and max keep their null ordering from one body.\n let best = data[0];\n\n for (let i = 1, length = data.length; i < length; i++) {\n const value = data[i];\n\n // Array.prototype.sort moves undefined elements to the END without consulting the\n // comparator. Mirror that: undefined is never selected unless every element is.\n if (value === undefined) {\n continue;\n }\n\n if (best === undefined || sort(value, best) < 0) {\n best = value;\n }\n }\n\n return best as T;\n }\n\n private _formatDataNotArrayError(functionName: string) {\n return `Cannot sum resulting data, it must be an array. Please return array of data for function: ${functionName}()`\n }\n}","import { IdType } from \"../../schema/types\";\nimport { UnknownRecord } from \"../../utilities/types\";\nimport { QueryOption } from \"../query/types\";\nimport { nearestBy } from \"../query/similarity\";\nimport { IQuery } from \"../types\";\nimport { DataTranslator } from \"./DataTranslator\";\n\n/**\n * A stored vector as a list of numbers, whatever the driver handed back.\n *\n * Three shapes reach here and all are legitimate. A JSON column decoded by\n * `decodeJsonColumns` is already an array. A driver with no type parser for its native vector\n * type returns the literal text — `pg` does exactly this for pgvector, giving `\"[1,2,3]\"`,\n * which happens to be JSON. Anything else is not a vector, and `null` sorts it last rather\n * than throwing.\n */\nconst toVector = (value: unknown): number[] | null => {\n if (Array.isArray(value)) {\n return value as number[];\n }\n\n if (typeof value !== \"string\") {\n return null;\n }\n\n try {\n const parsed = JSON.parse(value);\n\n return Array.isArray(parsed) ? parsed as number[] : null;\n } catch {\n return null;\n }\n};\n\n/**\n * What the statement that produced these rows actually did.\n *\n * Supplied by the plugin because only its query builder knows: an extension may be missing, a\n * window may have made a pushdown unsafe, an inner filter may have had no column to compare\n * against. Every flag defaults to false — the safe direction, since doing the work twice is slow\n * and skipping it is wrong.\n */\nexport type SqlPushdown = {\n /** The statement contained a real `INNER JOIN`/`LEFT JOIN` and its rows are already tuples. */\n join?: boolean;\n};\n\nexport class SqlTranslator<TRoot extends {}, TShape> extends DataTranslator<TRoot, TShape> {\n\n protected readonly pushedDown: SqlPushdown;\n\n constructor(query: IQuery<TRoot, TShape>, pushedDown: SqlPushdown = {}) {\n super(query);\n this.pushedDown = pushedDown;\n }\n\n count<TResult extends number>(data: unknown, _: QueryOption<TShape, \"count\">): TResult {\n if (Array.isArray(data) && data.length > 0) {\n // Count is returned as the property alias on the query.\n //\n // Driver-specific coercion does NOT belong here. Some drivers return COUNT(*)\n // as a bigint string rather than a number; which ones is a fact about those\n // drivers, so a plugin whose driver deviates overrides this method. Naming them\n // here is how engine knowledge starts accumulating in a storage-agnostic\n // package — one bug fix at a time.\n return data[0].count;\n }\n\n return data as TResult;\n }\n\n min<TResult extends string | number | Date>(data: unknown, _: QueryOption<TShape, \"min\">): TResult {\n return this.shapeResult(data);\n }\n\n max<TResult extends string | number | Date>(data: unknown, _: QueryOption<TShape, \"max\">): TResult {\n return this.shapeResult(data);\n }\n\n sum<TResult extends number>(data: unknown, _: QueryOption<TShape, \"sum\">): TResult {\n return this.shapeResult(data);\n }\n\n private shapeResult<TResult>(data: unknown) {\n if (Array.isArray(data) && data.length > 0) {\n // Shape the result\n return data[0];\n }\n\n return data as TResult;\n }\n\n distinct<TResult>(data: unknown, _: QueryOption<TShape, \"distinct\">): TResult {\n return data as TResult;\n }\n\n filter<TResult>(data: unknown, _: QueryOption<TShape, \"filter\">): TResult {\n return data as TResult;\n }\n\n skip(data: unknown, _: QueryOption<TShape, \"skip\">): TShape {\n return data as TShape;\n }\n\n take(data: unknown, _: QueryOption<TShape, \"take\">): TShape {\n return data as TShape;\n }\n\n sort(data: unknown, _: QueryOption<TShape, \"sort\">): TShape {\n return data as TShape;\n }\n\n /**\n * Scores in memory, unlike every other shaper here.\n *\n * The pass-throughs above are safe because the SQL that produced these rows contained the\n * corresponding clause. No `sql-core` statement contains a similarity ordering — engines\n * that can express one are the exception, not the rule — so passing the data through\n * would return whatever order the engine happened to produce.\n *\n * A plugin whose engine DID push the search down overrides this with a pass-through,\n * gated on `option.target`. Postgres is the only one today.\n *\n * Rows arrive keyed by storage column name and are read that way rather than through the\n * option's selector, because the selector is written against the entity shape and these\n * rows have not been deserialized into it yet.\n */\n nearest(data: unknown, option: QueryOption<TShape, \"nearest\">): TShape {\n\n if (Array.isArray(data) === false) {\n return data as TShape;\n }\n\n const { property, propertyName, vector, count } = option.value;\n const column = property?.getResolvedName() ?? propertyName;\n\n return nearestBy(data, vector, count, row => toVector((row as UnknownRecord)[column])) as TShape;\n }\n\n /**\n * Passes through only when the statement really did contain the `JOIN`, and refuses otherwise.\n *\n * The pass-throughs above are safe unconditionally because the SQL that produced these rows\n * contained the corresponding clause. A join is not like that: if the plugin did not emit one,\n * these rows are the outer side alone, and passing them through hands the caller entities\n * where the contract says tuples — every `([outer, inner]) => ...` lambda downstream then\n * destructures the wrong object, and nothing errors.\n *\n * So the plugin has to say, and the default is to refuse. A plugin that DID emit the join has\n * already split each flat row into its two deserialized halves (`splitJoinRows` in\n * `@routier/sql-plugin-core`), so by the time the option is walked the work is done.\n */\n join(data: unknown, option: QueryOption<TShape, \"join\">): TShape {\n if (this.pushedDown.join === true && option.target === \"database\") {\n return data as TShape;\n }\n\n throw new Error(\n `This SQL plugin did not push the join down, so it cannot produce the pairs. Kind: ${option.value.kind}. ` +\n `Emitting the JOIN is the plugin's job: build the joined statement with buildJoinStatement, split the rows with ` +\n `splitJoinRows, and construct this translator with { join: true }.`\n );\n }\n\n group<T>(data: unknown, option: QueryOption<T, \"group\">): T {\n\n if (Array.isArray(data) == false) {\n throw new Error(\"Can only group an array of data\");\n }\n\n const group: Record<IdType, unknown[]> = {};\n\n for (let i = 0, length = data.length; i < length; i++) {\n\n const keyValue = option.value.selector(data[i]) as IdType;\n\n if (!group[keyValue]) {\n group[keyValue] = [];\n }\n\n const item: UnknownRecord = {};\n\n for (let j = 0, l = option.value.fields.length; j < l; j++) {\n const field = option.value.fields[j];\n\n if (field.property != null) {\n const value = field.property.getValue(data[i]);\n\n if (value != null) {\n field.property.setValue(item, field.property.deserialize(value));\n }\n }\n }\n\n group[keyValue].push(item);\n }\n\n return group as T;\n }\n\n map(data: unknown, option: QueryOption<TShape, \"map\">): TShape {\n if (Array.isArray(data) == false) {\n throw new Error(\"Can only map an array of data\");\n }\n\n if (this.query.options.has(\"count\") && data.length === 1) {\n // data here is the shape of { count: number }[] and will map to nothing. \n // Return the original data and let count take care of this\n return data as TShape;\n }\n\n const response = [];\n\n for (let i = 0, length = data.length; i < length; i++) {\n\n for (let j = 0, l = option.value.fields.length; j < l; j++) {\n const field = option.value.fields[j];\n\n if (field.property != null) {\n const value = field.property.getValue(data[i]);\n\n if (value != null) {\n field.property.setValue(data[i], field.property.deserialize(value));\n }\n }\n }\n\n response.push(option.value.selector(data[i]));\n }\n\n return response as TShape;\n }\n}","import { DataTranslator } from \"./DataTranslator\";\nimport { QueryOption } from \"../query/types\";\nimport { assertIsArray } from \"../../assertions\";\nimport { ParamsFilter } from \"../../expressions\";\n\n/**\n * The memory half's pass over JOIN TUPLES.\n *\n * `JsonTranslator` cannot do this job, and the reason is one line of it: `map` and `group` walk\n * `option.value.fields` and deserialize each field through its `PropertyInfo`. A tuple has no\n * schema and no fields — `getFields` over `([p, m]) => ({ ... })` extracts nothing meaningful —\n * so that loop would either no-op or write properties onto a two-element array.\n *\n * Everything a join query is allowed to do after the join is expressible as a plain closure\n * over the tuple, and that is all this does. The lambdas the caller wrote (`([p, m]) => ...`)\n * are applied as-is, which is also why the result is identical whichever backend produced the\n * pairs.\n *\n * Both halves are already in entity shape when the tuples arrive here (the wire contract), so\n * there is nothing left to deserialize — the reason the missing field loop costs nothing.\n *\n * The absent operations are absent by design, not by omission: `sum`/`min`/`max`/`distinct` and\n * `group` are not declared on the tuple queryable's type, so reaching them means something\n * built an option this API cannot express, and a throw naming it is the honest answer.\n */\nexport class TupleTranslator<TRoot extends {}, TShape> extends DataTranslator<TRoot, TShape> {\n\n override filter<TResult>(data: unknown, option: QueryOption<TShape, \"filter\">): TResult {\n\n assertIsArray(data);\n\n if (option.value.filter == null) {\n return data as TResult;\n }\n\n if (option.value.params == null) {\n return data.filter(option.value.filter) as TResult;\n }\n\n const selector = option.value.filter as ParamsFilter<unknown, {}>;\n return data.filter(tuple => selector([tuple, option.value.params])) as TResult;\n }\n\n override map<TResult>(data: unknown, option: QueryOption<TShape, \"map\">): TResult {\n\n assertIsArray(data, this.notAnArray(\"map\"));\n\n return data.map(tuple => option.value.selector(tuple as TShape)) as TResult;\n }\n\n override sort<TResult>(data: unknown, option: QueryOption<TShape, \"sort\">): TResult {\n\n if (Array.isArray(data) === false) {\n return data as TResult;\n }\n\n const direction = option.value.direction === \"asc\" ? 1 : -1;\n\n // Relational comparison rather than subtraction, and nulls first ascending — the same\n // ordering `JsonTranslator.sort` produces, so a sort means the same thing on either\n // side of a join.\n data.sort((x, y) => {\n const a = option.value.selector(x) as any;\n const b = option.value.selector(y) as any;\n\n if (a === b) {\n return 0;\n }\n\n if (a == null) {\n return -1 * direction;\n }\n\n if (b == null) {\n return 1 * direction;\n }\n\n return (a < b ? -1 : 1) * direction;\n });\n\n return data as TResult;\n }\n\n override skip<TResult>(data: unknown, option: QueryOption<TShape, \"skip\">): TResult {\n\n if (Array.isArray(data) === false || option.value <= 0) {\n return data as TResult;\n }\n\n return data.slice(option.value) as TResult;\n }\n\n override take<TResult>(data: unknown, option: QueryOption<TShape, \"take\">): TResult {\n\n if (Array.isArray(data) === false || option.value <= 0) {\n return data as TResult;\n }\n\n return data.slice(0, option.value) as TResult;\n }\n\n override count<TResult extends number>(data: unknown, _: QueryOption<TShape, \"count\">): TResult {\n\n assertIsArray(data, this.notAnArray(\"count\"));\n\n return data.length as TResult;\n }\n\n /**\n * Already joined by the time anything reaches here.\n *\n * The pairs were produced either by the plugin (its translator's `join`) or by the datastore\n * before this pass ran, so the option is a record of what happened rather than work to do.\n */\n override join(data: unknown, _: QueryOption<TShape, \"join\">): TShape {\n return data as TShape;\n }\n\n override group<TResult>(_: unknown, __: QueryOption<TShape, \"group\">): TResult {\n throw new Error(this.notSupported(\"toGroup\"));\n }\n\n override sum<TResult extends number>(_: unknown, __: QueryOption<TShape, \"sum\">): TResult {\n throw new Error(this.notSupported(\"sum\"));\n }\n\n override min<TResult extends string | number | Date>(_: unknown, __: QueryOption<TShape, \"min\">): TResult {\n throw new Error(this.notSupported(\"min\"));\n }\n\n override max<TResult extends string | number | Date>(_: unknown, __: QueryOption<TShape, \"max\">): TResult {\n throw new Error(this.notSupported(\"max\"));\n }\n\n override distinct<TResult>(_: unknown, __: QueryOption<TShape, \"distinct\">): TResult {\n throw new Error(this.notSupported(\"distinct\"));\n }\n\n override nearest(_: unknown, __: QueryOption<TShape, \"nearest\">): TShape {\n // A similarity search BEFORE the join stays in the outer side's options and never\n // reaches a tuple. One after it would have to score a pair, which has no vector.\n throw new Error(this.notSupported(\"nearest\"));\n }\n\n private notSupported(name: string) {\n return `${name}() is not available on a join result. Project the tuples with .map() first, then run it on the projection.`;\n }\n\n private notAnArray(name: string) {\n return `Cannot ${name} a join result, it must be an array of tuples.`;\n }\n}\n","export * from './DataTranslator';\nexport * from './JsonTranslator';\nexport * from './SqlTranslator';\nexport * from './TupleTranslator';\nexport * from './types';\nexport * from './TranslatedArrayValue';\nexport * from './TranslatedGroupValue';\nexport * from './TranslatedSingleValue';","import { Expression } from \"../../expressions/types\";\nimport { MemoryExecutionReason, QueryOption, QueryOptionExecutionTarget, QueryOptionName } from \"./types\";\nimport { QueryOptionsCollection } from \"./QueryOptionsCollection\";\n\n/**\n * One sentence per reason code, written for someone meeting pushdown for the first time.\n *\n * Beside the codes rather than in the formatter, so console output, a failing test and the\n * docs all say the same thing.\n */\nexport const MEMORY_EXECUTION_EXPLANATIONS: Record<MemoryExecutionReason, string> = {\n \"not-parsable\": \"A filter could not be parsed into an expression tree, so it and every option after it run in memory.\",\n \"unmapped-property\": \"The property is not stored in the database, so it can only be read after deserialization.\",\n \"renamed-property\": \"The property is stored under a different name, and selectors use the in-memory name, so it can only be read after deserialization.\",\n \"map-rename\": \"A map renames or drops properties, so every option after it refers to names the database does not have.\",\n \"after-nearest\": \"A similarity search orders and limits rows, and the plugin cannot report whether it performed the search, so every option after it runs in memory.\",\n \"after-join\": \"A join produces [outer, inner] tuples rather than entities, and the plugin cannot report how it joined, so every option after it runs in memory.\",\n \"cross-plugin-join\": \"The two sides of this join live on different plugins, so neither can read the other's rows and the join runs in the datastore.\"\n};\n\n/**\n * One thing a backend actually executed, in the backend's own language.\n *\n * A plugin pushes these onto `DbPluginQueryEvent.executedQueries` as it runs them, so a join —\n * which reads twice — reports both, in execution order. `text` is not required to be SQL: a\n * key-value store describes what it did in whatever terms it has.\n */\nexport type ExecutedQuery = {\n text: string;\n parameters?: unknown[];\n};\n\nexport type ExplainedOption = {\n index: number;\n name: QueryOptionName;\n detail?: Record<string, unknown>;\n};\n\nexport const EXECUTED_QUERIES_UNSUPPORTED =\n \"This plugin did not report what it executed. It may not support explain.\";\n\nexport type ExecutionStep = {\n step: number;\n of: number;\n executedIn: QueryOptionExecutionTarget;\n description: string;\n options: ExplainedOption[];\n /** Set on database steps once the plugin has reported. */\n executedQueries?: ExecutedQuery[];\n /** Set on the first database step instead, when the plugin reported nothing. */\n executedQueriesUnsupported?: string;\n /** Set on memory steps only. */\n reason?: MemoryExecutionReason;\n explanation?: string;\n};\n\nexport type QueryExplanationSummary = {\n database: number;\n memory: number;\n /** Deduped, in first-seen order. Empty when the whole query pushed down. */\n reasons: MemoryExecutionReason[];\n explanation: string;\n};\n\nexport type QueryExplanation = {\n collection: string;\n database: string;\n summary: QueryExplanationSummary;\n executionSteps: ExecutionStep[];\n plugin: { kind: string };\n};\n\nexport type ExplainContext = {\n collection: string;\n database: string;\n pluginKind: string;\n};\n\nconst DATABASE_STEP_DESCRIPTION = \"These options are sent to the plugin.\";\nconst MEMORY_STEP_DESCRIPTION = \"Routier runs these over the rows the database returned, after deserializing them.\";\nconst UNNARROWED_READ_DESCRIPTION = \"No option could be pushed down, so the plugin reads the whole collection.\";\n\n/**\n * The reportable shape of one option's value.\n *\n * Serializable facts only, never the live selector functions — an explanation is a document a\n * caller may log, diff in a test, or send to a server, and a closure survives none of that.\n */\nconst detailOf = (option: QueryOption<any, any>): Record<string, unknown> | undefined => {\n\n if (option.name === \"filter\") {\n const value = option.value as { expression?: Expression };\n\n if (value.expression == null) {\n return undefined;\n }\n\n try {\n return { expression: Expression.toJson(value.expression) };\n } catch {\n // `valueToJson` rejects a value no wire can carry. Reporting the rest of the\n // explanation beats taking the diagnostic down with the query it describes.\n return { expressionUnavailable: \"This filter holds a value that cannot be serialized.\" };\n }\n }\n\n if (option.name === \"sort\") {\n const value = option.value as { propertyName: string, direction: string };\n\n return { propertyName: value.propertyName, direction: value.direction };\n }\n\n if (option.name === \"skip\" || option.name === \"take\") {\n return { value: option.value as number };\n }\n\n if (option.name === \"nearest\") {\n const value = option.value as { propertyName: string, vector: number[], count: number };\n\n return { propertyName: value.propertyName, dimensions: value.vector.length, count: value.count };\n }\n\n if (option.name === \"join\") {\n const value = option.value as {\n kind: string,\n outerKey: { propertyName: string },\n innerKey: { propertyName: string },\n crossPlugin: boolean,\n innerOptions: QueryOptionsCollection<any>\n };\n\n return {\n kind: value.kind,\n outerKey: value.outerKey.propertyName,\n innerKey: value.innerKey.propertyName,\n crossPlugin: value.crossPlugin,\n innerOptions: explainedOptionsOf(value.innerOptions)\n };\n }\n\n if (option.name === \"map\" || option.name === \"group\") {\n const value = option.value as { fields: { sourceName: string, destinationName: string }[] };\n\n return { fields: value.fields.map(x => ({ from: x.sourceName, to: x.destinationName })) };\n }\n\n return undefined;\n};\n\nconst explainedOptionOf = (option: QueryOption<any, any>, index: number): ExplainedOption => {\n const detail = detailOf(option);\n\n return { index, name: option.name, ...(detail == null ? {} : { detail }) };\n};\n\nconst explainedOptionsOf = (options: QueryOptionsCollection<any>): ExplainedOption[] => {\n const explained: ExplainedOption[] = [];\n let index = 0;\n\n options.forEach(option => explained.push(explainedOptionOf(option, index++)));\n\n return explained;\n};\n\nconst summarize = (steps: ExecutionStep[]): QueryExplanationSummary => {\n const reasons: MemoryExecutionReason[] = [];\n let database = 0;\n let memory = 0;\n\n for (const step of steps) {\n if (step.executedIn === \"database\") {\n database += step.options.length;\n continue;\n }\n\n memory += step.options.length;\n\n if (step.reason != null && reasons.includes(step.reason) === false) {\n reasons.push(step.reason);\n }\n }\n\n const counts = `${database} ${database === 1 ? \"option ran\" : \"options ran\"} in the database, ${memory} ran in memory.`;\n const causes = reasons.map(reason => MEMORY_EXECUTION_EXPLANATIONS[reason]).join(\" \");\n\n return { database, memory, reasons, explanation: causes.length === 0 ? counts : `${counts} ${causes}` };\n};\n\n/**\n * Groups options into consecutive runs that execute in the same place.\n *\n * A step boundary is where execution moves, and a reader has to see the statement as step 1 OF\n * 2 to understand it is not the whole query. Cutting over to memory is a ratchet, so the\n * database options are always a prefix and there are at most two steps.\n *\n * A database step is emitted even when NO option pushed down, because the plugin is dispatched\n * either way — `createQueryPayload` always builds a database event. Without it, the worst case\n * the feature exists to expose reports \"0 in the database\" while the backend reads the whole\n * table, which is the opposite of the truth.\n */\nconst toExecutionSteps = (options: QueryOptionsCollection<any>): ExecutionStep[] => {\n const steps: ExecutionStep[] = [];\n let index = 0;\n\n options.forEach(option => {\n const explained = explainedOptionOf(option, index++);\n const current = steps[steps.length - 1];\n\n if (current != null && current.executedIn === option.target) {\n current.options.push(explained);\n return;\n }\n\n steps.push({\n step: steps.length + 1,\n of: 0,\n executedIn: option.target,\n description: option.target === \"database\" ? DATABASE_STEP_DESCRIPTION : MEMORY_STEP_DESCRIPTION,\n options: [explained],\n ...(option.reason == null ? {} : {\n reason: option.reason,\n explanation: MEMORY_EXECUTION_EXPLANATIONS[option.reason]\n })\n });\n });\n\n if (steps[0]?.executedIn !== \"database\") {\n steps.unshift({\n step: 0,\n of: 0,\n executedIn: \"database\",\n description: UNNARROWED_READ_DESCRIPTION,\n options: []\n });\n }\n\n for (let i = 0; i < steps.length; i++) {\n steps[i].step = i + 1;\n steps[i].of = steps.length;\n }\n\n return steps;\n};\n\n/**\n * Builds the explanation from the resolved options, with no plugin involvement.\n *\n * Takes the collection BEFORE `split()`, and throws otherwise. Splitting re-adds each half\n * into a fresh collection, which re-derives targets without the options that caused them — a\n * post-join filter alone in the memory half derives back to `\"database\"`, and the document\n * would report memory work as having run in the database.\n */\nexport const explainQuery = (options: QueryOptionsCollection<any>, context: ExplainContext): QueryExplanation => {\n\n if (options.isDerived === true) {\n throw new Error(\n \"explainQuery was given a collection produced by split() or splitAt(). Those re-derive \" +\n \"execution targets without the options that caused them, so the explanation would report \" +\n \"memory work as having run in the database. Pass the collection as it was resolved, \" +\n \"before splitting.\"\n );\n }\n\n const executionSteps = toExecutionSteps(options);\n\n return {\n collection: context.collection,\n database: context.database,\n summary: summarize(executionSteps),\n executionSteps,\n plugin: { kind: context.pluginKind }\n };\n};\n\n/**\n * Attaches what the backend reported to the step that was sent to it.\n *\n * Reporting is optional for a plugin, so an empty report is not an error: the step is marked\n * `executedQueriesUnsupported` instead, and the rest of the explanation stands — the pushdown\n * analysis comes from the options and is correct with or without the plugin's statements.\n *\n * Copies the steps rather than writing into them, so the explanation a caller already holds\n * does not gain statements after the fact. Options and their details are shared with the\n * original — nothing mutates them, and copying deeper would only look safer than it is.\n */\nexport const withExecutedQueries = (explanation: QueryExplanation, executedQueries: ExecutedQuery[]): QueryExplanation => {\n let attached = false;\n\n const executionSteps = explanation.executionSteps.map((step): ExecutionStep => {\n\n // Only the first database step: a plugin reports what IT ran, and everything it ran\n // was sent as one dispatch. Stamping the same statements onto a second database step\n // would claim they ran twice.\n if (step.executedIn !== \"database\" || attached === true) {\n return { ...step, options: [...step.options] };\n }\n\n attached = true;\n\n if (executedQueries.length === 0) {\n return { ...step, options: [...step.options], executedQueriesUnsupported: EXECUTED_QUERIES_UNSUPPORTED };\n }\n\n return { ...step, options: [...step.options], executedQueries: [...executedQueries] };\n });\n\n return { ...explanation, executionSteps };\n};\n","import { ExecutionStep, ExplainedOption, QueryExplanation } from \"./explain\";\n\nconst OPTION_LABEL_WIDTH = 8;\nconst WRAP_WIDTH = 68;\n\n/** Wraps `text` to `WRAP_WIDTH`, prefixing every line with `indent`. */\nconst wrap = (text: string, indent: string): string[] => {\n const lines: string[] = [];\n let line = \"\";\n\n for (const word of text.split(\" \")) {\n if (line.length > 0 && line.length + word.length + 1 > WRAP_WIDTH) {\n lines.push(indent + line);\n line = word;\n continue;\n }\n\n line = line.length === 0 ? word : `${line} ${word}`;\n }\n\n if (line.length > 0) {\n lines.push(indent + line);\n }\n\n return lines;\n};\n\nconst COMPARATOR_SYMBOLS: Record<string, string> = {\n \"equals\": \"===\",\n \"greater-than\": \">\",\n \"greater-than-equals\": \">=\",\n \"less-than\": \"<\",\n \"less-than-equals\": \"<=\"\n};\n\nconst describeValue = (value: any): string => {\n if (value == null) {\n return \"?\";\n }\n\n if (value.k === \"raw\") {\n return typeof value.v === \"string\" ? `\"${value.v}\"` : String(value.v);\n }\n\n if (value.k === \"date\") {\n return value.v;\n }\n\n if (value.k === \"array\") {\n return `[${(value.v as unknown[]).map(describeValue).join(\", \")}]`;\n }\n\n return value.k === \"undefined\" ? \"undefined\" : String(value.v);\n};\n\n/** Renders a serialized expression back to something close to the source predicate. */\nconst describeExpression = (expression: any): string => {\n\n if (expression == null) {\n return \"?\";\n }\n\n if (expression.t === \"operator\") {\n return `${describeExpression(expression.left)} ${expression.operator} ${describeExpression(expression.right)}`;\n }\n\n if (expression.t === \"comparator\") {\n const left = describeExpression(expression.left);\n const right = describeExpression(expression.right);\n const symbol = COMPARATOR_SYMBOLS[expression.comparator];\n\n if (symbol == null) {\n return `${left}.${expression.comparator}(${right})${expression.negated === true ? \" === false\" : \"\"}`;\n }\n\n return `${left} ${expression.negated === true ? \"!==\" : symbol} ${right}`;\n }\n\n if (expression.t === \"property\") {\n return expression.path;\n }\n\n if (expression.t === \"value\") {\n return describeValue(expression.value);\n }\n\n return expression.t === \"empty\" ? \"(no filter)\" : \"(not parsable)\";\n};\n\nconst describeOption = (option: ExplainedOption): string => {\n const detail = option.detail;\n\n if (detail == null) {\n return \"\";\n }\n\n if (option.name === \"filter\") {\n return detail.expression == null\n ? String(detail.expressionUnavailable ?? \"\")\n : describeExpression(detail.expression);\n }\n\n if (option.name === \"sort\") {\n return `${detail.propertyName} ${detail.direction}`;\n }\n\n if (option.name === \"skip\" || option.name === \"take\") {\n return String(detail.value);\n }\n\n if (option.name === \"join\") {\n return `${detail.kind} → ${detail.outerKey} = ${detail.innerKey}`;\n }\n\n if (option.name === \"nearest\") {\n return `${detail.propertyName}, ${detail.count} nearest`;\n }\n\n if (option.name === \"map\" || option.name === \"group\") {\n const fields = detail.fields as { from: string, to: string }[];\n\n return fields.map(x => x.from === x.to ? x.from : `${x.from} → ${x.to}`).join(\", \");\n }\n\n return \"\";\n};\n\nconst formatStep = (step: ExecutionStep, lines: string[]) => {\n const reason = step.reason == null ? \"\" : ` [${step.reason}]`;\n\n lines.push(` STEP ${step.step} of ${step.of} — ${step.executedIn}${reason}`);\n lines.push(...wrap(step.description, \" \"));\n\n if (step.explanation != null) {\n lines.push(...wrap(step.explanation, \" \"));\n }\n\n lines.push(\"\");\n\n for (const option of step.options) {\n lines.push(` ${option.name.padEnd(OPTION_LABEL_WIDTH)} ${describeOption(option)}`.trimEnd());\n }\n\n for (const executed of step.executedQueries ?? []) {\n lines.push(\"\");\n lines.push(...executed.text.split(\"\\n\").map(line => ` ${line}`));\n\n if (executed.parameters != null && executed.parameters.length > 0) {\n lines.push(` parameters: ${JSON.stringify(executed.parameters)}`);\n }\n }\n\n if (step.executedQueriesUnsupported != null) {\n lines.push(\"\");\n lines.push(...wrap(step.executedQueriesUnsupported, \" \"));\n }\n\n lines.push(\"\");\n};\n\n/**\n * Renders an explanation for a terminal.\n *\n * The STEP headers carry the whole lesson: a reader who has never heard of pushdown still sees\n * that the statement in step 1 is not the entire query. Nobody should have to notice a missing\n * ORDER BY to work that out.\n */\nexport const formatExplanation = (explanation: QueryExplanation): string => {\n const { collection, database, summary, executionSteps } = explanation;\n const stepCount = `${executionSteps.length} ${executionSteps.length === 1 ? \"step\" : \"steps\"}`;\n const lines: string[] = [`${collection} · ${database} · ${stepCount}`, \"\"];\n\n for (const step of executionSteps) {\n formatStep(step, lines);\n }\n\n lines.push(...wrap(summary.explanation, \" \"));\n\n return lines.join(\"\\n\");\n};\n","import { Expression, Filter, ParamsFilter } from \"../../expressions\";\nimport { PropertyInfo, SchemaId } from \"../../schema\";\nimport { GenericFunction } from \"../../types\";\nimport type { JoinKeyReference, JoinKind } from \"./join\";\nimport type { QueryOptionsCollection } from \"./QueryOptionsCollection\";\n\nexport enum QueryOrdering {\n Descending = \"desc\",\n Ascending = \"asc\"\n}\n\n/**\n * Field mapping for a query result, including source and destination names and a getter function.\n */\nexport type QueryField = {\n sourceName: string,\n destinationName: string,\n isRename: boolean;\n property?: PropertyInfo<unknown>;\n getter: <T>(data: Record<string, unknown>) => T;\n};\n\nexport type QueryOptionExecutionTarget = \"database\" | \"memory\";\nexport type QueryOptionName = keyof QueryOptionValueMap<unknown>;\n\n/**\n * Why an option runs in memory rather than in the database.\n *\n * A code rather than a sentence, so a test can assert on it — the sentences live in\n * `MEMORY_EXECUTION_EXPLANATIONS`. Every cause is a ratchet, because `nextExecutionTarget`\n * never returns to `\"database\"`, so the code recorded is the FIRST cause and it stays on every\n * option after it. Reporting a later one would name a symptom of this one.\n */\nexport type MemoryExecutionReason =\n | \"not-parsable\"\n | \"unmapped-property\"\n | \"renamed-property\"\n | \"map-rename\"\n | \"after-nearest\"\n | \"after-join\"\n | \"cross-plugin-join\";\n\nexport type QueryOption<T, K extends QueryOptionName> = {\n name: QueryOptionName;\n value: QueryOptionValueMap<T>[K],\n target: QueryOptionExecutionTarget;\n /** Set only when `target` is `\"memory\"`. */\n reason?: MemoryExecutionReason;\n}\n\nexport type QueryOptionValueMap<T extends {}> = {\n skip: number;\n take: number;\n sort: { selector: GenericFunction<T, T[keyof T]>, direction: QueryOrdering, propertyName: string, property?: PropertyInfo<T> | null };\n map: { selector: GenericFunction<T, any>, fields: QueryField[] };\n group: { selector: GenericFunction<T, any>, key: QueryField, fields: QueryField[] };\n filter: { params?: {}, filter: ParamsFilter<T, {}> | Filter<T>, expression: Expression };\n /**\n * Similarity search: an ordering plus a limit, never a filter.\n *\n * `count` is part of the option rather than a separate `take` because the two are one\n * operation to a backend that can push this down — `ORDER BY ... LIMIT n` is what makes an\n * approximate index usable, and splitting them would order every row before limiting.\n */\n nearest: { selector: GenericFunction<T, T[keyof T]>, propertyName: string, property?: PropertyInfo<T> | null, vector: number[], count: number };\n /**\n * An equi-join against a second collection, interpreted by whoever receives it.\n *\n * A first-class query option rather than a datastore side-path: a SQL backend emits a real\n * `INNER JOIN`/`LEFT JOIN`, every other backend loads the rows it needs and the shared hash\n * join runs inside the plugin, and a cross-plugin join runs in the datastore's memory half.\n * All three produce the same pairs — see `specs/joins.md`.\n *\n * Serializable by construction: property paths and a schema id, never live rows, with any\n * filter's values travelling in its params object. That is what lets the whole option be\n * forwarded to a server once expression-tree serialization lands.\n */\n join: {\n kind: JoinKind;\n /** Resolved through `event.schemas`, which already carries every schema in the store. */\n innerSchemaId: SchemaId;\n outerKey: JoinKeyReference;\n innerKey: JoinKeyReference;\n /**\n * The inner side's own filters — INCLUDING its soft-delete scope and `.scope()`\n * filters. Every interpreter must apply these: it is the only place they exist, because\n * a join bypasses the inner collection's normal read path.\n */\n innerOptions: QueryOptionsCollection<any>;\n /**\n * Whether the two sides live on DIFFERENT plugin instances, in which case no plugin can\n * receive the option and the datastore is the interpreter.\n *\n * Decided by plugin instance identity at build time, never by comparing database names —\n * two plugins over one database are still two interpreters, and one name can front two\n * databases.\n */\n crossPlugin: boolean;\n /**\n * How many distinct outer keys are still worth turning into an `IN (...)` prefilter on the\n * inner read — the datastore's `semiJoinKeyThreshold`, default 500.\n *\n * Carried in the option because the decision is made where the join executes, which is\n * usually inside a plugin, and a plugin cannot see a datastore's configuration. A number\n * serializes; a reference to the store would not.\n *\n * Cost only. Above the threshold the inner side is read under its own scopes and the hash\n * join discards the surplus — the same answer by a slower route.\n */\n semiJoinKeyThreshold: number;\n };\n min: true; // True or not set\n max: true; // True or not set\n count: true; // True or not set\n sum: true; // True or not set\n distinct: true; // True or not set\n};\n\n/**\n * Sort specification for a query.\n */\nexport type QuerySort = { key: string, selector: (item: unknown) => unknown, direction: \"asc\" | \"desc\" };","export * from './explain';\nexport * from './formatExplanation';\nexport * from './join';\nexport * from './Query';\nexport * from './QueryOptionsCollection';\nexport * from './types';\nexport * from './similarity';","import { Expression, toStrictPredicate } from \"../../expressions\";\nimport { CompiledSchema } from \"../../schema\";\nimport { UnknownRecord } from \"../../utilities\";\nimport { JoinKeyReference } from \"../query/join\";\nimport { QueryOptionsCollection } from \"../query/QueryOptionsCollection\";\nimport { QueryOptionName, QueryOrdering } from \"../query/types\";\nimport { SerializedQueryOption } from \"./types\";\n\n/**\n * Which options can cross a wire, and how the rest are handled.\n *\n * Everything except `map` and `group`. Those two are defined BY a closure — the projection is the\n * option — and no data form of them exists to send. Nothing else needs its closure: a sort is a\n * property and a direction, a filter is an expression tree, `nearest` is a vector and a count.\n */\nconst SENDABLE: ReadonlySet<QueryOptionName> = new Set<QueryOptionName>([\n \"skip\", \"take\", \"sort\", \"filter\", \"nearest\", \"join\", \"count\", \"min\", \"max\", \"sum\", \"distinct\"\n]);\n\n/**\n * Splits options into the PREFIX that can be sent and the remainder that cannot.\n *\n * A prefix, not a filtered subset, and that is the whole correctness argument. Options are ordered,\n * and most are not idempotent: sending `count` while keeping `map` local would count unmapped rows,\n * and applying `take` on both sides would window twice. So the split stops at the first option that\n * cannot travel, and everything from there on runs where the closures are.\n *\n * It is the same shape as the database/memory split this composes with — one more cut of the same\n * ordered list, for one more reason.\n */\nexport const splitSendableOptions = <T>(options: QueryOptionsCollection<T>): {\n sendable: QueryOptionsCollection<T>;\n local: QueryOptionsCollection<T>;\n} => {\n const sendable = new QueryOptionsCollection<T>();\n const local = new QueryOptionsCollection<T>();\n\n let stopped = false;\n\n options.forEach(option => {\n if (stopped === false && SENDABLE.has(option.name) === false) {\n stopped = true;\n }\n\n (stopped ? local : sendable).add(option.name, option.value);\n });\n\n return { sendable, local };\n};\n\n/** The key's property path, which is what the receiver resolves against its own schema. */\nconst keyPath = (reference: JoinKeyReference) => reference.property?.id ?? reference.propertyName;\n\nexport const serializeQueryOptions = <T>(options: QueryOptionsCollection<T>): SerializedQueryOption[] => {\n const serialized: SerializedQueryOption[] = [];\n\n options.forEach(option => {\n const value = option.value as never as UnknownRecord;\n\n switch (option.name) {\n case \"skip\":\n case \"take\":\n serialized.push({ name: option.name, value: option.value as never as number });\n return;\n\n case \"sort\":\n serialized.push({\n name: \"sort\",\n value: {\n // The declared path, so the receiver can resolve its own property and rebuild\n // both the selector and the storage column name from it\n propertyName: (value.property as { id?: string } | null)?.id ?? String(value.propertyName),\n direction: value.direction as QueryOrdering\n }\n });\n return;\n\n case \"filter\": {\n const expression = value.expression as never as Expression;\n\n /**\n * A filter with no usable tree must not be SENT, and this is a hard error.\n *\n * `not-parsable` means the intent is unknown — the parser could not work out what the\n * predicate asks for. A receiver handed that has two options, and both are wrong: read\n * everything (returning rows the caller excluded) or return nothing (silently losing\n * them). Neither is a degradation worth accepting when the caller's own closure is\n * sitting right here and can answer correctly.\n *\n * In practice this is unreachable: `QueryOptionsCollection.add` targets an unparsable\n * filter at the MEMORY half, so it never reaches a plugin. The guard is here because\n * \"unreachable\" is a property of code that changes, and the failure it would let\n * through is silent.\n */\n if (Expression.isNotParsable(expression)) {\n throw new Error(\n \"Cannot send a filter whose expression could not be parsed: the receiver would have to guess whether to \" +\n \"return everything or nothing, and both answers are wrong. A filter like this belongs in the memory half, \" +\n \"where the caller's own predicate runs.\"\n );\n }\n\n serialized.push({ name: \"filter\", value: { expression: Expression.toJson(expression) } });\n return;\n }\n\n case \"nearest\":\n serialized.push({\n name: \"nearest\",\n value: {\n propertyName: (value.property as { id?: string } | null)?.id ?? String(value.propertyName),\n vector: value.vector as number[],\n count: value.count as number\n }\n });\n return;\n\n case \"join\": {\n const join = value as never as {\n kind: \"inner\" | \"left\";\n innerOptions: QueryOptionsCollection<unknown>;\n outerKey: JoinKeyReference;\n innerKey: JoinKeyReference;\n semiJoinKeyThreshold: number;\n innerCollectionName?: string;\n };\n\n serialized.push({\n name: \"join\",\n value: {\n kind: join.kind,\n // Resolved by the caller, which is the only place that can see the schema\n // collection the id refers to\n innerCollectionName: join.innerCollectionName ?? \"\",\n outerKeyPath: keyPath(join.outerKey),\n innerKeyPath: keyPath(join.innerKey),\n innerOptions: serializeQueryOptions(join.innerOptions),\n semiJoinKeyThreshold: join.semiJoinKeyThreshold\n }\n });\n return;\n }\n\n case \"count\":\n case \"min\":\n case \"max\":\n case \"sum\":\n case \"distinct\":\n serialized.push({ name: option.name, value: true });\n return;\n\n default:\n throw new Error(\n `Cannot serialize the '${option.name}' query option: it is defined by a function, which cannot cross a wire. ` +\n `Use splitSendableOptions so it runs where its closure is.`\n );\n }\n });\n\n return serialized;\n};\n\n/** How the receiver finds a collection it was sent the NAME of. */\nexport type SchemaResolver = (collectionName: string) => CompiledSchema<any> | null;\n\n/**\n * A filter the RECEIVER adds to every read of a collection, whatever the sender asked for.\n *\n * Returns `null` for a collection with nothing to add. See `createRequestHandler` for the policy\n * side; this is only how it reaches the options.\n */\nexport type ScopeProvider = (schema: CompiledSchema<any>) => Expression | null;\n\n/**\n * Rebuilds query options from their wire form, against the receiver's own schemas.\n *\n * The closures that were dropped are reconstructed here rather than sent:\n *\n * - a **sort selector** from its property, which is all `JsonTranslator.sort` reads;\n * - a **filter predicate** from its expression tree, via `toStrictPredicate` — which THROWS rather\n * than keeping a row it cannot judge, because on a receiver a filter that quietly stops filtering\n * returns rows the requester excluded.\n *\n * @throws when a named property or collection is not declared by the receiver's schemas. A payload\n * describing data this side does not have is a disagreement, and it has to be loud.\n */\nexport const deserializeQueryOptions = (\n serialized: SerializedQueryOption[],\n schema: CompiledSchema<any>,\n resolveSchema: SchemaResolver,\n /**\n * A receiver-side filter per collection, applied to this collection AND to every collection a\n * join reaches. Prepended, so it is ANDed with whatever the sender sent and there is no order of\n * options that removes it.\n */\n scopeFor?: ScopeProvider\n): QueryOptionsCollection<any> => {\n\n const options = new QueryOptionsCollection<any>();\n\n /**\n * FIRST, before anything the sender asked for.\n *\n * Position matters twice. It cannot be displaced by any option the sender chose, and being at\n * the front it is in the database half — so a backend pushes it down rather than the receiver\n * reading the whole collection and filtering afterwards.\n */\n const scope = scopeFor?.(schema) ?? null;\n\n if (scope != null) {\n options.add(\"filter\", {\n filter: toStrictPredicate(scope) as never,\n expression: scope,\n params: undefined\n } as never);\n }\n\n const propertyOf = (path: string) => {\n const property = schema.getProperty(path);\n\n if (property == null) {\n throw new Error(\n `Cannot deserialize a query: this schema does not declare the property it names. ` +\n `Property: ${path}, Collection: ${schema.collectionName}`\n );\n }\n\n return property;\n };\n\n for (const option of serialized) {\n switch (option.name) {\n case \"skip\":\n case \"take\":\n options.add(option.name, option.value as never);\n break;\n\n case \"sort\": {\n const property = propertyOf(option.value.propertyName);\n\n options.add(\"sort\", {\n selector: ((row: UnknownRecord) => property.getValue(row)) as never,\n direction: option.value.direction,\n propertyName: option.value.propertyName,\n property\n } as never);\n break;\n }\n\n case \"filter\": {\n const expression = Expression.fromJson(option.value.expression, schema);\n\n options.add(\"filter\", {\n filter: toStrictPredicate(expression) as never,\n expression,\n params: undefined\n } as never);\n break;\n }\n\n case \"nearest\": {\n const property = propertyOf(option.value.propertyName);\n\n options.add(\"nearest\", {\n selector: ((row: UnknownRecord) => property.getValue(row)) as never,\n propertyName: option.value.propertyName,\n property,\n vector: option.value.vector,\n count: option.value.count\n } as never);\n break;\n }\n\n case \"join\": {\n const innerSchema = resolveSchema(option.value.innerCollectionName);\n\n if (innerSchema == null) {\n throw new Error(\n `Cannot deserialize a join: this store has no collection named '${option.value.innerCollectionName}'.`\n );\n }\n\n options.add(\"join\", {\n kind: option.value.kind,\n innerSchemaId: innerSchema.id,\n outerKey: { propertyName: option.value.outerKeyPath, property: propertyOf(option.value.outerKeyPath) },\n innerKey: {\n propertyName: option.value.innerKeyPath,\n property: innerSchema.getProperty(option.value.innerKeyPath)\n },\n /**\n * The inner side is deserialized with the SAME scope provider, which is what\n * stops a join being a way around a scope: a sender that cannot read a\n * collection directly must not be able to read it by joining to it.\n */\n innerOptions: deserializeQueryOptions(option.value.innerOptions, innerSchema, resolveSchema, scopeFor),\n // False by construction: the receiver executes both sides against its own single\n // plugin, whatever the sender's topology was.\n crossPlugin: false,\n semiJoinKeyThreshold: option.value.semiJoinKeyThreshold\n } as never);\n break;\n }\n\n default:\n options.add(option.name, true as never);\n break;\n }\n }\n\n return options;\n};\n","import { BulkPersistChanges, BulkPersistResult } from \"../../collections\";\nimport { CompiledSchema } from \"../../schema\";\nimport { ReadonlySchemaCollection } from \"../../collections/ReadonlySchemaCollection\";\nimport { SchemaResolver } from \"./query\";\nimport { SerializedPersistRequest, SerializedResponse, SerializedSchemaChanges } from \"./types\";\n\n/**\n * Saves, in the form that survives a wire.\n *\n * Simpler than a query, because a change set holds no functions: adds, updates and removes are\n * entities, and an entity reaching a plugin has already been through `preprocess` — so it is in\n * STORAGE shape, where a Date is already an ISO string and a nested object is already whatever the\n * schema said to store. It is JSON by the time it gets here.\n *\n * Two things are deliberately left behind:\n *\n * - **Tags.** `SchemaPersistChanges.tags` is caller-side metadata for correlating a save with its\n * echo locally. The receiver has no use for it and no business seeing it.\n * - **Schema ids.** Collections are NAMED. An id is a hash of the schema's own shape, so it would\n * couple both sides to identical schema definitions; a name lets the receiver resolve its own.\n */\n\nexport const serializeBulkPersist = (\n changes: BulkPersistChanges,\n schemas: ReadonlySchemaCollection\n): SerializedPersistRequest => {\n\n const serialized: SerializedSchemaChanges[] = [];\n\n for (const [schemaId, schemaChanges] of changes) {\n if (schemaChanges.hasItems === false) {\n continue;\n }\n\n const schema = schemas.get(schemaId);\n\n if (schema == null) {\n throw new Error(`Cannot serialize a save: no schema is registered for the id it names. SchemaId: ${schemaId}`);\n }\n\n serialized.push({\n collectionName: schema.collectionName,\n adds: schemaChanges.adds as unknown[],\n updates: schemaChanges.updates.map(update => ({\n entity: update.entity,\n changeType: update.changeType,\n delta: update.delta,\n ...(update.concurrency != null && { concurrency: update.concurrency })\n })),\n removes: schemaChanges.removes as unknown[]\n });\n }\n\n return { kind: \"persist\", changes: serialized };\n};\n\n/**\n * Rebuilds a change set from its wire form, keyed by the RECEIVER's schema ids.\n *\n * @throws when a named collection is not one this store declares. A save aimed at data this side\n * does not have must not be silently dropped — the caller would be told it succeeded.\n */\nexport const deserializeBulkPersist = (\n request: SerializedPersistRequest,\n resolveSchema: SchemaResolver\n): { changes: BulkPersistChanges; schemas: CompiledSchema<any>[] } => {\n\n const changes = new BulkPersistChanges();\n const schemas: CompiledSchema<any>[] = [];\n\n for (const schemaChanges of request.changes) {\n const schema = resolveSchema(schemaChanges.collectionName);\n\n if (schema == null) {\n throw new Error(\n `Cannot apply a save: this store has no collection named '${schemaChanges.collectionName}'.`\n );\n }\n\n schemas.push(schema);\n\n const resolved = changes.resolve(schema.id);\n resolved.adds = schemaChanges.adds as never[];\n resolved.updates = schemaChanges.updates.map(update => ({\n entity: update.entity as never,\n changeType: update.changeType,\n delta: update.delta as never,\n ...(update.concurrency != null && { concurrency: update.concurrency })\n })) as never[];\n resolved.removes = schemaChanges.removes as never[];\n }\n\n return { changes, schemas };\n};\n\n/**\n * Serializes the ECHO of a save — the part the change tracker cannot do without.\n *\n * A save's result is not a receipt. It carries the rows as the database wrote them, including any\n * identity the database assigned, and the change tracker matches each one back to the addition that\n * produced it. Returning a count instead would leave every inserted entity without its key.\n */\nexport const serializePersistResult = (\n result: BulkPersistResult,\n schemas: ReadonlySchemaCollection\n): SerializedResponse => {\n\n const changes: Array<{ collectionName: string; adds: unknown[]; updates: unknown[]; removes: unknown[] }> = [];\n\n for (const [schemaId, schemaResult] of result) {\n const schema = schemas.get(schemaId);\n\n if (schema == null) {\n continue;\n }\n\n changes.push({\n collectionName: schema.collectionName,\n adds: schemaResult.adds as unknown[],\n updates: schemaResult.updates as unknown[],\n removes: schemaResult.removes as unknown[]\n });\n }\n\n return { ok: true, kind: \"persist\", changes };\n};\n\n/** Rebuilds a save's echo against the SENDER's schema ids, which is what its change tracker holds. */\nexport const deserializePersistResult = (\n response: Extract<SerializedResponse, { kind: \"persist\" }>,\n resolveSchema: SchemaResolver\n): BulkPersistResult => {\n\n const result = new BulkPersistResult();\n\n for (const schemaChanges of response.changes) {\n const schema = resolveSchema(schemaChanges.collectionName);\n\n if (schema == null) {\n throw new Error(\n `A save came back naming a collection this store does not declare: '${schemaChanges.collectionName}'.`\n );\n }\n\n const resolved = result.resolve(schema.id);\n resolved.adds = schemaChanges.adds as never[];\n resolved.updates = schemaChanges.updates as never[];\n resolved.removes = schemaChanges.removes as never[];\n }\n\n return result;\n};\n","import { ReadonlySchemaCollection } from \"../../collections/ReadonlySchemaCollection\";\nimport { Expression, Filter, ParamsFilter, toExpression, toStrictPredicate } from \"../../expressions\";\nimport { PluginEventResult, Result } from \"../../results\";\nimport { CompiledSchema } from \"../../schema\";\nimport { UnknownRecord, uuid } from \"../../utilities\";\nimport { IDbPlugin } from \"../types\";\nimport { ExecutedQuery } from \"../query/explain\";\nimport { Query } from \"../query/Query\";\nimport { deserializeBulkPersist, serializePersistResult } from \"./persist\";\nimport { deserializeQueryOptions, SchemaResolver, ScopeProvider } from \"./query\";\nimport { SerializedRequest, SerializedResponse } from \"./types\";\n\n/**\n * The receiving half: takes a serialized request, executes it, returns a serialized response.\n *\n * Deliberately not a server. It is one async function from JSON to JSON, with no notion of HTTP, so\n * the same handler sits behind Express, a Cloudflare Worker, a Lambda, a WebSocket message, or a\n * worker `postMessage`. Transport is the caller's business; this is the part that would otherwise be\n * rewritten per framework.\n *\n * ```ts\n * const handle = createRequestHandler({ plugin, schemas });\n *\n * app.post(\"/routier\", async (req, res) => res.json(await handle(req.body)));\n * ```\n *\n * ## Security is YOURS, and this gives you the two places to put it\n *\n * There is no built-in notion of a user, a tenant, a role or a token, and there should not be: this\n * library cannot know what your identities are or what they may see. What it can do is make sure\n * there is nowhere for a decision to be forgotten. Two hooks, and both receive a `context` you built\n * from the request:\n *\n * - **`authorize`** — may this caller do this at all? Called once per request, before anything is\n * deserialized or executed, with the action and every collection the request touches.\n * - **`scope`** — which ROWS may this caller see? A filter the receiver ANDs into every read of a\n * collection, and checks every written row against.\n *\n * With neither supplied, the endpoint answers anything for anyone. That is the correct default for a\n * function with no idea who is calling it — and the moment you name a context type, passing one\n * becomes required, so a policy cannot be half-wired.\n *\n * ```ts\n * const handle = createRequestHandler<{ tenantId: string }>({\n * plugin,\n * schemas,\n * authorize: ({ action, context }) => context.tenantId != null || \"not signed in\",\n * scope: ({ context }) => ({ filter: ([row, p]) => row.tenantId === p.tenantId, params: context }),\n * });\n *\n * app.post(\"/routier\", async (req, res) => {\n * const context = { tenantId: req.user?.tenantId }; // from the REQUEST, never from the body\n * res.json(await handle(req.body, context));\n * });\n * ```\n *\n * ## Errors are values\n *\n * A failure comes back as `{ ok: false, error }` rather than as a rejected promise, so a transport\n * cannot accidentally turn a query error into a 500 with no body. The caller decides the status.\n */\n\n/** What a hook is told about the request it is judging. */\nexport type RequestInfo<TContext> = {\n action: \"query\" | \"persist\" | \"destroy\";\n /** Every collection this request touches, including the inner side of any join. */\n collectionNames: string[];\n /** Whatever the transport built from the request — a user, a tenant, a token. Never the body. */\n context: TContext;\n /** The raw request, for a policy that needs to look closer. Treat it as caller-controlled input. */\n request: SerializedRequest;\n};\n\n/**\n * May this request proceed?\n *\n * `true` to allow. `false` or a string to refuse — a string becomes the error message, which is the\n * cheapest way to say WHY without inventing an error type. Throwing also refuses.\n *\n * Called once, before deserialization, so a refused request never reaches a schema or a plugin.\n */\nexport type AuthorizeHook<TContext> = (info: RequestInfo<TContext>) => boolean | string | Promise<boolean | string>;\n\n/** What a scope hook is asked. One collection at a time, since each may be scoped differently. */\nexport type ScopeInfo<TContext> = {\n collectionName: string;\n schema: CompiledSchema<any>;\n context: TContext;\n action: \"query\" | \"persist\";\n};\n\n/**\n * The rows of one collection this caller may touch, as a filter.\n *\n * Written exactly like a collection's own `.scope()` — a filter, optionally with params — so the same\n * expression is pushed into the database on reads and checked against each row on writes. Return\n * `null` for a collection this caller may see in full.\n *\n * ```ts\n * scope: ({ collectionName, context }) =>\n * collectionName === \"orders\"\n * ? { filter: ([row, p]) => row.tenantId === p.tenantId, params: { tenantId: context.tenantId } }\n * : null\n * ```\n */\nexport type ScopeHook<TContext> = (info: ScopeInfo<TContext>) =>\n | { filter: Filter<any> | ParamsFilter<any, any>; params?: {} }\n | null;\n\nexport type RequestHandlerOptions<TContext> = {\n /** The plugin that actually holds the data. Anything implementing `IDbPlugin`. */\n plugin: IDbPlugin;\n /** Every collection this endpoint will answer for. A name absent from here is refused. */\n schemas: ReadonlySchemaCollection;\n /** May this caller do this? See `AuthorizeHook`. Absent means yes, to everyone. */\n authorize?: AuthorizeHook<TContext>;\n /** Which rows may this caller touch? See `ScopeHook`. Absent means all of them. */\n scope?: ScopeHook<TContext>;\n /**\n * Whether a `destroy` request may drop the database. **Defaults to false.**\n *\n * `HttpTransportDbPlugin` never sends one, but an endpoint answers whatever arrives — and a\n * hand-written `{\"kind\":\"destroy\"}` would otherwise wipe the store for anyone who could reach\n * the route. Destroying a database is not something a remote caller should be able to ask for by\n * default, so it is opt-in and still passes through `authorize`.\n */\n allowDestroy?: boolean;\n};\n\nexport type RequestHandler<TContext> = (request: SerializedRequest, context: TContext) => Promise<SerializedResponse>;\n\n/** Every collection a request touches, joins included — what `authorize` is given. */\nconst collectionsIn = (request: SerializedRequest): string[] => {\n if (request.kind === \"destroy\") {\n return [];\n }\n\n if (request.kind === \"persist\") {\n return request.changes.map(change => change.collectionName);\n }\n\n const names = [request.collectionName];\n\n const walk = (options: typeof request.options) => {\n for (const option of options) {\n if (option.name === \"join\") {\n names.push(option.value.innerCollectionName);\n walk(option.value.innerOptions);\n }\n }\n };\n\n walk(request.options);\n\n return names;\n};\n\nexport const createRequestHandler = <TContext = void>(options: RequestHandlerOptions<TContext>): RequestHandler<TContext> => {\n const { plugin, schemas, authorize, scope, allowDestroy = false } = options;\n\n const byName = new Map<string, CompiledSchema<any>>();\n\n for (const [, schema] of schemas) {\n byName.set(schema.collectionName, schema as CompiledSchema<any>);\n }\n\n const resolveSchema: SchemaResolver = (collectionName) => byName.get(collectionName) ?? null;\n\n const failed = (error: unknown): SerializedResponse => ({\n ok: false,\n error: error instanceof Error ? error.message : String(error)\n });\n\n /**\n * Turns a scope hook's filter into an expression, once per collection per request.\n *\n * `toExpression` rather than only keeping the closure, because an expression is what a backend\n * can push down — a scope that could only run in memory would mean reading the whole collection\n * to hide most of it. A filter that cannot be parsed is REFUSED rather than silently degraded:\n * a scope is the boundary, and one that quietly stops applying is worse than an error.\n */\n const scopeExpressionFor = (schema: CompiledSchema<any>, context: TContext, action: \"query\" | \"persist\"): Expression | null => {\n if (scope == null) {\n return null;\n }\n\n const declared = scope({ collectionName: schema.collectionName, schema, context, action });\n\n if (declared == null) {\n return null;\n }\n\n const expression = toExpression(schema, declared.filter as never, declared.params as never);\n\n if (Expression.isNotParsable(expression)) {\n throw new Error(\n `The scope declared for '${schema.collectionName}' cannot be expressed as a filter, so it cannot be enforced. ` +\n `Scopes must be parseable — they are the boundary between callers, and one that cannot be applied must not be ignored.`\n );\n }\n\n return expression;\n };\n\n return async (request, context) => {\n try {\n if (request.kind === \"destroy\" && allowDestroy === false) {\n return failed(new Error(\n \"This endpoint does not allow destroy. Dropping the database is opt-in: pass allowDestroy to createRequestHandler if a remote caller really should be able to ask for it.\"\n ));\n }\n\n if (authorize != null) {\n const verdict = await authorize({\n action: request.kind,\n collectionNames: collectionsIn(request),\n context,\n request\n });\n\n if (verdict !== true) {\n return failed(new Error(typeof verdict === \"string\" ? verdict : \"Not authorized.\"));\n }\n }\n\n if (request.kind === \"query\") {\n const schema = resolveSchema(request.collectionName);\n\n if (schema == null) {\n return failed(new Error(`This endpoint has no collection named '${request.collectionName}'.`));\n }\n\n const queryOptions = deserializeQueryOptions(\n request.options,\n schema,\n resolveSchema,\n // Applied to the outer collection AND to every collection a join reaches, so a\n // join cannot be used to read around a scope\n (target) => scopeExpressionFor(target, context, \"query\")\n );\n\n const executedQueries: ExecutedQuery[] = [];\n\n return await new Promise<SerializedResponse>(resolve => {\n plugin.query({\n // `false`: nothing here attaches to a change tracker — the tracker lives on\n // the caller, on the other side of the wire.\n operation: new Query(queryOptions, schema, false),\n schemas: schemas as never,\n id: uuid(8),\n source: \"RequestHandler\",\n action: \"query\",\n explain: request.explain,\n executedQueries\n }, result => {\n if (result.ok === PluginEventResult.ERROR) {\n resolve(failed(result.error));\n return;\n }\n\n resolve({\n ok: true,\n kind: \"query\",\n value: result.data.value as unknown,\n // Only when asked, and only what the plugin reported. A plugin\n // that reported nothing sends nothing, and the caller marks the\n // remote step as not reported.\n ...(request.explain === true && executedQueries.length > 0 ? { executedQueries } : {})\n });\n });\n });\n }\n\n if (request.kind === \"persist\") {\n const { changes } = deserializeBulkPersist(request, resolveSchema);\n\n /**\n * A scope has to be enforced on WRITES too, and differently.\n *\n * On a read it narrows what comes back. On a write there is nothing to narrow — the\n * rows are supplied by the caller — so each one is CHECKED against the same\n * expression, and a single row outside the scope refuses the whole save. Without\n * this, a caller who can only read their own rows could still write somebody else's.\n *\n * All-or-nothing on purpose: a partial save would leave the caller believing the\n * rejected rows were stored.\n */\n for (const [schemaId, schemaChanges] of changes) {\n const schema = schemas.get(schemaId);\n\n if (schema == null) {\n continue;\n }\n\n const expression = scopeExpressionFor(schema as CompiledSchema<any>, context, \"persist\");\n\n if (expression == null) {\n continue;\n }\n\n const permitted = toStrictPredicate(expression);\n\n const rows = [\n ...schemaChanges.adds as UnknownRecord[],\n ...schemaChanges.updates.map(update => update.entity as UnknownRecord),\n ...schemaChanges.removes as UnknownRecord[]\n ];\n\n for (const row of rows) {\n if (permitted(row) === false) {\n return failed(new Error(\n `This save was refused: a row of '${schema.collectionName}' falls outside the scope allowed for this caller.`\n ));\n }\n }\n }\n\n return await new Promise<SerializedResponse>(resolve => {\n plugin.bulkPersist({\n operation: changes,\n schemas: schemas as never,\n id: uuid(8),\n source: \"RequestHandler\",\n action: \"persist\"\n }, result => {\n if (result.ok === Result.ERROR) {\n resolve(failed(result.error));\n return;\n }\n\n // A PARTIAL result carries data AND an error. Reported as a failure, because\n // the caller must not treat a half-applied save as a success.\n if (result.ok === Result.PARTIAL) {\n resolve(failed(result.error));\n return;\n }\n\n resolve(serializePersistResult(result.data, schemas));\n });\n });\n }\n\n return await new Promise<SerializedResponse>(resolve => {\n plugin.destroy({\n schemas: schemas as never,\n id: uuid(8),\n source: \"RequestHandler\",\n action: \"destroy\"\n }, result => {\n if (result.ok === PluginEventResult.ERROR) {\n resolve(failed(result.error));\n return;\n }\n\n resolve({ ok: true, kind: \"destroy\" });\n });\n });\n } catch (error) {\n return failed(error);\n }\n };\n};\n\n/** Re-exported so a caller can type its own scope provider without reaching for the query module. */\nexport type { ScopeProvider };\n","export * from './types';\nexport * from './query';\nexport * from './persist';\nexport * from './handler';\n","import { BulkPersistResult, SchemaCollection } from \"../collections\";\nimport { OptimisticConcurrencyError } from \"../errors\";\nimport { DbPluginBulkPersistEvent, DbPluginEvent, DbPluginQueryEvent, IDbPlugin, ITranslatedValue } from \".\";\nimport { Query } from \"./query/Query\";\nimport { PluginEventCallbackPartialResult, PluginEventCallbackResult } from \"../results\";\nimport { CompiledSchema, IdType, InferType, PropertyInfo, SchemaId, SchemaTypes } from \"../schema\";\n\n/**\n * Optimistic concurrency as a wrapper plugin — the whole opt-in is one wrap:\n *\n * ```ts\n * class Bank extends DataStore {\n * constructor() {\n * super(new ConcurrencyDbPlugin(new SqlitePlugin('bank.db')));\n * }\n * }\n * ```\n *\n * Nothing is declared on the schema and nothing on the collection builder: the plugin\n * maintains a hidden `__version` column in the SAME tables/records as the data, entirely\n * below the entity surface. Rows start at version 1; every update is applied ONLY IF the\n * stored version still matches what this store last read (and bumps it); a stale write\n * rejects the save with `OptimisticConcurrencyError` naming the rows instead of silently\n * overwriting another writer. Recovery is always: re-read, reapply, save again.\n *\n * ## How the hidden column exists without schema changes\n *\n * The wrapper hands the inner plugin an AUGMENTED VIEW of each compiled schema — the same\n * object via prototype delegation, with one synthetic `__version` property appended to\n * `properties`. That list is exactly what the storage plugins read to build DDL, INSERT\n * and SELECT column lists, so the column materializes and round-trips through completely\n * unmodified plugin code. Above the wrapper the real schema is untouched, and the\n * datastore's generated deserialize/enrich drop undeclared fields, so `__version` never\n * reaches an entity a caller holds.\n *\n * The synthetic property carries `from: '__version'` on purpose: EphemeralDataPlugin\n * deep-copies query results with `structuredClone` (rather than the generated clone, which\n * drops undeclared fields) when any property is renamed — which is what lets the hidden\n * column survive reads from the in-process plugins so this wrapper can observe it.\n *\n * ## What this store \"read\"\n *\n * `expected` is per store instance: the version this wrapper last saw for the row, from a\n * query result or a persist echo. A row updated WITHOUT ever being read through this store\n * (rare — an attach of a foreign instance) has no expected value and is written unchecked,\n * initializing its token; the row is protected from the next read on.\n *\n * ## Enforcement and limits\n *\n * The conditional check itself is performed by the INNER plugin via the\n * `EntityUpdateInfo.concurrency` contract — memory, file-system, sqlite and postgresql\n * enforce it (see specs/optimistic-concurrency.md for the not-yet list). Existing SQL\n * tables created before the wrapper was adopted lack the column and need\n * `ALTER TABLE ... ADD COLUMN \"__version\" <number type>` — new tables get it from the\n * augmented DDL automatically.\n */\nexport class ConcurrencyDbPlugin implements IDbPlugin {\n\n static readonly VERSION_COLUMN = \"__version\";\n\n private readonly plugin: IDbPlugin;\n /** Augmented schema views, one per schema — identity matters, so they are cached. */\n private readonly augmentedSchemas = new Map<SchemaId, CompiledSchema<any>>();\n /** collectionName -> rowId -> the version this store last observed for the row. */\n private readonly observedVersions = new Map<string, Map<IdType, number>>();\n\n constructor(plugin: IDbPlugin) {\n this.plugin = plugin;\n }\n\n get databaseName(): string {\n return this.plugin.databaseName;\n }\n\n query<TRoot extends {}, TShape extends any = TRoot>(event: DbPluginQueryEvent<TRoot, TShape>, done: PluginEventCallbackResult<ITranslatedValue<TShape>>): void {\n const schema = event.operation.schema;\n\n const augmentedEvent: DbPluginQueryEvent<TRoot, TShape> = {\n ...event,\n schemas: this.augmentSchemas(event.schemas),\n operation: new Query<TRoot, TShape>(\n event.operation.options,\n this.augment(schema),\n // Preserve the override rather than letting the getter re-derive it\n (event.operation as unknown as { enableChangeTrackingOverride?: boolean }).enableChangeTrackingOverride\n ),\n };\n\n this.plugin.query(augmentedEvent, result => {\n if (result.ok !== \"error\") {\n // Query rows are plugin-made copies, so the hidden column can be removed in\n // place after its value is recorded.\n this.captureAndStrip(schema, this.rowsOf(result.data), { strip: true });\n }\n\n done(result);\n });\n }\n\n bulkPersist(event: DbPluginBulkPersistEvent, done: PluginEventCallbackPartialResult<BulkPersistResult>): void {\n const schemaIds: SchemaId[] = [];\n\n for (const [schemaId, changes] of event.operation) {\n schemaIds.push(schemaId);\n\n if (changes == null || changes.hasItems === false) {\n continue;\n }\n\n const schema = event.schemas.get(schemaId);\n const versions = this.versionsFor(schema.collectionName);\n\n for (const add of changes.adds) {\n (add as Record<string, unknown>)[ConcurrencyDbPlugin.VERSION_COLUMN] = 1;\n }\n\n for (const update of changes.updates) {\n const entity = update.entity as Record<string, unknown>;\n const id = schema.getId(update.entity as InferType<{}>);\n const expected = versions.get(id);\n // An EMPTY delta means \"write the whole entity\" (the plugins' fallback);\n // adding the column would silently narrow the write to the token alone.\n const deltaCarriesColumns = Object.keys(update.delta as Record<string, unknown>).length > 0;\n\n if (typeof expected === \"number\") {\n entity[ConcurrencyDbPlugin.VERSION_COLUMN] = expected + 1;\n if (deltaCarriesColumns) {\n (update.delta as Record<string, unknown>)[ConcurrencyDbPlugin.VERSION_COLUMN] = expected + 1;\n }\n update.concurrency = { column: ConcurrencyDbPlugin.VERSION_COLUMN, expected };\n } else {\n // Never observed through this store — initialize the token, unchecked.\n entity[ConcurrencyDbPlugin.VERSION_COLUMN] = 1;\n if (deltaCarriesColumns) {\n (update.delta as Record<string, unknown>)[ConcurrencyDbPlugin.VERSION_COLUMN] = 1;\n }\n }\n }\n }\n\n const augmentedEvent: DbPluginBulkPersistEvent = {\n ...event,\n schemas: this.augmentSchemas(event.schemas),\n };\n\n this.plugin.bulkPersist(augmentedEvent, result => {\n if (result.ok === \"success\") {\n for (const schemaId of schemaIds) {\n const schema = event.schemas.get(schemaId);\n const buckets = result.data.get(schemaId);\n\n // Echoed rows can BE the stored records (the in-process plugins echo by\n // reference), so the hidden column is recorded but never deleted here —\n // the datastore's generated deserialize drops it before any caller sees\n // it, and deleting it would erase the stored token itself.\n this.captureAndStrip(schema, buckets.adds as unknown[], { strip: false });\n this.captureAndStrip(schema, buckets.updates as unknown[], { strip: false });\n\n for (const removed of buckets.removes as unknown[]) {\n this.forget(schema, removed);\n }\n }\n } else if (OptimisticConcurrencyError.is(result.error)) {\n // The expected values that lost the race are stale; drop them so the\n // caller's re-read re-arms the check with fresh observations.\n const conflicted = result.error as OptimisticConcurrencyError;\n const versions = this.observedVersions.get(conflicted.collectionName);\n\n if (versions != null) {\n for (const id of conflicted.conflicts) {\n versions.delete(id);\n }\n }\n }\n\n done(result);\n });\n }\n\n destroy(event: DbPluginEvent, done: PluginEventCallbackResult<never>): void {\n this.observedVersions.clear();\n this.plugin.destroy(event, done);\n }\n\n private versionsFor(collectionName: string) {\n let versions = this.observedVersions.get(collectionName);\n\n if (versions == null) {\n versions = new Map<IdType, number>();\n this.observedVersions.set(collectionName, versions);\n }\n\n return versions;\n }\n\n /** Extracts entity rows from a translated query result; scalars/aggregates have none. */\n private rowsOf(data: ITranslatedValue<unknown>): unknown[] {\n const value = (data as { value?: unknown }).value;\n\n if (Array.isArray(value)) {\n return value;\n }\n\n if (value != null && typeof value === \"object\") {\n return [value];\n }\n\n return [];\n }\n\n private captureAndStrip(schema: CompiledSchema<any>, rows: unknown[], options: { strip: boolean }) {\n const versions = this.versionsFor(schema.collectionName);\n\n for (const row of rows) {\n if (row == null || typeof row !== \"object\") {\n continue;\n }\n\n const record = row as Record<string, unknown>;\n const version = record[ConcurrencyDbPlugin.VERSION_COLUMN];\n\n if (typeof version === \"number\") {\n try {\n versions.set(schema.getId(record as InferType<{}>), version);\n } catch {\n // Projected rows may not carry the key; nothing to observe.\n }\n }\n\n if (options.strip) {\n delete record[ConcurrencyDbPlugin.VERSION_COLUMN];\n }\n }\n }\n\n private forget(schema: CompiledSchema<any>, row: unknown) {\n if (row == null || typeof row !== \"object\") {\n return;\n }\n\n try {\n this.observedVersions.get(schema.collectionName)?.delete(schema.getId(row as InferType<{}>));\n } catch {\n // Removals without a resolvable id have nothing recorded.\n }\n }\n\n /** A SchemaCollection whose every schema is the augmented view. */\n private augmentSchemas(schemas: SchemaCollection): SchemaCollection {\n const augment = (schema: CompiledSchema<any>) => this.augment(schema);\n\n return new Proxy(schemas, {\n get(target, property, receiver) {\n if (property === \"get\") {\n return (id: SchemaId) => augment(target.get(id));\n }\n\n return Reflect.get(target, property, receiver);\n },\n });\n }\n\n /**\n * The augmented view of a compiled schema: the same object via prototype delegation,\n * with a synthetic `__version` property appended to `properties`. Everything else —\n * generated functions, ids, id properties — delegates to the real schema.\n */\n private augment<T extends {}>(schema: CompiledSchema<T>): CompiledSchema<T> {\n const cached = this.augmentedSchemas.get(schema.id);\n\n if (cached != null) {\n return cached as CompiledSchema<T>;\n }\n\n const synthetic = {\n name: ConcurrencyDbPlugin.VERSION_COLUMN,\n parent: null,\n type: SchemaTypes.Number,\n isKey: false,\n isIdentity: false,\n isDistinct: false,\n isNullable: true,\n isOptional: false,\n isReadonly: false,\n isUnmapped: false,\n isConcurrency: false,\n indexes: [] as string[],\n tags: [] as string[],\n literals: [] as unknown[],\n // Non-null `from` makes EphemeralDataPlugin structural-copy query results\n // (the generated clone would drop the hidden column before this wrapper\n // could observe it). The resolved name is unchanged.\n from: ConcurrencyDbPlugin.VERSION_COLUMN,\n valueSerializer: null,\n valueDeserializer: null,\n injected: null,\n defaultValue: null,\n getResolvedName: () => ConcurrencyDbPlugin.VERSION_COLUMN,\n getValue: (entity: Record<string, unknown>) => entity[ConcurrencyDbPlugin.VERSION_COLUMN],\n } as unknown as PropertyInfo<T>;\n\n const view = Object.create(schema) as CompiledSchema<T> & { properties: PropertyInfo<T>[] };\n Object.defineProperty(view, \"properties\", {\n value: [...schema.properties, synthetic],\n enumerable: true,\n });\n\n this.augmentedSchemas.set(schema.id, view);\n\n return view;\n }\n}\n","import { assertIsNotNull } from '../assertions';\nimport { OptimisticConcurrencyError } from '../errors';\nimport { BulkPersistResult, SchemaPersistChanges } from '../collections';\nimport { WorkPipeline } from '../pipeline';\nimport { DbPluginBulkPersistEvent, DbPluginEvent, DbPluginQueryEvent, distinctJoinKeys, IDbPlugin, ITranslatedValue, JoinInnerSide, JsonTranslator } from '.';\nimport { PluginEventCallbackPartialResult, PluginEventCallbackResult, PluginEventResult, Result } from '../results';\nimport { CompiledSchema, IdType, InferCreateType } from '../schema';\nimport { isComparatorExpression, isPropertyExpression, isValueExpression } from '../assertions';\nimport { DeepPartial } from '../types';\nimport { MemoryDataCollection } from '../collections/MemoryDataCollection';\nimport { UnknownRecord } from '../utilities';\n\n/**\n * Extracts the key value from a parsed filter expression when the whole filter\n * is a single non-negated equality on the schema's key property. Returns null\n * for anything else — compound filters, transformed properties, or filters that\n * could not be parsed.\n */\nconst getKeyEqualityValue = (expression: unknown): { value: IdType } | null => {\n\n // Type guards over the `type` discriminant, not instanceof — expression\n // instances can originate from a different bundled copy of the classes\n if (!isComparatorExpression(expression)) {\n return null;\n }\n\n if (expression.comparator !== \"equals\" || expression.negated === true) {\n return null;\n }\n\n const { left, right } = expression;\n\n if (!isPropertyExpression(left) || !isValueExpression(right)) {\n return null;\n }\n\n if (left.property.isKey !== true || left.transformer != null || right.value == null) {\n return null;\n }\n\n return { value: right.value as IdType };\n}\n\nexport abstract class EphemeralDataPlugin implements IDbPlugin {\n\n protected readonly _databaseName: string;\n\n constructor(databaseName: string) {\n this._databaseName = databaseName;\n }\n\n /**\n * See `IDbPlugin.databaseName`. A getter rather than the field itself so a subclass whose\n * database is identified by more than a name can widen it — `FileSystemPlugin` returns the\n * resolved file path, because one name in two directories is two databases.\n */\n get databaseName(): string {\n return this._databaseName;\n }\n\n protected abstract resolveCollection<TEntity extends {}>(schema: CompiledSchema<TEntity>): MemoryDataCollection;\n\n /**\n * All-or-nothing across every collection in the save.\n *\n * The naive shape — validate/apply/save one schema at a time — leaks partial saves:\n * a conflict in the SECOND collection left the first collection's changes applied\n * (measured in the finance stress app as one orphan ledger row per conflict). So the\n * work is phased: every collection loads and validates BEFORE anything is applied,\n * mutations apply with an undo log, and a failure anywhere reverts the memory state\n * (and re-saves any files already written) so the caller sees a save that did nothing.\n *\n * The remaining honesty gap is crash-safety across FILES: a process dying between two\n * file writes can leave disk partially updated. Guarding that needs a journal, which\n * a memory-first plugin does not pretend to have.\n */\n bulkPersist(event: DbPluginBulkPersistEvent, done: PluginEventCallbackPartialResult<BulkPersistResult>) {\n try {\n const bulkPersistResult = event.operation.toResult();\n const schemas = event.schemas;\n\n type StagedSchema = {\n schema: CompiledSchema<UnknownRecord>;\n collection: MemoryDataCollection;\n changes: SchemaPersistChanges<Record<string, unknown>>;\n result: ReturnType<BulkPersistResult[\"get\"]>;\n };\n\n const staged: StagedSchema[] = [];\n\n for (const [schemaId, changes] of event.operation) {\n if (!changes.hasItems) {\n continue;\n }\n\n const schema = schemas.get(schemaId);\n assertIsNotNull(schema);\n\n staged.push({\n schema: schema as CompiledSchema<UnknownRecord>,\n collection: this.resolveCollection(schema),\n changes: changes as SchemaPersistChanges<Record<string, unknown>>,\n result: bulkPersistResult.get(schemaId),\n });\n }\n\n if (staged.length === 0) {\n done(PluginEventResult.success(event.id, bulkPersistResult));\n return;\n }\n\n const pipeline = new WorkPipeline();\n\n // Phase 1 — load every collection that needs its stored data (updates/removes,\n // and any conditional update), before anything is validated or applied.\n //\n // An ADD-ONLY batch is skipped: an add needs no prior state, and for the memory\n // backing this class was written against, loading is free anyway.\n //\n // ⚠ SUBCLASSES THAT PERSIST WHOLE COLLECTIONS MUST HYDRATE IN `save()`.\n // If `save()` serializes `this.records` over the entire stored value — a JSON\n // file, one localStorage key, a blob — then a collection instance that has\n // never loaded holds only this batch's adds, and writing it DELETES everything\n // previously persisted. The skip above means `save()` cannot assume `load()`\n // ran. Hydrate first (load-once, then `addIfAbsent` so stored rows never\n // clobber pending mutations); `FileSystemDbCollection.save` and\n // `BrowserStorageCollection.save` both do exactly that.\n //\n // This has now been a data-loss defect twice — known-defects #18\n // (file-system) and #30 (browser-storage).\n for (const { collection, changes } of staged) {\n if (changes.updates.length === 0 && changes.removes.length === 0) {\n continue;\n }\n\n pipeline.pipe((d) => {\n collection.load(readResult => {\n if (readResult.ok === Result.ERROR) {\n d(readResult);\n return;\n }\n d(Result.success());\n });\n });\n }\n\n // Phase 2 — validate everything, then apply everything, then save everything.\n pipeline.pipe((d) => {\n try {\n // Validate: optimistic-concurrency checks for EVERY collection run\n // before ANY collection is touched, so a conflict rejects the whole\n // save with nothing written anywhere.\n for (const { schema, collection, changes } of staged) {\n const conflicts: IdType[] = [];\n\n for (const { entity, concurrency } of changes.updates) {\n if (concurrency == null) {\n continue;\n }\n\n const id = schema.getId(entity as never);\n const stored = collection.getByIds([id]) as Record<string, unknown> | null;\n\n // A missing row is not a token conflict — it falls through\n // to the same no-op an unconditional update would be.\n if (stored != null && stored[concurrency.column] !== concurrency.expected) {\n conflicts.push(id);\n }\n }\n\n if (conflicts.length > 0) {\n d(Result.error(new OptimisticConcurrencyError(schema.collectionName, conflicts)));\n return;\n }\n }\n\n // Apply, recording the inverse of every mutation. The in-memory maps\n // make undo exact: an add is removed, an update or remove restores the\n // captured prior record.\n const undo: (() => void)[] = [];\n\n const revert = () => {\n for (let i = undo.length - 1; i >= 0; i--) {\n undo[i]();\n }\n };\n\n try {\n for (const { schema, collection, changes, result } of staged) {\n const { adds, updates, removes } = changes;\n\n result.adds = Array.from({ length: adds.length });\n result.updates = Array.from({ length: updates.length });\n result.removes = Array.from({ length: removes.length });\n\n for (let j = 0; j < adds.length; j++) {\n const item = adds[j];\n collection.add(item);\n undo.push(() => collection.remove(item));\n result.adds[j] = item as DeepPartial<InferCreateType<UnknownRecord>>;\n }\n\n for (let j = 0; j < updates.length; j++) {\n const item = updates[j].entity;\n const prior = collection.getByIds(schema.getIds(item as never)) as Record<string, unknown> | undefined;\n collection.update(item);\n undo.push(prior != null ? () => collection.update(prior) : () => collection.remove(item));\n result.updates[j] = item;\n }\n\n for (let j = 0; j < removes.length; j++) {\n const item = removes[j];\n const prior = collection.getByIds(schema.getIds(item as never)) as Record<string, unknown> | undefined;\n collection.remove(item);\n if (prior != null) {\n undo.push(() => collection.update(prior));\n }\n result.removes[j] = item;\n }\n }\n } catch (applyError) {\n revert();\n d(Result.error(applyError));\n return;\n }\n\n // Save every collection. A failure reverts the memory state and\n // re-saves the files already written so disk follows it back.\n const saveNext = (index: number) => {\n if (index >= staged.length) {\n d(Result.success());\n return;\n }\n\n staged[index].collection.save(saveResult => {\n if (saveResult.ok === Result.ERROR) {\n revert();\n\n const resaveNext = (k: number) => {\n if (k >= index) {\n d(saveResult);\n return;\n }\n\n staged[k].collection.save(() => resaveNext(k + 1));\n };\n\n resaveNext(0);\n return;\n }\n\n saveNext(index + 1);\n });\n };\n\n saveNext(0);\n } catch (e) {\n d(Result.error(e));\n }\n });\n\n pipeline.filter((result) => {\n if (result.ok === Result.ERROR) {\n done(PluginEventResult.error(event.id, result.error));\n return;\n }\n done(PluginEventResult.success(event.id, bulkPersistResult));\n });\n } catch (e: any) {\n done(PluginEventResult.error(event.id, e));\n }\n }\n\n /**\n * Loads the inner side of a join, when the query carries one.\n *\n * This is the whole of \"interpretation 2\" for the ephemeral family — memory, file-system and\n * browser-storage all reach the inner collection the same way they reach the outer one, so\n * the wiring lives here once rather than in each subclass. The shared hash join in\n * `JsonTranslator.join` does everything after it.\n *\n * `load()` is called on the inner collection too: a durable subclass has nothing in memory\n * until it reads, and a join that skipped it would return no pairs on the first query after\n * a restart — an empty result, not an error.\n *\n * The rows are CLONED, like the outer side's are. Deserialization builds a new object for the\n * entity and its nested objects, but an array property can come through by reference — and\n * here that reference is the one this plugin's own storage holds, so a caller appending to a\n * joined row's array would be editing the database. The outer path has always cloned for this\n * reason; the inner path is the same read.\n *\n * @param outerKeys The distinct keys the outer rows actually hold — the semi-join prefilter.\n * Rows whose key is not among them cannot pair with anything, so they are skipped before the\n * clone rather than after the hash join, which is where the saving is. `null` means the outer\n * side had more distinct keys than `semiJoinKeyThreshold`, so every inner row is taken and the\n * join discards the surplus. Same pairs either way.\n */\n private resolveJoinInnerSide<TEntity extends {}, TShape>(\n event: DbPluginQueryEvent<TEntity, TShape>,\n outerKeys: ReadonlySet<unknown> | null,\n done: (result: { ok: \"success\", innerSide?: JoinInnerSide } | { ok: \"error\", error: unknown }) => void\n ) {\n const joinOption = event.operation.options.getLast(\"join\");\n\n if (joinOption == null) {\n done({ ok: \"success\" });\n return;\n }\n\n const innerSchema = event.schemas.get(joinOption.value.innerSchemaId);\n\n if (innerSchema == null) {\n done({\n ok: \"error\",\n error: new Error(`Cannot join: the inner collection's schema is not registered in this store. SchemaId: ${joinOption.value.innerSchemaId}`)\n });\n return;\n }\n\n const innerCollection = this.resolveCollection(innerSchema);\n\n innerCollection.load(r => {\n if (r.ok === Result.ERROR) {\n done({ ok: \"error\", error: r.error });\n return;\n }\n\n const cloneRecord = this.recordCloner(innerSchema);\n const innerRows: Record<string, unknown>[] = [];\n\n // Records are held in STORAGE shape, so the key is read by its resolved column name.\n const innerKey = joinOption.value.innerKey;\n const keyColumn = innerKey.property?.getResolvedName() ?? innerKey.propertyName;\n\n for (const record of innerCollection.values()) {\n if (outerKeys != null && outerKeys.has(record[keyColumn]) === false) {\n continue;\n }\n\n innerRows.push(cloneRecord(record));\n }\n\n const narrowing = outerKeys == null ? \"full scan\" : `narrowed by ${outerKeys.size} outer ${outerKeys.size === 1 ? \"key\" : \"keys\"}`;\n\n event.executedQueries.push({\n text: `${innerSchema.collectionName}: scanned ${innerRows.length} in-memory ${innerRows.length === 1 ? \"record\" : \"records\"} for join inner side (${narrowing})`\n });\n\n done({ ok: \"success\", innerSide: { innerSchema, innerRows } });\n });\n }\n\n /**\n * How to copy a stored record of this schema.\n *\n * Stored records use the storage shape (`from` names). `schema.clone` reads IN-MEMORY property\n * names and would silently drop renamed fields, so a schema with renames uses the cloner\n * generated against the storage shape instead. Both are generated code; the renamed case used\n * to fall back to `structuredClone`, which is roughly an order of magnitude slower and was paid\n * on EVERY read of EVERY schema that renames a property.\n */\n private recordCloner(schema: CompiledSchema<any>) {\n const hasRenamedProperties = schema.properties.some(property => property.from != null);\n\n return (hasRenamedProperties ? schema.cloneStorage : schema.clone) as (record: Record<string, unknown>) => Record<string, unknown>;\n }\n\n query<TEntity extends {}, TShape extends any = TEntity>(event: DbPluginQueryEvent<TEntity, TShape>, done: PluginEventCallbackResult<ITranslatedValue<TShape>>): void {\n this._query(event, done);\n }\n\n private _query<TEntity extends {}, TShape extends any = TEntity>(event: DbPluginQueryEvent<TEntity, TShape>, done: PluginEventCallbackResult<ITranslatedValue<TShape>>): void {\n try {\n const operation = event.operation;\n const schema = operation.schema;\n const collection = this.resolveCollection(schema);\n\n const cloneRecord = this.recordCloner(schema);\n\n collection.load(r => {\n if (r.ok === Result.ERROR) {\n done(PluginEventResult.error(event.id, r.error));\n return;\n }\n\n const orderedOptions: { name: string, value: any }[] = [];\n operation.options.forEach(o => orderedOptions.push(o));\n\n let leadingFilterCount = 0;\n\n while (leadingFilterCount < orderedOptions.length && orderedOptions[leadingFilterCount].name === \"filter\") {\n leadingFilterCount++;\n }\n\n // Key-equality fast path: when a leading filter's parsed expression pins\n // the key property to a single value, resolve that record directly from\n // the collection instead of scanning everything\n let source: Record<string, unknown>[] | null = null;\n\n if (schema.idProperties.length === 1) {\n for (let i = 0; i < leadingFilterCount; i++) {\n const id = getKeyEqualityValue(orderedOptions[i].value.expression);\n\n if (id == null) {\n continue;\n }\n\n const found = collection.getByIds([id.value]);\n source = found == null ? [] : [found];\n break;\n }\n }\n\n // Apply the leading filter options against the raw records before cloning\n // so only surviving rows pay the clone cost. Filter predicates are pure,\n // so re-running them inside translate() is a no-op pass over the survivors.\n //\n // Filter and clone are FUSED into one pass, and the unfiltered case iterates\n // the collection instead of spreading it into an array. The staged form walked\n // the collection up to four times and allocated a full-size array at each step.\n const leadingFilters: { filter: (arg: any) => unknown, params: unknown | null }[] = [];\n\n for (let i = 0; i < leadingFilterCount; i++) {\n const value = orderedOptions[i].value;\n\n if (value.filter == null) {\n continue;\n }\n\n leadingFilters.push({ filter: value.filter, params: value.params ?? null });\n }\n\n const filterCount = leadingFilters.length;\n const cloned: Record<string, unknown>[] = [];\n\n for (const record of (source ?? collection.values())) {\n let kept = true;\n\n for (let i = 0; i < filterCount; i++) {\n const { filter, params } = leadingFilters[i];\n\n // Truthiness, not === true: Array.prototype.filter keeps a row on any\n // truthy return, and these predicates are generated code that returns\n // whatever the expression evaluated to.\n if (!(params == null ? filter(record) : filter([record, params]))) {\n kept = false;\n break;\n }\n }\n\n if (kept === false) {\n continue;\n }\n\n cloned.push(cloneRecord(record));\n }\n\n /**\n * The inner side is loaded LAST, once the outer rows are known.\n *\n * That ordering is the whole semi-join: the outer keys are what narrow the inner\n * read, and they do not exist until the outer filters have run. Reading the inner\n * side first — which is what this did before — means loading and cloning a whole\n * collection to pair it with three rows.\n *\n * `cloned` is in storage shape, so the keys are read by resolved column name.\n */\n // No statement to quote — an ephemeral store walks its own records. Said\n // plainly so `.explain()` does not leave a reader wondering whether the\n // plugin simply failed to report. Before the inner side, to match execution order.\n event.executedQueries.push({\n text: `${operation.schema.collectionName}: scanned ${cloned.length} in-memory ${cloned.length === 1 ? \"record\" : \"records\"}`\n });\n\n const joinOption = operation.options.getLast(\"join\");\n const outerKeys = joinOption == null\n ? null\n : distinctJoinKeys(cloned, joinOption.value.outerKey, joinOption.value.semiJoinKeyThreshold, { storageShape: true });\n\n this.resolveJoinInnerSide(event, outerKeys, joinResult => {\n if (joinResult.ok === \"error\") {\n done(PluginEventResult.error(event.id, joinResult.error));\n return;\n }\n\n try {\n const translator = new JsonTranslator<TEntity, TShape>(operation, joinResult.innerSide);\n\n done(PluginEventResult.success(event.id, translator.translate(cloned)));\n } catch (e) {\n done(PluginEventResult.error(event.id, e));\n }\n });\n });\n } catch (e) {\n done(PluginEventResult.error(event.id, e));\n }\n }\n\n abstract destroy(event: DbPluginEvent, done: PluginEventCallbackResult<never>): void;\n}","import { BulkPersistResult } from \"../collections\";\nimport { PluginEventCallbackPartialResult, PluginEventCallbackResult, PluginEventResult } from \"../results\";\nimport { ITranslatedValue } from \"./translators\";\nimport { DbPluginBulkPersistEvent, DbPluginEvent, DbPluginQueryEvent, IDbPlugin } from \"./types\";\n\n/**\n * Retries a failed READ, and never a write.\n *\n * ## Why reads only\n *\n * A read is idempotent by construction: running the same query twice asks the same question\n * and changes nothing, so a second attempt is free apart from latency. That is what makes a\n * blanket retry safe here, and it is why this wrapper does not need to know which errors are\n * transient — see `shouldRetry`.\n *\n * A save is not. `bulkPersist` is a batch of adds, updates and removes, and a failure gives no\n * general way to know how much of it landed: a backend without atomic batches may have applied\n * part of it, and a retry then re-applies what already succeeded. Adds are the sharpest case —\n * an identity is assigned by the database, so a repeated INSERT does not collide, it\n * DUPLICATES. Rows appear that no caller asked for, no error is reported, and the change\n * tracker records a successful save.\n *\n * Retrying a write safely would need the write to carry an idempotency key the backend\n * deduplicates on, which is a property of a backend rather than something a wrapper can add.\n * So this refuses to guess, and a failed save is surfaced for the caller to decide about.\n *\n * ```ts\n * const store = new MyStore(new RetryDbPlugin(new SomeDbPlugin(...), { attempts: 3 }));\n * ```\n */\n\nexport type RetryDbPluginOptions = {\n /**\n * Total attempts, including the first. Default 3, minimum 1.\n *\n * \"Attempts\" rather than \"retries\" because off-by-one here is a real cost — the difference\n * between three calls and four against a struggling backend.\n */\n attempts?: number;\n /**\n * Milliseconds to wait before attempt `attempt` (2 for the first retry).\n *\n * Default is exponential — 50ms, 100ms, 200ms — with no jitter. Jitter matters when many\n * clients retry in lockstep after a shared outage, and a caller with that problem knows it\n * and can supply a delay; adding randomness by default would make tests non-deterministic\n * for everyone else.\n */\n delayMs?: (attempt: number) => number;\n /**\n * Whether an error is worth another attempt. Default: every error is.\n *\n * That default is deliberate and only defensible because this retries reads alone. A\n * wrapper cannot know which of a backend's errors are transient without naming that\n * backend, and guessing wrong in the cautious direction means not retrying the failure the\n * caller installed this for. Retrying a permanent error instead costs a bounded amount of\n * latency and nothing else.\n *\n * Supply this to narrow it — a syntax error in a filter will never succeed on a second try.\n */\n shouldRetry?: (error: unknown, attempt: number) => boolean;\n};\n\nconst DEFAULT_ATTEMPTS = 3;\nconst defaultDelay = (attempt: number) => 50 * Math.pow(2, attempt - 2);\n\nexport class RetryDbPlugin implements IDbPlugin {\n\n private readonly plugin: IDbPlugin;\n private readonly attempts: number;\n private readonly delayMs: (attempt: number) => number;\n private readonly shouldRetry: (error: unknown, attempt: number) => boolean;\n\n constructor(plugin: IDbPlugin, options: RetryDbPluginOptions = {}) {\n this.plugin = plugin;\n // Floored at 1: zero attempts would never call the inner plugin and would report a\n // failure that never happened.\n this.attempts = Math.max(1, options.attempts ?? DEFAULT_ATTEMPTS);\n this.delayMs = options.delayMs ?? defaultDelay;\n this.shouldRetry = options.shouldRetry ?? (() => true);\n }\n\n get databaseName(): string {\n return this.plugin.databaseName;\n }\n\n query<TRoot extends {}, TShape extends any = TRoot>(\n event: DbPluginQueryEvent<TRoot, TShape>,\n done: PluginEventCallbackResult<ITranslatedValue<TShape>>\n ): void {\n this.attempt(event, done, 1);\n }\n\n /**\n * One attempt, scheduling the next on failure.\n *\n * Recursive rather than a loop because the inner plugin is callback-based: there is no\n * promise to await, and wrapping each attempt in one would change when errors surface.\n */\n private attempt<TRoot extends {}, TShape>(\n event: DbPluginQueryEvent<TRoot, TShape>,\n done: PluginEventCallbackResult<ITranslatedValue<TShape>>,\n attempt: number\n ): void {\n this.plugin.query<TRoot, TShape>(event, result => {\n\n if (result.ok !== PluginEventResult.ERROR) {\n done(result);\n return;\n }\n\n const isLastAttempt = attempt >= this.attempts;\n\n if (isLastAttempt || this.shouldRetry(result.error, attempt) === false) {\n // The error from the LAST attempt, not the first. It is the most recent state\n // of the world, and a caller comparing two failures wants the newer one.\n done(result);\n return;\n }\n\n const delay = this.delayMs(attempt + 1);\n\n if (delay <= 0) {\n this.attempt(event, done, attempt + 1);\n return;\n }\n\n setTimeout(() => this.attempt(event, done, attempt + 1), delay);\n });\n }\n\n bulkPersist(\n event: DbPluginBulkPersistEvent,\n done: PluginEventCallbackPartialResult<BulkPersistResult>\n ): void {\n // Straight through. See the note on this class: a partly-applied save cannot be\n // repeated safely, and a duplicated add is worse than a surfaced error.\n this.plugin.bulkPersist(event, done);\n }\n\n destroy(event: DbPluginEvent, done: PluginEventCallbackResult<never>): void {\n // Not retried either. Destroy is usually irreversible, and a second attempt against a\n // database the first one already removed reports a failure for work that succeeded.\n this.plugin.destroy(event, done);\n }\n}\n","import { BulkPersistResult } from \"../collections\";\nimport { SchemaId } from \"../schema\";\nimport { PluginEventCallbackPartialResult, PluginEventCallbackResult, PluginEventResult } from \"../results\";\nimport { ITranslatedValue } from \"./translators\";\nimport { QueryOption, QueryOptionName } from \"./query\";\nimport { DbPluginBulkPersistEvent, DbPluginEvent, DbPluginQueryEvent, IDbPlugin } from \"./types\";\n\n/**\n * A read-through LRU in front of a slower plugin.\n *\n * ## What it can and cannot promise\n *\n * Invalidation is the whole problem with a cache, and this one solves exactly one version of\n * it: **writes that go through this wrapper**. A save invalidates every cached read for the\n * schemas it touched, so a store that reads and writes through the same instance never sees\n * its own stale data.\n *\n * It cannot see anything else. A write by another process, another tab, or another store over\n * the same database leaves this cache holding rows that no longer exist, until they age out.\n * That is not a defect to fix later — a cache in front of a plugin has no way to learn about a\n * change it did not make — it is the condition for using this at all. Put it in front of data\n * that is slow to fetch and tolerant of being briefly wrong, and nowhere else.\n *\n * Invalidation is per SCHEMA rather than per row, deliberately. Deciding whether a changed row\n * would have matched a cached filter means evaluating every cached query against it, which is\n * the work the cache exists to avoid, and getting it wrong keeps a stale row visible. Dropping\n * a schema's entries is cheap and cannot be subtly wrong.\n *\n * ```ts\n * const store = new MyStore(new CacheDbPlugin(new SomeDbPlugin(...), { max: 100 }));\n * ```\n */\n\nexport type CacheDbPluginOptions = {\n /** How many query results to keep. Default 100; the least recently used is evicted. */\n max?: number;\n};\n\ntype CacheEntry = {\n readonly value: unknown;\n readonly isTransformed: boolean;\n /** The concrete translated-value class, so a hit rebuilds the same shape. */\n readonly construct: new (value: unknown, isTransformed: boolean) => ITranslatedValue<unknown>;\n};\n\n/**\n * A stable string for one query.\n *\n * Built from the option VALUES rather than by serialising the expression tree, which holds\n * `PropertyInfo` objects carrying functions and would not survive `JSON.stringify`. A filter is\n * identified by its source text plus its params, which is what the expression is derived from\n * anyway — two queries with the same source and params are the same query.\n */\nconst describeOption = (option: QueryOption<unknown, QueryOptionName>): string => {\n const value = option.value as Record<string, unknown>;\n\n switch (option.name) {\n case \"filter\":\n return `${String(value.filter)}|${JSON.stringify(value.params ?? null)}`;\n case \"sort\":\n return `${String(value.propertyName)}|${String(value.direction)}`;\n case \"nearest\":\n return `${String(value.propertyName)}|${(value.vector as number[]).join(\",\")}|${String(value.count)}`;\n case \"map\":\n case \"group\":\n return String(value.selector);\n default:\n // skip, take and the aggregates are plain values.\n return JSON.stringify(option.value ?? null);\n }\n};\n\nexport class CacheDbPlugin implements IDbPlugin {\n\n private readonly plugin: IDbPlugin;\n private readonly max: number;\n /**\n * Insertion-ordered, which is what makes this an LRU without a second structure: a hit\n * deletes and re-sets the key to move it to the end, so the oldest is always first.\n */\n private readonly entries = new Map<string, CacheEntry>();\n\n constructor(plugin: IDbPlugin, options: CacheDbPluginOptions = {}) {\n this.plugin = plugin;\n this.max = Math.max(1, options.max ?? 100);\n }\n\n get databaseName(): string {\n return this.plugin.databaseName;\n }\n\n /** `schemaId` first, so invalidating a schema is a prefix match. */\n private keyFor<TRoot extends {}, TShape>(event: DbPluginQueryEvent<TRoot, TShape>): string {\n const parts: string[] = [];\n\n event.operation.options.forEach(option => {\n parts.push(`${option.name}:${describeOption(option as QueryOption<unknown, QueryOptionName>)}`);\n });\n\n return `${String(event.operation.schema.id)}\\u0000${parts.join(\"\\u0001\")}`;\n }\n\n /**\n * A fresh translated value over a copy of the cached data.\n *\n * Never the cached object itself, and never its array. `TranslatedArrayValue.forEach`\n * REASSIGNS its own slots — that is how the change tracker swaps in attached entities —\n * so handing out the cached instance would let the first caller replace the cache's\n * contents with its own tracked proxies. The second caller would then receive entities\n * attached to somebody else's store.\n *\n * It protects a second thing that is easy to miss, so do not replace it with a shallow copy\n * or hand out the entry directly. `ConcurrencyDbPlugin` strips `__version` from result rows\n * IN PLACE after observing them. Stacked as `ConcurrencyDbPlugin(CacheDbPlugin(...))` the\n * strip therefore lands on this copy, and the cached row keeps its token — without that,\n * every hit after the first would carry no version, the observer would record nothing, and\n * the next update would be written UNCHECKED with no error anywhere.\n * Pinned by `datastore/src/collections/wrapperStacking.test.ts`.\n */\n private rebuild(entry: CacheEntry): ITranslatedValue<unknown> {\n return new entry.construct(structuredClone(entry.value), entry.isTransformed);\n }\n\n query<TRoot extends {}, TShape extends any = TRoot>(\n event: DbPluginQueryEvent<TRoot, TShape>,\n done: PluginEventCallbackResult<ITranslatedValue<TShape>>\n ): void {\n const key = this.keyFor(event);\n const cached = this.entries.get(key);\n\n if (cached != null) {\n // Re-set to move it to the end of the insertion order: most recently used.\n this.entries.delete(key);\n this.entries.set(key, cached);\n\n // Said rather than left blank. A hit means no database was touched, which is a fact\n // worth reporting — and an empty report would otherwise read as a plugin that failed\n // to say what it ran.\n event.executedQueries.push({ text: \"cache hit — no query was executed\" });\n\n done(PluginEventResult.success(event.id, this.rebuild(cached) as ITranslatedValue<TShape>));\n return;\n }\n\n this.plugin.query<TRoot, TShape>(event, result => {\n\n if (result.ok === PluginEventResult.ERROR) {\n done(result);\n return;\n }\n\n this.store(key, result.data);\n\n // The caller gets a rebuilt value too, not the one just stored, so that mutating\n // the result of a MISS cannot corrupt what the next hit returns.\n const stored = this.entries.get(key);\n\n done(PluginEventResult.success(\n event.id,\n (stored == null ? result.data : this.rebuild(stored)) as ITranslatedValue<TShape>\n ));\n });\n }\n\n private store(key: string, value: ITranslatedValue<unknown>): void {\n let snapshot: unknown;\n\n try {\n snapshot = structuredClone(value.value);\n } catch {\n // Not every result is structured-cloneable — a projection can carry anything a\n // caller's `.map()` returned, including a function. Declining to cache is the\n // only safe answer; caching a reference would share mutable state.\n return;\n }\n\n this.entries.set(key, {\n value: snapshot,\n isTransformed: value.isTransformed,\n construct: value.constructor as CacheEntry[\"construct\"],\n });\n\n if (this.entries.size > this.max) {\n // First key is the least recently used, because every hit re-inserts.\n const oldest = this.entries.keys().next();\n\n if (oldest.done === false) {\n this.entries.delete(oldest.value);\n }\n }\n }\n\n /** Drops every cached read for these schemas. */\n private invalidate(schemaIds: Iterable<SchemaId>): void {\n for (const schemaId of schemaIds) {\n const prefix = `${String(schemaId)}\\u0000`;\n\n for (const key of [...this.entries.keys()]) {\n if (key.startsWith(prefix)) {\n this.entries.delete(key);\n }\n }\n }\n }\n\n bulkPersist(\n event: DbPluginBulkPersistEvent,\n done: PluginEventCallbackPartialResult<BulkPersistResult>\n ): void {\n const touched = [...event.operation.keys()];\n\n // Invalidated BEFORE the write is attempted, not after it succeeds. A failed save can\n // still have applied part of itself on a backend without atomic batches, and a cache\n // that kept its entries because the call reported an error would then serve rows that\n // are wrong. Throwing away a still-valid cache costs one refetch; keeping an invalid\n // one is silent.\n this.invalidate(touched);\n\n this.plugin.bulkPersist(event, result => {\n this.invalidate(touched);\n done(result);\n });\n }\n\n destroy(event: DbPluginEvent, done: PluginEventCallbackResult<never>): void {\n this.entries.clear();\n this.plugin.destroy(event, done);\n }\n}\n","import { BulkPersistChanges, BulkPersistResult, SchemaCollection, SchemaPersistResult } from \"../collections\";\nimport { PluginDestroyedError } from \"../errors\";\nimport { PluginEventCallbackPartialResult, PluginEventCallbackResult, PluginEventPartialResultType, PluginEventPartialType, PluginEventResult, PluginEventSuccessType } from \"../results\";\nimport { SchemaId } from \"../schema\";\nimport { ITranslatedValue } from \"./translators\";\nimport { DbPluginBulkPersistEvent, DbPluginEvent, DbPluginQueryEvent, IDbPlugin } from \"./types\";\nimport { uuid } from \"../utilities\";\n\nexport type BatchingDbPluginOptions = {\n /**\n * The caller PROMISING that a failed `bulkPersist` beneath this wrapper leaves NOTHING\n * applied. Only then may separate callers' saves be merged into one write, because the\n * failure path re-runs a failed batch item by item — and re-running a HALF-APPLIED batch\n * applies the landed items twice, which for adds means duplicate rows under fresh\n * identities, with nothing raised.\n *\n * Omitted, the wrapper still queues and serializes; it just writes batches of one, which\n * is what happens without it in the stack at all. True of SQLite, PostgreSQL and MySQL —\n * one transaction, rolled back entire. Not true of anything that applies writes as it\n * goes without a way to undo them.\n */\n isAtomic?: boolean;\n /**\n * The most writes one drain may take. Default 100.\n *\n * A drain takes everything waiting, so a burst puts an unbounded statement set in one\n * transaction — and some engines cap that outright, D1's `batch()` in particular. Taking N\n * per pass changes none of the reasoning: the remainder is still waiting, the next drain\n * runs the moment this one returns, and a batch is still only what had already arrived.\n *\n * It also bounds the failure fallback, which costs N+1 writes for a failing batch of N.\n */\n maxBatchSize?: number;\n};\n\nconst DEFAULT_MAX_BATCH_SIZE = 100;\n\n/** A caller's write, waiting its turn. */\ntype QueuedWrite = {\n readonly event: DbPluginBulkPersistEvent;\n readonly done: PluginEventCallbackPartialResult<BulkPersistResult>;\n};\n\n/**\n * A batch of writes that may go out as ONE, with the merged event already built.\n * `items` is kept so a failure can re-run them individually and so results can be split back.\n */\ntype PreparedGroup = {\n readonly items: QueuedWrite[];\n readonly event: DbPluginBulkPersistEvent;\n};\n\n/**\n * Coalesces overlapping writes into single round trips.\n *\n * ## Why\n *\n * One logical change produces more than one write: the caller's `saveChanges`, then every view\n * reconciling in response to it. A store with three views issues four writes, none coordinated\n * with the others. On a local file that is invisible; against a server the round trip dominates\n * everything else a save does.\n *\n * ## The shape, and why it cannot cost anything\n *\n * A write arrives and joins the queue. If one is already in flight, the running drain will take\n * it. Otherwise drain immediately: take everything waiting up to `maxBatchSize` and write it,\n * then drain again for whatever arrived meanwhile and whatever the ceiling left behind.\n *\n * Nothing polls, nothing sleeps, nothing waits for a batch to fill. **A batch is only what had\n * already arrived**, so when writes do not overlap the queue is empty, the batch is one item,\n * and the write is byte for byte what happens without this wrapper. Latency cannot increase;\n * throughput improves exactly when there is contention to improve.\n *\n * ## What may be merged\n *\n * Only items whose schemas do not overlap, and only with `isAtomic`. Two writes to one\n * collection are genuinely ordered — a plugin applies removes, then updates, then adds WITHIN a\n * schema, so merging an add of a row with a later update of it would run the update first,\n * against a row that does not exist yet, and lose it silently. Items sharing a schema therefore\n * go in separate writes, in arrival order.\n *\n * That same rule is what lets a merged result be split back by SCHEMA rather than by position:\n * each schema in a merged write came from exactly one item, so no assumption about the order a\n * plugin echoes rows in is needed anywhere.\n *\n * @see specs/write-batching.md\n */\nexport class BatchingDbPlugin implements IDbPlugin {\n\n private readonly plugin: IDbPlugin;\n private readonly canMerge: boolean;\n private readonly maxBatchSize: number;\n\n private readonly queue: QueuedWrite[] = [];\n private isWriting = false;\n private isDestroyed = false;\n /** Set when `destroy` arrives mid-write; run once the in-flight batch settles. */\n private onSettled: (() => void) | null = null;\n\n constructor(plugin: IDbPlugin, options: BatchingDbPluginOptions = {}) {\n this.plugin = plugin;\n this.canMerge = options.isAtomic === true;\n // Floored at 1: a ceiling of zero would take nothing and drain forever.\n this.maxBatchSize = Math.max(1, options.maxBatchSize ?? DEFAULT_MAX_BATCH_SIZE);\n }\n\n get databaseName(): string {\n return this.plugin.databaseName;\n }\n\n /** Reads are not batched: they have no lock to contend for and no ordering to preserve. */\n query<TRoot extends {}, TShape extends any = TRoot>(\n event: DbPluginQueryEvent<TRoot, TShape>,\n done: PluginEventCallbackResult<ITranslatedValue<TShape>>\n ): void {\n this.plugin.query(event, done);\n }\n\n bulkPersist(\n event: DbPluginBulkPersistEvent,\n done: PluginEventCallbackPartialResult<BulkPersistResult>\n ): void {\n\n if (this.isDestroyed) {\n // Fails rather than passing through. The queue's contract is that an accepted write\n // is eventually answered by a live drain loop, and there is no loop left; passing it\n // down is worse still, since a plugin that creates missing tables would recreate the\n // database the destroy just deleted and report success against an empty one.\n done(PluginEventResult.error(event.id, new PluginDestroyedError(\"write submitted after destroy\")));\n return;\n }\n\n this.queue.push({ event, done });\n\n // In flight: the continuation below takes this one. Doing anything else here is what\n // turns a queue into a race.\n if (this.isWriting) {\n return;\n }\n\n this.drain();\n }\n\n /**\n * Destroys the inner plugin, answering everything this wrapper is holding first.\n *\n * `destroy` is destructive rather than graceful — the SQLite plugin deletes the database —\n * so draining first would spend round trips producing state the next call destroys, and\n * the drain loop refills, making teardown unbounded. Queued items are therefore failed\n * rather than flushed.\n *\n * An in-flight write is a different matter: it has already been sent, destroying cannot\n * un-send it, and its callers are owed the real result. So the inner `destroy` waits for it\n * to settle — dropping a `deleteDatabase` on top of an open transaction is its own failure.\n */\n destroy(event: DbPluginEvent, done: PluginEventCallbackResult<never>): void {\n this.isDestroyed = true;\n\n for (const item of this.queue.splice(0)) {\n this.answer(item, PluginEventResult.error(\n item.event.id,\n new PluginDestroyedError(\"destroyed before the write was attempted\")\n ));\n }\n\n const forward = () => this.plugin.destroy(event, done);\n\n if (this.isWriting) {\n this.onSettled = forward;\n return;\n }\n\n forward();\n }\n\n /**\n * Takes everything waiting and writes it, then schedules itself again for whatever arrived\n * while that ran.\n */\n private drain(): void {\n // Not everything — up to the ceiling. Whatever is left stays queued for the next pass,\n // which starts as soon as this one returns.\n const batch = this.queue.splice(0, this.maxBatchSize);\n\n if (batch.length === 0) {\n this.isWriting = false;\n\n const settled = this.onSettled;\n\n if (settled != null) {\n this.onSettled = null;\n settled();\n }\n\n return;\n }\n\n this.isWriting = true;\n\n // The latch's only way down. Every path below MUST reach it: an exception that escaped\n // would leave `isWriting` stuck true and every future write queued forever — a total,\n // silent write outage that nothing else would report.\n const next = () => this.drain();\n\n let groups: PreparedGroup[];\n\n try {\n groups = this.prepare(batch);\n } catch (error) {\n // A throw here is a bug in this wrapper rather than a backend failure, and — because\n // preparing is pure and happens BEFORE any write is issued — nothing has been\n // applied. Degrading to one write per item is exactly what not batching does.\n //\n // This is also why the guard stops here and does not cover `writeGroups`. If group 1\n // had already landed, re-running the batch item by item would apply it twice, which\n // is the hazard `isAtomic` exists to rule out.\n this.writeIndividually(batch, next);\n return;\n }\n\n this.writeGroups(groups, 0, next);\n }\n\n /**\n * Partitions the batch, APPEND-ONLY: an item joins the last group if none of its schemas is\n * claimed there, and otherwise closes that group and starts a new one.\n *\n * Not first-fit. Scanning every open group for one an item fits merges more, and reorders\n * doing it: with arrivals A(schema S), B(schema S), C(schema T), first-fit would put C in\n * A's group and write it before the earlier-arrived B. Nothing is lost inside a table, but a\n * caller who saved B before C could observe C land first. The last-group rule keeps arrival\n * order unconditionally — everything in group N arrived before everything in group N+1 — and\n * on the case that matters, several views over distinct schemas, both rules produce the same\n * single group.\n */\n private prepare(batch: QueuedWrite[]): PreparedGroup[] {\n const groups: QueuedWrite[][] = [];\n let claimed = new Set<SchemaId>();\n\n for (const item of batch) {\n const schemas = [...item.event.operation.keys()];\n const overlaps = schemas.some(schemaId => claimed.has(schemaId));\n\n if (groups.length === 0 || overlaps || this.canMerge === false) {\n groups.push([item]);\n claimed = new Set(schemas);\n continue;\n }\n\n groups[groups.length - 1].push(item);\n\n for (const schemaId of schemas) {\n claimed.add(schemaId);\n }\n }\n\n return groups.map(items => ({ items, event: this.mergeEvents(items) }));\n }\n\n /**\n * One event standing for several. Synthetic THROUGHOUT: its own id, its operation the union\n * of the items' operations, and its schemas the union of theirs — a plugin resolving\n * `event.schemas.get(schemaId)` must find every schema any item brought.\n *\n * A single-item group passes its own event through untouched. That is most writes, so the\n * uncontended path never reaches the merging machinery at all.\n */\n private mergeEvents(items: QueuedWrite[]): DbPluginBulkPersistEvent {\n\n if (items.length === 1) {\n return items[0].event;\n }\n\n const operation = new BulkPersistChanges();\n const schemas = new SchemaCollection();\n\n for (const item of items) {\n for (const [schemaId, changes] of item.event.operation) {\n operation.set(schemaId, changes);\n }\n\n for (const [schemaId, schema] of item.event.schemas) {\n schemas.set(schemaId, schema);\n }\n }\n\n return {\n ...items[0].event,\n // Its own id: no caller has ever seen this one, and nothing upstream may be handed it.\n id: uuid(16),\n source: \"BatchingDbPlugin\",\n reason: `merged ${items.length} writes`,\n operation,\n schemas,\n };\n }\n\n /** Groups go out in order, because two writes to one collection are genuinely ordered. */\n private writeGroups(groups: PreparedGroup[], index: number, next: () => void): void {\n\n if (index >= groups.length) {\n next();\n return;\n }\n\n const group = groups[index];\n const advance = () => this.writeGroups(groups, index + 1, next);\n\n const attempt = (result: PluginEventPartialResultType<BulkPersistResult>) => {\n\n if (result.ok === PluginEventResult.ERROR) {\n\n if (group.items.length === 1) {\n this.answer(group.items[0], result);\n advance();\n return;\n }\n\n // Coupled failure, unpicked: one caller's bad data must not fail its\n // batchmates, so the batch is re-run item by item. Costs N+1 writes for a\n // failing batch of N, paid only when something is already going wrong. Safe\n // only because `isAtomic` promised the failed batch left nothing applied.\n this.writeIndividually(group.items, advance);\n return;\n }\n\n this.split(group, result);\n advance();\n };\n\n try {\n this.plugin.bulkPersist(group.event, attempt);\n } catch (error) {\n attempt(PluginEventResult.error(group.event.id, error));\n }\n }\n\n /**\n * Hands each item its own slice of a merged result, keyed by SCHEMA.\n *\n * Disjoint schemas are what make this possible: each schema in the write came from exactly\n * one item, so there is no counting, no slicing by position, and no reliance on the order a\n * plugin echoes rows in — an assumption that is load-bearing elsewhere and would be SILENT\n * here, handing one caller another's database-assigned identities.\n */\n private split(\n group: PreparedGroup,\n result: PluginEventSuccessType<BulkPersistResult> | PluginEventPartialType<BulkPersistResult>\n ): void {\n\n if (group.items.length === 1) {\n this.answer(group.items[0], result);\n return;\n }\n\n const merged = result.data;\n // A PARTIAL from an inner plugin that promised atomicity should not happen. If it does,\n // every caller is told — splitting the data but reporting the error to all of them,\n // rather than retrying. Retrying is what would be unsafe here: partial means something\n // already landed, and re-running it applies that twice.\n const isPartial = result.ok === PluginEventResult.PARTIAL;\n\n for (const item of group.items) {\n const mine = new BulkPersistResult();\n\n for (const schemaId of item.event.operation.keys()) {\n // A schema the plugin had nothing to echo for gets an empty result, never a hole.\n mine.set(schemaId, merged?.get(schemaId) ?? new SchemaPersistResult());\n }\n\n // Answered under ITS OWN event id — the merged write ran under a synthetic one.\n this.answer(item, isPartial\n ? PluginEventResult.partial(item.event.id, mine, (result as PluginEventPartialType<BulkPersistResult>).error)\n : PluginEventResult.success(item.event.id, mine));\n }\n }\n\n /** One write per item, in arrival order — what happens with no batching at all. */\n private writeIndividually(items: QueuedWrite[], next: () => void): void {\n\n const run = (index: number): void => {\n\n if (index >= items.length) {\n next();\n return;\n }\n\n const item = items[index];\n const advance = () => run(index + 1);\n\n try {\n this.plugin.bulkPersist(item.event, result => {\n this.answer(item, result);\n advance();\n });\n } catch (error) {\n this.answer(item, PluginEventResult.error(item.event.id, error));\n advance();\n }\n };\n\n run(0);\n }\n\n /**\n * A caller's callback, guarded. One caller's `done` throwing must not eat its batchmates'\n * results, and must not strand the latch — which it would, since the continuation runs\n * after the answers.\n */\n private answer(item: QueuedWrite, result: PluginEventPartialResultType<BulkPersistResult>): void {\n try {\n item.done(result);\n } catch (error) {\n // Nobody left to tell: the caller we would report to is the one that threw.\n }\n }\n}\n","export * from './types';\nexport * from './translators';\nexport * from './query';\nexport * from './wire';\nexport * from './ConcurrencyDbPlugin';\nexport * from './EphemeralDataPlugin';\nexport * from './RetryDbPlugin';\nexport * from './CacheDbPlugin';\nexport * from './BatchingDbPlugin';\n"],"names":["EXPRESSION_TYPES","isDate","assertDate","data","TypeError","assertIsNotNull","message","assertIsArray","Array","assertString","assertInstanceOf","value","Instance","assertIsNumber","isObjectWithType","isExpression","isOperatorExpression","isComparatorExpression","isPropertyExpression","isValueExpression","isEmptyExpression","isNotParsableExpression","TagCollection","BulkPersistResult","Map","schemaId","SchemaPersistResult","count","result","BulkPersistChanges","SchemaPersistChanges","ReadonlySchemaCollection","callbackfn","thisArg","Symbol","collectionName","found","x","undefined","SchemaCollection","schema","key","tag","keys","i","length","tags","OptimisticConcurrencyError","Error","conflicts","String","error","PluginDestroyedError","reason","UNRESOLVED","applyTransformer","transformer","operand","expression","row","equals","left","right","strict","Date","compare","comparator","asComparable","a","b","comparable","evaluateComparator","item","evaluate","toPredicate","toStrictPredicate","logger","SchemaTypes","Expression","OperatorExpression","ComparatorExpression","ValueExpression","PropertyExpression","ERROR_MESSAGES","path","params","JSON","parseUnknown","ParamDependentParseError","converters","v","Boolean","Number","MULTI_CHARACTER_PUNCTUATION","SINGLE_CHARACTER_PUNCTUATION","Set","STRING_ESCAPES","isIdentifierStart","char","isIdentifierPart","isDigit","isHexDigit","decodeCodeEscape","source","backslashIndex","kind","start","end","parseInt","digits","d","tokenize","tokens","quote","escaped","decoded","nextChar","radixPrefix","signLength","multi","w","TokenStream","offset","token","COMPARATOR_METHODS","TRANSFORM_METHODS","COMPARISON_OPERATORS","SWAPPED_COMPARATORS","ParamReferenceExpression","options","resolveParamPath","paramsName","name","resolvePairedValue","pairedProperty","applyConverter","ExpressionParser","stream","entityName","trailing","operatorToken","numberToken","elements","element","array","method","argument","root","locale","segment","paramPath","resolved","pathString","property","parentPath","parent","operator","comparedToFalse","swapped","target","isStringMatch","bindExpression","raw","bound","clone","resolveFunctionShape","stringifiedFunction","hasParams","parameterNames","body","functionHead","parametersEnd","arrowIndex","destructured","inner","templateCache","WeakMap","MAX_CACHED_TEMPLATES_PER_SCHEMA","getCachedTemplate","setCachedTemplate","entry","bySource","combineExpressions","expressions","parseFragment","rootName","parser","toExpression","fn","warn","cached","template","structurallyDependsOnParams","shape","valueToJson","Object","valueFromJson","EmptyExpression","NotParsableExpression","json","child","node","rebuilt","getProperties","properties","traverse","expr","forEach","callback","Result","TrampolinePipeline","initialData","done","index","currentData","isRunning","finalStepSentinel","createStepRevised","idx","processor","syncCallbackResult","calledSync","nextStep","trampoline","step","currentStep","trampolineError","items","map","previous","WorkPipeline","work","QueryOptionsCollection","mapValue","filterValue","sortValue","nearestValue","joinValue","sortedItems","before","after","at","option","destination","nextExecutionTarget","nextExecutionReason","nextIndex","memoryQueryOptionsCollection","databaseQueryOptionsCollection","sortedItem","transformationOptions","iterator","BaseResult","resolve","reject","PluginEventResult","id","HashType","LOG_LEVELS","RANK","isLogLevel","resolveLevel","globalThis","g","process","debug","env","level","rank","setLogLevel","next","getLogLevel","resetLogLevel","isLogLevelEnabled","emit","args","console","uuid","chars","charLength","Math","HEX_CHARS","UUID_TEMPLATE","hasCrypto","crypto","hasRandomUUID","uuidv4","uuidv4Fallback","randomBytes","Uint8Array","byteIndex","c","r","TranslatedArrayValue","isTransformed","TranslatedGroupValue","group","j","len","TranslatedSingleValue","DataTranslator","query","cosineDistance","Infinity","dot","leftMagnitude","rightMagnitude","l","nearestBy","rows","vector","select","mismatched","scored","stored","Query","enableChangeTrackingOverride","max","min","sum","toEntityShape","readJoinKey","reference","current","isMatchableKey","applyInnerOptions","innerOptions","filtered","filter","selector","hashJoin","outerRows","innerRows","outerKey","innerKey","isLeft","buckets","bucket","tuples","outer","matches","matchLength","DEFAULT_SEMI_JOIN_KEY_THRESHOLD","distinctJoinKeys","threshold","read","semiJoinFilter","values","propertyName","loadJoinInnerSide","event","outerKeys","joinOption","innerSchema","innerEvent","joinInPlugin","outerEvent","outerResult","innerResult","executeJoin","e","JsonTranslator","innerSide","response","field","resolvedValue","keyValue","_","direction","y","needsDateConversion","mapOption","sort","best","functionName","toVector","parsed","SqlTranslator","pushedDown","column","TupleTranslator","tuple","__","MEMORY_EXECUTION_EXPLANATIONS","EXECUTED_QUERIES_UNSUPPORTED","DATABASE_STEP_DESCRIPTION","MEMORY_STEP_DESCRIPTION","UNNARROWED_READ_DESCRIPTION","detailOf","explainedOptionsOf","explainedOptionOf","detail","explained","summarize","steps","reasons","database","memory","counts","causes","toExecutionSteps","explainQuery","context","executionSteps","withExecutedQueries","explanation","executedQueries","attached","OPTION_LABEL_WIDTH","WRAP_WIDTH","wrap","text","indent","lines","line","word","COMPARATOR_SYMBOLS","describeValue","describeExpression","symbol","describeOption","fields","formatStep","executed","formatExplanation","collection","summary","stepCount","QueryOrdering","SENDABLE","splitSendableOptions","sendable","local","stopped","keyPath","serializeQueryOptions","serialized","join","deserializeQueryOptions","resolveSchema","scopeFor","scope","propertyOf","serializeBulkPersist","changes","schemas","schemaChanges","update","deserializeBulkPersist","request","serializePersistResult","schemaResult","deserializePersistResult","collectionsIn","change","names","walk","createRequestHandler","plugin","authorize","allowDestroy","byName","failed","scopeExpressionFor","action","declared","verdict","queryOptions","Promise","permitted","ConcurrencyDbPlugin","augmentedEvent","schemaIds","versions","add","entity","expected","deltaCarriesColumns","removed","conflicted","record","version","augment","Proxy","receiver","Reflect","synthetic","view","getKeyEqualityValue","EphemeralDataPlugin","databaseName","bulkPersistResult","staged","pipeline","readResult","concurrency","undo","revert","adds","updates","removes","prior","applyError","saveNext","saveResult","resaveNext","k","innerCollection","cloneRecord","keyColumn","narrowing","hasRenamedProperties","operation","orderedOptions","o","leadingFilterCount","leadingFilters","filterCount","cloned","kept","joinResult","translator","DEFAULT_ATTEMPTS","defaultDelay","attempt","RetryDbPlugin","isLastAttempt","delay","setTimeout","CacheDbPlugin","parts","structuredClone","snapshot","oldest","prefix","touched","DEFAULT_MAX_BATCH_SIZE","BatchingDbPlugin","forward","batch","settled","groups","claimed","overlaps","advance","merged","isPartial","mine","run"],"mappings":"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"}
1
+ {"version":3,"file":"plugins/index.cjs","sources":["webpack://@routier/core/./src/assertions/index.ts","webpack://@routier/core/./src/collections/Changes.ts","webpack://@routier/core/./src/collections/ReadonlySchemaCollection.ts","webpack://@routier/core/./src/collections/SchemaCollection.ts","webpack://@routier/core/./src/collections/TagCollection.ts","webpack://@routier/core/./src/errors/OptimisticConcurrencyError.ts","webpack://@routier/core/./src/errors/PluginDestroyedError.ts","webpack://@routier/core/./src/expressions/evaluate.ts","webpack://@routier/core/./src/expressions/parser.ts","webpack://@routier/core/./src/expressions/types.ts","webpack://@routier/core/./src/expressions/utils.ts","webpack://@routier/core/./src/pipeline/TrampolinePipeline.ts","webpack://@routier/core/./src/plugins/query/QueryOptionsCollection.ts","webpack://@routier/core/./src/results/Result.ts","webpack://@routier/core/./src/schema/types.ts","webpack://@routier/core/./src/utilities/dates.ts","webpack://@routier/core/./src/utilities/logger.ts","webpack://@routier/core/./src/utilities/uuid.ts","webpack://@routier/core/webpack/runtime/define_property_getters","webpack://@routier/core/webpack/runtime/has_own_property","webpack://@routier/core/webpack/runtime/make_namespace_object","webpack://@routier/core/./src/plugins/resultShape.ts","webpack://@routier/core/./src/plugins/translators/TranslatedArrayValue.ts","webpack://@routier/core/./src/plugins/translators/TranslatedGroupValue.ts","webpack://@routier/core/./src/plugins/translators/TranslatedSingleValue.ts","webpack://@routier/core/./src/plugins/translators/DataTranslator.ts","webpack://@routier/core/./src/plugins/query/similarity.ts","webpack://@routier/core/./src/plugins/query/Query.ts","webpack://@routier/core/./src/plugins/query/join.ts","webpack://@routier/core/./src/plugins/translators/JsonTranslator.ts","webpack://@routier/core/./src/plugins/translators/SqlTranslator.ts","webpack://@routier/core/./src/plugins/translators/TupleTranslator.ts","webpack://@routier/core/./src/plugins/translators/index.ts","webpack://@routier/core/./src/plugins/query/explain.ts","webpack://@routier/core/./src/plugins/query/formatExplanation.ts","webpack://@routier/core/./src/plugins/query/types.ts","webpack://@routier/core/./src/plugins/query/index.ts","webpack://@routier/core/./src/plugins/wire/query.ts","webpack://@routier/core/./src/plugins/wire/persist.ts","webpack://@routier/core/./src/plugins/wire/handler.ts","webpack://@routier/core/./src/plugins/wire/index.ts","webpack://@routier/core/./src/plugins/ConcurrencyDbPlugin.ts","webpack://@routier/core/./src/plugins/EphemeralDataPlugin.ts","webpack://@routier/core/./src/plugins/RetryDbPlugin.ts","webpack://@routier/core/./src/plugins/TelemetryDbPlugin.ts","webpack://@routier/core/./src/plugins/CacheDbPlugin.ts","webpack://@routier/core/./src/plugins/BatchingDbPlugin.ts","webpack://@routier/core/./src/plugins/index.ts"],"sourcesContent":["import { EXPRESSION_TYPES } from \"../expressions/constants\";\nimport { ComparatorExpression, EmptyExpression, Expression, ExpressionType, NotParsableExpression, OperatorExpression, PropertyExpression, ValueExpression } from \"../expressions/types\";\nimport { isDate } from \"../utilities\";\n\nexport function assertDate(data: unknown): asserts data is Date {\n if (isDate(data) === false) {\n throw new TypeError('Value is not a Date');\n }\n}\n\nexport function assertIsNotNull<T>(data: T | null | undefined, message?: string | (() => string)): asserts data is NonNullable<T> {\n if (data == null) {\n if (message == null) {\n throw new TypeError('Assertion failed, data is null');\n }\n\n if (typeof message === \"string\") {\n throw new TypeError(message);\n }\n\n throw new TypeError(message());\n }\n}\n\nexport function assertIsArray<T>(data: unknown, message?: string): asserts data is T[] {\n if (!Array.isArray(data)) {\n throw new TypeError(message ?? 'Assertion failed, data is not of type Array');\n }\n}\n\nexport function assertString(data: unknown, message?: string): asserts data is string {\n if (typeof data !== \"string\") {\n throw new TypeError(message ?? 'Assertion failed, data is not of type String');\n }\n}\n\nexport function assertInstanceOf<T extends new (...args: any[]) => any>(value: unknown, Instance: T): asserts value is T {\n if (value instanceof Instance) {\n return;\n }\n\n if (value != null && typeof value === \"object\" && \"constructor\" in value) {\n throw new TypeError(`value is not instance of type. Type: ${value.constructor.name}`);\n }\n\n throw new TypeError(`value is not instance of type`);\n}\n\nexport function assertIsNumber(value: unknown): asserts value is number {\n if (typeof value !== \"number\") {\n throw new TypeError(\"value is not of type `number`\");\n }\n}\n\n\nfunction isObjectWithType(value: unknown): value is Record<\"type\", unknown> {\n return typeof value === \"object\" && value !== null && \"type\" in value;\n}\n\n/**\n * Type guard: narrows `value` to `Expression` when it is an object with a valid `type` property.\n */\nexport function isExpression(value: unknown): value is Expression {\n return isObjectWithType(value) && EXPRESSION_TYPES.includes(value.type as ExpressionType);\n}\n\n/**\n * Type guard: narrows `value` to `OperatorExpression` when it is an object with `type === \"operator\"`.\n */\nexport function isOperatorExpression(value: unknown): value is OperatorExpression {\n return isObjectWithType(value) && value.type === \"operator\";\n}\n\n/**\n * Type guard: narrows `value` to `ComparatorExpression` when it is an object with `type === \"comparator\"`.\n */\nexport function isComparatorExpression(value: unknown): value is ComparatorExpression {\n return isObjectWithType(value) && value.type === \"comparator\";\n}\n\n/**\n * Type guard: narrows `value` to `PropertyExpression` when it is an object with `type === \"property\"`.\n */\nexport function isPropertyExpression(value: unknown): value is PropertyExpression {\n return isObjectWithType(value) && value.type === \"property\";\n}\n\n/**\n * Type guard: narrows `value` to `ValueExpression` when it is an object with `type === \"value\"`.\n */\nexport function isValueExpression(value: unknown): value is ValueExpression {\n return isObjectWithType(value) && value.type === \"value\";\n}\n\n/**\n * Type guard: narrows `value` to `EmptyExpression` when it is an object with `type === \"empty\"`.\n */\nexport function isEmptyExpression(value: unknown): value is EmptyExpression {\n return isObjectWithType(value) && value.type === \"empty\";\n}\n\n/**\n * Type guard: narrows `value` to `NotParsableExpression` when it is an object with `type === \"not-parsable\"`.\n */\nexport function isNotParsableExpression(value: unknown): value is NotParsableExpression {\n return isObjectWithType(value) && value.type === \"not-parsable\";\n}","import { EntityUpdateInfo } from \"../plugins/types\";\nimport { InferCreateType, InferType, SchemaId } from \"../schema\";\nimport { TagCollection } from \"./TagCollection\";\nexport class BulkPersistResult extends Map<SchemaId, SchemaPersistResult> {\n\n resolve<T extends {} = Record<string, unknown>>(schemaId: SchemaId): SchemaPersistResult<T> {\n if (this.has(schemaId)) {\n return this.get(schemaId);\n }\n\n this.set(schemaId, new SchemaPersistResult<T>());\n\n return this.get(schemaId);\n }\n\n override get<T extends {} = Record<string, unknown>>(schemaId: SchemaId) {\n return super.get(schemaId) as SchemaPersistResult<T>\n }\n\n get aggregate() {\n return {\n size: this.aggregateSize,\n adds: this.aggregateAddsSize,\n updates: this.aggregateUpdatesSize,\n removes: this.aggregateRemovesSize\n }\n }\n\n private get aggregateSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.total;\n }\n\n return count;\n }\n\n private get aggregateAddsSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.adds.length;\n }\n\n return count;\n }\n\n private get aggregateUpdatesSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.updates.length;\n }\n\n return count;\n }\n\n private get aggregateRemovesSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.removes.length;\n }\n\n return count;\n }\n}\n\nexport class BulkPersistChanges extends Map<SchemaId, SchemaPersistChanges> {\n\n resolve<T extends {} = Record<string, unknown>>(schemaId: SchemaId): SchemaPersistChanges<T> {\n if (this.has(schemaId)) {\n return this.get(schemaId);\n }\n\n this.set(schemaId, new SchemaPersistChanges<T>());\n\n return this.get(schemaId);\n }\n\n override get<T extends {} = Record<string, unknown>>(schemaId: SchemaId) {\n return super.get(schemaId) as SchemaPersistChanges<T>\n }\n\n get aggregate() {\n return {\n size: this.aggregateSize,\n adds: this.aggregateAddsSize,\n updates: this.aggregateUpdatesSize,\n removes: this.aggregateRemovesSize\n }\n }\n\n private get aggregateSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.total;\n }\n\n return count;\n }\n\n private get aggregateAddsSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.adds.length;\n }\n\n return count;\n }\n\n private get aggregateUpdatesSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.updates.length;\n }\n\n return count;\n }\n\n private get aggregateRemovesSize() {\n let count = 0;\n\n for (const [, result] of this) {\n count += result.removes.length;\n }\n\n return count;\n }\n\n /**\n * Ensures the result has the same result sets as the change sets\n * @returns \n */\n toResult() {\n const result = new BulkPersistResult();\n\n for (const [schemaId] of this) {\n result.set(schemaId, new SchemaPersistResult());\n }\n\n return result;\n }\n}\n\nexport class SchemaPersistChanges<T extends {} = Record<string, unknown>> {\n adds: InferCreateType<T>[] = [];\n updates: EntityUpdateInfo<T>[] = [];\n removes: InferType<T>[] = [];\n tags: TagCollection = new TagCollection();\n\n get hasItems() {\n return this.total > 0;\n }\n\n get total() {\n return this.adds.length + this.updates.length + this.removes.length;\n }\n}\n\nexport class SchemaPersistResult<T extends {} = Record<string, unknown>> {\n adds: InferType<T>[] = [];\n updates: InferType<T>[] = [];\n removes: InferType<T>[] = [];\n\n get hasItems() {\n return this.total > 0;\n }\n\n get total() {\n return this.adds.length + this.updates.length + this.removes.length;\n }\n}","import { CompiledSchema, SchemaId } from \"../schema\";\n\n/**\n * Collection of schemas with generic typing for type-safe schema retrieval\n */\nexport class ReadonlySchemaCollection {\n\n protected data: Map<SchemaId, CompiledSchema<Record<string, unknown>>>;\n\n constructor(data?: [SchemaId, CompiledSchema<Record<string, unknown>>][]) {\n this.data = new Map<SchemaId, CompiledSchema<Record<string, unknown>>>(data);\n }\n\n get<T>(schemaId: SchemaId): CompiledSchema<T> | undefined {\n return this.data.get(schemaId) as CompiledSchema<T> | undefined;\n }\n\n has(schemaId: SchemaId): boolean {\n return this.data.has(schemaId);\n }\n\n get size(): number {\n return this.data.size;\n }\n\n keys(): IterableIterator<SchemaId> {\n return this.data.keys();\n }\n\n values(): IterableIterator<CompiledSchema<Record<string, unknown>>> {\n return this.data.values();\n }\n\n entries(): IterableIterator<[SchemaId, CompiledSchema<Record<string, unknown>>]> {\n return this.data.entries();\n }\n\n forEach(callbackfn: (value: CompiledSchema<Record<string, unknown>>, key: SchemaId, map: Map<SchemaId, CompiledSchema<Record<string, unknown>>>) => void, thisArg?: any): void {\n this.data.forEach(callbackfn, thisArg);\n }\n\n [Symbol.iterator](): IterableIterator<[SchemaId, CompiledSchema<Record<string, unknown>>]> {\n return this.data[Symbol.iterator]();\n }\n\n getByName<T>(collectionName: string): CompiledSchema<T> | undefined {\n const found = [...this.data].find(x => x[1].collectionName === collectionName);\n\n if (found != null) {\n return found[1] as CompiledSchema<T>;\n }\n\n return undefined;\n }\n}","import { CompiledSchema, SchemaId } from \"../schema\";\nimport { ReadonlySchemaCollection } from \"./ReadonlySchemaCollection\";\n\n/**\n * Collection of schemas with generic typing for type-safe schema retrieval\n */\nexport class SchemaCollection extends ReadonlySchemaCollection {\n\n set<T>(schemaId: SchemaId, schema: CompiledSchema<T>): this {\n this.data.set(schemaId, schema as CompiledSchema<Record<string, unknown>>);\n return this;\n }\n\n delete(schemaId: SchemaId): boolean {\n return this.data.delete(schemaId);\n }\n\n clear(): void {\n this.data.clear();\n }\n}","export class TagCollection implements Disposable {\n\n private data: Map<object, unknown> = new Map<object, unknown>();\n\n // Delegated to the map rather than tracked in a counter field: every mutation path\n // (set, setMany, combine, delete, dispose) would otherwise have to maintain it, and\n // a missed path silently reports a size that disagrees with the contents.\n get size() {\n return this.data.size;\n }\n\n get(key: object) {\n return this.data.get(key);\n }\n\n has(key: object) {\n return this.data.has(key);\n }\n\n set(key: object, tag: unknown) {\n return this.data.set(key, tag);\n }\n\n delete(key: object) {\n return this.data.delete(key);\n }\n\n setMany(keys: object[], tag: unknown) {\n for (let i = 0, length = keys.length; i < length; i++) {\n const key = keys[i];\n this.set(key, tag);\n }\n }\n\n combine(tags: TagCollection) {\n for (const [key, value] of tags) {\n this.set(key, value);\n }\n }\n\n values() {\n return this.data.values();\n }\n\n keys() {\n return this.data.keys();\n }\n\n [Symbol.dispose]() {\n this.data.clear();\n }\n\n [Symbol.iterator]() {\n return this.data[Symbol.iterator]();\n }\n}","import { IdType } from \"../schema\";\n\n/**\n * A save was rejected because another writer changed one of its rows first.\n *\n * Raised when a schema declares a `.concurrency()` token and an update's expected token\n * no longer matches the stored row. The whole save is rolled back — nothing was applied.\n * The caller's recovery is always the same: re-read the conflicted rows (the re-read\n * merges fresh values into the canonical instances), reapply the intent, and save again.\n */\nexport class OptimisticConcurrencyError extends Error {\n\n /** The collection whose rows conflicted. */\n readonly collectionName: string;\n /** Ids of the rows whose stored token no longer matched the writer's read. */\n readonly conflicts: IdType[];\n\n constructor(collectionName: string, conflicts: IdType[]) {\n super(\n `Optimistic concurrency conflict on '${collectionName}': ${conflicts.length} row(s) were changed by another writer after they were read. ` +\n `Nothing was saved. Re-read the rows, reapply the changes, and save again. Conflicted ids: ${conflicts.map(String).join(\", \")}`\n );\n this.name = \"OptimisticConcurrencyError\";\n this.collectionName = collectionName;\n this.conflicts = conflicts;\n }\n\n /** Type guard that survives errors crossing realm/serialization boundaries. */\n static is(error: unknown): error is OptimisticConcurrencyError {\n return error instanceof OptimisticConcurrencyError\n || (error != null && typeof error === \"object\" && (error as Error).name === \"OptimisticConcurrencyError\");\n }\n}\n","/**\n * A write that was accepted but never reached the database, because the plugin holding it was\n * destroyed first — or one submitted after the destroy.\n *\n * Distinct from a backend failure on purpose: nothing was attempted, so a caller that retries\n * on transient errors must not retry this one. There is no database left to retry against.\n */\nexport class PluginDestroyedError extends Error {\n\n constructor(reason: string) {\n super(`The plugin was destroyed: ${reason}`);\n this.name = \"PluginDestroyedError\";\n }\n}\n","import { isComparatorExpression, isOperatorExpression, isPropertyExpression, isValueExpression } from \"../assertions\";\nimport { UnknownRecord } from \"../utilities\";\nimport { Comparator, Expression, Transformer } from \"./types\";\n\n/**\n * Runs a parsed expression against a row.\n *\n * The counterpart to `toSql` and `toMql`: those turn a tree into a backend's language, and this\n * turns it into an answer. Needed wherever a tree exists but the closure that produced it does\n * not — a filter split out of a larger predicate, an option rebuilt from a serialized query.\n *\n * ## It fails OPEN, and that is the whole safety argument\n *\n * `undefined` means \"this tree cannot be evaluated here\" — an unknown node, a transformer with no\n * implementation, a comparison between shapes that do not compare. Callers must read that as KEEP\n * THE ROW, never as exclude it.\n *\n * The reason is asymmetric cost. Every caller today uses this to NARROW something that a\n * subsequent, authoritative predicate will check again: a semi-join prefilter, a split conjunct.\n * Keeping a row this cannot judge costs one wasted comparison downstream. Dropping one loses data\n * from a query result and nothing anywhere reports it. So every uncertain path returns `undefined`,\n * and no path guesses `false`.\n *\n * ## Why not just reuse the caller's closure\n *\n * Because there often isn't one. A conjunct pulled out of `([p, m]) => p.a === 1 && m.b === 2` is\n * source TEXT; turning it back into a callable needs `new Function`, which a\n * Content-Security-Policy blocks — the same constraint that makes `softDeleteScope` build its tree\n * by hand. The tree is the only representation that survives.\n */\nexport type EvaluationResult = boolean | undefined;\n\n/** Reads a property or literal operand, or `UNRESOLVED` when the node is not one. */\nconst UNRESOLVED = Symbol(\"unresolved\");\n\nconst applyTransformer = (value: unknown, transformer: Transformer | null): unknown | typeof UNRESOLVED => {\n if (transformer == null) {\n return value;\n }\n\n // A transformer applied to an absent value has no answer, and inventing one (\"\" for a missing\n // string) is how a filter starts matching rows it should not.\n if (value == null) {\n return UNRESOLVED;\n }\n\n if (transformer === \"to-lower-case\") {\n return typeof value === \"string\" ? value.toLowerCase() : UNRESOLVED;\n }\n\n if (transformer === \"to-upper-case\") {\n return typeof value === \"string\" ? value.toUpperCase() : UNRESOLVED;\n }\n\n if (transformer === \"length\") {\n return typeof value === \"string\" || Array.isArray(value) ? value.length : UNRESOLVED;\n }\n\n return UNRESOLVED;\n};\n\nconst operand = (expression: Expression | undefined, row: UnknownRecord): unknown | typeof UNRESOLVED => {\n if (expression == null) {\n return UNRESOLVED;\n }\n\n if (isValueExpression(expression)) {\n return applyTransformer(expression.value, expression.transformer);\n }\n\n if (isPropertyExpression(expression)) {\n // Through the PropertyInfo, so a nested path and a `from`-renamed segment resolve the same\n // way every other consumer of the tree resolves them.\n return applyTransformer(expression.property.getValue(row), expression.transformer);\n }\n\n return UNRESOLVED;\n};\n\n/**\n * `a === b` for the comparators, with Dates compared by VALUE.\n *\n * A Date compares by reference under `===`, so two Dates holding the same instant would be\n * unequal — which is not what a filter on a date means, and not what any backend does.\n */\nconst equals = (left: unknown, right: unknown, strict: boolean): boolean => {\n if (left instanceof Date && right instanceof Date) {\n return left.getTime() === right.getTime();\n }\n\n // oxlint-disable-next-line eqeqeq\n return strict ? left === right : left == right;\n};\n\n/** Ordered comparison, only for shapes that have an order. */\nconst compare = (left: unknown, right: unknown, comparator: Comparator): EvaluationResult => {\n const asComparable = (value: unknown) => value instanceof Date ? value.getTime() : value;\n\n const a = asComparable(left);\n const b = asComparable(right);\n\n const comparable = (typeof a === \"number\" && typeof b === \"number\")\n || (typeof a === \"string\" && typeof b === \"string\");\n\n if (comparable === false) {\n return undefined;\n }\n\n if (comparator === \"greater-than\") {\n return a > b;\n }\n\n if (comparator === \"greater-than-equals\") {\n return a >= b;\n }\n\n if (comparator === \"less-than\") {\n return a < b;\n }\n\n return a <= b;\n};\n\nconst evaluateComparator = (comparator: Comparator, left: unknown, right: unknown, strict: boolean): EvaluationResult => {\n\n if (comparator === \"equals\") {\n return equals(left, right, strict);\n }\n\n if (comparator === \"includes\") {\n // Two shapes, and the tree does not distinguish them: `array.includes(value)` and\n // `string.includes(substring)`. Whichever side is the container decides.\n if (Array.isArray(left)) {\n return left.some(item => equals(item, right, strict));\n }\n\n if (Array.isArray(right)) {\n return right.some(item => equals(item, left, strict));\n }\n\n return typeof left === \"string\" && typeof right === \"string\" ? left.includes(right) : undefined;\n }\n\n if (comparator === \"starts-with\") {\n return typeof left === \"string\" && typeof right === \"string\" ? left.startsWith(right) : undefined;\n }\n\n if (comparator === \"ends-with\") {\n return typeof left === \"string\" && typeof right === \"string\" ? left.endsWith(right) : undefined;\n }\n\n return compare(left, right, comparator);\n};\n\n/**\n * Evaluates `expression` against `row`, or returns `undefined` when it cannot.\n *\n * See the note at the top of this file: `undefined` means KEEP the row.\n */\nexport const evaluate = (expression: Expression, row: UnknownRecord): EvaluationResult => {\n\n if (isOperatorExpression(expression)) {\n const left = expression.left == null ? undefined : evaluate(expression.left, row);\n const right = expression.right == null ? undefined : evaluate(expression.right, row);\n\n /**\n * One unevaluable side does not have to sink the whole tree.\n *\n * `a && b` where `a` is definitely false is false whatever `b` is, and `a || b` where `a`\n * is definitely true is true. That short-circuiting is what lets a mostly-understood\n * predicate still narrow anything at all — without it, one unfamiliar sub-expression makes\n * the entire filter a no-op.\n */\n if (expression.operator === \"&&\") {\n if (left === false || right === false) {\n return false;\n }\n\n return left === true && right === true ? true : undefined;\n }\n\n if (left === true || right === true) {\n return true;\n }\n\n return left === false && right === false ? false : undefined;\n }\n\n if (isComparatorExpression(expression)) {\n const left = operand(expression.left, row);\n const right = operand(expression.right, row);\n\n if (left === UNRESOLVED || right === UNRESOLVED) {\n return undefined;\n }\n\n const result = evaluateComparator(expression.comparator, left, right, expression.strict);\n\n if (result === undefined) {\n return undefined;\n }\n\n return expression.negated ? result === false : result;\n }\n\n // A tautology excludes nothing, which is exactly `true`. Anything else — a bare property, a\n // literal, `not-parsable` — is not a predicate this can judge.\n return expression.type === \"empty\" ? true : undefined;\n};\n\n/**\n * `evaluate`, as a predicate that keeps whatever it cannot judge.\n *\n * The form every narrowing caller wants, with the fail-open rule applied once here rather than\n * remembered at each call site.\n */\nexport const toPredicate = (expression: Expression) => (row: UnknownRecord): boolean =>\n evaluate(expression, row) !== false;\n\n/**\n * `evaluate`, as a predicate that THROWS on anything it cannot judge.\n *\n * The opposite default to `toPredicate`, and the right one when the predicate is the only thing\n * standing between a caller and rows they asked to exclude — a filter that arrived over a wire and\n * is being applied by the receiver. Failing open there does not cost a wasted comparison; it returns\n * data the requester filtered out, and reports nothing.\n *\n * Use `toPredicate` when something authoritative re-checks the result, and this when nothing does.\n */\nexport const toStrictPredicate = (expression: Expression) => (row: UnknownRecord): boolean => {\n const result = evaluate(expression, row);\n\n if (result === undefined) {\n throw new Error(\n \"Cannot apply this filter: its expression cannot be evaluated in memory, and applying it partially would \" +\n \"return rows the filter excludes. This happens when a filter arrives without a runnable predicate — over a \" +\n \"wire, or rebuilt from a serialized query — and names something the evaluator does not understand.\"\n );\n }\n\n return result;\n};\n","import { logger } from \"../utilities\";\nimport { assertString } from \"../assertions\";\nimport { CompiledSchema, PropertyInfo, SchemaTypes } from \"../schema\";\nimport { Expression, OperatorExpression, ComparatorExpression, ValueExpression, PropertyExpression, Filter, ParamsFilter, Comparator, Transformer } from \"./types\";\n\n// Error message constants\nconst ERROR_MESSAGES = {\n PROPERTY_NOT_FOUND: (path: string) => `Error parsing query, could not find PropertyInfo for path: ${path}`,\n PARAM_PATH_NOT_FOUND: (value: string, params: unknown) => `Cannot find path in params for .where(). Make sure parameters are not used inline.\\r\\nPath: ${value}, Params: ${JSON.stringify(params)}`,\n VARIABLE_VALUE: (value: string) => `Cannot derive value from variable, please pass parameters into the expression.\n\nExample: .where(([x, params]) => x.id === params.id, { id: someVar.id })\nIssue At: ${value}`,\n UNSUPPORTED: (value: string) => `Unsupported expression format: ${value}`\n};\n\nconst parseUnknown = (value: unknown) => {\n assertString(value);\n return JSON.parse(value);\n}\n\n/**\n * A parse failure caused by the params VALUES rather than the filter source.\n * These must never poison the template cache — the same source can succeed\n * with different params.\n */\nclass ParamDependentParseError extends Error { }\n\nconst converters: Record<SchemaTypes, (value: unknown) => unknown> = {\n Array: v => v,\n Boolean: v => v == null ? v : Boolean(v),\n // Stryker disable next-line ArrowFunction: filters on computed properties route to\n // in-memory execution, so this entry cannot be reached through a parsable filter.\n Computed: v => v,\n Date: v => v,\n // A file is a reference, and a filter can legitimately compare its fields — content type\n // and size are ordinary columns. The value passes through unconverted like an object.\n File: v => v,\n // Stryker disable next-line ArrowFunction: SchemaTypes.Definition is handled as a\n // generic primitive everywhere (specs/known-defects.md) and never pairs in a filter.\n Definition: v => v,\n // Stryker disable next-line ArrowFunction: filters on function properties route to\n // in-memory execution, so this entry cannot be reached through a parsable filter.\n Function: v => v,\n Number: v => v == null ? v : Number(v),\n Object: v => v,\n String: v => v == null ? v : String(v),\n // A vector is a list of numbers and passes through like any other array. Nothing\n // converts it because nothing compares it: similarity is `.nearest()`, not a filter.\n Vector: v => v\n};\n\n// #region Tokenizer\n\ntype TokenKind = \"identifier\" | \"string\" | \"number\" | \"punctuation\";\n\ntype Token = {\n kind: TokenKind;\n value: string;\n}\n\n// Longest first so multi-character punctuation wins over its prefixes\nconst MULTI_CHARACTER_PUNCTUATION = [\"===\", \"!==\", \"?.\", \"&&\", \"||\", \"==\", \"!=\", \">=\", \"<=\", \"=>\"] as const;\n// Stryker disable next-line all: documented equivalent cluster (see\n// docs/mutation-backlog.md) — dropping an entry only affects source the parser rejects\n// either way, and the rejection message names the character from the source rather than\n// from this set, so no observable boundary distinguishes the mutant. Established\n// experimentally: 30 message-asserting tests killed 1 of 12.\nconst SINGLE_CHARACTER_PUNCTUATION = new Set([\"(\", \")\", \"[\", \"]\", \"{\", \"}\", \".\", \",\", \";\", \"!\", \">\", \"<\", \"-\", \"+\", \"*\", \"/\", \"%\", \"=\", \"?\", \":\", \"&\", \"|\"]);\n\nconst STRING_ESCAPES: Record<string, string> = {\n \"n\": \"\\n\",\n \"r\": \"\\r\",\n \"t\": \"\\t\",\n \"b\": \"\\b\",\n \"f\": \"\\f\",\n \"v\": \"\\v\",\n \"0\": \"\\0\"\n};\n\nconst isIdentifierStart = (char: string) => /[a-zA-Z_$]/.test(char);\nconst isIdentifierPart = (char: string) => /[a-zA-Z0-9_$]/.test(char);\nconst isDigit = (char: string) => char >= \"0\" && char <= \"9\";\nconst isHexDigit = (char: string) => isDigit(char) || (char >= \"a\" && char <= \"f\") || (char >= \"A\" && char <= \"F\");\n\n/**\n * Decodes a `\\uXXXX`, `\\u{...}` or `\\xXX` escape starting at the backslash.\n * Returns the decoded character and the index just past the escape. These\n * escapes carry a computed character, so mapping them through STRING_ESCAPES\n * (which would yield the literal \"u\"/\"x\") silently corrupts the value.\n */\nconst decodeCodeEscape = (source: string, backslashIndex: number): { value: string, nextIndex: number } => {\n const kind = source[backslashIndex + 1];\n let start = backslashIndex + 2;\n\n if (kind === \"u\" && source[start] === \"{\") {\n const end = source.indexOf(\"}\", start + 1);\n\n if (end === -1) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"unterminated unicode escape\"));\n }\n\n return { value: String.fromCodePoint(parseInt(source.slice(start + 1, end), 16)), nextIndex: end + 1 };\n }\n\n const length = kind === \"u\" ? 4 : 2;\n const digits = source.slice(start, start + length);\n\n if (digits.length < length || [...digits].some(d => !isHexDigit(d))) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`'\\\\${kind}' escape`));\n }\n\n return { value: String.fromCharCode(parseInt(digits, 16)), nextIndex: start + length };\n}\n\n/**\n * Converts filter source text into a flat token stream. Strings and comments are\n * consumed here so operator characters inside literals can never be mistaken for\n * real operators.\n */\nconst tokenize = (source: string): Token[] => {\n\n const tokens: Token[] = [];\n let i = 0;\n\n while (i < source.length) {\n const char = source[i];\n\n // Whitespace\n if (char === \" \" || char === \"\\t\" || char === \"\\r\" || char === \"\\n\") {\n i++;\n continue;\n }\n\n // Comments\n if (char === \"/\" && source[i + 1] === \"/\") {\n while (i < source.length && source[i] !== \"\\n\") {\n i++;\n }\n continue;\n }\n\n if (char === \"/\" && source[i + 1] === \"*\") {\n i += 2;\n while (i < source.length && !(source[i] === \"*\" && source[i + 1] === \"/\")) {\n i++;\n }\n i += 2;\n continue;\n }\n\n // String literals\n if (char === \"'\" || char === \"\\\"\" || char === \"`\") {\n const quote = char;\n let value = \"\";\n i++;\n\n while (i < source.length && source[i] !== quote) {\n if (source[i] === \"\\\\\") {\n const escaped = source[i + 1];\n\n if (escaped === \"u\" || escaped === \"x\") {\n const decoded = decodeCodeEscape(source, i);\n value += decoded.value;\n i = decoded.nextIndex;\n continue;\n }\n\n value += STRING_ESCAPES[escaped] ?? escaped;\n i += 2;\n continue;\n }\n\n if (quote === \"`\" && source[i] === \"$\" && source[i + 1] === \"{\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"template literal interpolation\"));\n }\n\n value += source[i];\n i++;\n }\n\n if (i >= source.length) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"unterminated string literal\"));\n }\n\n i++; // consume closing quote\n tokens.push({ kind: \"string\", value });\n continue;\n }\n\n // Numbers — covers decimals, exponents (1e6), hex/octal/binary (0xFF),\n // and numeric separators (1_000_000). Values are normalized here (the\n // separator stripped) so the parser can hand them straight to Number()\n if (isDigit(char)) {\n let value = \"\";\n\n const nextChar = source[i + 1];\n const radixPrefix = char === \"0\" && nextChar != null && \"xXoObB\".includes(nextChar);\n\n if (radixPrefix) {\n value = source[i] + source[i + 1];\n i += 2;\n\n while (i < source.length && (isHexDigit(source[i]) || source[i] === \"_\")) {\n value += source[i];\n i++;\n }\n } else {\n while (i < source.length && (isDigit(source[i]) || source[i] === \".\" || source[i] === \"_\")) {\n value += source[i];\n i++;\n }\n\n // Exponent part: e/E, optional sign, then digits. Only consumed when\n // digits follow, so a stray identifier after a number still errors\n if ((source[i] === \"e\" || source[i] === \"E\")) {\n const signLength = source[i + 1] === \"+\" || source[i + 1] === \"-\" ? 1 : 0;\n\n if (isDigit(source[i + 1 + signLength])) {\n value += source[i];\n i++;\n\n if (signLength === 1) {\n value += source[i];\n i++;\n }\n\n while (i < source.length && isDigit(source[i])) {\n value += source[i];\n i++;\n }\n }\n }\n }\n\n tokens.push({ kind: \"number\", value: value.replace(/_/g, \"\") });\n continue;\n }\n\n // Identifiers / keywords\n if (isIdentifierStart(char)) {\n let value = \"\";\n\n while (i < source.length && isIdentifierPart(source[i])) {\n value += source[i];\n i++;\n }\n\n tokens.push({ kind: \"identifier\", value });\n continue;\n }\n\n // Multi-character punctuation (longest match first)\n const multi = MULTI_CHARACTER_PUNCTUATION.find(w => source.startsWith(w, i));\n\n if (multi != null) {\n tokens.push({ kind: \"punctuation\", value: multi });\n i += multi.length;\n continue;\n }\n\n if (SINGLE_CHARACTER_PUNCTUATION.has(char)) {\n tokens.push({ kind: \"punctuation\", value: char });\n i++;\n continue;\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`unexpected character '${char}'`));\n }\n\n return tokens;\n}\n\n/**\n * Cursor over the token stream with the small set of lookahead operations the\n * parser needs.\n */\nclass TokenStream {\n\n private readonly tokens: Token[];\n private index: number = 0;\n\n constructor(tokens: Token[]) {\n this.tokens = tokens;\n }\n\n get isAtEnd() {\n return this.index >= this.tokens.length;\n }\n\n peek(offset: number = 0): Token | null {\n return this.tokens[this.index + offset] ?? null;\n }\n\n next(): Token {\n const token = this.tokens[this.index];\n\n if (token == null) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"unexpected end of expression\"));\n }\n\n this.index++;\n return token;\n }\n\n isPunctuation(value: string, offset: number = 0): boolean {\n const token = this.peek(offset);\n return token != null && token.kind === \"punctuation\" && token.value === value;\n }\n\n matchPunctuation(value: string): boolean {\n if (this.isPunctuation(value)) {\n this.index++;\n return true;\n }\n\n return false;\n }\n\n expectPunctuation(value: string) {\n if (!this.matchPunctuation(value)) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`expected '${value}'`));\n }\n }\n}\n\n// #endregion\n\n// #region Operands\n\n// Discriminated union so a condition builder can only ever see the operand\n// shapes the grammar allows\ntype PropertyOperand = {\n kind: \"property\";\n property: PropertyInfo<any>;\n transformer: Transformer | null;\n locale: string | null;\n}\n\ntype ValueOperand = {\n kind: \"value\";\n value: unknown;\n transformer: Transformer | null;\n locale: string | null;\n}\n\ntype ParamOperand = {\n kind: \"param\";\n path: string[];\n transformer: Transformer | null;\n locale: string | null;\n}\n\ntype MethodCallOperand = {\n kind: \"method-call\";\n target: PropertyOperand | ParamOperand | ValueOperand;\n method: \"startsWith\" | \"endsWith\" | \"includes\";\n argument: PropertyOperand | ValueOperand | ParamOperand;\n}\n\ntype Operand = PropertyOperand | ValueOperand | ParamOperand | MethodCallOperand;\n\nconst COMPARATOR_METHODS: Record<string, Comparator> = {\n startsWith: \"starts-with\",\n endsWith: \"ends-with\",\n includes: \"includes\"\n};\n\nconst TRANSFORM_METHODS: Record<string, { transformer: Transformer, locale: string | null }> = {\n toLowerCase: { transformer: \"to-lower-case\", locale: null },\n toUpperCase: { transformer: \"to-upper-case\", locale: null },\n toLocaleLowerCase: { transformer: \"to-lower-case\", locale: \"en-US\" },\n toLocaleUpperCase: { transformer: \"to-upper-case\", locale: \"en-US\" }\n};\n\nconst COMPARISON_OPERATORS: Record<string, { comparator: Comparator, negated: boolean, strict: boolean }> = {\n \"==\": { comparator: \"equals\", negated: false, strict: false },\n \"===\": { comparator: \"equals\", negated: false, strict: true },\n \"!=\": { comparator: \"equals\", negated: true, strict: false },\n \"!==\": { comparator: \"equals\", negated: true, strict: true },\n \">\": { comparator: \"greater-than\", negated: false, strict: false },\n \">=\": { comparator: \"greater-than-equals\", negated: false, strict: false },\n \"<\": { comparator: \"less-than\", negated: false, strict: false },\n \"<=\": { comparator: \"less-than-equals\", negated: false, strict: false }\n};\n\nconst SWAPPED_COMPARATORS: Record<Comparator, Comparator> = {\n \"equals\": \"equals\",\n \"greater-than\": \"less-than\",\n \"greater-than-equals\": \"less-than-equals\",\n \"less-than\": \"greater-than\",\n \"less-than-equals\": \"greater-than-equals\",\n \"starts-with\": \"starts-with\",\n \"ends-with\": \"ends-with\",\n \"includes\": \"includes\"\n};\n\n// #endregion\n\n// #region Param references\n\n/**\n * Placeholder for a parameter value inside a cached expression template. Never\n * escapes this module — binding replaces it with a plain ValueExpression that\n * holds the resolved value.\n */\nclass ParamReferenceExpression extends ValueExpression {\n\n /** Path into the params object, excluding the params root name. */\n readonly paramPath: string[];\n /** The property this value is compared against; drives serialization/conversion at bind time. */\n readonly pairedProperty: PropertyInfo<any> | null;\n /** Whether the paired property's type converter applies (equality/relational comparisons only). */\n readonly applyConverter: boolean;\n\n constructor(options: {\n paramPath: string[],\n pairedProperty: PropertyInfo<any> | null,\n applyConverter: boolean\n }) {\n super({ value: undefined });\n this.paramPath = options.paramPath;\n this.pairedProperty = options.pairedProperty;\n this.applyConverter = options.applyConverter;\n }\n}\n\nconst resolveParamPath = (paramsName: string, path: string[], data: unknown) => {\n\n let result = data as Record<string, unknown>;\n\n for (let i = 0; i < path.length; i++) {\n const name = path[i];\n\n if (result != null && typeof result === \"object\" && name in result) {\n result = result[name] as Record<string, unknown>;\n continue;\n }\n\n throw new ParamDependentParseError(ERROR_MESSAGES.PARAM_PATH_NOT_FOUND([paramsName, ...path].join(\".\"), data));\n }\n\n return result as unknown;\n}\n\n/**\n * Applies the paired property's value serializer and (optionally) its schema\n * type converter, matching how literal values are treated at parse time.\n */\nconst resolvePairedValue = (value: unknown, pairedProperty: PropertyInfo<any> | null, applyConverter: boolean) => {\n\n if (pairedProperty == null) {\n return value;\n }\n\n let result = value;\n\n if (pairedProperty.valueSerializer != null) {\n result = String(pairedProperty.valueSerializer(parseUnknown(result)));\n }\n\n if (applyConverter) {\n result = converters[pairedProperty.type](result);\n }\n\n return result;\n}\n\n// #endregion\n\n// #region Parser\n\n/**\n * Recursive descent parser over the token stream. Produces an expression\n * template: literal values are fully resolved, parameter values are represented\n * as ParamReferenceExpression placeholders so the template can be cached and\n * re-bound with different params.\n */\nclass ExpressionParser {\n\n private readonly schema: CompiledSchema<any>;\n private readonly stream: TokenStream;\n private readonly entityName: string;\n private readonly paramsName: string | null;\n private readonly params: unknown;\n\n /** Set when a param value shaped the tree itself (e.g. x[p.name]) — such templates cannot be cached. */\n structurallyDependsOnParams: boolean = false;\n\n constructor(schema: CompiledSchema<any>, stream: TokenStream, entityName: string, paramsName: string | null, params: unknown) {\n this.schema = schema;\n this.stream = stream;\n this.entityName = entityName;\n this.paramsName = paramsName;\n this.params = params;\n }\n\n parse(): Expression {\n const expression = this.parseOr();\n\n if (!this.stream.isAtEnd) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`unexpected token '${this.stream.peek()?.value}'`));\n }\n\n return expression;\n }\n\n // || binds loosest, so it sits at the root of the parse\n private parseOr(): Expression {\n let left = this.parseAnd();\n\n while (this.stream.matchPunctuation(\"||\")) {\n const right = this.parseAnd();\n\n // A tautology (`true`) absorbs the whole disjunction\n if (Expression.isEmpty(left) || Expression.isEmpty(right)) {\n left = Expression.EMPTY;\n continue;\n }\n\n left = new OperatorExpression({ operator: \"||\", left, right });\n }\n\n return left;\n }\n\n private parseAnd(): Expression {\n let left = this.parseUnary();\n\n while (this.stream.matchPunctuation(\"&&\")) {\n const right = this.parseUnary();\n\n // A tautology (`true`) is the identity of a conjunction\n if (Expression.isEmpty(left)) {\n left = right;\n continue;\n }\n\n if (Expression.isEmpty(right)) {\n continue;\n }\n\n left = new OperatorExpression({ operator: \"&&\", left, right });\n }\n\n return left;\n }\n\n private parseUnary(): Expression {\n if (this.stream.matchPunctuation(\"!\")) {\n return this.negateExpression(this.parseUnary());\n }\n\n return this.parseComparison();\n }\n\n /**\n * Applies `!` to an already-parsed expression: comparators flip their\n * negated flag, compound expressions distribute via De Morgan's laws.\n */\n private negateExpression(expression: Expression): Expression {\n if (expression instanceof ComparatorExpression) {\n expression.negated = !expression.negated;\n return expression;\n }\n\n if (expression instanceof OperatorExpression && expression.left != null && expression.right != null) {\n return new OperatorExpression({\n operator: expression.operator === \"&&\" ? \"||\" : \"&&\",\n left: this.negateExpression(expression.left),\n right: this.negateExpression(expression.right)\n });\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"'!' on this expression\"));\n }\n\n private parseComparison(): Expression {\n\n // Parenthesized group\n if (this.stream.matchPunctuation(\"(\")) {\n const expression = this.parseOr();\n this.stream.expectPunctuation(\")\");\n\n const trailing = this.stream.peek();\n if (trailing != null && trailing.kind === \"punctuation\" && COMPARISON_OPERATORS[trailing.value] != null) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"comparison against a parenthesized expression\"));\n }\n\n return expression;\n }\n\n const left = this.parseOperand();\n const operatorToken = this.stream.peek();\n\n if (operatorToken != null && operatorToken.kind === \"punctuation\" && COMPARISON_OPERATORS[operatorToken.value] != null) {\n this.stream.next();\n const right = this.parseOperand();\n return this.buildComparison(left, COMPARISON_OPERATORS[operatorToken.value], right);\n }\n\n return this.buildStandalone(left);\n }\n\n private parseOperand(): Operand {\n const token = this.stream.peek();\n\n if (token == null) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"unexpected end of expression\"));\n }\n\n if (token.kind === \"string\") {\n this.stream.next();\n return this.withValueTransformer({ kind: \"value\", value: token.value, transformer: null, locale: null });\n }\n\n if (token.kind === \"number\") {\n this.stream.next();\n return { kind: \"value\", value: Number(token.value), transformer: null, locale: null };\n }\n\n if (token.kind === \"punctuation\" && token.value === \"-\") {\n this.stream.next();\n const numberToken = this.stream.next();\n\n if (numberToken.kind !== \"number\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"unary '-' on a non-number\"));\n }\n\n return { kind: \"value\", value: -Number(numberToken.value), transformer: null, locale: null };\n }\n\n if (token.kind === \"punctuation\" && token.value === \"[\") {\n return this.parseArrayLiteralOperand();\n }\n\n if (token.kind === \"identifier\") {\n return this.parseIdentifierOperand();\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(String(token.value)));\n }\n\n /**\n * Parses an inline array of literals, e.g. `[\"active\", \"pending\"]`, and the\n * membership test that follows it: `[...].includes(entity.property)`.\n */\n private parseArrayLiteralOperand(): Operand {\n this.stream.expectPunctuation(\"[\");\n const elements: unknown[] = [];\n\n while (!this.stream.isPunctuation(\"]\")) {\n const element = this.parseOperand();\n\n if (element.kind !== \"value\" || element.transformer != null) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"a non-literal element in an array literal\"));\n }\n\n elements.push(element.value);\n\n if (!this.stream.matchPunctuation(\",\")) {\n break;\n }\n }\n\n this.stream.expectPunctuation(\"]\");\n\n const array: ValueOperand = { kind: \"value\", value: elements, transformer: null, locale: null };\n\n // The only supported use is a membership test on a schema property\n if (this.stream.isPunctuation(\".\") || this.stream.isPunctuation(\"?.\")) {\n this.stream.next();\n const method = this.stream.next();\n\n if (method.kind !== \"identifier\" || method.value !== \"includes\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`'.${method.value}' on an array literal`));\n }\n\n this.stream.expectPunctuation(\"(\");\n const argument = this.parseOperand();\n this.stream.expectPunctuation(\")\");\n\n if (argument.kind === \"method-call\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"nested method call inside .includes()\"));\n }\n\n return { kind: \"method-call\", target: array, method: \"includes\", argument };\n }\n\n return array;\n }\n\n private parseIdentifierOperand(): Operand {\n const root = this.stream.next().value;\n\n // Keyword literals\n if (root === \"true\" || root === \"false\") {\n return { kind: \"value\", value: root === \"true\", transformer: null, locale: null };\n }\n\n if (root === \"null\") {\n return { kind: \"value\", value: null, transformer: null, locale: null };\n }\n\n if (root === \"undefined\") {\n return { kind: \"value\", value: undefined, transformer: null, locale: null };\n }\n\n if (root === \"void\") {\n this.stream.next(); // the '0'\n return { kind: \"value\", value: undefined, transformer: null, locale: null };\n }\n\n if (root === this.entityName) {\n return this.parseChain({ kind: \"property\", root });\n }\n\n if (this.paramsName != null && root === this.paramsName) {\n return this.parseChain({ kind: \"param\", root });\n }\n\n // A bare variable from the outer scope — its value cannot be derived from source text\n throw new Error(ERROR_MESSAGES.VARIABLE_VALUE(root));\n }\n\n /**\n * Parses the segments after an entity/params root: dot access, bracket\n * access, transform methods and comparator methods.\n */\n private parseChain(options: { kind: \"property\" | \"param\", root: string }): Operand {\n const path: string[] = [];\n let transformer: Transformer | null = null;\n let locale: string | null = null;\n\n while (true) {\n if (this.stream.matchPunctuation(\".\") || this.stream.matchPunctuation(\"?.\")) {\n const segment = this.stream.next();\n\n if (segment.kind !== \"identifier\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`'.${segment.value}'`));\n }\n\n // Method call\n if (this.stream.isPunctuation(\"(\")) {\n const method = segment.value;\n\n if (TRANSFORM_METHODS[method] != null) {\n this.stream.expectPunctuation(\"(\");\n this.stream.expectPunctuation(\")\");\n transformer = TRANSFORM_METHODS[method].transformer;\n locale = TRANSFORM_METHODS[method].locale;\n continue;\n }\n\n if (COMPARATOR_METHODS[method] != null) {\n this.stream.expectPunctuation(\"(\");\n const argument = this.parseOperand();\n this.stream.expectPunctuation(\")\");\n\n if (argument.kind === \"method-call\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`nested method call inside .${method}()`));\n }\n\n return {\n kind: \"method-call\",\n target: this.resolveChain(options.kind, path, transformer, locale),\n method: method as MethodCallOperand[\"method\"],\n argument\n };\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`method '.${method}()'`));\n }\n\n if (transformer != null) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"property access after a transform method\"));\n }\n\n path.push(segment.value);\n continue;\n }\n\n if (this.stream.matchPunctuation(\"[\")) {\n path.push(this.parseBracketSegment(options.kind));\n this.stream.expectPunctuation(\"]\");\n continue;\n }\n\n break;\n }\n\n return this.resolveChain(options.kind, path, transformer, locale);\n }\n\n private parseBracketSegment(kind: \"property\" | \"param\"): string {\n const token = this.stream.next();\n\n // Literal segment: entity[\"name\"]\n if (token.kind === \"string\") {\n return token.value;\n }\n\n // Param-driven segment: entity[p.name] — the property depends on the\n // param VALUE, so the resulting template is tied to these params.\n // Stryker disable next-line all: documented equivalent cluster (see\n // docs/mutation-backlog.md) — every mutation of this four-conjunct guard reroutes\n // bracket access between two paths that both collapse to NOT_PARSABLE; the\n // experiment recorded there aimed 30 tests at this line and killed none.\n if (kind === \"property\" && token.kind === \"identifier\" && this.paramsName != null && token.value === this.paramsName) {\n const paramPath: string[] = [];\n\n while (this.stream.matchPunctuation(\".\") || this.stream.matchPunctuation(\"?.\")) {\n paramPath.push(this.stream.next().value);\n }\n\n const resolved = resolveParamPath(this.paramsName, paramPath, this.params);\n\n if (typeof resolved !== \"string\") {\n throw new ParamDependentParseError(ERROR_MESSAGES.PROPERTY_NOT_FOUND(paramPath.join(\".\")));\n }\n\n this.structurallyDependsOnParams = true;\n return resolved;\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`bracket access '[${token.value}]'`));\n }\n\n private resolveChain(kind: \"property\" | \"param\", path: string[], transformer: Transformer | null, locale: string | null): PropertyOperand | ParamOperand {\n\n if (kind === \"param\") {\n if (path.length === 0) {\n // `params` alone is a variable, not a value we can resolve\n throw new Error(ERROR_MESSAGES.PARAM_PATH_NOT_FOUND(this.paramsName ?? \"params\", this.params));\n }\n\n return { kind: \"param\", path, transformer, locale };\n }\n\n const pathString = path.join(\".\");\n const property = this.schema.properties.find(w => w.getAssignmentPath() == pathString);\n\n if (property == null) {\n // `.length` on a string/array property — a real schema property named\n // `length` wins (checked above); otherwise treat it as a transformer\n if (path.length > 1 && path[path.length - 1] === \"length\" && transformer == null) {\n const parentPath = path.slice(0, -1).join(\".\");\n const parent = this.schema.properties.find(w => w.getAssignmentPath() == parentPath);\n\n // Vector is deliberately absent. Its length is the dimension count declared\n // in the schema — a constant, not data — so a filter on it answers a question\n // nobody asks, and pushing it down would need `json_array_length` on a\n // backend storing JSON and something else entirely on one with a native\n // vector column. Not parsing it leaves a clear error instead of a dialect gap.\n if (parent != null && (parent.type === SchemaTypes.String || parent.type === SchemaTypes.Array)) {\n return { kind: \"property\", property: parent, transformer: \"length\", locale: null };\n }\n }\n\n throw new Error(ERROR_MESSAGES.PROPERTY_NOT_FOUND(pathString));\n }\n\n return { kind: \"property\", property, transformer, locale };\n }\n\n private withValueTransformer(operand: ValueOperand): ValueOperand {\n if (this.stream.isPunctuation(\".\")) {\n const method = this.stream.peek(1);\n\n // Stryker disable next-line all: documented equivalent cluster (see\n // docs/mutation-backlog.md) — the guard's conjuncts each route to a rejection that\n // collapses to NOT_PARSABLE with an indistinguishable message; 18 targeted tests\n // killed none of these.\n if (method != null && method.kind === \"identifier\" && TRANSFORM_METHODS[method.value] != null) {\n this.stream.next(); // .\n this.stream.next(); // method name\n this.stream.expectPunctuation(\"(\");\n this.stream.expectPunctuation(\")\");\n\n operand.transformer = TRANSFORM_METHODS[method.value].transformer;\n operand.locale = TRANSFORM_METHODS[method.value].locale;\n }\n }\n\n return operand;\n }\n\n // #region Condition building\n\n private buildComparison(left: Operand, operator: { comparator: Comparator, negated: boolean, strict: boolean }, right: Operand): Expression {\n\n // methodCall == true/false — fold the boolean into negation\n if (left.kind === \"method-call\") {\n if (operator.comparator === \"equals\" && right.kind === \"value\" && typeof right.value === \"boolean\") {\n const comparator = this.buildMethodComparator(left);\n const comparedToFalse = right.value === false;\n comparator.negated = comparator.negated !== (operator.negated !== comparedToFalse);\n return comparator;\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"comparing a method call to a non-boolean\"));\n }\n\n if (right.kind === \"method-call\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"method call on the right side of a comparison\"));\n }\n\n if (left.kind === \"property\" && right.kind === \"property\") {\n // Casing transformers are only valid with string-matching comparators,\n // which cannot produce a property-to-property comparison\n if (left.transformer === \"to-lower-case\" || left.transformer === \"to-upper-case\" ||\n right.transformer === \"to-lower-case\" || right.transformer === \"to-upper-case\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"transform method outside of startsWith/endsWith/includes\"));\n }\n\n return new ComparatorExpression({\n comparator: operator.comparator,\n negated: operator.negated,\n strict: operator.strict,\n left: this.createPropertyExpression(left),\n right: this.createPropertyExpression(right)\n });\n }\n\n if (left.kind === \"property\" && right.kind !== \"property\") {\n return this.buildPropertyComparator(left, operator, right, /* applyConverter */ true);\n }\n\n if (right.kind === \"property\" && left.kind !== \"property\") {\n const swapped = { ...operator, comparator: SWAPPED_COMPARATORS[operator.comparator] };\n return this.buildPropertyComparator(right, swapped, left, /* applyConverter */ true);\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"comparison requires a schema property on at least one side\"));\n }\n\n private buildStandalone(operand: Operand): Expression {\n\n if (operand.kind === \"method-call\") {\n return this.buildMethodComparator(operand);\n }\n\n if (operand.kind === \"property\") {\n // Truthy shorthand on `.length`: a length is truthy exactly when > 0\n if (operand.transformer === \"length\") {\n return this.buildPropertyComparator(operand, COMPARISON_OPERATORS[\">\"], { kind: \"value\", value: 0, transformer: null, locale: null }, /* applyConverter */ true);\n }\n\n // Truthy shorthand: `w.isActive` → isActive === true\n return this.buildPropertyComparator(operand, COMPARISON_OPERATORS[\"===\"], { kind: \"value\", value: true, transformer: null, locale: null }, /* applyConverter */ true);\n }\n\n // Constant `true` — a tautology, which parseAnd/parseOr simplify away\n if (operand.kind === \"value\" && operand.value === true && operand.transformer == null) {\n return Expression.EMPTY;\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"a filter condition must reference a schema property\"));\n }\n\n private buildMethodComparator(operand: MethodCallOperand): ComparatorExpression {\n const { target, method, argument } = operand;\n\n if (target.kind === \"property\") {\n if (argument.kind === \"property\") {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`.${method}() comparing two schema properties`));\n }\n\n // Method arguments skip type conversion — only the value serializer applies\n return this.buildPropertyComparator(target, { comparator: COMPARATOR_METHODS[method], negated: false, strict: false }, argument, /* applyConverter */ false);\n }\n\n // [\"a\", \"b\"].includes(x.prop) / params.list.includes(x.prop) —\n // membership test with the collection on the left\n if (method === \"includes\" && argument.kind === \"property\") {\n if (target.transformer != null) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"transform method on a collection used with .includes()\"));\n }\n\n return new ComparatorExpression({\n comparator: \"includes\",\n negated: false,\n strict: false,\n left: this.createValueExpression(target, argument.property, /* applyConverter */ false),\n right: this.createPropertyExpression(argument)\n });\n }\n\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(`.${method}() on a non-property target`));\n }\n\n private buildPropertyComparator(property: PropertyOperand, operator: { comparator: Comparator, negated: boolean, strict: boolean }, value: ValueOperand | ParamOperand, applyConverter: boolean): ComparatorExpression {\n\n const isStringMatch = operator.comparator === \"starts-with\" || operator.comparator === \"ends-with\" || operator.comparator === \"includes\";\n\n // `.length` compares a NUMBER, so the paired property's serializer and\n // type converter must not touch the value; and a length has no meaning\n // inside a string-matching comparator\n if (property.transformer === \"length\") {\n if (isStringMatch) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"'.length' with startsWith/endsWith/includes\"));\n }\n\n return new ComparatorExpression({\n comparator: operator.comparator,\n negated: operator.negated,\n strict: operator.strict,\n left: this.createPropertyExpression(property),\n right: this.createValueExpression(value, null, /* applyConverter */ false)\n });\n }\n\n // Casing transformers on a property are only meaningful with string-matching\n // comparators; on relational comparators the plugins would silently\n // ignore them and return wrong data\n if (property.transformer != null && !isStringMatch) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"transform method outside of startsWith/endsWith/includes\"));\n }\n\n return new ComparatorExpression({\n comparator: operator.comparator,\n negated: operator.negated,\n strict: operator.strict,\n left: this.createPropertyExpression(property),\n right: this.createValueExpression(value, property.property, applyConverter)\n });\n }\n\n private createPropertyExpression(operand: PropertyOperand): PropertyExpression {\n const expression = new PropertyExpression({ property: operand.property });\n expression.transformer = operand.transformer;\n expression.locale = operand.locale;\n return expression;\n }\n\n private createValueExpression(operand: ValueOperand | ParamOperand, pairedProperty: PropertyInfo<any> | null, applyConverter: boolean): ValueExpression {\n\n if (operand.kind === \"param\") {\n const expression = new ParamReferenceExpression({ paramPath: operand.path, pairedProperty, applyConverter });\n expression.transformer = operand.transformer;\n expression.locale = operand.locale;\n return expression;\n }\n\n const expression = new ValueExpression({ value: resolvePairedValue(operand.value, pairedProperty, applyConverter) });\n expression.transformer = operand.transformer;\n expression.locale = operand.locale;\n return expression;\n }\n\n // #endregion\n}\n\n// #endregion\n\n// #region Template binding\n\n/**\n * Deep-clones a template into a consumer-facing tree, resolving parameter\n * placeholders against the supplied params. Always clones so cached templates\n * can never be mutated by consumers.\n */\nconst bindExpression = (expression: Expression, paramsName: string | null, params: unknown): Expression => {\n\n if (expression instanceof ParamReferenceExpression) {\n const raw = resolveParamPath(paramsName ?? \"params\", expression.paramPath, params);\n const bound = new ValueExpression({ value: resolvePairedValue(raw, expression.pairedProperty, expression.applyConverter) });\n bound.transformer = expression.transformer;\n bound.locale = expression.locale;\n return bound;\n }\n\n if (expression instanceof ValueExpression) {\n const clone = new ValueExpression({ value: expression.value });\n clone.transformer = expression.transformer;\n clone.locale = expression.locale;\n return clone;\n }\n\n if (expression instanceof PropertyExpression) {\n const clone = new PropertyExpression({ property: expression.property });\n clone.transformer = expression.transformer;\n clone.locale = expression.locale;\n return clone;\n }\n\n if (expression instanceof ComparatorExpression) {\n return new ComparatorExpression({\n comparator: expression.comparator,\n negated: expression.negated,\n strict: expression.strict,\n left: expression.left ? bindExpression(expression.left, paramsName, params) : undefined,\n right: expression.right ? bindExpression(expression.right, paramsName, params) : undefined\n });\n }\n\n if (expression instanceof OperatorExpression) {\n return new OperatorExpression({\n operator: expression.operator,\n left: expression.left ? bindExpression(expression.left, paramsName, params) : undefined,\n right: expression.right ? bindExpression(expression.right, paramsName, params) : undefined\n });\n }\n\n return expression;\n}\n\n// #endregion\n\n// #region Function source handling\n\ntype FunctionShape = {\n entityName: string;\n paramsName: string | null;\n body: string;\n}\n\n/**\n * Splits stringified filter source into parameter names and the expression\n * body, unwrapping single-return block bodies.\n */\nconst resolveFunctionShape = (stringifiedFunction: string, hasParams: boolean): FunctionShape => {\n\n const source = stringifiedFunction.trim();\n\n let parameterNames: string;\n let body: string;\n\n // `function (x) { ... }` / `function name(x) { ... }` — what ES5-targeting\n // transpilers rewrite every arrow filter into\n const functionHead = /^function\\b[^(]*\\(/.exec(source);\n\n if (functionHead != null) {\n const parametersEnd = source.indexOf(\")\", functionHead[0].length);\n\n if (parametersEnd === -1) {\n throw new Error(\"Invalid Function\");\n }\n\n parameterNames = source.slice(functionHead[0].length, parametersEnd).trim();\n body = source.slice(parametersEnd + 1).trim();\n } else {\n const arrowIndex = source.indexOf(\"=>\");\n\n if (arrowIndex === -1) {\n throw new Error(\"Invalid Function\");\n }\n\n parameterNames = source.substring(0, arrowIndex).trim();\n body = source.substring(arrowIndex + 2).trim();\n\n // Strip wrapping parens: (entity) or ([x, p])\n if (parameterNames.startsWith(\"(\") && parameterNames.endsWith(\")\")) {\n parameterNames = parameterNames.slice(1, -1).trim();\n }\n }\n\n let entityName: string;\n let paramsName: string | null = null;\n\n if (parameterNames.startsWith(\"[\") && parameterNames.endsWith(\"]\")) {\n const destructured = parameterNames.slice(1, -1).split(\",\").map(w => w.trim());\n entityName = destructured[0];\n\n if (hasParams) {\n paramsName = destructured[1] ?? null;\n }\n } else {\n entityName = parameterNames;\n }\n\n if (entityName == null || entityName.length === 0) {\n throw new Error(\"Invalid Function\");\n }\n\n // Unwrap a single-return block body: { return <expression>; }\n if (body.startsWith(\"{\")) {\n const inner = body.slice(1, body.lastIndexOf(\"}\")).trim();\n\n if (!inner.startsWith(\"return\")) {\n throw new Error(ERROR_MESSAGES.UNSUPPORTED(\"block body without a single return statement\"));\n }\n\n body = inner.slice(\"return\".length).trim();\n\n if (body.endsWith(\";\")) {\n body = body.slice(0, -1).trim();\n }\n }\n\n return { entityName, paramsName, body };\n}\n\n// #endregion\n\n// #region Cache\n\ntype ParsedTemplate = {\n template: Expression;\n paramsName: string | null;\n}\n\n// Keyed by schema instance so identical filter source on different schemas can\n// never collide; entries live only as long as the schema does\nconst templateCache = new WeakMap<CompiledSchema<any>, Map<string, ParsedTemplate>>();\nconst MAX_CACHED_TEMPLATES_PER_SCHEMA = 1024;\n\nconst getCachedTemplate = (schema: CompiledSchema<any>, source: string): ParsedTemplate | null => {\n return templateCache.get(schema)?.get(source) ?? null;\n}\n\nconst setCachedTemplate = (schema: CompiledSchema<any>, source: string, entry: ParsedTemplate) => {\n let bySource = templateCache.get(schema);\n\n if (bySource == null) {\n bySource = new Map<string, ParsedTemplate>();\n templateCache.set(schema, bySource);\n }\n\n // Filter source strings come from static code, so this cap should never be\n // hit in practice — it only guards against unbounded dynamic generation.\n // Stryker disable next-line all: the cap is a pure resource bound — every mutation of\n // it (never clear, always clear, off-by-one) parses identically and differs only in\n // memory growth, which no observable boundary can assert.\n if (bySource.size >= MAX_CACHED_TEMPLATES_PER_SCHEMA) {\n bySource.clear();\n }\n\n bySource.set(source, entry);\n}\n\n// #endregion\n\nexport const combineExpressions = (...expressions: Expression[]): Expression => {\n\n if (expressions.length === 0) {\n throw new Error(\"combineExpressions requires at least 1 expression\");\n }\n\n\n if (expressions.length === 1) {\n return expressions[0];\n }\n\n // Start with the first expression\n let result = expressions[0];\n\n // Loop through remaining expressions and combine them\n for (let i = 1; i < expressions.length; i++) {\n result = new OperatorExpression({\n operator: \"&&\",\n left: result,\n right: expressions[i]\n });\n }\n\n return result;\n};\n\n/**\n * Parses an expression SOURCE FRAGMENT against one schema and one root name.\n *\n * `toExpression` starts from a function and works out its own roots. This starts from text, which\n * is what a caller has when it has split a larger predicate apart — `p.rank > 10` lifted out of\n * `([p, m]) => p.rank > 10 && m.won === true`.\n *\n * **A fragment naming anything other than `rootName` returns `NOT_PARSABLE`, and that is the\n * point.** It is how a caller discovers which side of a join a conjunct belongs to: parse it\n * against each side in turn, and exactly one succeeds for a single-side condition. A condition\n * spanning both fails against both, which is the correct answer — it cannot be pushed to either.\n *\n * No params: a fragment carrying a params reference has no bag to resolve it against here, so it\n * fails rather than binding to nothing.\n *\n * Deliberately NOT cached. The cache is keyed by function source, and a fragment is not a function\n * — two different lambdas can contain the same fragment text against different schemas.\n */\nexport const parseFragment = (schema: CompiledSchema<any>, body: string, rootName: string): Expression => {\n try {\n const stream = new TokenStream(tokenize(body));\n const parser = new ExpressionParser(schema, stream, rootName, null, undefined);\n\n return parser.parse();\n } catch {\n // The failure is expected and informative — see above — so it is not logged. A caller that\n // parses one conjunct against two schemas would otherwise warn on every successful split.\n return Expression.NOT_PARSABLE;\n }\n};\n\nexport const toExpression = <T extends any, P extends any>(schema: CompiledSchema<any>, fn: Filter<T> | ParamsFilter<T, P>, params?: P) => {\n const stringifiedFunction = fn.toString();\n\n const warn = (error: unknown) => logger.warn(\"Error parsing expression\", {\n error,\n collectionName: schema.collectionName,\n params,\n selector: stringifiedFunction\n });\n\n const cached = getCachedTemplate(schema, stringifiedFunction);\n\n if (cached != null) {\n // A cached failure — the warning was already logged when it was discovered\n if (Expression.isNotParsable(cached.template)) {\n return Expression.NOT_PARSABLE;\n }\n\n try {\n return bindExpression(cached.template, cached.paramsName, params);\n } catch (error) {\n // Binding failures are param-dependent by nature — never cached\n warn(error);\n return Expression.NOT_PARSABLE;\n }\n }\n\n let paramsName: string | null = null;\n let template: Expression;\n let structurallyDependsOnParams: boolean;\n\n try {\n const shape = resolveFunctionShape(stringifiedFunction, params != null);\n const stream = new TokenStream(tokenize(shape.body));\n const parser = new ExpressionParser(schema, stream, shape.entityName, shape.paramsName, params);\n paramsName = shape.paramsName;\n template = parser.parse();\n structurallyDependsOnParams = parser.structurallyDependsOnParams;\n } catch (error) {\n // Cache the failure so a hot query on an unsupported filter doesn't\n // re-parse and re-warn on every execution. Param-dependent failures are\n // exempt: the same source can succeed with different params.\n if (!(error instanceof ParamDependentParseError)) {\n setCachedTemplate(schema, stringifiedFunction, { template: Expression.NOT_PARSABLE, paramsName: null });\n }\n\n warn(error);\n return Expression.NOT_PARSABLE;\n }\n\n // Templates whose structure was resolved from param values are only\n // valid for this exact params object — parse those fresh every time\n if (!structurallyDependsOnParams) {\n setCachedTemplate(schema, stringifiedFunction, { template, paramsName });\n }\n\n try {\n return bindExpression(template, paramsName, params);\n } catch (error) {\n warn(error);\n return Expression.NOT_PARSABLE;\n }\n}\n","import { QueryOptionExecutionTarget } from \"../plugins\";\nimport { CompiledSchemaCore, PropertyInfo } from \"../schema\";\n\n/**\n * JSON-safe form of a literal. Tagged only where JSON cannot carry the value as it is.\n *\n * See `Expression.toJson`.\n */\nexport type SerializedValue =\n | { k: \"raw\"; v: string | number | boolean | null }\n | { k: \"date\"; v: string }\n | { k: \"undefined\" }\n | { k: \"number\"; v: \"NaN\" | \"Infinity\" | \"-Infinity\" }\n | { k: \"array\"; v: SerializedValue[] };\n\n/** JSON-safe form of an expression tree. See `Expression.toJson`. */\nexport type SerializedExpression =\n | { t: \"empty\" }\n | { t: \"not-parsable\" }\n | { t: \"operator\"; operator: Operator; left?: SerializedExpression; right?: SerializedExpression }\n | {\n t: \"comparator\";\n comparator: Comparator;\n negated: boolean;\n strict: boolean;\n left?: SerializedExpression;\n right?: SerializedExpression;\n }\n | { t: \"property\"; path: string; transformer: Transformer | null; locale: string | null }\n | { t: \"value\"; value: SerializedValue; transformer: Transformer | null; locale: string | null };\n\nconst valueToJson = (value: unknown): SerializedValue => {\n if (value === undefined) {\n return { k: \"undefined\" };\n }\n\n if (value === null) {\n return { k: \"raw\", v: null };\n }\n\n if (value instanceof Date) {\n // ISO rather than epoch millis: it survives a human reading the payload, and an invalid\n // Date has no ISO form — so it is caught here rather than becoming a silent `null`.\n return { k: \"date\", v: value.toISOString() };\n }\n\n if (Array.isArray(value)) {\n return { k: \"array\", v: value.map(valueToJson) };\n }\n\n if (typeof value === \"number\" && Number.isFinite(value) === false) {\n // `JSON.stringify` turns all three of these into `null`, which would compare as a different\n // value entirely rather than failing.\n return { k: \"number\", v: Number.isNaN(value) ? \"NaN\" : value > 0 ? \"Infinity\" : \"-Infinity\" };\n }\n\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return { k: \"raw\", v: value };\n }\n\n throw new Error(\n `Cannot serialize this filter value: only strings, numbers, booleans, null, undefined, Dates and arrays of those can cross a wire. ` +\n `Received: ${Object.prototype.toString.call(value)}`\n );\n};\n\nconst valueFromJson = (value: SerializedValue): unknown => {\n if (value.k === \"undefined\") {\n return undefined;\n }\n\n if (value.k === \"date\") {\n return new Date(value.v);\n }\n\n if (value.k === \"array\") {\n return value.v.map(valueFromJson);\n }\n\n if (value.k === \"number\") {\n return value.v === \"NaN\" ? Number.NaN : value.v === \"Infinity\" ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\n }\n\n return value.v;\n};\n\nexport type ParsedExpression = {\n expression: Expression;\n // Will be memory when trying to query on an untracked computed property or on a function\n executionTarget: QueryOptionExecutionTarget;\n}\n\n/**\n * The base class for all expression types.\n */\nexport abstract class Expression {\n /** The type of the expression. */\n abstract readonly type: ExpressionType;\n /** The left-hand side of the expression (if applicable). */\n left?: Expression;\n /** The right-hand side of the expression (if applicable). */\n right?: Expression;\n\n constructor(left?: Expression, right?: Expression) {\n this.left = left;\n this.right = right;\n }\n\n static get EMPTY() {\n return new EmptyExpression();\n }\n\n static get NOT_PARSABLE() {\n return new NotParsableExpression();\n }\n\n static isEmpty(expression: Expression) {\n return expression.type === \"empty\" || expression instanceof EmptyExpression;\n }\n\n static isNotParsable(expression: Expression) {\n return expression.type === \"not-parsable\" || expression instanceof NotParsableExpression;\n }\n\n /**\n * Turns a tree into plain JSON, so a whole query can cross a wire.\n *\n * On the class rather than beside it, because this is the type's own REPRESENTATION — there is one\n * right answer and it belongs with the thing being represented, next to `EMPTY` and `isEmpty`.\n * Rendering a tree into some other language (`toSql`, `toMql`, `evaluate`) is a different kind of\n * thing: there are many, each belongs to its consumer, and none of them is canonical.\n *\n * ## Why it is this small\n *\n * Of the six node types a bound tree can contain, exactly one holds anything JSON cannot carry:\n * `PropertyExpression`, whose live `PropertyInfo` has functions, a parent chain and caches. It\n * reduces to a property PATH — `PropertyInfo.id` IS the dotted path, and `getProperty` is keyed by\n * exactly that — so rebinding is one lookup.\n *\n * `ParamReferenceExpression` never appears: it is a parse-time placeholder that binding replaces\n * with a plain `ValueExpression` holding the resolved value. A serialized tree is always already\n * bound, so there is no params object to send alongside it.\n *\n * Switches on `type` rather than using the `isXExpression` guards, which live in `../assertions`\n * and import this module — the guards test the same discriminant, so nothing is lost.\n */\n static toJson(expression: Expression): SerializedExpression {\n\n if (expression.type === \"operator\") {\n const operator = expression as OperatorExpression;\n\n return {\n t: \"operator\",\n operator: operator.operator,\n ...(operator.left != null && { left: Expression.toJson(operator.left) }),\n ...(operator.right != null && { right: Expression.toJson(operator.right) }),\n };\n }\n\n if (expression.type === \"comparator\") {\n const comparator = expression as ComparatorExpression;\n\n return {\n t: \"comparator\",\n comparator: comparator.comparator,\n negated: comparator.negated,\n strict: comparator.strict,\n ...(comparator.left != null && { left: Expression.toJson(comparator.left) }),\n ...(comparator.right != null && { right: Expression.toJson(comparator.right) }),\n };\n }\n\n if (expression.type === \"property\") {\n const property = expression as PropertyExpression;\n\n return {\n t: \"property\",\n // The dotted path, which is exactly the key `getProperty` is looking up\n path: property.property.id,\n transformer: property.transformer,\n locale: property.locale,\n };\n }\n\n if (expression.type === \"value\") {\n const value = expression as ValueExpression;\n\n return {\n t: \"value\",\n value: valueToJson(value.value),\n transformer: value.transformer,\n locale: value.locale,\n };\n }\n\n return expression.type === \"empty\" ? { t: \"empty\" } : { t: \"not-parsable\" };\n }\n\n /**\n * Rebuilds a tree from JSON, rebinding every property against `schema`.\n *\n * The schema is SUPPLIED rather than read out of the payload. A filter always belongs to a known\n * collection, and the RECEIVER's schema is the authority on what its properties are — taking an\n * id from the payload would mean rebinding against a schema the sender chose, which is backwards\n * for anything crossing a trust boundary.\n *\n * @throws when a property path is not declared by `schema`. Not `NOT_PARSABLE`: on a receiver, a\n * filter that silently stops filtering returns rows the requester excluded, which is the one\n * failure here worse than an error.\n */\n static fromJson(json: SerializedExpression, schema: CompiledSchemaCore<any>): Expression {\n\n const child = (node: SerializedExpression | undefined) => node == null ? undefined : Expression.fromJson(node, schema);\n\n if (json.t === \"operator\") {\n return new OperatorExpression({ operator: json.operator, left: child(json.left), right: child(json.right) });\n }\n\n if (json.t === \"comparator\") {\n return new ComparatorExpression({\n comparator: json.comparator,\n negated: json.negated,\n strict: json.strict,\n left: child(json.left),\n right: child(json.right),\n });\n }\n\n if (json.t === \"property\") {\n const property = schema.getProperty(json.path);\n\n if (property == null) {\n throw new Error(\n `Cannot deserialize a filter: this schema does not declare the property it names. ` +\n `Property: ${json.path}, Collection: ${schema.collectionName}. ` +\n `The two sides disagree about the shape of the data, so the filter cannot be applied.`\n );\n }\n\n const rebuilt = new PropertyExpression({ property });\n rebuilt.transformer = json.transformer;\n rebuilt.locale = json.locale;\n\n return rebuilt;\n }\n\n if (json.t === \"value\") {\n const rebuilt = new ValueExpression({ value: valueFromJson(json.value) });\n rebuilt.transformer = json.transformer;\n rebuilt.locale = json.locale;\n\n return rebuilt;\n }\n\n return json.t === \"empty\" ? Expression.EMPTY : Expression.NOT_PARSABLE;\n }\n}\n\nexport class EmptyExpression extends Expression {\n readonly type = \"empty\" as const;\n}\n\nexport class NotParsableExpression extends Expression {\n readonly type = \"not-parsable\" as const;\n}\n\n/**\n * A class representing a comparison operation (e.g., equals, greater-than).\n */\nexport class ComparatorExpression extends Expression {\n /** The type of the expression (always 'comparator'). */\n readonly type = \"comparator\" as const;\n /** The comparator operation (e.g., equals, greater-than). */\n comparator: Comparator;\n /** Whether the comparison is negated (e.g., not equals). */\n negated: boolean;\n /** Whether the comparison is strict (type-sensitive). */\n strict: boolean;\n\n constructor(\n options: {\n comparator: Comparator,\n negated: boolean,\n strict: boolean,\n left?: Expression,\n right?: Expression\n }\n ) {\n super(options.left, options.right);\n this.comparator = options.comparator;\n this.negated = options.negated;\n this.strict = options.strict;\n }\n}\n\n/**\n * A class representing a logical operator (e.g., &&, ||).\n */\nexport class OperatorExpression extends Expression {\n /** The type of the expression (always 'operator'). */\n readonly type = \"operator\" as const;\n /** The logical operator. */\n operator: Operator;\n\n constructor(options: { operator: Operator, left?: Expression, right?: Expression }) {\n super(options.left, options.right);\n this.operator = options.operator;\n }\n}\n\n/**\n * A class representing a property path.\n */\nexport class PropertyExpression extends Expression {\n /** The type of the expression (always 'property'). */\n readonly type = \"property\" as const;\n /** The property info for the path. */\n property: PropertyInfo<any>;\n transformer: Transformer | null = null;\n locale: string | null = null;\n\n constructor(options: { property: PropertyInfo<any> }) {\n super();\n this.property = options.property;\n }\n}\n\n/**\n * A class representing a literal value.\n */\nexport class ValueExpression extends Expression {\n /** The type of the expression (always 'value'). */\n readonly type = \"value\" as const;\n /** The literal value. */\n value: unknown;\n\n transformer: Transformer | null = null;\n locale: string | null = null;\n\n constructor(options: {\n value: unknown\n }) {\n super();\n this.value = options.value;\n }\n}\n\n\n/**\n * The set of possible expression types.\n */\nexport type ExpressionType = \"operator\" | \"comparator\" | \"property\" | \"value\" | \"empty\" | \"not-parsable\";\n\n/**\n * Supported value transformations that can be applied to values.\n * `length` reads the length of a string or array property.\n */\nexport type Transformer = \"to-lower-case\" | \"to-upper-case\" | \"length\";\n\n/**\n * Supported comparator operations for expressions.\n */\nexport type Comparator =\n | \"equals\"\n | \"starts-with\"\n | \"includes\"\n | \"ends-with\"\n | \"greater-than\"\n | \"greater-than-equals\"\n | \"less-than\"\n | \"less-than-equals\";\n\n/**\n * Supported logical operators for expressions.\n */\nexport type Operator = \"&&\" | \"||\";\n\n/**\n * A function that filters a value of type T and returns a boolean.\n */\nexport type Filter<T extends any> = (value: T) => boolean;\n\n/**\n * A function that filters a value of type T with additional parameters P.\n */\nexport type ParamsFilter<T extends any, P> = (payload: [T, P]) => boolean;\n\n/**\n * A filter that can be either a simple filter or a parameterized filter.\n */\nexport type CompositeFilter<T extends any, P = never> = Filter<T> | ParamsFilter<T, P>;\n\n/**\n * An object that can be filtered using a composite filter and optional parameters.\n */\nexport type Filterable<T extends any, P = any> = {\n /** The filter function. */\n filter: CompositeFilter<T, P>;\n /** Optional parameters for the filter. */\n params?: P;\n};","import { PropertyInfo } from \"../schema\";\nimport { Expression, PropertyExpression } from \"./types\";\n\n/**\n * Extracts all properties referenced in an expression\n * @param expression The expression to analyze\n * @returns Array of PropertyInfo objects referenced in the expression\n */\nexport function getProperties(expression: Expression): PropertyInfo<any>[] {\n const properties: PropertyInfo<any>[] = [];\n\n function traverse(expr: Expression) {\n // If this is a property expression, add it to our collection\n if (expr.type === \"property\") {\n properties.push((expr as PropertyExpression).property);\n }\n\n // Traverse left and right expressions if they exist\n if (expr.left) {\n traverse(expr.left);\n }\n if (expr.right) {\n traverse(expr.right);\n }\n }\n\n traverse(expression);\n return properties;\n}\n\nexport function forEach(expression: Expression, callback: (expression: Expression) => boolean) {\n function traverse(expr: Expression): boolean {\n // Call the callback for this expression\n // If callback returns false, stop traversing\n if (!callback(expr)) {\n return false;\n }\n\n // Traverse left and right expressions if they exist\n if (expr.left) {\n if (!traverse(expr.left)) {\n return false;\n }\n }\n if (expr.right) {\n if (!traverse(expr.right)) {\n return false;\n }\n }\n\n return true;\n }\n\n traverse(expression);\n}","import { logger } from \"../utilities\";\nimport { CallbackResult, Result, ResultType } from \"../results\";\n\n/**\n * Type definition for an asynchronous function that takes data and a callback.\n * TIn: The input data type.\n * TOut: The output data type (passed to the callback).\n */\nexport type Processor<TIn, TOut> = (data: TIn, callback: (result: TOut, error?: any) => void) => void;\n\n// Return type for a step execution: Either the next step function or null if waiting/done.\ntype StepResult<TData> = TrampolineStep<TData> | null;\ntype TrampolineStep<TData> = () => StepResult<TData>;\n\nexport class TrampolinePipeline<TInitial, TCurrent = TInitial> {\n private _list: Processor<any, any>[] = [];\n private _hasErrored: boolean = false; // Flag to prevent calling done on error\n\n filter<TFinal>(initialData: TInitial, done: (data: TFinal, error?: any) => void) {\n\n this._hasErrored = false; // Reset error flag on new execution\n\n if (this._list.length === 0) {\n done(initialData as unknown as TFinal);\n return;\n }\n\n let index = 0;\n let currentData: any = initialData;\n let isRunning = false; // Guard against overlapping trampoline calls\n\n try {\n // --- Revised Completion Logic --- (Moved up for clarity)\n const finalStepSentinel = (): StepResult<any> => { // A special step function for the very end\n // Only call done if no error has occurred\n if (!this._hasErrored) {\n done(currentData as TFinal);\n }\n return null; // Stop the trampoline\n };\n\n const createStepRevised = (idx: number): TrampolineStep<any> => {\n return () => {\n if (this._hasErrored) return null; // Stop if an error occurred elsewhere\n\n if (idx >= this._list.length) {\n return finalStepSentinel(); // Execute the dedicated final step\n }\n\n const processor = this._list[idx];\n // Initialize syncCallbackResult to null to satisfy StepResult type\n let syncCallbackResult: StepResult<any> = null;\n let calledSync = false;\n\n try {\n processor(currentData, (result, error) => {\n // --- Error Handling ---\n if (error) {\n logger.error(`Error reported by processor at index ${idx}:`, error);\n this._hasErrored = true; // Set flag\n // Throw the error to be caught by outer try...catch blocks\n throw error;\n }\n // --- /Error Handling ---\n\n // If no error, proceed as before\n currentData = result;\n index = idx + 1; // Update index for the next step\n const nextStep = createStepRevised(index); // Use updated index\n\n if (isRunning) {\n // Callback was synchronous\n syncCallbackResult = nextStep; // Store next step function\n calledSync = true;\n } else {\n // Callback was asynchronous, restart trampoline\n trampoline(nextStep);\n }\n });\n } catch (error) {\n if (!this._hasErrored) { // Check flag to avoid double logging if error was from callback\n logger.error(`Error thrown by processor at index ${idx} or its callback:`, error);\n this._hasErrored = true;\n }\n // Rethrow to be caught by the trampoline's catch block\n throw error;\n }\n\n if (calledSync) {\n // Return the next step function for the sync loop\n return syncCallbackResult;\n } else {\n // Pause trampoline for async, loop will stop as step returns null\n return null;\n }\n };\n };\n\n // The trampoline loop\n const trampoline = (step: TrampolineStep<any> | null) => {\n\n if (isRunning) {\n return;\n }\n\n isRunning = true;\n let currentStep = step;\n\n while (currentStep !== null) {\n try {\n // Stop immediately if an error was flagged elsewhere\n if (this._hasErrored) {\n currentStep = null;\n break;\n }\n currentStep = currentStep(); // Execute step, get next step or null\n } catch (trampolineError) {\n // Catch errors propagated from step execution (processor or callback errors)\n if (!this._hasErrored) { // Avoid double logging\n logger.error(\"Error during trampoline step execution:\", trampolineError);\n this._hasErrored = true;\n }\n currentStep = null; // Stop the loop\n\n // Report the failure to the caller.\n //\n // This used to break without calling `done`, on the reasoning that\n // the application should handle the uncaught exception. It cannot:\n // the error is caught right here, so nothing escapes to be handled,\n // and every caller awaiting the callback waits forever. A hang is\n // strictly worse than an error — it gives the caller nothing to act\n // on and no way to time out.\n //\n // `done` runs exactly once per execution: this path returns\n // immediately, and finalStepSentinel checks `_hasErrored` before\n // reporting success, so the two are mutually exclusive.\n isRunning = false;\n done(currentData as TFinal, trampolineError);\n return;\n }\n }\n // Loop ends when currentStep is null or loop is broken by error\n isRunning = false;\n\n // Completion check is now handled by finalStepSentinel ensuring `done` isn't called on error.\n };\n\n // --- Start the process ---\n index = 0; // Reset index\n currentData = initialData; // Reset data\n trampoline(createStepRevised(0)); // Start with the revised step creator\n } catch (error: any) {\n done(currentData, error);\n }\n }\n\n pipe<TNext>(processor: Processor<TCurrent, TNext>) {\n this._list.push(processor);\n return this as unknown as TrampolinePipeline<TInitial, TNext>;\n }\n\n pipeEach(items: TCurrent[], fn: (payload: ResultType<TCurrent>, done: CallbackResult<TCurrent>) => void, map: (previous: ResultType<TCurrent>, current: ResultType<TCurrent>) => ResultType<TCurrent>) {\n for (let i = 0, length = items.length; i < length; i++) {\n\n this.pipe<ResultType<TCurrent>>((previous, done) => {\n\n fn(map(previous as ResultType<TCurrent>, Result.success(items[i])), done);\n });\n }\n }\n}\n\nexport type UnitOfWork = (done: CallbackResult<never>) => void;\n\n/**\n * Processes functions with callbacks asynchronously.\n * \n * This pipeline handles work items that contain callback functions,\n * executing them in an asynchronous manner while maintaining proper\n * flow control and error handling.\n */\nexport class WorkPipeline {\n private unitsOfWork: UnitOfWork[] = [];\n private _hasErrored: boolean = false; // Flag to prevent calling done on error\n\n filter(done: CallbackResult<never>) {\n\n this._hasErrored = false; // Reset error flag on new execution\n\n if (this.unitsOfWork.length === 0) {\n done(Result.success());\n return;\n }\n\n let index = 0;\n let isRunning = false; // Guard against overlapping trampoline calls\n\n try {\n // --- Revised Completion Logic --- (Moved up for clarity)\n const finalStepSentinel = (): StepResult<never> => { // A special step function for the very end\n // Only call done if no error has occurred\n if (!this._hasErrored) {\n done(Result.success());\n }\n return null; // Stop the trampoline\n };\n\n const createStepRevised = (idx: number): TrampolineStep<any> => {\n return () => {\n if (this._hasErrored) return null; // Stop if an error occurred elsewhere\n\n if (idx >= this.unitsOfWork.length) {\n return finalStepSentinel(); // Execute the dedicated final step\n }\n\n const processor = this.unitsOfWork[idx];\n // Initialize syncCallbackResult to null to satisfy StepResult type\n let syncCallbackResult: StepResult<any> = null;\n let calledSync = false;\n\n try {\n processor((result) => {\n // --- Error Handling ---\n if (result.ok === Result.ERROR) {\n logger.error(`Error reported by AsyncPipeline at index ${idx}:`, result.error);\n this._hasErrored = true; // Set flag\n // Throw the error to be caught by outer try...catch blocks\n throw result.error;\n }\n // --- /Error Handling ---\n\n // If no error, proceed as before\n index = idx + 1; // Update index for the next step\n const nextStep = createStepRevised(index); // Use updated index\n\n if (isRunning) {\n // Callback was synchronous\n syncCallbackResult = nextStep; // Store next step function\n calledSync = true;\n } else {\n // Callback was asynchronous, restart trampoline\n trampoline(nextStep);\n }\n });\n } catch (error) {\n if (!this._hasErrored) { // Check flag to avoid double logging if error was from callback\n logger.error(`Error thrown by processor at index ${idx} or its callback:`, error);\n this._hasErrored = true;\n }\n // Rethrow to be caught by the trampoline's catch block\n throw error;\n }\n\n if (calledSync) {\n // Return the next step function for the sync loop\n return syncCallbackResult;\n } else {\n // Pause trampoline for async, loop will stop as step returns null\n return null;\n }\n };\n };\n\n // The trampoline loop\n const trampoline = (step: TrampolineStep<any> | null) => {\n\n if (isRunning) {\n return;\n }\n\n isRunning = true;\n let currentStep = step;\n\n while (currentStep !== null) {\n try {\n // Stop immediately if an error was flagged elsewhere\n if (this._hasErrored) {\n currentStep = null;\n break;\n }\n currentStep = currentStep(); // Execute step, get next step or null\n } catch (trampolineError) {\n // Catch errors propagated from step execution (processor or callback errors)\n if (!this._hasErrored) { // Avoid double logging\n logger.error(\"Error during trampoline step execution:\", trampolineError);\n this._hasErrored = true;\n }\n currentStep = null; // Stop the loop\n\n // Report the failure to the caller. See the note on the same path in\n // TrampolinePipeline: swallowing the error here left every caller\n // awaiting `done` hanging instead of receiving a failure.\n isRunning = false;\n done(Result.error(trampolineError));\n return;\n }\n }\n // Loop ends when currentStep is null or loop is broken by error\n isRunning = false;\n\n // Completion check is now handled by finalStepSentinel ensuring `done` isn't called on error.\n };\n\n // --- Start the process ---\n index = 0; // Reset index\n trampoline(createStepRevised(0)); // Start with the revised step creator\n } catch (error: any) {\n done(Result.error(error));\n }\n }\n\n pipe(work: UnitOfWork) {\n this.unitsOfWork.push(work);\n }\n}","import { isPropertyExpression } from \"../../assertions\";\nimport { forEach } from \"../../expressions/utils\";\nimport { MemoryExecutionReason, QueryOption, QueryOptionName, QueryOptionExecutionTarget, QueryOptionValueMap } from \"./types\";\n\nexport type QueryCollectionItem<T, K extends QueryOptionName> = { index: number, option: QueryOption<T, K> };\n\nexport class QueryOptionsCollection<T> {\n\n private options: Map<QueryOptionName, QueryCollectionItem<any, any>[]> = new Map<QueryOptionName, QueryCollectionItem<any, any>[]>();\n private nextExecutionTarget: QueryOptionExecutionTarget = \"database\";\n private nextExecutionReason: MemoryExecutionReason | null = null;\n private nextIndex: number = 0;\n private enumeratedItems: QueryCollectionItem<any, any>[] = [];\n\n /** Cuts over to memory execution, keeping the first cause. See `MemoryExecutionReason`. */\n private cutOverToMemory(reason: MemoryExecutionReason) {\n this.nextExecutionTarget = \"memory\";\n\n if (this.nextExecutionReason == null) {\n this.nextExecutionReason = reason;\n }\n }\n\n /**\n * True when `split()` or `splitAt()` produced this collection.\n *\n * Those rebuild each half by re-adding its options, which re-derives execution targets\n * without the options that caused them — a post-join filter alone in the memory half\n * derives back to `\"database\"`. Anything reading `target` as a report of where work runs\n * has to reject a derived collection; see `explainQuery`.\n */\n private derived: boolean = false;\n\n get isDerived() {\n return this.derived;\n }\n\n get items() {\n return this.options;\n }\n\n get isEmpty() {\n return this.items.size === 0;\n }\n\n static EMPTY<R>() {\n return new QueryOptionsCollection<R>();\n }\n\n static isEmpty<T>(options: QueryOptionsCollection<T>) {\n return options.isEmpty;\n }\n\n add<K extends QueryOptionName>(name: K, value: QueryOption<T, K>[\"value\"]) {\n\n if (name === \"map\") {\n const mapValue = value as QueryOptionValueMap<T>[\"map\"];\n\n // Evaluate the map value to see if we are renaming properties, \n // if we are we need to perform everything after in memory\n if (mapValue.fields.some(x => x.isRename === true) || mapValue.fields.some(x => x.property?.isUnmapped === true)) {\n // Cut over to memory execution since we are renaming a property with .map\n // We do not want to figure out how the new name flows through the entire query\n this.cutOverToMemory(\"map-rename\");\n }\n }\n\n if (name === \"filter\") {\n // Need to check for unmapped and renamed properties\n const filterValue = value as QueryOptionValueMap<T>[\"filter\"];\n\n // A tautology (`x => true`) filters nothing — skip it entirely so\n // plugins never see it\n if (filterValue.expression.type === \"empty\") {\n return;\n }\n\n if (filterValue.expression.type === \"not-parsable\") {\n this.cutOverToMemory(\"not-parsable\");\n } else {\n forEach(filterValue.expression, (expression) => {\n\n if (isPropertyExpression(expression) && expression.property.isUnmapped) {\n // Cut over to memory execution, unmapped properties are not in the database and\n // cannot be queried\n this.cutOverToMemory(\"unmapped-property\");\n return false;\n }\n\n if (isPropertyExpression(expression) && expression.property.hasRenamedSegments) {\n // Cut over to memory execution: the plugin stores data under the\n // `from` (storage) names, but filter selectors reference the\n // in-memory names. Memory execution runs after deserialization,\n // where the in-memory names exist\n this.cutOverToMemory(\"renamed-property\");\n return false;\n }\n\n return true;\n });\n }\n }\n\n if (name === \"sort\") {\n const sortValue = value as QueryOptionValueMap<T>[\"sort\"];\n\n // Same rule as filters: sort selectors reference in-memory names, which\n // only exist after deserialization when the property is renamed or unmapped\n if (sortValue.property != null && sortValue.property.isUnmapped) {\n this.cutOverToMemory(\"unmapped-property\");\n } else if (sortValue.property != null && sortValue.property.hasRenamedSegments) {\n this.cutOverToMemory(\"renamed-property\");\n }\n }\n\n if (name === \"nearest\") {\n const nearestValue = value as QueryOptionValueMap<T>[\"nearest\"];\n\n // Same rule as sort, and for the same reason: the plugin stores the vector under\n // the `from` name, and an unmapped property is not stored at all. Both are only\n // readable after deserialization, which is where memory execution runs.\n //\n // This is also what lets every translator's in-memory fallback read the column by\n // its resolved name — anything whose storage name differs never reaches them.\n if (nearestValue.property != null && nearestValue.property.isUnmapped) {\n this.cutOverToMemory(\"unmapped-property\");\n } else if (nearestValue.property != null && nearestValue.property.hasRenamedSegments) {\n this.cutOverToMemory(\"renamed-property\");\n }\n }\n\n if (name === \"join\") {\n const joinValue = value as QueryOptionValueMap<T>[\"join\"];\n\n // A join whose two sides live on different plugins cannot be sent to EITHER of\n // them — neither can read the other's rows — so the option itself belongs to the\n // memory half, where the datastore interprets it.\n //\n // Set BEFORE the item is created, unlike `nearest`'s ratchet below, because this\n // moves the join option itself rather than everything after it.\n if (joinValue.crossPlugin === true) {\n this.cutOverToMemory(\"cross-plugin-join\");\n }\n }\n\n const item: QueryCollectionItem<T, K> = {\n index: this.nextIndex,\n option: {\n name,\n target: this.nextExecutionTarget,\n value,\n ...(this.nextExecutionReason == null ? {} : { reason: this.nextExecutionReason })\n }\n }\n\n this.nextIndex++;\n\n const found = this.options.get(name);\n\n this.options.set(name, [...found ?? [], item]);\n\n if (name === \"nearest\") {\n // Everything AFTER a similarity search runs in memory, whatever the backend.\n //\n // Whether the search was pushed down is a fact about the plugin, which this\n // collection cannot see — so a later option is only safe if it runs after the\n // scoring definitely happened, and in memory is the only place that is true of.\n //\n // The failure this prevents is silent. `.nearest(x => x.embedding, v, 10).take(3)`\n // sends `LIMIT 3` to a backend that ignored the ordering, so three arbitrary rows\n // come back and get scored — three real rows, in a plausible order, and not the\n // three nearest. Nothing errors.\n //\n // A plugin that DID push the search down loses nothing but the chance to also\n // push down what follows it, which is a limit over ten rows.\n this.cutOverToMemory(\"after-nearest\");\n }\n\n if (name === \"join\") {\n // Everything AFTER a join runs in memory, for the same reason as `nearest`: this\n // collection cannot see HOW the plugin executed the join, and the rows it produced\n // are TUPLES rather than entities of the root schema.\n //\n // A `take` sent to a backend that hash-joined in its translator would limit the\n // OUTER rows read, not the pairs produced — a plausible-looking result with the\n // wrong number of rows in it. Conjuncts that can safely run earlier are split off\n // by the query builder BEFORE dispatch, which is the only exception.\n this.cutOverToMemory(\"after-join\");\n }\n }\n\n /**\n * Splits the collection around the FIRST occurrence of `name`, preserving order.\n *\n * For a join: the options recorded before it operate on entity rows, the option itself\n * produces tuples, and the ones after it operate on tuples. Three different shapes, so the\n * caller has to run them in three steps rather than one pass.\n */\n splitAt<K extends QueryOptionName>(name: K): { before: QueryOptionsCollection<T>, at: QueryOption<T, K> | null, after: QueryOptionsCollection<T> } {\n this.resolveEnumeration();\n\n const sortedItems = this.enumeratedItems.toSorted((a, b) => a.index - b.index);\n const before = new QueryOptionsCollection<T>();\n const after = new QueryOptionsCollection<T>();\n\n before.derived = true;\n after.derived = true;\n let at: QueryOption<T, K> | null = null;\n\n for (let i = 0, length = sortedItems.length; i < length; i++) {\n const { option } = sortedItems[i];\n\n if (at == null && option.name === name) {\n at = option as QueryOption<T, K>;\n continue;\n }\n\n const destination = at == null ? before : after;\n destination.add(option.name, option.value);\n }\n\n return { before, at, after };\n }\n\n /**\n * Captures the collection's current state and returns a function that restores it.\n *\n * Terminal queryable operations (count, first, aggregates, …) record their option on\n * the shared collection before executing. Without restoring, a re-executed terminal —\n * the whole point of a subscribed queryable — stacks its option a second time and\n * runs it over the first execution's scalar result.\n */\n snapshot(): () => void {\n const options = new Map([...this.options.entries()].map(([key, items]): [QueryOptionName, QueryCollectionItem<any, any>[]] => [key, [...items]]));\n const nextExecutionTarget = this.nextExecutionTarget;\n const nextExecutionReason = this.nextExecutionReason;\n const nextIndex = this.nextIndex;\n\n return () => {\n this.options = new Map(options);\n this.nextExecutionTarget = nextExecutionTarget;\n this.nextExecutionReason = nextExecutionReason;\n this.nextIndex = nextIndex;\n this.enumeratedItems = [];\n };\n }\n\n split(): { memory: QueryOptionsCollection<T>, database: QueryOptionsCollection<T> } {\n this.resolveEnumeration();\n\n const sortedItems = this.enumeratedItems.toSorted((a, b) => a.index - b.index);\n const memoryQueryOptionsCollection = new QueryOptionsCollection<T>();\n const databaseQueryOptionsCollection = new QueryOptionsCollection<T>();\n\n memoryQueryOptionsCollection.derived = true;\n databaseQueryOptionsCollection.derived = true;\n\n for (let i = 0, length = sortedItems.length; i < length; i++) {\n const sortedItem = sortedItems[i];\n\n if (sortedItem.option.target === \"database\") {\n databaseQueryOptionsCollection.add(sortedItem.option.name, sortedItem.option.value);\n continue;\n }\n\n memoryQueryOptionsCollection.add(sortedItem.option.name, sortedItem.option.value);\n }\n\n return {\n memory: memoryQueryOptionsCollection,\n database: databaseQueryOptionsCollection\n }\n }\n\n hasTransformations(): boolean {\n const transformationOptions: QueryOptionName[] = [\"map\", \"group\", \"min\", \"max\", \"count\", \"sum\"];\n return transformationOptions.some((name) => this.options.has(name));\n }\n\n has<K extends QueryOptionName>(name: K): boolean {\n return this.options.has(name);\n }\n\n get<K extends QueryOptionName>(name: K): QueryCollectionItem<T, K>[] {\n return this.options.get(name) ?? [] as QueryCollectionItem<T, K>[];\n }\n\n getLast<K extends QueryOptionName>(name: K): QueryOption<T, K> | null {\n this.resolveEnumeration();\n\n for (let i = this.enumeratedItems.length - 1; i >= 0; i--) {\n const item = this.enumeratedItems[i];\n\n if (item.option.name === name) {\n return item.option;\n }\n }\n\n return null\n }\n\n getValues<K extends QueryOptionName>(name: K): QueryCollectionItem<T, K>[\"option\"][\"value\"][] | undefined {\n\n const found = this.options.get(name);\n\n if (found == null) {\n return [];\n }\n\n return found.map(w => w.option.value) as QueryCollectionItem<T, K>[\"option\"][\"value\"][];\n }\n\n private getEnumeration() {\n return [...this.options.values()].flat().toSorted((a, b) => a.index - b.index);\n }\n\n private resolveEnumeration() {\n if (this.enumeratedItems.length != this.nextIndex) {\n this.enumeratedItems = this.getEnumeration();\n }\n }\n\n forEach(iterator: (item: QueryCollectionItem<T, any>[\"option\"]) => void) {\n this.resolveEnumeration();\n\n for (let i = 0, length = this.enumeratedItems.length; i < length; i++) {\n iterator(this.enumeratedItems[i].option);\n }\n }\n}","import { PartialResultType, PluginEventPartialResultType, PluginEventResultType, ResultType } from \"./types\";\n\nabstract class BaseResult {\n static ERROR = \"error\" as const;\n static SUCCESS = \"success\" as const;\n static PARTIAL = \"partial\" as const;\n\n static resolve<T>(result: ResultType<T> | PartialResultType<T>, resolve: (data: T) => void, reject: (error?: any) => void) {\n if (result.ok === BaseResult.SUCCESS) {\n resolve(result.data);\n return;\n }\n\n if (result.ok === BaseResult.PARTIAL) {\n reject({\n partial: result.data,\n error: result.error\n });\n return;\n }\n\n reject(result.error);\n }\n\n static assertSuccess<T>(result: any): asserts result is { ok: \"success\"; data: T } {\n if (result.ok !== BaseResult.SUCCESS) {\n throw new Error(`Expected success result, but got ${result.ok}: ${result.error}`);\n }\n }\n}\n\nexport class Result extends BaseResult {\n static success<T>(data: T): ResultType<T>;\n static success(): ResultType<never>;\n static success<T>(data?: T): ResultType<T> {\n return {\n ok: Result.SUCCESS,\n data\n }\n }\n\n static error<T>(error: any): ResultType<T> {\n return {\n ok: Result.ERROR,\n error\n }\n }\n\n static partial<T>(data: T, error: any): PartialResultType<T> {\n return {\n ok: Result.PARTIAL,\n data,\n error\n }\n }\n}\n\nexport class PluginEventResult extends BaseResult {\n static success<T>(id: string, data: T): PluginEventResultType<T>;\n static success(id: string): PluginEventResultType<never>;\n static success<T>(id: string, data?: T): PluginEventResultType<T> {\n return {\n id,\n ok: Result.SUCCESS,\n data\n }\n }\n\n static error<T>(id: string, error: any): PluginEventResultType<T> {\n return {\n id,\n ok: Result.ERROR,\n error\n }\n }\n\n static partial<T>(id: string, data: T, error: any): PluginEventPartialResultType<T> {\n return {\n id,\n ok: Result.PARTIAL,\n data,\n error\n }\n }\n\n static assertSuccess<T>(result: PluginEventResultType<T>): asserts result is { ok: \"success\"; data: T; id: string } {\n if (result.ok !== Result.SUCCESS) {\n throw new Error(`Expected success result, but got ${result.ok}: ${result.error}`);\n }\n }\n}\n","import type { SchemaDefinition } from \"./SchemaDefinition\";\nimport type { SchemaBase } from \"./property/base/SchemaBase\";\nimport type { SchemaArray } from \"./property/types/SchemaArray\";\nimport type { SchemaVector } from \"./property/types/SchemaVector\";\nimport type { SchemaObject } from \"./property/types/SchemaObject\";\nimport type { PropertyInfo } from \"./PropertyInfo\";\nimport type { DeepPartial } from \"../types\";\nimport type { SchemaFunction } from \"./table\";\nimport type { SchemaOptional, SchemaTag } from \"./property/modifiers\";\nimport type { Branded } from \"../utilities/types\";\nimport type { SchemaSubscriptionOptions } from \"./communication/broadcast\";\n\nexport type DefaultValue<T, I = never> = T | ((injected: I) => T);\nexport type FunctionBody<TEntity, TResult> = (entity: TEntity, collectionName: CollectionName) => TResult;\nexport type IdType = string | number;\nexport type ForeignKey<T extends {}> = { \n schema: CompiledSchema<T>, \n property: PropertyInfo<T> \n};\n\nexport enum SchemaTypes {\n Array = \"Array\",\n Boolean = \"Boolean\",\n Date = \"Date\",\n Number = \"Number\",\n Object = \"Object\",\n String = \"String\",\n Definition = \"Definition\",\n Function = \"Function\",\n Computed = \"Computed\",\n /**\n * Content in, reference out. The only type whose write shape differs from its stored\n * shape, and a leaf on purpose — see `SchemaFile`.\n */\n File = \"File\",\n /**\n * A fixed-length list of numbers, carrying its dimension count — see `SchemaVector`.\n *\n * Value-shaped exactly like `s.array(s.number())`, which is why every array codegen\n * handler accepts it. It is a distinct type only so a backend can recognise it and store\n * it natively; nothing else needs to tell the two apart.\n */\n Vector = \"Vector\"\n}\n\nexport type ArrayShape = string | number | Date | {};\n\n\n/**\n * What a file property gives back: where the bytes are and what they are.\n *\n * Declared in core so `InferType` can name it. Core never reads or writes the bytes — it only\n * carries this shape — and `@routier/blob-plugin` is what puts one here.\n */\nexport type FileReferenceValue = {\n /** Where the bytes live, content-addressed by the blob plugin. */\n key: string;\n /** Byte length. */\n size: number;\n /** Media type as supplied at upload. */\n contentType: string;\n /** SHA-256 of the bytes, lowercase hex. */\n checksum: string;\n /** The name to show a user. Not part of the key. */\n fileName: string;\n};\n\n/**\n * What a file property ACCEPTS: content, or a reference you already have.\n *\n * `Blob` covers `File`, which is what an `<input type=\"file\">` yields. A reference is accepted\n * too, so re-saving an entity that was read from the database does not have to re-upload it.\n */\nexport type FileContentValue =\n | FileReferenceValue\n | Uint8Array\n | ArrayBuffer\n | Blob\n | string;\n\n/**\n * What a vector property holds, in and out: a plain list of numbers.\n *\n * Named rather than written inline because the inference rules have to recognise it after a\n * modifier has erased which class produced it — the same problem `FileReferenceValue` solves\n * above, and for the same reason.\n */\nexport type VectorValue = number[];\n\n/**\n * What `s.string({ ... })` accepts.\n *\n * Declarations only. Core stores them and never acts on them; a backend that can use one does.\n */\nexport type StringOptions = {\n /**\n * The longest value the property is declared to hold.\n *\n * MySQL uses it for `VARCHAR(maxLength)`; without it every string column is\n * `VARCHAR(255)`, which silently truncates longer values. Other backends ignore it. Core\n * never validates a value against it — see `SchemaBase.maxLength`.\n */\n maxLength?: number;\n};\n\nexport type ExpandedProperty = ExpandedChildProperty & {\n assignmentPath: string;\n selectorPath: string;\n properties: Map<string, ExpandedChildProperty>;\n childDegree: number;\n};\n\nexport type ExpandedChildProperty = {\n propertyName: string;\n type: SchemaTypes;\n isNullableOrOptional: boolean;\n isReadonly: boolean;\n isIdentity: boolean;\n isUnmapped: boolean;\n}\n\nexport enum HashType {\n Ids = \"Ids\",\n Object = \"Object\"\n}\n\nexport type HashFunction<TEntity extends {}> = {\n (entity: InferCreateType<TEntity>, type: HashType.Object): string;\n (entity: InferType<TEntity>, type: HashType.Ids): string;\n}\n\nexport type GetHashTypeFunction<TEntity extends {}> = {\n (entity: InferCreateType<TEntity>): HashType.Object;\n (entity: InferType<TEntity>): HashType.Ids;\n}\n\nexport type ChangeTrackingType = \"proxy\" | \"diff\" | \"immutable\";\n\nexport type IndexType = \"single\" | \"compound\" | \"unique\" | \"primary-key\"\nexport type Index = {\n properties: PropertyInfo<any>[],\n type: IndexType;\n name: string;\n}\n\n/**\n * Represents changes to subscriptions, categorizing them by modifications to\n * entities (additions, updates, removals) or query-driven removals.\n * @template T - The type of the entities in the subscription.\n */\nexport type SubscriptionChanges<T extends {}> = {\n /**\n * Entities that have been added to the subscription.\n */\n adds: InferType<T>[];\n /**\n * Entities that have been updated within the subscription.\n */\n updates: InferType<T>[];\n /**\n * Entities that have been removed from the subscription.\n */\n removals: InferType<T>[];\n /**\n * Entities that have been added/updated/removed from the subscription and it is unknown \n * if the entities have been added/updated/removed.\n */\n unknown: InferType<T>[];\n}\n\nexport interface ISchemaSubscription<T extends {}> extends Disposable {\n send(changes: SubscriptionChanges<T>): void;\n onMessage(callback: (changes: SubscriptionChanges<T>) => void): void;\n}\n\nexport type Enrich<TEntity extends {}> = {\n (entity: InferType<TEntity>, changeTrackingType: ChangeTrackingType): InferType<TEntity>;\n (entity: InferCreateType<TEntity>, changeTrackingType: ChangeTrackingType): InferCreateType<TEntity>;\n}\nexport type Prepare<TEntity extends {}> = {\n (entity: InferCreateType<TEntity>): InferCreateType<TEntity>;\n (entity: InferType<TEntity>): InferType<TEntity>;\n}\nexport type Preprocess<TEntity extends {}> = {\n (entity: InferCreateType<TEntity>): InferType<TEntity>;\n (entity: InferType<TEntity>): InferType<TEntity>;\n}\n\nexport type SetProperties<TEntity extends {}> = (destination: DeepPartial<InferType<TEntity> | InferCreateType<TEntity>>, source: DeepPartial<InferType<TEntity> | InferCreateType<TEntity>>) => void;\n\nexport type CompiledSchemaCore<TEntity extends {}> = Omit<CompiledSchema<TEntity>, \"createSubscription\">;\n\nexport type CompiledSchemaWithMetadata<TEntity extends {}, TMetadata> = {\n readonly metadata: TMetadata;\n} & CompiledSchema<TEntity>;\n\n/**\n * Represents a fully compiled schema with all utilities and metadata for an entity type.\n */\nexport type CompiledSchema<TEntity extends {}> = {\n\n deserializePartial: (item: Record<string, unknown>, properties: PropertyInfo<TEntity>[]) => DeepPartial<InferType<TEntity>>;\n\n createSubscription: (abortSignal?: AbortSignal, scope?: string, options?: SchemaSubscriptionOptions) => ISchemaSubscription<TEntity>;\n /** Returns the property info for a given id (full path) */\n getProperty: (id: string) => PropertyInfo<TEntity>;\n /** Returns the ID of the given entity. */\n getId: (entity: InferType<TEntity>) => IdType;\n /** Returns a deep clone of the given entity. */\n clone: (entity: InferType<TEntity>) => InferType<TEntity>;\n /**\n * Returns a deep clone of a record that is still in the STORAGE shape — renamed properties\n * under their `from` names rather than their in-memory names.\n *\n * `clone` reads in-memory names, so it returns `undefined` for every renamed property of a\n * stored record. Use this when copying rows a store holds before they have been deserialized.\n * Generated on first call; schemas that are never cloned in storage shape never build it.\n */\n cloneStorage: (entity: InferType<TEntity>) => InferType<TEntity>;\n /** Removes unmapped or extraneous properties from the entity. */\n strip: (entity: InferType<TEntity>) => InferType<TEntity>;\n /** Prepares a new entity for creation, applying defaults and transformations. */\n prepare: Prepare<TEntity>;\n /** Merges the source entity into the destination entity. */\n merge: (destination: InferType<TEntity> | InferCreateType<TEntity>, source: InferType<TEntity>) => InferType<TEntity>;\n /** Indicates if the schema has identity properties. */\n hasIdentities: boolean;\n /** List of properties that are identity keys. */\n idProperties: PropertyInfo<TEntity>[];\n /** All property metadata for the schema. */\n properties: PropertyInfo<TEntity>[],\n /** The hash type used for this schema. */\n hashType: HashType;\n /** Computes a hash for the given entity. */\n hash: HashFunction<TEntity>;\n /** Returns the hash type for the given entity. */\n getHashType: GetHashTypeFunction<TEntity>;\n /** Compares two entities for equality. */\n compare: (a: InferType<TEntity>, fromDb: InferType<TEntity>) => boolean;\n /** Deserializes an entity from storage format. */\n deserialize: (entity: InferType<TEntity>) => InferType<TEntity>;\n /** Sets 1 or many properties from the source object onto the destination object with change tracking. */\n set: SetProperties<TEntity>;\n /** Combines serializing and preparing an entity for saving. */\n preprocess: Preprocess<TEntity>;\n /** Combines deserializing and enriching an entity for selection. */\n postprocess: Enrich<TEntity>;\n\n /** Serializes an entity to storage format. */\n serialize: (entity: InferType<TEntity>) => InferType<TEntity>;\n /** Unique id for the schema. */\n id: SchemaId,\n /** The name of the collection for this schema. */\n collectionName: CollectionName;\n /** Returns all IDs for the given entity (usually a single-element tuple). */\n getIds: (entity: InferType<TEntity>) => [IdType];\n /** Enriches the entity with change tracking or other metadata. */\n enrich: Enrich<TEntity>;\n /** Indicates if the schema has identity keys. */\n hasIdentityKeys: boolean;\n /** Returns a deeply frozen (immutable) version of the entity. */\n freeze: (entity: InferType<TEntity>) => InferType<TEntity>;\n /** Enables change tracking on the entity. */\n enableChangeTracking: (entity: InferType<TEntity>) => InferType<TEntity>;\n /** The schema definition object. */\n definition: SchemaDefinition<TEntity>;\n /** Returns all indexes defined for this schema. */\n getIndexes: () => Index[];\n /** Compares two entities for Id equality. */\n compareIds: (a: InferType<TEntity>, b: InferType<TEntity>) => boolean;\n}\n\nexport type PropertySerializer<T extends any> = (value: T) => string | number;\nexport type PropertyDeserializer<T extends any> = (value: string | number) => T;\n\n/**\n * A two-way transform between the application value and the stored value.\n *\n * Both directions may be async. Held as a live reference rather than stringified, so a\n * closure works and `injected` is a convenience rather than the only way in.\n */\nexport type PropertyTransform<T extends any> = {\n /**\n * Application value to stored value. Runs before the plugin sees it. May be async.\n *\n * `entity` is there for the one-way case: a transform with no `from` derives a value\n * rather than converting one, which is what `computed` does.\n */\n to: (value: T, entity: Record<string, unknown>) => unknown | Promise<unknown>;\n\n /**\n * Stored value back to application value. Runs after the plugin returns it.\n *\n * Optional. Leave it out and the transform is one-way: the stored value is the value.\n */\n from?: (value: unknown) => T | Promise<T>;\n\n /**\n * What the column becomes, when the stored form is not the property's own type.\n *\n * Defaults to the property's own type, so nothing changes unless you say it does. A\n * library that always produces text — a cipher, a compressor — sets this once, and the\n * caller who uses that library never writes it.\n */\n stores?: SchemaTypes;\n\n /**\n * Whether a filter on this property can still run in the database.\n *\n * Defaults to `none`, which rejects the filter rather than returning wrong rows. Set\n * `equality` only when `to` is deterministic.\n */\n comparable?: 'equality' | 'none';\n};\n\nexport type SchemaId = Branded<number, \"SchemaId\">;\nexport type CollectionName = Branded<string, \"CollectionName\">;\n\nexport type SchemaModifiers = \"default\" | \"deserialize\" |\n \"identity\" | \"key\" |\n \"nullable\" | \"optional\" |\n \"readonly\" | \"serialize\" |\n \"unmapped\" | \"computed\" |\n \"distinct\" | \"searchable\";\n\n/**\n * What a tagged property infers to.\n *\n * `tag()` is metadata and must not change a type, but `SchemaTag<T>` carries the same `T` as\n * whatever it wrapped without carrying which class that was. For a string `T` is already\n * `string`; for an object `T` is the map of child schemas, which only the `SchemaObject`\n * branch below knows how to unwrap. Falling through to the generic `SchemaBase` branch\n * therefore handed the raw map back, so `s.object({ key: s.string() }).tag('x')` typed\n * `key` as `SchemaString` instead of `string` — everything ran, and only the types lied.\n *\n * An array is distinguishable because `SchemaArray`'s parameter is the ELEMENT schema, so a\n * tagged array arrives here as a `SchemaBase` rather than a plain map.\n */\ntype InferTagged<C> = ResolveWrapped<C>;\n\n/**\n * What a wrapping modifier's inner type resolves to.\n *\n * `SchemaOptional`, `SchemaNullable` and `SchemaTag` all carry the same `C` as whatever they\n * wrapped, without carrying which class that was, so each has to work out what it is holding.\n * Three shapes are possible:\n *\n * - an already-resolved value (`string` from `s.string()`, a file reference from `s.file()`)\n * - an ELEMENT schema, which is what `SchemaArray` parameterises on\n * - a map of child schemas, which is what `SchemaObject` parameterises on\n *\n * Getting this wrong is silent. The map branch applied to an already-resolved object walks\n * its keys and infers `never` for each, so `s.file().optional()` typed as\n * `{ key: never, size: never, ... }` — which no value can satisfy and no test would catch at\n * runtime.\n */\ntype ResolveWrapped<C> =\n C extends string | number | boolean | Date | FileReferenceValue ? C :\n C extends VectorValue ? C :\n C extends SchemaBase<any, any> ? InferPrimitive<C>[] :\n { [K in keyof C]: InferPrimitive<C[K]> };\n\ntype InferPrimitive<T> =\n T extends SchemaOptional<infer C, infer __> ? ResolveWrapped<C> :\n T extends SchemaTag<infer C, infer __> ? InferTagged<C> :\n // Before the generic `SchemaBase` branch below, which would see `X = number[]` and map\n // the element through `InferPrimitive<number>` — no branch matches a bare `number`, so a\n // vector would type as `never[]`: assignable from nothing, and invisible at runtime.\n T extends SchemaVector<infer __, infer ___> ? VectorValue :\n T extends SchemaArray<infer Y, infer __> ? InferPrimitive<Y>[]\n : T extends SchemaObject<infer Obj, infer _> ?\n { [K in keyof Obj]: InferPrimitive<Obj[K]> } : // Process nested objects\n T extends SchemaFunction<infer F, infer __> ? F : T extends SchemaBase<infer X, infer _> ?\n X extends Array<infer A> ? InferPrimitive<A>[] : X : // Extract the primitive type\n never;\n\nexport type InferType<T> = T extends CompiledSchema<infer R> ? InferCompiledSchema<R> : T extends {} ? InferCompiledSchema<T> : T;\nexport type InferCreateType<T> = T extends CompiledSchema<infer R> ? InferCompiledCreateSchema<R> : T extends {} ? InferCompiledCreateSchema<T> : unknown;\nexport type InferMappedType<T> = T extends SchemaBase<infer K, infer __> ? InferType<K> : InferCompiledSchema<T>;\nexport type InferRoot<T> = T extends CompiledSchema<infer R> ? R : never;\n\ntype HasModifier<T, K extends keyof T, M extends SchemaModifiers> =\n T[K] extends SchemaBase<any, infer Mods> ?\n M extends Mods ? true : false :\n false;\n\ntype IsPlainProperty<T, K extends keyof T> =\n [\n HasModifier<T, K, \"readonly\">,\n HasModifier<T, K, \"optional\">,\n HasModifier<T, K, \"nullable\">\n ] extends [\n false,\n false,\n false\n ] ? true : false;\n\ntype IsCreateExcluded<T, K extends keyof T> =\n [\n HasModifier<T, K, \"identity\">,\n HasModifier<T, K, \"computed\">,\n HasModifier<T, K, \"unmapped\">\n ] extends [\n false,\n false,\n false\n ] ? false : true;\n\ntype IsCreateOptional<T, K extends keyof T> =\n [\n HasModifier<T, K, \"optional\">,\n HasModifier<T, K, \"default\">\n ] extends [\n false,\n false\n ] ? false : true;\n\ntype IsCreateNullable<T, K extends keyof T> =\n HasModifier<T, K, \"nullable\"> extends true ? true : false;\n\n/**\n * What a property ACCEPTS on the way in, which is not always what it gives back.\n *\n * Only a file differs today: you assign content and read a reference. Matching on the read\n * type rather than on `SchemaFile` itself is deliberate — it keeps working through every\n * modifier. `s.file().optional()` is a `SchemaOptional`, `s.file().tag('x')` is a\n * `SchemaTag`, and neither carries the original class, so a check against the class alone\n * would silently stop accepting content the moment anyone added a modifier.\n *\n * Assignability is required in BOTH directions, and the tuple wrappers are load-bearing.\n * One-way `extends` matches `never` — which is assignable to everything — so a generic\n * property over `Record<string, unknown>` resolved to file content and broke the Dexie\n * plugin's types. It also matched any object that merely happens to have these five fields\n * plus more. Mutual assignability admits the reference shape and nothing else, and the\n * tuples stop the conditional distributing over a union.\n */\ntype InferWritePrimitive<T> =\n [InferPrimitive<T>] extends [FileReferenceValue]\n ? [FileReferenceValue] extends [InferPrimitive<T>] ? FileContentValue : InferPrimitive<T>\n : InferPrimitive<T>;\n\ntype InferCreateProperty<T, K extends keyof T> =\n IsCreateNullable<T, K> extends true ? null | InferWritePrimitive<T[K]> : InferWritePrimitive<T[K]>;\n\ntype InferCompiledSchema<T> = CoalesceEmpty<{\n [K in keyof T as IsPlainProperty<T, K> extends true ? K : never]: InferPrimitive<T[K]>\n}, {\n readonly [K in keyof T as HasModifier<T, K, \"readonly\"> extends true ? K : never]: InferPrimitive<T[K]>\n }, {\n [K in keyof T as HasModifier<T, K, \"optional\"> extends true ? K : never]?: InferPrimitive<T[K]>\n }, {\n [K in keyof T as HasModifier<T, K, \"nullable\"> extends true ? K : never]: null | InferPrimitive<T[K]>\n}>;\n\ntype InferCompiledCreateSchema<T> = {\n [K in keyof T as IsCreateExcluded<T, K> extends true ? never\n : IsCreateOptional<T, K> extends true ? K : never]?: InferCreateProperty<T, K>\n} & {\n [K in keyof T as IsCreateExcluded<T, K> extends true ? never\n : IsCreateOptional<T, K> extends true ? never : K]: InferCreateProperty<T, K>\n};\n\ntype IsEmptyObject<T> = keyof T extends never ? true : false;\ntype CoalesceEmpty<T1 extends {}, T2 extends {}, T3 extends {}, T4 extends {}> = (IsEmptyObject<T1> extends true ? {} : T1) & (IsEmptyObject<T2> extends true ? {} : T2) & (IsEmptyObject<T3> extends true ? {} : T3) & (IsEmptyObject<T4> extends true ? {} : T4);\n","export const isDate = (data: unknown): data is Date => {\n if (data == null) {\n return false;\n }\n\n if (typeof data !== \"object\") {\n return false;\n }\n\n return data instanceof Date;\n}","/**\n * Levelled logging, resolved once.\n *\n * Three things about the previous implementation drove this shape:\n *\n * - **There was no way to turn logging off.** `globalThis.__ROUTIER_DEBUG__` was only ever\n * compared against `true`, so setting it to `false` did nothing — while\n * `docs/how-to/debug-logging.md` documented exactly that as the way to force logging off.\n * A documented switch that silently does nothing is worse than no switch.\n * - **`NODE_ENV === 'test'` enabled it.** Every Jest run therefore logged, because Jest always\n * sets `NODE_ENV=test`. Measured on the S7 stress scenario, which drives ~2,000 saves through\n * a plugin that logs three lines per query: 12.4s with logging, ~6s without. Test runners also\n * capture console output by snapshotting a stack trace per call, so the cost is far above what\n * writing to a terminal would suggest — and the output buries whatever the failure was.\n * - **It was all-or-nothing, and re-resolved per call.** An error could not be kept while debug\n * was dropped, and every one of the ~97 call sites re-read `globalThis` and `process.env`.\n *\n * Levels are compared numerically against a value cached at module load. Measured against a\n * no-op console at 200k calls: an enabled call costs ~70ns, a call rejected by the gate ~3ns.\n * Building the arguments the call site passes in accounts for ~0.2ns of that 3ns, which is why\n * this keeps the ordinary `logger.debug(msg, payload)` signature instead of taking a thunk —\n * a lazy API would recover 0.3% of an enabled call's cost and would have to change every call\n * site to do it.\n */\n\n/** Ordered from most severe to most verbose. `silent` discards everything. */\nexport const LOG_LEVELS = ['silent', 'error', 'warn', 'info', 'debug'] as const;\n\nexport type LogLevel = (typeof LOG_LEVELS)[number];\n\n/** Numeric rank, so a gate is one integer comparison. */\nconst RANK: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n};\n\nconst isLogLevel = (value: unknown): value is LogLevel =>\n typeof value === 'string' && (LOG_LEVELS as readonly string[]).includes(value);\n\n/**\n * Resolves the configured level, in precedence order.\n *\n * Ordered most specific first: an explicit level beats a boolean flag, a boolean flag beats an\n * environment variable, and an environment variable beats an inference from `NODE_ENV`. Anything\n * unrecognised is ignored rather than treated as an error — a typo'd level should not take down\n * an application, and `silent` is the safe direction to fall back to.\n */\nconst resolveLevel = (): LogLevel => {\n if (typeof globalThis !== 'undefined') {\n const g = globalThis as { __ROUTIER_LOG_LEVEL__?: unknown; __ROUTIER_DEBUG__?: unknown };\n\n if (isLogLevel(g.__ROUTIER_LOG_LEVEL__)) {\n return g.__ROUTIER_LOG_LEVEL__;\n }\n\n // Both directions honoured. `=== false` used to fall through to the NODE_ENV checks\n // below and re-enable the logging it was asked to suppress.\n if (g.__ROUTIER_DEBUG__ === true) return 'debug';\n if (g.__ROUTIER_DEBUG__ === false) return 'silent';\n }\n\n // There is deliberately no `import.meta.env` branch, although the documentation used to\n // promise one. It could never work: this package is bundled with rspack, which replaces\n // `import.meta` with `undefined`, so the check would read the *library's* build-time\n // environment rather than the application's — and referencing `import.meta` at all is a parse\n // error under a CommonJS build target, which is how the test suite loads this file. Vite and\n // similar apps set `__ROUTIER_LOG_LEVEL__` or `__ROUTIER_DEBUG__` from their own\n // `import.meta.env`, which is what the docs now describe.\n if (typeof process !== 'undefined' && process.env != null) {\n if (isLogLevel(process.env.ROUTIER_LOG_LEVEL)) {\n return process.env.ROUTIER_LOG_LEVEL as LogLevel;\n }\n\n const debug = process.env.DEBUG;\n if (debug === 'routier' || debug === '*') return 'debug';\n\n const env = process.env.NODE_ENV?.toLowerCase();\n\n // `test` is deliberately absent. It used to be here, which meant no test suite anywhere\n // could run Routier quietly. Opt in with DEBUG=routier or ROUTIER_LOG_LEVEL when a test\n // needs the output.\n if (env === 'dev' || env === 'development') return 'debug';\n }\n\n return 'silent';\n};\n\nlet level: LogLevel = resolveLevel();\nlet rank = RANK[level];\n\n/**\n * Overrides the level for the rest of the process.\n *\n * The configuration above is read once, at import, which is what makes the gate cheap — but it\n * also means an application that decides its verbosity after startup, or a test that wants to\n * assert on output, has no way in. This is that way in.\n */\nexport const setLogLevel = (next: LogLevel): void => {\n if (isLogLevel(next) === false) {\n throw new Error(`Unknown log level \"${next}\". Expected one of: ${LOG_LEVELS.join(', ')}`);\n }\n\n level = next;\n rank = RANK[next];\n};\n\nexport const getLogLevel = (): LogLevel => level;\n\n/** Re-reads the environment. For tests that change it after this module was imported. */\nexport const resetLogLevel = (): void => {\n level = resolveLevel();\n rank = RANK[level];\n};\n\n/**\n * Whether a message at this level would be emitted.\n *\n * For the rare call site whose *arguments* are expensive to build — a serialization, a deep\n * clone, a join over a large collection. An ordinary payload object is not worth guarding; see\n * the measurement in the header.\n */\nexport const isLogLevelEnabled = (at: LogLevel): boolean => rank >= RANK[at];\n\ntype ConsoleMethod = 'log' | 'info' | 'warn' | 'error' | 'debug' | 'table';\n\nconst emit = (at: LogLevel, method: ConsoleMethod, args: unknown[]) => {\n if (rank < RANK[at]) {\n return;\n }\n\n // Resolved at call time rather than captured once: test harnesses and browser devtools both\n // replace console methods after modules have loaded, and a captured reference would keep\n // writing past the replacement.\n (console[method] as (...a: unknown[]) => void)(...args);\n};\n\nexport const logger = {\n /** General-purpose output. Carried at `info`, since `log` names a console method, not a level. */\n log: (...args: unknown[]): void => emit('info', 'log', args),\n info: (...args: unknown[]): void => emit('info', 'info', args),\n warn: (...args: unknown[]): void => emit('warn', 'warn', args),\n error: (...args: unknown[]): void => emit('error', 'error', args),\n debug: (...args: unknown[]): void => emit('debug', 'debug', args),\n /** Diagnostic tabular output; verbose by nature, so it sits at `debug`. */\n table: (...args: unknown[]): void => emit('debug', 'table', args),\n};\n","export const uuid = (length: number = 16): string => {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n const charLength = chars.length;\n let result = '';\n\n for (let i = 0; i < length; i++) {\n result += chars[Math.random() * charLength | 0];\n }\n return result;\n}\n\nconst HEX_CHARS = '0123456789abcdef';\nconst UUID_TEMPLATE = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';\n\nconst hasCrypto =\n typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function';\n\nconst hasRandomUUID =\n typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function';\n\nexport const uuidv4 = (): string => {\n if (hasRandomUUID) {\n return crypto.randomUUID();\n }\n\n return uuidv4Fallback();\n};\n\nconst uuidv4Fallback = (): string => {\n let randomBytes: Uint8Array | null = null;\n if (hasCrypto) {\n randomBytes = crypto.getRandomValues(new Uint8Array(16));\n }\n\n let byteIndex = 0;\n let uuid = '';\n\n for (let i = 0; i < UUID_TEMPLATE.length; i++) {\n const c = UUID_TEMPLATE[i];\n if (c === '-') {\n uuid += '-';\n continue;\n }\n\n let r: number;\n if (hasCrypto && randomBytes) {\n // Each byte gives two hex digits (nibbles)\n r =\n (i % 2 === 0\n ? randomBytes[byteIndex] >> 4\n : randomBytes[byteIndex++] & 0x0f);\n } else {\n r = Math.floor(Math.random() * 16);\n }\n\n if (c === 'x') {\n uuid += HEX_CHARS[r];\n } else if (c === 'y') {\n // Variant bits: 8, 9, A, or B\n uuid += HEX_CHARS[(r & 0x3) | 0x8];\n } else if (c === '4') {\n uuid += '4';\n }\n }\n\n return uuid;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { PropertyInfo } from '../schema/PropertyInfo';\nimport type { QueryField } from './query/types';\n\n/**\n * What a statement or command RETURNS, described before it runs.\n *\n * A plugin's builder knows this and nothing else knows it: the shape of a result comes from the\n * projection, the join aliases, or the `RETURNING` list, none of which survive into the SQL as\n * anything a reader could recover. So the builder states it, once, beside the statement it built.\n *\n * Deliberately says nothing about what anyone does with the result. It is a description, not an\n * instruction — the same description serves a driver that transfers rows across a worker\n * boundary, one that hands them straight back, and one that only wants to know the column order.\n * A consumer that needs more turns this into whatever it needs: `buildTransferPlan` in\n * `@routier/core/transfer` is one such consumer, and it is not privileged.\n */\nexport type ResultColumn = {\n /** Exact name the engine will return, including any projection or join alias. */\n readonly name: string;\n /**\n * The schema property behind the column, or `null`.\n *\n * `null` for an expression — a computed value, an aggregate, anything with no declared type\n * to reason from. A consumer that wants to treat the value specially needs the property; one\n * that only wants names does not.\n */\n readonly property: PropertyInfo<any> | null;\n};\n\n/**\n * The columns a `map` projection selects.\n *\n * Named by `sourceName`, which is what the statement actually emits; the rename to\n * `destinationName` happens in the translator, after the rows come back. A field with no\n * `property` is an expression.\n */\nexport const mappedResultColumns = (fields: readonly QueryField[]): ResultColumn[] =>\n fields.map(field => ({\n name: field.sourceName,\n property: (field.property as PropertyInfo<any> | undefined) ?? null,\n }));\n","import { ITranslatedValue } from './types';\n\nexport class TranslatedArrayValue<T> implements ITranslatedValue<T> {\n\n readonly value: T;\n readonly isTransformed: boolean;\n readonly isEmpty: boolean;\n\n constructor(value: unknown, isTransformed: boolean) {\n this.value = value as T;\n this.isEmpty = value == null || (Array.isArray(value) && value.length === 0);\n this.isTransformed = isTransformed;\n }\n\n forEach(callback: (item: unknown) => unknown): void {\n const data = this.value as unknown[];\n for (let i = 0, length = data.length; i < length; i++) {\n const result = callback(data[i]);\n\n if (result) {\n // reassign if the callback returns a result\n data[i] = result;\n }\n }\n }\n}","import { ITranslatedValue } from './types';\n\nexport class TranslatedGroupValue<T> implements ITranslatedValue<T> {\n\n readonly value: T;\n readonly isTransformed: boolean;\n readonly isEmpty: boolean;\n\n constructor(value: unknown, isTransformed: boolean) {\n this.value = value as T;\n this.isEmpty = value == null;\n this.isTransformed = isTransformed;\n }\n\n forEach(callback: (item: unknown) => unknown): void {\n const group = this.value as Record<string, unknown[]>;\n const keys = Object.keys(group);\n for (let i = 0, length = keys.length; i < length; i++) {\n const key = keys[i];\n const data = group[key];\n\n for (let j = 0, len = data.length; j < len; j++) {\n\n const result = callback(data[j]);\n\n if (result) {\n // reassign if the callback returns a result\n data[j] = result;\n }\n }\n }\n }\n}","import { ITranslatedValue } from './types';\n\nexport class TranslatedSingleValue<T> implements ITranslatedValue<T> {\n\n value: T;\n readonly isTransformed: boolean;\n readonly isEmpty: boolean;\n\n constructor(value: unknown, isTransformed: boolean) {\n this.value = value as T;\n this.isEmpty = value == null;\n this.isTransformed = isTransformed;\n }\n\n forEach(callback: (item: unknown) => unknown): void {\n const result = callback(this.value) as T;\n\n if (result) {\n this.value = result;\n }\n }\n}","import { QueryOption, QueryOptionName } from \"../query/types\";\nimport { IQuery } from \"../types\";\nimport { TranslatedArrayValue } from \"./TranslatedArrayValue\";\nimport { TranslatedGroupValue } from \"./TranslatedGroupValue\";\nimport { TranslatedSingleValue } from \"./TranslatedSingleValue\";\nimport { ITranslatedValue } from \"./types\";\n\nexport abstract class DataTranslator<TRoot extends {}, TShape> {\n\n protected query: IQuery<TRoot, TShape>;\n private functionMap: Record<QueryOptionName, (data: unknown, option: QueryOption<any, any>) => TShape> = {\n count: (data: unknown, option: QueryOption<TShape, \"count\">) => this.count<any>(data, option),\n distinct: (data: unknown, option: QueryOption<TShape, \"distinct\">) => this.distinct(data, option),\n filter: (data: unknown, option: QueryOption<TShape, \"filter\">) => this.filter(data, option),\n map: (data: unknown, option: QueryOption<TShape, \"map\">) => this.map(data, option),\n max: (data: unknown, option: QueryOption<TShape, \"max\">) => this.max<any>(data, option),\n min: (data: unknown, option: QueryOption<TShape, \"min\">) => this.min<any>(data, option),\n skip: (data: unknown, option: QueryOption<TShape, \"skip\">) => this.skip(data, option),\n sort: (data: unknown, option: QueryOption<TShape, \"sort\">) => this.sort(data, option),\n sum: (data: unknown, option: QueryOption<TShape, \"sum\">) => this.sum<any>(data, option),\n take: (data: unknown, option: QueryOption<TShape, \"take\">) => this.take(data, option),\n group: (data: unknown, option: QueryOption<TShape, \"group\">) => this.group(data, option),\n nearest: (data: unknown, option: QueryOption<TShape, \"nearest\">) => this.nearest(data, option),\n join: (data: unknown, option: QueryOption<TShape, \"join\">) => this.join(data, option)\n };\n\n constructor(query: IQuery<TRoot, TShape>) {\n this.query = query;\n }\n\n // Terminators\n abstract count<TResult extends number>(data: unknown, option: QueryOption<TShape, \"count\">): TResult;\n abstract min<TResult extends string | number | Date>(data: unknown, option: QueryOption<TShape, \"min\">): TResult;\n abstract max<TResult extends string | number | Date>(data: unknown, option: QueryOption<TShape, \"max\">): TResult;\n abstract sum<TResult extends number>(data: unknown, option: QueryOption<TShape, \"sum\">): TResult;\n abstract distinct<TResult>(data: unknown, option: QueryOption<TShape, \"distinct\">): TResult;\n\n // Shapers\n abstract filter<TResult>(data: unknown, option: QueryOption<TShape, \"filter\">): TResult;\n abstract skip(data: unknown, option: QueryOption<TShape, \"skip\">): TShape;\n abstract take(data: unknown, option: QueryOption<TShape, \"take\">): TShape;\n abstract sort(data: unknown, option: QueryOption<TShape, \"sort\">): TShape;\n abstract map(data: unknown, option: QueryOption<TShape, \"map\">): TShape;\n abstract group(data: unknown, option: QueryOption<TShape, \"group\">): TShape;\n /**\n * Abstract on purpose, unlike the pass-throughs a storage translator can usually inherit.\n *\n * Every other shaper degrades safely when a backend ignores it — an unsorted result is\n * still the right rows. A similarity search is not: it is the only option whose value is\n * ENTIRELY in the ordering and the limit, so a translator that quietly passes the data\n * through returns every row in insertion order and calls it the ten nearest.\n *\n * Requiring an answer here means a new translator cannot be written without deciding\n * whether its backend performed the search, and the compiler asks the question.\n */\n abstract nearest(data: unknown, option: QueryOption<TShape, \"nearest\">): TShape;\n\n /**\n * Abstract for the same reason as `nearest`, one step further.\n *\n * A translator that quietly passed a join through would not return an unsorted or unlimited\n * result — it would return the OUTER rows, one object each where the contract says tuples,\n * and every `([outer, inner]) => ...` lambda downstream would destructure the outer entity\n * instead. Nothing errors; the answer is simply a different query's answer.\n *\n * So the compiler asks the question. Every translator must state how its backend joins:\n * natively (pass through the rows the SQL already paired), in memory (the shared hash join\n * over rows the plugin supplies), or not at all (throw, loudly, naming the backend).\n *\n * The output contract, whichever answer: an array of `[outer, inner]` tuples, each half\n * fully deserialized into its OWN schema's entity shape.\n */\n abstract join(data: unknown, option: QueryOption<TShape, \"join\">): TShape;\n\n translate(data: unknown): ITranslatedValue<TShape> {\n\n const isTransformed = this.query.options.hasTransformations();\n\n this.query.options.forEach(item => {\n data = this.functionMap[item.name](data, item);\n });\n\n if (Array.isArray(data)) {\n return new TranslatedArrayValue<TShape>(data, isTransformed);\n }\n\n if (this.query.options.has(\"group\")) {\n return new TranslatedGroupValue<TShape>(data, isTransformed);\n }\n\n return new TranslatedSingleValue<TShape>(data, isTransformed);\n }\n}","import { logger } from \"../../utilities\";\n\n/**\n * Cosine distance, and the ordering rules that go with it.\n *\n * One implementation, shared by every in-memory path, because the promise the feature makes\n * is that a backend with no vector support returns the SAME ROWS IN THE SAME ORDER as one\n * that pushes the search down. Two copies of this arithmetic would drift, and the drift would\n * only ever show up as a conformance failure nobody could localise.\n *\n * The tie-breaking and degenerate cases below are chosen to match pgvector rather than to be\n * independently reasonable — parity is the point.\n */\n\n/**\n * Distance in `[0, 2]`, or `Infinity` for a value that cannot be compared.\n *\n * `Infinity` covers three cases, and they all sort LAST, which is what PostgreSQL does too:\n * a missing value (`NULL` sorts last under `ASC` by default), a zero-magnitude vector\n * (pgvector's `<=>` yields `NaN`, which PostgreSQL orders after every real number), and a\n * stored vector of the wrong width.\n *\n * The width case cannot happen on a native `vector(n)` column — the engine rejects the write —\n * so it only arises on a backend storing JSON, where the data was written by something other\n * than this schema. Sorting it last rather than throwing keeps one corrupt row from failing a\n * query that is otherwise answerable.\n */\nexport const cosineDistance = (left: readonly number[] | null | undefined, right: readonly number[]): number => {\n if (left == null || left.length !== right.length) {\n return Infinity;\n }\n\n let dot = 0;\n let leftMagnitude = 0;\n let rightMagnitude = 0;\n\n for (let i = 0, length = right.length; i < length; i++) {\n const l = left[i];\n const r = right[i];\n\n dot += l * r;\n leftMagnitude += l * l;\n rightMagnitude += r * r;\n }\n\n if (leftMagnitude === 0 || rightMagnitude === 0) {\n return Infinity;\n }\n\n return 1 - (dot / (Math.sqrt(leftMagnitude) * Math.sqrt(rightMagnitude)));\n};\n\n/**\n * The `count` rows closest to `vector`, nearest first.\n *\n * Distances are computed once per row rather than inside the comparator: a comparison-time\n * computation runs O(n log n) times over vectors that are commonly 1536 wide, which turns an\n * ordering into the dominant cost of the query.\n *\n * The sort is stable, so rows at equal distance keep the order the backend returned them in.\n * That is not a guarantee worth relying on across backends — two engines can hand back the\n * same rows in different orders — but it does mean this function never introduces a\n * difference of its own.\n */\nexport const nearestBy = <T>(\n rows: readonly T[],\n vector: number[],\n count: number,\n select: (row: T) => readonly number[] | null | undefined\n): T[] => {\n if (count <= 0) {\n return [];\n }\n\n /**\n * Rows whose stored vector is the wrong width, counted so the query can say so once.\n *\n * `cosineDistance` already handles them safely — they score `Infinity` and sort last, the\n * way PostgreSQL orders `NULL` — and that is deliberately not an error, because one corrupt\n * row must not fail a query that is otherwise answerable.\n *\n * The problem is that it is also SILENT. A row written at the wrong width is never returned\n * by any search and never reported by one, so an embedding model that changed its output\n * size degrades results steadily with nothing to notice. Counting costs a length comparison\n * per row against a vector that is commonly 1536 wide, and the warning is emitted once per\n * query rather than once per row.\n */\n let mismatched = 0;\n\n const scored = rows.map((row, index) => {\n const stored = select(row);\n\n if (stored != null && stored.length !== vector.length) {\n mismatched++;\n }\n\n return { row, index, distance: cosineDistance(stored, vector) };\n });\n\n if (mismatched > 0) {\n logger.warn(\n `nearest(): ${mismatched} of ${rows.length} stored vectors are not ${vector.length} wide, ` +\n `so they cannot be scored and sort last. They will never be returned by a search. ` +\n `This usually means the rows were written with a different embedding model.`\n );\n }\n\n scored.sort((a, b) => {\n if (a.distance === b.distance) {\n // Infinity === Infinity, so unscoreable rows fall through to insertion order\n // rather than to `Infinity - Infinity`, which is NaN and would leave the\n // comparator inconsistent — V8 is free to produce any permutation from that.\n return a.index - b.index;\n }\n\n return a.distance - b.distance;\n });\n\n return scored.slice(0, count).map(x => x.row);\n};\n","\nimport { CompiledSchema } from '../../schema';\nimport { IQuery } from '../types';\nimport { QueryOptionsCollection } from './QueryOptionsCollection';\n\nexport class Query<TRoot extends {}, TShape> implements IQuery<TRoot, TShape> {\n\n readonly options: QueryOptionsCollection<TShape>;\n readonly schema: CompiledSchema<TRoot>;\n private enableChangeTrackingOverride?: boolean\n\n constructor(\n options: QueryOptionsCollection<TShape>,\n schema: CompiledSchema<TRoot>,\n enableChangeTrackingOverride?: boolean,\n ) {\n this.schema = schema;\n this.options = options;\n this.enableChangeTrackingOverride = enableChangeTrackingOverride;\n }\n\n // boolean value whether or not change tracking can be enabled on the query result\n get changeTracking(): boolean {\n\n if (this.enableChangeTrackingOverride != null) {\n return this.enableChangeTrackingOverride;\n }\n\n const map = this.options.getValues(\"map\");\n const count = this.options.has(\"count\");\n const max = this.options.has(\"max\");\n const min = this.options.has(\"min\");\n const sum = this.options.has(\"sum\");\n\n if (map.some(x => x.fields.length > 0)) {\n return false\n }\n\n // A join returns TUPLES, not entities of this query's root schema. Attaching one would\n // hand the change tracker a two-element array to find an id on, and freezing or\n // membership-capturing it means reading the root schema's id off something that has no\n // properties at all. Join results are read-only projections, like `.map()` results.\n if (this.options.has(\"join\")) {\n return false;\n }\n\n if (count === true ||\n max === true ||\n min === true ||\n sum === true) {\n return false\n }\n\n return true;\n }\n\n static EMPTY<T extends {}, S>(schema: CompiledSchema<T>) {\n return new Query<T, S>(QueryOptionsCollection.EMPTY<S>(), schema);\n }\n\n static isEmpty<T extends {}, S>(query: IQuery<T, S>) {\n return QueryOptionsCollection.isEmpty(query.options);\n }\n\n static toString<TRoot extends {}, TShape>(query: IQuery<TRoot, TShape>) {\n return JSON.stringify({\n options: query.options.items,\n schema: {\n id: query.schema.id,\n collectionName: query.schema.collectionName\n },\n changeTracking: query.changeTracking\n })\n }\n}","import { CompiledSchemaCore, InferType, PropertyInfo } from \"../../schema\";\nimport { ComparatorExpression, Expression, ParamsFilter, PropertyExpression, ValueExpression } from \"../../expressions\";\nimport { UnknownRecord } from \"../../utilities\";\nimport { PluginEventCallbackResult, PluginEventResult } from \"../../results\";\nimport type { DbPluginQueryEvent } from \"../types\";\nimport type { ITranslatedValue } from \"../translators/types\";\nimport { TranslatedArrayValue } from \"../translators/TranslatedArrayValue\";\nimport { Query } from \"./Query\";\nimport { QueryOptionsCollection } from \"./QueryOptionsCollection\";\nimport { QueryOptionValueMap } from \"./types\";\n\nexport type JoinKind = \"inner\" | \"left\";\n\n/**\n * One side's join key, as a property path plus the resolved property.\n *\n * The path is what survives serialization; the `PropertyInfo` is the live handle that reads\n * the value and resolves a `from`-renamed storage name. Both, because a key read has to work\n * on either side of the wire.\n */\nexport type JoinKeyReference = {\n propertyName: string;\n property: PropertyInfo<any> | null;\n};\n\nexport type JoinQueryOptionValue = QueryOptionValueMap<any>[\"join\"];\n\n/**\n * The inner side of a join, as the PLUGIN sees it.\n *\n * Supplied by the plugin rather than fetched by the translator, because loading rows is the one\n * part of a join that is backend-specific: a memory plugin resolves a collection, Dexie opens a\n * store, Mongo reads a collection. Everything after that — deserializing, applying the inner\n * scopes, pairing — is identical, so it lives here and runs once.\n *\n * Rows arrive in STORAGE shape, exactly as the plugin holds them; the translator deserializes\n * them with `innerSchema`, which the outer query's own deserialization would never do.\n */\nexport type JoinInnerSide = {\n innerSchema: CompiledSchemaCore<any>;\n innerRows: readonly unknown[];\n};\n\n/**\n * `undefined` when the query has no join at all, which is the common case and not an error.\n */\nexport type JoinInnerSideResult =\n | { ok: \"success\"; innerSide?: JoinInnerSide }\n | { ok: \"error\"; error: unknown };\n\n/**\n * A joined pair, each half fully deserialized into its own schema's ENTITY shape.\n *\n * The wire contract for every interpretation of a join: a native SQL join, an in-plugin hash\n * join, and the datastore's cross-plugin join all produce exactly this. Flat combined rows\n * never leave a translator — see `specs/joins.md`.\n */\nexport type JoinTuple = [UnknownRecord, UnknownRecord | undefined];\n\n/**\n * Turns storage-shape records into entity-shape values, one side of a join at a time.\n *\n * The inner side does NOT pass through the outer query's normal deserialization —\n * `DatabaseDataAccessStrategy.query` transforms against the outer schema only — so each side\n * is deserialized with its own schema here, which is what makes the two halves of a tuple\n * readable by the same property names the caller wrote in the selectors.\n *\n * `\"diff\"` rather than `\"proxy\"`: join results are read-only projections and never attach to\n * the change tracker, so there is nothing for a tracking proxy to record.\n */\nexport const toEntityShape = (schema: CompiledSchemaCore<any>, rows: readonly unknown[]): UnknownRecord[] => {\n const result: UnknownRecord[] = Array.from({ length: rows.length });\n\n for (let i = 0, length = rows.length; i < length; i++) {\n result[i] = schema.postprocess(rows[i] as InferType<any>, \"diff\") as UnknownRecord;\n }\n\n return result;\n};\n\n/**\n * Reads a join key off an entity-shape row.\n *\n * Through the `PropertyInfo` when there is one, so a nested path (`a.b.id`) resolves the same\n * way every other option resolves it. The string fallback exists for an option that crossed a\n * wire without its schema; it walks the same path by name.\n */\nexport const readJoinKey = (row: UnknownRecord | undefined, reference: JoinKeyReference): unknown => {\n if (row == null) {\n return null;\n }\n\n if (reference.property != null) {\n return reference.property.getValue(row);\n }\n\n const path = reference.propertyName.split(\".\");\n let current: unknown = row;\n\n for (let i = 0, length = path.length; i < length; i++) {\n if (current == null) {\n return null;\n }\n\n current = (current as UnknownRecord)[path[i]];\n }\n\n return current;\n};\n\n/**\n * Whether a key value can participate in a match at all.\n *\n * `null`/`undefined` never match anything (semantics table in `specs/joins.md`), and `NaN` is\n * excluded for a subtler reason: a `Map` compares keys by SameValueZero, under which `NaN`\n * equals itself, while the specified comparison is strict `===`, under which it does not. A\n * `NaN` key that matched here would be the one value where the in-memory hash join and a SQL\n * join disagree.\n */\nconst isMatchableKey = (value: unknown): boolean => {\n if (value == null) {\n return false;\n }\n\n return typeof value !== \"number\" || Number.isNaN(value) === false;\n};\n\n/**\n * Applies an inner side's own filters to its rows.\n *\n * **This is the correctness trap of the whole feature.** Every interpretation of a join\n * bypasses the inner collection's normal datastore read path, so the inner side's soft-delete\n * scope and `.scope()` filters exist ONLY because `innerOptions` carries them. An interpreter\n * that skips this returns soft-deleted rows.\n *\n * Filters only. Nothing else reaches `innerOptions` today — scopes are filters — and applying\n * a `skip`/`take` recorded against the inner collection to the rows feeding a join would\n * change which pairs exist rather than which rows are visible.\n */\nexport const applyInnerOptions = (rows: UnknownRecord[], innerOptions: QueryOptionsCollection<any>): UnknownRecord[] => {\n let filtered = rows;\n\n for (const { option } of innerOptions.get(\"filter\")) {\n const { filter, params } = option.value;\n\n if (filter == null) {\n continue;\n }\n\n if (params == null) {\n filtered = filtered.filter(filter as (row: unknown) => boolean);\n continue;\n }\n\n const selector = filter as ParamsFilter<unknown, {}>;\n filtered = filtered.filter(row => selector([row, params]));\n }\n\n return filtered;\n};\n\n/**\n * The join itself: one hash join, written once, called from every interpreter.\n *\n * O(n + m) rather than a nested loop, which is the whole reason the API takes explicit key\n * selectors instead of a free-form predicate. Both key properties are `string` or `number` by\n * a build-time rule, so the keys are hashable and compare the same way in JS and in SQL.\n *\n * Semantics, exactly as `specs/joins.md` states them:\n *\n * - **Null keys** never match. Under `left` the outer row still appears, paired with\n * `undefined`.\n * - **Duplicates** produce every pair: the full cross product per key group.\n * - **Ordering** is outer order, then inner order within a key group. Undefined by contract —\n * a caller who cares sorts.\n */\nexport const hashJoin = (options: {\n kind: JoinKind;\n outerRows: UnknownRecord[];\n innerRows: UnknownRecord[];\n outerKey: JoinKeyReference;\n innerKey: JoinKeyReference;\n}): JoinTuple[] => {\n const { kind, outerRows, innerRows, outerKey, innerKey } = options;\n const isLeft = kind === \"left\";\n\n const buckets = new Map<unknown, UnknownRecord[]>();\n\n for (let i = 0, length = innerRows.length; i < length; i++) {\n const row = innerRows[i];\n const key = readJoinKey(row, innerKey);\n\n if (isMatchableKey(key) === false) {\n continue;\n }\n\n const bucket = buckets.get(key);\n\n if (bucket == null) {\n buckets.set(key, [row]);\n continue;\n }\n\n bucket.push(row);\n }\n\n const tuples: JoinTuple[] = [];\n\n for (let i = 0, length = outerRows.length; i < length; i++) {\n const outer = outerRows[i];\n const key = readJoinKey(outer, outerKey);\n const matches = isMatchableKey(key) ? buckets.get(key) : undefined;\n\n if (matches == null) {\n if (isLeft) {\n tuples.push([outer, undefined]);\n }\n\n continue;\n }\n\n for (let j = 0, matchLength = matches.length; j < matchLength; j++) {\n tuples.push([outer, matches[j]]);\n }\n }\n\n return tuples;\n};\n\n/**\n * How many distinct outer keys are still worth turning into an `IN (...)` prefilter.\n *\n * A cost decision, never a correctness one: above the threshold the inner side is read under its\n * own scopes and the hash join discards the surplus, which is the same answer by a slower route.\n * 500 because a bound-parameter list is cheap in the hundreds and starts costing more than the\n * scan it saves in the thousands — and some engines refuse a list that long outright.\n */\nexport const DEFAULT_SEMI_JOIN_KEY_THRESHOLD = 500;\n\n/**\n * The distinct join keys of the outer rows, or `null` when there are too many to be worth sending.\n *\n * `null` means \"do not prefilter\", not \"no keys\" — an empty SET is a real answer meaning the inner\n * side cannot match anything.\n *\n * @param column The key's STORAGE column name when `rows` are storage-shaped, or its property name\n * when they are entity-shaped. The caller knows which it holds.\n */\nexport const distinctJoinKeys = (\n rows: readonly UnknownRecord[],\n reference: JoinKeyReference,\n threshold: number = DEFAULT_SEMI_JOIN_KEY_THRESHOLD,\n options?: { storageShape?: boolean }\n): Set<unknown> | null => {\n const keys = new Set<unknown>();\n\n const read = options?.storageShape === true\n ? (row: UnknownRecord) => row[reference.property?.getResolvedName() ?? reference.propertyName]\n : (row: UnknownRecord) => readJoinKey(row, reference);\n\n for (const row of rows) {\n const key = read(row);\n\n // A null key matches nothing, so it never belongs in the prefilter — and including it\n // would widen the inner read to rows that cannot pair.\n if (isMatchableKey(key) === false) {\n continue;\n }\n\n keys.add(key);\n\n if (keys.size > threshold) {\n return null;\n }\n }\n\n return keys;\n};\n\n/**\n * A filter restricting the inner side to rows whose key is one the outer side actually has.\n *\n * Built as an expression tree by hand rather than parsed from generated source, for the reason\n * `softDeleteScope` gives: generating source needs `new Function`, which a Content-Security-Policy\n * blocks, and the shape is known here so there is nothing to parse. An `includes` comparator over\n * an array value is what every translator already turns into `IN (...)` or `$in`, so this pushes\n * down on the backends that can take it and runs as the closure on the ones that cannot.\n *\n * Cost only. Every pair it removes from the inner read is one the hash join would have discarded.\n */\nexport const semiJoinFilter = (\n reference: JoinKeyReference,\n keys: ReadonlySet<unknown>\n): QueryOptionValueMap<any>[\"filter\"] => {\n const values = [...keys];\n const propertyName = reference.propertyName;\n\n const expression = reference.property == null\n ? Expression.NOT_PARSABLE\n : new ComparatorExpression({\n comparator: \"includes\",\n negated: false,\n strict: true,\n left: new ValueExpression({ value: values }),\n right: new PropertyExpression({ property: reference.property }),\n });\n\n // Read through the PropertyInfo when there is one so a nested path resolves; the Set is closed\n // over rather than rebuilt per row.\n const read = reference.property != null\n ? (row: UnknownRecord) => reference.property!.getValue(row)\n : (row: UnknownRecord) => readJoinKey(row, { propertyName, property: null });\n\n return {\n filter: ((row: UnknownRecord) => keys.has(read(row))) as never,\n expression,\n params: undefined\n };\n};\n\n/**\n * Loads a join's inner side by asking the plugin to run an ORDINARY query for it.\n *\n * The generic way for a plugin to interpret a join — one call, no join-specific reading code.\n * The inner side is just \"this collection, under these filters\", which is a query every plugin\n * already knows how to answer, through whatever indexes and scoping it normally applies.\n *\n * Only the DATABASE half of `innerOptions` is sent. The memory half would mean nothing to the\n * plugin, and `executeJoin` re-applies every filter regardless — filters are pure, so the second\n * pass costs a walk over the survivors and guarantees the inner scopes are honoured even if the\n * plugin silently ignored them.\n *\n * The inner query carries no `join` option of its own, so this cannot recurse.\n *\n * @param query How this plugin runs a query. **Not necessarily `plugin.query`**: a plugin that\n * serializes queries through a work queue must pass its UN-QUEUED path, or this call waits behind\n * the outer query that is still holding the queue and the plugin deadlocks.\n */\nexport const loadJoinInnerSide = <TRoot extends {}, TShape>(\n event: DbPluginQueryEvent<TRoot, TShape>,\n query: (innerEvent: DbPluginQueryEvent<UnknownRecord, UnknownRecord>, done: PluginEventCallbackResult<ITranslatedValue<UnknownRecord>>) => void,\n done: (result: JoinInnerSideResult) => void,\n /**\n * The outer side's distinct keys, when the caller already has them.\n *\n * Only a plugin that runs its outer query FIRST can supply these, and most run this loader\n * before anything else — so it is optional, and its absence costs a wider inner read rather\n * than a wrong one.\n */\n outerKeys?: ReadonlySet<unknown> | null\n): void => {\n\n const joinOption = event.operation.options.getLast(\"join\");\n\n if (joinOption == null) {\n done({ ok: \"success\" });\n return;\n }\n\n const innerSchema = event.schemas.get(joinOption.value.innerSchemaId);\n\n if (innerSchema == null) {\n done({\n ok: \"error\",\n error: new Error(`Cannot join: the inner collection's schema is not registered in this store. SchemaId: ${joinOption.value.innerSchemaId}`)\n });\n return;\n }\n\n const innerOptions = joinOption.value.innerOptions.split().database;\n\n if (outerKeys != null) {\n innerOptions.add(\"filter\", semiJoinFilter(joinOption.value.innerKey, outerKeys));\n }\n\n const innerEvent: DbPluginQueryEvent<UnknownRecord, UnknownRecord> = {\n operation: new Query(innerOptions, innerSchema) as unknown as DbPluginQueryEvent<UnknownRecord, UnknownRecord>[\"operation\"],\n schemas: event.schemas,\n id: `${event.id}-inner`,\n source: event.source,\n action: \"query\",\n reason: \"join inner side\",\n explain: event.explain,\n // The same array the outer read pushes into, so a join reports BOTH reads in execution\n // order. Built fresh rather than spread, so this has to be carried explicitly.\n executedQueries: event.executedQueries\n };\n\n query(innerEvent, result => {\n if (result.ok === PluginEventResult.ERROR) {\n done({ ok: \"error\", error: result.error });\n return;\n }\n\n done({ ok: \"success\", innerSide: { innerSchema, innerRows: result.data.value as unknown as unknown[] } });\n });\n};\n\n/**\n * Interprets a join by running TWO ordinary queries through the plugin's own read path.\n *\n * The whole of interpretation 2 for a plugin that has no reason to do anything cleverer, and the\n * shape every non-SQL backend should prefer:\n *\n * ```ts\n * query(event, done) {\n * if (event.operation.options.has(\"join\")) {\n * joinInPlugin(event, (e, d) => this.query(e, d), done);\n * return;\n * }\n * // ...the ordinary single-collection path\n * }\n * ```\n *\n * **The outer side runs FIRST, and that ordering is the optimization.** Its keys are what narrow\n * the inner read to rows that can actually pair — and they do not exist until the outer filters\n * have run. Loading the inner side first, which is what a naive implementation does, means reading\n * and materializing a whole collection to pair it with three rows.\n *\n * Neither query carries the join option, so both take the plugin's normal path: its indexes, its\n * pushdown decisions, its retries. Nothing recurses, because the option is stripped before either\n * goes out.\n *\n * @param query How this plugin runs a query. NOT necessarily `plugin.query` — a plugin that\n * serializes queries through a work queue must pass its UN-QUEUED path, or the two reads below\n * wait on the slot this one is holding.\n */\nexport const joinInPlugin = <TRoot extends {}, TShape>(\n event: DbPluginQueryEvent<TRoot, TShape>,\n query: (innerEvent: DbPluginQueryEvent<UnknownRecord, UnknownRecord>, done: PluginEventCallbackResult<ITranslatedValue<UnknownRecord>>) => void,\n done: PluginEventCallbackResult<ITranslatedValue<TShape>>\n): void => {\n\n const { before, at } = event.operation.options.splitAt(\"join\");\n\n if (at == null) {\n done(PluginEventResult.error(event.id, new Error(\"joinInPlugin was called for a query with no join option.\")));\n return;\n }\n\n const innerSchema = event.schemas.get(at.value.innerSchemaId);\n\n if (innerSchema == null) {\n done(PluginEventResult.error(event.id, new Error(\n `Cannot join: the inner collection's schema is not registered in this store. SchemaId: ${at.value.innerSchemaId}`\n )));\n return;\n }\n\n /**\n * The outer side, as the ordinary query it would have been without the join.\n *\n * `before` is everything recorded ahead of the join — the outer filters, and any sort or\n * window. Those belong to the outer ROWS, and running them here rather than around a joined\n * result is what makes `.take(2).join(...)` pair the first two rows on every backend.\n */\n const outerEvent = {\n ...event,\n id: `${event.id}-outer`,\n reason: \"join outer side\",\n operation: new Query(before, event.operation.schema)\n } as unknown as DbPluginQueryEvent<UnknownRecord, UnknownRecord>;\n\n query(outerEvent, outerResult => {\n try {\n if (outerResult.ok === PluginEventResult.ERROR) {\n done(PluginEventResult.error(event.id, outerResult.error));\n return;\n }\n\n const outerRows = (outerResult.data.value ?? []) as unknown as UnknownRecord[];\n\n // Storage shape: the plugin returns rows as it holds them, and deserialization is what\n // `executeJoin` does per side below.\n const outerKeys = distinctJoinKeys(outerRows, at.value.outerKey, at.value.semiJoinKeyThreshold, { storageShape: true });\n\n loadJoinInnerSide(event, query, innerResult => {\n try {\n if (innerResult.ok === \"error\") {\n done(PluginEventResult.error(event.id, innerResult.error));\n return;\n }\n\n const tuples = executeJoin({\n option: at.value,\n outerRows: toEntityShape(event.operation.schema, outerRows),\n innerRows: toEntityShape(innerSchema, innerResult.innerSide?.innerRows ?? [])\n });\n\n // Nothing else can be in the database half — everything after a join ratchets\n // to memory — so these tuples are the whole of this plugin's answer.\n done(PluginEventResult.success(event.id, new TranslatedArrayValue<TShape>(tuples as never[], false)));\n } catch (e) {\n done(PluginEventResult.error(event.id, e));\n }\n }, outerKeys);\n } catch (e) {\n done(PluginEventResult.error(event.id, e));\n }\n });\n};\n\n/**\n * A join over rows both sides have already deserialized, with the inner side's scopes applied.\n *\n * The one entry point every interpreter uses: `JsonTranslator.join` inside a plugin, and the\n * datastore's own memory half for a cross-plugin join. Callers hand over ENTITY-shape rows —\n * `toEntityShape` is separate because a caller may already have paid for it.\n */\nexport const executeJoin = (options: {\n option: JoinQueryOptionValue;\n outerRows: UnknownRecord[];\n innerRows: UnknownRecord[];\n}): JoinTuple[] => {\n const { option, outerRows, innerRows } = options;\n\n return hashJoin({\n kind: option.kind,\n outerRows,\n innerRows: applyInnerOptions(innerRows, option.innerOptions),\n outerKey: option.outerKey,\n innerKey: option.innerKey\n });\n};\n","import { DataTranslator } from \"./DataTranslator\";\nimport { QueryOption } from \"../query/types\";\nimport { nearestBy } from \"../query/similarity\";\nimport { executeJoin, JoinInnerSide, toEntityShape } from \"../query/join\";\nimport { assertIsArray } from \"../../assertions\";\nimport { ParamsFilter } from \"../../expressions\";\nimport { isDate, UnknownRecord } from \"../../utilities\";\nimport { IdType } from \"../../schema\";\nimport { IQuery } from \"../types\";\n\nexport class JsonTranslator<TRoot extends {}, TShape> extends DataTranslator<TRoot, TShape> {\n\n private readonly innerSide?: JoinInnerSide;\n\n /**\n * @param innerSide The inner collection's rows, when this query carries a `join` option.\n * A plugin that omits it for a query that HAS a join gets a throw from `join()` rather than\n * a silently un-joined result.\n */\n constructor(query: IQuery<TRoot, TShape>, innerSide?: JoinInnerSide) {\n super(query);\n this.innerSide = innerSide;\n }\n\n /**\n * The hash join itself, over rows already in memory — the floor every non-SQL backend\n * stands on.\n *\n * Both halves are deserialized here, each with its own schema, because that is where the\n * `===` on key values is specified to happen: in entity shape, by the property names the\n * caller wrote in the key selectors. A `from`-renamed column reads correctly for free.\n */\n override join<TResult>(data: unknown, option: QueryOption<TShape, \"join\">): TResult {\n\n if (Array.isArray(data) === false) {\n return data as TResult;\n }\n\n if (this.innerSide == null) {\n throw new Error(\n `Cannot join: this plugin did not supply the inner collection's rows. ` +\n `A plugin whose translator inherits JsonTranslator.join must construct it with the inner side ` +\n `(new JsonTranslator(operation, { innerSchema, innerRows })) when the query carries a join option.`\n );\n }\n\n const { innerSchema, innerRows } = this.innerSide;\n\n return executeJoin({\n option: option.value,\n outerRows: toEntityShape(this.query.schema, data),\n innerRows: toEntityShape(innerSchema, innerRows)\n }) as TResult;\n }\n\n override filter<TResult>(data: unknown, option: QueryOption<TShape, \"filter\">): TResult {\n\n assertIsArray(data);\n\n if (option.value.filter) {\n\n if (option.value.params == null) {\n // standard filtering\n return data.filter(option.value.filter) as TResult;\n }\n\n // params filtering\n const selector = option.value.filter as ParamsFilter<unknown, {}>\n return data.filter(w => selector([w, option.value.params])) as TResult;\n }\n\n return data as TResult;\n }\n\n override map<T>(data: unknown, option: QueryOption<T, \"map\">): T {\n\n if (Array.isArray(data) == false) {\n throw new Error(\"Can only map an array of data\");\n }\n\n const response = Array.from({ length: data.length });\n\n for (let i = 0, length = data.length; i < length; i++) {\n\n for (let j = 0, l = option.value.fields.length; j < l; j++) {\n const field = option.value.fields[j];\n\n if (field.property != null) {\n const value = field.property.getValue(data[i]);\n\n if (value != null) {\n // Some types do not support deserialization (Array, Function, Computed, etc), just directly set the incoming value\n const resolvedValue = field.property.supportsDeserialization ? field.property.deserialize(value) : value;\n field.property.setValue(data[i], resolvedValue);\n }\n }\n }\n\n response[i] = option.value.selector(data[i]);\n }\n\n return response as T;\n }\n\n override group<T>(data: unknown, option: QueryOption<T, \"group\">): T {\n\n if (Array.isArray(data) == false) {\n throw new Error(\"Can only group an array of data\");\n }\n\n const group: Record<IdType, unknown[]> = {};\n\n for (let i = 0, length = data.length; i < length; i++) {\n\n const keyValue = option.value.selector(data[i]) as IdType;\n\n if (!group[keyValue]) {\n group[keyValue] = [];\n }\n\n const item: UnknownRecord = {};\n\n for (let j = 0, l = option.value.fields.length; j < l; j++) {\n const field = option.value.fields[j];\n\n if (field.property != null) {\n const value = field.property.getValue(data[i]);\n\n if (value != null) {\n // Some types do not support deserialization (Array, Function, Computed, etc), just directly set the incoming value\n const resolvedValue = field.property.supportsDeserialization ? field.property.deserialize(value) : value;\n field.property.setValue(item, resolvedValue);\n continue;\n }\n\n // The property exists, lets set it to the value (null/undefined)\n if (Object.hasOwn(data[i], field.destinationName)) {\n field.property.setValue(item, value);\n }\n }\n }\n\n group[keyValue].push(item);\n }\n\n return group as T;\n }\n\n override count<TResult extends number>(data: unknown, _: QueryOption<TShape, \"count\">): TResult {\n\n if (Array.isArray(data)) {\n return data.length as TResult;\n }\n\n throw new Error(\"Cannot count resulting data, it must be an array. Please return array of data for function: count()\");\n }\n\n // Relational comparison instead of subtraction, for the same reason as sort():\n // subtraction is NaN for strings, which made min()/max() return an arbitrary element.\n // Nulls order first ascending — min() of a column with nulls is null, max() is the\n // largest value — matching what sort() does with the same data.\n override min<TResult extends string | number | Date>(data: unknown, _: QueryOption<TShape, \"min\">): TResult {\n return this._minMax(data, \"min\", (a: any, b: any) => {\n if (a === b) {\n return 0;\n }\n\n if (a == null) {\n return -1;\n }\n\n if (b == null) {\n return 1;\n }\n\n return a < b ? -1 : 1;\n });\n }\n\n override max<TResult extends string | number | Date>(data: unknown, _: QueryOption<TShape, \"max\">): TResult {\n return this._minMax(data, \"max\", (a: any, b: any) => {\n if (a === b) {\n return 0;\n }\n\n if (a == null) {\n return 1;\n }\n\n if (b == null) {\n return -1;\n }\n\n return a < b ? 1 : -1;\n });\n }\n\n override sort<TResult>(data: unknown, option: QueryOption<TShape, \"sort\">): TResult {\n\n if (Array.isArray(data)) {\n const direction = option.value.direction === \"asc\" ? 1 : -1;\n\n // Relational comparison instead of subtraction — subtraction is NaN\n // for strings, which leaves the array unsorted\n data.sort((x, y) => {\n const a = option.value.selector(x) as any;\n const b = option.value.selector(y) as any;\n\n if (a === b) {\n return 0;\n }\n\n if (a == null) {\n return -1 * direction;\n }\n\n if (b == null) {\n return 1 * direction;\n }\n\n return (a < b ? -1 : 1) * direction;\n });\n }\n\n return data as TResult;\n }\n\n /**\n * The similarity search itself, over values already in memory.\n *\n * This is the floor the whole feature stands on: it is reached whenever the backend did\n * not do the search, which is every backend except the ones with a native vector index.\n * It reads the property through the option's selector, so it works on any shape the rows\n * arrive in.\n */\n override nearest<TResult>(data: unknown, option: QueryOption<TShape, \"nearest\">): TResult {\n\n if (Array.isArray(data) === false) {\n return data as TResult;\n }\n\n const { selector, vector, count } = option.value;\n\n return nearestBy(data, vector, count, row => selector(row) as unknown as number[] | null) as TResult;\n }\n\n override sum<TResult extends number>(data: unknown, _: QueryOption<TShape, \"sum\">): TResult {\n\n assertIsArray(data, this._formatDataNotArrayError(\"sum\"));\n\n if (data.length === 0) {\n throw new Error(\"Cannot perform operation on empty array, result query contains no data\")\n }\n\n const map = this.query.options.getLast(\"map\");\n\n let sum = 0;\n const field = this._getSelectionField(\"sum\", map);\n\n for (let i = 0, length = data.length; i < length; i++) {\n const value = data[i];\n\n if (typeof value !== \"number\") {\n throw new Error(`Cannot sum, property is not a number. Property: ${field.sourceName}`);\n }\n\n sum += value;\n }\n\n return sum as TResult;\n }\n\n override distinct<TResult>(data: unknown, _: QueryOption<TShape, \"distinct\">): TResult {\n\n assertIsArray(data, this._formatDataNotArrayError(\"distinct\"));\n\n const result = new Set<string | number | Date>();\n\n // would be nice to have property info here for type detection\n let needsDateConversion = false;\n\n for (let i = 0, length = data.length; i < length; i++) {\n const value = data[i];\n\n if (typeof value === \"number\" || typeof value === \"string\") {\n result.add(value);\n continue;\n }\n\n if (isDate(value)) {\n needsDateConversion = true;\n result.add(value.toISOString());\n continue;\n }\n\n }\n\n if (needsDateConversion) {\n return [...result].map(w => new Date(w)) as TResult;\n }\n\n return [...result] as TResult\n }\n\n override skip<TResult>(data: unknown, option: QueryOption<TShape, \"skip\">): TResult {\n\n if (Array.isArray(data)) {\n\n if (option.value > 0) {\n\n if (data.length < option.value) {\n // We don't have enough data to skip, return an empty array\n return [] as TResult;\n }\n\n return data.slice(option.value) as TResult;\n }\n\n return data as TResult;\n }\n\n return data as TResult;\n }\n\n override take<TResult>(data: unknown, option: QueryOption<TShape, \"take\">): TResult {\n if (Array.isArray(data)) {\n\n if (option.value > 0) {\n\n if (data.length < option.value) {\n return data as TResult;\n }\n\n return data.slice(0, option.value) as TResult;\n }\n\n return data as TResult;\n }\n\n return data as TResult;\n }\n\n private _getSelectionField(name: string, mapOption: QueryOption<TShape, \"map\"> | null) {\n\n if (mapOption == null ||\n mapOption.value.fields.length === 0 ||\n mapOption.value.fields.length > 1) {\n throw new Error(`${name}() operation can only be performed when one field is mapped for a result. Ex. myset.map(x => x.someNumberOrDateOrString).${name}()`)\n }\n\n return mapOption.value.fields[0];\n }\n\n private _minMax<T extends string | number | Date>(data: unknown, name: string, sort: (a: any, b: any) => any): T {\n\n assertIsArray(data, this._formatDataNotArrayError(name));\n\n if (data.length === 0) {\n throw new Error(\"Cannot perform operation on empty array, result query contains no data\")\n }\n\n // A single pass, not sort-and-take-first: O(n) for an O(n) question, and it does not\n // MUTATE the array the caller handed us — the sort did. The caller's comparator is\n // reused so min and max keep their null ordering from one body.\n let best = data[0];\n\n for (let i = 1, length = data.length; i < length; i++) {\n const value = data[i];\n\n // Array.prototype.sort moves undefined elements to the END without consulting the\n // comparator. Mirror that: undefined is never selected unless every element is.\n if (value === undefined) {\n continue;\n }\n\n if (best === undefined || sort(value, best) < 0) {\n best = value;\n }\n }\n\n return best as T;\n }\n\n private _formatDataNotArrayError(functionName: string) {\n return `Cannot sum resulting data, it must be an array. Please return array of data for function: ${functionName}()`\n }\n}","import { IdType } from \"../../schema/types\";\nimport { UnknownRecord } from \"../../utilities/types\";\nimport { QueryOption } from \"../query/types\";\nimport { nearestBy } from \"../query/similarity\";\nimport { IQuery } from \"../types\";\nimport { DataTranslator } from \"./DataTranslator\";\n\n/**\n * A stored vector as a list of numbers, whatever the driver handed back.\n *\n * Three shapes reach here and all are legitimate. A JSON column decoded by\n * `decodeJsonColumns` is already an array. A driver with no type parser for its native vector\n * type returns the literal text — `pg` does exactly this for pgvector, giving `\"[1,2,3]\"`,\n * which happens to be JSON. Anything else is not a vector, and `null` sorts it last rather\n * than throwing.\n */\nconst toVector = (value: unknown): number[] | null => {\n if (Array.isArray(value)) {\n return value as number[];\n }\n\n if (typeof value !== \"string\") {\n return null;\n }\n\n try {\n const parsed = JSON.parse(value);\n\n return Array.isArray(parsed) ? parsed as number[] : null;\n } catch {\n return null;\n }\n};\n\n/**\n * What the statement that produced these rows actually did.\n *\n * Supplied by the plugin because only its query builder knows: an extension may be missing, a\n * window may have made a pushdown unsafe, an inner filter may have had no column to compare\n * against. Every flag defaults to false — the safe direction, since doing the work twice is slow\n * and skipping it is wrong.\n */\nexport type SqlPushdown = {\n /** The statement contained a real `INNER JOIN`/`LEFT JOIN` and its rows are already tuples. */\n join?: boolean;\n};\n\nexport class SqlTranslator<TRoot extends {}, TShape> extends DataTranslator<TRoot, TShape> {\n\n protected readonly pushedDown: SqlPushdown;\n\n constructor(query: IQuery<TRoot, TShape>, pushedDown: SqlPushdown = {}) {\n super(query);\n this.pushedDown = pushedDown;\n }\n\n count<TResult extends number>(data: unknown, _: QueryOption<TShape, \"count\">): TResult {\n if (Array.isArray(data) && data.length > 0) {\n // Count is returned as the property alias on the query.\n //\n // Driver-specific coercion does NOT belong here. Some drivers return COUNT(*)\n // as a bigint string rather than a number; which ones is a fact about those\n // drivers, so a plugin whose driver deviates overrides this method. Naming them\n // here is how engine knowledge starts accumulating in a storage-agnostic\n // package — one bug fix at a time.\n return data[0].count;\n }\n\n return data as TResult;\n }\n\n min<TResult extends string | number | Date>(data: unknown, _: QueryOption<TShape, \"min\">): TResult {\n return this.shapeResult(data);\n }\n\n max<TResult extends string | number | Date>(data: unknown, _: QueryOption<TShape, \"max\">): TResult {\n return this.shapeResult(data);\n }\n\n sum<TResult extends number>(data: unknown, _: QueryOption<TShape, \"sum\">): TResult {\n return this.shapeResult(data);\n }\n\n private shapeResult<TResult>(data: unknown) {\n if (Array.isArray(data) && data.length > 0) {\n // Shape the result\n return data[0];\n }\n\n return data as TResult;\n }\n\n distinct<TResult>(data: unknown, _: QueryOption<TShape, \"distinct\">): TResult {\n return data as TResult;\n }\n\n filter<TResult>(data: unknown, _: QueryOption<TShape, \"filter\">): TResult {\n return data as TResult;\n }\n\n skip(data: unknown, _: QueryOption<TShape, \"skip\">): TShape {\n return data as TShape;\n }\n\n take(data: unknown, _: QueryOption<TShape, \"take\">): TShape {\n return data as TShape;\n }\n\n sort(data: unknown, _: QueryOption<TShape, \"sort\">): TShape {\n return data as TShape;\n }\n\n /**\n * Scores in memory, unlike every other shaper here.\n *\n * The pass-throughs above are safe because the SQL that produced these rows contained the\n * corresponding clause. No `sql-core` statement contains a similarity ordering — engines\n * that can express one are the exception, not the rule — so passing the data through\n * would return whatever order the engine happened to produce.\n *\n * A plugin whose engine DID push the search down overrides this with a pass-through,\n * gated on `option.target`. Postgres is the only one today.\n *\n * Rows arrive keyed by storage column name and are read that way rather than through the\n * option's selector, because the selector is written against the entity shape and these\n * rows have not been deserialized into it yet.\n */\n nearest(data: unknown, option: QueryOption<TShape, \"nearest\">): TShape {\n\n if (Array.isArray(data) === false) {\n return data as TShape;\n }\n\n const { property, propertyName, vector, count } = option.value;\n const column = property?.getResolvedName() ?? propertyName;\n\n return nearestBy(data, vector, count, row => toVector((row as UnknownRecord)[column])) as TShape;\n }\n\n /**\n * Passes through only when the statement really did contain the `JOIN`, and refuses otherwise.\n *\n * The pass-throughs above are safe unconditionally because the SQL that produced these rows\n * contained the corresponding clause. A join is not like that: if the plugin did not emit one,\n * these rows are the outer side alone, and passing them through hands the caller entities\n * where the contract says tuples — every `([outer, inner]) => ...` lambda downstream then\n * destructures the wrong object, and nothing errors.\n *\n * So the plugin has to say, and the default is to refuse. A plugin that DID emit the join has\n * already split each flat row into its two deserialized halves (`splitJoinRows` in\n * `@routier/sql-plugin-core`), so by the time the option is walked the work is done.\n */\n join(data: unknown, option: QueryOption<TShape, \"join\">): TShape {\n if (this.pushedDown.join === true && option.target === \"database\") {\n return data as TShape;\n }\n\n throw new Error(\n `This SQL plugin did not push the join down, so it cannot produce the pairs. Kind: ${option.value.kind}. ` +\n `Emitting the JOIN is the plugin's job: build the joined statement with buildJoinStatement, split the rows with ` +\n `splitJoinRows, and construct this translator with { join: true }.`\n );\n }\n\n group<T>(data: unknown, option: QueryOption<T, \"group\">): T {\n\n if (Array.isArray(data) == false) {\n throw new Error(\"Can only group an array of data\");\n }\n\n const group: Record<IdType, unknown[]> = {};\n\n for (let i = 0, length = data.length; i < length; i++) {\n\n const keyValue = option.value.selector(data[i]) as IdType;\n\n if (!group[keyValue]) {\n group[keyValue] = [];\n }\n\n const item: UnknownRecord = {};\n\n for (let j = 0, l = option.value.fields.length; j < l; j++) {\n const field = option.value.fields[j];\n\n if (field.property != null) {\n const value = field.property.getValue(data[i]);\n\n if (value != null) {\n field.property.setValue(item, field.property.deserialize(value));\n }\n }\n }\n\n group[keyValue].push(item);\n }\n\n return group as T;\n }\n\n map(data: unknown, option: QueryOption<TShape, \"map\">): TShape {\n if (Array.isArray(data) == false) {\n throw new Error(\"Can only map an array of data\");\n }\n\n if (this.query.options.has(\"count\") && data.length === 1) {\n // data here is the shape of { count: number }[] and will map to nothing. \n // Return the original data and let count take care of this\n return data as TShape;\n }\n\n const response = [];\n\n for (let i = 0, length = data.length; i < length; i++) {\n\n for (let j = 0, l = option.value.fields.length; j < l; j++) {\n const field = option.value.fields[j];\n\n if (field.property != null) {\n const value = field.property.getValue(data[i]);\n\n if (value != null) {\n field.property.setValue(data[i], field.property.deserialize(value));\n }\n }\n }\n\n response.push(option.value.selector(data[i]));\n }\n\n return response as TShape;\n }\n}","import { DataTranslator } from \"./DataTranslator\";\nimport { QueryOption } from \"../query/types\";\nimport { assertIsArray } from \"../../assertions\";\nimport { ParamsFilter } from \"../../expressions\";\n\n/**\n * The memory half's pass over JOIN TUPLES.\n *\n * `JsonTranslator` cannot do this job, and the reason is one line of it: `map` and `group` walk\n * `option.value.fields` and deserialize each field through its `PropertyInfo`. A tuple has no\n * schema and no fields — `getFields` over `([p, m]) => ({ ... })` extracts nothing meaningful —\n * so that loop would either no-op or write properties onto a two-element array.\n *\n * Everything a join query is allowed to do after the join is expressible as a plain closure\n * over the tuple, and that is all this does. The lambdas the caller wrote (`([p, m]) => ...`)\n * are applied as-is, which is also why the result is identical whichever backend produced the\n * pairs.\n *\n * Both halves are already in entity shape when the tuples arrive here (the wire contract), so\n * there is nothing left to deserialize — the reason the missing field loop costs nothing.\n *\n * The absent operations are absent by design, not by omission: `sum`/`min`/`max`/`distinct` and\n * `group` are not declared on the tuple queryable's type, so reaching them means something\n * built an option this API cannot express, and a throw naming it is the honest answer.\n */\nexport class TupleTranslator<TRoot extends {}, TShape> extends DataTranslator<TRoot, TShape> {\n\n override filter<TResult>(data: unknown, option: QueryOption<TShape, \"filter\">): TResult {\n\n assertIsArray(data);\n\n if (option.value.filter == null) {\n return data as TResult;\n }\n\n if (option.value.params == null) {\n return data.filter(option.value.filter) as TResult;\n }\n\n const selector = option.value.filter as ParamsFilter<unknown, {}>;\n return data.filter(tuple => selector([tuple, option.value.params])) as TResult;\n }\n\n override map<TResult>(data: unknown, option: QueryOption<TShape, \"map\">): TResult {\n\n assertIsArray(data, this.notAnArray(\"map\"));\n\n return data.map(tuple => option.value.selector(tuple as TShape)) as TResult;\n }\n\n override sort<TResult>(data: unknown, option: QueryOption<TShape, \"sort\">): TResult {\n\n if (Array.isArray(data) === false) {\n return data as TResult;\n }\n\n const direction = option.value.direction === \"asc\" ? 1 : -1;\n\n // Relational comparison rather than subtraction, and nulls first ascending — the same\n // ordering `JsonTranslator.sort` produces, so a sort means the same thing on either\n // side of a join.\n data.sort((x, y) => {\n const a = option.value.selector(x) as any;\n const b = option.value.selector(y) as any;\n\n if (a === b) {\n return 0;\n }\n\n if (a == null) {\n return -1 * direction;\n }\n\n if (b == null) {\n return 1 * direction;\n }\n\n return (a < b ? -1 : 1) * direction;\n });\n\n return data as TResult;\n }\n\n override skip<TResult>(data: unknown, option: QueryOption<TShape, \"skip\">): TResult {\n\n if (Array.isArray(data) === false || option.value <= 0) {\n return data as TResult;\n }\n\n return data.slice(option.value) as TResult;\n }\n\n override take<TResult>(data: unknown, option: QueryOption<TShape, \"take\">): TResult {\n\n if (Array.isArray(data) === false || option.value <= 0) {\n return data as TResult;\n }\n\n return data.slice(0, option.value) as TResult;\n }\n\n override count<TResult extends number>(data: unknown, _: QueryOption<TShape, \"count\">): TResult {\n\n assertIsArray(data, this.notAnArray(\"count\"));\n\n return data.length as TResult;\n }\n\n /**\n * Already joined by the time anything reaches here.\n *\n * The pairs were produced either by the plugin (its translator's `join`) or by the datastore\n * before this pass ran, so the option is a record of what happened rather than work to do.\n */\n override join(data: unknown, _: QueryOption<TShape, \"join\">): TShape {\n return data as TShape;\n }\n\n override group<TResult>(_: unknown, __: QueryOption<TShape, \"group\">): TResult {\n throw new Error(this.notSupported(\"toGroup\"));\n }\n\n override sum<TResult extends number>(_: unknown, __: QueryOption<TShape, \"sum\">): TResult {\n throw new Error(this.notSupported(\"sum\"));\n }\n\n override min<TResult extends string | number | Date>(_: unknown, __: QueryOption<TShape, \"min\">): TResult {\n throw new Error(this.notSupported(\"min\"));\n }\n\n override max<TResult extends string | number | Date>(_: unknown, __: QueryOption<TShape, \"max\">): TResult {\n throw new Error(this.notSupported(\"max\"));\n }\n\n override distinct<TResult>(_: unknown, __: QueryOption<TShape, \"distinct\">): TResult {\n throw new Error(this.notSupported(\"distinct\"));\n }\n\n override nearest(_: unknown, __: QueryOption<TShape, \"nearest\">): TShape {\n // A similarity search BEFORE the join stays in the outer side's options and never\n // reaches a tuple. One after it would have to score a pair, which has no vector.\n throw new Error(this.notSupported(\"nearest\"));\n }\n\n private notSupported(name: string) {\n return `${name}() is not available on a join result. Project the tuples with .map() first, then run it on the projection.`;\n }\n\n private notAnArray(name: string) {\n return `Cannot ${name} a join result, it must be an array of tuples.`;\n }\n}\n","export * from './DataTranslator';\nexport * from './JsonTranslator';\nexport * from './SqlTranslator';\nexport * from './TupleTranslator';\nexport * from './types';\nexport * from './TranslatedArrayValue';\nexport * from './TranslatedGroupValue';\nexport * from './TranslatedSingleValue';","import { Expression } from \"../../expressions/types\";\nimport { MemoryExecutionReason, QueryOption, QueryOptionExecutionTarget, QueryOptionName } from \"./types\";\nimport { QueryOptionsCollection } from \"./QueryOptionsCollection\";\n\n/**\n * One sentence per reason code, written for someone meeting pushdown for the first time.\n *\n * Beside the codes rather than in the formatter, so console output, a failing test and the\n * docs all say the same thing.\n */\nexport const MEMORY_EXECUTION_EXPLANATIONS: Record<MemoryExecutionReason, string> = {\n \"not-parsable\": \"A filter could not be parsed into an expression tree, so it and every option after it run in memory.\",\n \"unmapped-property\": \"The property is not stored in the database, so it can only be read after deserialization.\",\n \"renamed-property\": \"The property is stored under a different name, and selectors use the in-memory name, so it can only be read after deserialization.\",\n \"map-rename\": \"A map renames or drops properties, so every option after it refers to names the database does not have.\",\n \"after-nearest\": \"A similarity search orders and limits rows, and the plugin cannot report whether it performed the search, so every option after it runs in memory.\",\n \"after-join\": \"A join produces [outer, inner] tuples rather than entities, and the plugin cannot report how it joined, so every option after it runs in memory.\",\n \"cross-plugin-join\": \"The two sides of this join live on different plugins, so neither can read the other's rows and the join runs in the datastore.\"\n};\n\n/**\n * One thing a backend actually executed, in the backend's own language.\n *\n * A plugin pushes these onto `DbPluginQueryEvent.executedQueries` as it runs them, so a join —\n * which reads twice — reports both, in execution order. `text` is not required to be SQL: a\n * key-value store describes what it did in whatever terms it has.\n */\nexport type ExecutedQuery = {\n text: string;\n parameters?: unknown[];\n};\n\nexport type ExplainedOption = {\n index: number;\n name: QueryOptionName;\n detail?: Record<string, unknown>;\n};\n\nexport const EXECUTED_QUERIES_UNSUPPORTED =\n \"This plugin did not report what it executed. It may not support explain.\";\n\nexport type ExecutionStep = {\n step: number;\n of: number;\n executedIn: QueryOptionExecutionTarget;\n description: string;\n options: ExplainedOption[];\n /** Set on database steps once the plugin has reported. */\n executedQueries?: ExecutedQuery[];\n /** Set on the first database step instead, when the plugin reported nothing. */\n executedQueriesUnsupported?: string;\n /** Set on memory steps only. */\n reason?: MemoryExecutionReason;\n explanation?: string;\n};\n\nexport type QueryExplanationSummary = {\n database: number;\n memory: number;\n /** Deduped, in first-seen order. Empty when the whole query pushed down. */\n reasons: MemoryExecutionReason[];\n explanation: string;\n};\n\nexport type QueryExplanation = {\n collection: string;\n database: string;\n summary: QueryExplanationSummary;\n executionSteps: ExecutionStep[];\n plugin: { kind: string };\n};\n\nexport type ExplainContext = {\n collection: string;\n database: string;\n pluginKind: string;\n};\n\nconst DATABASE_STEP_DESCRIPTION = \"These options are sent to the plugin.\";\nconst MEMORY_STEP_DESCRIPTION = \"Routier runs these over the rows the database returned, after deserializing them.\";\nconst UNNARROWED_READ_DESCRIPTION = \"No option could be pushed down, so the plugin reads the whole collection.\";\n\n/**\n * The reportable shape of one option's value.\n *\n * Serializable facts only, never the live selector functions — an explanation is a document a\n * caller may log, diff in a test, or send to a server, and a closure survives none of that.\n */\nconst detailOf = (option: QueryOption<any, any>): Record<string, unknown> | undefined => {\n\n if (option.name === \"filter\") {\n const value = option.value as { expression?: Expression };\n\n if (value.expression == null) {\n return undefined;\n }\n\n try {\n return { expression: Expression.toJson(value.expression) };\n } catch {\n // `valueToJson` rejects a value no wire can carry. Reporting the rest of the\n // explanation beats taking the diagnostic down with the query it describes.\n return { expressionUnavailable: \"This filter holds a value that cannot be serialized.\" };\n }\n }\n\n if (option.name === \"sort\") {\n const value = option.value as { propertyName: string, direction: string };\n\n return { propertyName: value.propertyName, direction: value.direction };\n }\n\n if (option.name === \"skip\" || option.name === \"take\") {\n return { value: option.value as number };\n }\n\n if (option.name === \"nearest\") {\n const value = option.value as { propertyName: string, vector: number[], count: number };\n\n return { propertyName: value.propertyName, dimensions: value.vector.length, count: value.count };\n }\n\n if (option.name === \"join\") {\n const value = option.value as {\n kind: string,\n outerKey: { propertyName: string },\n innerKey: { propertyName: string },\n crossPlugin: boolean,\n innerOptions: QueryOptionsCollection<any>\n };\n\n return {\n kind: value.kind,\n outerKey: value.outerKey.propertyName,\n innerKey: value.innerKey.propertyName,\n crossPlugin: value.crossPlugin,\n innerOptions: explainedOptionsOf(value.innerOptions)\n };\n }\n\n if (option.name === \"map\" || option.name === \"group\") {\n const value = option.value as { fields: { sourceName: string, destinationName: string }[] };\n\n return { fields: value.fields.map(x => ({ from: x.sourceName, to: x.destinationName })) };\n }\n\n return undefined;\n};\n\nconst explainedOptionOf = (option: QueryOption<any, any>, index: number): ExplainedOption => {\n const detail = detailOf(option);\n\n return { index, name: option.name, ...(detail == null ? {} : { detail }) };\n};\n\nconst explainedOptionsOf = (options: QueryOptionsCollection<any>): ExplainedOption[] => {\n const explained: ExplainedOption[] = [];\n let index = 0;\n\n options.forEach(option => explained.push(explainedOptionOf(option, index++)));\n\n return explained;\n};\n\nconst summarize = (steps: ExecutionStep[]): QueryExplanationSummary => {\n const reasons: MemoryExecutionReason[] = [];\n let database = 0;\n let memory = 0;\n\n for (const step of steps) {\n if (step.executedIn === \"database\") {\n database += step.options.length;\n continue;\n }\n\n memory += step.options.length;\n\n if (step.reason != null && reasons.includes(step.reason) === false) {\n reasons.push(step.reason);\n }\n }\n\n const counts = `${database} ${database === 1 ? \"option ran\" : \"options ran\"} in the database, ${memory} ran in memory.`;\n const causes = reasons.map(reason => MEMORY_EXECUTION_EXPLANATIONS[reason]).join(\" \");\n\n return { database, memory, reasons, explanation: causes.length === 0 ? counts : `${counts} ${causes}` };\n};\n\n/**\n * Groups options into consecutive runs that execute in the same place.\n *\n * A step boundary is where execution moves, and a reader has to see the statement as step 1 OF\n * 2 to understand it is not the whole query. Cutting over to memory is a ratchet, so the\n * database options are always a prefix and there are at most two steps.\n *\n * A database step is emitted even when NO option pushed down, because the plugin is dispatched\n * either way — `createQueryPayload` always builds a database event. Without it, the worst case\n * the feature exists to expose reports \"0 in the database\" while the backend reads the whole\n * table, which is the opposite of the truth.\n */\nconst toExecutionSteps = (options: QueryOptionsCollection<any>): ExecutionStep[] => {\n const steps: ExecutionStep[] = [];\n let index = 0;\n\n options.forEach(option => {\n const explained = explainedOptionOf(option, index++);\n const current = steps[steps.length - 1];\n\n if (current != null && current.executedIn === option.target) {\n current.options.push(explained);\n return;\n }\n\n steps.push({\n step: steps.length + 1,\n of: 0,\n executedIn: option.target,\n description: option.target === \"database\" ? DATABASE_STEP_DESCRIPTION : MEMORY_STEP_DESCRIPTION,\n options: [explained],\n ...(option.reason == null ? {} : {\n reason: option.reason,\n explanation: MEMORY_EXECUTION_EXPLANATIONS[option.reason]\n })\n });\n });\n\n if (steps[0]?.executedIn !== \"database\") {\n steps.unshift({\n step: 0,\n of: 0,\n executedIn: \"database\",\n description: UNNARROWED_READ_DESCRIPTION,\n options: []\n });\n }\n\n for (let i = 0; i < steps.length; i++) {\n steps[i].step = i + 1;\n steps[i].of = steps.length;\n }\n\n return steps;\n};\n\n/**\n * Builds the explanation from the resolved options, with no plugin involvement.\n *\n * Takes the collection BEFORE `split()`, and throws otherwise. Splitting re-adds each half\n * into a fresh collection, which re-derives targets without the options that caused them — a\n * post-join filter alone in the memory half derives back to `\"database\"`, and the document\n * would report memory work as having run in the database.\n */\nexport const explainQuery = (options: QueryOptionsCollection<any>, context: ExplainContext): QueryExplanation => {\n\n if (options.isDerived === true) {\n throw new Error(\n \"explainQuery was given a collection produced by split() or splitAt(). Those re-derive \" +\n \"execution targets without the options that caused them, so the explanation would report \" +\n \"memory work as having run in the database. Pass the collection as it was resolved, \" +\n \"before splitting.\"\n );\n }\n\n const executionSteps = toExecutionSteps(options);\n\n return {\n collection: context.collection,\n database: context.database,\n summary: summarize(executionSteps),\n executionSteps,\n plugin: { kind: context.pluginKind }\n };\n};\n\n/**\n * Attaches what the backend reported to the step that was sent to it.\n *\n * Reporting is optional for a plugin, so an empty report is not an error: the step is marked\n * `executedQueriesUnsupported` instead, and the rest of the explanation stands — the pushdown\n * analysis comes from the options and is correct with or without the plugin's statements.\n *\n * Copies the steps rather than writing into them, so the explanation a caller already holds\n * does not gain statements after the fact. Options and their details are shared with the\n * original — nothing mutates them, and copying deeper would only look safer than it is.\n */\nexport const withExecutedQueries = (explanation: QueryExplanation, executedQueries: ExecutedQuery[]): QueryExplanation => {\n let attached = false;\n\n const executionSteps = explanation.executionSteps.map((step): ExecutionStep => {\n\n // Only the first database step: a plugin reports what IT ran, and everything it ran\n // was sent as one dispatch. Stamping the same statements onto a second database step\n // would claim they ran twice.\n if (step.executedIn !== \"database\" || attached === true) {\n return { ...step, options: [...step.options] };\n }\n\n attached = true;\n\n if (executedQueries.length === 0) {\n return { ...step, options: [...step.options], executedQueriesUnsupported: EXECUTED_QUERIES_UNSUPPORTED };\n }\n\n return { ...step, options: [...step.options], executedQueries: [...executedQueries] };\n });\n\n return { ...explanation, executionSteps };\n};\n","import { ExecutionStep, ExplainedOption, QueryExplanation } from \"./explain\";\n\nconst OPTION_LABEL_WIDTH = 8;\nconst WRAP_WIDTH = 68;\n\n/** Wraps `text` to `WRAP_WIDTH`, prefixing every line with `indent`. */\nconst wrap = (text: string, indent: string): string[] => {\n const lines: string[] = [];\n let line = \"\";\n\n for (const word of text.split(\" \")) {\n if (line.length > 0 && line.length + word.length + 1 > WRAP_WIDTH) {\n lines.push(indent + line);\n line = word;\n continue;\n }\n\n line = line.length === 0 ? word : `${line} ${word}`;\n }\n\n if (line.length > 0) {\n lines.push(indent + line);\n }\n\n return lines;\n};\n\nconst COMPARATOR_SYMBOLS: Record<string, string> = {\n \"equals\": \"===\",\n \"greater-than\": \">\",\n \"greater-than-equals\": \">=\",\n \"less-than\": \"<\",\n \"less-than-equals\": \"<=\"\n};\n\nconst describeValue = (value: any): string => {\n if (value == null) {\n return \"?\";\n }\n\n if (value.k === \"raw\") {\n return typeof value.v === \"string\" ? `\"${value.v}\"` : String(value.v);\n }\n\n if (value.k === \"date\") {\n return value.v;\n }\n\n if (value.k === \"array\") {\n return `[${(value.v as unknown[]).map(describeValue).join(\", \")}]`;\n }\n\n return value.k === \"undefined\" ? \"undefined\" : String(value.v);\n};\n\n/** Renders a serialized expression back to something close to the source predicate. */\nconst describeExpression = (expression: any): string => {\n\n if (expression == null) {\n return \"?\";\n }\n\n if (expression.t === \"operator\") {\n return `${describeExpression(expression.left)} ${expression.operator} ${describeExpression(expression.right)}`;\n }\n\n if (expression.t === \"comparator\") {\n const left = describeExpression(expression.left);\n const right = describeExpression(expression.right);\n const symbol = COMPARATOR_SYMBOLS[expression.comparator];\n\n if (symbol == null) {\n return `${left}.${expression.comparator}(${right})${expression.negated === true ? \" === false\" : \"\"}`;\n }\n\n return `${left} ${expression.negated === true ? \"!==\" : symbol} ${right}`;\n }\n\n if (expression.t === \"property\") {\n return expression.path;\n }\n\n if (expression.t === \"value\") {\n return describeValue(expression.value);\n }\n\n return expression.t === \"empty\" ? \"(no filter)\" : \"(not parsable)\";\n};\n\nconst describeOption = (option: ExplainedOption): string => {\n const detail = option.detail;\n\n if (detail == null) {\n return \"\";\n }\n\n if (option.name === \"filter\") {\n return detail.expression == null\n ? String(detail.expressionUnavailable ?? \"\")\n : describeExpression(detail.expression);\n }\n\n if (option.name === \"sort\") {\n return `${detail.propertyName} ${detail.direction}`;\n }\n\n if (option.name === \"skip\" || option.name === \"take\") {\n return String(detail.value);\n }\n\n if (option.name === \"join\") {\n return `${detail.kind} → ${detail.outerKey} = ${detail.innerKey}`;\n }\n\n if (option.name === \"nearest\") {\n return `${detail.propertyName}, ${detail.count} nearest`;\n }\n\n if (option.name === \"map\" || option.name === \"group\") {\n const fields = detail.fields as { from: string, to: string }[];\n\n return fields.map(x => x.from === x.to ? x.from : `${x.from} → ${x.to}`).join(\", \");\n }\n\n return \"\";\n};\n\nconst formatStep = (step: ExecutionStep, lines: string[]) => {\n const reason = step.reason == null ? \"\" : ` [${step.reason}]`;\n\n lines.push(` STEP ${step.step} of ${step.of} — ${step.executedIn}${reason}`);\n lines.push(...wrap(step.description, \" \"));\n\n if (step.explanation != null) {\n lines.push(...wrap(step.explanation, \" \"));\n }\n\n lines.push(\"\");\n\n for (const option of step.options) {\n lines.push(` ${option.name.padEnd(OPTION_LABEL_WIDTH)} ${describeOption(option)}`.trimEnd());\n }\n\n for (const executed of step.executedQueries ?? []) {\n lines.push(\"\");\n lines.push(...executed.text.split(\"\\n\").map(line => ` ${line}`));\n\n if (executed.parameters != null && executed.parameters.length > 0) {\n lines.push(` parameters: ${JSON.stringify(executed.parameters)}`);\n }\n }\n\n if (step.executedQueriesUnsupported != null) {\n lines.push(\"\");\n lines.push(...wrap(step.executedQueriesUnsupported, \" \"));\n }\n\n lines.push(\"\");\n};\n\n/**\n * Renders an explanation for a terminal.\n *\n * The STEP headers carry the whole lesson: a reader who has never heard of pushdown still sees\n * that the statement in step 1 is not the entire query. Nobody should have to notice a missing\n * ORDER BY to work that out.\n */\nexport const formatExplanation = (explanation: QueryExplanation): string => {\n const { collection, database, summary, executionSteps } = explanation;\n const stepCount = `${executionSteps.length} ${executionSteps.length === 1 ? \"step\" : \"steps\"}`;\n const lines: string[] = [`${collection} · ${database} · ${stepCount}`, \"\"];\n\n for (const step of executionSteps) {\n formatStep(step, lines);\n }\n\n lines.push(...wrap(summary.explanation, \" \"));\n\n return lines.join(\"\\n\");\n};\n","import { Expression, Filter, ParamsFilter } from \"../../expressions\";\nimport { PropertyInfo, SchemaId } from \"../../schema\";\nimport { GenericFunction } from \"../../types\";\nimport type { JoinKeyReference, JoinKind } from \"./join\";\nimport type { QueryOptionsCollection } from \"./QueryOptionsCollection\";\n\nexport enum QueryOrdering {\n Descending = \"desc\",\n Ascending = \"asc\"\n}\n\n/**\n * Field mapping for a query result, including source and destination names and a getter function.\n */\nexport type QueryField = {\n sourceName: string,\n destinationName: string,\n isRename: boolean;\n property?: PropertyInfo<unknown>;\n getter: <T>(data: Record<string, unknown>) => T;\n};\n\nexport type QueryOptionExecutionTarget = \"database\" | \"memory\";\nexport type QueryOptionName = keyof QueryOptionValueMap<unknown>;\n\n/**\n * Why an option runs in memory rather than in the database.\n *\n * A code rather than a sentence, so a test can assert on it — the sentences live in\n * `MEMORY_EXECUTION_EXPLANATIONS`. Every cause is a ratchet, because `nextExecutionTarget`\n * never returns to `\"database\"`, so the code recorded is the FIRST cause and it stays on every\n * option after it. Reporting a later one would name a symptom of this one.\n */\nexport type MemoryExecutionReason =\n | \"not-parsable\"\n | \"unmapped-property\"\n | \"renamed-property\"\n | \"map-rename\"\n | \"after-nearest\"\n | \"after-join\"\n | \"cross-plugin-join\";\n\nexport type QueryOption<T, K extends QueryOptionName> = {\n name: QueryOptionName;\n value: QueryOptionValueMap<T>[K],\n target: QueryOptionExecutionTarget;\n /** Set only when `target` is `\"memory\"`. */\n reason?: MemoryExecutionReason;\n}\n\nexport type QueryOptionValueMap<T extends {}> = {\n skip: number;\n take: number;\n sort: { selector: GenericFunction<T, T[keyof T]>, direction: QueryOrdering, propertyName: string, property?: PropertyInfo<T> | null };\n map: { selector: GenericFunction<T, any>, fields: QueryField[] };\n group: { selector: GenericFunction<T, any>, key: QueryField, fields: QueryField[] };\n filter: { params?: {}, filter: ParamsFilter<T, {}> | Filter<T>, expression: Expression };\n /**\n * Similarity search: an ordering plus a limit, never a filter.\n *\n * `count` is part of the option rather than a separate `take` because the two are one\n * operation to a backend that can push this down — `ORDER BY ... LIMIT n` is what makes an\n * approximate index usable, and splitting them would order every row before limiting.\n */\n nearest: { selector: GenericFunction<T, T[keyof T]>, propertyName: string, property?: PropertyInfo<T> | null, vector: number[], count: number };\n /**\n * An equi-join against a second collection, interpreted by whoever receives it.\n *\n * A first-class query option rather than a datastore side-path: a SQL backend emits a real\n * `INNER JOIN`/`LEFT JOIN`, every other backend loads the rows it needs and the shared hash\n * join runs inside the plugin, and a cross-plugin join runs in the datastore's memory half.\n * All three produce the same pairs — see `specs/joins.md`.\n *\n * Serializable by construction: property paths and a schema id, never live rows, with any\n * filter's values travelling in its params object. That is what lets the whole option be\n * forwarded to a server once expression-tree serialization lands.\n */\n join: {\n kind: JoinKind;\n /** Resolved through `event.schemas`, which already carries every schema in the store. */\n innerSchemaId: SchemaId;\n outerKey: JoinKeyReference;\n innerKey: JoinKeyReference;\n /**\n * The inner side's own filters — INCLUDING its soft-delete scope and `.scope()`\n * filters. Every interpreter must apply these: it is the only place they exist, because\n * a join bypasses the inner collection's normal read path.\n */\n innerOptions: QueryOptionsCollection<any>;\n /**\n * Whether the two sides live on DIFFERENT plugin instances, in which case no plugin can\n * receive the option and the datastore is the interpreter.\n *\n * Decided by plugin instance identity at build time, never by comparing database names —\n * two plugins over one database are still two interpreters, and one name can front two\n * databases.\n */\n crossPlugin: boolean;\n /**\n * How many distinct outer keys are still worth turning into an `IN (...)` prefilter on the\n * inner read — the datastore's `semiJoinKeyThreshold`, default 500.\n *\n * Carried in the option because the decision is made where the join executes, which is\n * usually inside a plugin, and a plugin cannot see a datastore's configuration. A number\n * serializes; a reference to the store would not.\n *\n * Cost only. Above the threshold the inner side is read under its own scopes and the hash\n * join discards the surplus — the same answer by a slower route.\n */\n semiJoinKeyThreshold: number;\n };\n min: true; // True or not set\n max: true; // True or not set\n count: true; // True or not set\n sum: true; // True or not set\n distinct: true; // True or not set\n};\n\n/**\n * Sort specification for a query.\n */\nexport type QuerySort = { key: string, selector: (item: unknown) => unknown, direction: \"asc\" | \"desc\" };","export * from './explain';\nexport * from './formatExplanation';\nexport * from './join';\nexport * from './Query';\nexport * from './QueryOptionsCollection';\nexport * from './types';\nexport * from './similarity';","import { Expression, toStrictPredicate } from \"../../expressions\";\nimport { CompiledSchema } from \"../../schema\";\nimport { UnknownRecord } from \"../../utilities\";\nimport { JoinKeyReference } from \"../query/join\";\nimport { QueryOptionsCollection } from \"../query/QueryOptionsCollection\";\nimport { QueryOptionName, QueryOrdering } from \"../query/types\";\nimport { SerializedQueryOption } from \"./types\";\n\n/**\n * Which options can cross a wire, and how the rest are handled.\n *\n * Everything except `map` and `group`. Those two are defined BY a closure — the projection is the\n * option — and no data form of them exists to send. Nothing else needs its closure: a sort is a\n * property and a direction, a filter is an expression tree, `nearest` is a vector and a count.\n */\nconst SENDABLE: ReadonlySet<QueryOptionName> = new Set<QueryOptionName>([\n \"skip\", \"take\", \"sort\", \"filter\", \"nearest\", \"join\", \"count\", \"min\", \"max\", \"sum\", \"distinct\"\n]);\n\n/**\n * Splits options into the PREFIX that can be sent and the remainder that cannot.\n *\n * A prefix, not a filtered subset, and that is the whole correctness argument. Options are ordered,\n * and most are not idempotent: sending `count` while keeping `map` local would count unmapped rows,\n * and applying `take` on both sides would window twice. So the split stops at the first option that\n * cannot travel, and everything from there on runs where the closures are.\n *\n * It is the same shape as the database/memory split this composes with — one more cut of the same\n * ordered list, for one more reason.\n */\nexport const splitSendableOptions = <T>(options: QueryOptionsCollection<T>): {\n sendable: QueryOptionsCollection<T>;\n local: QueryOptionsCollection<T>;\n} => {\n const sendable = new QueryOptionsCollection<T>();\n const local = new QueryOptionsCollection<T>();\n\n let stopped = false;\n\n options.forEach(option => {\n if (stopped === false && SENDABLE.has(option.name) === false) {\n stopped = true;\n }\n\n (stopped ? local : sendable).add(option.name, option.value);\n });\n\n return { sendable, local };\n};\n\n/** The key's property path, which is what the receiver resolves against its own schema. */\nconst keyPath = (reference: JoinKeyReference) => reference.property?.id ?? reference.propertyName;\n\nexport const serializeQueryOptions = <T>(options: QueryOptionsCollection<T>): SerializedQueryOption[] => {\n const serialized: SerializedQueryOption[] = [];\n\n options.forEach(option => {\n const value = option.value as never as UnknownRecord;\n\n switch (option.name) {\n case \"skip\":\n case \"take\":\n serialized.push({ name: option.name, value: option.value as never as number });\n return;\n\n case \"sort\":\n serialized.push({\n name: \"sort\",\n value: {\n // The declared path, so the receiver can resolve its own property and rebuild\n // both the selector and the storage column name from it\n propertyName: (value.property as { id?: string } | null)?.id ?? String(value.propertyName),\n direction: value.direction as QueryOrdering\n }\n });\n return;\n\n case \"filter\": {\n const expression = value.expression as never as Expression;\n\n /**\n * A filter with no usable tree must not be SENT, and this is a hard error.\n *\n * `not-parsable` means the intent is unknown — the parser could not work out what the\n * predicate asks for. A receiver handed that has two options, and both are wrong: read\n * everything (returning rows the caller excluded) or return nothing (silently losing\n * them). Neither is a degradation worth accepting when the caller's own closure is\n * sitting right here and can answer correctly.\n *\n * In practice this is unreachable: `QueryOptionsCollection.add` targets an unparsable\n * filter at the MEMORY half, so it never reaches a plugin. The guard is here because\n * \"unreachable\" is a property of code that changes, and the failure it would let\n * through is silent.\n */\n if (Expression.isNotParsable(expression)) {\n throw new Error(\n \"Cannot send a filter whose expression could not be parsed: the receiver would have to guess whether to \" +\n \"return everything or nothing, and both answers are wrong. A filter like this belongs in the memory half, \" +\n \"where the caller's own predicate runs.\"\n );\n }\n\n serialized.push({ name: \"filter\", value: { expression: Expression.toJson(expression) } });\n return;\n }\n\n case \"nearest\":\n serialized.push({\n name: \"nearest\",\n value: {\n propertyName: (value.property as { id?: string } | null)?.id ?? String(value.propertyName),\n vector: value.vector as number[],\n count: value.count as number\n }\n });\n return;\n\n case \"join\": {\n const join = value as never as {\n kind: \"inner\" | \"left\";\n innerOptions: QueryOptionsCollection<unknown>;\n outerKey: JoinKeyReference;\n innerKey: JoinKeyReference;\n semiJoinKeyThreshold: number;\n innerCollectionName?: string;\n };\n\n serialized.push({\n name: \"join\",\n value: {\n kind: join.kind,\n // Resolved by the caller, which is the only place that can see the schema\n // collection the id refers to\n innerCollectionName: join.innerCollectionName ?? \"\",\n outerKeyPath: keyPath(join.outerKey),\n innerKeyPath: keyPath(join.innerKey),\n innerOptions: serializeQueryOptions(join.innerOptions),\n semiJoinKeyThreshold: join.semiJoinKeyThreshold\n }\n });\n return;\n }\n\n case \"count\":\n case \"min\":\n case \"max\":\n case \"sum\":\n case \"distinct\":\n serialized.push({ name: option.name, value: true });\n return;\n\n default:\n throw new Error(\n `Cannot serialize the '${option.name}' query option: it is defined by a function, which cannot cross a wire. ` +\n `Use splitSendableOptions so it runs where its closure is.`\n );\n }\n });\n\n return serialized;\n};\n\n/** How the receiver finds a collection it was sent the NAME of. */\nexport type SchemaResolver = (collectionName: string) => CompiledSchema<any> | null;\n\n/**\n * A filter the RECEIVER adds to every read of a collection, whatever the sender asked for.\n *\n * Returns `null` for a collection with nothing to add. See `createRequestHandler` for the policy\n * side; this is only how it reaches the options.\n */\nexport type ScopeProvider = (schema: CompiledSchema<any>) => Expression | null;\n\n/**\n * Rebuilds query options from their wire form, against the receiver's own schemas.\n *\n * The closures that were dropped are reconstructed here rather than sent:\n *\n * - a **sort selector** from its property, which is all `JsonTranslator.sort` reads;\n * - a **filter predicate** from its expression tree, via `toStrictPredicate` — which THROWS rather\n * than keeping a row it cannot judge, because on a receiver a filter that quietly stops filtering\n * returns rows the requester excluded.\n *\n * @throws when a named property or collection is not declared by the receiver's schemas. A payload\n * describing data this side does not have is a disagreement, and it has to be loud.\n */\nexport const deserializeQueryOptions = (\n serialized: SerializedQueryOption[],\n schema: CompiledSchema<any>,\n resolveSchema: SchemaResolver,\n /**\n * A receiver-side filter per collection, applied to this collection AND to every collection a\n * join reaches. Prepended, so it is ANDed with whatever the sender sent and there is no order of\n * options that removes it.\n */\n scopeFor?: ScopeProvider\n): QueryOptionsCollection<any> => {\n\n const options = new QueryOptionsCollection<any>();\n\n /**\n * FIRST, before anything the sender asked for.\n *\n * Position matters twice. It cannot be displaced by any option the sender chose, and being at\n * the front it is in the database half — so a backend pushes it down rather than the receiver\n * reading the whole collection and filtering afterwards.\n */\n const scope = scopeFor?.(schema) ?? null;\n\n if (scope != null) {\n options.add(\"filter\", {\n filter: toStrictPredicate(scope) as never,\n expression: scope,\n params: undefined\n } as never);\n }\n\n const propertyOf = (path: string) => {\n const property = schema.getProperty(path);\n\n if (property == null) {\n throw new Error(\n `Cannot deserialize a query: this schema does not declare the property it names. ` +\n `Property: ${path}, Collection: ${schema.collectionName}`\n );\n }\n\n return property;\n };\n\n for (const option of serialized) {\n switch (option.name) {\n case \"skip\":\n case \"take\":\n options.add(option.name, option.value as never);\n break;\n\n case \"sort\": {\n const property = propertyOf(option.value.propertyName);\n\n options.add(\"sort\", {\n selector: ((row: UnknownRecord) => property.getValue(row)) as never,\n direction: option.value.direction,\n propertyName: option.value.propertyName,\n property\n } as never);\n break;\n }\n\n case \"filter\": {\n const expression = Expression.fromJson(option.value.expression, schema);\n\n options.add(\"filter\", {\n filter: toStrictPredicate(expression) as never,\n expression,\n params: undefined\n } as never);\n break;\n }\n\n case \"nearest\": {\n const property = propertyOf(option.value.propertyName);\n\n options.add(\"nearest\", {\n selector: ((row: UnknownRecord) => property.getValue(row)) as never,\n propertyName: option.value.propertyName,\n property,\n vector: option.value.vector,\n count: option.value.count\n } as never);\n break;\n }\n\n case \"join\": {\n const innerSchema = resolveSchema(option.value.innerCollectionName);\n\n if (innerSchema == null) {\n throw new Error(\n `Cannot deserialize a join: this store has no collection named '${option.value.innerCollectionName}'.`\n );\n }\n\n options.add(\"join\", {\n kind: option.value.kind,\n innerSchemaId: innerSchema.id,\n outerKey: { propertyName: option.value.outerKeyPath, property: propertyOf(option.value.outerKeyPath) },\n innerKey: {\n propertyName: option.value.innerKeyPath,\n property: innerSchema.getProperty(option.value.innerKeyPath)\n },\n /**\n * The inner side is deserialized with the SAME scope provider, which is what\n * stops a join being a way around a scope: a sender that cannot read a\n * collection directly must not be able to read it by joining to it.\n */\n innerOptions: deserializeQueryOptions(option.value.innerOptions, innerSchema, resolveSchema, scopeFor),\n // False by construction: the receiver executes both sides against its own single\n // plugin, whatever the sender's topology was.\n crossPlugin: false,\n semiJoinKeyThreshold: option.value.semiJoinKeyThreshold\n } as never);\n break;\n }\n\n default:\n options.add(option.name, true as never);\n break;\n }\n }\n\n return options;\n};\n","import { BulkPersistChanges, BulkPersistResult } from \"../../collections\";\nimport { CompiledSchema } from \"../../schema\";\nimport { ReadonlySchemaCollection } from \"../../collections/ReadonlySchemaCollection\";\nimport { SchemaResolver } from \"./query\";\nimport { SerializedPersistRequest, SerializedResponse, SerializedSchemaChanges } from \"./types\";\n\n/**\n * Saves, in the form that survives a wire.\n *\n * Simpler than a query, because a change set holds no functions: adds, updates and removes are\n * entities, and an entity reaching a plugin has already been through `preprocess` — so it is in\n * STORAGE shape, where a Date is already an ISO string and a nested object is already whatever the\n * schema said to store. It is JSON by the time it gets here.\n *\n * Two things are deliberately left behind:\n *\n * - **Tags.** `SchemaPersistChanges.tags` is caller-side metadata for correlating a save with its\n * echo locally. The receiver has no use for it and no business seeing it.\n * - **Schema ids.** Collections are NAMED. An id is a hash of the schema's own shape, so it would\n * couple both sides to identical schema definitions; a name lets the receiver resolve its own.\n */\n\nexport const serializeBulkPersist = (\n changes: BulkPersistChanges,\n schemas: ReadonlySchemaCollection\n): SerializedPersistRequest => {\n\n const serialized: SerializedSchemaChanges[] = [];\n\n for (const [schemaId, schemaChanges] of changes) {\n if (schemaChanges.hasItems === false) {\n continue;\n }\n\n const schema = schemas.get(schemaId);\n\n if (schema == null) {\n throw new Error(`Cannot serialize a save: no schema is registered for the id it names. SchemaId: ${schemaId}`);\n }\n\n serialized.push({\n collectionName: schema.collectionName,\n adds: schemaChanges.adds as unknown[],\n updates: schemaChanges.updates.map(update => ({\n entity: update.entity,\n changeType: update.changeType,\n delta: update.delta,\n ...(update.concurrency != null && { concurrency: update.concurrency })\n })),\n removes: schemaChanges.removes as unknown[]\n });\n }\n\n return { kind: \"persist\", changes: serialized };\n};\n\n/**\n * Rebuilds a change set from its wire form, keyed by the RECEIVER's schema ids.\n *\n * @throws when a named collection is not one this store declares. A save aimed at data this side\n * does not have must not be silently dropped — the caller would be told it succeeded.\n */\nexport const deserializeBulkPersist = (\n request: SerializedPersistRequest,\n resolveSchema: SchemaResolver\n): { changes: BulkPersistChanges; schemas: CompiledSchema<any>[] } => {\n\n const changes = new BulkPersistChanges();\n const schemas: CompiledSchema<any>[] = [];\n\n for (const schemaChanges of request.changes) {\n const schema = resolveSchema(schemaChanges.collectionName);\n\n if (schema == null) {\n throw new Error(\n `Cannot apply a save: this store has no collection named '${schemaChanges.collectionName}'.`\n );\n }\n\n schemas.push(schema);\n\n const resolved = changes.resolve(schema.id);\n resolved.adds = schemaChanges.adds as never[];\n resolved.updates = schemaChanges.updates.map(update => ({\n entity: update.entity as never,\n changeType: update.changeType,\n delta: update.delta as never,\n ...(update.concurrency != null && { concurrency: update.concurrency })\n })) as never[];\n resolved.removes = schemaChanges.removes as never[];\n }\n\n return { changes, schemas };\n};\n\n/**\n * Serializes the ECHO of a save — the part the change tracker cannot do without.\n *\n * A save's result is not a receipt. It carries the rows as the database wrote them, including any\n * identity the database assigned, and the change tracker matches each one back to the addition that\n * produced it. Returning a count instead would leave every inserted entity without its key.\n */\nexport const serializePersistResult = (\n result: BulkPersistResult,\n schemas: ReadonlySchemaCollection\n): SerializedResponse => {\n\n const changes: Array<{ collectionName: string; adds: unknown[]; updates: unknown[]; removes: unknown[] }> = [];\n\n for (const [schemaId, schemaResult] of result) {\n const schema = schemas.get(schemaId);\n\n if (schema == null) {\n continue;\n }\n\n changes.push({\n collectionName: schema.collectionName,\n adds: schemaResult.adds as unknown[],\n updates: schemaResult.updates as unknown[],\n removes: schemaResult.removes as unknown[]\n });\n }\n\n return { ok: true, kind: \"persist\", changes };\n};\n\n/** Rebuilds a save's echo against the SENDER's schema ids, which is what its change tracker holds. */\nexport const deserializePersistResult = (\n response: Extract<SerializedResponse, { kind: \"persist\" }>,\n resolveSchema: SchemaResolver\n): BulkPersistResult => {\n\n const result = new BulkPersistResult();\n\n for (const schemaChanges of response.changes) {\n const schema = resolveSchema(schemaChanges.collectionName);\n\n if (schema == null) {\n throw new Error(\n `A save came back naming a collection this store does not declare: '${schemaChanges.collectionName}'.`\n );\n }\n\n const resolved = result.resolve(schema.id);\n resolved.adds = schemaChanges.adds as never[];\n resolved.updates = schemaChanges.updates as never[];\n resolved.removes = schemaChanges.removes as never[];\n }\n\n return result;\n};\n","import { ReadonlySchemaCollection } from \"../../collections/ReadonlySchemaCollection\";\nimport { Expression, Filter, ParamsFilter, toExpression, toStrictPredicate } from \"../../expressions\";\nimport { PluginEventResult, Result } from \"../../results\";\nimport { CompiledSchema } from \"../../schema\";\nimport { UnknownRecord, uuid } from \"../../utilities\";\nimport { IDbPlugin } from \"../types\";\nimport { ExecutedQuery } from \"../query/explain\";\nimport { Query } from \"../query/Query\";\nimport { deserializeBulkPersist, serializePersistResult } from \"./persist\";\nimport { deserializeQueryOptions, SchemaResolver, ScopeProvider } from \"./query\";\nimport { SerializedRequest, SerializedResponse } from \"./types\";\n\n/**\n * The receiving half: takes a serialized request, executes it, returns a serialized response.\n *\n * Deliberately not a server. It is one async function from JSON to JSON, with no notion of HTTP, so\n * the same handler sits behind Express, a Cloudflare Worker, a Lambda, a WebSocket message, or a\n * worker `postMessage`. Transport is the caller's business; this is the part that would otherwise be\n * rewritten per framework.\n *\n * ```ts\n * const handle = createRequestHandler({ plugin, schemas });\n *\n * app.post(\"/routier\", async (req, res) => res.json(await handle(req.body)));\n * ```\n *\n * ## Security is YOURS, and this gives you the two places to put it\n *\n * There is no built-in notion of a user, a tenant, a role or a token, and there should not be: this\n * library cannot know what your identities are or what they may see. What it can do is make sure\n * there is nowhere for a decision to be forgotten. Two hooks, and both receive a `context` you built\n * from the request:\n *\n * - **`authorize`** — may this caller do this at all? Called once per request, before anything is\n * deserialized or executed, with the action and every collection the request touches.\n * - **`scope`** — which ROWS may this caller see? A filter the receiver ANDs into every read of a\n * collection, and checks every written row against.\n *\n * With neither supplied, the endpoint answers anything for anyone. That is the correct default for a\n * function with no idea who is calling it — and the moment you name a context type, passing one\n * becomes required, so a policy cannot be half-wired.\n *\n * ```ts\n * const handle = createRequestHandler<{ tenantId: string }>({\n * plugin,\n * schemas,\n * authorize: ({ action, context }) => context.tenantId != null || \"not signed in\",\n * scope: ({ context }) => ({ filter: ([row, p]) => row.tenantId === p.tenantId, params: context }),\n * });\n *\n * app.post(\"/routier\", async (req, res) => {\n * const context = { tenantId: req.user?.tenantId }; // from the REQUEST, never from the body\n * res.json(await handle(req.body, context));\n * });\n * ```\n *\n * ## Errors are values\n *\n * A failure comes back as `{ ok: false, error }` rather than as a rejected promise, so a transport\n * cannot accidentally turn a query error into a 500 with no body. The caller decides the status.\n */\n\n/** What a hook is told about the request it is judging. */\nexport type RequestInfo<TContext> = {\n action: \"query\" | \"persist\" | \"destroy\";\n /** Every collection this request touches, including the inner side of any join. */\n collectionNames: string[];\n /** Whatever the transport built from the request — a user, a tenant, a token. Never the body. */\n context: TContext;\n /** The raw request, for a policy that needs to look closer. Treat it as caller-controlled input. */\n request: SerializedRequest;\n};\n\n/**\n * May this request proceed?\n *\n * `true` to allow. `false` or a string to refuse — a string becomes the error message, which is the\n * cheapest way to say WHY without inventing an error type. Throwing also refuses.\n *\n * Called once, before deserialization, so a refused request never reaches a schema or a plugin.\n */\nexport type AuthorizeHook<TContext> = (info: RequestInfo<TContext>) => boolean | string | Promise<boolean | string>;\n\n/** What a scope hook is asked. One collection at a time, since each may be scoped differently. */\nexport type ScopeInfo<TContext> = {\n collectionName: string;\n schema: CompiledSchema<any>;\n context: TContext;\n action: \"query\" | \"persist\";\n};\n\n/**\n * The rows of one collection this caller may touch, as a filter.\n *\n * Written exactly like a collection's own `.scope()` — a filter, optionally with params — so the same\n * expression is pushed into the database on reads and checked against each row on writes. Return\n * `null` for a collection this caller may see in full.\n *\n * ```ts\n * scope: ({ collectionName, context }) =>\n * collectionName === \"orders\"\n * ? { filter: ([row, p]) => row.tenantId === p.tenantId, params: { tenantId: context.tenantId } }\n * : null\n * ```\n */\nexport type ScopeHook<TContext> = (info: ScopeInfo<TContext>) =>\n | { filter: Filter<any> | ParamsFilter<any, any>; params?: {} }\n | null;\n\nexport type RequestHandlerOptions<TContext> = {\n /** The plugin that actually holds the data. Anything implementing `IDbPlugin`. */\n plugin: IDbPlugin;\n /** Every collection this endpoint will answer for. A name absent from here is refused. */\n schemas: ReadonlySchemaCollection;\n /** May this caller do this? See `AuthorizeHook`. Absent means yes, to everyone. */\n authorize?: AuthorizeHook<TContext>;\n /** Which rows may this caller touch? See `ScopeHook`. Absent means all of them. */\n scope?: ScopeHook<TContext>;\n /**\n * Whether a `destroy` request may drop the database. **Defaults to false.**\n *\n * `HttpTransportDbPlugin` never sends one, but an endpoint answers whatever arrives — and a\n * hand-written `{\"kind\":\"destroy\"}` would otherwise wipe the store for anyone who could reach\n * the route. Destroying a database is not something a remote caller should be able to ask for by\n * default, so it is opt-in and still passes through `authorize`.\n */\n allowDestroy?: boolean;\n};\n\nexport type RequestHandler<TContext> = (request: SerializedRequest, context: TContext) => Promise<SerializedResponse>;\n\n/** Every collection a request touches, joins included — what `authorize` is given. */\nconst collectionsIn = (request: SerializedRequest): string[] => {\n if (request.kind === \"destroy\") {\n return [];\n }\n\n if (request.kind === \"persist\") {\n return request.changes.map(change => change.collectionName);\n }\n\n const names = [request.collectionName];\n\n const walk = (options: typeof request.options) => {\n for (const option of options) {\n if (option.name === \"join\") {\n names.push(option.value.innerCollectionName);\n walk(option.value.innerOptions);\n }\n }\n };\n\n walk(request.options);\n\n return names;\n};\n\nexport const createRequestHandler = <TContext = void>(options: RequestHandlerOptions<TContext>): RequestHandler<TContext> => {\n const { plugin, schemas, authorize, scope, allowDestroy = false } = options;\n\n const byName = new Map<string, CompiledSchema<any>>();\n\n for (const [, schema] of schemas) {\n byName.set(schema.collectionName, schema as CompiledSchema<any>);\n }\n\n const resolveSchema: SchemaResolver = (collectionName) => byName.get(collectionName) ?? null;\n\n const failed = (error: unknown): SerializedResponse => ({\n ok: false,\n error: error instanceof Error ? error.message : String(error)\n });\n\n /**\n * Turns a scope hook's filter into an expression, once per collection per request.\n *\n * `toExpression` rather than only keeping the closure, because an expression is what a backend\n * can push down — a scope that could only run in memory would mean reading the whole collection\n * to hide most of it. A filter that cannot be parsed is REFUSED rather than silently degraded:\n * a scope is the boundary, and one that quietly stops applying is worse than an error.\n */\n const scopeExpressionFor = (schema: CompiledSchema<any>, context: TContext, action: \"query\" | \"persist\"): Expression | null => {\n if (scope == null) {\n return null;\n }\n\n const declared = scope({ collectionName: schema.collectionName, schema, context, action });\n\n if (declared == null) {\n return null;\n }\n\n const expression = toExpression(schema, declared.filter as never, declared.params as never);\n\n if (Expression.isNotParsable(expression)) {\n throw new Error(\n `The scope declared for '${schema.collectionName}' cannot be expressed as a filter, so it cannot be enforced. ` +\n `Scopes must be parseable — they are the boundary between callers, and one that cannot be applied must not be ignored.`\n );\n }\n\n return expression;\n };\n\n return async (request, context) => {\n try {\n if (request.kind === \"destroy\" && allowDestroy === false) {\n return failed(new Error(\n \"This endpoint does not allow destroy. Dropping the database is opt-in: pass allowDestroy to createRequestHandler if a remote caller really should be able to ask for it.\"\n ));\n }\n\n if (authorize != null) {\n const verdict = await authorize({\n action: request.kind,\n collectionNames: collectionsIn(request),\n context,\n request\n });\n\n if (verdict !== true) {\n return failed(new Error(typeof verdict === \"string\" ? verdict : \"Not authorized.\"));\n }\n }\n\n if (request.kind === \"query\") {\n const schema = resolveSchema(request.collectionName);\n\n if (schema == null) {\n return failed(new Error(`This endpoint has no collection named '${request.collectionName}'.`));\n }\n\n const queryOptions = deserializeQueryOptions(\n request.options,\n schema,\n resolveSchema,\n // Applied to the outer collection AND to every collection a join reaches, so a\n // join cannot be used to read around a scope\n (target) => scopeExpressionFor(target, context, \"query\")\n );\n\n const executedQueries: ExecutedQuery[] = [];\n\n return await new Promise<SerializedResponse>(resolve => {\n plugin.query({\n // `false`: nothing here attaches to a change tracker — the tracker lives on\n // the caller, on the other side of the wire.\n operation: new Query(queryOptions, schema, false),\n schemas: schemas as never,\n id: uuid(8),\n source: \"RequestHandler\",\n action: \"query\",\n explain: request.explain,\n executedQueries\n }, result => {\n if (result.ok === PluginEventResult.ERROR) {\n resolve(failed(result.error));\n return;\n }\n\n resolve({\n ok: true,\n kind: \"query\",\n value: result.data.value as unknown,\n // Only when asked, and only what the plugin reported. A plugin\n // that reported nothing sends nothing, and the caller marks the\n // remote step as not reported.\n ...(request.explain === true && executedQueries.length > 0 ? { executedQueries } : {})\n });\n });\n });\n }\n\n if (request.kind === \"persist\") {\n const { changes } = deserializeBulkPersist(request, resolveSchema);\n\n /**\n * A scope has to be enforced on WRITES too, and differently.\n *\n * On a read it narrows what comes back. On a write there is nothing to narrow — the\n * rows are supplied by the caller — so each one is CHECKED against the same\n * expression, and a single row outside the scope refuses the whole save. Without\n * this, a caller who can only read their own rows could still write somebody else's.\n *\n * All-or-nothing on purpose: a partial save would leave the caller believing the\n * rejected rows were stored.\n */\n for (const [schemaId, schemaChanges] of changes) {\n const schema = schemas.get(schemaId);\n\n if (schema == null) {\n continue;\n }\n\n const expression = scopeExpressionFor(schema as CompiledSchema<any>, context, \"persist\");\n\n if (expression == null) {\n continue;\n }\n\n const permitted = toStrictPredicate(expression);\n\n const rows = [\n ...schemaChanges.adds as UnknownRecord[],\n ...schemaChanges.updates.map(update => update.entity as UnknownRecord),\n ...schemaChanges.removes as UnknownRecord[]\n ];\n\n for (const row of rows) {\n if (permitted(row) === false) {\n return failed(new Error(\n `This save was refused: a row of '${schema.collectionName}' falls outside the scope allowed for this caller.`\n ));\n }\n }\n }\n\n return await new Promise<SerializedResponse>(resolve => {\n plugin.bulkPersist({\n operation: changes,\n schemas: schemas as never,\n id: uuid(8),\n source: \"RequestHandler\",\n action: \"persist\"\n }, result => {\n if (result.ok === Result.ERROR) {\n resolve(failed(result.error));\n return;\n }\n\n // A PARTIAL result carries data AND an error. Reported as a failure, because\n // the caller must not treat a half-applied save as a success.\n if (result.ok === Result.PARTIAL) {\n resolve(failed(result.error));\n return;\n }\n\n resolve(serializePersistResult(result.data, schemas));\n });\n });\n }\n\n return await new Promise<SerializedResponse>(resolve => {\n plugin.destroy({\n schemas: schemas as never,\n id: uuid(8),\n source: \"RequestHandler\",\n action: \"destroy\"\n }, result => {\n if (result.ok === PluginEventResult.ERROR) {\n resolve(failed(result.error));\n return;\n }\n\n resolve({ ok: true, kind: \"destroy\" });\n });\n });\n } catch (error) {\n return failed(error);\n }\n };\n};\n\n/** Re-exported so a caller can type its own scope provider without reaching for the query module. */\nexport type { ScopeProvider };\n","export * from './types';\nexport * from './query';\nexport * from './persist';\nexport * from './handler';\n","import { BulkPersistResult, SchemaCollection } from \"../collections\";\nimport { OptimisticConcurrencyError } from \"../errors\";\nimport { DbPluginBulkPersistEvent, DbPluginEvent, DbPluginQueryEvent, IDbPlugin, ITranslatedValue } from \".\";\nimport { Query } from \"./query/Query\";\nimport { PluginEventCallbackPartialResult, PluginEventCallbackResult } from \"../results\";\nimport { CompiledSchema, IdType, InferType, PropertyInfo, SchemaId, SchemaTypes } from \"../schema\";\n\n/**\n * Optimistic concurrency as a wrapper plugin — the whole opt-in is one wrap:\n *\n * ```ts\n * class Bank extends DataStore {\n * constructor() {\n * super(new ConcurrencyDbPlugin(new SqlitePlugin('bank.db')));\n * }\n * }\n * ```\n *\n * Nothing is declared on the schema and nothing on the collection builder: the plugin\n * maintains a hidden `__version` column in the SAME tables/records as the data, entirely\n * below the entity surface. Rows start at version 1; every update is applied ONLY IF the\n * stored version still matches what this store last read (and bumps it); a stale write\n * rejects the save with `OptimisticConcurrencyError` naming the rows instead of silently\n * overwriting another writer. Recovery is always: re-read, reapply, save again.\n *\n * ## How the hidden column exists without schema changes\n *\n * The wrapper hands the inner plugin an AUGMENTED VIEW of each compiled schema — the same\n * object via prototype delegation, with one synthetic `__version` property appended to\n * `properties`. That list is exactly what the storage plugins read to build DDL, INSERT\n * and SELECT column lists, so the column materializes and round-trips through completely\n * unmodified plugin code. Above the wrapper the real schema is untouched, and the\n * datastore's generated deserialize/enrich drop undeclared fields, so `__version` never\n * reaches an entity a caller holds.\n *\n * The synthetic property carries `from: '__version'` on purpose: EphemeralDataPlugin\n * deep-copies query results with `structuredClone` (rather than the generated clone, which\n * drops undeclared fields) when any property is renamed — which is what lets the hidden\n * column survive reads from the in-process plugins so this wrapper can observe it.\n *\n * ## What this store \"read\"\n *\n * `expected` is per store instance: the version this wrapper last saw for the row, from a\n * query result or a persist echo. A row updated WITHOUT ever being read through this store\n * (rare — an attach of a foreign instance) has no expected value and is written unchecked,\n * initializing its token; the row is protected from the next read on.\n *\n * ## Enforcement and limits\n *\n * The conditional check itself is performed by the INNER plugin via the\n * `EntityUpdateInfo.concurrency` contract — memory, file-system, sqlite and postgresql\n * enforce it (see specs/optimistic-concurrency.md for the not-yet list). Existing SQL\n * tables created before the wrapper was adopted lack the column and need\n * `ALTER TABLE ... ADD COLUMN \"__version\" <number type>` — new tables get it from the\n * augmented DDL automatically.\n */\nexport class ConcurrencyDbPlugin implements IDbPlugin {\n\n static readonly VERSION_COLUMN = \"__version\";\n\n private readonly plugin: IDbPlugin;\n /** Augmented schema views, one per schema — identity matters, so they are cached. */\n private readonly augmentedSchemas = new Map<SchemaId, CompiledSchema<any>>();\n /** collectionName -> rowId -> the version this store last observed for the row. */\n private readonly observedVersions = new Map<string, Map<IdType, number>>();\n\n constructor(plugin: IDbPlugin) {\n this.plugin = plugin;\n }\n\n get databaseName(): string {\n return this.plugin.databaseName;\n }\n\n query<TRoot extends {}, TShape extends any = TRoot>(event: DbPluginQueryEvent<TRoot, TShape>, done: PluginEventCallbackResult<ITranslatedValue<TShape>>): void {\n const schema = event.operation.schema;\n\n const augmentedEvent: DbPluginQueryEvent<TRoot, TShape> = {\n ...event,\n schemas: this.augmentSchemas(event.schemas),\n operation: new Query<TRoot, TShape>(\n event.operation.options,\n this.augment(schema),\n // Preserve the override rather than letting the getter re-derive it\n (event.operation as unknown as { enableChangeTrackingOverride?: boolean }).enableChangeTrackingOverride\n ),\n };\n\n this.plugin.query(augmentedEvent, result => {\n if (result.ok !== \"error\") {\n // Query rows are plugin-made copies, so the hidden column can be removed in\n // place after its value is recorded.\n this.captureAndStrip(schema, this.rowsOf(result.data), { strip: true });\n }\n\n done(result);\n });\n }\n\n bulkPersist(event: DbPluginBulkPersistEvent, done: PluginEventCallbackPartialResult<BulkPersistResult>): void {\n const schemaIds: SchemaId[] = [];\n\n for (const [schemaId, changes] of event.operation) {\n schemaIds.push(schemaId);\n\n if (changes == null || changes.hasItems === false) {\n continue;\n }\n\n const schema = event.schemas.get(schemaId);\n const versions = this.versionsFor(schema.collectionName);\n\n for (const add of changes.adds) {\n (add as Record<string, unknown>)[ConcurrencyDbPlugin.VERSION_COLUMN] = 1;\n }\n\n for (const update of changes.updates) {\n const entity = update.entity as Record<string, unknown>;\n const id = schema.getId(update.entity as InferType<{}>);\n const expected = versions.get(id);\n // An EMPTY delta means \"write the whole entity\" (the plugins' fallback);\n // adding the column would silently narrow the write to the token alone.\n const deltaCarriesColumns = Object.keys(update.delta as Record<string, unknown>).length > 0;\n\n if (typeof expected === \"number\") {\n entity[ConcurrencyDbPlugin.VERSION_COLUMN] = expected + 1;\n if (deltaCarriesColumns) {\n (update.delta as Record<string, unknown>)[ConcurrencyDbPlugin.VERSION_COLUMN] = expected + 1;\n }\n update.concurrency = { column: ConcurrencyDbPlugin.VERSION_COLUMN, expected };\n } else {\n // Never observed through this store — initialize the token, unchecked.\n entity[ConcurrencyDbPlugin.VERSION_COLUMN] = 1;\n if (deltaCarriesColumns) {\n (update.delta as Record<string, unknown>)[ConcurrencyDbPlugin.VERSION_COLUMN] = 1;\n }\n }\n }\n }\n\n const augmentedEvent: DbPluginBulkPersistEvent = {\n ...event,\n schemas: this.augmentSchemas(event.schemas),\n };\n\n this.plugin.bulkPersist(augmentedEvent, result => {\n if (result.ok === \"success\") {\n for (const schemaId of schemaIds) {\n const schema = event.schemas.get(schemaId);\n const buckets = result.data.get(schemaId);\n\n // Echoed rows can BE the stored records (the in-process plugins echo by\n // reference), so the hidden column is recorded but never deleted here —\n // the datastore's generated deserialize drops it before any caller sees\n // it, and deleting it would erase the stored token itself.\n this.captureAndStrip(schema, buckets.adds as unknown[], { strip: false });\n this.captureAndStrip(schema, buckets.updates as unknown[], { strip: false });\n\n for (const removed of buckets.removes as unknown[]) {\n this.forget(schema, removed);\n }\n }\n } else if (OptimisticConcurrencyError.is(result.error)) {\n // The expected values that lost the race are stale; drop them so the\n // caller's re-read re-arms the check with fresh observations.\n const conflicted = result.error as OptimisticConcurrencyError;\n const versions = this.observedVersions.get(conflicted.collectionName);\n\n if (versions != null) {\n for (const id of conflicted.conflicts) {\n versions.delete(id);\n }\n }\n }\n\n done(result);\n });\n }\n\n destroy(event: DbPluginEvent, done: PluginEventCallbackResult<never>): void {\n this.observedVersions.clear();\n this.plugin.destroy(event, done);\n }\n\n private versionsFor(collectionName: string) {\n let versions = this.observedVersions.get(collectionName);\n\n if (versions == null) {\n versions = new Map<IdType, number>();\n this.observedVersions.set(collectionName, versions);\n }\n\n return versions;\n }\n\n /** Extracts entity rows from a translated query result; scalars/aggregates have none. */\n private rowsOf(data: ITranslatedValue<unknown>): unknown[] {\n const value = (data as { value?: unknown }).value;\n\n if (Array.isArray(value)) {\n return value;\n }\n\n if (value != null && typeof value === \"object\") {\n return [value];\n }\n\n return [];\n }\n\n private captureAndStrip(schema: CompiledSchema<any>, rows: unknown[], options: { strip: boolean }) {\n const versions = this.versionsFor(schema.collectionName);\n\n for (const row of rows) {\n if (row == null || typeof row !== \"object\") {\n continue;\n }\n\n const record = row as Record<string, unknown>;\n const version = record[ConcurrencyDbPlugin.VERSION_COLUMN];\n\n if (typeof version === \"number\") {\n try {\n versions.set(schema.getId(record as InferType<{}>), version);\n } catch {\n // Projected rows may not carry the key; nothing to observe.\n }\n }\n\n if (options.strip) {\n delete record[ConcurrencyDbPlugin.VERSION_COLUMN];\n }\n }\n }\n\n private forget(schema: CompiledSchema<any>, row: unknown) {\n if (row == null || typeof row !== \"object\") {\n return;\n }\n\n try {\n this.observedVersions.get(schema.collectionName)?.delete(schema.getId(row as InferType<{}>));\n } catch {\n // Removals without a resolvable id have nothing recorded.\n }\n }\n\n /** A SchemaCollection whose every schema is the augmented view. */\n private augmentSchemas(schemas: SchemaCollection): SchemaCollection {\n const augment = (schema: CompiledSchema<any>) => this.augment(schema);\n\n return new Proxy(schemas, {\n get(target, property, receiver) {\n if (property === \"get\") {\n return (id: SchemaId) => augment(target.get(id));\n }\n\n return Reflect.get(target, property, receiver);\n },\n });\n }\n\n /**\n * The augmented view of a compiled schema: the same object via prototype delegation,\n * with a synthetic `__version` property appended to `properties`. Everything else —\n * generated functions, ids, id properties — delegates to the real schema.\n */\n private augment<T extends {}>(schema: CompiledSchema<T>): CompiledSchema<T> {\n const cached = this.augmentedSchemas.get(schema.id);\n\n if (cached != null) {\n return cached as CompiledSchema<T>;\n }\n\n const synthetic = {\n name: ConcurrencyDbPlugin.VERSION_COLUMN,\n parent: null,\n type: SchemaTypes.Number,\n isKey: false,\n isIdentity: false,\n isDistinct: false,\n isNullable: true,\n isOptional: false,\n isReadonly: false,\n isUnmapped: false,\n isConcurrency: false,\n indexes: [] as string[],\n tags: [] as string[],\n literals: [] as unknown[],\n // Non-null `from` makes EphemeralDataPlugin structural-copy query results\n // (the generated clone would drop the hidden column before this wrapper\n // could observe it). The resolved name is unchanged.\n from: ConcurrencyDbPlugin.VERSION_COLUMN,\n valueSerializer: null,\n valueDeserializer: null,\n injected: null,\n defaultValue: null,\n getResolvedName: () => ConcurrencyDbPlugin.VERSION_COLUMN,\n getValue: (entity: Record<string, unknown>) => entity[ConcurrencyDbPlugin.VERSION_COLUMN],\n } as unknown as PropertyInfo<T>;\n\n const view = Object.create(schema) as CompiledSchema<T> & { properties: PropertyInfo<T>[] };\n Object.defineProperty(view, \"properties\", {\n value: [...schema.properties, synthetic],\n enumerable: true,\n });\n\n this.augmentedSchemas.set(schema.id, view);\n\n return view;\n }\n}\n","import { assertIsNotNull } from '../assertions';\nimport { OptimisticConcurrencyError } from '../errors';\nimport { BulkPersistResult, SchemaPersistChanges } from '../collections';\nimport { WorkPipeline } from '../pipeline';\nimport { DbPluginBulkPersistEvent, DbPluginEvent, DbPluginQueryEvent, distinctJoinKeys, IDbPlugin, ITranslatedValue, JoinInnerSide, JsonTranslator } from '.';\nimport { PluginEventCallbackPartialResult, PluginEventCallbackResult, PluginEventResult, Result } from '../results';\nimport { CompiledSchema, IdType, InferCreateType } from '../schema';\nimport { isComparatorExpression, isPropertyExpression, isValueExpression } from '../assertions';\nimport { DeepPartial } from '../types';\nimport { MemoryDataCollection } from '../collections/MemoryDataCollection';\nimport { UnknownRecord } from '../utilities';\n\n/**\n * Extracts the key value from a parsed filter expression when the whole filter\n * is a single non-negated equality on the schema's key property. Returns null\n * for anything else — compound filters, transformed properties, or filters that\n * could not be parsed.\n */\nconst getKeyEqualityValue = (expression: unknown): { value: IdType } | null => {\n\n // Type guards over the `type` discriminant, not instanceof — expression\n // instances can originate from a different bundled copy of the classes\n if (!isComparatorExpression(expression)) {\n return null;\n }\n\n if (expression.comparator !== \"equals\" || expression.negated === true) {\n return null;\n }\n\n const { left, right } = expression;\n\n if (!isPropertyExpression(left) || !isValueExpression(right)) {\n return null;\n }\n\n if (left.property.isKey !== true || left.transformer != null || right.value == null) {\n return null;\n }\n\n return { value: right.value as IdType };\n}\n\nexport abstract class EphemeralDataPlugin implements IDbPlugin {\n\n protected readonly _databaseName: string;\n\n constructor(databaseName: string) {\n this._databaseName = databaseName;\n }\n\n /**\n * See `IDbPlugin.databaseName`. A getter rather than the field itself so a subclass whose\n * database is identified by more than a name can widen it — `FileSystemPlugin` returns the\n * resolved file path, because one name in two directories is two databases.\n */\n get databaseName(): string {\n return this._databaseName;\n }\n\n protected abstract resolveCollection<TEntity extends {}>(schema: CompiledSchema<TEntity>): MemoryDataCollection;\n\n /**\n * All-or-nothing across every collection in the save.\n *\n * The naive shape — validate/apply/save one schema at a time — leaks partial saves:\n * a conflict in the SECOND collection left the first collection's changes applied\n * (measured in the finance stress app as one orphan ledger row per conflict). So the\n * work is phased: every collection loads and validates BEFORE anything is applied,\n * mutations apply with an undo log, and a failure anywhere reverts the memory state\n * (and re-saves any files already written) so the caller sees a save that did nothing.\n *\n * The remaining honesty gap is crash-safety across FILES: a process dying between two\n * file writes can leave disk partially updated. Guarding that needs a journal, which\n * a memory-first plugin does not pretend to have.\n */\n bulkPersist(event: DbPluginBulkPersistEvent, done: PluginEventCallbackPartialResult<BulkPersistResult>) {\n try {\n const bulkPersistResult = event.operation.toResult();\n const schemas = event.schemas;\n\n type StagedSchema = {\n schema: CompiledSchema<UnknownRecord>;\n collection: MemoryDataCollection;\n changes: SchemaPersistChanges<Record<string, unknown>>;\n result: ReturnType<BulkPersistResult[\"get\"]>;\n };\n\n const staged: StagedSchema[] = [];\n\n for (const [schemaId, changes] of event.operation) {\n if (!changes.hasItems) {\n continue;\n }\n\n const schema = schemas.get(schemaId);\n assertIsNotNull(schema);\n\n staged.push({\n schema: schema as CompiledSchema<UnknownRecord>,\n collection: this.resolveCollection(schema),\n changes: changes as SchemaPersistChanges<Record<string, unknown>>,\n result: bulkPersistResult.get(schemaId),\n });\n }\n\n if (staged.length === 0) {\n done(PluginEventResult.success(event.id, bulkPersistResult));\n return;\n }\n\n const pipeline = new WorkPipeline();\n\n // Phase 1 — load every collection that needs its stored data (updates/removes,\n // and any conditional update), before anything is validated or applied.\n //\n // An ADD-ONLY batch is skipped: an add needs no prior state, and for the memory\n // backing this class was written against, loading is free anyway.\n //\n // ⚠ SUBCLASSES THAT PERSIST WHOLE COLLECTIONS MUST HYDRATE IN `save()`.\n // If `save()` serializes `this.records` over the entire stored value — a JSON\n // file, one localStorage key, a blob — then a collection instance that has\n // never loaded holds only this batch's adds, and writing it DELETES everything\n // previously persisted. The skip above means `save()` cannot assume `load()`\n // ran. Hydrate first (load-once, then `addIfAbsent` so stored rows never\n // clobber pending mutations); `FileSystemDbCollection.save` and\n // `BrowserStorageCollection.save` both do exactly that.\n //\n // This has now been a data-loss defect twice — known-defects #18\n // (file-system) and #30 (browser-storage).\n for (const { collection, changes } of staged) {\n if (changes.updates.length === 0 && changes.removes.length === 0) {\n continue;\n }\n\n pipeline.pipe((d) => {\n collection.load(readResult => {\n if (readResult.ok === Result.ERROR) {\n d(readResult);\n return;\n }\n d(Result.success());\n });\n });\n }\n\n // Phase 2 — validate everything, then apply everything, then save everything.\n pipeline.pipe((d) => {\n try {\n // Validate: optimistic-concurrency checks for EVERY collection run\n // before ANY collection is touched, so a conflict rejects the whole\n // save with nothing written anywhere.\n for (const { schema, collection, changes } of staged) {\n const conflicts: IdType[] = [];\n\n for (const { entity, concurrency } of changes.updates) {\n if (concurrency == null) {\n continue;\n }\n\n const id = schema.getId(entity as never);\n const stored = collection.getByIds([id]) as Record<string, unknown> | null;\n\n // A missing row is not a token conflict — it falls through\n // to the same no-op an unconditional update would be.\n if (stored != null && stored[concurrency.column] !== concurrency.expected) {\n conflicts.push(id);\n }\n }\n\n if (conflicts.length > 0) {\n d(Result.error(new OptimisticConcurrencyError(schema.collectionName, conflicts)));\n return;\n }\n }\n\n // Apply, recording the inverse of every mutation. The in-memory maps\n // make undo exact: an add is removed, an update or remove restores the\n // captured prior record.\n const undo: (() => void)[] = [];\n\n const revert = () => {\n for (let i = undo.length - 1; i >= 0; i--) {\n undo[i]();\n }\n };\n\n try {\n for (const { schema, collection, changes, result } of staged) {\n const { adds, updates, removes } = changes;\n\n result.adds = Array.from({ length: adds.length });\n result.updates = Array.from({ length: updates.length });\n result.removes = Array.from({ length: removes.length });\n\n for (let j = 0; j < adds.length; j++) {\n const item = adds[j];\n collection.add(item);\n undo.push(() => collection.remove(item));\n result.adds[j] = item as DeepPartial<InferCreateType<UnknownRecord>>;\n }\n\n for (let j = 0; j < updates.length; j++) {\n const item = updates[j].entity;\n const prior = collection.getByIds(schema.getIds(item as never)) as Record<string, unknown> | undefined;\n collection.update(item);\n undo.push(prior != null ? () => collection.update(prior) : () => collection.remove(item));\n result.updates[j] = item;\n }\n\n for (let j = 0; j < removes.length; j++) {\n const item = removes[j];\n const prior = collection.getByIds(schema.getIds(item as never)) as Record<string, unknown> | undefined;\n collection.remove(item);\n if (prior != null) {\n undo.push(() => collection.update(prior));\n }\n result.removes[j] = item;\n }\n }\n } catch (applyError) {\n revert();\n d(Result.error(applyError));\n return;\n }\n\n // Save every collection. A failure reverts the memory state and\n // re-saves the files already written so disk follows it back.\n const saveNext = (index: number) => {\n if (index >= staged.length) {\n d(Result.success());\n return;\n }\n\n staged[index].collection.save(saveResult => {\n if (saveResult.ok === Result.ERROR) {\n revert();\n\n const resaveNext = (k: number) => {\n if (k >= index) {\n d(saveResult);\n return;\n }\n\n staged[k].collection.save(() => resaveNext(k + 1));\n };\n\n resaveNext(0);\n return;\n }\n\n saveNext(index + 1);\n });\n };\n\n saveNext(0);\n } catch (e) {\n d(Result.error(e));\n }\n });\n\n pipeline.filter((result) => {\n if (result.ok === Result.ERROR) {\n done(PluginEventResult.error(event.id, result.error));\n return;\n }\n done(PluginEventResult.success(event.id, bulkPersistResult));\n });\n } catch (e: any) {\n done(PluginEventResult.error(event.id, e));\n }\n }\n\n /**\n * Loads the inner side of a join, when the query carries one.\n *\n * This is the whole of \"interpretation 2\" for the ephemeral family — memory, file-system and\n * browser-storage all reach the inner collection the same way they reach the outer one, so\n * the wiring lives here once rather than in each subclass. The shared hash join in\n * `JsonTranslator.join` does everything after it.\n *\n * `load()` is called on the inner collection too: a durable subclass has nothing in memory\n * until it reads, and a join that skipped it would return no pairs on the first query after\n * a restart — an empty result, not an error.\n *\n * The rows are CLONED, like the outer side's are. Deserialization builds a new object for the\n * entity and its nested objects, but an array property can come through by reference — and\n * here that reference is the one this plugin's own storage holds, so a caller appending to a\n * joined row's array would be editing the database. The outer path has always cloned for this\n * reason; the inner path is the same read.\n *\n * @param outerKeys The distinct keys the outer rows actually hold — the semi-join prefilter.\n * Rows whose key is not among them cannot pair with anything, so they are skipped before the\n * clone rather than after the hash join, which is where the saving is. `null` means the outer\n * side had more distinct keys than `semiJoinKeyThreshold`, so every inner row is taken and the\n * join discards the surplus. Same pairs either way.\n */\n private resolveJoinInnerSide<TEntity extends {}, TShape>(\n event: DbPluginQueryEvent<TEntity, TShape>,\n outerKeys: ReadonlySet<unknown> | null,\n done: (result: { ok: \"success\", innerSide?: JoinInnerSide } | { ok: \"error\", error: unknown }) => void\n ) {\n const joinOption = event.operation.options.getLast(\"join\");\n\n if (joinOption == null) {\n done({ ok: \"success\" });\n return;\n }\n\n const innerSchema = event.schemas.get(joinOption.value.innerSchemaId);\n\n if (innerSchema == null) {\n done({\n ok: \"error\",\n error: new Error(`Cannot join: the inner collection's schema is not registered in this store. SchemaId: ${joinOption.value.innerSchemaId}`)\n });\n return;\n }\n\n const innerCollection = this.resolveCollection(innerSchema);\n\n innerCollection.load(r => {\n if (r.ok === Result.ERROR) {\n done({ ok: \"error\", error: r.error });\n return;\n }\n\n const cloneRecord = this.recordCloner(innerSchema);\n const innerRows: Record<string, unknown>[] = [];\n\n // Records are held in STORAGE shape, so the key is read by its resolved column name.\n const innerKey = joinOption.value.innerKey;\n const keyColumn = innerKey.property?.getResolvedName() ?? innerKey.propertyName;\n\n for (const record of innerCollection.values()) {\n if (outerKeys != null && outerKeys.has(record[keyColumn]) === false) {\n continue;\n }\n\n innerRows.push(cloneRecord(record));\n }\n\n const narrowing = outerKeys == null ? \"full scan\" : `narrowed by ${outerKeys.size} outer ${outerKeys.size === 1 ? \"key\" : \"keys\"}`;\n\n event.executedQueries.push({\n text: `${innerSchema.collectionName}: scanned ${innerRows.length} in-memory ${innerRows.length === 1 ? \"record\" : \"records\"} for join inner side (${narrowing})`\n });\n\n done({ ok: \"success\", innerSide: { innerSchema, innerRows } });\n });\n }\n\n /**\n * How to copy a stored record of this schema.\n *\n * Stored records use the storage shape (`from` names). `schema.clone` reads IN-MEMORY property\n * names and would silently drop renamed fields, so a schema with renames uses the cloner\n * generated against the storage shape instead. Both are generated code; the renamed case used\n * to fall back to `structuredClone`, which is roughly an order of magnitude slower and was paid\n * on EVERY read of EVERY schema that renames a property.\n */\n private recordCloner(schema: CompiledSchema<any>) {\n const hasRenamedProperties = schema.properties.some(property => property.from != null);\n\n return (hasRenamedProperties ? schema.cloneStorage : schema.clone) as (record: Record<string, unknown>) => Record<string, unknown>;\n }\n\n query<TEntity extends {}, TShape extends any = TEntity>(event: DbPluginQueryEvent<TEntity, TShape>, done: PluginEventCallbackResult<ITranslatedValue<TShape>>): void {\n this._query(event, done);\n }\n\n private _query<TEntity extends {}, TShape extends any = TEntity>(event: DbPluginQueryEvent<TEntity, TShape>, done: PluginEventCallbackResult<ITranslatedValue<TShape>>): void {\n try {\n const operation = event.operation;\n const schema = operation.schema;\n const collection = this.resolveCollection(schema);\n\n const cloneRecord = this.recordCloner(schema);\n\n collection.load(r => {\n if (r.ok === Result.ERROR) {\n done(PluginEventResult.error(event.id, r.error));\n return;\n }\n\n const orderedOptions: { name: string, value: any }[] = [];\n operation.options.forEach(o => orderedOptions.push(o));\n\n let leadingFilterCount = 0;\n\n while (leadingFilterCount < orderedOptions.length && orderedOptions[leadingFilterCount].name === \"filter\") {\n leadingFilterCount++;\n }\n\n // Key-equality fast path: when a leading filter's parsed expression pins\n // the key property to a single value, resolve that record directly from\n // the collection instead of scanning everything\n let source: Record<string, unknown>[] | null = null;\n\n if (schema.idProperties.length === 1) {\n for (let i = 0; i < leadingFilterCount; i++) {\n const id = getKeyEqualityValue(orderedOptions[i].value.expression);\n\n if (id == null) {\n continue;\n }\n\n const found = collection.getByIds([id.value]);\n source = found == null ? [] : [found];\n break;\n }\n }\n\n // Apply the leading filter options against the raw records before cloning\n // so only surviving rows pay the clone cost. Filter predicates are pure,\n // so re-running them inside translate() is a no-op pass over the survivors.\n //\n // Filter and clone are FUSED into one pass, and the unfiltered case iterates\n // the collection instead of spreading it into an array. The staged form walked\n // the collection up to four times and allocated a full-size array at each step.\n const leadingFilters: { filter: (arg: any) => unknown, params: unknown | null }[] = [];\n\n for (let i = 0; i < leadingFilterCount; i++) {\n const value = orderedOptions[i].value;\n\n if (value.filter == null) {\n continue;\n }\n\n leadingFilters.push({ filter: value.filter, params: value.params ?? null });\n }\n\n const filterCount = leadingFilters.length;\n const cloned: Record<string, unknown>[] = [];\n\n for (const record of (source ?? collection.values())) {\n let kept = true;\n\n for (let i = 0; i < filterCount; i++) {\n const { filter, params } = leadingFilters[i];\n\n // Truthiness, not === true: Array.prototype.filter keeps a row on any\n // truthy return, and these predicates are generated code that returns\n // whatever the expression evaluated to.\n if (!(params == null ? filter(record) : filter([record, params]))) {\n kept = false;\n break;\n }\n }\n\n if (kept === false) {\n continue;\n }\n\n cloned.push(cloneRecord(record));\n }\n\n /**\n * The inner side is loaded LAST, once the outer rows are known.\n *\n * That ordering is the whole semi-join: the outer keys are what narrow the inner\n * read, and they do not exist until the outer filters have run. Reading the inner\n * side first — which is what this did before — means loading and cloning a whole\n * collection to pair it with three rows.\n *\n * `cloned` is in storage shape, so the keys are read by resolved column name.\n */\n // No statement to quote — an ephemeral store walks its own records. Said\n // plainly so `.explain()` does not leave a reader wondering whether the\n // plugin simply failed to report. Before the inner side, to match execution order.\n event.executedQueries.push({\n text: `${operation.schema.collectionName}: scanned ${cloned.length} in-memory ${cloned.length === 1 ? \"record\" : \"records\"}`\n });\n\n const joinOption = operation.options.getLast(\"join\");\n const outerKeys = joinOption == null\n ? null\n : distinctJoinKeys(cloned, joinOption.value.outerKey, joinOption.value.semiJoinKeyThreshold, { storageShape: true });\n\n this.resolveJoinInnerSide(event, outerKeys, joinResult => {\n if (joinResult.ok === \"error\") {\n done(PluginEventResult.error(event.id, joinResult.error));\n return;\n }\n\n try {\n const translator = new JsonTranslator<TEntity, TShape>(operation, joinResult.innerSide);\n\n done(PluginEventResult.success(event.id, translator.translate(cloned)));\n } catch (e) {\n done(PluginEventResult.error(event.id, e));\n }\n });\n });\n } catch (e) {\n done(PluginEventResult.error(event.id, e));\n }\n }\n\n abstract destroy(event: DbPluginEvent, done: PluginEventCallbackResult<never>): void;\n}","import { BulkPersistResult } from \"../collections\";\nimport { PluginEventCallbackPartialResult, PluginEventCallbackResult, PluginEventResult } from \"../results\";\nimport { ITranslatedValue } from \"./translators\";\nimport { DbPluginBulkPersistEvent, DbPluginEvent, DbPluginQueryEvent, IDbPlugin } from \"./types\";\n\n/**\n * Retries a failed READ, and never a write.\n *\n * ## Why reads only\n *\n * A read is idempotent by construction: running the same query twice asks the same question\n * and changes nothing, so a second attempt is free apart from latency. That is what makes a\n * blanket retry safe here, and it is why this wrapper does not need to know which errors are\n * transient — see `shouldRetry`.\n *\n * A save is not. `bulkPersist` is a batch of adds, updates and removes, and a failure gives no\n * general way to know how much of it landed: a backend without atomic batches may have applied\n * part of it, and a retry then re-applies what already succeeded. Adds are the sharpest case —\n * an identity is assigned by the database, so a repeated INSERT does not collide, it\n * DUPLICATES. Rows appear that no caller asked for, no error is reported, and the change\n * tracker records a successful save.\n *\n * Retrying a write safely would need the write to carry an idempotency key the backend\n * deduplicates on, which is a property of a backend rather than something a wrapper can add.\n * So this refuses to guess, and a failed save is surfaced for the caller to decide about.\n *\n * ```ts\n * const store = new MyStore(new RetryDbPlugin(new SomeDbPlugin(...), { attempts: 3 }));\n * ```\n */\n\nexport type RetryDbPluginOptions = {\n /**\n * Total attempts, including the first. Default 3, minimum 1.\n *\n * \"Attempts\" rather than \"retries\" because off-by-one here is a real cost — the difference\n * between three calls and four against a struggling backend.\n */\n attempts?: number;\n /**\n * Milliseconds to wait before attempt `attempt` (2 for the first retry).\n *\n * Default is exponential — 50ms, 100ms, 200ms — with no jitter. Jitter matters when many\n * clients retry in lockstep after a shared outage, and a caller with that problem knows it\n * and can supply a delay; adding randomness by default would make tests non-deterministic\n * for everyone else.\n */\n delayMs?: (attempt: number) => number;\n /**\n * Whether an error is worth another attempt. Default: every error is.\n *\n * That default is deliberate and only defensible because this retries reads alone. A\n * wrapper cannot know which of a backend's errors are transient without naming that\n * backend, and guessing wrong in the cautious direction means not retrying the failure the\n * caller installed this for. Retrying a permanent error instead costs a bounded amount of\n * latency and nothing else.\n *\n * Supply this to narrow it — a syntax error in a filter will never succeed on a second try.\n */\n shouldRetry?: (error: unknown, attempt: number) => boolean;\n};\n\nconst DEFAULT_ATTEMPTS = 3;\nconst defaultDelay = (attempt: number) => 50 * Math.pow(2, attempt - 2);\n\nexport class RetryDbPlugin implements IDbPlugin {\n\n private readonly plugin: IDbPlugin;\n private readonly attempts: number;\n private readonly delayMs: (attempt: number) => number;\n private readonly shouldRetry: (error: unknown, attempt: number) => boolean;\n\n constructor(plugin: IDbPlugin, options: RetryDbPluginOptions = {}) {\n this.plugin = plugin;\n // Floored at 1: zero attempts would never call the inner plugin and would report a\n // failure that never happened.\n this.attempts = Math.max(1, options.attempts ?? DEFAULT_ATTEMPTS);\n this.delayMs = options.delayMs ?? defaultDelay;\n this.shouldRetry = options.shouldRetry ?? (() => true);\n }\n\n get databaseName(): string {\n return this.plugin.databaseName;\n }\n\n query<TRoot extends {}, TShape extends any = TRoot>(\n event: DbPluginQueryEvent<TRoot, TShape>,\n done: PluginEventCallbackResult<ITranslatedValue<TShape>>\n ): void {\n this.attempt(event, done, 1);\n }\n\n /**\n * One attempt, scheduling the next on failure.\n *\n * Recursive rather than a loop because the inner plugin is callback-based: there is no\n * promise to await, and wrapping each attempt in one would change when errors surface.\n */\n private attempt<TRoot extends {}, TShape>(\n event: DbPluginQueryEvent<TRoot, TShape>,\n done: PluginEventCallbackResult<ITranslatedValue<TShape>>,\n attempt: number\n ): void {\n this.plugin.query<TRoot, TShape>(event, result => {\n\n if (result.ok !== PluginEventResult.ERROR) {\n done(result);\n return;\n }\n\n const isLastAttempt = attempt >= this.attempts;\n\n if (isLastAttempt || this.shouldRetry(result.error, attempt) === false) {\n // The error from the LAST attempt, not the first. It is the most recent state\n // of the world, and a caller comparing two failures wants the newer one.\n done(result);\n return;\n }\n\n const delay = this.delayMs(attempt + 1);\n\n if (delay <= 0) {\n this.attempt(event, done, attempt + 1);\n return;\n }\n\n setTimeout(() => this.attempt(event, done, attempt + 1), delay);\n });\n }\n\n bulkPersist(\n event: DbPluginBulkPersistEvent,\n done: PluginEventCallbackPartialResult<BulkPersistResult>\n ): void {\n // Straight through. See the note on this class: a partly-applied save cannot be\n // repeated safely, and a duplicated add is worse than a surfaced error.\n this.plugin.bulkPersist(event, done);\n }\n\n destroy(event: DbPluginEvent, done: PluginEventCallbackResult<never>): void {\n // Not retried either. Destroy is usually irreversible, and a second attempt against a\n // database the first one already removed reports a failure for work that succeeded.\n this.plugin.destroy(event, done);\n }\n}\n","import { BulkPersistResult } from \"../collections\";\nimport { PluginEventCallbackPartialResult, PluginEventCallbackResult } from \"../results\";\nimport { ITranslatedValue } from \"./translators\";\nimport { DbPluginBulkPersistEvent, DbPluginEvent, DbPluginQueryEvent, IDbPlugin } from \"./types\";\nimport { logger } from \"../utilities\";\n\n/**\n * Measures every operation an inner plugin performs and hands one event per call to a sink.\n *\n * ```ts\n * const store = new MyStore(new TelemetryDbPlugin(new SomeDbPlugin(...)));\n * ```\n */\n\nexport type TelemetryEvent = {\n operation: \"query\" | \"bulkPersist\" | \"destroy\";\n /** `id` of the plugin event that produced this measurement. */\n eventId: string;\n /** The class/component that triggered the operation (`event.source`). */\n source: string;\n /** Collection names involved, from `event.schemas`. */\n schemas: string[];\n durationMs: number;\n ok: \"success\" | \"partial\" | \"error\";\n /** Present when ok is \"error\" or \"partial\". */\n error?: unknown;\n};\n\nexport type TelemetrySink = (e: TelemetryEvent) => void;\n\nexport type TelemetryDbPluginOptions = {\n /** Where events go. Default: `loggerSink()`. */\n onEvent?: TelemetrySink;\n};\n\n/** Default sink: writes through the levelled logger, so ROUTIER_LOG_LEVEL governs it. */\nexport const loggerSink = (): TelemetrySink => e => {\n const line = `[routier] ${e.operation} ${e.schemas.join(\",\")} ${e.durationMs.toFixed(1)}ms`;\n\n if (e.ok === \"error\") {\n logger.error(line, e.error);\n return;\n }\n\n logger.info(line);\n};\n\n/** Pushes every event into `into`. For tests and custom buffering. */\nexport const collectingSink = (into: TelemetryEvent[]): TelemetrySink => e => {\n into.push(e);\n};\n\nexport class TelemetryDbPlugin implements IDbPlugin {\n\n private readonly plugin: IDbPlugin;\n private readonly onEvent: TelemetrySink;\n\n constructor(plugin: IDbPlugin, options: TelemetryDbPluginOptions = {}) {\n this.plugin = plugin;\n this.onEvent = options.onEvent ?? loggerSink();\n }\n\n get databaseName(): string {\n return this.plugin.databaseName;\n }\n\n query<TRoot extends {}, TShape extends any = TRoot>(\n event: DbPluginQueryEvent<TRoot, TShape>,\n done: PluginEventCallbackResult<ITranslatedValue<TShape>>\n ): void {\n const start = performance.now();\n\n this.plugin.query<TRoot, TShape>(event, result => {\n this.emit(\"query\", event, result, start);\n done(result);\n });\n }\n\n bulkPersist(\n event: DbPluginBulkPersistEvent,\n done: PluginEventCallbackPartialResult<BulkPersistResult>\n ): void {\n const start = performance.now();\n\n this.plugin.bulkPersist(event, result => {\n this.emit(\"bulkPersist\", event, result, start);\n done(result);\n });\n }\n\n destroy(event: DbPluginEvent, done: PluginEventCallbackResult<never>): void {\n const start = performance.now();\n\n this.plugin.destroy(event, result => {\n this.emit(\"destroy\", event, result, start);\n done(result);\n });\n }\n\n private emit(\n operation: TelemetryEvent[\"operation\"],\n event: DbPluginEvent,\n result: { ok: \"success\" | \"partial\" | \"error\"; error?: unknown },\n start: number\n ): void {\n try {\n this.onEvent({\n operation,\n eventId: event.id,\n source: event.source,\n schemas: [...event.schemas.values()].map(s => s.collectionName),\n durationMs: performance.now() - start,\n ok: result.ok,\n error: result.ok === \"success\" ? undefined : (result as { error?: unknown }).error,\n });\n } catch {\n // A broken sink must never fail the data operation.\n }\n }\n}\n","import { BulkPersistResult } from \"../collections\";\nimport { SchemaId } from \"../schema\";\nimport { PluginEventCallbackPartialResult, PluginEventCallbackResult, PluginEventResult } from \"../results\";\nimport { ITranslatedValue } from \"./translators\";\nimport { QueryOption, QueryOptionName } from \"./query\";\nimport { DbPluginBulkPersistEvent, DbPluginEvent, DbPluginQueryEvent, IDbPlugin } from \"./types\";\n\n/**\n * A read-through LRU in front of a slower plugin.\n *\n * ## What it can and cannot promise\n *\n * Invalidation is the whole problem with a cache, and this one solves exactly one version of\n * it: **writes that go through this wrapper**. A save invalidates every cached read for the\n * schemas it touched, so a store that reads and writes through the same instance never sees\n * its own stale data.\n *\n * It cannot see anything else. A write by another process, another tab, or another store over\n * the same database leaves this cache holding rows that no longer exist, until they age out.\n * That is not a defect to fix later — a cache in front of a plugin has no way to learn about a\n * change it did not make — it is the condition for using this at all. Put it in front of data\n * that is slow to fetch and tolerant of being briefly wrong, and nowhere else.\n *\n * Invalidation is per SCHEMA rather than per row, deliberately. Deciding whether a changed row\n * would have matched a cached filter means evaluating every cached query against it, which is\n * the work the cache exists to avoid, and getting it wrong keeps a stale row visible. Dropping\n * a schema's entries is cheap and cannot be subtly wrong.\n *\n * ```ts\n * const store = new MyStore(new CacheDbPlugin(new SomeDbPlugin(...), { max: 100 }));\n * ```\n */\n\nexport type CacheDbPluginOptions = {\n /** How many query results to keep. Default 100; the least recently used is evicted. */\n max?: number;\n};\n\ntype CacheEntry = {\n readonly value: unknown;\n readonly isTransformed: boolean;\n /** The concrete translated-value class, so a hit rebuilds the same shape. */\n readonly construct: new (value: unknown, isTransformed: boolean) => ITranslatedValue<unknown>;\n};\n\n/**\n * A stable string for one query.\n *\n * Built from the option VALUES rather than by serialising the expression tree, which holds\n * `PropertyInfo` objects carrying functions and would not survive `JSON.stringify`. A filter is\n * identified by its source text plus its params, which is what the expression is derived from\n * anyway — two queries with the same source and params are the same query.\n */\nconst describeOption = (option: QueryOption<unknown, QueryOptionName>): string => {\n const value = option.value as Record<string, unknown>;\n\n switch (option.name) {\n case \"filter\":\n return `${String(value.filter)}|${JSON.stringify(value.params ?? null)}`;\n case \"sort\":\n return `${String(value.propertyName)}|${String(value.direction)}`;\n case \"nearest\":\n return `${String(value.propertyName)}|${(value.vector as number[]).join(\",\")}|${String(value.count)}`;\n case \"map\":\n case \"group\":\n return String(value.selector);\n default:\n // skip, take and the aggregates are plain values.\n return JSON.stringify(option.value ?? null);\n }\n};\n\nexport class CacheDbPlugin implements IDbPlugin {\n\n private readonly plugin: IDbPlugin;\n private readonly max: number;\n /**\n * Insertion-ordered, which is what makes this an LRU without a second structure: a hit\n * deletes and re-sets the key to move it to the end, so the oldest is always first.\n */\n private readonly entries = new Map<string, CacheEntry>();\n\n constructor(plugin: IDbPlugin, options: CacheDbPluginOptions = {}) {\n this.plugin = plugin;\n this.max = Math.max(1, options.max ?? 100);\n }\n\n get databaseName(): string {\n return this.plugin.databaseName;\n }\n\n /** `schemaId` first, so invalidating a schema is a prefix match. */\n private keyFor<TRoot extends {}, TShape>(event: DbPluginQueryEvent<TRoot, TShape>): string {\n const parts: string[] = [];\n\n event.operation.options.forEach(option => {\n parts.push(`${option.name}:${describeOption(option as QueryOption<unknown, QueryOptionName>)}`);\n });\n\n return `${String(event.operation.schema.id)}\\u0000${parts.join(\"\\u0001\")}`;\n }\n\n /**\n * A fresh translated value over a copy of the cached data.\n *\n * Never the cached object itself, and never its array. `TranslatedArrayValue.forEach`\n * REASSIGNS its own slots — that is how the change tracker swaps in attached entities —\n * so handing out the cached instance would let the first caller replace the cache's\n * contents with its own tracked proxies. The second caller would then receive entities\n * attached to somebody else's store.\n *\n * It protects a second thing that is easy to miss, so do not replace it with a shallow copy\n * or hand out the entry directly. `ConcurrencyDbPlugin` strips `__version` from result rows\n * IN PLACE after observing them. Stacked as `ConcurrencyDbPlugin(CacheDbPlugin(...))` the\n * strip therefore lands on this copy, and the cached row keeps its token — without that,\n * every hit after the first would carry no version, the observer would record nothing, and\n * the next update would be written UNCHECKED with no error anywhere.\n * Pinned by `datastore/src/collections/wrapperStacking.test.ts`.\n */\n private rebuild(entry: CacheEntry): ITranslatedValue<unknown> {\n return new entry.construct(structuredClone(entry.value), entry.isTransformed);\n }\n\n query<TRoot extends {}, TShape extends any = TRoot>(\n event: DbPluginQueryEvent<TRoot, TShape>,\n done: PluginEventCallbackResult<ITranslatedValue<TShape>>\n ): void {\n const key = this.keyFor(event);\n const cached = this.entries.get(key);\n\n if (cached != null) {\n // Re-set to move it to the end of the insertion order: most recently used.\n this.entries.delete(key);\n this.entries.set(key, cached);\n\n // Said rather than left blank. A hit means no database was touched, which is a fact\n // worth reporting — and an empty report would otherwise read as a plugin that failed\n // to say what it ran.\n event.executedQueries.push({ text: \"cache hit — no query was executed\" });\n\n done(PluginEventResult.success(event.id, this.rebuild(cached) as ITranslatedValue<TShape>));\n return;\n }\n\n this.plugin.query<TRoot, TShape>(event, result => {\n\n if (result.ok === PluginEventResult.ERROR) {\n done(result);\n return;\n }\n\n this.store(key, result.data);\n\n // The caller gets a rebuilt value too, not the one just stored, so that mutating\n // the result of a MISS cannot corrupt what the next hit returns.\n const stored = this.entries.get(key);\n\n done(PluginEventResult.success(\n event.id,\n (stored == null ? result.data : this.rebuild(stored)) as ITranslatedValue<TShape>\n ));\n });\n }\n\n private store(key: string, value: ITranslatedValue<unknown>): void {\n let snapshot: unknown;\n\n try {\n snapshot = structuredClone(value.value);\n } catch {\n // Not every result is structured-cloneable — a projection can carry anything a\n // caller's `.map()` returned, including a function. Declining to cache is the\n // only safe answer; caching a reference would share mutable state.\n return;\n }\n\n this.entries.set(key, {\n value: snapshot,\n isTransformed: value.isTransformed,\n construct: value.constructor as CacheEntry[\"construct\"],\n });\n\n if (this.entries.size > this.max) {\n // First key is the least recently used, because every hit re-inserts.\n const oldest = this.entries.keys().next();\n\n if (oldest.done === false) {\n this.entries.delete(oldest.value);\n }\n }\n }\n\n /** Drops every cached read for these schemas. */\n private invalidate(schemaIds: Iterable<SchemaId>): void {\n for (const schemaId of schemaIds) {\n const prefix = `${String(schemaId)}\\u0000`;\n\n for (const key of [...this.entries.keys()]) {\n if (key.startsWith(prefix)) {\n this.entries.delete(key);\n }\n }\n }\n }\n\n bulkPersist(\n event: DbPluginBulkPersistEvent,\n done: PluginEventCallbackPartialResult<BulkPersistResult>\n ): void {\n const touched = [...event.operation.keys()];\n\n // Invalidated BEFORE the write is attempted, not after it succeeds. A failed save can\n // still have applied part of itself on a backend without atomic batches, and a cache\n // that kept its entries because the call reported an error would then serve rows that\n // are wrong. Throwing away a still-valid cache costs one refetch; keeping an invalid\n // one is silent.\n this.invalidate(touched);\n\n this.plugin.bulkPersist(event, result => {\n this.invalidate(touched);\n done(result);\n });\n }\n\n destroy(event: DbPluginEvent, done: PluginEventCallbackResult<never>): void {\n this.entries.clear();\n this.plugin.destroy(event, done);\n }\n}\n","import { BulkPersistChanges, BulkPersistResult, SchemaCollection, SchemaPersistResult } from \"../collections\";\nimport { PluginDestroyedError } from \"../errors\";\nimport { PluginEventCallbackPartialResult, PluginEventCallbackResult, PluginEventPartialResultType, PluginEventPartialType, PluginEventResult, PluginEventSuccessType } from \"../results\";\nimport { SchemaId } from \"../schema\";\nimport { ITranslatedValue } from \"./translators\";\nimport { DbPluginBulkPersistEvent, DbPluginEvent, DbPluginQueryEvent, IDbPlugin } from \"./types\";\nimport { uuid } from \"../utilities\";\n\nexport type BatchingDbPluginOptions = {\n /**\n * The caller PROMISING that a failed `bulkPersist` beneath this wrapper leaves NOTHING\n * applied. Only then may separate callers' saves be merged into one write, because the\n * failure path re-runs a failed batch item by item — and re-running a HALF-APPLIED batch\n * applies the landed items twice, which for adds means duplicate rows under fresh\n * identities, with nothing raised.\n *\n * Omitted, the wrapper still queues and serializes; it just writes batches of one, which\n * is what happens without it in the stack at all. True of SQLite, PostgreSQL and MySQL —\n * one transaction, rolled back entire. Not true of anything that applies writes as it\n * goes without a way to undo them.\n */\n isAtomic?: boolean;\n /**\n * The most writes one drain may take. Default 100.\n *\n * A drain takes everything waiting, so a burst puts an unbounded statement set in one\n * transaction — and some engines cap that outright, D1's `batch()` in particular. Taking N\n * per pass changes none of the reasoning: the remainder is still waiting, the next drain\n * runs the moment this one returns, and a batch is still only what had already arrived.\n *\n * It also bounds the failure fallback, which costs N+1 writes for a failing batch of N.\n */\n maxBatchSize?: number;\n};\n\nconst DEFAULT_MAX_BATCH_SIZE = 100;\n\n/** A caller's write, waiting its turn. */\ntype QueuedWrite = {\n readonly event: DbPluginBulkPersistEvent;\n readonly done: PluginEventCallbackPartialResult<BulkPersistResult>;\n};\n\n/**\n * A batch of writes that may go out as ONE, with the merged event already built.\n * `items` is kept so a failure can re-run them individually and so results can be split back.\n */\ntype PreparedGroup = {\n readonly items: QueuedWrite[];\n readonly event: DbPluginBulkPersistEvent;\n};\n\n/**\n * Coalesces overlapping writes into single round trips.\n *\n * ## Why\n *\n * One logical change produces more than one write: the caller's `saveChanges`, then every view\n * reconciling in response to it. A store with three views issues four writes, none coordinated\n * with the others. On a local file that is invisible; against a server the round trip dominates\n * everything else a save does.\n *\n * ## The shape, and why it cannot cost anything\n *\n * A write arrives and joins the queue. If one is already in flight, the running drain will take\n * it. Otherwise drain immediately: take everything waiting up to `maxBatchSize` and write it,\n * then drain again for whatever arrived meanwhile and whatever the ceiling left behind.\n *\n * Nothing polls, nothing sleeps, nothing waits for a batch to fill. **A batch is only what had\n * already arrived**, so when writes do not overlap the queue is empty, the batch is one item,\n * and the write is byte for byte what happens without this wrapper. Latency cannot increase;\n * throughput improves exactly when there is contention to improve.\n *\n * ## What may be merged\n *\n * Only items whose schemas do not overlap, and only with `isAtomic`. Two writes to one\n * collection are genuinely ordered — a plugin applies removes, then updates, then adds WITHIN a\n * schema, so merging an add of a row with a later update of it would run the update first,\n * against a row that does not exist yet, and lose it silently. Items sharing a schema therefore\n * go in separate writes, in arrival order.\n *\n * That same rule is what lets a merged result be split back by SCHEMA rather than by position:\n * each schema in a merged write came from exactly one item, so no assumption about the order a\n * plugin echoes rows in is needed anywhere.\n *\n * @see specs/write-batching.md\n */\nexport class BatchingDbPlugin implements IDbPlugin {\n\n private readonly plugin: IDbPlugin;\n private readonly canMerge: boolean;\n private readonly maxBatchSize: number;\n\n private readonly queue: QueuedWrite[] = [];\n private isWriting = false;\n private isDestroyed = false;\n /** Set when `destroy` arrives mid-write; run once the in-flight batch settles. */\n private onSettled: (() => void) | null = null;\n\n constructor(plugin: IDbPlugin, options: BatchingDbPluginOptions = {}) {\n this.plugin = plugin;\n this.canMerge = options.isAtomic === true;\n // Floored at 1: a ceiling of zero would take nothing and drain forever.\n this.maxBatchSize = Math.max(1, options.maxBatchSize ?? DEFAULT_MAX_BATCH_SIZE);\n }\n\n get databaseName(): string {\n return this.plugin.databaseName;\n }\n\n /** Reads are not batched: they have no lock to contend for and no ordering to preserve. */\n query<TRoot extends {}, TShape extends any = TRoot>(\n event: DbPluginQueryEvent<TRoot, TShape>,\n done: PluginEventCallbackResult<ITranslatedValue<TShape>>\n ): void {\n this.plugin.query(event, done);\n }\n\n bulkPersist(\n event: DbPluginBulkPersistEvent,\n done: PluginEventCallbackPartialResult<BulkPersistResult>\n ): void {\n\n if (this.isDestroyed) {\n // Fails rather than passing through. The queue's contract is that an accepted write\n // is eventually answered by a live drain loop, and there is no loop left; passing it\n // down is worse still, since a plugin that creates missing tables would recreate the\n // database the destroy just deleted and report success against an empty one.\n done(PluginEventResult.error(event.id, new PluginDestroyedError(\"write submitted after destroy\")));\n return;\n }\n\n this.queue.push({ event, done });\n\n // In flight: the continuation below takes this one. Doing anything else here is what\n // turns a queue into a race.\n if (this.isWriting) {\n return;\n }\n\n this.drain();\n }\n\n /**\n * Destroys the inner plugin, answering everything this wrapper is holding first.\n *\n * `destroy` is destructive rather than graceful — the SQLite plugin deletes the database —\n * so draining first would spend round trips producing state the next call destroys, and\n * the drain loop refills, making teardown unbounded. Queued items are therefore failed\n * rather than flushed.\n *\n * An in-flight write is a different matter: it has already been sent, destroying cannot\n * un-send it, and its callers are owed the real result. So the inner `destroy` waits for it\n * to settle — dropping a `deleteDatabase` on top of an open transaction is its own failure.\n */\n destroy(event: DbPluginEvent, done: PluginEventCallbackResult<never>): void {\n this.isDestroyed = true;\n\n for (const item of this.queue.splice(0)) {\n this.answer(item, PluginEventResult.error(\n item.event.id,\n new PluginDestroyedError(\"destroyed before the write was attempted\")\n ));\n }\n\n const forward = () => this.plugin.destroy(event, done);\n\n if (this.isWriting) {\n this.onSettled = forward;\n return;\n }\n\n forward();\n }\n\n /**\n * Takes everything waiting and writes it, then schedules itself again for whatever arrived\n * while that ran.\n */\n private drain(): void {\n // Not everything — up to the ceiling. Whatever is left stays queued for the next pass,\n // which starts as soon as this one returns.\n const batch = this.queue.splice(0, this.maxBatchSize);\n\n if (batch.length === 0) {\n this.isWriting = false;\n\n const settled = this.onSettled;\n\n if (settled != null) {\n this.onSettled = null;\n settled();\n }\n\n return;\n }\n\n this.isWriting = true;\n\n // The latch's only way down. Every path below MUST reach it: an exception that escaped\n // would leave `isWriting` stuck true and every future write queued forever — a total,\n // silent write outage that nothing else would report.\n const next = () => this.drain();\n\n let groups: PreparedGroup[];\n\n try {\n groups = this.prepare(batch);\n } catch (error) {\n // A throw here is a bug in this wrapper rather than a backend failure, and — because\n // preparing is pure and happens BEFORE any write is issued — nothing has been\n // applied. Degrading to one write per item is exactly what not batching does.\n //\n // This is also why the guard stops here and does not cover `writeGroups`. If group 1\n // had already landed, re-running the batch item by item would apply it twice, which\n // is the hazard `isAtomic` exists to rule out.\n this.writeIndividually(batch, next);\n return;\n }\n\n this.writeGroups(groups, 0, next);\n }\n\n /**\n * Partitions the batch, APPEND-ONLY: an item joins the last group if none of its schemas is\n * claimed there, and otherwise closes that group and starts a new one.\n *\n * Not first-fit. Scanning every open group for one an item fits merges more, and reorders\n * doing it: with arrivals A(schema S), B(schema S), C(schema T), first-fit would put C in\n * A's group and write it before the earlier-arrived B. Nothing is lost inside a table, but a\n * caller who saved B before C could observe C land first. The last-group rule keeps arrival\n * order unconditionally — everything in group N arrived before everything in group N+1 — and\n * on the case that matters, several views over distinct schemas, both rules produce the same\n * single group.\n */\n private prepare(batch: QueuedWrite[]): PreparedGroup[] {\n const groups: QueuedWrite[][] = [];\n let claimed = new Set<SchemaId>();\n\n for (const item of batch) {\n const schemas = [...item.event.operation.keys()];\n const overlaps = schemas.some(schemaId => claimed.has(schemaId));\n\n if (groups.length === 0 || overlaps || this.canMerge === false) {\n groups.push([item]);\n claimed = new Set(schemas);\n continue;\n }\n\n groups[groups.length - 1].push(item);\n\n for (const schemaId of schemas) {\n claimed.add(schemaId);\n }\n }\n\n return groups.map(items => ({ items, event: this.mergeEvents(items) }));\n }\n\n /**\n * One event standing for several. Synthetic THROUGHOUT: its own id, its operation the union\n * of the items' operations, and its schemas the union of theirs — a plugin resolving\n * `event.schemas.get(schemaId)` must find every schema any item brought.\n *\n * A single-item group passes its own event through untouched. That is most writes, so the\n * uncontended path never reaches the merging machinery at all.\n */\n private mergeEvents(items: QueuedWrite[]): DbPluginBulkPersistEvent {\n\n if (items.length === 1) {\n return items[0].event;\n }\n\n const operation = new BulkPersistChanges();\n const schemas = new SchemaCollection();\n\n for (const item of items) {\n for (const [schemaId, changes] of item.event.operation) {\n operation.set(schemaId, changes);\n }\n\n for (const [schemaId, schema] of item.event.schemas) {\n schemas.set(schemaId, schema);\n }\n }\n\n return {\n ...items[0].event,\n // Its own id: no caller has ever seen this one, and nothing upstream may be handed it.\n id: uuid(16),\n source: \"BatchingDbPlugin\",\n reason: `merged ${items.length} writes`,\n operation,\n schemas,\n };\n }\n\n /** Groups go out in order, because two writes to one collection are genuinely ordered. */\n private writeGroups(groups: PreparedGroup[], index: number, next: () => void): void {\n\n if (index >= groups.length) {\n next();\n return;\n }\n\n const group = groups[index];\n const advance = () => this.writeGroups(groups, index + 1, next);\n\n const attempt = (result: PluginEventPartialResultType<BulkPersistResult>) => {\n\n if (result.ok === PluginEventResult.ERROR) {\n\n if (group.items.length === 1) {\n this.answer(group.items[0], result);\n advance();\n return;\n }\n\n // Coupled failure, unpicked: one caller's bad data must not fail its\n // batchmates, so the batch is re-run item by item. Costs N+1 writes for a\n // failing batch of N, paid only when something is already going wrong. Safe\n // only because `isAtomic` promised the failed batch left nothing applied.\n this.writeIndividually(group.items, advance);\n return;\n }\n\n this.split(group, result);\n advance();\n };\n\n try {\n this.plugin.bulkPersist(group.event, attempt);\n } catch (error) {\n attempt(PluginEventResult.error(group.event.id, error));\n }\n }\n\n /**\n * Hands each item its own slice of a merged result, keyed by SCHEMA.\n *\n * Disjoint schemas are what make this possible: each schema in the write came from exactly\n * one item, so there is no counting, no slicing by position, and no reliance on the order a\n * plugin echoes rows in — an assumption that is load-bearing elsewhere and would be SILENT\n * here, handing one caller another's database-assigned identities.\n */\n private split(\n group: PreparedGroup,\n result: PluginEventSuccessType<BulkPersistResult> | PluginEventPartialType<BulkPersistResult>\n ): void {\n\n if (group.items.length === 1) {\n this.answer(group.items[0], result);\n return;\n }\n\n const merged = result.data;\n // A PARTIAL from an inner plugin that promised atomicity should not happen. If it does,\n // every caller is told — splitting the data but reporting the error to all of them,\n // rather than retrying. Retrying is what would be unsafe here: partial means something\n // already landed, and re-running it applies that twice.\n const isPartial = result.ok === PluginEventResult.PARTIAL;\n\n for (const item of group.items) {\n const mine = new BulkPersistResult();\n\n for (const schemaId of item.event.operation.keys()) {\n // A schema the plugin had nothing to echo for gets an empty result, never a hole.\n mine.set(schemaId, merged?.get(schemaId) ?? new SchemaPersistResult());\n }\n\n // Answered under ITS OWN event id — the merged write ran under a synthetic one.\n this.answer(item, isPartial\n ? PluginEventResult.partial(item.event.id, mine, (result as PluginEventPartialType<BulkPersistResult>).error)\n : PluginEventResult.success(item.event.id, mine));\n }\n }\n\n /** One write per item, in arrival order — what happens with no batching at all. */\n private writeIndividually(items: QueuedWrite[], next: () => void): void {\n\n const run = (index: number): void => {\n\n if (index >= items.length) {\n next();\n return;\n }\n\n const item = items[index];\n const advance = () => run(index + 1);\n\n try {\n this.plugin.bulkPersist(item.event, result => {\n this.answer(item, result);\n advance();\n });\n } catch (error) {\n this.answer(item, PluginEventResult.error(item.event.id, error));\n advance();\n }\n };\n\n run(0);\n }\n\n /**\n * A caller's callback, guarded. One caller's `done` throwing must not eat its batchmates'\n * results, and must not strand the latch — which it would, since the continuation runs\n * after the answers.\n */\n private answer(item: QueuedWrite, result: PluginEventPartialResultType<BulkPersistResult>): void {\n try {\n item.done(result);\n } catch (error) {\n // Nobody left to tell: the caller we would report to is the one that threw.\n }\n }\n}\n","export * from './types';\nexport * from './resultShape';\nexport * from './translators';\nexport * from './query';\nexport * from './wire';\nexport * from './ConcurrencyDbPlugin';\nexport * from './EphemeralDataPlugin';\nexport * from './RetryDbPlugin';\nexport * from './TelemetryDbPlugin';\nexport * from './CacheDbPlugin';\nexport * from './BatchingDbPlugin';\n"],"names":["EXPRESSION_TYPES","isDate","assertDate","data","TypeError","assertIsNotNull","message","assertIsArray","Array","assertString","assertInstanceOf","value","Instance","assertIsNumber","isObjectWithType","isExpression","isOperatorExpression","isComparatorExpression","isPropertyExpression","isValueExpression","isEmptyExpression","isNotParsableExpression","TagCollection","BulkPersistResult","Map","schemaId","SchemaPersistResult","count","result","BulkPersistChanges","SchemaPersistChanges","ReadonlySchemaCollection","callbackfn","thisArg","Symbol","collectionName","found","x","undefined","SchemaCollection","schema","key","tag","keys","i","length","tags","OptimisticConcurrencyError","Error","conflicts","String","error","PluginDestroyedError","reason","UNRESOLVED","applyTransformer","transformer","operand","expression","row","equals","left","right","strict","Date","compare","comparator","asComparable","a","b","comparable","evaluateComparator","item","evaluate","toPredicate","toStrictPredicate","logger","SchemaTypes","Expression","OperatorExpression","ComparatorExpression","ValueExpression","PropertyExpression","ERROR_MESSAGES","path","params","JSON","parseUnknown","ParamDependentParseError","converters","v","Boolean","Number","MULTI_CHARACTER_PUNCTUATION","SINGLE_CHARACTER_PUNCTUATION","Set","STRING_ESCAPES","isIdentifierStart","char","isIdentifierPart","isDigit","isHexDigit","decodeCodeEscape","source","backslashIndex","kind","start","end","parseInt","digits","d","tokenize","tokens","quote","escaped","decoded","nextChar","radixPrefix","signLength","multi","w","TokenStream","offset","token","COMPARATOR_METHODS","TRANSFORM_METHODS","COMPARISON_OPERATORS","SWAPPED_COMPARATORS","ParamReferenceExpression","options","resolveParamPath","paramsName","name","resolvePairedValue","pairedProperty","applyConverter","ExpressionParser","stream","entityName","trailing","operatorToken","numberToken","elements","element","array","method","argument","root","locale","segment","paramPath","resolved","pathString","property","parentPath","parent","operator","comparedToFalse","swapped","target","isStringMatch","bindExpression","raw","bound","clone","resolveFunctionShape","stringifiedFunction","hasParams","parameterNames","body","functionHead","parametersEnd","arrowIndex","destructured","inner","templateCache","WeakMap","MAX_CACHED_TEMPLATES_PER_SCHEMA","getCachedTemplate","setCachedTemplate","entry","bySource","combineExpressions","expressions","parseFragment","rootName","parser","toExpression","fn","warn","cached","template","structurallyDependsOnParams","shape","valueToJson","Object","valueFromJson","EmptyExpression","NotParsableExpression","json","child","node","rebuilt","getProperties","properties","traverse","expr","forEach","callback","Result","TrampolinePipeline","initialData","done","index","currentData","isRunning","finalStepSentinel","createStepRevised","idx","processor","syncCallbackResult","calledSync","nextStep","trampoline","step","currentStep","trampolineError","items","map","previous","WorkPipeline","work","QueryOptionsCollection","mapValue","filterValue","sortValue","nearestValue","joinValue","sortedItems","before","after","at","option","destination","nextExecutionTarget","nextExecutionReason","nextIndex","memoryQueryOptionsCollection","databaseQueryOptionsCollection","sortedItem","transformationOptions","iterator","BaseResult","resolve","reject","PluginEventResult","id","HashType","LOG_LEVELS","RANK","isLogLevel","resolveLevel","globalThis","g","process","debug","env","level","rank","setLogLevel","next","getLogLevel","resetLogLevel","isLogLevelEnabled","emit","args","console","uuid","chars","charLength","Math","HEX_CHARS","UUID_TEMPLATE","hasCrypto","crypto","hasRandomUUID","uuidv4","uuidv4Fallback","randomBytes","Uint8Array","byteIndex","c","r","mappedResultColumns","fields","field","TranslatedArrayValue","isTransformed","TranslatedGroupValue","group","j","len","TranslatedSingleValue","DataTranslator","query","cosineDistance","Infinity","dot","leftMagnitude","rightMagnitude","l","nearestBy","rows","vector","select","mismatched","scored","stored","Query","enableChangeTrackingOverride","max","min","sum","toEntityShape","readJoinKey","reference","current","isMatchableKey","applyInnerOptions","innerOptions","filtered","filter","selector","hashJoin","outerRows","innerRows","outerKey","innerKey","isLeft","buckets","bucket","tuples","outer","matches","matchLength","DEFAULT_SEMI_JOIN_KEY_THRESHOLD","distinctJoinKeys","threshold","read","semiJoinFilter","values","propertyName","loadJoinInnerSide","event","outerKeys","joinOption","innerSchema","innerEvent","joinInPlugin","outerEvent","outerResult","innerResult","executeJoin","e","JsonTranslator","innerSide","response","resolvedValue","keyValue","_","direction","y","needsDateConversion","mapOption","sort","best","functionName","toVector","parsed","SqlTranslator","pushedDown","column","TupleTranslator","tuple","__","MEMORY_EXECUTION_EXPLANATIONS","EXECUTED_QUERIES_UNSUPPORTED","DATABASE_STEP_DESCRIPTION","MEMORY_STEP_DESCRIPTION","UNNARROWED_READ_DESCRIPTION","detailOf","explainedOptionsOf","explainedOptionOf","detail","explained","summarize","steps","reasons","database","memory","counts","causes","toExecutionSteps","explainQuery","context","executionSteps","withExecutedQueries","explanation","executedQueries","attached","OPTION_LABEL_WIDTH","WRAP_WIDTH","wrap","text","indent","lines","line","word","COMPARATOR_SYMBOLS","describeValue","describeExpression","symbol","describeOption","formatStep","executed","formatExplanation","collection","summary","stepCount","QueryOrdering","SENDABLE","splitSendableOptions","sendable","local","stopped","keyPath","serializeQueryOptions","serialized","join","deserializeQueryOptions","resolveSchema","scopeFor","scope","propertyOf","serializeBulkPersist","changes","schemas","schemaChanges","update","deserializeBulkPersist","request","serializePersistResult","schemaResult","deserializePersistResult","collectionsIn","change","names","walk","createRequestHandler","plugin","authorize","allowDestroy","byName","failed","scopeExpressionFor","action","declared","verdict","queryOptions","Promise","permitted","ConcurrencyDbPlugin","augmentedEvent","schemaIds","versions","add","entity","expected","deltaCarriesColumns","removed","conflicted","record","version","augment","Proxy","receiver","Reflect","synthetic","view","getKeyEqualityValue","EphemeralDataPlugin","databaseName","bulkPersistResult","staged","pipeline","readResult","concurrency","undo","revert","adds","updates","removes","prior","applyError","saveNext","saveResult","resaveNext","k","innerCollection","cloneRecord","keyColumn","narrowing","hasRenamedProperties","operation","orderedOptions","o","leadingFilterCount","leadingFilters","filterCount","cloned","kept","joinResult","translator","DEFAULT_ATTEMPTS","defaultDelay","attempt","RetryDbPlugin","isLastAttempt","delay","setTimeout","loggerSink","collectingSink","into","TelemetryDbPlugin","performance","s","CacheDbPlugin","parts","structuredClone","snapshot","oldest","prefix","touched","DEFAULT_MAX_BATCH_SIZE","BatchingDbPlugin","forward","batch","settled","groups","claimed","overlaps","advance","merged","isPartial","mine","run"],"mappings":"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"}