@pond-ts/process 0.54.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/CHANGELOG.md +5914 -0
- package/LICENSE +21 -0
- package/README.md +345 -0
- package/dist/cjs-fallback.cjs +15 -0
- package/dist/column.d.ts +197 -0
- package/dist/column.js +306 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.js +25 -0
- package/dist/graph.d.ts +89 -0
- package/dist/graph.js +133 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.js +45 -0
- package/dist/node.d.ts +151 -0
- package/dist/node.js +268 -0
- package/dist/plan/builder.d.ts +138 -0
- package/dist/plan/builder.js +166 -0
- package/dist/plan/fluent.d.ts +93 -0
- package/dist/plan/fluent.js +140 -0
- package/dist/plan/folds.d.ts +25 -0
- package/dist/plan/folds.js +190 -0
- package/dist/plan/graph.d.ts +171 -0
- package/dist/plan/graph.js +658 -0
- package/dist/plan/history.d.ts +61 -0
- package/dist/plan/history.js +82 -0
- package/dist/plan/host.d.ts +173 -0
- package/dist/plan/host.js +234 -0
- package/dist/plan/identity.d.ts +81 -0
- package/dist/plan/identity.js +158 -0
- package/dist/plan/params.d.ts +15 -0
- package/dist/plan/params.js +26 -0
- package/dist/plan/registry.d.ts +162 -0
- package/dist/plan/registry.js +422 -0
- package/dist/plan/run.d.ts +211 -0
- package/dist/plan/run.js +360 -0
- package/dist/plan/slots.d.ts +65 -0
- package/dist/plan/slots.js +114 -0
- package/dist/plan/source.d.ts +49 -0
- package/dist/plan/source.js +54 -0
- package/dist/plan/types.d.ts +376 -0
- package/dist/plan/types.js +20 -0
- package/dist/pool/index.d.ts +15 -0
- package/dist/pool/index.js +12 -0
- package/dist/pool/pool.d.ts +92 -0
- package/dist/pool/pool.js +237 -0
- package/dist/pool/protocol.d.ts +48 -0
- package/dist/pool/protocol.js +9 -0
- package/dist/pool/wire.d.ts +52 -0
- package/dist/pool/wire.js +95 -0
- package/dist/pool/worker.d.ts +22 -0
- package/dist/pool/worker.js +80 -0
- package/dist/port.d.ts +79 -0
- package/dist/port.js +222 -0
- package/dist/source.d.ts +161 -0
- package/dist/source.js +182 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.js +26 -0
- package/package.json +50 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `bind` and plan compilation — [PND-DEMOM0].
|
|
3
|
+
*
|
|
4
|
+
* A **bound graph** is one source plus the nodes compiled against it.
|
|
5
|
+
* Identity is scoped to the binding, which is what makes `specId` safe as
|
|
6
|
+
* a cache key: the id names the computation, not the data, so two
|
|
7
|
+
* instruments sharing one id-space would answer for each other. One
|
|
8
|
+
* graph per binding; hosts own graph lifecycle, the graph owns
|
|
9
|
+
* memoization.
|
|
10
|
+
*/
|
|
11
|
+
import { ProcessError } from '../errors.js';
|
|
12
|
+
import { type Node } from '../node.js';
|
|
13
|
+
import type { Column, SeriesSchema, TimeSeries } from 'pond-ts';
|
|
14
|
+
import type { Registry } from './registry.js';
|
|
15
|
+
import { type FactBody, type Params, type Spec, type Units } from './types.js';
|
|
16
|
+
/** Thrown when an op demands an input unit its source does not carry. */
|
|
17
|
+
export declare class UnitError extends ProcessError {
|
|
18
|
+
}
|
|
19
|
+
/** One node per spec, plus the spec and params it was compiled from. */
|
|
20
|
+
interface Compiled {
|
|
21
|
+
readonly id: string;
|
|
22
|
+
readonly spec: Spec;
|
|
23
|
+
readonly params: Params;
|
|
24
|
+
readonly node: Node<any, any>;
|
|
25
|
+
readonly outlets: Readonly<Record<string, string>>;
|
|
26
|
+
/** True when the node ends in a fact. Its `outlets` are then empty. */
|
|
27
|
+
readonly fold: boolean;
|
|
28
|
+
/** Ids this node reads from — for unwinding a chain on eviction. */
|
|
29
|
+
readonly upstream: readonly string[];
|
|
30
|
+
/** Ids reading from this node. Non-empty ⇒ evicting it frees nothing. */
|
|
31
|
+
readonly dependents: Set<string>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A source plus every node compiled against it.
|
|
35
|
+
*
|
|
36
|
+
* ## The budget — [PND-PROCCACHE]
|
|
37
|
+
*
|
|
38
|
+
* Every distinct spec ever compiled used to be retained forever, so
|
|
39
|
+
* memory scaled with *questions asked* rather than with anything
|
|
40
|
+
* bounded. A session that walks a slider from period 20 to 200 leaves
|
|
41
|
+
* 180 nodes holding 180 result columns, and nothing ever drops one.
|
|
42
|
+
*
|
|
43
|
+
* The ticket framed this as an op-level cache: an op declares which of
|
|
44
|
+
* its inputs key a result, and the engine memoizes around `compute`.
|
|
45
|
+
* **Half of that is already true here and should not be rebuilt.** A
|
|
46
|
+
* spec's `specId` is content-addressed over its op, params and inputs,
|
|
47
|
+
* so asking the same question twice hits the same node by construction —
|
|
48
|
+
* there is nothing for an op to declare, and a per-op cache would be a
|
|
49
|
+
* second key beside a correct one.
|
|
50
|
+
*
|
|
51
|
+
* What was genuinely missing is the other half, and the ticket is right
|
|
52
|
+
* that it does not belong to the op: **a per-op capacity is a per-op
|
|
53
|
+
* promise, and nothing supervises the total.** Measured at 20 nodes ×
|
|
54
|
+
* 5 entries of a 200k-row result, a per-op cap held 100 entries and
|
|
55
|
+
* 157 MB where one engine-wide cap held 10 and 35 MB.
|
|
56
|
+
*
|
|
57
|
+
* So the budget is graph-wide, in **bytes** rather than entries — the
|
|
58
|
+
* unit that means anything, and only knowable since [PND-PROCCOL] made
|
|
59
|
+
* node values columns with a reportable `columnBytes`. Eviction is LRU
|
|
60
|
+
* with one constraint: a node feeding a retained node is skipped,
|
|
61
|
+
* because dropping it frees nothing while its consumer still holds the
|
|
62
|
+
* outlet.
|
|
63
|
+
*/
|
|
64
|
+
export declare class BoundGraph {
|
|
65
|
+
#private;
|
|
66
|
+
readonly registry: Registry;
|
|
67
|
+
readonly units: Units;
|
|
68
|
+
constructor(series: TimeSeries<SeriesSchema>, options: {
|
|
69
|
+
registry: Registry;
|
|
70
|
+
units?: Units;
|
|
71
|
+
budgetBytes?: number;
|
|
72
|
+
});
|
|
73
|
+
/** Bytes currently retained across every materialized node value. */
|
|
74
|
+
get retainedBytes(): number;
|
|
75
|
+
/** How many nodes the budget has dropped over this graph's life. */
|
|
76
|
+
get evictions(): number;
|
|
77
|
+
/**
|
|
78
|
+
* Recomputes that ran ranged, and that ran whole — [PND-PROCRANGE].
|
|
79
|
+
*
|
|
80
|
+
* Worth having as a counter rather than inferring it from timings: a
|
|
81
|
+
* node silently falling back to a full recompute is the failure mode
|
|
82
|
+
* here, and it looks exactly like "the optimisation did not help much".
|
|
83
|
+
*/
|
|
84
|
+
get recomputes(): {
|
|
85
|
+
ranged: number;
|
|
86
|
+
full: number;
|
|
87
|
+
};
|
|
88
|
+
/** Rows still owed per node, for tests and for `explain`. */
|
|
89
|
+
get pendingFrom(): ReadonlyMap<string, number>;
|
|
90
|
+
/**
|
|
91
|
+
* Drops least-recently-used nodes until the graph is inside its byte
|
|
92
|
+
* budget. Called after a run resolves; safe to call at any time.
|
|
93
|
+
*
|
|
94
|
+
* A node that feeds a retained node is skipped — its consumer holds
|
|
95
|
+
* the outlet, so dropping the lookup frees nothing and would only
|
|
96
|
+
* force a recompile on the next pull.
|
|
97
|
+
*/
|
|
98
|
+
enforceBudget(): void;
|
|
99
|
+
/** Replaces the bound data. Every node downstream goes dirty. */
|
|
100
|
+
setSource(series: TimeSeries<SeriesSchema>): void;
|
|
101
|
+
/**
|
|
102
|
+
* Replaces the bound data, declaring that rows before `changedFrom`
|
|
103
|
+
* are unchanged — [PND-PROCRANGE].
|
|
104
|
+
*
|
|
105
|
+
* This is the whole input to ranged recompute: a node that declares a
|
|
106
|
+
* `lookback` and a `runRange` then rebuilds only
|
|
107
|
+
* `[changedFrom - lookback, length)` instead of the whole column.
|
|
108
|
+
*
|
|
109
|
+
* **The claim is the caller's to keep.** Nothing here verifies that
|
|
110
|
+
* the earlier rows really are untouched, because verifying costs the
|
|
111
|
+
* scan the whole feature exists to avoid. Pass a row that is genuinely
|
|
112
|
+
* at or before the first difference — a live feed appending a bar
|
|
113
|
+
* passes the old length, which is the case this is built for. Getting
|
|
114
|
+
* it wrong yields a stale prefix rather than an error, so when in
|
|
115
|
+
* doubt use {@link setSource}, which recomputes everything.
|
|
116
|
+
*/
|
|
117
|
+
setSourceFrom(series: TimeSeries<SeriesSchema>, changedFrom: number): void;
|
|
118
|
+
get series(): TimeSeries<SeriesSchema>;
|
|
119
|
+
/** Ids currently compiled. Node lifetime is a budget question — see [PND-PROCCACHE]. */
|
|
120
|
+
get ids(): string[];
|
|
121
|
+
get(id: string): Compiled | undefined;
|
|
122
|
+
/**
|
|
123
|
+
* Compiles a spec (and its inputs) into nodes, memoized by `specId`.
|
|
124
|
+
*
|
|
125
|
+
* **A returned handle is not durable under a byte budget.** Eviction
|
|
126
|
+
* disconnects a node's inlets, so a `Compiled` held across a `run` can
|
|
127
|
+
* throw `UnconnectedInputError` on a later pull, naming the input
|
|
128
|
+
* rather than the budget that took it. `run` re-resolves through
|
|
129
|
+
* `columnOf` and never hits this; a caller holding its own handle
|
|
130
|
+
* should re-`compile` after any run, which is a memoized lookup when
|
|
131
|
+
* the node survived. Only relevant with `budgetBytes` set — without
|
|
132
|
+
* one, nothing is ever evicted.
|
|
133
|
+
*
|
|
134
|
+
* Validation happens here rather than at pull time so a bad plan is
|
|
135
|
+
* rejected before any work: params first, then arity, then the typed
|
|
136
|
+
* input check.
|
|
137
|
+
*/
|
|
138
|
+
compile(spec: Spec): Compiled;
|
|
139
|
+
/** Reads one output column of a compiled spec, by output suffix. */
|
|
140
|
+
columnOf(compiled: Compiled, suffix: string): Column;
|
|
141
|
+
/**
|
|
142
|
+
* Reads a fold's fact.
|
|
143
|
+
*
|
|
144
|
+
* The same memoized pull `columnOf` does, which is the whole change:
|
|
145
|
+
* the value is cached against the node's version like any column, so
|
|
146
|
+
* asking twice costs a version check rather than a rescan.
|
|
147
|
+
*/
|
|
148
|
+
factOf(compiled: Compiled): FactBody;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Binds a dataset, producing a graph its plans resolve against.
|
|
152
|
+
*
|
|
153
|
+
* One graph per data binding — two instruments get two graphs and share
|
|
154
|
+
* no nodes, even though their specs produce identical ids.
|
|
155
|
+
*/
|
|
156
|
+
export declare function bind(series: TimeSeries<SeriesSchema>, options: {
|
|
157
|
+
registry: Registry;
|
|
158
|
+
units?: Units;
|
|
159
|
+
/**
|
|
160
|
+
* Cap on retained node values, in bytes — [PND-PROCCACHE]. Unbounded
|
|
161
|
+
* when omitted, which is the behaviour every existing caller has.
|
|
162
|
+
*
|
|
163
|
+
* Bytes rather than entries because entries are not the unit anyone
|
|
164
|
+
* has a limit in: one node over 1M rows outweighs fifty over 5,000.
|
|
165
|
+
* Enforced after each `run`, LRU, skipping any node whose consumer
|
|
166
|
+
* still holds its outlet.
|
|
167
|
+
*/
|
|
168
|
+
budgetBytes?: number;
|
|
169
|
+
}): BoundGraph;
|
|
170
|
+
export {};
|
|
171
|
+
//# sourceMappingURL=graph.d.ts.map
|