@rotorsoft/act-tck 1.41.4 → 2.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/README.md +3 -2
- package/dist/.tsbuildinfo +1 -1
- package/dist/@types/fixtures/helpers.d.ts.map +1 -1
- package/dist/@types/store-differential-tck.d.ts.map +1 -1
- package/dist/@types/store-property-tck.d.ts.map +1 -1
- package/dist/@types/store-tck.d.ts +2 -2
- package/dist/@types/store-tck.d.ts.map +1 -1
- package/dist/index.cjs +933 -418
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +934 -418
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -28,8 +28,7 @@ var seed_stream = async (store, stream, count, correlation) => {
|
|
|
28
28
|
const out = [];
|
|
29
29
|
for (let i = 0; i < count; i++) {
|
|
30
30
|
const committed = await store.commit(
|
|
31
|
-
stream,
|
|
32
|
-
[inc(1)],
|
|
31
|
+
[{ stream, msgs: [inc(1)] }],
|
|
33
32
|
make_meta({ correlation, stream })
|
|
34
33
|
);
|
|
35
34
|
out.push(...committed);
|
|
@@ -592,14 +591,17 @@ var apply_plan = async (store, plan, pii_isolation) => {
|
|
|
592
591
|
if (op.t === "commit") {
|
|
593
592
|
const msgs = op.pii && pii_isolation ? op.msgs.map((m, i) => i === 0 ? { ...m, pii: op.pii } : m) : op.msgs;
|
|
594
593
|
await store.commit(
|
|
595
|
-
op.stream,
|
|
596
|
-
msgs,
|
|
594
|
+
[{ stream: op.stream, msgs }],
|
|
597
595
|
make_meta({ stream: op.stream, correlation: plan.correlation })
|
|
598
596
|
);
|
|
599
597
|
} else if (op.t === "snapshot") {
|
|
600
598
|
await store.commit(
|
|
601
|
-
|
|
602
|
-
|
|
599
|
+
[
|
|
600
|
+
{
|
|
601
|
+
stream: op.stream,
|
|
602
|
+
msgs: [{ name: SNAP_EVENT, data: { count: op.count } }]
|
|
603
|
+
}
|
|
604
|
+
],
|
|
603
605
|
make_meta({ stream: op.stream, correlation: plan.correlation })
|
|
604
606
|
);
|
|
605
607
|
} else if (op.t === "truncate") {
|
|
@@ -608,8 +610,12 @@ var apply_plan = async (store, plan, pii_isolation) => {
|
|
|
608
610
|
]);
|
|
609
611
|
} else if (op.t === "truncate_windowed") {
|
|
610
612
|
await store.commit(
|
|
611
|
-
|
|
612
|
-
|
|
613
|
+
[
|
|
614
|
+
{
|
|
615
|
+
stream: op.stream,
|
|
616
|
+
msgs: [{ name: SNAP_EVENT, data: { count: 1 } }]
|
|
617
|
+
}
|
|
618
|
+
],
|
|
613
619
|
make_meta({ stream: op.stream, correlation: plan.correlation })
|
|
614
620
|
);
|
|
615
621
|
await store.truncate([
|
|
@@ -920,8 +926,7 @@ var runStorePropertyTck = (options) => {
|
|
|
920
926
|
for (const { stream, count } of commits) {
|
|
921
927
|
const before = expected.get(stream) ?? -1;
|
|
922
928
|
const committed = await store.commit(
|
|
923
|
-
stream,
|
|
924
|
-
events(count),
|
|
929
|
+
[{ stream, msgs: events(count) }],
|
|
925
930
|
make_meta({ stream })
|
|
926
931
|
);
|
|
927
932
|
committed.forEach((e, i) => {
|
|
@@ -946,8 +951,7 @@ var runStorePropertyTck = (options) => {
|
|
|
946
951
|
await reset2();
|
|
947
952
|
for (const { stream: stream2, count } of commits) {
|
|
948
953
|
await store.commit(
|
|
949
|
-
stream2,
|
|
950
|
-
events(count),
|
|
954
|
+
[{ stream: stream2, msgs: events(count) }],
|
|
951
955
|
make_meta({ stream: stream2 })
|
|
952
956
|
);
|
|
953
957
|
}
|
|
@@ -955,10 +959,8 @@ var runStorePropertyTck = (options) => {
|
|
|
955
959
|
const before = await collect(store, { stream, stream_exact: true });
|
|
956
960
|
await expect7(
|
|
957
961
|
store.commit(
|
|
958
|
-
stream,
|
|
959
|
-
|
|
960
|
-
make_meta({ stream }),
|
|
961
|
-
before.length
|
|
962
|
+
[{ stream, msgs: [inc(1)], expectedVersion: before.length }],
|
|
963
|
+
make_meta({ stream })
|
|
962
964
|
)
|
|
963
965
|
).rejects.toThrow();
|
|
964
966
|
const after = await collect(store, { stream, stream_exact: true });
|
|
@@ -985,8 +987,7 @@ var runStorePropertyTck = (options) => {
|
|
|
985
987
|
for (const op of ops) {
|
|
986
988
|
if (op.kind === "commit") {
|
|
987
989
|
await store.commit(
|
|
988
|
-
op.stream,
|
|
989
|
-
[inc(1)],
|
|
990
|
+
[{ stream: op.stream, msgs: [inc(1)] }],
|
|
990
991
|
make_meta({ stream: op.stream })
|
|
991
992
|
);
|
|
992
993
|
} else if (op.kind === "claim") {
|
|
@@ -1028,8 +1029,7 @@ var runStorePropertyTck = (options) => {
|
|
|
1028
1029
|
await store.subscribe(all.map((stream) => ({ stream })));
|
|
1029
1030
|
for (const stream of commitsA) {
|
|
1030
1031
|
await store.commit(
|
|
1031
|
-
stream,
|
|
1032
|
-
[inc(1)],
|
|
1032
|
+
[{ stream, msgs: [inc(1)] }],
|
|
1033
1033
|
make_meta({ stream })
|
|
1034
1034
|
);
|
|
1035
1035
|
}
|
|
@@ -1041,8 +1041,7 @@ var runStorePropertyTck = (options) => {
|
|
|
1041
1041
|
for (const l of acked1) watermark1.set(l.stream, l.at);
|
|
1042
1042
|
for (const stream of commitsB) {
|
|
1043
1043
|
await store.commit(
|
|
1044
|
-
stream,
|
|
1045
|
-
[inc(1)],
|
|
1044
|
+
[{ stream, msgs: [inc(1)] }],
|
|
1046
1045
|
make_meta({ stream })
|
|
1047
1046
|
);
|
|
1048
1047
|
}
|
|
@@ -1068,8 +1067,7 @@ var runStorePropertyTck = (options) => {
|
|
|
1068
1067
|
await store.subscribe(streams.map((stream) => ({ stream })));
|
|
1069
1068
|
for (const stream of commits) {
|
|
1070
1069
|
await store.commit(
|
|
1071
|
-
stream,
|
|
1072
|
-
[inc(1)],
|
|
1070
|
+
[{ stream, msgs: [inc(1)] }],
|
|
1073
1071
|
make_meta({ stream })
|
|
1074
1072
|
);
|
|
1075
1073
|
}
|
|
@@ -1079,8 +1077,7 @@ var runStorePropertyTck = (options) => {
|
|
|
1079
1077
|
const blockedSet = new Set(claimed.map((l) => l.stream));
|
|
1080
1078
|
await store.subscribe([{ stream: "ctrl" }]);
|
|
1081
1079
|
await store.commit(
|
|
1082
|
-
"ctrl",
|
|
1083
|
-
[inc(1)],
|
|
1080
|
+
[{ stream: "ctrl", msgs: [inc(1)] }],
|
|
1084
1081
|
make_meta({ stream: "ctrl" })
|
|
1085
1082
|
);
|
|
1086
1083
|
await mark_all(store);
|
|
@@ -1099,6 +1096,7 @@ import {
|
|
|
1099
1096
|
ConcurrencyError,
|
|
1100
1097
|
InMemoryCache,
|
|
1101
1098
|
is_literal_source,
|
|
1099
|
+
PreconditionError,
|
|
1102
1100
|
SNAP_EVENT as SNAP_EVENT2,
|
|
1103
1101
|
sensitive,
|
|
1104
1102
|
sleep,
|
|
@@ -1170,14 +1168,12 @@ var runStoreTck = (options) => {
|
|
|
1170
1168
|
await zero_config.seed();
|
|
1171
1169
|
const s = `default-config-${uid()}`;
|
|
1172
1170
|
const first = await zero_config.commit(
|
|
1173
|
-
s,
|
|
1174
|
-
[inc(1)],
|
|
1171
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
1175
1172
|
make_meta({ stream: s })
|
|
1176
1173
|
);
|
|
1177
1174
|
expect8(first[0].version).toBe(0);
|
|
1178
1175
|
const second = await zero_config.commit(
|
|
1179
|
-
s,
|
|
1180
|
-
[inc(2)],
|
|
1176
|
+
[{ stream: s, msgs: [inc(2)] }],
|
|
1181
1177
|
make_meta({ stream: s })
|
|
1182
1178
|
);
|
|
1183
1179
|
expect8(second[0].version).toBe(1);
|
|
@@ -1193,12 +1189,371 @@ var runStoreTck = (options) => {
|
|
|
1193
1189
|
});
|
|
1194
1190
|
});
|
|
1195
1191
|
}
|
|
1192
|
+
describe8("commit across streams", () => {
|
|
1193
|
+
const meta = make_meta({ stream: "across" });
|
|
1194
|
+
const count = (stream) => store.query(() => {
|
|
1195
|
+
}, { stream, stream_exact: true });
|
|
1196
|
+
it7("lands every append, each from its own head, with ids in append order", async () => {
|
|
1197
|
+
const a = `across-a-${uid()}`;
|
|
1198
|
+
const b = `across-b-${uid()}`;
|
|
1199
|
+
await store.commit(
|
|
1200
|
+
[{ stream: a, msgs: [inc(1)] }],
|
|
1201
|
+
meta
|
|
1202
|
+
);
|
|
1203
|
+
const committed = await store.commit(
|
|
1204
|
+
[
|
|
1205
|
+
{ stream: a, msgs: [inc(2), inc(3)], expectedVersion: 0 },
|
|
1206
|
+
{ stream: b, msgs: [dec(4)], expectedVersion: -1 }
|
|
1207
|
+
],
|
|
1208
|
+
meta
|
|
1209
|
+
);
|
|
1210
|
+
expect8(committed.map((e) => [e.stream, e.version])).toEqual([
|
|
1211
|
+
[a, 1],
|
|
1212
|
+
[a, 2],
|
|
1213
|
+
[b, 0]
|
|
1214
|
+
]);
|
|
1215
|
+
for (let i = 1; i < committed.length; i++)
|
|
1216
|
+
expect8(committed[i].id).toBeGreaterThan(committed[i - 1].id);
|
|
1217
|
+
const read = [];
|
|
1218
|
+
await store.query((e) => read.push(e.id), {
|
|
1219
|
+
after: committed[0].id - 1
|
|
1220
|
+
});
|
|
1221
|
+
expect8(read.filter((id) => committed.some((e) => e.id === id))).toEqual(
|
|
1222
|
+
committed.map((e) => e.id)
|
|
1223
|
+
);
|
|
1224
|
+
});
|
|
1225
|
+
it7("stores nothing when the first, a middle or the last append is stale, and names its stream", async () => {
|
|
1226
|
+
for (const at of [0, 1, 2]) {
|
|
1227
|
+
const streams = [0, 1, 2].map((i) => `across-stale-${i}-${uid()}`);
|
|
1228
|
+
for (const stream of streams)
|
|
1229
|
+
await store.commit(
|
|
1230
|
+
[{ stream, msgs: [inc(1)] }],
|
|
1231
|
+
meta
|
|
1232
|
+
);
|
|
1233
|
+
const refused = store.commit(
|
|
1234
|
+
streams.map((stream, i) => ({
|
|
1235
|
+
stream,
|
|
1236
|
+
msgs: [inc(2)],
|
|
1237
|
+
expectedVersion: i === at ? 5 : 0
|
|
1238
|
+
})),
|
|
1239
|
+
meta
|
|
1240
|
+
);
|
|
1241
|
+
await expect8(refused).rejects.toBeInstanceOf(ConcurrencyError);
|
|
1242
|
+
await expect8(refused).rejects.toMatchObject({ stream: streams[at] });
|
|
1243
|
+
for (const stream of streams) expect8(await count(stream)).toBe(1);
|
|
1244
|
+
}
|
|
1245
|
+
});
|
|
1246
|
+
it7("refuses a stream named twice and an append with no events, storing nothing", async () => {
|
|
1247
|
+
const a = `across-twice-${uid()}`;
|
|
1248
|
+
const b = `across-empty-${uid()}`;
|
|
1249
|
+
await expect8(
|
|
1250
|
+
store.commit(
|
|
1251
|
+
[
|
|
1252
|
+
{ stream: a, msgs: [inc(1)] },
|
|
1253
|
+
{ stream: a, msgs: [inc(2)] }
|
|
1254
|
+
],
|
|
1255
|
+
meta
|
|
1256
|
+
)
|
|
1257
|
+
).rejects.toThrow(`stream "${a}" is named twice`);
|
|
1258
|
+
await expect8(
|
|
1259
|
+
store.commit(
|
|
1260
|
+
[
|
|
1261
|
+
{ stream: a, msgs: [inc(1)] },
|
|
1262
|
+
{ stream: b, msgs: [] }
|
|
1263
|
+
],
|
|
1264
|
+
meta
|
|
1265
|
+
)
|
|
1266
|
+
).rejects.toThrow(`the append to "${b}" has no events`);
|
|
1267
|
+
expect8(await count(a)).toBe(0);
|
|
1268
|
+
expect8(await count(b)).toBe(0);
|
|
1269
|
+
});
|
|
1270
|
+
it7("commits nothing for no appends", async () => {
|
|
1271
|
+
expect8(await store.commit([], meta)).toEqual([]);
|
|
1272
|
+
});
|
|
1273
|
+
it7("lands an unguarded append beside guarded ones", async () => {
|
|
1274
|
+
const a = `across-guarded-${uid()}`;
|
|
1275
|
+
const b = `across-free-${uid()}`;
|
|
1276
|
+
await store.commit(
|
|
1277
|
+
[{ stream: b, msgs: [inc(1)] }],
|
|
1278
|
+
meta
|
|
1279
|
+
);
|
|
1280
|
+
const committed = await store.commit(
|
|
1281
|
+
[
|
|
1282
|
+
{ stream: a, msgs: [inc(1)], expectedVersion: -1 },
|
|
1283
|
+
{ stream: b, msgs: [inc(2)] }
|
|
1284
|
+
],
|
|
1285
|
+
meta
|
|
1286
|
+
);
|
|
1287
|
+
expect8(committed.map((e) => [e.stream, e.version])).toEqual([
|
|
1288
|
+
[a, 0],
|
|
1289
|
+
[b, 1]
|
|
1290
|
+
]);
|
|
1291
|
+
});
|
|
1292
|
+
it7("stores every event of every append, whole", async () => {
|
|
1293
|
+
const a = `across-whole-a-${uid()}`;
|
|
1294
|
+
const b = `across-whole-b-${uid()}`;
|
|
1295
|
+
const across = make_meta({ stream: a });
|
|
1296
|
+
const committed = await store.commit(
|
|
1297
|
+
[
|
|
1298
|
+
{ stream: a, msgs: [inc(1)] },
|
|
1299
|
+
{ stream: b, msgs: [inc(2), dec(3)] }
|
|
1300
|
+
],
|
|
1301
|
+
across
|
|
1302
|
+
);
|
|
1303
|
+
const shape = (e) => [
|
|
1304
|
+
e.name,
|
|
1305
|
+
e.data,
|
|
1306
|
+
e.meta
|
|
1307
|
+
];
|
|
1308
|
+
const expected = [
|
|
1309
|
+
["Incremented", { amount: 2 }, across],
|
|
1310
|
+
["Decremented", { amount: 3 }, across]
|
|
1311
|
+
];
|
|
1312
|
+
expect8(committed.filter((e) => e.stream === b).map(shape)).toEqual(
|
|
1313
|
+
expected
|
|
1314
|
+
);
|
|
1315
|
+
const stored = [];
|
|
1316
|
+
await store.query((e) => stored.push(e), {
|
|
1317
|
+
stream: b,
|
|
1318
|
+
stream_exact: true
|
|
1319
|
+
});
|
|
1320
|
+
expect8(stored.map(shape)).toEqual(expected);
|
|
1321
|
+
});
|
|
1322
|
+
it7.skipIf(!caps.pii_isolation)(
|
|
1323
|
+
"keeps the sensitive fields of a later append",
|
|
1324
|
+
async () => {
|
|
1325
|
+
const a = `across-pii-a-${uid()}`;
|
|
1326
|
+
const b = `across-pii-b-${uid()}`;
|
|
1327
|
+
await store.commit(
|
|
1328
|
+
[
|
|
1329
|
+
{ stream: a, msgs: [inc(1)] },
|
|
1330
|
+
{ stream: b, msgs: [{ ...inc(2), pii: { email: "e" } }] }
|
|
1331
|
+
],
|
|
1332
|
+
make_meta({ stream: a })
|
|
1333
|
+
);
|
|
1334
|
+
const stored = [];
|
|
1335
|
+
await store.query((e) => stored.push(e.pii), {
|
|
1336
|
+
stream: b,
|
|
1337
|
+
stream_exact: true
|
|
1338
|
+
});
|
|
1339
|
+
expect8(stored).toEqual([{ email: "e" }]);
|
|
1340
|
+
}
|
|
1341
|
+
);
|
|
1342
|
+
it7("leaves nothing of the commit that lost a race, on any of its streams", async () => {
|
|
1343
|
+
const shared = `across-all-shared-${uid()}`;
|
|
1344
|
+
const [x, y] = [`across-all-x-${uid()}`, `across-all-y-${uid()}`];
|
|
1345
|
+
const race = (own) => store.commit(
|
|
1346
|
+
[
|
|
1347
|
+
{ stream: own, msgs: [inc(1)], expectedVersion: -1 },
|
|
1348
|
+
{ stream: shared, msgs: [inc(1)], expectedVersion: -1 }
|
|
1349
|
+
],
|
|
1350
|
+
meta
|
|
1351
|
+
);
|
|
1352
|
+
const rs = await Promise.allSettled([race(x), race(y)]);
|
|
1353
|
+
expect8(rs.filter((r) => r.status === "fulfilled")).toHaveLength(1);
|
|
1354
|
+
expect8(await count(x) + await count(y)).toBe(1);
|
|
1355
|
+
});
|
|
1356
|
+
it7("lets one of two racing commits on a shared stream win, and both on disjoint streams", async () => {
|
|
1357
|
+
const shared = `across-shared-${uid()}`;
|
|
1358
|
+
const [x, y] = [`across-x-${uid()}`, `across-y-${uid()}`];
|
|
1359
|
+
const race = (own, other) => store.commit(
|
|
1360
|
+
[
|
|
1361
|
+
{ stream: own, msgs: [inc(1)], expectedVersion: -1 },
|
|
1362
|
+
{ stream: other, msgs: [inc(1)], expectedVersion: -1 }
|
|
1363
|
+
],
|
|
1364
|
+
meta
|
|
1365
|
+
);
|
|
1366
|
+
const shared_race = await Promise.allSettled([
|
|
1367
|
+
race(x, shared),
|
|
1368
|
+
race(y, shared)
|
|
1369
|
+
]);
|
|
1370
|
+
expect8(
|
|
1371
|
+
shared_race.filter((r2) => r2.status === "fulfilled")
|
|
1372
|
+
).toHaveLength(1);
|
|
1373
|
+
const lost = shared_race.find((r2) => r2.status === "rejected");
|
|
1374
|
+
expect8(lost.reason).toBeInstanceOf(
|
|
1375
|
+
ConcurrencyError
|
|
1376
|
+
);
|
|
1377
|
+
expect8(await count(shared)).toBe(1);
|
|
1378
|
+
const [p, q, r, t] = [0, 1, 2, 3].map((i) => `across-d${i}-${uid()}`);
|
|
1379
|
+
const disjoint = await Promise.allSettled([race(p, q), race(r, t)]);
|
|
1380
|
+
expect8(disjoint.every((d) => d.status === "fulfilled")).toBe(true);
|
|
1381
|
+
});
|
|
1382
|
+
});
|
|
1383
|
+
describe8("what a commit, guard or truncate must not get wrong", () => {
|
|
1384
|
+
const edge_uid = () => uid();
|
|
1385
|
+
const E = (data = { a: 1 }, pii) => ({
|
|
1386
|
+
name: "E",
|
|
1387
|
+
data,
|
|
1388
|
+
...pii ? { pii } : {}
|
|
1389
|
+
});
|
|
1390
|
+
const edge_meta = (correlation = "m") => ({ correlation, causation: {} });
|
|
1391
|
+
const rows = async (query) => {
|
|
1392
|
+
const found = [];
|
|
1393
|
+
await store.query((e) => found.push(e), query);
|
|
1394
|
+
return found;
|
|
1395
|
+
};
|
|
1396
|
+
const one = (stream) => ({ stream, stream_exact: true });
|
|
1397
|
+
it7("names the FIRST stale stream when two are stale", async () => {
|
|
1398
|
+
const [a, b] = [`a-${edge_uid()}`, `b-${edge_uid()}`];
|
|
1399
|
+
const e = await store.commit(
|
|
1400
|
+
[
|
|
1401
|
+
{ stream: a, msgs: [E()], expectedVersion: 3 },
|
|
1402
|
+
{ stream: b, msgs: [E()], expectedVersion: 4 }
|
|
1403
|
+
],
|
|
1404
|
+
edge_meta()
|
|
1405
|
+
).catch((x) => x);
|
|
1406
|
+
expect8(e).toBeInstanceOf(ConcurrencyError);
|
|
1407
|
+
expect8(e.stream).toBe(a);
|
|
1408
|
+
});
|
|
1409
|
+
it7("checks a stale expectedVersion of 0 inside a multi-stream commit", async () => {
|
|
1410
|
+
const [a, b] = [`a-${edge_uid()}`, `b-${edge_uid()}`];
|
|
1411
|
+
await store.commit(
|
|
1412
|
+
[{ stream: b, msgs: [E(), E()] }],
|
|
1413
|
+
edge_meta()
|
|
1414
|
+
);
|
|
1415
|
+
await expect8(
|
|
1416
|
+
store.commit(
|
|
1417
|
+
[
|
|
1418
|
+
{ stream: a, msgs: [E()], expectedVersion: -1 },
|
|
1419
|
+
{ stream: b, msgs: [E()], expectedVersion: 0 }
|
|
1420
|
+
],
|
|
1421
|
+
edge_meta()
|
|
1422
|
+
)
|
|
1423
|
+
).rejects.toBeInstanceOf(ConcurrencyError);
|
|
1424
|
+
expect8(await rows(one(a))).toHaveLength(0);
|
|
1425
|
+
});
|
|
1426
|
+
it7("attaches meta to every append, not just the last", async () => {
|
|
1427
|
+
const ss = [0, 1, 2].map((i) => `m${i}-${edge_uid()}`);
|
|
1428
|
+
const c = `corr-${edge_uid()}`;
|
|
1429
|
+
await store.commit(
|
|
1430
|
+
ss.map((stream) => ({ stream, msgs: [E()] })),
|
|
1431
|
+
edge_meta(c)
|
|
1432
|
+
);
|
|
1433
|
+
for (const stream of ss)
|
|
1434
|
+
expect8((await rows(one(stream)))[0].meta.correlation).toBe(c);
|
|
1435
|
+
});
|
|
1436
|
+
it7("refuses a stream named twice when not adjacent", async () => {
|
|
1437
|
+
const [a, b] = [`a-${edge_uid()}`, `b-${edge_uid()}`];
|
|
1438
|
+
await expect8(
|
|
1439
|
+
store.commit(
|
|
1440
|
+
[
|
|
1441
|
+
{ stream: a, msgs: [E()] },
|
|
1442
|
+
{ stream: b, msgs: [E()] },
|
|
1443
|
+
{ stream: a, msgs: [E()] }
|
|
1444
|
+
],
|
|
1445
|
+
edge_meta()
|
|
1446
|
+
)
|
|
1447
|
+
).rejects.toThrow("named twice");
|
|
1448
|
+
expect8(await rows(one(a))).toHaveLength(0);
|
|
1449
|
+
});
|
|
1450
|
+
it7("refuses a lone empty append (a version check alone)", async () => {
|
|
1451
|
+
const a = `a-${edge_uid()}`;
|
|
1452
|
+
await expect8(
|
|
1453
|
+
store.commit(
|
|
1454
|
+
[{ stream: a, msgs: [], expectedVersion: -1 }],
|
|
1455
|
+
edge_meta()
|
|
1456
|
+
)
|
|
1457
|
+
).rejects.toThrow("no events");
|
|
1458
|
+
});
|
|
1459
|
+
it7("refuses an empty FIRST append", async () => {
|
|
1460
|
+
const [a, b] = [`a-${edge_uid()}`, `b-${edge_uid()}`];
|
|
1461
|
+
await expect8(
|
|
1462
|
+
store.commit(
|
|
1463
|
+
[
|
|
1464
|
+
{ stream: a, msgs: [] },
|
|
1465
|
+
{ stream: b, msgs: [E()] }
|
|
1466
|
+
],
|
|
1467
|
+
edge_meta()
|
|
1468
|
+
)
|
|
1469
|
+
).rejects.toThrow("no events");
|
|
1470
|
+
expect8(await rows(one(b))).toHaveLength(0);
|
|
1471
|
+
});
|
|
1472
|
+
it7("keeps the sensitive fields of the FIRST append", async () => {
|
|
1473
|
+
const [a, b] = [`a-${edge_uid()}`, `b-${edge_uid()}`];
|
|
1474
|
+
await store.commit(
|
|
1475
|
+
[
|
|
1476
|
+
{ stream: a, msgs: [E({}, { email: "x" })] },
|
|
1477
|
+
{ stream: b, msgs: [E()] }
|
|
1478
|
+
],
|
|
1479
|
+
edge_meta()
|
|
1480
|
+
);
|
|
1481
|
+
expect8((await rows(one(a)))[0].pii).toEqual({ email: "x" });
|
|
1482
|
+
});
|
|
1483
|
+
it7("a guard below a trailing snapshot is stale", async () => {
|
|
1484
|
+
const a = `a-${edge_uid()}`;
|
|
1485
|
+
await store.commit([{ stream: a, msgs: [E()] }], edge_meta());
|
|
1486
|
+
await store.commit(
|
|
1487
|
+
[
|
|
1488
|
+
{
|
|
1489
|
+
stream: a,
|
|
1490
|
+
msgs: [{ name: SNAP_EVENT2, data: {} }],
|
|
1491
|
+
expectedVersion: 0
|
|
1492
|
+
}
|
|
1493
|
+
],
|
|
1494
|
+
edge_meta()
|
|
1495
|
+
);
|
|
1496
|
+
await expect8(
|
|
1497
|
+
store.commit(
|
|
1498
|
+
[{ stream: a, msgs: [E()], expectedVersion: 0 }],
|
|
1499
|
+
edge_meta()
|
|
1500
|
+
)
|
|
1501
|
+
).rejects.toBeInstanceOf(ConcurrencyError);
|
|
1502
|
+
});
|
|
1503
|
+
it7("a guard below a trailing tombstone is stale (what stops a writer during a close)", async () => {
|
|
1504
|
+
const a = `a-${edge_uid()}`;
|
|
1505
|
+
await store.commit([{ stream: a, msgs: [E()] }], edge_meta());
|
|
1506
|
+
await store.commit(
|
|
1507
|
+
[
|
|
1508
|
+
{
|
|
1509
|
+
stream: a,
|
|
1510
|
+
msgs: [{ name: "__tombstone__", data: {} }],
|
|
1511
|
+
expectedVersion: 0
|
|
1512
|
+
}
|
|
1513
|
+
],
|
|
1514
|
+
edge_meta()
|
|
1515
|
+
);
|
|
1516
|
+
await expect8(
|
|
1517
|
+
store.commit(
|
|
1518
|
+
[{ stream: a, msgs: [E()], expectedVersion: 0 }],
|
|
1519
|
+
edge_meta()
|
|
1520
|
+
)
|
|
1521
|
+
).rejects.toBeInstanceOf(ConcurrencyError);
|
|
1522
|
+
});
|
|
1523
|
+
it7("a commit after a full truncate continues from the seed at version 0", async () => {
|
|
1524
|
+
const a = `a-${edge_uid()}`;
|
|
1525
|
+
await store.commit(
|
|
1526
|
+
[{ stream: a, msgs: [E(), E(), E()] }],
|
|
1527
|
+
edge_meta()
|
|
1528
|
+
);
|
|
1529
|
+
await store.truncate([{ stream: a, snapshot: { n: 3 } }]);
|
|
1530
|
+
const [c] = await store.commit(
|
|
1531
|
+
[{ stream: a, msgs: [E()], expectedVersion: 0 }],
|
|
1532
|
+
edge_meta()
|
|
1533
|
+
);
|
|
1534
|
+
expect8(c.version).toBe(1);
|
|
1535
|
+
});
|
|
1536
|
+
it7("seeds a full truncate at version 0, carrying the meta it was given", async () => {
|
|
1537
|
+
const a = `a-${edge_uid()}`;
|
|
1538
|
+
await store.commit(
|
|
1539
|
+
[{ stream: a, msgs: [E(), E(), E()] }],
|
|
1540
|
+
edge_meta()
|
|
1541
|
+
);
|
|
1542
|
+
const c = `close-${edge_uid()}`;
|
|
1543
|
+
const r = await store.truncate([
|
|
1544
|
+
{ stream: a, snapshot: { n: 3 }, meta: edge_meta(c) }
|
|
1545
|
+
]);
|
|
1546
|
+
expect8(r.get(a).committed.version).toBe(0);
|
|
1547
|
+
const [seed] = await rows({ ...one(a), with_snaps: true });
|
|
1548
|
+
expect8(seed.version).toBe(0);
|
|
1549
|
+
expect8(seed.meta.correlation).toBe(c);
|
|
1550
|
+
});
|
|
1551
|
+
});
|
|
1196
1552
|
describe8("commit", () => {
|
|
1197
1553
|
it7("returns committed events with sequenced ids and versions", async () => {
|
|
1198
1554
|
const s = `commit-seq-${uid()}`;
|
|
1199
1555
|
const committed = await store.commit(
|
|
1200
|
-
s,
|
|
1201
|
-
[inc(1), inc(2), dec(3)],
|
|
1556
|
+
[{ stream: s, msgs: [inc(1), inc(2), dec(3)] }],
|
|
1202
1557
|
make_meta({ stream: s })
|
|
1203
1558
|
);
|
|
1204
1559
|
expect8(committed).toHaveLength(3);
|
|
@@ -1215,8 +1570,7 @@ var runStoreTck = (options) => {
|
|
|
1215
1570
|
const s = `commit-meta-${uid()}`;
|
|
1216
1571
|
const correlation = `cor-${uid()}`;
|
|
1217
1572
|
const committed = await store.commit(
|
|
1218
|
-
s,
|
|
1219
|
-
[inc(1)],
|
|
1573
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
1220
1574
|
make_meta({ stream: s, correlation })
|
|
1221
1575
|
);
|
|
1222
1576
|
expect8(committed[0].stream).toBe(s);
|
|
@@ -1225,64 +1579,50 @@ var runStoreTck = (options) => {
|
|
|
1225
1579
|
it7("throws ConcurrencyError when expectedVersion is wrong", async () => {
|
|
1226
1580
|
const s = `commit-cc-${uid()}`;
|
|
1227
1581
|
await store.commit(
|
|
1228
|
-
s,
|
|
1229
|
-
[inc(1)],
|
|
1582
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
1230
1583
|
make_meta({ stream: s })
|
|
1231
1584
|
);
|
|
1232
1585
|
await store.commit(
|
|
1233
|
-
s,
|
|
1234
|
-
|
|
1235
|
-
make_meta({ stream: s }),
|
|
1236
|
-
0
|
|
1586
|
+
[{ stream: s, msgs: [inc(1)], expectedVersion: 0 }],
|
|
1587
|
+
make_meta({ stream: s })
|
|
1237
1588
|
);
|
|
1238
1589
|
await expect8(
|
|
1239
|
-
store.commit(
|
|
1590
|
+
store.commit(
|
|
1591
|
+
[{ stream: s, msgs: [inc(1)], expectedVersion: 0 }],
|
|
1592
|
+
make_meta({ stream: s })
|
|
1593
|
+
)
|
|
1240
1594
|
).rejects.toBeInstanceOf(ConcurrencyError);
|
|
1241
1595
|
});
|
|
1242
1596
|
it7("treats expectedVersion -1 as an empty stream", async () => {
|
|
1243
1597
|
const s = `commit-new-cc-${uid()}`;
|
|
1244
1598
|
const [first] = await store.commit(
|
|
1245
|
-
s,
|
|
1246
|
-
[inc(1)],
|
|
1247
|
-
make_meta({ stream: s }),
|
|
1248
|
-
-1
|
|
1249
|
-
);
|
|
1250
|
-
expect8(first.version).toBe(0);
|
|
1251
|
-
await expect8(
|
|
1252
|
-
store.commit(s, [inc(1)], make_meta({ stream: s }), -1)
|
|
1253
|
-
).rejects.toBeInstanceOf(ConcurrencyError);
|
|
1254
|
-
});
|
|
1255
|
-
it7("checks expectedVersion even when committing no events", async () => {
|
|
1256
|
-
const s = `commit-empty-cc-${uid()}`;
|
|
1257
|
-
await store.commit(
|
|
1258
|
-
s,
|
|
1259
|
-
[inc(1)],
|
|
1599
|
+
[{ stream: s, msgs: [inc(1)], expectedVersion: -1 }],
|
|
1260
1600
|
make_meta({ stream: s })
|
|
1261
1601
|
);
|
|
1602
|
+
expect8(first.version).toBe(0);
|
|
1262
1603
|
await expect8(
|
|
1263
|
-
store.commit(
|
|
1604
|
+
store.commit(
|
|
1605
|
+
[{ stream: s, msgs: [inc(1)], expectedVersion: -1 }],
|
|
1606
|
+
make_meta({ stream: s })
|
|
1607
|
+
)
|
|
1264
1608
|
).rejects.toBeInstanceOf(ConcurrencyError);
|
|
1265
|
-
expect8(
|
|
1266
|
-
await store.commit(s, [], make_meta({ stream: s }), 0)
|
|
1267
|
-
).toEqual([]);
|
|
1268
1609
|
});
|
|
1269
1610
|
it7("takes concurrent commits, reads and writes on one instance", async () => {
|
|
1270
1611
|
const x = `commit-concurrent-x-${uid()}`;
|
|
1271
1612
|
const y = `commit-concurrent-y-${uid()}`;
|
|
1272
1613
|
const [first, second, other, read, subscribed] = await Promise.allSettled([
|
|
1273
1614
|
store.commit(
|
|
1274
|
-
x,
|
|
1275
|
-
|
|
1276
|
-
make_meta({ stream: x }),
|
|
1277
|
-
-1
|
|
1615
|
+
[{ stream: x, msgs: [inc(1)], expectedVersion: -1 }],
|
|
1616
|
+
make_meta({ stream: x })
|
|
1278
1617
|
),
|
|
1279
1618
|
store.commit(
|
|
1280
|
-
x,
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1619
|
+
[{ stream: x, msgs: [inc(2)], expectedVersion: -1 }],
|
|
1620
|
+
make_meta({ stream: x })
|
|
1621
|
+
),
|
|
1622
|
+
store.commit(
|
|
1623
|
+
[{ stream: y, msgs: [inc(1)] }],
|
|
1624
|
+
make_meta({ stream: y })
|
|
1284
1625
|
),
|
|
1285
|
-
store.commit(y, [inc(1)], make_meta({ stream: y })),
|
|
1286
1626
|
store.query(() => {
|
|
1287
1627
|
}, { stream: x, stream_exact: true }),
|
|
1288
1628
|
// A source nothing writes, so later claims never see it.
|
|
@@ -1304,12 +1644,14 @@ var runStoreTck = (options) => {
|
|
|
1304
1644
|
it7("preserves prior events when a concurrent commit is rejected", async () => {
|
|
1305
1645
|
const s = `commit-cc-preserve-${uid()}`;
|
|
1306
1646
|
await store.commit(
|
|
1307
|
-
s,
|
|
1308
|
-
[inc(1), inc(2)],
|
|
1647
|
+
[{ stream: s, msgs: [inc(1), inc(2)] }],
|
|
1309
1648
|
make_meta({ stream: s })
|
|
1310
1649
|
);
|
|
1311
1650
|
await expect8(
|
|
1312
|
-
store.commit(
|
|
1651
|
+
store.commit(
|
|
1652
|
+
[{ stream: s, msgs: [inc(3)], expectedVersion: 0 }],
|
|
1653
|
+
make_meta({ stream: s })
|
|
1654
|
+
)
|
|
1313
1655
|
).rejects.toBeInstanceOf(ConcurrencyError);
|
|
1314
1656
|
const found = await collect(store, { stream: s, stream_exact: true });
|
|
1315
1657
|
expect8(found).toHaveLength(2);
|
|
@@ -1321,13 +1663,11 @@ var runStoreTck = (options) => {
|
|
|
1321
1663
|
const s2 = `q-s2-${uid()}`;
|
|
1322
1664
|
const cor = `q-cor-${uid()}`;
|
|
1323
1665
|
await store.commit(
|
|
1324
|
-
s1,
|
|
1325
|
-
[inc(1), dec(1)],
|
|
1666
|
+
[{ stream: s1, msgs: [inc(1), dec(1)] }],
|
|
1326
1667
|
make_meta({ stream: s1, correlation: cor })
|
|
1327
1668
|
);
|
|
1328
1669
|
await store.commit(
|
|
1329
|
-
s2,
|
|
1330
|
-
[inc(2), dec(2), reset()],
|
|
1670
|
+
[{ stream: s2, msgs: [inc(2), dec(2), reset()] }],
|
|
1331
1671
|
make_meta({ stream: s2, correlation: cor })
|
|
1332
1672
|
);
|
|
1333
1673
|
const by_stream = await collect(store, {
|
|
@@ -1353,8 +1693,7 @@ var runStoreTck = (options) => {
|
|
|
1353
1693
|
it7("excludes snapshots when called with no query object", async () => {
|
|
1354
1694
|
const s = `q-nofilter-${uid()}`;
|
|
1355
1695
|
await store.commit(
|
|
1356
|
-
s,
|
|
1357
|
-
[{ name: SNAP_EVENT2, data: { count: 0 } }],
|
|
1696
|
+
[{ stream: s, msgs: [{ name: SNAP_EVENT2, data: { count: 0 } }] }],
|
|
1358
1697
|
make_meta({ stream: s })
|
|
1359
1698
|
);
|
|
1360
1699
|
const names = [];
|
|
@@ -1366,18 +1705,15 @@ var runStoreTck = (options) => {
|
|
|
1366
1705
|
it7("with_snaps resumes from the latest snapshot per stream", async () => {
|
|
1367
1706
|
const s = `q-snap-${uid()}`;
|
|
1368
1707
|
await store.commit(
|
|
1369
|
-
s,
|
|
1370
|
-
[inc(1), inc(1)],
|
|
1708
|
+
[{ stream: s, msgs: [inc(1), inc(1)] }],
|
|
1371
1709
|
make_meta({ stream: s })
|
|
1372
1710
|
);
|
|
1373
1711
|
const [snap] = await store.commit(
|
|
1374
|
-
s,
|
|
1375
|
-
[{ name: SNAP_EVENT2, data: { count: 2 } }],
|
|
1712
|
+
[{ stream: s, msgs: [{ name: SNAP_EVENT2, data: { count: 2 } }] }],
|
|
1376
1713
|
make_meta({ stream: s })
|
|
1377
1714
|
);
|
|
1378
1715
|
await store.commit(
|
|
1379
|
-
s,
|
|
1380
|
-
[inc(1), inc(1), inc(1)],
|
|
1716
|
+
[{ stream: s, msgs: [inc(1), inc(1), inc(1)] }],
|
|
1381
1717
|
make_meta({ stream: s })
|
|
1382
1718
|
);
|
|
1383
1719
|
const from_snap = await collect(store, {
|
|
@@ -1398,8 +1734,7 @@ var runStoreTck = (options) => {
|
|
|
1398
1734
|
expect8(after_snap).toHaveLength(3);
|
|
1399
1735
|
const s2 = `q-nosnap-${uid()}`;
|
|
1400
1736
|
await store.commit(
|
|
1401
|
-
s2,
|
|
1402
|
-
[inc(1), inc(1)],
|
|
1737
|
+
[{ stream: s2, msgs: [inc(1), inc(1)] }],
|
|
1403
1738
|
make_meta({ stream: s2 })
|
|
1404
1739
|
);
|
|
1405
1740
|
const full = await collect(store, {
|
|
@@ -1412,18 +1747,15 @@ var runStoreTck = (options) => {
|
|
|
1412
1747
|
it7("with_snaps applies the resume floor on a backward scan too", async () => {
|
|
1413
1748
|
const s = `q-snap-back-${uid()}`;
|
|
1414
1749
|
await store.commit(
|
|
1415
|
-
s,
|
|
1416
|
-
[inc(1), inc(1)],
|
|
1750
|
+
[{ stream: s, msgs: [inc(1), inc(1)] }],
|
|
1417
1751
|
make_meta({ stream: s })
|
|
1418
1752
|
);
|
|
1419
1753
|
const [snap] = await store.commit(
|
|
1420
|
-
s,
|
|
1421
|
-
[{ name: SNAP_EVENT2, data: { count: 2 } }],
|
|
1754
|
+
[{ stream: s, msgs: [{ name: SNAP_EVENT2, data: { count: 2 } }] }],
|
|
1422
1755
|
make_meta({ stream: s })
|
|
1423
1756
|
);
|
|
1424
1757
|
await store.commit(
|
|
1425
|
-
s,
|
|
1426
|
-
[inc(1), inc(1), inc(1)],
|
|
1758
|
+
[{ stream: s, msgs: [inc(1), inc(1), inc(1)] }],
|
|
1427
1759
|
make_meta({ stream: s })
|
|
1428
1760
|
);
|
|
1429
1761
|
const backward = await collect(store, {
|
|
@@ -1437,8 +1769,7 @@ var runStoreTck = (options) => {
|
|
|
1437
1769
|
expect8(backward.every((e) => e.id >= snap.id)).toBe(true);
|
|
1438
1770
|
const s2 = `q-nosnap-back-${uid()}`;
|
|
1439
1771
|
await store.commit(
|
|
1440
|
-
s2,
|
|
1441
|
-
[inc(1), inc(1)],
|
|
1772
|
+
[{ stream: s2, msgs: [inc(1), inc(1)] }],
|
|
1442
1773
|
make_meta({ stream: s2 })
|
|
1443
1774
|
);
|
|
1444
1775
|
const full = await collect(store, {
|
|
@@ -1452,8 +1783,7 @@ var runStoreTck = (options) => {
|
|
|
1452
1783
|
it7("supports backward traversal", async () => {
|
|
1453
1784
|
const s = `q-back-${uid()}`;
|
|
1454
1785
|
const committed = await store.commit(
|
|
1455
|
-
s,
|
|
1456
|
-
[inc(1), inc(2), inc(3)],
|
|
1786
|
+
[{ stream: s, msgs: [inc(1), inc(2), inc(3)] }],
|
|
1457
1787
|
make_meta({ stream: s })
|
|
1458
1788
|
);
|
|
1459
1789
|
const forward = await collect(store, { stream: s, stream_exact: true });
|
|
@@ -1478,8 +1808,7 @@ var runStoreTck = (options) => {
|
|
|
1478
1808
|
it7("after/before bound the id range", async () => {
|
|
1479
1809
|
const s = `q-bounds-${uid()}`;
|
|
1480
1810
|
const committed = await store.commit(
|
|
1481
|
-
s,
|
|
1482
|
-
[inc(1), inc(2), inc(3), inc(4)],
|
|
1811
|
+
[{ stream: s, msgs: [inc(1), inc(2), inc(3), inc(4)] }],
|
|
1483
1812
|
make_meta({ stream: s })
|
|
1484
1813
|
);
|
|
1485
1814
|
const after_first = await collect(store, {
|
|
@@ -1502,8 +1831,7 @@ var runStoreTck = (options) => {
|
|
|
1502
1831
|
it7("names:[] matches no events", async () => {
|
|
1503
1832
|
const s = `q-names-empty-${uid()}`;
|
|
1504
1833
|
await store.commit(
|
|
1505
|
-
s,
|
|
1506
|
-
[inc(1), dec(1)],
|
|
1834
|
+
[{ stream: s, msgs: [inc(1), dec(1)] }],
|
|
1507
1835
|
make_meta({ stream: s })
|
|
1508
1836
|
);
|
|
1509
1837
|
const none = await collect(store, {
|
|
@@ -1518,8 +1846,7 @@ var runStoreTck = (options) => {
|
|
|
1518
1846
|
it7("after:0 and before:0 are honored as id bounds", async () => {
|
|
1519
1847
|
const s = `q-zero-bound-${uid()}`;
|
|
1520
1848
|
await store.commit(
|
|
1521
|
-
s,
|
|
1522
|
-
[inc(1), inc(2), inc(3)],
|
|
1849
|
+
[{ stream: s, msgs: [inc(1), inc(2), inc(3)] }],
|
|
1523
1850
|
make_meta({ stream: s })
|
|
1524
1851
|
);
|
|
1525
1852
|
expect8(
|
|
@@ -1550,8 +1877,7 @@ var runStoreTck = (options) => {
|
|
|
1550
1877
|
it7("created_after/created_before filter by timestamp", async () => {
|
|
1551
1878
|
const s = `q-ts-${uid()}`;
|
|
1552
1879
|
const committed = await store.commit(
|
|
1553
|
-
s,
|
|
1554
|
-
[inc(1)],
|
|
1880
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
1555
1881
|
make_meta({ stream: s })
|
|
1556
1882
|
);
|
|
1557
1883
|
const ts = committed[0].created.getTime();
|
|
@@ -1574,8 +1900,7 @@ var runStoreTck = (options) => {
|
|
|
1574
1900
|
it7("created bounds exclude the event they are pinned to", async () => {
|
|
1575
1901
|
const s = `q-ts-self-${uid()}`;
|
|
1576
1902
|
const committed = await store.commit(
|
|
1577
|
-
s,
|
|
1578
|
-
[inc(1)],
|
|
1903
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
1579
1904
|
make_meta({ stream: s })
|
|
1580
1905
|
);
|
|
1581
1906
|
const own = committed[0].created;
|
|
@@ -1595,8 +1920,7 @@ var runStoreTck = (options) => {
|
|
|
1595
1920
|
it7("backward traversal short-circuits at `after` id boundary", async () => {
|
|
1596
1921
|
const s = `q-back-after-${uid()}`;
|
|
1597
1922
|
const committed = await store.commit(
|
|
1598
|
-
s,
|
|
1599
|
-
[inc(1), inc(2), inc(3)],
|
|
1923
|
+
[{ stream: s, msgs: [inc(1), inc(2), inc(3)] }],
|
|
1600
1924
|
make_meta({ stream: s })
|
|
1601
1925
|
);
|
|
1602
1926
|
const got = await collect(store, {
|
|
@@ -1613,8 +1937,7 @@ var runStoreTck = (options) => {
|
|
|
1613
1937
|
it7("backward traversal short-circuits at `created_after` boundary", async () => {
|
|
1614
1938
|
const s = `q-back-cafter-${uid()}`;
|
|
1615
1939
|
await store.commit(
|
|
1616
|
-
s,
|
|
1617
|
-
[inc(1)],
|
|
1940
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
1618
1941
|
make_meta({ stream: s })
|
|
1619
1942
|
);
|
|
1620
1943
|
const future = new Date(Date.now() + 6e4);
|
|
@@ -1629,8 +1952,7 @@ var runStoreTck = (options) => {
|
|
|
1629
1952
|
it7("backward traversal honors created_before by skipping newer events", async () => {
|
|
1630
1953
|
const s = `q-back-ts-${uid()}`;
|
|
1631
1954
|
const committed = await store.commit(
|
|
1632
|
-
s,
|
|
1633
|
-
[inc(1)],
|
|
1955
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
1634
1956
|
make_meta()
|
|
1635
1957
|
);
|
|
1636
1958
|
const past = new Date(committed[0].created.getTime() - 6e4);
|
|
@@ -1647,13 +1969,11 @@ var runStoreTck = (options) => {
|
|
|
1647
1969
|
const a = `q-exact-${tag}`;
|
|
1648
1970
|
const b = `q-exact-${tag}-extra`;
|
|
1649
1971
|
await store.commit(
|
|
1650
|
-
a,
|
|
1651
|
-
[inc(1)],
|
|
1972
|
+
[{ stream: a, msgs: [inc(1)] }],
|
|
1652
1973
|
make_meta({ stream: a })
|
|
1653
1974
|
);
|
|
1654
1975
|
await store.commit(
|
|
1655
|
-
b,
|
|
1656
|
-
[inc(2)],
|
|
1976
|
+
[{ stream: b, msgs: [inc(2)] }],
|
|
1657
1977
|
make_meta({ stream: b })
|
|
1658
1978
|
);
|
|
1659
1979
|
const exact = await collect(store, { stream: a, stream_exact: true });
|
|
@@ -1665,13 +1985,11 @@ var runStoreTck = (options) => {
|
|
|
1665
1985
|
const inner = `qr-${tag}-inner`;
|
|
1666
1986
|
const longer = `qr-${tag}-inner-extra`;
|
|
1667
1987
|
await store.commit(
|
|
1668
|
-
inner,
|
|
1669
|
-
[inc(1)],
|
|
1988
|
+
[{ stream: inner, msgs: [inc(1)] }],
|
|
1670
1989
|
make_meta({ stream: inner })
|
|
1671
1990
|
);
|
|
1672
1991
|
await store.commit(
|
|
1673
|
-
longer,
|
|
1674
|
-
[inc(2)],
|
|
1992
|
+
[{ stream: longer, msgs: [inc(2)] }],
|
|
1675
1993
|
make_meta({ stream: longer })
|
|
1676
1994
|
);
|
|
1677
1995
|
const got = await collect(store, { stream: `qr-${tag}-inner` });
|
|
@@ -1682,13 +2000,11 @@ var runStoreTck = (options) => {
|
|
|
1682
2000
|
const inner = `qr-${tag}-anchor`;
|
|
1683
2001
|
const longer = `qr-${tag}-anchor-extra`;
|
|
1684
2002
|
await store.commit(
|
|
1685
|
-
inner,
|
|
1686
|
-
[inc(1)],
|
|
2003
|
+
[{ stream: inner, msgs: [inc(1)] }],
|
|
1687
2004
|
make_meta({ stream: inner })
|
|
1688
2005
|
);
|
|
1689
2006
|
await store.commit(
|
|
1690
|
-
longer,
|
|
1691
|
-
[inc(2)],
|
|
2007
|
+
[{ stream: longer, msgs: [inc(2)] }],
|
|
1692
2008
|
make_meta({ stream: longer })
|
|
1693
2009
|
);
|
|
1694
2010
|
const got = await collect(store, { stream: `^qr-${tag}-anchor$` });
|
|
@@ -1701,18 +2017,15 @@ var runStoreTck = (options) => {
|
|
|
1701
2017
|
const b = `qr-${tag}-pfx-b`;
|
|
1702
2018
|
const other = `zz-${tag}-other`;
|
|
1703
2019
|
await store.commit(
|
|
1704
|
-
a,
|
|
1705
|
-
[inc(1)],
|
|
2020
|
+
[{ stream: a, msgs: [inc(1)] }],
|
|
1706
2021
|
make_meta({ stream: a })
|
|
1707
2022
|
);
|
|
1708
2023
|
await store.commit(
|
|
1709
|
-
b,
|
|
1710
|
-
[inc(2)],
|
|
2024
|
+
[{ stream: b, msgs: [inc(2)] }],
|
|
1711
2025
|
make_meta({ stream: b })
|
|
1712
2026
|
);
|
|
1713
2027
|
await store.commit(
|
|
1714
|
-
other,
|
|
1715
|
-
[inc(3)],
|
|
2028
|
+
[{ stream: other, msgs: [inc(3)] }],
|
|
1716
2029
|
make_meta({ stream: other })
|
|
1717
2030
|
);
|
|
1718
2031
|
const got = await collect(store, { stream: `^qr-${tag}-pfx-` });
|
|
@@ -1723,8 +2036,7 @@ var runStoreTck = (options) => {
|
|
|
1723
2036
|
const seed_streams = async (streams) => {
|
|
1724
2037
|
for (const s of streams)
|
|
1725
2038
|
await store.commit(
|
|
1726
|
-
s,
|
|
1727
|
-
[inc(1)],
|
|
2039
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
1728
2040
|
make_meta({ stream: s })
|
|
1729
2041
|
);
|
|
1730
2042
|
};
|
|
@@ -1903,8 +2215,7 @@ var runStoreTck = (options) => {
|
|
|
1903
2215
|
const src = `fresh-first-src-${uid()}`;
|
|
1904
2216
|
await store.subscribe([{ stream: s, source: src }]);
|
|
1905
2217
|
const [first] = await store.commit(
|
|
1906
|
-
src,
|
|
1907
|
-
[inc(1)],
|
|
2218
|
+
[{ stream: src, msgs: [inc(1)] }],
|
|
1908
2219
|
make_meta({ stream: src })
|
|
1909
2220
|
);
|
|
1910
2221
|
await store.subscribe([{ stream: s, correlated_at: first.id }]);
|
|
@@ -2093,8 +2404,7 @@ var runStoreTck = (options) => {
|
|
|
2093
2404
|
const src = `ws-unmarked-src-${uid()}`;
|
|
2094
2405
|
await store.subscribe([{ stream: s, source: src }]);
|
|
2095
2406
|
const [event] = await store.commit(
|
|
2096
|
-
src,
|
|
2097
|
-
[inc(1)],
|
|
2407
|
+
[{ stream: src, msgs: [inc(1)] }],
|
|
2098
2408
|
make_meta({ stream: src })
|
|
2099
2409
|
);
|
|
2100
2410
|
expect8(await claimable(s)).toBe(false);
|
|
@@ -2126,8 +2436,7 @@ var runStoreTck = (options) => {
|
|
|
2126
2436
|
const s = `claim-${uid()}`;
|
|
2127
2437
|
await store.subscribe([{ stream: s }]);
|
|
2128
2438
|
await store.commit(
|
|
2129
|
-
s,
|
|
2130
|
-
[inc(1)],
|
|
2439
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2131
2440
|
make_meta({ stream: s })
|
|
2132
2441
|
);
|
|
2133
2442
|
const by = `worker-${uid()}`;
|
|
@@ -2150,8 +2459,7 @@ var runStoreTck = (options) => {
|
|
|
2150
2459
|
const other = `claim-other-${uid()}`;
|
|
2151
2460
|
await store.subscribe([{ stream: s }]);
|
|
2152
2461
|
await store.commit(
|
|
2153
|
-
s,
|
|
2154
|
-
[inc(1)],
|
|
2462
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2155
2463
|
make_meta({ stream: s })
|
|
2156
2464
|
);
|
|
2157
2465
|
await correlate();
|
|
@@ -2160,8 +2468,7 @@ var runStoreTck = (options) => {
|
|
|
2160
2468
|
expect8(targetA).toBeDefined();
|
|
2161
2469
|
await store.subscribe([{ stream: other }]);
|
|
2162
2470
|
await store.commit(
|
|
2163
|
-
other,
|
|
2164
|
-
[inc(2)],
|
|
2471
|
+
[{ stream: other, msgs: [inc(2)] }],
|
|
2165
2472
|
make_meta({ stream: other })
|
|
2166
2473
|
);
|
|
2167
2474
|
await correlate();
|
|
@@ -2174,8 +2481,7 @@ var runStoreTck = (options) => {
|
|
|
2174
2481
|
const s = `claim-stolen-${uid()}`;
|
|
2175
2482
|
await store.subscribe([{ stream: s }]);
|
|
2176
2483
|
await store.commit(
|
|
2177
|
-
s,
|
|
2178
|
-
[inc(1), inc(2)],
|
|
2484
|
+
[{ stream: s, msgs: [inc(1), inc(2)] }],
|
|
2179
2485
|
make_meta({ stream: s })
|
|
2180
2486
|
);
|
|
2181
2487
|
await correlate();
|
|
@@ -2201,8 +2507,7 @@ var runStoreTck = (options) => {
|
|
|
2201
2507
|
const s = `claim-dual-${uid()}`;
|
|
2202
2508
|
await store.subscribe([{ stream: s }]);
|
|
2203
2509
|
await store.commit(
|
|
2204
|
-
s,
|
|
2205
|
-
[inc(1), inc(2)],
|
|
2510
|
+
[{ stream: s, msgs: [inc(1), inc(2)] }],
|
|
2206
2511
|
make_meta({ stream: s })
|
|
2207
2512
|
);
|
|
2208
2513
|
await correlate();
|
|
@@ -2231,13 +2536,11 @@ var runStoreTck = (options) => {
|
|
|
2231
2536
|
]);
|
|
2232
2537
|
for (const stream of highs)
|
|
2233
2538
|
await fresh.commit(
|
|
2234
|
-
stream,
|
|
2235
|
-
[inc(1)],
|
|
2539
|
+
[{ stream, msgs: [inc(1)] }],
|
|
2236
2540
|
make_meta({ stream })
|
|
2237
2541
|
);
|
|
2238
2542
|
await fresh.commit(
|
|
2239
|
-
low,
|
|
2240
|
-
[inc(1)],
|
|
2543
|
+
[{ stream: low, msgs: [inc(1)] }],
|
|
2241
2544
|
make_meta({ stream: low })
|
|
2242
2545
|
);
|
|
2243
2546
|
const by = `w-${uid()}`;
|
|
@@ -2253,8 +2556,7 @@ var runStoreTck = (options) => {
|
|
|
2253
2556
|
for (const l of leases) {
|
|
2254
2557
|
await fresh.ack([{ ...l, at: l.at + 1 }]);
|
|
2255
2558
|
await fresh.commit(
|
|
2256
|
-
l.stream,
|
|
2257
|
-
[inc(1)],
|
|
2559
|
+
[{ stream: l.stream, msgs: [inc(1)] }],
|
|
2258
2560
|
make_meta({ stream: l.stream })
|
|
2259
2561
|
);
|
|
2260
2562
|
}
|
|
@@ -2268,8 +2570,7 @@ var runStoreTck = (options) => {
|
|
|
2268
2570
|
const s = `claim-dedup-${uid()}`;
|
|
2269
2571
|
await store.subscribe([{ stream: s }]);
|
|
2270
2572
|
await store.commit(
|
|
2271
|
-
s,
|
|
2272
|
-
[inc(1)],
|
|
2573
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2273
2574
|
make_meta({ stream: s })
|
|
2274
2575
|
);
|
|
2275
2576
|
await correlate();
|
|
@@ -2282,13 +2583,11 @@ var runStoreTck = (options) => {
|
|
|
2282
2583
|
const sibling = `ack-sibling-${uid()}`;
|
|
2283
2584
|
await store.subscribe([{ stream: s }, { stream: sibling }]);
|
|
2284
2585
|
await store.commit(
|
|
2285
|
-
s,
|
|
2286
|
-
[inc(1)],
|
|
2586
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2287
2587
|
make_meta({ stream: s })
|
|
2288
2588
|
);
|
|
2289
2589
|
await store.commit(
|
|
2290
|
-
sibling,
|
|
2291
|
-
[inc(2)],
|
|
2590
|
+
[{ stream: sibling, msgs: [inc(2)] }],
|
|
2292
2591
|
make_meta({ stream: sibling })
|
|
2293
2592
|
);
|
|
2294
2593
|
await correlate();
|
|
@@ -2338,8 +2637,7 @@ var runStoreTck = (options) => {
|
|
|
2338
2637
|
const s = `lease-retry-${uid()}`;
|
|
2339
2638
|
await fresh.subscribe([{ stream: s }]);
|
|
2340
2639
|
await fresh.commit(
|
|
2341
|
-
s,
|
|
2342
|
-
[inc(1)],
|
|
2640
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2343
2641
|
make_meta({ stream: s })
|
|
2344
2642
|
);
|
|
2345
2643
|
await correlate(fresh);
|
|
@@ -2364,8 +2662,7 @@ var runStoreTck = (options) => {
|
|
|
2364
2662
|
const s = `lease-zero-${uid()}`;
|
|
2365
2663
|
await fresh.subscribe([{ stream: s }]);
|
|
2366
2664
|
const [committed] = await fresh.commit(
|
|
2367
|
-
s,
|
|
2368
|
-
[inc(1)],
|
|
2665
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2369
2666
|
make_meta({ stream: s })
|
|
2370
2667
|
);
|
|
2371
2668
|
await correlate(fresh);
|
|
@@ -2394,8 +2691,7 @@ var runStoreTck = (options) => {
|
|
|
2394
2691
|
const s = `lease-lag-${uid()}`;
|
|
2395
2692
|
await fresh.subscribe([{ stream: s }]);
|
|
2396
2693
|
await fresh.commit(
|
|
2397
|
-
s,
|
|
2398
|
-
[inc(1)],
|
|
2694
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2399
2695
|
make_meta({ stream: s })
|
|
2400
2696
|
);
|
|
2401
2697
|
await correlate(fresh);
|
|
@@ -2524,8 +2820,7 @@ var runStoreTck = (options) => {
|
|
|
2524
2820
|
await fresh.subscribe(streams.map((stream) => ({ stream })));
|
|
2525
2821
|
for (const stream of streams) {
|
|
2526
2822
|
await fresh.commit(
|
|
2527
|
-
stream,
|
|
2528
|
-
[inc(1)],
|
|
2823
|
+
[{ stream, msgs: [inc(1)] }],
|
|
2529
2824
|
make_meta({ stream })
|
|
2530
2825
|
);
|
|
2531
2826
|
}
|
|
@@ -2597,8 +2892,7 @@ var runStoreTck = (options) => {
|
|
|
2597
2892
|
const s = `block-${uid()}`;
|
|
2598
2893
|
await store.subscribe([{ stream: s }]);
|
|
2599
2894
|
await store.commit(
|
|
2600
|
-
s,
|
|
2601
|
-
[inc(1)],
|
|
2895
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2602
2896
|
make_meta({ stream: s })
|
|
2603
2897
|
);
|
|
2604
2898
|
await correlate();
|
|
@@ -2620,8 +2914,7 @@ var runStoreTck = (options) => {
|
|
|
2620
2914
|
const s = `block-returns-${uid()}`;
|
|
2621
2915
|
await store.subscribe([{ stream: s }]);
|
|
2622
2916
|
await store.commit(
|
|
2623
|
-
s,
|
|
2624
|
-
[inc(1)],
|
|
2917
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2625
2918
|
make_meta({ stream: s })
|
|
2626
2919
|
);
|
|
2627
2920
|
await correlate();
|
|
@@ -2646,8 +2939,7 @@ var runStoreTck = (options) => {
|
|
|
2646
2939
|
const s = `block-wrong-${uid()}`;
|
|
2647
2940
|
await store.subscribe([{ stream: s }]);
|
|
2648
2941
|
await store.commit(
|
|
2649
|
-
s,
|
|
2650
|
-
[inc(1)],
|
|
2942
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2651
2943
|
make_meta({ stream: s })
|
|
2652
2944
|
);
|
|
2653
2945
|
await correlate();
|
|
@@ -2665,8 +2957,7 @@ var runStoreTck = (options) => {
|
|
|
2665
2957
|
const s = `block-twice-${uid()}`;
|
|
2666
2958
|
await store.subscribe([{ stream: s }]);
|
|
2667
2959
|
await store.commit(
|
|
2668
|
-
s,
|
|
2669
|
-
[inc(1)],
|
|
2960
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2670
2961
|
make_meta({ stream: s })
|
|
2671
2962
|
);
|
|
2672
2963
|
await correlate();
|
|
@@ -2691,8 +2982,7 @@ var runStoreTck = (options) => {
|
|
|
2691
2982
|
await store.subscribe([{ stream: s }, { stream: ctl }]);
|
|
2692
2983
|
for (const st of [s, ctl])
|
|
2693
2984
|
await store.commit(
|
|
2694
|
-
st,
|
|
2695
|
-
[inc(1)],
|
|
2985
|
+
[{ stream: st, msgs: [inc(1)] }],
|
|
2696
2986
|
make_meta({ stream: st })
|
|
2697
2987
|
);
|
|
2698
2988
|
expect8(await store.defer([s], Date.now() + 36e5)).toBe(1);
|
|
@@ -2705,8 +2995,7 @@ var runStoreTck = (options) => {
|
|
|
2705
2995
|
const s = `defer-clock-${uid()}`;
|
|
2706
2996
|
await store.subscribe([{ stream: s }]);
|
|
2707
2997
|
await store.commit(
|
|
2708
|
-
s,
|
|
2709
|
-
[inc(1)],
|
|
2998
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2710
2999
|
make_meta({ stream: s })
|
|
2711
3000
|
);
|
|
2712
3001
|
expect8(await store.defer([s], Date.now() + 6e4)).toBe(1);
|
|
@@ -2729,8 +3018,7 @@ var runStoreTck = (options) => {
|
|
|
2729
3018
|
const s = `defer-past-${uid()}`;
|
|
2730
3019
|
await store.subscribe([{ stream: s }]);
|
|
2731
3020
|
await store.commit(
|
|
2732
|
-
s,
|
|
2733
|
-
[inc(1)],
|
|
3021
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2734
3022
|
make_meta({ stream: s })
|
|
2735
3023
|
);
|
|
2736
3024
|
expect8(await store.defer([s], Date.now() - 1e3)).toBe(1);
|
|
@@ -2746,8 +3034,7 @@ var runStoreTck = (options) => {
|
|
|
2746
3034
|
const s = `defer-retry-${uid()}`;
|
|
2747
3035
|
await store.subscribe([{ stream: s }]);
|
|
2748
3036
|
await store.commit(
|
|
2749
|
-
s,
|
|
2750
|
-
[inc(1)],
|
|
3037
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2751
3038
|
make_meta({ stream: s })
|
|
2752
3039
|
);
|
|
2753
3040
|
await store.defer([s], Date.now() + 36e5);
|
|
@@ -2769,8 +3056,7 @@ var runStoreTck = (options) => {
|
|
|
2769
3056
|
const s = `defer-reset-${uid()}`;
|
|
2770
3057
|
await store.subscribe([{ stream: s }]);
|
|
2771
3058
|
await store.commit(
|
|
2772
|
-
s,
|
|
2773
|
-
[inc(1)],
|
|
3059
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2774
3060
|
make_meta({ stream: s })
|
|
2775
3061
|
);
|
|
2776
3062
|
await store.defer([s], Date.now() + 36e5);
|
|
@@ -2785,8 +3071,7 @@ var runStoreTck = (options) => {
|
|
|
2785
3071
|
await store.subscribe([{ stream: deferred }, { stream: plain }]);
|
|
2786
3072
|
for (const s of [deferred, plain])
|
|
2787
3073
|
await store.commit(
|
|
2788
|
-
s,
|
|
2789
|
-
[inc(1)],
|
|
3074
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2790
3075
|
make_meta({ stream: s })
|
|
2791
3076
|
);
|
|
2792
3077
|
const due = Date.now() + 36e5;
|
|
@@ -2808,15 +3093,13 @@ var runStoreTck = (options) => {
|
|
|
2808
3093
|
await store.subscribe([{ stream: a }, { stream: b }]);
|
|
2809
3094
|
for (const s of [a, b])
|
|
2810
3095
|
await store.commit(
|
|
2811
|
-
s,
|
|
2812
|
-
[inc(1)],
|
|
3096
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2813
3097
|
make_meta({ stream: s })
|
|
2814
3098
|
);
|
|
2815
3099
|
const ctl = `defer-filterctl-${tag}`;
|
|
2816
3100
|
await store.subscribe([{ stream: ctl }]);
|
|
2817
3101
|
await store.commit(
|
|
2818
|
-
ctl,
|
|
2819
|
-
[inc(1)],
|
|
3102
|
+
[{ stream: ctl, msgs: [inc(1)] }],
|
|
2820
3103
|
make_meta({ stream: ctl })
|
|
2821
3104
|
);
|
|
2822
3105
|
const n = await store.defer(
|
|
@@ -2838,8 +3121,7 @@ var runStoreTck = (options) => {
|
|
|
2838
3121
|
const s = `defer-dup-${uid()}`;
|
|
2839
3122
|
await store.subscribe([{ stream: s }]);
|
|
2840
3123
|
await store.commit(
|
|
2841
|
-
s,
|
|
2842
|
-
[inc(1)],
|
|
3124
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2843
3125
|
make_meta({ stream: s })
|
|
2844
3126
|
);
|
|
2845
3127
|
expect8(await store.defer([s, s], Date.now() + 36e5)).toBe(1);
|
|
@@ -2851,13 +3133,11 @@ var runStoreTck = (options) => {
|
|
|
2851
3133
|
const ctl = `ackdefer-ctl-${uid()}`;
|
|
2852
3134
|
await store.subscribe([{ stream: s }, { stream: ctl }]);
|
|
2853
3135
|
await store.commit(
|
|
2854
|
-
s,
|
|
2855
|
-
[inc(1)],
|
|
3136
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2856
3137
|
make_meta({ stream: s })
|
|
2857
3138
|
);
|
|
2858
3139
|
const [ctl_head] = await store.commit(
|
|
2859
|
-
ctl,
|
|
2860
|
-
[inc(1)],
|
|
3140
|
+
[{ stream: ctl, msgs: [inc(1)] }],
|
|
2861
3141
|
make_meta({ stream: ctl })
|
|
2862
3142
|
);
|
|
2863
3143
|
await correlate();
|
|
@@ -2871,8 +3151,7 @@ var runStoreTck = (options) => {
|
|
|
2871
3151
|
expect8(acked.find((l) => l.stream === ctl)).toBeDefined();
|
|
2872
3152
|
expect8(acked.find((l) => l.stream === s)).toBeUndefined();
|
|
2873
3153
|
await store.commit(
|
|
2874
|
-
ctl,
|
|
2875
|
-
[inc(2)],
|
|
3154
|
+
[{ stream: ctl, msgs: [inc(2)] }],
|
|
2876
3155
|
make_meta({ stream: ctl })
|
|
2877
3156
|
);
|
|
2878
3157
|
await correlate();
|
|
@@ -2884,8 +3163,7 @@ var runStoreTck = (options) => {
|
|
|
2884
3163
|
const s = `ackdefer-past-${uid()}`;
|
|
2885
3164
|
await store.subscribe([{ stream: s }]);
|
|
2886
3165
|
await store.commit(
|
|
2887
|
-
s,
|
|
2888
|
-
[inc(1)],
|
|
3166
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2889
3167
|
make_meta({ stream: s })
|
|
2890
3168
|
);
|
|
2891
3169
|
await correlate();
|
|
@@ -2904,8 +3182,7 @@ var runStoreTck = (options) => {
|
|
|
2904
3182
|
const s = `ackdefer-retry-${uid()}`;
|
|
2905
3183
|
await store.subscribe([{ stream: s }]);
|
|
2906
3184
|
await store.commit(
|
|
2907
|
-
s,
|
|
2908
|
-
[inc(1)],
|
|
3185
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2909
3186
|
make_meta({ stream: s })
|
|
2910
3187
|
);
|
|
2911
3188
|
await correlate();
|
|
@@ -2924,13 +3201,11 @@ var runStoreTck = (options) => {
|
|
|
2924
3201
|
const s = `ackadvance-${uid()}`;
|
|
2925
3202
|
await store.subscribe([{ stream: s }]);
|
|
2926
3203
|
const [e1] = await store.commit(
|
|
2927
|
-
s,
|
|
2928
|
-
[inc(1)],
|
|
3204
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2929
3205
|
make_meta({ stream: s })
|
|
2930
3206
|
);
|
|
2931
3207
|
await store.commit(
|
|
2932
|
-
s,
|
|
2933
|
-
[inc(1)],
|
|
3208
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2934
3209
|
make_meta({ stream: s })
|
|
2935
3210
|
);
|
|
2936
3211
|
await correlate();
|
|
@@ -2952,8 +3227,7 @@ var runStoreTck = (options) => {
|
|
|
2952
3227
|
const s = `ackdefer-owner-${uid()}`;
|
|
2953
3228
|
await store.subscribe([{ stream: s }]);
|
|
2954
3229
|
await store.commit(
|
|
2955
|
-
s,
|
|
2956
|
-
[inc(1)],
|
|
3230
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2957
3231
|
make_meta({ stream: s })
|
|
2958
3232
|
);
|
|
2959
3233
|
await correlate();
|
|
@@ -2971,8 +3245,7 @@ var runStoreTck = (options) => {
|
|
|
2971
3245
|
const s = `reset-${uid()}`;
|
|
2972
3246
|
await store.subscribe([{ stream: s }]);
|
|
2973
3247
|
await store.commit(
|
|
2974
|
-
s,
|
|
2975
|
-
[inc(1)],
|
|
3248
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2976
3249
|
make_meta({ stream: s })
|
|
2977
3250
|
);
|
|
2978
3251
|
await correlate();
|
|
@@ -2991,8 +3264,7 @@ var runStoreTck = (options) => {
|
|
|
2991
3264
|
const s = `reset-blk-${uid()}`;
|
|
2992
3265
|
await store.subscribe([{ stream: s }]);
|
|
2993
3266
|
await store.commit(
|
|
2994
|
-
s,
|
|
2995
|
-
[inc(1)],
|
|
3267
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
2996
3268
|
make_meta({ stream: s })
|
|
2997
3269
|
);
|
|
2998
3270
|
await correlate();
|
|
@@ -3014,8 +3286,7 @@ var runStoreTck = (options) => {
|
|
|
3014
3286
|
const s = `reset-dup-${uid()}`;
|
|
3015
3287
|
await store.subscribe([{ stream: s }]);
|
|
3016
3288
|
await store.commit(
|
|
3017
|
-
s,
|
|
3018
|
-
[inc(1)],
|
|
3289
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
3019
3290
|
make_meta({ stream: s })
|
|
3020
3291
|
);
|
|
3021
3292
|
expect8(await store.reset([s, s])).toBe(1);
|
|
@@ -3026,13 +3297,11 @@ var runStoreTck = (options) => {
|
|
|
3026
3297
|
const s = `unblock-${uid()}`;
|
|
3027
3298
|
await store.subscribe([{ stream: s }]);
|
|
3028
3299
|
await store.commit(
|
|
3029
|
-
s,
|
|
3030
|
-
[inc(1)],
|
|
3300
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
3031
3301
|
make_meta({ stream: s })
|
|
3032
3302
|
);
|
|
3033
3303
|
await store.commit(
|
|
3034
|
-
s,
|
|
3035
|
-
[inc(2)],
|
|
3304
|
+
[{ stream: s, msgs: [inc(2)] }],
|
|
3036
3305
|
make_meta({ stream: s })
|
|
3037
3306
|
);
|
|
3038
3307
|
await correlate();
|
|
@@ -3065,8 +3334,7 @@ var runStoreTck = (options) => {
|
|
|
3065
3334
|
const s = `unblock-noop-${uid()}`;
|
|
3066
3335
|
await store.subscribe([{ stream: s }]);
|
|
3067
3336
|
await store.commit(
|
|
3068
|
-
s,
|
|
3069
|
-
[inc(1)],
|
|
3337
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
3070
3338
|
make_meta({ stream: s })
|
|
3071
3339
|
);
|
|
3072
3340
|
expect8(await store.unblock([s])).toBe(0);
|
|
@@ -3080,13 +3348,11 @@ var runStoreTck = (options) => {
|
|
|
3080
3348
|
const s2 = `unblock-mix-b-${uid()}`;
|
|
3081
3349
|
await store.subscribe([{ stream: s1 }, { stream: s2 }]);
|
|
3082
3350
|
await store.commit(
|
|
3083
|
-
s1,
|
|
3084
|
-
[inc(1)],
|
|
3351
|
+
[{ stream: s1, msgs: [inc(1)] }],
|
|
3085
3352
|
make_meta({ stream: s1 })
|
|
3086
3353
|
);
|
|
3087
3354
|
await store.commit(
|
|
3088
|
-
s2,
|
|
3089
|
-
[inc(1)],
|
|
3355
|
+
[{ stream: s2, msgs: [inc(1)] }],
|
|
3090
3356
|
make_meta({ stream: s2 })
|
|
3091
3357
|
);
|
|
3092
3358
|
await correlate();
|
|
@@ -3104,18 +3370,15 @@ var runStoreTck = (options) => {
|
|
|
3104
3370
|
const s3 = `other-${tag}`;
|
|
3105
3371
|
await store.subscribe([{ stream: s1 }, { stream: s2 }, { stream: s3 }]);
|
|
3106
3372
|
await store.commit(
|
|
3107
|
-
s1,
|
|
3108
|
-
[inc(1)],
|
|
3373
|
+
[{ stream: s1, msgs: [inc(1)] }],
|
|
3109
3374
|
make_meta({ stream: s1 })
|
|
3110
3375
|
);
|
|
3111
3376
|
await store.commit(
|
|
3112
|
-
s2,
|
|
3113
|
-
[inc(1)],
|
|
3377
|
+
[{ stream: s2, msgs: [inc(1)] }],
|
|
3114
3378
|
make_meta({ stream: s2 })
|
|
3115
3379
|
);
|
|
3116
3380
|
await store.commit(
|
|
3117
|
-
s3,
|
|
3118
|
-
[inc(1)],
|
|
3381
|
+
[{ stream: s3, msgs: [inc(1)] }],
|
|
3119
3382
|
make_meta({ stream: s3 })
|
|
3120
3383
|
);
|
|
3121
3384
|
await correlate();
|
|
@@ -3143,13 +3406,11 @@ var runStoreTck = (options) => {
|
|
|
3143
3406
|
const s2 = `unblock-empty-${tag}-b`;
|
|
3144
3407
|
await store.subscribe([{ stream: s1 }, { stream: s2 }]);
|
|
3145
3408
|
await store.commit(
|
|
3146
|
-
s1,
|
|
3147
|
-
[inc(1)],
|
|
3409
|
+
[{ stream: s1, msgs: [inc(1)] }],
|
|
3148
3410
|
make_meta({ stream: s1 })
|
|
3149
3411
|
);
|
|
3150
3412
|
await store.commit(
|
|
3151
|
-
s2,
|
|
3152
|
-
[inc(1)],
|
|
3413
|
+
[{ stream: s2, msgs: [inc(1)] }],
|
|
3153
3414
|
make_meta({ stream: s2 })
|
|
3154
3415
|
);
|
|
3155
3416
|
await correlate();
|
|
@@ -3169,8 +3430,7 @@ var runStoreTck = (options) => {
|
|
|
3169
3430
|
const s = `unblock-blocked-false-${tag}`;
|
|
3170
3431
|
await store.subscribe([{ stream: s }]);
|
|
3171
3432
|
await store.commit(
|
|
3172
|
-
s,
|
|
3173
|
-
[inc(1)],
|
|
3433
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
3174
3434
|
make_meta({ stream: s })
|
|
3175
3435
|
);
|
|
3176
3436
|
expect8(
|
|
@@ -3193,18 +3453,15 @@ var runStoreTck = (options) => {
|
|
|
3193
3453
|
{ stream: other }
|
|
3194
3454
|
]);
|
|
3195
3455
|
await store.commit(
|
|
3196
|
-
s1,
|
|
3197
|
-
[inc(1)],
|
|
3456
|
+
[{ stream: s1, msgs: [inc(1)] }],
|
|
3198
3457
|
make_meta({ stream: s1 })
|
|
3199
3458
|
);
|
|
3200
3459
|
await store.commit(
|
|
3201
|
-
s2,
|
|
3202
|
-
[inc(1)],
|
|
3460
|
+
[{ stream: s2, msgs: [inc(1)] }],
|
|
3203
3461
|
make_meta({ stream: s2 })
|
|
3204
3462
|
);
|
|
3205
3463
|
await store.commit(
|
|
3206
|
-
other,
|
|
3207
|
-
[inc(1)],
|
|
3464
|
+
[{ stream: other, msgs: [inc(1)] }],
|
|
3208
3465
|
make_meta({ stream: other })
|
|
3209
3466
|
);
|
|
3210
3467
|
await correlate();
|
|
@@ -3235,13 +3492,11 @@ var runStoreTck = (options) => {
|
|
|
3235
3492
|
const s2 = `reset-blocked-${tag}-fine`;
|
|
3236
3493
|
await store.subscribe([{ stream: s1 }, { stream: s2 }]);
|
|
3237
3494
|
await store.commit(
|
|
3238
|
-
s1,
|
|
3239
|
-
[inc(1)],
|
|
3495
|
+
[{ stream: s1, msgs: [inc(1)] }],
|
|
3240
3496
|
make_meta({ stream: s1 })
|
|
3241
3497
|
);
|
|
3242
3498
|
await store.commit(
|
|
3243
|
-
s2,
|
|
3244
|
-
[inc(1)],
|
|
3499
|
+
[{ stream: s2, msgs: [inc(1)] }],
|
|
3245
3500
|
make_meta({ stream: s2 })
|
|
3246
3501
|
);
|
|
3247
3502
|
await correlate();
|
|
@@ -3320,8 +3575,7 @@ var runStoreTck = (options) => {
|
|
|
3320
3575
|
const ok = `pri-${tag}-ok`;
|
|
3321
3576
|
const bad = `pri-${tag}-bad`;
|
|
3322
3577
|
await fresh.commit(
|
|
3323
|
-
src,
|
|
3324
|
-
[inc(1)],
|
|
3578
|
+
[{ stream: src, msgs: [inc(1)] }],
|
|
3325
3579
|
make_meta({ stream: src })
|
|
3326
3580
|
);
|
|
3327
3581
|
await fresh.subscribe([
|
|
@@ -3367,8 +3621,7 @@ var runStoreTck = (options) => {
|
|
|
3367
3621
|
const tag = uid();
|
|
3368
3622
|
const src = `pri-src-${tag}`;
|
|
3369
3623
|
await fresh.commit(
|
|
3370
|
-
src,
|
|
3371
|
-
[inc(1), inc(2)],
|
|
3624
|
+
[{ stream: src, msgs: [inc(1), inc(2)] }],
|
|
3372
3625
|
make_meta({ stream: src })
|
|
3373
3626
|
);
|
|
3374
3627
|
await fresh.subscribe([
|
|
@@ -3466,13 +3719,11 @@ var runStoreTck = (options) => {
|
|
|
3466
3719
|
const sub_default = `lane-claim-def-${tag}`;
|
|
3467
3720
|
const sub_slow = `lane-claim-slow-${tag}`;
|
|
3468
3721
|
await store.commit(
|
|
3469
|
-
src1,
|
|
3470
|
-
[inc(1)],
|
|
3722
|
+
[{ stream: src1, msgs: [inc(1)] }],
|
|
3471
3723
|
make_meta({ stream: src1 })
|
|
3472
3724
|
);
|
|
3473
3725
|
await store.commit(
|
|
3474
|
-
src2,
|
|
3475
|
-
[inc(1)],
|
|
3726
|
+
[{ stream: src2, msgs: [inc(1)] }],
|
|
3476
3727
|
make_meta({ stream: src2 })
|
|
3477
3728
|
);
|
|
3478
3729
|
await store.subscribe([
|
|
@@ -3539,8 +3790,7 @@ var runStoreTck = (options) => {
|
|
|
3539
3790
|
const a = `lane-reset-a-${tag}`;
|
|
3540
3791
|
const b = `lane-reset-b-${tag}`;
|
|
3541
3792
|
await store.commit(
|
|
3542
|
-
src,
|
|
3543
|
-
[inc(1)],
|
|
3793
|
+
[{ stream: src, msgs: [inc(1)] }],
|
|
3544
3794
|
make_meta({ stream: src })
|
|
3545
3795
|
);
|
|
3546
3796
|
await store.subscribe([
|
|
@@ -3569,8 +3819,7 @@ var runStoreTck = (options) => {
|
|
|
3569
3819
|
const a = `lane-ub-a-${tag}`;
|
|
3570
3820
|
const b = `lane-ub-b-${tag}`;
|
|
3571
3821
|
await store.commit(
|
|
3572
|
-
src,
|
|
3573
|
-
[inc(1)],
|
|
3822
|
+
[{ stream: src, msgs: [inc(1)] }],
|
|
3574
3823
|
make_meta({ stream: src })
|
|
3575
3824
|
);
|
|
3576
3825
|
await store.subscribe([
|
|
@@ -3599,8 +3848,7 @@ var runStoreTck = (options) => {
|
|
|
3599
3848
|
const tag = uid();
|
|
3600
3849
|
const long = `${tag}-${"x".repeat(140)}`;
|
|
3601
3850
|
await store.commit(
|
|
3602
|
-
long,
|
|
3603
|
-
[inc(1)],
|
|
3851
|
+
[{ stream: long, msgs: [inc(1)] }],
|
|
3604
3852
|
make_meta({ stream: long })
|
|
3605
3853
|
);
|
|
3606
3854
|
await store.subscribe([
|
|
@@ -3625,8 +3873,7 @@ var runStoreTck = (options) => {
|
|
|
3625
3873
|
for (const s of [restarted, retired]) {
|
|
3626
3874
|
await store.subscribe([{ stream: s }]);
|
|
3627
3875
|
await store.commit(
|
|
3628
|
-
s,
|
|
3629
|
-
[inc(1)],
|
|
3876
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
3630
3877
|
make_meta({ stream: s })
|
|
3631
3878
|
);
|
|
3632
3879
|
}
|
|
@@ -3650,8 +3897,7 @@ var runStoreTck = (options) => {
|
|
|
3650
3897
|
const lane = `inert-lane-${uid()}`;
|
|
3651
3898
|
const s = `trunc-inert-${uid()}`;
|
|
3652
3899
|
const [e] = await store.commit(
|
|
3653
|
-
s,
|
|
3654
|
-
[inc(1)],
|
|
3900
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
3655
3901
|
make_meta({ stream: s })
|
|
3656
3902
|
);
|
|
3657
3903
|
await store.subscribe([{ stream: s, correlated_at: e.id, lane }]);
|
|
@@ -3666,8 +3912,7 @@ var runStoreTck = (options) => {
|
|
|
3666
3912
|
it7("seeds a tombstone when no snapshot is provided", async () => {
|
|
3667
3913
|
const s = `trunc-tomb-${uid()}`;
|
|
3668
3914
|
await store.commit(
|
|
3669
|
-
s,
|
|
3670
|
-
[inc(1), inc(2)],
|
|
3915
|
+
[{ stream: s, msgs: [inc(1), inc(2)] }],
|
|
3671
3916
|
make_meta({ stream: s })
|
|
3672
3917
|
);
|
|
3673
3918
|
const result = await store.truncate([{ stream: s }]);
|
|
@@ -3687,8 +3932,7 @@ var runStoreTck = (options) => {
|
|
|
3687
3932
|
it7("seeds a snapshot when one is provided", async () => {
|
|
3688
3933
|
const s = `trunc-snap-${uid()}`;
|
|
3689
3934
|
await store.commit(
|
|
3690
|
-
s,
|
|
3691
|
-
[inc(1)],
|
|
3935
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
3692
3936
|
make_meta({ stream: s })
|
|
3693
3937
|
);
|
|
3694
3938
|
const result = await store.truncate([
|
|
@@ -3711,8 +3955,7 @@ var runStoreTck = (options) => {
|
|
|
3711
3955
|
it7("leaves exactly one seed when a stream is listed twice", async () => {
|
|
3712
3956
|
const s = `trunc-dup-${uid()}`;
|
|
3713
3957
|
await store.commit(
|
|
3714
|
-
s,
|
|
3715
|
-
[inc(1), inc(2)],
|
|
3958
|
+
[{ stream: s, msgs: [inc(1), inc(2)] }],
|
|
3716
3959
|
make_meta({ stream: s })
|
|
3717
3960
|
);
|
|
3718
3961
|
const result = await store.truncate([
|
|
@@ -3733,13 +3976,11 @@ var runStoreTck = (options) => {
|
|
|
3733
3976
|
it7("applies windowed targets before full ones", async () => {
|
|
3734
3977
|
const s = `trunc-mix-${uid()}`;
|
|
3735
3978
|
await store.commit(
|
|
3736
|
-
s,
|
|
3737
|
-
[inc(1)],
|
|
3979
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
3738
3980
|
make_meta({ stream: s })
|
|
3739
3981
|
);
|
|
3740
3982
|
await store.commit(
|
|
3741
|
-
s,
|
|
3742
|
-
[inc(2)],
|
|
3983
|
+
[{ stream: s, msgs: [inc(2)] }],
|
|
3743
3984
|
make_meta({ stream: s })
|
|
3744
3985
|
);
|
|
3745
3986
|
await sleep(5);
|
|
@@ -3776,28 +4017,23 @@ var runStoreTck = (options) => {
|
|
|
3776
4017
|
describe8("windowed (before boundary)", () => {
|
|
3777
4018
|
async function seed_windowed(s) {
|
|
3778
4019
|
await store.commit(
|
|
3779
|
-
s,
|
|
3780
|
-
[inc(1), inc(1)],
|
|
4020
|
+
[{ stream: s, msgs: [inc(1), inc(1)] }],
|
|
3781
4021
|
make_meta({ stream: s })
|
|
3782
4022
|
);
|
|
3783
4023
|
const [snap_a] = await store.commit(
|
|
3784
|
-
s,
|
|
3785
|
-
[{ name: SNAP_EVENT2, data: { count: 2 } }],
|
|
4024
|
+
[{ stream: s, msgs: [{ name: SNAP_EVENT2, data: { count: 2 } }] }],
|
|
3786
4025
|
make_meta({ stream: s })
|
|
3787
4026
|
);
|
|
3788
4027
|
await store.commit(
|
|
3789
|
-
s,
|
|
3790
|
-
[inc(1)],
|
|
4028
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
3791
4029
|
make_meta({ stream: s })
|
|
3792
4030
|
);
|
|
3793
4031
|
const [snap_b] = await store.commit(
|
|
3794
|
-
s,
|
|
3795
|
-
[{ name: SNAP_EVENT2, data: { count: 3 } }],
|
|
4032
|
+
[{ stream: s, msgs: [{ name: SNAP_EVENT2, data: { count: 3 } }] }],
|
|
3796
4033
|
make_meta({ stream: s })
|
|
3797
4034
|
);
|
|
3798
4035
|
await store.commit(
|
|
3799
|
-
s,
|
|
3800
|
-
[inc(1)],
|
|
4036
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
3801
4037
|
make_meta({ stream: s })
|
|
3802
4038
|
);
|
|
3803
4039
|
return { snap_a, snap_b };
|
|
@@ -3867,8 +4103,7 @@ var runStoreTck = (options) => {
|
|
|
3867
4103
|
it7("no-ops when no snapshot qualifies \u2014 stream absent from the result, events untouched", async () => {
|
|
3868
4104
|
const s = `trunc-win-noop-${uid()}`;
|
|
3869
4105
|
await store.commit(
|
|
3870
|
-
s,
|
|
3871
|
-
[inc(1), inc(1)],
|
|
4106
|
+
[{ stream: s, msgs: [inc(1), inc(1)] }],
|
|
3872
4107
|
make_meta({ stream: s })
|
|
3873
4108
|
);
|
|
3874
4109
|
const none = await store.truncate([
|
|
@@ -3876,8 +4111,7 @@ var runStoreTck = (options) => {
|
|
|
3876
4111
|
]);
|
|
3877
4112
|
expect8(none.has(s)).toBe(false);
|
|
3878
4113
|
await store.commit(
|
|
3879
|
-
s,
|
|
3880
|
-
[{ name: SNAP_EVENT2, data: { count: 2 } }],
|
|
4114
|
+
[{ stream: s, msgs: [{ name: SNAP_EVENT2, data: { count: 2 } }] }],
|
|
3881
4115
|
make_meta({ stream: s })
|
|
3882
4116
|
);
|
|
3883
4117
|
const too_early = await store.truncate([
|
|
@@ -3915,8 +4149,7 @@ var runStoreTck = (options) => {
|
|
|
3915
4149
|
const f = `trunc-win-mix-f-${uid()}`;
|
|
3916
4150
|
const { snap_b } = await seed_windowed(w);
|
|
3917
4151
|
await store.commit(
|
|
3918
|
-
f,
|
|
3919
|
-
[inc(1)],
|
|
4152
|
+
[{ stream: f, msgs: [inc(1)] }],
|
|
3920
4153
|
make_meta({ stream: f })
|
|
3921
4154
|
);
|
|
3922
4155
|
const result = await store.truncate([
|
|
@@ -3936,8 +4169,7 @@ var runStoreTck = (options) => {
|
|
|
3936
4169
|
{ stream: s, before: new Date(Date.now() + 6e4) }
|
|
3937
4170
|
]);
|
|
3938
4171
|
const [next] = await store.commit(
|
|
3939
|
-
s,
|
|
3940
|
-
[inc(1)],
|
|
4172
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
3941
4173
|
make_meta({ stream: s })
|
|
3942
4174
|
);
|
|
3943
4175
|
expect8(next.version).toBe(6);
|
|
@@ -4075,8 +4307,7 @@ var runStoreTck = (options) => {
|
|
|
4075
4307
|
const sibling = `qb-${tag}-other`;
|
|
4076
4308
|
await store.subscribe([{ stream: s }, { stream: sibling }]);
|
|
4077
4309
|
await store.commit(
|
|
4078
|
-
s,
|
|
4079
|
-
[inc(1)],
|
|
4310
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
4080
4311
|
make_meta({ stream: s })
|
|
4081
4312
|
);
|
|
4082
4313
|
await correlate();
|
|
@@ -4107,18 +4338,15 @@ var runStoreTck = (options) => {
|
|
|
4107
4338
|
const sB = `qst-${tag}-b`;
|
|
4108
4339
|
const sUnasked = `qst-${tag}-unasked`;
|
|
4109
4340
|
await store.commit(
|
|
4110
|
-
sA,
|
|
4111
|
-
[inc(1), inc(2)],
|
|
4341
|
+
[{ stream: sA, msgs: [inc(1), inc(2)] }],
|
|
4112
4342
|
make_meta({ stream: sA })
|
|
4113
4343
|
);
|
|
4114
4344
|
await store.commit(
|
|
4115
|
-
sB,
|
|
4116
|
-
[dec(5)],
|
|
4345
|
+
[{ stream: sB, msgs: [dec(5)] }],
|
|
4117
4346
|
make_meta({ stream: sB })
|
|
4118
4347
|
);
|
|
4119
4348
|
await store.commit(
|
|
4120
|
-
sUnasked,
|
|
4121
|
-
[inc(99)],
|
|
4349
|
+
[{ stream: sUnasked, msgs: [inc(99)] }],
|
|
4122
4350
|
make_meta({ stream: sUnasked })
|
|
4123
4351
|
);
|
|
4124
4352
|
const stats = await store.query_stats([sA, sB]);
|
|
@@ -4136,8 +4364,7 @@ var runStoreTck = (options) => {
|
|
|
4136
4364
|
it7("limit: 0 returns no rows", async () => {
|
|
4137
4365
|
const s = `qst-zero-${uid()}`;
|
|
4138
4366
|
await store.commit(
|
|
4139
|
-
s,
|
|
4140
|
-
[inc(1)],
|
|
4367
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
4141
4368
|
make_meta({ stream: s })
|
|
4142
4369
|
);
|
|
4143
4370
|
const filter = { stream: s, stream_exact: true };
|
|
@@ -4158,8 +4385,7 @@ var runStoreTck = (options) => {
|
|
|
4158
4385
|
];
|
|
4159
4386
|
for (const s of names)
|
|
4160
4387
|
await store.commit(
|
|
4161
|
-
s,
|
|
4162
|
-
[inc(1)],
|
|
4388
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
4163
4389
|
make_meta({ stream: s })
|
|
4164
4390
|
);
|
|
4165
4391
|
const visited = [];
|
|
@@ -4182,18 +4408,15 @@ var runStoreTck = (options) => {
|
|
|
4182
4408
|
const tag = uid();
|
|
4183
4409
|
const s = `qst-tail-${tag}`;
|
|
4184
4410
|
await store.commit(
|
|
4185
|
-
s,
|
|
4186
|
-
[inc(1)],
|
|
4411
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
4187
4412
|
make_meta({ stream: s })
|
|
4188
4413
|
);
|
|
4189
4414
|
await store.commit(
|
|
4190
|
-
s,
|
|
4191
|
-
[inc(2)],
|
|
4415
|
+
[{ stream: s, msgs: [inc(2)] }],
|
|
4192
4416
|
make_meta({ stream: s })
|
|
4193
4417
|
);
|
|
4194
4418
|
await store.commit(
|
|
4195
|
-
s,
|
|
4196
|
-
[inc(3)],
|
|
4419
|
+
[{ stream: s, msgs: [inc(3)] }],
|
|
4197
4420
|
make_meta({ stream: s })
|
|
4198
4421
|
);
|
|
4199
4422
|
const stats = await store.query_stats([s], {
|
|
@@ -4209,14 +4432,12 @@ var runStoreTck = (options) => {
|
|
|
4209
4432
|
const tag = uid();
|
|
4210
4433
|
const s = `qst-cn-${tag}`;
|
|
4211
4434
|
await store.commit(
|
|
4212
|
-
s,
|
|
4213
|
-
[inc(1)],
|
|
4435
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
4214
4436
|
make_meta({ stream: s })
|
|
4215
4437
|
);
|
|
4216
4438
|
await store.truncate([{ stream: s, snapshot: { count: 99 } }]);
|
|
4217
4439
|
await store.commit(
|
|
4218
|
-
s,
|
|
4219
|
-
[inc(2), inc(3), dec(1)],
|
|
4440
|
+
[{ stream: s, msgs: [inc(2), inc(3), dec(1)] }],
|
|
4220
4441
|
make_meta({ stream: s })
|
|
4221
4442
|
);
|
|
4222
4443
|
const stats = await store.query_stats([s], {
|
|
@@ -4235,13 +4456,11 @@ var runStoreTck = (options) => {
|
|
|
4235
4456
|
const s = `qst-excl-${tag}`;
|
|
4236
4457
|
const sAllOut = `qst-allout-${tag}`;
|
|
4237
4458
|
await store.commit(
|
|
4238
|
-
s,
|
|
4239
|
-
[inc(1), dec(2), inc(3)],
|
|
4459
|
+
[{ stream: s, msgs: [inc(1), dec(2), inc(3)] }],
|
|
4240
4460
|
make_meta({ stream: s })
|
|
4241
4461
|
);
|
|
4242
4462
|
await store.commit(
|
|
4243
|
-
sAllOut,
|
|
4244
|
-
[inc(7)],
|
|
4463
|
+
[{ stream: sAllOut, msgs: [inc(7)] }],
|
|
4245
4464
|
make_meta({ stream: sAllOut })
|
|
4246
4465
|
);
|
|
4247
4466
|
const all = await store.query_stats([s]);
|
|
@@ -4265,18 +4484,15 @@ var runStoreTck = (options) => {
|
|
|
4265
4484
|
const tag = uid();
|
|
4266
4485
|
const s = `qst-tt-${tag}`;
|
|
4267
4486
|
const c1 = await store.commit(
|
|
4268
|
-
s,
|
|
4269
|
-
[inc(1)],
|
|
4487
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
4270
4488
|
make_meta({ stream: s })
|
|
4271
4489
|
);
|
|
4272
4490
|
const c2 = await store.commit(
|
|
4273
|
-
s,
|
|
4274
|
-
[inc(2)],
|
|
4491
|
+
[{ stream: s, msgs: [inc(2)] }],
|
|
4275
4492
|
make_meta({ stream: s })
|
|
4276
4493
|
);
|
|
4277
4494
|
await store.commit(
|
|
4278
|
-
s,
|
|
4279
|
-
[inc(3)],
|
|
4495
|
+
[{ stream: s, msgs: [inc(3)] }],
|
|
4280
4496
|
make_meta({ stream: s })
|
|
4281
4497
|
);
|
|
4282
4498
|
const before = c2[0].id;
|
|
@@ -4300,18 +4516,15 @@ var runStoreTck = (options) => {
|
|
|
4300
4516
|
const sB = `qsf-${tag}-orders-2`;
|
|
4301
4517
|
const sOther = `qsf-${tag}-users-1`;
|
|
4302
4518
|
await store.commit(
|
|
4303
|
-
sA,
|
|
4304
|
-
[inc(1)],
|
|
4519
|
+
[{ stream: sA, msgs: [inc(1)] }],
|
|
4305
4520
|
make_meta({ stream: sA })
|
|
4306
4521
|
);
|
|
4307
4522
|
await store.commit(
|
|
4308
|
-
sB,
|
|
4309
|
-
[inc(2)],
|
|
4523
|
+
[{ stream: sB, msgs: [inc(2)] }],
|
|
4310
4524
|
make_meta({ stream: sB })
|
|
4311
4525
|
);
|
|
4312
4526
|
await store.commit(
|
|
4313
|
-
sOther,
|
|
4314
|
-
[inc(3)],
|
|
4527
|
+
[{ stream: sOther, msgs: [inc(3)] }],
|
|
4315
4528
|
make_meta({ stream: sOther })
|
|
4316
4529
|
);
|
|
4317
4530
|
const orders = await store.query_stats({
|
|
@@ -4334,13 +4547,11 @@ var runStoreTck = (options) => {
|
|
|
4334
4547
|
const b = `qsc-${tag}-b`;
|
|
4335
4548
|
await store.subscribe([{ stream: a }, { stream: b }]);
|
|
4336
4549
|
await store.commit(
|
|
4337
|
-
a,
|
|
4338
|
-
[inc(1)],
|
|
4550
|
+
[{ stream: a, msgs: [inc(1)] }],
|
|
4339
4551
|
make_meta({ stream: a })
|
|
4340
4552
|
);
|
|
4341
4553
|
await store.commit(
|
|
4342
|
-
b,
|
|
4343
|
-
[inc(2)],
|
|
4554
|
+
[{ stream: b, msgs: [inc(2)] }],
|
|
4344
4555
|
make_meta({ stream: b })
|
|
4345
4556
|
);
|
|
4346
4557
|
await correlate();
|
|
@@ -4365,13 +4576,11 @@ var runStoreTck = (options) => {
|
|
|
4365
4576
|
const a = `qse-${tag}-a`;
|
|
4366
4577
|
const b = `qse-${tag}-b`;
|
|
4367
4578
|
await store.commit(
|
|
4368
|
-
a,
|
|
4369
|
-
[inc(1)],
|
|
4579
|
+
[{ stream: a, msgs: [inc(1)] }],
|
|
4370
4580
|
make_meta({ stream: a })
|
|
4371
4581
|
);
|
|
4372
4582
|
await store.commit(
|
|
4373
|
-
b,
|
|
4374
|
-
[dec(2)],
|
|
4583
|
+
[{ stream: b, msgs: [dec(2)] }],
|
|
4375
4584
|
make_meta({ stream: b })
|
|
4376
4585
|
);
|
|
4377
4586
|
const all = await store.query_stats({});
|
|
@@ -4382,8 +4591,7 @@ var runStoreTck = (options) => {
|
|
|
4382
4591
|
const tag = uid();
|
|
4383
4592
|
const s = `qsfl-${tag}`;
|
|
4384
4593
|
await store.commit(
|
|
4385
|
-
s,
|
|
4386
|
-
[inc(1), inc(2), dec(3)],
|
|
4594
|
+
[{ stream: s, msgs: [inc(1), inc(2), dec(3)] }],
|
|
4387
4595
|
make_meta({ stream: s })
|
|
4388
4596
|
);
|
|
4389
4597
|
const c = await store.query_stats([s], {
|
|
@@ -4414,8 +4622,7 @@ var runStoreTck = (options) => {
|
|
|
4414
4622
|
];
|
|
4415
4623
|
for (const s of streams) {
|
|
4416
4624
|
await store.commit(
|
|
4417
|
-
s,
|
|
4418
|
-
[inc(1)],
|
|
4625
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
4419
4626
|
make_meta({ stream: s })
|
|
4420
4627
|
);
|
|
4421
4628
|
}
|
|
@@ -4445,8 +4652,7 @@ var runStoreTck = (options) => {
|
|
|
4445
4652
|
const tag = uid();
|
|
4446
4653
|
for (const s of [`qsc-${tag}-c`, `qsc-${tag}-a`, `qsc-${tag}-b`])
|
|
4447
4654
|
await store.commit(
|
|
4448
|
-
s,
|
|
4449
|
-
[inc(1), inc(2)],
|
|
4655
|
+
[{ stream: s, msgs: [inc(1), inc(2)] }],
|
|
4450
4656
|
make_meta({ stream: s })
|
|
4451
4657
|
);
|
|
4452
4658
|
const pattern = { stream: `qsc-${tag}-.*` };
|
|
@@ -4595,8 +4801,7 @@ var runStoreTck = (options) => {
|
|
|
4595
4801
|
const s = `head-${uid()}`;
|
|
4596
4802
|
await store.subscribe([{ stream: s }]);
|
|
4597
4803
|
await store.commit(
|
|
4598
|
-
s,
|
|
4599
|
-
[inc(1)],
|
|
4804
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
4600
4805
|
make_meta({ stream: s })
|
|
4601
4806
|
);
|
|
4602
4807
|
const positions = [];
|
|
@@ -4612,7 +4817,7 @@ var runStoreTck = (options) => {
|
|
|
4612
4817
|
const actor2 = { id: "reader", name: "Reader" };
|
|
4613
4818
|
const reader = (shape) => {
|
|
4614
4819
|
const Happened = z2.object(shape);
|
|
4615
|
-
return state({ Reader: z2.object({ n: z2.number() }) }).init(() => ({ n: 0 })).emits({ Happened }).patch({ Happened: (_, s) => ({ n: s.n + 1 }) }).on({ Do: Happened }).emit(
|
|
4820
|
+
return state({ Reader: z2.object({ n: z2.number() }) }).init(() => ({ n: 0 })).emits({ Happened }).patch({ Happened: (_, s) => ({ n: s.n + 1 }) }).on({ Do: Happened }).emit("Happened").build();
|
|
4616
4821
|
};
|
|
4617
4822
|
const over = async (S) => {
|
|
4618
4823
|
const fresh = await options.factory();
|
|
@@ -4705,10 +4910,16 @@ var runStoreTck = (options) => {
|
|
|
4705
4910
|
const t = await over(S);
|
|
4706
4911
|
try {
|
|
4707
4912
|
await t.fresh.commit(
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4913
|
+
[
|
|
4914
|
+
{
|
|
4915
|
+
stream: t.stream,
|
|
4916
|
+
msgs: [
|
|
4917
|
+
{ name: "Happened", data: { at: /* @__PURE__ */ new Date("2020-01-01") } }
|
|
4918
|
+
],
|
|
4919
|
+
expectedVersion: -1
|
|
4920
|
+
}
|
|
4921
|
+
],
|
|
4922
|
+
raw
|
|
4712
4923
|
);
|
|
4713
4924
|
const d = await t.read();
|
|
4714
4925
|
expect8(d.label).toBeUndefined();
|
|
@@ -4722,10 +4933,14 @@ var runStoreTck = (options) => {
|
|
|
4722
4933
|
const t = await over(S);
|
|
4723
4934
|
try {
|
|
4724
4935
|
await t.fresh.commit(
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4936
|
+
[
|
|
4937
|
+
{
|
|
4938
|
+
stream: t.stream,
|
|
4939
|
+
msgs: [{ name: "Happened", data: { at: "not a date" } }],
|
|
4940
|
+
expectedVersion: -1
|
|
4941
|
+
}
|
|
4942
|
+
],
|
|
4943
|
+
raw
|
|
4729
4944
|
);
|
|
4730
4945
|
expect8((await t.read()).at).toBe("not a date");
|
|
4731
4946
|
} finally {
|
|
@@ -4865,6 +5080,19 @@ var runStoreTck = (options) => {
|
|
|
4865
5080
|
expect8((await take(k, who)).correlating).toBe(true);
|
|
4866
5081
|
await release(k, who);
|
|
4867
5082
|
});
|
|
5083
|
+
it7("advances the checkpoint for a caller refused the lease", async () => {
|
|
5084
|
+
const k = key();
|
|
5085
|
+
const holder = by();
|
|
5086
|
+
expect8((await take(k, holder)).correlating).toBe(true);
|
|
5087
|
+
const refused = await store.subscribe([], 123456, {
|
|
5088
|
+
key: k,
|
|
5089
|
+
by: by(),
|
|
5090
|
+
millis: 1e4
|
|
5091
|
+
});
|
|
5092
|
+
expect8(refused.correlating).toBe(false);
|
|
5093
|
+
expect8((await take(k, holder)).correlated_at).toBe(123456);
|
|
5094
|
+
await release(k, holder);
|
|
5095
|
+
});
|
|
4868
5096
|
it7("answers undefined when no correlator is supplied", async () => {
|
|
4869
5097
|
expect8(await store.subscribe([])).not.toHaveProperty("correlating");
|
|
4870
5098
|
});
|
|
@@ -4946,7 +5174,234 @@ var runStoreTck = (options) => {
|
|
|
4946
5174
|
});
|
|
4947
5175
|
}
|
|
4948
5176
|
);
|
|
5177
|
+
describe8("an action across streams", () => {
|
|
5178
|
+
const SeatTaken = z2.object({ student: z2.string() });
|
|
5179
|
+
const Seats = state({
|
|
5180
|
+
Seats: z2.object({ taken: z2.number() }).refine((s) => s.taken <= 3, "the course is full")
|
|
5181
|
+
}).init(() => ({ taken: 0 })).emits({ SeatTaken }).patch({ SeatTaken: (_, s) => ({ taken: s.taken + 1 }) }).on({ TakeSeat: SeatTaken }).emit("SeatTaken").build();
|
|
5182
|
+
const Enroll = z2.object({ course: z2.string(), student: z2.string() });
|
|
5183
|
+
const course = (data) => `course-${data.course}`;
|
|
5184
|
+
const Enrollment = state({ Enrollment: Enroll }).init(() => ({ course: "", student: "" })).emits({ Enrolled: Enroll }).on({ Enroll }, { maxRetries: 8 }).loads(Seats, course, ["SeatTaken"]).requires([
|
|
5185
|
+
{
|
|
5186
|
+
description: "the course has a free seat",
|
|
5187
|
+
holds: (_, __, ___, { Seats: Seats2 }) => Seats2.taken < 3
|
|
5188
|
+
}
|
|
5189
|
+
]).emit((data) => [
|
|
5190
|
+
["Enrolled", data],
|
|
5191
|
+
["SeatTaken", { student: data.student }]
|
|
5192
|
+
]).on({ Overfill: Enroll }).loads(Seats, course, ["SeatTaken"]).emit((data) => [
|
|
5193
|
+
["Enrolled", data],
|
|
5194
|
+
["SeatTaken", { student: data.student }]
|
|
5195
|
+
]).build();
|
|
5196
|
+
const actor2 = { id: "a", name: "a" };
|
|
5197
|
+
const at = (stream) => ({ stream, actor: actor2 });
|
|
5198
|
+
const over = async (run) => {
|
|
5199
|
+
const fresh = await options.factory();
|
|
5200
|
+
await fresh.seed();
|
|
5201
|
+
const cache = new InMemoryCache();
|
|
5202
|
+
const app = act().withState(Seats).withState(Enrollment).build({ scoped: { store: fresh, cache } });
|
|
5203
|
+
const c = `c${uid()}`;
|
|
5204
|
+
const events2 = async (stream) => {
|
|
5205
|
+
const found = [];
|
|
5206
|
+
await fresh.query((e) => found.push(e), {
|
|
5207
|
+
stream,
|
|
5208
|
+
stream_exact: true
|
|
5209
|
+
});
|
|
5210
|
+
return found;
|
|
5211
|
+
};
|
|
5212
|
+
try {
|
|
5213
|
+
await run({
|
|
5214
|
+
app,
|
|
5215
|
+
fresh,
|
|
5216
|
+
c,
|
|
5217
|
+
events: events2,
|
|
5218
|
+
seat: (student) => ({ course: c, student })
|
|
5219
|
+
});
|
|
5220
|
+
} finally {
|
|
5221
|
+
vi.restoreAllMocks();
|
|
5222
|
+
await app.shutdown();
|
|
5223
|
+
await cache.dispose();
|
|
5224
|
+
await fresh.dispose();
|
|
5225
|
+
}
|
|
5226
|
+
};
|
|
5227
|
+
it7("commits both streams at once and fires committed once per stream", () => over(async ({ app, c, events: events2, seat }) => {
|
|
5228
|
+
const stream = `enr-${uid()}`;
|
|
5229
|
+
const heard = [];
|
|
5230
|
+
app.on("committed", (s) => heard.push(s));
|
|
5231
|
+
const snapshots = await app.do("Enroll", at(stream), seat("s1"));
|
|
5232
|
+
expect8(snapshots.map((s) => s.event?.name)).toEqual([
|
|
5233
|
+
"Enrolled"
|
|
5234
|
+
]);
|
|
5235
|
+
const [own] = await events2(stream);
|
|
5236
|
+
const [other] = await events2(`course-${c}`);
|
|
5237
|
+
expect8(own.name).toBe("Enrolled");
|
|
5238
|
+
expect8(other.name).toBe("SeatTaken");
|
|
5239
|
+
expect8(other.id).toBeGreaterThan(own.id);
|
|
5240
|
+
expect8(other.meta.correlation).toBe(own.meta.correlation);
|
|
5241
|
+
expect8(heard.map((h) => h[0].event?.stream)).toEqual([
|
|
5242
|
+
stream,
|
|
5243
|
+
`course-${c}`
|
|
5244
|
+
]);
|
|
5245
|
+
expect8((await app.load(Seats, `course-${c}`)).state.taken).toBe(1);
|
|
5246
|
+
}));
|
|
5247
|
+
it7("stores nothing on either stream when a rule or a schema refuses", () => over(async ({ app, c, events: events2, seat }) => {
|
|
5248
|
+
for (const i of [1, 2, 3])
|
|
5249
|
+
await app.do("TakeSeat", at(`course-${c}`), { student: `s${i}` });
|
|
5250
|
+
const [a, b] = [`enr-${uid()}`, `enr-${uid()}`];
|
|
5251
|
+
await expect8(app.do("Enroll", at(a), seat("late"))).rejects.toThrow(
|
|
5252
|
+
PreconditionError
|
|
5253
|
+
);
|
|
5254
|
+
await expect8(app.do("Overfill", at(b), seat("late"))).rejects.toThrow(
|
|
5255
|
+
ValidationError
|
|
5256
|
+
);
|
|
5257
|
+
expect8(await events2(a)).toEqual([]);
|
|
5258
|
+
expect8(await events2(b)).toEqual([]);
|
|
5259
|
+
expect8(await events2(`course-${c}`)).toHaveLength(3);
|
|
5260
|
+
}));
|
|
5261
|
+
it7("a rival on the loaded stream refuses the whole commit, naming that stream", () => over(async ({ app, fresh, c, events: events2, seat }) => {
|
|
5262
|
+
const commit = fresh.commit.bind(fresh);
|
|
5263
|
+
vi.spyOn(fresh, "commit").mockImplementationOnce(
|
|
5264
|
+
async (...args) => {
|
|
5265
|
+
await commit(
|
|
5266
|
+
[
|
|
5267
|
+
{
|
|
5268
|
+
stream: `course-${c}`,
|
|
5269
|
+
msgs: [{ name: "SeatTaken", data: { student: "rival" } }]
|
|
5270
|
+
}
|
|
5271
|
+
],
|
|
5272
|
+
{ correlation: "rival", causation: {} }
|
|
5273
|
+
);
|
|
5274
|
+
return commit(...args);
|
|
5275
|
+
}
|
|
5276
|
+
);
|
|
5277
|
+
const stream = `enr-${uid()}`;
|
|
5278
|
+
const err = await app.do("Overfill", at(stream), seat("s")).catch((e) => e);
|
|
5279
|
+
expect8(err).toBeInstanceOf(ConcurrencyError);
|
|
5280
|
+
expect8(err.stream).toBe(`course-${c}`);
|
|
5281
|
+
expect8(await events2(stream)).toEqual([]);
|
|
5282
|
+
expect8(await events2(`course-${c}`)).toHaveLength(1);
|
|
5283
|
+
}));
|
|
5284
|
+
it7("racing enrollments fill the seats exactly: the rest are refused by the rule", () => over(async ({ app, c, events: events2, seat }) => {
|
|
5285
|
+
const results = await Promise.allSettled(
|
|
5286
|
+
[1, 2, 3, 4, 5, 6].map(
|
|
5287
|
+
(i) => app.do("Enroll", at(`race-${uid()}-${i}`), seat(`s${i}`))
|
|
5288
|
+
)
|
|
5289
|
+
);
|
|
5290
|
+
expect8(results.filter((r) => r.status === "fulfilled")).toHaveLength(
|
|
5291
|
+
3
|
|
5292
|
+
);
|
|
5293
|
+
for (const r of results.filter((r2) => r2.status === "rejected"))
|
|
5294
|
+
expect8(r.reason).toBeInstanceOf(
|
|
5295
|
+
PreconditionError
|
|
5296
|
+
);
|
|
5297
|
+
expect8(await events2(`course-${c}`)).toHaveLength(3);
|
|
5298
|
+
}));
|
|
5299
|
+
});
|
|
4949
5300
|
describe8.skipIf(!caps.restore)("restore (capability)", () => {
|
|
5301
|
+
describe8("what a restore must not get wrong", () => {
|
|
5302
|
+
const edge_uid = () => uid();
|
|
5303
|
+
const E = (data = { a: 1 }, pii) => ({
|
|
5304
|
+
name: "E",
|
|
5305
|
+
data,
|
|
5306
|
+
...pii ? { pii } : {}
|
|
5307
|
+
});
|
|
5308
|
+
const edge_meta = (correlation = "m") => ({ correlation, causation: {} });
|
|
5309
|
+
const rows = async (query) => {
|
|
5310
|
+
const found = [];
|
|
5311
|
+
await store.query((e) => found.push(e), query);
|
|
5312
|
+
return found;
|
|
5313
|
+
};
|
|
5314
|
+
const one = (stream) => ({ stream, stream_exact: true });
|
|
5315
|
+
it7("a commit after restore continues each stream from its restored head", async () => {
|
|
5316
|
+
const a = `a-${edge_uid()}`;
|
|
5317
|
+
await store.commit(
|
|
5318
|
+
[{ stream: a, msgs: [E(), E()] }],
|
|
5319
|
+
edge_meta()
|
|
5320
|
+
);
|
|
5321
|
+
const log = await rows({ with_snaps: true });
|
|
5322
|
+
await store.restore(async (cb) => {
|
|
5323
|
+
for (const e of log) await cb(e);
|
|
5324
|
+
});
|
|
5325
|
+
const [c] = await store.commit(
|
|
5326
|
+
[{ stream: a, msgs: [E()], expectedVersion: 1 }],
|
|
5327
|
+
edge_meta()
|
|
5328
|
+
);
|
|
5329
|
+
expect8(c.version).toBe(2);
|
|
5330
|
+
});
|
|
5331
|
+
it7("restore renumbers: ids are dense whatever the source ids were", async () => {
|
|
5332
|
+
const a = `a-${edge_uid()}`;
|
|
5333
|
+
const ev = (version, id) => ({
|
|
5334
|
+
id,
|
|
5335
|
+
stream: a,
|
|
5336
|
+
version,
|
|
5337
|
+
name: "E",
|
|
5338
|
+
data: {},
|
|
5339
|
+
meta: edge_meta(),
|
|
5340
|
+
created: /* @__PURE__ */ new Date()
|
|
5341
|
+
});
|
|
5342
|
+
const ids = [];
|
|
5343
|
+
await store.restore(async (cb) => {
|
|
5344
|
+
ids.push(await cb(ev(0, 500)));
|
|
5345
|
+
ids.push(await cb(ev(1, 900)));
|
|
5346
|
+
});
|
|
5347
|
+
expect8(ids[1]).toBe(ids[0] + 1);
|
|
5348
|
+
expect8(ids[0]).toBeLessThanOrEqual(1);
|
|
5349
|
+
});
|
|
5350
|
+
it7("changes nothing when it fails", async () => {
|
|
5351
|
+
const a = `rb-${edge_uid()}`;
|
|
5352
|
+
const key = `k-${edge_uid()}`;
|
|
5353
|
+
const sub = `sub-${edge_uid()}`;
|
|
5354
|
+
const committed = await store.commit(
|
|
5355
|
+
[{ stream: a, msgs: [E({}, { email: "x" }), E()] }],
|
|
5356
|
+
edge_meta()
|
|
5357
|
+
);
|
|
5358
|
+
const head = committed.at(-1).id;
|
|
5359
|
+
await store.subscribe([{ stream: sub }], head);
|
|
5360
|
+
const keyed = await store.subscribe([], head, {
|
|
5361
|
+
key,
|
|
5362
|
+
by: "w",
|
|
5363
|
+
millis: 1
|
|
5364
|
+
});
|
|
5365
|
+
const shared = await store.subscribe([]);
|
|
5366
|
+
await expect8(
|
|
5367
|
+
store.restore(async (callback) => {
|
|
5368
|
+
await callback({
|
|
5369
|
+
id: 1,
|
|
5370
|
+
stream: "other",
|
|
5371
|
+
version: 0,
|
|
5372
|
+
name: "E",
|
|
5373
|
+
data: {},
|
|
5374
|
+
meta: edge_meta(),
|
|
5375
|
+
created: /* @__PURE__ */ new Date()
|
|
5376
|
+
});
|
|
5377
|
+
throw new Error("mid-restore");
|
|
5378
|
+
})
|
|
5379
|
+
).rejects.toThrow();
|
|
5380
|
+
const subscriptions = [];
|
|
5381
|
+
await store.query_streams((p) => subscriptions.push(p.stream), {
|
|
5382
|
+
stream: sub,
|
|
5383
|
+
stream_exact: true
|
|
5384
|
+
});
|
|
5385
|
+
expect8(subscriptions).toEqual([sub]);
|
|
5386
|
+
expect8((await store.subscribe([])).correlated_at).toBe(
|
|
5387
|
+
shared.correlated_at
|
|
5388
|
+
);
|
|
5389
|
+
await sleep(5);
|
|
5390
|
+
const keyed_after = await store.subscribe([], void 0, {
|
|
5391
|
+
key,
|
|
5392
|
+
by: "w2",
|
|
5393
|
+
millis: 1
|
|
5394
|
+
});
|
|
5395
|
+
expect8(keyed_after.correlated_at).toBe(keyed.correlated_at);
|
|
5396
|
+
expect8((await rows(one(a)))[0].pii).toEqual({ email: "x" });
|
|
5397
|
+
const [next] = await store.commit(
|
|
5398
|
+
[{ stream: a, msgs: [E()], expectedVersion: 1 }],
|
|
5399
|
+
edge_meta()
|
|
5400
|
+
);
|
|
5401
|
+
expect8(next.version).toBe(2);
|
|
5402
|
+
expect8(next.id).toBeGreaterThan(head);
|
|
5403
|
+
});
|
|
5404
|
+
});
|
|
4950
5405
|
beforeEach(async () => {
|
|
4951
5406
|
await store.drop();
|
|
4952
5407
|
await store.seed();
|
|
@@ -5132,8 +5587,7 @@ var runStoreTck = (options) => {
|
|
|
5132
5587
|
it7("wipes pre-existing events before inserting", async () => {
|
|
5133
5588
|
const old = `restore-old-${uid()}`;
|
|
5134
5589
|
await store.commit(
|
|
5135
|
-
old,
|
|
5136
|
-
[inc(1), inc(2)],
|
|
5590
|
+
[{ stream: old, msgs: [inc(1), inc(2)] }],
|
|
5137
5591
|
make_meta({ stream: old })
|
|
5138
5592
|
);
|
|
5139
5593
|
const fresh = `restore-fresh-${uid()}`;
|
|
@@ -5280,8 +5734,7 @@ var runStoreTck = (options) => {
|
|
|
5280
5734
|
it7("rolls back atomically when the source throws mid-iteration", async () => {
|
|
5281
5735
|
const original = `restore-pre-${uid()}`;
|
|
5282
5736
|
const committed = await store.commit(
|
|
5283
|
-
original,
|
|
5284
|
-
[inc(1), inc(2), inc(3)],
|
|
5737
|
+
[{ stream: original, msgs: [inc(1), inc(2), inc(3)] }],
|
|
5285
5738
|
make_meta({ stream: original })
|
|
5286
5739
|
);
|
|
5287
5740
|
const explosive = {
|
|
@@ -5454,12 +5907,16 @@ var runStoreTck = (options) => {
|
|
|
5454
5907
|
it7("commits and loads pii alongside data", async () => {
|
|
5455
5908
|
const s = `pii-roundtrip-${uid()}`;
|
|
5456
5909
|
const committed = await store.commit(
|
|
5457
|
-
s,
|
|
5458
5910
|
[
|
|
5459
5911
|
{
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5912
|
+
stream: s,
|
|
5913
|
+
msgs: [
|
|
5914
|
+
{
|
|
5915
|
+
name: "Incremented",
|
|
5916
|
+
data: { amount: 1 },
|
|
5917
|
+
pii: { email: "u@example.com", name: "Ursula" }
|
|
5918
|
+
}
|
|
5919
|
+
]
|
|
5463
5920
|
}
|
|
5464
5921
|
],
|
|
5465
5922
|
make_meta({ stream: s })
|
|
@@ -5482,12 +5939,16 @@ var runStoreTck = (options) => {
|
|
|
5482
5939
|
});
|
|
5483
5940
|
describe8("with_pii", () => {
|
|
5484
5941
|
const seed_pii = async (s) => await store.commit(
|
|
5485
|
-
s,
|
|
5486
5942
|
[
|
|
5487
5943
|
{
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5944
|
+
stream: s,
|
|
5945
|
+
msgs: [
|
|
5946
|
+
{
|
|
5947
|
+
name: "Incremented",
|
|
5948
|
+
data: { amount: 1 },
|
|
5949
|
+
pii: { email: "w@example.com" }
|
|
5950
|
+
}
|
|
5951
|
+
]
|
|
5491
5952
|
}
|
|
5492
5953
|
],
|
|
5493
5954
|
make_meta({ stream: s })
|
|
@@ -5548,12 +6009,16 @@ var runStoreTck = (options) => {
|
|
|
5548
6009
|
const s = `pii-date-${uid()}`;
|
|
5549
6010
|
const when = /* @__PURE__ */ new Date("2024-03-01T10:20:30.000Z");
|
|
5550
6011
|
await store.commit(
|
|
5551
|
-
s,
|
|
5552
6012
|
[
|
|
5553
6013
|
{
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
6014
|
+
stream: s,
|
|
6015
|
+
msgs: [
|
|
6016
|
+
{
|
|
6017
|
+
name: "Incremented",
|
|
6018
|
+
data: { amount: 1, at: when },
|
|
6019
|
+
pii: { born: when }
|
|
6020
|
+
}
|
|
6021
|
+
]
|
|
5557
6022
|
}
|
|
5558
6023
|
],
|
|
5559
6024
|
make_meta({ stream: s })
|
|
@@ -5576,17 +6041,21 @@ var runStoreTck = (options) => {
|
|
|
5576
6041
|
it7("query_stats head/tail never carry pii \u2014 introspection surface is pii-safe", async () => {
|
|
5577
6042
|
const s = `pii-stats-${uid()}`;
|
|
5578
6043
|
await store.commit(
|
|
5579
|
-
s,
|
|
5580
6044
|
[
|
|
5581
6045
|
{
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
6046
|
+
stream: s,
|
|
6047
|
+
msgs: [
|
|
6048
|
+
{
|
|
6049
|
+
name: "Incremented",
|
|
6050
|
+
data: { amount: 1 },
|
|
6051
|
+
pii: { email: "head@example.com" }
|
|
6052
|
+
},
|
|
6053
|
+
{
|
|
6054
|
+
name: "Incremented",
|
|
6055
|
+
data: { amount: 2 },
|
|
6056
|
+
pii: { email: "tail@example.com" }
|
|
6057
|
+
}
|
|
6058
|
+
]
|
|
5590
6059
|
}
|
|
5591
6060
|
],
|
|
5592
6061
|
make_meta({ stream: s })
|
|
@@ -5610,8 +6079,7 @@ var runStoreTck = (options) => {
|
|
|
5610
6079
|
it7("passes through events without pii (pii is null or undefined on load)", async () => {
|
|
5611
6080
|
const s = `pii-none-${uid()}`;
|
|
5612
6081
|
await store.commit(
|
|
5613
|
-
s,
|
|
5614
|
-
[inc(1)],
|
|
6082
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
5615
6083
|
make_meta({ stream: s })
|
|
5616
6084
|
);
|
|
5617
6085
|
const seen = [];
|
|
@@ -5627,17 +6095,21 @@ var runStoreTck = (options) => {
|
|
|
5627
6095
|
it7("wipes pii for every event on the stream via forget_pii", async () => {
|
|
5628
6096
|
const s = `pii-forget-${uid()}`;
|
|
5629
6097
|
await store.commit(
|
|
5630
|
-
s,
|
|
5631
6098
|
[
|
|
5632
6099
|
{
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
6100
|
+
stream: s,
|
|
6101
|
+
msgs: [
|
|
6102
|
+
{
|
|
6103
|
+
name: "Incremented",
|
|
6104
|
+
data: { amount: 1 },
|
|
6105
|
+
pii: { email: "a@example.com" }
|
|
6106
|
+
},
|
|
6107
|
+
{
|
|
6108
|
+
name: "Incremented",
|
|
6109
|
+
data: { amount: 2 },
|
|
6110
|
+
pii: { email: "b@example.com" }
|
|
6111
|
+
}
|
|
6112
|
+
]
|
|
5641
6113
|
}
|
|
5642
6114
|
],
|
|
5643
6115
|
make_meta({ stream: s })
|
|
@@ -5662,12 +6134,16 @@ var runStoreTck = (options) => {
|
|
|
5662
6134
|
it7("is idempotent \u2014 second forget_pii returns 0, no error", async () => {
|
|
5663
6135
|
const s = `pii-forget-idem-${uid()}`;
|
|
5664
6136
|
await store.commit(
|
|
5665
|
-
s,
|
|
5666
6137
|
[
|
|
5667
6138
|
{
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
6139
|
+
stream: s,
|
|
6140
|
+
msgs: [
|
|
6141
|
+
{
|
|
6142
|
+
name: "Incremented",
|
|
6143
|
+
data: { amount: 1 },
|
|
6144
|
+
pii: { email: "u@example.com" }
|
|
6145
|
+
}
|
|
6146
|
+
]
|
|
5671
6147
|
}
|
|
5672
6148
|
],
|
|
5673
6149
|
make_meta({ stream: s })
|
|
@@ -5682,23 +6158,31 @@ var runStoreTck = (options) => {
|
|
|
5682
6158
|
const sA = `pii-iso-a-${uid()}`;
|
|
5683
6159
|
const sB = `pii-iso-b-${uid()}`;
|
|
5684
6160
|
await store.commit(
|
|
5685
|
-
sA,
|
|
5686
6161
|
[
|
|
5687
6162
|
{
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
|
|
6163
|
+
stream: sA,
|
|
6164
|
+
msgs: [
|
|
6165
|
+
{
|
|
6166
|
+
name: "Incremented",
|
|
6167
|
+
data: { amount: 1 },
|
|
6168
|
+
pii: { email: "alice@example.com" }
|
|
6169
|
+
}
|
|
6170
|
+
]
|
|
5691
6171
|
}
|
|
5692
6172
|
],
|
|
5693
6173
|
make_meta({ stream: sA })
|
|
5694
6174
|
);
|
|
5695
6175
|
await store.commit(
|
|
5696
|
-
sB,
|
|
5697
6176
|
[
|
|
5698
6177
|
{
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
6178
|
+
stream: sB,
|
|
6179
|
+
msgs: [
|
|
6180
|
+
{
|
|
6181
|
+
name: "Incremented",
|
|
6182
|
+
data: { amount: 1 },
|
|
6183
|
+
pii: { email: "bob@example.com" }
|
|
6184
|
+
}
|
|
6185
|
+
]
|
|
5702
6186
|
}
|
|
5703
6187
|
],
|
|
5704
6188
|
make_meta({ stream: sB })
|
|
@@ -5724,8 +6208,7 @@ var runStoreTck = (options) => {
|
|
|
5724
6208
|
it7("forget_pii on a stream with no pii events returns 0", async () => {
|
|
5725
6209
|
const s = `pii-forget-empty-${uid()}`;
|
|
5726
6210
|
await store.commit(
|
|
5727
|
-
s,
|
|
5728
|
-
[inc(1)],
|
|
6211
|
+
[{ stream: s, msgs: [inc(1)] }],
|
|
5729
6212
|
make_meta({ stream: s })
|
|
5730
6213
|
);
|
|
5731
6214
|
const wiped = await store.forget_pii.call(store, s);
|
|
@@ -5750,8 +6233,7 @@ var runStoreTck = (options) => {
|
|
|
5750
6233
|
try {
|
|
5751
6234
|
const stream = `notify-${uid()}`;
|
|
5752
6235
|
await writer.commit(
|
|
5753
|
-
stream,
|
|
5754
|
-
[inc(1)],
|
|
6236
|
+
[{ stream, msgs: [inc(1)] }],
|
|
5755
6237
|
make_meta({ stream })
|
|
5756
6238
|
);
|
|
5757
6239
|
await arrived;
|
|
@@ -5779,18 +6261,15 @@ var runStoreTck = (options) => {
|
|
|
5779
6261
|
const writer = await options.factory();
|
|
5780
6262
|
try {
|
|
5781
6263
|
await store.commit(
|
|
5782
|
-
own,
|
|
5783
|
-
[inc(1)],
|
|
6264
|
+
[{ stream: own, msgs: [inc(1)] }],
|
|
5784
6265
|
make_meta({ stream: own })
|
|
5785
6266
|
);
|
|
5786
6267
|
await writer.commit(
|
|
5787
|
-
remote,
|
|
5788
|
-
[inc(1)],
|
|
6268
|
+
[{ stream: remote, msgs: [inc(1)] }],
|
|
5789
6269
|
make_meta({ stream: remote })
|
|
5790
6270
|
);
|
|
5791
6271
|
await writer.commit(
|
|
5792
|
-
sentinel,
|
|
5793
|
-
[inc(1)],
|
|
6272
|
+
[{ stream: sentinel, msgs: [inc(1)] }],
|
|
5794
6273
|
make_meta({ stream: sentinel })
|
|
5795
6274
|
);
|
|
5796
6275
|
await sentinel_arrived;
|
|
@@ -5802,7 +6281,7 @@ var runStoreTck = (options) => {
|
|
|
5802
6281
|
await Promise.resolve(disposer());
|
|
5803
6282
|
}
|
|
5804
6283
|
});
|
|
5805
|
-
it7("delivers one notification
|
|
6284
|
+
it7("delivers one notification carrying a stream's full batch from one commit", async () => {
|
|
5806
6285
|
const received = [];
|
|
5807
6286
|
let resolve_sentinel;
|
|
5808
6287
|
const sentinel_arrived = new Promise((res) => {
|
|
@@ -5817,13 +6296,11 @@ var runStoreTck = (options) => {
|
|
|
5817
6296
|
const writer = await options.factory();
|
|
5818
6297
|
try {
|
|
5819
6298
|
await writer.commit(
|
|
5820
|
-
batch,
|
|
5821
|
-
[inc(1), inc(2), inc(3)],
|
|
6299
|
+
[{ stream: batch, msgs: [inc(1), inc(2), inc(3)] }],
|
|
5822
6300
|
make_meta({ stream: batch })
|
|
5823
6301
|
);
|
|
5824
6302
|
await writer.commit(
|
|
5825
|
-
sentinel,
|
|
5826
|
-
[inc(1)],
|
|
6303
|
+
[{ stream: sentinel, msgs: [inc(1)] }],
|
|
5827
6304
|
make_meta({ stream: sentinel })
|
|
5828
6305
|
);
|
|
5829
6306
|
await sentinel_arrived;
|
|
@@ -5846,6 +6323,45 @@ var runStoreTck = (options) => {
|
|
|
5846
6323
|
await Promise.resolve(disposer());
|
|
5847
6324
|
}
|
|
5848
6325
|
});
|
|
6326
|
+
it7("delivers one notification per stream a commit appends to, with that stream's events", async () => {
|
|
6327
|
+
const received = [];
|
|
6328
|
+
let resolve_sentinel;
|
|
6329
|
+
const sentinel_arrived = new Promise((res) => {
|
|
6330
|
+
resolve_sentinel = res;
|
|
6331
|
+
});
|
|
6332
|
+
const a = `notify-across-a-${uid()}`;
|
|
6333
|
+
const b = `notify-across-b-${uid()}`;
|
|
6334
|
+
const sentinel = `notify-across-sentinel-${uid()}`;
|
|
6335
|
+
const disposer = await store.notify.call(store, (n) => {
|
|
6336
|
+
received.push(n);
|
|
6337
|
+
if (n.stream === sentinel) resolve_sentinel();
|
|
6338
|
+
});
|
|
6339
|
+
const writer = await options.factory();
|
|
6340
|
+
try {
|
|
6341
|
+
const committed = await writer.commit(
|
|
6342
|
+
[
|
|
6343
|
+
{ stream: a, msgs: [inc(1), inc(2)] },
|
|
6344
|
+
{ stream: b, msgs: [dec(3)] }
|
|
6345
|
+
],
|
|
6346
|
+
make_meta({ stream: a })
|
|
6347
|
+
);
|
|
6348
|
+
await writer.commit(
|
|
6349
|
+
[{ stream: sentinel, msgs: [inc(1)] }],
|
|
6350
|
+
make_meta({ stream: sentinel })
|
|
6351
|
+
);
|
|
6352
|
+
await sentinel_arrived;
|
|
6353
|
+
for (const stream of [a, b]) {
|
|
6354
|
+
const of_stream = received.filter((n) => n.stream === stream);
|
|
6355
|
+
expect8(of_stream).toHaveLength(1);
|
|
6356
|
+
expect8(of_stream[0].events.map((e) => e.id)).toEqual(
|
|
6357
|
+
committed.filter((e) => e.stream === stream).map((e) => e.id)
|
|
6358
|
+
);
|
|
6359
|
+
}
|
|
6360
|
+
} finally {
|
|
6361
|
+
await writer.dispose();
|
|
6362
|
+
await Promise.resolve(disposer());
|
|
6363
|
+
}
|
|
6364
|
+
});
|
|
5849
6365
|
});
|
|
5850
6366
|
}
|
|
5851
6367
|
});
|