@chkit/plugin-ingest 0.2.0-beta.8

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.
Files changed (58) hide show
  1. package/README.md +30 -0
  2. package/dist/destination.d.ts +40 -0
  3. package/dist/destination.d.ts.map +1 -0
  4. package/dist/destination.js +63 -0
  5. package/dist/destination.js.map +1 -0
  6. package/dist/errors.d.ts +33 -0
  7. package/dist/errors.d.ts.map +1 -0
  8. package/dist/errors.js +133 -0
  9. package/dist/errors.js.map +1 -0
  10. package/dist/executor.d.ts +30 -0
  11. package/dist/executor.d.ts.map +1 -0
  12. package/dist/executor.js +538 -0
  13. package/dist/executor.js.map +1 -0
  14. package/dist/incremental.d.ts +45 -0
  15. package/dist/incremental.d.ts.map +1 -0
  16. package/dist/incremental.js +72 -0
  17. package/dist/incremental.js.map +1 -0
  18. package/dist/index.d.ts +11 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +10 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/journal.d.ts +44 -0
  23. package/dist/journal.d.ts.map +1 -0
  24. package/dist/journal.js +222 -0
  25. package/dist/journal.js.map +1 -0
  26. package/dist/loader.d.ts +12 -0
  27. package/dist/loader.d.ts.map +1 -0
  28. package/dist/loader.js +37 -0
  29. package/dist/loader.js.map +1 -0
  30. package/dist/paginate.d.ts +20 -0
  31. package/dist/paginate.d.ts.map +1 -0
  32. package/dist/paginate.js +29 -0
  33. package/dist/paginate.js.map +1 -0
  34. package/dist/plugin.d.ts +110 -0
  35. package/dist/plugin.d.ts.map +1 -0
  36. package/dist/plugin.js +255 -0
  37. package/dist/plugin.js.map +1 -0
  38. package/dist/queue.d.ts +9 -0
  39. package/dist/queue.d.ts.map +1 -0
  40. package/dist/queue.js +47 -0
  41. package/dist/queue.js.map +1 -0
  42. package/dist/registry.d.ts +48 -0
  43. package/dist/registry.d.ts.map +1 -0
  44. package/dist/registry.js +109 -0
  45. package/dist/registry.js.map +1 -0
  46. package/dist/retry.d.ts +12 -0
  47. package/dist/retry.d.ts.map +1 -0
  48. package/dist/retry.js +69 -0
  49. package/dist/retry.js.map +1 -0
  50. package/dist/testing.d.ts +16 -0
  51. package/dist/testing.d.ts.map +1 -0
  52. package/dist/testing.js +46 -0
  53. package/dist/testing.js.map +1 -0
  54. package/dist/types.d.ts +221 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +2 -0
  57. package/dist/types.js.map +1 -0
  58. package/package.json +57 -0
package/dist/plugin.js ADDED
@@ -0,0 +1,255 @@
1
+ import process from 'node:process';
2
+ import { createStatelessClickHouseExecutor } from '@chkit/clickhouse';
3
+ import { createPluginRunner, defineFlags, withFactoryDefaults, } from '@chkit/core';
4
+ import { loadDefinitionModules } from '@chkit/core/schema-loader';
5
+ import { z } from 'zod';
6
+ import { BATCH_ID_COLUMN, createClickHouseDestination, INGESTED_AT_COLUMN, RUN_ID_COLUMN } from './destination.js';
7
+ import { IngestConfigError } from './errors.js';
8
+ import { runIngestion } from './executor.js';
9
+ import { createClickHouseJournal, DEFAULT_JOURNAL_TABLE } from './journal.js';
10
+ import { collectPipelines, selectStreams } from './registry.js';
11
+ const REQUIRED_COLUMNS = [BATCH_ID_COLUMN, RUN_ID_COLUMN, INGESTED_AT_COLUMN];
12
+ const IngestOptionsSchema = z.object({
13
+ journalTable: z.string().min(1).default(DEFAULT_JOURNAL_TABLE),
14
+ /** Host-default execution budget in seconds. */
15
+ maxDurationSeconds: z.number().positive().default(3600),
16
+ prefetchBatches: z.number().int().positive().default(1),
17
+ });
18
+ const SELECTION_FLAGS = defineFlags([
19
+ { name: '--tag', type: 'string[]', description: 'Exact tag every selected stream must carry (repeatable, AND)', placeholder: '<tag>' },
20
+ ]);
21
+ const RUN_FLAGS = defineFlags([
22
+ ...SELECTION_FLAGS,
23
+ { name: '--backfill', type: 'string', description: 'Stable backfill id; uses an isolated checkpoint namespace', placeholder: '<id>' },
24
+ { name: '--from', type: 'string', description: 'Backfill range lower bound (ISO timestamp)', placeholder: '<timestamp>' },
25
+ { name: '--to', type: 'string', description: 'Backfill range upper bound (ISO timestamp)', placeholder: '<timestamp>' },
26
+ { name: '--max-duration', type: 'string', description: 'Execution budget in seconds', placeholder: '<seconds>' },
27
+ ]);
28
+ const runCommand = createPluginRunner({ configErrorClass: IngestConfigError });
29
+ export function createIngestPlugin(options = {}) {
30
+ const optionsSchema = withFactoryDefaults(IngestOptionsSchema, options);
31
+ return {
32
+ manifest: { name: 'ingest', apiVersion: 1 },
33
+ optionsSchema,
34
+ commands: [
35
+ {
36
+ name: 'run',
37
+ description: 'Execute the selected ingestion streams from their journaled checkpoints',
38
+ flags: RUN_FLAGS,
39
+ optionsSchema,
40
+ run: runCommand({
41
+ command: 'run',
42
+ label: 'Ingest run',
43
+ fn: async (context) => {
44
+ const selected = await loadSelection(context);
45
+ const backfill = parseBackfill(context.flags);
46
+ const maxDurationSeconds = parseMaxDuration(context.flags['--max-duration']) ?? context.options.maxDurationSeconds;
47
+ const target = openTarget(context);
48
+ const abort = new AbortController();
49
+ const onSignal = () => abort.abort(new DOMException('Interrupted', 'AbortError'));
50
+ process.once('SIGINT', onSignal);
51
+ process.once('SIGTERM', onSignal);
52
+ try {
53
+ const result = await runIngestion({ selected, backfill }, {
54
+ journal: createClickHouseJournal({
55
+ executor: target.executor,
56
+ database: target.database,
57
+ targetId: target.targetId,
58
+ table: context.options.journalTable,
59
+ }),
60
+ destination: createClickHouseDestination(target.executor),
61
+ signal: abort.signal,
62
+ maxDurationMs: maxDurationSeconds * 1000,
63
+ prefetchBatches: context.options.prefetchBatches,
64
+ log: context.jsonMode ? undefined : (message) => context.print(message),
65
+ });
66
+ if (context.jsonMode) {
67
+ context.print({ command: 'run', ...result });
68
+ }
69
+ else {
70
+ const rows = result.streams.reduce((sum, stream) => sum + stream.rows, 0);
71
+ context.print(`Ingest run ${result.runId}: ${result.ok ? 'ok' : 'incomplete'} (${result.streams.length} streams, ${rows} rows)`);
72
+ }
73
+ return result.ok ? 0 : 1;
74
+ }
75
+ finally {
76
+ process.off('SIGINT', onSignal);
77
+ process.off('SIGTERM', onSignal);
78
+ await target.close();
79
+ }
80
+ },
81
+ }),
82
+ },
83
+ {
84
+ name: 'list',
85
+ description: 'List the ingestion streams in the loaded definition graph',
86
+ flags: SELECTION_FLAGS,
87
+ optionsSchema,
88
+ run: runCommand({
89
+ command: 'list',
90
+ label: 'Ingest list',
91
+ fn: async (context) => {
92
+ const selected = await loadSelection(context);
93
+ const streams = selected.map(describeStream);
94
+ if (context.jsonMode) {
95
+ context.print({ ok: true, command: 'list', streams });
96
+ }
97
+ else {
98
+ for (const stream of streams) {
99
+ context.print(`${stream.streamId} -> ${stream.destination} [${stream.tags.join(', ')}]`);
100
+ }
101
+ }
102
+ return 0;
103
+ },
104
+ }),
105
+ },
106
+ {
107
+ name: 'status',
108
+ description: 'Show the committed checkpoint of each selected stream',
109
+ flags: SELECTION_FLAGS,
110
+ optionsSchema,
111
+ run: runCommand({
112
+ command: 'status',
113
+ label: 'Ingest status',
114
+ fn: async (context) => {
115
+ const selected = await loadSelection(context);
116
+ const target = openTarget(context);
117
+ try {
118
+ const journal = createClickHouseJournal({
119
+ executor: target.executor,
120
+ database: target.database,
121
+ targetId: target.targetId,
122
+ table: context.options.journalTable,
123
+ });
124
+ await journal.ensure();
125
+ const streams = await Promise.all(selected.map(async (entry) => {
126
+ const checkpoint = await journal.readCheckpoint(entry.stream.id);
127
+ return { ...describeStream(entry), checkpointVersion: checkpoint.version, checkpoint: checkpoint.envelope ?? null };
128
+ }));
129
+ if (context.jsonMode) {
130
+ context.print({ ok: true, command: 'status', targetId: target.targetId, streams });
131
+ }
132
+ else {
133
+ for (const stream of streams) {
134
+ context.print(`${stream.streamId}: v${stream.checkpointVersion} ${stream.checkpoint ? JSON.stringify(stream.checkpoint.state) : '(no checkpoint)'}`);
135
+ }
136
+ }
137
+ return 0;
138
+ }
139
+ finally {
140
+ await target.close();
141
+ }
142
+ },
143
+ }),
144
+ },
145
+ ],
146
+ hooks: {
147
+ async onCheck(context) {
148
+ const findings = checkGraph(await loadGraph(context.config));
149
+ return {
150
+ plugin: 'ingest',
151
+ evaluated: true,
152
+ ok: findings.every((finding) => finding.severity !== 'error'),
153
+ findings,
154
+ };
155
+ },
156
+ },
157
+ };
158
+ }
159
+ export function ingest(options = {}) {
160
+ return { plugin: createIngestPlugin(options), name: 'ingest', enabled: true, options };
161
+ }
162
+ /** Local, zero-network graph checks: they hold in `--offline` mode too. */
163
+ export function checkGraph(pipelines) {
164
+ const findings = [];
165
+ if (pipelines.length === 0) {
166
+ findings.push({ code: 'ingest_no_pipelines', message: 'No ingestion pipeline is exported by the project entry.', severity: 'warn' });
167
+ }
168
+ for (const pipeline of pipelines) {
169
+ for (const stream of pipeline.streams) {
170
+ const columns = new Set(stream.destination.columns.map((column) => column.name));
171
+ const missing = REQUIRED_COLUMNS.filter((name) => !columns.has(name));
172
+ if (missing.length > 0) {
173
+ findings.push({
174
+ code: 'ingest_missing_metadata_columns',
175
+ message: `Stream "${stream.id}" destination ${stream.destination.database}.${stream.destination.name} is missing ${missing.join(', ')}. Spread ingestionColumns into its columns.`,
176
+ severity: 'error',
177
+ });
178
+ }
179
+ }
180
+ }
181
+ return findings;
182
+ }
183
+ // Discover values exported from the configured entry (or legacy schema files).
184
+ async function loadGraph(config) {
185
+ if (config.schema.length === 0)
186
+ return [];
187
+ return collectPipelines(await loadDefinitionModules(config.schema, { cwd: process.cwd() }));
188
+ }
189
+ async function loadSelection(context) {
190
+ const pipelines = await loadGraph(context.config);
191
+ if (pipelines.length === 0) {
192
+ throw new IngestConfigError('No ingestion pipeline is exported. Export a definePipeline(...) value from the module configured as "entry".');
193
+ }
194
+ const tags = context.flags['--tag'];
195
+ return selectStreams(pipelines, Array.isArray(tags) ? tags : typeof tags === 'string' ? [tags] : []);
196
+ }
197
+ function openTarget(context) {
198
+ const clickhouse = context.config.clickhouse;
199
+ // Ingestion requires JSONEachRow and per-insert deduplication settings.
200
+ // The host executor contract does not guarantee either capability.
201
+ // Streams fetch, load and journal concurrently, so the executor must not be
202
+ // bound to one ClickHouse HTTP session (a session allows one in-flight query).
203
+ if (clickhouse) {
204
+ const executor = createStatelessClickHouseExecutor(clickhouse);
205
+ return { executor, database: clickhouse.database, targetId: targetIdOf(clickhouse.url, clickhouse.database), close: () => executor.close() };
206
+ }
207
+ throw new IngestConfigError('Ingestion requires a direct ClickHouse connection for JSON rows and deduplication settings. Configure clickhouse in your clickhouse.config.ts; a host-provided executor is not supported.');
208
+ }
209
+ function targetIdOf(url, database) {
210
+ try {
211
+ return `${new URL(url).host}/${database}`;
212
+ }
213
+ catch {
214
+ return `${url}/${database}`;
215
+ }
216
+ }
217
+ function parseBackfill(flags) {
218
+ const id = flags['--backfill'];
219
+ const from = parseTimestamp(flags['--from'], '--from');
220
+ const to = parseTimestamp(flags['--to'], '--to');
221
+ if (typeof id !== 'string') {
222
+ if (from || to)
223
+ throw new IngestConfigError('--from and --to require --backfill <id>: explicit ranges never touch the scheduled checkpoint.');
224
+ return undefined;
225
+ }
226
+ if (!/^[A-Za-z0-9][A-Za-z0-9_.-]*$/.test(id))
227
+ throw new IngestConfigError(`Invalid --backfill id "${id}".`);
228
+ return { id, from, to };
229
+ }
230
+ function parseTimestamp(raw, flag) {
231
+ if (typeof raw !== 'string')
232
+ return undefined;
233
+ const date = new Date(raw);
234
+ if (Number.isNaN(date.getTime()))
235
+ throw new IngestConfigError(`Invalid timestamp for ${flag}: ${raw}`);
236
+ return date;
237
+ }
238
+ function parseMaxDuration(raw) {
239
+ if (typeof raw !== 'string')
240
+ return undefined;
241
+ const seconds = Number(raw);
242
+ if (!Number.isFinite(seconds) || seconds <= 0)
243
+ throw new IngestConfigError(`Invalid value for --max-duration: ${raw}`);
244
+ return seconds;
245
+ }
246
+ function describeStream(entry) {
247
+ return {
248
+ streamId: entry.stream.id,
249
+ pipelineId: entry.pipeline.id,
250
+ destination: `${entry.stream.destination.database}.${entry.stream.destination.name}`,
251
+ strategy: `${entry.stream.incremental.id}@${entry.stream.incremental.version}`,
252
+ tags: [...entry.effectiveTags],
253
+ };
254
+ }
255
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export interface BoundedQueue<T> {
2
+ /** Waits while the queue is full, which is what applies backpressure to the reader. */
3
+ push(item: T, signal: AbortSignal): Promise<void>;
4
+ /** Resolves `undefined` once the queue is closed and drained. */
5
+ pop(signal: AbortSignal): Promise<T | undefined>;
6
+ close(): void;
7
+ }
8
+ export declare function createBoundedQueue<T>(capacity: number): BoundedQueue<T>;
9
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,uFAAuF;IACvF,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACjD,iEAAiE;IACjE,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;IAChD,KAAK,IAAI,IAAI,CAAA;CACd;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,CA+CvE"}
package/dist/queue.js ADDED
@@ -0,0 +1,47 @@
1
+ export function createBoundedQueue(capacity) {
2
+ const limit = Math.max(1, capacity);
3
+ const items = [];
4
+ let closed = false;
5
+ let wake = [];
6
+ const notify = () => {
7
+ const waiting = wake;
8
+ wake = [];
9
+ for (const resolve of waiting)
10
+ resolve();
11
+ };
12
+ const wait = (signal) => new Promise((resolve, reject) => {
13
+ const onAbort = () => reject(signal.reason);
14
+ signal.addEventListener('abort', onAbort, { once: true });
15
+ wake.push(() => {
16
+ signal.removeEventListener('abort', onAbort);
17
+ resolve();
18
+ });
19
+ });
20
+ return {
21
+ async push(item, signal) {
22
+ while (items.length >= limit) {
23
+ signal.throwIfAborted();
24
+ await wait(signal);
25
+ }
26
+ signal.throwIfAborted();
27
+ items.push(item);
28
+ notify();
29
+ },
30
+ async pop(signal) {
31
+ while (items.length === 0) {
32
+ if (closed)
33
+ return undefined;
34
+ signal.throwIfAborted();
35
+ await wait(signal);
36
+ }
37
+ const item = items.shift();
38
+ notify();
39
+ return item;
40
+ },
41
+ close() {
42
+ closed = true;
43
+ notify();
44
+ },
45
+ };
46
+ }
47
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,kBAAkB,CAAI,QAAgB;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;IACnC,MAAM,KAAK,GAAQ,EAAE,CAAA;IACrB,IAAI,MAAM,GAAG,KAAK,CAAA;IAClB,IAAI,IAAI,GAAsB,EAAE,CAAA;IAEhC,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,MAAM,OAAO,GAAG,IAAI,CAAA;QACpB,IAAI,GAAG,EAAE,CAAA;QACT,KAAK,MAAM,OAAO,IAAI,OAAO;YAAE,OAAO,EAAE,CAAA;IAC1C,CAAC,CAAA;IAED,MAAM,IAAI,GAAG,CAAC,MAAmB,EAAE,EAAE,CACnC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACpC,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAC3C,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;QACzD,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;YACb,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC5C,OAAO,EAAE,CAAA;QACX,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEJ,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM;YACrB,OAAO,KAAK,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;gBAC7B,MAAM,CAAC,cAAc,EAAE,CAAA;gBACvB,MAAM,IAAI,CAAC,MAAM,CAAC,CAAA;YACpB,CAAC;YACD,MAAM,CAAC,cAAc,EAAE,CAAA;YACvB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAChB,MAAM,EAAE,CAAA;QACV,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,MAAM;YACd,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,IAAI,MAAM;oBAAE,OAAO,SAAS,CAAA;gBAC5B,MAAM,CAAC,cAAc,EAAE,CAAA;gBACvB,MAAM,IAAI,CAAC,MAAM,CAAC,CAAA;YACpB,CAAC;YACD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAE,CAAA;YAC1B,MAAM,EAAE,CAAA;YACR,OAAO,IAAI,CAAA;QACb,CAAC;QACD,KAAK;YACH,MAAM,GAAG,IAAI,CAAA;YACb,MAAM,EAAE,CAAA;QACV,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,48 @@
1
+ import type { TableDefinition } from '@chkit/core';
2
+ import type { AnyStreamDefinition, ErrorClassifier, IncrementalStrategy, LoaderFactory, PipelineDefinition, ReadContext, RetryOptions, Row, SourceChunk, StreamBudget, StreamDefinition } from './types.js';
3
+ export interface StreamInput<TRow extends Row, TState, TSelection> {
4
+ id: string;
5
+ destination: TableDefinition;
6
+ tags?: readonly string[];
7
+ incremental: IncrementalStrategy<TState, TSelection>;
8
+ read: (context: ReadContext<TSelection, TState>) => AsyncIterable<SourceChunk<TRow, TState>>;
9
+ loader?: LoaderFactory;
10
+ retry?: RetryOptions;
11
+ batchSize?: number;
12
+ budget?: StreamBudget;
13
+ classifyError?: ErrorClassifier;
14
+ }
15
+ export interface FullSyncStreamInput<TRow extends Row> extends Omit<StreamInput<TRow, undefined, undefined>, 'incremental'> {
16
+ incremental?: undefined;
17
+ }
18
+ export interface PipelineInput {
19
+ id: string;
20
+ tags?: readonly string[];
21
+ streams: readonly AnyStreamDefinition[];
22
+ maxStreams?: number;
23
+ maxFetches?: number;
24
+ maxLoads?: number;
25
+ retry?: RetryOptions;
26
+ }
27
+ export interface SelectedStream {
28
+ stream: AnyStreamDefinition;
29
+ pipeline: PipelineDefinition;
30
+ effectiveTags: readonly string[];
31
+ }
32
+ export declare function defineStream<TRow extends Row>(input: FullSyncStreamInput<TRow>): StreamDefinition<TRow, undefined, undefined>;
33
+ export declare function defineStream<TRow extends Row, TState, TSelection>(input: StreamInput<TRow, TState, TSelection>): StreamDefinition<TRow, TState, TSelection>;
34
+ /**
35
+ * Define a non-durable named group of streams. Pipeline identity never
36
+ * participates in checkpoint or batch identity, so moving a stream between
37
+ * pipelines does not reset its state.
38
+ */
39
+ export declare function definePipeline(input: PipelineInput): PipelineDefinition;
40
+ /** Only exported pipeline values participate; aliases of the same value count once. */
41
+ export declare function collectPipelines(modules: readonly Record<string, unknown>[]): PipelineDefinition[];
42
+ /**
43
+ * Repeated exact case-sensitive tags with AND semantics over the union of
44
+ * pipeline and stream tags plus derived `pipeline:<id>` and `stream:<id>`.
45
+ * No filter selects the complete graph; an explicit empty selection throws.
46
+ */
47
+ export declare function selectStreams(pipelines: readonly PipelineDefinition[], tags: readonly string[]): SelectedStream[];
48
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAIlD,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,GAAG,EACH,WAAW,EACX,YAAY,EACZ,gBAAgB,EACjB,MAAM,YAAY,CAAA;AAInB,MAAM,WAAW,WAAW,CAAC,IAAI,SAAS,GAAG,EAAE,MAAM,EAAE,UAAU;IAC/D,EAAE,EAAE,MAAM,CAAA;IACV,WAAW,EAAE,eAAe,CAAA;IAC5B,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,WAAW,EAAE,mBAAmB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IACpD,IAAI,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,KAAK,aAAa,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAA;IAC5F,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,KAAK,CAAC,EAAE,YAAY,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,aAAa,CAAC,EAAE,eAAe,CAAA;CAChC;AAED,MAAM,WAAW,mBAAmB,CAAC,IAAI,SAAS,GAAG,CACnD,SAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,aAAa,CAAC;IACpE,WAAW,CAAC,EAAE,SAAS,CAAA;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAA;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,YAAY,CAAA;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,mBAAmB,CAAA;IAC3B,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;CACjC;AAED,wBAAgB,YAAY,CAAC,IAAI,SAAS,GAAG,EAAE,KAAK,EAAE,mBAAmB,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAA;AAC9H,wBAAgB,YAAY,CAAC,IAAI,SAAS,GAAG,EAAE,MAAM,EAAE,UAAU,EAC/D,KAAK,EAAE,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,GAC3C,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,CAAA;AAuB7C;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,kBAAkB,CAsBvE;AAqBD,uFAAuF;AACvF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,kBAAkB,EAAE,CAMlG;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,SAAS,kBAAkB,EAAE,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,cAAc,EAAE,CAmBjH"}
@@ -0,0 +1,109 @@
1
+ import { IngestConfigError } from './errors.js';
2
+ import { fullSync } from './incremental.js';
3
+ const STREAM_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.:-]*$/;
4
+ export function defineStream(input) {
5
+ assertValidId('stream', input.id);
6
+ if (input.batchSize !== undefined && (!Number.isInteger(input.batchSize) || input.batchSize <= 0)) {
7
+ throw new IngestConfigError(`Stream "${input.id}": batchSize must be a positive integer.`);
8
+ }
9
+ return {
10
+ kind: 'ingest_stream',
11
+ id: input.id,
12
+ destination: input.destination,
13
+ tags: dedupe(input.tags ?? []),
14
+ incremental: input.incremental ?? fullSync(),
15
+ read: input.read,
16
+ loader: input.loader,
17
+ retry: input.retry,
18
+ batchSize: input.batchSize,
19
+ budget: input.budget,
20
+ classifyError: input.classifyError,
21
+ };
22
+ }
23
+ /**
24
+ * Define a non-durable named group of streams. Pipeline identity never
25
+ * participates in checkpoint or batch identity, so moving a stream between
26
+ * pipelines does not reset its state.
27
+ */
28
+ export function definePipeline(input) {
29
+ assertValidId('pipeline', input.id);
30
+ const pipeline = {
31
+ kind: 'ingest_pipeline',
32
+ id: input.id,
33
+ tags: dedupe(input.tags ?? []),
34
+ streams: [...input.streams],
35
+ maxStreams: positiveCeiling(input.id, 'maxStreams', input.maxStreams, 4),
36
+ maxFetches: positiveCeiling(input.id, 'maxFetches', input.maxFetches, 4),
37
+ maxLoads: positiveCeiling(input.id, 'maxLoads', input.maxLoads, 2),
38
+ retry: input.retry,
39
+ };
40
+ const seen = new Set();
41
+ for (const stream of pipeline.streams) {
42
+ if (seen.has(stream.id)) {
43
+ throw new IngestConfigError(`Pipeline "${pipeline.id}" lists stream "${stream.id}" more than once.`);
44
+ }
45
+ seen.add(stream.id);
46
+ }
47
+ return pipeline;
48
+ }
49
+ /** Validate identities within this graph, without process-wide registration. */
50
+ function validatePipelines(pipelines) {
51
+ const ids = new Set();
52
+ const owners = new Map();
53
+ for (const pipeline of pipelines) {
54
+ if (ids.has(pipeline.id))
55
+ throw new IngestConfigError(`Duplicate pipeline id "${pipeline.id}".`);
56
+ ids.add(pipeline.id);
57
+ for (const stream of pipeline.streams) {
58
+ const owner = owners.get(stream.id);
59
+ if (owner !== undefined) {
60
+ throw new IngestConfigError(`Stream id "${stream.id}" occurs in pipelines "${owner}" and "${pipeline.id}". Stream ids must be globally unique.`);
61
+ }
62
+ owners.set(stream.id, pipeline.id);
63
+ }
64
+ }
65
+ }
66
+ /** Only exported pipeline values participate; aliases of the same value count once. */
67
+ export function collectPipelines(modules) {
68
+ const pipelines = [...new Set(modules.flatMap((mod) => Object.values(mod).filter((value) => typeof value === 'object' && value !== null && 'kind' in value && value.kind === 'ingest_pipeline')))];
69
+ validatePipelines(pipelines);
70
+ return pipelines;
71
+ }
72
+ /**
73
+ * Repeated exact case-sensitive tags with AND semantics over the union of
74
+ * pipeline and stream tags plus derived `pipeline:<id>` and `stream:<id>`.
75
+ * No filter selects the complete graph; an explicit empty selection throws.
76
+ */
77
+ export function selectStreams(pipelines, tags) {
78
+ validatePipelines(pipelines);
79
+ const wanted = dedupe(tags);
80
+ const all = pipelines.flatMap((pipeline) => pipeline.streams.map((stream) => ({
81
+ stream,
82
+ pipeline,
83
+ effectiveTags: dedupe([...pipeline.tags, ...stream.tags, `pipeline:${pipeline.id}`, `stream:${stream.id}`]),
84
+ })));
85
+ if (wanted.length === 0)
86
+ return all;
87
+ const selected = all.filter((entry) => wanted.every((tag) => entry.effectiveTags.includes(tag)));
88
+ if (selected.length === 0) {
89
+ throw new IngestConfigError(`No stream matches every requested tag: ${wanted.map((tag) => `--tag ${tag}`).join(' ')}. Nothing was executed.`);
90
+ }
91
+ return selected;
92
+ }
93
+ function assertValidId(kind, id) {
94
+ if (!STREAM_ID_PATTERN.test(id)) {
95
+ throw new IngestConfigError(`Invalid ${kind} id "${id}". Use letters, digits, "_", ".", ":" or "-", starting with a letter or digit.`);
96
+ }
97
+ }
98
+ function positiveCeiling(pipelineId, name, value, fallback) {
99
+ if (value === undefined)
100
+ return fallback;
101
+ if (!Number.isInteger(value) || value <= 0) {
102
+ throw new IngestConfigError(`Pipeline "${pipelineId}": ${name} must be a positive integer.`);
103
+ }
104
+ return value;
105
+ }
106
+ function dedupe(values) {
107
+ return [...new Set(values)];
108
+ }
109
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAe3C,MAAM,iBAAiB,GAAG,+BAA+B,CAAA;AAwCzD,MAAM,UAAU,YAAY,CAC1B,KAAoE;IAEpE,aAAa,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,CAAA;IACjC,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC;QAClG,MAAM,IAAI,iBAAiB,CAAC,WAAW,KAAK,CAAC,EAAE,0CAA0C,CAAC,CAAA;IAC5F,CAAC;IACD,OAAO;QACL,IAAI,EAAE,eAAe;QACrB,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;QAC9B,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,QAAQ,EAAE;QAC5C,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,aAAa,EAAE,KAAK,CAAC,aAAa;KACnC,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAoB;IACjD,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,CAAA;IACnC,MAAM,QAAQ,GAAuB;QACnC,IAAI,EAAE,iBAAiB;QACvB,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;QAC9B,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC;QAC3B,UAAU,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;QACxE,UAAU,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;QACxE,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QAClE,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAA;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAC9B,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,iBAAiB,CAAC,aAAa,QAAQ,CAAC,EAAE,mBAAmB,MAAM,CAAC,EAAE,mBAAmB,CAAC,CAAA;QACtG,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACrB,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,gFAAgF;AAChF,SAAS,iBAAiB,CAAC,SAAwC;IACjE,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAA;IAC7B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAA;IACxC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,iBAAiB,CAAC,0BAA0B,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAA;QAChG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;QACpB,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,IAAI,iBAAiB,CACzB,cAAc,MAAM,CAAC,EAAE,0BAA0B,KAAK,UAAU,QAAQ,CAAC,EAAE,wCAAwC,CACpH,CAAA;YACH,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAA;QACpC,CAAC;IACH,CAAC;AACH,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,gBAAgB,CAAC,OAA2C;IAC1E,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAC9E,CAAC,KAAK,EAA+B,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAC3I,CAAC,CAAC,CAAC,CAAA;IACJ,iBAAiB,CAAC,SAAS,CAAC,CAAA;IAC5B,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,SAAwC,EAAE,IAAuB;IAC7F,iBAAiB,CAAC,SAAS,CAAC,CAAA;IAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;IAC3B,MAAM,GAAG,GAAqB,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC3D,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAChC,MAAM;QACN,QAAQ;QACR,aAAa,EAAE,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,IAAI,EAAE,YAAY,QAAQ,CAAC,EAAE,EAAE,EAAE,UAAU,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;KAC5G,CAAC,CAAC,CACJ,CAAA;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAA;IAEnC,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAChG,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,iBAAiB,CACzB,0CAA0C,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,yBAAyB,CACjH,CAAA;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,aAAa,CAAC,IAA2B,EAAE,EAAU;IAC5D,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,iBAAiB,CACzB,WAAW,IAAI,QAAQ,EAAE,gFAAgF,CAC1G,CAAA;IACH,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,UAAkB,EAAE,IAAY,EAAE,KAAyB,EAAE,QAAgB;IACpG,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAA;IACxC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,iBAAiB,CAAC,aAAa,UAAU,MAAM,IAAI,8BAA8B,CAAC,CAAA;IAC9F,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,MAAM,CAAC,MAAyB;IACvC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { ErrorClassifier, RetryContext, RetryOptions } from './types.js';
2
+ interface AttemptEnv {
3
+ signal: AbortSignal;
4
+ classifier: ErrorClassifier | undefined;
5
+ onRetry: (context: RetryContext, retryAfterMs: number | undefined) => Promise<void> | void;
6
+ }
7
+ /** Pipeline default, partially overridden by the stream. */
8
+ export declare function mergeRetry(...layers: Array<RetryOptions | undefined>): RetryOptions;
9
+ /** p-retry owns retry budgets and backoff; this adapter adds provider classification and Retry-After. */
10
+ export declare function runAttempt<T>(operation: (attemptNumber: number) => Promise<T>, policy: RetryOptions, env: AttemptEnv): Promise<T>;
11
+ export {};
12
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAW7E,UAAU,UAAU;IAClB,MAAM,EAAE,WAAW,CAAA;IACnB,UAAU,EAAE,eAAe,GAAG,SAAS,CAAA;IACvC,OAAO,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAC3F;AAED,4DAA4D;AAC5D,wBAAgB,UAAU,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,YAAY,GAAG,SAAS,CAAC,GAAG,YAAY,CASnF;AAED,yGAAyG;AACzG,wBAAgB,UAAU,CAAC,CAAC,EAC1B,SAAS,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAChD,MAAM,EAAE,YAAY,EACpB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,CAAC,CAAC,CAqCZ"}
package/dist/retry.js ADDED
@@ -0,0 +1,69 @@
1
+ import { setTimeout as sleep } from 'node:timers/promises';
2
+ import pRetry, { AbortError } from 'p-retry';
3
+ import { classifyFailure, FetchFailure, IngestConfigError } from './errors.js';
4
+ const DEFAULT_RETRY = {
5
+ retries: 5,
6
+ factor: 2,
7
+ minTimeout: 1000,
8
+ maxTimeout: 60_000,
9
+ randomize: true,
10
+ maxRetryTime: 10 * 60_000,
11
+ };
12
+ /** Pipeline default, partially overridden by the stream. */
13
+ export function mergeRetry(...layers) {
14
+ const merged = {};
15
+ for (const layer of layers) {
16
+ if (!layer)
17
+ continue;
18
+ for (const [key, value] of Object.entries(layer)) {
19
+ if (value !== undefined)
20
+ Object.assign(merged, { [key]: value });
21
+ }
22
+ }
23
+ return merged;
24
+ }
25
+ /** p-retry owns retry budgets and backoff; this adapter adds provider classification and Retry-After. */
26
+ export function runAttempt(operation, policy, env) {
27
+ const options = { ...DEFAULT_RETRY, ...mergeRetry(policy) };
28
+ const deadline = performance.now() + options.maxRetryTime;
29
+ let notBefore = 0;
30
+ return pRetry(async (attemptNumber) => {
31
+ // Backoff and Retry-After overlap: only wait out the remaining provider embargo.
32
+ const remaining = notBefore - performance.now();
33
+ if (remaining > 0)
34
+ await sleep(remaining, undefined, { signal: env.signal });
35
+ env.signal.throwIfAborted();
36
+ try {
37
+ return await operation(attemptNumber);
38
+ }
39
+ catch (cause) {
40
+ // A nested source attempt already exhausted its retries. Never replay it
41
+ // through the reader's coarser retry boundary.
42
+ if (cause instanceof FetchFailure || cause instanceof IngestConfigError)
43
+ throw new AbortError(cause);
44
+ const failure = new FetchFailure(cause, classifyFailure(cause, env.signal, env.classifier));
45
+ if (failure.classification.kind === 'cancelled' || failure.classification.kind === 'permanent')
46
+ throw new AbortError(failure);
47
+ throw failure;
48
+ }
49
+ }, {
50
+ ...options,
51
+ signal: env.signal,
52
+ shouldConsumeRetry: ({ error, ...context }) => error instanceof FetchFailure ? (policy.shouldConsumeRetry?.({ ...context, error }) ?? true) : true,
53
+ shouldRetry: async ({ error, ...context }) => {
54
+ env.signal.throwIfAborted();
55
+ if (!(error instanceof FetchFailure))
56
+ return false;
57
+ const retryContext = { ...context, error };
58
+ if (policy.shouldRetry && !(await policy.shouldRetry(retryContext)))
59
+ return false;
60
+ const retryAfterMs = error.classification.kind === 'rate_limited' ? error.classification.retryAfterMs : undefined;
61
+ notBefore = performance.now() + (retryAfterMs ?? 0);
62
+ if (notBefore > deadline)
63
+ return false;
64
+ await env.onRetry(retryContext, retryAfterMs);
65
+ return true;
66
+ },
67
+ });
68
+ }
69
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAE1D,OAAO,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAE5C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAG9E,MAAM,aAAa,GAAG;IACpB,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,CAAC;IACT,UAAU,EAAE,IAAI;IAChB,UAAU,EAAE,MAAM;IAClB,SAAS,EAAE,IAAI;IACf,YAAY,EAAE,EAAE,GAAG,MAAM;CAC1B,CAAA;AAQD,4DAA4D;AAC5D,MAAM,UAAU,UAAU,CAAC,GAAG,MAAuC;IACnE,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK;YAAE,SAAQ;QACpB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,IAAI,KAAK,KAAK,SAAS;gBAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;QAClE,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,UAAU,CACxB,SAAgD,EAChD,MAAoB,EACpB,GAAe;IAEf,MAAM,OAAO,GAAG,EAAE,GAAG,aAAa,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,EAAE,CAAA;IAC3D,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,YAAY,CAAA;IACzD,IAAI,SAAS,GAAG,CAAC,CAAA;IAEjB,OAAO,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE;QACpC,iFAAiF;QACjF,MAAM,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;QAC/C,IAAI,SAAS,GAAG,CAAC;YAAE,MAAM,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;QAC5E,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,CAAA;QAC3B,IAAI,CAAC;YACH,OAAO,MAAM,SAAS,CAAC,aAAa,CAAC,CAAA;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,yEAAyE;YACzE,+CAA+C;YAC/C,IAAI,KAAK,YAAY,YAAY,IAAI,KAAK,YAAY,iBAAiB;gBAAE,MAAM,IAAI,UAAU,CAAC,KAAK,CAAC,CAAA;YACpG,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,KAAK,EAAE,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAA;YAC3F,IAAI,OAAO,CAAC,cAAc,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,CAAC,cAAc,CAAC,IAAI,KAAK,WAAW;gBAAE,MAAM,IAAI,UAAU,CAAC,OAAO,CAAC,CAAA;YAC7H,MAAM,OAAO,CAAA;QACf,CAAC;IACH,CAAC,EAAE;QACD,GAAG,OAAO;QACV,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,kBAAkB,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,CAC5C,KAAK,YAAY,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;QACrG,WAAW,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE;YAC3C,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,CAAA;YAC3B,IAAI,CAAC,CAAC,KAAK,YAAY,YAAY,CAAC;gBAAE,OAAO,KAAK,CAAA;YAClD,MAAM,YAAY,GAAG,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,CAAA;YAC1C,IAAI,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAA;YACjF,MAAM,YAAY,GAAG,KAAK,CAAC,cAAc,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAA;YACjH,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,YAAY,IAAI,CAAC,CAAC,CAAA;YACnD,IAAI,SAAS,GAAG,QAAQ;gBAAE,OAAO,KAAK,CAAA;YACtC,MAAM,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;YAC7C,OAAO,IAAI,CAAA;QACb,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type JournalRow } from './journal.js';
2
+ import type { DestinationAdapter, Journal, JournalEvent, Row } from './types.js';
3
+ export interface MemoryJournal extends Journal {
4
+ readonly events: JournalEvent[];
5
+ readonly rows: JournalRow[];
6
+ }
7
+ export interface MemoryDestination extends DestinationAdapter {
8
+ /** Physical rows per `database.table`, after token deduplication. */
9
+ readonly tables: Map<string, Row[]>;
10
+ readonly tokens: string[];
11
+ }
12
+ /** In-memory journal with the same projection semantics as the ClickHouse one. */
13
+ export declare function createMemoryJournal(): MemoryJournal;
14
+ /** In-memory destination that honours `insert_deduplication_token` like ClickHouse. */
15
+ export declare function createMemoryDestination(): MemoryDestination;
16
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,UAAU,EAAE,MAAM,cAAc,CAAA;AAC7E,OAAO,KAAK,EAAuB,kBAAkB,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,YAAY,CAAA;AAErG,MAAM,WAAW,aAAc,SAAQ,OAAO;IAC5C,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,CAAA;IAC/B,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,CAAA;CAC5B;AAED,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED,kFAAkF;AAClF,wBAAgB,mBAAmB,IAAI,aAAa,CAyBnD;AAED,uFAAuF;AACvF,wBAAgB,uBAAuB,IAAI,iBAAiB,CAa3D"}