@useairfoil/connector-kit 0.6.0 → 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 +38 -42
- package/README.md +111 -444
- package/dist/annotations-vzSzXtr-.d.mts +34 -0
- package/dist/arrow-flight-DDQ0ktx9.mjs +251 -0
- package/dist/arrow-flight-DDQ0ktx9.mjs.map +1 -0
- package/dist/auth/index.d.mts +2 -0
- package/dist/{auth-DvU_CZ7C.js → auth/index.mjs} +6 -8
- package/dist/auth/index.mjs.map +1 -0
- package/dist/connector-app/index.d.mts +2 -0
- package/dist/connector-app/index.mjs +2 -0
- package/dist/connector-app-C6_dZnhE.mjs +256 -0
- package/dist/connector-app-C6_dZnhE.mjs.map +1 -0
- package/dist/{constants-D113Ut1x.js → constants-v3UX-hf6.mjs} +5 -5
- package/dist/constants-v3UX-hf6.mjs.map +1 -0
- package/dist/demo/index.d.mts +2 -0
- package/dist/demo/index.mjs +2 -0
- package/dist/demo-DqTJ7TWI.mjs +204 -0
- package/dist/demo-DqTJ7TWI.mjs.map +1 -0
- package/dist/errors/index.d.mts +2 -0
- package/dist/errors/index.mjs +2 -0
- package/dist/{errors-DHWylqRZ.js → errors-pT0YVJU5.mjs} +2 -3
- package/dist/errors-pT0YVJU5.mjs.map +1 -0
- package/dist/iceberg/index.d.mts +3 -0
- package/dist/iceberg/index.mjs +3 -0
- package/dist/iceberg-Cj2PwlNm.mjs +30 -0
- package/dist/iceberg-Cj2PwlNm.mjs.map +1 -0
- package/dist/index-BTAbexBp.d.mts +55 -0
- package/dist/{index-DXa26Ry5.d.ts → index-BX8G7d41.d.mts} +1 -2
- package/dist/{index-VpHaZXZw.d.ts → index-Byr8NTdG.d.mts} +11 -13
- package/dist/index-CV6V6fyx.d.mts +79 -0
- package/dist/{index-C5Ma7V7t.d.ts → index-CZKx2Yce.d.mts} +72 -37
- package/dist/{index-DYpEMJf-.d.ts → index-CgvFomO6.d.mts} +6 -7
- package/dist/{index-bfjH7Yb0.d.ts → index-DeTwIUKl.d.mts} +9 -10
- package/dist/{index-DKoRwyFn.d.ts → index-DkVNO6ks.d.mts} +2 -5
- package/dist/{index-BKw7jA2a.d.ts → index-dHS59EZl.d.mts} +10 -8
- package/dist/{index-CR9HJDdr.d.ts → index-eFuoMZZ3.d.mts} +18 -20
- package/dist/{index-ZSuiZX5H.d.ts → index-fHIJJoRe.d.mts} +25 -30
- package/dist/index-uFa2wwYo.d.mts +27 -0
- package/dist/index.d.mts +16 -0
- package/dist/index.mjs +45 -0
- package/dist/index.mjs.map +1 -0
- package/dist/ingestion/index.d.mts +2 -0
- package/dist/ingestion/index.mjs +2 -0
- package/dist/ingestion-DoCUwm5N.mjs +275 -0
- package/dist/ingestion-DoCUwm5N.mjs.map +1 -0
- package/dist/ingestor/index.d.mts +3 -0
- package/dist/ingestor/index.mjs +4 -0
- package/dist/ingestor-DjCEzBzZ.mjs +26 -0
- package/dist/ingestor-DjCEzBzZ.mjs.map +1 -0
- package/dist/instrumented-Bq1WX2L5.mjs +29 -0
- package/dist/instrumented-Bq1WX2L5.mjs.map +1 -0
- package/dist/manifest/index.d.mts +2 -0
- package/dist/manifest/{index.js → index.mjs} +2 -4
- package/dist/{manifest-P7kBnch9.js → manifest-CABeIhAG.mjs} +14 -19
- package/dist/manifest-CABeIhAG.mjs.map +1 -0
- package/dist/{telemetry-j_nxwYfh.js → metrics-C901IIYZ.mjs} +172 -26
- package/dist/metrics-C901IIYZ.mjs.map +1 -0
- package/dist/{metrics-C4V1pm6v.d.ts → metrics-DoJ0WeKu.d.mts} +18 -13
- package/dist/metrics.d.mts +2 -0
- package/dist/metrics.mjs +2 -0
- package/dist/{chunk-Bp6m_JJh.js → rolldown-runtime-D7D4PA-g.mjs} +4 -4
- package/dist/runtime-config/index.d.mts +2 -0
- package/dist/runtime-config/index.mjs +3 -0
- package/dist/runtime-config-Bn8Fivt1.mjs +100 -0
- package/dist/runtime-config-Bn8Fivt1.mjs.map +1 -0
- package/dist/server-D1TTN0_D.mjs +144 -0
- package/dist/server-D1TTN0_D.mjs.map +1 -0
- package/dist/service-BRoy_EId.d.mts +27 -0
- package/dist/service-jWxxfEht.mjs +7 -0
- package/dist/service-jWxxfEht.mjs.map +1 -0
- package/dist/state-store/index.d.mts +2 -0
- package/dist/state-store/index.mjs +2 -0
- package/dist/{state-store-BdYulQOY.js → state-store-DhSrKVEH.mjs} +15 -22
- package/dist/state-store-DhSrKVEH.mjs.map +1 -0
- package/dist/status/{index.d.ts → index.d.mts} +1 -4
- package/dist/status/{index.js → index.mjs} +2 -6
- package/dist/{status-BTTd7AUR.js → status-4h6Oxh-O.mjs} +14 -16
- package/dist/status-4h6Oxh-O.mjs.map +1 -0
- package/dist/table-CxM09xf7.mjs +307 -0
- package/dist/table-CxM09xf7.mjs.map +1 -0
- package/dist/types-NtSv6gwl.d.mts +220 -0
- package/dist/webhook/index.d.mts +3 -0
- package/dist/webhook/index.mjs +12 -0
- package/dist/webhook/index.mjs.map +1 -0
- package/package.json +72 -58
- package/src/catalog/retry.ts +25 -0
- package/src/catalog/table.ts +237 -0
- package/src/connector-app/create-table.ts +47 -0
- package/src/connector-app/demo.ts +47 -0
- package/src/connector-app/index.ts +3 -0
- package/src/connector-app/setup.ts +69 -0
- package/src/connector-app/start.ts +1 -1
- package/src/core/builder.ts +15 -23
- package/src/core/index.ts +11 -1
- package/src/core/types.ts +114 -39
- package/src/demo/definition.ts +68 -0
- package/src/demo/generate.ts +167 -0
- package/src/demo/index.ts +3 -0
- package/src/demo/run.ts +172 -0
- package/src/iceberg/annotations.ts +49 -0
- package/src/iceberg/error.ts +9 -0
- package/src/iceberg/index.ts +3 -0
- package/src/iceberg/table.ts +461 -0
- package/src/index.ts +3 -1
- package/src/ingestion/engine.ts +240 -60
- package/src/ingestor/arrow-flight.ts +141 -0
- package/src/ingestor/arrow.ts +248 -0
- package/src/ingestor/console.ts +13 -0
- package/src/ingestor/index.ts +13 -0
- package/src/ingestor/instrumented.ts +61 -0
- package/src/ingestor/service.ts +30 -0
- package/src/manifest/config.ts +3 -3
- package/src/metrics.ts +66 -20
- package/src/runtime-config/config.ts +11 -8
- package/src/runtime-config/constants.ts +3 -2
- package/src/runtime-config/index.ts +2 -7
- package/src/runtime-config/layer.ts +1 -1
- package/src/runtime-config/table-bindings.ts +50 -136
- package/src/state-store/layer-key-value-store.ts +8 -3
- package/src/state-store/layer-memory.ts +1 -1
- package/src/state-store/layer-sql.ts +4 -4
- package/src/state-store/schema.ts +2 -2
- package/src/state-store/state.ts +14 -2
- package/src/status/route.ts +2 -2
- package/src/telemetry.ts +20 -28
- package/src/webhook/server.ts +39 -40
- package/dist/auth/index.d.ts +0 -2
- package/dist/auth/index.js +0 -3
- package/dist/auth-DvU_CZ7C.js.map +0 -1
- package/dist/connector-app/index.d.ts +0 -14
- package/dist/connector-app/index.js +0 -12
- package/dist/connector-app-BljHd0Pe.js +0 -64
- package/dist/connector-app-BljHd0Pe.js.map +0 -1
- package/dist/constants-D113Ut1x.js.map +0 -1
- package/dist/errors/index.d.ts +0 -2
- package/dist/errors/index.js +0 -3
- package/dist/errors-DHWylqRZ.js.map +0 -1
- package/dist/index-BA8ASHKr.d.ts +0 -31
- package/dist/index.d.ts +0 -14
- package/dist/index.js +0 -60
- package/dist/index.js.map +0 -1
- package/dist/ingestion/index.d.ts +0 -6
- package/dist/ingestion/index.js +0 -11
- package/dist/ingestion-QBGKrFr9.js +0 -200
- package/dist/ingestion-QBGKrFr9.js.map +0 -1
- package/dist/manifest/index.d.ts +0 -2
- package/dist/manifest-P7kBnch9.js.map +0 -1
- package/dist/metrics-inkCAxKq.js +0 -136
- package/dist/metrics-inkCAxKq.js.map +0 -1
- package/dist/metrics.d.ts +0 -4
- package/dist/metrics.js +0 -5
- package/dist/publisher/index.d.ts +0 -6
- package/dist/publisher/index.js +0 -8
- package/dist/publisher-BdWJOfer.js +0 -138
- package/dist/publisher-BdWJOfer.js.map +0 -1
- package/dist/runtime-config/index.d.ts +0 -4
- package/dist/runtime-config/index.js +0 -5
- package/dist/runtime-config-IbyCVpei.js +0 -60
- package/dist/runtime-config-IbyCVpei.js.map +0 -1
- package/dist/server-D-eLX3yN.js +0 -183
- package/dist/server-D-eLX3yN.js.map +0 -1
- package/dist/service-CUjGhe-7.d.ts +0 -32
- package/dist/service-DiP-XETo.js +0 -8
- package/dist/service-DiP-XETo.js.map +0 -1
- package/dist/state-store/index.d.ts +0 -3
- package/dist/state-store/index.js +0 -5
- package/dist/state-store-BdYulQOY.js.map +0 -1
- package/dist/status-BTTd7AUR.js.map +0 -1
- package/dist/table-bindings-Dp1DhTeS.js +0 -106
- package/dist/table-bindings-Dp1DhTeS.js.map +0 -1
- package/dist/telemetry-j_nxwYfh.js.map +0 -1
- package/dist/types-jVD5Ys43.d.ts +0 -174
- package/dist/webhook/index.d.ts +0 -7
- package/dist/webhook/index.js +0 -9
- package/dist/webhook-MhFcLW-o.js +0 -13
- package/dist/webhook-MhFcLW-o.js.map +0 -1
- package/src/publisher/console.ts +0 -18
- package/src/publisher/index.ts +0 -7
- package/src/publisher/instrumented.ts +0 -75
- package/src/publisher/service.ts +0 -37
- package/src/publisher/wings.ts +0 -204
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server-D-eLX3yN.js","names":["Metrics.withResourceAttributes","Metrics.publishDuration","Metrics.batches","Metrics.entitiesUpserted","Metrics.entitiesDeleted","Metrics.batchSize","payload","batches","collected: Array<QueuedWebhookBatch>","Metrics.recordWebhookRequest","Metrics.setWebhookQueueDepth"],"sources":["../src/publisher/instrumented.ts","../src/webhook/server.ts"],"sourcesContent":["import { Effect, Metric } from \"effect\";\n\nimport type { ResourceBatch } from \"../core/types\";\n\nimport { ConnectorError } from \"../errors\";\nimport * as Metrics from \"../metrics\";\nimport { Attr, EventAttr, EventName, addCurrentSpanEvent } from \"../telemetry\";\nimport { Publisher, type PublishSource } from \"./service\";\n\nexport const publishBatch = Effect.fnUntraced(function* (options: {\n readonly connector?: string;\n readonly resource: string;\n readonly source: PublishSource;\n readonly batch: ResourceBatch;\n}) {\n const metric = {\n connector: options.connector ?? \"unknown\",\n resource: options.resource,\n source: options.source,\n };\n const metricAttributes = Metrics.withResourceAttributes(metric);\n const upserts = options.batch.mutations.filter((mutation) => mutation.op === \"upsert\").length;\n const deletes = options.batch.mutations.length - upserts;\n\n const publisher = yield* Publisher;\n const ack = yield* publisher\n .publish({\n resource: options.resource,\n source: options.source,\n batch: options.batch,\n })\n .pipe(\n Effect.trackDuration(Metric.withAttributes(Metrics.publishDuration, metricAttributes)),\n Effect.catchCause((cause) =>\n Metric.update(\n Metric.withAttributes(Metrics.batches, {\n ...metricAttributes,\n [Attr.batchOutcome]: \"error\",\n }),\n 1,\n ).pipe(Effect.andThen(Effect.failCause(cause))),\n ),\n );\n\n yield* Metric.update(\n Metric.withAttributes(Metrics.batches, {\n ...metricAttributes,\n [Attr.batchOutcome]: ack.status,\n }),\n 1,\n );\n\n yield* Effect.annotateCurrentSpan({ [Attr.publisherSuccess]: ack.status === \"accepted\" });\n if (ack.status === \"rejected\") {\n yield* Effect.annotateCurrentSpan({ [Attr.errorPhase]: \"publish\" });\n return yield* Effect.fail(\n new ConnectorError({\n message: `Publisher rejected batch for ${options.resource}: ${ack.reason}`,\n }),\n );\n }\n\n yield* Metric.update(Metric.withAttributes(Metrics.entitiesUpserted, metricAttributes), upserts);\n yield* Metric.update(Metric.withAttributes(Metrics.entitiesDeleted, metricAttributes), deletes);\n yield* Metric.update(\n Metric.withAttributes(Metrics.batchSize, metricAttributes),\n options.batch.mutations.length,\n );\n\n if (options.batch.cursor !== undefined) {\n yield* addCurrentSpanEvent(EventName.batchCheckpoint, {\n [EventAttr.batchCursor]: options.batch.cursor,\n });\n }\n});\n","import { Cause, Context, Effect, Queue, Schema } from \"effect\";\nimport { HttpRouter, HttpServerRequest, HttpServerResponse } from \"effect/unstable/http\";\n\nimport type {\n ResourceBatch,\n ResourceDefinition,\n ResourceMutation,\n WebhookHandler,\n WebhookRoute,\n WebhookRouteContext,\n} from \"../core/types\";\n\nimport { ConnectorError } from \"../errors\";\nimport * as Metrics from \"../metrics\";\nimport { publishBatch } from \"../publisher/instrumented\";\nimport { Attr, SpanName, annotateError } from \"../telemetry\";\n\nexport type QueuedWebhookBatch = {\n readonly resource: string;\n readonly batch: ResourceBatch;\n};\n\nexport class WebhookQueue extends Context.Service<\n WebhookQueue,\n {\n readonly queue: Queue.Queue<QueuedWebhookBatch>;\n }\n>()(\"@useairfoil/connector-kit/WebhookQueue\") {}\n\nconst resourceBatch = <Row extends object>(\n mutations: ReadonlyArray<ResourceMutation<Row>>,\n): ResourceBatch<Row> => ({\n mutations,\n});\n\nconst decodeAndHandleWebhook = <Row extends object, Payload>(\n resourceName: string,\n webhook: WebhookHandler<Row, Payload>,\n payload: unknown,\n) =>\n Schema.decodeUnknownEffect(webhook.schema)(payload).pipe(\n Effect.mapError(\n (cause) =>\n new ConnectorError({\n message: `Invalid webhook payload for resource ${resourceName}`,\n cause,\n }),\n ),\n Effect.flatMap((decoded) => webhook.handler({ payload: decoded })),\n );\n\nconst makeRouteContext = (\n request: HttpServerRequest.HttpServerRequest,\n rawBody: Uint8Array,\n payload: unknown,\n batches: Array<QueuedWebhookBatch>,\n): WebhookRouteContext<ReadonlyArray<ResourceDefinition>, unknown> => ({\n request,\n rawBody,\n payload,\n to: (resource, payload) =>\n Effect.gen(function* () {\n if (!resource.webhook) {\n return yield* Effect.fail(\n new ConnectorError({\n message: `Resource ${resource.name} does not define a webhook handler`,\n }),\n );\n }\n\n const mutations = yield* decodeAndHandleWebhook(resource.name, resource.webhook, payload);\n batches.push({\n resource: resource.name,\n batch: resourceBatch(mutations),\n });\n }),\n});\n\nconst compactBatches = (batches: ReadonlyArray<QueuedWebhookBatch>) => {\n const grouped = new Map<string, ResourceMutation[]>();\n for (const item of batches) {\n const current = grouped.get(item.resource) ?? [];\n grouped.set(item.resource, [...current, ...item.batch.mutations]);\n }\n return Array.from(grouped.entries()).map(([resource, mutations]) => ({\n resource,\n batch: resourceBatch(mutations),\n }));\n};\n\nconst publishBatches = (\n batches: ReadonlyArray<QueuedWebhookBatch>,\n options: { readonly connectorName: string },\n) =>\n Effect.gen(function* () {\n yield* Effect.forEach(\n batches,\n (batch) =>\n publishBatch({\n connector: options.connectorName,\n resource: batch.resource,\n source: \"webhook\",\n batch: batch.batch,\n }),\n { concurrency: \"unbounded\" },\n );\n });\n\nconst badRequest = (message: string) =>\n HttpServerResponse.jsonUnsafe({ ok: false, error: message }, { status: 400 });\n\nconst readRawBody = (request: HttpServerRequest.HttpServerRequest) =>\n request.arrayBuffer.pipe(Effect.map((buffer) => new Uint8Array(buffer)));\n\nconst parseJson = (rawBody: Uint8Array) =>\n Effect.try({\n try: () => JSON.parse(new TextDecoder().decode(rawBody)),\n catch: (cause) => new ConnectorError({ message: \"Invalid webhook JSON\", cause }),\n });\n\nconst makeHandler = (route: WebhookRoute, options: { readonly connectorName: string }) =>\n Effect.gen(function* () {\n const request = yield* HttpServerRequest.HttpServerRequest;\n const collected: Array<QueuedWebhookBatch> = [];\n\n const rawBodyResult = yield* readRawBody(request).pipe(\n Effect.match({\n onFailure: () => ({ _tag: \"Error\" as const, message: \"Failed to read webhook body\" }),\n onSuccess: (value) => ({ _tag: \"Success\" as const, value }),\n }),\n );\n if (rawBodyResult._tag === \"Error\") {\n yield* Metrics.recordWebhookRequest({\n connector: options.connectorName,\n path: String(route.path),\n outcome: \"read_error\",\n });\n return badRequest(rawBodyResult.message);\n }\n\n const jsonResult = yield* parseJson(rawBodyResult.value).pipe(\n Effect.match({\n onFailure: (error) => ({ _tag: \"Error\" as const, message: error.message }),\n onSuccess: (value) => ({ _tag: \"Success\" as const, value }),\n }),\n );\n if (jsonResult._tag === \"Error\") {\n yield* Metrics.recordWebhookRequest({\n connector: options.connectorName,\n path: String(route.path),\n outcome: \"invalid_json\",\n });\n return badRequest(jsonResult.message);\n }\n\n const payloadResult = yield* Schema.decodeUnknownEffect(route.schema)(jsonResult.value).pipe(\n Effect.match({\n onFailure: () => ({ _tag: \"Error\" as const, message: \"Invalid webhook payload\" }),\n onSuccess: (value) => ({ _tag: \"Success\" as const, value }),\n }),\n );\n if (payloadResult._tag === \"Error\") {\n yield* Metrics.recordWebhookRequest({\n connector: options.connectorName,\n path: String(route.path),\n outcome: \"invalid_payload\",\n });\n return badRequest(payloadResult.message);\n }\n\n const response = yield* Effect.withSpan(\n route\n .handler(makeRouteContext(request, rawBodyResult.value, payloadResult.value, collected))\n .pipe(Effect.tapError((error) => annotateError(\"webhook_handle\", error))),\n SpanName.webhookHandle,\n { attributes: { [Attr.webhookPath]: route.path } },\n );\n\n const batches = compactBatches(collected);\n\n if (route.ackMode === \"after-enqueue\") {\n const queue = yield* WebhookQueue;\n yield* Queue.offerAll(queue.queue, batches);\n const depth = yield* Queue.size(queue.queue);\n yield* Metrics.setWebhookQueueDepth(options.connectorName, depth);\n yield* Metrics.recordWebhookRequest({\n connector: options.connectorName,\n path: String(route.path),\n outcome: response.status >= 400 ? \"rejected\" : \"ok\",\n });\n return response;\n }\n\n yield* Effect.withSpan(\n publishBatches(batches, { connectorName: options.connectorName }).pipe(\n Effect.tapError((error) => annotateError(\"webhook_publish\", error)),\n ),\n SpanName.webhookHandle,\n { attributes: { [Attr.webhookPath]: route.path } },\n );\n\n yield* Metrics.recordWebhookRequest({\n connector: options.connectorName,\n path: String(route.path),\n outcome: response.status >= 400 ? \"rejected\" : \"ok\",\n });\n return response;\n }).pipe(\n Effect.catchCause((cause) =>\n Metrics.recordWebhookRequest({\n connector: options.connectorName,\n path: String(route.path),\n outcome: \"handler_error\",\n }).pipe(\n Effect.andThen(Effect.logWarning(`Webhook handler error: ${Cause.pretty(cause)}`)),\n Effect.andThen(\n Effect.succeed(\n HttpServerResponse.jsonUnsafe(\n { ok: false, error: \"Webhook handler failed\" },\n { status: 500 },\n ),\n ),\n ),\n ),\n ),\n );\n\nexport const router = (\n routes: ReadonlyArray<WebhookRoute>,\n options: { readonly connectorName: string },\n) =>\n HttpRouter.addAll(\n routes.map((route) => HttpRouter.route(\"POST\", route.path, makeHandler(route, options))),\n );\n"],"mappings":"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"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { t as ConnectorError } from "./index-DKoRwyFn.js";
|
|
2
|
-
import { c as ResourceBatch } from "./types-jVD5Ys43.js";
|
|
3
|
-
import { Context } from "effect";
|
|
4
|
-
import * as Wings from "@useairfoil/wings";
|
|
5
|
-
import * as Effect$1 from "effect/Effect";
|
|
6
|
-
|
|
7
|
-
//#region src/publisher/service.d.ts
|
|
8
|
-
type PublishSource = "backfill" | "changes" | "webhook";
|
|
9
|
-
type PublishAck = {
|
|
10
|
-
readonly status: "accepted";
|
|
11
|
-
readonly resource: string;
|
|
12
|
-
readonly partition?: Wings.PartitionValue.PartitionValue;
|
|
13
|
-
} | {
|
|
14
|
-
readonly status: "rejected";
|
|
15
|
-
readonly resource: string;
|
|
16
|
-
readonly reason: string;
|
|
17
|
-
readonly rejectedRows?: number;
|
|
18
|
-
readonly partition?: Wings.PartitionValue.PartitionValue;
|
|
19
|
-
};
|
|
20
|
-
type PublishOptions = {
|
|
21
|
-
readonly resource: string;
|
|
22
|
-
readonly source: PublishSource;
|
|
23
|
-
readonly batch: ResourceBatch;
|
|
24
|
-
};
|
|
25
|
-
interface PublisherService {
|
|
26
|
-
readonly publish: (options: PublishOptions) => Effect$1.Effect<PublishAck, ConnectorError>;
|
|
27
|
-
}
|
|
28
|
-
declare const Publisher_base: Context.ServiceClass<Publisher, "@useairfoil/connector-kit/Publisher", PublisherService>;
|
|
29
|
-
declare class Publisher extends Publisher_base {}
|
|
30
|
-
//#endregion
|
|
31
|
-
export { PublisherService as a, Publisher as i, PublishOptions as n, PublishSource as r, PublishAck as t };
|
|
32
|
-
//# sourceMappingURL=service-CUjGhe-7.d.ts.map
|
package/dist/service-DiP-XETo.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"service-DiP-XETo.js","names":[],"sources":["../src/publisher/service.ts"],"sourcesContent":["import type * as Wings from \"@useairfoil/wings\";\nimport type * as Effect from \"effect/Effect\";\n\nimport { Context } from \"effect\";\n\nimport type { ResourceBatch } from \"../core/types\";\nimport type { ConnectorError } from \"../errors\";\n\nexport type PublishSource = \"backfill\" | \"changes\" | \"webhook\";\n\nexport type PublishAck =\n | {\n readonly status: \"accepted\";\n readonly resource: string;\n readonly partition?: Wings.PartitionValue.PartitionValue;\n }\n | {\n readonly status: \"rejected\";\n readonly resource: string;\n readonly reason: string;\n readonly rejectedRows?: number;\n readonly partition?: Wings.PartitionValue.PartitionValue;\n };\n\nexport type PublishOptions = {\n readonly resource: string;\n readonly source: PublishSource;\n readonly batch: ResourceBatch;\n};\n\nexport interface PublisherService {\n readonly publish: (options: PublishOptions) => Effect.Effect<PublishAck, ConnectorError>;\n}\n\nexport class Publisher extends Context.Service<Publisher, PublisherService>()(\n \"@useairfoil/connector-kit/Publisher\",\n) {}\n"],"mappings":";;;AAkCA,IAAa,YAAb,cAA+B,QAAQ,SAAsC,CAC3E,sCACD,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"state-store-BdYulQOY.js","names":["layerKeyValueStore: Layer.Layer<StateStore, never, KeyValueStore.KeyValueStore>","layerMemory: Layer.Layer<StateStore>"],"sources":["../src/state-store/service.ts","../src/state-store/keys.ts","../src/state-store/schema.ts","../src/state-store/layer-key-value-store.ts","../src/state-store/layer-memory.ts","../src/state-store/layer-sql.ts","../src/state-store/index.ts"],"sourcesContent":["import { Context, Effect } from \"effect\";\n\nimport type {\n PersistedBackfillState,\n PersistedChangesState,\n PersistedResourceState,\n StateOperation,\n StateSource,\n} from \"./schema\";\n\nimport { ConnectorError } from \"../errors\";\n\n/** Connector-facing durable state operations, independent of the storage backend. */\nexport interface StateStoreService {\n readonly getResourceState: (\n resource: string,\n ) => Effect.Effect<PersistedResourceState | undefined, ConnectorError>;\n readonly setBackfillState: (\n resource: string,\n state: PersistedBackfillState,\n ) => Effect.Effect<void, ConnectorError>;\n readonly setChangesState: (\n resource: string,\n state: PersistedChangesState,\n ) => Effect.Effect<void, ConnectorError>;\n readonly setResourceError: (\n resource: string,\n source: StateSource,\n operation: StateOperation,\n ) => Effect.Effect<void, ConnectorError>;\n readonly clearResourceError: (\n resource: string,\n source: StateSource,\n ) => Effect.Effect<void, ConnectorError>;\n}\n\n/**\n * Effect service used by ingestion and status logic for connector checkpoints.\n * Production provides `layerSql`; sandboxes and tests may provide `layerMemory`.\n *\n * @example\n * ```ts\n * const program = Effect.gen(function* () {\n * const state = yield* StateStore;\n * yield* state.setChangesState(\"orders\", { cursor: \"next-page\" });\n * });\n * ```\n */\nexport class StateStore extends Context.Service<StateStore, StateStoreService>()(\n \"@useairfoil/connector-kit/StateStore\",\n) {}\n","import type { StateSource } from \"./schema\";\n\ntype StateComponent = StateSource | `error:${StateSource}`;\n\nexport const resourceComponentKey = (resource: string, component: StateComponent): string =>\n `resource:${resource}:${component}`;\n\nexport const resourceErrorKey = (resource: string, source: StateSource): string =>\n resourceComponentKey(resource, `error:${source}`);\n\n/**\n * Prefix for all state owned by one connector instance. The platform-owned ID\n * stays visible so operators can inspect and clean up shared-table rows directly.\n *\n * @example\n * ```ts\n * connectorInstanceKeyPrefix(\"team-a/orders\");\n * // \"connector-instance:team-a/orders:\"\n * ```\n */\nexport const connectorInstanceKeyPrefix = (connectorInstanceId: string): string =>\n `connector-instance:${connectorInstanceId}:`;\n","import { Schema } from \"effect\";\n\nconst CursorValueSchema = Schema.Union([Schema.String, Schema.Number]);\n\n/** Durable progress for a finite historical backfill. */\nexport const BackfillStateSchema = Schema.Struct({\n cutoff: CursorValueSchema,\n pageCursor: Schema.optional(CursorValueSchema),\n completed: Schema.Boolean,\n lastSuccessAt: Schema.optional(Schema.String),\n});\n\n/** Durable cursor for an ongoing incremental changes stream. */\nexport const ChangesStateSchema = Schema.Struct({\n cursor: CursorValueSchema,\n lastSuccessAt: Schema.optional(Schema.String),\n});\n\nexport const StateSourceSchema = Schema.Literals([\"backfill\", \"changes\"]);\n\nexport const StateOperationSchema = Schema.Literals([\"fetch\", \"publish\", \"checkpoint\"]);\n\nexport const StateErrorCodeSchema = Schema.Literals([\n \"fetch_failed\",\n \"publish_failed\",\n \"checkpoint_failed\",\n]);\n\n/** SDK-owned error context safe to persist and expose through status. */\nexport const ResourceErrorContextSchema = Schema.Struct({\n source: StateSourceSchema,\n operation: StateOperationSchema,\n code: StateErrorCodeSchema,\n message: Schema.String,\n});\n\n/** Stable public error summary persisted for status reporting; never a raw cause. */\nexport const ResourceErrorSchema = Schema.Struct({\n ...ResourceErrorContextSchema.fields,\n at: Schema.String,\n});\n\n/** Complete persisted state assembled from independently stored components. */\nexport const ResourceStateSchema = Schema.Struct({\n backfill: Schema.optional(BackfillStateSchema),\n changes: Schema.optional(ChangesStateSchema),\n lastError: Schema.optional(ResourceErrorSchema),\n});\n\nexport type PersistedBackfillState = Schema.Schema.Type<typeof BackfillStateSchema>;\nexport type PersistedChangesState = Schema.Schema.Type<typeof ChangesStateSchema>;\nexport type StateSource = Schema.Schema.Type<typeof StateSourceSchema>;\nexport type StateOperation = Schema.Schema.Type<typeof StateOperationSchema>;\nexport type StateErrorCode = Schema.Schema.Type<typeof StateErrorCodeSchema>;\nexport type ResourceErrorContext = Schema.Schema.Type<typeof ResourceErrorContextSchema>;\nexport type PersistedResourceError = Schema.Schema.Type<typeof ResourceErrorSchema>;\nexport type PersistedResourceState = Schema.Schema.Type<typeof ResourceStateSchema>;\n","import { DateTime, Effect, Layer, Option, Schema } from \"effect\";\nimport { KeyValueStore } from \"effect/unstable/persistence\";\n\nimport { ConnectorError } from \"../errors\";\nimport { resourceComponentKey, resourceErrorKey } from \"./keys\";\nimport {\n BackfillStateSchema,\n ChangesStateSchema,\n ResourceErrorSchema,\n type PersistedBackfillState,\n type PersistedChangesState,\n type PersistedResourceError,\n type ResourceErrorContext,\n type StateOperation,\n type StateSource,\n} from \"./schema\";\nimport { StateStore } from \"./service\";\n\nconst mapStoreError = (operation: \"read\" | \"write\" | \"clear\", resource: string) =>\n Effect.mapError(\n (cause: KeyValueStore.KeyValueStoreError | Schema.SchemaError) =>\n new ConnectorError({\n message: `Failed to ${operation} state for resource ${resource}`,\n cause,\n }),\n );\n\nconst resourceErrorContext = (\n source: StateSource,\n operation: StateOperation,\n): ResourceErrorContext => {\n const sourceName = source === \"backfill\" ? \"Backfill\" : \"Changes\";\n switch (operation) {\n case \"fetch\":\n return { source, operation, code: \"fetch_failed\", message: `${sourceName} fetch failed` };\n case \"publish\":\n return { source, operation, code: \"publish_failed\", message: `${sourceName} publish failed` };\n case \"checkpoint\":\n return {\n source,\n operation,\n code: \"checkpoint_failed\",\n message: `${sourceName} checkpoint failed`,\n };\n }\n};\n\nconst latestError = (\n backfill: Option.Option<PersistedResourceError>,\n changes: Option.Option<PersistedResourceError>,\n): Option.Option<PersistedResourceError> => {\n if (Option.isNone(backfill)) return changes;\n if (Option.isNone(changes)) return backfill;\n return backfill.value.at >= changes.value.at ? backfill : changes;\n};\n\n/**\n * Implements StateStore over any Effect KeyValueStore. `toSchemaStore` owns\n * serialization and validates persisted values when they are read and written.\n * The caller owns instance scoping; `layerSql` supplies the production prefix.\n */\nexport const layerKeyValueStore: Layer.Layer<StateStore, never, KeyValueStore.KeyValueStore> =\n Layer.effect(StateStore)(\n Effect.gen(function* () {\n const keyValueStore = yield* KeyValueStore.KeyValueStore;\n const backfillStore = KeyValueStore.toSchemaStore(keyValueStore, BackfillStateSchema);\n const changesStore = KeyValueStore.toSchemaStore(keyValueStore, ChangesStateSchema);\n const errorStore = KeyValueStore.toSchemaStore(keyValueStore, ResourceErrorSchema);\n\n const getResourceState = (resource: string) =>\n // Components use separate keys so a cursor update cannot overwrite the\n // independently managed error or backfill state.\n Effect.all(\n {\n backfill: backfillStore.get(resourceComponentKey(resource, \"backfill\")),\n changes: changesStore.get(resourceComponentKey(resource, \"changes\")),\n backfillError: errorStore.get(resourceErrorKey(resource, \"backfill\")),\n changesError: errorStore.get(resourceErrorKey(resource, \"changes\")),\n },\n { concurrency: \"unbounded\" },\n ).pipe(\n Effect.map(({ backfill, changes, backfillError, changesError }) => {\n const lastError = latestError(backfillError, changesError);\n if (Option.isNone(backfill) && Option.isNone(changes) && Option.isNone(lastError)) {\n return undefined;\n }\n return {\n ...(Option.isSome(backfill) ? { backfill: backfill.value } : {}),\n ...(Option.isSome(changes) ? { changes: changes.value } : {}),\n ...(Option.isSome(lastError) ? { lastError: lastError.value } : {}),\n };\n }),\n mapStoreError(\"read\", resource),\n );\n\n const setBackfillState = (resource: string, state: PersistedBackfillState) =>\n backfillStore\n .set(resourceComponentKey(resource, \"backfill\"), state)\n .pipe(mapStoreError(\"write\", resource));\n\n const setChangesState = (resource: string, state: PersistedChangesState) =>\n changesStore\n .set(resourceComponentKey(resource, \"changes\"), state)\n .pipe(mapStoreError(\"write\", resource));\n\n const setResourceError = (resource: string, source: StateSource, operation: StateOperation) =>\n DateTime.now.pipe(\n Effect.map(DateTime.formatIso),\n Effect.flatMap((at) => {\n const error = resourceErrorContext(source, operation);\n return errorStore.set(resourceErrorKey(resource, source), {\n ...error,\n at,\n });\n }),\n mapStoreError(\"write\", resource),\n );\n\n const clearResourceError = (resource: string, source: StateSource) =>\n errorStore\n .remove(resourceErrorKey(resource, source))\n .pipe(mapStoreError(\"clear\", resource));\n\n return StateStore.of({\n getResourceState,\n setBackfillState,\n setChangesState,\n setResourceError,\n clearResourceError,\n });\n }),\n );\n","import { Layer } from \"effect\";\nimport { KeyValueStore } from \"effect/unstable/persistence\";\n\nimport type { StateStore } from \"./service\";\n\nimport { layerKeyValueStore } from \"./layer-key-value-store\";\n\n/** Process-local state for tests and explicit local sandbox commands. */\nexport const layerMemory: Layer.Layer<StateStore> = layerKeyValueStore.pipe(\n Layer.provide(KeyValueStore.layerMemory),\n);\n","import { Config, Effect, Layer } from \"effect\";\nimport { KeyValueStore } from \"effect/unstable/persistence\";\nimport { SqlClient } from \"effect/unstable/sql\";\n\nimport type { StateStore } from \"./service\";\n\nimport { PlatformRuntimeDefault, PlatformRuntimeKey } from \"../runtime-config/constants\";\nimport { connectorInstanceKeyPrefix } from \"./keys\";\nimport { layerKeyValueStore } from \"./layer-key-value-store\";\n\nconst scopedKeyValueStore = (connectorInstanceId: string) =>\n Layer.effect(KeyValueStore.KeyValueStore)(\n KeyValueStore.KeyValueStore.pipe(\n Effect.map(KeyValueStore.prefix(connectorInstanceKeyPrefix(connectorInstanceId))),\n ),\n );\n\n/**\n * Shared SQL state using the immutable connector instance ID supplied by\n * platform-owned Effect configuration. The table defaults to\n * `_airfoil_connectors_state` and can be overridden with `AIRFOIL_STATE_TABLE`.\n * Effect's SQL KeyValueStore owns the table, while `KeyValueStore.prefix`\n * provides application-level isolation between connector instances in that\n * table. The resulting layer exposes only StateStore, never the unscoped\n * KeyValueStore.\n *\n * @example\n * ```ts\n * const StateStoreLive = layerSql().pipe(Layer.provide(PostgresLive));\n * ```\n */\nexport const layerSql = (): Layer.Layer<StateStore, Config.ConfigError, SqlClient.SqlClient> =>\n Layer.unwrap(\n Config.all({\n connectorInstanceId: Config.nonEmptyString(PlatformRuntimeKey.connectorInstanceId),\n table: Config.nonEmptyString(PlatformRuntimeKey.stateTable).pipe(\n Config.withDefault(PlatformRuntimeDefault.stateTable),\n ),\n }).pipe(\n Effect.map(({ connectorInstanceId, table }) =>\n layerKeyValueStore.pipe(\n Layer.provide(\n scopedKeyValueStore(connectorInstanceId).pipe(\n Layer.provide(KeyValueStore.layerSql({ table })),\n ),\n ),\n ),\n ),\n ),\n );\n","export { StateStore, type StateStoreService } from \"./service\";\nexport { layerMemory } from \"./layer-memory\";\nexport { layerSql } from \"./layer-sql\";\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"status-BTTd7AUR.js","names":["ResourceErrorSchema","StateResourceErrorSchema"],"sources":["../src/state-store/state.ts","../src/status/route.ts","../src/status/types.ts","../src/status/index.ts"],"sourcesContent":["import type { Cursor, ResourceDefinition, ResourceState, SyncState } from \"../core/types\";\n\n/** Normalizes a cursor value to its persisted/wire representation (never a Date). */\nexport const normalizeCursor = (value: Cursor.Value): string | number =>\n value instanceof Date ? value.toISOString() : value;\n\n/** Derives connector-facing sync state from durable state and resource capabilities. */\nexport const deriveSyncState = (\n resource: ResourceDefinition,\n state: ResourceState | undefined,\n): SyncState => {\n if (state?.lastError) return \"error\";\n if (!resource.backfill && !resource.changes) return \"live\";\n if (!state) return \"pending\";\n if (resource.backfill && (!state.backfill || !state.backfill.completed)) return \"backfilling\";\n return \"live\";\n};\n","import { Cause, Effect } from \"effect\";\nimport { HttpRouter, HttpServerResponse } from \"effect/unstable/http\";\n\nimport type { ConnectorDefinition } from \"../core/types\";\nimport type { ResourceStatus, StatusUnavailableResponse } from \"./types\";\n\nimport { StateStore } from \"../state-store\";\nimport { deriveSyncState, normalizeCursor } from \"../state-store/state\";\n\nexport const statusRoute = (\n connector: ConnectorDefinition,\n path: HttpRouter.PathInput = \"/status\",\n) =>\n HttpRouter.add(\n \"GET\",\n path,\n Effect.gen(function* () {\n const store = yield* StateStore;\n\n const resources = yield* Effect.forEach(\n connector.resources,\n (resource) =>\n store.getResourceState(resource.name).pipe(\n Effect.map(\n (state): ResourceStatus => ({\n name: resource.name,\n state: deriveSyncState(resource, state),\n ...(state?.backfill\n ? {\n backfill: {\n completed: state.backfill.completed,\n cutoff: normalizeCursor(state.backfill.cutoff),\n ...(state.backfill.pageCursor !== undefined\n ? { pageCursor: normalizeCursor(state.backfill.pageCursor) }\n : {}),\n ...(state.backfill.lastSuccessAt !== undefined\n ? { lastSuccessAt: state.backfill.lastSuccessAt }\n : {}),\n },\n }\n : {}),\n ...(state?.changes\n ? {\n changes: {\n cursor: normalizeCursor(state.changes.cursor),\n ...(state.changes.lastSuccessAt !== undefined\n ? { lastSuccessAt: state.changes.lastSuccessAt }\n : {}),\n },\n }\n : {}),\n ...(state?.lastError ? { lastError: state.lastError } : {}),\n }),\n ),\n ),\n { concurrency: \"unbounded\" },\n );\n\n return HttpServerResponse.jsonUnsafe({ connector: connector.name, resources });\n }).pipe(\n Effect.catchCause((cause) =>\n Effect.logWarning(`Status route failed: ${Cause.pretty(cause)}`).pipe(\n Effect.andThen(\n Effect.succeed(\n HttpServerResponse.jsonUnsafe(\n {\n ok: false,\n error: \"Failed to compute status\",\n } satisfies StatusUnavailableResponse,\n { status: 500 },\n ),\n ),\n ),\n ),\n ),\n ),\n );\n","import { Schema } from \"effect\";\n\nimport {\n ResourceErrorSchema as StateResourceErrorSchema,\n ResourceStateSchema,\n} from \"../state-store/schema\";\n\nexport const SyncStateSchema = Schema.Literals([\"pending\", \"backfilling\", \"live\", \"error\"]);\nexport type SyncState = Schema.Schema.Type<typeof SyncStateSchema>;\n\n/** Safe source failure returned by the status endpoint. */\nexport const ResourceErrorSchema = StateResourceErrorSchema;\nexport type ResourceError = Schema.Schema.Type<typeof ResourceErrorSchema>;\n\nexport const ResourceStatusSchema = Schema.Struct({\n name: Schema.String,\n state: SyncStateSchema,\n ...ResourceStateSchema.fields,\n});\nexport type ResourceStatus = Schema.Schema.Type<typeof ResourceStatusSchema>;\n\nexport const StatusResponseSchema = Schema.Struct({\n connector: Schema.String,\n resources: Schema.Array(ResourceStatusSchema),\n});\nexport type StatusResponse = Schema.Schema.Type<typeof StatusResponseSchema>;\n\n/** Returned when durable resource status cannot be read. */\nexport const StatusUnavailableResponseSchema = Schema.Struct({\n ok: Schema.Literal(false),\n error: Schema.String,\n});\nexport type StatusUnavailableResponse = Schema.Schema.Type<typeof StatusUnavailableResponseSchema>;\n","export * from \"./route\";\nexport * from \"./types\";\n"],"mappings":";;;;;;;AAGA,MAAa,mBAAmB,UAC9B,iBAAiB,OAAO,MAAM,aAAa,GAAG;;AAGhD,MAAa,mBACX,UACA,UACc;AACd,KAAI,OAAO,UAAW,QAAO;AAC7B,KAAI,CAAC,SAAS,YAAY,CAAC,SAAS,QAAS,QAAO;AACpD,KAAI,CAAC,MAAO,QAAO;AACnB,KAAI,SAAS,aAAa,CAAC,MAAM,YAAY,CAAC,MAAM,SAAS,WAAY,QAAO;AAChF,QAAO;;;;;ACNT,MAAa,eACX,WACA,OAA6B,cAE7B,WAAW,IACT,OACA,MACA,OAAO,IAAI,aAAa;CACtB,MAAM,QAAQ,OAAO;CAErB,MAAM,YAAY,OAAO,OAAO,QAC9B,UAAU,YACT,aACC,MAAM,iBAAiB,SAAS,KAAK,CAAC,KACpC,OAAO,KACJ,WAA2B;EAC1B,MAAM,SAAS;EACf,OAAO,gBAAgB,UAAU,MAAM;EACvC,GAAI,OAAO,WACP,EACE,UAAU;GACR,WAAW,MAAM,SAAS;GAC1B,QAAQ,gBAAgB,MAAM,SAAS,OAAO;GAC9C,GAAI,MAAM,SAAS,eAAe,SAC9B,EAAE,YAAY,gBAAgB,MAAM,SAAS,WAAW,EAAE,GAC1D,EAAE;GACN,GAAI,MAAM,SAAS,kBAAkB,SACjC,EAAE,eAAe,MAAM,SAAS,eAAe,GAC/C,EAAE;GACP,EACF,GACD,EAAE;EACN,GAAI,OAAO,UACP,EACE,SAAS;GACP,QAAQ,gBAAgB,MAAM,QAAQ,OAAO;GAC7C,GAAI,MAAM,QAAQ,kBAAkB,SAChC,EAAE,eAAe,MAAM,QAAQ,eAAe,GAC9C,EAAE;GACP,EACF,GACD,EAAE;EACN,GAAI,OAAO,YAAY,EAAE,WAAW,MAAM,WAAW,GAAG,EAAE;EAC3D,EACF,CACF,EACH,EAAE,aAAa,aAAa,CAC7B;AAED,QAAO,mBAAmB,WAAW;EAAE,WAAW,UAAU;EAAM;EAAW,CAAC;EAC9E,CAAC,KACD,OAAO,YAAY,UACjB,OAAO,WAAW,wBAAwB,MAAM,OAAO,MAAM,GAAG,CAAC,KAC/D,OAAO,QACL,OAAO,QACL,mBAAmB,WACjB;CACE,IAAI;CACJ,OAAO;CACR,EACD,EAAE,QAAQ,KAAK,CAChB,CACF,CACF,CACF,CACF,CACF,CACF;;;;ACrEH,MAAa,kBAAkB,OAAO,SAAS;CAAC;CAAW;CAAe;CAAQ;CAAQ,CAAC;;AAI3F,MAAaA,wBAAsBC;AAGnC,MAAa,uBAAuB,OAAO,OAAO;CAChD,MAAM,OAAO;CACb,OAAO;CACP,GAAG,oBAAoB;CACxB,CAAC;AAGF,MAAa,uBAAuB,OAAO,OAAO;CAChD,WAAW,OAAO;CAClB,WAAW,OAAO,MAAM,qBAAqB;CAC9C,CAAC;;AAIF,MAAa,kCAAkC,OAAO,OAAO;CAC3D,IAAI,OAAO,QAAQ,MAAM;CACzB,OAAO,OAAO;CACf,CAAC"}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { n as PlatformRuntimeKey } from "./constants-D113Ut1x.js";
|
|
2
|
-
import { Config, Data, Effect, Schema } from "effect";
|
|
3
|
-
import * as Wings from "@useairfoil/wings";
|
|
4
|
-
|
|
5
|
-
//#region src/runtime-config/error.ts
|
|
6
|
-
/** Expected hosted-config failure with a stable code and diagnostic cause. */
|
|
7
|
-
var RuntimeConfigError = class extends Data.TaggedError("RuntimeConfigError") {};
|
|
8
|
-
|
|
9
|
-
//#endregion
|
|
10
|
-
//#region src/runtime-config/table-bindings.ts
|
|
11
|
-
const RawBindingsSchema = Schema.fromJsonString(Schema.Record(Schema.String, Schema.Unknown));
|
|
12
|
-
const duplicateTopLevelKey = (json) => {
|
|
13
|
-
const keys = /* @__PURE__ */ new Set();
|
|
14
|
-
let depth = 0;
|
|
15
|
-
let expectKey = false;
|
|
16
|
-
for (let index = 0; index < json.length; index += 1) {
|
|
17
|
-
const char = json[index];
|
|
18
|
-
if (char === "\"") {
|
|
19
|
-
const start = index;
|
|
20
|
-
for (index += 1; index < json.length; index += 1) if (json[index] === "\\") index += 1;
|
|
21
|
-
else if (json[index] === "\"") break;
|
|
22
|
-
if (depth === 1 && expectKey) {
|
|
23
|
-
const key = JSON.parse(json.slice(start, index + 1));
|
|
24
|
-
if (keys.has(key)) return key;
|
|
25
|
-
keys.add(key);
|
|
26
|
-
expectKey = false;
|
|
27
|
-
}
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
if (char === "{") {
|
|
31
|
-
depth += 1;
|
|
32
|
-
if (depth === 1) expectKey = true;
|
|
33
|
-
} else if (char === "}") depth -= 1;
|
|
34
|
-
else if (char === "," && depth === 1) expectKey = true;
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
const asError = (cause) => cause instanceof Error ? cause : new Error(String(cause));
|
|
38
|
-
const fail = (code, message) => new RuntimeConfigError({
|
|
39
|
-
code,
|
|
40
|
-
message,
|
|
41
|
-
cause: new Error(message)
|
|
42
|
-
});
|
|
43
|
-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
44
|
-
const hasExactKeys = (value, allowed) => {
|
|
45
|
-
const keys = Object.keys(value);
|
|
46
|
-
return keys.length === allowed.filter((key) => key in value).length && keys.every((key) => allowed.includes(key));
|
|
47
|
-
};
|
|
48
|
-
const nonEmptyName = (value) => {
|
|
49
|
-
if (typeof value !== "string" || value.length === 0 || value.trim() !== value) throw fail("TABLE_BINDINGS_INVALID", "Table binding names must be non-empty strings");
|
|
50
|
-
return value;
|
|
51
|
-
};
|
|
52
|
-
const resolveBinding = (input) => Effect.gen(function* () {
|
|
53
|
-
const binding = yield* Effect.try({
|
|
54
|
-
try: () => {
|
|
55
|
-
if (typeof input === "string") return { name: nonEmptyName(input) };
|
|
56
|
-
if (!isRecord(input) || !hasExactKeys(input, ["name", "partition"])) throw fail("TABLE_BINDINGS_INVALID", "Table bindings must be a name string or an object containing name and optional partition");
|
|
57
|
-
return {
|
|
58
|
-
name: nonEmptyName(input.name),
|
|
59
|
-
partition: input.partition
|
|
60
|
-
};
|
|
61
|
-
},
|
|
62
|
-
catch: (cause) => cause instanceof RuntimeConfigError ? cause : fail("TABLE_BINDINGS_INVALID", "Hosted table binding is invalid")
|
|
63
|
-
});
|
|
64
|
-
if (!("partition" in binding) || binding.partition === void 0) return { name: binding.name };
|
|
65
|
-
const partitionValue = yield* Wings.PartitionValue.decodeJson(binding.partition).pipe(Effect.mapError((cause) => new RuntimeConfigError({
|
|
66
|
-
code: "TABLE_BINDINGS_INVALID",
|
|
67
|
-
message: "Hosted table binding has an invalid partition value",
|
|
68
|
-
cause
|
|
69
|
-
})));
|
|
70
|
-
return {
|
|
71
|
-
name: binding.name,
|
|
72
|
-
partitionValue
|
|
73
|
-
};
|
|
74
|
-
});
|
|
75
|
-
/** Loads and validates the complete hosted Wings table map for a connector. */
|
|
76
|
-
const loadTableBindings = (connector) => Effect.gen(function* () {
|
|
77
|
-
const raw = yield* Config.nonEmptyString(PlatformRuntimeKey.tableBindings).pipe(Effect.mapError((cause) => new RuntimeConfigError({
|
|
78
|
-
code: "TABLE_BINDINGS_MISSING",
|
|
79
|
-
message: `${PlatformRuntimeKey.tableBindings} is required in hosted mode`,
|
|
80
|
-
cause: asError(cause)
|
|
81
|
-
})));
|
|
82
|
-
if ((yield* Effect.try({
|
|
83
|
-
try: () => duplicateTopLevelKey(raw),
|
|
84
|
-
catch: (cause) => new RuntimeConfigError({
|
|
85
|
-
code: "TABLE_BINDINGS_INVALID",
|
|
86
|
-
message: "Hosted table bindings are not valid JSON",
|
|
87
|
-
cause: asError(cause)
|
|
88
|
-
})
|
|
89
|
-
})) !== void 0) return yield* Effect.fail(fail("TABLE_BINDINGS_INVALID", "Hosted table bindings contain a duplicate resource"));
|
|
90
|
-
const decoded = yield* Schema.decodeUnknownEffect(RawBindingsSchema)(raw).pipe(Effect.mapError((cause) => new RuntimeConfigError({
|
|
91
|
-
code: "TABLE_BINDINGS_INVALID",
|
|
92
|
-
message: "Hosted table bindings are not valid JSON",
|
|
93
|
-
cause: asError(cause)
|
|
94
|
-
})));
|
|
95
|
-
const expected = new Set(connector.resources.map((resource) => resource.name));
|
|
96
|
-
const actual = Object.keys(decoded);
|
|
97
|
-
const missing = [...expected].filter((name) => !(name in decoded));
|
|
98
|
-
const unknown = actual.filter((name) => !expected.has(name));
|
|
99
|
-
if (missing.length > 0 || unknown.length > 0) return yield* Effect.fail(fail("TABLE_BINDINGS_MISMATCH", `Hosted table bindings do not match connector resources (missing: ${missing.join(", ") || "none"}; unknown resources: ${unknown.length})`));
|
|
100
|
-
const entries = yield* Effect.forEach(actual, (name) => resolveBinding(decoded[name]).pipe(Effect.map((binding) => [name, binding])));
|
|
101
|
-
return Object.fromEntries(entries);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
//#endregion
|
|
105
|
-
export { RuntimeConfigError as n, loadTableBindings as t };
|
|
106
|
-
//# sourceMappingURL=table-bindings-Dp1DhTeS.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"table-bindings-Dp1DhTeS.js","names":[],"sources":["../src/runtime-config/error.ts","../src/runtime-config/table-bindings.ts"],"sourcesContent":["import { Data } from \"effect\";\n\nexport type RuntimeConfigErrorCode =\n | \"CONFIG_PATH_MISSING\"\n | \"CONFIG_FILE_UNREADABLE\"\n | \"CONFIG_JSON_INVALID\"\n | \"TABLE_BINDINGS_MISSING\"\n | \"TABLE_BINDINGS_INVALID\"\n | \"TABLE_BINDINGS_MISMATCH\";\n\n/** Expected hosted-config failure with a stable code and diagnostic cause. */\nexport class RuntimeConfigError extends Data.TaggedError(\"RuntimeConfigError\")<{\n readonly code: RuntimeConfigErrorCode;\n readonly message: string;\n readonly cause: Error;\n}> {}\n","import * as Wings from \"@useairfoil/wings\";\nimport { Config, Effect, Schema } from \"effect\";\n\nimport type { ConnectorDefinition, ResourceName } from \"../core/types\";\n\nimport { PlatformRuntimeKey } from \"./constants\";\nimport { RuntimeConfigError } from \"./error\";\n\n/** Table binding shape accepted in `AIRFOIL_TABLE_BINDINGS`. */\nexport type HostedTableBinding =\n | string\n | {\n readonly name: string;\n readonly partition?: Wings.PartitionValue.Json;\n };\n\n/** Validated table binding ready for the Wings publisher. */\nexport type ResolvedTableBinding = {\n readonly name: string;\n readonly partitionValue?: Wings.PartitionValue.PartitionValue;\n};\n\n/** One resolved binding for each resource in a connector manifest. */\nexport type ResolvedTableBindings<Connector extends ConnectorDefinition> = Readonly<\n Record<ResourceName<Connector[\"resources\"]>, ResolvedTableBinding>\n>;\n\nconst RawBindingsSchema = Schema.fromJsonString(Schema.Record(Schema.String, Schema.Unknown));\n\n// JSON.parse keeps the last duplicate key, so check before decoding.\nconst duplicateTopLevelKey = (json: string): string | undefined => {\n const keys = new Set<string>();\n let depth = 0;\n let expectKey = false;\n for (let index = 0; index < json.length; index += 1) {\n const char = json[index];\n if (char === '\"') {\n const start = index;\n for (index += 1; index < json.length; index += 1) {\n if (json[index] === \"\\\\\") {\n index += 1;\n } else if (json[index] === '\"') {\n break;\n }\n }\n if (depth === 1 && expectKey) {\n const key = JSON.parse(json.slice(start, index + 1)) as string;\n if (keys.has(key)) return key;\n keys.add(key);\n expectKey = false;\n }\n continue;\n }\n if (char === \"{\") {\n depth += 1;\n if (depth === 1) expectKey = true;\n } else if (char === \"}\") {\n depth -= 1;\n } else if (char === \",\" && depth === 1) {\n expectKey = true;\n }\n }\n return undefined;\n};\n\nconst asError = (cause: unknown): Error =>\n cause instanceof Error ? cause : new Error(String(cause));\n\nconst fail = (code: \"TABLE_BINDINGS_INVALID\" | \"TABLE_BINDINGS_MISMATCH\", message: string) =>\n new RuntimeConfigError({ code, message, cause: new Error(message) });\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst hasExactKeys = (value: Record<string, unknown>, allowed: ReadonlyArray<string>) => {\n const keys = Object.keys(value);\n return (\n keys.length === allowed.filter((key) => key in value).length &&\n keys.every((key) => allowed.includes(key))\n );\n};\n\nconst nonEmptyName = (value: unknown): string => {\n if (typeof value !== \"string\" || value.length === 0 || value.trim() !== value) {\n throw fail(\"TABLE_BINDINGS_INVALID\", \"Table binding names must be non-empty strings\");\n }\n return value;\n};\n\nconst resolveBinding = (input: unknown): Effect.Effect<ResolvedTableBinding, RuntimeConfigError> =>\n Effect.gen(function* () {\n const binding = yield* Effect.try({\n try: () => {\n if (typeof input === \"string\") return { name: nonEmptyName(input) } as const;\n if (!isRecord(input) || !hasExactKeys(input, [\"name\", \"partition\"])) {\n throw fail(\n \"TABLE_BINDINGS_INVALID\",\n \"Table bindings must be a name string or an object containing name and optional partition\",\n );\n }\n return { name: nonEmptyName(input.name), partition: input.partition } as const;\n },\n catch: (cause) =>\n cause instanceof RuntimeConfigError\n ? cause\n : fail(\"TABLE_BINDINGS_INVALID\", \"Hosted table binding is invalid\"),\n });\n if (!(\"partition\" in binding) || binding.partition === undefined) {\n return { name: binding.name };\n }\n const partitionValue = yield* Wings.PartitionValue.decodeJson(binding.partition).pipe(\n Effect.mapError(\n (cause) =>\n new RuntimeConfigError({\n code: \"TABLE_BINDINGS_INVALID\",\n message: \"Hosted table binding has an invalid partition value\",\n cause,\n }),\n ),\n );\n return { name: binding.name, partitionValue };\n });\n\n/** Loads and validates the complete hosted Wings table map for a connector. */\nexport const loadTableBindings = <const Connector extends ConnectorDefinition>(\n connector: Connector,\n): Effect.Effect<ResolvedTableBindings<Connector>, RuntimeConfigError> =>\n Effect.gen(function* () {\n const raw = yield* Config.nonEmptyString(PlatformRuntimeKey.tableBindings).pipe(\n Effect.mapError(\n (cause) =>\n new RuntimeConfigError({\n code: \"TABLE_BINDINGS_MISSING\",\n message: `${PlatformRuntimeKey.tableBindings} is required in hosted mode`,\n cause: asError(cause),\n }),\n ),\n );\n const duplicate = yield* Effect.try({\n try: () => duplicateTopLevelKey(raw),\n catch: (cause) =>\n new RuntimeConfigError({\n code: \"TABLE_BINDINGS_INVALID\",\n message: \"Hosted table bindings are not valid JSON\",\n cause: asError(cause),\n }),\n });\n if (duplicate !== undefined) {\n return yield* Effect.fail(\n fail(\"TABLE_BINDINGS_INVALID\", \"Hosted table bindings contain a duplicate resource\"),\n );\n }\n const decoded = yield* Schema.decodeUnknownEffect(RawBindingsSchema)(raw).pipe(\n Effect.mapError(\n (cause) =>\n new RuntimeConfigError({\n code: \"TABLE_BINDINGS_INVALID\",\n message: \"Hosted table bindings are not valid JSON\",\n cause: asError(cause),\n }),\n ),\n );\n // Starting with a partial map would leave some manifest resources unwired.\n const expected = new Set(connector.resources.map((resource) => resource.name));\n const actual = Object.keys(decoded);\n const missing = [...expected].filter((name) => !(name in decoded));\n const unknown = actual.filter((name) => !expected.has(name));\n if (missing.length > 0 || unknown.length > 0) {\n return yield* Effect.fail(\n fail(\n \"TABLE_BINDINGS_MISMATCH\",\n `Hosted table bindings do not match connector resources (missing: ${missing.join(\", \") || \"none\"}; unknown resources: ${unknown.length})`,\n ),\n );\n }\n const entries = yield* Effect.forEach(actual, (name) =>\n resolveBinding(decoded[name]).pipe(Effect.map((binding) => [name, binding] as const)),\n );\n return Object.fromEntries(entries) as ResolvedTableBindings<Connector>;\n });\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry-j_nxwYfh.js","names":["defaultRedactedHeaders: ReadonlyArray<string | RegExp>"],"sources":["../src/telemetry.ts"],"sourcesContent":["import { Cause, Config, Effect, Layer, Metric, Option, type Duration } from \"effect\";\nimport { Headers } from \"effect/unstable/http\";\nimport * as Observability from \"effect/unstable/observability\";\n\nimport { PlatformRuntimeKey } from \"./runtime-config/constants\";\n\n/** Canonical span names emitted by connector-kit runtime instrumentation. */\nexport const SpanName = {\n batchProcess: \"connector.batch.process\",\n webhookDecode: \"connector.webhook.decode\",\n webhookHandle: \"connector.webhook.handle\",\n publish: \"connector.publish\",\n stateSet: \"connector.state.set\",\n apiFetch: \"connector.api.fetch\",\n} as const;\n\n/** Canonical span attribute names. Keep these stable for collector queries. */\nexport const Attr = {\n connectorName: \"airfoil.connector.name\",\n connectorResourcesCount: \"airfoil.connector.resources.count\",\n resourceName: \"airfoil.resource.name\",\n resourceSource: \"airfoil.resource.source\",\n batchMutations: \"airfoil.batch.mutations\",\n batchOutcome: \"airfoil.batch.outcome\",\n webhookPath: \"airfoil.webhook.path\",\n webhookOutcome: \"airfoil.webhook.outcome\",\n syncState: \"airfoil.connector.sync.state\",\n apiRetryReason: \"airfoil.connector.api.retry.reason\",\n publisherSuccess: \"airfoil.publisher.success\",\n stateKey: \"airfoil.state.key\",\n apiPath: \"airfoil.api.path\",\n errorPhase: \"airfoil.error.phase\",\n errorType: \"airfoil.error.type\",\n errorMessage: \"airfoil.error.message\",\n errorDetails: \"airfoil.error.details\",\n} as const;\n\n/** Resource attributes injected by the hosted operator through standard OTel environment keys. */\nexport const ResourceAttr = {\n serviceInstanceId: \"service.instance.id\",\n connectorRevision: \"airfoil.connector.revision\",\n teamId: \"airfoil.team.id\",\n} as const;\n\n/** Span event names for high-cardinality reproduction details. */\nexport const EventName = {\n batchCheckpoint: \"airfoil.batch.checkpoint\",\n} as const;\n\n/** Event-only attributes. These are intentionally not span attributes. */\nexport const EventAttr = {\n batchCursor: \"airfoil.batch.cursor\",\n} as const;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst maxErrorMessageLength = 500;\n\nconst OtlpEnvConfig = Config.all({\n enabled: Config.boolean(PlatformRuntimeKey.otelEnabled).pipe(Config.withDefault(false)),\n baseUrl: Config.option(Config.string(PlatformRuntimeKey.otelExporterOtlpEndpoint)),\n rawHeaders: Config.option(Config.string(PlatformRuntimeKey.otelExporterOtlpHeaders)),\n});\n\nconst defaultRedactedHeaders: ReadonlyArray<string | RegExp> = [\n \"authorization\",\n \"cookie\",\n \"set-cookie\",\n \"x-api-key\",\n /api[-_]?key/i,\n /secret/i,\n /signature/i,\n /token/i,\n];\n\nconst parseOtelHeaders = (value: string): Record<string, string> =>\n Object.fromEntries(\n value\n .split(\",\")\n .map((entry) => entry.trim())\n .filter(Boolean)\n .flatMap((entry) => {\n const separator = entry.indexOf(\"=\");\n if (separator < 1) return [];\n return [[entry.slice(0, separator).trim(), entry.slice(separator + 1).trim()]];\n }),\n );\n\nconst appendPath = (baseUrl: string, path: string) =>\n `${baseUrl.replace(/\\/$/, \"\")}/${path.replace(/^\\//, \"\")}`;\n\n/**\n * Best-effort stable error classifier for span metadata.\n *\n * Effect/Data tagged errors expose `_tag`; that is the most useful value for\n * connector bugs (`ConnectorError`, `InvalidWebhookPayloadError`, etc.). For\n * non-tagged errors we fall back to the JS `Error.name`, then constructor name,\n * then the primitive type.\n */\nconst errorType = (error: unknown) => {\n if (isRecord(error) && typeof error._tag === \"string\") {\n return String(error._tag);\n }\n if (error instanceof Error) {\n return error.name;\n }\n if (isRecord(error) && typeof error.constructor?.name === \"string\") {\n return error.constructor.name;\n }\n return typeof error;\n};\n\n/**\n * Human-readable error summary for span metadata.\n *\n * Tagged errors in this package carry a `message` field, so this preserves the\n * important diagnostic text. Unknown object failures are intentionally reduced\n * to their type; full structured error payloads belong in logs, not span attrs.\n */\nconst errorMessage = (error: unknown) => {\n const message = (() => {\n if (isRecord(error) && typeof error.message === \"string\") {\n return error.message;\n }\n if (typeof error === \"string\") {\n return error;\n }\n return errorType(error);\n })();\n\n if (message.length > maxErrorMessageLength) {\n return `${message.slice(0, maxErrorMessageLength)}...`;\n }\n\n return message;\n};\n\nconst errorDetails = (error: unknown): string | undefined => {\n if (!isRecord(error) || error.cause === undefined) return undefined;\n return Cause.pretty(Cause.die(error.cause));\n};\n\n/** Annotates the active span with phase-aware error metadata before re-failing. */\nexport const annotateError = (phase: string, error: unknown) => {\n const details = errorDetails(error);\n return Effect.annotateCurrentSpan({\n [Attr.errorPhase]: phase,\n [Attr.errorType]: errorType(error),\n [Attr.errorMessage]: errorMessage(error),\n ...(details !== undefined ? { [Attr.errorDetails]: details } : {}),\n });\n};\n\n/** Adds an event to the active span, or no-ops when no span is active. */\nexport const addCurrentSpanEvent = (name: string, attributes?: Record<string, unknown>) =>\n Effect.currentSpan.pipe(\n Effect.flatMap((span) =>\n Effect.clockWith((clock) =>\n Effect.sync(() => span.event(name, clock.currentTimeNanosUnsafe(), attributes)),\n ),\n ),\n Effect.ignore,\n );\n\n/** Transport configuration for OTLP trace export. All fields are direct values. */\nexport type OtlpTracingConfig = {\n readonly enabled?: boolean;\n readonly endpoint?: string;\n readonly headers?: Record<string, string>;\n};\n\n/** Runtime options — not config-wrappable since RegExp cannot live in Config. */\nexport type OtlpTracingOptions = {\n /** Additional connector-specific header names or regexes to redact from HTTP logs/traces. */\n readonly redactedHeaders?: ReadonlyArray<string | RegExp>;\n};\n\n/** OTLP metric export settings. */\nexport type OtlpMetricsOptions = {\n readonly exportInterval?: Duration.Input;\n};\n\nconst buildOtlpTracingLayer = (config: OtlpTracingConfig, options: OtlpTracingOptions) =>\n Effect.gen(function* () {\n const allRedacted = [...defaultRedactedHeaders, ...(options.redactedHeaders ?? [])];\n const RedactionLayer = Layer.succeed(Headers.CurrentRedactedNames)(allRedacted);\n\n if (!config.enabled) {\n return RedactionLayer;\n }\n\n if (!config.endpoint) {\n return yield* Effect.fail(new Error(\"enabled=true requires endpoint\"));\n }\n\n yield* Effect.logInfo(\"telemetry enabled\").pipe(\n Effect.annotateLogs({\n endpoint: config.endpoint,\n headers: config.headers ? Object.keys(config.headers) : [],\n }),\n );\n\n return Layer.mergeAll(\n RedactionLayer,\n Observability.OtlpTracer.layer({\n url: appendPath(config.endpoint, \"/v1/traces\"),\n headers: config.headers,\n }).pipe(Layer.provide(Observability.OtlpSerialization.layerJson)),\n );\n });\n\n/**\n * Trace-only OTLP export with sensitive HTTP header redaction.\n * Takes direct config values — no `ConfigProvider` required.\n */\nexport const layer = (config: OtlpTracingConfig = {}, options: OtlpTracingOptions = {}) =>\n Layer.unwrap(buildOtlpTracingLayer(config, options));\n\n/**\n * Trace-only OTLP export with sensitive HTTP header redaction.\n * Takes Effect Config-wrapped values — reads from `ConfigProvider`.\n *\n * @example\n * Telemetry.layerConfig({\n * enabled: Config.boolean(\"MY_OTEL_ENABLED\"),\n * endpoint: Config.string(\"MY_COLLECTOR_URL\"),\n * })\n */\nexport const layerConfig = (\n config: Config.Wrap<OtlpTracingConfig>,\n options: OtlpTracingOptions = {},\n) =>\n Layer.unwrap(\n Effect.gen(function* () {\n const resolved = yield* Config.unwrap(config);\n return yield* buildOtlpTracingLayer(resolved, options);\n }),\n );\n\n/**\n * Trace-only OTLP export with sensitive HTTP header redaction.\n * Zero-config shortcut that reads the standard `OTEL_*` env var names.\n *\n * Reads `OTEL_ENABLED`, `OTEL_EXPORTER_OTLP_ENDPOINT`, and\n * `OTEL_EXPORTER_OTLP_HEADERS`. Effect's OTLP resource handling reads\n * `OTEL_SERVICE_NAME`, `OTEL_SERVICE_VERSION`, and `OTEL_RESOURCE_ATTRIBUTES`.\n */\nexport const layerOtlpTracing = (options: OtlpTracingOptions = {}) =>\n Layer.unwrap(\n Effect.gen(function* () {\n const raw = yield* OtlpEnvConfig;\n return yield* buildOtlpTracingLayer(\n {\n enabled: raw.enabled,\n endpoint: Option.getOrUndefined(raw.baseUrl),\n headers: Option.isSome(raw.rawHeaders)\n ? parseOtelHeaders(raw.rawHeaders.value)\n : undefined,\n },\n options,\n );\n }),\n );\n\n/** Exports connector metrics over OTLP when telemetry is enabled. */\nexport const layerOtlpMetrics = (options: OtlpMetricsOptions = {}) =>\n Layer.unwrap(\n Effect.gen(function* () {\n const raw = yield* OtlpEnvConfig;\n if (!raw.enabled) return Layer.empty;\n const endpoint = Option.getOrUndefined(raw.baseUrl);\n if (!endpoint)\n return yield* Effect.fail(\n new Error(\"OTEL_ENABLED=true requires OTEL_EXPORTER_OTLP_ENDPOINT\"),\n );\n return Observability.OtlpMetrics.layer({\n url: appendPath(endpoint, \"/v1/metrics\"),\n headers: Option.isSome(raw.rawHeaders) ? parseOtelHeaders(raw.rawHeaders.value) : undefined,\n exportInterval: options.exportInterval,\n temporality: \"cumulative\",\n }).pipe(Layer.provide(Observability.OtlpSerialization.layerJson));\n }),\n );\n\n/** Enables OTLP traces and metrics with shared environment configuration. */\nexport const layerOtlp = (options: OtlpTracingOptions & OtlpMetricsOptions = {}) =>\n Layer.mergeAll(layerOtlpTracing(options), layerOtlpMetrics(options));\n\n/** Periodically logs the in-memory metric snapshot for local debugging. */\nexport const layerMetricsConsoleDump = (interval: Duration.Input = \"30 seconds\") =>\n Layer.effectDiscard(\n Effect.gen(function* () {\n yield* Effect.forkScoped(\n Effect.forever(\n Metric.dump.pipe(\n Effect.flatMap((snapshot) => Effect.logInfo(snapshot)),\n Effect.andThen(Effect.sleep(interval)),\n ),\n ),\n );\n }),\n );\n"],"mappings":"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"}
|
package/dist/types-jVD5Ys43.d.ts
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import { t as ConnectorError } from "./index-DKoRwyFn.js";
|
|
2
|
-
import { Duration, Effect, Schema } from "effect";
|
|
3
|
-
import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
|
|
4
|
-
|
|
5
|
-
//#region src/core/types.d.ts
|
|
6
|
-
declare namespace Cursor {
|
|
7
|
-
type Value = string | number | Date;
|
|
8
|
-
type Kind = "string" | "number" | "isoDateTime";
|
|
9
|
-
type Definition<T extends Value = Value> = {
|
|
10
|
-
readonly kind: Kind;
|
|
11
|
-
readonly decode: (value: unknown) => Effect.Effect<T, ConnectorError>;
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
type DeleteValue = string | number | boolean | Date;
|
|
15
|
-
type ResourceMutation<Row extends object = object> = {
|
|
16
|
-
readonly op: "upsert";
|
|
17
|
-
readonly row: Row;
|
|
18
|
-
} | {
|
|
19
|
-
readonly op: "delete";
|
|
20
|
-
readonly key: DeleteValue;
|
|
21
|
-
readonly version: DeleteValue;
|
|
22
|
-
};
|
|
23
|
-
type ResourceBatch<Row extends object = object> = {
|
|
24
|
-
readonly cursor?: Cursor.Value;
|
|
25
|
-
readonly mutations: ReadonlyArray<ResourceMutation<Row>>;
|
|
26
|
-
};
|
|
27
|
-
type ResourceState = {
|
|
28
|
-
readonly backfill?: {
|
|
29
|
-
readonly cutoff: Cursor.Value;
|
|
30
|
-
readonly pageCursor?: Cursor.Value;
|
|
31
|
-
readonly completed: boolean;
|
|
32
|
-
readonly lastSuccessAt?: string;
|
|
33
|
-
};
|
|
34
|
-
readonly changes?: {
|
|
35
|
-
readonly cursor: Cursor.Value;
|
|
36
|
-
readonly lastSuccessAt?: string;
|
|
37
|
-
};
|
|
38
|
-
readonly lastError?: {
|
|
39
|
-
readonly source: "backfill" | "changes";
|
|
40
|
-
readonly operation: "fetch" | "publish" | "checkpoint";
|
|
41
|
-
readonly code: "fetch_failed" | "publish_failed" | "checkpoint_failed";
|
|
42
|
-
readonly message: string;
|
|
43
|
-
readonly at: string;
|
|
44
|
-
};
|
|
45
|
-
};
|
|
46
|
-
type SyncState = "pending" | "backfilling" | "live" | "error";
|
|
47
|
-
type ResourceSchema = Schema.Decoder<object>;
|
|
48
|
-
/**
|
|
49
|
-
* Takes a resource schema and returns its decoded row object type.
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* ```ts
|
|
53
|
-
* const ProductSchema = Schema.Struct({ id: Schema.String, updatedAt: Schema.String });
|
|
54
|
-
* type Product = ResourceRow<typeof ProductSchema>;
|
|
55
|
-
* // Result:
|
|
56
|
-
* // type Product = { readonly id: string; readonly updatedAt: string }
|
|
57
|
-
* ```
|
|
58
|
-
*/
|
|
59
|
-
type ResourceRow<S$1 extends ResourceSchema> = Schema.Schema.Type<S$1>;
|
|
60
|
-
/**
|
|
61
|
-
* Takes a resource schema and returns the string keys available on its row type.
|
|
62
|
-
*
|
|
63
|
-
* @example
|
|
64
|
-
* ```ts
|
|
65
|
-
* const ProductSchema = Schema.Struct({ id: Schema.String, updatedAt: Schema.String });
|
|
66
|
-
* type ProductField = ResourceField<typeof ProductSchema>;
|
|
67
|
-
* // Result:
|
|
68
|
-
* // type ProductField = "id" | "updatedAt"
|
|
69
|
-
*
|
|
70
|
-
* const key: ResourceField<typeof ProductSchema> = "id";
|
|
71
|
-
* ```
|
|
72
|
-
*/
|
|
73
|
-
type ResourceField<S$1 extends ResourceSchema> = keyof ResourceRow<S$1> & string;
|
|
74
|
-
type FetchPageResult<Row extends object> = {
|
|
75
|
-
readonly mutations: ReadonlyArray<ResourceMutation<Row>>;
|
|
76
|
-
readonly nextPageCursor?: Cursor.Value;
|
|
77
|
-
readonly hasMore: boolean;
|
|
78
|
-
};
|
|
79
|
-
type PageFetch<Row extends object, R = never> = {
|
|
80
|
-
readonly pageCursor: Cursor.Definition;
|
|
81
|
-
readonly cutoff: Cursor.Definition;
|
|
82
|
-
readonly fetch: (input: {
|
|
83
|
-
readonly pageCursor?: Cursor.Value;
|
|
84
|
-
readonly cutoff: Cursor.Value;
|
|
85
|
-
}) => Effect.Effect<FetchPageResult<Row>, ConnectorError, R>;
|
|
86
|
-
};
|
|
87
|
-
type FetchChangesResult<Row extends object> = {
|
|
88
|
-
readonly mutations: ReadonlyArray<ResourceMutation<Row>>;
|
|
89
|
-
readonly cursor: Cursor.Value;
|
|
90
|
-
};
|
|
91
|
-
type ChangesFetch<Row extends object, R = never> = {
|
|
92
|
-
readonly cursor: Cursor.Definition;
|
|
93
|
-
readonly interval?: Duration.Input;
|
|
94
|
-
readonly fetch: (input: {
|
|
95
|
-
readonly cursor: Cursor.Value;
|
|
96
|
-
}) => Effect.Effect<FetchChangesResult<Row>, ConnectorError, R>;
|
|
97
|
-
};
|
|
98
|
-
type WebhookHandler<Row extends object, Payload$1> = {
|
|
99
|
-
readonly schema: Schema.Decoder<Payload$1>;
|
|
100
|
-
handler(input: {
|
|
101
|
-
readonly payload: Payload$1;
|
|
102
|
-
}): Effect.Effect<ReadonlyArray<ResourceMutation<Row>>, ConnectorError>;
|
|
103
|
-
};
|
|
104
|
-
type ResourceDefinition<S$1 extends ResourceSchema = ResourceSchema, Payload$1 = unknown, R = never, Name extends string = string> = {
|
|
105
|
-
readonly name: Name;
|
|
106
|
-
readonly schema: S$1;
|
|
107
|
-
readonly key: ResourceField<NoInfer<S$1>>;
|
|
108
|
-
readonly version: ResourceField<NoInfer<S$1>>;
|
|
109
|
-
readonly partition?: {
|
|
110
|
-
readonly required: boolean;
|
|
111
|
-
};
|
|
112
|
-
/** Read-only validation used before provisioning this resource. */
|
|
113
|
-
readonly check: Effect.Effect<void, ConnectorError>;
|
|
114
|
-
readonly backfill?: PageFetch<ResourceRow<NoInfer<S$1>>, R>;
|
|
115
|
-
readonly changes?: ChangesFetch<ResourceRow<NoInfer<S$1>>, R>;
|
|
116
|
-
readonly webhook?: WebhookHandler<ResourceRow<NoInfer<S$1>>, Payload$1>;
|
|
117
|
-
};
|
|
118
|
-
/**
|
|
119
|
-
* Takes a connector resource tuple and returns a `{ [resourceName]: rowType }`
|
|
120
|
-
* map.
|
|
121
|
-
*
|
|
122
|
-
* @example
|
|
123
|
-
* ```ts
|
|
124
|
-
* type Rows = ResourceRows<[typeof Products, typeof Orders]>;
|
|
125
|
-
* // Result:
|
|
126
|
-
* // type Rows = {
|
|
127
|
-
* // readonly products: Product;
|
|
128
|
-
* // readonly orders: Order;
|
|
129
|
-
* // }
|
|
130
|
-
*
|
|
131
|
-
* type ProductRow = Rows["products"];
|
|
132
|
-
* // Result:
|
|
133
|
-
* // type ProductRow = Product
|
|
134
|
-
* ```
|
|
135
|
-
*/
|
|
136
|
-
type ResourceRows<Resources extends ReadonlyArray<ResourceDefinition>> = { readonly [Resource in Resources[number] as Resource["name"]]: Resource extends ResourceDefinition<infer S, unknown, unknown> ? ResourceRow<S> : never };
|
|
137
|
-
/** Resource names preserved from a connector's resource tuple. */
|
|
138
|
-
type ResourceName<Resources extends ReadonlyArray<ResourceDefinition>> = keyof ResourceRows<Resources> & string;
|
|
139
|
-
/**
|
|
140
|
-
* Takes a resource definition and returns the payload type accepted by
|
|
141
|
-
* `to(resource, payload)`.
|
|
142
|
-
*
|
|
143
|
-
* @example
|
|
144
|
-
* ```ts
|
|
145
|
-
* type ProductPayload = ResourcePayload<typeof Products>;
|
|
146
|
-
* // Result, if Products was defined with a ProductEvent webhook schema:
|
|
147
|
-
* // type ProductPayload = ProductEvent
|
|
148
|
-
* ```
|
|
149
|
-
*/
|
|
150
|
-
type ResourcePayload<R> = R extends ResourceDefinition<ResourceSchema, infer Payload, unknown> ? Payload : never;
|
|
151
|
-
type WebhookAckMode = "after-enqueue" | "after-publish";
|
|
152
|
-
type WebhookRouteContext<Resources extends ReadonlyArray<ResourceDefinition> = ReadonlyArray<ResourceDefinition>, Payload$1 = unknown> = {
|
|
153
|
-
readonly request: HttpServerRequest.HttpServerRequest;
|
|
154
|
-
readonly rawBody: Uint8Array;
|
|
155
|
-
readonly payload: Payload$1;
|
|
156
|
-
/** Decodes and collects mutations for a resource-owned webhook handler. */
|
|
157
|
-
readonly to: <Resource$1 extends Resources[number]>(resource: Resource$1, payload: ResourcePayload<Resource$1>) => Effect.Effect<void, ConnectorError>;
|
|
158
|
-
};
|
|
159
|
-
type WebhookRoute<Resources extends ReadonlyArray<ResourceDefinition> = ReadonlyArray<ResourceDefinition>, Payload$1 = unknown> = {
|
|
160
|
-
readonly path: HttpRouter.PathInput;
|
|
161
|
-
readonly ackMode: WebhookAckMode;
|
|
162
|
-
readonly schema: Schema.Decoder<Payload$1>;
|
|
163
|
-
handler(context: WebhookRouteContext<Resources, Payload$1>): Effect.Effect<HttpServerResponse.HttpServerResponse, ConnectorError>;
|
|
164
|
-
};
|
|
165
|
-
type WebhookRouteInput<Resources extends ReadonlyArray<ResourceDefinition>, Payload$1> = WebhookRoute<Resources, Payload$1>;
|
|
166
|
-
type ConnectorDefinition<Resources extends ReadonlyArray<ResourceDefinition> = ReadonlyArray<ResourceDefinition>> = {
|
|
167
|
-
readonly name: string;
|
|
168
|
-
readonly title?: string;
|
|
169
|
-
readonly resources: Resources;
|
|
170
|
-
readonly webhooks?: ReadonlyArray<WebhookRoute>;
|
|
171
|
-
};
|
|
172
|
-
//#endregion
|
|
173
|
-
export { WebhookRouteInput as C, WebhookRouteContext as S, ResourceState as _, FetchChangesResult as a, WebhookHandler as b, ResourceBatch as c, ResourceMutation as d, ResourceName as f, ResourceSchema as g, ResourceRows as h, DeleteValue as i, ResourceDefinition as l, ResourceRow as m, ConnectorDefinition as n, FetchPageResult as o, ResourcePayload as p, Cursor as r, PageFetch as s, ChangesFetch as t, ResourceField as u, SyncState as v, WebhookRoute as x, WebhookAckMode as y };
|
|
174
|
-
//# sourceMappingURL=types-jVD5Ys43.d.ts.map
|
package/dist/webhook/index.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import "../index-DKoRwyFn.js";
|
|
2
|
-
import { C as WebhookRouteInput, S as WebhookRouteContext, x as WebhookRoute, y as WebhookAckMode } from "../types-jVD5Ys43.js";
|
|
3
|
-
import "../service-CUjGhe-7.js";
|
|
4
|
-
import "../index-ZSuiZX5H.js";
|
|
5
|
-
import "../index-BA8ASHKr.js";
|
|
6
|
-
import { n as route, r as router } from "../index-BKw7jA2a.js";
|
|
7
|
-
export { WebhookAckMode, WebhookRoute, WebhookRouteContext, WebhookRouteInput, route, router };
|
package/dist/webhook/index.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import "../errors-DHWylqRZ.js";
|
|
2
|
-
import "../constants-D113Ut1x.js";
|
|
3
|
-
import "../telemetry-j_nxwYfh.js";
|
|
4
|
-
import "../metrics-inkCAxKq.js";
|
|
5
|
-
import "../service-DiP-XETo.js";
|
|
6
|
-
import { n as router } from "../server-D-eLX3yN.js";
|
|
7
|
-
import { t as route } from "../webhook-MhFcLW-o.js";
|
|
8
|
-
|
|
9
|
-
export { route, router };
|
package/dist/webhook-MhFcLW-o.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { t as __export } from "./chunk-Bp6m_JJh.js";
|
|
2
|
-
import { n as router } from "./server-D-eLX3yN.js";
|
|
3
|
-
|
|
4
|
-
//#region src/webhook/index.ts
|
|
5
|
-
var webhook_exports = /* @__PURE__ */ __export({
|
|
6
|
-
route: () => route,
|
|
7
|
-
router: () => router
|
|
8
|
-
});
|
|
9
|
-
const route = (definition) => definition;
|
|
10
|
-
|
|
11
|
-
//#endregion
|
|
12
|
-
export { webhook_exports as n, route as t };
|
|
13
|
-
//# sourceMappingURL=webhook-MhFcLW-o.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webhook-MhFcLW-o.js","names":[],"sources":["../src/webhook/index.ts"],"sourcesContent":["import type { ResourceDefinition, WebhookRoute, WebhookRouteInput } from \"../core/types\";\n\nexport { router } from \"./server\";\nexport type { WebhookAckMode, WebhookRoute, WebhookRouteContext, WebhookRouteInput } from \"./types\";\n\nexport const route = <const Resources extends ReadonlyArray<ResourceDefinition>, Payload>(\n definition: WebhookRouteInput<Resources, Payload>,\n): WebhookRoute<Resources, Payload> => definition;\n"],"mappings":";;;;;;;;AAKA,MAAa,SACX,eACqC"}
|
package/src/publisher/console.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Effect, Layer } from "effect";
|
|
2
|
-
|
|
3
|
-
import { Publisher } from "./service";
|
|
4
|
-
|
|
5
|
-
export const layerConsole = Layer.succeed(Publisher)({
|
|
6
|
-
publish: ({ resource, source, batch }) =>
|
|
7
|
-
Effect.gen(function* () {
|
|
8
|
-
yield* Effect.logInfo(`[publisher] -> Source: ${source} | Resource: ${resource}`).pipe(
|
|
9
|
-
Effect.annotateLogs({
|
|
10
|
-
mutations: batch.mutations.length,
|
|
11
|
-
cursor: batch.cursor,
|
|
12
|
-
source,
|
|
13
|
-
}),
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
return { status: "accepted" as const, resource };
|
|
17
|
-
}),
|
|
18
|
-
});
|
package/src/publisher/index.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export type { ResourceBatch } from "../core/types";
|
|
2
|
-
export type { PublishAck, PublishOptions, PublisherService, PublishSource } from "./service";
|
|
3
|
-
export type { WingsPublisherConfig } from "./wings";
|
|
4
|
-
|
|
5
|
-
export { layerConsole } from "./console";
|
|
6
|
-
export { Publisher } from "./service";
|
|
7
|
-
export { layerWings, layerWingsConfig } from "./wings";
|