@catalyst-cloud/sdk 0.2.1 → 0.3.1

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/otel.js ADDED
@@ -0,0 +1,259 @@
1
+ // @catalyst-cloud/sdk — guarded, zero-hard-dep OpenTelemetry seam (CTC-138).
2
+ //
3
+ // `@opentelemetry/api` is an OPTIONAL peer dependency. This module is the ONE place the SDK touches
4
+ // it, and it does so through a guarded **dynamic** import resolved once during the async `start()`
5
+ // path — never a static top-level `import`. That distinction is load-bearing:
6
+ //
7
+ // • A static `import { trace, metrics } from "@opentelemetry/api"` fails MODULE RESOLUTION when a
8
+ // consumer hasn't installed the package → a hard dependency in practice. The api package's
9
+ // built-in no-op tracer/meter only save you AFTER it has been resolved (i.e. when it's installed
10
+ // but no provider is registered); they do nothing for "not installed at all".
11
+ // • The guarded `await import("@opentelemetry/api")` here catches the resolution failure and falls
12
+ // back to hand-rolled no-op stubs, so the SDK imports + runs with the package entirely ABSENT.
13
+ //
14
+ // When the package IS present and the consumer has registered a global TracerProvider/MeterProvider,
15
+ // spans + metrics route through `trace.getTracer()` / `metrics.getMeter()` — so the consumer's
16
+ // Resource (service.name, etc.) flows through automatically. When present but with NO provider, the
17
+ // api's own no-ops apply and every call is harmless.
18
+ //
19
+ // Kept free of any node-only import so the browser bundle stays clean; the public surfaces below are
20
+ // declared STRUCTURALLY (no `@opentelemetry/api` type import) so no OTel type leaks into the package's
21
+ // generated `.d.ts`, and the whole seam tree-shakes away (package.json `sideEffects:false`) when
22
+ // telemetry is off.
23
+ /** The shared `catalyst.*` semconv attribute keys emitted across spans + metrics. */
24
+ export const CATALYST_ATTR = {
25
+ /** The tenant id (= mirror/account name). */
26
+ tenant: "catalyst.tenant",
27
+ /** The upstream system a row originates from: `"linear"` | `"github"`. */
28
+ source: "catalyst.source",
29
+ /** The durable change-feed cursor (last applied seq). */
30
+ cursor: "catalyst.replica.cursor",
31
+ /** head_seq − cursor (mirror lag in seqs), when head_seq is known. */
32
+ lagSeq: "catalyst.replica.lag_seq",
33
+ /** The connection lifecycle status string. */
34
+ status: "catalyst.replica.status",
35
+ /** Rows applied during a seed. */
36
+ rowCount: "catalyst.replica.row_count",
37
+ /** Rows in one seed apply-batch. */
38
+ batchRows: "catalyst.replica.batch_rows",
39
+ /** The per-frame apply outcome (CTL-1402): `"applied"` | `"skipped"` | `"failed"`. Low-cardinality
40
+ * — safe as a metric label; seq/entity/err_message are VALUES on the log line, never labels. */
41
+ result: "catalyst.replica.result",
42
+ };
43
+ /** Metric instrument names (OTel metric stream names). */
44
+ export const REPLICA_METRIC = {
45
+ cursor: "catalyst.replica.cursor",
46
+ lagSeq: "catalyst.replica.lag_seq",
47
+ freshnessMs: "catalyst.replica.freshness_ms",
48
+ status: "catalyst.replica.status",
49
+ applied: "catalyst.replica.applied",
50
+ applyBatchRows: "catalyst.replica.apply_batch_rows",
51
+ };
52
+ /** Structured-log MESSAGE names the daemon's `log` callback routes to Loki, where the fleet's
53
+ * logs→metrics connector materializes them (the fleet has no in-process MeterProvider, so the
54
+ * per-frame apply RESULT rides a structured log line, not an OTLP metric — CTL-1402). */
55
+ export const REPLICA_LOG = {
56
+ /** Per applied frame: `{result, seq, entity, source, err_message?}`. */
57
+ apply: "catalyst.replica.apply",
58
+ };
59
+ /** Span names. */
60
+ export const REPLICA_SPAN = {
61
+ seed: "catalyst.replica.seed",
62
+ applyBatch: "catalyst.replica.apply_batch",
63
+ resync: "catalyst.replica.resync",
64
+ reconnect: "catalyst.replica.reconnect",
65
+ };
66
+ /** `LiveSyncStatus` → a numeric gauge code (the `catalyst.replica.status` gauge value). */
67
+ export const REPLICA_STATUS_CODE = {
68
+ connecting: 0,
69
+ live: 1,
70
+ reconnecting: 2,
71
+ resyncing: 3,
72
+ error: 4,
73
+ stopped: 5,
74
+ };
75
+ /** The default instrumentation-scope name for both the tracer and the meter. */
76
+ export const DEFAULT_SCOPE_NAME = "@catalyst-cloud/sdk";
77
+ /** The mirror entities sourced from GitHub (the rest are Linear) — drives the `catalyst.source` attr. */
78
+ const GITHUB_ENTITIES = new Set([
79
+ "pull_requests",
80
+ "check_runs",
81
+ "commit_statuses",
82
+ "reviews",
83
+ ]);
84
+ /** Map a change-feed `entity` (table name) to its upstream source system, for `catalyst.source`. */
85
+ export function entitySource(entity) {
86
+ return GITHUB_ENTITIES.has(entity) ? "github" : "linear";
87
+ }
88
+ // ── No-op implementation (used when telemetry is OFF or `@opentelemetry/api` is absent). ───────────
89
+ const NOOP_SPAN_HANDLE = { setAttribute() { } };
90
+ const NOOP_MANUAL_SPAN = { setAttribute() { }, end() { } };
91
+ const NOOP_REGISTRATION = { remove() { } };
92
+ const NOOP_COUNTER = { add() { } };
93
+ const NOOP_HISTOGRAM = { record() { } };
94
+ /** A telemetry that does nothing but still threads the callback's return value through `withActiveSpan*`. */
95
+ export const NOOP_TELEMETRY = {
96
+ enabled: false,
97
+ withActiveSpan: (_name, _attributes, fn) => fn(NOOP_SPAN_HANDLE),
98
+ withActiveSpanSync: (_name, _attributes, fn) => fn(NOOP_SPAN_HANDLE),
99
+ startSpan: () => NOOP_MANUAL_SPAN,
100
+ observableGauge: () => NOOP_REGISTRATION,
101
+ counter: () => NOOP_COUNTER,
102
+ histogram: () => NOOP_HISTOGRAM,
103
+ };
104
+ /** Drop `undefined`-valued attributes (OTel rejects them) → a clean attribute record. */
105
+ function cleanAttrs(attributes) {
106
+ const out = {};
107
+ if (!attributes)
108
+ return out;
109
+ for (const [k, v] of Object.entries(attributes)) {
110
+ if (v !== undefined)
111
+ out[k] = v;
112
+ }
113
+ return out;
114
+ }
115
+ /**
116
+ * Build a REAL telemetry facade over a resolved `@opentelemetry/api` surface (or the NO-OP when
117
+ * `api` is null — the "package absent" branch). Exported (but NOT re-exported from the package
118
+ * entrypoints) so it can be unit-tested directly with `null` for the absent case.
119
+ */
120
+ export function buildTelemetry(api, names) {
121
+ if (!api)
122
+ return NOOP_TELEMETRY;
123
+ const tracer = api.trace.getTracer(names.tracerName);
124
+ const meter = api.metrics.getMeter(names.meterName);
125
+ const OK = api.SpanStatusCode.OK;
126
+ const ERROR = api.SpanStatusCode.ERROR;
127
+ const endSpan = (span, error) => {
128
+ if (error !== undefined) {
129
+ span.recordException(error);
130
+ span.setStatus({ code: ERROR, message: error instanceof Error ? error.message : String(error) });
131
+ }
132
+ else {
133
+ span.setStatus({ code: OK });
134
+ }
135
+ span.end();
136
+ };
137
+ const handleFor = (span) => ({
138
+ setAttribute: (k, v) => {
139
+ span.setAttribute(k, v);
140
+ },
141
+ });
142
+ return {
143
+ enabled: true,
144
+ withActiveSpan(name, attributes, fn) {
145
+ return tracer.startActiveSpan(name, { attributes: cleanAttrs(attributes) }, async (span) => {
146
+ try {
147
+ const result = await fn(handleFor(span));
148
+ endSpan(span);
149
+ return result;
150
+ }
151
+ catch (err) {
152
+ endSpan(span, err);
153
+ throw err;
154
+ }
155
+ });
156
+ },
157
+ withActiveSpanSync(name, attributes, fn) {
158
+ return tracer.startActiveSpan(name, { attributes: cleanAttrs(attributes) }, (span) => {
159
+ try {
160
+ const result = fn(handleFor(span));
161
+ endSpan(span);
162
+ return result;
163
+ }
164
+ catch (err) {
165
+ endSpan(span, err);
166
+ throw err;
167
+ }
168
+ });
169
+ },
170
+ startSpan(name, attributes) {
171
+ const span = tracer.startSpan(name, { attributes: cleanAttrs(attributes) });
172
+ return {
173
+ setAttribute: (k, v) => {
174
+ span.setAttribute(k, v);
175
+ },
176
+ end: (error) => endSpan(span, error),
177
+ };
178
+ },
179
+ observableGauge(name, options, callback) {
180
+ const gauge = meter.createObservableGauge(name, options);
181
+ const cb = (result) => {
182
+ callback({ observe: (value, attrs) => result.observe(value, cleanAttrs(attrs)) });
183
+ };
184
+ gauge.addCallback(cb);
185
+ return { remove: () => gauge.removeCallback(cb) };
186
+ },
187
+ counter(name, options) {
188
+ const instrument = meter.createCounter(name, options);
189
+ return { add: (value, attrs) => instrument.add(value, cleanAttrs(attrs)) };
190
+ },
191
+ histogram(name, options) {
192
+ const instrument = meter.createHistogram(name, options);
193
+ return { record: (value, attrs) => instrument.record(value, cleanAttrs(attrs)) };
194
+ },
195
+ };
196
+ }
197
+ // ── The guarded one-time dynamic import. ──────────────────────────────────────────────────────────
198
+ let apiPromise;
199
+ let warnedAbsent = false;
200
+ /** Dynamic-import `@opentelemetry/api` ONCE (cached). Resolves to its surface, or `null` if the
201
+ * package isn't installed — the catch is what makes it a TRUE optional peer dependency. */
202
+ async function loadOtelApi() {
203
+ if (apiPromise === undefined) {
204
+ apiPromise = import("@opentelemetry/api").then((mod) => {
205
+ // The named exports (trace/metrics/SpanStatusCode) may sit on the module namespace OR on
206
+ // `default`, depending on the CJS/ESM interop (node vs a bundler/test runner). Pick whichever
207
+ // object actually carries them rather than guessing `default ?? mod`.
208
+ const hasApi = (o) => typeof o === "object" &&
209
+ o !== null &&
210
+ "trace" in o &&
211
+ "metrics" in o &&
212
+ "SpanStatusCode" in o;
213
+ const ns = mod;
214
+ if (hasApi(mod))
215
+ return mod;
216
+ if (hasApi(ns.default))
217
+ return ns.default;
218
+ return null;
219
+ }, () => null);
220
+ }
221
+ return apiPromise;
222
+ }
223
+ /** True iff `value` is an already-resolved {@link Telemetry} (internal pass-through, e.g. a replica
224
+ * sharing its instance with the transport) rather than a {@link TelemetryConfig}. */
225
+ function isTelemetry(value) {
226
+ return (typeof value === "object" &&
227
+ value !== null &&
228
+ typeof value.withActiveSpan === "function");
229
+ }
230
+ /**
231
+ * Resolve the opt-in `telemetry` option into a {@link Telemetry}. Defaults to {@link NOOP_TELEMETRY}
232
+ * (no dynamic import attempted) when undefined/false so the off path is truly zero-overhead. When ON,
233
+ * guard-imports `@opentelemetry/api`; if absent, warns once and falls back to no-op (never throws). An
234
+ * already-resolved `Telemetry` is returned as-is so a replica + its transport share ONE instance.
235
+ */
236
+ export async function createTelemetry(config, defaults) {
237
+ if (isTelemetry(config))
238
+ return config;
239
+ if (config === undefined || config === false)
240
+ return NOOP_TELEMETRY;
241
+ const names = config === true
242
+ ? defaults
243
+ : {
244
+ tracerName: config.tracerName ?? defaults.tracerName,
245
+ meterName: config.meterName ?? defaults.meterName,
246
+ };
247
+ const api = await loadOtelApi();
248
+ if (!api) {
249
+ if (!warnedAbsent) {
250
+ warnedAbsent = true;
251
+ // eslint-disable-next-line no-console
252
+ console.warn("[catalyst-sdk:otel] telemetry was enabled but the optional peer '@opentelemetry/api' is not " +
253
+ "installed — running with no-op telemetry. Install '@opentelemetry/api' to emit spans/metrics.");
254
+ }
255
+ return NOOP_TELEMETRY;
256
+ }
257
+ return buildTelemetry(api, names);
258
+ }
259
+ //# sourceMappingURL=otel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otel.js","sourceRoot":"","sources":["../src/otel.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import { type SqlExecutor, type IssueView, type IssueDetailView, type PullView,
2
2
  import { type AuthStrategy, type LiveSyncStatus, type LogLevel, type WebSocketFactory } from "../live-sync-client.js";
3
3
  import { type EngineFactory, type ReplicaEngine } from "./engine.js";
4
4
  import { type WriterGuardOptions } from "./writer-lock.js";
5
+ import { type TelemetryConfig } from "../otel.js";
5
6
  export interface CatalystReplicaOptions {
6
7
  /** http(s) origin incl. any path prefix (…/api/v1); the scheme is swapped to ws(s) for /connect. */
7
8
  baseUrl: string;
@@ -43,6 +44,22 @@ export interface CatalystReplicaOptions {
43
44
  * hanging. Off by default.
44
45
  */
45
46
  startTimeoutMs?: number;
47
+ /**
48
+ * Opt-in OpenTelemetry (CTC-138). `false`/absent = OFF (strictly zero overhead; no
49
+ * `@opentelemetry/api` import is even attempted). `true` = ON with the default `@catalyst-cloud/sdk`
50
+ * instrumentation scope; an object overrides the tracer/meter name. When ON the replica emits:
51
+ * • SPANS — `catalyst.replica.seed` (snapshot pull+apply), `catalyst.replica.apply_batch` (per
52
+ * seed batch), plus the transport's `catalyst.replica.resync` + `catalyst.replica.reconnect`.
53
+ * • METRICS — observable gauges `catalyst.replica.cursor`, `catalyst.replica.lag_seq` (only when
54
+ * the mirror head_seq is known from the `x-catalyst-head-seq` /snapshot response header),
55
+ * `catalyst.replica.freshness_ms`, `catalyst.replica.status`; a `catalyst.replica.applied`
56
+ * counter (per live frame) and a `catalyst.replica.apply_batch_rows` histogram.
57
+ * All carry `catalyst.tenant` (+ `catalyst.source` where a single entity is involved). `@opentelemetry/api`
58
+ * is an OPTIONAL peer dep: enabling this without it installed logs once and runs no-op (never throws).
59
+ * Spans/metrics route through the consumer's GLOBAL TracerProvider/MeterProvider so their Resource
60
+ * (service.name) flows through.
61
+ */
62
+ telemetry?: TelemetryConfig;
46
63
  }
47
64
  /**
48
65
  * Options for a READ-ONLY reader ({@link CatalystReplica.openReadOnly}). A reader needs only the file
@@ -82,6 +99,19 @@ export declare class CatalystReplica {
82
99
  * an initial seed failure. */
83
100
  private liveResolve;
84
101
  private liveReject;
102
+ /** Resolved once in start(); the no-op until then so any early metric/span call is safe. */
103
+ private telemetry;
104
+ /** Observable-gauge unregister handles, torn down in close() so a closed replica stops being scraped. */
105
+ private metricRegs;
106
+ /** Per-live-frame applied counter + per-seed-batch row histogram (no-op until telemetry is wired). */
107
+ private appliedCounter;
108
+ private applyBatchHistogram;
109
+ /** Last mirror head_seq + server clock observed from the `x-catalyst-head-seq` /snapshot headers
110
+ * (CTC-137), or null until seen. Drives the `lag_seq` gauge (emitted ONLY when non-null). */
111
+ private lastHeadSeq;
112
+ private lastServerTimeMs;
113
+ /** Wall-clock ms of the last applied delta (live frame or seed), or null. Drives `freshness_ms`. */
114
+ private lastAppliedAtMs;
85
115
  constructor(opts: CatalystReplicaOptions);
86
116
  /**
87
117
  * Open a CatalystReplica as a READ-ONLY READER over a file another process owns as the WRITER
@@ -134,6 +164,15 @@ export declare class CatalystReplica {
134
164
  get status(): LiveSyncStatus;
135
165
  /** The raw driver Database the SDK owns — for `drizzle(replica.handle, { schema: mirrorSchema })`. */
136
166
  get handle(): unknown;
167
+ /** Ms since the last applied delta (live frame or seed), or null before the first apply. The basis
168
+ * of the `catalyst.replica.freshness_ms` gauge — "how stale is the local copy right now". */
169
+ get freshnessMs(): number | null;
170
+ /** The last mirror head_seq read from the `x-catalyst-head-seq` /snapshot response header (CTC-137),
171
+ * or null if the header has never been observed. `headSeq − cursor` is the replica's lag in seqs. */
172
+ get headSeq(): number | null;
173
+ /** The mirror server clock (ms) read from the `x-catalyst-server-time-ms` /snapshot response header
174
+ * (CTC-137), or null if never observed — for a consumer that wants to estimate clock skew. */
175
+ get serverTimeMs(): number | null;
137
176
  private resolveEngine;
138
177
  /**
139
178
  * Open the read-only engine and wire ONLY the read ports — no migrations, no `sync_meta` DDL, no
@@ -144,8 +183,32 @@ export declare class CatalystReplica {
144
183
  private openReadOnlyInternal;
145
184
  private handleStatus;
146
185
  private clearLiveDeferred;
186
+ /**
187
+ * Register the four `catalyst.replica.*` observable gauges (whose async callbacks read live instance
188
+ * state) + create the per-frame counter and per-batch histogram. A no-op telemetry returns no-op
189
+ * instruments + empty registrations, so this is safe (and free) when telemetry is OFF. Idempotent
190
+ * per start(); the registrations are torn down in close().
191
+ */
192
+ private registerMetrics;
147
193
  /** Land one delta + advance the durable cursor atomically (a crash can't skip a seq), then signal. */
148
194
  private applyFrame;
195
+ /**
196
+ * CTL-1402: record ONE apply outcome per live frame. Two coherent emit paths, both carrying
197
+ * `result: applied|skipped|failed`:
198
+ *
199
+ * 1. A structured `catalyst.replica.apply` LOG line (via the consumer's `log` callback) — the
200
+ * fleet's primary signal, since it runs NO in-process MeterProvider: the daemon serializes
201
+ * `extra` into fields the Loki→metrics connector materializes. `seq` is the join key to the
202
+ * mirror's `ingest.committed.headSeq`; the failure branch carries the untruncated `err_message`
203
+ * the #127 drift needs. This REPLACES the old string-interpolated `"apply failed for … seq="`
204
+ * line — one emit path, no double-count (the interim in-repo bridge retires on the SDK bump).
205
+ * 2. A `result`-tagged bump of the `catalyst.replica.applied` OTLP counter — durable for when a
206
+ * MeterProvider is adopted; a no-op when telemetry is off.
207
+ *
208
+ * Cardinality: only `source` + `result` are counter labels (both low-card); `seq` / `entity` /
209
+ * `err_message` ride the log line as VALUES, never labels.
210
+ */
211
+ private recordApplyResult;
149
212
  /**
150
213
  * Stream-seed the replica from /snapshot and return the fresh cursor. Streams `response.body` as
151
214
  * NDJSON (chunked, batched transactions) so a large tenant never materializes the whole snapshot in
@@ -154,6 +217,9 @@ export declare class CatalystReplica {
154
217
  * atomic truncate+apply+setCursor safety without holding one giant transaction.
155
218
  */
156
219
  private seedFromSnapshot;
220
+ /** Read CTC-137's `x-catalyst-head-seq` (+ `x-catalyst-server-time-ms`) off the /snapshot response,
221
+ * if present. Guarded so a header-less test fetch stand-in is a no-op. */
222
+ private readHeadSeqHeaders;
157
223
  private feedHeaders;
158
224
  }
159
225
  //# sourceMappingURL=catalyst-replica.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"catalyst-replica.d.ts","sourceRoot":"","sources":["../../src/replica/catalyst-replica.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"catalyst-replica.d.ts","sourceRoot":"","sources":["../../src/replica/catalyst-replica.ts"],"names":[],"mappings":"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"}