@lunora/do 1.0.0-alpha.40 → 1.0.0-alpha.41
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 +90 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.mjs +2 -2
- package/dist/packem_shared/{ROOT_DO_SIZE_WARN_BYTES-COEnnBhO.mjs → ROOT_DO_SIZE_WARN_BYTES-B4Cpm7Qv.mjs} +21 -1
- package/dist/packem_shared/{context-telemetry-BVSDl6PU.mjs → context-telemetry-CDpyil58.mjs} +79 -31
- package/dist/packem_shared/createMetrics-C4I2Yanj.mjs +1 -0
- package/package.json +1 -1
- package/dist/packem_shared/createMetrics-DFADosgV.mjs +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -2378,14 +2378,66 @@ interface TraceAnchor {
|
|
|
2378
2378
|
rootSpanId: string;
|
|
2379
2379
|
traceId: string;
|
|
2380
2380
|
}
|
|
2381
|
+
/**
|
|
2382
|
+
* Minimal structural shape of one **Cloudflare custom span** — the object CF's
|
|
2383
|
+
* `tracing.enterSpan(name, (span) => …)` callback receives (GA 2026-06-16). Only
|
|
2384
|
+
* the surface the bridge touches is declared, so `@lunora/do` needs no runtime
|
|
2385
|
+
* dependency on `cloudflare:workers`; the real platform span is structurally
|
|
2386
|
+
* assignable.
|
|
2387
|
+
*/
|
|
2388
|
+
interface CloudflareSpanLike {
|
|
2389
|
+
/**
|
|
2390
|
+
* Whether this span is actually being recorded by the runtime's sampler.
|
|
2391
|
+
* `false` off the traced path (unsampled) — the bridge skips its
|
|
2392
|
+
* `setAttribute` work in that case rather than building attribute strings for
|
|
2393
|
+
* a span nobody will read.
|
|
2394
|
+
*/
|
|
2395
|
+
readonly isTraced: boolean;
|
|
2396
|
+
/** Attach one primitive attribute to the CF span. */
|
|
2397
|
+
setAttribute: (key: string, value: boolean | number | string | undefined) => void;
|
|
2398
|
+
}
|
|
2399
|
+
/**
|
|
2400
|
+
* Minimal structural shape of the `tracing` namespace exported by
|
|
2401
|
+
* `cloudflare:workers`. `enterSpan` opens a custom span that auto-nests under the
|
|
2402
|
+
* runtime's ambient span and ends when `callback` settles.
|
|
2403
|
+
*/
|
|
2404
|
+
interface CloudflareTracingLike {
|
|
2405
|
+
enterSpan: <T>(name: string, callback: (span: CloudflareSpanLike) => T) => T;
|
|
2406
|
+
}
|
|
2407
|
+
/**
|
|
2408
|
+
* Resolves CF's `tracing` namespace, or `undefined` when it is unavailable —
|
|
2409
|
+
* off-Cloudflare, on a compat date predating custom spans, or when
|
|
2410
|
+
* `tracing.enterSpan` is not a function. **Injected, never imported here**, so the
|
|
2411
|
+
* tracer stays pure and unit-testable without `cloudflare:workers`; the shard
|
|
2412
|
+
* supplies the real resolver, tests a fake or `undefined`.
|
|
2413
|
+
*/
|
|
2414
|
+
type CloudflareTracingResolver = () => CloudflareTracingLike | Promise<CloudflareTracingLike | undefined> | undefined;
|
|
2381
2415
|
/** What {@link createTracer} needs from the shard to build a span. */
|
|
2382
2416
|
interface TracerDeps {
|
|
2383
2417
|
/** The trace this ctx's spans belong to. */
|
|
2384
2418
|
anchor: TraceAnchor;
|
|
2385
2419
|
/** Function path the spans are attributed to. */
|
|
2386
2420
|
functionPath: string;
|
|
2421
|
+
/**
|
|
2422
|
+
* **Opt-in, EXPERIMENTAL, default off.** When `true` *and*
|
|
2423
|
+
* {@link TracerDeps.resolveCloudflareTracing} yields a working
|
|
2424
|
+
* `tracing.enterSpan`, each `ctx.trace` span is ALSO emitted as a Cloudflare
|
|
2425
|
+
* **custom span**, so it nests inside CF's native binding/fetch/handler trace
|
|
2426
|
+
* tree on the hosted path. This only ADDS a CF-side span — the recorded
|
|
2427
|
+
* {@link SpanEvent} (our `SpanBuffer`/`otlpSink`) is untouched and remains the
|
|
2428
|
+
* source of truth plus the local studio waterfall. See {@link createTracer}
|
|
2429
|
+
* for the double-export and Durable-Object async-context caveats.
|
|
2430
|
+
*/
|
|
2431
|
+
fuseCloudflareSpans?: boolean;
|
|
2387
2432
|
/** Hand a finished span to the buffer + sink. */
|
|
2388
2433
|
record: (span: SpanEvent) => void;
|
|
2434
|
+
/**
|
|
2435
|
+
* Injected resolver for CF's `tracing` namespace (see
|
|
2436
|
+
* {@link CloudflareTracingResolver}). Only consulted when
|
|
2437
|
+
* {@link TracerDeps.fuseCloudflareSpans} is `true`, so the default path never
|
|
2438
|
+
* calls it.
|
|
2439
|
+
*/
|
|
2440
|
+
resolveCloudflareTracing?: CloudflareTracingResolver;
|
|
2389
2441
|
/** Shard key for single-shard calls; absent for the unnamed root DO. */
|
|
2390
2442
|
shardKey: string | undefined;
|
|
2391
2443
|
/** Read lazily — the acting user is resolved per span, not per ctx. */
|
|
@@ -2418,6 +2470,30 @@ interface MetricsDeps {
|
|
|
2418
2470
|
* cleared in the dispatch `finally`, and a subscription re-run builds its ctx
|
|
2419
2471
|
* during* the writing mutation's flush — so reading that shared field at span
|
|
2420
2472
|
* time would file the re-run's spans under the mutation's trace.
|
|
2473
|
+
*
|
|
2474
|
+
* **Cloudflare custom-spans bridge (opt-in, EXPERIMENTAL).** When
|
|
2475
|
+
* `deps.fuseCloudflareSpans` is `true` and `deps.resolveCloudflareTracing` yields
|
|
2476
|
+
* a working `tracing.enterSpan` (`cloudflare:workers`, GA 2026-06-16), each span
|
|
2477
|
+
* body runs inside a CF custom span so our span nests under CF's native
|
|
2478
|
+
* binding/fetch/handler trace tree on the hosted path, and the finished span's
|
|
2479
|
+
* key attributes are mirrored onto it (gated on `span.isTraced`). Two deliberate
|
|
2480
|
+
* boundaries hold.
|
|
2481
|
+
*
|
|
2482
|
+
* **No double-export by default, and never a replacement.** The bridge only ADDS a
|
|
2483
|
+
* CF-side span; the recorded {@link SpanEvent} handed to `record` (our
|
|
2484
|
+
* `SpanBuffer`/`otlpSink`) is byte-for-byte the same as without the bridge and
|
|
2485
|
+
* stays the source of truth. It is off unless explicitly enabled precisely
|
|
2486
|
+
* because, once on, a deployment that ALSO ships our `otlpSink` to a collector
|
|
2487
|
+
* AND lets CF export its trace tree emits the same logical span down two
|
|
2488
|
+
* pipelines — an intentional, documented trade the operator opts into, not a
|
|
2489
|
+
* default.
|
|
2490
|
+
*
|
|
2491
|
+
* **DO async-context caveat.** `tracing.enterSpan`'s parent-linking inside Durable
|
|
2492
|
+
* Objects is unverified upstream, so this is capability-probed: an
|
|
2493
|
+
* absent/undefined `tracing`, a missing `enterSpan`, or an off-CF/unsampled run
|
|
2494
|
+
* all resolve to `undefined` and the bridge is a total no-op — exact prior
|
|
2495
|
+
* behavior. If CF's ambient-span linkage misbehaves in a DO, the worst case is a
|
|
2496
|
+
* mis-parented CF span; our own recorded waterfall is unaffected.
|
|
2421
2497
|
*/
|
|
2422
2498
|
declare const createTracer: (deps: TracerDeps) => ContextTracer;
|
|
2423
2499
|
/**
|
|
@@ -4324,6 +4400,17 @@ declare const subscriptionListDeltas: (previousJson: string, nextResult: unknown
|
|
|
4324
4400
|
* `@lunora/runtime`'s `ObservabilitySink` without taking a dependency on it.
|
|
4325
4401
|
*/
|
|
4326
4402
|
interface TelemetrySink {
|
|
4403
|
+
/**
|
|
4404
|
+
* **Opt-in, EXPERIMENTAL, default off.** When `true`, each `ctx.trace` span is
|
|
4405
|
+
* ALSO emitted as a Cloudflare **custom span** (`tracing.enterSpan` from
|
|
4406
|
+
* `cloudflare:workers`, GA 2026-06-16) so it nests inside CF's native trace
|
|
4407
|
+
* tree on the hosted path — capability-probed, and a safe no-op off-CF / on an
|
|
4408
|
+
* older compat date / when unsampled. This only ADDS a CF-side span; the
|
|
4409
|
+
* `onSpan` event below (our `SpanBuffer`/`otlpSink`) is unchanged and stays the
|
|
4410
|
+
* source of truth. Mirror of `@lunora/runtime`'s `ObservabilitySink`
|
|
4411
|
+
* `fuseCloudflareTraces`; see {@link createTracer} for the double-export caveat.
|
|
4412
|
+
*/
|
|
4413
|
+
fuseCloudflareTraces?: boolean;
|
|
4327
4414
|
onLog?: (event: LogEventInput, context?: LogSinkContext) => void;
|
|
4328
4415
|
onMetric?: (event: MetricEvent, context?: LogSinkContext) => void;
|
|
4329
4416
|
onSpan?: (event: SpanEvent, context?: LogSinkContext) => void;
|
|
@@ -5921,6 +6008,9 @@ declare abstract class ShardDO {
|
|
|
5921
6008
|
* `anchor` is the trace this ctx's spans belong to; omit it for a ctx with no
|
|
5922
6009
|
* owning dispatch (an alarm, a subscription re-run) to mint a fresh anchor, so
|
|
5923
6010
|
* `ctx.trace` still yields a coherent self-contained trace there.
|
|
6011
|
+
*
|
|
6012
|
+
* The Cloudflare custom-spans bridge is threaded here but stays off unless the
|
|
6013
|
+
* resolved sink sets `fuseCloudflareTraces` (see {@link resolveCloudflareTracing}).
|
|
5924
6014
|
*/
|
|
5925
6015
|
protected makeTracer(functionPath: string, sink?: TelemetrySink, anchor?: TraceAnchor): ContextTracer;
|
|
5926
6016
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -2378,14 +2378,66 @@ interface TraceAnchor {
|
|
|
2378
2378
|
rootSpanId: string;
|
|
2379
2379
|
traceId: string;
|
|
2380
2380
|
}
|
|
2381
|
+
/**
|
|
2382
|
+
* Minimal structural shape of one **Cloudflare custom span** — the object CF's
|
|
2383
|
+
* `tracing.enterSpan(name, (span) => …)` callback receives (GA 2026-06-16). Only
|
|
2384
|
+
* the surface the bridge touches is declared, so `@lunora/do` needs no runtime
|
|
2385
|
+
* dependency on `cloudflare:workers`; the real platform span is structurally
|
|
2386
|
+
* assignable.
|
|
2387
|
+
*/
|
|
2388
|
+
interface CloudflareSpanLike {
|
|
2389
|
+
/**
|
|
2390
|
+
* Whether this span is actually being recorded by the runtime's sampler.
|
|
2391
|
+
* `false` off the traced path (unsampled) — the bridge skips its
|
|
2392
|
+
* `setAttribute` work in that case rather than building attribute strings for
|
|
2393
|
+
* a span nobody will read.
|
|
2394
|
+
*/
|
|
2395
|
+
readonly isTraced: boolean;
|
|
2396
|
+
/** Attach one primitive attribute to the CF span. */
|
|
2397
|
+
setAttribute: (key: string, value: boolean | number | string | undefined) => void;
|
|
2398
|
+
}
|
|
2399
|
+
/**
|
|
2400
|
+
* Minimal structural shape of the `tracing` namespace exported by
|
|
2401
|
+
* `cloudflare:workers`. `enterSpan` opens a custom span that auto-nests under the
|
|
2402
|
+
* runtime's ambient span and ends when `callback` settles.
|
|
2403
|
+
*/
|
|
2404
|
+
interface CloudflareTracingLike {
|
|
2405
|
+
enterSpan: <T>(name: string, callback: (span: CloudflareSpanLike) => T) => T;
|
|
2406
|
+
}
|
|
2407
|
+
/**
|
|
2408
|
+
* Resolves CF's `tracing` namespace, or `undefined` when it is unavailable —
|
|
2409
|
+
* off-Cloudflare, on a compat date predating custom spans, or when
|
|
2410
|
+
* `tracing.enterSpan` is not a function. **Injected, never imported here**, so the
|
|
2411
|
+
* tracer stays pure and unit-testable without `cloudflare:workers`; the shard
|
|
2412
|
+
* supplies the real resolver, tests a fake or `undefined`.
|
|
2413
|
+
*/
|
|
2414
|
+
type CloudflareTracingResolver = () => CloudflareTracingLike | Promise<CloudflareTracingLike | undefined> | undefined;
|
|
2381
2415
|
/** What {@link createTracer} needs from the shard to build a span. */
|
|
2382
2416
|
interface TracerDeps {
|
|
2383
2417
|
/** The trace this ctx's spans belong to. */
|
|
2384
2418
|
anchor: TraceAnchor;
|
|
2385
2419
|
/** Function path the spans are attributed to. */
|
|
2386
2420
|
functionPath: string;
|
|
2421
|
+
/**
|
|
2422
|
+
* **Opt-in, EXPERIMENTAL, default off.** When `true` *and*
|
|
2423
|
+
* {@link TracerDeps.resolveCloudflareTracing} yields a working
|
|
2424
|
+
* `tracing.enterSpan`, each `ctx.trace` span is ALSO emitted as a Cloudflare
|
|
2425
|
+
* **custom span**, so it nests inside CF's native binding/fetch/handler trace
|
|
2426
|
+
* tree on the hosted path. This only ADDS a CF-side span — the recorded
|
|
2427
|
+
* {@link SpanEvent} (our `SpanBuffer`/`otlpSink`) is untouched and remains the
|
|
2428
|
+
* source of truth plus the local studio waterfall. See {@link createTracer}
|
|
2429
|
+
* for the double-export and Durable-Object async-context caveats.
|
|
2430
|
+
*/
|
|
2431
|
+
fuseCloudflareSpans?: boolean;
|
|
2387
2432
|
/** Hand a finished span to the buffer + sink. */
|
|
2388
2433
|
record: (span: SpanEvent) => void;
|
|
2434
|
+
/**
|
|
2435
|
+
* Injected resolver for CF's `tracing` namespace (see
|
|
2436
|
+
* {@link CloudflareTracingResolver}). Only consulted when
|
|
2437
|
+
* {@link TracerDeps.fuseCloudflareSpans} is `true`, so the default path never
|
|
2438
|
+
* calls it.
|
|
2439
|
+
*/
|
|
2440
|
+
resolveCloudflareTracing?: CloudflareTracingResolver;
|
|
2389
2441
|
/** Shard key for single-shard calls; absent for the unnamed root DO. */
|
|
2390
2442
|
shardKey: string | undefined;
|
|
2391
2443
|
/** Read lazily — the acting user is resolved per span, not per ctx. */
|
|
@@ -2418,6 +2470,30 @@ interface MetricsDeps {
|
|
|
2418
2470
|
* cleared in the dispatch `finally`, and a subscription re-run builds its ctx
|
|
2419
2471
|
* during* the writing mutation's flush — so reading that shared field at span
|
|
2420
2472
|
* time would file the re-run's spans under the mutation's trace.
|
|
2473
|
+
*
|
|
2474
|
+
* **Cloudflare custom-spans bridge (opt-in, EXPERIMENTAL).** When
|
|
2475
|
+
* `deps.fuseCloudflareSpans` is `true` and `deps.resolveCloudflareTracing` yields
|
|
2476
|
+
* a working `tracing.enterSpan` (`cloudflare:workers`, GA 2026-06-16), each span
|
|
2477
|
+
* body runs inside a CF custom span so our span nests under CF's native
|
|
2478
|
+
* binding/fetch/handler trace tree on the hosted path, and the finished span's
|
|
2479
|
+
* key attributes are mirrored onto it (gated on `span.isTraced`). Two deliberate
|
|
2480
|
+
* boundaries hold.
|
|
2481
|
+
*
|
|
2482
|
+
* **No double-export by default, and never a replacement.** The bridge only ADDS a
|
|
2483
|
+
* CF-side span; the recorded {@link SpanEvent} handed to `record` (our
|
|
2484
|
+
* `SpanBuffer`/`otlpSink`) is byte-for-byte the same as without the bridge and
|
|
2485
|
+
* stays the source of truth. It is off unless explicitly enabled precisely
|
|
2486
|
+
* because, once on, a deployment that ALSO ships our `otlpSink` to a collector
|
|
2487
|
+
* AND lets CF export its trace tree emits the same logical span down two
|
|
2488
|
+
* pipelines — an intentional, documented trade the operator opts into, not a
|
|
2489
|
+
* default.
|
|
2490
|
+
*
|
|
2491
|
+
* **DO async-context caveat.** `tracing.enterSpan`'s parent-linking inside Durable
|
|
2492
|
+
* Objects is unverified upstream, so this is capability-probed: an
|
|
2493
|
+
* absent/undefined `tracing`, a missing `enterSpan`, or an off-CF/unsampled run
|
|
2494
|
+
* all resolve to `undefined` and the bridge is a total no-op — exact prior
|
|
2495
|
+
* behavior. If CF's ambient-span linkage misbehaves in a DO, the worst case is a
|
|
2496
|
+
* mis-parented CF span; our own recorded waterfall is unaffected.
|
|
2421
2497
|
*/
|
|
2422
2498
|
declare const createTracer: (deps: TracerDeps) => ContextTracer;
|
|
2423
2499
|
/**
|
|
@@ -4324,6 +4400,17 @@ declare const subscriptionListDeltas: (previousJson: string, nextResult: unknown
|
|
|
4324
4400
|
* `@lunora/runtime`'s `ObservabilitySink` without taking a dependency on it.
|
|
4325
4401
|
*/
|
|
4326
4402
|
interface TelemetrySink {
|
|
4403
|
+
/**
|
|
4404
|
+
* **Opt-in, EXPERIMENTAL, default off.** When `true`, each `ctx.trace` span is
|
|
4405
|
+
* ALSO emitted as a Cloudflare **custom span** (`tracing.enterSpan` from
|
|
4406
|
+
* `cloudflare:workers`, GA 2026-06-16) so it nests inside CF's native trace
|
|
4407
|
+
* tree on the hosted path — capability-probed, and a safe no-op off-CF / on an
|
|
4408
|
+
* older compat date / when unsampled. This only ADDS a CF-side span; the
|
|
4409
|
+
* `onSpan` event below (our `SpanBuffer`/`otlpSink`) is unchanged and stays the
|
|
4410
|
+
* source of truth. Mirror of `@lunora/runtime`'s `ObservabilitySink`
|
|
4411
|
+
* `fuseCloudflareTraces`; see {@link createTracer} for the double-export caveat.
|
|
4412
|
+
*/
|
|
4413
|
+
fuseCloudflareTraces?: boolean;
|
|
4327
4414
|
onLog?: (event: LogEventInput, context?: LogSinkContext) => void;
|
|
4328
4415
|
onMetric?: (event: MetricEvent, context?: LogSinkContext) => void;
|
|
4329
4416
|
onSpan?: (event: SpanEvent, context?: LogSinkContext) => void;
|
|
@@ -5921,6 +6008,9 @@ declare abstract class ShardDO {
|
|
|
5921
6008
|
* `anchor` is the trace this ctx's spans belong to; omit it for a ctx with no
|
|
5922
6009
|
* owning dispatch (an alarm, a subscription re-run) to mint a fresh anchor, so
|
|
5923
6010
|
* `ctx.trace` still yields a coherent self-contained trace there.
|
|
6011
|
+
*
|
|
6012
|
+
* The Cloudflare custom-spans bridge is threaded here but stays off unless the
|
|
6013
|
+
* resolved sink sets `fuseCloudflareTraces` (see {@link resolveCloudflareTracing}).
|
|
5924
6014
|
*/
|
|
5925
6015
|
protected makeTracer(functionPath: string, sink?: TelemetrySink, anchor?: TraceAnchor): ContextTracer;
|
|
5926
6016
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ export { AGGREGATE_SQL_FUNCTION, aggregateSqlFunction, matchesStaticWhere, norma
|
|
|
3
3
|
export { aggregateTableName, coerceAggregateNumber, encodeAggregateKey, foldAggregateTally, readAggregateValue } from './packem_shared/aggregateTableName-CxNqY1Sl.mjs';
|
|
4
4
|
export { CountRlsUnsupportedError, mergeWhere, planAggregateLookup, selectIndexForAggregate, selectIndexForCount, selectIndexForGroupBy } from './packem_shared/CountRlsUnsupportedError-BGxj0pgS.mjs';
|
|
5
5
|
export { AUTH_METRICS_BUCKETS_TABLE, AUTH_METRICS_BUCKET_MS, AUTH_METRICS_BUCKET_RETENTION, AUTH_METRICS_TABLE, ensureAuthMetricsTables, readAuthMetrics, recordAuthEvent } from './packem_shared/AUTH_METRICS_BUCKETS_TABLE-CiHHYeJi.mjs';
|
|
6
|
-
export { c as createMetrics, a as createTracer, d as dispatchRootSpan } from './packem_shared/context-telemetry-
|
|
6
|
+
export { c as createMetrics, a as createTracer, d as dispatchRootSpan } from './packem_shared/context-telemetry-CDpyil58.mjs';
|
|
7
7
|
export { NotUniqueError, assertValidClientId, createShardCtxDb, normalizeIdStructurally } from './packem_shared/NotUniqueError-DbtlWwcG.mjs';
|
|
8
8
|
export { DATA_MIGRATION_STATE_TABLE, readMigrationStatus, runDataMigration } from './packem_shared/DATA_MIGRATION_STATE_TABLE-CYwBpyTr.mjs';
|
|
9
9
|
export { SCAN_DEP, createDependencyTracker, depKey } from './packem_shared/SCAN_DEP-DLJF8dsj.mjs';
|
|
@@ -28,7 +28,7 @@ export { RLS_UNWRAP_SYMBOL, RlsRequiredError, guardWriter } from './packem_share
|
|
|
28
28
|
export { buildFtsMatch, ftsTableName, scoreDocument, stringifySearchText, tokenizeSearch } from './packem_shared/buildFtsMatch-BLEMawrp.mjs';
|
|
29
29
|
export { M as MIN_ADMIN_TOKEN_LENGTH, a as MIN_AUTH_SECRET_LENGTH, b as buildSecurityAudit } from './packem_shared/security-audit-CucgBice.mjs';
|
|
30
30
|
export { SESSION_DO_TTL_DEFAULT, SessionDO } from './packem_shared/SESSION_DO_TTL_DEFAULT-BnSKgVO4.mjs';
|
|
31
|
-
export { ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, ShardDO } from './packem_shared/ROOT_DO_SIZE_WARN_BYTES-
|
|
31
|
+
export { ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, ShardDO } from './packem_shared/ROOT_DO_SIZE_WARN_BYTES-B4Cpm7Qv.mjs';
|
|
32
32
|
export { SHARD_REGISTRY_DO_NAME, ShardRegistryDO } from './packem_shared/SHARD_REGISTRY_DO_NAME-D99roc-r.mjs';
|
|
33
33
|
export { MAX_SQL_ROWS, assertReadonly, runReadonlySql } from './packem_shared/MAX_SQL_ROWS-iFAA8FbD.mjs';
|
|
34
34
|
export { createSystemReader } from './packem_shared/createSystemReader-D12eNH13.mjs';
|
|
@@ -2,7 +2,7 @@ import { LunoraError, toErrorBody } from '@lunora/errors';
|
|
|
2
2
|
import { drizzle } from 'drizzle-orm/durable-sqlite';
|
|
3
3
|
import { c as constantTimeEqual } from './constant-time-equal-BVRWZgES.mjs';
|
|
4
4
|
import { j as jsonResponse } from './json-response-BdbtpOhm.mjs';
|
|
5
|
-
import { n as normalizeLogFields, r as resolveTraceAnchor, p as parseTraceparent, a as createTracer, c as createMetrics, d as dispatchRootSpan } from './context-telemetry-
|
|
5
|
+
import { n as normalizeLogFields, r as resolveTraceAnchor, p as parseTraceparent, a as createTracer, c as createMetrics, d as dispatchRootSpan } from './context-telemetry-CDpyil58.mjs';
|
|
6
6
|
import { e as encodeWire, d as decodeWire } from './wire-codec-CzQc1pvf.mjs';
|
|
7
7
|
import { parseExportShardArgs, parseImportShardArgs } from './exportShardRows-Dy3oFZ26.mjs';
|
|
8
8
|
import { recordAuthEvent, readAuthMetrics } from './AUTH_METRICS_BUCKETS_TABLE-CiHHYeJi.mjs';
|
|
@@ -1968,6 +1968,21 @@ const findDanglingReferences = (sql, storageColumns, liveKeys) => {
|
|
|
1968
1968
|
const WS_KEEPALIVE_PING = "lunora-ping";
|
|
1969
1969
|
const WS_KEEPALIVE_PONG = "lunora-pong";
|
|
1970
1970
|
const REQUIRE_EPHEMERAL_ENV_VALUES = /* @__PURE__ */ new Set(["1", "enabled", "on", "true", "yes"]);
|
|
1971
|
+
let cloudflareTracingResolved = false;
|
|
1972
|
+
let cloudflareTracing;
|
|
1973
|
+
const resolveCloudflareTracing = async () => {
|
|
1974
|
+
if (!cloudflareTracingResolved) {
|
|
1975
|
+
cloudflareTracingResolved = true;
|
|
1976
|
+
try {
|
|
1977
|
+
const cloudflareModule = await import('cloudflare:workers');
|
|
1978
|
+
const candidate = cloudflareModule.tracing;
|
|
1979
|
+
cloudflareTracing = candidate !== null && typeof candidate === "object" && typeof candidate.enterSpan === "function" ? candidate : void 0;
|
|
1980
|
+
} catch {
|
|
1981
|
+
cloudflareTracing = void 0;
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
return cloudflareTracing;
|
|
1985
|
+
};
|
|
1971
1986
|
const UNDELIVERED_BASELINE = "<undelivered>";
|
|
1972
1987
|
const ROOT_DO_SIZE_WARN_BYTES = 1073741824;
|
|
1973
1988
|
const CDC_RESUME_SCAN_LIMIT = 1e4;
|
|
@@ -4786,14 +4801,19 @@ class ShardDO {
|
|
|
4786
4801
|
* `anchor` is the trace this ctx's spans belong to; omit it for a ctx with no
|
|
4787
4802
|
* owning dispatch (an alarm, a subscription re-run) to mint a fresh anchor, so
|
|
4788
4803
|
* `ctx.trace` still yields a coherent self-contained trace there.
|
|
4804
|
+
*
|
|
4805
|
+
* The Cloudflare custom-spans bridge is threaded here but stays off unless the
|
|
4806
|
+
* resolved sink sets `fuseCloudflareTraces` (see {@link resolveCloudflareTracing}).
|
|
4789
4807
|
*/
|
|
4790
4808
|
makeTracer(functionPath, sink, anchor) {
|
|
4791
4809
|
return createTracer({
|
|
4792
4810
|
anchor: anchor ?? resolveTraceAnchor(void 0),
|
|
4811
|
+
fuseCloudflareSpans: sink?.fuseCloudflareTraces === true,
|
|
4793
4812
|
functionPath,
|
|
4794
4813
|
record: (span) => {
|
|
4795
4814
|
this.recordSpan(span, sink);
|
|
4796
4815
|
},
|
|
4816
|
+
resolveCloudflareTracing,
|
|
4797
4817
|
shardKey: this.state.id?.name,
|
|
4798
4818
|
userId: () => this.getCurrentUserId()
|
|
4799
4819
|
});
|
package/dist/packem_shared/{context-telemetry-BVSDl6PU.mjs → context-telemetry-CDpyil58.mjs}
RENAMED
|
@@ -63,8 +63,31 @@ const toErrorType = (error) => {
|
|
|
63
63
|
return error instanceof Error ? error.constructor.name : "Error";
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
+
const applyCloudflareSpanAttributes = (span, meta) => {
|
|
67
|
+
if (!span.isTraced) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
span.setAttribute("lunora.function_path", meta.functionPath);
|
|
71
|
+
span.setAttribute("lunora.ok", meta.ok);
|
|
72
|
+
span.setAttribute("lunora.duration_ms", meta.durationMs);
|
|
73
|
+
if (meta.shardKey !== void 0) {
|
|
74
|
+
span.setAttribute("lunora.shard_key", meta.shardKey);
|
|
75
|
+
}
|
|
76
|
+
if (meta.userId !== void 0) {
|
|
77
|
+
span.setAttribute("lunora.user_id", meta.userId);
|
|
78
|
+
}
|
|
79
|
+
if (meta.error !== void 0) {
|
|
80
|
+
span.setAttribute("lunora.error.type", meta.error.type);
|
|
81
|
+
span.setAttribute("lunora.error.message", meta.error.message);
|
|
82
|
+
}
|
|
83
|
+
for (const [key, value] of Object.entries(meta.attributes)) {
|
|
84
|
+
if (typeof value === "boolean" || typeof value === "number" || typeof value === "string") {
|
|
85
|
+
span.setAttribute(`lunora.attr.${key}`, value);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
};
|
|
66
89
|
const createTracer = (deps) => {
|
|
67
|
-
const { anchor, functionPath, record, shardKey, userId } = deps;
|
|
90
|
+
const { anchor, fuseCloudflareSpans, functionPath, record, resolveCloudflareTracing, shardKey, userId } = deps;
|
|
68
91
|
const tracerFor = (parentSpanId) => async (name, function_, attributes) => {
|
|
69
92
|
const spanId = otlpRandomHex(8);
|
|
70
93
|
const startTs = Date.now();
|
|
@@ -78,39 +101,64 @@ const createTracer = (deps) => {
|
|
|
78
101
|
Object.assign(collected, normalizeLogFields(fields));
|
|
79
102
|
}
|
|
80
103
|
};
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return await function_(tracerFor(spanId), spanHandle);
|
|
85
|
-
} catch (error_) {
|
|
86
|
-
ok = false;
|
|
87
|
-
error = {
|
|
88
|
-
message: error_ instanceof Error ? error_.message : String(error_),
|
|
89
|
-
// Prefer a LunoraError's stable `code` over the class name so
|
|
90
|
-
// spans group by the same taxonomy the RPC spans use.
|
|
91
|
-
type: toErrorType(error_)
|
|
92
|
-
};
|
|
93
|
-
throw error_;
|
|
94
|
-
} finally {
|
|
104
|
+
const runRecorded = async (cfSpan) => {
|
|
105
|
+
let ok = true;
|
|
106
|
+
let error;
|
|
95
107
|
try {
|
|
108
|
+
return await function_(tracerFor(spanId), spanHandle);
|
|
109
|
+
} catch (error_) {
|
|
110
|
+
ok = false;
|
|
111
|
+
error = {
|
|
112
|
+
message: error_ instanceof Error ? error_.message : String(error_),
|
|
113
|
+
// Prefer a LunoraError's stable `code` over the class name
|
|
114
|
+
// so spans group by the same taxonomy the RPC spans use.
|
|
115
|
+
type: toErrorType(error_)
|
|
116
|
+
};
|
|
117
|
+
throw error_;
|
|
118
|
+
} finally {
|
|
119
|
+
const durationMs = Date.now() - startTs;
|
|
120
|
+
const resolvedUserId = userId();
|
|
96
121
|
const merged = { ...normalized, ...collected };
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
122
|
+
try {
|
|
123
|
+
record({
|
|
124
|
+
...Object.keys(merged).length === 0 ? {} : { attributes: merged },
|
|
125
|
+
durationMs,
|
|
126
|
+
...error === void 0 ? {} : { error },
|
|
127
|
+
functionPath,
|
|
128
|
+
name,
|
|
129
|
+
ok,
|
|
130
|
+
parentSpanId,
|
|
131
|
+
shardKey,
|
|
132
|
+
spanId,
|
|
133
|
+
startTs,
|
|
134
|
+
traceId: anchor.traceId,
|
|
135
|
+
userId: resolvedUserId
|
|
136
|
+
});
|
|
137
|
+
} catch {
|
|
138
|
+
}
|
|
139
|
+
if (cfSpan !== void 0) {
|
|
140
|
+
try {
|
|
141
|
+
applyCloudflareSpanAttributes(cfSpan, {
|
|
142
|
+
attributes: merged,
|
|
143
|
+
durationMs,
|
|
144
|
+
error,
|
|
145
|
+
functionPath,
|
|
146
|
+
ok,
|
|
147
|
+
shardKey,
|
|
148
|
+
userId: resolvedUserId
|
|
149
|
+
});
|
|
150
|
+
} catch {
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
if (fuseCloudflareSpans === true && resolveCloudflareTracing !== void 0) {
|
|
156
|
+
const cfTracing = await resolveCloudflareTracing();
|
|
157
|
+
if (cfTracing !== void 0 && typeof cfTracing.enterSpan === "function") {
|
|
158
|
+
return await cfTracing.enterSpan(name, (span) => runRecorded(span));
|
|
112
159
|
}
|
|
113
160
|
}
|
|
161
|
+
return await runRecorded();
|
|
114
162
|
};
|
|
115
163
|
return tracerFor(anchor.rootSpanId);
|
|
116
164
|
};
|
|
@@ -172,4 +220,4 @@ const dispatchRootSpan = (input) => {
|
|
|
172
220
|
};
|
|
173
221
|
};
|
|
174
222
|
|
|
175
|
-
export { createTracer as a, createMetrics as c, dispatchRootSpan as d, normalizeLogFields as n, parseTraceparent as p, resolveTraceAnchor as r };
|
|
223
|
+
export { createTracer as a, applyCloudflareSpanAttributes as b, createMetrics as c, dispatchRootSpan as d, normalizeLogFields as n, parseTraceparent as p, resolveTraceAnchor as r };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { b as applyCloudflareSpanAttributes, c as createMetrics, a as createTracer, d as dispatchRootSpan } from './context-telemetry-CDpyil58.mjs';
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { c as createMetrics, a as createTracer, d as dispatchRootSpan } from './context-telemetry-BVSDl6PU.mjs';
|