@flowcore/data-pump 0.21.0 → 0.21.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.21.2](https://github.com/flowcore-io/data-pump/compare/v0.21.1...v0.21.2) (2026-05-13)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **data-pump:** self-heal main fetch loop on error and validate restart input ([#74](https://github.com/flowcore-io/data-pump/issues/74)) ([7fbbe1d](https://github.com/flowcore-io/data-pump/commit/7fbbe1d25851eef4003051aa34e48a93d1669172))
9
+
10
+ ## [0.21.1](https://github.com/flowcore-io/data-pump/compare/v0.21.0...v0.21.1) (2026-05-10)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **notifier:** resolve waitWebSocket promise on WS error to prevent pull-loop wedge ([#72](https://github.com/flowcore-io/data-pump/issues/72)) ([d76ee0f](https://github.com/flowcore-io/data-pump/commit/d76ee0f0b5431f6a250a46948ad0c39693135c9c))
16
+
3
17
  ## [0.21.0](https://github.com/flowcore-io/data-pump/compare/v0.20.0...v0.21.0) (2026-04-24)
4
18
 
5
19
 
@@ -64,11 +64,13 @@ export declare class FlowcoreDataPump {
64
64
  private failedCount;
65
65
  private pulledCount;
66
66
  private processLoopRestartAttempts;
67
+ private mainLoopRestartAttempts;
67
68
  private constructor();
68
69
  get isRunning(): boolean;
69
70
  getSnapshot(): PulseSnapshot | null;
70
71
  static create(options: FlowcoreDataPumpOptions, dataSourceOverride?: FlowcoreDataSource): FlowcoreDataPump;
71
72
  start(callback?: (error?: Error) => void): Promise<void>;
73
+ private startMainLoop;
72
74
  restart(state: FlowcoreDataPumpState, stopAt?: Date | null): void;
73
75
  stop(isRestart?: boolean): void;
74
76
  private updateState;
@@ -1 +1 @@
1
- {"version":3,"file":"data-pump.d.ts","sourceRoot":"","sources":["../../src/data-pump/data-pump.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"data-pump.d.ts","sourceRoot":"","sources":["../../src/data-pump/data-pump.ts"],"names":[],"mappings":"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"}
@@ -127,6 +127,12 @@ export class FlowcoreDataPump {
127
127
  writable: true,
128
128
  value: 0
129
129
  });
130
+ Object.defineProperty(this, "mainLoopRestartAttempts", {
131
+ enumerable: true,
132
+ configurable: true,
133
+ writable: true,
134
+ value: 0
135
+ });
130
136
  // #endregion
131
137
  // #region Waiters
132
138
  Object.defineProperty(this, "waiterEvents", {
@@ -259,11 +265,36 @@ export class FlowcoreDataPump {
259
265
  if (!callback) {
260
266
  return this.loop();
261
267
  }
262
- void this.loop()
263
- .then(() => callback())
264
- .catch((error) => callback(error));
268
+ this.startMainLoop(callback);
269
+ }
270
+ startMainLoop(callback) {
271
+ this.loop()
272
+ .then(() => {
273
+ this.mainLoopRestartAttempts = 0;
274
+ callback?.();
275
+ })
276
+ .catch((error) => {
277
+ this.logger?.error("Error in fetch loop", { error });
278
+ if (!this.running) {
279
+ callback?.(error);
280
+ return;
281
+ }
282
+ this.mainLoopRestartAttempts++;
283
+ const delay = Math.min(1_000 * Math.pow(2, this.mainLoopRestartAttempts - 1), 30_000);
284
+ this.logger?.warn(`Restarting fetch loop in ${delay}ms (attempt ${this.mainLoopRestartAttempts})`);
285
+ setTimeout(() => {
286
+ if (!this.running) {
287
+ callback?.(error);
288
+ return;
289
+ }
290
+ this.startMainLoop(callback);
291
+ }, delay);
292
+ });
265
293
  }
266
294
  restart(state, stopAt) {
295
+ if (typeof state.timeBucket !== "string" || !state.timeBucket.match(/^\d{14}$/)) {
296
+ throw new Error(`Invalid timebucket: ${state.timeBucket}`);
297
+ }
267
298
  this.restartTo = state;
268
299
  if (stopAt !== undefined) {
269
300
  this.options.stopAt = stopAt ?? undefined;
@@ -273,6 +304,7 @@ export class FlowcoreDataPump {
273
304
  stop(isRestart = false) {
274
305
  this.running = false;
275
306
  this.processLoopRestartAttempts = 0;
307
+ this.mainLoopRestartAttempts = 0;
276
308
  this.buffer = [];
277
309
  this.updateMetricsGauges();
278
310
  this.pulseEmitter?.stop();
@@ -309,6 +341,7 @@ export class FlowcoreDataPump {
309
341
  }
310
342
  this.logger?.debug(`fetched ${events.length} events`);
311
343
  this.pulledCount += events.length;
344
+ this.mainLoopRestartAttempts = 0;
312
345
  this.buffer.push(...events.map((event) => ({ event, status: "open", deliveryCount: 0 })));
313
346
  this.nextCursor = nextCursor;
314
347
  this.updateMetricsGauges();
@@ -344,14 +377,21 @@ export class FlowcoreDataPump {
344
377
  }
345
378
  } while (this.running);
346
379
  if (this.restartTo) {
347
- await this.dataSource.getTimeBuckets(true);
348
- this.restartTo.timeBucket = (await this.dataSource.getClosestTimeBucket(this.restartTo.timeBucket)) ??
349
- format(startOfHour(utc(new Date())), "yyyyMMddHH0000");
350
- this.nextCursor = undefined;
351
- this.bufferState = this.restartTo;
352
- this.restartTo = undefined;
353
- this.running = true;
354
- return this.loop();
380
+ try {
381
+ await this.dataSource.getTimeBuckets(true);
382
+ this.restartTo.timeBucket = (await this.dataSource.getClosestTimeBucket(this.restartTo.timeBucket)) ??
383
+ format(startOfHour(utc(new Date())), "yyyyMMddHH0000");
384
+ this.nextCursor = undefined;
385
+ this.bufferState = this.restartTo;
386
+ this.restartTo = undefined;
387
+ this.running = true;
388
+ return this.loop();
389
+ }
390
+ catch (error) {
391
+ this.logger?.error("Failed to consume restartTo, dropping it", { error });
392
+ this.restartTo = undefined;
393
+ return;
394
+ }
355
395
  }
356
396
  this.logger?.info("Data pump stopped");
357
397
  }
@@ -1,3 +1,4 @@
1
+ import { NotificationClient } from "../deps/jsr.io/@flowcore/sdk/1.79.0/src/mod.js";
1
2
  import { NatsConnectionManager } from "./nats-connection.js";
2
3
  import type { FlowcoreDataPumpAuth, FlowcoreDataPumpDataSource, FlowcoreLogger } from "./types.js";
3
4
  export interface FlowcoreNotifierOptions {
@@ -27,4 +28,15 @@ export declare class FlowcoreNotifier {
27
28
  private waitWebSocket;
28
29
  private webSocketAuth;
29
30
  }
31
+ /**
32
+ * Test seam for stubbing the NotificationClient constructor. Production code
33
+ * routes through `_internals.createNotificationClient`; tests replace this
34
+ * property with a fake factory to drive the subject manually. Not part of the
35
+ * public API.
36
+ */
37
+ type NotificationClientFactory = (...args: any[]) => NotificationClient;
38
+ export declare const _internals: {
39
+ createNotificationClient: NotificationClientFactory;
40
+ };
41
+ export {};
30
42
  //# sourceMappingURL=notifier.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"notifier.d.ts","sourceRoot":"","sources":["../../src/data-pump/notifier.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAKlG,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,0BAA0B,CAAA;IACtC,IAAI,EAAE,oBAAoB,CAAA;IAC1B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IAC7C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,qBAAa,gBAAgB;IASf,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,WAAW,CAAC,CAAuB;IAC3C,OAAO,CAAC,OAAO,CAAC,CAA4B;IAC5C,OAAO,CAAC,kBAAkB,CAAC,CAAoB;IAC/C,OAAO,CAAC,aAAa,CAAC,CAAY;IAElC,OAAO,CAAC,KAAK,CAAC,CAAK;gBAEU,OAAO,EAAE,uBAAuB;IAetD,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW;YASlB,UAAU;YAUV,QAAQ;IAoCtB,OAAO,CAAC,gBAAgB;YAMV,aAAa;IAmC3B,OAAO,CAAC,aAAa;CAiBtB"}
1
+ {"version":3,"file":"notifier.d.ts","sourceRoot":"","sources":["../../src/data-pump/notifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA0B,MAAM,gDAAgD,CAAA;AAG3G,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAKlG,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,0BAA0B,CAAA;IACtC,IAAI,EAAE,oBAAoB,CAAA;IAC1B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IAC7C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,qBAAa,gBAAgB;IASf,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,WAAW,CAAC,CAAuB;IAC3C,OAAO,CAAC,OAAO,CAAC,CAA4B;IAC5C,OAAO,CAAC,kBAAkB,CAAC,CAAoB;IAC/C,OAAO,CAAC,aAAa,CAAC,CAAY;IAElC,OAAO,CAAC,KAAK,CAAC,CAAK;gBAEU,OAAO,EAAE,uBAAuB;IAetD,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW;YASlB,UAAU;YAUV,QAAQ;IAoCtB,OAAO,CAAC,gBAAgB;YAMV,aAAa;IA2C3B,OAAO,CAAC,aAAa;CAiBtB;AAED;;;;;GAKG;AAEH,KAAK,yBAAyB,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,kBAAkB,CAAA;AACvE,eAAO,MAAM,UAAU,EAAE;IAAE,wBAAwB,EAAE,yBAAyB,CAAA;CAG7E,CAAA"}
@@ -113,12 +113,18 @@ export class FlowcoreNotifier {
113
113
  }
114
114
  async waitWebSocket(signal) {
115
115
  this.options.logger?.debug("Waiting for web socket");
116
+ const promise = new Promise((resolve) => {
117
+ this.eventResolver = resolve;
118
+ });
116
119
  this.subject = new Subject();
117
120
  this.subject.subscribe({
118
121
  next: this.onWebSocketEvent.bind(this),
119
- error: (error) => this.options.logger?.error("Notification stream error:", { error }),
122
+ error: (error) => {
123
+ this.options.logger?.error("Notification stream error:", { error });
124
+ this.eventResolver?.();
125
+ },
120
126
  });
121
- this.notificationClient = new NotificationClient(this.subject, this.webSocketAuth(), {
127
+ this.notificationClient = _internals.createNotificationClient(this.subject, this.webSocketAuth(), {
122
128
  tenant: this.dataSource.tenant,
123
129
  dataCore: this.dataSource.dataCore,
124
130
  flowType: this.dataSource.flowType,
@@ -126,16 +132,18 @@ export class FlowcoreNotifier {
126
132
  logger: this.options.logger ?? noOpLogger,
127
133
  reconnectInterval: 1000,
128
134
  });
129
- await this.notificationClient.connect();
130
- const promise = new Promise((resolve) => {
131
- this.eventResolver = resolve;
132
- });
133
- clearTimeout(this.timer);
134
- this.timer = setTimeout(() => this.eventResolver?.(), this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
135
- signal?.addEventListener("abort", () => this.eventResolver?.());
136
- await promise;
137
- this.eventResolver = undefined;
138
- this.notificationClient.disconnect();
135
+ try {
136
+ await this.notificationClient.connect();
137
+ clearTimeout(this.timer);
138
+ this.timer = setTimeout(() => this.eventResolver?.(), this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
139
+ signal?.addEventListener("abort", () => this.eventResolver?.());
140
+ await promise;
141
+ }
142
+ finally {
143
+ clearTimeout(this.timer);
144
+ this.eventResolver = undefined;
145
+ this.notificationClient.disconnect();
146
+ }
139
147
  }
140
148
  webSocketAuth() {
141
149
  if ("apiKey" in this.options.auth) {
@@ -155,3 +163,6 @@ export class FlowcoreNotifier {
155
163
  };
156
164
  }
157
165
  }
166
+ export const _internals = {
167
+ createNotificationClient: (...args) => new NotificationClient(...args),
168
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowcore/data-pump",
3
- "version": "0.21.0",
3
+ "version": "0.21.2",
4
4
  "description": "Flowcore Data Pump",
5
5
  "homepage": "https://github.com/flowcore-io/flowcore-data-pump#readme",
6
6
  "repository": {
@@ -64,11 +64,13 @@ export declare class FlowcoreDataPump {
64
64
  private failedCount;
65
65
  private pulledCount;
66
66
  private processLoopRestartAttempts;
67
+ private mainLoopRestartAttempts;
67
68
  private constructor();
68
69
  get isRunning(): boolean;
69
70
  getSnapshot(): PulseSnapshot | null;
70
71
  static create(options: FlowcoreDataPumpOptions, dataSourceOverride?: FlowcoreDataSource): FlowcoreDataPump;
71
72
  start(callback?: (error?: Error) => void): Promise<void>;
73
+ private startMainLoop;
72
74
  restart(state: FlowcoreDataPumpState, stopAt?: Date | null): void;
73
75
  stop(isRestart?: boolean): void;
74
76
  private updateState;
@@ -1 +1 @@
1
- {"version":3,"file":"data-pump.d.ts","sourceRoot":"","sources":["../../src/data-pump/data-pump.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"data-pump.d.ts","sourceRoot":"","sources":["../../src/data-pump/data-pump.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAA;AAGnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAGrD,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AAC7D,OAAO,KAAK,EACV,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACrB,4BAA4B,EAC5B,cAAc,EACf,MAAM,YAAY,CAAA;AAEnB,UAAU,mCAAmC;IAC3C,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,UAAU,wCAAwC;IAChD,IAAI,EAAE,WAAW,CAAA;CAClB;AAED,UAAU,qCAAqC;IAC7C,IAAI,EAAE,QAAQ,CAAA;IACd;;OAEG;IACH,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,KAAK,+BAA+B,GAChC,mCAAmC,GACnC,wCAAwC,GACxC,qCAAqC,CAAA;AAEzC,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,oBAAoB,CAAA;IAC1B,UAAU,EAAE,0BAA0B,CAAA;IACtC,YAAY,EAAE,4BAA4B,CAAA;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,SAAS,CAAC,EAAE,yBAAyB,CAAA;IACrC,QAAQ,CAAC,EAAE,+BAA+B,CAAA;IAC1C,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,MAAM,CAAC,EAAE,IAAI,CAAA;IACb,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE;QACN,GAAG,EAAE,MAAM,CAAA;QACX,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,SAAS,EAAE,MAAM,CAAA;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,4DAA4D;QAC5D,eAAe,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;QACrD,wDAAwD;QACxD,eAAe,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;KACtD,CAAA;CACF;AAmBD,qBAAa,gBAAgB;aAmBT,UAAU,EAAE,kBAAkB;IAC9C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAtB1B,OAAO,CAAC,UAAU,CAAC,CAAQ;IAC3B,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,SAAS,CAAC,CAAuB;IACzC,OAAO,CAAC,eAAe,CAAC,CAAiB;IACzC,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,WAAW,CAAC,CAAuB;IAC3C,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,oBAAoB,CAAC,CAAmD;IAChF,OAAO,CAAC,YAAY,CAAC,CAAc;IACnC,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,iBAAiB,CAAI;IAC7B,OAAO,CAAC,WAAW,CAAI;IACvB,OAAO,CAAC,WAAW,CAAI;IACvB,OAAO,CAAC,0BAA0B,CAAI;IACtC,OAAO,CAAC,uBAAuB,CAAI;IAEnC,OAAO;IAaP,IAAW,SAAS,IAAI,OAAO,CAE9B;IAEM,WAAW,IAAI,aAAa,GAAG,IAAI;WAoB5B,MAAM,CAAC,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,CAAC,EAAE,kBAAkB,GAAG,gBAAgB;IAmEpG,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAwCrE,OAAO,CAAC,aAAa;IAyBd,OAAO,CAAC,KAAK,EAAE,qBAAqB,EAAE,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI;IAWjE,IAAI,CAAC,SAAS,UAAQ,GAAG,IAAI;IAcpC,OAAO,CAAC,WAAW;YAaL,IAAI;IA2FL,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAqCvD,cAAc,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAInE,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE;IA2B9B,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE;YA6BtB,MAAM;IAkDpB,OAAO,CAAC,gBAAgB;YAcV,WAAW;IAkBzB,OAAO,CAAC,mBAAmB;IA4D3B,OAAO,CAAC,iBAAiB;IA0CzB,OAAO,CAAC,YAAY,CAAC,CAAY;YACnB,aAAa;IAO3B,OAAO,CAAC,qBAAqB,CAAC,CAAY;YAC5B,sBAAsB;IAOpC,OAAO,CAAC,iBAAiB,CAAC,CAAY;YACxB,kBAAkB;CAWjC"}
@@ -130,6 +130,12 @@ class FlowcoreDataPump {
130
130
  writable: true,
131
131
  value: 0
132
132
  });
133
+ Object.defineProperty(this, "mainLoopRestartAttempts", {
134
+ enumerable: true,
135
+ configurable: true,
136
+ writable: true,
137
+ value: 0
138
+ });
133
139
  // #endregion
134
140
  // #region Waiters
135
141
  Object.defineProperty(this, "waiterEvents", {
@@ -262,11 +268,36 @@ class FlowcoreDataPump {
262
268
  if (!callback) {
263
269
  return this.loop();
264
270
  }
265
- void this.loop()
266
- .then(() => callback())
267
- .catch((error) => callback(error));
271
+ this.startMainLoop(callback);
272
+ }
273
+ startMainLoop(callback) {
274
+ this.loop()
275
+ .then(() => {
276
+ this.mainLoopRestartAttempts = 0;
277
+ callback?.();
278
+ })
279
+ .catch((error) => {
280
+ this.logger?.error("Error in fetch loop", { error });
281
+ if (!this.running) {
282
+ callback?.(error);
283
+ return;
284
+ }
285
+ this.mainLoopRestartAttempts++;
286
+ const delay = Math.min(1_000 * Math.pow(2, this.mainLoopRestartAttempts - 1), 30_000);
287
+ this.logger?.warn(`Restarting fetch loop in ${delay}ms (attempt ${this.mainLoopRestartAttempts})`);
288
+ setTimeout(() => {
289
+ if (!this.running) {
290
+ callback?.(error);
291
+ return;
292
+ }
293
+ this.startMainLoop(callback);
294
+ }, delay);
295
+ });
268
296
  }
269
297
  restart(state, stopAt) {
298
+ if (typeof state.timeBucket !== "string" || !state.timeBucket.match(/^\d{14}$/)) {
299
+ throw new Error(`Invalid timebucket: ${state.timeBucket}`);
300
+ }
270
301
  this.restartTo = state;
271
302
  if (stopAt !== undefined) {
272
303
  this.options.stopAt = stopAt ?? undefined;
@@ -276,6 +307,7 @@ class FlowcoreDataPump {
276
307
  stop(isRestart = false) {
277
308
  this.running = false;
278
309
  this.processLoopRestartAttempts = 0;
310
+ this.mainLoopRestartAttempts = 0;
279
311
  this.buffer = [];
280
312
  this.updateMetricsGauges();
281
313
  this.pulseEmitter?.stop();
@@ -312,6 +344,7 @@ class FlowcoreDataPump {
312
344
  }
313
345
  this.logger?.debug(`fetched ${events.length} events`);
314
346
  this.pulledCount += events.length;
347
+ this.mainLoopRestartAttempts = 0;
315
348
  this.buffer.push(...events.map((event) => ({ event, status: "open", deliveryCount: 0 })));
316
349
  this.nextCursor = nextCursor;
317
350
  this.updateMetricsGauges();
@@ -347,14 +380,21 @@ class FlowcoreDataPump {
347
380
  }
348
381
  } while (this.running);
349
382
  if (this.restartTo) {
350
- await this.dataSource.getTimeBuckets(true);
351
- this.restartTo.timeBucket = (await this.dataSource.getClosestTimeBucket(this.restartTo.timeBucket)) ??
352
- (0, date_fns_1.format)((0, date_fns_1.startOfHour)((0, utc_1.utc)(new Date())), "yyyyMMddHH0000");
353
- this.nextCursor = undefined;
354
- this.bufferState = this.restartTo;
355
- this.restartTo = undefined;
356
- this.running = true;
357
- return this.loop();
383
+ try {
384
+ await this.dataSource.getTimeBuckets(true);
385
+ this.restartTo.timeBucket = (await this.dataSource.getClosestTimeBucket(this.restartTo.timeBucket)) ??
386
+ (0, date_fns_1.format)((0, date_fns_1.startOfHour)((0, utc_1.utc)(new Date())), "yyyyMMddHH0000");
387
+ this.nextCursor = undefined;
388
+ this.bufferState = this.restartTo;
389
+ this.restartTo = undefined;
390
+ this.running = true;
391
+ return this.loop();
392
+ }
393
+ catch (error) {
394
+ this.logger?.error("Failed to consume restartTo, dropping it", { error });
395
+ this.restartTo = undefined;
396
+ return;
397
+ }
358
398
  }
359
399
  this.logger?.info("Data pump stopped");
360
400
  }
@@ -1,3 +1,4 @@
1
+ import { NotificationClient } from "../deps/jsr.io/@flowcore/sdk/1.79.0/src/mod.js";
1
2
  import { NatsConnectionManager } from "./nats-connection.js";
2
3
  import type { FlowcoreDataPumpAuth, FlowcoreDataPumpDataSource, FlowcoreLogger } from "./types.js";
3
4
  export interface FlowcoreNotifierOptions {
@@ -27,4 +28,15 @@ export declare class FlowcoreNotifier {
27
28
  private waitWebSocket;
28
29
  private webSocketAuth;
29
30
  }
31
+ /**
32
+ * Test seam for stubbing the NotificationClient constructor. Production code
33
+ * routes through `_internals.createNotificationClient`; tests replace this
34
+ * property with a fake factory to drive the subject manually. Not part of the
35
+ * public API.
36
+ */
37
+ type NotificationClientFactory = (...args: any[]) => NotificationClient;
38
+ export declare const _internals: {
39
+ createNotificationClient: NotificationClientFactory;
40
+ };
41
+ export {};
30
42
  //# sourceMappingURL=notifier.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"notifier.d.ts","sourceRoot":"","sources":["../../src/data-pump/notifier.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAKlG,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,0BAA0B,CAAA;IACtC,IAAI,EAAE,oBAAoB,CAAA;IAC1B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IAC7C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,qBAAa,gBAAgB;IASf,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,WAAW,CAAC,CAAuB;IAC3C,OAAO,CAAC,OAAO,CAAC,CAA4B;IAC5C,OAAO,CAAC,kBAAkB,CAAC,CAAoB;IAC/C,OAAO,CAAC,aAAa,CAAC,CAAY;IAElC,OAAO,CAAC,KAAK,CAAC,CAAK;gBAEU,OAAO,EAAE,uBAAuB;IAetD,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW;YASlB,UAAU;YAUV,QAAQ;IAoCtB,OAAO,CAAC,gBAAgB;YAMV,aAAa;IAmC3B,OAAO,CAAC,aAAa;CAiBtB"}
1
+ {"version":3,"file":"notifier.d.ts","sourceRoot":"","sources":["../../src/data-pump/notifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA0B,MAAM,gDAAgD,CAAA;AAG3G,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAKlG,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,0BAA0B,CAAA;IACtC,IAAI,EAAE,oBAAoB,CAAA;IAC1B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IAC7C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,qBAAa,gBAAgB;IASf,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,WAAW,CAAC,CAAuB;IAC3C,OAAO,CAAC,OAAO,CAAC,CAA4B;IAC5C,OAAO,CAAC,kBAAkB,CAAC,CAAoB;IAC/C,OAAO,CAAC,aAAa,CAAC,CAAY;IAElC,OAAO,CAAC,KAAK,CAAC,CAAK;gBAEU,OAAO,EAAE,uBAAuB;IAetD,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW;YASlB,UAAU;YAUV,QAAQ;IAoCtB,OAAO,CAAC,gBAAgB;YAMV,aAAa;IA2C3B,OAAO,CAAC,aAAa;CAiBtB;AAED;;;;;GAKG;AAEH,KAAK,yBAAyB,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,kBAAkB,CAAA;AACvE,eAAO,MAAM,UAAU,EAAE;IAAE,wBAAwB,EAAE,yBAAyB,CAAA;CAG7E,CAAA"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FlowcoreNotifier = void 0;
3
+ exports._internals = exports.FlowcoreNotifier = void 0;
4
4
  const mod_js_1 = require("../deps/jsr.io/@flowcore/sdk/1.79.0/src/mod.js");
5
5
  const rxjs_1 = require("rxjs");
6
6
  const data_source_js_1 = require("./data-source.js");
@@ -116,12 +116,18 @@ class FlowcoreNotifier {
116
116
  }
117
117
  async waitWebSocket(signal) {
118
118
  this.options.logger?.debug("Waiting for web socket");
119
+ const promise = new Promise((resolve) => {
120
+ this.eventResolver = resolve;
121
+ });
119
122
  this.subject = new rxjs_1.Subject();
120
123
  this.subject.subscribe({
121
124
  next: this.onWebSocketEvent.bind(this),
122
- error: (error) => this.options.logger?.error("Notification stream error:", { error }),
125
+ error: (error) => {
126
+ this.options.logger?.error("Notification stream error:", { error });
127
+ this.eventResolver?.();
128
+ },
123
129
  });
124
- this.notificationClient = new mod_js_1.NotificationClient(this.subject, this.webSocketAuth(), {
130
+ this.notificationClient = exports._internals.createNotificationClient(this.subject, this.webSocketAuth(), {
125
131
  tenant: this.dataSource.tenant,
126
132
  dataCore: this.dataSource.dataCore,
127
133
  flowType: this.dataSource.flowType,
@@ -129,16 +135,18 @@ class FlowcoreNotifier {
129
135
  logger: this.options.logger ?? no_op_logger_js_1.noOpLogger,
130
136
  reconnectInterval: 1000,
131
137
  });
132
- await this.notificationClient.connect();
133
- const promise = new Promise((resolve) => {
134
- this.eventResolver = resolve;
135
- });
136
- clearTimeout(this.timer);
137
- this.timer = setTimeout(() => this.eventResolver?.(), this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
138
- signal?.addEventListener("abort", () => this.eventResolver?.());
139
- await promise;
140
- this.eventResolver = undefined;
141
- this.notificationClient.disconnect();
138
+ try {
139
+ await this.notificationClient.connect();
140
+ clearTimeout(this.timer);
141
+ this.timer = setTimeout(() => this.eventResolver?.(), this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
142
+ signal?.addEventListener("abort", () => this.eventResolver?.());
143
+ await promise;
144
+ }
145
+ finally {
146
+ clearTimeout(this.timer);
147
+ this.eventResolver = undefined;
148
+ this.notificationClient.disconnect();
149
+ }
142
150
  }
143
151
  webSocketAuth() {
144
152
  if ("apiKey" in this.options.auth) {
@@ -159,3 +167,6 @@ class FlowcoreNotifier {
159
167
  }
160
168
  }
161
169
  exports.FlowcoreNotifier = FlowcoreNotifier;
170
+ exports._internals = {
171
+ createNotificationClient: (...args) => new mod_js_1.NotificationClient(...args),
172
+ };