@flowcore/data-pump 0.1.9 → 0.1.11

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.1.11](https://github.com/flowcore-io/data-pump/compare/v0.1.10...v0.1.11) (2025-02-19)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * fix for stop at ([efded7a](https://github.com/flowcore-io/data-pump/commit/efded7ad473e9b533378eb0b0c629ca7805ba2e4))
9
+
10
+ ## [0.1.10](https://github.com/flowcore-io/data-pump/compare/v0.1.9...v0.1.10) (2025-02-19)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * add stop at option ([e0d90eb](https://github.com/flowcore-io/data-pump/commit/e0d90eb48dea096ee8cc9602b9b3acf9a706d7f8))
16
+
3
17
  ## [0.1.9](https://github.com/flowcore-io/data-pump/compare/v0.1.8...v0.1.9) (2025-02-19)
4
18
 
5
19
 
@@ -0,0 +1,50 @@
1
+ declare global {
2
+ interface Array<T> {
3
+ /**
4
+ * Returns the value of the last element in the array where predicate is true, and undefined
5
+ * otherwise.
6
+ * @param predicate find calls predicate once for each element of the array, in ascending
7
+ * order, until it finds one where predicate returns true. If such an element is found, find
8
+ * immediately returns that element value. Otherwise, find returns undefined.
9
+ * @param thisArg If provided, it will be used as the this value for each invocation of
10
+ * predicate. If it is not provided, undefined is used instead.
11
+ */
12
+ findLast<S extends T>(predicate: (this: void, value: T, index: number, obj: T[]) => value is S, thisArg?: any): S | undefined;
13
+ findLast(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): T | undefined;
14
+ /**
15
+ * Returns the index of the last element in the array where predicate is true, and -1
16
+ * otherwise.
17
+ * @param predicate find calls predicate once for each element of the array, in ascending
18
+ * order, until it finds one where predicate returns true. If such an element is found,
19
+ * findIndex immediately returns that element index. Otherwise, findIndex returns -1.
20
+ * @param thisArg If provided, it will be used as the this value for each invocation of
21
+ * predicate. If it is not provided, undefined is used instead.
22
+ */
23
+ findLastIndex(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): number;
24
+ }
25
+ interface Uint8Array {
26
+ /**
27
+ * Returns the value of the last element in the array where predicate is true, and undefined
28
+ * otherwise.
29
+ * @param predicate findLast calls predicate once for each element of the array, in descending
30
+ * order, until it finds one where predicate returns true. If such an element is found, findLast
31
+ * immediately returns that element value. Otherwise, findLast returns undefined.
32
+ * @param thisArg If provided, it will be used as the this value for each invocation of
33
+ * predicate. If it is not provided, undefined is used instead.
34
+ */
35
+ findLast<S extends number>(predicate: (value: number, index: number, array: Uint8Array) => value is S, thisArg?: any): S | undefined;
36
+ findLast(predicate: (value: number, index: number, array: Uint8Array) => unknown, thisArg?: any): number | undefined;
37
+ /**
38
+ * Returns the index of the last element in the array where predicate is true, and -1
39
+ * otherwise.
40
+ * @param predicate findLastIndex calls predicate once for each element of the array, in descending
41
+ * order, until it finds one where predicate returns true. If such an element is found,
42
+ * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
43
+ * @param thisArg If provided, it will be used as the this value for each invocation of
44
+ * predicate. If it is not provided, undefined is used instead.
45
+ */
46
+ findLastIndex(predicate: (value: number, index: number, array: Uint8Array) => unknown, thisArg?: any): number;
47
+ }
48
+ }
49
+ export {};
50
+ //# sourceMappingURL=_dnt.polyfills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_dnt.polyfills.d.ts","sourceRoot":"","sources":["../src/_dnt.polyfills.ts"],"names":[],"mappings":"AACA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,KAAK,CAAC,CAAC;QACf;;;;;;;;WAQG;QACH,QAAQ,CAAC,CAAC,SAAS,CAAC,EAClB,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC,EACxE,OAAO,CAAC,EAAE,GAAG,GACZ,CAAC,GAAG,SAAS,CAAC;QACjB,QAAQ,CACN,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,OAAO,EACzD,OAAO,CAAC,EAAE,GAAG,GACZ,CAAC,GAAG,SAAS,CAAC;QAEjB;;;;;;;;WAQG;QACH,aAAa,CACX,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,OAAO,EACzD,OAAO,CAAC,EAAE,GAAG,GACZ,MAAM,CAAC;KACX;IACD,UAAU,UAAU;QAClB;;;;;;;;WAQG;QACH,QAAQ,CAAC,CAAC,SAAS,MAAM,EACvB,SAAS,EAAE,CACP,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,UAAU,KAChB,KAAK,IAAI,CAAC,EACf,OAAO,CAAC,EAAE,GAAG,GACZ,CAAC,GAAG,SAAS,CAAC;QACjB,QAAQ,CACJ,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,OAAO,EACvE,OAAO,CAAC,EAAE,GAAG,GACd,MAAM,GAAG,SAAS,CAAC;QAEtB;;;;;;;;WAQG;QACH,aAAa,CACT,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,OAAO,EACvE,OAAO,CAAC,EAAE,GAAG,GACd,MAAM,CAAC;KACX;CACF;AA4CD,OAAO,EAAE,CAAC"}
@@ -0,0 +1,37 @@
1
+ function findLastIndex(self, callbackfn, that) {
2
+ const boundFunc = that === undefined ? callbackfn : callbackfn.bind(that);
3
+ let index = self.length - 1;
4
+ while (index >= 0) {
5
+ const result = boundFunc(self[index], index, self);
6
+ if (result) {
7
+ return index;
8
+ }
9
+ index--;
10
+ }
11
+ return -1;
12
+ }
13
+ function findLast(self, callbackfn, that) {
14
+ const index = self.findLastIndex(callbackfn, that);
15
+ return index === -1 ? undefined : self[index];
16
+ }
17
+ if (!Array.prototype.findLastIndex) {
18
+ Array.prototype.findLastIndex = function (callbackfn, that) {
19
+ return findLastIndex(this, callbackfn, that);
20
+ };
21
+ }
22
+ if (!Array.prototype.findLast) {
23
+ Array.prototype.findLast = function (callbackfn, that) {
24
+ return findLast(this, callbackfn, that);
25
+ };
26
+ }
27
+ if (!Uint8Array.prototype.findLastIndex) {
28
+ Uint8Array.prototype.findLastIndex = function (callbackfn, that) {
29
+ return findLastIndex(this, callbackfn, that);
30
+ };
31
+ }
32
+ if (!Uint8Array.prototype.findLast) {
33
+ Uint8Array.prototype.findLast = function (callbackfn, that) {
34
+ return findLast(this, callbackfn, that);
35
+ };
36
+ }
37
+ export {};
@@ -36,7 +36,9 @@ export interface DataPumpClientOptions {
36
36
  concurrency?: number;
37
37
  onEvents: (events: FlowcoreEvent[]) => Promise<boolean> | boolean;
38
38
  onFailedEvents?: (events: FlowcoreEvent[]) => Promise<void> | void;
39
+ onDone?: () => Promise<void> | void;
39
40
  };
41
+ stopAt?: Date;
40
42
  natsServers?: string[];
41
43
  }
42
44
  export declare function createDataPump(options: DataPumpClientOptions): DataPump;
@@ -1 +1 @@
1
- {"version":3,"file":"data-pump-create.d.ts","sourceRoot":"","sources":["../../src/lib/data-pump-create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,iDAAiD,CAAA;AACpG,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAIjF,eAAO,MAAM,UAAU,EAAE,MAKxB,CAAA;AAED,UAAU,mCAAmC;IAC3C,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,OAAO,CAAC;YAAE,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KACjD,CAAA;CACF;AAED,UAAU,+BAA+B;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,KAAK,yBAAyB,GAAG,mCAAmC,GAAG,+BAA+B,CAAA;AAEtG;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,yBAAyB,CAAA;IAC/B,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;QAChB,UAAU,EAAE,MAAM,EAAE,CAAA;KACrB,CAAA;IACD,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,kBAAkB,CAAC,EAAE,MAAM,CAAA;QAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAA;KAC/B,CAAA;IACD,YAAY,CAAC,EAAE,oBAAoB,CAAA;IACnC,SAAS,CAAC,EAAE;QACV,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;QACjE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;KACnE,CAAA;IACD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,QAAQ,CAwDvE"}
1
+ {"version":3,"file":"data-pump-create.d.ts","sourceRoot":"","sources":["../../src/lib/data-pump-create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,iDAAiD,CAAA;AACpG,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAIjF,eAAO,MAAM,UAAU,EAAE,MAKxB,CAAA;AAED,UAAU,mCAAmC;IAC3C,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,OAAO,CAAC;YAAE,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KACjD,CAAA;CACF;AAED,UAAU,+BAA+B;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,KAAK,yBAAyB,GAAG,mCAAmC,GAAG,+BAA+B,CAAA;AAEtG;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,yBAAyB,CAAA;IAC/B,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;QAChB,UAAU,EAAE,MAAM,EAAE,CAAA;KACrB,CAAA;IACD,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,kBAAkB,CAAC,EAAE,MAAM,CAAA;QAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAA;KAC/B,CAAA;IACD,YAAY,CAAC,EAAE,oBAAoB,CAAA;IACnC,SAAS,CAAC,EAAE;QACV,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;QACjE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;QAClE,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;KACpC,CAAA;IACD,MAAM,CAAC,EAAE,IAAI,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,QAAQ,CA0DvE"}
@@ -47,6 +47,7 @@ export function createDataPump(options) {
47
47
  concurrency: options.processor.concurrency ?? 1,
48
48
  onEvents: options.processor.onEvents,
49
49
  onFailedEvents: options.processor.onFailedEvents,
50
+ onDone: options.processor.onDone,
50
51
  }
51
52
  : undefined;
52
53
  const dataPump = new DataPump({
@@ -57,6 +58,7 @@ export function createDataPump(options) {
57
58
  processor,
58
59
  notifier: notifier.getNotifier(),
59
60
  logger: options.logger,
61
+ stopAt: options.stopAt,
60
62
  });
61
63
  return dataPump;
62
64
  }
@@ -26,15 +26,18 @@ interface DataPumpOptions {
26
26
  concurrency: number;
27
27
  onEvents: (events: FlowcoreEvent[]) => Promise<boolean> | boolean;
28
28
  onFailedEvents?: (events: FlowcoreEvent[]) => Promise<void> | void;
29
+ onDone?: () => Promise<void> | void;
29
30
  };
31
+ stopAt?: Date;
30
32
  }
31
33
  export interface DataPumpState {
32
34
  timeBucket: string;
33
35
  eventId?: string;
34
36
  }
35
37
  export interface DataPumpStateManager {
36
- getState(): Promise<DataPumpState | null> | DataPumpState | null;
37
- setState(state: DataPumpState): Promise<void> | void;
38
+ getState: () => Promise<DataPumpState | null> | DataPumpState | null;
39
+ setState?: (state: DataPumpState) => Promise<void> | void;
40
+ stopAt?: () => Date;
38
41
  }
39
42
  export interface DataPumpNotifier {
40
43
  wait(dataSource: DataPumpOptions["dataSource"] & {
@@ -52,6 +55,7 @@ export declare class DataPump {
52
55
  private running;
53
56
  private notifierAbortController?;
54
57
  private dataCoreId?;
58
+ private stopAt?;
55
59
  constructor(options: DataPumpOptions);
56
60
  start(): Promise<void>;
57
61
  stop(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"data-pump.d.ts","sourceRoot":"","sources":["../../src/lib/data-pump.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"data-pump.d.ts","sourceRoot":"","sources":["../../src/lib/data-pump.ts"],"names":[],"mappings":"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"}
@@ -69,6 +69,12 @@ export class DataPump {
69
69
  writable: true,
70
70
  value: void 0
71
71
  });
72
+ Object.defineProperty(this, "stopAt", {
73
+ enumerable: true,
74
+ configurable: true,
75
+ writable: true,
76
+ value: void 0
77
+ });
72
78
  this.state = {
73
79
  timeBucket: this.getNowTimeBucket(),
74
80
  };
@@ -79,6 +85,17 @@ export class DataPump {
79
85
  return;
80
86
  }
81
87
  await this.updateTimeBuckets();
88
+ if (this.options.stopAt) {
89
+ const timeBucket = format(startOfHour(utc(this.options.stopAt)), "yyyyMMddHH0000");
90
+ const lastTimeBucket = this.getClosestTimeBucket(timeBucket, true);
91
+ const lastEventId = TimeUuid.fromDate(this.options.stopAt).toString();
92
+ this.stopAt = {
93
+ timeBucket: lastTimeBucket,
94
+ eventId: lastEventId,
95
+ eventBufferReached: false,
96
+ };
97
+ console.log("stop at", this.stopAt);
98
+ }
82
99
  const newState = await this.options.stateManager.getState();
83
100
  if (!newState) {
84
101
  this.state.timeBucket = this.getClosestTimeBucket(this.getNowTimeBucket());
@@ -88,6 +105,9 @@ export class DataPump {
88
105
  this.state.timeBucket = this.getClosestTimeBucket(newState.timeBucket);
89
106
  this.state.eventId = newState.eventId;
90
107
  }
108
+ if (this.stopAt?.timeBucket && this.state.timeBucket > this.stopAt.timeBucket) {
109
+ throw new Error("Stop at time is lower than current state");
110
+ }
91
111
  this.running = true;
92
112
  this.logger?.debug("Starting event buffer loop");
93
113
  this.eventBufferLoop()
@@ -138,6 +158,10 @@ export class DataPump {
138
158
  if (!this.running) {
139
159
  return;
140
160
  }
161
+ if (this.stopAt?.eventBufferReached) {
162
+ await new Promise((resolve) => setTimeout(resolve, 10_000));
163
+ return this.eventBufferLoop();
164
+ }
141
165
  // Buffer is full, wait for some space
142
166
  if (this.buffer.length >= this.options.buffer.size - this.options.buffer.threshold && this.running) {
143
167
  this.logger?.debug("Buffer is full, waiting for some space");
@@ -159,6 +183,7 @@ export class DataPump {
159
183
  timeBucket: this.state.timeBucket,
160
184
  afterEventId: this.state.eventId,
161
185
  pageSize: eventsToFetch,
186
+ toEventId: this.stopAt?.eventId,
162
187
  });
163
188
  const result = await this.options.flowcoreClient.execute(command);
164
189
  const time = Date.now() - timeStart;
@@ -181,6 +206,13 @@ export class DataPump {
181
206
  this.state.eventId = result.events[result.events.length - 1]?.eventId ?? this.state.eventId;
182
207
  // If we don't have a next cursor move to next time bucket
183
208
  if (!result.nextCursor) {
209
+ // Check if we reached the stop at
210
+ if (this.state.timeBucket === this.stopAt?.timeBucket) {
211
+ this.stopAt.eventBufferReached = true;
212
+ this.logger?.debug("Reached stop at");
213
+ this.waiter?.();
214
+ return this.eventBufferLoop();
215
+ }
184
216
  // Get next time bucket
185
217
  const nextTimeBucketIndex = this.timeBuckets.indexOf(this.state.timeBucket) + 1;
186
218
  // There is no next time bucket
@@ -238,13 +270,13 @@ export class DataPump {
238
270
  if (!firstEvent) {
239
271
  if (eventId) {
240
272
  const timeUuid = TimeUuid.fromString(eventId);
241
- return this.options.stateManager.setState({ timeBucket: timeUuid.getTimeBucket(), eventId });
273
+ return this.options.stateManager.setState?.({ timeBucket: timeUuid.getTimeBucket(), eventId });
242
274
  }
243
275
  return;
244
276
  }
245
277
  const timeUuid = TimeUuid.fromString(firstEvent.event.eventId);
246
278
  const timeBucket = firstEvent.event.timeBucket;
247
- return this.options.stateManager.setState({ timeBucket, eventId: timeUuid.getBefore().toString() });
279
+ return this.options.stateManager.setState?.({ timeBucket, eventId: timeUuid.getBefore().toString() });
248
280
  }
249
281
  get timeBuckets() {
250
282
  const timeBucketNow = this.getNowTimeBucket();
@@ -253,10 +285,14 @@ export class DataPump {
253
285
  }
254
286
  return this._timeBuckets;
255
287
  }
256
- getClosestTimeBucket(timeBucket) {
288
+ getClosestTimeBucket(timeBucket, getBefore = false) {
257
289
  if (!timeBucket.match(/^\d{14}$/)) {
258
290
  throw new Error(`Invalid timebucket: ${timeBucket}`);
259
291
  }
292
+ if (getBefore) {
293
+ return (this.timeBuckets.findLast((t) => Number.parseFloat(t) <= Number.parseFloat(timeBucket)) ??
294
+ this.timeBuckets[this.timeBuckets.length - 1]);
295
+ }
260
296
  return (this.timeBuckets.find((t) => Number.parseFloat(t) >= Number.parseFloat(timeBucket)) ??
261
297
  this.timeBuckets[this.timeBuckets.length - 1]);
262
298
  }
@@ -283,6 +319,11 @@ export class DataPump {
283
319
  if (!this.running) {
284
320
  throw new Error("Data pump not running");
285
321
  }
322
+ if (this.stopAt?.eventBufferReached && this.buffer.length === 0) {
323
+ await this.options.processor?.onDone?.();
324
+ await this.stop();
325
+ return [];
326
+ }
286
327
  const deliveryId = crypto.randomUUID();
287
328
  const events = [];
288
329
  for (const event of this.buffer) {
@@ -329,6 +370,10 @@ export class DataPump {
329
370
  else {
330
371
  await this.updateState();
331
372
  }
373
+ if (!this.buffer.length && this.stopAt?.eventBufferReached) {
374
+ await this.options.processor?.onDone?.();
375
+ await this.stop();
376
+ }
332
377
  }
333
378
  async waitForNotifier() {
334
379
  this.logger?.debug("No more events, waiting for notifier...");
package/esm/mod.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import "./_dnt.polyfills.js";
1
2
  export * from "./lib/data-pump.js";
2
3
  export * from "./lib/data-pump-create.js";
3
4
  export * from "./lib/time-uuid.js";
package/esm/mod.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,2BAA2B,CAAA;AAEzC,cAAc,oBAAoB,CAAA"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAC7B,cAAc,oBAAoB,CAAA;AAClC,cAAc,2BAA2B,CAAA;AAEzC,cAAc,oBAAoB,CAAA"}
package/esm/mod.js CHANGED
@@ -1,3 +1,4 @@
1
+ import "./_dnt.polyfills.js";
1
2
  export * from "./lib/data-pump.js";
2
3
  export * from "./lib/data-pump-create.js";
3
4
  export * from "./lib/time-uuid.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowcore/data-pump",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "Flowcore Data Pump",
5
5
  "homepage": "https://github.com/flowcore-io/flowcore-data-pump#readme",
6
6
  "repository": {
@@ -0,0 +1,50 @@
1
+ declare global {
2
+ interface Array<T> {
3
+ /**
4
+ * Returns the value of the last element in the array where predicate is true, and undefined
5
+ * otherwise.
6
+ * @param predicate find calls predicate once for each element of the array, in ascending
7
+ * order, until it finds one where predicate returns true. If such an element is found, find
8
+ * immediately returns that element value. Otherwise, find returns undefined.
9
+ * @param thisArg If provided, it will be used as the this value for each invocation of
10
+ * predicate. If it is not provided, undefined is used instead.
11
+ */
12
+ findLast<S extends T>(predicate: (this: void, value: T, index: number, obj: T[]) => value is S, thisArg?: any): S | undefined;
13
+ findLast(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): T | undefined;
14
+ /**
15
+ * Returns the index of the last element in the array where predicate is true, and -1
16
+ * otherwise.
17
+ * @param predicate find calls predicate once for each element of the array, in ascending
18
+ * order, until it finds one where predicate returns true. If such an element is found,
19
+ * findIndex immediately returns that element index. Otherwise, findIndex returns -1.
20
+ * @param thisArg If provided, it will be used as the this value for each invocation of
21
+ * predicate. If it is not provided, undefined is used instead.
22
+ */
23
+ findLastIndex(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): number;
24
+ }
25
+ interface Uint8Array {
26
+ /**
27
+ * Returns the value of the last element in the array where predicate is true, and undefined
28
+ * otherwise.
29
+ * @param predicate findLast calls predicate once for each element of the array, in descending
30
+ * order, until it finds one where predicate returns true. If such an element is found, findLast
31
+ * immediately returns that element value. Otherwise, findLast returns undefined.
32
+ * @param thisArg If provided, it will be used as the this value for each invocation of
33
+ * predicate. If it is not provided, undefined is used instead.
34
+ */
35
+ findLast<S extends number>(predicate: (value: number, index: number, array: Uint8Array) => value is S, thisArg?: any): S | undefined;
36
+ findLast(predicate: (value: number, index: number, array: Uint8Array) => unknown, thisArg?: any): number | undefined;
37
+ /**
38
+ * Returns the index of the last element in the array where predicate is true, and -1
39
+ * otherwise.
40
+ * @param predicate findLastIndex calls predicate once for each element of the array, in descending
41
+ * order, until it finds one where predicate returns true. If such an element is found,
42
+ * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
43
+ * @param thisArg If provided, it will be used as the this value for each invocation of
44
+ * predicate. If it is not provided, undefined is used instead.
45
+ */
46
+ findLastIndex(predicate: (value: number, index: number, array: Uint8Array) => unknown, thisArg?: any): number;
47
+ }
48
+ }
49
+ export {};
50
+ //# sourceMappingURL=_dnt.polyfills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_dnt.polyfills.d.ts","sourceRoot":"","sources":["../src/_dnt.polyfills.ts"],"names":[],"mappings":"AACA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,KAAK,CAAC,CAAC;QACf;;;;;;;;WAQG;QACH,QAAQ,CAAC,CAAC,SAAS,CAAC,EAClB,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC,EACxE,OAAO,CAAC,EAAE,GAAG,GACZ,CAAC,GAAG,SAAS,CAAC;QACjB,QAAQ,CACN,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,OAAO,EACzD,OAAO,CAAC,EAAE,GAAG,GACZ,CAAC,GAAG,SAAS,CAAC;QAEjB;;;;;;;;WAQG;QACH,aAAa,CACX,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,OAAO,EACzD,OAAO,CAAC,EAAE,GAAG,GACZ,MAAM,CAAC;KACX;IACD,UAAU,UAAU;QAClB;;;;;;;;WAQG;QACH,QAAQ,CAAC,CAAC,SAAS,MAAM,EACvB,SAAS,EAAE,CACP,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,UAAU,KAChB,KAAK,IAAI,CAAC,EACf,OAAO,CAAC,EAAE,GAAG,GACZ,CAAC,GAAG,SAAS,CAAC;QACjB,QAAQ,CACJ,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,OAAO,EACvE,OAAO,CAAC,EAAE,GAAG,GACd,MAAM,GAAG,SAAS,CAAC;QAEtB;;;;;;;;WAQG;QACH,aAAa,CACT,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,OAAO,EACvE,OAAO,CAAC,EAAE,GAAG,GACd,MAAM,CAAC;KACX;CACF;AA4CD,OAAO,EAAE,CAAC"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function findLastIndex(self, callbackfn, that) {
4
+ const boundFunc = that === undefined ? callbackfn : callbackfn.bind(that);
5
+ let index = self.length - 1;
6
+ while (index >= 0) {
7
+ const result = boundFunc(self[index], index, self);
8
+ if (result) {
9
+ return index;
10
+ }
11
+ index--;
12
+ }
13
+ return -1;
14
+ }
15
+ function findLast(self, callbackfn, that) {
16
+ const index = self.findLastIndex(callbackfn, that);
17
+ return index === -1 ? undefined : self[index];
18
+ }
19
+ if (!Array.prototype.findLastIndex) {
20
+ Array.prototype.findLastIndex = function (callbackfn, that) {
21
+ return findLastIndex(this, callbackfn, that);
22
+ };
23
+ }
24
+ if (!Array.prototype.findLast) {
25
+ Array.prototype.findLast = function (callbackfn, that) {
26
+ return findLast(this, callbackfn, that);
27
+ };
28
+ }
29
+ if (!Uint8Array.prototype.findLastIndex) {
30
+ Uint8Array.prototype.findLastIndex = function (callbackfn, that) {
31
+ return findLastIndex(this, callbackfn, that);
32
+ };
33
+ }
34
+ if (!Uint8Array.prototype.findLast) {
35
+ Uint8Array.prototype.findLast = function (callbackfn, that) {
36
+ return findLast(this, callbackfn, that);
37
+ };
38
+ }
@@ -36,7 +36,9 @@ export interface DataPumpClientOptions {
36
36
  concurrency?: number;
37
37
  onEvents: (events: FlowcoreEvent[]) => Promise<boolean> | boolean;
38
38
  onFailedEvents?: (events: FlowcoreEvent[]) => Promise<void> | void;
39
+ onDone?: () => Promise<void> | void;
39
40
  };
41
+ stopAt?: Date;
40
42
  natsServers?: string[];
41
43
  }
42
44
  export declare function createDataPump(options: DataPumpClientOptions): DataPump;
@@ -1 +1 @@
1
- {"version":3,"file":"data-pump-create.d.ts","sourceRoot":"","sources":["../../src/lib/data-pump-create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,iDAAiD,CAAA;AACpG,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAIjF,eAAO,MAAM,UAAU,EAAE,MAKxB,CAAA;AAED,UAAU,mCAAmC;IAC3C,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,OAAO,CAAC;YAAE,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KACjD,CAAA;CACF;AAED,UAAU,+BAA+B;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,KAAK,yBAAyB,GAAG,mCAAmC,GAAG,+BAA+B,CAAA;AAEtG;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,yBAAyB,CAAA;IAC/B,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;QAChB,UAAU,EAAE,MAAM,EAAE,CAAA;KACrB,CAAA;IACD,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,kBAAkB,CAAC,EAAE,MAAM,CAAA;QAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAA;KAC/B,CAAA;IACD,YAAY,CAAC,EAAE,oBAAoB,CAAA;IACnC,SAAS,CAAC,EAAE;QACV,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;QACjE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;KACnE,CAAA;IACD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,QAAQ,CAwDvE"}
1
+ {"version":3,"file":"data-pump-create.d.ts","sourceRoot":"","sources":["../../src/lib/data-pump-create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,iDAAiD,CAAA;AACpG,OAAO,EAAE,QAAQ,EAAE,KAAK,oBAAoB,EAAE,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAIjF,eAAO,MAAM,UAAU,EAAE,MAKxB,CAAA;AAED,UAAU,mCAAmC;IAC3C,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,OAAO,CAAC;YAAE,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KACjD,CAAA;CACF;AAED,UAAU,+BAA+B;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,KAAK,yBAAyB,GAAG,mCAAmC,GAAG,+BAA+B,CAAA;AAEtG;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,yBAAyB,CAAA;IAC/B,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;QAChB,UAAU,EAAE,MAAM,EAAE,CAAA;KACrB,CAAA;IACD,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,kBAAkB,CAAC,EAAE,MAAM,CAAA;QAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAA;KAC/B,CAAA;IACD,YAAY,CAAC,EAAE,oBAAoB,CAAA;IACnC,SAAS,CAAC,EAAE;QACV,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;QACjE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;QAClE,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;KACpC,CAAA;IACD,MAAM,CAAC,EAAE,IAAI,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,QAAQ,CA0DvE"}
@@ -51,6 +51,7 @@ function createDataPump(options) {
51
51
  concurrency: options.processor.concurrency ?? 1,
52
52
  onEvents: options.processor.onEvents,
53
53
  onFailedEvents: options.processor.onFailedEvents,
54
+ onDone: options.processor.onDone,
54
55
  }
55
56
  : undefined;
56
57
  const dataPump = new data_pump_js_1.DataPump({
@@ -61,6 +62,7 @@ function createDataPump(options) {
61
62
  processor,
62
63
  notifier: notifier.getNotifier(),
63
64
  logger: options.logger,
65
+ stopAt: options.stopAt,
64
66
  });
65
67
  return dataPump;
66
68
  }
@@ -26,15 +26,18 @@ interface DataPumpOptions {
26
26
  concurrency: number;
27
27
  onEvents: (events: FlowcoreEvent[]) => Promise<boolean> | boolean;
28
28
  onFailedEvents?: (events: FlowcoreEvent[]) => Promise<void> | void;
29
+ onDone?: () => Promise<void> | void;
29
30
  };
31
+ stopAt?: Date;
30
32
  }
31
33
  export interface DataPumpState {
32
34
  timeBucket: string;
33
35
  eventId?: string;
34
36
  }
35
37
  export interface DataPumpStateManager {
36
- getState(): Promise<DataPumpState | null> | DataPumpState | null;
37
- setState(state: DataPumpState): Promise<void> | void;
38
+ getState: () => Promise<DataPumpState | null> | DataPumpState | null;
39
+ setState?: (state: DataPumpState) => Promise<void> | void;
40
+ stopAt?: () => Date;
38
41
  }
39
42
  export interface DataPumpNotifier {
40
43
  wait(dataSource: DataPumpOptions["dataSource"] & {
@@ -52,6 +55,7 @@ export declare class DataPump {
52
55
  private running;
53
56
  private notifierAbortController?;
54
57
  private dataCoreId?;
58
+ private stopAt?;
55
59
  constructor(options: DataPumpOptions);
56
60
  start(): Promise<void>;
57
61
  stop(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"data-pump.d.ts","sourceRoot":"","sources":["../../src/lib/data-pump.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"data-pump.d.ts","sourceRoot":"","sources":["../../src/lib/data-pump.ts"],"names":[],"mappings":"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"}
@@ -72,6 +72,12 @@ class DataPump {
72
72
  writable: true,
73
73
  value: void 0
74
74
  });
75
+ Object.defineProperty(this, "stopAt", {
76
+ enumerable: true,
77
+ configurable: true,
78
+ writable: true,
79
+ value: void 0
80
+ });
75
81
  this.state = {
76
82
  timeBucket: this.getNowTimeBucket(),
77
83
  };
@@ -82,6 +88,17 @@ class DataPump {
82
88
  return;
83
89
  }
84
90
  await this.updateTimeBuckets();
91
+ if (this.options.stopAt) {
92
+ const timeBucket = (0, date_fns_1.format)((0, date_fns_1.startOfHour)((0, utc_1.utc)(this.options.stopAt)), "yyyyMMddHH0000");
93
+ const lastTimeBucket = this.getClosestTimeBucket(timeBucket, true);
94
+ const lastEventId = time_uuid_js_1.TimeUuid.fromDate(this.options.stopAt).toString();
95
+ this.stopAt = {
96
+ timeBucket: lastTimeBucket,
97
+ eventId: lastEventId,
98
+ eventBufferReached: false,
99
+ };
100
+ console.log("stop at", this.stopAt);
101
+ }
85
102
  const newState = await this.options.stateManager.getState();
86
103
  if (!newState) {
87
104
  this.state.timeBucket = this.getClosestTimeBucket(this.getNowTimeBucket());
@@ -91,6 +108,9 @@ class DataPump {
91
108
  this.state.timeBucket = this.getClosestTimeBucket(newState.timeBucket);
92
109
  this.state.eventId = newState.eventId;
93
110
  }
111
+ if (this.stopAt?.timeBucket && this.state.timeBucket > this.stopAt.timeBucket) {
112
+ throw new Error("Stop at time is lower than current state");
113
+ }
94
114
  this.running = true;
95
115
  this.logger?.debug("Starting event buffer loop");
96
116
  this.eventBufferLoop()
@@ -141,6 +161,10 @@ class DataPump {
141
161
  if (!this.running) {
142
162
  return;
143
163
  }
164
+ if (this.stopAt?.eventBufferReached) {
165
+ await new Promise((resolve) => setTimeout(resolve, 10_000));
166
+ return this.eventBufferLoop();
167
+ }
144
168
  // Buffer is full, wait for some space
145
169
  if (this.buffer.length >= this.options.buffer.size - this.options.buffer.threshold && this.running) {
146
170
  this.logger?.debug("Buffer is full, waiting for some space");
@@ -162,6 +186,7 @@ class DataPump {
162
186
  timeBucket: this.state.timeBucket,
163
187
  afterEventId: this.state.eventId,
164
188
  pageSize: eventsToFetch,
189
+ toEventId: this.stopAt?.eventId,
165
190
  });
166
191
  const result = await this.options.flowcoreClient.execute(command);
167
192
  const time = Date.now() - timeStart;
@@ -184,6 +209,13 @@ class DataPump {
184
209
  this.state.eventId = result.events[result.events.length - 1]?.eventId ?? this.state.eventId;
185
210
  // If we don't have a next cursor move to next time bucket
186
211
  if (!result.nextCursor) {
212
+ // Check if we reached the stop at
213
+ if (this.state.timeBucket === this.stopAt?.timeBucket) {
214
+ this.stopAt.eventBufferReached = true;
215
+ this.logger?.debug("Reached stop at");
216
+ this.waiter?.();
217
+ return this.eventBufferLoop();
218
+ }
187
219
  // Get next time bucket
188
220
  const nextTimeBucketIndex = this.timeBuckets.indexOf(this.state.timeBucket) + 1;
189
221
  // There is no next time bucket
@@ -241,13 +273,13 @@ class DataPump {
241
273
  if (!firstEvent) {
242
274
  if (eventId) {
243
275
  const timeUuid = time_uuid_js_1.TimeUuid.fromString(eventId);
244
- return this.options.stateManager.setState({ timeBucket: timeUuid.getTimeBucket(), eventId });
276
+ return this.options.stateManager.setState?.({ timeBucket: timeUuid.getTimeBucket(), eventId });
245
277
  }
246
278
  return;
247
279
  }
248
280
  const timeUuid = time_uuid_js_1.TimeUuid.fromString(firstEvent.event.eventId);
249
281
  const timeBucket = firstEvent.event.timeBucket;
250
- return this.options.stateManager.setState({ timeBucket, eventId: timeUuid.getBefore().toString() });
282
+ return this.options.stateManager.setState?.({ timeBucket, eventId: timeUuid.getBefore().toString() });
251
283
  }
252
284
  get timeBuckets() {
253
285
  const timeBucketNow = this.getNowTimeBucket();
@@ -256,10 +288,14 @@ class DataPump {
256
288
  }
257
289
  return this._timeBuckets;
258
290
  }
259
- getClosestTimeBucket(timeBucket) {
291
+ getClosestTimeBucket(timeBucket, getBefore = false) {
260
292
  if (!timeBucket.match(/^\d{14}$/)) {
261
293
  throw new Error(`Invalid timebucket: ${timeBucket}`);
262
294
  }
295
+ if (getBefore) {
296
+ return (this.timeBuckets.findLast((t) => Number.parseFloat(t) <= Number.parseFloat(timeBucket)) ??
297
+ this.timeBuckets[this.timeBuckets.length - 1]);
298
+ }
263
299
  return (this.timeBuckets.find((t) => Number.parseFloat(t) >= Number.parseFloat(timeBucket)) ??
264
300
  this.timeBuckets[this.timeBuckets.length - 1]);
265
301
  }
@@ -286,6 +322,11 @@ class DataPump {
286
322
  if (!this.running) {
287
323
  throw new Error("Data pump not running");
288
324
  }
325
+ if (this.stopAt?.eventBufferReached && this.buffer.length === 0) {
326
+ await this.options.processor?.onDone?.();
327
+ await this.stop();
328
+ return [];
329
+ }
289
330
  const deliveryId = crypto.randomUUID();
290
331
  const events = [];
291
332
  for (const event of this.buffer) {
@@ -332,6 +373,10 @@ class DataPump {
332
373
  else {
333
374
  await this.updateState();
334
375
  }
376
+ if (!this.buffer.length && this.stopAt?.eventBufferReached) {
377
+ await this.options.processor?.onDone?.();
378
+ await this.stop();
379
+ }
335
380
  }
336
381
  async waitForNotifier() {
337
382
  this.logger?.debug("No more events, waiting for notifier...");
package/script/mod.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import "./_dnt.polyfills.js";
1
2
  export * from "./lib/data-pump.js";
2
3
  export * from "./lib/data-pump-create.js";
3
4
  export * from "./lib/time-uuid.js";
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,2BAA2B,CAAA;AAEzC,cAAc,oBAAoB,CAAA"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAC7B,cAAc,oBAAoB,CAAA;AAClC,cAAc,2BAA2B,CAAA;AAEzC,cAAc,oBAAoB,CAAA"}
package/script/mod.js CHANGED
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ require("./_dnt.polyfills.js");
17
18
  __exportStar(require("./lib/data-pump.js"), exports);
18
19
  __exportStar(require("./lib/data-pump-create.js"), exports);
19
20
  __exportStar(require("./lib/time-uuid.js"), exports);