khotan-data 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +196 -0
- package/dist/chunk-42CNRMAQ.js +99 -0
- package/dist/chunk-42CNRMAQ.js.map +1 -0
- package/dist/chunk-6PDC7DFX.cjs +215 -0
- package/dist/chunk-6PDC7DFX.cjs.map +1 -0
- package/dist/chunk-6R4QVX2Q.cjs +80 -0
- package/dist/chunk-6R4QVX2Q.cjs.map +1 -0
- package/dist/chunk-FRRSW3TN.cjs +105 -0
- package/dist/chunk-FRRSW3TN.cjs.map +1 -0
- package/dist/chunk-NVPI7OV3.js +71 -0
- package/dist/chunk-NVPI7OV3.js.map +1 -0
- package/dist/chunk-TK4HD4XA.js +213 -0
- package/dist/chunk-TK4HD4XA.js.map +1 -0
- package/dist/drizzle.cjs +28 -0
- package/dist/drizzle.cjs.map +1 -0
- package/dist/drizzle.d.cts +120 -0
- package/dist/drizzle.d.ts +120 -0
- package/dist/drizzle.js +3 -0
- package/dist/drizzle.js.map +1 -0
- package/dist/index.cjs +107 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +35 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/pipeline.cjs +12 -0
- package/dist/pipeline.cjs.map +1 -0
- package/dist/pipeline.d.cts +43 -0
- package/dist/pipeline.d.ts +43 -0
- package/dist/pipeline.js +3 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/transform.cjs +40 -0
- package/dist/transform.cjs.map +1 -0
- package/dist/transform.d.cts +38 -0
- package/dist/transform.d.ts +38 -0
- package/dist/transform.js +3 -0
- package/dist/transform.js.map +1 -0
- package/dist/types-EpLTQcN2.d.cts +54 -0
- package/dist/types-EpLTQcN2.d.ts +54 -0
- package/package.json +110 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { D as DataRecord, E as Extractor, b as Loader } from './types-EpLTQcN2.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create an extractor from any Drizzle select query.
|
|
5
|
+
*
|
|
6
|
+
* Pass a function that returns the query — this makes the extractor
|
|
7
|
+
* re-runnable and avoids consuming a one-shot promise.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { fromQuery } from "khotan-data/drizzle";
|
|
12
|
+
* import { db } from "@/db";
|
|
13
|
+
* import { users } from "@/db/schema";
|
|
14
|
+
* import { eq } from "drizzle-orm";
|
|
15
|
+
*
|
|
16
|
+
* const extractor = fromQuery("active-users", () =>
|
|
17
|
+
* db.select().from(users).where(eq(users.active, true))
|
|
18
|
+
* );
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
declare function fromQuery<T extends DataRecord>(name: string, queryFn: () => PromiseLike<T[]>): Extractor<T>;
|
|
22
|
+
/**
|
|
23
|
+
* Create an extractor from a Drizzle query that streams results in
|
|
24
|
+
* chunks. Use this for large tables where materializing all rows
|
|
25
|
+
* at once is too expensive.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* const extractor = fromQueryCursor("all-events", async function* () {
|
|
30
|
+
* let offset = 0;
|
|
31
|
+
* const limit = 5000;
|
|
32
|
+
* while (true) {
|
|
33
|
+
* const batch = await db.select().from(events).limit(limit).offset(offset);
|
|
34
|
+
* if (batch.length === 0) break;
|
|
35
|
+
* yield* batch;
|
|
36
|
+
* offset += limit;
|
|
37
|
+
* }
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
declare function fromQueryCursor<T extends DataRecord>(name: string, generatorFn: () => AsyncIterable<T>): Extractor<T>;
|
|
42
|
+
/**
|
|
43
|
+
* Create an extractor from a paginated Drizzle query. Automatically
|
|
44
|
+
* handles offset-based pagination so you don't have to write the loop.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const extractor = fromQueryPaginated("all-users", {
|
|
49
|
+
* pageSize: 2000,
|
|
50
|
+
* query: (limit, offset) => db.select().from(users).limit(limit).offset(offset),
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
declare function fromQueryPaginated<T extends DataRecord>(name: string, opts: {
|
|
55
|
+
query: (limit: number, offset: number) => PromiseLike<T[]>;
|
|
56
|
+
pageSize?: number;
|
|
57
|
+
}): Extractor<T>;
|
|
58
|
+
|
|
59
|
+
interface ToDrizzleOptions {
|
|
60
|
+
/**
|
|
61
|
+
* Max records per INSERT statement. When a batch exceeds this,
|
|
62
|
+
* it's automatically split into sub-batches to stay within Postgres
|
|
63
|
+
* parameter limits. Defaults to auto-calculated from columnsPerRow.
|
|
64
|
+
*/
|
|
65
|
+
maxRowsPerStatement?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Number of columns per row. Used to auto-calculate maxRowsPerStatement
|
|
68
|
+
* to stay under Postgres' 65535 parameter limit.
|
|
69
|
+
* If not provided, falls back to maxRowsPerStatement or 1000.
|
|
70
|
+
*/
|
|
71
|
+
columnsPerRow?: number;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Create a loader that writes records using a Drizzle insert/upsert.
|
|
75
|
+
*
|
|
76
|
+
* You provide the write function — this keeps the loader decoupled from
|
|
77
|
+
* specific Drizzle driver types while giving you full control over
|
|
78
|
+
* insert/upsert/conflict behavior.
|
|
79
|
+
*
|
|
80
|
+
* Automatically sub-batches to stay within Postgres' 65535 parameter limit.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* import { toDrizzle } from "khotan-data/drizzle";
|
|
85
|
+
* import { db } from "@/db";
|
|
86
|
+
* import { processedUsers } from "@/db/schema";
|
|
87
|
+
*
|
|
88
|
+
* // Simple insert
|
|
89
|
+
* const loader = toDrizzle("insert-users", (rows) =>
|
|
90
|
+
* db.insert(processedUsers).values(rows)
|
|
91
|
+
* );
|
|
92
|
+
*
|
|
93
|
+
* // Upsert
|
|
94
|
+
* const loader = toDrizzle("upsert-users", (rows) =>
|
|
95
|
+
* db.insert(processedUsers).values(rows).onConflictDoUpdate({
|
|
96
|
+
* target: processedUsers.id,
|
|
97
|
+
* set: { name: sql`excluded.name`, updatedAt: new Date() },
|
|
98
|
+
* })
|
|
99
|
+
* );
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
declare function toDrizzle<T extends DataRecord>(name: string, writeFn: (records: T[]) => PromiseLike<unknown>, options?: ToDrizzleOptions): Loader<T>;
|
|
103
|
+
/**
|
|
104
|
+
* Create a loader that writes records inside a Drizzle transaction.
|
|
105
|
+
*
|
|
106
|
+
* All sub-batches for a single load call are wrapped in a single
|
|
107
|
+
* transaction — if any batch fails, the entire load is rolled back.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* const loader = toDrizzleTx("tx-insert", db, (tx, rows) =>
|
|
112
|
+
* tx.insert(processedUsers).values(rows)
|
|
113
|
+
* );
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
declare function toDrizzleTx<T extends DataRecord>(name: string, db: {
|
|
117
|
+
transaction: <R>(fn: (tx: never) => Promise<R>) => Promise<R>;
|
|
118
|
+
}, writeFn: (tx: never, records: T[]) => PromiseLike<unknown>, options?: ToDrizzleOptions): Loader<T>;
|
|
119
|
+
|
|
120
|
+
export { fromQuery, fromQueryCursor, fromQueryPaginated, toDrizzle, toDrizzleTx };
|
package/dist/drizzle.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"drizzle.js"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk6PDC7DFX_cjs = require('./chunk-6PDC7DFX.cjs');
|
|
4
|
+
var chunk6R4QVX2Q_cjs = require('./chunk-6R4QVX2Q.cjs');
|
|
5
|
+
var chunkFRRSW3TN_cjs = require('./chunk-FRRSW3TN.cjs');
|
|
6
|
+
|
|
7
|
+
// src/extractors.ts
|
|
8
|
+
function createExtractor(name, fn) {
|
|
9
|
+
return {
|
|
10
|
+
name,
|
|
11
|
+
extract: fn
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function fromArray(name, data) {
|
|
15
|
+
return createExtractor(name, async function* () {
|
|
16
|
+
for (const record of data) {
|
|
17
|
+
yield record;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function fromIterable(name, iterable) {
|
|
22
|
+
return createExtractor(name, () => iterable);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/loaders.ts
|
|
26
|
+
function createLoader(name, fn) {
|
|
27
|
+
return { name, load: fn };
|
|
28
|
+
}
|
|
29
|
+
function toArray(name, target) {
|
|
30
|
+
return createLoader(name, async (records) => {
|
|
31
|
+
target.push(...records);
|
|
32
|
+
return { recordsLoaded: records.length, errors: [] };
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function toConsole(name) {
|
|
36
|
+
return createLoader(name, async (records) => {
|
|
37
|
+
for (const record of records) {
|
|
38
|
+
console.log(JSON.stringify(record));
|
|
39
|
+
}
|
|
40
|
+
return { recordsLoaded: records.length, errors: [] };
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
Object.defineProperty(exports, "Pipeline", {
|
|
45
|
+
enumerable: true,
|
|
46
|
+
get: function () { return chunk6PDC7DFX_cjs.Pipeline; }
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(exports, "compose", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () { return chunk6R4QVX2Q_cjs.compose; }
|
|
51
|
+
});
|
|
52
|
+
Object.defineProperty(exports, "createTransformer", {
|
|
53
|
+
enumerable: true,
|
|
54
|
+
get: function () { return chunk6R4QVX2Q_cjs.createTransformer; }
|
|
55
|
+
});
|
|
56
|
+
Object.defineProperty(exports, "filter", {
|
|
57
|
+
enumerable: true,
|
|
58
|
+
get: function () { return chunk6R4QVX2Q_cjs.filter; }
|
|
59
|
+
});
|
|
60
|
+
Object.defineProperty(exports, "flatMap", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () { return chunk6R4QVX2Q_cjs.flatMap; }
|
|
63
|
+
});
|
|
64
|
+
Object.defineProperty(exports, "map", {
|
|
65
|
+
enumerable: true,
|
|
66
|
+
get: function () { return chunk6R4QVX2Q_cjs.map; }
|
|
67
|
+
});
|
|
68
|
+
Object.defineProperty(exports, "omit", {
|
|
69
|
+
enumerable: true,
|
|
70
|
+
get: function () { return chunk6R4QVX2Q_cjs.omit; }
|
|
71
|
+
});
|
|
72
|
+
Object.defineProperty(exports, "pick", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: function () { return chunk6R4QVX2Q_cjs.pick; }
|
|
75
|
+
});
|
|
76
|
+
Object.defineProperty(exports, "rename", {
|
|
77
|
+
enumerable: true,
|
|
78
|
+
get: function () { return chunk6R4QVX2Q_cjs.rename; }
|
|
79
|
+
});
|
|
80
|
+
Object.defineProperty(exports, "fromQuery", {
|
|
81
|
+
enumerable: true,
|
|
82
|
+
get: function () { return chunkFRRSW3TN_cjs.fromQuery; }
|
|
83
|
+
});
|
|
84
|
+
Object.defineProperty(exports, "fromQueryCursor", {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
get: function () { return chunkFRRSW3TN_cjs.fromQueryCursor; }
|
|
87
|
+
});
|
|
88
|
+
Object.defineProperty(exports, "fromQueryPaginated", {
|
|
89
|
+
enumerable: true,
|
|
90
|
+
get: function () { return chunkFRRSW3TN_cjs.fromQueryPaginated; }
|
|
91
|
+
});
|
|
92
|
+
Object.defineProperty(exports, "toDrizzle", {
|
|
93
|
+
enumerable: true,
|
|
94
|
+
get: function () { return chunkFRRSW3TN_cjs.toDrizzle; }
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(exports, "toDrizzleTx", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
get: function () { return chunkFRRSW3TN_cjs.toDrizzleTx; }
|
|
99
|
+
});
|
|
100
|
+
exports.createExtractor = createExtractor;
|
|
101
|
+
exports.createLoader = createLoader;
|
|
102
|
+
exports.fromArray = fromArray;
|
|
103
|
+
exports.fromIterable = fromIterable;
|
|
104
|
+
exports.toArray = toArray;
|
|
105
|
+
exports.toConsole = toConsole;
|
|
106
|
+
//# sourceMappingURL=index.cjs.map
|
|
107
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/extractors.ts","../src/loaders.ts"],"names":[],"mappings":";;;;;;;AAKO,SAAS,eAAA,CACd,MACA,EAAA,EACc;AACd,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,OAAA,EAAS;AAAA,GACX;AACF;AAMO,SAAS,SAAA,CACd,MACA,IAAA,EACc;AACd,EAAA,OAAO,eAAA,CAAgB,MAAM,mBAAmB;AAC9C,IAAA,KAAA,MAAW,UAAU,IAAA,EAAM;AACzB,MAAA,MAAM,MAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA;AACH;AAKO,SAAS,YAAA,CACd,MACA,QAAA,EACc;AACd,EAAA,OAAO,eAAA,CAAgB,IAAA,EAAM,MAAM,QAAQ,CAAA;AAC7C;;;ACjCO,SAAS,YAAA,CACd,MACA,EAAA,EACW;AACX,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,EAAA,EAAG;AAC1B;AAMO,SAAS,OAAA,CACd,MACA,MAAA,EACW;AACX,EAAA,OAAO,YAAA,CAAa,IAAA,EAAM,OAAO,OAAA,KAAY;AAC3C,IAAA,MAAA,CAAO,IAAA,CAAK,GAAG,OAAO,CAAA;AACtB,IAAA,OAAO,EAAE,aAAA,EAAe,OAAA,CAAQ,MAAA,EAAQ,MAAA,EAAQ,EAAC,EAAE;AAAA,EACrD,CAAC,CAAA;AACH;AAKO,SAAS,UAAgC,IAAA,EAAyB;AACvE,EAAA,OAAO,YAAA,CAAa,IAAA,EAAM,OAAO,OAAA,KAAY;AAC3C,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,MAAM,CAAC,CAAA;AAAA,IACpC;AACA,IAAA,OAAO,EAAE,aAAA,EAAe,OAAA,CAAQ,MAAA,EAAQ,MAAA,EAAQ,EAAC,EAAE;AAAA,EACrD,CAAC,CAAA;AACH","file":"index.cjs","sourcesContent":["import type { DataRecord, Extractor } from \"./types.js\";\n\n/**\n * Create a custom extractor from an async generator function.\n */\nexport function createExtractor<T extends DataRecord>(\n name: string,\n fn: () => AsyncIterable<T>,\n): Extractor<T> {\n return {\n name,\n extract: fn,\n };\n}\n\n/**\n * Create an extractor from an in-memory array. Useful for testing\n * and for small datasets that are already loaded.\n */\nexport function fromArray<T extends DataRecord>(\n name: string,\n data: T[],\n): Extractor<T> {\n return createExtractor(name, async function* () {\n for (const record of data) {\n yield record;\n }\n });\n}\n\n/**\n * Create an extractor from any async iterable source.\n */\nexport function fromIterable<T extends DataRecord>(\n name: string,\n iterable: AsyncIterable<T>,\n): Extractor<T> {\n return createExtractor(name, () => iterable);\n}\n","import type { DataRecord, Loader, LoadResult } from \"./types.js\";\n\n/**\n * Create a custom loader from a function.\n */\nexport function createLoader<T extends DataRecord>(\n name: string,\n fn: (records: T[]) => Promise<LoadResult>,\n): Loader<T> {\n return { name, load: fn };\n}\n\n/**\n * Load records into an in-memory array. Useful for testing\n * and collecting pipeline output.\n */\nexport function toArray<T extends DataRecord>(\n name: string,\n target: T[],\n): Loader<T> {\n return createLoader(name, async (records) => {\n target.push(...records);\n return { recordsLoaded: records.length, errors: [] };\n });\n}\n\n/**\n * Load records by logging them to the console. Useful for debugging.\n */\nexport function toConsole<T extends DataRecord>(name: string): Loader<T> {\n return createLoader(name, async (records) => {\n for (const record of records) {\n console.log(JSON.stringify(record));\n }\n return { recordsLoaded: records.length, errors: [] };\n });\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { D as DataRecord, E as Extractor, a as LoadResult, b as Loader } from './types-EpLTQcN2.cjs';
|
|
2
|
+
export { L as LoadError, P as PipelineEvent, c as PipelineEventListener, d as PipelineOptions, e as PipelineResult, f as PipelineStepError, T as Transformer } from './types-EpLTQcN2.cjs';
|
|
3
|
+
export { Pipeline } from './pipeline.cjs';
|
|
4
|
+
export { compose, createTransformer, filter, flatMap, map, omit, pick, rename } from './transform.cjs';
|
|
5
|
+
export { fromQuery, fromQueryCursor, fromQueryPaginated, toDrizzle, toDrizzleTx } from './drizzle.cjs';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Create a custom extractor from an async generator function.
|
|
9
|
+
*/
|
|
10
|
+
declare function createExtractor<T extends DataRecord>(name: string, fn: () => AsyncIterable<T>): Extractor<T>;
|
|
11
|
+
/**
|
|
12
|
+
* Create an extractor from an in-memory array. Useful for testing
|
|
13
|
+
* and for small datasets that are already loaded.
|
|
14
|
+
*/
|
|
15
|
+
declare function fromArray<T extends DataRecord>(name: string, data: T[]): Extractor<T>;
|
|
16
|
+
/**
|
|
17
|
+
* Create an extractor from any async iterable source.
|
|
18
|
+
*/
|
|
19
|
+
declare function fromIterable<T extends DataRecord>(name: string, iterable: AsyncIterable<T>): Extractor<T>;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Create a custom loader from a function.
|
|
23
|
+
*/
|
|
24
|
+
declare function createLoader<T extends DataRecord>(name: string, fn: (records: T[]) => Promise<LoadResult>): Loader<T>;
|
|
25
|
+
/**
|
|
26
|
+
* Load records into an in-memory array. Useful for testing
|
|
27
|
+
* and collecting pipeline output.
|
|
28
|
+
*/
|
|
29
|
+
declare function toArray<T extends DataRecord>(name: string, target: T[]): Loader<T>;
|
|
30
|
+
/**
|
|
31
|
+
* Load records by logging them to the console. Useful for debugging.
|
|
32
|
+
*/
|
|
33
|
+
declare function toConsole<T extends DataRecord>(name: string): Loader<T>;
|
|
34
|
+
|
|
35
|
+
export { DataRecord, Extractor, LoadResult, Loader, createExtractor, createLoader, fromArray, fromIterable, toArray, toConsole };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { D as DataRecord, E as Extractor, a as LoadResult, b as Loader } from './types-EpLTQcN2.js';
|
|
2
|
+
export { L as LoadError, P as PipelineEvent, c as PipelineEventListener, d as PipelineOptions, e as PipelineResult, f as PipelineStepError, T as Transformer } from './types-EpLTQcN2.js';
|
|
3
|
+
export { Pipeline } from './pipeline.js';
|
|
4
|
+
export { compose, createTransformer, filter, flatMap, map, omit, pick, rename } from './transform.js';
|
|
5
|
+
export { fromQuery, fromQueryCursor, fromQueryPaginated, toDrizzle, toDrizzleTx } from './drizzle.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Create a custom extractor from an async generator function.
|
|
9
|
+
*/
|
|
10
|
+
declare function createExtractor<T extends DataRecord>(name: string, fn: () => AsyncIterable<T>): Extractor<T>;
|
|
11
|
+
/**
|
|
12
|
+
* Create an extractor from an in-memory array. Useful for testing
|
|
13
|
+
* and for small datasets that are already loaded.
|
|
14
|
+
*/
|
|
15
|
+
declare function fromArray<T extends DataRecord>(name: string, data: T[]): Extractor<T>;
|
|
16
|
+
/**
|
|
17
|
+
* Create an extractor from any async iterable source.
|
|
18
|
+
*/
|
|
19
|
+
declare function fromIterable<T extends DataRecord>(name: string, iterable: AsyncIterable<T>): Extractor<T>;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Create a custom loader from a function.
|
|
23
|
+
*/
|
|
24
|
+
declare function createLoader<T extends DataRecord>(name: string, fn: (records: T[]) => Promise<LoadResult>): Loader<T>;
|
|
25
|
+
/**
|
|
26
|
+
* Load records into an in-memory array. Useful for testing
|
|
27
|
+
* and collecting pipeline output.
|
|
28
|
+
*/
|
|
29
|
+
declare function toArray<T extends DataRecord>(name: string, target: T[]): Loader<T>;
|
|
30
|
+
/**
|
|
31
|
+
* Load records by logging them to the console. Useful for debugging.
|
|
32
|
+
*/
|
|
33
|
+
declare function toConsole<T extends DataRecord>(name: string): Loader<T>;
|
|
34
|
+
|
|
35
|
+
export { DataRecord, Extractor, LoadResult, Loader, createExtractor, createLoader, fromArray, fromIterable, toArray, toConsole };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export { Pipeline } from './chunk-TK4HD4XA.js';
|
|
2
|
+
export { compose, createTransformer, filter, flatMap, map, omit, pick, rename } from './chunk-NVPI7OV3.js';
|
|
3
|
+
export { fromQuery, fromQueryCursor, fromQueryPaginated, toDrizzle, toDrizzleTx } from './chunk-42CNRMAQ.js';
|
|
4
|
+
|
|
5
|
+
// src/extractors.ts
|
|
6
|
+
function createExtractor(name, fn) {
|
|
7
|
+
return {
|
|
8
|
+
name,
|
|
9
|
+
extract: fn
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function fromArray(name, data) {
|
|
13
|
+
return createExtractor(name, async function* () {
|
|
14
|
+
for (const record of data) {
|
|
15
|
+
yield record;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function fromIterable(name, iterable) {
|
|
20
|
+
return createExtractor(name, () => iterable);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/loaders.ts
|
|
24
|
+
function createLoader(name, fn) {
|
|
25
|
+
return { name, load: fn };
|
|
26
|
+
}
|
|
27
|
+
function toArray(name, target) {
|
|
28
|
+
return createLoader(name, async (records) => {
|
|
29
|
+
target.push(...records);
|
|
30
|
+
return { recordsLoaded: records.length, errors: [] };
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function toConsole(name) {
|
|
34
|
+
return createLoader(name, async (records) => {
|
|
35
|
+
for (const record of records) {
|
|
36
|
+
console.log(JSON.stringify(record));
|
|
37
|
+
}
|
|
38
|
+
return { recordsLoaded: records.length, errors: [] };
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { createExtractor, createLoader, fromArray, fromIterable, toArray, toConsole };
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
44
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/extractors.ts","../src/loaders.ts"],"names":[],"mappings":";;;;;AAKO,SAAS,eAAA,CACd,MACA,EAAA,EACc;AACd,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,OAAA,EAAS;AAAA,GACX;AACF;AAMO,SAAS,SAAA,CACd,MACA,IAAA,EACc;AACd,EAAA,OAAO,eAAA,CAAgB,MAAM,mBAAmB;AAC9C,IAAA,KAAA,MAAW,UAAU,IAAA,EAAM;AACzB,MAAA,MAAM,MAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA;AACH;AAKO,SAAS,YAAA,CACd,MACA,QAAA,EACc;AACd,EAAA,OAAO,eAAA,CAAgB,IAAA,EAAM,MAAM,QAAQ,CAAA;AAC7C;;;ACjCO,SAAS,YAAA,CACd,MACA,EAAA,EACW;AACX,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,EAAA,EAAG;AAC1B;AAMO,SAAS,OAAA,CACd,MACA,MAAA,EACW;AACX,EAAA,OAAO,YAAA,CAAa,IAAA,EAAM,OAAO,OAAA,KAAY;AAC3C,IAAA,MAAA,CAAO,IAAA,CAAK,GAAG,OAAO,CAAA;AACtB,IAAA,OAAO,EAAE,aAAA,EAAe,OAAA,CAAQ,MAAA,EAAQ,MAAA,EAAQ,EAAC,EAAE;AAAA,EACrD,CAAC,CAAA;AACH;AAKO,SAAS,UAAgC,IAAA,EAAyB;AACvE,EAAA,OAAO,YAAA,CAAa,IAAA,EAAM,OAAO,OAAA,KAAY;AAC3C,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,MAAM,CAAC,CAAA;AAAA,IACpC;AACA,IAAA,OAAO,EAAE,aAAA,EAAe,OAAA,CAAQ,MAAA,EAAQ,MAAA,EAAQ,EAAC,EAAE;AAAA,EACrD,CAAC,CAAA;AACH","file":"index.js","sourcesContent":["import type { DataRecord, Extractor } from \"./types.js\";\n\n/**\n * Create a custom extractor from an async generator function.\n */\nexport function createExtractor<T extends DataRecord>(\n name: string,\n fn: () => AsyncIterable<T>,\n): Extractor<T> {\n return {\n name,\n extract: fn,\n };\n}\n\n/**\n * Create an extractor from an in-memory array. Useful for testing\n * and for small datasets that are already loaded.\n */\nexport function fromArray<T extends DataRecord>(\n name: string,\n data: T[],\n): Extractor<T> {\n return createExtractor(name, async function* () {\n for (const record of data) {\n yield record;\n }\n });\n}\n\n/**\n * Create an extractor from any async iterable source.\n */\nexport function fromIterable<T extends DataRecord>(\n name: string,\n iterable: AsyncIterable<T>,\n): Extractor<T> {\n return createExtractor(name, () => iterable);\n}\n","import type { DataRecord, Loader, LoadResult } from \"./types.js\";\n\n/**\n * Create a custom loader from a function.\n */\nexport function createLoader<T extends DataRecord>(\n name: string,\n fn: (records: T[]) => Promise<LoadResult>,\n): Loader<T> {\n return { name, load: fn };\n}\n\n/**\n * Load records into an in-memory array. Useful for testing\n * and collecting pipeline output.\n */\nexport function toArray<T extends DataRecord>(\n name: string,\n target: T[],\n): Loader<T> {\n return createLoader(name, async (records) => {\n target.push(...records);\n return { recordsLoaded: records.length, errors: [] };\n });\n}\n\n/**\n * Load records by logging them to the console. Useful for debugging.\n */\nexport function toConsole<T extends DataRecord>(name: string): Loader<T> {\n return createLoader(name, async (records) => {\n for (const record of records) {\n console.log(JSON.stringify(record));\n }\n return { recordsLoaded: records.length, errors: [] };\n });\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk6PDC7DFX_cjs = require('./chunk-6PDC7DFX.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "Pipeline", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () { return chunk6PDC7DFX_cjs.Pipeline; }
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=pipeline.cjs.map
|
|
12
|
+
//# sourceMappingURL=pipeline.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"pipeline.cjs"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { D as DataRecord, E as Extractor, T as Transformer, b as Loader, c as PipelineEventListener, d as PipelineOptions, e as PipelineResult } from './types-EpLTQcN2.cjs';
|
|
2
|
+
export { P as PipelineEvent, f as PipelineStepError } from './types-EpLTQcN2.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A composable, type-safe ETL pipeline builder.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const result = await Pipeline.create("my-pipeline")
|
|
10
|
+
* .extract(myExtractor)
|
|
11
|
+
* .transform(myTransformer)
|
|
12
|
+
* .load(myLoader)
|
|
13
|
+
* .run();
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
declare class Pipeline<TCurrent extends DataRecord = DataRecord> {
|
|
17
|
+
#private;
|
|
18
|
+
private constructor();
|
|
19
|
+
static create(name: string): Pipeline;
|
|
20
|
+
get name(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Set the data source for this pipeline.
|
|
23
|
+
*/
|
|
24
|
+
extract<T extends DataRecord>(extractor: Extractor<T>): Pipeline<T>;
|
|
25
|
+
/**
|
|
26
|
+
* Add a transformation step.
|
|
27
|
+
*/
|
|
28
|
+
transform<TOutput extends DataRecord>(transformer: Transformer<TCurrent, TOutput>): Pipeline<TOutput>;
|
|
29
|
+
/**
|
|
30
|
+
* Add a load destination.
|
|
31
|
+
*/
|
|
32
|
+
load(loader: Loader<TCurrent>): Pipeline<TCurrent>;
|
|
33
|
+
/**
|
|
34
|
+
* Subscribe to pipeline events.
|
|
35
|
+
*/
|
|
36
|
+
on(listener: PipelineEventListener): Pipeline<TCurrent>;
|
|
37
|
+
/**
|
|
38
|
+
* Execute the pipeline.
|
|
39
|
+
*/
|
|
40
|
+
run(options?: PipelineOptions): Promise<PipelineResult>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { Pipeline, PipelineEventListener, PipelineOptions, PipelineResult };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { D as DataRecord, E as Extractor, T as Transformer, b as Loader, c as PipelineEventListener, d as PipelineOptions, e as PipelineResult } from './types-EpLTQcN2.js';
|
|
2
|
+
export { P as PipelineEvent, f as PipelineStepError } from './types-EpLTQcN2.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A composable, type-safe ETL pipeline builder.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const result = await Pipeline.create("my-pipeline")
|
|
10
|
+
* .extract(myExtractor)
|
|
11
|
+
* .transform(myTransformer)
|
|
12
|
+
* .load(myLoader)
|
|
13
|
+
* .run();
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
declare class Pipeline<TCurrent extends DataRecord = DataRecord> {
|
|
17
|
+
#private;
|
|
18
|
+
private constructor();
|
|
19
|
+
static create(name: string): Pipeline;
|
|
20
|
+
get name(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Set the data source for this pipeline.
|
|
23
|
+
*/
|
|
24
|
+
extract<T extends DataRecord>(extractor: Extractor<T>): Pipeline<T>;
|
|
25
|
+
/**
|
|
26
|
+
* Add a transformation step.
|
|
27
|
+
*/
|
|
28
|
+
transform<TOutput extends DataRecord>(transformer: Transformer<TCurrent, TOutput>): Pipeline<TOutput>;
|
|
29
|
+
/**
|
|
30
|
+
* Add a load destination.
|
|
31
|
+
*/
|
|
32
|
+
load(loader: Loader<TCurrent>): Pipeline<TCurrent>;
|
|
33
|
+
/**
|
|
34
|
+
* Subscribe to pipeline events.
|
|
35
|
+
*/
|
|
36
|
+
on(listener: PipelineEventListener): Pipeline<TCurrent>;
|
|
37
|
+
/**
|
|
38
|
+
* Execute the pipeline.
|
|
39
|
+
*/
|
|
40
|
+
run(options?: PipelineOptions): Promise<PipelineResult>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { Pipeline, PipelineEventListener, PipelineOptions, PipelineResult };
|
package/dist/pipeline.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"pipeline.js"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk6R4QVX2Q_cjs = require('./chunk-6R4QVX2Q.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "compose", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () { return chunk6R4QVX2Q_cjs.compose; }
|
|
10
|
+
});
|
|
11
|
+
Object.defineProperty(exports, "createTransformer", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: function () { return chunk6R4QVX2Q_cjs.createTransformer; }
|
|
14
|
+
});
|
|
15
|
+
Object.defineProperty(exports, "filter", {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () { return chunk6R4QVX2Q_cjs.filter; }
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports, "flatMap", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return chunk6R4QVX2Q_cjs.flatMap; }
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports, "map", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function () { return chunk6R4QVX2Q_cjs.map; }
|
|
26
|
+
});
|
|
27
|
+
Object.defineProperty(exports, "omit", {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
get: function () { return chunk6R4QVX2Q_cjs.omit; }
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(exports, "pick", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get: function () { return chunk6R4QVX2Q_cjs.pick; }
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(exports, "rename", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
get: function () { return chunk6R4QVX2Q_cjs.rename; }
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=transform.cjs.map
|
|
40
|
+
//# sourceMappingURL=transform.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"transform.cjs"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { D as DataRecord, T as Transformer } from './types-EpLTQcN2.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create a custom transformer from a function.
|
|
5
|
+
*/
|
|
6
|
+
declare function createTransformer<TInput extends DataRecord = DataRecord, TOutput extends DataRecord = DataRecord>(name: string, fn: (record: TInput) => TOutput | TOutput[] | Promise<TOutput | TOutput[]>): Transformer<TInput, TOutput>;
|
|
7
|
+
/**
|
|
8
|
+
* Transform each record using a mapping function.
|
|
9
|
+
*/
|
|
10
|
+
declare function map<TInput extends DataRecord = DataRecord, TOutput extends DataRecord = DataRecord>(name: string, fn: (record: TInput) => TOutput | Promise<TOutput>): Transformer<TInput, TOutput>;
|
|
11
|
+
/**
|
|
12
|
+
* Filter records based on a predicate. Records that don't match
|
|
13
|
+
* are dropped (returned as empty array).
|
|
14
|
+
*/
|
|
15
|
+
declare function filter<T extends DataRecord = DataRecord>(name: string, predicate: (record: T) => boolean | Promise<boolean>): Transformer<T, T>;
|
|
16
|
+
/**
|
|
17
|
+
* Transform each record into zero or more records.
|
|
18
|
+
*/
|
|
19
|
+
declare function flatMap<TInput extends DataRecord = DataRecord, TOutput extends DataRecord = DataRecord>(name: string, fn: (record: TInput) => TOutput[] | Promise<TOutput[]>): Transformer<TInput, TOutput>;
|
|
20
|
+
/**
|
|
21
|
+
* Pick specific keys from each record.
|
|
22
|
+
*/
|
|
23
|
+
declare function pick<T extends DataRecord, K extends keyof T & string>(name: string, keys: K[]): Transformer<T, Pick<T, K> & DataRecord>;
|
|
24
|
+
/**
|
|
25
|
+
* Omit specific keys from each record.
|
|
26
|
+
*/
|
|
27
|
+
declare function omit<T extends DataRecord, K extends keyof T & string>(name: string, keys: K[]): Transformer<T, Omit<T, K> & DataRecord>;
|
|
28
|
+
/**
|
|
29
|
+
* Rename keys in each record.
|
|
30
|
+
*/
|
|
31
|
+
declare function rename<T extends DataRecord>(name: string, mapping: Record<string, string>): Transformer<T>;
|
|
32
|
+
/**
|
|
33
|
+
* Compose multiple transformers into a single transformer that
|
|
34
|
+
* applies them in sequence.
|
|
35
|
+
*/
|
|
36
|
+
declare function compose<T extends DataRecord>(name: string, transformers: Transformer[]): Transformer<T>;
|
|
37
|
+
|
|
38
|
+
export { Transformer, compose, createTransformer, filter, flatMap, map, omit, pick, rename };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { D as DataRecord, T as Transformer } from './types-EpLTQcN2.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create a custom transformer from a function.
|
|
5
|
+
*/
|
|
6
|
+
declare function createTransformer<TInput extends DataRecord = DataRecord, TOutput extends DataRecord = DataRecord>(name: string, fn: (record: TInput) => TOutput | TOutput[] | Promise<TOutput | TOutput[]>): Transformer<TInput, TOutput>;
|
|
7
|
+
/**
|
|
8
|
+
* Transform each record using a mapping function.
|
|
9
|
+
*/
|
|
10
|
+
declare function map<TInput extends DataRecord = DataRecord, TOutput extends DataRecord = DataRecord>(name: string, fn: (record: TInput) => TOutput | Promise<TOutput>): Transformer<TInput, TOutput>;
|
|
11
|
+
/**
|
|
12
|
+
* Filter records based on a predicate. Records that don't match
|
|
13
|
+
* are dropped (returned as empty array).
|
|
14
|
+
*/
|
|
15
|
+
declare function filter<T extends DataRecord = DataRecord>(name: string, predicate: (record: T) => boolean | Promise<boolean>): Transformer<T, T>;
|
|
16
|
+
/**
|
|
17
|
+
* Transform each record into zero or more records.
|
|
18
|
+
*/
|
|
19
|
+
declare function flatMap<TInput extends DataRecord = DataRecord, TOutput extends DataRecord = DataRecord>(name: string, fn: (record: TInput) => TOutput[] | Promise<TOutput[]>): Transformer<TInput, TOutput>;
|
|
20
|
+
/**
|
|
21
|
+
* Pick specific keys from each record.
|
|
22
|
+
*/
|
|
23
|
+
declare function pick<T extends DataRecord, K extends keyof T & string>(name: string, keys: K[]): Transformer<T, Pick<T, K> & DataRecord>;
|
|
24
|
+
/**
|
|
25
|
+
* Omit specific keys from each record.
|
|
26
|
+
*/
|
|
27
|
+
declare function omit<T extends DataRecord, K extends keyof T & string>(name: string, keys: K[]): Transformer<T, Omit<T, K> & DataRecord>;
|
|
28
|
+
/**
|
|
29
|
+
* Rename keys in each record.
|
|
30
|
+
*/
|
|
31
|
+
declare function rename<T extends DataRecord>(name: string, mapping: Record<string, string>): Transformer<T>;
|
|
32
|
+
/**
|
|
33
|
+
* Compose multiple transformers into a single transformer that
|
|
34
|
+
* applies them in sequence.
|
|
35
|
+
*/
|
|
36
|
+
declare function compose<T extends DataRecord>(name: string, transformers: Transformer[]): Transformer<T>;
|
|
37
|
+
|
|
38
|
+
export { Transformer, compose, createTransformer, filter, flatMap, map, omit, pick, rename };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"transform.js"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** A single record flowing through a pipeline. */
|
|
2
|
+
type DataRecord = Record<string, unknown>;
|
|
3
|
+
/** Extracts data from a source, yielding records lazily. */
|
|
4
|
+
interface Extractor<T extends DataRecord = DataRecord> {
|
|
5
|
+
readonly name: string;
|
|
6
|
+
extract(): AsyncIterable<T>;
|
|
7
|
+
}
|
|
8
|
+
/** Transforms a record into zero or more output records. */
|
|
9
|
+
interface Transformer<TInput extends DataRecord = DataRecord, TOutput extends DataRecord = DataRecord> {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
transform(record: TInput): TOutput | TOutput[] | Promise<TOutput | TOutput[]>;
|
|
12
|
+
}
|
|
13
|
+
/** Loads a batch of records into a destination. */
|
|
14
|
+
interface Loader<T extends DataRecord = DataRecord> {
|
|
15
|
+
readonly name: string;
|
|
16
|
+
load(records: T[]): Promise<LoadResult>;
|
|
17
|
+
}
|
|
18
|
+
interface LoadResult {
|
|
19
|
+
readonly recordsLoaded: number;
|
|
20
|
+
readonly errors: LoadError[];
|
|
21
|
+
}
|
|
22
|
+
interface LoadError {
|
|
23
|
+
readonly record: DataRecord;
|
|
24
|
+
readonly error: Error;
|
|
25
|
+
}
|
|
26
|
+
/** Events emitted during pipeline execution. */
|
|
27
|
+
interface PipelineEvent {
|
|
28
|
+
readonly type: "pipeline:start" | "pipeline:end" | "step:start" | "step:end" | "record:extracted" | "record:transformed" | "record:loaded" | "error";
|
|
29
|
+
readonly timestamp: Date;
|
|
30
|
+
readonly stepName?: string;
|
|
31
|
+
readonly data?: unknown;
|
|
32
|
+
}
|
|
33
|
+
type PipelineEventListener = (event: PipelineEvent) => void;
|
|
34
|
+
interface PipelineOptions {
|
|
35
|
+
/** Records per load batch. Defaults to 1000. */
|
|
36
|
+
readonly batchSize?: number;
|
|
37
|
+
/** Keep processing after errors instead of throwing. */
|
|
38
|
+
readonly continueOnError?: boolean;
|
|
39
|
+
/** Cancel the pipeline. */
|
|
40
|
+
readonly signal?: AbortSignal;
|
|
41
|
+
}
|
|
42
|
+
interface PipelineResult {
|
|
43
|
+
readonly recordsProcessed: number;
|
|
44
|
+
readonly recordsLoaded: number;
|
|
45
|
+
readonly errors: PipelineStepError[];
|
|
46
|
+
readonly duration: number;
|
|
47
|
+
}
|
|
48
|
+
interface PipelineStepError {
|
|
49
|
+
readonly stepName: string;
|
|
50
|
+
readonly error: Error;
|
|
51
|
+
readonly record?: DataRecord;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type { DataRecord as D, Extractor as E, LoadError as L, PipelineEvent as P, Transformer as T, LoadResult as a, Loader as b, PipelineEventListener as c, PipelineOptions as d, PipelineResult as e, PipelineStepError as f };
|