@kairos-es/read 0.0.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/LICENSE +28 -0
- package/README.md +538 -0
- package/dist/cjs/EventLogDurability.js +184 -0
- package/dist/cjs/EventLogDurability.js.map +1 -0
- package/dist/cjs/ProjectionRunner.js +478 -0
- package/dist/cjs/ProjectionRunner.js.map +1 -0
- package/dist/cjs/ProjectionStore.js +233 -0
- package/dist/cjs/ProjectionStore.js.map +1 -0
- package/dist/cjs/foldIntoRef.js +36 -0
- package/dist/cjs/foldIntoRef.js.map +1 -0
- package/dist/cjs/inMemoryProjectionStore.js +138 -0
- package/dist/cjs/inMemoryProjectionStore.js.map +1 -0
- package/dist/cjs/index.js +128 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/projectionWiringFault.js +532 -0
- package/dist/cjs/projectionWiringFault.js.map +1 -0
- package/dist/cjs/runProjection.js +117 -0
- package/dist/cjs/runProjection.js.map +1 -0
- package/dist/cjs/runProjections.js +144 -0
- package/dist/cjs/runProjections.js.map +1 -0
- package/dist/cjs/superviseOnProgress.js +580 -0
- package/dist/cjs/superviseOnProgress.js.map +1 -0
- package/dist/cjs/testing.js +143 -0
- package/dist/cjs/testing.js.map +1 -0
- package/dist/dts/EventLogDurability.d.ts +182 -0
- package/dist/dts/EventLogDurability.d.ts.map +1 -0
- package/dist/dts/ProjectionRunner.d.ts +557 -0
- package/dist/dts/ProjectionRunner.d.ts.map +1 -0
- package/dist/dts/ProjectionStore.d.ts +475 -0
- package/dist/dts/ProjectionStore.d.ts.map +1 -0
- package/dist/dts/foldIntoRef.d.ts +39 -0
- package/dist/dts/foldIntoRef.d.ts.map +1 -0
- package/dist/dts/inMemoryProjectionStore.d.ts +11 -0
- package/dist/dts/inMemoryProjectionStore.d.ts.map +1 -0
- package/dist/dts/index.d.ts +185 -0
- package/dist/dts/index.d.ts.map +1 -0
- package/dist/dts/projectionWiringFault.d.ts +260 -0
- package/dist/dts/projectionWiringFault.d.ts.map +1 -0
- package/dist/dts/runProjection.d.ts +185 -0
- package/dist/dts/runProjection.d.ts.map +1 -0
- package/dist/dts/runProjections.d.ts +480 -0
- package/dist/dts/runProjections.d.ts.map +1 -0
- package/dist/dts/superviseOnProgress.d.ts +587 -0
- package/dist/dts/superviseOnProgress.d.ts.map +1 -0
- package/dist/dts/testing.d.ts +207 -0
- package/dist/dts/testing.d.ts.map +1 -0
- package/dist/esm/EventLogDurability.js +175 -0
- package/dist/esm/EventLogDurability.js.map +1 -0
- package/dist/esm/ProjectionRunner.js +468 -0
- package/dist/esm/ProjectionRunner.js.map +1 -0
- package/dist/esm/ProjectionStore.js +223 -0
- package/dist/esm/ProjectionStore.js.map +1 -0
- package/dist/esm/foldIntoRef.js +29 -0
- package/dist/esm/foldIntoRef.js.map +1 -0
- package/dist/esm/inMemoryProjectionStore.js +131 -0
- package/dist/esm/inMemoryProjectionStore.js.map +1 -0
- package/dist/esm/index.js +185 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +4 -0
- package/dist/esm/projectionWiringFault.js +524 -0
- package/dist/esm/projectionWiringFault.js.map +1 -0
- package/dist/esm/runProjection.js +109 -0
- package/dist/esm/runProjection.js.map +1 -0
- package/dist/esm/runProjections.js +137 -0
- package/dist/esm/runProjections.js.map +1 -0
- package/dist/esm/superviseOnProgress.js +571 -0
- package/dist/esm/superviseOnProgress.js.map +1 -0
- package/dist/esm/testing.js +133 -0
- package/dist/esm/testing.js.map +1 -0
- package/package.json +41 -0
- package/src/EventLogDurability.ts +201 -0
- package/src/ProjectionRunner.ts +923 -0
- package/src/ProjectionStore.ts +528 -0
- package/src/foldIntoRef.ts +63 -0
- package/src/inMemoryProjectionStore.ts +163 -0
- package/src/index.ts +218 -0
- package/src/projectionWiringFault.ts +694 -0
- package/src/runProjection.ts +270 -0
- package/src/runProjections.ts +623 -0
- package/src/superviseOnProgress.ts +897 -0
- package/src/testing.ts +290 -0
- package/testing/package.json +6 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.runProjection = exports.projectionLayer = void 0;
|
|
7
|
+
var _effect = require("effect");
|
|
8
|
+
var _ProjectionRunner = require("./ProjectionRunner.js");
|
|
9
|
+
/**
|
|
10
|
+
* Start the daemon maintaining `readModel`, forked into the caller's `Scope`.
|
|
11
|
+
*
|
|
12
|
+
* The returned effect is INFALLIBLE (`E = never`): starting a projection cannot
|
|
13
|
+
* fail, because everything that can go wrong once it is running is the
|
|
14
|
+
* supervisor's business and lives on the fibre's error channel.
|
|
15
|
+
*
|
|
16
|
+
* ## What can go wrong BEFORE the fork is a programming error, and those are defects
|
|
17
|
+
*
|
|
18
|
+
* Which wirings are refused on the READ SIDE'S rules, why each one is a wiring
|
|
19
|
+
* nothing at runtime would ever notice, and the order they are judged in are all
|
|
20
|
+
* `projectionWiringFault`'s — one gate over five rules, whose only relation to this
|
|
21
|
+
* function is that it is the one place they can be applied before anything exists to
|
|
22
|
+
* be wrong. The gate judges a SET of materialisations, and this function supplies a
|
|
23
|
+
* SINGLETON: the two PER-ENTRY rungs judge that one wiring, the two that are
|
|
24
|
+
* functions of the shared query and slice record judge it once and would do so
|
|
25
|
+
* whatever N was, and the collision rung is a property of the set and is vacuous over
|
|
26
|
+
* one entry, having no sibling to be paired with. That is also why nothing here carries
|
|
27
|
+
* an entry index — the gate names one only where there is a set to index into.
|
|
28
|
+
* A further refusal is the CODEC's and fires just below the gate; `prepareProjection`
|
|
29
|
+
* owns that ordering for both entry points, and the gate's doc says why the rule
|
|
30
|
+
* stays in the codec. This function keeps the two claims that are its own.
|
|
31
|
+
*
|
|
32
|
+
* The verdict is a DEFECT rather than a value on the error channel, because no
|
|
33
|
+
* application can handle its own mis-wiring: the only repair is to change the
|
|
34
|
+
* wiring, and a channel value would ask every caller to write a handler for a
|
|
35
|
+
* mistake that has already been made by the time the program runs. `Effect.die`
|
|
36
|
+
* with an `Error` is the same classification the store gives a mis-built query
|
|
37
|
+
* through `assertServableQuery`, which is one of the rules.
|
|
38
|
+
*
|
|
39
|
+
* And it lands on THIS effect before the `forkScoped` at the foot of `buildAndFork`:
|
|
40
|
+
* the gate is consulted while the daemon is still being
|
|
41
|
+
* assembled, so a rejected wiring has read no checkpoint, opened no subscription
|
|
42
|
+
* and left no half-started fibre behind. That is what makes the defect safe to
|
|
43
|
+
* raise rather than merely early, and every construction case in this package
|
|
44
|
+
* asserts the stored checkpoint is still `ORIGIN` afterwards to keep it true.
|
|
45
|
+
*
|
|
46
|
+
* The preamble on the message is written HERE, once, naming the projection and the
|
|
47
|
+
* partition — the gate returns the sentence about the RULE, and this function knows
|
|
48
|
+
* WHO broke it. The single `Effect.die` that joins them is `prepareProjection`'s,
|
|
49
|
+
* which is why there is one for both entry points rather than one per rule.
|
|
50
|
+
*/
|
|
51
|
+
const runProjection = (readModel, options) => _effect.Effect.gen(function* () {
|
|
52
|
+
// ## RESOLVE — every value the gate has to judge, and every figure that runs
|
|
53
|
+
//
|
|
54
|
+
// `resolveProjection` is a pure function shared with `runProjections`, so the
|
|
55
|
+
// defaults, the key and the view's durability are read in ONE place for both
|
|
56
|
+
// callers: the figure that was judged cannot differ from the figure that runs.
|
|
57
|
+
const view = readModel.store;
|
|
58
|
+
const resolved = (0, _ProjectionRunner.resolveProjection)(view, options);
|
|
59
|
+
// ## PREPARE — the log's durability, the merged query, the gate, the decode
|
|
60
|
+
//
|
|
61
|
+
// The shared middle, and the same call `runProjections` makes: it reads
|
|
62
|
+
// `EventLogDurability` from context, composes the query, consults the gate and
|
|
63
|
+
// only then builds the decode stage — an order `prepareProjection` owns on behalf
|
|
64
|
+
// of both entry points, and whose reasons are on it rather than restated here.
|
|
65
|
+
//
|
|
66
|
+
// The entry list is a SINGLETON, over which the collision rung has no pair to
|
|
67
|
+
// find. Its `cursorIdentity` is what that rung compares by reference — the BOUND
|
|
68
|
+
// view here, which `runProjections` could not use and does not, since a lone
|
|
69
|
+
// entry can only ever be compared with itself and the choice is therefore free at
|
|
70
|
+
// this arity.
|
|
71
|
+
//
|
|
72
|
+
// The preamble is this function's own half of the defect message and the only
|
|
73
|
+
// half it writes: the gate returns the sentence about the RULE, and this names
|
|
74
|
+
// the projection and the partition whose wiring broke it. No entry index, because
|
|
75
|
+
// there is no set to index into.
|
|
76
|
+
const prepared = yield* (0, _ProjectionRunner.prepareProjection)(readModel.slices, [{
|
|
77
|
+
...resolved,
|
|
78
|
+
cursorIdentity: view
|
|
79
|
+
}], `runProjection: invalid wiring for projection ` + `'${resolved.key.projection}' (partition ` + `'${resolved.key.partition}')`);
|
|
80
|
+
// ## BUILD AND FORK — the pipeline, the read side's own rules now satisfied
|
|
81
|
+
return yield* (0, _ProjectionRunner.buildAndFork)(resolved, {
|
|
82
|
+
query: prepared.query,
|
|
83
|
+
decode: prepared.decode,
|
|
84
|
+
apply: readModel.apply,
|
|
85
|
+
options
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
/**
|
|
89
|
+
* `runProjection` as a `Layer` whose own scope owns the daemon.
|
|
90
|
+
*
|
|
91
|
+
* It provides NOTHING (`ROut = never`): a projection is a background process, not
|
|
92
|
+
* a service, and nothing should be able to depend on it as one — a read model is
|
|
93
|
+
* queried through its view store, never through the runner. What the `Layer` buys
|
|
94
|
+
* is lifecycle: dropped into an application's layer graph, the daemon starts when
|
|
95
|
+
* the graph is built and is interrupted when it is released, alongside the store
|
|
96
|
+
* layers it reads from, with no bespoke startup or shutdown code.
|
|
97
|
+
*
|
|
98
|
+
* Discarding the runner discards its fibre too, which is correct and has one
|
|
99
|
+
* consequence worth wiring for: under this `Layer` — the recommended shape — a
|
|
100
|
+
* `ProjectionStalled` has no fibre to be awaited on, so it reaches the outside
|
|
101
|
+
* world only through the supervisor's `Effect.logError` and through `onStalled`.
|
|
102
|
+
* That hook is the reason a stall need not be a log line somebody happens to grep
|
|
103
|
+
* for; pass one in `options` if a stalled projection should fail a health check,
|
|
104
|
+
* exit non-zero, or page.
|
|
105
|
+
*
|
|
106
|
+
* `Layer.scopedDiscard` discharges the `Scope` the fork needs; the store, its
|
|
107
|
+
* `EventLogDurability` declaration, the `Serializer`, the slices' requirements and
|
|
108
|
+
* the read model's own `R` stay on the layer's inputs, so they are satisfied the
|
|
109
|
+
* same way every other layer's are. `EventLogDurability` being an INPUT is what
|
|
110
|
+
* makes the wiring read correctly: the declaration is provided once, alongside the
|
|
111
|
+
* `DcbEventStore` layer it describes, and every projection layer in the graph is
|
|
112
|
+
* then satisfied from that one declaration.
|
|
113
|
+
*/
|
|
114
|
+
exports.runProjection = runProjection;
|
|
115
|
+
const projectionLayer = (readModel, options) => _effect.Layer.scopedDiscard(runProjection(readModel, options));
|
|
116
|
+
exports.projectionLayer = projectionLayer;
|
|
117
|
+
//# sourceMappingURL=runProjection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runProjection.js","names":["_effect","require","_ProjectionRunner","runProjection","readModel","options","Effect","gen","view","store","resolved","resolveProjection","prepared","prepareProjection","slices","cursorIdentity","key","projection","partition","buildAndFork","query","decode","apply","exports","projectionLayer","Layer","scopedDiscard"],"sources":["../../src/runProjection.ts"],"sourcesContent":[null],"mappings":";;;;;;AAuCA,IAAAA,OAAA,GAAAC,OAAA;AAEA,IAAAC,iBAAA,GAAAD,OAAA;AA6FA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CO,MAAME,aAAa,GAAGA,CAC3BC,SAA6B,EAC7BC,OAAiC,KAWjCC,cAAM,CAACC,GAAG,CAAC,aAAS;EAClB;EACA;EACA;EACA;EACA;EACA,MAAMC,IAAI,GAAGJ,SAAS,CAACK,KAAK;EAC5B,MAAMC,QAAQ,GAAG,IAAAC,mCAAiB,EAACH,IAAI,EAAEH,OAAO,CAAC;EAEjD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAMO,QAAQ,GAAG,OAAO,IAAAC,mCAAiB,EACvCT,SAAS,CAACU,MAAM,EAChB,CAAC;IAAE,GAAGJ,QAAQ;IAAEK,cAAc,EAAEP;EAAI,CAAE,CAAC,EACvC,+CAA+C,GAC7C,IAAIE,QAAQ,CAACM,GAAG,CAACC,UAAU,eAAe,GAC1C,IAAIP,QAAQ,CAACM,GAAG,CAACE,SAAS,IAAI,CACjC;EAED;EACA,OAAO,OAAO,IAAAC,8BAAY,EAACT,QAAQ,EAAE;IACnCU,KAAK,EAAER,QAAQ,CAACQ,KAAK;IACrBC,MAAM,EAAET,QAAQ,CAACS,MAAM;IACvBC,KAAK,EAAElB,SAAS,CAACkB,KAAK;IACtBjB;GACD,CAAC;AACJ,CAAC,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;AAAAkB,OAAA,CAAApB,aAAA,GAAAA,aAAA;AA0BO,MAAMqB,eAAe,GAAGA,CAK7BpB,SAA6B,EAC7BC,OAAiC,KAK9BoB,aAAK,CAACC,aAAa,CAACvB,aAAa,CAACC,SAAS,EAAEC,OAAO,CAAC,CAAC;AAAAkB,OAAA,CAAAC,eAAA,GAAAA,eAAA","ignoreList":[]}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.runProjections = void 0;
|
|
7
|
+
var _effect = require("effect");
|
|
8
|
+
var _ProjectionRunner = require("./ProjectionRunner.js");
|
|
9
|
+
var _ProjectionStore = require("./ProjectionStore.js");
|
|
10
|
+
/**
|
|
11
|
+
* Start one daemon per materialisation, all forked into the caller's `Scope`.
|
|
12
|
+
*
|
|
13
|
+
* The returned effect is INFALLIBLE for the reason `runProjection`'s is: starting a
|
|
14
|
+
* projection cannot fail, because everything that can go wrong once one is running
|
|
15
|
+
* belongs to its own supervisor and lives on its own fibre's error channel. The
|
|
16
|
+
* runners come back in ENTRY ORDER, so `runners[i]` is `materialisations[i]`'s.
|
|
17
|
+
*
|
|
18
|
+
* Each runner carries the store THIS call bound for its entry, so `runners[i].store`
|
|
19
|
+
* is that materialisation's cursor and a caller observing one re-derives no binding
|
|
20
|
+
* it never wrote. It is also what tells the N handles apart: under one `ProjectionId`
|
|
21
|
+
* the keys are equal wherever no entry named a partition, so a runner carrying only a
|
|
22
|
+
* key could not name which of the N views it maintains.
|
|
23
|
+
*
|
|
24
|
+
* ## N = 1 is legal and carries nothing inert
|
|
25
|
+
*
|
|
26
|
+
* One entry is `runProjection` with the `forKey` binding done for you, and every
|
|
27
|
+
* field means the same thing it means at N = 3. The two run the identical phases —
|
|
28
|
+
* one `resolveProjection`, one `prepareProjection`, one `buildAndFork` — rather than
|
|
29
|
+
* merely offering the same surface, so there is no threshold at which a caller should
|
|
30
|
+
* switch functions: a read model that grows a second materialisation adds an entry.
|
|
31
|
+
*
|
|
32
|
+
* ## Every rule is judged before ANY entry is forked
|
|
33
|
+
*
|
|
34
|
+
* The construction gate takes the whole call — the shared log, query and slice
|
|
35
|
+
* record, plus the N resolved wirings — and this call reaches it ONCE, through
|
|
36
|
+
* `prepareProjection`, above the `Effect.forEach` below. So a call refused for ANY
|
|
37
|
+
* reason has forked NOTHING,
|
|
38
|
+
* not even the entries that were sound: not the collision, which is a property of
|
|
39
|
+
* the set, and not a degenerate `batchWindow` or an R2 violation on the last entry
|
|
40
|
+
* either. Half a call running is a worse state than none of it, and the pairing of N
|
|
41
|
+
* materialisations is one wiring decision.
|
|
42
|
+
*
|
|
43
|
+
* Two consequences of the gate judging a SET are worth stating rather than leaving
|
|
44
|
+
* to be met.
|
|
45
|
+
*
|
|
46
|
+
* A per-entry rung names its ENTRY. The gate prefixes its verdict with
|
|
47
|
+
* `materialisations[i]` where there is more than one entry, in the vocabulary the
|
|
48
|
+
* collision sentence already uses; this function's preamble names the PROJECTION and
|
|
49
|
+
* no partition, because under one `ProjectionId` the N keys are equal wherever no
|
|
50
|
+
* entry named a partition, so a partition never discriminated them.
|
|
51
|
+
*
|
|
52
|
+
* And the order is over RULES, not over entries. Where two entries break two
|
|
53
|
+
* DIFFERENT rules the earlier RULE wins whatever entry it is in — entry 0's
|
|
54
|
+
* degenerate `batchWindow` beside entry 1's illegal durability pairing reports entry
|
|
55
|
+
* 1's R2 fault, because R2 is the wider mistake wherever it sits. The gate's module
|
|
56
|
+
* doc argues that, and it is why the rules are judged rule-major rather than by
|
|
57
|
+
* walking the entries.
|
|
58
|
+
*/
|
|
59
|
+
const runProjections = spec => _effect.Effect.gen(function* () {
|
|
60
|
+
// ## RESOLVE — everything the gate has to judge, and every figure that runs
|
|
61
|
+
//
|
|
62
|
+
// Each entry's key and its five defaulted figures, through the same pure
|
|
63
|
+
// `resolveProjection` a single wiring goes through. Resolved here and carried,
|
|
64
|
+
// rather than derived twice: the gate below judges these values and the pipelines
|
|
65
|
+
// further down run from these same values, so what was checked cannot differ from
|
|
66
|
+
// what runs.
|
|
67
|
+
//
|
|
68
|
+
// Built as an EXPLICIT literal rather than by spreading the `Materialisation`,
|
|
69
|
+
// so every field on an entry has exactly one meaning and nothing dead rides
|
|
70
|
+
// along. A spread would carry the caller's `store` and `partition` into a record
|
|
71
|
+
// that already holds the BOUND view (from the resolve step) and the UNBOUND port
|
|
72
|
+
// under `cursorIdentity` — two names for one reference, one name for a different
|
|
73
|
+
// one, and a `partition` nothing downstream reads because `key` has absorbed it.
|
|
74
|
+
// That is a near-miss of the very hazard `cursorIdentity` was renamed to close.
|
|
75
|
+
//
|
|
76
|
+
// `cursorIdentity` is the UNBOUND port here, which is the last surface at which
|
|
77
|
+
// sameness is askable — `forKey` returns a fresh literal per call and does not
|
|
78
|
+
// expose what it closed over, so two bound views are never equal even over one
|
|
79
|
+
// store. `runProjection` passes its bound view instead, which is free at an arity
|
|
80
|
+
// where the rung cannot fire. `MaterialisationWiring`'s doc owns that argument.
|
|
81
|
+
const entries = _effect.Array.map(spec.materialisations, materialisation => {
|
|
82
|
+
const key = (0, _ProjectionStore.checkpointKey)(spec.projection, materialisation.partition);
|
|
83
|
+
return {
|
|
84
|
+
...(0, _ProjectionRunner.resolveProjection)((0, _ProjectionStore.forKey)(materialisation.store, key), materialisation.options),
|
|
85
|
+
cursorIdentity: materialisation.store,
|
|
86
|
+
apply: materialisation.apply,
|
|
87
|
+
options: materialisation.options
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
// ## PREPARE — the log's durability, the merged query, the gate, the decode
|
|
91
|
+
//
|
|
92
|
+
// The shared middle, and the same call `runProjection` makes with a singleton.
|
|
93
|
+
// It reads the LOG's half of R2 from context — once for the call, because it IS
|
|
94
|
+
// one fact about one log — composes the ONE query the N subscriptions share,
|
|
95
|
+
// judges all five rungs over the whole entry list, and only then builds the ONE
|
|
96
|
+
// decode stage the N pipelines share. All of it above the `Effect.forEach` below,
|
|
97
|
+
// so a refused call has forked nothing.
|
|
98
|
+
//
|
|
99
|
+
// The order of the last two steps is `prepareProjection`'s to own, and it is why
|
|
100
|
+
// `decodeSlices` is not simply hoisted beside the composition: a record wrong in
|
|
101
|
+
// the codec's way AND in one of the gate's must meet the gate's sentence.
|
|
102
|
+
//
|
|
103
|
+
// The preamble is this function's own half of the defect message: the PROJECTION
|
|
104
|
+
// and no partition, because under one `ProjectionId` the N keys are equal wherever
|
|
105
|
+
// no entry named one, so a partition never discriminated them. The gate prefixes
|
|
106
|
+
// the entry index itself, where there is a set to index into.
|
|
107
|
+
const prepared = yield* (0, _ProjectionRunner.prepareProjection)(spec.slices, entries, `runProjections: invalid wiring for projection '${spec.projection}'`);
|
|
108
|
+
// ## FORK — one runner per entry, SEQUENTIALLY
|
|
109
|
+
//
|
|
110
|
+
// No `concurrency` option, deliberately. `buildAndFork` returns as soon as its
|
|
111
|
+
// daemon is forked into this scope, so it does no waiting for a concurrent pass
|
|
112
|
+
// to overlap: concurrency would buy nothing and would cost the returned ORDER,
|
|
113
|
+
// which is what lets a caller pair a runner with the entry it maintains. The
|
|
114
|
+
// daemons themselves run concurrently regardless — that is what forking them is.
|
|
115
|
+
//
|
|
116
|
+
// A runner naming its own bound cursor does not make that order redundant. The
|
|
117
|
+
// entry hands over an UNBOUND port and `forKey` deliberately does not expose what
|
|
118
|
+
// it closed over, so nothing a caller still holds can be compared against
|
|
119
|
+
// `runners[i].store` to recover which entry it came from. The order is the only
|
|
120
|
+
// statement of that pairing, and it is why this fold stays sequential.
|
|
121
|
+
//
|
|
122
|
+
// Each entry reaches the SAME build step a single wiring reaches, with the same
|
|
123
|
+
// shared query and the same shared decode stage, so the N pipelines differ in
|
|
124
|
+
// nothing but their store, their `apply` and their tuning.
|
|
125
|
+
return yield* _effect.Effect.forEach(entries, entry => (0, _ProjectionRunner.buildAndFork)(entry, {
|
|
126
|
+
query: prepared.query,
|
|
127
|
+
decode: prepared.decode,
|
|
128
|
+
// THE one assertion in this function, and the reason the requirement
|
|
129
|
+
// channel declared above is checked rather than wished for. Inside the
|
|
130
|
+
// body an entry is known only by its constraint, so this `apply` reads as
|
|
131
|
+
// `Effect<void, unknown, unknown>`; naming the alias the return type
|
|
132
|
+
// already names is what carries the entries' real requirement through
|
|
133
|
+
// `buildAndFork`, where a wildcard bound would instead absorb the lot and
|
|
134
|
+
// leave every member of that union unverified. It is narrow on purpose —
|
|
135
|
+
// `entry.apply` alone, to one expression written in one other place —
|
|
136
|
+
// and it cannot be dropped: without it the module does not compile.
|
|
137
|
+
// `MaterialisationAny` owns the mechanic, `MaterialisedProjection` what
|
|
138
|
+
// the compiler is being asked to take on trust.
|
|
139
|
+
apply: entry.apply,
|
|
140
|
+
options: entry.options
|
|
141
|
+
}));
|
|
142
|
+
});
|
|
143
|
+
exports.runProjections = runProjections;
|
|
144
|
+
//# sourceMappingURL=runProjections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runProjections.js","names":["_effect","require","_ProjectionRunner","_ProjectionStore","runProjections","spec","Effect","gen","entries","Arr","map","materialisations","materialisation","key","checkpointKey","projection","partition","resolveProjection","forKey","store","options","cursorIdentity","apply","prepared","prepareProjection","slices","forEach","entry","buildAndFork","query","decode","exports"],"sources":["../../src/runProjections.ts"],"sourcesContent":[null],"mappings":";;;;;;AA8FA,IAAAA,OAAA,GAAAC,OAAA;AAEA,IAAAC,iBAAA,GAAAD,OAAA;AAOA,IAAAE,gBAAA,GAAAF,OAAA;AAuWA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDO,MAAMG,cAAc,GAIzBC,IAAmC,IAWnCC,cAAM,CAACC,GAAG,CAAC,aAAS;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAMC,OAAO,GAAGC,aAAG,CAACC,GAAG,CAACL,IAAI,CAACM,gBAAgB,EAAGC,eAAe,IAAI;IACjE,MAAMC,GAAG,GAAG,IAAAC,8BAAa,EAACT,IAAI,CAACU,UAAU,EAAEH,eAAe,CAACI,SAAS,CAAC;IACrE,OAAO;MACL,GAAG,IAAAC,mCAAiB,EAClB,IAAAC,uBAAM,EAACN,eAAe,CAACO,KAAK,EAAEN,GAAG,CAAC,EAClCD,eAAe,CAACQ,OAAO,CACxB;MACDC,cAAc,EAAET,eAAe,CAACO,KAAK;MACrCG,KAAK,EAAEV,eAAe,CAACU,KAAK;MAC5BF,OAAO,EAAER,eAAe,CAACQ;KAC1B;EACH,CAAC,CAAC;EAEF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAMG,QAAQ,GAAG,OAAO,IAAAC,mCAAiB,EACvCnB,IAAI,CAACoB,MAAM,EACXjB,OAAO,EACP,kDAAkDH,IAAI,CAACU,UAAU,GAAG,CACrE;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,OAAO,OAAOT,cAAM,CAACoB,OAAO,CAAClB,OAAO,EAAGmB,KAAK,IAC1C,IAAAC,8BAAY,EAACD,KAAK,EAAE;IAClBE,KAAK,EAAEN,QAAQ,CAACM,KAAK;IACrBC,MAAM,EAAEP,QAAQ,CAACO,MAAM;IACvB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACAR,KAAK,EAAEK,KAAK,CAACL,KAEgD;IAC7DF,OAAO,EAAEO,KAAK,CAACP;GAChB,CAAC,CACH;AACH,CAAC,CAAC;AAAAW,OAAA,CAAA3B,cAAA,GAAAA,cAAA","ignoreList":[]}
|