@retaw106/mmc-pi 2.4.0 → 2.6.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/{index-zmx631ey.js → index-07rh0nr2.js} +333 -56
- package/dist/{index-cr4hzd76.js → index-vhs0y3s0.js} +214 -5
- package/dist/index.js +2588 -1661
- package/dist/{message-time-backfill-fvkrfyp4.js → message-time-backfill-y26yy5pp.js} +1 -1
- package/dist/{read-session-chunk-g164kwxz.js → read-session-chunk-qg5jfqjg.js} +2 -2
- package/dist/web/main.js +307 -12
- package/package.json +1 -1
|
@@ -166,6 +166,177 @@ function topLevelCommaSegments(text) {
|
|
|
166
166
|
function getTagIdentityWriteGeneration() {
|
|
167
167
|
return tagIdentityWriteGeneration;
|
|
168
168
|
}
|
|
169
|
+
var busyTimeoutStates = new WeakMap;
|
|
170
|
+
var BUSY_TIMEOUT_QUERY = /^\s*PRAGMA\s+(?:(?:\w+|"[^"]+"|`[^`]+`|\[[^\]]+\])\s*\.\s*)?(?:busy_timeout|"busy_timeout"|`busy_timeout`|\[busy_timeout\])\s*;?\s*$/i;
|
|
171
|
+
var BUSY_TIMEOUT_SETTER = /^\s*PRAGMA\s+(?:(?:\w+|"[^"]+"|`[^`]+`|\[[^\]]+\])\s*\.\s*)?(?:busy_timeout|"busy_timeout"|`busy_timeout`|\[busy_timeout\])\s*(?==|\()/i;
|
|
172
|
+
function literalBusyTimeout(sql) {
|
|
173
|
+
const head = BUSY_TIMEOUT_SETTER.exec(sql);
|
|
174
|
+
if (!head)
|
|
175
|
+
return;
|
|
176
|
+
const match = /^(?:=\s*|\(\s*)(?:'(-?\d+)'|"(-?\d+)"|(-?\d+))\s*\)?\s*;?\s*$/.exec(sql.slice(head[0].length));
|
|
177
|
+
if (!match)
|
|
178
|
+
return;
|
|
179
|
+
const value = Number(match[1] ?? match[2] ?? match[3]);
|
|
180
|
+
return value < 0 ? 0 : value <= 2147483647 ? value : undefined;
|
|
181
|
+
}
|
|
182
|
+
function busyTimeoutStatements(sql) {
|
|
183
|
+
const statements = [];
|
|
184
|
+
let statement = "";
|
|
185
|
+
let quote = "";
|
|
186
|
+
for (let i = 0;i < sql.length; i++) {
|
|
187
|
+
const char = sql[i];
|
|
188
|
+
if (quote) {
|
|
189
|
+
statement += char;
|
|
190
|
+
if (char === quote) {
|
|
191
|
+
if (sql[i + 1] === quote)
|
|
192
|
+
statement += sql[++i];
|
|
193
|
+
else
|
|
194
|
+
quote = "";
|
|
195
|
+
}
|
|
196
|
+
} else if (char === "'" || char === '"' || char === "`" || char === "[") {
|
|
197
|
+
quote = char === "[" ? "]" : char;
|
|
198
|
+
statement += char;
|
|
199
|
+
} else if (char === "-" && sql[i + 1] === "-") {
|
|
200
|
+
while (i + 1 < sql.length && sql[i + 1] !== `
|
|
201
|
+
`)
|
|
202
|
+
i++;
|
|
203
|
+
statement += " ";
|
|
204
|
+
} else if (char === "/" && sql[i + 1] === "*") {
|
|
205
|
+
i += 2;
|
|
206
|
+
while (i < sql.length && !(sql[i] === "*" && sql[i + 1] === "/"))
|
|
207
|
+
i++;
|
|
208
|
+
i++;
|
|
209
|
+
statement += " ";
|
|
210
|
+
} else if (char === ";") {
|
|
211
|
+
statements.push(statement);
|
|
212
|
+
statement = "";
|
|
213
|
+
} else
|
|
214
|
+
statement += char;
|
|
215
|
+
}
|
|
216
|
+
statements.push(statement);
|
|
217
|
+
return statements.filter((part) => part.trim().length > 0);
|
|
218
|
+
}
|
|
219
|
+
function installNativeDeadlineRouting(db) {
|
|
220
|
+
const rawExec = db.exec.bind(db);
|
|
221
|
+
const rawPrepare = db.prepare.bind(db);
|
|
222
|
+
const readTimeout = () => {
|
|
223
|
+
const statement = rawPrepare("PRAGMA busy_timeout");
|
|
224
|
+
try {
|
|
225
|
+
return Object.values(statement.get())[0];
|
|
226
|
+
} finally {
|
|
227
|
+
statement.finalize?.();
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
const timeoutState = { current: readTimeout() };
|
|
231
|
+
busyTimeoutStates.set(db, timeoutState);
|
|
232
|
+
const setBusyTimeout = (timeout) => {
|
|
233
|
+
rawExec(`PRAGMA busy_timeout=${timeout}`);
|
|
234
|
+
timeoutState.current = timeout;
|
|
235
|
+
};
|
|
236
|
+
const withinDeadline = (operation) => {
|
|
237
|
+
const deadline = nativeWaitScope?.getStore();
|
|
238
|
+
if (!deadline?.active || !deadline.remainingMs)
|
|
239
|
+
return operation();
|
|
240
|
+
const remaining = deadline.remainingMs();
|
|
241
|
+
if (remaining === Infinity)
|
|
242
|
+
return operation();
|
|
243
|
+
const previous = timeoutState.current;
|
|
244
|
+
const timeout = Math.min(previous, Math.max(0, Math.floor(remaining)));
|
|
245
|
+
if (timeout === previous)
|
|
246
|
+
return operation();
|
|
247
|
+
setBusyTimeout(timeout);
|
|
248
|
+
try {
|
|
249
|
+
return operation();
|
|
250
|
+
} finally {
|
|
251
|
+
setBusyTimeout(previous);
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
Object.defineProperty(db, "exec", {
|
|
255
|
+
configurable: true,
|
|
256
|
+
writable: true,
|
|
257
|
+
value: (sql) => {
|
|
258
|
+
const parts = /\bbusy_timeout\b/i.test(sql) ? busyTimeoutStatements(sql) : [];
|
|
259
|
+
if (parts.length === 1 && BUSY_TIMEOUT_QUERY.test(parts[0]))
|
|
260
|
+
return rawExec(sql);
|
|
261
|
+
const singleSetter = parts.length === 1 && BUSY_TIMEOUT_SETTER.test(parts[0]);
|
|
262
|
+
const setting = singleSetter ? literalBusyTimeout(parts[0]) : undefined;
|
|
263
|
+
if (singleSetter) {
|
|
264
|
+
const result = rawExec(sql);
|
|
265
|
+
timeoutState.current = setting ?? readTimeout();
|
|
266
|
+
return result;
|
|
267
|
+
}
|
|
268
|
+
if (!/\bbusy_timeout\b/i.test(sql))
|
|
269
|
+
return withinDeadline(() => rawExec(sql));
|
|
270
|
+
const setters = parts.filter((part) => BUSY_TIMEOUT_SETTER.test(part));
|
|
271
|
+
return withinDeadline(() => {
|
|
272
|
+
try {
|
|
273
|
+
const result = rawExec(sql);
|
|
274
|
+
if (setters.length)
|
|
275
|
+
timeoutState.current = literalBusyTimeout(setters[setters.length - 1]) ?? readTimeout();
|
|
276
|
+
return result;
|
|
277
|
+
} catch (error) {
|
|
278
|
+
if (setters.length)
|
|
279
|
+
timeoutState.current = readTimeout();
|
|
280
|
+
throw error;
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
const nativePrepare = (sql) => BUSY_TIMEOUT_QUERY.test(sql) || BUSY_TIMEOUT_SETTER.test(sql) ? rawPrepare(sql) : withinDeadline(() => rawPrepare(sql));
|
|
286
|
+
Object.defineProperty(db, "prepare", {
|
|
287
|
+
configurable: true,
|
|
288
|
+
writable: true,
|
|
289
|
+
value: (sql) => {
|
|
290
|
+
const statement = nativePrepare(sql);
|
|
291
|
+
const normalized = /\bbusy_timeout\b/i.test(sql) ? busyTimeoutStatements(sql)[0] ?? sql : sql;
|
|
292
|
+
const setting = literalBusyTimeout(normalized);
|
|
293
|
+
const timeoutSetter = BUSY_TIMEOUT_SETTER.test(normalized);
|
|
294
|
+
const timeoutQuery = BUSY_TIMEOUT_QUERY.test(normalized);
|
|
295
|
+
if (timeoutSetter)
|
|
296
|
+
timeoutState.current = setting ?? readTimeout();
|
|
297
|
+
for (const method of ["run", "get", "all", "values"]) {
|
|
298
|
+
const execute = statement[method]?.bind(statement);
|
|
299
|
+
if (!execute)
|
|
300
|
+
continue;
|
|
301
|
+
Object.defineProperty(statement, method, {
|
|
302
|
+
configurable: true,
|
|
303
|
+
value: (...args) => {
|
|
304
|
+
if (timeoutQuery)
|
|
305
|
+
return execute(...args);
|
|
306
|
+
if (!timeoutSetter)
|
|
307
|
+
return withinDeadline(() => execute(...args));
|
|
308
|
+
const result = execute(...args);
|
|
309
|
+
timeoutState.current = readTimeout();
|
|
310
|
+
return result;
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
if (typeof statement.iterate === "function") {
|
|
315
|
+
const iterate = statement.iterate.bind(statement);
|
|
316
|
+
Object.defineProperty(statement, "iterate", {
|
|
317
|
+
configurable: true,
|
|
318
|
+
value: (...args) => {
|
|
319
|
+
const iterator = !timeoutSetter && !timeoutQuery ? withinDeadline(() => iterate(...args)) : iterate(...args);
|
|
320
|
+
const next = iterator.next.bind(iterator);
|
|
321
|
+
if (timeoutSetter)
|
|
322
|
+
timeoutState.current = readTimeout();
|
|
323
|
+
iterator.next = () => {
|
|
324
|
+
if (timeoutQuery)
|
|
325
|
+
return next();
|
|
326
|
+
if (!timeoutSetter)
|
|
327
|
+
return withinDeadline(next);
|
|
328
|
+
const result = next();
|
|
329
|
+
timeoutState.current = readTimeout();
|
|
330
|
+
return result;
|
|
331
|
+
};
|
|
332
|
+
return iterator;
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
return statement;
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
}
|
|
169
340
|
function installTransactionRouting(db, readonly) {
|
|
170
341
|
const nativeExec = db.exec.bind(db);
|
|
171
342
|
Object.defineProperty(db, "exec", {
|
|
@@ -303,7 +474,7 @@ function wrapRemainingTagWriteForms(statement) {
|
|
|
303
474
|
});
|
|
304
475
|
}
|
|
305
476
|
}
|
|
306
|
-
function trackSqliteConnection(db, filename, options) {
|
|
477
|
+
function trackSqliteConnection(db, filename, options, turnDeadlines = false) {
|
|
307
478
|
const originalClose = db.close.bind(db);
|
|
308
479
|
const sequence = nextSqliteConnectionSequence++;
|
|
309
480
|
const metadata = {
|
|
@@ -311,6 +482,8 @@ function trackSqliteConnection(db, filename, options) {
|
|
|
311
482
|
filename: typeof filename === "string" ? filename : Buffer.isBuffer(filename) ? "<buffer>" : ":memory:",
|
|
312
483
|
readonly: Boolean(options) && typeof options === "object" && (options.readonly === true || options.readOnly === true)
|
|
313
484
|
};
|
|
485
|
+
if (turnDeadlines)
|
|
486
|
+
installNativeDeadlineRouting(db);
|
|
314
487
|
installTransactionRouting(db, metadata.readonly);
|
|
315
488
|
Object.defineProperty(db, "close", {
|
|
316
489
|
configurable: true,
|
|
@@ -363,6 +536,12 @@ function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
|
363
536
|
return NodeSqliteDatabase;
|
|
364
537
|
}
|
|
365
538
|
var Database = TrackedDatabase;
|
|
539
|
+
function createSqliteTurnDatabase(filename, options) {
|
|
540
|
+
return trackSqliteConnection(new DatabaseImpl(filename, options), filename, options, true);
|
|
541
|
+
}
|
|
542
|
+
function hasSqliteTurnDeadlineRouting(db) {
|
|
543
|
+
return busyTimeoutStates.has(db);
|
|
544
|
+
}
|
|
366
545
|
function getSqliteDatabasePath(db) {
|
|
367
546
|
for (const connection of trackedSqliteConnections.values()) {
|
|
368
547
|
if (connection.reference.deref() === db) {
|
|
@@ -382,6 +561,11 @@ function pragmaValue(db, name) {
|
|
|
382
561
|
return row[name] ?? Object.values(row)[0];
|
|
383
562
|
}
|
|
384
563
|
function pragmaNumber(db, name) {
|
|
564
|
+
if (name === "busy_timeout") {
|
|
565
|
+
const state = busyTimeoutStates.get(db);
|
|
566
|
+
if (state)
|
|
567
|
+
return state.current;
|
|
568
|
+
}
|
|
385
569
|
try {
|
|
386
570
|
const value = pragmaValue(db, name);
|
|
387
571
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
@@ -447,11 +631,34 @@ function prepareCachedStatement(db, sql) {
|
|
|
447
631
|
return ownPreparedStatement(db, db.prepare(sql));
|
|
448
632
|
}
|
|
449
633
|
var privilegeDepth = new WeakMap;
|
|
634
|
+
var nativeWaitScope;
|
|
635
|
+
function releaseNativeWaitLease(lease) {
|
|
636
|
+
lease.active = false;
|
|
637
|
+
lease.remainingMs = undefined;
|
|
638
|
+
}
|
|
639
|
+
function withSqliteTurnDeadline(remainingMs, operation) {
|
|
640
|
+
const scope = nativeWaitScope ??= new AsyncLocalStorage;
|
|
641
|
+
const lease = { active: true, remainingMs };
|
|
642
|
+
return scope.run(lease, () => {
|
|
643
|
+
try {
|
|
644
|
+
const result = operation();
|
|
645
|
+
if (result && typeof result.then === "function")
|
|
646
|
+
return Promise.resolve(result).finally(releaseNativeWaitLease.bind(null, lease));
|
|
647
|
+
releaseNativeWaitLease(lease);
|
|
648
|
+
return result;
|
|
649
|
+
} catch (error) {
|
|
650
|
+
releaseNativeWaitLease(lease);
|
|
651
|
+
throw error;
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
}
|
|
450
655
|
var transformPassScope = new AsyncLocalStorage;
|
|
451
656
|
var admissionScope = new AsyncLocalStorage;
|
|
452
657
|
var backgroundWriterScope = new AsyncLocalStorage;
|
|
453
658
|
function withSqliteBackgroundWriter(operation) {
|
|
454
|
-
|
|
659
|
+
if (!nativeWaitScope?.getStore())
|
|
660
|
+
return backgroundWriterScope.run(true, operation);
|
|
661
|
+
return nativeWaitScope.run(undefined, () => backgroundWriterScope.run(true, operation));
|
|
455
662
|
}
|
|
456
663
|
function withSqliteTransformPass(operation) {
|
|
457
664
|
const existing = transformPassScope.getStore();
|
|
@@ -482,7 +689,9 @@ function withSqliteTransformPass(operation) {
|
|
|
482
689
|
return typeof reservation === "function" ? run(reservation) : reservation.then(run);
|
|
483
690
|
}
|
|
484
691
|
function withoutSqliteTransformPass(operation) {
|
|
485
|
-
|
|
692
|
+
if (!nativeWaitScope?.getStore())
|
|
693
|
+
return transformPassScope.run(undefined, operation);
|
|
694
|
+
return nativeWaitScope.run(undefined, () => transformPassScope.run(undefined, operation));
|
|
486
695
|
}
|
|
487
696
|
function guardSqliteTransformPass(guard) {
|
|
488
697
|
const lease = transformPassScope.getStore();
|
|
@@ -656,7 +865,7 @@ async function withAsyncPrivilegedWriter(db, operation, options = {}) {
|
|
|
656
865
|
} catch (error) {
|
|
657
866
|
if (entered || !(error instanceof SqliteAcquisitionBusyError))
|
|
658
867
|
throw error;
|
|
659
|
-
options.beforeRetry?.(error);
|
|
868
|
+
await options.beforeRetry?.(error);
|
|
660
869
|
const elapsed = performance.now() - started;
|
|
661
870
|
if (elapsed >= budgetMs) {
|
|
662
871
|
reportSqliteDiagnostic(`sqlite writer site=privileged_writer lane=foreground acquire_ms=${Math.round(elapsed)} attempts=${attempts} outcome=busy`);
|
|
@@ -791,4 +1000,4 @@ async function withIndexChunk(input, operation) {
|
|
|
791
1000
|
}
|
|
792
1001
|
}
|
|
793
1002
|
|
|
794
|
-
export { inRootAsyncContext, registerSlowWriteReporter, registerSqliteDiagnosticSink, detectSqliteRuntime, getTagIdentityWriteGeneration, Database, getSqliteDatabasePath, prepareCachedStatement, withSqliteBackgroundWriter, withSqliteTransformPass, withoutSqliteTransformPass, guardSqliteTransformPass, isTransientSqliteError, withAsyncPrivilegedWriter, withPrivilegedWriter, indexCoordinationInput, withIndexChunk };
|
|
1003
|
+
export { inRootAsyncContext, registerSlowWriteReporter, registerSqliteDiagnosticSink, detectSqliteRuntime, getTagIdentityWriteGeneration, Database, createSqliteTurnDatabase, hasSqliteTurnDeadlineRouting, getSqliteDatabasePath, prepareCachedStatement, withSqliteTurnDeadline, withSqliteBackgroundWriter, withSqliteTransformPass, withoutSqliteTransformPass, guardSqliteTransformPass, isTransientSqliteError, withAsyncPrivilegedWriter, withPrivilegedWriter, indexCoordinationInput, withIndexChunk };
|