@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.
Files changed (82) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +538 -0
  3. package/dist/cjs/EventLogDurability.js +184 -0
  4. package/dist/cjs/EventLogDurability.js.map +1 -0
  5. package/dist/cjs/ProjectionRunner.js +478 -0
  6. package/dist/cjs/ProjectionRunner.js.map +1 -0
  7. package/dist/cjs/ProjectionStore.js +233 -0
  8. package/dist/cjs/ProjectionStore.js.map +1 -0
  9. package/dist/cjs/foldIntoRef.js +36 -0
  10. package/dist/cjs/foldIntoRef.js.map +1 -0
  11. package/dist/cjs/inMemoryProjectionStore.js +138 -0
  12. package/dist/cjs/inMemoryProjectionStore.js.map +1 -0
  13. package/dist/cjs/index.js +128 -0
  14. package/dist/cjs/index.js.map +1 -0
  15. package/dist/cjs/projectionWiringFault.js +532 -0
  16. package/dist/cjs/projectionWiringFault.js.map +1 -0
  17. package/dist/cjs/runProjection.js +117 -0
  18. package/dist/cjs/runProjection.js.map +1 -0
  19. package/dist/cjs/runProjections.js +144 -0
  20. package/dist/cjs/runProjections.js.map +1 -0
  21. package/dist/cjs/superviseOnProgress.js +580 -0
  22. package/dist/cjs/superviseOnProgress.js.map +1 -0
  23. package/dist/cjs/testing.js +143 -0
  24. package/dist/cjs/testing.js.map +1 -0
  25. package/dist/dts/EventLogDurability.d.ts +182 -0
  26. package/dist/dts/EventLogDurability.d.ts.map +1 -0
  27. package/dist/dts/ProjectionRunner.d.ts +557 -0
  28. package/dist/dts/ProjectionRunner.d.ts.map +1 -0
  29. package/dist/dts/ProjectionStore.d.ts +475 -0
  30. package/dist/dts/ProjectionStore.d.ts.map +1 -0
  31. package/dist/dts/foldIntoRef.d.ts +39 -0
  32. package/dist/dts/foldIntoRef.d.ts.map +1 -0
  33. package/dist/dts/inMemoryProjectionStore.d.ts +11 -0
  34. package/dist/dts/inMemoryProjectionStore.d.ts.map +1 -0
  35. package/dist/dts/index.d.ts +185 -0
  36. package/dist/dts/index.d.ts.map +1 -0
  37. package/dist/dts/projectionWiringFault.d.ts +260 -0
  38. package/dist/dts/projectionWiringFault.d.ts.map +1 -0
  39. package/dist/dts/runProjection.d.ts +185 -0
  40. package/dist/dts/runProjection.d.ts.map +1 -0
  41. package/dist/dts/runProjections.d.ts +480 -0
  42. package/dist/dts/runProjections.d.ts.map +1 -0
  43. package/dist/dts/superviseOnProgress.d.ts +587 -0
  44. package/dist/dts/superviseOnProgress.d.ts.map +1 -0
  45. package/dist/dts/testing.d.ts +207 -0
  46. package/dist/dts/testing.d.ts.map +1 -0
  47. package/dist/esm/EventLogDurability.js +175 -0
  48. package/dist/esm/EventLogDurability.js.map +1 -0
  49. package/dist/esm/ProjectionRunner.js +468 -0
  50. package/dist/esm/ProjectionRunner.js.map +1 -0
  51. package/dist/esm/ProjectionStore.js +223 -0
  52. package/dist/esm/ProjectionStore.js.map +1 -0
  53. package/dist/esm/foldIntoRef.js +29 -0
  54. package/dist/esm/foldIntoRef.js.map +1 -0
  55. package/dist/esm/inMemoryProjectionStore.js +131 -0
  56. package/dist/esm/inMemoryProjectionStore.js.map +1 -0
  57. package/dist/esm/index.js +185 -0
  58. package/dist/esm/index.js.map +1 -0
  59. package/dist/esm/package.json +4 -0
  60. package/dist/esm/projectionWiringFault.js +524 -0
  61. package/dist/esm/projectionWiringFault.js.map +1 -0
  62. package/dist/esm/runProjection.js +109 -0
  63. package/dist/esm/runProjection.js.map +1 -0
  64. package/dist/esm/runProjections.js +137 -0
  65. package/dist/esm/runProjections.js.map +1 -0
  66. package/dist/esm/superviseOnProgress.js +571 -0
  67. package/dist/esm/superviseOnProgress.js.map +1 -0
  68. package/dist/esm/testing.js +133 -0
  69. package/dist/esm/testing.js.map +1 -0
  70. package/package.json +41 -0
  71. package/src/EventLogDurability.ts +201 -0
  72. package/src/ProjectionRunner.ts +923 -0
  73. package/src/ProjectionStore.ts +528 -0
  74. package/src/foldIntoRef.ts +63 -0
  75. package/src/inMemoryProjectionStore.ts +163 -0
  76. package/src/index.ts +218 -0
  77. package/src/projectionWiringFault.ts +694 -0
  78. package/src/runProjection.ts +270 -0
  79. package/src/runProjections.ts +623 -0
  80. package/src/superviseOnProgress.ts +897 -0
  81. package/src/testing.ts +290 -0
  82. package/testing/package.json +6 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runProjection.js","names":["Effect","Layer","buildAndFork","prepareProjection","resolveProjection","runProjection","readModel","options","gen","view","store","resolved","prepared","slices","cursorIdentity","key","projection","partition","query","decode","apply","projectionLayer","scopedDiscard"],"sources":["../../src/runProjection.ts"],"sourcesContent":[null],"mappings":"AAuCA,SAA4BA,MAAM,EAAEC,KAAK,QAAoB,QAAQ;AAErE,SACEC,YAAY,EAGZC,iBAAiB,EACjBC,iBAAiB,QACZ,uBAAoB;AAuF3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,OAAO,MAAMC,aAAa,GAAGA,CAC3BC,SAA6B,EAC7BC,OAAiC,KAWjCP,MAAM,CAACQ,GAAG,CAAC,aAAS;EAClB;EACA;EACA;EACA;EACA;EACA,MAAMC,IAAI,GAAGH,SAAS,CAACI,KAAK;EAC5B,MAAMC,QAAQ,GAAGP,iBAAiB,CAACK,IAAI,EAAEF,OAAO,CAAC;EAEjD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAMK,QAAQ,GAAG,OAAOT,iBAAiB,CACvCG,SAAS,CAACO,MAAM,EAChB,CAAC;IAAE,GAAGF,QAAQ;IAAEG,cAAc,EAAEL;EAAI,CAAE,CAAC,EACvC,+CAA+C,GAC7C,IAAIE,QAAQ,CAACI,GAAG,CAACC,UAAU,eAAe,GAC1C,IAAIL,QAAQ,CAACI,GAAG,CAACE,SAAS,IAAI,CACjC;EAED;EACA,OAAO,OAAOf,YAAY,CAACS,QAAQ,EAAE;IACnCO,KAAK,EAAEN,QAAQ,CAACM,KAAK;IACrBC,MAAM,EAAEP,QAAQ,CAACO,MAAM;IACvBC,KAAK,EAAEd,SAAS,CAACc,KAAK;IACtBb;GACD,CAAC;AACJ,CAAC,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,OAAO,MAAMc,eAAe,GAAGA,CAK7Bf,SAA6B,EAC7BC,OAAiC,KAK9BN,KAAK,CAACqB,aAAa,CAACjB,aAAa,CAACC,SAAS,EAAEC,OAAO,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,137 @@
1
+ import { Array as Arr, Effect } from 'effect';
2
+ import { buildAndFork, prepareProjection, resolveProjection } from "./ProjectionRunner.js";
3
+ import { checkpointKey, forKey } from "./ProjectionStore.js";
4
+ /**
5
+ * Start one daemon per materialisation, all forked into the caller's `Scope`.
6
+ *
7
+ * The returned effect is INFALLIBLE for the reason `runProjection`'s is: starting a
8
+ * projection cannot fail, because everything that can go wrong once one is running
9
+ * belongs to its own supervisor and lives on its own fibre's error channel. The
10
+ * runners come back in ENTRY ORDER, so `runners[i]` is `materialisations[i]`'s.
11
+ *
12
+ * Each runner carries the store THIS call bound for its entry, so `runners[i].store`
13
+ * is that materialisation's cursor and a caller observing one re-derives no binding
14
+ * it never wrote. It is also what tells the N handles apart: under one `ProjectionId`
15
+ * the keys are equal wherever no entry named a partition, so a runner carrying only a
16
+ * key could not name which of the N views it maintains.
17
+ *
18
+ * ## N = 1 is legal and carries nothing inert
19
+ *
20
+ * One entry is `runProjection` with the `forKey` binding done for you, and every
21
+ * field means the same thing it means at N = 3. The two run the identical phases —
22
+ * one `resolveProjection`, one `prepareProjection`, one `buildAndFork` — rather than
23
+ * merely offering the same surface, so there is no threshold at which a caller should
24
+ * switch functions: a read model that grows a second materialisation adds an entry.
25
+ *
26
+ * ## Every rule is judged before ANY entry is forked
27
+ *
28
+ * The construction gate takes the whole call — the shared log, query and slice
29
+ * record, plus the N resolved wirings — and this call reaches it ONCE, through
30
+ * `prepareProjection`, above the `Effect.forEach` below. So a call refused for ANY
31
+ * reason has forked NOTHING,
32
+ * not even the entries that were sound: not the collision, which is a property of
33
+ * the set, and not a degenerate `batchWindow` or an R2 violation on the last entry
34
+ * either. Half a call running is a worse state than none of it, and the pairing of N
35
+ * materialisations is one wiring decision.
36
+ *
37
+ * Two consequences of the gate judging a SET are worth stating rather than leaving
38
+ * to be met.
39
+ *
40
+ * A per-entry rung names its ENTRY. The gate prefixes its verdict with
41
+ * `materialisations[i]` where there is more than one entry, in the vocabulary the
42
+ * collision sentence already uses; this function's preamble names the PROJECTION and
43
+ * no partition, because under one `ProjectionId` the N keys are equal wherever no
44
+ * entry named a partition, so a partition never discriminated them.
45
+ *
46
+ * And the order is over RULES, not over entries. Where two entries break two
47
+ * DIFFERENT rules the earlier RULE wins whatever entry it is in — entry 0's
48
+ * degenerate `batchWindow` beside entry 1's illegal durability pairing reports entry
49
+ * 1's R2 fault, because R2 is the wider mistake wherever it sits. The gate's module
50
+ * doc argues that, and it is why the rules are judged rule-major rather than by
51
+ * walking the entries.
52
+ */
53
+ export const runProjections = spec => Effect.gen(function* () {
54
+ // ## RESOLVE — everything the gate has to judge, and every figure that runs
55
+ //
56
+ // Each entry's key and its five defaulted figures, through the same pure
57
+ // `resolveProjection` a single wiring goes through. Resolved here and carried,
58
+ // rather than derived twice: the gate below judges these values and the pipelines
59
+ // further down run from these same values, so what was checked cannot differ from
60
+ // what runs.
61
+ //
62
+ // Built as an EXPLICIT literal rather than by spreading the `Materialisation`,
63
+ // so every field on an entry has exactly one meaning and nothing dead rides
64
+ // along. A spread would carry the caller's `store` and `partition` into a record
65
+ // that already holds the BOUND view (from the resolve step) and the UNBOUND port
66
+ // under `cursorIdentity` — two names for one reference, one name for a different
67
+ // one, and a `partition` nothing downstream reads because `key` has absorbed it.
68
+ // That is a near-miss of the very hazard `cursorIdentity` was renamed to close.
69
+ //
70
+ // `cursorIdentity` is the UNBOUND port here, which is the last surface at which
71
+ // sameness is askable — `forKey` returns a fresh literal per call and does not
72
+ // expose what it closed over, so two bound views are never equal even over one
73
+ // store. `runProjection` passes its bound view instead, which is free at an arity
74
+ // where the rung cannot fire. `MaterialisationWiring`'s doc owns that argument.
75
+ const entries = Arr.map(spec.materialisations, materialisation => {
76
+ const key = checkpointKey(spec.projection, materialisation.partition);
77
+ return {
78
+ ...resolveProjection(forKey(materialisation.store, key), materialisation.options),
79
+ cursorIdentity: materialisation.store,
80
+ apply: materialisation.apply,
81
+ options: materialisation.options
82
+ };
83
+ });
84
+ // ## PREPARE — the log's durability, the merged query, the gate, the decode
85
+ //
86
+ // The shared middle, and the same call `runProjection` makes with a singleton.
87
+ // It reads the LOG's half of R2 from context — once for the call, because it IS
88
+ // one fact about one log — composes the ONE query the N subscriptions share,
89
+ // judges all five rungs over the whole entry list, and only then builds the ONE
90
+ // decode stage the N pipelines share. All of it above the `Effect.forEach` below,
91
+ // so a refused call has forked nothing.
92
+ //
93
+ // The order of the last two steps is `prepareProjection`'s to own, and it is why
94
+ // `decodeSlices` is not simply hoisted beside the composition: a record wrong in
95
+ // the codec's way AND in one of the gate's must meet the gate's sentence.
96
+ //
97
+ // The preamble is this function's own half of the defect message: the PROJECTION
98
+ // and no partition, because under one `ProjectionId` the N keys are equal wherever
99
+ // no entry named one, so a partition never discriminated them. The gate prefixes
100
+ // the entry index itself, where there is a set to index into.
101
+ const prepared = yield* prepareProjection(spec.slices, entries, `runProjections: invalid wiring for projection '${spec.projection}'`);
102
+ // ## FORK — one runner per entry, SEQUENTIALLY
103
+ //
104
+ // No `concurrency` option, deliberately. `buildAndFork` returns as soon as its
105
+ // daemon is forked into this scope, so it does no waiting for a concurrent pass
106
+ // to overlap: concurrency would buy nothing and would cost the returned ORDER,
107
+ // which is what lets a caller pair a runner with the entry it maintains. The
108
+ // daemons themselves run concurrently regardless — that is what forking them is.
109
+ //
110
+ // A runner naming its own bound cursor does not make that order redundant. The
111
+ // entry hands over an UNBOUND port and `forKey` deliberately does not expose what
112
+ // it closed over, so nothing a caller still holds can be compared against
113
+ // `runners[i].store` to recover which entry it came from. The order is the only
114
+ // statement of that pairing, and it is why this fold stays sequential.
115
+ //
116
+ // Each entry reaches the SAME build step a single wiring reaches, with the same
117
+ // shared query and the same shared decode stage, so the N pipelines differ in
118
+ // nothing but their store, their `apply` and their tuning.
119
+ return yield* Effect.forEach(entries, entry => buildAndFork(entry, {
120
+ query: prepared.query,
121
+ decode: prepared.decode,
122
+ // THE one assertion in this function, and the reason the requirement
123
+ // channel declared above is checked rather than wished for. Inside the
124
+ // body an entry is known only by its constraint, so this `apply` reads as
125
+ // `Effect<void, unknown, unknown>`; naming the alias the return type
126
+ // already names is what carries the entries' real requirement through
127
+ // `buildAndFork`, where a wildcard bound would instead absorb the lot and
128
+ // leave every member of that union unverified. It is narrow on purpose —
129
+ // `entry.apply` alone, to one expression written in one other place —
130
+ // and it cannot be dropped: without it the module does not compile.
131
+ // `MaterialisationAny` owns the mechanic, `MaterialisedProjection` what
132
+ // the compiler is being asked to take on trust.
133
+ apply: entry.apply,
134
+ options: entry.options
135
+ }));
136
+ });
137
+ //# sourceMappingURL=runProjections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runProjections.js","names":["Array","Arr","Effect","buildAndFork","prepareProjection","resolveProjection","checkpointKey","forKey","runProjections","spec","gen","entries","map","materialisations","materialisation","key","projection","partition","store","options","cursorIdentity","apply","prepared","slices","forEach","entry","query","decode"],"sources":["../../src/runProjections.ts"],"sourcesContent":[null],"mappings":"AA8FA,SAASA,KAAK,IAAIC,GAAG,EAAEC,MAAM,QAAoB,QAAQ;AAEzD,SACEC,YAAY,EAGZC,iBAAiB,EACjBC,iBAAiB,QACZ,uBAAoB;AAC3B,SACEC,aAAa,EACbC,MAAM,QAID,sBAAmB;AAiW1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,OAAO,MAAMC,cAAc,GAIzBC,IAAmC,IAWnCP,MAAM,CAACQ,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,GAAGV,GAAG,CAACW,GAAG,CAACH,IAAI,CAACI,gBAAgB,EAAGC,eAAe,IAAI;IACjE,MAAMC,GAAG,GAAGT,aAAa,CAACG,IAAI,CAACO,UAAU,EAAEF,eAAe,CAACG,SAAS,CAAC;IACrE,OAAO;MACL,GAAGZ,iBAAiB,CAClBE,MAAM,CAACO,eAAe,CAACI,KAAK,EAAEH,GAAG,CAAC,EAClCD,eAAe,CAACK,OAAO,CACxB;MACDC,cAAc,EAAEN,eAAe,CAACI,KAAK;MACrCG,KAAK,EAAEP,eAAe,CAACO,KAAK;MAC5BF,OAAO,EAAEL,eAAe,CAACK;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,OAAOlB,iBAAiB,CACvCK,IAAI,CAACc,MAAM,EACXZ,OAAO,EACP,kDAAkDF,IAAI,CAACO,UAAU,GAAG,CACrE;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,OAAO,OAAOd,MAAM,CAACsB,OAAO,CAACb,OAAO,EAAGc,KAAK,IAC1CtB,YAAY,CAACsB,KAAK,EAAE;IAClBC,KAAK,EAAEJ,QAAQ,CAACI,KAAK;IACrBC,MAAM,EAAEL,QAAQ,CAACK,MAAM;IACvB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACAN,KAAK,EAAEI,KAAK,CAACJ,KAEgD;IAC7DF,OAAO,EAAEM,KAAK,CAACN;GAChB,CAAC,CACH;AACH,CAAC,CAAC","ignoreList":[]}