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.
Files changed (172) hide show
  1. package/dist/cf-do/worker.d.ts.map +1 -1
  2. package/dist/cf-do/worker.js +9 -1
  3. package/dist/cf-do/worker.js.map +1 -1
  4. package/dist/pg-proxy-do-backend.d.ts +2 -0
  5. package/dist/pg-proxy-do-backend.d.ts.map +1 -1
  6. package/dist/pg-proxy-do-backend.js +49 -7
  7. package/dist/pg-proxy-do-backend.js.map +1 -1
  8. package/dist/pg-sqlite-compiler/catalog/seed.d.ts +67 -0
  9. package/dist/pg-sqlite-compiler/catalog/seed.d.ts.map +1 -0
  10. package/dist/pg-sqlite-compiler/catalog/seed.js +436 -0
  11. package/dist/pg-sqlite-compiler/catalog/seed.js.map +1 -0
  12. package/dist/pg-sqlite-compiler/index.d.ts +12 -0
  13. package/dist/pg-sqlite-compiler/index.d.ts.map +1 -0
  14. package/dist/pg-sqlite-compiler/index.js +59 -0
  15. package/dist/pg-sqlite-compiler/index.js.map +1 -0
  16. package/dist/pg-sqlite-compiler/passes/ast-utils.d.ts +48 -0
  17. package/dist/pg-sqlite-compiler/passes/ast-utils.d.ts.map +1 -0
  18. package/dist/pg-sqlite-compiler/passes/ast-utils.js +93 -0
  19. package/dist/pg-sqlite-compiler/passes/ast-utils.js.map +1 -0
  20. package/dist/pg-sqlite-compiler/passes/catalog.d.ts +34 -0
  21. package/dist/pg-sqlite-compiler/passes/catalog.d.ts.map +1 -0
  22. package/dist/pg-sqlite-compiler/passes/catalog.js +30 -0
  23. package/dist/pg-sqlite-compiler/passes/catalog.js.map +1 -0
  24. package/dist/pg-sqlite-compiler/passes/datetime.d.ts +21 -0
  25. package/dist/pg-sqlite-compiler/passes/datetime.d.ts.map +1 -0
  26. package/dist/pg-sqlite-compiler/passes/datetime.js +53 -0
  27. package/dist/pg-sqlite-compiler/passes/datetime.js.map +1 -0
  28. package/dist/pg-sqlite-compiler/passes/index.d.ts +21 -0
  29. package/dist/pg-sqlite-compiler/passes/index.d.ts.map +1 -0
  30. package/dist/pg-sqlite-compiler/passes/index.js +39 -0
  31. package/dist/pg-sqlite-compiler/passes/index.js.map +1 -0
  32. package/dist/pg-sqlite-compiler/passes/types.d.ts +41 -0
  33. package/dist/pg-sqlite-compiler/passes/types.d.ts.map +1 -0
  34. package/dist/pg-sqlite-compiler/passes/types.js +103 -0
  35. package/dist/pg-sqlite-compiler/passes/types.js.map +1 -0
  36. package/dist/pg-sqlite-compiler/test/oracle.d.ts +34 -0
  37. package/dist/pg-sqlite-compiler/test/oracle.d.ts.map +1 -0
  38. package/dist/pg-sqlite-compiler/test/oracle.js +204 -0
  39. package/dist/pg-sqlite-compiler/test/oracle.js.map +1 -0
  40. package/dist/pg-sqlite-compiler/types.d.ts +55 -0
  41. package/dist/pg-sqlite-compiler/types.d.ts.map +1 -0
  42. package/dist/pg-sqlite-compiler/types.js +2 -0
  43. package/dist/pg-sqlite-compiler/types.js.map +1 -0
  44. package/package.json +8 -4
  45. package/src/admin/admin-data.test.ts +0 -348
  46. package/src/admin/http-proxy.ts +0 -252
  47. package/src/admin/log-store.ts +0 -192
  48. package/src/admin/server.ts +0 -471
  49. package/src/admin/ui.ts +0 -1322
  50. package/src/bench/proxy-throughput.bench.ts +0 -343
  51. package/src/bench/serial-mutations.bench.ts +0 -270
  52. package/src/browser.ts +0 -203
  53. package/src/cf-do/.wrangler/cache/cf.json +0 -1
  54. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
  55. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
  56. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
  57. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/0f0f3bdf0abda097eb6f1246db4657d9fc622081362d894d82c1a1ce067b05b6.sqlite +0 -0
  58. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/1ddd3a4a48a11b51658444f5458a1fb175194b1d5b6a5bda20ef3fe3205b900c.sqlite +0 -0
  59. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/204a39120310d37e972c5914cfd71ad55c151bdb9e8ed289a5f8c5b052dd60e4.sqlite +0 -0
  60. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/3835f242df9728adba3d127a238793fd054ed3e51df3f60749ee744c469bf2a2.sqlite +0 -0
  61. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/4aa9c80eb716cf55b8995ccf7afab0b36c683e6da07d7c37a3f9c570136036df.sqlite +0 -0
  62. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/533e2fd1d6ea46e7a9a0017916ef341802d438d72583462755f2c1f8225e9bf2.sqlite +0 -0
  63. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/5ffa1aced1225ecaeac6366f7586aa3de92761cdff8711d81fbd81f248076abd.sqlite +0 -0
  64. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/686c3a9f0d7e59ed2ab607efd4b76d779c97cafeb3818380033bf7c7eb86c819.sqlite +0 -0
  65. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/6e8214e8dcfadd0deb52d64e5e9ca85c6b329ace11193909845995396914c473.sqlite +0 -0
  66. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/78d9ec9ff873d3fe3507ff53c2a6f6dfc408b4268eb0db3f2a146c0678965366.sqlite +0 -0
  67. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/7eff9f0ed7e27ad0d3f9d923de0682fab1928591172c1ba336c5f79a134a5d85.sqlite +0 -0
  68. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/836cda5b995b25867d722ed4f4c2292167e80351a3c6038db626648eb247dd8b.sqlite +0 -0
  69. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/91ef63b112209ab30172763acd8a0935106c248f7f1bcae5545ce37a9f201551.sqlite +0 -0
  70. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/a66ea4293a5f5938bc6d116edfa2522bb85bc37aea3541fbc09c3b613b9b32c0.sqlite +0 -0
  71. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/ceb2ab26b80590840b65651deb6e948d3bf81565c6751f3a58752cf4bf4aecae.sqlite +0 -0
  72. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite +0 -0
  73. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-shm +0 -0
  74. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-wal +0 -0
  75. package/src/cf-do/ARCHITECTURE.md +0 -83
  76. package/src/cf-do/watermark.test.ts +0 -103
  77. package/src/cf-do/watermark.ts +0 -118
  78. package/src/cf-do/worker.ts +0 -1033
  79. package/src/cf-do/wrangler.toml +0 -11
  80. package/src/cf-pglite/README.md +0 -19
  81. package/src/change-tracking.ts +0 -25
  82. package/src/child-process.test.ts +0 -147
  83. package/src/child-process.ts +0 -90
  84. package/src/cli-entry.ts +0 -72
  85. package/src/cli.test.ts +0 -38
  86. package/src/cli.ts +0 -1214
  87. package/src/config.ts +0 -150
  88. package/src/do-sql-tracking.test.ts +0 -19
  89. package/src/do-sql-tracking.ts +0 -19
  90. package/src/index.ts +0 -1215
  91. package/src/integration/integration.test.ts +0 -517
  92. package/src/integration/native-binary.guard.test.ts +0 -13
  93. package/src/integration/native-startup.test.ts +0 -44
  94. package/src/integration/replication-latency.test.ts +0 -428
  95. package/src/integration/restore-live-stress.test.ts +0 -433
  96. package/src/integration/restore-reset.test.ts +0 -400
  97. package/src/integration/restore.test.ts +0 -274
  98. package/src/integration/test-permissions.ts +0 -147
  99. package/src/load-config.ts +0 -46
  100. package/src/log.ts +0 -96
  101. package/src/mutex.ts +0 -47
  102. package/src/pg-proxy-browser.singledb.test.ts +0 -233
  103. package/src/pg-proxy-browser.ts +0 -2022
  104. package/src/pg-proxy-do-backend.test.ts +0 -3890
  105. package/src/pg-proxy-do-backend.ts +0 -7157
  106. package/src/pg-proxy.ts +0 -1087
  107. package/src/pglite-ipc.test.ts +0 -116
  108. package/src/pglite-ipc.ts +0 -266
  109. package/src/pglite-manager.ts +0 -557
  110. package/src/pglite-web-proxy.test.ts +0 -57
  111. package/src/pglite-web-proxy.ts +0 -221
  112. package/src/pglite-web-worker.ts +0 -152
  113. package/src/pglite-worker-thread.ts +0 -253
  114. package/src/port.ts +0 -25
  115. package/src/process-title.ts +0 -9
  116. package/src/recovery.ts +0 -155
  117. package/src/replication/change-tracker.test.ts +0 -357
  118. package/src/replication/change-tracker.ts +0 -279
  119. package/src/replication/handler.test.ts +0 -511
  120. package/src/replication/handler.ts +0 -1190
  121. package/src/replication/pgoutput-encoder.test.ts +0 -697
  122. package/src/replication/pgoutput-encoder.ts +0 -373
  123. package/src/replication/tcp-replication.test.ts +0 -876
  124. package/src/replication/zero-compat.test.ts +0 -1150
  125. package/src/restore-stress.test.ts +0 -188
  126. package/src/s3-local.ts +0 -203
  127. package/src/shim/hooks.mjs +0 -120
  128. package/src/shim/register.mjs +0 -4
  129. package/src/sqlite-mode/apply-mode.ts +0 -224
  130. package/src/sqlite-mode/index.ts +0 -15
  131. package/src/sqlite-mode/native-binary.ts +0 -89
  132. package/src/sqlite-mode/package-resolve.ts +0 -17
  133. package/src/sqlite-mode/resolve-mode.ts +0 -80
  134. package/src/sqlite-mode/shim-template.ts +0 -159
  135. package/src/sqlite-mode/sqlite-mode.test.ts +0 -427
  136. package/src/sqlite-mode/types.ts +0 -30
  137. package/src/vite-plugin.ts +0 -67
  138. package/src/wasm-sqlite.test.ts +0 -537
  139. package/src/worker/browser-admin.ts +0 -52
  140. package/src/worker/browser-build-config.test.ts +0 -71
  141. package/src/worker/browser-build-config.ts +0 -109
  142. package/src/worker/browser-embed-admin.test.ts +0 -75
  143. package/src/worker/browser-embed.ts +0 -345
  144. package/src/worker/cf-patches.ts +0 -384
  145. package/src/worker/embed-integration.test.ts +0 -321
  146. package/src/worker/index.ts +0 -138
  147. package/src/worker/shims/fastify.test.ts +0 -255
  148. package/src/worker/shims/fastify.ts +0 -306
  149. package/src/worker/shims/http-service.test.ts +0 -355
  150. package/src/worker/shims/http-service.ts +0 -293
  151. package/src/worker/shims/node-stub.ts +0 -290
  152. package/src/worker/shims/oxfmt.ts +0 -3
  153. package/src/worker/shims/postgres-browser.ts +0 -59
  154. package/src/worker/shims/postgres-socket.test.ts +0 -576
  155. package/src/worker/shims/postgres-socket.ts +0 -310
  156. package/src/worker/shims/postgres.test.ts +0 -364
  157. package/src/worker/shims/postgres.ts +0 -1454
  158. package/src/worker/shims/sqlite-browser.test.ts +0 -233
  159. package/src/worker/shims/sqlite-browser.ts +0 -175
  160. package/src/worker/shims/sqlite.test.ts +0 -786
  161. package/src/worker/shims/sqlite.ts +0 -978
  162. package/src/worker/shims/stream-browser.ts +0 -15
  163. package/src/worker/shims/ws-browser.test.ts +0 -205
  164. package/src/worker/shims/ws-browser.ts +0 -248
  165. package/src/worker/shims/ws.test.ts +0 -288
  166. package/src/worker/shims/ws.ts +0 -467
  167. package/src/worker/shims/zero-process-env.ts +0 -11
  168. package/src/worker/types.ts +0 -75
  169. package/src/worker/worker-integration.test.ts +0 -223
  170. package/src/worker/worker.test.ts +0 -136
  171. package/src/worker/zero-cache-embed-cf.ts +0 -463
  172. package/src/worker/zero-cache-embed.ts +0 -277
@@ -1,233 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
-
3
- import { createSqlJsStorage, createInMemoryStorage } from './sqlite-browser.js'
4
- import { Database, StatementRunner } from './sqlite.js'
5
-
6
- // mock sql.js Database for testing
7
- function createMockSqlJsDb() {
8
- const tables = new Map<string, { columns: string[]; rows: Record<string, unknown>[] }>()
9
- let rowsModified = 0
10
-
11
- return {
12
- run(sql: string, params?: unknown[]) {
13
- // minimal DML support for testing
14
- const upper = sql.trim().toUpperCase()
15
- if (
16
- upper.startsWith('BEGIN') ||
17
- upper.startsWith('COMMIT') ||
18
- upper.startsWith('ROLLBACK')
19
- ) {
20
- return
21
- }
22
- if (upper.startsWith('CREATE TABLE')) {
23
- const match = sql.match(/CREATE TABLE\s+(?:IF NOT EXISTS\s+)?(\w+)\s*\((.+)\)/i)
24
- if (match) {
25
- const name = match[1]
26
- const cols = match[2].split(',').map((c) => c.trim().split(/\s/)[0])
27
- if (!tables.has(name)) {
28
- tables.set(name, { columns: cols, rows: [] })
29
- }
30
- }
31
- return
32
- }
33
- if (upper.startsWith('INSERT')) {
34
- const match = sql.match(/INSERT INTO\s+(\w+)/i)
35
- if (match) {
36
- const table = tables.get(match[1])
37
- if (table && params) {
38
- const row: Record<string, unknown> = {}
39
- table.columns.forEach((col, i) => {
40
- row[col] = params[i] ?? null
41
- })
42
- table.rows.push(row)
43
- rowsModified = 1
44
- }
45
- }
46
- return
47
- }
48
- },
49
-
50
- exec(
51
- sql: string,
52
- params?: unknown[]
53
- ): Array<{ columns: string[]; values: unknown[][] }> {
54
- const upper = sql.trim().toUpperCase()
55
- if (upper.startsWith('SELECT')) {
56
- const match = sql.match(/FROM\s+(\w+)/i)
57
- if (match) {
58
- const table = tables.get(match[1])
59
- if (table) {
60
- return [
61
- {
62
- columns: table.columns,
63
- values: table.rows.map((r) => table.columns.map((c) => r[c])),
64
- },
65
- ]
66
- }
67
- }
68
- }
69
- // for non-SELECT, delegate to run
70
- this.run(sql, params)
71
- return []
72
- },
73
-
74
- prepare(sql: string) {
75
- const self = this
76
- let boundParams: unknown[] | undefined
77
- let resultIndex = 0
78
- let results: Array<{ columns: string[]; values: unknown[][] }> = []
79
- let stepped = false
80
-
81
- return {
82
- bind(params?: unknown[]) {
83
- boundParams = params
84
- // for DML (INSERT etc), just run it
85
- const upper = sql.trim().toUpperCase()
86
- if (
87
- upper.startsWith('INSERT') ||
88
- upper.startsWith('CREATE') ||
89
- upper.startsWith('BEGIN') ||
90
- upper.startsWith('COMMIT') ||
91
- upper.startsWith('ROLLBACK')
92
- ) {
93
- self.run(sql, params)
94
- results = []
95
- } else {
96
- results = self.exec(sql, params)
97
- }
98
- resultIndex = 0
99
- stepped = false
100
- return true
101
- },
102
- step() {
103
- if (!stepped && !results.length) {
104
- results = self.exec(sql, boundParams)
105
- stepped = true
106
- }
107
- if (results.length === 0 || results[0].values.length <= resultIndex) {
108
- return false
109
- }
110
- return true
111
- },
112
- getAsObject() {
113
- const r = results[0]
114
- if (!r || resultIndex >= r.values.length) return {}
115
- const row: Record<string, unknown> = {}
116
- r.columns.forEach((col, i) => {
117
- row[col] = r.values[resultIndex][i]
118
- })
119
- resultIndex++
120
- return row
121
- },
122
- getColumnNames() {
123
- return results[0]?.columns || []
124
- },
125
- free() {
126
- return true
127
- },
128
- reset() {
129
- resultIndex = 0
130
- },
131
- }
132
- },
133
-
134
- getRowsModified() {
135
- return rowsModified
136
- },
137
-
138
- close() {},
139
- }
140
- }
141
-
142
- describe('createSqlJsStorage', () => {
143
- it('creates a SqlStorageLike from sql.js Database', () => {
144
- const sqlJs = createMockSqlJsDb()
145
- const storage = createSqlJsStorage(sqlJs as any)
146
- expect(storage).toBeDefined()
147
- expect(storage.exec).toBeInstanceOf(Function)
148
- })
149
-
150
- it('exec runs queries and returns cursor', () => {
151
- const sqlJs = createMockSqlJsDb()
152
- const storage = createSqlJsStorage(sqlJs as any)
153
-
154
- // insert directly via run (not through storage) to set up test data
155
- sqlJs.run('CREATE TABLE test (id, name)')
156
- sqlJs.run('INSERT INTO test VALUES (?, ?)', [1, 'hello'])
157
-
158
- const cursor = storage.exec('SELECT * FROM test')
159
- const rows = cursor.toArray()
160
- expect(rows.length).toBe(1)
161
- expect(rows[0]).toHaveProperty('id')
162
- expect(rows[0]).toHaveProperty('name')
163
- })
164
-
165
- it('transactionSync wraps in BEGIN/COMMIT', () => {
166
- const sqlJs = createMockSqlJsDb()
167
- const storage = createSqlJsStorage(sqlJs as any)
168
-
169
- sqlJs.run('CREATE TABLE t (v)')
170
-
171
- storage.transactionSync!(() => {
172
- sqlJs.run('INSERT INTO t VALUES (?)', [42])
173
- })
174
-
175
- const cursor = storage.exec('SELECT * FROM t')
176
- expect(cursor.toArray().length).toBe(1)
177
- })
178
-
179
- it('transactionSync rolls back on error', () => {
180
- const sqlJs = createMockSqlJsDb()
181
- const storage = createSqlJsStorage(sqlJs as any)
182
-
183
- expect(() => {
184
- storage.transactionSync!(() => {
185
- throw new Error('abort')
186
- })
187
- }).toThrow('abort')
188
- })
189
-
190
- it('works with sqlite shim Database', () => {
191
- const sqlJs = createMockSqlJsDb()
192
- const storage = createSqlJsStorage(sqlJs as any)
193
-
194
- // set on globalThis for the Database constructor
195
- const prev = (globalThis as any).__orez_do_sqlite
196
- ;(globalThis as any).__orez_do_sqlite = storage
197
- try {
198
- const db = new Database(':browser-sqlite:')
199
- expect(db.open).toBe(true)
200
- expect(db.name).toBe(':browser-sqlite:')
201
- } finally {
202
- if (prev) (globalThis as any).__orez_do_sqlite = prev
203
- else delete (globalThis as any).__orez_do_sqlite
204
- }
205
- })
206
- })
207
-
208
- describe('createInMemoryStorage', () => {
209
- it('creates a stub storage with exec', () => {
210
- const prev = (globalThis as any).__orez_sqljs_db
211
- delete (globalThis as any).__orez_sqljs_db
212
- try {
213
- const storage = createInMemoryStorage()
214
- expect(storage).toBeDefined()
215
- const cursor = storage.exec('SELECT 1')
216
- expect(cursor.toArray()).toEqual([])
217
- } finally {
218
- if (prev) (globalThis as any).__orez_sqljs_db = prev
219
- }
220
- })
221
-
222
- it('uses globalThis.__orez_sqljs_db if available', () => {
223
- const sqlJs = createMockSqlJsDb()
224
- ;(globalThis as any).__orez_sqljs_db = sqlJs
225
- try {
226
- const storage = createInMemoryStorage()
227
- // just verify it uses the sqlJs db (not the stub)
228
- expect(storage.transactionSync).toBeInstanceOf(Function)
229
- } finally {
230
- delete (globalThis as any).__orez_sqljs_db
231
- }
232
- })
233
- })
@@ -1,175 +0,0 @@
1
- /**
2
- * sql.js adapter for the sqlite shim.
3
- *
4
- * wraps a sql.js Database instance to implement the SqlStorageLike
5
- * interface that the existing sqlite shim expects. this lets zero-cache
6
- * use sql.js (SQLite compiled to WASM) in browser Web Workers.
7
- *
8
- * usage:
9
- * import initSqlJs from 'sql.js'
10
- * import { createSqlJsStorage } from 'orez/worker/shims/sqlite-browser'
11
- *
12
- * const SQL = await initSqlJs()
13
- * const db = new SQL.Database()
14
- * const storage = createSqlJsStorage(db)
15
- * globalThis.__orez_do_sqlite = storage
16
- */
17
-
18
- import type { SqlStorageLike, SqlStorageCursor, SqlStorageValue } from './sqlite.js'
19
-
20
- // sql.js Database interface (minimal, to avoid hard dependency)
21
- interface SqlJsDatabase {
22
- run(sql: string, params?: unknown[]): void
23
- exec(
24
- sql: string,
25
- params?: unknown[]
26
- ): Array<{
27
- columns: string[]
28
- values: unknown[][]
29
- }>
30
- prepare(sql: string): SqlJsStatement
31
- getRowsModified(): number
32
- close(): void
33
- }
34
-
35
- interface SqlJsStatement {
36
- bind(params?: unknown[]): boolean
37
- step(): boolean
38
- getAsObject(params?: object): Record<string, unknown>
39
- getColumnNames(): string[]
40
- free(): boolean
41
- reset(): void
42
- }
43
-
44
- /**
45
- * create a SqlStorageLike adapter around a sql.js Database.
46
- *
47
- * the returned object can be set on `globalThis.__orez_do_sqlite`
48
- * or passed directly to the sqlite shim's Database constructor.
49
- */
50
- export function createSqlJsStorage(sqlJsDb: SqlJsDatabase): SqlStorageLike {
51
- return {
52
- exec(query: string, ...bindings: SqlStorageValue[]): SqlStorageCursor {
53
- const stmt = sqlJsDb.prepare(query)
54
- try {
55
- if (bindings.length > 0) {
56
- // named parameters: single object arg → pass object with prefixed keys to sql.js
57
- if (
58
- bindings.length === 1 &&
59
- bindings[0] !== null &&
60
- typeof bindings[0] === 'object' &&
61
- !Array.isArray(bindings[0]) &&
62
- !(bindings[0] instanceof ArrayBuffer)
63
- ) {
64
- // sql.js expects keys with $/:/@ prefix for named params
65
- // better-sqlite3 accepts keys without prefix — add @ prefix
66
- const obj = bindings[0] as Record<string, unknown>
67
- const prefixed: Record<string, unknown> = {}
68
- for (const [k, v] of Object.entries(obj)) {
69
- // add @ prefix if not already prefixed
70
- const key =
71
- k.startsWith('$') || k.startsWith(':') || k.startsWith('@') ? k : `@${k}`
72
- prefixed[key] = v
73
- }
74
- stmt.bind(prefixed as any)
75
- } else {
76
- stmt.bind(bindings as unknown[])
77
- }
78
- }
79
-
80
- const rows: Record<string, SqlStorageValue>[] = []
81
- let columnNames: string[] = []
82
-
83
- while (stmt.step()) {
84
- const row = stmt.getAsObject() as Record<string, SqlStorageValue>
85
- if (columnNames.length === 0) {
86
- columnNames = stmt.getColumnNames()
87
- }
88
- rows.push(row)
89
- }
90
-
91
- // rowsWritten only meaningful for DML
92
- const rowsWritten = sqlJsDb.getRowsModified()
93
-
94
- return {
95
- toArray: () => rows,
96
- rowsRead: rows.length,
97
- rowsWritten,
98
- columnNames,
99
- }
100
- } finally {
101
- stmt.free()
102
- }
103
- },
104
-
105
- // sql.js transaction handling with nested transaction support
106
- transactionSync<T>(fn: () => T): T {
107
- // check if already in a transaction by trying BEGIN
108
- let inTransaction = false
109
- try {
110
- sqlJsDb.run('BEGIN')
111
- } catch {
112
- // already in a transaction — use savepoint instead
113
- inTransaction = true
114
- }
115
-
116
- if (inTransaction) {
117
- const sp = `sp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
118
- sqlJsDb.run(`SAVEPOINT "${sp}"`)
119
- try {
120
- const result = fn()
121
- sqlJsDb.run(`RELEASE SAVEPOINT "${sp}"`)
122
- return result
123
- } catch (err) {
124
- try {
125
- sqlJsDb.run(`ROLLBACK TO SAVEPOINT "${sp}"`)
126
- } catch {}
127
- throw err
128
- }
129
- }
130
-
131
- try {
132
- const result = fn()
133
- sqlJsDb.run('COMMIT')
134
- return result
135
- } catch (err) {
136
- try {
137
- sqlJsDb.run('ROLLBACK')
138
- } catch {}
139
- throw err
140
- }
141
- },
142
- }
143
- }
144
-
145
- /**
146
- * create an in-memory sql.js-like storage for environments where
147
- * sql.js isn't available. uses a minimal Map-based implementation
148
- * that handles basic CREATE TABLE / INSERT / SELECT / UPDATE / DELETE.
149
- *
150
- * NOTE: this is a very limited stub. for production use, prefer
151
- * a real sql.js instance. this stub exists so the browser embed
152
- * can start without sql.js for basic testing.
153
- */
154
- export function createInMemoryStorage(): SqlStorageLike {
155
- // use sql.js if available on globalThis (consumer may have loaded it)
156
- const sqlJsDb = (globalThis as any).__orez_sqljs_db
157
- if (sqlJsDb) {
158
- return createSqlJsStorage(sqlJsDb)
159
- }
160
-
161
- // minimal stub — zero-cache's schema migrations will likely fail
162
- // but this allows the embed to start for basic PGlite-only use cases.
163
- // note: this fires during normal init before sql.js is wired up — not an error.
164
-
165
- return {
166
- exec(_query: string, ..._bindings: SqlStorageValue[]): SqlStorageCursor {
167
- return {
168
- toArray: () => [],
169
- rowsRead: 0,
170
- rowsWritten: 0,
171
- columnNames: [],
172
- }
173
- },
174
- }
175
- }