@absolutejs/sync 1.2.0 → 1.4.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.
@@ -1,4 +1,6 @@
1
1
  // @bun
2
+ var __require = import.meta.require;
3
+
2
4
  // src/adapters/drizzle/topics.ts
3
5
  import {
4
6
  Column,
@@ -261,5 +263,5 @@ export {
261
263
  UnsupportedDrizzleFilterError
262
264
  };
263
265
 
264
- //# debugId=A28CA296A764961764756E2164756E21
266
+ //# debugId=8F10A80D3C4C330164756E2164756E21
265
267
  //# sourceMappingURL=index.js.map
@@ -8,7 +8,7 @@
8
8
  "import type { SQL, Table } from 'drizzle-orm';\nimport { extractKeyFromWhere, keyTopic, tableTopic } from './topics';\n\nexport type DeriveReadTopicsOptions = {\n\t/**\n\t * Column (its JS property name on the table) to treat as the row key when\n\t * narrowing to a `table:key` topic. Defaults to the table's single\n\t * primary-key column; composite or absent primary keys disable row-level\n\t * narrowing.\n\t */\n\tkeyColumn?: string;\n};\n\nexport type DerivedReadTopics = {\n\t/** Topics this read depends on — subscribe to all of them. */\n\ttopics: string[];\n\t/**\n\t * `true` when derivation narrowed to a specific row (`table:key`); `false`\n\t * when it fell back to the whole-table topic.\n\t */\n\trowLevel: boolean;\n};\n\n/**\n * Derive the reactive topics a read of `table` (optionally filtered by `where`)\n * depends on. A recognised primary-key equality narrows to a single `table:key`\n * topic; everything else subscribes to the whole-table topic, over-invalidating\n * a little rather than missing an update.\n *\n * @example\n * deriveReadTopics(users); // { topics: ['users'], rowLevel: false }\n * deriveReadTopics(users, eq(users.id, 5)); // { topics: ['users:5'], rowLevel: true }\n * deriveReadTopics(users, gt(users.id, 5)); // { topics: ['users'], rowLevel: false }\n */\nexport const deriveReadTopics = (\n\ttable: Table,\n\twhere?: SQL,\n\toptions: DeriveReadTopicsOptions = {}\n): DerivedReadTopics => {\n\tconst key =\n\t\twhere === undefined\n\t\t\t? undefined\n\t\t\t: extractKeyFromWhere(table, where, options.keyColumn);\n\n\tif (key === undefined) {\n\t\treturn { topics: [tableTopic(table)], rowLevel: false };\n\t}\n\treturn { topics: [keyTopic(table, key)], rowLevel: true };\n};\n",
9
9
  "import type { SQL, Table } from 'drizzle-orm';\nimport type { ReactiveHub } from '../../reactiveHub';\nimport {\n\textractKeyFromWhere,\n\textractRowKeys,\n\tkeyTopic,\n\ttableTopic\n} from './topics';\n\n/**\n * Drizzle write-side topic publishing (Tier 2).\n *\n * The mirror of {@link deriveReadTopics}: after a mutation commits, publish the\n * topics it invalidates so subscribed reads refetch. Every change publishes the\n * **table** topic (so list/table queries refresh) plus a **row** topic per\n * affected key (so row-level queries refresh) — the exact topics the read side\n * subscribes to.\n *\n * These are the \"route mutations through us\" change source from the roadmap:\n * call them right after your durable write. They work on any DB Drizzle supports\n * and never touch DB-specific machinery; out-of-band writes (caught later by CDC\n * adapters) are the only thing they miss.\n */\n\n/** The kind of mutation, forwarded in the change-event payload. */\nexport type ChangeOp = 'insert' | 'update' | 'delete';\n\n/** Payload carried by every change event the write side publishes. */\nexport type ChangePayload = {\n\t/** Name of the table that changed. */\n\ttable: string;\n\t/** Mutation kind, when the caller provided it. */\n\top?: ChangeOp;\n\t/** Affected row keys (empty for a table-wide change). */\n\tkeys: (string | number)[];\n};\n\nexport type PublishChangeOptions = {\n\t/** Row keys that changed; each emits a `table:key` topic. */\n\tkeys?: ReadonlyArray<string | number>;\n\top?: ChangeOp;\n};\n\n/**\n * Publish the reactive topics a change to `table` invalidates: the whole-table\n * topic (always) plus a `table:key` topic per affected row. Call after the\n * durable write commits. Returns the (de-duplicated) topics published.\n */\nexport const publishChange = (\n\thub: Pick<ReactiveHub, 'publish'>,\n\ttable: Table,\n\toptions: PublishChangeOptions = {}\n): string[] => {\n\tconst name = tableTopic(table);\n\tconst keys = options.keys === undefined ? [] : [...new Set(options.keys)];\n\tconst payload: ChangePayload = { table: name, op: options.op, keys };\n\tconst topics = [\n\t\t...new Set([name, ...keys.map((key) => keyTopic(table, key))])\n\t];\n\tfor (const topic of topics) {\n\t\thub.publish(topic, payload);\n\t}\n\treturn topics;\n};\n\nexport type PublishRowsOptions = {\n\t/** Key column (JS property name); defaults to the table's primary key. */\n\tkeyColumn?: string;\n\top?: ChangeOp;\n};\n\n/**\n * Publish change topics for a set of rows — typically the output of a mutation's\n * `.returning()`, which yields real keys including auto-generated ones. Reads\n * each row's primary-key column (or `keyColumn`) to emit `table:key` topics.\n *\n * @example\n * const rows = await db.insert(users).values(input).returning();\n * publishRows(hub, users, rows, { op: 'insert' });\n */\nexport const publishRows = (\n\thub: Pick<ReactiveHub, 'publish'>,\n\ttable: Table,\n\trows: ReadonlyArray<Record<string, unknown>>,\n\toptions: PublishRowsOptions = {}\n): string[] =>\n\tpublishChange(hub, table, {\n\t\tkeys: extractRowKeys(table, rows, options.keyColumn),\n\t\top: options.op\n\t});\n\nexport type PublishWhereOptions = {\n\t/** Key column (JS property name); defaults to the table's primary key. */\n\tkeyColumn?: string;\n\top?: ChangeOp;\n};\n\n/**\n * Publish change topics for an `update`/`delete` identified by a `where` filter.\n * A simple primary-key equality narrows to that row's topic; any other filter\n * publishes just the table topic, so every affected subscriber refetches and\n * re-evaluates.\n *\n * @example\n * await db.update(users).set(patch).where(eq(users.id, id));\n * publishWhere(hub, users, eq(users.id, id), { op: 'update' });\n */\nexport const publishWhere = (\n\thub: Pick<ReactiveHub, 'publish'>,\n\ttable: Table,\n\twhere: SQL,\n\toptions: PublishWhereOptions = {}\n): string[] => {\n\tconst key = extractKeyFromWhere(table, where, options.keyColumn);\n\treturn publishChange(hub, table, {\n\t\tkeys: key === undefined ? [] : [key],\n\t\top: options.op\n\t});\n};\n"
10
10
  ],
11
- "mappings": ";;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBO,IAAM,aAAa,CAAC,UAAyB,aAAa,KAAK;AAG/D,IAAM,WAAW,CAAC,OAAc,QACtC,GAAG,aAAa,KAAK,KAAK;AAcpB,IAAM,mBAAmB,CAC/B,OACA,cAC6B;AAAA,EAC7B,MAAM,UAAU,gBAAgB,KAAK;AAAA,EACrC,IAAI,cAAc,WAAW;AAAA,IAC5B,MAAM,SAAS,QAAQ;AAAA,IACvB,OAAO,WAAW,YACf,YACA,EAAE,UAAU,WAAW,QAAQ,OAAO,KAAK;AAAA,EAC/C;AAAA,EACA,MAAM,YAAY,OAAO,QAAQ,OAAO,EAAE,OACzC,IAAI,YAAY,OAAO,OACxB;AAAA,EACA,MAAM,UAAU,UAAU,WAAW,IAAI,UAAU,KAAK;AAAA,EACxD,OAAO,YAAY,YAChB,YACA,EAAE,UAAU,QAAQ,IAAI,QAAQ,QAAQ,GAAG,KAAK;AAAA;AAa7C,IAAM,sBAAsB,CAClC,OACA,OACA,cACiC;AAAA,EACjC,MAAM,WAAW,iBAAiB,OAAO,SAAS;AAAA,EAClD,IAAI,aAAa,WAAW;AAAA,IAC3B;AAAA,EACD;AAAA,EAEA,MAAM,SAAmB,MAAoC;AAAA,EAC7D,IAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAAA,IAC3B;AAAA,EACD;AAAA,EAEA,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI,aAAa;AAAA,EACjB,IAAI,WAAW;AAAA,EAEf,WAAW,SAAS,QAAQ;AAAA,IAC3B,IAAI,GAAG,OAAO,GAAG,GAAG;AAAA,MAEnB;AAAA,IACD;AAAA,IACA,IAAI,GAAG,OAAO,MAAM,GAAG;AAAA,MACtB,IAAI,WAAW,WAAW;AAAA,QACzB,aAAa;AAAA,MACd;AAAA,MACA,SAAS;AAAA,IACV,EAAO,SAAI,GAAG,OAAO,KAAK,GAAG;AAAA,MAC5B,IAAI,UAAU,WAAW;AAAA,QACxB,aAAa;AAAA,MACd;AAAA,MACA,QAAQ;AAAA,IACT,EAAO;AAAA,MACN,MAAM,SAAkB,MAA8B;AAAA,MACtD,IAAI,MAAM,QAAQ,MAAK,GAAG;AAAA,QACzB,YAAY,OAAM,KAAK,EAAE;AAAA,MAC1B;AAAA;AAAA,EAEF;AAAA,EAEA,IAAI,cAAc,WAAW,aAAa,UAAU,WAAW;AAAA,IAC9D;AAAA,EACD;AAAA,EACA,IAAI,SAAS,KAAK,MAAM,KAAK;AAAA,IAC5B;AAAA,EACD;AAAA,EACA,IAAI,OAAO,SAAS,SAAS,QAAQ;AAAA,IACpC;AAAA,EACD;AAAA,EACA,IAAI,aAAa,OAAO,KAAK,MAAM,aAAa,KAAK,GAAG;AAAA,IACvD;AAAA,EACD;AAAA,EAEA,MAAM,QAAiB,MAAM;AAAA,EAC7B,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,WAClD,QACA;AAAA;AAQG,IAAM,iBAAiB,CAC7B,OACA,MACA,cACyB;AAAA,EACzB,MAAM,WAAW,iBAAiB,OAAO,SAAS;AAAA,EAClD,IAAI,aAAa,WAAW;AAAA,IAC3B,OAAO,CAAC;AAAA,EACT;AAAA,EACA,MAAM,OAA4B,CAAC;AAAA,EACnC,WAAW,OAAO,MAAM;AAAA,IACvB,MAAM,QAAQ,IAAI,SAAS;AAAA,IAC3B,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;AAAA,MAC3D,KAAK,KAAK,KAAK;AAAA,IAChB;AAAA,EACD;AAAA,EACA,OAAO;AAAA;;ACpJR,yBAAS;;;ACAT,mBAAS,4BAAQ,wBAAiB,cAAI,eAAO;AAAA;AAStC,MAAM,sCAAsC,MAAM;AAAA,EACxD,WAAW,CAAC,QAAgB;AAAA,IAC3B,MAAM,mCAAmC,uBAAuB;AAAA,IAChE,KAAK,OAAO;AAAA;AAEd;AAEA,IAAM,SAAS,CAAC,UAAkC,iBAAiB;AAEnE,IAAM,SAAS,CAAC,OAAgB,YAA8B;AAAA,EAC7D,IAAI,YAAY,MAAM;AAAA,IACrB,OAAO,UAAU,QAAQ,UAAU;AAAA,EACpC;AAAA,EACA,IAAI,OAAO,KAAK,KAAK,OAAO,OAAO,GAAG;AAAA,IACrC,OAAO,MAAM,QAAQ,MAAM,QAAQ,QAAQ;AAAA,EAC5C;AAAA,EACA,OAAO,UAAU;AAAA;AAGlB,IAAM,QAAQ,CAAC,UACd,OAAO,KAAK,IAAI,MAAM,QAAQ,IAAK;AAEpC,IAAM,UAAU,CAAC,OAAgB,YAA6B;AAAA,EAC7D,MAAM,IAAI,MAAM,KAAK;AAAA,EACrB,MAAM,IAAI,MAAM,OAAO;AAAA,EACvB,IAAI,IAAI,GAAG;AAAA,IACV,OAAO;AAAA,EACR;AAAA,EACA,IAAI,IAAI,GAAG;AAAA,IACV,OAAO;AAAA,EACR;AAAA,EACA,OAAO;AAAA;AAGR,IAAM,aAAa,CAAC,UACnB,UAAU,QAAQ,UAAU;AAiB7B,IAAM,WAAW,CAAC,WAAkC;AAAA,EACnD,MAAM,OAAiB,CAAC;AAAA,EACxB,MAAM,SAAoB,CAAC;AAAA,EAC3B,MAAM,SAAsB,CAAC;AAAA,EAC7B,MAAM,OAAc,CAAC;AAAA,EACrB,MAAM,MAAgB,CAAC;AAAA,EACvB,WAAW,SAAS,QAAQ;AAAA,IAC3B,IAAI,IAAG,OAAO,IAAG,GAAG;AAAA,MACnB,KAAK,KAAK,KAAK;AAAA,IAChB,EAAO,SAAI,IAAG,OAAO,OAAM,GAAG;AAAA,MAC7B,KAAK,KAAK,KAAK;AAAA,IAChB,EAAO,SAAI,IAAG,OAAO,MAAK,GAAG;AAAA,MAC5B,OAAO,KAAK,MAAM,KAAK;AAAA,IACxB,EAAO,SAAI,MAAM,QAAQ,KAAK,GAAG;AAAA,MAChC,OAAO,KACN,MAAM,IAAI,CAAC,YACV,IAAG,SAAS,MAAK,IAAI,QAAQ,QAAQ,OACtC,CACD;AAAA,IACD,EAAO;AAAA,MACN,MAAM,MAAO,MAA8B;AAAA,MAC3C,MAAM,QACL,MAAM,QAAQ,GAAG,IAAI,IAAI,KAAK,EAAE,IAAI,OAAO,OAAO,EAAE,GACnD,KAAK;AAAA,MACP,IAAI,SAAS,MAAM,SAAS,OAAO,SAAS,KAAK;AAAA,QAChD,IAAI,KAAK,IAAI;AAAA,MACd;AAAA;AAAA,EAEF;AAAA,EAEA,OAAO,EAAE,QAAQ,MAAM,KAAK,QAAQ,KAAK;AAAA;AAG1C,IAAM,eAAe,CACpB,QACA,IACA,QACA,QACA,KACA,YACa;AAAA,EACb,MAAM,OAAO,QAAQ,MAAM;AAAA,EAC3B,IAAI,SAAS,WAAW;AAAA,IACvB,MAAM,IAAI,8BAA8B,UAAU,OAAO,MAAM;AAAA,EAChE;AAAA,EACA,MAAM,QAAQ,IAAI;AAAA,EAClB,MAAM,UAAU,OAAO;AAAA,EACvB,QAAQ;AAAA,SACF;AAAA,MACJ,OAAO,OAAO,OAAO,OAAO;AAAA,SACxB;AAAA,MACJ,OAAO,CAAC,OAAO,OAAO,OAAO;AAAA,SACzB;AAAA,MACJ,OAAO,WAAW,KAAK,KAAK,QAAQ,OAAO,OAAO,IAAI;AAAA,SAClD;AAAA,MACJ,OAAO,WAAW,KAAK,KAAK,QAAQ,OAAO,OAAO,KAAK;AAAA,SACnD;AAAA,MACJ,OAAO,WAAW,KAAK,KAAK,QAAQ,OAAO,OAAO,IAAI;AAAA,SAClD;AAAA,MACJ,OAAO,WAAW,KAAK,KAAK,QAAQ,OAAO,OAAO,KAAK;AAAA,SACnD;AAAA,MACJ,QAAQ,OAAO,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,OAAO,OAAO,IAAI,CAAC;AAAA,SACvD;AAAA,MACJ,OAAO,EAAE,OAAO,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,OAAO,OAAO,IAAI,CAAC;AAAA,SACxD;AAAA,MACJ,OAAO,UAAU,QAAQ,UAAU;AAAA,SAC/B;AAAA,MACJ,OAAO,UAAU,QAAQ,UAAU;AAAA;AAAA,MAEnC,MAAM,IAAI,8BAA8B,EAAE;AAAA;AAAA;AAI7C,IAAM,oBAAoB,CACzB,MACA,KACA,YACa;AAAA,EACb,QAAQ,MAAM,QAAQ,QAAQ,MAAM,QAAQ,SAC1C,KAA+C,WACjD;AAAA,EAGA,IACC,IAAI,WAAW,KACf,IAAI,OAAO,SACX,KAAK,WAAW,KAChB,KAAK,WAAW,GACf;AAAA,IACD,OAAO,CAAC,kBAAkB,KAAK,IAAK,KAAK,OAAO;AAAA,EACjD;AAAA,EAEA,IAAI,KAAK,WAAW,KAAK,KAAK,WAAW,KAAK,IAAI,WAAW,GAAG;AAAA,IAC/D,OAAO,kBAAkB,KAAK,IAAK,KAAK,OAAO;AAAA,EAChD;AAAA,EAEA,IAAI,KAAK,WAAW,KAAK,KAAK,UAAU,KAAK,IAAI,SAAS,GAAG;AAAA,IAC5D,MAAM,aAAa,IAAI;AAAA,IACvB,KACE,eAAe,SAAS,eAAe,SACxC,IAAI,MAAM,CAAC,OAAO,OAAO,UAAU,GAClC;AAAA,MACD,MAAM,UAAU,KAAK,IAAI,CAAC,QACzB,kBAAkB,KAAK,KAAK,OAAO,CACpC;AAAA,MACA,OAAO,eAAe,QACnB,QAAQ,MAAM,OAAO,IACrB,QAAQ,KAAK,OAAO;AAAA,IACxB;AAAA,IACA,MAAM,IAAI,8BAA8B,IAAI,KAAK,GAAG,CAAC;AAAA,EACtD;AAAA,EAEA,IAAI,KAAK,WAAW,KAAK,KAAK,WAAW,KAAK,IAAI,WAAW,GAAG;AAAA,IAC/D,OAAO,aAAa,KAAK,IAAK,IAAI,IAAK,QAAQ,QAAQ,KAAK,OAAO;AAAA,EACpE;AAAA,EACA,MAAM,IAAI,8BACT,IAAI,KAAK,GAAG,KAAK,wBAClB;AAAA;AAWM,IAAM,sBAAsB,CAClC,OACA,OACA,QACa;AAAA,EACb,MAAM,aAAa,IAAI;AAAA,EACvB,YAAY,MAAM,WAAW,OAAO,QAAQ,iBAAgB,KAAK,CAAC,GAAG;AAAA,IACpE,WAAW,IAAI,OAAO,MAAM,IAAI;AAAA,EACjC;AAAA,EAEA,OAAO,kBAAkB,OAAO,KAAK,CAAC,WACrC,WAAW,IAAI,OAAO,IAAI,CAC3B;AAAA;;;ADnKM,IAAM,oBAAoB,CAChC,YACqC;AAAA,EACrC,MAAM,UAAU,iBACf,QAAQ,OACR,QAAQ,SACT,GAAG;AAAA,EACH,MAAM,MACL,QAAQ,QACP,CAAC,QACD,YAAY,YACR,IAA+B,WAC/B,IAAuB;AAAA,EAE7B,OAAO;AAAA,IACN,MAAM,QAAQ;AAAA,IACd,QAAQ,CAAC,cAAa,QAAQ,KAAK,CAAC;AAAA,IACpC,SAAS,CAAC,QAAQ,QACjB,QAAQ,KAAK,QAAQ,MAAM,QAAQ,GAAG,GAAG,QAAQ,GAAG;AAAA,IACrD,OAAO,CAAC,KAAK,QAAQ,QACpB,oBACC,QAAQ,OACR,QAAQ,MAAM,QAAQ,GAAG,GACzB,GACD;AAAA,IACD;AAAA,IACA,WAAW,QAAQ;AAAA,EACpB;AAAA;;AE/BM,IAAM,mBAAmB,CAC/B,OACA,OACA,UAAmC,CAAC,MACb;AAAA,EACvB,MAAM,MACL,UAAU,YACP,YACA,oBAAoB,OAAO,OAAO,QAAQ,SAAS;AAAA,EAEvD,IAAI,QAAQ,WAAW;AAAA,IACtB,OAAO,EAAE,QAAQ,CAAC,WAAW,KAAK,CAAC,GAAG,UAAU,MAAM;AAAA,EACvD;AAAA,EACA,OAAO,EAAE,QAAQ,CAAC,SAAS,OAAO,GAAG,CAAC,GAAG,UAAU,KAAK;AAAA;;ACClD,IAAM,gBAAgB,CAC5B,KACA,OACA,UAAgC,CAAC,MACnB;AAAA,EACd,MAAM,OAAO,WAAW,KAAK;AAAA,EAC7B,MAAM,OAAO,QAAQ,SAAS,YAAY,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,QAAQ,IAAI,CAAC;AAAA,EACxE,MAAM,UAAyB,EAAE,OAAO,MAAM,IAAI,QAAQ,IAAI,KAAK;AAAA,EACnE,MAAM,SAAS;AAAA,IACd,GAAG,IAAI,IAAI,CAAC,MAAM,GAAG,KAAK,IAAI,CAAC,QAAQ,SAAS,OAAO,GAAG,CAAC,CAAC,CAAC;AAAA,EAC9D;AAAA,EACA,WAAW,SAAS,QAAQ;AAAA,IAC3B,IAAI,QAAQ,OAAO,OAAO;AAAA,EAC3B;AAAA,EACA,OAAO;AAAA;AAkBD,IAAM,cAAc,CAC1B,KACA,OACA,MACA,UAA8B,CAAC,MAE/B,cAAc,KAAK,OAAO;AAAA,EACzB,MAAM,eAAe,OAAO,MAAM,QAAQ,SAAS;AAAA,EACnD,IAAI,QAAQ;AACb,CAAC;AAkBK,IAAM,eAAe,CAC3B,KACA,OACA,OACA,UAA+B,CAAC,MAClB;AAAA,EACd,MAAM,MAAM,oBAAoB,OAAO,OAAO,QAAQ,SAAS;AAAA,EAC/D,OAAO,cAAc,KAAK,OAAO;AAAA,IAChC,MAAM,QAAQ,YAAY,CAAC,IAAI,CAAC,GAAG;AAAA,IACnC,IAAI,QAAQ;AAAA,EACb,CAAC;AAAA;",
12
- "debugId": "A28CA296A764961764756E2164756E21",
11
+ "mappings": "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",
12
+ "debugId": "8F10A80D3C4C330164756E2164756E21",
13
13
  "names": []
14
14
  }
@@ -1,4 +1,6 @@
1
1
  // @bun
2
+ var __require = import.meta.require;
3
+
2
4
  // src/engine/pollingSource.ts
3
5
  var OP_BY_NAME = {
4
6
  insert: "insert",
@@ -167,5 +169,5 @@ export {
167
169
  createPollingChangeSource
168
170
  };
169
171
 
170
- //# debugId=48EE1E12A50EB47064756E2164756E21
172
+ //# debugId=5FBCD902F44C556164756E2164756E21
171
173
  //# sourceMappingURL=index.js.map
@@ -5,7 +5,7 @@
5
5
  "import type { ChangeSource, EmitChange, ParsedChange, RowOp } from './types';\n\n/**\n * A database-agnostic CDC {@link ChangeSource} that tails an append-only\n * changelog (outbox) table and emits its rows into the engine.\n *\n * This is the portable way to catch out-of-band writes on databases without a\n * native push channel — MySQL (no `LISTEN/NOTIFY`) and SQLite (no update hook\n * reachable from the JS runtime). Install per-table triggers that append to the\n * changelog (see `@absolutejs/sync/mysql` and `/sqlite`), then poll it here. It\n * is also a fine fallback for Postgres when you'd rather not run `LISTEN`.\n *\n * Driver-agnostic: you supply `poll(sinceSeq)` — a single\n * `SELECT seq, tbl, op, payload FROM <changelog> WHERE seq > ? ORDER BY seq` run\n * with your client — and the adapter tracks the cursor, parses each row, emits,\n * and advances. Delivery is at-least-once across crashes (a row may re-emit if\n * the process dies mid-batch); the engine's per-key last-write-wins makes that\n * safe. Use `onProcessed` to prune the changelog once a watermark is durable.\n */\n\nconst OP_BY_NAME: Record<string, RowOp> = {\n\tinsert: 'insert',\n\tINSERT: 'insert',\n\tupdate: 'update',\n\tUPDATE: 'update',\n\tdelete: 'delete',\n\tDELETE: 'delete'\n};\n\n/** One changelog row, as returned by your `poll` query. */\nexport type OutboxRow = {\n\t/** Monotonic sequence (the cursor advances to the max seen). */\n\tseq: number;\n\t/** Source table the change happened on. */\n\ttbl: string;\n\t/** `insert` | `update` | `delete` (upper- or lower-case). */\n\top: string;\n\t/** The row's captured values — a JSON string or an already-parsed object. */\n\tpayload: unknown;\n};\n\n/**\n * Default changelog-row parser: normalizes `op`, JSON-parses a string `payload`,\n * and returns `{ table, change }`. Returns `undefined` for a malformed row so it\n * is skipped (and its `seq` still advances the cursor) rather than wedging the\n * feed.\n */\nexport const parseOutboxRow = (row: OutboxRow): ParsedChange | undefined => {\n\tif (typeof row.tbl !== 'string') {\n\t\treturn undefined;\n\t}\n\tconst op = OP_BY_NAME[row.op];\n\tif (op === undefined) {\n\t\treturn undefined;\n\t}\n\tlet payload: unknown = row.payload;\n\tif (typeof payload === 'string') {\n\t\ttry {\n\t\t\tpayload = JSON.parse(payload);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\tif (typeof payload !== 'object' || payload === null) {\n\t\treturn undefined;\n\t}\n\treturn { table: row.tbl, change: { op, row: payload } };\n};\n\nexport type PollingChangeSourceOptions = {\n\t/**\n\t * Fetch changelog rows with `seq > sinceSeq`, ordered by `seq` ascending.\n\t * e.g. `(since) => sql\\`SELECT seq, tbl, op, payload FROM absolute_sync_changelog WHERE seq > ${since} ORDER BY seq\\``.\n\t */\n\tpoll: (sinceSeq: number) => Promise<OutboxRow[]> | OutboxRow[];\n\t/** Poll interval in ms. Defaults to 1000. */\n\tintervalMs?: number;\n\t/** Resume cursor (highest `seq` already processed). Defaults to 0. */\n\tstartSeq?: number;\n\t/** Override the row parser (defaults to {@link parseOutboxRow}). */\n\tparse?: (row: OutboxRow) => ParsedChange | undefined;\n\t/** Called after a non-empty batch with the new watermark — prune here. */\n\tonProcessed?: (uptoSeq: number) => void | Promise<void>;\n\t/** Called if a poll throws (the loop keeps running). Defaults to a warning. */\n\tonError?: (error: unknown) => void;\n};\n\n/**\n * Create a polling {@link ChangeSource} over a changelog table. Connect it with\n * `engine.connectSource(...)`; `start` runs an immediate first poll (draining any\n * backlog) and then polls every `intervalMs` until `stop`.\n */\nexport const createPollingChangeSource = (\n\toptions: PollingChangeSourceOptions\n): ChangeSource => {\n\tconst intervalMs = options.intervalMs ?? 1000;\n\tconst parse = options.parse ?? parseOutboxRow;\n\tconst onError =\n\t\toptions.onError ??\n\t\t((error: unknown) => {\n\t\t\tconsole.warn('[sync] polling change source error:', error);\n\t\t});\n\tlet cursor = options.startSeq ?? 0;\n\tlet running = false;\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\n\tconst tick = async (emit: EmitChange): Promise<void> => {\n\t\tif (!running) {\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tconst rows = await options.poll(cursor);\n\t\t\tfor (const row of rows) {\n\t\t\t\tconst parsed = parse(row);\n\t\t\t\tif (parsed !== undefined) {\n\t\t\t\t\tawait emit(parsed.table, parsed.change);\n\t\t\t\t}\n\t\t\t\tif (typeof row.seq === 'number' && row.seq > cursor) {\n\t\t\t\t\tcursor = row.seq;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (rows.length > 0) {\n\t\t\t\tawait options.onProcessed?.(cursor);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tonError(error);\n\t\t}\n\t\tif (running) {\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\tvoid tick(emit);\n\t\t\t}, intervalMs);\n\t\t}\n\t};\n\n\treturn {\n\t\tstart: async (emit) => {\n\t\t\tif (running) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\trunning = true;\n\t\t\tawait tick(emit);\n\t\t},\n\t\tstop: () => {\n\t\t\trunning = false;\n\t\t\tif (timer !== undefined) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\ttimer = undefined;\n\t\t\t}\n\t\t}\n\t};\n};\n",
6
6
  "import type { ChangeSource, ParsedChange, RowOp } from '../../engine/types';\n\n/**\n * MySQL CDC adapter for @absolutejs/sync (Tier 3, M5).\n *\n * MySQL has no `LISTEN/NOTIFY`, so two pluggable strategies catch out-of-band\n * writes — both behind the engine's {@link ChangeSource} seam:\n *\n * - **Changelog + poll (portable).** Install triggers with\n * {@link mysqlChangelogSchema} and tail the changelog with\n * {@link createPollingChangeSource}. Works anywhere, no extra privileges.\n * - **Binlog (higher throughput).** Wire a binlog reader (e.g. zongji) into\n * {@link mysqlBinlogChangeSource}; it normalizes row events into the change\n * feed. Catches writes without the per-write changelog overhead.\n *\n * Dependency-free — you bring the MySQL client / binlog reader.\n */\n\nexport {\n\tcreatePollingChangeSource,\n\tparseOutboxRow\n} from '../../engine/pollingSource';\nexport type {\n\tOutboxRow,\n\tPollingChangeSourceOptions\n} from '../../engine/pollingSource';\n\nconst DEFAULT_CHANGELOG = 'absolute_sync_changelog';\nconst DEFAULT_PREFIX = 'absolute_sync';\nconst OPS = ['insert', 'update', 'delete'] as const;\n\nexport type MysqlChangelogOptions = {\n\t/** Table name → the column names to capture in the change payload. */\n\ttables: Record<string, string[]>;\n\t/** Changelog table name. Defaults to `absolute_sync_changelog`. */\n\tchangelogTable?: string;\n\t/** Trigger name prefix. Defaults to `absolute_sync`. */\n\tprefix?: string;\n};\n\n/**\n * Generate the SQL that installs the changelog table and per-table\n * insert/update/delete triggers — run it once (e.g. in a migration). Each\n * trigger appends `{ tbl, op, payload }` (payload built with `JSON_OBJECT` from\n * the listed columns) to the changelog for {@link createPollingChangeSource}.\n *\n * Each `CREATE TRIGGER` body is a single statement (no `DELIMITER` needed). The\n * statements are `;`-separated; run them as a script, or split on `;` if your\n * driver executes one statement per call.\n */\nexport const mysqlChangelogSchema = (\n\toptions: MysqlChangelogOptions\n): string => {\n\tconst changelog = options.changelogTable ?? DEFAULT_CHANGELOG;\n\tconst prefix = options.prefix ?? DEFAULT_PREFIX;\n\n\tconst createTable = [\n\t\t`CREATE TABLE IF NOT EXISTS \\`${changelog}\\` (`,\n\t\t'\\tseq BIGINT AUTO_INCREMENT PRIMARY KEY,',\n\t\t'\\ttbl VARCHAR(255) NOT NULL,',\n\t\t'\\top VARCHAR(16) NOT NULL,',\n\t\t'\\tpayload JSON NOT NULL,',\n\t\t'\\tcreated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP',\n\t\t');'\n\t].join('\\n');\n\n\tconst jsonObject = (columns: string[], ref: 'NEW' | 'OLD'): string =>\n\t\t`JSON_OBJECT(${columns\n\t\t\t.map((column) => `'${column}', ${ref}.\\`${column}\\``)\n\t\t\t.join(', ')})`;\n\n\tconst triggers = Object.entries(options.tables).flatMap(\n\t\t([table, columns]) =>\n\t\t\tOPS.map((op) => {\n\t\t\t\tconst ref = op === 'delete' ? 'OLD' : 'NEW';\n\t\t\t\tconst name = `${prefix}_${table}_${op}`;\n\t\t\t\treturn [\n\t\t\t\t\t`DROP TRIGGER IF EXISTS \\`${name}\\`;`,\n\t\t\t\t\t`CREATE TRIGGER \\`${name}\\` AFTER ${op.toUpperCase()} ON \\`${table}\\` FOR EACH ROW`,\n\t\t\t\t\t`INSERT INTO \\`${changelog}\\` (tbl, op, payload)`,\n\t\t\t\t\t`VALUES ('${table}', '${op}', ${jsonObject(columns, ref)});`\n\t\t\t\t].join('\\n');\n\t\t\t})\n\t);\n\n\treturn [createTable, ...triggers].join('\\n\\n');\n};\n\nconst BINLOG_OP: Record<string, RowOp> = {\n\twriterows: 'insert',\n\tupdaterows: 'update',\n\tdeleterows: 'delete'\n};\n\n/** A row-level binlog event (the subset {@link normalizeBinlogEvent} needs). */\nexport type BinlogRowEvent = {\n\t/**\n\t * Event kind — zongji's `writerows` / `updaterows` / `deleterows`\n\t * (case-insensitive).\n\t */\n\ttype: string;\n\t/** The affected table. */\n\ttable: string;\n\t/**\n\t * Affected rows. Insert/delete: each entry is the row object. Update: each\n\t * entry is `{ before, after }` (zongji's shape).\n\t */\n\trows: unknown[];\n};\n\n/**\n * Normalize a binlog row event into engine changes — one per affected row. For\n * updates it takes the `after` image; for deletes the row (or its `before`\n * image). Rows that aren't objects are skipped. Pure, so it's easy to test and\n * to swap for a different reader's shape.\n */\nexport const normalizeBinlogEvent = (event: BinlogRowEvent): ParsedChange[] => {\n\tconst op = BINLOG_OP[event.type.toLowerCase()];\n\tif (op === undefined || typeof event.table !== 'string') {\n\t\treturn [];\n\t}\n\tconst changes: ParsedChange[] = [];\n\tfor (const entry of event.rows) {\n\t\tlet row: unknown = entry;\n\t\tif (entry !== null && typeof entry === 'object') {\n\t\t\tif (op === 'update' && 'after' in entry) {\n\t\t\t\trow = (entry as { after: unknown }).after;\n\t\t\t} else if (op === 'delete' && 'before' in entry) {\n\t\t\t\trow = (entry as { before: unknown }).before;\n\t\t\t}\n\t\t}\n\t\tif (typeof row === 'object' && row !== null) {\n\t\t\tchanges.push({ table: event.table, change: { op, row } });\n\t\t}\n\t}\n\treturn changes;\n};\n\nexport type MysqlBinlogChangeSourceOptions = {\n\t/**\n\t * Subscribe to row events from a binlog reader; return a function that stops\n\t * it. e.g. with zongji:\n\t * `(onEvent) => { zongji.on('binlog', e => onEvent({ type: e.getEventName(), table: e.tableMap[e.tableId].tableName, rows: e.rows })); zongji.start(...); return () => zongji.stop(); }`.\n\t */\n\tsubscribe: (\n\t\tonEvent: (event: BinlogRowEvent) => void\n\t) => Promise<() => void | Promise<void>> | (() => void | Promise<void>);\n\t/** Override the event normalizer (defaults to {@link normalizeBinlogEvent}). */\n\tnormalize?: (event: BinlogRowEvent) => ParsedChange[];\n};\n\n/**\n * A {@link ChangeSource} backed by the MySQL binlog. Each row event is\n * normalized and emitted into the engine. Connect with\n * `engine.connectSource(...)`.\n */\nexport const mysqlBinlogChangeSource = (\n\toptions: MysqlBinlogChangeSourceOptions\n): ChangeSource => {\n\tconst normalize = options.normalize ?? normalizeBinlogEvent;\n\tlet unsubscribe: (() => void | Promise<void>) | undefined;\n\n\treturn {\n\t\tstart: async (emit) => {\n\t\t\tunsubscribe = await options.subscribe((event) => {\n\t\t\t\tfor (const parsed of normalize(event)) {\n\t\t\t\t\tvoid emit(parsed.table, parsed.change);\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\tstop: async () => {\n\t\t\tawait unsubscribe?.();\n\t\t\tunsubscribe = undefined;\n\t\t}\n\t};\n};\n"
7
7
  ],
8
- "mappings": "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",
9
- "debugId": "48EE1E12A50EB47064756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "5FBCD902F44C556164756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -1,4 +1,6 @@
1
1
  // @bun
2
+ var __require = import.meta.require;
3
+
2
4
  // src/adapters/postgres/index.ts
3
5
  var DEFAULT_CHANNEL = "absolute_sync";
4
6
  var DEFAULT_FUNCTION = "absolute_sync_notify";
@@ -82,5 +84,5 @@ export {
82
84
  parseNotification
83
85
  };
84
86
 
85
- //# debugId=0625BCD90123273B64756E2164756E21
87
+ //# debugId=7D22AF8D04FDCF6D64756E2164756E21
86
88
  //# sourceMappingURL=index.js.map
@@ -4,7 +4,7 @@
4
4
  "sourcesContent": [
5
5
  "import type { ChangeSource, ParsedChange, RowOp } from '../../engine/types';\n\n/**\n * Postgres CDC adapter for @absolutejs/sync (Tier 3, M5).\n *\n * Catches writes that didn't go through the mutation API by turning Postgres\n * `LISTEN/NOTIFY` into the engine's change feed. Install the triggers once with\n * {@link postgresNotifyTrigger}, then connect {@link postgresChangeSource} via\n * `engine.connectSource(...)`.\n *\n * Client-agnostic: you supply how to `listen` on a channel, so it works with\n * porsager/postgres (`sql.listen`), node-postgres, or `Bun.sql` — and the\n * adapter itself has no database dependency.\n */\n\nconst DEFAULT_CHANNEL = 'absolute_sync';\nconst DEFAULT_FUNCTION = 'absolute_sync_notify';\n\nconst OP_BY_TG: Record<string, RowOp> = {\n\tINSERT: 'insert',\n\tUPDATE: 'update',\n\tDELETE: 'delete'\n};\n\n/** A parsed change ready to feed the engine. */\nexport type ParsedNotification = ParsedChange;\n\n/**\n * Default NOTIFY-payload parser: expects the JSON the trigger from\n * {@link postgresNotifyTrigger} sends — `{ table, op, row }` where `op` is\n * `INSERT`/`UPDATE`/`DELETE`. Returns `undefined` for anything malformed so a\n * bad payload is skipped rather than throwing.\n */\nexport const parseNotification = (\n\tpayload: string\n): ParsedNotification | undefined => {\n\tlet data: unknown;\n\ttry {\n\t\tdata = JSON.parse(payload);\n\t} catch {\n\t\treturn undefined;\n\t}\n\tif (typeof data !== 'object' || data === null) {\n\t\treturn undefined;\n\t}\n\tconst { table, op, row } = data as {\n\t\ttable?: unknown;\n\t\top?: unknown;\n\t\trow?: unknown;\n\t};\n\tif (typeof table !== 'string') {\n\t\treturn undefined;\n\t}\n\tconst rowOp = typeof op === 'string' ? OP_BY_TG[op] : undefined;\n\tif (rowOp === undefined) {\n\t\treturn undefined;\n\t}\n\tif (typeof row !== 'object' || row === null) {\n\t\treturn undefined;\n\t}\n\treturn { table, change: { op: rowOp, row } };\n};\n\nexport type PostgresChangeSourceOptions = {\n\t/**\n\t * Subscribe to a Postgres NOTIFY channel; return a function that stops\n\t * listening. The wiring is yours, e.g. with porsager/postgres:\n\t * `(channel, onNotify) => { const s = await sql.listen(channel, onNotify); return s.unlisten; }`.\n\t */\n\tlisten: (\n\t\tchannel: string,\n\t\tonNotify: (payload: string) => void\n\t) => Promise<() => void | Promise<void>> | (() => void | Promise<void>);\n\t/** NOTIFY channel; must match the trigger's. Defaults to `absolute_sync`. */\n\tchannel?: string;\n\t/** Override the payload parser (defaults to {@link parseNotification}). */\n\tparse?: (payload: string) => ParsedNotification | undefined;\n};\n\n/**\n * A {@link ChangeSource} backed by Postgres `LISTEN/NOTIFY`. Each notification\n * is parsed to `(table, change)` and emitted into the engine.\n *\n * @example\n * const disconnect = await engine.connectSource(\n * postgresChangeSource({\n * listen: async (channel, onNotify) =>\n * (await sql.listen(channel, onNotify)).unlisten\n * })\n * );\n */\nexport const postgresChangeSource = (\n\toptions: PostgresChangeSourceOptions\n): ChangeSource => {\n\tconst channel = options.channel ?? DEFAULT_CHANNEL;\n\tconst parse = options.parse ?? parseNotification;\n\tlet unlisten: (() => void | Promise<void>) | undefined;\n\n\treturn {\n\t\tstart: async (emit) => {\n\t\t\tunlisten = await options.listen(channel, (payload) => {\n\t\t\t\tconst parsed = parse(payload);\n\t\t\t\tif (parsed !== undefined) {\n\t\t\t\t\tvoid emit(parsed.table, parsed.change);\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\tstop: async () => {\n\t\t\tawait unlisten?.();\n\t\t\tunlisten = undefined;\n\t\t}\n\t};\n};\n\nexport type PostgresNotifyTriggerOptions = {\n\t/** Tables to emit changes for. */\n\ttables: string[];\n\t/** NOTIFY channel; must match the change source's. Defaults to `absolute_sync`. */\n\tchannel?: string;\n\t/** Trigger function name. Defaults to `absolute_sync_notify`. */\n\tfunctionName?: string;\n};\n\n/**\n * Generate the SQL that installs a NOTIFY trigger on each table — run it once\n * (e.g. in a migration). On every insert/update/delete it sends\n * `{ table, op, row }` JSON on the channel for {@link postgresChangeSource}.\n *\n * Note: `pg_notify` payloads are capped at 8000 bytes, so very wide rows can be\n * truncated (the parser then skips them). For large rows or high throughput,\n * prefer a logical-replication source behind the same {@link ChangeSource} seam.\n */\nexport const postgresNotifyTrigger = (\n\toptions: PostgresNotifyTriggerOptions\n): string => {\n\tconst channel = options.channel ?? DEFAULT_CHANNEL;\n\tconst fn = options.functionName ?? DEFAULT_FUNCTION;\n\n\tconst functionSql = [\n\t\t`CREATE OR REPLACE FUNCTION ${fn}() RETURNS trigger AS $$`,\n\t\t'BEGIN',\n\t\t` PERFORM pg_notify('${channel}', json_build_object(`,\n\t\t` 'table', TG_TABLE_NAME,`,\n\t\t` 'op', TG_OP,`,\n\t\t` 'row', row_to_json(COALESCE(NEW, OLD))`,\n\t\t' )::text);',\n\t\t' RETURN COALESCE(NEW, OLD);',\n\t\t'END;',\n\t\t'$$ LANGUAGE plpgsql;'\n\t].join('\\n');\n\n\tconst triggerSql = options.tables.map((table) =>\n\t\t[\n\t\t\t`DROP TRIGGER IF EXISTS ${fn}_${table} ON ${table};`,\n\t\t\t`CREATE TRIGGER ${fn}_${table}`,\n\t\t\t`AFTER INSERT OR UPDATE OR DELETE ON ${table}`,\n\t\t\t`FOR EACH ROW EXECUTE FUNCTION ${fn}();`\n\t\t].join('\\n')\n\t);\n\n\treturn [functionSql, ...triggerSql].join('\\n\\n');\n};\n"
6
6
  ],
7
- "mappings": ";;AAeA,IAAM,kBAAkB;AACxB,IAAM,mBAAmB;AAEzB,IAAM,WAAkC;AAAA,EACvC,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AACT;AAWO,IAAM,oBAAoB,CAChC,YACoC;AAAA,EACpC,IAAI;AAAA,EACJ,IAAI;AAAA,IACH,OAAO,KAAK,MAAM,OAAO;AAAA,IACxB,MAAM;AAAA,IACP;AAAA;AAAA,EAED,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAAA,IAC9C;AAAA,EACD;AAAA,EACA,QAAQ,OAAO,IAAI,QAAQ;AAAA,EAK3B,IAAI,OAAO,UAAU,UAAU;AAAA,IAC9B;AAAA,EACD;AAAA,EACA,MAAM,QAAQ,OAAO,OAAO,WAAW,SAAS,MAAM;AAAA,EACtD,IAAI,UAAU,WAAW;AAAA,IACxB;AAAA,EACD;AAAA,EACA,IAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAAA,IAC5C;AAAA,EACD;AAAA,EACA,OAAO,EAAE,OAAO,QAAQ,EAAE,IAAI,OAAO,IAAI,EAAE;AAAA;AA+BrC,IAAM,uBAAuB,CACnC,YACkB;AAAA,EAClB,MAAM,UAAU,QAAQ,WAAW;AAAA,EACnC,MAAM,QAAQ,QAAQ,SAAS;AAAA,EAC/B,IAAI;AAAA,EAEJ,OAAO;AAAA,IACN,OAAO,OAAO,SAAS;AAAA,MACtB,WAAW,MAAM,QAAQ,OAAO,SAAS,CAAC,YAAY;AAAA,QACrD,MAAM,SAAS,MAAM,OAAO;AAAA,QAC5B,IAAI,WAAW,WAAW;AAAA,UACpB,KAAK,OAAO,OAAO,OAAO,MAAM;AAAA,QACtC;AAAA,OACA;AAAA;AAAA,IAEF,MAAM,YAAY;AAAA,MACjB,MAAM,WAAW;AAAA,MACjB,WAAW;AAAA;AAAA,EAEb;AAAA;AAqBM,IAAM,wBAAwB,CACpC,YACY;AAAA,EACZ,MAAM,UAAU,QAAQ,WAAW;AAAA,EACnC,MAAM,KAAK,QAAQ,gBAAgB;AAAA,EAEnC,MAAM,cAAc;AAAA,IACnB,8BAA8B;AAAA,IAC9B;AAAA,IACA,wBAAwB;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,EAAE,KAAK;AAAA,CAAI;AAAA,EAEX,MAAM,aAAa,QAAQ,OAAO,IAAI,CAAC,UACtC;AAAA,IACC,0BAA0B,MAAM,YAAY;AAAA,IAC5C,kBAAkB,MAAM;AAAA,IACxB,uCAAuC;AAAA,IACvC,iCAAiC;AAAA,EAClC,EAAE,KAAK;AAAA,CAAI,CACZ;AAAA,EAEA,OAAO,CAAC,aAAa,GAAG,UAAU,EAAE,KAAK;AAAA;AAAA,CAAM;AAAA;",
8
- "debugId": "0625BCD90123273B64756E2164756E21",
7
+ "mappings": ";;;;AAeA,IAAM,kBAAkB;AACxB,IAAM,mBAAmB;AAEzB,IAAM,WAAkC;AAAA,EACvC,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AACT;AAWO,IAAM,oBAAoB,CAChC,YACoC;AAAA,EACpC,IAAI;AAAA,EACJ,IAAI;AAAA,IACH,OAAO,KAAK,MAAM,OAAO;AAAA,IACxB,MAAM;AAAA,IACP;AAAA;AAAA,EAED,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAAA,IAC9C;AAAA,EACD;AAAA,EACA,QAAQ,OAAO,IAAI,QAAQ;AAAA,EAK3B,IAAI,OAAO,UAAU,UAAU;AAAA,IAC9B;AAAA,EACD;AAAA,EACA,MAAM,QAAQ,OAAO,OAAO,WAAW,SAAS,MAAM;AAAA,EACtD,IAAI,UAAU,WAAW;AAAA,IACxB;AAAA,EACD;AAAA,EACA,IAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAAA,IAC5C;AAAA,EACD;AAAA,EACA,OAAO,EAAE,OAAO,QAAQ,EAAE,IAAI,OAAO,IAAI,EAAE;AAAA;AA+BrC,IAAM,uBAAuB,CACnC,YACkB;AAAA,EAClB,MAAM,UAAU,QAAQ,WAAW;AAAA,EACnC,MAAM,QAAQ,QAAQ,SAAS;AAAA,EAC/B,IAAI;AAAA,EAEJ,OAAO;AAAA,IACN,OAAO,OAAO,SAAS;AAAA,MACtB,WAAW,MAAM,QAAQ,OAAO,SAAS,CAAC,YAAY;AAAA,QACrD,MAAM,SAAS,MAAM,OAAO;AAAA,QAC5B,IAAI,WAAW,WAAW;AAAA,UACpB,KAAK,OAAO,OAAO,OAAO,MAAM;AAAA,QACtC;AAAA,OACA;AAAA;AAAA,IAEF,MAAM,YAAY;AAAA,MACjB,MAAM,WAAW;AAAA,MACjB,WAAW;AAAA;AAAA,EAEb;AAAA;AAqBM,IAAM,wBAAwB,CACpC,YACY;AAAA,EACZ,MAAM,UAAU,QAAQ,WAAW;AAAA,EACnC,MAAM,KAAK,QAAQ,gBAAgB;AAAA,EAEnC,MAAM,cAAc;AAAA,IACnB,8BAA8B;AAAA,IAC9B;AAAA,IACA,wBAAwB;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,EAAE,KAAK;AAAA,CAAI;AAAA,EAEX,MAAM,aAAa,QAAQ,OAAO,IAAI,CAAC,UACtC;AAAA,IACC,0BAA0B,MAAM,YAAY;AAAA,IAC5C,kBAAkB,MAAM;AAAA,IACxB,uCAAuC;AAAA,IACvC,iCAAiC;AAAA,EAClC,EAAE,KAAK;AAAA,CAAI,CACZ;AAAA,EAEA,OAAO,CAAC,aAAa,GAAG,UAAU,EAAE,KAAK;AAAA;AAAA,CAAM;AAAA;",
8
+ "debugId": "7D22AF8D04FDCF6D64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,4 +1,6 @@
1
1
  // @bun
2
+ var __require = import.meta.require;
3
+
2
4
  // src/adapters/prisma/topics.ts
3
5
  var tableTopic = (model) => model;
4
6
  var keyTopic = (model, key) => `${model}:${key}`;
@@ -227,5 +229,5 @@ export {
227
229
  UnsupportedFilterError
228
230
  };
229
231
 
230
- //# debugId=96C8D5DF158A4DF864756E2164756E21
232
+ //# debugId=AFF3207442A931ED64756E2164756E21
231
233
  //# sourceMappingURL=index.js.map
@@ -8,7 +8,7 @@
8
8
  "import type { PrismaWhere } from './topics';\n\n/**\n * Thrown when a Prisma `where` uses an operator the incremental matcher can't\n * evaluate in JS. The sync engine catches it and degrades that subscription to\n * a refetch, so it never produces a wrong result — only a less efficient one.\n */\nexport class UnsupportedFilterError extends Error {\n\tconstructor(operator: string) {\n\t\tsuper(\n\t\t\t`Cannot evaluate Prisma filter operator \"${operator}\" incrementally`\n\t\t);\n\t\tthis.name = 'UnsupportedFilterError';\n\t}\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n\ttypeof value === 'object' &&\n\tvalue !== null &&\n\t!Array.isArray(value) &&\n\t!(value instanceof Date);\n\n/** Prisma equality semantics (a `null` operand means IS NULL). */\nconst equals = (value: unknown, operand: unknown): boolean => {\n\tif (operand === null) {\n\t\treturn value === null || value === undefined;\n\t}\n\tif (value instanceof Date && operand instanceof Date) {\n\t\treturn value.getTime() === operand.getTime();\n\t}\n\treturn value === operand;\n};\n\nconst order = (value: unknown): number | string =>\n\tvalue instanceof Date ? value.getTime() : (value as number | string);\n\nconst compare = (value: unknown, operand: unknown): number => {\n\tconst a = order(value);\n\tconst b = order(operand);\n\tif (a < b) {\n\t\treturn -1;\n\t}\n\tif (a > b) {\n\t\treturn 1;\n\t}\n\treturn 0;\n};\n\nconst comparable = (value: unknown): boolean =>\n\tvalue !== null && value !== undefined;\n\nconst FIELD_OPERATORS = new Set([\n\t'equals',\n\t'not',\n\t'in',\n\t'notIn',\n\t'lt',\n\t'lte',\n\t'gt',\n\t'gte',\n\t'contains',\n\t'startsWith',\n\t'endsWith'\n]);\n\n/** Evaluate a single field's condition (scalar equality or an operator object). */\nconst matchesField = (value: unknown, condition: unknown): boolean => {\n\tif (!isPlainObject(condition)) {\n\t\treturn equals(value, condition);\n\t}\n\t// Validate support up front: an unsupported operator must force a refetch\n\t// even when an earlier operator would short-circuit to false.\n\tfor (const operator of Object.keys(condition)) {\n\t\tif (!FIELD_OPERATORS.has(operator)) {\n\t\t\tthrow new UnsupportedFilterError(operator);\n\t\t}\n\t}\n\tfor (const [operator, operand] of Object.entries(condition)) {\n\t\tswitch (operator) {\n\t\t\tcase 'equals':\n\t\t\t\tif (!equals(value, operand)) return false;\n\t\t\t\tbreak;\n\t\t\tcase 'not':\n\t\t\t\tif (isPlainObject(operand)) {\n\t\t\t\t\tif (matchesField(value, operand)) return false;\n\t\t\t\t} else if (equals(value, operand)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'in':\n\t\t\t\tif (\n\t\t\t\t\t!Array.isArray(operand) ||\n\t\t\t\t\t!operand.some((item) => equals(value, item))\n\t\t\t\t)\n\t\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t\tcase 'notIn':\n\t\t\t\tif (\n\t\t\t\t\tArray.isArray(operand) &&\n\t\t\t\t\toperand.some((item) => equals(value, item))\n\t\t\t\t)\n\t\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t\tcase 'lt':\n\t\t\t\tif (!comparable(value) || compare(value, operand) >= 0)\n\t\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t\tcase 'lte':\n\t\t\t\tif (!comparable(value) || compare(value, operand) > 0)\n\t\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t\tcase 'gt':\n\t\t\t\tif (!comparable(value) || compare(value, operand) <= 0)\n\t\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t\tcase 'gte':\n\t\t\t\tif (!comparable(value) || compare(value, operand) < 0)\n\t\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t\tcase 'contains':\n\t\t\t\tif (\n\t\t\t\t\ttypeof value !== 'string' ||\n\t\t\t\t\t!value.includes(String(operand))\n\t\t\t\t)\n\t\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t\tcase 'startsWith':\n\t\t\t\tif (\n\t\t\t\t\ttypeof value !== 'string' ||\n\t\t\t\t\t!value.startsWith(String(operand))\n\t\t\t\t)\n\t\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t\tcase 'endsWith':\n\t\t\t\tif (\n\t\t\t\t\ttypeof value !== 'string' ||\n\t\t\t\t\t!value.endsWith(String(operand))\n\t\t\t\t)\n\t\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// `mode`, relation filters, etc. — bail so the engine refetches.\n\t\t\t\tthrow new UnsupportedFilterError(operator);\n\t\t}\n\t}\n\treturn true;\n};\n\nconst toConditions = (value: unknown): PrismaWhere[] => {\n\tif (Array.isArray(value)) {\n\t\treturn value.filter(isPlainObject);\n\t}\n\treturn isPlainObject(value) ? [value] : [];\n};\n\n/**\n * Evaluate a Prisma `where` object against an in-memory row — the JS mirror of\n * the SQL filter, used for incremental matching. Supports field equality and the\n * `equals/not/in/notIn/lt/lte/gt/gte/contains/startsWith/endsWith` operators\n * plus `AND`/`OR`/`NOT`. Anything else throws {@link UnsupportedFilterError}, so\n * the engine falls back to a refetch.\n *\n * @example\n * matchesWhere({ userId: 5, status: { not: 'archived' } }, row)\n */\nexport const matchesWhere = (\n\twhere: PrismaWhere,\n\trow: Record<string, unknown>\n): boolean => {\n\tfor (const [field, condition] of Object.entries(where)) {\n\t\tif (field === 'AND') {\n\t\t\tif (\n\t\t\t\t!toConditions(condition).every((part) =>\n\t\t\t\t\tmatchesWhere(part, row)\n\t\t\t\t)\n\t\t\t)\n\t\t\t\treturn false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (field === 'OR') {\n\t\t\tconst parts = toConditions(condition);\n\t\t\tif (\n\t\t\t\tparts.length > 0 &&\n\t\t\t\t!parts.some((part) => matchesWhere(part, row))\n\t\t\t)\n\t\t\t\treturn false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (field === 'NOT') {\n\t\t\tif (toConditions(condition).some((part) => matchesWhere(part, row)))\n\t\t\t\treturn false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (!matchesField(row[field], condition)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n};\n",
9
9
  "import type {\n\tCollectionContext,\n\tCollectionDefinition\n} from '../../engine/collection';\nimport type { RowKey } from '../../engine/types';\nimport { matchesWhere } from './predicate';\nimport type { PrismaWhere } from './topics';\n\nexport type PrismaCollectionOptions<T, P, Ctx> = {\n\t/** Collection name (change-feed key and topic root). */\n\tname: string;\n\t/**\n\t * The query filter, written once. Used both to hydrate from the database\n\t * (passed to `find`) and, mirrored in JS, to match changed rows\n\t * incrementally. Receives the subscription's params and context.\n\t */\n\twhere: (params: P, ctx: Ctx) => PrismaWhere;\n\t/**\n\t * Run the database read for a given `where` — your Prisma call, e.g.\n\t * `(where) => prisma.order.findMany({ where })`.\n\t */\n\tfind: (\n\t\twhere: PrismaWhere,\n\t\tparams: P,\n\t\tctx: Ctx\n\t) => Promise<Iterable<T>> | Iterable<T>;\n\t/** Row identity. Defaults to `row.id`. */\n\tkey?: (row: T) => RowKey;\n\t/** Access control; return false (or throw) to deny. */\n\tauthorize?: (params: P, ctx: Ctx) => boolean | Promise<boolean>;\n};\n\n/**\n * Build a syncable {@link CollectionDefinition} for Prisma from a single filter:\n * `where` is written once and powers both `hydrate` (via your `find`) and the\n * incremental `match` (via {@link matchesWhere}) — no restating the WHERE.\n *\n * If the filter uses an operator the JS matcher can't evaluate, that change\n * degrades to a refetch (handled by the engine), so the result stays correct.\n *\n * @example\n * prismaCollection({\n * name: 'orders',\n * where: (p) => ({ userId: p.userId, status: 'open' }),\n * find: (where) => prisma.order.findMany({ where }),\n * authorize: (p, ctx) => p.userId === ctx.userId\n * });\n */\nexport const prismaCollection = <T, P = void, Ctx = CollectionContext>(\n\toptions: PrismaCollectionOptions<T, P, Ctx>\n): CollectionDefinition<T, P, Ctx> => ({\n\tname: options.name,\n\thydrate: (params, ctx) =>\n\t\toptions.find(options.where(params, ctx), params, ctx),\n\tmatch: (row, params, ctx) =>\n\t\tmatchesWhere(\n\t\t\toptions.where(params, ctx),\n\t\t\trow as Record<string, unknown>\n\t\t),\n\tkey: options.key,\n\tauthorize: options.authorize\n});\n"
10
10
  ],
11
- "mappings": "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",
12
- "debugId": "96C8D5DF158A4DF864756E2164756E21",
11
+ "mappings": "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",
12
+ "debugId": "AFF3207442A931ED64756E2164756E21",
13
13
  "names": []
14
14
  }
@@ -1,4 +1,6 @@
1
1
  // @bun
2
+ var __require = import.meta.require;
3
+
2
4
  // src/engine/pollingSource.ts
3
5
  var OP_BY_NAME = {
4
6
  insert: "insert",
@@ -124,5 +126,5 @@ export {
124
126
  createPollingChangeSource
125
127
  };
126
128
 
127
- //# debugId=3D209B4D7BF1282864756E2164756E21
129
+ //# debugId=55545DA3CDEDC0F664756E2164756E21
128
130
  //# sourceMappingURL=index.js.map
@@ -5,7 +5,7 @@
5
5
  "import type { ChangeSource, EmitChange, ParsedChange, RowOp } from './types';\n\n/**\n * A database-agnostic CDC {@link ChangeSource} that tails an append-only\n * changelog (outbox) table and emits its rows into the engine.\n *\n * This is the portable way to catch out-of-band writes on databases without a\n * native push channel — MySQL (no `LISTEN/NOTIFY`) and SQLite (no update hook\n * reachable from the JS runtime). Install per-table triggers that append to the\n * changelog (see `@absolutejs/sync/mysql` and `/sqlite`), then poll it here. It\n * is also a fine fallback for Postgres when you'd rather not run `LISTEN`.\n *\n * Driver-agnostic: you supply `poll(sinceSeq)` — a single\n * `SELECT seq, tbl, op, payload FROM <changelog> WHERE seq > ? ORDER BY seq` run\n * with your client — and the adapter tracks the cursor, parses each row, emits,\n * and advances. Delivery is at-least-once across crashes (a row may re-emit if\n * the process dies mid-batch); the engine's per-key last-write-wins makes that\n * safe. Use `onProcessed` to prune the changelog once a watermark is durable.\n */\n\nconst OP_BY_NAME: Record<string, RowOp> = {\n\tinsert: 'insert',\n\tINSERT: 'insert',\n\tupdate: 'update',\n\tUPDATE: 'update',\n\tdelete: 'delete',\n\tDELETE: 'delete'\n};\n\n/** One changelog row, as returned by your `poll` query. */\nexport type OutboxRow = {\n\t/** Monotonic sequence (the cursor advances to the max seen). */\n\tseq: number;\n\t/** Source table the change happened on. */\n\ttbl: string;\n\t/** `insert` | `update` | `delete` (upper- or lower-case). */\n\top: string;\n\t/** The row's captured values — a JSON string or an already-parsed object. */\n\tpayload: unknown;\n};\n\n/**\n * Default changelog-row parser: normalizes `op`, JSON-parses a string `payload`,\n * and returns `{ table, change }`. Returns `undefined` for a malformed row so it\n * is skipped (and its `seq` still advances the cursor) rather than wedging the\n * feed.\n */\nexport const parseOutboxRow = (row: OutboxRow): ParsedChange | undefined => {\n\tif (typeof row.tbl !== 'string') {\n\t\treturn undefined;\n\t}\n\tconst op = OP_BY_NAME[row.op];\n\tif (op === undefined) {\n\t\treturn undefined;\n\t}\n\tlet payload: unknown = row.payload;\n\tif (typeof payload === 'string') {\n\t\ttry {\n\t\t\tpayload = JSON.parse(payload);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\tif (typeof payload !== 'object' || payload === null) {\n\t\treturn undefined;\n\t}\n\treturn { table: row.tbl, change: { op, row: payload } };\n};\n\nexport type PollingChangeSourceOptions = {\n\t/**\n\t * Fetch changelog rows with `seq > sinceSeq`, ordered by `seq` ascending.\n\t * e.g. `(since) => sql\\`SELECT seq, tbl, op, payload FROM absolute_sync_changelog WHERE seq > ${since} ORDER BY seq\\``.\n\t */\n\tpoll: (sinceSeq: number) => Promise<OutboxRow[]> | OutboxRow[];\n\t/** Poll interval in ms. Defaults to 1000. */\n\tintervalMs?: number;\n\t/** Resume cursor (highest `seq` already processed). Defaults to 0. */\n\tstartSeq?: number;\n\t/** Override the row parser (defaults to {@link parseOutboxRow}). */\n\tparse?: (row: OutboxRow) => ParsedChange | undefined;\n\t/** Called after a non-empty batch with the new watermark — prune here. */\n\tonProcessed?: (uptoSeq: number) => void | Promise<void>;\n\t/** Called if a poll throws (the loop keeps running). Defaults to a warning. */\n\tonError?: (error: unknown) => void;\n};\n\n/**\n * Create a polling {@link ChangeSource} over a changelog table. Connect it with\n * `engine.connectSource(...)`; `start` runs an immediate first poll (draining any\n * backlog) and then polls every `intervalMs` until `stop`.\n */\nexport const createPollingChangeSource = (\n\toptions: PollingChangeSourceOptions\n): ChangeSource => {\n\tconst intervalMs = options.intervalMs ?? 1000;\n\tconst parse = options.parse ?? parseOutboxRow;\n\tconst onError =\n\t\toptions.onError ??\n\t\t((error: unknown) => {\n\t\t\tconsole.warn('[sync] polling change source error:', error);\n\t\t});\n\tlet cursor = options.startSeq ?? 0;\n\tlet running = false;\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\n\tconst tick = async (emit: EmitChange): Promise<void> => {\n\t\tif (!running) {\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tconst rows = await options.poll(cursor);\n\t\t\tfor (const row of rows) {\n\t\t\t\tconst parsed = parse(row);\n\t\t\t\tif (parsed !== undefined) {\n\t\t\t\t\tawait emit(parsed.table, parsed.change);\n\t\t\t\t}\n\t\t\t\tif (typeof row.seq === 'number' && row.seq > cursor) {\n\t\t\t\t\tcursor = row.seq;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (rows.length > 0) {\n\t\t\t\tawait options.onProcessed?.(cursor);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tonError(error);\n\t\t}\n\t\tif (running) {\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\tvoid tick(emit);\n\t\t\t}, intervalMs);\n\t\t}\n\t};\n\n\treturn {\n\t\tstart: async (emit) => {\n\t\t\tif (running) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\trunning = true;\n\t\t\tawait tick(emit);\n\t\t},\n\t\tstop: () => {\n\t\t\trunning = false;\n\t\t\tif (timer !== undefined) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\ttimer = undefined;\n\t\t\t}\n\t\t}\n\t};\n};\n",
6
6
  "/**\n * SQLite CDC adapter for @absolutejs/sync (Tier 3, M5).\n *\n * SQLite has no `LISTEN/NOTIFY`, and its `update_hook` isn't reachable from the\n * JS runtimes we target, so out-of-band writes are caught with the portable\n * changelog (outbox) pattern: install triggers that append every row change to a\n * changelog table, then tail it with {@link createPollingChangeSource}. Polling a\n * local SQLite table is cheap (same process, no network).\n *\n * Dependency-free — it only generates SQL; bring your own client (`bun:sqlite`,\n * better-sqlite3, …) to run it and to back the poll query.\n */\n\nexport {\n\tcreatePollingChangeSource,\n\tparseOutboxRow\n} from '../../engine/pollingSource';\nexport type {\n\tOutboxRow,\n\tPollingChangeSourceOptions\n} from '../../engine/pollingSource';\n\nconst DEFAULT_CHANGELOG = 'absolute_sync_changelog';\nconst DEFAULT_PREFIX = 'absolute_sync';\nconst OPS = ['insert', 'update', 'delete'] as const;\n\nexport type SqliteChangelogOptions = {\n\t/** Table name → the column names to capture in the change payload. */\n\ttables: Record<string, string[]>;\n\t/** Changelog table name. Defaults to `absolute_sync_changelog`. */\n\tchangelogTable?: string;\n\t/** Trigger name prefix. Defaults to `absolute_sync`. */\n\tprefix?: string;\n};\n\n/**\n * Generate the SQL that installs the changelog table and per-table\n * insert/update/delete triggers — run it once (e.g. in a migration). Each\n * trigger appends `{ tbl, op, payload }` (payload built with `json_object` from\n * the listed columns) to the changelog for {@link createPollingChangeSource}.\n *\n * The statements are `;`-separated; run them as a script, or split on `;` if your\n * driver executes one statement per call.\n */\nexport const sqliteChangelogSchema = (\n\toptions: SqliteChangelogOptions\n): string => {\n\tconst changelog = options.changelogTable ?? DEFAULT_CHANGELOG;\n\tconst prefix = options.prefix ?? DEFAULT_PREFIX;\n\n\tconst createTable = [\n\t\t`CREATE TABLE IF NOT EXISTS ${changelog} (`,\n\t\t'\\tseq INTEGER PRIMARY KEY AUTOINCREMENT,',\n\t\t'\\ttbl TEXT NOT NULL,',\n\t\t'\\top TEXT NOT NULL,',\n\t\t'\\tpayload TEXT NOT NULL,',\n\t\t\"\\tcreated_at TEXT NOT NULL DEFAULT (datetime('now'))\",\n\t\t');'\n\t].join('\\n');\n\n\tconst jsonObject = (columns: string[], ref: 'NEW' | 'OLD'): string =>\n\t\t`json_object(${columns\n\t\t\t.map((column) => `'${column}', ${ref}.${column}`)\n\t\t\t.join(', ')})`;\n\n\tconst triggers = Object.entries(options.tables).flatMap(\n\t\t([table, columns]) =>\n\t\t\tOPS.map((op) => {\n\t\t\t\tconst ref = op === 'delete' ? 'OLD' : 'NEW';\n\t\t\t\tconst name = `${prefix}_${table}_${op}`;\n\t\t\t\treturn [\n\t\t\t\t\t`DROP TRIGGER IF EXISTS ${name};`,\n\t\t\t\t\t`CREATE TRIGGER ${name} AFTER ${op.toUpperCase()} ON ${table}`,\n\t\t\t\t\t'BEGIN',\n\t\t\t\t\t`\\tINSERT INTO ${changelog} (tbl, op, payload)`,\n\t\t\t\t\t`\\tVALUES ('${table}', '${op}', ${jsonObject(columns, ref)});`,\n\t\t\t\t\t'END;'\n\t\t\t\t].join('\\n');\n\t\t\t})\n\t);\n\n\treturn [createTable, ...triggers].join('\\n\\n');\n};\n"
7
7
  ],
8
- "mappings": "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",
9
- "debugId": "3D209B4D7BF1282864756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "55545DA3CDEDC0F664756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -42,6 +42,7 @@ export { defineSchedule } from './schedule';
42
42
  export type { ScheduleContext, ScheduleDefinition } from './schedule';
43
43
  export { defineMutation } from './mutation';
44
44
  export type { MutationActions, MutationDefinition, MutationHandler, TableWriter, TransactionRunner } from './mutation';
45
+ export type { SandboxConfig } from './sandbox';
45
46
  export { createSyncEngine, SchemaError, UnauthorizedError } from './syncEngine';
46
47
  export type { CrdtFields, SubscribeArgs, Subscription, SyncEngine } from './syncEngine';
47
48
  export type { CrdtMergeable } from '../crdt';
@@ -1,4 +1,6 @@
1
1
  // @bun
2
+ var __require = import.meta.require;
3
+
2
4
  // src/engine/materializedView.ts
3
5
  var emptyDiff = () => ({
4
6
  added: [],
@@ -1039,6 +1041,76 @@ var createVectorIndex = (options) => {
1039
1041
  var defineSchedule = (definition) => definition;
1040
1042
  // src/engine/mutation.ts
1041
1043
  var defineMutation = (definition) => definition;
1044
+ // src/engine/sandbox.ts
1045
+ var isolatedJscModule;
1046
+ var loadIsolatedJsc = async () => {
1047
+ if (isolatedJscModule !== undefined)
1048
+ return isolatedJscModule;
1049
+ try {
1050
+ isolatedJscModule = await import("@absolutejs/isolated-jsc");
1051
+ return isolatedJscModule;
1052
+ } catch (error) {
1053
+ throw new Error('sandboxedHandler requires the optional peer "@absolutejs/isolated-jsc". Install it with: bun add @absolutejs/isolated-jsc', { cause: error });
1054
+ }
1055
+ };
1056
+ var wrap = (source) => `
1057
+ (async () => {
1058
+ const userFn = (${source});
1059
+ if (typeof userFn !== 'function') {
1060
+ throw new Error(
1061
+ 'sandboxedHandler must evaluate to (args, ctx, actions) => result; got ' +
1062
+ typeof userFn
1063
+ );
1064
+ }
1065
+ const actions = {
1066
+ insert: __syncActionInsert,
1067
+ update: __syncActionUpdate,
1068
+ delete: __syncActionDelete,
1069
+ change: __syncActionChange
1070
+ };
1071
+ return await userFn(args, ctx, actions);
1072
+ })()
1073
+ `;
1074
+ var compile = async (source, config) => {
1075
+ const { createIsolate } = await loadIsolatedJsc();
1076
+ const isolate = await createIsolate({
1077
+ memoryLimit: config.memoryLimit ?? 32
1078
+ });
1079
+ const script = await isolate.compileScript(wrap(source));
1080
+ return { isolate, script, timeoutMs: config.timeout ?? 5000 };
1081
+ };
1082
+ var makeSandboxedHandler = (source, config = {}) => {
1083
+ let pending;
1084
+ const getCompiled = async () => {
1085
+ if (pending !== undefined) {
1086
+ const compiled = await pending;
1087
+ if (!compiled.isolate.isDisposed)
1088
+ return compiled;
1089
+ pending = undefined;
1090
+ }
1091
+ pending = compile(source, config);
1092
+ return pending;
1093
+ };
1094
+ return async (args, ctx, actions) => {
1095
+ const { Reference } = await loadIsolatedJsc();
1096
+ const compiled = await getCompiled();
1097
+ const context = await compiled.isolate.createContext();
1098
+ try {
1099
+ await context.setGlobal("args", args);
1100
+ await context.setGlobal("ctx", ctx);
1101
+ await context.setGlobal("__syncActionInsert", new Reference((table, data) => actions.insert(table, data)));
1102
+ await context.setGlobal("__syncActionUpdate", new Reference((table, data) => actions.update(table, data)));
1103
+ await context.setGlobal("__syncActionDelete", new Reference((table, row) => actions.delete(table, row)));
1104
+ await context.setGlobal("__syncActionChange", new Reference((collection, change) => actions.change(collection, change)));
1105
+ return await compiled.script.run(context, {
1106
+ timeout: compiled.timeoutMs
1107
+ });
1108
+ } finally {
1109
+ await context.dispose().catch(() => {});
1110
+ }
1111
+ };
1112
+ };
1113
+
1042
1114
  // src/engine/syncEngine.ts
1043
1115
  class UnauthorizedError extends Error {
1044
1116
  constructor(subject) {
@@ -1115,6 +1187,7 @@ var equalsIgnoringScore = (a, b) => {
1115
1187
  var createSyncEngine = (options = {}) => {
1116
1188
  const registry = new Map;
1117
1189
  const mutations = new Map;
1190
+ const sandboxRunners = new Map;
1118
1191
  const writers = new Map;
1119
1192
  const readers = new Map;
1120
1193
  const schedules = new Map;
@@ -1160,6 +1233,37 @@ var createSyncEngine = (options = {}) => {
1160
1233
  const changeLogSize = options.changeLogSize ?? 1024;
1161
1234
  const changeLog = [];
1162
1235
  let version = 0;
1236
+ const reactiveCacheMax = options.reactiveCache?.max ?? 256;
1237
+ const reactiveCacheTtlMs = options.reactiveCache?.ttlMs ?? 60000;
1238
+ const cachedReruns = new Map;
1239
+ const touchCacheEntry = (key, entry) => {
1240
+ cachedReruns.delete(key);
1241
+ cachedReruns.set(key, entry);
1242
+ };
1243
+ const readCacheEntry = (key) => {
1244
+ if (reactiveCacheMax <= 0)
1245
+ return;
1246
+ const entry = cachedReruns.get(key);
1247
+ if (entry === undefined)
1248
+ return;
1249
+ if (reactiveCacheTtlMs > 0 && entry.expiresAt < Date.now()) {
1250
+ cachedReruns.delete(key);
1251
+ return;
1252
+ }
1253
+ touchCacheEntry(key, entry);
1254
+ return entry;
1255
+ };
1256
+ const writeCacheEntry = (entry) => {
1257
+ if (reactiveCacheMax <= 0)
1258
+ return;
1259
+ cachedReruns.set(entry.rerunKey, entry);
1260
+ while (cachedReruns.size > reactiveCacheMax) {
1261
+ const oldest = cachedReruns.keys().next().value;
1262
+ if (oldest === undefined)
1263
+ break;
1264
+ cachedReruns.delete(oldest);
1265
+ }
1266
+ };
1163
1267
  const activityListeners = new Set;
1164
1268
  const emitActivity = (event) => {
1165
1269
  for (const listener of activityListeners) {
@@ -1443,8 +1547,19 @@ var createSyncEngine = (options = {}) => {
1443
1547
  return { added, removed, changed };
1444
1548
  };
1445
1549
  const inRange = (dep, change) => dep.table === change.table && (change.key !== undefined && dep.keys.has(change.key) || dep.predicate(change.row));
1446
- const isReactiveAffected = (sub, changes) => changes.some((change) => sub.readTables.has(change.table) || change.key !== undefined && sub.readKeys.has(depKey(change.table, change.key)) || sub.rangeDeps.some((dep) => inRange(dep, change)));
1550
+ const readSetOverlaps = (readTables, readKeys, rangeDeps, changes) => changes.some((change) => readTables.has(change.table) || change.key !== undefined && readKeys.has(depKey(change.table, change.key)) || rangeDeps.some((dep) => inRange(dep, change)));
1551
+ const isReactiveAffected = (sub, changes) => readSetOverlaps(sub.readTables, sub.readKeys, sub.rangeDeps, changes);
1552
+ const invalidateCacheForChanges = (changes) => {
1553
+ if (cachedReruns.size === 0)
1554
+ return;
1555
+ for (const [key, entry] of cachedReruns) {
1556
+ if (readSetOverlaps(entry.readTables, entry.readKeys, entry.rangeDeps, changes)) {
1557
+ cachedReruns.delete(key);
1558
+ }
1559
+ }
1560
+ };
1447
1561
  const reactivePairs = async (changes) => {
1562
+ invalidateCacheForChanges(changes);
1448
1563
  const pairs = [];
1449
1564
  const sharedRuns = new Map;
1450
1565
  for (const sub of reactiveSubs) {
@@ -1465,6 +1580,19 @@ var createSyncEngine = (options = {}) => {
1465
1580
  pairs.push([sub, diff]);
1466
1581
  }
1467
1582
  }
1583
+ for (const [key, runPromise] of sharedRuns) {
1584
+ runPromise.then(({ rows, readTables, readKeys, rangeDeps }) => {
1585
+ writeCacheEntry({
1586
+ expiresAt: Date.now() + reactiveCacheTtlMs,
1587
+ rangeDeps,
1588
+ readKeys,
1589
+ readTables,
1590
+ rerunKey: key,
1591
+ rows,
1592
+ version
1593
+ });
1594
+ }).catch(() => {});
1595
+ }
1468
1596
  return pairs;
1469
1597
  };
1470
1598
  const ensureSearchIndex = async (definition) => {
@@ -1698,7 +1826,25 @@ var createSyncEngine = (options = {}) => {
1698
1826
  const rows = [...await definition.run({ ctx, db, params })];
1699
1827
  return { rangeDeps, readKeys, readTables, rows };
1700
1828
  };
1701
- const first = await rerun();
1829
+ const rerunKey = stableSubKey(collection, params, ctx);
1830
+ const cached = readCacheEntry(rerunKey);
1831
+ const first = cached !== undefined ? {
1832
+ rangeDeps: cached.rangeDeps,
1833
+ readKeys: cached.readKeys,
1834
+ readTables: cached.readTables,
1835
+ rows: cached.rows
1836
+ } : await rerun();
1837
+ if (cached === undefined) {
1838
+ writeCacheEntry({
1839
+ expiresAt: Date.now() + reactiveCacheTtlMs,
1840
+ rangeDeps: first.rangeDeps,
1841
+ readKeys: first.readKeys,
1842
+ readTables: first.readTables,
1843
+ rerunKey,
1844
+ rows: first.rows,
1845
+ version
1846
+ });
1847
+ }
1702
1848
  const current = new Map;
1703
1849
  for (const row of first.rows) {
1704
1850
  current.set(definition.key(row), row);
@@ -1709,7 +1855,7 @@ var createSyncEngine = (options = {}) => {
1709
1855
  collection,
1710
1856
  key: definition.key,
1711
1857
  rerun,
1712
- rerunKey: stableSubKey(collection, params, ctx),
1858
+ rerunKey,
1713
1859
  current,
1714
1860
  readTables: first.readTables,
1715
1861
  readKeys: first.readKeys,
@@ -1918,7 +2064,16 @@ var createSyncEngine = (options = {}) => {
1918
2064
  return total;
1919
2065
  },
1920
2066
  registerMutation: (mutation) => {
2067
+ if (mutation.handler === undefined && mutation.sandboxedHandler === undefined) {
2068
+ throw new Error(`Mutation "${mutation.name}" must define either \`handler\` or \`sandboxedHandler\``);
2069
+ }
2070
+ if (mutation.handler !== undefined && mutation.sandboxedHandler !== undefined) {
2071
+ throw new Error(`Mutation "${mutation.name}" defines both \`handler\` and \`sandboxedHandler\` \u2014 pick one`);
2072
+ }
1921
2073
  mutations.set(mutation.name, mutation);
2074
+ if (mutation.sandboxedHandler !== undefined) {
2075
+ sandboxRunners.set(mutation.name, makeSandboxedHandler(mutation.sandboxedHandler, mutation.sandbox));
2076
+ }
1922
2077
  },
1923
2078
  registerWriter: (table, writer) => {
1924
2079
  writers.set(table, writer);
@@ -1958,9 +2113,11 @@ var createSyncEngine = (options = {}) => {
1958
2113
  throw new UnauthorizedError(`run mutation "${name}"`);
1959
2114
  }
1960
2115
  }
2116
+ const sandboxRunner = sandboxRunners.get(name);
2117
+ const invokeHandler = sandboxRunner !== undefined ? sandboxRunner : (a, c, actions) => Promise.resolve(mutation.handler(a, c, actions));
1961
2118
  const runHandler = async (tx) => {
1962
2119
  const { actions, buffered } = makeActions(tx, ctx, true);
1963
- const result = await mutation.handler(args, ctx, actions);
2120
+ const result = await invokeHandler(args, ctx, actions);
1964
2121
  return { buffered, result };
1965
2122
  };
1966
2123
  try {
@@ -2336,5 +2493,5 @@ export {
2336
2493
  SEARCH_SCORE_FIELD
2337
2494
  };
2338
2495
 
2339
- //# debugId=4154536B9F3F3F5A64756E2164756E21
2496
+ //# debugId=03508BC44A5CF91064756E2164756E21
2340
2497
  //# sourceMappingURL=index.js.map