@kairos-es/feed 0.0.0-stage → 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.
- package/LICENSE +28 -0
- package/README.md +109 -2
- package/dist/cjs/Feed.js +6 -0
- package/dist/cjs/Feed.js.map +1 -0
- package/dist/cjs/FeedSink.js +54 -0
- package/dist/cjs/FeedSink.js.map +1 -0
- package/dist/cjs/FeedSyncStore.js +10 -0
- package/dist/cjs/FeedSyncStore.js.map +1 -0
- package/dist/cjs/deliver.js +86 -0
- package/dist/cjs/deliver.js.map +1 -0
- package/dist/cjs/errors.js +114 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/identifiers.js +63 -0
- package/dist/cjs/identifiers.js.map +1 -0
- package/dist/cjs/inMemoryFeed.js +328 -0
- package/dist/cjs/inMemoryFeed.js.map +1 -0
- package/dist/cjs/inMemorySink.js +142 -0
- package/dist/cjs/inMemorySink.js.map +1 -0
- package/dist/cjs/index.js +184 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/inspect.js +68 -0
- package/dist/cjs/inspect.js.map +1 -0
- package/dist/cjs/readiness.js +100 -0
- package/dist/cjs/readiness.js.map +1 -0
- package/dist/cjs/reconcile.js +164 -0
- package/dist/cjs/reconcile.js.map +1 -0
- package/dist/cjs/runFeedSync.js +603 -0
- package/dist/cjs/runFeedSync.js.map +1 -0
- package/dist/cjs/tuning.js +60 -0
- package/dist/cjs/tuning.js.map +1 -0
- package/dist/dts-cjs/Feed.d.ts +99 -0
- package/dist/dts-cjs/Feed.d.ts.map +1 -0
- package/dist/dts-cjs/FeedSink.d.ts +189 -0
- package/dist/dts-cjs/FeedSink.d.ts.map +1 -0
- package/dist/dts-cjs/FeedSyncStore.d.ts +281 -0
- package/dist/dts-cjs/FeedSyncStore.d.ts.map +1 -0
- package/dist/dts-cjs/deliver.d.ts +16 -0
- package/dist/dts-cjs/deliver.d.ts.map +1 -0
- package/dist/dts-cjs/errors.d.ts +131 -0
- package/dist/dts-cjs/errors.d.ts.map +1 -0
- package/dist/dts-cjs/identifiers.d.ts +67 -0
- package/dist/dts-cjs/identifiers.d.ts.map +1 -0
- package/dist/dts-cjs/inMemoryFeed.d.ts +32 -0
- package/dist/dts-cjs/inMemoryFeed.d.ts.map +1 -0
- package/dist/dts-cjs/inMemorySink.d.ts +61 -0
- package/dist/dts-cjs/inMemorySink.d.ts.map +1 -0
- package/dist/dts-cjs/index.d.ts +63 -0
- package/dist/dts-cjs/index.d.ts.map +1 -0
- package/dist/dts-cjs/inspect.d.ts +71 -0
- package/dist/dts-cjs/inspect.d.ts.map +1 -0
- package/dist/dts-cjs/package.json +3 -0
- package/dist/dts-cjs/readiness.d.ts +84 -0
- package/dist/dts-cjs/readiness.d.ts.map +1 -0
- package/dist/dts-cjs/reconcile.d.ts +68 -0
- package/dist/dts-cjs/reconcile.d.ts.map +1 -0
- package/dist/dts-cjs/runFeedSync.d.ts +220 -0
- package/dist/dts-cjs/runFeedSync.d.ts.map +1 -0
- package/dist/dts-cjs/tuning.d.ts +40 -0
- package/dist/dts-cjs/tuning.d.ts.map +1 -0
- package/dist/dts-esm/Feed.d.ts +99 -0
- package/dist/dts-esm/Feed.d.ts.map +1 -0
- package/dist/dts-esm/FeedSink.d.ts +189 -0
- package/dist/dts-esm/FeedSink.d.ts.map +1 -0
- package/dist/dts-esm/FeedSyncStore.d.ts +281 -0
- package/dist/dts-esm/FeedSyncStore.d.ts.map +1 -0
- package/dist/dts-esm/deliver.d.ts +16 -0
- package/dist/dts-esm/deliver.d.ts.map +1 -0
- package/dist/dts-esm/errors.d.ts +131 -0
- package/dist/dts-esm/errors.d.ts.map +1 -0
- package/dist/dts-esm/identifiers.d.ts +67 -0
- package/dist/dts-esm/identifiers.d.ts.map +1 -0
- package/dist/dts-esm/inMemoryFeed.d.ts +32 -0
- package/dist/dts-esm/inMemoryFeed.d.ts.map +1 -0
- package/dist/dts-esm/inMemorySink.d.ts +61 -0
- package/dist/dts-esm/inMemorySink.d.ts.map +1 -0
- package/dist/dts-esm/index.d.ts +63 -0
- package/dist/dts-esm/index.d.ts.map +1 -0
- package/dist/dts-esm/inspect.d.ts +71 -0
- package/dist/dts-esm/inspect.d.ts.map +1 -0
- package/dist/dts-esm/package.json +3 -0
- package/dist/dts-esm/readiness.d.ts +84 -0
- package/dist/dts-esm/readiness.d.ts.map +1 -0
- package/dist/dts-esm/reconcile.d.ts +68 -0
- package/dist/dts-esm/reconcile.d.ts.map +1 -0
- package/dist/dts-esm/runFeedSync.d.ts +220 -0
- package/dist/dts-esm/runFeedSync.d.ts.map +1 -0
- package/dist/dts-esm/tuning.d.ts +40 -0
- package/dist/dts-esm/tuning.d.ts.map +1 -0
- package/dist/esm/Feed.js +2 -0
- package/dist/esm/Feed.js.map +1 -0
- package/dist/esm/FeedSink.js +46 -0
- package/dist/esm/FeedSink.js.map +1 -0
- package/dist/esm/FeedSyncStore.js +3 -0
- package/dist/esm/FeedSyncStore.js.map +1 -0
- package/dist/esm/deliver.js +78 -0
- package/dist/esm/deliver.js.map +1 -0
- package/dist/esm/errors.js +98 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/identifiers.js +56 -0
- package/dist/esm/identifiers.js.map +1 -0
- package/dist/esm/inMemoryFeed.js +320 -0
- package/dist/esm/inMemoryFeed.js.map +1 -0
- package/dist/esm/inMemorySink.js +134 -0
- package/dist/esm/inMemorySink.js.map +1 -0
- package/dist/esm/index.js +62 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/inspect.js +58 -0
- package/dist/esm/inspect.js.map +1 -0
- package/dist/esm/package.json +4 -0
- package/dist/esm/readiness.js +92 -0
- package/dist/esm/readiness.js.map +1 -0
- package/dist/esm/reconcile.js +153 -0
- package/dist/esm/reconcile.js.map +1 -0
- package/dist/esm/runFeedSync.js +595 -0
- package/dist/esm/runFeedSync.js.map +1 -0
- package/dist/esm/tuning.js +51 -0
- package/dist/esm/tuning.js.map +1 -0
- package/package.json +34 -3
- package/src/Feed.ts +111 -0
- package/src/FeedSink.ts +130 -0
- package/src/FeedSyncStore.ts +326 -0
- package/src/deliver.ts +108 -0
- package/src/errors.ts +134 -0
- package/src/identifiers.ts +92 -0
- package/src/inMemoryFeed.ts +582 -0
- package/src/inMemorySink.ts +215 -0
- package/src/index.ts +136 -0
- package/src/inspect.ts +114 -0
- package/src/readiness.ts +137 -0
- package/src/reconcile.ts +224 -0
- package/src/runFeedSync.ts +882 -0
- package/src/tuning.ts +65 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.withInMemoryFeed = exports.makeInMemoryFeed = void 0;
|
|
7
|
+
var _effect = require("effect");
|
|
8
|
+
var _errors = require("./errors.js");
|
|
9
|
+
var _FeedSyncStore = require("./FeedSyncStore.js");
|
|
10
|
+
var _identifiers = require("./identifiers.js");
|
|
11
|
+
const EMPTY_SINK = {
|
|
12
|
+
cursor: /*#__PURE__*/_effect.Option.none(),
|
|
13
|
+
lastAdvance: /*#__PURE__*/_effect.Option.none(),
|
|
14
|
+
holder: /*#__PURE__*/_effect.Option.none(),
|
|
15
|
+
parked: /*#__PURE__*/new Map()
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* A JSON value as a string with every object's keys sorted, so two encodings that
|
|
19
|
+
* differ only in key order compare equal.
|
|
20
|
+
*/
|
|
21
|
+
const canonicalJson = value => JSON.stringify(value, (_key, held) => held !== null && typeof held === 'object' && !Array.isArray(held) ? Object.fromEntries(Object.entries(held).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0)) : held);
|
|
22
|
+
const internals = /*#__PURE__*/new WeakMap();
|
|
23
|
+
/** Build an in-memory feed at a fresh generation; see the module doc. */
|
|
24
|
+
const makeInMemoryFeed = options => _effect.Effect.gen(function* () {
|
|
25
|
+
const feed = options.feed;
|
|
26
|
+
const initial = yield* _effect.Random.nextIntBetween(1, Number.MAX_SAFE_INTEGER);
|
|
27
|
+
const state = yield* _effect.Ref.make({
|
|
28
|
+
generation: _identifiers.Generation.make(BigInt(initial)),
|
|
29
|
+
lastSeq: 0n,
|
|
30
|
+
rows: new Map(),
|
|
31
|
+
sinks: new Map(),
|
|
32
|
+
boundTo: _effect.Option.none()
|
|
33
|
+
});
|
|
34
|
+
const wake = yield* _effect.PubSub.sliding(1);
|
|
35
|
+
const encode = _effect.Schema.encodeEffect(options.doc);
|
|
36
|
+
const requireFeed = name => name === feed ? _effect.Effect.void : _effect.Effect.die(new Error(`in-memory feed '${feed}' was asked about feed '${name}', which it does not hold`));
|
|
37
|
+
const sinkOf = (s, sink) => s.sinks.get(sink) ?? EMPTY_SINK;
|
|
38
|
+
const withSink = (s, sink, f) => ({
|
|
39
|
+
...s,
|
|
40
|
+
sinks: new Map(s.sinks).set(sink, f(sinkOf(s, sink)))
|
|
41
|
+
});
|
|
42
|
+
// --- the write side ---------------------------------------------------
|
|
43
|
+
const write = (at, body) => _effect.Effect.gen(function* () {
|
|
44
|
+
const buffer = new Map();
|
|
45
|
+
const set = (key, doc) => _effect.Effect.sync(() => {
|
|
46
|
+
buffer.delete(key);
|
|
47
|
+
buffer.set(key, doc);
|
|
48
|
+
});
|
|
49
|
+
const result = yield* body({
|
|
50
|
+
upsert: (key, doc) => set(key, _effect.Option.some(doc)),
|
|
51
|
+
remove: key => set(key, _effect.Option.none())
|
|
52
|
+
});
|
|
53
|
+
const staged = [];
|
|
54
|
+
for (const [key, doc] of buffer) {
|
|
55
|
+
const encoded = _effect.Option.isSome(doc) ? canonicalJson(yield* _effect.Effect.orDie(encode(doc.value))) : undefined;
|
|
56
|
+
staged.push({
|
|
57
|
+
key,
|
|
58
|
+
doc,
|
|
59
|
+
encoded
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
const wrote = yield* _effect.Ref.modify(state, s => {
|
|
63
|
+
const rows = new Map(s.rows);
|
|
64
|
+
let lastSeq = s.lastSeq;
|
|
65
|
+
for (const {
|
|
66
|
+
key,
|
|
67
|
+
doc,
|
|
68
|
+
encoded
|
|
69
|
+
} of staged) {
|
|
70
|
+
const stored = rows.get(key);
|
|
71
|
+
const unchanged = encoded === undefined ? stored === undefined || stored.encoded === undefined : stored !== undefined && stored.encoded === encoded;
|
|
72
|
+
if (unchanged) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
lastSeq += 1n;
|
|
76
|
+
rows.set(key, {
|
|
77
|
+
row: {
|
|
78
|
+
key,
|
|
79
|
+
doc,
|
|
80
|
+
seq: _identifiers.FeedSeq.make(lastSeq),
|
|
81
|
+
eventPosition: at
|
|
82
|
+
},
|
|
83
|
+
encoded
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return lastSeq === s.lastSeq ? [false, s] : [true, {
|
|
87
|
+
...s,
|
|
88
|
+
rows,
|
|
89
|
+
lastSeq
|
|
90
|
+
}];
|
|
91
|
+
});
|
|
92
|
+
if (wrote) {
|
|
93
|
+
yield* _effect.PubSub.publish(wake, undefined);
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
96
|
+
});
|
|
97
|
+
// --- the read side ----------------------------------------------------
|
|
98
|
+
const changesAfter = (after, limit) => _effect.Effect.map(_effect.Ref.get(state), s => Array.from(s.rows.values(), stored => stored.row).filter(row => row.seq > after).sort((left, right) => left.seq < right.seq ? -1 : left.seq > right.seq ? 1 : 0).slice(0, limit));
|
|
99
|
+
const source = {
|
|
100
|
+
feed,
|
|
101
|
+
generation: _effect.Effect.map(_effect.Ref.get(state), s => s.generation),
|
|
102
|
+
changesAfter,
|
|
103
|
+
listen: _effect.Stream.fromPubSub(wake)
|
|
104
|
+
};
|
|
105
|
+
// --- the sync store ---------------------------------------------------
|
|
106
|
+
// Take-if-free and record the holder in ONE `Ref.modify`, so the check and the
|
|
107
|
+
// take cannot be split by a rival, and the lease has one home that `casCursor`,
|
|
108
|
+
// `describe` and `removeSink` read. `acquireRelease` runs the take
|
|
109
|
+
// uninterruptibly, so a lease taken is always paired with its release.
|
|
110
|
+
const acquireLease = id => _effect.Effect.gen(function* () {
|
|
111
|
+
yield* requireFeed(id.feed);
|
|
112
|
+
const holder = _identifiers.LeaseHolder.make(`in-memory:${yield* _effect.Random.nextIntBetween(1, Number.MAX_SAFE_INTEGER)}`);
|
|
113
|
+
const take = _effect.Effect.flatMap(_effect.Ref.modify(state, s => _effect.Option.isSome(sinkOf(s, id.sink).holder) ? [false, s] : [true, withSink(s, id.sink, sink => ({
|
|
114
|
+
...sink,
|
|
115
|
+
holder: _effect.Option.some(holder)
|
|
116
|
+
}))]), taken => taken ? _effect.Effect.void : _effect.Effect.fail(new _errors.LeaseHeld(id)));
|
|
117
|
+
// Cleared only while it is still this holder's, so a release can never
|
|
118
|
+
// take the lease from anyone else.
|
|
119
|
+
const release = _effect.Ref.update(state, s => {
|
|
120
|
+
const current = s.sinks.get(id.sink);
|
|
121
|
+
return current !== undefined && _effect.Option.isSome(current.holder) && current.holder.value === holder ? withSink(s, id.sink, sink => ({
|
|
122
|
+
...sink,
|
|
123
|
+
holder: _effect.Option.none()
|
|
124
|
+
})) : s;
|
|
125
|
+
});
|
|
126
|
+
yield* _effect.Effect.acquireRelease(take, () => release);
|
|
127
|
+
const lease = {
|
|
128
|
+
holder,
|
|
129
|
+
ensureHeld: _effect.Effect.void
|
|
130
|
+
};
|
|
131
|
+
return lease;
|
|
132
|
+
});
|
|
133
|
+
const casCursor = args => _effect.Effect.flatMap(_effect.Effect.zip(requireFeed(args.feed), _effect.DateTime.now), ([, now]) => _effect.Effect.flatMap(_effect.Ref.modify(state, s => {
|
|
134
|
+
const current = sinkOf(s, args.sink);
|
|
135
|
+
const fenced = _effect.Option.isSome(current.holder) && current.holder.value === args.holder;
|
|
136
|
+
if (!fenced || !(0, _FeedSyncStore.sameCursor)(current.cursor, args.expected)) {
|
|
137
|
+
return [false, s];
|
|
138
|
+
}
|
|
139
|
+
return [true, withSink(s, args.sink, sink => ({
|
|
140
|
+
...sink,
|
|
141
|
+
cursor: _effect.Option.some(args.next),
|
|
142
|
+
lastAdvance: _effect.Option.some(now),
|
|
143
|
+
parked: moveParked(sink.parked, args.parked)
|
|
144
|
+
}))];
|
|
145
|
+
}), landed => landed ? _effect.Effect.void : _effect.Effect.fail(new _errors.CursorSuperseded({
|
|
146
|
+
feed: args.feed,
|
|
147
|
+
sink: args.sink
|
|
148
|
+
}))));
|
|
149
|
+
const retryParked = args => _effect.Effect.gen(function* () {
|
|
150
|
+
yield* requireFeed(args.feed);
|
|
151
|
+
const retried = yield* _effect.Ref.modify(state, s => {
|
|
152
|
+
const sink = sinkOf(s, args.sink);
|
|
153
|
+
if (!sink.parked.has(args.key)) {
|
|
154
|
+
return [false, s];
|
|
155
|
+
}
|
|
156
|
+
const parked = new Map(sink.parked);
|
|
157
|
+
parked.delete(args.key);
|
|
158
|
+
const unparked = withSink(s, args.sink, current => ({
|
|
159
|
+
...current,
|
|
160
|
+
parked
|
|
161
|
+
}));
|
|
162
|
+
const stored = s.rows.get(args.key);
|
|
163
|
+
if (stored === undefined) {
|
|
164
|
+
return [true, unparked];
|
|
165
|
+
}
|
|
166
|
+
const lastSeq = s.lastSeq + 1n;
|
|
167
|
+
return [true, {
|
|
168
|
+
...unparked,
|
|
169
|
+
lastSeq,
|
|
170
|
+
rows: new Map(s.rows).set(args.key, {
|
|
171
|
+
...stored,
|
|
172
|
+
row: {
|
|
173
|
+
...stored.row,
|
|
174
|
+
seq: _identifiers.FeedSeq.make(lastSeq)
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
}];
|
|
178
|
+
});
|
|
179
|
+
if (retried) {
|
|
180
|
+
yield* _effect.PubSub.publish(wake, undefined);
|
|
181
|
+
}
|
|
182
|
+
return retried;
|
|
183
|
+
});
|
|
184
|
+
const collectTombstones = name => _effect.Effect.flatMap(requireFeed(name), () => _effect.Ref.modify(state, s => {
|
|
185
|
+
// Every sink with a lease or a cursor counts, whatever its cursor's
|
|
186
|
+
// generation, and one with no cursor blocks collection outright: the
|
|
187
|
+
// port's doc says why a resyncing sink still needs the tombstones it has
|
|
188
|
+
// not read, and why an older generation needs no arm of its own.
|
|
189
|
+
let lowest;
|
|
190
|
+
for (const sink of s.sinks.values()) {
|
|
191
|
+
if (_effect.Option.isNone(sink.cursor)) {
|
|
192
|
+
return [0, s];
|
|
193
|
+
}
|
|
194
|
+
if (lowest === undefined || sink.cursor.value.seq < lowest) {
|
|
195
|
+
lowest = sink.cursor.value.seq;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (lowest === undefined) {
|
|
199
|
+
return [0, s];
|
|
200
|
+
}
|
|
201
|
+
const rows = new Map(s.rows);
|
|
202
|
+
let collected = 0;
|
|
203
|
+
for (const [key, stored] of s.rows) {
|
|
204
|
+
if (stored.encoded === undefined && stored.row.seq <= lowest) {
|
|
205
|
+
rows.delete(key);
|
|
206
|
+
collected += 1;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return collected === 0 ? [0, s] : [collected, {
|
|
210
|
+
...s,
|
|
211
|
+
rows
|
|
212
|
+
}];
|
|
213
|
+
}));
|
|
214
|
+
const describe = name => _effect.Effect.flatMap(requireFeed(name), () => _effect.Effect.map(_effect.Ref.get(state), s => {
|
|
215
|
+
let head = _identifiers.FEED_ORIGIN;
|
|
216
|
+
for (const stored of s.rows.values()) {
|
|
217
|
+
if (stored.row.seq > head) {
|
|
218
|
+
head = stored.row.seq;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
const sinks = Array.from(s.sinks.entries(), ([sink, state]) => ({
|
|
222
|
+
sink,
|
|
223
|
+
cursor: state.cursor,
|
|
224
|
+
lastAdvance: state.lastAdvance,
|
|
225
|
+
lease: _effect.Option.map(state.holder, holder => ({
|
|
226
|
+
holder,
|
|
227
|
+
expiresAt: _effect.Option.none()
|
|
228
|
+
})),
|
|
229
|
+
parked: Array.from(state.parked.values()),
|
|
230
|
+
pending: Array.from(s.rows.values()).filter(stored => _effect.Option.match(state.cursor, {
|
|
231
|
+
onNone: () => stored.encoded !== undefined,
|
|
232
|
+
onSome: cursor => stored.row.seq > cursor.seq
|
|
233
|
+
})).length
|
|
234
|
+
}));
|
|
235
|
+
return {
|
|
236
|
+
head: _identifiers.FeedSeq.make(head),
|
|
237
|
+
sinks
|
|
238
|
+
};
|
|
239
|
+
}));
|
|
240
|
+
const removeSink = id => _effect.Effect.flatMap(requireFeed(id.feed), () => _effect.Effect.flatten(_effect.Ref.modify(state, s => {
|
|
241
|
+
const current = s.sinks.get(id.sink);
|
|
242
|
+
if (current === undefined) {
|
|
243
|
+
return [_effect.Effect.succeed(false), s];
|
|
244
|
+
}
|
|
245
|
+
if (_effect.Option.isSome(current.holder)) {
|
|
246
|
+
return [_effect.Effect.fail(new _errors.LeaseHeld(id)), s];
|
|
247
|
+
}
|
|
248
|
+
const sinks = new Map(s.sinks);
|
|
249
|
+
sinks.delete(id.sink);
|
|
250
|
+
return [_effect.Effect.succeed(true), {
|
|
251
|
+
...s,
|
|
252
|
+
sinks
|
|
253
|
+
}];
|
|
254
|
+
})));
|
|
255
|
+
const syncStore = {
|
|
256
|
+
acquireLease,
|
|
257
|
+
readCursor: id => _effect.Effect.flatMap(requireFeed(id.feed), () => _effect.Effect.map(_effect.Ref.get(state), s => sinkOf(s, id.sink).cursor)),
|
|
258
|
+
casCursor,
|
|
259
|
+
readParked: id => _effect.Effect.flatMap(requireFeed(id.feed), () => _effect.Effect.map(_effect.Ref.get(state), s => Array.from(sinkOf(s, id.sink).parked.values()))),
|
|
260
|
+
retryParked,
|
|
261
|
+
collectTombstones,
|
|
262
|
+
removeSink,
|
|
263
|
+
describe
|
|
264
|
+
};
|
|
265
|
+
const result = {
|
|
266
|
+
feed,
|
|
267
|
+
write,
|
|
268
|
+
source,
|
|
269
|
+
syncStore
|
|
270
|
+
};
|
|
271
|
+
internals.set(result, {
|
|
272
|
+
bind: key => _effect.Effect.flatMap(_effect.Ref.modify(state, s => _effect.Option.isNone(s.boundTo) ? [_effect.Option.none(), {
|
|
273
|
+
...s,
|
|
274
|
+
boundTo: _effect.Option.some(key)
|
|
275
|
+
}] : [s.boundTo, s]), already => _effect.Option.isSome(already) && !sameKey(already.value, key) ? _effect.Effect.die(new Error(`withInMemoryFeed: feed '${feed}' is already bound to projection '${already.value.projection}' (partition '${already.value.partition}'), and one feed serves one materialisation`)) : _effect.Effect.void),
|
|
276
|
+
reset: _effect.Effect.andThen(_effect.Ref.update(state, s => ({
|
|
277
|
+
...s,
|
|
278
|
+
rows: new Map(),
|
|
279
|
+
generation: _identifiers.Generation.make(s.generation + 1n)
|
|
280
|
+
})), _effect.PubSub.publish(wake, undefined))
|
|
281
|
+
});
|
|
282
|
+
return result;
|
|
283
|
+
});
|
|
284
|
+
exports.makeInMemoryFeed = makeInMemoryFeed;
|
|
285
|
+
const sameKey = (left, right) => left.projection === right.projection && left.partition === right.partition;
|
|
286
|
+
const moveParked = (parked, change) => {
|
|
287
|
+
const next = change._tag === 'Replace' ? new Map() : new Map(parked);
|
|
288
|
+
if (change._tag === 'Amend') {
|
|
289
|
+
for (const key of change.unpark) {
|
|
290
|
+
next.delete(key);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
for (const record of change.park) {
|
|
294
|
+
next.set(record.key, record);
|
|
295
|
+
}
|
|
296
|
+
return next;
|
|
297
|
+
};
|
|
298
|
+
/**
|
|
299
|
+
* `store`, with `resetCheckpoint` for `key` replaced by one that also empties
|
|
300
|
+
* `feed` and moves its generation on, so every sink resyncs once the read model is
|
|
301
|
+
* replayed. Every other key passes through untouched, and `readCheckpoint` and
|
|
302
|
+
* `commit` are the store's own, so the result works through `forKey` exactly as
|
|
303
|
+
* the store does.
|
|
304
|
+
*
|
|
305
|
+
* Binding is checked here, at construction: a feed serves ONE materialisation,
|
|
306
|
+
* because one writer is what keeps its sequence ascending in commit order, so a
|
|
307
|
+
* feed already bound to another checkpoint key is refused, as is a durable `store`
|
|
308
|
+
* (see the module doc). Both refusals are defects.
|
|
309
|
+
*/
|
|
310
|
+
const withInMemoryFeed = (store, feed, key) => _effect.Effect.gen(function* () {
|
|
311
|
+
const inner = internals.get(feed);
|
|
312
|
+
if (inner === undefined) {
|
|
313
|
+
return yield* _effect.Effect.die(new Error(`withInMemoryFeed: feed '${feed.feed}' was not made by makeInMemoryFeed`));
|
|
314
|
+
}
|
|
315
|
+
if (store.durability === 'durable') {
|
|
316
|
+
return yield* _effect.Effect.die(new Error(`withInMemoryFeed: feed '${feed.feed}' is ephemeral and the store is durable; the view would outlive the feed`));
|
|
317
|
+
}
|
|
318
|
+
yield* inner.bind(key);
|
|
319
|
+
const decorated = {
|
|
320
|
+
durability: store.durability,
|
|
321
|
+
readCheckpoint: store.readCheckpoint,
|
|
322
|
+
commit: store.commit,
|
|
323
|
+
resetCheckpoint: reset => sameKey(reset, key) ? _effect.Effect.andThen(store.resetCheckpoint(reset), _effect.Effect.uninterruptible(inner.reset)) : store.resetCheckpoint(reset)
|
|
324
|
+
};
|
|
325
|
+
return decorated;
|
|
326
|
+
});
|
|
327
|
+
exports.withInMemoryFeed = withInMemoryFeed;
|
|
328
|
+
//# sourceMappingURL=inMemoryFeed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inMemoryFeed.js","names":["_effect","require","_errors","_FeedSyncStore","_identifiers","EMPTY_SINK","cursor","Option","none","lastAdvance","holder","parked","Map","canonicalJson","value","JSON","stringify","_key","held","Array","isArray","Object","fromEntries","entries","sort","left","right","internals","WeakMap","makeInMemoryFeed","options","Effect","gen","feed","initial","Random","nextIntBetween","Number","MAX_SAFE_INTEGER","state","Ref","make","generation","Generation","BigInt","lastSeq","rows","sinks","boundTo","wake","PubSub","sliding","encode","Schema","encodeEffect","doc","requireFeed","name","void","die","Error","sinkOf","s","sink","get","withSink","f","set","write","at","body","buffer","key","sync","delete","result","upsert","some","remove","staged","encoded","isSome","orDie","undefined","push","wrote","modify","stored","unchanged","row","seq","FeedSeq","eventPosition","publish","changesAfter","after","limit","map","from","values","filter","slice","source","listen","Stream","fromPubSub","acquireLease","id","LeaseHolder","take","flatMap","taken","fail","LeaseHeld","release","update","current","acquireRelease","lease","ensureHeld","casCursor","args","zip","DateTime","now","fenced","sameCursor","expected","next","moveParked","landed","CursorSuperseded","retryParked","retried","has","unparked","collectTombstones","lowest","isNone","collected","describe","head","FEED_ORIGIN","expiresAt","pending","match","onNone","onSome","length","removeSink","flatten","succeed","syncStore","readCursor","readParked","bind","already","sameKey","projection","partition","reset","andThen","exports","change","_tag","unpark","record","park","withInMemoryFeed","store","inner","durability","decorated","readCheckpoint","commit","resetCheckpoint","uninterruptible"],"sources":["../../src/inMemoryFeed.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.makeInMemorySink = void 0;
|
|
7
|
+
var _effect = require("effect");
|
|
8
|
+
var _errors = require("./errors.js");
|
|
9
|
+
/**
|
|
10
|
+
* The in-memory sink: a `FeedSink` over a `Ref` of documents, with an optional
|
|
11
|
+
* `FeedResync` and `FeedReconcile`, and the ORACLE the sink law suite holds every
|
|
12
|
+
* other sink against.
|
|
13
|
+
*
|
|
14
|
+
* It keeps the laws by construction: an upsert replaces the whole document, a
|
|
15
|
+
* delete of an absent key is a no-op, so the same batch applied twice leaves it as
|
|
16
|
+
* once; a batch is visible the moment `apply` returns, so `confirm` has nothing to
|
|
17
|
+
* wait for; a resync target is a separate map that `publish` swaps in whole, so a
|
|
18
|
+
* published resync holds exactly what was loaded into it, and a load into a target
|
|
19
|
+
* a later `begin` dropped fails rather than recreating it. Each `begin` names its
|
|
20
|
+
* target by a counter the sink's own state holds, so two workers sharing one sink
|
|
21
|
+
* value — the way two processes share one real index — never share a target, and
|
|
22
|
+
* the name is the same on every run of a test.
|
|
23
|
+
*
|
|
24
|
+
* Its two optional parts are switched on by option rather than always present,
|
|
25
|
+
* because which parts a sink has CHANGES what the driver does — a sink with no
|
|
26
|
+
* `resync` is resynced in place — and a test of either path needs a sink that
|
|
27
|
+
* lacks the other. It also records every batch it is handed, live or into a
|
|
28
|
+
* target, so a case can say how many sends a change cost.
|
|
29
|
+
*
|
|
30
|
+
* It lives for as long as the value is held, independently of any feed, which is
|
|
31
|
+
* what lets a test keep one sink across two in-memory feeds and watch the second
|
|
32
|
+
* feed's fresh generation force a resync.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
const LIVE = 'live';
|
|
36
|
+
const applyTo = (documents, changes) => {
|
|
37
|
+
const next = new Map(documents);
|
|
38
|
+
for (const change of changes) {
|
|
39
|
+
if (change._tag === 'Upsert') {
|
|
40
|
+
next.set(change.key, change.doc);
|
|
41
|
+
} else {
|
|
42
|
+
next.delete(change.key);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return next;
|
|
46
|
+
};
|
|
47
|
+
/** What a load into, or a publish of, a target a later `begin` dropped fails with. */
|
|
48
|
+
const droppedTarget = name => new _errors.SinkRetryable({
|
|
49
|
+
reason: `the resync target '${name}' was dropped by a later begin`
|
|
50
|
+
});
|
|
51
|
+
/** The resync target's name for one attempt at `generation`; see the module doc. */
|
|
52
|
+
const targetName = (generation, attempt) => `${LIVE}__g${generation}_${attempt}`;
|
|
53
|
+
/** Build an in-memory sink; see the module doc. */
|
|
54
|
+
const makeInMemorySink = options => _effect.Effect.gen(function* () {
|
|
55
|
+
const state = yield* _effect.Ref.make({
|
|
56
|
+
live: new Map(),
|
|
57
|
+
targets: new Map(),
|
|
58
|
+
batches: [],
|
|
59
|
+
published: [],
|
|
60
|
+
attempts: 0
|
|
61
|
+
});
|
|
62
|
+
const record = (target, changes) => _effect.Effect.flatten(_effect.Ref.modify(state, s => {
|
|
63
|
+
const batches = [...s.batches, {
|
|
64
|
+
target,
|
|
65
|
+
changes
|
|
66
|
+
}];
|
|
67
|
+
const receipt = {
|
|
68
|
+
target,
|
|
69
|
+
batch: batches.length
|
|
70
|
+
};
|
|
71
|
+
if (target === LIVE) {
|
|
72
|
+
return [_effect.Effect.succeed(receipt), {
|
|
73
|
+
...s,
|
|
74
|
+
batches,
|
|
75
|
+
live: applyTo(s.live, changes)
|
|
76
|
+
}];
|
|
77
|
+
}
|
|
78
|
+
const built = s.targets.get(target);
|
|
79
|
+
// Dropped by a later begin: recreating it here is what would let a
|
|
80
|
+
// stale worker's publish swap a fragment in. `FeedResync.load` says so.
|
|
81
|
+
if (built === undefined) {
|
|
82
|
+
return [_effect.Effect.fail(droppedTarget(target)), s];
|
|
83
|
+
}
|
|
84
|
+
return [_effect.Effect.succeed(receipt), {
|
|
85
|
+
...s,
|
|
86
|
+
batches,
|
|
87
|
+
targets: new Map(s.targets).set(target, applyTo(built, changes))
|
|
88
|
+
}];
|
|
89
|
+
}));
|
|
90
|
+
const resync = {
|
|
91
|
+
// Every other target is dropped: whatever attempt left it, it will never be
|
|
92
|
+
// published now, and its own publish must fail rather than swap it in.
|
|
93
|
+
begin: generation => _effect.Ref.modify(state, s => {
|
|
94
|
+
const attempts = s.attempts + 1;
|
|
95
|
+
const name = targetName(generation, attempts);
|
|
96
|
+
return [{
|
|
97
|
+
generation,
|
|
98
|
+
name
|
|
99
|
+
}, {
|
|
100
|
+
...s,
|
|
101
|
+
attempts,
|
|
102
|
+
targets: new Map([[name, new Map()]])
|
|
103
|
+
}];
|
|
104
|
+
}),
|
|
105
|
+
load: (target, batch) => record(target.name, batch),
|
|
106
|
+
publish: target => _effect.Effect.flatten(_effect.Ref.modify(state, s => {
|
|
107
|
+
const built = s.targets.get(target.name);
|
|
108
|
+
if (built === undefined) {
|
|
109
|
+
return [_effect.Effect.fail(droppedTarget(target.name)), s];
|
|
110
|
+
}
|
|
111
|
+
const targets = new Map(s.targets);
|
|
112
|
+
targets.delete(target.name);
|
|
113
|
+
return [_effect.Effect.void, {
|
|
114
|
+
...s,
|
|
115
|
+
live: built,
|
|
116
|
+
targets,
|
|
117
|
+
published: [...s.published, target.generation]
|
|
118
|
+
}];
|
|
119
|
+
}))
|
|
120
|
+
};
|
|
121
|
+
const sink = {
|
|
122
|
+
name: options.name,
|
|
123
|
+
apply: batch => record(LIVE, batch),
|
|
124
|
+
confirm: () => _effect.Effect.void,
|
|
125
|
+
...(options.resync === true ? {
|
|
126
|
+
resync
|
|
127
|
+
} : {}),
|
|
128
|
+
...(options.reconcile === true ? {
|
|
129
|
+
reconcile: {
|
|
130
|
+
listKeys: _effect.Stream.unwrap(_effect.Effect.map(_effect.Ref.get(state), s => _effect.Stream.fromIterable(Array.from(s.live.keys()))))
|
|
131
|
+
}
|
|
132
|
+
} : {})
|
|
133
|
+
};
|
|
134
|
+
return {
|
|
135
|
+
sink,
|
|
136
|
+
documents: _effect.Effect.map(_effect.Ref.get(state), s => s.live),
|
|
137
|
+
batches: _effect.Effect.map(_effect.Ref.get(state), s => s.batches),
|
|
138
|
+
published: _effect.Effect.map(_effect.Ref.get(state), s => s.published)
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
exports.makeInMemorySink = makeInMemorySink;
|
|
142
|
+
//# sourceMappingURL=inMemorySink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inMemorySink.js","names":["_effect","require","_errors","LIVE","applyTo","documents","changes","next","Map","change","_tag","set","key","doc","delete","droppedTarget","name","SinkRetryable","reason","targetName","generation","attempt","makeInMemorySink","options","Effect","gen","state","Ref","make","live","targets","batches","published","attempts","record","target","flatten","modify","s","receipt","batch","length","succeed","built","get","undefined","fail","resync","begin","load","publish","void","sink","apply","confirm","reconcile","listKeys","Stream","unwrap","map","fromIterable","Array","from","keys","exports"],"sources":["../../src/inMemorySink.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|