@useairfoil/connector-kit 0.6.1 → 0.7.0
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.txt +201 -0
- package/METRICS.md +27 -30
- package/README.md +33 -51
- package/dist/{annotations-BE74YmAO.d.mts → annotations-vzSzXtr-.d.mts} +5 -10
- package/dist/{wings-I56hGtNv.mjs → arrow-flight-DDQ0ktx9.mjs} +25 -99
- package/dist/arrow-flight-DDQ0ktx9.mjs.map +1 -0
- package/dist/connector-app/index.d.mts +2 -2
- package/dist/connector-app/index.mjs +2 -2
- package/dist/connector-app-C6_dZnhE.mjs +256 -0
- package/dist/connector-app-C6_dZnhE.mjs.map +1 -0
- package/dist/{constants-D-GQzpHZ.mjs → constants-v3UX-hf6.mjs} +3 -2
- package/dist/constants-v3UX-hf6.mjs.map +1 -0
- package/dist/demo/index.d.mts +1 -1
- package/dist/demo/index.mjs +1 -1
- package/dist/{demo-B30Vlkk2.mjs → demo-DqTJ7TWI.mjs} +32 -19
- package/dist/demo-DqTJ7TWI.mjs.map +1 -0
- package/dist/iceberg/index.d.mts +3 -3
- package/dist/iceberg/index.mjs +3 -3
- package/dist/iceberg-Cj2PwlNm.mjs +30 -0
- package/dist/iceberg-Cj2PwlNm.mjs.map +1 -0
- package/dist/{index-DJhDp4Xc.d.mts → index-BTAbexBp.d.mts} +13 -16
- package/dist/{index-BUHSGm9Q.d.mts → index-Byr8NTdG.d.mts} +2 -2
- package/dist/{index-Dk7urvpF.d.mts → index-CV6V6fyx.d.mts} +9 -6
- package/dist/{index-NnCutIqM.d.mts → index-CZKx2Yce.d.mts} +29 -19
- package/dist/{index-BfXpgxk9.d.mts → index-DeTwIUKl.d.mts} +3 -3
- package/dist/{index-CRVAwJ5-.d.mts → index-dHS59EZl.d.mts} +4 -4
- package/dist/{index-ygpml2kC.d.mts → index-fHIJJoRe.d.mts} +17 -10
- package/dist/index-uFa2wwYo.d.mts +27 -0
- package/dist/index.d.mts +11 -11
- package/dist/index.mjs +10 -10
- package/dist/ingestion/index.d.mts +1 -1
- package/dist/ingestion/index.mjs +1 -1
- package/dist/{ingestion-q0WwqUSt.mjs → ingestion-DoCUwm5N.mjs} +6 -6
- package/dist/{ingestion-q0WwqUSt.mjs.map → ingestion-DoCUwm5N.mjs.map} +1 -1
- package/dist/ingestor/index.d.mts +3 -3
- package/dist/ingestor/index.mjs +3 -3
- package/dist/{ingestor-D4L-HPkg.mjs → ingestor-DjCEzBzZ.mjs} +6 -6
- package/dist/ingestor-DjCEzBzZ.mjs.map +1 -0
- package/dist/{instrumented-Bhp7fyvh.mjs → instrumented-Bq1WX2L5.mjs} +2 -2
- package/dist/{instrumented-Bhp7fyvh.mjs.map → instrumented-Bq1WX2L5.mjs.map} +1 -1
- package/dist/manifest/index.mjs +1 -1
- package/dist/{manifest-BGKxmKLy.mjs → manifest-CABeIhAG.mjs} +2 -2
- package/dist/{manifest-BGKxmKLy.mjs.map → manifest-CABeIhAG.mjs.map} +1 -1
- package/dist/{metrics-BaEX__MN.mjs → metrics-C901IIYZ.mjs} +6 -11
- package/dist/metrics-C901IIYZ.mjs.map +1 -0
- package/dist/{metrics-CVXFL7YT.d.mts → metrics-DoJ0WeKu.d.mts} +2 -2
- package/dist/metrics.d.mts +1 -1
- package/dist/metrics.mjs +1 -1
- package/dist/runtime-config/index.d.mts +2 -2
- package/dist/runtime-config/index.mjs +3 -3
- package/dist/{runtime-config-Oa55gAew.mjs → runtime-config-Bn8Fivt1.mjs} +11 -8
- package/dist/runtime-config-Bn8Fivt1.mjs.map +1 -0
- package/dist/{server-CMnxz3h0.mjs → server-D1TTN0_D.mjs} +3 -3
- package/dist/{server-CMnxz3h0.mjs.map → server-D1TTN0_D.mjs.map} +1 -1
- package/dist/{service-DLkhuxYl.d.mts → service-BRoy_EId.d.mts} +2 -2
- package/dist/state-store/index.mjs +1 -1
- package/dist/{state-store-uFvHY7Ax.mjs → state-store-DhSrKVEH.mjs} +2 -2
- package/dist/{state-store-uFvHY7Ax.mjs.map → state-store-DhSrKVEH.mjs.map} +1 -1
- package/dist/status/index.d.mts +1 -1
- package/dist/status/index.mjs +1 -1
- package/dist/{status-CKb9IhQ9.mjs → status-4h6Oxh-O.mjs} +2 -2
- package/dist/{status-CKb9IhQ9.mjs.map → status-4h6Oxh-O.mjs.map} +1 -1
- package/dist/{table-V0tgUC5i.mjs → table-CxM09xf7.mjs} +22 -85
- package/dist/table-CxM09xf7.mjs.map +1 -0
- package/dist/{types-xZtSmrGA.d.mts → types-NtSv6gwl.d.mts} +3 -3
- package/dist/webhook/index.d.mts +2 -2
- package/dist/webhook/index.mjs +1 -1
- package/package.json +19 -18
- package/src/catalog/retry.ts +25 -0
- package/src/catalog/table.ts +73 -37
- package/src/connector-app/create-table.ts +8 -8
- package/src/connector-app/demo.ts +24 -19
- package/src/connector-app/index.ts +1 -0
- package/src/connector-app/setup.ts +69 -0
- package/src/core/types.ts +1 -1
- package/src/demo/definition.ts +1 -1
- package/src/demo/generate.ts +1 -1
- package/src/demo/run.ts +60 -30
- package/src/iceberg/annotations.ts +3 -16
- package/src/iceberg/index.ts +2 -2
- package/src/iceberg/table.ts +28 -78
- package/src/ingestion/engine.ts +1 -1
- package/src/ingestor/{wings.ts → arrow-flight.ts} +25 -27
- package/src/ingestor/console.ts +1 -1
- package/src/ingestor/index.ts +5 -1
- package/src/runtime-config/config.ts +8 -3
- package/src/runtime-config/constants.ts +2 -1
- package/src/runtime-config/index.ts +1 -1
- package/src/runtime-config/table-bindings.ts +6 -4
- package/src/telemetry.ts +11 -19
- package/dist/connector-app-C-L4QqG6.mjs +0 -123
- package/dist/connector-app-C-L4QqG6.mjs.map +0 -1
- package/dist/constants-D-GQzpHZ.mjs.map +0 -1
- package/dist/demo-B30Vlkk2.mjs.map +0 -1
- package/dist/iceberg-D6L8I6vA.mjs +0 -39
- package/dist/iceberg-D6L8I6vA.mjs.map +0 -1
- package/dist/index-CUPP2A_m.d.mts +0 -27
- package/dist/ingestor-D4L-HPkg.mjs.map +0 -1
- package/dist/metrics-BaEX__MN.mjs.map +0 -1
- package/dist/runtime-config-Oa55gAew.mjs.map +0 -1
- package/dist/table-V0tgUC5i.mjs.map +0 -1
- package/dist/wings-I56hGtNv.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iceberg-Cj2PwlNm.mjs","names":[],"sources":["../src/iceberg/annotations.ts","../src/iceberg/index.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\ndeclare module \"effect/Schema\" {\n namespace Annotations {\n interface Annotations {\n readonly icebergIdentifierFields?: ReadonlyArray<string> | undefined;\n }\n }\n}\n\ntype KnownField<S extends Schema.Top> = keyof S[\"Type\"] & string;\n\n/** A row field that cannot be null or undefined. */\nexport type RequiredField<S extends Schema.Top> = [KnownField<S>] extends [never]\n ? string\n : {\n readonly [Field in KnownField<S>]-?: undefined extends S[\"Type\"][Field]\n ? never\n : null extends S[\"Type\"][Field]\n ? never\n : Field;\n }[KnownField<S>];\n\n/** A row schema whose identifier fields are `Key`. Only the type has it. */\nexport interface Identified<Key extends string> {\n readonly \"~iceberg.identifier\": Key;\n}\n\n/**\n * Marks the fields that identify a row. The engine upserts rows by them.\n *\n * Put it last. A later `.annotate()` keeps the runtime annotation, but the type\n * loses the key, so `Resource.entity` stops compiling.\n *\n * @example\n * ```ts\n * const Post = Schema.Struct({\n * id: Schema.String,\n * updatedAt: Schema.String,\n * }).pipe(Iceberg.identifier(\"id\"));\n * ```\n */\nexport const identifier =\n <S extends Schema.Top, const Key extends RequiredField<S>>(\n ...keys: readonly [Key, ...ReadonlyArray<Key>]\n ) =>\n (schema: S): S[\"Rebuild\"] & Identified<Key> =>\n // Effect has no slot for the key in the schema type, so we add it.\n schema.annotate({ icebergIdentifierFields: keys }) as S[\"Rebuild\"] & Identified<Key>;\n","export { identifier } from \"./annotations\";\nexport { IcebergSchemaError } from \"./error\";\nexport { makeCreateTableRequest, type CreateTableOptions } from \"./table\";\n"],"mappings":";;;;;;;;;;;;;;;;;;AA0CA,MAAa,cAET,GAAG,UAEJ,WAEC,OAAO,SAAS,EAAE,yBAAyB,KAAK,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { r as identifier } from "./annotations-vzSzXtr-.mjs";
|
|
2
2
|
import { Effect, Schema } from "effect";
|
|
3
|
-
import {
|
|
3
|
+
import { CreateTableRequest } from "iceberg-js";
|
|
4
4
|
//#region src/iceberg/error.d.ts
|
|
5
5
|
declare const IcebergSchemaError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
6
6
|
readonly _tag: "IcebergSchemaError";
|
|
@@ -15,20 +15,16 @@ declare class IcebergSchemaError extends IcebergSchemaError_base<{
|
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region src/iceberg/table.d.ts
|
|
17
17
|
/** Options for creating a table. */
|
|
18
|
-
type
|
|
18
|
+
type CreateTableOptions = {
|
|
19
|
+
readonly name: string;
|
|
19
20
|
/** Where the table's files go. The catalog may choose this when omitted. */
|
|
20
21
|
readonly location?: string | undefined;
|
|
21
|
-
/** UUID for the table. Random by default. */
|
|
22
|
-
readonly uuid?: string | undefined;
|
|
23
22
|
/** Extra table properties. These win over the ones from the schema. */
|
|
24
23
|
readonly properties?: Readonly<Record<string, string>> | undefined;
|
|
25
24
|
};
|
|
26
25
|
/**
|
|
27
|
-
* Builds
|
|
28
|
-
*
|
|
29
|
-
* The field IDs come from the schema, so the table has to keep them. Send the
|
|
30
|
-
* commit with `commitTable`. Then load the table and check the IDs before you
|
|
31
|
-
* write any rows. Don't use `createTable` here, because it can change the IDs.
|
|
26
|
+
* Builds a REST create-table request from an Effect schema.
|
|
27
|
+
* The catalog assigns the stored field IDs.
|
|
32
28
|
*
|
|
33
29
|
* A root `description` becomes the table `comment`, and a field `description`
|
|
34
30
|
* becomes its `doc`. `title` and `examples` are dropped.
|
|
@@ -39,20 +35,21 @@ type CreateTableCommitOptions = {
|
|
|
39
35
|
* @example
|
|
40
36
|
* ```ts
|
|
41
37
|
* const Row = Schema.Struct({
|
|
42
|
-
* id: Schema.String.pipe(
|
|
38
|
+
* id: Schema.String.pipe(Schema.annotateKey({ description: "Row identifier" })),
|
|
43
39
|
* })
|
|
44
40
|
* .annotate({ description: "Connector rows" })
|
|
45
41
|
* .pipe(Iceberg.identifier("id"))
|
|
46
42
|
*
|
|
47
|
-
* const request = yield* Iceberg.
|
|
43
|
+
* const request = yield* Iceberg.makeCreateTableRequest(Row, {
|
|
44
|
+
* name: "rows",
|
|
48
45
|
* location: "s3://warehouse/rows"
|
|
49
46
|
* })
|
|
50
47
|
* ```
|
|
51
48
|
*/
|
|
52
|
-
declare const
|
|
49
|
+
declare const makeCreateTableRequest: (schema: Schema.Top, options: CreateTableOptions) => Effect.Effect<CreateTableRequest, IcebergSchemaError>;
|
|
53
50
|
declare namespace index_d_exports {
|
|
54
|
-
export {
|
|
51
|
+
export { CreateTableOptions, IcebergSchemaError, identifier, makeCreateTableRequest };
|
|
55
52
|
}
|
|
56
53
|
//#endregion
|
|
57
|
-
export { IcebergSchemaError as i,
|
|
58
|
-
//# sourceMappingURL=index-
|
|
54
|
+
export { IcebergSchemaError as i, CreateTableOptions as n, makeCreateTableRequest as r, index_d_exports as t };
|
|
55
|
+
//# sourceMappingURL=index-BTAbexBp.d.mts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as ConnectorDefinition } from "./types-
|
|
1
|
+
import { r as ConnectorDefinition } from "./types-NtSv6gwl.mjs";
|
|
2
2
|
import { i as StateStore } from "./index-CgvFomO6.mjs";
|
|
3
3
|
import { Schema } from "effect";
|
|
4
4
|
import { HttpRouter } from "effect/http";
|
|
@@ -75,4 +75,4 @@ declare namespace index_d_exports {
|
|
|
75
75
|
}
|
|
76
76
|
//#endregion
|
|
77
77
|
export { ResourceStatusSchema as a, StatusUnavailableResponse as c, SyncStateSchema as d, statusRoute as f, ResourceStatus as i, StatusUnavailableResponseSchema as l, ResourceError as n, StatusResponse as o, ResourceErrorSchema as r, StatusResponseSchema as s, index_d_exports as t, SyncState as u };
|
|
78
|
-
//# sourceMappingURL=index-
|
|
78
|
+
//# sourceMappingURL=index-Byr8NTdG.d.mts.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { t as ConnectorError } from "./index-DkVNO6ks.mjs";
|
|
2
|
-
import { _ as ResourceRequiredField, b as ResourceSchema } from "./types-
|
|
3
|
-
import { i as Ingestor, n as IngestResult } from "./service-
|
|
2
|
+
import { _ as ResourceRequiredField, b as ResourceSchema } from "./types-NtSv6gwl.mjs";
|
|
3
|
+
import { i as Ingestor, n as IngestResult } from "./service-BRoy_EId.mjs";
|
|
4
4
|
import { Effect, Schema } from "effect";
|
|
5
5
|
import { Faker } from "@faker-js/faker";
|
|
6
6
|
//#region src/demo/generate.d.ts
|
|
7
|
-
/** What one run shares: the
|
|
7
|
+
/** What one run shares: the Faker and the time the run started. */
|
|
8
8
|
type DemoContext = {
|
|
9
9
|
readonly faker: Faker;
|
|
10
10
|
readonly now: Date;
|
|
@@ -36,7 +36,7 @@ type DemoDefinition<Setup extends ReadonlyArray<DemoTable> = ReadonlyArray<DemoT
|
|
|
36
36
|
readonly tables: Group;
|
|
37
37
|
readonly rows: (index: number, context: DemoContext) => DemoRows<Group>;
|
|
38
38
|
/**
|
|
39
|
-
* Groups written per chunk,
|
|
39
|
+
* Groups written per chunk, 1000 by default. A run can go over the size by
|
|
40
40
|
* one chunk, so lower it when a group is big.
|
|
41
41
|
*/
|
|
42
42
|
readonly groupsPerChunk?: number;
|
|
@@ -53,9 +53,12 @@ declare const define: <const Setup extends ReadonlyArray<DemoTable>, const Group
|
|
|
53
53
|
type RunOptions = {
|
|
54
54
|
/** Stop once this many Arrow bytes are written. */
|
|
55
55
|
readonly bytes: number;
|
|
56
|
-
|
|
56
|
+
/** Omit for random data on each run. */
|
|
57
|
+
readonly seed?: number;
|
|
57
58
|
/** The time data is made around. Same seed, time and tables give the same rows. */
|
|
58
59
|
readonly now: Date;
|
|
60
|
+
/** Maximum rows per ingestion batch. Defaults to 500. Must be a positive integer. */
|
|
61
|
+
readonly batchSize?: number;
|
|
59
62
|
/** Groups per chunk. Overrides the demo's. */
|
|
60
63
|
readonly groupsPerChunk?: number;
|
|
61
64
|
};
|
|
@@ -73,4 +76,4 @@ declare namespace index_d_exports {
|
|
|
73
76
|
}
|
|
74
77
|
//#endregion
|
|
75
78
|
export { DemoDefinition as a, define as c, run as i, table as l, DemoTotals as n, DemoRows as o, RunOptions as r, DemoTable as s, index_d_exports as t, DemoContext as u };
|
|
76
|
-
//# sourceMappingURL=index-
|
|
79
|
+
//# sourceMappingURL=index-CV6V6fyx.d.mts.map
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import "./index-BX8G7d41.mjs";
|
|
2
2
|
import { t as ConnectorError } from "./index-DkVNO6ks.mjs";
|
|
3
|
-
import "./annotations-
|
|
4
|
-
import { _ as ResourceRequiredField, b as ResourceSchema, d as ResourceDefinition, h as ResourceName, i as Cursor$1, l as PageFetch, n as ChangesFetch, r as ConnectorDefinition, t as ChangesFeed } from "./types-
|
|
5
|
-
import { a as DemoDefinition } from "./index-
|
|
6
|
-
import { i as Ingestor } from "./service-
|
|
7
|
-
import "./index-
|
|
3
|
+
import "./annotations-vzSzXtr-.mjs";
|
|
4
|
+
import { _ as ResourceRequiredField, b as ResourceSchema, d as ResourceDefinition, h as ResourceName, i as Cursor$1, l as PageFetch, n as ChangesFetch, r as ConnectorDefinition, t as ChangesFeed } from "./types-NtSv6gwl.mjs";
|
|
5
|
+
import { a as DemoDefinition } from "./index-CV6V6fyx.mjs";
|
|
6
|
+
import { i as Ingestor } from "./service-BRoy_EId.mjs";
|
|
7
|
+
import "./index-BTAbexBp.mjs";
|
|
8
8
|
import { i as StateStore } from "./index-CgvFomO6.mjs";
|
|
9
|
-
import "./index-
|
|
10
|
-
import "./index-
|
|
11
|
-
import "./index-
|
|
9
|
+
import "./index-DeTwIUKl.mjs";
|
|
10
|
+
import "./index-uFa2wwYo.mjs";
|
|
11
|
+
import { f as RuntimeConfigError, t as index_d_exports$1 } from "./index-fHIJJoRe.mjs";
|
|
12
12
|
import "./index-eFuoMZZ3.mjs";
|
|
13
|
-
import "./metrics-
|
|
14
|
-
import "./index-
|
|
15
|
-
import "./index-
|
|
13
|
+
import "./metrics-DoJ0WeKu.mjs";
|
|
14
|
+
import "./index-Byr8NTdG.mjs";
|
|
15
|
+
import "./index-dHS59EZl.mjs";
|
|
16
16
|
import { Config, Context, Duration, Effect, Layer, Option, Schema } from "effect";
|
|
17
17
|
import { CliError, Command } from "effect/cli";
|
|
18
|
+
import { CatalogManager } from "@useairfoil/api";
|
|
18
19
|
import { HttpRouter } from "effect/http";
|
|
19
20
|
//#region src/connector-app/check.d.ts
|
|
20
21
|
type ResourceCheckResult = {
|
|
@@ -153,7 +154,7 @@ declare const layerOtlp: (options?: OtlpTracingOptions & OtlpMetricsOptions) =>
|
|
|
153
154
|
declare const layerMetricsConsoleDump: (interval?: Duration.Input) => Layer.Layer<never, never, never>;
|
|
154
155
|
//#endregion
|
|
155
156
|
//#region src/connector-app/create-table.d.ts
|
|
156
|
-
/** Creates the table command
|
|
157
|
+
/** Creates the table command; existing tables must match the connector's row schemas. */
|
|
157
158
|
declare const makeCreateTableCommand: (schemas: Readonly<Record<string, Schema.Top>>) => Command.Command<"create-table", {
|
|
158
159
|
readonly table: string;
|
|
159
160
|
readonly catalog: string;
|
|
@@ -162,15 +163,16 @@ declare const makeCreateTableCommand: (schemas: Readonly<Record<string, Schema.T
|
|
|
162
163
|
}, {}, ConnectorError | import("effect/Config").ConfigError | CliError.UserError, import("effect/http/HttpClient").HttpClient>;
|
|
163
164
|
//#endregion
|
|
164
165
|
//#region src/connector-app/demo.d.ts
|
|
165
|
-
/** Reads sizes such as `
|
|
166
|
+
/** Reads byte sizes such as `512kB`, `128MB` or `1.5GB`. */
|
|
166
167
|
declare const parseSize: (input: string) => Option.Option<number>;
|
|
167
168
|
/**
|
|
168
|
-
* Creates the command that writes
|
|
169
|
-
* It reads
|
|
169
|
+
* Creates the command that writes demo data over Arrow Flight, then exits.
|
|
170
|
+
* It reads hosted config and table bindings, so provide `RuntimeConfig.layerHosted()`.
|
|
170
171
|
*/
|
|
171
172
|
declare const makeDemoCommand: (demo: DemoDefinition) => Command.Command<"demo", {
|
|
172
173
|
readonly size: number;
|
|
173
|
-
readonly seed: number
|
|
174
|
+
readonly seed: Option.Option<number>;
|
|
175
|
+
readonly batchSize: Option.Option<number>;
|
|
174
176
|
}, {}, ConnectorError, never>;
|
|
175
177
|
//#endregion
|
|
176
178
|
//#region src/connector-app/start.d.ts
|
|
@@ -184,9 +186,17 @@ type StartOptions = {
|
|
|
184
186
|
readonly disableHttpLogger?: boolean;
|
|
185
187
|
};
|
|
186
188
|
declare const start: (app: App, options: StartOptions) => Effect.Effect<void, ConnectorError | import("effect/http/HttpServerError").ServeError, StateStore | Ingestor>;
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region src/connector-app/setup.d.ts
|
|
191
|
+
/** Creates or verifies all bound tables without loading provider credentials. */
|
|
192
|
+
declare const makeSetupCommand: (schemas: Readonly<Record<string, Schema.Top>>) => Command.Command<"setup", {
|
|
193
|
+
readonly checkpointIntervalSec: Option.Option<number>;
|
|
194
|
+
readonly retryInterval: Duration.Duration;
|
|
195
|
+
readonly retries: number;
|
|
196
|
+
}, {}, ConnectorError | import("effect/Config").ConfigError | RuntimeConfigError | CatalogManager.CatalogManagerError, import("effect/http/HttpClient").HttpClient | import("effect/Scope").Scope>;
|
|
187
197
|
declare namespace index_d_exports {
|
|
188
|
-
export { App, CheckOptions, CheckResult, ResourceCheckResult, StartOptions, check, makeCreateTableCommand, makeDemoCommand, parseSize, start };
|
|
198
|
+
export { App, CheckOptions, CheckResult, ResourceCheckResult, StartOptions, check, makeCreateTableCommand, makeDemoCommand, makeSetupCommand, parseSize, start };
|
|
189
199
|
}
|
|
190
200
|
//#endregion
|
|
191
|
-
export {
|
|
192
|
-
//# sourceMappingURL=index-
|
|
201
|
+
export { check as _, start as a, makeCreateTableCommand as c, Cursor as d, Fetch as f, ResourceCheckResult as g, CheckResult as h, StartOptions as i, telemetry_d_exports as l, CheckOptions as m, makeSetupCommand as n, makeDemoCommand as o, Resource as p, App as r, parseSize as s, index_d_exports as t, Connector as u };
|
|
202
|
+
//# sourceMappingURL=index-CZKx2Yce.d.mts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as ConnectorError } from "./index-DkVNO6ks.mjs";
|
|
2
|
-
import { d as ResourceDefinition, i as Cursor, k as WebhookRoute, r as ConnectorDefinition } from "./types-
|
|
3
|
-
import { i as Ingestor } from "./service-
|
|
2
|
+
import { d as ResourceDefinition, i as Cursor, k as WebhookRoute, r as ConnectorDefinition } from "./types-NtSv6gwl.mjs";
|
|
3
|
+
import { i as Ingestor } from "./service-BRoy_EId.mjs";
|
|
4
4
|
import { i as StateStore } from "./index-CgvFomO6.mjs";
|
|
5
5
|
import { Effect } from "effect";
|
|
6
6
|
import { HttpRouter, HttpServer } from "effect/http";
|
|
@@ -34,4 +34,4 @@ declare namespace index_d_exports {
|
|
|
34
34
|
}
|
|
35
35
|
//#endregion
|
|
36
36
|
export { RunOptions as n, run as r, index_d_exports as t };
|
|
37
|
-
//# sourceMappingURL=index-
|
|
37
|
+
//# sourceMappingURL=index-DeTwIUKl.d.mts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as WebhookRouteContext, D as WebhookAckMode, d as ResourceDefinition, j as WebhookRouteInput, k as WebhookRoute, u as ResourceBatch } from "./types-
|
|
2
|
-
import { i as Ingestor } from "./service-
|
|
3
|
-
import "./index-
|
|
1
|
+
import { A as WebhookRouteContext, D as WebhookAckMode, d as ResourceDefinition, j as WebhookRouteInput, k as WebhookRoute, u as ResourceBatch } from "./types-NtSv6gwl.mjs";
|
|
2
|
+
import { i as Ingestor } from "./service-BRoy_EId.mjs";
|
|
3
|
+
import "./index-uFa2wwYo.mjs";
|
|
4
4
|
import { Context, Queue } from "effect";
|
|
5
5
|
import { HttpRouter } from "effect/http";
|
|
6
6
|
//#region src/webhook/server.d.ts
|
|
@@ -24,4 +24,4 @@ declare namespace index_d_exports {
|
|
|
24
24
|
declare const route: <const Resources extends ReadonlyArray<ResourceDefinition>, Payload>(definition: WebhookRouteInput<Resources, Payload>) => WebhookRoute<Resources, Payload>;
|
|
25
25
|
//#endregion
|
|
26
26
|
export { route as n, router as r, index_d_exports as t };
|
|
27
|
-
//# sourceMappingURL=index-
|
|
27
|
+
//# sourceMappingURL=index-dHS59EZl.d.mts.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { E as TableSource } from "./types-xZtSmrGA.mjs";
|
|
2
1
|
import { Config, Effect, FileSystem } from "effect";
|
|
3
2
|
import { TableIdentifier } from "iceberg-js";
|
|
4
3
|
//#region src/runtime-config/error.d.ts
|
|
@@ -16,9 +15,11 @@ declare class RuntimeConfigError extends RuntimeConfigError_base<{
|
|
|
16
15
|
//#region src/runtime-config/config.d.ts
|
|
17
16
|
/** Shared HTTP port used by hosted and sandbox connector entrypoints. */
|
|
18
17
|
declare const httpPort: Config.Config<number>;
|
|
19
|
-
/**
|
|
20
|
-
declare const
|
|
21
|
-
/**
|
|
18
|
+
/** Engine URL, including the protocol. */
|
|
19
|
+
declare const engineUri: Config.Config<URL>;
|
|
20
|
+
/** Arrow Flight URL. Uses the engine URL when unset. */
|
|
21
|
+
declare const flightUri: Config.Config<URL>;
|
|
22
|
+
/** Catalog ID. */
|
|
22
23
|
declare const catalog: Config.Config<string>;
|
|
23
24
|
//#endregion
|
|
24
25
|
//#region src/runtime-config/constants.d.ts
|
|
@@ -30,7 +31,8 @@ declare const PlatformRuntimeKey: {
|
|
|
30
31
|
readonly connectorInstanceId: "AIRFOIL_CONNECTOR_INSTANCE_ID";
|
|
31
32
|
readonly stateTable: "AIRFOIL_STATE_TABLE";
|
|
32
33
|
readonly postgresConnectionString: "POSTGRES_CONNECTION_STRING";
|
|
33
|
-
readonly
|
|
34
|
+
readonly engineUri: "ENGINE_URI";
|
|
35
|
+
readonly flightUri: "FLIGHT_URI";
|
|
34
36
|
readonly catalog: "AIRFOIL_CATALOG";
|
|
35
37
|
readonly otelEnabled: "OTEL_ENABLED";
|
|
36
38
|
readonly otelExporterOtlpEndpoint: "OTEL_EXPORTER_OTLP_ENDPOINT";
|
|
@@ -58,16 +60,21 @@ declare const PlatformRuntimeDefault: {
|
|
|
58
60
|
declare const layerHosted: () => import("effect/Layer").Layer<never, RuntimeConfigError, FileSystem.FileSystem>;
|
|
59
61
|
//#endregion
|
|
60
62
|
//#region src/runtime-config/table-bindings.d.ts
|
|
63
|
+
type BindingSource = {
|
|
64
|
+
readonly resources: ReadonlyArray<{
|
|
65
|
+
readonly name: string;
|
|
66
|
+
}>;
|
|
67
|
+
};
|
|
61
68
|
/** An Iceberg table and its storage location for each connector resource. */
|
|
62
69
|
type TableBinding = TableIdentifier & {
|
|
63
70
|
readonly location?: string | undefined;
|
|
64
71
|
};
|
|
65
|
-
type ResolvedTableBindings<Source extends
|
|
72
|
+
type ResolvedTableBindings<Source extends BindingSource> = Readonly<Partial<Record<Source["resources"][number]["name"], TableBinding>>>;
|
|
66
73
|
/** Reads hosted table bindings and checks they name resources of the connector. */
|
|
67
|
-
declare const loadTableBindings: <const Source extends
|
|
74
|
+
declare const loadTableBindings: <const Source extends BindingSource>(connector: Source) => Effect.Effect<ResolvedTableBindings<Source>, RuntimeConfigError>;
|
|
68
75
|
declare namespace index_d_exports {
|
|
69
|
-
export { PlatformRuntimeDefault, PlatformRuntimeKey, ResolvedTableBindings, RuntimeConfigError, RuntimeConfigErrorCode, TableBinding, catalog, httpPort, layerHosted, loadTableBindings
|
|
76
|
+
export { PlatformRuntimeDefault, PlatformRuntimeKey, ResolvedTableBindings, RuntimeConfigError, RuntimeConfigErrorCode, TableBinding, catalog, engineUri, flightUri, httpPort, layerHosted, loadTableBindings };
|
|
70
77
|
}
|
|
71
78
|
//#endregion
|
|
72
|
-
export { layerHosted as a, catalog as c,
|
|
73
|
-
//# sourceMappingURL=index-
|
|
79
|
+
export { layerHosted as a, catalog as c, httpPort as d, RuntimeConfigError as f, loadTableBindings as i, engineUri as l, ResolvedTableBindings as n, PlatformRuntimeDefault as o, RuntimeConfigErrorCode as p, TableBinding as r, PlatformRuntimeKey as s, index_d_exports as t, flightUri as u };
|
|
80
|
+
//# sourceMappingURL=index-fHIJJoRe.d.mts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { t as ConnectorError } from "./index-DkVNO6ks.mjs";
|
|
2
|
+
import { E as TableSource } from "./types-NtSv6gwl.mjs";
|
|
3
|
+
import { a as IngestorService, i as Ingestor, n as IngestResult, r as IngestSource, t as IngestOptions } from "./service-BRoy_EId.mjs";
|
|
4
|
+
import { n as ResolvedTableBindings, t as index_d_exports$1 } from "./index-fHIJJoRe.mjs";
|
|
5
|
+
import { Layer } from "effect";
|
|
6
|
+
import { CatalogManager } from "@useairfoil/api";
|
|
7
|
+
//#region src/ingestor/console.d.ts
|
|
8
|
+
/** Logs batches without sending them over Arrow Flight. */
|
|
9
|
+
declare const layerConsole: Layer.Layer<Ingestor, never, never>;
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/ingestor/arrow-flight.d.ts
|
|
12
|
+
/** One catalog and an Iceberg table for each resource that runs. */
|
|
13
|
+
type ArrowFlightIngestorConfig<Source extends TableSource = TableSource> = {
|
|
14
|
+
readonly connector: Source;
|
|
15
|
+
readonly catalog: string;
|
|
16
|
+
readonly tables: ResolvedTableBindings<Source>;
|
|
17
|
+
};
|
|
18
|
+
/** Compiles local schemas and opens one Arrow Flight stream per bound resource. */
|
|
19
|
+
declare const layerArrowFlight: <const Source extends TableSource>(config: ArrowFlightIngestorConfig<Source>) => Layer.Layer<Ingestor, ConnectorError, CatalogManager.CatalogManager>;
|
|
20
|
+
/** Configures Arrow Flight ingestion from the hosted URL, catalog and table bindings. */
|
|
21
|
+
declare const layerArrowFlightConfig: (connector: TableSource) => Layer.Layer<Ingestor, ConnectorError, never>;
|
|
22
|
+
declare namespace index_d_exports {
|
|
23
|
+
export { ArrowFlightIngestorConfig, IngestOptions, IngestResult, IngestSource, Ingestor, IngestorService, layerArrowFlight, layerArrowFlightConfig, layerConsole };
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { layerConsole as a, layerArrowFlightConfig as i, ArrowFlightIngestorConfig as n, layerArrowFlight as r, index_d_exports as t };
|
|
27
|
+
//# sourceMappingURL=index-uFa2wwYo.d.mts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { t as index_d_exports } from "./index-BX8G7d41.mjs";
|
|
2
2
|
import { t as ConnectorError } from "./index-DkVNO6ks.mjs";
|
|
3
|
-
import { t as Identified } from "./annotations-
|
|
4
|
-
import { A as WebhookRouteContext, C as ResourceUpdateOf, D as WebhookAckMode, E as TableSource, O as WebhookHandler, S as ResourceUpdate, T as TableResource, _ as ResourceRequiredField, a as FeedRows, b as ResourceSchema, c as FetchPageResult, d as ResourceDefinition, f as ResourceDelete, g as ResourcePayload, i as Cursor$1, k as WebhookRoute, l as PageFetch, m as ResourceKey, n as ChangesFetch, o as FetchChangesResult, p as ResourceField, r as ConnectorDefinition, s as FetchFeedResult, t as ChangesFeed, u as ResourceBatch, v as ResourceRow, x as ResourceState, y as ResourceRows } from "./types-
|
|
5
|
-
import {
|
|
6
|
-
import { t as index_d_exports$2 } from "./index-
|
|
7
|
-
import { t as index_d_exports$3 } from "./index-
|
|
3
|
+
import { t as Identified } from "./annotations-vzSzXtr-.mjs";
|
|
4
|
+
import { A as WebhookRouteContext, C as ResourceUpdateOf, D as WebhookAckMode, E as TableSource, O as WebhookHandler, S as ResourceUpdate, T as TableResource, _ as ResourceRequiredField, a as FeedRows, b as ResourceSchema, c as FetchPageResult, d as ResourceDefinition, f as ResourceDelete, g as ResourcePayload, i as Cursor$1, k as WebhookRoute, l as PageFetch, m as ResourceKey, n as ChangesFetch, o as FetchChangesResult, p as ResourceField, r as ConnectorDefinition, s as FetchFeedResult, t as ChangesFeed, u as ResourceBatch, v as ResourceRow, x as ResourceState, y as ResourceRows } from "./types-NtSv6gwl.mjs";
|
|
5
|
+
import { d as Cursor, f as Fetch, l as telemetry_d_exports, p as Resource, t as index_d_exports$1, u as Connector } from "./index-CZKx2Yce.mjs";
|
|
6
|
+
import { t as index_d_exports$2 } from "./index-CV6V6fyx.mjs";
|
|
7
|
+
import { t as index_d_exports$3 } from "./index-BTAbexBp.mjs";
|
|
8
8
|
import { t as index_d_exports$8 } from "./index-CgvFomO6.mjs";
|
|
9
|
-
import { t as index_d_exports$4 } from "./index-
|
|
10
|
-
import { t as index_d_exports$5 } from "./index-
|
|
11
|
-
import { t as index_d_exports$7 } from "./index-
|
|
9
|
+
import { t as index_d_exports$4 } from "./index-DeTwIUKl.mjs";
|
|
10
|
+
import { t as index_d_exports$5 } from "./index-uFa2wwYo.mjs";
|
|
11
|
+
import { t as index_d_exports$7 } from "./index-fHIJJoRe.mjs";
|
|
12
12
|
import { t as index_d_exports$6 } from "./index-eFuoMZZ3.mjs";
|
|
13
|
-
import { h as metrics_d_exports } from "./metrics-
|
|
14
|
-
import { t as index_d_exports$9 } from "./index-
|
|
15
|
-
import { t as index_d_exports$10 } from "./index-
|
|
13
|
+
import { h as metrics_d_exports } from "./metrics-DoJ0WeKu.mjs";
|
|
14
|
+
import { t as index_d_exports$9 } from "./index-Byr8NTdG.mjs";
|
|
15
|
+
import { t as index_d_exports$10 } from "./index-dHS59EZl.mjs";
|
|
16
16
|
export { index_d_exports as Auth, type ChangesFeed, type ChangesFetch, Connector, index_d_exports$1 as ConnectorApp, type ConnectorDefinition, ConnectorError, Cursor, type Cursor$1 as CursorTypes, index_d_exports$2 as Demo, type FeedRows, Fetch, type FetchChangesResult, type FetchFeedResult, type FetchPageResult, index_d_exports$3 as Iceberg, type Identified, index_d_exports$4 as Ingestion, index_d_exports$5 as Ingestor, index_d_exports$6 as Manifest, metrics_d_exports as Metrics, type PageFetch, Resource, type ResourceBatch, type ResourceDefinition, type ResourceDelete, type ResourceField, type ResourceKey, type ResourcePayload, type ResourceRequiredField, type ResourceRow, type ResourceRows, type ResourceSchema, type ResourceState, type ResourceUpdate, type ResourceUpdateOf, index_d_exports$7 as RuntimeConfig, index_d_exports$8 as StateStore, index_d_exports$9 as Status, type TableResource, type TableSource, telemetry_d_exports as Telemetry, index_d_exports$10 as Webhook, type WebhookAckMode, type WebhookHandler, type WebhookRoute, type WebhookRouteContext };
|
package/dist/index.mjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { t as ConnectorError } from "./errors-pT0YVJU5.mjs";
|
|
2
2
|
import { t as auth_exports } from "./auth/index.mjs";
|
|
3
|
-
import { t as connector_app_exports } from "./connector-app-
|
|
4
|
-
import { t as runtime_config_exports } from "./runtime-config-
|
|
5
|
-
import { t as demo_exports } from "./demo-
|
|
6
|
-
import { o as metrics_exports, w as telemetry_exports } from "./metrics-
|
|
7
|
-
import { t as state_store_exports } from "./state-store-
|
|
8
|
-
import { t as status_exports } from "./status-
|
|
9
|
-
import { t as ingestion_exports } from "./ingestion-
|
|
10
|
-
import { t as iceberg_exports } from "./iceberg-
|
|
11
|
-
import { t as ingestor_exports } from "./ingestor-
|
|
12
|
-
import { t as manifest_exports } from "./manifest-
|
|
3
|
+
import { t as connector_app_exports } from "./connector-app-C6_dZnhE.mjs";
|
|
4
|
+
import { t as runtime_config_exports } from "./runtime-config-Bn8Fivt1.mjs";
|
|
5
|
+
import { t as demo_exports } from "./demo-DqTJ7TWI.mjs";
|
|
6
|
+
import { o as metrics_exports, w as telemetry_exports } from "./metrics-C901IIYZ.mjs";
|
|
7
|
+
import { t as state_store_exports } from "./state-store-DhSrKVEH.mjs";
|
|
8
|
+
import { t as status_exports } from "./status-4h6Oxh-O.mjs";
|
|
9
|
+
import { t as ingestion_exports } from "./ingestion-DoCUwm5N.mjs";
|
|
10
|
+
import { t as iceberg_exports } from "./iceberg-Cj2PwlNm.mjs";
|
|
11
|
+
import { t as ingestor_exports } from "./ingestor-DjCEzBzZ.mjs";
|
|
12
|
+
import { t as manifest_exports } from "./manifest-CABeIhAG.mjs";
|
|
13
13
|
import { t as webhook_exports } from "./webhook/index.mjs";
|
|
14
14
|
import { DateTime, Effect, Option } from "effect";
|
|
15
15
|
//#region src/core/builder.ts
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as RunOptions, r as run } from "../index-
|
|
1
|
+
import { n as RunOptions, r as run } from "../index-DeTwIUKl.mjs";
|
|
2
2
|
export { type RunOptions, run };
|
package/dist/ingestion/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as run } from "../ingestion-
|
|
1
|
+
import { n as run } from "../ingestion-DoCUwm5N.mjs";
|
|
2
2
|
export { run };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
2
|
import { t as ConnectorError } from "./errors-pT0YVJU5.mjs";
|
|
3
|
-
import { C as annotateError, d as setLastSuccessTimestamp, f as setSyncState, p as setWebhookQueueDepth, v as Attr, x as SpanName } from "./metrics-
|
|
3
|
+
import { C as annotateError, d as setLastSuccessTimestamp, f as setSyncState, p as setWebhookQueueDepth, v as Attr, x as SpanName } from "./metrics-C901IIYZ.mjs";
|
|
4
4
|
import { t as Ingestor } from "./service-jWxxfEht.mjs";
|
|
5
|
-
import { t as ingestBatch } from "./instrumented-
|
|
6
|
-
import { o as StateStore } from "./state-store-
|
|
7
|
-
import { c as deriveSyncState, l as hasChanges, s as statusRoute, u as normalizeCursor } from "./status-
|
|
8
|
-
import { n as router, t as WebhookQueue } from "./server-
|
|
5
|
+
import { t as ingestBatch } from "./instrumented-Bq1WX2L5.mjs";
|
|
6
|
+
import { o as StateStore } from "./state-store-DhSrKVEH.mjs";
|
|
7
|
+
import { c as deriveSyncState, l as hasChanges, s as statusRoute, u as normalizeCursor } from "./status-4h6Oxh-O.mjs";
|
|
8
|
+
import { n as router, t as WebhookQueue } from "./server-D1TTN0_D.mjs";
|
|
9
9
|
import { Array, DateTime, Effect, Layer, Order, Queue } from "effect";
|
|
10
10
|
import { HttpRouter, HttpServerResponse } from "effect/http";
|
|
11
11
|
import * as Observability from "effect/observability";
|
|
@@ -272,4 +272,4 @@ var ingestion_exports = /* @__PURE__ */ __exportAll({ run: () => run });
|
|
|
272
272
|
//#endregion
|
|
273
273
|
export { run as n, ingestion_exports as t };
|
|
274
274
|
|
|
275
|
-
//# sourceMappingURL=ingestion-
|
|
275
|
+
//# sourceMappingURL=ingestion-DoCUwm5N.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingestion-q0WwqUSt.mjs","names":["Metrics.setWebhookQueueDepth","Metrics.setSyncState","Metrics.setLastSuccessTimestamp","Arr"],"sources":["../src/ingestion/engine.ts","../src/ingestion/index.ts"],"sourcesContent":["import { Array as Arr, DateTime, Effect, Layer, Order, Queue } from \"effect\";\nimport { HttpRouter, type HttpServer, HttpServerResponse } from \"effect/http\";\nimport * as Observability from \"effect/observability\";\n\nimport type {\n ChangesFeed,\n ConnectorDefinition,\n Cursor,\n ResourceDefinition,\n ResourceState,\n WebhookRoute,\n} from \"../core/types\";\nimport type { StateOperation, StateSource } from \"../state-store/schema\";\n\nimport { ConnectorError } from \"../errors\";\nimport { ingestBatch } from \"../ingestor/instrumented\";\nimport { Ingestor } from \"../ingestor/service\";\nimport * as Metrics from \"../metrics\";\nimport { StateStore } from \"../state-store\";\nimport { deriveSyncState, hasChanges, normalizeCursor } from \"../state-store/state\";\nimport { statusRoute } from \"../status\";\nimport { Attr, SpanName, annotateError } from \"../telemetry\";\nimport { router, WebhookQueue, type QueuedWebhookBatch } from \"../webhook/server\";\n\ntype RunBaseOptions = {\n readonly initialCutoff?: Cursor.Value;\n};\n\nexport type RunOptions = RunBaseOptions & {\n readonly webhook?: {\n readonly routes: ReadonlyArray<WebhookRoute>;\n readonly healthPath?: HttpRouter.PathInput;\n readonly metricsPath?: HttpRouter.PathInput | false;\n readonly statusPath?: HttpRouter.PathInput | false;\n readonly disableHttpLogger?: boolean;\n };\n};\n\ntype RunNoWebhookOptions = RunBaseOptions & {\n readonly webhook?: undefined;\n};\n\ntype RunWebhookOptions = RunOptions & {\n readonly webhook: NonNullable<RunOptions[\"webhook\"]>;\n};\n\n/**\n * Runs all connector ingestion loops. Callers provide the Ingestor and\n * StateStore layers; webhook mode additionally requires an HttpServer layer.\n */\nexport function run<const Resources extends ReadonlyArray<ResourceDefinition>>(\n connector: ConnectorDefinition<Resources>,\n options?: RunNoWebhookOptions,\n): Effect.Effect<void, ConnectorError, StateStore | Ingestor>;\nexport function run<const Resources extends ReadonlyArray<ResourceDefinition>>(\n connector: ConnectorDefinition<Resources>,\n options: RunWebhookOptions,\n): Effect.Effect<void, ConnectorError, StateStore | Ingestor | HttpServer.HttpServer>;\nexport function run(definition: ConnectorDefinition, options?: RunOptions) {\n return Effect.gen(function* () {\n // Check the whole feed, even the resources that don't run.\n if (definition.changes) yield* validateFeed(definition, definition.changes);\n const ingestor = yield* Ingestor;\n const connector = selectResources(definition, ingestor.resourceNames);\n const queueLayer = makeWebhookQueueLayer(connector.name);\n const runtimeLayer = options?.webhook\n ? Layer.mergeAll(\n queueLayer,\n makeWebhookServerLayer(connector, options.webhook).pipe(Layer.provide(queueLayer)),\n )\n : Layer.empty;\n\n return yield* Effect.gen(function* () {\n const initialCutoff =\n options?.initialCutoff ?? (yield* DateTime.now.pipe(Effect.map(DateTime.formatIso)));\n yield* Effect.logInfo(\"Connector started\").pipe(\n Effect.annotateLogs({\n [Attr.connectorName]: connector.name,\n resources: connector.resources.length,\n }),\n );\n\n const sourceRun = runIngestion(connector, initialCutoff);\n const webhookRun = options?.webhook\n ? runWebhookRuntime(connector, options.webhook.routes)\n : Effect.void;\n\n return yield* Effect.all([sourceRun, webhookRun], { concurrency: \"unbounded\" }).pipe(\n Effect.asVoid,\n );\n }).pipe(Effect.provide(runtimeLayer));\n });\n}\n\nconst selectResources = (\n connector: ConnectorDefinition,\n names: ReadonlyArray<string> | undefined,\n): ConnectorDefinition => {\n if (names === undefined) return connector;\n const isSelected = (resource: ResourceDefinition) => names.includes(resource.name);\n const { changes, ...rest } = connector;\n const feedResources = changes?.resources.filter(isSelected) ?? [];\n return {\n ...rest,\n resources: connector.resources.filter(isSelected),\n ...(changes && feedResources.length > 0\n ? { changes: { ...changes, resources: feedResources } }\n : {}),\n };\n};\n\nconst makeWebhookQueueLayer = (connector: string): Layer.Layer<WebhookQueue> =>\n Layer.effect(WebhookQueue)(\n Effect.gen(function* () {\n const queue = yield* Queue.bounded<QueuedWebhookBatch>(1024);\n yield* Metrics.setWebhookQueueDepth(connector, 0);\n return WebhookQueue.of({ queue });\n }),\n );\n\nconst runWebhookRuntime = (connector: ConnectorDefinition, routes: ReadonlyArray<WebhookRoute>) => {\n const hasAfterEnqueue = routes.some((route) => route.ackMode === \"after-enqueue\");\n return Effect.all(\n [hasAfterEnqueue ? runWebhookQueueConsumer(connector) : Effect.void, Effect.never],\n {\n concurrency: \"unbounded\",\n },\n ).pipe(Effect.asVoid);\n};\n\nconst runWebhookQueueConsumer = (connector: ConnectorDefinition) =>\n Effect.gen(function* () {\n const queue = yield* WebhookQueue;\n while (true) {\n const batch = yield* Queue.take(queue.queue);\n const depth = yield* Queue.size(queue.queue);\n yield* Metrics.setWebhookQueueDepth(connector.name, depth);\n yield* ingestBatch({\n connector: connector.name,\n resource: batch.resource,\n source: \"webhook\",\n batch: batch.batch,\n });\n }\n });\n\nconst makeWebhookServerLayer = (\n connector: ConnectorDefinition,\n options: {\n readonly routes: ReadonlyArray<WebhookRoute>;\n readonly healthPath?: HttpRouter.PathInput;\n readonly metricsPath?: HttpRouter.PathInput | false;\n readonly statusPath?: HttpRouter.PathInput | false;\n readonly disableHttpLogger?: boolean;\n },\n): Layer.Layer<never, never, HttpServer.HttpServer> => {\n const healthPath: HttpRouter.PathInput = options.healthPath ?? \"/health\";\n const metricsPath = options.metricsPath === undefined ? \"/metrics\" : options.metricsPath;\n const statusPath = options.statusPath === undefined ? \"/status\" : options.statusPath;\n const app = Layer.mergeAll(\n router(options.routes, {\n connectorName: connector.name,\n resourceNames: connector.resources.map((resource) => resource.name),\n }),\n HttpRouter.add(\"GET\", healthPath, Effect.succeed(HttpServerResponse.text(\"ok\"))),\n ...(metricsPath === false\n ? []\n : [Observability.PrometheusMetrics.layerHttp({ path: metricsPath })]),\n ...(statusPath === false ? [] : [statusRoute(connector, statusPath)]),\n );\n\n return HttpRouter.serve(app, {\n disableLogger: options.disableHttpLogger ?? true,\n });\n};\n\nconst runIngestion = (\n connector: ConnectorDefinition,\n initialCutoff: Cursor.Value,\n): Effect.Effect<void, ConnectorError, StateStore | Ingestor> =>\n Effect.gen(function* () {\n const feed = connector.changes;\n yield* Effect.all(\n [\n Effect.forEach(\n connector.resources,\n (resource) => runResourceSources(connector, resource, initialCutoff),\n { concurrency: \"unbounded\" },\n ),\n feed ? runChangesFeed(connector, feed, initialCutoff) : Effect.void,\n ],\n { concurrency: \"unbounded\" },\n );\n });\n\nconst bySavedAt = Order.mapInput(\n Order.String,\n (state: NonNullable<ResourceState[\"changes\"]>) => state.lastSuccessAt ?? \"\",\n);\n\nconst validateFeed = (connector: ConnectorDefinition, feed: ChangesFeed) =>\n Effect.forEach(feed.resources, (member, index) => {\n if (feed.resources.findIndex((item) => item.name === member.name) !== index) {\n return Effect.fail(\n new ConnectorError({ message: `Resource ${member.name} is in the changes feed twice` }),\n );\n }\n const resource = connector.resources.find((item) => item.name === member.name);\n if (!resource) {\n return Effect.fail(\n new ConnectorError({\n message: `Changes feed resource ${member.name} is not a resource of connector ${connector.name}`,\n }),\n );\n }\n if (resource.changes) {\n return Effect.fail(\n new ConnectorError({\n message: `Resource ${member.name} has its own changes and is also in the changes feed`,\n }),\n );\n }\n return Effect.void;\n }).pipe(\n Effect.andThen(\n feed.resources.length === 0\n ? Effect.fail(new ConnectorError({ message: \"The changes feed has no resources\" }))\n : Effect.void,\n ),\n );\n\nconst initializeResourceState = (\n existing: ResourceState | undefined,\n initialCutoff: Cursor.Value,\n): ResourceState => ({\n ...existing,\n changes: existing?.changes ?? { cursor: initialCutoff },\n backfill: existing?.backfill ?? {\n cutoff: initialCutoff,\n completed: false,\n },\n});\n\nconst getInitializedState = Effect.fnUntraced(function* (\n resource: string,\n initialCutoff: Cursor.Value,\n) {\n const store = yield* StateStore;\n const existing = yield* store.getResourceState(resource);\n return initializeResourceState(existing, initialCutoff);\n});\n\nconst runResourceSources = (\n connector: ConnectorDefinition,\n resource: ResourceDefinition,\n initialCutoff: Cursor.Value,\n) => {\n const runs = [\n resource.backfill\n ? isolateSourceFailure(\n runBackfill(connector, resource, initialCutoff),\n connector,\n resource,\n \"backfill\",\n )\n : Effect.void,\n resource.changes\n ? isolateSourceFailure(\n runChanges(connector, resource, initialCutoff),\n connector,\n resource,\n \"changes\",\n )\n : Effect.void,\n ];\n\n return initializeRuntimeStatus(connector, resource, initialCutoff).pipe(\n Effect.andThen(Effect.all(runs, { concurrency: \"unbounded\" })),\n Effect.asVoid,\n Effect.catch((error) =>\n Metrics.setSyncState({ connector: connector.name, resource: resource.name }, \"error\").pipe(\n Effect.andThen(Effect.logError(\"Connector resource initialization failed\", error)),\n Effect.annotateLogs({\n [Attr.connectorName]: connector.name,\n resource: resource.name,\n }),\n Effect.andThen(Effect.never),\n ),\n ),\n );\n};\n\nconst recordResourceError =\n (\n connector: ConnectorDefinition,\n resource: ResourceDefinition,\n source: StateSource,\n operation: StateOperation,\n ) =>\n <A, R>(\n effect: Effect.Effect<A, ConnectorError, R>,\n ): Effect.Effect<A, ConnectorError, R | StateStore> =>\n effect.pipe(\n Effect.tapError(() =>\n Metrics.setSyncState({ connector: connector.name, resource: resource.name }, \"error\").pipe(\n Effect.andThen(\n StateStore.pipe(\n Effect.flatMap((store) => store.setResourceError(resource.name, source, operation)),\n ),\n ),\n ),\n ),\n );\n\nconst isolateSourceFailure = <A, R>(\n effect: Effect.Effect<A, ConnectorError, R>,\n connector: ConnectorDefinition,\n resource: ResourceDefinition,\n source: StateSource,\n): Effect.Effect<A, never, R> =>\n // Only typed source errors are isolated. Defects and interruption still stop the runtime.\n effect.pipe(\n Effect.catch((error) =>\n Effect.logError(\"Connector source parked\", error).pipe(\n Effect.annotateLogs({\n [Attr.connectorName]: connector.name,\n resource: resource.name,\n source,\n }),\n Effect.andThen(Effect.never),\n ),\n ),\n );\n\nconst refreshRuntimeStatus = Effect.fnUntraced(function* (\n connector: ConnectorDefinition,\n resource: ResourceDefinition,\n initialCutoff: Cursor.Value,\n) {\n const state = yield* getInitializedState(resource.name, initialCutoff);\n yield* Metrics.setSyncState(\n { connector: connector.name, resource: resource.name },\n deriveSyncState(connector, resource, state),\n );\n\n return state;\n});\n\nconst initializeRuntimeStatus = Effect.fnUntraced(function* (\n connector: ConnectorDefinition,\n resource: ResourceDefinition,\n initialCutoff: Cursor.Value,\n) {\n const state = yield* getInitializedState(resource.name, initialCutoff);\n yield* Metrics.setSyncState(\n { connector: connector.name, resource: resource.name },\n deriveSyncState(connector, resource, state),\n );\n\n if (resource.backfill) {\n yield* Metrics.setLastSuccessTimestamp(\n { connector: connector.name, resource: resource.name, source: \"backfill\" },\n state.backfill?.lastSuccessAt,\n );\n }\n if (hasChanges(connector, resource)) {\n yield* Metrics.setLastSuccessTimestamp(\n { connector: connector.name, resource: resource.name, source: \"changes\" },\n state.changes?.lastSuccessAt,\n );\n }\n});\n\nconst runBackfill = Effect.fnUntraced(function* (\n connector: ConnectorDefinition,\n resource: ResourceDefinition,\n initialCutoff: Cursor.Value,\n) {\n if (!resource.backfill) return;\n const store = yield* StateStore;\n let state = yield* getInitializedState(resource.name, initialCutoff);\n\n if (state.backfill?.completed === true) {\n // The checkpoint may have committed before the previous process cleared\n // its error marker. It may also be hidden by a newer changes error.\n yield* store\n .clearResourceError(resource.name, \"backfill\")\n .pipe(recordResourceError(connector, resource, \"backfill\", \"checkpoint\"));\n yield* refreshRuntimeStatus(connector, resource, initialCutoff);\n return;\n }\n\n while (state.backfill?.completed !== true) {\n const backfill = state.backfill ?? { cutoff: initialCutoff, completed: false };\n const clearsVisibleError = state.lastError?.source === \"backfill\";\n const page = yield* resource.backfill\n .fetch({\n pageCursor: backfill.pageCursor,\n cutoff: backfill.cutoff,\n })\n .pipe(recordResourceError(connector, resource, \"backfill\", \"fetch\"));\n\n yield* ingestBatch({\n connector: connector.name,\n resource: resource.name,\n source: \"backfill\",\n batch: {\n cursor: page.nextPageCursor ?? backfill.cutoff,\n rows: page.rows,\n },\n }).pipe(recordResourceError(connector, resource, \"backfill\", \"ingest\"));\n\n const lastSuccessAt = yield* DateTime.now.pipe(Effect.map(DateTime.formatIso));\n state = {\n ...state,\n backfill: {\n cutoff: backfill.cutoff,\n pageCursor: page.nextPageCursor,\n completed: !page.hasMore,\n lastSuccessAt,\n },\n };\n\n // Checkpoint only after ingestion succeeds so a crash cannot skip an\n // unacknowledged page; replay therefore remains at-least-once.\n yield* Effect.withSpan(\n store\n .setBackfillState(resource.name, {\n cutoff: normalizeCursor(backfill.cutoff),\n pageCursor:\n page.nextPageCursor === undefined ? undefined : normalizeCursor(page.nextPageCursor),\n completed: !page.hasMore,\n lastSuccessAt,\n })\n .pipe(\n Effect.andThen(\n Metrics.setLastSuccessTimestamp(\n { connector: connector.name, resource: resource.name, source: \"backfill\" },\n lastSuccessAt,\n ),\n ),\n Effect.andThen(store.clearResourceError(resource.name, \"backfill\")),\n Effect.tapError((error) => annotateError(\"state_set\", error)),\n ),\n SpanName.stateSet,\n { attributes: { [Attr.stateKey]: resource.name } },\n ).pipe(recordResourceError(connector, resource, \"backfill\", \"checkpoint\"));\n\n // Completion or clearing an error can change the resource-wide sync state.\n if (clearsVisibleError || !page.hasMore) {\n state = yield* refreshRuntimeStatus(connector, resource, initialCutoff);\n }\n }\n});\n\nconst runChanges = Effect.fnUntraced(function* (\n connector: ConnectorDefinition,\n resource: ResourceDefinition,\n initialCutoff: Cursor.Value,\n) {\n if (!resource.changes) return;\n const store = yield* StateStore;\n\n while (true) {\n const state = yield* getInitializedState(resource.name, initialCutoff);\n const cursor = state.changes?.cursor ?? initialCutoff;\n const clearsVisibleError = state.lastError?.source === \"changes\";\n const page = yield* resource.changes\n .fetch({ cursor })\n .pipe(recordResourceError(connector, resource, \"changes\", \"fetch\"));\n\n yield* ingestBatch({\n connector: connector.name,\n resource: resource.name,\n source: \"changes\",\n batch: {\n cursor: page.cursor,\n rows: page.rows,\n },\n }).pipe(recordResourceError(connector, resource, \"changes\", \"ingest\"));\n\n const lastSuccessAt = yield* DateTime.now.pipe(Effect.map(DateTime.formatIso));\n // Advance the durable cursor only after Wings acknowledges the page.\n yield* Effect.withSpan(\n store\n .setChangesState(resource.name, {\n cursor: normalizeCursor(page.cursor),\n lastSuccessAt,\n })\n .pipe(\n Effect.andThen(\n Metrics.setLastSuccessTimestamp(\n { connector: connector.name, resource: resource.name, source: \"changes\" },\n lastSuccessAt,\n ),\n ),\n Effect.andThen(store.clearResourceError(resource.name, \"changes\")),\n Effect.tapError((error) => annotateError(\"state_set\", error)),\n ),\n SpanName.stateSet,\n { attributes: { [Attr.stateKey]: resource.name } },\n ).pipe(recordResourceError(connector, resource, \"changes\", \"checkpoint\"));\n\n if (clearsVisibleError) {\n yield* refreshRuntimeStatus(connector, resource, initialCutoff);\n }\n\n if (!page.hasMore) {\n yield* Effect.sleep(resource.changes.interval ?? \"1 minute\");\n }\n }\n});\n\n// Every member resource stores the feed cursor. All rows are ingested before any\n// cursor is written. If a crash stops the writes partway, the next run starts\n// from the oldest cursor.\nconst runChangesFeed = (\n connector: ConnectorDefinition,\n feed: ChangesFeed,\n initialCutoff: Cursor.Value,\n): Effect.Effect<void, never, StateStore | Ingestor> =>\n Effect.gen(function* () {\n const store = yield* StateStore;\n const members = feed.resources;\n const selected = new Set(members.map((resource) => resource.name));\n // Any failure stops the whole feed, so it is an error for every resource in it.\n const recordFeedError =\n (operation: StateOperation) =>\n <A, R>(effect: Effect.Effect<A, ConnectorError, R>) =>\n effect.pipe(\n Effect.tapError(() =>\n Effect.forEach(\n members,\n (resource) =>\n Metrics.setSyncState(\n { connector: connector.name, resource: resource.name },\n \"error\",\n ).pipe(Effect.andThen(store.setResourceError(resource.name, \"changes\", operation))),\n { discard: true },\n ),\n ),\n );\n\n while (true) {\n const states = yield* Effect.forEach(members, (resource) =>\n store.getResourceState(resource.name),\n );\n // A resource that was off has an older cursor. Resume from the oldest, so it\n // gets the changes it missed. The others read some changes again.\n const saved = states.flatMap((state) => (state?.changes ? [state.changes] : []));\n const cursor = Arr.isReadonlyArrayNonEmpty(saved)\n ? Arr.min(saved, bySavedAt).cursor\n : initialCutoff;\n const result = yield* feed.fetch({ cursor, selected }).pipe(recordFeedError(\"fetch\"));\n\n yield* Effect.forEach(\n members,\n (resource) =>\n ingestBatch({\n connector: connector.name,\n resource: resource.name,\n source: \"changes\",\n batch: {\n cursor: result.cursor,\n rows: result.rows[resource.name] ?? [],\n },\n }),\n { discard: true },\n ).pipe(recordFeedError(\"ingest\"));\n\n const lastSuccessAt = yield* DateTime.now.pipe(Effect.map(DateTime.formatIso));\n yield* Effect.forEach(\n members,\n (resource) =>\n Effect.withSpan(\n store\n .setChangesState(resource.name, {\n cursor: normalizeCursor(result.cursor),\n lastSuccessAt,\n })\n .pipe(\n Effect.andThen(\n Metrics.setLastSuccessTimestamp(\n { connector: connector.name, resource: resource.name, source: \"changes\" },\n lastSuccessAt,\n ),\n ),\n Effect.andThen(store.clearResourceError(resource.name, \"changes\")),\n Effect.tapError((error) => annotateError(\"state_set\", error)),\n ),\n SpanName.stateSet,\n { attributes: { [Attr.stateKey]: resource.name } },\n ),\n { discard: true },\n ).pipe(recordFeedError(\"checkpoint\"));\n\n yield* Effect.forEach(members, (resource, index) =>\n states[index]?.lastError?.source === \"changes\"\n ? refreshRuntimeStatus(connector, resource, initialCutoff)\n : Effect.void,\n );\n\n if (!result.hasMore) {\n yield* Effect.sleep(feed.interval ?? \"1 minute\");\n }\n }\n }).pipe(\n // Only typed errors park the feed. Defects and interruption still stop the runtime.\n Effect.catch((error) =>\n Effect.logError(\"Connector changes feed parked\", error).pipe(\n Effect.annotateLogs({\n [Attr.connectorName]: connector.name,\n resources: feed.resources.map((resource) => resource.name).join(\",\"),\n }),\n Effect.andThen(Effect.never),\n ),\n ),\n );\n","export { run, type RunOptions } from \"./engine\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ingestion-DoCUwm5N.mjs","names":["Metrics.setWebhookQueueDepth","Metrics.setSyncState","Metrics.setLastSuccessTimestamp","Arr"],"sources":["../src/ingestion/engine.ts","../src/ingestion/index.ts"],"sourcesContent":["import { Array as Arr, DateTime, Effect, Layer, Order, Queue } from \"effect\";\nimport { HttpRouter, type HttpServer, HttpServerResponse } from \"effect/http\";\nimport * as Observability from \"effect/observability\";\n\nimport type {\n ChangesFeed,\n ConnectorDefinition,\n Cursor,\n ResourceDefinition,\n ResourceState,\n WebhookRoute,\n} from \"../core/types\";\nimport type { StateOperation, StateSource } from \"../state-store/schema\";\n\nimport { ConnectorError } from \"../errors\";\nimport { ingestBatch } from \"../ingestor/instrumented\";\nimport { Ingestor } from \"../ingestor/service\";\nimport * as Metrics from \"../metrics\";\nimport { StateStore } from \"../state-store\";\nimport { deriveSyncState, hasChanges, normalizeCursor } from \"../state-store/state\";\nimport { statusRoute } from \"../status\";\nimport { Attr, SpanName, annotateError } from \"../telemetry\";\nimport { router, WebhookQueue, type QueuedWebhookBatch } from \"../webhook/server\";\n\ntype RunBaseOptions = {\n readonly initialCutoff?: Cursor.Value;\n};\n\nexport type RunOptions = RunBaseOptions & {\n readonly webhook?: {\n readonly routes: ReadonlyArray<WebhookRoute>;\n readonly healthPath?: HttpRouter.PathInput;\n readonly metricsPath?: HttpRouter.PathInput | false;\n readonly statusPath?: HttpRouter.PathInput | false;\n readonly disableHttpLogger?: boolean;\n };\n};\n\ntype RunNoWebhookOptions = RunBaseOptions & {\n readonly webhook?: undefined;\n};\n\ntype RunWebhookOptions = RunOptions & {\n readonly webhook: NonNullable<RunOptions[\"webhook\"]>;\n};\n\n/**\n * Runs all connector ingestion loops. Callers provide the Ingestor and\n * StateStore layers; webhook mode additionally requires an HttpServer layer.\n */\nexport function run<const Resources extends ReadonlyArray<ResourceDefinition>>(\n connector: ConnectorDefinition<Resources>,\n options?: RunNoWebhookOptions,\n): Effect.Effect<void, ConnectorError, StateStore | Ingestor>;\nexport function run<const Resources extends ReadonlyArray<ResourceDefinition>>(\n connector: ConnectorDefinition<Resources>,\n options: RunWebhookOptions,\n): Effect.Effect<void, ConnectorError, StateStore | Ingestor | HttpServer.HttpServer>;\nexport function run(definition: ConnectorDefinition, options?: RunOptions) {\n return Effect.gen(function* () {\n // Check the whole feed, even the resources that don't run.\n if (definition.changes) yield* validateFeed(definition, definition.changes);\n const ingestor = yield* Ingestor;\n const connector = selectResources(definition, ingestor.resourceNames);\n const queueLayer = makeWebhookQueueLayer(connector.name);\n const runtimeLayer = options?.webhook\n ? Layer.mergeAll(\n queueLayer,\n makeWebhookServerLayer(connector, options.webhook).pipe(Layer.provide(queueLayer)),\n )\n : Layer.empty;\n\n return yield* Effect.gen(function* () {\n const initialCutoff =\n options?.initialCutoff ?? (yield* DateTime.now.pipe(Effect.map(DateTime.formatIso)));\n yield* Effect.logInfo(\"Connector started\").pipe(\n Effect.annotateLogs({\n [Attr.connectorName]: connector.name,\n resources: connector.resources.length,\n }),\n );\n\n const sourceRun = runIngestion(connector, initialCutoff);\n const webhookRun = options?.webhook\n ? runWebhookRuntime(connector, options.webhook.routes)\n : Effect.void;\n\n return yield* Effect.all([sourceRun, webhookRun], { concurrency: \"unbounded\" }).pipe(\n Effect.asVoid,\n );\n }).pipe(Effect.provide(runtimeLayer));\n });\n}\n\nconst selectResources = (\n connector: ConnectorDefinition,\n names: ReadonlyArray<string> | undefined,\n): ConnectorDefinition => {\n if (names === undefined) return connector;\n const isSelected = (resource: ResourceDefinition) => names.includes(resource.name);\n const { changes, ...rest } = connector;\n const feedResources = changes?.resources.filter(isSelected) ?? [];\n return {\n ...rest,\n resources: connector.resources.filter(isSelected),\n ...(changes && feedResources.length > 0\n ? { changes: { ...changes, resources: feedResources } }\n : {}),\n };\n};\n\nconst makeWebhookQueueLayer = (connector: string): Layer.Layer<WebhookQueue> =>\n Layer.effect(WebhookQueue)(\n Effect.gen(function* () {\n const queue = yield* Queue.bounded<QueuedWebhookBatch>(1024);\n yield* Metrics.setWebhookQueueDepth(connector, 0);\n return WebhookQueue.of({ queue });\n }),\n );\n\nconst runWebhookRuntime = (connector: ConnectorDefinition, routes: ReadonlyArray<WebhookRoute>) => {\n const hasAfterEnqueue = routes.some((route) => route.ackMode === \"after-enqueue\");\n return Effect.all(\n [hasAfterEnqueue ? runWebhookQueueConsumer(connector) : Effect.void, Effect.never],\n {\n concurrency: \"unbounded\",\n },\n ).pipe(Effect.asVoid);\n};\n\nconst runWebhookQueueConsumer = (connector: ConnectorDefinition) =>\n Effect.gen(function* () {\n const queue = yield* WebhookQueue;\n while (true) {\n const batch = yield* Queue.take(queue.queue);\n const depth = yield* Queue.size(queue.queue);\n yield* Metrics.setWebhookQueueDepth(connector.name, depth);\n yield* ingestBatch({\n connector: connector.name,\n resource: batch.resource,\n source: \"webhook\",\n batch: batch.batch,\n });\n }\n });\n\nconst makeWebhookServerLayer = (\n connector: ConnectorDefinition,\n options: {\n readonly routes: ReadonlyArray<WebhookRoute>;\n readonly healthPath?: HttpRouter.PathInput;\n readonly metricsPath?: HttpRouter.PathInput | false;\n readonly statusPath?: HttpRouter.PathInput | false;\n readonly disableHttpLogger?: boolean;\n },\n): Layer.Layer<never, never, HttpServer.HttpServer> => {\n const healthPath: HttpRouter.PathInput = options.healthPath ?? \"/health\";\n const metricsPath = options.metricsPath === undefined ? \"/metrics\" : options.metricsPath;\n const statusPath = options.statusPath === undefined ? \"/status\" : options.statusPath;\n const app = Layer.mergeAll(\n router(options.routes, {\n connectorName: connector.name,\n resourceNames: connector.resources.map((resource) => resource.name),\n }),\n HttpRouter.add(\"GET\", healthPath, Effect.succeed(HttpServerResponse.text(\"ok\"))),\n ...(metricsPath === false\n ? []\n : [Observability.PrometheusMetrics.layerHttp({ path: metricsPath })]),\n ...(statusPath === false ? [] : [statusRoute(connector, statusPath)]),\n );\n\n return HttpRouter.serve(app, {\n disableLogger: options.disableHttpLogger ?? true,\n });\n};\n\nconst runIngestion = (\n connector: ConnectorDefinition,\n initialCutoff: Cursor.Value,\n): Effect.Effect<void, ConnectorError, StateStore | Ingestor> =>\n Effect.gen(function* () {\n const feed = connector.changes;\n yield* Effect.all(\n [\n Effect.forEach(\n connector.resources,\n (resource) => runResourceSources(connector, resource, initialCutoff),\n { concurrency: \"unbounded\" },\n ),\n feed ? runChangesFeed(connector, feed, initialCutoff) : Effect.void,\n ],\n { concurrency: \"unbounded\" },\n );\n });\n\nconst bySavedAt = Order.mapInput(\n Order.String,\n (state: NonNullable<ResourceState[\"changes\"]>) => state.lastSuccessAt ?? \"\",\n);\n\nconst validateFeed = (connector: ConnectorDefinition, feed: ChangesFeed) =>\n Effect.forEach(feed.resources, (member, index) => {\n if (feed.resources.findIndex((item) => item.name === member.name) !== index) {\n return Effect.fail(\n new ConnectorError({ message: `Resource ${member.name} is in the changes feed twice` }),\n );\n }\n const resource = connector.resources.find((item) => item.name === member.name);\n if (!resource) {\n return Effect.fail(\n new ConnectorError({\n message: `Changes feed resource ${member.name} is not a resource of connector ${connector.name}`,\n }),\n );\n }\n if (resource.changes) {\n return Effect.fail(\n new ConnectorError({\n message: `Resource ${member.name} has its own changes and is also in the changes feed`,\n }),\n );\n }\n return Effect.void;\n }).pipe(\n Effect.andThen(\n feed.resources.length === 0\n ? Effect.fail(new ConnectorError({ message: \"The changes feed has no resources\" }))\n : Effect.void,\n ),\n );\n\nconst initializeResourceState = (\n existing: ResourceState | undefined,\n initialCutoff: Cursor.Value,\n): ResourceState => ({\n ...existing,\n changes: existing?.changes ?? { cursor: initialCutoff },\n backfill: existing?.backfill ?? {\n cutoff: initialCutoff,\n completed: false,\n },\n});\n\nconst getInitializedState = Effect.fnUntraced(function* (\n resource: string,\n initialCutoff: Cursor.Value,\n) {\n const store = yield* StateStore;\n const existing = yield* store.getResourceState(resource);\n return initializeResourceState(existing, initialCutoff);\n});\n\nconst runResourceSources = (\n connector: ConnectorDefinition,\n resource: ResourceDefinition,\n initialCutoff: Cursor.Value,\n) => {\n const runs = [\n resource.backfill\n ? isolateSourceFailure(\n runBackfill(connector, resource, initialCutoff),\n connector,\n resource,\n \"backfill\",\n )\n : Effect.void,\n resource.changes\n ? isolateSourceFailure(\n runChanges(connector, resource, initialCutoff),\n connector,\n resource,\n \"changes\",\n )\n : Effect.void,\n ];\n\n return initializeRuntimeStatus(connector, resource, initialCutoff).pipe(\n Effect.andThen(Effect.all(runs, { concurrency: \"unbounded\" })),\n Effect.asVoid,\n Effect.catch((error) =>\n Metrics.setSyncState({ connector: connector.name, resource: resource.name }, \"error\").pipe(\n Effect.andThen(Effect.logError(\"Connector resource initialization failed\", error)),\n Effect.annotateLogs({\n [Attr.connectorName]: connector.name,\n resource: resource.name,\n }),\n Effect.andThen(Effect.never),\n ),\n ),\n );\n};\n\nconst recordResourceError =\n (\n connector: ConnectorDefinition,\n resource: ResourceDefinition,\n source: StateSource,\n operation: StateOperation,\n ) =>\n <A, R>(\n effect: Effect.Effect<A, ConnectorError, R>,\n ): Effect.Effect<A, ConnectorError, R | StateStore> =>\n effect.pipe(\n Effect.tapError(() =>\n Metrics.setSyncState({ connector: connector.name, resource: resource.name }, \"error\").pipe(\n Effect.andThen(\n StateStore.pipe(\n Effect.flatMap((store) => store.setResourceError(resource.name, source, operation)),\n ),\n ),\n ),\n ),\n );\n\nconst isolateSourceFailure = <A, R>(\n effect: Effect.Effect<A, ConnectorError, R>,\n connector: ConnectorDefinition,\n resource: ResourceDefinition,\n source: StateSource,\n): Effect.Effect<A, never, R> =>\n // Only typed source errors are isolated. Defects and interruption still stop the runtime.\n effect.pipe(\n Effect.catch((error) =>\n Effect.logError(\"Connector source parked\", error).pipe(\n Effect.annotateLogs({\n [Attr.connectorName]: connector.name,\n resource: resource.name,\n source,\n }),\n Effect.andThen(Effect.never),\n ),\n ),\n );\n\nconst refreshRuntimeStatus = Effect.fnUntraced(function* (\n connector: ConnectorDefinition,\n resource: ResourceDefinition,\n initialCutoff: Cursor.Value,\n) {\n const state = yield* getInitializedState(resource.name, initialCutoff);\n yield* Metrics.setSyncState(\n { connector: connector.name, resource: resource.name },\n deriveSyncState(connector, resource, state),\n );\n\n return state;\n});\n\nconst initializeRuntimeStatus = Effect.fnUntraced(function* (\n connector: ConnectorDefinition,\n resource: ResourceDefinition,\n initialCutoff: Cursor.Value,\n) {\n const state = yield* getInitializedState(resource.name, initialCutoff);\n yield* Metrics.setSyncState(\n { connector: connector.name, resource: resource.name },\n deriveSyncState(connector, resource, state),\n );\n\n if (resource.backfill) {\n yield* Metrics.setLastSuccessTimestamp(\n { connector: connector.name, resource: resource.name, source: \"backfill\" },\n state.backfill?.lastSuccessAt,\n );\n }\n if (hasChanges(connector, resource)) {\n yield* Metrics.setLastSuccessTimestamp(\n { connector: connector.name, resource: resource.name, source: \"changes\" },\n state.changes?.lastSuccessAt,\n );\n }\n});\n\nconst runBackfill = Effect.fnUntraced(function* (\n connector: ConnectorDefinition,\n resource: ResourceDefinition,\n initialCutoff: Cursor.Value,\n) {\n if (!resource.backfill) return;\n const store = yield* StateStore;\n let state = yield* getInitializedState(resource.name, initialCutoff);\n\n if (state.backfill?.completed === true) {\n // The checkpoint may have committed before the previous process cleared\n // its error marker. It may also be hidden by a newer changes error.\n yield* store\n .clearResourceError(resource.name, \"backfill\")\n .pipe(recordResourceError(connector, resource, \"backfill\", \"checkpoint\"));\n yield* refreshRuntimeStatus(connector, resource, initialCutoff);\n return;\n }\n\n while (state.backfill?.completed !== true) {\n const backfill = state.backfill ?? { cutoff: initialCutoff, completed: false };\n const clearsVisibleError = state.lastError?.source === \"backfill\";\n const page = yield* resource.backfill\n .fetch({\n pageCursor: backfill.pageCursor,\n cutoff: backfill.cutoff,\n })\n .pipe(recordResourceError(connector, resource, \"backfill\", \"fetch\"));\n\n yield* ingestBatch({\n connector: connector.name,\n resource: resource.name,\n source: \"backfill\",\n batch: {\n cursor: page.nextPageCursor ?? backfill.cutoff,\n rows: page.rows,\n },\n }).pipe(recordResourceError(connector, resource, \"backfill\", \"ingest\"));\n\n const lastSuccessAt = yield* DateTime.now.pipe(Effect.map(DateTime.formatIso));\n state = {\n ...state,\n backfill: {\n cutoff: backfill.cutoff,\n pageCursor: page.nextPageCursor,\n completed: !page.hasMore,\n lastSuccessAt,\n },\n };\n\n // Checkpoint only after ingestion succeeds so a crash cannot skip an\n // unacknowledged page; replay therefore remains at-least-once.\n yield* Effect.withSpan(\n store\n .setBackfillState(resource.name, {\n cutoff: normalizeCursor(backfill.cutoff),\n pageCursor:\n page.nextPageCursor === undefined ? undefined : normalizeCursor(page.nextPageCursor),\n completed: !page.hasMore,\n lastSuccessAt,\n })\n .pipe(\n Effect.andThen(\n Metrics.setLastSuccessTimestamp(\n { connector: connector.name, resource: resource.name, source: \"backfill\" },\n lastSuccessAt,\n ),\n ),\n Effect.andThen(store.clearResourceError(resource.name, \"backfill\")),\n Effect.tapError((error) => annotateError(\"state_set\", error)),\n ),\n SpanName.stateSet,\n { attributes: { [Attr.stateKey]: resource.name } },\n ).pipe(recordResourceError(connector, resource, \"backfill\", \"checkpoint\"));\n\n // Completion or clearing an error can change the resource-wide sync state.\n if (clearsVisibleError || !page.hasMore) {\n state = yield* refreshRuntimeStatus(connector, resource, initialCutoff);\n }\n }\n});\n\nconst runChanges = Effect.fnUntraced(function* (\n connector: ConnectorDefinition,\n resource: ResourceDefinition,\n initialCutoff: Cursor.Value,\n) {\n if (!resource.changes) return;\n const store = yield* StateStore;\n\n while (true) {\n const state = yield* getInitializedState(resource.name, initialCutoff);\n const cursor = state.changes?.cursor ?? initialCutoff;\n const clearsVisibleError = state.lastError?.source === \"changes\";\n const page = yield* resource.changes\n .fetch({ cursor })\n .pipe(recordResourceError(connector, resource, \"changes\", \"fetch\"));\n\n yield* ingestBatch({\n connector: connector.name,\n resource: resource.name,\n source: \"changes\",\n batch: {\n cursor: page.cursor,\n rows: page.rows,\n },\n }).pipe(recordResourceError(connector, resource, \"changes\", \"ingest\"));\n\n const lastSuccessAt = yield* DateTime.now.pipe(Effect.map(DateTime.formatIso));\n // Advance the durable cursor only after the engine acknowledges the page.\n yield* Effect.withSpan(\n store\n .setChangesState(resource.name, {\n cursor: normalizeCursor(page.cursor),\n lastSuccessAt,\n })\n .pipe(\n Effect.andThen(\n Metrics.setLastSuccessTimestamp(\n { connector: connector.name, resource: resource.name, source: \"changes\" },\n lastSuccessAt,\n ),\n ),\n Effect.andThen(store.clearResourceError(resource.name, \"changes\")),\n Effect.tapError((error) => annotateError(\"state_set\", error)),\n ),\n SpanName.stateSet,\n { attributes: { [Attr.stateKey]: resource.name } },\n ).pipe(recordResourceError(connector, resource, \"changes\", \"checkpoint\"));\n\n if (clearsVisibleError) {\n yield* refreshRuntimeStatus(connector, resource, initialCutoff);\n }\n\n if (!page.hasMore) {\n yield* Effect.sleep(resource.changes.interval ?? \"1 minute\");\n }\n }\n});\n\n// Every member resource stores the feed cursor. All rows are ingested before any\n// cursor is written. If a crash stops the writes partway, the next run starts\n// from the oldest cursor.\nconst runChangesFeed = (\n connector: ConnectorDefinition,\n feed: ChangesFeed,\n initialCutoff: Cursor.Value,\n): Effect.Effect<void, never, StateStore | Ingestor> =>\n Effect.gen(function* () {\n const store = yield* StateStore;\n const members = feed.resources;\n const selected = new Set(members.map((resource) => resource.name));\n // Any failure stops the whole feed, so it is an error for every resource in it.\n const recordFeedError =\n (operation: StateOperation) =>\n <A, R>(effect: Effect.Effect<A, ConnectorError, R>) =>\n effect.pipe(\n Effect.tapError(() =>\n Effect.forEach(\n members,\n (resource) =>\n Metrics.setSyncState(\n { connector: connector.name, resource: resource.name },\n \"error\",\n ).pipe(Effect.andThen(store.setResourceError(resource.name, \"changes\", operation))),\n { discard: true },\n ),\n ),\n );\n\n while (true) {\n const states = yield* Effect.forEach(members, (resource) =>\n store.getResourceState(resource.name),\n );\n // A resource that was off has an older cursor. Resume from the oldest, so it\n // gets the changes it missed. The others read some changes again.\n const saved = states.flatMap((state) => (state?.changes ? [state.changes] : []));\n const cursor = Arr.isReadonlyArrayNonEmpty(saved)\n ? Arr.min(saved, bySavedAt).cursor\n : initialCutoff;\n const result = yield* feed.fetch({ cursor, selected }).pipe(recordFeedError(\"fetch\"));\n\n yield* Effect.forEach(\n members,\n (resource) =>\n ingestBatch({\n connector: connector.name,\n resource: resource.name,\n source: \"changes\",\n batch: {\n cursor: result.cursor,\n rows: result.rows[resource.name] ?? [],\n },\n }),\n { discard: true },\n ).pipe(recordFeedError(\"ingest\"));\n\n const lastSuccessAt = yield* DateTime.now.pipe(Effect.map(DateTime.formatIso));\n yield* Effect.forEach(\n members,\n (resource) =>\n Effect.withSpan(\n store\n .setChangesState(resource.name, {\n cursor: normalizeCursor(result.cursor),\n lastSuccessAt,\n })\n .pipe(\n Effect.andThen(\n Metrics.setLastSuccessTimestamp(\n { connector: connector.name, resource: resource.name, source: \"changes\" },\n lastSuccessAt,\n ),\n ),\n Effect.andThen(store.clearResourceError(resource.name, \"changes\")),\n Effect.tapError((error) => annotateError(\"state_set\", error)),\n ),\n SpanName.stateSet,\n { attributes: { [Attr.stateKey]: resource.name } },\n ),\n { discard: true },\n ).pipe(recordFeedError(\"checkpoint\"));\n\n yield* Effect.forEach(members, (resource, index) =>\n states[index]?.lastError?.source === \"changes\"\n ? refreshRuntimeStatus(connector, resource, initialCutoff)\n : Effect.void,\n );\n\n if (!result.hasMore) {\n yield* Effect.sleep(feed.interval ?? \"1 minute\");\n }\n }\n }).pipe(\n // Only typed errors park the feed. Defects and interruption still stop the runtime.\n Effect.catch((error) =>\n Effect.logError(\"Connector changes feed parked\", error).pipe(\n Effect.annotateLogs({\n [Attr.connectorName]: connector.name,\n resources: feed.resources.map((resource) => resource.name).join(\",\"),\n }),\n Effect.andThen(Effect.never),\n ),\n ),\n );\n","export { run, type RunOptions } from \"./engine\";\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as IngestorService, i as Ingestor, n as IngestResult, r as IngestSource, t as IngestOptions } from "../service-
|
|
2
|
-
import { a as layerConsole, i as
|
|
3
|
-
export { type IngestOptions, type IngestResult, type IngestSource, Ingestor, type IngestorService,
|
|
1
|
+
import { a as IngestorService, i as Ingestor, n as IngestResult, r as IngestSource, t as IngestOptions } from "../service-BRoy_EId.mjs";
|
|
2
|
+
import { a as layerConsole, i as layerArrowFlightConfig, n as ArrowFlightIngestorConfig, r as layerArrowFlight } from "../index-uFa2wwYo.mjs";
|
|
3
|
+
export { type ArrowFlightIngestorConfig, type IngestOptions, type IngestResult, type IngestSource, Ingestor, type IngestorService, layerArrowFlight, layerArrowFlightConfig, layerConsole };
|
package/dist/ingestor/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as layerWingsConfig, t as layerWings } from "../wings-I56hGtNv.mjs";
|
|
2
1
|
import { t as Ingestor } from "../service-jWxxfEht.mjs";
|
|
3
|
-
import { n as
|
|
4
|
-
|
|
2
|
+
import { n as layerArrowFlightConfig, t as layerArrowFlight } from "../arrow-flight-DDQ0ktx9.mjs";
|
|
3
|
+
import { n as layerConsole } from "../ingestor-DjCEzBzZ.mjs";
|
|
4
|
+
export { Ingestor, layerArrowFlight, layerArrowFlightConfig, layerConsole };
|