@lunora/server 1.0.0-alpha.32 → 1.0.0-alpha.34
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.md +213 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/otel.d.mts +543 -0
- package/dist/otel.d.ts +543 -0
- package/dist/otel.mjs +1 -0
- package/dist/types.d.mts +135 -4
- package/dist/types.d.ts +135 -4
- package/package.json +14 -2
package/dist/types.d.mts
CHANGED
|
@@ -1381,6 +1381,28 @@ interface LunoraLogMethod {
|
|
|
1381
1381
|
interface LunoraLogger {
|
|
1382
1382
|
readonly debug: LunoraLogMethod;
|
|
1383
1383
|
readonly error: LunoraLogMethod;
|
|
1384
|
+
/**
|
|
1385
|
+
* Emit a **structured event** instead of a log line — OpenTelemetry's Events
|
|
1386
|
+
* API, on the wire as `LogRecord.eventName` (plus an `event.name` attribute
|
|
1387
|
+
* for collectors predating that field).
|
|
1388
|
+
*
|
|
1389
|
+
* ```ts
|
|
1390
|
+
* ctx.log.event("checkout.completed", { plan: user.plan, total, currency });
|
|
1391
|
+
* ```
|
|
1392
|
+
*
|
|
1393
|
+
* The difference from `ctx.log.info("checkout completed", { … })` is what a
|
|
1394
|
+
* backend can do with it. A log line's payload is its message: prose, written
|
|
1395
|
+
* for a human, free to be reworded next sprint — so "how many checkouts
|
|
1396
|
+
* completed, by plan, this hour" degrades into a substring search over
|
|
1397
|
+
* English. An event's payload is its `fields` under a **stable name**, which a
|
|
1398
|
+
* collector can index, group, and alert on directly.
|
|
1399
|
+
*
|
|
1400
|
+
* Rule of thumb: `log.*` for narration you'd read while debugging, `event` for
|
|
1401
|
+
* anything you'd ever put on a dashboard. And for facts about the request as a
|
|
1402
|
+
* whole, prefer `ctx.span` — one wide event beats a dozen
|
|
1403
|
+
* events, however well named.
|
|
1404
|
+
*/
|
|
1405
|
+
readonly event: (name: string, fields?: LogFields) => void;
|
|
1384
1406
|
readonly fatal: LunoraLogMethod;
|
|
1385
1407
|
readonly info: LunoraLogMethod;
|
|
1386
1408
|
readonly log: LunoraLogMethod;
|
|
@@ -1404,10 +1426,71 @@ interface LunoraLogger {
|
|
|
1404
1426
|
* handle writes are merged over them at record time, post-hoc winning on a clash.
|
|
1405
1427
|
*/
|
|
1406
1428
|
interface SpanHandle {
|
|
1429
|
+
/**
|
|
1430
|
+
* Record a timestamped event on the enclosing span — a retry, a cache miss, a
|
|
1431
|
+
* state transition. Prefer this over an extra `ctx.log` line for anything that
|
|
1432
|
+
* only makes sense *relative to this span*: it rides the span's own export, so
|
|
1433
|
+
* it costs no additional record and can never be separated from its context.
|
|
1434
|
+
*/
|
|
1435
|
+
addEvent: (name: string, attributes?: LogFields) => void;
|
|
1436
|
+
/**
|
|
1437
|
+
* Link this span to one in another trace — how a queue consumer points back at
|
|
1438
|
+
* the request that enqueued its message without collapsing every producer into
|
|
1439
|
+
* one giant trace.
|
|
1440
|
+
*/
|
|
1441
|
+
addLink: (link: SpanLink) => void;
|
|
1442
|
+
/**
|
|
1443
|
+
* Record a **handled** exception as the OTel-conventional `exception` span
|
|
1444
|
+
* event (`exception.type` / `exception.message` / `exception.stacktrace`),
|
|
1445
|
+
* without marking the span failed.
|
|
1446
|
+
*
|
|
1447
|
+
* For an error you swallowed — a retried request, a fallback that worked. An
|
|
1448
|
+
* error that escapes the span body is recorded automatically and *does* set
|
|
1449
|
+
* the error status, so don't call this for one you're re-throwing.
|
|
1450
|
+
*/
|
|
1451
|
+
recordException: (error: unknown) => void;
|
|
1407
1452
|
/** Set one attribute on the enclosing span (merged at record time; post-hoc wins on key clash). */
|
|
1408
1453
|
setAttribute: (key: string, value: LogFields[string]) => void;
|
|
1409
1454
|
/** Merge attributes onto the enclosing span (post-hoc wins on key clash). */
|
|
1410
1455
|
setAttributes: (fields: LogFields) => void;
|
|
1456
|
+
/**
|
|
1457
|
+
* The W3C ids of the span this handle refers to (32-hex trace, 16-hex span).
|
|
1458
|
+
*
|
|
1459
|
+
* On `ctx.span` these are the DISPATCH's ids — the trace the whole request
|
|
1460
|
+
* belongs to. Use it to echo a trace id back to a caller so a user can quote
|
|
1461
|
+
* it in a bug report, to build a `traceparent` for a hand-rolled outbound
|
|
1462
|
+
* call, or to parent a third-party library's spans onto this request.
|
|
1463
|
+
*/
|
|
1464
|
+
spanContext: () => {
|
|
1465
|
+
spanId: string;
|
|
1466
|
+
traceId: string;
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
/**
|
|
1470
|
+
* A causal reference to a span in another trace (OTel `Span.links`). Ids are
|
|
1471
|
+
* lowercase hex — 32 chars for `traceId`, 16 for `spanId`.
|
|
1472
|
+
*/
|
|
1473
|
+
interface SpanLink {
|
|
1474
|
+
/** Attributes describing the relationship, e.g. `{ "link.kind": "enqueued_by" }`. */
|
|
1475
|
+
attributes?: LogFields;
|
|
1476
|
+
spanId: string;
|
|
1477
|
+
traceId: string;
|
|
1478
|
+
}
|
|
1479
|
+
/** OTel `SpanKind`. Drives a collector's service map — see {@link SpanOptions.kind}. */
|
|
1480
|
+
type SpanKind = "client" | "consumer" | "internal" | "producer" | "server";
|
|
1481
|
+
/** Options accepted by `ctx.trace(name, fn, options)` beyond a plain attribute bag. */
|
|
1482
|
+
interface SpanOptions {
|
|
1483
|
+
/** Start attributes, snapshotted before the body runs. */
|
|
1484
|
+
attributes?: LogFields;
|
|
1485
|
+
/**
|
|
1486
|
+
* OTel `SpanKind`, default `"internal"`. Set `"client"` for a call OUT to
|
|
1487
|
+
* another service and `"producer"`/`"consumer"` for queue hops: a collector
|
|
1488
|
+
* builds its service map from this, so leaving everything `"internal"` yields
|
|
1489
|
+
* a trace with no topology.
|
|
1490
|
+
*/
|
|
1491
|
+
kind?: SpanKind;
|
|
1492
|
+
/** Links to spans in other traces, known at span start. */
|
|
1493
|
+
links?: SpanLink[];
|
|
1411
1494
|
}
|
|
1412
1495
|
/**
|
|
1413
1496
|
* Span factory on every function `ctx`. Wraps a sub-operation so it becomes its
|
|
@@ -1458,10 +1541,52 @@ interface SpanHandle {
|
|
|
1458
1541
|
* @param fn The body to time, receiving a tracer bound to this span for any
|
|
1459
1542
|
* nested spans and the enclosing span's {@link SpanHandle} for post-hoc
|
|
1460
1543
|
* attributes. May be sync or async; the result is awaited.
|
|
1461
|
-
* @param attributes
|
|
1462
|
-
* normalized like a log line's `fields
|
|
1544
|
+
* @param attributes Either a plain attribute bag to stamp on the span at start
|
|
1545
|
+
* (normalized like a log line's `fields`), or a {@link SpanOptions} object when
|
|
1546
|
+
* you need `kind` or `links`. It is read as options only when *every* key is one
|
|
1547
|
+
* of `attributes`/`kind`/`links`; `{ attributes: { kind: "premium" } }` is the
|
|
1548
|
+
* explicit form if your own attributes happen to be named that.
|
|
1549
|
+
*/
|
|
1550
|
+
type LunoraTracer = <T>(name: string, function_: (trace: LunoraTracer, span: SpanHandle) => Promise<T> | T, attributes?: LogFields | SpanOptions) => Promise<T>;
|
|
1551
|
+
/**
|
|
1552
|
+
* `ctx.span` — a handle onto **this request's own span**, and with it the
|
|
1553
|
+
* wide-event API.
|
|
1554
|
+
*
|
|
1555
|
+
* ```ts
|
|
1556
|
+
* export const checkout = mutation({ handler: async (ctx, args) => {
|
|
1557
|
+
* ctx.span.setAttributes({ "user.plan": user.plan, "cart.items": cart.length });
|
|
1558
|
+
* const payment = await charge(cart);
|
|
1559
|
+
* ctx.span.setAttributes({ "payment.provider": payment.provider, "payment.total": payment.total });
|
|
1560
|
+
* if (payment.retried) ctx.span.addEvent("payment.retried", { attempts: payment.attempts });
|
|
1561
|
+
* return payment;
|
|
1562
|
+
* }});
|
|
1563
|
+
* ```
|
|
1564
|
+
*
|
|
1565
|
+
* **Why this instead of more log lines.** The usual way to make a handler
|
|
1566
|
+
* observable is to sprinkle `ctx.log.info` through it, which costs one record per
|
|
1567
|
+
* call, scatters one request's facts across a dozen rows, and forces every
|
|
1568
|
+
* question to be answered by correlating them back together. The wide-event
|
|
1569
|
+
* pattern inverts that: accumulate the facts as you learn them, and emit **one**
|
|
1570
|
+
* richly-attributed record per unit of work. Cost is flat — one span per request
|
|
1571
|
+
* no matter how much you attach — and every question ("p99 checkout latency for
|
|
1572
|
+
* pro-plan users with >10 items") becomes a single filter over one table instead
|
|
1573
|
+
* of a join across log lines.
|
|
1574
|
+
*
|
|
1575
|
+
* **This is plain OpenTelemetry, not a Lunora convention.** The attributes land
|
|
1576
|
+
* on the span the dispatch already emits, and are additionally exported as an
|
|
1577
|
+
* OTel Event record named `lunora.dispatch`, correlated by `trace_id`/`span_id`.
|
|
1578
|
+
* Any OTLP backend groups and aggregates them with no special configuration.
|
|
1579
|
+
*
|
|
1580
|
+
* **`span` vs `trace`.** `ctx.trace(name, fn)` creates a NEW child span to time a
|
|
1581
|
+
* sub-operation; `ctx.span` attaches to the one that already exists for the
|
|
1582
|
+
* request. Use `trace` for "how long did this part take", `span` for "what was
|
|
1583
|
+
* true about this request". Inside a `ctx.trace` body, the handle passed as the
|
|
1584
|
+
* body's second argument is that child span's equivalent of this.
|
|
1585
|
+
*
|
|
1586
|
+
* Attributes are normalized exactly like `ctx.log` fields, and recording is
|
|
1587
|
+
* best-effort — a telemetry failure never breaks the handler.
|
|
1463
1588
|
*/
|
|
1464
|
-
type
|
|
1589
|
+
type LunoraWideEvent = SpanHandle;
|
|
1465
1590
|
/**
|
|
1466
1591
|
* Application metrics on every function `ctx` — the third signal alongside
|
|
1467
1592
|
* `ctx.log` and `ctx.trace`. Each call records one measurement that flows to an
|
|
@@ -1546,6 +1671,8 @@ interface QueryCtx {
|
|
|
1546
1671
|
readonly runQuery: <A extends ArgsValidator, R>(reference: RegisteredQuery<A, R>, args: InferArgs<A>) => Promise<R>;
|
|
1547
1672
|
/** Read account-level secrets from Cloudflare Secrets Store; see {@link Secrets}. */
|
|
1548
1673
|
readonly secrets: Secrets;
|
|
1674
|
+
/** Attach facts to THIS request's span — the wide event; see {@link LunoraWideEvent}. */
|
|
1675
|
+
readonly span: LunoraWideEvent;
|
|
1549
1676
|
readonly storage: ReadOnlyStorage;
|
|
1550
1677
|
/** Wrap a sub-operation in its own nested span; see {@link LunoraTracer}. */
|
|
1551
1678
|
readonly trace: LunoraTracer;
|
|
@@ -1600,6 +1727,8 @@ interface MutationCtx {
|
|
|
1600
1727
|
readonly scheduler: Scheduler;
|
|
1601
1728
|
/** Read account-level secrets from Cloudflare Secrets Store; see {@link Secrets}. */
|
|
1602
1729
|
readonly secrets: Secrets;
|
|
1730
|
+
/** Attach facts to THIS request's span — the wide event; see {@link LunoraWideEvent}. */
|
|
1731
|
+
readonly span: LunoraWideEvent;
|
|
1603
1732
|
readonly storage: ReadOnlyStorage;
|
|
1604
1733
|
/** Wrap a sub-operation in its own nested span; see {@link LunoraTracer}. */
|
|
1605
1734
|
readonly trace: LunoraTracer;
|
|
@@ -1649,6 +1778,8 @@ interface ActionCtx {
|
|
|
1649
1778
|
readonly scheduler: Scheduler;
|
|
1650
1779
|
/** Read account-level secrets from Cloudflare Secrets Store; see {@link Secrets}. */
|
|
1651
1780
|
readonly secrets: Secrets;
|
|
1781
|
+
/** Attach facts to THIS request's span — the wide event; see {@link LunoraWideEvent}. */
|
|
1782
|
+
readonly span: LunoraWideEvent;
|
|
1652
1783
|
readonly storage: Storage;
|
|
1653
1784
|
/** Wrap a sub-operation in its own nested span; see {@link LunoraTracer}. */
|
|
1654
1785
|
readonly trace: LunoraTracer;
|
|
@@ -1662,4 +1793,4 @@ interface ActionCtx {
|
|
|
1662
1793
|
*/
|
|
1663
1794
|
type AnyApi = Record<string, Record<string, RegisteredFunction<ArgsValidator, unknown, FunctionKind>>>;
|
|
1664
1795
|
declare const anyApi: AnyApi;
|
|
1665
|
-
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExposeConfig, type ExternalSourceCursor, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type Secrets, type SecretsStoreSecretLike, type ShardMode, type SpanHandle, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type TtlDefinition, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, type X402ProcedureConfig, anyApi };
|
|
1796
|
+
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExposeConfig, type ExternalSourceCursor, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, type LunoraWideEvent, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type Secrets, type SecretsStoreSecretLike, type ShardMode, type SpanHandle, type SpanKind, type SpanLink, type SpanOptions, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type TtlDefinition, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, type X402ProcedureConfig, anyApi };
|
package/dist/types.d.ts
CHANGED
|
@@ -1381,6 +1381,28 @@ interface LunoraLogMethod {
|
|
|
1381
1381
|
interface LunoraLogger {
|
|
1382
1382
|
readonly debug: LunoraLogMethod;
|
|
1383
1383
|
readonly error: LunoraLogMethod;
|
|
1384
|
+
/**
|
|
1385
|
+
* Emit a **structured event** instead of a log line — OpenTelemetry's Events
|
|
1386
|
+
* API, on the wire as `LogRecord.eventName` (plus an `event.name` attribute
|
|
1387
|
+
* for collectors predating that field).
|
|
1388
|
+
*
|
|
1389
|
+
* ```ts
|
|
1390
|
+
* ctx.log.event("checkout.completed", { plan: user.plan, total, currency });
|
|
1391
|
+
* ```
|
|
1392
|
+
*
|
|
1393
|
+
* The difference from `ctx.log.info("checkout completed", { … })` is what a
|
|
1394
|
+
* backend can do with it. A log line's payload is its message: prose, written
|
|
1395
|
+
* for a human, free to be reworded next sprint — so "how many checkouts
|
|
1396
|
+
* completed, by plan, this hour" degrades into a substring search over
|
|
1397
|
+
* English. An event's payload is its `fields` under a **stable name**, which a
|
|
1398
|
+
* collector can index, group, and alert on directly.
|
|
1399
|
+
*
|
|
1400
|
+
* Rule of thumb: `log.*` for narration you'd read while debugging, `event` for
|
|
1401
|
+
* anything you'd ever put on a dashboard. And for facts about the request as a
|
|
1402
|
+
* whole, prefer `ctx.span` — one wide event beats a dozen
|
|
1403
|
+
* events, however well named.
|
|
1404
|
+
*/
|
|
1405
|
+
readonly event: (name: string, fields?: LogFields) => void;
|
|
1384
1406
|
readonly fatal: LunoraLogMethod;
|
|
1385
1407
|
readonly info: LunoraLogMethod;
|
|
1386
1408
|
readonly log: LunoraLogMethod;
|
|
@@ -1404,10 +1426,71 @@ interface LunoraLogger {
|
|
|
1404
1426
|
* handle writes are merged over them at record time, post-hoc winning on a clash.
|
|
1405
1427
|
*/
|
|
1406
1428
|
interface SpanHandle {
|
|
1429
|
+
/**
|
|
1430
|
+
* Record a timestamped event on the enclosing span — a retry, a cache miss, a
|
|
1431
|
+
* state transition. Prefer this over an extra `ctx.log` line for anything that
|
|
1432
|
+
* only makes sense *relative to this span*: it rides the span's own export, so
|
|
1433
|
+
* it costs no additional record and can never be separated from its context.
|
|
1434
|
+
*/
|
|
1435
|
+
addEvent: (name: string, attributes?: LogFields) => void;
|
|
1436
|
+
/**
|
|
1437
|
+
* Link this span to one in another trace — how a queue consumer points back at
|
|
1438
|
+
* the request that enqueued its message without collapsing every producer into
|
|
1439
|
+
* one giant trace.
|
|
1440
|
+
*/
|
|
1441
|
+
addLink: (link: SpanLink) => void;
|
|
1442
|
+
/**
|
|
1443
|
+
* Record a **handled** exception as the OTel-conventional `exception` span
|
|
1444
|
+
* event (`exception.type` / `exception.message` / `exception.stacktrace`),
|
|
1445
|
+
* without marking the span failed.
|
|
1446
|
+
*
|
|
1447
|
+
* For an error you swallowed — a retried request, a fallback that worked. An
|
|
1448
|
+
* error that escapes the span body is recorded automatically and *does* set
|
|
1449
|
+
* the error status, so don't call this for one you're re-throwing.
|
|
1450
|
+
*/
|
|
1451
|
+
recordException: (error: unknown) => void;
|
|
1407
1452
|
/** Set one attribute on the enclosing span (merged at record time; post-hoc wins on key clash). */
|
|
1408
1453
|
setAttribute: (key: string, value: LogFields[string]) => void;
|
|
1409
1454
|
/** Merge attributes onto the enclosing span (post-hoc wins on key clash). */
|
|
1410
1455
|
setAttributes: (fields: LogFields) => void;
|
|
1456
|
+
/**
|
|
1457
|
+
* The W3C ids of the span this handle refers to (32-hex trace, 16-hex span).
|
|
1458
|
+
*
|
|
1459
|
+
* On `ctx.span` these are the DISPATCH's ids — the trace the whole request
|
|
1460
|
+
* belongs to. Use it to echo a trace id back to a caller so a user can quote
|
|
1461
|
+
* it in a bug report, to build a `traceparent` for a hand-rolled outbound
|
|
1462
|
+
* call, or to parent a third-party library's spans onto this request.
|
|
1463
|
+
*/
|
|
1464
|
+
spanContext: () => {
|
|
1465
|
+
spanId: string;
|
|
1466
|
+
traceId: string;
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
/**
|
|
1470
|
+
* A causal reference to a span in another trace (OTel `Span.links`). Ids are
|
|
1471
|
+
* lowercase hex — 32 chars for `traceId`, 16 for `spanId`.
|
|
1472
|
+
*/
|
|
1473
|
+
interface SpanLink {
|
|
1474
|
+
/** Attributes describing the relationship, e.g. `{ "link.kind": "enqueued_by" }`. */
|
|
1475
|
+
attributes?: LogFields;
|
|
1476
|
+
spanId: string;
|
|
1477
|
+
traceId: string;
|
|
1478
|
+
}
|
|
1479
|
+
/** OTel `SpanKind`. Drives a collector's service map — see {@link SpanOptions.kind}. */
|
|
1480
|
+
type SpanKind = "client" | "consumer" | "internal" | "producer" | "server";
|
|
1481
|
+
/** Options accepted by `ctx.trace(name, fn, options)` beyond a plain attribute bag. */
|
|
1482
|
+
interface SpanOptions {
|
|
1483
|
+
/** Start attributes, snapshotted before the body runs. */
|
|
1484
|
+
attributes?: LogFields;
|
|
1485
|
+
/**
|
|
1486
|
+
* OTel `SpanKind`, default `"internal"`. Set `"client"` for a call OUT to
|
|
1487
|
+
* another service and `"producer"`/`"consumer"` for queue hops: a collector
|
|
1488
|
+
* builds its service map from this, so leaving everything `"internal"` yields
|
|
1489
|
+
* a trace with no topology.
|
|
1490
|
+
*/
|
|
1491
|
+
kind?: SpanKind;
|
|
1492
|
+
/** Links to spans in other traces, known at span start. */
|
|
1493
|
+
links?: SpanLink[];
|
|
1411
1494
|
}
|
|
1412
1495
|
/**
|
|
1413
1496
|
* Span factory on every function `ctx`. Wraps a sub-operation so it becomes its
|
|
@@ -1458,10 +1541,52 @@ interface SpanHandle {
|
|
|
1458
1541
|
* @param fn The body to time, receiving a tracer bound to this span for any
|
|
1459
1542
|
* nested spans and the enclosing span's {@link SpanHandle} for post-hoc
|
|
1460
1543
|
* attributes. May be sync or async; the result is awaited.
|
|
1461
|
-
* @param attributes
|
|
1462
|
-
* normalized like a log line's `fields
|
|
1544
|
+
* @param attributes Either a plain attribute bag to stamp on the span at start
|
|
1545
|
+
* (normalized like a log line's `fields`), or a {@link SpanOptions} object when
|
|
1546
|
+
* you need `kind` or `links`. It is read as options only when *every* key is one
|
|
1547
|
+
* of `attributes`/`kind`/`links`; `{ attributes: { kind: "premium" } }` is the
|
|
1548
|
+
* explicit form if your own attributes happen to be named that.
|
|
1549
|
+
*/
|
|
1550
|
+
type LunoraTracer = <T>(name: string, function_: (trace: LunoraTracer, span: SpanHandle) => Promise<T> | T, attributes?: LogFields | SpanOptions) => Promise<T>;
|
|
1551
|
+
/**
|
|
1552
|
+
* `ctx.span` — a handle onto **this request's own span**, and with it the
|
|
1553
|
+
* wide-event API.
|
|
1554
|
+
*
|
|
1555
|
+
* ```ts
|
|
1556
|
+
* export const checkout = mutation({ handler: async (ctx, args) => {
|
|
1557
|
+
* ctx.span.setAttributes({ "user.plan": user.plan, "cart.items": cart.length });
|
|
1558
|
+
* const payment = await charge(cart);
|
|
1559
|
+
* ctx.span.setAttributes({ "payment.provider": payment.provider, "payment.total": payment.total });
|
|
1560
|
+
* if (payment.retried) ctx.span.addEvent("payment.retried", { attempts: payment.attempts });
|
|
1561
|
+
* return payment;
|
|
1562
|
+
* }});
|
|
1563
|
+
* ```
|
|
1564
|
+
*
|
|
1565
|
+
* **Why this instead of more log lines.** The usual way to make a handler
|
|
1566
|
+
* observable is to sprinkle `ctx.log.info` through it, which costs one record per
|
|
1567
|
+
* call, scatters one request's facts across a dozen rows, and forces every
|
|
1568
|
+
* question to be answered by correlating them back together. The wide-event
|
|
1569
|
+
* pattern inverts that: accumulate the facts as you learn them, and emit **one**
|
|
1570
|
+
* richly-attributed record per unit of work. Cost is flat — one span per request
|
|
1571
|
+
* no matter how much you attach — and every question ("p99 checkout latency for
|
|
1572
|
+
* pro-plan users with >10 items") becomes a single filter over one table instead
|
|
1573
|
+
* of a join across log lines.
|
|
1574
|
+
*
|
|
1575
|
+
* **This is plain OpenTelemetry, not a Lunora convention.** The attributes land
|
|
1576
|
+
* on the span the dispatch already emits, and are additionally exported as an
|
|
1577
|
+
* OTel Event record named `lunora.dispatch`, correlated by `trace_id`/`span_id`.
|
|
1578
|
+
* Any OTLP backend groups and aggregates them with no special configuration.
|
|
1579
|
+
*
|
|
1580
|
+
* **`span` vs `trace`.** `ctx.trace(name, fn)` creates a NEW child span to time a
|
|
1581
|
+
* sub-operation; `ctx.span` attaches to the one that already exists for the
|
|
1582
|
+
* request. Use `trace` for "how long did this part take", `span` for "what was
|
|
1583
|
+
* true about this request". Inside a `ctx.trace` body, the handle passed as the
|
|
1584
|
+
* body's second argument is that child span's equivalent of this.
|
|
1585
|
+
*
|
|
1586
|
+
* Attributes are normalized exactly like `ctx.log` fields, and recording is
|
|
1587
|
+
* best-effort — a telemetry failure never breaks the handler.
|
|
1463
1588
|
*/
|
|
1464
|
-
type
|
|
1589
|
+
type LunoraWideEvent = SpanHandle;
|
|
1465
1590
|
/**
|
|
1466
1591
|
* Application metrics on every function `ctx` — the third signal alongside
|
|
1467
1592
|
* `ctx.log` and `ctx.trace`. Each call records one measurement that flows to an
|
|
@@ -1546,6 +1671,8 @@ interface QueryCtx {
|
|
|
1546
1671
|
readonly runQuery: <A extends ArgsValidator, R>(reference: RegisteredQuery<A, R>, args: InferArgs<A>) => Promise<R>;
|
|
1547
1672
|
/** Read account-level secrets from Cloudflare Secrets Store; see {@link Secrets}. */
|
|
1548
1673
|
readonly secrets: Secrets;
|
|
1674
|
+
/** Attach facts to THIS request's span — the wide event; see {@link LunoraWideEvent}. */
|
|
1675
|
+
readonly span: LunoraWideEvent;
|
|
1549
1676
|
readonly storage: ReadOnlyStorage;
|
|
1550
1677
|
/** Wrap a sub-operation in its own nested span; see {@link LunoraTracer}. */
|
|
1551
1678
|
readonly trace: LunoraTracer;
|
|
@@ -1600,6 +1727,8 @@ interface MutationCtx {
|
|
|
1600
1727
|
readonly scheduler: Scheduler;
|
|
1601
1728
|
/** Read account-level secrets from Cloudflare Secrets Store; see {@link Secrets}. */
|
|
1602
1729
|
readonly secrets: Secrets;
|
|
1730
|
+
/** Attach facts to THIS request's span — the wide event; see {@link LunoraWideEvent}. */
|
|
1731
|
+
readonly span: LunoraWideEvent;
|
|
1603
1732
|
readonly storage: ReadOnlyStorage;
|
|
1604
1733
|
/** Wrap a sub-operation in its own nested span; see {@link LunoraTracer}. */
|
|
1605
1734
|
readonly trace: LunoraTracer;
|
|
@@ -1649,6 +1778,8 @@ interface ActionCtx {
|
|
|
1649
1778
|
readonly scheduler: Scheduler;
|
|
1650
1779
|
/** Read account-level secrets from Cloudflare Secrets Store; see {@link Secrets}. */
|
|
1651
1780
|
readonly secrets: Secrets;
|
|
1781
|
+
/** Attach facts to THIS request's span — the wide event; see {@link LunoraWideEvent}. */
|
|
1782
|
+
readonly span: LunoraWideEvent;
|
|
1652
1783
|
readonly storage: Storage;
|
|
1653
1784
|
/** Wrap a sub-operation in its own nested span; see {@link LunoraTracer}. */
|
|
1654
1785
|
readonly trace: LunoraTracer;
|
|
@@ -1662,4 +1793,4 @@ interface ActionCtx {
|
|
|
1662
1793
|
*/
|
|
1663
1794
|
type AnyApi = Record<string, Record<string, RegisteredFunction<ArgsValidator, unknown, FunctionKind>>>;
|
|
1664
1795
|
declare const anyApi: AnyApi;
|
|
1665
|
-
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExposeConfig, type ExternalSourceCursor, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type Secrets, type SecretsStoreSecretLike, type ShardMode, type SpanHandle, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type TtlDefinition, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, type X402ProcedureConfig, anyApi };
|
|
1796
|
+
export { type ActionCtx, type AggregateIndexDefinition, type AggregateOp, type AnyApi, type ArgsValidator, type AuthState, type CachePurge, type DatabaseReader, type DatabaseWriter, type DurableObjectJurisdiction, type ExposeConfig, type ExternalSourceCursor, type ExternalSourceDefinition, type ExternalSourceMode, type ExternalSourceRefresh, type FunctionKind, type FunctionVisibility, type GeoBoundingBox, type GeoFilterBuilder, type GeoIndexDefinition, type GeoPointInput, type GlobalBackend, type IndexDefinition, type IndexRangeBuilder, type InferArgs, type LifecycleEvent, type LifecycleEventKind, type LogFields, type LunoraLogMethod, type LunoraLogger, type LunoraMetrics, type LunoraTracer, type LunoraWideEvent, type MutationCtx, type OnDeleteAction, type PaginationOptions, type PaginationResult, type QueryCtx, type RankIndexDefinition, type RankSortKey, type ReadOnlyStorage, type RegisteredAction, type RegisteredFunction, type RegisteredLifecycleHook, type RegisteredMutation, type RegisteredQuery, type RegisteredStream, type RelationDefinition, type ScheduledFunctionDoc, type ScheduledJob, type Scheduler, type Schema, type SearchFilterBuilder, type SearchIndexDefinition, type Secrets, type SecretsStoreSecretLike, type ShardMode, type SpanHandle, type SpanKind, type SpanLink, type SpanOptions, type Storage, type StorageMetadata, type SystemDatabaseReader, type SystemDoc, type SystemQuery, type SystemTableName, type TableDefinition, type TableReader, type TableVectorIndex, type TriggerAggregateOptions, type TriggerBuilder, type TriggerCtx, type TriggerDatabase, type TriggerDefinition, type TriggerDeleteEvent, type TriggerEvent, type TriggerGroupByEntry, type TriggerGroupByOptions, type TriggerHandler, type TriggerInsertEvent, type TriggerOp, type TriggerQueryArgs, type TriggerQueryPage, type TriggerRankOptions, type TriggerRankPageOptions, type TriggerRankResult, type TriggerRow, type TriggerTiming, type TriggerUpdateEvent, type TtlDefinition, type VectorEmbedder, type VectorIndexDefinition, type VectorMatch, type VectorMatches, type VectorMetric, type VectorQueryInput, type VectorRecord, type VectorSearch, type VectorSearchReader, type VectorUpsertInput, type WorkflowCreateOptions, type WorkflowHandle, type WorkflowInstance, type WorkflowInstanceStatus, type WorkflowStatusResult, type Workflows, type X402ProcedureConfig, anyApi };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/server",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.34",
|
|
4
4
|
"description": "Server primitives for Lunora: defineSchema, defineTable, query, mutation, and action",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"backend",
|
|
@@ -56,6 +56,10 @@
|
|
|
56
56
|
"types": "./dist/rls/testing.d.ts",
|
|
57
57
|
"import": "./dist/rls/testing.mjs"
|
|
58
58
|
},
|
|
59
|
+
"./otel": {
|
|
60
|
+
"types": "./dist/otel.d.ts",
|
|
61
|
+
"import": "./dist/otel.mjs"
|
|
62
|
+
},
|
|
59
63
|
"./package.json": "./package.json"
|
|
60
64
|
},
|
|
61
65
|
"publishConfig": {
|
|
@@ -66,7 +70,15 @@
|
|
|
66
70
|
"@lunora/scheduler": "1.0.0-alpha.12",
|
|
67
71
|
"@lunora/values": "1.0.0-alpha.11",
|
|
68
72
|
"drizzle-orm": "^0.45.2",
|
|
69
|
-
"hono": "^4.12.
|
|
73
|
+
"hono": "^4.12.32"
|
|
74
|
+
},
|
|
75
|
+
"peerDependencies": {
|
|
76
|
+
"@opentelemetry/api": "^1.9.1"
|
|
77
|
+
},
|
|
78
|
+
"peerDependenciesMeta": {
|
|
79
|
+
"@opentelemetry/api": {
|
|
80
|
+
"optional": true
|
|
81
|
+
}
|
|
70
82
|
},
|
|
71
83
|
"engines": {
|
|
72
84
|
"node": "^22.15.0 || >=24.11.0"
|