@prisma/streams-server 0.1.0 → 0.1.1

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/src/db/db.ts CHANGED
@@ -964,60 +964,6 @@ export class SqliteDurableStore {
964
964
  }
965
965
  }
966
966
 
967
- findFirstWalOffsetForRoutingKeys(
968
- stream: string,
969
- startOffsetExclusive: bigint,
970
- endOffsetInclusive: bigint,
971
- routingKeys: Uint8Array[]
972
- ): bigint | null {
973
- if (routingKeys.length === 0) return null;
974
- const start = this.bindInt(startOffsetExclusive);
975
-
976
- // Avoid tripping SQLite variable limits (commonly 999) when callers watch a
977
- // large number of keys. Chunking is cheap because the touch WAL ranges we
978
- // scan are typically small and indexed by (stream, routing_key, offset).
979
- const MAX_KEYS_PER_QUERY = 400;
980
- let best: bigint | null = null;
981
- let endLimit = endOffsetInclusive;
982
- const touchNameLooksDefault = stream.endsWith(".__touch");
983
- const touchLikeClause = touchNameLooksDefault ? " AND stream LIKE '%.__touch'" : "";
984
-
985
- for (let i = 0; i < routingKeys.length; i += MAX_KEYS_PER_QUERY) {
986
- const chunk = routingKeys.slice(i, i + MAX_KEYS_PER_QUERY);
987
- if (chunk.length === 0) continue;
988
- const end = this.bindInt(endLimit);
989
- const placeholders = chunk.map(() => "?").join(", ");
990
- const stmt = this.db.query(
991
- `SELECT MIN(offset) as offset
992
- FROM wal
993
- WHERE stream = ?${touchLikeClause}
994
- AND offset > ?
995
- AND offset <= ?
996
- AND routing_key IN (${placeholders});`
997
- );
998
- try {
999
- const row = stmt.get(stream, start, end, ...chunk) as any;
1000
- if (!row || row.offset == null) continue;
1001
- const off = this.toBigInt(row.offset);
1002
- if (best == null || off < best) {
1003
- best = off;
1004
- // No need to search beyond the best match so far.
1005
- endLimit = off - 1n;
1006
- if (off <= startOffsetExclusive + 1n) break;
1007
- }
1008
- } finally {
1009
- try {
1010
- stmt.finalize?.();
1011
- } catch {
1012
- // ignore
1013
- }
1014
- }
1015
- if (endLimit < startOffsetExclusive + 1n) break;
1016
- }
1017
-
1018
- return best;
1019
- }
1020
-
1021
967
  nextSegmentIndexForStream(stream: string): number {
1022
968
  const row = this.stmts.nextSegmentIndex.get(stream) as any;
1023
969
  return Number(row?.next_idx ?? 0);
package/src/db/schema.ts CHANGED
@@ -9,7 +9,7 @@ import { dsError } from "../util/ds_error.ts";
9
9
  * - local metadata store (streams/segments/manifests/schemas)
10
10
  */
11
11
 
12
- export const SCHEMA_VERSION = 10;
12
+ export const SCHEMA_VERSION = 11;
13
13
 
14
14
  export const DEFAULT_PRAGMAS_SQL = `
15
15
  PRAGMA journal_mode = WAL;
@@ -75,8 +75,6 @@ CREATE TABLE IF NOT EXISTS wal (
75
75
  CREATE UNIQUE INDEX IF NOT EXISTS wal_stream_offset_uniq ON wal(stream, offset);
76
76
  CREATE INDEX IF NOT EXISTS wal_stream_offset_idx ON wal(stream, offset);
77
77
  CREATE INDEX IF NOT EXISTS wal_ts_idx ON wal(ts_ms);
78
- -- Partial index for internal companion touch streams (WAL-only, routing-key heavy).
79
- CREATE INDEX IF NOT EXISTS wal_touch_stream_rk_offset_idx ON wal(stream, routing_key, offset) WHERE stream LIKE '%.__touch';
80
78
 
81
79
  CREATE TABLE IF NOT EXISTS segments (
82
80
  segment_id TEXT PRIMARY KEY,
@@ -134,7 +132,7 @@ CREATE TABLE IF NOT EXISTS stream_interpreters (
134
132
  updated_at_ms INTEGER NOT NULL
135
133
  );
136
134
 
137
- -- Live Query V2 dynamic template registry (per base stream).
135
+ -- Live dynamic template registry (per base stream).
138
136
  CREATE TABLE IF NOT EXISTS live_templates (
139
137
  stream TEXT NOT NULL,
140
138
  template_id TEXT NOT NULL,
@@ -267,7 +265,6 @@ const CREATE_INDEXES_V4_SQL = `
267
265
  CREATE UNIQUE INDEX IF NOT EXISTS wal_stream_offset_uniq ON wal(stream, offset);
268
266
  CREATE INDEX IF NOT EXISTS wal_stream_offset_idx ON wal(stream, offset);
269
267
  CREATE INDEX IF NOT EXISTS wal_ts_idx ON wal(ts_ms);
270
- CREATE INDEX IF NOT EXISTS wal_touch_stream_rk_offset_idx ON wal(stream, routing_key, offset) WHERE stream LIKE '%.__touch';
271
268
 
272
269
  CREATE INDEX IF NOT EXISTS streams_pending_bytes_idx ON streams(pending_bytes);
273
270
  CREATE INDEX IF NOT EXISTS streams_last_cut_idx ON streams(last_segment_cut_ms);
@@ -326,6 +323,8 @@ export function initSchema(db: SqliteDatabase, opts: { skipMigrations?: boolean
326
323
  migrateV8ToV9(db);
327
324
  } else if (version === 9) {
328
325
  migrateV9ToV10(db);
326
+ } else if (version === 10) {
327
+ migrateV10ToV11(db);
329
328
  } else {
330
329
  throw dsError(`unexpected schema version: ${version} (expected ${SCHEMA_VERSION})`);
331
330
  }
@@ -555,7 +554,6 @@ function migrateV6ToV7(db: SqliteDatabase): void {
555
554
 
556
555
  function migrateV7ToV8(db: SqliteDatabase): void {
557
556
  const tx = db.transaction(() => {
558
- db.exec(`CREATE INDEX IF NOT EXISTS wal_touch_stream_rk_offset_idx ON wal(stream, routing_key, offset) WHERE stream LIKE '%.__touch';`);
559
557
  db.exec(`UPDATE schema_version SET version = 8;`);
560
558
  });
561
559
  tx();
@@ -613,6 +611,14 @@ function migrateV9ToV10(db: SqliteDatabase): void {
613
611
  `);
614
612
  db.exec(`DROP TABLE wal_stats;`);
615
613
 
614
+ db.exec(`UPDATE schema_version SET version = 10;`);
615
+ });
616
+ tx();
617
+ }
618
+
619
+ function migrateV10ToV11(db: SqliteDatabase): void {
620
+ const tx = db.transaction(() => {
621
+ db.exec(`DROP INDEX IF EXISTS wal_touch_stream_rk_offset_idx;`);
616
622
  db.exec(`UPDATE schema_version SET version = ${SCHEMA_VERSION};`);
617
623
  });
618
624
  tx();
@@ -5,9 +5,8 @@ import { SqliteDurableStore } from "../db/db.ts";
5
5
  import { initConsoleLogging } from "../util/log.ts";
6
6
  import type { ProcessRequest } from "./worker_protocol.ts";
7
7
  import { interpretRecordToChanges } from "./engine.ts";
8
- import { encodeTemplateArg, tableKeyFor, tableKeyIdFor, templateKeyFor, templateKeyIdFor, watchKeyFor, watchKeyIdFor, type TemplateEncoding } from "./live_keys.ts";
8
+ import { encodeTemplateArg, tableKeyIdFor, templateKeyIdFor, watchKeyIdFor, type TemplateEncoding } from "./live_keys.ts";
9
9
  import { isTouchEnabled } from "./spec.ts";
10
- import { resolveTouchStreamName } from "./naming.ts";
11
10
 
12
11
  initConsoleLogging();
13
12
 
@@ -50,9 +49,6 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
50
49
  return;
51
50
  }
52
51
  const touch = interpreter.touch;
53
- const derivedStream = resolveTouchStreamName(stream, touch);
54
- const touchStorage = touch.storage ?? "memory";
55
- const emitRoutingKey = touchStorage === "sqlite";
56
52
 
57
53
  const fineBudgetRaw = msg.fineTouchBudget ?? touch.fineTouchBudgetPerBatch;
58
54
  const fineBudget = fineBudgetRaw == null ? null : Math.max(0, Math.floor(fineBudgetRaw));
@@ -125,7 +121,6 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
125
121
 
126
122
  type PendingTouch = {
127
123
  keyId: number;
128
- key?: string;
129
124
  windowStartMs: number;
130
125
  watermark: string;
131
126
  entity: string;
@@ -136,17 +131,16 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
136
131
 
137
132
  const pending = new Map<string, PendingTouch>();
138
133
  const templateOnlyEntityTouch = new Map<string, EntityTemplateOnlyTouch>();
139
- const touches: Array<{ keyId: number; key?: string; watermark: string; entity: string; kind: "table" | "template"; templateId?: string }> = [];
134
+ const touches: Array<{ keyId: number; watermark: string; entity: string; kind: "table" | "template"; templateId?: string }> = [];
140
135
  let fineTouchesDroppedDueToBudget = 0;
141
136
  let fineTouchesSkippedColdTemplate = 0;
142
137
 
143
138
  const flush = (_mapKey: string, p: PendingTouch) => {
144
- touches.push({ keyId: p.keyId >>> 0, key: p.key, watermark: p.watermark, entity: p.entity, kind: p.kind, templateId: p.templateId });
139
+ touches.push({ keyId: p.keyId >>> 0, watermark: p.watermark, entity: p.entity, kind: p.kind, templateId: p.templateId });
145
140
  };
146
141
 
147
142
  const queueTouch = (args: {
148
143
  keyId: number;
149
- key?: string;
150
144
  tsMs: number;
151
145
  watermark: string;
152
146
  entity: string;
@@ -154,7 +148,7 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
154
148
  templateId?: string;
155
149
  windowMs: number;
156
150
  }) => {
157
- const mapKey = args.key ? `k:${args.key}` : `i:${args.keyId >>> 0}`;
151
+ const mapKey = `i:${args.keyId >>> 0}`;
158
152
  const prev = pending.get(mapKey);
159
153
 
160
154
  // Guardrail: cap fine/template touches (key cardinality) per batch.
@@ -177,7 +171,6 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
177
171
  if (!prev) {
178
172
  pending.set(mapKey, {
179
173
  keyId: args.keyId >>> 0,
180
- key: args.key,
181
174
  windowStartMs: args.tsMs,
182
175
  watermark: args.watermark,
183
176
  entity: args.entity,
@@ -194,7 +187,6 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
194
187
  flush(mapKey, prev);
195
188
  pending.set(mapKey, {
196
189
  keyId: args.keyId >>> 0,
197
- key: args.key,
198
190
  windowStartMs: args.tsMs,
199
191
  watermark: args.watermark,
200
192
  entity: args.entity,
@@ -237,7 +229,6 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
237
229
  const coarseKeyId = tableKeyIdFor(entity);
238
230
  queueTouch({
239
231
  keyId: coarseKeyId,
240
- key: emitRoutingKey ? tableKeyFor(entity) : undefined,
241
232
  tsMs,
242
233
  watermark,
243
234
  entity,
@@ -267,7 +258,6 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
267
258
  if (fineGranularity === "template") {
268
259
  queueTouch({
269
260
  keyId: templateKeyIdFor(tpl.templateId) >>> 0,
270
- key: emitRoutingKey ? templateKeyFor(tpl.templateId) : undefined,
271
261
  tsMs,
272
262
  watermark,
273
263
  entity,
@@ -282,9 +272,9 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
282
272
  const afterObj = ch.after;
283
273
  const beforeObj = ch.before;
284
274
 
285
- const watchKeys = new Map<number, string | undefined>();
275
+ const watchKeyIds = new Set<number>();
286
276
 
287
- const compute = (obj: unknown): { keyId: number; key?: string } | null => {
277
+ const compute = (obj: unknown): number | null => {
288
278
  if (!obj || typeof obj !== "object" || Array.isArray(obj)) return null;
289
279
  const args: string[] = [];
290
280
  for (let i = 0; i < tpl.fields.length; i++) {
@@ -295,19 +285,15 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
295
285
  if (encoded == null) return null;
296
286
  args.push(encoded);
297
287
  }
298
- if (emitRoutingKey) {
299
- const key = watchKeyFor(tpl.templateId, args);
300
- return { keyId: Number.parseInt(key.slice(8), 16) >>> 0, key };
301
- }
302
- return { keyId: watchKeyIdFor(tpl.templateId, args) >>> 0 };
288
+ return watchKeyIdFor(tpl.templateId, args) >>> 0;
303
289
  };
304
290
 
305
291
  if (ch.op === "insert") {
306
292
  const k = compute(afterObj);
307
- if (k) watchKeys.set(k.keyId >>> 0, k.key);
293
+ if (k != null) watchKeyIds.add(k >>> 0);
308
294
  } else if (ch.op === "delete") {
309
295
  const k = compute(beforeObj);
310
- if (k) watchKeys.set(k.keyId >>> 0, k.key);
296
+ if (k != null) watchKeyIds.add(k >>> 0);
311
297
  } else {
312
298
  // update: compute touches from both before and after (when possible).
313
299
  // Policy for missing/insufficient before image:
@@ -317,9 +303,9 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
317
303
  const kAfter = compute(afterObj);
318
304
  const kBefore = compute(beforeObj);
319
305
 
320
- if (kBefore) {
321
- watchKeys.set(kBefore.keyId >>> 0, kBefore.key);
322
- if (kAfter) watchKeys.set(kAfter.keyId >>> 0, kAfter.key);
306
+ if (kBefore != null) {
307
+ watchKeyIds.add(kBefore >>> 0);
308
+ if (kAfter != null) watchKeyIds.add(kAfter >>> 0);
323
309
  } else {
324
310
  if (beforeObj === undefined) {
325
311
  if (onMissingBefore === "error") {
@@ -335,17 +321,16 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
335
321
  }
336
322
 
337
323
  if (onMissingBefore === "skipBefore") {
338
- if (kAfter) watchKeys.set(kAfter.keyId >>> 0, kAfter.key);
324
+ if (kAfter != null) watchKeyIds.add(kAfter >>> 0);
339
325
  } else {
340
326
  // coarse: no fine touches
341
327
  }
342
328
  }
343
329
  }
344
330
 
345
- for (const [watchKeyId, watchKey] of watchKeys.entries()) {
331
+ for (const watchKeyId of watchKeyIds) {
346
332
  queueTouch({
347
333
  keyId: watchKeyId >>> 0,
348
- key: watchKey,
349
334
  tsMs,
350
335
  watermark,
351
336
  entity,
@@ -369,7 +354,6 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
369
354
  if (agg.offset < tpl.activeFromSourceOffset) continue;
370
355
  queueTouch({
371
356
  keyId: templateKeyIdFor(tpl.templateId) >>> 0,
372
- key: emitRoutingKey ? templateKeyFor(tpl.templateId) : undefined,
373
357
  tsMs: agg.tsMs,
374
358
  watermark: agg.watermark,
375
359
  entity,
@@ -386,8 +370,8 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
386
370
  }
387
371
 
388
372
  touches.sort((a, b) => {
389
- const ak = a.key ?? `~${(a.keyId >>> 0).toString(16).padStart(8, "0")}`;
390
- const bk = b.key ?? `~${(b.keyId >>> 0).toString(16).padStart(8, "0")}`;
373
+ const ak = a.keyId >>> 0;
374
+ const bk = b.keyId >>> 0;
391
375
  if (ak < bk) return -1;
392
376
  if (ak > bk) return 1;
393
377
  const aw = BigInt(a.watermark);
@@ -408,7 +392,6 @@ async function handleProcess(msg: ProcessRequest): Promise<void> {
408
392
  type: "result",
409
393
  id: msg.id,
410
394
  stream,
411
- derivedStream,
412
395
  processedThrough,
413
396
  touches,
414
397
  stats: {
@@ -4,8 +4,6 @@ import { STREAM_FLAG_TOUCH } from "../db/db";
4
4
  import { encodeOffset } from "../offset";
5
5
  import type { TouchConfig } from "./spec";
6
6
  import type { TemplateLifecycleEvent } from "./live_templates";
7
- import { resolveTouchStreamName } from "./naming";
8
- import type { RoutingKeyNotifier } from "./routing_key_notifier";
9
7
  import type { TouchJournalIntervalStats, TouchJournalMeta } from "./touch_journal";
10
8
  import { Result } from "better-result";
11
9
 
@@ -207,8 +205,7 @@ export class LiveMetricsV2 {
207
205
  private readonly snapshotIntervalMs: number;
208
206
  private readonly snapshotChunkSize: number;
209
207
  private readonly retentionMs: number;
210
- private readonly routingKeyNotifier?: RoutingKeyNotifier;
211
- private readonly getTouchJournal?: (derivedStream: string) => { meta: TouchJournalMeta; interval: TouchJournalIntervalStats } | null;
208
+ private readonly getTouchJournal?: (stream: string) => { meta: TouchJournalMeta; interval: TouchJournalIntervalStats } | null;
212
209
  private timer: any | null = null;
213
210
  private snapshotTimer: any | null = null;
214
211
  private retentionTimer: any | null = null;
@@ -234,8 +231,7 @@ export class LiveMetricsV2 {
234
231
  snapshotIntervalMs?: number;
235
232
  snapshotChunkSize?: number;
236
233
  retentionMs?: number;
237
- routingKeyNotifier?: RoutingKeyNotifier;
238
- getTouchJournal?: (derivedStream: string) => { meta: TouchJournalMeta; interval: TouchJournalIntervalStats } | null;
234
+ getTouchJournal?: (stream: string) => { meta: TouchJournalMeta; interval: TouchJournalIntervalStats } | null;
239
235
  }
240
236
  ) {
241
237
  this.db = db;
@@ -246,7 +242,6 @@ export class LiveMetricsV2 {
246
242
  this.snapshotIntervalMs = opts?.snapshotIntervalMs ?? 60_000;
247
243
  this.snapshotChunkSize = opts?.snapshotChunkSize ?? 200;
248
244
  this.retentionMs = opts?.retentionMs ?? 7 * 24 * 60 * 60 * 1000;
249
- this.routingKeyNotifier = opts?.routingKeyNotifier;
250
245
  this.getTouchJournal = opts?.getTouchJournal;
251
246
  }
252
247
 
@@ -500,8 +495,6 @@ export class LiveMetricsV2 {
500
495
  this.lagSumMs = 0;
501
496
  this.lagSamples = 0;
502
497
 
503
- const rkInterval = this.routingKeyNotifier?.snapshotAndResetIntervalStats() ?? null;
504
-
505
498
  for (const st of states) {
506
499
  const stream = st.stream;
507
500
  const regRow = this.db.getStream(stream);
@@ -522,26 +515,8 @@ export class LiveMetricsV2 {
522
515
  if (!touchCfg) continue;
523
516
 
524
517
  const c = this.get(stream, touchCfg);
525
- const storage = (touchCfg.storage ?? "memory") as "memory" | "sqlite";
526
- const derived = resolveTouchStreamName(stream, touchCfg);
527
- const journal = storage === "memory" ? this.getTouchJournal?.(derived) ?? null : null;
528
- const trow = (() => {
529
- try {
530
- return this.db.getStream(derived);
531
- } catch {
532
- return null;
533
- }
534
- })();
535
- const touchTailSeq = trow ? (trow.next_offset > 0n ? trow.next_offset - 1n : -1n) : -1n;
536
- let touchWalOldestOffset: string | null = null;
537
- try {
538
- const oldest = this.db.getWalOldestOffset(derived);
539
- touchWalOldestOffset = oldest == null || !trow ? null : encodeOffset(trow.epoch, oldest);
540
- } catch {
541
- touchWalOldestOffset = null;
542
- }
543
- const waitActive =
544
- storage === "memory" ? (journal?.meta.activeWaiters ?? 0) : this.routingKeyNotifier ? this.routingKeyNotifier.getActiveWaiters(derived) : 0;
518
+ const journal = this.getTouchJournal?.(stream) ?? null;
519
+ const waitActive = journal?.meta.activeWaiters ?? 0;
545
520
  const tailSeq = regRow.next_offset > 0n ? regRow.next_offset - 1n : -1n;
546
521
  const interpretedThrough = st.interpreted_through;
547
522
  const gcThrough = interpretedThrough < regRow.uploaded_through ? interpretedThrough : regRow.uploaded_through;
@@ -571,7 +546,6 @@ export class LiveMetricsV2 {
571
546
  instanceId: this.instanceId,
572
547
  region: this.region,
573
548
  touch: {
574
- storage,
575
549
  coarseIntervalMs: c.touch.coarseIntervalMs,
576
550
  coalesceWindowMs: c.touch.coalesceWindowMs,
577
551
  mode: c.touch.mode,
@@ -596,16 +570,11 @@ export class LiveMetricsV2 {
596
570
  fineTouchesSuppressedBatchesDueToLag: c.touch.fineTouchesSuppressedBatchesDueToLag,
597
571
  fineTouchesSuppressedSecondsDueToLag: c.touch.fineTouchesSuppressedMsDueToLag / 1000,
598
572
  fineTouchesSuppressedBatchesDueToBudget: c.touch.fineTouchesSuppressedBatchesDueToBudget,
599
- cursor: storage === "memory" ? (journal?.meta.cursor ?? null) : null,
600
- epoch: storage === "memory" ? (journal?.meta.epoch ?? null) : null,
601
- generation: storage === "memory" ? (journal?.meta.generation ?? null) : null,
602
- pendingKeys: storage === "memory" ? (journal?.meta.pendingKeys ?? 0) : 0,
603
- overflowBuckets: storage === "memory" ? (journal?.meta.overflowBuckets ?? 0) : 0,
604
- walTailOffset: trow ? encodeOffset(trow.epoch, touchTailSeq) : null,
605
- walNextOffset: trow ? encodeOffset(trow.epoch, trow.next_offset) : null,
606
- walOldestOffset: touchWalOldestOffset,
607
- walRetainedRows: trow ? clampBigInt(trow.wal_rows) : 0,
608
- walRetainedBytes: trow ? clampBigInt(trow.wal_bytes) : 0,
573
+ cursor: journal?.meta.cursor ?? null,
574
+ epoch: journal?.meta.epoch ?? null,
575
+ generation: journal?.meta.generation ?? null,
576
+ pendingKeys: journal?.meta.pendingKeys ?? 0,
577
+ overflowBuckets: journal?.meta.overflowBuckets ?? 0,
609
578
  },
610
579
  templates: {
611
580
  active: activeTemplates,
@@ -624,15 +593,15 @@ export class LiveMetricsV2 {
624
593
  avgLatencyMs: c.wait.calls > 0 ? c.wait.latencySumMs / c.wait.calls : 0,
625
594
  p95LatencyMs: c.wait.latencyHist.p95(),
626
595
  activeWaiters: waitActive,
627
- timeoutsFired: storage === "memory" ? (journal?.interval.timeoutsFired ?? 0) : rkInterval?.timeoutsFired ?? 0,
628
- timeoutSweeps: storage === "memory" ? (journal?.interval.timeoutSweeps ?? 0) : rkInterval?.timeoutSweeps ?? 0,
629
- timeoutSweepMsSum: storage === "memory" ? (journal?.interval.timeoutSweepMsSum ?? 0) : rkInterval?.timeoutSweepMsSum ?? 0,
630
- timeoutSweepMsMax: storage === "memory" ? (journal?.interval.timeoutSweepMsMax ?? 0) : rkInterval?.timeoutSweepMsMax ?? 0,
631
- notifyWakeups: storage === "memory" ? (journal?.interval.notifyWakeups ?? 0) : 0,
632
- notifyFlushes: storage === "memory" ? (journal?.interval.notifyFlushes ?? 0) : 0,
633
- notifyWakeMsSum: storage === "memory" ? (journal?.interval.notifyWakeMsSum ?? 0) : 0,
634
- notifyWakeMsMax: storage === "memory" ? (journal?.interval.notifyWakeMsMax ?? 0) : 0,
635
- timeoutHeapSize: storage === "memory" ? (journal?.interval.heapSize ?? 0) : rkInterval?.heapSize ?? 0,
596
+ timeoutsFired: journal?.interval.timeoutsFired ?? 0,
597
+ timeoutSweeps: journal?.interval.timeoutSweeps ?? 0,
598
+ timeoutSweepMsSum: journal?.interval.timeoutSweepMsSum ?? 0,
599
+ timeoutSweepMsMax: journal?.interval.timeoutSweepMsMax ?? 0,
600
+ notifyWakeups: journal?.interval.notifyWakeups ?? 0,
601
+ notifyFlushes: journal?.interval.notifyFlushes ?? 0,
602
+ notifyWakeMsSum: journal?.interval.notifyWakeMsSum ?? 0,
603
+ notifyWakeMsMax: journal?.interval.notifyWakeMsMax ?? 0,
604
+ timeoutHeapSize: journal?.interval.heapSize ?? 0,
636
605
  },
637
606
  interpreter: {
638
607
  eventsIn: c.interpreter.eventsIn,