@prisma-idb/adapter-idb 0.9.1 → 0.11.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.
- package/dist/runtime.d.mts +3 -0
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +3 -0
- package/dist/runtime.mjs.map +1 -1
- package/package.json +3 -3
package/dist/runtime.d.mts
CHANGED
|
@@ -297,6 +297,9 @@ declare function evaluateFilter(expr: IdbFilterExpr, row: Record<string, unknown
|
|
|
297
297
|
* `IdbQueryPlan` is already execution-ready because IDB has no query
|
|
298
298
|
* language to compile from. Every current `idb/*` codec is an identity
|
|
299
299
|
* transform for stored values, so no field needs encoding.
|
|
300
|
+
*
|
|
301
|
+
* The `codecs` constructor parameter matches the framework adapter shape and
|
|
302
|
+
* is the extension point for field encoding with non-identity codecs.
|
|
300
303
|
*/
|
|
301
304
|
declare class IdbAdapter implements IdbRuntimeAdapterInstance {
|
|
302
305
|
#private;
|
package/dist/runtime.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/core/idb-filter-expr.ts","../src/core/idb-query-ast.ts","../src/core/idb-query-plan.ts","../src/core/runtime-adapter-instance.ts","../src/core/filter-eval.ts","../src/core/idb-adapter.ts","../src/exports/runtime.ts"],"mappings":";;;;;;;;;;;;;;;;;;KAcY;;UAIK;WACN;WACA;WACA,IAAI;WACJ;;;UAIM;WACN;WACA,OAAO,cAAc;;;UAIf;WACN;WACA,OAAO,cAAc;;;UAIf;WACN;WACA,MAAM;;;;;;;UAQA;WACN;WACA;WACA;;KAGC,gBAAgB,iBAAiB,aAAa,YAAY,aAAa;;cAKtE,cAAe,eAAe,IAAI,aAAa,mBAAiB;;cAIhE,UAAW,OAAO,cAAc,mBAAiB;;cAIjD,SAAU,OAAO,cAAc,mBAAiB;;cAIhD,UAAW,MAAM,kBAAgB;;cAGjC,gBAAiB,eAAe,oBAAkB;;;;;;;;;;;iBAe/C,sBAAsB,SAAS,0BAA0B;;;;;;;;;;KCnE7D,cACR,iBACA,mBACA,eACA,eACA,eACA,kBACA,oBACA,kBACA,oBACA,kBACA,oBACA,cACA,kBACA;;UAGa;WACN;;WAEA;;WAEA,QAAQ;;WAER,UAAU;;WAEV;;WAEA;;;UAIM;WACN;;WAEA;;WAEA;;;UAIM;WACN;;WAEA;;WAEA,MAAM;;;UAIA;WACN;;WAEA;;WAEA;;;UAIM;WACN;WACA;WACA,OAAO;WACP,QAAQ;;;UAIF;WACN;WACA;WACA,OAAO;WACP,QAAQ;;;UAIF;WACN;WACA;WACA,OAAO;WACP,QAAQ;;;UAIF;WACN;WACA;WACA,MAAM;;;UAIA;WACN;WACA;WACA,MAAM;;;UAIA;WACN;WACA;WACA,QAAQ;;;UAIF;WACN;WACA;WACA,QAAQ;;;UAIF;WACN;WACA;WACA,QAAQ;;;UAIF;;WAEN;;WAEA;;;;;;;;;UAUM;WACN;WACA;WACA,QAAQ;;WAER,YAAY,SAAS,eAAe;;;;;;;;UAS9B;WACN;WACA;WACA,QAAQ;;WAER;;WAEA,YAAY,SAAS,eAAe;;;;cC1KjC;;;;;;;;;;;;;;;;;;;UAoBG,aAAa,uBAAuB,UAAU;;WAEpD,SAAS;;;;;;;WAOT,MAAM;;YAEL,qBAAqB;;;;;;;;;;;;;UCtBhB,kBAAkB,6BAA6B;;WAErD,UAAU;;;;;;;;;;;;;;;UAgBJ,kCAAkC;;;;;;;;;;EAUjD,MAAM,MAAM,cAAc,KAAK,oBAAoB,QAAQ;;;;;iBCvB7C,eAAe,MAAM,eAAe,KAAK
|
|
1
|
+
{"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/core/idb-filter-expr.ts","../src/core/idb-query-ast.ts","../src/core/idb-query-plan.ts","../src/core/runtime-adapter-instance.ts","../src/core/filter-eval.ts","../src/core/idb-adapter.ts","../src/exports/runtime.ts"],"mappings":";;;;;;;;;;;;;;;;;;KAcY;;UAIK;WACN;WACA;WACA,IAAI;WACJ;;;UAIM;WACN;WACA,OAAO,cAAc;;;UAIf;WACN;WACA,OAAO,cAAc;;;UAIf;WACN;WACA,MAAM;;;;;;;UAQA;WACN;WACA;WACA;;KAGC,gBAAgB,iBAAiB,aAAa,YAAY,aAAa;;cAKtE,cAAe,eAAe,IAAI,aAAa,mBAAiB;;cAIhE,UAAW,OAAO,cAAc,mBAAiB;;cAIjD,SAAU,OAAO,cAAc,mBAAiB;;cAIhD,UAAW,MAAM,kBAAgB;;cAGjC,gBAAiB,eAAe,oBAAkB;;;;;;;;;;;iBAe/C,sBAAsB,SAAS,0BAA0B;;;;;;;;;;KCnE7D,cACR,iBACA,mBACA,eACA,eACA,eACA,kBACA,oBACA,kBACA,oBACA,kBACA,oBACA,cACA,kBACA;;UAGa;WACN;;WAEA;;WAEA,QAAQ;;WAER,UAAU;;WAEV;;WAEA;;;UAIM;WACN;;WAEA;;WAEA;;;UAIM;WACN;;WAEA;;WAEA,MAAM;;;UAIA;WACN;;WAEA;;WAEA;;;UAIM;WACN;WACA;WACA,OAAO;WACP,QAAQ;;;UAIF;WACN;WACA;WACA,OAAO;WACP,QAAQ;;;UAIF;WACN;WACA;WACA,OAAO;WACP,QAAQ;;;UAIF;WACN;WACA;WACA,MAAM;;;UAIA;WACN;WACA;WACA,MAAM;;;UAIA;WACN;WACA;WACA,QAAQ;;;UAIF;WACN;WACA;WACA,QAAQ;;;UAIF;WACN;WACA;WACA,QAAQ;;;UAIF;;WAEN;;WAEA;;;;;;;;;UAUM;WACN;WACA;WACA,QAAQ;;WAER,YAAY,SAAS,eAAe;;;;;;;;UAS9B;WACN;WACA;WACA,QAAQ;;WAER;;WAEA,YAAY,SAAS,eAAe;;;;cC1KjC;;;;;;;;;;;;;;;;;;;UAoBG,aAAa,uBAAuB,UAAU;;WAEpD,SAAS;;;;;;;WAOT,MAAM;;YAEL,qBAAqB;;;;;;;;;;;;;UCtBhB,kBAAkB,6BAA6B;;WAErD,UAAU;;;;;;;;;;;;;;;UAgBJ,kCAAkC;;;;;;;;;;EAUjD,MAAM,MAAM,cAAc,KAAK,oBAAoB,QAAQ;;;;;iBCvB7C,eAAe,MAAM,eAAe,KAAK;;;;;;;;;;;;;;;;;;cCC5C,sBAAsB;;WACxB;WACA;EAIG,YAAA,QAAQ;EAIpB,MAAM,MAAM,cAAc,KAAK,oBAAoB,QAAQ;;;;cCSvD,6BAA6B,uCAAuC"}
|
package/dist/runtime.mjs
CHANGED
|
@@ -12,6 +12,9 @@ import { compareFieldValues, fieldValuesEqual, idbCodecLookup } from "@prisma-id
|
|
|
12
12
|
* `IdbQueryPlan` is already execution-ready because IDB has no query
|
|
13
13
|
* language to compile from. Every current `idb/*` codec is an identity
|
|
14
14
|
* transform for stored values, so no field needs encoding.
|
|
15
|
+
*
|
|
16
|
+
* The `codecs` constructor parameter matches the framework adapter shape and
|
|
17
|
+
* is the extension point for field encoding with non-identity codecs.
|
|
15
18
|
*/
|
|
16
19
|
var IdbAdapter = class {
|
|
17
20
|
familyId = "idb";
|
package/dist/runtime.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.mjs","names":["#codecs"],"sources":["../src/core/idb-adapter.ts","../src/core/idb-filter-expr.ts","../src/core/filter-eval.ts","../src/exports/runtime.ts"],"sourcesContent":["import type { CodecLookup } from \"@prisma/orm-framework/components/codec\";\nimport type { IdbPlanBody } from \"@prisma-idb/driver-idb/runtime\";\nimport type { IdbQueryPlan } from \"./idb-query-plan\";\nimport type { IdbLowererContext, IdbRuntimeAdapterInstance } from \"./runtime-adapter-instance\";\n\n/**\n * Concrete IDB runtime adapter.\n *\n * Implements {@link IdbRuntimeAdapterInstance} — the `lower()` method that\n * translates an {@link IdbQueryPlan} into an {@link IdbPlanBody} ready for\n * the driver.\n *\n * `lower()` is a structural passthrough: the `idbPlan` carried by\n * `IdbQueryPlan` is already execution-ready because IDB has no query\n * language to compile from. Every current `idb/*` codec is an identity\n * transform for stored values, so no field needs encoding.\n */\nexport class IdbAdapter implements IdbRuntimeAdapterInstance {\n readonly familyId = \"idb\" as const;\n readonly targetId = \"idb\" as const;\n\n readonly #codecs: CodecLookup;\n\n constructor(codecs: CodecLookup) {\n this.#codecs = codecs;\n }\n\n lower(plan: IdbQueryPlan, ctx: IdbLowererContext): Promise<IdbPlanBody> {\n // If a codec ever transforms stored values, encode plan.idbPlan's\n // record and key fields here: resolve each field's codec through\n // this.#codecs and ctx.contract, then call codec.encode(value, ctx).\n void this.#codecs; // codec registry for per-field encoding\n void ctx.contract; // contract storage schema (field→codec resolution)\n void ctx.signal; // AbortSignal for cooperative cancellation\n return Promise.resolve(plan.idbPlan);\n }\n}\n","/**\n * Filter expression AST for IDB queries.\n *\n * Plain frozen objects (not classes) — IDB has no codec trait gating to\n * worry about and no visitor pattern needed (a recursive `evaluateFilter`\n * is plenty). Mirrors the design of Prisma ORM's Mongo family\n * (`MongoFieldFilter`, `MongoAndExpr`, ...) and the SQL ORM's `BinaryExpr`,\n * but with the class machinery stripped out.\n *\n * The AST is carried on `IdbQueryAst` (intent layer) and lowered into an\n * `IdbRowFilter` closure that the driver applies during cursor scans —\n * keeping the driver free of any AST imports.\n */\n\nexport type IdbFilterOp =\n \"eq\" | \"neq\" | \"gt\" | \"lt\" | \"gte\" | \"lte\" | \"in\" | \"notIn\" | \"contains\" | \"startsWith\" | \"endsWith\";\n\n/** Comparison / membership predicate on a single field. */\nexport interface IdbFieldFilter {\n readonly kind: \"field\";\n readonly field: string;\n readonly op: IdbFilterOp;\n readonly value: unknown;\n}\n\n/** Conjunction. Empty `exprs` is truthy (vacuously true). */\nexport interface IdbAndExpr {\n readonly kind: \"and\";\n readonly exprs: ReadonlyArray<IdbFilterExpr>;\n}\n\n/** Disjunction. Empty `exprs` is falsy. */\nexport interface IdbOrExpr {\n readonly kind: \"or\";\n readonly exprs: ReadonlyArray<IdbFilterExpr>;\n}\n\n/** Logical NOT. */\nexport interface IdbNotExpr {\n readonly kind: \"not\";\n readonly expr: IdbFilterExpr;\n}\n\n/**\n * Null check. Distinct from `eq null` because IDB serialises absent\n * fields as `undefined`; a null check treats `null` and `undefined`\n * as equivalent (matching the shorthand `where({ field: null })`).\n */\nexport interface IdbNullCheckExpr {\n readonly kind: \"null-check\";\n readonly field: string;\n readonly isNull: boolean;\n}\n\nexport type IdbFilterExpr = IdbFieldFilter | IdbAndExpr | IdbOrExpr | IdbNotExpr | IdbNullCheckExpr;\n\n// ── Factory helpers ───────────────────────────────────────────────────────────\n\n/** Build a frozen field-filter node. */\nexport const fieldFilter = (field: string, op: IdbFilterOp, value: unknown): IdbFieldFilter =>\n Object.freeze({ kind: \"field\", field, op, value });\n\n/** Build a frozen AND combinator with a frozen `exprs` array. */\nexport const andExpr = (exprs: ReadonlyArray<IdbFilterExpr>): IdbAndExpr =>\n Object.freeze({ kind: \"and\", exprs: Object.freeze([...exprs]) });\n\n/** Build a frozen OR combinator with a frozen `exprs` array. */\nexport const orExpr = (exprs: ReadonlyArray<IdbFilterExpr>): IdbOrExpr =>\n Object.freeze({ kind: \"or\", exprs: Object.freeze([...exprs]) });\n\n/** Build a frozen NOT combinator. */\nexport const notExpr = (expr: IdbFilterExpr): IdbNotExpr => Object.freeze({ kind: \"not\", expr });\n\n/** Build a frozen null-check node. */\nexport const nullCheckExpr = (field: string, isNull: boolean): IdbNullCheckExpr =>\n Object.freeze({ kind: \"null-check\", field, isNull });\n\n// ── Shorthand → expression ────────────────────────────────────────────────────\n\n/**\n * Convert a shorthand equality object (e.g. `{ active: true, email: \"x\" }`)\n * into the canonical AST form. `undefined` entries are dropped; `null`\n * values become null-checks rather than literal-null equalities (IDB\n * stores absent fields as `undefined`, so a literal-null equality misses).\n *\n * Returns `undefined` when the input has no usable entries — callers can\n * skip filter installation in that case rather than testing an empty\n * AND node every row.\n */\nexport function shorthandToFilterExpr(filters: Record<string, unknown>): IdbFilterExpr | undefined {\n const exprs: IdbFilterExpr[] = [];\n for (const [field, value] of Object.entries(filters)) {\n if (value === undefined) continue;\n if (value === null) {\n exprs.push(nullCheckExpr(field, true));\n continue;\n }\n exprs.push(fieldFilter(field, \"eq\", value));\n }\n if (exprs.length === 0) return undefined;\n return exprs.length === 1 ? exprs[0]! : andExpr(exprs);\n}\n","/**\n * Pure-JS evaluator for {@link IdbFilterExpr}.\n *\n * The driver's `IdbRowFilter` type stays as `(row) => boolean` — the\n * accessor builds a closure that calls `evaluateFilter(expr, row)` and\n * passes that to the driver. The driver therefore never imports the\n * adapter's AST types, and keeps no dependency on the adapter.\n *\n * Equality and ordering compare values the way IndexedDB compares keys, so\n * a filter gives the same answer whether it runs here or through an index\n * key range. Plain `===` would never match two equal `Date`s or byte arrays,\n * because values read back from IndexedDB are fresh objects. String\n * operations coerce both sides via `String(...)` so they work on numbers too.\n */\n\nimport { compareFieldValues, fieldValuesEqual } from \"@prisma-idb/target-idb/runtime\";\nimport type { IdbFilterExpr, IdbFilterOp } from \"./idb-filter-expr\";\n\n/** Evaluate an AST node against a single row. Returns `true` to keep the row. */\nexport function evaluateFilter(expr: IdbFilterExpr, row: Record<string, unknown>): boolean {\n switch (expr.kind) {\n case \"field\":\n return evalFieldOp(expr.field, expr.op, expr.value, row);\n case \"and\": {\n for (const e of expr.exprs) {\n if (!evaluateFilter(e, row)) return false;\n }\n return true;\n }\n case \"or\": {\n if (expr.exprs.length === 0) return false;\n for (const e of expr.exprs) {\n if (evaluateFilter(e, row)) return true;\n }\n return false;\n }\n case \"not\":\n return !evaluateFilter(expr.expr, row);\n case \"null-check\": {\n const v = row[expr.field];\n const isNullish = v === null || v === undefined;\n return expr.isNull ? isNullish : !isNullish;\n }\n }\n}\n\nfunction evalFieldOp(field: string, op: IdbFilterOp, value: unknown, row: Record<string, unknown>): boolean {\n const cell = row[field];\n switch (op) {\n case \"eq\":\n // `eq` treats null and undefined as equivalent so the shorthand path\n // (`{ field: someValue }`) keeps working when stored rows omit the\n // field. Literal-null equality goes through `null-check` instead.\n if (value === null) return cell === null || cell === undefined;\n return fieldValuesEqual(cell, value);\n case \"neq\":\n if (value === null) return cell !== null && cell !== undefined;\n return !fieldValuesEqual(cell, value);\n case \"gt\":\n return isPresent(cell) && isPresent(value) && compareFieldValues(cell, value) > 0;\n case \"lt\":\n return isPresent(cell) && isPresent(value) && compareFieldValues(cell, value) < 0;\n case \"gte\":\n return isPresent(cell) && isPresent(value) && compareFieldValues(cell, value) >= 0;\n case \"lte\":\n return isPresent(cell) && isPresent(value) && compareFieldValues(cell, value) <= 0;\n case \"in\": {\n if (!Array.isArray(value)) return false;\n return value.some((v) => fieldValuesEqual(cell, v));\n }\n case \"notIn\": {\n if (!Array.isArray(value)) return true;\n return !value.some((v) => fieldValuesEqual(cell, v));\n }\n case \"contains\":\n return isPresent(cell) && String(cell).includes(String(value));\n case \"startsWith\":\n return isPresent(cell) && String(cell).startsWith(String(value));\n case \"endsWith\":\n return isPresent(cell) && String(cell).endsWith(String(value));\n default:\n return false;\n }\n}\n\nfunction isPresent(value: unknown): boolean {\n return value !== null && value !== undefined;\n}\n","import type { RuntimeAdapterDescriptor, ExecutionStack } from \"@prisma/orm-framework/components/execution\";\nimport { idbCodecLookup } from \"@prisma-idb/target-idb/runtime\";\nimport { idbAdapterDescriptorMeta } from \"../core/descriptor-meta\";\nimport { IdbAdapter } from \"../core/idb-adapter\";\nimport type { IdbRuntimeAdapterInstance } from \"../core/runtime-adapter-instance\";\n\nexport type { IdbRuntimeAdapterInstance, IdbLowererContext } from \"../core/runtime-adapter-instance\";\nexport type { IdbQueryPlan } from \"../core/idb-query-plan\";\nexport type {\n IdbQueryAst,\n IdbFindManyAst,\n IdbFindUniqueAst,\n IdbCreateAst,\n IdbDeleteAst,\n IdbUpdateAst,\n IdbUpdateAllAst,\n IdbUpdateCountAst,\n IdbCreateAllAst,\n IdbCreateCountAst,\n IdbDeleteAllAst,\n IdbDeleteCountAst,\n IdbCountAst,\n IdbAggregateAst,\n IdbGroupByAst,\n IdbAggregateRequest,\n} from \"../core/idb-query-ast\";\nexport type {\n IdbFilterExpr,\n IdbFieldFilter,\n IdbAndExpr,\n IdbOrExpr,\n IdbNotExpr,\n IdbNullCheckExpr,\n IdbFilterOp,\n} from \"../core/idb-filter-expr\";\nexport { fieldFilter, andExpr, orExpr, notExpr, nullCheckExpr, shorthandToFilterExpr } from \"../core/idb-filter-expr\";\nexport { evaluateFilter } from \"../core/filter-eval\";\nexport { IdbAdapter } from \"../core/idb-adapter\";\n\nconst idbRuntimeAdapterDescriptor: RuntimeAdapterDescriptor<\"idb\", \"idb\", IdbRuntimeAdapterInstance> = {\n ...idbAdapterDescriptorMeta,\n create(_stack: ExecutionStack<\"idb\", \"idb\">): IdbRuntimeAdapterInstance {\n // Construct the adapter with the real IDB codec lookup so per-field\n // encoding works when non-identity codecs are added. The current set\n // is all-identity, so output behavior is unchanged; this wiring makes\n // the descriptor-built adapter match the hand-constructed one in\n // `createIdbClient`.\n return new IdbAdapter(idbCodecLookup);\n },\n};\n\nexport default idbRuntimeAdapterDescriptor;\n"],"mappings":";;;;;;;;;;;;;;;AAiBA,IAAa,aAAb,MAA6D;CAC3D,WAAoB;CACpB,WAAoB;CAEpB;CAEA,YAAY,QAAqB;EAC/B,KAAKA,UAAU;CACjB;CAEA,MAAM,MAAoB,KAA8C;EAItE,KAAUA;EACV,IAAS;EACT,IAAS;EACT,OAAO,QAAQ,QAAQ,KAAK,OAAO;CACrC;AACF;;;;ACuBA,MAAa,eAAe,OAAe,IAAiB,UAC1D,OAAO,OAAO;CAAE,MAAM;CAAS;CAAO;CAAI;AAAM,CAAC;;AAGnD,MAAa,WAAW,UACtB,OAAO,OAAO;CAAE,MAAM;CAAO,OAAO,OAAO,OAAO,CAAC,GAAG,KAAK,CAAC;AAAE,CAAC;;AAGjE,MAAa,UAAU,UACrB,OAAO,OAAO;CAAE,MAAM;CAAM,OAAO,OAAO,OAAO,CAAC,GAAG,KAAK,CAAC;AAAE,CAAC;;AAGhE,MAAa,WAAW,SAAoC,OAAO,OAAO;CAAE,MAAM;CAAO;AAAK,CAAC;;AAG/F,MAAa,iBAAiB,OAAe,WAC3C,OAAO,OAAO;CAAE,MAAM;CAAc;CAAO;AAAO,CAAC;;;;;;;;;;;AAcrD,SAAgB,sBAAsB,SAA6D;CACjG,MAAM,QAAyB,CAAC;CAChC,KAAK,MAAM,CAAC,OAAO,UAAU,OAAO,QAAQ,OAAO,GAAG;EACpD,IAAI,UAAU,KAAA,GAAW;EACzB,IAAI,UAAU,MAAM;GAClB,MAAM,KAAK,cAAc,OAAO,IAAI,CAAC;GACrC;EACF;EACA,MAAM,KAAK,YAAY,OAAO,MAAM,KAAK,CAAC;CAC5C;CACA,IAAI,MAAM,WAAW,GAAG,OAAO,KAAA;CAC/B,OAAO,MAAM,WAAW,IAAI,MAAM,KAAM,QAAQ,KAAK;AACvD;;;;;;;;;;;;;;;;;;AClFA,SAAgB,eAAe,MAAqB,KAAuC;CACzF,QAAQ,KAAK,MAAb;EACE,KAAK,SACH,OAAO,YAAY,KAAK,OAAO,KAAK,IAAI,KAAK,OAAO,GAAG;EACzD,KAAK;GACH,KAAK,MAAM,KAAK,KAAK,OACnB,IAAI,CAAC,eAAe,GAAG,GAAG,GAAG,OAAO;GAEtC,OAAO;EAET,KAAK;GACH,IAAI,KAAK,MAAM,WAAW,GAAG,OAAO;GACpC,KAAK,MAAM,KAAK,KAAK,OACnB,IAAI,eAAe,GAAG,GAAG,GAAG,OAAO;GAErC,OAAO;EAET,KAAK,OACH,OAAO,CAAC,eAAe,KAAK,MAAM,GAAG;EACvC,KAAK,cAAc;GACjB,MAAM,IAAI,IAAI,KAAK;GACnB,MAAM,YAAY,MAAM,QAAQ,MAAM,KAAA;GACtC,OAAO,KAAK,SAAS,YAAY,CAAC;EACpC;CACF;AACF;AAEA,SAAS,YAAY,OAAe,IAAiB,OAAgB,KAAuC;CAC1G,MAAM,OAAO,IAAI;CACjB,QAAQ,IAAR;EACE,KAAK;GAIH,IAAI,UAAU,MAAM,OAAO,SAAS,QAAQ,SAAS,KAAA;GACrD,OAAO,iBAAiB,MAAM,KAAK;EACrC,KAAK;GACH,IAAI,UAAU,MAAM,OAAO,SAAS,QAAQ,SAAS,KAAA;GACrD,OAAO,CAAC,iBAAiB,MAAM,KAAK;EACtC,KAAK,MACH,OAAO,UAAU,IAAI,KAAK,UAAU,KAAK,KAAK,mBAAmB,MAAM,KAAK,IAAI;EAClF,KAAK,MACH,OAAO,UAAU,IAAI,KAAK,UAAU,KAAK,KAAK,mBAAmB,MAAM,KAAK,IAAI;EAClF,KAAK,OACH,OAAO,UAAU,IAAI,KAAK,UAAU,KAAK,KAAK,mBAAmB,MAAM,KAAK,KAAK;EACnF,KAAK,OACH,OAAO,UAAU,IAAI,KAAK,UAAU,KAAK,KAAK,mBAAmB,MAAM,KAAK,KAAK;EACnF,KAAK;GACH,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO;GAClC,OAAO,MAAM,MAAM,MAAM,iBAAiB,MAAM,CAAC,CAAC;EAEpD,KAAK;GACH,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,OAAO;GAClC,OAAO,CAAC,MAAM,MAAM,MAAM,iBAAiB,MAAM,CAAC,CAAC;EAErD,KAAK,YACH,OAAO,UAAU,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,SAAS,OAAO,KAAK,CAAC;EAC/D,KAAK,cACH,OAAO,UAAU,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,WAAW,OAAO,KAAK,CAAC;EACjE,KAAK,YACH,OAAO,UAAU,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,SAAS,OAAO,KAAK,CAAC;EAC/D,SACE,OAAO;CACX;AACF;AAEA,SAAS,UAAU,OAAyB;CAC1C,OAAO,UAAU,QAAQ,UAAU,KAAA;AACrC;;;AChDA,MAAM,8BAAiG;CACrG,GAAG;CACH,OAAO,QAAiE;EAMtE,OAAO,IAAI,WAAW,cAAc;CACtC;AACF"}
|
|
1
|
+
{"version":3,"file":"runtime.mjs","names":["#codecs"],"sources":["../src/core/idb-adapter.ts","../src/core/idb-filter-expr.ts","../src/core/filter-eval.ts","../src/exports/runtime.ts"],"sourcesContent":["import type { CodecLookup } from \"@prisma/orm-framework/components/codec\";\nimport type { IdbPlanBody } from \"@prisma-idb/driver-idb/runtime\";\nimport type { IdbQueryPlan } from \"./idb-query-plan\";\nimport type { IdbLowererContext, IdbRuntimeAdapterInstance } from \"./runtime-adapter-instance\";\n\n/**\n * Concrete IDB runtime adapter.\n *\n * Implements {@link IdbRuntimeAdapterInstance} — the `lower()` method that\n * translates an {@link IdbQueryPlan} into an {@link IdbPlanBody} ready for\n * the driver.\n *\n * `lower()` is a structural passthrough: the `idbPlan` carried by\n * `IdbQueryPlan` is already execution-ready because IDB has no query\n * language to compile from. Every current `idb/*` codec is an identity\n * transform for stored values, so no field needs encoding.\n *\n * The `codecs` constructor parameter matches the framework adapter shape and\n * is the extension point for field encoding with non-identity codecs.\n */\nexport class IdbAdapter implements IdbRuntimeAdapterInstance {\n readonly familyId = \"idb\" as const;\n readonly targetId = \"idb\" as const;\n\n readonly #codecs: CodecLookup;\n\n constructor(codecs: CodecLookup) {\n this.#codecs = codecs;\n }\n\n lower(plan: IdbQueryPlan, ctx: IdbLowererContext): Promise<IdbPlanBody> {\n // If a codec ever transforms stored values, encode plan.idbPlan's\n // record and key fields here: resolve each field's codec through\n // this.#codecs and ctx.contract, then call codec.encode(value, ctx).\n void this.#codecs; // codec registry for per-field encoding\n void ctx.contract; // contract storage schema (field→codec resolution)\n void ctx.signal; // AbortSignal for cooperative cancellation\n return Promise.resolve(plan.idbPlan);\n }\n}\n","/**\n * Filter expression AST for IDB queries.\n *\n * Plain frozen objects (not classes) — IDB has no codec trait gating to\n * worry about and no visitor pattern needed (a recursive `evaluateFilter`\n * is plenty). Mirrors the design of Prisma ORM's Mongo family\n * (`MongoFieldFilter`, `MongoAndExpr`, ...) and the SQL ORM's `BinaryExpr`,\n * but with the class machinery stripped out.\n *\n * The AST is carried on `IdbQueryAst` (intent layer) and lowered into an\n * `IdbRowFilter` closure that the driver applies during cursor scans —\n * keeping the driver free of any AST imports.\n */\n\nexport type IdbFilterOp =\n \"eq\" | \"neq\" | \"gt\" | \"lt\" | \"gte\" | \"lte\" | \"in\" | \"notIn\" | \"contains\" | \"startsWith\" | \"endsWith\";\n\n/** Comparison / membership predicate on a single field. */\nexport interface IdbFieldFilter {\n readonly kind: \"field\";\n readonly field: string;\n readonly op: IdbFilterOp;\n readonly value: unknown;\n}\n\n/** Conjunction. Empty `exprs` is truthy (vacuously true). */\nexport interface IdbAndExpr {\n readonly kind: \"and\";\n readonly exprs: ReadonlyArray<IdbFilterExpr>;\n}\n\n/** Disjunction. Empty `exprs` is falsy. */\nexport interface IdbOrExpr {\n readonly kind: \"or\";\n readonly exprs: ReadonlyArray<IdbFilterExpr>;\n}\n\n/** Logical NOT. */\nexport interface IdbNotExpr {\n readonly kind: \"not\";\n readonly expr: IdbFilterExpr;\n}\n\n/**\n * Null check. Distinct from `eq null` because IDB serialises absent\n * fields as `undefined`; a null check treats `null` and `undefined`\n * as equivalent (matching the shorthand `where({ field: null })`).\n */\nexport interface IdbNullCheckExpr {\n readonly kind: \"null-check\";\n readonly field: string;\n readonly isNull: boolean;\n}\n\nexport type IdbFilterExpr = IdbFieldFilter | IdbAndExpr | IdbOrExpr | IdbNotExpr | IdbNullCheckExpr;\n\n// ── Factory helpers ───────────────────────────────────────────────────────────\n\n/** Build a frozen field-filter node. */\nexport const fieldFilter = (field: string, op: IdbFilterOp, value: unknown): IdbFieldFilter =>\n Object.freeze({ kind: \"field\", field, op, value });\n\n/** Build a frozen AND combinator with a frozen `exprs` array. */\nexport const andExpr = (exprs: ReadonlyArray<IdbFilterExpr>): IdbAndExpr =>\n Object.freeze({ kind: \"and\", exprs: Object.freeze([...exprs]) });\n\n/** Build a frozen OR combinator with a frozen `exprs` array. */\nexport const orExpr = (exprs: ReadonlyArray<IdbFilterExpr>): IdbOrExpr =>\n Object.freeze({ kind: \"or\", exprs: Object.freeze([...exprs]) });\n\n/** Build a frozen NOT combinator. */\nexport const notExpr = (expr: IdbFilterExpr): IdbNotExpr => Object.freeze({ kind: \"not\", expr });\n\n/** Build a frozen null-check node. */\nexport const nullCheckExpr = (field: string, isNull: boolean): IdbNullCheckExpr =>\n Object.freeze({ kind: \"null-check\", field, isNull });\n\n// ── Shorthand → expression ────────────────────────────────────────────────────\n\n/**\n * Convert a shorthand equality object (e.g. `{ active: true, email: \"x\" }`)\n * into the canonical AST form. `undefined` entries are dropped; `null`\n * values become null-checks rather than literal-null equalities (IDB\n * stores absent fields as `undefined`, so a literal-null equality misses).\n *\n * Returns `undefined` when the input has no usable entries — callers can\n * skip filter installation in that case rather than testing an empty\n * AND node every row.\n */\nexport function shorthandToFilterExpr(filters: Record<string, unknown>): IdbFilterExpr | undefined {\n const exprs: IdbFilterExpr[] = [];\n for (const [field, value] of Object.entries(filters)) {\n if (value === undefined) continue;\n if (value === null) {\n exprs.push(nullCheckExpr(field, true));\n continue;\n }\n exprs.push(fieldFilter(field, \"eq\", value));\n }\n if (exprs.length === 0) return undefined;\n return exprs.length === 1 ? exprs[0]! : andExpr(exprs);\n}\n","/**\n * Pure-JS evaluator for {@link IdbFilterExpr}.\n *\n * The driver's `IdbRowFilter` type stays as `(row) => boolean` — the\n * accessor builds a closure that calls `evaluateFilter(expr, row)` and\n * passes that to the driver. The driver therefore never imports the\n * adapter's AST types, and keeps no dependency on the adapter.\n *\n * Equality and ordering compare values the way IndexedDB compares keys, so\n * a filter gives the same answer whether it runs here or through an index\n * key range. Plain `===` would never match two equal `Date`s or byte arrays,\n * because values read back from IndexedDB are fresh objects. String\n * operations coerce both sides via `String(...)` so they work on numbers too.\n */\n\nimport { compareFieldValues, fieldValuesEqual } from \"@prisma-idb/target-idb/runtime\";\nimport type { IdbFilterExpr, IdbFilterOp } from \"./idb-filter-expr\";\n\n/** Evaluate an AST node against a single row. Returns `true` to keep the row. */\nexport function evaluateFilter(expr: IdbFilterExpr, row: Record<string, unknown>): boolean {\n switch (expr.kind) {\n case \"field\":\n return evalFieldOp(expr.field, expr.op, expr.value, row);\n case \"and\": {\n for (const e of expr.exprs) {\n if (!evaluateFilter(e, row)) return false;\n }\n return true;\n }\n case \"or\": {\n if (expr.exprs.length === 0) return false;\n for (const e of expr.exprs) {\n if (evaluateFilter(e, row)) return true;\n }\n return false;\n }\n case \"not\":\n return !evaluateFilter(expr.expr, row);\n case \"null-check\": {\n const v = row[expr.field];\n const isNullish = v === null || v === undefined;\n return expr.isNull ? isNullish : !isNullish;\n }\n }\n}\n\nfunction evalFieldOp(field: string, op: IdbFilterOp, value: unknown, row: Record<string, unknown>): boolean {\n const cell = row[field];\n switch (op) {\n case \"eq\":\n // `eq` treats null and undefined as equivalent so the shorthand path\n // (`{ field: someValue }`) keeps working when stored rows omit the\n // field. Literal-null equality goes through `null-check` instead.\n if (value === null) return cell === null || cell === undefined;\n return fieldValuesEqual(cell, value);\n case \"neq\":\n if (value === null) return cell !== null && cell !== undefined;\n return !fieldValuesEqual(cell, value);\n case \"gt\":\n return isPresent(cell) && isPresent(value) && compareFieldValues(cell, value) > 0;\n case \"lt\":\n return isPresent(cell) && isPresent(value) && compareFieldValues(cell, value) < 0;\n case \"gte\":\n return isPresent(cell) && isPresent(value) && compareFieldValues(cell, value) >= 0;\n case \"lte\":\n return isPresent(cell) && isPresent(value) && compareFieldValues(cell, value) <= 0;\n case \"in\": {\n if (!Array.isArray(value)) return false;\n return value.some((v) => fieldValuesEqual(cell, v));\n }\n case \"notIn\": {\n if (!Array.isArray(value)) return true;\n return !value.some((v) => fieldValuesEqual(cell, v));\n }\n case \"contains\":\n return isPresent(cell) && String(cell).includes(String(value));\n case \"startsWith\":\n return isPresent(cell) && String(cell).startsWith(String(value));\n case \"endsWith\":\n return isPresent(cell) && String(cell).endsWith(String(value));\n default:\n return false;\n }\n}\n\nfunction isPresent(value: unknown): boolean {\n return value !== null && value !== undefined;\n}\n","import type { RuntimeAdapterDescriptor, ExecutionStack } from \"@prisma/orm-framework/components/execution\";\nimport { idbCodecLookup } from \"@prisma-idb/target-idb/runtime\";\nimport { idbAdapterDescriptorMeta } from \"../core/descriptor-meta\";\nimport { IdbAdapter } from \"../core/idb-adapter\";\nimport type { IdbRuntimeAdapterInstance } from \"../core/runtime-adapter-instance\";\n\nexport type { IdbRuntimeAdapterInstance, IdbLowererContext } from \"../core/runtime-adapter-instance\";\nexport type { IdbQueryPlan } from \"../core/idb-query-plan\";\nexport type {\n IdbQueryAst,\n IdbFindManyAst,\n IdbFindUniqueAst,\n IdbCreateAst,\n IdbDeleteAst,\n IdbUpdateAst,\n IdbUpdateAllAst,\n IdbUpdateCountAst,\n IdbCreateAllAst,\n IdbCreateCountAst,\n IdbDeleteAllAst,\n IdbDeleteCountAst,\n IdbCountAst,\n IdbAggregateAst,\n IdbGroupByAst,\n IdbAggregateRequest,\n} from \"../core/idb-query-ast\";\nexport type {\n IdbFilterExpr,\n IdbFieldFilter,\n IdbAndExpr,\n IdbOrExpr,\n IdbNotExpr,\n IdbNullCheckExpr,\n IdbFilterOp,\n} from \"../core/idb-filter-expr\";\nexport { fieldFilter, andExpr, orExpr, notExpr, nullCheckExpr, shorthandToFilterExpr } from \"../core/idb-filter-expr\";\nexport { evaluateFilter } from \"../core/filter-eval\";\nexport { IdbAdapter } from \"../core/idb-adapter\";\n\nconst idbRuntimeAdapterDescriptor: RuntimeAdapterDescriptor<\"idb\", \"idb\", IdbRuntimeAdapterInstance> = {\n ...idbAdapterDescriptorMeta,\n create(_stack: ExecutionStack<\"idb\", \"idb\">): IdbRuntimeAdapterInstance {\n // Construct the adapter with the real IDB codec lookup so per-field\n // encoding works when non-identity codecs are added. The current set\n // is all-identity, so output behavior is unchanged; this wiring makes\n // the descriptor-built adapter match the hand-constructed one in\n // `createIdbClient`.\n return new IdbAdapter(idbCodecLookup);\n },\n};\n\nexport default idbRuntimeAdapterDescriptor;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-idb/adapter-idb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Prisma 8 IDB family — adapter (lowers query AST to opaque IDB plan body)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"./package.json": "./package.json"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@prisma-idb/driver-idb": "0.
|
|
33
|
-
"@prisma-idb/target-idb": "0.
|
|
32
|
+
"@prisma-idb/driver-idb": "0.11.0",
|
|
33
|
+
"@prisma-idb/target-idb": "0.11.0",
|
|
34
34
|
"@prisma/orm-framework": "8.0.0-rc.12"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|