orez 0.1.36 → 0.1.37

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 (130) hide show
  1. package/dist/cli-entry.js +0 -0
  2. package/dist/cli.js +7 -1
  3. package/dist/cli.js.map +1 -1
  4. package/dist/config.d.ts +1 -0
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +1 -0
  7. package/dist/config.js.map +1 -1
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +14 -11
  10. package/dist/index.js.map +1 -1
  11. package/dist/pg-proxy.d.ts.map +1 -1
  12. package/dist/pg-proxy.js +8 -4
  13. package/dist/pg-proxy.js.map +1 -1
  14. package/dist/pglite-manager.d.ts +12 -0
  15. package/dist/pglite-manager.d.ts.map +1 -1
  16. package/dist/pglite-manager.js +81 -0
  17. package/dist/pglite-manager.js.map +1 -1
  18. package/dist/recovery.js +2 -2
  19. package/dist/recovery.js.map +1 -1
  20. package/dist/replication/change-tracker.js +9 -9
  21. package/dist/replication/change-tracker.js.map +1 -1
  22. package/dist/replication/handler.d.ts +12 -0
  23. package/dist/replication/handler.d.ts.map +1 -1
  24. package/dist/replication/handler.js +32 -4
  25. package/dist/replication/handler.js.map +1 -1
  26. package/dist/worker/browser-build-config.d.ts +59 -0
  27. package/dist/worker/browser-build-config.d.ts.map +1 -0
  28. package/dist/worker/browser-build-config.js +101 -0
  29. package/dist/worker/browser-build-config.js.map +1 -0
  30. package/dist/worker/browser-embed.d.ts +58 -0
  31. package/dist/worker/browser-embed.d.ts.map +1 -0
  32. package/dist/worker/browser-embed.js +195 -0
  33. package/dist/worker/browser-embed.js.map +1 -0
  34. package/dist/worker/cf-patches.d.ts +20 -0
  35. package/dist/worker/cf-patches.d.ts.map +1 -0
  36. package/dist/worker/cf-patches.js +94 -0
  37. package/dist/worker/cf-patches.js.map +1 -0
  38. package/dist/worker/index.d.ts +12 -0
  39. package/dist/worker/index.d.ts.map +1 -0
  40. package/dist/worker/index.js +105 -0
  41. package/dist/worker/index.js.map +1 -0
  42. package/dist/worker/shims/fastify.d.ts +80 -0
  43. package/dist/worker/shims/fastify.d.ts.map +1 -0
  44. package/dist/worker/shims/fastify.js +223 -0
  45. package/dist/worker/shims/fastify.js.map +1 -0
  46. package/dist/worker/shims/http-service.d.ts +104 -0
  47. package/dist/worker/shims/http-service.d.ts.map +1 -0
  48. package/dist/worker/shims/http-service.js +198 -0
  49. package/dist/worker/shims/http-service.js.map +1 -0
  50. package/dist/worker/shims/node-stub.d.ts +147 -0
  51. package/dist/worker/shims/node-stub.d.ts.map +1 -0
  52. package/dist/worker/shims/node-stub.js +204 -0
  53. package/dist/worker/shims/node-stub.js.map +1 -0
  54. package/dist/worker/shims/postgres.d.ts +115 -0
  55. package/dist/worker/shims/postgres.d.ts.map +1 -0
  56. package/dist/worker/shims/postgres.js +1167 -0
  57. package/dist/worker/shims/postgres.js.map +1 -0
  58. package/dist/worker/shims/sqlite-browser.d.ts +54 -0
  59. package/dist/worker/shims/sqlite-browser.d.ts.map +1 -0
  60. package/dist/worker/shims/sqlite-browser.js +144 -0
  61. package/dist/worker/shims/sqlite-browser.js.map +1 -0
  62. package/dist/worker/shims/sqlite.d.ts +126 -0
  63. package/dist/worker/shims/sqlite.d.ts.map +1 -0
  64. package/dist/worker/shims/sqlite.js +599 -0
  65. package/dist/worker/shims/sqlite.js.map +1 -0
  66. package/dist/worker/shims/stream-browser.d.ts +9 -0
  67. package/dist/worker/shims/stream-browser.d.ts.map +1 -0
  68. package/dist/worker/shims/stream-browser.js +13 -0
  69. package/dist/worker/shims/stream-browser.js.map +1 -0
  70. package/dist/worker/shims/ws-browser.d.ts +50 -0
  71. package/dist/worker/shims/ws-browser.d.ts.map +1 -0
  72. package/dist/worker/shims/ws-browser.js +105 -0
  73. package/dist/worker/shims/ws-browser.js.map +1 -0
  74. package/dist/worker/shims/ws.d.ts +62 -0
  75. package/dist/worker/shims/ws.d.ts.map +1 -0
  76. package/dist/worker/shims/ws.js +310 -0
  77. package/dist/worker/shims/ws.js.map +1 -0
  78. package/dist/worker/types.d.ts +57 -0
  79. package/dist/worker/types.d.ts.map +1 -0
  80. package/dist/worker/types.js +9 -0
  81. package/dist/worker/types.js.map +1 -0
  82. package/dist/worker/zero-cache-embed-cf.d.ts +63 -0
  83. package/dist/worker/zero-cache-embed-cf.d.ts.map +1 -0
  84. package/dist/worker/zero-cache-embed-cf.js +268 -0
  85. package/dist/worker/zero-cache-embed-cf.js.map +1 -0
  86. package/dist/worker/zero-cache-embed.d.ts +66 -0
  87. package/dist/worker/zero-cache-embed.d.ts.map +1 -0
  88. package/dist/worker/zero-cache-embed.js +200 -0
  89. package/dist/worker/zero-cache-embed.js.map +1 -0
  90. package/package.json +62 -3
  91. package/src/cli-entry.ts +0 -0
  92. package/src/cli.ts +8 -1
  93. package/src/config.ts +2 -0
  94. package/src/index.ts +15 -10
  95. package/src/integration/integration.test.ts +1 -1
  96. package/src/integration/restore-live-stress.test.ts +2 -2
  97. package/src/pg-proxy.ts +9 -4
  98. package/src/pglite-manager.ts +111 -0
  99. package/src/recovery.ts +2 -2
  100. package/src/replication/change-tracker.test.ts +1 -1
  101. package/src/replication/change-tracker.ts +9 -9
  102. package/src/replication/handler.test.ts +37 -0
  103. package/src/replication/handler.ts +46 -4
  104. package/src/wasm-sqlite.test.ts +2 -1
  105. package/src/worker/browser-build-config.test.ts +59 -0
  106. package/src/worker/browser-build-config.ts +105 -0
  107. package/src/worker/browser-embed.ts +306 -0
  108. package/src/worker/cf-patches.ts +114 -0
  109. package/src/worker/embed-integration.test.ts +321 -0
  110. package/src/worker/index.ts +138 -0
  111. package/src/worker/shims/fastify.test.ts +255 -0
  112. package/src/worker/shims/fastify.ts +292 -0
  113. package/src/worker/shims/http-service.test.ts +355 -0
  114. package/src/worker/shims/http-service.ts +293 -0
  115. package/src/worker/shims/node-stub.ts +223 -0
  116. package/src/worker/shims/postgres.test.ts +364 -0
  117. package/src/worker/shims/postgres.ts +1419 -0
  118. package/src/worker/shims/sqlite-browser.test.ts +233 -0
  119. package/src/worker/shims/sqlite-browser.ts +178 -0
  120. package/src/worker/shims/sqlite.test.ts +641 -0
  121. package/src/worker/shims/sqlite.ts +731 -0
  122. package/src/worker/shims/ws-browser.test.ts +184 -0
  123. package/src/worker/shims/ws-browser.ts +125 -0
  124. package/src/worker/shims/ws.test.ts +288 -0
  125. package/src/worker/shims/ws.ts +367 -0
  126. package/src/worker/types.ts +75 -0
  127. package/src/worker/worker-integration.test.ts +223 -0
  128. package/src/worker/worker.test.ts +136 -0
  129. package/src/worker/zero-cache-embed-cf.ts +367 -0
  130. package/src/worker/zero-cache-embed.ts +277 -0
@@ -0,0 +1,101 @@
1
+ /**
2
+ * browser build configuration for zero-cache embed.
3
+ *
4
+ * provides the bundler alias map and polyfill configuration needed
5
+ * to bundle zero-cache for browser Web Workers.
6
+ *
7
+ * usage with esbuild:
8
+ *
9
+ * import { getBrowserAliases, getBrowserDefine } from 'orez/worker/browser-build-config'
10
+ *
11
+ * await esbuild.build({
12
+ * entryPoints: ['./my-worker.ts'],
13
+ * bundle: true,
14
+ * format: 'esm',
15
+ * alias: getBrowserAliases(),
16
+ * define: getBrowserDefine(),
17
+ * })
18
+ *
19
+ * usage with vite:
20
+ *
21
+ * import { getBrowserAliases } from 'orez/worker/browser-build-config'
22
+ *
23
+ * export default defineConfig({
24
+ * resolve: { alias: getBrowserAliases() },
25
+ * worker: { format: 'es' },
26
+ * })
27
+ */
28
+ /**
29
+ * bundler aliases that swap zero-cache's Node.js dependencies
30
+ * for browser-compatible shims.
31
+ *
32
+ * the consumer must have these packages installed:
33
+ * - orez (provides postgres/sqlite/fastify/ws shims)
34
+ * - events (EventEmitter polyfill)
35
+ * - buffer (Buffer polyfill)
36
+ * - process (process polyfill)
37
+ *
38
+ * optional (only needed if zero-cache code uses them):
39
+ * - crypto-browserify, stream-browserify, path-browserify, os-browserify
40
+ */
41
+ export function getBrowserAliases() {
42
+ return {
43
+ // -- orez shims for zero-cache dependencies --
44
+ postgres: 'orez/worker/shims/postgres',
45
+ '@rocicorp/zero-sqlite3': 'orez/worker/shims/sqlite',
46
+ fastify: 'orez/worker/shims/fastify',
47
+ ws: 'orez/worker/shims/ws',
48
+ // -- Node.js built-in polyfills --
49
+ // these are needed because zero-cache imports node: modules.
50
+ // the bundler replaces them with browser-compatible packages.
51
+ 'node:events': 'events',
52
+ 'node:buffer': 'buffer',
53
+ 'node:process': 'process/browser',
54
+ 'node:crypto': 'orez/worker/shims/node-stub',
55
+ 'crypto-browserify': 'orez/worker/shims/node-stub',
56
+ 'node:stream': 'stream-browserify',
57
+ 'node:path': 'path-browserify',
58
+ 'node:os': 'os-browserify/browser',
59
+ // -- stubs for Node.js modules that zero-cache imports but doesn't --
60
+ // -- use in SINGLE_PROCESS mode --
61
+ 'node:http': 'orez/worker/shims/node-stub',
62
+ 'node:net': 'orez/worker/shims/node-stub',
63
+ 'node:tls': 'orez/worker/shims/node-stub',
64
+ 'node:child_process': 'orez/worker/shims/node-stub',
65
+ 'node:fs': 'orez/worker/shims/node-stub',
66
+ 'node:fs/promises': 'orez/worker/shims/node-stub',
67
+ 'node:url': 'orez/worker/shims/node-stub',
68
+ 'node:util': 'orez/worker/shims/node-stub',
69
+ 'node:assert': 'orez/worker/shims/node-stub',
70
+ 'node:inspector/promises': 'orez/worker/shims/node-stub',
71
+ 'node:v8': 'orez/worker/shims/node-stub',
72
+ 'node:zlib': 'orez/worker/shims/node-stub',
73
+ };
74
+ }
75
+ /**
76
+ * esbuild define map for browser builds.
77
+ * replaces Node.js globals with browser equivalents.
78
+ */
79
+ export function getBrowserDefine() {
80
+ return {
81
+ 'process.env.NODE_ENV': '"development"',
82
+ 'process.env.SINGLE_PROCESS': '"1"',
83
+ 'process.versions.node': '"20.0.0"',
84
+ };
85
+ }
86
+ /**
87
+ * combined config for esbuild builds.
88
+ * merges aliases, define, and common settings.
89
+ */
90
+ export function getBrowserBuildConfig() {
91
+ return {
92
+ alias: getBrowserAliases(),
93
+ define: getBrowserDefine(),
94
+ // recommended esbuild settings for browser worker bundles
95
+ format: 'esm',
96
+ platform: 'browser',
97
+ target: 'es2022',
98
+ bundle: true,
99
+ };
100
+ }
101
+ //# sourceMappingURL=browser-build-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-build-config.js","sourceRoot":"","sources":["../../src/worker/browser-build-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO;QACL,+CAA+C;QAC/C,QAAQ,EAAE,4BAA4B;QACtC,wBAAwB,EAAE,0BAA0B;QACpD,OAAO,EAAE,2BAA2B;QACpC,EAAE,EAAE,sBAAsB;QAE1B,mCAAmC;QACnC,6DAA6D;QAC7D,8DAA8D;QAC9D,aAAa,EAAE,QAAQ;QACvB,aAAa,EAAE,QAAQ;QACvB,cAAc,EAAE,iBAAiB;QACjC,aAAa,EAAE,6BAA6B;QAC5C,mBAAmB,EAAE,6BAA6B;QAClD,aAAa,EAAE,mBAAmB;QAClC,WAAW,EAAE,iBAAiB;QAC9B,SAAS,EAAE,uBAAuB;QAElC,sEAAsE;QACtE,mCAAmC;QACnC,WAAW,EAAE,6BAA6B;QAC1C,UAAU,EAAE,6BAA6B;QACzC,UAAU,EAAE,6BAA6B;QACzC,oBAAoB,EAAE,6BAA6B;QACnD,SAAS,EAAE,6BAA6B;QACxC,kBAAkB,EAAE,6BAA6B;QACjD,UAAU,EAAE,6BAA6B;QACzC,WAAW,EAAE,6BAA6B;QAC1C,aAAa,EAAE,6BAA6B;QAC5C,yBAAyB,EAAE,6BAA6B;QACxD,SAAS,EAAE,6BAA6B;QACxC,WAAW,EAAE,6BAA6B;KAC3C,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO;QACL,sBAAsB,EAAE,eAAe;QACvC,4BAA4B,EAAE,KAAK;QACnC,uBAAuB,EAAE,UAAU;KACpC,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,KAAK,EAAE,iBAAiB,EAAE;QAC1B,MAAM,EAAE,gBAAgB,EAAE;QAC1B,0DAA0D;QAC1D,MAAM,EAAE,KAAc;QACtB,QAAQ,EAAE,SAAkB;QAC5B,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,IAAI;KACb,CAAA;AACH,CAAC"}
@@ -0,0 +1,58 @@
1
+ import type { PGlite } from '@electric-sql/pglite';
2
+ export interface ZeroCacheEmbedBrowserOptions {
3
+ /** PGlite instance */
4
+ pglite: PGlite;
5
+ /**
6
+ * sql.js Database instance for SQLite replica storage.
7
+ * if not provided, looks for globalThis.__orez_sqljs_db,
8
+ * then falls back to an in-memory stub (limited functionality).
9
+ */
10
+ sqlite?: unknown;
11
+ /** zero app ID (default: 'zero') */
12
+ appId?: string;
13
+ /** publication names */
14
+ publications?: string[];
15
+ /** additional env vars passed to zero-cache */
16
+ env?: Record<string, string>;
17
+ /** timeout in ms waiting for zero-cache ready (default: 30000) */
18
+ readyTimeout?: number;
19
+ }
20
+ export interface HttpRequest {
21
+ method: string;
22
+ url: string;
23
+ headers?: Record<string, string>;
24
+ body?: string | null;
25
+ }
26
+ export interface HttpResponse {
27
+ status: number;
28
+ headers: Record<string, string>;
29
+ body: string;
30
+ }
31
+ /** WebSocket-like object — matches CF WebSocket, browser WebSocket, or MessagePort adapter */
32
+ interface WsLike {
33
+ readyState: number;
34
+ send(data: string | ArrayBuffer | ArrayBufferView): void;
35
+ close(code?: number, reason?: string): void;
36
+ addEventListener(type: string, handler: (event: any) => void): void;
37
+ removeEventListener(type: string, handler: (event: any) => void): void;
38
+ }
39
+ export interface ZeroCacheEmbedBrowser {
40
+ /** whether zero-cache is ready */
41
+ readonly ready: boolean;
42
+ /**
43
+ * handle a WebSocket connection from a Zero client.
44
+ * accepts any WebSocket-like object (browser WebSocket, MessagePort adapter, etc.)
45
+ * feeds it into zero-cache's handoff mechanism.
46
+ */
47
+ handleWebSocket(ws: WsLike, url?: string): void;
48
+ /**
49
+ * handle an HTTP request (push/pull/health).
50
+ * for environments without the Fetch API Request/Response.
51
+ */
52
+ handleHttp(request: HttpRequest): Promise<HttpResponse>;
53
+ /** stop zero-cache */
54
+ stop(): Promise<void>;
55
+ }
56
+ export declare function startZeroCacheEmbedBrowser(opts: ZeroCacheEmbedBrowserOptions): Promise<ZeroCacheEmbedBrowser>;
57
+ export {};
58
+ //# sourceMappingURL=browser-embed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-embed.d.ts","sourceRoot":"","sources":["../../src/worker/browser-embed.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAOlD,MAAM,WAAW,4BAA4B;IAC3C,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAA;IAEd;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd,wBAAwB;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IAEvB,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAE5B,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,IAAI,EAAE,MAAM,CAAA;CACb;AAED,8FAA8F;AAC9F,UAAU,MAAM;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,eAAe,GAAG,IAAI,CAAA;IACxD,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3C,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAA;IACnE,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAA;CACvE;AAED,MAAM,WAAW,qBAAqB;IACpC,kCAAkC;IAClC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IAEvB;;;;OAIG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAE/C;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAEvD,sBAAsB;IACtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB;AAED,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,4BAA4B,GACjC,OAAO,CAAC,qBAAqB,CAAC,CA+LhC"}
@@ -0,0 +1,195 @@
1
+ // NOTE THIS IS NOT OREZ NODE THIS IS NOT A GOOD REFERENCE BECAUSE ITS OUR EARLY GUESS AT WHAT COULD WORK
2
+ // DO NOT STUDY THIS, THE OTHER STUFF IN SRC IS WHERE YOU EANT TO LOOK
3
+ /**
4
+ * zero-cache embedded runner for browser Web Workers.
5
+ *
6
+ * same pattern as the CF embed but for browser environments:
7
+ *
8
+ * postgres → orez/worker/shims/postgres (PGlite-backed)
9
+ * @rocicorp/zero-sqlite3 → orez/worker/shims/sqlite (sql.js or in-memory)
10
+ * fastify → orez/worker/shims/fastify (route capture)
11
+ * ws → orez/worker/shims/ws (MessagePort/WebSocket)
12
+ *
13
+ * the consumer's bundler (esbuild/vite) must configure these aliases
14
+ * plus Node.js polyfills. use getBrowserBuildConfig() for the alias map.
15
+ *
16
+ * usage:
17
+ *
18
+ * import { startZeroCacheEmbedBrowser } from 'orez/worker/browser-embed'
19
+ *
20
+ * const zc = await startZeroCacheEmbedBrowser({
21
+ * pglite: pg,
22
+ * sqlite: sqlJsDb, // optional — sql.js Database instance
23
+ * })
24
+ *
25
+ * // connect a Zero client via WebSocket-like object
26
+ * zc.handleWebSocket(wsOrPort)
27
+ *
28
+ * // or handle HTTP requests (push/pull)
29
+ * const result = await zc.handleHttp({ method: 'GET', url: '/' })
30
+ */
31
+ import EventEmitter from 'node:events';
32
+ // static import so the bundler can follow the dependency tree.
33
+ // @ts-expect-error — internal zero-cache module, no type declarations
34
+ import { runWorker as _runWorker } from '@rocicorp/zero/out/zero-cache/src/server/runner/run-worker.js';
35
+ const runWorkerFn = _runWorker;
36
+ export async function startZeroCacheEmbedBrowser(opts) {
37
+ const appId = opts.appId || 'zero';
38
+ const publications = opts.publications?.join(',') || `orez_${appId}_public`;
39
+ const readyTimeout = opts.readyTimeout ?? 30000;
40
+ // set up sqlite storage from sql.js or in-memory
41
+ if (opts.sqlite) {
42
+ // consumer provided a sql.js Database — create adapter
43
+ const { createSqlJsStorage } = await import('./shims/sqlite-browser.js');
44
+ globalThis.__orez_do_sqlite = createSqlJsStorage(opts.sqlite);
45
+ }
46
+ else if (!globalThis.__orez_do_sqlite) {
47
+ // no sqlite provided — use in-memory stub
48
+ const { createInMemoryStorage } = await import('./shims/sqlite-browser.js');
49
+ globalThis.__orez_do_sqlite = createInMemoryStorage();
50
+ }
51
+ // set up PGlite for postgres shim
52
+ ;
53
+ globalThis.__orez_pglite = opts.pglite;
54
+ globalThis.process ??= {};
55
+ globalThis.process.env ??= {};
56
+ globalThis.process.pid ??= 1;
57
+ globalThis.process.argv ??= [];
58
+ globalThis.process.kill ??= () => { };
59
+ globalThis.process.env.SINGLE_PROCESS = '1';
60
+ globalThis.process.env.NODE_ENV = 'development';
61
+ // create fake parent EventEmitter for zero-cache's runWorker()
62
+ const parent = new EventEmitter();
63
+ const parentEmitter = new EventEmitter();
64
+ parent.send = (message) => {
65
+ parentEmitter.emit('message', message);
66
+ return true;
67
+ };
68
+ parent.kill = (signal = 'SIGTERM') => {
69
+ parent.emit(signal, signal);
70
+ };
71
+ parent.pid = 1;
72
+ // shim process.exit
73
+ const origExit = globalThis.process.exit;
74
+ globalThis.process.exit = (code) => {
75
+ parent.emit('exit', code ?? 0);
76
+ };
77
+ // build env for zero-cache
78
+ const env = {
79
+ ...globalThis.process.env,
80
+ SINGLE_PROCESS: '1',
81
+ NODE_ENV: 'development',
82
+ ZERO_UPSTREAM_DB: 'pglite://in-process',
83
+ ZERO_CVR_DB: 'pglite://in-process',
84
+ ZERO_CHANGE_DB: 'pglite://in-process',
85
+ ZERO_REPLICA_FILE: ':browser-sqlite:',
86
+ ZERO_PORT: '0',
87
+ ZERO_APP_ID: appId,
88
+ ZERO_APP_PUBLICATIONS: publications,
89
+ ZERO_LOG_LEVEL: opts.env?.ZERO_LOG_LEVEL || 'info',
90
+ ZERO_NUM_SYNC_WORKERS: opts.env?.ZERO_NUM_SYNC_WORKERS || '1',
91
+ ZERO_ENABLE_QUERY_PLANNER: 'false',
92
+ ...opts.env,
93
+ };
94
+ // wrap parent with onMessageType/onceMessageType helpers
95
+ const wrappedParent = new Proxy(parent, {
96
+ get(target, prop, receiver) {
97
+ if (prop === 'onMessageType') {
98
+ return (type, handler) => {
99
+ target.on('message', (data) => {
100
+ if (Array.isArray(data) && data.length === 2 && data[0] === type) {
101
+ handler(data[1]);
102
+ }
103
+ });
104
+ return receiver;
105
+ };
106
+ }
107
+ if (prop === 'onceMessageType') {
108
+ return (type, handler) => {
109
+ const listener = (data) => {
110
+ if (Array.isArray(data) && data.length === 2 && data[0] === type) {
111
+ target.off('message', listener);
112
+ handler(data[1]);
113
+ }
114
+ };
115
+ target.on('message', listener);
116
+ return receiver;
117
+ };
118
+ }
119
+ return Reflect.get(target, prop, receiver);
120
+ },
121
+ });
122
+ // state
123
+ let isReady = false;
124
+ let runWorkerPromise = null;
125
+ let fastifyInstance = null;
126
+ // wait for "ready" message
127
+ const readyPromise = new Promise((resolve, reject) => {
128
+ const timeout = setTimeout(() => {
129
+ reject(new Error(`zero-cache browser embed: timed out waiting for ready after ${readyTimeout}ms`));
130
+ }, readyTimeout);
131
+ parentEmitter.on('message', (msg) => {
132
+ if (Array.isArray(msg) && msg[0] === 'ready') {
133
+ clearTimeout(timeout);
134
+ isReady = true;
135
+ resolve();
136
+ }
137
+ });
138
+ });
139
+ // start zero-cache
140
+ runWorkerPromise = runWorkerFn(wrappedParent, env).catch((err) => {
141
+ if (!isReady) {
142
+ throw err;
143
+ }
144
+ });
145
+ await readyPromise;
146
+ fastifyInstance = globalThis.__orez_fastify_instance;
147
+ return {
148
+ get ready() {
149
+ return isReady;
150
+ },
151
+ handleWebSocket(ws, url = '/', headers) {
152
+ if (!isReady || !fastifyInstance?.server)
153
+ return;
154
+ const message = {
155
+ url,
156
+ headers: headers || {},
157
+ method: 'GET',
158
+ };
159
+ // feed the WebSocket into zero-cache's handoff mechanism.
160
+ // the fastify shim's server is an EventEmitter with onMessageType.
161
+ // installWebSocketHandoff (non-Server branch) listens for "handoff".
162
+ fastifyInstance.server.emit('message', ['handoff', { message, head: new Uint8Array(0) }], ws // the WebSocket-like object as sendHandle
163
+ );
164
+ },
165
+ async handleHttp(request) {
166
+ if (!isReady || !fastifyInstance?.inject) {
167
+ return { status: 503, headers: {}, body: 'not ready' };
168
+ }
169
+ const result = await fastifyInstance.inject({
170
+ method: request.method,
171
+ url: request.url,
172
+ headers: request.headers || {},
173
+ payload: request.body,
174
+ });
175
+ return {
176
+ status: result.statusCode,
177
+ headers: result.headers,
178
+ body: result.body,
179
+ };
180
+ },
181
+ async stop() {
182
+ isReady = false;
183
+ wrappedParent.kill('SIGTERM');
184
+ if (runWorkerPromise) {
185
+ await Promise.race([runWorkerPromise, new Promise((r) => setTimeout(r, 5000))]);
186
+ }
187
+ if (origExit) {
188
+ ;
189
+ globalThis.process.exit = origExit;
190
+ }
191
+ delete globalThis.process.env.SINGLE_PROCESS;
192
+ },
193
+ };
194
+ }
195
+ //# sourceMappingURL=browser-embed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-embed.js","sourceRoot":"","sources":["../../src/worker/browser-embed.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * zero-cache CF Workers patches.
3
+ *
4
+ * applies patches to @rocicorp/zero's internal files so zero-cache
5
+ * can run in SINGLE_PROCESS mode on CF Workers where dynamic import()
6
+ * doesn't work.
7
+ *
8
+ * two patches:
9
+ * 1. worker-urls.js — replace file:// URLs with zero-worker:// identifiers
10
+ * 2. processes.js — replace dynamic import() with static worker module lookup
11
+ *
12
+ * usage in a post-build script:
13
+ *
14
+ * import { patchZeroCacheForCF } from 'orez/worker/cf-patches'
15
+ * patchZeroCacheForCF('./node_modules')
16
+ *
17
+ * idempotent: safe to run multiple times.
18
+ */
19
+ export declare function patchZeroCacheForCF(nodeModulesPath: string): void;
20
+ //# sourceMappingURL=cf-patches.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cf-patches.d.ts","sourceRoot":"","sources":["../../src/worker/cf-patches.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAKjE"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * zero-cache CF Workers patches.
3
+ *
4
+ * applies patches to @rocicorp/zero's internal files so zero-cache
5
+ * can run in SINGLE_PROCESS mode on CF Workers where dynamic import()
6
+ * doesn't work.
7
+ *
8
+ * two patches:
9
+ * 1. worker-urls.js — replace file:// URLs with zero-worker:// identifiers
10
+ * 2. processes.js — replace dynamic import() with static worker module lookup
11
+ *
12
+ * usage in a post-build script:
13
+ *
14
+ * import { patchZeroCacheForCF } from 'orez/worker/cf-patches'
15
+ * patchZeroCacheForCF('./node_modules')
16
+ *
17
+ * idempotent: safe to run multiple times.
18
+ */
19
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
20
+ import { resolve } from 'node:path';
21
+ export function patchZeroCacheForCF(nodeModulesPath) {
22
+ const zcBase = resolve(nodeModulesPath, '@rocicorp', 'zero', 'out', 'zero-cache', 'src');
23
+ patchWorkerUrls(zcBase);
24
+ patchProcesses(zcBase);
25
+ }
26
+ function patchWorkerUrls(zcBase) {
27
+ const workerUrlsPath = resolve(zcBase, 'server', 'worker-urls.js');
28
+ if (!existsSync(workerUrlsPath)) {
29
+ console.warn('[orez] worker-urls.js not found at', workerUrlsPath);
30
+ return;
31
+ }
32
+ const content = readFileSync(workerUrlsPath, 'utf-8');
33
+ // skip if already patched
34
+ if (content.includes('zero-worker://')) {
35
+ return;
36
+ }
37
+ writeFileSync(workerUrlsPath, `// patched by orez for CF Workers (replaces file:// URLs with identifiers)
38
+ const u = (n) => new URL("zero-worker://" + n);
39
+ export const MAIN_URL = u("main");
40
+ export const CHANGE_STREAMER_URL = u("change-streamer");
41
+ export const REAPER_URL = u("reaper");
42
+ export const REPLICATOR_URL = u("replicator");
43
+ export const SYNCER_URL = u("syncer");
44
+ `);
45
+ console.log('[orez] patched zero-cache worker-urls.js');
46
+ }
47
+ function patchProcesses(zcBase) {
48
+ const processesPath = resolve(zcBase, 'types', 'processes.js');
49
+ if (!existsSync(processesPath)) {
50
+ console.warn('[orez] processes.js not found at', processesPath);
51
+ return;
52
+ }
53
+ let code = readFileSync(processesPath, 'utf-8');
54
+ // skip if already patched
55
+ if (code.includes('__zc_workers')) {
56
+ return;
57
+ }
58
+ // add static imports of all zero-cache worker modules at the top.
59
+ // these are relative to processes.js location in @rocicorp/zero.
60
+ const workerImports = `\
61
+ // patched by orez for CF Workers (static imports replace dynamic import())
62
+ import { default as __zc_main } from "../server/main.js";
63
+ import { default as __zc_change_streamer } from "../server/change-streamer.js";
64
+ import { default as __zc_reaper } from "../server/reaper.js";
65
+ import { default as __zc_replicator } from "../server/replicator.js";
66
+ import { default as __zc_syncer } from "../server/syncer.js";
67
+ const __zc_workers = {
68
+ "main": __zc_main,
69
+ "change-streamer": __zc_change_streamer,
70
+ "reaper": __zc_reaper,
71
+ "replicator": __zc_replicator,
72
+ "syncer": __zc_syncer,
73
+ };
74
+ `;
75
+ // replace the dynamic import in childWorker with a synchronous lookup.
76
+ // original: import(moduleUrl.href).then(async ({ default: runWorker }) => ...
77
+ // patched: lookup __zc_workers by name, then continue as before
78
+ const dynamicImportPattern = 'import(moduleUrl.href).then(async ({ default: runWorker })';
79
+ const staticLookup = '((async () => { ' +
80
+ 'const _name = moduleUrl.hostname || moduleUrl.pathname.split("/").pop()?.replace(".js",""); ' +
81
+ 'const runWorker = __zc_workers[_name]; ' +
82
+ 'if (!runWorker) throw new Error("orez: unknown zero-cache worker: " + _name + " (available: " + Object.keys(__zc_workers).join(", ") + ")"); ' +
83
+ 'return { default: runWorker }; ' +
84
+ '})()).then(async ({ default: runWorker })';
85
+ if (!code.includes(dynamicImportPattern)) {
86
+ console.warn('[orez] could not find dynamic import pattern in processes.js. ' +
87
+ 'zero-cache version may have changed — check compatibility.');
88
+ return;
89
+ }
90
+ code = workerImports + code.replace(dynamicImportPattern, staticLookup);
91
+ writeFileSync(processesPath, code);
92
+ console.log('[orez] patched zero-cache processes.js (static worker imports)');
93
+ }
94
+ //# sourceMappingURL=cf-patches.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cf-patches.js","sourceRoot":"","sources":["../../src/worker/cf-patches.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,MAAM,UAAU,mBAAmB,CAAC,eAAuB;IACzD,MAAM,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,CAAC,CAAA;IAExF,eAAe,CAAC,MAAM,CAAC,CAAA;IACvB,cAAc,CAAC,MAAM,CAAC,CAAA;AACxB,CAAC;AAED,SAAS,eAAe,CAAC,MAAc;IACrC,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAA;IAClE,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,IAAI,CAAC,oCAAoC,EAAE,cAAc,CAAC,CAAA;QAClE,OAAM;IACR,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAA;IAErD,0BAA0B;IAC1B,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACvC,OAAM;IACR,CAAC;IAED,aAAa,CACX,cAAc,EACd;;;;;;;CAOH,CACE,CAAA;IACD,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAA;AACzD,CAAC;AAED,SAAS,cAAc,CAAC,MAAc;IACpC,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,CAAA;IAC9D,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,kCAAkC,EAAE,aAAa,CAAC,CAAA;QAC/D,OAAM;IACR,CAAC;IAED,IAAI,IAAI,GAAG,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAA;IAE/C,0BAA0B;IAC1B,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QAClC,OAAM;IACR,CAAC;IAED,kEAAkE;IAClE,iEAAiE;IACjE,MAAM,aAAa,GAAG;;;;;;;;;;;;;;CAcvB,CAAA;IAEC,uEAAuE;IACvE,8EAA8E;IAC9E,iEAAiE;IACjE,MAAM,oBAAoB,GACxB,4DAA4D,CAAA;IAC9D,MAAM,YAAY,GAChB,kBAAkB;QAClB,8FAA8F;QAC9F,yCAAyC;QACzC,+IAA+I;QAC/I,iCAAiC;QACjC,2CAA2C,CAAA;IAE7C,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;QACzC,OAAO,CAAC,IAAI,CACV,gEAAgE;YAC9D,4DAA4D,CAC/D,CAAA;QACD,OAAM;IACR,CAAC;IAED,IAAI,GAAG,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,YAAY,CAAC,CAAA;IACvE,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;IAClC,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAA;AAC/E,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { OrezWorkerOptions, OrezWorker } from './types.js';
2
+ export type { OrezWorkerOptions, OrezWorker } from './types.js';
3
+ export type { ChangeRecord } from '../replication/change-tracker.js';
4
+ export type { ReplicationWriter } from '../replication/handler.js';
5
+ /**
6
+ * create an orez worker instance.
7
+ *
8
+ * accepts either a pre-created PGlite instance or PGliteOptions to
9
+ * create one. installs the _orez schema and change tracking infrastructure.
10
+ */
11
+ export declare function createOrezWorker(opts: OrezWorkerOptions): Promise<OrezWorker>;
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/worker/index.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAG/D,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC/D,YAAY,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACpE,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAElE;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CA2FnF"}
@@ -0,0 +1,105 @@
1
+ // NOTE THIS IS NOT OREZ NODE THIS IS NOT A GOOD REFERENCE BECAUSE ITS OUR EARLY GUESS AT WHAT COULD WORK
2
+ // DO NOT STUDY THIS, THE OTHER STUFF IN SRC IS WHERE YOU EANT TO LOOK
3
+ /**
4
+ * orez/worker: embeddable PGlite + change tracking.
5
+ *
6
+ * runs without Node.js dependencies — works in CF Workers, browsers,
7
+ * vitest, bun, deno. provides the PGlite database layer with change
8
+ * tracking and replication encoding that zero-cache needs.
9
+ *
10
+ * usage:
11
+ * import { createOrezWorker } from 'orez/worker'
12
+ *
13
+ * const orez = await createOrezWorker({
14
+ * pgliteOptions: { dataDir: 'memory://' },
15
+ * })
16
+ * await orez.exec('CREATE TABLE foo (id TEXT PRIMARY KEY, name TEXT)')
17
+ * await orez.installChangeTracking()
18
+ * await orez.query('INSERT INTO foo VALUES ($1, $2)', ['1', 'bar'])
19
+ * const changes = await orez.getChangesSince(0)
20
+ */
21
+ import { Mutex } from '../mutex.js';
22
+ import { installChangeTracking, getChangesSince, getCurrentWatermark, purgeConsumedChanges, } from '../replication/change-tracker.js';
23
+ import { handleStartReplication } from '../replication/handler.js';
24
+ /**
25
+ * create an orez worker instance.
26
+ *
27
+ * accepts either a pre-created PGlite instance or PGliteOptions to
28
+ * create one. installs the _orez schema and change tracking infrastructure.
29
+ */
30
+ export async function createOrezWorker(opts) {
31
+ let db;
32
+ let ownsInstance;
33
+ if (opts.pglite) {
34
+ db = opts.pglite;
35
+ ownsInstance = false;
36
+ }
37
+ else if (opts.pgliteOptions) {
38
+ // dynamic import so PGlite isn't required at module load time.
39
+ // this lets the worker module be imported in environments where
40
+ // PGlite is provided externally (CF Workers with custom WASM).
41
+ const { PGlite: PGliteCtor } = await import('@electric-sql/pglite');
42
+ db = new PGliteCtor(opts.pgliteOptions);
43
+ await db.waitReady;
44
+ ownsInstance = true;
45
+ }
46
+ else {
47
+ throw new Error('orez/worker: provide either pglite or pgliteOptions');
48
+ }
49
+ const mutex = new Mutex();
50
+ // set up publication env if provided (change-tracker reads this)
51
+ if (opts.publications?.length) {
52
+ // change-tracker reads ZERO_APP_PUBLICATIONS to decide which tables to track.
53
+ // in non-Node environments globalThis may not have process.env, so we
54
+ // set it defensively.
55
+ if (typeof globalThis !== 'undefined') {
56
+ ;
57
+ globalThis.process ??= {};
58
+ globalThis.process.env ??= {};
59
+ globalThis.process.env.ZERO_APP_PUBLICATIONS = opts.publications.join(',');
60
+ }
61
+ }
62
+ // install core schema (plpgsql, _orez schema)
63
+ await db.exec('CREATE EXTENSION IF NOT EXISTS plpgsql');
64
+ // install change tracking (creates _orez schema, tables, trigger function)
65
+ await installChangeTracking(db);
66
+ const worker = {
67
+ get db() {
68
+ return db;
69
+ },
70
+ get mutex() {
71
+ return mutex;
72
+ },
73
+ get ownsInstance() {
74
+ return ownsInstance;
75
+ },
76
+ async query(sql, params) {
77
+ return db.query(sql, params);
78
+ },
79
+ async exec(sql) {
80
+ await db.exec(sql);
81
+ },
82
+ async installChangeTracking() {
83
+ await installChangeTracking(db);
84
+ },
85
+ async getChangesSince(watermark, limit) {
86
+ return getChangesSince(db, watermark, limit);
87
+ },
88
+ async getCurrentWatermark() {
89
+ return getCurrentWatermark(db);
90
+ },
91
+ async purgeChanges(watermark) {
92
+ return purgeConsumedChanges(db, watermark);
93
+ },
94
+ async startReplication(writer) {
95
+ await handleStartReplication('START_REPLICATION', writer, db, mutex);
96
+ },
97
+ async close() {
98
+ if (ownsInstance && !db.closed) {
99
+ await db.close();
100
+ }
101
+ },
102
+ };
103
+ return worker;
104
+ }
105
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/worker/index.ts"],"names":[],"mappings":"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"}