@kairos-es/core 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +33 -0
  3. package/dist/cjs/AppendCondition.js +26 -0
  4. package/dist/cjs/AppendCondition.js.map +1 -0
  5. package/dist/cjs/ContractStore.js +80 -0
  6. package/dist/cjs/ContractStore.js.map +1 -0
  7. package/dist/cjs/DcbEventStore.js +10 -0
  8. package/dist/cjs/DcbEventStore.js.map +1 -0
  9. package/dist/cjs/Event.js +89 -0
  10. package/dist/cjs/Event.js.map +1 -0
  11. package/dist/cjs/Projection.js +73 -0
  12. package/dist/cjs/Projection.js.map +1 -0
  13. package/dist/cjs/Query.js +221 -0
  14. package/dist/cjs/Query.js.map +1 -0
  15. package/dist/cjs/SubscribeMachine.js +235 -0
  16. package/dist/cjs/SubscribeMachine.js.map +1 -0
  17. package/dist/cjs/errors.js +22 -0
  18. package/dist/cjs/errors.js.map +1 -0
  19. package/dist/cjs/inMemory.js +191 -0
  20. package/dist/cjs/inMemory.js.map +1 -0
  21. package/dist/cjs/index.js +124 -0
  22. package/dist/cjs/index.js.map +1 -0
  23. package/dist/cjs/retryOnConflict.js +95 -0
  24. package/dist/cjs/retryOnConflict.js.map +1 -0
  25. package/dist/cjs/testing.js +54 -0
  26. package/dist/cjs/testing.js.map +1 -0
  27. package/dist/dts/AppendCondition.d.ts +23 -0
  28. package/dist/dts/AppendCondition.d.ts.map +1 -0
  29. package/dist/dts/ContractStore.d.ts +56 -0
  30. package/dist/dts/ContractStore.d.ts.map +1 -0
  31. package/dist/dts/DcbEventStore.d.ts +64 -0
  32. package/dist/dts/DcbEventStore.d.ts.map +1 -0
  33. package/dist/dts/Event.d.ts +104 -0
  34. package/dist/dts/Event.d.ts.map +1 -0
  35. package/dist/dts/Projection.d.ts +108 -0
  36. package/dist/dts/Projection.d.ts.map +1 -0
  37. package/dist/dts/Query.d.ts +145 -0
  38. package/dist/dts/Query.d.ts.map +1 -0
  39. package/dist/dts/SubscribeMachine.d.ts +179 -0
  40. package/dist/dts/SubscribeMachine.d.ts.map +1 -0
  41. package/dist/dts/errors.d.ts +17 -0
  42. package/dist/dts/errors.d.ts.map +1 -0
  43. package/dist/dts/inMemory.d.ts +76 -0
  44. package/dist/dts/inMemory.d.ts.map +1 -0
  45. package/dist/dts/index.d.ts +35 -0
  46. package/dist/dts/index.d.ts.map +1 -0
  47. package/dist/dts/retryOnConflict.d.ts +70 -0
  48. package/dist/dts/retryOnConflict.d.ts.map +1 -0
  49. package/dist/dts/testing.d.ts +39 -0
  50. package/dist/dts/testing.d.ts.map +1 -0
  51. package/dist/esm/AppendCondition.js +19 -0
  52. package/dist/esm/AppendCondition.js.map +1 -0
  53. package/dist/esm/ContractStore.js +73 -0
  54. package/dist/esm/ContractStore.js.map +1 -0
  55. package/dist/esm/DcbEventStore.js +3 -0
  56. package/dist/esm/DcbEventStore.js.map +1 -0
  57. package/dist/esm/Event.js +81 -0
  58. package/dist/esm/Event.js.map +1 -0
  59. package/dist/esm/Projection.js +66 -0
  60. package/dist/esm/Projection.js.map +1 -0
  61. package/dist/esm/Query.js +209 -0
  62. package/dist/esm/Query.js.map +1 -0
  63. package/dist/esm/SubscribeMachine.js +227 -0
  64. package/dist/esm/SubscribeMachine.js.map +1 -0
  65. package/dist/esm/errors.js +14 -0
  66. package/dist/esm/errors.js.map +1 -0
  67. package/dist/esm/inMemory.js +184 -0
  68. package/dist/esm/inMemory.js.map +1 -0
  69. package/dist/esm/index.js +38 -0
  70. package/dist/esm/index.js.map +1 -0
  71. package/dist/esm/package.json +4 -0
  72. package/dist/esm/retryOnConflict.js +87 -0
  73. package/dist/esm/retryOnConflict.js.map +1 -0
  74. package/dist/esm/testing.js +46 -0
  75. package/dist/esm/testing.js.map +1 -0
  76. package/package.json +39 -0
  77. package/src/AppendCondition.ts +18 -0
  78. package/src/ContractStore.ts +148 -0
  79. package/src/DcbEventStore.ts +77 -0
  80. package/src/Event.ts +135 -0
  81. package/src/Projection.ts +168 -0
  82. package/src/Query.ts +237 -0
  83. package/src/SubscribeMachine.ts +316 -0
  84. package/src/errors.ts +19 -0
  85. package/src/inMemory.ts +356 -0
  86. package/src/index.ts +37 -0
  87. package/src/retryOnConflict.ts +100 -0
  88. package/src/testing.ts +47 -0
  89. package/testing/package.json +6 -0
package/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Neverbland
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # @kairos-es/core
2
+
3
+ DCB-first event-sourcing contract and in-memory store for Effect v3.
4
+
5
+ Provides the `DcbEventStore` contract (branded `Position` / `Tag` / `EventType`,
6
+ the `DcbEvent` / `Query` / `AppendCondition` schemas, the errors and the
7
+ `Context.Tag`), the pure `Projection` / `composeProjections` fold primitives, and
8
+ the in-memory `Layer` — the canonical, readable form of the check-then-append
9
+ algorithm. Decoding is deliberately not core's job, because it needs `Schema` and
10
+ a `Serializer`: the event-def builder, the slice builder and `buildDecisionModel`
11
+ live in `@kairos-es/codec`.
12
+
13
+ `retryOnConflict(command, schedule?)` is here too, because it is the recovery
14
+ half of the append condition: `AppendConditionFailed` carries no conflicting
15
+ position, so the only correct retry re-runs the whole read-decide-append cycle
16
+ and lets a fresh read re-derive the condition. It retries only on that tag — a
17
+ domain rejection escapes unretried — under a bounded jittered backoff, and it
18
+ takes nothing core did not already have (the error is core's, `Schedule` is
19
+ `effect`'s). See
20
+ [ADR-0008](../../docs/adr/0008-retry-on-append-condition-failed-decider-level-combinator.md).
21
+
22
+ The main entry also carries the surface an ENGINE author builds against, which is a
23
+ real surface rather than an internal one: `makeContractStore` / `RawDcbEventStore`,
24
+ the shared `subscribe` wake/poll/dedup machine every engine's `subscribe` is built
25
+ from and the two tuning constants and config fields that go with it
26
+ ([ADR-0009](../../docs/adr/0009-subscribe-machine-in-core-ascending-commit-order-precondition.md)),
27
+ and `classifyServableQuery` beside the `assertServableQuery` defining the grammar it
28
+ dispatches over. `SubscribeMachine.ts` states the one obligation an engine using it
29
+ inherits.
30
+
31
+ Platform-neutral (no `node:*` imports); `effect` is the only peer dependency.
32
+ `@kairos-es/core/testing` is a published subpath carrying the deterministic
33
+ `EPOCH` domain time and counter-based uuid support every suite shares.
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.AppendCondition = void 0;
7
+ var _effect = require("effect");
8
+ var _Event = require("./Event.js");
9
+ var _Query = require("./Query.js");
10
+ /**
11
+ * The optimistic-concurrency guard for `append`. The append fails if any event
12
+ * matching `failIfEventsMatch` exists strictly after `after`. This is the whole
13
+ * DCB consistency mechanism: "fail if anything I based my decision on has
14
+ * changed since I read it."
15
+ *
16
+ * `after` is exact-optional (absent, never `undefined`) per
17
+ * `exactOptionalPropertyTypes`. Absent means "scan the whole log".
18
+ */
19
+
20
+ const AppendCondition = exports.AppendCondition = /*#__PURE__*/_effect.Schema.Struct({
21
+ failIfEventsMatch: _Query.Query,
22
+ after: /*#__PURE__*/_effect.Schema.optionalWith(_Event.Position, {
23
+ exact: true
24
+ })
25
+ });
26
+ //# sourceMappingURL=AppendCondition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppendCondition.js","names":["_effect","require","_Event","_Query","AppendCondition","exports","Schema","Struct","failIfEventsMatch","Query","after","optionalWith","Position","exact"],"sources":["../../src/AppendCondition.ts"],"sourcesContent":[null],"mappings":";;;;;;AASA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AACA,IAAAE,MAAA,GAAAF,OAAA;AAXA;;;;;;;;;;AAaO,MAAMG,eAAe,GAAAC,OAAA,CAAAD,eAAA,gBAAGE,cAAM,CAACC,MAAM,CAAC;EAC3CC,iBAAiB,EAAEC,YAAK;EACxBC,KAAK,eAAEJ,cAAM,CAACK,YAAY,CAACC,eAAQ,EAAE;IAAEC,KAAK,EAAE;EAAI,CAAE;CACrD,CAAC","ignoreList":[]}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.makeContractStore = void 0;
7
+ var _effect = require("effect");
8
+ var _Event = require("./Event.js");
9
+ var _Query = require("./Query.js");
10
+ /** Decode an unknown limit through `ReadLimit`, dying on a defect-worthy value. */
11
+ const decodeReadLimit = /*#__PURE__*/_effect.Schema.decodeUnknownSync(_Event.ReadLimit);
12
+ /**
13
+ * Wrap a raw engine's mechanics with the shared contract-enforcement policy,
14
+ * producing a full `DcbEventStore` service value.
15
+ */
16
+ const makeContractStore = raw => ({
17
+ read: (query, options) => _effect.Effect.suspend(() => {
18
+ // Defects (surface when the Effect runs), keeping `read` at `E = never`.
19
+ (0, _Query.assertServableQuery)(query);
20
+ if (options?.limit !== undefined) {
21
+ decodeReadLimit(options.limit);
22
+ }
23
+ // Infrastructure faults are defects, not contract values.
24
+ return _effect.Effect.orDie(raw.read(query, options));
25
+ }),
26
+ append: (events, condition) => _effect.Effect.suspend(() => {
27
+ // An EMPTY batch is a plain-data caller bypassing the
28
+ // `NonEmptyReadonlyArray` type: there is nothing to append. The engines
29
+ // diverge on it at an unchecked boundary — Postgres inserts zero rows and
30
+ // its conditional function returns zero rows, indistinguishable from a
31
+ // conflict, so it surfaces a PHANTOM `AppendConditionFailed`, whereas
32
+ // in-memory silently returns the previous head (`start - 1n`). Make it a
33
+ // DEFECT here, at the one choke point, so the policy is definitionally
34
+ // identical across engines and zero-rows stays an unambiguous conflict
35
+ // signal (a throw inside the suspend becomes a defect, like
36
+ // `assertServableQuery`).
37
+ if (events.length === 0) {
38
+ throw new Error('makeContractStore.append: the events batch is empty; append requires ' + 'at least one event (a NonEmptyReadonlyArray). An empty batch is a ' + 'plain-data caller bypassing the type — a defect, not a conflict.');
39
+ }
40
+ // A non-servable guard query is a defect in every engine.
41
+ if (condition !== undefined) {
42
+ (0, _Query.assertServableQuery)(condition.failIfEventsMatch);
43
+ }
44
+ // Only `AppendConditionFailed` belongs on the contract error channel;
45
+ // every other fault (a `SqlError`, a `55P03` lock-timeout abort, …) is
46
+ // infrastructure and surfaces OFF the shared contract as a defect.
47
+ //
48
+ // Classified by `_tag`, NEVER by `instanceof`, and this is the site where
49
+ // that matters most: it is the ONE gate every backend's conflicts pass
50
+ // through, so a class-identity check here is a single point of silent
51
+ // failure for the whole write side. `@kairos-es/core` ships dual ESM/CJS,
52
+ // so a consumer's graph can hold two distinct `AppendConditionFailed`
53
+ // classes for one error — an engine wired against one copy of core and
54
+ // wrapped by a `makeContractStore` from another. Under `instanceof` that
55
+ // engine's GENUINE conflicts fail the class check and are `Effect.die`d
56
+ // as infrastructure, which does not merely mislabel them: it takes the
57
+ // conflict OFF the error channel, where `retryOnConflict` (which already
58
+ // matches on the tag, and correctly) can never see it to retry. The tag
59
+ // is the error's identity across realms; `retryOnConflict.ts` makes the
60
+ // argument at length and this is its other end.
61
+ //
62
+ // `Predicate.isTagged` is total over `unknown` — an object check, then
63
+ // `_tag` equality — so a `null`, a string or a raw `SqlError` on the
64
+ // engine's channel simply answers false and dies as it should. It also
65
+ // narrows the raw `AppendConditionFailed | E` to the contract's single
66
+ // error, which is what keeps `append` at `E = AppendConditionFailed`.
67
+ return _effect.Effect.catchAll(raw.append(events, condition), error => _effect.Predicate.isTagged('AppendConditionFailed')(error) ? _effect.Effect.fail(error) : _effect.Effect.die(error));
68
+ }),
69
+ subscribe: (query, after) =>
70
+ // `Effect.sync` runs when the stream is executed; a throw from
71
+ // `assertServableQuery` becomes a stream defect (identical rule to
72
+ // read/append). Infrastructure faults on the live tail die (subscribe is
73
+ // `E = never`).
74
+ _effect.Stream.unwrap(_effect.Effect.sync(() => {
75
+ (0, _Query.assertServableQuery)(query);
76
+ return _effect.Stream.orDie(raw.subscribe(query, after));
77
+ }))
78
+ });
79
+ exports.makeContractStore = makeContractStore;
80
+ //# sourceMappingURL=ContractStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContractStore.js","names":["_effect","require","_Event","_Query","decodeReadLimit","Schema","decodeUnknownSync","ReadLimit","makeContractStore","raw","read","query","options","Effect","suspend","assertServableQuery","limit","undefined","orDie","append","events","condition","length","Error","failIfEventsMatch","catchAll","error","Predicate","isTagged","fail","die","subscribe","after","Stream","unwrap","sync","exports"],"sources":["../../src/ContractStore.ts"],"sourcesContent":[null],"mappings":";;;;;;AAgCA,IAAAA,OAAA,GAAAC,OAAA;AAIA,IAAAC,MAAA,GAAAD,OAAA;AAEA,IAAAE,MAAA,GAAAF,OAAA;AAEA;AACA,MAAMG,eAAe,gBAAGC,cAAM,CAACC,iBAAiB,CAACC,gBAAS,CAAC;AAwB3D;;;;AAIO,MAAMC,iBAAiB,GAC5BC,GAAwB,KACG;EAC3BC,IAAI,EAAEA,CAACC,KAAK,EAAEC,OAAO,KACnBC,cAAM,CAACC,OAAO,CAAC,MAAK;IAClB;IACA,IAAAC,0BAAmB,EAACJ,KAAK,CAAC;IAC1B,IAAIC,OAAO,EAAEI,KAAK,KAAKC,SAAS,EAAE;MAChCb,eAAe,CAACQ,OAAO,CAACI,KAAK,CAAC;IAChC;IACA;IACA,OAAOH,cAAM,CAACK,KAAK,CAACT,GAAG,CAACC,IAAI,CAACC,KAAK,EAAEC,OAAO,CAAC,CAAC;EAC/C,CAAC,CAAC;EAEJO,MAAM,EAAEA,CAACC,MAAM,EAAEC,SAAS,KACxBR,cAAM,CAACC,OAAO,CAAC,MAAK;IAClB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,IAAIM,MAAM,CAACE,MAAM,KAAK,CAAC,EAAE;MACvB,MAAM,IAAIC,KAAK,CACb,uEAAuE,GACrE,oEAAoE,GACpE,kEAAkE,CACrE;IACH;IACA;IACA,IAAIF,SAAS,KAAKJ,SAAS,EAAE;MAC3B,IAAAF,0BAAmB,EAACM,SAAS,CAACG,iBAAiB,CAAC;IAClD;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,OAAOX,cAAM,CAACY,QAAQ,CAAChB,GAAG,CAACU,MAAM,CAACC,MAAM,EAAEC,SAAS,CAAC,EAAGK,KAAK,IAC1DC,iBAAS,CAACC,QAAQ,CAAC,uBAAuB,CAAC,CAACF,KAAK,CAAC,GAC9Cb,cAAM,CAACgB,IAAI,CAACH,KAAK,CAAC,GAClBb,cAAM,CAACiB,GAAG,CAACJ,KAAK,CAAC,CACtB;EACH,CAAC,CAAC;EAEJK,SAAS,EAAEA,CAACpB,KAAK,EAAEqB,KAAK;EACtB;EACA;EACA;EACA;EACAC,cAAM,CAACC,MAAM,CACXrB,cAAM,CAACsB,IAAI,CAAC,MAAK;IACf,IAAApB,0BAAmB,EAACJ,KAAK,CAAC;IAC1B,OAAOsB,cAAM,CAACf,KAAK,CAACT,GAAG,CAACsB,SAAS,CAACpB,KAAK,EAAEqB,KAAK,CAAC,CAAC;EAClD,CAAC,CAAC;CAEP,CAAC;AAAAI,OAAA,CAAA5B,iBAAA,GAAAA,iBAAA","ignoreList":[]}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.DcbEventStore = void 0;
7
+ var _effect = require("effect");
8
+ class DcbEventStore extends /*#__PURE__*/_effect.Context.Tag('@kairos-es/core/DcbEventStore')() {}
9
+ exports.DcbEventStore = DcbEventStore;
10
+ //# sourceMappingURL=DcbEventStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DcbEventStore.js","names":["_effect","require","DcbEventStore","Context","Tag","exports"],"sources":["../../src/DcbEventStore.ts"],"sourcesContent":[null],"mappings":";;;;;;AAiBA,IAAAA,OAAA,GAAAC,OAAA;AA2BM,MAAOC,aAAc,sBAAQC,eAAO,CAACC,GAAG,CAAC,+BAA+B,CAAC,EAgC5E;AAAAC,OAAA,CAAAH,aAAA,GAAAA,aAAA","ignoreList":[]}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.tagIdentity = exports.Tag = exports.SequencedEvent = exports.ReadLimit = exports.Position = exports.ORIGIN = exports.EventType = exports.DcbEvent = void 0;
7
+ var _effect = require("effect");
8
+ /**
9
+ * Core domain types for the DCB event log: branded scalars and the wire
10
+ * `DcbEvent`/`SequencedEvent` shapes.
11
+ *
12
+ * `data` is opaque bytes at the store layer; the codec (`@kairos-es/codec`) turns typed
13
+ * payloads into these bytes. Ordering is by `position` alone; `occurredAt` is
14
+ * producer-supplied domain time and is informational only.
15
+ */
16
+
17
+ /**
18
+ * A position in the single global event log: a branded, non-negative `bigint`.
19
+ *
20
+ * The log is 64-bit (`bigserial` in Postgres) and exceeds JS `number` safety at
21
+ * 2^53, so positions are a `bigint`. They are compared, never arithmetic'd.
22
+ * `Schema.BigInt` encodes to a decimal string (JSON-safe) and decodes to
23
+ * `bigint`. `0n` is the "before the first event" sentinel used by `after` and by
24
+ * an empty store's head.
25
+ */
26
+ const Position = exports.Position = /*#__PURE__*/_effect.Schema.BigInt.pipe(/*#__PURE__*/_effect.Schema.nonNegativeBigInt(), /*#__PURE__*/_effect.Schema.brand('Position'));
27
+ /** The sentinel position meaning "before the first event". */
28
+ const ORIGIN = exports.ORIGIN = /*#__PURE__*/Position.make(0n);
29
+ /**
30
+ * A business identifier attached to an event, following the `key:value`
31
+ * convention (e.g. `student:s1`). Tags replace the per-stream id of classic
32
+ * event sourcing; a query matches an event when the event carries all of an
33
+ * item's tags (superset test).
34
+ */
35
+ const Tag = exports.Tag = /*#__PURE__*/_effect.Schema.String.pipe(/*#__PURE__*/_effect.Schema.pattern(/^[^:]+:.+/, {
36
+ identifier: 'Tag'
37
+ }), /*#__PURE__*/_effect.Schema.brand('Tag'));
38
+ const tagIdentity = key => {
39
+ if (key.length === 0 || key.includes(':')) {
40
+ throw new Error(`tagIdentity: key must be non-empty and contain no ':' (got ${JSON.stringify(key)})`);
41
+ }
42
+ return {
43
+ key,
44
+ make: value => {
45
+ if (value.length === 0 || value.includes(':')) {
46
+ throw new Error(`tagIdentity(${JSON.stringify(key)}).make: value must be non-empty and contain no ':' (got ${JSON.stringify(value)})`);
47
+ }
48
+ return Tag.make(`${key}:${value}`);
49
+ }
50
+ };
51
+ };
52
+ /**
53
+ * A read cap: a branded non-negative integer bounding how many events a `read`
54
+ * returns. `0` returns none; an absent limit returns all matching events.
55
+ *
56
+ * The bound lives in the type, not merely in prose: a negative or non-integer
57
+ * limit is a programming error, so it is a DEFECT at the store boundary — the
58
+ * store validates through this schema and dies rather than surfacing it on the
59
+ * error channel (`read` keeps `E = never`). Constructed at call sites with
60
+ * `ReadLimit.make(n)`.
61
+ */
62
+ exports.tagIdentity = tagIdentity;
63
+ const ReadLimit = exports.ReadLimit = /*#__PURE__*/_effect.Schema.Int.pipe(/*#__PURE__*/_effect.Schema.greaterThanOrEqualTo(0), /*#__PURE__*/_effect.Schema.brand('ReadLimit'));
64
+ /**
65
+ * An event type name, a branded non-empty string. Versioning is by convention
66
+ * in the name (e.g. `course-registered.v2`); only non-emptiness is enforced.
67
+ */
68
+ const EventType = exports.EventType = /*#__PURE__*/_effect.Schema.String.pipe(/*#__PURE__*/_effect.Schema.nonEmptyString(), /*#__PURE__*/_effect.Schema.brand('EventType'));
69
+ /**
70
+ * An event as stored: an opaque payload plus its type, tags, a
71
+ * producer-supplied `uuid`, and producer-supplied `occurredAt` domain time.
72
+ *
73
+ * `data` is `Uint8Array` (opaque bytes); the store does not interpret it.
74
+ * `uuid` is producer-supplied to keep `core` deterministic (no RNG in core).
75
+ * `occurredAt` is informational only; ordering is by position alone.
76
+ */
77
+ const DcbEvent = exports.DcbEvent = /*#__PURE__*/_effect.Schema.Struct({
78
+ type: EventType,
79
+ data: _effect.Schema.Uint8ArrayFromSelf,
80
+ tags: /*#__PURE__*/_effect.Schema.Array(Tag),
81
+ uuid: _effect.Schema.UUID,
82
+ occurredAt: _effect.Schema.DateTimeUtc
83
+ });
84
+ /** A persisted event: the event together with the position it was written at. */
85
+ const SequencedEvent = exports.SequencedEvent = /*#__PURE__*/_effect.Schema.Struct({
86
+ event: DcbEvent,
87
+ position: Position
88
+ });
89
+ //# sourceMappingURL=Event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Event.js","names":["_effect","require","Position","exports","Schema","BigInt","pipe","nonNegativeBigInt","brand","ORIGIN","make","Tag","String","pattern","identifier","tagIdentity","key","length","includes","Error","JSON","stringify","value","ReadLimit","Int","greaterThanOrEqualTo","EventType","nonEmptyString","DcbEvent","Struct","type","data","Uint8ArrayFromSelf","tags","Array","uuid","UUID","occurredAt","DateTimeUtc","SequencedEvent","event","position"],"sources":["../../src/Event.ts"],"sourcesContent":[null],"mappings":";;;;;;AAQA,IAAAA,OAAA,GAAAC,OAAA;AARA;;;;;;;;;AAUA;;;;;;;;;AASO,MAAMC,QAAQ,GAAAC,OAAA,CAAAD,QAAA,gBAAGE,cAAM,CAACC,MAAM,CAACC,IAAI,cACxCF,cAAM,CAACG,iBAAiB,EAAE,eAC1BH,cAAM,CAACI,KAAK,CAAC,UAAU,CAAC,CACzB;AAGD;AACO,MAAMC,MAAM,GAAAN,OAAA,CAAAM,MAAA,gBAAaP,QAAQ,CAACQ,IAAI,CAAC,EAAE,CAAC;AAEjD;;;;;;AAMO,MAAMC,GAAG,GAAAR,OAAA,CAAAQ,GAAA,gBAAGP,cAAM,CAACQ,MAAM,CAACN,IAAI,cACnCF,cAAM,CAACS,OAAO,CAAC,WAAW,EAAE;EAAEC,UAAU,EAAE;AAAK,CAAE,CAAC,eAClDV,cAAM,CAACI,KAAK,CAAC,KAAK,CAAC,CACpB;AA8BM,MAAMO,WAAW,GAAIC,GAAW,IAAiB;EACtD,IAAIA,GAAG,CAACC,MAAM,KAAK,CAAC,IAAID,GAAG,CAACE,QAAQ,CAAC,GAAG,CAAC,EAAE;IACzC,MAAM,IAAIC,KAAK,CACb,8DAA8DC,IAAI,CAACC,SAAS,CAACL,GAAG,CAAC,GAAG,CACrF;EACH;EACA,OAAO;IACLA,GAAG;IACHN,IAAI,EAAGY,KAAK,IAAI;MACd,IAAIA,KAAK,CAACL,MAAM,KAAK,CAAC,IAAIK,KAAK,CAACJ,QAAQ,CAAC,GAAG,CAAC,EAAE;QAC7C,MAAM,IAAIC,KAAK,CACb,eAAeC,IAAI,CAACC,SAAS,CAACL,GAAG,CAAC,2DAA2DI,IAAI,CAACC,SAAS,CAACC,KAAK,CAAC,GAAG,CACtH;MACH;MACA,OAAOX,GAAG,CAACD,IAAI,CAAC,GAAGM,GAAG,IAAIM,KAAK,EAAE,CAAC;IACpC;GACD;AACH,CAAC;AAED;;;;;;;;;;AAAAnB,OAAA,CAAAY,WAAA,GAAAA,WAAA;AAUO,MAAMQ,SAAS,GAAApB,OAAA,CAAAoB,SAAA,gBAAGnB,cAAM,CAACoB,GAAG,CAAClB,IAAI,cACtCF,cAAM,CAACqB,oBAAoB,CAAC,CAAC,CAAC,eAC9BrB,cAAM,CAACI,KAAK,CAAC,WAAW,CAAC,CAC1B;AAGD;;;;AAIO,MAAMkB,SAAS,GAAAvB,OAAA,CAAAuB,SAAA,gBAAGtB,cAAM,CAACQ,MAAM,CAACN,IAAI,cACzCF,cAAM,CAACuB,cAAc,EAAE,eACvBvB,cAAM,CAACI,KAAK,CAAC,WAAW,CAAC,CAC1B;AAGD;;;;;;;;AAQO,MAAMoB,QAAQ,GAAAzB,OAAA,CAAAyB,QAAA,gBAAGxB,cAAM,CAACyB,MAAM,CAAC;EACpCC,IAAI,EAAEJ,SAAS;EACfK,IAAI,EAAE3B,cAAM,CAAC4B,kBAAkB;EAC/BC,IAAI,eAAE7B,cAAM,CAAC8B,KAAK,CAACvB,GAAG,CAAC;EACvBwB,IAAI,EAAE/B,cAAM,CAACgC,IAAI;EACjBC,UAAU,EAAEjC,cAAM,CAACkC;CACpB,CAAC;AAGF;AACO,MAAMC,cAAc,GAAApC,OAAA,CAAAoC,cAAA,gBAAGnC,cAAM,CAACyB,MAAM,CAAC;EAC1CW,KAAK,EAAEZ,QAAQ;EACfa,QAAQ,EAAEvC;CACX,CAAC","ignoreList":[]}
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.composeProjections = exports.AnyProjection = void 0;
7
+ var _Query = require("./Query.js");
8
+ // The wildcard query, built directly (not via the public `query` surface).
9
+ // Decision-model composition assembles `Query` values from plain data because
10
+ // it may legitimately produce shapes the public fast-path surface withholds:
11
+ // composing a type-only projection with tagged ones yields an OR that mixes a
12
+ // tagless item with tagged items. That is the one restriction edge left
13
+ // un-enforced by construction, deliberately, in this internal layer.
14
+ const WILDCARD = {
15
+ items: []
16
+ };
17
+ const AnyProjection = exports.AnyProjection = {
18
+ /**
19
+ * View a typed `Projection<S>` as an opaque `AnyProjection<S>`. This is the
20
+ * one place the invariant `evolve` is widened to the erased surface, so the
21
+ * unsoundness of a heterogeneous projection record is discharged here and
22
+ * nowhere else. `composeProjections` calls `evolve` with each projection's
23
+ * own state, so the widening is sound at runtime.
24
+ */
25
+ of: projection => projection
26
+ };
27
+ /** Merge two queries by OR-ing their items; either wildcard yields a wildcard. */
28
+ const mergeQuery = (left, right) => {
29
+ if (left.items.length === 0 || right.items.length === 0) {
30
+ return WILDCARD;
31
+ }
32
+ return {
33
+ items: [...left.items, ...right.items]
34
+ };
35
+ };
36
+ /**
37
+ * Compose named projections into one whose state is a record of sub-states and
38
+ * whose query is the OR-merge of all sub-queries. Each sub-projection only
39
+ * folds events matching its own query — the guarantee that `Projection.evolve`'s
40
+ * contract lets sub-projections rely on (so they need not re-gate themselves).
41
+ *
42
+ * The fold always writes each *matching* sub-result into a fresh record and
43
+ * returns it (no `changed` short-circuit, no `evolved !== prev` reference
44
+ * check): an in-place-mutating fold that returns the same reference would
45
+ * otherwise be silently dropped. At decision-model scale the extra copy is nil.
46
+ */
47
+ const composeProjections = projections => {
48
+ const keys = Object.keys(projections);
49
+ const initialState = Object.fromEntries(keys.map(key => [key, projections[key].initialState]));
50
+ // Seeding the reduce with the wildcard would swallow everything (mergeQuery
51
+ // treats an empty-items query as a wildcard), so fold the sub-queries
52
+ // directly with no seed.
53
+ const mergedQuery = keys.length === 0 ? WILDCARD : keys.map(key => projections[key].query).reduce((acc, q) => mergeQuery(acc, q));
54
+ return {
55
+ initialState,
56
+ query: mergedQuery,
57
+ evolve: (state, decoded) => {
58
+ const next = {
59
+ ...state
60
+ };
61
+ for (const key of keys) {
62
+ const projection = projections[key];
63
+ if (!(0, _Query.matchesSequenced)(decoded.sequenced, projection.query)) {
64
+ continue;
65
+ }
66
+ next[key] = projection.evolve(state[key], decoded);
67
+ }
68
+ return next;
69
+ }
70
+ };
71
+ };
72
+ exports.composeProjections = composeProjections;
73
+ //# sourceMappingURL=Projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Projection.js","names":["_Query","require","WILDCARD","items","AnyProjection","exports","of","projection","mergeQuery","left","right","length","composeProjections","projections","keys","Object","initialState","fromEntries","map","key","mergedQuery","query","reduce","acc","q","evolve","state","decoded","next","matchesSequenced","sequenced"],"sources":["../../src/Projection.ts"],"sourcesContent":[null],"mappings":";;;;;;AA4BA,IAAAA,MAAA,GAAAC,OAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,QAAQ,GAAU;EAAEC,KAAK,EAAE;AAAE,CAAE;AAqD9B,MAAMC,aAAa,GAAAC,OAAA,CAAAD,aAAA,GAAG;EAC3B;;;;;;;EAOAE,EAAE,EAAMC,UAAyB,IAC/BA;CACM;AAaV;AACA,MAAMC,UAAU,GAAGA,CAACC,IAAW,EAAEC,KAAY,KAAW;EACtD,IAAID,IAAI,CAACN,KAAK,CAACQ,MAAM,KAAK,CAAC,IAAID,KAAK,CAACP,KAAK,CAACQ,MAAM,KAAK,CAAC,EAAE;IACvD,OAAOT,QAAQ;EACjB;EACA,OAAO;IAAEC,KAAK,EAAE,CAAC,GAAGM,IAAI,CAACN,KAAK,EAAE,GAAGO,KAAK,CAACP,KAAK;EAAC,CAAE;AACnD,CAAC;AAED;;;;;;;;;;;AAWO,MAAMS,kBAAkB,GAC7BC,WAAc,IACmB;EACjC,MAAMC,IAAI,GAAGC,MAAM,CAACD,IAAI,CAACD,WAAW,CAAoC;EAExE,MAAMG,YAAY,GAAGD,MAAM,CAACE,WAAW,CACrCH,IAAI,CAACI,GAAG,CAAEC,GAAG,IAAK,CAACA,GAAG,EAAEN,WAAW,CAACM,GAAG,CAAC,CAACH,YAAY,CAAC,CAAC,CACnC;EAEtB;EACA;EACA;EACA,MAAMI,WAAW,GACfN,IAAI,CAACH,MAAM,KAAK,CAAC,GACbT,QAAQ,GACRY,IAAI,CACDI,GAAG,CAAEC,GAAG,IAAKN,WAAW,CAACM,GAAG,CAAC,CAACE,KAAK,CAAC,CACpCC,MAAM,CAAC,CAACC,GAAG,EAAEC,CAAC,KAAKhB,UAAU,CAACe,GAAG,EAAEC,CAAC,CAAC,CAAC;EAE/C,OAAO;IACLR,YAAY;IACZK,KAAK,EAAED,WAAW;IAClBK,MAAM,EAAEA,CAACC,KAAK,EAAEC,OAAO,KAAI;MACzB,MAAMC,IAAI,GAAG;QAAE,GAAGF;MAAK,CAAuC;MAC9D,KAAK,MAAMP,GAAG,IAAIL,IAAI,EAAE;QACtB,MAAMP,UAAU,GAAGM,WAAW,CAACM,GAAG,CAAC;QACnC,IAAI,CAAC,IAAAU,uBAAgB,EAACF,OAAO,CAACG,SAAS,EAAEvB,UAAU,CAACc,KAAK,CAAC,EAAE;UAC1D;QACF;QACAO,IAAI,CAACT,GAAG,CAAC,GAAGZ,UAAU,CAACkB,MAAM,CAACC,KAAK,CAACP,GAAG,CAAC,EAAEQ,OAAO,CAEhD;MACH;MACA,OAAOC,IAAI;IACb;GACD;AACH,CAAC;AAAAvB,OAAA,CAAAO,kBAAA,GAAAA,kBAAA","ignoreList":[]}
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.query = exports.matchesSequenced = exports.matchesQueryItem = exports.matchesQuery = exports.classifyServableQuery = exports.assertServableQuery = exports.QueryItem = exports.Query = void 0;
7
+ var _effect = require("effect");
8
+ var _Event = require("./Event.js");
9
+ /**
10
+ * The DCB selection language: `Query` is an OR of `QueryItem`s. Within an item,
11
+ * `types` is an OR-filter (empty means any type) and `tags` is an AND superset
12
+ * test (the event must carry all of the item's tags; extra event tags are
13
+ * fine). The empty query (`items: []`) matches every event.
14
+ *
15
+ * The match predicate is a single pure module function over plain data;
16
+ * `Query` values carry no methods. See `matchesQuery` / `matchesQueryItem`.
17
+ *
18
+ * Smart constructors enforce the indexed fast-path restriction at the
19
+ * constructor surface (not via a runtime throw): every query built through them
20
+ * is the wildcard (`query.all`), a single type-only item (`query.types`), or an
21
+ * OR of tagged items each carrying at least one tag (`query.item` + `query.or`,
22
+ * or `query.tags` for the single-item case). The `query.item` constructor
23
+ * requires a non-empty `tags` at the type level, so there is no public way to
24
+ * build an unrestricted item (empty types and empty tags). `QueryItem`/`Query`
25
+ * are plain data, so internal decision-model plumbing can still assemble any
26
+ * shape directly; the restriction binds the public surface, where consumers
27
+ * build their consistency boundaries.
28
+ *
29
+ * The grammar's DISPATCH lives here too, beside the grammar it dispatches over:
30
+ * `ServableQueryShape` / `classifyServableQuery` own the three shapes an engine
31
+ * serves and the routing of the degenerate empty item.
32
+ */
33
+
34
+ /**
35
+ * One clause of a query: a set of types (OR, empty = any) AND a set of tags
36
+ * (superset test, empty = no tag constraint).
37
+ */
38
+ const QueryItem = exports.QueryItem = /*#__PURE__*/_effect.Schema.Struct({
39
+ types: /*#__PURE__*/_effect.Schema.Array(_Event.EventType),
40
+ tags: /*#__PURE__*/_effect.Schema.Array(_Event.Tag)
41
+ });
42
+ /** A query: an OR of items. Empty `items` matches everything. */
43
+ const Query = exports.Query = /*#__PURE__*/_effect.Schema.Struct({
44
+ items: /*#__PURE__*/_effect.Schema.Array(QueryItem)
45
+ });
46
+ /**
47
+ * True when `event` satisfies `item`: its type is in `item.types` (or the item
48
+ * has no type constraint) AND the event's tags are a superset of `item.tags`.
49
+ */
50
+ const matchesQueryItem = (event, item) => {
51
+ const typeOk = item.types.length === 0 || item.types.includes(event.type);
52
+ if (!typeOk) {
53
+ return false;
54
+ }
55
+ const eventTags = new Set(event.tags);
56
+ return item.tags.every(tag => eventTags.has(tag));
57
+ };
58
+ /**
59
+ * The one true match predicate (ported from `popo.py:48-54`): an empty query is
60
+ * a wildcard; otherwise the event must match at least one item (OR across
61
+ * items).
62
+ */
63
+ exports.matchesQueryItem = matchesQueryItem;
64
+ const matchesQuery = (event, query) => {
65
+ if (query.items.length === 0) {
66
+ return true;
67
+ }
68
+ return query.items.some(item => matchesQueryItem(event, item));
69
+ };
70
+ /** Convenience predicate over a `SequencedEvent`. */
71
+ exports.matchesQuery = matchesQuery;
72
+ const matchesSequenced = (sequenced, query) => matchesQuery(sequenced.event, query);
73
+ /**
74
+ * Assert `query` is *servable* by the indexed fast paths, throwing a plain
75
+ * `Error` describing the violation otherwise. This enforces at the store
76
+ * boundary the restriction the smart constructors enforce at the type level
77
+ * (`Query.ts` module docs) but which plain-data assembly — e.g. decision-model
78
+ * composition, `Projection.ts:31-36` — can still bypass.
79
+ *
80
+ * The servable grammar is exactly one of:
81
+ * - the wildcard (`items.length === 0`), which matches every event;
82
+ * - a *single* item (`items.length === 1`), any types/tags, including a
83
+ * type-only item; or
84
+ * - a *multi*-item query (`items.length > 1`) in which every item carries at
85
+ * least one tag.
86
+ *
87
+ * A multi-item query that mixes a tagless (type-only) item with tagged items is
88
+ * NOT servable: the by-type path and the by-tag path are indexed differently,
89
+ * so an OR spanning both cannot ride a single index. This is the previously
90
+ * un-enforced edge (`Projection.ts:31-36`).
91
+ *
92
+ * This function is pure (no clock, no RNG, no effect). Every engine applies it at
93
+ * its read/subscribe/append entry points, through the one shared
94
+ * `makeContractStore` decorator, so the rule is inherited rather than restated per
95
+ * backend; a throw inside a store `Effect` becomes a *defect* — a programming
96
+ * error, not an error-channel value — which is the intended "defect in every
97
+ * engine" behaviour.
98
+ */
99
+ exports.matchesSequenced = matchesSequenced;
100
+ const assertServableQuery = query => {
101
+ const {
102
+ items
103
+ } = query;
104
+ // Wildcard and single-item queries are always servable.
105
+ if (items.length <= 1) {
106
+ return;
107
+ }
108
+ // A multi-item query is servable only if every item is tagged; a tagless
109
+ // (type-only) item mixed with tagged items cannot ride a single index.
110
+ const hasTaglessItem = items.some(item => item.tags.length === 0);
111
+ if (hasTaglessItem) {
112
+ throw new Error('assertServableQuery: a multi-item query must have every item carry at ' + 'least one tag; a type-only item mixed with tagged items is not servable');
113
+ }
114
+ };
115
+ /**
116
+ * Classify a servable `Query` into the shape that serves it.
117
+ *
118
+ * ## Why the dispatch lives beside the grammar
119
+ *
120
+ * The three shapes ARE the three bullets `assertServableQuery` above admits, so an
121
+ * engine that re-derives the dispatch is a second answer to "which shape is
122
+ * this?", and the shapes only stay in step while there is one answer. Core states
123
+ * the grammar, so stating the dispatch over it here is that one fact once rather
124
+ * than once per backend. It is pure — no clock, no RNG, no effect — and knows
125
+ * nothing of SQL: what a shape COMPILES to stays entirely the engine's.
126
+ *
127
+ * ## The degenerate empty item routes to the WILDCARD, structurally
128
+ *
129
+ * A single item with neither types nor tags — `{ items: [{ types: [], tags: [] }] }`
130
+ * — matches EVERY event: `matchesQueryItem` reads empty types as "any type" and
131
+ * empty tags as a vacuous superset test. It must therefore be served by the
132
+ * wildcard. Served by the type-only path it would compile to a value list with
133
+ * nothing in it, and a membership test against an empty list matches NOTHING — the
134
+ * exact inversion of what the query means. Nothing upstream stops it reaching an
135
+ * engine: `assertServableQuery` admits a SINGLE item of any shape, and the servable
136
+ * grammar forbids a tagless item only in a MULTI-item query, so this dispatch is
137
+ * the last place the divergence can be closed.
138
+ *
139
+ * It is closed by the SHAPE and not by a branch in front of it. `typeOnly` carries
140
+ * `NonEmptyReadonlyArray`, so there is no way to construct it from an empty list;
141
+ * the emptiness test IS the constructor, and deleting it does not silently restore
142
+ * the wrong routing, it stops compiling. A guard clause placed before the
143
+ * construction would have been deletable by anyone tidying what looks like a
144
+ * redundant check on a list that "obviously" has types in it.
145
+ */
146
+ exports.assertServableQuery = assertServableQuery;
147
+ const classifyServableQuery = query => {
148
+ if (query.items.length === 0) {
149
+ return {
150
+ kind: 'wildcard'
151
+ };
152
+ }
153
+ const only = query.items.length === 1 ? query.items[0] : undefined;
154
+ if (only !== undefined && only.tags.length === 0) {
155
+ return _effect.Array.isNonEmptyReadonlyArray(only.types) ? {
156
+ kind: 'typeOnly',
157
+ types: only.types
158
+ } : {
159
+ kind: 'wildcard'
160
+ };
161
+ }
162
+ return {
163
+ kind: 'tagged'
164
+ };
165
+ };
166
+ // --- Smart constructors (the fast-path-enforcing surface) -------------------
167
+ /**
168
+ * A query item carrying at least one tag (superset test), optionally narrowed
169
+ * to `types`. The non-empty `tags` requirement is the fast-path restriction,
170
+ * enforced at the type level rather than as a runtime throw. Combine several
171
+ * items with `or`.
172
+ */
173
+ exports.classifyServableQuery = classifyServableQuery;
174
+ const item = fields => ({
175
+ types: fields.types ?? [],
176
+ tags: fields.tags
177
+ });
178
+ /** The wildcard query: matches every event. */
179
+ const all = () => ({
180
+ items: []
181
+ });
182
+ /**
183
+ * A single-item query matching events that carry all of `tags`, optionally also
184
+ * constrained to `types`. The common indexed fast-path shape.
185
+ */
186
+ const tags = (tags, types) => ({
187
+ items: [item({
188
+ tags,
189
+ ...(types === undefined ? {} : {
190
+ types
191
+ })
192
+ })]
193
+ });
194
+ /**
195
+ * A single type-only query (the other indexed fast path): one item constrained
196
+ * to `types` with no tag filter. This is the only tagless item shape the
197
+ * surface admits, and only as the whole query.
198
+ */
199
+ const types = types => ({
200
+ items: [{
201
+ types,
202
+ tags: []
203
+ }]
204
+ });
205
+ /**
206
+ * An OR of query items. Each item should be built with `item` (which requires
207
+ * at least one tag); combining bare type-only items is intentionally not
208
+ * offered (use `types` for the single type-only query).
209
+ */
210
+ const or = items => ({
211
+ items
212
+ });
213
+ /** Namespaced smart constructors for `Query`. */
214
+ const query = exports.query = {
215
+ all,
216
+ item,
217
+ or,
218
+ tags,
219
+ types
220
+ };
221
+ //# sourceMappingURL=Query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Query.js","names":["_effect","require","_Event","QueryItem","exports","Schema","Struct","types","Array","EventType","tags","Tag","Query","items","matchesQueryItem","event","item","typeOk","length","includes","type","eventTags","Set","every","tag","has","matchesQuery","query","some","matchesSequenced","sequenced","assertServableQuery","hasTaglessItem","Error","classifyServableQuery","kind","only","undefined","Arr","isNonEmptyReadonlyArray","fields","all","or"],"sources":["../../src/Query.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}