footprintjs 9.32.0 → 9.34.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/AGENTS.md +670 -194
- package/dist/esm/lib/capture/freeze.d.ts +47 -0
- package/dist/esm/lib/capture/freeze.js +60 -0
- package/dist/esm/lib/capture/index.d.ts +1 -0
- package/dist/esm/lib/capture/index.js +2 -1
- package/dist/esm/lib/detach/drivers/immediate.d.ts +25 -24
- package/dist/esm/lib/detach/drivers/immediate.js +26 -25
- package/dist/esm/lib/detach/drivers/microtaskBatch.d.ts +5 -4
- package/dist/esm/lib/detach/drivers/microtaskBatch.js +6 -5
- package/dist/esm/lib/engine/handlers/SubflowExecutor.js +27 -7
- package/dist/esm/lib/engine/handlers/SubflowInputMapper.d.ts +4 -1
- package/dist/esm/lib/engine/handlers/SubflowInputMapper.js +15 -2
- package/dist/esm/lib/memory/EventLog.d.ts +28 -3
- package/dist/esm/lib/memory/EventLog.js +31 -4
- package/dist/esm/lib/memory/StageContext.d.ts +20 -0
- package/dist/esm/lib/memory/StageContext.js +36 -10
- package/dist/esm/lib/memory/TransactionBuffer.d.ts +2 -2
- package/dist/esm/lib/memory/TransactionBuffer.js +6 -4
- package/dist/esm/lib/memory/backtrack.d.ts +24 -0
- package/dist/esm/lib/memory/backtrack.js +52 -41
- package/dist/esm/lib/memory/commitLogUtils.d.ts +129 -38
- package/dist/esm/lib/memory/commitLogUtils.js +252 -59
- package/dist/esm/lib/memory/deltaEncoding.d.ts +1 -1
- package/dist/esm/lib/memory/deltaEncoding.js +2 -2
- package/dist/esm/lib/memory/honesty.d.ts +5 -1
- package/dist/esm/lib/memory/honesty.js +11 -6
- package/dist/esm/lib/memory/index.d.ts +2 -2
- package/dist/esm/lib/memory/index.js +3 -3
- package/dist/esm/lib/memory/keyPaths.d.ts +125 -0
- package/dist/esm/lib/memory/keyPaths.js +227 -0
- package/dist/esm/lib/memory/logModel.d.ts +76 -0
- package/dist/esm/lib/memory/logModel.js +357 -0
- package/dist/esm/lib/memory/placeholders.d.ts +3 -3
- package/dist/esm/lib/memory/placeholders.js +4 -4
- package/dist/esm/lib/memory/redaction.d.ts +34 -1
- package/dist/esm/lib/memory/redaction.js +55 -4
- package/dist/esm/lib/memory/utils.d.ts +2 -6
- package/dist/esm/lib/memory/utils.js +4 -21
- package/dist/esm/lib/memory/verbs.d.ts +65 -22
- package/dist/esm/lib/memory/verbs.js +64 -23
- package/dist/esm/lib/runner/ExecutionRuntime.js +5 -3
- package/dist/esm/lib/runner/FlowChartExecutor.js +5 -5
- package/dist/esm/lib/scope/protection/readonlyInput.d.ts +2 -6
- package/dist/esm/lib/scope/protection/readonlyInput.js +4 -18
- package/dist/esm/lib/slice/elementProvenance.d.ts +4 -1
- package/dist/esm/lib/slice/elementProvenance.js +33 -15
- package/dist/esm/lib/slice/forwardSliceForKey.d.ts +4 -0
- package/dist/esm/lib/slice/forwardSliceForKey.js +32 -9
- package/dist/esm/lib/slice/keyIndex.d.ts +50 -8
- package/dist/esm/lib/slice/keyIndex.js +97 -16
- package/dist/esm/lib/slice/keyTimeline.js +11 -6
- package/dist/esm/lib/slice/serialize.js +8 -2
- package/dist/esm/lib/slice/sliceForKey.js +22 -6
- package/dist/esm/lib/slice/types.d.ts +53 -7
- package/dist/esm/lib/slice/types.js +1 -1
- package/dist/esm/lib/time-travel/commitStops.js +46 -8
- package/dist/esm/lib/time-travel/stateAt.js +4 -14
- package/dist/esm/lib/time-travel/timeTravel.js +2 -2
- package/dist/esm/lib/time-travel/types.d.ts +4 -3
- package/dist/esm/lib/time-travel/types.js +1 -1
- package/dist/esm/trace.d.ts +2 -1
- package/dist/esm/trace.js +2 -6
- package/dist/lib/capture/freeze.js +64 -0
- package/dist/lib/capture/index.js +4 -2
- package/dist/lib/detach/drivers/immediate.js +26 -25
- package/dist/lib/detach/drivers/microtaskBatch.js +6 -5
- package/dist/lib/engine/handlers/SubflowExecutor.js +27 -7
- package/dist/lib/engine/handlers/SubflowInputMapper.js +15 -2
- package/dist/lib/memory/EventLog.js +31 -4
- package/dist/lib/memory/StageContext.js +35 -9
- package/dist/lib/memory/TransactionBuffer.js +6 -4
- package/dist/lib/memory/backtrack.js +52 -41
- package/dist/lib/memory/commitLogUtils.js +257 -61
- package/dist/lib/memory/deltaEncoding.js +2 -2
- package/dist/lib/memory/honesty.js +11 -6
- package/dist/lib/memory/index.js +3 -3
- package/dist/lib/memory/keyPaths.js +243 -0
- package/dist/lib/memory/logModel.js +365 -0
- package/dist/lib/memory/placeholders.js +4 -4
- package/dist/lib/memory/redaction.js +56 -3
- package/dist/lib/memory/utils.js +8 -26
- package/dist/lib/memory/verbs.js +64 -23
- package/dist/lib/runner/ExecutionRuntime.js +6 -4
- package/dist/lib/runner/FlowChartExecutor.js +6 -6
- package/dist/lib/scope/protection/readonlyInput.js +6 -21
- package/dist/lib/slice/elementProvenance.js +32 -14
- package/dist/lib/slice/forwardSliceForKey.js +31 -8
- package/dist/lib/slice/keyIndex.js +103 -17
- package/dist/lib/slice/keyTimeline.js +10 -5
- package/dist/lib/slice/serialize.js +8 -2
- package/dist/lib/slice/sliceForKey.js +21 -5
- package/dist/lib/slice/types.js +1 -1
- package/dist/lib/time-travel/commitStops.js +46 -8
- package/dist/lib/time-travel/stateAt.js +4 -14
- package/dist/lib/time-travel/timeTravel.js +2 -2
- package/dist/lib/time-travel/types.js +1 -1
- package/dist/trace.js +5 -7
- package/dist/types/lib/capture/freeze.d.ts +47 -0
- package/dist/types/lib/capture/index.d.ts +1 -0
- package/dist/types/lib/detach/drivers/immediate.d.ts +25 -24
- package/dist/types/lib/detach/drivers/microtaskBatch.d.ts +5 -4
- package/dist/types/lib/engine/handlers/SubflowInputMapper.d.ts +4 -1
- package/dist/types/lib/memory/EventLog.d.ts +28 -3
- package/dist/types/lib/memory/StageContext.d.ts +20 -0
- package/dist/types/lib/memory/TransactionBuffer.d.ts +2 -2
- package/dist/types/lib/memory/backtrack.d.ts +24 -0
- package/dist/types/lib/memory/commitLogUtils.d.ts +129 -38
- package/dist/types/lib/memory/deltaEncoding.d.ts +1 -1
- package/dist/types/lib/memory/honesty.d.ts +5 -1
- package/dist/types/lib/memory/index.d.ts +2 -2
- package/dist/types/lib/memory/keyPaths.d.ts +125 -0
- package/dist/types/lib/memory/logModel.d.ts +76 -0
- package/dist/types/lib/memory/placeholders.d.ts +3 -3
- package/dist/types/lib/memory/redaction.d.ts +34 -1
- package/dist/types/lib/memory/utils.d.ts +2 -6
- package/dist/types/lib/memory/verbs.d.ts +65 -22
- package/dist/types/lib/scope/protection/readonlyInput.d.ts +2 -6
- package/dist/types/lib/slice/elementProvenance.d.ts +4 -1
- package/dist/types/lib/slice/forwardSliceForKey.d.ts +4 -0
- package/dist/types/lib/slice/keyIndex.d.ts +50 -8
- package/dist/types/lib/slice/types.d.ts +53 -7
- package/dist/types/lib/time-travel/types.d.ts +4 -3
- package/dist/types/trace.d.ts +2 -1
- package/package.json +2 -1
|
@@ -4,62 +4,153 @@
|
|
|
4
4
|
* The commitLog is an ordered array of CommitBundle — one per stage commit.
|
|
5
5
|
* These helpers provide type-safe queries without (b: any) casts.
|
|
6
6
|
*/
|
|
7
|
+
import type { RegisteredCode } from './honesty.js';
|
|
7
8
|
import type { CommitBundle } from './types.js';
|
|
8
9
|
import { type Touch } from './verbs.js';
|
|
9
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Find the first commit by `stageId`, optionally the first one that WROTE `key` — under the writer
|
|
12
|
+
* rule: a row on the key, inside it, or around it that changed it (see {@link writersOf}).
|
|
13
|
+
*/
|
|
10
14
|
export declare function findCommit(commitLog: CommitBundle[], stageId: string, key?: string): CommitBundle | undefined;
|
|
11
15
|
/** Find all commits by stageId. */
|
|
12
16
|
export declare function findCommits(commitLog: CommitBundle[], stageId: string): CommitBundle[];
|
|
13
|
-
/** Find the last commit that wrote a specific key (for backtracking). */
|
|
14
|
-
export declare function findLastWriter(commitLog: CommitBundle[], key: string, beforeIdx?: number): CommitBundle | undefined;
|
|
15
17
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* `TraceEntry.path` exactly (DELIM-joined for nested paths). A row whose verb
|
|
19
|
-
* is not one of the four is refused with {@link UnknownVerbError} naming the
|
|
20
|
-
* row — whether or not the fold would have reached it: the answer must not
|
|
21
|
-
* depend on where an optimisation starts.
|
|
18
|
+
* Find the last commit that WROTE `key` before `beforeIdx` (exclusive; default: the whole log) —
|
|
19
|
+
* the anchor of every backward question ("who made it this?").
|
|
22
20
|
*
|
|
23
|
-
*
|
|
21
|
+
* The writer rule (`keyPaths.ts`): a commit writes `key` when one of its rows is ON the key,
|
|
22
|
+
* INSIDE it (a subflow's input seed writes `cfg␟a`; an outputMapper merge-back writes `cfg␟b`;
|
|
23
|
+
* either is a write of `cfg`), or AROUND it with the value at the key different across the commit
|
|
24
|
+
* (a `set` of `cfg` writes `cfg␟a`; a `merge` of `cfg` that never reaches `a` does not). A write
|
|
25
|
+
* found through a row INSIDE the key wrote only PART of its value — the slice readers say so with
|
|
26
|
+
* the `'nested-rows'` note.
|
|
27
|
+
*
|
|
28
|
+
* @param key A DELIM-joined path (`normalisePath`); a top-level key is a one-segment path.
|
|
29
|
+
*/
|
|
30
|
+
export declare function findLastWriter(commitLog: CommitBundle[], key: string, beforeIdx?: number): CommitBundle | undefined;
|
|
31
|
+
/** What {@link writersOf} is asked. */
|
|
32
|
+
export interface WritersOptions {
|
|
33
|
+
/** The last commit ARRAY index considered, inclusive. Default: the whole log. */
|
|
34
|
+
readonly end?: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The ARRAY positions (ascending) of every commit in `commitLog[0..end]` that WROTE `key` — the
|
|
38
|
+
* writer rule of `keyPaths.ts`, the one definition every key query shares (`logModel.ts` applies it).
|
|
39
|
+
*/
|
|
40
|
+
export declare function writersOf(commitLog: readonly CommitBundle[], key: string, options?: WritersOptions): number[];
|
|
41
|
+
/**
|
|
42
|
+
* Every row under `key`'s TOP-LEVEL key in `commitLog[0..end]`, in commit order — the rows the value
|
|
43
|
+
* rule folds ({@link foldKey}), each with its {@link Touch.relation} to `key` (absent for a sibling
|
|
44
|
+
* under the same top-level key: applied, not observed) — found through the log's index. A row whose
|
|
45
|
+
* verb is not one of the four is refused with {@link UnknownVerbError} naming the row — whether or
|
|
46
|
+
* not the fold would have reached it: the answer must not depend on where an optimisation starts.
|
|
24
47
|
*/
|
|
25
|
-
export declare function
|
|
48
|
+
export declare function rowsUnderRoot(commitLog: readonly CommitBundle[], key: string, end: number): Touch[];
|
|
26
49
|
/**
|
|
27
50
|
* Reconstruct the FULL value of `key` as of commit array index `idx`
|
|
28
51
|
* (inclusive) — the migration helper for the "read `bundle.overwrite[key]`
|
|
29
52
|
* as the full value written" pattern (#13c-B).
|
|
30
53
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* (
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* row
|
|
40
|
-
*
|
|
54
|
+
* The value rule (`keyPaths.ts`, 9.33.0): every row under the key's TOP-LEVEL
|
|
55
|
+
* key in `commitLog[0..idx]` is folded, anchored at that key's last `set` /
|
|
56
|
+
* `delete`, with the SAME step and clone discipline the replay uses
|
|
57
|
+
* (`verbs.ts` · `foldKey`), and the result is read at `key`. So the answer is
|
|
58
|
+
* the value `stateAt` gives at that path when it folds the log alone — rows
|
|
59
|
+
* INSIDE the key (a subflow seed, an outputMapper merge-back) and AROUND it (a
|
|
60
|
+
* `set` of the container) count; before 9.33.0 only rows on the exact path did,
|
|
61
|
+
* and a seeded `cfg` read as `undefined`. Under `commitValues: 'delta'`, an
|
|
62
|
+
* `append` row's `overwrite[key]` holds only the TAIL; the fold puts the array
|
|
63
|
+
* back together. Two `merge` rows of one bundle see one copy of the bundle's
|
|
64
|
+
* delta, as the replay's do.
|
|
41
65
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* @param key Matched against `TraceEntry.path` exactly (same contract as
|
|
46
|
-
* `findLastWriter`) — DELIM-joined for nested paths.
|
|
66
|
+
* @param key A DELIM-joined path (`normalisePath`); a top-level key is a
|
|
67
|
+
* one-segment path.
|
|
47
68
|
* @param idx CommitBundle ARRAY index (the `bundle.idx` position),
|
|
48
69
|
* inclusive. NOT the executionIndex from a runtimeStageId.
|
|
49
|
-
* @returns The reconstructed value (a detached clone), or `undefined` when
|
|
50
|
-
*
|
|
51
|
-
* delete. Caveat:
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* `stateAt(snapshot, idx)
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
70
|
+
* @returns The reconstructed value (a detached clone), or `undefined` when no
|
|
71
|
+
* row in `commitLog[0..idx]` is on, inside or around the key, or the fold
|
|
72
|
+
* leaves it absent (its last write was a delete). Caveat: a key that held a
|
|
73
|
+
* value in the run's INITIAL state folds from absent here — the log alone
|
|
74
|
+
* cannot see the pre-run base, so merges and nested writes onto a seeded key
|
|
75
|
+
* give only what they added. Since 9.17.0 the base TRAVELS with the log:
|
|
76
|
+
* `stateAt(snapshot, idx)` (footprintjs/trace) folds from
|
|
77
|
+
* `RuntimeSnapshot.initialState`, which this function never receives.
|
|
78
|
+
* @throws {@link UnknownVerbError} when a row under the key's top-level key
|
|
79
|
+
* carries a verb other than `set | merge | append | delete` — a foreign or
|
|
80
|
+
* corrupted log is refused, not folded as a `merge`. Engine-written logs
|
|
81
|
+
* never carry one.
|
|
82
|
+
* @see commitValueAtWithBasis — the same answer, with the codes that say WHY it is
|
|
83
|
+
* `undefined` or partial (and the `initialState` base this function never receives).
|
|
61
84
|
*/
|
|
62
85
|
export declare function commitValueAt(commitLog: CommitBundle[], idx: number, key: string): unknown;
|
|
86
|
+
/**
|
|
87
|
+
* Why {@link commitValueAtWithBasis} answered what it did. Each code is registered, with the one
|
|
88
|
+
* sentence that says what it means, in `memory/honesty.ts · HONESTY_CODES` (served on
|
|
89
|
+
* `footprintjs/trace`); the union declares its members through `RegisteredCode`.
|
|
90
|
+
*
|
|
91
|
+
* - `'never-written'` — no commit in range wrote the key (the writer rule — the answer
|
|
92
|
+
* `findLastWriter` and the slice layer give), unless the run removed a value
|
|
93
|
+
* the passed `initialState` held (then `'deleted'`), or a redaction at or
|
|
94
|
+
* around the key hid the write (then `'redacted'` alone).
|
|
95
|
+
* - `'deleted'` — the answer is `undefined` and the key WAS written: its last write left it
|
|
96
|
+
* absent.
|
|
97
|
+
* - `'nested-rows'` — the value rests on rows INSIDE the key (a subflow seed, an outputMapper
|
|
98
|
+
* merge-back, a fork child's namespace) with no `set`/`delete` of the key or
|
|
99
|
+
* of a container around it in range.
|
|
100
|
+
* - `'from-initial-state'` — no `set`/`delete` of the key or around it in range, so the value rests on
|
|
101
|
+
* the pre-run base: folded from `options.initialState` when it holds the
|
|
102
|
+
* key's top-level key, partial when no `initialState` was passed.
|
|
103
|
+
* - `'redacted'` — a path at, inside or around the key is in the `redactedPaths` of a commit
|
|
104
|
+
* the value rests on (from its last `set`/`delete` on, or the whole range).
|
|
105
|
+
*/
|
|
106
|
+
export type ValueBasis = RegisteredCode<'never-written' | 'deleted' | 'nested-rows' | 'from-initial-state' | 'redacted'>;
|
|
107
|
+
/** What {@link commitValueAtWithBasis} is asked besides the log, the index and the key. */
|
|
108
|
+
export interface ValueBasisOptions {
|
|
109
|
+
/**
|
|
110
|
+
* The state before the run — `RuntimeSnapshot.initialState` (or a subflow's
|
|
111
|
+
* `treeContext.initialState`). When given, a key with no `set`/`delete` in range folds from it, as
|
|
112
|
+
* `stateAt` does; when absent, such an answer is the log-only fold and carries `'from-initial-state'`.
|
|
113
|
+
*/
|
|
114
|
+
readonly initialState?: Readonly<Record<string, unknown>>;
|
|
115
|
+
}
|
|
116
|
+
/** A key's value read off the log, and the codes that say what it rests on — absent codes = an exact answer. */
|
|
117
|
+
export interface ValueWithBasis {
|
|
118
|
+
readonly value: unknown;
|
|
119
|
+
/** In the order of {@link ValueBasis}'s list; EMPTY when a `set`/`delete` of the key or around it anchors the value and no redaction touched it. */
|
|
120
|
+
readonly basis: ValueBasis[];
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* {@link commitValueAt}, with the codes that say what the answer rests on. Without `options.initialState`
|
|
124
|
+
* the value IS `commitValueAt(commitLog, idx, key)` (pinned by a property); with it, a key that has no
|
|
125
|
+
* `set`/`delete` of itself or of a container around it in range folds from that base — the value
|
|
126
|
+
* `stateAt(snapshot, idx)` gives at the key. Refuses an unknown verb exactly as `commitValueAt` does.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* const { value, basis } = commitValueAtWithBasis(snap.commitLog, i, 'cfg', { initialState: snap.initialState });
|
|
131
|
+
* for (const code of basis) console.log(code, HONESTY_CODES[code]);
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
export declare function commitValueAtWithBasis(commitLog: CommitBundle[], idx: number, key: string, options?: ValueBasisOptions): ValueWithBasis;
|
|
135
|
+
/**
|
|
136
|
+
* Why {@link findLastWriterWithBasis} answered what it did — registered in `HONESTY_CODES`:
|
|
137
|
+
* `'never-written'` (no writer before the bound), `'nested-rows'` (the writer reached the key only
|
|
138
|
+
* through rows inside it, so it wrote part of the value), `'redacted'` (no writer the log can see, because a
|
|
139
|
+
* redaction at or around the key hid the write — the rule `commitValueAtWithBasis` follows).
|
|
140
|
+
*/
|
|
141
|
+
export type WriterBasis = RegisteredCode<'never-written' | 'nested-rows' | 'redacted'>;
|
|
142
|
+
/** The last writer of a key, and the codes that say what kind of write it was — absent codes = a write on or around the key. */
|
|
143
|
+
export interface WriterWithBasis {
|
|
144
|
+
/** Absent exactly when `basis` holds `'never-written'` or `'redacted'`. */
|
|
145
|
+
readonly writer?: CommitBundle;
|
|
146
|
+
readonly basis: WriterBasis[];
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* {@link findLastWriter}, with the code that says why: `writer` is `findLastWriter(commitLog, key, beforeIdx)`;
|
|
150
|
+
* `basis` is `['never-written']` when there is none and `['nested-rows']` when that commit wrote the key
|
|
151
|
+
* only through rows inside it.
|
|
152
|
+
*/
|
|
153
|
+
export declare function findLastWriterWithBasis(commitLog: CommitBundle[], key: string, beforeIdx?: number): WriterWithBasis;
|
|
63
154
|
/**
|
|
64
155
|
* Position index over a commit log: `runtimeStageId` → the ARRAY INDEX of the
|
|
65
156
|
* FIRST bundle that stage committed.
|