@kairos-es/codec 1.0.0-alpha.0 → 1.0.0-alpha.2
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 +75 -3
- package/dist/cjs/decider.js +44 -69
- package/dist/cjs/decider.js.map +1 -1
- package/dist/cjs/decision.js +45 -0
- package/dist/cjs/decision.js.map +1 -0
- package/dist/cjs/decisionModel.js +76 -20
- package/dist/cjs/decisionModel.js.map +1 -1
- package/dist/cjs/index.js +63 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/precondition.js +191 -0
- package/dist/cjs/precondition.js.map +1 -0
- package/dist/cjs/readLedger.js +224 -0
- package/dist/cjs/readLedger.js.map +1 -0
- package/dist/dts/decider.d.ts +57 -8
- package/dist/dts/decider.d.ts.map +1 -1
- package/dist/dts/decision.d.ts +161 -0
- package/dist/dts/decision.d.ts.map +1 -0
- package/dist/dts/decisionModel.d.ts +33 -13
- package/dist/dts/decisionModel.d.ts.map +1 -1
- package/dist/dts/index.d.ts +69 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/precondition.d.ts +244 -0
- package/dist/dts/precondition.d.ts.map +1 -0
- package/dist/dts/readLedger.d.ts +263 -0
- package/dist/dts/readLedger.d.ts.map +1 -0
- package/dist/esm/decider.js +42 -67
- package/dist/esm/decider.js.map +1 -1
- package/dist/esm/decision.js +37 -0
- package/dist/esm/decision.js.map +1 -0
- package/dist/esm/decisionModel.js +77 -21
- package/dist/esm/decisionModel.js.map +1 -1
- package/dist/esm/index.js +69 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/precondition.js +182 -0
- package/dist/esm/precondition.js.map +1 -0
- package/dist/esm/readLedger.js +212 -0
- package/dist/esm/readLedger.js.map +1 -0
- package/package.json +2 -2
- package/src/decider.ts +98 -19
- package/src/decision.ts +174 -0
- package/src/decisionModel.ts +87 -23
- package/src/index.ts +87 -0
- package/src/precondition.ts +371 -0
- package/src/readLedger.ts +394 -0
package/dist/esm/index.js
CHANGED
|
@@ -34,6 +34,72 @@
|
|
|
34
34
|
* error union are written once, in the two function bodies, rather than restated
|
|
35
35
|
* as an annotation above them.
|
|
36
36
|
*
|
|
37
|
+
* A decision may also answer `Unchanged` — "already done, nothing to append" —
|
|
38
|
+
* built with `Decision.unchanged(reason?)` and recognised ONLY by
|
|
39
|
+
* `isUnchanged`, by its `UnchangedTypeId`. It is a success, not an error and not
|
|
40
|
+
* an empty batch: every runner returns it in place of a `Position` and appends
|
|
41
|
+
* nothing. `Decider`'s fifth type parameter carries the widening and defaults to
|
|
42
|
+
* the non-empty batch, and each runner's result is `DecisionResult<O>`, so a
|
|
43
|
+
* decider or body that cannot answer `Unchanged` keeps a plain `Position` — an
|
|
44
|
+
* untyped one and one generic in its success type included — and its caller is
|
|
45
|
+
* never asked to handle it. `decision.ts` owns the argument, and the one type
|
|
46
|
+
* query that does read differently.
|
|
47
|
+
*
|
|
48
|
+
* `transact(precondition)(body)` is the layered write path, for a decision whose
|
|
49
|
+
* second query cannot be written until an earlier read has been folded. It opens
|
|
50
|
+
* an ambient read ledger, evaluates the precondition inside it, hands that
|
|
51
|
+
* precondition's output to the body as a service, and appends what the body
|
|
52
|
+
* returned under the union of every query either of them read, at the earliest
|
|
53
|
+
* head observed. No condition reaches the caller. `unsafeAppend(events, reason)`
|
|
54
|
+
* is the one sanctioned way out. `precondition.ts` owns the argument for the
|
|
55
|
+
* bracket and everything on it, and `readLedger.ts` for the ledger the seam rests
|
|
56
|
+
* on — including why the derivation itself is deliberately not on this surface.
|
|
57
|
+
*
|
|
58
|
+
* ## ⚠ `runDecider` and `decideOnly` are TWO DISPOSITIONS OF ONE CYCLE
|
|
59
|
+
*
|
|
60
|
+
* They are read as a pair or not at all, because each refuses exactly where the
|
|
61
|
+
* other is the answer:
|
|
62
|
+
*
|
|
63
|
+
* | | outside a bracket | inside a bracket |
|
|
64
|
+
* | ------------ | ---------------------------------------- | ----------------------------------- |
|
|
65
|
+
* | `runDecider` | ✅ the ordinary single-hop case | ⛔ a DEFECT, refused at the store |
|
|
66
|
+
* | `decideOnly` | ⛔ unrunnable, and `tsc` says so | ✅ the layered case |
|
|
67
|
+
*
|
|
68
|
+
* Both carry `Unchanged` the same way, which is what keeps them one pair:
|
|
69
|
+
* `runDecider` returns it having appended nothing, and `decideOnly` passes it to
|
|
70
|
+
* the body unaltered, where `transact` returns it having appended nothing —
|
|
71
|
+
* and, having no write to guard, without refusing an empty bracket as
|
|
72
|
+
* `NoReadsRecorded`.
|
|
73
|
+
*
|
|
74
|
+
* ⚠ *Unrunnable* rather than *unwritable*, and the difference is measured. A bare
|
|
75
|
+
* `decideOnly(d, cmd)` outside a bracket COMPILES, and so does an exported helper
|
|
76
|
+
* over it: its `ReadLedger` requirement simply propagates, as any unmet requirement
|
|
77
|
+
* does. The refusal lands where the context is DISCHARGED — an `Effect.provide`, a
|
|
78
|
+
* `runPromise`, an annotation asking for `R = never` — which may be another file.
|
|
79
|
+
* So `pnpm check` catches it without anything running, which is the whole gain over
|
|
80
|
+
* the runtime defect this replaced; what it does not do is underline the call.
|
|
81
|
+
*
|
|
82
|
+
* Neither is expressed over the other, and that is forced rather than chosen: a
|
|
83
|
+
* definition of `runDecider` as *"`decideOnly`, then append"* would have to call
|
|
84
|
+
* `decideOnly` outside a bracket, which does not typecheck, and the append it then
|
|
85
|
+
* made inside one would be refused. The two refusals are the same fact seen from
|
|
86
|
+
* either side — an append inside a bracket belongs to the bracket — so any
|
|
87
|
+
* expression of one over the other has to defeat one of them.
|
|
88
|
+
*
|
|
89
|
+
* ⚠ The two refusals arrive at DIFFERENT MOMENTS, which is the part a caller acts
|
|
90
|
+
* on. `runDecider` inside a bracket is refused when it RUNS, at core's shared append
|
|
91
|
+
* decorator — so the same refusal also meets a raw `store.append` and a runner one
|
|
92
|
+
* call away in a helper. `decideOnly` outside a bracket is refused by `tsc`, at the
|
|
93
|
+
* discharge point above, by naming `ReadLedger` in its requirement channel. Why each
|
|
94
|
+
* was given the instrument it was is a DECISION and belongs to the record that took
|
|
95
|
+
* it: ADR-0014's `Status`. A lint rule reaches the first case earlier still, while it
|
|
96
|
+
* is being written; `biome-plugins/README.md` in the source repository owns what a
|
|
97
|
+
* rule there can and cannot see.
|
|
98
|
+
*
|
|
99
|
+
* The remedy is one identifier away in each direction, which is the whole reason a
|
|
100
|
+
* refusal is affordable at all. `decider.ts` and `precondition.ts` carry the two
|
|
101
|
+
* halves.
|
|
102
|
+
*
|
|
37
103
|
* `modelAtHead(slices)` is that same read-decode-fold WITHOUT the
|
|
38
104
|
* `AppendCondition`: `{ state, head }`, one slice record materialised at read
|
|
39
105
|
* time with no table, no checkpoint and no runner, current as of the `head` its
|
|
@@ -51,11 +117,14 @@
|
|
|
51
117
|
* record other than the one the query came from (see `decode.ts`).
|
|
52
118
|
*/
|
|
53
119
|
export { decider, runDecider } from "./decider.js";
|
|
120
|
+
export { Decision, isUnchanged, Unchanged, UnchangedTypeId } from "./decision.js";
|
|
54
121
|
export { buildDecisionModel, modelAtHead } from "./decisionModel.js";
|
|
55
122
|
export { decodeSlices } from "./decode.js";
|
|
56
123
|
export { CodecError, UnknownEventType } from "./errors.js";
|
|
57
124
|
export { event } from "./event.js";
|
|
125
|
+
export { decideOnly, transact, unsafeAppend } from "./precondition.js";
|
|
58
126
|
export { projection } from "./projection.js";
|
|
127
|
+
export { NoReadsRecorded, ReadLedger, TaglessSliceInLedger } from "./readLedger.js";
|
|
59
128
|
export { makeRegistry } from "./registry.js";
|
|
60
129
|
export { Serializer, SerializerDefault } from "./Serializer.js";
|
|
61
130
|
export { toEvent } from "./toEvent.js";
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["decider","runDecider","buildDecisionModel","modelAtHead","decodeSlices","CodecError","UnknownEventType","event","projection","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","decideOnly","transact","unsafeAppend","projection","NoReadsRecorded","ReadLedger","TaglessSliceInLedger","makeRegistry","Serializer","SerializerDefault","toEvent","Uuid","UuidLive","UuidTest"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuHA,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,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":[]}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { AppendIsOwned, DcbEventStore } from '@kairos-es/core';
|
|
2
|
+
import { Context, Effect, Layer } from 'effect';
|
|
3
|
+
import { isUnchanged } from "./decision.js";
|
|
4
|
+
import { modelAtHead } from "./decisionModel.js";
|
|
5
|
+
import { deriveLayeredCondition, makeReadLedger, NoReadsRecorded, ReadLedger } from "./readLedger.js";
|
|
6
|
+
/**
|
|
7
|
+
* The DCB command cycle MINUS the append: read the decision model, decode, fold,
|
|
8
|
+
* decide, and RETURN the events for the bracket to append — or the decider's
|
|
9
|
+
* `Unchanged`, passed through as it came, for the bracket to append nothing.
|
|
10
|
+
*
|
|
11
|
+
* Bracket-only, and the refusal is STATIC — see the section below for the mechanism
|
|
12
|
+
* and, more importantly, for where the error actually lands, which is not where a
|
|
13
|
+
* reader first expects. Forced through anyway, being outside a bracket is a DEFECT
|
|
14
|
+
* rather than an error-channel value: it is not a data-dependent outcome a caller
|
|
15
|
+
* could handle, and the events produced would be dropped with nothing to append them.
|
|
16
|
+
*
|
|
17
|
+
* It is also what makes the nesting refusal liveable. A command runner inside a
|
|
18
|
+
* bracket is refused at the store, and this is the function a builder reaches for
|
|
19
|
+
* instead — one identifier away. A refusal is only affordable when the fix is that
|
|
20
|
+
* close.
|
|
21
|
+
*
|
|
22
|
+
* `modelAtHead` and NOT `buildDecisionModel`: this function must not derive a
|
|
23
|
+
* condition at all. The bracket owns that, and owning it in ONE place is what
|
|
24
|
+
* stops a caller appending under the last hop's condition alone.
|
|
25
|
+
*
|
|
26
|
+
* ## Bracket-only is a REQUIREMENT, so `tsc` refuses it rather than a run
|
|
27
|
+
*
|
|
28
|
+
* `ReadLedger` is named in the requirement channel and `transact` is the only thing
|
|
29
|
+
* that provides it, so a program that calls this outside a bracket cannot be RUN,
|
|
30
|
+
* and `tsc` is what says so — nothing has to execute for a caller to be told.
|
|
31
|
+
*
|
|
32
|
+
* ⚠ Measured, because the obvious stronger reading is wrong: the call site itself
|
|
33
|
+
* COMPILES. A bare `decideOnly(d, cmd)` outside a bracket is fine, and so is an
|
|
34
|
+
* exported helper over it; the requirement just propagates, as any unmet requirement
|
|
35
|
+
* does. What fails is the DISCHARGE — `Effect.provide`, `runPromise`, an annotation
|
|
36
|
+
* asking for `R = never` — possibly in another file. That is still a static refusal
|
|
37
|
+
* and it is the whole gain over the runtime defect this replaced. It is not a
|
|
38
|
+
* squiggle under the mistake.
|
|
39
|
+
*
|
|
40
|
+
* That is a PRESENCE check, and presence is the direction the type system can
|
|
41
|
+
* decide here — the same direction `transact`'s `Exclude<R, Id>` already spends on
|
|
42
|
+
* the precondition's output. ADR-0014's 2026-08-29 amendment carries the rule that
|
|
43
|
+
* follows: look for a presence check before reaching for a defect. This function
|
|
44
|
+
* shipped a defect first, and the check was available all along.
|
|
45
|
+
*
|
|
46
|
+
* ⚠ Two lines carry it and their JOBS differ. The RETURN ANNOTATION is the surface a
|
|
47
|
+
* consumer is judged against, and what the discharge above meets. The
|
|
48
|
+
* `yield* ReadLedger` keeps the requirement in the INFERRED type, so it survives the
|
|
49
|
+
* annotation being edited, and it dies at run time for the audience no type reaches
|
|
50
|
+
* — a JavaScript consumer runs no compile step — rather than handing back events
|
|
51
|
+
* with no bracket to append them. Nothing here READS the ledger; `modelAtHead` does
|
|
52
|
+
* the recording, ambiently, through `Effect.serviceOption`.
|
|
53
|
+
*
|
|
54
|
+
* ⚠ Do not try to write down which check catches which deletion. It was tried twice
|
|
55
|
+
* and was wrong twice, and `test/appendOwnership.test.ts` in the source repository
|
|
56
|
+
* says why the second failure means there should be no third attempt. Plant the
|
|
57
|
+
* mutation instead.
|
|
58
|
+
*/
|
|
59
|
+
export const decideOnly = (decider, command) => Effect.gen(function* () {
|
|
60
|
+
yield* ReadLedger;
|
|
61
|
+
const {
|
|
62
|
+
state
|
|
63
|
+
} = yield* modelAtHead(decider.projections(command));
|
|
64
|
+
return yield* decider.decide(state, command);
|
|
65
|
+
});
|
|
66
|
+
/**
|
|
67
|
+
* The sanctioned exception to the nesting refusal: append these events under NO
|
|
68
|
+
* condition, and say in the identifier and in a required `reason` why that is
|
|
69
|
+
* deliberate.
|
|
70
|
+
*
|
|
71
|
+
* It covers three cases and no others: deliberate narrowing, a genuinely
|
|
72
|
+
* unconditional creation, and a second append inside one bracket. The `reason` is
|
|
73
|
+
* ceremony on purpose, and ADR-0014 decision 6 owns why a hatch has to cost more
|
|
74
|
+
* than the safe path — that argument is a DECISION and belongs to the record that
|
|
75
|
+
* took it, so it is not restated here. How biome turns a required argument into a
|
|
76
|
+
* review signal is the source repository's `biome-plugins/unsafeAppendReported.grit`.
|
|
77
|
+
*
|
|
78
|
+
* ⚠ It BYPASSES the derived condition rather than composing with it. A caller who
|
|
79
|
+
* genuinely needs *the union, minus one event type* must restate the whole
|
|
80
|
+
* condition here. If that turns up in practice, a composing override is the
|
|
81
|
+
* additive answer and this hatch is not it.
|
|
82
|
+
*
|
|
83
|
+
* `Effect.mapInputContext` over
|
|
84
|
+
* `Context.omit(AppendIsOwned)` is what lets it through the store's ownership
|
|
85
|
+
* refusal — the one route, and `AppendIsOwned.ts` owns why removing the marker is
|
|
86
|
+
* the shape rather than a second tag or a sanctioning flag.
|
|
87
|
+
*/
|
|
88
|
+
export const unsafeAppend = (events,
|
|
89
|
+
// Required by the signature and never read, which IS the mechanism: the value a
|
|
90
|
+
// caller has to write is what a reviewer sees in the diff, and `tsc` refuses the
|
|
91
|
+
// call that omits it. A lint rule asserting the same arity existed and was
|
|
92
|
+
// deleted, on the ground that the type already refuses it — which made that
|
|
93
|
+
// ground load-bearing, so `test/appendOwnership.test.ts` in the source repository
|
|
94
|
+
// pins it. Reading the value here would give it a second job and a second place to
|
|
95
|
+
// be wrong.
|
|
96
|
+
//
|
|
97
|
+
// NOT `_reason`, though it is unused. This name SHIPS — it is what a consumer's
|
|
98
|
+
// editor offers and what the published `.d.ts` carries — and a leading underscore
|
|
99
|
+
// is this ecosystem's way of saying "ignore me", which is the opposite of what a
|
|
100
|
+
// required argument whose whole purpose is to be read by a human should say.
|
|
101
|
+
// biome-ignore lint/correctness/noUnusedFunctionParameters: unread on purpose; this name ships in the .d.ts and an underscore would tell a consumer to ignore it
|
|
102
|
+
reason) => Effect.flatMap(DcbEventStore, store =>
|
|
103
|
+
// ⛔ DO NOT SIMPLIFY THIS. The annotation reads as "map an empty context to an
|
|
104
|
+
// empty context", and the types say nothing else — but `Context.omit` runs
|
|
105
|
+
// against the RUNTIME context, which inside a bracket holds `AppendIsOwned`,
|
|
106
|
+
// and removing it is the entire reason this function can append at all. That
|
|
107
|
+
// marker is deliberately absent from every signature (it is read through
|
|
108
|
+
// `Effect.serviceOption`, which is what keeps it out of `append`'s requirement
|
|
109
|
+
// channel), so nothing here will fail to compile if this is deleted — what
|
|
110
|
+
// catches it is `test/appendOwnership.test.ts` in the source repository, not the
|
|
111
|
+
// type checker.
|
|
112
|
+
Effect.mapInputContext(store.append(events), context => Context.omit(AppendIsOwned)(context)));
|
|
113
|
+
/**
|
|
114
|
+
* Open a bracket over ONE decision: evaluate the precondition inside it, hand its
|
|
115
|
+
* output to the body under the precondition's tag, and append what the body
|
|
116
|
+
* produced under the union of every read either of them performed.
|
|
117
|
+
*
|
|
118
|
+
* Curried so the precondition reads as the thing the command DECLARES and the body
|
|
119
|
+
* reads as the thing it DOES.
|
|
120
|
+
*
|
|
121
|
+
* The ownership marker is provided ALONGSIDE the ledger and to the body only, so
|
|
122
|
+
* any append inside the body — a nested bracket, a command runner, a raw
|
|
123
|
+
* `store.append` — is refused at the store as a defect, while the bracket's own
|
|
124
|
+
* closing append below runs outside that scope and is unaffected. That is why the
|
|
125
|
+
* refusal is on APPENDING rather than on opening a bracket: a command runner
|
|
126
|
+
* appends without opening one, and its events usually match the union the bracket
|
|
127
|
+
* is about to guard on, so the bracket's own close would be refused by a condition
|
|
128
|
+
* its own body invalidated.
|
|
129
|
+
*
|
|
130
|
+
* The body may succeed with `Unchanged` (see the module documentation), and the
|
|
131
|
+
* result is then `DecisionResult<O>`: `Position` for a body that cannot answer
|
|
132
|
+
* it, `Position | Unchanged` for one that can. `O` is last and defaulted, so an
|
|
133
|
+
* explicit `<E, R>` written against the narrower signature still means what it
|
|
134
|
+
* did.
|
|
135
|
+
*/
|
|
136
|
+
export const transact = precondition => body => Effect.gen(function* () {
|
|
137
|
+
const store = yield* DcbEventStore;
|
|
138
|
+
const ledger = yield* makeReadLedger;
|
|
139
|
+
const output = yield* Effect.gen(function* () {
|
|
140
|
+
// ORDER IS THE DESIGN. The precondition runs first and runs HERE, with the
|
|
141
|
+
// ledger already in context, so its reads are hops in the very condition
|
|
142
|
+
// that will guard the body's write.
|
|
143
|
+
const proof = yield* precondition.evaluate;
|
|
144
|
+
return yield* body.pipe(Effect.provideService(precondition.tag, proof));
|
|
145
|
+
}).pipe(
|
|
146
|
+
// ONE layer, not two provisions, and it is the ANNOTATION above that makes
|
|
147
|
+
// that mandatory rather than tidy.
|
|
148
|
+
//
|
|
149
|
+
// TypeScript does not simplify a deferred conditional over an unresolved
|
|
150
|
+
// type variable, so `Exclude<Exclude<X, A>, B>` and
|
|
151
|
+
// `Exclude<X, A | B>` are unrelated types while `X` is still a parameter,
|
|
152
|
+
// and every provision here adds one level of nesting the annotation has to
|
|
153
|
+
// mirror EXACTLY. Both halves measured, each as a `TS2719` at the return
|
|
154
|
+
// annotation: two chained provisions refuse the flat
|
|
155
|
+
// `Exclude<PR, ReadLedger | AppendIsOwned>`, and even with this merge the
|
|
156
|
+
// flat `Exclude<R, Id | ReadLedger | AppendIsOwned>` is refused too,
|
|
157
|
+
// because the precondition's own tag is provided separately and further in.
|
|
158
|
+
// So `PR` is flat and `R` is one deep, and that asymmetry is the pipeline
|
|
159
|
+
// showing through rather than a slip.
|
|
160
|
+
//
|
|
161
|
+
// Merging says what is true anyway, which is why it is the fix rather than
|
|
162
|
+
// a cast: the ledger and the ownership marker have one lifetime and one
|
|
163
|
+
// meaning between them, and that meaning is *you are inside a bracket*.
|
|
164
|
+
Effect.provide(Layer.merge(ledger.layer, Layer.succeed(AppendIsOwned, {
|
|
165
|
+
by: 'transact'
|
|
166
|
+
}))));
|
|
167
|
+
// "Already done": nothing to append, so no condition to derive and nothing
|
|
168
|
+
// for `NoReadsRecorded` to protect — that refusal guards a WRITE that would
|
|
169
|
+
// go out unguarded, and there is none. It must stay BEFORE the derivation,
|
|
170
|
+
// or an empty bracket answering `Unchanged` would be refused for a write it
|
|
171
|
+
// never asked for. The casts restate `DecisionResult<O>`, which the checker
|
|
172
|
+
// cannot relate to either branch while `O` is still a type variable.
|
|
173
|
+
if (isUnchanged(output)) {
|
|
174
|
+
return output;
|
|
175
|
+
}
|
|
176
|
+
const condition = deriveLayeredCondition(yield* ledger.hops);
|
|
177
|
+
if (condition === undefined) {
|
|
178
|
+
return yield* new NoReadsRecorded();
|
|
179
|
+
}
|
|
180
|
+
return yield* store.append(output, condition);
|
|
181
|
+
});
|
|
182
|
+
//# sourceMappingURL=precondition.js.map
|
|
@@ -0,0 +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","mapInputContext","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,eAAe,CACpBD,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":[]}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { composeProjections, ORIGIN, servableQueryFault, unionQueries } from '@kairos-es/core';
|
|
2
|
+
import { Context, Data, Effect, Layer, Option, Ref } from 'effect';
|
|
3
|
+
/**
|
|
4
|
+
* The ambient ledger, present only inside a bracket.
|
|
5
|
+
*
|
|
6
|
+
* ⚠ A RECORDING path reads it with `Effect.serviceOption` and never
|
|
7
|
+
* `yield* ReadLedger`: its absence is the normal case there, and costing the
|
|
8
|
+
* requirement channel nothing is exactly what makes this change additive.
|
|
9
|
+
* `modelAtHead` is that path and is why the rule exists.
|
|
10
|
+
*
|
|
11
|
+
* A BRACKET-ONLY function is the opposite case and yields the tag deliberately.
|
|
12
|
+
* `decideOnly` does, and naming the requirement is what turns *"call me inside a
|
|
13
|
+
* bracket"* from a runtime defect into a compile error — presence being the one
|
|
14
|
+
* direction the type system can decide here. So the test is what the function
|
|
15
|
+
* means outside a bracket: nothing (record ambiently), or nothing sensible
|
|
16
|
+
* (require it).
|
|
17
|
+
*
|
|
18
|
+
* Recording is two-phase, and `record`'s own doc below owns why and what shape the
|
|
19
|
+
* second phase takes.
|
|
20
|
+
*/
|
|
21
|
+
export class ReadLedger extends /*#__PURE__*/Context.Tag('@kairos-es/codec/ReadLedger')() {}
|
|
22
|
+
/**
|
|
23
|
+
* Raised when a bracket closes having recorded no read at all.
|
|
24
|
+
*
|
|
25
|
+
* On the ERROR channel and deliberately split from the nested-append DEFECT,
|
|
26
|
+
* because the two are different mistakes. An empty bracket can arise from a
|
|
27
|
+
* data-dependent branch that produces events without reading — a genuinely
|
|
28
|
+
* unconditional creation, written inside a bracket by mistake — where a nested
|
|
29
|
+
* append is always a wiring fault. An error-channel value lets a caller decide
|
|
30
|
+
* which it is.
|
|
31
|
+
*
|
|
32
|
+
* Its job is narrower than it looks, and the narrowing is worth stating because
|
|
33
|
+
* the wider reading is the tempting one. Once a bracket's guard is itself a fold,
|
|
34
|
+
* a body that reads nothing still has a hop, so this cannot fire — it is the guard
|
|
35
|
+
* against an unguarded UNCONDITIONAL bracket, not against an unguarded bracket. A
|
|
36
|
+
* bracket that looks guarded and is not is NOT what this catches and never was,
|
|
37
|
+
* and nothing else catches it either — `precondition.ts` owns that gap and the
|
|
38
|
+
* rule a reader has to keep in its place. A refusal taken BEFORE reading is not
|
|
39
|
+
* this case either: it short-circuits and surfaces as the refusal.
|
|
40
|
+
*/
|
|
41
|
+
export class NoReadsRecorded extends /*#__PURE__*/Data.TaggedError('NoReadsRecorded') {
|
|
42
|
+
/**
|
|
43
|
+
* The sentence, as the `Error` field that says why — so the fault renders
|
|
44
|
+
* ITSELF, exactly as this package's other two errors do (`errors.ts` owns the
|
|
45
|
+
* argument for the mechanism and it is not restated here).
|
|
46
|
+
*
|
|
47
|
+
* A getter over a constant rather than a constructor field, because there is no
|
|
48
|
+
* datum to vary: every raise of this error means one thing.
|
|
49
|
+
*/
|
|
50
|
+
get message() {
|
|
51
|
+
return 'the bracket closed having recorded no read, so there is no append condition ' + 'to derive. A decision that reads nothing is unconditional — say so with the ' + 'escape hatch, which takes a reason, rather than by opening a bracket.';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Raised when recording a hop would leave the bracket's accumulated union
|
|
56
|
+
* unservable.
|
|
57
|
+
*
|
|
58
|
+
* The store refuses a multi-item query in which any item is tagless, and it
|
|
59
|
+
* refuses it by THROWING inside the append decorator, which becomes a defect:
|
|
60
|
+
* uncatchable, one call and one layer away from the `build()` that chose no tags.
|
|
61
|
+
* A slice built without tags defaults to none, so it is perfectly servable alone
|
|
62
|
+
* and kills the append the moment it is unioned. This moves that failure onto the
|
|
63
|
+
* error channel, to the read that caused it, naming the record entry to fix.
|
|
64
|
+
*
|
|
65
|
+
* It refuses an unservable UNION and not every tagless hop, which is the easy
|
|
66
|
+
* mistake to make in the other direction: one tagless slice read on its own is
|
|
67
|
+
* servable and must keep working. Two cases reach it — a tagless hop unioned with
|
|
68
|
+
* another, and a single hop whose own RECORD holds two tagless slices, which
|
|
69
|
+
* composes to a multi-item query with no second hop needed.
|
|
70
|
+
*/
|
|
71
|
+
export class TaglessSliceInLedger extends /*#__PURE__*/Data.TaggedError('TaglessSliceInLedger') {
|
|
72
|
+
/** The offending slice and the remedy, in one sentence. */
|
|
73
|
+
get message() {
|
|
74
|
+
return `slice '${this.sliceKey}' was built with no tags, and this bracket now reads ` + 'more than one slice. A layered append condition unions every query it ' + 'recorded, and the store refuses a multi-item query if any item is tagless. ' + 'Pass `build({ tags: [...] })` for this slice.';
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The ONE derivation: the union of every query walked, at the earliest head
|
|
79
|
+
* observed. Package-internal, for the reason the module doc gives.
|
|
80
|
+
*
|
|
81
|
+
* The union goes through core's own `unionQueries` — the merge
|
|
82
|
+
* `composeProjections` folds a record through, reached without one — and never a
|
|
83
|
+
* spread of `items`, because a wildcard hop (`items: []`) is ABSORBING under OR
|
|
84
|
+
* while a spread of an empty list contributes nothing, so hand-rolling the union
|
|
85
|
+
* narrows a match-everything hop to its sibling, silently and in the unsafe
|
|
86
|
+
* direction. A
|
|
87
|
+
* repeated or overlapping hop is harmless because this derives ONCE from a merged
|
|
88
|
+
* set and matching is idempotent over an OR; that property belongs to deriving
|
|
89
|
+
* once and would be lost by a refactor to per-hop evaluation.
|
|
90
|
+
*
|
|
91
|
+
* ## When any hop is headless the floor is `ORIGIN`, and the alternative is unsound
|
|
92
|
+
*
|
|
93
|
+
* The earliest head that actually ARRIVED is refused, and is named here as refused
|
|
94
|
+
* rather than merely not chosen, because it is what a reader writes by accident
|
|
95
|
+
* when told to take the earliest head. With one headless hop among completed hops
|
|
96
|
+
* the union looks right and the floor betrays it, sitting already above the
|
|
97
|
+
* invalidating event.
|
|
98
|
+
*
|
|
99
|
+
* `ORIGIN`'s cost is measured rather than described: it refuses every append to
|
|
100
|
+
* any identity that already has history, so it is not a conservative default but a
|
|
101
|
+
* hard stop. It is affordable only because conflict retry wraps the bracket from
|
|
102
|
+
* OUTSIDE and re-reads, which is the rule the whole shape depends on.
|
|
103
|
+
*/
|
|
104
|
+
export const deriveLayeredCondition = hops => {
|
|
105
|
+
if (hops.length === 0) {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
const merged = unionQueries(hops.map(hop => hop.query));
|
|
109
|
+
const arrived = hops.flatMap(hop => hop.head === undefined ? [] : [hop.head]);
|
|
110
|
+
// A headless hop widens the guard to the whole log. Unioning its query is the
|
|
111
|
+
// half that is not in dispute; the floor is where the two readings diverge.
|
|
112
|
+
const after = arrived.length === hops.length ? arrived.reduce((a, b) => b < a ? b : a) : ORIGIN;
|
|
113
|
+
return {
|
|
114
|
+
failIfEventsMatch: merged,
|
|
115
|
+
after
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* A fresh ledger and the `Layer` providing it: a `Ref` of hops behind the two-phase
|
|
120
|
+
* `record` the service declares.
|
|
121
|
+
*
|
|
122
|
+
* The hops effect is handed back beside the layer because the bracket reads them
|
|
123
|
+
* AFTER the body has run and the layer is out of scope, which is the same moment it
|
|
124
|
+
* stops being able to reach the service.
|
|
125
|
+
*/
|
|
126
|
+
export const makeReadLedger = /*#__PURE__*/Effect.gen(function* () {
|
|
127
|
+
const ref = yield* Ref.make([]);
|
|
128
|
+
return {
|
|
129
|
+
layer: Layer.succeed(ReadLedger, {
|
|
130
|
+
record: query => Ref.modify(ref, hops => [
|
|
131
|
+
// The close effect closes over the slot this hop just took, so the slot
|
|
132
|
+
// never becomes a value anything else has to carry or interpret.
|
|
133
|
+
head => Ref.update(ref, current => current.map((hop, index) => index === hops.length ? {
|
|
134
|
+
query: hop.query,
|
|
135
|
+
head
|
|
136
|
+
} : hop)), [...hops, {
|
|
137
|
+
query
|
|
138
|
+
}]]),
|
|
139
|
+
hops: Ref.get(ref)
|
|
140
|
+
}),
|
|
141
|
+
// The same effect the service exposes, reachable AFTER the layer is out of
|
|
142
|
+
// scope — which is exactly when the bracket derives.
|
|
143
|
+
hops: Ref.get(ref)
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
/**
|
|
147
|
+
* Run `f` against the ambient ledger, or answer `absent` when there is none.
|
|
148
|
+
*
|
|
149
|
+
* "Outside a bracket this is a no-op" is ONE fact stated once, rather than one
|
|
150
|
+
* per consumer free to drift from the others. Every ambient lookup in this module
|
|
151
|
+
* goes through here, which is also what keeps `Effect.serviceOption` — the reason
|
|
152
|
+
* nothing enters the requirement channel — from being a detail each caller has to
|
|
153
|
+
* remember.
|
|
154
|
+
*/
|
|
155
|
+
const withLedger = (absent, f) => Effect.flatMap(Effect.serviceOption(ReadLedger), ledger => Option.isNone(ledger) ? Effect.succeed(absent) : f(ledger.value));
|
|
156
|
+
/** A close effect that does nothing: what a read outside a bracket gets back. */
|
|
157
|
+
const NO_CLOSE = () => Effect.void;
|
|
158
|
+
/**
|
|
159
|
+
* File a query into the ambient ledger if there is one, and hand back the effect
|
|
160
|
+
* that completes it. Outside a bracket the whole thing is a no-op, and the caller
|
|
161
|
+
* still writes one line rather than a conditional.
|
|
162
|
+
*/
|
|
163
|
+
export const recordQuery = query => withLedger(NO_CLOSE, ledger => ledger.record(query));
|
|
164
|
+
/** The tagless slice keys in a record, in declaration order. */
|
|
165
|
+
const taglessKeys = projections => Object.entries(projections).filter(([, projection]) => projection.query.items.some(item => item.tags.length === 0)).map(([key]) => key);
|
|
166
|
+
/** Would recording this record's query leave the accumulated union unservable? */
|
|
167
|
+
const unionWouldBeUnservable = (existing, incoming) => servableQueryFault(unionQueries([...existing.map(h => h.query), incoming])) !== undefined;
|
|
168
|
+
/**
|
|
169
|
+
* Refuse a read that would leave the bracket's accumulated union unservable,
|
|
170
|
+
* BEFORE the read is paid for.
|
|
171
|
+
*
|
|
172
|
+
* Servability is answerable from the queries alone, so the check runs when a hop is
|
|
173
|
+
* recorded rather than at append time — the eager half of the eager/lazy split doing
|
|
174
|
+
* one more job. Outside a bracket nothing is unioned and nothing is unservable, so
|
|
175
|
+
* the ordinary single-hop caller is untaxed.
|
|
176
|
+
*
|
|
177
|
+
* It judges the PROSPECTIVE UNION and asks core for the verdict, which is what makes
|
|
178
|
+
* both failing shapes one case rather than two. An earlier version tested each
|
|
179
|
+
* recorded query separately and treated a FIRST hop as unconditionally fine — but a
|
|
180
|
+
* hop is a RECORD, and a record of two tagless slices composes to a multi-item query
|
|
181
|
+
* that is unservable on its own. That read died at the store, uncatchably, on the
|
|
182
|
+
* exact path this error exists to keep off the defect channel. A grammar with two
|
|
183
|
+
* homes drifts at the shapes neither author had in mind, so there is one home and it
|
|
184
|
+
* is `servableQueryFault`'s.
|
|
185
|
+
*
|
|
186
|
+
* Where the OFFENDING slice is THIS record's the ledger can name its key; where it
|
|
187
|
+
* belongs to an earlier hop it can only say so, a recorded hop keeping its query
|
|
188
|
+
* rather than the key it was composed from. That asymmetry is diagnostic-only and is
|
|
189
|
+
* why the message is built from a key that may be a placeholder.
|
|
190
|
+
*/
|
|
191
|
+
export const assertServableAddition = projections => withLedger(undefined, ledger => Effect.flatMap(ledger.hops, existing => {
|
|
192
|
+
const incoming = composeProjections(projections).query;
|
|
193
|
+
if (!unionWouldBeUnservable(existing, incoming)) {
|
|
194
|
+
return Effect.void;
|
|
195
|
+
}
|
|
196
|
+
// The offending key where the tagless slice is THIS record's, and a
|
|
197
|
+
// placeholder where it belongs to an earlier hop — a recorded hop keeps its
|
|
198
|
+
// query rather than the key it was composed from.
|
|
199
|
+
const offending = taglessKeys(projections)[0] ?? '<an earlier hop>';
|
|
200
|
+
return new TaglessSliceInLedger({
|
|
201
|
+
sliceKey: offending
|
|
202
|
+
});
|
|
203
|
+
}));
|
|
204
|
+
/**
|
|
205
|
+
* The condition the ambient ledger derives right now, or `None` outside a bracket.
|
|
206
|
+
*
|
|
207
|
+
* This is what makes `buildDecisionModel` correct inside a bracket: the call whose
|
|
208
|
+
* current behaviour is the hazard derives from every hop the bracket walked rather
|
|
209
|
+
* than from its own single read.
|
|
210
|
+
*/
|
|
211
|
+
export const ambientLayeredCondition = /*#__PURE__*/withLedger(/*#__PURE__*/Option.none(), ledger => Effect.map(ledger.hops, hops => Option.fromNullable(deriveLayeredCondition(hops))));
|
|
212
|
+
//# sourceMappingURL=readLedger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readLedger.js","names":["composeProjections","ORIGIN","servableQueryFault","unionQueries","Context","Data","Effect","Layer","Option","Ref","ReadLedger","Tag","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","h","assertServableAddition","offending","ambientLayeredCondition","none","fromNullable"],"sources":["../../src/readLedger.ts"],"sourcesContent":[null],"mappings":"AAsEA,SACEA,kBAAkB,EAClBC,MAAM,EACNC,kBAAkB,EAClBC,YAAY,QACP,iBAAiB;AACxB,SAASC,OAAO,EAAEC,IAAI,EAAEC,MAAM,EAAEC,KAAK,EAAEC,MAAM,EAAEC,GAAG,QAAQ,QAAQ;AAelE;;;;;;;;;;;;;;;;;;AAkBA,OAAM,MAAOC,UAAW,sBAAQN,OAAO,CAACO,GAAG,CAAC,6BAA6B,CAAC,EAmBvE;AAYH;;;;;;;;;;;;;;;;;;;AAmBA,OAAM,MAAOC,eAAgB,sBAAQP,IAAI,CAACQ,WAAW,CAAC,iBAAiB,CAEtE;EACC;;;;;;;;EAQA,IAAaC,OAAOA,CAAA;IAClB,OACE,8EAA8E,GAC9E,8EAA8E,GAC9E,uEAAuE;EAE3E;;AAGF;;;;;;;;;;;;;;;;;AAiBA,OAAM,MAAOC,oBAAqB,sBAAQV,IAAI,CAACQ,WAAW,CACxD,sBAAsB,CACQ;EAC9B;EACA,IAAaC,OAAOA,CAAA;IAClB,OACE,UAAU,IAAI,CAACE,QAAQ,uDAAuD,GAC9E,wEAAwE,GACxE,6EAA6E,GAC7E,+CAA+C;EAEnD;;AAGF;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,OAAO,MAAMC,sBAAsB,GACjCC,IAAwB,IACO;EAC/B,IAAIA,IAAI,CAACC,MAAM,KAAK,CAAC,EAAE;IACrB,OAAOC,SAAS;EAClB;EACA,MAAMC,MAAM,GAAGlB,YAAY,CAACe,IAAI,CAACI,GAAG,CAAEC,GAAG,IAAKA,GAAG,CAACC,KAAK,CAAC,CAAC;EAEzD,MAAMC,OAAO,GAAGP,IAAI,CAACQ,OAAO,CAAEH,GAAG,IAC/BA,GAAG,CAACI,IAAI,KAAKP,SAAS,GAAG,EAAE,GAAG,CAACG,GAAG,CAACI,IAAI,CAAC,CACzC;EACD;EACA;EACA,MAAMC,KAAK,GACTH,OAAO,CAACN,MAAM,KAAKD,IAAI,CAACC,MAAM,GAC1BM,OAAO,CAACI,MAAM,CAAC,CAACC,CAAC,EAAEC,CAAC,KAAMA,CAAC,GAAGD,CAAC,GAAGC,CAAC,GAAGD,CAAE,CAAC,GACzC7B,MAAM;EAEZ,OAAO;IAAE+B,iBAAiB,EAAEX,MAAM;IAAEO;EAAK,CAAE;AAC7C,CAAC;AAED;;;;;;;;AAQA,OAAO,MAAMK,cAAc,gBAGtB3B,MAAM,CAAC4B,GAAG,CAAC,aAAS;EACvB,MAAMC,GAAG,GAAG,OAAO1B,GAAG,CAAC2B,IAAI,CAAqB,EAAE,CAAC;EACnD,OAAO;IACLC,KAAK,EAAE9B,KAAK,CAAC+B,OAAO,CAAC5B,UAAU,EAAE;MAC/B6B,MAAM,EAAGf,KAAY,IACnBf,GAAG,CAAC+B,MAAM,CAACL,GAAG,EAAGjB,IAAI,IAAK;MACxB;MACA;MACCS,IAAc,IACblB,GAAG,CAACgC,MAAM,CAACN,GAAG,EAAGO,OAAO,IACtBA,OAAO,CAACpB,GAAG,CAAC,CAACC,GAAG,EAAEoB,KAAK,KACrBA,KAAK,KAAKzB,IAAI,CAACC,MAAM,GAAG;QAAEK,KAAK,EAAED,GAAG,CAACC,KAAK;QAAEG;MAAI,CAAE,GAAGJ,GAAG,CACzD,CACF,EACH,CAAC,GAAGL,IAAI,EAAE;QAAEM;MAAK,CAAE,CAAC,CACrB,CAAC;MACJN,IAAI,EAAET,GAAG,CAACmC,GAAG,CAACT,GAAG;KAClB,CAAC;IACF;IACA;IACAjB,IAAI,EAAET,GAAG,CAACmC,GAAG,CAACT,GAAG;GAClB;AACH,CAAC,CAAC;AAEF;;;;;;;;;AASA,MAAMU,UAAU,GAAGA,CACjBC,MAAS,EACTC,CAAmE,KAEnEzC,MAAM,CAACoB,OAAO,CAACpB,MAAM,CAAC0C,aAAa,CAACtC,UAAU,CAAC,EAAGuC,MAAM,IACtDzC,MAAM,CAAC0C,MAAM,CAACD,MAAM,CAAC,GAAG3C,MAAM,CAACgC,OAAO,CAACQ,MAAM,CAAC,GAAGC,CAAC,CAACE,MAAM,CAACE,KAAK,CAAC,CACjE;AAEH;AACA,MAAMC,QAAQ,GAAaA,CAAA,KAAM9C,MAAM,CAAC+C,IAAI;AAE5C;;;;;AAKA,OAAO,MAAMC,WAAW,GAAI9B,KAAY,IACtCqB,UAAU,CAACO,QAAQ,EAAGH,MAAM,IAAKA,MAAM,CAACV,MAAM,CAACf,KAAK,CAAC,CAAC;AAExD;AACA,MAAM+B,WAAW,GACfC,WAA0C,IAE1CC,MAAM,CAACC,OAAO,CAACF,WAAW,CAAC,CACxBG,MAAM,CAAC,CAAC,GAAGC,UAAU,CAAC,KACrBA,UAAU,CAACpC,KAAK,CAACqC,KAAK,CAACC,IAAI,CAAEC,IAAI,IAAKA,IAAI,CAACC,IAAI,CAAC7C,MAAM,KAAK,CAAC,CAAC,CAC9D,CACAG,GAAG,CAAC,CAAC,CAAC2C,GAAG,CAAC,KAAKA,GAAG,CAAC;AAExB;AACA,MAAMC,sBAAsB,GAAGA,CAC7BC,QAA4B,EAC5BC,QAAe,KAEflE,kBAAkB,CAChBC,YAAY,CAAC,CAAC,GAAGgE,QAAQ,CAAC7C,GAAG,CAAE+C,CAAC,IAAKA,CAAC,CAAC7C,KAAK,CAAC,EAAE4C,QAAQ,CAAC,CAAC,CAC1D,KAAKhD,SAAS;AAEjB;;;;;;;;;;;;;;;;;;;;;;;AAuBA,OAAO,MAAMkD,sBAAsB,GACjCd,WAA0C,IAE1CX,UAAU,CAA6BzB,SAAS,EAAG6B,MAAM,IACvD3C,MAAM,CAACoB,OAAO,CAACuB,MAAM,CAAC/B,IAAI,EAAGiD,QAAQ,IAAI;EACvC,MAAMC,QAAQ,GAAGpE,kBAAkB,CAACwD,WAAW,CAAC,CAAChC,KAAK;EACtD,IAAI,CAAC0C,sBAAsB,CAACC,QAAQ,EAAEC,QAAQ,CAAC,EAAE;IAC/C,OAAO9D,MAAM,CAAC+C,IAAI;EACpB;EACA;EACA;EACA;EACA,MAAMkB,SAAS,GAAGhB,WAAW,CAACC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,kBAAkB;EACnE,OAAO,IAAIzC,oBAAoB,CAAC;IAAEC,QAAQ,EAAEuD;EAAS,CAAE,CAAC;AAC1D,CAAC,CAAC,CACH;AAEH;;;;;;;AAOA,OAAO,MAAMC,uBAAuB,gBAEhC3B,UAAU,cAACrC,MAAM,CAACiE,IAAI,EAAmB,EAAGxB,MAAM,IACpD3C,MAAM,CAACgB,GAAG,CAAC2B,MAAM,CAAC/B,IAAI,EAAGA,IAAI,IAC3BV,MAAM,CAACkE,YAAY,CAACzD,sBAAsB,CAACC,IAAI,CAAC,CAAC,CAClD,CACF","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.2",
|
|
4
4
|
"description": "Schema-first codec with encryption seam for kairos-es",
|
|
5
5
|
"license": "BSD-3-Clause",
|
|
6
6
|
"repository": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"homepage": "https://github.com/neverbland/kairos-es",
|
|
13
13
|
"peerDependencies": {
|
|
14
14
|
"effect": "^3.22.0",
|
|
15
|
-
"@kairos-es/core": "^1.0.0-alpha.
|
|
15
|
+
"@kairos-es/core": "^1.0.0-alpha.2"
|
|
16
16
|
},
|
|
17
17
|
"main": "./dist/cjs/index.js",
|
|
18
18
|
"module": "./dist/esm/index.js",
|