orez 0.2.20 → 0.2.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/browser.d.ts +5 -0
  2. package/dist/browser.d.ts.map +1 -1
  3. package/dist/browser.js +1 -0
  4. package/dist/browser.js.map +1 -1
  5. package/dist/cf-do/test-protocol.d.ts +11 -0
  6. package/dist/cf-do/test-protocol.d.ts.map +1 -0
  7. package/dist/cf-do/test-protocol.js +137 -0
  8. package/dist/cf-do/test-protocol.js.map +1 -0
  9. package/dist/cf-do/worker.d.ts +65 -0
  10. package/dist/cf-do/worker.d.ts.map +1 -0
  11. package/dist/cf-do/worker.js +440 -0
  12. package/dist/cf-do/worker.js.map +1 -0
  13. package/dist/config.d.ts +4 -0
  14. package/dist/config.d.ts.map +1 -1
  15. package/dist/config.js +1 -0
  16. package/dist/config.js.map +1 -1
  17. package/dist/index.d.ts +2 -3
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +60 -28
  20. package/dist/index.js.map +1 -1
  21. package/dist/pg-proxy-do-backend.d.ts +49 -0
  22. package/dist/pg-proxy-do-backend.d.ts.map +1 -0
  23. package/dist/pg-proxy-do-backend.js +713 -0
  24. package/dist/pg-proxy-do-backend.js.map +1 -0
  25. package/dist/pglite-ipc.d.ts +3 -0
  26. package/dist/pglite-ipc.d.ts.map +1 -1
  27. package/dist/pglite-ipc.js +34 -12
  28. package/dist/pglite-ipc.js.map +1 -1
  29. package/dist/pglite-web-proxy.d.ts +3 -0
  30. package/dist/pglite-web-proxy.d.ts.map +1 -1
  31. package/dist/pglite-web-proxy.js +50 -7
  32. package/dist/pglite-web-proxy.js.map +1 -1
  33. package/dist/query-rewrites.d.ts +2 -0
  34. package/dist/query-rewrites.d.ts.map +1 -0
  35. package/dist/query-rewrites.js +140 -0
  36. package/dist/query-rewrites.js.map +1 -0
  37. package/dist/worker/browser-admin.d.ts +13 -0
  38. package/dist/worker/browser-admin.d.ts.map +1 -0
  39. package/dist/worker/browser-admin.js +33 -0
  40. package/dist/worker/browser-admin.js.map +1 -0
  41. package/dist/worker/browser-embed.d.ts +12 -12
  42. package/dist/worker/browser-embed.d.ts.map +1 -1
  43. package/dist/worker/browser-embed.js +7 -0
  44. package/dist/worker/browser-embed.js.map +1 -1
  45. package/package.json +2 -2
  46. package/src/browser.ts +7 -0
  47. package/src/config.ts +5 -0
  48. package/src/index.ts +66 -33
  49. package/src/pg-proxy-do-backend.ts +840 -0
  50. package/src/pglite-ipc.test.ts +17 -0
  51. package/src/pglite-ipc.ts +31 -12
  52. package/src/pglite-web-proxy.test.ts +57 -0
  53. package/src/pglite-web-proxy.ts +48 -7
  54. package/src/query-rewrites.test.ts +30 -0
  55. package/src/query-rewrites.ts +152 -0
  56. package/src/worker/browser-admin.ts +52 -0
  57. package/src/worker/browser-embed-admin.test.ts +75 -0
  58. package/src/worker/browser-embed.ts +21 -12
package/dist/browser.d.ts CHANGED
@@ -24,6 +24,11 @@ export interface OrezBrowserConfig {
24
24
  initSql?: string;
25
25
  /** log level */
26
26
  logLevel?: string;
27
+ /**
28
+ * intercept browser-mode orez admin routes before they reach zero-cache.
29
+ * default: true.
30
+ */
31
+ disableAdminApi?: boolean;
27
32
  }
28
33
  export interface OrezBrowserInstance {
29
34
  /** PGlite proxies (for direct queries from project-server) */
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAMtD,MAAM,WAAW,iBAAiB;IAChC,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,wCAAwC;IACxC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IAEvB,uCAAuC;IACvC,eAAe,EAAE,MAAM,CAAA;IAEvB,kCAAkC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAEzB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,SAAS,EAAE;QACT,QAAQ,EAAE,cAAc,CAAA;QACxB,GAAG,EAAE,cAAc,CAAA;QACnB,GAAG,EAAE,cAAc,CAAA;KACpB,CAAA;IAED,gEAAgE;IAChE,iBAAiB,IAAI,IAAI,CAAA;IAEzB,uDAAuD;IACvD,eAAe,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAA;IAE9E,yCAAyC;IACzC,UAAU,CAAC,OAAO,EAAE;QAClB,MAAM,EAAE,MAAM,CAAA;QACd,GAAG,EAAE,MAAM,CAAA;QACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAChC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KACrB,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAE9E,sBAAsB;IACtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CAgI9B"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAMtD,MAAM,WAAW,iBAAiB;IAChC,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,wCAAwC;IACxC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IAEvB,uCAAuC;IACvC,eAAe,EAAE,MAAM,CAAA;IAEvB,kCAAkC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAEzB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,SAAS,EAAE;QACT,QAAQ,EAAE,cAAc,CAAA;QACxB,GAAG,EAAE,cAAc,CAAA;QACnB,GAAG,EAAE,cAAc,CAAA;KACpB,CAAA;IAED,gEAAgE;IAChE,iBAAiB,IAAI,IAAI,CAAA;IAEzB,uDAAuD;IACvD,eAAe,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAA;IAE9E,yCAAyC;IACzC,UAAU,CAAC,OAAO,EAAE;QAClB,MAAM,EAAE,MAAM,CAAA;QACd,GAAG,EAAE,MAAM,CAAA;QACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAChC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KACrB,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAE9E,sBAAsB;IACtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CAiI9B"}
package/dist/browser.js CHANGED
@@ -82,6 +82,7 @@ export async function startOrezBrowser(config) {
82
82
  pglite: pgPostgres,
83
83
  appId,
84
84
  publications: config.publications,
85
+ disableAdminApi: config.disableAdminApi ?? true,
85
86
  env: {
86
87
  ZERO_LOG_LEVEL: config.logLevel || 'info',
87
88
  },
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAkDhE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAyB;IAEzB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAA;IACpC,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,KAAK,SAAS,CAAA;IAE7E,kEAAkE;IAClE,MAAM,gBAAgB,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE;QAC1D,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,iBAAiB;KACxB,CAAC,CAAA;IACF,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE;QACrD,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,YAAY;KACnB,CAAC,CAAA;IACF,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE;QACrD,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,YAAY;KACnB,CAAC,CAAA;IAEF,0BAA0B;IAC1B,gBAAgB,CAAC,WAAW,CAAC;QAC3B,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,qBAAqB;QAC9B,IAAI,EAAE,UAAU;KACjB,CAAC,CAAA;IACF,WAAW,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IACjF,WAAW,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAEjF,sDAAsD;IACtD,MAAM,UAAU,GAAG,IAAI,cAAc,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAA;IACnE,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IACpD,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IAEpD,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAA;IAC3E,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAA;IAE1D,mDAAmD;IACnD,MAAM,qBAAqB,CAAC,UAA+B,CAAC,CAAA;IAC5D,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAA;IAEzD,gCAAgC;IAChC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QACrC,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAA;IACnD,CAAC;IAED,qBAAqB;IACrB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,KAAK,CACjC,iEAAiE,EACjE,CAAC,YAAY,CAAC,CACf,CAAA;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,MAAM,UAAU,CAAC,IAAI,CAAC,uBAAuB,YAAY,GAAG,CAAC,CAAA;QAC/D,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,iCAAiC;IACjC,qFAAqF;IACrF,gEAAgE;IAChE,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAA;IACpE,MAAM,KAAK,GAAG,MAAM,kBAAkB,CACpC;QACE,QAAQ,EAAE,UAA+B;QACzC,GAAG,EAAE,KAA0B;QAC/B,GAAG,EAAE,KAA0B;QAC/B,gBAAgB,EAAE,EAAE;KACrB,EACD,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CACnC,CAAA;IACD,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAQvD;IAAC,UAAkB,CAAC,oBAAoB,GAAG,CAAC,IAAiB,EAAE,EAAE;QAChE,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAC9B,CAAC,CACA;IAAC,UAAkB,CAAC,qBAAqB,GAAG,EAAE,CAC9C;IAAC,UAAkB,CAAC,iBAAiB,GAAG,MAAM,CAG9C;IAAC,UAAkB,CAAC,aAAa,GAAG,UAAU,CAAA;IAE/C,iDAAiD;IACjD,MAAM,EAAE,0BAA0B,EAAE,GAAG,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAA;IAChF,MAAM,EAAE,GAAG,MAAM,0BAA0B,CAAC;QAC1C,MAAM,EAAE,UAA+B;QACvC,KAAK;QACL,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,GAAG,EAAE;YACH,cAAc,EAAE,MAAM,CAAC,QAAQ,IAAI,MAAM;SAC1C;KACF,CAAC,CAAA;IACF,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAA;IAElD,qBAAqB;IACrB,MAAM,EAAE,uBAAuB,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAA;IAE5E,OAAO;QACL,SAAS,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE;QAE3D,iBAAiB;YACf,uBAAuB,EAAE,CAAA;QAC3B,CAAC;QAED,eAAe,CAAC,EAAO,EAAE,GAAG,GAAG,GAAG,EAAE,OAAgC;YAClE,EAAE,CAAC,eAAe,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;QAC7B,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,OAKhB;YACC,OAAO,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QAC/B,CAAC;QAED,KAAK,CAAC,IAAI;YACR,MAAM,EAAE,CAAC,IAAI,EAAE,CAAA;YACf,KAAK,CAAC,KAAK,EAAE,CAAA;YACb,qBAAqB,EAAE,CAAA;YACvB,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;QACvE,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAwDhE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAyB;IAEzB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAA;IACpC,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,KAAK,SAAS,CAAA;IAE7E,kEAAkE;IAClE,MAAM,gBAAgB,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE;QAC1D,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,iBAAiB;KACxB,CAAC,CAAA;IACF,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE;QACrD,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,YAAY;KACnB,CAAC,CAAA;IACF,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE;QACrD,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,YAAY;KACnB,CAAC,CAAA;IAEF,0BAA0B;IAC1B,gBAAgB,CAAC,WAAW,CAAC;QAC3B,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,qBAAqB;QAC9B,IAAI,EAAE,UAAU;KACjB,CAAC,CAAA;IACF,WAAW,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IACjF,WAAW,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAEjF,sDAAsD;IACtD,MAAM,UAAU,GAAG,IAAI,cAAc,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAA;IACnE,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IACpD,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IAEpD,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAA;IAC3E,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAA;IAE1D,mDAAmD;IACnD,MAAM,qBAAqB,CAAC,UAA+B,CAAC,CAAA;IAC5D,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAA;IAEzD,gCAAgC;IAChC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QACrC,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAA;IACnD,CAAC;IAED,qBAAqB;IACrB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,KAAK,CACjC,iEAAiE,EACjE,CAAC,YAAY,CAAC,CACf,CAAA;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,MAAM,UAAU,CAAC,IAAI,CAAC,uBAAuB,YAAY,GAAG,CAAC,CAAA;QAC/D,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,iCAAiC;IACjC,qFAAqF;IACrF,gEAAgE;IAChE,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAA;IACpE,MAAM,KAAK,GAAG,MAAM,kBAAkB,CACpC;QACE,QAAQ,EAAE,UAA+B;QACzC,GAAG,EAAE,KAA0B;QAC/B,GAAG,EAAE,KAA0B;QAC/B,gBAAgB,EAAE,EAAE;KACrB,EACD,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CACnC,CAAA;IACD,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAQvD;IAAC,UAAkB,CAAC,oBAAoB,GAAG,CAAC,IAAiB,EAAE,EAAE;QAChE,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAC9B,CAAC,CACA;IAAC,UAAkB,CAAC,qBAAqB,GAAG,EAAE,CAC9C;IAAC,UAAkB,CAAC,iBAAiB,GAAG,MAAM,CAG9C;IAAC,UAAkB,CAAC,aAAa,GAAG,UAAU,CAAA;IAE/C,iDAAiD;IACjD,MAAM,EAAE,0BAA0B,EAAE,GAAG,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAA;IAChF,MAAM,EAAE,GAAG,MAAM,0BAA0B,CAAC;QAC1C,MAAM,EAAE,UAA+B;QACvC,KAAK;QACL,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,IAAI;QAC/C,GAAG,EAAE;YACH,cAAc,EAAE,MAAM,CAAC,QAAQ,IAAI,MAAM;SAC1C;KACF,CAAC,CAAA;IACF,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAA;IAElD,qBAAqB;IACrB,MAAM,EAAE,uBAAuB,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAA;IAE5E,OAAO;QACL,SAAS,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE;QAE3D,iBAAiB;YACf,uBAAuB,EAAE,CAAA;QAC3B,CAAC;QAED,eAAe,CAAC,EAAO,EAAE,GAAG,GAAG,GAAG,EAAE,OAAgC;YAClE,EAAE,CAAC,eAAe,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;QAC7B,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,OAKhB;YACC,OAAO,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QAC/B,CAAC;QAED,KAAK,CAAC,IAAI;YACR,MAAM,EAAE,CAAC,IAAI,EAAE,CAAA;YACf,KAAK,CAAC,KAAK,EAAE,CAAA;YACb,qBAAqB,EAAE,CAAA;YACvB,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;QACvE,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * quick protocol test: connects to the DO, sends initConnection,
3
+ * does CRUD, verifies pokes.
4
+ *
5
+ * usage:
6
+ * npx wrangler dev --port 8799 &
7
+ * sleep 3
8
+ * bun run src/cf-do/test-protocol.ts
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=test-protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-protocol.d.ts","sourceRoot":"","sources":["../../src/cf-do/test-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ /**
3
+ * quick protocol test: connects to the DO, sends initConnection,
4
+ * does CRUD, verifies pokes.
5
+ *
6
+ * usage:
7
+ * npx wrangler dev --port 8799 &
8
+ * sleep 3
9
+ * bun run src/cf-do/test-protocol.ts
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const ws_1 = require("ws");
13
+ const DO_URL = 'http://127.0.0.1:8799';
14
+ const CLIENT_SCHEMA = {
15
+ tables: {
16
+ todo: {
17
+ primaryKey: ['id'],
18
+ columns: {
19
+ id: { type: 'string' },
20
+ title: { type: 'string' },
21
+ completed: { type: 'boolean' },
22
+ sortOrder: { type: 'number' },
23
+ createdAt: { type: 'number' },
24
+ updatedAt: { type: 'number' },
25
+ },
26
+ },
27
+ user: {
28
+ primaryKey: ['id'],
29
+ columns: {
30
+ id: { type: 'string' },
31
+ name: { type: 'string' },
32
+ },
33
+ },
34
+ },
35
+ };
36
+ const FOO_QUERY = {
37
+ table: 'todo',
38
+ orderBy: [['sortOrder', 'asc']],
39
+ };
40
+ const INIT_CONNECTION_MSG = [
41
+ 'initConnection',
42
+ {
43
+ desiredQueriesPatch: [
44
+ { op: 'put', hash: 'query-hash-1', ast: FOO_QUERY },
45
+ ],
46
+ clientSchema: CLIENT_SCHEMA,
47
+ },
48
+ ];
49
+ function makeInitURL(clientGroupID = 'test-group', clientID = 'test-client') {
50
+ const params = new URLSearchParams({
51
+ clientGroupID,
52
+ clientID,
53
+ userID: 'test-user',
54
+ wsid: 'ws-1',
55
+ schemaVersion: '1',
56
+ ts: String(Date.now()),
57
+ });
58
+ return `ws://127.0.0.1:8799/sync/v49/connect?${params}`;
59
+ }
60
+ async function waitForMessage(ws, timeoutMs = 5000) {
61
+ return new Promise((resolve, reject) => {
62
+ const timeout = setTimeout(() => reject(new Error('timeout')), timeoutMs);
63
+ ws.once('message', (data) => {
64
+ clearTimeout(timeout);
65
+ resolve(JSON.parse(data.toString()));
66
+ });
67
+ });
68
+ }
69
+ async function main() {
70
+ console.log('connecting to DO...');
71
+ const ws = new ws_1.WebSocket(makeInitURL(), {
72
+ headers: {
73
+ 'Sec-WebSocket-Protocol': btoa(JSON.stringify(INIT_CONNECTION_MSG)),
74
+ },
75
+ });
76
+ await new Promise((resolve, reject) => {
77
+ ws.on('open', resolve);
78
+ ws.on('error', reject);
79
+ setTimeout(() => reject(new Error('connect timeout')), 5000);
80
+ });
81
+ console.log('connected!');
82
+ // Should receive: connected, pokeStart, pokePart, pokeEnd
83
+ const connected = await waitForMessage(ws);
84
+ console.log('got:', JSON.stringify(connected).slice(0, 200));
85
+ const pokeStart = await waitForMessage(ws);
86
+ console.log('got:', JSON.stringify(pokeStart).slice(0, 200));
87
+ const pokePart = await waitForMessage(ws);
88
+ console.log('got:', JSON.stringify(pokePart).slice(0, 400));
89
+ const pokeEnd = await waitForMessage(ws);
90
+ console.log('got:', JSON.stringify(pokeEnd).slice(0, 200));
91
+ // Send CRUD push
92
+ console.log('\nsending push mutation...');
93
+ ws.send(JSON.stringify([
94
+ 'push',
95
+ {
96
+ mutations: [
97
+ {
98
+ type: 'crud',
99
+ name: '_zero_crud',
100
+ clientID: 'test-client',
101
+ id: 1,
102
+ args: [{
103
+ ops: [{
104
+ op: 'upsert',
105
+ tableName: 'todo',
106
+ value: {
107
+ id: 'todo-1',
108
+ title: 'test todo',
109
+ completed: false,
110
+ sortOrder: 0,
111
+ createdAt: Date.now(),
112
+ updatedAt: Date.now(),
113
+ },
114
+ primaryKey: ['id'],
115
+ }],
116
+ }],
117
+ },
118
+ ],
119
+ },
120
+ ]));
121
+ // Should receive: pushResponse + pokeStart/pokePart/pokeEnd
122
+ const pushResponse = await waitForMessage(ws);
123
+ console.log('pushResponse:', JSON.stringify(pushResponse).slice(0, 200));
124
+ const pokeStart2 = await waitForMessage(ws);
125
+ console.log('poke:', JSON.stringify(pokeStart2).slice(0, 200));
126
+ const pokePart2 = await waitForMessage(ws);
127
+ console.log('pokePart:', JSON.stringify(pokePart2).slice(0, 400));
128
+ const pokeEnd2 = await waitForMessage(ws);
129
+ console.log('pokeEnd:', JSON.stringify(pokeEnd2).slice(0, 200));
130
+ console.log('\n✓ protocol test passed!');
131
+ ws.close();
132
+ }
133
+ main().catch((err) => {
134
+ console.error('FAIL:', err);
135
+ process.exit(1);
136
+ });
137
+ //# sourceMappingURL=test-protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-protocol.js","sourceRoot":"","sources":["../../src/cf-do/test-protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import { DurableObject } from 'cloudflare:workers';
2
+ /**
3
+ * zero-do: a Durable Object that speaks the Zero sync protocol
4
+ * over DO-native SQLite. replaces zero-cache + pg-proxy + pGlite
5
+ * with a single DO that handles initConnection, push/pull, and pokes.
6
+ */
7
+ interface Env {
8
+ ZERO_DO: DurableObjectNamespace;
9
+ }
10
+ export declare class ZeroDO extends DurableObject {
11
+ private sql;
12
+ private initialized;
13
+ private schemaTables;
14
+ constructor(ctx: DurableObjectState, env: Env);
15
+ fetch(request: Request): Promise<Response>;
16
+ private handleSyncConnect;
17
+ webSocketMessage(socket: WebSocket, messageData: string | ArrayBuffer): Promise<void>;
18
+ webSocketClose(socket: WebSocket, code: number, reason: string, wasClean: boolean): Promise<void>;
19
+ private applyDesiredQueries;
20
+ private resolveTablesFromPatch;
21
+ private extractTableFromAST;
22
+ private handlePush;
23
+ private handleHttpPush;
24
+ private applyCrudMutation;
25
+ private upsertRow;
26
+ private updateRow;
27
+ private deleteRow;
28
+ private appendChange;
29
+ private readChangesSince;
30
+ private currentWatermark;
31
+ private ensureInternalTables;
32
+ private ensureSchemaTables;
33
+ private createTable;
34
+ private mapZeroTypeToSQLite;
35
+ private tableExists;
36
+ private readAllRows;
37
+ private sendSyncPoke;
38
+ private broadcastPoke;
39
+ private syncRowPatchFromChange;
40
+ private extractID;
41
+ private sendJSON;
42
+ private parseMessage;
43
+ private decodeInitConnection;
44
+ }
45
+ declare const _default: {
46
+ fetch(request: Request, env: Env): Promise<Response>;
47
+ };
48
+ export default _default;
49
+ interface DurableObjectState {
50
+ storage: {
51
+ sql: any;
52
+ };
53
+ acceptWebSocket(socket: WebSocket): void;
54
+ getWebSockets(): WebSocket[];
55
+ }
56
+ interface DurableObjectNamespace {
57
+ idFromName(name: string): DurableObjectId;
58
+ get(id: DurableObjectId): DurableObjectStub;
59
+ }
60
+ interface DurableObjectId {
61
+ }
62
+ interface DurableObjectStub {
63
+ fetch(request: Request): Promise<Response>;
64
+ }
65
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/cf-do/worker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD;;;;GAIG;AAIH,UAAU,GAAG;IACX,OAAO,EAAE,sBAAsB,CAAA;CAChC;AA0DD,qBAAa,MAAO,SAAQ,aAAa;IACvC,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,WAAW,CAAQ;IAE3B,OAAO,CAAC,YAAY,CAAoB;gBAE5B,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG;IAOvC,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IA0BhD,OAAO,CAAC,iBAAiB;IA+CnB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW;IAiCrE,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO;IAMvF,OAAO,CAAC,mBAAmB;IA0C3B,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,UAAU;YAsCJ,cAAc;IA6B5B,OAAO,CAAC,iBAAiB;IAuBzB,OAAO,CAAC,SAAS;IAiBjB,OAAO,CAAC,SAAS;IAgBjB,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,oBAAoB;IAgB5B,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,WAAW;IAkBnB,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,oBAAoB;CAQ7B;;mBAKsB,OAAO,OAAO,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;;AAD5D,wBAqBC;AAID,UAAU,kBAAkB;IAC1B,OAAO,EAAE;QAAE,GAAG,EAAE,GAAG,CAAA;KAAE,CAAA;IACrB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAA;IACxC,aAAa,IAAI,SAAS,EAAE,CAAA;CAC7B;AAED,UAAU,sBAAsB;IAC9B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAA;IACzC,GAAG,CAAC,EAAE,EAAE,eAAe,GAAG,iBAAiB,CAAA;CAC5C;AAED,UAAU,eAAe;CAAI;AAE7B,UAAU,iBAAiB;IACzB,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;CAC3C"}