orez 0.2.25 → 0.2.26
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/watermark.d.ts +21 -0
- package/dist/cf-do/watermark.d.ts.map +1 -0
- package/dist/cf-do/watermark.js +93 -0
- package/dist/cf-do/watermark.js.map +1 -0
- package/dist/cf-do/worker.d.ts +48 -22
- package/dist/cf-do/worker.d.ts.map +1 -1
- package/dist/cf-do/worker.js +642 -269
- package/dist/cf-do/worker.js.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/do-sql-tracking.d.ts +6 -0
- package/dist/do-sql-tracking.d.ts.map +1 -0
- package/dist/do-sql-tracking.js +14 -0
- package/dist/do-sql-tracking.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -14
- package/dist/index.js.map +1 -1
- package/dist/pg-proxy-browser.js +6 -6
- package/dist/pg-proxy-browser.js.map +1 -1
- package/dist/pg-proxy-do-backend.d.ts +96 -17
- package/dist/pg-proxy-do-backend.d.ts.map +1 -1
- package/dist/pg-proxy-do-backend.js +6033 -454
- package/dist/pg-proxy-do-backend.js.map +1 -1
- package/dist/replication/change-tracker.d.ts.map +1 -1
- package/dist/replication/change-tracker.js +18 -1
- package/dist/replication/change-tracker.js.map +1 -1
- package/dist/replication/handler.d.ts.map +1 -1
- package/dist/replication/handler.js +7 -2
- package/dist/replication/handler.js.map +1 -1
- package/dist/replication/pgoutput-encoder.d.ts.map +1 -1
- package/dist/replication/pgoutput-encoder.js +72 -30
- package/dist/replication/pgoutput-encoder.js.map +1 -1
- package/dist/worker/browser-build-config.d.ts.map +1 -1
- package/dist/worker/browser-build-config.js +2 -1
- package/dist/worker/browser-build-config.js.map +1 -1
- package/dist/worker/cf-patches.d.ts +5 -2
- package/dist/worker/cf-patches.d.ts.map +1 -1
- package/dist/worker/cf-patches.js +238 -4
- package/dist/worker/cf-patches.js.map +1 -1
- package/dist/worker/shims/node-stub.d.ts +35 -0
- package/dist/worker/shims/node-stub.d.ts.map +1 -1
- package/dist/worker/shims/node-stub.js +53 -1
- package/dist/worker/shims/node-stub.js.map +1 -1
- package/dist/worker/shims/oxfmt.d.ts +4 -0
- package/dist/worker/shims/oxfmt.d.ts.map +1 -0
- package/dist/worker/shims/oxfmt.js +4 -0
- package/dist/worker/shims/oxfmt.js.map +1 -0
- package/dist/worker/shims/postgres-socket.js +1 -1
- package/dist/worker/shims/postgres-socket.js.map +1 -1
- package/dist/worker/shims/sqlite.d.ts +1 -0
- package/dist/worker/shims/sqlite.d.ts.map +1 -1
- package/dist/worker/shims/sqlite.js +229 -9
- package/dist/worker/shims/sqlite.js.map +1 -1
- package/dist/worker/shims/ws.d.ts.map +1 -1
- package/dist/worker/shims/ws.js +45 -0
- package/dist/worker/shims/ws.js.map +1 -1
- package/dist/worker/shims/zero-process-env.d.ts +2 -0
- package/dist/worker/shims/zero-process-env.d.ts.map +1 -0
- package/dist/worker/shims/zero-process-env.js +9 -0
- package/dist/worker/shims/zero-process-env.js.map +1 -0
- package/dist/worker/zero-cache-embed-cf.d.ts +29 -12
- package/dist/worker/zero-cache-embed-cf.d.ts.map +1 -1
- package/dist/worker/zero-cache-embed-cf.js +83 -14
- package/dist/worker/zero-cache-embed-cf.js.map +1 -1
- package/package.json +6 -2
- package/src/cf-do/.wrangler/cache/cf.json +1 -0
- 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 +83 -0
- package/src/cf-do/watermark.test.ts +103 -0
- package/src/cf-do/watermark.ts +118 -0
- package/src/cf-do/worker.ts +1033 -0
- package/src/cf-do/wrangler.toml +11 -0
- package/src/config.ts +1 -1
- package/src/do-sql-tracking.test.ts +19 -0
- package/src/do-sql-tracking.ts +19 -0
- package/src/index.ts +29 -14
- package/src/pg-proxy-browser.ts +6 -6
- package/src/pg-proxy-do-backend.test.ts +3890 -0
- package/src/pg-proxy-do-backend.ts +6799 -482
- package/src/replication/change-tracker.ts +16 -1
- package/src/replication/handler.test.ts +35 -0
- package/src/replication/handler.ts +7 -2
- package/src/replication/pgoutput-encoder.test.ts +71 -2
- package/src/replication/pgoutput-encoder.ts +65 -30
- package/src/worker/browser-build-config.test.ts +12 -0
- package/src/worker/browser-build-config.ts +2 -1
- package/src/worker/cf-patches.ts +274 -4
- package/src/worker/shims/node-stub.ts +53 -1
- package/src/worker/shims/oxfmt.ts +3 -0
- package/src/worker/shims/postgres-socket.ts +1 -1
- package/src/worker/shims/sqlite.test.ts +145 -0
- package/src/worker/shims/sqlite.ts +256 -9
- package/src/worker/shims/ws.ts +45 -0
- package/src/worker/shims/zero-process-env.ts +11 -0
- package/src/worker/zero-cache-embed-cf.ts +114 -18
- package/src/query-rewrites.test.ts +0 -30
- package/src/query-rewrites.ts +0 -152
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
export interface DurableSqlResult {
|
|
2
|
+
one(): Record<string, unknown> | undefined
|
|
3
|
+
toArray(): Array<Record<string, unknown>>
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface DurableSqlStorage {
|
|
7
|
+
exec(sql: string, ...params: unknown[]): DurableSqlResult
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const WATERMARK_STATE_TABLE = '_zero_change_state'
|
|
11
|
+
|
|
12
|
+
function quoteIdent(name: string): string {
|
|
13
|
+
return `"${name.replace(/"/g, '""')}"`
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function finitePositiveNumber(value: unknown): number {
|
|
17
|
+
const number = Number(value ?? 0)
|
|
18
|
+
return Number.isFinite(number) && number > 0 ? number : 0
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class DurableWatermarkState {
|
|
22
|
+
constructor(private readonly sql: DurableSqlStorage) {}
|
|
23
|
+
|
|
24
|
+
ensureTables(): void {
|
|
25
|
+
this.sql.exec(
|
|
26
|
+
"CREATE TABLE IF NOT EXISTS _zero_changes (watermark INTEGER PRIMARY KEY AUTOINCREMENT, table_name TEXT NOT NULL, op TEXT NOT NULL CHECK (op IN ('INSERT', 'UPDATE', 'DELETE')), row_data TEXT, old_data TEXT, created_at INTEGER NOT NULL DEFAULT (unixepoch()))"
|
|
27
|
+
)
|
|
28
|
+
this.sql.exec(
|
|
29
|
+
`CREATE TABLE IF NOT EXISTS ${quoteIdent(WATERMARK_STATE_TABLE)} (id INTEGER PRIMARY KEY CHECK (id = 1), last_value INTEGER NOT NULL DEFAULT 0)`
|
|
30
|
+
)
|
|
31
|
+
this.setWatermarkState(this.watermarkState())
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
next(): number {
|
|
35
|
+
return this.current() + 1
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
mark(watermark: number): void {
|
|
39
|
+
this.setWatermarkState(watermark)
|
|
40
|
+
this.updateWatermarkSequences(watermark)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
current(): number {
|
|
44
|
+
this.ensureTables()
|
|
45
|
+
const state = this.watermarkState()
|
|
46
|
+
const row = this.sql
|
|
47
|
+
.exec('SELECT COALESCE(MAX(watermark), 0) AS watermark FROM _zero_changes')
|
|
48
|
+
.one() as { watermark?: unknown } | undefined
|
|
49
|
+
const tableWatermark = finitePositiveNumber(row?.watermark)
|
|
50
|
+
const sequenceWatermark = this.watermarkSequenceValue()
|
|
51
|
+
const watermark = Math.max(state, tableWatermark, sequenceWatermark)
|
|
52
|
+
if (watermark > state) this.setWatermarkState(watermark)
|
|
53
|
+
if (watermark > sequenceWatermark) this.updateWatermarkSequences(watermark)
|
|
54
|
+
return watermark
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private watermarkState(): number {
|
|
58
|
+
try {
|
|
59
|
+
const table = quoteIdent(WATERMARK_STATE_TABLE)
|
|
60
|
+
const row = this.sql.exec(`SELECT last_value FROM ${table} WHERE id = 1`).one() as
|
|
61
|
+
| { last_value?: unknown }
|
|
62
|
+
| undefined
|
|
63
|
+
return finitePositiveNumber(row?.last_value)
|
|
64
|
+
} catch {
|
|
65
|
+
return 0
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private setWatermarkState(watermark: number): void {
|
|
70
|
+
const table = quoteIdent(WATERMARK_STATE_TABLE)
|
|
71
|
+
this.sql.exec(`INSERT OR IGNORE INTO ${table} (id, last_value) VALUES (1, 0)`)
|
|
72
|
+
this.sql.exec(`UPDATE ${table} SET last_value = ? WHERE id = 1`, watermark)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private watermarkSequenceValue(): number {
|
|
76
|
+
let watermark = 0
|
|
77
|
+
for (const name of this.watermarkSequenceTables()) {
|
|
78
|
+
try {
|
|
79
|
+
const row = this.sql
|
|
80
|
+
.exec(`SELECT last_value, is_called FROM ${quoteIdent(name)} WHERE dummy = 1`)
|
|
81
|
+
.one() as { last_value?: unknown; is_called?: unknown } | undefined
|
|
82
|
+
if (!row || !row.is_called) continue
|
|
83
|
+
watermark = Math.max(watermark, finitePositiveNumber(row.last_value))
|
|
84
|
+
} catch {
|
|
85
|
+
/* not an orez sequence table */
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return watermark
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private watermarkSequenceTables(): string[] {
|
|
92
|
+
return this.sql
|
|
93
|
+
.exec(
|
|
94
|
+
"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '%zero_watermark%'"
|
|
95
|
+
)
|
|
96
|
+
.toArray()
|
|
97
|
+
.map((row) => String(row.name || ''))
|
|
98
|
+
.filter(Boolean)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private updateWatermarkSequences(watermark: number): void {
|
|
102
|
+
for (const name of this.watermarkSequenceTables()) {
|
|
103
|
+
const table = quoteIdent(name)
|
|
104
|
+
try {
|
|
105
|
+
this.sql.exec(
|
|
106
|
+
`INSERT OR IGNORE INTO ${table} (dummy, last_value, is_called) VALUES (1, ?, 1)`,
|
|
107
|
+
watermark
|
|
108
|
+
)
|
|
109
|
+
this.sql.exec(
|
|
110
|
+
`UPDATE ${table} SET last_value = ?, is_called = 1 WHERE dummy = 1`,
|
|
111
|
+
watermark
|
|
112
|
+
)
|
|
113
|
+
} catch {
|
|
114
|
+
/* not an orez sequence table */
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|