@kairos-es/codec 1.0.0-alpha.3 → 1.0.0-alpha.5
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/README.md +27 -2
- package/dist/cjs/MetadataSource.js +10 -0
- package/dist/cjs/MetadataSource.js.map +1 -0
- package/dist/cjs/Serializer.js +3 -3
- package/dist/cjs/Serializer.js.map +1 -1
- package/dist/cjs/Uuid.js +6 -3
- package/dist/cjs/Uuid.js.map +1 -1
- package/dist/cjs/decider.js +1 -1
- package/dist/cjs/decisionModel.js +1 -1
- package/dist/cjs/decisionModel.js.map +1 -1
- package/dist/cjs/decode.js +5 -5
- package/dist/cjs/decode.js.map +1 -1
- package/dist/cjs/deserialiseThenDecode.js +1 -1
- package/dist/cjs/deserialiseThenDecode.js.map +1 -1
- package/dist/cjs/errors.js +6 -4
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/event.js.map +1 -1
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/precondition.js +2 -2
- package/dist/cjs/precondition.js.map +1 -1
- package/dist/cjs/projection.js +9 -10
- package/dist/cjs/projection.js.map +1 -1
- package/dist/cjs/readLedger.js +20 -5
- package/dist/cjs/readLedger.js.map +1 -1
- package/dist/cjs/registry.js.map +1 -1
- package/dist/cjs/toEvent.js +58 -4
- package/dist/cjs/toEvent.js.map +1 -1
- package/dist/dts-cjs/MetadataSource.d.ts +8 -0
- package/dist/dts-cjs/MetadataSource.d.ts.map +1 -0
- package/dist/{dts → dts-cjs}/Serializer.d.ts +3 -3
- package/dist/{dts → dts-cjs}/Serializer.d.ts.map +1 -1
- package/dist/{dts → dts-cjs}/Uuid.d.ts +6 -3
- package/dist/{dts → dts-cjs}/Uuid.d.ts.map +1 -1
- package/dist/{dts → dts-cjs}/decider.d.ts +7 -7
- package/dist/{dts → dts-cjs}/decider.d.ts.map +1 -1
- package/dist/{dts → dts-cjs}/decision.d.ts +2 -2
- package/dist/{dts → dts-cjs}/decode.d.ts +3 -3
- package/dist/{dts → dts-cjs}/decode.d.ts.map +1 -1
- package/dist/{dts → dts-cjs}/deserialiseThenDecode.d.ts +3 -3
- package/dist/{dts → dts-cjs}/deserialiseThenDecode.d.ts.map +1 -1
- package/dist/{dts → dts-cjs}/errors.d.ts +4 -3
- package/dist/dts-cjs/errors.d.ts.map +1 -0
- package/dist/{dts → dts-cjs}/event.d.ts +18 -8
- package/dist/dts-cjs/event.d.ts.map +1 -0
- package/dist/{dts → dts-cjs}/index.d.ts +4 -2
- package/dist/dts-cjs/index.d.ts.map +1 -0
- package/dist/dts-cjs/package.json +3 -0
- package/dist/{dts → dts-cjs}/precondition.d.ts +2 -2
- package/dist/{dts → dts-cjs}/projection.d.ts +2 -2
- package/dist/dts-cjs/projection.d.ts.map +1 -0
- package/dist/{dts → dts-cjs}/readLedger.d.ts +4 -4
- package/dist/{dts → dts-cjs}/readLedger.d.ts.map +1 -1
- package/dist/{dts → dts-cjs}/toEvent.d.ts +15 -4
- package/dist/dts-cjs/toEvent.d.ts.map +1 -0
- package/dist/dts-esm/MetadataSource.d.ts +8 -0
- package/dist/dts-esm/MetadataSource.d.ts.map +1 -0
- package/dist/dts-esm/Serializer.d.ts +27 -0
- package/dist/dts-esm/Serializer.d.ts.map +1 -0
- package/dist/dts-esm/Uuid.d.ts +22 -0
- package/dist/dts-esm/Uuid.d.ts.map +1 -0
- package/dist/dts-esm/decider.d.ts +206 -0
- package/dist/dts-esm/decider.d.ts.map +1 -0
- package/dist/dts-esm/decision.d.ts +161 -0
- package/dist/dts-esm/decision.d.ts.map +1 -0
- package/dist/dts-esm/decisionModel.d.ts +149 -0
- package/dist/dts-esm/decisionModel.d.ts.map +1 -0
- package/dist/dts-esm/decode.d.ts +92 -0
- package/dist/dts-esm/decode.d.ts.map +1 -0
- package/dist/dts-esm/deserialiseThenDecode.d.ts +62 -0
- package/dist/dts-esm/deserialiseThenDecode.d.ts.map +1 -0
- package/dist/dts-esm/errors.d.ts +80 -0
- package/dist/dts-esm/errors.d.ts.map +1 -0
- package/dist/dts-esm/event.d.ts +81 -0
- package/dist/dts-esm/event.d.ts.map +1 -0
- package/dist/dts-esm/index.d.ts +134 -0
- package/dist/dts-esm/index.d.ts.map +1 -0
- package/dist/dts-esm/package.json +3 -0
- package/dist/dts-esm/precondition.d.ts +244 -0
- package/dist/dts-esm/precondition.d.ts.map +1 -0
- package/dist/dts-esm/projection.d.ts +56 -0
- package/dist/dts-esm/projection.d.ts.map +1 -0
- package/dist/dts-esm/readLedger.d.ts +263 -0
- package/dist/dts-esm/readLedger.d.ts.map +1 -0
- package/dist/dts-esm/registry.d.ts +46 -0
- package/dist/dts-esm/registry.d.ts.map +1 -0
- package/dist/dts-esm/toEvent.d.ts +45 -0
- package/dist/dts-esm/toEvent.d.ts.map +1 -0
- package/dist/esm/MetadataSource.js +3 -0
- package/dist/esm/MetadataSource.js.map +1 -0
- package/dist/esm/Serializer.js +3 -3
- package/dist/esm/Serializer.js.map +1 -1
- package/dist/esm/Uuid.js +6 -3
- package/dist/esm/Uuid.js.map +1 -1
- package/dist/esm/decider.js +1 -1
- package/dist/esm/decisionModel.js +1 -1
- package/dist/esm/decisionModel.js.map +1 -1
- package/dist/esm/decode.js +5 -5
- package/dist/esm/decode.js.map +1 -1
- package/dist/esm/deserialiseThenDecode.js +1 -1
- package/dist/esm/deserialiseThenDecode.js.map +1 -1
- package/dist/esm/errors.js +6 -4
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/event.js.map +1 -1
- package/dist/esm/index.js +4 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/precondition.js +2 -2
- package/dist/esm/precondition.js.map +1 -1
- package/dist/esm/projection.js +9 -10
- package/dist/esm/projection.js.map +1 -1
- package/dist/esm/readLedger.js +21 -6
- package/dist/esm/readLedger.js.map +1 -1
- package/dist/esm/registry.js.map +1 -1
- package/dist/esm/toEvent.js +58 -5
- package/dist/esm/toEvent.js.map +1 -1
- package/package.json +12 -7
- package/src/MetadataSource.ts +43 -0
- package/src/Serializer.ts +4 -4
- package/src/Uuid.ts +7 -4
- package/src/decider.ts +9 -9
- package/src/decision.ts +1 -1
- package/src/decisionModel.ts +1 -1
- package/src/decode.ts +12 -18
- package/src/deserialiseThenDecode.ts +5 -5
- package/src/errors.ts +6 -4
- package/src/event.ts +19 -9
- package/src/index.ts +4 -2
- package/src/precondition.ts +3 -3
- package/src/projection.ts +15 -20
- package/src/readLedger.ts +28 -12
- package/src/registry.ts +1 -1
- package/src/toEvent.ts +54 -7
- package/dist/dts/errors.d.ts.map +0 -1
- package/dist/dts/event.d.ts.map +0 -1
- package/dist/dts/index.d.ts.map +0 -1
- package/dist/dts/projection.d.ts.map +0 -1
- package/dist/dts/toEvent.d.ts.map +0 -1
- /package/dist/{dts → dts-cjs}/decision.d.ts.map +0 -0
- /package/dist/{dts → dts-cjs}/decisionModel.d.ts +0 -0
- /package/dist/{dts → dts-cjs}/decisionModel.d.ts.map +0 -0
- /package/dist/{dts → dts-cjs}/precondition.d.ts.map +0 -0
- /package/dist/{dts → dts-cjs}/registry.d.ts +0 -0
- /package/dist/{dts → dts-cjs}/registry.d.ts.map +0 -0
package/dist/esm/event.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event.js","names":["Schema","event","type","fields","tagsFor","schema","Struct"],"sources":["../../src/event.ts"],"sourcesContent":[null],"mappings":"AA+BA,SAASA,MAAM,QAAQ,QAAQ;
|
|
1
|
+
{"version":3,"file":"event.js","names":["Schema","event","type","fields","tagsFor","schema","Struct"],"sources":["../../src/event.ts"],"sourcesContent":[null],"mappings":"AA+BA,SAASA,MAAM,QAAQ,QAAQ;AAyC/B;;;;;;;;AAQA,OAAO,MAAMC,KAAK,GAAGA,CAInBC,IAAU,EACVC,MAAc,EACdC,OAA4C,KAK1C;EACF,MAAMC,MAAM,GAAGL,MAAM,CAACM,MAAM,CAACH,MAAM,CAAC;EACpC,OAAO;IACL;IACAD,IAAI,EAAEA,IAAwB;IAC9BG,MAAM;IACND;GACD;AACH,CAAC","ignoreList":[]}
|
package/dist/esm/index.js
CHANGED
|
@@ -17,8 +17,9 @@
|
|
|
17
17
|
* on this path: the type is discovered at runtime, so no def was named to
|
|
18
18
|
* narrow it (see `registry.ts`).
|
|
19
19
|
*
|
|
20
|
-
* `toEvent(def, payload, { uuid?, occurredAt? })` produces a wire
|
|
21
|
-
* -> serialise, tags derived from `def.tagsFor`, clock + uuid from
|
|
20
|
+
* `toEvent(def, payload, { uuid?, occurredAt?, metadata? })` produces a wire
|
|
21
|
+
* event (encode -> serialise, tags derived from `def.tagsFor`, clock + uuid from
|
|
22
|
+
* services, metadata from the call or the optional ambient `MetadataSource`).
|
|
22
23
|
* Serialisation is a pluggable `Serializer` (JSON
|
|
23
24
|
* default). Encryption, when needed, is an *application*-authored `Schema`
|
|
24
25
|
* transform on a payload field; the codec only propagates its requirement and
|
|
@@ -122,6 +123,7 @@ export { buildDecisionModel, modelAtHead } from "./decisionModel.js";
|
|
|
122
123
|
export { decodeSlices } from "./decode.js";
|
|
123
124
|
export { CodecError, UnknownEventType } from "./errors.js";
|
|
124
125
|
export { event } from "./event.js";
|
|
126
|
+
export { MetadataSource } from "./MetadataSource.js";
|
|
125
127
|
export { decideOnly, transact, unsafeAppend } from "./precondition.js";
|
|
126
128
|
export { projection } from "./projection.js";
|
|
127
129
|
export { NoReadsRecorded, ReadLedger, TaglessSliceInLedger } from "./readLedger.js";
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["decider","runDecider","Decision","isUnchanged","Unchanged","UnchangedTypeId","buildDecisionModel","modelAtHead","decodeSlices","CodecError","UnknownEventType","event","decideOnly","transact","unsafeAppend","projection","NoReadsRecorded","ReadLedger","TaglessSliceInLedger","makeRegistry","Serializer","SerializerDefault","toEvent","Uuid","UuidLive","UuidTest"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","names":["decider","runDecider","Decision","isUnchanged","Unchanged","UnchangedTypeId","buildDecisionModel","modelAtHead","decodeSlices","CodecError","UnknownEventType","event","MetadataSource","decideOnly","transact","unsafeAppend","projection","NoReadsRecorded","ReadLedger","TaglessSliceInLedger","makeRegistry","Serializer","SerializerDefault","toEvent","Uuid","UuidLive","UuidTest"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwHA,SAAuBA,OAAO,EAAEC,UAAU,QAAQ,cAAW;AAC7D,SACEC,QAAQ,EAGRC,WAAW,EACXC,SAAS,EACTC,eAAe,QACV,eAAY;AACnB,SACEC,kBAAkB,EAClBC,WAAW,QAEN,oBAAiB;AACxB,SAASC,YAAY,QAAQ,aAAU;AACvC,SAASC,UAAU,EAAEC,gBAAgB,QAAQ,aAAU;AACvD,SAA0CC,KAAK,QAAsB,YAAS;AAC9E,SAASC,cAAc,QAAQ,qBAAkB;AACjD,SACEC,UAAU,EAEVC,QAAQ,EACRC,YAAY,QACP,mBAAgB;AACvB,SAEEC,UAAU,QAEL,iBAAc;AACrB,SAGEC,eAAe,EACfC,UAAU,EACVC,oBAAoB,QACf,iBAAc;AACrB,SAASC,YAAY,QAAuB,eAAY;AACxD,SAASC,UAAU,EAAEC,iBAAiB,QAAQ,iBAAc;AAC5D,SAASC,OAAO,QAAQ,cAAW;AACnC,SAASC,IAAI,EAAEC,QAAQ,EAAEC,QAAQ,QAAQ,WAAQ","ignoreList":[]}
|
package/dist/esm/precondition.js
CHANGED
|
@@ -80,7 +80,7 @@ export const decideOnly = (decider, command) => Effect.gen(function* () {
|
|
|
80
80
|
* condition here. If that turns up in practice, a composing override is the
|
|
81
81
|
* additive answer and this hatch is not it.
|
|
82
82
|
*
|
|
83
|
-
* `Effect.
|
|
83
|
+
* `Effect.updateContext` over
|
|
84
84
|
* `Context.omit(AppendIsOwned)` is what lets it through the store's ownership
|
|
85
85
|
* refusal — the one route, and `AppendIsOwned.ts` owns why removing the marker is
|
|
86
86
|
* the shape rather than a second tag or a sanctioning flag.
|
|
@@ -109,7 +109,7 @@ reason) => Effect.flatMap(DcbEventStore, store =>
|
|
|
109
109
|
// channel), so nothing here will fail to compile if this is deleted — what
|
|
110
110
|
// catches it is `test/appendOwnership.test.ts` in the source repository, not the
|
|
111
111
|
// type checker.
|
|
112
|
-
Effect.
|
|
112
|
+
Effect.updateContext(store.append(events), context => Context.omit(AppendIsOwned)(context)));
|
|
113
113
|
/**
|
|
114
114
|
* Open a bracket over ONE decision: evaluate the precondition inside it, hand its
|
|
115
115
|
* output to the body under the precondition's tag, and append what the body
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"precondition.js","names":["AppendIsOwned","DcbEventStore","Context","Effect","Layer","isUnchanged","modelAtHead","deriveLayeredCondition","makeReadLedger","NoReadsRecorded","ReadLedger","decideOnly","decider","command","gen","state","projections","decide","unsafeAppend","events","reason","flatMap","store","
|
|
1
|
+
{"version":3,"file":"precondition.js","names":["AppendIsOwned","DcbEventStore","Context","Effect","Layer","isUnchanged","modelAtHead","deriveLayeredCondition","makeReadLedger","NoReadsRecorded","ReadLedger","decideOnly","decider","command","gen","state","projections","decide","unsafeAppend","events","reason","flatMap","store","updateContext","append","context","omit","transact","precondition","body","ledger","output","proof","evaluate","pipe","provideService","tag","provide","merge","layer","succeed","by","condition","hops","undefined"],"sources":["../../src/precondition.ts"],"sourcesContent":[null],"mappings":"AAwGA,SAASA,aAAa,EAAEC,aAAa,QAAQ,iBAAiB;AAE9D,SAASC,OAAO,EAAEC,MAAM,EAAEC,KAAK,QAAQ,QAAQ;AAE/C,SAGEC,WAAW,QACN,eAAY;AACnB,SAASC,WAAW,QAA4B,oBAAiB;AAGjE,SACEC,sBAAsB,EACtBC,cAAc,EACdC,eAAe,EACfC,UAAU,QAEL,iBAAc;AAgCrB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDA,OAAO,MAAMC,UAAU,GAAGA,CAOxBC,OAAqC,EACrCC,OAAgB,KAMhBV,MAAM,CAACW,GAAG,CAAC,aAAS;EAClB,OAAOJ,UAAU;EAEjB,MAAM;IAAEK;EAAK,CAAE,GAAG,OAAOT,WAAW,CAACM,OAAO,CAACI,WAAW,CAACH,OAAO,CAAC,CAAC;EAClE,OAAO,OAAOD,OAAO,CAACK,MAAM,CAACF,KAAK,EAAEF,OAAO,CAAC;AAC9C,CAAC,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;AAsBA,OAAO,MAAMK,YAAY,GAAGA,CAC1BC,MAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACAC,MAAc,KAEdjB,MAAM,CAACkB,OAAO,CAACpB,aAAa,EAAGqB,KAAK;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACAnB,MAAM,CAACoB,aAAa,CAClBD,KAAK,CAACE,MAAM,CAACL,MAAM,CAAC,EACnBM,OAA+B,IAAKvB,OAAO,CAACwB,IAAI,CAAC1B,aAAa,CAAC,CAACyB,OAAO,CAAC,CAC1E,CACF;AAEH;;;;;;;;;;;;;;;;;;;;;;;AAuBA,OAAO,MAAME,QAAQ,GACGC,YAA+C,IAEnEC,IAA4B,IAQ5B1B,MAAM,CAACW,GAAG,CAAC,aAAS;EAClB,MAAMQ,KAAK,GAAG,OAAOrB,aAAa;EAClC,MAAM6B,MAAM,GAAG,OAAOtB,cAAc;EAEpC,MAAMuB,MAAM,GAAmB,OAAO5B,MAAM,CAACW,GAAG,CAAC,aAAS;IACxD;IACA;IACA;IACA,MAAMkB,KAAK,GAAG,OAAOJ,YAAY,CAACK,QAAQ;IAC1C,OAAO,OAAOJ,IAAI,CAACK,IAAI,CAAC/B,MAAM,CAACgC,cAAc,CAACP,YAAY,CAACQ,GAAG,EAAEJ,KAAK,CAAC,CAAC;EACzE,CAAC,CAAC,CAACE,IAAI;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA/B,MAAM,CAACkC,OAAO,CACZjC,KAAK,CAACkC,KAAK,CACTR,MAAM,CAACS,KAAK,EACZnC,KAAK,CAACoC,OAAO,CAACxC,aAAa,EAAE;IAAEyC,EAAE,EAAE;EAAU,CAAE,CAAC,CACjD,CACF,CACF;EAED;EACA;EACA;EACA;EACA;EACA;EACA,IAAIpC,WAAW,CAAC0B,MAAM,CAAC,EAAE;IACvB,OAAOA,MAA2B;EACpC;EAEA,MAAMW,SAAS,GAAGnC,sBAAsB,CAAC,OAAOuB,MAAM,CAACa,IAAI,CAAC;EAC5D,IAAID,SAAS,KAAKE,SAAS,EAAE;IAC3B,OAAO,OAAO,IAAInC,eAAe,EAAE;EACrC;EAEA,OAAQ,OAAOa,KAAK,CAACE,MAAM,CAACO,MAAM,EAAEW,SAAS,CAAC;AAChD,CAAC,CAAC","ignoreList":[]}
|
package/dist/esm/projection.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* A `SliceProjection<S, R>` is a core `AnyProjection<S>` (directly composable —
|
|
6
6
|
* its `evolve` folds a `DecodedEvent`) enriched with the `type -> Schema` map
|
|
7
7
|
* `decodeSlices` merges and decodes through. That map's value type carries `R`
|
|
8
|
-
* covariantly (`Schema<unknown,
|
|
8
|
+
* covariantly (`Schema.Decoder<unknown, R>`), so the union of the defs'
|
|
9
9
|
* requirements flows to the decision model with no cast (and no phantom marker).
|
|
10
10
|
* Because `evolve` is already erased, a built slice drops straight into
|
|
11
11
|
* `composeProjections` — no `AnyProjection.of` ceremony.
|
|
@@ -50,18 +50,17 @@ export const projection = initialState => {
|
|
|
50
50
|
// The entry type is annotated `R | R2` rather than inferred, and that
|
|
51
51
|
// annotation is what carries the requirement forward — `build` reads `R`
|
|
52
52
|
// straight off this map, so `RequirementOf` ultimately reads it from here.
|
|
53
|
-
// Widening the copied `R` entries into it costs nothing: `Schema`
|
|
54
|
-
// declared `<
|
|
53
|
+
// Widening the copied `R` entries into it costs nothing: `Schema.Decoder`
|
|
54
|
+
// is declared `<out T, out RD>` upstream, hence covariant in its
|
|
55
55
|
// requirement.
|
|
56
56
|
const nextSchemas = new Map(schemas);
|
|
57
|
-
// Erasing `A`/`I`
|
|
58
|
-
//
|
|
59
|
-
// `Schema<unknown, unknown, R2>` are unrelated in either direction. It is
|
|
57
|
+
// Erasing `A`/`I` needs no cast: a `Schema.Codec` is covariant in both, so
|
|
58
|
+
// `Codec<A, I, R2, R2>` is already a `Decoder<unknown, R2>`. The erasure is
|
|
60
59
|
// sound because the payload is only ever read back through `evolve`, which
|
|
61
|
-
// re-narrows by event type via the matching `fold`.
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
//
|
|
60
|
+
// re-narrows by event type via the matching `fold`. What survives it is
|
|
61
|
+
// `R2`, the def's DECODING requirement — an `Encrypted` field's `CipherKey`
|
|
62
|
+
// is not nothing — and that is the half a slice ever spends, since a slice
|
|
63
|
+
// decodes and never encodes.
|
|
65
64
|
nextSchemas.set(def.type, def.schema);
|
|
66
65
|
const nextFolds = new Map(folds);
|
|
67
66
|
// Contravariance in the payload parameter, so this one is a cast too: the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projection.js","names":["EventType","projection","initialState","make","schemas","folds","on","def","fold","has","type","Error","nextSchemas","Map","set","schema","nextFolds","build","options","types","keys","map","t","query","items","tags","evolve","state","decoded","get","sequenced","event","undefined","payload"],"sources":["../../src/projection.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;AAmBA,SAGEA,SAAS,QAGJ,iBAAiB;AAoCxB;;;;AAIA,OAAO,MAAMC,UAAU,GAAOC,YAAe,IAAiC;EAC5E;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAMC,IAAI,GAAGA,CACXC,
|
|
1
|
+
{"version":3,"file":"projection.js","names":["EventType","projection","initialState","make","schemas","folds","on","def","fold","has","type","Error","nextSchemas","Map","set","schema","nextFolds","build","options","types","keys","map","t","query","items","tags","evolve","state","decoded","get","sequenced","event","undefined","payload"],"sources":["../../src/projection.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;AAmBA,SAGEA,SAAS,QAGJ,iBAAiB;AAoCxB;;;;AAIA,OAAO,MAAMC,UAAU,GAAOC,YAAe,IAAiC;EAC5E;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAMC,IAAI,GAAGA,CACXC,OAAwD,EACxDC,KAA6D,MAChC;IAC7BC,EAAE,EAAEA,CACFC,GAAuB,EACvBC,IAAiC,KACD;MAChC;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA,IAAIJ,OAAO,CAACK,GAAG,CAACF,GAAG,CAACG,IAAI,CAAC,EAAE;QACzB,MAAM,IAAIC,KAAK,CACb,yBAAyBJ,GAAG,CAACG,IAAI,mCAAmC,GAClE,gEAAgE,GAChE,gCAAgC,CACnC;MACH;MACA;MACA;MACA;MACA;MACA;MACA;MACA,MAAME,WAAW,GAAG,IAAIC,GAAG,CACzBT,OAAO,CACR;MACD;MACA;MACA;MACA;MACA;MACA;MACA;MACAQ,WAAW,CAACE,GAAG,CAACP,GAAG,CAACG,IAAI,EAAEH,GAAG,CAACQ,MAAM,CAAC;MACrC,MAAMC,SAAS,GAAG,IAAIH,GAAG,CAACR,KAAK,CAAC;MAChC;MACA;MACA;MACAW,SAAS,CAACF,GAAG,CAACP,GAAG,CAACG,IAAI,EAAEF,IAAyC,CAAC;MAClE,OAAOL,IAAI,CAASS,WAAW,EAAEI,SAAS,CAAC;IAC7C,CAAC;IACDC,KAAK,EAAGC,OAAO,IAAI;MACjB;MACA;MACA,MAAMC,KAAK,GAAG,CAAC,GAAGf,OAAO,CAACgB,IAAI,EAAE,CAAC,CAACC,GAAG,CAAEC,CAAC,IAAKtB,SAAS,CAACG,IAAI,CAACmB,CAAC,CAAC,CAAC;MAC/D,MAAMC,KAAK,GAAU;QACnBC,KAAK,EAAE,CAAC;UAAEL,KAAK;UAAEM,IAAI,EAAEP,OAAO,EAAEO,IAAI,IAAI;QAAE,CAAE;OAC7C;MACD,OAAO;QACLvB,YAAY;QACZqB,KAAK;QACL;QACA;QACA;QACA;QACA;QACA;QACAnB,OAAO,EAAE,IAAIS,GAAG,CAACT,OAAO,CAAC;QACzB;QACA;QACA;QACA;QACA;QACA;QACAsB,MAAM,EAAEA,CAACC,KAAK,EAAEC,OAAqB,KAAI;UACvC,MAAMpB,IAAI,GAAGH,KAAK,CAACwB,GAAG,CAACD,OAAO,CAACE,SAAS,CAACC,KAAK,CAACrB,IAAI,CAAC;UACpD,OAAOF,IAAI,KAAKwB,SAAS,GAAGL,KAAK,GAAGnB,IAAI,CAACmB,KAAU,EAAEC,OAAO,CAACK,OAAO,CAAC;QACvE;OACD;IACH;GACD,CAAC;EACF;EACA;EACA,OAAO9B,IAAI,CAAQ,IAAIU,GAAG,EAAE,EAAE,IAAIA,GAAG,EAAE,CAAC;AAC1C,CAAC","ignoreList":[]}
|
package/dist/esm/readLedger.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { composeProjections, ORIGIN, servableQueryFault, unionQueries } from '@kairos-es/core';
|
|
1
|
+
import { composeProjections, ORIGIN, servableQueryFault, unionQueries, unknownQueryKeyFault } from '@kairos-es/core';
|
|
2
2
|
import { Context, Data, Effect, Layer, Option, Ref } from 'effect';
|
|
3
3
|
/**
|
|
4
4
|
* The ambient ledger, present only inside a bracket.
|
|
@@ -8,7 +8,7 @@ import { Context, Data, Effect, Layer, Option, Ref } from 'effect';
|
|
|
8
8
|
* requirement channel nothing is exactly what makes this change additive.
|
|
9
9
|
* `modelAtHead` is that path and is why the rule exists.
|
|
10
10
|
*
|
|
11
|
-
* A BRACKET-ONLY function is the opposite case and yields the
|
|
11
|
+
* A BRACKET-ONLY function is the opposite case and yields the service deliberately.
|
|
12
12
|
* `decideOnly` does, and naming the requirement is what turns *"call me inside a
|
|
13
13
|
* bracket"* from a runtime defect into a compile error — presence being the one
|
|
14
14
|
* direction the type system can decide here. So the test is what the function
|
|
@@ -18,7 +18,7 @@ import { Context, Data, Effect, Layer, Option, Ref } from 'effect';
|
|
|
18
18
|
* Recording is two-phase, and `record`'s own doc below owns why and what shape the
|
|
19
19
|
* second phase takes.
|
|
20
20
|
*/
|
|
21
|
-
export class ReadLedger extends /*#__PURE__*/Context.
|
|
21
|
+
export class ReadLedger extends /*#__PURE__*/Context.Service()('@kairos-es/codec/ReadLedger') {}
|
|
22
22
|
/**
|
|
23
23
|
* Raised when a bracket closes having recorded no read at all.
|
|
24
24
|
*
|
|
@@ -163,8 +163,23 @@ const NO_CLOSE = () => Effect.void;
|
|
|
163
163
|
export const recordQuery = query => withLedger(NO_CLOSE, ledger => ledger.record(query));
|
|
164
164
|
/** The tagless slice keys in a record, in declaration order. */
|
|
165
165
|
const taglessKeys = projections => Object.entries(projections).filter(([, projection]) => projection.query.items.some(item => item.tags.length === 0)).map(([key]) => key);
|
|
166
|
-
/**
|
|
167
|
-
|
|
166
|
+
/**
|
|
167
|
+
* Would recording this record's query leave the accumulated union unservable in
|
|
168
|
+
* its SHAPE — the one fault a slice's tags can fix, and so the one this ledger
|
|
169
|
+
* reports?
|
|
170
|
+
*
|
|
171
|
+
* An unknown key anywhere in the union answers no. It is not a tagless slice and no
|
|
172
|
+
* slice's tags would fix it, and the store refuses it as a defect naming the key at
|
|
173
|
+
* the read of the hop that carries it, so an earlier hop's key has already been
|
|
174
|
+
* refused once by the time a later record is judged. Judged here it would surface
|
|
175
|
+
* as this ledger's error, on the error channel, naming a slice with nothing wrong
|
|
176
|
+
* with it — and a hop is recorded before its read runs, so an earlier hop's key
|
|
177
|
+
* would go on doing that to every clean read after it.
|
|
178
|
+
*/
|
|
179
|
+
const unionWouldBeUnservable = (existing, incoming) => {
|
|
180
|
+
const union = unionQueries([...existing.map(h => h.query), incoming]);
|
|
181
|
+
return unknownQueryKeyFault(union) === undefined && servableQueryFault(union) !== undefined;
|
|
182
|
+
};
|
|
168
183
|
/**
|
|
169
184
|
* Refuse a read that would leave the bracket's accumulated union unservable,
|
|
170
185
|
* BEFORE the read is paid for.
|
|
@@ -208,5 +223,5 @@ export const assertServableAddition = projections => withLedger(undefined, ledge
|
|
|
208
223
|
* current behaviour is the hazard derives from every hop the bracket walked rather
|
|
209
224
|
* than from its own single read.
|
|
210
225
|
*/
|
|
211
|
-
export const ambientLayeredCondition = /*#__PURE__*/withLedger(/*#__PURE__*/Option.none(), ledger => Effect.map(ledger.hops, hops => Option.
|
|
226
|
+
export const ambientLayeredCondition = /*#__PURE__*/withLedger(/*#__PURE__*/Option.none(), ledger => Effect.map(ledger.hops, hops => Option.fromNullishOr(deriveLayeredCondition(hops))));
|
|
212
227
|
//# sourceMappingURL=readLedger.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readLedger.js","names":["composeProjections","ORIGIN","servableQueryFault","unionQueries","Context","Data","Effect","Layer","Option","Ref","ReadLedger","
|
|
1
|
+
{"version":3,"file":"readLedger.js","names":["composeProjections","ORIGIN","servableQueryFault","unionQueries","unknownQueryKeyFault","Context","Data","Effect","Layer","Option","Ref","ReadLedger","Service","NoReadsRecorded","TaggedError","message","TaglessSliceInLedger","sliceKey","deriveLayeredCondition","hops","length","undefined","merged","map","hop","query","arrived","flatMap","head","after","reduce","a","b","failIfEventsMatch","makeReadLedger","gen","ref","make","layer","succeed","record","modify","update","current","index","get","withLedger","absent","f","serviceOption","ledger","isNone","value","NO_CLOSE","void","recordQuery","taglessKeys","projections","Object","entries","filter","projection","items","some","item","tags","key","unionWouldBeUnservable","existing","incoming","union","h","assertServableAddition","offending","ambientLayeredCondition","none","fromNullishOr"],"sources":["../../src/readLedger.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
package/dist/esm/registry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","names":["Effect","deserialiseThenDecode","UnknownEventType","Serializer","makeRegistry","defs","map","Map","def","has","type","Error","set","schema","decode","event","gen","get","undefined","fail","serializer","payload","data"],"sources":["../../src/registry.ts"],"sourcesContent":[null],"mappings":"AA2BA,SAASA,MAAM,QAAqB,QAAQ;AAC5C,SAASC,qBAAqB,QAAQ,4BAAyB;AAC/D,SAA0BC,gBAAgB,QAAQ,aAAU;AAE5D,SAASC,UAAU,QAAQ,iBAAc;AAqBzC,OAAO,MAAMC,YAAY,GACvBC,IAAU,IAC2B;EACrC,MAAMC,GAAG,GAAG,IAAIC,GAAG,
|
|
1
|
+
{"version":3,"file":"registry.js","names":["Effect","deserialiseThenDecode","UnknownEventType","Serializer","makeRegistry","defs","map","Map","def","has","type","Error","set","schema","decode","event","gen","get","undefined","fail","serializer","payload","data"],"sources":["../../src/registry.ts"],"sourcesContent":[null],"mappings":"AA2BA,SAASA,MAAM,QAAqB,QAAQ;AAC5C,SAASC,qBAAqB,QAAQ,4BAAyB;AAC/D,SAA0BC,gBAAgB,QAAQ,aAAU;AAE5D,SAASC,UAAU,QAAQ,iBAAc;AAqBzC,OAAO,MAAMC,YAAY,GACvBC,IAAU,IAC2B;EACrC,MAAMC,GAAG,GAAG,IAAIC,GAAG,EAA4C;EAC/D,KAAK,MAAMC,GAAG,IAAIH,IAAI,EAAE;IACtB,IAAIC,GAAG,CAACG,GAAG,CAACD,GAAG,CAACE,IAAI,CAAC,EAAE;MACrB,MAAM,IAAIC,KAAK,CAAC,yBAAyBH,GAAG,CAACE,IAAI,eAAe,CAAC;IACnE;IACAJ,GAAG,CAACM,GAAG,CAACJ,GAAG,CAACE,IAAI,EAAEF,GAAG,CAACK,MAAM,CAAC;EAC/B;EACA,OAAO;IACLC,MAAM,EAAGC,KAAK,IACZf,MAAM,CAACgB,GAAG,CAAC,aAAS;MAClB,MAAMH,MAAM,GAAGP,GAAG,CAACW,GAAG,CAACF,KAAK,CAACL,IAAI,CAAC;MAClC,IAAIG,MAAM,KAAKK,SAAS,EAAE;QACxB,OAAO,OAAOlB,MAAM,CAACmB,IAAI,CAAC,IAAIjB,gBAAgB,CAAC;UAAEQ,IAAI,EAAEK,KAAK,CAACL;QAAI,CAAE,CAAC,CAAC;MACvE;MACA,MAAMU,UAAU,GAAG,OAAOjB,UAAU;MACpC,MAAMkB,OAAO,GAAG,OAAOpB,qBAAqB,CAC1CmB,UAAU,EACVP,MAAM,EACNE,KAAK,CAACO,IAAI,CACX;MACD,OAAO;QAAEZ,IAAI,EAAEK,KAAK,CAACL,IAAI;QAAEW;MAAO,CAAE;MACpC;MACA;MACA;MACA;IACF,CAAC;GAKJ;AACH,CAAC","ignoreList":[]}
|
package/dist/esm/toEvent.js
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Event production (codec edge-helper): turn a typed payload into a wire
|
|
3
|
+
* `DcbEvent`. Encode is `Schema.encodeEffect(def.schema)` (a `SchemaError`
|
|
4
|
+
* becomes a `CodecError`; any encryption transform runs here, *before* serialisation)
|
|
5
|
+
* then `serialiser.serialise`. The wire `tags` are derived from the def's
|
|
6
|
+
* required `tagsFor` mapper (ADR-0006) — they are never hand-passed, so two
|
|
7
|
+
* command sites emitting the same event type cannot tag it differently. A mapper
|
|
8
|
+
* that throws (e.g. an ill-formed `key:value` rejected by `Tag.make`) is
|
|
9
|
+
* surfaced on the `CodecError` channel, not as a defect. `uuid`
|
|
10
|
+
* comes from `options.uuid` or the `Uuid` service; `occurredAt` from
|
|
11
|
+
* `options.occurredAt` or the Effect clock (`DateTime.now`), keeping `core`
|
|
12
|
+
* clock- and RNG-free while staying overridable for backdated imports.
|
|
13
|
+
* `metadata` comes from `options.metadata` or the OPTIONAL ambient
|
|
14
|
+
* `MetadataSource` service, and is `{}` when neither supplies it (ADR-0017). A
|
|
15
|
+
* bag core's `Metadata` schema refuses, such as one holding a value that is not a
|
|
16
|
+
* string, fails on the `CodecError` channel (`reason: 'metadata'`), whichever of
|
|
17
|
+
* the two supplied it. It never reaches `tagsFor`, the
|
|
18
|
+
* event's schema or the serialiser, so it can enter neither the tag junction
|
|
19
|
+
* table nor the encryption seam.
|
|
20
|
+
*/
|
|
21
|
+
import { Metadata } from '@kairos-es/core';
|
|
22
|
+
import { DateTime, Effect, Option, Schema } from 'effect';
|
|
2
23
|
import { CodecError } from "./errors.js";
|
|
24
|
+
import { MetadataSource } from "./MetadataSource.js";
|
|
3
25
|
import { Serializer } from "./Serializer.js";
|
|
4
26
|
import { Uuid } from "./Uuid.js";
|
|
5
27
|
/**
|
|
@@ -10,10 +32,40 @@ import { Uuid } from "./Uuid.js";
|
|
|
10
32
|
* wire-envelope fields (the query surface), so a `tagsFor` mapper may only key
|
|
11
33
|
* off cleartext payload fields (ADR-0006). `uuid` / `occurredAt` are
|
|
12
34
|
* exact-optional overrides; absent, they come from the `Uuid` service and the
|
|
13
|
-
* Effect clock.
|
|
35
|
+
* Effect clock. `metadata` is an exact-optional override too; absent, it comes
|
|
36
|
+
* from the ambient `MetadataSource` if one is provided and is `{}` otherwise.
|
|
37
|
+
* The ambient read adds nothing to the requirement channel. A bag core's
|
|
38
|
+
* `Metadata` schema refuses fails as a `CodecError` with `reason: 'metadata'`.
|
|
14
39
|
*/
|
|
15
40
|
export const toEvent = (def, payload, options) => Effect.gen(function* () {
|
|
16
|
-
//
|
|
41
|
+
// Resolve metadata before anything else. Per-call wins, ambient fills,
|
|
42
|
+
// absent yields `{}`. `serviceOption` keeps `MetadataSource` out of the
|
|
43
|
+
// requirement channel.
|
|
44
|
+
//
|
|
45
|
+
// The bag is then CHECKED against core's `Metadata` schema, whichever arm
|
|
46
|
+
// supplied it. The type holds a typed caller to a bag of strings, but an
|
|
47
|
+
// `any` or untyped JavaScript gets past it, and the engines then disagree
|
|
48
|
+
// about what they stored: the cross-engine parity of this field rests on its
|
|
49
|
+
// values being strings, and this is the one place a value is refused. It is
|
|
50
|
+
// refused HERE, at write, and never on read: a read-side check would make an
|
|
51
|
+
// event the store had accepted unreadable for ever. A bad bag is the
|
|
52
|
+
// caller's mistake, so it fails on the `CodecError` channel exactly as a
|
|
53
|
+
// throwing `tagsFor` does, never as a defect. Checking consumes no sequence,
|
|
54
|
+
// so placing it above the tag derivation leaves the property below intact.
|
|
55
|
+
//
|
|
56
|
+
// The bag is COPIED, never stamped by reference: an ambient bag would
|
|
57
|
+
// otherwise be ONE object shared by every event of a request, and the
|
|
58
|
+
// caller's own object would be shared with the event it built, so a mutation
|
|
59
|
+
// of either before the append would rewrite the other. (After the append no
|
|
60
|
+
// store shares anything with its caller; that is each store's guarantee.)
|
|
61
|
+
const given = options?.metadata === undefined ? Option.getOrElse(yield* Effect.serviceOption(MetadataSource), () => ({})) : options.metadata;
|
|
62
|
+
const metadata = {
|
|
63
|
+
...(yield* Schema.decodeUnknownEffect(Metadata)(given).pipe(Effect.mapError(cause => new CodecError({
|
|
64
|
+
reason: 'metadata',
|
|
65
|
+
cause
|
|
66
|
+
}))))
|
|
67
|
+
};
|
|
68
|
+
// Derive tags next. A mapper is app code that can throw (e.g. `Tag.make`
|
|
17
69
|
// rejects an ill-formed `key:value`), and the codec's contract is that such
|
|
18
70
|
// failures are values on the `CodecError` channel, never defects (errors.ts).
|
|
19
71
|
// Deriving before the uuid/clock effects also means a bad tag fails without
|
|
@@ -26,7 +78,7 @@ export const toEvent = (def, payload, options) => Effect.gen(function* () {
|
|
|
26
78
|
})
|
|
27
79
|
});
|
|
28
80
|
const serializer = yield* Serializer;
|
|
29
|
-
const encoded = yield* Schema.
|
|
81
|
+
const encoded = yield* Schema.encodeEffect(def.schema)(payload).pipe(Effect.mapError(cause => new CodecError({
|
|
30
82
|
reason: 'encode',
|
|
31
83
|
cause
|
|
32
84
|
})));
|
|
@@ -38,7 +90,8 @@ export const toEvent = (def, payload, options) => Effect.gen(function* () {
|
|
|
38
90
|
data,
|
|
39
91
|
tags,
|
|
40
92
|
uuid,
|
|
41
|
-
occurredAt
|
|
93
|
+
occurredAt,
|
|
94
|
+
metadata
|
|
42
95
|
};
|
|
43
96
|
});
|
|
44
97
|
//# sourceMappingURL=toEvent.js.map
|
package/dist/esm/toEvent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toEvent.js","names":["DateTime","Effect","Schema","CodecError","Serializer","Uuid","toEvent","def","payload","options","gen","
|
|
1
|
+
{"version":3,"file":"toEvent.js","names":["Metadata","DateTime","Effect","Option","Schema","CodecError","MetadataSource","Serializer","Uuid","toEvent","def","payload","options","gen","given","metadata","undefined","getOrElse","serviceOption","decodeUnknownEffect","pipe","mapError","cause","reason","tags","try","tagsFor","catch","serializer","encoded","encodeEffect","schema","data","serialise","uuid","generate","occurredAt","now","type"],"sources":["../../src/toEvent.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;AAoBA,SAAwBA,QAAQ,QAAQ,iBAAiB;AACzD,SAASC,QAAQ,EAAEC,MAAM,EAAEC,MAAM,EAAEC,MAAM,QAAQ,QAAQ;AACzD,SAASC,UAAU,QAAQ,aAAU;AAErC,SAASC,cAAc,QAAQ,qBAAkB;AACjD,SAASC,UAAU,QAAQ,iBAAc;AACzC,SAASC,IAAI,QAAQ,WAAQ;AAE7B;;;;;;;;;;;;;AAaA,OAAO,MAAMC,OAAO,GAAGA,CACrBC,GAAsB,EACtBC,OAAU,EACVC,OAIC,KAEDV,MAAM,CAACW,GAAG,CAAC,aAAS;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAMC,KAAK,GACTF,OAAO,EAAEG,QAAQ,KAAKC,SAAS,GAC3Bb,MAAM,CAACc,SAAS,CACd,OAAOf,MAAM,CAACgB,aAAa,CAACZ,cAAc,CAAC,EAC3C,OAAiB,EAAE,CAAC,CACrB,GACDM,OAAO,CAACG,QAAQ;EACtB,MAAMA,QAAQ,GAAa;IACzB,IAAI,OAAOX,MAAM,CAACe,mBAAmB,CAACnB,QAAQ,CAAC,CAACc,KAAK,CAAC,CAACM,IAAI,CACzDlB,MAAM,CAACmB,QAAQ,CACZC,KAAK,IAAK,IAAIjB,UAAU,CAAC;MAAEkB,MAAM,EAAE,UAAU;MAAED;IAAK,CAAE,CAAC,CACzD,CACF;GACF;EACD;EACA;EACA;EACA;EACA;EACA,MAAME,IAAI,GAAG,OAAOtB,MAAM,CAACuB,GAAG,CAAC;IAC7BA,GAAG,EAAEA,CAAA,KAAMf,GAAG,CAACgB,OAAO,CAACf,OAAO,CAAC;IAC/BgB,KAAK,EAAGL,KAAK,IAAK,IAAIjB,UAAU,CAAC;MAAEkB,MAAM,EAAE,MAAM;MAAED;IAAK,CAAE;GAC3D,CAAC;EACF,MAAMM,UAAU,GAAG,OAAOrB,UAAU;EACpC,MAAMsB,OAAO,GAAG,OAAOzB,MAAM,CAAC0B,YAAY,CAACpB,GAAG,CAACqB,MAAM,CAAC,CAACpB,OAAO,CAAC,CAACS,IAAI,CAClElB,MAAM,CAACmB,QAAQ,CAAEC,KAAK,IAAK,IAAIjB,UAAU,CAAC;IAAEkB,MAAM,EAAE,QAAQ;IAAED;EAAK,CAAE,CAAC,CAAC,CACxE;EACD,MAAMU,IAAI,GAAGJ,UAAU,CAACK,SAAS,CAACJ,OAAO,CAAC;EAC1C,MAAMK,IAAI,GAAGtB,OAAO,EAAEsB,IAAI,KAAK,OAAO,CAAC,OAAO1B,IAAI,EAAE2B,QAAQ,CAAC;EAC7D,MAAMC,UAAU,GAAGxB,OAAO,EAAEwB,UAAU,KAAK,OAAOnC,QAAQ,CAACoC,GAAG,CAAC;EAC/D,OAAO;IACLC,IAAI,EAAE5B,GAAG,CAAC4B,IAAI;IACdN,IAAI;IACJR,IAAI;IACJU,IAAI;IACJE,UAAU;IACVrB;GACD;AACH,CAAC,CAAC","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kairos-es/codec",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.5",
|
|
4
4
|
"description": "Schema-first codec with encryption seam for kairos-es",
|
|
5
5
|
"license": "BSD-3-Clause",
|
|
6
6
|
"repository": {
|
|
@@ -11,17 +11,22 @@
|
|
|
11
11
|
"sideEffects": [],
|
|
12
12
|
"homepage": "https://github.com/neverbland/kairos-es",
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"effect": "^
|
|
15
|
-
"@kairos-es/core": "^1.0.0-alpha.
|
|
14
|
+
"effect": "^4.0.5",
|
|
15
|
+
"@kairos-es/core": "^1.0.0-alpha.5"
|
|
16
16
|
},
|
|
17
17
|
"main": "./dist/cjs/index.js",
|
|
18
18
|
"module": "./dist/esm/index.js",
|
|
19
|
-
"types": "./dist/dts/index.d.ts",
|
|
19
|
+
"types": "./dist/dts-cjs/index.d.ts",
|
|
20
20
|
"exports": {
|
|
21
21
|
".": {
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
"import": {
|
|
23
|
+
"types": "./dist/dts-esm/index.d.ts",
|
|
24
|
+
"default": "./dist/esm/index.js"
|
|
25
|
+
},
|
|
26
|
+
"require": {
|
|
27
|
+
"types": "./dist/dts-cjs/index.d.ts",
|
|
28
|
+
"default": "./dist/cjs/index.js"
|
|
29
|
+
}
|
|
25
30
|
},
|
|
26
31
|
"./package.json": "./package.json"
|
|
27
32
|
},
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ambient metadata service: an OPTIONAL source of the `metadata` bag that
|
|
3
|
+
* `toEvent` stamps on an event when the call itself passes none (ADR-0017).
|
|
4
|
+
*
|
|
5
|
+
* An application provides it once, at the edge of a unit of work — an HTTP
|
|
6
|
+
* request, a job — and every event appended inside that scope carries the bag
|
|
7
|
+
* with no command handler, decider or `toEvent` call site mentioning it:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* handleRequest.pipe(
|
|
11
|
+
* Effect.provideService(MetadataSource, { traceparent: header }),
|
|
12
|
+
* )
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* It is read through `Effect.serviceOption`, never `yield* MetadataSource`, and
|
|
16
|
+
* that choice is the whole design. `serviceOption` returns `Effect<Option<…>>`
|
|
17
|
+
* with BOTH the requirement and the error channel as `never`, so this tag never
|
|
18
|
+
* appears in `toEvent`'s requirement channel nor in any signature above it, and
|
|
19
|
+
* no consumer is forced to provide a layer it does not want. The `Uuid` service
|
|
20
|
+
* beside this is a REQUIRED tag; adopting that shape here would put a metadata
|
|
21
|
+
* layer on every consumer of the codec. Core stays a passive carrier: the
|
|
22
|
+
* ambient read happens here, in the codec, where reading a service breaches no
|
|
23
|
+
* purity rule.
|
|
24
|
+
*
|
|
25
|
+
* A per-call `options.metadata` REPLACES this value rather than merging with it:
|
|
26
|
+
* per-call wins, ambient fills, and absent yields `{}`. A merge would make the
|
|
27
|
+
* bag an event carries depend on two sources at once, and a caller who passes a
|
|
28
|
+
* bag explicitly is stating what the event's bag is.
|
|
29
|
+
*
|
|
30
|
+
* One key is reserved, as a convention and not a column: `traceparent`. Reserved
|
|
31
|
+
* means that when a bag carries W3C trace context it carries it under that key,
|
|
32
|
+
* holding a W3C `traceparent` header value, so tracing tools match it; kairos
|
|
33
|
+
* itself never writes or reads it. Every other key is the application's: a key
|
|
34
|
+
* is kairos's to name only when kairos writes it or a standard owns the
|
|
35
|
+
* spelling, and `correlationId` / `causationId` are suggested spellings rather
|
|
36
|
+
* than reserved ones (ADR-0017).
|
|
37
|
+
*/
|
|
38
|
+
import type { Metadata } from '@kairos-es/core'
|
|
39
|
+
import { Context } from 'effect'
|
|
40
|
+
|
|
41
|
+
export class MetadataSource extends Context.Service<MetadataSource, Metadata>()(
|
|
42
|
+
'@kairos-es/codec/MetadataSource',
|
|
43
|
+
) {}
|
package/src/Serializer.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The pluggable serialiser: the `Uint8Array` <-> value boundary applied
|
|
3
|
-
* *outside* `Schema`. Encode is `Schema.
|
|
4
|
-
* `deserialise` then `Schema.
|
|
3
|
+
* *outside* `Schema`. Encode is `Schema.encodeEffect` then `serialise`; decode is
|
|
4
|
+
* `deserialise` then `Schema.decodeUnknownEffect`. Both codec paths read the same
|
|
5
5
|
* `Serializer` from context, so encode and decode cannot mismatch; swapping
|
|
6
6
|
* JSON for msgpack is a different layer with no schema or call-site changes.
|
|
7
7
|
*
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { Context, Layer } from 'effect'
|
|
14
14
|
|
|
15
|
-
export class Serializer extends Context.
|
|
15
|
+
export class Serializer extends Context.Service<
|
|
16
16
|
Serializer,
|
|
17
17
|
{
|
|
18
18
|
readonly serialise: (v: unknown) => Uint8Array
|
|
19
19
|
readonly deserialise: (b: Uint8Array) => unknown
|
|
20
20
|
}
|
|
21
|
-
>() {}
|
|
21
|
+
>()('@kairos-es/codec/Serializer') {}
|
|
22
22
|
|
|
23
23
|
const encoder = new TextEncoder()
|
|
24
24
|
const decoder = new TextDecoder()
|
package/src/Uuid.ts
CHANGED
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
import { makeSequentialUuid } from '@kairos-es/core/testing'
|
|
13
13
|
import { Context, Effect, Layer } from 'effect'
|
|
14
14
|
|
|
15
|
-
export class Uuid extends Context.
|
|
15
|
+
export class Uuid extends Context.Service<
|
|
16
16
|
Uuid,
|
|
17
17
|
{ readonly generate: Effect.Effect<string> }
|
|
18
|
-
>() {}
|
|
18
|
+
>()('@kairos-es/codec/Uuid') {}
|
|
19
19
|
|
|
20
20
|
/** Live uuid generation via WebCrypto (no `node:crypto`). */
|
|
21
21
|
export const UuidLive: Layer.Layer<Uuid> = Layer.succeed(Uuid, {
|
|
@@ -25,9 +25,12 @@ export const UuidLive: Layer.Layer<Uuid> = Layer.succeed(Uuid, {
|
|
|
25
25
|
/**
|
|
26
26
|
* A deterministic uuid layer for suites, wrapping core's shared
|
|
27
27
|
* `makeSequentialUuid` (the single source of truth for the counter scheme).
|
|
28
|
-
* Each layer
|
|
28
|
+
* Each BUILD of the layer makes a fresh generator, so it owns its own counter and
|
|
29
29
|
* yields a stable v4-shaped sequence `00000000-0000-4000-8000-<12 hex>` starting
|
|
30
|
-
* at `...000000000000`.
|
|
30
|
+
* at `...000000000000`. A build is not one per `Effect.provide`: Effect memoises
|
|
31
|
+
* a layer across the provisions that share a memo map, so a nested second
|
|
32
|
+
* provision of this layer continues the counter rather than restarting it, and
|
|
33
|
+
* `Layer.fresh` is the way to ask for a restart. Generation is wrapped in `Effect.sync` because the
|
|
31
34
|
* generator advances its counter (a side effect on each call).
|
|
32
35
|
*/
|
|
33
36
|
export const UuidTest: Layer.Layer<Uuid> = Layer.sync(Uuid, () => {
|
package/src/decider.ts
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
* append condition the read produced. That IS the optimistic-concurrency
|
|
40
40
|
* contract, in production and in a scenario alike — which is also why the
|
|
41
41
|
* Given/When/Then surface built on it exercises the real fold and the real store
|
|
42
|
-
* rather than a mock. It is a free function rather than a `Context.
|
|
42
|
+
* rather than a mock. It is a free function rather than a `Context.Service`,
|
|
43
43
|
* so it is still not the "production command-runner service method" a retrying
|
|
44
44
|
* `Layer` would need (ADR-0008): the correct retry remains
|
|
45
45
|
* `retryOnConflict(runDecider(...))`, wrapping the whole cycle so a fresh read
|
|
@@ -152,7 +152,7 @@ export interface Decider<
|
|
|
152
152
|
* unioning them. Against the shaped target `E` therefore came out as whichever
|
|
153
153
|
* branch won, and every other branch was then rejected against it. Inference to
|
|
154
154
|
* a NAKED type variable takes the union whole, which is why `Eff` is the
|
|
155
|
-
* parameter and `Effect.
|
|
155
|
+
* parameter and `Effect.Error` / `Effect.Services` recover the two
|
|
156
156
|
* channels afterwards: those do distribute across a union of effects.
|
|
157
157
|
*
|
|
158
158
|
* The constraint on `Eff` is load-bearing twice over. It is what still refuses a
|
|
@@ -190,9 +190,9 @@ export interface Decider<
|
|
|
190
190
|
* them in would state the same requirement twice and make an ordinary decider
|
|
191
191
|
* read as though it carried an extra one, though the set `runDecider` ends up
|
|
192
192
|
* asking for is identical either way. The exclusion cannot swallow a caller's
|
|
193
|
-
* own service by accident: a `Context.
|
|
194
|
-
* a literal `
|
|
195
|
-
* `@kairos-es/codec/Serializer` matches — and a
|
|
193
|
+
* own service by accident: a `Context.Service` class's requirement type carries
|
|
194
|
+
* its key as a literal `key` field, so only a service declared under `@kairos-es/codec/Uuid` or
|
|
195
|
+
* `@kairos-es/codec/Serializer` matches — and a service under that key IS that
|
|
196
196
|
* service, context being keyed by the same string at runtime.
|
|
197
197
|
*/
|
|
198
198
|
export function decider<
|
|
@@ -209,8 +209,8 @@ export function decider<
|
|
|
209
209
|
): Decider<
|
|
210
210
|
P,
|
|
211
211
|
Command,
|
|
212
|
-
Effect.
|
|
213
|
-
Exclude<Effect.
|
|
212
|
+
Effect.Error<Eff>,
|
|
213
|
+
Exclude<Effect.Services<Eff>, Serializer | Uuid>
|
|
214
214
|
>
|
|
215
215
|
export function decider<
|
|
216
216
|
P extends Record<string, SliceProjection>,
|
|
@@ -222,8 +222,8 @@ export function decider<
|
|
|
222
222
|
): Decider<
|
|
223
223
|
P,
|
|
224
224
|
Command,
|
|
225
|
-
Effect.
|
|
226
|
-
Exclude<Effect.
|
|
225
|
+
Effect.Error<Eff>,
|
|
226
|
+
Exclude<Effect.Services<Eff>, Serializer | Uuid>,
|
|
227
227
|
DecisionOutput
|
|
228
228
|
>
|
|
229
229
|
export function decider<P extends Record<string, SliceProjection>, Command>(
|
package/src/decision.ts
CHANGED
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
* channels; an overloaded step would lose both to `unknown`.
|
|
67
67
|
*
|
|
68
68
|
* `decider(…)` cannot be served by a conditional at all. Its `O` is derived from
|
|
69
|
-
* the SUCCESS of an effect type variable, and `Effect.
|
|
69
|
+
* the SUCCESS of an effect type variable, and `Effect.Success` of a type
|
|
70
70
|
* variable is itself deferred, so a wrapper that copies `decider`'s own generics
|
|
71
71
|
* would get a `Decider` whose `O` nothing can resolve, and a runner result that
|
|
72
72
|
* is not `Position`. So `decider` is declared TWICE, which asks the question by
|
package/src/decisionModel.ts
CHANGED
|
@@ -152,7 +152,7 @@ export const modelAtHead = <T extends Record<string, SliceProjection>>(
|
|
|
152
152
|
|
|
153
153
|
const state = (yield* Stream.runFold(
|
|
154
154
|
decoded,
|
|
155
|
-
composite.initialState,
|
|
155
|
+
() => composite.initialState,
|
|
156
156
|
(acc, event) => composite.evolve(acc, event),
|
|
157
157
|
)) as CompositeState<T>
|
|
158
158
|
|
package/src/decode.ts
CHANGED
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
* than memory.
|
|
21
21
|
*
|
|
22
22
|
* Be precise about what adding `concurrency` here would and would not cost,
|
|
23
|
-
* because the obvious reason is the wrong one. Effect
|
|
23
|
+
* because the obvious reason is the wrong one. Effect's `mapEffect` is
|
|
24
24
|
* order-PRESERVING even when concurrent — reordering needs the separate
|
|
25
|
-
* `unordered: true` option (verified against
|
|
26
|
-
*
|
|
25
|
+
* `unordered: true` option (verified against `effect@4`'s `Channel.mapEffect`,
|
|
26
|
+
* which takes the ordered path unless that option is set) — so a bare
|
|
27
27
|
* `concurrency` would NOT hand the fold its events out of position order. What
|
|
28
28
|
* it would actually cost is the back-pressure above, and it would run
|
|
29
29
|
* application-authored `Schema` transforms (an ADR-0004 decryption hook, say)
|
|
@@ -84,9 +84,9 @@ import { Serializer } from './Serializer'
|
|
|
84
84
|
* last, an ordering the record does not express and its author never chose.
|
|
85
85
|
* Every event of that type is then decoded against the wrong def for one of the
|
|
86
86
|
* slices, and where the two shapes overlap that failure is SILENT rather than a
|
|
87
|
-
* `CodecError`: `Schema.
|
|
88
|
-
* (`effect@
|
|
89
|
-
* `'error'`
|
|
87
|
+
* `CodecError`: `Schema.decodeUnknownEffect` defaults `onExcessProperty` to
|
|
88
|
+
* `'ignore'` (`effect@4`'s `SchemaAST.ts` runs its excess-key loop only under
|
|
89
|
+
* `'error'`), so a field the other def declared is dropped, not
|
|
90
90
|
* reported, and the fold downstream is handed a payload quietly missing it.
|
|
91
91
|
*
|
|
92
92
|
* **Why a throw, and why here rather than at the read side's wiring gate.**
|
|
@@ -100,8 +100,8 @@ import { Serializer } from './Serializer'
|
|
|
100
100
|
* the write path merges before its first `store.read`, and the read side
|
|
101
101
|
* merges after that gate and before it forks the pipeline — and inside
|
|
102
102
|
* their `Effect.gen`s a throw becomes a DEFECT rather than an escaping exception
|
|
103
|
-
* (`effect@
|
|
104
|
-
* `
|
|
103
|
+
* (`effect@4`'s fibre run loop catches a thrown value and converts it with
|
|
104
|
+
* `exitDie`), which is the classification a mis-wiring already has on both
|
|
105
105
|
* sides of the library.
|
|
106
106
|
*
|
|
107
107
|
* The sentence names BOTH slices. The two halves of this mistake are in
|
|
@@ -120,11 +120,8 @@ import { Serializer } from './Serializer'
|
|
|
120
120
|
*/
|
|
121
121
|
const mergeSliceSchemas = <T extends Record<string, SliceProjection>>(
|
|
122
122
|
projections: T,
|
|
123
|
-
): ReadonlyMap<string, Schema.
|
|
124
|
-
const schemas = new Map<
|
|
125
|
-
string,
|
|
126
|
-
Schema.Schema<unknown, unknown, RequirementOf<T>>
|
|
127
|
-
>()
|
|
123
|
+
): ReadonlyMap<string, Schema.Decoder<unknown, RequirementOf<T>>> => {
|
|
124
|
+
const schemas = new Map<string, Schema.Decoder<unknown, RequirementOf<T>>>()
|
|
128
125
|
// Which slice contributed each entry, kept in lockstep with `schemas` purely
|
|
129
126
|
// so the refusal can name both sides of a collision. Its presence is also what
|
|
130
127
|
// the check below reads, rather than a second `schemas.has`, so the narrowing
|
|
@@ -142,10 +139,7 @@ const mergeSliceSchemas = <T extends Record<string, SliceProjection>>(
|
|
|
142
139
|
'only by sharing one EventDef.',
|
|
143
140
|
)
|
|
144
141
|
}
|
|
145
|
-
schemas.set(
|
|
146
|
-
type,
|
|
147
|
-
schema as Schema.Schema<unknown, unknown, RequirementOf<T>>,
|
|
148
|
-
)
|
|
142
|
+
schemas.set(type, schema as Schema.Decoder<unknown, RequirementOf<T>>)
|
|
149
143
|
contributedBy.set(type, key)
|
|
150
144
|
}
|
|
151
145
|
}
|
|
@@ -181,7 +175,7 @@ const mergeSliceSchemas = <T extends Record<string, SliceProjection>>(
|
|
|
181
175
|
* "build the lookup once, reuse the stage" property explicit in the types.
|
|
182
176
|
*/
|
|
183
177
|
const decodeEvents =
|
|
184
|
-
<RS>(schemas: ReadonlyMap<string, Schema.
|
|
178
|
+
<RS>(schemas: ReadonlyMap<string, Schema.Decoder<unknown, RS>>) =>
|
|
185
179
|
<E, R>(
|
|
186
180
|
events: Stream.Stream<SequencedEvent, E, R>,
|
|
187
181
|
): Stream.Stream<DecodedEvent, E | CodecError, R | RS | Serializer> =>
|