@cortexkit/pi-magic-context 0.46.1 → 0.48.0
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/auto-search-worker.js +112 -0
- package/dist/embedding-activity-ew6dshfd.js +10 -0
- package/dist/embedding-backfill-bnnytehy.js +20 -0
- package/dist/embedding-cache-7rp4gqzr.js +16 -0
- package/dist/embedding-worker.js +11 -8
- package/dist/harness-9872e0ym.js +10 -0
- package/dist/historian-calibration-extension.js +3 -2
- package/dist/index-0am8a7k1.js +152 -0
- package/dist/index-0h2mkab2.js +17 -0
- package/dist/index-135e8hvg.js +43 -0
- package/dist/{index-wv28nczk.js → index-3cgbv47m.js} +354 -38
- package/dist/index-419bndtm.js +2309 -0
- package/dist/index-544c0e0x.js +3026 -0
- package/dist/index-5hd7h4rr.js +3098 -0
- package/dist/index-5jp1h0bz.js +750 -0
- package/dist/index-603mt6nm.js +171 -0
- package/dist/index-674f6qs2.js +16 -0
- package/dist/{index-r01b1b78.js → index-6pgq5ns2.js} +157 -2454
- package/dist/index-72bdc1bd.js +3591 -0
- package/dist/index-8976mezv.js +209 -0
- package/dist/{index-td885aah.js → index-8y5knskr.js} +98 -231
- package/dist/{index-ykb8kkm3.js → index-98z1c1r0.js} +14599 -22287
- package/dist/index-9p40dgkm.js +22 -0
- package/dist/index-9x1f96r8.js +11 -0
- package/dist/{index-266qrgss.js → index-9xb0axhc.js} +301 -27
- package/dist/{index-phh7e055.js → index-bgmv2kaf.js} +28 -28
- package/dist/index-dkx0b1kt.js +514 -0
- package/dist/{index-7n8gb6j3.js → index-f956htf3.js} +28 -31
- package/dist/index-fapenpch.js +13 -0
- package/dist/index-fm3ksh5e.js +1060 -0
- package/dist/{index-2p1e8706.js → index-fp37he9a.js} +3 -3
- package/dist/index-hrf13mn3.js +2388 -0
- package/dist/index-pvm4pd5d.js +3069 -0
- package/dist/index-r7xg4hvw.js +3480 -0
- package/dist/index-rt5jgzp1.js +1127 -0
- package/dist/{index-n3g5mwa8.js → index-wrm4nbj7.js} +3 -3
- package/dist/index-xjqheg7a.js +931 -0
- package/dist/index-yhzhdp3m.js +143 -0
- package/dist/{index-w76x3af7.js → index-zrr5t5a7.js} +1 -3
- package/dist/index.js +6345 -2585
- package/dist/logger-v3dsxdnm.js +19 -0
- package/dist/message-index-bounded-t7vvty76.js +120 -0
- package/dist/{message-time-backfill-4688z1k2.js → message-time-backfill-4ndf7hrq.js} +7 -6
- package/dist/migration-worker.js +24 -16
- package/dist/project-embedding-registry-jy2hmq28.js +85 -0
- package/dist/raw-ordinal-warmup-worker.js +60 -0
- package/dist/{read-session-chunk-tc6yn2pe.js → read-session-chunk-47pjn7fz.js} +12 -6
- package/dist/read-session-raw-yn8nawav.js +55 -0
- package/dist/{safe-notification-target-6cn3z99t.js → safe-notification-target-3c1ns931.js} +3 -2
- package/dist/search-42szfhwp.js +40 -0
- package/dist/sqlite-3yye76ht.js +44 -0
- package/dist/sqlite-context-pragmas-gcgch6qz.js +6 -0
- package/dist/storage-memory-1z20y55x.js +71 -0
- package/dist/storage-tags-jym5z6yk.js +127 -0
- package/dist/subagent-entry.js +36 -16
- package/dist/transformers-node-wasm.js +18415 -18415
- package/package.json +3 -3
- package/dist/index-4vfrjwf6.js +0 -7737
- package/dist/index-xvw8zptx.js +0 -5123
- /package/dist/{index-901ekbga.js → index-5prbx026.js} +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// ../plugin/src/shared/sqlite.ts
|
|
2
2
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
3
|
var reportSlowPrivilegedWrite;
|
|
4
|
-
function
|
|
4
|
+
function registerSlowWriteReporter2(reporter) {
|
|
5
5
|
reportSlowPrivilegedWrite = reporter;
|
|
6
6
|
}
|
|
7
7
|
var sqliteDiagnosticSink;
|
|
8
|
-
function
|
|
8
|
+
function registerSqliteDiagnosticSink2(sink) {
|
|
9
9
|
sqliteDiagnosticSink = sink;
|
|
10
10
|
}
|
|
11
11
|
function reportSqliteDiagnostic(message) {
|
|
@@ -13,7 +13,7 @@ function reportSqliteDiagnostic(message) {
|
|
|
13
13
|
sqliteDiagnosticSink?.(`[magic-context] ${message}`);
|
|
14
14
|
} catch {}
|
|
15
15
|
}
|
|
16
|
-
function
|
|
16
|
+
function detectSqliteRuntime2() {
|
|
17
17
|
const hasBunVersion = typeof process !== "undefined" && typeof process.versions?.bun === "string";
|
|
18
18
|
const hasBunGlobal = typeof globalThis !== "undefined" && typeof globalThis.Bun !== "undefined";
|
|
19
19
|
return hasBunVersion || hasBunGlobal ? "Bun" : "Node.js";
|
|
@@ -46,10 +46,31 @@ class SqliteRuntimeUnavailableError extends Error {
|
|
|
46
46
|
this.specifier = specifier;
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
const
|
|
49
|
+
function isNodeSqliteExperimentalWarning(args) {
|
|
50
|
+
const [warning, options] = args;
|
|
51
|
+
const message = warning instanceof Error ? warning.message : warning;
|
|
52
|
+
const type = typeof options === "string" ? options : options && typeof options === "object" ? options.type : undefined;
|
|
53
|
+
return type === "ExperimentalWarning" && typeof message === "string" && message.startsWith("SQLite is an experimental feature");
|
|
54
|
+
}
|
|
55
|
+
async function importSqliteModuleForRuntime(runtime, specifier, importer) {
|
|
56
|
+
if (runtime !== "Node.js")
|
|
57
|
+
return importer(specifier);
|
|
58
|
+
const originalEmitWarning = process.emitWarning;
|
|
59
|
+
process.emitWarning = function(...args) {
|
|
60
|
+
if (isNodeSqliteExperimentalWarning(args))
|
|
61
|
+
return;
|
|
62
|
+
Reflect.apply(originalEmitWarning, this, args);
|
|
63
|
+
};
|
|
51
64
|
try {
|
|
52
65
|
return await importer(specifier);
|
|
66
|
+
} finally {
|
|
67
|
+
process.emitWarning = originalEmitWarning;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async function loadSqliteModule(runtime = detectSqliteRuntime2(), importer = importSqliteModule) {
|
|
71
|
+
const specifier = runtime === "Bun" ? bunSpec : nodeSpec;
|
|
72
|
+
try {
|
|
73
|
+
return await importSqliteModuleForRuntime(runtime, specifier, importer);
|
|
53
74
|
} catch (error) {
|
|
54
75
|
if (isModuleNotFoundError(error, specifier)) {
|
|
55
76
|
throw new SqliteRuntimeUnavailableError(runtime, specifier, error);
|
|
@@ -57,18 +78,95 @@ async function loadSqliteModule(runtime = detectSqliteRuntime(), importer = impo
|
|
|
57
78
|
throw error;
|
|
58
79
|
}
|
|
59
80
|
}
|
|
60
|
-
var detectedRuntime =
|
|
81
|
+
var detectedRuntime = detectSqliteRuntime2();
|
|
61
82
|
var isBun = detectedRuntime === "Bun";
|
|
62
83
|
var sqliteModule = await loadSqliteModule(detectedRuntime);
|
|
63
84
|
var DatabaseImpl = isBun ? sqliteModule.Database : buildNodeSqliteDatabaseClass(sqliteModule.DatabaseSync);
|
|
64
85
|
var trackedSqliteConnections = new Map;
|
|
65
86
|
var nextSqliteConnectionSequence = 1;
|
|
87
|
+
var TAG_COLUMNS_OUTSIDE_IDENTITY = new Set([
|
|
88
|
+
"status",
|
|
89
|
+
"drop_mode",
|
|
90
|
+
"byte_size",
|
|
91
|
+
"input_byte_size",
|
|
92
|
+
"reasoning_byte_size",
|
|
93
|
+
"token_count",
|
|
94
|
+
"input_token_count",
|
|
95
|
+
"caveman_depth",
|
|
96
|
+
"entry_fingerprint",
|
|
97
|
+
"tool_name",
|
|
98
|
+
"harness"
|
|
99
|
+
]);
|
|
100
|
+
var tagIdentityWriteGeneration = 0;
|
|
101
|
+
function mayChangeTagIdentity(sql) {
|
|
102
|
+
if (!/\btags\b/i.test(sql) || /^\s*(?:SELECT|EXPLAIN|PRAGMA)\b/i.test(sql))
|
|
103
|
+
return false;
|
|
104
|
+
if (/^\s*WITH\b/i.test(sql) && !/\b(?:INSERT|UPDATE|DELETE|REPLACE)\b/i.test(sql))
|
|
105
|
+
return false;
|
|
106
|
+
if (/;\s*\S/.test(sql) || /\bREPLACE\b/i.test(sql) || /\bON\s+CONFLICT\b/i.test(sql))
|
|
107
|
+
return true;
|
|
108
|
+
const insert = /^\s*INSERT\s+INTO\s+(?:main\.)?["`]?tags["`]?\s*\(([^)]*)\)/i.exec(sql);
|
|
109
|
+
if (insert) {
|
|
110
|
+
const columns = (insert[1] ?? "").split(",").map((column) => column.trim().replace(/["`[\]]/g, "").toLowerCase());
|
|
111
|
+
return columns.includes("id") || columns.includes("rowid");
|
|
112
|
+
}
|
|
113
|
+
const update = /^\s*UPDATE\s+(?:main\.)?["`]?tags["`]?\s+SET\s+([\s\S]*?)\bWHERE\b/i.exec(sql);
|
|
114
|
+
if (update && !/\bSELECT\b/i.test(sql)) {
|
|
115
|
+
const assignments = topLevelCommaSegments(update[1] ?? "");
|
|
116
|
+
if (!assignments)
|
|
117
|
+
return true;
|
|
118
|
+
return !assignments.every((assignment) => {
|
|
119
|
+
const column = /^\s*["`]?(\w+)["`]?\s*=(?!=)/.exec(assignment)?.[1];
|
|
120
|
+
return column !== undefined && TAG_COLUMNS_OUTSIDE_IDENTITY.has(column.toLowerCase());
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
function topLevelCommaSegments(text) {
|
|
126
|
+
const segments = [];
|
|
127
|
+
let depth = 0;
|
|
128
|
+
let quote = null;
|
|
129
|
+
let start = 0;
|
|
130
|
+
for (let index = 0;index < text.length; index += 1) {
|
|
131
|
+
const char = text[index];
|
|
132
|
+
if (quote) {
|
|
133
|
+
if (char === quote) {
|
|
134
|
+
if (text[index + 1] === quote)
|
|
135
|
+
index += 1;
|
|
136
|
+
else
|
|
137
|
+
quote = null;
|
|
138
|
+
}
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (char === "'" || char === '"' || char === "`")
|
|
142
|
+
quote = char;
|
|
143
|
+
else if (char === "(")
|
|
144
|
+
depth += 1;
|
|
145
|
+
else if (char === ")") {
|
|
146
|
+
depth -= 1;
|
|
147
|
+
if (depth < 0)
|
|
148
|
+
return null;
|
|
149
|
+
} else if (char === "," && depth === 0) {
|
|
150
|
+
segments.push(text.slice(start, index));
|
|
151
|
+
start = index + 1;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (quote || depth !== 0)
|
|
155
|
+
return null;
|
|
156
|
+
segments.push(text.slice(start));
|
|
157
|
+
return segments;
|
|
158
|
+
}
|
|
159
|
+
function getTagIdentityWriteGeneration2() {
|
|
160
|
+
return tagIdentityWriteGeneration;
|
|
161
|
+
}
|
|
66
162
|
function installTransactionRouting(db, readonly) {
|
|
67
163
|
const nativeExec = db.exec.bind(db);
|
|
68
164
|
Object.defineProperty(db, "exec", {
|
|
69
165
|
configurable: true,
|
|
70
166
|
writable: true,
|
|
71
167
|
value: (sql) => {
|
|
168
|
+
if (/^\s*(?:COMMIT|END)\b/i.test(sql))
|
|
169
|
+
assertTransformWrite2();
|
|
72
170
|
if (/^\s*BEGIN\s+(?:IMMEDIATE|EXCLUSIVE)(?:\s+TRANSACTION)?\s*;?\s*$/i.test(sql)) {
|
|
73
171
|
openWriterTransactions.delete(db);
|
|
74
172
|
if (transformPassScope.getStore()?.active || backgroundWriterScope.getStore())
|
|
@@ -79,8 +177,14 @@ function installTransactionRouting(db, readonly) {
|
|
|
79
177
|
}
|
|
80
178
|
if (WRITER_TRANSACTION_END.test(sql) && openWriterTransactions.has(db))
|
|
81
179
|
return endWriterTransaction(db, () => nativeExec(sql), sql);
|
|
82
|
-
if (!/^\s*(?:SELECT|EXPLAIN|PRAGMA|COMMIT|END|ROLLBACK|SAVEPOINT|RELEASE)\b/i.test(sql))
|
|
83
|
-
|
|
180
|
+
if (!/^\s*(?:SELECT|EXPLAIN|PRAGMA|COMMIT|END|ROLLBACK|SAVEPOINT|RELEASE)\b/i.test(sql)) {
|
|
181
|
+
try {
|
|
182
|
+
return withAutocommitTimeout(db, () => nativeExec(sql));
|
|
183
|
+
} finally {
|
|
184
|
+
if (mayChangeTagIdentity(sql))
|
|
185
|
+
tagIdentityWriteGeneration += 1;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
84
188
|
return nativeExec(sql);
|
|
85
189
|
}
|
|
86
190
|
});
|
|
@@ -91,13 +195,23 @@ function installTransactionRouting(db, readonly) {
|
|
|
91
195
|
value: (sql) => {
|
|
92
196
|
const statement = nativePrepare(sql);
|
|
93
197
|
if (!readonly && !/^\s*(?:SELECT|EXPLAIN|PRAGMA)\b/i.test(sql)) {
|
|
198
|
+
const changesTagIdentity = mayChangeTagIdentity(sql);
|
|
94
199
|
for (const method of ["run", "get", "all"]) {
|
|
95
200
|
const execute = statement[method].bind(statement);
|
|
96
201
|
Object.defineProperty(statement, method, {
|
|
97
202
|
configurable: true,
|
|
98
|
-
value: (...args) =>
|
|
203
|
+
value: (...args) => {
|
|
204
|
+
try {
|
|
205
|
+
return withAutocommitTimeout(db, () => execute(...args));
|
|
206
|
+
} finally {
|
|
207
|
+
if (changesTagIdentity)
|
|
208
|
+
tagIdentityWriteGeneration += 1;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
99
211
|
});
|
|
100
212
|
}
|
|
213
|
+
if (changesTagIdentity)
|
|
214
|
+
wrapRemainingTagWriteForms(statement);
|
|
101
215
|
}
|
|
102
216
|
return statement;
|
|
103
217
|
}
|
|
@@ -145,6 +259,35 @@ function installTransactionRouting(db, readonly) {
|
|
|
145
259
|
}
|
|
146
260
|
});
|
|
147
261
|
}
|
|
262
|
+
function wrapRemainingTagWriteForms(statement) {
|
|
263
|
+
if (typeof statement.iterate === "function") {
|
|
264
|
+
const iterate = statement.iterate.bind(statement);
|
|
265
|
+
Object.defineProperty(statement, "iterate", {
|
|
266
|
+
configurable: true,
|
|
267
|
+
value: function* (...args) {
|
|
268
|
+
tagIdentityWriteGeneration += 1;
|
|
269
|
+
try {
|
|
270
|
+
yield* iterate(...args);
|
|
271
|
+
} finally {
|
|
272
|
+
tagIdentityWriteGeneration += 1;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
if (typeof statement.values === "function") {
|
|
278
|
+
const values = statement.values.bind(statement);
|
|
279
|
+
Object.defineProperty(statement, "values", {
|
|
280
|
+
configurable: true,
|
|
281
|
+
value: (...args) => {
|
|
282
|
+
try {
|
|
283
|
+
return values(...args);
|
|
284
|
+
} finally {
|
|
285
|
+
tagIdentityWriteGeneration += 1;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
148
291
|
function trackSqliteConnection(db, filename, options) {
|
|
149
292
|
const originalClose = db.close.bind(db);
|
|
150
293
|
const sequence = nextSqliteConnectionSequence++;
|
|
@@ -204,7 +347,19 @@ function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
|
204
347
|
}
|
|
205
348
|
return NodeSqliteDatabase;
|
|
206
349
|
}
|
|
207
|
-
var
|
|
350
|
+
var Database2 = TrackedDatabase;
|
|
351
|
+
function getSqliteDatabasePath2(db) {
|
|
352
|
+
for (const connection of trackedSqliteConnections.values()) {
|
|
353
|
+
if (connection.reference.deref() === db) {
|
|
354
|
+
return connection.filename === ":memory:" || connection.filename === "<buffer>" ? null : connection.filename;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
const native = db;
|
|
358
|
+
const path = native.filename ?? native.name;
|
|
359
|
+
if (typeof path === "string" && path !== ":memory:" && path !== "")
|
|
360
|
+
return path;
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
208
363
|
function pragmaValue(db, name) {
|
|
209
364
|
const row = db.prepare(`PRAGMA ${name}`).get();
|
|
210
365
|
if (!row)
|
|
@@ -221,6 +376,15 @@ function pragmaNumber(db, name) {
|
|
|
221
376
|
}
|
|
222
377
|
var statementOwners = new WeakMap;
|
|
223
378
|
var FIRST_PRUNE_AT = 256;
|
|
379
|
+
function closeReleasingStatements(close, args) {
|
|
380
|
+
if (args[0] === true)
|
|
381
|
+
return close(true);
|
|
382
|
+
try {
|
|
383
|
+
return close(true);
|
|
384
|
+
} catch {
|
|
385
|
+
return close(...args);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
224
388
|
function ownPreparedStatement(db, statement) {
|
|
225
389
|
const finalizable = statement;
|
|
226
390
|
if (typeof finalizable.finalize !== "function")
|
|
@@ -244,7 +408,7 @@ function ownPreparedStatement(db, statement) {
|
|
|
244
408
|
}
|
|
245
409
|
}
|
|
246
410
|
references.clear();
|
|
247
|
-
const result = close
|
|
411
|
+
const result = closeReleasingStatements(close, args);
|
|
248
412
|
if (failure)
|
|
249
413
|
throw failure;
|
|
250
414
|
return result;
|
|
@@ -264,41 +428,57 @@ function ownPreparedStatement(db, statement) {
|
|
|
264
428
|
}
|
|
265
429
|
return statement;
|
|
266
430
|
}
|
|
267
|
-
function
|
|
431
|
+
function prepareCachedStatement2(db, sql) {
|
|
268
432
|
return ownPreparedStatement(db, db.prepare(sql));
|
|
269
433
|
}
|
|
270
434
|
var privilegeDepth = new WeakMap;
|
|
271
435
|
var transformPassScope = new AsyncLocalStorage;
|
|
272
436
|
var admissionScope = new AsyncLocalStorage;
|
|
273
437
|
var backgroundWriterScope = new AsyncLocalStorage;
|
|
274
|
-
function
|
|
438
|
+
function withSqliteBackgroundWriter2(operation) {
|
|
275
439
|
return backgroundWriterScope.run(true, operation);
|
|
276
440
|
}
|
|
277
|
-
function
|
|
441
|
+
function withSqliteTransformPass2(operation) {
|
|
278
442
|
const existing = transformPassScope.getStore();
|
|
279
443
|
if (existing?.active)
|
|
280
444
|
return operation();
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
445
|
+
const reservation = reserveForegroundSqliteTurn();
|
|
446
|
+
const run = (release) => {
|
|
447
|
+
const lease = { active: true, remainingWaitMs: FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS };
|
|
448
|
+
return transformPassScope.run(lease, () => {
|
|
449
|
+
try {
|
|
450
|
+
const result = operation();
|
|
451
|
+
if (result && typeof result.then === "function") {
|
|
452
|
+
return Promise.resolve(result).finally(() => {
|
|
453
|
+
lease.active = false;
|
|
454
|
+
release();
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
lease.active = false;
|
|
458
|
+
release();
|
|
459
|
+
return result;
|
|
460
|
+
} catch (error) {
|
|
461
|
+
lease.active = false;
|
|
462
|
+
release();
|
|
463
|
+
throw error;
|
|
289
464
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
lease.active = false;
|
|
294
|
-
throw error;
|
|
295
|
-
}
|
|
296
|
-
});
|
|
465
|
+
});
|
|
466
|
+
};
|
|
467
|
+
return typeof reservation === "function" ? run(reservation) : reservation.then(run);
|
|
297
468
|
}
|
|
298
|
-
function
|
|
469
|
+
function withoutSqliteTransformPass2(operation) {
|
|
299
470
|
return transformPassScope.run(undefined, operation);
|
|
300
471
|
}
|
|
301
|
-
function
|
|
472
|
+
function guardSqliteTransformPass2(guard) {
|
|
473
|
+
const lease = transformPassScope.getStore();
|
|
474
|
+
if (lease)
|
|
475
|
+
lease.guard = guard;
|
|
476
|
+
}
|
|
477
|
+
function assertTransformWrite2() {
|
|
478
|
+
if (!backgroundWriterScope.getStore())
|
|
479
|
+
transformPassScope.getStore()?.guard?.assert();
|
|
480
|
+
}
|
|
481
|
+
function isTransientSqliteError2(error) {
|
|
302
482
|
if (!error || typeof error !== "object")
|
|
303
483
|
return false;
|
|
304
484
|
const value = error;
|
|
@@ -316,6 +496,7 @@ class SqliteAcquisitionBusyError extends Error {
|
|
|
316
496
|
}
|
|
317
497
|
var SHORT_BUSY_TIMEOUT_MS = 25;
|
|
318
498
|
var FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS = 250;
|
|
499
|
+
var FOREGROUND_ACQUISITION_BUDGET_MS = 16500;
|
|
319
500
|
var SLOW_WRITER_LOG_MS = 250;
|
|
320
501
|
var WRITER_TRANSACTION_END = /^\s*(?:COMMIT|END|ROLLBACK)(?:\s+TRANSACTION)?\s*;?\s*$/i;
|
|
321
502
|
var writerAcquisitionScope = new AsyncLocalStorage;
|
|
@@ -325,6 +506,7 @@ function foregroundWaitLease() {
|
|
|
325
506
|
return lease?.active && !admissionScope.getStore() && !backgroundWriterScope.getStore() ? lease : undefined;
|
|
326
507
|
}
|
|
327
508
|
function withAutocommitTimeout(db, operation) {
|
|
509
|
+
assertTransformWrite2();
|
|
328
510
|
const lease = foregroundWaitLease();
|
|
329
511
|
if (isInTransaction(db) || !lease && !backgroundWriterScope.getStore())
|
|
330
512
|
return operation();
|
|
@@ -334,7 +516,7 @@ function withAutocommitTimeout(db, operation) {
|
|
|
334
516
|
try {
|
|
335
517
|
return operation();
|
|
336
518
|
} catch (error) {
|
|
337
|
-
if (lease &&
|
|
519
|
+
if (lease && isTransientSqliteError2(error))
|
|
338
520
|
throw new SqliteAcquisitionBusyError(error, "autocommit");
|
|
339
521
|
throw error;
|
|
340
522
|
} finally {
|
|
@@ -345,6 +527,7 @@ function withAutocommitTimeout(db, operation) {
|
|
|
345
527
|
}
|
|
346
528
|
}
|
|
347
529
|
function acquireShort(db, acquire, site) {
|
|
530
|
+
assertTransformWrite2();
|
|
348
531
|
const started = performance.now();
|
|
349
532
|
const previous = pragmaNumber(db, "busy_timeout");
|
|
350
533
|
const outer = writerAcquisitionScope.getStore();
|
|
@@ -356,12 +539,12 @@ function acquireShort(db, acquire, site) {
|
|
|
356
539
|
let acquiredAt;
|
|
357
540
|
try {
|
|
358
541
|
const lease = foregroundWaitLease();
|
|
359
|
-
const timeout =
|
|
542
|
+
const timeout = Math.floor(Math.min(lease ? lease.remainingWaitMs : SHORT_BUSY_TIMEOUT_MS, owner?.remainingMs?.() ?? lease?.guard?.remainingMs() ?? Infinity));
|
|
360
543
|
db.exec(`PRAGMA busy_timeout=${timeout}`);
|
|
361
544
|
acquire();
|
|
362
545
|
acquiredAt = performance.now();
|
|
363
546
|
} catch (error) {
|
|
364
|
-
if (transformPassScope.getStore()?.active &&
|
|
547
|
+
if (transformPassScope.getStore()?.active && isTransientSqliteError2(error))
|
|
365
548
|
throw new SqliteAcquisitionBusyError(error, site);
|
|
366
549
|
throw error;
|
|
367
550
|
} finally {
|
|
@@ -386,27 +569,106 @@ function acquireShort(db, acquire, site) {
|
|
|
386
569
|
}
|
|
387
570
|
function endWriterTransaction(db, end, sql) {
|
|
388
571
|
let ended = false;
|
|
572
|
+
const endStarted = performance.now();
|
|
389
573
|
try {
|
|
390
574
|
const result = end();
|
|
391
575
|
ended = true;
|
|
392
576
|
return result;
|
|
393
577
|
} finally {
|
|
394
578
|
const open = openWriterTransactions.get(db);
|
|
579
|
+
const endMs = performance.now() - endStarted;
|
|
395
580
|
if (open && !isInTransaction(db)) {
|
|
396
581
|
openWriterTransactions.delete(db);
|
|
397
582
|
const holdMs = performance.now() - open.acquiredAt;
|
|
398
583
|
if (open.acquireMs >= SLOW_WRITER_LOG_MS || holdMs >= SLOW_WRITER_LOG_MS) {
|
|
399
584
|
const outcome = /^\s*ROLLBACK/i.test(sql) ? "rolled_back" : ended ? "committed" : "failed";
|
|
400
|
-
reportSqliteDiagnostic(`sqlite writer site=${open.site} lane=${open.lane} acquire_ms=${Math.round(open.acquireMs)} hold_ms=${Math.round(holdMs)} attempts=${open.attempts} outcome=${outcome}`);
|
|
585
|
+
reportSqliteDiagnostic(`sqlite writer site=${open.site} lane=${open.lane} acquire_ms=${Math.round(open.acquireMs)} hold_ms=${Math.round(holdMs)} end_ms=${Math.round(endMs)} attempts=${open.attempts} outcome=${outcome}`);
|
|
401
586
|
}
|
|
402
587
|
}
|
|
403
588
|
}
|
|
404
589
|
}
|
|
590
|
+
async function beginSqliteWriterAsync2(db, site) {
|
|
591
|
+
const started = performance.now();
|
|
592
|
+
let attempts = 0;
|
|
593
|
+
for (;; ) {
|
|
594
|
+
attempts++;
|
|
595
|
+
try {
|
|
596
|
+
const acquisition = {
|
|
597
|
+
site,
|
|
598
|
+
lane: "background",
|
|
599
|
+
startedAt: started,
|
|
600
|
+
attempts,
|
|
601
|
+
claimed: false
|
|
602
|
+
};
|
|
603
|
+
writerAcquisitionScope.run(acquisition, () => withSqliteBackgroundWriter2(() => db.exec("BEGIN IMMEDIATE")));
|
|
604
|
+
return performance.now();
|
|
605
|
+
} catch (error) {
|
|
606
|
+
if (!isTransientSqliteError2(error))
|
|
607
|
+
throw error;
|
|
608
|
+
const elapsed = performance.now() - started;
|
|
609
|
+
if (elapsed >= FOREGROUND_ACQUISITION_BUDGET_MS) {
|
|
610
|
+
reportSqliteDiagnostic(`sqlite writer site=${site} lane=background acquire_ms=${Math.round(elapsed)} attempts=${attempts} outcome=busy`);
|
|
611
|
+
throw error;
|
|
612
|
+
}
|
|
613
|
+
await new Promise((resolve) => setTimeout(resolve, Math.min(attempts === 1 ? 500 : 1000, FOREGROUND_ACQUISITION_BUDGET_MS - elapsed)));
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
async function withAsyncPrivilegedWriter2(db, operation, options = {}) {
|
|
618
|
+
const started = performance.now();
|
|
619
|
+
const budgetMs = Math.max(0, Math.min(FOREGROUND_ACQUISITION_BUDGET_MS, options.budgetMs ?? Infinity));
|
|
620
|
+
let attempts = 0;
|
|
621
|
+
for (;; ) {
|
|
622
|
+
options.signal?.throwIfAborted();
|
|
623
|
+
options.assertCurrentPass?.();
|
|
624
|
+
attempts++;
|
|
625
|
+
let entered = false;
|
|
626
|
+
try {
|
|
627
|
+
const acquisition = {
|
|
628
|
+
site: "privileged_writer",
|
|
629
|
+
lane: "foreground",
|
|
630
|
+
startedAt: started,
|
|
631
|
+
attempts,
|
|
632
|
+
claimed: false,
|
|
633
|
+
remainingMs: () => Math.max(0, budgetMs - (performance.now() - started))
|
|
634
|
+
};
|
|
635
|
+
return admissionScope.run(true, () => withSqliteTransformPass2(() => writerAcquisitionScope.run(acquisition, () => withPrivilegedWriter2(db, () => {
|
|
636
|
+
entered = true;
|
|
637
|
+
return operation();
|
|
638
|
+
}))));
|
|
639
|
+
} catch (error) {
|
|
640
|
+
if (entered || !(error instanceof SqliteAcquisitionBusyError))
|
|
641
|
+
throw error;
|
|
642
|
+
options.beforeRetry?.(error);
|
|
643
|
+
const elapsed = performance.now() - started;
|
|
644
|
+
if (elapsed >= budgetMs) {
|
|
645
|
+
reportSqliteDiagnostic(`sqlite writer site=privileged_writer lane=foreground acquire_ms=${Math.round(elapsed)} attempts=${attempts} outcome=busy`);
|
|
646
|
+
throw error;
|
|
647
|
+
}
|
|
648
|
+
const backoff = attempts === 1 ? 500 : 1000;
|
|
649
|
+
const delay = Math.min(options.jitter ? backoff * (0.8 + Math.random() * 0.4) : backoff, budgetMs - elapsed);
|
|
650
|
+
await new Promise((resolve, reject) => {
|
|
651
|
+
const abort = () => {
|
|
652
|
+
clearTimeout(timer);
|
|
653
|
+
options.signal?.removeEventListener("abort", abort);
|
|
654
|
+
reject(options.signal?.reason ?? new Error("Writer wait aborted"));
|
|
655
|
+
};
|
|
656
|
+
const timer = setTimeout(() => {
|
|
657
|
+
options.signal?.removeEventListener("abort", abort);
|
|
658
|
+
resolve();
|
|
659
|
+
}, delay);
|
|
660
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
661
|
+
if (options.signal?.aborted)
|
|
662
|
+
abort();
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
405
667
|
function isInTransaction(db) {
|
|
406
668
|
const candidate = db;
|
|
407
669
|
return candidate.inTransaction === true || candidate.isTransaction === true;
|
|
408
670
|
}
|
|
409
|
-
function
|
|
671
|
+
function withPrivilegedWriter2(db, operation) {
|
|
410
672
|
const previousDepth = privilegeDepth.get(db) ?? 0;
|
|
411
673
|
const nested = isInTransaction(db);
|
|
412
674
|
const savepoint = "mc_privilege_scope";
|
|
@@ -417,7 +679,7 @@ function withPrivilegedWriter(db, operation) {
|
|
|
417
679
|
try {
|
|
418
680
|
db.exec("BEGIN IMMEDIATE");
|
|
419
681
|
} catch (error) {
|
|
420
|
-
if (transformPassScope.getStore()?.active &&
|
|
682
|
+
if (transformPassScope.getStore()?.active && isTransientSqliteError2(error))
|
|
421
683
|
throw new SqliteAcquisitionBusyError(error);
|
|
422
684
|
throw error;
|
|
423
685
|
}
|
|
@@ -460,5 +722,59 @@ function withPrivilegedWriter(db, operation) {
|
|
|
460
722
|
throw error;
|
|
461
723
|
}
|
|
462
724
|
}
|
|
725
|
+
var indexCoordinationKey = Symbol.for("magic-context.index-foreground-coordination.v1");
|
|
726
|
+
var indexCoordinationHeap = globalThis;
|
|
727
|
+
var indexCoordinationBuffer = indexCoordinationHeap[indexCoordinationKey] ?? new SharedArrayBuffer(3 * Int32Array.BYTES_PER_ELEMENT);
|
|
728
|
+
indexCoordinationHeap[indexCoordinationKey] = indexCoordinationBuffer;
|
|
729
|
+
var indexCoordinationState = new Int32Array(indexCoordinationBuffer);
|
|
730
|
+
function indexCoordinationInput2() {
|
|
731
|
+
return {
|
|
732
|
+
indexCoordination: indexCoordinationBuffer,
|
|
733
|
+
indexOwner: Atomics.add(indexCoordinationState, 2, 1) + 1
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
var yieldIndexTurn = () => new Promise((resolve) => setTimeout(resolve, 1));
|
|
737
|
+
function reserveForegroundSqliteTurn() {
|
|
738
|
+
Atomics.add(indexCoordinationState, 0, 1);
|
|
739
|
+
const release = () => {
|
|
740
|
+
Atomics.sub(indexCoordinationState, 0, 1);
|
|
741
|
+
Atomics.notify(indexCoordinationState, 0);
|
|
742
|
+
};
|
|
743
|
+
if (Atomics.load(indexCoordinationState, 1) === 0)
|
|
744
|
+
return release;
|
|
745
|
+
return (async () => {
|
|
746
|
+
while (Atomics.load(indexCoordinationState, 1) !== 0)
|
|
747
|
+
await yieldIndexTurn();
|
|
748
|
+
return release;
|
|
749
|
+
})();
|
|
750
|
+
}
|
|
751
|
+
function releaseIndexOwner2(input) {
|
|
752
|
+
if (!input.indexCoordination || !input.indexOwner)
|
|
753
|
+
return;
|
|
754
|
+
const shared = new Int32Array(input.indexCoordination);
|
|
755
|
+
Atomics.compareExchange(shared, 1, input.indexOwner, 0);
|
|
756
|
+
Atomics.notify(shared, 1);
|
|
757
|
+
}
|
|
758
|
+
async function withIndexChunk2(input, operation) {
|
|
759
|
+
if (!input.indexCoordination || !input.indexOwner)
|
|
760
|
+
return operation();
|
|
761
|
+
const shared = new Int32Array(input.indexCoordination);
|
|
762
|
+
for (;; ) {
|
|
763
|
+
if (Atomics.load(shared, 0) === 0 && Atomics.compareExchange(shared, 1, 0, input.indexOwner) === 0) {
|
|
764
|
+
if (Atomics.load(shared, 0) === 0)
|
|
765
|
+
break;
|
|
766
|
+
releaseIndexOwner2(input);
|
|
767
|
+
}
|
|
768
|
+
await yieldIndexTurn();
|
|
769
|
+
}
|
|
770
|
+
try {
|
|
771
|
+
return await operation();
|
|
772
|
+
} finally {
|
|
773
|
+
releaseIndexOwner2(input);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
async function yieldIndexChunk2() {
|
|
777
|
+
await yieldIndexTurn();
|
|
778
|
+
}
|
|
463
779
|
|
|
464
|
-
export {
|
|
780
|
+
export { registerSlowWriteReporter2, registerSqliteDiagnosticSink2, detectSqliteRuntime2, getTagIdentityWriteGeneration2, Database2, getSqliteDatabasePath2, prepareCachedStatement2, withSqliteBackgroundWriter2, withSqliteTransformPass2, withoutSqliteTransformPass2, guardSqliteTransformPass2, assertTransformWrite2, isTransientSqliteError2, beginSqliteWriterAsync2, withAsyncPrivilegedWriter2, withPrivilegedWriter2, indexCoordinationInput2, releaseIndexOwner2, withIndexChunk2, yieldIndexChunk2 };
|