@viceme-ai/sdk 0.7.0 → 0.8.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.
@@ -1 +1 @@
1
- {"version":3,"file":"viceme.min.js","sources":["../src/core/errors.ts","../src/core/build-endpoints.ts","../src/core/config.ts","../src/loader/attributes.ts","../src/loader/registry.ts","../src/browser-events.ts","../src/core/lifecycle.ts","../src/session/session.ts","../src/version.ts","../src/core/presentation.ts","../src/core/capabilities.ts","../src/core/client.ts","../src/transport/transport.ts","../src/index.ts","../src/loader/auto-loader.ts"],"sourcesContent":["/**\n * Public error model.\n *\n * Consumers branch on the stable `code` only — never on `message` text.\n * Error payloads must never contain provider responses, tokens, cookies, or\n * internal stack traces; `toJSON()` exposes the safe diagnostic subset.\n */\n\nexport type ViceMeErrorCode =\n | 'CONFIG_INVALID'\n | 'WORK_NOT_FOUND'\n | 'CAPABILITY_DISABLED'\n | 'CLIENT_DESTROYED'\n | 'SESSION_EXPIRED'\n | 'AUTH_REQUIRED'\n | 'AUTH_CANCELLED'\n | 'RETURN_URL_NOT_ALLOWED'\n | 'RATE_LIMITED'\n | 'NETWORK_TIMEOUT'\n | 'CHECKOUT_UNAVAILABLE'\n | 'INTERNAL_ERROR'\n | 'TIP_CONFIG_CREDENTIALS_NOT_ALLOWED'\n | 'TIP_CONFIG_INVALID'\n | 'TIP_OPEN_IN_PROGRESS'\n | 'TIP_READY_TIMEOUT';\n\nexport interface ViceMeErrorInit {\n code: ViceMeErrorCode;\n message: string;\n retryable?: boolean;\n /** Server-assigned request id echoed back for support correlation. */\n requestId?: string;\n /** Capability the error belongs to, when scoped to one. */\n capability?: string;\n}\n\nconst RETRYABLE_BY_DEFAULT: ReadonlySet<ViceMeErrorCode> = new Set([\n 'RATE_LIMITED',\n 'NETWORK_TIMEOUT',\n 'CHECKOUT_UNAVAILABLE',\n 'INTERNAL_ERROR',\n]);\n\nexport class ViceMeError extends Error {\n readonly code: ViceMeErrorCode;\n readonly retryable: boolean;\n readonly requestId?: string;\n readonly capability?: string;\n\n constructor(init: ViceMeErrorInit) {\n super(init.message);\n this.name = 'ViceMeError';\n this.code = init.code;\n this.retryable = init.retryable ?? RETRYABLE_BY_DEFAULT.has(init.code);\n this.requestId = init.requestId;\n this.capability = init.capability;\n }\n\n /** Safe, stable-shape serialization for logs and `viceme:error` events. */\n toJSON(): {\n code: ViceMeErrorCode;\n retryable: boolean;\n requestId?: string;\n capability?: string;\n } {\n const json: {\n code: ViceMeErrorCode;\n retryable: boolean;\n requestId?: string;\n capability?: string;\n } = { code: this.code, retryable: this.retryable };\n if (this.requestId !== undefined) json.requestId = this.requestId;\n if (this.capability !== undefined) json.capability = this.capability;\n return json;\n }\n}\n\nexport function isViceMeError(value: unknown): value is ViceMeError {\n return value instanceof ViceMeError;\n}\n\n/** Build a CONFIG_INVALID error with a stable, non-sensitive message. */\nexport function configInvalid(message: string): ViceMeError {\n return new ViceMeError({ code: 'CONFIG_INVALID', message, retryable: false });\n}\n\n/** Build a CLIENT_DESTROYED error for post-destroy calls. */\nexport function clientDestroyed(): ViceMeError {\n return new ViceMeError({\n code: 'CLIENT_DESTROYED',\n message: 'ViceMe client has been destroyed.',\n retryable: false,\n });\n}\n","declare const __VICEME_BUILD_CN_API_BASE_URL__: string | undefined;\ndeclare const __VICEME_BUILD_GLOBAL_API_BASE_URL__: string | undefined;\ndeclare const __VICEME_BUILD_CN_WIDGET_ORIGIN__: string | undefined;\ndeclare const __VICEME_BUILD_GLOBAL_WIDGET_ORIGIN__: string | undefined;\n\n/** Public Shop API origins baked into immutable release artifacts. */\nexport const BUILD_API_BASE_URLS = {\n cn:\n typeof __VICEME_BUILD_CN_API_BASE_URL__ === 'string'\n ? __VICEME_BUILD_CN_API_BASE_URL__\n : 'https://api.viceme.cn',\n global:\n typeof __VICEME_BUILD_GLOBAL_API_BASE_URL__ === 'string'\n ? __VICEME_BUILD_GLOBAL_API_BASE_URL__\n : 'https://api.viceme.ai',\n} as const;\n\n/** Hosted Shop origins baked into immutable release artifacts. */\nexport const BUILD_WIDGET_ORIGINS = {\n cn:\n typeof __VICEME_BUILD_CN_WIDGET_ORIGIN__ === 'string'\n ? __VICEME_BUILD_CN_WIDGET_ORIGIN__\n : 'https://viceme.cn',\n global:\n typeof __VICEME_BUILD_GLOBAL_WIDGET_ORIGIN__ === 'string'\n ? __VICEME_BUILD_GLOBAL_WIDGET_ORIGIN__\n : 'https://viceme.ai',\n} as const;\n","/**\n * Public client configuration.\n *\n * Production `createViceMe()` accepts exactly `workKey`, `region`, and\n * `signal`. Anything else (transport, clock, request ids, base URLs) is a\n * testing-only concern and lives in `@viceme-ai/sdk/testing`, so Agents can\n * never bake temporary or internal endpoints into user projects.\n */\n\nimport { configInvalid } from './errors.ts';\nimport { BUILD_API_BASE_URLS } from './build-endpoints.ts';\nexport type ViceMeRegion = 'cn' | 'global';\n\nexport interface ViceMeConfig {\n /** Public opaque test or live Work key. It is not a secret. */\n workKey: string;\n /** Routes public API and CDN traffic. */\n region: ViceMeRegion;\n /** Optional abort signal owned by the host page. */\n signal?: AbortSignal;\n}\n\nconst REGIONS: ReadonlySet<string> = new Set(['cn', 'global']);\n\n/**\n * Public API origins per region. These are the only production endpoints the\n * SDK may contact; B1 confirms final hostnames and any change happens here in\n * one place (never via a public `apiBaseUrl` option).\n */\nexport const PUBLIC_API_BASE_URLS: Readonly<Record<ViceMeRegion, string>> = {\n cn: BUILD_API_BASE_URLS.cn,\n global: BUILD_API_BASE_URLS.global,\n};\n\nexport function resolveApiBaseUrl(region: ViceMeRegion): string {\n return PUBLIC_API_BASE_URLS[region];\n}\n\nexport function isValidWorkKey(value: unknown): value is string {\n return typeof value === 'string' && /^wrk_(?:test|live)_[A-Za-z0-9_-]{4,119}$/.test(value);\n}\n\nexport function isValidRegion(value: unknown): value is ViceMeRegion {\n return typeof value === 'string' && REGIONS.has(value);\n}\n\n/**\n * Validate unknown input as a public client config. Throws a CONFIG_INVALID\n * ViceMeError that never echoes values back beyond the offending field name.\n */\nexport function validatePublicConfig(input: unknown): ViceMeConfig {\n if (typeof input !== 'object' || input === null) {\n throw configInvalid('createViceMe expects a configuration object.');\n }\n const raw = input as Record<string, unknown>;\n\n const known = new Set(['workKey', 'region', 'signal']);\n for (const key of Object.keys(raw)) {\n if (!known.has(key)) {\n throw configInvalid(`Unknown configuration field \"${key}\".`);\n }\n }\n if (!isValidWorkKey(raw.workKey)) {\n throw configInvalid(\n 'Configuration field \"workKey\" must start with \"wrk_test_\" or \"wrk_live_\".',\n );\n }\n if (!isValidRegion(raw.region)) {\n throw configInvalid('Configuration field \"region\" must be \"cn\" or \"global\".');\n }\n if (raw.signal !== undefined && !(raw.signal instanceof AbortSignal)) {\n throw configInvalid('Configuration field \"signal\" must be an AbortSignal.');\n }\n return {\n workKey: raw.workKey,\n region: raw.region,\n signal: raw.signal,\n };\n}\n","/**\n * `data-viceme-*` attribute parsing for the CDN auto-loader.\n *\n * The attribute set is fixed; unknown `data-viceme-*` attributes are rejected\n * so pages can never smuggle endpoints, tokens, secrets, prices, or payment\n * state through the loader. Parse failures never guess defaults for work,\n * region, or target.\n */\n\nimport { configInvalid } from '../core/errors.ts';\nimport type { ViceMeRegion } from '../core/config.ts';\nimport { isValidRegion, isValidWorkKey } from '../core/config.ts';\n\nexport type ViceMeTheme = 'light' | 'dark' | 'auto';\nexport type LoaderFeature = 'danmaku' | 'tip';\n\nexport interface LoaderAttributes {\n workKey: string;\n region: ViceMeRegion;\n /** Hosted capabilities mounted by this loader invocation. */\n features: LoaderFeature[];\n /** CSS selector; required whenever features are declared. */\n target?: string;\n theme: ViceMeTheme;\n}\n\nconst KNOWN_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'data-viceme-work',\n 'data-viceme-region',\n 'data-viceme-features',\n 'data-viceme-target',\n 'data-viceme-theme',\n // Marker for explicit opt-in when document.currentScript is unavailable.\n 'data-viceme-loader',\n]);\n\nconst THEMES: ReadonlySet<string> = new Set(['light', 'dark', 'auto']);\nconst FEATURE_ORDER: readonly LoaderFeature[] = ['danmaku', 'tip'];\n\nexport function parseLoaderAttributes(element: Element): LoaderAttributes {\n for (const name of element.getAttributeNames()) {\n if (name.startsWith('data-viceme-') && !KNOWN_ATTRIBUTES.has(name)) {\n throw configInvalid(`Unknown loader attribute \"${name}\".`);\n }\n }\n\n const workKey = element.getAttribute('data-viceme-work');\n if (!isValidWorkKey(workKey)) {\n throw configInvalid('Loader attribute \"data-viceme-work\" must be a public Work key.');\n }\n\n const region = element.getAttribute('data-viceme-region');\n if (!isValidRegion(region)) {\n throw configInvalid('Loader attribute \"data-viceme-region\" must be \"cn\" or \"global\".');\n }\n\n const rawFeatures = element.getAttribute('data-viceme-features');\n const declaredFeatures = rawFeatures?.split(',') ?? [];\n const featureSet = new Set(declaredFeatures);\n if (\n !rawFeatures ||\n /\\s/.test(rawFeatures) ||\n declaredFeatures.length !== featureSet.size ||\n declaredFeatures.some(\n (feature): feature is string => !FEATURE_ORDER.includes(feature as LoaderFeature),\n )\n ) {\n throw configInvalid(\n 'Loader attribute \"data-viceme-features\" must contain each of \"danmaku\" and \"tip\" at most once.',\n );\n }\n const features = FEATURE_ORDER.filter((feature) => featureSet.has(feature));\n\n const target = element.getAttribute('data-viceme-target');\n if (target === '') {\n throw configInvalid('Loader attribute \"data-viceme-target\" must be a CSS selector.');\n }\n // Loader-mounted features are visual capabilities, so a target is required.\n if (target === null) {\n throw configInvalid(\n 'Loader attribute \"data-viceme-target\" is required when features are declared.',\n );\n }\n try {\n // Probe-parse the selector now: an invalid selector is a configuration\n // error and must fail closed here, never surface later as a retryable\n // INTERNAL_ERROR from querySelectorAll.\n element.matches(target);\n } catch {\n throw configInvalid('Loader attribute \"data-viceme-target\" is not a valid CSS selector.');\n }\n\n const rawTheme = element.getAttribute('data-viceme-theme');\n if (rawTheme !== null && !THEMES.has(rawTheme)) {\n throw configInvalid('Loader attribute \"data-viceme-theme\" must be \"light\", \"dark\", or \"auto\".');\n }\n\n return {\n workKey,\n region,\n features,\n target,\n theme: (rawTheme ?? 'auto') as ViceMeTheme,\n };\n}\n","/**\n * Loader registry.\n *\n * Only the CDN loader maintains this registry (explicit `createViceMe()`\n * instances never register). Local clients are shared by\n * `major + region + workKey`; danmaku mounts are deduplicated by\n * `clientKey + capability + target Element identity`.\n *\n * The registry itself is never exposed on `window` — only the fixed\n * `ViceMe.versions.v1` diagnostics/destroy namespace is. It stores raw\n * capability handles; the loader wraps them into the public\n * `ViceMeMountedInstance` and owns destroy/event deduplication.\n */\n\nimport type { ViceMeClient } from '../core/client.ts';\nimport type { CapabilityMountHandle } from '../capability-mount.ts';\n\nexport interface RegisteredClient {\n clientKey: string;\n client: ViceMeClient;\n ready: Promise<void>;\n pendingMounts: Set<AbortController>;\n}\n\nexport interface RegisteredInstance {\n instanceKey: string;\n clientKey: string;\n capability: string;\n host: Element;\n raw: CapabilityMountHandle;\n destroyed: boolean;\n}\n\nexport function clientKeyOf(majorVersion: number, region: string, workKey: string): string {\n return `v${majorVersion}+${region}+${workKey}`;\n}\n\nexport class LoaderRegistry {\n readonly #clients = new Map<string, RegisteredClient>();\n readonly #instances = new Map<string, RegisteredInstance>();\n /** (clientKey, capability) -> mounted host element -> instance. */\n readonly #elements = new Map<string, WeakMap<Element, RegisteredInstance>>();\n #elementCounter = 0;\n\n getClient(clientKey: string): RegisteredClient | undefined {\n return this.#clients.get(clientKey);\n }\n\n registerClient(entry: RegisteredClient): void {\n this.#clients.set(entry.clientKey, entry);\n }\n\n unregisterClient(clientKey: string): void {\n this.#clients.delete(clientKey);\n }\n\n getInstance(instanceKey: string): RegisteredInstance | undefined {\n return this.#instances.get(instanceKey);\n }\n\n /** Existing mount for the same client+capability+element, if any. */\n findInstance(\n clientKey: string,\n capability: string,\n element: Element,\n ): RegisteredInstance | undefined {\n return this.#elements.get(`${clientKey}::${capability}`)?.get(element);\n }\n\n registerInstance(\n clientKey: string,\n capability: string,\n element: Element,\n raw: CapabilityMountHandle,\n ): RegisteredInstance {\n const compositeKey = `${clientKey}::${capability}`;\n let byElement = this.#elements.get(compositeKey);\n if (byElement === undefined) {\n byElement = new WeakMap();\n this.#elements.set(compositeKey, byElement);\n }\n const existing = byElement.get(element);\n if (existing) return existing;\n\n this.#elementCounter += 1;\n const instance: RegisteredInstance = {\n instanceKey: `${clientKey}::${capability}::el${this.#elementCounter}`,\n clientKey,\n capability,\n host: element,\n raw,\n destroyed: false,\n };\n this.#instances.set(instance.instanceKey, instance);\n byElement.set(element, instance);\n return instance;\n }\n\n removeInstance(instanceKey: string): RegisteredInstance | undefined {\n const instance = this.#instances.get(instanceKey);\n if (!instance) return undefined;\n this.#instances.delete(instanceKey);\n this.#elements.get(`${instance.clientKey}::${instance.capability}`)?.delete(instance.host);\n return instance;\n }\n\n instancesForClient(clientKey: string): RegisteredInstance[] {\n return [...this.#instances.values()].filter((i) => i.clientKey === clientKey);\n }\n}\n","/** Stable, allowlisted `viceme:*` DOM events shared by hosted capabilities. */\n\nimport type { ViceMeErrorCode } from './core/errors.ts';\n\nexport interface VicemeReadyDetail {\n clientKey: string;\n workKey: string;\n capabilities: string[];\n version: string;\n}\n\nexport interface VicemeCapabilityReadyDetail {\n clientKey: string;\n instanceKey: string;\n capability: string;\n version: string;\n}\n\nexport interface VicemeErrorDetail {\n clientKey?: string;\n instanceKey?: string;\n capability?: string;\n code: ViceMeErrorCode;\n retryable: boolean;\n requestId?: string;\n}\n\nexport interface VicemeDestroyedDetail {\n clientKey: string;\n instanceKey: string;\n capability: string;\n}\n\nexport interface VicemeWidgetCloseDetail {\n workId: string;\n}\n\nexport interface VicemeTipPaidDetail {\n status: 'PAID';\n work: {\n id: string;\n title: string;\n };\n amountCents: number;\n currency: 'CNY';\n}\n\nexport type VicemeEventType =\n | 'viceme:ready'\n | 'viceme:capability-ready'\n | 'viceme:error'\n | 'viceme:destroyed'\n | 'viceme:widget-close'\n | 'viceme:tip-paid';\n\nexport type VicemeEventDetailMap = {\n 'viceme:ready': VicemeReadyDetail;\n 'viceme:capability-ready': VicemeCapabilityReadyDetail;\n 'viceme:error': VicemeErrorDetail;\n 'viceme:destroyed': VicemeDestroyedDetail;\n 'viceme:widget-close': VicemeWidgetCloseDetail;\n 'viceme:tip-paid': VicemeTipPaidDetail;\n};\n\nconst ALLOWED_KEYS: ReadonlyMap<VicemeEventType, ReadonlySet<string>> = new Map([\n ['viceme:ready', new Set(['clientKey', 'workKey', 'capabilities', 'version'])],\n ['viceme:capability-ready', new Set(['clientKey', 'instanceKey', 'capability', 'version'])],\n [\n 'viceme:error',\n new Set(['clientKey', 'instanceKey', 'capability', 'code', 'retryable', 'requestId']),\n ],\n ['viceme:destroyed', new Set(['clientKey', 'instanceKey', 'capability'])],\n ['viceme:widget-close', new Set(['workId'])],\n ['viceme:tip-paid', new Set(['status', 'work', 'amountCents', 'currency'])],\n]);\n\n/** Strip anything outside the documented allowlist before dispatch. */\nexport function sanitizeDetail(\n type: VicemeEventType,\n detail: VicemeEventDetailMap[VicemeEventType],\n): VicemeEventDetailMap[VicemeEventType] {\n if (type === 'viceme:tip-paid') {\n const paid = detail as VicemeTipPaidDetail;\n return {\n status: paid.status,\n work: { id: paid.work.id, title: paid.work.title },\n amountCents: paid.amountCents,\n currency: paid.currency,\n };\n }\n const allowed = ALLOWED_KEYS.get(type)!;\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(detail)) {\n if (allowed.has(key) && value !== undefined) result[key] = value;\n }\n return result as unknown as VicemeEventDetailMap[VicemeEventType];\n}\n\nexport function dispatchViceMeEvent<K extends VicemeEventType>(\n target: EventTarget,\n type: K,\n detail: VicemeEventDetailMap[K],\n): void {\n const event = new CustomEvent(type, {\n detail: sanitizeDetail(type, detail),\n bubbles: true,\n composed: true,\n cancelable: false,\n });\n target.dispatchEvent(event);\n}\n","/**\n * Client lifecycle state machine.\n *\n * ```text\n * CREATED -> READY -> DESTROYED\n * READY -> DEGRADED (single capability unavailable; host page keeps working)\n * ```\n *\n * State is exposed read-only; consumers can never assign it directly.\n */\n\nimport { ViceMeError, clientDestroyed } from './errors.ts';\n\nexport type ViceMeClientState = 'CREATED' | 'READY' | 'DEGRADED' | 'DESTROYED';\n\nconst ALLOWED_TRANSITIONS: Readonly<Record<ViceMeClientState, readonly ViceMeClientState[]>> = {\n CREATED: ['READY', 'DESTROYED'],\n READY: ['DEGRADED', 'DESTROYED'],\n DEGRADED: ['DESTROYED'],\n DESTROYED: [],\n};\n\nexport type LifecycleListener = (state: ViceMeClientState) => void;\n\nexport class Lifecycle {\n #state: ViceMeClientState = 'CREATED';\n #listeners = new Set<LifecycleListener>();\n\n get state(): ViceMeClientState {\n return this.#state;\n }\n\n get destroyed(): boolean {\n return this.#state === 'DESTROYED';\n }\n\n transition(next: ViceMeClientState): void {\n if (next === this.#state) return;\n if (!ALLOWED_TRANSITIONS[this.#state]!.includes(next)) {\n throw new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: `Illegal lifecycle transition ${this.#state} -> ${next}.`,\n retryable: false,\n });\n }\n this.#state = next;\n for (const listener of this.#listeners) listener(next);\n }\n\n /** Any operation on a destroyed client must fail closed with this guard. */\n assertAlive(): void {\n if (this.destroyed) throw clientDestroyed();\n }\n\n subscribe(listener: LifecycleListener): () => void {\n this.#listeners.add(listener);\n return () => {\n this.#listeners.delete(listener);\n };\n }\n\n clearListeners(): void {\n this.#listeners.clear();\n }\n}\n","/**\n * Public visitor session.\n *\n * ```text\n * SDK + workKey + Origin -> POST /v1/public/work-sdk/sessions\n * -> short-lived capability token -> public capability calls\n * ```\n *\n * The token lives in memory only (never localStorage/cookies), is bound to the\n * Work, Origin, capability set, and expiry by the server, and is dropped on\n * `destroy()`. `workKey` locates the Work — it is never an authorization\n * credential.\n */\n\nimport { clientDestroyed, ViceMeError } from '../core/errors.ts';\nimport type { Transport, TransportRequest, TransportResponse } from '../transport/transport.ts';\nexport interface CreateWorkSessionRequestDto {\n workKey: string;\n}\n\nexport interface WorkDescriptor {\n key: string;\n /** Capability names enabled for this work. */\n capabilities: string[];\n creator?: WorkCreatorDescriptor;\n details?: WorkPresentationDescriptor;\n}\n\nexport interface WorkCreatorDescriptor {\n displayName: string;\n avatarUrl: string | null;\n publishedWorkCount: number;\n}\n\nexport interface WorkPresentationDescriptor {\n title: string;\n summary: string;\n coverUrl: string | null;\n}\n\nexport interface WorkSessionSnapshot {\n work: WorkDescriptor;\n /** Opaque short-lived capability token; memory-only. */\n token?: string;\n /** Epoch milliseconds when the token expires, when provided by the server. */\n expiresAt?: number;\n user?: WorkUser;\n userToken?: string;\n}\n\nexport interface WorkUser {\n subject: string;\n nickname: string | null;\n avatarUrl: string | null;\n}\n\nexport interface SessionManagerOptions {\n workKey: string;\n transport: Transport;\n signal?: AbortSignal;\n timeoutMs?: number;\n /** Injectable clock for tests. */\n now?: () => number;\n}\n\nfunction parseSessionResponse(body: unknown, workKey: string): WorkSessionSnapshot {\n if (typeof body !== 'object' || body === null) {\n throw malformedSessionResponse();\n }\n const raw = body as Record<string, unknown>;\n if (\n typeof raw.workKey !== 'string' ||\n !Array.isArray(raw.capabilities) ||\n !raw.capabilities.every((c) => typeof c === 'string')\n ) {\n throw malformedSessionResponse();\n }\n if (raw.workKey !== workKey) {\n throw new ViceMeError({\n code: 'WORK_NOT_FOUND',\n message: 'Work-session response did not match the requested work key.',\n retryable: false,\n });\n }\n const snapshot: WorkSessionSnapshot = {\n work: {\n key: raw.workKey,\n capabilities: raw.capabilities as string[],\n },\n };\n if (raw.creator !== undefined || raw.work !== undefined) {\n const creator = record(raw.creator);\n const work = record(raw.work);\n if (\n typeof creator.displayName !== 'string' ||\n creator.displayName.length === 0 ||\n !nullableUrl(creator.avatarUrl) ||\n !Number.isInteger(creator.publishedWorkCount) ||\n (creator.publishedWorkCount as number) < 0 ||\n typeof work.title !== 'string' ||\n work.title.length === 0 ||\n typeof work.summary !== 'string' ||\n !nullableUrl(work.coverUrl)\n ) {\n throw malformedSessionResponse();\n }\n snapshot.work.creator = {\n displayName: creator.displayName,\n avatarUrl: creator.avatarUrl as string | null,\n publishedWorkCount: creator.publishedWorkCount as number,\n };\n snapshot.work.details = {\n title: work.title,\n summary: work.summary,\n coverUrl: work.coverUrl as string | null,\n };\n }\n // Unknown extra fields are allowed and ignored (forward compatibility).\n if (typeof raw.token === 'string') snapshot.token = raw.token;\n if (typeof raw.expiresAt === 'string') {\n const expiresAt = new Date(raw.expiresAt).getTime();\n if (!Number.isNaN(expiresAt)) snapshot.expiresAt = expiresAt;\n }\n return snapshot;\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n if (typeof value !== 'object' || value === null) throw malformedSessionResponse();\n return value as Record<string, unknown>;\n}\n\nfunction nullableUrl(value: unknown): value is string | null {\n if (value === null) return true;\n if (typeof value !== 'string') return false;\n try {\n new URL(value);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction malformedSessionResponse(): ViceMeError {\n return new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: 'Malformed work-session response.',\n retryable: true,\n });\n}\n\nfunction sessionInvalidated(): ViceMeError {\n return new ViceMeError({\n code: 'SESSION_EXPIRED',\n message: 'The work session was invalidated before it completed.',\n retryable: true,\n });\n}\n\nexport class SessionManager {\n readonly #options: SessionManagerOptions;\n readonly #now: () => number;\n #snapshot: WorkSessionSnapshot | undefined;\n #pending: Promise<WorkSessionSnapshot> | undefined;\n #generation = 0;\n #destroyed = false;\n\n constructor(options: SessionManagerOptions) {\n this.#options = options;\n this.#now = options.now ?? (() => Date.now());\n }\n\n get snapshot(): WorkSessionSnapshot | undefined {\n return this.#snapshot;\n }\n\n /** True when the cached snapshot's server-provided expiry has passed. */\n #isExpired(): boolean {\n const expiresAt = this.#snapshot?.expiresAt;\n return expiresAt !== undefined && expiresAt <= this.#now();\n }\n\n /**\n * Establish (or return the established) public session.\n *\n * A cached snapshot is reused only while it is unexpired; an expired\n * snapshot is dropped and re-authenticated. Concurrent callers share one\n * in-flight request (single flight).\n */\n establish(): Promise<WorkSessionSnapshot> {\n if (this.#destroyed) return Promise.reject(clientDestroyed());\n if (this.#snapshot) {\n if (!this.#isExpired()) return Promise.resolve(this.#snapshot);\n this.#snapshot = undefined;\n }\n if (this.#pending) return this.#pending;\n const generation = this.#generation;\n const pending = this.#options.transport\n .request({\n method: 'POST',\n path: '/v1/public/work-sdk/sessions',\n body: { workKey: this.#options.workKey } satisfies CreateWorkSessionRequestDto,\n signal: this.#options.signal,\n timeoutMs: this.#options.timeoutMs,\n })\n .then((response) => {\n this.#assertCurrent(generation);\n const snapshot = parseSessionResponse(response.body, this.#options.workKey);\n this.#assertCurrent(generation);\n this.#snapshot = snapshot;\n return snapshot;\n })\n .finally(() => {\n if (this.#pending === pending) this.#pending = undefined;\n });\n this.#pending = pending;\n return pending;\n }\n\n async request(\n request: Omit<TransportRequest, 'authorization' | 'userAuthorization' | 'signal'>,\n ): Promise<TransportResponse> {\n const snapshot = await this.establish();\n if (!snapshot.token) throw malformedSessionResponse();\n try {\n return await this.#requestWithSnapshot(request, snapshot);\n } catch (error) {\n if (this.#destroyed) throw clientDestroyed();\n if (!(error instanceof ViceMeError) || error.code !== 'SESSION_EXPIRED') throw error;\n if (this.#snapshot === snapshot) this.invalidate();\n const refreshed = await this.establish();\n if (!refreshed.token) throw malformedSessionResponse();\n return this.#requestWithSnapshot(request, refreshed);\n }\n }\n\n authenticate(input: { userToken: string; user: WorkUser }): void {\n this.#assertAlive();\n if (!this.#snapshot) throw malformedSessionResponse();\n this.#snapshot = {\n ...this.#snapshot,\n userToken: input.userToken,\n user: input.user,\n };\n }\n\n async signOut(): Promise<void> {\n this.#assertAlive();\n this.invalidate();\n await this.establish();\n }\n\n /** Drop the token; next `establish()` re-authenticates. */\n invalidate(): void {\n this.#generation += 1;\n this.#snapshot = undefined;\n this.#pending = undefined;\n }\n\n /** Hard cleanup: forget the token and pending work. */\n destroy(): void {\n if (this.#destroyed) return;\n this.#destroyed = true;\n this.#generation += 1;\n this.#snapshot = undefined;\n this.#pending = undefined;\n }\n\n #assertAlive(): void {\n if (this.#destroyed) throw clientDestroyed();\n }\n\n #assertCurrent(generation: number): void {\n this.#assertAlive();\n if (generation !== this.#generation) throw sessionInvalidated();\n }\n\n async #requestWithSnapshot(\n request: Omit<TransportRequest, 'authorization' | 'userAuthorization' | 'signal'>,\n snapshot: WorkSessionSnapshot,\n ): Promise<TransportResponse> {\n this.#assertAlive();\n try {\n const response = await this.#options.transport.request({\n ...request,\n authorization: snapshot.token,\n userAuthorization: snapshot.userToken,\n signal: this.#options.signal,\n });\n this.#assertAlive();\n return response;\n } catch (error) {\n if (this.#destroyed) throw clientDestroyed();\n throw error;\n }\n }\n}\n","/**\n * Single source of truth for the SDK runtime version.\n *\n * Kept in sync with `packages/sdk/package.json#version`; a unit test enforces\n * the match so the loader, release manifest, and npm metadata can never drift.\n */\nexport const SDK_VERSION = '0.7.0';\n\n/** Public API major carried by this build (loader namespace `v1`). */\nexport const API_MAJOR = 1;\n","import type { FollowTarget } from './capabilities.ts';\nimport { isViceMeError } from './errors.ts';\n\nexport type AccessInteractionAction = 'SIGN_IN' | 'FOLLOW' | 'CHECKOUT';\n\nexport interface AccessInteraction {\n featureKey: string;\n reason: string;\n action: AccessInteractionAction;\n followTarget?: FollowTarget;\n work?: {\n title: string;\n summary: string;\n coverUrl: string | null;\n };\n /** Client-owned lifecycle signal; abort closes any active hosted surface. */\n signal?: AbortSignal;\n perform(): Promise<AccessActionResult>;\n}\n\nexport interface AccessCompletedAction {\n type: 'completed';\n}\n\nexport interface AccessFrameAction {\n type: 'frame';\n url: string;\n completion: Promise<void>;\n cancel(): void;\n}\n\nexport interface AccessExternalAction {\n type: 'external';\n completion: Promise<void>;\n cancel(): void;\n}\n\nexport type AccessActionResult = AccessCompletedAction | AccessFrameAction | AccessExternalAction;\n\nexport type AccessPresentationResult = 'acted' | 'dismissed';\n\n/** Internal interaction seam used by the ViceMe layer and deterministic tests. */\nexport type AccessPresenter = (interaction: AccessInteraction) => Promise<AccessPresentationResult>;\n\nconst ELEMENT_NAME = 'viceme-access-layer';\nconst PROFILE_DESCRIPTION_LIMIT = 50;\n\ninterface AccessLayerElement extends HTMLElement {\n interaction: AccessInteraction;\n}\n\nfunction actionCopy(action: AccessInteractionAction): {\n description: string;\n label: string;\n} {\n switch (action) {\n case 'SIGN_IN':\n return {\n description: '',\n label: '授权',\n };\n case 'FOLLOW':\n return {\n description: '',\n label: '关注',\n };\n case 'CHECKOUT':\n return {\n description: '',\n label: '打开支付',\n };\n }\n}\n\nfunction actionErrorCopy(error: unknown): string {\n if (!isViceMeError(error)) return '操作未完成,请重试。';\n switch (error.code) {\n case 'CONFIG_INVALID':\n return '微信授权配置无效,请稍后重试。';\n case 'AUTH_CANCELLED':\n return '微信授权已取消,请重试。';\n case 'SESSION_EXPIRED':\n return '授权会话已过期,请重试。';\n case 'NETWORK_TIMEOUT':\n return '网络连接超时,请重试。';\n default:\n return error.requestId\n ? `操作未完成,请重试。请求 ID:${error.requestId}`\n : '操作未完成,请重试。';\n }\n}\n\nfunction ensureAccessLayerElement(): void {\n if (customElements.get(ELEMENT_NAME)) return;\n\n class ViceMeAccessLayerElement extends HTMLElement implements AccessLayerElement {\n interaction!: AccessInteraction;\n\n connectedCallback(): void {\n const copy = actionCopy(this.interaction.action);\n const shadow = this.attachShadow({ mode: 'open' });\n shadow.innerHTML = `\n <style>\n :host {\n position: fixed;\n inset: 0;\n z-index: 2147483000;\n display: grid;\n align-items: end;\n color: #18181b;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif;\n font-size: 16px;\n line-height: 1.5;\n }\n [data-viceme='backdrop'] {\n position: absolute;\n inset: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n }\n [data-viceme='panel'] {\n position: relative;\n box-sizing: border-box;\n display: flex;\n width: 100%;\n max-height: min(92dvh, 46rem);\n flex-direction: column;\n overflow: auto;\n border-radius: 1.25rem 1.25rem 0 0;\n background: #ffffff;\n color: #18181b;\n padding: 3.75rem 1.25rem calc(1.25rem + env(safe-area-inset-bottom));\n box-shadow: 0 -1rem 3rem rgb(0 0 0 / 18%);\n }\n [data-viceme='content'] { display: flex; min-height: 0; flex-direction: column; }\n [data-viceme='close'] {\n position: absolute;\n top: 0.75rem;\n left: 0.75rem;\n width: 2.75rem;\n height: 2.75rem;\n border: 0;\n border-radius: 999px;\n padding: 0;\n background: transparent;\n color: #52525b;\n font-size: 2rem;\n font-weight: 400;\n line-height: 1;\n }\n [data-viceme='description'] { margin: 0.75rem 0 1.25rem; color: #71717a; line-height: 1.6; }\n [data-viceme='profile'] {\n display: none;\n margin: 0;\n border: 1px solid #e4e4e7;\n border-radius: 1rem;\n padding: 1.5rem;\n background: #ffffff;\n box-shadow: 0 0.75rem 2rem rgb(0 0 0 / 6%);\n text-align: center;\n }\n [data-viceme='profile'][data-visible='true'] { display: block; }\n [data-viceme='avatar'] {\n display: block;\n width: 5.5rem;\n height: 5.5rem;\n margin: 0 auto 1rem;\n border-radius: 999px;\n object-fit: cover;\n background: #f4f4f5;\n }\n [data-viceme='avatar-fallback'] {\n display: grid;\n width: 5.5rem;\n height: 5.5rem;\n margin: 0 auto 1rem;\n place-items: center;\n border-radius: 999px;\n background: #f4f4f5;\n color: #18181b;\n font-size: 2rem;\n font-weight: 700;\n }\n [data-viceme='avatar'][hidden], [data-viceme='avatar-fallback'][hidden] { display: none; }\n [data-viceme='profile-summary'] {\n display: flex;\n min-width: 0;\n align-items: baseline;\n justify-content: center;\n gap: 0.5rem;\n }\n [data-viceme='profile-name'] { margin: 0; font-size: 1.375rem; font-weight: 700; }\n [data-viceme='profile-separator'], [data-viceme='profile-stats'] {\n color: #71717a;\n }\n [data-viceme='profile-description'] {\n margin: 0.25rem 0 0;\n overflow-wrap: anywhere;\n color: #71717a;\n }\n [data-viceme='profile-description']:empty { display: none; }\n [data-viceme='profile-stats'] {\n margin: 0;\n font-size: 0.875rem;\n }\n [data-viceme='profile-header'] { min-width: 0; }\n [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='description'] { display: none; }\n [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='profile'][data-visible='true'] {\n display: block;\n border: 0;\n padding: 0;\n background: transparent;\n box-shadow: none;\n text-align: center;\n }\n [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='profile-name'] {\n font-size: 1.125rem;\n }\n [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='profile-description'] {\n display: none;\n }\n [data-viceme='work'] {\n display: none;\n overflow: hidden;\n margin-top: 1.25rem;\n border: 1px solid #e4e4e7;\n border-radius: 1rem;\n background: #fafafa;\n text-align: left;\n }\n [data-viceme='work'][data-visible='true'] { display: block; }\n [data-viceme='work-cover'] {\n display: block;\n width: 100%;\n aspect-ratio: 16 / 9;\n object-fit: cover;\n background: #f4f4f5;\n }\n [data-viceme='work-cover'][hidden] { display: none; }\n [data-viceme='work-copy'] { padding: 1rem; }\n [data-viceme='work-title'] {\n margin: 0;\n color: #18181b;\n font-size: 1rem;\n font-weight: 700;\n line-height: 1.5;\n }\n [data-viceme='work-summary'] {\n display: -webkit-box;\n overflow: hidden;\n margin: 0.375rem 0 0;\n color: #71717a;\n font-size: 0.875rem;\n line-height: 1.5;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n }\n [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='action'] {\n width: 100%;\n }\n [data-viceme='actions'] {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n margin-top: 1.25rem;\n }\n button {\n box-sizing: border-box;\n display: inline-flex;\n height: 3.25rem;\n align-items: center;\n justify-content: center;\n border-radius: 0.75rem;\n padding: 0.625rem 1rem;\n font: 600 1rem/1.5 -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif;\n cursor: pointer;\n }\n button:focus-visible, iframe:focus-visible { outline: 2px solid #18181b; outline-offset: 2px; }\n [data-viceme='action'] {\n width: min(11rem, 48%);\n border: 1px solid #18181b;\n background: #18181b;\n color: #ffffff;\n }\n [data-viceme='action']:hover { background: #3f3f46; border-color: #3f3f46; }\n [data-viceme='actions'][data-single='true'] [data-viceme='action'] { width: 100%; }\n button:disabled { cursor: wait; opacity: 0.5; }\n button[hidden] { display: none; }\n [data-viceme='error'] { margin: 0.75rem 0 0; color: #b91c1c; font-size: 0.875rem; }\n [data-viceme='error']:empty { display: none; }\n [data-viceme='frame'] {\n display: none;\n width: 100%;\n min-height: 0;\n flex: 1 1 auto;\n border: 0;\n border-radius: 0.75rem;\n background: #ffffff;\n }\n [data-viceme='panel'][data-frame='true'] {\n height: min(92dvh, 46rem);\n max-height: 92dvh;\n overflow: hidden;\n }\n [data-viceme='panel'][data-frame='true'] [data-viceme='content'] { display: none; }\n [data-viceme='panel'][data-frame='true'] [data-viceme='frame'] { display: block; }\n @media (min-width: 48rem) {\n :host { place-items: center; padding: 1.5rem; }\n [data-viceme='panel'] {\n width: min(24rem, 100%);\n border-radius: 1.25rem;\n padding: 3.75rem 1.25rem 1.25rem;\n box-shadow: 0 1.5rem 4rem rgb(0 0 0 / 24%);\n }\n [data-viceme='panel'][data-frame='true'] { width: min(30rem, 100%); }\n [data-viceme='panel'][data-action='SIGN_IN'] { width: min(30rem, 100%); }\n [data-viceme='panel'][data-action='CHECKOUT'][data-frame='true'] {\n width: min(42rem, 100%);\n }\n }\n @media (prefers-reduced-motion: no-preference) {\n [data-viceme='panel'] { animation: viceme-enter 160ms ease-out; }\n @keyframes viceme-enter { from { opacity: 0; transform: translateY(1rem); } }\n }\n </style>\n <button data-viceme=\"backdrop\" type=\"button\" tabindex=\"-1\" aria-label=\"关闭\"></button>\n <section data-viceme=\"panel\" role=\"dialog\" aria-modal=\"true\" aria-label=\"ViceMe 授权\">\n <button data-viceme=\"close\" type=\"button\" aria-label=\"关闭\">×</button>\n <div data-viceme=\"content\">\n <p data-viceme=\"description\"></p>\n <section data-viceme=\"profile\" aria-label=\"创作者\">\n <div data-viceme=\"profile-header\">\n <img data-viceme=\"avatar\" hidden />\n <span data-viceme=\"avatar-fallback\" aria-hidden=\"true\"></span>\n <div data-viceme=\"profile-summary\">\n <p data-viceme=\"profile-name\"></p>\n <span data-viceme=\"profile-separator\" aria-hidden=\"true\">·</span>\n <p data-viceme=\"profile-stats\"></p>\n </div>\n </div>\n <p data-viceme=\"profile-description\"></p>\n </section>\n <article data-viceme=\"work\">\n <img data-viceme=\"work-cover\" hidden />\n <div data-viceme=\"work-copy\">\n <p data-viceme=\"work-title\"></p>\n <p data-viceme=\"work-summary\"></p>\n </div>\n </article>\n <p data-viceme=\"error\" role=\"alert\" aria-live=\"polite\"></p>\n <div data-viceme=\"actions\">\n <button data-viceme=\"action\" type=\"button\"></button>\n </div>\n </div>\n <iframe data-viceme=\"frame\" title=\"\" referrerpolicy=\"no-referrer\" allow=\"payment\"></iframe>\n </section>\n `;\n const panel = shadow.querySelector<HTMLElement>(\"[data-viceme='panel']\")!;\n panel.dataset.action = this.interaction.action;\n panel.dataset.frame = 'false';\n const description = shadow.querySelector<HTMLElement>(\"[data-viceme='description']\")!;\n description.textContent = copy.description;\n const action = shadow.querySelector<HTMLButtonElement>(\"[data-viceme='action']\")!;\n const mainActions = action.parentElement!;\n const closeAction = shadow.querySelector<HTMLButtonElement>(\"[data-viceme='close']\")!;\n const backdrop = shadow.querySelector<HTMLButtonElement>(\"[data-viceme='backdrop']\")!;\n const error = shadow.querySelector<HTMLElement>(\"[data-viceme='error']\")!;\n const frame = shadow.querySelector<HTMLIFrameElement>(\"[data-viceme='frame']\")!;\n const profile = shadow.querySelector<HTMLElement>(\"[data-viceme='profile']\")!;\n const avatar = shadow.querySelector<HTMLImageElement>(\"[data-viceme='avatar']\")!;\n const avatarFallback = shadow.querySelector<HTMLElement>(\"[data-viceme='avatar-fallback']\")!;\n const profileName = shadow.querySelector<HTMLElement>(\"[data-viceme='profile-name']\")!;\n const profileDescription = shadow.querySelector<HTMLElement>(\n \"[data-viceme='profile-description']\",\n )!;\n const profileStats = shadow.querySelector<HTMLElement>(\"[data-viceme='profile-stats']\")!;\n const work = shadow.querySelector<HTMLElement>(\"[data-viceme='work']\")!;\n const workCover = shadow.querySelector<HTMLImageElement>(\"[data-viceme='work-cover']\")!;\n const workTitle = shadow.querySelector<HTMLElement>(\"[data-viceme='work-title']\")!;\n const workSummary = shadow.querySelector<HTMLElement>(\"[data-viceme='work-summary']\")!;\n action.textContent = copy.label;\n action.hidden = false;\n mainActions.dataset.single = 'true';\n const idleActionLabel = copy.label;\n frame.title = this.interaction.action === 'SIGN_IN' ? '登录授权' : '支付';\n\n const target = this.interaction.followTarget;\n if (target) {\n panel.setAttribute(\n 'aria-label',\n this.interaction.action === 'SIGN_IN'\n ? `授权 ${target.displayName}`\n : `关注 ${target.displayName}`,\n );\n profile.dataset.visible = 'true';\n profileName.textContent = target.displayName;\n const descriptionCharacters = [...(target.description ?? '')];\n profileDescription.textContent =\n descriptionCharacters.length > PROFILE_DESCRIPTION_LIMIT\n ? `${descriptionCharacters.slice(0, PROFILE_DESCRIPTION_LIMIT).join('')}…`\n : descriptionCharacters.join('');\n if (descriptionCharacters.length > PROFILE_DESCRIPTION_LIMIT) {\n profileDescription.title = target.description!;\n }\n profileStats.textContent = `${target.workCount} 个作品`;\n avatarFallback.textContent = target.displayName.trim().slice(0, 1) || 'V';\n if (target.avatarUrl) {\n avatar.src = target.avatarUrl;\n avatar.alt = `${target.displayName}的头像`;\n avatar.hidden = false;\n avatarFallback.hidden = true;\n }\n }\n const workDetails = this.interaction.work;\n if (workDetails) {\n work.dataset.visible = 'true';\n workTitle.textContent = workDetails.title;\n workSummary.textContent = workDetails.summary;\n if (workDetails.coverUrl) {\n workCover.src = workDetails.coverUrl;\n workCover.alt = workDetails.title;\n workCover.hidden = false;\n }\n }\n\n let activeAction: AccessFrameAction | AccessExternalAction | null = null;\n let closed = false;\n const close = (result: AccessPresentationResult) => {\n if (closed) return;\n closed = true;\n this.interaction.signal?.removeEventListener('abort', dismissLayer);\n this.dispatchEvent(new CustomEvent('viceme:access-layer-close', { detail: result }));\n };\n const dismissLayer = () => {\n activeAction?.cancel();\n close('dismissed');\n };\n this.interaction.signal?.addEventListener('abort', dismissLayer, { once: true });\n if (this.interaction.signal?.aborted) queueMicrotask(dismissLayer);\n backdrop.addEventListener('click', dismissLayer);\n closeAction.addEventListener('click', dismissLayer);\n this.addEventListener('keydown', (event) => {\n if (event.key === 'Escape') dismissLayer();\n if (event.key === 'Tab') {\n event.preventDefault();\n if (activeAction?.type === 'frame') {\n frame.focus();\n return;\n }\n const focusable = [closeAction, ...(action.hidden ? [] : [action])];\n const available = focusable.filter((element) => !element.disabled && !element.hidden);\n if (available.length === 0) return;\n const currentIndex = available.indexOf(shadow.activeElement as HTMLButtonElement);\n const direction = event.shiftKey ? -1 : 1;\n available[(currentIndex + direction + available.length) % available.length]?.focus();\n }\n });\n const performAction = async () => {\n action.disabled = true;\n action.setAttribute('aria-busy', 'true');\n action.textContent = '正在打开…';\n error.textContent = '';\n try {\n const result = await this.interaction.perform();\n // The layer may close while an async action is still being created.\n // Cancel that late action immediately so its timers/listeners cannot\n // outlive the client-owned presentation surface.\n if (closed || this.interaction.signal?.aborted) {\n if (result.type !== 'completed') result.cancel();\n return;\n }\n if (result.type === 'frame') {\n activeAction = result;\n panel.dataset.frame = 'true';\n frame.src = result.url;\n frame.focus();\n await result.completion;\n } else if (result.type === 'external') {\n activeAction = result;\n await result.completion;\n }\n close('acted');\n } catch (caught) {\n if (closed) return;\n activeAction?.cancel();\n activeAction = null;\n panel.dataset.frame = 'false';\n frame.removeAttribute('src');\n error.textContent = actionErrorCopy(caught);\n action.hidden = false;\n action.disabled = false;\n action.removeAttribute('aria-busy');\n action.textContent = idleActionLabel;\n action.focus();\n }\n };\n action.addEventListener('click', performAction);\n queueMicrotask(() => action.focus());\n }\n }\n\n customElements.define(ELEMENT_NAME, ViceMeAccessLayerElement);\n}\n\nexport const defaultAccessPresenter: AccessPresenter = async (interaction) => {\n if (typeof document === 'undefined' || typeof customElements === 'undefined') {\n return 'dismissed';\n }\n if (interaction.signal?.aborted) return 'dismissed';\n ensureAccessLayerElement();\n const element = document.createElement(ELEMENT_NAME) as AccessLayerElement;\n element.interaction = interaction;\n const previousOverflow = document.documentElement.style.overflow;\n const previousFocus =\n document.activeElement instanceof HTMLElement ? document.activeElement : null;\n document.documentElement.style.overflow = 'hidden';\n document.body.append(element);\n try {\n return await new Promise<AccessPresentationResult>((resolve) => {\n element.addEventListener(\n 'viceme:access-layer-close',\n (event) => resolve((event as CustomEvent<AccessPresentationResult>).detail),\n { once: true },\n );\n });\n } finally {\n element.remove();\n document.documentElement.style.overflow = previousOverflow;\n previousFocus?.focus();\n }\n};\n","import { clientDestroyed, ViceMeError } from './errors.ts';\nimport {\n defaultAccessPresenter,\n type AccessActionResult,\n type AccessFrameAction,\n type AccessInteraction,\n type AccessPresenter,\n} from './presentation.ts';\nimport type { SessionManager, WorkUser } from '../session/session.ts';\n\nexport interface AuthState {\n authenticated: boolean;\n user: WorkUser | null;\n}\n\nexport interface FollowState {\n following: boolean;\n followedAt: string | null;\n target: FollowTarget;\n}\n\nexport interface FollowTarget {\n kind: 'CREATOR' | 'USER';\n displayName: string;\n avatarUrl: string | null;\n description: string | null;\n workCount: number;\n}\n\nexport type AccessReason =\n | 'PUBLIC'\n | 'OWNER'\n | 'FOLLOWING'\n | 'ENTITLED'\n | 'AUTH_REQUIRED'\n | 'FOLLOW_REQUIRED'\n | 'PURCHASE_REQUIRED'\n | 'FEATURE_NOT_FOUND'\n | 'FEATURE_DISABLED';\n\nexport interface AccessDecision {\n allowed: boolean;\n reason: AccessReason;\n nextAction: 'SIGN_IN' | 'FOLLOW' | 'CHECKOUT' | null;\n}\n\nexport type AccessPolicyType = 'PUBLIC' | 'FOLLOW_OWNER' | 'WORK_ENTITLEMENT';\n\nexport interface AccessFeaturePresentation {\n featureKey: string;\n title: string;\n policy: { type: AccessPolicyType };\n price: { amountCents: number; currency: 'CNY' } | null;\n}\n\nexport interface CheckoutOptions {\n featureKey: string;\n locale?: 'zh-CN' | 'en-US';\n}\n\nexport interface CheckoutResult {\n checkoutUrl: string;\n alreadyOwned: boolean;\n expiresAt: string | null;\n}\n\nexport interface AuthCapability {\n getState(): Promise<AuthState>;\n signIn(): Promise<AuthState>;\n signOut(): Promise<void>;\n}\n\nexport interface FollowCapability {\n getState(): Promise<FollowState>;\n follow(): Promise<FollowState>;\n unfollow(): Promise<FollowState>;\n}\n\nexport interface AccessCapability {\n getFeatures(): Promise<AccessFeaturePresentation[]>;\n check(featureKey: string): Promise<AccessDecision>;\n checkMany(featureKeys: string[]): Promise<Record<string, AccessDecision>>;\n require(featureKey: string): Promise<AccessDecision>;\n refresh(): Promise<void>;\n}\n\nexport interface CheckoutCapability {\n open(options: CheckoutOptions): Promise<CheckoutResult>;\n}\n\ninterface CapabilityDeps {\n session: SessionManager;\n workKey: string;\n widgetOrigin: string;\n now: () => number;\n presenter?: AccessPresenter;\n signal: AbortSignal;\n ready: () => Promise<void>;\n}\n\nfunction objectBody(value: unknown): Record<string, unknown> {\n if (typeof value !== 'object' || value === null) throw malformedResponse();\n return value as Record<string, unknown>;\n}\n\nfunction malformedResponse(): ViceMeError {\n return new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: 'Malformed public API response.',\n retryable: true,\n });\n}\n\nfunction parseUser(value: unknown): WorkUser {\n const body = objectBody(value);\n if (\n typeof body.id !== 'string' ||\n !(typeof body.displayName === 'string' || body.displayName === null) ||\n !(typeof body.avatarUrl === 'string' || body.avatarUrl === null)\n ) {\n throw malformedResponse();\n }\n return {\n subject: body.id,\n nickname: body.displayName,\n avatarUrl: body.avatarUrl,\n };\n}\n\nfunction parseFollowState(value: unknown): FollowState {\n const body = objectBody(value);\n if (\n typeof body.following !== 'boolean' ||\n !(typeof body.followedAt === 'string' || body.followedAt === null)\n ) {\n throw malformedResponse();\n }\n const target = objectBody(body.creator);\n if (\n typeof target.displayName !== 'string' ||\n !(typeof target.avatarUrl === 'string' || target.avatarUrl === null) ||\n !(typeof target.description === 'string' || target.description === null) ||\n !Number.isInteger(target.publishedWorkCount) ||\n (target.publishedWorkCount as number) < 0\n ) {\n throw malformedResponse();\n }\n return {\n following: body.following,\n followedAt: body.followedAt,\n target: {\n kind: 'CREATOR',\n displayName: target.displayName,\n avatarUrl: target.avatarUrl,\n description: target.description,\n workCount: target.publishedWorkCount as number,\n },\n };\n}\n\nfunction parseDecision(value: unknown): AccessDecision {\n const body = objectBody(value);\n const reasons: ReadonlySet<string> = new Set([\n 'PUBLIC',\n 'OWNER',\n 'FOLLOWING',\n 'ENTITLED',\n 'AUTH_REQUIRED',\n 'FOLLOW_REQUIRED',\n 'PURCHASE_REQUIRED',\n 'FEATURE_NOT_FOUND',\n 'FEATURE_DISABLED',\n ]);\n const actions: ReadonlySet<unknown> = new Set([null, 'SIGN_IN', 'FOLLOW', 'CHECKOUT']);\n if (\n typeof body.allowed !== 'boolean' ||\n typeof body.reason !== 'string' ||\n !reasons.has(body.reason) ||\n !actions.has(body.nextAction)\n ) {\n throw malformedResponse();\n }\n return {\n allowed: body.allowed,\n reason: body.reason as AccessReason,\n nextAction: body.nextAction as AccessDecision['nextAction'],\n };\n}\n\nfunction parseFeaturePresentation(value: unknown): AccessFeaturePresentation {\n const body = objectBody(value);\n if (\n typeof body.featureKey !== 'string' ||\n !/^[a-z][a-z0-9_-]{1,63}$/.test(body.featureKey) ||\n typeof body.title !== 'string' ||\n body.title.trim().length === 0 ||\n body.title.length > 120 ||\n !(\n body.policyType === 'PUBLIC' ||\n body.policyType === 'FOLLOW_OWNER' ||\n body.policyType === 'WORK_ENTITLEMENT'\n )\n ) {\n throw malformedResponse();\n }\n const price = body.price === null ? null : objectBody(body.price);\n if (\n price !== null &&\n (!Number.isInteger(price.amountCents) ||\n (price.amountCents as number) <= 0 ||\n price.currency !== 'CNY')\n ) {\n throw malformedResponse();\n }\n if ((body.policyType === 'WORK_ENTITLEMENT') !== (price !== null)) {\n throw malformedResponse();\n }\n return {\n featureKey: body.featureKey,\n title: body.title,\n policy: { type: body.policyType },\n price: price === null ? null : { amountCents: price.amountCents as number, currency: 'CNY' },\n };\n}\n\nfunction randomVerifier(): string {\n const bytes = crypto.getRandomValues(new Uint8Array(32));\n return base64Url(bytes);\n}\n\nfunction base64Url(bytes: Uint8Array): string {\n let binary = '';\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary).replaceAll('+', '-').replaceAll('/', '_').replace(/=+$/, '');\n}\n\nfunction resolveLocale(): 'zh-CN' | 'en-US' {\n return typeof document !== 'undefined' && document.documentElement.lang.toLowerCase() === 'en-us'\n ? 'en-US'\n : 'zh-CN';\n}\n\nexport function createCapabilities(deps: CapabilityDeps): {\n auth: AuthCapability;\n follow: FollowCapability;\n access: AccessCapability;\n checkout: CheckoutCapability;\n} {\n const cancelled = () =>\n new ViceMeError({\n code: 'AUTH_CANCELLED',\n message: 'The interactive action was cancelled.',\n retryable: false,\n });\n\n const present = (\n interaction: Omit<Parameters<AccessPresenter>[0], 'signal'>,\n ): ReturnType<AccessPresenter> => {\n if (deps.signal.aborted) return Promise.reject(clientDestroyed());\n let onAbort: (() => void) | undefined;\n const cancellation = new Promise<never>((_resolve, reject) => {\n onAbort = () => reject(clientDestroyed());\n deps.signal.addEventListener('abort', onAbort, { once: true });\n if (deps.signal.aborted) onAbort();\n });\n let presentation: ReturnType<AccessPresenter>;\n try {\n presentation = (deps.presenter ?? defaultAccessPresenter)({\n ...interaction,\n signal: deps.signal,\n });\n } catch (error) {\n presentation = Promise.reject(error);\n }\n return Promise.race([presentation, cancellation])\n .then((result) => {\n if (deps.signal.aborted) throw clientDestroyed();\n return result;\n })\n .finally(() => {\n if (onAbort) deps.signal.removeEventListener('abort', onAbort);\n });\n };\n\n const embeddedFrame = (\n url: string,\n completionOrigin: string,\n channel: string,\n type: 'auth',\n initialization: Record<string, unknown>,\n complete: (data: Record<string, unknown>) => Promise<void>,\n ): AccessFrameAction => {\n if (typeof window === 'undefined') {\n throw new ViceMeError({\n code: 'CONFIG_INVALID',\n message: 'Interactive access requires a browser window.',\n retryable: false,\n });\n }\n let active = true;\n let settle!: () => void;\n let fail!: (error: unknown) => void;\n const cleanup = () => {\n if (!active) return;\n active = false;\n window.removeEventListener('message', receive);\n };\n const completion = new Promise<void>((resolve, reject) => {\n settle = resolve;\n fail = reject;\n });\n const receive = (event: MessageEvent) => {\n if (!active || event.origin !== completionOrigin) return;\n if (typeof event.data !== 'object' || event.data === null) return;\n const data = event.data as Record<string, unknown>;\n if (data.workKey !== deps.workKey || data.channel !== channel) return;\n if (data.type === `viceme:${type}:ready`) {\n if (event.source && 'postMessage' in event.source) {\n (event.source as WindowProxy).postMessage(\n {\n type: `viceme:${type}:init`,\n workKey: deps.workKey,\n channel,\n ...initialization,\n },\n completionOrigin,\n );\n }\n return;\n }\n if (data.type === `viceme:${type}:cancelled`) {\n cleanup();\n fail(cancelled());\n return;\n }\n if (data.type !== `viceme:${type}:complete`) return;\n cleanup();\n void complete(data).then(settle, fail);\n };\n window.addEventListener('message', receive);\n return {\n type: 'frame',\n url,\n completion,\n cancel() {\n cleanup();\n settle();\n },\n };\n };\n\n const startSignIn = async (): Promise<AccessActionResult> => {\n await deps.ready();\n if (typeof window === 'undefined') {\n throw new ViceMeError({\n code: 'CONFIG_INVALID',\n message: 'Interactive access requires a browser window.',\n retryable: false,\n });\n }\n const channel = randomVerifier();\n const authorizationUrl = new URL('/sdk/login', deps.widgetOrigin);\n authorizationUrl.search = new URLSearchParams({\n workKey: deps.workKey,\n channel,\n parentOrigin: window.location.origin,\n locale: resolveLocale(),\n }).toString();\n const workSessionToken = deps.session.snapshot?.token;\n if (!workSessionToken) throw malformedResponse();\n return embeddedFrame(\n authorizationUrl.toString(),\n deps.widgetOrigin,\n channel,\n 'auth',\n { workSessionToken },\n async (data) => {\n if (typeof data.userToken !== 'string') {\n throw malformedResponse();\n }\n deps.session.authenticate({ userToken: data.userToken, user: parseUser(data.user) });\n },\n );\n };\n\n const getFollowState = async (): Promise<FollowState> => {\n await deps.ready();\n return parseFollowState(\n (await deps.session.request({ method: 'GET', path: '/v1/public/work-sdk/follow' })).body,\n );\n };\n\n const updateFollow = async (): Promise<FollowState> => {\n await deps.ready();\n return parseFollowState(\n (await deps.session.request({ method: 'PUT', path: '/v1/public/work-sdk/follow' })).body,\n );\n };\n\n const signInPresentation = (): Pick<AccessInteraction, 'followTarget' | 'work'> => {\n const descriptor = deps.session.snapshot?.work;\n return {\n ...(descriptor?.creator\n ? {\n followTarget: {\n kind: 'CREATOR' as const,\n displayName: descriptor.creator.displayName,\n avatarUrl: descriptor.creator.avatarUrl,\n description: null,\n workCount: descriptor.creator.publishedWorkCount,\n },\n }\n : {}),\n ...(descriptor?.details ? { work: descriptor.details } : {}),\n };\n };\n\n const auth: AuthCapability = {\n async getState() {\n await deps.ready();\n const user = deps.session.snapshot?.user ?? null;\n return { authenticated: user !== null, user };\n },\n async signIn() {\n await deps.ready();\n const result = await present({\n featureKey: 'auth',\n reason: 'AUTH_REQUIRED',\n action: 'SIGN_IN',\n ...signInPresentation(),\n perform: startSignIn,\n });\n if (result === 'dismissed') throw cancelled();\n return this.getState();\n },\n async signOut() {\n await deps.ready();\n await deps.session.signOut();\n },\n };\n\n const follow: FollowCapability = {\n getState: getFollowState,\n follow: updateFollow,\n unfollow: async () => {\n throw new ViceMeError({\n code: 'CAPABILITY_DISABLED',\n message: 'Unfollow is not exposed by website access.',\n retryable: false,\n });\n },\n };\n\n const checkMany = async (featureKeys: string[]): Promise<Record<string, AccessDecision>> => {\n await deps.ready();\n const response = objectBody(\n (\n await deps.session.request({\n method: 'POST',\n path: '/v1/public/work-sdk/access/check',\n body: { featureKeys },\n })\n ).body,\n );\n const raw = objectBody(response.decisions);\n return Object.fromEntries(\n Object.entries(raw).map(([key, value]) => [key, parseDecision(value)]),\n );\n };\n\n const createCheckout = async (\n featureKey: string,\n options: Omit<CheckoutOptions, 'featureKey'> = {},\n ): Promise<CheckoutResult> => {\n await deps.ready();\n const body = {\n featureKey,\n locale: options.locale ?? 'zh-CN',\n };\n const response = objectBody(\n (\n await deps.session.request({\n method: 'POST',\n path: '/v1/public/work-sdk/checkout',\n body,\n })\n ).body,\n );\n if (\n typeof response.checkoutUrl !== 'string' ||\n typeof response.alreadyOwned !== 'boolean' ||\n !(\n response.expiresAt === null ||\n (typeof response.expiresAt === 'string' && !Number.isNaN(Date.parse(response.expiresAt)))\n ) ||\n response.alreadyOwned !== (response.expiresAt === null)\n ) {\n throw malformedResponse();\n }\n let checkoutUrl: URL;\n try {\n checkoutUrl = new URL(response.checkoutUrl);\n } catch {\n throw malformedResponse();\n }\n if (\n !response.alreadyOwned &&\n (checkoutUrl.protocol !== 'https:' || checkoutUrl.origin !== deps.widgetOrigin)\n ) {\n throw malformedResponse();\n }\n return {\n checkoutUrl: response.checkoutUrl,\n alreadyOwned: response.alreadyOwned,\n expiresAt: response.expiresAt,\n };\n };\n\n const openCheckout = (result: CheckoutResult, featureKey: string): AccessActionResult => {\n if (result.alreadyOwned) return { type: 'completed' };\n const expiresAt = Date.parse(result.expiresAt!);\n if (typeof window === 'undefined') {\n throw new ViceMeError({\n code: 'CONFIG_INVALID',\n message: 'Hosted checkout requires a browser window.',\n retryable: false,\n });\n }\n\n let active = true;\n let pollTimer: ReturnType<typeof setTimeout> | undefined;\n let expiryTimer: ReturnType<typeof setTimeout> | undefined;\n let settle!: () => void;\n let fail!: (error: unknown) => void;\n const completion = new Promise<void>((resolve, reject) => {\n settle = resolve;\n fail = reject;\n });\n const cleanup = () => {\n if (pollTimer) clearTimeout(pollTimer);\n if (expiryTimer) clearTimeout(expiryTimer);\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n };\n const expire = () => {\n if (!active) return;\n active = false;\n cleanup();\n fail(\n new ViceMeError({\n code: 'SESSION_EXPIRED',\n message: 'Hosted checkout session expired.',\n retryable: true,\n }),\n );\n };\n const schedule = () => {\n if (!active || document.visibilityState === 'hidden') return;\n const remaining = expiresAt - deps.now();\n if (remaining <= 0) {\n expire();\n return;\n }\n pollTimer = setTimeout(() => void poll(), Math.min(1_500, remaining));\n };\n const poll = async () => {\n if (!active) return;\n try {\n const decision = (await checkMany([featureKey]))[featureKey];\n if (!decision) throw malformedResponse();\n if (decision.allowed) {\n active = false;\n cleanup();\n settle();\n return;\n }\n schedule();\n } catch (error) {\n active = false;\n cleanup();\n fail(error);\n }\n };\n function handleVisibilityChange() {\n if (!active) return;\n if (document.visibilityState === 'hidden') {\n if (pollTimer) clearTimeout(pollTimer);\n pollTimer = undefined;\n return;\n }\n schedule();\n }\n document.addEventListener('visibilitychange', handleVisibilityChange);\n const remaining = expiresAt - deps.now();\n if (remaining <= 0) expire();\n else {\n expiryTimer = setTimeout(expire, remaining);\n schedule();\n }\n return {\n type: 'frame',\n url: result.checkoutUrl,\n completion,\n cancel() {\n if (!active) return;\n active = false;\n cleanup();\n settle();\n },\n };\n };\n\n const checkout: CheckoutCapability = {\n async open(options) {\n const checkoutResult = await createCheckout(options.featureKey, options);\n if (checkoutResult.alreadyOwned) return checkoutResult;\n const presented = await present({\n featureKey: options.featureKey,\n reason: 'PURCHASE_REQUIRED',\n action: 'CHECKOUT',\n perform: async () => openCheckout(checkoutResult, options.featureKey),\n });\n if (presented === 'dismissed') throw cancelled();\n return checkoutResult;\n },\n };\n\n const access: AccessCapability = {\n async getFeatures() {\n await deps.ready();\n const response = objectBody(\n (\n await deps.session.request({\n method: 'GET',\n path: '/v1/public/work-sdk/access/features',\n })\n ).body,\n );\n if (!Array.isArray(response.features) || response.features.length > 100) {\n throw malformedResponse();\n }\n return response.features.map(parseFeaturePresentation);\n },\n async check(featureKey) {\n const decisions = await checkMany([featureKey]);\n const decision = decisions[featureKey];\n if (!decision) throw malformedResponse();\n return decision;\n },\n checkMany,\n async require(featureKey) {\n let decision = await this.check(featureKey);\n for (\n let attempts = 0;\n !decision.allowed && decision.nextAction && attempts < 3;\n attempts += 1\n ) {\n const nextAction = decision.nextAction;\n const followTarget = nextAction === 'FOLLOW' ? (await follow.getState()).target : undefined;\n const checkoutResult =\n nextAction === 'CHECKOUT' ? await createCheckout(featureKey) : undefined;\n if (checkoutResult?.alreadyOwned) {\n decision = await this.check(featureKey);\n continue;\n }\n const result = await present({\n featureKey,\n reason: decision.reason,\n action: nextAction,\n ...(nextAction === 'SIGN_IN'\n ? signInPresentation()\n : followTarget\n ? { followTarget }\n : {}),\n perform: async () => {\n if (nextAction === 'SIGN_IN') {\n return startSignIn();\n } else if (nextAction === 'FOLLOW') {\n await follow.follow();\n return { type: 'completed' };\n } else {\n return openCheckout(checkoutResult!, featureKey);\n }\n },\n });\n if (result === 'dismissed') return decision;\n decision = await this.check(featureKey);\n }\n return decision;\n },\n async refresh() {\n await deps.ready();\n },\n };\n\n return { auth, follow, access, checkout };\n}\n","/**\n * ViceMe client for hosted capabilities and optional website access.\n *\n * `ready()` and access checks remain headless. Interactive authentication and\n * checkout touch `window` only when the caller explicitly invokes them. `ready()` is\n * Hosted capability initialization stays local and synchronous. Website\n * access establishes its Work session lazily on the first access operation.\n * `ready()` is idempotent per instance (shares one promise), `destroy()` is idempotent and\n * synchronously cancels requests and subscriptions; every business method on a\n * destroyed client fails with `CLIENT_DESTROYED`.\n */\n\nimport { clientDestroyed } from './errors.ts';\nimport { Lifecycle, type ViceMeClientState } from './lifecycle.ts';\nimport type { ViceMeConfig, ViceMeRegion } from './config.ts';\nimport { SessionManager } from '../session/session.ts';\nimport type { Transport } from '../transport/transport.ts';\nimport { API_MAJOR, SDK_VERSION } from '../version.ts';\nimport {\n createCapabilities,\n type AccessCapability,\n type AuthCapability,\n type CheckoutCapability,\n} from './capabilities.ts';\nimport type { AccessPresenter } from './presentation.ts';\nimport { BUILD_WIDGET_ORIGINS } from './build-endpoints.ts';\n\nexport interface ViceMeClient {\n readonly version: string;\n readonly workKey: string;\n readonly region: ViceMeRegion;\n readonly state: ViceMeClientState;\n readonly auth: AuthCapability;\n readonly access: AccessCapability;\n readonly checkout: CheckoutCapability;\n ready(): Promise<void>;\n hasCapability(name: string): boolean;\n destroy(): void;\n}\n\nexport interface ViceMeMountedInstance {\n readonly instanceKey: string;\n readonly capability: string;\n destroy(): void;\n}\n\n/** Internal loader hook; keeps degradation outside the public client contract. */\nexport function markClientDegraded(client: ViceMeClient): void {\n if (client instanceof ViceMeClientImpl) client.markDegraded();\n}\n\n/** Marker so in-flight requests cancelled by `destroy()` map to CLIENT_DESTROYED. */\nclass DestroySignalReason extends DOMException {\n constructor() {\n super('ViceMe client destroyed.', 'AbortError');\n }\n}\n\nexport interface ViceMeClientDeps {\n config: ViceMeConfig;\n transport: Transport;\n /** Interaction override for the testing entry only. */\n presenter?: AccessPresenter;\n /** Injectable clock (testing only). */\n now?: () => number;\n}\n\nexport class ViceMeClientImpl implements ViceMeClient {\n readonly #lifecycle = new Lifecycle();\n readonly #session: SessionManager;\n readonly #config: ViceMeConfig;\n readonly #internalSignal = new AbortController();\n #readyPromise: Promise<void> | undefined;\n readonly auth: AuthCapability;\n readonly access: AccessCapability;\n readonly checkout: CheckoutCapability;\n /** Detaches the caller-signal listener; undefined when none was attached. */\n #detachCallerAbort: (() => void) | undefined;\n\n constructor(deps: ViceMeClientDeps) {\n this.#config = deps.config;\n this.#session = new SessionManager({\n workKey: deps.config.workKey,\n transport: deps.transport,\n signal: this.#internalSignal.signal,\n ...(deps.now !== undefined ? { now: deps.now } : {}),\n });\n const capabilities = createCapabilities({\n session: this.#session,\n workKey: deps.config.workKey,\n widgetOrigin: BUILD_WIDGET_ORIGINS[deps.config.region],\n now: deps.now ?? (() => Date.now()),\n presenter: deps.presenter,\n signal: this.#internalSignal.signal,\n ready: () => this.#readyAccess(),\n });\n this.auth = capabilities.auth;\n this.access = capabilities.access;\n this.checkout = capabilities.checkout;\n const callerSignal = deps.config.signal;\n if (callerSignal) {\n // Propagate the caller's own abort reason when one was set.\n const abortInternal = () => {\n this.#internalSignal.abort(\n callerSignal.reason instanceof Error\n ? callerSignal.reason\n : new DOMException('Caller signal aborted.', 'AbortError'),\n );\n };\n // An already-aborted signal never fires the listener; check\n // synchronously so a pre-cancelled caller cannot issue session\n // requests or reach the network at all.\n if (callerSignal.aborted) abortInternal();\n else {\n callerSignal.addEventListener('abort', abortInternal, { once: true });\n this.#detachCallerAbort = () => {\n callerSignal.removeEventListener('abort', abortInternal);\n };\n }\n }\n }\n\n get version(): string {\n return SDK_VERSION;\n }\n\n get workKey(): string {\n return this.#config.workKey;\n }\n\n get region(): ViceMeRegion {\n return this.#config.region;\n }\n\n get state(): ViceMeClientState {\n return this.#lifecycle.state;\n }\n\n /** Internal: public API major, used by the loader registry namespace. */\n get apiMajor(): number {\n return API_MAJOR;\n }\n\n ready(): Promise<void> {\n if (this.#lifecycle.destroyed) return Promise.reject(clientDestroyed());\n if (!this.#readyPromise) {\n this.#lifecycle.transition('READY');\n this.#readyPromise = Promise.resolve();\n }\n return this.#readyPromise;\n }\n\n async #readyAccess(): Promise<void> {\n if (this.#lifecycle.destroyed) throw clientDestroyed();\n await this.ready();\n try {\n await this.#session.establish();\n if (this.#lifecycle.destroyed) throw clientDestroyed();\n } catch (error) {\n if (this.#lifecycle.destroyed) throw clientDestroyed();\n this.#session.invalidate();\n throw error;\n }\n }\n\n hasCapability(name: string): boolean {\n if (this.#lifecycle.destroyed) return false;\n const capabilities = this.#session.snapshot?.work.capabilities;\n return name === 'danmaku' || name === 'tip' || capabilities?.includes(name) === true;\n }\n\n /** Names of capabilities enabled for this work (empty before `ready()`). */\n get capabilities(): readonly string[] {\n return this.#session.snapshot?.work.capabilities ?? [];\n }\n\n /**\n * Internal: mark one capability unavailable without taking down the client\n * (loader uses this when a feature chunk fails after the core is READY).\n */\n markDegraded(): void {\n if (this.#lifecycle.state === 'READY') this.#lifecycle.transition('DEGRADED');\n }\n\n /** Internal: session snapshot access for capability modules. */\n get sessionSnapshot() {\n return this.#session.snapshot;\n }\n\n destroy(): void {\n if (this.#lifecycle.destroyed) return;\n this.#lifecycle.transition('DESTROYED');\n this.#internalSignal.abort(new DestroySignalReason());\n this.#session.destroy();\n this.#lifecycle.clearListeners();\n this.#readyPromise = undefined;\n // A destroyed client must not stay reachable through the caller's own\n // (possibly long-lived, never-aborting) signal.\n this.#detachCallerAbort?.();\n this.#detachCallerAbort = undefined;\n }\n}\n","/**\n * HTTP transport for the public API.\n *\n * Responsibilities: request execution with timeout, abort, client request ids,\n * and normalization of every failure into the public `ViceMeError` model.\n * Capabilities and the loader never build their own `fetch` calls — they go\n * through a Transport so tests can swap in `createMemoryTransport`.\n */\n\nimport { ViceMeError, type ViceMeErrorCode } from '../core/errors.ts';\n\nexport interface TransportRequest {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\n /** Absolute path under the public API base. */\n path: string;\n /** JSON-serializable request body. */\n body?: unknown;\n /** Work-session token. It is never persisted by the transport. */\n authorization?: string;\n /** Optional memory-only signed-in widget token. */\n userAuthorization?: string;\n signal?: AbortSignal;\n /** Per-request timeout; defaults to the transport default. */\n timeoutMs?: number;\n}\n\nexport interface TransportResponse {\n status: number;\n body?: unknown;\n /** Echoed server request id, when provided. */\n requestId?: string;\n}\n\nexport interface Transport {\n request(request: TransportRequest): Promise<TransportResponse>;\n}\n\nexport interface FetchTransportOptions {\n apiBaseUrl: string;\n /** Injectable for tests; defaults to global `fetch`. */\n fetchImpl?: typeof fetch;\n defaultTimeoutMs?: number;\n /** Injectable id generator (default: `crypto.randomUUID`). */\n generateRequestId?: () => string;\n}\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nconst STATUS_CODE_MAP: ReadonlyMap<number, ViceMeErrorCode> = new Map([\n [400, 'CONFIG_INVALID'],\n [401, 'SESSION_EXPIRED'],\n [403, 'CAPABILITY_DISABLED'],\n [404, 'WORK_NOT_FOUND'],\n [409, 'CONFIG_INVALID'],\n [422, 'CONFIG_INVALID'],\n [429, 'RATE_LIMITED'],\n]);\n\nconst KNOWN_CODES: ReadonlySet<string> = new Set([\n 'CONFIG_INVALID',\n 'WORK_NOT_FOUND',\n 'CAPABILITY_DISABLED',\n 'SESSION_EXPIRED',\n 'AUTH_REQUIRED',\n 'AUTH_CANCELLED',\n 'RETURN_URL_NOT_ALLOWED',\n 'RATE_LIMITED',\n 'NETWORK_TIMEOUT',\n 'CHECKOUT_UNAVAILABLE',\n 'INTERNAL_ERROR',\n]);\n\n/** Extract a stable error payload from a JSON error body, if well-formed. */\nfunction parseErrorBody(body: unknown): {\n code?: ViceMeErrorCode;\n message?: string;\n retryable?: boolean;\n requestId?: string;\n} {\n if (typeof body !== 'object' || body === null) return {};\n const raw = body as Record<string, unknown>;\n const candidate =\n typeof raw.error === 'object' && raw.error !== null\n ? (raw.error as Record<string, unknown>)\n : raw;\n const result: {\n code?: ViceMeErrorCode;\n message?: string;\n retryable?: boolean;\n requestId?: string;\n } = {};\n if (typeof candidate.code === 'string' && KNOWN_CODES.has(candidate.code)) {\n result.code = candidate.code as ViceMeErrorCode;\n }\n if (typeof candidate.message === 'string') {\n result.message = candidate.message.slice(0, 200);\n }\n if (typeof candidate.retryable === 'boolean') {\n result.retryable = candidate.retryable;\n }\n if (typeof candidate.requestId === 'string') {\n result.requestId = candidate.requestId;\n }\n return result;\n}\n\nfunction defaultRequestId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return `req-${Math.random().toString(36).slice(2)}`;\n}\n\nexport class FetchTransport implements Transport {\n readonly #apiBaseUrl: string;\n readonly #fetchImpl: typeof fetch;\n readonly #defaultTimeoutMs: number;\n readonly #generateRequestId: () => string;\n\n constructor(options: FetchTransportOptions) {\n this.#apiBaseUrl = options.apiBaseUrl.replace(/\\/+$/, '');\n this.#fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);\n this.#defaultTimeoutMs = options.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.#generateRequestId = options.generateRequestId ?? defaultRequestId;\n }\n\n async request(request: TransportRequest): Promise<TransportResponse> {\n // A pre-aborted signal must never reach the network. Preserve the\n // caller's abort reason when one was set.\n if (request.signal?.aborted) {\n throw this.#callerAbortError(request.signal);\n }\n const timeoutMs = request.timeoutMs ?? this.#defaultTimeoutMs;\n const controller = new AbortController();\n // Engine notes: Chrome/Firefox reject fetch with the abort reason and\n // WebKit may reject with a plain error — so timeout/abort classification\n // keys off our own timer/signal state, never off the exception shape.\n let timedOut = false;\n const timer = setTimeout(() => {\n timedOut = true;\n controller.abort(new TimeoutAbort());\n }, timeoutMs);\n const onOuterAbort = () => controller.abort(new TimeoutAbort(false));\n request.signal?.addEventListener('abort', onOuterAbort, { once: true });\n\n const requestId = this.#generateRequestId();\n try {\n const response = await this.#fetchImpl(`${this.#apiBaseUrl}${request.path}`, {\n method: request.method,\n // Public API is CORS-only; credentials must stay off so Shop session\n // cookies can never attach to public SDK requests.\n credentials: 'omit',\n mode: 'cors',\n headers: {\n 'content-type': 'application/json',\n 'x-client-request-id': requestId,\n ...(request.authorization !== undefined\n ? { authorization: `Bearer ${request.authorization}` }\n : {}),\n ...(request.userAuthorization !== undefined\n ? { 'x-viceme-user-token': request.userAuthorization }\n : {}),\n },\n body: request.body !== undefined ? JSON.stringify(request.body) : undefined,\n signal: controller.signal,\n });\n\n // Body reading stays inside the same timeout/abort lifecycle: a server\n // that returns headers and then stalls the body still hits\n // NETWORK_TIMEOUT, caller abort still cancels the read, and a late\n // body can never outlive a destroyed client/session.\n let body: unknown;\n try {\n body = await response.json();\n } catch (error) {\n // A malformed/empty body is tolerated; a cancelled read must\n // propagate so the outer handler can classify it.\n if (request.signal?.aborted || timedOut) {\n throw error;\n }\n body = undefined;\n }\n\n // A fulfilled body promise cannot be rejected by abort(). Recheck before\n // delivering it so cancellation between parsing and this continuation\n // cannot turn into a successful request or a cached Work session.\n if (controller.signal.aborted) throw controller.signal.reason;\n\n const serverRequestId = response.headers.get('x-request-id') ?? undefined;\n if (!response.ok) {\n const parsed = parseErrorBody(body);\n const code = parsed.code ?? STATUS_CODE_MAP.get(response.status) ?? 'INTERNAL_ERROR';\n throw new ViceMeError({\n code,\n message: parsed.message ?? 'Public API request failed.',\n retryable: parsed.retryable,\n requestId: parsed.requestId ?? serverRequestId,\n });\n }\n return { status: response.status, body, requestId: serverRequestId };\n } catch (cause) {\n if (request.signal?.aborted) {\n throw this.#callerAbortError(request.signal);\n }\n if (timedOut) {\n throw new ViceMeError({\n code: 'NETWORK_TIMEOUT',\n message: 'Public API request timed out.',\n retryable: true,\n requestId,\n });\n }\n // Non-OK statuses already carry a normalized error — pass it through.\n if (cause instanceof ViceMeError) {\n throw cause;\n }\n if (cause instanceof DOMException && cause.name === 'AbortError') {\n throw new DOMException('ViceMe request aborted by caller.', 'AbortError');\n }\n throw new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: 'Public API request failed.',\n retryable: true,\n requestId,\n });\n } finally {\n clearTimeout(timer);\n request.signal?.removeEventListener('abort', onOuterAbort);\n }\n }\n\n /** Caller-abort error that preserves the caller's own abort reason. */\n #callerAbortError(signal: AbortSignal): unknown {\n return signal.reason instanceof Error\n ? signal.reason\n : new DOMException('ViceMe request aborted by caller.', 'AbortError');\n }\n}\n\nexport function createFetchTransport(options: FetchTransportOptions): Transport {\n return new FetchTransport(options);\n}\n\n/** Internal marker distinguishing timeout aborts from caller aborts. */\nclass TimeoutAbort extends DOMException {\n constructor(timedOut = true) {\n super(timedOut ? 'ViceMe request timed out.' : 'ViceMe request aborted.', 'AbortError');\n }\n}\n","/**\n * `@viceme-ai/sdk` public entry.\n *\n * Production consumers get `createViceMe` plus public types. Test injection\n * lives under `@viceme-ai/sdk/testing`.\n */\n\nimport { createFetchTransport } from './transport/transport.ts';\nimport { resolveApiBaseUrl, validatePublicConfig } from './core/config.ts';\nimport { ViceMeClientImpl } from './core/client.ts';\nimport { ViceMeError, isViceMeError, type ViceMeErrorCode } from './core/errors.ts';\nimport type { ViceMeClient, ViceMeMountedInstance } from './core/client.ts';\nimport type { ViceMeRegion, ViceMeConfig } from './core/config.ts';\nimport type { ViceMeClientState } from './core/lifecycle.ts';\nimport type {\n AccessCapability,\n AccessDecision,\n AccessFeaturePresentation,\n AccessPolicyType,\n AccessReason,\n AuthCapability,\n AuthState,\n CheckoutCapability,\n CheckoutOptions,\n CheckoutResult,\n} from './core/capabilities.ts';\nimport type { WorkUser } from './session/session.ts';\nimport { SDK_VERSION, API_MAJOR } from './version.ts';\n\nexport { ViceMeError, isViceMeError, SDK_VERSION, API_MAJOR, resolveApiBaseUrl };\nexport type {\n ViceMeClient,\n ViceMeMountedInstance,\n ViceMeConfig,\n ViceMeRegion,\n ViceMeClientState,\n ViceMeErrorCode,\n AccessCapability,\n AccessDecision,\n AccessFeaturePresentation,\n AccessPolicyType,\n AccessReason,\n AuthCapability,\n AuthState,\n CheckoutCapability,\n CheckoutOptions,\n CheckoutResult,\n WorkUser,\n};\n\n/**\n * Create a ViceMe client for one Work. Hosted capabilities initialize locally;\n * website access establishes a short-lived Work session only when used.\n *\n * @example\n * ```ts\n * const client = createViceMe({ workKey: 'wrk_live_demo', region: 'cn' });\n * await client.ready();\n * client.destroy();\n * ```\n */\nexport function createViceMe(config: unknown): ViceMeClient {\n const validated = validatePublicConfig(config);\n const apiBaseUrl = resolveApiBaseUrl(validated.region);\n const transport = createFetchTransport({\n apiBaseUrl,\n });\n return new ViceMeClientImpl({ config: validated, transport });\n}\n","/**\n * CDN auto-loader (`viceme.min.js`, IIFE).\n *\n * Deterministic algorithm (fixed baseline):\n *\n * 1. Read `document.currentScript`; when unavailable, accept exactly one\n * explicit `script[data-viceme-loader]`.\n * 2. Parse and validate `data-viceme-*`; build `clientKey` and per-feature\n * `instanceKey`s.\n * 3. Wait for DOM ready; a missing/ambiguous target emits `CONFIG_INVALID`\n * and never creates phantom nodes.\n * 4. Read `manifest.json` from the loader's own directory (exact release\n * version; URLs are never assembled from page parameters).\n * 5. Create the local client embedded in this loader, then load the\n * requested same-version capability chunks declared by the manifest.\n * 6. Mount; handles land in an internal registry.\n * 7. Re-running the same instance key returns the original handle — no\n * duplicate clients, subscriptions, or DOM.\n * 8. A failing mount keeps the host page working and degrades only its client.\n * 9. `pagehide` never auto-destroys (bfcache); cleanup happens on explicit\n * `destroy()` only.\n *\n * The loader never writes localStorage, cookies, global CSS, or globals other\n * than the fixed `window.ViceMe.versions.vN` namespace.\n */\n\nimport { parseLoaderAttributes, type LoaderAttributes, type LoaderFeature } from './attributes.ts';\nimport { LoaderRegistry, clientKeyOf, type RegisteredInstance } from './registry.ts';\nimport type { CapabilityMountHandle, CapabilityMountFunction } from '../capability-mount.ts';\nimport { dispatchViceMeEvent, type VicemeErrorDetail } from '../browser-events.ts';\nimport { clientDestroyed, configInvalid, ViceMeError } from '../core/errors.ts';\nimport {\n markClientDegraded,\n type ViceMeClient,\n type ViceMeMountedInstance,\n} from '../core/client.ts';\nimport { createViceMe } from '../index.ts';\nimport { API_MAJOR, SDK_VERSION } from '../version.ts';\n\nexport interface ReleaseManifest {\n version: string;\n apiMajor: number;\n loader: string;\n features: Record<string, string>;\n}\n\nexport interface ViceMeLoaderNamespaceV1 {\n readonly version: string;\n whenReady(clientKey: string): Promise<ViceMeClient>;\n getInstance(instanceKey: string): ViceMeMountedInstance | undefined;\n destroyInstance(instanceKey: string): void;\n destroyClient(clientKey: string): void;\n}\n\nexport interface ViceMeBrowserGlobal {\n versions: {\n // Other majors coexist; they are never overwritten by this loader.\n [major: string]: ViceMeLoaderNamespaceV1 | undefined;\n };\n}\n\nconst MANIFEST_TIMEOUT_MS = 8_000;\nconst CAPABILITY_MOUNT_TIMEOUT_MS = 8_000;\nconst FEATURE_PATHS: Readonly<Record<LoaderFeature, string>> = {\n danmaku: 'danmaku.js',\n tip: 'tip.js',\n};\nconst MOUNT_EXPORTS: Readonly<Record<LoaderFeature, 'mountDanmaku' | 'mountTip'>> = {\n danmaku: 'mountDanmaku',\n tip: 'mountTip',\n};\n\ninterface LoaderSharedState {\n registry: LoaderRegistry;\n /** Serialized run queue shared across every execution of this loader. */\n queue: { current: Promise<void> };\n}\n\nconst STATE_KEY = Symbol.for('viceme.loader.state.v1');\n\n/**\n * Loader state must survive multiple executions of the same (or an identical)\n * loader `<script>`: browsers execute each script tag as an independent IIFE,\n * so the registry and run queue live on a hidden, symbol-keyed, non-enumerable\n * global — never an undeclared string-named global.\n */\nfunction sharedState(): LoaderSharedState {\n const holder = globalThis as Record<symbol, unknown>;\n const existing = holder[STATE_KEY] as LoaderSharedState | undefined;\n if (existing) return existing;\n const state: LoaderSharedState = {\n registry: new LoaderRegistry(),\n queue: { current: Promise.resolve() },\n };\n Object.defineProperty(globalThis, STATE_KEY, {\n value: state,\n writable: true,\n configurable: true,\n enumerable: false,\n });\n return state;\n}\n\n/* ------------------------------------------------------------------ */\n/* Instance wrapper + destroy */\n/* ------------------------------------------------------------------ */\n\nfunction destroyInstanceInternal(instance: RegisteredInstance): void {\n if (instance.destroyed) return;\n instance.destroyed = true;\n sharedState().registry.removeInstance(instance.instanceKey);\n try {\n instance.raw.destroy();\n } finally {\n dispatchViceMeEvent(instance.host, 'viceme:destroyed', {\n clientKey: instance.clientKey,\n instanceKey: instance.instanceKey,\n capability: instance.capability,\n });\n }\n}\n\nfunction wrapInstance(instance: RegisteredInstance): ViceMeMountedInstance {\n return {\n instanceKey: instance.instanceKey,\n capability: instance.capability,\n destroy: () => destroyInstanceInternal(instance),\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Namespace installation */\n/* ------------------------------------------------------------------ */\n\nfunction defineHidden(target: object, key: string, value: unknown): void {\n Object.defineProperty(target, key, {\n value,\n writable: true,\n configurable: true,\n enumerable: false,\n });\n}\n\nexport function ensureNamespace(version: string): ViceMeLoaderNamespaceV1 {\n const holder = globalThis as { ViceMe?: ViceMeBrowserGlobal };\n let global = holder.ViceMe;\n if (!global) {\n global = {} as ViceMeBrowserGlobal;\n defineHidden(globalThis, 'ViceMe', global);\n }\n let versions = global.versions;\n if (!versions) {\n versions = {} as ViceMeBrowserGlobal['versions'];\n defineHidden(global, 'versions', versions);\n }\n const existing = versions[`v${API_MAJOR}`];\n if (existing) return existing;\n\n const namespace: ViceMeLoaderNamespaceV1 = {\n version,\n whenReady(clientKey: string): Promise<ViceMeClient> {\n const entry = sharedState().registry.getClient(clientKey);\n if (!entry) {\n return Promise.reject(configInvalid(`Unknown clientKey \"${clientKey}\".`));\n }\n return entry.ready.then(() => entry.client);\n },\n getInstance(instanceKey: string): ViceMeMountedInstance | undefined {\n const instance = sharedState().registry.getInstance(instanceKey);\n return instance ? wrapInstance(instance) : undefined;\n },\n destroyInstance(instanceKey: string): void {\n const instance = sharedState().registry.getInstance(instanceKey);\n if (instance) destroyInstanceInternal(instance);\n },\n destroyClient(clientKey: string): void {\n for (const instance of sharedState().registry.instancesForClient(clientKey)) {\n destroyInstanceInternal(instance);\n }\n const entry = sharedState().registry.getClient(clientKey);\n for (const controller of entry?.pendingMounts ?? []) controller.abort();\n sharedState().registry.unregisterClient(clientKey);\n entry?.client.destroy();\n },\n };\n defineHidden(versions, `v${API_MAJOR}`, namespace);\n return namespace;\n}\n\n/* ------------------------------------------------------------------ */\n/* Loader algorithm */\n/* ------------------------------------------------------------------ */\n\nfunction whenDomReady(): Promise<void> {\n if (document.readyState !== 'loading') return Promise.resolve();\n return new Promise((resolve) => {\n document.addEventListener('DOMContentLoaded', () => resolve(), { once: true });\n });\n}\n\nasync function fetchReleaseManifest(\n manifestUrl: URL,\n): Promise<{ manifest: ReleaseManifest; baseUrl: URL }> {\n // Bound both headers and JSON-body parsing on every supported browser.\n // `AbortSignal.timeout()` is absent in older engines; without this manual\n // controller, one stalled manifest blocks the serialized loader queue.\n const controller = new AbortController();\n const timeout = globalThis.setTimeout(() => controller.abort(), MANIFEST_TIMEOUT_MS);\n try {\n let response: Response;\n try {\n response = await fetch(manifestUrl, {\n credentials: 'omit',\n signal: controller.signal,\n });\n } catch {\n if (controller.signal.aborted) {\n throw new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: 'Release manifest request timed out.',\n retryable: true,\n });\n }\n response = { ok: false, status: 0 } as Response;\n }\n return { manifest: await parseManifest(response), baseUrl: manifestUrl };\n } finally {\n globalThis.clearTimeout(timeout);\n }\n}\n\nasync function parseManifest(response: Response): Promise<ReleaseManifest> {\n if (!response.ok) {\n throw configInvalid(`Release manifest is not available (HTTP ${response.status}).`);\n }\n const body: unknown = await response.json();\n if (\n typeof body !== 'object' ||\n body === null ||\n typeof (body as ReleaseManifest).version !== 'string' ||\n typeof (body as ReleaseManifest).apiMajor !== 'number' ||\n typeof (body as ReleaseManifest).features !== 'object' ||\n (body as ReleaseManifest).features === null\n ) {\n throw configInvalid('Release manifest is malformed.');\n }\n const manifest = body as ReleaseManifest;\n if (manifest.version !== SDK_VERSION) {\n throw configInvalid('Release manifest version does not match this loader.');\n }\n if (manifest.apiMajor !== API_MAJOR) {\n throw configInvalid('Release manifest major version does not match this loader.');\n }\n const featureNames = Object.keys(manifest.features).sort();\n if (\n featureNames.length !== 2 ||\n featureNames[0] !== 'danmaku' ||\n featureNames[1] !== 'tip' ||\n manifest.features.danmaku !== FEATURE_PATHS.danmaku ||\n manifest.features.tip !== FEATURE_PATHS.tip\n ) {\n throw configInvalid('Release manifest features must be exactly danmaku.js and tip.js.');\n }\n return manifest;\n}\n\nconst KNOWN_ERROR_CODES: ReadonlySet<string> = new Set([\n 'CONFIG_INVALID',\n 'CAPABILITY_DISABLED',\n 'CLIENT_DESTROYED',\n 'INTERNAL_ERROR',\n]);\n\n/**\n * Normalize any thrown value into an event detail. Uses structural checks,\n * not `instanceof`: the loader IIFE and the core ESM chunk are separate\n * builds, so their `ViceMeError` classes are distinct at runtime.\n */\nfunction toErrorDetail(error: unknown): VicemeErrorDetail {\n if (typeof error === 'object' && error !== null) {\n const candidate = error as Record<string, unknown>;\n if (\n typeof candidate.code === 'string' &&\n KNOWN_ERROR_CODES.has(candidate.code) &&\n typeof candidate.retryable === 'boolean'\n ) {\n const detail: VicemeErrorDetail = {\n code: candidate.code as VicemeErrorDetail['code'],\n retryable: candidate.retryable,\n };\n if (typeof candidate.requestId === 'string') detail.requestId = candidate.requestId;\n if (typeof candidate.capability === 'string') detail.capability = candidate.capability;\n return detail;\n }\n }\n return { code: 'INTERNAL_ERROR', retryable: true };\n}\n\nfunction emitError(\n target: EventTarget,\n error: unknown,\n extra: Partial<Pick<VicemeErrorDetail, 'clientKey' | 'instanceKey' | 'capability'>> = {},\n): void {\n dispatchViceMeEvent(target, 'viceme:error', { ...toErrorDetail(error), ...extra });\n}\n\nfunction withCapabilityDeadline<T>(\n operation: Promise<T>,\n controller: AbortController,\n capability: LoaderFeature,\n): Promise<T> {\n let timeout: ReturnType<typeof globalThis.setTimeout> | undefined;\n let onAbort: (() => void) | undefined;\n const cancellation = new Promise<never>((_resolve, reject) => {\n onAbort = () => reject(clientDestroyed());\n if (controller.signal.aborted) {\n onAbort();\n return;\n }\n controller.signal.addEventListener('abort', onAbort, { once: true });\n timeout = globalThis.setTimeout(() => {\n reject(\n new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: `Capability \"${capability}\" did not load and mount in time.`,\n retryable: true,\n capability,\n }),\n );\n controller.abort();\n }, CAPABILITY_MOUNT_TIMEOUT_MS);\n });\n return Promise.race([operation, cancellation]).finally(() => {\n if (timeout !== undefined) globalThis.clearTimeout(timeout);\n if (onAbort) controller.signal.removeEventListener('abort', onAbort);\n });\n}\n\nexport async function runAutoLoader(script: HTMLScriptElement): Promise<void> {\n let attributes: LoaderAttributes;\n try {\n attributes = parseLoaderAttributes(script);\n } catch (error) {\n // Configuration errors before any host exists go to `document`.\n emitError(document, error);\n return;\n }\n\n if (!script.src) {\n emitError(document, configInvalid('Loader script requires a src URL.'));\n return;\n }\n const manifestUrl = new URL('manifest.json', script.src);\n\n let manifest: ReleaseManifest;\n let releaseBase: URL;\n try {\n ({ manifest, baseUrl: releaseBase } = await fetchReleaseManifest(manifestUrl));\n } catch (error) {\n emitError(document, error, {\n clientKey: clientKeyOf(API_MAJOR, attributes.region, attributes.workKey),\n });\n return;\n }\n\n await whenDomReady();\n\n let host: Element;\n try {\n const matches = document.querySelectorAll(attributes.target!);\n if (matches.length === 0) {\n throw configInvalid(\n `Loader target \"${attributes.target}\" matched no element; no node was created.`,\n );\n }\n if (matches.length > 1) {\n throw configInvalid(\n `Loader target \"${attributes.target}\" matched ${matches.length} elements; exactly one is required.`,\n );\n }\n host = matches[0]!;\n } catch (error) {\n emitError(document, error, {\n clientKey: clientKeyOf(manifest.apiMajor, attributes.region, attributes.workKey),\n });\n return;\n }\n\n const clientKey = clientKeyOf(manifest.apiMajor, attributes.region, attributes.workKey);\n ensureNamespace(manifest.version);\n\n // Shared core client per (major, region, workKey).\n let entry = sharedState().registry.getClient(clientKey);\n let client: ViceMeClient;\n if (entry) {\n client = entry.client;\n } else {\n try {\n client = createViceMe({\n workKey: attributes.workKey,\n region: attributes.region,\n });\n } catch (error) {\n emitError(host, error, { clientKey });\n return;\n }\n const ready = client.ready();\n // Keep an unhandled-rejection-free copy on the registry entry; failures\n // are reported through this loader run and via whenReady().\n void ready.catch(() => {});\n entry = { clientKey, client, ready, pendingMounts: new Set() };\n sharedState().registry.registerClient(entry);\n }\n\n try {\n await entry.ready;\n } catch (error) {\n sharedState().registry.unregisterClient(clientKey);\n client.destroy();\n emitError(host, error, { clientKey });\n return;\n }\n if (sharedState().registry.getClient(clientKey) !== entry) return;\n\n const mountCapability = async (capability: LoaderFeature): Promise<LoaderFeature | undefined> => {\n // Same client + capability + element: reuse the original handle.\n if (sharedState().registry.findInstance(clientKey, capability, host)) return undefined;\n\n const fileName = manifest.features[capability];\n if (typeof fileName !== 'string') {\n markClientDegraded(client);\n emitError(\n host,\n new ViceMeError({\n code: 'CAPABILITY_DISABLED',\n message: `Capability \"${capability}\" is not part of this release.`,\n retryable: false,\n capability,\n }),\n { clientKey, capability },\n );\n return undefined;\n }\n\n const controller = new AbortController();\n entry.pendingMounts.add(controller);\n try {\n const operation = (async (): Promise<CapabilityMountHandle> => {\n const chunkUrl = new URL(fileName, releaseBase);\n const module = (await import(/* @vite-ignore */ chunkUrl.href)) as Record<string, unknown>;\n const exportName = MOUNT_EXPORTS[capability];\n const mount = module[exportName];\n if (typeof mount !== 'function') {\n throw configInvalid(`Capability chunk \"${capability}\" does not export ${exportName}().`);\n }\n if (sharedState().registry.getClient(clientKey) !== entry) throw clientDestroyed();\n return (await (mount as CapabilityMountFunction)(client, {\n target: host,\n theme: attributes.theme,\n signal: controller.signal,\n ...(capability === 'tip' && attributes.features.includes('danmaku')\n ? { presentation: 'integrated' as const }\n : {}),\n })) as CapabilityMountHandle;\n })();\n const raw = await withCapabilityDeadline(operation, controller, capability);\n if (sharedState().registry.getClient(clientKey) !== entry) {\n raw.destroy();\n return undefined;\n }\n const instance = sharedState().registry.registerInstance(clientKey, capability, host, raw);\n dispatchViceMeEvent(host, 'viceme:capability-ready', {\n clientKey,\n instanceKey: instance.instanceKey,\n capability,\n version: manifest.version,\n });\n return capability;\n } catch (error) {\n if (sharedState().registry.getClient(clientKey) !== entry) return undefined;\n // Only this capability's partial state is discarded; everything else\n // (including the host page) keeps working.\n markClientDegraded(client);\n emitError(host, error, { clientKey, capability });\n return undefined;\n } finally {\n entry.pendingMounts.delete(controller);\n }\n };\n\n const mounted = (await Promise.all(attributes.features.map(mountCapability))).filter(\n (capability): capability is LoaderFeature => capability !== undefined,\n );\n\n if (mounted.length > 0 && sharedState().registry.getClient(clientKey) === entry) {\n dispatchViceMeEvent(host, 'viceme:ready', {\n clientKey,\n workKey: attributes.workKey,\n capabilities: mounted,\n version: manifest.version,\n });\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* IIFE bootstrap */\n/* ------------------------------------------------------------------ */\n\n/**\n * Loader runs are serialized so identical scripts (duplicate tags, re-runs,\n * same work with different targets) observe registry state deterministically\n * and never create duplicate clients or DOM.\n */\nfunction enqueueRun(script: HTMLScriptElement): Promise<void> {\n const { queue } = sharedState();\n const run = queue.current.then(() => runAutoLoader(script));\n queue.current = run.catch(() => {});\n return run;\n}\n\nfunction bootstrap(): void {\n if (typeof document === 'undefined') return;\n let script: HTMLScriptElement | null =\n document.currentScript instanceof HTMLScriptElement ? document.currentScript : null;\n if (!script) {\n const explicit = document.querySelectorAll<HTMLScriptElement>('script[data-viceme-loader]');\n if (explicit.length === 1) script = explicit[0] ?? null;\n }\n if (!script) return;\n void enqueueRun(script).catch((error: unknown) => {\n emitError(document, error);\n });\n}\n\nbootstrap();\n\n// Test-only handle for re-running the bootstrap in controlled environments.\nexport const __bootstrapForTests = bootstrap;\nexport type { RegisteredInstance };\n"],"names":["RETRYABLE_BY_DEFAULT","ViceMeError","init","json","isViceMeError","value","configInvalid","message","clientDestroyed","BUILD_API_BASE_URLS","BUILD_WIDGET_ORIGINS","REGIONS","PUBLIC_API_BASE_URLS","resolveApiBaseUrl","region","isValidWorkKey","isValidRegion","validatePublicConfig","input","raw","known","key","KNOWN_ATTRIBUTES","THEMES","FEATURE_ORDER","parseLoaderAttributes","element","name","workKey","rawFeatures","declaredFeatures","featureSet","feature","features","target","rawTheme","clientKeyOf","majorVersion","LoaderRegistry","#clients","#instances","#elements","#elementCounter","clientKey","entry","instanceKey","capability","compositeKey","byElement","existing","instance","i","ALLOWED_KEYS","sanitizeDetail","type","detail","paid","allowed","result","dispatchViceMeEvent","event","ALLOWED_TRANSITIONS","Lifecycle","#state","#listeners","next","listener","parseSessionResponse","body","malformedSessionResponse","c","snapshot","creator","record","work","nullableUrl","expiresAt","sessionInvalidated","SessionManager","#options","#now","#snapshot","#pending","#generation","#destroyed","options","#isExpired","generation","pending","response","#assertCurrent","request","#requestWithSnapshot","error","refreshed","#assertAlive","SDK_VERSION","API_MAJOR","ELEMENT_NAME","PROFILE_DESCRIPTION_LIMIT","actionCopy","action","actionErrorCopy","ensureAccessLayerElement","ViceMeAccessLayerElement","copy","shadow","panel","description","mainActions","closeAction","backdrop","frame","profile","avatar","avatarFallback","profileName","profileDescription","profileStats","workCover","workTitle","workSummary","idleActionLabel","descriptionCharacters","workDetails","activeAction","closed","close","dismissLayer","available","currentIndex","direction","performAction","caught","defaultAccessPresenter","interaction","previousOverflow","previousFocus","resolve","objectBody","malformedResponse","parseUser","parseFollowState","parseDecision","reasons","actions","parseFeaturePresentation","price","randomVerifier","bytes","base64Url","binary","byte","resolveLocale","createCapabilities","deps","cancelled","present","onAbort","cancellation","_resolve","reject","presentation","embeddedFrame","url","completionOrigin","channel","initialization","complete","active","settle","fail","cleanup","receive","completion","data","startSignIn","authorizationUrl","workSessionToken","getFollowState","updateFollow","signInPresentation","descriptor","auth","user","follow","checkMany","featureKeys","createCheckout","featureKey","checkoutUrl","openCheckout","pollTimer","expiryTimer","handleVisibilityChange","expire","schedule","remaining","poll","decision","attempts","nextAction","followTarget","checkoutResult","markClientDegraded","client","ViceMeClientImpl","DestroySignalReason","#lifecycle","#session","#config","#internalSignal","#readyPromise","#detachCallerAbort","capabilities","#readyAccess","callerSignal","abortInternal","DEFAULT_TIMEOUT_MS","STATUS_CODE_MAP","KNOWN_CODES","parseErrorBody","candidate","defaultRequestId","FetchTransport","#apiBaseUrl","#fetchImpl","#defaultTimeoutMs","#generateRequestId","#callerAbortError","timeoutMs","controller","timedOut","timer","TimeoutAbort","onOuterAbort","requestId","serverRequestId","parsed","code","cause","signal","createFetchTransport","createViceMe","config","validated","apiBaseUrl","transport","MANIFEST_TIMEOUT_MS","CAPABILITY_MOUNT_TIMEOUT_MS","FEATURE_PATHS","MOUNT_EXPORTS","STATE_KEY","sharedState","state","destroyInstanceInternal","wrapInstance","defineHidden","ensureNamespace","version","global","versions","namespace","whenDomReady","fetchReleaseManifest","manifestUrl","timeout","parseManifest","manifest","featureNames","KNOWN_ERROR_CODES","toErrorDetail","emitError","extra","withCapabilityDeadline","operation","runAutoLoader","script","attributes","releaseBase","host","matches","ready","mountCapability","fileName","module","exportName","mount","mounted","enqueueRun","queue","run","bootstrap","explicit","__bootstrapForTests"],"mappings":"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"}
1
+ {"version":3,"file":"viceme.min.js","sources":["../src/core/errors.ts","../src/core/build-endpoints.ts","../src/core/config.ts","../src/loader/attributes.ts","../src/loader/registry.ts","../src/browser-events.ts","../src/core/lifecycle.ts","../src/session/session.ts","../src/version.ts","../src/core/presentation.ts","../src/core/access-bridge.ts","../src/core/capabilities.ts","../src/core/client.ts","../src/transport/transport.ts","../src/index.ts","../src/loader/auto-loader.ts"],"sourcesContent":["/**\n * Public error model.\n *\n * Consumers branch on the stable `code` only — never on `message` text.\n * Error payloads must never contain provider responses, tokens, cookies, or\n * internal stack traces; `toJSON()` exposes the safe diagnostic subset.\n */\n\nexport type ViceMeErrorCode =\n | 'CONFIG_INVALID'\n | 'WORK_NOT_FOUND'\n | 'CAPABILITY_DISABLED'\n | 'CLIENT_DESTROYED'\n | 'SESSION_EXPIRED'\n | 'AUTH_REQUIRED'\n | 'AUTH_CANCELLED'\n | 'RETURN_URL_NOT_ALLOWED'\n | 'RATE_LIMITED'\n | 'NETWORK_TIMEOUT'\n | 'CHECKOUT_UNAVAILABLE'\n | 'INTERNAL_ERROR'\n | 'TIP_CONFIG_CREDENTIALS_NOT_ALLOWED'\n | 'TIP_CONFIG_INVALID'\n | 'TIP_OPEN_IN_PROGRESS'\n | 'TIP_READY_TIMEOUT';\n\nexport interface ViceMeErrorInit {\n code: ViceMeErrorCode;\n message: string;\n retryable?: boolean;\n /** Server-assigned request id echoed back for support correlation. */\n requestId?: string;\n /** Capability the error belongs to, when scoped to one. */\n capability?: string;\n}\n\nconst RETRYABLE_BY_DEFAULT: ReadonlySet<ViceMeErrorCode> = new Set([\n 'RATE_LIMITED',\n 'NETWORK_TIMEOUT',\n 'CHECKOUT_UNAVAILABLE',\n 'INTERNAL_ERROR',\n]);\n\nexport class ViceMeError extends Error {\n readonly code: ViceMeErrorCode;\n readonly retryable: boolean;\n readonly requestId?: string;\n readonly capability?: string;\n\n constructor(init: ViceMeErrorInit) {\n super(init.message);\n this.name = 'ViceMeError';\n this.code = init.code;\n this.retryable = init.retryable ?? RETRYABLE_BY_DEFAULT.has(init.code);\n this.requestId = init.requestId;\n this.capability = init.capability;\n }\n\n /** Safe, stable-shape serialization for logs and `viceme:error` events. */\n toJSON(): {\n code: ViceMeErrorCode;\n retryable: boolean;\n requestId?: string;\n capability?: string;\n } {\n const json: {\n code: ViceMeErrorCode;\n retryable: boolean;\n requestId?: string;\n capability?: string;\n } = { code: this.code, retryable: this.retryable };\n if (this.requestId !== undefined) json.requestId = this.requestId;\n if (this.capability !== undefined) json.capability = this.capability;\n return json;\n }\n}\n\nexport function isViceMeError(value: unknown): value is ViceMeError {\n return value instanceof ViceMeError;\n}\n\n/** Build a CONFIG_INVALID error with a stable, non-sensitive message. */\nexport function configInvalid(message: string): ViceMeError {\n return new ViceMeError({ code: 'CONFIG_INVALID', message, retryable: false });\n}\n\n/** Build a CLIENT_DESTROYED error for post-destroy calls. */\nexport function clientDestroyed(): ViceMeError {\n return new ViceMeError({\n code: 'CLIENT_DESTROYED',\n message: 'ViceMe client has been destroyed.',\n retryable: false,\n });\n}\n","declare const __VICEME_BUILD_CN_API_BASE_URL__: string | undefined;\ndeclare const __VICEME_BUILD_GLOBAL_API_BASE_URL__: string | undefined;\ndeclare const __VICEME_BUILD_CN_WIDGET_ORIGIN__: string | undefined;\ndeclare const __VICEME_BUILD_GLOBAL_WIDGET_ORIGIN__: string | undefined;\n\n/** Public Shop API origins baked into immutable release artifacts. */\nexport const BUILD_API_BASE_URLS = {\n cn:\n typeof __VICEME_BUILD_CN_API_BASE_URL__ === 'string'\n ? __VICEME_BUILD_CN_API_BASE_URL__\n : 'https://api.viceme.cn',\n global:\n typeof __VICEME_BUILD_GLOBAL_API_BASE_URL__ === 'string'\n ? __VICEME_BUILD_GLOBAL_API_BASE_URL__\n : 'https://api.viceme.ai',\n} as const;\n\n/** Hosted Shop origins baked into immutable release artifacts. */\nexport const BUILD_WIDGET_ORIGINS = {\n cn:\n typeof __VICEME_BUILD_CN_WIDGET_ORIGIN__ === 'string'\n ? __VICEME_BUILD_CN_WIDGET_ORIGIN__\n : 'https://viceme.cn',\n global:\n typeof __VICEME_BUILD_GLOBAL_WIDGET_ORIGIN__ === 'string'\n ? __VICEME_BUILD_GLOBAL_WIDGET_ORIGIN__\n : 'https://viceme.ai',\n} as const;\n","/**\n * Public client configuration.\n *\n * Production `createViceMe()` accepts exactly `workKey`, `region`, and\n * `signal`. Anything else (transport, clock, request ids, base URLs) is a\n * testing-only concern and lives in `@viceme-ai/sdk/testing`, so Agents can\n * never bake temporary or internal endpoints into user projects.\n */\n\nimport { configInvalid } from './errors.ts';\nimport { BUILD_API_BASE_URLS } from './build-endpoints.ts';\nexport type ViceMeRegion = 'cn' | 'global';\n\nexport interface ViceMeConfig {\n /** Public opaque test or live Work key. It is not a secret. */\n workKey: string;\n /** Routes public API and CDN traffic. */\n region: ViceMeRegion;\n /** Optional abort signal owned by the host page. */\n signal?: AbortSignal;\n}\n\nconst REGIONS: ReadonlySet<string> = new Set(['cn', 'global']);\n\n/**\n * Public API origins per region. These are the only production endpoints the\n * SDK may contact; B1 confirms final hostnames and any change happens here in\n * one place (never via a public `apiBaseUrl` option).\n */\nexport const PUBLIC_API_BASE_URLS: Readonly<Record<ViceMeRegion, string>> = {\n cn: BUILD_API_BASE_URLS.cn,\n global: BUILD_API_BASE_URLS.global,\n};\n\nexport function resolveApiBaseUrl(region: ViceMeRegion): string {\n return PUBLIC_API_BASE_URLS[region];\n}\n\nexport function isValidWorkKey(value: unknown): value is string {\n return typeof value === 'string' && /^wrk_(?:test|live)_[A-Za-z0-9_-]{4,119}$/.test(value);\n}\n\nexport function isValidRegion(value: unknown): value is ViceMeRegion {\n return typeof value === 'string' && REGIONS.has(value);\n}\n\n/**\n * Validate unknown input as a public client config. Throws a CONFIG_INVALID\n * ViceMeError that never echoes values back beyond the offending field name.\n */\nexport function validatePublicConfig(input: unknown): ViceMeConfig {\n if (typeof input !== 'object' || input === null) {\n throw configInvalid('createViceMe expects a configuration object.');\n }\n const raw = input as Record<string, unknown>;\n\n const known = new Set(['workKey', 'region', 'signal']);\n for (const key of Object.keys(raw)) {\n if (!known.has(key)) {\n throw configInvalid(`Unknown configuration field \"${key}\".`);\n }\n }\n if (!isValidWorkKey(raw.workKey)) {\n throw configInvalid(\n 'Configuration field \"workKey\" must start with \"wrk_test_\" or \"wrk_live_\".',\n );\n }\n if (!isValidRegion(raw.region)) {\n throw configInvalid('Configuration field \"region\" must be \"cn\" or \"global\".');\n }\n if (raw.signal !== undefined && !(raw.signal instanceof AbortSignal)) {\n throw configInvalid('Configuration field \"signal\" must be an AbortSignal.');\n }\n return {\n workKey: raw.workKey,\n region: raw.region,\n signal: raw.signal,\n };\n}\n","/**\n * `data-viceme-*` attribute parsing for the CDN auto-loader.\n *\n * The attribute set is fixed; unknown `data-viceme-*` attributes are rejected\n * so pages can never smuggle endpoints, tokens, secrets, prices, or payment\n * state through the loader. Parse failures never guess defaults for work,\n * region, or target.\n */\n\nimport { configInvalid } from '../core/errors.ts';\nimport type { ViceMeRegion } from '../core/config.ts';\nimport { isValidRegion, isValidWorkKey } from '../core/config.ts';\n\nexport type ViceMeTheme = 'light' | 'dark' | 'auto';\nexport type LoaderFeature = 'danmaku' | 'tip';\n\nexport interface LoaderAttributes {\n workKey: string;\n region: ViceMeRegion;\n /** Hosted capabilities mounted by this loader invocation. */\n features: LoaderFeature[];\n /** CSS selector; required whenever features are declared. */\n target?: string;\n theme: ViceMeTheme;\n}\n\nconst KNOWN_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'data-viceme-work',\n 'data-viceme-region',\n 'data-viceme-features',\n 'data-viceme-target',\n 'data-viceme-theme',\n // Marker for explicit opt-in when document.currentScript is unavailable.\n 'data-viceme-loader',\n]);\n\nconst THEMES: ReadonlySet<string> = new Set(['light', 'dark', 'auto']);\nconst FEATURE_ORDER: readonly LoaderFeature[] = ['danmaku', 'tip'];\n\nexport function parseLoaderAttributes(element: Element): LoaderAttributes {\n for (const name of element.getAttributeNames()) {\n if (name.startsWith('data-viceme-') && !KNOWN_ATTRIBUTES.has(name)) {\n throw configInvalid(`Unknown loader attribute \"${name}\".`);\n }\n }\n\n const workKey = element.getAttribute('data-viceme-work');\n if (!isValidWorkKey(workKey)) {\n throw configInvalid('Loader attribute \"data-viceme-work\" must be a public Work key.');\n }\n\n const region = element.getAttribute('data-viceme-region');\n if (!isValidRegion(region)) {\n throw configInvalid('Loader attribute \"data-viceme-region\" must be \"cn\" or \"global\".');\n }\n\n const rawFeatures = element.getAttribute('data-viceme-features');\n const declaredFeatures = rawFeatures?.split(',') ?? [];\n const featureSet = new Set(declaredFeatures);\n if (\n !rawFeatures ||\n /\\s/.test(rawFeatures) ||\n declaredFeatures.length !== featureSet.size ||\n declaredFeatures.some(\n (feature): feature is string => !FEATURE_ORDER.includes(feature as LoaderFeature),\n )\n ) {\n throw configInvalid(\n 'Loader attribute \"data-viceme-features\" must contain each of \"danmaku\" and \"tip\" at most once.',\n );\n }\n const features = FEATURE_ORDER.filter((feature) => featureSet.has(feature));\n\n const target = element.getAttribute('data-viceme-target');\n if (target === '') {\n throw configInvalid('Loader attribute \"data-viceme-target\" must be a CSS selector.');\n }\n // Loader-mounted features are visual capabilities, so a target is required.\n if (target === null) {\n throw configInvalid(\n 'Loader attribute \"data-viceme-target\" is required when features are declared.',\n );\n }\n try {\n // Probe-parse the selector now: an invalid selector is a configuration\n // error and must fail closed here, never surface later as a retryable\n // INTERNAL_ERROR from querySelectorAll.\n element.matches(target);\n } catch {\n throw configInvalid('Loader attribute \"data-viceme-target\" is not a valid CSS selector.');\n }\n\n const rawTheme = element.getAttribute('data-viceme-theme');\n if (rawTheme !== null && !THEMES.has(rawTheme)) {\n throw configInvalid('Loader attribute \"data-viceme-theme\" must be \"light\", \"dark\", or \"auto\".');\n }\n\n return {\n workKey,\n region,\n features,\n target,\n theme: (rawTheme ?? 'auto') as ViceMeTheme,\n };\n}\n","/**\n * Loader registry.\n *\n * Only the CDN loader maintains this registry (explicit `createViceMe()`\n * instances never register). Local clients are shared by\n * `major + region + workKey`; danmaku mounts are deduplicated by\n * `clientKey + capability + target Element identity`.\n *\n * The registry itself is never exposed on `window` — only the fixed\n * `ViceMe.versions.v1` diagnostics/destroy namespace is. It stores raw\n * capability handles; the loader wraps them into the public\n * `ViceMeMountedInstance` and owns destroy/event deduplication.\n */\n\nimport type { ViceMeClient } from '../core/client.ts';\nimport type { CapabilityMountHandle } from '../capability-mount.ts';\n\nexport interface RegisteredClient {\n clientKey: string;\n client: ViceMeClient;\n ready: Promise<void>;\n pendingMounts: Set<AbortController>;\n}\n\nexport interface RegisteredInstance {\n instanceKey: string;\n clientKey: string;\n capability: string;\n host: Element;\n raw: CapabilityMountHandle;\n destroyed: boolean;\n}\n\nexport function clientKeyOf(majorVersion: number, region: string, workKey: string): string {\n return `v${majorVersion}+${region}+${workKey}`;\n}\n\nexport class LoaderRegistry {\n readonly #clients = new Map<string, RegisteredClient>();\n readonly #instances = new Map<string, RegisteredInstance>();\n /** (clientKey, capability) -> mounted host element -> instance. */\n readonly #elements = new Map<string, WeakMap<Element, RegisteredInstance>>();\n #elementCounter = 0;\n\n getClient(clientKey: string): RegisteredClient | undefined {\n return this.#clients.get(clientKey);\n }\n\n registerClient(entry: RegisteredClient): void {\n this.#clients.set(entry.clientKey, entry);\n }\n\n unregisterClient(clientKey: string): void {\n this.#clients.delete(clientKey);\n }\n\n getInstance(instanceKey: string): RegisteredInstance | undefined {\n return this.#instances.get(instanceKey);\n }\n\n /** Existing mount for the same client+capability+element, if any. */\n findInstance(\n clientKey: string,\n capability: string,\n element: Element,\n ): RegisteredInstance | undefined {\n return this.#elements.get(`${clientKey}::${capability}`)?.get(element);\n }\n\n registerInstance(\n clientKey: string,\n capability: string,\n element: Element,\n raw: CapabilityMountHandle,\n ): RegisteredInstance {\n const compositeKey = `${clientKey}::${capability}`;\n let byElement = this.#elements.get(compositeKey);\n if (byElement === undefined) {\n byElement = new WeakMap();\n this.#elements.set(compositeKey, byElement);\n }\n const existing = byElement.get(element);\n if (existing) return existing;\n\n this.#elementCounter += 1;\n const instance: RegisteredInstance = {\n instanceKey: `${clientKey}::${capability}::el${this.#elementCounter}`,\n clientKey,\n capability,\n host: element,\n raw,\n destroyed: false,\n };\n this.#instances.set(instance.instanceKey, instance);\n byElement.set(element, instance);\n return instance;\n }\n\n removeInstance(instanceKey: string): RegisteredInstance | undefined {\n const instance = this.#instances.get(instanceKey);\n if (!instance) return undefined;\n this.#instances.delete(instanceKey);\n this.#elements.get(`${instance.clientKey}::${instance.capability}`)?.delete(instance.host);\n return instance;\n }\n\n instancesForClient(clientKey: string): RegisteredInstance[] {\n return [...this.#instances.values()].filter((i) => i.clientKey === clientKey);\n }\n}\n","/** Stable, allowlisted `viceme:*` DOM events shared by hosted capabilities. */\n\nimport type { ViceMeErrorCode } from './core/errors.ts';\n\nexport interface VicemeReadyDetail {\n clientKey: string;\n workKey: string;\n capabilities: string[];\n version: string;\n}\n\nexport interface VicemeCapabilityReadyDetail {\n clientKey: string;\n instanceKey: string;\n capability: string;\n version: string;\n}\n\nexport interface VicemeErrorDetail {\n clientKey?: string;\n instanceKey?: string;\n capability?: string;\n code: ViceMeErrorCode;\n retryable: boolean;\n requestId?: string;\n}\n\nexport interface VicemeDestroyedDetail {\n clientKey: string;\n instanceKey: string;\n capability: string;\n}\n\nexport interface VicemeWidgetCloseDetail {\n workId: string;\n}\n\nexport interface VicemeTipPaidDetail {\n status: 'PAID';\n work: {\n id: string;\n title: string;\n };\n amountCents: number;\n currency: 'CNY';\n}\n\nexport type VicemeEventType =\n | 'viceme:ready'\n | 'viceme:capability-ready'\n | 'viceme:error'\n | 'viceme:destroyed'\n | 'viceme:widget-close'\n | 'viceme:tip-paid';\n\nexport type VicemeEventDetailMap = {\n 'viceme:ready': VicemeReadyDetail;\n 'viceme:capability-ready': VicemeCapabilityReadyDetail;\n 'viceme:error': VicemeErrorDetail;\n 'viceme:destroyed': VicemeDestroyedDetail;\n 'viceme:widget-close': VicemeWidgetCloseDetail;\n 'viceme:tip-paid': VicemeTipPaidDetail;\n};\n\nconst ALLOWED_KEYS: ReadonlyMap<VicemeEventType, ReadonlySet<string>> = new Map([\n ['viceme:ready', new Set(['clientKey', 'workKey', 'capabilities', 'version'])],\n ['viceme:capability-ready', new Set(['clientKey', 'instanceKey', 'capability', 'version'])],\n [\n 'viceme:error',\n new Set(['clientKey', 'instanceKey', 'capability', 'code', 'retryable', 'requestId']),\n ],\n ['viceme:destroyed', new Set(['clientKey', 'instanceKey', 'capability'])],\n ['viceme:widget-close', new Set(['workId'])],\n ['viceme:tip-paid', new Set(['status', 'work', 'amountCents', 'currency'])],\n]);\n\n/** Strip anything outside the documented allowlist before dispatch. */\nexport function sanitizeDetail(\n type: VicemeEventType,\n detail: VicemeEventDetailMap[VicemeEventType],\n): VicemeEventDetailMap[VicemeEventType] {\n if (type === 'viceme:tip-paid') {\n const paid = detail as VicemeTipPaidDetail;\n return {\n status: paid.status,\n work: { id: paid.work.id, title: paid.work.title },\n amountCents: paid.amountCents,\n currency: paid.currency,\n };\n }\n const allowed = ALLOWED_KEYS.get(type)!;\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(detail)) {\n if (allowed.has(key) && value !== undefined) result[key] = value;\n }\n return result as unknown as VicemeEventDetailMap[VicemeEventType];\n}\n\nexport function dispatchViceMeEvent<K extends VicemeEventType>(\n target: EventTarget,\n type: K,\n detail: VicemeEventDetailMap[K],\n): void {\n const event = new CustomEvent(type, {\n detail: sanitizeDetail(type, detail),\n bubbles: true,\n composed: true,\n cancelable: false,\n });\n target.dispatchEvent(event);\n}\n","/**\n * Client lifecycle state machine.\n *\n * ```text\n * CREATED -> READY -> DESTROYED\n * READY -> DEGRADED (single capability unavailable; host page keeps working)\n * ```\n *\n * State is exposed read-only; consumers can never assign it directly.\n */\n\nimport { ViceMeError, clientDestroyed } from './errors.ts';\n\nexport type ViceMeClientState = 'CREATED' | 'READY' | 'DEGRADED' | 'DESTROYED';\n\nconst ALLOWED_TRANSITIONS: Readonly<Record<ViceMeClientState, readonly ViceMeClientState[]>> = {\n CREATED: ['READY', 'DESTROYED'],\n READY: ['DEGRADED', 'DESTROYED'],\n DEGRADED: ['DESTROYED'],\n DESTROYED: [],\n};\n\nexport type LifecycleListener = (state: ViceMeClientState) => void;\n\nexport class Lifecycle {\n #state: ViceMeClientState = 'CREATED';\n #listeners = new Set<LifecycleListener>();\n\n get state(): ViceMeClientState {\n return this.#state;\n }\n\n get destroyed(): boolean {\n return this.#state === 'DESTROYED';\n }\n\n transition(next: ViceMeClientState): void {\n if (next === this.#state) return;\n if (!ALLOWED_TRANSITIONS[this.#state]!.includes(next)) {\n throw new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: `Illegal lifecycle transition ${this.#state} -> ${next}.`,\n retryable: false,\n });\n }\n this.#state = next;\n for (const listener of this.#listeners) listener(next);\n }\n\n /** Any operation on a destroyed client must fail closed with this guard. */\n assertAlive(): void {\n if (this.destroyed) throw clientDestroyed();\n }\n\n subscribe(listener: LifecycleListener): () => void {\n this.#listeners.add(listener);\n return () => {\n this.#listeners.delete(listener);\n };\n }\n\n clearListeners(): void {\n this.#listeners.clear();\n }\n}\n","/**\n * Public visitor session.\n *\n * ```text\n * SDK + workKey + supported protocols -> POST /v1/public/work-sdk/sessions\n * -> short-lived capability token -> public capability calls\n * ```\n *\n * The token lives in memory only (never localStorage/cookies), is bound to the\n * Work, market, capability set, and expiry by the server, and is dropped on\n * `destroy()`. `workKey` locates the Work — it is never an authorization\n * credential.\n */\n\nimport { clientDestroyed, ViceMeError } from '../core/errors.ts';\nimport type { Transport, TransportRequest, TransportResponse } from '../transport/transport.ts';\nexport interface CreateWorkSessionRequestDto {\n workKey: string;\n supportedAccessProtocolVersions: [3];\n}\n\nexport interface AccessMarketCapabilities {\n market: 'CN' | 'GLOBAL';\n loginMethods: string[];\n supportedPriceCurrencies: Array<'CNY' | 'USD'>;\n checkoutAvailability: 'AVAILABLE' | 'PENDING_CHANNEL' | 'DISABLED';\n anonymousPurchase: boolean;\n}\n\nexport interface WorkDescriptor {\n key: string;\n /** Capability names enabled for this work. */\n capabilities: string[];\n creator?: WorkCreatorDescriptor;\n details?: WorkPresentationDescriptor;\n}\n\nexport interface WorkCreatorDescriptor {\n displayName: string;\n avatarUrl: string | null;\n publishedWorkCount: number;\n}\n\nexport interface WorkPresentationDescriptor {\n title: string;\n summary: string;\n coverUrl: string | null;\n}\n\nexport interface WorkSessionSnapshot {\n work: WorkDescriptor;\n /** Opaque short-lived capability token; memory-only. */\n token?: string;\n /** Epoch milliseconds when the token expires, when provided by the server. */\n expiresAt?: number;\n user?: WorkUser;\n userToken?: string;\n userExpiresAt?: number;\n accessProtocolVersion?: 3;\n marketCapabilities?: AccessMarketCapabilities;\n buyerToken?: string;\n buyerExpiresAt?: number;\n}\n\nexport interface WorkUser {\n subject: string;\n nickname: string | null;\n avatarUrl: string | null;\n}\n\nexport interface SessionManagerOptions {\n workKey: string;\n region?: 'cn' | 'global';\n transport: Transport;\n signal?: AbortSignal;\n timeoutMs?: number;\n /** Injectable clock for tests. */\n now?: () => number;\n}\n\nfunction parseSessionResponse(\n body: unknown,\n workKey: string,\n region?: 'cn' | 'global',\n): WorkSessionSnapshot {\n if (typeof body !== 'object' || body === null) {\n throw malformedSessionResponse();\n }\n const raw = body as Record<string, unknown>;\n if (\n typeof raw.workKey !== 'string' ||\n !Array.isArray(raw.capabilities) ||\n !raw.capabilities.every((c) => typeof c === 'string')\n ) {\n throw malformedSessionResponse();\n }\n if (raw.workKey !== workKey) {\n throw new ViceMeError({\n code: 'WORK_NOT_FOUND',\n message: 'Work-session response did not match the requested work key.',\n retryable: false,\n });\n }\n const snapshot: WorkSessionSnapshot = {\n work: {\n key: raw.workKey,\n capabilities: raw.capabilities as string[],\n },\n };\n if (raw.accessProtocolVersion !== undefined) {\n if (raw.accessProtocolVersion !== 3) throw malformedSessionResponse();\n const capabilities = record(raw.marketCapabilities);\n if (region !== undefined && capabilities.market !== (region === 'cn' ? 'CN' : 'GLOBAL')) {\n throw malformedSessionResponse();\n }\n if (\n !['CN', 'GLOBAL'].includes(capabilities.market as string) ||\n !Array.isArray(capabilities.loginMethods) ||\n !capabilities.loginMethods.every((method) => typeof method === 'string') ||\n !Array.isArray(capabilities.supportedPriceCurrencies) ||\n !capabilities.supportedPriceCurrencies.every(\n (currency) => currency === 'CNY' || currency === 'USD',\n ) ||\n !['AVAILABLE', 'PENDING_CHANNEL', 'DISABLED'].includes(\n capabilities.checkoutAvailability as string,\n ) ||\n typeof capabilities.anonymousPurchase !== 'boolean'\n )\n throw malformedSessionResponse();\n snapshot.accessProtocolVersion = 3;\n snapshot.marketCapabilities = capabilities as unknown as AccessMarketCapabilities;\n }\n if (raw.creator !== undefined || raw.work !== undefined) {\n const creator = record(raw.creator);\n const work = record(raw.work);\n if (\n typeof creator.displayName !== 'string' ||\n creator.displayName.length === 0 ||\n !nullableUrl(creator.avatarUrl) ||\n !Number.isInteger(creator.publishedWorkCount) ||\n (creator.publishedWorkCount as number) < 0 ||\n typeof work.title !== 'string' ||\n work.title.length === 0 ||\n typeof work.summary !== 'string' ||\n !nullableUrl(work.coverUrl)\n ) {\n throw malformedSessionResponse();\n }\n snapshot.work.creator = {\n displayName: creator.displayName,\n avatarUrl: creator.avatarUrl as string | null,\n publishedWorkCount: creator.publishedWorkCount as number,\n };\n snapshot.work.details = {\n title: work.title,\n summary: work.summary,\n coverUrl: work.coverUrl as string | null,\n };\n }\n // Unknown extra fields are allowed and ignored (forward compatibility).\n if (typeof raw.token === 'string') snapshot.token = raw.token;\n if (typeof raw.expiresAt === 'string') {\n const expiresAt = new Date(raw.expiresAt).getTime();\n if (!Number.isNaN(expiresAt)) snapshot.expiresAt = expiresAt;\n }\n return snapshot;\n}\n\nfunction record(value: unknown): Record<string, unknown> {\n if (typeof value !== 'object' || value === null) throw malformedSessionResponse();\n return value as Record<string, unknown>;\n}\n\nfunction nullableUrl(value: unknown): value is string | null {\n if (value === null) return true;\n if (typeof value !== 'string') return false;\n try {\n new URL(value);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction malformedSessionResponse(): ViceMeError {\n return new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: 'Malformed work-session response.',\n retryable: true,\n });\n}\n\nfunction sessionInvalidated(): ViceMeError {\n return new ViceMeError({\n code: 'SESSION_EXPIRED',\n message: 'The work session was invalidated before it completed.',\n retryable: true,\n });\n}\n\nexport class SessionManager {\n readonly #options: SessionManagerOptions;\n readonly #now: () => number;\n #snapshot: WorkSessionSnapshot | undefined;\n #pending: Promise<WorkSessionSnapshot> | undefined;\n #generation = 0;\n #identityGeneration = 0;\n #destroyed = false;\n\n constructor(options: SessionManagerOptions) {\n this.#options = options;\n this.#now = options.now ?? (() => Date.now());\n }\n\n get snapshot(): WorkSessionSnapshot | undefined {\n return this.#snapshot;\n }\n\n /** Identity generation prevents a late bridge from undoing logout or account changes. */\n get identityGeneration(): number {\n return this.#identityGeneration;\n }\n\n /** True when the cached snapshot's server-provided expiry has passed. */\n #isExpired(): boolean {\n const expiresAt = this.#snapshot?.expiresAt;\n return expiresAt !== undefined && expiresAt <= this.#now();\n }\n\n /**\n * Establish (or return the established) public session.\n *\n * A cached snapshot is reused only while it is unexpired; an expired\n * snapshot is dropped and re-authenticated. Concurrent callers share one\n * in-flight request (single flight).\n */\n establish(): Promise<WorkSessionSnapshot> {\n if (this.#destroyed) return Promise.reject(clientDestroyed());\n if (this.#snapshot) {\n if (!this.#isExpired()) {\n if (\n this.#snapshot.userExpiresAt !== undefined &&\n this.#snapshot.userExpiresAt <= this.#now()\n ) {\n this.#generation += 1;\n this.#identityGeneration += 1;\n this.#snapshot = {\n ...this.#snapshot,\n user: undefined,\n userToken: undefined,\n userExpiresAt: undefined,\n };\n }\n if (\n this.#snapshot.buyerExpiresAt !== undefined &&\n this.#snapshot.buyerExpiresAt <= this.#now()\n ) {\n this.#generation += 1;\n this.#identityGeneration += 1;\n this.#snapshot = { ...this.#snapshot, buyerToken: undefined, buyerExpiresAt: undefined };\n }\n return Promise.resolve(this.#snapshot);\n }\n this.#generation += 1;\n this.#snapshot = undefined;\n }\n if (this.#pending) return this.#pending;\n const generation = this.#generation;\n const pending = this.#options.transport\n .request({\n method: 'POST',\n path: '/v1/public/work-sdk/sessions',\n body: {\n workKey: this.#options.workKey,\n supportedAccessProtocolVersions: [3],\n } satisfies CreateWorkSessionRequestDto,\n signal: this.#options.signal,\n timeoutMs: this.#options.timeoutMs,\n })\n .then((response) => {\n this.#assertCurrent(generation);\n const snapshot = parseSessionResponse(\n response.body,\n this.#options.workKey,\n this.#options.region,\n );\n this.#assertCurrent(generation);\n this.#snapshot = snapshot;\n return snapshot;\n })\n .finally(() => {\n if (this.#pending === pending) this.#pending = undefined;\n });\n this.#pending = pending;\n return pending;\n }\n\n async request(\n request: Omit<TransportRequest, 'authorization' | 'userAuthorization' | 'buyerAuthorization'>,\n ): Promise<TransportResponse> {\n const snapshot = await this.establish();\n if (!snapshot.token) throw malformedSessionResponse();\n try {\n return await this.#requestWithSnapshot(request, snapshot);\n } catch (error) {\n if (this.#destroyed) throw clientDestroyed();\n if (request.signal?.aborted || this.#options.signal?.aborted) throw error;\n if (!(error instanceof ViceMeError) || error.code !== 'SESSION_EXPIRED') throw error;\n if (this.#snapshot === snapshot) this.invalidate();\n const refreshed = await this.establish();\n if (!refreshed.token) throw malformedSessionResponse();\n return this.#requestWithSnapshot(request, refreshed);\n }\n }\n\n authenticate(input: { userToken: string; user: WorkUser; expiresAt?: number }): void {\n this.#assertAlive();\n if (!this.#snapshot) throw malformedSessionResponse();\n if (input.expiresAt !== undefined && input.expiresAt <= this.#now()) throw sessionInvalidated();\n this.#generation += 1;\n this.#identityGeneration += 1;\n this.#snapshot = {\n ...this.#snapshot,\n userToken: input.userToken,\n user: input.user,\n userExpiresAt: input.expiresAt,\n buyerToken: undefined,\n buyerExpiresAt: undefined,\n };\n }\n\n identifyBuyer(input: { buyerToken: string; expiresAt: number }, generation: number): void {\n this.#assertAlive();\n if (generation !== this.#identityGeneration) throw sessionInvalidated();\n if (!this.#snapshot || input.expiresAt <= this.#now()) throw sessionInvalidated();\n this.#generation += 1;\n this.#identityGeneration += 1;\n this.#snapshot = {\n ...this.#snapshot,\n user: undefined,\n userToken: undefined,\n userExpiresAt: undefined,\n buyerToken: input.buyerToken,\n buyerExpiresAt: input.expiresAt,\n };\n }\n\n async signOut(): Promise<void> {\n this.#assertAlive();\n this.#identityGeneration += 1;\n this.invalidate();\n await this.establish();\n }\n\n /** Drop the token; next `establish()` re-authenticates. */\n invalidate(): void {\n this.#generation += 1;\n this.#snapshot = undefined;\n this.#pending = undefined;\n }\n\n /** Hard cleanup: forget the token and pending work. */\n destroy(): void {\n if (this.#destroyed) return;\n this.#destroyed = true;\n this.#generation += 1;\n this.#identityGeneration += 1;\n this.#snapshot = undefined;\n this.#pending = undefined;\n }\n\n #assertAlive(): void {\n if (this.#destroyed) throw clientDestroyed();\n }\n\n #assertCurrent(generation: number): void {\n this.#assertAlive();\n if (generation !== this.#generation) throw sessionInvalidated();\n }\n\n async #requestWithSnapshot(\n request: Omit<TransportRequest, 'authorization' | 'userAuthorization' | 'buyerAuthorization'>,\n snapshot: WorkSessionSnapshot,\n ): Promise<TransportResponse> {\n this.#assertAlive();\n const generation = this.#generation;\n try {\n const response = await this.#options.transport.request({\n ...request,\n authorization: snapshot.token,\n userAuthorization: snapshot.userToken,\n buyerAuthorization:\n snapshot.buyerExpiresAt !== undefined && snapshot.buyerExpiresAt > this.#now()\n ? snapshot.buyerToken\n : undefined,\n signal:\n request.signal && this.#options.signal\n ? AbortSignal.any([request.signal, this.#options.signal])\n : (request.signal ?? this.#options.signal),\n });\n this.#assertAlive();\n // A late authorization read must not grant access after identity changes.\n // Successful mutations are not replayed just because another request refreshed a session.\n if (request.method === 'GET' || request.path === '/v1/public/work-sdk/access/check') {\n this.#assertCurrent(generation);\n }\n return response;\n } catch (error) {\n if (this.#destroyed) throw clientDestroyed();\n throw error;\n }\n }\n}\n","/**\n * Single source of truth for the SDK runtime version.\n *\n * Kept in sync with `packages/sdk/package.json#version`; a unit test enforces\n * the match so the loader, release manifest, and npm metadata can never drift.\n */\nexport const SDK_VERSION = '0.8.0';\n\n/** Public API major carried by this build (loader namespace `v1`). */\nexport const API_MAJOR = 1;\n","import type { FollowTarget } from './capabilities.ts';\nimport { isViceMeError } from './errors.ts';\n\nexport type AccessInteractionAction = 'SIGN_IN' | 'FOLLOW' | 'CHECKOUT' | 'RESOLVE_BUYER';\n\nexport interface AccessInteraction {\n featureKey: string;\n reason: string;\n action: AccessInteractionAction;\n followTarget?: FollowTarget;\n work?: {\n title: string;\n summary: string;\n coverUrl: string | null;\n };\n /** Client-owned lifecycle signal; abort closes any active hosted surface. */\n signal?: AbortSignal;\n /** The host's original click already authorized opening this interaction. */\n autoStart?: boolean;\n perform(): Promise<AccessActionResult>;\n}\n\nexport interface AccessCompletedAction {\n type: 'completed';\n}\n\nexport interface AccessFrameAction {\n type: 'frame';\n url: string;\n completion: Promise<void>;\n cancel(): void;\n /** User-triggered fallback when a first-party context is required. */\n continueInSamePage?(): void;\n}\n\nexport interface AccessExternalAction {\n type: 'external';\n completion: Promise<void>;\n cancel(): void;\n}\n\nexport type AccessActionResult = AccessCompletedAction | AccessFrameAction | AccessExternalAction;\n\nexport type AccessPresentationResult = 'acted' | 'dismissed';\n\n/** Internal interaction seam used by the ViceMe layer and deterministic tests. */\nexport type AccessPresenter = (interaction: AccessInteraction) => Promise<AccessPresentationResult>;\n\nconst ELEMENT_NAME = 'viceme-access-layer';\nconst PROFILE_DESCRIPTION_LIMIT = 50;\n\ninterface AccessLayerElement extends HTMLElement {\n interaction: AccessInteraction;\n}\n\nfunction english(): boolean {\n return (\n typeof document !== 'undefined' && document.documentElement.lang.toLowerCase().startsWith('en')\n );\n}\n\nfunction actionCopy(action: AccessInteractionAction): {\n description: string;\n label: string;\n} {\n switch (action) {\n case 'SIGN_IN':\n return {\n description: '',\n label: english() ? 'Sign in' : '授权',\n };\n case 'FOLLOW':\n return {\n description: '',\n label: english() ? 'Follow' : '关注',\n };\n case 'CHECKOUT':\n return {\n description: '',\n label: english() ? 'Open checkout' : '打开支付',\n };\n case 'RESOLVE_BUYER':\n return {\n description: '',\n label: english() ? 'Continue or restore purchase' : '继续购买或恢复权益',\n };\n }\n}\n\nfunction actionErrorCopy(error: unknown): string {\n const fallback = english()\n ? 'Unable to complete this action. Please try again.'\n : '操作未完成,请重试。';\n if (!isViceMeError(error)) return fallback;\n switch (error.code) {\n case 'CONFIG_INVALID':\n return english()\n ? 'This action is not configured correctly. Please try again later.'\n : '操作配置无效,请稍后重试。';\n case 'AUTH_CANCELLED':\n return english() ? 'This action was cancelled. Please try again.' : '操作已取消,请重试。';\n case 'SESSION_EXPIRED':\n return english() ? 'Your session expired. Please try again.' : '授权会话已过期,请重试。';\n case 'NETWORK_TIMEOUT':\n return english() ? 'The connection timed out. Please try again.' : '网络连接超时,请重试。';\n default:\n return error.requestId\n ? `${fallback} ${english() ? 'Request ID:' : '请求 ID:'} ${error.requestId}`\n : fallback;\n }\n}\n\nfunction ensureAccessLayerElement(): void {\n if (customElements.get(ELEMENT_NAME)) return;\n\n class ViceMeAccessLayerElement extends HTMLElement implements AccessLayerElement {\n interaction!: AccessInteraction;\n\n connectedCallback(): void {\n const copy = actionCopy(this.interaction.action);\n const shadow = this.attachShadow({ mode: 'open' });\n shadow.innerHTML = `\n <style>\n :host {\n position: fixed;\n inset: 0;\n z-index: 2147483000;\n display: grid;\n align-items: end;\n color: #18181b;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif;\n font-size: 16px;\n line-height: 1.5;\n }\n [data-viceme='backdrop'] {\n position: absolute;\n inset: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n }\n [data-viceme='panel'] {\n position: relative;\n box-sizing: border-box;\n display: flex;\n width: 100%;\n max-height: min(92dvh, 46rem);\n flex-direction: column;\n overflow: auto;\n border-radius: 1.25rem 1.25rem 0 0;\n background: #ffffff;\n color: #18181b;\n padding: 3.75rem 1.25rem calc(1.25rem + env(safe-area-inset-bottom));\n box-shadow: 0 -1rem 3rem rgb(0 0 0 / 18%);\n }\n [data-viceme='content'] { display: flex; min-height: 0; flex-direction: column; }\n [data-viceme='close'] {\n position: absolute;\n top: 0.75rem;\n left: 0.75rem;\n width: 2.75rem;\n height: 2.75rem;\n border: 0;\n border-radius: 999px;\n padding: 0;\n background: transparent;\n color: #52525b;\n font-size: 2rem;\n font-weight: 400;\n line-height: 1;\n }\n [data-viceme='description'] { margin: 0.75rem 0 1.25rem; color: #71717a; line-height: 1.6; }\n [data-viceme='profile'] {\n display: none;\n margin: 0;\n border: 1px solid #e4e4e7;\n border-radius: 1rem;\n padding: 1.5rem;\n background: #ffffff;\n box-shadow: 0 0.75rem 2rem rgb(0 0 0 / 6%);\n text-align: center;\n }\n [data-viceme='profile'][data-visible='true'] { display: block; }\n [data-viceme='avatar'] {\n display: block;\n width: 5.5rem;\n height: 5.5rem;\n margin: 0 auto 1rem;\n border-radius: 999px;\n object-fit: cover;\n background: #f4f4f5;\n }\n [data-viceme='avatar-fallback'] {\n display: grid;\n width: 5.5rem;\n height: 5.5rem;\n margin: 0 auto 1rem;\n place-items: center;\n border-radius: 999px;\n background: #f4f4f5;\n color: #18181b;\n font-size: 2rem;\n font-weight: 700;\n }\n [data-viceme='avatar'][hidden], [data-viceme='avatar-fallback'][hidden] { display: none; }\n [data-viceme='profile-summary'] {\n display: flex;\n min-width: 0;\n align-items: baseline;\n justify-content: center;\n gap: 0.5rem;\n }\n [data-viceme='profile-name'] { margin: 0; font-size: 1.375rem; font-weight: 700; }\n [data-viceme='profile-separator'], [data-viceme='profile-stats'] {\n color: #71717a;\n }\n [data-viceme='profile-description'] {\n margin: 0.25rem 0 0;\n overflow-wrap: anywhere;\n color: #71717a;\n }\n [data-viceme='profile-description']:empty { display: none; }\n [data-viceme='profile-stats'] {\n margin: 0;\n font-size: 0.875rem;\n }\n [data-viceme='profile-header'] { min-width: 0; }\n [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='description'] { display: none; }\n [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='profile'][data-visible='true'] {\n display: block;\n border: 0;\n padding: 0;\n background: transparent;\n box-shadow: none;\n text-align: center;\n }\n [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='profile-name'] {\n font-size: 1.125rem;\n }\n [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='profile-description'] {\n display: none;\n }\n [data-viceme='work'] {\n display: none;\n overflow: hidden;\n margin-top: 1.25rem;\n border: 1px solid #e4e4e7;\n border-radius: 1rem;\n background: #fafafa;\n text-align: left;\n }\n [data-viceme='work'][data-visible='true'] { display: block; }\n [data-viceme='work-cover'] {\n display: block;\n width: 100%;\n aspect-ratio: 16 / 9;\n object-fit: cover;\n background: #f4f4f5;\n }\n [data-viceme='work-cover'][hidden] { display: none; }\n [data-viceme='work-copy'] { padding: 1rem; }\n [data-viceme='work-title'] {\n margin: 0;\n color: #18181b;\n font-size: 1rem;\n font-weight: 700;\n line-height: 1.5;\n }\n [data-viceme='work-summary'] {\n display: -webkit-box;\n overflow: hidden;\n margin: 0.375rem 0 0;\n color: #71717a;\n font-size: 0.875rem;\n line-height: 1.5;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n }\n [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='action'] {\n width: 100%;\n }\n [data-viceme='actions'] {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n margin-top: 1.25rem;\n }\n button {\n box-sizing: border-box;\n display: inline-flex;\n height: 3.25rem;\n align-items: center;\n justify-content: center;\n border-radius: 0.75rem;\n padding: 0.625rem 1rem;\n font: 600 1rem/1.5 -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", sans-serif;\n cursor: pointer;\n }\n button:focus-visible, iframe:focus-visible { outline: 2px solid #18181b; outline-offset: 2px; }\n [data-viceme='action'] {\n width: min(11rem, 48%);\n border: 1px solid #18181b;\n background: #18181b;\n color: #ffffff;\n }\n [data-viceme='action']:hover { background: #3f3f46; border-color: #3f3f46; }\n [data-viceme='actions'][data-single='true'] [data-viceme='action'] { width: 100%; }\n button:disabled { cursor: wait; opacity: 0.5; }\n button[hidden] { display: none; }\n [data-viceme='error'] { margin: 0.75rem 0 0; color: #b91c1c; font-size: 0.875rem; }\n [data-viceme='error']:empty { display: none; }\n [data-viceme='frame'] {\n display: none;\n width: 100%;\n min-height: 0;\n flex: 1 1 auto;\n border: 0;\n border-radius: 0.75rem;\n background: #ffffff;\n }\n [data-viceme='panel'][data-frame='true'] {\n height: min(92dvh, 46rem);\n max-height: 92dvh;\n overflow: hidden;\n }\n [data-viceme='panel'][data-frame='true'] [data-viceme='content'] { display: none; }\n [data-viceme='panel'][data-frame='true'] [data-viceme='frame'] { display: block; }\n @media (min-width: 48rem) {\n :host { place-items: center; padding: 1.5rem; }\n [data-viceme='panel'] {\n width: min(24rem, 100%);\n border-radius: 1.25rem;\n padding: 3.75rem 1.25rem 1.25rem;\n box-shadow: 0 1.5rem 4rem rgb(0 0 0 / 24%);\n }\n [data-viceme='panel'][data-frame='true'] { width: min(30rem, 100%); }\n [data-viceme='panel'][data-action='SIGN_IN'] { width: min(30rem, 100%); }\n [data-viceme='panel'][data-action='CHECKOUT'][data-frame='true'] {\n width: min(42rem, 100%);\n }\n }\n @media (prefers-reduced-motion: no-preference) {\n [data-viceme='panel'] { animation: viceme-enter 160ms ease-out; }\n @keyframes viceme-enter { from { opacity: 0; transform: translateY(1rem); } }\n }\n </style>\n <button data-viceme=\"backdrop\" type=\"button\" tabindex=\"-1\" aria-label=\"${english() ? 'Close' : '关闭'}\"></button>\n <section data-viceme=\"panel\" role=\"dialog\" aria-modal=\"true\" aria-label=\"${english() ? 'ViceMe access' : 'ViceMe 授权'}\">\n <button data-viceme=\"close\" type=\"button\" aria-label=\"${english() ? 'Close' : '关闭'}\">×</button>\n <div data-viceme=\"content\">\n <p data-viceme=\"description\"></p>\n <section data-viceme=\"profile\" aria-label=\"${english() ? 'Creator' : '创作者'}\">\n <div data-viceme=\"profile-header\">\n <img data-viceme=\"avatar\" hidden />\n <span data-viceme=\"avatar-fallback\" aria-hidden=\"true\"></span>\n <div data-viceme=\"profile-summary\">\n <p data-viceme=\"profile-name\"></p>\n <span data-viceme=\"profile-separator\" aria-hidden=\"true\">·</span>\n <p data-viceme=\"profile-stats\"></p>\n </div>\n </div>\n <p data-viceme=\"profile-description\"></p>\n </section>\n <article data-viceme=\"work\">\n <img data-viceme=\"work-cover\" hidden />\n <div data-viceme=\"work-copy\">\n <p data-viceme=\"work-title\"></p>\n <p data-viceme=\"work-summary\"></p>\n </div>\n </article>\n <p data-viceme=\"error\" role=\"alert\" aria-live=\"polite\"></p>\n <div data-viceme=\"actions\">\n <button data-viceme=\"action\" type=\"button\"></button>\n </div>\n </div>\n <iframe data-viceme=\"frame\" title=\"\" referrerpolicy=\"no-referrer\" allow=\"payment\"></iframe>\n <button data-viceme=\"continue\" type=\"button\" hidden>${english() ? 'Continue in this page' : '在当前页面继续'}</button>\n </section>\n `;\n const panel = shadow.querySelector<HTMLElement>(\"[data-viceme='panel']\")!;\n panel.dataset.action = this.interaction.action;\n panel.dataset.frame = 'false';\n const description = shadow.querySelector<HTMLElement>(\"[data-viceme='description']\")!;\n description.textContent = copy.description;\n const action = shadow.querySelector<HTMLButtonElement>(\"[data-viceme='action']\")!;\n const mainActions = action.parentElement!;\n const closeAction = shadow.querySelector<HTMLButtonElement>(\"[data-viceme='close']\")!;\n const backdrop = shadow.querySelector<HTMLButtonElement>(\"[data-viceme='backdrop']\")!;\n const error = shadow.querySelector<HTMLElement>(\"[data-viceme='error']\")!;\n const frame = shadow.querySelector<HTMLIFrameElement>(\"[data-viceme='frame']\")!;\n const continueAction = shadow.querySelector<HTMLButtonElement>(\"[data-viceme='continue']\")!;\n const profile = shadow.querySelector<HTMLElement>(\"[data-viceme='profile']\")!;\n const avatar = shadow.querySelector<HTMLImageElement>(\"[data-viceme='avatar']\")!;\n const avatarFallback = shadow.querySelector<HTMLElement>(\"[data-viceme='avatar-fallback']\")!;\n const profileName = shadow.querySelector<HTMLElement>(\"[data-viceme='profile-name']\")!;\n const profileDescription = shadow.querySelector<HTMLElement>(\n \"[data-viceme='profile-description']\",\n )!;\n const profileStats = shadow.querySelector<HTMLElement>(\"[data-viceme='profile-stats']\")!;\n const work = shadow.querySelector<HTMLElement>(\"[data-viceme='work']\")!;\n const workCover = shadow.querySelector<HTMLImageElement>(\"[data-viceme='work-cover']\")!;\n const workTitle = shadow.querySelector<HTMLElement>(\"[data-viceme='work-title']\")!;\n const workSummary = shadow.querySelector<HTMLElement>(\"[data-viceme='work-summary']\")!;\n action.textContent = copy.label;\n action.hidden = false;\n mainActions.dataset.single = 'true';\n const idleActionLabel = copy.label;\n frame.title =\n this.interaction.action === 'SIGN_IN'\n ? '登录授权'\n : this.interaction.action === 'RESOLVE_BUYER'\n ? '购买权益恢复'\n : '支付';\n\n const target = this.interaction.followTarget;\n if (target) {\n panel.setAttribute(\n 'aria-label',\n this.interaction.action === 'SIGN_IN'\n ? `授权 ${target.displayName}`\n : `关注 ${target.displayName}`,\n );\n profile.dataset.visible = 'true';\n profileName.textContent = target.displayName;\n const descriptionCharacters = [...(target.description ?? '')];\n profileDescription.textContent =\n descriptionCharacters.length > PROFILE_DESCRIPTION_LIMIT\n ? `${descriptionCharacters.slice(0, PROFILE_DESCRIPTION_LIMIT).join('')}…`\n : descriptionCharacters.join('');\n if (descriptionCharacters.length > PROFILE_DESCRIPTION_LIMIT) {\n profileDescription.title = target.description!;\n }\n profileStats.textContent = `${target.workCount} 个作品`;\n avatarFallback.textContent = target.displayName.trim().slice(0, 1) || 'V';\n if (target.avatarUrl) {\n avatar.src = target.avatarUrl;\n avatar.alt = `${target.displayName}的头像`;\n avatar.hidden = false;\n avatarFallback.hidden = true;\n }\n }\n const workDetails = this.interaction.work;\n if (workDetails) {\n work.dataset.visible = 'true';\n workTitle.textContent = workDetails.title;\n workSummary.textContent = workDetails.summary;\n if (workDetails.coverUrl) {\n workCover.src = workDetails.coverUrl;\n workCover.alt = workDetails.title;\n workCover.hidden = false;\n }\n }\n\n let activeAction: AccessFrameAction | AccessExternalAction | null = null;\n let closed = false;\n const close = (result: AccessPresentationResult) => {\n if (closed) return;\n closed = true;\n this.interaction.signal?.removeEventListener('abort', dismissLayer);\n this.dispatchEvent(new CustomEvent('viceme:access-layer-close', { detail: result }));\n };\n const dismissLayer = () => {\n activeAction?.cancel();\n close('dismissed');\n };\n this.interaction.signal?.addEventListener('abort', dismissLayer, { once: true });\n if (this.interaction.signal?.aborted) queueMicrotask(dismissLayer);\n backdrop.addEventListener('click', dismissLayer);\n closeAction.addEventListener('click', dismissLayer);\n continueAction.addEventListener('click', () => {\n try {\n if (activeAction?.type === 'frame') activeAction.continueInSamePage?.();\n } catch (caught) {\n error.textContent = actionErrorCopy(caught);\n panel.dataset.frame = 'false';\n }\n });\n this.addEventListener('keydown', (event) => {\n if (event.key === 'Escape') dismissLayer();\n if (event.key === 'Tab') {\n event.preventDefault();\n if (activeAction?.type === 'frame') {\n const available = [\n closeAction,\n frame,\n ...(continueAction.hidden ? [] : [continueAction]),\n ];\n const index = available.indexOf(shadow.activeElement as HTMLButtonElement);\n available[\n (index + (event.shiftKey ? -1 : 1) + available.length) % available.length\n ]?.focus();\n return;\n }\n const focusable = [closeAction, ...(action.hidden ? [] : [action])];\n const available = focusable.filter((element) => !element.disabled && !element.hidden);\n if (available.length === 0) return;\n const currentIndex = available.indexOf(shadow.activeElement as HTMLButtonElement);\n const direction = event.shiftKey ? -1 : 1;\n available[(currentIndex + direction + available.length) % available.length]?.focus();\n }\n });\n const performAction = async () => {\n action.disabled = true;\n action.setAttribute('aria-busy', 'true');\n action.textContent = english() ? 'Opening…' : '正在打开…';\n error.textContent = '';\n try {\n const result = await this.interaction.perform();\n // The layer may close while an async action is still being created.\n // Cancel that late action immediately so its timers/listeners cannot\n // outlive the client-owned presentation surface.\n if (closed || this.interaction.signal?.aborted) {\n if (result.type !== 'completed') result.cancel();\n return;\n }\n if (result.type === 'frame') {\n activeAction = result;\n continueAction.hidden = !result.continueInSamePage;\n panel.dataset.frame = 'true';\n frame.src = result.url;\n frame.focus();\n await result.completion;\n } else if (result.type === 'external') {\n activeAction = result;\n await result.completion;\n }\n close('acted');\n } catch (caught) {\n if (closed) return;\n activeAction?.cancel();\n activeAction = null;\n continueAction.hidden = true;\n panel.dataset.frame = 'false';\n frame.removeAttribute('src');\n error.textContent = actionErrorCopy(caught);\n action.hidden = false;\n action.disabled = false;\n action.removeAttribute('aria-busy');\n action.textContent = idleActionLabel;\n action.focus();\n }\n };\n action.addEventListener('click', performAction);\n queueMicrotask(() => {\n if (closed) return;\n if (this.interaction.autoStart) void performAction();\n else action.focus();\n });\n }\n }\n\n customElements.define(ELEMENT_NAME, ViceMeAccessLayerElement);\n}\n\nexport const defaultAccessPresenter: AccessPresenter = async (interaction) => {\n if (typeof document === 'undefined' || typeof customElements === 'undefined') {\n return 'dismissed';\n }\n if (interaction.signal?.aborted) return 'dismissed';\n ensureAccessLayerElement();\n const element = document.createElement(ELEMENT_NAME) as AccessLayerElement;\n element.interaction = interaction;\n const previousOverflow = document.documentElement.style.overflow;\n const previousFocus =\n document.activeElement instanceof HTMLElement ? document.activeElement : null;\n document.documentElement.style.overflow = 'hidden';\n document.body.append(element);\n try {\n return await new Promise<AccessPresentationResult>((resolve) => {\n element.addEventListener(\n 'viceme:access-layer-close',\n (event) => resolve((event as CustomEvent<AccessPresentationResult>).detail),\n { once: true },\n );\n });\n } finally {\n element.remove();\n document.documentElement.style.overflow = previousOverflow;\n previousFocus?.focus();\n }\n};\n","import { clientDestroyed, ViceMeError } from './errors.ts';\nimport type { AccessFrameAction } from './presentation.ts';\nimport type { SessionManager, WorkUser } from '../session/session.ts';\n\nexport type AccessBridgePurpose = 'IDENTIFY' | 'RESTORE' | 'CLAIM' | 'SIGN_IN';\n\ninterface BridgeOptions {\n session: SessionManager;\n workKey: string;\n widgetOrigin: string;\n signal: AbortSignal;\n now: () => number;\n}\n\ninterface Handshake {\n challengeId: string;\n bridgeUrl: string;\n expiresAt: number;\n verifier: string;\n state: string;\n purpose: AccessBridgePurpose;\n featureKey?: string;\n}\n\nfunction invalid(): ViceMeError {\n return new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: 'Malformed access bridge response.',\n retryable: false,\n });\n}\n\nfunction body(value: unknown): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw invalid();\n return value as Record<string, unknown>;\n}\n\nfunction base64url(bytes: Uint8Array): string {\n return btoa(String.fromCharCode(...bytes))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n}\n\nfunction officialUrl(value: unknown, origin: string): string {\n if (typeof value !== 'string') throw invalid();\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw invalid();\n }\n if (url.protocol !== 'https:' || url.origin !== origin || url.username || url.password)\n throw invalid();\n return url.href;\n}\n\nfunction expired(): ViceMeError {\n return new ViceMeError({\n code: 'SESSION_EXPIRED',\n message: 'Access recovery expired. Please try again.',\n retryable: true,\n });\n}\n\n/** A proof-of-possession bridge: window messages and return URLs never carry credentials. */\nexport function createAccessBridge(options: BridgeOptions): {\n start(purpose: AccessBridgePurpose, featureKey?: string): Promise<AccessFrameAction>;\n clear(): void;\n} {\n const storageKey = `viceme:access-bridge:v3:${options.widgetOrigin}:${options.workKey}`;\n let active: AbortController | undefined;\n const clear = () => {\n active?.abort(options.signal.aborted ? options.signal.reason : undefined);\n active = undefined;\n try {\n sessionStorage.removeItem(storageKey);\n } catch {\n /* Storage may be unavailable. */\n }\n };\n options.signal.addEventListener('abort', clear, { once: true });\n\n return {\n clear,\n async start(purpose, featureKey) {\n if (options.signal.aborted) throw options.signal.reason ?? clientDestroyed();\n if (active)\n throw new ViceMeError({\n code: 'CONFIG_INVALID',\n message: 'An access interaction is already open.',\n retryable: true,\n });\n if (typeof window === 'undefined' || !globalThis.crypto?.subtle) {\n throw new ViceMeError({\n code: 'CONFIG_INVALID',\n message: 'Access recovery requires a browser with Web Crypto.',\n retryable: false,\n });\n }\n const controller = new AbortController();\n active = controller;\n const signal = AbortSignal.any([options.signal, controller.signal]);\n const assertActive = () => {\n if (signal.aborted) throw signal.reason ?? clientDestroyed();\n };\n try {\n await options.session.establish();\n const generation = options.session.identityGeneration;\n const request = async (path: string, fields: Record<string, unknown>) => {\n assertActive();\n const snapshot = await options.session.establish();\n const response = await options.session.request({\n method: 'POST',\n path,\n signal,\n body: { ...fields, workSessionToken: snapshot.token },\n });\n assertActive();\n return body(response.body);\n };\n\n let handshake: Handshake | undefined;\n try {\n const stored = JSON.parse(sessionStorage.getItem(storageKey) ?? 'null');\n if (\n stored &&\n (stored.purpose === purpose ||\n (purpose === 'IDENTIFY' && ['RESTORE', 'CLAIM'].includes(stored.purpose))) &&\n stored.featureKey === featureKey &&\n typeof stored.expiresAt === 'number' &&\n stored.expiresAt > options.now() &&\n stored.expiresAt <= options.now() + 300_000 &&\n typeof stored.challengeId === 'string' &&\n /^[A-Za-z0-9_-]+$/.test(stored.challengeId) &&\n typeof stored.verifier === 'string' &&\n /^[A-Za-z0-9_-]{43,128}$/.test(stored.verifier) &&\n typeof stored.state === 'string'\n ) {\n handshake = {\n ...stored,\n bridgeUrl: officialUrl(stored.bridgeUrl, options.widgetOrigin),\n } as Handshake;\n // require() may resume the user's already-authorized recovery/claim after navigation.\n purpose = handshake.purpose;\n }\n } catch {\n /* Invalid or unavailable navigation state starts a new handshake. */\n }\n if (!handshake) {\n const verifier = base64url(crypto.getRandomValues(new Uint8Array(32)));\n const state = base64url(crypto.getRandomValues(new Uint8Array(32)));\n const codeChallenge = base64url(\n new Uint8Array(\n await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier)),\n ),\n );\n assertActive();\n const returnUrl = /^https?:$/.test(window.location.protocol)\n ? window.location.href\n : undefined;\n const result = await request('/v1/public/work-sdk/buyer/challenges', {\n purpose,\n ...(featureKey ? { featureKey } : {}),\n codeChallenge,\n state,\n requestId: crypto.randomUUID(),\n ...(returnUrl ? { returnUrl } : {}),\n });\n const expiresAt =\n typeof result.expiresAt === 'string' ? Date.parse(result.expiresAt) : NaN;\n if (\n typeof result.challengeId !== 'string' ||\n !/^[A-Za-z0-9_-]+$/.test(result.challengeId) ||\n !Number.isFinite(expiresAt) ||\n expiresAt <= options.now()\n )\n throw invalid();\n handshake = {\n challengeId: result.challengeId,\n bridgeUrl: officialUrl(result.bridgeUrl, options.widgetOrigin),\n expiresAt: Math.min(expiresAt, options.now() + 300_000),\n verifier,\n state,\n purpose,\n featureKey,\n };\n }\n const current = handshake;\n let navigating = false;\n const forget = () => {\n if (active === controller) active = undefined;\n if (!navigating) {\n try {\n sessionStorage.removeItem(storageKey);\n } catch {\n /* No persistent credential required. */\n }\n }\n };\n let timer: ReturnType<typeof setTimeout> | undefined;\n let deadline: ReturnType<typeof setTimeout> | undefined;\n const pause = () =>\n new Promise<void>((resolve, reject) => {\n const abort = () => {\n if (timer) clearTimeout(timer);\n reject(signal.reason);\n };\n signal.addEventListener('abort', abort, { once: true });\n timer = setTimeout(() => {\n signal.removeEventListener('abort', abort);\n resolve();\n }, 1_000);\n if (signal.aborted) abort();\n });\n const complete = async () => {\n deadline = setTimeout(\n () => controller.abort(expired()),\n Math.max(0, current.expiresAt - options.now()),\n );\n try {\n while (options.now() < current.expiresAt) {\n assertActive();\n const result = await request(\n `/v1/public/work-sdk/buyer/challenges/${current.challengeId}/result`,\n { codeVerifier: current.verifier },\n );\n if (result.status === 'EXPIRED') throw expired();\n if (result.status === 'PENDING') {\n await pause();\n continue;\n }\n if (result.status !== 'READY' || typeof result.code !== 'string' || !result.code)\n throw invalid();\n const identity = await request('/v1/public/work-sdk/buyer/exchange', {\n code: result.code,\n codeVerifier: current.verifier,\n });\n assertActive();\n if (options.session.identityGeneration !== generation) throw expired();\n if (identity.purpose !== purpose) throw invalid();\n const identityExpiresAt =\n typeof identity.expiresAt === 'string' ? Date.parse(identity.expiresAt) : NaN;\n if (!Number.isFinite(identityExpiresAt) || identityExpiresAt <= options.now())\n throw invalid();\n if (typeof identity.userToken === 'string' && identity.userToken) {\n if (purpose !== 'SIGN_IN' && purpose !== 'CLAIM') throw invalid();\n const user = body(identity.user);\n if (\n typeof user.id !== 'string' ||\n !(typeof user.displayName === 'string' || user.displayName === null) ||\n !(typeof user.avatarUrl === 'string' || user.avatarUrl === null)\n )\n throw invalid();\n const parsed: WorkUser = {\n subject: user.id,\n nickname: user.displayName,\n avatarUrl: user.avatarUrl,\n };\n options.session.authenticate({\n userToken: identity.userToken,\n user: parsed,\n expiresAt: identityExpiresAt,\n });\n } else {\n const expiresAt =\n typeof identity.expiresAt === 'string' ? Date.parse(identity.expiresAt) : NaN;\n if (\n purpose === 'SIGN_IN' ||\n purpose === 'CLAIM' ||\n typeof identity.buyerToken !== 'string' ||\n !identity.buyerToken ||\n !Number.isFinite(expiresAt)\n )\n throw invalid();\n options.session.identifyBuyer(\n { buyerToken: identity.buyerToken, expiresAt },\n generation,\n );\n }\n return;\n }\n throw expired();\n } finally {\n if (deadline) clearTimeout(deadline);\n if (timer) clearTimeout(timer);\n forget();\n }\n };\n let completion: Promise<void> | undefined;\n return {\n type: 'frame',\n url: current.bridgeUrl,\n get completion() {\n // Do not exchange an identity before the presenter accepts the action.\n return (completion ??= complete());\n },\n cancel: () => {\n controller.abort();\n forget();\n },\n continueInSamePage: () => {\n assertActive();\n // Only a bounded PKCE handshake is saved, never buyer/user tokens or recovery secrets.\n try {\n sessionStorage.setItem(storageKey, JSON.stringify(current));\n } catch {\n throw new ViceMeError({\n code: 'CONFIG_INVALID',\n message: 'Browser storage is unavailable. Use the recovery page in another window.',\n retryable: true,\n });\n }\n navigating = true;\n controller.abort();\n window.location.assign(current.bridgeUrl);\n },\n };\n } catch (error) {\n if (active === controller) active = undefined;\n controller.abort();\n throw error;\n }\n },\n };\n}\n","import { clientDestroyed, ViceMeError } from './errors.ts';\nimport {\n defaultAccessPresenter,\n type AccessActionResult,\n type AccessFrameAction,\n type AccessInteraction,\n type AccessPresenter,\n} from './presentation.ts';\nimport type { SessionManager, WorkUser } from '../session/session.ts';\nimport { createAccessBridge, type AccessBridgePurpose } from './access-bridge.ts';\n\nexport interface AuthState {\n authenticated: boolean;\n user: WorkUser | null;\n}\n\nexport interface FollowState {\n following: boolean;\n followedAt: string | null;\n target: FollowTarget;\n}\n\nexport interface FollowTarget {\n kind: 'CREATOR' | 'USER';\n displayName: string;\n avatarUrl: string | null;\n description: string | null;\n workCount: number;\n}\n\nexport type AccessReason =\n | 'PUBLIC'\n | 'OWNER'\n | 'FOLLOWING'\n | 'ENTITLED'\n | 'AUTH_REQUIRED'\n | 'FOLLOW_REQUIRED'\n | 'PURCHASE_REQUIRED'\n | 'FEATURE_NOT_FOUND'\n | 'FEATURE_DISABLED'\n | 'BUYER_REQUIRED'\n | 'FEATURE_NOT_READY'\n | 'PAYMENT_CHANNEL_UNAVAILABLE';\n\nexport interface AccessDecision {\n allowed: boolean;\n reason: AccessReason;\n nextAction: 'SIGN_IN' | 'FOLLOW' | 'CHECKOUT' | 'RESOLVE_BUYER' | null;\n}\n\nexport type AccessPolicyType = 'PUBLIC' | 'FOLLOW_OWNER' | 'WORK_ENTITLEMENT';\n\nexport interface AccessFeaturePresentation {\n featureKey: string;\n title: string;\n policy: { type: AccessPolicyType };\n price:\n | { amountCents: number; currency: 'CNY' }\n | { amountMinor: number; currency: 'CNY' | 'USD' }\n | null;\n status?: 'ACTIVE' | 'PENDING_CHANNEL' | 'DISABLED';\n pricingIntent?: { amountMinor: number; currency: 'CNY' | 'USD' } | null;\n}\n\nexport interface CheckoutOptions {\n featureKey: string;\n locale?: 'zh-CN' | 'en-US';\n}\n\nexport interface CheckoutResult {\n checkoutUrl: string;\n alreadyOwned: boolean;\n expiresAt: string | null;\n}\n\nexport interface AuthCapability {\n getState(): Promise<AuthState>;\n signIn(): Promise<AuthState>;\n signOut(): Promise<void>;\n}\n\nexport interface FollowCapability {\n getState(): Promise<FollowState>;\n follow(): Promise<FollowState>;\n unfollow(): Promise<FollowState>;\n}\n\nexport interface AccessCapability {\n getFeatures(): Promise<AccessFeaturePresentation[]>;\n check(featureKey: string): Promise<AccessDecision>;\n checkMany(featureKeys: string[]): Promise<Record<string, AccessDecision>>;\n require(featureKey: string): Promise<AccessDecision>;\n refresh(): Promise<void>;\n restorePurchase(featureKey: string): Promise<AccessDecision>;\n claimPurchase(featureKey: string): Promise<AccessDecision>;\n}\n\nexport interface CheckoutCapability {\n open(options: CheckoutOptions): Promise<CheckoutResult>;\n}\n\ninterface CapabilityDeps {\n session: SessionManager;\n workKey: string;\n widgetOrigin: string;\n now: () => number;\n presenter?: AccessPresenter;\n signal: AbortSignal;\n ready: () => Promise<void>;\n}\n\nfunction objectBody(value: unknown): Record<string, unknown> {\n if (typeof value !== 'object' || value === null) throw malformedResponse();\n return value as Record<string, unknown>;\n}\n\nfunction malformedResponse(): ViceMeError {\n return new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: 'Malformed public API response.',\n retryable: true,\n });\n}\n\nfunction parseUser(value: unknown): WorkUser {\n const body = objectBody(value);\n if (\n typeof body.id !== 'string' ||\n !(typeof body.displayName === 'string' || body.displayName === null) ||\n !(typeof body.avatarUrl === 'string' || body.avatarUrl === null)\n ) {\n throw malformedResponse();\n }\n return {\n subject: body.id,\n nickname: body.displayName,\n avatarUrl: body.avatarUrl,\n };\n}\n\nfunction parseFollowState(value: unknown): FollowState {\n const body = objectBody(value);\n if (\n typeof body.following !== 'boolean' ||\n !(typeof body.followedAt === 'string' || body.followedAt === null)\n ) {\n throw malformedResponse();\n }\n const target = objectBody(body.creator);\n if (\n typeof target.displayName !== 'string' ||\n !(typeof target.avatarUrl === 'string' || target.avatarUrl === null) ||\n !(typeof target.description === 'string' || target.description === null) ||\n !Number.isInteger(target.publishedWorkCount) ||\n (target.publishedWorkCount as number) < 0\n ) {\n throw malformedResponse();\n }\n return {\n following: body.following,\n followedAt: body.followedAt,\n target: {\n kind: 'CREATOR',\n displayName: target.displayName,\n avatarUrl: target.avatarUrl,\n description: target.description,\n workCount: target.publishedWorkCount as number,\n },\n };\n}\n\nfunction parseDecision(value: unknown, version?: 3): AccessDecision {\n const body = objectBody(value);\n const reasons = new Set<string>([\n 'PUBLIC',\n 'OWNER',\n 'FOLLOWING',\n 'ENTITLED',\n 'AUTH_REQUIRED',\n 'FOLLOW_REQUIRED',\n 'PURCHASE_REQUIRED',\n 'FEATURE_NOT_FOUND',\n 'FEATURE_DISABLED',\n ]);\n const actions = new Set<unknown>([null, 'SIGN_IN', 'FOLLOW', 'CHECKOUT']);\n if (version === 3) {\n reasons.add('BUYER_REQUIRED').add('FEATURE_NOT_READY').add('PAYMENT_CHANNEL_UNAVAILABLE');\n actions.add('RESOLVE_BUYER');\n }\n if (\n typeof body.allowed !== 'boolean' ||\n typeof body.reason !== 'string' ||\n !reasons.has(body.reason) ||\n !actions.has(body.nextAction)\n ) {\n throw malformedResponse();\n }\n return {\n allowed: body.allowed,\n reason: body.reason as AccessReason,\n nextAction: body.nextAction as AccessDecision['nextAction'],\n };\n}\n\nfunction parseFeaturePresentation(value: unknown, version?: 3): AccessFeaturePresentation {\n const body = objectBody(value);\n if (\n typeof body.featureKey !== 'string' ||\n !/^[a-z][a-z0-9_-]{1,63}$/.test(body.featureKey) ||\n typeof body.title !== 'string' ||\n body.title.trim().length === 0 ||\n body.title.length > 120 ||\n !(\n body.policyType === 'PUBLIC' ||\n body.policyType === 'FOLLOW_OWNER' ||\n body.policyType === 'WORK_ENTITLEMENT'\n )\n ) {\n throw malformedResponse();\n }\n const price = body.price === null ? null : objectBody(body.price);\n if (version === 3) {\n const parsePrice = (\n value: unknown,\n ): { amountMinor: number; currency: 'CNY' | 'USD' } | null => {\n if (value === null) return null;\n const money = objectBody(value);\n if (\n !Number.isSafeInteger(money.amountMinor) ||\n (money.amountMinor as number) <= 0 ||\n !(money.currency === 'CNY' || money.currency === 'USD')\n )\n throw malformedResponse();\n return { amountMinor: money.amountMinor as number, currency: money.currency };\n };\n if (body.status !== 'ACTIVE' && body.status !== 'PENDING_CHANNEL' && body.status !== 'DISABLED')\n throw malformedResponse();\n const parsedPrice = parsePrice(price);\n const pricingIntent = parsePrice(body.pricingIntent);\n if (\n (body.policyType !== 'WORK_ENTITLEMENT' &&\n (parsedPrice !== null || body.status === 'PENDING_CHANNEL')) ||\n (body.policyType === 'WORK_ENTITLEMENT' &&\n body.status === 'ACTIVE' &&\n parsedPrice === null) ||\n (body.status === 'PENDING_CHANNEL' && (parsedPrice !== null || pricingIntent === null))\n )\n throw malformedResponse();\n return {\n featureKey: body.featureKey,\n title: body.title,\n policy: { type: body.policyType },\n price: parsedPrice,\n status: body.status,\n pricingIntent,\n };\n }\n if (\n price !== null &&\n (!Number.isInteger(price.amountCents) ||\n (price.amountCents as number) <= 0 ||\n price.currency !== 'CNY')\n ) {\n throw malformedResponse();\n }\n if ((body.policyType === 'WORK_ENTITLEMENT') !== (price !== null)) {\n throw malformedResponse();\n }\n return {\n featureKey: body.featureKey,\n title: body.title,\n policy: { type: body.policyType },\n price: price === null ? null : { amountCents: price.amountCents as number, currency: 'CNY' },\n };\n}\n\nfunction randomVerifier(): string {\n const bytes = crypto.getRandomValues(new Uint8Array(32));\n return base64Url(bytes);\n}\n\nfunction base64Url(bytes: Uint8Array): string {\n let binary = '';\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary).replaceAll('+', '-').replaceAll('/', '_').replace(/=+$/, '');\n}\n\nfunction resolveLocale(): 'zh-CN' | 'en-US' {\n return typeof document !== 'undefined' && document.documentElement.lang.toLowerCase() === 'en-us'\n ? 'en-US'\n : 'zh-CN';\n}\n\nexport function createCapabilities(deps: CapabilityDeps): {\n auth: AuthCapability;\n follow: FollowCapability;\n access: AccessCapability;\n checkout: CheckoutCapability;\n} {\n const bridge = createAccessBridge(deps);\n const cancelled = () =>\n new ViceMeError({\n code: 'AUTH_CANCELLED',\n message: 'The interactive action was cancelled.',\n retryable: false,\n });\n\n const presentationAbortReason = (): Error =>\n deps.signal.reason instanceof Error ? deps.signal.reason : clientDestroyed();\n\n const present = (\n interaction: Omit<Parameters<AccessPresenter>[0], 'signal'>,\n ): ReturnType<AccessPresenter> => {\n if (deps.signal.aborted) return Promise.reject(presentationAbortReason());\n let onAbort: (() => void) | undefined;\n const cancellation = new Promise<never>((_resolve, reject) => {\n onAbort = () => reject(presentationAbortReason());\n deps.signal.addEventListener('abort', onAbort, { once: true });\n if (deps.signal.aborted) onAbort();\n });\n let presentation: ReturnType<AccessPresenter>;\n try {\n presentation = (deps.presenter ?? defaultAccessPresenter)({\n ...interaction,\n signal: deps.signal,\n });\n } catch (error) {\n presentation = Promise.reject(error);\n }\n return Promise.race([presentation, cancellation])\n .then((result) => {\n // The presenter may win the race immediately before its owner aborts.\n // Preserve the same caller-owned reason at this final delivery guard;\n // explicit client.destroy() already aborts with CLIENT_DESTROYED.\n if (deps.signal.aborted) throw presentationAbortReason();\n return result;\n })\n .finally(() => {\n if (onAbort) deps.signal.removeEventListener('abort', onAbort);\n });\n };\n\n const embeddedFrame = (\n url: string,\n completionOrigin: string,\n channel: string,\n type: 'auth',\n initialization: Record<string, unknown>,\n complete: (data: Record<string, unknown>) => Promise<void>,\n ): AccessFrameAction => {\n if (typeof window === 'undefined') {\n throw new ViceMeError({\n code: 'CONFIG_INVALID',\n message: 'Interactive access requires a browser window.',\n retryable: false,\n });\n }\n let active = true;\n let settle!: () => void;\n let fail!: (error: unknown) => void;\n const cleanup = () => {\n if (!active) return;\n active = false;\n window.removeEventListener('message', receive);\n };\n const completion = new Promise<void>((resolve, reject) => {\n settle = resolve;\n fail = reject;\n });\n const receive = (event: MessageEvent) => {\n if (!active || event.origin !== completionOrigin) return;\n if (typeof event.data !== 'object' || event.data === null) return;\n const data = event.data as Record<string, unknown>;\n if (data.workKey !== deps.workKey || data.channel !== channel) return;\n if (data.type === `viceme:${type}:ready`) {\n if (event.source && 'postMessage' in event.source) {\n (event.source as WindowProxy).postMessage(\n {\n type: `viceme:${type}:init`,\n workKey: deps.workKey,\n channel,\n ...initialization,\n },\n completionOrigin,\n );\n }\n return;\n }\n if (data.type === `viceme:${type}:cancelled`) {\n cleanup();\n fail(cancelled());\n return;\n }\n if (data.type !== `viceme:${type}:complete`) return;\n cleanup();\n void complete(data).then(settle, fail);\n };\n window.addEventListener('message', receive);\n return {\n type: 'frame',\n url,\n completion,\n cancel() {\n cleanup();\n settle();\n },\n };\n };\n\n const startSignIn = async (): Promise<AccessActionResult> => {\n await deps.ready();\n if (deps.session.snapshot?.accessProtocolVersion === 3) return bridge.start('SIGN_IN');\n if (typeof window === 'undefined') {\n throw new ViceMeError({\n code: 'CONFIG_INVALID',\n message: 'Interactive access requires a browser window.',\n retryable: false,\n });\n }\n const channel = randomVerifier();\n const authorizationUrl = new URL('/sdk/login', deps.widgetOrigin);\n authorizationUrl.search = new URLSearchParams({\n workKey: deps.workKey,\n channel,\n parentOrigin: window.location.origin,\n locale: resolveLocale(),\n }).toString();\n const workSessionToken = deps.session.snapshot?.token;\n if (!workSessionToken) throw malformedResponse();\n return embeddedFrame(\n authorizationUrl.toString(),\n deps.widgetOrigin,\n channel,\n 'auth',\n { workSessionToken },\n async (data) => {\n if (typeof data.userToken !== 'string') {\n throw malformedResponse();\n }\n deps.session.authenticate({ userToken: data.userToken, user: parseUser(data.user) });\n },\n );\n };\n\n const getFollowState = async (): Promise<FollowState> => {\n await deps.ready();\n return parseFollowState(\n (await deps.session.request({ method: 'GET', path: '/v1/public/work-sdk/follow' })).body,\n );\n };\n\n const updateFollow = async (): Promise<FollowState> => {\n await deps.ready();\n return parseFollowState(\n (await deps.session.request({ method: 'PUT', path: '/v1/public/work-sdk/follow' })).body,\n );\n };\n\n const signInPresentation = (): Pick<AccessInteraction, 'followTarget' | 'work'> => {\n const descriptor = deps.session.snapshot?.work;\n return {\n ...(descriptor?.creator\n ? {\n followTarget: {\n kind: 'CREATOR' as const,\n displayName: descriptor.creator.displayName,\n avatarUrl: descriptor.creator.avatarUrl,\n description: null,\n workCount: descriptor.creator.publishedWorkCount,\n },\n }\n : {}),\n ...(descriptor?.details ? { work: descriptor.details } : {}),\n };\n };\n\n const auth: AuthCapability = {\n async getState() {\n await deps.ready();\n const user = deps.session.snapshot?.user ?? null;\n return { authenticated: user !== null, user };\n },\n async signIn() {\n await deps.ready();\n const result = await present({\n featureKey: 'auth',\n reason: 'AUTH_REQUIRED',\n action: 'SIGN_IN',\n autoStart: deps.session.snapshot?.accessProtocolVersion === 3,\n ...signInPresentation(),\n perform: startSignIn,\n });\n if (result === 'dismissed') throw cancelled();\n return this.getState();\n },\n async signOut() {\n await deps.ready();\n bridge.clear();\n await deps.session.signOut();\n },\n };\n\n const follow: FollowCapability = {\n getState: getFollowState,\n follow: updateFollow,\n unfollow: async () => {\n throw new ViceMeError({\n code: 'CAPABILITY_DISABLED',\n message: 'Unfollow is not exposed by website access.',\n retryable: false,\n });\n },\n };\n\n const checkMany = async (featureKeys: string[]): Promise<Record<string, AccessDecision>> => {\n await deps.ready();\n const response = objectBody(\n (\n await deps.session.request({\n method: 'POST',\n path: '/v1/public/work-sdk/access/check',\n body: { featureKeys },\n })\n ).body,\n );\n const raw = objectBody(response.decisions);\n return Object.fromEntries(\n Object.entries(raw).map(([key, value]) => [\n key,\n parseDecision(value, deps.session.snapshot?.accessProtocolVersion),\n ]),\n );\n };\n\n const createCheckout = async (\n featureKey: string,\n options: Omit<CheckoutOptions, 'featureKey'> = {},\n ): Promise<CheckoutResult> => {\n await deps.ready();\n const body = {\n featureKey,\n locale:\n options.locale ??\n (deps.session.snapshot?.accessProtocolVersion === 3 ? resolveLocale() : 'zh-CN'),\n ...(deps.session.snapshot?.accessProtocolVersion === 3 &&\n typeof window !== 'undefined' &&\n /^https?:$/.test(window.location.protocol)\n ? { returnUrl: window.location.href }\n : {}),\n };\n const response = objectBody(\n (\n await deps.session.request({\n method: 'POST',\n path: '/v1/public/work-sdk/checkout',\n body,\n })\n ).body,\n );\n if (\n typeof response.checkoutUrl !== 'string' ||\n typeof response.alreadyOwned !== 'boolean' ||\n !(\n response.expiresAt === null ||\n (typeof response.expiresAt === 'string' && !Number.isNaN(Date.parse(response.expiresAt)))\n ) ||\n response.alreadyOwned !== (response.expiresAt === null)\n ) {\n throw malformedResponse();\n }\n let checkoutUrl: URL;\n try {\n checkoutUrl = new URL(response.checkoutUrl);\n } catch {\n throw malformedResponse();\n }\n if (\n !response.alreadyOwned &&\n (checkoutUrl.protocol !== 'https:' || checkoutUrl.origin !== deps.widgetOrigin)\n ) {\n throw malformedResponse();\n }\n return {\n checkoutUrl: response.checkoutUrl,\n alreadyOwned: response.alreadyOwned,\n expiresAt: response.expiresAt,\n };\n };\n\n const openCheckout = (result: CheckoutResult, featureKey: string): AccessActionResult => {\n if (result.alreadyOwned) return { type: 'completed' };\n const expiresAt = Date.parse(result.expiresAt!);\n if (typeof window === 'undefined') {\n throw new ViceMeError({\n code: 'CONFIG_INVALID',\n message: 'Hosted checkout requires a browser window.',\n retryable: false,\n });\n }\n\n let active = true;\n let pollTimer: ReturnType<typeof setTimeout> | undefined;\n let expiryTimer: ReturnType<typeof setTimeout> | undefined;\n let settle!: () => void;\n let fail!: (error: unknown) => void;\n const completion = new Promise<void>((resolve, reject) => {\n settle = resolve;\n fail = reject;\n });\n const cleanup = () => {\n if (pollTimer) clearTimeout(pollTimer);\n if (expiryTimer) clearTimeout(expiryTimer);\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n };\n const expire = () => {\n if (!active) return;\n active = false;\n cleanup();\n fail(\n new ViceMeError({\n code: 'SESSION_EXPIRED',\n message: 'Hosted checkout session expired.',\n retryable: true,\n }),\n );\n };\n const schedule = () => {\n if (!active || document.visibilityState === 'hidden') return;\n const remaining = expiresAt - deps.now();\n if (remaining <= 0) {\n expire();\n return;\n }\n pollTimer = setTimeout(() => void poll(), Math.min(1_500, remaining));\n };\n const poll = async () => {\n if (!active) return;\n try {\n const decision = (await checkMany([featureKey]))[featureKey];\n if (!decision) throw malformedResponse();\n if (decision.allowed) {\n active = false;\n cleanup();\n settle();\n return;\n }\n schedule();\n } catch (error) {\n active = false;\n cleanup();\n fail(error);\n }\n };\n function handleVisibilityChange() {\n if (!active) return;\n if (document.visibilityState === 'hidden') {\n if (pollTimer) clearTimeout(pollTimer);\n pollTimer = undefined;\n return;\n }\n schedule();\n }\n document.addEventListener('visibilitychange', handleVisibilityChange);\n const remaining = expiresAt - deps.now();\n if (remaining <= 0) expire();\n else {\n expiryTimer = setTimeout(expire, remaining);\n schedule();\n }\n return {\n type: 'frame',\n url: result.checkoutUrl,\n completion,\n cancel() {\n if (!active) return;\n active = false;\n cleanup();\n settle();\n },\n };\n };\n\n const checkout: CheckoutCapability = {\n async open(options) {\n await deps.ready();\n if (deps.session.snapshot?.accessProtocolVersion === 3) {\n const decision = (await checkMany([options.featureKey]))[options.featureKey];\n if (!decision) throw malformedResponse();\n if (decision.nextAction === 'RESOLVE_BUYER') {\n const result = await present({\n featureKey: options.featureKey,\n reason: decision.reason,\n action: 'RESOLVE_BUYER',\n autoStart: true,\n perform: () => bridge.start('IDENTIFY', options.featureKey),\n });\n if (result === 'dismissed') throw cancelled();\n } else if (!decision.allowed && decision.nextAction !== 'CHECKOUT') {\n throw new ViceMeError({\n code: 'CHECKOUT_UNAVAILABLE',\n message: 'Checkout is not available for this feature.',\n retryable: false,\n });\n }\n }\n const checkoutResult = await createCheckout(options.featureKey, options);\n if (checkoutResult.alreadyOwned) return checkoutResult;\n const presented = await present({\n featureKey: options.featureKey,\n reason: 'PURCHASE_REQUIRED',\n action: 'CHECKOUT',\n autoStart: deps.session.snapshot?.accessProtocolVersion === 3,\n perform: async () => openCheckout(checkoutResult, options.featureKey),\n });\n if (presented === 'dismissed') throw cancelled();\n return checkoutResult;\n },\n };\n\n const access: AccessCapability = {\n async getFeatures() {\n await deps.ready();\n const response = objectBody(\n (\n await deps.session.request({\n method: 'GET',\n path: '/v1/public/work-sdk/access/features',\n })\n ).body,\n );\n if (!Array.isArray(response.features) || response.features.length > 100) {\n throw malformedResponse();\n }\n return response.features.map((feature) =>\n parseFeaturePresentation(feature, deps.session.snapshot?.accessProtocolVersion),\n );\n },\n async check(featureKey) {\n const decisions = await checkMany([featureKey]);\n const decision = decisions[featureKey];\n if (!decision) throw malformedResponse();\n return decision;\n },\n checkMany,\n async require(featureKey) {\n let decision = await this.check(featureKey);\n const stages = new Set<string>();\n for (\n let attempts = 0;\n !decision.allowed && decision.nextAction && attempts < 6;\n attempts += 1\n ) {\n const nextAction = decision.nextAction;\n const stage = `${decision.reason}:${nextAction}`;\n if (stages.has(stage)) return decision;\n stages.add(stage);\n if (nextAction === 'FOLLOW' && deps.session.snapshot?.accessProtocolVersion === 3) {\n await follow.follow();\n decision = await this.check(featureKey);\n continue;\n }\n const followTarget = nextAction === 'FOLLOW' ? (await follow.getState()).target : undefined;\n const checkoutResult =\n nextAction === 'CHECKOUT' ? await createCheckout(featureKey) : undefined;\n if (checkoutResult?.alreadyOwned) {\n decision = await this.check(featureKey);\n continue;\n }\n const result = await present({\n featureKey,\n reason: decision.reason,\n action: nextAction,\n autoStart: deps.session.snapshot?.accessProtocolVersion === 3,\n ...(nextAction === 'SIGN_IN'\n ? signInPresentation()\n : followTarget\n ? { followTarget }\n : {}),\n perform: async () => {\n if (nextAction === 'SIGN_IN') {\n return startSignIn();\n } else if (nextAction === 'RESOLVE_BUYER') {\n return bridge.start('IDENTIFY', featureKey);\n } else if (nextAction === 'FOLLOW') {\n await follow.follow();\n return { type: 'completed' };\n } else {\n return openCheckout(checkoutResult!, featureKey);\n }\n },\n });\n if (result === 'dismissed') return decision;\n decision = await this.check(featureKey);\n }\n return decision;\n },\n async refresh() {\n await deps.ready();\n },\n restorePurchase: (featureKey) => resolvePurchase('RESTORE', featureKey),\n claimPurchase: (featureKey) => resolvePurchase('CLAIM', featureKey),\n };\n\n async function resolvePurchase(\n purpose: AccessBridgePurpose,\n featureKey: string,\n ): Promise<AccessDecision> {\n await deps.ready();\n if (deps.session.snapshot?.accessProtocolVersion !== 3) {\n throw new ViceMeError({\n code: 'CAPABILITY_DISABLED',\n message: 'This website has not enabled purchase recovery.',\n retryable: false,\n });\n }\n const result = await present({\n featureKey,\n reason: 'BUYER_REQUIRED',\n action: 'RESOLVE_BUYER',\n autoStart: true,\n perform: () => bridge.start(purpose, featureKey),\n });\n if (result === 'dismissed') throw cancelled();\n return access.check(featureKey);\n }\n\n return { auth, follow, access, checkout };\n}\n","/**\n * ViceMe client for hosted capabilities and optional website access.\n *\n * `ready()` and access checks remain headless. Interactive authentication and\n * checkout touch `window` only when the caller explicitly invokes them. `ready()` is\n * Hosted capability initialization stays local and synchronous. Website\n * access establishes its Work session lazily on the first access operation.\n * `ready()` is idempotent per instance (shares one promise), `destroy()` is idempotent and\n * synchronously cancels requests and subscriptions; every business method on a\n * destroyed client fails with `CLIENT_DESTROYED`.\n */\n\nimport { clientDestroyed } from './errors.ts';\nimport { Lifecycle, type ViceMeClientState } from './lifecycle.ts';\nimport type { ViceMeConfig, ViceMeRegion } from './config.ts';\nimport { SessionManager } from '../session/session.ts';\nimport type { Transport } from '../transport/transport.ts';\nimport { API_MAJOR, SDK_VERSION } from '../version.ts';\nimport {\n createCapabilities,\n type AccessCapability,\n type AuthCapability,\n type CheckoutCapability,\n} from './capabilities.ts';\nimport type { AccessPresenter } from './presentation.ts';\nimport { BUILD_WIDGET_ORIGINS } from './build-endpoints.ts';\n\nexport interface ViceMeClient {\n readonly version: string;\n readonly workKey: string;\n readonly region: ViceMeRegion;\n readonly state: ViceMeClientState;\n readonly auth: AuthCapability;\n readonly access: AccessCapability;\n readonly checkout: CheckoutCapability;\n ready(): Promise<void>;\n hasCapability(name: string): boolean;\n destroy(): void;\n}\n\nexport interface ViceMeMountedInstance {\n readonly instanceKey: string;\n readonly capability: string;\n destroy(): void;\n}\n\n/** Internal loader hook; keeps degradation outside the public client contract. */\nexport function markClientDegraded(client: ViceMeClient): void {\n if (client instanceof ViceMeClientImpl) client.markDegraded();\n}\n\nexport interface ViceMeClientDeps {\n config: ViceMeConfig;\n transport: Transport;\n /** Interaction override for the testing entry only. */\n presenter?: AccessPresenter;\n /** Injectable clock (testing only). */\n now?: () => number;\n}\n\nexport class ViceMeClientImpl implements ViceMeClient {\n readonly #lifecycle = new Lifecycle();\n readonly #session: SessionManager;\n readonly #config: ViceMeConfig;\n readonly #internalSignal = new AbortController();\n #readyPromise: Promise<void> | undefined;\n readonly auth: AuthCapability;\n readonly access: AccessCapability;\n readonly checkout: CheckoutCapability;\n /** Detaches the caller-signal listener; undefined when none was attached. */\n #detachCallerAbort: (() => void) | undefined;\n\n constructor(deps: ViceMeClientDeps) {\n this.#config = deps.config;\n this.#session = new SessionManager({\n workKey: deps.config.workKey,\n region: deps.config.region,\n transport: deps.transport,\n signal: this.#internalSignal.signal,\n ...(deps.now !== undefined ? { now: deps.now } : {}),\n });\n const capabilities = createCapabilities({\n session: this.#session,\n workKey: deps.config.workKey,\n widgetOrigin: BUILD_WIDGET_ORIGINS[deps.config.region],\n now: deps.now ?? (() => Date.now()),\n presenter: deps.presenter,\n signal: this.#internalSignal.signal,\n ready: () => this.#readyAccess(),\n });\n this.auth = capabilities.auth;\n this.access = capabilities.access;\n this.checkout = capabilities.checkout;\n const callerSignal = deps.config.signal;\n if (callerSignal) {\n // Propagate the caller's own abort reason when one was set.\n const abortInternal = () => {\n this.#internalSignal.abort(\n callerSignal.reason instanceof Error\n ? callerSignal.reason\n : new DOMException('Caller signal aborted.', 'AbortError'),\n );\n };\n // An already-aborted signal never fires the listener; check\n // synchronously so a pre-cancelled caller cannot issue session\n // requests or reach the network at all.\n if (callerSignal.aborted) abortInternal();\n else {\n callerSignal.addEventListener('abort', abortInternal, { once: true });\n this.#detachCallerAbort = () => {\n callerSignal.removeEventListener('abort', abortInternal);\n };\n }\n }\n }\n\n get version(): string {\n return SDK_VERSION;\n }\n\n get workKey(): string {\n return this.#config.workKey;\n }\n\n get region(): ViceMeRegion {\n return this.#config.region;\n }\n\n get state(): ViceMeClientState {\n return this.#lifecycle.state;\n }\n\n /** Internal: public API major, used by the loader registry namespace. */\n get apiMajor(): number {\n return API_MAJOR;\n }\n\n ready(): Promise<void> {\n if (this.#lifecycle.destroyed) return Promise.reject(clientDestroyed());\n if (!this.#readyPromise) {\n this.#lifecycle.transition('READY');\n this.#readyPromise = Promise.resolve();\n }\n return this.#readyPromise;\n }\n\n async #readyAccess(): Promise<void> {\n if (this.#lifecycle.destroyed) throw clientDestroyed();\n await this.ready();\n try {\n await this.#session.establish();\n if (this.#lifecycle.destroyed) throw clientDestroyed();\n } catch (error) {\n if (this.#lifecycle.destroyed) throw clientDestroyed();\n this.#session.invalidate();\n throw error;\n }\n }\n\n hasCapability(name: string): boolean {\n if (this.#lifecycle.destroyed) return false;\n const capabilities = this.#session.snapshot?.work.capabilities;\n return name === 'danmaku' || name === 'tip' || capabilities?.includes(name) === true;\n }\n\n /** Names of capabilities enabled for this work (empty before `ready()`). */\n get capabilities(): readonly string[] {\n return this.#session.snapshot?.work.capabilities ?? [];\n }\n\n /**\n * Internal: mark one capability unavailable without taking down the client\n * (loader uses this when a feature chunk fails after the core is READY).\n */\n markDegraded(): void {\n if (this.#lifecycle.state === 'READY') this.#lifecycle.transition('DEGRADED');\n }\n\n /** Internal: session snapshot access for capability modules. */\n get sessionSnapshot() {\n return this.#session.snapshot;\n }\n\n destroy(): void {\n if (this.#lifecycle.destroyed) return;\n this.#lifecycle.transition('DESTROYED');\n // The shared signal also owns interactive presentation work. Use the\n // public lifecycle error as its reason so every consumer can distinguish\n // explicit client destruction from a caller-owned abort reason.\n this.#internalSignal.abort(clientDestroyed());\n this.#session.destroy();\n this.#lifecycle.clearListeners();\n this.#readyPromise = undefined;\n // A destroyed client must not stay reachable through the caller's own\n // (possibly long-lived, never-aborting) signal.\n this.#detachCallerAbort?.();\n this.#detachCallerAbort = undefined;\n }\n}\n","/**\n * HTTP transport for the public API.\n *\n * Responsibilities: request execution with timeout, abort, client request ids,\n * and normalization of every failure into the public `ViceMeError` model.\n * Capabilities and the loader never build their own `fetch` calls — they go\n * through a Transport so tests can swap in `createMemoryTransport`.\n */\n\nimport { ViceMeError, type ViceMeErrorCode } from '../core/errors.ts';\n\nexport interface TransportRequest {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\n /** Absolute path under the public API base. */\n path: string;\n /** JSON-serializable request body. */\n body?: unknown;\n /** Work-session token. It is never persisted by the transport. */\n authorization?: string;\n /** Optional memory-only signed-in widget token. */\n userAuthorization?: string;\n /** Optional memory-only, Work-scoped anonymous purchase authorization. */\n buyerAuthorization?: string;\n signal?: AbortSignal;\n /** Per-request timeout; defaults to the transport default. */\n timeoutMs?: number;\n}\n\nexport interface TransportResponse {\n status: number;\n body?: unknown;\n /** Echoed server request id, when provided. */\n requestId?: string;\n}\n\nexport interface Transport {\n request(request: TransportRequest): Promise<TransportResponse>;\n}\n\nexport interface FetchTransportOptions {\n apiBaseUrl: string;\n /** Injectable for tests; defaults to global `fetch`. */\n fetchImpl?: typeof fetch;\n defaultTimeoutMs?: number;\n /** Injectable id generator (default: `crypto.randomUUID`). */\n generateRequestId?: () => string;\n}\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nconst STATUS_CODE_MAP: ReadonlyMap<number, ViceMeErrorCode> = new Map([\n [400, 'CONFIG_INVALID'],\n [401, 'SESSION_EXPIRED'],\n [403, 'CAPABILITY_DISABLED'],\n [404, 'WORK_NOT_FOUND'],\n [409, 'CONFIG_INVALID'],\n [422, 'CONFIG_INVALID'],\n [429, 'RATE_LIMITED'],\n]);\n\nconst KNOWN_CODES: ReadonlySet<string> = new Set([\n 'CONFIG_INVALID',\n 'WORK_NOT_FOUND',\n 'CAPABILITY_DISABLED',\n 'SESSION_EXPIRED',\n 'AUTH_REQUIRED',\n 'AUTH_CANCELLED',\n 'RETURN_URL_NOT_ALLOWED',\n 'RATE_LIMITED',\n 'NETWORK_TIMEOUT',\n 'CHECKOUT_UNAVAILABLE',\n 'INTERNAL_ERROR',\n]);\n\n/** Extract a stable error payload from a JSON error body, if well-formed. */\nfunction parseErrorBody(body: unknown): {\n code?: ViceMeErrorCode;\n message?: string;\n retryable?: boolean;\n requestId?: string;\n} {\n if (typeof body !== 'object' || body === null) return {};\n const raw = body as Record<string, unknown>;\n const candidate =\n typeof raw.error === 'object' && raw.error !== null\n ? (raw.error as Record<string, unknown>)\n : raw;\n const result: {\n code?: ViceMeErrorCode;\n message?: string;\n retryable?: boolean;\n requestId?: string;\n } = {};\n if (typeof candidate.code === 'string' && KNOWN_CODES.has(candidate.code)) {\n result.code = candidate.code as ViceMeErrorCode;\n }\n if (typeof candidate.message === 'string') {\n result.message = candidate.message.slice(0, 200);\n }\n if (typeof candidate.retryable === 'boolean') {\n result.retryable = candidate.retryable;\n }\n if (typeof candidate.requestId === 'string') {\n result.requestId = candidate.requestId;\n }\n return result;\n}\n\nfunction defaultRequestId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return `req-${Math.random().toString(36).slice(2)}`;\n}\n\nexport class FetchTransport implements Transport {\n readonly #apiBaseUrl: string;\n readonly #fetchImpl: typeof fetch;\n readonly #defaultTimeoutMs: number;\n readonly #generateRequestId: () => string;\n\n constructor(options: FetchTransportOptions) {\n this.#apiBaseUrl = options.apiBaseUrl.replace(/\\/+$/, '');\n this.#fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);\n this.#defaultTimeoutMs = options.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.#generateRequestId = options.generateRequestId ?? defaultRequestId;\n }\n\n async request(request: TransportRequest): Promise<TransportResponse> {\n // A pre-aborted signal must never reach the network. Preserve the\n // caller's abort reason when one was set.\n if (request.signal?.aborted) {\n throw this.#callerAbortError(request.signal);\n }\n const timeoutMs = request.timeoutMs ?? this.#defaultTimeoutMs;\n const controller = new AbortController();\n // Engine notes: Chrome/Firefox reject fetch with the abort reason and\n // WebKit may reject with a plain error — so timeout/abort classification\n // keys off our own timer/signal state, never off the exception shape.\n let timedOut = false;\n const timer = setTimeout(() => {\n timedOut = true;\n controller.abort(new TimeoutAbort());\n }, timeoutMs);\n const onOuterAbort = () => controller.abort(new TimeoutAbort(false));\n request.signal?.addEventListener('abort', onOuterAbort, { once: true });\n\n const requestId = this.#generateRequestId();\n try {\n const response = await this.#fetchImpl(`${this.#apiBaseUrl}${request.path}`, {\n method: request.method,\n // Public API is CORS-only; credentials must stay off so Shop session\n // cookies can never attach to public SDK requests.\n credentials: 'omit',\n mode: 'cors',\n headers: {\n 'content-type': 'application/json',\n 'x-client-request-id': requestId,\n ...(request.authorization !== undefined\n ? { authorization: `Bearer ${request.authorization}` }\n : {}),\n ...(request.userAuthorization !== undefined\n ? { 'x-viceme-user-token': request.userAuthorization }\n : {}),\n ...(request.buyerAuthorization !== undefined\n ? { 'x-viceme-buyer-token': request.buyerAuthorization }\n : {}),\n },\n body: request.body !== undefined ? JSON.stringify(request.body) : undefined,\n signal: controller.signal,\n });\n\n // Body reading stays inside the same timeout/abort lifecycle: a server\n // that returns headers and then stalls the body still hits\n // NETWORK_TIMEOUT, caller abort still cancels the read, and a late\n // body can never outlive a destroyed client/session.\n let body: unknown;\n try {\n body = await response.json();\n } catch (error) {\n // A malformed/empty body is tolerated; a cancelled read must\n // propagate so the outer handler can classify it.\n if (request.signal?.aborted || timedOut) {\n throw error;\n }\n body = undefined;\n }\n\n // A fulfilled body promise cannot be rejected by abort(). Recheck before\n // delivering it so cancellation between parsing and this continuation\n // cannot turn into a successful request or a cached Work session.\n if (controller.signal.aborted) throw controller.signal.reason;\n\n const serverRequestId = response.headers.get('x-request-id') ?? undefined;\n if (!response.ok) {\n const parsed = parseErrorBody(body);\n const code = parsed.code ?? STATUS_CODE_MAP.get(response.status) ?? 'INTERNAL_ERROR';\n throw new ViceMeError({\n code,\n message: parsed.message ?? 'Public API request failed.',\n retryable: parsed.retryable,\n requestId: parsed.requestId ?? serverRequestId,\n });\n }\n return { status: response.status, body, requestId: serverRequestId };\n } catch (cause) {\n if (request.signal?.aborted) {\n throw this.#callerAbortError(request.signal);\n }\n if (timedOut) {\n throw new ViceMeError({\n code: 'NETWORK_TIMEOUT',\n message: 'Public API request timed out.',\n retryable: true,\n requestId,\n });\n }\n // Non-OK statuses already carry a normalized error — pass it through.\n if (cause instanceof ViceMeError) {\n throw cause;\n }\n if (cause instanceof DOMException && cause.name === 'AbortError') {\n throw new DOMException('ViceMe request aborted by caller.', 'AbortError');\n }\n throw new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: 'Public API request failed.',\n retryable: true,\n requestId,\n });\n } finally {\n clearTimeout(timer);\n request.signal?.removeEventListener('abort', onOuterAbort);\n }\n }\n\n /** Caller-abort error that preserves the caller's own abort reason. */\n #callerAbortError(signal: AbortSignal): unknown {\n return signal.reason instanceof Error\n ? signal.reason\n : new DOMException('ViceMe request aborted by caller.', 'AbortError');\n }\n}\n\nexport function createFetchTransport(options: FetchTransportOptions): Transport {\n return new FetchTransport(options);\n}\n\n/** Internal marker distinguishing timeout aborts from caller aborts. */\nclass TimeoutAbort extends DOMException {\n constructor(timedOut = true) {\n super(timedOut ? 'ViceMe request timed out.' : 'ViceMe request aborted.', 'AbortError');\n }\n}\n","/**\n * `@viceme-ai/sdk` public entry.\n *\n * Production consumers get `createViceMe` plus public types. Test injection\n * lives under `@viceme-ai/sdk/testing`.\n */\n\nimport { createFetchTransport } from './transport/transport.ts';\nimport { resolveApiBaseUrl, validatePublicConfig } from './core/config.ts';\nimport { ViceMeClientImpl } from './core/client.ts';\nimport { ViceMeError, isViceMeError, type ViceMeErrorCode } from './core/errors.ts';\nimport type { ViceMeClient, ViceMeMountedInstance } from './core/client.ts';\nimport type { ViceMeRegion, ViceMeConfig } from './core/config.ts';\nimport type { ViceMeClientState } from './core/lifecycle.ts';\nimport type {\n AccessCapability,\n AccessDecision,\n AccessFeaturePresentation,\n AccessPolicyType,\n AccessReason,\n AuthCapability,\n AuthState,\n CheckoutCapability,\n CheckoutOptions,\n CheckoutResult,\n} from './core/capabilities.ts';\nimport type { WorkUser } from './session/session.ts';\nimport { SDK_VERSION, API_MAJOR } from './version.ts';\n\nexport { ViceMeError, isViceMeError, SDK_VERSION, API_MAJOR, resolveApiBaseUrl };\nexport type {\n ViceMeClient,\n ViceMeMountedInstance,\n ViceMeConfig,\n ViceMeRegion,\n ViceMeClientState,\n ViceMeErrorCode,\n AccessCapability,\n AccessDecision,\n AccessFeaturePresentation,\n AccessPolicyType,\n AccessReason,\n AuthCapability,\n AuthState,\n CheckoutCapability,\n CheckoutOptions,\n CheckoutResult,\n WorkUser,\n};\n\n/**\n * Create a ViceMe client for one Work. Hosted capabilities initialize locally;\n * website access establishes a short-lived Work session only when used.\n *\n * @example\n * ```ts\n * const client = createViceMe({ workKey: 'wrk_live_demo', region: 'cn' });\n * await client.ready();\n * client.destroy();\n * ```\n */\nexport function createViceMe(config: unknown): ViceMeClient {\n const validated = validatePublicConfig(config);\n const apiBaseUrl = resolveApiBaseUrl(validated.region);\n const transport = createFetchTransport({\n apiBaseUrl,\n });\n return new ViceMeClientImpl({ config: validated, transport });\n}\n","/**\n * CDN auto-loader (`viceme.min.js`, IIFE).\n *\n * Deterministic algorithm (fixed baseline):\n *\n * 1. Read `document.currentScript`; when unavailable, accept exactly one\n * explicit `script[data-viceme-loader]`.\n * 2. Parse and validate `data-viceme-*`; build `clientKey` and per-feature\n * `instanceKey`s.\n * 3. Wait for DOM ready; a missing/ambiguous target emits `CONFIG_INVALID`\n * and never creates phantom nodes.\n * 4. Read `manifest.json` from the loader's own directory (exact release\n * version; URLs are never assembled from page parameters).\n * 5. Create the local client embedded in this loader, then load the\n * requested same-version capability chunks declared by the manifest.\n * 6. Mount; handles land in an internal registry.\n * 7. Re-running the same instance key returns the original handle — no\n * duplicate clients, subscriptions, or DOM.\n * 8. A failing mount keeps the host page working and degrades only its client.\n * 9. `pagehide` never auto-destroys (bfcache); cleanup happens on explicit\n * `destroy()` only.\n *\n * The loader never writes localStorage, cookies, global CSS, or globals other\n * than the fixed `window.ViceMe.versions.vN` namespace.\n */\n\nimport { parseLoaderAttributes, type LoaderAttributes, type LoaderFeature } from './attributes.ts';\nimport { LoaderRegistry, clientKeyOf, type RegisteredInstance } from './registry.ts';\nimport type { CapabilityMountHandle, CapabilityMountFunction } from '../capability-mount.ts';\nimport { dispatchViceMeEvent, type VicemeErrorDetail } from '../browser-events.ts';\nimport { clientDestroyed, configInvalid, ViceMeError } from '../core/errors.ts';\nimport {\n markClientDegraded,\n type ViceMeClient,\n type ViceMeMountedInstance,\n} from '../core/client.ts';\nimport { createViceMe } from '../index.ts';\nimport { API_MAJOR, SDK_VERSION } from '../version.ts';\n\nexport interface ReleaseManifest {\n version: string;\n apiMajor: number;\n loader: string;\n features: Record<string, string>;\n}\n\nexport interface ViceMeLoaderNamespaceV1 {\n readonly version: string;\n whenReady(clientKey: string): Promise<ViceMeClient>;\n getInstance(instanceKey: string): ViceMeMountedInstance | undefined;\n destroyInstance(instanceKey: string): void;\n destroyClient(clientKey: string): void;\n}\n\nexport interface ViceMeBrowserGlobal {\n versions: {\n // Other majors coexist; they are never overwritten by this loader.\n [major: string]: ViceMeLoaderNamespaceV1 | undefined;\n };\n}\n\nconst MANIFEST_TIMEOUT_MS = 8_000;\nconst CAPABILITY_MOUNT_TIMEOUT_MS = 8_000;\nconst FEATURE_PATHS: Readonly<Record<LoaderFeature, string>> = {\n danmaku: 'danmaku.js',\n tip: 'tip.js',\n};\nconst MOUNT_EXPORTS: Readonly<Record<LoaderFeature, 'mountDanmaku' | 'mountTip'>> = {\n danmaku: 'mountDanmaku',\n tip: 'mountTip',\n};\n\ninterface LoaderSharedState {\n registry: LoaderRegistry;\n /** Serialized run queue shared across every execution of this loader. */\n queue: { current: Promise<void> };\n}\n\nconst STATE_KEY = Symbol.for('viceme.loader.state.v1');\n\n/**\n * Loader state must survive multiple executions of the same (or an identical)\n * loader `<script>`: browsers execute each script tag as an independent IIFE,\n * so the registry and run queue live on a hidden, symbol-keyed, non-enumerable\n * global — never an undeclared string-named global.\n */\nfunction sharedState(): LoaderSharedState {\n const holder = globalThis as Record<symbol, unknown>;\n const existing = holder[STATE_KEY] as LoaderSharedState | undefined;\n if (existing) return existing;\n const state: LoaderSharedState = {\n registry: new LoaderRegistry(),\n queue: { current: Promise.resolve() },\n };\n Object.defineProperty(globalThis, STATE_KEY, {\n value: state,\n writable: true,\n configurable: true,\n enumerable: false,\n });\n return state;\n}\n\n/* ------------------------------------------------------------------ */\n/* Instance wrapper + destroy */\n/* ------------------------------------------------------------------ */\n\nfunction destroyInstanceInternal(instance: RegisteredInstance): void {\n if (instance.destroyed) return;\n instance.destroyed = true;\n sharedState().registry.removeInstance(instance.instanceKey);\n try {\n instance.raw.destroy();\n } finally {\n dispatchViceMeEvent(instance.host, 'viceme:destroyed', {\n clientKey: instance.clientKey,\n instanceKey: instance.instanceKey,\n capability: instance.capability,\n });\n }\n}\n\nfunction wrapInstance(instance: RegisteredInstance): ViceMeMountedInstance {\n return {\n instanceKey: instance.instanceKey,\n capability: instance.capability,\n destroy: () => destroyInstanceInternal(instance),\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Namespace installation */\n/* ------------------------------------------------------------------ */\n\nfunction defineHidden(target: object, key: string, value: unknown): void {\n Object.defineProperty(target, key, {\n value,\n writable: true,\n configurable: true,\n enumerable: false,\n });\n}\n\nexport function ensureNamespace(version: string): ViceMeLoaderNamespaceV1 {\n const holder = globalThis as { ViceMe?: ViceMeBrowserGlobal };\n let global = holder.ViceMe;\n if (!global) {\n global = {} as ViceMeBrowserGlobal;\n defineHidden(globalThis, 'ViceMe', global);\n }\n let versions = global.versions;\n if (!versions) {\n versions = {} as ViceMeBrowserGlobal['versions'];\n defineHidden(global, 'versions', versions);\n }\n const existing = versions[`v${API_MAJOR}`];\n if (existing) return existing;\n\n const namespace: ViceMeLoaderNamespaceV1 = {\n version,\n whenReady(clientKey: string): Promise<ViceMeClient> {\n const entry = sharedState().registry.getClient(clientKey);\n if (!entry) {\n return Promise.reject(configInvalid(`Unknown clientKey \"${clientKey}\".`));\n }\n return entry.ready.then(() => entry.client);\n },\n getInstance(instanceKey: string): ViceMeMountedInstance | undefined {\n const instance = sharedState().registry.getInstance(instanceKey);\n return instance ? wrapInstance(instance) : undefined;\n },\n destroyInstance(instanceKey: string): void {\n const instance = sharedState().registry.getInstance(instanceKey);\n if (instance) destroyInstanceInternal(instance);\n },\n destroyClient(clientKey: string): void {\n for (const instance of sharedState().registry.instancesForClient(clientKey)) {\n destroyInstanceInternal(instance);\n }\n const entry = sharedState().registry.getClient(clientKey);\n for (const controller of entry?.pendingMounts ?? []) controller.abort();\n sharedState().registry.unregisterClient(clientKey);\n entry?.client.destroy();\n },\n };\n defineHidden(versions, `v${API_MAJOR}`, namespace);\n return namespace;\n}\n\n/* ------------------------------------------------------------------ */\n/* Loader algorithm */\n/* ------------------------------------------------------------------ */\n\nfunction whenDomReady(): Promise<void> {\n if (document.readyState !== 'loading') return Promise.resolve();\n return new Promise((resolve) => {\n document.addEventListener('DOMContentLoaded', () => resolve(), { once: true });\n });\n}\n\nasync function fetchReleaseManifest(\n manifestUrl: URL,\n): Promise<{ manifest: ReleaseManifest; baseUrl: URL }> {\n // Bound both headers and JSON-body parsing on every supported browser.\n // `AbortSignal.timeout()` is absent in older engines; without this manual\n // controller, one stalled manifest blocks the serialized loader queue.\n const controller = new AbortController();\n const timeout = globalThis.setTimeout(() => controller.abort(), MANIFEST_TIMEOUT_MS);\n try {\n let response: Response;\n try {\n response = await fetch(manifestUrl, {\n credentials: 'omit',\n signal: controller.signal,\n });\n } catch {\n if (controller.signal.aborted) {\n throw new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: 'Release manifest request timed out.',\n retryable: true,\n });\n }\n response = { ok: false, status: 0 } as Response;\n }\n return { manifest: await parseManifest(response), baseUrl: manifestUrl };\n } finally {\n globalThis.clearTimeout(timeout);\n }\n}\n\nasync function parseManifest(response: Response): Promise<ReleaseManifest> {\n if (!response.ok) {\n throw configInvalid(`Release manifest is not available (HTTP ${response.status}).`);\n }\n const body: unknown = await response.json();\n if (\n typeof body !== 'object' ||\n body === null ||\n typeof (body as ReleaseManifest).version !== 'string' ||\n typeof (body as ReleaseManifest).apiMajor !== 'number' ||\n typeof (body as ReleaseManifest).features !== 'object' ||\n (body as ReleaseManifest).features === null\n ) {\n throw configInvalid('Release manifest is malformed.');\n }\n const manifest = body as ReleaseManifest;\n if (manifest.version !== SDK_VERSION) {\n throw configInvalid('Release manifest version does not match this loader.');\n }\n if (manifest.apiMajor !== API_MAJOR) {\n throw configInvalid('Release manifest major version does not match this loader.');\n }\n const featureNames = Object.keys(manifest.features).sort();\n if (\n featureNames.length !== 2 ||\n featureNames[0] !== 'danmaku' ||\n featureNames[1] !== 'tip' ||\n manifest.features.danmaku !== FEATURE_PATHS.danmaku ||\n manifest.features.tip !== FEATURE_PATHS.tip\n ) {\n throw configInvalid('Release manifest features must be exactly danmaku.js and tip.js.');\n }\n return manifest;\n}\n\nconst KNOWN_ERROR_CODES: ReadonlySet<string> = new Set([\n 'CONFIG_INVALID',\n 'CAPABILITY_DISABLED',\n 'CLIENT_DESTROYED',\n 'INTERNAL_ERROR',\n]);\n\n/**\n * Normalize any thrown value into an event detail. Uses structural checks,\n * not `instanceof`: the loader IIFE and the core ESM chunk are separate\n * builds, so their `ViceMeError` classes are distinct at runtime.\n */\nfunction toErrorDetail(error: unknown): VicemeErrorDetail {\n if (typeof error === 'object' && error !== null) {\n const candidate = error as Record<string, unknown>;\n if (\n typeof candidate.code === 'string' &&\n KNOWN_ERROR_CODES.has(candidate.code) &&\n typeof candidate.retryable === 'boolean'\n ) {\n const detail: VicemeErrorDetail = {\n code: candidate.code as VicemeErrorDetail['code'],\n retryable: candidate.retryable,\n };\n if (typeof candidate.requestId === 'string') detail.requestId = candidate.requestId;\n if (typeof candidate.capability === 'string') detail.capability = candidate.capability;\n return detail;\n }\n }\n return { code: 'INTERNAL_ERROR', retryable: true };\n}\n\nfunction emitError(\n target: EventTarget,\n error: unknown,\n extra: Partial<Pick<VicemeErrorDetail, 'clientKey' | 'instanceKey' | 'capability'>> = {},\n): void {\n dispatchViceMeEvent(target, 'viceme:error', { ...toErrorDetail(error), ...extra });\n}\n\nfunction withCapabilityDeadline<T>(\n operation: Promise<T>,\n controller: AbortController,\n capability: LoaderFeature,\n): Promise<T> {\n let timeout: ReturnType<typeof globalThis.setTimeout> | undefined;\n let onAbort: (() => void) | undefined;\n const cancellation = new Promise<never>((_resolve, reject) => {\n onAbort = () => reject(clientDestroyed());\n if (controller.signal.aborted) {\n onAbort();\n return;\n }\n controller.signal.addEventListener('abort', onAbort, { once: true });\n timeout = globalThis.setTimeout(() => {\n reject(\n new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: `Capability \"${capability}\" did not load and mount in time.`,\n retryable: true,\n capability,\n }),\n );\n controller.abort();\n }, CAPABILITY_MOUNT_TIMEOUT_MS);\n });\n return Promise.race([operation, cancellation]).finally(() => {\n if (timeout !== undefined) globalThis.clearTimeout(timeout);\n if (onAbort) controller.signal.removeEventListener('abort', onAbort);\n });\n}\n\nexport async function runAutoLoader(script: HTMLScriptElement): Promise<void> {\n let attributes: LoaderAttributes;\n try {\n attributes = parseLoaderAttributes(script);\n } catch (error) {\n // Configuration errors before any host exists go to `document`.\n emitError(document, error);\n return;\n }\n\n if (!script.src) {\n emitError(document, configInvalid('Loader script requires a src URL.'));\n return;\n }\n const manifestUrl = new URL('manifest.json', script.src);\n\n let manifest: ReleaseManifest;\n let releaseBase: URL;\n try {\n ({ manifest, baseUrl: releaseBase } = await fetchReleaseManifest(manifestUrl));\n } catch (error) {\n emitError(document, error, {\n clientKey: clientKeyOf(API_MAJOR, attributes.region, attributes.workKey),\n });\n return;\n }\n\n await whenDomReady();\n\n let host: Element;\n try {\n const matches = document.querySelectorAll(attributes.target!);\n if (matches.length === 0) {\n throw configInvalid(\n `Loader target \"${attributes.target}\" matched no element; no node was created.`,\n );\n }\n if (matches.length > 1) {\n throw configInvalid(\n `Loader target \"${attributes.target}\" matched ${matches.length} elements; exactly one is required.`,\n );\n }\n host = matches[0]!;\n } catch (error) {\n emitError(document, error, {\n clientKey: clientKeyOf(manifest.apiMajor, attributes.region, attributes.workKey),\n });\n return;\n }\n\n const clientKey = clientKeyOf(manifest.apiMajor, attributes.region, attributes.workKey);\n ensureNamespace(manifest.version);\n\n // Shared core client per (major, region, workKey).\n let entry = sharedState().registry.getClient(clientKey);\n let client: ViceMeClient;\n if (entry) {\n client = entry.client;\n } else {\n try {\n client = createViceMe({\n workKey: attributes.workKey,\n region: attributes.region,\n });\n } catch (error) {\n emitError(host, error, { clientKey });\n return;\n }\n const ready = client.ready();\n // Keep an unhandled-rejection-free copy on the registry entry; failures\n // are reported through this loader run and via whenReady().\n void ready.catch(() => {});\n entry = { clientKey, client, ready, pendingMounts: new Set() };\n sharedState().registry.registerClient(entry);\n }\n\n try {\n await entry.ready;\n } catch (error) {\n sharedState().registry.unregisterClient(clientKey);\n client.destroy();\n emitError(host, error, { clientKey });\n return;\n }\n if (sharedState().registry.getClient(clientKey) !== entry) return;\n\n const mountCapability = async (capability: LoaderFeature): Promise<LoaderFeature | undefined> => {\n // Same client + capability + element: reuse the original handle.\n if (sharedState().registry.findInstance(clientKey, capability, host)) return undefined;\n\n const fileName = manifest.features[capability];\n if (typeof fileName !== 'string') {\n markClientDegraded(client);\n emitError(\n host,\n new ViceMeError({\n code: 'CAPABILITY_DISABLED',\n message: `Capability \"${capability}\" is not part of this release.`,\n retryable: false,\n capability,\n }),\n { clientKey, capability },\n );\n return undefined;\n }\n\n const controller = new AbortController();\n entry.pendingMounts.add(controller);\n try {\n const operation = (async (): Promise<CapabilityMountHandle> => {\n const chunkUrl = new URL(fileName, releaseBase);\n const module = (await import(/* @vite-ignore */ chunkUrl.href)) as Record<string, unknown>;\n const exportName = MOUNT_EXPORTS[capability];\n const mount = module[exportName];\n if (typeof mount !== 'function') {\n throw configInvalid(`Capability chunk \"${capability}\" does not export ${exportName}().`);\n }\n if (sharedState().registry.getClient(clientKey) !== entry) throw clientDestroyed();\n return (await (mount as CapabilityMountFunction)(client, {\n target: host,\n theme: attributes.theme,\n signal: controller.signal,\n ...(capability === 'tip' && attributes.features.includes('danmaku')\n ? { presentation: 'integrated' as const }\n : {}),\n })) as CapabilityMountHandle;\n })();\n const raw = await withCapabilityDeadline(operation, controller, capability);\n if (sharedState().registry.getClient(clientKey) !== entry) {\n raw.destroy();\n return undefined;\n }\n const instance = sharedState().registry.registerInstance(clientKey, capability, host, raw);\n dispatchViceMeEvent(host, 'viceme:capability-ready', {\n clientKey,\n instanceKey: instance.instanceKey,\n capability,\n version: manifest.version,\n });\n return capability;\n } catch (error) {\n if (sharedState().registry.getClient(clientKey) !== entry) return undefined;\n // Only this capability's partial state is discarded; everything else\n // (including the host page) keeps working.\n markClientDegraded(client);\n emitError(host, error, { clientKey, capability });\n return undefined;\n } finally {\n entry.pendingMounts.delete(controller);\n }\n };\n\n const mounted = (await Promise.all(attributes.features.map(mountCapability))).filter(\n (capability): capability is LoaderFeature => capability !== undefined,\n );\n\n if (mounted.length > 0 && sharedState().registry.getClient(clientKey) === entry) {\n dispatchViceMeEvent(host, 'viceme:ready', {\n clientKey,\n workKey: attributes.workKey,\n capabilities: mounted,\n version: manifest.version,\n });\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* IIFE bootstrap */\n/* ------------------------------------------------------------------ */\n\n/**\n * Loader runs are serialized so identical scripts (duplicate tags, re-runs,\n * same work with different targets) observe registry state deterministically\n * and never create duplicate clients or DOM.\n */\nfunction enqueueRun(script: HTMLScriptElement): Promise<void> {\n const { queue } = sharedState();\n const run = queue.current.then(() => runAutoLoader(script));\n queue.current = run.catch(() => {});\n return run;\n}\n\nfunction bootstrap(): void {\n if (typeof document === 'undefined') return;\n let script: HTMLScriptElement | null =\n document.currentScript instanceof HTMLScriptElement ? document.currentScript : null;\n if (!script) {\n const explicit = document.querySelectorAll<HTMLScriptElement>('script[data-viceme-loader]');\n if (explicit.length === 1) script = explicit[0] ?? null;\n }\n if (!script) return;\n void enqueueRun(script).catch((error: unknown) => {\n emitError(document, error);\n });\n}\n\nbootstrap();\n\n// Test-only handle for re-running the bootstrap in controlled environments.\nexport const __bootstrapForTests = bootstrap;\nexport type { RegisteredInstance };\n"],"names":["RETRYABLE_BY_DEFAULT","ViceMeError","init","json","isViceMeError","value","configInvalid","message","clientDestroyed","BUILD_API_BASE_URLS","BUILD_WIDGET_ORIGINS","REGIONS","PUBLIC_API_BASE_URLS","resolveApiBaseUrl","region","isValidWorkKey","isValidRegion","validatePublicConfig","input","raw","known","key","KNOWN_ATTRIBUTES","THEMES","FEATURE_ORDER","parseLoaderAttributes","element","name","workKey","rawFeatures","declaredFeatures","featureSet","feature","features","target","rawTheme","clientKeyOf","majorVersion","LoaderRegistry","#clients","#instances","#elements","#elementCounter","clientKey","entry","instanceKey","capability","compositeKey","byElement","existing","instance","i","ALLOWED_KEYS","sanitizeDetail","type","detail","paid","allowed","result","dispatchViceMeEvent","event","ALLOWED_TRANSITIONS","Lifecycle","#state","#listeners","next","listener","parseSessionResponse","body","malformedSessionResponse","c","snapshot","capabilities","record","method","currency","creator","work","nullableUrl","expiresAt","sessionInvalidated","SessionManager","#options","#now","#snapshot","#pending","#generation","#identityGeneration","#destroyed","options","#isExpired","generation","pending","response","#assertCurrent","request","#requestWithSnapshot","error","refreshed","#assertAlive","SDK_VERSION","API_MAJOR","ELEMENT_NAME","PROFILE_DESCRIPTION_LIMIT","english","actionCopy","action","actionErrorCopy","fallback","ensureAccessLayerElement","ViceMeAccessLayerElement","copy","shadow","panel","description","mainActions","closeAction","backdrop","frame","continueAction","profile","avatar","avatarFallback","profileName","profileDescription","profileStats","workCover","workTitle","workSummary","idleActionLabel","descriptionCharacters","workDetails","activeAction","closed","close","dismissLayer","caught","available","index","currentIndex","direction","performAction","defaultAccessPresenter","interaction","previousOverflow","previousFocus","resolve","invalid","base64url","bytes","officialUrl","origin","url","expired","createAccessBridge","storageKey","active","clear","purpose","featureKey","controller","signal","assertActive","path","fields","handshake","stored","verifier","state","codeChallenge","returnUrl","current","navigating","forget","timer","deadline","pause","reject","abort","complete","identity","identityExpiresAt","user","parsed","completion","objectBody","malformedResponse","parseUser","parseFollowState","parseDecision","version","reasons","actions","parseFeaturePresentation","price","parsePrice","money","parsedPrice","pricingIntent","randomVerifier","base64Url","binary","byte","resolveLocale","createCapabilities","deps","bridge","cancelled","presentationAbortReason","present","onAbort","cancellation","_resolve","presentation","embeddedFrame","completionOrigin","channel","initialization","settle","fail","cleanup","receive","data","startSignIn","authorizationUrl","workSessionToken","getFollowState","updateFollow","signInPresentation","descriptor","auth","follow","checkMany","featureKeys","createCheckout","checkoutUrl","openCheckout","pollTimer","expiryTimer","handleVisibilityChange","expire","schedule","remaining","poll","decision","checkout","checkoutResult","access","stages","attempts","nextAction","stage","followTarget","resolvePurchase","markClientDegraded","client","ViceMeClientImpl","#lifecycle","#session","#config","#internalSignal","#readyPromise","#detachCallerAbort","#readyAccess","callerSignal","abortInternal","DEFAULT_TIMEOUT_MS","STATUS_CODE_MAP","KNOWN_CODES","parseErrorBody","candidate","defaultRequestId","FetchTransport","#apiBaseUrl","#fetchImpl","#defaultTimeoutMs","#generateRequestId","#callerAbortError","timeoutMs","timedOut","TimeoutAbort","onOuterAbort","requestId","serverRequestId","code","cause","createFetchTransport","createViceMe","config","validated","apiBaseUrl","transport","MANIFEST_TIMEOUT_MS","CAPABILITY_MOUNT_TIMEOUT_MS","FEATURE_PATHS","MOUNT_EXPORTS","STATE_KEY","sharedState","destroyInstanceInternal","wrapInstance","defineHidden","ensureNamespace","global","versions","namespace","whenDomReady","fetchReleaseManifest","manifestUrl","timeout","parseManifest","manifest","featureNames","KNOWN_ERROR_CODES","toErrorDetail","emitError","extra","withCapabilityDeadline","operation","runAutoLoader","script","attributes","releaseBase","host","matches","ready","mountCapability","fileName","module","exportName","mount","mounted","enqueueRun","queue","run","bootstrap","explicit","__bootstrapForTests"],"mappings":"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"}