/** * @oxpulse/chat-widget — Custom Element. * * Skeleton: handles lifecycle + origin check + placeholder rendering. * Full UI (message list, composer, reactions) ships in W2.2. * * Voice/video interface reserved for v3.0: see WidgetConfig for attribute stub. */ import { type MountOptions, type WidgetConfig, type ProductMeta } from './types.js'; import type { MessageRow } from './ui/message-list.js'; /** * Derive the self uid from the JWT `sub` claim (display-side only — the * server never trusts it; it drives self/other bubble alignment). * * Fail-soft by design: a malformed or expired token returns `undefined` * here rather than throwing — bootstrap's own `decodeJwtPayload` call is * where the real error surfaces to the embedder. Alignment sugar must * never take the widget down. */ export declare function selfUidFromJwt(jwt: string | null): string | undefined; /** * issue #67: read-side inverse of composerClient.sendAttachmentMessage's * envelope encode (composerClient.uploadAttachment + sendAttachmentMessage * below — the old single-shot sendFile field was replaced, not kept, once * AttachmentPicker moved to stage-then-send; see PR #88's changeset). * * chat-sdk's MessageRow has no attachments field at all (verified: types.ts, * client.ts's rowToMessageRow) — a stored attachment blob is structurally * unlinked from any message on the wire. This widget links them itself: since * cryptoMode is always 'plaintext' here, row.plaintext is UTF-8 bytes fully * controlled by the widget. When those bytes decode as our attachment * envelope (attachment-envelope.ts), unwrap it into row.text (caption) + * row.attachments (AttachmentMeta[], url built from the already-documented * GET /api/sdk/attachments/{id} route). Any other plaintext — every * pre-existing plain-text message — fails the shape check and passes through * unchanged, so this never touches the ordinary text path. */ /** @internal Exported for tests only. */ export declare function decodeRowAttachments(row: MessageRow, baseUrl: string): MessageRow; /** * Custom Element. * * HTML usage: * * * Attributes: * app-id — OxPulse app ID (required) * jwt — signed JWT (required) * room-id — room to open (required) * mode — 'inline' | 'iframe' (default: 'inline') * theme — 'light' | 'dark' | 'auto' (default: 'auto') * lang — BCP 47 locale override */ export declare class OxpulseChatElement extends HTMLElement { #private; static readonly observedAttributes: readonly string[]; connectedCallback(): void; disconnectedCallback(): void; attributeChangedCallback(name: string, old: string | null, value: string | null): void; /** * W2.2 slice 5: Returns the last seq value seen by the MessageList. * Used by tests and reconnect logic to pass lastSeq on reconnect. */ getLastSeq(): number; /** * W9: Attach a product card to the next outgoing composer message. * Call after the 'oxpulse-chat:ready' event when the composer is mounted. * * E2EE posture: `productMeta` (title/price/imageUrl/productUrl) travels * UNSEALED in the wire payload and is server-visible even in E2EE rooms — * by design, mirroring the sendProductCard contract to enable marketplace * search. Only `productRef` is opaque. Do not put sensitive data in * `productMeta`. */ setProductCard(productRef: string, productMeta: ProductMeta): void; /** * CB2: Test hook — trigger an error through the real SDK subscribe() onError path. * Routes through the real error-handling path (Reconnector) rather than bypassing it. * @internal — for testing only. Not exposed on the public type surface. */ triggerSubscribeError(err: unknown): void; /** * Provide a fresh JWT (called after 'oxpulse-chat:token-expired' event). * * In-place path (iframe mode): posts the fresh JWT to the LIVE iframe over an * origin-pinned postMessage — no remount, so the SSE stream, scroll position * and decrypt state survive. The iframe re-authenticates internally without a * document reload. * * Fallback (inline mode, the iframe is not present/ready, OR a remount is * already pending): re-bootstrap with the fresh token. A pending remount * (e.g. from a same-tick base-url/room change) would replace the current * iframe, so an in-place post to it targets the OLD origin and the browser * drops it (token lost) — instead we sync the attribute and let the pending * remount deliver the fresh token. Inline uses a `readonly`-JWT SDKChatClient * that can only be re-authed by reconstruction, so a re-bootstrap is required. */ refreshToken(jwt: string): void; /** * Tear down the widget, cancel in-flight async operations, clear shadow DOM. */ destroy(): void; /** * Store config callbacks from programmatic mount(). * Not exposed as attributes — only via the JS API. * @internal */ _setCallbacks(config: Pick): void; } /** * Register as a Custom Element. * Safe to call multiple times — no-ops if already registered. */ export declare function defineElement(): void; /** * Programmatically mount an OxPulse Chat widget on a target element. * * This is an alternative to dropping in the HTML. * The element is created, configured, and appended to `target`. * * @returns An object with a `destroy()` method to remove the widget. */ export declare function mount(target: HTMLElement, config: MountOptions): { destroy: () => void; }; //# sourceMappingURL=element.d.ts.map