orez 0.2.27 → 0.2.30
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 +3 -0
- package/dist/cf-do/worker.d.ts.map +1 -1
- package/dist/cf-do/worker.js +37 -15
- package/dist/cf-do/worker.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -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/0ffaabee41a60e04dd0eb7db3073f0a40139e6a97ccd26823967acb652b89a7b.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/.wrangler/tmp/bundle-0z4CpE/middleware-insertion-facade.js +0 -11
- package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-loader.entry.ts +0 -134
- package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-insertion-facade.js +0 -11
- package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-loader.entry.ts +0 -134
- package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js +0 -1059
- package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js.map +0 -8
- package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js +0 -1059
- package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js.map +0 -8
- package/src/cf-do/ARCHITECTURE.md +0 -93
- package/src/cf-do/CHAT_E2E.md +0 -213
- package/src/cf-do/watermark.test.ts +0 -103
- package/src/cf-do/watermark.ts +0 -118
- package/src/cf-do/worker.ts +0 -1041
- 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 -40
- 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 -7191
- package/src/pg-proxy.ts +0 -1087
- package/src/pg-sqlite-compiler/README.md +0 -53
- package/src/pg-sqlite-compiler/catalog/seed.ts +0 -524
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/arithmetic.json +0 -307
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/array.json +0 -377
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/cast.json +0 -12
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/catalog.json +0 -447
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/create-table.json +0 -32
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/datetime.json +0 -397
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/enum.json +0 -337
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/insert.json +0 -337
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/json.json +0 -537
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/misc.json +0 -1837
- package/src/pg-sqlite-compiler/index.ts +0 -73
- package/src/pg-sqlite-compiler/integration.test.ts +0 -136
- package/src/pg-sqlite-compiler/passes/ast-utils.ts +0 -113
- package/src/pg-sqlite-compiler/passes/catalog.ts +0 -65
- package/src/pg-sqlite-compiler/passes/datetime.ts +0 -74
- package/src/pg-sqlite-compiler/passes/index.ts +0 -49
- package/src/pg-sqlite-compiler/passes/types.ts +0 -156
- package/src/pg-sqlite-compiler/smoke.test.ts +0 -69
- package/src/pg-sqlite-compiler/test/catalog.test.ts +0 -171
- package/src/pg-sqlite-compiler/test/corpus.test.ts +0 -161
- package/src/pg-sqlite-compiler/test/datetime.oracle.test.ts +0 -102
- package/src/pg-sqlite-compiler/test/oracle.ts +0 -237
- package/src/pg-sqlite-compiler/test/types.test.ts +0 -109
- package/src/pg-sqlite-compiler/types.ts +0 -63
- 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,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
|
-
}
|