@viceme-ai/sdk 0.1.5 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -25
- package/dist/bootstrap.min.js +1 -1
- package/dist/bootstrap.min.js.map +1 -1
- package/dist/chunks/version-BbUa2jZV.js +38 -0
- package/dist/chunks/version-BbUa2jZV.js.map +1 -0
- package/dist/core/build-endpoints.d.ts +6 -0
- package/dist/core/build-endpoints.d.ts.map +1 -0
- package/dist/core/client.d.ts +9 -23
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/config.d.ts +4 -14
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/errors.d.ts +1 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/lifecycle.d.ts +2 -4
- package/dist/core/lifecycle.d.ts.map +1 -1
- package/dist/danmaku/anchor.d.ts +14 -0
- package/dist/danmaku/anchor.d.ts.map +1 -0
- package/dist/danmaku/index.d.ts +12 -0
- package/dist/danmaku/index.d.ts.map +1 -0
- package/dist/danmaku/mount.d.ts +5 -0
- package/dist/danmaku/mount.d.ts.map +1 -0
- package/dist/danmaku.js +202 -0
- package/dist/danmaku.js.map +1 -0
- package/dist/generated/public-contract.d.ts +68 -56
- package/dist/generated/public-contract.d.ts.map +1 -1
- package/dist/index.d.ts +3 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +96 -111
- package/dist/index.js.map +1 -1
- package/dist/loader/attributes.d.ts +1 -1
- package/dist/loader/attributes.d.ts.map +1 -1
- package/dist/loader/auto-loader.d.ts +6 -6
- package/dist/loader/auto-loader.d.ts.map +1 -1
- package/dist/loader/mount-handle.d.ts +2 -2
- package/dist/loader/mount-handle.d.ts.map +1 -1
- package/dist/loader/registry.d.ts +2 -2
- package/dist/manifest.json +27 -25
- package/dist/version.d.ts +1 -1
- package/dist/viceme.min.js +1 -1
- package/dist/viceme.min.js.map +1 -1
- package/package.json +7 -8
- package/dist/chunks/client-CfKmb4Lm.js +0 -275
- package/dist/chunks/client-CfKmb4Lm.js.map +0 -1
- package/dist/session/session.d.ts +0 -54
- package/dist/session/session.d.ts.map +0 -1
- package/dist/testing/test-adapter.d.ts +0 -57
- package/dist/testing/test-adapter.d.ts.map +0 -1
- package/dist/testing.d.ts +0 -9
- package/dist/testing.d.ts.map +0 -1
- package/dist/testing.js +0 -69
- package/dist/testing.js.map +0 -1
- package/dist/transport/transport.d.ts +0 -42
- package/dist/transport/transport.d.ts.map +0 -1
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
* and never creates phantom nodes.
|
|
12
12
|
* 4. Read `manifest.json` from the loader's own directory (exact release
|
|
13
13
|
* version; URLs are never assembled from page parameters).
|
|
14
|
-
* 5.
|
|
15
|
-
*
|
|
14
|
+
* 5. Create the local client embedded in this loader, then load the
|
|
15
|
+
* same-version danmaku chunk declared by the manifest.
|
|
16
|
+
* 6. Mount; handles land in an internal registry.
|
|
16
17
|
* 7. Re-running the same instance key returns the original handle — no
|
|
17
|
-
* duplicate
|
|
18
|
-
* 8. A failing
|
|
19
|
-
* the page and other capabilities keep working.
|
|
18
|
+
* duplicate clients, subscriptions, or DOM.
|
|
19
|
+
* 8. A failing mount keeps the host page working and degrades only its client.
|
|
20
20
|
* 9. `pagehide` never auto-destroys (bfcache); cleanup happens on explicit
|
|
21
21
|
* `destroy()` only.
|
|
22
22
|
*
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* than the fixed `window.ViceMe.versions.vN` namespace.
|
|
25
25
|
*/
|
|
26
26
|
import { type RegisteredInstance } from './registry.ts';
|
|
27
|
-
import type
|
|
27
|
+
import { type ViceMeClient, type ViceMeMountedInstance } from '../core/client.ts';
|
|
28
28
|
export interface ReleaseManifest {
|
|
29
29
|
version: string;
|
|
30
30
|
apiMajor: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-loader.d.ts","sourceRoot":"","sources":["../../src/loader/auto-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAA+B,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAIrF,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"auto-loader.d.ts","sourceRoot":"","sources":["../../src/loader/auto-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAA+B,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAIrF,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC3B,MAAM,mBAAmB,CAAC;AAI3B,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACpD,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS,CAAC;IACpE,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE;QAER,CAAC,KAAK,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS,CAAC;KACtD,CAAC;CACH;AA4ED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,uBAAuB,CA2CxE;AA0GD,wBAAsB,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuJ5E;AAkBD,iBAAS,SAAS,IAAI,IAAI,CAYzB;AAKD,eAAO,MAAM,mBAAmB,kBAAY,CAAC;AAC7C,YAAY,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The handle
|
|
2
|
+
* The handle the danmaku mount function returns to the loader (no
|
|
3
3
|
* registry/identity concerns). The loader wraps it into the public
|
|
4
4
|
* `ViceMeMountedInstance`, which carries the registry-assigned `instanceKey`
|
|
5
5
|
* and owns idempotent destroy + event dispatch.
|
|
@@ -20,6 +20,6 @@ export interface CapabilityMountHandle {
|
|
|
20
20
|
export type CapabilityMountFunction = (client: ViceMeClient, options: CapabilityMountOptions) => Promise<CapabilityMountHandle>;
|
|
21
21
|
/** Convenience for ESM-direct capability entry points. */
|
|
22
22
|
export interface ViceMeCapabilityModule {
|
|
23
|
-
|
|
23
|
+
mountDanmaku: CapabilityMountFunction;
|
|
24
24
|
}
|
|
25
25
|
//# sourceMappingURL=mount-handle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount-handle.d.ts","sourceRoot":"","sources":["../../src/loader/mount-handle.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,WAAW,sBAAsB;IACrC,sEAAsE;IACtE,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,2EAA2E;AAC3E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,0EAA0E;IAC1E,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,MAAM,uBAAuB,GAAG,CACpC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,sBAAsB,KAC5B,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEpC,0DAA0D;AAC1D,MAAM,WAAW,sBAAsB;IACrC,
|
|
1
|
+
{"version":3,"file":"mount-handle.d.ts","sourceRoot":"","sources":["../../src/loader/mount-handle.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,WAAW,sBAAsB;IACrC,sEAAsE;IACtE,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,2EAA2E;AAC3E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,0EAA0E;IAC1E,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,MAAM,uBAAuB,GAAG,CACpC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,sBAAsB,KAC5B,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEpC,0DAA0D;AAC1D,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,uBAAuB,CAAC;CACvC"}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Loader registry.
|
|
3
3
|
*
|
|
4
4
|
* Only the CDN loader maintains this registry (explicit `createViceMe()`
|
|
5
|
-
* instances never register).
|
|
6
|
-
* `major + region + workKey`;
|
|
5
|
+
* instances never register). Local clients are shared by
|
|
6
|
+
* `major + region + workKey`; danmaku mounts are deduplicated by
|
|
7
7
|
* `clientKey + capability + target Element identity`.
|
|
8
8
|
*
|
|
9
9
|
* The registry itself is never exposed on `window` — only the fixed
|
package/dist/manifest.json
CHANGED
|
@@ -1,38 +1,40 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
2
|
+
"version": "0.2.0",
|
|
3
3
|
"apiMajor": 1,
|
|
4
4
|
"loader": "viceme.min.js",
|
|
5
|
-
"features": {
|
|
5
|
+
"features": {
|
|
6
|
+
"danmaku": "danmaku.js"
|
|
7
|
+
},
|
|
6
8
|
"files": {
|
|
7
9
|
"bootstrap.min.js": {
|
|
8
|
-
"sha256": "
|
|
9
|
-
"sri": "sha384-
|
|
10
|
-
"bytes":
|
|
11
|
-
"gzipBytes":
|
|
10
|
+
"sha256": "43efabdb3e999156cac881090602e45edcc795b73dcaaee50fe710f7c0cb45e3",
|
|
11
|
+
"sri": "sha384-iAKo6ccUGEfjVkOBlHiisPrXqeVwysUM+zjb0QGlRhdtO8nBTXj26nLQhFK8exbr",
|
|
12
|
+
"bytes": 964,
|
|
13
|
+
"gzipBytes": 597
|
|
12
14
|
},
|
|
13
|
-
"chunks/
|
|
14
|
-
"sha256": "
|
|
15
|
-
"sri": "sha384-
|
|
16
|
-
"bytes":
|
|
17
|
-
"gzipBytes":
|
|
15
|
+
"chunks/version-BbUa2jZV.js": {
|
|
16
|
+
"sha256": "2c6e1471b3162fc1f5d22fe9409d5dee132ac3dcf5813e86b3484c532795ea2f",
|
|
17
|
+
"sri": "sha384-9xs64VnKybQmjrIQAQIZXPB3jjMD3L+lYG2IUCWuXM1m6N61XJfiPYqFiLrJ/g53",
|
|
18
|
+
"bytes": 1033,
|
|
19
|
+
"gzipBytes": 545
|
|
18
20
|
},
|
|
19
|
-
"
|
|
20
|
-
"sha256": "
|
|
21
|
-
"sri": "sha384-
|
|
22
|
-
"bytes":
|
|
23
|
-
"gzipBytes":
|
|
21
|
+
"danmaku.js": {
|
|
22
|
+
"sha256": "01b50d712efeb192741c212f3b5145f74f36af9b2d6f521270c331c28dd50497",
|
|
23
|
+
"sri": "sha384-nvVUPE872/arFChMvzTh4rnmMGDKXOIjbV5gRpRvXAIamvzoam7xvJGszK8nFL4k",
|
|
24
|
+
"bytes": 8969,
|
|
25
|
+
"gzipBytes": 3219
|
|
24
26
|
},
|
|
25
|
-
"
|
|
26
|
-
"sha256": "
|
|
27
|
-
"sri": "sha384-
|
|
28
|
-
"bytes":
|
|
29
|
-
"gzipBytes":
|
|
27
|
+
"index.js": {
|
|
28
|
+
"sha256": "6cd6dad051a6426be8aec028c80bdef6e51d142d8ca511d5ea5ff8d230d11d2d",
|
|
29
|
+
"sri": "sha384-N6nFflxbSfoM0bFcqoJOIykbg5k6DXvXXp5h/uoGSwEyLe7cuVeT1uZE1qIRoafm",
|
|
30
|
+
"bytes": 2849,
|
|
31
|
+
"gzipBytes": 1248
|
|
30
32
|
},
|
|
31
33
|
"viceme.min.js": {
|
|
32
|
-
"sha256": "
|
|
33
|
-
"sri": "sha384-
|
|
34
|
-
"bytes":
|
|
35
|
-
"gzipBytes":
|
|
34
|
+
"sha256": "b220fda500ea54fdfb2288379e12e5de8e376ca4d2dc8e7831e18e98be3eb7b2",
|
|
35
|
+
"sri": "sha384-5cWwq3wmL/wBaC+sj4CNSZ2bCK+3Ai/eKgUf/08YWyuT0yd9YXQA5Aj+78G3lhsF",
|
|
36
|
+
"bytes": 10496,
|
|
37
|
+
"gzipBytes": 3635
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
}
|
package/dist/version.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Kept in sync with `packages/sdk/package.json#version`; a unit test enforces
|
|
5
5
|
* the match so the loader, release manifest, and npm metadata can never drift.
|
|
6
6
|
*/
|
|
7
|
-
export declare const SDK_VERSION = "0.
|
|
7
|
+
export declare const SDK_VERSION = "0.2.0";
|
|
8
8
|
/** Public API major carried by this build (loader namespace `v1`). */
|
|
9
9
|
export declare const API_MAJOR = 1;
|
|
10
10
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/viceme.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(){"use strict";const _=new Set(["RATE_LIMITED","NETWORK_TIMEOUT","CHECKOUT_UNAVAILABLE","INTERNAL_ERROR"]);class h extends Error{code;retryable;requestId;capability;constructor(e){super(e.message),this.name="ViceMeError",this.code=e.code,this.retryable=e.retryable??_.has(e.code),this.requestId=e.requestId,this.capability=e.capability}toJSON(){const e={code:this.code,retryable:this.retryable};return this.requestId!==void 0&&(e.requestId=this.requestId),this.capability!==void 0&&(e.capability=this.capability),e}}function Q(t){return t instanceof h}function s(t){return new h({code:"CONFIG_INVALID",message:t,retryable:!1})}function ee(){return new h({code:"CLIENT_DESTROYED",message:"ViceMe client has been destroyed.",retryable:!1})}const O=new Set(["cn","global"]),C={cn:"https://api.viceme.cn",global:"https://api.viceme.ai"};function te(t){return C[t]}function I(t){return typeof t=="string"&&/^wrk_[A-Za-z0-9_-]{4,124}$/.test(t)}function A(t){return typeof t=="string"&&O.has(t)}function re(t){if(typeof t!="object"||t===null)throw s("createViceMe expects a configuration object.");const e=t,r=new Set(["workKey","region","signal"]);for(const n of Object.keys(e))if(!r.has(n))throw s(`Unknown configuration field "${n}".`);if(!I(e.workKey))throw s('Configuration field "workKey" must be a public work key ("wrk_…").');if(!A(e.region))throw s('Configuration field "region" must be "cn" or "global".');if(e.signal!==void 0&&!(e.signal instanceof AbortSignal))throw s('Configuration field "signal" must be an AbortSignal.');return{workKey:e.workKey,region:e.region,signal:e.signal}}const M=new Set(["data-viceme-work","data-viceme-region","data-viceme-features","data-viceme-target","data-viceme-theme","data-viceme-loader"]),N=/^[a-z][a-z0-9-]{1,31}$/,$=new Set(["light","dark","auto"]);function D(t){for(const o of t.getAttributeNames())if(o.startsWith("data-viceme-")&&!M.has(o))throw s(`Unknown loader attribute "${o}".`);const e=t.getAttribute("data-viceme-work");if(!I(e))throw s('Loader attribute "data-viceme-work" must be a public work key ("wrk_…").');const r=t.getAttribute("data-viceme-region");if(!A(r))throw s('Loader attribute "data-viceme-region" must be "cn" or "global".');const n=t.getAttribute("data-viceme-features");if(n===null||n.trim()==="")throw s('Loader attribute "data-viceme-features" is required.');const u=[];for(const o of n.split(",")){const l=o.trim();if(l!==""){if(!N.test(l))throw s(`Loader feature name "${l}" is not a valid capability name.`);u.includes(l)||u.push(l)}}if(u.length===0)throw s('Loader attribute "data-viceme-features" must list at least one feature.');const c=t.getAttribute("data-viceme-target");if(c==="")throw s('Loader attribute "data-viceme-target" must be a CSS selector.');if(c===null)throw s('Loader attribute "data-viceme-target" is required when features are declared.');const i=t.getAttribute("data-viceme-theme");if(i!==null&&!$.has(i))throw s('Loader attribute "data-viceme-theme" must be "light", "dark", or "auto".');return{workKey:e,region:r,features:u,target:c,theme:i??"auto"}}function w(t,e,r){return`v${t}+${e}+${r}`}class U{#r=new Map;#e=new Map;#t=new Map;#n=0;getClient(e){return this.#r.get(e)}registerClient(e){this.#r.set(e.clientKey,e)}unregisterClient(e){this.#r.delete(e)}getInstance(e){return this.#e.get(e)}findInstance(e,r,n){return this.#t.get(`${e}::${r}`)?.get(n)}registerInstance(e,r,n,u){const c=`${e}::${r}`;let i=this.#t.get(c);i===void 0&&(i=new WeakMap,this.#t.set(c,i));const o=i.get(n);if(o)return o;this.#n+=1;const l={instanceKey:`${e}::${r}::el${this.#n}`,clientKey:e,capability:r,host:n,raw:u,destroyed:!1};return this.#e.set(l.instanceKey,l),i.set(n,l),l}removeInstance(e){const r=this.#e.get(e);if(r)return this.#e.delete(e),this.#t.get(`${r.clientKey}::${r.capability}`)?.delete(r.host),r}instancesForClient(e){return[...this.#e.values()].filter(r=>r.clientKey===e)}}const j=new Map([["viceme:ready",new Set(["clientKey","workKey","capabilities","version"])],["viceme:capability-ready",new Set(["clientKey","instanceKey","capability","version"])],["viceme:error",new Set(["clientKey","instanceKey","capability","code","retryable","requestId"])],["viceme:destroyed",new Set(["clientKey","instanceKey","capability"])]]);function q(t,e){const r=j.get(t),n={};for(const[u,c]of Object.entries(e))r.has(u)&&c!==void 0&&(n[u]=c);return n}function m(t,e,r){const n=new CustomEvent(e,{detail:q(e,r),bubbles:!0,composed:!0,cancelable:!1});t.dispatchEvent(n)}const ne="0.1.5",y=1,V=8e3,k=Symbol.for("viceme.loader.state.v1");function d(){const e=globalThis[k];if(e)return e;const r={registry:new U,queue:{current:Promise.resolve()}};return Object.defineProperty(globalThis,k,{value:r,writable:!0,configurable:!0,enumerable:!1}),r}function p(t){if(!t.destroyed){t.destroyed=!0,d().registry.removeInstance(t.instanceKey);try{t.raw.destroy()}finally{m(t.host,"viceme:destroyed",{clientKey:t.clientKey,instanceKey:t.instanceKey,capability:t.capability})}}}function P(t){return{instanceKey:t.instanceKey,capability:t.capability,destroy:()=>p(t)}}function v(t,e,r){Object.defineProperty(t,e,{value:r,writable:!0,configurable:!0,enumerable:!1})}function B(t){let r=globalThis.ViceMe;r||(r={},v(globalThis,"ViceMe",r));let n=r.versions;n||(n={},v(r,"versions",n));const u=n[`v${y}`];if(u)return u;const c={version:t,whenReady(i){const o=d().registry.getClient(i);return o?o.ready.then(()=>o.client):Promise.reject(s(`Unknown clientKey "${i}".`))},getInstance(i){const o=d().registry.getInstance(i);return o?P(o):void 0},destroyInstance(i){const o=d().registry.getInstance(i);o&&p(o)},destroyClient(i){for(const l of d().registry.instancesForClient(i))p(l);const o=d().registry.getClient(i);d().registry.unregisterClient(i),o?.client.destroy()}};return v(n,`v${y}`,c),c}function x(){return document.readyState!=="loading"?Promise.resolve():new Promise(t=>{document.addEventListener("DOMContentLoaded",()=>t(),{once:!0})})}async function W(t){let e;try{e=await E(t)}catch{e={ok:!1,status:0}}if(!e.ok){const r=await F(t);if(r!==void 0){const n=new URL(`/viceme-sdk/${r}/manifest.json`,t);return{manifest:await L(await E(n)),baseUrl:n}}}return{manifest:await L(e),baseUrl:t}}function E(t){const e=typeof AbortSignal<"u"&&typeof AbortSignal.timeout=="function"?AbortSignal.timeout(V):void 0;return fetch(t,{credentials:"omit",signal:e})}async function F(t){if(!(!/\/viceme-sdk\/[^/]+\/manifest\.json$/.test(t.pathname)||t.pathname.split("/viceme-sdk/")[1]?.split("/")[0]!==`v${y}`))try{const r=await E(new URL("/viceme-sdk/-/aliases/v1",t));if(!r.ok)return;const n=(await r.text()).trim();return/^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/.test(n)?n:void 0}catch{return}}async function L(t){if(!t.ok)throw s(`Release manifest is not available (HTTP ${t.status}).`);const e=await t.json();if(typeof e!="object"||e===null||typeof e.version!="string"||typeof e.apiMajor!="number"||typeof e.features!="object"||e.features===null)throw s("Release manifest is malformed.");const r=e;if(r.apiMajor!==y)throw s("Release manifest major version does not match this loader.");return r}async function Y(t){const r=await import(new URL("index.js",t).href);if(typeof r.createViceMe!="function")throw s("SDK core chunk does not export createViceMe().");return r}const H=new Set(["CONFIG_INVALID","WORK_NOT_FOUND","ORIGIN_NOT_ALLOWED","CAPABILITY_DISABLED","CLIENT_DESTROYED","SESSION_EXPIRED","RATE_LIMITED","NETWORK_TIMEOUT","CHECKOUT_UNAVAILABLE","INTERNAL_ERROR"]);function z(t){if(typeof t=="object"&&t!==null){const e=t;if(typeof e.code=="string"&&H.has(e.code)&&typeof e.retryable=="boolean"){const r={code:e.code,retryable:e.retryable};return typeof e.requestId=="string"&&(r.requestId=e.requestId),typeof e.capability=="string"&&(r.capability=e.capability),r}}return{code:"INTERNAL_ERROR",retryable:!0}}function f(t,e,r={}){m(t,"viceme:error",{...z(e),...r})}async function G(t){let e;try{e=D(t)}catch(a){f(document,a);return}if(!t.src){f(document,s("Loader script requires a src URL."));return}const r=new URL("manifest.json",t.src);let n,u;try{({manifest:n,baseUrl:u}=await W(r))}catch(a){f(document,a,{clientKey:w(y,e.region,e.workKey)});return}await x();let c;try{const a=document.querySelectorAll(e.target);if(a.length===0)throw s(`Loader target "${e.target}" matched no element; no node was created.`);if(a.length>1)throw s(`Loader target "${e.target}" matched ${a.length} elements; exactly one is required.`);c=a[0]}catch(a){f(document,a,{clientKey:w(n.apiMajor,e.region,e.workKey)});return}const i=w(n.apiMajor,e.region,e.workKey);B(n.version);let o=d().registry.getClient(i),l;if(o)l=o.client;else{let a;try{a=await Y(u)}catch(b){f(c,b,{clientKey:i});return}l=a.createViceMe({workKey:e.workKey,region:e.region});const g=l.ready();g.catch(()=>{}),o={clientKey:i,client:l,ready:g},d().registry.registerClient(o)}try{await o.ready}catch(a){d().registry.unregisterClient(i),l.destroy(),f(c,a,{clientKey:i});return}let K=!1;const T=[];for(const a of e.features){if(d().registry.findInstance(i,a,c))continue;const g=n.features[a];if(typeof g!="string"){l.markDegraded(),f(c,new h({code:"CAPABILITY_DISABLED",message:`Capability "${a}" is not part of this release.`,retryable:!1,capability:a}),{clientKey:i,capability:a});continue}try{const S=await import(new URL(g,u).href);if(typeof S.mount!="function")throw s(`Capability chunk "${a}" does not export mount().`);const Z=await S.mount(l,{target:c,theme:e.theme}),X=d().registry.registerInstance(i,a,c,Z);K=!0,T.push(a),m(c,"viceme:capability-ready",{clientKey:i,instanceKey:X.instanceKey,capability:a,version:n.version})}catch(b){l.markDegraded(),f(c,b,{clientKey:i,capability:a})}}K&&m(c,"viceme:ready",{clientKey:i,workKey:e.workKey,capabilities:T,version:n.version})}function J(t){const{queue:e}=d(),r=e.current.then(()=>G(t));return e.current=r.catch(()=>{}),r}function R(){if(typeof document>"u")return;let t=document.currentScript instanceof HTMLScriptElement?document.currentScript:null;if(!t){const e=document.querySelectorAll("script[data-viceme-loader]");e.length===1&&(t=e[0]??null)}t&&J(t).catch(e=>{f(document,e)})}R();const ie=R})();
|
|
1
|
+
(function(){"use strict";const O=new Set(["INTERNAL_ERROR"]);class y extends Error{code;retryable;requestId;capability;constructor(e){super(e.message),this.name="ViceMeError",this.code=e.code,this.retryable=e.retryable??O.has(e.code),this.requestId=e.requestId,this.capability=e.capability}toJSON(){const e={code:this.code,retryable:this.retryable};return this.requestId!==void 0&&(e.requestId=this.requestId),this.capability!==void 0&&(e.capability=this.capability),e}}function ae(t){return t instanceof y}function c(t){return new y({code:"CONFIG_INVALID",message:t,retryable:!1})}function p(){return new y({code:"CLIENT_DESTROYED",message:"ViceMe client has been destroyed.",retryable:!1})}const M=new Set(["cn","global"]);function R(t){return typeof t=="string"&&/^wrk_[A-Za-z0-9_-]{4,124}$/.test(t)}function k(t){return typeof t=="string"&&M.has(t)}function _(t){if(typeof t!="object"||t===null)throw c("createViceMe expects a configuration object.");const e=t,r=new Set(["workKey","region"]);for(const i of Object.keys(e))if(!r.has(i))throw c(`Unknown configuration field "${i}".`);if(!R(e.workKey))throw c('Configuration field "workKey" must be a public work key ("wrk_…").');if(!k(e.region))throw c('Configuration field "region" must be "cn" or "global".');return{workKey:e.workKey,region:e.region}}const N=new Set(["data-viceme-work","data-viceme-region","data-viceme-features","data-viceme-target","data-viceme-theme","data-viceme-loader"]),$=new Set(["light","dark","auto"]);function j(t){for(const a of t.getAttributeNames())if(a.startsWith("data-viceme-")&&!N.has(a))throw c(`Unknown loader attribute "${a}".`);const e=t.getAttribute("data-viceme-work");if(!R(e))throw c('Loader attribute "data-viceme-work" must be a public work key ("wrk_…").');const r=t.getAttribute("data-viceme-region");if(!k(r))throw c('Loader attribute "data-viceme-region" must be "cn" or "global".');if(t.getAttribute("data-viceme-features")!=="danmaku")throw c('Loader attribute "data-viceme-features" must be exactly "danmaku".');const d=["danmaku"],o=t.getAttribute("data-viceme-target");if(o==="")throw c('Loader attribute "data-viceme-target" must be a CSS selector.');if(o===null)throw c('Loader attribute "data-viceme-target" is required when features are declared.');try{t.matches(o)}catch{throw c('Loader attribute "data-viceme-target" is not a valid CSS selector.')}const n=t.getAttribute("data-viceme-theme");if(n!==null&&!$.has(n))throw c('Loader attribute "data-viceme-theme" must be "light", "dark", or "auto".');return{workKey:e,region:r,features:d,target:o,theme:n??"auto"}}function b(t,e,r){return`v${t}+${e}+${r}`}class q{#e=new Map;#t=new Map;#r=new Map;#n=0;getClient(e){return this.#e.get(e)}registerClient(e){this.#e.set(e.clientKey,e)}unregisterClient(e){this.#e.delete(e)}getInstance(e){return this.#t.get(e)}findInstance(e,r,i){return this.#r.get(`${e}::${r}`)?.get(i)}registerInstance(e,r,i,d){const o=`${e}::${r}`;let n=this.#r.get(o);n===void 0&&(n=new WeakMap,this.#r.set(o,n));const a=n.get(i);if(a)return a;this.#n+=1;const l={instanceKey:`${e}::${r}::el${this.#n}`,clientKey:e,capability:r,host:i,raw:d,destroyed:!1};return this.#t.set(l.instanceKey,l),n.set(i,l),l}removeInstance(e){const r=this.#t.get(e);if(r)return this.#t.delete(e),this.#r.get(`${r.clientKey}::${r.capability}`)?.delete(r.host),r}instancesForClient(e){return[...this.#t.values()].filter(r=>r.clientKey===e)}}const Y=new Map([["viceme:ready",new Set(["clientKey","workKey","capabilities","version"])],["viceme:capability-ready",new Set(["clientKey","instanceKey","capability","version"])],["viceme:error",new Set(["clientKey","instanceKey","capability","code","retryable","requestId"])],["viceme:destroyed",new Set(["clientKey","instanceKey","capability"])]]);function V(t,e){const r=Y.get(t),i={};for(const[d,o]of Object.entries(e))r.has(d)&&o!==void 0&&(i[d]=o);return i}function h(t,e,r){const i=new CustomEvent(e,{detail:V(e,r),bubbles:!0,composed:!0,cancelable:!1});t.dispatchEvent(i)}const P={CREATED:["READY","DESTROYED"],READY:["DEGRADED","DESTROYED"],DEGRADED:["DESTROYED"],DESTROYED:[]};class U{#e="CREATED";#t=new Set;get state(){return this.#e}get destroyed(){return this.#e==="DESTROYED"}transition(e){if(e!==this.#e){if(!P[this.#e].includes(e))throw new y({code:"INTERNAL_ERROR",message:`Illegal lifecycle transition ${this.#e} -> ${e}.`,retryable:!1});this.#e=e;for(const r of this.#t)r(e)}}assertAlive(){if(this.destroyed)throw p()}subscribe(e){return this.#t.add(e),()=>{this.#t.delete(e)}}clearListeners(){this.#t.clear()}}const w=Symbol("ViceMeClient.markDegraded");function D(t){w in t&&t[w]()}class F{#e=new U;#t;#r;constructor(e){this.#t=e}get workKey(){return this.#t.workKey}get region(){return this.#t.region}get state(){return this.#e.state}ready(){return this.#e.destroyed?Promise.reject(p()):(this.#r||(this.#e.transition("READY"),this.#r=Promise.resolve()),this.#r)}hasCapability(e){return!this.#e.destroyed&&e==="danmaku"}[w](){this.#e.state==="READY"&&this.#e.transition("DEGRADED")}destroy(){this.#e.destroyed||(this.#e.transition("DESTROYED"),this.#e.clearListeners(),this.#r=void 0)}}const B="0.2.0",g=1;function W(t){const e=_(t);return new F(e)}const G=8e3,x="danmaku.js",A=Symbol.for("viceme.loader.state.v1");function u(){const e=globalThis[A];if(e)return e;const r={registry:new q,queue:{current:Promise.resolve()}};return Object.defineProperty(globalThis,A,{value:r,writable:!0,configurable:!0,enumerable:!1}),r}function E(t){if(!t.destroyed){t.destroyed=!0,u().registry.removeInstance(t.instanceKey);try{t.raw.destroy()}finally{h(t.host,"viceme:destroyed",{clientKey:t.clientKey,instanceKey:t.instanceKey,capability:t.capability})}}}function H(t){return{instanceKey:t.instanceKey,capability:t.capability,destroy:()=>E(t)}}function v(t,e,r){Object.defineProperty(t,e,{value:r,writable:!0,configurable:!0,enumerable:!1})}function z(t){let r=globalThis.ViceMe;r||(r={},v(globalThis,"ViceMe",r));let i=r.versions;i||(i={},v(r,"versions",i));const d=i[`v${g}`];if(d)return d;const o={version:t,whenReady(n){const a=u().registry.getClient(n);return a?a.ready.then(()=>a.client):Promise.reject(c(`Unknown clientKey "${n}".`))},getInstance(n){const a=u().registry.getInstance(n);return a?H(a):void 0},destroyInstance(n){const a=u().registry.getInstance(n);a&&E(a)},destroyClient(n){for(const l of u().registry.instancesForClient(n))E(l);const a=u().registry.getClient(n);u().registry.unregisterClient(n),a?.client.destroy()}};return v(i,`v${g}`,o),o}function J(){return document.readyState!=="loading"?Promise.resolve():new Promise(t=>{document.addEventListener("DOMContentLoaded",()=>t(),{once:!0})})}async function Z(t){let e;try{e=await Q(t)}catch{e={ok:!1,status:0}}return{manifest:await X(e),baseUrl:t}}function Q(t){const e=typeof AbortSignal<"u"&&typeof AbortSignal.timeout=="function"?AbortSignal.timeout(G):void 0;return fetch(t,{credentials:"omit",signal:e})}async function X(t){if(!t.ok)throw c(`Release manifest is not available (HTTP ${t.status}).`);const e=await t.json();if(typeof e!="object"||e===null||typeof e.version!="string"||typeof e.apiMajor!="number"||typeof e.features!="object"||e.features===null)throw c("Release manifest is malformed.");const r=e;if(r.version!==B)throw c("Release manifest version does not match this loader.");if(r.apiMajor!==g)throw c("Release manifest major version does not match this loader.");const i=Object.keys(r.features);if(i.length!==1||i[0]!=="danmaku"||r.features.danmaku!==x)throw c("Release manifest features must be exactly danmaku.js.");return r}const ee=new Set(["CONFIG_INVALID","CAPABILITY_DISABLED","CLIENT_DESTROYED","INTERNAL_ERROR"]);function te(t){if(typeof t=="object"&&t!==null){const e=t;if(typeof e.code=="string"&&ee.has(e.code)&&typeof e.retryable=="boolean"){const r={code:e.code,retryable:e.retryable};return typeof e.requestId=="string"&&(r.requestId=e.requestId),typeof e.capability=="string"&&(r.capability=e.capability),r}}return{code:"INTERNAL_ERROR",retryable:!0}}function f(t,e,r={}){h(t,"viceme:error",{...te(e),...r})}async function re(t){let e;try{e=j(t)}catch(s){f(document,s);return}if(!t.src){f(document,c("Loader script requires a src URL."));return}const r=new URL("manifest.json",t.src);let i,d;try{({manifest:i,baseUrl:d}=await Z(r))}catch(s){f(document,s,{clientKey:b(g,e.region,e.workKey)});return}await J();let o;try{const s=document.querySelectorAll(e.target);if(s.length===0)throw c(`Loader target "${e.target}" matched no element; no node was created.`);if(s.length>1)throw c(`Loader target "${e.target}" matched ${s.length} elements; exactly one is required.`);o=s[0]}catch(s){f(document,s,{clientKey:b(i.apiMajor,e.region,e.workKey)});return}const n=b(i.apiMajor,e.region,e.workKey);z(i.version);let a=u().registry.getClient(n),l;if(a)l=a.client;else{try{l=W({workKey:e.workKey,region:e.region})}catch(m){f(o,m,{clientKey:n});return}const s=l.ready();s.catch(()=>{}),a={clientKey:n,client:l,ready:s},u().registry.registerClient(a)}try{await a.ready}catch(s){u().registry.unregisterClient(n),l.destroy(),f(o,s,{clientKey:n});return}if(u().registry.getClient(n)!==a)return;let S=!1;const K=[];for(const s of e.features){if(u().registry.findInstance(n,s,o))continue;const m=i.features[s];if(typeof m!="string"){D(l),f(o,new y({code:"CAPABILITY_DISABLED",message:`Capability "${s}" is not part of this release.`,retryable:!1,capability:s}),{clientKey:n,capability:s});continue}try{const C=await import(new URL(m,d).href);if(typeof C.mountDanmaku!="function")throw c(`Capability chunk "${s}" does not export mountDanmaku().`);if(u().registry.getClient(n)!==a)return;const L=await C.mountDanmaku(l,{target:o,theme:e.theme});if(u().registry.getClient(n)!==a){L.destroy();return}const ie=u().registry.registerInstance(n,s,o,L);S=!0,K.push(s),h(o,"viceme:capability-ready",{clientKey:n,instanceKey:ie.instanceKey,capability:s,version:i.version})}catch(T){if(u().registry.getClient(n)!==a)return;D(l),f(o,T,{clientKey:n,capability:s})}}S&&u().registry.getClient(n)===a&&h(o,"viceme:ready",{clientKey:n,workKey:e.workKey,capabilities:K,version:i.version})}function ne(t){const{queue:e}=u(),r=e.current.then(()=>re(t));return e.current=r.catch(()=>{}),r}function I(){if(typeof document>"u")return;let t=document.currentScript instanceof HTMLScriptElement?document.currentScript:null;if(!t){const e=document.querySelectorAll("script[data-viceme-loader]");e.length===1&&(t=e[0]??null)}t&&ne(t).catch(e=>{f(document,e)})}I();const se=I})();
|
|
2
2
|
//# sourceMappingURL=viceme.min.js.map
|
package/dist/viceme.min.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viceme.min.js","sources":["../src/core/errors.ts","../src/core/config.ts","../src/loader/attributes.ts","../src/loader/registry.ts","../src/loader/events.ts","../src/version.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 | 'ORIGIN_NOT_ALLOWED'\n | 'CAPABILITY_DISABLED'\n | 'CLIENT_DESTROYED'\n | 'SESSION_EXPIRED'\n | 'RATE_LIMITED'\n | 'NETWORK_TIMEOUT'\n | 'CHECKOUT_UNAVAILABLE'\n | 'INTERNAL_ERROR';\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","/**\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';\n\nexport type ViceMeRegion = 'cn' | 'global';\n\nexport interface ViceMeConfig {\n /** Public opaque work key (`wrk_…`). Locates a Work; 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: 'https://api.viceme.cn',\n global: 'https://api.viceme.ai',\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_[A-Za-z0-9_-]{4,124}$/.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('Configuration field \"workKey\" must be a public work key (\"wrk_…\").');\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 { workKey: raw.workKey, region: raw.region, signal: raw.signal };\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';\n\nexport interface LoaderAttributes {\n workKey: string;\n region: ViceMeRegion;\n /** Deduplicated feature names in declared order. */\n features: string[];\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 FEATURE_NAME_PATTERN = /^[a-z][a-z0-9-]{1,31}$/;\nconst THEMES: ReadonlySet<string> = new Set(['light', 'dark', 'auto']);\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 (\"wrk_…\").');\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 if (rawFeatures === null || rawFeatures.trim() === '') {\n throw configInvalid('Loader attribute \"data-viceme-features\" is required.');\n }\n const features: string[] = [];\n for (const part of rawFeatures.split(',')) {\n const feature = part.trim();\n if (feature === '') continue;\n if (!FEATURE_NAME_PATTERN.test(feature)) {\n throw configInvalid(`Loader feature name \"${feature}\" is not a valid capability name.`);\n }\n if (!features.includes(feature)) features.push(feature);\n }\n if (features.length === 0) {\n throw configInvalid('Loader attribute \"data-viceme-features\" must list at least one feature.');\n }\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\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). Core clients are shared by\n * `major + region + workKey`; capability 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 './mount-handle.ts';\n\nexport interface RegisteredClient {\n clientKey: string;\n client: ViceMeClient;\n ready: Promise<void>;\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","/**\n * Stable `viceme:*` DOM events.\n *\n * Dispatch target is the mount host element; configuration errors that happen\n * before a host exists are dispatched on `document`. Event details carry an\n * allowlisted field set only — never tokens, cookies, provider payloads, or\n * internal stacks.\n */\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 type VicemeEventType =\n 'viceme:ready' | 'viceme:capability-ready' | 'viceme:error' | 'viceme:destroyed';\n\nexport type VicemeEventDetailMap = {\n 'viceme:ready': VicemeReadyDetail;\n 'viceme:capability-ready': VicemeCapabilityReadyDetail;\n 'viceme:error': VicemeErrorDetail;\n 'viceme:destroyed': VicemeDestroyedDetail;\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]);\n\n/** Strip anything outside the documented allowlist before dispatch. */\nexport function sanitizeDetail(\n type: VicemeEventType,\n detail: VicemeEventDetailMap[VicemeEventType],\n): VicemeEventDetailMap[VicemeEventType] {\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 * 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.1.5';\n\n/** Public API major carried by this build (loader namespace `v1`). */\nexport const API_MAJOR = 1;\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. Load the same-version core, then each declared feature chunk in order.\n * 6. Create the client, then mount; handles land in an internal registry.\n * 7. Re-running the same instance key returns the original handle — no\n * duplicate sessions, subscriptions, or DOM.\n * 8. A failing capability destroys only its own partial state; the rest of\n * the page and other capabilities keep working.\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 } from './attributes.ts';\nimport { LoaderRegistry, clientKeyOf, type RegisteredInstance } from './registry.ts';\nimport type { CapabilityMountHandle, CapabilityMountFunction } from './mount-handle.ts';\nimport { dispatchViceMeEvent, type VicemeErrorDetail } from './events.ts';\nimport { configInvalid, ViceMeError } from '../core/errors.ts';\nimport type { ViceMeClient, ViceMeMountedInstance } from '../core/client.ts';\nimport { API_MAJOR } from '../version.ts';\n\nexport interface ReleaseManifest {\n version: string;\n apiMajor: number;\n loader: string;\n features: Record<string, string>;\n}\n\ninterface CoreModule {\n createViceMe: (config: unknown) => ViceMeClient;\n}\n\n/** Internal surface the core implementation provides to the loader. */\ninterface InternalCoreClient extends ViceMeClient {\n markDegraded(): void;\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;\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 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 let response: Response;\n try {\n response = await fetchWithTimeout(manifestUrl);\n } catch {\n response = { ok: false, status: 0 } as Response;\n }\n // Alias path (e.g. /sdk/v1/) holds no manifest on the S3 topology: it\n // carries only the loader object plus the version POINTER. Resolve the\n // pointer and load the exact version beside it.\n if (!response.ok) {\n const aliasVersion = await resolveAliasPointer(manifestUrl);\n if (aliasVersion !== undefined) {\n const aliasUrl = new URL(`/viceme-sdk/${aliasVersion}/manifest.json`, manifestUrl);\n return { manifest: await parseManifest(await fetchWithTimeout(aliasUrl)), baseUrl: aliasUrl };\n }\n }\n return { manifest: await parseManifest(response), baseUrl: manifestUrl };\n}\n\nfunction fetchWithTimeout(url: URL): Promise<Response> {\n const signal =\n typeof AbortSignal !== 'undefined' && typeof AbortSignal.timeout === 'function'\n ? AbortSignal.timeout(MANIFEST_TIMEOUT_MS)\n : undefined;\n return fetch(url, { credentials: 'omit', signal });\n}\n\n/** Read /sdk/-/aliases/v1 when the loader itself sits under /sdk/v1/. */\nasync function resolveAliasPointer(manifestUrl: URL): Promise<string | undefined> {\n if (!/\\/viceme-sdk\\/[^/]+\\/manifest\\.json$/.test(manifestUrl.pathname)) return undefined;\n const segment = manifestUrl.pathname.split('/viceme-sdk/')[1]?.split('/')[0];\n if (segment !== `v${API_MAJOR}`) return undefined;\n try {\n const response = await fetchWithTimeout(new URL('/viceme-sdk/-/aliases/v1', manifestUrl));\n if (!response.ok) return undefined;\n const version = (await response.text()).trim();\n return /^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z.-]+)?$/.test(version) ? version : undefined;\n } catch {\n return undefined;\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.apiMajor !== API_MAJOR) {\n throw configInvalid('Release manifest major version does not match this loader.');\n }\n return manifest;\n}\n\nasync function loadCore(baseUrl: URL): Promise<CoreModule> {\n const coreUrl = new URL('index.js', baseUrl);\n const core = (await import(/* @vite-ignore */ coreUrl.href)) as Partial<CoreModule>;\n if (typeof core.createViceMe !== 'function') {\n throw configInvalid('SDK core chunk does not export createViceMe().');\n }\n return core as CoreModule;\n}\n\nconst KNOWN_ERROR_CODES: ReadonlySet<string> = new Set([\n 'CONFIG_INVALID',\n 'WORK_NOT_FOUND',\n 'ORIGIN_NOT_ALLOWED',\n 'CAPABILITY_DISABLED',\n 'CLIENT_DESTROYED',\n 'SESSION_EXPIRED',\n 'RATE_LIMITED',\n 'NETWORK_TIMEOUT',\n 'CHECKOUT_UNAVAILABLE',\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\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 let core: CoreModule;\n try {\n core = await loadCore(releaseBase);\n } catch (error) {\n emitError(host, error, { clientKey });\n return;\n }\n client = core.createViceMe({\n workKey: attributes.workKey,\n region: attributes.region,\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 };\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\n let mountedAny = false;\n const mounted: string[] = [];\n for (const capability of attributes.features) {\n // Same client + capability + element: reuse the original handle.\n if (sharedState().registry.findInstance(clientKey, capability, host)) continue;\n\n const fileName = manifest.features[capability];\n if (typeof fileName !== 'string') {\n (client as InternalCoreClient).markDegraded();\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 continue;\n }\n\n try {\n const chunkUrl = new URL(fileName, releaseBase);\n const module = (await import(/* @vite-ignore */ chunkUrl.href)) as {\n mount?: unknown;\n };\n if (typeof module.mount !== 'function') {\n throw configInvalid(`Capability chunk \"${capability}\" does not export mount().`);\n }\n const raw = (await (module.mount as CapabilityMountFunction)(client, {\n target: host,\n theme: attributes.theme,\n })) as CapabilityMountHandle;\n const instance = sharedState().registry.registerInstance(clientKey, capability, host, raw);\n mountedAny = true;\n mounted.push(capability);\n dispatchViceMeEvent(host, 'viceme:capability-ready', {\n clientKey,\n instanceKey: instance.instanceKey,\n capability,\n version: manifest.version,\n });\n } catch (error) {\n // Only this capability's partial state is discarded; everything else\n // (including the host page) keeps working.\n (client as InternalCoreClient).markDegraded();\n emitError(host, error, { clientKey, capability });\n }\n }\n\n if (mountedAny) {\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 sessions 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","REGIONS","PUBLIC_API_BASE_URLS","resolveApiBaseUrl","region","isValidWorkKey","isValidRegion","validatePublicConfig","input","raw","known","key","KNOWN_ATTRIBUTES","FEATURE_NAME_PATTERN","THEMES","parseLoaderAttributes","element","name","workKey","rawFeatures","features","part","feature","target","rawTheme","clientKeyOf","majorVersion","LoaderRegistry","#clients","#instances","#elements","#elementCounter","clientKey","entry","instanceKey","capability","compositeKey","byElement","existing","instance","i","ALLOWED_KEYS","sanitizeDetail","type","detail","allowed","result","dispatchViceMeEvent","event","SDK_VERSION","API_MAJOR","MANIFEST_TIMEOUT_MS","STATE_KEY","sharedState","state","destroyInstanceInternal","wrapInstance","defineHidden","ensureNamespace","version","global","versions","namespace","whenDomReady","resolve","fetchReleaseManifest","manifestUrl","response","fetchWithTimeout","aliasVersion","resolveAliasPointer","aliasUrl","parseManifest","url","signal","body","manifest","loadCore","baseUrl","core","KNOWN_ERROR_CODES","toErrorDetail","error","candidate","emitError","extra","runAutoLoader","script","attributes","releaseBase","host","matches","client","ready","mountedAny","mounted","fileName","module","enqueueRun","queue","run","bootstrap","explicit","__bootstrapForTests"],"mappings":"yBA8BA,MAAMA,MAAyD,IAAI,CACjE,eACA,kBACA,uBACA,gBACF,CAAC,EAEM,MAAMC,UAAoB,KAAM,CAC5B,KACA,UACA,UACA,WAET,YAAYC,EAAuB,CACjC,MAAMA,EAAK,OAAO,EAClB,KAAK,KAAO,cACZ,KAAK,KAAOA,EAAK,KACjB,KAAK,UAAYA,EAAK,WAAaF,EAAqB,IAAIE,EAAK,IAAI,EACrE,KAAK,UAAYA,EAAK,UACtB,KAAK,WAAaA,EAAK,UACzB,CAGA,QAKE,CACA,MAAMC,EAKF,CAAE,KAAM,KAAK,KAAM,UAAW,KAAK,SAAA,EACvC,OAAI,KAAK,YAAc,SAAWA,EAAK,UAAY,KAAK,WACpD,KAAK,aAAe,SAAWA,EAAK,WAAa,KAAK,YACnDA,CACT,CACF,CAEO,SAASC,EAAcC,EAAsC,CAClE,OAAOA,aAAiBJ,CAC1B,CAGO,SAASK,EAAcC,EAA8B,CAC1D,OAAO,IAAIN,EAAY,CAAE,KAAM,iBAAkB,QAAAM,EAAS,UAAW,GAAO,CAC9E,CAGO,SAASC,IAA+B,CAC7C,OAAO,IAAIP,EAAY,CACrB,KAAM,mBACN,QAAS,oCACT,UAAW,EAAA,CACZ,CACH,CCjEA,MAAMQ,EAA+B,IAAI,IAAI,CAAC,KAAM,QAAQ,CAAC,EAOhDC,EAA+D,CAC1E,GAAI,wBACJ,OAAQ,uBACV,EAEO,SAASC,GAAkBC,EAA8B,CAC9D,OAAOF,EAAqBE,CAAM,CACpC,CAEO,SAASC,EAAeR,EAAiC,CAC9D,OAAO,OAAOA,GAAU,UAAY,6BAA6B,KAAKA,CAAK,CAC7E,CAEO,SAASS,EAAcT,EAAuC,CACnE,OAAO,OAAOA,GAAU,UAAYI,EAAQ,IAAIJ,CAAK,CACvD,CAMO,SAASU,GAAqBC,EAA8B,CACjE,GAAI,OAAOA,GAAU,UAAYA,IAAU,KACzC,MAAMV,EAAc,8CAA8C,EAEpE,MAAMW,EAAMD,EAENE,EAAQ,IAAI,IAAI,CAAC,UAAW,SAAU,QAAQ,CAAC,EACrD,UAAWC,KAAO,OAAO,KAAKF,CAAG,EAC/B,GAAI,CAACC,EAAM,IAAIC,CAAG,EAChB,MAAMb,EAAc,gCAAgCa,CAAG,IAAI,EAG/D,GAAI,CAACN,EAAeI,EAAI,OAAO,EAC7B,MAAMX,EAAc,oEAAoE,EAE1F,GAAI,CAACQ,EAAcG,EAAI,MAAM,EAC3B,MAAMX,EAAc,wDAAwD,EAE9E,GAAIW,EAAI,SAAW,QAAa,EAAEA,EAAI,kBAAkB,aACtD,MAAMX,EAAc,sDAAsD,EAE5E,MAAO,CAAE,QAASW,EAAI,QAAS,OAAQA,EAAI,OAAQ,OAAQA,EAAI,MAAA,CACjE,CC/CA,MAAMG,MAA4C,IAAI,CACpD,mBACA,qBACA,uBACA,qBACA,oBAEA,oBACF,CAAC,EAEKC,EAAuB,yBACvBC,EAA8B,IAAI,IAAI,CAAC,QAAS,OAAQ,MAAM,CAAC,EAE9D,SAASC,EAAsBC,EAAoC,CACxE,UAAWC,KAAQD,EAAQ,oBACzB,GAAIC,EAAK,WAAW,cAAc,GAAK,CAACL,EAAiB,IAAIK,CAAI,EAC/D,MAAMnB,EAAc,6BAA6BmB,CAAI,IAAI,EAI7D,MAAMC,EAAUF,EAAQ,aAAa,kBAAkB,EACvD,GAAI,CAACX,EAAea,CAAO,EACzB,MAAMpB,EAAc,0EAA0E,EAGhG,MAAMM,EAASY,EAAQ,aAAa,oBAAoB,EACxD,GAAI,CAACV,EAAcF,CAAM,EACvB,MAAMN,EAAc,iEAAiE,EAGvF,MAAMqB,EAAcH,EAAQ,aAAa,sBAAsB,EAC/D,GAAIG,IAAgB,MAAQA,EAAY,KAAA,IAAW,GACjD,MAAMrB,EAAc,sDAAsD,EAE5E,MAAMsB,EAAqB,CAAA,EAC3B,UAAWC,KAAQF,EAAY,MAAM,GAAG,EAAG,CACzC,MAAMG,EAAUD,EAAK,KAAA,EACrB,GAAIC,IAAY,GAChB,IAAI,CAACT,EAAqB,KAAKS,CAAO,EACpC,MAAMxB,EAAc,wBAAwBwB,CAAO,mCAAmC,EAEnFF,EAAS,SAASE,CAAO,GAAGF,EAAS,KAAKE,CAAO,EACxD,CACA,GAAIF,EAAS,SAAW,EACtB,MAAMtB,EAAc,yEAAyE,EAG/F,MAAMyB,EAASP,EAAQ,aAAa,oBAAoB,EACxD,GAAIO,IAAW,GACb,MAAMzB,EAAc,+DAA+D,EAGrF,GAAIyB,IAAW,KACb,MAAMzB,EACJ,+EAAA,EAIJ,MAAM0B,EAAWR,EAAQ,aAAa,mBAAmB,EACzD,GAAIQ,IAAa,MAAQ,CAACV,EAAO,IAAIU,CAAQ,EAC3C,MAAM1B,EAAc,0EAA0E,EAGhG,MAAO,CACL,QAAAoB,EACA,OAAAd,EACA,SAAAgB,EACA,OAAAG,EACA,MAAQC,GAAY,MAAA,CAExB,CC/DO,SAASC,EAAYC,EAAsBtB,EAAgBc,EAAyB,CACzF,MAAO,IAAIQ,CAAY,IAAItB,CAAM,IAAIc,CAAO,EAC9C,CAEO,MAAMS,CAAe,CACjBC,OAAe,IACfC,OAAiB,IAEjBC,OAAgB,IACzBC,GAAkB,EAElB,UAAUC,EAAiD,CACzD,OAAO,KAAKJ,GAAS,IAAII,CAAS,CACpC,CAEA,eAAeC,EAA+B,CAC5C,KAAKL,GAAS,IAAIK,EAAM,UAAWA,CAAK,CAC1C,CAEA,iBAAiBD,EAAyB,CACxC,KAAKJ,GAAS,OAAOI,CAAS,CAChC,CAEA,YAAYE,EAAqD,CAC/D,OAAO,KAAKL,GAAW,IAAIK,CAAW,CACxC,CAGA,aACEF,EACAG,EACAnB,EACgC,CAChC,OAAO,KAAKc,GAAU,IAAI,GAAGE,CAAS,KAAKG,CAAU,EAAE,GAAG,IAAInB,CAAO,CACvE,CAEA,iBACEgB,EACAG,EACAnB,EACAP,EACoB,CACpB,MAAM2B,EAAe,GAAGJ,CAAS,KAAKG,CAAU,GAChD,IAAIE,EAAY,KAAKP,GAAU,IAAIM,CAAY,EAC3CC,IAAc,SAChBA,MAAgB,QAChB,KAAKP,GAAU,IAAIM,EAAcC,CAAS,GAE5C,MAAMC,EAAWD,EAAU,IAAIrB,CAAO,EACtC,GAAIsB,EAAU,OAAOA,EAErB,KAAKP,IAAmB,EACxB,MAAMQ,EAA+B,CACnC,YAAa,GAAGP,CAAS,KAAKG,CAAU,OAAO,KAAKJ,EAAe,GACnE,UAAAC,EACA,WAAAG,EACA,KAAMnB,EACN,IAAAP,EACA,UAAW,EAAA,EAEb,YAAKoB,GAAW,IAAIU,EAAS,YAAaA,CAAQ,EAClDF,EAAU,IAAIrB,EAASuB,CAAQ,EACxBA,CACT,CAEA,eAAeL,EAAqD,CAClE,MAAMK,EAAW,KAAKV,GAAW,IAAIK,CAAW,EAChD,GAAKK,EACL,YAAKV,GAAW,OAAOK,CAAW,EAClC,KAAKJ,GAAU,IAAI,GAAGS,EAAS,SAAS,KAAKA,EAAS,UAAU,EAAE,GAAG,OAAOA,EAAS,IAAI,EAClFA,CACT,CAEA,mBAAmBP,EAAyC,CAC1D,MAAO,CAAC,GAAG,KAAKH,GAAW,OAAA,CAAQ,EAAE,OAAQW,GAAMA,EAAE,YAAcR,CAAS,CAC9E,CACF,CC1DA,MAAMS,MAAsE,IAAI,CAC9E,CAAC,eAAgB,IAAI,IAAI,CAAC,YAAa,UAAW,eAAgB,SAAS,CAAC,CAAC,EAC7E,CAAC,0BAA2B,IAAI,IAAI,CAAC,YAAa,cAAe,aAAc,SAAS,CAAC,CAAC,EAC1F,CACE,eACA,IAAI,IAAI,CAAC,YAAa,cAAe,aAAc,OAAQ,YAAa,WAAW,CAAC,CAAA,EAEtF,CAAC,mBAAoB,IAAI,IAAI,CAAC,YAAa,cAAe,YAAY,CAAC,CAAC,CAC1E,CAAC,EAGM,SAASC,EACdC,EACAC,EACuC,CACvC,MAAMC,EAAUJ,EAAa,IAAIE,CAAI,EAC/BG,EAAkC,CAAA,EACxC,SAAW,CAACnC,EAAKd,CAAK,IAAK,OAAO,QAAQ+C,CAAM,EAC1CC,EAAQ,IAAIlC,CAAG,GAAKd,IAAU,SAAWiD,EAAOnC,CAAG,EAAId,GAE7D,OAAOiD,CACT,CAEO,SAASC,EACdxB,EACAoB,EACAC,EACM,CACN,MAAMI,EAAQ,IAAI,YAAYL,EAAM,CAClC,OAAQD,EAAeC,EAAMC,CAAM,EACnC,QAAS,GACT,SAAU,GACV,WAAY,EAAA,CACb,EACDrB,EAAO,cAAcyB,CAAK,CAC5B,CC/EO,MAAMC,GAAc,QAGdC,EAAY,ECwDnBC,EAAsB,IAQtBC,EAAY,OAAO,IAAI,wBAAwB,EAQrD,SAASC,GAAiC,CAExC,MAAMf,EADS,WACSc,CAAS,EACjC,GAAId,EAAU,OAAOA,EACrB,MAAMgB,EAA2B,CAC/B,SAAU,IAAI3B,EACd,MAAO,CAAE,QAAS,QAAQ,SAAQ,CAAE,EAEtC,cAAO,eAAe,WAAYyB,EAAW,CAC3C,MAAOE,EACP,SAAU,GACV,aAAc,GACd,WAAY,EAAA,CACb,EACMA,CACT,CAMA,SAASC,EAAwBhB,EAAoC,CACnE,GAAI,CAAAA,EAAS,UACb,CAAAA,EAAS,UAAY,GACrBc,EAAA,EAAc,SAAS,eAAed,EAAS,WAAW,EAC1D,GAAI,CACFA,EAAS,IAAI,QAAA,CACf,QAAA,CACEQ,EAAoBR,EAAS,KAAM,mBAAoB,CACrD,UAAWA,EAAS,UACpB,YAAaA,EAAS,YACtB,WAAYA,EAAS,UAAA,CACtB,CACH,EACF,CAEA,SAASiB,EAAajB,EAAqD,CACzE,MAAO,CACL,YAAaA,EAAS,YACtB,WAAYA,EAAS,WACrB,QAAS,IAAMgB,EAAwBhB,CAAQ,CAAA,CAEnD,CAMA,SAASkB,EAAalC,EAAgBZ,EAAad,EAAsB,CACvE,OAAO,eAAe0B,EAAQZ,EAAK,CACjC,MAAAd,EACA,SAAU,GACV,aAAc,GACd,WAAY,EAAA,CACb,CACH,CAEO,SAAS6D,EAAgBC,EAA0C,CAExE,IAAIC,EADW,WACK,OACfA,IACHA,EAAS,CAAA,EACTH,EAAa,WAAY,SAAUG,CAAM,GAE3C,IAAIC,EAAWD,EAAO,SACjBC,IACHA,EAAW,CAAA,EACXJ,EAAaG,EAAQ,WAAYC,CAAQ,GAE3C,MAAMvB,EAAWuB,EAAS,IAAIX,CAAS,EAAE,EACzC,GAAIZ,EAAU,OAAOA,EAErB,MAAMwB,EAAqC,CACzC,QAAAH,EACA,UAAU3B,EAA0C,CAClD,MAAMC,EAAQoB,EAAA,EAAc,SAAS,UAAUrB,CAAS,EACxD,OAAKC,EAGEA,EAAM,MAAM,KAAK,IAAMA,EAAM,MAAM,EAFjC,QAAQ,OAAOnC,EAAc,sBAAsBkC,CAAS,IAAI,CAAC,CAG5E,EACA,YAAYE,EAAwD,CAClE,MAAMK,EAAWc,EAAA,EAAc,SAAS,YAAYnB,CAAW,EAC/D,OAAOK,EAAWiB,EAAajB,CAAQ,EAAI,MAC7C,EACA,gBAAgBL,EAA2B,CACzC,MAAMK,EAAWc,EAAA,EAAc,SAAS,YAAYnB,CAAW,EAC3DK,KAAkCA,CAAQ,CAChD,EACA,cAAcP,EAAyB,CACrC,UAAWO,KAAYc,EAAA,EAAc,SAAS,mBAAmBrB,CAAS,EACxEuB,EAAwBhB,CAAQ,EAElC,MAAMN,EAAQoB,EAAA,EAAc,SAAS,UAAUrB,CAAS,EACxDqB,IAAc,SAAS,iBAAiBrB,CAAS,EACjDC,GAAO,OAAO,QAAA,CAChB,CAAA,EAEF,OAAAwB,EAAaI,EAAU,IAAIX,CAAS,GAAIY,CAAS,EAC1CA,CACT,CAMA,SAASC,GAA8B,CACrC,OAAI,SAAS,aAAe,UAAkB,QAAQ,QAAA,EAC/C,IAAI,QAASC,GAAY,CAC9B,SAAS,iBAAiB,mBAAoB,IAAMA,EAAA,EAAW,CAAE,KAAM,GAAM,CAC/E,CAAC,CACH,CAEA,eAAeC,EACbC,EACsD,CACtD,IAAIC,EACJ,GAAI,CACFA,EAAW,MAAMC,EAAiBF,CAAW,CAC/C,MAAQ,CACNC,EAAW,CAAE,GAAI,GAAO,OAAQ,CAAA,CAClC,CAIA,GAAI,CAACA,EAAS,GAAI,CAChB,MAAME,EAAe,MAAMC,EAAoBJ,CAAW,EAC1D,GAAIG,IAAiB,OAAW,CAC9B,MAAME,EAAW,IAAI,IAAI,eAAeF,CAAY,iBAAkBH,CAAW,EACjF,MAAO,CAAE,SAAU,MAAMM,EAAc,MAAMJ,EAAiBG,CAAQ,CAAC,EAAG,QAASA,CAAA,CACrF,CACF,CACA,MAAO,CAAE,SAAU,MAAMC,EAAcL,CAAQ,EAAG,QAASD,CAAA,CAC7D,CAEA,SAASE,EAAiBK,EAA6B,CACrD,MAAMC,EACJ,OAAO,YAAgB,KAAe,OAAO,YAAY,SAAY,WACjE,YAAY,QAAQvB,CAAmB,EACvC,OACN,OAAO,MAAMsB,EAAK,CAAE,YAAa,OAAQ,OAAAC,EAAQ,CACnD,CAGA,eAAeJ,EAAoBJ,EAA+C,CAGhF,GAFI,GAAC,uCAAuC,KAAKA,EAAY,QAAQ,GACrDA,EAAY,SAAS,MAAM,cAAc,EAAE,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC,IAC3D,IAAIhB,CAAS,IAC7B,GAAI,CACF,MAAMiB,EAAW,MAAMC,EAAiB,IAAI,IAAI,2BAA4BF,CAAW,CAAC,EACxF,GAAI,CAACC,EAAS,GAAI,OAClB,MAAMR,GAAW,MAAMQ,EAAS,KAAA,GAAQ,KAAA,EACxC,MAAO,oCAAoC,KAAKR,CAAO,EAAIA,EAAU,MACvE,MAAQ,CACN,MACF,CACF,CAEA,eAAea,EAAcL,EAA8C,CACzE,GAAI,CAACA,EAAS,GACZ,MAAMrE,EAAc,2CAA2CqE,EAAS,MAAM,IAAI,EAEpF,MAAMQ,EAAgB,MAAMR,EAAS,KAAA,EACrC,GACE,OAAOQ,GAAS,UAChBA,IAAS,MACT,OAAQA,EAAyB,SAAY,UAC7C,OAAQA,EAAyB,UAAa,UAC9C,OAAQA,EAAyB,UAAa,UAC7CA,EAAyB,WAAa,KAEvC,MAAM7E,EAAc,gCAAgC,EAEtD,MAAM8E,EAAWD,EACjB,GAAIC,EAAS,WAAa1B,EACxB,MAAMpD,EAAc,4DAA4D,EAElF,OAAO8E,CACT,CAEA,eAAeC,EAASC,EAAmC,CAEzD,MAAMC,EAAQ,MAAM,OADJ,IAAI,IAAI,WAAYD,CAAO,EACW,MACtD,GAAI,OAAOC,EAAK,cAAiB,WAC/B,MAAMjF,EAAc,gDAAgD,EAEtE,OAAOiF,CACT,CAEA,MAAMC,MAA6C,IAAI,CACrD,iBACA,iBACA,qBACA,sBACA,mBACA,kBACA,eACA,kBACA,uBACA,gBACF,CAAC,EAOD,SAASC,EAAcC,EAAmC,CACxD,GAAI,OAAOA,GAAU,UAAYA,IAAU,KAAM,CAC/C,MAAMC,EAAYD,EAClB,GACE,OAAOC,EAAU,MAAS,UAC1BH,EAAkB,IAAIG,EAAU,IAAI,GACpC,OAAOA,EAAU,WAAc,UAC/B,CACA,MAAMvC,EAA4B,CAChC,KAAMuC,EAAU,KAChB,UAAWA,EAAU,SAAA,EAEvB,OAAI,OAAOA,EAAU,WAAc,WAAUvC,EAAO,UAAYuC,EAAU,WACtE,OAAOA,EAAU,YAAe,WAAUvC,EAAO,WAAauC,EAAU,YACrEvC,CACT,CACF,CACA,MAAO,CAAE,KAAM,iBAAkB,UAAW,EAAA,CAC9C,CAEA,SAASwC,EACP7D,EACA2D,EACAG,EAAsF,CAAA,EAChF,CACNtC,EAAoBxB,EAAQ,eAAgB,CAAE,GAAG0D,EAAcC,CAAK,EAAG,GAAGG,EAAO,CACnF,CAEA,eAAsBC,EAAcC,EAA0C,CAC5E,IAAIC,EACJ,GAAI,CACFA,EAAazE,EAAsBwE,CAAM,CAC3C,OAASL,EAAO,CAEdE,EAAU,SAAUF,CAAK,EACzB,MACF,CAEA,GAAI,CAACK,EAAO,IAAK,CACfH,EAAU,SAAUtF,EAAc,mCAAmC,CAAC,EACtE,MACF,CACA,MAAMoE,EAAc,IAAI,IAAI,gBAAiBqB,EAAO,GAAG,EAEvD,IAAIX,EACAa,EACJ,GAAI,EACD,CAAE,SAAAb,EAAU,QAASa,GAAgB,MAAMxB,EAAqBC,CAAW,EAC9E,OAASgB,EAAO,CACdE,EAAU,SAAUF,EAAO,CACzB,UAAWzD,EAAYyB,EAAWsC,EAAW,OAAQA,EAAW,OAAO,CAAA,CACxE,EACD,MACF,CAEA,MAAMzB,EAAA,EAEN,IAAI2B,EACJ,GAAI,CACF,MAAMC,EAAU,SAAS,iBAAiBH,EAAW,MAAO,EAC5D,GAAIG,EAAQ,SAAW,EACrB,MAAM7F,EACJ,kBAAkB0F,EAAW,MAAM,4CAAA,EAGvC,GAAIG,EAAQ,OAAS,EACnB,MAAM7F,EACJ,kBAAkB0F,EAAW,MAAM,aAAaG,EAAQ,MAAM,qCAAA,EAGlED,EAAOC,EAAQ,CAAC,CAClB,OAAST,EAAO,CACdE,EAAU,SAAUF,EAAO,CACzB,UAAWzD,EAAYmD,EAAS,SAAUY,EAAW,OAAQA,EAAW,OAAO,CAAA,CAChF,EACD,MACF,CAEA,MAAMxD,EAAYP,EAAYmD,EAAS,SAAUY,EAAW,OAAQA,EAAW,OAAO,EACtF9B,EAAgBkB,EAAS,OAAO,EAGhC,IAAI3C,EAAQoB,EAAA,EAAc,SAAS,UAAUrB,CAAS,EAClD4D,EACJ,GAAI3D,EACF2D,EAAS3D,EAAM,WACV,CACL,IAAI8C,EACJ,GAAI,CACFA,EAAO,MAAMF,EAASY,CAAW,CACnC,OAASP,EAAO,CACdE,EAAUM,EAAMR,EAAO,CAAE,UAAAlD,CAAA,CAAW,EACpC,MACF,CACA4D,EAASb,EAAK,aAAa,CACzB,QAASS,EAAW,QACpB,OAAQA,EAAW,MAAA,CACpB,EACD,MAAMK,EAAQD,EAAO,MAAA,EAGhBC,EAAM,MAAM,IAAM,CAAC,CAAC,EACzB5D,EAAQ,CAAE,UAAAD,EAAW,OAAA4D,EAAQ,MAAAC,CAAA,EAC7BxC,IAAc,SAAS,eAAepB,CAAK,CAC7C,CAEA,GAAI,CACF,MAAMA,EAAM,KACd,OAASiD,EAAO,CACd7B,IAAc,SAAS,iBAAiBrB,CAAS,EACjD4D,EAAO,QAAA,EACPR,EAAUM,EAAMR,EAAO,CAAE,UAAAlD,CAAA,CAAW,EACpC,MACF,CAEA,IAAI8D,EAAa,GACjB,MAAMC,EAAoB,CAAA,EAC1B,UAAW5D,KAAcqD,EAAW,SAAU,CAE5C,GAAInC,IAAc,SAAS,aAAarB,EAAWG,EAAYuD,CAAI,EAAG,SAEtE,MAAMM,EAAWpB,EAAS,SAASzC,CAAU,EAC7C,GAAI,OAAO6D,GAAa,SAAU,CAC/BJ,EAA8B,aAAA,EAC/BR,EACEM,EACA,IAAIjG,EAAY,CACd,KAAM,sBACN,QAAS,eAAe0C,CAAU,iCAClC,UAAW,GACX,WAAAA,CAAA,CACD,EACD,CAAE,UAAAH,EAAW,WAAAG,CAAA,CAAW,EAE1B,QACF,CAEA,GAAI,CAEF,MAAM8D,EAAU,MAAM,OADL,IAAI,IAAID,EAAUP,CAAW,EACW,MAGzD,GAAI,OAAOQ,EAAO,OAAU,WAC1B,MAAMnG,EAAc,qBAAqBqC,CAAU,4BAA4B,EAEjF,MAAM1B,EAAO,MAAOwF,EAAO,MAAkCL,EAAQ,CACnE,OAAQF,EACR,MAAOF,EAAW,KAAA,CACnB,EACKjD,EAAWc,IAAc,SAAS,iBAAiBrB,EAAWG,EAAYuD,EAAMjF,CAAG,EACzFqF,EAAa,GACbC,EAAQ,KAAK5D,CAAU,EACvBY,EAAoB2C,EAAM,0BAA2B,CACnD,UAAA1D,EACA,YAAaO,EAAS,YACtB,WAAAJ,EACA,QAASyC,EAAS,OAAA,CACnB,CACH,OAASM,EAAO,CAGbU,EAA8B,aAAA,EAC/BR,EAAUM,EAAMR,EAAO,CAAE,UAAAlD,EAAW,WAAAG,EAAY,CAClD,CACF,CAEI2D,GACF/C,EAAoB2C,EAAM,eAAgB,CACxC,UAAA1D,EACA,QAASwD,EAAW,QACpB,aAAcO,EACd,QAASnB,EAAS,OAAA,CACnB,CAEL,CAWA,SAASsB,EAAWX,EAA0C,CAC5D,KAAM,CAAE,MAAAY,CAAA,EAAU9C,EAAA,EACZ+C,EAAMD,EAAM,QAAQ,KAAK,IAAMb,EAAcC,CAAM,CAAC,EAC1D,OAAAY,EAAM,QAAUC,EAAI,MAAM,IAAM,CAAC,CAAC,EAC3BA,CACT,CAEA,SAASC,GAAkB,CACzB,GAAI,OAAO,SAAa,IAAa,OACrC,IAAId,EACF,SAAS,yBAAyB,kBAAoB,SAAS,cAAgB,KACjF,GAAI,CAACA,EAAQ,CACX,MAAMe,EAAW,SAAS,iBAAoC,4BAA4B,EACtFA,EAAS,SAAW,IAAGf,EAASe,EAAS,CAAC,GAAK,KACrD,CACKf,GACAW,EAAWX,CAAM,EAAE,MAAOL,GAAmB,CAChDE,EAAU,SAAUF,CAAK,CAC3B,CAAC,CACH,CAEAmB,EAAA,EAGO,MAAME,GAAsBF"}
|
|
1
|
+
{"version":3,"file":"viceme.min.js","sources":["../src/core/errors.ts","../src/core/config.ts","../src/loader/attributes.ts","../src/loader/registry.ts","../src/loader/events.ts","../src/core/lifecycle.ts","../src/core/client.ts","../src/version.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' | 'CAPABILITY_DISABLED' | 'CLIENT_DESTROYED' | 'INTERNAL_ERROR';\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(['INTERNAL_ERROR']);\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","/**\n * Public client configuration.\n *\n * Production `createViceMe()` accepts exactly `workKey` and `region`.\n * Endpoints, credentials, access policy, and provider state are not client\n * configuration: the hosted Shop runtime owns those concerns.\n */\n\nimport { configInvalid } from './errors.ts';\nexport type ViceMeRegion = 'cn' | 'global';\n\nexport interface ViceMeConfig {\n /** Public opaque work key (`wrk_…`). Locates a Work; it is not a secret. */\n workKey: string;\n /** Selects the hosted Shop region. */\n region: ViceMeRegion;\n}\n\nconst REGIONS: ReadonlySet<string> = new Set(['cn', 'global']);\n\nexport function isValidWorkKey(value: unknown): value is string {\n return typeof value === 'string' && /^wrk_[A-Za-z0-9_-]{4,124}$/.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']);\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('Configuration field \"workKey\" must be a public work key (\"wrk_…\").');\n }\n if (!isValidRegion(raw.region)) {\n throw configInvalid('Configuration field \"region\" must be \"cn\" or \"global\".');\n }\n return {\n workKey: raw.workKey,\n region: raw.region,\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';\n\nexport interface LoaderAttributes {\n workKey: string;\n region: ViceMeRegion;\n /** The only released public feature. */\n features: string[];\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']);\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 (\"wrk_…\").');\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 if (rawFeatures !== 'danmaku') {\n throw configInvalid('Loader attribute \"data-viceme-features\" must be exactly \"danmaku\".');\n }\n const features = ['danmaku'];\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 './mount-handle.ts';\n\nexport interface RegisteredClient {\n clientKey: string;\n client: ViceMeClient;\n ready: Promise<void>;\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","/**\n * Stable `viceme:*` DOM events.\n *\n * Dispatch target is the mount host element; configuration errors that happen\n * before a host exists are dispatched on `document`. Event details carry an\n * allowlisted field set only — never tokens, cookies, provider payloads, or\n * internal stacks.\n */\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 type VicemeEventType =\n 'viceme:ready' | 'viceme:capability-ready' | 'viceme:error' | 'viceme:destroyed';\n\nexport type VicemeEventDetailMap = {\n 'viceme:ready': VicemeReadyDetail;\n 'viceme:capability-ready': VicemeCapabilityReadyDetail;\n 'viceme:error': VicemeErrorDetail;\n 'viceme:destroyed': VicemeDestroyedDetail;\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]);\n\n/** Strip anything outside the documented allowlist before dispatch. */\nexport function sanitizeDetail(\n type: VicemeEventType,\n detail: VicemeEventDetailMap[VicemeEventType],\n): VicemeEventDetailMap[VicemeEventType] {\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 * Local ViceMe client for the public hosted danmaku capability.\n *\n * Initialization performs no network request. The static loader owns release\n * manifest/chunk loading, while the hosted iframe owns Shop API calls.\n */\n\nimport { clientDestroyed } from './errors.ts';\nimport { Lifecycle, type ViceMeClientState } from './lifecycle.ts';\nimport type { ViceMeConfig, ViceMeRegion } from './config.ts';\n\nconst MARK_DEGRADED = Symbol('ViceMeClient.markDegraded');\n\ninterface DegradableViceMeClient {\n [MARK_DEGRADED](): void;\n}\n\nexport interface ViceMeClient {\n readonly workKey: string;\n readonly region: ViceMeRegion;\n readonly state: ViceMeClientState;\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; not part of the client object's string-keyed surface. */\nexport function markClientDegraded(client: ViceMeClient): void {\n if (MARK_DEGRADED in client) {\n (client as ViceMeClient & DegradableViceMeClient)[MARK_DEGRADED]();\n }\n}\n\nexport class ViceMeClientImpl implements ViceMeClient {\n readonly #lifecycle = new Lifecycle();\n readonly #config: ViceMeConfig;\n #readyPromise: Promise<void> | undefined;\n\n constructor(config: ViceMeConfig) {\n this.#config = config;\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 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 hasCapability(name: string): boolean {\n return !this.#lifecycle.destroyed && name === 'danmaku';\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 [MARK_DEGRADED](): void {\n if (this.#lifecycle.state === 'READY') this.#lifecycle.transition('DEGRADED');\n }\n\n destroy(): void {\n if (this.#lifecycle.destroyed) return;\n this.#lifecycle.transition('DESTROYED');\n this.#lifecycle.clearListeners();\n this.#readyPromise = undefined;\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.2.0';\n\n/** Public API major carried by this build (loader namespace `v1`). */\nexport const API_MAJOR = 1;\n","/**\n * `@viceme-ai/sdk` public entry.\n *\n * Production consumers get a local public-danmaku client plus public types.\n */\n\nimport { 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 { SDK_VERSION, API_MAJOR } from './version.ts';\n\nexport { ViceMeError, isViceMeError, SDK_VERSION, API_MAJOR };\nexport type {\n ViceMeClient,\n ViceMeMountedInstance,\n ViceMeConfig,\n ViceMeRegion,\n ViceMeClientState,\n ViceMeErrorCode,\n};\n\n/**\n * Create a local public-danmaku client for one Work.\n *\n * @example\n * ```ts\n * const client = createViceMe({ workKey: 'wrk_public_xxx', region: 'cn' });\n * await client.ready();\n * client.destroy();\n * ```\n */\nexport function createViceMe(config: unknown): ViceMeClient {\n const validated = validatePublicConfig(config);\n return new ViceMeClientImpl(validated);\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 * same-version danmaku chunk 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 } from './attributes.ts';\nimport { LoaderRegistry, clientKeyOf, type RegisteredInstance } from './registry.ts';\nimport type { CapabilityMountHandle, CapabilityMountFunction } from './mount-handle.ts';\nimport { dispatchViceMeEvent, type VicemeErrorDetail } from './events.ts';\nimport { 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 DANMAKU_FEATURE_PATH = 'danmaku.js';\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 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 let response: Response;\n try {\n response = await fetchWithTimeout(manifestUrl);\n } catch {\n response = { ok: false, status: 0 } as Response;\n }\n return { manifest: await parseManifest(response), baseUrl: manifestUrl };\n}\n\nfunction fetchWithTimeout(url: URL): Promise<Response> {\n const signal =\n typeof AbortSignal !== 'undefined' && typeof AbortSignal.timeout === 'function'\n ? AbortSignal.timeout(MANIFEST_TIMEOUT_MS)\n : undefined;\n return fetch(url, { credentials: 'omit', signal });\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);\n if (\n featureNames.length !== 1 ||\n featureNames[0] !== 'danmaku' ||\n manifest.features.danmaku !== DANMAKU_FEATURE_PATH\n ) {\n throw configInvalid('Release manifest features must be exactly danmaku.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\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 };\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 let mountedAny = false;\n const mounted: string[] = [];\n for (const capability of attributes.features) {\n // Same client + capability + element: reuse the original handle.\n if (sharedState().registry.findInstance(clientKey, capability, host)) continue;\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 continue;\n }\n\n try {\n const chunkUrl = new URL(fileName, releaseBase);\n const module = (await import(/* @vite-ignore */ chunkUrl.href)) as {\n mountDanmaku?: unknown;\n };\n if (typeof module.mountDanmaku !== 'function') {\n throw configInvalid(`Capability chunk \"${capability}\" does not export mountDanmaku().`);\n }\n if (sharedState().registry.getClient(clientKey) !== entry) return;\n const raw = (await (module.mountDanmaku as CapabilityMountFunction)(client, {\n target: host,\n theme: attributes.theme,\n })) as CapabilityMountHandle;\n if (sharedState().registry.getClient(clientKey) !== entry) {\n raw.destroy();\n return;\n }\n const instance = sharedState().registry.registerInstance(clientKey, capability, host, raw);\n mountedAny = true;\n mounted.push(capability);\n dispatchViceMeEvent(host, 'viceme:capability-ready', {\n clientKey,\n instanceKey: instance.instanceKey,\n capability,\n version: manifest.version,\n });\n } catch (error) {\n if (sharedState().registry.getClient(clientKey) !== entry) return;\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 }\n }\n\n if (mountedAny && 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","REGIONS","isValidWorkKey","isValidRegion","validatePublicConfig","input","raw","known","key","KNOWN_ATTRIBUTES","THEMES","parseLoaderAttributes","element","name","workKey","region","features","target","rawTheme","clientKeyOf","majorVersion","LoaderRegistry","#clients","#instances","#elements","#elementCounter","clientKey","entry","instanceKey","capability","compositeKey","byElement","existing","instance","i","ALLOWED_KEYS","sanitizeDetail","type","detail","allowed","result","dispatchViceMeEvent","event","ALLOWED_TRANSITIONS","Lifecycle","#state","#listeners","next","listener","MARK_DEGRADED","markClientDegraded","client","ViceMeClientImpl","#lifecycle","#config","#readyPromise","config","SDK_VERSION","API_MAJOR","createViceMe","validated","MANIFEST_TIMEOUT_MS","DANMAKU_FEATURE_PATH","STATE_KEY","sharedState","state","destroyInstanceInternal","wrapInstance","defineHidden","ensureNamespace","version","global","versions","namespace","whenDomReady","resolve","fetchReleaseManifest","manifestUrl","response","fetchWithTimeout","parseManifest","url","signal","body","manifest","featureNames","KNOWN_ERROR_CODES","toErrorDetail","error","candidate","emitError","extra","runAutoLoader","script","attributes","releaseBase","host","matches","ready","mountedAny","mounted","fileName","module","enqueueRun","queue","run","bootstrap","explicit","__bootstrapForTests"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viceme-ai/sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "ViceMe
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "ViceMe PUBLIC-only hosted danmaku SDK for static HTML, ESM, React, and Agent-generated sites.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"types": "./dist/index.d.ts",
|
|
16
16
|
"import": "./dist/index.js"
|
|
17
17
|
},
|
|
18
|
-
"./
|
|
19
|
-
"types": "./dist/
|
|
20
|
-
"import": "./dist/
|
|
18
|
+
"./danmaku": {
|
|
19
|
+
"types": "./dist/danmaku/index.d.ts",
|
|
20
|
+
"import": "./dist/danmaku.js"
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
@@ -33,13 +33,12 @@
|
|
|
33
33
|
"node": ">=20"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
|
-
"clean": "node ../../scripts/rmrf.mjs dist
|
|
37
|
-
"build": "pnpm clean && pnpm build:esm && pnpm build:loader && pnpm build:bootstrap && pnpm build:types && pnpm build:
|
|
36
|
+
"clean": "node ../../scripts/rmrf.mjs dist",
|
|
37
|
+
"build": "pnpm clean && pnpm build:esm && pnpm build:loader && pnpm build:bootstrap && pnpm build:types && pnpm build:manifest && pnpm build:license",
|
|
38
38
|
"build:esm": "vite build --config vite.config.esm.ts",
|
|
39
39
|
"build:loader": "vite build --config vite.config.loader.ts",
|
|
40
40
|
"build:bootstrap": "vite build --config vite.config.bootstrap.ts",
|
|
41
41
|
"build:types": "tsc -p tsconfig.build.json",
|
|
42
|
-
"build:fixture": "vite build --config vite.config.fixture.ts",
|
|
43
42
|
"build:manifest": "node ../../scripts/build-manifest.mjs",
|
|
44
43
|
"build:license": "node ../../scripts/sync-package-license.mjs",
|
|
45
44
|
"lint": "eslint .",
|