@camstack/system 1.2.318 → 1.2.320
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/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +3 -77
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +3 -77
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer-apply-waits.d.ts +21 -0
- package/dist/builtins/composer/composer-live-set.d.ts +22 -0
- package/dist/builtins/composer/composer-runtime-factory.d.ts +22 -0
- package/dist/builtins/composer/composer-seeds.d.ts +22 -0
- package/dist/builtins/composer/composer.addon.js +1905 -1809
- package/dist/builtins/composer/composer.addon.mjs +1905 -1809
- package/dist/builtins/composer/composer.d.ts +3 -15
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/retired-collections.d.ts +9 -0
- package/dist/builtins/sqlite-storage/shm-lock-canary.d.ts +60 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +1 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/sqlite-storage/wal-checkpoint-policy.d.ts +115 -34
- package/dist/builtins/sqlite-storage/wal-checkpointer.d.ts +6 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-backup/system-backup.service.d.ts +2 -17
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-BjRPhWtU.js → composition-sources-D4UkcIhl.js} +1 -1
- package/dist/{composition-sources-Cg2MP-qf.mjs → composition-sources-Due6vto8.mjs} +1 -1
- package/dist/{dist-Dcy0gVHu.js → dist-B0AvBZxe.js} +1 -174
- package/dist/{dist-CQ9vXSUh.mjs → dist-XfFiGX64.mjs} +1 -174
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{retired-settings-keys-pzlrLUbA.js → retired-settings-keys-AmO1MZks.js} +1 -1
- package/dist/{retired-settings-keys-DNIbyfTR.mjs → retired-settings-keys-DXI77cc8.mjs} +1 -1
- package/dist/wal-checkpoint-policy-BahrTtyD.mjs +186 -0
- package/dist/wal-checkpoint-policy-d2z2qPqx.js +233 -0
- package/dist/wal-checkpoint-worker.js +63 -57
- package/dist/wal-checkpoint-worker.mjs +63 -57
- package/package.json +1 -1
- package/dist/wal-checkpoint-policy-CAcg63o-.mjs +0 -92
- package/dist/wal-checkpoint-policy-CCJZngds.js +0 -127
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { closeSync, openSync, readSync } from "node:fs";
|
|
1
|
+
import { c as workerStartObservation, o as isWorkerStop, s as nextCheckpointPlan } from "./wal-checkpoint-policy-BahrTtyD.mjs";
|
|
3
2
|
import Database from "better-sqlite3";
|
|
4
3
|
import { parentPort, workerData } from "node:worker_threads";
|
|
5
4
|
//#region src/builtins/sqlite-storage/wal-checkpoint-worker.ts
|
|
@@ -20,9 +19,15 @@ import { parentPort, workerData } from "node:worker_threads";
|
|
|
20
19
|
* writers and readers are never blocked by this thread. (The idle-gated
|
|
21
20
|
* TRUNCATE in `wal-maintenance.ts` is a different job — reclaiming a
|
|
22
21
|
* sidecar that outgrew its limit — and stays where it is.)
|
|
23
|
-
* -
|
|
24
|
-
*
|
|
25
|
-
*
|
|
22
|
+
* - It NEVER touches a SQLite file except through that connection — no
|
|
23
|
+
* `open`/`read`/`close` of the `.db`, `-wal` or `-shm`. Until 2026-09-29 it
|
|
24
|
+
* read the wal-index header out of `-shm` once a second, and each
|
|
25
|
+
* `closeSync` dropped every fcntl lock this PROCESS held on the file —
|
|
26
|
+
* SQLite's DMS lock included — which let the nightly backup's connection
|
|
27
|
+
* rebuild the `-shm` under the runner's mappings: the SIGBUS of D468,
|
|
28
|
+
* diagnosed in D679. `scripts/check-sqlite-files-not-opened-by-fs.ts`
|
|
29
|
+
* refuses the pattern. The schedule is derived from the checkpoints'
|
|
30
|
+
* own answers instead (`nextCheckpointPlan`).
|
|
26
31
|
* - Every checkpoint is reported to the parent with its numbers. The parent
|
|
27
32
|
* decides what is worth a line.
|
|
28
33
|
*
|
|
@@ -46,31 +51,8 @@ function readCheckpointRow(value) {
|
|
|
46
51
|
}
|
|
47
52
|
function isWorkerData(value) {
|
|
48
53
|
if (typeof value !== "object" || value === null) return false;
|
|
49
|
-
if (!("dbPath" in value) || !("pollMs" in value)) return false;
|
|
50
|
-
return typeof value.dbPath === "string" && typeof value.pollMs === "number";
|
|
51
|
-
}
|
|
52
|
-
/** The two wal-index counters, or nulls when the sidecar cannot be read. */
|
|
53
|
-
function readWalIndex(shmPath) {
|
|
54
|
-
let fd = null;
|
|
55
|
-
try {
|
|
56
|
-
fd = openSync(shmPath, "r");
|
|
57
|
-
const buffer = Buffer.alloc(100);
|
|
58
|
-
if (readSync(fd, buffer, 0, 100, 0) < 100) return {
|
|
59
|
-
mxFrame: null,
|
|
60
|
-
nBackfill: null
|
|
61
|
-
};
|
|
62
|
-
return parseWalIndexHeader(buffer) ?? {
|
|
63
|
-
mxFrame: null,
|
|
64
|
-
nBackfill: null
|
|
65
|
-
};
|
|
66
|
-
} catch {
|
|
67
|
-
return {
|
|
68
|
-
mxFrame: null,
|
|
69
|
-
nBackfill: null
|
|
70
|
-
};
|
|
71
|
-
} finally {
|
|
72
|
-
if (fd !== null) closeSync(fd);
|
|
73
|
-
}
|
|
54
|
+
if (!("dbPath" in value) || !("pollMs" in value) || !("maxDelayMs" in value)) return false;
|
|
55
|
+
return typeof value.dbPath === "string" && typeof value.pollMs === "number" && typeof value.maxDelayMs === "number";
|
|
74
56
|
}
|
|
75
57
|
function post(message) {
|
|
76
58
|
parentPort?.postMessage(message);
|
|
@@ -79,45 +61,69 @@ function run() {
|
|
|
79
61
|
const port = parentPort;
|
|
80
62
|
if (port === null) throw new Error("wal-checkpoint-worker: no parent port");
|
|
81
63
|
if (!isWorkerData(workerData)) throw new Error("wal-checkpoint-worker: bad workerData");
|
|
82
|
-
const { dbPath, pollMs } = workerData;
|
|
83
|
-
const shmPath = `${dbPath}-shm`;
|
|
64
|
+
const { dbPath, pollMs, maxDelayMs } = workerData;
|
|
84
65
|
const db = new Database(dbPath);
|
|
85
66
|
db.pragma("cache_size = -2048");
|
|
86
67
|
db.pragma("mmap_size = 0");
|
|
87
|
-
let
|
|
68
|
+
let previous = workerStartObservation(Date.now());
|
|
69
|
+
let first = true;
|
|
88
70
|
let timer = null;
|
|
89
71
|
let stopping = false;
|
|
90
72
|
const tick = () => {
|
|
91
73
|
if (stopping) return;
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const row = readCheckpointRow(raw);
|
|
110
|
-
if (row !== null) post({
|
|
74
|
+
const startedAt = Date.now();
|
|
75
|
+
let raw = null;
|
|
76
|
+
try {
|
|
77
|
+
raw = db.pragma("wal_checkpoint(PASSIVE)");
|
|
78
|
+
} catch (err) {
|
|
79
|
+
post({
|
|
80
|
+
kind: "failed",
|
|
81
|
+
error: err instanceof Error ? err.message : String(err)
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
const row = readCheckpointRow(raw);
|
|
85
|
+
if (row === null) {
|
|
86
|
+
timer = setTimeout(tick, maxDelayMs);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (row.busy !== 0) {
|
|
90
|
+
post({
|
|
111
91
|
kind: "checkpointed",
|
|
112
|
-
reason:
|
|
113
|
-
|
|
92
|
+
reason: first ? "first" : "scheduled",
|
|
93
|
+
appendedFrames: 0,
|
|
94
|
+
nextDelayMs: pollMs,
|
|
114
95
|
walFrames: row.log,
|
|
115
96
|
checkpointedFrames: row.checkpointed,
|
|
116
|
-
busy:
|
|
117
|
-
ms:
|
|
97
|
+
busy: true,
|
|
98
|
+
ms: Date.now() - startedAt
|
|
118
99
|
});
|
|
100
|
+
timer = setTimeout(tick, pollMs);
|
|
101
|
+
return;
|
|
119
102
|
}
|
|
120
|
-
|
|
103
|
+
const current = {
|
|
104
|
+
at: Date.now(),
|
|
105
|
+
walFrames: row.log,
|
|
106
|
+
checkpointedFrames: row.checkpointed
|
|
107
|
+
};
|
|
108
|
+
const plan = nextCheckpointPlan({
|
|
109
|
+
previous,
|
|
110
|
+
current,
|
|
111
|
+
minDelayMs: pollMs,
|
|
112
|
+
maxDelayMs
|
|
113
|
+
});
|
|
114
|
+
post({
|
|
115
|
+
kind: "checkpointed",
|
|
116
|
+
reason: first ? "first" : "scheduled",
|
|
117
|
+
appendedFrames: plan.appendedFrames,
|
|
118
|
+
nextDelayMs: plan.nextDelayMs,
|
|
119
|
+
walFrames: row.log,
|
|
120
|
+
checkpointedFrames: row.checkpointed,
|
|
121
|
+
busy: row.busy !== 0,
|
|
122
|
+
ms: current.at - startedAt
|
|
123
|
+
});
|
|
124
|
+
previous = current;
|
|
125
|
+
first = false;
|
|
126
|
+
timer = setTimeout(tick, plan.nextDelayMs);
|
|
121
127
|
};
|
|
122
128
|
port.on("message", (message) => {
|
|
123
129
|
if (!isWorkerStop(message)) return;
|
package/package.json
CHANGED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Longest the worker lets pending frames sit before folding them, in ms. A
|
|
3
|
-
* quiet database (a developer machine, an agent with little to persist) still
|
|
4
|
-
* gets its WAL folded and its pages made durable within a minute.
|
|
5
|
-
*/
|
|
6
|
-
var WAL_CHECKPOINT_MAX_INTERVAL_MS = 6e4;
|
|
7
|
-
/** How often the worker looks at the wal-index, in ms. A 136-byte read. */
|
|
8
|
-
var WAL_CHECKPOINT_POLL_MS = 1e3;
|
|
9
|
-
/**
|
|
10
|
-
* A checkpoint that took this long is reported at WARN with its numbers.
|
|
11
|
-
* Matched to `SQLITE_SLOW_CALL_MS`: it is the same "the disk held us" event
|
|
12
|
-
* the profiler used to file as a slow `set`, now on the thread that paid it.
|
|
13
|
-
*/
|
|
14
|
-
var WAL_CHECKPOINT_SLOW_MS = 1e3;
|
|
15
|
-
/** Should the worker run `wal_checkpoint(PASSIVE)` now? */
|
|
16
|
-
function decideCheckpoint(input) {
|
|
17
|
-
const intervalDue = input.sinceLastRunMs >= WAL_CHECKPOINT_MAX_INTERVAL_MS;
|
|
18
|
-
if (input.mxFrame === null || input.nBackfill === null) return intervalDue ? {
|
|
19
|
-
run: true,
|
|
20
|
-
reason: "unknown-interval",
|
|
21
|
-
pendingFrames: null
|
|
22
|
-
} : {
|
|
23
|
-
run: false,
|
|
24
|
-
reason: "unknown-below-interval",
|
|
25
|
-
pendingFrames: null
|
|
26
|
-
};
|
|
27
|
-
const pendingFrames = Math.max(0, input.mxFrame - input.nBackfill);
|
|
28
|
-
if (pendingFrames === 0) return {
|
|
29
|
-
run: false,
|
|
30
|
-
reason: "nothing-pending",
|
|
31
|
-
pendingFrames
|
|
32
|
-
};
|
|
33
|
-
if (pendingFrames >= 1e3) return {
|
|
34
|
-
run: true,
|
|
35
|
-
reason: "threshold",
|
|
36
|
-
pendingFrames
|
|
37
|
-
};
|
|
38
|
-
if (intervalDue) return {
|
|
39
|
-
run: true,
|
|
40
|
-
reason: "interval",
|
|
41
|
-
pendingFrames
|
|
42
|
-
};
|
|
43
|
-
return {
|
|
44
|
-
run: false,
|
|
45
|
-
reason: "below-threshold",
|
|
46
|
-
pendingFrames
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Byte offsets in the `-shm` file, from `wal.c` ("WAL-index file format"):
|
|
51
|
-
* two copies of the 48-byte `WalIndexHdr` (copy 2 at 48), then `WalCkptInfo`
|
|
52
|
-
* at 96 whose first field is `nBackfill`. `mxFrame` is at byte 16 of the
|
|
53
|
-
* header. Both are u32 in the writer's native byte order — little-endian on
|
|
54
|
-
* every x86-64 and arm64 node this ships to.
|
|
55
|
-
*/
|
|
56
|
-
var WAL_INDEX_MXFRAME_OFFSET = 16;
|
|
57
|
-
var WAL_INDEX_HDR_SIZE = 48;
|
|
58
|
-
var WAL_INDEX_NBACKFILL_OFFSET = 96;
|
|
59
|
-
/**
|
|
60
|
-
* `mxFrame` and `nBackfill` from the first {@link WAL_INDEX_HEADER_READ_BYTES}
|
|
61
|
-
* of the `-shm` file, or `null` when the buffer is short or the two header
|
|
62
|
-
* copies disagree (a writer was updating them — SQLite's own readers retry on
|
|
63
|
-
* exactly that comparison; this caller simply waits for the next poll).
|
|
64
|
-
*/
|
|
65
|
-
function parseWalIndexHeader(buffer) {
|
|
66
|
-
if (buffer.length < 100) return null;
|
|
67
|
-
const copy1 = buffer.subarray(0, WAL_INDEX_HDR_SIZE);
|
|
68
|
-
const copy2 = buffer.subarray(WAL_INDEX_HDR_SIZE, WAL_INDEX_HDR_SIZE * 2);
|
|
69
|
-
if (!copy1.equals(copy2)) return null;
|
|
70
|
-
return {
|
|
71
|
-
mxFrame: buffer.readUInt32LE(WAL_INDEX_MXFRAME_OFFSET),
|
|
72
|
-
nBackfill: buffer.readUInt32LE(WAL_INDEX_NBACKFILL_OFFSET)
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
function isRecord(value) {
|
|
76
|
-
return typeof value === "object" && value !== null;
|
|
77
|
-
}
|
|
78
|
-
/** Narrow a message off the worker port without a cast. */
|
|
79
|
-
function isWorkerMessage(value) {
|
|
80
|
-
if (!isRecord(value)) return false;
|
|
81
|
-
switch (value["kind"]) {
|
|
82
|
-
case "ready": return true;
|
|
83
|
-
case "failed": return typeof value["error"] === "string";
|
|
84
|
-
case "checkpointed": return typeof value["reason"] === "string" && (typeof value["pendingFrames"] === "number" || value["pendingFrames"] === null) && typeof value["walFrames"] === "number" && typeof value["checkpointedFrames"] === "number" && typeof value["busy"] === "boolean" && typeof value["ms"] === "number";
|
|
85
|
-
default: return false;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
function isWorkerStop(value) {
|
|
89
|
-
return isRecord(value) && value["kind"] === "stop";
|
|
90
|
-
}
|
|
91
|
-
//#endregion
|
|
92
|
-
export { isWorkerStop as a, isWorkerMessage as i, WAL_CHECKPOINT_SLOW_MS as n, parseWalIndexHeader as o, decideCheckpoint as r, WAL_CHECKPOINT_POLL_MS as t };
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Longest the worker lets pending frames sit before folding them, in ms. A
|
|
3
|
-
* quiet database (a developer machine, an agent with little to persist) still
|
|
4
|
-
* gets its WAL folded and its pages made durable within a minute.
|
|
5
|
-
*/
|
|
6
|
-
var WAL_CHECKPOINT_MAX_INTERVAL_MS = 6e4;
|
|
7
|
-
/** How often the worker looks at the wal-index, in ms. A 136-byte read. */
|
|
8
|
-
var WAL_CHECKPOINT_POLL_MS = 1e3;
|
|
9
|
-
/**
|
|
10
|
-
* A checkpoint that took this long is reported at WARN with its numbers.
|
|
11
|
-
* Matched to `SQLITE_SLOW_CALL_MS`: it is the same "the disk held us" event
|
|
12
|
-
* the profiler used to file as a slow `set`, now on the thread that paid it.
|
|
13
|
-
*/
|
|
14
|
-
var WAL_CHECKPOINT_SLOW_MS = 1e3;
|
|
15
|
-
/** Should the worker run `wal_checkpoint(PASSIVE)` now? */
|
|
16
|
-
function decideCheckpoint(input) {
|
|
17
|
-
const intervalDue = input.sinceLastRunMs >= WAL_CHECKPOINT_MAX_INTERVAL_MS;
|
|
18
|
-
if (input.mxFrame === null || input.nBackfill === null) return intervalDue ? {
|
|
19
|
-
run: true,
|
|
20
|
-
reason: "unknown-interval",
|
|
21
|
-
pendingFrames: null
|
|
22
|
-
} : {
|
|
23
|
-
run: false,
|
|
24
|
-
reason: "unknown-below-interval",
|
|
25
|
-
pendingFrames: null
|
|
26
|
-
};
|
|
27
|
-
const pendingFrames = Math.max(0, input.mxFrame - input.nBackfill);
|
|
28
|
-
if (pendingFrames === 0) return {
|
|
29
|
-
run: false,
|
|
30
|
-
reason: "nothing-pending",
|
|
31
|
-
pendingFrames
|
|
32
|
-
};
|
|
33
|
-
if (pendingFrames >= 1e3) return {
|
|
34
|
-
run: true,
|
|
35
|
-
reason: "threshold",
|
|
36
|
-
pendingFrames
|
|
37
|
-
};
|
|
38
|
-
if (intervalDue) return {
|
|
39
|
-
run: true,
|
|
40
|
-
reason: "interval",
|
|
41
|
-
pendingFrames
|
|
42
|
-
};
|
|
43
|
-
return {
|
|
44
|
-
run: false,
|
|
45
|
-
reason: "below-threshold",
|
|
46
|
-
pendingFrames
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Byte offsets in the `-shm` file, from `wal.c` ("WAL-index file format"):
|
|
51
|
-
* two copies of the 48-byte `WalIndexHdr` (copy 2 at 48), then `WalCkptInfo`
|
|
52
|
-
* at 96 whose first field is `nBackfill`. `mxFrame` is at byte 16 of the
|
|
53
|
-
* header. Both are u32 in the writer's native byte order — little-endian on
|
|
54
|
-
* every x86-64 and arm64 node this ships to.
|
|
55
|
-
*/
|
|
56
|
-
var WAL_INDEX_MXFRAME_OFFSET = 16;
|
|
57
|
-
var WAL_INDEX_HDR_SIZE = 48;
|
|
58
|
-
var WAL_INDEX_NBACKFILL_OFFSET = 96;
|
|
59
|
-
/**
|
|
60
|
-
* `mxFrame` and `nBackfill` from the first {@link WAL_INDEX_HEADER_READ_BYTES}
|
|
61
|
-
* of the `-shm` file, or `null` when the buffer is short or the two header
|
|
62
|
-
* copies disagree (a writer was updating them — SQLite's own readers retry on
|
|
63
|
-
* exactly that comparison; this caller simply waits for the next poll).
|
|
64
|
-
*/
|
|
65
|
-
function parseWalIndexHeader(buffer) {
|
|
66
|
-
if (buffer.length < 100) return null;
|
|
67
|
-
const copy1 = buffer.subarray(0, WAL_INDEX_HDR_SIZE);
|
|
68
|
-
const copy2 = buffer.subarray(WAL_INDEX_HDR_SIZE, WAL_INDEX_HDR_SIZE * 2);
|
|
69
|
-
if (!copy1.equals(copy2)) return null;
|
|
70
|
-
return {
|
|
71
|
-
mxFrame: buffer.readUInt32LE(WAL_INDEX_MXFRAME_OFFSET),
|
|
72
|
-
nBackfill: buffer.readUInt32LE(WAL_INDEX_NBACKFILL_OFFSET)
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
function isRecord(value) {
|
|
76
|
-
return typeof value === "object" && value !== null;
|
|
77
|
-
}
|
|
78
|
-
/** Narrow a message off the worker port without a cast. */
|
|
79
|
-
function isWorkerMessage(value) {
|
|
80
|
-
if (!isRecord(value)) return false;
|
|
81
|
-
switch (value["kind"]) {
|
|
82
|
-
case "ready": return true;
|
|
83
|
-
case "failed": return typeof value["error"] === "string";
|
|
84
|
-
case "checkpointed": return typeof value["reason"] === "string" && (typeof value["pendingFrames"] === "number" || value["pendingFrames"] === null) && typeof value["walFrames"] === "number" && typeof value["checkpointedFrames"] === "number" && typeof value["busy"] === "boolean" && typeof value["ms"] === "number";
|
|
85
|
-
default: return false;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
function isWorkerStop(value) {
|
|
89
|
-
return isRecord(value) && value["kind"] === "stop";
|
|
90
|
-
}
|
|
91
|
-
//#endregion
|
|
92
|
-
Object.defineProperty(exports, "WAL_CHECKPOINT_POLL_MS", {
|
|
93
|
-
enumerable: true,
|
|
94
|
-
get: function() {
|
|
95
|
-
return WAL_CHECKPOINT_POLL_MS;
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
Object.defineProperty(exports, "WAL_CHECKPOINT_SLOW_MS", {
|
|
99
|
-
enumerable: true,
|
|
100
|
-
get: function() {
|
|
101
|
-
return WAL_CHECKPOINT_SLOW_MS;
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
Object.defineProperty(exports, "decideCheckpoint", {
|
|
105
|
-
enumerable: true,
|
|
106
|
-
get: function() {
|
|
107
|
-
return decideCheckpoint;
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
Object.defineProperty(exports, "isWorkerMessage", {
|
|
111
|
-
enumerable: true,
|
|
112
|
-
get: function() {
|
|
113
|
-
return isWorkerMessage;
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
Object.defineProperty(exports, "isWorkerStop", {
|
|
117
|
-
enumerable: true,
|
|
118
|
-
get: function() {
|
|
119
|
-
return isWorkerStop;
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
Object.defineProperty(exports, "parseWalIndexHeader", {
|
|
123
|
-
enumerable: true,
|
|
124
|
-
get: function() {
|
|
125
|
-
return parseWalIndexHeader;
|
|
126
|
-
}
|
|
127
|
-
});
|