@rotorsoft/act-tck 1.25.0 → 1.26.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/dist/index.cjs CHANGED
@@ -2232,6 +2232,165 @@ var runStoreTck = (options) => {
2232
2232
  const result = await store.truncate([{ stream: s }]);
2233
2233
  (0, import_vitest9.expect)(result.get(s)?.deleted).toBe(0);
2234
2234
  });
2235
+ (0, import_vitest9.describe)("windowed (before boundary)", () => {
2236
+ async function seed_windowed(s) {
2237
+ await store.commit(
2238
+ s,
2239
+ [inc(1), inc(1)],
2240
+ make_meta({ stream: s })
2241
+ );
2242
+ const [snap_a] = await store.commit(
2243
+ s,
2244
+ [{ name: import_act2.SNAP_EVENT, data: { count: 2 } }],
2245
+ make_meta({ stream: s })
2246
+ );
2247
+ await store.commit(
2248
+ s,
2249
+ [inc(1)],
2250
+ make_meta({ stream: s })
2251
+ );
2252
+ const [snap_b] = await store.commit(
2253
+ s,
2254
+ [{ name: import_act2.SNAP_EVENT, data: { count: 3 } }],
2255
+ make_meta({ stream: s })
2256
+ );
2257
+ await store.commit(
2258
+ s,
2259
+ [inc(1)],
2260
+ make_meta({ stream: s })
2261
+ );
2262
+ return { snap_a, snap_b };
2263
+ }
2264
+ (0, import_vitest9.it)("deletes the prefix below the closest safe snapshot and keeps the snapshot + tail", async () => {
2265
+ const s = `trunc-win-${uid()}`;
2266
+ const { snap_b } = await seed_windowed(s);
2267
+ const before = new Date(Date.now() + 6e4);
2268
+ const result = await store.truncate([{ stream: s, before }]);
2269
+ const entry2 = result.get(s);
2270
+ (0, import_vitest9.expect)(entry2?.deleted).toBe(4);
2271
+ (0, import_vitest9.expect)(entry2?.committed.id).toBe(snap_b.id);
2272
+ (0, import_vitest9.expect)(entry2?.committed.name).toBe(import_act2.SNAP_EVENT);
2273
+ (0, import_vitest9.expect)(entry2?.committed.data).toEqual({ count: 3 });
2274
+ (0, import_vitest9.expect)(entry2?.before).toEqual(before);
2275
+ const remaining = await collect(store, {
2276
+ stream: s,
2277
+ stream_exact: true,
2278
+ with_snaps: true,
2279
+ after: -1
2280
+ });
2281
+ (0, import_vitest9.expect)(remaining.map((e) => e.name)).toEqual([
2282
+ import_act2.SNAP_EVENT,
2283
+ "Incremented"
2284
+ ]);
2285
+ (0, import_vitest9.expect)(remaining[0].id).toBe(snap_b.id);
2286
+ });
2287
+ (0, import_vitest9.it)("honors the max_id cap \u2014 boundary never rises past a lagging consumer", async () => {
2288
+ const s = `trunc-win-cap-${uid()}`;
2289
+ const { snap_a, snap_b } = await seed_windowed(s);
2290
+ const before = new Date(Date.now() + 6e4);
2291
+ const result = await store.truncate([
2292
+ { stream: s, before, max_id: snap_a.id }
2293
+ ]);
2294
+ const entry2 = result.get(s);
2295
+ (0, import_vitest9.expect)(entry2?.committed.id).toBe(snap_a.id);
2296
+ (0, import_vitest9.expect)(entry2?.deleted).toBe(2);
2297
+ const remaining = await collect(store, {
2298
+ stream: s,
2299
+ stream_exact: true,
2300
+ with_snaps: true,
2301
+ after: -1
2302
+ });
2303
+ (0, import_vitest9.expect)(remaining.map((e) => e.id)).toContain(snap_b.id);
2304
+ (0, import_vitest9.expect)(remaining[0].id).toBe(snap_a.id);
2305
+ (0, import_vitest9.expect)(remaining).toHaveLength(4);
2306
+ });
2307
+ (0, import_vitest9.it)("no-ops when no snapshot qualifies \u2014 stream absent from the result, events untouched", async () => {
2308
+ const s = `trunc-win-noop-${uid()}`;
2309
+ await store.commit(
2310
+ s,
2311
+ [inc(1), inc(1)],
2312
+ make_meta({ stream: s })
2313
+ );
2314
+ const none = await store.truncate([
2315
+ { stream: s, before: new Date(Date.now() + 6e4) }
2316
+ ]);
2317
+ (0, import_vitest9.expect)(none.has(s)).toBe(false);
2318
+ await store.commit(
2319
+ s,
2320
+ [{ name: import_act2.SNAP_EVENT, data: { count: 2 } }],
2321
+ make_meta({ stream: s })
2322
+ );
2323
+ const too_early = await store.truncate([
2324
+ { stream: s, before: /* @__PURE__ */ new Date(0) }
2325
+ ]);
2326
+ (0, import_vitest9.expect)(too_early.has(s)).toBe(false);
2327
+ const missing = await store.truncate([
2328
+ { stream: `trunc-win-missing-${uid()}`, before: /* @__PURE__ */ new Date() }
2329
+ ]);
2330
+ (0, import_vitest9.expect)(missing.size).toBe(0);
2331
+ const remaining = await collect(store, {
2332
+ stream: s,
2333
+ stream_exact: true,
2334
+ with_snaps: true,
2335
+ after: -1
2336
+ });
2337
+ (0, import_vitest9.expect)(remaining).toHaveLength(3);
2338
+ });
2339
+ (0, import_vitest9.it)("leaves subscriptions untouched, unlike a full truncate", async () => {
2340
+ const s = `trunc-win-subs-${uid()}`;
2341
+ await seed_windowed(s);
2342
+ await store.subscribe([{ stream: s }]);
2343
+ await store.truncate([
2344
+ { stream: s, before: new Date(Date.now() + 6e4) }
2345
+ ]);
2346
+ const positions = [];
2347
+ await store.query_streams((p) => positions.push(p.stream), {
2348
+ stream: s,
2349
+ stream_exact: true
2350
+ });
2351
+ (0, import_vitest9.expect)(positions).toEqual([s]);
2352
+ });
2353
+ (0, import_vitest9.it)("mixes full and windowed targets in one call", async () => {
2354
+ const w = `trunc-win-mix-w-${uid()}`;
2355
+ const f = `trunc-win-mix-f-${uid()}`;
2356
+ const { snap_b } = await seed_windowed(w);
2357
+ await store.commit(
2358
+ f,
2359
+ [inc(1)],
2360
+ make_meta({ stream: f })
2361
+ );
2362
+ const result = await store.truncate([
2363
+ { stream: w, before: new Date(Date.now() + 6e4) },
2364
+ { stream: f }
2365
+ ]);
2366
+ (0, import_vitest9.expect)(result.get(w)?.committed.id).toBe(snap_b.id);
2367
+ (0, import_vitest9.expect)(result.get(w)?.before).toBeInstanceOf(Date);
2368
+ (0, import_vitest9.expect)(result.get(f)?.deleted).toBe(1);
2369
+ (0, import_vitest9.expect)(result.get(f)?.committed.name).toBe("__tombstone__");
2370
+ (0, import_vitest9.expect)(result.get(f)?.before).toBeUndefined();
2371
+ });
2372
+ (0, import_vitest9.it)("keeps the stream writable and readable after a prune", async () => {
2373
+ const s = `trunc-win-cont-${uid()}`;
2374
+ const { snap_b } = await seed_windowed(s);
2375
+ await store.truncate([
2376
+ { stream: s, before: new Date(Date.now() + 6e4) }
2377
+ ]);
2378
+ const [next] = await store.commit(
2379
+ s,
2380
+ [inc(1)],
2381
+ make_meta({ stream: s })
2382
+ );
2383
+ (0, import_vitest9.expect)(next.version).toBe(6);
2384
+ (0, import_vitest9.expect)(next.id).toBeGreaterThan(snap_b.id);
2385
+ const replay = await collect(store, {
2386
+ stream: s,
2387
+ stream_exact: true,
2388
+ with_snaps: true
2389
+ });
2390
+ (0, import_vitest9.expect)(replay[0].id).toBe(snap_b.id);
2391
+ (0, import_vitest9.expect)(replay).toHaveLength(3);
2392
+ });
2393
+ });
2235
2394
  });
2236
2395
  (0, import_vitest9.describe)("query_streams", () => {
2237
2396
  (0, import_vitest9.it)("returns positions filtered by stream regex, exact, source, and source_exact", async () => {