@datadog/apps-frontend 0.0.6 → 0.0.7

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.
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/embedding/react/provider.ts", "../../../src/embedding/handshake/origins.ts", "../../../src/embedding/handshake/bootstrap.ts", "../../../src/embedding/handshake/compatibility.ts", "../../../src/embedding/protocol/establish.ts", "../../../src/embedding/protocol/heartbeat.ts", "../../../src/embedding/protocol/validation.ts", "../../../src/embedding/protocol/wire-errors.ts", "../../../src/embedding/protocol/endpoint.ts", "../../../src/embedding/connection.ts", "../../../src/embedding/errors.ts", "../../../src/embedding/runtime.ts"],
4
- "sourcesContent": ["import { createElement, useEffect, useState } from 'react';\nimport type { ComponentType, PropsWithChildren, ReactElement } from 'react';\n\nimport { browserAppEmbedding } from '../connection';\nimport { createAppEmbedding } from '../runtime';\n\nimport type { DatadogAppProviderModule } from './config';\nimport { installDatadogAppProviderModules } from './config';\nimport { createDatadogAppProvider } from './context';\n\nconst embedding = createAppEmbedding(browserAppEmbedding);\nconst EmbeddingProvider = createDatadogAppProvider(embedding);\n\nexport interface DatadogAppProviderProps extends PropsWithChildren {\n /**\n * Capability modules to install on this mount, in list order. Read once\n * per mount: modules are startup configuration, so a later change to\n * this prop is ignored -- remount the provider to change modules. (The\n * common inline form, `modules={[resizing(...)]}`, builds a fresh array\n * every render; installs deliberately do not track it.)\n */\n readonly modules?: readonly DatadogAppProviderModule[];\n}\n\nconst NO_MODULES: readonly DatadogAppProviderModule[] = Object.freeze([]);\n\n/**\n * Owns the shared embedding connection and installs capability modules.\n *\n * On each mount, every listed module's `install` runs once, in list order,\n * receiving the shared connection and this mount's dispose signal (aborted on\n * unmount, so modules clean up). A failing install is reported and isolated;\n * the remaining modules and the app still run. Installs happen after this\n * provider's children have mounted, and modules have no render rights, so no\n * child can observe module state during its own mount.\n *\n * Sibling mounts (independent subtrees, each with its own\n * `DatadogAppProvider`) are supported: every mount from the same loaded\n * copy of this package shares one underlying embedding connection\n * (ref-counted -- the wire connection opens on the first mount and closes on\n * the last unmount) and one `ClaimStore` per contract (claims for the same\n * contract are never duplicated on the wire), while each mount installs its\n * own `modules` independently, each module receiving its own mount's dispose\n * signal.\n *\n * Nesting one `DatadogAppProvider` inside another's subtree is NOT\n * supported and should be avoided. The connection/claim sharing above still\n * holds, but there is no cross-provider dedup of modules: a module installed\n * by both providers installs -- and its effects run -- once per provider.\n */\nexport const DatadogAppProvider: ComponentType<DatadogAppProviderProps> = ({\n children,\n modules = NO_MODULES,\n}: DatadogAppProviderProps): ReactElement => {\n // Mount-time snapshot: installs run once per mount (StrictMode aside),\n // not once per modules-prop identity.\n const [mountedModules] = useState(() => modules);\n useEffect(() => {\n const controller = new AbortController();\n installDatadogAppProviderModules(\n mountedModules,\n embedding,\n controller.signal,\n );\n return () => controller.abort();\n }, [mountedModules]);\n return createElement(EmbeddingProvider, null, children);\n};\n", "// TODO: keep in sync with the canonical Datadog site-domain list; consider\n// generating this allowlist from that source instead of hardcoding it here.\nconst DATADOG_PRODUCTION_ORIGIN =\n /^https:\\/\\/(?:[a-zA-Z0-9-]+\\.)*(?:datadoghq\\.(?:com|eu)|ddog-gov\\.com)$/;\nconst DATADOG_INTERNAL_ORIGIN =\n /^https:\\/\\/(?:[a-zA-Z0-9-]+\\.)*(?:datad0g\\.com|datad0g\\.eu|staging\\.dog|prod\\.dog)$/;\nconst LOCAL_ORIGIN = /^https?:\\/\\/(?:localhost|127\\.0\\.0\\.1)(?::\\d+)?$/;\n\nexport function isDatadogHostOrigin(origin: string): boolean {\n return (\n DATADOG_PRODUCTION_ORIGIN.test(origin) ||\n DATADOG_INTERNAL_ORIGIN.test(origin) ||\n LOCAL_ORIGIN.test(origin)\n );\n}\n", "/**\n * Permanent bootstrap: phase 1 of the embedding connection.\n *\n * This exchange transfers a private control port across the window boundary\n * and nothing else. It is deliberately independent of any operational\n * protocol: an app bundle uploaded today may later meet a host that has\n * retired the operational protocol it speaks, and this hop has to keep working\n * long enough to reach the compatibility prelude, which tells that app to\n * update instead of leaving it to infer failure from a timeout.\n *\n * This exchange is frozen. Changes here are wire-compatibility changes.\n */\n\nimport { BOOTSTRAP_TIMEOUT_MS } from '../config';\nimport {\n createId,\n err,\n isRecord,\n isValidIdentifier,\n success,\n teardown,\n} from '../shared';\nimport type { ConnectError, Result } from '../types';\n\nimport { isDatadogHostOrigin } from './origins';\n\nconst BOOTSTRAP_NAMESPACE = 'dd-apps-frontend-bootstrap';\nconst BOOTSTRAP_VERSION = 1;\n\ntype BootstrapEvent = Readonly<{\n source: MessageEventSource | null;\n origin: string;\n data: unknown;\n ports: readonly MessagePort[];\n}>;\n\nexport type BootstrapRequest = Readonly<{\n attemptId: string;\n documentId: string;\n controlPort: MessagePort;\n}>;\n\ntype BootstrapAcknowledgement =\n | Readonly<{ status: 'accepted' }>\n | Readonly<{ status: 'rejected-origin'; origin: string }>\n | Readonly<{ status: 'ignored' }>;\n\nfunction extractBootstrapRequest(\n expectedSource: Window,\n event: BootstrapEvent,\n): BootstrapRequest | undefined {\n const { data } = event;\n const [controlPort] = event.ports;\n if (\n event.source !== expectedSource ||\n event.ports.length !== 1 ||\n controlPort === undefined ||\n !isRecord(data) ||\n data.namespace !== BOOTSTRAP_NAMESPACE ||\n data.version !== BOOTSTRAP_VERSION ||\n data.type !== 'request' ||\n !isValidIdentifier(data.attemptId) ||\n !isValidIdentifier(data.documentId)\n ) {\n return undefined;\n }\n return {\n attemptId: data.attemptId,\n documentId: data.documentId,\n controlPort,\n };\n}\n\nexport function acceptHostBootstrapRequest(\n expectedSource: Window,\n expectedOrigin: string,\n event: MessageEvent<unknown>,\n allowOpaqueOrigin = false,\n): Result<BootstrapRequest, ConnectError> | undefined {\n const request = extractBootstrapRequest(expectedSource, event);\n if (!request) {\n return undefined;\n }\n const originAccepted =\n event.origin === 'null'\n ? allowOpaqueOrigin\n : event.origin === expectedOrigin;\n if (!originAccepted) {\n teardown('origin-rejection acknowledgement', () =>\n expectedSource.postMessage(\n {\n namespace: BOOTSTRAP_NAMESPACE,\n version: BOOTSTRAP_VERSION,\n type: 'rejected-origin',\n attemptId: request.attemptId,\n origin: event.origin,\n },\n event.origin === 'null' ? '*' : event.origin,\n ),\n );\n teardown('origin-rejected host bootstrap port', () =>\n request.controlPort.close(),\n );\n return err({ code: 'ORIGIN_REJECTED', origin: event.origin });\n }\n try {\n expectedSource.postMessage(\n {\n namespace: BOOTSTRAP_NAMESPACE,\n version: BOOTSTRAP_VERSION,\n type: 'accepted',\n attemptId: request.attemptId,\n },\n event.origin === 'null' ? '*' : event.origin,\n );\n return success(request);\n } catch (cause) {\n teardown('rejected host bootstrap port', () =>\n request.controlPort.close(),\n );\n return err({ code: 'TRANSPORT_FAILED', cause });\n }\n}\n\nfunction inspectBootstrapAcknowledgement(\n expectedSource: Window,\n expectedAttemptId: string,\n event: BootstrapEvent,\n): BootstrapAcknowledgement {\n const { data } = event;\n if (\n event.source !== expectedSource ||\n event.ports.length !== 0 ||\n !isRecord(data) ||\n data.namespace !== BOOTSTRAP_NAMESPACE ||\n data.version !== BOOTSTRAP_VERSION ||\n (data.type !== 'accepted' && data.type !== 'rejected-origin') ||\n data.attemptId !== expectedAttemptId\n ) {\n return { status: 'ignored' };\n }\n if (!isDatadogHostOrigin(event.origin)) {\n return { status: 'rejected-origin', origin: event.origin };\n }\n if (data.type === 'rejected-origin') {\n return typeof data.origin === 'string'\n ? { status: 'rejected-origin', origin: data.origin }\n : { status: 'ignored' };\n }\n return { status: 'accepted' };\n}\n\n// The wildcard window hop transfers only a control port. Exact parent, origin,\n// request identity and port-count checks precede operational traffic.\nexport function requestBootstrapControlPort(\n appWindow: Window,\n documentId: string,\n signal: AbortSignal,\n timeoutMs: number = BOOTSTRAP_TIMEOUT_MS,\n): Promise<Result<MessagePort, ConnectError>> {\n if (signal.aborted) {\n return Promise.resolve(err({ code: 'ABORTED' }));\n }\n const hostWindow = appWindow.parent;\n if (hostWindow === appWindow) {\n return Promise.resolve(\n err({\n code: 'TRANSPORT_FAILED',\n cause: new Error('The app is not running in an iframe.'),\n }),\n );\n }\n const attemptId = createId('bootstrap');\n const control = new MessageChannel();\n return new Promise((resolve) => {\n let settled = false;\n let transferred = false;\n let posted = false;\n let timer: ReturnType<typeof globalThis.setTimeout> | undefined;\n const finish = (result: Result<MessagePort, ConnectError>) => {\n if (settled) {\n return;\n }\n settled = true;\n appWindow.removeEventListener('message', onMessage);\n signal.removeEventListener('abort', onAbort);\n if (timer !== undefined) {\n globalThis.clearTimeout(timer);\n }\n if (!result.ok) {\n teardown('failed app bootstrap port', () =>\n control.port1.close(),\n );\n if (!transferred) {\n teardown('untransferred app bootstrap port', () =>\n control.port2.close(),\n );\n }\n }\n resolve(result);\n };\n const onMessage = (event: MessageEvent<unknown>) => {\n const inspected = inspectBootstrapAcknowledgement(\n hostWindow,\n attemptId,\n event,\n );\n if (inspected.status === 'accepted') {\n finish(success(control.port1));\n } else if (inspected.status === 'rejected-origin') {\n finish(\n err({\n code: 'ORIGIN_REJECTED',\n origin: inspected.origin,\n }),\n );\n }\n };\n const onAbort = () => finish(err({ code: 'ABORTED' }));\n const postRequest = () => {\n if (posted || settled) {\n return;\n }\n posted = true;\n timer = globalThis.setTimeout(\n () => finish(err({ code: 'TIMED_OUT', timeoutMs })),\n Math.max(0, timeoutMs),\n );\n try {\n hostWindow.postMessage(\n {\n namespace: BOOTSTRAP_NAMESPACE,\n version: BOOTSTRAP_VERSION,\n type: 'request',\n attemptId,\n documentId,\n },\n '*',\n [control.port2],\n );\n transferred = true;\n } catch (cause) {\n finish(err({ code: 'TRANSPORT_FAILED', cause }));\n }\n };\n\n appWindow.addEventListener('message', onMessage);\n signal.addEventListener('abort', onAbort, { once: true });\n if (signal.aborted) {\n onAbort();\n return;\n }\n postRequest();\n });\n}\n\n/**\n * Stable for the lifetime of this document and regenerated by its successor.\n * The frozen bootstrap envelope retains this identity for wire compatibility;\n * operational session lifetime is determined by the private port itself.\n */\nexport const APP_DOCUMENT_ID: string = createId('document');\n", "import { isRecord } from '../shared';\nimport type { ConnectError, ErrorOf, Result } from '../types';\n\n/**\n * The compatibility prelude remains compatible across operational protocol\n * versions so incompatible peers can report a version mismatch instead of\n * timing out.\n */\nconst COMPATIBILITY_NAMESPACE = 'dd-apps-frontend-compatibility';\nconst COMPATIBILITY_PRELUDE_VERSION = 1;\n// Bounds the peer-controlled list before it reaches Math.min/Math.max, which\n// throw RangeError on a large-enough spread argument.\nconst MAX_SUPPORTED_PROTOCOLS = 64;\n\ntype ProtocolCompatibilityError = ErrorOf<\n 'APP_PROTOCOL_TOO_OLD' | 'HOST_PROTOCOL_TOO_OLD' | 'PROTOCOL_INCOMPATIBLE'\n>;\n\ntype NegotiatedProtocol = Readonly<{\n protocol: number;\n operationalPort: MessagePort;\n}>;\n\ntype ControlMessageEvent = Readonly<{\n data: unknown;\n ports: readonly MessagePort[];\n}>;\n\nfunction nextControlMessage(\n port: MessagePort,\n timeoutMs: number,\n signal: AbortSignal,\n afterListening?: () => void,\n): Promise<Result<ControlMessageEvent, ConnectError>> {\n if (signal.aborted) {\n return Promise.resolve({ ok: false, error: { code: 'ABORTED' } });\n }\n return new Promise((resolve) => {\n let settled = false;\n let timer: ReturnType<typeof globalThis.setTimeout> | undefined;\n const finish = (result: Result<ControlMessageEvent, ConnectError>) => {\n if (settled) {\n return;\n }\n settled = true;\n port.removeEventListener('message', onMessage);\n signal.removeEventListener('abort', onAbort);\n if (timer !== undefined) {\n globalThis.clearTimeout(timer);\n }\n resolve(result);\n };\n const onMessage = (event: MessageEvent<unknown>) =>\n finish({ ok: true, value: event });\n const onAbort = () => finish({ ok: false, error: { code: 'ABORTED' } });\n\n port.addEventListener('message', onMessage);\n signal.addEventListener('abort', onAbort, { once: true });\n timer = globalThis.setTimeout(\n () =>\n finish({\n ok: false,\n error: { code: 'TIMED_OUT', timeoutMs },\n }),\n Math.max(0, timeoutMs),\n );\n try {\n port.start();\n afterListening?.();\n } catch (cause) {\n finish({\n ok: false,\n error: { code: 'TRANSPORT_FAILED', cause },\n });\n }\n });\n}\n\nfunction parseSupportedProtocols(\n value: unknown,\n): readonly number[] | undefined {\n if (\n !Array.isArray(value) ||\n value.length === 0 ||\n value.length > MAX_SUPPORTED_PROTOCOLS ||\n !Array.from(value).every(\n (protocol) => Number.isSafeInteger(protocol) && protocol > 0,\n ) ||\n new Set(value).size !== value.length\n ) {\n return undefined;\n }\n return [...value].sort((left, right) => left - right);\n}\n\nfunction negotiateProtocols(\n appProtocols: readonly number[],\n hostProtocols: readonly number[],\n): Result<number, ProtocolCompatibilityError> {\n const common = appProtocols.filter((version) =>\n hostProtocols.includes(version),\n );\n if (common.length > 0) {\n return { ok: true, value: Math.max(...common) };\n }\n\n const oldestApp = Math.min(...appProtocols);\n const newestApp = Math.max(...appProtocols);\n const oldestHost = Math.min(...hostProtocols);\n const newestHost = Math.max(...hostProtocols);\n\n if (newestApp < oldestHost) {\n return {\n ok: false,\n error: {\n code: 'APP_PROTOCOL_TOO_OLD',\n appProtocols,\n hostProtocols,\n },\n };\n }\n if (newestHost < oldestApp) {\n return {\n ok: false,\n error: {\n code: 'HOST_PROTOCOL_TOO_OLD',\n appProtocols,\n hostProtocols,\n },\n };\n }\n return {\n ok: false,\n error: {\n code: 'PROTOCOL_INCOMPATIBLE',\n appProtocols,\n hostProtocols,\n },\n };\n}\n\nexport async function negotiateAppProtocol(\n controlPort: MessagePort,\n supportedProtocols: readonly number[],\n timeoutMs: number,\n signal: AbortSignal,\n): Promise<Result<NegotiatedProtocol, ConnectError>> {\n const appProtocols = parseSupportedProtocols(supportedProtocols);\n if (!appProtocols) {\n controlPort.close();\n return {\n ok: false,\n error: {\n code: 'TRANSPORT_FAILED',\n cause: new Error('The app protocol registry is invalid.'),\n },\n };\n }\n const answer = await nextControlMessage(\n controlPort,\n timeoutMs,\n signal,\n () => {\n controlPort.postMessage({\n namespace: COMPATIBILITY_NAMESPACE,\n version: COMPATIBILITY_PRELUDE_VERSION,\n type: 'offer',\n role: 'app',\n protocols: appProtocols,\n });\n },\n );\n controlPort.close();\n if (!answer.ok) {\n return answer;\n }\n const { data, ports } = answer.value;\n if (\n !isRecord(data) ||\n data.namespace !== COMPATIBILITY_NAMESPACE ||\n data.version !== COMPATIBILITY_PRELUDE_VERSION ||\n data.type !== 'answer' ||\n data.role !== 'host'\n ) {\n for (const port of ports) {\n port.close();\n }\n return {\n ok: false,\n error: {\n code: 'TRANSPORT_FAILED',\n cause: new Error(\n 'The host returned an invalid compatibility answer.',\n ),\n },\n };\n }\n const hostProtocols = parseSupportedProtocols(data.protocols);\n if (!hostProtocols) {\n for (const port of ports) {\n port.close();\n }\n return {\n ok: false,\n error: {\n code: 'TRANSPORT_FAILED',\n cause: new Error(\n 'The host returned an invalid supported-protocol list.',\n ),\n },\n };\n }\n const negotiated = negotiateProtocols(appProtocols, hostProtocols);\n if (!negotiated.ok) {\n for (const port of ports) {\n port.close();\n }\n return negotiated;\n }\n const [operationalPort] = ports;\n if (ports.length !== 1 || operationalPort === undefined) {\n for (const port of ports) {\n port.close();\n }\n return {\n ok: false,\n error: {\n code: 'TRANSPORT_FAILED',\n cause: new Error(\n 'A compatible host must transfer exactly one operational port.',\n ),\n },\n };\n }\n return {\n ok: true,\n value: {\n protocol: negotiated.value,\n operationalPort,\n },\n };\n}\n\nexport async function negotiateHostProtocol(\n controlPort: MessagePort,\n supportedProtocols: readonly number[],\n timeoutMs: number,\n signal: AbortSignal,\n createChannel: () => Readonly<{\n port1: MessagePort;\n port2: MessagePort;\n }> = () => new MessageChannel(),\n): Promise<Result<NegotiatedProtocol, ConnectError>> {\n const hostProtocols = parseSupportedProtocols(supportedProtocols);\n if (!hostProtocols) {\n controlPort.close();\n return {\n ok: false,\n error: {\n code: 'TRANSPORT_FAILED',\n cause: new Error('The host protocol registry is invalid.'),\n },\n };\n }\n const offer = await nextControlMessage(controlPort, timeoutMs, signal);\n if (!offer.ok) {\n controlPort.close();\n return offer;\n }\n const { data, ports } = offer.value;\n if (\n ports.length !== 0 ||\n !isRecord(data) ||\n data.namespace !== COMPATIBILITY_NAMESPACE ||\n data.version !== COMPATIBILITY_PRELUDE_VERSION ||\n data.type !== 'offer' ||\n data.role !== 'app'\n ) {\n for (const port of ports) {\n port.close();\n }\n controlPort.close();\n return {\n ok: false,\n error: {\n code: 'TRANSPORT_FAILED',\n cause: new Error(\n 'The app sent an invalid compatibility offer.',\n ),\n },\n };\n }\n const appProtocols = parseSupportedProtocols(data.protocols);\n if (!appProtocols) {\n controlPort.close();\n return {\n ok: false,\n error: {\n code: 'TRANSPORT_FAILED',\n cause: new Error(\n 'The app sent an invalid supported-protocol list.',\n ),\n },\n };\n }\n const negotiated = negotiateProtocols(appProtocols, hostProtocols);\n if (!negotiated.ok) {\n try {\n controlPort.postMessage({\n namespace: COMPATIBILITY_NAMESPACE,\n version: COMPATIBILITY_PRELUDE_VERSION,\n type: 'answer',\n role: 'host',\n protocols: hostProtocols,\n });\n } catch (cause) {\n controlPort.close();\n return {\n ok: false,\n error: { code: 'TRANSPORT_FAILED', cause },\n };\n }\n controlPort.close();\n return negotiated;\n }\n\n let operational: Readonly<{ port1: MessagePort; port2: MessagePort }>;\n try {\n operational = createChannel();\n } catch (cause) {\n controlPort.close();\n return {\n ok: false,\n error: { code: 'TRANSPORT_FAILED', cause },\n };\n }\n try {\n controlPort.postMessage(\n {\n namespace: COMPATIBILITY_NAMESPACE,\n version: COMPATIBILITY_PRELUDE_VERSION,\n type: 'answer',\n role: 'host',\n protocols: hostProtocols,\n },\n [operational.port2],\n );\n } catch (cause) {\n operational.port1.close();\n operational.port2.close();\n controlPort.close();\n return {\n ok: false,\n error: { code: 'TRANSPORT_FAILED', cause },\n };\n }\n controlPort.close();\n return {\n ok: true,\n value: {\n protocol: negotiated.value,\n operationalPort: operational.port1,\n },\n };\n}\n", "/**\n * Brings up the operational protocol on a negotiated port: start the heartbeat,\n * complete the Penpal handshake, exchange role descriptions, and hand back a\n * live endpoint.\n */\n\nimport { connect, PortMessenger, Reply } from 'penpal';\nimport type {\n Connection as PenpalConnection,\n Methods as PenpalMethods,\n} from 'penpal';\n\nimport {\n assertValidTimerDelay,\n CLAIM_TIMEOUT_MS,\n CLOSE_DELIVERY_TIMEOUT_MS,\n MAX_PENDING_ENDPOINT_OPERATIONS,\n} from '../config';\nimport { describeCause, describeError, logWarning } from '../diagnostics';\nimport { err, isRecord, isValidIdentifier, success, teardown } from '../shared';\nimport type {\n AnyContract,\n AnyError,\n AppConnection,\n ClaimOptions,\n Claimed,\n ConnectError,\n HostModule,\n ManagedAppConnection,\n ManagedHostConnection,\n Result,\n SurfaceId,\n WireClaimError,\n} from '../types';\n\nimport { ProtocolEndpoint } from './endpoint';\nimport type { ServedFunctionCall } from './endpoint';\nimport {\n Heartbeat,\n closeFailedOperationalTransport,\n postOperationalClose,\n} from './heartbeat';\nimport type { HeartbeatPolicy } from './heartbeat';\nimport { isVersion } from './validation';\nimport { advertisedClaimError, connectErrorFrom } from './wire-errors';\nimport type {\n ProtocolMethods,\n ProtocolRemote,\n PeerDescription,\n WireModuleDescription,\n} from './wire';\n\ntype EstablishedEndpoint = Readonly<{\n endpoint: ProtocolEndpoint;\n description: PeerDescription;\n}>;\n\ntype ServedProtocolMethods = Omit<ProtocolMethods, '__ddCall'> &\n Readonly<{\n __ddCall(\n request: Parameters<ProtocolMethods['__ddCall']>[0],\n ): Promise<ServedFunctionCall>;\n }>;\n\n/**\n * Names the fields of an inbound wire request that identify it, without\n * logging the payload: `inputs` and `values` are app-supplied data that has no\n * place in a host console.\n */\nfunction requestSummary(\n request: unknown,\n fields: readonly string[],\n): Readonly<Record<string, unknown>> {\n if (!isRecord(request)) {\n return { malformed: true, received: typeof request };\n }\n const summary: Record<string, unknown> = {};\n for (const field of fields) {\n summary[field] = request[field];\n }\n return summary;\n}\n\nclass AppConnectionImplementation implements AppConnection {\n constructor(\n private readonly endpoint: ProtocolEndpoint,\n private readonly modules: readonly WireModuleDescription[],\n ) {}\n\n async claim<TContract extends AnyContract>(\n contract: TContract,\n options?: ClaimOptions,\n ): Promise<Result<Claimed<TContract>, WireClaimError>> {\n if (this.endpoint.closed || options?.signal?.aborted) {\n return this.endpoint.claim(contract, options);\n }\n assertValidTimerDelay(\n 'ClaimOptions.timeoutMs',\n options?.timeoutMs ?? CLAIM_TIMEOUT_MS,\n );\n const unavailable = advertisedClaimError(contract, this.modules);\n return unavailable\n ? Promise.resolve(err(unavailable))\n : this.endpoint.claim(contract, options);\n }\n}\n\n/**\n * `role` and `modules` (as an array) are the only things this app build\n * needs to run the operational protocol at all -- everything else on a\n * `PeerDescription`, present or future, is metadata (`surfaceId` today) that\n * must never gate the connection. Do not add checks here for new fields:\n * an app built against an older SDK cannot know about a value a newer host\n * starts sending, and must connect successfully anyway. See\n * `establish.unit.ts` for the regression test that enforces this.\n */\nexport function isHostDescription(value: unknown): value is PeerDescription & {\n role: 'host';\n modules: readonly WireModuleDescription[];\n} {\n return (\n isRecord(value) && value.role === 'host' && Array.isArray(value.modules)\n );\n}\n\n/**\n * A malformed or unrecognized individual module descriptor must not cost the\n * app its entire connection -- it just makes that one module unclaimable.\n * Same principle as `isHostDescription`: only drop what's actually broken,\n * never the whole peer.\n */\nexport function sanitizeModules(\n modules: readonly unknown[],\n): readonly WireModuleDescription[] {\n const versions = new Set<string>();\n const sanitized: WireModuleDescription[] = [];\n for (const module of modules) {\n if (\n !isRecord(module) ||\n !isValidIdentifier(module.identifier) ||\n !isVersion(module.version)\n ) {\n continue;\n }\n const key = JSON.stringify([module.identifier, module.version]);\n if (versions.has(key)) {\n continue;\n }\n versions.add(key);\n sanitized.push({\n identifier: module.identifier,\n version: module.version,\n });\n }\n return sanitized;\n}\n\nasync function establishEndpoint(\n operationalPort: MessagePort,\n role: 'app' | 'host',\n timeoutMs: number,\n signal: AbortSignal,\n modules: readonly HostModule[],\n surfaceId: SurfaceId | undefined,\n heartbeatPolicy: HeartbeatPolicy,\n): Promise<Result<EstablishedEndpoint, ConnectError>> {\n let endpoint: ProtocolEndpoint | undefined;\n let heartbeat: Heartbeat;\n let disconnectedBeforeReady = false;\n let closeRequestedBeforeReady = false;\n let rejectForDisconnect: ((reason: unknown) => void) | undefined;\n const disconnected = new Promise<never>((_resolve, reject) => {\n rejectForDisconnect = reject;\n });\n try {\n heartbeat = new Heartbeat(\n operationalPort,\n (notifyPeer) => {\n if (endpoint) {\n endpoint.noteDisconnected(notifyPeer);\n } else {\n disconnectedBeforeReady = true;\n if (!notifyPeer) {\n // An inbound `__ddClose`: the peer already knows, so\n // there is nothing to deliver and no reason to hold\n // the port open for a grace period.\n operationalPort.close();\n }\n // A locally detected loss deliberately does not tear down\n // here. This rejection is raced by the establishment body,\n // so it lands in that `catch`, which owns the single\n // pre-ready teardown: post the close envelope, wait\n // CLOSE_DELIVERY_TIMEOUT_MS so it is not truncated, then\n // destroy Penpal and the port.\n rejectForDisconnect?.({ code: 'DISCONNECTED' });\n }\n },\n heartbeatPolicy,\n role,\n );\n } catch (cause) {\n teardown('failed operational port', () => operationalPort.close());\n return err({ code: 'TRANSPORT_FAILED', cause });\n }\n let endpointReadySettled = false;\n let pendingEndpointOperations = 0;\n let resolveEndpointReady: (\n value: ProtocolEndpoint | undefined,\n ) => void = () => undefined;\n const endpointReady = new Promise<ProtocolEndpoint | undefined>(\n (resolve) => {\n resolveEndpointReady = resolve;\n },\n );\n const settleEndpointReady = (value: ProtocolEndpoint | undefined) => {\n if (!endpointReadySettled) {\n endpointReadySettled = true;\n resolveEndpointReady(value);\n }\n };\n // A small queue permits the legitimate race where one peer finishes\n // description first without allowing an undescribed peer to retain\n // unbounded work.\n const requireReadyEndpoint = (\n expectedRole: 'app' | 'host',\n operation: string,\n ): Promise<ProtocolEndpoint> => {\n // A rejection here becomes a rejected remote call the peer can only\n // read as a lost connection, so the reason is only ever visible in\n // this console.\n const rejected = (reason: string): Error => {\n logWarning('an embedding operation was refused', {\n side: role,\n operation,\n expectedRole,\n reason,\n pendingEndpointOperations,\n });\n return new Error(reason);\n };\n if (endpoint) {\n return endpoint.role === expectedRole\n ? Promise.resolve(endpoint)\n : Promise.reject(\n rejected('The embedding operation is not valid here.'),\n );\n }\n if (\n endpointReadySettled ||\n pendingEndpointOperations >= MAX_PENDING_ENDPOINT_OPERATIONS\n ) {\n return Promise.reject(\n rejected('The embedding endpoint is not ready for work.'),\n );\n }\n pendingEndpointOperations += 1;\n return endpointReady\n .then((ready) => {\n if (!ready || ready.role !== expectedRole) {\n throw rejected(\n 'The embedding operation is not valid here.',\n );\n }\n return ready;\n })\n .finally(() => {\n pendingEndpointOperations -= 1;\n });\n };\n const localDescription: PeerDescription =\n role === 'host'\n ? {\n role: 'host',\n modules: modules.map(({ contract }) => ({\n identifier: contract.identifier,\n version: contract.version,\n })),\n surfaceId,\n }\n : { role: 'app' };\n // The one place where every locally-served operation's outcome is visible.\n // A peer only ever receives the failure code, so a rejection is reported\n // here alongside the request fields that produced it.\n const logRejection = <TValue, TError extends AnyError>(\n operation: string,\n request: unknown,\n requestFields: readonly string[],\n result: Result<TValue, TError>,\n ): Result<TValue, TError> => {\n if (!result.ok) {\n logWarning(`${operation} was rejected`, {\n side: role,\n request: requestSummary(request, requestFields),\n error: describeError(result.error),\n });\n }\n return result;\n };\n const methods: ServedProtocolMethods = {\n __ddDescribe: () => localDescription,\n __ddClaim: (request) =>\n requireReadyEndpoint('host', '__ddClaim').then((ready) =>\n ready\n .receiveClaim(request)\n .then((result) =>\n logRejection(\n '__ddClaim',\n request,\n ['claimId', 'identifier', 'version', 'fields'],\n result,\n ),\n ),\n ),\n __ddRelease: (claimId) =>\n requireReadyEndpoint('host', '__ddRelease').then((ready) =>\n ready.receiveRelease(claimId),\n ),\n __ddValues: (claimId, values) =>\n requireReadyEndpoint('app', '__ddValues').then((ready) =>\n ready.receiveValues(claimId, values),\n ),\n __ddCall: (request) =>\n requireReadyEndpoint('host', '__ddCall').then((ready) =>\n ready.receiveFunctionCall(request).then((response) => {\n logRejection(\n '__ddCall',\n request,\n ['claimId', 'callId', 'field'],\n response instanceof Reply ? response.value : response,\n );\n return response;\n }),\n ),\n __ddCancel: (request) =>\n requireReadyEndpoint('host', '__ddCancel').then((ready) =>\n ready.receiveFunctionCancel(request),\n ),\n __ddInvalidate: (claimId, invalidation) =>\n requireReadyEndpoint('app', '__ddInvalidate').then((ready) =>\n ready.receiveInvalidation(claimId, invalidation),\n ),\n __ddClose: () => {\n // Recorded synchronously at call time, not after the\n // endpoint-readiness promise settles: a peer can fire __ddClose\n // from its own __ddDescribe handler, before this side's endpoint\n // exists. Waiting on requireReadyEndpoint alone lets that close\n // run after establishment already decided to return success.\n if (!endpoint) {\n closeRequestedBeforeReady = true;\n }\n return requireReadyEndpoint(role, '__ddClose').then((ready) =>\n ready.close(false),\n );\n },\n };\n\n let penpal: PenpalConnection;\n try {\n penpal = connect({\n messenger: new PortMessenger({ port: operationalPort }),\n methods: methods as unknown as PenpalMethods,\n timeout: timeoutMs,\n });\n } catch (cause) {\n heartbeat.stop();\n postOperationalClose(operationalPort);\n globalThis.setTimeout(\n () => operationalPort.close(),\n CLOSE_DELIVERY_TIMEOUT_MS,\n );\n return err({ code: 'TRANSPORT_FAILED', cause });\n }\n\n let rejectForAbort: ((reason: unknown) => void) | undefined;\n let rejectForTimeout: ((reason: unknown) => void) | undefined;\n const onAbort = () => rejectForAbort?.({ code: 'ABORTED' });\n const aborted = new Promise<never>((_resolve, reject) => {\n rejectForAbort = reject;\n });\n const timedOut = new Promise<never>((_resolve, reject) => {\n rejectForTimeout = reject;\n });\n const timer = globalThis.setTimeout(\n () => rejectForTimeout?.({ code: 'TIMED_OUT' }),\n Math.max(0, timeoutMs),\n );\n signal.addEventListener('abort', onAbort, { once: true });\n // Which step a failure interrupted. A timeout or disconnect reaches the\n // caller as a bare code, so the stage is the only thing distinguishing \"the\n // peer never completed the Penpal handshake\" from \"the peer never described\n // itself\" or \"the peer described itself as the wrong role\".\n let stage: 'handshake' | 'peer-description' | 'validation' = 'handshake';\n try {\n if (signal.aborted) {\n throw Object.assign(new Error('The connection was aborted.'), {\n code: 'ABORTED',\n });\n }\n const remote = (await Promise.race([\n penpal.promise,\n aborted,\n timedOut,\n disconnected,\n ])) as unknown as ProtocolRemote;\n stage = 'peer-description';\n const peer: unknown = await Promise.race([\n remote['__ddDescribe'](),\n aborted,\n timedOut,\n disconnected,\n ]);\n stage = 'validation';\n const validPeer =\n role === 'app'\n ? isHostDescription(peer)\n : isRecord(peer) && peer.role === 'app';\n if (!validPeer) {\n throw new Error(\n `Expected an embedding ${role === 'app' ? 'host' : 'app'} using the operational protocol.`,\n );\n }\n endpoint = new ProtocolEndpoint(\n role,\n remote,\n penpal,\n operationalPort,\n modules,\n timeoutMs,\n );\n // The transport can be reported disconnected by the heartbeat in the\n // same tick that the peer-description race above resolved with the\n // other branch, which discards that rejection. Re-check the flag it\n // set rather than trust a stale \"success\" outcome.\n if (disconnectedBeforeReady) {\n throw Object.assign(\n new Error(\n 'The transport disconnected before establishment completed.',\n ),\n { code: 'DISCONNECTED' },\n );\n }\n // Same re-check as `disconnectedBeforeReady` above: a peer's __ddClose\n // can arrive in the same tick the peer-description race resolved with\n // the other branch, discarding it. Trust the flag it set, not a stale\n // \"success\" outcome that would hand back an endpoint the peer already\n // asked to close.\n if (closeRequestedBeforeReady) {\n throw Object.assign(\n new Error(\n 'The peer requested to close before establishment completed.',\n ),\n { code: 'DISCONNECTED' },\n );\n }\n settleEndpointReady(endpoint);\n endpoint.attachHeartbeat(heartbeat);\n return success({\n endpoint,\n description: peer as PeerDescription,\n });\n } catch (error) {\n const connectError = connectErrorFrom(error, timeoutMs);\n // The owner decides whether this is terminal and logs it as such; this\n // line exists to name the stage and the raw cause, which the returned\n // code cannot carry.\n logWarning('the operational protocol could not be established', {\n side: role,\n stage,\n timeoutMs,\n describedPeer: Boolean(endpoint),\n error: describeError(connectError),\n cause: describeCause(error),\n });\n heartbeat.stop();\n if (endpoint) {\n endpoint.close();\n } else {\n closeFailedOperationalTransport(penpal, operationalPort);\n }\n return err(connectError);\n } finally {\n settleEndpointReady(undefined);\n globalThis.clearTimeout(timer);\n signal.removeEventListener('abort', onAbort);\n }\n}\n\nfunction managedApp(established: EstablishedEndpoint): ManagedAppConnection {\n const endpoint = established.endpoint;\n const description = established.description as PeerDescription & {\n role: 'host';\n modules: readonly unknown[];\n };\n return {\n connection: new AppConnectionImplementation(\n endpoint,\n sanitizeModules(description.modules),\n ),\n surfaceId:\n typeof description.surfaceId === 'string'\n ? description.surfaceId\n : undefined,\n closeSignal: endpoint.closeSignal,\n close: () => endpoint.close(),\n };\n}\n\nfunction managedHost(established: EstablishedEndpoint): ManagedHostConnection {\n const endpoint = established.endpoint;\n return {\n closeSignal: endpoint.closeSignal,\n close: () => endpoint.close(),\n };\n}\n\n/**\n * Runs the operational protocol on a negotiated port and returns a connection\n * described without reference to that protocol, so the caller stays\n * agnostic.\n */\nexport async function connectApp(\n operationalPort: MessagePort,\n timeoutMs: number,\n signal: AbortSignal,\n heartbeatPolicy: HeartbeatPolicy,\n): Promise<Result<ManagedAppConnection, ConnectError>> {\n const established = await establishEndpoint(\n operationalPort,\n 'app',\n timeoutMs,\n signal,\n [],\n undefined,\n heartbeatPolicy,\n );\n return established.ok\n ? success(managedApp(established.value))\n : established;\n}\n\nexport async function connectHost(\n operationalPort: MessagePort,\n modules: readonly HostModule[],\n surfaceId: SurfaceId | undefined,\n timeoutMs: number,\n signal: AbortSignal,\n heartbeatPolicy: HeartbeatPolicy,\n): Promise<Result<ManagedHostConnection, ConnectError>> {\n const established = await establishEndpoint(\n operationalPort,\n 'host',\n timeoutMs,\n signal,\n modules,\n surfaceId,\n heartbeatPolicy,\n );\n return established.ok\n ? success(managedHost(established.value))\n : established;\n}\n", "/**\n * Liveness for the operational protocol.\n *\n * The heartbeat exists so a frozen app cannot present stale values as live\n * after a silent peer loss. Timing may be tuned conservatively, but that\n * stale-data guarantee must hold.\n */\n\nimport type { Connection as PenpalConnection } from 'penpal';\n\nimport {\n CLOSE_DELIVERY_TIMEOUT_MS,\n HEARTBEAT_DEADLINE_MS,\n HEARTBEAT_INTERVAL_MS,\n} from '../config';\nimport { describeCause, logFailure, logWarning } from '../diagnostics';\nimport type { DiagnosticSide } from '../diagnostics';\nimport { createId, isRecord, isValidIdentifier, teardown } from '../shared';\n\nconst HEARTBEAT_NAMESPACE = 'dd-apps-frontend-heartbeat';\nconst HEARTBEAT_VERSION = 1;\n\nexport type HeartbeatPolicy = Readonly<{\n intervalMs: number;\n timeoutMs: number;\n}>;\n\nexport const PRODUCTION_HEARTBEAT: HeartbeatPolicy = Object.freeze({\n intervalMs: HEARTBEAT_INTERVAL_MS,\n timeoutMs: HEARTBEAT_DEADLINE_MS,\n});\n\ntype HeartbeatEnvelope =\n | Readonly<{\n namespace: typeof HEARTBEAT_NAMESPACE;\n version: typeof HEARTBEAT_VERSION;\n type: 'ping' | 'pong';\n nonce: string;\n }>\n | Readonly<{\n namespace: typeof HEARTBEAT_NAMESPACE;\n version: typeof HEARTBEAT_VERSION;\n type: 'close';\n }>;\n\nexport function postOperationalClose(port: MessagePort): void {\n try {\n port.postMessage({\n namespace: HEARTBEAT_NAMESPACE,\n version: HEARTBEAT_VERSION,\n type: 'close',\n } satisfies HeartbeatEnvelope);\n } catch {\n // The port is already unusable.\n }\n}\n\nexport function closeFailedOperationalTransport(\n penpal: PenpalConnection,\n port: MessagePort,\n): void {\n postOperationalClose(port);\n globalThis.setTimeout(() => {\n teardown('failed Penpal connection', () => penpal.destroy());\n teardown('failed operational port', () => port.close());\n }, CLOSE_DELIVERY_TIMEOUT_MS);\n}\n\nexport class Heartbeat {\n #timer?: ReturnType<typeof globalThis.setTimeout>;\n #nonce?: string;\n #misses = 0;\n #started = false;\n #stopped = false;\n\n constructor(\n private readonly port: MessagePort,\n // `notifyPeer` tells the caller whether the peer still needs to\n // learn the session is over: true for a locally-detected loss (the\n // peer has no way to find out on its own), false for an inbound\n // close (the peer already knows, since it's the one that sent it).\n // The caller -- not this class -- owns actually notifying: it can\n // fold that into the same immediate-semantic/delayed-transport\n // teardown its own close() already does for an explicit close,\n // rather than this class managing its own separate delay.\n private readonly onDead: (notifyPeer: boolean) => void,\n private readonly policy: HeartbeatPolicy,\n private readonly side: DiagnosticSide,\n ) {\n this.port.addEventListener('message', this.#onMessage);\n }\n\n start(): void {\n if (this.#started || this.#stopped) {\n return;\n }\n this.#started = true;\n this.#schedule(this.policy.intervalMs);\n }\n\n stop(): void {\n if (this.#stopped) {\n return;\n }\n this.#stopped = true;\n this.#nonce = undefined;\n if (this.#timer !== undefined) {\n globalThis.clearTimeout(this.#timer);\n this.#timer = undefined;\n }\n this.port.removeEventListener('message', this.#onMessage);\n }\n\n readonly #onMessage = (event: MessageEvent<unknown>): void => {\n const envelope = event.data;\n if (\n !isRecord(envelope) ||\n envelope.namespace !== HEARTBEAT_NAMESPACE ||\n envelope.version !== HEARTBEAT_VERSION\n ) {\n return;\n }\n if (envelope.type === 'close') {\n // The peer sent this itself, so it already knows the session is\n // over -- no need to notify it back.\n this.#disconnect(false);\n return;\n }\n if (!isValidIdentifier(envelope.nonce)) {\n return;\n }\n if (envelope.type === 'ping') {\n try {\n this.port.postMessage({\n namespace: HEARTBEAT_NAMESPACE,\n version: HEARTBEAT_VERSION,\n type: 'pong',\n nonce: envelope.nonce,\n } satisfies HeartbeatEnvelope);\n } catch (cause) {\n logFailure('could not answer a heartbeat probe', {\n side: this.side,\n cause: describeCause(cause),\n });\n this.#disconnect(true);\n }\n return;\n }\n if (envelope.type !== 'pong' || envelope.nonce !== this.#nonce) {\n return;\n }\n this.#nonce = undefined;\n this.#misses = 0;\n if (this.#timer !== undefined) {\n globalThis.clearTimeout(this.#timer);\n this.#timer = undefined;\n }\n this.#schedule(this.policy.intervalMs);\n };\n\n #schedule(delayMs: number): void {\n if (this.#stopped) {\n return;\n }\n this.#timer = globalThis.setTimeout(\n () => this.#probe(),\n Math.max(0, delayMs),\n );\n }\n\n #probe(): void {\n if (this.#stopped) {\n return;\n }\n const nonce = createId('heartbeat');\n this.#nonce = nonce;\n try {\n this.port.postMessage({\n namespace: HEARTBEAT_NAMESPACE,\n version: HEARTBEAT_VERSION,\n type: 'ping',\n nonce,\n } satisfies HeartbeatEnvelope);\n } catch (cause) {\n logWarning('could not send a heartbeat probe', {\n side: this.side,\n misses: this.#misses,\n cause: describeCause(cause),\n });\n this.#miss(nonce);\n return;\n }\n this.#timer = globalThis.setTimeout(\n () => this.#miss(nonce),\n Math.max(0, this.policy.timeoutMs),\n );\n }\n\n #miss(nonce: string): void {\n if (this.#stopped || this.#nonce !== nonce) {\n return;\n }\n this.#nonce = undefined;\n this.#misses += 1;\n if (this.#misses >= 2) {\n logFailure('the peer stopped answering heartbeats', {\n side: this.side,\n misses: this.#misses,\n probeTimeoutMs: this.policy.timeoutMs,\n intervalMs: this.policy.intervalMs,\n });\n this.#disconnect(true);\n return;\n }\n logWarning('a heartbeat probe went unanswered', {\n side: this.side,\n misses: this.#misses,\n probeTimeoutMs: this.policy.timeoutMs,\n });\n this.#probe();\n }\n\n #disconnect(notifyPeer: boolean): void {\n if (this.#stopped) {\n return;\n }\n this.stop();\n // Semantic death is reported immediately either way -- the stale-\n // data guarantee this module exists for (see the module doc above)\n // requires the caller to know *now*, not after some delay. Whether\n // the peer still needs telling is a question the caller answers on\n // its own terms (e.g. its close()'s existing immediate-semantic/\n // delayed-transport split for an explicit close), not something\n // this class should approximate by delaying its own callback.\n this.onDead(notifyPeer);\n }\n}\n", "/**\n * Everything crossing the iframe boundary is hostile input by default.\n *\n * Each peer parses values with the contract compiled into its own bundle and\n * checks structured-clone safety before posting and again after receiving.\n * These helpers are validation-only: they never coerce or transform a value.\n */\n\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Reply } from 'penpal';\n\nimport { describeCause, logFailure } from '../diagnostics';\nimport { err, isRecord, success, teardown } from '../shared';\nimport type {\n AnyContract,\n AnySchema,\n ClaimInvalidationError,\n ContractVersion,\n FunctionField,\n InferOf,\n Issue,\n LiveValue,\n Result,\n} from '../types';\n\nexport function isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n ((typeof value === 'object' && value !== null) ||\n typeof value === 'function') &&\n typeof (value as { then?: unknown }).then === 'function'\n );\n}\n\nexport function isVersion(value: unknown): value is ContractVersion {\n return (\n typeof value === 'number' && Number.isSafeInteger(value) && value >= 1\n );\n}\n\nexport function isVersionList(\n value: unknown,\n): value is readonly ContractVersion[] {\n return Array.isArray(value) && value.every(isVersion);\n}\n\nexport function isNumberList(value: unknown): value is readonly number[] {\n return (\n Array.isArray(value) &&\n value.every(\n (entry) =>\n typeof entry === 'number' &&\n Number.isSafeInteger(entry) &&\n entry > 0,\n )\n );\n}\n\nexport function isPath(value: unknown): value is readonly (string | number)[] {\n return (\n Array.isArray(value) &&\n value.every(\n (segment) =>\n typeof segment === 'string' ||\n (typeof segment === 'number' &&\n Number.isSafeInteger(segment) &&\n segment >= 0),\n )\n );\n}\n\nexport function isIssueList(value: unknown): value is readonly Issue[] {\n return (\n Array.isArray(value) &&\n value.every(\n (issue) =>\n isRecord(issue) &&\n typeof issue.message === 'string' &&\n isPath(issue.path),\n )\n );\n}\n\nexport function validate<TSchema extends AnySchema>(\n schema: TSchema,\n value: unknown,\n): Result<InferOf<TSchema>, readonly Issue[]> {\n try {\n const validated = schema['~standard'].validate(value);\n if (isPromiseLike(validated)) {\n // Async schemas are unsupported, but their validation may already\n // have started and rejected. Observe that rejection so rejecting\n // an unsupported schema cannot surface as an unhandled promise.\n Promise.resolve(validated).catch(() => undefined);\n return err([\n {\n message: 'Embedding value schemas must be synchronous.',\n path: [],\n },\n ]);\n }\n if (validated.issues) {\n return err(\n validated.issues.map((issue) => ({\n message: issue.message,\n path: standardIssuePath(issue.path),\n })),\n );\n }\n // Standard Schema validators may transform same-type values or strip\n // unknown object keys. Returning the validated value (not the raw\n // input) ensures those transforms actually take effect, so a hostile\n // peer can't smuggle unvalidated properties past this boundary into\n // validateFunctionInputs/validateFunctionResult/readProvidedValue.\n return success(validated.value as InferOf<TSchema>);\n } catch (error) {\n return err([\n {\n message:\n error instanceof Error\n ? error.message\n : 'The value parser rejected this value.',\n path: [],\n },\n ]);\n }\n}\n\nfunction standardIssuePath(\n path: StandardSchemaV1.Issue['path'],\n): readonly (string | number)[] {\n if (!path) {\n return [];\n }\n return path.map((segment) => {\n const key =\n typeof segment === 'object' && segment !== null && 'key' in segment\n ? (segment as { key: unknown }).key\n : segment;\n if (typeof key === 'string') {\n return key;\n }\n return typeof key === 'number' && Number.isSafeInteger(key) && key >= 0\n ? key\n : String(key);\n });\n}\n\nexport function uncloneablePath(\n value: unknown,\n path: readonly (string | number)[] = [],\n seen: Set<object> = new Set<object>(),\n): readonly (string | number)[] | undefined {\n try {\n globalThis.structuredClone(value);\n return undefined;\n } catch {\n if (\n (typeof value !== 'object' && typeof value !== 'function') ||\n value === null ||\n seen.has(value)\n ) {\n return path;\n }\n seen.add(value);\n let entries: readonly [string, unknown][];\n try {\n entries = Object.entries(value);\n } catch {\n return path;\n }\n for (const [key, child] of entries) {\n const childPath = uncloneablePath(\n child,\n [...path, Array.isArray(value) ? Number(key) : key],\n seen,\n );\n if (childPath) {\n return childPath;\n }\n }\n return path;\n }\n}\n\nexport function prefixIssues(\n field: string,\n issues: readonly Issue[],\n): readonly Issue[] {\n return issues.map((issue) => ({\n message: issue.message,\n path: [field, ...issue.path],\n }));\n}\n\nexport function valueFieldNames(contract: AnyContract): readonly string[] {\n return Object.entries(contract.fields)\n .filter(([, field]) => field.kind === 'value')\n .map(([name]) => name);\n}\n\ntype FieldKeyIssue = Readonly<{ field: string; kind: 'missing' | 'unknown' }>;\n\n/**\n * The key-diff shared by both value-batch checks: which claimed fields are\n * missing (only relevant when the caller requires completeness) and which\n * present fields were never claimed at all (always checked).\n */\nfunction findFieldKeyIssue(\n expectedFields: Iterable<string>,\n values: Readonly<Record<string, unknown>>,\n requireComplete: boolean,\n): FieldKeyIssue | undefined {\n const expected = new Set(expectedFields);\n if (requireComplete) {\n const missingField = [...expected].find(\n (field) => !Object.prototype.hasOwnProperty.call(values, field),\n );\n if (missingField !== undefined) {\n return { field: missingField, kind: 'missing' };\n }\n }\n const unknownField = Object.keys(values).find(\n (field) => !expected.has(field),\n );\n return unknownField === undefined\n ? undefined\n : { field: unknownField, kind: 'unknown' };\n}\n\nfunction keyIssueError(issue: FieldKeyIssue): ClaimInvalidationError {\n return {\n code: 'INVALID_RESULT',\n issues: [\n {\n message:\n issue.kind === 'missing'\n ? 'The host value snapshot omitted a claimed field.'\n : 'The host value snapshot included an unclaimed field.',\n path: [issue.field],\n },\n ],\n };\n}\n\n/**\n * Validates a hydration snapshot: the claim response, or the first\n * `__ddValues` message a claim ever receives. The receiver has no prior state\n * to fall back on, so every claimed field must be present.\n */\nexport function invalidHydrationValueBatch(\n expectedFields: Iterable<string>,\n values: Readonly<Record<string, unknown>>,\n): ClaimInvalidationError | undefined {\n const issue = findFieldKeyIssue(expectedFields, values, true);\n return issue && keyIssueError(issue);\n}\n\n/**\n * Validates a partial update against an already-hydrated claim: any subset of\n * claimed fields is allowed, but a field outside the claim is still rejected.\n */\nexport function invalidUpdateValueBatch(\n expectedFields: Iterable<string>,\n values: Readonly<Record<string, unknown>>,\n): ClaimInvalidationError | undefined {\n const issue = findFieldKeyIssue(expectedFields, values, false);\n return issue && keyIssueError(issue);\n}\n\nexport function readProvidedValue(\n field: string,\n schema: AnySchema,\n provider: LiveValue<unknown>,\n): Result<unknown, readonly Issue[]> {\n let value: unknown;\n try {\n value = provider.get();\n } catch (error) {\n // Issues cross the embedding boundary into app code we do not control,\n // so the thrown message stays host-side. This matches how a throwing\n // host *function* is reported: logged here, opaque on the wire.\n logFailure('a host value provider threw while being read', {\n side: 'host',\n field,\n cause: describeCause(error),\n });\n return err([\n {\n message: 'The host value provider threw while being read.',\n path: [field],\n },\n ]);\n }\n const parsed = validate(schema, value);\n if (!parsed.ok) {\n return err(prefixIssues(field, parsed.error));\n }\n try {\n return success(globalThis.structuredClone(parsed.value));\n } catch {\n const path = uncloneablePath(parsed.value) ?? [];\n return err([\n {\n message: 'The host value is not structured-clone-safe.',\n path: [field, ...path],\n },\n ]);\n }\n}\n\nexport function reportInvalidHostValue(\n identifier: string,\n field: string,\n details: unknown,\n): readonly Issue[] {\n logFailure('a host value could not be provided', {\n side: 'host',\n target: `${identifier}.${field}`,\n details: describeCause(details),\n });\n return [\n {\n message:\n 'The host could not provide a value that satisfies this field schema.',\n path: [field],\n },\n ];\n}\n\nexport function validateFunctionInputs(\n fieldName: string,\n field: FunctionField<Readonly<Record<string, AnySchema>>, AnySchema>,\n inputs: unknown,\n): Result<Readonly<Record<string, unknown>>, readonly Issue[]> {\n if (!isRecord(inputs)) {\n return err([\n {\n message: 'Expected a named inputs object.',\n path: [fieldName, 'inputs'],\n },\n ]);\n }\n // An input name the field doesn't declare is rejected outright: unlike an\n // *omitted* input (below), there is no schema that could make an unknown\n // key acceptable, so this stays a plain existence check.\n const unknownInput = Object.keys(inputs).find(\n (name) => !Object.hasOwn(field.inputs, name),\n );\n if (unknownInput !== undefined) {\n return err([\n {\n message: `Unknown function input \"${unknownInput}\".`,\n path: [fieldName, 'inputs', unknownInput],\n },\n ]);\n }\n // A schema field literally named \"__proto__\" must become an own property\n // rather than invoking the object's prototype accessor.\n const parsedInputs: Record<string, unknown> = Object.create(null);\n for (const [name, schema] of Object.entries(field.inputs)) {\n // A caller omitting a key entirely is not pre-rejected as \"missing\":\n // reading an absent key gives the same `undefined` as one explicitly\n // set to it, and the field's own schema -- not this function -- is\n // what decides whether that value is acceptable. This is what lets an\n // input declared with an optional schema actually be omitted by a\n // caller, instead of every declared input being implicitly required\n // regardless of its own schema.\n // Read only the caller's own property: a value inherited through\n // the prototype chain (e.g. `Object.create({ required: 1 })`, or a\n // key like \"__proto__\") must not be able to satisfy a required\n // input that was never actually supplied.\n const parsed = validate(\n schema,\n Object.hasOwn(inputs, name) ? inputs[name] : undefined,\n );\n if (!parsed.ok) {\n return err(\n parsed.error.map((issue) => ({\n message: issue.message,\n path: [fieldName, 'inputs', name, ...issue.path],\n })),\n );\n }\n parsedInputs[name] = parsed.value;\n }\n try {\n return success(globalThis.structuredClone(parsedInputs));\n } catch {\n const path = uncloneablePath(parsedInputs) ?? [];\n return err([\n {\n message: 'The function inputs are not structured-clone-safe.',\n path: [fieldName, 'inputs', ...path],\n },\n ]);\n }\n}\n\nexport type PreparedFunctionResult =\n | Result<unknown, never>\n | Reply<Result<unknown, never>>;\n\nfunction isMessagePort(value: unknown): value is MessagePort {\n if (\n typeof value !== 'object' ||\n value === null ||\n typeof globalThis.MessagePort !== 'function'\n ) {\n return false;\n }\n if (value instanceof globalThis.MessagePort) {\n return true;\n }\n\n // Unlike Object#toString, a Web IDL getter checks the MessagePort internal\n // slot and cannot be forged with Symbol.toStringTag. Using the local\n // realm's getter also recognizes ports originating in another realm --\n // host and app are always different realms in this SDK, so this is the\n // ordinary case, not an edge case.\n let prototype: object | null = globalThis.MessagePort.prototype;\n while (prototype) {\n const getter = Object.getOwnPropertyDescriptor(\n prototype,\n 'onmessage',\n )?.get;\n if (getter) {\n try {\n getter.call(value);\n return true;\n } catch {\n return false;\n }\n }\n prototype = Object.getPrototypeOf(prototype);\n }\n return false;\n}\n\n/**\n * The `result` schema for a function field that returns a MessagePort\n * instead of structured-clone-safe data. Declaring a field with\n * `result: messagePortResult` is what makes `prepareFunctionResult` transfer\n * the returned port instead of cloning it as data; every other field is\n * completely unaware ports exist.\n */\nexport const messagePortResult: StandardSchemaV1<MessagePort, MessagePort> =\n /* @__PURE__ */ Object.freeze({\n '~standard': {\n version: 1 as const,\n vendor: '@datadog/apps-frontend',\n validate(value: unknown): StandardSchemaV1.Result<MessagePort> {\n return isMessagePort(value)\n ? { value }\n : { issues: [{ message: 'Expected a MessagePort.' }] };\n },\n },\n });\n\n/** Closes a MessagePort result that's being discarded without being handed to anyone. */\nexport function discardFunctionResult(value: unknown): void {\n if (isMessagePort(value)) {\n teardown('discarded function result MessagePort', () => value.close());\n }\n}\n\nfunction cloneFailure(\n fieldName: string,\n path: readonly (string | number)[] = [],\n): Result<never, readonly Issue[]> {\n return err([\n {\n message: 'The function result is not structured-clone-safe.',\n path: [fieldName, ...path],\n },\n ]);\n}\n\n/**\n * Validates and clones a provider result. A field declared with\n * `result: messagePortResult` gets its validated MessagePort transferred\n * instead of cloned; every other field takes the ordinary\n * structured-clone-safe data path, unchanged from before ports existed.\n */\nexport function prepareFunctionResult(\n fieldName: string,\n field: FunctionField<Readonly<Record<string, AnySchema>>, AnySchema>,\n value: unknown,\n): Result<PreparedFunctionResult, readonly Issue[]> {\n const parsed = validate(field.result, value);\n if (!parsed.ok) {\n return err(prefixIssues(fieldName, parsed.error));\n }\n if (field.result === messagePortResult) {\n // messagePortResult's own validate() guarantees parsed.value is a\n // MessagePort; any other schema takes the ordinary data path below\n // even if it happens to accept (or coincidentally is) a MessagePort\n // value -- only this exact declared schema opts a field in.\n const port = parsed.value as MessagePort;\n try {\n const cloned = globalThis.structuredClone(port, {\n transfer: [port],\n });\n return success(\n new Reply(success(cloned), { transferables: [cloned] }),\n );\n } catch {\n return cloneFailure(fieldName);\n }\n }\n try {\n return success(success(globalThis.structuredClone(parsed.value)));\n } catch {\n const path = uncloneablePath(parsed.value) ?? [];\n return cloneFailure(fieldName, path);\n }\n}\n\n/**\n * Validates a result after Penpal and the browser have already cloned it. A\n * `messagePortResult` field's value is already the transferred, live local\n * MessagePort by the time this runs; `messagePortResult`'s own schema\n * validation is what recognizes it, same as any other field's schema.\n */\nexport function receiveFunctionResult(\n fieldName: string,\n field: FunctionField<Readonly<Record<string, AnySchema>>, AnySchema>,\n value: unknown,\n): Result<unknown, readonly Issue[]> {\n const parsed = validate(field.result, value);\n if (!parsed.ok) {\n return err(prefixIssues(fieldName, parsed.error));\n }\n if (field.result === messagePortResult) {\n // Already the live, transferred MessagePort -- structuredClone\n // cannot reclone it without a transfer list, and there is nothing\n // further to verify.\n return success(parsed.value);\n }\n // A same-type schema transform can still return a reference that isn't\n // itself structured-clone-safe (e.g. attaching a function property);\n // recloning here is what the pre-port baseline did to catch that,\n // unchanged for every field except messagePortResult.\n try {\n return success(globalThis.structuredClone(parsed.value));\n } catch {\n const path = uncloneablePath(parsed.value) ?? [];\n return cloneFailure(fieldName, path);\n }\n}\n", "/**\n * Failure codes are data, not exception class names.\n *\n * Host exceptions are never serialized into the app: a call rejects with a\n * stable code and a diagnostic message naming the schema and field. An\n * unknown or malformed peer failure becomes UNRECOGNIZED rather than being\n * trusted or crashing the receiver.\n */\n\nimport { ErrorCode, PenpalError } from 'penpal';\n\nimport {\n MAX_CALL_ID_LENGTH,\n MAX_CLAIM_FIELD_NAME_LENGTH,\n MAX_CLAIM_FIELDS,\n MAX_CLAIM_ID_LENGTH,\n} from '../config';\nimport { describeError, logFailure } from '../diagnostics';\nimport { err, isRecord, isValidIdentifier, success } from '../shared';\nimport type {\n AnyContract,\n AnyError,\n ConnectError,\n ContractVersion,\n ErrorOf,\n Result,\n WireClaimError,\n WireFunctionError,\n} from '../types';\n\nimport {\n isIssueList,\n isNumberList,\n isVersion,\n isVersionList,\n} from './validation';\nimport type { WireModuleDescription } from './wire';\n\n// A version too old in one direction implies the other's version cannot also\n// appear among the offered hostVersions -- otherwise the two claims disagree\n// about who is behind.\nfunction appTooOld(raw: Record<string, unknown>): boolean {\n const wanted = raw.wanted;\n const hostVersions = raw.hostVersions;\n return (\n isVersion(wanted) &&\n isVersionList(hostVersions) &&\n !hostVersions.includes(wanted) &&\n hostVersions.some((version) => version > wanted)\n );\n}\n\nfunction hostTooOld(raw: Record<string, unknown>): boolean {\n const wanted = raw.wanted;\n const hostVersions = raw.hostVersions;\n return (\n isVersion(wanted) &&\n isVersionList(hostVersions) &&\n !hostVersions.includes(wanted) &&\n hostVersions.every((version) => version < wanted)\n );\n}\n\nconst ERROR_PAYLOAD: Readonly<\n Record<AnyError['code'], (raw: Record<string, unknown>) => boolean>\n> = {\n ORIGIN_REJECTED: (raw) => typeof raw.origin === 'string',\n APP_PROTOCOL_TOO_OLD: (raw) =>\n isNumberList(raw.appProtocols) && isNumberList(raw.hostProtocols),\n HOST_PROTOCOL_TOO_OLD: (raw) =>\n isNumberList(raw.appProtocols) && isNumberList(raw.hostProtocols),\n PROTOCOL_INCOMPATIBLE: (raw) =>\n isNumberList(raw.appProtocols) && isNumberList(raw.hostProtocols),\n PEER_LACKS_MODULE: (raw) => typeof raw.identifier === 'string',\n APP_MAJOR_TOO_OLD: appTooOld,\n HOST_MAJOR_TOO_OLD: hostTooOld,\n CONTRACT_INCOMPATIBLE: (raw) => typeof raw.field === 'string',\n INVALID_ARGUMENT: (raw) => isIssueList(raw.issues),\n FUNCTION_FAILED: (raw) => typeof raw.field === 'string',\n INVALID_RESULT: (raw) => isIssueList(raw.issues),\n TIMED_OUT: (raw) =>\n typeof raw.timeoutMs === 'number' &&\n Number.isFinite(raw.timeoutMs) &&\n raw.timeoutMs >= 0,\n TRANSPORT_FAILED: () => true,\n ABORTED: () => true,\n DISCONNECTED: () => true,\n UNRECOGNIZED: (raw) =>\n typeof raw.rawCode === 'string' && raw.rawCode.length > 0,\n};\n\n// Only these fields are trusted onto the returned error, even once a payload\n// passes ERROR_PAYLOAD validation -- a peer can add arbitrary extra keys to a\n// wire message, and those must not ride along into app-visible Error.cause.\nconst ERROR_FIELDS: Readonly<Record<AnyError['code'], readonly string[]>> = {\n ORIGIN_REJECTED: ['origin'],\n APP_PROTOCOL_TOO_OLD: ['appProtocols', 'hostProtocols'],\n HOST_PROTOCOL_TOO_OLD: ['appProtocols', 'hostProtocols'],\n PROTOCOL_INCOMPATIBLE: ['appProtocols', 'hostProtocols'],\n PEER_LACKS_MODULE: ['identifier'],\n APP_MAJOR_TOO_OLD: ['wanted', 'hostVersions'],\n HOST_MAJOR_TOO_OLD: ['wanted', 'hostVersions'],\n CONTRACT_INCOMPATIBLE: ['field'],\n INVALID_ARGUMENT: ['issues'],\n FUNCTION_FAILED: ['field'],\n INVALID_RESULT: ['issues'],\n TIMED_OUT: ['timeoutMs'],\n // TRANSPORT_FAILED is code-only on the wire: a peer-supplied cause could\n // otherwise carry an Error message/stack or arbitrary structured-cloneable\n // data across the embedding boundary. No current call site's `allowed`\n // list includes TRANSPORT_FAILED, but keep this array empty so that\n // can't change silently in the future.\n TRANSPORT_FAILED: [],\n ABORTED: [],\n DISCONNECTED: [],\n UNRECOGNIZED: ['rawCode', 'raw'],\n};\n\nexport function normalizeError<TError extends AnyError>(\n raw: unknown,\n allowed: readonly TError['code'][],\n): TError {\n if (isRecord(raw) && typeof raw.code === 'string') {\n const code = raw.code as AnyError['code'];\n if (\n allowed.includes(code as TError['code']) &&\n Object.prototype.hasOwnProperty.call(ERROR_PAYLOAD, code)\n ) {\n const validatePayload = ERROR_PAYLOAD[code];\n if (validatePayload(raw)) {\n if (code === 'UNRECOGNIZED') {\n return {\n code,\n rawCode: raw.rawCode,\n raw: undefined,\n } as TError;\n }\n const picked: Record<string, unknown> = { code };\n for (const name of ERROR_FIELDS[code]) {\n picked[name] = raw[name];\n }\n return picked as TError;\n }\n }\n }\n return {\n code: 'UNRECOGNIZED',\n rawCode:\n isRecord(raw) && typeof raw.code === 'string'\n ? raw.code\n : 'MALFORMED_ERROR',\n raw: undefined,\n } as TError;\n}\n\nexport function functionError(\n contract: AnyContract,\n field: string,\n errorValue: WireFunctionError,\n): Error {\n const target = `${contract.identifier}.${field}`;\n const publicCode =\n errorValue.code === 'UNRECOGNIZED' ? 'UNKNOWN' : errorValue.code;\n let message: string;\n switch (errorValue.code) {\n case 'INVALID_ARGUMENT':\n message = `The inputs passed to \"${target}\" are invalid: ${errorValue.issues[0]?.message ?? 'the schema rejected them'}.`;\n break;\n case 'INVALID_RESULT':\n message = `Datadog returned an invalid result from \"${target}\": ${errorValue.issues[0]?.message ?? 'the schema rejected it'}. The app and host may be using incompatible schema implementations.`;\n break;\n case 'FUNCTION_FAILED':\n message = `Datadog could not complete \"${target}\". Screenshot this message and contact support if the problem continues.`;\n break;\n case 'TIMED_OUT':\n message = `\"${target}\" did not finish within ${errorValue.timeoutMs} ms. It may still complete in Datadog; do not automatically retry an action that is not idempotent.`;\n break;\n case 'CONTRACT_INCOMPATIBLE':\n message = `The Datadog host contract for \"${target}\" does not match the schema compiled into this app. Update the app or contact support.`;\n break;\n case 'ABORTED':\n message = `The inputs used by \"${target}\" were released before it completed. Its outcome is unknown; wait for the inputs to become ready before calling it again.`;\n break;\n case 'DISCONNECTED':\n message = `The Datadog connection closed before \"${target}\" completed. Its outcome is unknown; reconnect before trying again.`;\n break;\n case 'UNRECOGNIZED':\n message = `Datadog returned an unrecognized failure for \"${target}\" (${errorValue.rawCode}). Screenshot this message and contact support.`;\n break;\n default: {\n const exhaustive: never = errorValue;\n message = exhaustive;\n }\n }\n const error = new Error(\n `DATADOG_APP_INPUT_FUNCTION_${publicCode}: ${message}`,\n { cause: errorValue },\n );\n error.name = 'DatadogAppInputFunctionError';\n // App code may swallow a rejected call, so the failure is reported here as\n // well as thrown: this is the only record that the call did not succeed.\n logFailure('a Datadog host function call failed', {\n side: 'app',\n target,\n error: describeError(errorValue),\n });\n return Object.assign(error, { code: publicCode });\n}\n\nexport function connectErrorFrom(\n error: unknown,\n timeoutMs: number,\n): ConnectError {\n if (isRecord(error) && error.code === 'ABORTED') {\n return { code: 'ABORTED' };\n }\n if (isRecord(error) && error.code === 'TIMED_OUT') {\n return { code: 'TIMED_OUT', timeoutMs };\n }\n if (isRecord(error) && error.code === 'DISCONNECTED') {\n return { code: 'DISCONNECTED' };\n }\n if (\n error instanceof PenpalError &&\n error.code === ErrorCode.ConnectionTimeout\n ) {\n return { code: 'TIMED_OUT', timeoutMs };\n }\n return { code: 'TRANSPORT_FAILED', cause: error };\n}\n\nexport function malformedClaimRequest(\n request: unknown,\n): ErrorOf<'INVALID_RESULT'> | undefined {\n if (!isRecord(request)) {\n return {\n code: 'INVALID_RESULT',\n issues: [\n {\n message:\n 'Malformed __ddClaim envelope: expected an object.',\n path: [],\n },\n ],\n };\n }\n if (!isValidIdentifier(request.claimId, MAX_CLAIM_ID_LENGTH)) {\n return {\n code: 'INVALID_RESULT',\n issues: [\n {\n message: `\"claimId\" must contain between 1 and ${MAX_CLAIM_ID_LENGTH} characters.`,\n path: ['claimId'],\n },\n ],\n };\n }\n if (!isValidIdentifier(request.identifier)) {\n return {\n code: 'INVALID_RESULT',\n issues: [\n {\n message: '\"identifier\" must be a non-empty string.',\n path: ['identifier'],\n },\n ],\n };\n }\n if (!isVersion(request.version)) {\n return {\n code: 'INVALID_RESULT',\n issues: [\n {\n message: '\"version\" must be a positive integer.',\n path: ['version'],\n },\n ],\n };\n }\n if (\n !Array.isArray(request.fields) ||\n request.fields.length === 0 ||\n request.fields.length > MAX_CLAIM_FIELDS\n ) {\n return {\n code: 'INVALID_RESULT',\n issues: [\n {\n message: `\"fields\" must contain between 1 and ${MAX_CLAIM_FIELDS} entries.`,\n path: ['fields'],\n },\n ],\n };\n }\n if (\n !request.fields.every(\n (field) =>\n typeof field === 'string' &&\n field.length > 0 &&\n field.length <= MAX_CLAIM_FIELD_NAME_LENGTH,\n ) ||\n new Set(request.fields).size !== request.fields.length\n ) {\n return {\n code: 'INVALID_RESULT',\n issues: [\n {\n message: `\"fields\" must contain unique non-empty strings of at most ${MAX_CLAIM_FIELD_NAME_LENGTH} characters.`,\n path: ['fields'],\n },\n ],\n };\n }\n return undefined;\n}\n\nexport function malformedFunctionRequest(\n request: unknown,\n): ErrorOf<'INVALID_ARGUMENT'> | undefined {\n if (!isRecord(request)) {\n return {\n code: 'INVALID_ARGUMENT',\n issues: [\n {\n message: 'Malformed __ddCall envelope: expected an object.',\n path: [],\n },\n ],\n };\n }\n if (!isValidIdentifier(request.claimId, MAX_CLAIM_ID_LENGTH)) {\n return {\n code: 'INVALID_ARGUMENT',\n issues: [\n {\n message: `\"claimId\" must contain between 1 and ${MAX_CLAIM_ID_LENGTH} characters.`,\n path: ['claimId'],\n },\n ],\n };\n }\n if (!isValidIdentifier(request.callId, MAX_CALL_ID_LENGTH)) {\n return {\n code: 'INVALID_ARGUMENT',\n issues: [\n {\n message: `\"callId\" must contain between 1 and ${MAX_CALL_ID_LENGTH} characters.`,\n path: ['callId'],\n },\n ],\n };\n }\n if (!isValidIdentifier(request.field)) {\n return {\n code: 'INVALID_ARGUMENT',\n issues: [\n {\n message: '\"field\" must be a non-empty string.',\n path: ['field'],\n },\n ],\n };\n }\n if (!isRecord(request.inputs)) {\n return {\n code: 'INVALID_ARGUMENT',\n issues: [\n {\n message: '\"inputs\" must be an object.',\n path: ['inputs'],\n },\n ],\n };\n }\n return undefined;\n}\n\ntype VersionCandidate = Readonly<{ version: ContractVersion }>;\n\nexport function negotiateVersion<TCandidate extends VersionCandidate>(\n wanted: ContractVersion,\n candidates: readonly TCandidate[],\n): Result<TCandidate, WireClaimError> {\n const hostVersions = candidates\n .map(({ version }) => version)\n .sort((left, right) => left - right);\n const newestVersion = hostVersions[hostVersions.length - 1];\n // Keep negotiation total when a caller provides no candidates.\n if (newestVersion === undefined) {\n return err({ code: 'HOST_MAJOR_TOO_OLD', wanted, hostVersions });\n }\n const sameVersion = candidates.find(({ version }) => version === wanted);\n if (sameVersion) {\n return success(sameVersion);\n }\n return err(\n wanted < newestVersion\n ? { code: 'APP_MAJOR_TOO_OLD', wanted, hostVersions }\n : { code: 'HOST_MAJOR_TOO_OLD', wanted, hostVersions },\n );\n}\n\nexport function advertisedClaimError(\n contract: AnyContract,\n modules: readonly WireModuleDescription[],\n): WireClaimError | undefined {\n const candidates = modules.filter(\n ({ identifier }) => identifier === contract.identifier,\n );\n if (candidates.length === 0) {\n return {\n code: 'PEER_LACKS_MODULE',\n identifier: contract.identifier,\n };\n }\n const negotiated = negotiateVersion(contract.version, candidates);\n return negotiated.ok ? undefined : negotiated.error;\n}\n", "/**\n * One live protocol-1 endpoint: the peer of a Penpal connection over the\n * negotiated operational port.\n *\n * Owns claims, function calls, and their deadlines for one connection, in\n * both the app and host roles.\n */\n\nimport type { Connection as PenpalConnection } from 'penpal';\n\nimport {\n assertValidTimerDelay,\n CLAIM_TIMEOUT_MS,\n CLOSE_DELIVERY_TIMEOUT_MS,\n FUNCTION_CALL_TIMEOUT_MS,\n MAX_CALL_ID_LENGTH,\n MAX_CLAIM_ID_LENGTH,\n MAX_LIVE_HOST_CLAIMS,\n MAX_LIVE_HOST_FUNCTION_CALLS,\n MAX_TIMER_DELAY_MS,\n} from '../config';\nimport {\n describeCause,\n describeError,\n logFailure,\n logWarning,\n} from '../diagnostics';\nimport {\n createId,\n err,\n isRecord,\n isValidIdentifier,\n notifyListeners,\n success,\n teardown,\n} from '../shared';\nimport type {\n AnyContract,\n AnyError,\n AnySchema,\n ClaimInvalidationError,\n ClaimOptions,\n Claimed,\n ClaimedFields,\n FunctionField,\n HostModule,\n Issue,\n LiveValue,\n ValueField,\n Result,\n Unsubscribe,\n WireClaimError,\n WireFunctionError,\n} from '../types';\n\nimport type { Heartbeat } from './heartbeat';\nimport { postOperationalClose } from './heartbeat';\nimport {\n discardFunctionResult,\n invalidHydrationValueBatch,\n invalidUpdateValueBatch,\n prefixIssues,\n prepareFunctionResult,\n readProvidedValue,\n receiveFunctionResult,\n reportInvalidHostValue,\n validate,\n validateFunctionInputs,\n valueFieldNames,\n} from './validation';\nimport type { PreparedFunctionResult } from './validation';\nimport {\n functionError,\n malformedClaimRequest,\n malformedFunctionRequest,\n negotiateVersion,\n normalizeError,\n} from './wire-errors';\nimport type {\n ProtocolRemote,\n WireClaimRequest,\n WireClaimSuccess,\n WireFunctionCancel,\n WireFunctionRequest,\n} from './wire';\n\nexport class MutableLiveValue<TValue> implements LiveValue<TValue> {\n readonly #listeners = new Set<() => void>();\n\n constructor(private value: TValue) {}\n\n get(): TValue {\n return this.value;\n }\n\n subscribe(onChange: () => void): Unsubscribe {\n this.#listeners.add(onChange);\n return () => {\n this.#listeners.delete(onChange);\n };\n }\n\n set(value: TValue): boolean {\n if (Object.is(this.value, value)) {\n return false;\n }\n this.value = value;\n return true;\n }\n\n notify(): void {\n notifyListeners(this.#listeners);\n }\n\n // A dead claim retains its last value only as a teardown safety net. The\n // owning resource must leave ready state when the claim is invalidated.\n freeze(): void {\n this.#listeners.clear();\n }\n}\n\ntype HostClaim = {\n readonly releases: Unsubscribe[];\n readonly module: HostModule;\n readonly fields: ReadonlyMap<string, AnyContract['fields'][string]>;\n};\n\ntype HostFunctionCall = {\n readonly claimId: string;\n readonly controller: AbortController;\n interrupt(reason: 'cancelled' | 'timed-out'): void;\n};\n\ntype AppClaim = {\n readonly contract: AnyContract;\n readonly values: Map<string, MutableLiveValue<unknown>>;\n readonly valueListeners: Set<() => void>;\n readonly invalidationListeners: Set<\n (error: ClaimInvalidationError) => void\n >;\n readonly releaseController: AbortController;\n invalidation?: ClaimInvalidationError;\n released: boolean;\n // True once this claim has applied one __ddValues message. That first\n // message must be complete (there is no prior state to fall back on);\n // every later message may be partial.\n hydrated: boolean;\n};\n\n// Shared across every ProtocolEndpoint in this bundle so calls that outlive an\n// endpoint teardown or reconnect remain counted. The resulting concurrency\n// budget is also shared by unrelated embedded apps on the same host page.\nlet liveHostFunctionCalls = 0;\n\n/**\n * The deadline governing one function call: the field's own `timeoutMs` when it\n * declares a usable one, otherwise `FUNCTION_CALL_TIMEOUT_MS`.\n *\n * Each side resolves this from its own copy of the contract, so the two need\n * not agree -- see `FunctionField.timeoutMs`.\n *\n * `defineContract()` rejects the same unusable set at definition time.\n * Re-screening it here is not redundant: a contract is only type-checked in the\n * bundle that declared it, and this is what the timer is actually armed from.\n */\nfunction resolveFunctionCallTimeoutMs(field: {\n readonly timeoutMs?: number;\n}): number {\n const declared = field.timeoutMs;\n return typeof declared === 'number' &&\n Number.isFinite(declared) &&\n declared > 0 &&\n declared <= MAX_TIMER_DELAY_MS\n ? declared\n : FUNCTION_CALL_TIMEOUT_MS;\n}\n\ntype SettleOptions<TError extends AnyError> = Readonly<{\n timeoutMs: number;\n signal?: AbortSignal;\n onCancel(): void;\n timeoutError(timeoutMs: number): TError;\n abortError: TError;\n disconnectedError: TError;\n normalize(raw: unknown): TError;\n onDiscardedResult?(result: unknown): void;\n}>;\n\nexport type ServedFunctionCall =\n | Result<unknown, WireFunctionError>\n | PreparedFunctionResult;\n\nexport class ProtocolEndpoint {\n readonly #closeController = new AbortController();\n readonly #hostClaims = new Map<string, HostClaim>();\n readonly #hostFunctionCalls = new Map<string, HostFunctionCall>();\n readonly #appClaims = new Map<string, AppClaim>();\n readonly #pendingClaims = new Map<string, AnyContract>();\n readonly #queuedValues = new Map<\n string,\n Readonly<Record<string, unknown>>\n >();\n readonly #queuedInvalidations = new Map<string, ClaimInvalidationError>();\n readonly #sendTimers = new Set<ReturnType<typeof globalThis.setTimeout>>();\n #heartbeat?: Heartbeat;\n #closed = false;\n #transportClosed = false;\n\n constructor(\n readonly role: 'app' | 'host',\n readonly remote: ProtocolRemote,\n private readonly penpal: PenpalConnection,\n private readonly port: MessagePort,\n private readonly modules: readonly HostModule[],\n private readonly operationTimeoutMs: number,\n ) {}\n\n get closed(): boolean {\n return this.#closed;\n }\n\n get closeSignal(): AbortSignal {\n return this.#closeController.signal;\n }\n\n attachHeartbeat(heartbeat: Heartbeat): void {\n if (this.closed) {\n heartbeat.stop();\n return;\n }\n this.#heartbeat = heartbeat;\n heartbeat.start();\n }\n\n // `operation` names the outbound message for diagnostics only; a failure\n // here closes the connection without telling the peer why.\n send(operation: string, call: () => Promise<unknown>): void {\n if (this.closed) {\n return;\n }\n let pending: Promise<unknown>;\n try {\n pending = call();\n } catch (cause) {\n logFailure('an outbound embedding message could not be sent', {\n side: this.role,\n operation,\n cause: describeCause(cause),\n });\n this.noteDisconnected();\n return;\n }\n const timer = globalThis.setTimeout(\n () => {\n this.#sendTimers.delete(timer);\n logFailure(\n 'an outbound embedding message was never acknowledged; closing the connection',\n {\n side: this.role,\n operation,\n timeoutMs: this.operationTimeoutMs,\n },\n );\n // A peer may still be alive enough to handle an explicit close\n // even though this operation stopped making progress.\n this.close();\n },\n Math.max(0, this.operationTimeoutMs),\n );\n this.#sendTimers.add(timer);\n const finish = (disconnected: boolean, cause?: unknown) => {\n if (!this.#sendTimers.delete(timer)) {\n return;\n }\n globalThis.clearTimeout(timer);\n if (disconnected) {\n logFailure('an outbound embedding message was rejected', {\n side: this.role,\n operation,\n cause: describeCause(cause),\n });\n this.noteDisconnected();\n }\n };\n pending.then(\n () => finish(false),\n (cause: unknown) => finish(true, cause),\n );\n }\n\n // `notifyPeer` defaults to false to match every existing call site: an\n // outbound send/call that itself failed or was rejected implies the\n // transport is already broken, so attempting another outbound message\n // to notify the peer would be pointless (and could throw again). The\n // one caller that passes `true` is a heartbeat's locally-detected peer\n // loss (see establish.ts): a missed probe doesn't imply postMessage\n // itself is broken, only that the peer's own process may be\n // unresponsive, so there's still a reasonable chance a close\n // notification actually gets through -- worth attempting, and this\n // reuses close()'s already-tested immediate-semantic/delayed-transport\n // split rather than approximating it separately.\n noteDisconnected(notifyPeer = false): void {\n this.close(notifyPeer);\n }\n\n // The endpoint owns every subscription, timer, claim and port. Teardown is\n // idempotent because disconnect, explicit close and heartbeat may race.\n close(notifyPeer = true): void {\n if (this.#closed) {\n return;\n }\n this.#closed = true;\n let peerClose: Promise<unknown> | undefined;\n if (notifyPeer) {\n postOperationalClose(this.port);\n try {\n peerClose = this.remote['__ddClose']();\n } catch {\n // The peer may already be gone. `peerClose` stays undefined\n // here, but transport teardown is still delayed below --\n // it's keyed on `notifyPeer`, not on `peerClose` -- since\n // postOperationalClose() above already queued a raw\n // envelope on this.port, and an immediate #closeTransport()\n // could truncate its delivery before it's actually flushed.\n }\n }\n this.#heartbeat?.stop();\n this.#heartbeat = undefined;\n for (const timer of this.#sendTimers) {\n globalThis.clearTimeout(timer);\n }\n this.#sendTimers.clear();\n this.#closeController.abort();\n for (const claimId of [...this.#hostClaims.keys()]) {\n this.receiveRelease(claimId);\n }\n // A consumer awaiting onInvalidated on a live claim must be told the\n // connection is gone instead of hanging forever, so this goes through\n // #invalidateAppClaim rather than tearing the claim down silently.\n // Snapshot first: #endAppClaim deletes from #appClaims as it goes.\n // notifyPeer is false because the peer already got __ddClose above;\n // per-claim __ddRelease messages would be pointless on a dead transport.\n for (const [claimId, claim] of [...this.#appClaims.entries()]) {\n this.#invalidateAppClaim(\n claimId,\n claim,\n { code: 'DISCONNECTED' },\n false,\n );\n }\n this.#pendingClaims.clear();\n this.#queuedValues.clear();\n this.#queuedInvalidations.clear();\n if (!notifyPeer) {\n this.#closeTransport();\n return;\n }\n // Keep the port alive for the full grace period whenever a peer\n // notification was attempted at all -- keyed on `notifyPeer`, not\n // on whether `peerClose` ended up defined, so a synchronously\n // thrown __ddClose() (caught above) still can't cause the just-\n // queued postOperationalClose() envelope to be truncated by an\n // immediate #closeTransport(). Penpal can also reject the close\n // call as soon as the peer begins its own teardown, before the\n // peer's close handler has propagated through the connection owner.\n peerClose?.catch(() => undefined);\n globalThis.setTimeout(\n () => this.#closeTransport(),\n CLOSE_DELIVERY_TIMEOUT_MS,\n );\n }\n\n #closeTransport(): void {\n if (this.#transportClosed) {\n return;\n }\n this.#transportClosed = true;\n teardown('Penpal connection', () => this.penpal.destroy());\n teardown('operational port', () => this.port.close());\n }\n\n async settleRemoteResult<TValue, TError extends AnyError>(\n remoteCall: Promise<Result<unknown, TError>>,\n options: SettleOptions<TError>,\n ): Promise<Result<TValue, TError>> {\n if (this.closed) {\n remoteCall.then(\n (result) => {\n options.onDiscardedResult?.(result);\n },\n () => undefined,\n );\n return err(options.disconnectedError);\n }\n return new Promise((resolve) => {\n let settled = false;\n let timer: ReturnType<typeof globalThis.setTimeout> | undefined;\n const finish = (result: Result<TValue, TError>) => {\n if (settled) {\n return;\n }\n settled = true;\n if (timer !== undefined) {\n globalThis.clearTimeout(timer);\n }\n options.signal?.removeEventListener('abort', onAbort);\n this.closeSignal.removeEventListener('abort', onDisconnect);\n resolve(result);\n };\n const onAbort = () => {\n options.onCancel();\n finish(err(options.abortError));\n };\n const onDisconnect = () => finish(err(options.disconnectedError));\n\n options.signal?.addEventListener('abort', onAbort, { once: true });\n this.closeSignal.addEventListener('abort', onDisconnect, {\n once: true,\n });\n if (options.signal?.aborted) {\n onAbort();\n return;\n }\n if (this.closeSignal.aborted) {\n onDisconnect();\n return;\n }\n timer = globalThis.setTimeout(\n () => {\n options.onCancel();\n finish(err(options.timeoutError(options.timeoutMs)));\n },\n Math.max(0, options.timeoutMs),\n );\n remoteCall.then(\n (result) => {\n if (settled) {\n options.onDiscardedResult?.(result);\n return;\n }\n if (isRecord(result) && result.ok === true) {\n finish(success(result.value as TValue));\n return;\n }\n options.onDiscardedResult?.(result);\n finish(\n err(\n options.normalize(\n isRecord(result) ? result.error : result,\n ),\n ),\n );\n },\n () => {\n this.noteDisconnected();\n finish(err(options.disconnectedError));\n },\n );\n });\n }\n\n async claim<TContract extends AnyContract>(\n contract: TContract,\n options: ClaimOptions = {},\n ): Promise<Result<Claimed<TContract>, WireClaimError>> {\n if (this.closed) {\n return err({ code: 'DISCONNECTED' });\n }\n if (options.signal?.aborted) {\n return err({ code: 'ABORTED' });\n }\n const timeoutMs = options.timeoutMs ?? CLAIM_TIMEOUT_MS;\n assertValidTimerDelay('ClaimOptions.timeoutMs', timeoutMs);\n const claimId = createId('claim');\n this.#pendingClaims.set(claimId, contract);\n let remoteCall: Promise<Result<WireClaimSuccess, WireClaimError>>;\n try {\n remoteCall = this.remote['__ddClaim']({\n claimId,\n identifier: contract.identifier,\n version: contract.version,\n fields: Object.keys(contract.fields),\n });\n } catch (cause) {\n logFailure('a claim could not be sent to the Datadog host', {\n side: this.role,\n claimId,\n identifier: contract.identifier,\n version: contract.version,\n cause: describeCause(cause),\n });\n this.#forgetPendingClaim(claimId);\n this.noteDisconnected();\n return err({ code: 'DISCONNECTED' });\n }\n remoteCall = remoteCall.then(\n (result) => result,\n () => {\n this.noteDisconnected();\n return err<WireClaimError>({ code: 'DISCONNECTED' });\n },\n );\n const claimed = await this.settleRemoteResult<\n WireClaimSuccess,\n WireClaimError\n >(remoteCall, {\n timeoutMs,\n signal: options.signal,\n onCancel: () => {\n this.send('__ddRelease', () =>\n this.remote['__ddRelease'](claimId),\n );\n },\n timeoutError: (deadlineMs) => ({\n code: 'TIMED_OUT',\n timeoutMs: deadlineMs,\n }),\n abortError: { code: 'ABORTED' },\n disconnectedError: { code: 'DISCONNECTED' },\n normalize: (raw) =>\n normalizeError<WireClaimError>(raw, [\n 'PEER_LACKS_MODULE',\n 'APP_MAJOR_TOO_OLD',\n 'HOST_MAJOR_TOO_OLD',\n 'CONTRACT_INCOMPATIBLE',\n 'INVALID_RESULT',\n 'TIMED_OUT',\n 'ABORTED',\n 'DISCONNECTED',\n 'UNRECOGNIZED',\n ]),\n });\n if (!claimed.ok) {\n this.#forgetPendingClaim(claimId);\n return claimed;\n }\n if (!isRecord(claimed.value) || !isRecord(claimed.value.values)) {\n this.#forgetPendingClaim(claimId);\n this.send('__ddRelease', () => this.remote['__ddRelease'](claimId));\n return err({\n code: 'INVALID_RESULT',\n issues: [\n { message: 'Malformed claim success payload.', path: [] },\n ],\n });\n }\n\n const invalidInitialValues = invalidHydrationValueBatch(\n valueFieldNames(contract),\n claimed.value.values,\n );\n if (invalidInitialValues) {\n this.#forgetPendingClaim(claimId);\n this.send('__ddRelease', () => this.remote['__ddRelease'](claimId));\n return err(invalidInitialValues);\n }\n\n const values = new Map<string, MutableLiveValue<unknown>>();\n const fields: Record<string, unknown> = {};\n const record: AppClaim = {\n contract,\n values,\n valueListeners: new Set(),\n invalidationListeners: new Set(),\n releaseController: new AbortController(),\n released: false,\n // The claim response above already seeded every field, but that\n // is a separate channel from __ddValues: the first message on\n // this channel still has to prove it is complete.\n hydrated: false,\n };\n for (const [name, field] of Object.entries(contract.fields)) {\n if (field.kind === 'function') {\n fields[name] = (...callArgs: readonly unknown[]) =>\n this.callFunction(claimId, record, name, field, callArgs);\n continue;\n }\n const initial = validate(field.schema, claimed.value.values[name]);\n if (!initial.ok) {\n this.#forgetPendingClaim(claimId);\n this.send('__ddRelease', () =>\n this.remote['__ddRelease'](claimId),\n );\n return err({\n code: 'INVALID_RESULT',\n issues: prefixIssues(name, initial.error),\n });\n }\n const live = new MutableLiveValue(initial.value);\n values.set(name, live as MutableLiveValue<unknown>);\n fields[name] = live;\n }\n this.#appClaims.set(claimId, record);\n const queuedValues = this.#queuedValues.get(claimId);\n if (queuedValues) {\n this.receiveValues(claimId, queuedValues);\n }\n const queuedInvalidation =\n record.invalidation ?? this.#queuedInvalidations.get(claimId);\n this.#forgetPendingClaim(claimId);\n if (queuedInvalidation) {\n this.#endAppClaim(claimId, record, true, queuedInvalidation);\n return err(queuedInvalidation);\n }\n\n return success({\n fields: fields as ClaimedFields<TContract>,\n release: () => this.#endAppClaim(claimId, record, true),\n onValuesChanged: (listener) => {\n if (record.released) {\n return () => undefined;\n }\n record.valueListeners.add(listener);\n return () => record.valueListeners.delete(listener);\n },\n onInvalidated: (listener) => {\n const invalidation = record.invalidation;\n if (invalidation) {\n globalThis.queueMicrotask(() => listener(invalidation));\n return () => undefined;\n }\n if (record.released) {\n return () => undefined;\n }\n record.invalidationListeners.add(listener);\n return () => record.invalidationListeners.delete(listener);\n },\n });\n }\n\n async callFunction(\n claimId: string,\n record: AppClaim,\n fieldName: string,\n field: FunctionField<Readonly<Record<string, AnySchema>>, AnySchema>,\n callArgs: readonly unknown[],\n ): Promise<unknown> {\n if (this.closed) {\n throw functionError(record.contract, fieldName, {\n code: 'DISCONNECTED',\n });\n }\n if (record.released) {\n throw functionError(record.contract, fieldName, {\n code: 'ABORTED',\n });\n }\n if (callArgs.length !== 1) {\n throw functionError(record.contract, fieldName, {\n code: 'INVALID_ARGUMENT',\n issues: [\n {\n message: `Expected one named inputs object, received ${callArgs.length} arguments.`,\n path: [fieldName, 'inputs'],\n },\n ],\n });\n }\n const parsedInputs = validateFunctionInputs(\n fieldName,\n field,\n callArgs[0],\n );\n if (!parsedInputs.ok) {\n throw functionError(record.contract, fieldName, {\n code: 'INVALID_ARGUMENT',\n issues: parsedInputs.error,\n });\n }\n\n const callId = createId('call');\n let remoteCall: Promise<Result<unknown, WireFunctionError>>;\n try {\n remoteCall = this.remote['__ddCall']({\n claimId,\n callId,\n field: fieldName,\n inputs: parsedInputs.value,\n });\n } catch {\n this.noteDisconnected();\n throw functionError(record.contract, fieldName, {\n code: 'DISCONNECTED',\n });\n }\n const result = await this.settleRemoteResult<\n unknown,\n WireFunctionError\n >(remoteCall, {\n // Independent of the host's own execution deadline and of this\n // endpoint's generic `operationTimeoutMs`.\n timeoutMs: resolveFunctionCallTimeoutMs(field),\n signal: record.releaseController.signal,\n onCancel: () => {\n this.send('__ddCancel', () =>\n this.remote['__ddCancel']({ claimId, callId }),\n );\n },\n timeoutError: (timeoutMs) => ({ code: 'TIMED_OUT', timeoutMs }),\n abortError: { code: 'ABORTED' },\n disconnectedError: { code: 'DISCONNECTED' },\n normalize: (raw) =>\n normalizeError<WireFunctionError>(raw, [\n 'CONTRACT_INCOMPATIBLE',\n 'INVALID_ARGUMENT',\n 'FUNCTION_FAILED',\n 'INVALID_RESULT',\n 'TIMED_OUT',\n 'ABORTED',\n 'DISCONNECTED',\n 'UNRECOGNIZED',\n ]),\n // onDiscardedResult receives the raw wire Result envelope, not\n // the unwrapped value discardFunctionResult expects -- only a\n // successful result can carry a MessagePort to close.\n onDiscardedResult: (discarded) => {\n if (isRecord(discarded) && discarded.ok === true) {\n discardFunctionResult(discarded.value);\n }\n },\n });\n if (!result.ok) {\n const remoteError: WireFunctionError =\n result.error.code === 'INVALID_ARGUMENT'\n ? { code: 'CONTRACT_INCOMPATIBLE', field: fieldName }\n : result.error;\n throw functionError(record.contract, fieldName, remoteError);\n }\n const parsedResult = receiveFunctionResult(\n fieldName,\n field,\n result.value,\n );\n if (!parsedResult.ok) {\n throw functionError(record.contract, fieldName, {\n code: 'INVALID_RESULT',\n issues: parsedResult.error,\n });\n }\n return parsedResult.value;\n }\n\n #forgetPendingClaim(claimId: string): void {\n this.#pendingClaims.delete(claimId);\n this.#queuedValues.delete(claimId);\n this.#queuedInvalidations.delete(claimId);\n }\n\n #endAppClaim(\n claimId: string,\n record: AppClaim,\n notifyPeer: boolean,\n invalidation?: ClaimInvalidationError,\n ): boolean {\n if (record.released) {\n return false;\n }\n record.released = true;\n record.invalidation = invalidation;\n record.releaseController.abort();\n for (const value of record.values.values()) {\n value.freeze();\n }\n record.valueListeners.clear();\n record.invalidationListeners.clear();\n this.#appClaims.delete(claimId);\n if (notifyPeer) {\n this.send('__ddRelease', () => this.remote['__ddRelease'](claimId));\n }\n return true;\n }\n\n #invalidateAppClaim(\n claimId: string,\n record: AppClaim,\n invalidation: ClaimInvalidationError,\n notifyPeer: boolean,\n ): void {\n const listeners = [...record.invalidationListeners];\n if (!this.#endAppClaim(claimId, record, notifyPeer, invalidation)) {\n return;\n }\n // A live claim losing its values is the moment an app stops seeing\n // trustworthy data, whether the cause was the connection or the data.\n const report =\n invalidation.code === 'DISCONNECTED' ? logWarning : logFailure;\n report('a live claim was invalidated', {\n side: this.role,\n claimId,\n identifier: record.contract.identifier,\n version: record.contract.version,\n observedListeners: listeners.length,\n error: describeError(invalidation),\n });\n notifyListeners(listeners, invalidation);\n }\n\n receiveValues(claimId: string, values: unknown): void {\n if (!isValidIdentifier(claimId, MAX_CLAIM_ID_LENGTH)) {\n logFailure(\n 'ignored a __ddValues envelope with an invalid claim id',\n {\n side: this.role,\n claimId,\n maxClaimIdLength: MAX_CLAIM_ID_LENGTH,\n },\n );\n return;\n }\n const claim = this.#appClaims.get(claimId);\n const pendingContract = this.#pendingClaims.get(claimId);\n if (!isRecord(values)) {\n const invalidation: ClaimInvalidationError = {\n code: 'INVALID_RESULT',\n issues: [\n {\n message: 'The host value snapshot must be an object.',\n path: [],\n },\n ],\n };\n if (claim) {\n this.#invalidateAppClaim(claimId, claim, invalidation, true);\n } else if (pendingContract) {\n this.#queuedInvalidations.set(claimId, invalidation);\n this.#queuedValues.delete(claimId);\n } else {\n logFailure(\n 'ignored a __ddValues envelope for an unknown claim',\n {\n side: this.role,\n claimId,\n receivedValues: typeof values,\n },\n );\n }\n return;\n }\n if (!claim) {\n if (!pendingContract) {\n return;\n }\n // A claim can receive more than one values message before it\n // resolves locally (for example a changedBeforeReady catch-up\n // racing the claim response). Only the first needs to be\n // complete; a claim that already has queued values has already\n // seen that first message.\n const alreadyQueued = this.#queuedValues.has(claimId);\n const invalidation = alreadyQueued\n ? invalidUpdateValueBatch(\n valueFieldNames(pendingContract),\n values,\n )\n : invalidHydrationValueBatch(\n valueFieldNames(pendingContract),\n values,\n );\n if (invalidation) {\n this.#queuedInvalidations.set(claimId, invalidation);\n this.#queuedValues.delete(claimId);\n return;\n }\n if (!this.#queuedInvalidations.has(claimId)) {\n // Merge onto whatever is already queued instead of replacing\n // it: a later partial message must not erase fields an\n // earlier queued message carried for this same claim.\n const previouslyQueued = this.#queuedValues.get(claimId);\n this.#queuedValues.set(\n claimId,\n Object.freeze({ ...previouslyQueued, ...values }),\n );\n }\n return;\n }\n\n const invalidation = claim.hydrated\n ? invalidUpdateValueBatch(claim.values.keys(), values)\n : invalidHydrationValueBatch(claim.values.keys(), values);\n if (invalidation) {\n this.#invalidateAppClaim(claimId, claim, invalidation, true);\n return;\n }\n // The key-shape requirement (complete vs. partial) is satisfied for\n // this message; every later message on this claim may be partial\n // regardless of whether a field value below fails to parse.\n claim.hydrated = true;\n\n const parsedValues: Array<\n readonly [MutableLiveValue<unknown>, unknown]\n > = [];\n for (const [field, value] of Object.entries(values)) {\n const live = claim.values.get(field);\n const schema = claim.contract.fields[field];\n if (!live || !schema || schema.kind !== 'value') {\n continue;\n }\n const parsed = validate(schema.schema, value);\n if (!parsed.ok) {\n // A last-known value cannot remain indistinguishable from a live\n // value after a contract violation. Invalidate only this claim.\n const fieldInvalidation: ClaimInvalidationError = {\n code: 'INVALID_RESULT',\n issues: prefixIssues(field, parsed.error),\n };\n this.#invalidateAppClaim(\n claimId,\n claim,\n fieldInvalidation,\n true,\n );\n return;\n }\n parsedValues.push([live, parsed.value]);\n }\n\n const changed: MutableLiveValue<unknown>[] = [];\n for (const [live, value] of parsedValues) {\n if (live.set(value)) {\n changed.push(live);\n }\n }\n for (const live of changed) {\n live.notify();\n }\n if (changed.length > 0) {\n // Every LiveValue already contains its new value. Publish one\n // claim-level change only after the complete message is applied so\n // aggregate consumers cannot observe a partly updated snapshot.\n notifyListeners(claim.valueListeners);\n }\n }\n\n receiveInvalidation(claimId: string, raw: unknown): void {\n if (!isValidIdentifier(claimId, MAX_CLAIM_ID_LENGTH)) {\n logFailure(\n 'ignored a __ddInvalidate envelope with an invalid claim id',\n {\n side: this.role,\n claimId,\n maxClaimIdLength: MAX_CLAIM_ID_LENGTH,\n },\n );\n return;\n }\n const invalidation = normalizeError<ClaimInvalidationError>(raw, [\n 'INVALID_RESULT',\n 'UNRECOGNIZED',\n ]);\n const claim = this.#appClaims.get(claimId);\n if (claim) {\n this.#invalidateAppClaim(claimId, claim, invalidation, false);\n return;\n }\n if (this.#pendingClaims.has(claimId)) {\n this.#queuedInvalidations.set(claimId, invalidation);\n }\n }\n\n async receiveClaim(\n request: WireClaimRequest,\n ): Promise<Result<WireClaimSuccess, WireClaimError>> {\n if (this.closed) {\n return err({ code: 'DISCONNECTED' });\n }\n const malformed = malformedClaimRequest(request);\n if (malformed) {\n return err(malformed);\n }\n if (this.#hostClaims.has(request.claimId)) {\n return err({\n code: 'INVALID_RESULT',\n issues: [\n {\n message: `Claim id \"${request.claimId}\" is already live.`,\n path: ['claimId'],\n },\n ],\n });\n }\n if (this.#hostClaims.size >= MAX_LIVE_HOST_CLAIMS) {\n return err({\n code: 'INVALID_RESULT',\n issues: [\n {\n message: `The peer exceeded the limit of ${MAX_LIVE_HOST_CLAIMS} simultaneous claims.`,\n path: ['claimId'],\n },\n ],\n });\n }\n const candidates = this.modules.filter(\n ({ contract }) => contract.identifier === request.identifier,\n );\n if (candidates.length === 0) {\n return err({\n code: 'PEER_LACKS_MODULE',\n identifier: request.identifier,\n });\n }\n const negotiated = negotiateVersion(\n request.version,\n candidates.map((module) => ({\n version: module.contract.version,\n module,\n })),\n );\n if (!negotiated.ok) {\n return negotiated;\n }\n const selected = negotiated.value.module;\n if (selected.signal?.aborted) {\n return err({\n code: 'INVALID_RESULT',\n issues: [\n {\n message: `The host provider for \"${request.identifier}\" is disposed.`,\n path: [],\n },\n ],\n });\n }\n const claimedFields = new Map<string, AnyContract['fields'][string]>();\n const claim: HostClaim = {\n releases: [],\n module: selected,\n fields: claimedFields,\n };\n this.#hostClaims.set(request.claimId, claim);\n if (selected.signal) {\n const onModuleDisposed = () =>\n this.#invalidateHostClaim(request.claimId, [\n {\n message: `The host provider for \"${request.identifier}\" was disposed.`,\n path: [],\n },\n ]);\n selected.signal.addEventListener('abort', onModuleDisposed, {\n once: true,\n });\n claim.releases.push(() =>\n selected.signal?.removeEventListener('abort', onModuleDisposed),\n );\n }\n const values: Record<string, unknown> = {};\n const hydration = { ready: false };\n let changedBeforeReady = false;\n let publishScheduled = false;\n // Tracks whether this claim has sent its first __ddValues message.\n // That first publish must carry every field, mirroring the\n // completeness the app requires of a claim's first values message;\n // every later publish sends only the fields named in `dirty`.\n let publishedOnce = false;\n const dirty = new Set<string>();\n const providers = new Map<\n string,\n Readonly<{\n field: ValueField<AnySchema>;\n provider: LiveValue<unknown>;\n }>\n >();\n const publishValues = () => {\n publishScheduled = false;\n if (!this.#hostClaims.has(request.claimId)) {\n return;\n }\n const isHydrationPublish = !publishedOnce;\n if (!isHydrationPublish && dirty.size === 0) {\n return;\n }\n const fieldsToSend = isHydrationPublish\n ? [...providers.keys()]\n : [...dirty];\n publishedOnce = true;\n dirty.clear();\n // Avoid validating and cloning unchanged fields.\n const nextValues: Record<string, unknown> = {};\n for (const name of fieldsToSend) {\n const entry = providers.get(name);\n if (!entry) {\n continue;\n }\n const next = readProvidedValue(\n name,\n entry.field.schema,\n entry.provider,\n );\n if (!next.ok) {\n this.#invalidateHostClaim(\n request.claimId,\n reportInvalidHostValue(\n request.identifier,\n name,\n next.error,\n ),\n );\n return;\n }\n nextValues[name] = next.value;\n }\n this.send('__ddValues', () =>\n this.remote['__ddValues'](request.claimId, nextValues),\n );\n };\n const schedulePublish = () => {\n if (!this.#hostClaims.has(request.claimId)) {\n return;\n }\n if (!hydration.ready) {\n changedBeforeReady = true;\n return;\n }\n if (publishScheduled) {\n return;\n }\n publishScheduled = true;\n globalThis.queueMicrotask(publishValues);\n };\n\n for (const name of request.fields) {\n const field = selected.contract.fields[name];\n if (!field) {\n this.receiveRelease(request.claimId);\n return err({ code: 'CONTRACT_INCOMPATIBLE', field: name });\n }\n claimedFields.set(name, field);\n if (field.kind === 'function') {\n const provider = Object.hasOwn(selected.implementation, name)\n ? selected.implementation[name]\n : undefined;\n if (\n !isRecord(provider) ||\n typeof provider.invoke !== 'function'\n ) {\n this.receiveRelease(request.claimId);\n return err({\n code: 'INVALID_RESULT',\n issues: [\n {\n message:\n 'The host implementation is not a callable function field.',\n path: [name],\n },\n ],\n });\n }\n continue;\n }\n const provider = (\n Object.hasOwn(selected.implementation, name)\n ? selected.implementation[name]\n : undefined\n ) as LiveValue<unknown> | undefined;\n if (\n !provider ||\n typeof provider.get !== 'function' ||\n typeof provider.subscribe !== 'function'\n ) {\n this.receiveRelease(request.claimId);\n return err({\n code: 'INVALID_RESULT',\n issues: [\n {\n message:\n 'The host implementation is not a live value.',\n path: [name],\n },\n ],\n });\n }\n providers.set(name, { field, provider });\n let unsubscribe: unknown;\n try {\n unsubscribe = provider.subscribe(() => {\n dirty.add(name);\n schedulePublish();\n });\n } catch (error) {\n this.receiveRelease(request.claimId);\n return err({\n code: 'INVALID_RESULT',\n issues: reportInvalidHostValue(\n request.identifier,\n name,\n error,\n ),\n });\n }\n if (typeof unsubscribe !== 'function') {\n this.receiveRelease(request.claimId);\n return err({\n code: 'INVALID_RESULT',\n issues: [\n {\n message:\n 'The host value provider did not return an unsubscribe function.',\n path: [name],\n },\n ],\n });\n }\n if (this.#hostClaims.get(request.claimId) !== claim) {\n teardown(\n `unsubscribe for interrupted claim ${request.claimId}`,\n unsubscribe as Unsubscribe,\n );\n return this.closed\n ? err({ code: 'DISCONNECTED' })\n : err({\n code: 'INVALID_RESULT',\n issues: [\n {\n message: `The host provider for \"${request.identifier}\" was disposed during claim setup.`,\n path: [],\n },\n ],\n });\n }\n claim.releases.push(unsubscribe as Unsubscribe);\n const initial = readProvidedValue(name, field.schema, provider);\n if (!initial.ok) {\n this.receiveRelease(request.claimId);\n return err({\n code: 'INVALID_RESULT',\n issues: reportInvalidHostValue(\n request.identifier,\n name,\n initial.error,\n ),\n });\n }\n values[name] = initial.value;\n }\n\n hydration.ready = true;\n if (changedBeforeReady) {\n schedulePublish();\n }\n return success({ values });\n }\n\n async receiveFunctionCall(\n request: WireFunctionRequest,\n ): Promise<ServedFunctionCall> {\n if (this.closed) {\n return err({ code: 'DISCONNECTED' });\n }\n const malformed = malformedFunctionRequest(request);\n if (malformed) {\n return err(malformed);\n }\n const claim = this.#hostClaims.get(request.claimId);\n if (!claim) {\n return err({ code: 'DISCONNECTED' });\n }\n const field = claim.fields.get(request.field);\n if (!field || field.kind !== 'function') {\n return err({\n code: 'CONTRACT_INCOMPATIBLE',\n field: request.field,\n });\n }\n if (this.#hostFunctionCalls.has(request.callId)) {\n return err({\n code: 'INVALID_ARGUMENT',\n issues: [\n {\n message: `Function call id \"${request.callId}\" is already active.`,\n path: ['callId'],\n },\n ],\n });\n }\n if (liveHostFunctionCalls >= MAX_LIVE_HOST_FUNCTION_CALLS) {\n return err({\n code: 'FUNCTION_FAILED',\n field: request.field,\n });\n }\n const parsedInputs = validateFunctionInputs(\n request.field,\n field,\n request.inputs,\n );\n if (!parsedInputs.ok) {\n // Standard Schema validators may echo app-controlled values in\n // their issues, so diagnostics retain only non-sensitive metadata.\n logFailure('the host rejected the inputs of a function call', {\n side: this.role,\n claimId: request.claimId,\n callId: request.callId,\n target: `${claim.module.contract.identifier}.${request.field}`,\n issueCount: parsedInputs.error.length,\n });\n return err({\n code: 'INVALID_ARGUMENT',\n issues: [\n {\n message:\n 'The function inputs do not satisfy the host schema.',\n path: [request.field, 'inputs'],\n },\n ],\n });\n }\n const provider = Object.hasOwn(\n claim.module.implementation,\n request.field,\n )\n ? claim.module.implementation[request.field]\n : undefined;\n if (!isRecord(provider) || typeof provider.invoke !== 'function') {\n return err({\n code: 'CONTRACT_INCOMPATIBLE',\n field: request.field,\n });\n }\n\n type HandlerOutcome =\n | Readonly<{ status: 'returned'; value: unknown }>\n | Readonly<{ status: 'threw'; cause: unknown }>\n | Readonly<{\n status: 'interrupted';\n reason: 'cancelled' | 'timed-out';\n }>;\n const controller = new AbortController();\n let resolveInterruption: (outcome: HandlerOutcome) => void = () =>\n undefined;\n const interruption = new Promise<HandlerOutcome>((resolve) => {\n resolveInterruption = resolve;\n });\n const activeCall: HostFunctionCall = {\n claimId: request.claimId,\n controller,\n interrupt(reason) {\n if (controller.signal.aborted) {\n return;\n }\n controller.abort();\n resolveInterruption({ status: 'interrupted', reason });\n },\n };\n liveHostFunctionCalls += 1;\n this.#hostFunctionCalls.set(request.callId, activeCall);\n const callTimeoutMs = resolveFunctionCallTimeoutMs(field);\n // Armed before invoking the provider so a synchronously slow\n // implementation still counts against the deadline, rather than\n // getting a fresh deadline once it finally returns.\n const deadline = globalThis.performance.now() + callTimeoutMs;\n const timer = globalThis.setTimeout(\n () => activeCall.interrupt('timed-out'),\n callTimeoutMs,\n );\n let handlerOutcome: Promise<HandlerOutcome>;\n try {\n const returned = provider.invoke(\n parsedInputs.value,\n Object.freeze({ signal: controller.signal }),\n );\n // No implementation -- sync or async -- ever yields to the timer\n // above before this line: a synchronous one's return/throw always\n // reaches here on the same tick, and an async one's own\n // synchronous prelude (everything before its first real yield)\n // does too, since `provider.invoke()` itself has already\n // returned by the time we get here either way. An implementation\n // that blocked past the deadline in that prelude must be caught\n // here instead of waiting for a macrotask that a resolved (or\n // same-tick-resolving) promise will always beat in the race\n // below.\n if (globalThis.performance.now() >= deadline) {\n activeCall.interrupt('timed-out');\n }\n // A handler-returned promise can still settle late without ever\n // yielding to the timer's macrotask: a long chain of *only*\n // microtasks (no real async I/O) fully drains before the engine\n // even considers a pending macrotask, no matter how much wall\n // clock time that chain took. Re-checking the deadline here, at\n // settlement rather than only at invocation, catches that case:\n // a late settlement is relabeled `timed-out` instead of\n // reporting success past the caller's own deadline.\n handlerOutcome = Promise.resolve(returned).then(\n (value): HandlerOutcome => {\n if (globalThis.performance.now() >= deadline) {\n // A late-settling handler must actually abort the\n // provider's signal, not just relabel the outcome:\n // interrupt() is what drives context.signal.aborted,\n // and it's idempotent, so it's safe to call even if\n // a race (the timeout timer, or an app cancel) has\n // already called it. The #hostFunctionCalls /\n // liveHostFunctionCalls bookkeeping below is not\n // conditional on this call -- handlerOutcome.finally()\n // runs it unconditionally once this promise settles.\n activeCall.interrupt('timed-out');\n // `value` is discarded right here, at the moment it\n // stops being reachable by any later cleanup: once\n // relabeled 'interrupted', this outcome carries no\n // value for the `outcome.status === 'interrupted'`\n // handler below to find and discard. Any MessagePort\n // in it must be closed now or it leaks permanently.\n discardFunctionResult(value);\n return { status: 'interrupted', reason: 'timed-out' };\n }\n return { status: 'returned', value };\n },\n (cause: unknown): HandlerOutcome => {\n if (globalThis.performance.now() >= deadline) {\n activeCall.interrupt('timed-out');\n return { status: 'interrupted', reason: 'timed-out' };\n }\n return { status: 'threw', cause };\n },\n );\n } catch (cause) {\n if (globalThis.performance.now() >= deadline) {\n activeCall.interrupt('timed-out');\n }\n handlerOutcome = Promise.resolve({ status: 'threw', cause });\n }\n const trackedHandlerOutcome = handlerOutcome.finally(() => {\n liveHostFunctionCalls -= 1;\n if (this.#hostFunctionCalls.get(request.callId) === activeCall) {\n this.#hostFunctionCalls.delete(request.callId);\n }\n });\n const outcome = await Promise.race([\n trackedHandlerOutcome,\n interruption,\n ]);\n globalThis.clearTimeout(timer);\n\n if (outcome.status === 'interrupted') {\n trackedHandlerOutcome.then((lateOutcome) => {\n if (lateOutcome.status === 'returned') {\n discardFunctionResult(lateOutcome.value);\n }\n });\n return outcome.reason === 'timed-out'\n ? err({\n code: 'TIMED_OUT',\n timeoutMs: callTimeoutMs,\n })\n : err({ code: 'DISCONNECTED' });\n }\n if (\n this.closed ||\n controller.signal.aborted ||\n this.#hostClaims.get(request.claimId) !== claim\n ) {\n if (outcome.status === 'returned') {\n discardFunctionResult(outcome.value);\n }\n return err({ code: 'DISCONNECTED' });\n }\n if (outcome.status === 'threw') {\n // The thrown value never crosses the boundary; the app receives\n // only FUNCTION_FAILED, so this is the only place it is readable.\n logFailure('a host function implementation threw', {\n side: this.role,\n claimId: request.claimId,\n callId: request.callId,\n target: `${claim.module.contract.identifier}.${request.field}`,\n cause: describeCause(outcome.cause),\n });\n return err({\n code: 'FUNCTION_FAILED',\n field: request.field,\n });\n }\n const prepared = prepareFunctionResult(\n request.field,\n field,\n outcome.value,\n );\n if (!prepared.ok) {\n logFailure('a host function returned an invalid result', {\n side: this.role,\n claimId: request.claimId,\n callId: request.callId,\n target: `${claim.module.contract.identifier}.${request.field}`,\n issues: prepared.error,\n });\n return err({\n code: 'INVALID_RESULT',\n issues: [\n {\n message:\n 'The host function returned a result that does not satisfy its schema.',\n path: [request.field],\n },\n ],\n });\n }\n return prepared.value;\n }\n\n receiveFunctionCancel(request: WireFunctionCancel): void {\n if (\n !isRecord(request) ||\n !isValidIdentifier(request.claimId, MAX_CLAIM_ID_LENGTH) ||\n !isValidIdentifier(request.callId, MAX_CALL_ID_LENGTH)\n ) {\n logFailure('ignored a malformed __ddCancel envelope', {\n side: this.role,\n request: isRecord(request)\n ? {\n claimId: request.claimId,\n callId: request.callId,\n }\n : { malformed: true, received: typeof request },\n });\n return;\n }\n const activeCall = this.#hostFunctionCalls.get(request.callId);\n if (activeCall?.claimId === request.claimId) {\n activeCall.interrupt('cancelled');\n }\n }\n\n #invalidateHostClaim(claimId: string, issues: readonly Issue[]): void {\n const claim = this.#hostClaims.get(claimId);\n if (!claim) {\n return;\n }\n logFailure('the host invalidated a claim it was serving', {\n side: this.role,\n claimId,\n identifier: claim.module.contract.identifier,\n version: claim.module.contract.version,\n issues,\n });\n this.receiveRelease(claimId);\n this.send('__ddInvalidate', () =>\n this.remote['__ddInvalidate'](claimId, {\n code: 'INVALID_RESULT',\n issues,\n }),\n );\n }\n\n receiveRelease(claimId: string): void {\n if (!isValidIdentifier(claimId, MAX_CLAIM_ID_LENGTH)) {\n logFailure('ignored a __ddRelease with an invalid claim id', {\n side: this.role,\n claimId,\n maxClaimIdLength: MAX_CLAIM_ID_LENGTH,\n });\n return;\n }\n const claim = this.#hostClaims.get(claimId);\n if (!claim) {\n return;\n }\n this.#hostClaims.delete(claimId);\n for (const activeCall of this.#hostFunctionCalls.values()) {\n if (activeCall.claimId === claimId) {\n activeCall.interrupt('cancelled');\n }\n }\n for (const release of claim.releases) {\n teardown(`unsubscribe for claim ${claimId}`, release);\n }\n }\n}\n", "import {\n assertValidTimerDelay,\n CONNECT_TIMEOUT_MS,\n PROTOCOL_VERSION,\n RECONNECT_GIVE_UP_AFTER_MS,\n RECONNECT_MAX_RETRY_MS,\n RECONNECT_RETRY_MS,\n} from './config';\nimport { invalidHostModule } from './contract';\nimport { describeError, logFailure, logWarning } from './diagnostics';\nimport {\n APP_DOCUMENT_ID,\n acceptHostBootstrapRequest,\n requestBootstrapControlPort,\n} from './handshake/bootstrap';\nimport {\n negotiateAppProtocol,\n negotiateHostProtocol,\n} from './handshake/compatibility';\nimport { connectApp, connectHost } from './protocol/establish';\nimport { PRODUCTION_HEARTBEAT } from './protocol/heartbeat';\nimport { err, isRecord, notifyListeners } from './shared';\nimport type {\n AppConnectionHandle,\n AppConnectionState,\n ConnectError,\n HostListenOptions,\n HostListener,\n HostModule,\n ManagedAppConnection,\n ManagedHostConnection,\n Result,\n SurfaceId,\n Unsubscribe,\n} from './types';\n\nexport type { HostListenOptions, HostListener, SurfaceId } from './types';\nexport type {\n ConnectDomain,\n ConnectResponsibleSide,\n ManualRetryPolicy,\n NormalizedConnectError,\n SanitizedConnectDetail,\n} from './connect-error-normalizer';\nexport { normalizeConnectError } from './connect-error-normalizer';\n\n/**\n * What this bundle can speak. The prelude answers a peer with this list, so a\n * peer with no overlap learns which side must update instead of timing out.\n * Adding a protocol means adding it here and branching where it is run.\n */\nconst SUPPORTED_PROTOCOLS = [PROTOCOL_VERSION] as const;\n\n/**\n * Phases 2 and 3: agree a protocol on the control port, then run it on the\n * operational port the host transferred. `negotiate*` closes the control port\n * on every path, so the caller never owns it after this point.\n */\nexport async function connectAppControlPort(\n controlPort: MessagePort,\n signal: AbortSignal,\n timeoutMs: number = CONNECT_TIMEOUT_MS,\n): Promise<Result<ManagedAppConnection, ConnectError>> {\n if (signal.aborted) {\n controlPort.close();\n return err({ code: 'ABORTED' });\n }\n const compatible = await negotiateAppProtocol(\n controlPort,\n SUPPORTED_PROTOCOLS,\n timeoutMs,\n signal,\n );\n if (!compatible.ok) {\n return compatible;\n }\n return connectApp(\n compatible.value.operationalPort,\n timeoutMs,\n signal,\n PRODUCTION_HEARTBEAT,\n );\n}\n\nexport async function connectHostControlPort(\n controlPort: MessagePort,\n modules: readonly HostModule[],\n surfaceId: SurfaceId | undefined,\n signal: AbortSignal,\n timeoutMs: number = CONNECT_TIMEOUT_MS,\n): Promise<Result<ManagedHostConnection, ConnectError>> {\n if (signal.aborted) {\n controlPort.close();\n return err({ code: 'ABORTED' });\n }\n const invalidModule = invalidHostModule(modules);\n if (invalidModule) {\n controlPort.close();\n return err({ code: 'TRANSPORT_FAILED', cause: invalidModule });\n }\n const compatible = await negotiateHostProtocol(\n controlPort,\n SUPPORTED_PROTOCOLS,\n timeoutMs,\n signal,\n );\n if (!compatible.ok) {\n return compatible;\n }\n return connectHost(\n compatible.value.operationalPort,\n modules,\n surfaceId,\n timeoutMs,\n signal,\n PRODUCTION_HEARTBEAT,\n );\n}\n\nclass RetryBackoff {\n #nextDelayMs?: number;\n\n next(): number {\n const delayMs = this.#nextDelayMs ?? RECONNECT_RETRY_MS;\n this.#nextDelayMs = Math.min(delayMs * 2, RECONNECT_MAX_RETRY_MS);\n return delayMs;\n }\n\n reset(): void {\n this.#nextDelayMs = undefined;\n }\n}\n\nfunction isEmbeddedFrame(): boolean {\n return (\n typeof globalThis.window !== 'undefined' &&\n globalThis.window.parent !== globalThis.window\n );\n}\n\nfunction isRetryableConnectError(error: ConnectError): boolean {\n switch (error.code) {\n case 'TIMED_OUT':\n case 'TRANSPORT_FAILED':\n case 'DISCONNECTED':\n case 'UNRECOGNIZED':\n return true;\n case 'ORIGIN_REJECTED':\n case 'APP_PROTOCOL_TOO_OLD':\n case 'HOST_PROTOCOL_TOO_OLD':\n case 'PROTOCOL_INCOMPATIBLE':\n case 'ABORTED':\n return false;\n default: {\n const exhaustive: never = error;\n return exhaustive;\n }\n }\n}\n\nclass AppConnectionHandleImplementation implements AppConnectionHandle {\n readonly #controller = new AbortController();\n readonly #listeners = new Set<() => void>();\n readonly #backoff = new RetryBackoff();\n #snapshot: AppConnectionState = { state: 'connecting' };\n #active?: ManagedAppConnection;\n #attemptController?: AbortController;\n #retryTimer?: ReturnType<typeof globalThis.setTimeout>;\n #giveUpTimer?: ReturnType<typeof globalThis.setTimeout>;\n #lastError?: ConnectError;\n #attempts = 0;\n #attempting = false;\n #gaveUp = false;\n\n constructor() {\n if (!isEmbeddedFrame()) {\n this.#snapshot = { state: 'not-embedded' };\n return;\n }\n this.#startGiveUpTimer();\n this.#attempt();\n }\n\n getSnapshot(): AppConnectionState {\n return this.#snapshot;\n }\n\n subscribe(onChange: () => void): Unsubscribe {\n this.#listeners.add(onChange);\n return () => {\n this.#listeners.delete(onChange);\n };\n }\n\n close(): void {\n if (this.#snapshot.state === 'closed') {\n return;\n }\n this.#controller.abort();\n this.#attemptController?.abort();\n this.#attemptController = undefined;\n this.#clearRetryTimer();\n this.#clearGiveUpTimer();\n const active = this.#active;\n this.#active = undefined;\n this.#setSnapshot({ state: 'closed' });\n active?.close();\n this.#listeners.clear();\n }\n\n // Phase 1 then phases 2-3, mirroring the host listener. The control port\n // is owned by whichever phase holds it: a failed bootstrap closes its own\n // ports, and protocol negotiation closes the control port on every path.\n async #connect(\n signal: AbortSignal,\n ): Promise<Result<ManagedAppConnection, ConnectError>> {\n const control = await requestBootstrapControlPort(\n globalThis.window,\n APP_DOCUMENT_ID,\n signal,\n );\n return control.ok\n ? connectAppControlPort(control.value, signal)\n : control;\n }\n\n async #attempt(): Promise<void> {\n if (\n this.#controller.signal.aborted ||\n this.#gaveUp ||\n this.#attempting ||\n this.#active\n ) {\n return;\n }\n this.#attempting = true;\n this.#attempts += 1;\n const attemptController = new AbortController();\n this.#attemptController = attemptController;\n let result: Result<ManagedAppConnection, ConnectError>;\n try {\n result = await this.#connect(attemptController.signal);\n } catch (cause) {\n result = {\n ok: false,\n error: { code: 'TRANSPORT_FAILED', cause },\n };\n }\n this.#attempting = false;\n if (this.#attemptController === attemptController) {\n this.#attemptController = undefined;\n }\n\n // A terminal owner may race a late attempt result; the late connection\n // must be closed because no subsequent state can own it.\n if (this.#controller.signal.aborted || this.#gaveUp) {\n if (result.ok) {\n result.value.close();\n }\n return;\n }\n if (!result.ok) {\n this.#lastError = result.error;\n if (!isRetryableConnectError(result.error)) {\n this.#clearGiveUpTimer();\n logFailure('the app connection was rejected', {\n side: 'app',\n attempt: this.#attempts,\n retryable: false,\n error: describeError(result.error),\n });\n this.#setSnapshot({\n state: 'rejected',\n error: result.error,\n });\n return;\n }\n this.#setSnapshot(\n this.#snapshot.state === 'reconnecting'\n ? { state: 'reconnecting', lastError: result.error }\n : { state: 'connecting', error: result.error },\n );\n this.#scheduleRetry();\n return;\n }\n\n this.#active = result.value;\n this.#lastError = undefined;\n this.#backoff.reset();\n this.#clearGiveUpTimer();\n const onConnectionClosed = () => {\n if (\n this.#controller.signal.aborted ||\n this.#active !== result.value\n ) {\n return;\n }\n this.#active = undefined;\n this.#lastError = { code: 'DISCONNECTED' };\n logWarning('the app lost its established connection', {\n side: 'app',\n attempt: this.#attempts,\n surfaceId: result.value.surfaceId,\n });\n this.#startGiveUpTimer();\n this.#setSnapshot({\n state: 'reconnecting',\n lastError: this.#lastError,\n });\n this.#scheduleRetry();\n };\n result.value.closeSignal.addEventListener('abort', onConnectionClosed, {\n once: true,\n });\n // AbortSignal events are not replayed to late listeners. Read its\n // durable state after subscribing so a connection that closed while\n // the async result propagated back cannot be published as active.\n if (result.value.closeSignal.aborted) {\n onConnectionClosed();\n return;\n }\n this.#setSnapshot({\n state: 'connected',\n connection: result.value.connection,\n surfaceId: result.value.surfaceId,\n });\n }\n\n #scheduleRetry(): void {\n if (\n this.#controller.signal.aborted ||\n this.#gaveUp ||\n this.#retryTimer !== undefined\n ) {\n return;\n }\n const delayMs = this.#backoff.next();\n logWarning('retrying the app connection', {\n side: 'app',\n state: this.#snapshot.state,\n failedAttempts: this.#attempts,\n retryInMs: delayMs,\n giveUpAfterMs: RECONNECT_GIVE_UP_AFTER_MS,\n error: this.#lastError && describeError(this.#lastError),\n });\n this.#retryTimer = globalThis.setTimeout(() => {\n this.#retryTimer = undefined;\n this.#attempt();\n }, delayMs);\n }\n\n #clearRetryTimer(): void {\n if (this.#retryTimer !== undefined) {\n globalThis.clearTimeout(this.#retryTimer);\n this.#retryTimer = undefined;\n }\n }\n\n #startGiveUpTimer(): void {\n if (this.#giveUpTimer !== undefined) {\n return;\n }\n this.#giveUpTimer = globalThis.setTimeout(() => {\n this.#giveUpTimer = undefined;\n this.#giveUp();\n }, RECONNECT_GIVE_UP_AFTER_MS);\n }\n\n #clearGiveUpTimer(): void {\n if (this.#giveUpTimer !== undefined) {\n globalThis.clearTimeout(this.#giveUpTimer);\n this.#giveUpTimer = undefined;\n }\n }\n\n #giveUp(): void {\n if (\n this.#controller.signal.aborted ||\n this.#snapshot.state === 'connected' ||\n this.#snapshot.state === 'closed'\n ) {\n return;\n }\n this.#gaveUp = true;\n this.#clearRetryTimer();\n this.#attemptController?.abort();\n this.#attemptController = undefined;\n const error: ConnectError = this.#lastError ?? {\n code: 'TIMED_OUT',\n timeoutMs: RECONNECT_GIVE_UP_AFTER_MS,\n };\n logFailure('the app gave up connecting to its Datadog host', {\n side: 'app',\n state: this.#snapshot.state,\n failedAttempts: this.#attempts,\n gaveUpAfterMs: RECONNECT_GIVE_UP_AFTER_MS,\n error: describeError(error),\n });\n this.#setSnapshot({ state: 'rejected', error });\n }\n\n #setSnapshot(next: AppConnectionState): void {\n if (this.#snapshot === next) {\n return;\n }\n this.#snapshot = next;\n notifyListeners(this.#listeners);\n }\n}\n\nclass HostListenerImplementation implements HostListener {\n readonly #errorListeners = new Set<(error: ConnectError) => void>();\n readonly #readyListeners = new Set<() => void>();\n #active?: ManagedHostConnection;\n #attemptController?: AbortController;\n #attemptGeneration = 0;\n #closed = false;\n\n constructor(private readonly options: HostListenOptions) {\n if (options.signal?.aborted) {\n this.#closed = true;\n return;\n }\n options.signal?.addEventListener('abort', this.#onExternalAbort, {\n once: true,\n });\n // contentWindow can be null before the iframe is attached to the DOM\n // and can change across navigations, so it is read fresh on every\n // bootstrap request rather than captured once here.\n globalThis.window.addEventListener('message', this.#onBootstrapRequest);\n }\n\n get #target(): Window | null {\n return this.options.peer.frame.contentWindow;\n }\n\n onError(listener: (error: ConnectError) => void): Unsubscribe {\n if (this.#closed) {\n return () => undefined;\n }\n this.#errorListeners.add(listener);\n return () => {\n this.#errorListeners.delete(listener);\n };\n }\n\n onReady(listener: () => void): Unsubscribe {\n if (this.#closed) {\n return () => undefined;\n }\n this.#readyListeners.add(listener);\n // A late subscriber -- one that calls `onReady` after this session's\n // operational handshake already completed -- must not miss it: the\n // session is still active right now, so replay immediately rather\n // than making the caller race the next reconnect to find out.\n if (this.#active) {\n notifyListeners([listener]);\n }\n return () => {\n this.#readyListeners.delete(listener);\n };\n }\n\n close(): void {\n if (this.#closed) {\n return;\n }\n this.#closed = true;\n this.#attemptGeneration += 1;\n this.#attemptController?.abort();\n this.#attemptController = undefined;\n this.options.signal?.removeEventListener(\n 'abort',\n this.#onExternalAbort,\n );\n globalThis.window.removeEventListener(\n 'message',\n this.#onBootstrapRequest,\n );\n const active = this.#active;\n this.#active = undefined;\n active?.close();\n this.#errorListeners.clear();\n this.#readyListeners.clear();\n }\n\n readonly #onExternalAbort = (): void => {\n this.close();\n };\n\n readonly #onBootstrapRequest = (event: MessageEvent<unknown>): void => {\n if (this.#closed || !this.#target) {\n return;\n }\n const accepted = acceptHostBootstrapRequest(\n this.#target,\n this.options.peer.appOrigin,\n event,\n this.options.peer.allowOpaqueOrigin,\n );\n if (!accepted) {\n return;\n }\n if (!accepted.ok) {\n this.#notifyError(accepted.error);\n return;\n }\n // `documentId` is deliberately not an authorization or sequencing\n // signal. Every document loaded into the configured customer frame is\n // in the same untrusted class; exact WindowProxy/origin validation is\n // the bootstrap boundary. Correlating identity-less iframe `load`\n // events with document IDs would not add authority and previously\n // introduced navigation-order races.\n this.#startConnection(accepted.value.controlPort);\n };\n\n #startConnection(controlPort: MessagePort): void {\n // Any valid bootstrap may replace the current private-port session.\n // The operational port and heartbeat, rather than page lifecycle,\n // define the lifetime of the connection being superseded here.\n this.#supersedeCurrentConnection();\n const attemptController = new AbortController();\n this.#attemptController = attemptController;\n const generation = ++this.#attemptGeneration;\n this.#establishConnection(\n controlPort,\n attemptController,\n generation,\n ).catch((error: unknown) => {\n globalThis.queueMicrotask(() => {\n throw error;\n });\n });\n }\n\n async #establishConnection(\n controlPort: MessagePort,\n attemptController: AbortController,\n generation: number,\n ): Promise<void> {\n let result: Result<ManagedHostConnection, ConnectError>;\n try {\n result = await connectHostControlPort(\n controlPort,\n this.options.modules,\n this.options.surfaceId,\n attemptController.signal,\n this.options.timeoutMs,\n );\n } catch (cause) {\n controlPort.close();\n result = {\n ok: false,\n error: { code: 'TRANSPORT_FAILED', cause },\n };\n }\n if (\n this.#closed ||\n generation !== this.#attemptGeneration ||\n attemptController.signal.aborted\n ) {\n if (result.ok) {\n result.value.close();\n }\n return;\n }\n this.#attemptController = undefined;\n if (!result.ok) {\n if (result.error.code !== 'ABORTED') {\n this.#notifyError(result.error);\n }\n return;\n }\n\n // An AbortSignal never replays a past abort to a listener added\n // after the fact, so a connection that's already closed by the time\n // we got here would never fire the listener below on its own.\n // Checked before publishing it as #active at all, rather than\n // publishing then immediately unpublishing, so a connection that's\n // already dead never gets a false-positive ready notification.\n if (result.value.closeSignal.aborted) {\n return;\n }\n this.#active = result.value;\n result.value.closeSignal.addEventListener(\n 'abort',\n () => {\n if (this.#closed || this.#active !== result.value) {\n return;\n }\n this.#active = undefined;\n },\n { once: true },\n );\n notifyListeners(this.#readyListeners);\n }\n\n #supersedeCurrentConnection(): void {\n this.#attemptGeneration += 1;\n this.#attemptController?.abort();\n this.#attemptController = undefined;\n const active = this.#active;\n this.#active = undefined;\n if (active) {\n // A newly accepted bootstrap owns the listener's one session. It\n // also closes a healthy predecessor, so make that replacement\n // visible next to the app-side disconnect it causes.\n logWarning('the host superseded a live app connection', {\n side: 'host',\n surfaceId: this.options.surfaceId,\n });\n }\n active?.close();\n }\n\n #notifyError(error: ConnectError): void {\n logFailure('the host could not connect to an app frame', {\n side: 'host',\n surfaceId: this.options.surfaceId,\n appOrigin: this.options.peer.appOrigin,\n allowOpaqueOrigin: this.options.peer.allowOpaqueOrigin ?? false,\n modules: Array.isArray(this.options.modules)\n ? this.options.modules.map((module) =>\n isRecord(module) &&\n isRecord(module.contract) &&\n typeof module.contract.identifier === 'string' &&\n typeof module.contract.version === 'number'\n ? `${module.contract.identifier}@${module.contract.version}`\n : '(malformed host module)',\n )\n : '(malformed host modules)',\n observedListeners: this.#errorListeners.size,\n error: describeError(error),\n });\n notifyListeners(this.#errorListeners, error);\n }\n}\n\nexport const browserAppEmbedding: Readonly<{\n connect(): AppConnectionHandle;\n}> = /* @__PURE__ */ Object.freeze({\n connect(): AppConnectionHandle {\n return new AppConnectionHandleImplementation();\n },\n});\n\nexport const browserHostEmbedding: Readonly<{\n listen(options: HostListenOptions): HostListener;\n}> = /* @__PURE__ */ Object.freeze({\n listen(options: HostListenOptions): HostListener {\n // Validate eagerly: malformed options should fail at registration,\n // not surface later once an app actually tries to connect.\n assertValidTimerDelay(\n 'HostListenOptions.timeoutMs',\n options.timeoutMs ?? CONNECT_TIMEOUT_MS,\n );\n const invalidModule = invalidHostModule(options.modules);\n if (invalidModule) {\n throw invalidModule;\n }\n return new HostListenerImplementation(options);\n },\n});\n", "import type {\n ClaimError,\n ConnectError,\n ContractVersion,\n EmbeddingError,\n Issue,\n WireClaimError,\n} from './types';\n\nfunction formatVersions(versions: readonly ContractVersion[]): string {\n return versions.join(', ');\n}\n\nfunction formatIssues(issues: readonly Issue[]): string {\n return issues\n .map(\n (issue) =>\n `${issue.path.length > 0 ? issue.path.join('.') : '(root)'}: ${issue.message}`,\n )\n .join('; ');\n}\n\n// This must never throw: it backs TRANSPORT_FAILED's message, which is the\n// one guaranteed-stable UNKNOWN error toEmbeddingError() promises callers.\nfunction boundedCauseText(cause: unknown): string {\n let text: string;\n try {\n if (cause instanceof Error) {\n text = cause.message || cause.name;\n } else if (typeof cause === 'string') {\n text = cause;\n } else {\n try {\n text = JSON.stringify(cause) ?? String(cause);\n } catch {\n text = Object.prototype.toString.call(cause);\n }\n }\n } catch {\n text = '(cause could not be described)';\n }\n return text.length > 200 ? `${text.slice(0, 200)}\u2026` : text;\n}\n\nexport function toEmbeddingError(error: ConnectError): EmbeddingError {\n switch (error.code) {\n case 'TIMED_OUT':\n return {\n code: 'TIMED_OUT',\n action: 'retry',\n message: `TIMED_OUT: the Datadog host did not complete the connection within ${error.timeoutMs}ms. Reload the app to try again.`,\n };\n case 'ORIGIN_REJECTED':\n return {\n code: 'ORIGIN_REJECTED',\n action: 'contact-support',\n message: `ORIGIN_REJECTED: the embedding connection failed origin validation for \"${error.origin}\". Screenshot this message and contact support.`,\n };\n case 'APP_PROTOCOL_TOO_OLD':\n return {\n code: 'APP_PROTOCOL_TOO_OLD',\n action: 'update-app',\n message: `APP_PROTOCOL_TOO_OLD: this app supports embedding protocols ${error.appProtocols.join(', ')}, while the Datadog host requires ${error.hostProtocols.join(', ')}. Update @datadog/apps-frontend, rebuild this app, and upload the new bundle.`,\n };\n case 'HOST_PROTOCOL_TOO_OLD':\n return {\n code: 'HOST_PROTOCOL_TOO_OLD',\n action: 'contact-support',\n message: `HOST_PROTOCOL_TOO_OLD: this app supports embedding protocols ${error.appProtocols.join(', ')}, newer than the Datadog host's ${error.hostProtocols.join(', ')}. Rebuilding the app will not fix this; screenshot this message and contact support.`,\n };\n case 'PROTOCOL_INCOMPATIBLE':\n return {\n code: 'PROTOCOL_INCOMPATIBLE',\n action: 'contact-support',\n message: `PROTOCOL_INCOMPATIBLE: this app supports embedding protocols ${error.appProtocols.join(', ')}, while the Datadog host supports ${error.hostProtocols.join(', ')}. The sets do not overlap; screenshot this message and contact support.`,\n };\n case 'DISCONNECTED':\n return {\n code: 'CONNECTION_LOST',\n action: 'retry',\n message:\n 'CONNECTION_LOST: the Datadog host stopped responding and the connection could not be re-established. Reload the app to try again.',\n };\n case 'TRANSPORT_FAILED':\n return {\n code: 'UNKNOWN',\n action: 'contact-support',\n message: `TRANSPORT_FAILED: the local embedding transport failed (${boundedCauseText(error.cause)}). Screenshot this message and contact support.`,\n };\n case 'UNRECOGNIZED':\n return {\n code: 'UNKNOWN',\n action: 'contact-support',\n message: `UNRECOGNIZED: the peer reported failure code \"${error.rawCode}\", which this app build does not know. Screenshot this message and contact support.`,\n };\n case 'ABORTED':\n return {\n code: 'UNKNOWN',\n action: 'contact-support',\n message:\n 'ABORTED: the embedding connection was cancelled unexpectedly. Screenshot this message and contact support.',\n };\n default: {\n const exhaustive: never = error;\n return exhaustive;\n }\n }\n}\n\nexport function toClaimError(\n error: Exclude<\n WireClaimError,\n Readonly<{ code: 'PEER_LACKS_MODULE' | 'ABORTED' }>\n >,\n): ClaimError {\n switch (error.code) {\n case 'APP_MAJOR_TOO_OLD':\n return {\n code: 'APP_MAJOR_TOO_OLD',\n action: 'update-app',\n requestedVersion: error.wanted,\n availableVersions: error.hostVersions,\n message: `APP_MAJOR_TOO_OLD: this app's claim requests v${error.wanted}, while the host now offers ${formatVersions(error.hostVersions)}. Update @datadog/apps-frontend, rebuild this app, and upload the new bundle.`,\n };\n case 'HOST_MAJOR_TOO_OLD':\n return {\n code: 'HOST_MAJOR_TOO_OLD',\n action: 'contact-support',\n requestedVersion: error.wanted,\n availableVersions: error.hostVersions,\n message: `HOST_MAJOR_TOO_OLD: this app's claim requests v${error.wanted}, newer than the host's ${formatVersions(error.hostVersions)}. Rebuilding the app will not fix this; screenshot this message and contact support.`,\n };\n case 'CONTRACT_INCOMPATIBLE':\n return {\n code: 'UNKNOWN',\n action: 'contact-support',\n message: `CONTRACT_INCOMPATIBLE: the host omitted required field \"${error.field}\" despite advertising a compatible contract version. Screenshot this message and contact support.`,\n };\n case 'INVALID_RESULT':\n return {\n code: 'UNKNOWN',\n action: 'contact-support',\n message: `INVALID_RESULT: a host value failed this app's bundled parser (${formatIssues(error.issues)}). Screenshot this message and contact support.`,\n };\n case 'TIMED_OUT':\n return {\n code: 'TIMED_OUT',\n action: 'retry',\n message: `TIMED_OUT: the Datadog host did not complete the claim request within ${error.timeoutMs}ms. Reload the app to try again.`,\n };\n case 'DISCONNECTED':\n case 'UNRECOGNIZED':\n return toEmbeddingError(error);\n default: {\n const exhaustive: never = error;\n return exhaustive;\n }\n }\n}\n", "import { describeCause, logFailure, logWarning } from './diagnostics';\nimport { toClaimError, toEmbeddingError } from './errors';\nimport { notifyListeners, teardown } from './shared';\nimport type {\n AnyContract,\n AppConnection,\n AppConnectionFactory,\n AppConnectionHandle,\n AppConnectionState,\n AppEmbedding,\n ClaimedValues,\n Claimed,\n ClaimInvalidationError,\n ClaimError,\n ClaimState,\n ClaimStore,\n EmbeddingMetadata,\n EmbeddingMetadataStore,\n LiveValue,\n Result,\n Unsubscribe,\n WireClaimError,\n} from './types';\n\ntype RuntimeDefinition = AnyContract;\n\ntype RuntimeClaim = Claimed<RuntimeDefinition>;\n\nconst RELEASE_GRACE_MS = 0;\nconst PENDING = Object.freeze({\n status: 'pending',\n} as const);\nconst UNAVAILABLE = Object.freeze({\n status: 'unavailable',\n} as const);\n\nconst CLOSED_ERROR: ClaimError = Object.freeze({\n code: 'UNKNOWN',\n action: 'contact-support',\n message:\n 'EMBEDDING_CLOSED: the Datadog App connection closed while its provider was still mounted. Screenshot this message and contact support.',\n});\nconst CLAIM_REJECTED_ERROR: ClaimError = Object.freeze({\n code: 'UNKNOWN',\n action: 'contact-support',\n message:\n 'CLAIM_REJECTED: the requested Datadog App claim failed unexpectedly. Screenshot this message and contact support.',\n});\nconst CONNECTION_START_ERROR: ClaimError = Object.freeze({\n code: 'UNKNOWN',\n action: 'contact-support',\n message:\n 'CONNECTION_START_FAILED: the Datadog App connection could not be started. Screenshot this message and contact support.',\n});\n\nfunction pending<TContract extends AnyContract>(): ClaimState<TContract> {\n return PENDING;\n}\n\nfunction unavailable<TContract extends AnyContract>(): ClaimState<TContract> {\n return UNAVAILABLE;\n}\n\nfunction failed<TContract extends AnyContract>(\n error: ClaimError,\n): ClaimState<TContract> {\n const immutableError: ClaimError =\n 'requestedVersion' in error\n ? Object.freeze({\n ...error,\n availableVersions: Object.freeze([\n ...error.availableVersions,\n ]),\n })\n : Object.freeze({ ...error });\n return Object.freeze({\n status: 'failed',\n error: immutableError,\n });\n}\n\ninterface ManagedClaimResource {\n fail(error: ClaimError): void;\n reset(): void;\n sync(state: AppConnectionState | undefined): void;\n}\n\ninterface ClaimResourceOwner {\n activate(resource: ManagedClaimResource): void;\n deactivate(resource: ManagedClaimResource): void;\n}\n\n/**\n * Shared activate/deactivate subscription lifecycle for a `ManagedClaimResource`:\n * the resource is active exactly while at least one listener is subscribed,\n * with a grace period before deactivating so a brief unsubscribe/resubscribe\n * (e.g. a React remount) doesn't churn the underlying connection.\n */\nclass ResourceSubscription {\n readonly #listeners = new Set<() => void>();\n #releaseTimer?: ReturnType<typeof globalThis.setTimeout>;\n #isActive = false;\n\n constructor(\n private readonly owner: ClaimResourceOwner,\n private readonly resource: ManagedClaimResource,\n ) {}\n\n readonly subscribe = (onChange: () => void): Unsubscribe => {\n if (this.#releaseTimer !== undefined) {\n globalThis.clearTimeout(this.#releaseTimer);\n this.#releaseTimer = undefined;\n }\n // A fresh wrapper per call, not `onChange` itself: a Set dedupes by\n // reference, so two subscriptions sharing a reference-equal callback\n // (e.g. the same memoized handler subscribing twice) would otherwise\n // collide into one entry that the first unsubscribe silently drops\n // for both callers.\n const listener = () => onChange();\n this.#listeners.add(listener);\n if (!this.#isActive) {\n this.#isActive = true;\n this.owner.activate(this.resource);\n }\n\n let isSubscribed = true;\n return () => {\n if (!isSubscribed) {\n return;\n }\n isSubscribed = false;\n this.#listeners.delete(listener);\n if (\n this.#listeners.size === 0 &&\n this.#releaseTimer === undefined\n ) {\n this.#releaseTimer = globalThis.setTimeout(() => {\n this.#releaseTimer = undefined;\n if (this.#listeners.size === 0 && this.#isActive) {\n this.#isActive = false;\n this.owner.deactivate(this.resource);\n }\n }, RELEASE_GRACE_MS);\n }\n };\n };\n\n notify(): void {\n notifyListeners(this.#listeners);\n }\n\n get isActive(): boolean {\n return this.#isActive;\n }\n}\n\nclass EmbeddingClaimStore<TContract extends AnyContract>\n implements ClaimStore<TContract>, ManagedClaimResource\n{\n readonly #subscription: ResourceSubscription;\n readonly #runtimeDefinition: RuntimeDefinition;\n #snapshot: ClaimState<TContract> = pending<TContract>();\n #connection?: AppConnection;\n #claimController?: AbortController;\n #claimed?: RuntimeClaim;\n #claimUnsubscribes: Unsubscribe[] = [];\n\n constructor(owner: ClaimResourceOwner, runtimeDefinition: TContract) {\n this.#runtimeDefinition = runtimeDefinition;\n this.#subscription = new ResourceSubscription(owner, this);\n }\n\n readonly getSnapshot = (): ClaimState<TContract> => this.#snapshot;\n\n readonly subscribe = (onChange: () => void): Unsubscribe =>\n this.#subscription.subscribe(onChange);\n\n sync(state: AppConnectionState | undefined): void {\n if (!state) {\n this.reset();\n return;\n }\n\n switch (state.state) {\n case 'connected':\n if (this.#connection === state.connection) {\n return;\n }\n this.#detachClaim();\n this.#connection = state.connection;\n this.#setSnapshot(pending<TContract>());\n this.#startClaim(state.connection);\n return;\n case 'connecting':\n case 'reconnecting':\n this.reset();\n return;\n case 'not-embedded':\n this.#connection = undefined;\n this.#detachClaim();\n this.#setSnapshot(unavailable<TContract>());\n return;\n case 'rejected':\n this.#connection = undefined;\n this.#detachClaim();\n this.#failWith(toEmbeddingError(state.error));\n return;\n case 'closed':\n this.#connection = undefined;\n this.#detachClaim();\n this.#failWith(CLOSED_ERROR);\n return;\n default: {\n const exhaustive: never = state;\n return exhaustive;\n }\n }\n }\n\n fail(error: ClaimError): void {\n this.#connection = undefined;\n this.#detachClaim();\n this.#failWith(error);\n }\n\n reset(): void {\n this.#connection = undefined;\n this.#detachClaim();\n this.#setSnapshot(pending<TContract>());\n }\n\n #startClaim(connection: AppConnection): void {\n const controller = new AbortController();\n this.#claimController = controller;\n\n let claim: Promise<Result<RuntimeClaim, WireClaimError>>;\n try {\n claim = connection.claim(this.#runtimeDefinition, {\n signal: controller.signal,\n });\n } catch (cause) {\n logFailure('a claim could not be requested', {\n side: 'app',\n identifier: this.#runtimeDefinition.identifier,\n current: this.#isCurrent(connection, controller),\n cause: describeCause(cause),\n });\n if (this.#isCurrent(connection, controller)) {\n this.#claimController = undefined;\n this.#failWith(CLAIM_REJECTED_ERROR);\n }\n return;\n }\n\n claim.then(\n (result) => {\n if (!this.#isCurrent(connection, controller)) {\n if (result.ok) {\n result.value.release();\n }\n return;\n }\n this.#claimController = undefined;\n\n if (!result.ok) {\n if (result.error.code === 'PEER_LACKS_MODULE') {\n // Allowed by the contract, but it is also the most\n // common reason an app sees no module data at all, and it is\n // otherwise indistinguishable from \"not embedded\".\n logWarning(\n 'the Datadog host does not offer this module',\n {\n side: 'app',\n identifier: this.#runtimeDefinition.identifier,\n version: this.#runtimeDefinition.version,\n },\n );\n this.#setSnapshot(unavailable<TContract>());\n return;\n }\n if (result.error.code === 'ABORTED') {\n this.#failWith(CLAIM_REJECTED_ERROR);\n return;\n }\n this.#failWith(toClaimError(result.error));\n return;\n }\n\n this.#attachClaim(connection, result.value);\n },\n (cause: unknown) => {\n logFailure('a claim request rejected', {\n side: 'app',\n identifier: this.#runtimeDefinition.identifier,\n current: this.#isCurrent(connection, controller),\n cause: describeCause(cause),\n });\n if (this.#isCurrent(connection, controller)) {\n this.#claimController = undefined;\n this.#failWith(CLAIM_REJECTED_ERROR);\n }\n },\n );\n }\n\n #attachClaim(connection: AppConnection, claimed: RuntimeClaim): void {\n if (\n !this.#subscription.isActive ||\n this.#connection !== connection ||\n this.#claimed\n ) {\n claimed.release();\n return;\n }\n\n this.#claimed = claimed;\n this.#claimUnsubscribes.push(\n claimed.onInvalidated((error) =>\n this.#invalidateClaim(claimed, error),\n ),\n );\n this.#claimUnsubscribes.push(\n claimed.onValuesChanged(() => {\n if (this.#claimed === claimed) {\n this.#publishFields(claimed);\n }\n }),\n );\n this.#publishFields(claimed);\n }\n\n #invalidateClaim(\n claimed: RuntimeClaim,\n error: ClaimInvalidationError,\n ): void {\n if (this.#claimed !== claimed) {\n return;\n }\n const claimError = toClaimError(error);\n this.#detachClaim();\n this.#failWith(claimError);\n }\n\n #publishFields(claimed: RuntimeClaim): void {\n const entries = Object.entries(this.#runtimeDefinition.fields);\n const names = entries.map(([name]) => name);\n // Null-prototype: a field literally named \"__proto__\" must become an\n // own property here, not invoke the inherited legacy setter and get\n // silently dropped from the published snapshot.\n const values: Record<string, unknown> = Object.create(null);\n for (const [name, field] of entries) {\n const claimedField = claimed.fields[name];\n values[name] =\n field.kind === 'value'\n ? (claimedField as LiveValue<unknown>).get()\n : claimedField;\n }\n if (this.#snapshot.status === 'ready') {\n const current = this.#snapshot.fields as Readonly<\n Record<string, unknown>\n >;\n if (names.every((name) => Object.is(current[name], values[name]))) {\n return;\n }\n }\n this.#setSnapshot(\n Object.freeze({\n status: 'ready',\n fields: Object.freeze(values) as ClaimedValues<TContract>,\n }),\n );\n }\n\n #isCurrent(\n connection: AppConnection,\n controller: AbortController,\n ): boolean {\n return (\n this.#subscription.isActive &&\n this.#connection === connection &&\n this.#claimController === controller &&\n !controller.signal.aborted\n );\n }\n\n #detachClaim(): void {\n this.#claimController?.abort();\n this.#claimController = undefined;\n for (const unsubscribe of this.#claimUnsubscribes.splice(0)) {\n unsubscribe();\n }\n const claimed = this.#claimed;\n this.#claimed = undefined;\n claimed?.release();\n }\n\n /**\n * The single place a claim becomes app-visibly failed. The public\n * `ClaimError` is what an app author can act on, and an app that renders a\n * fallback instead of reading `error` would otherwise leave no trace of\n * why its claim never delivered data.\n */\n #failWith(error: ClaimError): void {\n logFailure('a Datadog App claim failed', {\n side: 'app',\n identifier: this.#runtimeDefinition.identifier,\n version: this.#runtimeDefinition.version,\n code: error.code,\n action: error.action,\n reason: error.message,\n });\n this.#setSnapshot(failed<TContract>(error));\n }\n\n #setSnapshot(next: ClaimState<TContract>): void {\n if (this.#snapshot === next) {\n return;\n }\n this.#snapshot = next;\n this.#subscription.notify();\n }\n}\n\nconst NOT_YET_CONNECTED: EmbeddingMetadata = Object.freeze({\n state: 'connecting',\n});\n\nfunction toEmbeddingMetadata(state: AppConnectionState): EmbeddingMetadata {\n switch (state.state) {\n case 'connecting':\n return { state: 'connecting', error: state.error };\n case 'connected':\n return { state: 'connected', surfaceId: state.surfaceId };\n case 'reconnecting':\n return { state: 'reconnecting', lastError: state.lastError };\n case 'rejected':\n return { state: 'rejected', error: state.error };\n case 'not-embedded':\n return { state: 'not-embedded' };\n case 'closed':\n return { state: 'closed' };\n default: {\n const exhaustive: never = state;\n return exhaustive;\n }\n }\n}\n\n/**\n * The one shared, contract-agnostic view of the embedding connection itself\n * -- its lifecycle state, any connection error, and the surface it was\n * embedded into. Participates in the same activate/deactivate/sync lifecycle\n * as `EmbeddingClaimStore` so it starts and stops the shared connection\n * exactly like any other consumer, without a claim of its own.\n */\nclass EmbeddingMetadataResource\n implements EmbeddingMetadataStore, ManagedClaimResource\n{\n readonly #subscription: ResourceSubscription;\n #snapshot: EmbeddingMetadata = NOT_YET_CONNECTED;\n\n constructor(owner: ClaimResourceOwner) {\n this.#subscription = new ResourceSubscription(owner, this);\n }\n\n readonly getSnapshot = (): EmbeddingMetadata => this.#snapshot;\n\n readonly subscribe = (onChange: () => void): Unsubscribe =>\n this.#subscription.subscribe(onChange);\n\n sync(state: AppConnectionState | undefined): void {\n this.#setSnapshot(\n state ? toEmbeddingMetadata(state) : NOT_YET_CONNECTED,\n );\n }\n\n fail(error: ClaimError): void {\n // Reachable only if the connector itself throws synchronously (see\n // `#failStart`); there is no `ConnectError` to report in that case, so\n // this folds the claim-level failure into the connect-level shape\n // every other `EmbeddingMetadata` error carries.\n this.#setSnapshot({\n state: 'rejected',\n error: { code: 'TRANSPORT_FAILED', cause: error },\n });\n }\n\n reset(): void {\n this.#setSnapshot(NOT_YET_CONNECTED);\n }\n\n #setSnapshot(next: EmbeddingMetadata): void {\n if (this.#snapshot === next) {\n return;\n }\n this.#snapshot = next;\n this.#subscription.notify();\n }\n}\n\n/** Owns one app connection and one shared child resource per contract object. */\nclass AppEmbeddingImplementation implements AppEmbedding {\n readonly #resources = new WeakMap<object, ManagedClaimResource>();\n readonly #activeResources = new Set<ManagedClaimResource>();\n readonly #owner: ClaimResourceOwner = {\n activate: (resource) => this.#activate(resource),\n deactivate: (resource) => this.#deactivate(resource),\n };\n #handle?: AppConnectionHandle;\n #handleUnsubscribe?: Unsubscribe;\n #startError?: ClaimError;\n #metadataResource?: EmbeddingMetadataResource;\n #owners = 0;\n\n constructor(private readonly connector: AppConnectionFactory) {}\n\n getClaim<TContract extends AnyContract>(\n contract: TContract,\n ): ClaimStore<TContract> {\n const key = contract as object;\n const cached = this.#resources.get(key);\n if (cached) {\n return cached as unknown as ClaimStore<TContract>;\n }\n\n const created = new EmbeddingClaimStore<TContract>(\n this.#owner,\n contract,\n );\n this.#resources.set(key, created);\n return created;\n }\n\n getEmbeddingMetadata(): EmbeddingMetadataStore {\n if (!this.#metadataResource) {\n this.#metadataResource = new EmbeddingMetadataResource(this.#owner);\n }\n return this.#metadataResource;\n }\n\n start(): Unsubscribe {\n this.#owners += 1;\n if (this.#owners === 1) {\n this.#startConnection();\n }\n\n let ownsLease = true;\n return () => {\n if (!ownsLease) {\n return;\n }\n ownsLease = false;\n this.#owners -= 1;\n if (this.#owners === 0) {\n this.#stopConnection();\n }\n };\n }\n\n #startConnection(): void {\n this.#startError = undefined;\n for (const resource of this.#activeResources) {\n resource.reset();\n }\n\n let handle: AppConnectionHandle;\n try {\n handle = this.connector.connect();\n } catch (cause) {\n this.#failStart('connect', cause);\n return;\n }\n\n this.#handle = handle;\n try {\n this.#handleUnsubscribe = handle.subscribe(() =>\n this.#sync(handle),\n );\n this.#sync(handle);\n } catch (cause) {\n this.#stop(handle);\n this.#failStart('subscribe', cause);\n return;\n }\n }\n\n #stopConnection(): void {\n const handle = this.#handle;\n if (handle) {\n this.#stop(handle);\n }\n this.#startError = undefined;\n for (const resource of this.#activeResources) {\n resource.reset();\n }\n }\n\n #activate(resource: ManagedClaimResource): void {\n this.#activeResources.add(resource);\n if (this.#startError) {\n resource.fail(this.#startError);\n return;\n }\n resource.sync(this.#handle?.getSnapshot());\n }\n\n #deactivate(resource: ManagedClaimResource): void {\n this.#activeResources.delete(resource);\n resource.reset();\n }\n\n #sync(handle: AppConnectionHandle): void {\n if (this.#handle !== handle) {\n return;\n }\n const state = handle.getSnapshot();\n for (const resource of this.#activeResources) {\n resource.sync(state);\n }\n }\n\n #stop(handle: AppConnectionHandle): void {\n if (this.#handle !== handle) {\n return;\n }\n this.#handle = undefined;\n // Each step is isolated: one throwing (a listener's unsubscribe, a\n // resource's reset) must not skip the rest of teardown, or the\n // underlying connection handle can leak unclosed.\n const handleUnsubscribe = this.#handleUnsubscribe;\n this.#handleUnsubscribe = undefined;\n if (handleUnsubscribe) {\n teardown('embedding connection handle unsubscribe', () =>\n handleUnsubscribe(),\n );\n }\n for (const resource of this.#activeResources) {\n teardown('embedding claim resource reset', () => resource.reset());\n }\n teardown('embedding connection handle close', () => handle.close());\n }\n\n // The connector itself threw, which no `ConnectError` describes: nothing\n // downstream ever sees this cause, so it is reported where it is caught.\n #failStart(step: 'connect' | 'subscribe', cause: unknown): void {\n logFailure('the embedding connection could not be started', {\n side: 'app',\n step,\n affectedResources: this.#activeResources.size,\n cause: describeCause(cause),\n });\n this.#startError = CONNECTION_START_ERROR;\n for (const resource of this.#activeResources) {\n resource.fail(CONNECTION_START_ERROR);\n }\n }\n}\n\nexport function createAppEmbedding(\n connector: AppConnectionFactory,\n): AppEmbedding {\n return new AppEmbeddingImplementation(connector);\n}\n"],
5
- "mappings": "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",
6
- "names": ["createElement", "useEffect", "useState", "DATADOG_PRODUCTION_ORIGIN", "DATADOG_INTERNAL_ORIGIN", "LOCAL_ORIGIN", "isDatadogHostOrigin", "origin", "BOOTSTRAP_NAMESPACE", "BOOTSTRAP_VERSION", "inspectBootstrapAcknowledgement", "expectedSource", "expectedAttemptId", "event", "data", "isRecord", "BOOTSTRAP_NAMESPACE", "BOOTSTRAP_VERSION", "isDatadogHostOrigin", "requestBootstrapControlPort", "appWindow", "documentId", "signal", "timeoutMs", "err", "hostWindow", "attemptId", "createId", "control", "resolve", "settled", "transferred", "posted", "timer", "finish", "result", "onMessage", "onAbort", "teardown", "inspected", "success", "postRequest", "cause", "APP_DOCUMENT_ID", "COMPATIBILITY_NAMESPACE", "COMPATIBILITY_PRELUDE_VERSION", "MAX_SUPPORTED_PROTOCOLS", "nextControlMessage", "port", "timeoutMs", "signal", "afterListening", "resolve", "settled", "timer", "finish", "result", "onMessage", "onAbort", "event", "cause", "parseSupportedProtocols", "value", "protocol", "left", "right", "negotiateProtocols", "appProtocols", "hostProtocols", "common", "version", "oldestApp", "newestApp", "oldestHost", "newestHost", "negotiateAppProtocol", "controlPort", "supportedProtocols", "answer", "data", "ports", "isRecord", "negotiated", "operationalPort", "connect", "PortMessenger", "Reply", "HEARTBEAT_NAMESPACE", "HEARTBEAT_VERSION", "PRODUCTION_HEARTBEAT", "HEARTBEAT_INTERVAL_MS", "HEARTBEAT_DEADLINE_MS", "postOperationalClose", "port", "closeFailedOperationalTransport", "penpal", "teardown", "CLOSE_DELIVERY_TIMEOUT_MS", "_timer", "_nonce", "_misses", "_started", "_stopped", "_onMessage", "_Heartbeat_instances", "schedule_fn", "probe_fn", "miss_fn", "disconnect_fn", "Heartbeat", "onDead", "policy", "side", "__privateAdd", "event", "envelope", "isRecord", "__privateMethod", "isValidIdentifier", "cause", "logFailure", "describeCause", "__privateGet", "__privateSet", "delayMs", "nonce", "createId", "logWarning", "notifyPeer", "Reply", "isPromiseLike", "value", "isVersion", "isVersionList", "isNumberList", "entry", "isPath", "segment", "isIssueList", "issue", "isRecord", "validate", "schema", "validated", "err", "standardIssuePath", "success", "error", "path", "key", "uncloneablePath", "seen", "entries", "child", "childPath", "prefixIssues", "field", "issues", "valueFieldNames", "contract", "name", "findFieldKeyIssue", "expectedFields", "values", "requireComplete", "expected", "missingField", "unknownField", "keyIssueError", "invalidHydrationValueBatch", "invalidUpdateValueBatch", "readProvidedValue", "provider", "logFailure", "describeCause", "parsed", "reportInvalidHostValue", "identifier", "details", "validateFunctionInputs", "fieldName", "inputs", "unknownInput", "parsedInputs", "isMessagePort", "prototype", "getter", "messagePortResult", "discardFunctionResult", "teardown", "cloneFailure", "prepareFunctionResult", "port", "cloned", "Reply", "receiveFunctionResult", "ErrorCode", "PenpalError", "appTooOld", "raw", "wanted", "hostVersions", "isVersion", "isVersionList", "version", "hostTooOld", "ERROR_PAYLOAD", "isNumberList", "isIssueList", "ERROR_FIELDS", "normalizeError", "allowed", "isRecord", "code", "validatePayload", "picked", "name", "functionError", "contract", "field", "errorValue", "target", "publicCode", "message", "error", "logFailure", "describeError", "connectErrorFrom", "timeoutMs", "PenpalError", "ErrorCode", "malformedClaimRequest", "request", "isValidIdentifier", "MAX_CLAIM_ID_LENGTH", "MAX_CLAIM_FIELDS", "MAX_CLAIM_FIELD_NAME_LENGTH", "malformedFunctionRequest", "MAX_CALL_ID_LENGTH", "negotiateVersion", "candidates", "left", "right", "newestVersion", "err", "sameVersion", "success", "advertisedClaimError", "modules", "identifier", "negotiated", "_listeners", "MutableLiveValue", "value", "__privateAdd", "onChange", "__privateGet", "notifyListeners", "liveHostFunctionCalls", "resolveFunctionCallTimeoutMs", "field", "declared", "_closeController", "_hostClaims", "_hostFunctionCalls", "_appClaims", "_pendingClaims", "_queuedValues", "_queuedInvalidations", "_sendTimers", "_heartbeat", "_closed", "_transportClosed", "_ProtocolEndpoint_instances", "closeTransport_fn", "forgetPendingClaim_fn", "endAppClaim_fn", "invalidateAppClaim_fn", "invalidateHostClaim_fn", "ProtocolEndpoint", "role", "remote", "penpal", "port", "modules", "operationTimeoutMs", "heartbeat", "__privateSet", "operation", "call", "pending", "cause", "logFailure", "describeCause", "timer", "finish", "disconnected", "notifyPeer", "peerClose", "postOperationalClose", "claimId", "claim", "__privateMethod", "CLOSE_DELIVERY_TIMEOUT_MS", "remoteCall", "options", "result", "err", "resolve", "settled", "onAbort", "onDisconnect", "isRecord", "success", "contract", "timeoutMs", "assertValidTimerDelay", "createId", "claimed", "deadlineMs", "raw", "normalizeError", "invalidInitialValues", "invalidHydrationValueBatch", "valueFieldNames", "values", "fields", "record", "name", "callArgs", "initial", "validate", "prefixIssues", "live", "queuedValues", "queuedInvalidation", "listener", "invalidation", "fieldName", "functionError", "parsedInputs", "validateFunctionInputs", "callId", "discarded", "discardFunctionResult", "remoteError", "parsedResult", "receiveFunctionResult", "isValidIdentifier", "MAX_CLAIM_ID_LENGTH", "pendingContract", "invalidUpdateValueBatch", "previouslyQueued", "parsedValues", "schema", "parsed", "fieldInvalidation", "changed", "request", "malformed", "malformedClaimRequest", "MAX_LIVE_HOST_CLAIMS", "candidates", "negotiated", "negotiateVersion", "module", "selected", "claimedFields", "onModuleDisposed", "hydration", "changedBeforeReady", "publishScheduled", "publishedOnce", "dirty", "providers", "publishValues", "isHydrationPublish", "fieldsToSend", "nextValues", "entry", "next", "readProvidedValue", "reportInvalidHostValue", "schedulePublish", "provider", "unsubscribe", "error", "teardown", "malformedFunctionRequest", "MAX_LIVE_HOST_FUNCTION_CALLS", "controller", "resolveInterruption", "interruption", "activeCall", "reason", "callTimeoutMs", "deadline", "handlerOutcome", "returned", "trackedHandlerOutcome", "outcome", "lateOutcome", "prepared", "prepareFunctionResult", "MAX_CALL_ID_LENGTH", "release", "listeners", "logWarning", "describeError", "issues", "requestSummary", "request", "fields", "isRecord", "summary", "field", "AppConnectionImplementation", "endpoint", "modules", "contract", "options", "assertValidTimerDelay", "unavailable", "advertisedClaimError", "err", "isHostDescription", "value", "sanitizeModules", "versions", "sanitized", "module", "isValidIdentifier", "isVersion", "key", "establishEndpoint", "operationalPort", "role", "timeoutMs", "signal", "surfaceId", "heartbeatPolicy", "heartbeat", "disconnectedBeforeReady", "closeRequestedBeforeReady", "rejectForDisconnect", "disconnected", "_resolve", "reject", "Heartbeat", "notifyPeer", "cause", "teardown", "endpointReadySettled", "pendingEndpointOperations", "resolveEndpointReady", "endpointReady", "resolve", "settleEndpointReady", "requireReadyEndpoint", "expectedRole", "operation", "rejected", "reason", "logWarning", "MAX_PENDING_ENDPOINT_OPERATIONS", "ready", "localDescription", "logRejection", "requestFields", "result", "describeError", "methods", "claimId", "values", "response", "Reply", "invalidation", "penpal", "connect", "PortMessenger", "postOperationalClose", "CLOSE_DELIVERY_TIMEOUT_MS", "rejectForAbort", "rejectForTimeout", "onAbort", "aborted", "timedOut", "timer", "stage", "remote", "peer", "ProtocolEndpoint", "success", "error", "connectError", "connectErrorFrom", "describeCause", "closeFailedOperationalTransport", "managedApp", "established", "description", "connectApp", "operationalPort", "timeoutMs", "signal", "heartbeatPolicy", "established", "establishEndpoint", "success", "managedApp", "SUPPORTED_PROTOCOLS", "connectAppControlPort", "controlPort", "signal", "timeoutMs", "err", "compatible", "negotiateAppProtocol", "connectApp", "PRODUCTION_HEARTBEAT", "_nextDelayMs", "RetryBackoff", "__privateAdd", "delayMs", "__privateGet", "RECONNECT_RETRY_MS", "__privateSet", "RECONNECT_MAX_RETRY_MS", "isEmbeddedFrame", "isRetryableConnectError", "error", "_controller", "_listeners", "_backoff", "_snapshot", "_active", "_attemptController", "_retryTimer", "_giveUpTimer", "_lastError", "_attempts", "_attempting", "_gaveUp", "_AppConnectionHandleImplementation_instances", "connect_fn", "attempt_fn", "scheduleRetry_fn", "clearRetryTimer_fn", "startGiveUpTimer_fn", "clearGiveUpTimer_fn", "giveUp_fn", "setSnapshot_fn", "AppConnectionHandleImplementation", "__privateMethod", "onChange", "active", "signal", "control", "requestBootstrapControlPort", "APP_DOCUMENT_ID", "connectAppControlPort", "attemptController", "result", "cause", "logFailure", "describeError", "onConnectionClosed", "logWarning", "RECONNECT_GIVE_UP_AFTER_MS", "next", "notifyListeners", "browserAppEmbedding", "AppConnectionHandleImplementation", "formatVersions", "versions", "formatIssues", "issues", "issue", "boundedCauseText", "cause", "text", "toEmbeddingError", "error", "toClaimError", "RELEASE_GRACE_MS", "PENDING", "UNAVAILABLE", "CLOSED_ERROR", "CLAIM_REJECTED_ERROR", "CONNECTION_START_ERROR", "pending", "unavailable", "failed", "error", "immutableError", "_listeners", "_releaseTimer", "_isActive", "ResourceSubscription", "owner", "resource", "__privateAdd", "__publicField", "onChange", "__privateGet", "__privateSet", "listener", "isSubscribed", "notifyListeners", "_subscription", "_runtimeDefinition", "_snapshot", "_connection", "_claimController", "_claimed", "_claimUnsubscribes", "_EmbeddingClaimStore_instances", "startClaim_fn", "attachClaim_fn", "invalidateClaim_fn", "publishFields_fn", "isCurrent_fn", "detachClaim_fn", "failWith_fn", "setSnapshot_fn", "EmbeddingClaimStore", "runtimeDefinition", "state", "__privateMethod", "toEmbeddingError", "connection", "controller", "claim", "cause", "logFailure", "describeCause", "result", "logWarning", "toClaimError", "claimed", "claimError", "entries", "names", "name", "values", "field", "claimedField", "current", "unsubscribe", "next", "NOT_YET_CONNECTED", "toEmbeddingMetadata", "_EmbeddingMetadataResource_instances", "EmbeddingMetadataResource", "_resources", "_activeResources", "_owner", "_handle", "_handleUnsubscribe", "_startError", "_metadataResource", "_owners", "_AppEmbeddingImplementation_instances", "startConnection_fn", "stopConnection_fn", "activate_fn", "deactivate_fn", "sync_fn", "stop_fn", "failStart_fn", "AppEmbeddingImplementation", "connector", "contract", "key", "cached", "created", "ownsLease", "handle", "handleUnsubscribe", "teardown", "step", "createAppEmbedding", "embedding", "createAppEmbedding", "browserAppEmbedding", "EmbeddingProvider", "createDatadogAppProvider", "NO_MODULES", "DatadogAppProvider", "children", "modules", "mountedModules", "useState", "useEffect", "controller", "installDatadogAppProviderModules", "createElement"]
7
- }