@delali/sirannon-db 0.3.5-next.71 → 0.3.5-next.72

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 (34) hide show
  1. package/dist/backup-scheduler/index.mjs +2 -2
  2. package/dist/{chunk-IWS4PJIO.mjs → chunk-AHCMO4YL.mjs} +18 -9
  3. package/dist/{chunk-YRNLEOSU.mjs → chunk-AP4367HK.mjs} +3 -3
  4. package/dist/{chunk-C53DPOR5.mjs → chunk-BTUD6XQO.mjs} +1 -1
  5. package/dist/{chunk-N4EXO2VH.mjs → chunk-DBN57KVR.mjs} +55 -1
  6. package/dist/{chunk-LHH4PMRV.mjs → chunk-DDIHBUEN.mjs} +82 -39
  7. package/dist/{chunk-YGFNJBF3.mjs → chunk-DKML5425.mjs} +2 -2
  8. package/dist/{chunk-NBPLGMPP.mjs → chunk-G4AG3ESO.mjs} +3 -3
  9. package/dist/{chunk-54MAOILS.mjs → chunk-ISDT4RBD.mjs} +1 -1
  10. package/dist/{chunk-EUNHTFR7.mjs → chunk-JFVEGN7J.mjs} +2 -2
  11. package/dist/{chunk-56HOLQKD.mjs → chunk-RPWBYASV.mjs} +1 -1
  12. package/dist/{chunk-UGGWPZIP.mjs → chunk-SB3MIFLG.mjs} +2 -2
  13. package/dist/{chunk-LRUC2GSU.mjs → chunk-UHUDPQFI.mjs} +1 -1
  14. package/dist/{chunk-RASMCXBN.mjs → chunk-WXPAWGTE.mjs} +49 -7
  15. package/dist/client/index.d.ts +3 -3
  16. package/dist/client/index.mjs +2 -2
  17. package/dist/client/topology.d.ts +1 -1
  18. package/dist/client/topology.mjs +1 -1
  19. package/dist/{client-base-CCY9go0g.d.ts → client-base-Doaqwrx3.d.ts} +14 -0
  20. package/dist/core/index.d.ts +3 -3
  21. package/dist/core/index.mjs +38 -13
  22. package/dist/core/writer-worker.mjs +3 -3
  23. package/dist/{database-D4oNUy_2.d.ts → database-fz-8CJBP.d.ts} +10 -1
  24. package/dist/driver/better-sqlite3.mjs +4 -4
  25. package/dist/driver/bun.mjs +2 -1
  26. package/dist/driver/expo.mjs +2 -1
  27. package/dist/driver/node.mjs +68 -11
  28. package/dist/driver/wa-sqlite.mjs +55 -0
  29. package/dist/replication/index.d.ts +1 -1
  30. package/dist/replication/index.mjs +7 -7
  31. package/dist/server/index.d.ts +2 -2
  32. package/dist/server/index.mjs +17 -9
  33. package/dist/{sirannon-B6sPKDye.d.ts → sirannon-D0CjDULa.d.ts} +1 -1
  34. package/package.json +9 -9
@@ -1,6 +1,6 @@
1
- export { BackupScheduler } from '../chunk-C53DPOR5.mjs';
1
+ export { BackupScheduler } from '../chunk-BTUD6XQO.mjs';
2
2
  import '../chunk-W67A4H2E.mjs';
3
- import '../chunk-IWS4PJIO.mjs';
3
+ import '../chunk-AHCMO4YL.mjs';
4
4
  import '../chunk-BUWJH3D3.mjs';
5
5
  import '../chunk-BGJ5JVYL.mjs';
6
6
  import '../chunk-HO2XTXVX.mjs';
@@ -3,6 +3,7 @@ import { SirannonError } from './chunk-KINDFBQP.mjs';
3
3
  import { open } from 'fs/promises';
4
4
 
5
5
  var READ_CHUNK_BYTES = 4 * 1024 * 1024;
6
+ var LOG_POSITION_READ_ATTEMPTS = 5;
6
7
  async function openForReading(path) {
7
8
  try {
8
9
  return await open(path, "r");
@@ -120,19 +121,27 @@ function logPathFor(sourcePath) {
120
121
  async function readLogPosition(sourcePath) {
121
122
  const logPath = logPathFor(sourcePath);
122
123
  try {
123
- const header = await readLogFileHeader(logPath);
124
- if (!header) return void 0;
125
- const scan = await scanLogFrames(logPath, header, { frame: 0, checksum: header.checksum });
126
- return {
127
- logSequence: header.logSequence,
128
- salt1: header.salt1,
129
- salt2: header.salt2,
130
- lastFrame: scan.lastCommitFrame
131
- };
124
+ for (let attempt = 0; attempt < LOG_POSITION_READ_ATTEMPTS; attempt++) {
125
+ const header = await readLogFileHeader(logPath);
126
+ if (!header) return void 0;
127
+ const scan = await scanLogFrames(logPath, header, { frame: 0, checksum: header.checksum });
128
+ const headerAfterScan = await readLogFileHeader(logPath);
129
+ if (headerAfterScan === void 0 || !sameGeneration(header, headerAfterScan)) continue;
130
+ return {
131
+ logSequence: header.logSequence,
132
+ salt1: header.salt1,
133
+ salt2: header.salt2,
134
+ lastFrame: scan.lastCommitFrame
135
+ };
136
+ }
137
+ return void 0;
132
138
  } catch {
133
139
  return void 0;
134
140
  }
135
141
  }
142
+ function sameGeneration(first, second) {
143
+ return first.logSequence === second.logSequence && first.salt1 === second.salt1 && first.salt2 === second.salt2;
144
+ }
136
145
  function cursorChecksum(cursor) {
137
146
  return { first: cursor.checksum1, second: cursor.checksum2 };
138
147
  }
@@ -1,8 +1,8 @@
1
1
  import { record, string, unknown, object, optional, nullable, picklist, safeParse, summarize } from './chunk-ZFFUVYYE.mjs';
2
- import { withoutRowCounts, runWriterTransaction, queryMetered, execute, executeBatch } from './chunk-LHH4PMRV.mjs';
3
- import { HLC, ensureMetaTable, selectMetaValue, IDENTIFIER_RE, attributeChangeSeqs, validateDdlSafety, insertDdlChange, extractDroppedTable, selectMaxChangeSeq, updateChangeStampsAfterSeqSql, selectOutboundHistoryChangesSql, selectOutboundChangesSql, selectNodeChangesAfterSeqSql, prepareUpsertNewerColumnVersion, canonicaliseForChecksum, upsertMetaValue, selectMaxColumnVersionHlcForRow, selectMaxRowChangeHlc, validateIdentifier, prepareDeleteRowColumnVersions, prepareUpsertColumnVersion, selectTableExists, selectAppliedSourceSeqsInRange, selectStagedPushTail, selectStagedPushSeqsInRange, deleteStagedPushChanges, prepareInsertStagedPushChange, selectStagedPushChangesAfter, insertAppliedChangesFromStagedPush, prepareInsertAppliedChange } from './chunk-56HOLQKD.mjs';
2
+ import { withoutRowCounts, runWriterTransaction, queryMetered, execute, executeBatch } from './chunk-DDIHBUEN.mjs';
3
+ import { HLC, ensureMetaTable, selectMetaValue, IDENTIFIER_RE, attributeChangeSeqs, validateDdlSafety, insertDdlChange, extractDroppedTable, selectMaxChangeSeq, updateChangeStampsAfterSeqSql, selectOutboundHistoryChangesSql, selectOutboundChangesSql, selectNodeChangesAfterSeqSql, prepareUpsertNewerColumnVersion, canonicaliseForChecksum, upsertMetaValue, selectMaxColumnVersionHlcForRow, selectMaxRowChangeHlc, validateIdentifier, prepareDeleteRowColumnVersions, prepareUpsertColumnVersion, selectTableExists, selectAppliedSourceSeqsInRange, selectStagedPushTail, selectStagedPushSeqsInRange, deleteStagedPushChanges, prepareInsertStagedPushChange, selectStagedPushChangesAfter, insertAppliedChangesFromStagedPush, prepareInsertAppliedChange } from './chunk-RPWBYASV.mjs';
4
4
  import { BatchValidationError, ConflictError, ReplicationError } from './chunk-BLMRNSUG.mjs';
5
- import { CHANGES_TABLE, isReservedIdentifier, decodeTaggedValues, encodeTaggedValues } from './chunk-EUNHTFR7.mjs';
5
+ import { CHANGES_TABLE, isReservedIdentifier, decodeTaggedValues, encodeTaggedValues } from './chunk-JFVEGN7J.mjs';
6
6
  import { sha256Hex } from './chunk-GVCNMPOS.mjs';
7
7
  import { lateRowCountsOf } from './chunk-K43WJORM.mjs';
8
8
  import { rowCountsOf, totalRowCounts, addRowCounts } from './chunk-E2GRX4ZD.mjs';
@@ -1,5 +1,5 @@
1
1
  import { startCopyWithoutHoldingWriter } from './chunk-W67A4H2E.mjs';
2
- import { readLogPosition } from './chunk-IWS4PJIO.mjs';
2
+ import { readLogPosition } from './chunk-AHCMO4YL.mjs';
3
3
  import { reportQuietly } from './chunk-BUWJH3D3.mjs';
4
4
  import { randomHex, destinationWithDeadline, DEFAULT_DESTINATION_TIMEOUT_MS, assertDeadline, withinDeadline } from './chunk-BGJ5JVYL.mjs';
5
5
  import { invokeCallerCallback } from './chunk-HO2XTXVX.mjs';
@@ -35,6 +35,60 @@ function defineDriver(config) {
35
35
  });
36
36
  }
37
37
 
38
+ // src/core/driver/statement-text.ts
39
+ var SPACE = 32;
40
+ var TAB = 9;
41
+ var LINE_FEED = 10;
42
+ var VERTICAL_TAB = 11;
43
+ var FORM_FEED = 12;
44
+ var CARRIAGE_RETURN = 13;
45
+ var SEMICOLON = 59;
46
+ var HYPHEN = 45;
47
+ var SLASH = 47;
48
+ var ASTERISK = 42;
49
+ var NO_STATEMENT_MESSAGE = "The supplied SQL string contains no statements";
50
+ function startsSqliteSpace(code) {
51
+ return code === SPACE || code === TAB || code === LINE_FEED || code === FORM_FEED || code === CARRIAGE_RETURN;
52
+ }
53
+ function continuesSqliteSpace(code) {
54
+ return startsSqliteSpace(code) || code === VERTICAL_TAB;
55
+ }
56
+ function holdsNoStatement(sql) {
57
+ const firstNul = sql.indexOf("\0");
58
+ const text = firstNul === -1 ? sql : sql.slice(0, firstNul);
59
+ let index = 0;
60
+ while (index < text.length) {
61
+ const code = text.charCodeAt(index);
62
+ if (startsSqliteSpace(code)) {
63
+ index++;
64
+ while (index < text.length && continuesSqliteSpace(text.charCodeAt(index))) index++;
65
+ continue;
66
+ }
67
+ if (code === SEMICOLON) {
68
+ index++;
69
+ continue;
70
+ }
71
+ const next = text.charCodeAt(index + 1);
72
+ if (code === HYPHEN && next === HYPHEN) {
73
+ const lineEnd = text.indexOf("\n", index + 2);
74
+ if (lineEnd === -1) return true;
75
+ index = lineEnd;
76
+ continue;
77
+ }
78
+ if (code === SLASH && next === ASTERISK && index + 2 < text.length) {
79
+ const commentEnd = text.indexOf("*/", index + 2);
80
+ if (commentEnd === -1) return true;
81
+ index = commentEnd + 2;
82
+ continue;
83
+ }
84
+ return false;
85
+ }
86
+ return true;
87
+ }
88
+ function assertHoldsStatement(sql) {
89
+ if (holdsNoStatement(sql)) throw new RangeError(NO_STATEMENT_MESSAGE);
90
+ }
91
+
38
92
  // src/core/driver/synchronous.ts
39
93
  var DEFAULT_SYNCHRONOUS = "normal";
40
94
  var SYNCHRONOUS_PRAGMA_VALUES = {
@@ -114,4 +168,4 @@ function bindableParams(params) {
114
168
  return bound ?? params;
115
169
  }
116
170
 
117
- export { ExtensionError, SirannonError, bindableParams, defineDriver, isNamedParams, narrowRowIntegers, narrowRowsIntegers, narrowSafeBigInt, synchronousPragmaValue };
171
+ export { ExtensionError, SirannonError, assertHoldsStatement, bindableParams, defineDriver, isNamedParams, narrowRowIntegers, narrowRowsIntegers, narrowSafeBigInt, synchronousPragmaValue };
@@ -1,37 +1,63 @@
1
- import { assertSqlAllowed, encodeWireRowsInPlace } from './chunk-EUNHTFR7.mjs';
1
+ import { encodeWireRowsInPlace, assertSqlAllowed } from './chunk-JFVEGN7J.mjs';
2
2
  import { withRowCounts, rowCountsOf, allMetered, addRowCounts } from './chunk-E2GRX4ZD.mjs';
3
3
  import { SirannonError, QueryError, TransactionError } from './chunk-KINDFBQP.mjs';
4
4
 
5
- // src/core/query-executor.ts
5
+ // src/core/prepared-statements.ts
6
6
  var STATEMENT_CACHE_CAPACITY = 128;
7
7
  var statementCaches = /* @__PURE__ */ new WeakMap();
8
- async function getStatement(conn, sql) {
8
+ function cacheOf(conn) {
9
9
  let cache = statementCaches.get(conn);
10
- if (!cache) {
11
- cache = /* @__PURE__ */ new Map();
10
+ if (cache === void 0) {
11
+ cache = { entries: /* @__PURE__ */ new Map(), newest: void 0 };
12
12
  statementCaches.set(conn, cache);
13
13
  }
14
- const cached = cache.get(sql);
15
- if (cached) {
16
- cache.delete(sql);
17
- cache.set(sql, cached);
18
- return cached;
19
- }
20
- const pending = conn.prepare(sql);
21
- cache.set(sql, pending);
22
- if (cache.size > STATEMENT_CACHE_CAPACITY) {
23
- const oldest = cache.keys().next().value;
24
- if (oldest !== void 0) {
25
- cache.delete(oldest);
14
+ return cache;
15
+ }
16
+ function lookUp(cache, sql) {
17
+ const entry = cache.entries.get(sql);
18
+ if (entry === void 0 || cache.newest === sql) return entry;
19
+ cache.entries.delete(sql);
20
+ cache.entries.set(sql, entry);
21
+ cache.newest = sql;
22
+ return entry;
23
+ }
24
+ function prepareInto(cache, conn, sql) {
25
+ const entry = { pending: conn.prepare(sql), prepared: void 0, passedSqlGuard: false };
26
+ cache.entries.set(sql, entry);
27
+ cache.newest = sql;
28
+ if (cache.entries.size > STATEMENT_CACHE_CAPACITY) {
29
+ const oldest = cache.entries.keys().next().value;
30
+ if (oldest !== void 0) cache.entries.delete(oldest);
31
+ }
32
+ entry.pending.then(
33
+ (statement) => {
34
+ entry.prepared = statement;
35
+ },
36
+ () => {
37
+ if (cache.entries.get(sql) === entry) cache.entries.delete(sql);
38
+ if (cache.newest === sql) cache.newest = void 0;
26
39
  }
27
- }
28
- try {
29
- return await pending;
30
- } catch (err) {
31
- cache.delete(sql);
32
- throw err;
33
- }
40
+ );
41
+ return entry;
42
+ }
43
+ function statementOf(entry) {
44
+ return entry.prepared ?? entry.pending;
34
45
  }
46
+ function trustedStatement(conn, sql) {
47
+ const cache = cacheOf(conn);
48
+ return statementOf(lookUp(cache, sql) ?? prepareInto(cache, conn, sql));
49
+ }
50
+ function guardedStatement(conn, sql) {
51
+ const cache = cacheOf(conn);
52
+ const cached = lookUp(cache, sql);
53
+ if (cached?.passedSqlGuard) return statementOf(cached);
54
+ assertSqlAllowed(sql);
55
+ const entry = cached ?? prepareInto(cache, conn, sql);
56
+ entry.passedSqlGuard = true;
57
+ return statementOf(entry);
58
+ }
59
+
60
+ // src/core/query-executor.ts
35
61
  function bindParams(params) {
36
62
  if (params === void 0) return [];
37
63
  if (Array.isArray(params)) return params;
@@ -49,20 +75,24 @@ function metered(value, counts) {
49
75
  return counts === void 0 ? { value } : { value, rowsRead: counts.rowsRead, rowsWritten: counts.rowsWritten };
50
76
  }
51
77
  async function query(conn, sql, params) {
52
- return (await queryMetered(conn, sql, params)).value;
78
+ try {
79
+ const handle = guardedStatement(conn, sql);
80
+ const stmt = handle instanceof Promise ? await handle : handle;
81
+ return await stmt.all(...bindParams(params));
82
+ } catch (err) {
83
+ throw asQueryError(err, sql);
84
+ }
53
85
  }
54
86
  async function queryMetered(conn, sql, params) {
55
- assertSqlAllowed(sql);
56
87
  try {
57
- return await allMetered(await getStatement(conn, sql), bindParams(params));
88
+ return await allMetered(await guardedStatement(conn, sql), bindParams(params));
58
89
  } catch (err) {
59
90
  throw asQueryError(err, sql);
60
91
  }
61
92
  }
62
93
  async function queryForWire(conn, sql, params) {
63
- assertSqlAllowed(sql);
64
94
  try {
65
- const stmt = await getStatement(conn, sql);
95
+ const stmt = await guardedStatement(conn, sql);
66
96
  const bound = bindParams(params);
67
97
  const counted = stmt.allRaw ? stmt.allRawCounted : stmt.allCounted;
68
98
  if (counted) {
@@ -75,13 +105,29 @@ async function queryForWire(conn, sql, params) {
75
105
  throw asQueryError(err, sql);
76
106
  }
77
107
  }
108
+ async function queryRowsForWire(conn, sql, params) {
109
+ try {
110
+ const handle = guardedStatement(conn, sql);
111
+ const stmt = handle instanceof Promise ? await handle : handle;
112
+ const bound = bindParams(params);
113
+ const rows = stmt.allRaw ? await stmt.allRaw(...bound) : await stmt.all(...bound);
114
+ return encodeWireRowsInPlace(rows);
115
+ } catch (err) {
116
+ throw asQueryError(err, sql);
117
+ }
118
+ }
78
119
  async function queryOne(conn, sql, params) {
79
- return (await queryOneMetered(conn, sql, params)).value;
120
+ try {
121
+ const handle = guardedStatement(conn, sql);
122
+ const stmt = handle instanceof Promise ? await handle : handle;
123
+ return await stmt.get(...bindParams(params));
124
+ } catch (err) {
125
+ throw asQueryError(err, sql);
126
+ }
80
127
  }
81
128
  async function queryOneMetered(conn, sql, params) {
82
- assertSqlAllowed(sql);
83
129
  try {
84
- const stmt = await getStatement(conn, sql);
130
+ const stmt = await guardedStatement(conn, sql);
85
131
  const bound = bindParams(params);
86
132
  if (stmt.getCounted) return await stmt.getCounted(...bound);
87
133
  return { value: await stmt.get(...bound) };
@@ -90,11 +136,9 @@ async function queryOneMetered(conn, sql, params) {
90
136
  }
91
137
  }
92
138
  async function execute(conn, sql, params, trusted = false) {
93
- if (!trusted) {
94
- assertSqlAllowed(sql);
95
- }
96
139
  try {
97
- const stmt = await getStatement(conn, sql);
140
+ const handle = trusted ? trustedStatement(conn, sql) : guardedStatement(conn, sql);
141
+ const stmt = handle instanceof Promise ? await handle : handle;
98
142
  const result = await stmt.run(...bindParams(params));
99
143
  return withRowCounts({ changes: result.changes, lastInsertRowId: result.lastInsertRowId }, rowCountsOf(result));
100
144
  } catch (err) {
@@ -102,10 +146,9 @@ async function execute(conn, sql, params, trusted = false) {
102
146
  }
103
147
  }
104
148
  async function forEachBatchRow(conn, sql, paramsBatch, sink) {
105
- assertSqlAllowed(sql);
106
149
  let counts;
107
150
  try {
108
- const stmt = await getStatement(conn, sql);
151
+ const stmt = await guardedStatement(conn, sql);
109
152
  for (const params of paramsBatch) {
110
153
  const result = await stmt.run(...bindParams(params));
111
154
  counts = addRowCounts(counts, rowCountsOf(result));
@@ -194,4 +237,4 @@ async function runInSavepoint(conn, body) {
194
237
  return value;
195
238
  }
196
239
 
197
- export { asQueryError, bindParams, commitFailure, execute, executeBatch, executeBatchSummary, query, queryForWire, queryMetered, queryOne, queryOneMetered, runInSavepoint, runWriterTransaction, withoutRowCounts };
240
+ export { asQueryError, bindParams, commitFailure, execute, executeBatch, executeBatchSummary, query, queryForWire, queryMetered, queryOne, queryOneMetered, queryRowsForWire, runInSavepoint, runWriterTransaction, withoutRowCounts };
@@ -1,6 +1,6 @@
1
- import { IDENTIFIER_RE, selectCountTableRows, canonicaliseForChecksum, selectUserSchemaObjects, validateDdlSafety, selectUserTableNames, referencedTables } from './chunk-56HOLQKD.mjs';
1
+ import { IDENTIFIER_RE, selectCountTableRows, canonicaliseForChecksum, selectUserSchemaObjects, validateDdlSafety, selectUserTableNames, referencedTables } from './chunk-RPWBYASV.mjs';
2
2
  import { ReplicationError } from './chunk-BLMRNSUG.mjs';
3
- import { INTERNAL_TABLE_PREFIX } from './chunk-EUNHTFR7.mjs';
3
+ import { INTERNAL_TABLE_PREFIX } from './chunk-JFVEGN7J.mjs';
4
4
  import { createHash } from 'crypto';
5
5
 
6
6
  var DumpOps = class {
@@ -1,12 +1,12 @@
1
1
  import { verifyBackupRecord } from './chunk-DX4WGJL7.mjs';
2
- import { BackupManager, BackupScheduler, DEFAULT_PIECE_BYTES, sendFileInPieces } from './chunk-C53DPOR5.mjs';
2
+ import { BackupManager, BackupScheduler, DEFAULT_PIECE_BYTES, sendFileInPieces } from './chunk-BTUD6XQO.mjs';
3
3
  import { DEFAULT_BACKUP_NAME_PREFIX, defaultStagingDir, DEFAULT_CAPTURE_INTERVAL_MS, DEFAULT_FULL_COPY_INTERVAL_MS } from './chunk-JAQ2I4OT.mjs';
4
4
  import { withLateGroupOutcomes, withLateRowCounts } from './chunk-K43WJORM.mjs';
5
5
  import { leftTransactionUnbegun, canCarryBegin, toWorkerGroupStatement, WORKER_CANCELLED_CODE, WORKER_COPY_STOPPED_CODE, deserializeError } from './chunk-75IBRE73.mjs';
6
6
  import { rowCountsOf, totalRowCounts } from './chunk-E2GRX4ZD.mjs';
7
- import { readCycleState, writeCycleState, removeCycleState, stagedCapturePath, captureAndCheckpointTurn } from './chunk-LRUC2GSU.mjs';
7
+ import { readCycleState, writeCycleState, removeCycleState, stagedCapturePath, captureAndCheckpointTurn } from './chunk-UHUDPQFI.mjs';
8
8
  import { checkpointLog } from './chunk-QGVRRKB2.mjs';
9
- import { logPathFor } from './chunk-IWS4PJIO.mjs';
9
+ import { logPathFor } from './chunk-AHCMO4YL.mjs';
10
10
  import { reportQuietly } from './chunk-BUWJH3D3.mjs';
11
11
  import { DEFAULT_CHAIN_NAME, readBackupChains, appendChainRecord, appendChainHead, readChainHeadAt, readChainHeads } from './chunk-CZL4D3BM.mjs';
12
12
  import { destinationWithDeadline, DEFAULT_DESTINATION_TIMEOUT_MS, randomHex } from './chunk-BGJ5JVYL.mjs';
@@ -1,4 +1,4 @@
1
- import { execute, commitFailure, asQueryError } from './chunk-LHH4PMRV.mjs';
1
+ import { execute, commitFailure, asQueryError } from './chunk-DDIHBUEN.mjs';
2
2
  import { rowCountsOf } from './chunk-E2GRX4ZD.mjs';
3
3
 
4
4
  // src/core/group-executor.ts
@@ -236,8 +236,8 @@ function encodeWireRowsInPlace(rows) {
236
236
  const obj = row;
237
237
  for (const k of Object.keys(obj)) {
238
238
  const cell = obj[k];
239
- if (typeof cell === "bigint" || isBinaryValue(cell)) {
240
- obj[k] = encodeTaggedLeaf(cell);
239
+ if (typeof cell === "bigint" || typeof cell === "object" && cell !== null && isBinaryValue(cell)) {
240
+ setOwnValue(obj, k, encodeTaggedLeaf(cell));
241
241
  }
242
242
  }
243
243
  }
@@ -1,5 +1,5 @@
1
1
  import { ReplicationError, BatchValidationError } from './chunk-BLMRNSUG.mjs';
2
- import { CHANGES_TABLE, META_TABLE, MIGRATIONS_TABLE, REPLACED_ROWS_TABLE, APPLIED_CHANGES_TABLE, STAGED_PUSH_CHANGES_TABLE, COLUMN_VERSIONS_TABLE, DEVICE_CURSORS_TABLE, PEER_STATE_TABLE, SYNC_STATE_TABLE, STAGED_CHANGES_TABLE, isReservedIdentifier } from './chunk-EUNHTFR7.mjs';
2
+ import { CHANGES_TABLE, META_TABLE, MIGRATIONS_TABLE, REPLACED_ROWS_TABLE, APPLIED_CHANGES_TABLE, STAGED_PUSH_CHANGES_TABLE, COLUMN_VERSIONS_TABLE, DEVICE_CURSORS_TABLE, PEER_STATE_TABLE, SYNC_STATE_TABLE, STAGED_CHANGES_TABLE, isReservedIdentifier } from './chunk-JFVEGN7J.mjs';
3
3
  import { SirannonError } from './chunk-KINDFBQP.mjs';
4
4
 
5
5
  // src/core/sync/hlc.ts
@@ -1,5 +1,5 @@
1
- import { selectOrdinaryTableName, deleteReplacedRowsOfTable, selectMinChangeSeqSql, selectMaxChangeSeq, deleteChangesBeforeUpToSeqSql, deleteAllReplacedRows, selectTableExists, ensureChangesTable, ensureReplacedRowsTable, ensureMetaTable, insertMetaValueIfAbsent, selectMetaValue, selectTriggerSql, selectChangesAfterSeqSql, selectTablesChangesInRangeSql, tableInfoRows, primaryKeyColumns, tableColumnsWithGenerated, tableIndexList, indexColumns, selectTableSql, TABLE_XINFO_HIDDEN, deleteExpiredDeviceCursors, selectMinDeviceCursorBoundary, SEQ_STRING_RE, selectIndexSql } from './chunk-56HOLQKD.mjs';
2
- import { CDC_TRIGGER_PREFIX, CHANGES_TABLE, isReservedIdentifier, META_TABLE, encodeTaggedValues, REPLACED_ROWS_TABLE, changedAtToEventTimestamp, decodeTaggedValues, DEVICE_CURSORS_TABLE, SAFE_INT_BOUND_TEXT } from './chunk-EUNHTFR7.mjs';
1
+ import { selectOrdinaryTableName, deleteReplacedRowsOfTable, selectMinChangeSeqSql, selectMaxChangeSeq, deleteChangesBeforeUpToSeqSql, deleteAllReplacedRows, selectTableExists, ensureChangesTable, ensureReplacedRowsTable, ensureMetaTable, insertMetaValueIfAbsent, selectMetaValue, selectTriggerSql, selectChangesAfterSeqSql, selectTablesChangesInRangeSql, tableInfoRows, primaryKeyColumns, tableColumnsWithGenerated, tableIndexList, indexColumns, selectTableSql, TABLE_XINFO_HIDDEN, deleteExpiredDeviceCursors, selectMinDeviceCursorBoundary, SEQ_STRING_RE, selectIndexSql } from './chunk-RPWBYASV.mjs';
2
+ import { CDC_TRIGGER_PREFIX, CHANGES_TABLE, isReservedIdentifier, META_TABLE, encodeTaggedValues, REPLACED_ROWS_TABLE, changedAtToEventTimestamp, decodeTaggedValues, DEVICE_CURSORS_TABLE, SAFE_INT_BOUND_TEXT } from './chunk-JFVEGN7J.mjs';
3
3
  import { tokenizeSql, isKeyword } from './chunk-SEL4A4WT.mjs';
4
4
  import { synchronousPragmaValue } from './chunk-YCMB6GR4.mjs';
5
5
  import { randomHex } from './chunk-BGJ5JVYL.mjs';
@@ -1,5 +1,5 @@
1
1
  import { checkpointLog } from './chunk-QGVRRKB2.mjs';
2
- import { readLogFileHeader, sameLog, cursorChecksum, scanLogFrames, copyLogRange } from './chunk-IWS4PJIO.mjs';
2
+ import { readLogFileHeader, sameLog, cursorChecksum, scanLogFrames, copyLogRange } from './chunk-AHCMO4YL.mjs';
3
3
  import { logFrameOffset } from './chunk-BUWJH3D3.mjs';
4
4
  import { isBackupChainPosition } from './chunk-CZL4D3BM.mjs';
5
5
  import { randomHex } from './chunk-BGJ5JVYL.mjs';
@@ -158,6 +158,7 @@ var RemoteSubscriptionBuilderImpl = class {
158
158
  // src/client/database-proxy.ts
159
159
  var DEFAULT_LOAD_BATCH_SIZE = 1e3;
160
160
  var READ_CONCERN_UNSUPPORTED_MESSAGE = "This transport does not carry a per-read concern to the server. Use the HTTP transport for a per-call readConcern, or set the client-wide readConcern that topology routing applies when choosing a node.";
161
+ var SQL_ACCEPTED = Promise.resolve();
161
162
  function closedDatabaseError() {
162
163
  return new RemoteError("TRANSPORT_ERROR", "Transport is closed");
163
164
  }
@@ -189,6 +190,7 @@ var RemoteDatabase = class {
189
190
  assertSqlAccepted() {
190
191
  const closed = this.lifetime.signal;
191
192
  if (closed.aborted) return Promise.reject(closedDatabaseError());
193
+ if (this.capabilities.knownToAcceptSql?.() === true) return SQL_ACCEPTED;
192
194
  return new Promise((resolve, reject) => {
193
195
  const refuse = () => reject(closedDatabaseError());
194
196
  closed.addEventListener("abort", refuse, { once: true });
@@ -525,6 +527,27 @@ function decodeTaggedValues(value) {
525
527
  }
526
528
  return out;
527
529
  }
530
+ function decodeWireRowsInPlace(rows) {
531
+ if (!Array.isArray(rows)) return decodeTaggedValues(rows);
532
+ for (let i = 0; i < rows.length; i++) {
533
+ const row = rows[i];
534
+ if (row === null || typeof row !== "object" || Array.isArray(row)) {
535
+ rows[i] = decodeTaggedValues(row);
536
+ continue;
537
+ }
538
+ const obj = row;
539
+ const keys = Object.keys(obj);
540
+ if (keys.length === 1 && (keys[0] === BLOB_TAG || keys[0] === INT_TAG)) {
541
+ rows[i] = decodeTaggedValues(row);
542
+ continue;
543
+ }
544
+ for (const k of keys) {
545
+ const cell = obj[k];
546
+ if (cell !== null && typeof cell === "object") setOwnValue(obj, k, decodeTaggedValues(cell));
547
+ }
548
+ }
549
+ return rows;
550
+ }
528
551
  function isBinaryValue(value) {
529
552
  return value instanceof Uint8Array || typeof Buffer !== "undefined" && Buffer.isBuffer(value);
530
553
  }
@@ -629,11 +652,22 @@ var ServerCapabilities = class {
629
652
  this.requestTimeoutMs = requestTimeoutMs;
630
653
  }
631
654
  pending = null;
655
+ acceptsSql = false;
632
656
  lifetime = new AbortController();
633
657
  /** Cancels the capability request in flight and fails every later check with `TRANSPORT_ERROR`. */
634
658
  close() {
635
659
  this.lifetime.abort();
636
660
  this.pending = null;
661
+ this.acceptsSql = false;
662
+ }
663
+ /**
664
+ * Returns whether the report that the client last read announces SQL, which stays `false` while a report is in
665
+ * flight and after the client closes.
666
+ *
667
+ * @returns `true` when a statement can skip waiting on {@link ServerCapabilities.assertSqlAccepted}.
668
+ */
669
+ knownToAcceptSql() {
670
+ return this.acceptsSql && !this.lifetime.signal.aborted;
637
671
  }
638
672
  async read(refresh = false) {
639
673
  if (this.lifetime.signal.aborted) throw new RemoteError("TRANSPORT_ERROR", "Transport is closed");
@@ -641,9 +675,17 @@ var ServerCapabilities = class {
641
675
  if (this.pending === null) {
642
676
  const request = this.fetch();
643
677
  this.pending = request;
644
- request.catch((err) => {
645
- if (this.pending === request && !isMissingEndpoint(err)) this.pending = null;
646
- });
678
+ this.acceptsSql = false;
679
+ request.then(
680
+ (report) => {
681
+ if (this.pending === request) this.acceptsSql = report.capabilities.includes(SQL_QUERY_CAPABILITY);
682
+ },
683
+ (err) => {
684
+ if (this.pending !== request) return;
685
+ if (isMissingEndpoint(err)) this.acceptsSql = true;
686
+ else this.pending = null;
687
+ }
688
+ );
647
689
  }
648
690
  return this.pending;
649
691
  }
@@ -703,7 +745,7 @@ var HttpTransport = class {
703
745
  params: encodeTaggedValues(params),
704
746
  readConcern
705
747
  });
706
- return { rows: decodeTaggedValues(response.rows ?? []) };
748
+ return { rows: decodeWireRowsInPlace(response.rows ?? []) };
707
749
  }
708
750
  /** Sends one write. */
709
751
  async execute(sql, params) {
@@ -738,7 +780,7 @@ var HttpTransport = class {
738
780
  args: encodeTaggedValues(args),
739
781
  readConcern
740
782
  });
741
- return { rows: decodeTaggedValues(response.rows ?? []) };
783
+ return { rows: decodeWireRowsInPlace(response.rows ?? []) };
742
784
  }
743
785
  /** Executes a registered write by name. */
744
786
  async executeNamed(name, args, writeConcern) {
@@ -1403,7 +1445,7 @@ var WebSocketTransport = class {
1403
1445
  async query(sql, params, readConcern) {
1404
1446
  await this.ensureConnected();
1405
1447
  const response = await this.request(queryFrame(this.nextId(), sql, params, readConcern));
1406
- return { rows: decodeTaggedValues(response.rows ?? []) };
1448
+ return { rows: decodeWireRowsInPlace(response.rows ?? []) };
1407
1449
  }
1408
1450
  /** Sends one write. */
1409
1451
  async execute(sql, params) {
@@ -1429,7 +1471,7 @@ var WebSocketTransport = class {
1429
1471
  async queryNamed(name, args, readConcern) {
1430
1472
  await this.ensureConnected();
1431
1473
  const response = await this.request(namedQueryFrame(this.nextId(), name, args, readConcern));
1432
- return { rows: decodeTaggedValues(response.rows ?? []) };
1474
+ return { rows: decodeWireRowsInPlace(response.rows ?? []) };
1433
1475
  }
1434
1476
  /** Executes a registered write by name. */
1435
1477
  async executeNamed(name, args, writeConcern) {
@@ -2,10 +2,10 @@ export { F as FieldMergeResolver, L as LWWResolver, P as PrimaryWinsResolver } f
2
2
  import { C as ConflictResolver, R as ReplicationBatch } from '../types-BG31TtrQ.js';
3
3
  export { a as ConflictContext, b as ConflictResolution } from '../types-BG31TtrQ.js';
4
4
  import { C as ClientOptions, B as BulkLoadDurability } from '../server-options-B9CsAZp5.js';
5
- import { D as DatabaseClient, T as Transport, L as LiveHandlers, R as RemoteSubscription, a as RemoteSubscriptionBuilder, S as SubscribeOptions, b as RegistryDigestSource } from '../client-base-CCY9go0g.js';
6
- export { c as LoadAllOptions, d as RemoteDatabase, e as RemoteError, f as SQL_REFUSED_MESSAGE, g as ServerCapabilities, h as ServerCapabilityCheck } from '../client-base-CCY9go0g.js';
5
+ import { D as DatabaseClient, T as Transport, L as LiveHandlers, R as RemoteSubscription, a as RemoteSubscriptionBuilder, S as SubscribeOptions, b as RegistryDigestSource } from '../client-base-Doaqwrx3.js';
6
+ export { c as LoadAllOptions, d as RemoteDatabase, e as RemoteError, f as SQL_REFUSED_MESSAGE, g as ServerCapabilities, h as ServerCapabilityCheck } from '../client-base-Doaqwrx3.js';
7
7
  import { a as LiveQuery, b as LiveQueryState, c as LiveUpdate } from '../types-CEJG0eFS.js';
8
- import { q as DeviceSyncPort, D as Database } from '../database-D4oNUy_2.js';
8
+ import { q as DeviceSyncPort, D as Database } from '../database-fz-8CJBP.js';
9
9
  import { C as ChangeEvent, P as Params, R as ReadConcern, W as WriteConcern } from '../query-types-5B02ixH0.js';
10
10
  import { Q as QueryResponse, E as ExecuteResponse, T as TransactionResponse, B as BatchResponse, L as LoadResponse, A as AckResponse } from '../protocol-DZSYSv0S.js';
11
11
  import '../operation-registry-CGhNT-Sn.js';
@@ -1,5 +1,5 @@
1
- import { DatabaseClient, createEndpointTransport, toBaseUrl, DEFAULT_HTTP_REQUEST_TIMEOUT_MS, postJson, decodeTaggedValues, RemoteError, invokeCallerCallback, encodeTaggedValues, assertWebSocketCredentials, STAGED_STREAM_CAPABILITY, verifyDeviceSyncCapabilities, unrefTimer, toWsUrl, WebSocketTransport } from '../chunk-RASMCXBN.mjs';
2
- export { HttpTransport, RemoteDatabase, RemoteError, RemoteLiveQuery, RemoteSubscriptionBuilderImpl, SQL_REFUSED_MESSAGE, ServerCapabilities, WebSocketTransport } from '../chunk-RASMCXBN.mjs';
1
+ import { DatabaseClient, createEndpointTransport, toBaseUrl, DEFAULT_HTTP_REQUEST_TIMEOUT_MS, postJson, decodeTaggedValues, RemoteError, invokeCallerCallback, encodeTaggedValues, assertWebSocketCredentials, STAGED_STREAM_CAPABILITY, verifyDeviceSyncCapabilities, unrefTimer, toWsUrl, WebSocketTransport } from '../chunk-WXPAWGTE.mjs';
2
+ export { HttpTransport, RemoteDatabase, RemoteError, RemoteLiveQuery, RemoteSubscriptionBuilderImpl, SQL_REFUSED_MESSAGE, ServerCapabilities, WebSocketTransport } from '../chunk-WXPAWGTE.mjs';
3
3
 
4
4
  // src/core/sync/canonicalise.ts
5
5
  function canonicaliseForChecksum(value) {
@@ -1,6 +1,6 @@
1
1
  import { a as ReadConcernLevel } from '../query-types-5B02ixH0.js';
2
2
  import { C as ClientOptions } from '../server-options-B9CsAZp5.js';
3
- import { T as Transport, D as DatabaseClient } from '../client-base-CCY9go0g.js';
3
+ import { T as Transport, D as DatabaseClient } from '../client-base-Doaqwrx3.js';
4
4
  import { I as ClusterStatusInfo } from '../types-DTmi7pXp.js';
5
5
  import '../operation-registry-CGhNT-Sn.js';
6
6
  import '../types-BG31TtrQ.js';
@@ -1,4 +1,4 @@
1
- import { DatabaseClient, toBaseUrl, createEndpointTransport, RemoteError, toServerBaseUrl, unrefTimer } from '../chunk-RASMCXBN.mjs';
1
+ import { DatabaseClient, toBaseUrl, createEndpointTransport, RemoteError, toServerBaseUrl, unrefTimer } from '../chunk-WXPAWGTE.mjs';
2
2
  import '../chunk-3LXXH3RA.mjs';
3
3
 
4
4
  // src/server/protocol.ts
@@ -21,6 +21,12 @@ interface ServerCapabilityCheck {
21
21
  * because it predates the capability report, and throws `SQL_NOT_ACCEPTED` when the report leaves SQL out.
22
22
  */
23
23
  assertSqlAccepted(): Promise<void>;
24
+ /**
25
+ * Returns `true` while the capability report that the client last read announces that the server accepts SQL, so
26
+ * that a remote database can send a statement without waiting on {@link ServerCapabilityCheck.assertSqlAccepted}.
27
+ * A check without this method makes every statement wait on that call.
28
+ */
29
+ knownToAcceptSql?(): boolean;
24
30
  /** Returns the digest of the server's operation registry, or `undefined` when the server announces none. */
25
31
  registryDigest(refresh?: boolean): Promise<string | undefined>;
26
32
  /** Cancels the capability request in flight, which the remote database calls when it closes. */
@@ -36,10 +42,18 @@ declare class ServerCapabilities implements ServerCapabilityCheck {
36
42
  private readonly headers;
37
43
  private readonly requestTimeoutMs;
38
44
  private pending;
45
+ private acceptsSql;
39
46
  private readonly lifetime;
40
47
  constructor(resolveUrl: () => string | Promise<string>, headers: Record<string, string> | undefined, requestTimeoutMs?: number);
41
48
  /** Cancels the capability request in flight and fails every later check with `TRANSPORT_ERROR`. */
42
49
  close(): void;
50
+ /**
51
+ * Returns whether the report that the client last read announces SQL, which stays `false` while a report is in
52
+ * flight and after the client closes.
53
+ *
54
+ * @returns `true` when a statement can skip waiting on {@link ServerCapabilities.assertSqlAccepted}.
55
+ */
56
+ knownToAcceptSql(): boolean;
43
57
  private read;
44
58
  registryDigest(refresh?: boolean): Promise<string | undefined>;
45
59
  assertSqlAccepted(): Promise<void>;
@@ -4,13 +4,13 @@ export { A as AfterQueryHook, Z as AfterQueryHookContext, _ as AppliedMigrationE
4
4
  import { B as BulkLoadDurability, a as BulkLoadResult, R as RequestContext } from '../server-options-B9CsAZp5.js';
5
5
  export { A as AppliedMigrationRow, b as AuthenticateHook, c as BulkLoadOptions, C as ClientOptions, d as ClusterStatusAuthorizer, e as CorsOptions, f as ReplicationStatusInfo, g as ServerExecutionTarget, h as ServerExecutionTargetResolver, S as ServerOptions, W as WSHandlerOptions } from '../server-options-B9CsAZp5.js';
6
6
  export { C as ChangeTracker, a as ChangeTrackerOptions } from '../change-tracker-Dpo99EI-.js';
7
- import { D as Database } from '../database-D4oNUy_2.js';
8
- export { B as BackupError, C as CDCError, b as ConnectionPool, c as ConnectionPoolError, d as ConnectionPoolOptions, e as DatabaseAlreadyExistsError, f as DatabaseBackups, g as DatabaseLifecycle, h as DatabaseNotFoundError, E as ExtensionError, F as ForbiddenSqlError, i as HookDeniedError, a as HookDispose, j as HookEvent, k as HookEventContextMap, l as HookHandler, H as HookRegistry, M as MaxDatabasesError, m as MigrationError, P as PushHookContext, Q as QueryError, R as ReadOnlyError, n as RequestDeniedError, S as SirannonError, o as SnapshotHookContext, p as SubscribeHookContext, T as TransactionError, W as WriteOverloadError } from '../database-D4oNUy_2.js';
7
+ import { D as Database } from '../database-fz-8CJBP.js';
8
+ export { B as BackupError, C as CDCError, b as ConnectionPool, c as ConnectionPoolError, d as ConnectionPoolOptions, e as DatabaseAlreadyExistsError, f as DatabaseBackups, g as DatabaseLifecycle, h as DatabaseNotFoundError, E as ExtensionError, F as ForbiddenSqlError, i as HookDeniedError, a as HookDispose, j as HookEvent, k as HookEventContextMap, l as HookHandler, H as HookRegistry, M as MaxDatabasesError, m as MigrationError, P as PushHookContext, Q as QueryError, R as ReadOnlyError, n as RequestDeniedError, S as SirannonError, o as SnapshotHookContext, p as SubscribeHookContext, T as TransactionError, W as WriteOverloadError } from '../database-fz-8CJBP.js';
9
9
  export { a as LiveQuery, L as LiveQueryOptions, b as LiveQueryState, c as LiveUpdate, R as ResultOp } from '../types-CEJG0eFS.js';
10
10
  import { B as BaselineFileOption } from '../baseline-Co3iIsN_.js';
11
11
  import { P as Params, E as ExecuteResult } from '../query-types-5B02ixH0.js';
12
12
  export { C as ChangeEvent, b as ChangeOperation, Q as QueryOptions, R as ReadConcern, a as ReadConcernLevel, S as Subscription, c as SubscriptionBuilder, d as SubscriptionOptions, W as WriteConcern, e as WriteConcernLevel } from '../query-types-5B02ixH0.js';
13
- export { S as Sirannon } from '../sirannon-B6sPKDye.js';
13
+ export { S as Sirannon } from '../sirannon-D0CjDULa.js';
14
14
  export { D as DatabaseOperations, b as OperationArguments, O as OperationRef, a as OperationRegistry, c as OperationStatement, R as ReadOperation, W as WriteOperation, o as operationName, d as operationRef } from '../operation-registry-CGhNT-Sn.js';
15
15
  import '../types-BG31TtrQ.js';
16
16
 
@@ -1,17 +1,17 @@
1
- import { Transaction, MetricsCollector, readOutcome, failedStatementOutcome, settleLateOutcome, ROW_COUNTS_UNKNOWN, leavesOutcomeUnknown, LWWResolver, REMOTE_ORIGIN_NODE_ID, BatchReader, BatchApplier, recordLocalColumnVersions, writeOutcome, batchWriteOutcome, StatementRecorder, loadPersistedHlc, isWellFormedHlc, HLC_CLOCK_META_KEY, readOneOutcome } from '../chunk-YRNLEOSU.mjs';
2
- export { MetricsCollector, Transaction } from '../chunk-YRNLEOSU.mjs';
1
+ import { Transaction, MetricsCollector, readOutcome, failedStatementOutcome, settleLateOutcome, ROW_COUNTS_UNKNOWN, leavesOutcomeUnknown, LWWResolver, REMOTE_ORIGIN_NODE_ID, BatchReader, BatchApplier, recordLocalColumnVersions, writeOutcome, batchWriteOutcome, StatementRecorder, loadPersistedHlc, isWellFormedHlc, HLC_CLOCK_META_KEY, readOneOutcome } from '../chunk-AP4367HK.mjs';
2
+ export { MetricsCollector, Transaction } from '../chunk-AP4367HK.mjs';
3
3
  import '../chunk-ZFFUVYYE.mjs';
4
- import { executeGroup } from '../chunk-54MAOILS.mjs';
5
- import { asQueryError, runInSavepoint, runWriterTransaction, withoutRowCounts, execute, executeBatchSummary, bindParams, executeBatch, queryMetered, queryForWire, queryOneMetered } from '../chunk-LHH4PMRV.mjs';
6
- export { execute, executeBatch, query, queryOne } from '../chunk-LHH4PMRV.mjs';
4
+ import { executeGroup } from '../chunk-ISDT4RBD.mjs';
5
+ import { query, queryRowsForWire, queryOne, asQueryError, runInSavepoint, runWriterTransaction, withoutRowCounts, execute, executeBatchSummary, bindParams, executeBatch, queryMetered, queryForWire, queryOneMetered } from '../chunk-DDIHBUEN.mjs';
6
+ export { execute, executeBatch, query, queryOne } from '../chunk-DDIHBUEN.mjs';
7
7
  import { unsupported, findClauses, readSource, readSortTerms, readWindow, readSelectItems } from '../chunk-D3YF2G7X.mjs';
8
- import { reconcileMigrationChecksums, migrationContentChecksum, resolveDeviceRetentionPolicy, ensureCdcEpoch, SubscriptionBuilderImpl, ChangeTracker, SubscriptionManager, startPolling, DEVICE_SYNC_PUSHED_SEQ_META_KEY, runBulkLoad, parseColumnDefinitions, TransactionGrouper, PrimedSubscription, dropCdcTriggers, ROWID_ALIASES } from '../chunk-UGGWPZIP.mjs';
9
- export { ChangeTracker, isBulkLoadDurability, runBulkLoad } from '../chunk-UGGWPZIP.mjs';
8
+ import { reconcileMigrationChecksums, migrationContentChecksum, resolveDeviceRetentionPolicy, ensureCdcEpoch, SubscriptionBuilderImpl, ChangeTracker, SubscriptionManager, startPolling, DEVICE_SYNC_PUSHED_SEQ_META_KEY, runBulkLoad, parseColumnDefinitions, TransactionGrouper, PrimedSubscription, dropCdcTriggers, ROWID_ALIASES } from '../chunk-SB3MIFLG.mjs';
9
+ export { ChangeTracker, isBulkLoadDurability, runBulkLoad } from '../chunk-SB3MIFLG.mjs';
10
10
  import { planBackupRestore, backupPiecesSafeToDelete } from '../chunk-YW7IKQ7T.mjs';
11
11
  export { backupPiecesSafeToDelete, planBackupRestore } from '../chunk-YW7IKQ7T.mjs';
12
- import { ensureMigrationsTable, prepareUpdateMigrationChecksum, prepareInsertMigration, selectAppliedMigrationsNewestFirst, prepareDeleteMigration, selectAppliedMigrations, selectTableExists, selectMetaValue, upsertMetaValue, SEQ_STRING_RE, replaceMigrationHistory, highestMigrationVersion, selectCountOutboundChanges, ensureMetaTable, ensureChangesTable, ensureBatchApplyTables, ensureStagedPushChangesTable, PkResolver, selectMaxChangeSeq, selectMaxAppliedSourceSeq, tableColumnsWithGenerated, TABLE_XINFO_HIDDEN, selectTableSql, primaryKeyColumns, tableIndexList, upsertMetaMaxChangeSeqSql, updateChangeStampsAboveMetaSeqSql, upsertMetaValueAndMaxChangeSeqSql, insertMetaValueIfAbsent, HLC, selectMaxChangeHlc, setForeignKeysEnabled, IDENTIFIER_RE, validateDdlSafety, ensureStagedChangesTable, upsertStagedChangeSql, selectFirstStagedTransactionEnd, deleteStagedChangesUpToSeq, selectMaxStagedSeq, deleteAllStagedChanges, deleteMetaValue, selectStagedChangesInRange, assertSafeIdentifier } from '../chunk-56HOLQKD.mjs';
12
+ import { ensureMigrationsTable, prepareUpdateMigrationChecksum, prepareInsertMigration, selectAppliedMigrationsNewestFirst, prepareDeleteMigration, selectAppliedMigrations, selectTableExists, selectMetaValue, upsertMetaValue, SEQ_STRING_RE, replaceMigrationHistory, highestMigrationVersion, selectCountOutboundChanges, ensureMetaTable, ensureChangesTable, ensureBatchApplyTables, ensureStagedPushChangesTable, PkResolver, selectMaxChangeSeq, selectMaxAppliedSourceSeq, tableColumnsWithGenerated, TABLE_XINFO_HIDDEN, selectTableSql, primaryKeyColumns, tableIndexList, upsertMetaMaxChangeSeqSql, updateChangeStampsAboveMetaSeqSql, upsertMetaValueAndMaxChangeSeqSql, insertMetaValueIfAbsent, HLC, selectMaxChangeHlc, setForeignKeysEnabled, IDENTIFIER_RE, validateDdlSafety, ensureStagedChangesTable, upsertStagedChangeSql, selectFirstStagedTransactionEnd, deleteStagedChangesUpToSeq, selectMaxStagedSeq, deleteAllStagedChanges, deleteMetaValue, selectStagedChangesInRange, assertSafeIdentifier } from '../chunk-RPWBYASV.mjs';
13
13
  import { ReplicationError } from '../chunk-BLMRNSUG.mjs';
14
- import { MIGRATIONS_TABLE, META_TABLE, CHANGES_TABLE, assertSqlAllowed, LIVE_PROBE_TABLE_PREFIX, eventTimestampToChangedAt, encodeTaggedValues, INTERNAL_TABLE_PREFIX, isReservedIdentifier, decodeTaggedValues, changedAtToEventTimestamp } from '../chunk-EUNHTFR7.mjs';
14
+ import { MIGRATIONS_TABLE, META_TABLE, CHANGES_TABLE, assertSqlAllowed, LIVE_PROBE_TABLE_PREFIX, eventTimestampToChangedAt, encodeTaggedValues, INTERNAL_TABLE_PREFIX, isReservedIdentifier, decodeTaggedValues, changedAtToEventTimestamp } from '../chunk-JFVEGN7J.mjs';
15
15
  import { tokenizeSql, isKeyword, parameterName } from '../chunk-SEL4A4WT.mjs';
16
16
  import '../chunk-GVCNMPOS.mjs';
17
17
  import { defaultStagingDir } from '../chunk-JAQ2I4OT.mjs';
@@ -1999,6 +1999,12 @@ var DatabaseWriteController = class {
1999
1999
  }
2000
2000
  execute(sql, params, options) {
2001
2001
  const { observer, writeGate, writerLock, groupCommitter } = this.deps;
2002
+ if (!observer.observesQueries) {
2003
+ const unobserved = this.refusedCaller() ?? writeGate.run(
2004
+ () => writerLock.isHeld() ? groupCommitter.runUngrouped(sql, params) : groupCommitter.submit(sql, params)
2005
+ );
2006
+ return unobserved.then(withoutRowCounts);
2007
+ }
2002
2008
  const failed = {};
2003
2009
  return observer.withQueryHooks(
2004
2010
  sql,
@@ -2909,6 +2915,7 @@ var DatabaseBackups = class extends DatabaseLifecycle {
2909
2915
 
2910
2916
  // src/core/database-reads.ts
2911
2917
  function readRows(deps, sql, params, options) {
2918
+ if (readsUnobserved(deps)) return query(deps.pool.acquireReader(), sql, params);
2912
2919
  return deps.observer.withQueryHooks(
2913
2920
  sql,
2914
2921
  params,
@@ -2917,6 +2924,7 @@ function readRows(deps, sql, params, options) {
2917
2924
  );
2918
2925
  }
2919
2926
  function readWireRows(deps, sql, params, options) {
2927
+ if (readsUnobserved(deps)) return queryRowsForWire(deps.pool.acquireReader(), sql, params);
2920
2928
  return deps.observer.withQueryHooks(
2921
2929
  sql,
2922
2930
  params,
@@ -2925,6 +2933,7 @@ function readWireRows(deps, sql, params, options) {
2925
2933
  );
2926
2934
  }
2927
2935
  function readOneRow(deps, sql, params, options) {
2936
+ if (readsUnobserved(deps)) return queryOne(deps.pool.acquireReader(), sql, params);
2928
2937
  return deps.observer.withQueryHooks(
2929
2938
  sql,
2930
2939
  params,
@@ -2932,6 +2941,9 @@ function readOneRow(deps, sql, params, options) {
2932
2941
  () => onReadConnection(deps, sql, (conn) => queryOneMetered(conn, sql, params), readOneOutcome)
2933
2942
  );
2934
2943
  }
2944
+ function readsUnobserved(deps) {
2945
+ return deps.pool.readerCount > 0 && !deps.observer.observesQueries;
2946
+ }
2935
2947
  async function onReadConnection(deps, sql, op, measure) {
2936
2948
  const refusal = deps.pool.readerCount === 0 ? deps.writerLock.callerRefusal() : null;
2937
2949
  if (refusal !== null) throw refusal;
@@ -4211,10 +4223,23 @@ var Database = class _Database extends DatabaseBackups {
4211
4223
  this.ensureOpen();
4212
4224
  return readRows(this.runtime.reads, sql, params, options);
4213
4225
  }
4214
- /** @internal */
4215
- async queryForWire(sql, params, options) {
4216
- this.ensureOpen();
4217
- return readWireRows(this.runtime.reads, sql, params, options);
4226
+ /**
4227
+ * Executes a read and returns its rows encoded for a network response, which the server sends without encoding
4228
+ * them again.
4229
+ *
4230
+ * @param sql - The statement to execute.
4231
+ * @param params - The values to bind to the statement, named or positional.
4232
+ * @param options - The read concern for this statement.
4233
+ * @returns The rows with every value encoded for the wire.
4234
+ * @internal
4235
+ */
4236
+ queryForWire(sql, params, options) {
4237
+ try {
4238
+ this.ensureOpen();
4239
+ return readWireRows(this.runtime.reads, sql, params, options);
4240
+ } catch (err) {
4241
+ return Promise.reject(err);
4242
+ }
4218
4243
  }
4219
4244
  /**
4220
4245
  * Executes a read and returns its first row.
@@ -1,6 +1,6 @@
1
- import { executeGroup } from '../chunk-54MAOILS.mjs';
2
- import '../chunk-LHH4PMRV.mjs';
3
- import '../chunk-EUNHTFR7.mjs';
1
+ import { executeGroup } from '../chunk-ISDT4RBD.mjs';
2
+ import '../chunk-DDIHBUEN.mjs';
3
+ import '../chunk-JFVEGN7J.mjs';
4
4
  import { WORKER_CANCELLED_CODE, serializeError, WORKER_BEGIN_FAILED_CODE, WORKER_COPY_STOPPED_CODE } from '../chunk-75IBRE73.mjs';
5
5
  import { addRowCounts, rowCountsOf, withRowCounts } from '../chunk-E2GRX4ZD.mjs';
6
6
  import { SirannonError } from '../chunk-KINDFBQP.mjs';
@@ -1032,7 +1032,16 @@ declare class Database extends DatabaseBackups {
1032
1032
  * @returns The rows that the statement returns.
1033
1033
  */
1034
1034
  query<T = Record<string, unknown>>(sql: string, params?: Params, options?: QueryOptions): Promise<T[]>;
1035
- /** @internal */
1035
+ /**
1036
+ * Executes a read and returns its rows encoded for a network response, which the server sends without encoding
1037
+ * them again.
1038
+ *
1039
+ * @param sql - The statement to execute.
1040
+ * @param params - The values to bind to the statement, named or positional.
1041
+ * @param options - The read concern for this statement.
1042
+ * @returns The rows with every value encoded for the wire.
1043
+ * @internal
1044
+ */
1036
1045
  queryForWire(sql: string, params?: Params, options?: QueryOptions): Promise<unknown[]>;
1037
1046
  /**
1038
1047
  * Executes a read and returns its first row.
@@ -1,15 +1,15 @@
1
1
  import { optionalDependencyError } from '../chunk-WOMADPM4.mjs';
2
- import { nodeResolveExtensionPath, asyncLocalWriterContext, nodeBackupEngine, nodeStreamingSupport, WriterWorker, createStatementCache, loadThroughRuntime, bindableParams, narrowSafeBigInt, narrowRowIntegers, narrowRowsIntegers } from '../chunk-NBPLGMPP.mjs';
2
+ import { nodeResolveExtensionPath, asyncLocalWriterContext, nodeBackupEngine, nodeStreamingSupport, WriterWorker, createStatementCache, loadThroughRuntime, bindableParams, narrowSafeBigInt, narrowRowIntegers, narrowRowsIntegers } from '../chunk-G4AG3ESO.mjs';
3
3
  import '../chunk-DX4WGJL7.mjs';
4
- import '../chunk-C53DPOR5.mjs';
4
+ import '../chunk-BTUD6XQO.mjs';
5
5
  import { defineDriver } from '../chunk-JAQ2I4OT.mjs';
6
6
  import '../chunk-W67A4H2E.mjs';
7
7
  import '../chunk-K43WJORM.mjs';
8
8
  import '../chunk-75IBRE73.mjs';
9
9
  import { withRowCounts } from '../chunk-E2GRX4ZD.mjs';
10
- import '../chunk-LRUC2GSU.mjs';
10
+ import '../chunk-UHUDPQFI.mjs';
11
11
  import '../chunk-QGVRRKB2.mjs';
12
- import '../chunk-IWS4PJIO.mjs';
12
+ import '../chunk-AHCMO4YL.mjs';
13
13
  import '../chunk-BUWJH3D3.mjs';
14
14
  import { synchronousPragmaValue } from '../chunk-YCMB6GR4.mjs';
15
15
  import '../chunk-CZL4D3BM.mjs';
@@ -1,4 +1,4 @@
1
- import { defineDriver, synchronousPragmaValue, bindableParams, narrowSafeBigInt, narrowRowIntegers, narrowRowsIntegers, SirannonError, ExtensionError } from '../chunk-N4EXO2VH.mjs';
1
+ import { defineDriver, synchronousPragmaValue, assertHoldsStatement, bindableParams, narrowSafeBigInt, narrowRowIntegers, narrowRowsIntegers, SirannonError, ExtensionError } from '../chunk-DBN57KVR.mjs';
2
2
  import { resolve } from 'path';
3
3
  import { AsyncLocalStorage } from 'async_hooks';
4
4
 
@@ -44,6 +44,7 @@ function bunSqlite(driverOptions) {
44
44
  db.run(sql);
45
45
  },
46
46
  async prepare(sql) {
47
+ assertHoldsStatement(sql);
47
48
  const stmt = db.query(sql);
48
49
  return {
49
50
  async all(...params) {
@@ -1,4 +1,4 @@
1
- import { defineDriver, synchronousPragmaValue, ExtensionError, isNamedParams } from '../chunk-N4EXO2VH.mjs';
1
+ import { defineDriver, synchronousPragmaValue, ExtensionError, assertHoldsStatement, isNamedParams } from '../chunk-DBN57KVR.mjs';
2
2
 
3
3
  // src/drivers/expo/bind.ts
4
4
  var LARGEST_SAFE_INTEGER = BigInt(Number.MAX_SAFE_INTEGER);
@@ -49,6 +49,7 @@ function expoSqlite() {
49
49
  await dbHandle.execAsync(sql);
50
50
  },
51
51
  async prepare(sql) {
52
+ assertHoldsStatement(sql);
52
53
  return {
53
54
  async all(...params) {
54
55
  return dbHandle.getAllAsync(sql, expoBindParams(params));
@@ -1,14 +1,14 @@
1
- import { nodeResolveExtensionPath, asyncLocalWriterContext, createStatementCache, nodeBackupEngine, nodeStreamingSupport, WriterWorker, loadThroughRuntime, bindableParams, narrowSafeBigInt, narrowRowIntegers, narrowRowsIntegers } from '../chunk-NBPLGMPP.mjs';
1
+ import { nodeResolveExtensionPath, asyncLocalWriterContext, createStatementCache, nodeBackupEngine, nodeStreamingSupport, WriterWorker, loadThroughRuntime, bindableParams, narrowSafeBigInt, narrowRowIntegers, narrowRowsIntegers } from '../chunk-G4AG3ESO.mjs';
2
2
  import '../chunk-DX4WGJL7.mjs';
3
- import '../chunk-C53DPOR5.mjs';
3
+ import '../chunk-BTUD6XQO.mjs';
4
4
  import { defineDriver } from '../chunk-JAQ2I4OT.mjs';
5
5
  import '../chunk-W67A4H2E.mjs';
6
6
  import '../chunk-K43WJORM.mjs';
7
7
  import '../chunk-75IBRE73.mjs';
8
8
  import '../chunk-E2GRX4ZD.mjs';
9
- import '../chunk-LRUC2GSU.mjs';
9
+ import '../chunk-UHUDPQFI.mjs';
10
10
  import '../chunk-QGVRRKB2.mjs';
11
- import '../chunk-IWS4PJIO.mjs';
11
+ import '../chunk-AHCMO4YL.mjs';
12
12
  import '../chunk-BUWJH3D3.mjs';
13
13
  import { synchronousPragmaValue } from '../chunk-YCMB6GR4.mjs';
14
14
  import '../chunk-CZL4D3BM.mjs';
@@ -37,6 +37,68 @@ async function copyDatabaseWithNodeSqlite(db, request) {
37
37
  return final;
38
38
  }
39
39
 
40
+ // src/core/driver/statement-text.ts
41
+ var SPACE = 32;
42
+ var TAB = 9;
43
+ var LINE_FEED = 10;
44
+ var VERTICAL_TAB = 11;
45
+ var FORM_FEED = 12;
46
+ var CARRIAGE_RETURN = 13;
47
+ var SEMICOLON = 59;
48
+ var HYPHEN = 45;
49
+ var SLASH = 47;
50
+ var ASTERISK = 42;
51
+ var NO_STATEMENT_MESSAGE = "The supplied SQL string contains no statements";
52
+ function startsSqliteSpace(code) {
53
+ return code === SPACE || code === TAB || code === LINE_FEED || code === FORM_FEED || code === CARRIAGE_RETURN;
54
+ }
55
+ function continuesSqliteSpace(code) {
56
+ return startsSqliteSpace(code) || code === VERTICAL_TAB;
57
+ }
58
+ function holdsNoStatement(sql) {
59
+ const firstNul = sql.indexOf("\0");
60
+ const text = firstNul === -1 ? sql : sql.slice(0, firstNul);
61
+ let index = 0;
62
+ while (index < text.length) {
63
+ const code = text.charCodeAt(index);
64
+ if (startsSqliteSpace(code)) {
65
+ index++;
66
+ while (index < text.length && continuesSqliteSpace(text.charCodeAt(index))) index++;
67
+ continue;
68
+ }
69
+ if (code === SEMICOLON) {
70
+ index++;
71
+ continue;
72
+ }
73
+ const next = text.charCodeAt(index + 1);
74
+ if (code === HYPHEN && next === HYPHEN) {
75
+ const lineEnd = text.indexOf("\n", index + 2);
76
+ if (lineEnd === -1) return true;
77
+ index = lineEnd;
78
+ continue;
79
+ }
80
+ if (code === SLASH && next === ASTERISK && index + 2 < text.length) {
81
+ const commentEnd = text.indexOf("*/", index + 2);
82
+ if (commentEnd === -1) return true;
83
+ index = commentEnd + 2;
84
+ continue;
85
+ }
86
+ return false;
87
+ }
88
+ return true;
89
+ }
90
+ function assertHoldsStatement(sql) {
91
+ if (holdsNoStatement(sql)) throw new RangeError(NO_STATEMENT_MESSAGE);
92
+ }
93
+
94
+ // src/drivers/node/statement-text.ts
95
+ function prepareStatement(db, sql) {
96
+ assertHoldsStatement(sql);
97
+ const statement = db.prepare(sql);
98
+ statement.setReadBigInts(true);
99
+ return statement;
100
+ }
101
+
40
102
  // src/drivers/node/index.ts
41
103
  var FIRST_NODE_MAJOR_THAT_OPENS_A_COPY_BY_URI = 23;
42
104
  function parsesBackupUris() {
@@ -83,18 +145,13 @@ function nodeSqlite(driverOptions) {
83
145
  if (options?.walAutoCheckpoint !== void 0) {
84
146
  db.exec(`PRAGMA wal_autocheckpoint = ${Math.trunc(options.walAutoCheckpoint)}`);
85
147
  }
86
- const batchStatementFor = createStatementCache((sql) => {
87
- const stmt = db.prepare(sql);
88
- stmt.setReadBigInts(true);
89
- return stmt;
90
- });
148
+ const batchStatementFor = createStatementCache((sql) => prepareStatement(db, sql));
91
149
  const conn = {
92
150
  async exec(sql) {
93
151
  db.exec(sql);
94
152
  },
95
153
  async prepare(sql) {
96
- const stmt = db.prepare(sql);
97
- stmt.setReadBigInts(true);
154
+ const stmt = prepareStatement(db, sql);
98
155
  return {
99
156
  async all(...params) {
100
157
  return narrowRowsIntegers(stmt.all(...bindableParams(params)));
@@ -35,6 +35,60 @@ function defineDriver(config) {
35
35
  });
36
36
  }
37
37
 
38
+ // src/core/driver/statement-text.ts
39
+ var SPACE = 32;
40
+ var TAB = 9;
41
+ var LINE_FEED = 10;
42
+ var VERTICAL_TAB = 11;
43
+ var FORM_FEED = 12;
44
+ var CARRIAGE_RETURN = 13;
45
+ var SEMICOLON = 59;
46
+ var HYPHEN = 45;
47
+ var SLASH = 47;
48
+ var ASTERISK = 42;
49
+ var NO_STATEMENT_MESSAGE = "The supplied SQL string contains no statements";
50
+ function startsSqliteSpace(code) {
51
+ return code === SPACE || code === TAB || code === LINE_FEED || code === FORM_FEED || code === CARRIAGE_RETURN;
52
+ }
53
+ function continuesSqliteSpace(code) {
54
+ return startsSqliteSpace(code) || code === VERTICAL_TAB;
55
+ }
56
+ function holdsNoStatement(sql) {
57
+ const firstNul = sql.indexOf("\0");
58
+ const text = firstNul === -1 ? sql : sql.slice(0, firstNul);
59
+ let index = 0;
60
+ while (index < text.length) {
61
+ const code = text.charCodeAt(index);
62
+ if (startsSqliteSpace(code)) {
63
+ index++;
64
+ while (index < text.length && continuesSqliteSpace(text.charCodeAt(index))) index++;
65
+ continue;
66
+ }
67
+ if (code === SEMICOLON) {
68
+ index++;
69
+ continue;
70
+ }
71
+ const next = text.charCodeAt(index + 1);
72
+ if (code === HYPHEN && next === HYPHEN) {
73
+ const lineEnd = text.indexOf("\n", index + 2);
74
+ if (lineEnd === -1) return true;
75
+ index = lineEnd;
76
+ continue;
77
+ }
78
+ if (code === SLASH && next === ASTERISK && index + 2 < text.length) {
79
+ const commentEnd = text.indexOf("*/", index + 2);
80
+ if (commentEnd === -1) return true;
81
+ index = commentEnd + 2;
82
+ continue;
83
+ }
84
+ return false;
85
+ }
86
+ return true;
87
+ }
88
+ function assertHoldsStatement(sql) {
89
+ if (holdsNoStatement(sql)) throw new RangeError(NO_STATEMENT_MESSAGE);
90
+ }
91
+
38
92
  // src/core/driver/synchronous.ts
39
93
  var DEFAULT_SYNCHRONOUS = "normal";
40
94
  var SYNCHRONOUS_PRAGMA_VALUES = {
@@ -273,6 +327,7 @@ function waSqlite(driverOptions) {
273
327
  await sqlite3.exec(db, sql);
274
328
  },
275
329
  async prepare(sql) {
330
+ assertHoldsStatement(sql);
276
331
  return {
277
332
  async all(...params) {
278
333
  const result = await execStatements(sql, params);
@@ -1,5 +1,5 @@
1
1
  export { F as FieldMergeResolver, L as LWWResolver, P as PrimaryWinsResolver } from '../primary-wins-BnNAEjwB.js';
2
- import { r as HLC, D as Database, S as SirannonError } from '../database-D4oNUy_2.js';
2
+ import { r as HLC, D as Database, S as SirannonError } from '../database-fz-8CJBP.js';
3
3
  import { J as SQLiteConnection, s as BackupGroupSource, a4 as ClusterReadEndpointInfo, I as ClusterStatusInfo, T as Transaction } from '../types-DTmi7pXp.js';
4
4
  import { C as ClusterCoordinator, c as CoordinatorWatchDisposer, o as CoordinatorLease, e as ReplicationGroupState } from '../types-MczwKtul.js';
5
5
  export { A as AcquireControllerLeaseInput, a as AcquireControllerLeaseResult, l as AdmitNodeToInSyncSetInput, j as CompareAndAdvancePrimaryTermInput, k as CompareAndAdvancePrimaryTermResult, b as ControllerLeaseWatcher, n as CoordinatorCompatibilityMetadata, d as CoordinatorNodeSession, p as CoordinatorPrimary, N as NodeSessionWatcher, P as PromoteEligibleReplicaInput, R as RegisterNodeSessionInput, i as ReplicationGroupWatcher, S as SetReplicationGroupStateInput, U as UpdateInSyncSetInput, m as UpdateNodeMaintenanceInput } from '../types-MczwKtul.js';
@@ -1,16 +1,16 @@
1
1
  import { groupMemberIds, isGroupMember, sameNodeIdSet, compatibilityAllowsPromotion, arraysEqual } from '../chunk-PJRCMG7L.mjs';
2
2
  import { CoordinatorError, TopologyError, WriteConcernError, AuthorityError, SyncError, StalePrimaryError, NodeDrainingError, NodeNotInSyncError, ReadConcernError, ProtocolVersionMismatchError } from '../chunk-KU32OT4H.mjs';
3
3
  export { AuthorityError, CoordinatorError, FailoverError, NoSafePrimaryError, NodeDrainingError, NodeNotInSyncError, ProtocolVersionMismatchError, ReadConcernError, StalePrimaryError, SyncError, TopologyError, TransportError, UnsafeRecoveryRequiredError, WriteConcernError } from '../chunk-KU32OT4H.mjs';
4
- import { LWWResolver, BatchReader, BatchApplier, StampOps, writeOutcome, failedStatementOutcome, StatementRecorder, batchWriteOutcome, isWellFormedHlc, Transaction, loadPersistedHlc } from '../chunk-YRNLEOSU.mjs';
5
- export { LWWResolver } from '../chunk-YRNLEOSU.mjs';
4
+ import { LWWResolver, BatchReader, BatchApplier, StampOps, writeOutcome, failedStatementOutcome, StatementRecorder, batchWriteOutcome, isWellFormedHlc, Transaction, loadPersistedHlc } from '../chunk-AP4367HK.mjs';
5
+ export { LWWResolver } from '../chunk-AP4367HK.mjs';
6
6
  import '../chunk-ZFFUVYYE.mjs';
7
- import { runWriterTransaction, execute, withoutRowCounts } from '../chunk-LHH4PMRV.mjs';
8
- import { DumpOps, dumpSchema, tablesInFkOrder } from '../chunk-YGFNJBF3.mjs';
9
- import { canonicaliseForChecksum, HLC, PkResolver, selectMaxChangeHlc, selectMaxColumnVersionHlc, selectMaxAppliedSourceSeq, upsertPeerAckedSeq, selectPeerAckedSeq, selectMaxChangeSeq, selectMaxNodeChangeSeq, selectMinPeerAckedSeq, upsertSyncTableStatus, upsertSyncMeta, selectSyncMetaRow, selectCompletedSyncTableNames, ensureChangesTable, ensureReplicationStateTables, ensureMetaTable, IDENTIFIER_RE, setForeignKeysEnabled, deleteSyncTableStates, extractDroppedTable, insertDdlChange, validateDdlSafety, prepareInsertAppliedChange, selectNewestHistoryChange, upsertQuarantined, deleteStampedChangesUpToSeq, deleteColumnVersions, upsertHistoryBase, deleteAppliedChangesAfterSeq, deletePeerState, upsertAnchoredTerm, selectPrimaryTermStart, selectMaxHistoryChangeSeq, deletePeerStates, upsertPrimaryTermStart, selectHistoryTransaction, selectMaxAppliedSourceSeqByNode, selectAnchoredTerm, selectQuarantined, selectHistoryBase, selectHistoryChangesAfterHlc, deleteHistoryChangesAfterHlc, deleteColumnVersionsAfterHlc, tablePkColumns, deletePrimaryTermStart, selectMaxAssignedChangeSeq } from '../chunk-56HOLQKD.mjs';
10
- export { HLC } from '../chunk-56HOLQKD.mjs';
7
+ import { runWriterTransaction, execute, withoutRowCounts } from '../chunk-DDIHBUEN.mjs';
8
+ import { DumpOps, dumpSchema, tablesInFkOrder } from '../chunk-DKML5425.mjs';
9
+ import { canonicaliseForChecksum, HLC, PkResolver, selectMaxChangeHlc, selectMaxColumnVersionHlc, selectMaxAppliedSourceSeq, upsertPeerAckedSeq, selectPeerAckedSeq, selectMaxChangeSeq, selectMaxNodeChangeSeq, selectMinPeerAckedSeq, upsertSyncTableStatus, upsertSyncMeta, selectSyncMetaRow, selectCompletedSyncTableNames, ensureChangesTable, ensureReplicationStateTables, ensureMetaTable, IDENTIFIER_RE, setForeignKeysEnabled, deleteSyncTableStates, extractDroppedTable, insertDdlChange, validateDdlSafety, prepareInsertAppliedChange, selectNewestHistoryChange, upsertQuarantined, deleteStampedChangesUpToSeq, deleteColumnVersions, upsertHistoryBase, deleteAppliedChangesAfterSeq, deletePeerState, upsertAnchoredTerm, selectPrimaryTermStart, selectMaxHistoryChangeSeq, deletePeerStates, upsertPrimaryTermStart, selectHistoryTransaction, selectMaxAppliedSourceSeqByNode, selectAnchoredTerm, selectQuarantined, selectHistoryBase, selectHistoryChangesAfterHlc, deleteHistoryChangesAfterHlc, deleteColumnVersionsAfterHlc, tablePkColumns, deletePrimaryTermStart, selectMaxAssignedChangeSeq } from '../chunk-RPWBYASV.mjs';
10
+ export { HLC } from '../chunk-RPWBYASV.mjs';
11
11
  import { ReplicationError, BatchValidationError } from '../chunk-BLMRNSUG.mjs';
12
12
  export { BatchValidationError, ConflictError, ReplicationError } from '../chunk-BLMRNSUG.mjs';
13
- import { CHANGES_TABLE, INTERNAL_TABLE_PREFIX, isReservedIdentifier, decodeTaggedValues } from '../chunk-EUNHTFR7.mjs';
13
+ import { CHANGES_TABLE, INTERNAL_TABLE_PREFIX, isReservedIdentifier, decodeTaggedValues } from '../chunk-JFVEGN7J.mjs';
14
14
  import '../chunk-GVCNMPOS.mjs';
15
15
  import '../chunk-K43WJORM.mjs';
16
16
  import { rowCountsOf } from '../chunk-E2GRX4ZD.mjs';
@@ -2,10 +2,10 @@ import { h as BackupChain, l as BackupChainRecord, p as BackupCycleStatus, C as
2
2
  import { b as BackupRestoreProgress, a as BackupRestoreReport } from '../restore-options-CcMukOLO.js';
3
3
  import { a as TransactionStatement, Q as QueryResponse, E as ExecuteResponse, T as TransactionResponse, B as BatchResponse, L as LoadResponse, A as AckResponse } from '../protocol-DZSYSv0S.js';
4
4
  export { b as BatchRequest, c as ErrorResponse, d as ExecuteRequest, e as LoadRequest, f as QueryRequest, g as TransactionRequest, t as toExecuteResponse } from '../protocol-DZSYSv0S.js';
5
- import { S as Sirannon } from '../sirannon-B6sPKDye.js';
5
+ import { S as Sirannon } from '../sirannon-D0CjDULa.js';
6
6
  import { B as BulkLoadDurability, S as ServerOptions, W as WSHandlerOptions } from '../server-options-B9CsAZp5.js';
7
7
  import { W as WriteConcern, R as ReadConcern } from '../query-types-5B02ixH0.js';
8
- import '../database-D4oNUy_2.js';
8
+ import '../database-fz-8CJBP.js';
9
9
  import '../change-tracker-Dpo99EI-.js';
10
10
  import '../database-backup-BwTNiBm2.js';
11
11
  import '../types-BG31TtrQ.js';
@@ -1,17 +1,17 @@
1
1
  import { restoreBackup, MAX_RESTORE_BATCH_SIZE } from '../chunk-L6EX6K27.mjs';
2
- import { tablesInFkOrder, dumpSchema, dumpTablePages } from '../chunk-YGFNJBF3.mjs';
3
- import { resolveDeviceRetentionPolicy, ChangeTracker, SubscriptionManager, ensureCdcEpoch, migrationChecksum, applyDeviceCursorBoundary, needsResync, filteredChange, TransactionGrouper, isBulkLoadDurability, PrimedSubscription } from '../chunk-UGGWPZIP.mjs';
2
+ import { tablesInFkOrder, dumpSchema, dumpTablePages } from '../chunk-DKML5425.mjs';
3
+ import { resolveDeviceRetentionPolicy, ChangeTracker, SubscriptionManager, ensureCdcEpoch, migrationChecksum, applyDeviceCursorBoundary, needsResync, filteredChange, TransactionGrouper, isBulkLoadDurability, PrimedSubscription } from '../chunk-SB3MIFLG.mjs';
4
4
  import '../chunk-YW7IKQ7T.mjs';
5
- import { SEQ_STRING_RE, highestMigrationVersion, selectCountTableRows, selectTableExists, selectAppliedMigrations, PkResolver, ensureDeviceCursorsTable, upsertDeviceCursor, updateDeviceCursor, selectMaxAssignedChangeSeq, MAX_CHANGE_SEQ, HLC, selectMaxChangeSeq, canonicaliseForChecksum, selectDeviceCursorExists, IDENTIFIER_RE } from '../chunk-56HOLQKD.mjs';
5
+ import { SEQ_STRING_RE, highestMigrationVersion, selectCountTableRows, selectTableExists, selectAppliedMigrations, PkResolver, ensureDeviceCursorsTable, upsertDeviceCursor, updateDeviceCursor, selectMaxAssignedChangeSeq, MAX_CHANGE_SEQ, HLC, selectMaxChangeSeq, canonicaliseForChecksum, selectDeviceCursorExists, IDENTIFIER_RE } from '../chunk-RPWBYASV.mjs';
6
6
  import { BatchValidationError } from '../chunk-BLMRNSUG.mjs';
7
- import { MIGRATIONS_TABLE, decodeTaggedValues, encodeTaggedValues, encodeWireRowsInPlace, DEVICE_CURSORS_TABLE, CHANGES_TABLE, INTERNAL_TABLE_PREFIX } from '../chunk-EUNHTFR7.mjs';
7
+ import { MIGRATIONS_TABLE, decodeTaggedValues, encodeTaggedValues, encodeWireRowsInPlace, DEVICE_CURSORS_TABLE, CHANGES_TABLE, INTERNAL_TABLE_PREFIX } from '../chunk-JFVEGN7J.mjs';
8
8
  import { createOperationSource, operationRegistryDigest, findRead, isRefusal, resolveArguments, findWrite } from '../chunk-KB4OLJAD.mjs';
9
9
  import '../chunk-SEL4A4WT.mjs';
10
10
  import '../chunk-GVCNMPOS.mjs';
11
11
  import { optionalDependencyError } from '../chunk-WOMADPM4.mjs';
12
- import { discardStagedChain } from '../chunk-LRUC2GSU.mjs';
12
+ import { discardStagedChain } from '../chunk-UHUDPQFI.mjs';
13
13
  import '../chunk-QGVRRKB2.mjs';
14
- import '../chunk-IWS4PJIO.mjs';
14
+ import '../chunk-AHCMO4YL.mjs';
15
15
  import '../chunk-BUWJH3D3.mjs';
16
16
  import '../chunk-YCMB6GR4.mjs';
17
17
  import '../chunk-CZL4D3BM.mjs';
@@ -648,10 +648,13 @@ function writeCorsOrigin(res, cors, requestOrigin) {
648
648
  }
649
649
 
650
650
  // src/server/wire-rows.ts
651
- async function queryWireRows(target, sql, params, options) {
651
+ function queryWireRows(target, sql, params, options) {
652
652
  if (target.queryForWire) {
653
653
  return target.queryForWire(sql, params, options);
654
654
  }
655
+ return queryAndEncode(target, sql, params, options);
656
+ }
657
+ async function queryAndEncode(target, sql, params, options) {
655
658
  return encodeTaggedValues(await target.query(sql, params, options));
656
659
  }
657
660
 
@@ -1994,6 +1997,10 @@ var DEFAULT_WS_BACKPRESSURE_BYTES = 16 * 1048576;
1994
1997
  var UWS_MAX_LIMIT_BYTES = 4294967295;
1995
1998
  var DEFAULT_CLOSE_TIMEOUT_MS = DEFAULT_HTTP_REQUEST_TIMEOUT_MS;
1996
1999
  var MAX_TIMER_DELAY_MS = 2147483647;
2000
+ var MAX_UTF8_BYTES_PER_UTF16_UNIT = 3;
2001
+ function exceedsUtf8Bytes(text, maxBytes) {
2002
+ return text.length * MAX_UTF8_BYTES_PER_UTF16_UNIT > maxBytes && Buffer.byteLength(text) > maxBytes;
2003
+ }
1997
2004
  function resolveCloseTimeout(value) {
1998
2005
  if (value === void 0) return DEFAULT_CLOSE_TIMEOUT_MS;
1999
2006
  if (typeof value !== "number" || !Number.isInteger(value) || value < 0 || value > MAX_TIMER_DELAY_MS) {
@@ -3687,7 +3694,7 @@ var WSHandler = class {
3687
3694
  handleMessage(conn, data) {
3688
3695
  const state = this.connections.get(conn);
3689
3696
  if (!state) return;
3690
- if (Buffer.byteLength(data) > this.maxPayloadLength) {
3697
+ if (exceedsUtf8Bytes(data, this.maxPayloadLength)) {
3691
3698
  conn.close(WS_CLOSE_MESSAGE_TOO_BIG, "PAYLOAD_TOO_LARGE");
3692
3699
  return;
3693
3700
  }
@@ -3800,12 +3807,13 @@ var WSHandler = class {
3800
3807
  await this.cdc.closeAll();
3801
3808
  }
3802
3809
  operationContext(conn, state) {
3803
- return {
3810
+ state.operationContext ??= {
3804
3811
  target: state.executionTarget,
3805
3812
  sendResult: (id, data) => this.frames.send(conn, { type: "result", id, data }),
3806
3813
  sendError: (id, code, message) => this.frames.sendError(conn, id, code, message),
3807
3814
  sendCaughtError: (id, err) => this.frames.sendSirannonError(conn, id, err)
3808
3815
  };
3816
+ return state.operationContext;
3809
3817
  }
3810
3818
  namedContext(conn, state) {
3811
3819
  return {
@@ -1,4 +1,4 @@
1
- import { H as HookRegistry, D as Database, a as HookDispose } from './database-D4oNUy_2.js';
1
+ import { H as HookRegistry, D as Database, a as HookDispose } from './database-fz-8CJBP.js';
2
2
  import { a as SirannonOptions, S as SQLiteDriver, b as MetricsCollector, D as DatabaseOptions, M as Migration, c as BeforeQueryHook, A as AfterQueryHook, d as BeforeConnectHook, e as DatabaseOpenHook, f as DatabaseCloseHook } from './types-DTmi7pXp.js';
3
3
 
4
4
  /** The outcome of taking one database offline.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@delali/sirannon-db",
3
3
  "type": "module",
4
- "version": "0.3.5-next.71",
4
+ "version": "0.3.5-next.72",
5
5
  "description": "A production-grade library that turns SQLite databases into a networked data layer with real-time subscriptions.",
6
6
  "author": "Delali (https://sondelali.com)",
7
7
  "license": "Apache-2.0",
@@ -149,7 +149,7 @@
149
149
  },
150
150
  "peerDependencies": {
151
151
  "@bufbuild/protobuf": ">=2.0.0",
152
- "@delali/sirannon-sqlite": "0.3.5-next.71",
152
+ "@delali/sirannon-sqlite": "0.3.5-next.72",
153
153
  "@grpc/grpc-js": ">=1.10.0",
154
154
  "better-sqlite3": ">=12.0.0",
155
155
  "etcd3": ">=1.1.2",
@@ -193,7 +193,7 @@
193
193
  },
194
194
  "devDependencies": {
195
195
  "@bufbuild/protobuf": "2.11.0",
196
- "@delali/sirannon-sqlite": "0.3.5-next.71",
196
+ "@delali/sirannon-sqlite": "0.3.5-next.72",
197
197
  "@grpc/grpc-js": "1.14.4",
198
198
  "@microsoft/api-extractor": "7.58.12",
199
199
  "@types/better-sqlite3": "7.6.13",
@@ -221,11 +221,11 @@
221
221
  "vitest": "4.0.18"
222
222
  },
223
223
  "optionalDependencies": {
224
- "@delali/sirannon-vfs-darwin-arm64": "0.3.5-next.71",
225
- "@delali/sirannon-vfs-darwin-x64": "0.3.5-next.71",
226
- "@delali/sirannon-vfs-linux-arm64": "0.3.5-next.71",
227
- "@delali/sirannon-vfs-linux-x64": "0.3.5-next.71",
228
- "@delali/sirannon-vfs-win32-arm64": "0.3.5-next.71",
229
- "@delali/sirannon-vfs-win32-x64": "0.3.5-next.71"
224
+ "@delali/sirannon-vfs-darwin-arm64": "0.3.5-next.72",
225
+ "@delali/sirannon-vfs-darwin-x64": "0.3.5-next.72",
226
+ "@delali/sirannon-vfs-linux-arm64": "0.3.5-next.72",
227
+ "@delali/sirannon-vfs-linux-x64": "0.3.5-next.72",
228
+ "@delali/sirannon-vfs-win32-arm64": "0.3.5-next.72",
229
+ "@delali/sirannon-vfs-win32-x64": "0.3.5-next.72"
230
230
  }
231
231
  }