@absolutejs/sync 1.3.0 → 1.5.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": ";;;;AAoBA,IAAM,aAAoC;AAAA,EACzC,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AACT;AAoBO,IAAM,iBAAiB,CAAC,QAA6C;AAAA,EAC3E,IAAI,OAAO,IAAI,QAAQ,UAAU;AAAA,IAChC;AAAA,EACD;AAAA,EACA,MAAM,KAAK,WAAW,IAAI;AAAA,EAC1B,IAAI,OAAO,WAAW;AAAA,IACrB;AAAA,EACD;AAAA,EACA,IAAI,UAAmB,IAAI;AAAA,EAC3B,IAAI,OAAO,YAAY,UAAU;AAAA,IAChC,IAAI;AAAA,MACH,UAAU,KAAK,MAAM,OAAO;AAAA,MAC3B,MAAM;AAAA,MACP;AAAA;AAAA,EAEF;AAAA,EACA,IAAI,OAAO,YAAY,YAAY,YAAY,MAAM;AAAA,IACpD;AAAA,EACD;AAAA,EACA,OAAO,EAAE,OAAO,IAAI,KAAK,QAAQ,EAAE,IAAI,KAAK,QAAQ,EAAE;AAAA;AA0BhD,IAAM,4BAA4B,CACxC,YACkB;AAAA,EAClB,MAAM,aAAa,QAAQ,cAAc;AAAA,EACzC,MAAM,QAAQ,QAAQ,SAAS;AAAA,EAC/B,MAAM,UACL,QAAQ,YACP,CAAC,UAAmB;AAAA,IACpB,QAAQ,KAAK,uCAAuC,KAAK;AAAA;AAAA,EAE3D,IAAI,SAAS,QAAQ,YAAY;AAAA,EACjC,IAAI,UAAU;AAAA,EACd,IAAI;AAAA,EAEJ,MAAM,OAAO,OAAO,SAAoC;AAAA,IACvD,IAAI,CAAC,SAAS;AAAA,MACb;AAAA,IACD;AAAA,IACA,IAAI;AAAA,MACH,MAAM,OAAO,MAAM,QAAQ,KAAK,MAAM;AAAA,MACtC,WAAW,OAAO,MAAM;AAAA,QACvB,MAAM,SAAS,MAAM,GAAG;AAAA,QACxB,IAAI,WAAW,WAAW;AAAA,UACzB,MAAM,KAAK,OAAO,OAAO,OAAO,MAAM;AAAA,QACvC;AAAA,QACA,IAAI,OAAO,IAAI,QAAQ,YAAY,IAAI,MAAM,QAAQ;AAAA,UACpD,SAAS,IAAI;AAAA,QACd;AAAA,MACD;AAAA,MACA,IAAI,KAAK,SAAS,GAAG;AAAA,QACpB,MAAM,QAAQ,cAAc,MAAM;AAAA,MACnC;AAAA,MACC,OAAO,OAAO;AAAA,MACf,QAAQ,KAAK;AAAA;AAAA,IAEd,IAAI,SAAS;AAAA,MACZ,QAAQ,WAAW,MAAM;AAAA,QACnB,KAAK,IAAI;AAAA,SACZ,UAAU;AAAA,IACd;AAAA;AAAA,EAGD,OAAO;AAAA,IACN,OAAO,OAAO,SAAS;AAAA,MACtB,IAAI,SAAS;AAAA,QACZ;AAAA,MACD;AAAA,MACA,UAAU;AAAA,MACV,MAAM,KAAK,IAAI;AAAA;AAAA,IAEhB,MAAM,MAAM;AAAA,MACX,UAAU;AAAA,MACV,IAAI,UAAU,WAAW;AAAA,QACxB,aAAa,KAAK;AAAA,QAClB,QAAQ;AAAA,MACT;AAAA;AAAA,EAEF;AAAA;;;AC1HD,IAAM,oBAAoB;AAC1B,IAAM,iBAAiB;AACvB,IAAM,MAAM,CAAC,UAAU,UAAU,QAAQ;AAqBlC,IAAM,uBAAuB,CACnC,YACY;AAAA,EACZ,MAAM,YAAY,QAAQ,kBAAkB;AAAA,EAC5C,MAAM,SAAS,QAAQ,UAAU;AAAA,EAEjC,MAAM,cAAc;AAAA,IACnB,gCAAgC;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,EAAE,KAAK;AAAA,CAAI;AAAA,EAEX,MAAM,aAAa,CAAC,SAAmB,QACtC,eAAe,QACb,IAAI,CAAC,WAAW,IAAI,YAAY,SAAS,UAAU,EACnD,KAAK,IAAI;AAAA,EAEZ,MAAM,WAAW,OAAO,QAAQ,QAAQ,MAAM,EAAE,QAC/C,EAAE,OAAO,aACR,IAAI,IAAI,CAAC,OAAO;AAAA,IACf,MAAM,MAAM,OAAO,WAAW,QAAQ;AAAA,IACtC,MAAM,OAAO,GAAG,UAAU,SAAS;AAAA,IACnC,OAAO;AAAA,MACN,4BAA4B;AAAA,MAC5B,oBAAoB,gBAAgB,GAAG,YAAY,UAAU;AAAA,MAC7D,iBAAiB;AAAA,MACjB,YAAY,YAAY,QAAQ,WAAW,SAAS,GAAG;AAAA,IACxD,EAAE,KAAK;AAAA,CAAI;AAAA,GACX,CACH;AAAA,EAEA,OAAO,CAAC,aAAa,GAAG,QAAQ,EAAE,KAAK;AAAA;AAAA,CAAM;AAAA;AAG9C,IAAM,YAAmC;AAAA,EACxC,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,YAAY;AACb;AAwBO,IAAM,uBAAuB,CAAC,UAA0C;AAAA,EAC9E,MAAM,KAAK,UAAU,MAAM,KAAK,YAAY;AAAA,EAC5C,IAAI,OAAO,aAAa,OAAO,MAAM,UAAU,UAAU;AAAA,IACxD,OAAO,CAAC;AAAA,EACT;AAAA,EACA,MAAM,UAA0B,CAAC;AAAA,EACjC,WAAW,SAAS,MAAM,MAAM;AAAA,IAC/B,IAAI,MAAe;AAAA,IACnB,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAAA,MAChD,IAAI,OAAO,YAAY,WAAW,OAAO;AAAA,QACxC,MAAO,MAA6B;AAAA,MACrC,EAAO,SAAI,OAAO,YAAY,YAAY,OAAO;AAAA,QAChD,MAAO,MAA8B;AAAA,MACtC;AAAA,IACD;AAAA,IACA,IAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAAA,MAC5C,QAAQ,KAAK,EAAE,OAAO,MAAM,OAAO,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC;AAAA,IACzD;AAAA,EACD;AAAA,EACA,OAAO;AAAA;AAqBD,IAAM,0BAA0B,CACtC,YACkB;AAAA,EAClB,MAAM,YAAY,QAAQ,aAAa;AAAA,EACvC,IAAI;AAAA,EAEJ,OAAO;AAAA,IACN,OAAO,OAAO,SAAS;AAAA,MACtB,cAAc,MAAM,QAAQ,UAAU,CAAC,UAAU;AAAA,QAChD,WAAW,UAAU,UAAU,KAAK,GAAG;AAAA,UACjC,KAAK,OAAO,OAAO,OAAO,MAAM;AAAA,QACtC;AAAA,OACA;AAAA;AAAA,IAEF,MAAM,YAAY;AAAA,MACjB,MAAM,cAAc;AAAA,MACpB,cAAc;AAAA;AAAA,EAEhB;AAAA;",
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": ";;;;AAoBA,IAAM,aAAoC;AAAA,EACzC,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AACT;AAoBO,IAAM,iBAAiB,CAAC,QAA6C;AAAA,EAC3E,IAAI,OAAO,IAAI,QAAQ,UAAU;AAAA,IAChC;AAAA,EACD;AAAA,EACA,MAAM,KAAK,WAAW,IAAI;AAAA,EAC1B,IAAI,OAAO,WAAW;AAAA,IACrB;AAAA,EACD;AAAA,EACA,IAAI,UAAmB,IAAI;AAAA,EAC3B,IAAI,OAAO,YAAY,UAAU;AAAA,IAChC,IAAI;AAAA,MACH,UAAU,KAAK,MAAM,OAAO;AAAA,MAC3B,MAAM;AAAA,MACP;AAAA;AAAA,EAEF;AAAA,EACA,IAAI,OAAO,YAAY,YAAY,YAAY,MAAM;AAAA,IACpD;AAAA,EACD;AAAA,EACA,OAAO,EAAE,OAAO,IAAI,KAAK,QAAQ,EAAE,IAAI,KAAK,QAAQ,EAAE;AAAA;AA0BhD,IAAM,4BAA4B,CACxC,YACkB;AAAA,EAClB,MAAM,aAAa,QAAQ,cAAc;AAAA,EACzC,MAAM,QAAQ,QAAQ,SAAS;AAAA,EAC/B,MAAM,UACL,QAAQ,YACP,CAAC,UAAmB;AAAA,IACpB,QAAQ,KAAK,uCAAuC,KAAK;AAAA;AAAA,EAE3D,IAAI,SAAS,QAAQ,YAAY;AAAA,EACjC,IAAI,UAAU;AAAA,EACd,IAAI;AAAA,EAEJ,MAAM,OAAO,OAAO,SAAoC;AAAA,IACvD,IAAI,CAAC,SAAS;AAAA,MACb;AAAA,IACD;AAAA,IACA,IAAI;AAAA,MACH,MAAM,OAAO,MAAM,QAAQ,KAAK,MAAM;AAAA,MACtC,WAAW,OAAO,MAAM;AAAA,QACvB,MAAM,SAAS,MAAM,GAAG;AAAA,QACxB,IAAI,WAAW,WAAW;AAAA,UACzB,MAAM,KAAK,OAAO,OAAO,OAAO,MAAM;AAAA,QACvC;AAAA,QACA,IAAI,OAAO,IAAI,QAAQ,YAAY,IAAI,MAAM,QAAQ;AAAA,UACpD,SAAS,IAAI;AAAA,QACd;AAAA,MACD;AAAA,MACA,IAAI,KAAK,SAAS,GAAG;AAAA,QACpB,MAAM,QAAQ,cAAc,MAAM;AAAA,MACnC;AAAA,MACC,OAAO,OAAO;AAAA,MACf,QAAQ,KAAK;AAAA;AAAA,IAEd,IAAI,SAAS;AAAA,MACZ,QAAQ,WAAW,MAAM;AAAA,QACnB,KAAK,IAAI;AAAA,SACZ,UAAU;AAAA,IACd;AAAA;AAAA,EAGD,OAAO;AAAA,IACN,OAAO,OAAO,SAAS;AAAA,MACtB,IAAI,SAAS;AAAA,QACZ;AAAA,MACD;AAAA,MACA,UAAU;AAAA,MACV,MAAM,KAAK,IAAI;AAAA;AAAA,IAEhB,MAAM,MAAM;AAAA,MACX,UAAU;AAAA,MACV,IAAI,UAAU,WAAW;AAAA,QACxB,aAAa,KAAK;AAAA,QAClB,QAAQ;AAAA,MACT;AAAA;AAAA,EAEF;AAAA;;;AC/HD,IAAM,oBAAoB;AAC1B,IAAM,iBAAiB;AACvB,IAAM,MAAM,CAAC,UAAU,UAAU,QAAQ;AAoBlC,IAAM,wBAAwB,CACpC,YACY;AAAA,EACZ,MAAM,YAAY,QAAQ,kBAAkB;AAAA,EAC5C,MAAM,SAAS,QAAQ,UAAU;AAAA,EAEjC,MAAM,cAAc;AAAA,IACnB,8BAA8B;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,EAAE,KAAK;AAAA,CAAI;AAAA,EAEX,MAAM,aAAa,CAAC,SAAmB,QACtC,eAAe,QACb,IAAI,CAAC,WAAW,IAAI,YAAY,OAAO,QAAQ,EAC/C,KAAK,IAAI;AAAA,EAEZ,MAAM,WAAW,OAAO,QAAQ,QAAQ,MAAM,EAAE,QAC/C,EAAE,OAAO,aACR,IAAI,IAAI,CAAC,OAAO;AAAA,IACf,MAAM,MAAM,OAAO,WAAW,QAAQ;AAAA,IACtC,MAAM,OAAO,GAAG,UAAU,SAAS;AAAA,IACnC,OAAO;AAAA,MACN,0BAA0B;AAAA,MAC1B,kBAAkB,cAAc,GAAG,YAAY,QAAQ;AAAA,MACvD;AAAA,MACA,gBAAiB;AAAA,MACjB,aAAc,YAAY,QAAQ,WAAW,SAAS,GAAG;AAAA,MACzD;AAAA,IACD,EAAE,KAAK;AAAA,CAAI;AAAA,GACX,CACH;AAAA,EAEA,OAAO,CAAC,aAAa,GAAG,QAAQ,EAAE,KAAK;AAAA;AAAA,CAAM;AAAA;",
9
+ "debugId": "55545DA3CDEDC0F664756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -52,4 +52,15 @@ export type EngineActivity = {
52
52
  at: number;
53
53
  name: string;
54
54
  status: 'ok' | 'error';
55
+ } | {
56
+ /** Emitted between attempts of a retried mutation. `attempt` is the
57
+ * attempt that just failed (1-indexed); `delayMs` is the wait before
58
+ * the next attempt. Surfaces OCC retries to observability. */
59
+ type: 'mutationRetry';
60
+ at: number;
61
+ name: string;
62
+ attempt: number;
63
+ delayMs: number;
64
+ errorName: string;
65
+ errorMessage: string;
55
66
  };
@@ -42,6 +42,9 @@ 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';
46
+ export { exponentialBackoff, isSerializationFailure, RetriesExhaustedError } from './retry';
47
+ export type { ExponentialBackoffOptions, RetryPolicy } from './retry';
45
48
  export { createSyncEngine, SchemaError, UnauthorizedError } from './syncEngine';
46
49
  export type { CrdtFields, SubscribeArgs, Subscription, SyncEngine } from './syncEngine';
47
50
  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,112 @@ var createVectorIndex = (options) => {
1039
1041
  var defineSchedule = (definition) => definition;
1040
1042
  // src/engine/mutation.ts
1041
1043
  var defineMutation = (definition) => definition;
1044
+ // src/engine/retry.ts
1045
+ var PG_RETRY_CODES = new Set(["40001", "40P01"]);
1046
+ var isSerializationFailure = (error) => {
1047
+ if (error === null || typeof error !== "object")
1048
+ return false;
1049
+ const code = error.code;
1050
+ if (typeof code === "string" && PG_RETRY_CODES.has(code))
1051
+ return true;
1052
+ const cause = error.cause;
1053
+ if (cause !== undefined)
1054
+ return isSerializationFailure(cause);
1055
+ return false;
1056
+ };
1057
+ var exponentialBackoff = (options = {}) => (attempt) => {
1058
+ const base = options.baseMs ?? 25;
1059
+ const factor = options.factor ?? 2;
1060
+ const max = options.maxMs ?? 1000;
1061
+ const jitter = options.jitter ?? 0.2;
1062
+ const raw = Math.min(max, base * factor ** Math.max(0, attempt - 1));
1063
+ const spread = raw * jitter;
1064
+ return raw + (Math.random() * 2 - 1) * spread;
1065
+ };
1066
+
1067
+ class RetriesExhaustedError extends Error {
1068
+ attempts;
1069
+ elapsedMs;
1070
+ cause;
1071
+ constructor(attempts, elapsedMs, cause) {
1072
+ const message = cause instanceof Error ? cause.message : String(cause);
1073
+ super(`retries exhausted after ${attempts} attempts (${elapsedMs}ms): ${message}`);
1074
+ this.name = "RetriesExhaustedError";
1075
+ this.attempts = attempts;
1076
+ this.elapsedMs = elapsedMs;
1077
+ this.cause = cause;
1078
+ }
1079
+ }
1080
+ // src/engine/sandbox.ts
1081
+ var isolatedJscModule;
1082
+ var loadIsolatedJsc = async () => {
1083
+ if (isolatedJscModule !== undefined)
1084
+ return isolatedJscModule;
1085
+ try {
1086
+ isolatedJscModule = await import("@absolutejs/isolated-jsc");
1087
+ return isolatedJscModule;
1088
+ } catch (error) {
1089
+ throw new Error('sandboxedHandler requires the optional peer "@absolutejs/isolated-jsc". Install it with: bun add @absolutejs/isolated-jsc', { cause: error });
1090
+ }
1091
+ };
1092
+ var wrap = (source) => `
1093
+ (async () => {
1094
+ const userFn = (${source});
1095
+ if (typeof userFn !== 'function') {
1096
+ throw new Error(
1097
+ 'sandboxedHandler must evaluate to (args, ctx, actions) => result; got ' +
1098
+ typeof userFn
1099
+ );
1100
+ }
1101
+ const actions = {
1102
+ insert: __syncActionInsert,
1103
+ update: __syncActionUpdate,
1104
+ delete: __syncActionDelete,
1105
+ change: __syncActionChange
1106
+ };
1107
+ return await userFn(args, ctx, actions);
1108
+ })()
1109
+ `;
1110
+ var compile = async (source, config) => {
1111
+ const { createIsolate } = await loadIsolatedJsc();
1112
+ const isolate = await createIsolate({
1113
+ memoryLimit: config.memoryLimit ?? 32
1114
+ });
1115
+ const script = await isolate.compileScript(wrap(source));
1116
+ return { isolate, script, timeoutMs: config.timeout ?? 5000 };
1117
+ };
1118
+ var makeSandboxedHandler = (source, config = {}) => {
1119
+ let pending;
1120
+ const getCompiled = async () => {
1121
+ if (pending !== undefined) {
1122
+ const compiled = await pending;
1123
+ if (!compiled.isolate.isDisposed)
1124
+ return compiled;
1125
+ pending = undefined;
1126
+ }
1127
+ pending = compile(source, config);
1128
+ return pending;
1129
+ };
1130
+ return async (args, ctx, actions) => {
1131
+ const { Reference } = await loadIsolatedJsc();
1132
+ const compiled = await getCompiled();
1133
+ const context = await compiled.isolate.createContext();
1134
+ try {
1135
+ await context.setGlobal("args", args);
1136
+ await context.setGlobal("ctx", ctx);
1137
+ await context.setGlobal("__syncActionInsert", new Reference((table, data) => actions.insert(table, data)));
1138
+ await context.setGlobal("__syncActionUpdate", new Reference((table, data) => actions.update(table, data)));
1139
+ await context.setGlobal("__syncActionDelete", new Reference((table, row) => actions.delete(table, row)));
1140
+ await context.setGlobal("__syncActionChange", new Reference((collection, change) => actions.change(collection, change)));
1141
+ return await compiled.script.run(context, {
1142
+ timeout: compiled.timeoutMs
1143
+ });
1144
+ } finally {
1145
+ await context.dispose().catch(() => {});
1146
+ }
1147
+ };
1148
+ };
1149
+
1042
1150
  // src/engine/syncEngine.ts
1043
1151
  class UnauthorizedError extends Error {
1044
1152
  constructor(subject) {
@@ -1115,6 +1223,7 @@ var equalsIgnoringScore = (a, b) => {
1115
1223
  var createSyncEngine = (options = {}) => {
1116
1224
  const registry = new Map;
1117
1225
  const mutations = new Map;
1226
+ const sandboxRunners = new Map;
1118
1227
  const writers = new Map;
1119
1228
  const readers = new Map;
1120
1229
  const schedules = new Map;
@@ -1991,7 +2100,16 @@ var createSyncEngine = (options = {}) => {
1991
2100
  return total;
1992
2101
  },
1993
2102
  registerMutation: (mutation) => {
2103
+ if (mutation.handler === undefined && mutation.sandboxedHandler === undefined) {
2104
+ throw new Error(`Mutation "${mutation.name}" must define either \`handler\` or \`sandboxedHandler\``);
2105
+ }
2106
+ if (mutation.handler !== undefined && mutation.sandboxedHandler !== undefined) {
2107
+ throw new Error(`Mutation "${mutation.name}" defines both \`handler\` and \`sandboxedHandler\` \u2014 pick one`);
2108
+ }
1994
2109
  mutations.set(mutation.name, mutation);
2110
+ if (mutation.sandboxedHandler !== undefined) {
2111
+ sandboxRunners.set(mutation.name, makeSandboxedHandler(mutation.sandboxedHandler, mutation.sandbox));
2112
+ }
1995
2113
  },
1996
2114
  registerWriter: (table, writer) => {
1997
2115
  writers.set(table, writer);
@@ -2031,30 +2149,68 @@ var createSyncEngine = (options = {}) => {
2031
2149
  throw new UnauthorizedError(`run mutation "${name}"`);
2032
2150
  }
2033
2151
  }
2152
+ const sandboxRunner = sandboxRunners.get(name);
2153
+ const invokeHandler = sandboxRunner !== undefined ? sandboxRunner : (a, c, actions) => Promise.resolve(mutation.handler(a, c, actions));
2034
2154
  const runHandler = async (tx) => {
2035
2155
  const { actions, buffered } = makeActions(tx, ctx, true);
2036
- const result = await mutation.handler(args, ctx, actions);
2156
+ const result = await invokeHandler(args, ctx, actions);
2037
2157
  return { buffered, result };
2038
2158
  };
2039
- try {
2040
- const { buffered, result } = runInTransaction !== undefined ? await runInTransaction((tx) => runHandler(tx)) : await runHandler(undefined);
2041
- await applyChangeBatch(buffered);
2042
- emitActivity({
2043
- type: "mutation",
2044
- at: Date.now(),
2045
- name,
2046
- status: "ok"
2047
- });
2048
- return result;
2049
- } catch (error) {
2050
- emitActivity({
2051
- type: "mutation",
2052
- at: Date.now(),
2053
- name,
2054
- status: "error"
2055
- });
2056
- throw error;
2159
+ const retry = mutation.retry;
2160
+ const maxAttempts = retry === undefined ? 1 : retry.maxAttempts ?? 5;
2161
+ const isRetryable = retry?.isRetryable ?? isSerializationFailure;
2162
+ const computeDelay = retry?.backoff ?? exponentialBackoff();
2163
+ const maxElapsedMs = retry?.maxElapsedMs ?? 30000;
2164
+ const startedAt = Date.now();
2165
+ let lastError;
2166
+ let attemptsMade = 0;
2167
+ for (let attempt = 1;attempt <= maxAttempts; attempt++) {
2168
+ attemptsMade = attempt;
2169
+ try {
2170
+ const { buffered, result } = runInTransaction !== undefined ? await runInTransaction((tx) => runHandler(tx)) : await runHandler(undefined);
2171
+ await applyChangeBatch(buffered);
2172
+ emitActivity({
2173
+ type: "mutation",
2174
+ at: Date.now(),
2175
+ name,
2176
+ status: "ok"
2177
+ });
2178
+ return result;
2179
+ } catch (error) {
2180
+ lastError = error;
2181
+ const elapsedMs = Date.now() - startedAt;
2182
+ const canRetry = attempt < maxAttempts && isRetryable(error) && elapsedMs < maxElapsedMs;
2183
+ if (!canRetry)
2184
+ break;
2185
+ const rawDelay = computeDelay(attempt);
2186
+ const remaining = maxElapsedMs - elapsedMs;
2187
+ if (remaining <= 0)
2188
+ break;
2189
+ const delayMs = Math.max(0, Math.min(rawDelay, remaining));
2190
+ emitActivity({
2191
+ type: "mutationRetry",
2192
+ at: Date.now(),
2193
+ name,
2194
+ attempt,
2195
+ delayMs,
2196
+ errorName: error instanceof Error ? error.name : "Error",
2197
+ errorMessage: error instanceof Error ? error.message : String(error)
2198
+ });
2199
+ if (delayMs > 0) {
2200
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
2201
+ }
2202
+ }
2203
+ }
2204
+ emitActivity({
2205
+ type: "mutation",
2206
+ at: Date.now(),
2207
+ name,
2208
+ status: "error"
2209
+ });
2210
+ if (attemptsMade > 1) {
2211
+ throw new RetriesExhaustedError(attemptsMade, Date.now() - startedAt, lastError);
2057
2212
  }
2213
+ throw lastError;
2058
2214
  },
2059
2215
  registerSchedule: (schedule) => {
2060
2216
  schedules.set(schedule.name, schedule);
@@ -2378,11 +2534,13 @@ export {
2378
2534
  materialize,
2379
2535
  mapOp,
2380
2536
  joinNode,
2537
+ isSerializationFailure,
2381
2538
  isEmptyViewDiff,
2382
2539
  hydrateRoute,
2383
2540
  fromRowChange,
2384
2541
  filterOp,
2385
2542
  field,
2543
+ exponentialBackoff,
2386
2544
  defineSearchCollection,
2387
2545
  defineSchema,
2388
2546
  defineSchedule,
@@ -2406,8 +2564,9 @@ export {
2406
2564
  aggregateOp,
2407
2565
  UnauthorizedError,
2408
2566
  SchemaError,
2409
- SEARCH_SCORE_FIELD
2567
+ SEARCH_SCORE_FIELD,
2568
+ RetriesExhaustedError
2410
2569
  };
2411
2570
 
2412
- //# debugId=3CE4C25B50EAC6B864756E2164756E21
2571
+ //# debugId=000A0D740DBD7CBA64756E2164756E21
2413
2572
  //# sourceMappingURL=index.js.map