@lunora/runtime 1.0.0-alpha.24 → 1.0.0-alpha.26
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/dist/index.d.mts +65 -1
- package/dist/index.d.ts +65 -1
- package/dist/index.mjs +2 -2
- package/dist/packem_shared/analyticsEngineSink-F-5ZAdUA.mjs +200 -0
- package/dist/packem_shared/{composeWorker-CxwkPZUl.mjs → composeWorker-BMxMYwKq.mjs} +7 -2
- package/dist/packem_shared/otlp-D_YzGXu1.mjs +81 -0
- package/package.json +1 -1
- package/dist/packem_shared/analyticsEngineSink-DqEvrQs0.mjs +0 -141
package/dist/index.d.mts
CHANGED
|
@@ -682,6 +682,16 @@ interface ObservabilityEvent {
|
|
|
682
682
|
ok: boolean;
|
|
683
683
|
/** Shard key for single-shard calls; absent for fan-outs. */
|
|
684
684
|
shardKey?: string;
|
|
685
|
+
/**
|
|
686
|
+
* W3C trace context for this dispatch, generated once at dispatch entry (32-
|
|
687
|
+
* and 16-hex). A sink (e.g. `otlpSink`) reuses these for the dispatch's span
|
|
688
|
+
* instead of minting fresh ids, and the runtime propagates them to the shard
|
|
689
|
+
* as a `traceparent` so a container the handler calls can stitch its spans
|
|
690
|
+
* under the same trace. Absent on paths that don't originate a trace (a sink
|
|
691
|
+
* falls back to random ids).
|
|
692
|
+
*/
|
|
693
|
+
spanId?: string;
|
|
694
|
+
traceId?: string;
|
|
685
695
|
}
|
|
686
696
|
/** Severity of a {@link LogEvent}, mirroring the usual console levels. */
|
|
687
697
|
type LogLevel = "debug" | "error" | "info" | "log" | "warn";
|
|
@@ -2778,6 +2788,60 @@ interface AnalyticsEngineSinkOptions extends OnlyErrorsOption {
|
|
|
2778
2788
|
* only error events (defaults to all events).
|
|
2779
2789
|
*/
|
|
2780
2790
|
declare const analyticsEngineSink: (options: AnalyticsEngineSinkOptions) => ObservabilitySink;
|
|
2791
|
+
/** Options for {@link otlpSink}. */
|
|
2792
|
+
interface OtlpSinkOptions extends OnlyErrorsOption {
|
|
2793
|
+
/**
|
|
2794
|
+
* The OTLP-over-HTTP collector base endpoint (e.g.
|
|
2795
|
+
* `https://collector.example.com`). Following the OTel base-endpoint
|
|
2796
|
+
* convention, the sink POSTs spans to `${endpoint}/v1/traces` and log
|
|
2797
|
+
* records to `${endpoint}/v1/logs`; a trailing slash is tolerated.
|
|
2798
|
+
*/
|
|
2799
|
+
endpoint: string;
|
|
2800
|
+
/**
|
|
2801
|
+
* Extra headers merged onto every OTLP POST — typically an `Authorization`
|
|
2802
|
+
* bearer plus the `x-lunora-deployment` / `x-lunora-org` correlation headers
|
|
2803
|
+
* the platform injects at deploy. `Content-Type: application/json` is set by
|
|
2804
|
+
* default and may be overridden here.
|
|
2805
|
+
*/
|
|
2806
|
+
headers?: Record<string, string>;
|
|
2807
|
+
/**
|
|
2808
|
+
* Value of the `service.name` resource attribute on every exported span and
|
|
2809
|
+
* log — the logical service the telemetry belongs to. Defaults to `lunora`.
|
|
2810
|
+
*/
|
|
2811
|
+
serviceName?: string;
|
|
2812
|
+
/**
|
|
2813
|
+
* Convenience bearer token: when set, an `Authorization: Bearer` header
|
|
2814
|
+
* carrying it is added to every POST (overriding any authorization in
|
|
2815
|
+
* `headers`). Mirrors the container exporter so the platform can inject the
|
|
2816
|
+
* same `LUNORA_OTLP_TOKEN` into both. Leave unset for an unauthenticated collector.
|
|
2817
|
+
*/
|
|
2818
|
+
token?: string;
|
|
2819
|
+
}
|
|
2820
|
+
/**
|
|
2821
|
+
* A fire-and-forget sink that exports telemetry over OTLP-over-HTTP (JSON).
|
|
2822
|
+
*
|
|
2823
|
+
* This is the single, standard wire contract both the worker and (via the
|
|
2824
|
+
* container exporter helper) container processes use, so telemetry from either
|
|
2825
|
+
* side lands in the same collector. Each RPC dispatch becomes one OTLP **span**
|
|
2826
|
+
* (`${endpoint}/v1/traces`) named after its `functionPath`, with start/end
|
|
2827
|
+
* derived from `durationMs` and status OK/ERROR; each `ctx.log.*` line becomes
|
|
2828
|
+
* one OTLP **log record** (`${endpoint}/v1/logs`). Trace/span ids are random
|
|
2829
|
+
* per span — real trace correlation (worker→container `traceparent`) is a later
|
|
2830
|
+
* phase.
|
|
2831
|
+
*
|
|
2832
|
+
* Like {@link webhookSink}, each export is its own `fetch`, registered with the
|
|
2833
|
+
* request's `context.waitUntil` when present so it survives isolate teardown,
|
|
2834
|
+
* and every rejection is swallowed so a flaky collector never surfaces to the
|
|
2835
|
+
* caller.
|
|
2836
|
+
*
|
|
2837
|
+
* Privacy: spans carry `error.type`/`error.message` and logs carry the rendered
|
|
2838
|
+
* `message`, which may include user input. Point `endpoint` only at a collector
|
|
2839
|
+
* you trust, and gate PII upstream if that is a concern.
|
|
2840
|
+
* @param options Sink options: `endpoint` is the collector base URL, `headers`
|
|
2841
|
+
* are merged onto every POST (auth + correlation), `serviceName` sets the
|
|
2842
|
+
* resource `service.name`, and `onlyErrors` exports error spans only.
|
|
2843
|
+
*/
|
|
2844
|
+
declare const otlpSink: (options: OtlpSinkOptions) => ObservabilitySink;
|
|
2781
2845
|
/**
|
|
2782
2846
|
* Combine several sinks into one that fans each event out to all of them.
|
|
2783
2847
|
*
|
|
@@ -2787,4 +2851,4 @@ declare const analyticsEngineSink: (options: AnalyticsEngineSinkOptions) => Obse
|
|
|
2787
2851
|
*/
|
|
2788
2852
|
declare const combineSinks: (...sinks: ObservabilitySink[]) => ObservabilitySink;
|
|
2789
2853
|
declare const VERSION: string;
|
|
2790
|
-
export { type AdminTableResolver, type AirbyteMessage, type AnalyticsEngineDataPointLike, type AnalyticsEngineDatasetLike, type AnalyticsEngineSinkOptions, type AuthAdmin, type AuthCapabilities, type AuthConfigInfo, type AuthImpersonation, type AuthIntrospector, type AuthPage, type AuthSession, type AuthUser, type AuthUserFieldSpec, type BackupManifest, type BackupStore, type ComposeIdentityResolversErrorMode, type ComposeIdentityResolversOptions, type ConnectorChange, type ConnectorSyncPage, type CorsOptions, type CronHandler, type CronJobDispatch, type CronJobInfo, type CrossShardCounter, type CrossShardReader, type CrossShardRelationCapabilities, type CrossShardRelationOptions, type CsrfOptions, DEFAULT_REGISTRY_CACHE_TTL_MS, type DurableObjectJurisdiction, type DynamicShardRegistry, type DynamicShardRegistryOptions, type ExecutionContextLike, type ExportFanOutRequest, type ExportFanOutResult, type FanOutRequest, type FanOutResult, type FanOutSpec, type FivetranResponse, type FrameworkHostHandler, type FrameworkWorkerOptions, type FrameworkWorkerOptionsInput, type FunctionDescriptor, type FunctionRegistryEntry, type FunctionRegistryLike, type GlobalExportFunction as GlobalExportFn, type GlobalImportFunction as GlobalImportFn, type GlobalIntrospector, type GlobalTableInfo as GlobalTableInfoMeta, type GlobalTablePage as GlobalTablePageMeta, type HttpActionContext, type HttpActionLike, type HttpRouterLike, type IdentityContractLike, type IdentityResolver, type IdentityValidation, type ImportFanOutRequest, type ImportFanOutResult, type KvIntrospector, type KvKeyEntry, type KvKeyListResult, type KvNamespaceSummary, type KvValueResult, type ListAuthUsersOptions, type LogEvent, type LogLevel, LunoraError, type LunoraErrorBody, type LunoraHandlerOptions, type LunoraWorker, type MergeStrategy, type MigrationFanOutRequest, type MigrationFanOutResult, NOOP_EXECUTION_CONTEXT, type ObservabilityEvent, type ObservabilitySink, type ObservabilitySinkContext, type QueryCoordinator, type QueryCoordinatorOptions, type RankFanOutRequest, type RankFanOutResult, type RankPageFanOutRequest, type RankPageFanOutResult, type ResolvedSecurity, type ResolvedShard, type Route, type RpcContext, type RpcEnvelope, SHARD_REGISTRY_DO_NAME, type ScheduledControllerLike, type SecurityHeadersOptions, type SecurityOptions, type SentrySinkOptions, type ShardError, type ShardExportOutcome, type ShardImportOutcome, type ShardMigrationOutcome, type ShardNamespaceLike, type ShardRankOutcome, type ShardRankPageOutcome, type ShardRegistry, type ShardTrafficEntry, type ShardTrafficFanOutRequest, type ShardTrafficFanOutResult, type ShardingInfo, type StorageListFunction as StorageListFn, type StorageObject, VERSION, type VectorIndexSummary, type VectorIntrospector, type VectorQueryMatch, type WebhookSinkOptions, type WorkerOptions, analyticsEngineSink, applyJurisdiction, combineSinks, composeIdentityResolvers, composeWorker, consoleSink, createCrossShardRelationCapabilities, createDynamicShardRegistry, createLunoraHandler, createQueryCoordinator, createStaticShardRegistry, createWorker, decorateResponse, defineRpcEnvelope, emitLogEvent, emitRpcEvent, enforceOrigin, handleCorsPreflight, mergeStrategyForAggregate, resolveLunoraOptions, resolveSecurity, resolveShard, routeIdentityResolvers, sentrySink, toAirbyteMessages, toErrorResponse, toFivetranResponse, webhookSink, withFrameworkWorker };
|
|
2854
|
+
export { type AdminTableResolver, type AirbyteMessage, type AnalyticsEngineDataPointLike, type AnalyticsEngineDatasetLike, type AnalyticsEngineSinkOptions, type AuthAdmin, type AuthCapabilities, type AuthConfigInfo, type AuthImpersonation, type AuthIntrospector, type AuthPage, type AuthSession, type AuthUser, type AuthUserFieldSpec, type BackupManifest, type BackupStore, type ComposeIdentityResolversErrorMode, type ComposeIdentityResolversOptions, type ConnectorChange, type ConnectorSyncPage, type CorsOptions, type CronHandler, type CronJobDispatch, type CronJobInfo, type CrossShardCounter, type CrossShardReader, type CrossShardRelationCapabilities, type CrossShardRelationOptions, type CsrfOptions, DEFAULT_REGISTRY_CACHE_TTL_MS, type DurableObjectJurisdiction, type DynamicShardRegistry, type DynamicShardRegistryOptions, type ExecutionContextLike, type ExportFanOutRequest, type ExportFanOutResult, type FanOutRequest, type FanOutResult, type FanOutSpec, type FivetranResponse, type FrameworkHostHandler, type FrameworkWorkerOptions, type FrameworkWorkerOptionsInput, type FunctionDescriptor, type FunctionRegistryEntry, type FunctionRegistryLike, type GlobalExportFunction as GlobalExportFn, type GlobalImportFunction as GlobalImportFn, type GlobalIntrospector, type GlobalTableInfo as GlobalTableInfoMeta, type GlobalTablePage as GlobalTablePageMeta, type HttpActionContext, type HttpActionLike, type HttpRouterLike, type IdentityContractLike, type IdentityResolver, type IdentityValidation, type ImportFanOutRequest, type ImportFanOutResult, type KvIntrospector, type KvKeyEntry, type KvKeyListResult, type KvNamespaceSummary, type KvValueResult, type ListAuthUsersOptions, type LogEvent, type LogLevel, LunoraError, type LunoraErrorBody, type LunoraHandlerOptions, type LunoraWorker, type MergeStrategy, type MigrationFanOutRequest, type MigrationFanOutResult, NOOP_EXECUTION_CONTEXT, type ObservabilityEvent, type ObservabilitySink, type ObservabilitySinkContext, type OtlpSinkOptions, type QueryCoordinator, type QueryCoordinatorOptions, type RankFanOutRequest, type RankFanOutResult, type RankPageFanOutRequest, type RankPageFanOutResult, type ResolvedSecurity, type ResolvedShard, type Route, type RpcContext, type RpcEnvelope, SHARD_REGISTRY_DO_NAME, type ScheduledControllerLike, type SecurityHeadersOptions, type SecurityOptions, type SentrySinkOptions, type ShardError, type ShardExportOutcome, type ShardImportOutcome, type ShardMigrationOutcome, type ShardNamespaceLike, type ShardRankOutcome, type ShardRankPageOutcome, type ShardRegistry, type ShardTrafficEntry, type ShardTrafficFanOutRequest, type ShardTrafficFanOutResult, type ShardingInfo, type StorageListFunction as StorageListFn, type StorageObject, VERSION, type VectorIndexSummary, type VectorIntrospector, type VectorQueryMatch, type WebhookSinkOptions, type WorkerOptions, analyticsEngineSink, applyJurisdiction, combineSinks, composeIdentityResolvers, composeWorker, consoleSink, createCrossShardRelationCapabilities, createDynamicShardRegistry, createLunoraHandler, createQueryCoordinator, createStaticShardRegistry, createWorker, decorateResponse, defineRpcEnvelope, emitLogEvent, emitRpcEvent, enforceOrigin, handleCorsPreflight, mergeStrategyForAggregate, otlpSink, resolveLunoraOptions, resolveSecurity, resolveShard, routeIdentityResolvers, sentrySink, toAirbyteMessages, toErrorResponse, toFivetranResponse, webhookSink, withFrameworkWorker };
|
package/dist/index.d.ts
CHANGED
|
@@ -682,6 +682,16 @@ interface ObservabilityEvent {
|
|
|
682
682
|
ok: boolean;
|
|
683
683
|
/** Shard key for single-shard calls; absent for fan-outs. */
|
|
684
684
|
shardKey?: string;
|
|
685
|
+
/**
|
|
686
|
+
* W3C trace context for this dispatch, generated once at dispatch entry (32-
|
|
687
|
+
* and 16-hex). A sink (e.g. `otlpSink`) reuses these for the dispatch's span
|
|
688
|
+
* instead of minting fresh ids, and the runtime propagates them to the shard
|
|
689
|
+
* as a `traceparent` so a container the handler calls can stitch its spans
|
|
690
|
+
* under the same trace. Absent on paths that don't originate a trace (a sink
|
|
691
|
+
* falls back to random ids).
|
|
692
|
+
*/
|
|
693
|
+
spanId?: string;
|
|
694
|
+
traceId?: string;
|
|
685
695
|
}
|
|
686
696
|
/** Severity of a {@link LogEvent}, mirroring the usual console levels. */
|
|
687
697
|
type LogLevel = "debug" | "error" | "info" | "log" | "warn";
|
|
@@ -2778,6 +2788,60 @@ interface AnalyticsEngineSinkOptions extends OnlyErrorsOption {
|
|
|
2778
2788
|
* only error events (defaults to all events).
|
|
2779
2789
|
*/
|
|
2780
2790
|
declare const analyticsEngineSink: (options: AnalyticsEngineSinkOptions) => ObservabilitySink;
|
|
2791
|
+
/** Options for {@link otlpSink}. */
|
|
2792
|
+
interface OtlpSinkOptions extends OnlyErrorsOption {
|
|
2793
|
+
/**
|
|
2794
|
+
* The OTLP-over-HTTP collector base endpoint (e.g.
|
|
2795
|
+
* `https://collector.example.com`). Following the OTel base-endpoint
|
|
2796
|
+
* convention, the sink POSTs spans to `${endpoint}/v1/traces` and log
|
|
2797
|
+
* records to `${endpoint}/v1/logs`; a trailing slash is tolerated.
|
|
2798
|
+
*/
|
|
2799
|
+
endpoint: string;
|
|
2800
|
+
/**
|
|
2801
|
+
* Extra headers merged onto every OTLP POST — typically an `Authorization`
|
|
2802
|
+
* bearer plus the `x-lunora-deployment` / `x-lunora-org` correlation headers
|
|
2803
|
+
* the platform injects at deploy. `Content-Type: application/json` is set by
|
|
2804
|
+
* default and may be overridden here.
|
|
2805
|
+
*/
|
|
2806
|
+
headers?: Record<string, string>;
|
|
2807
|
+
/**
|
|
2808
|
+
* Value of the `service.name` resource attribute on every exported span and
|
|
2809
|
+
* log — the logical service the telemetry belongs to. Defaults to `lunora`.
|
|
2810
|
+
*/
|
|
2811
|
+
serviceName?: string;
|
|
2812
|
+
/**
|
|
2813
|
+
* Convenience bearer token: when set, an `Authorization: Bearer` header
|
|
2814
|
+
* carrying it is added to every POST (overriding any authorization in
|
|
2815
|
+
* `headers`). Mirrors the container exporter so the platform can inject the
|
|
2816
|
+
* same `LUNORA_OTLP_TOKEN` into both. Leave unset for an unauthenticated collector.
|
|
2817
|
+
*/
|
|
2818
|
+
token?: string;
|
|
2819
|
+
}
|
|
2820
|
+
/**
|
|
2821
|
+
* A fire-and-forget sink that exports telemetry over OTLP-over-HTTP (JSON).
|
|
2822
|
+
*
|
|
2823
|
+
* This is the single, standard wire contract both the worker and (via the
|
|
2824
|
+
* container exporter helper) container processes use, so telemetry from either
|
|
2825
|
+
* side lands in the same collector. Each RPC dispatch becomes one OTLP **span**
|
|
2826
|
+
* (`${endpoint}/v1/traces`) named after its `functionPath`, with start/end
|
|
2827
|
+
* derived from `durationMs` and status OK/ERROR; each `ctx.log.*` line becomes
|
|
2828
|
+
* one OTLP **log record** (`${endpoint}/v1/logs`). Trace/span ids are random
|
|
2829
|
+
* per span — real trace correlation (worker→container `traceparent`) is a later
|
|
2830
|
+
* phase.
|
|
2831
|
+
*
|
|
2832
|
+
* Like {@link webhookSink}, each export is its own `fetch`, registered with the
|
|
2833
|
+
* request's `context.waitUntil` when present so it survives isolate teardown,
|
|
2834
|
+
* and every rejection is swallowed so a flaky collector never surfaces to the
|
|
2835
|
+
* caller.
|
|
2836
|
+
*
|
|
2837
|
+
* Privacy: spans carry `error.type`/`error.message` and logs carry the rendered
|
|
2838
|
+
* `message`, which may include user input. Point `endpoint` only at a collector
|
|
2839
|
+
* you trust, and gate PII upstream if that is a concern.
|
|
2840
|
+
* @param options Sink options: `endpoint` is the collector base URL, `headers`
|
|
2841
|
+
* are merged onto every POST (auth + correlation), `serviceName` sets the
|
|
2842
|
+
* resource `service.name`, and `onlyErrors` exports error spans only.
|
|
2843
|
+
*/
|
|
2844
|
+
declare const otlpSink: (options: OtlpSinkOptions) => ObservabilitySink;
|
|
2781
2845
|
/**
|
|
2782
2846
|
* Combine several sinks into one that fans each event out to all of them.
|
|
2783
2847
|
*
|
|
@@ -2787,4 +2851,4 @@ declare const analyticsEngineSink: (options: AnalyticsEngineSinkOptions) => Obse
|
|
|
2787
2851
|
*/
|
|
2788
2852
|
declare const combineSinks: (...sinks: ObservabilitySink[]) => ObservabilitySink;
|
|
2789
2853
|
declare const VERSION: string;
|
|
2790
|
-
export { type AdminTableResolver, type AirbyteMessage, type AnalyticsEngineDataPointLike, type AnalyticsEngineDatasetLike, type AnalyticsEngineSinkOptions, type AuthAdmin, type AuthCapabilities, type AuthConfigInfo, type AuthImpersonation, type AuthIntrospector, type AuthPage, type AuthSession, type AuthUser, type AuthUserFieldSpec, type BackupManifest, type BackupStore, type ComposeIdentityResolversErrorMode, type ComposeIdentityResolversOptions, type ConnectorChange, type ConnectorSyncPage, type CorsOptions, type CronHandler, type CronJobDispatch, type CronJobInfo, type CrossShardCounter, type CrossShardReader, type CrossShardRelationCapabilities, type CrossShardRelationOptions, type CsrfOptions, DEFAULT_REGISTRY_CACHE_TTL_MS, type DurableObjectJurisdiction, type DynamicShardRegistry, type DynamicShardRegistryOptions, type ExecutionContextLike, type ExportFanOutRequest, type ExportFanOutResult, type FanOutRequest, type FanOutResult, type FanOutSpec, type FivetranResponse, type FrameworkHostHandler, type FrameworkWorkerOptions, type FrameworkWorkerOptionsInput, type FunctionDescriptor, type FunctionRegistryEntry, type FunctionRegistryLike, type GlobalExportFunction as GlobalExportFn, type GlobalImportFunction as GlobalImportFn, type GlobalIntrospector, type GlobalTableInfo as GlobalTableInfoMeta, type GlobalTablePage as GlobalTablePageMeta, type HttpActionContext, type HttpActionLike, type HttpRouterLike, type IdentityContractLike, type IdentityResolver, type IdentityValidation, type ImportFanOutRequest, type ImportFanOutResult, type KvIntrospector, type KvKeyEntry, type KvKeyListResult, type KvNamespaceSummary, type KvValueResult, type ListAuthUsersOptions, type LogEvent, type LogLevel, LunoraError, type LunoraErrorBody, type LunoraHandlerOptions, type LunoraWorker, type MergeStrategy, type MigrationFanOutRequest, type MigrationFanOutResult, NOOP_EXECUTION_CONTEXT, type ObservabilityEvent, type ObservabilitySink, type ObservabilitySinkContext, type QueryCoordinator, type QueryCoordinatorOptions, type RankFanOutRequest, type RankFanOutResult, type RankPageFanOutRequest, type RankPageFanOutResult, type ResolvedSecurity, type ResolvedShard, type Route, type RpcContext, type RpcEnvelope, SHARD_REGISTRY_DO_NAME, type ScheduledControllerLike, type SecurityHeadersOptions, type SecurityOptions, type SentrySinkOptions, type ShardError, type ShardExportOutcome, type ShardImportOutcome, type ShardMigrationOutcome, type ShardNamespaceLike, type ShardRankOutcome, type ShardRankPageOutcome, type ShardRegistry, type ShardTrafficEntry, type ShardTrafficFanOutRequest, type ShardTrafficFanOutResult, type ShardingInfo, type StorageListFunction as StorageListFn, type StorageObject, VERSION, type VectorIndexSummary, type VectorIntrospector, type VectorQueryMatch, type WebhookSinkOptions, type WorkerOptions, analyticsEngineSink, applyJurisdiction, combineSinks, composeIdentityResolvers, composeWorker, consoleSink, createCrossShardRelationCapabilities, createDynamicShardRegistry, createLunoraHandler, createQueryCoordinator, createStaticShardRegistry, createWorker, decorateResponse, defineRpcEnvelope, emitLogEvent, emitRpcEvent, enforceOrigin, handleCorsPreflight, mergeStrategyForAggregate, resolveLunoraOptions, resolveSecurity, resolveShard, routeIdentityResolvers, sentrySink, toAirbyteMessages, toErrorResponse, toFivetranResponse, webhookSink, withFrameworkWorker };
|
|
2854
|
+
export { type AdminTableResolver, type AirbyteMessage, type AnalyticsEngineDataPointLike, type AnalyticsEngineDatasetLike, type AnalyticsEngineSinkOptions, type AuthAdmin, type AuthCapabilities, type AuthConfigInfo, type AuthImpersonation, type AuthIntrospector, type AuthPage, type AuthSession, type AuthUser, type AuthUserFieldSpec, type BackupManifest, type BackupStore, type ComposeIdentityResolversErrorMode, type ComposeIdentityResolversOptions, type ConnectorChange, type ConnectorSyncPage, type CorsOptions, type CronHandler, type CronJobDispatch, type CronJobInfo, type CrossShardCounter, type CrossShardReader, type CrossShardRelationCapabilities, type CrossShardRelationOptions, type CsrfOptions, DEFAULT_REGISTRY_CACHE_TTL_MS, type DurableObjectJurisdiction, type DynamicShardRegistry, type DynamicShardRegistryOptions, type ExecutionContextLike, type ExportFanOutRequest, type ExportFanOutResult, type FanOutRequest, type FanOutResult, type FanOutSpec, type FivetranResponse, type FrameworkHostHandler, type FrameworkWorkerOptions, type FrameworkWorkerOptionsInput, type FunctionDescriptor, type FunctionRegistryEntry, type FunctionRegistryLike, type GlobalExportFunction as GlobalExportFn, type GlobalImportFunction as GlobalImportFn, type GlobalIntrospector, type GlobalTableInfo as GlobalTableInfoMeta, type GlobalTablePage as GlobalTablePageMeta, type HttpActionContext, type HttpActionLike, type HttpRouterLike, type IdentityContractLike, type IdentityResolver, type IdentityValidation, type ImportFanOutRequest, type ImportFanOutResult, type KvIntrospector, type KvKeyEntry, type KvKeyListResult, type KvNamespaceSummary, type KvValueResult, type ListAuthUsersOptions, type LogEvent, type LogLevel, LunoraError, type LunoraErrorBody, type LunoraHandlerOptions, type LunoraWorker, type MergeStrategy, type MigrationFanOutRequest, type MigrationFanOutResult, NOOP_EXECUTION_CONTEXT, type ObservabilityEvent, type ObservabilitySink, type ObservabilitySinkContext, type OtlpSinkOptions, type QueryCoordinator, type QueryCoordinatorOptions, type RankFanOutRequest, type RankFanOutResult, type RankPageFanOutRequest, type RankPageFanOutResult, type ResolvedSecurity, type ResolvedShard, type Route, type RpcContext, type RpcEnvelope, SHARD_REGISTRY_DO_NAME, type ScheduledControllerLike, type SecurityHeadersOptions, type SecurityOptions, type SentrySinkOptions, type ShardError, type ShardExportOutcome, type ShardImportOutcome, type ShardMigrationOutcome, type ShardNamespaceLike, type ShardRankOutcome, type ShardRankPageOutcome, type ShardRegistry, type ShardTrafficEntry, type ShardTrafficFanOutRequest, type ShardTrafficFanOutResult, type ShardingInfo, type StorageListFunction as StorageListFn, type StorageObject, VERSION, type VectorIndexSummary, type VectorIntrospector, type VectorQueryMatch, type WebhookSinkOptions, type WorkerOptions, analyticsEngineSink, applyJurisdiction, combineSinks, composeIdentityResolvers, composeWorker, consoleSink, createCrossShardRelationCapabilities, createDynamicShardRegistry, createLunoraHandler, createQueryCoordinator, createStaticShardRegistry, createWorker, decorateResponse, defineRpcEnvelope, emitLogEvent, emitRpcEvent, enforceOrigin, handleCorsPreflight, mergeStrategyForAggregate, otlpSink, resolveLunoraOptions, resolveSecurity, resolveShard, routeIdentityResolvers, sentrySink, toAirbyteMessages, toErrorResponse, toFivetranResponse, webhookSink, withFrameworkWorker };
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export { toAirbyteMessages, toFivetranResponse } from './packem_shared/toAirbyteMessages-DrHdplb4.mjs';
|
|
2
|
-
export { composeWorker, createLunoraHandler, createWorker, defineRpcEnvelope, resolveLunoraOptions, withFrameworkWorker } from './packem_shared/composeWorker-
|
|
2
|
+
export { composeWorker, createLunoraHandler, createWorker, defineRpcEnvelope, resolveLunoraOptions, withFrameworkWorker } from './packem_shared/composeWorker-BMxMYwKq.mjs';
|
|
3
3
|
export { createCrossShardRelationCapabilities } from './packem_shared/createCrossShardRelationCapabilities-CbcWjkAn.mjs';
|
|
4
4
|
export { DEFAULT_REGISTRY_CACHE_TTL_MS, SHARD_REGISTRY_DO_NAME, createDynamicShardRegistry } from './packem_shared/DEFAULT_REGISTRY_CACHE_TTL_MS-B3pA7aXp.mjs';
|
|
5
5
|
export { LunoraError, toErrorResponse } from './packem_shared/LunoraError-Bpb9EFJ3.mjs';
|
|
6
6
|
export { emitLogEvent, emitRpcEvent } from './packem_shared/emitLogEvent-pEdtqAK8.mjs';
|
|
7
|
-
export { analyticsEngineSink, combineSinks, consoleSink, sentrySink, webhookSink } from './packem_shared/analyticsEngineSink-
|
|
7
|
+
export { analyticsEngineSink, combineSinks, consoleSink, otlpSink, sentrySink, webhookSink } from './packem_shared/analyticsEngineSink-F-5ZAdUA.mjs';
|
|
8
8
|
export { createQueryCoordinator, createStaticShardRegistry, mergeStrategyForAggregate } from './packem_shared/createQueryCoordinator-DNCJzOZE.mjs';
|
|
9
9
|
export { applyJurisdiction, resolveShard } from './packem_shared/applyJurisdiction-BkZtTkct.mjs';
|
|
10
10
|
export { decorateResponse, enforceOrigin, handleCorsPreflight, resolveSecurity } from './packem_shared/decorateResponse-DRWQFNhF.mjs';
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { m as mergeHeaders, o as otlpRandomHex, w as wrapResourceSpans, a as wrapResourceLogs, e as encodeAttribute, O as OTLP_SEVERITY, c as otlpUnixNano } from './otlp-D_YzGXu1.mjs';
|
|
2
|
+
|
|
3
|
+
const shouldSkip = (event, onlyErrors) => onlyErrors === true && event.ok;
|
|
4
|
+
const otlpTraceBody = (event, serviceName, endMs) => {
|
|
5
|
+
const attributes = [encodeAttribute("lunora.function_path", event.functionPath), encodeAttribute("lunora.ok", event.ok)];
|
|
6
|
+
if (event.shardKey !== void 0) {
|
|
7
|
+
attributes.push(encodeAttribute("lunora.shard_key", event.shardKey));
|
|
8
|
+
}
|
|
9
|
+
if (event.error) {
|
|
10
|
+
attributes.push(encodeAttribute("error.type", event.error.code), encodeAttribute("lunora.error_status", event.error.status));
|
|
11
|
+
}
|
|
12
|
+
if (event.fanOut) {
|
|
13
|
+
attributes.push(
|
|
14
|
+
encodeAttribute("lunora.fanout.table", event.fanOut.table),
|
|
15
|
+
encodeAttribute("lunora.fanout.shards", event.fanOut.shards),
|
|
16
|
+
encodeAttribute("lunora.fanout.failed", event.fanOut.failed)
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
const span = {
|
|
20
|
+
attributes,
|
|
21
|
+
endTimeUnixNano: otlpUnixNano(endMs),
|
|
22
|
+
// SPAN_KIND_SERVER — a dispatched RPC is server-side request handling.
|
|
23
|
+
kind: 2,
|
|
24
|
+
name: event.functionPath,
|
|
25
|
+
// Reuse the dispatch's trace context when the runtime set it (so this span
|
|
26
|
+
// shares the id it propagated as `traceparent`); else mint fresh ids.
|
|
27
|
+
spanId: event.spanId ?? otlpRandomHex(8),
|
|
28
|
+
startTimeUnixNano: otlpUnixNano(endMs - event.durationMs),
|
|
29
|
+
// STATUS_CODE_OK (1) / STATUS_CODE_ERROR (2).
|
|
30
|
+
status: event.ok ? { code: 1 } : { code: 2, message: event.error?.message ?? "" },
|
|
31
|
+
traceId: event.traceId ?? otlpRandomHex(16)
|
|
32
|
+
};
|
|
33
|
+
return wrapResourceSpans(span, "@lunora/runtime", serviceName);
|
|
34
|
+
};
|
|
35
|
+
const otlpLogBody = (event, serviceName) => {
|
|
36
|
+
const attributes = [encodeAttribute("lunora.function_path", event.functionPath)];
|
|
37
|
+
if (event.shardKey !== void 0) {
|
|
38
|
+
attributes.push(encodeAttribute("lunora.shard_key", event.shardKey));
|
|
39
|
+
}
|
|
40
|
+
if (event.userId !== void 0) {
|
|
41
|
+
attributes.push(encodeAttribute("lunora.user_id", event.userId));
|
|
42
|
+
}
|
|
43
|
+
const logRecord = {
|
|
44
|
+
attributes,
|
|
45
|
+
body: { stringValue: event.message },
|
|
46
|
+
severityNumber: OTLP_SEVERITY[event.level],
|
|
47
|
+
severityText: event.level.toUpperCase(),
|
|
48
|
+
timeUnixNano: otlpUnixNano(event.ts)
|
|
49
|
+
};
|
|
50
|
+
return wrapResourceLogs(logRecord, "@lunora/runtime", serviceName);
|
|
51
|
+
};
|
|
52
|
+
const otlpPost = (url, body, headers, context) => {
|
|
53
|
+
try {
|
|
54
|
+
const sent = fetch(url, { body: JSON.stringify(body), headers, method: "POST" }).catch(() => {
|
|
55
|
+
});
|
|
56
|
+
if (context?.waitUntil) {
|
|
57
|
+
context.waitUntil(sent);
|
|
58
|
+
}
|
|
59
|
+
} catch {
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const consoleSink = (options = {}) => {
|
|
63
|
+
const { onlyErrors } = options;
|
|
64
|
+
return {
|
|
65
|
+
onLog: (event) => {
|
|
66
|
+
if (event.level === "error") {
|
|
67
|
+
console.error("[lunora:log]", event.functionPath, event.message);
|
|
68
|
+
} else {
|
|
69
|
+
console.log("[lunora:log]", event.functionPath, event.message);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
onRpc: (event) => {
|
|
73
|
+
if (shouldSkip(event, onlyErrors)) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (event.ok) {
|
|
77
|
+
console.log("[lunora:rpc]", event);
|
|
78
|
+
} else {
|
|
79
|
+
console.error("[lunora:rpc]", event);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
const webhookSink = (options) => {
|
|
85
|
+
const { headers, onlyErrors, transform, url } = options;
|
|
86
|
+
const mergedHeaders = mergeHeaders({ "content-type": "application/json" }, headers);
|
|
87
|
+
return {
|
|
88
|
+
onRpc: (event, context) => {
|
|
89
|
+
if (shouldSkip(event, onlyErrors)) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
let payload = event;
|
|
94
|
+
if (transform) {
|
|
95
|
+
try {
|
|
96
|
+
payload = transform(event);
|
|
97
|
+
} catch {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (payload === null || payload === void 0) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const sent = fetch(url, {
|
|
105
|
+
body: JSON.stringify(payload),
|
|
106
|
+
headers: mergedHeaders,
|
|
107
|
+
method: "POST"
|
|
108
|
+
}).catch(() => {
|
|
109
|
+
});
|
|
110
|
+
if (context?.waitUntil) {
|
|
111
|
+
context.waitUntil(sent);
|
|
112
|
+
}
|
|
113
|
+
} catch {
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
const sentrySink = (options) => {
|
|
119
|
+
const { capture } = options;
|
|
120
|
+
const onlyErrors = options.onlyErrors ?? true;
|
|
121
|
+
return {
|
|
122
|
+
onRpc: (event) => {
|
|
123
|
+
if (shouldSkip(event, onlyErrors)) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
capture(event);
|
|
128
|
+
} catch {
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
const analyticsEngineSink = (options) => {
|
|
134
|
+
const { dataset, onlyErrors } = options;
|
|
135
|
+
return {
|
|
136
|
+
onRpc: (event) => {
|
|
137
|
+
if (shouldSkip(event, onlyErrors)) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
dataset.writeDataPoint({
|
|
142
|
+
blobs: [event.functionPath, event.ok ? "ok" : "error", event.shardKey ?? "", event.error?.code ?? "", event.fanOut?.table ?? ""],
|
|
143
|
+
doubles: [event.durationMs, event.ok ? 0 : 1, event.fanOut?.shards ?? 0, event.fanOut?.failed ?? 0],
|
|
144
|
+
indexes: [event.functionPath]
|
|
145
|
+
});
|
|
146
|
+
} catch {
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
const otlpSink = (options) => {
|
|
152
|
+
const { endpoint, headers, onlyErrors, token } = options;
|
|
153
|
+
const serviceName = options.serviceName ?? "lunora";
|
|
154
|
+
let base = endpoint;
|
|
155
|
+
while (base.endsWith("/")) {
|
|
156
|
+
base = base.slice(0, -1);
|
|
157
|
+
}
|
|
158
|
+
const tracesUrl = `${base}/v1/traces`;
|
|
159
|
+
const logsUrl = `${base}/v1/logs`;
|
|
160
|
+
const mergedHeaders = mergeHeaders({ "content-type": "application/json" }, headers, token);
|
|
161
|
+
return {
|
|
162
|
+
onLog: (event, context) => {
|
|
163
|
+
otlpPost(logsUrl, otlpLogBody(event, serviceName), mergedHeaders, context);
|
|
164
|
+
},
|
|
165
|
+
onRpc: (event, context) => {
|
|
166
|
+
if (shouldSkip(event, onlyErrors)) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
otlpPost(tracesUrl, otlpTraceBody(event, serviceName, Date.now()), mergedHeaders, context);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
};
|
|
173
|
+
const combineSinks = (...sinks) => {
|
|
174
|
+
return {
|
|
175
|
+
onLog: (event, context) => {
|
|
176
|
+
for (const sink of sinks) {
|
|
177
|
+
if (!sink.onLog) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
sink.onLog(event, context);
|
|
182
|
+
} catch {
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
onRpc: (event, context) => {
|
|
187
|
+
for (const sink of sinks) {
|
|
188
|
+
if (!sink.onRpc) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
sink.onRpc(event, context);
|
|
193
|
+
} catch {
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
export { analyticsEngineSink, combineSinks, consoleSink, otlpSink, sentrySink, webhookSink };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isLunoraError, toErrorBody } from '@lunora/errors';
|
|
2
2
|
import { NOOP_EXECUTION_CONTEXT } from './NOOP_EXECUTION_CONTEXT-CCTu0Bf1.mjs';
|
|
3
|
+
import { o as otlpRandomHex, b as buildTraceparent } from './otlp-D_YzGXu1.mjs';
|
|
3
4
|
import { LunoraError, toErrorResponse } from './LunoraError-Bpb9EFJ3.mjs';
|
|
4
5
|
import { wrapResolverWithContract } from './composeIdentityResolvers-XGjO7V1J.mjs';
|
|
5
6
|
export { composeIdentityResolvers, routeIdentityResolvers } from './composeIdentityResolvers-XGjO7V1J.mjs';
|
|
@@ -2605,9 +2606,11 @@ const createWorker = (options) => {
|
|
|
2605
2606
|
const dispatchSingleShard = async (functionPath, args, shardKey, forwardedHeaders, sinkContext) => {
|
|
2606
2607
|
const rpcStartedAt = Date.now();
|
|
2607
2608
|
const { observability } = options;
|
|
2609
|
+
const traceId = otlpRandomHex(16);
|
|
2610
|
+
const spanId = otlpRandomHex(8);
|
|
2608
2611
|
const forwarded = new Request(`https://shard.internal/rpc`, {
|
|
2609
2612
|
body: JSON.stringify({ args, functionPath }),
|
|
2610
|
-
headers: forwardedHeaders,
|
|
2613
|
+
headers: { ...forwardedHeaders, traceparent: buildTraceparent(traceId, spanId) },
|
|
2611
2614
|
method: "POST"
|
|
2612
2615
|
});
|
|
2613
2616
|
try {
|
|
@@ -2619,13 +2622,15 @@ const createWorker = (options) => {
|
|
|
2619
2622
|
functionPath,
|
|
2620
2623
|
ok: response.ok,
|
|
2621
2624
|
shardKey,
|
|
2625
|
+
spanId,
|
|
2626
|
+
traceId,
|
|
2622
2627
|
...response.ok ? {} : { error: { code: "SHARD_ERROR", message: `shard returned ${String(response.status)}`, status: response.status } }
|
|
2623
2628
|
},
|
|
2624
2629
|
sinkContext
|
|
2625
2630
|
);
|
|
2626
2631
|
return response;
|
|
2627
2632
|
} catch (error) {
|
|
2628
|
-
emitRpcEvent(observability, buildErrorEvent(functionPath, Date.now() - rpcStartedAt, error, { shardKey }), sinkContext);
|
|
2633
|
+
emitRpcEvent(observability, { ...buildErrorEvent(functionPath, Date.now() - rpcStartedAt, error, { shardKey }), spanId, traceId }, sinkContext);
|
|
2629
2634
|
throw error;
|
|
2630
2635
|
}
|
|
2631
2636
|
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const OTLP_SEVERITY = {
|
|
2
|
+
debug: 5,
|
|
3
|
+
// DEBUG
|
|
4
|
+
error: 17,
|
|
5
|
+
// ERROR
|
|
6
|
+
info: 9,
|
|
7
|
+
// INFO
|
|
8
|
+
log: 9,
|
|
9
|
+
// INFO
|
|
10
|
+
warn: 13
|
|
11
|
+
// WARN
|
|
12
|
+
};
|
|
13
|
+
const otlpUnixNano = (ms) => `${String(Math.round(ms))}000000`;
|
|
14
|
+
const otlpRandomHex = (bytes) => {
|
|
15
|
+
const buffer = new Uint8Array(bytes);
|
|
16
|
+
crypto.getRandomValues(buffer);
|
|
17
|
+
let hex = "";
|
|
18
|
+
for (const byte of buffer) {
|
|
19
|
+
hex += byte.toString(16).padStart(2, "0");
|
|
20
|
+
}
|
|
21
|
+
return hex;
|
|
22
|
+
};
|
|
23
|
+
const buildTraceparent = (traceId, spanId) => `00-${traceId}-${spanId}-01`;
|
|
24
|
+
const encodeAttribute = (key, value) => {
|
|
25
|
+
if (typeof value === "boolean") {
|
|
26
|
+
return { key, value: { boolValue: value } };
|
|
27
|
+
}
|
|
28
|
+
if (typeof value === "number") {
|
|
29
|
+
if (!Number.isFinite(value)) {
|
|
30
|
+
return { key, value: { stringValue: String(value) } };
|
|
31
|
+
}
|
|
32
|
+
return Number.isSafeInteger(value) ? { key, value: { intValue: String(value) } } : { key, value: { doubleValue: value } };
|
|
33
|
+
}
|
|
34
|
+
return { key, value: { stringValue: value } };
|
|
35
|
+
};
|
|
36
|
+
const mergeHeaders = (defaults, overrides, token) => {
|
|
37
|
+
const merged = {};
|
|
38
|
+
const seen = /* @__PURE__ */ new Map();
|
|
39
|
+
const put = (name, value) => {
|
|
40
|
+
const lower = name.toLowerCase();
|
|
41
|
+
const existing = seen.get(lower);
|
|
42
|
+
if (existing === void 0) {
|
|
43
|
+
seen.set(lower, name);
|
|
44
|
+
merged[name] = value;
|
|
45
|
+
} else {
|
|
46
|
+
merged[existing] = value;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
for (const [name, value] of Object.entries(defaults)) {
|
|
50
|
+
put(name, value);
|
|
51
|
+
}
|
|
52
|
+
for (const [name, value] of Object.entries(overrides ?? {})) {
|
|
53
|
+
put(name, value);
|
|
54
|
+
}
|
|
55
|
+
if (token !== void 0 && token.length > 0) {
|
|
56
|
+
put("authorization", `Bearer ${token}`);
|
|
57
|
+
}
|
|
58
|
+
return merged;
|
|
59
|
+
};
|
|
60
|
+
const wrapResourceSpans = (span, scopeName, serviceName) => {
|
|
61
|
+
return {
|
|
62
|
+
resourceSpans: [
|
|
63
|
+
{
|
|
64
|
+
resource: { attributes: [encodeAttribute("service.name", serviceName)] },
|
|
65
|
+
scopeSpans: [{ scope: { name: scopeName }, spans: [span] }]
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
const wrapResourceLogs = (logRecord, scopeName, serviceName) => {
|
|
71
|
+
return {
|
|
72
|
+
resourceLogs: [
|
|
73
|
+
{
|
|
74
|
+
resource: { attributes: [encodeAttribute("service.name", serviceName)] },
|
|
75
|
+
scopeLogs: [{ logRecords: [logRecord], scope: { name: scopeName } }]
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export { OTLP_SEVERITY as O, wrapResourceLogs as a, buildTraceparent as b, otlpUnixNano as c, encodeAttribute as e, mergeHeaders as m, otlpRandomHex as o, wrapResourceSpans as w };
|
package/package.json
CHANGED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
const shouldSkip = (event, onlyErrors) => onlyErrors === true && event.ok;
|
|
2
|
-
const mergeHeaders = (defaults, overrides) => {
|
|
3
|
-
if (!overrides) {
|
|
4
|
-
return { ...defaults };
|
|
5
|
-
}
|
|
6
|
-
const merged = {};
|
|
7
|
-
const seen = /* @__PURE__ */ new Map();
|
|
8
|
-
for (const [name, value] of Object.entries(defaults)) {
|
|
9
|
-
const lower = name.toLowerCase();
|
|
10
|
-
seen.set(lower, name);
|
|
11
|
-
merged[name] = value;
|
|
12
|
-
}
|
|
13
|
-
for (const [name, value] of Object.entries(overrides)) {
|
|
14
|
-
const lower = name.toLowerCase();
|
|
15
|
-
const existing = seen.get(lower);
|
|
16
|
-
if (existing === void 0) {
|
|
17
|
-
seen.set(lower, name);
|
|
18
|
-
merged[name] = value;
|
|
19
|
-
} else {
|
|
20
|
-
merged[existing] = value;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return merged;
|
|
24
|
-
};
|
|
25
|
-
const consoleSink = (options = {}) => {
|
|
26
|
-
const { onlyErrors } = options;
|
|
27
|
-
return {
|
|
28
|
-
onLog: (event) => {
|
|
29
|
-
if (event.level === "error") {
|
|
30
|
-
console.error("[lunora:log]", event.functionPath, event.message);
|
|
31
|
-
} else {
|
|
32
|
-
console.log("[lunora:log]", event.functionPath, event.message);
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
onRpc: (event) => {
|
|
36
|
-
if (shouldSkip(event, onlyErrors)) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (event.ok) {
|
|
40
|
-
console.log("[lunora:rpc]", event);
|
|
41
|
-
} else {
|
|
42
|
-
console.error("[lunora:rpc]", event);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
|
-
const webhookSink = (options) => {
|
|
48
|
-
const { headers, onlyErrors, transform, url } = options;
|
|
49
|
-
const mergedHeaders = mergeHeaders({ "content-type": "application/json" }, headers);
|
|
50
|
-
return {
|
|
51
|
-
onRpc: (event, context) => {
|
|
52
|
-
if (shouldSkip(event, onlyErrors)) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
try {
|
|
56
|
-
let payload = event;
|
|
57
|
-
if (transform) {
|
|
58
|
-
try {
|
|
59
|
-
payload = transform(event);
|
|
60
|
-
} catch {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
if (payload === null || payload === void 0) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
const sent = fetch(url, {
|
|
68
|
-
body: JSON.stringify(payload),
|
|
69
|
-
headers: mergedHeaders,
|
|
70
|
-
method: "POST"
|
|
71
|
-
}).catch(() => {
|
|
72
|
-
});
|
|
73
|
-
if (context?.waitUntil) {
|
|
74
|
-
context.waitUntil(sent);
|
|
75
|
-
}
|
|
76
|
-
} catch {
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
};
|
|
81
|
-
const sentrySink = (options) => {
|
|
82
|
-
const { capture } = options;
|
|
83
|
-
const onlyErrors = options.onlyErrors ?? true;
|
|
84
|
-
return {
|
|
85
|
-
onRpc: (event) => {
|
|
86
|
-
if (shouldSkip(event, onlyErrors)) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
try {
|
|
90
|
-
capture(event);
|
|
91
|
-
} catch {
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
};
|
|
96
|
-
const analyticsEngineSink = (options) => {
|
|
97
|
-
const { dataset, onlyErrors } = options;
|
|
98
|
-
return {
|
|
99
|
-
onRpc: (event) => {
|
|
100
|
-
if (shouldSkip(event, onlyErrors)) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
try {
|
|
104
|
-
dataset.writeDataPoint({
|
|
105
|
-
blobs: [event.functionPath, event.ok ? "ok" : "error", event.shardKey ?? "", event.error?.code ?? "", event.fanOut?.table ?? ""],
|
|
106
|
-
doubles: [event.durationMs, event.ok ? 0 : 1, event.fanOut?.shards ?? 0, event.fanOut?.failed ?? 0],
|
|
107
|
-
indexes: [event.functionPath]
|
|
108
|
-
});
|
|
109
|
-
} catch {
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
};
|
|
114
|
-
const combineSinks = (...sinks) => {
|
|
115
|
-
return {
|
|
116
|
-
onLog: (event, context) => {
|
|
117
|
-
for (const sink of sinks) {
|
|
118
|
-
if (!sink.onLog) {
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
try {
|
|
122
|
-
sink.onLog(event, context);
|
|
123
|
-
} catch {
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
onRpc: (event, context) => {
|
|
128
|
-
for (const sink of sinks) {
|
|
129
|
-
if (!sink.onRpc) {
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
try {
|
|
133
|
-
sink.onRpc(event, context);
|
|
134
|
-
} catch {
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
export { analyticsEngineSink, combineSinks, consoleSink, sentrySink, webhookSink };
|