@claudexor/journal 3.10.5 → 3.12.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/append-batch.d.ts +2 -0
- package/dist/append-batch.d.ts.map +1 -1
- package/dist/append-batch.js +4 -0
- package/dist/append-batch.js.map +1 -1
- package/dist/frame-codec.d.ts +54 -0
- package/dist/frame-codec.d.ts.map +1 -1
- package/dist/frame-codec.js +167 -87
- package/dist/frame-codec.js.map +1 -1
- package/dist/frame-reader.d.ts +30 -0
- package/dist/frame-reader.d.ts.map +1 -0
- package/dist/frame-reader.js +97 -0
- package/dist/frame-reader.js.map +1 -0
- package/dist/index.d.ts +34 -44
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +81 -156
- package/dist/index.js.map +1 -1
- package/dist/journal-background-compaction.d.ts +7 -2
- package/dist/journal-background-compaction.d.ts.map +1 -1
- package/dist/journal-background-compaction.js +79 -78
- package/dist/journal-background-compaction.js.map +1 -1
- package/dist/journal-compaction-chunks.d.ts +29 -0
- package/dist/journal-compaction-chunks.d.ts.map +1 -0
- package/dist/journal-compaction-chunks.js +112 -0
- package/dist/journal-compaction-chunks.js.map +1 -0
- package/dist/journal-compaction.d.ts +27 -5
- package/dist/journal-compaction.d.ts.map +1 -1
- package/dist/journal-compaction.js +22 -4
- package/dist/journal-compaction.js.map +1 -1
- package/dist/journal-core.d.ts +96 -0
- package/dist/journal-core.d.ts.map +1 -0
- package/dist/journal-core.js +173 -0
- package/dist/journal-core.js.map +1 -0
- package/dist/journal-files.d.ts +0 -1
- package/dist/journal-files.d.ts.map +1 -1
- package/dist/journal-files.js +0 -9
- package/dist/journal-files.js.map +1 -1
- package/dist/journal-fold.d.ts +47 -0
- package/dist/journal-fold.d.ts.map +1 -0
- package/dist/journal-fold.js +81 -0
- package/dist/journal-fold.js.map +1 -0
- package/dist/journal-recovery.d.ts +18 -6
- package/dist/journal-recovery.d.ts.map +1 -1
- package/dist/journal-recovery.js +46 -30
- package/dist/journal-recovery.js.map +1 -1
- package/dist/read-only-preparation.d.ts +7 -0
- package/dist/read-only-preparation.d.ts.map +1 -1
- package/dist/read-only-preparation.js +98 -41
- package/dist/read-only-preparation.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { type JournalRecord } from "./frame-codec.js";
|
|
2
|
+
import type { JournalCompactionOutcome, JournalCompactionResult } from "./journal-compaction.js";
|
|
3
|
+
import type { JournalFold } from "./journal-fold.js";
|
|
4
|
+
import { type JournalRecoveryState } from "./journal-recovery-state.js";
|
|
5
|
+
import type { JournalPreparationReceipt } from "./read-only-preparation.js";
|
|
6
|
+
export interface DurableJournalOptions {
|
|
7
|
+
rootDir: string;
|
|
8
|
+
partition: string;
|
|
9
|
+
now?: () => Date;
|
|
10
|
+
epochFactory?: () => string;
|
|
11
|
+
appendAndSync?: (fd: number, bytes: Buffer) => void;
|
|
12
|
+
/** Growth since the last completed maintenance pass that arms a crossing:
|
|
13
|
+
* the file bytes appended after the last background pass that reached the
|
|
14
|
+
* data (an install, a real decline or a failed pass), never the absolute
|
|
15
|
+
* file size, so a partition whose retained set alone exceeds the threshold
|
|
16
|
+
* is compacted once per threshold of new bytes rather than on every append.
|
|
17
|
+
* Under a fold the
|
|
18
|
+
* replay at open is the first completed pass: the baseline starts at the
|
|
19
|
+
* file size minus what the fold retired while replaying, so a restart on an
|
|
20
|
+
* already-compacted partition waits for a threshold of new bytes while a
|
|
21
|
+
* legacy partition whose replay retires a threshold's worth fires at once.
|
|
22
|
+
* Without a fold the baseline starts at zero and the inline open-time
|
|
23
|
+
* compaction keeps its absolute-size trigger. */
|
|
24
|
+
compactionThresholdBytes?: number;
|
|
25
|
+
/** The daemon opts into after-admission maintenance; standalone callers keep inline compaction. */
|
|
26
|
+
deferCompaction?: boolean;
|
|
27
|
+
/** Applied at replay and at background compaction; the retained set is what
|
|
28
|
+
* `records()` sees while epoch/seq/chain state always follow the disk. */
|
|
29
|
+
fold?: JournalFold;
|
|
30
|
+
/** Fired at most once per threshold crossing after an append — a crossing
|
|
31
|
+
* being `compactionThresholdBytes` of growth since the last completed pass —
|
|
32
|
+
* and re-armed when a maintenance pass completes (install, typed decline or
|
|
33
|
+
* a failed pass), so a daemon that dedupes in-flight requests sees every
|
|
34
|
+
* new crossing and a
|
|
35
|
+
* file that stays large never re-fires on every append. Never fires after
|
|
36
|
+
* `close()`. No timers, no persisted state. */
|
|
37
|
+
onCompactionThreshold?: () => void;
|
|
38
|
+
}
|
|
39
|
+
/** Writer state, recovery and physical installation shared by the public
|
|
40
|
+
* `DurableJournal` surface. Not exported from the package entry. */
|
|
41
|
+
export declare abstract class JournalCore {
|
|
42
|
+
readonly options: Readonly<DurableJournalOptions>;
|
|
43
|
+
readonly partitionDir: string;
|
|
44
|
+
readonly path: string;
|
|
45
|
+
protected readonly now: () => Date;
|
|
46
|
+
protected readonly appendFrame: (fd: number, bytes: Buffer) => void;
|
|
47
|
+
protected fd: number;
|
|
48
|
+
protected entries: JournalRecord[];
|
|
49
|
+
protected background: {
|
|
50
|
+
controller: AbortController;
|
|
51
|
+
promise: Promise<JournalCompactionOutcome>;
|
|
52
|
+
} | null;
|
|
53
|
+
protected epoch: string;
|
|
54
|
+
protected nextSeq: number;
|
|
55
|
+
protected previousFrameHash: string;
|
|
56
|
+
protected knownFileBytes: number;
|
|
57
|
+
protected recovery: JournalRecoveryState;
|
|
58
|
+
protected preparationState: JournalPreparationReceipt | null;
|
|
59
|
+
protected writable: boolean;
|
|
60
|
+
protected closed: boolean;
|
|
61
|
+
protected thresholdNotified: boolean;
|
|
62
|
+
/** File size at the last completed pass over the data: a folded replay
|
|
63
|
+
* sets it to the size minus what it retired (0 without a fold), an install
|
|
64
|
+
* to the installed size, and any other settled background pass — a real
|
|
65
|
+
* decline or a failure — to the size it settled at. `atCompactionThreshold`
|
|
66
|
+
* measures growth from it. */
|
|
67
|
+
protected compactionBaselineBytes: number;
|
|
68
|
+
protected replayRetired: {
|
|
69
|
+
count: number;
|
|
70
|
+
bytes: number;
|
|
71
|
+
};
|
|
72
|
+
protected constructor(options: DurableJournalOptions);
|
|
73
|
+
/** Growth-since-last-pass edge: true once the file grew by the threshold
|
|
74
|
+
* beyond the size the last completed pass left (or observed). */
|
|
75
|
+
atCompactionThreshold(): boolean;
|
|
76
|
+
/** Replay the file into the retained set and disk chain state. Returns the
|
|
77
|
+
* pending-suffix bytes recovery discarded; the caller journals that fact. */
|
|
78
|
+
protected recover(): number;
|
|
79
|
+
/** A folded replay is a completed pass: what it retired is the growth still
|
|
80
|
+
* to reclaim (the retired bytes are logical sizes, so the result is clamped
|
|
81
|
+
* at zero). Without a fold nothing was evaluated and the baseline stays 0. */
|
|
82
|
+
protected replayBaselineBytes(): number;
|
|
83
|
+
protected intentPath(): string;
|
|
84
|
+
protected openWriter(): void;
|
|
85
|
+
/** One physical install owner for both producers; no serialization or await. */
|
|
86
|
+
protected installCompaction(result: JournalCompactionResult): void;
|
|
87
|
+
protected closeWriter(): void;
|
|
88
|
+
protected failPreparedActivation(error: unknown): never;
|
|
89
|
+
protected requireRecovery(byteOffset: number, reason: string): Extract<JournalRecoveryState, {
|
|
90
|
+
status: "recovery_required";
|
|
91
|
+
}>;
|
|
92
|
+
protected assertReadable(): void;
|
|
93
|
+
protected assertWritable(): void;
|
|
94
|
+
protected assertOpen(): void;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=journal-core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal-core.d.ts","sourceRoot":"","sources":["../src/journal-core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { closeSync, fstatSync, renameSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fsyncDirectory } from "@claudexor/util";
|
|
4
|
+
import { ZERO_HASH } from "./frame-codec.js";
|
|
5
|
+
import { appendAndSync, openJournalWriter, reopenOriginalWriter } from "./journal-files.js";
|
|
6
|
+
import { journalPartitionDirectory } from "./journal-partition.js";
|
|
7
|
+
import { recoverJournal } from "./journal-recovery.js";
|
|
8
|
+
import { JournalRecoveryRequiredError, journalRecoveryAt, } from "./journal-recovery-state.js";
|
|
9
|
+
const DEFAULT_COMPACTION_THRESHOLD_BYTES = 8 * 1024 * 1024;
|
|
10
|
+
/** Writer state, recovery and physical installation shared by the public
|
|
11
|
+
* `DurableJournal` surface. Not exported from the package entry. */
|
|
12
|
+
export class JournalCore {
|
|
13
|
+
options;
|
|
14
|
+
partitionDir;
|
|
15
|
+
path;
|
|
16
|
+
now;
|
|
17
|
+
appendFrame;
|
|
18
|
+
fd = -1;
|
|
19
|
+
entries = [];
|
|
20
|
+
background = null;
|
|
21
|
+
epoch = "";
|
|
22
|
+
nextSeq = 1;
|
|
23
|
+
previousFrameHash = ZERO_HASH;
|
|
24
|
+
knownFileBytes = 0;
|
|
25
|
+
recovery = { status: "ready", discardedTailBytes: 0 };
|
|
26
|
+
preparationState = null;
|
|
27
|
+
writable = false;
|
|
28
|
+
closed = false;
|
|
29
|
+
thresholdNotified = false;
|
|
30
|
+
/** File size at the last completed pass over the data: a folded replay
|
|
31
|
+
* sets it to the size minus what it retired (0 without a fold), an install
|
|
32
|
+
* to the installed size, and any other settled background pass — a real
|
|
33
|
+
* decline or a failure — to the size it settled at. `atCompactionThreshold`
|
|
34
|
+
* measures growth from it. */
|
|
35
|
+
compactionBaselineBytes = 0;
|
|
36
|
+
replayRetired = { count: 0, bytes: 0 };
|
|
37
|
+
constructor(options) {
|
|
38
|
+
if (!options.partition.trim())
|
|
39
|
+
throw new Error("journal partition must not be empty");
|
|
40
|
+
this.options = Object.freeze({ ...options });
|
|
41
|
+
this.now = options.now ?? (() => new Date());
|
|
42
|
+
this.appendFrame = options.appendAndSync ?? appendAndSync;
|
|
43
|
+
this.partitionDir = journalPartitionDirectory(options.rootDir, options.partition);
|
|
44
|
+
this.path = join(this.partitionDir, "journal.bin");
|
|
45
|
+
}
|
|
46
|
+
/** Growth-since-last-pass edge: true once the file grew by the threshold
|
|
47
|
+
* beyond the size the last completed pass left (or observed). */
|
|
48
|
+
atCompactionThreshold() {
|
|
49
|
+
return (this.knownFileBytes - this.compactionBaselineBytes >=
|
|
50
|
+
(this.options.compactionThresholdBytes ?? DEFAULT_COMPACTION_THRESHOLD_BYTES));
|
|
51
|
+
}
|
|
52
|
+
/** Replay the file into the retained set and disk chain state. Returns the
|
|
53
|
+
* pending-suffix bytes recovery discarded; the caller journals that fact. */
|
|
54
|
+
recover() {
|
|
55
|
+
let result;
|
|
56
|
+
try {
|
|
57
|
+
result = recoverJournal(this.fd, this.path, this.options, this.intentPath());
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (!(error instanceof JournalRecoveryRequiredError))
|
|
61
|
+
throw error;
|
|
62
|
+
this.recovery = error.recovery;
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
this.entries = result.retained;
|
|
66
|
+
this.replayRetired = { count: result.retiredCount, bytes: result.retiredBytes };
|
|
67
|
+
this.epoch = result.epoch ?? this.epoch;
|
|
68
|
+
this.nextSeq = result.nextSeq;
|
|
69
|
+
this.previousFrameHash = result.previousFrameHash;
|
|
70
|
+
this.knownFileBytes = result.knownFileBytes;
|
|
71
|
+
this.compactionBaselineBytes = this.replayBaselineBytes();
|
|
72
|
+
if (result.discardedBytes > 0)
|
|
73
|
+
this.recovery = { status: "ready", discardedTailBytes: result.discardedBytes };
|
|
74
|
+
return result.discardedBytes;
|
|
75
|
+
}
|
|
76
|
+
/** A folded replay is a completed pass: what it retired is the growth still
|
|
77
|
+
* to reclaim (the retired bytes are logical sizes, so the result is clamped
|
|
78
|
+
* at zero). Without a fold nothing was evaluated and the baseline stays 0. */
|
|
79
|
+
replayBaselineBytes() {
|
|
80
|
+
if (!this.options.fold)
|
|
81
|
+
return 0;
|
|
82
|
+
return Math.max(0, this.knownFileBytes - this.replayRetired.bytes);
|
|
83
|
+
}
|
|
84
|
+
intentPath() {
|
|
85
|
+
return join(this.partitionDir, "append.pending.json");
|
|
86
|
+
}
|
|
87
|
+
openWriter() {
|
|
88
|
+
this.fd = openJournalWriter(this.path);
|
|
89
|
+
this.writable = true;
|
|
90
|
+
}
|
|
91
|
+
/** One physical install owner for both producers; no serialization or await. */
|
|
92
|
+
installCompaction(result) {
|
|
93
|
+
const original = fstatSync(this.fd);
|
|
94
|
+
if (result.knownFileBytes >= this.knownFileBytes)
|
|
95
|
+
throw new Error("compaction did not reclaim bytes");
|
|
96
|
+
let renamed = false;
|
|
97
|
+
let closed = false;
|
|
98
|
+
const fd = this.fd;
|
|
99
|
+
this.fd = -1;
|
|
100
|
+
this.writable = false;
|
|
101
|
+
try {
|
|
102
|
+
closeSync(fd);
|
|
103
|
+
closed = true;
|
|
104
|
+
renameSync(result.path, this.path);
|
|
105
|
+
renamed = true;
|
|
106
|
+
fsyncDirectory(dirname(this.path));
|
|
107
|
+
this.openWriter();
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
this.closeWriter();
|
|
111
|
+
if (closed && !renamed) {
|
|
112
|
+
this.fd = reopenOriginalWriter(this.path, original);
|
|
113
|
+
this.writable = this.fd >= 0;
|
|
114
|
+
}
|
|
115
|
+
if (!this.writable)
|
|
116
|
+
throw new JournalRecoveryRequiredError(this.requireRecovery(0, `journal compaction install failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
this.entries = result.records;
|
|
120
|
+
this.epoch = result.epoch;
|
|
121
|
+
this.nextSeq = result.nextSeq;
|
|
122
|
+
this.previousFrameHash = result.previousFrameHash;
|
|
123
|
+
this.knownFileBytes = result.knownFileBytes;
|
|
124
|
+
this.compactionBaselineBytes = result.knownFileBytes;
|
|
125
|
+
this.thresholdNotified = false;
|
|
126
|
+
}
|
|
127
|
+
closeWriter() {
|
|
128
|
+
const fd = this.fd;
|
|
129
|
+
this.fd = -1;
|
|
130
|
+
this.writable = false;
|
|
131
|
+
if (fd < 0)
|
|
132
|
+
return;
|
|
133
|
+
try {
|
|
134
|
+
closeSync(fd);
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
/* best-effort revocation: the handle number is never reused by this writer */
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
failPreparedActivation(error) {
|
|
141
|
+
this.closeWriter();
|
|
142
|
+
this.entries.length = 0;
|
|
143
|
+
this.nextSeq = 1;
|
|
144
|
+
this.previousFrameHash = ZERO_HASH;
|
|
145
|
+
this.knownFileBytes = 0;
|
|
146
|
+
this.compactionBaselineBytes = 0;
|
|
147
|
+
const recovery = error instanceof JournalRecoveryRequiredError
|
|
148
|
+
? error.recovery
|
|
149
|
+
: this.requireRecovery(0, `prepared activation failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
150
|
+
this.recovery = structuredClone(recovery);
|
|
151
|
+
throw new JournalRecoveryRequiredError(recovery);
|
|
152
|
+
}
|
|
153
|
+
requireRecovery(byteOffset, reason) {
|
|
154
|
+
this.recovery = journalRecoveryAt(byteOffset, reason);
|
|
155
|
+
this.background?.controller.abort();
|
|
156
|
+
return this.recovery;
|
|
157
|
+
}
|
|
158
|
+
assertReadable() {
|
|
159
|
+
this.assertOpen();
|
|
160
|
+
if (this.recovery.status === "recovery_required") {
|
|
161
|
+
throw new JournalRecoveryRequiredError(this.recovery);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
assertWritable() {
|
|
165
|
+
if (!this.writable)
|
|
166
|
+
throw new Error("journal preparation is not activated");
|
|
167
|
+
}
|
|
168
|
+
assertOpen() {
|
|
169
|
+
if (this.closed)
|
|
170
|
+
throw new Error("journal writer is closed");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=journal-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal-core.js","sourceRoot":"","sources":["../src/journal-core.ts"],"names":[],"mappings":"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"}
|
package/dist/journal-files.d.ts
CHANGED
|
@@ -13,7 +13,6 @@ export declare function appendAndSync(fd: number, bytes: Buffer): void;
|
|
|
13
13
|
* lack FILE_WRITE_DATA, required by NtSetInformationFile's EOF operation. */
|
|
14
14
|
export declare function truncatePendingSuffix(fd: number, path: string, offset: number, bytes: number): void;
|
|
15
15
|
export declare function ensurePrivateFile(path: string): void;
|
|
16
|
-
export declare function readDescriptor(fd: number): Buffer;
|
|
17
16
|
export declare function readIntent(path: string): AppendIntent | null;
|
|
18
17
|
export declare function writeIntent(path: string, value: AppendIntent): void;
|
|
19
18
|
export declare function removeFile(path: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"journal-files.d.ts","sourceRoot":"","sources":["../src/journal-files.ts"],"names":[],"mappings":"AACA,OAAO,EAcL,KAAK,KAAK,EACX,MAAM,SAAS,CAAC;AAIjB,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,CAAC,CAAC;IACL,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,SAAgB,GAAG,OAAO,CAQ9F;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CActD;AAED,yEAAyE;AACzE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,GAAG,MAAM,CAW1E;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAI7D;AAED;6EAC6E;AAC7E,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,IAAI,CA6BN;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAcpD;AAED,wBAAgB,
|
|
1
|
+
{"version":3,"file":"journal-files.d.ts","sourceRoot":"","sources":["../src/journal-files.ts"],"names":[],"mappings":"AACA,OAAO,EAcL,KAAK,KAAK,EACX,MAAM,SAAS,CAAC;AAIjB,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,CAAC,CAAC;IACL,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,SAAgB,GAAG,OAAO,CAQ9F;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CActD;AAED,yEAAyE;AACzE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,GAAG,MAAM,CAW1E;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAI7D;AAED;6EAC6E;AAC7E,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,IAAI,CA6BN;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAcpD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAqB5D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAanE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI7C"}
|
package/dist/journal-files.js
CHANGED
|
@@ -94,15 +94,6 @@ export function ensurePrivateFile(path) {
|
|
|
94
94
|
throw new Error("journal path is not a private regular file");
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
-
export function readDescriptor(fd) {
|
|
98
|
-
const size = Number(fstatSync(fd, { bigint: true }).size);
|
|
99
|
-
if (!Number.isSafeInteger(size) || size < 0)
|
|
100
|
-
throw new Error("journal file size is invalid");
|
|
101
|
-
const bytes = readFileSync(fd);
|
|
102
|
-
if (bytes.length !== size)
|
|
103
|
-
throw new Error("journal changed while being read");
|
|
104
|
-
return bytes;
|
|
105
|
-
}
|
|
106
97
|
export function readIntent(path) {
|
|
107
98
|
if (!existsSync(path))
|
|
108
99
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"journal-files.js","sourceRoot":"","sources":["../src/journal-files.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"journal-files.js","sourceRoot":"","sources":["../src/journal-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** One logical journal record as the fold sees it: an ordinary frame or one
|
|
2
|
+
* record inside a compacted snapshot. `byteLength` is the record's serialized
|
|
3
|
+
* logical size in bytes as stored in its source (informational: it feeds the
|
|
4
|
+
* retired-bytes receipt, never a decision). */
|
|
5
|
+
export interface FoldRecord {
|
|
6
|
+
seq: number;
|
|
7
|
+
type: string;
|
|
8
|
+
time: string;
|
|
9
|
+
payload: unknown;
|
|
10
|
+
byteLength: number;
|
|
11
|
+
}
|
|
12
|
+
/** Default (undefined / empty object) = keep. Deterministic. Called once per
|
|
13
|
+
* logical record in seq order, for ordinary frames and for records inside
|
|
14
|
+
* compacted snapshots alike. */
|
|
15
|
+
export interface FoldVerdict {
|
|
16
|
+
/** Do not retain this record (retire/slot/group still apply). */
|
|
17
|
+
drop?: boolean;
|
|
18
|
+
/** Single-holder key: a later record with the same slot drops the earlier holder. */
|
|
19
|
+
slot?: string;
|
|
20
|
+
/** Multi-holder key: registered, never auto-superseded. */
|
|
21
|
+
group?: string;
|
|
22
|
+
/** Drop every retained record currently registered under these slot/group
|
|
23
|
+
* names (applied BEFORE registering this record). */
|
|
24
|
+
retire?: readonly string[];
|
|
25
|
+
}
|
|
26
|
+
/** The policy is supplied by the caller (the daemon); the journal stays generic
|
|
27
|
+
* and never decides WHAT is dead. */
|
|
28
|
+
export interface JournalFold {
|
|
29
|
+
verdict(record: FoldRecord): FoldVerdict;
|
|
30
|
+
}
|
|
31
|
+
/** Identity fold: every record is retained. */
|
|
32
|
+
export declare const keepEverything: JournalFold;
|
|
33
|
+
export interface FoldResult<T> {
|
|
34
|
+
retained: T[];
|
|
35
|
+
retiredCount: number;
|
|
36
|
+
retiredBytes: number;
|
|
37
|
+
}
|
|
38
|
+
/** Streaming fold engine. Records are pushed in seq order; a record dropped by
|
|
39
|
+
* a later verdict leaves no reference behind (tombstones are Map deletions), so
|
|
40
|
+
* memory is proportional to the retained set plus live slot/group names, never
|
|
41
|
+
* to the number of records seen. */
|
|
42
|
+
export interface FoldStream<T> {
|
|
43
|
+
push(record: T, view: FoldRecord): void;
|
|
44
|
+
finish(): FoldResult<T>;
|
|
45
|
+
}
|
|
46
|
+
export declare function foldStream<T>(fold?: JournalFold): FoldStream<T>;
|
|
47
|
+
//# sourceMappingURL=journal-fold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal-fold.d.ts","sourceRoot":"","sources":["../src/journal-fold.ts"],"names":[],"mappings":"AAAA;;;+CAG+C;AAC/C,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;gCAEgC;AAChC,MAAM,WAAW,WAAW;IAC1B,iEAAiE;IACjE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;yDACqD;IACrD,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED;qCACqC;AACrC,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,CAAC;CAC1C;AAED,+CAA+C;AAC/C,eAAO,MAAM,cAAc,EAAE,WAAoD,CAAC;AAElF,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;oCAGoC;AACpC,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxC,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;CACzB;AASD,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,GAAE,WAA4B,GAAG,UAAU,CAAC,CAAC,CAAC,CAoE/E"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/** Identity fold: every record is retained. */
|
|
2
|
+
export const keepEverything = Object.freeze({ verdict: () => ({}) });
|
|
3
|
+
export function foldStream(fold = keepEverything) {
|
|
4
|
+
// Insertion order is seq order; deletions never reorder the survivors.
|
|
5
|
+
const held = new Map();
|
|
6
|
+
const slots = new Map();
|
|
7
|
+
const groups = new Map();
|
|
8
|
+
let nextId = 0;
|
|
9
|
+
let retiredCount = 0;
|
|
10
|
+
let retiredBytes = 0;
|
|
11
|
+
let finished = false;
|
|
12
|
+
const drop = (id) => {
|
|
13
|
+
const entry = held.get(id);
|
|
14
|
+
if (!entry)
|
|
15
|
+
return;
|
|
16
|
+
held.delete(id);
|
|
17
|
+
retiredCount += 1;
|
|
18
|
+
retiredBytes += entry.bytes;
|
|
19
|
+
if (entry.slot !== undefined && slots.get(entry.slot) === id)
|
|
20
|
+
slots.delete(entry.slot);
|
|
21
|
+
if (entry.group !== undefined) {
|
|
22
|
+
const members = groups.get(entry.group);
|
|
23
|
+
members?.delete(id);
|
|
24
|
+
if (members && members.size === 0)
|
|
25
|
+
groups.delete(entry.group);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const retire = (name) => {
|
|
29
|
+
const holder = slots.get(name);
|
|
30
|
+
if (holder !== undefined)
|
|
31
|
+
drop(holder);
|
|
32
|
+
const members = groups.get(name);
|
|
33
|
+
if (members)
|
|
34
|
+
for (const id of [...members])
|
|
35
|
+
drop(id);
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
push(record, view) {
|
|
39
|
+
if (finished)
|
|
40
|
+
throw new Error("journal fold stream is finished");
|
|
41
|
+
const verdict = fold.verdict(view) ?? {};
|
|
42
|
+
if (verdict.retire)
|
|
43
|
+
for (const name of verdict.retire)
|
|
44
|
+
retire(name);
|
|
45
|
+
if (verdict.slot !== undefined) {
|
|
46
|
+
const holder = slots.get(verdict.slot);
|
|
47
|
+
if (holder !== undefined)
|
|
48
|
+
drop(holder);
|
|
49
|
+
}
|
|
50
|
+
if (verdict.drop) {
|
|
51
|
+
retiredCount += 1;
|
|
52
|
+
retiredBytes += view.byteLength;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const id = nextId;
|
|
56
|
+
nextId += 1;
|
|
57
|
+
held.set(id, { record, bytes: view.byteLength, slot: verdict.slot, group: verdict.group });
|
|
58
|
+
if (verdict.slot !== undefined)
|
|
59
|
+
slots.set(verdict.slot, id);
|
|
60
|
+
if (verdict.group !== undefined) {
|
|
61
|
+
let members = groups.get(verdict.group);
|
|
62
|
+
if (!members) {
|
|
63
|
+
members = new Set();
|
|
64
|
+
groups.set(verdict.group, members);
|
|
65
|
+
}
|
|
66
|
+
members.add(id);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
finish() {
|
|
70
|
+
finished = true;
|
|
71
|
+
const retained = [];
|
|
72
|
+
for (const entry of held.values())
|
|
73
|
+
retained.push(entry.record);
|
|
74
|
+
held.clear();
|
|
75
|
+
slots.clear();
|
|
76
|
+
groups.clear();
|
|
77
|
+
return { retained, retiredCount, retiredBytes };
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=journal-fold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal-fold.js","sourceRoot":"","sources":["../src/journal-fold.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { type FrameReadResult } from "./frame-reader.js";
|
|
2
|
+
import type { JournalFold } from "./journal-fold.js";
|
|
3
|
+
export interface RecoveredJournal {
|
|
4
|
+
retained: FrameReadResult["retained"];
|
|
5
|
+
epoch: string | null;
|
|
6
|
+
nextSeq: number;
|
|
7
|
+
previousFrameHash: string;
|
|
6
8
|
knownFileBytes: number;
|
|
7
9
|
discardedBytes: number;
|
|
8
|
-
|
|
10
|
+
retiredCount: number;
|
|
11
|
+
retiredBytes: number;
|
|
12
|
+
}
|
|
13
|
+
/** Recover only the original canonical file. A compaction candidate is never
|
|
14
|
+
* consulted as recovery authority. Returns the retained ACK history for its
|
|
15
|
+
* writer plus the chain state of the last frame on disk. A positional-read
|
|
16
|
+
* failure propagates with its own message; only intent handling is labelled. */
|
|
17
|
+
export declare function recoverJournal(fd: number, path: string, options: {
|
|
18
|
+
partition: string;
|
|
19
|
+
fold?: JournalFold;
|
|
20
|
+
}, intentPath: string): RecoveredJournal;
|
|
9
21
|
//# sourceMappingURL=journal-recovery.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"journal-recovery.d.ts","sourceRoot":"","sources":["../src/journal-recovery.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"journal-recovery.d.ts","sourceRoot":"","sources":["../src/journal-recovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAOrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC;IACtC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;gFAGgF;AAChF,wBAAgB,cAAc,CAC5B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,WAAW,CAAA;CAAE,EAClD,UAAU,EAAE,MAAM,GACjB,gBAAgB,CA8BlB"}
|
package/dist/journal-recovery.js
CHANGED
|
@@ -1,40 +1,56 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { descriptorSize, readFrames } from "./frame-reader.js";
|
|
2
|
+
import { readIntent, removeFile, truncatePendingSuffix, } from "./journal-files.js";
|
|
3
3
|
import { JournalRecoveryRequiredError, journalRecoveryAt } from "./journal-recovery-state.js";
|
|
4
4
|
/** Recover only the original canonical file. A compaction candidate is never
|
|
5
|
-
* consulted as recovery authority. Returns
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
* consulted as recovery authority. Returns the retained ACK history for its
|
|
6
|
+
* writer plus the chain state of the last frame on disk. A positional-read
|
|
7
|
+
* failure propagates with its own message; only intent handling is labelled. */
|
|
8
|
+
export function recoverJournal(fd, path, options, intentPath) {
|
|
9
|
+
const size = descriptorSize(fd);
|
|
10
|
+
let intent;
|
|
9
11
|
try {
|
|
10
|
-
|
|
11
|
-
if (intent) {
|
|
12
|
-
const prefix = replayFrames(bytes.subarray(0, intent.offset), partition);
|
|
13
|
-
if (intent.offset > bytes.length ||
|
|
14
|
-
bytes.length > intent.offset + intent.length ||
|
|
15
|
-
prefix.error ||
|
|
16
|
-
prefix.incompleteOffset !== null) {
|
|
17
|
-
throw required(intent.offset, "append intent does not match the journal prefix");
|
|
18
|
-
}
|
|
19
|
-
discardedBytes = bytes.length - intent.offset;
|
|
20
|
-
if (discardedBytes > 0) {
|
|
21
|
-
truncatePendingSuffix(fd, path, intent.offset, bytes.length);
|
|
22
|
-
bytes = bytes.subarray(0, intent.offset);
|
|
23
|
-
}
|
|
24
|
-
removeFile(intentPath);
|
|
25
|
-
}
|
|
12
|
+
intent = readIntent(intentPath);
|
|
26
13
|
}
|
|
27
14
|
catch (error) {
|
|
28
|
-
if (error instanceof JournalRecoveryRequiredError)
|
|
29
|
-
throw error;
|
|
30
15
|
throw required(0, `append intent is malformed: ${String(error)}`);
|
|
31
16
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
17
|
+
if (!intent) {
|
|
18
|
+
const decoded = readFrames(fd, options.partition, { fold: options.fold });
|
|
19
|
+
if (decoded.incompleteOffset !== null)
|
|
20
|
+
throw required(decoded.incompleteOffset, "unexplained suffix without append intent");
|
|
21
|
+
if (decoded.error)
|
|
22
|
+
throw required(decoded.error.offset, decoded.error.reason);
|
|
23
|
+
return recovered(decoded, size, 0);
|
|
24
|
+
}
|
|
25
|
+
if (intent.offset > size || size > intent.offset + intent.length) {
|
|
26
|
+
throw required(intent.offset, "append intent does not match the journal prefix");
|
|
27
|
+
}
|
|
28
|
+
const decoded = readFrames(fd, options.partition, { limit: intent.offset, fold: options.fold });
|
|
29
|
+
if (decoded.error || decoded.incompleteOffset !== null) {
|
|
30
|
+
throw required(intent.offset, "append intent does not match the journal prefix");
|
|
31
|
+
}
|
|
32
|
+
const discardedBytes = size - intent.offset;
|
|
33
|
+
try {
|
|
34
|
+
if (discardedBytes > 0)
|
|
35
|
+
truncatePendingSuffix(fd, path, intent.offset, size);
|
|
36
|
+
removeFile(intentPath);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw required(intent.offset, `append intent recovery failed: ${String(error)}`);
|
|
40
|
+
}
|
|
41
|
+
return recovered(decoded, intent.offset, discardedBytes);
|
|
42
|
+
}
|
|
43
|
+
function recovered(decoded, knownFileBytes, discardedBytes) {
|
|
44
|
+
return {
|
|
45
|
+
retained: decoded.retained,
|
|
46
|
+
epoch: decoded.epoch,
|
|
47
|
+
nextSeq: decoded.nextSeq,
|
|
48
|
+
previousFrameHash: decoded.previousFrameHash,
|
|
49
|
+
knownFileBytes,
|
|
50
|
+
discardedBytes,
|
|
51
|
+
retiredCount: decoded.retiredCount,
|
|
52
|
+
retiredBytes: decoded.retiredBytes,
|
|
53
|
+
};
|
|
38
54
|
}
|
|
39
55
|
function required(byteOffset, reason) {
|
|
40
56
|
return new JournalRecoveryRequiredError(journalRecoveryAt(byteOffset, reason));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"journal-recovery.js","sourceRoot":"","sources":["../src/journal-recovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"journal-recovery.js","sourceRoot":"","sources":["../src/journal-recovery.ts"],"names":[],"mappings":"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"}
|