@susilkumar006/widgets-test 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +445 -0
- package/dist/api/FacePeApiClient.d.cts +74 -0
- package/dist/api/FacePeApiClient.d.ts +74 -0
- package/dist/api/FacePeApiContext.d.cts +8 -0
- package/dist/api/FacePeApiContext.d.ts +8 -0
- package/dist/api/decoders.d.cts +48 -0
- package/dist/api/decoders.d.ts +48 -0
- package/dist/api/index.d.cts +8 -0
- package/dist/api/index.d.ts +8 -0
- package/dist/api/json.d.cts +5 -0
- package/dist/api/json.d.ts +5 -0
- package/dist/api/useFacePeResource.d.cts +21 -0
- package/dist/api/useFacePeResource.d.ts +21 -0
- package/dist/components/Avatar/FacePeAvatar.d.cts +23 -0
- package/dist/components/Avatar/FacePeAvatar.d.ts +23 -0
- package/dist/components/Avatar/engines.d.cts +30 -0
- package/dist/components/Avatar/engines.d.ts +30 -0
- package/dist/components/Avatar/index.d.cts +1 -0
- package/dist/components/Avatar/index.d.ts +1 -0
- package/dist/components/Form/FacePeForm.d.cts +19 -0
- package/dist/components/Form/FacePeForm.d.ts +19 -0
- package/dist/components/Form/index.d.cts +1 -0
- package/dist/components/Form/index.d.ts +1 -0
- package/dist/components/Picker/FacePePicker.d.cts +22 -0
- package/dist/components/Picker/FacePePicker.d.ts +22 -0
- package/dist/components/Picker/index.d.cts +1 -0
- package/dist/components/Picker/index.d.ts +1 -0
- package/dist/components/Placement/FacePeOverlay.d.cts +13 -0
- package/dist/components/Placement/FacePeOverlay.d.ts +13 -0
- package/dist/components/Placement/FacePePage.d.cts +10 -0
- package/dist/components/Placement/FacePePage.d.ts +10 -0
- package/dist/components/Placement/index.d.cts +2 -0
- package/dist/components/Placement/index.d.ts +2 -0
- package/dist/components/Timeline/FacePeTimeline.d.cts +23 -0
- package/dist/components/Timeline/FacePeTimeline.d.ts +23 -0
- package/dist/components/Timeline/index.d.cts +1 -0
- package/dist/components/Timeline/index.d.ts +1 -0
- package/dist/components/shared/FacePeErrorBoundary.d.cts +28 -0
- package/dist/components/shared/FacePeErrorBoundary.d.ts +28 -0
- package/dist/components/shared/surface.d.cts +6 -0
- package/dist/components/shared/surface.d.ts +6 -0
- package/dist/context/FacePeContext.d.cts +22 -0
- package/dist/context/FacePeContext.d.ts +22 -0
- package/dist/context/avatar.d.cts +6 -0
- package/dist/context/avatar.d.ts +6 -0
- package/dist/context/index.d.cts +5 -0
- package/dist/context/index.d.ts +5 -0
- package/dist/context/navigation.d.cts +10 -0
- package/dist/context/navigation.d.ts +10 -0
- package/dist/events/FacePeEventEmitter.d.cts +59 -0
- package/dist/events/FacePeEventEmitter.d.ts +59 -0
- package/dist/events/createCorrelationId.d.cts +9 -0
- package/dist/events/createCorrelationId.d.ts +9 -0
- package/dist/events/index.d.cts +8 -0
- package/dist/events/index.d.ts +8 -0
- package/dist/events/telemetry.d.cts +11 -0
- package/dist/events/telemetry.d.ts +11 -0
- package/dist/events/useFacePeEmitter.d.cts +15 -0
- package/dist/events/useFacePeEmitter.d.ts +15 -0
- package/dist/index.cjs +1925 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +26 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +1903 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/FacePeCustomerPayload.schema.json +31 -0
- package/dist/schemas/FacePeError.schema.json +63 -0
- package/dist/schemas/FacePeEventMeta.schema.json +53 -0
- package/dist/schemas/FacePeFormValues.schema.json +27 -0
- package/dist/schemas/FacePeNavigationRequest.schema.json +33 -0
- package/dist/schemas/FacePePickerOption.schema.json +34 -0
- package/dist/schemas/FacePePickerOptionsPayload.schema.json +49 -0
- package/dist/schemas/FacePeTelemetryEvent.schema.json +66 -0
- package/dist/schemas/FacePeTimelineItem.schema.json +91 -0
- package/dist/schemas/FacePeTimelinePayload.schema.json +109 -0
- package/dist/styles.css +887 -0
- package/dist/types/api.d.cts +60 -0
- package/dist/types/api.d.ts +60 -0
- package/dist/types/avatar.d.cts +102 -0
- package/dist/types/avatar.d.ts +102 -0
- package/dist/types/common.d.cts +42 -0
- package/dist/types/common.d.ts +42 -0
- package/dist/types/components.d.cts +53 -0
- package/dist/types/components.d.ts +53 -0
- package/dist/types/config.d.cts +27 -0
- package/dist/types/config.d.ts +27 -0
- package/dist/types/events.d.cts +85 -0
- package/dist/types/events.d.ts +85 -0
- package/dist/types/form.d.cts +83 -0
- package/dist/types/form.d.ts +83 -0
- package/dist/types/index.d.cts +18 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/picker.d.cts +82 -0
- package/dist/types/picker.d.ts +82 -0
- package/dist/types/placement.d.cts +69 -0
- package/dist/types/placement.d.ts +69 -0
- package/dist/types/provider.d.cts +75 -0
- package/dist/types/provider.d.ts +75 -0
- package/dist/types/results.d.cts +28 -0
- package/dist/types/results.d.ts +28 -0
- package/dist/types/telemetry.d.cts +38 -0
- package/dist/types/telemetry.d.ts +38 -0
- package/dist/types/timeline.d.cts +103 -0
- package/dist/types/timeline.d.ts +103 -0
- package/dist/version.d.cts +2 -0
- package/dist/version.d.ts +2 -0
- package/package.json +71 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/events/createCorrelationId.ts","../src/version.ts","../src/api/json.ts","../src/api/FacePeApiClient.ts","../src/api/FacePeApiContext.ts","../src/api/decoders.ts","../src/api/useFacePeResource.ts","../src/events/telemetry.ts","../src/events/FacePeEventEmitter.ts","../src/events/useFacePeEmitter.ts","../src/context/avatar.ts","../src/context/navigation.ts","../src/context/FacePeContext.tsx","../src/components/shared/surface.ts","../src/components/shared/FacePeErrorBoundary.tsx","../src/components/Form/FacePeForm.tsx","../src/components/Picker/FacePePicker.tsx","../src/components/Timeline/FacePeTimeline.tsx","../src/components/Avatar/engines.ts","../src/components/Avatar/FacePeAvatar.tsx","../src/components/Placement/FacePePage.tsx","../src/components/Placement/FacePeOverlay.tsx"],"sourcesContent":["/**\n * Internal: correlation ids for SDK events. Not exported from the package.\n */\nimport type { CorrelationId } from '../types/index.js';\n\n/**\n * A new, unique correlation id. Uses `crypto.randomUUID` and falls back where\n * it is unavailable (pages not served over HTTPS, older runtimes).\n */\nexport function createCorrelationId(): CorrelationId {\n if (typeof globalThis.crypto?.randomUUID === 'function') return globalThis.crypto.randomUUID();\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;\n}\n","/** The version of this SDK build, taken from package.json at build time. */\nexport const SDK_VERSION: string = __FACEPE_SDK_VERSION__;\n","import type { JsonObject, JsonValue } from '../types/index.js';\n\n/** True when `value` is valid JSON data (what `JSON.parse` can produce). */\nexport function isJsonValue(value: unknown): value is JsonValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return true;\n if (typeof value === 'number') return Number.isFinite(value);\n if (Array.isArray(value)) return value.every(isJsonValue);\n if (typeof value === 'object') return Object.values(value).every(isJsonValue);\n return false;\n}\n\n/** True for a JSON object (not an array, not null). */\nexport function isJsonObject(value: JsonValue | undefined): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","/**\r\n * Internal: the HTTP client SDK components use to reach the FacePe backend.\r\n * One per `<FacePeProvider>`; not exported from the package.\r\n *\r\n * request → getToken() → Authorization: Bearer <token> → backend\r\n * → 401 → getToken({ forceRefresh: true }) → retried once\r\n * → 401 again → `sessionExpired`, Failure SESSION_EXPIRED\r\n *\r\n * Every call resolves to a `Result`; HTTP, network, timeout and parsing\r\n * problems come back as a `Failure`, never a rejection. Nothing here logs, and\r\n * no error detail carries a token or a request header.\r\n */\r\nimport { createCorrelationId } from '../events/createCorrelationId.js';\r\nimport type { FacePeTelemetryReporter } from '../events/telemetry.js';\r\nimport { SDK_VERSION } from '../version.js';\r\nimport type {\r\n AsyncResult,\r\n CorrelationId,\r\n FacePeHttpMethod,\r\n FacePeSessionExpiredPayload,\r\n FacePeTokenProvider,\r\n Failure,\r\n JsonValue,\r\n Result,\r\n} from '../types/index.js';\r\nimport { isJsonObject, isJsonValue } from './json.js';\r\n\r\n/** Request header carrying the correlation id (the gateway's agreed name). */\r\nexport const CORRELATION_HEADER = 'X-Request-Id';\r\n/** Request header carrying the SDK version, for the gateway's per-version metrics. */\r\nexport const SDK_VERSION_HEADER = 'X-FacePe-SDK-Version';\r\n/** The audience every token is requested for (architecture §7.4: the FacePe service). */\r\nexport const TOKEN_AUDIENCE = 'app-b';\r\n/** Per-attempt timeout when neither the provider nor the call sets one. */\r\nexport const DEFAULT_TIMEOUT_MS = 15_000;\r\n\r\n/** Provider settings, read afresh on every request. */\r\nexport type FacePeApiSettings = {\r\n readonly baseUrl?: string;\r\n readonly getToken?: FacePeTokenProvider;\r\n readonly timeoutMs?: number;\r\n};\r\n\r\nexport type FacePeApiClientOptions = {\r\n readonly settings: () => FacePeApiSettings;\r\n /** Called once a request is refused even after a fresh token. */\r\n readonly onSessionExpired?: (payload: FacePeSessionExpiredPayload) => void;\r\n /** Receives one `api.request` telemetry record per call. */\r\n readonly onTelemetry?: FacePeTelemetryReporter;\r\n};\r\n\r\n/** Turns response data into the type a caller expects, or a Failure if it does not fit. */\r\nexport type FacePeDecoder<T> = (data: JsonValue) => Result<T>;\r\n\r\nexport type FacePeQuery = Readonly<Record<string, string | number | boolean | null | undefined>>;\r\n\r\nexport type FacePeRequestOptions = {\r\n /** Query-string parameters; `null`/`undefined` ones are left out. */\r\n readonly query?: FacePeQuery;\r\n /** Overrides the provider's per-attempt timeout for this call. */\r\n readonly timeoutMs?: number;\r\n /** Lets the caller cancel (e.g. on unmount); resolves to Failure ABORTED. */\r\n readonly signal?: AbortSignal;\r\n /** Let the request outlive the page (e.g. ending a session as the tab closes). */\r\n readonly keepalive?: boolean;\r\n};\r\n\r\ntype Decoded<T> = FacePeRequestOptions & { readonly decode: FacePeDecoder<T> };\r\ntype MaybeDecoded<T> = FacePeRequestOptions & { readonly decode?: FacePeDecoder<T> };\r\n\r\n/**\r\n * Where a failure happened. Safe to hand to the host: no tokens, no headers.\r\n * `status` is filled in once a response arrives (for telemetry).\r\n */\r\ntype RequestInfo = { method: FacePeHttpMethod; path: string; correlationId: CorrelationId; status?: number };\r\n\r\ntype Attempt =\r\n | { readonly kind: 'response'; readonly status: number; readonly ok: boolean; readonly text: string }\r\n | { readonly kind: 'failure'; readonly failure: Failure };\r\n\r\nconst asJson: FacePeDecoder<JsonValue> = (data) => ({ success: true, data });\r\n\r\nfunction fail(code: string, message: string, info: RequestInfo, status?: number): Failure {\r\n return {\r\n success: false,\r\n error: {\r\n code,\r\n message,\r\n details: {\r\n method: info.method,\r\n path: info.path,\r\n correlationId: info.correlationId,\r\n ...(status === undefined ? {} : { status }),\r\n },\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * `path` resolved against the base URL. Paths are relative to the API base,\r\n * leading slash or not; a full URL is refused so a token is only ever sent to\r\n * the configured backend.\r\n */\r\nfunction buildUrl(baseUrl: string, path: string, query: FacePeQuery | undefined): string | null {\r\n if (/^[a-z][a-z\\d+.-]*:/i.test(path) || path.startsWith('//')) return null;\r\n try {\r\n const base = new URL(baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`, globalThis.location?.href);\r\n const url = new URL(path.replace(/^\\/+/, ''), base);\r\n for (const [key, value] of Object.entries(query ?? {})) {\r\n if (value !== null && value !== undefined) url.searchParams.set(key, String(value));\r\n }\r\n return url.href;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport class FacePeApiClient {\r\n /** The last token getToken returned (memory only), for keepalive requests. */\r\n private lastToken: string | null = null;\r\n\r\n constructor(private readonly options: FacePeApiClientOptions) {}\r\n\r\n /**\r\n * A full address for an asset the API returned as a path (e.g. an avatar's\r\n * picture, \"/avatars/aria.jpg\"): resolved against the API's address, not\r\n * the host page's. Absolute URLs are returned unchanged.\r\n */\r\n assetUrl(url: string | null | undefined): string | null {\r\n if (!url) return null;\r\n if (/^(https?:|data:|blob:)/i.test(url) || url.startsWith('//')) return url;\r\n const base = this.options.settings().baseUrl;\r\n if (!base) return url;\r\n try {\r\n return new URL(url, new URL(base.endsWith('/') ? base : `${base}/`, globalThis.location?.href)).href;\r\n } catch {\r\n return url;\r\n }\r\n }\r\n\r\n get(path: string, options?: FacePeRequestOptions): AsyncResult<JsonValue>;\r\n get<T>(path: string, options: Decoded<T>): AsyncResult<T>;\r\n get<T>(path: string, options?: MaybeDecoded<T>): AsyncResult<T | JsonValue> {\r\n return options?.decode\r\n ? this.send('GET', path, undefined, options.decode, options)\r\n : this.send('GET', path, undefined, asJson, options);\r\n }\r\n\r\n post(path: string, body?: JsonValue, options?: FacePeRequestOptions): AsyncResult<JsonValue>;\r\n post<T>(path: string, body: JsonValue | undefined, options: Decoded<T>): AsyncResult<T>;\r\n post<T>(path: string, body?: JsonValue, options?: MaybeDecoded<T>): AsyncResult<T | JsonValue> {\r\n return options?.decode\r\n ? this.send('POST', path, body, options.decode, options)\r\n : this.send('POST', path, body, asJson, options);\r\n }\r\n\r\n put(path: string, body?: JsonValue, options?: FacePeRequestOptions): AsyncResult<JsonValue>;\r\n put<T>(path: string, body: JsonValue | undefined, options: Decoded<T>): AsyncResult<T>;\r\n put<T>(path: string, body?: JsonValue, options?: MaybeDecoded<T>): AsyncResult<T | JsonValue> {\r\n return options?.decode\r\n ? this.send('PUT', path, body, options.decode, options)\r\n : this.send('PUT', path, body, asJson, options);\r\n }\r\n\r\n patch(path: string, body?: JsonValue, options?: FacePeRequestOptions): AsyncResult<JsonValue>;\r\n patch<T>(path: string, body: JsonValue | undefined, options: Decoded<T>): AsyncResult<T>;\r\n patch<T>(path: string, body?: JsonValue, options?: MaybeDecoded<T>): AsyncResult<T | JsonValue> {\r\n return options?.decode\r\n ? this.send('PATCH', path, body, options.decode, options)\r\n : this.send('PATCH', path, body, asJson, options);\r\n }\r\n\r\n delete(path: string, options?: FacePeRequestOptions): AsyncResult<JsonValue>;\r\n delete<T>(path: string, options: Decoded<T>): AsyncResult<T>;\r\n delete<T>(path: string, options?: MaybeDecoded<T>): AsyncResult<T | JsonValue> {\r\n return options?.decode\r\n ? this.send('DELETE', path, undefined, options.decode, options)\r\n : this.send('DELETE', path, undefined, asJson, options);\r\n }\r\n\r\n private async send<T>(\r\n method: FacePeHttpMethod,\r\n path: string,\r\n body: JsonValue | undefined,\r\n decode: FacePeDecoder<T>,\r\n options: FacePeRequestOptions | undefined,\r\n ): AsyncResult<T> {\r\n // One id for the request and its single retry: they are one logical call.\r\n const info: RequestInfo = { method, path, correlationId: createCorrelationId() };\r\n const started = Date.now();\r\n const result = await this.perform(body, decode, options, info);\r\n this.options.onTelemetry?.({\r\n name: 'api.request',\r\n source: 'FacePeApiClient',\r\n correlationId: info.correlationId,\r\n timestamp: new Date(started).toISOString(),\r\n sdkVersion: SDK_VERSION,\r\n attributes: {\r\n method,\r\n path,\r\n outcome: result.success ? 'success' : result.error.code,\r\n durationMs: Date.now() - started,\r\n ...(info.status === undefined ? {} : { status: info.status }),\r\n },\r\n });\r\n return result;\r\n }\r\n\r\n private async perform<T>(\r\n body: JsonValue | undefined,\r\n decode: FacePeDecoder<T>,\r\n options: FacePeRequestOptions | undefined,\r\n info: RequestInfo,\r\n ): AsyncResult<T> {\r\n const { method, path } = info;\r\n const settings = this.options.settings();\r\n\r\n if (!settings.baseUrl) return fail('API_NOT_CONFIGURED', 'No apiBaseUrl was given to FacePeProvider.', info);\r\n const url = buildUrl(settings.baseUrl, path, options?.query);\r\n if (url === null) return fail('INVALID_URL', 'The request URL could not be built.', info);\r\n const timeoutMs = options?.timeoutMs ?? settings.timeoutMs ?? DEFAULT_TIMEOUT_MS;\r\n\r\n // A keepalive request is usually sent as the page closes: there is no time\r\n // to ask the host for a token (a network round trip the unload would cut\r\n // off), so the last one is reused. A 401 still refreshes it below.\r\n const token =\r\n options?.keepalive && this.lastToken !== null\r\n ? { success: true as const, data: this.lastToken }\r\n : await this.token(settings.getToken, false, info);\r\n if (!token.success) return token;\r\n let attempt = await this.attempt(url, body, token.data, timeoutMs, options?.signal, info, options?.keepalive);\r\n if (attempt.kind === 'failure') return attempt.failure;\r\n\r\n if (attempt.status === 401) {\r\n // Without a token provider there is nothing to refresh.\r\n if (!settings.getToken) return fail('UNAUTHORIZED', 'The request was not authorised.', info, 401);\r\n const fresh = await this.token(settings.getToken, true, info);\r\n if (!fresh.success) return fresh;\r\n attempt = await this.attempt(url, body, fresh.data, timeoutMs, options?.signal, info, options?.keepalive);\r\n if (attempt.kind === 'failure') return attempt.failure;\r\n if (attempt.status === 401) {\r\n this.options.onSessionExpired?.({ method, path });\r\n return fail('SESSION_EXPIRED', 'The session has expired. Sign in again.', info, 401);\r\n }\r\n }\r\n return this.read(attempt.status, attempt.ok, attempt.text, decode, info);\r\n }\r\n\r\n /** The token to send, or `null` when the provider has no token provider. */\r\n private async token(\r\n getToken: FacePeTokenProvider | undefined,\r\n forceRefresh: boolean,\r\n info: RequestInfo,\r\n ): AsyncResult<string | null> {\r\n if (!getToken) return { success: true, data: null };\r\n try {\r\n const token = await getToken({ audience: TOKEN_AUDIENCE, forceRefresh });\r\n if (typeof token === 'string' && token !== '') {\r\n this.lastToken = token;\r\n return { success: true, data: token };\r\n }\r\n } catch {\r\n // The host's error is not passed on: it may describe its credentials.\r\n }\r\n return fail('TOKEN_UNAVAILABLE', 'getToken did not return a token.', info);\r\n }\r\n\r\n /** One HTTP attempt, response body included, under one timeout. */\r\n private async attempt(\r\n url: string,\r\n body: JsonValue | undefined,\r\n token: string | null,\r\n timeoutMs: number,\r\n signal: AbortSignal | undefined,\r\n info: RequestInfo,\r\n keepalive = false,\r\n ): Promise<Attempt> {\r\n if (typeof globalThis.fetch !== 'function') {\r\n return { kind: 'failure', failure: fail('NETWORK_ERROR', 'fetch is not available in this environment.', info) };\r\n }\r\n if (signal?.aborted) return { kind: 'failure', failure: fail('ABORTED', 'The request was cancelled.', info) };\r\n\r\n const controller = new AbortController();\r\n let timedOut = false;\r\n const timer = setTimeout(() => {\r\n timedOut = true;\r\n controller.abort();\r\n }, timeoutMs);\r\n const onCallerAbort = () => controller.abort();\r\n signal?.addEventListener('abort', onCallerAbort, { once: true });\r\n\r\n const headers: Record<string, string> = {\r\n Accept: 'application/json',\r\n [CORRELATION_HEADER]: info.correlationId,\r\n [SDK_VERSION_HEADER]: SDK_VERSION,\r\n };\r\n if (token !== null) headers.Authorization = `Bearer ${token}`;\r\n if (body !== undefined) headers['Content-Type'] = 'application/json';\r\n\r\n try {\r\n const response = await globalThis.fetch(url, {\r\n method: info.method,\r\n headers,\r\n body: body === undefined ? undefined : JSON.stringify(body),\r\n signal: controller.signal,\r\n ...(keepalive ? { keepalive: true } : {}),\r\n });\r\n const text = await response.text();\r\n info.status = response.status;\r\n return { kind: 'response', status: response.status, ok: response.ok, text };\r\n } catch {\r\n if (timedOut) return { kind: 'failure', failure: fail('TIMEOUT', `No response within ${timeoutMs} ms.`, info) };\r\n if (signal?.aborted) return { kind: 'failure', failure: fail('ABORTED', 'The request was cancelled.', info) };\r\n return { kind: 'failure', failure: fail('NETWORK_ERROR', 'The API could not be reached.', info) };\r\n } finally {\r\n clearTimeout(timer);\r\n signal?.removeEventListener('abort', onCallerAbort);\r\n }\r\n }\r\n\r\n /**\r\n * Parses the body. The FacePe backend answers `{ success: true, data }` or\r\n * `{ success: false, error: { code, message } }`; the envelope is unwrapped\r\n * and its error code kept. Any other JSON body is taken as the data itself.\r\n */\r\n private read<T>(status: number, ok: boolean, text: string, decode: FacePeDecoder<T>, info: RequestInfo): Result<T> {\r\n let parsed: JsonValue | undefined;\r\n if (text.trim() !== '') {\r\n try {\r\n const raw: unknown = JSON.parse(text);\r\n parsed = isJsonValue(raw) ? raw : undefined;\r\n } catch {\r\n parsed = undefined;\r\n }\r\n if (parsed === undefined && ok) return fail('INVALID_RESPONSE', 'The API returned a response that is not JSON.', info, status);\r\n }\r\n\r\n if (!ok) {\r\n const error = isJsonObject(parsed) ? parsed.error : undefined;\r\n if (isJsonObject(error) && typeof error.code === 'string' && typeof error.message === 'string') {\r\n return fail(error.code, error.message, info, status);\r\n }\r\n return fail('HTTP_ERROR', `The API answered with status ${status}.`, info, status);\r\n }\r\n\r\n const data = isJsonObject(parsed) && parsed.success === true && 'data' in parsed ? parsed.data : parsed;\r\n return decode(data ?? null);\r\n }\r\n}\r\n","import { createContext, useContext } from 'react';\nimport type { FacePeApiClient } from './FacePeApiClient.js';\n\n/**\n * Internal: the API client of the nearest `<FacePeProvider>`. Kept apart from\n * the public context so `useFacePe()` and `FacePeContextValue` are unchanged.\n */\nexport const FacePeApiContext = createContext<FacePeApiClient | null>(null);\nFacePeApiContext.displayName = 'FacePeApiContext';\n\n/** The API client of the nearest `<FacePeProvider>`, for SDK components. */\nexport function useFacePeApi(): FacePeApiClient {\n const client = useContext(FacePeApiContext);\n if (client === null) throw new Error('useFacePeApi must be used within a FacePeProvider');\n return client;\n}\n","/**\r\n * Internal: runtime validation of gateway payloads — the trust boundary, the\r\n * one place types are checked at runtime (architecture §7.5). Each decoder\r\n * accepts the documented shape, ignores unknown fields (forward\r\n * compatibility) and turns anything else into Failure INVAL_RESPONSE-style\r\n * `INVALID_PAYLOAD`, never an exception.\r\n */\r\nimport type {\r\n FacePeAvatarInfo,\r\n FacePeFormValues,\r\n FacePePickerOption,\r\n FacePeTimelineItem,\r\n FacePeTimelineItemStatus,\r\n JsonObject,\r\n JsonValue,\r\n Result,\r\n} from '../types/index.js';\r\nimport type { FacePeDecoder } from './FacePeApiClient.js';\r\nimport { isJsonObject } from './json.js';\r\n\r\nconst STATUSES: readonly FacePeTimelineItemStatus[] = ['completed', 'current', 'pending', 'error'];\r\n\r\nconst invalid = (what: string): Result<never> => ({\r\n success: false,\r\n error: { code: 'INVALID_PAYLOAD', message: `The gateway returned an invalid ${what}.` },\r\n});\r\n\r\nconst str = (o: JsonObject, key: string): string | undefined => (typeof o[key] === 'string' ? (o[key] as string) : undefined);\r\n\r\n/** `items` of an object, or undefined if the payload is not `{ <key>: [...] }`. */\r\nfunction listIn(data: JsonValue, key: string): readonly JsonValue[] | undefined {\r\n if (!isJsonObject(data)) return undefined;\r\n const list = data[key];\r\n return Array.isArray(list) ? list : undefined;\r\n}\r\n\r\nfunction timelineItem(value: JsonValue): FacePeTimelineItem | undefined {\r\n if (!isJsonObject(value)) return undefined;\r\n const id = str(value, 'id');\r\n const title = str(value, 'title');\r\n const timestamp = str(value, 'timestamp');\r\n const status = str(value, 'status') as FacePeTimelineItemStatus | undefined;\r\n if (id === undefined || title === undefined || timestamp === undefined) return undefined;\r\n if (status === undefined || !STATUSES.includes(status)) return undefined;\r\n const description = str(value, 'description');\r\n return { id, title, timestamp, status, ...(description === undefined ? {} : { description }) };\r\n}\r\n\r\n/** GET /orders/:id/timeline → `{ items: FacePeTimelineItem[] }`. */\r\nexport const decodeTimeline: FacePeDecoder<readonly FacePeTimelineItem[]> = (data) => {\r\n const list = listIn(data, 'items');\r\n if (list === undefined) return invalid('timeline');\r\n const items = list.map(timelineItem);\r\n if (items.some((item) => item === undefined)) return invalid('timeline item');\r\n return { success: true, data: items as FacePeTimelineItem[] };\r\n};\r\n\r\nfunction pickerOption(value: JsonValue): FacePePickerOption | undefined {\r\n if (!isJsonObject(value)) return undefined;\r\n const optionValue = str(value, 'value');\r\n const label = str(value, 'label');\r\n if (optionValue === undefined || label === undefined) return undefined;\r\n const description = str(value, 'description');\r\n return {\r\n value: optionValue,\r\n label,\r\n ...(description === undefined ? {} : { description }),\r\n ...(value.disabled === true ? { disabled: true } : {}),\r\n };\r\n}\r\n\r\n/** GET /locations/:id/categories → `{ options: FacePePickerOption[] }`. */\r\nexport const decodePickerOptions: FacePeDecoder<readonly FacePePickerOption[]> = (data) => {\r\n const list = listIn(data, 'options');\r\n if (list === undefined) return invalid('option list');\r\n const options = list.map(pickerOption);\r\n if (options.some((option) => option === undefined)) return invalid('option');\r\n return { success: true, data: options as FacePePickerOption[] };\r\n};\r\n\r\n/** GET/PUT /orders/:id/customer → `{ name, email, notes }`. */\r\nexport const decodeFormValues: FacePeDecoder<FacePeFormValues> = (data) => {\r\n if (!isJsonObject(data)) return invalid('customer');\r\n const name = str(data, 'name');\r\n const email = str(data, 'email');\r\n const notes = str(data, 'notes');\r\n if (name === undefined || email === undefined || notes === undefined) return invalid('customer');\r\n return { success: true, data: { name, email, notes } };\r\n};\r\n\r\nfunction avatarInfo(value: JsonValue | undefined): FacePeAvatarInfo | undefined {\r\n if (value === undefined || !isJsonObject(value)) return undefined;\r\n const id = str(value, 'id');\r\n const name = str(value, 'name');\r\n if (id === undefined || name === undefined) return undefined;\r\n const languages = Array.isArray(value.languages) ? value.languages.filter((l): l is string => typeof l === 'string') : [];\r\n return {\r\n id, name,\r\n gender: str(value, 'gender') ?? '',\r\n previewUrl: str(value, 'previewUrl') ?? null,\r\n description: str(value, 'description') ?? null,\r\n languages,\r\n };\r\n}\r\n\r\n/** GET /avatars/:avatarId → `{ avatar }`. */\r\nexport const decodeAvatar: FacePeDecoder<FacePeAvatarInfo> = (data) => {\r\n const avatar = isJsonObject(data) ? avatarInfo(data.avatar) : undefined;\r\n return avatar ? { success: true, data: avatar } : invalid('avatar');\r\n};\r\n\r\n/** GET /avatars → `{ avatars }`: the avatars the signed-in user may use. Entries that do not decode are skipped. */\r\nexport const decodeAvatarList: FacePeDecoder<readonly FacePeAvatarInfo[]> = (data) => {\r\n if (!isJsonObject(data) || !Array.isArray(data.avatars)) return invalid('avatars');\r\n return { success: true, data: data.avatars.map(avatarInfo).filter((a): a is FacePeAvatarInfo => a !== undefined) };\r\n};\r\n\r\n/**\r\n * What POST /avatars/:avatarId/sessions returns: how to connect. The gateway\r\n * never says where an avatar comes from, only the kind of connection:\r\n * `room` (join a media room) or `stream` (a hosted stream).\r\n */\r\nexport type FacePeAvatarConnection =\r\n | { readonly type: 'stream'; readonly usageId: string | null; readonly avatar: FacePeAvatarInfo; readonly token: string; readonly greeting: string | null }\r\n | { readonly type: 'room'; readonly usageId: string | null; readonly avatar: FacePeAvatarInfo; readonly url: string; readonly token: string };\r\n\r\nexport const decodeAvatarConnection: FacePeDecoder<FacePeAvatarConnection> = (data) => {\r\n if (!isJsonObject(data)) return invalid('avatar session');\r\n const avatar = avatarInfo(data.avatar);\r\n const usageId = typeof data.usageId === 'string' ? data.usageId : null;\r\n const c = data.connection;\r\n if (!avatar || !isJsonObject(c) || typeof c.token !== 'string' || c.token === '') return invalid('avatar session');\r\n if (c.type === 'stream') {\r\n const greeting = typeof c.greeting === 'string' ? c.greeting : null;\r\n return { success: true, data: { type: 'stream', usageId, avatar, token: c.token, greeting } };\r\n }\r\n if (c.type === 'room' && typeof c.url === 'string' && c.url !== '') {\r\n return { success: true, data: { type: 'room', usageId, avatar, url: c.url, token: c.token } };\r\n }\r\n return invalid('avatar session');\r\n};\r\n\r\n/** Gateway paths, one per component (entity ids are path-encoded). */\r\nexport const gatewayPath = {\r\n avatars: '/avatars',\r\n avatar: (avatarId: string) => `/avatars/${encodeURIComponent(avatarId)}`,\r\n avatarSessions: (avatarId: string) => `/avatars/${encodeURIComponent(avatarId)}/sessions`,\r\n endAvatarSession: (usageId: string) => `/avatar-sessions/${encodeURIComponent(usageId)}/end`,\r\n timeline: (orderId: string) => `/orders/${encodeURIComponent(orderId)}/timeline`,\r\n pickerOptions: (locationId: string) => `/locations/${encodeURIComponent(locationId)}/categories`,\r\n customer: (orderId: string) => `/orders/${encodeURIComponent(orderId)}/customer`,\r\n} as const;\r\n","import { useEffect, useState } from 'react';\nimport type { FacePeError } from '../types/index.js';\nimport type { FacePeDecoder } from './FacePeApiClient.js';\nimport { useFacePeApi } from './FacePeApiContext.js';\n\n/** What a component knows about data it fetches through the gateway. */\nexport type FacePeResource<T> =\n | { readonly status: 'idle' }\n | { readonly status: 'loading' }\n | { readonly status: 'ready'; readonly data: T }\n | { readonly status: 'failed'; readonly error: FacePeError };\n\nconst IDLE = { status: 'idle' } as const;\n\n/**\n * Internal: GETs `path` through the provider's API client and decodes it.\n * `path` null means \"nothing to fetch\" (the host passed the data itself).\n * A new path cancels the request in flight; so does unmounting. The component\n * reports a `failed` state through its own `error` event.\n */\nexport function useFacePeResource<T>(path: string | null, decode: FacePeDecoder<T>): FacePeResource<T> {\n const api = useFacePeApi();\n const [state, setState] = useState<{ path: string | null; resource: FacePeResource<T> }>({\n path: null,\n resource: IDLE,\n });\n\n useEffect(() => {\n if (path === null) return;\n const controller = new AbortController();\n setState({ path, resource: { status: 'loading' } });\n void api.get(path, { decode, signal: controller.signal }).then((result) => {\n if (controller.signal.aborted) return;\n setState({\n path,\n resource: result.success ? { status: 'ready', data: result.data } : { status: 'failed', error: result.error },\n });\n });\n return () => controller.abort();\n // `decode` is a module-level function; only the path decides a refetch.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [api, path]);\n\n if (path === null) return IDLE;\n // Before the effect has run for a new path, it is already loading.\n return state.path === path ? state.resource : { status: 'loading' };\n}\n","import { createContext, useContext } from 'react';\nimport type { FacePeEvent, FacePeTelemetryEvent } from '../types/index.js';\n\n/**\n * Internal: hands a telemetry record to the host's sink. The provider supplies\n * one that reads its current `telemetry` prop and isolates a throwing sink;\n * outside a provider it does nothing.\n */\nexport type FacePeTelemetryReporter = (event: FacePeTelemetryEvent) => void;\n\nconst noop: FacePeTelemetryReporter = () => undefined;\n\nexport const FacePeTelemetryContext = createContext<FacePeTelemetryReporter>(noop);\nFacePeTelemetryContext.displayName = 'FacePeTelemetryContext';\n\nexport function useFacePeTelemetryReporter(): FacePeTelemetryReporter {\n return useContext(FacePeTelemetryContext);\n}\n\n/** The telemetry record of a component event: its envelope minus the payload. */\nexport function telemetryOf(event: FacePeEvent<string, unknown>): FacePeTelemetryEvent {\n const { meta } = event;\n const payload = event.payload as { code?: unknown } | null;\n const code = event.type === 'error' && typeof payload?.code === 'string' ? payload.code : undefined;\n return {\n name: event.type,\n source: meta.source,\n correlationId: meta.correlationId,\n timestamp: meta.timestamp,\n sdkVersion: meta.sdkVersion,\n ...(meta.entityId === undefined ? {} : { entityId: meta.entityId }),\n ...(code === undefined ? {} : { attributes: { code } }),\n };\n}\n","/**\r\n * Internal: the event emitter every SDK component emits through. Not exported\r\n * from the package — hosts receive events through the components' `on…`\r\n * props, which the components subscribe to their emitter.\r\n */\r\nimport type {\r\n CorrelationId,\r\n EntityId,\r\n FacePeEvent,\r\n FacePeEventHandler,\r\n FacePeEventMap,\r\n} from '../types/index.js';\r\nimport { SDK_VERSION } from '../version.js';\r\nimport { createCorrelationId } from './createCorrelationId.js';\r\nimport { telemetryOf, type FacePeTelemetryReporter } from './telemetry.js';\r\n\r\ntype EventName<TEvents extends FacePeEventMap> = keyof TEvents & string;\r\n\r\n/** A listener for one event type: the public `FacePeEventHandler` for that event. */\r\nexport type FacePeListener<TEvents extends FacePeEventMap, K extends EventName<TEvents>> = FacePeEventHandler<\r\n FacePeEvent<K, TEvents[K]>\r\n>;\r\n\r\n/** Per-component values stamped on each event's meta, read at emit time. */\r\nexport type FacePeEventContext = { readonly entityId?: EntityId };\r\n\r\ntype ListenerSets<TEvents extends FacePeEventMap> = {\r\n [K in EventName<TEvents>]?: Set<FacePeListener<TEvents, K>>;\r\n};\r\n\r\n/**\r\n * A listener threw. Surface it like an uncaught error — in the browser,\r\n * `reportError` logs it and fires the window \"error\" event that error trackers\r\n * listen to — without stopping the other listeners or the component.\r\n */\r\nfunction reportListenerError(error: unknown, source: string, type: string): void {\r\n if (typeof globalThis.reportError === 'function') {\r\n globalThis.reportError(error);\r\n return;\r\n }\r\n console.error(`[FacePe] A \"${type}\" listener of ${source} threw:`, error);\r\n}\r\n\r\n/**\r\n * Typed publish/subscribe for one component's events.\r\n *\r\n * @typeParam TEvents - the component's event map (event name → payload type).\r\n */\r\nexport class FacePeEventEmitter<TEvents extends FacePeEventMap> {\r\n private listeners: ListenerSets<TEvents> = {};\r\n\r\n /**\r\n * @param source - the emitting component's name, stamped on every event's meta.\r\n * @param context - read on every emit, e.g. the component's current `entityId`.\r\n * @param report - receives the telemetry record of every emitted event.\r\n */\r\n constructor(\r\n private readonly source: string,\r\n private readonly context: () => FacePeEventContext = () => ({}),\r\n private readonly report: FacePeTelemetryReporter = () => undefined,\r\n ) {}\r\n\r\n /**\r\n * Subscribes a listener to one event type. The same function subscribed\r\n * twice is held once. Returns the matching unsubscribe function.\r\n */\r\n on<K extends EventName<TEvents>>(type: K, listener: FacePeListener<TEvents, K>): () => void {\r\n const set = this.listeners[type] ?? new Set<FacePeListener<TEvents, K>>();\r\n set.add(listener);\r\n this.listeners[type] = set;\r\n return () => this.off(type, listener);\r\n }\r\n\r\n /** Unsubscribes one listener; others on the same event are untouched. */\r\n off<K extends EventName<TEvents>>(type: K, listener: FacePeListener<TEvents, K>): void {\r\n const set = this.listeners[type];\r\n if (set === undefined) return;\r\n set.delete(listener);\r\n if (set.size === 0) delete this.listeners[type];\r\n }\r\n\r\n /** How many listeners an event type has (for cleanup checks). */\r\n listenerCount<K extends EventName<TEvents>>(type: K): number {\r\n return this.listeners[type]?.size ?? 0;\r\n }\r\n\r\n /** Removes every listener. */\r\n clear(): void {\r\n this.listeners = {};\r\n }\r\n\r\n /**\r\n * Wraps `payload` in the standard envelope and delivers it to every\r\n * listener of `type`, in subscription order. A listener that throws is\r\n * reported and skipped; the rest still run. The event is also reported to\r\n * telemetry (without its payload). Returns the event delivered.\r\n *\r\n * @param correlationId - pass one to tie several events to one action\r\n * (e.g. a submit attempt's `submit` or `error`); a new one otherwise.\r\n */\r\n emit<K extends EventName<TEvents>>(\r\n type: K,\r\n payload: TEvents[K],\r\n correlationId: CorrelationId = createCorrelationId(),\r\n ): FacePeEvent<K, TEvents[K]> {\r\n const { entityId } = this.context();\r\n const event: FacePeEvent<K, TEvents[K]> = {\r\n type,\r\n payload,\r\n meta: {\r\n schemaVersion: 1,\r\n correlationId,\r\n timestamp: new Date().toISOString(),\r\n sdkVersion: SDK_VERSION,\r\n source: this.source,\r\n ...(entityId === undefined ? {} : { entityId }),\r\n },\r\n };\r\n this.dispatch(event);\r\n this.report(telemetryOf(event));\r\n return event;\r\n }\r\n\r\n /**\r\n * Delivers an event that already has its envelope — e.g. a component's\r\n * `navigate` relayed to the provider, so both receive the very same event.\r\n * Same isolation as `emit`. Not reported to telemetry: `emit` already did.\r\n */\r\n dispatch<K extends EventName<TEvents>>(event: FacePeEvent<K, TEvents[K]>): void {\r\n const set = this.listeners[event.type];\r\n if (set === undefined) return;\r\n // A snapshot, so a listener that (un)subscribes during delivery cannot\r\n // change who receives this event.\r\n for (const listener of [...set]) {\r\n try {\r\n listener(event);\r\n } catch (error) {\r\n reportListenerError(error, this.source, event.type);\r\n }\r\n }\r\n }\r\n}\r\n","import { useState } from 'react';\r\nimport type { FacePeEventMap } from '../types/index.js';\r\nimport { FacePeEventEmitter, type FacePeEventContext } from './FacePeEventEmitter.js';\r\nimport { useFacePeTelemetryReporter, type FacePeTelemetryReporter } from './telemetry.js';\r\n\r\n/**\r\n * Internal: one emitter per component instance, created on first render and\r\n * kept for the component's life. Components subscribe their host handlers in\r\n * an effect (and unsubscribe in its cleanup), declared before any effect that\r\n * emits, so listeners are in place for `ready`.\r\n *\r\n * @param context - read on every emit; pass a function over a ref so it sees\r\n * current values (e.g. `() => ({ entityId: entityRef.current })`).\r\n * @param report - telemetry reporter; defaults to the nearest provider's (the\r\n * provider passes its own, as it sits above its own context).\r\n */\r\nexport function useFacePeEmitter<TEvents extends FacePeEventMap>(\r\n source: string,\r\n context?: () => FacePeEventContext,\r\n report?: FacePeTelemetryReporter,\r\n): FacePeEventEmitter<TEvents> {\r\n const fromProvider = useFacePeTelemetryReporter();\r\n const [emitter] = useState(() => new FacePeEventEmitter<TEvents>(source, context, report ?? fromProvider));\r\n return emitter;\r\n}\r\n","import { createContext, useContext } from 'react';\r\n\r\n/**\r\n * Internal: the provider's `avatarId`, the default for `<FacePeAvatar>`.\r\n * Kept apart from the public context so `FacePeContextValue` is unchanged.\r\n */\r\nexport const FacePeAvatarIdContext = createContext<string | undefined>(undefined);\r\nFacePeAvatarIdContext.displayName = 'FacePeAvatarIdContext';\r\n\r\nexport function useFacePeAvatarId(): string | undefined {\r\n return useContext(FacePeAvatarIdContext);\r\n}\r\n","import { createContext, useContext } from 'react';\nimport type { FacePeEvent, FacePeNavigationRequest } from '../types/index.js';\n\n/** Hands a component's `navigate` event to the provider's `onNavigate`. */\nexport type FacePeNavigationRelay = (event: FacePeEvent<'navigate', FacePeNavigationRequest>) => void;\n\n/**\n * Internal: the navigation side of the context bridge. Components emit\n * `navigate` to their own handler and relay the same event here; the host's\n * router does the navigating. Not exported from the package.\n */\nexport const FacePeNavigationContext = createContext<FacePeNavigationRelay>(() => undefined);\nFacePeNavigationContext.displayName = 'FacePeNavigationContext';\n\nexport function useFacePeNavigationRelay(): FacePeNavigationRelay {\n return useContext(FacePeNavigationContext);\n}\n","import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, type CSSProperties } from 'react';\r\nimport { FacePeApiClient, FacePeApiContext } from '../api/index.js';\r\nimport { FacePeTelemetryContext, useFacePeEmitter, type FacePeTelemetryReporter } from '../events/index.js';\r\nimport type {\r\n FacePeColorScheme,\r\n FacePeConfig,\r\n FacePeContextValue,\r\n FacePeProviderEvents,\r\n FacePeProviderProps,\r\n FacePeThemeTokens,\r\n} from '../types/index.js';\r\nimport { FacePeAvatarIdContext } from './avatar.js';\r\nimport { FacePeNavigationContext, type FacePeNavigationRelay } from './navigation.js';\r\n\r\ntype ThemeStyle = CSSProperties & { [K in `--fp-${string}`]?: string };\r\n\r\n/** Stands in for a missing `config` (one shared object, so it never changes identity). */\r\nconst NO_CONFIG: FacePeConfig = Object.freeze({});\r\n\r\n/**\r\n * The active token scheme as the documented `--fp-*` custom properties (rung\r\n * L1 → L4), on a wrapper that adds no layout box. Inline, so it holds even if\r\n * the host has not loaded the SDK stylesheet. `color-scheme` follows the\r\n * host's choice, so native controls match it; the components never read the\r\n * system preference themselves (§7.1).\r\n */\r\nfunction themeStyle(theme: FacePeThemeTokens, colorScheme: FacePeColorScheme | undefined): ThemeStyle {\r\n const style: ThemeStyle = { display: 'contents' };\r\n if (colorScheme !== undefined) style.colorScheme = colorScheme;\r\n const tokens: ReadonlyArray<[string | undefined, `--fp-${string}`]> = [\r\n [theme.colorSurface, '--fp-color-surface'],\r\n [theme.colorSurfaceMuted, '--fp-color-surface-muted'],\r\n [theme.colorText, '--fp-color-text'],\r\n [theme.colorMuted, '--fp-color-muted'],\r\n [theme.colorBorder, '--fp-color-border'],\r\n [theme.colorAccent, '--fp-color-accent'],\r\n [theme.colorOnAccent, '--fp-color-on-accent'],\r\n [theme.colorDanger, '--fp-color-danger'],\r\n [theme.colorSuccess, '--fp-color-success'],\r\n [theme.fontFamily, '--fp-font-family'],\r\n [theme.fontSize, '--fp-font-size'],\r\n [theme.spacing, '--fp-spacing'],\r\n [theme.radius, '--fp-radius'],\r\n [theme.shadow, '--fp-shadow'],\r\n ];\r\n for (const [value, variable] of tokens) {\r\n if (value !== undefined) style[variable] = value;\r\n }\r\n return style;\r\n}\r\n\r\n// null means \"no provider above\": useFacePe() turns that into a clear error\r\n// instead of letting components run on a silent default configuration.\r\nconst FacePeContext = createContext<FacePeContextValue | null>(null);\r\nFacePeContext.displayName = 'FacePeContext';\r\n\r\n/**\r\n * Makes the host's FacePe configuration available to every FacePe component\r\n * rendered below it, and gives them an API client scoped to this provider.\r\n *\r\n * @example\r\n * <FacePeProvider\r\n * config={{ locale: 'en-IN', density: 'compact' }}\r\n * apiBaseUrl=\"https://api.example.com/api/v1\"\r\n * getToken={({ forceRefresh }) => auth.accessToken({ forceRefresh })}\r\n * onSessionExpired={() => auth.signIn()}\r\n * >\r\n * <App />\r\n * </FacePeProvider>\r\n */\r\nexport function FacePeProvider({ config, children, ...settings }: FacePeProviderProps) {\r\n // `config` is required by the types, but a JavaScript host gets no compile\r\n // error for leaving it out; treat that as \"no configuration\" rather than\r\n // letting components fail on `undefined`. Memoised on the config object, so\r\n // consumers re-render only when the host passes a new config.\r\n const value = useMemo<FacePeContextValue>(() => ({ config: config ?? NO_CONFIG }), [config]);\r\n\r\n // The client reads these on every request, so a new apiBaseUrl or getToken\r\n // takes effect without recreating it.\r\n const settingsRef = useRef(settings);\r\n settingsRef.current = settings;\r\n\r\n // The host's telemetry sink, read on every record (a new `telemetry` prop\r\n // takes effect at once). A sink that throws is reported, never propagated\r\n // into the component that produced the record.\r\n const reportTelemetry = useCallback<FacePeTelemetryReporter>((record) => {\r\n const sink = settingsRef.current.telemetry;\r\n if (sink === undefined) return;\r\n try {\r\n sink.track(record);\r\n } catch (error) {\r\n if (typeof globalThis.reportError === 'function') globalThis.reportError(error);\r\n else console.error('[FacePe] The telemetry sink threw:', error);\r\n }\r\n }, []);\r\n\r\n const events = useFacePeEmitter<FacePeProviderEvents>('FacePeProvider', undefined, reportTelemetry);\r\n useEffect(() => {\r\n const unsubscribe = [\r\n events.on('sessionExpired', (e) => settingsRef.current.onSessionExpired?.(e)),\r\n events.on('navigate', (e) => settingsRef.current.onNavigate?.(e)),\r\n ];\r\n return () => unsubscribe.forEach((off) => off());\r\n }, [events]);\r\n\r\n // Components relay their own `navigate` event here, so the host's\r\n // provider-level onNavigate gets the same envelope (source = component).\r\n const relayNavigation = useCallback<FacePeNavigationRelay>((event) => events.dispatch(event), [events]);\r\n\r\n // One client per provider instance: no singleton, no state shared between\r\n // providers on the same page.\r\n const [api] = useState(\r\n () =>\r\n new FacePeApiClient({\r\n settings: () => ({\r\n baseUrl: settingsRef.current.apiBaseUrl,\r\n getToken: settingsRef.current.getToken,\r\n timeoutMs: settingsRef.current.requestTimeoutMs,\r\n }),\r\n onSessionExpired: (payload) => {\r\n events.emit('sessionExpired', payload);\r\n },\r\n onTelemetry: reportTelemetry,\r\n }),\r\n );\r\n\r\n // The second token scheme (§7.1): dark tokens win while the host has chosen\r\n // 'dark', falling back to the main theme per token.\r\n const { theme, darkTheme, colorScheme } = settings;\r\n const style = useMemo(() => {\r\n if (theme === undefined && darkTheme === undefined && colorScheme === undefined) return undefined;\r\n const active = colorScheme === 'dark' ? { ...theme, ...darkTheme } : { ...theme };\r\n return themeStyle(active, colorScheme);\r\n }, [theme, darkTheme, colorScheme]);\r\n\r\n return (\r\n <FacePeContext.Provider value={value}>\r\n <FacePeApiContext.Provider value={api}>\r\n <FacePeTelemetryContext.Provider value={reportTelemetry}>\r\n <FacePeNavigationContext.Provider value={relayNavigation}>\r\n <FacePeAvatarIdContext.Provider value={settings.avatarId}>\r\n {/* Only with a theme: without one the provider adds no DOM at all. */}\r\n {style === undefined ? (\r\n children\r\n ) : (\r\n <div style={style}>{children}</div>\r\n )}\r\n </FacePeAvatarIdContext.Provider>\r\n </FacePeNavigationContext.Provider>\r\n </FacePeTelemetryContext.Provider>\r\n </FacePeApiContext.Provider>\r\n </FacePeContext.Provider>\r\n );\r\n}\r\n\r\n/**\r\n * Reads the configuration from the nearest `<FacePeProvider>`.\r\n *\r\n * @throws Error when called outside a `<FacePeProvider>`.\r\n */\r\nexport function useFacePe(): FacePeContextValue {\r\n const value = useContext(FacePeContext);\r\n if (value === null) {\r\n throw new Error('useFacePe must be used within a FacePeProvider');\r\n }\r\n return value;\r\n}\r\n","/**\n * Internal: the root classes every FacePe component shares — the token\n * defaults plus the L2 `emphasis` and `size` variants.\n */\nimport type { FacePeEmphasis, FacePeSize } from '../../types/index.js';\nimport tokens from './tokens.module.css';\n\nconst EMPHASIS: Readonly<Record<FacePeEmphasis, string>> = {\n subtle: tokens.subtle,\n default: tokens.framed,\n strong: tokens.elevated,\n};\n\nconst SIZE: Readonly<Record<FacePeSize, string>> = {\n small: tokens.small,\n medium: tokens.medium,\n large: tokens.large,\n};\n\nexport function surfaceClass(emphasis: FacePeEmphasis = 'default', size: FacePeSize = 'medium'): string {\n return `${tokens.root} ${EMPHASIS[emphasis]} ${SIZE[size]}`;\n}\n","import { Component, type ReactNode } from 'react';\r\nimport { FacePeEventEmitter } from '../../events/index.js';\r\nimport type {\r\n EntityId,\r\n FacePeError,\r\n FacePeEvent,\r\n FacePeEventHandler,\r\n FacePeFallbackContext,\r\n FacePeSlot,\r\n} from '../../types/index.js';\r\nimport { surfaceClass } from './surface.js';\r\nimport styles from './FacePeErrorBoundary.module.css';\r\n\r\ntype Props = {\r\n /** The wrapped component's name, stamped on the error event. */\r\n readonly source: string;\r\n readonly entityId?: EntityId;\r\n readonly onError?: FacePeEventHandler<FacePeEvent<'error', FacePeError>>;\r\n readonly fallback?: FacePeSlot<FacePeFallbackContext>;\r\n readonly children?: ReactNode;\r\n};\r\n\r\ntype State = { readonly error: FacePeError | null };\r\n\r\n// Deliberately generic: the thrown value can hold anything (host slot code,\r\n// data), so none of it is copied into an event the host may log or display.\r\nconst RENDER_FAILED: FacePeError = { code: 'RENDER_FAILED', message: 'The component failed to render.' };\r\n\r\n/**\r\n * Internal: keeps a failing FacePe component from taking the host's React tree\r\n * down with it. Reports `error` (code RENDER_FAILED) through the same event\r\n * envelope as every other event, then shows the host's `fallback` slot, or a\r\n * short message. To retry, the host remounts the component (e.g. a new `key`).\r\n */\r\nexport class FacePeErrorBoundary extends Component<Props, State> {\r\n override state: State = { error: null };\r\n\r\n private readonly events = new FacePeEventEmitter<{ error: FacePeError }>(this.props.source, () => ({\r\n entityId: this.props.entityId,\r\n }));\r\n\r\n constructor(props: Props) {\r\n super(props);\r\n // Read through this.props at call time, so a new onError prop is honoured.\r\n this.events.on('error', (event) => this.props.onError?.(event));\r\n }\r\n\r\n static getDerivedStateFromError(): State {\r\n return { error: RENDER_FAILED };\r\n }\r\n\r\n override componentDidCatch(): void {\r\n this.events.emit('error', RENDER_FAILED);\r\n }\r\n\r\n override render(): ReactNode {\r\n const { error } = this.state;\r\n if (error === null) return this.props.children;\r\n const { fallback } = this.props;\r\n if (fallback !== undefined) return typeof fallback === 'function' ? fallback({ error }) : fallback;\r\n return (\r\n <div role=\"alert\" className={`${surfaceClass()} ${styles.fallback}`}>\r\n This content could not be displayed.\r\n </div>\r\n );\r\n }\r\n}\r\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n useState,\n type ChangeEvent,\n type FormEvent,\n} from 'react';\nimport { decodeFormValues, gatewayPath, useFacePeApi, useFacePeResource } from '../../api/index.js';\nimport { useFacePe } from '../../context/index.js';\nimport { createCorrelationId, useFacePeEmitter } from '../../events/index.js';\nimport { FacePeErrorBoundary } from '../shared/FacePeErrorBoundary.js';\nimport type {\n AsyncResult,\n Failure,\n FacePeFormEvents,\n FacePeFormHandle,\n FacePeFormProps,\n FacePeFormValues,\n JsonValue,\n Result,\n} from '../../types/index.js';\nimport { surfaceClass } from '../shared/surface.js';\nimport styles from './FacePeForm.module.css';\n\nconst SOURCE = 'FacePeForm';\n\ntype FieldName = keyof FacePeFormValues;\ntype FieldErrors = Partial<Record<FieldName, string>>;\ntype FieldElement = HTMLInputElement | HTMLTextAreaElement;\n\n/** Field order: errors are focused in this order. */\nconst FIELDS: readonly FieldName[] = ['name', 'email', 'notes'];\nconst EMAIL = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nfunction initialValuesOf(initial: Partial<FacePeFormValues> | undefined): FacePeFormValues {\n return { name: initial?.name ?? '', email: initial?.email ?? '', notes: initial?.notes ?? '' };\n}\n\nfunction trimmed(values: FacePeFormValues): FacePeFormValues {\n return { name: values.name.trim(), email: values.email.trim(), notes: values.notes.trim() };\n}\n\nfunction validateValues(values: FacePeFormValues): FieldErrors {\n const errors: FieldErrors = {};\n if (!values.name) errors.name = 'Name is required.';\n if (!values.email) errors.email = 'Email is required.';\n else if (!EMAIL.test(values.email)) errors.email = 'Enter a valid email address.';\n return errors;\n}\n\nfunction failure(code: string, message: string, details?: JsonValue): Failure {\n return { success: false, error: details === undefined ? { code, message } : { code, message, details } };\n}\n\n/**\n * A basic FacePe form: name, email and notes, with required-field validation.\n *\n * Reads shared configuration from the nearest `<FacePeProvider>`; its own\n * `mode`, `density` and `locale` props override the provider's. In `view`\n * mode (the default) the fields are read-only and there is no submit action.\n *\n * Styles ship separately: import \"@facepe/widgets/styles.css\" once in the host.\n */\nexport const FacePeForm = forwardRef<FacePeFormHandle, FacePeFormProps>(function FacePeForm(props, ref) {\n // Outside the boundary on purpose: a missing provider is a setup error that\n // must surface, not be contained as a render failure.\n const { config } = useFacePe();\n return (\n <FacePeErrorBoundary\n source={SOURCE}\n entityId={props.entityId ?? config.entityId}\n onError={props.onError}\n fallback={props.slots?.fallback}\n >\n <FacePeFormContent {...props} ref={ref} />\n </FacePeErrorBoundary>\n );\n});\n\nFacePeForm.displayName = 'FacePeForm';\n\nconst FacePeFormContent = forwardRef<FacePeFormHandle, FacePeFormProps>(function FacePeFormContent(props, ref) {\n const { config } = useFacePe();\n const mode = props.mode ?? config.mode ?? 'view';\n const entityId = props.entityId ?? config.entityId;\n const density = props.density ?? config.density ?? 'comfortable';\n const locale = props.locale ?? config.locale;\n const readOnly = mode === 'view';\n\n // Values passed by the host win; otherwise the entity (an order) is passed\n // by reference: its customer details are loaded, and saved on submit.\n const byReference = props.initialValues === undefined && entityId !== undefined;\n const resource = useFacePeResource(byReference ? gatewayPath.customer(entityId) : null, decodeFormValues);\n const loading = resource.status === 'loading';\n const loaded = resource.status === 'ready' ? resource.data : null;\n const loadError = resource.status === 'failed' ? resource.error : null;\n const api = useFacePeApi();\n\n const [values, setValues] = useState<FacePeFormValues>(() => initialValuesOf(props.initialValues));\n const [errors, setErrors] = useState<FieldErrors>({});\n const [submitting, setSubmitting] = useState(false);\n const [formError, setFormError] = useState<string | null>(null);\n\n // Refs let the async submit and the imperative handle see current values and\n // handlers without being recreated on every keystroke.\n const propsRef = useRef(props);\n propsRef.current = props;\n const entityRef = useRef(entityId);\n entityRef.current = entityId;\n const valuesRef = useRef(values);\n valuesRef.current = values;\n const submittingRef = useRef(false);\n // The last values loaded or saved through the gateway: what reset() restores.\n const baselineRef = useRef<FacePeFormValues | null>(null);\n const byReferenceRef = useRef(byReference);\n byReferenceRef.current = byReference;\n const readyRef = useRef(false);\n const fieldRefs = useRef<Partial<Record<FieldName, FieldElement | null>>>({});\n\n const id = useId();\n const fieldId = (field: FieldName) => `${id}-${field}`;\n const errorId = (field: FieldName) => `${id}-${field}-error`;\n\n // The host's handlers listen on this form's emitter, read through propsRef so\n // a new handler prop needs no re-subscribing. Subscribed once per mount and\n // removed on unmount; declared before the ready effect so they hear it.\n const events = useFacePeEmitter<FacePeFormEvents>(SOURCE, () => ({ entityId: entityRef.current }));\n useEffect(() => {\n const unsubscribe = [\n events.on('ready', (e) => propsRef.current.onReady?.(e)),\n events.on('submit', (e) => propsRef.current.onSubmit?.(e)),\n events.on('cancel', (e) => propsRef.current.onCancel?.(e)),\n events.on('error', (e) => propsRef.current.onError?.(e)),\n ];\n return () => unsubscribe.forEach((off) => off());\n }, [events]);\n\n // Emitted once per mount (the guard also covers StrictMode's double effect).\n useEffect(() => {\n if (readyRef.current) return;\n readyRef.current = true;\n events.emit('ready', null);\n }, [events]);\n\n // Loaded details replace the (empty) starting values.\n useEffect(() => {\n if (loaded === null) return;\n baselineRef.current = loaded;\n setValues(loaded);\n setErrors({});\n }, [loaded]);\n\n // A failed load is reported once, after `ready`.\n useEffect(() => {\n if (loadError !== null) events.emit('error', loadError);\n }, [loadError, events]);\n\n /** Validates current values, shows errors, and focuses the first invalid field. */\n const check = useCallback((): Result<FacePeFormValues> => {\n const clean = trimmed(valuesRef.current);\n const found = validateValues(clean);\n setErrors(found);\n const firstInvalid = FIELDS.find((field) => found[field] !== undefined);\n if (firstInvalid === undefined) return { success: true, data: clean };\n\n fieldRefs.current[firstInvalid]?.focus();\n const fields: Record<string, string> = {};\n for (const field of FIELDS) {\n const message = found[field];\n if (message !== undefined) fields[field] = message;\n }\n return failure('VALIDATION_FAILED', 'One or more fields are invalid.', { fields });\n }, []);\n\n const submit = useCallback(async (): AsyncResult<FacePeFormValues> => {\n if (readOnly) return failure('READ_ONLY', 'The form is in view mode.');\n if (submittingRef.current) return failure('SUBMIT_IN_PROGRESS', 'A submission is already in progress.');\n\n const checked = check();\n if (!checked.success) return checked;\n\n // One correlation id ties this attempt's submit or error event together.\n const correlationId = createCorrelationId();\n submittingRef.current = true;\n setSubmitting(true);\n setFormError(null);\n try {\n const action = propsRef.current.submitAction;\n let outcome: Result<void> = { success: true, data: undefined };\n let submitted = checked.data;\n if (action) {\n try {\n outcome = await action(checked.data);\n } catch (err) {\n outcome = failure('SUBMIT_FAILED', err instanceof Error ? err.message : 'Submission failed.');\n }\n } else if (byReferenceRef.current && entityRef.current !== undefined) {\n // Passed by reference: save to the entity through the gateway.\n const { name, email, notes } = checked.data;\n const saved = await api.put(gatewayPath.customer(entityRef.current), { name, email, notes }, { decode: decodeFormValues });\n if (saved.success) {\n submitted = saved.data;\n baselineRef.current = saved.data;\n } else {\n outcome = saved;\n }\n }\n if (!outcome.success) {\n setFormError('Submission failed. Please try again.');\n events.emit('error', outcome.error, correlationId);\n return outcome;\n }\n events.emit('submit', submitted, correlationId);\n return { success: true, data: submitted };\n } finally {\n submittingRef.current = false;\n setSubmitting(false);\n }\n }, [check, readOnly, events, api]);\n\n const validate = useCallback(async (): AsyncResult<FacePeFormValues> => check(), [check]);\n\n const reset = useCallback(async (): AsyncResult<void> => {\n setValues(baselineRef.current ?? initialValuesOf(propsRef.current.initialValues));\n setErrors({});\n setFormError(null);\n return { success: true, data: undefined };\n }, []);\n\n const focus = useCallback(async (): AsyncResult<void> => {\n const first = fieldRefs.current[FIELDS[0]];\n if (!first) return failure('NOTHING_TO_FOCUS', 'The form has no field to focus.');\n first.focus();\n return { success: true, data: undefined };\n }, []);\n\n // The architecture's handle (§7.3): focus, validate, reset. Submitting is a\n // user action (the button, or the `actions` slot), reported as `submit`.\n useImperativeHandle(ref, () => ({ validate, reset, focus }), [validate, reset, focus]);\n\n const handleSubmit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n void submit();\n };\n\n const handleCancel = () => {\n events.emit('cancel', null);\n };\n\n const handleChange = (field: FieldName) => (event: ChangeEvent<FieldElement>) => {\n const value = event.target.value;\n setValues((prev) => ({ ...prev, [field]: value }));\n // Clear a field's error as soon as the user edits it.\n if (errors[field] !== undefined) setErrors((prev) => ({ ...prev, [field]: undefined }));\n };\n\n // Shared attributes that wire a field to its label and error message.\n const fieldProps = (field: FieldName) => {\n const hasError = errors[field] !== undefined;\n return {\n id: fieldId(field),\n name: field,\n value: values[field],\n onChange: handleChange(field),\n readOnly,\n disabled: submitting || loading,\n 'aria-invalid': hasError,\n 'aria-describedby': hasError ? errorId(field) : undefined,\n className: hasError ? `${styles.control} ${styles.invalid}` : styles.control,\n ref: (element: FieldElement | null) => {\n fieldRefs.current[field] = element;\n },\n };\n };\n\n const fieldError = (field: FieldName) =>\n errors[field] === undefined ? null : (\n <p id={errorId(field)} className={styles.error}>\n {errors[field]}\n </p>\n );\n\n const actionsSlot = props.slots?.actions;\n\n return (\n <form\n className={[\n surfaceClass(props.emphasis, props.size),\n styles.form,\n density === 'compact' ? styles.compact : styles.comfortable,\n props.variant === 'inline' ? styles.inline : styles.stacked,\n ].join(' ')}\n lang={locale}\n noValidate\n aria-busy={submitting || loading}\n onSubmit={handleSubmit}\n >\n {props.slots?.header}\n\n <div className={`${styles.field} ${styles.half}`}>\n <label htmlFor={fieldId('name')} className={styles.label}>\n Name <span aria-hidden=\"true\">*</span>\n </label>\n <input type=\"text\" autoComplete=\"name\" required {...fieldProps('name')} />\n {fieldError('name')}\n </div>\n\n <div className={`${styles.field} ${styles.half}`}>\n <label htmlFor={fieldId('email')} className={styles.label}>\n Email <span aria-hidden=\"true\">*</span>\n </label>\n <input type=\"email\" autoComplete=\"email\" inputMode=\"email\" required {...fieldProps('email')} />\n {fieldError('email')}\n </div>\n\n <div className={styles.field}>\n <label htmlFor={fieldId('notes')} className={styles.label}>\n Notes\n </label>\n <textarea rows={3} {...fieldProps('notes')} />\n </div>\n\n {loadError !== null && (\n <p role=\"alert\" className={styles.formError}>\n The details could not be loaded.\n </p>\n )}\n\n {formError !== null && (\n <p role=\"alert\" className={styles.formError}>\n {formError}\n </p>\n )}\n\n <div className={styles.actions}>\n {actionsSlot !== undefined ? (\n typeof actionsSlot === 'function' ? (\n actionsSlot({ submit: () => void submit(), cancel: handleCancel, submitting, readOnly })\n ) : (\n actionsSlot\n )\n ) : (\n <>\n <button type=\"button\" className={styles.secondary} onClick={handleCancel} disabled={submitting}>\n Cancel\n </button>\n {!readOnly && (\n <button type=\"submit\" className={styles.primary} disabled={submitting || loading}>\n {submitting ? 'Submitting…' : 'Submit'}\n </button>\n )}\n </>\n )}\n </div>\n\n {props.slots?.footer}\n </form>\n );\n});\n\nFacePeFormContent.displayName = 'FacePeFormContent';\n","import {\r\n forwardRef,\r\n useCallback,\r\n useEffect,\r\n useId,\r\n useImperativeHandle,\r\n useMemo,\r\n useRef,\r\n useState,\r\n type ChangeEvent,\r\n} from 'react';\r\nimport { decodePickerOptions, gatewayPath, useFacePeResource } from '../../api/index.js';\r\nimport { useFacePe } from '../../context/index.js';\r\nimport { useFacePeEmitter } from '../../events/index.js';\r\nimport { FacePeErrorBoundary } from '../shared/FacePeErrorBoundary.js';\r\nimport type {\r\n AsyncResult,\r\n FacePeError,\r\n FacePePickerEvents,\r\n FacePePickerHandle,\r\n FacePePickerOption,\r\n FacePePickerProps,\r\n FacePePickerSelection,\r\n Failure,\r\n} from '../../types/index.js';\r\nimport { surfaceClass } from '../shared/surface.js';\r\nimport styles from './FacePePicker.module.css';\r\n\r\nconst SOURCE = 'FacePePicker';\r\nconst DESCRIPTIONS_FLAG = 'picker.descriptions';\r\n\r\nconst NO_OPTIONS: readonly FacePePickerOption[] = [];\r\n\r\n/** How `defaultValue` resolved: the value to preselect, or why it cannot be used. */\r\ntype ResolvedDefault = { value: string | null; error: FacePeError | null };\r\n\r\nfunction failure(code: string, message: string): Failure {\r\n return { success: false, error: { code, message } };\r\n}\r\n\r\n/** The value `defaultValue` resolves to, or the reason it cannot be used. */\r\nfunction resolveDefault(\r\n defaultValue: string | undefined,\r\n options: readonly FacePePickerOption[],\r\n): ResolvedDefault {\r\n if (defaultValue === undefined) return { value: null, error: null };\r\n const option = options.find((o) => o.value === defaultValue);\r\n if (option === undefined) {\r\n return { value: null, error: { code: 'INVALID_DEFAULT_VALUE', message: `No option has the value \"${defaultValue}\".` } };\r\n }\r\n if (option.disabled === true) {\r\n return { value: null, error: { code: 'INVALID_DEFAULT_VALUE', message: `Option \"${defaultValue}\" is disabled.` } };\r\n }\r\n return { value: option.value, error: null };\r\n}\r\n\r\n/**\r\n * A single-choice FacePe picker built on a native radio group, so arrow keys,\r\n * focus and the selected/disabled states work and are announced natively.\r\n *\r\n * Reads shared configuration from the nearest `<FacePeProvider>`; its own\r\n * `mode`, `density`, `locale` and `featureFlags` props override the provider's.\r\n * In `view` mode (the default) the current selection is shown but cannot be\r\n * changed.\r\n *\r\n * Styles ship separately: import \"@facepe/widgets/styles.css\" once in the host.\r\n */\r\nexport const FacePePicker = forwardRef<FacePePickerHandle, FacePePickerProps>(function FacePePicker(props, ref) {\r\n // Outside the boundary on purpose: a missing provider is a setup error that\r\n // must surface, not be contained as a render failure.\r\n const { config } = useFacePe();\r\n return (\r\n <FacePeErrorBoundary\r\n source={SOURCE}\r\n entityId={props.entityId ?? config.entityId}\r\n onError={props.onError}\r\n fallback={props.slots?.fallback}\r\n >\r\n <FacePePickerContent {...props} ref={ref} />\r\n </FacePeErrorBoundary>\r\n );\r\n});\r\n\r\nFacePePicker.displayName = 'FacePePicker';\r\n\r\nconst FacePePickerContent = forwardRef<FacePePickerHandle, FacePePickerProps>(function FacePePickerContent(props, ref) {\r\n const { config } = useFacePe();\r\n const mode = props.mode ?? config.mode ?? 'view';\r\n const entityId = props.entityId ?? config.entityId;\r\n const density = props.density ?? config.density ?? 'comfortable';\r\n const locale = props.locale ?? config.locale;\r\n const showDescriptions =\r\n props.featureFlags?.[DESCRIPTIONS_FLAG] ?? config.featureFlags?.[DESCRIPTIONS_FLAG] ?? false;\r\n const readOnly = mode === 'view';\r\n\r\n // Options passed by the host win; otherwise the entity (a location) is\r\n // passed by reference and its menu categories are fetched through the gateway.\r\n const resource = useFacePeResource(\r\n props.options === undefined && entityId !== undefined ? gatewayPath.pickerOptions(entityId) : null,\r\n decodePickerOptions,\r\n );\r\n const options = props.options ?? (resource.status === 'ready' ? resource.data : NO_OPTIONS);\r\n const loading = resource.status === 'loading';\r\n const loadError = resource.status === 'failed' ? resource.error : null;\r\n\r\n // defaultValue is read once, like an uncontrolled input's — as soon as the\r\n // options are known (at once, or when the fetch completes).\r\n const [initial, setInitial] = useState<ResolvedDefault | null>(() =>\r\n loading ? null : resolveDefault(props.defaultValue, options),\r\n );\r\n const [selectedValue, setSelectedValue] = useState<string | null>(initial?.value ?? null);\r\n\r\n const optionsByValue = useMemo(() => new Map(options.map((o) => [o.value, o])), [options]);\r\n // A selection whose option has since been removed counts as no selection.\r\n const selected = selectedValue === null ? undefined : optionsByValue.get(selectedValue);\r\n\r\n const propsRef = useRef(props);\r\n propsRef.current = props;\r\n const entityRef = useRef(entityId);\r\n entityRef.current = entityId;\r\n const selectedRef = useRef<string | null>(selected?.value ?? null);\r\n selectedRef.current = selected?.value ?? null;\r\n const readyRef = useRef(false);\r\n const groupRef = useRef<HTMLDivElement | null>(null);\r\n\r\n const id = useId();\r\n const legendId = `${id}-legend`;\r\n\r\n // The host's handlers listen on this picker's emitter, read through propsRef\r\n // so a new handler prop needs no re-subscribing. Subscribed once per mount and\r\n // removed on unmount; declared before the ready effect so they hear it.\r\n const events = useFacePeEmitter<FacePePickerEvents>(SOURCE, () => ({ entityId: entityRef.current }));\r\n useEffect(() => {\r\n const unsubscribe = [\r\n events.on('ready', (e) => propsRef.current.onReady?.(e)),\r\n events.on('select', (e) => propsRef.current.onSelect?.(e)),\r\n events.on('error', (e) => propsRef.current.onError?.(e)),\r\n ];\r\n return () => unsubscribe.forEach((off) => off());\r\n }, [events]);\r\n\r\n // Emitted once per mount (the guard also covers StrictMode's double effect).\r\n useEffect(() => {\r\n if (readyRef.current) return;\r\n readyRef.current = true;\r\n events.emit('ready', null);\r\n }, [events]);\r\n\r\n // Fetched options arrived: resolve defaultValue against them, once. A failed\r\n // fetch leaves nothing to resolve against, so it is not reported as a bad default.\r\n useEffect(() => {\r\n if (initial !== null || loading) return;\r\n const resolved: ResolvedDefault =\r\n loadError === null ? resolveDefault(propsRef.current.defaultValue, options) : { value: null, error: null };\r\n selectedRef.current = resolved.value;\r\n setSelectedValue(resolved.value);\r\n setInitial(resolved);\r\n }, [initial, loading, loadError, options]);\r\n\r\n // An unusable defaultValue, and a failed fetch, are each reported once, after `ready`.\r\n const reportedRef = useRef<ResolvedDefault | null>(null);\r\n useEffect(() => {\r\n if (initial === null || initial.error === null || reportedRef.current === initial) return;\r\n reportedRef.current = initial;\r\n events.emit('error', initial.error);\r\n }, [initial, events]);\r\n useEffect(() => {\r\n if (loadError !== null) events.emit('error', loadError);\r\n }, [loadError, events]);\r\n\r\n /** Selects `value` and emits `select`; the one path for users and the handle alike. */\r\n const selectValue = useCallback(\r\n async (value: string): AsyncResult<FacePePickerSelection> => {\r\n if (readOnly) return failure('READ_ONLY', 'The picker is in view mode.');\r\n const option = optionsByValue.get(value);\r\n if (option === undefined) return failure('OPTION_NOT_FOUND', `No option has the value \"${value}\".`);\r\n if (option.disabled === true) return failure('OPTION_DISABLED', `Option \"${value}\" is disabled.`);\r\n\r\n const selection: FacePePickerSelection = {\r\n value: option.value,\r\n label: option.label,\r\n previousValue: selectedRef.current,\r\n };\r\n // Re-selecting the current option changes nothing, so it emits nothing.\r\n if (selectedRef.current === option.value) return { success: true, data: selection };\r\n\r\n selectedRef.current = option.value;\r\n setSelectedValue(option.value);\r\n events.emit('select', selection);\r\n return { success: true, data: selection };\r\n },\r\n [optionsByValue, readOnly, events],\r\n );\r\n\r\n const focus = useCallback(async (): AsyncResult<void> => {\r\n // Focus the checked radio if there is one, else the first enabled one:\r\n // the same radio the Tab key would land on.\r\n const target =\r\n groupRef.current?.querySelector<HTMLInputElement>('input:checked') ??\r\n groupRef.current?.querySelector<HTMLInputElement>('input:not(:disabled)');\r\n if (target == null) return failure('NOTHING_TO_FOCUS', 'The picker has no selectable option.');\r\n target.focus();\r\n return { success: true, data: undefined };\r\n }, []);\r\n\r\n const reset = useCallback(async (): AsyncResult<void> => {\r\n if (readOnly) return failure('READ_ONLY', 'The picker is in view mode.');\r\n const value = initial?.value ?? null;\r\n selectedRef.current = value;\r\n setSelectedValue(value);\r\n return { success: true, data: undefined };\r\n }, [readOnly, initial]);\r\n\r\n // The architecture's handle (§7.3): focus and reset. Selecting is a user\r\n // action, reported as `select`.\r\n useImperativeHandle(ref, () => ({ focus, reset }), [focus, reset]);\r\n\r\n const handleChange = useCallback(\r\n (event: ChangeEvent<HTMLInputElement>) => {\r\n void selectValue(event.target.value);\r\n },\r\n [selectValue],\r\n );\r\n\r\n const optionSlot = props.slots?.option;\r\n\r\n return (\r\n <fieldset\r\n className={[\r\n surfaceClass(props.emphasis, props.size),\r\n styles.picker,\r\n density === 'compact' ? styles.compact : styles.comfortable,\r\n props.variant === 'grid' ? styles.grid : styles.list,\r\n ].join(' ')}\r\n lang={locale}\r\n aria-busy={loading}\r\n >\r\n <legend id={legendId} className={styles.legend}>\r\n {props.label ?? 'Choose an option'}\r\n </legend>\r\n\r\n {props.slots?.header}\r\n\r\n {loading ? (\r\n <p role=\"status\" className={styles.empty}>\r\n Loading options…\r\n </p>\r\n ) : loadError !== null ? (\r\n <p role=\"alert\" className={styles.empty}>\r\n The options could not be loaded.\r\n </p>\r\n ) : options.length === 0 ? (\r\n <div className={styles.empty}>{props.slots?.emptyState ?? <p>No options available.</p>}</div>\r\n ) : (\r\n <div\r\n ref={groupRef}\r\n role=\"radiogroup\"\r\n aria-labelledby={legendId}\r\n aria-readonly={readOnly}\r\n className={styles.options}\r\n >\r\n {options.map((option) => {\r\n const isSelected = option.value === selected?.value;\r\n const isDisabled = option.disabled === true;\r\n const inputId = `${id}-${option.value}`;\r\n const descriptionId = `${inputId}-description`;\r\n const hasDescription = optionSlot === undefined && showDescriptions && option.description !== undefined;\r\n const className = [styles.option, isSelected ? styles.selected : '', isDisabled ? styles.disabled : '']\r\n .filter(Boolean)\r\n .join(' ');\r\n return (\r\n <label key={option.value} htmlFor={inputId} className={className}>\r\n <input\r\n type=\"radio\"\r\n id={inputId}\r\n name={`${id}-choice`}\r\n value={option.value}\r\n checked={isSelected}\r\n disabled={isDisabled}\r\n onChange={handleChange}\r\n aria-describedby={hasDescription ? descriptionId : undefined}\r\n className={styles.input}\r\n />\r\n <span className={styles.text}>\r\n {optionSlot !== undefined ? (\r\n typeof optionSlot === 'function' ? (\r\n optionSlot({ option, selected: isSelected, disabled: isDisabled })\r\n ) : (\r\n optionSlot\r\n )\r\n ) : (\r\n <>\r\n <span className={styles.label}>{option.label}</span>\r\n {hasDescription && (\r\n <span id={descriptionId} className={styles.description}>\r\n {option.description}\r\n </span>\r\n )}\r\n </>\r\n )}\r\n </span>\r\n </label>\r\n );\r\n })}\r\n </div>\r\n )}\r\n </fieldset>\r\n );\r\n});\r\n\r\nFacePePickerContent.displayName = 'FacePePickerContent';\r\n","import {\r\n forwardRef,\r\n useCallback,\r\n useEffect,\r\n useId,\r\n useImperativeHandle,\r\n useMemo,\r\n useRef,\r\n useState,\r\n} from 'react';\r\nimport { decodeTimeline, gatewayPath, useFacePeResource } from '../../api/index.js';\r\nimport { useFacePe } from '../../context/index.js';\r\nimport { useFacePeNavigationRelay } from '../../context/navigation.js';\r\nimport { useFacePeEmitter } from '../../events/index.js';\r\nimport { FacePeErrorBoundary } from '../shared/FacePeErrorBoundary.js';\r\nimport type {\r\n AsyncResult,\r\n FacePeError,\r\n FacePeLocale,\r\n FacePeNavigationRequest,\r\n FacePeTimelineEvents,\r\n FacePeTimelineHandle,\r\n FacePeTimelineItem,\r\n FacePeTimelineItemStatus,\r\n FacePeTimelineProps,\r\n FacePeTimelineSelection,\r\n Failure,\r\n} from '../../types/index.js';\r\nimport { surfaceClass } from '../shared/surface.js';\r\nimport styles from './FacePeTimeline.module.css';\r\n\r\nconst SOURCE = 'FacePeTimeline';\r\nconst NO_ITEMS: readonly FacePeTimelineItem[] = [];\r\nconst RELATIVE_TIME_FLAG = 'timeline.relativeTime';\r\n\r\n/** Marker shape and text per status, so status never depends on colour. */\r\nconst STATUS: Readonly<Record<FacePeTimelineItemStatus, { marker: string; text: string; className: string }>> = {\r\n completed: { marker: '✓', text: 'Completed', className: styles.completed },\r\n current: { marker: '●', text: 'In progress', className: styles.current },\r\n pending: { marker: '○', text: 'Pending', className: styles.pending },\r\n error: { marker: '!', text: 'Failed', className: styles.error },\r\n};\r\n\r\nconst RELATIVE_UNITS: readonly [Intl.RelativeTimeFormatUnit, number][] = [\r\n ['year', 365 * 24 * 3600],\r\n ['month', 30 * 24 * 3600],\r\n ['week', 7 * 24 * 3600],\r\n ['day', 24 * 3600],\r\n ['hour', 3600],\r\n ['minute', 60],\r\n ['second', 1],\r\n];\r\n\r\nfunction failure(code: string, message: string): Failure {\r\n return { success: false, error: { code, message } };\r\n}\r\n\r\n/**\r\n * Formatters for the configured locale. An invalid locale tag makes Intl\r\n * throw, so it falls back to the runtime's default locale instead.\r\n */\r\nfunction formattersFor(locale: FacePeLocale | undefined) {\r\n const make = (tag: FacePeLocale | undefined) => ({\r\n absolute: new Intl.DateTimeFormat(tag, { dateStyle: 'medium', timeStyle: 'short' }),\r\n relative: new Intl.RelativeTimeFormat(tag, { numeric: 'auto' }),\r\n });\r\n try {\r\n return make(locale);\r\n } catch {\r\n return make(undefined);\r\n }\r\n}\r\n\r\nfunction relativeTime(format: Intl.RelativeTimeFormat, time: number, now: number): string {\r\n const seconds = Math.round((time - now) / 1000);\r\n for (const [unit, size] of RELATIVE_UNITS) {\r\n if (Math.abs(seconds) >= size || unit === 'second') return format.format(Math.round(seconds / size), unit);\r\n }\r\n return format.format(0, 'second');\r\n}\r\n\r\n/** A sorted copy (or the original order); never mutates `items`. */\r\nfunction ordered(items: readonly FacePeTimelineItem[], sort: 'none' | 'ascending' | 'descending') {\r\n if (sort === 'none') return items;\r\n const direction = sort === 'ascending' ? 1 : -1;\r\n return items\r\n .map((item, index) => ({ item, index, time: Date.parse(item.timestamp) }))\r\n .sort((a, b) => {\r\n const aValid = !Number.isNaN(a.time);\r\n const bValid = !Number.isNaN(b.time);\r\n if (aValid !== bValid) return aValid ? -1 : 1; // unparseable last, either direction\r\n if (aValid && a.time !== b.time) return (a.time - b.time) * direction;\r\n return a.index - b.index; // ties keep the given order\r\n })\r\n .map((entry) => entry.item);\r\n}\r\n\r\n/** Data problems worth reporting once: unparseable timestamps and duplicate ids. */\r\nfunction problemsIn(items: readonly FacePeTimelineItem[]): FacePeError[] {\r\n const problems: FacePeError[] = [];\r\n const invalid = items.filter((item) => Number.isNaN(Date.parse(item.timestamp))).map((item) => item.id);\r\n if (invalid.length > 0) {\r\n problems.push({ code: 'INVALID_TIMESTAMP', message: 'Some items have an unparseable timestamp.', details: { ids: invalid } });\r\n }\r\n const seen = new Set<string>();\r\n const duplicates = new Set<string>();\r\n for (const item of items) {\r\n if (seen.has(item.id)) duplicates.add(item.id);\r\n seen.add(item.id);\r\n }\r\n if (duplicates.size > 0) {\r\n problems.push({ code: 'DUPLICATE_ITEM_ID', message: 'Item ids must be unique.', details: { ids: [...duplicates] } });\r\n }\r\n return problems;\r\n}\r\n\r\n/**\r\n * A chronological FacePe timeline: each item shows a status marker and label,\r\n * title, time, and optional description and metadata.\r\n *\r\n * Items become selectable buttons when `onSelect` is passed; otherwise the\r\n * timeline is a plain, read-only list. Reads shared configuration from the\r\n * nearest `<FacePeProvider>`; its own `density`, `locale` and `featureFlags`\r\n * props override the provider's. `mode` has no effect: a timeline has\r\n * nothing to edit, and selecting an item is viewing, not editing.\r\n *\r\n * Styles ship separately: import \"@facepe/widgets/styles.css\" once in the host.\r\n */\r\nexport const FacePeTimeline = forwardRef<FacePeTimelineHandle, FacePeTimelineProps>(function FacePeTimeline(props, ref) {\r\n // Outside the boundary on purpose: a missing provider is a setup error that\r\n // must surface, not be contained as a render failure.\r\n const { config } = useFacePe();\r\n return (\r\n <FacePeErrorBoundary\r\n source={SOURCE}\r\n entityId={props.entityId ?? config.entityId}\r\n onError={props.onError}\r\n fallback={props.slots?.fallback}\r\n >\r\n <FacePeTimelineContent {...props} ref={ref} />\r\n </FacePeErrorBoundary>\r\n );\r\n});\r\n\r\nFacePeTimeline.displayName = 'FacePeTimeline';\r\n\r\nconst FacePeTimelineContent = forwardRef<FacePeTimelineHandle, FacePeTimelineProps>(function FacePeTimelineContent(props, ref) {\r\n const { config } = useFacePe();\r\n const entityId = props.entityId ?? config.entityId;\r\n const density = props.density ?? config.density ?? 'comfortable';\r\n const locale = props.locale ?? config.locale;\r\n const showRelative =\r\n props.featureFlags?.[RELATIVE_TIME_FLAG] ?? config.featureFlags?.[RELATIVE_TIME_FLAG] ?? false;\r\n const interactive = props.onSelect !== undefined;\r\n const sort = props.sort ?? 'none';\r\n\r\n // Items passed by the host win; otherwise the entity is passed by reference\r\n // and its history is fetched through the gateway.\r\n const resource = useFacePeResource(\r\n props.items === undefined && entityId !== undefined ? gatewayPath.timeline(entityId) : null,\r\n decodeTimeline,\r\n );\r\n const items = props.items ?? (resource.status === 'ready' ? resource.data : NO_ITEMS);\r\n const loading = props.loading === true || resource.status === 'loading';\r\n const loadError = resource.status === 'failed' ? resource.error : null;\r\n\r\n const visibleItems = useMemo(() => ordered(items, sort), [items, sort]);\r\n const itemsById = useMemo(() => new Map(items.map((item) => [item.id, item])), [items]);\r\n const formatters = useMemo(() => formattersFor(locale), [locale]);\r\n\r\n const [selectedId, setSelectedId] = useState<string | null>(null);\r\n // A selection whose item has since been removed counts as no selection.\r\n const currentSelectedId = selectedId !== null && itemsById.has(selectedId) ? selectedId : null;\r\n\r\n const propsRef = useRef(props);\r\n propsRef.current = props;\r\n const entityRef = useRef(entityId);\r\n entityRef.current = entityId;\r\n const selectedRef = useRef<string | null>(currentSelectedId);\r\n selectedRef.current = currentSelectedId;\r\n const readyRef = useRef(false);\r\n const reportedRef = useRef('');\r\n const itemRefs = useRef(new Map<string, HTMLLIElement>());\r\n const listRef = useRef<HTMLOListElement | null>(null);\r\n\r\n const id = useId();\r\n const labelId = `${id}-label`;\r\n\r\n // The host's handlers listen on this timeline's emitter, read through\r\n // propsRef so a new handler prop needs no re-subscribing. Subscribed once per\r\n // mount and removed on unmount; declared before the effects that emit.\r\n const events = useFacePeEmitter<FacePeTimelineEvents>(SOURCE, () => ({ entityId: entityRef.current }));\r\n useEffect(() => {\r\n const unsubscribe = [\r\n events.on('ready', (e) => propsRef.current.onReady?.(e)),\r\n events.on('select', (e) => propsRef.current.onSelect?.(e)),\r\n events.on('navigate', (e) => propsRef.current.onNavigate?.(e)),\r\n events.on('error', (e) => propsRef.current.onError?.(e)),\r\n ];\r\n return () => unsubscribe.forEach((off) => off());\r\n }, [events]);\r\n\r\n // Navigation is only ever requested: the event goes to this timeline's\r\n // onNavigate and, as the very same event, to the provider's. The host's\r\n // router does the navigating; nothing here touches the URL.\r\n const relayNavigation = useFacePeNavigationRelay();\r\n const navigate = useCallback(\r\n (request: FacePeNavigationRequest) => {\r\n relayNavigation(events.emit('navigate', request));\r\n },\r\n [events, relayNavigation],\r\n );\r\n\r\n // Emitted once per mount (the guard also covers StrictMode's double effect).\r\n useEffect(() => {\r\n if (readyRef.current) return;\r\n readyRef.current = true;\r\n events.emit('ready', null);\r\n }, [events]);\r\n\r\n // A failed fetch is reported once, after `ready`.\r\n useEffect(() => {\r\n if (loadError !== null) events.emit('error', loadError);\r\n }, [loadError, events]);\r\n\r\n // Report each distinct data problem once, not on every render that passes\r\n // an equal array.\r\n useEffect(() => {\r\n const problems = problemsIn(items);\r\n const signature = JSON.stringify(problems);\r\n if (signature === reportedRef.current) return;\r\n reportedRef.current = signature;\r\n for (const problem of problems) events.emit('error', problem);\r\n }, [items, events]);\r\n\r\n /** Selects an item and emits `select`; the one path for users and the handle alike. */\r\n const selectItem = useCallback(\r\n async (itemId: string): AsyncResult<FacePeTimelineSelection> => {\r\n const item = itemsById.get(itemId);\r\n if (item === undefined) return failure('ITEM_NOT_FOUND', `No item has the id \"${itemId}\".`);\r\n const selection: FacePeTimelineSelection = {\r\n id: item.id,\r\n title: item.title,\r\n status: item.status,\r\n previousId: selectedRef.current,\r\n };\r\n // Re-selecting the current item changes nothing, so it emits nothing.\r\n if (selectedRef.current === item.id) return { success: true, data: selection };\r\n selectedRef.current = item.id;\r\n setSelectedId(item.id);\r\n events.emit('select', selection);\r\n return { success: true, data: selection };\r\n },\r\n [itemsById, events],\r\n );\r\n\r\n const reset = useCallback(async (): AsyncResult<void> => {\r\n selectedRef.current = null;\r\n setSelectedId(null);\r\n return { success: true, data: undefined };\r\n }, []);\r\n\r\n const scrollToSection = useCallback(\r\n async (itemId: string): AsyncResult<void> => {\r\n const element = itemRefs.current.get(itemId);\r\n if (element === undefined) return failure('ITEM_NOT_FOUND', `No item has the id \"${itemId}\".`);\r\n if (typeof element.scrollIntoView === 'function') element.scrollIntoView({ block: 'nearest' });\r\n element.querySelector('button')?.focus();\r\n return { success: true, data: undefined };\r\n },\r\n [],\r\n );\r\n\r\n const focus = useCallback(async (): AsyncResult<void> => {\r\n // The selected item if there is one, else the first; only buttons take focus.\r\n const selected = selectedRef.current === null ? undefined : itemRefs.current.get(selectedRef.current);\r\n const target = selected?.querySelector('button') ?? listRef.current?.querySelector('button');\r\n if (target == null) return failure('NOTHING_TO_FOCUS', 'The timeline has no interactive item to focus.');\r\n target.focus();\r\n return { success: true, data: undefined };\r\n }, []);\r\n\r\n // The architecture's handle (§7.3): focus, reset and scrollToSection.\r\n // Selecting is a user action, reported as `select`.\r\n useImperativeHandle(ref, () => ({ focus, reset, scrollToSection }), [focus, reset, scrollToSection]);\r\n\r\n const rootClass = `${surfaceClass(props.emphasis, props.size)} ${styles.timeline} ${density === 'compact' ? styles.compact : styles.comfortable}`;\r\n const heading = (\r\n <p id={labelId} className={styles.heading}>\r\n {props.label ?? 'Timeline'}\r\n </p>\r\n );\r\n\r\n if (loading) {\r\n return (\r\n <section className={rootClass} lang={locale} aria-labelledby={labelId} aria-busy=\"true\">\r\n {heading}\r\n <p role=\"status\" className={styles.message}>\r\n Loading…\r\n </p>\r\n </section>\r\n );\r\n }\r\n\r\n const now = Date.now();\r\n const itemSlot = props.slots?.item;\r\n\r\n return (\r\n <section className={rootClass} lang={locale} aria-labelledby={labelId}>\r\n {heading}\r\n {loadError !== null ? (\r\n <p role=\"alert\" className={styles.message}>\r\n The timeline could not be loaded.\r\n </p>\r\n ) : visibleItems.length === 0 ? (\r\n <div role=\"status\" className={styles.message}>\r\n {props.slots?.emptyState ?? <p>No events yet.</p>}\r\n </div>\r\n ) : (\r\n <ol ref={listRef} className={styles.list} aria-labelledby={labelId}>\r\n {visibleItems.map((item, index) => {\r\n const status = STATUS[item.status];\r\n const time = Date.parse(item.timestamp);\r\n const valid = !Number.isNaN(time);\r\n const formattedTimestamp = valid ? formatters.absolute.format(time) : item.timestamp;\r\n const isSelected = item.id === currentSelectedId;\r\n // Keyed by position too: duplicate ids are reported, not allowed to break rendering.\r\n const key = `${item.id}\\u0000${index}`;\r\n const statusId = `${id}-${index}-status`;\r\n const timeId = `${id}-${index}-time`;\r\n const titleId = `${id}-${index}-title`;\r\n const { link } = item;\r\n const metadata = item.metadata === undefined ? [] : Object.entries(item.metadata);\r\n const itemClass = [styles.item, status.className, isSelected ? styles.selected : '']\r\n .filter(Boolean)\r\n .join(' ');\r\n\r\n return (\r\n <li\r\n key={key}\r\n className={itemClass}\r\n aria-current={item.status === 'current' ? 'step' : undefined}\r\n ref={(element) => {\r\n if (element === null) itemRefs.current.delete(item.id);\r\n else if (!itemRefs.current.has(item.id)) itemRefs.current.set(item.id, element);\r\n }}\r\n >\r\n <span className={styles.marker} aria-hidden=\"true\">\r\n {status.marker}\r\n </span>\r\n <div className={styles.body}>\r\n {interactive ? (\r\n <button\r\n type=\"button\"\r\n id={titleId}\r\n className={styles.title}\r\n aria-pressed={isSelected}\r\n aria-describedby={`${statusId} ${timeId}`}\r\n onClick={() => {\r\n void selectItem(item.id);\r\n }}\r\n >\r\n {item.title}\r\n </button>\r\n ) : (\r\n <p id={titleId} className={styles.title}>\r\n {item.title}\r\n </p>\r\n )}\r\n <p className={styles.meta}>\r\n <span id={statusId} className={styles.status}>\r\n {status.text}\r\n </span>\r\n <span aria-hidden=\"true\"> · </span>\r\n {valid ? (\r\n <time id={timeId} dateTime={item.timestamp} className={styles.time}>\r\n {formattedTimestamp}\r\n {showRelative && ` (${relativeTime(formatters.relative, time, now)})`}\r\n </time>\r\n ) : (\r\n <span id={timeId} className={styles.time}>\r\n {formattedTimestamp}\r\n </span>\r\n )}\r\n </p>\r\n {itemSlot !== undefined ? (\r\n typeof itemSlot === 'function' ? (\r\n itemSlot({ item, selected: isSelected, formattedTimestamp })\r\n ) : (\r\n itemSlot\r\n )\r\n ) : (\r\n <>\r\n {item.description !== undefined && <p className={styles.description}>{item.description}</p>}\r\n {metadata.length > 0 && (\r\n <dl className={styles.metadata}>\r\n {metadata.map(([name, value]) => (\r\n <div key={name} className={styles.metadataEntry}>\r\n <dt>{name}</dt>\r\n <dd>{String(value)}</dd>\r\n </div>\r\n ))}\r\n </dl>\r\n )}\r\n </>\r\n )}\r\n {link !== undefined && (\r\n <button\r\n type=\"button\"\r\n className={styles.link}\r\n aria-describedby={titleId}\r\n onClick={() => navigate(link)}\r\n >\r\n View details\r\n </button>\r\n )}\r\n </div>\r\n </li>\r\n );\r\n })}\r\n </ol>\r\n )}\r\n </section>\r\n );\r\n});\r\n\r\nFacePeTimelineContent.displayName = 'FacePeTimelineContent';\r\n","/**\n * Internal: the two avatar engines behind <FacePeAvatar>, as on the FacePe\n * website — Anam's hosted avatar, or FacePe's self-hosted agent in a LiveKit\n * room. Each is loaded with import() only when a conversation starts, so a\n * host pays for it (in its own bundle, as a separate chunk) only when used.\n */\nimport type { FacePeAvatarConnection } from '../../api/index.js';\nimport type { FacePeTranscriptLine } from '../../types/index.js';\n\nexport type EngineHandlers = {\n /** The avatar's picture is playing. */\n onLive(): void;\n onTranscript(line: FacePeTranscriptLine): void;\n onOrder(items: readonly { name: string; qty: number }[]): void;\n /** The stream dropped (not called after end()). */\n onDisconnected(): void;\n};\n\nexport type EngineSession = {\n end(): Promise<void>;\n setMuted(muted: boolean): Promise<void>;\n};\n\n// Each engine library is fetched once and kept: preloadEngines() starts the\n// download early (when the avatar is shown), so pressing Start does not wait\n// for it.\nlet anamModule: Promise<typeof import('@anam-ai/js-sdk')> | null = null;\nlet livekitModule: Promise<typeof import('livekit-client')> | null = null;\nconst loadAnam = () => (anamModule ??= import('@anam-ai/js-sdk'));\nconst loadLiveKit = () => (livekitModule ??= import('livekit-client'));\n\n/**\n * Starts fetching the connection libraries; safe to call any number of times.\n * Which one an avatar needs is only known when its session starts, so both\n * are fetched (each once). A failed preload is retried by connectEngine.\n */\nexport function preloadEngines(): void {\n loadLiveKit().catch(() => { livekitModule = null; });\n loadAnam().catch(() => { anamModule = null; });\n}\n\nconst roleOf = (role: unknown): 'user' | 'assistant' => (String(role).toLowerCase().includes('user') ? 'user' : 'assistant');\n\n/** Anam: their SDK streams the avatar (video + voice) into our <video>. */\nasync function connectAnam(\n video: HTMLVideoElement,\n conn: Extract<FacePeAvatarConnection, { type: 'stream' }>,\n on: EngineHandlers,\n): Promise<EngineSession> {\n const { createClient, AnamEvent } = await loadAnam();\n const client = createClient(conn.token);\n let ended = false;\n // Anam re-sends the whole history on every update: forward each line once.\n const seen = new Map<string, string>();\n\n client.addListener(AnamEvent.VIDEO_PLAY_STARTED, () => {\n on.onLive();\n // Talking starts straight away: Anam cancels its own echo.\n try { client.unmuteInputAudio(); } catch { /* not fatal */ }\n if (conn.greeting) void client.talk(conn.greeting).catch(() => undefined);\n });\n client.addListener(AnamEvent.CONNECTION_CLOSED, () => {\n if (!ended) on.onDisconnected();\n });\n client.addListener(AnamEvent.MESSAGE_HISTORY_UPDATED, (messages) => {\n for (const m of messages) {\n const text = (m.content || '').trim();\n if (!text || seen.get(m.id) === text) continue;\n seen.set(m.id, text);\n on.onTranscript({ role: roleOf(m.role), text, id: m.id });\n }\n });\n\n if (!video.id) video.id = `facepe-avatar-${Math.random().toString(36).slice(2, 10)}`;\n await client.streamToVideoElement(video.id);\n return {\n async end() {\n ended = true;\n await client.stopStreaming().catch(() => undefined);\n },\n async setMuted(muted) {\n if (muted) client.muteInputAudio();\n else client.unmuteInputAudio();\n },\n };\n}\n\n/** FacePe's self-hosted agent: join its LiveKit room, publish the microphone. */\nasync function connectLiveKit(\n video: HTMLVideoElement,\n conn: Extract<FacePeAvatarConnection, { type: 'room' }>,\n on: EngineHandlers,\n): Promise<EngineSession> {\n const { Room, RoomEvent, Track, createLocalAudioTrack } = await loadLiveKit();\n const room = new Room({ adaptiveStream: false, dynacast: false });\n let ended = false;\n // Exactly one audio element: the agent can publish more than one audio\n // track, and playing two at once is heard as an echo.\n let audio: HTMLMediaElement | null = null;\n const dropAudio = () => {\n if (!audio) return;\n try { audio.pause(); } catch { /* ignore */ }\n audio.remove();\n audio = null;\n };\n\n room.on(RoomEvent.TrackSubscribed, (track) => {\n if (track.kind === Track.Kind.Video) {\n track.attach(video);\n void video.play().catch(() => undefined);\n on.onLive();\n } else if (track.kind === Track.Kind.Audio) {\n dropAudio();\n const el = track.attach();\n el.style.display = 'none';\n document.body.appendChild(el);\n audio = el;\n }\n });\n room.on(RoomEvent.DataReceived, (payload: Uint8Array) => {\n let msg: Record<string, unknown>;\n try {\n msg = JSON.parse(new TextDecoder().decode(payload)) as Record<string, unknown>;\n } catch {\n return;\n }\n const type = String(msg.type ?? msg.event_type ?? '');\n const text = String(msg.text ?? msg.transcript ?? msg.content ?? '').trim();\n if (type === 'avatar.transcription' && text) on.onTranscript({ role: 'assistant', text });\n else if (type === 'user.transcription' && text) on.onTranscript({ role: 'user', text });\n else if (type === 'order.update' && Array.isArray(msg.items)) {\n on.onOrder((msg.items as { name?: unknown; qty?: unknown }[])\n .map((i) => ({ name: String(i.name ?? ''), qty: Number(i.qty) || 0 }))\n .filter((i) => i.name && i.qty > 0));\n }\n });\n room.on(RoomEvent.Disconnected, () => {\n dropAudio();\n if (!ended) on.onDisconnected();\n });\n\n await room.connect(conn.url, conn.token, { autoSubscribe: true });\n // Start was a user gesture, so the browser lets the voice play.\n await room.startAudio().catch(() => undefined);\n const mic = await createLocalAudioTrack({ echoCancellation: true, noiseSuppression: true, autoGainControl: true });\n await room.localParticipant.publishTrack(mic);\n // Ask the agent for transcripts of what the user says (captions), as the\n // FacePe kiosk does; repeated because the agent may not be listening yet.\n const sessionUpdate = new TextEncoder().encode(JSON.stringify({\n type: 'session.update',\n session: { input_audio_transcription: { model: 'whisper-1' }, turn_detection: { type: 'server_vad' } },\n }));\n const send = () => { if (!ended) void room.localParticipant.publishData(sessionUpdate, { reliable: true }).catch(() => undefined); };\n send();\n [600, 1500, 3500].forEach((ms) => setTimeout(send, ms));\n\n return {\n async end() {\n ended = true;\n mic.stop();\n dropAudio();\n await room.disconnect().catch(() => undefined);\n },\n async setMuted(muted) {\n if (muted) await mic.mute();\n else await mic.unmute();\n },\n };\n}\n\nexport function connectEngine(video: HTMLVideoElement, conn: FacePeAvatarConnection, on: EngineHandlers): Promise<EngineSession> {\n return conn.type === 'stream' ? connectAnam(video, conn, on) : connectLiveKit(video, conn, on);\n}\n","import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';\r\nimport {\r\n decodeAvatar,\r\n decodeAvatarConnection,\r\n decodeAvatarList,\r\n gatewayPath,\r\n useFacePeApi,\r\n useFacePeResource,\r\n type FacePeAvatarConnection,\r\n} from '../../api/index.js';\r\nimport { useFacePe } from '../../context/index.js';\r\nimport { useFacePeAvatarId } from '../../context/avatar.js';\r\nimport { useFacePeEmitter } from '../../events/index.js';\r\nimport { FacePeErrorBoundary } from '../shared/FacePeErrorBoundary.js';\r\nimport { surfaceClass } from '../shared/surface.js';\r\nimport type {\r\n AsyncResult,\r\n FacePeAvatarControlsContext,\r\n FacePeAvatarEvents,\r\n FacePeAvatarHandle,\r\n FacePeAvatarProps,\r\n FacePeAvatarSessionEnd,\r\n FacePeAvatarStatus,\r\n FacePeError,\r\n FacePeTranscriptLine,\r\n Failure,\r\n} from '../../types/index.js';\r\nimport { connectEngine, preloadEngines, type EngineSession } from './engines.js';\r\nimport styles from './FacePeAvatar.module.css';\r\n\r\nconst SOURCE = 'FacePeAvatar';\r\nconst CAPTION_LINES = 2;\r\nconst NO_AVATARS: FacePeError = { code: 'NO_AVATAR', message: 'No avatars are assigned to this user.' };\r\n\r\nfunction failure(code: string, message: string): Failure {\r\n return { success: false, error: { code, message } };\r\n}\r\n\r\n/**\r\n * The FacePe avatar conversation, embedded in the host's page: the same\r\n * avatar, trained prompt, voice and features as on the FacePe website.\r\n *\r\n * Talks to the avatar_id given here or on the provider. The user whose keys\r\n * the host uses must have that avatar assigned (super admin → company → user\r\n * → avatar); otherwise the component reports `FORBIDDEN` through `onError`.\r\n * Without an avatar_id it loads the user's assigned avatars and lets the user\r\n * choose (the first is selected), so the keys alone are enough.\r\n *\r\n * Styles ship separately: import \"@facepe/widgets/styles.css\" once in the host.\r\n */\r\nexport const FacePeAvatar = forwardRef<FacePeAvatarHandle, FacePeAvatarProps>(function FacePeAvatar(props, ref) {\r\n // Outside the boundary on purpose: a missing provider is a setup error that\r\n // must surface, not be contained as a render failure.\r\n const { config } = useFacePe();\r\n return (\r\n <FacePeErrorBoundary\r\n source={SOURCE}\r\n entityId={props.entityId ?? config.entityId}\r\n onError={props.onError}\r\n fallback={props.slots?.fallback}\r\n >\r\n <FacePeAvatarContent {...props} ref={ref} />\r\n </FacePeErrorBoundary>\r\n );\r\n});\r\n\r\nFacePeAvatar.displayName = 'FacePeAvatar';\r\n\r\nconst FacePeAvatarContent = forwardRef<FacePeAvatarHandle, FacePeAvatarProps>(function FacePeAvatarContent(props, ref) {\r\n const { config } = useFacePe();\r\n const providerAvatarId = useFacePeAvatarId();\r\n const fixedId = props.avatarId ?? providerAvatarId;\r\n const entityId = props.entityId ?? config.entityId;\r\n const locale = props.locale ?? config.locale;\r\n const density = props.density ?? config.density ?? 'comfortable';\r\n const api = useFacePeApi();\r\n\r\n const [status, setStatus] = useState<FacePeAvatarStatus>('idle');\r\n const [muted, setMutedState] = useState(false);\r\n const [lines, setLines] = useState<readonly FacePeTranscriptLine[]>([]);\r\n const [problem, setProblem] = useState<string | null>(null);\r\n\r\n const propsRef = useRef(props);\r\n propsRef.current = props;\r\n const entityRef = useRef(entityId);\r\n entityRef.current = entityId;\r\n const videoRef = useRef<HTMLVideoElement | null>(null);\r\n const mainButtonRef = useRef<HTMLButtonElement | null>(null);\r\n const engineRef = useRef<EngineSession | null>(null);\r\n const connRef = useRef<FacePeAvatarConnection | null>(null);\r\n const statusRef = useRef(status);\r\n statusRef.current = status;\r\n const runRef = useRef(0); // invalidates a start that is overtaken by end()/unmount\r\n const readyRef = useRef(false);\r\n\r\n // No avatar_id from the host: the user's own avatars, to choose from.\r\n const list = useFacePeResource(fixedId === undefined ? gatewayPath.avatars : null, decodeAvatarList);\r\n const choices = list.status === 'ready' ? list.data : [];\r\n const [chosenId, setChosenId] = useState<string | null>(null);\r\n const chosen = choices.find((a) => a.id === chosenId) ?? choices[0];\r\n const avatarId = fixedId ?? chosen?.id;\r\n\r\n // The avatar's name and portrait, shown before the conversation starts.\r\n const info = useFacePeResource(fixedId === undefined ? null : gatewayPath.avatar(fixedId), decodeAvatar);\r\n const avatar = fixedId === undefined ? chosen ?? null : info.status === 'ready' ? info.data : null;\r\n const portrait = api.assetUrl(avatar?.previewUrl);\r\n // Fetch the connection libraries while the user is still looking at the portrait.\r\n const known = avatar !== null;\r\n useEffect(() => {\r\n if (known) preloadEngines();\r\n }, [known]);\r\n const [portraitFailed, setPortraitFailed] = useState<string | null>(null);\r\n\r\n const events = useFacePeEmitter<FacePeAvatarEvents>(SOURCE, () => ({ entityId: entityRef.current }));\r\n useEffect(() => {\r\n const unsubscribe = [\r\n events.on('ready', (e) => propsRef.current.onReady?.(e)),\r\n events.on('sessionStart', (e) => propsRef.current.onSessionStart?.(e)),\r\n events.on('sessionEnd', (e) => propsRef.current.onSessionEnd?.(e)),\r\n events.on('transcript', (e) => propsRef.current.onTranscript?.(e)),\r\n events.on('orderUpdate', (e) => propsRef.current.onOrderUpdate?.(e)),\r\n events.on('error', (e) => propsRef.current.onError?.(e)),\r\n ];\r\n return () => unsubscribe.forEach((off) => off());\r\n }, [events]);\r\n\r\n useEffect(() => {\r\n if (readyRef.current) return;\r\n readyRef.current = true;\r\n events.emit('ready', null);\r\n }, [events]);\r\n\r\n const noAvatars = list.status === 'ready' && list.data.length === 0;\r\n const loadError = info.status === 'failed' ? info.error : list.status === 'failed' ? list.error : null;\r\n const infoError: FacePeError | null =\r\n loadError ?? (noAvatars ? NO_AVATARS : null);\r\n useEffect(() => {\r\n if (infoError === null) return;\r\n setProblem(\r\n infoError.code === 'FORBIDDEN' ? 'This avatar is not available to this account.'\r\n : infoError.code === 'NO_AVATAR' ? 'No avatars are assigned to this account yet.'\r\n : 'The avatar could not be loaded.',\r\n );\r\n events.emit('error', infoError);\r\n }, [infoError, events]);\r\n\r\n /** The user picked another of their avatars (only between conversations). */\r\n const choose = (id: string) => {\r\n if (statusRef.current === 'connecting' || statusRef.current === 'live' || id === avatarId) return;\r\n setChosenId(id);\r\n setStatus('idle');\r\n setProblem(null);\r\n setLines([]);\r\n };\r\n\r\n const report = useCallback(\r\n (error: FacePeError, shown: string) => {\r\n setProblem(shown);\r\n setStatus('error');\r\n events.emit('error', error);\r\n },\r\n [events],\r\n );\r\n\r\n /** Frees the engine and closes the usage record (minutes and points). */\r\n const finish = useCallback(\r\n async (reason: FacePeAvatarSessionEnd['reason']) => {\r\n runRef.current += 1;\r\n const engine = engineRef.current;\r\n const conn = connRef.current;\r\n engineRef.current = null;\r\n connRef.current = null;\r\n // Closed first: disconnecting can take seconds, and a page that closes\r\n // meanwhile must not leave the usage record open. keepalive: still sent\r\n // when this runs because the page is closing.\r\n if (conn?.usageId) {\r\n void api.post(gatewayPath.endAvatarSession(conn.usageId), undefined, { keepalive: true });\r\n }\r\n if (engine) await engine.end().catch(() => undefined);\r\n if (conn) events.emit('sessionEnd', { avatarId: conn.avatar.id, usageId: conn.usageId, reason });\r\n },\r\n [api, events],\r\n );\r\n\r\n const start = useCallback(async (): AsyncResult<void> => {\r\n if (statusRef.current === 'connecting' || statusRef.current === 'live') return { success: true, data: undefined };\r\n if (avatarId === undefined) {\r\n const result = failure('NO_AVATAR', 'No avatar is available: none was given, and none is assigned to this user.');\r\n report(result.error, 'No avatar is available.');\r\n return result;\r\n }\r\n const run = ++runRef.current;\r\n setProblem(null);\r\n setLines([]);\r\n setMutedState(false);\r\n setStatus('connecting');\r\n\r\n const language = propsRef.current.language;\r\n const session = await api.post(\r\n gatewayPath.avatarSessions(avatarId),\r\n language ? { language } : {},\r\n { decode: decodeAvatarConnection },\r\n );\r\n if (run !== runRef.current) return failure('CANCELLED', 'The conversation was ended before it started.');\r\n if (!session.success) {\r\n report(session.error, session.error.code === 'FORBIDDEN' ? 'This avatar is not available to this account.' : 'The conversation could not be started.');\r\n return session;\r\n }\r\n connRef.current = session.data;\r\n events.emit('sessionStart', { avatarId: session.data.avatar.id, usageId: session.data.usageId });\r\n\r\n const video = videoRef.current;\r\n if (video === null) return failure('NOT_MOUNTED', 'The avatar is not on the page.');\r\n try {\r\n const engine = await connectEngine(video, session.data, {\r\n onLive: () => {\r\n if (run === runRef.current) setStatus('live');\r\n },\r\n onTranscript: (line) => {\r\n if (run !== runRef.current) return;\r\n setLines((prev) => [...prev, line].slice(-CAPTION_LINES));\r\n events.emit('transcript', line);\r\n },\r\n onOrder: (items) => {\r\n if (run === runRef.current) events.emit('orderUpdate', { items });\r\n },\r\n onDisconnected: () => {\r\n if (run !== runRef.current) return;\r\n setStatus('ended');\r\n void finish('disconnected');\r\n },\r\n });\r\n if (run !== runRef.current) {\r\n await engine.end().catch(() => undefined);\r\n return failure('CANCELLED', 'The conversation was ended before it started.');\r\n }\r\n engineRef.current = engine;\r\n return { success: true, data: undefined };\r\n } catch (err) {\r\n const error = { code: 'AVATAR_CONNECT_FAILED', message: err instanceof Error ? err.message : 'Could not connect to the avatar.' };\r\n await finish('disconnected');\r\n report(error, 'Could not connect to the avatar. Check the microphone permission and try again.');\r\n return { success: false, error };\r\n }\r\n }, [api, avatarId, events, finish, report]);\r\n\r\n const end = useCallback(async (): AsyncResult<void> => {\r\n if (statusRef.current !== 'connecting' && statusRef.current !== 'live') return { success: true, data: undefined };\r\n setStatus('ended');\r\n await finish('ended');\r\n return { success: true, data: undefined };\r\n }, [finish]);\r\n\r\n const setMuted = useCallback(async (next: boolean): AsyncResult<void> => {\r\n const engine = engineRef.current;\r\n if (engine === null) return failure('NOT_LIVE', 'There is no conversation to mute.');\r\n try {\r\n await engine.setMuted(next);\r\n setMutedState(next);\r\n return { success: true, data: undefined };\r\n } catch {\r\n return failure('MUTE_FAILED', 'The microphone could not be changed.');\r\n }\r\n }, []);\r\n\r\n const focus = useCallback(async (): AsyncResult<void> => {\r\n if (!mainButtonRef.current) return failure('NOTHING_TO_FOCUS', 'The avatar has no control to focus.');\r\n mainButtonRef.current.focus();\r\n return { success: true, data: undefined };\r\n }, []);\r\n\r\n useImperativeHandle(ref, () => ({ focus, start, end, setMuted }), [focus, start, end, setMuted]);\r\n\r\n // Optional start on mount; and always clean up on unmount or page close.\r\n const autoStarted = useRef(false);\r\n useEffect(() => {\r\n if (!props.autoStart || autoStarted.current || avatarId === undefined) return;\r\n autoStarted.current = true;\r\n void start();\r\n }, [props.autoStart, avatarId, start]);\r\n useEffect(() => {\r\n const onPageHide = () => void finish('unmounted');\r\n window.addEventListener('pagehide', onPageHide);\r\n return () => {\r\n window.removeEventListener('pagehide', onPageHide);\r\n void finish('unmounted');\r\n };\r\n }, [finish]);\r\n\r\n const live = status === 'live';\r\n const busy = status === 'connecting';\r\n const name = avatar?.name ?? 'FacePe avatar';\r\n const controls: FacePeAvatarControlsContext = {\r\n status,\r\n muted,\r\n start: () => void start(),\r\n end: () => void end(),\r\n setMuted: (next) => void setMuted(next),\r\n };\r\n const controlsSlot = props.slots?.controls;\r\n const statusText =\r\n status === 'connecting' ? `Connecting to ${name}…`\r\n : status === 'ended' ? 'Conversation ended.'\r\n : status === 'idle' ? `Talk to ${name}` : null;\r\n\r\n return (\r\n <section\r\n className={[surfaceClass(props.emphasis, props.size), styles.avatar, density === 'compact' ? styles.compact : styles.comfortable].join(' ')}\r\n lang={locale}\r\n aria-label={name}\r\n aria-busy={busy}\r\n >\r\n {props.slots?.header}\r\n\r\n <div className={styles.stage}>\r\n <video ref={videoRef} className={styles.video} autoPlay playsInline aria-label={`${name}, video`} />\r\n {/* Whenever there is no live picture — before Start, while connecting,\r\n after End or an error — the avatar's portrait (or initials). A\r\n video's own poster does not come back once a stream has played. */}\r\n {!live && (\r\n portrait && portraitFailed !== portrait ? (\r\n <img className={styles.portrait} src={portrait} alt={name} onError={() => setPortraitFailed(portrait)} />\r\n ) : (\r\n <span className={styles.initials} aria-hidden=\"true\">\r\n {name.split(/\\s+/).map((w) => w[0]).join('').slice(0, 2).toUpperCase()}\r\n </span>\r\n )\r\n )}\r\n {!live && statusText !== null && (\r\n <p role=\"status\" className={styles.overlay}>\r\n {statusText}\r\n </p>\r\n )}\r\n </div>\r\n\r\n {/* The user's avatars, when the host did not name one and there is a choice. */}\r\n {choices.length > 1 && (\r\n <div className={styles.choices} role=\"radiogroup\" aria-label=\"Choose an avatar\">\r\n {choices.map((a) => {\r\n const thumb = api.assetUrl(a.previewUrl);\r\n return (\r\n <button\r\n key={a.id}\r\n type=\"button\"\r\n role=\"radio\"\r\n aria-checked={a.id === avatarId}\r\n className={styles.choice}\r\n disabled={live || busy}\r\n onClick={() => choose(a.id)}\r\n >\r\n {thumb ? (\r\n <img className={styles.thumb} src={thumb} alt=\"\" />\r\n ) : (\r\n <span className={styles.thumb} aria-hidden=\"true\">{a.name.slice(0, 1).toUpperCase()}</span>\r\n )}\r\n <span>{a.name}</span>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n )}\r\n\r\n {problem !== null && (\r\n <p role=\"alert\" className={styles.problem}>\r\n {problem}\r\n </p>\r\n )}\r\n\r\n {props.captions !== false && lines.length > 0 && (\r\n <div className={styles.captions} aria-live=\"polite\">\r\n {lines.map((line, i) => (\r\n <p key={line.id ?? `${i}-${line.text}`} className={line.role === 'user' ? styles.user : styles.assistant}>\r\n <span className={styles.speaker}>{line.role === 'user' ? 'You' : name}: </span>\r\n {line.text}\r\n </p>\r\n ))}\r\n </div>\r\n )}\r\n\r\n <div className={styles.controls}>\r\n {controlsSlot !== undefined ? (\r\n typeof controlsSlot === 'function' ? controlsSlot(controls) : controlsSlot\r\n ) : live || busy ? (\r\n <>\r\n <button type=\"button\" className={styles.secondary} disabled={!live} aria-pressed={muted} onClick={() => void setMuted(!muted)}>\r\n {muted ? 'Unmute' : 'Mute'}\r\n </button>\r\n <button ref={mainButtonRef} type=\"button\" className={styles.danger} onClick={() => void end()}>\r\n End\r\n </button>\r\n </>\r\n ) : (\r\n <button\r\n ref={mainButtonRef}\r\n type=\"button\"\r\n className={styles.primary}\r\n disabled={avatarId === undefined || infoError !== null}\r\n onClick={() => void start()}\r\n >\r\n {status === 'ended' || status === 'error' ? 'Start again' : 'Start conversation'}\r\n </button>\r\n )}\r\n </div>\r\n </section>\r\n );\r\n});\r\n\r\nFacePeAvatarContent.displayName = 'FacePeAvatarContent';\r\n","import type { FacePePageProps } from '../../types/index.js';\nimport styles from './Placement.module.css';\n\n/**\n * Page display mode: shows a FacePe component as a full view filling the\n * container the host gives it. The component inside is unchanged; titles,\n * breadcrumbs and navigation stay with the host.\n *\n * @example\n * <Route path=\"/schedule\" element={<FacePePage><FacePeTimeline items={items} /></FacePePage>} />\n */\nexport function FacePePage({ children }: FacePePageProps) {\n return <div className={styles.page}>{children}</div>;\n}\n","import { useEffect, useRef, type SyntheticEvent } from 'react';\r\nimport type { FacePeOverlayProps } from '../../types/index.js';\r\nimport styles from './Placement.module.css';\r\n\r\n/**\r\n * Overlay display mode: shows a FacePe component over the page, as a centred\r\n * modal or (`variant=\"drawer\"`) a side drawer. Both are a modal dialog built on\r\n * the native `<dialog>`, so focus stays inside, Escape is handled and the page\r\n * behind is inert. The host owns `open`; Escape only asks, via `onClose`.\r\n *\r\n * @example\r\n * <FacePeOverlay open={open} label=\"Update details\" onClose={() => setOpen(false)}>\r\n * <FacePeForm onCancel={() => setOpen(false)} />\r\n * </FacePeOverlay>\r\n */\r\nexport function FacePeOverlay({ open, label, variant = 'modal', onClose, children }: FacePeOverlayProps) {\r\n const dialogRef = useRef<HTMLDialogElement | null>(null);\r\n const onCloseRef = useRef(onClose);\r\n onCloseRef.current = onClose;\r\n\r\n useEffect(() => {\r\n const dialog = dialogRef.current;\r\n if (dialog === null) return;\r\n const shown = dialog.hasAttribute('open');\r\n // showModal/close are missing in some environments (older browsers, test\r\n // DOMs); the open attribute still shows and hides the dialog there.\r\n if (open && !shown) {\r\n if (typeof dialog.showModal === 'function') dialog.showModal();\r\n else dialog.setAttribute('open', '');\r\n } else if (!open && shown) {\r\n if (typeof dialog.close === 'function') dialog.close();\r\n else dialog.removeAttribute('open');\r\n }\r\n }, [open]);\r\n\r\n // Escape: keep the dialog as the host left it and ask the host to close it.\r\n const handleCancel = (event: SyntheticEvent<HTMLDialogElement>) => {\r\n event.preventDefault();\r\n onCloseRef.current?.();\r\n };\r\n\r\n return (\r\n <dialog ref={dialogRef} aria-label={label} className={`${styles.overlay} ${variant === 'drawer' ? styles.drawer : styles.modal}`} onCancel={handleCancel}>\r\n {children}\r\n </dialog>\r\n );\r\n}\r\n"],"names":["message","status","options","body","text","error","createContext","useContext","invalid","list","title","description","item","label","option","avatar","useState","useEffect","meta","tokens","useMemo","useRef","useCallback","jsx","Component","fallback","styles","SOURCE","failure","forwardRef","FacePeForm","FacePeFormContent","formError","useId","field","useImperativeHandle","jsxs","Fragment","FacePePicker","FacePePickerContent","selected","FacePeTimeline","FacePeTimelineContent","problem","heading","link","metadata","video","FacePeAvatar","FacePeAvatarContent","choices","portrait","controls","thumb"],"mappings":"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"}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @facepe/widgets — the single public entry point.
|
|
3
|
+
*
|
|
4
|
+
* Consumers import only from "@facepe/widgets"; package.json exports nothing
|
|
5
|
+
* else, so no other path in this package is reachable from a host app.
|
|
6
|
+
*
|
|
7
|
+
* Rules for this file:
|
|
8
|
+
* - It contains exports only, never implementation.
|
|
9
|
+
* - Every export is named explicitly. No `export *`: a helper added inside a
|
|
10
|
+
* module must never become public API by accident.
|
|
11
|
+
* - Types are exported with `export type`, so they vanish from the JS output.
|
|
12
|
+
* - Relative imports end in `.js` (e.g. './version.cjs'). The build derives the
|
|
13
|
+
* CommonJS declarations (.d.cts) from them and fails on an extensionless one.
|
|
14
|
+
* - Anything exported here is a versioned contract (SemVer): removing or
|
|
15
|
+
* changing it is a breaking change.
|
|
16
|
+
*
|
|
17
|
+
* Sections are filled in by later tasks, in this order.
|
|
18
|
+
*/
|
|
19
|
+
export { FacePeForm } from './components/Form/index.cjs';
|
|
20
|
+
export { FacePePicker } from './components/Picker/index.cjs';
|
|
21
|
+
export { FacePeTimeline } from './components/Timeline/index.cjs';
|
|
22
|
+
export { FacePeAvatar } from './components/Avatar/index.cjs';
|
|
23
|
+
export { FacePePage, FacePeOverlay } from './components/Placement/index.cjs';
|
|
24
|
+
export { FacePeProvider, useFacePe } from './context/index.cjs';
|
|
25
|
+
export type { CorrelationId, EntityId, FacePeDataObject, FacePeDensity, FacePeError, FacePeFeatureFlags, FacePeLocale, FacePeMode, JsonArray, JsonObject, JsonPrimitive, JsonValue, FacePeConfig, FacePeContextValue, FacePeProviderProps, FacePeColorScheme, FacePeFallbackContext, FacePeOverlayProps, FacePeOverlayVariant, FacePePageProps, FacePeThemeTokens, FacePeCustomerPayload, FacePeHttpMethod, FacePePickerOptionsPayload, FacePeTimelinePayload, FacePeProviderEvents, FacePeSessionExpiredPayload, FacePeTokenProvider, FacePeTokenRequest, FacePeFormActionsContext, FacePeFormEvents, FacePeFormHandle, FacePeFormProps, FacePeFormSlots, FacePeFormSubmitAction, FacePeFormValues, FacePeFormVariant, FacePePickerEvents, FacePePickerHandle, FacePePickerOption, FacePePickerOptionSlotContext, FacePePickerProps, FacePePickerSelection, FacePePickerSlots, FacePePickerVariant, FacePeTimelineEvents, FacePeTimelineHandle, FacePeTimelineItem, FacePeTimelineItemSlotContext, FacePeTimelineItemStatus, FacePeTimelineMetadata, FacePeTimelineProps, FacePeTimelineSelection, FacePeTimelineSlots, FacePeEvent, FacePeEventHandler, FacePeEventHandlers, FacePeEventMap, FacePeEventMeta, FacePeEventOf, FacePeNavigationRequest, FacePeEventType, FacePeStandardEvents, FacePeTelemetry, FacePeTelemetryAttributes, FacePeTelemetryEvent, FacePeAvatarControlsContext, FacePeAvatarEvents, FacePeAvatarHandle, FacePeAvatarInfo, FacePeAvatarProps, FacePeAvatarSession, FacePeAvatarSessionEnd, FacePeAvatarSlots, FacePeAvatarStatus, FacePeTranscriptLine, AsyncResult, Failure, Result, Success, FacePeComponentProps, FacePeEmphasis, FacePeHandle, FacePeHandleMethod, FacePeSlot, FacePeSlotMap, FacePeSize, FacePeSlots, } from './types/index.cjs';
|
|
26
|
+
export { SDK_VERSION } from './version.cjs';
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @facepe/widgets — the single public entry point.
|
|
3
|
+
*
|
|
4
|
+
* Consumers import only from "@facepe/widgets"; package.json exports nothing
|
|
5
|
+
* else, so no other path in this package is reachable from a host app.
|
|
6
|
+
*
|
|
7
|
+
* Rules for this file:
|
|
8
|
+
* - It contains exports only, never implementation.
|
|
9
|
+
* - Every export is named explicitly. No `export *`: a helper added inside a
|
|
10
|
+
* module must never become public API by accident.
|
|
11
|
+
* - Types are exported with `export type`, so they vanish from the JS output.
|
|
12
|
+
* - Relative imports end in `.js` (e.g. './version.js'). The build derives the
|
|
13
|
+
* CommonJS declarations (.d.cts) from them and fails on an extensionless one.
|
|
14
|
+
* - Anything exported here is a versioned contract (SemVer): removing or
|
|
15
|
+
* changing it is a breaking change.
|
|
16
|
+
*
|
|
17
|
+
* Sections are filled in by later tasks, in this order.
|
|
18
|
+
*/
|
|
19
|
+
export { FacePeForm } from './components/Form/index.js';
|
|
20
|
+
export { FacePePicker } from './components/Picker/index.js';
|
|
21
|
+
export { FacePeTimeline } from './components/Timeline/index.js';
|
|
22
|
+
export { FacePeAvatar } from './components/Avatar/index.js';
|
|
23
|
+
export { FacePePage, FacePeOverlay } from './components/Placement/index.js';
|
|
24
|
+
export { FacePeProvider, useFacePe } from './context/index.js';
|
|
25
|
+
export type { CorrelationId, EntityId, FacePeDataObject, FacePeDensity, FacePeError, FacePeFeatureFlags, FacePeLocale, FacePeMode, JsonArray, JsonObject, JsonPrimitive, JsonValue, FacePeConfig, FacePeContextValue, FacePeProviderProps, FacePeColorScheme, FacePeFallbackContext, FacePeOverlayProps, FacePeOverlayVariant, FacePePageProps, FacePeThemeTokens, FacePeCustomerPayload, FacePeHttpMethod, FacePePickerOptionsPayload, FacePeTimelinePayload, FacePeProviderEvents, FacePeSessionExpiredPayload, FacePeTokenProvider, FacePeTokenRequest, FacePeFormActionsContext, FacePeFormEvents, FacePeFormHandle, FacePeFormProps, FacePeFormSlots, FacePeFormSubmitAction, FacePeFormValues, FacePeFormVariant, FacePePickerEvents, FacePePickerHandle, FacePePickerOption, FacePePickerOptionSlotContext, FacePePickerProps, FacePePickerSelection, FacePePickerSlots, FacePePickerVariant, FacePeTimelineEvents, FacePeTimelineHandle, FacePeTimelineItem, FacePeTimelineItemSlotContext, FacePeTimelineItemStatus, FacePeTimelineMetadata, FacePeTimelineProps, FacePeTimelineSelection, FacePeTimelineSlots, FacePeEvent, FacePeEventHandler, FacePeEventHandlers, FacePeEventMap, FacePeEventMeta, FacePeEventOf, FacePeNavigationRequest, FacePeEventType, FacePeStandardEvents, FacePeTelemetry, FacePeTelemetryAttributes, FacePeTelemetryEvent, FacePeAvatarControlsContext, FacePeAvatarEvents, FacePeAvatarHandle, FacePeAvatarInfo, FacePeAvatarProps, FacePeAvatarSession, FacePeAvatarSessionEnd, FacePeAvatarSlots, FacePeAvatarStatus, FacePeTranscriptLine, AsyncResult, Failure, Result, Success, FacePeComponentProps, FacePeEmphasis, FacePeHandle, FacePeHandleMethod, FacePeSlot, FacePeSlotMap, FacePeSize, FacePeSlots, } from './types/index.js';
|
|
26
|
+
export { SDK_VERSION } from './version.js';
|