orez 0.2.26 → 0.2.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cf-do/worker.d.ts.map +1 -1
- package/dist/cf-do/worker.js +9 -1
- package/dist/cf-do/worker.js.map +1 -1
- package/dist/pg-proxy-do-backend.d.ts +2 -0
- package/dist/pg-proxy-do-backend.d.ts.map +1 -1
- package/dist/pg-proxy-do-backend.js +49 -7
- package/dist/pg-proxy-do-backend.js.map +1 -1
- package/dist/pg-sqlite-compiler/catalog/seed.d.ts +67 -0
- package/dist/pg-sqlite-compiler/catalog/seed.d.ts.map +1 -0
- package/dist/pg-sqlite-compiler/catalog/seed.js +436 -0
- package/dist/pg-sqlite-compiler/catalog/seed.js.map +1 -0
- package/dist/pg-sqlite-compiler/index.d.ts +12 -0
- package/dist/pg-sqlite-compiler/index.d.ts.map +1 -0
- package/dist/pg-sqlite-compiler/index.js +59 -0
- package/dist/pg-sqlite-compiler/index.js.map +1 -0
- package/dist/pg-sqlite-compiler/passes/ast-utils.d.ts +48 -0
- package/dist/pg-sqlite-compiler/passes/ast-utils.d.ts.map +1 -0
- package/dist/pg-sqlite-compiler/passes/ast-utils.js +93 -0
- package/dist/pg-sqlite-compiler/passes/ast-utils.js.map +1 -0
- package/dist/pg-sqlite-compiler/passes/catalog.d.ts +34 -0
- package/dist/pg-sqlite-compiler/passes/catalog.d.ts.map +1 -0
- package/dist/pg-sqlite-compiler/passes/catalog.js +30 -0
- package/dist/pg-sqlite-compiler/passes/catalog.js.map +1 -0
- package/dist/pg-sqlite-compiler/passes/datetime.d.ts +21 -0
- package/dist/pg-sqlite-compiler/passes/datetime.d.ts.map +1 -0
- package/dist/pg-sqlite-compiler/passes/datetime.js +53 -0
- package/dist/pg-sqlite-compiler/passes/datetime.js.map +1 -0
- package/dist/pg-sqlite-compiler/passes/index.d.ts +21 -0
- package/dist/pg-sqlite-compiler/passes/index.d.ts.map +1 -0
- package/dist/pg-sqlite-compiler/passes/index.js +39 -0
- package/dist/pg-sqlite-compiler/passes/index.js.map +1 -0
- package/dist/pg-sqlite-compiler/passes/types.d.ts +41 -0
- package/dist/pg-sqlite-compiler/passes/types.d.ts.map +1 -0
- package/dist/pg-sqlite-compiler/passes/types.js +103 -0
- package/dist/pg-sqlite-compiler/passes/types.js.map +1 -0
- package/dist/pg-sqlite-compiler/test/oracle.d.ts +34 -0
- package/dist/pg-sqlite-compiler/test/oracle.d.ts.map +1 -0
- package/dist/pg-sqlite-compiler/test/oracle.js +204 -0
- package/dist/pg-sqlite-compiler/test/oracle.js.map +1 -0
- package/dist/pg-sqlite-compiler/types.d.ts +55 -0
- package/dist/pg-sqlite-compiler/types.d.ts.map +1 -0
- package/dist/pg-sqlite-compiler/types.js +2 -0
- package/dist/pg-sqlite-compiler/types.js.map +1 -0
- package/package.json +8 -4
- package/src/admin/admin-data.test.ts +0 -348
- package/src/admin/http-proxy.ts +0 -252
- package/src/admin/log-store.ts +0 -192
- package/src/admin/server.ts +0 -471
- package/src/admin/ui.ts +0 -1322
- package/src/bench/proxy-throughput.bench.ts +0 -343
- package/src/bench/serial-mutations.bench.ts +0 -270
- package/src/browser.ts +0 -203
- package/src/cf-do/.wrangler/cache/cf.json +0 -1
- package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
- package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/0f0f3bdf0abda097eb6f1246db4657d9fc622081362d894d82c1a1ce067b05b6.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/1ddd3a4a48a11b51658444f5458a1fb175194b1d5b6a5bda20ef3fe3205b900c.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/204a39120310d37e972c5914cfd71ad55c151bdb9e8ed289a5f8c5b052dd60e4.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/3835f242df9728adba3d127a238793fd054ed3e51df3f60749ee744c469bf2a2.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/4aa9c80eb716cf55b8995ccf7afab0b36c683e6da07d7c37a3f9c570136036df.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/533e2fd1d6ea46e7a9a0017916ef341802d438d72583462755f2c1f8225e9bf2.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/5ffa1aced1225ecaeac6366f7586aa3de92761cdff8711d81fbd81f248076abd.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/686c3a9f0d7e59ed2ab607efd4b76d779c97cafeb3818380033bf7c7eb86c819.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/6e8214e8dcfadd0deb52d64e5e9ca85c6b329ace11193909845995396914c473.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/78d9ec9ff873d3fe3507ff53c2a6f6dfc408b4268eb0db3f2a146c0678965366.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/7eff9f0ed7e27ad0d3f9d923de0682fab1928591172c1ba336c5f79a134a5d85.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/836cda5b995b25867d722ed4f4c2292167e80351a3c6038db626648eb247dd8b.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/91ef63b112209ab30172763acd8a0935106c248f7f1bcae5545ce37a9f201551.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/a66ea4293a5f5938bc6d116edfa2522bb85bc37aea3541fbc09c3b613b9b32c0.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/ceb2ab26b80590840b65651deb6e948d3bf81565c6751f3a58752cf4bf4aecae.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-shm +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-wal +0 -0
- package/src/cf-do/ARCHITECTURE.md +0 -83
- package/src/cf-do/watermark.test.ts +0 -103
- package/src/cf-do/watermark.ts +0 -118
- package/src/cf-do/worker.ts +0 -1033
- package/src/cf-do/wrangler.toml +0 -11
- package/src/cf-pglite/README.md +0 -19
- package/src/change-tracking.ts +0 -25
- package/src/child-process.test.ts +0 -147
- package/src/child-process.ts +0 -90
- package/src/cli-entry.ts +0 -72
- package/src/cli.test.ts +0 -38
- package/src/cli.ts +0 -1214
- package/src/config.ts +0 -150
- package/src/do-sql-tracking.test.ts +0 -19
- package/src/do-sql-tracking.ts +0 -19
- package/src/index.ts +0 -1215
- package/src/integration/integration.test.ts +0 -517
- package/src/integration/native-binary.guard.test.ts +0 -13
- package/src/integration/native-startup.test.ts +0 -44
- package/src/integration/replication-latency.test.ts +0 -428
- package/src/integration/restore-live-stress.test.ts +0 -433
- package/src/integration/restore-reset.test.ts +0 -400
- package/src/integration/restore.test.ts +0 -274
- package/src/integration/test-permissions.ts +0 -147
- package/src/load-config.ts +0 -46
- package/src/log.ts +0 -96
- package/src/mutex.ts +0 -47
- package/src/pg-proxy-browser.singledb.test.ts +0 -233
- package/src/pg-proxy-browser.ts +0 -2022
- package/src/pg-proxy-do-backend.test.ts +0 -3890
- package/src/pg-proxy-do-backend.ts +0 -7157
- package/src/pg-proxy.ts +0 -1087
- package/src/pglite-ipc.test.ts +0 -116
- package/src/pglite-ipc.ts +0 -266
- package/src/pglite-manager.ts +0 -557
- package/src/pglite-web-proxy.test.ts +0 -57
- package/src/pglite-web-proxy.ts +0 -221
- package/src/pglite-web-worker.ts +0 -152
- package/src/pglite-worker-thread.ts +0 -253
- package/src/port.ts +0 -25
- package/src/process-title.ts +0 -9
- package/src/recovery.ts +0 -155
- package/src/replication/change-tracker.test.ts +0 -357
- package/src/replication/change-tracker.ts +0 -279
- package/src/replication/handler.test.ts +0 -511
- package/src/replication/handler.ts +0 -1190
- package/src/replication/pgoutput-encoder.test.ts +0 -697
- package/src/replication/pgoutput-encoder.ts +0 -373
- package/src/replication/tcp-replication.test.ts +0 -876
- package/src/replication/zero-compat.test.ts +0 -1150
- package/src/restore-stress.test.ts +0 -188
- package/src/s3-local.ts +0 -203
- package/src/shim/hooks.mjs +0 -120
- package/src/shim/register.mjs +0 -4
- package/src/sqlite-mode/apply-mode.ts +0 -224
- package/src/sqlite-mode/index.ts +0 -15
- package/src/sqlite-mode/native-binary.ts +0 -89
- package/src/sqlite-mode/package-resolve.ts +0 -17
- package/src/sqlite-mode/resolve-mode.ts +0 -80
- package/src/sqlite-mode/shim-template.ts +0 -159
- package/src/sqlite-mode/sqlite-mode.test.ts +0 -427
- package/src/sqlite-mode/types.ts +0 -30
- package/src/vite-plugin.ts +0 -67
- package/src/wasm-sqlite.test.ts +0 -537
- package/src/worker/browser-admin.ts +0 -52
- package/src/worker/browser-build-config.test.ts +0 -71
- package/src/worker/browser-build-config.ts +0 -109
- package/src/worker/browser-embed-admin.test.ts +0 -75
- package/src/worker/browser-embed.ts +0 -345
- package/src/worker/cf-patches.ts +0 -384
- package/src/worker/embed-integration.test.ts +0 -321
- package/src/worker/index.ts +0 -138
- package/src/worker/shims/fastify.test.ts +0 -255
- package/src/worker/shims/fastify.ts +0 -306
- package/src/worker/shims/http-service.test.ts +0 -355
- package/src/worker/shims/http-service.ts +0 -293
- package/src/worker/shims/node-stub.ts +0 -290
- package/src/worker/shims/oxfmt.ts +0 -3
- package/src/worker/shims/postgres-browser.ts +0 -59
- package/src/worker/shims/postgres-socket.test.ts +0 -576
- package/src/worker/shims/postgres-socket.ts +0 -310
- package/src/worker/shims/postgres.test.ts +0 -364
- package/src/worker/shims/postgres.ts +0 -1454
- package/src/worker/shims/sqlite-browser.test.ts +0 -233
- package/src/worker/shims/sqlite-browser.ts +0 -175
- package/src/worker/shims/sqlite.test.ts +0 -786
- package/src/worker/shims/sqlite.ts +0 -978
- package/src/worker/shims/stream-browser.ts +0 -15
- package/src/worker/shims/ws-browser.test.ts +0 -205
- package/src/worker/shims/ws-browser.ts +0 -248
- package/src/worker/shims/ws.test.ts +0 -288
- package/src/worker/shims/ws.ts +0 -467
- package/src/worker/shims/zero-process-env.ts +0 -11
- package/src/worker/types.ts +0 -75
- package/src/worker/worker-integration.test.ts +0 -223
- package/src/worker/worker.test.ts +0 -136
- package/src/worker/zero-cache-embed-cf.ts +0 -463
- package/src/worker/zero-cache-embed.ts +0 -277
|
@@ -1,463 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* zero-cache embedded runner for cloudflare workers.
|
|
3
|
-
*
|
|
4
|
-
* runs zero-cache in-process with SINGLE_PROCESS=1, using bundler aliases
|
|
5
|
-
* to swap Node.js dependencies for CF-compatible shims:
|
|
6
|
-
*
|
|
7
|
-
* postgres → orez/worker/shims/postgres-browser
|
|
8
|
-
* (real postgres package over MessagePort)
|
|
9
|
-
* @rocicorp/zero-sqlite3 → orez/worker/shims/sqlite (DO SQLite)
|
|
10
|
-
* fastify → orez/worker/shims/fastify (route capture)
|
|
11
|
-
* ws → orez/worker/shims/ws (CF WebSocket)
|
|
12
|
-
*
|
|
13
|
-
* the postgres MessagePort proxy is backed by DoBackend, so zero-cache still
|
|
14
|
-
* uses its real PG wire protocol, but storage is Cloudflare DO SQLite instead
|
|
15
|
-
* of PGlite.
|
|
16
|
-
*
|
|
17
|
-
* usage in a Durable Object:
|
|
18
|
-
*
|
|
19
|
-
* import { startZeroCacheEmbedCF } from 'orez/worker'
|
|
20
|
-
*
|
|
21
|
-
* // in ensureInitialized():
|
|
22
|
-
* const zc = await startZeroCacheEmbedCF({ ... })
|
|
23
|
-
*
|
|
24
|
-
* // in DO fetch():
|
|
25
|
-
* return zc.handleRequest(request)
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
import './shims/zero-process-env.js'
|
|
29
|
-
|
|
30
|
-
import EventEmitter from 'node:events'
|
|
31
|
-
|
|
32
|
-
// static import so wrangler can follow the dependency tree and bundle
|
|
33
|
-
// zero-cache with all its transitive deps + our shim aliases.
|
|
34
|
-
// @ts-expect-error — internal zero-cache module, no type declarations
|
|
35
|
-
import { runWorker as _runWorker } from '@rocicorp/zero/out/zero-cache/src/server/runner/run-worker.js'
|
|
36
|
-
|
|
37
|
-
import { createBrowserProxy, type BrowserProxy } from '../pg-proxy-browser.js'
|
|
38
|
-
import { DoBackend } from '../pg-proxy-do-backend.js'
|
|
39
|
-
|
|
40
|
-
const runWorkerFn = _runWorker as (
|
|
41
|
-
parent: unknown,
|
|
42
|
-
env: Record<string, string>
|
|
43
|
-
) => Promise<void>
|
|
44
|
-
|
|
45
|
-
export interface ZeroCacheEmbedCFOptions {
|
|
46
|
-
/** DO SQLite storage (also registered on globalThis.__orez_do_sqlite) */
|
|
47
|
-
doSqlite: unknown
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* base URL for the DO SQL execution endpoints (`/exec`, `/batch`).
|
|
51
|
-
* ignored when `backends` is supplied.
|
|
52
|
-
*/
|
|
53
|
-
backendUrl?: string
|
|
54
|
-
|
|
55
|
-
/** custom fetch used by DoBackend; lets a DO route directly to another DO stub. */
|
|
56
|
-
backendFetch?: typeof fetch
|
|
57
|
-
|
|
58
|
-
/** namespace sent to the DO SQL endpoints. */
|
|
59
|
-
backendNamespace?: string
|
|
60
|
-
|
|
61
|
-
/** pre-created DoBackend instances. mainly useful for tests. */
|
|
62
|
-
backends?: {
|
|
63
|
-
postgres: DoBackend
|
|
64
|
-
cvr: DoBackend
|
|
65
|
-
cdb: DoBackend
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/** postgres username/password expected by the in-process proxy. */
|
|
69
|
-
pgUser?: string
|
|
70
|
-
pgPassword?: string
|
|
71
|
-
|
|
72
|
-
/** zero app ID (default: 'zero') */
|
|
73
|
-
appId?: string
|
|
74
|
-
|
|
75
|
-
/** publication names */
|
|
76
|
-
publications?: string[]
|
|
77
|
-
|
|
78
|
-
/** additional env vars passed to zero-cache */
|
|
79
|
-
env?: Record<string, string>
|
|
80
|
-
|
|
81
|
-
/** fetch implementation for Worker-local mutate/query API URLs. */
|
|
82
|
-
apiFetch?: typeof fetch
|
|
83
|
-
|
|
84
|
-
/** timeout in ms waiting for zero-cache ready (default: 30000) */
|
|
85
|
-
readyTimeout?: number
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export interface ZeroCacheEmbedCF {
|
|
89
|
-
/** whether zero-cache is ready */
|
|
90
|
-
readonly ready: boolean
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* handle an incoming request from the DO's fetch() handler.
|
|
94
|
-
* routes HTTP to zero-cache's Fastify handlers, WebSocket
|
|
95
|
-
* upgrades through the zero-cache handoff mechanism.
|
|
96
|
-
*/
|
|
97
|
-
handleRequest(request: Request): Promise<Response>
|
|
98
|
-
|
|
99
|
-
/** stop zero-cache */
|
|
100
|
-
stop(): Promise<void>
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* start zero-cache in embedded CF Workers mode.
|
|
105
|
-
*
|
|
106
|
-
* must be called with a DO SQLite handle for zero-cache's replica storage and
|
|
107
|
-
* a DoBackend target for upstream/CVR/change Postgres connections.
|
|
108
|
-
*/
|
|
109
|
-
export async function startZeroCacheEmbedCF(
|
|
110
|
-
opts: ZeroCacheEmbedCFOptions
|
|
111
|
-
): Promise<ZeroCacheEmbedCF> {
|
|
112
|
-
const appId = opts.appId || 'zero'
|
|
113
|
-
const publications = opts.publications?.join(',') || `orez_${appId}_public`
|
|
114
|
-
const readyTimeout = opts.readyTimeout ?? 30000
|
|
115
|
-
const pgUser = opts.pgUser || 'user'
|
|
116
|
-
const pgPassword = opts.pgPassword || ''
|
|
117
|
-
const backendUrl = opts.backendUrl || 'https://orez-do-backend.local'
|
|
118
|
-
const backendNamespace = opts.backendNamespace || appId
|
|
119
|
-
|
|
120
|
-
const backends =
|
|
121
|
-
opts.backends ??
|
|
122
|
-
({
|
|
123
|
-
postgres: new DoBackend(backendUrl, 'postgres', backendNamespace, {
|
|
124
|
-
fetch: opts.backendFetch,
|
|
125
|
-
}),
|
|
126
|
-
cvr: new DoBackend(backendUrl, 'zero_cvr', backendNamespace, {
|
|
127
|
-
fetch: opts.backendFetch,
|
|
128
|
-
}),
|
|
129
|
-
cdb: new DoBackend(backendUrl, 'zero_cdb', backendNamespace, {
|
|
130
|
-
fetch: opts.backendFetch,
|
|
131
|
-
}),
|
|
132
|
-
} satisfies NonNullable<ZeroCacheEmbedCFOptions['backends']>)
|
|
133
|
-
|
|
134
|
-
await Promise.all([
|
|
135
|
-
backends.postgres.waitReady,
|
|
136
|
-
backends.cvr.waitReady,
|
|
137
|
-
backends.cdb.waitReady,
|
|
138
|
-
])
|
|
139
|
-
|
|
140
|
-
const proxy: BrowserProxy = await createBrowserProxy(
|
|
141
|
-
{
|
|
142
|
-
postgres: backends.postgres as any,
|
|
143
|
-
cvr: backends.cvr as any,
|
|
144
|
-
cdb: backends.cdb as any,
|
|
145
|
-
postgresReplicas: [],
|
|
146
|
-
} as any,
|
|
147
|
-
{
|
|
148
|
-
pgUser,
|
|
149
|
-
pgPassword,
|
|
150
|
-
singleDb: false,
|
|
151
|
-
logLevel: opts.env?.ZERO_LOG_LEVEL || 'info',
|
|
152
|
-
}
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
// ensure globals are set for shims
|
|
156
|
-
;(globalThis as any).__orez_do_sqlite = opts.doSqlite
|
|
157
|
-
;(globalThis as any).__orez_proxy_connect = (port: MessagePort) => {
|
|
158
|
-
proxy.handleConnection(port)
|
|
159
|
-
}
|
|
160
|
-
;(globalThis as any).__orez_proxy_user = pgUser
|
|
161
|
-
;(globalThis as any).__orez_proxy_password = pgPassword
|
|
162
|
-
|
|
163
|
-
// ensure process.env exists (CF Workers doesn't have it natively)
|
|
164
|
-
;(globalThis as any).process ??= {}
|
|
165
|
-
;(globalThis as any).process.env ??= {}
|
|
166
|
-
;(globalThis as any).process.pid ??= 1
|
|
167
|
-
;(globalThis as any).process.argv ??= []
|
|
168
|
-
|
|
169
|
-
// CRITICAL: set SINGLE_PROCESS before importing zero-cache.
|
|
170
|
-
// zero-cache's childWorker() checks process.env.SINGLE_PROCESS directly.
|
|
171
|
-
;(globalThis as any).process.env.SINGLE_PROCESS = '1'
|
|
172
|
-
;(globalThis as any).process.env.NODE_ENV = 'development'
|
|
173
|
-
|
|
174
|
-
// shim process.kill (used by HeartbeatMonitor) to be a no-op
|
|
175
|
-
;(globalThis as any).process.kill ??= () => {}
|
|
176
|
-
|
|
177
|
-
// create fake parent EventEmitter for zero-cache's runWorker()
|
|
178
|
-
// must be declared before process.exit shim (which references it)
|
|
179
|
-
const parent = new EventEmitter() as EventEmitter & {
|
|
180
|
-
send: (msg: unknown) => boolean
|
|
181
|
-
kill: (signal?: string) => void
|
|
182
|
-
pid: number
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
const parentEmitter = new EventEmitter()
|
|
186
|
-
|
|
187
|
-
parent.send = (message: unknown, sendHandle?: unknown) => {
|
|
188
|
-
parentEmitter.emit('message', message, sendHandle)
|
|
189
|
-
return true
|
|
190
|
-
}
|
|
191
|
-
parent.kill = (signal = 'SIGTERM') => {
|
|
192
|
-
parent.emit(signal, signal)
|
|
193
|
-
}
|
|
194
|
-
parent.pid = (globalThis as any).process.pid ?? 1
|
|
195
|
-
|
|
196
|
-
// shim process.exit to emit on parent instead of actually exiting
|
|
197
|
-
const origExit = (globalThis as any).process.exit
|
|
198
|
-
const origNodeEnv = (globalThis as any).process.env.NODE_ENV
|
|
199
|
-
const origKill = (globalThis as any).process.kill
|
|
200
|
-
const origFetch = (globalThis as any).fetch
|
|
201
|
-
;(globalThis as any).process.exit = (code?: number) => {
|
|
202
|
-
parent.emit('exit', code ?? 0)
|
|
203
|
-
}
|
|
204
|
-
if (opts.apiFetch) {
|
|
205
|
-
;(globalThis as any).fetch = (input: RequestInfo | URL, init?: RequestInit) => {
|
|
206
|
-
const request = new Request(input, init)
|
|
207
|
-
const url = new URL(request.url)
|
|
208
|
-
if (url.hostname === 'orez-zero-api.local') return opts.apiFetch!(request)
|
|
209
|
-
return origFetch(input as any, init as any)
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// build env for zero-cache
|
|
214
|
-
const env: Record<string, string> = {
|
|
215
|
-
...((globalThis as any).process.env as Record<string, string>),
|
|
216
|
-
SINGLE_PROCESS: '1',
|
|
217
|
-
NODE_ENV: 'development',
|
|
218
|
-
// postgres-browser intercepts these URLs and routes PG wire over
|
|
219
|
-
// MessagePort to the DoBackend-backed proxy above.
|
|
220
|
-
ZERO_UPSTREAM_DB: `postgres://${pgUser}:ignored@127.0.0.1/postgres`,
|
|
221
|
-
ZERO_CVR_DB: `postgres://${pgUser}:ignored@127.0.0.1/zero_cvr`,
|
|
222
|
-
ZERO_CHANGE_DB: `postgres://${pgUser}:ignored@127.0.0.1/zero_cdb`,
|
|
223
|
-
// this path is intercepted by the sqlite shim
|
|
224
|
-
ZERO_REPLICA_FILE: ':do-sqlite:',
|
|
225
|
-
// don't bind a port — we route via inject/handoff
|
|
226
|
-
ZERO_PORT: '0',
|
|
227
|
-
ZERO_APP_ID: appId,
|
|
228
|
-
ZERO_APP_PUBLICATIONS: publications,
|
|
229
|
-
ZERO_ADMIN_PASSWORD: opts.env?.ZERO_ADMIN_PASSWORD || crypto.randomUUID(),
|
|
230
|
-
ZERO_LOG_LEVEL: opts.env?.ZERO_LOG_LEVEL || 'info',
|
|
231
|
-
ZERO_NUM_SYNC_WORKERS: opts.env?.ZERO_NUM_SYNC_WORKERS || '1',
|
|
232
|
-
ZERO_ENABLE_QUERY_PLANNER: 'false',
|
|
233
|
-
...opts.env,
|
|
234
|
-
}
|
|
235
|
-
Object.assign((globalThis as any).process.env, env)
|
|
236
|
-
|
|
237
|
-
const debugEmbed =
|
|
238
|
-
env.OREZ_DEBUG_EMBED === '1' || (globalThis as any).__OREZ_DEBUG_EMBED__ === true
|
|
239
|
-
|
|
240
|
-
// wrap parent with onMessageType/onceMessageType helpers
|
|
241
|
-
// must forward sendHandle (second arg) for WebSocket handoff
|
|
242
|
-
const wrappedParent = new Proxy(parent, {
|
|
243
|
-
get(target, prop, receiver) {
|
|
244
|
-
if (prop === 'onMessageType') {
|
|
245
|
-
return (type: string, handler: (msg: unknown, sendHandle?: unknown) => void) => {
|
|
246
|
-
target.on('message', (data: unknown, sendHandle?: unknown) => {
|
|
247
|
-
if (Array.isArray(data) && data.length === 2 && data[0] === type) {
|
|
248
|
-
handler(data[1], sendHandle)
|
|
249
|
-
}
|
|
250
|
-
})
|
|
251
|
-
return receiver
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
if (prop === 'onceMessageType') {
|
|
255
|
-
return (type: string, handler: (msg: unknown, sendHandle?: unknown) => void) => {
|
|
256
|
-
const listener = (data: unknown, sendHandle?: unknown) => {
|
|
257
|
-
if (Array.isArray(data) && data.length === 2 && data[0] === type) {
|
|
258
|
-
target.off('message', listener)
|
|
259
|
-
handler(data[1], sendHandle)
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
target.on('message', listener)
|
|
263
|
-
return receiver
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
return Reflect.get(target, prop, receiver)
|
|
267
|
-
},
|
|
268
|
-
})
|
|
269
|
-
|
|
270
|
-
// track state
|
|
271
|
-
let isReady = false
|
|
272
|
-
let runWorkerPromise: Promise<void> | null = null
|
|
273
|
-
|
|
274
|
-
// capture the Fastify shim instance from zero-cache's HttpService.
|
|
275
|
-
// the fastify shim stores itself on globalThis when created.
|
|
276
|
-
let fastifyInstance: any = null
|
|
277
|
-
|
|
278
|
-
// wait for "ready" message
|
|
279
|
-
const readyPromise = new Promise<void>((resolve, reject) => {
|
|
280
|
-
const timeout = setTimeout(() => {
|
|
281
|
-
reject(
|
|
282
|
-
new Error(
|
|
283
|
-
`zero-cache CF embed: timed out waiting for ready after ${readyTimeout}ms`
|
|
284
|
-
)
|
|
285
|
-
)
|
|
286
|
-
}, readyTimeout)
|
|
287
|
-
|
|
288
|
-
parentEmitter.on('message', (msg: unknown) => {
|
|
289
|
-
if (debugEmbed) console.debug('[orez-zero-cache-cf] parent message', msg)
|
|
290
|
-
if (Array.isArray(msg) && msg[0] === 'ready') {
|
|
291
|
-
clearTimeout(timeout)
|
|
292
|
-
isReady = true
|
|
293
|
-
resolve()
|
|
294
|
-
}
|
|
295
|
-
})
|
|
296
|
-
})
|
|
297
|
-
|
|
298
|
-
// start zero-cache
|
|
299
|
-
runWorkerPromise = runWorkerFn(wrappedParent, env).catch((err) => {
|
|
300
|
-
if (debugEmbed) console.error('[orez-zero-cache-cf] runWorker error', err)
|
|
301
|
-
if (!isReady) {
|
|
302
|
-
throw err
|
|
303
|
-
}
|
|
304
|
-
// after ready, errors during shutdown are expected
|
|
305
|
-
})
|
|
306
|
-
|
|
307
|
-
// wait for ready
|
|
308
|
-
await readyPromise
|
|
309
|
-
|
|
310
|
-
// get the fastify instance (set by our shim during init)
|
|
311
|
-
fastifyInstance = (globalThis as any).__orez_fastify_instance
|
|
312
|
-
|
|
313
|
-
return {
|
|
314
|
-
get ready() {
|
|
315
|
-
return isReady
|
|
316
|
-
},
|
|
317
|
-
|
|
318
|
-
async handleRequest(request: Request): Promise<Response> {
|
|
319
|
-
if (!isReady) {
|
|
320
|
-
return new Response('zero-cache not ready', { status: 503 })
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
const url = new URL(request.url)
|
|
324
|
-
const isUpgrade =
|
|
325
|
-
request.headers.get('upgrade')?.toLowerCase() === 'websocket' ||
|
|
326
|
-
request.headers.get('x-soot-ws-upgrade') === 'true'
|
|
327
|
-
|
|
328
|
-
if (isUpgrade) {
|
|
329
|
-
return handleWebSocketUpgrade(request, url, fastifyInstance)
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
return handleHttpRequest(request, url, fastifyInstance)
|
|
333
|
-
},
|
|
334
|
-
|
|
335
|
-
async stop() {
|
|
336
|
-
isReady = false
|
|
337
|
-
wrappedParent.kill('SIGTERM')
|
|
338
|
-
if (runWorkerPromise) {
|
|
339
|
-
await Promise.race([runWorkerPromise, new Promise((r) => setTimeout(r, 5000))])
|
|
340
|
-
}
|
|
341
|
-
await new Promise((r) => setTimeout(r, 200))
|
|
342
|
-
proxy.close()
|
|
343
|
-
await Promise.all([
|
|
344
|
-
backends.postgres.close(),
|
|
345
|
-
backends.cvr.close(),
|
|
346
|
-
backends.cdb.close(),
|
|
347
|
-
])
|
|
348
|
-
// restore all modified globals
|
|
349
|
-
if (origExit) {
|
|
350
|
-
;(globalThis as any).process.exit = origExit
|
|
351
|
-
}
|
|
352
|
-
if (origNodeEnv !== undefined) {
|
|
353
|
-
;(globalThis as any).process.env.NODE_ENV = origNodeEnv
|
|
354
|
-
}
|
|
355
|
-
if (origKill) {
|
|
356
|
-
;(globalThis as any).process.kill = origKill
|
|
357
|
-
}
|
|
358
|
-
if (opts.apiFetch) {
|
|
359
|
-
;(globalThis as any).fetch = origFetch
|
|
360
|
-
}
|
|
361
|
-
delete (globalThis as any).process.env.SINGLE_PROCESS
|
|
362
|
-
delete (globalThis as any).__orez_proxy_connect
|
|
363
|
-
delete (globalThis as any).__orez_proxy_user
|
|
364
|
-
delete (globalThis as any).__orez_proxy_password
|
|
365
|
-
},
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
// -- HTTP request handling --
|
|
370
|
-
// routes through the Fastify shim's inject() method
|
|
371
|
-
|
|
372
|
-
async function handleHttpRequest(
|
|
373
|
-
request: Request,
|
|
374
|
-
url: URL,
|
|
375
|
-
fastify: any
|
|
376
|
-
): Promise<Response> {
|
|
377
|
-
if (!fastify?.inject) {
|
|
378
|
-
return new Response('fastify not available', { status: 503 })
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
const headers: Record<string, string> = {}
|
|
382
|
-
request.headers.forEach((value, key) => {
|
|
383
|
-
headers[key] = value
|
|
384
|
-
})
|
|
385
|
-
|
|
386
|
-
let payload: string | null = null
|
|
387
|
-
if (request.method !== 'GET' && request.method !== 'HEAD' && request.body) {
|
|
388
|
-
payload = await request.text()
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
const result = await fastify.inject({
|
|
392
|
-
method: request.method,
|
|
393
|
-
url: url.pathname + url.search,
|
|
394
|
-
headers,
|
|
395
|
-
payload,
|
|
396
|
-
})
|
|
397
|
-
|
|
398
|
-
return new Response(result.body, {
|
|
399
|
-
status: result.statusCode,
|
|
400
|
-
headers: result.headers,
|
|
401
|
-
})
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// -- WebSocket upgrade handling --
|
|
405
|
-
// creates WebSocketPair and feeds the server socket into zero-cache's
|
|
406
|
-
// handoff mechanism via the Fastify shim's server EventEmitter.
|
|
407
|
-
|
|
408
|
-
function handleWebSocketUpgrade(request: Request, url: URL, fastify: any): Response {
|
|
409
|
-
const WsPair = (globalThis as any).WebSocketPair
|
|
410
|
-
if (!WsPair) {
|
|
411
|
-
return new Response('WebSocketPair not available', { status: 500 })
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
const pair = new WsPair()
|
|
415
|
-
const [client, server] = Object.values(pair) as [any, any]
|
|
416
|
-
|
|
417
|
-
// accept the server side (CF Workers requirement)
|
|
418
|
-
server.accept()
|
|
419
|
-
|
|
420
|
-
// build a serializable request object for the handoff
|
|
421
|
-
const headers: Record<string, string> = {}
|
|
422
|
-
request.headers.forEach((value, key) => {
|
|
423
|
-
headers[key] = value
|
|
424
|
-
})
|
|
425
|
-
|
|
426
|
-
const message = {
|
|
427
|
-
url: url.pathname + url.search,
|
|
428
|
-
headers,
|
|
429
|
-
method: 'GET',
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
// emit handoff on the Fastify server's EventEmitter.
|
|
433
|
-
// installWebSocketHandoff (non-Server branch) listens for this:
|
|
434
|
-
// source.onMessageType("handoff", (msg, socket) => { ... })
|
|
435
|
-
if (fastify?.server) {
|
|
436
|
-
fastify.server.emit(
|
|
437
|
-
'message',
|
|
438
|
-
['handoff', { message, head: new Uint8Array(0) }],
|
|
439
|
-
server // the CF WebSocket as sendHandle
|
|
440
|
-
)
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
// return 101 with client socket
|
|
444
|
-
// must echo Sec-WebSocket-Protocol — browsers reject the upgrade without it
|
|
445
|
-
const secProtocol = request.headers.get('sec-websocket-protocol')
|
|
446
|
-
const upgradeHeaders: Record<string, string> = {}
|
|
447
|
-
if (secProtocol) {
|
|
448
|
-
upgradeHeaders['Sec-WebSocket-Protocol'] = secProtocol
|
|
449
|
-
}
|
|
450
|
-
try {
|
|
451
|
-
return new Response(null, {
|
|
452
|
-
status: 101,
|
|
453
|
-
headers: upgradeHeaders,
|
|
454
|
-
// @ts-expect-error CF Workers Response extension
|
|
455
|
-
webSocket: client,
|
|
456
|
-
})
|
|
457
|
-
} catch {
|
|
458
|
-
const resp = new Response(null, { status: 200 })
|
|
459
|
-
;(resp as any).__orez_websocket = client
|
|
460
|
-
;(resp as any).__orez_ws_upgrade = true
|
|
461
|
-
return resp
|
|
462
|
-
}
|
|
463
|
-
}
|