@kairos-es/core 1.0.0-alpha.4 → 1.0.0-alpha.6

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 (114) hide show
  1. package/README.md +3 -3
  2. package/dist/cjs/AppendCondition.js +1 -3
  3. package/dist/cjs/AppendCondition.js.map +1 -1
  4. package/dist/cjs/AppendIsOwned.js +6 -6
  5. package/dist/cjs/AppendIsOwned.js.map +1 -1
  6. package/dist/cjs/ContractStore.js +2 -2
  7. package/dist/cjs/ContractStore.js.map +1 -1
  8. package/dist/cjs/DcbEventStore.js +1 -1
  9. package/dist/cjs/DcbEventStore.js.map +1 -1
  10. package/dist/cjs/Event.js +29 -13
  11. package/dist/cjs/Event.js.map +1 -1
  12. package/dist/cjs/Query.js +1 -1
  13. package/dist/cjs/Query.js.map +1 -1
  14. package/dist/cjs/SubscribeMachine.js +158 -67
  15. package/dist/cjs/SubscribeMachine.js.map +1 -1
  16. package/dist/cjs/inMemory.js +4 -4
  17. package/dist/cjs/inMemory.js.map +1 -1
  18. package/dist/cjs/retryOnConflict.js +4 -10
  19. package/dist/cjs/retryOnConflict.js.map +1 -1
  20. package/dist/cjs/testing.js +2 -2
  21. package/dist/cjs/testing.js.map +1 -1
  22. package/dist/{dts → dts-cjs}/AppendCondition.d.ts +5 -7
  23. package/dist/{dts → dts-cjs}/AppendCondition.d.ts.map +1 -1
  24. package/dist/{dts → dts-cjs}/AppendIsOwned.d.ts +6 -6
  25. package/dist/{dts → dts-cjs}/AppendIsOwned.d.ts.map +1 -1
  26. package/dist/{dts → dts-cjs}/ContractStore.d.ts +3 -2
  27. package/dist/dts-cjs/ContractStore.d.ts.map +1 -0
  28. package/dist/{dts → dts-cjs}/DcbEventStore.d.ts +2 -2
  29. package/dist/{dts → dts-cjs}/DcbEventStore.d.ts.map +1 -1
  30. package/dist/{dts → dts-cjs}/Event.d.ts +31 -20
  31. package/dist/dts-cjs/Event.d.ts.map +1 -0
  32. package/dist/{dts → dts-cjs}/Query.d.ts +5 -5
  33. package/dist/dts-cjs/SubscribeMachine.d.ts +289 -0
  34. package/dist/dts-cjs/SubscribeMachine.d.ts.map +1 -0
  35. package/dist/{dts → dts-cjs}/inMemory.d.ts.map +1 -1
  36. package/dist/{dts → dts-cjs}/index.d.ts +1 -1
  37. package/dist/dts-cjs/package.json +3 -0
  38. package/dist/{dts → dts-cjs}/retryOnConflict.d.ts +1 -7
  39. package/dist/dts-cjs/retryOnConflict.d.ts.map +1 -0
  40. package/dist/{dts → dts-cjs}/testing.d.ts +1 -1
  41. package/dist/dts-esm/AppendCondition.d.ts +21 -0
  42. package/dist/dts-esm/AppendCondition.d.ts.map +1 -0
  43. package/dist/dts-esm/AppendIsOwned.d.ts +78 -0
  44. package/dist/dts-esm/AppendIsOwned.d.ts.map +1 -0
  45. package/dist/dts-esm/ContractStore.d.ts +62 -0
  46. package/dist/dts-esm/ContractStore.d.ts.map +1 -0
  47. package/dist/dts-esm/DcbEventStore.d.ts +64 -0
  48. package/dist/dts-esm/DcbEventStore.d.ts.map +1 -0
  49. package/dist/dts-esm/Event.d.ts +174 -0
  50. package/dist/dts-esm/Event.d.ts.map +1 -0
  51. package/dist/dts-esm/Projection.d.ts +124 -0
  52. package/dist/dts-esm/Projection.d.ts.map +1 -0
  53. package/dist/dts-esm/Query.d.ts +180 -0
  54. package/dist/dts-esm/Query.d.ts.map +1 -0
  55. package/dist/dts-esm/SubscribeMachine.d.ts +289 -0
  56. package/dist/dts-esm/SubscribeMachine.d.ts.map +1 -0
  57. package/dist/dts-esm/errors.d.ts +17 -0
  58. package/dist/dts-esm/errors.d.ts.map +1 -0
  59. package/dist/dts-esm/inMemory.d.ts +76 -0
  60. package/dist/dts-esm/inMemory.d.ts.map +1 -0
  61. package/dist/dts-esm/index.d.ts +40 -0
  62. package/dist/dts-esm/index.d.ts.map +1 -0
  63. package/dist/dts-esm/package.json +3 -0
  64. package/dist/dts-esm/retryOnConflict.d.ts +64 -0
  65. package/dist/dts-esm/retryOnConflict.d.ts.map +1 -0
  66. package/dist/dts-esm/testing.d.ts +39 -0
  67. package/dist/dts-esm/testing.d.ts.map +1 -0
  68. package/dist/esm/AppendCondition.js +1 -3
  69. package/dist/esm/AppendCondition.js.map +1 -1
  70. package/dist/esm/AppendIsOwned.js +6 -6
  71. package/dist/esm/AppendIsOwned.js.map +1 -1
  72. package/dist/esm/ContractStore.js +2 -2
  73. package/dist/esm/ContractStore.js.map +1 -1
  74. package/dist/esm/DcbEventStore.js +1 -1
  75. package/dist/esm/DcbEventStore.js.map +1 -1
  76. package/dist/esm/Event.js +30 -14
  77. package/dist/esm/Event.js.map +1 -1
  78. package/dist/esm/Query.js +1 -1
  79. package/dist/esm/Query.js.map +1 -1
  80. package/dist/esm/SubscribeMachine.js +157 -67
  81. package/dist/esm/SubscribeMachine.js.map +1 -1
  82. package/dist/esm/inMemory.js +5 -5
  83. package/dist/esm/inMemory.js.map +1 -1
  84. package/dist/esm/index.js +1 -1
  85. package/dist/esm/retryOnConflict.js +4 -10
  86. package/dist/esm/retryOnConflict.js.map +1 -1
  87. package/dist/esm/testing.js +2 -2
  88. package/dist/esm/testing.js.map +1 -1
  89. package/package.json +21 -11
  90. package/src/AppendCondition.ts +1 -1
  91. package/src/AppendIsOwned.ts +7 -7
  92. package/src/ContractStore.ts +5 -4
  93. package/src/DcbEventStore.ts +3 -3
  94. package/src/Event.ts +49 -14
  95. package/src/Query.ts +1 -1
  96. package/src/SubscribeMachine.ts +278 -96
  97. package/src/inMemory.ts +6 -6
  98. package/src/index.ts +1 -1
  99. package/src/retryOnConflict.ts +6 -11
  100. package/src/testing.ts +2 -2
  101. package/testing/package.json +1 -1
  102. package/dist/dts/ContractStore.d.ts.map +0 -1
  103. package/dist/dts/Event.d.ts.map +0 -1
  104. package/dist/dts/SubscribeMachine.d.ts +0 -179
  105. package/dist/dts/SubscribeMachine.d.ts.map +0 -1
  106. package/dist/dts/retryOnConflict.d.ts.map +0 -1
  107. /package/dist/{dts → dts-cjs}/Projection.d.ts +0 -0
  108. /package/dist/{dts → dts-cjs}/Projection.d.ts.map +0 -0
  109. /package/dist/{dts → dts-cjs}/Query.d.ts.map +0 -0
  110. /package/dist/{dts → dts-cjs}/errors.d.ts +0 -0
  111. /package/dist/{dts → dts-cjs}/errors.d.ts.map +0 -0
  112. /package/dist/{dts → dts-cjs}/inMemory.d.ts +0 -0
  113. /package/dist/{dts → dts-cjs}/index.d.ts.map +0 -0
  114. /package/dist/{dts → dts-cjs}/testing.d.ts.map +0 -0
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.subscriptionTuningFields = exports.subscribeStream = exports.DEFAULT_POLL_INTERVAL_MILLIS = exports.DEFAULT_CATCH_UP_PAGE_SIZE = void 0;
6
+ exports.subscriptionTuningFields = exports.subscribeStream = exports.subscribeItems = exports.DEFAULT_POLL_INTERVAL_MILLIS = exports.DEFAULT_CATCH_UP_PAGE_SIZE = void 0;
7
7
  var _effect = require("effect");
8
8
  var _Event = require("./Event.js");
9
9
  /**
@@ -13,6 +13,15 @@ var _Event = require("./Event.js");
13
13
  * the cursor's exclusive lower bound) and the poll loop that together turn a paged
14
14
  * read into a live subscription.
15
15
  *
16
+ * The algorithm is `subscribeItems`, generic over the item `A` it delivers and the
17
+ * cursor `C` it resumes from, because nothing in it is about an event: any source
18
+ * that can page-read strictly after a cursor and name the cursor of what it
19
+ * returned is subscribable by the same loop. `subscribeStream` is the event-store
20
+ * shape — `SequencedEvent` ordered by `Position` — over the same loop, and it is
21
+ * what every engine calls, unchanged by the generalisation. A second kind of
22
+ * source reuses the loop rather than growing a second one, for the reason the next
23
+ * paragraph gives.
24
+ *
16
25
  * It lives in core because delivery semantics are contract semantics. An engine
17
26
  * supplies TRANSPORT through two STUBBABLE seams — `fetch`, a paged read strictly
18
27
  * after a cursor, and `listen`, an optional wake source — and inherits the delivery
@@ -23,48 +32,52 @@ var _Event = require("./Event.js");
23
32
  * Both seams take plain in-memory values in a test, so the wake/poll/de-dup logic
24
33
  * is exercisable with no live backend at all.
25
34
  *
26
- * All THREE are the callers, and the count matters to a reader here: it means there
27
- * is exactly ONE delivery algorithm in this repo, and it is the code below. The
35
+ * All THREE engines are callers, and the count matters to a reader here: it means
36
+ * there is exactly ONE delivery algorithm in this repo, and it is the code below. The
28
37
  * in-memory store is a caller like the rest — it hands in a `fetch` over its log
29
38
  * `Ref` and its append `PubSub` as a wake source and keeps no delivery logic of its
30
39
  * own — which is what makes the shared contract suite's subscribe cases a comparison
31
40
  * of two BACKENDS rather than of two delivery algorithms.
32
41
  *
33
- * Correctness rests on the periodic position-based reconcile — a re-read from the
42
+ * Correctness rests on the periodic cursor-based reconcile — a re-read from the
34
43
  * cursor every poll interval — and NEVER on the wake source, which only lowers
35
44
  * delivery latency below that interval. A subscription with no wake source at all
36
45
  * is therefore complete and correct, merely slower, which is why `listen` is
37
46
  * optional in the TYPE rather than by the convention of passing `Stream.never`:
38
47
  * poll-only delivery is a supported shape, not a degraded one.
39
48
  *
40
- * ## The precondition every engine inherits: ASCENDING COMMIT ORDER
49
+ * ## The precondition every caller inherits: ASCENDING COMMIT ORDER
41
50
  *
42
- * A position that is committed and VISIBLE must never be below one already
43
- * delivered. Gaps are fine: the cursor is an ascending exclusive lower bound, so a
44
- * number that is allocated and never committed, or never allocated at all, is
45
- * simply a number the machine never sees. Out-of-order commits are not fine. If one
51
+ * It binds EVERY caller, over whatever cursor it chose — an engine's `Position`, or
52
+ * any other `C` handed to `subscribeItems` — and the example below is written in
53
+ * positions only because the engines are the callers it was first written for. A
54
+ * cursor that is committed and VISIBLE must never be below one already delivered.
55
+ * Gaps are fine: the cursor is an ascending exclusive lower bound, so a number
56
+ * that is allocated and never committed, or never allocated at all, is simply a
57
+ * number the machine never sees. Out-of-order commits are not fine. If one
46
58
  * writer allocates position 5 and another allocates 6, and 6 commits first, a poll
47
59
  * landing between the two commits delivers 6 and advances the cursor past it — and
48
60
  * 5 is then lost forever, because no later read looks below the cursor and nothing
49
- * anywhere notices the hole. An engine whose concurrent writers can commit out of
61
+ * anywhere notices the hole. A caller whose concurrent writers can commit out of
50
62
  * order MUST serialise them, or this machine will silently skip. An engine that
51
63
  * takes an exclusive lock on both of its append paths discharges the obligation
52
64
  * that way; an engine whose append is a single statement discharges it
53
65
  * structurally.
54
66
  *
55
67
  * The obligation is written down HERE, in the algorithm that depends on it, rather
56
- * than in whichever engine happens to satisfy it. It is a property of this delivery
57
- * loop and of nothing else, so an engine author reading only their own source has
68
+ * than in whichever caller happens to satisfy it. It is a property of this delivery
69
+ * loop and of nothing else, so an author reading only their own source has
58
70
  * no way to discover that anything downstream needs it — and the failure mode is
59
71
  * the worst kind there is: no error, no defect, no failing test, just an event that
60
72
  * a subscriber never receives. A single engine owning both its append path and its
61
73
  * own wake loop can leave the assumption implicit; a shared machine cannot.
62
74
  *
63
- * ## `catchUpPageSize` bounds the READ, not the emission
75
+ * ## `catchUpPageSize` bounds the READ, not the emission — unless `emit: 'page'`
64
76
  *
65
- * `drainFrom` below PAGES the catch-up read — `catchUpPageSize` bounds each
66
- * `fetch` — but it COLLECTS every page into one array, which is emitted as a SINGLE
67
- * chunk. So peak memory at subscription start is O(backlog) rather than O(page): a
77
+ * Under the default `emit: 'backlog'`, which is what `subscribeStream` and so every
78
+ * engine uses, `drainFrom` below PAGES the catch-up read — `catchUpPageSize` bounds
79
+ * each `fetch` — but it COLLECTS every page into one array, which is emitted as a
80
+ * SINGLE chunk. So peak memory at subscription start is O(backlog) rather than O(page): a
68
81
  * subscriber joining behind a large log materialises the whole backlog before its
69
82
  * consumer sees the first element.
70
83
  *
@@ -75,6 +88,19 @@ var _Event = require("./Event.js");
75
88
  * stay small even against a one-chunk catch-up. The cost therefore lands on backlog
76
89
  * memory alone, and it lands hardest on the durable-log-with-in-memory-view mode,
77
90
  * where an ephemeral view re-catches-up the entire log on every boot.
91
+ *
92
+ * `emit: 'page'` changes exactly that and nothing else. Each fetched page is
93
+ * emitted as its own chunk and the cursor advances past it before the next read, so
94
+ * peak memory is O(page) and the consumer sees the first item after ONE read rather
95
+ * than after the whole backlog. Delivery is unchanged: the same items in the same
96
+ * order, the same de-dup, the same wake and poll. What a caller gives up is the
97
+ * one-chunk catch-up, so it must not read meaning into chunk boundaries under
98
+ * either mode. It is for a consumer that does NOT re-chunk downstream and whose
99
+ * catch-up can be the whole of a large source — a full resync of a table, say —
100
+ * where holding the backlog would be the cost the paging was meant to avoid. The
101
+ * engines keep `'backlog'` because the read side's re-chunking already bounds what
102
+ * they commit, and changing their emission would move a behaviour nobody asked to
103
+ * move.
78
104
  */
79
105
 
80
106
  /**
@@ -102,6 +128,10 @@ const DEFAULT_CATCH_UP_PAGE_SIZE = exports.DEFAULT_CATCH_UP_PAGE_SIZE = 512;
102
128
  * one-second fallback poll (`conn.wait(..., interval=1)`).
103
129
  */
104
130
  const DEFAULT_POLL_INTERVAL_MILLIS = exports.DEFAULT_POLL_INTERVAL_MILLIS = 1000;
131
+ /** A usable `pollInterval`: see `subscriptionTuningFields` for the bounds' argument. */
132
+ const PollIntervalMillis = /*#__PURE__*/_effect.Schema.Number.check(/*#__PURE__*/_effect.Schema.isGreaterThan(0), /*#__PURE__*/_effect.Schema.isFinite());
133
+ /** A usable `catchUpPageSize`: see `subscriptionTuningFields` for the bounds' argument. */
134
+ const CatchUpPageSize = /*#__PURE__*/_effect.Schema.Int.check(/*#__PURE__*/_effect.Schema.isGreaterThan(0));
105
135
  /**
106
136
  * The two subscribe-tuning config FIELDS, for an engine whose config is a `Schema`
107
137
  * to spread into its own struct.
@@ -114,12 +144,12 @@ const DEFAULT_POLL_INTERVAL_MILLIS = exports.DEFAULT_POLL_INTERVAL_MILLIS = 1000
114
144
  * the key NAME, the VALIDATION and the DEFAULT from one place, so a caller who has
115
145
  * tuned one engine's subscribe reads another's without translating, and the two
116
146
  * cannot drift in what they ACCEPT any more than in what they assume. Two engines
117
- * hand-authoring the identical `Schema.optionalWith(…)` twice were identical only
147
+ * hand-authoring the identical `Schema.optionalKey(…)` twice were identical only
118
148
  * by inspection.
119
149
  *
120
150
  * The bounds differ between the two because the quantities do. `pollInterval` is a
121
- * duration, so a fraction of a millisecond is meaningful and only `positive` and
122
- * `finite` matter: at zero or below the loop would spin without ever waiting for a
151
+ * duration, so a fraction of a millisecond is meaningful and only `isGreaterThan(0)`
152
+ * and `isFinite` matter: at zero or below the loop would spin without ever waiting for a
123
153
  * wake, and at `Infinity` the periodic re-read — the half that carries delivery —
124
154
  * would never come, which silently converts the wake source from an optimisation
125
155
  * into the guarantee. `catchUpPageSize` is a COUNT, so it must be an integer
@@ -127,17 +157,29 @@ const DEFAULT_POLL_INTERVAL_MILLIS = exports.DEFAULT_POLL_INTERVAL_MILLIS = 1000
127
157
  * length against it to decide the tail is drained, and a page of zero would report
128
158
  * "drained" forever without reading anything.
129
159
  *
130
- * `exact: true` on both keeps the decoded type at `key?: T` rather than
160
+ * `optionalKey` on both keeps the decoded type at `key?: T` rather than
131
161
  * `T | undefined`, matching the repo's `exactOptionalPropertyTypes` discipline — an
132
162
  * absent key, never an explicit `undefined`.
133
163
  */
134
164
  const subscriptionTuningFields = exports.subscriptionTuningFields = {
135
- pollInterval: /*#__PURE__*/_effect.Schema.optionalWith(/*#__PURE__*/_effect.Schema.Number.pipe(/*#__PURE__*/_effect.Schema.positive(), /*#__PURE__*/_effect.Schema.finite()), {
136
- exact: true
137
- }),
138
- catchUpPageSize: /*#__PURE__*/_effect.Schema.optionalWith(/*#__PURE__*/_effect.Schema.Int.pipe(/*#__PURE__*/_effect.Schema.positive()), {
139
- exact: true
140
- })
165
+ pollInterval: /*#__PURE__*/_effect.Schema.optionalKey(PollIntervalMillis),
166
+ catchUpPageSize: /*#__PURE__*/_effect.Schema.optionalKey(CatchUpPageSize)
167
+ };
168
+ /**
169
+ * Why a caller-supplied tuning knob is unusable, naming the field and the value, or
170
+ * `undefined` when both are usable or absent. It judges with the SAME two schemas
171
+ * the config fields are built from, so `subscribeItems`, whose caller may have no
172
+ * config to decode, accepts exactly what an engine's config accepts and the bounds
173
+ * have one home.
174
+ */
175
+ const tuningFault = deps => {
176
+ if (deps.pollInterval !== undefined && !_effect.Schema.is(PollIntervalMillis)(deps.pollInterval)) {
177
+ return `subscribeItems: pollInterval must be a finite number of milliseconds greater than 0, got ${deps.pollInterval}`;
178
+ }
179
+ if (deps.catchUpPageSize !== undefined && !_effect.Schema.is(CatchUpPageSize)(deps.catchUpPageSize)) {
180
+ return `subscribeItems: catchUpPageSize must be an integer greater than 0, got ${deps.catchUpPageSize}`;
181
+ }
182
+ return undefined;
141
183
  };
142
184
  /**
143
185
  * Retry a TRANSIENT poll fault (an `E` from one reconcile read) on a capped
@@ -146,16 +188,42 @@ const subscriptionTuningFields = exports.subscriptionTuningFields = {
146
188
  * past the cap propagates (the decorator dies it) — infrastructure stays off the
147
189
  * contract channel while the stream survives ordinary transients.
148
190
  */
149
- const POLL_RETRY_SCHEDULE = /*#__PURE__*/_effect.Schedule.exponential('100 millis', 2).pipe(/*#__PURE__*/_effect.Schedule.union(/*#__PURE__*/_effect.Schedule.spaced('2 seconds')), /*#__PURE__*/_effect.Schedule.intersect(/*#__PURE__*/_effect.Schedule.recurs(20)));
191
+ const POLL_RETRY_SCHEDULE = /*#__PURE__*/_effect.Schedule.max([/*#__PURE__*/_effect.Schedule.min([/*#__PURE__*/_effect.Schedule.exponential('100 millis', 2), /*#__PURE__*/_effect.Schedule.spaced('2 seconds')]), /*#__PURE__*/_effect.Schedule.recurs(20)]);
150
192
  /**
151
- * Build the subscription `Stream`: catch up from `after`, then track the live tail.
152
- * The cursor threads through the `unfoldChunkEffect` unfold state, starting at
153
- * `after` and advancing to the last delivered position each batch; the stream never
154
- * completes on its own (always `Option.some`), so the enclosing scope interrupts it
155
- * on close. An `E` mid-stream stays on the channel; `makeContractStore` dies it
156
- * (subscribe is `E = never` on the contract).
193
+ * Build a subscription `Stream` over any ascending-cursor source: catch up from
194
+ * `initial`, then track the live tail. The cursor threads through the
195
+ * `Stream.paginate` state, starting at `initial` and advancing to the cursor of the
196
+ * last delivered item each batch; the stream never completes on its own (the next
197
+ * state is always `Option.some`), so the enclosing scope interrupts it on close. An
198
+ * `E` mid-stream stays on the channel, for the caller to die or to supervise.
199
+ *
200
+ * This is THE delivery algorithm, and `subscribeStream` runs the same machine. Under
201
+ * `emit: 'backlog'` a batch is everything a drain to the tail returned; under
202
+ * `'page'` it is one fetched page, so the paginate step and the page coincide and a
203
+ * full page is followed at once by the next read rather than by a wait.
204
+ *
205
+ * A `pollInterval` or `catchUpPageSize` the config fields would refuse is a DEFECT
206
+ * here, raised by the stream before it reads or forks anything, with a message
207
+ * naming the field. This caller may have no config whose decode would have caught
208
+ * it, and unchecked the two failures are silent or late: a page size of 0 gives a
209
+ * stream that never emits and never fails, and 1.5 dies only at the first read,
210
+ * inside `ReadLimit`, in words that name neither knob.
157
211
  */
158
- const subscribeStream = (deps, after) => _effect.Stream.unwrapScoped(_effect.Effect.gen(function* () {
212
+ const subscribeItems = deps => {
213
+ const fault = tuningFault(deps);
214
+ return fault === undefined ? machine(deps) : _effect.Stream.die(new Error(fault));
215
+ };
216
+ /**
217
+ * The machine itself, with no check of its tuning. `subscribeStream` runs it
218
+ * directly, and deliberately: the event path stays exactly as it was, with no
219
+ * second check of figures each SQL engine has already decoded from its config
220
+ * through the same bounds, and the in-memory store's are a test's own options.
221
+ */
222
+ exports.subscribeItems = subscribeItems;
223
+ const machine = deps => _effect.Stream.unwrap(_effect.Effect.gen(function* () {
224
+ const pageSize = deps.catchUpPageSize ?? DEFAULT_CATCH_UP_PAGE_SIZE;
225
+ const pollInterval = deps.pollInterval ?? DEFAULT_POLL_INTERVAL_MILLIS;
226
+ const limit = _Event.ReadLimit.make(pageSize);
159
227
  // The wake primitive: a sliding(1) queue holding at most one pending
160
228
  // signal. The wake source `offer`s an opaque wake on every notification;
161
229
  // the poll loop `take`s (with a timeout). The lost-wakeup guard is
@@ -171,65 +239,88 @@ const subscribeStream = (deps, after) => _effect.Stream.unwrapScoped(_effect.Eff
171
239
  // silently-dropped (and later re-established) wake source loses no
172
240
  // positions. Absent a wake source entirely, `Stream.never` makes this a
173
241
  // fibre that parks forever and delivery falls to the poll alone.
174
- const listener = (deps.listen ?? _effect.Stream.never).pipe(_effect.Stream.tap(() => _effect.Queue.offer(wake, undefined)), _effect.Stream.retry(_effect.Schedule.exponential('50 millis').pipe(_effect.Schedule.union(_effect.Schedule.spaced('1 seconds')))));
242
+ const listener = (deps.listen ?? _effect.Stream.never).pipe(_effect.Stream.tap(() => _effect.Queue.offer(wake, undefined)), _effect.Stream.retry(_effect.Schedule.min([_effect.Schedule.exponential('50 millis'), _effect.Schedule.spaced('1 seconds')])));
175
243
  // Drain the wake source into the wake queue on a background fibre; the
176
244
  // scope releases it. We never read its elements directly — every
177
245
  // notification is an opaque wake signal.
178
246
  yield* listener.pipe(_effect.Stream.runDrain, _effect.Effect.forkScoped);
247
+ // One page strictly after `from`: the step `drainFrom` loops, and the whole
248
+ // of a `'page'` read.
249
+ const fetchPage = from => deps.fetch(from, limit);
179
250
  // Reconcile: page-read from `from` until a short page, advancing to the last
180
- // delivered position. Retries a TRANSIENT poll fault on a capped schedule so
251
+ // delivered cursor. Retries a TRANSIENT poll fault on a capped schedule so
181
252
  // a single connection blip does not kill a days-long subscription; a
182
- // persistent fault propagates and dies.
253
+ // persistent fault propagates. The retry wraps the WHOLE drain, so a fault on
254
+ // page three re-reads pages one and two: nothing has been emitted yet, so
255
+ // that costs reads and never a duplicate.
183
256
  const drainFrom = from => _effect.Effect.gen(function* () {
184
257
  const collected = [];
185
258
  let cursor = from;
186
259
  // Loop pages until a short page signals the tail is drained.
187
260
  while (true) {
188
- const events = yield* deps.fetch(cursor, _Event.ReadLimit.make(deps.catchUpPageSize));
189
- for (const event of events) {
190
- collected.push(event);
261
+ const items = yield* fetchPage(cursor);
262
+ for (const item of items) {
263
+ collected.push(item);
191
264
  }
192
- const lastEvent = events.at(-1);
193
- if (lastEvent === undefined || events.length < deps.catchUpPageSize) {
265
+ const lastItem = items.at(-1);
266
+ if (lastItem === undefined || items.length < pageSize) {
194
267
  break;
195
268
  }
196
- cursor = lastEvent.position;
269
+ cursor = deps.cursorOf(lastItem);
197
270
  }
198
- const last = collected.at(-1)?.position ?? from;
199
- return {
200
- events: collected,
201
- last
202
- };
271
+ return collected;
203
272
  }).pipe(_effect.Effect.retry(POLL_RETRY_SCHEDULE));
273
+ // The read one paginate step performs, by emission mode. Under `'page'` the
274
+ // retry wraps the single page, which is the whole of what is unemitted.
275
+ const read = (deps.emit ?? 'backlog') === 'page' ? from => fetchPage(from).pipe(_effect.Effect.retry(POLL_RETRY_SCHEDULE)) : drainFrom;
204
276
  /**
205
- * Produce the NEXT non-empty batch from a cursor position, together with
206
- * the advanced cursor — a pure `Position → Effect<[Chunk, next]>`. The
207
- * `> boundary` de-dup is enforced by `fetch`'s exclusive lower bound, so a
208
- * live re-read after a wake never re-emits an already-delivered position.
277
+ * Produce the NEXT non-empty batch from a cursor, together with the advanced
278
+ * cursor — a pure `C → Effect<[items, next]>`. The `> boundary` de-dup is
279
+ * enforced by `fetch`'s exclusive lower bound, so a live re-read after a wake
280
+ * never re-emits an already-delivered item.
209
281
  *
210
- * Drain the wake queue BEFORE reading (lost-wakeup guard), then drain from
211
- * the cursor. If a drain yields nothing, wait for a wake but only up to the
212
- * poll interval, then loop and re-read ANYWAY — the periodic position-based
213
- * poll that makes delivery correct independently of any wake. This effect
214
- * only completes by returning a non-empty chunk; the scope interrupts it on
215
- * close.
282
+ * Drain the wake queue BEFORE reading (lost-wakeup guard), then read from the
283
+ * cursor. If a read yields nothing, wait for a wake but only up to the poll
284
+ * interval, then loop and re-read ANYWAY — the periodic cursor-based poll that
285
+ * makes delivery correct independently of any wake. This effect only
286
+ * completes by returning a non-empty batch; the scope interrupts it on close.
216
287
  */
217
288
  const nextBatch = from => _effect.Effect.gen(function* () {
218
289
  while (true) {
219
- yield* _effect.Queue.takeAll(wake);
220
- const {
221
- events,
222
- last
223
- } = yield* drainFrom(from);
224
- if (events.length > 0) {
225
- return [_effect.Chunk.fromIterable(events), last];
290
+ // `Queue.clear` and not `Queue.takeAll`: the drain must NOT wait, and
291
+ // `takeAll` suspends until at least one signal is present.
292
+ yield* _effect.Queue.clear(wake);
293
+ const items = yield* read(from);
294
+ const last = items.at(-1);
295
+ if (last !== undefined) {
296
+ return [items, deps.cursorOf(last)];
226
297
  }
227
298
  // Nothing new: block on a wake, but only up to the poll interval — on
228
299
  // timeout we fall through and the loop re-reads regardless.
229
- yield* _effect.Effect.ignore(_effect.Effect.timeout(_effect.Queue.take(wake), deps.pollInterval));
300
+ yield* _effect.Effect.ignore(_effect.Effect.timeout(_effect.Queue.take(wake), pollInterval));
230
301
  }
231
302
  });
232
- return _effect.Stream.unfoldChunkEffect(after ?? _Event.ORIGIN, from => _effect.Effect.map(nextBatch(from), _effect.Option.some));
303
+ return _effect.Stream.paginate(deps.initial, from => _effect.Effect.map(nextBatch(from), ([items, next]) => [items, _effect.Option.some(next)]));
233
304
  }));
305
+ /**
306
+ * Build the event subscription `Stream`: catch up from `after`, then track the live
307
+ * tail. A THIN wrapper over the machine `subscribeItems` runs, fixing the item to
308
+ * `SequencedEvent`, the cursor to its `position`, the start to `ORIGIN` when `after`
309
+ * is absent, and the emission to the default `'backlog'` — so every engine's call
310
+ * site, and every figure it delivers, is what it was before the machine became
311
+ * generic. It skips `subscribeItems`' tuning check, for the reason on `machine`. An `E`
312
+ * mid-stream stays on the channel; `makeContractStore` dies it (subscribe is
313
+ * `E = never` on the contract).
314
+ */
315
+ const subscribeStream = (deps, after) => machine({
316
+ fetch: deps.fetch,
317
+ cursorOf: event => event.position,
318
+ initial: after ?? _Event.ORIGIN,
319
+ ...(deps.listen === undefined ? {} : {
320
+ listen: deps.listen
321
+ }),
322
+ pollInterval: deps.pollInterval,
323
+ catchUpPageSize: deps.catchUpPageSize
324
+ });
234
325
  exports.subscribeStream = subscribeStream;
235
326
  //# sourceMappingURL=SubscribeMachine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SubscribeMachine.js","names":["_effect","require","_Event","DEFAULT_CATCH_UP_PAGE_SIZE","exports","DEFAULT_POLL_INTERVAL_MILLIS","subscriptionTuningFields","pollInterval","Schema","optionalWith","Number","pipe","positive","finite","exact","catchUpPageSize","Int","POLL_RETRY_SCHEDULE","Schedule","exponential","union","spaced","intersect","recurs","subscribeStream","deps","after","Stream","unwrapScoped","Effect","gen","wake","Queue","sliding","listener","listen","never","tap","offer","undefined","retry","runDrain","forkScoped","drainFrom","from","collected","cursor","events","fetch","ReadLimit","make","event","push","lastEvent","at","length","position","last","nextBatch","takeAll","Chunk","fromIterable","ignore","timeout","take","unfoldChunkEffect","ORIGIN","map","Option","some"],"sources":["../../src/SubscribeMachine.ts"],"sourcesContent":[null],"mappings":";;;;;;AAsEA,IAAAA,OAAA,GAAAC,OAAA;AAWA,IAAAC,MAAA,GAAAD,OAAA;AAjFA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmFA;;;;;;;AAOO,MAAME,0BAA0B,GAAAC,OAAA,CAAAD,0BAAA,GAAG,GAAG;AAE7C;;;;;;;;;;;;;;;;AAgBO,MAAME,4BAA4B,GAAAD,OAAA,CAAAC,4BAAA,GAAG,IAAI;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BO,MAAMC,wBAAwB,GAAAF,OAAA,CAAAE,wBAAA,GAAG;EACtCC,YAAY,eAAEC,cAAM,CAACC,YAAY,cAC/BD,cAAM,CAACE,MAAM,CAACC,IAAI,cAACH,cAAM,CAACI,QAAQ,EAAE,eAAEJ,cAAM,CAACK,MAAM,EAAE,CAAC,EACtD;IAAEC,KAAK,EAAE;EAAI,CAAE,CAChB;EACDC,eAAe,eAAEP,cAAM,CAACC,YAAY,cAACD,cAAM,CAACQ,GAAG,CAACL,IAAI,cAACH,cAAM,CAACI,QAAQ,EAAE,CAAC,EAAE;IACvEE,KAAK,EAAE;GACR;CACO;AAEV;;;;;;;AAOA,MAAMG,mBAAmB,gBAAGC,gBAAQ,CAACC,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC,CAACR,IAAI,cACpEO,gBAAQ,CAACE,KAAK,cAACF,gBAAQ,CAACG,MAAM,CAAC,WAAW,CAAC,CAAC,eAC5CH,gBAAQ,CAACI,SAAS,cAACJ,gBAAQ,CAACK,MAAM,CAAC,EAAE,CAAC,CAAC,CACxC;AAwCD;;;;;;;;AAQO,MAAMC,eAAe,GAAGA,CAC7BC,IAAyB,EACzBC,KAA2B,KAE3BC,cAAM,CAACC,YAAY,CACjBC,cAAM,CAACC,GAAG,CAAC,aAAS;EAClB;EACA;EACA;EACA;EACA;EACA;EACA,MAAMC,IAAI,GAAG,OAAOC,aAAK,CAACC,OAAO,CAAO,CAAC,CAAC;EAE1C;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAMC,QAAQ,GAAG,CAACT,IAAI,CAACU,MAAM,IAAIR,cAAM,CAACS,KAAK,EAAEzB,IAAI,CACjDgB,cAAM,CAACU,GAAG,CAAC,MAAML,aAAK,CAACM,KAAK,CAACP,IAAI,EAAEQ,SAAS,CAAC,CAAC,EAC9CZ,cAAM,CAACa,KAAK,CACVtB,gBAAQ,CAACC,WAAW,CAAC,WAAW,CAAC,CAACR,IAAI,CACpCO,gBAAQ,CAACE,KAAK,CAACF,gBAAQ,CAACG,MAAM,CAAC,WAAW,CAAC,CAAC,CAC7C,CACF,CACF;EACD;EACA;EACA;EACA,OAAOa,QAAQ,CAACvB,IAAI,CAACgB,cAAM,CAACc,QAAQ,EAAEZ,cAAM,CAACa,UAAU,CAAC;EAExD;EACA;EACA;EACA;EACA,MAAMC,SAAS,GACbC,IAAc,IAQdf,cAAM,CAACC,GAAG,CAAC,aAAS;IAClB,MAAMe,SAAS,GAA0B,EAAE;IAC3C,IAAIC,MAAM,GAAGF,IAAI;IACjB;IACA,OAAO,IAAI,EAAE;MACX,MAAMG,MAAM,GAAG,OAAOtB,IAAI,CAACuB,KAAK,CAC9BF,MAAM,EACNG,gBAAS,CAACC,IAAI,CAACzB,IAAI,CAACV,eAAe,CAAC,CACrC;MACD,KAAK,MAAMoC,KAAK,IAAIJ,MAAM,EAAE;QAC1BF,SAAS,CAACO,IAAI,CAACD,KAAK,CAAC;MACvB;MACA,MAAME,SAAS,GAAGN,MAAM,CAACO,EAAE,CAAC,CAAC,CAAC,CAAC;MAC/B,IACED,SAAS,KAAKd,SAAS,IACvBQ,MAAM,CAACQ,MAAM,GAAG9B,IAAI,CAACV,eAAe,EACpC;QACA;MACF;MACA+B,MAAM,GAAGO,SAAS,CAACG,QAAQ;IAC7B;IACA,MAAMC,IAAI,GAAGZ,SAAS,CAACS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAEE,QAAQ,IAAIZ,IAAI;IAC/C,OAAO;MAAEG,MAAM,EAAEF,SAAS;MAAEY;IAAI,CAAE;EACpC,CAAC,CAAC,CAAC9C,IAAI,CAACkB,cAAM,CAACW,KAAK,CAACvB,mBAAmB,CAAC,CAAC;EAE5C;;;;;;;;;;;;;EAaA,MAAMyC,SAAS,GACbd,IAAc,IAEdf,cAAM,CAACC,GAAG,CAAC,aAAS;IAClB,OAAO,IAAI,EAAE;MACX,OAAOE,aAAK,CAAC2B,OAAO,CAAC5B,IAAI,CAAC;MAC1B,MAAM;QAAEgB,MAAM;QAAEU;MAAI,CAAE,GAAG,OAAOd,SAAS,CAACC,IAAI,CAAC;MAC/C,IAAIG,MAAM,CAACQ,MAAM,GAAG,CAAC,EAAE;QACrB,OAAO,CAACK,aAAK,CAACC,YAAY,CAACd,MAAM,CAAC,EAAEU,IAAI,CAAU;MACpD;MACA;MACA;MACA,OAAO5B,cAAM,CAACiC,MAAM,CAClBjC,cAAM,CAACkC,OAAO,CAAC/B,aAAK,CAACgC,IAAI,CAACjC,IAAI,CAAC,EAAEN,IAAI,CAAClB,YAAY,CAAC,CACpD;IACH;EACF,CAAC,CAAC;EAEJ,OAAOoB,cAAM,CAACsC,iBAAiB,CAACvC,KAAK,IAAIwC,aAAM,EAAGtB,IAAI,IACpDf,cAAM,CAACsC,GAAG,CAACT,SAAS,CAACd,IAAI,CAAC,EAAEwB,cAAM,CAACC,IAAI,CAAC,CACzC;AACH,CAAC,CAAC,CACH;AAAAjE,OAAA,CAAAoB,eAAA,GAAAA,eAAA","ignoreList":[]}
1
+ {"version":3,"file":"SubscribeMachine.js","names":["_effect","require","_Event","DEFAULT_CATCH_UP_PAGE_SIZE","exports","DEFAULT_POLL_INTERVAL_MILLIS","PollIntervalMillis","Schema","Number","check","isGreaterThan","isFinite","CatchUpPageSize","Int","subscriptionTuningFields","pollInterval","optionalKey","catchUpPageSize","tuningFault","deps","undefined","is","POLL_RETRY_SCHEDULE","Schedule","max","min","exponential","spaced","recurs","subscribeItems","fault","machine","Stream","die","Error","unwrap","Effect","gen","pageSize","limit","ReadLimit","make","wake","Queue","sliding","listener","listen","never","pipe","tap","offer","retry","runDrain","forkScoped","fetchPage","from","fetch","drainFrom","collected","cursor","items","item","push","lastItem","at","length","cursorOf","read","emit","nextBatch","clear","last","ignore","timeout","take","paginate","initial","map","next","Option","some","subscribeStream","after","event","position","ORIGIN"],"sources":["../../src/SubscribeMachine.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -43,7 +43,7 @@ const copyEvent = event => ({
43
43
  data: new Uint8Array(event.data),
44
44
  tags: [...event.tags],
45
45
  uuid: event.uuid,
46
- occurredAt: _effect.DateTime.unsafeMake(_effect.DateTime.toEpochMillis(event.occurredAt)),
46
+ occurredAt: _effect.DateTime.makeUnsafe(_effect.DateTime.toEpochMillis(event.occurredAt)),
47
47
  metadata: {
48
48
  ...event.metadata
49
49
  }
@@ -158,7 +158,7 @@ const make = options => _effect.Effect.gen(function* () {
158
158
  const catchUpPageSize = options?.catchUpPageSize ?? _SubscribeMachine.DEFAULT_CATCH_UP_PAGE_SIZE;
159
159
  const pollInterval = options?.pollInterval ?? _SubscribeMachine.DEFAULT_POLL_INTERVAL_MILLIS;
160
160
  const log = yield* _effect.Ref.make([]);
161
- const mutex = yield* _effect.Effect.makeSemaphore(1);
161
+ const mutex = yield* _effect.Semaphore.make(1);
162
162
  const hub = yield* _effect.PubSub.unbounded();
163
163
  const nextPosition = yield* _effect.Ref.make(1n);
164
164
  const read = (query, options) =>
@@ -225,14 +225,14 @@ const make = options => _effect.Effect.gen(function* () {
225
225
  // exclusive cursor is what makes the catch-up/live seam exactly-once, so there
226
226
  // is nothing left here for a critical section to protect. `append` keeps its
227
227
  // permit, which is the whole exactly-one-wins guarantee.
228
- _effect.Stream.unwrapScoped(_effect.Effect.gen(function* () {
228
+ _effect.Stream.unwrap(_effect.Effect.gen(function* () {
229
229
  // Taken when the subscription starts, as the SQL engines compile theirs
230
230
  // (see `copyQuery`).
231
231
  const judged = copyQuery(query);
232
232
  const wakes = yield* _effect.PubSub.subscribe(hub);
233
233
  return (0, _SubscribeMachine.subscribeStream)({
234
234
  fetch: (from, limit) => _effect.Effect.map(_effect.Ref.get(log), snapshot => fetchPage(snapshot, judged, from, limit)),
235
- listen: _effect.Stream.fromQueue(wakes),
235
+ listen: _effect.Stream.fromSubscription(wakes),
236
236
  pollInterval,
237
237
  catchUpPageSize
238
238
  }, after);
@@ -1 +1 @@
1
- {"version":3,"file":"inMemory.js","names":["_effect","require","_ContractStore","_DcbEventStore","_Event","_errors","_Query","_SubscribeMachine","copyEvent","event","type","data","Uint8Array","tags","uuid","occurredAt","DateTime","unsafeMake","toEpochMillis","metadata","copyQuery","query","items","map","item","types","copySequenced","sequenced","position","filterLog","log","after","filter","undefined","matchesSequenced","lastPosition","events","at","readSnapshot","options","matched","limited","limit","slice","head","ORIGIN","Stream","fromIterable","firstIndexAfter","low","high","length","mid","fetchPage","from","page","index","push","make","Effect","gen","beforeCommit","void","suppressWake","catchUpPageSize","DEFAULT_CATCH_UP_PAGE_SIZE","pollInterval","DEFAULT_POLL_INTERVAL_MILLIS","Ref","mutex","makeSemaphore","hub","PubSub","unbounded","nextPosition","read","withPermits","get","snapshot","append","condition","suspend","owned","conflicts","failIfEventsMatch","AppendConditionFailed","start","appended","BigInt","end","set","publishAll","subscribe","unwrapScoped","judged","wakes","subscribeStream","fetch","listen","fromQueue","DcbEventStoreInMemory","exports","Layer","effect","DcbEventStore","makeContractStore","makeInMemoryTestLayer"],"sources":["../../src/inMemory.ts"],"sourcesContent":[null],"mappings":";;;;;;AA2BA,IAAAA,OAAA,GAAAC,OAAA;AAEA,IAAAC,cAAA,GAAAD,OAAA;AAEA,IAAAE,cAAA,GAAAF,OAAA;AAEA,IAAAG,MAAA,GAAAH,OAAA;AACA,IAAAI,OAAA,GAAAJ,OAAA;AAEA,IAAAK,MAAA,GAAAL,OAAA;AACA,IAAAM,iBAAA,GAAAN,OAAA;AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,MAAMO,SAAS,GAAIC,KAAe,KAAgB;EAChDC,IAAI,EAAED,KAAK,CAACC,IAAI;EAChBC,IAAI,EAAE,IAAIC,UAAU,CAACH,KAAK,CAACE,IAAI,CAAC;EAChCE,IAAI,EAAE,CAAC,GAAGJ,KAAK,CAACI,IAAI,CAAC;EACrBC,IAAI,EAAEL,KAAK,CAACK,IAAI;EAChBC,UAAU,EAAEC,gBAAQ,CAACC,UAAU,CAACD,gBAAQ,CAACE,aAAa,CAACT,KAAK,CAACM,UAAU,CAAC,CAAC;EACzEI,QAAQ,EAAE;IAAE,GAAGV,KAAK,CAACU;EAAQ;CAC9B,CAAC;AAEF;;;;;;;;;;;;;AAaA,MAAMC,SAAS,GAAIC,KAAY,KAAa;EAC1CC,KAAK,EAAED,KAAK,CAACC,KAAK,CAACC,GAAG,CAAEC,IAAI,KAAM;IAChCC,KAAK,EAAE,CAAC,GAAGD,IAAI,CAACC,KAAK,CAAC;IACtBZ,IAAI,EAAE,CAAC,GAAGW,IAAI,CAACX,IAAI;GACpB,CAAC;CACH,CAAC;AAEF;AACA,MAAMa,aAAa,GAAIC,SAAyB,KAAsB;EACpElB,KAAK,EAAED,SAAS,CAACmB,SAAS,CAAClB,KAAK,CAAC;EACjCmB,QAAQ,EAAED,SAAS,CAACC;CACrB,CAAC;AAEF;AACA,MAAMC,SAAS,GAAGA,CAChBC,GAAkC,EAClCT,KAAY,EACZU,KAA2B,KAE3BD,GAAG,CAACE,MAAM,CACPL,SAAS,IACR,CAACI,KAAK,KAAKE,SAAS,IAAIN,SAAS,CAACC,QAAQ,GAAGG,KAAK,KAClD,IAAAG,uBAAgB,EAACP,SAAS,EAAEN,KAAK,CAAC,CACrC;AAEH;AACA,MAAMc,YAAY,GAChBC,MAAqC,IACZA,MAAM,CAACC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAET,QAAQ;AAElD;;;;;AAKA,MAAMU,YAAY,GAAGA,CACnBR,GAAkC,EAClCT,KAAY,EACZkB,OAAgC,KAChB;EAChB,MAAMC,OAAO,GAAGX,SAAS,CAACC,GAAG,EAAET,KAAK,EAAEkB,OAAO,EAAER,KAAK,CAAC;EACrD,MAAMU,OAAO,GACXF,OAAO,EAAEG,KAAK,KAAKT,SAAS,GAAGO,OAAO,GAAGA,OAAO,CAACG,KAAK,CAAC,CAAC,EAAEJ,OAAO,CAACG,KAAK,CAAC;EAE1E;EACA;EACA;EACA,MAAME,IAAI,GACR,CAACL,OAAO,EAAEG,KAAK,KAAKT,SAAS,GACzBE,YAAY,CAACL,GAAG,CAAC,GACjBK,YAAY,CAACM,OAAO,CAAC,KAAKI,aAAM;EAEtC,OAAO;IAAET,MAAM,EAAEU,cAAM,CAACC,YAAY,CAACN,OAAO,CAAClB,GAAG,CAACG,aAAa,CAAC,CAAC;IAAEkB;EAAI,CAAE;AAC1E,CAAC;AAED;;;;;;;;;AASA,MAAMI,eAAe,GAAGA,CACtBlB,GAAkC,EAClCC,KAAe,KACL;EACV,IAAIkB,GAAG,GAAG,CAAC;EACX,IAAIC,IAAI,GAAGpB,GAAG,CAACqB,MAAM;EACrB,OAAOF,GAAG,GAAGC,IAAI,EAAE;IACjB;IACA,MAAME,GAAG,GAAIH,GAAG,GAAGC,IAAI,KAAM,CAAC;IAC9B,IAAIpB,GAAG,CAACsB,GAAG,CAAC,CAACxB,QAAQ,GAAGG,KAAK,EAAE;MAC7BmB,IAAI,GAAGE,GAAG;IACZ,CAAC,MAAM;MACLH,GAAG,GAAGG,GAAG,GAAG,CAAC;IACf;EACF;EACA,OAAOH,GAAG;AACZ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;AAoBA,MAAMI,SAAS,GAAGA,CAChBvB,GAAkC,EAClCT,KAAY,EACZiC,IAAc,EACdZ,KAAgB,KACiB;EACjC,MAAMa,IAAI,GAA0B,EAAE;EACtC,KACE,IAAIC,KAAK,GAAGR,eAAe,CAAClB,GAAG,EAAEwB,IAAI,CAAC,EACtCE,KAAK,GAAG1B,GAAG,CAACqB,MAAM,IAAII,IAAI,CAACJ,MAAM,GAAGT,KAAK,EACzCc,KAAK,IAAI,CAAC,EACV;IACA,MAAM7B,SAAS,GAAGG,GAAG,CAAC0B,KAAK,CAAC;IAC5B,IAAI,IAAAtB,uBAAgB,EAACP,SAAS,EAAEN,KAAK,CAAC,EAAE;MACtCkC,IAAI,CAACE,IAAI,CAAC/B,aAAa,CAACC,SAAS,CAAC,CAAC;IACrC;EACF;EACA,OAAO4B,IAAI;AACb,CAAC;AA8DD;;;;;;AAMA,MAAMG,IAAI,GACRnB,OAA8B,IAE9BoB,cAAM,CAACC,GAAG,CAAC,aAAS;EAClB,MAAMC,YAAY,GAAGtB,OAAO,EAAEsB,YAAY,IAAIF,cAAM,CAACG,IAAI;EACzD,MAAMC,YAAY,GAAGxB,OAAO,EAAEwB,YAAY,IAAI,KAAK;EACnD,MAAMC,eAAe,GACnBzB,OAAO,EAAEyB,eAAe,IAAIC,4CAA0B;EACxD,MAAMC,YAAY,GAAG3B,OAAO,EAAE2B,YAAY,IAAIC,8CAA4B;EAC1E,MAAMrC,GAAG,GAAG,OAAOsC,WAAG,CAACV,IAAI,CAAgC,EAAE,CAAC;EAC9D,MAAMW,KAAK,GAAG,OAAOV,cAAM,CAACW,aAAa,CAAC,CAAC,CAAC;EAC5C,MAAMC,GAAG,GAAG,OAAOC,cAAM,CAACC,SAAS,EAAkB;EACrD,MAAMC,YAAY,GAAG,OAAON,WAAG,CAACV,IAAI,CAAS,EAAE,CAAC;EAEhD,MAAMiB,IAAI,GAAGA,CACXtD,KAAY,EACZkB,OAAqB;EAErB;EACA;EACA;EACA8B,KAAK,CAACO,WAAW,CAAC,CAAC,CAAC,CAClBjB,cAAM,CAACpC,GAAG,CAAC6C,WAAG,CAACS,GAAG,CAAC/C,GAAG,CAAC,EAAGgD,QAAQ,IAChCxC,YAAY,CAACwC,QAAQ,EAAEzD,KAAK,EAAEkB,OAAO,CAAC,CACvC,CACF;EAEH,MAAMwC,MAAM,GAAGA,CACb3C,MAA2C,EAC3C4C,SAA2B,KAE3BrB,cAAM,CAACsB,OAAO,CAAC,MAAK;IAClB;IACA;IACA;IACA;IACA,MAAMC,KAAK,GAAG9C,MAAM,CAACb,GAAG,CAACf,SAAS,CAAC;IACnC;IACA,OAAO6D,KAAK,CAACO,WAAW,CAAC,CAAC,CAAC,CACzBjB,cAAM,CAACC,GAAG,CAAC,aAAS;MAClB,MAAMkB,QAAQ,GAAG,OAAOV,WAAG,CAACS,GAAG,CAAC/C,GAAG,CAAC;MAEpC,IAAIkD,SAAS,KAAK/C,SAAS,EAAE;QAC3B,MAAMkD,SAAS,GAAGtD,SAAS,CACzBiD,QAAQ,EACRE,SAAS,CAACI,iBAAiB,EAC3BJ,SAAS,CAACjD,KAAK,CAChB;QACD;QACA;QACA;QACA,IAAIoD,SAAS,CAAChC,MAAM,GAAG,CAAC,EAAE;UACxB,OAAO,OAAO,IAAIkC,6BAAqB,CAAC;YAAEL;UAAS,CAAE,CAAC;QACxD;MACF;MAEA;MACA;MACA;MACA;MACA;MACA,OAAOnB,YAAY;MAEnB,MAAMyB,KAAK,GAAG,OAAOlB,WAAG,CAACS,GAAG,CAACH,YAAY,CAAC;MAC1C,MAAMa,QAAQ,GAA0BL,KAAK,CAAC3D,GAAG,CAC/C,CAACd,KAAK,EAAE+C,KAAK,MAAM;QACjB/C,KAAK;QACLmB,QAAQ,EAAG0D,KAAK,GAAGE,MAAM,CAAChC,KAAK;OAChC,CAAC,CACH;MACD,MAAMiC,GAAG,GAAGH,KAAK,GAAGE,MAAM,CAACpD,MAAM,CAACe,MAAM,CAAC;MACzC,OAAOiB,WAAG,CAACsB,GAAG,CAAC5D,GAAG,EAAE,CAAC,GAAGgD,QAAQ,EAAE,GAAGS,QAAQ,CAAC,CAAC;MAC/C,OAAOnB,WAAG,CAACsB,GAAG,CAAChB,YAAY,EAAEe,GAAG,CAAC;MACjC;MACA;MACA;MACA;MACA,IAAI,CAAC1B,YAAY,EAAE;QACjB,OAAOS,cAAM,CAACmB,UAAU,CAACpB,GAAG,EAAEgB,QAAQ,CAAC;MACzC;MACA;MACA,OAAQE,GAAG,GAAG,EAAE;IAClB,CAAC,CAAC,CACH;EACH,CAAC,CAAC;EAEJ,MAAMG,SAAS,GAAGA,CAChBvE,KAAY,EACZU,KAAgB;EAEhB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACAe,cAAM,CAAC+C,YAAY,CACjBlC,cAAM,CAACC,GAAG,CAAC,aAAS;IAClB;IACA;IACA,MAAMkC,MAAM,GAAG1E,SAAS,CAACC,KAAK,CAAC;IAC/B,MAAM0E,KAAK,GAAG,OAAOvB,cAAM,CAACoB,SAAS,CAACrB,GAAG,CAAC;IAC1C,OAAO,IAAAyB,iCAAe,EACpB;MACEC,KAAK,EAAEA,CAAC3C,IAAI,EAAEZ,KAAK,KACjBiB,cAAM,CAACpC,GAAG,CAAC6C,WAAG,CAACS,GAAG,CAAC/C,GAAG,CAAC,EAAGgD,QAAQ,IAChCzB,SAAS,CAACyB,QAAQ,EAAEgB,MAAM,EAAExC,IAAI,EAAEZ,KAAK,CAAC,CACzC;MACHwD,MAAM,EAAEpD,cAAM,CAACqD,SAAS,CAACJ,KAAK,CAAC;MAC/B7B,YAAY;MACZF;KACD,EACDjC,KAAK,CACN;EACH,CAAC,CAAC,CACH;EAEH,OAAO;IAAE4C,IAAI;IAAEI,MAAM;IAAEa;EAAS,CAAW;AAC7C,CAAC,CAAC;AAEJ;AACO,MAAMQ,qBAAqB,GAAAC,OAAA,CAAAD,qBAAA,gBAA+BE,aAAK,CAACC,MAAM,CAC3EC,4BAAa,eACb7C,cAAM,CAACpC,GAAG,cAACmC,IAAI,EAAE,EAAE+C,gCAAiB,CAAC,CACtC;AAED;;;;;;;;;;;AAWO,MAAMC,qBAAqB,GAChCnE,OAA6B,IAE7B+D,aAAK,CAACC,MAAM,CAACC,4BAAa,EAAE7C,cAAM,CAACpC,GAAG,CAACmC,IAAI,CAACnB,OAAO,CAAC,EAAEkE,gCAAiB,CAAC,CAAC;AAAAJ,OAAA,CAAAK,qBAAA,GAAAA,qBAAA","ignoreList":[]}
1
+ {"version":3,"file":"inMemory.js","names":["_effect","require","_ContractStore","_DcbEventStore","_Event","_errors","_Query","_SubscribeMachine","copyEvent","event","type","data","Uint8Array","tags","uuid","occurredAt","DateTime","makeUnsafe","toEpochMillis","metadata","copyQuery","query","items","map","item","types","copySequenced","sequenced","position","filterLog","log","after","filter","undefined","matchesSequenced","lastPosition","events","at","readSnapshot","options","matched","limited","limit","slice","head","ORIGIN","Stream","fromIterable","firstIndexAfter","low","high","length","mid","fetchPage","from","page","index","push","make","Effect","gen","beforeCommit","void","suppressWake","catchUpPageSize","DEFAULT_CATCH_UP_PAGE_SIZE","pollInterval","DEFAULT_POLL_INTERVAL_MILLIS","Ref","mutex","Semaphore","hub","PubSub","unbounded","nextPosition","read","withPermits","get","snapshot","append","condition","suspend","owned","conflicts","failIfEventsMatch","AppendConditionFailed","start","appended","BigInt","end","set","publishAll","subscribe","unwrap","judged","wakes","subscribeStream","fetch","listen","fromSubscription","DcbEventStoreInMemory","exports","Layer","effect","DcbEventStore","makeContractStore","makeInMemoryTestLayer"],"sources":["../../src/inMemory.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -42,21 +42,15 @@ var _effect = require("effect");
42
42
  * jitter draws from `Random.next`, a default service on the same footing as the
43
43
  * clock rather than a host `Math.random`. No `node:*`, no wall-clock reading, no
44
44
  * ungoverned RNG.
45
- *
46
- * Effect v3 caveat: the `Schedule` API below is the THREE-type-parameter
47
- * `Schedule<Out, In, R>` that `effect@3` exports, with `Schedule.intersect`. The
48
- * currently-published docs show a newer four-type-parameter `Schedule` without
49
- * `intersect` — do not copy them; this file is written against the installed
50
- * `effect@3` type definitions.
51
45
  */
52
46
 
53
47
  /**
54
48
  * The default conflict backoff: exponential from 20ms, jittered, capped at five
55
49
  * retries.
56
50
  *
57
- * `Schedule.intersect` continues only while BOTH schedules continue, so the
58
- * `recurs(5)` arm is what bounds the attempts and the exponential arm is what
59
- * spaces them. Jitter matters more here than in a typical backoff: contending
51
+ * `Schedule.max` continues only while BOTH schedules continue, waiting the longer
52
+ * of their two delays, so the `recurs(5)` arm is what bounds the attempts and the
53
+ * exponential arm is what spaces them. Jitter matters more here than in a typical backoff: contending
60
54
  * deciders conflict precisely because they read the same boundary at the same
61
55
  * time, so an unjittered backoff would re-synchronise them into the same conflict
62
56
  * on every round. The figures are the conventional starting point (Emmett,
@@ -64,7 +58,7 @@ var _effect = require("effect");
64
58
  * command with a tighter latency budget, or one contending harder, should pass its
65
59
  * own schedule.
66
60
  */
67
- const conflictBackoff = /*#__PURE__*/_effect.Schedule.intersect(/*#__PURE__*/_effect.Schedule.jittered(/*#__PURE__*/_effect.Schedule.exponential('20 millis', 2)), /*#__PURE__*/_effect.Schedule.recurs(5));
61
+ const conflictBackoff = /*#__PURE__*/_effect.Schedule.max([/*#__PURE__*/_effect.Schedule.jittered(/*#__PURE__*/_effect.Schedule.exponential('20 millis', 2)), /*#__PURE__*/_effect.Schedule.recurs(5)]);
68
62
  /**
69
63
  * Retry `command` while — and only while — it fails `AppendConditionFailed`.
70
64
  *
@@ -1 +1 @@
1
- {"version":3,"file":"retryOnConflict.js","names":["_effect","require","conflictBackoff","Schedule","intersect","jittered","exponential","recurs","retryOnConflict","command","schedule","Effect","retry","while","Predicate","isTagged","exports"],"sources":["../../src/retryOnConflict.ts"],"sourcesContent":[null],"mappings":";;;;;;AA4CA,IAAAA,OAAA,GAAAC,OAAA;AA5CA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA;;;;;;;;;;;;;;AAcA,MAAMC,eAAe,gBAAGC,gBAAQ,CAACC,SAAS,cACxCD,gBAAQ,CAACE,QAAQ,cAACF,gBAAQ,CAACG,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,eACvDH,gBAAQ,CAACI,MAAM,CAAC,CAAC,CAAC,CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;AAsBO,MAAMC,eAAe,GAAGA,CAC7BC,OAAuD,EACvDC,QAAA,GAIIR,eAAe,KAEnBS,cAAM,CAACC,KAAK,CAACH,OAAO,EAAE;EACpBC,QAAQ;EACRG,KAAK,EAAEC,iBAAS,CAACC,QAAQ,CAAC,uBAAuB;CAClD,CAAC;AAAAC,OAAA,CAAAR,eAAA,GAAAA,eAAA","ignoreList":[]}
1
+ {"version":3,"file":"retryOnConflict.js","names":["_effect","require","conflictBackoff","Schedule","max","jittered","exponential","recurs","retryOnConflict","command","schedule","Effect","retry","while","Predicate","isTagged","exports"],"sources":["../../src/retryOnConflict.ts"],"sourcesContent":[null],"mappings":";;;;;;AAsCA,IAAAA,OAAA,GAAAC,OAAA;AAtCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA;;;;;;;;;;;;;;AAcA,MAAMC,eAAe,gBAAGC,gBAAQ,CAACC,GAAG,CAAC,cACnCD,gBAAQ,CAACE,QAAQ,cAACF,gBAAQ,CAACG,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,eACvDH,gBAAQ,CAACI,MAAM,CAAC,CAAC,CAAC,CACnB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;AAsBO,MAAMC,eAAe,GAAGA,CAC7BC,OAAuD,EACvDC,QAAA,GAKIR,eAAe,KAEnBS,cAAM,CAACC,KAAK,CAACH,OAAO,EAAE;EACpBC,QAAQ;EACRG,KAAK,EAAEC,iBAAS,CAACC,QAAQ,CAAC,uBAAuB;CAClD,CAAC;AAAAC,OAAA,CAAAR,eAAA,GAAAA,eAAA","ignoreList":[]}
@@ -27,10 +27,10 @@ var _effect = require("effect");
27
27
  *
28
28
  * Ordering in the log is by `position` alone, so an event's `occurredAt` is
29
29
  * informational; pinning it to the epoch keeps serialised bytes and comparisons
30
- * stable across runs. Built via `DateTime.unsafeMake(0)` (the value is a
30
+ * stable across runs. Built via `DateTime.makeUnsafe(0)` (the value is a
31
31
  * compile-time constant, not read from the host clock).
32
32
  */
33
- const EPOCH = exports.EPOCH = /*#__PURE__*/_effect.DateTime.unsafeMake(0);
33
+ const EPOCH = exports.EPOCH = /*#__PURE__*/_effect.DateTime.makeUnsafe(0);
34
34
  /**
35
35
  * Build a fresh, deterministic uuid generator: a zero-based counter producing
36
36
  * RFC-4122 v4-shaped ids `00000000-0000-4000-8000-<counter as 12 hex digits>`,
@@ -1 +1 @@
1
- {"version":3,"file":"testing.js","names":["_effect","require","EPOCH","exports","DateTime","unsafeMake","makeSequentialUuid","counter","suffix","toString","padStart"],"sources":["../../src/testing.ts"],"sourcesContent":[null],"mappings":";;;;;;AAgBA,IAAAA,OAAA,GAAAC,OAAA;AAhBA;;;;;;;;;;;;;;;;;AAkBA;;;;;;;;AAQO,MAAMC,KAAK,GAAAC,OAAA,CAAAD,KAAA,gBAAGE,gBAAQ,CAACC,UAAU,CAAC,CAAC,CAAC;AAE3C;;;;;;;;;;;AAWO,MAAMC,kBAAkB,GAAGA,CAAA,KAAqB;EACrD,IAAIC,OAAO,GAAG,CAAC;EACf,OAAO,MAAK;IACV,MAAMC,MAAM,GAAGD,OAAO,CAACE,QAAQ,CAAC,EAAE,CAAC,CAACC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC;IACrDH,OAAO,IAAI,CAAC;IACZ,OAAO,2BAA2BC,MAAM,EAAE;EAC5C,CAAC;AACH,CAAC;AAAAL,OAAA,CAAAG,kBAAA,GAAAA,kBAAA","ignoreList":[]}
1
+ {"version":3,"file":"testing.js","names":["_effect","require","EPOCH","exports","DateTime","makeUnsafe","makeSequentialUuid","counter","suffix","toString","padStart"],"sources":["../../src/testing.ts"],"sourcesContent":[null],"mappings":";;;;;;AAgBA,IAAAA,OAAA,GAAAC,OAAA;AAhBA;;;;;;;;;;;;;;;;;AAkBA;;;;;;;;AAQO,MAAMC,KAAK,GAAAC,OAAA,CAAAD,KAAA,gBAAGE,gBAAQ,CAACC,UAAU,CAAC,CAAC,CAAC;AAE3C;;;;;;;;;;;AAWO,MAAMC,kBAAkB,GAAGA,CAAA,KAAqB;EACrD,IAAIC,OAAO,GAAG,CAAC;EACf,OAAO,MAAK;IACV,MAAMC,MAAM,GAAGD,OAAO,CAACE,QAAQ,CAAC,EAAE,CAAC,CAACC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC;IACrDH,OAAO,IAAI,CAAC;IACZ,OAAO,2BAA2BC,MAAM,EAAE;EAC5C,CAAC;AACH,CAAC;AAAAL,OAAA,CAAAG,kBAAA,GAAAA,kBAAA","ignoreList":[]}
@@ -9,15 +9,13 @@
9
9
  */
10
10
  import { Schema } from 'effect';
11
11
  export declare const AppendCondition: Schema.Struct<{
12
- failIfEventsMatch: Schema.Struct<{
13
- items: Schema.Array$<Schema.Struct<{
14
- types: Schema.Array$<Schema.brand<Schema.filter<typeof Schema.String>, "EventType">>;
15
- tags: Schema.Array$<Schema.brand<Schema.filter<typeof Schema.String>, "Tag">>;
12
+ readonly failIfEventsMatch: Schema.Struct<{
13
+ readonly items: Schema.$Array<Schema.Struct<{
14
+ readonly types: Schema.$Array<Schema.brand<Schema.String, "EventType">>;
15
+ readonly tags: Schema.$Array<Schema.brand<Schema.String, "Tag">>;
16
16
  }>>;
17
17
  }>;
18
- after: Schema.optionalWith<Schema.brand<Schema.filter<typeof Schema.BigInt>, "Position">, {
19
- exact: true;
20
- }>;
18
+ readonly after: Schema.optionalKey<Schema.brand<Schema.decodeTo<Schema.BigInt, Schema.String, never, never>, "Position">>;
21
19
  }>;
22
20
  export type AppendCondition = typeof AppendCondition.Type;
23
21
  //# sourceMappingURL=AppendCondition.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AppendCondition.d.ts","sourceRoot":"","sources":["../../src/AppendCondition.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAI/B,eAAO,MAAM,eAAe;;;;;;;;;;EAG1B,CAAA;AACF,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAA"}
1
+ {"version":3,"file":"AppendCondition.d.ts","sourceRoot":"","sources":["../../src/AppendCondition.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAI/B,eAAO,MAAM,eAAe;;;;;;;;EAG1B,CAAA;AACF,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAA"}
@@ -30,21 +30,21 @@
30
30
  *
31
31
  * ## Present means refused, so a sanctioned append REMOVES the marker
32
32
  *
33
- * The check reads the tag through `Effect.serviceOption`, so its ABSENCE is the
33
+ * The check reads the service through `Effect.serviceOption`, so its ABSENCE is the
34
34
  * normal case and costs the `append` signature nothing — `DcbEventStore.append`
35
35
  * keeps `R = never` and no caller provides anything. Presence is what refuses.
36
36
  *
37
37
  * That shape decides how the two legitimate appends inside a bracket get through,
38
38
  * and there is only one route: run with the marker STRIPPED from the context
39
- * (`Effect.mapInputContext` over `Context.omit(AppendIsOwned)`). The bracket's own
39
+ * (`Effect.updateContext` over `Context.omit(AppendIsOwned)`). The bracket's own
40
40
  * closing append is issued outside the scope it provided the marker in, and the
41
- * codec's escape hatch strips it explicitly. Neither needs a second tag, a
41
+ * codec's escape hatch strips it explicitly. Neither needs a second service, a
42
42
  * sanctioning flag or a mutable cell, and there is no way to be exempt by
43
43
  * accident: an append is either lexically outside the marked region or it says in
44
44
  * as many words that it is removing the marker.
45
45
  */
46
46
  import { Context, Effect } from 'effect';
47
- declare const AppendIsOwned_base: Context.TagClass<AppendIsOwned, "@kairos-es/core/AppendIsOwned", {
47
+ declare const AppendIsOwned_base: Context.ServiceClass<AppendIsOwned, "@kairos-es/core/AppendIsOwned", {
48
48
  readonly by: string;
49
49
  }>;
50
50
  /**
@@ -52,7 +52,7 @@ declare const AppendIsOwned_base: Context.TagClass<AppendIsOwned, "@kairos-es/co
52
52
  * owns it.
53
53
  *
54
54
  * `by` is a human-readable owner name and exists for the defect message alone —
55
- * the refusal is decided by the tag's PRESENCE, never by this value, so nothing
55
+ * the refusal is decided by the service's PRESENCE, never by this value, so nothing
56
56
  * branches on it and no caller need agree on a vocabulary for it.
57
57
  */
58
58
  export declare class AppendIsOwned extends AppendIsOwned_base {
@@ -69,7 +69,7 @@ export declare class AppendIsOwned extends AppendIsOwned_base {
69
69
  * its escape hatch for a deliberate second append — which is what makes a defect
70
70
  * affordable here.
71
71
  *
72
- * `Effect.serviceOption` is what keeps this free: it reads the tag if present and
72
+ * `Effect.serviceOption` is what keeps this free: it reads the service if present and
73
73
  * adds NOTHING to the requirement channel, so every existing append is unchanged
74
74
  * and unprovisioned.
75
75
  */
@@ -1 +1 @@
1
- {"version":3,"file":"AppendIsOwned.d.ts","sourceRoot":"","sources":["../../src/AppendIsOwned.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;;iBAYvB,MAAM;;AAVvB;;;;;;;GAOG;AACH,qBAAa,aAAc,SAAQ,kBAGhC;CAAG;AAEN;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAepD,CAAA"}
1
+ {"version":3,"file":"AppendIsOwned.d.ts","sourceRoot":"","sources":["../../src/AppendIsOwned.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;;iBAYvB,MAAM;;AAVvB;;;;;;;GAOG;AACH,qBAAa,aAAc,SAAQ,kBAGC;CAAG;AAEvC;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAepD,CAAA"}