@cortexkit/pi-magic-context 0.47.0 → 0.49.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 +27 -22
- package/dist/embedding-activity-ew6dshfd.js +10 -0
- package/dist/embedding-backfill-b71dvfs8.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 +30 -4
- package/dist/index-041ex0cj.js +519 -0
- package/dist/index-0h2mkab2.js +17 -0
- package/dist/{index-2p1e8706.js → index-0vrkp1jq.js} +3 -3
- package/dist/index-135e8hvg.js +43 -0
- package/dist/{index-vgcemg0n.js → index-1evzceyw.js} +151 -2452
- package/dist/index-21v1kfs7.js +2309 -0
- package/dist/{index-n3g5mwa8.js → index-290tzwp1.js} +3 -3
- package/dist/{index-0qejsd7f.js → index-3cgbv47m.js} +289 -45
- package/dist/{index-xpbh1ypk.js → index-3mgf68pn.js} +38 -741
- package/dist/index-3rea6zd9.js +2396 -0
- package/dist/index-674f6qs2.js +16 -0
- package/dist/index-8976mezv.js +209 -0
- package/dist/index-904reqtg.js +152 -0
- package/dist/index-9p40dgkm.js +22 -0
- package/dist/index-9x1f96r8.js +11 -0
- package/dist/index-bejpsj10.js +1060 -0
- package/dist/{index-spk5vrhy.js → index-bgmv2kaf.js} +1 -16
- package/dist/{index-k3ezsjng.js → index-ehybv5nr.js} +14657 -13951
- package/dist/index-fapenpch.js +13 -0
- package/dist/index-hwqb3s7f.js +3804 -0
- package/dist/index-kjd1fj55.js +3106 -0
- package/dist/{index-td885aah.js → index-mcgehvgw.js} +181 -230
- package/dist/index-r024r8da.js +171 -0
- package/dist/{index-266qrgss.js → index-r56xgha8.js} +301 -27
- package/dist/{index-kztsbkqq.js → index-t7xfqtg6.js} +171 -168
- package/dist/index-vakawmbc.js +1262 -0
- package/dist/{index-7n8gb6j3.js → index-x3dcnxh0.js} +34 -33
- package/dist/index-xjqheg7a.js +931 -0
- package/dist/index-yarjn32j.js +3026 -0
- package/dist/index-yhzhdp3m.js +143 -0
- package/dist/index-yzcjxnt2.js +787 -0
- package/dist/{index-w76x3af7.js → index-zh1jw8qp.js} +107 -4
- package/dist/index.js +4926 -2437
- package/dist/logger-j6tecd1h.js +19 -0
- package/dist/message-index-bounded-qz5dz2se.js +120 -0
- package/dist/{message-time-backfill-d3db2etr.js → message-time-backfill-05ppypkz.js} +7 -6
- package/dist/migration-worker.js +20 -14
- package/dist/project-embedding-registry-ky7wrkr1.js +85 -0
- package/dist/raw-ordinal-warmup-worker.js +60 -0
- package/dist/{read-session-chunk-atxsyfqv.js → read-session-chunk-24sd89tf.js} +14 -6
- package/dist/read-session-raw-npx3920c.js +57 -0
- package/dist/{safe-notification-target-6cn3z99t.js → safe-notification-target-vn9kpmv4.js} +3 -2
- package/dist/search-jbh28nwy.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-kjnsqbdb.js +127 -0
- package/dist/subagent-entry.js +35 -17
- package/dist/transformers-node-wasm.js +18415 -18415
- package/package.json +3 -3
- package/dist/index-7s8vw2y0.js +0 -5207
- package/dist/index-qaa5j277.js +0 -8544
- /package/dist/{index-en1k8h8m.js → index-5prbx026.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./index-
|
|
2
|
+
log2
|
|
3
|
+
} from "./index-x3dcnxh0.js";
|
|
4
4
|
|
|
5
5
|
// ../plugin/src/shared/safe-notification-target.ts
|
|
6
6
|
var DEFAULT_TITLE_RE = /^(New session - |Child session - )\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
|
|
@@ -33,7 +33,7 @@ async function waitForSafeNotificationTarget2(client, sessionId, options) {
|
|
|
33
33
|
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
log2(`[magic-context] notification skipped: session ${sessionId} still has its default title (would suppress title generation); will retry on a later startup`);
|
|
37
37
|
return "skip";
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -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,12 +78,87 @@ 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", {
|
|
@@ -70,7 +166,7 @@ function installTransactionRouting(db, readonly) {
|
|
|
70
166
|
writable: true,
|
|
71
167
|
value: (sql) => {
|
|
72
168
|
if (/^\s*(?:COMMIT|END)\b/i.test(sql))
|
|
73
|
-
|
|
169
|
+
assertTransformWrite2();
|
|
74
170
|
if (/^\s*BEGIN\s+(?:IMMEDIATE|EXCLUSIVE)(?:\s+TRANSACTION)?\s*;?\s*$/i.test(sql)) {
|
|
75
171
|
openWriterTransactions.delete(db);
|
|
76
172
|
if (transformPassScope.getStore()?.active || backgroundWriterScope.getStore())
|
|
@@ -81,8 +177,14 @@ function installTransactionRouting(db, readonly) {
|
|
|
81
177
|
}
|
|
82
178
|
if (WRITER_TRANSACTION_END.test(sql) && openWriterTransactions.has(db))
|
|
83
179
|
return endWriterTransaction(db, () => nativeExec(sql), sql);
|
|
84
|
-
if (!/^\s*(?:SELECT|EXPLAIN|PRAGMA|COMMIT|END|ROLLBACK|SAVEPOINT|RELEASE)\b/i.test(sql))
|
|
85
|
-
|
|
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
|
+
}
|
|
86
188
|
return nativeExec(sql);
|
|
87
189
|
}
|
|
88
190
|
});
|
|
@@ -93,13 +195,23 @@ function installTransactionRouting(db, readonly) {
|
|
|
93
195
|
value: (sql) => {
|
|
94
196
|
const statement = nativePrepare(sql);
|
|
95
197
|
if (!readonly && !/^\s*(?:SELECT|EXPLAIN|PRAGMA)\b/i.test(sql)) {
|
|
198
|
+
const changesTagIdentity = mayChangeTagIdentity(sql);
|
|
96
199
|
for (const method of ["run", "get", "all"]) {
|
|
97
200
|
const execute = statement[method].bind(statement);
|
|
98
201
|
Object.defineProperty(statement, method, {
|
|
99
202
|
configurable: true,
|
|
100
|
-
value: (...args) =>
|
|
203
|
+
value: (...args) => {
|
|
204
|
+
try {
|
|
205
|
+
return withAutocommitTimeout(db, () => execute(...args));
|
|
206
|
+
} finally {
|
|
207
|
+
if (changesTagIdentity)
|
|
208
|
+
tagIdentityWriteGeneration += 1;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
101
211
|
});
|
|
102
212
|
}
|
|
213
|
+
if (changesTagIdentity)
|
|
214
|
+
wrapRemainingTagWriteForms(statement);
|
|
103
215
|
}
|
|
104
216
|
return statement;
|
|
105
217
|
}
|
|
@@ -147,6 +259,35 @@ function installTransactionRouting(db, readonly) {
|
|
|
147
259
|
}
|
|
148
260
|
});
|
|
149
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
|
+
}
|
|
150
291
|
function trackSqliteConnection(db, filename, options) {
|
|
151
292
|
const originalClose = db.close.bind(db);
|
|
152
293
|
const sequence = nextSqliteConnectionSequence++;
|
|
@@ -206,13 +347,17 @@ function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
|
206
347
|
}
|
|
207
348
|
return NodeSqliteDatabase;
|
|
208
349
|
}
|
|
209
|
-
var
|
|
210
|
-
function
|
|
350
|
+
var Database2 = TrackedDatabase;
|
|
351
|
+
function getSqliteDatabasePath2(db) {
|
|
211
352
|
for (const connection of trackedSqliteConnections.values()) {
|
|
212
353
|
if (connection.reference.deref() === db) {
|
|
213
354
|
return connection.filename === ":memory:" || connection.filename === "<buffer>" ? null : connection.filename;
|
|
214
355
|
}
|
|
215
356
|
}
|
|
357
|
+
const native = db;
|
|
358
|
+
const path = native.filename ?? native.name;
|
|
359
|
+
if (typeof path === "string" && path !== ":memory:" && path !== "")
|
|
360
|
+
return path;
|
|
216
361
|
return null;
|
|
217
362
|
}
|
|
218
363
|
function pragmaValue(db, name) {
|
|
@@ -231,6 +376,15 @@ function pragmaNumber(db, name) {
|
|
|
231
376
|
}
|
|
232
377
|
var statementOwners = new WeakMap;
|
|
233
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
|
+
}
|
|
234
388
|
function ownPreparedStatement(db, statement) {
|
|
235
389
|
const finalizable = statement;
|
|
236
390
|
if (typeof finalizable.finalize !== "function")
|
|
@@ -254,7 +408,7 @@ function ownPreparedStatement(db, statement) {
|
|
|
254
408
|
}
|
|
255
409
|
}
|
|
256
410
|
references.clear();
|
|
257
|
-
const result = close
|
|
411
|
+
const result = closeReleasingStatements(close, args);
|
|
258
412
|
if (failure)
|
|
259
413
|
throw failure;
|
|
260
414
|
return result;
|
|
@@ -274,50 +428,57 @@ function ownPreparedStatement(db, statement) {
|
|
|
274
428
|
}
|
|
275
429
|
return statement;
|
|
276
430
|
}
|
|
277
|
-
function
|
|
431
|
+
function prepareCachedStatement2(db, sql) {
|
|
278
432
|
return ownPreparedStatement(db, db.prepare(sql));
|
|
279
433
|
}
|
|
280
434
|
var privilegeDepth = new WeakMap;
|
|
281
435
|
var transformPassScope = new AsyncLocalStorage;
|
|
282
436
|
var admissionScope = new AsyncLocalStorage;
|
|
283
437
|
var backgroundWriterScope = new AsyncLocalStorage;
|
|
284
|
-
function
|
|
438
|
+
function withSqliteBackgroundWriter2(operation) {
|
|
285
439
|
return backgroundWriterScope.run(true, operation);
|
|
286
440
|
}
|
|
287
|
-
function
|
|
441
|
+
function withSqliteTransformPass2(operation) {
|
|
288
442
|
const existing = transformPassScope.getStore();
|
|
289
443
|
if (existing?.active)
|
|
290
444
|
return operation();
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
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;
|
|
299
464
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
lease.active = false;
|
|
304
|
-
throw error;
|
|
305
|
-
}
|
|
306
|
-
});
|
|
465
|
+
});
|
|
466
|
+
};
|
|
467
|
+
return typeof reservation === "function" ? run(reservation) : reservation.then(run);
|
|
307
468
|
}
|
|
308
|
-
function
|
|
469
|
+
function withoutSqliteTransformPass2(operation) {
|
|
309
470
|
return transformPassScope.run(undefined, operation);
|
|
310
471
|
}
|
|
311
|
-
function
|
|
472
|
+
function guardSqliteTransformPass2(guard) {
|
|
312
473
|
const lease = transformPassScope.getStore();
|
|
313
474
|
if (lease)
|
|
314
475
|
lease.guard = guard;
|
|
315
476
|
}
|
|
316
|
-
function
|
|
477
|
+
function assertTransformWrite2() {
|
|
317
478
|
if (!backgroundWriterScope.getStore())
|
|
318
479
|
transformPassScope.getStore()?.guard?.assert();
|
|
319
480
|
}
|
|
320
|
-
function
|
|
481
|
+
function isTransientSqliteError2(error) {
|
|
321
482
|
if (!error || typeof error !== "object")
|
|
322
483
|
return false;
|
|
323
484
|
const value = error;
|
|
@@ -345,7 +506,7 @@ function foregroundWaitLease() {
|
|
|
345
506
|
return lease?.active && !admissionScope.getStore() && !backgroundWriterScope.getStore() ? lease : undefined;
|
|
346
507
|
}
|
|
347
508
|
function withAutocommitTimeout(db, operation) {
|
|
348
|
-
|
|
509
|
+
assertTransformWrite2();
|
|
349
510
|
const lease = foregroundWaitLease();
|
|
350
511
|
if (isInTransaction(db) || !lease && !backgroundWriterScope.getStore())
|
|
351
512
|
return operation();
|
|
@@ -355,7 +516,7 @@ function withAutocommitTimeout(db, operation) {
|
|
|
355
516
|
try {
|
|
356
517
|
return operation();
|
|
357
518
|
} catch (error) {
|
|
358
|
-
if (lease &&
|
|
519
|
+
if (lease && isTransientSqliteError2(error))
|
|
359
520
|
throw new SqliteAcquisitionBusyError(error, "autocommit");
|
|
360
521
|
throw error;
|
|
361
522
|
} finally {
|
|
@@ -366,7 +527,7 @@ function withAutocommitTimeout(db, operation) {
|
|
|
366
527
|
}
|
|
367
528
|
}
|
|
368
529
|
function acquireShort(db, acquire, site) {
|
|
369
|
-
|
|
530
|
+
assertTransformWrite2();
|
|
370
531
|
const started = performance.now();
|
|
371
532
|
const previous = pragmaNumber(db, "busy_timeout");
|
|
372
533
|
const outer = writerAcquisitionScope.getStore();
|
|
@@ -383,7 +544,7 @@ function acquireShort(db, acquire, site) {
|
|
|
383
544
|
acquire();
|
|
384
545
|
acquiredAt = performance.now();
|
|
385
546
|
} catch (error) {
|
|
386
|
-
if (transformPassScope.getStore()?.active &&
|
|
547
|
+
if (transformPassScope.getStore()?.active && isTransientSqliteError2(error))
|
|
387
548
|
throw new SqliteAcquisitionBusyError(error, site);
|
|
388
549
|
throw error;
|
|
389
550
|
} finally {
|
|
@@ -408,23 +569,52 @@ function acquireShort(db, acquire, site) {
|
|
|
408
569
|
}
|
|
409
570
|
function endWriterTransaction(db, end, sql) {
|
|
410
571
|
let ended = false;
|
|
572
|
+
const endStarted = performance.now();
|
|
411
573
|
try {
|
|
412
574
|
const result = end();
|
|
413
575
|
ended = true;
|
|
414
576
|
return result;
|
|
415
577
|
} finally {
|
|
416
578
|
const open = openWriterTransactions.get(db);
|
|
579
|
+
const endMs = performance.now() - endStarted;
|
|
417
580
|
if (open && !isInTransaction(db)) {
|
|
418
581
|
openWriterTransactions.delete(db);
|
|
419
582
|
const holdMs = performance.now() - open.acquiredAt;
|
|
420
583
|
if (open.acquireMs >= SLOW_WRITER_LOG_MS || holdMs >= SLOW_WRITER_LOG_MS) {
|
|
421
584
|
const outcome = /^\s*ROLLBACK/i.test(sql) ? "rolled_back" : ended ? "committed" : "failed";
|
|
422
|
-
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}`);
|
|
423
586
|
}
|
|
424
587
|
}
|
|
425
588
|
}
|
|
426
589
|
}
|
|
427
|
-
async function
|
|
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 = {}) {
|
|
428
618
|
const started = performance.now();
|
|
429
619
|
const budgetMs = Math.max(0, Math.min(FOREGROUND_ACQUISITION_BUDGET_MS, options.budgetMs ?? Infinity));
|
|
430
620
|
let attempts = 0;
|
|
@@ -442,7 +632,7 @@ async function withAsyncPrivilegedWriter(db, operation, options = {}) {
|
|
|
442
632
|
claimed: false,
|
|
443
633
|
remainingMs: () => Math.max(0, budgetMs - (performance.now() - started))
|
|
444
634
|
};
|
|
445
|
-
return admissionScope.run(true, () =>
|
|
635
|
+
return admissionScope.run(true, () => withSqliteTransformPass2(() => writerAcquisitionScope.run(acquisition, () => withPrivilegedWriter2(db, () => {
|
|
446
636
|
entered = true;
|
|
447
637
|
return operation();
|
|
448
638
|
}))));
|
|
@@ -478,7 +668,7 @@ function isInTransaction(db) {
|
|
|
478
668
|
const candidate = db;
|
|
479
669
|
return candidate.inTransaction === true || candidate.isTransaction === true;
|
|
480
670
|
}
|
|
481
|
-
function
|
|
671
|
+
function withPrivilegedWriter2(db, operation) {
|
|
482
672
|
const previousDepth = privilegeDepth.get(db) ?? 0;
|
|
483
673
|
const nested = isInTransaction(db);
|
|
484
674
|
const savepoint = "mc_privilege_scope";
|
|
@@ -489,7 +679,7 @@ function withPrivilegedWriter(db, operation) {
|
|
|
489
679
|
try {
|
|
490
680
|
db.exec("BEGIN IMMEDIATE");
|
|
491
681
|
} catch (error) {
|
|
492
|
-
if (transformPassScope.getStore()?.active &&
|
|
682
|
+
if (transformPassScope.getStore()?.active && isTransientSqliteError2(error))
|
|
493
683
|
throw new SqliteAcquisitionBusyError(error);
|
|
494
684
|
throw error;
|
|
495
685
|
}
|
|
@@ -532,5 +722,59 @@ function withPrivilegedWriter(db, operation) {
|
|
|
532
722
|
throw error;
|
|
533
723
|
}
|
|
534
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
|
+
}
|
|
535
779
|
|
|
536
|
-
export {
|
|
780
|
+
export { registerSlowWriteReporter2, registerSqliteDiagnosticSink2, detectSqliteRuntime2, getTagIdentityWriteGeneration2, Database2, getSqliteDatabasePath2, prepareCachedStatement2, withSqliteBackgroundWriter2, withSqliteTransformPass2, withoutSqliteTransformPass2, guardSqliteTransformPass2, assertTransformWrite2, isTransientSqliteError2, beginSqliteWriterAsync2, withAsyncPrivilegedWriter2, withPrivilegedWriter2, indexCoordinationInput2, releaseIndexOwner2, withIndexChunk2, yieldIndexChunk2 };
|