@retaw106/mmc-oc 2.2.0 → 2.3.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/cli.js +2 -2
- package/dist/config/deprecated-config.d.ts +4 -0
- package/dist/config/deprecated-config.d.ts.map +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +2 -2
- package/dist/config/schema/magic-context.d.ts +3 -3
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/config-init.js +2 -2
- package/dist/{context-mrvm92n8.js → context-wt7g4f8k.js} +1641 -1543
- package/dist/{derive-budgets-rjjz5f7y.js → derive-budgets-s1p37t2g.js} +2 -2
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/historian-failure-reason.d.ts +7 -0
- package/dist/features/magic-context/historian-failure-reason.d.ts.map +1 -0
- package/dist/features/magic-context/message-index-async.d.ts +21 -3
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/message-index.d.ts +7 -1
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/pi-content-decisions.d.ts +7 -1
- package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -1
- package/dist/features/magic-context/search.d.ts +29 -0
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/storage-clone.d.ts +2 -0
- package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
- package/dist/features/magic-context/storage-compartment-history-version.d.ts +4 -0
- package/dist/features/magic-context/storage-compartment-history-version.d.ts.map +1 -0
- package/dist/features/magic-context/storage-db.d.ts +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-historian-runs.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +23 -5
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts +7 -1
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-session-tables.d.ts +5 -1
- package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tag-identity-revision.d.ts +50 -0
- package/dist/features/magic-context/storage-tag-identity-revision.d.ts.map +1 -0
- package/dist/features/magic-context/storage-tags.d.ts +155 -5
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/tagger.d.ts +2 -0
- package/dist/features/magic-context/tagger.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts +3 -0
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
- package/dist/hooks/magic-context/active-anthropic-turn.d.ts +2 -0
- package/dist/hooks/magic-context/active-anthropic-turn.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts +7 -0
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-runner.d.ts +2 -2
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/history-boundary-repair.d.ts +11 -2
- package/dist/hooks/magic-context/history-boundary-repair.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-measured-request.d.ts +3 -1
- package/dist/hooks/magic-context/lkg-measured-request.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-persist.d.ts +10 -13
- package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-recovery-fence.d.ts +62 -0
- package/dist/hooks/magic-context/lkg-recovery-fence.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-recovery-prefix.d.ts +38 -0
- package/dist/hooks/magic-context/lkg-recovery-prefix.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-replay.d.ts +16 -9
- package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts +141 -2
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/opaque-thinking.d.ts +12 -0
- package/dist/hooks/magic-context/opaque-thinking.d.ts.map +1 -0
- package/dist/hooks/magic-context/pass-outcome.d.ts +1 -0
- package/dist/hooks/magic-context/pass-outcome.d.ts.map +1 -1
- package/dist/hooks/magic-context/pending-materialization.d.ts +8 -0
- package/dist/hooks/magic-context/pending-materialization.d.ts.map +1 -0
- package/dist/hooks/magic-context/postprocess-read-cache.d.ts.map +1 -1
- package/dist/hooks/magic-context/provider-visible-parts.d.ts +45 -0
- package/dist/hooks/magic-context/provider-visible-parts.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts +22 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts +3 -0
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts +5 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +123 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
- package/dist/hooks/magic-context/reasoning-budget.d.ts.map +1 -1
- package/dist/hooks/magic-context/sentinel.d.ts +41 -1
- package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
- package/dist/hooks/magic-context/strict-thinking-prefix.d.ts +8 -0
- package/dist/hooks/magic-context/strict-thinking-prefix.d.ts.map +1 -0
- package/dist/hooks/magic-context/strip-content.d.ts +38 -24
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-date-refresh.d.ts +29 -0
- package/dist/hooks/magic-context/system-date-refresh.d.ts.map +1 -0
- package/dist/hooks/magic-context/system-prompt-dates.d.ts +6 -0
- package/dist/hooks/magic-context/system-prompt-dates.d.ts.map +1 -0
- package/dist/hooks/magic-context/system-prompt-delivery.d.ts +47 -0
- package/dist/hooks/magic-context/system-prompt-delivery.d.ts.map +1 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +18 -5
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +19 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-owner-warmup.d.ts +14 -0
- package/dist/hooks/magic-context/tag-owner-warmup.d.ts.map +1 -0
- package/dist/hooks/magic-context/token-count-exact.d.ts +35 -0
- package/dist/hooks/magic-context/token-count-exact.d.ts.map +1 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts +2 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +7 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +21 -4
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index-18yrysyj.js +1477 -0
- package/dist/{index-g2z2k5m4.js → index-3gj1ak4c.js} +2 -2
- package/dist/{index-5cep2r9n.js → index-5ty9rnbx.js} +60 -258
- package/dist/{index-amycb7b1.js → index-a5mw0xp3.js} +3 -3
- package/dist/{index-1j34a56j.js → index-czba8tw3.js} +266 -32
- package/dist/{index-qbkzdkk0.js → index-k59af64t.js} +6 -2
- package/dist/{index-53g38ggt.js → index-kmbme1v1.js} +1 -1
- package/dist/{index-5b7x80ec.js → index-kw21z5pe.js} +6055 -3973
- package/dist/{index-33gprt9g.js → index-yjv8dpht.js} +1 -1
- package/dist/{index-btp5tdc8.js → index-z2w1eq3y.js} +840 -456
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +114 -2
- package/dist/{message-time-backfill-phrwp2fz.js → message-time-backfill-sykevdax.js} +3 -3
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/{read-session-chunk-2xm4sc4y.js → read-session-chunk-863d6c06.js} +6 -4
- package/dist/recomp-orchestrator-wrjy3qym.js +21 -0
- package/dist/{safe-notification-target-ph3xd1ve.js → safe-notification-target-1jkf0m82.js} +2 -2
- package/dist/{send-session-notification-rnc4nrsr.js → send-session-notification-cz6ev088.js} +5 -5
- package/dist/shared/auto-search-lifecycle.d.ts +14 -0
- package/dist/shared/auto-search-lifecycle.d.ts.map +1 -1
- package/dist/shared/logger.d.ts.map +1 -1
- package/dist/shared/models-dev-cache.d.ts.map +1 -1
- package/dist/shared/models-dev-temperature.d.ts +18 -0
- package/dist/shared/models-dev-temperature.d.ts.map +1 -0
- package/dist/shared/processed-image-eligibility.d.ts +22 -0
- package/dist/shared/processed-image-eligibility.d.ts.map +1 -0
- package/dist/shared/project-directory-key.d.ts +16 -0
- package/dist/shared/project-directory-key.d.ts.map +1 -1
- package/dist/shared/recovery-reasoning-prefix.d.ts +9 -0
- package/dist/shared/recovery-reasoning-prefix.d.ts.map +1 -0
- package/dist/shared/sqlite.d.ts +33 -1
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/stable-json.d.ts.map +1 -1
- package/dist/shared/storage-file-mutex.d.ts +9 -0
- package/dist/shared/storage-file-mutex.d.ts.map +1 -0
- package/dist/shared/storage-permissions.d.ts +6 -0
- package/dist/shared/storage-permissions.d.ts.map +1 -1
- package/dist/shared/subagent-temperature.d.ts +46 -0
- package/dist/shared/subagent-temperature.d.ts.map +1 -0
- package/dist/shared/tag-owner-id.d.ts +1 -0
- package/dist/shared/tag-owner-id.d.ts.map +1 -1
- package/dist/shared/tag-transcript.d.ts +9 -0
- package/dist/shared/tag-transcript.d.ts.map +1 -1
- package/dist/shared/window-geometry.d.ts +9 -66
- package/dist/shared/window-geometry.d.ts.map +1 -1
- package/dist/standalone-plugin-marker.d.ts +8 -0
- package/dist/standalone-plugin-marker.d.ts.map +1 -0
- package/dist/tools/ctx-expand/search-archive.d.ts +4 -0
- package/dist/tools/ctx-expand/search-archive.d.ts.map +1 -0
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/constants.d.ts +1 -2
- package/dist/tools/ctx-reduce/constants.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/tools.d.ts +1 -1
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
- package/dist/v2/hooks/context.d.ts +1 -1
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/copied-tag-notation.d.ts +19 -0
- package/dist/v2/hooks/copied-tag-notation.d.ts.map +1 -0
- package/dist/v2/hooks/generate.d.ts +9 -2
- package/dist/v2/hooks/generate.d.ts.map +1 -1
- package/dist/v2/hooks/payload.d.ts.map +1 -1
- package/dist/v2/hooks/system-prompt-response.d.ts +5 -0
- package/dist/v2/hooks/system-prompt-response.d.ts.map +1 -0
- package/dist/v2/server.d.ts.map +1 -1
- package/dist/v2/server.js +34550 -30855
- package/dist/web/main.js +373 -19
- package/dist/{wrapup-orchestrator-yknks3ad.js → wrapup-orchestrator-bmybc5p5.js} +10 -10
- package/package.json +1 -1
- package/src/config/deprecated-config.ts +18 -0
- package/src/config/index.test.ts +13 -37
- package/src/config/index.ts +2 -2
- package/src/config/project-security.ts +3 -3
- package/src/config/schema/magic-context.ts +10 -6
- package/src/shared/auto-search-lifecycle.ts +43 -0
- package/src/shared/logger.ts +10 -2
- package/src/shared/models-dev-cache.ts +1 -7
- package/src/shared/models-dev-temperature.ts +107 -0
- package/src/shared/processed-image-eligibility.test.ts +68 -0
- package/src/shared/processed-image-eligibility.ts +41 -0
- package/src/shared/processed-image-position-review.json +20 -0
- package/src/shared/processed-image-position-review.test.ts +19 -0
- package/src/shared/project-directory-key.ts +20 -0
- package/src/shared/recovery-reasoning-prefix.test.ts +34 -0
- package/src/shared/recovery-reasoning-prefix.ts +35 -0
- package/src/shared/sqlite-acquisition-routing.test.ts +4 -3
- package/src/shared/sqlite-foreground-wait.test.ts +68 -0
- package/src/shared/sqlite-pass-scope.test.ts +4 -4
- package/src/shared/sqlite-writer-diagnostics.test.ts +52 -12
- package/src/shared/sqlite.ts +380 -39
- package/src/shared/stable-json.ts +37 -7
- package/src/shared/storage-file-mutex.test.ts +50 -0
- package/src/shared/storage-file-mutex.ts +130 -0
- package/src/shared/storage-permissions.ts +46 -0
- package/src/shared/subagent-temperature.ts +110 -0
- package/src/shared/tag-owner-id.ts +13 -0
- package/src/shared/tag-transcript.ts +118 -0
- package/src/shared/window-geometry.test.ts +102 -236
- package/src/shared/window-geometry.ts +23 -413
- package/dist/index-ramz5kkm.js +0 -514
- package/dist/recomp-orchestrator-frmwj9hz.js +0 -21
- package/src/shared/__fixtures__/window-overlay.v1.json +0 -337
|
@@ -6,12 +6,15 @@ function registerSlowWriteReporter(reporter) {
|
|
|
6
6
|
reportSlowPrivilegedWrite = reporter;
|
|
7
7
|
}
|
|
8
8
|
var sqliteDiagnosticSink;
|
|
9
|
-
|
|
9
|
+
var sqliteDiagnosticHost = () => "unknown";
|
|
10
|
+
function registerSqliteDiagnosticSink(sink, host) {
|
|
10
11
|
sqliteDiagnosticSink = sink;
|
|
12
|
+
if (host)
|
|
13
|
+
sqliteDiagnosticHost = host;
|
|
11
14
|
}
|
|
12
15
|
function reportSqliteDiagnostic(message) {
|
|
13
16
|
try {
|
|
14
|
-
sqliteDiagnosticSink?.(`[magic-context] ${message}`);
|
|
17
|
+
sqliteDiagnosticSink?.(`[magic-context] ${message} pid=${process.pid} host=${sqliteDiagnosticHost()}`);
|
|
15
18
|
} catch {}
|
|
16
19
|
}
|
|
17
20
|
function detectSqliteRuntime() {
|
|
@@ -47,10 +50,31 @@ class SqliteRuntimeUnavailableError extends Error {
|
|
|
47
50
|
this.specifier = specifier;
|
|
48
51
|
}
|
|
49
52
|
}
|
|
53
|
+
function isNodeSqliteExperimentalWarning(args) {
|
|
54
|
+
const [warning, options] = args;
|
|
55
|
+
const message = warning instanceof Error ? warning.message : warning;
|
|
56
|
+
const type = typeof options === "string" ? options : options && typeof options === "object" ? options.type : undefined;
|
|
57
|
+
return type === "ExperimentalWarning" && typeof message === "string" && message.startsWith("SQLite is an experimental feature");
|
|
58
|
+
}
|
|
59
|
+
async function importSqliteModuleForRuntime(runtime, specifier, importer) {
|
|
60
|
+
if (runtime !== "Node.js")
|
|
61
|
+
return importer(specifier);
|
|
62
|
+
const originalEmitWarning = process.emitWarning;
|
|
63
|
+
process.emitWarning = function(...args) {
|
|
64
|
+
if (isNodeSqliteExperimentalWarning(args))
|
|
65
|
+
return;
|
|
66
|
+
Reflect.apply(originalEmitWarning, this, args);
|
|
67
|
+
};
|
|
68
|
+
try {
|
|
69
|
+
return await importer(specifier);
|
|
70
|
+
} finally {
|
|
71
|
+
process.emitWarning = originalEmitWarning;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
50
74
|
async function loadSqliteModule(runtime = detectSqliteRuntime(), importer = importSqliteModule) {
|
|
51
75
|
const specifier = runtime === "Bun" ? bunSpec : nodeSpec;
|
|
52
76
|
try {
|
|
53
|
-
return await
|
|
77
|
+
return await importSqliteModuleForRuntime(runtime, specifier, importer);
|
|
54
78
|
} catch (error) {
|
|
55
79
|
if (isModuleNotFoundError(error, specifier)) {
|
|
56
80
|
throw new SqliteRuntimeUnavailableError(runtime, specifier, error);
|
|
@@ -64,6 +88,81 @@ var sqliteModule = await loadSqliteModule(detectedRuntime);
|
|
|
64
88
|
var DatabaseImpl = isBun ? sqliteModule.Database : buildNodeSqliteDatabaseClass(sqliteModule.DatabaseSync);
|
|
65
89
|
var trackedSqliteConnections = new Map;
|
|
66
90
|
var nextSqliteConnectionSequence = 1;
|
|
91
|
+
var TAG_COLUMNS_OUTSIDE_IDENTITY = new Set([
|
|
92
|
+
"status",
|
|
93
|
+
"drop_mode",
|
|
94
|
+
"byte_size",
|
|
95
|
+
"input_byte_size",
|
|
96
|
+
"reasoning_byte_size",
|
|
97
|
+
"token_count",
|
|
98
|
+
"input_token_count",
|
|
99
|
+
"caveman_depth",
|
|
100
|
+
"entry_fingerprint",
|
|
101
|
+
"tool_name",
|
|
102
|
+
"harness"
|
|
103
|
+
]);
|
|
104
|
+
var tagIdentityWriteGeneration = 0;
|
|
105
|
+
function mayChangeTagIdentity(sql) {
|
|
106
|
+
if (!/\btags\b/i.test(sql) || /^\s*(?:SELECT|EXPLAIN|PRAGMA)\b/i.test(sql))
|
|
107
|
+
return false;
|
|
108
|
+
if (/^\s*WITH\b/i.test(sql) && !/\b(?:INSERT|UPDATE|DELETE|REPLACE)\b/i.test(sql))
|
|
109
|
+
return false;
|
|
110
|
+
if (/;\s*\S/.test(sql) || /\bREPLACE\b/i.test(sql) || /\bON\s+CONFLICT\b/i.test(sql))
|
|
111
|
+
return true;
|
|
112
|
+
const insert = /^\s*INSERT\s+INTO\s+(?:main\.)?["`]?tags["`]?\s*\(([^)]*)\)/i.exec(sql);
|
|
113
|
+
if (insert) {
|
|
114
|
+
const columns = (insert[1] ?? "").split(",").map((column) => column.trim().replace(/["`[\]]/g, "").toLowerCase());
|
|
115
|
+
return columns.includes("id") || columns.includes("rowid");
|
|
116
|
+
}
|
|
117
|
+
const update = /^\s*UPDATE\s+(?:main\.)?["`]?tags["`]?\s+SET\s+([\s\S]*?)\bWHERE\b/i.exec(sql);
|
|
118
|
+
if (update && !/\bSELECT\b/i.test(sql)) {
|
|
119
|
+
const assignments = topLevelCommaSegments(update[1] ?? "");
|
|
120
|
+
if (!assignments)
|
|
121
|
+
return true;
|
|
122
|
+
return !assignments.every((assignment) => {
|
|
123
|
+
const column = /^\s*["`]?(\w+)["`]?\s*=(?!=)/.exec(assignment)?.[1];
|
|
124
|
+
return column !== undefined && TAG_COLUMNS_OUTSIDE_IDENTITY.has(column.toLowerCase());
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
function topLevelCommaSegments(text) {
|
|
130
|
+
const segments = [];
|
|
131
|
+
let depth = 0;
|
|
132
|
+
let quote = null;
|
|
133
|
+
let start = 0;
|
|
134
|
+
for (let index = 0;index < text.length; index += 1) {
|
|
135
|
+
const char = text[index];
|
|
136
|
+
if (quote) {
|
|
137
|
+
if (char === quote) {
|
|
138
|
+
if (text[index + 1] === quote)
|
|
139
|
+
index += 1;
|
|
140
|
+
else
|
|
141
|
+
quote = null;
|
|
142
|
+
}
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (char === "'" || char === '"' || char === "`")
|
|
146
|
+
quote = char;
|
|
147
|
+
else if (char === "(")
|
|
148
|
+
depth += 1;
|
|
149
|
+
else if (char === ")") {
|
|
150
|
+
depth -= 1;
|
|
151
|
+
if (depth < 0)
|
|
152
|
+
return null;
|
|
153
|
+
} else if (char === "," && depth === 0) {
|
|
154
|
+
segments.push(text.slice(start, index));
|
|
155
|
+
start = index + 1;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (quote || depth !== 0)
|
|
159
|
+
return null;
|
|
160
|
+
segments.push(text.slice(start));
|
|
161
|
+
return segments;
|
|
162
|
+
}
|
|
163
|
+
function getTagIdentityWriteGeneration() {
|
|
164
|
+
return tagIdentityWriteGeneration;
|
|
165
|
+
}
|
|
67
166
|
function installTransactionRouting(db, readonly) {
|
|
68
167
|
const nativeExec = db.exec.bind(db);
|
|
69
168
|
Object.defineProperty(db, "exec", {
|
|
@@ -74,16 +173,30 @@ function installTransactionRouting(db, readonly) {
|
|
|
74
173
|
assertTransformWrite();
|
|
75
174
|
if (/^\s*BEGIN\s+(?:IMMEDIATE|EXCLUSIVE)(?:\s+TRANSACTION)?\s*;?\s*$/i.test(sql)) {
|
|
76
175
|
openWriterTransactions.delete(db);
|
|
77
|
-
if (transformPassScope.getStore()?.active || backgroundWriterScope.getStore())
|
|
176
|
+
if (transformPassScope.getStore()?.active || backgroundWriterScope.getStore()) {
|
|
78
177
|
acquireShort(db, () => nativeExec(sql), sql.trim());
|
|
79
|
-
else
|
|
178
|
+
} else {
|
|
80
179
|
nativeExec(sql);
|
|
180
|
+
openWriterTransactions.set(db, {
|
|
181
|
+
site: sql.trim(),
|
|
182
|
+
lane: "background",
|
|
183
|
+
acquireMs: 0,
|
|
184
|
+
attempts: 1,
|
|
185
|
+
acquiredAt: performance.now()
|
|
186
|
+
});
|
|
187
|
+
}
|
|
81
188
|
return db;
|
|
82
189
|
}
|
|
83
190
|
if (WRITER_TRANSACTION_END.test(sql) && openWriterTransactions.has(db))
|
|
84
191
|
return endWriterTransaction(db, () => nativeExec(sql), sql);
|
|
85
|
-
if (!/^\s*(?:SELECT|EXPLAIN|PRAGMA|COMMIT|END|ROLLBACK|SAVEPOINT|RELEASE)\b/i.test(sql))
|
|
86
|
-
|
|
192
|
+
if (!/^\s*(?:SELECT|EXPLAIN|PRAGMA|COMMIT|END|ROLLBACK|SAVEPOINT|RELEASE)\b/i.test(sql)) {
|
|
193
|
+
try {
|
|
194
|
+
return withAutocommitTimeout(db, () => nativeExec(sql));
|
|
195
|
+
} finally {
|
|
196
|
+
if (mayChangeTagIdentity(sql))
|
|
197
|
+
tagIdentityWriteGeneration += 1;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
87
200
|
return nativeExec(sql);
|
|
88
201
|
}
|
|
89
202
|
});
|
|
@@ -94,13 +207,23 @@ function installTransactionRouting(db, readonly) {
|
|
|
94
207
|
value: (sql) => {
|
|
95
208
|
const statement = nativePrepare(sql);
|
|
96
209
|
if (!readonly && !/^\s*(?:SELECT|EXPLAIN|PRAGMA)\b/i.test(sql)) {
|
|
210
|
+
const changesTagIdentity = mayChangeTagIdentity(sql);
|
|
97
211
|
for (const method of ["run", "get", "all"]) {
|
|
98
212
|
const execute = statement[method].bind(statement);
|
|
99
213
|
Object.defineProperty(statement, method, {
|
|
100
214
|
configurable: true,
|
|
101
|
-
value: (...args) =>
|
|
215
|
+
value: (...args) => {
|
|
216
|
+
try {
|
|
217
|
+
return withAutocommitTimeout(db, () => execute(...args));
|
|
218
|
+
} finally {
|
|
219
|
+
if (changesTagIdentity)
|
|
220
|
+
tagIdentityWriteGeneration += 1;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
102
223
|
});
|
|
103
224
|
}
|
|
225
|
+
if (changesTagIdentity)
|
|
226
|
+
wrapRemainingTagWriteForms(statement);
|
|
104
227
|
}
|
|
105
228
|
return statement;
|
|
106
229
|
}
|
|
@@ -148,6 +271,35 @@ function installTransactionRouting(db, readonly) {
|
|
|
148
271
|
}
|
|
149
272
|
});
|
|
150
273
|
}
|
|
274
|
+
function wrapRemainingTagWriteForms(statement) {
|
|
275
|
+
if (typeof statement.iterate === "function") {
|
|
276
|
+
const iterate = statement.iterate.bind(statement);
|
|
277
|
+
Object.defineProperty(statement, "iterate", {
|
|
278
|
+
configurable: true,
|
|
279
|
+
value: function* (...args) {
|
|
280
|
+
tagIdentityWriteGeneration += 1;
|
|
281
|
+
try {
|
|
282
|
+
yield* iterate(...args);
|
|
283
|
+
} finally {
|
|
284
|
+
tagIdentityWriteGeneration += 1;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
if (typeof statement.values === "function") {
|
|
290
|
+
const values = statement.values.bind(statement);
|
|
291
|
+
Object.defineProperty(statement, "values", {
|
|
292
|
+
configurable: true,
|
|
293
|
+
value: (...args) => {
|
|
294
|
+
try {
|
|
295
|
+
return values(...args);
|
|
296
|
+
} finally {
|
|
297
|
+
tagIdentityWriteGeneration += 1;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
151
303
|
function trackSqliteConnection(db, filename, options) {
|
|
152
304
|
const originalClose = db.close.bind(db);
|
|
153
305
|
const sequence = nextSqliteConnectionSequence++;
|
|
@@ -208,6 +360,18 @@ function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
|
208
360
|
return NodeSqliteDatabase;
|
|
209
361
|
}
|
|
210
362
|
var Database = TrackedDatabase;
|
|
363
|
+
function getSqliteDatabasePath(db) {
|
|
364
|
+
for (const connection of trackedSqliteConnections.values()) {
|
|
365
|
+
if (connection.reference.deref() === db) {
|
|
366
|
+
return connection.filename === ":memory:" || connection.filename === "<buffer>" ? null : connection.filename;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
const native = db;
|
|
370
|
+
const path = native.filename ?? native.name;
|
|
371
|
+
if (typeof path === "string" && path !== ":memory:" && path !== "")
|
|
372
|
+
return path;
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
211
375
|
function pragmaValue(db, name) {
|
|
212
376
|
const row = db.prepare(`PRAGMA ${name}`).get();
|
|
213
377
|
if (!row)
|
|
@@ -355,22 +519,29 @@ function withSqliteTransformPass(operation) {
|
|
|
355
519
|
const existing = transformPassScope.getStore();
|
|
356
520
|
if (existing?.active)
|
|
357
521
|
return operation();
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
522
|
+
const reservation = reserveForegroundSqliteTurn();
|
|
523
|
+
const run = (release) => {
|
|
524
|
+
const lease = { active: true, remainingWaitMs: FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS };
|
|
525
|
+
return transformPassScope.run(lease, () => {
|
|
526
|
+
try {
|
|
527
|
+
const result = operation();
|
|
528
|
+
if (result && typeof result.then === "function") {
|
|
529
|
+
return Promise.resolve(result).finally(() => {
|
|
530
|
+
lease.active = false;
|
|
531
|
+
release();
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
lease.active = false;
|
|
535
|
+
release();
|
|
536
|
+
return result;
|
|
537
|
+
} catch (error) {
|
|
538
|
+
lease.active = false;
|
|
539
|
+
release();
|
|
540
|
+
throw error;
|
|
366
541
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
lease.active = false;
|
|
371
|
-
throw error;
|
|
372
|
-
}
|
|
373
|
-
});
|
|
542
|
+
});
|
|
543
|
+
};
|
|
544
|
+
return typeof reservation === "function" ? run(reservation) : reservation.then(run);
|
|
374
545
|
}
|
|
375
546
|
function withoutSqliteTransformPass(operation) {
|
|
376
547
|
return transformPassScope.run(undefined, operation);
|
|
@@ -396,9 +567,9 @@ class SqliteAcquisitionBusyError extends Error {
|
|
|
396
567
|
}
|
|
397
568
|
}
|
|
398
569
|
var SHORT_BUSY_TIMEOUT_MS = 25;
|
|
399
|
-
var FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS =
|
|
570
|
+
var FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS = 2000;
|
|
400
571
|
var FOREGROUND_ACQUISITION_BUDGET_MS = 16500;
|
|
401
|
-
var SLOW_WRITER_LOG_MS =
|
|
572
|
+
var SLOW_WRITER_LOG_MS = 100;
|
|
402
573
|
var WRITER_TRANSACTION_END = /^\s*(?:COMMIT|END|ROLLBACK)(?:\s+TRANSACTION)?\s*;?\s*$/i;
|
|
403
574
|
var writerAcquisitionScope = new AsyncLocalStorage;
|
|
404
575
|
var openWriterTransactions = new WeakMap;
|
|
@@ -409,22 +580,30 @@ function foregroundWaitLease() {
|
|
|
409
580
|
function withAutocommitTimeout(db, operation) {
|
|
410
581
|
assertTransformWrite();
|
|
411
582
|
const lease = foregroundWaitLease();
|
|
412
|
-
if (isInTransaction(db)
|
|
583
|
+
if (isInTransaction(db))
|
|
413
584
|
return operation();
|
|
414
|
-
const
|
|
415
|
-
|
|
585
|
+
const scoped = lease || backgroundWriterScope.getStore();
|
|
586
|
+
const previous = scoped ? pragmaNumber(db, "busy_timeout") : null;
|
|
587
|
+
if (scoped)
|
|
588
|
+
db.exec(`PRAGMA busy_timeout=${lease ? Math.floor(Math.min(lease.remainingWaitMs, lease.guard?.remainingMs() ?? Infinity)) : SHORT_BUSY_TIMEOUT_MS}`);
|
|
416
589
|
const started = performance.now();
|
|
590
|
+
let completed = false;
|
|
417
591
|
try {
|
|
418
|
-
|
|
592
|
+
const result = operation();
|
|
593
|
+
completed = true;
|
|
594
|
+
return result;
|
|
419
595
|
} catch (error) {
|
|
420
596
|
if (lease && isTransientSqliteError(error))
|
|
421
597
|
throw new SqliteAcquisitionBusyError(error, "autocommit");
|
|
422
598
|
throw error;
|
|
423
599
|
} finally {
|
|
600
|
+
const elapsed = performance.now() - started;
|
|
424
601
|
if (lease)
|
|
425
|
-
lease.remainingWaitMs = Math.max(0, lease.remainingWaitMs -
|
|
602
|
+
lease.remainingWaitMs = Math.max(0, lease.remainingWaitMs - elapsed);
|
|
426
603
|
if (previous !== null)
|
|
427
604
|
db.exec(`PRAGMA busy_timeout=${previous}`);
|
|
605
|
+
if (elapsed >= SLOW_WRITER_LOG_MS)
|
|
606
|
+
reportSqliteDiagnostic(`sqlite writer site=autocommit lane=${lease ? "foreground" : "background"} elapsed_ms=${Math.round(elapsed)} timing=statement_including_acquisition outcome=${completed ? "completed" : "failed"} caller=${writerCaller()}`);
|
|
428
607
|
}
|
|
429
608
|
}
|
|
430
609
|
function acquireShort(db, acquire, site) {
|
|
@@ -481,11 +660,15 @@ function endWriterTransaction(db, end, sql) {
|
|
|
481
660
|
const holdMs = performance.now() - open.acquiredAt;
|
|
482
661
|
if (open.acquireMs >= SLOW_WRITER_LOG_MS || holdMs >= SLOW_WRITER_LOG_MS) {
|
|
483
662
|
const outcome = /^\s*ROLLBACK/i.test(sql) ? "rolled_back" : ended ? "committed" : "failed";
|
|
484
|
-
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}`);
|
|
663
|
+
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} timing=through_commit_upper_bound caller=${writerCaller()}`);
|
|
485
664
|
}
|
|
486
665
|
}
|
|
487
666
|
}
|
|
488
667
|
}
|
|
668
|
+
function writerCaller() {
|
|
669
|
+
return new Error().stack?.split(`
|
|
670
|
+
`).find((line) => line.includes(" at ") && !/[/\\]sqlite\.[tj]s[:)]/.test(line) && !/\b(?:writerCaller|endWriterTransaction|withAutocommitTimeout|value)\b/.test(line))?.trim().replace(/\s+/g, "_") ?? "unknown";
|
|
671
|
+
}
|
|
489
672
|
async function beginSqliteWriterAsync(db, site) {
|
|
490
673
|
const started = performance.now();
|
|
491
674
|
let attempts = 0;
|
|
@@ -621,5 +804,56 @@ function withPrivilegedWriter(db, operation) {
|
|
|
621
804
|
throw error;
|
|
622
805
|
}
|
|
623
806
|
}
|
|
807
|
+
var indexCoordinationKey = Symbol.for("magic-context.index-foreground-coordination.v1");
|
|
808
|
+
var indexCoordinationHeap = globalThis;
|
|
809
|
+
var indexCoordinationBuffer = indexCoordinationHeap[indexCoordinationKey] ?? new SharedArrayBuffer(3 * Int32Array.BYTES_PER_ELEMENT);
|
|
810
|
+
indexCoordinationHeap[indexCoordinationKey] = indexCoordinationBuffer;
|
|
811
|
+
var indexCoordinationState = new Int32Array(indexCoordinationBuffer);
|
|
812
|
+
function indexCoordinationInput() {
|
|
813
|
+
return {
|
|
814
|
+
indexCoordination: indexCoordinationBuffer,
|
|
815
|
+
indexOwner: Atomics.add(indexCoordinationState, 2, 1) + 1
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
var yieldIndexTurn = () => new Promise((resolve) => setTimeout(resolve, 1));
|
|
819
|
+
function reserveForegroundSqliteTurn() {
|
|
820
|
+
Atomics.add(indexCoordinationState, 0, 1);
|
|
821
|
+
const release = () => {
|
|
822
|
+
Atomics.sub(indexCoordinationState, 0, 1);
|
|
823
|
+
Atomics.notify(indexCoordinationState, 0);
|
|
824
|
+
};
|
|
825
|
+
if (Atomics.load(indexCoordinationState, 1) === 0)
|
|
826
|
+
return release;
|
|
827
|
+
return (async () => {
|
|
828
|
+
while (Atomics.load(indexCoordinationState, 1) !== 0)
|
|
829
|
+
await yieldIndexTurn();
|
|
830
|
+
return release;
|
|
831
|
+
})();
|
|
832
|
+
}
|
|
833
|
+
function releaseIndexOwner(input) {
|
|
834
|
+
if (!input.indexCoordination || !input.indexOwner)
|
|
835
|
+
return;
|
|
836
|
+
const shared = new Int32Array(input.indexCoordination);
|
|
837
|
+
Atomics.compareExchange(shared, 1, input.indexOwner, 0);
|
|
838
|
+
Atomics.notify(shared, 1);
|
|
839
|
+
}
|
|
840
|
+
async function withIndexChunk(input, operation) {
|
|
841
|
+
if (!input.indexCoordination || !input.indexOwner)
|
|
842
|
+
return operation();
|
|
843
|
+
const shared = new Int32Array(input.indexCoordination);
|
|
844
|
+
for (;; ) {
|
|
845
|
+
if (Atomics.load(shared, 0) === 0 && Atomics.compareExchange(shared, 1, 0, input.indexOwner) === 0) {
|
|
846
|
+
if (Atomics.load(shared, 0) === 0)
|
|
847
|
+
break;
|
|
848
|
+
releaseIndexOwner(input);
|
|
849
|
+
}
|
|
850
|
+
await yieldIndexTurn();
|
|
851
|
+
}
|
|
852
|
+
try {
|
|
853
|
+
return await operation();
|
|
854
|
+
} finally {
|
|
855
|
+
releaseIndexOwner(input);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
624
858
|
|
|
625
|
-
export { registerSlowWriteReporter, registerSqliteDiagnosticSink, detectSqliteRuntime, Database, getSqliteMemoryStats, prepareCachedStatement, withSqliteBackgroundWriter, withSqliteTransformPass, withoutSqliteTransformPass, isTransientSqliteError, SqliteAcquisitionBusyError, beginSqliteWriterAsync, withAsyncPrivilegedWriter, withPrivilegedWriter };
|
|
859
|
+
export { registerSlowWriteReporter, registerSqliteDiagnosticSink, detectSqliteRuntime, getTagIdentityWriteGeneration, Database, getSqliteDatabasePath, getSqliteMemoryStats, prepareCachedStatement, withSqliteBackgroundWriter, withSqliteTransformPass, withoutSqliteTransformPass, isTransientSqliteError, SqliteAcquisitionBusyError, beginSqliteWriterAsync, withAsyncPrivilegedWriter, withPrivilegedWriter, indexCoordinationInput, withIndexChunk };
|
|
@@ -431,8 +431,12 @@ function flush() {
|
|
|
431
431
|
let currentSize = getCurrentLogSize(logFile);
|
|
432
432
|
const dataSize = Buffer.byteLength(data);
|
|
433
433
|
if (currentSize > 0 && currentSize + dataSize > MAX_LOG_FILE_BYTES) {
|
|
434
|
-
|
|
435
|
-
currentSize =
|
|
434
|
+
flushesSinceSizeCheck = SIZE_CHECK_INTERVAL_FLUSHES;
|
|
435
|
+
currentSize = getCurrentLogSize(logFile);
|
|
436
|
+
if (currentSize > 0 && currentSize + dataSize > MAX_LOG_FILE_BYTES) {
|
|
437
|
+
rotateLogFile(logFile, currentSize);
|
|
438
|
+
currentSize = 0;
|
|
439
|
+
}
|
|
436
440
|
}
|
|
437
441
|
fs.appendFileSync(logFile, data, { encoding: "utf8", mode: 384 });
|
|
438
442
|
buffer = [];
|