@tracewayapp/opamp 0.0.0-stage → 2.0.0-beta.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/wire.ts","../src/messages.ts","../src/client.ts"],"sourcesContent":["export {\n AgentCapabilities,\n AgentToServerFlags,\n ServerToAgentFlags,\n RemoteConfigStatus,\n ServerErrorType,\n encodeAgentToServer,\n decodeServerToAgent,\n encodeServerToAgent,\n} from \"./messages.js\";\nexport type { AgentToServer, ServerToAgent, AgentConfigObject, AttributeValue } from \"./messages.js\";\nexport { OpampHttpClient, uuidString } from \"./client.js\";\nexport type { OpampClientOptions, AgentDescription, RemoteConfig, ApplyResult } from \"./client.js\";\n","/**\n * The protobuf wire format, only as much as OpAMP needs: varints, length-\n * delimited fields and fixed 64-bit doubles. Numbers are JavaScript numbers,\n * which is exact for every value OpAMP carries below 2^53.\n */\n\nexport const WIRE_VARINT = 0;\nexport const WIRE_FIXED64 = 1;\nexport const WIRE_LENGTH = 2;\nexport const WIRE_FIXED32 = 5;\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\nexport class Writer {\n private chunks: number[] = [];\n\n varint(value: number): this {\n let v = Math.max(0, Math.floor(value));\n while (v >= 0x80) {\n this.chunks.push((v % 0x80) | 0x80);\n v = Math.floor(v / 0x80);\n }\n this.chunks.push(v);\n return this;\n }\n\n tag(field: number, wireType: number): this {\n return this.varint(field * 8 + wireType);\n }\n\n uint(field: number, value: number): this {\n if (value === 0) return this;\n return this.tag(field, WIRE_VARINT).varint(value);\n }\n\n bool(field: number, value: boolean): this {\n return value ? this.tag(field, WIRE_VARINT).varint(1) : this;\n }\n\n bytes(field: number, value: Uint8Array): this {\n if (value.length === 0) return this;\n this.tag(field, WIRE_LENGTH).varint(value.length);\n for (const b of value) this.chunks.push(b);\n return this;\n }\n\n string(field: number, value: string): this {\n return this.bytes(field, encoder.encode(value));\n }\n\n double(field: number, value: number): this {\n if (value === 0) return this;\n const buf = new DataView(new ArrayBuffer(8));\n buf.setFloat64(0, value, true);\n this.tag(field, WIRE_FIXED64);\n for (let i = 0; i < 8; i++) this.chunks.push(buf.getUint8(i));\n return this;\n }\n\n /** Writes a nested message. An empty message is still written when `always` is set (presence matters). */\n message(field: number, build: (w: Writer) => void, always = false): this {\n const inner = new Writer();\n build(inner);\n const bytes = inner.finish();\n if (bytes.length === 0 && !always) return this;\n this.tag(field, WIRE_LENGTH).varint(bytes.length);\n for (const b of bytes) this.chunks.push(b);\n return this;\n }\n\n finish(): Uint8Array {\n return Uint8Array.from(this.chunks);\n }\n}\n\nexport class Reader {\n private pos = 0;\n\n constructor(private readonly buf: Uint8Array) {}\n\n done(): boolean {\n return this.pos >= this.buf.length;\n }\n\n varint(): number {\n let result = 0;\n let multiplier = 1;\n for (;;) {\n if (this.pos >= this.buf.length) throw new Error(\"truncated varint\");\n const byte = this.buf[this.pos++]!;\n result += (byte & 0x7f) * multiplier;\n if (byte < 0x80) return result;\n multiplier *= 0x80;\n if (multiplier > 2 ** 70) throw new Error(\"varint too long\");\n }\n }\n\n tag(): { field: number; wireType: number } {\n const tag = this.varint();\n return { field: Math.floor(tag / 8), wireType: tag % 8 };\n }\n\n bytes(): Uint8Array {\n const length = this.varint();\n if (this.pos + length > this.buf.length) throw new Error(\"truncated field\");\n const out = this.buf.subarray(this.pos, this.pos + length);\n this.pos += length;\n return out;\n }\n\n string(): string {\n return decoder.decode(this.bytes());\n }\n\n double(): number {\n if (this.pos + 8 > this.buf.length) throw new Error(\"truncated double\");\n const view = new DataView(this.buf.buffer, this.buf.byteOffset + this.pos, 8);\n this.pos += 8;\n return view.getFloat64(0, true);\n }\n\n skip(wireType: number): void {\n switch (wireType) {\n case WIRE_VARINT:\n this.varint();\n return;\n case WIRE_FIXED64:\n this.pos += 8;\n return;\n case WIRE_LENGTH:\n this.bytes();\n return;\n case WIRE_FIXED32:\n this.pos += 4;\n return;\n }\n throw new Error(`unsupported wire type ${wireType}`);\n }\n}\n","import { Reader, Writer, WIRE_LENGTH, WIRE_VARINT } from \"./wire.js\";\n\n/** AgentCapabilities from the OpAMP spec. */\nexport const AgentCapabilities = {\n ReportsStatus: 0x1,\n AcceptsRemoteConfig: 0x2,\n ReportsEffectiveConfig: 0x4,\n ReportsHealth: 0x800,\n ReportsRemoteConfig: 0x1000,\n ReportsHeartbeat: 0x2000,\n} as const;\n\nexport const AgentToServerFlags = { RequestInstanceUid: 0x1 } as const;\nexport const ServerToAgentFlags = { ReportFullState: 0x1 } as const;\n\nexport enum RemoteConfigStatus {\n Unset = 0,\n Applied = 1,\n Applying = 2,\n Failed = 3,\n}\n\nexport enum ServerErrorType {\n Unknown = 0,\n BadRequest = 1,\n Unavailable = 2,\n}\n\nexport type AttributeValue = string | boolean | number | string[];\n\nexport interface AgentToServer {\n instanceUid: Uint8Array;\n sequenceNum: number;\n agentDescription?: {\n identifying: Record<string, AttributeValue>;\n nonIdentifying: Record<string, AttributeValue>;\n };\n capabilities: number;\n remoteConfigStatus?: { lastRemoteConfigHash: Uint8Array; status: RemoteConfigStatus; errorMessage?: string };\n agentDisconnect?: boolean;\n flags?: number;\n customCapabilities?: string[];\n}\n\nexport interface AgentConfigObject {\n body: Uint8Array;\n contentType: string;\n}\n\nexport interface ServerToAgent {\n instanceUid?: Uint8Array;\n errorResponse?: { type: ServerErrorType; message: string; retryAfterMs?: number };\n remoteConfig?: { configMap: Record<string, AgentConfigObject>; configHash: Uint8Array };\n heartbeatIntervalSeconds?: number;\n flags: number;\n capabilities: number;\n newInstanceUid?: Uint8Array;\n customMessage?: { capability: string; type: string; data: Uint8Array };\n}\n\nfunction writeAnyValue(w: Writer, value: AttributeValue): void {\n if (typeof value === \"string\") {\n w.string(1, value);\n } else if (typeof value === \"boolean\") {\n w.bool(2, value);\n } else if (typeof value === \"number\") {\n if (Number.isInteger(value) && value >= 0) {\n if (value !== 0) w.tag(3, WIRE_VARINT).varint(value);\n } else {\n w.double(4, value);\n }\n } else {\n w.message(5, (array) => {\n for (const item of value) array.message(1, (v) => v.string(1, item), true);\n });\n }\n}\n\nfunction writeAttributes(w: Writer, field: number, attrs: Record<string, AttributeValue>): void {\n for (const [key, value] of Object.entries(attrs)) {\n w.message(field, (kv) => {\n kv.string(1, key);\n kv.message(2, (v) => writeAnyValue(v, value), true);\n });\n }\n}\n\nexport function encodeAgentToServer(msg: AgentToServer): Uint8Array {\n const w = new Writer();\n w.bytes(1, msg.instanceUid);\n w.uint(2, msg.sequenceNum);\n if (msg.agentDescription) {\n const description = msg.agentDescription;\n w.message(3, (d) => {\n writeAttributes(d, 1, description.identifying);\n writeAttributes(d, 2, description.nonIdentifying);\n });\n }\n w.uint(4, msg.capabilities);\n if (msg.remoteConfigStatus) {\n const status = msg.remoteConfigStatus;\n w.message(7, (s) => {\n s.bytes(1, status.lastRemoteConfigHash);\n s.uint(2, status.status);\n if (status.errorMessage) s.string(3, status.errorMessage);\n });\n }\n if (msg.agentDisconnect) w.message(9, () => {}, true);\n w.uint(10, msg.flags ?? 0);\n if (msg.customCapabilities?.length) {\n const capabilities = msg.customCapabilities;\n w.message(12, (c) => {\n for (const capability of capabilities) c.string(1, capability);\n });\n }\n return w.finish();\n}\n\nfunction each(buf: Uint8Array, handle: (field: number, wireType: number, r: Reader) => boolean): void {\n const r = new Reader(buf);\n while (!r.done()) {\n const { field, wireType } = r.tag();\n if (!handle(field, wireType, r)) r.skip(wireType);\n }\n}\n\nfunction decodeConfigObject(buf: Uint8Array): AgentConfigObject {\n const object: AgentConfigObject = { body: new Uint8Array(), contentType: \"\" };\n each(buf, (field, wireType, r) => {\n if (wireType !== WIRE_LENGTH) return false;\n if (field === 1) object.body = r.bytes().slice();\n else if (field === 2) object.contentType = r.string();\n else return false;\n return true;\n });\n return object;\n}\n\nfunction decodeRemoteConfig(buf: Uint8Array): NonNullable<ServerToAgent[\"remoteConfig\"]> {\n const config: NonNullable<ServerToAgent[\"remoteConfig\"]> = { configMap: {}, configHash: new Uint8Array() };\n each(buf, (field, wireType, r) => {\n if (wireType !== WIRE_LENGTH) return false;\n if (field === 2) {\n config.configHash = r.bytes().slice();\n return true;\n }\n if (field !== 1) return false;\n each(r.bytes(), (mapField, mapWire, mapReader) => {\n if (mapField !== 1 || mapWire !== WIRE_LENGTH) return false;\n let key = \"\";\n let value: AgentConfigObject = { body: new Uint8Array(), contentType: \"\" };\n each(mapReader.bytes(), (entryField, entryWire, entryReader) => {\n if (entryWire !== WIRE_LENGTH) return false;\n if (entryField === 1) key = entryReader.string();\n else if (entryField === 2) value = decodeConfigObject(entryReader.bytes());\n else return false;\n return true;\n });\n config.configMap[key] = value;\n return true;\n });\n return true;\n });\n return config;\n}\n\nexport function decodeServerToAgent(buf: Uint8Array): ServerToAgent {\n const msg: ServerToAgent = { flags: 0, capabilities: 0 };\n each(buf, (field, wireType, r) => {\n switch (field) {\n case 1:\n if (wireType !== WIRE_LENGTH) return false;\n msg.instanceUid = r.bytes().slice();\n return true;\n case 2: {\n if (wireType !== WIRE_LENGTH) return false;\n const error: NonNullable<ServerToAgent[\"errorResponse\"]> = { type: ServerErrorType.Unknown, message: \"\" };\n each(r.bytes(), (f, w, er) => {\n if (f === 1 && w === WIRE_VARINT) error.type = er.varint();\n else if (f === 2 && w === WIRE_LENGTH) error.message = er.string();\n else if (f === 3 && w === WIRE_LENGTH) {\n each(er.bytes(), (rf, rw, rr) => {\n if (rf !== 1 || rw !== WIRE_VARINT) return false;\n error.retryAfterMs = rr.varint() / 1e6;\n return true;\n });\n } else return false;\n return true;\n });\n msg.errorResponse = error;\n return true;\n }\n case 3:\n if (wireType !== WIRE_LENGTH) return false;\n msg.remoteConfig = decodeRemoteConfig(r.bytes());\n return true;\n case 4:\n if (wireType !== WIRE_LENGTH) return false;\n each(r.bytes(), (f, w, cr) => {\n if (f !== 2 || w !== WIRE_LENGTH) return false;\n each(cr.bytes(), (of, ow, or) => {\n if (of !== 4 || ow !== WIRE_VARINT) return false;\n msg.heartbeatIntervalSeconds = or.varint();\n return true;\n });\n return true;\n });\n return true;\n case 6:\n if (wireType !== WIRE_VARINT) return false;\n msg.flags = r.varint();\n return true;\n case 7:\n if (wireType !== WIRE_VARINT) return false;\n msg.capabilities = r.varint();\n return true;\n case 8:\n if (wireType !== WIRE_LENGTH) return false;\n each(r.bytes(), (f, w, ir) => {\n if (f !== 1 || w !== WIRE_LENGTH) return false;\n msg.newInstanceUid = ir.bytes().slice();\n return true;\n });\n return true;\n case 11: {\n if (wireType !== WIRE_LENGTH) return false;\n const custom = { capability: \"\", type: \"\", data: new Uint8Array() };\n each(r.bytes(), (f, w, cr) => {\n if (w !== WIRE_LENGTH) return false;\n if (f === 1) custom.capability = cr.string();\n else if (f === 2) custom.type = cr.string();\n else if (f === 3) custom.data = cr.bytes().slice();\n else return false;\n return true;\n });\n msg.customMessage = custom;\n return true;\n }\n }\n return false;\n });\n return msg;\n}\n\n/** Encodes the parts of a ServerToAgent this client reads; for mock servers in tests. */\nexport function encodeServerToAgent(msg: Omit<ServerToAgent, \"errorResponse\" | \"customMessage\">): Uint8Array {\n const w = new Writer();\n if (msg.instanceUid) w.bytes(1, msg.instanceUid);\n if (msg.remoteConfig) {\n const config = msg.remoteConfig;\n w.message(3, (rc) => {\n rc.message(1, (map) => {\n for (const [key, object] of Object.entries(config.configMap)) {\n map.message(1, (entry) => {\n entry.string(1, key);\n entry.message(2, (o) => o.bytes(1, object.body).string(2, object.contentType), true);\n });\n }\n });\n rc.bytes(2, config.configHash);\n });\n }\n if (msg.heartbeatIntervalSeconds) {\n const seconds = msg.heartbeatIntervalSeconds;\n w.message(4, (cs) => cs.message(2, (o) => o.uint(4, seconds)));\n }\n w.uint(6, msg.flags);\n w.uint(7, msg.capabilities);\n if (msg.newInstanceUid) w.message(8, (id) => id.bytes(1, msg.newInstanceUid!));\n return w.finish();\n}\n","import type {\n AgentConfigObject,\n AgentToServer,\n AttributeValue,\n ServerToAgent,\n} from \"./messages.js\";\nimport {\n decodeServerToAgent,\n encodeAgentToServer,\n RemoteConfigStatus,\n ServerErrorType,\n ServerToAgentFlags,\n} from \"./messages.js\";\n\nexport interface AgentDescription {\n identifying: Record<string, AttributeValue>;\n nonIdentifying: Record<string, AttributeValue>;\n}\n\nexport interface RemoteConfig {\n configMap: Record<string, AgentConfigObject>;\n configHash: Uint8Array;\n}\n\nexport type ApplyResult =\n { applied: true } | { applied: false; errorMessage: string };\n\nexport interface OpampClientOptions {\n /** The server's OpAMP endpoint, e.g. https://traceway.example.com/api/otel/v1/opamp. */\n endpoint: string;\n headers?: Record<string, string>;\n instanceUid: Uint8Array;\n capabilities: number;\n customCapabilities?: string[];\n /** Read on every poll: the client sends its full state each time, so a stateless server can answer. */\n describe: () => AgentDescription;\n onRemoteConfig: (config: RemoteConfig) => ApplyResult;\n /** Hash of the config applied on an earlier page, so the server does not resend what is already in effect. */\n appliedConfigHash?: Uint8Array;\n onHeartbeatChange?: (seconds: number) => void;\n onInstanceUidChange?: (uid: Uint8Array) => void;\n /** Called once when the server rejects the credentials; the client stops polling. */\n onUnauthorized?: () => void;\n /** A pre-OpAMP server: stop polling and let the SDK use its legacy protocol. */\n onUnsupported?: () => void;\n /** Fetch failed, including a missing CORS preflight on older cross-origin servers. */\n onUnavailable?: () => void;\n onConnected?: () => void;\n defaultPollIntervalMs?: number;\n fetchImpl?: typeof fetch;\n requestTimeoutMs?: number;\n}\n\nconst MIN_POLL_INTERVAL_MS = 30_000;\nconst MAX_BACKOFF_MS = 30 * 60_000;\nconst FIRST_BACKOFF_MS = 30_000;\n\nexport function uuidString(bytes: Uint8Array): string {\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\n \"\",\n );\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nfunction sameBytes(\n a: Uint8Array | undefined,\n b: Uint8Array | undefined,\n): boolean {\n if (!a || !b || a.length !== b.length) return false;\n return a.every((v, i) => v === b[i]);\n}\n\n/**\n * An OpAMP client for the plain-HTTP transport: it polls, applies the remote\n * config the server offers and reports the result on the next poll. Polling\n * follows the server's heartbeat interval, backs off on errors and honours\n * Retry-After; a 413 is not retried and a 401/403 stops the client.\n */\nexport class OpampHttpClient {\n private uid: Uint8Array;\n private sequenceNum = 0;\n private status: AgentToServer[\"remoteConfigStatus\"];\n private intervalMs: number;\n private backoffMs = 0;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private inFlight: Promise<void> | null = null;\n private stopped = true;\n private lastPollAt = 0;\n private readonly fetchImpl: typeof fetch;\n\n constructor(private readonly options: OpampClientOptions) {\n this.uid = options.instanceUid;\n this.intervalMs = Math.max(\n options.defaultPollIntervalMs ?? 300_000,\n MIN_POLL_INTERVAL_MS,\n );\n this.fetchImpl = options.fetchImpl ?? ((...args) => fetch(...args));\n if (options.appliedConfigHash?.length) {\n this.status = {\n lastRemoteConfigHash: options.appliedConfigHash,\n status: RemoteConfigStatus.Applied,\n };\n }\n }\n\n start(): void {\n if (!this.stopped) return;\n this.stopped = false;\n void this.poll();\n }\n\n stop(): void {\n this.stopped = true;\n if (this.timer !== null) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n\n pollIntervalMs(): number {\n return this.intervalMs;\n }\n\n millisSinceLastPoll(): number {\n return this.lastPollAt === 0 ? Infinity : Date.now() - this.lastPollAt;\n }\n\n /** Polls now unless a poll is running or the client is backing off after an error. */\n poll(): Promise<void> {\n if (this.stopped) return Promise.resolve();\n if (this.inFlight) return this.inFlight;\n if (this.backoffMs > 0 && this.timer !== null) return Promise.resolve();\n if (this.timer !== null) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n this.inFlight = this.exchange().finally(() => {\n this.inFlight = null;\n });\n return this.inFlight;\n }\n\n /** Polls with the current description even if a poll is under way, e.g. right after a targeting attribute changed. */\n async refresh(): Promise<void> {\n if (this.inFlight) await this.inFlight;\n await this.poll();\n }\n\n private schedule(delayMs: number): void {\n if (this.stopped) return;\n if (this.timer !== null) clearTimeout(this.timer);\n this.timer = setTimeout(() => {\n this.timer = null;\n void this.poll();\n }, delayMs);\n }\n\n private async exchange(): Promise<void> {\n const controller = new AbortController();\n const timer = setTimeout(\n () => controller.abort(),\n this.options.requestTimeoutMs ?? 10_000,\n );\n try {\n await this.exchangeWithSignal(controller.signal);\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async exchangeWithSignal(signal: AbortSignal): Promise<void> {\n this.lastPollAt = Date.now();\n let response: Response;\n try {\n response = await this.send(\n {\n instanceUid: this.uid,\n sequenceNum: this.sequenceNum++,\n agentDescription: this.options.describe(),\n capabilities: this.options.capabilities,\n remoteConfigStatus: this.status,\n customCapabilities: this.options.customCapabilities,\n },\n signal,\n );\n } catch {\n this.options.onUnavailable?.();\n this.backOff(null);\n return;\n }\n\n if (\n response.status === 404 ||\n response.status === 405 ||\n response.status === 501\n ) {\n this.stop();\n this.options.onUnsupported?.();\n return;\n }\n if (response.status === 401 || response.status === 403) {\n this.stop();\n this.options.onUnauthorized?.();\n return;\n }\n if (response.status === 413) {\n this.backoffMs = 0;\n this.schedule(this.intervalMs);\n return;\n }\n let message: ServerToAgent | null = null;\n try {\n message = decodeServerToAgent(\n new Uint8Array(await response.arrayBuffer()),\n );\n } catch {\n message = null;\n }\n if (\n response.status === 429 ||\n response.status >= 500 ||\n message?.errorResponse?.type === ServerErrorType.Unavailable\n ) {\n const header = Number(response.headers.get(\"Retry-After\"));\n const retryAfter =\n Number.isFinite(header) && header > 0\n ? header * 1000\n : (message?.errorResponse?.retryAfterMs ?? null);\n this.backOff(retryAfter);\n return;\n }\n if (!response.ok || !message) {\n this.backOff(null);\n return;\n }\n if (this.stopped) return;\n this.backoffMs = 0;\n this.options.onConnected?.();\n this.handle(message);\n }\n\n private handle(message: ServerToAgent): void {\n if (message.newInstanceUid?.length === 16) {\n this.uid = message.newInstanceUid;\n this.options.onInstanceUidChange?.(this.uid);\n }\n if (message.heartbeatIntervalSeconds) {\n const next = Math.max(\n message.heartbeatIntervalSeconds * 1000,\n MIN_POLL_INTERVAL_MS,\n );\n if (next !== this.intervalMs) {\n this.intervalMs = next;\n this.options.onHeartbeatChange?.(message.heartbeatIntervalSeconds);\n }\n }\n\n let reportNow = false;\n if (\n message.remoteConfig &&\n !sameBytes(\n message.remoteConfig.configHash,\n this.status?.lastRemoteConfigHash,\n )\n ) {\n let result: ApplyResult;\n try {\n result = this.options.onRemoteConfig(message.remoteConfig);\n } catch (err) {\n result = {\n applied: false,\n errorMessage: err instanceof Error ? err.message : String(err),\n };\n }\n this.status = result.applied\n ? {\n lastRemoteConfigHash: message.remoteConfig.configHash,\n status: RemoteConfigStatus.Applied,\n }\n : {\n lastRemoteConfigHash: message.remoteConfig.configHash,\n status: RemoteConfigStatus.Failed,\n errorMessage: result.errorMessage,\n };\n reportNow = true;\n }\n // The server answers a poll it cannot evaluate with ReportFullState; this client always sends its full state,\n // so it only needs to poll again. A freshly applied config is reported straight away for the same reason.\n if (\n reportNow ||\n (message.flags & ServerToAgentFlags.ReportFullState) !== 0\n ) {\n this.schedule(0);\n return;\n }\n this.schedule(this.intervalMs);\n }\n\n private backOff(retryAfterMs: number | null): void {\n this.backoffMs =\n retryAfterMs ??\n Math.min(\n this.backoffMs > 0 ? this.backoffMs * 2 : FIRST_BACKOFF_MS,\n MAX_BACKOFF_MS,\n );\n this.schedule(Math.max(this.backoffMs, 1_000));\n }\n\n private send(message: AgentToServer, signal: AbortSignal): Promise<Response> {\n return this.fetchImpl(this.options.endpoint, {\n method: \"POST\",\n signal,\n headers: {\n ...this.options.headers,\n \"Content-Type\": \"application/x-protobuf\",\n \"OpAMP-Instance-UID\": uuidString(this.uid),\n },\n body: encodeAgentToServer(message) as BodyInit,\n });\n }\n}\n"],"mappings":"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","names":["RemoteConfigStatus","ServerErrorType"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,582 @@
1
+ // src/wire.ts
2
+ var WIRE_VARINT = 0;
3
+ var WIRE_FIXED64 = 1;
4
+ var WIRE_LENGTH = 2;
5
+ var WIRE_FIXED32 = 5;
6
+ var encoder = new TextEncoder();
7
+ var decoder = new TextDecoder();
8
+ var Writer = class _Writer {
9
+ chunks = [];
10
+ varint(value) {
11
+ let v = Math.max(0, Math.floor(value));
12
+ while (v >= 128) {
13
+ this.chunks.push(v % 128 | 128);
14
+ v = Math.floor(v / 128);
15
+ }
16
+ this.chunks.push(v);
17
+ return this;
18
+ }
19
+ tag(field, wireType) {
20
+ return this.varint(field * 8 + wireType);
21
+ }
22
+ uint(field, value) {
23
+ if (value === 0) return this;
24
+ return this.tag(field, WIRE_VARINT).varint(value);
25
+ }
26
+ bool(field, value) {
27
+ return value ? this.tag(field, WIRE_VARINT).varint(1) : this;
28
+ }
29
+ bytes(field, value) {
30
+ if (value.length === 0) return this;
31
+ this.tag(field, WIRE_LENGTH).varint(value.length);
32
+ for (const b of value) this.chunks.push(b);
33
+ return this;
34
+ }
35
+ string(field, value) {
36
+ return this.bytes(field, encoder.encode(value));
37
+ }
38
+ double(field, value) {
39
+ if (value === 0) return this;
40
+ const buf = new DataView(new ArrayBuffer(8));
41
+ buf.setFloat64(0, value, true);
42
+ this.tag(field, WIRE_FIXED64);
43
+ for (let i = 0; i < 8; i++) this.chunks.push(buf.getUint8(i));
44
+ return this;
45
+ }
46
+ /** Writes a nested message. An empty message is still written when `always` is set (presence matters). */
47
+ message(field, build, always = false) {
48
+ const inner = new _Writer();
49
+ build(inner);
50
+ const bytes = inner.finish();
51
+ if (bytes.length === 0 && !always) return this;
52
+ this.tag(field, WIRE_LENGTH).varint(bytes.length);
53
+ for (const b of bytes) this.chunks.push(b);
54
+ return this;
55
+ }
56
+ finish() {
57
+ return Uint8Array.from(this.chunks);
58
+ }
59
+ };
60
+ var Reader = class {
61
+ constructor(buf) {
62
+ this.buf = buf;
63
+ }
64
+ buf;
65
+ pos = 0;
66
+ done() {
67
+ return this.pos >= this.buf.length;
68
+ }
69
+ varint() {
70
+ let result = 0;
71
+ let multiplier = 1;
72
+ for (; ; ) {
73
+ if (this.pos >= this.buf.length) throw new Error("truncated varint");
74
+ const byte = this.buf[this.pos++];
75
+ result += (byte & 127) * multiplier;
76
+ if (byte < 128) return result;
77
+ multiplier *= 128;
78
+ if (multiplier > 2 ** 70) throw new Error("varint too long");
79
+ }
80
+ }
81
+ tag() {
82
+ const tag = this.varint();
83
+ return { field: Math.floor(tag / 8), wireType: tag % 8 };
84
+ }
85
+ bytes() {
86
+ const length = this.varint();
87
+ if (this.pos + length > this.buf.length) throw new Error("truncated field");
88
+ const out = this.buf.subarray(this.pos, this.pos + length);
89
+ this.pos += length;
90
+ return out;
91
+ }
92
+ string() {
93
+ return decoder.decode(this.bytes());
94
+ }
95
+ double() {
96
+ if (this.pos + 8 > this.buf.length) throw new Error("truncated double");
97
+ const view = new DataView(this.buf.buffer, this.buf.byteOffset + this.pos, 8);
98
+ this.pos += 8;
99
+ return view.getFloat64(0, true);
100
+ }
101
+ skip(wireType) {
102
+ switch (wireType) {
103
+ case WIRE_VARINT:
104
+ this.varint();
105
+ return;
106
+ case WIRE_FIXED64:
107
+ this.pos += 8;
108
+ return;
109
+ case WIRE_LENGTH:
110
+ this.bytes();
111
+ return;
112
+ case WIRE_FIXED32:
113
+ this.pos += 4;
114
+ return;
115
+ }
116
+ throw new Error(`unsupported wire type ${wireType}`);
117
+ }
118
+ };
119
+
120
+ // src/messages.ts
121
+ var AgentCapabilities = {
122
+ ReportsStatus: 1,
123
+ AcceptsRemoteConfig: 2,
124
+ ReportsEffectiveConfig: 4,
125
+ ReportsHealth: 2048,
126
+ ReportsRemoteConfig: 4096,
127
+ ReportsHeartbeat: 8192
128
+ };
129
+ var AgentToServerFlags = { RequestInstanceUid: 1 };
130
+ var ServerToAgentFlags = { ReportFullState: 1 };
131
+ var RemoteConfigStatus = /* @__PURE__ */ ((RemoteConfigStatus2) => {
132
+ RemoteConfigStatus2[RemoteConfigStatus2["Unset"] = 0] = "Unset";
133
+ RemoteConfigStatus2[RemoteConfigStatus2["Applied"] = 1] = "Applied";
134
+ RemoteConfigStatus2[RemoteConfigStatus2["Applying"] = 2] = "Applying";
135
+ RemoteConfigStatus2[RemoteConfigStatus2["Failed"] = 3] = "Failed";
136
+ return RemoteConfigStatus2;
137
+ })(RemoteConfigStatus || {});
138
+ var ServerErrorType = /* @__PURE__ */ ((ServerErrorType2) => {
139
+ ServerErrorType2[ServerErrorType2["Unknown"] = 0] = "Unknown";
140
+ ServerErrorType2[ServerErrorType2["BadRequest"] = 1] = "BadRequest";
141
+ ServerErrorType2[ServerErrorType2["Unavailable"] = 2] = "Unavailable";
142
+ return ServerErrorType2;
143
+ })(ServerErrorType || {});
144
+ function writeAnyValue(w, value) {
145
+ if (typeof value === "string") {
146
+ w.string(1, value);
147
+ } else if (typeof value === "boolean") {
148
+ w.bool(2, value);
149
+ } else if (typeof value === "number") {
150
+ if (Number.isInteger(value) && value >= 0) {
151
+ if (value !== 0) w.tag(3, WIRE_VARINT).varint(value);
152
+ } else {
153
+ w.double(4, value);
154
+ }
155
+ } else {
156
+ w.message(5, (array) => {
157
+ for (const item of value) array.message(1, (v) => v.string(1, item), true);
158
+ });
159
+ }
160
+ }
161
+ function writeAttributes(w, field, attrs) {
162
+ for (const [key, value] of Object.entries(attrs)) {
163
+ w.message(field, (kv) => {
164
+ kv.string(1, key);
165
+ kv.message(2, (v) => writeAnyValue(v, value), true);
166
+ });
167
+ }
168
+ }
169
+ function encodeAgentToServer(msg) {
170
+ const w = new Writer();
171
+ w.bytes(1, msg.instanceUid);
172
+ w.uint(2, msg.sequenceNum);
173
+ if (msg.agentDescription) {
174
+ const description = msg.agentDescription;
175
+ w.message(3, (d) => {
176
+ writeAttributes(d, 1, description.identifying);
177
+ writeAttributes(d, 2, description.nonIdentifying);
178
+ });
179
+ }
180
+ w.uint(4, msg.capabilities);
181
+ if (msg.remoteConfigStatus) {
182
+ const status = msg.remoteConfigStatus;
183
+ w.message(7, (s) => {
184
+ s.bytes(1, status.lastRemoteConfigHash);
185
+ s.uint(2, status.status);
186
+ if (status.errorMessage) s.string(3, status.errorMessage);
187
+ });
188
+ }
189
+ if (msg.agentDisconnect) w.message(9, () => {
190
+ }, true);
191
+ w.uint(10, msg.flags ?? 0);
192
+ if (msg.customCapabilities?.length) {
193
+ const capabilities = msg.customCapabilities;
194
+ w.message(12, (c) => {
195
+ for (const capability of capabilities) c.string(1, capability);
196
+ });
197
+ }
198
+ return w.finish();
199
+ }
200
+ function each(buf, handle) {
201
+ const r = new Reader(buf);
202
+ while (!r.done()) {
203
+ const { field, wireType } = r.tag();
204
+ if (!handle(field, wireType, r)) r.skip(wireType);
205
+ }
206
+ }
207
+ function decodeConfigObject(buf) {
208
+ const object = { body: new Uint8Array(), contentType: "" };
209
+ each(buf, (field, wireType, r) => {
210
+ if (wireType !== WIRE_LENGTH) return false;
211
+ if (field === 1) object.body = r.bytes().slice();
212
+ else if (field === 2) object.contentType = r.string();
213
+ else return false;
214
+ return true;
215
+ });
216
+ return object;
217
+ }
218
+ function decodeRemoteConfig(buf) {
219
+ const config = { configMap: {}, configHash: new Uint8Array() };
220
+ each(buf, (field, wireType, r) => {
221
+ if (wireType !== WIRE_LENGTH) return false;
222
+ if (field === 2) {
223
+ config.configHash = r.bytes().slice();
224
+ return true;
225
+ }
226
+ if (field !== 1) return false;
227
+ each(r.bytes(), (mapField, mapWire, mapReader) => {
228
+ if (mapField !== 1 || mapWire !== WIRE_LENGTH) return false;
229
+ let key = "";
230
+ let value = { body: new Uint8Array(), contentType: "" };
231
+ each(mapReader.bytes(), (entryField, entryWire, entryReader) => {
232
+ if (entryWire !== WIRE_LENGTH) return false;
233
+ if (entryField === 1) key = entryReader.string();
234
+ else if (entryField === 2) value = decodeConfigObject(entryReader.bytes());
235
+ else return false;
236
+ return true;
237
+ });
238
+ config.configMap[key] = value;
239
+ return true;
240
+ });
241
+ return true;
242
+ });
243
+ return config;
244
+ }
245
+ function decodeServerToAgent(buf) {
246
+ const msg = { flags: 0, capabilities: 0 };
247
+ each(buf, (field, wireType, r) => {
248
+ switch (field) {
249
+ case 1:
250
+ if (wireType !== WIRE_LENGTH) return false;
251
+ msg.instanceUid = r.bytes().slice();
252
+ return true;
253
+ case 2: {
254
+ if (wireType !== WIRE_LENGTH) return false;
255
+ const error = { type: 0 /* Unknown */, message: "" };
256
+ each(r.bytes(), (f, w, er) => {
257
+ if (f === 1 && w === WIRE_VARINT) error.type = er.varint();
258
+ else if (f === 2 && w === WIRE_LENGTH) error.message = er.string();
259
+ else if (f === 3 && w === WIRE_LENGTH) {
260
+ each(er.bytes(), (rf, rw, rr) => {
261
+ if (rf !== 1 || rw !== WIRE_VARINT) return false;
262
+ error.retryAfterMs = rr.varint() / 1e6;
263
+ return true;
264
+ });
265
+ } else return false;
266
+ return true;
267
+ });
268
+ msg.errorResponse = error;
269
+ return true;
270
+ }
271
+ case 3:
272
+ if (wireType !== WIRE_LENGTH) return false;
273
+ msg.remoteConfig = decodeRemoteConfig(r.bytes());
274
+ return true;
275
+ case 4:
276
+ if (wireType !== WIRE_LENGTH) return false;
277
+ each(r.bytes(), (f, w, cr) => {
278
+ if (f !== 2 || w !== WIRE_LENGTH) return false;
279
+ each(cr.bytes(), (of, ow, or) => {
280
+ if (of !== 4 || ow !== WIRE_VARINT) return false;
281
+ msg.heartbeatIntervalSeconds = or.varint();
282
+ return true;
283
+ });
284
+ return true;
285
+ });
286
+ return true;
287
+ case 6:
288
+ if (wireType !== WIRE_VARINT) return false;
289
+ msg.flags = r.varint();
290
+ return true;
291
+ case 7:
292
+ if (wireType !== WIRE_VARINT) return false;
293
+ msg.capabilities = r.varint();
294
+ return true;
295
+ case 8:
296
+ if (wireType !== WIRE_LENGTH) return false;
297
+ each(r.bytes(), (f, w, ir) => {
298
+ if (f !== 1 || w !== WIRE_LENGTH) return false;
299
+ msg.newInstanceUid = ir.bytes().slice();
300
+ return true;
301
+ });
302
+ return true;
303
+ case 11: {
304
+ if (wireType !== WIRE_LENGTH) return false;
305
+ const custom = { capability: "", type: "", data: new Uint8Array() };
306
+ each(r.bytes(), (f, w, cr) => {
307
+ if (w !== WIRE_LENGTH) return false;
308
+ if (f === 1) custom.capability = cr.string();
309
+ else if (f === 2) custom.type = cr.string();
310
+ else if (f === 3) custom.data = cr.bytes().slice();
311
+ else return false;
312
+ return true;
313
+ });
314
+ msg.customMessage = custom;
315
+ return true;
316
+ }
317
+ }
318
+ return false;
319
+ });
320
+ return msg;
321
+ }
322
+ function encodeServerToAgent(msg) {
323
+ const w = new Writer();
324
+ if (msg.instanceUid) w.bytes(1, msg.instanceUid);
325
+ if (msg.remoteConfig) {
326
+ const config = msg.remoteConfig;
327
+ w.message(3, (rc) => {
328
+ rc.message(1, (map) => {
329
+ for (const [key, object] of Object.entries(config.configMap)) {
330
+ map.message(1, (entry) => {
331
+ entry.string(1, key);
332
+ entry.message(2, (o) => o.bytes(1, object.body).string(2, object.contentType), true);
333
+ });
334
+ }
335
+ });
336
+ rc.bytes(2, config.configHash);
337
+ });
338
+ }
339
+ if (msg.heartbeatIntervalSeconds) {
340
+ const seconds = msg.heartbeatIntervalSeconds;
341
+ w.message(4, (cs) => cs.message(2, (o) => o.uint(4, seconds)));
342
+ }
343
+ w.uint(6, msg.flags);
344
+ w.uint(7, msg.capabilities);
345
+ if (msg.newInstanceUid) w.message(8, (id) => id.bytes(1, msg.newInstanceUid));
346
+ return w.finish();
347
+ }
348
+
349
+ // src/client.ts
350
+ var MIN_POLL_INTERVAL_MS = 3e4;
351
+ var MAX_BACKOFF_MS = 30 * 6e4;
352
+ var FIRST_BACKOFF_MS = 3e4;
353
+ function uuidString(bytes) {
354
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join(
355
+ ""
356
+ );
357
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
358
+ }
359
+ function sameBytes(a, b) {
360
+ if (!a || !b || a.length !== b.length) return false;
361
+ return a.every((v, i) => v === b[i]);
362
+ }
363
+ var OpampHttpClient = class {
364
+ constructor(options) {
365
+ this.options = options;
366
+ this.uid = options.instanceUid;
367
+ this.intervalMs = Math.max(
368
+ options.defaultPollIntervalMs ?? 3e5,
369
+ MIN_POLL_INTERVAL_MS
370
+ );
371
+ this.fetchImpl = options.fetchImpl ?? ((...args) => fetch(...args));
372
+ if (options.appliedConfigHash?.length) {
373
+ this.status = {
374
+ lastRemoteConfigHash: options.appliedConfigHash,
375
+ status: 1 /* Applied */
376
+ };
377
+ }
378
+ }
379
+ options;
380
+ uid;
381
+ sequenceNum = 0;
382
+ status;
383
+ intervalMs;
384
+ backoffMs = 0;
385
+ timer = null;
386
+ inFlight = null;
387
+ stopped = true;
388
+ lastPollAt = 0;
389
+ fetchImpl;
390
+ start() {
391
+ if (!this.stopped) return;
392
+ this.stopped = false;
393
+ void this.poll();
394
+ }
395
+ stop() {
396
+ this.stopped = true;
397
+ if (this.timer !== null) {
398
+ clearTimeout(this.timer);
399
+ this.timer = null;
400
+ }
401
+ }
402
+ pollIntervalMs() {
403
+ return this.intervalMs;
404
+ }
405
+ millisSinceLastPoll() {
406
+ return this.lastPollAt === 0 ? Infinity : Date.now() - this.lastPollAt;
407
+ }
408
+ /** Polls now unless a poll is running or the client is backing off after an error. */
409
+ poll() {
410
+ if (this.stopped) return Promise.resolve();
411
+ if (this.inFlight) return this.inFlight;
412
+ if (this.backoffMs > 0 && this.timer !== null) return Promise.resolve();
413
+ if (this.timer !== null) {
414
+ clearTimeout(this.timer);
415
+ this.timer = null;
416
+ }
417
+ this.inFlight = this.exchange().finally(() => {
418
+ this.inFlight = null;
419
+ });
420
+ return this.inFlight;
421
+ }
422
+ /** Polls with the current description even if a poll is under way, e.g. right after a targeting attribute changed. */
423
+ async refresh() {
424
+ if (this.inFlight) await this.inFlight;
425
+ await this.poll();
426
+ }
427
+ schedule(delayMs) {
428
+ if (this.stopped) return;
429
+ if (this.timer !== null) clearTimeout(this.timer);
430
+ this.timer = setTimeout(() => {
431
+ this.timer = null;
432
+ void this.poll();
433
+ }, delayMs);
434
+ }
435
+ async exchange() {
436
+ const controller = new AbortController();
437
+ const timer = setTimeout(
438
+ () => controller.abort(),
439
+ this.options.requestTimeoutMs ?? 1e4
440
+ );
441
+ try {
442
+ await this.exchangeWithSignal(controller.signal);
443
+ } finally {
444
+ clearTimeout(timer);
445
+ }
446
+ }
447
+ async exchangeWithSignal(signal) {
448
+ this.lastPollAt = Date.now();
449
+ let response;
450
+ try {
451
+ response = await this.send(
452
+ {
453
+ instanceUid: this.uid,
454
+ sequenceNum: this.sequenceNum++,
455
+ agentDescription: this.options.describe(),
456
+ capabilities: this.options.capabilities,
457
+ remoteConfigStatus: this.status,
458
+ customCapabilities: this.options.customCapabilities
459
+ },
460
+ signal
461
+ );
462
+ } catch {
463
+ this.options.onUnavailable?.();
464
+ this.backOff(null);
465
+ return;
466
+ }
467
+ if (response.status === 404 || response.status === 405 || response.status === 501) {
468
+ this.stop();
469
+ this.options.onUnsupported?.();
470
+ return;
471
+ }
472
+ if (response.status === 401 || response.status === 403) {
473
+ this.stop();
474
+ this.options.onUnauthorized?.();
475
+ return;
476
+ }
477
+ if (response.status === 413) {
478
+ this.backoffMs = 0;
479
+ this.schedule(this.intervalMs);
480
+ return;
481
+ }
482
+ let message = null;
483
+ try {
484
+ message = decodeServerToAgent(
485
+ new Uint8Array(await response.arrayBuffer())
486
+ );
487
+ } catch {
488
+ message = null;
489
+ }
490
+ if (response.status === 429 || response.status >= 500 || message?.errorResponse?.type === 2 /* Unavailable */) {
491
+ const header = Number(response.headers.get("Retry-After"));
492
+ const retryAfter = Number.isFinite(header) && header > 0 ? header * 1e3 : message?.errorResponse?.retryAfterMs ?? null;
493
+ this.backOff(retryAfter);
494
+ return;
495
+ }
496
+ if (!response.ok || !message) {
497
+ this.backOff(null);
498
+ return;
499
+ }
500
+ if (this.stopped) return;
501
+ this.backoffMs = 0;
502
+ this.options.onConnected?.();
503
+ this.handle(message);
504
+ }
505
+ handle(message) {
506
+ if (message.newInstanceUid?.length === 16) {
507
+ this.uid = message.newInstanceUid;
508
+ this.options.onInstanceUidChange?.(this.uid);
509
+ }
510
+ if (message.heartbeatIntervalSeconds) {
511
+ const next = Math.max(
512
+ message.heartbeatIntervalSeconds * 1e3,
513
+ MIN_POLL_INTERVAL_MS
514
+ );
515
+ if (next !== this.intervalMs) {
516
+ this.intervalMs = next;
517
+ this.options.onHeartbeatChange?.(message.heartbeatIntervalSeconds);
518
+ }
519
+ }
520
+ let reportNow = false;
521
+ if (message.remoteConfig && !sameBytes(
522
+ message.remoteConfig.configHash,
523
+ this.status?.lastRemoteConfigHash
524
+ )) {
525
+ let result;
526
+ try {
527
+ result = this.options.onRemoteConfig(message.remoteConfig);
528
+ } catch (err) {
529
+ result = {
530
+ applied: false,
531
+ errorMessage: err instanceof Error ? err.message : String(err)
532
+ };
533
+ }
534
+ this.status = result.applied ? {
535
+ lastRemoteConfigHash: message.remoteConfig.configHash,
536
+ status: 1 /* Applied */
537
+ } : {
538
+ lastRemoteConfigHash: message.remoteConfig.configHash,
539
+ status: 3 /* Failed */,
540
+ errorMessage: result.errorMessage
541
+ };
542
+ reportNow = true;
543
+ }
544
+ if (reportNow || (message.flags & ServerToAgentFlags.ReportFullState) !== 0) {
545
+ this.schedule(0);
546
+ return;
547
+ }
548
+ this.schedule(this.intervalMs);
549
+ }
550
+ backOff(retryAfterMs) {
551
+ this.backoffMs = retryAfterMs ?? Math.min(
552
+ this.backoffMs > 0 ? this.backoffMs * 2 : FIRST_BACKOFF_MS,
553
+ MAX_BACKOFF_MS
554
+ );
555
+ this.schedule(Math.max(this.backoffMs, 1e3));
556
+ }
557
+ send(message, signal) {
558
+ return this.fetchImpl(this.options.endpoint, {
559
+ method: "POST",
560
+ signal,
561
+ headers: {
562
+ ...this.options.headers,
563
+ "Content-Type": "application/x-protobuf",
564
+ "OpAMP-Instance-UID": uuidString(this.uid)
565
+ },
566
+ body: encodeAgentToServer(message)
567
+ });
568
+ }
569
+ };
570
+ export {
571
+ AgentCapabilities,
572
+ AgentToServerFlags,
573
+ OpampHttpClient,
574
+ RemoteConfigStatus,
575
+ ServerErrorType,
576
+ ServerToAgentFlags,
577
+ decodeServerToAgent,
578
+ encodeAgentToServer,
579
+ encodeServerToAgent,
580
+ uuidString
581
+ };
582
+ //# sourceMappingURL=index.mjs.map