@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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/live-sync-client.d.ts +18 -0
- package/dist/live-sync-client.d.ts.map +1 -1
- package/dist/live-sync-client.js +43 -2
- package/dist/live-sync-client.js.map +1 -1
- package/dist/node.d.ts +1 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +4 -0
- package/dist/node.js.map +1 -1
- package/dist/otel.d.ts +178 -0
- package/dist/otel.d.ts.map +1 -0
- package/dist/otel.js +259 -0
- package/dist/otel.js.map +1 -0
- package/dist/replica/catalyst-replica.d.ts +66 -0
- package/dist/replica/catalyst-replica.d.ts.map +1 -1
- package/dist/replica/catalyst-replica.js +202 -46
- package/dist/replica/catalyst-replica.js.map +1 -1
- package/package.json +10 -1
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
|
package/dist/otel.js.map
ADDED
|
@@ -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":"AA4BA,OAAO,EAQL,KAAK,WAAW,EAEhB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAC1B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"catalyst-replica.d.ts","sourceRoot":"","sources":["../../src/replica/catalyst-replica.ts"],"names":[],"mappings":"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"}
|