@viceme-ai/sdk 0.2.0 → 0.4.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.
Files changed (67) hide show
  1. package/README.md +46 -17
  2. package/dist/browser-events.d.ts +49 -0
  3. package/dist/browser-events.d.ts.map +1 -0
  4. package/dist/capability-mount.d.ts +15 -0
  5. package/dist/capability-mount.d.ts.map +1 -0
  6. package/dist/chunks/client-Cbldd7F2.js +949 -0
  7. package/dist/chunks/client-Cbldd7F2.js.map +1 -0
  8. package/dist/chunks/{version-BbUa2jZV.js → errors-B-Qv_azy.js} +27 -17
  9. package/dist/chunks/errors-B-Qv_azy.js.map +1 -0
  10. package/dist/chunks/version-C8DeBm39.js +6 -0
  11. package/dist/chunks/version-C8DeBm39.js.map +1 -0
  12. package/dist/core/build-endpoints.d.ts +5 -0
  13. package/dist/core/build-endpoints.d.ts.map +1 -1
  14. package/dist/core/capabilities.d.ts +79 -0
  15. package/dist/core/capabilities.d.ts.map +1 -0
  16. package/dist/core/client.d.ts +36 -8
  17. package/dist/core/client.d.ts.map +1 -1
  18. package/dist/core/config.d.ts +14 -4
  19. package/dist/core/config.d.ts.map +1 -1
  20. package/dist/core/errors.d.ts +1 -1
  21. package/dist/core/errors.d.ts.map +1 -1
  22. package/dist/core/presentation.d.ts +29 -0
  23. package/dist/core/presentation.d.ts.map +1 -0
  24. package/dist/danmaku/index.d.ts +1 -0
  25. package/dist/danmaku/index.d.ts.map +1 -1
  26. package/dist/danmaku/mount.d.ts +1 -1
  27. package/dist/danmaku/mount.d.ts.map +1 -1
  28. package/dist/danmaku.js +127 -125
  29. package/dist/danmaku.js.map +1 -1
  30. package/dist/generated/public-contract.d.ts +291 -43
  31. package/dist/generated/public-contract.d.ts.map +1 -1
  32. package/dist/index.d.ts +9 -4
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +114 -95
  35. package/dist/index.js.map +1 -1
  36. package/dist/loader/attributes.d.ts +3 -2
  37. package/dist/loader/attributes.d.ts.map +1 -1
  38. package/dist/loader/auto-loader.d.ts +1 -1
  39. package/dist/loader/auto-loader.d.ts.map +1 -1
  40. package/dist/loader/events.d.ts +1 -44
  41. package/dist/loader/events.d.ts.map +1 -1
  42. package/dist/loader/registry.d.ts +2 -1
  43. package/dist/loader/registry.d.ts.map +1 -1
  44. package/dist/manifest.json +44 -19
  45. package/dist/session/session.d.ts +68 -0
  46. package/dist/session/session.d.ts.map +1 -0
  47. package/dist/testing/test-adapter.d.ts +59 -0
  48. package/dist/testing/test-adapter.d.ts.map +1 -0
  49. package/dist/testing.d.ts +9 -0
  50. package/dist/testing.d.ts.map +1 -0
  51. package/dist/testing.js +76 -0
  52. package/dist/testing.js.map +1 -0
  53. package/dist/tip/index.d.ts +22 -0
  54. package/dist/tip/index.d.ts.map +1 -0
  55. package/dist/tip/mount.d.ts +5 -0
  56. package/dist/tip/mount.d.ts.map +1 -0
  57. package/dist/tip.js +137 -0
  58. package/dist/tip.js.map +1 -0
  59. package/dist/transport/transport.d.ts +46 -0
  60. package/dist/transport/transport.d.ts.map +1 -0
  61. package/dist/version.d.ts +1 -1
  62. package/dist/viceme.min.js +212 -1
  63. package/dist/viceme.min.js.map +1 -1
  64. package/package.json +10 -2
  65. package/dist/chunks/version-BbUa2jZV.js.map +0 -1
  66. package/dist/loader/mount-handle.d.ts +0 -25
  67. package/dist/loader/mount-handle.d.ts.map +0 -1
package/dist/danmaku.js CHANGED
@@ -1,202 +1,204 @@
1
- import { V as H, S as j } from "./chunks/version-BbUa2jZV.js";
2
- const ee = {
3
- cn: "https://viceme.cn",
4
- global: "https://viceme.ai"
5
- };
6
- function G(n = window, a = document) {
7
- const t = te(n, a), e = ae(n, a);
1
+ import { c as S, V as P, B as re } from "./chunks/errors-B-Qv_azy.js";
2
+ import { S as ae } from "./chunks/version-C8DeBm39.js";
3
+ function Z(a = window, t = document) {
4
+ const r = ne(a, t), e = oe(a, t);
8
5
  return {
9
- anchorKey: `page:${ne(t)}:scroll:${e}`,
6
+ anchorKey: `page:${se(r)}:scroll:${e}`,
10
7
  scrollBucket: e
11
8
  };
12
9
  }
13
- function te(n, a) {
14
- const t = a.querySelector('link[rel="canonical"][href]'), e = t?.href || n.location.href;
10
+ function ne(a, t) {
11
+ const r = t.querySelector('link[rel="canonical"][href]'), e = r?.href || a.location.href;
15
12
  try {
16
- const i = new URL(e, n.location.href);
17
- return i.username = "", i.password = "", t && !i.hash && n.location.hash && (i.hash = n.location.hash), i.toString();
13
+ const l = new URL(e, a.location.href);
14
+ return l.username = "", l.password = "", r && !l.hash && a.location.hash && (l.hash = a.location.hash), l.toString();
18
15
  } catch {
19
- return n.location.href;
16
+ return a.location.href;
20
17
  }
21
18
  }
22
- function ae(n, a) {
23
- const t = a.documentElement, e = a.body, i = n.scrollY || n.pageYOffset || t.scrollTop || e?.scrollTop || 0, m = Math.max(
24
- t.scrollHeight,
25
- t.offsetHeight,
26
- t.clientHeight,
19
+ function oe(a, t) {
20
+ const r = t.documentElement, e = t.body, l = a.scrollY || a.pageYOffset || r.scrollTop || e?.scrollTop || 0, m = Math.max(
21
+ r.scrollHeight,
22
+ r.offsetHeight,
23
+ r.clientHeight,
27
24
  e?.scrollHeight ?? 0,
28
25
  e?.offsetHeight ?? 0
29
- ), p = Math.max(0, m - n.innerHeight);
30
- if (p <= 1) return "0-100";
31
- const w = Math.max(0, Math.min(99, i / p * 100)), y = Math.min(90, Math.floor(w / 10) * 10);
26
+ ), v = Math.max(0, m - a.innerHeight);
27
+ if (v <= 1) return "0-100";
28
+ const f = Math.max(0, Math.min(99, l / v * 100)), y = Math.min(90, Math.floor(f / 10) * 10);
32
29
  return `${y}-${y + 10}`;
33
30
  }
34
- function ne(n) {
35
- let a = 3735928559 ^ n.length, t = 1103547991 ^ n.length;
36
- for (let e = 0; e < n.length; e += 1) {
37
- const i = n.charCodeAt(e);
38
- a = Math.imul(a ^ i, 2654435761), t = Math.imul(t ^ i, 1597334677);
31
+ function se(a) {
32
+ let t = 3735928559 ^ a.length, r = 1103547991 ^ a.length;
33
+ for (let e = 0; e < a.length; e += 1) {
34
+ const l = a.charCodeAt(e);
35
+ t = Math.imul(t ^ l, 2654435761), r = Math.imul(r ^ l, 1597334677);
39
36
  }
40
- return a = Math.imul(a ^ a >>> 16, 2246822507), a ^= Math.imul(t ^ t >>> 13, 3266489909), t = Math.imul(t ^ t >>> 16, 2246822507), t ^= Math.imul(a ^ a >>> 13, 3266489909), ((t >>> 0).toString(36).padStart(7, "0") + (a >>> 0).toString(36).padStart(7, "0")).slice(0, 16);
37
+ return t = Math.imul(t ^ t >>> 16, 2246822507), t ^= Math.imul(r ^ r >>> 13, 3266489909), r = Math.imul(r ^ r >>> 16, 2246822507), r ^= Math.imul(t ^ t >>> 13, 3266489909), ((r >>> 0).toString(36).padStart(7, "0") + (t >>> 0).toString(36).padStart(7, "0")).slice(0, 16);
41
38
  }
42
- const C = 32, oe = 56, re = 360, L = 480, se = 120, ie = 1e3, Y = 8e3;
43
- async function le(n, a) {
44
- if (await n.ready(), !n.hasCapability("danmaku"))
45
- throw new H({
39
+ const W = 32, ie = 56, le = 360, A = 480, ce = 120, de = 1e3, J = 8e3;
40
+ async function me(a, t) {
41
+ if (t.signal?.aborted) throw S();
42
+ if (await a.ready(), t.signal?.aborted) throw S();
43
+ if (!a.hasCapability("danmaku"))
44
+ throw new P({
46
45
  code: "CAPABILITY_DISABLED",
47
46
  message: "Danmaku is not available in this SDK build.",
48
47
  retryable: !1,
49
48
  capability: "danmaku"
50
49
  });
51
- const t = a.target.ownerDocument, e = t.defaultView;
50
+ const r = t.target.ownerDocument, e = r.defaultView;
52
51
  if (!e)
53
- throw new H({
52
+ throw new P({
54
53
  code: "CONFIG_INVALID",
55
54
  message: "Danmaku requires a browser document.",
56
55
  retryable: !1,
57
56
  capability: "danmaku"
58
57
  });
59
- const i = ee[n.region];
60
- let m = G(e, t);
61
- const p = t.documentElement.lang.trim() || e.navigator.language || "en";
62
- let w = !1, y, b, u, A = !1, P = 0, S = "", M = !1;
63
- const I = /* @__PURE__ */ new WeakSet(), x = /* @__PURE__ */ new Set(), h = t.createElement("div");
58
+ const l = re[a.region];
59
+ let m = Z(e, r);
60
+ const v = r.documentElement.lang.trim() || e.navigator.language || "en";
61
+ let f = !1, y, E, u, I = !1, O = 0, T = "", L = !1;
62
+ const x = /* @__PURE__ */ new WeakSet(), R = /* @__PURE__ */ new Set(), h = r.createElement("div");
64
63
  h.dataset.vicemeDanmaku = "mounted", h.style.all = "initial", h.style.position = "fixed", h.style.inset = "0", h.style.width = "100%", h.style.height = "100%", h.style.pointerEvents = "none", h.style.zIndex = "2147483000", h.style.contain = "layout style size";
65
- const Z = h.attachShadow({ mode: "open" }), g = t.createElement("div");
66
- g.style.boxSizing = "border-box", g.style.position = "fixed", g.style.inset = "0", g.style.width = "100%", g.style.height = "100%", g.style.pointerEvents = "none", Z.append(g);
67
- const R = (o) => {
68
- const l = new URL("/embed/danmaku", i);
69
- return l.searchParams.set("mode", o), l.searchParams.set("workKey", n.workKey), l.searchParams.set("theme", a.theme), l.searchParams.set("locale", p), l.searchParams.set("sdk", j), l.searchParams.set("anchorKey", m.anchorKey), l;
70
- }, _ = (o, l, k) => {
71
- const s = t.createElement("iframe");
72
- return s.title = l, s.src = k, s.loading = "eager", s.referrerPolicy = "no-referrer", s.setAttribute("allowtransparency", "true"), s.setAttribute(
64
+ const j = h.attachShadow({ mode: "open" }), p = r.createElement("div");
65
+ p.style.boxSizing = "border-box", p.style.position = "fixed", p.style.inset = "0", p.style.width = "100%", p.style.height = "100%", p.style.pointerEvents = "none", j.append(p);
66
+ const _ = (n) => {
67
+ const i = new URL("/embed/danmaku", l);
68
+ return i.searchParams.set("mode", n), i.searchParams.set("workKey", a.workKey), i.searchParams.set("theme", t.theme), i.searchParams.set("locale", v), i.searchParams.set("sdk", ae), i.searchParams.set("anchorKey", m.anchorKey), i;
69
+ }, D = (n, i, k) => {
70
+ const s = r.createElement("iframe");
71
+ return s.title = i, s.src = k, s.loading = "eager", s.referrerPolicy = "no-referrer", s.setAttribute("allowtransparency", "true"), s.setAttribute(
73
72
  "sandbox",
74
73
  "allow-forms allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"
75
- ), s.dataset.mode = o, s.style.boxSizing = "border-box", s.style.colorScheme = "normal", s.style.position = "fixed", s.style.margin = "0", s.style.border = "0", s.style.background = "transparent", s.style.width = "100%", s.style.zIndex = "2147483000", s;
76
- }, f = _("stage", "ViceMe Danmaku", R("stage").toString());
77
- f.setAttribute("aria-hidden", "true"), f.style.inset = "0", f.style.height = "100%", f.style.pointerEvents = "none";
78
- const d = _(
74
+ ), s.dataset.mode = n, s.style.boxSizing = "border-box", s.style.colorScheme = "normal", s.style.position = "fixed", s.style.margin = "0", s.style.border = "0", s.style.background = "transparent", s.style.width = "100%", s.style.zIndex = "2147483000", s;
75
+ }, g = D("stage", "ViceMe Danmaku", _("stage").toString());
76
+ g.setAttribute("aria-hidden", "true"), g.style.inset = "0", g.style.height = "100%", g.style.pointerEvents = "none";
77
+ const d = D(
79
78
  "controls",
80
79
  "ViceMe Danmaku controls",
81
- R("controls").toString()
80
+ _("controls").toString()
82
81
  );
83
- d.style.left = "50%", d.style.bottom = "env(safe-area-inset-bottom, 0px)", d.style.maxWidth = `${L}px`, d.style.transform = "translateX(-50%)";
84
- let W = L, O = oe;
85
- const D = () => {
86
- const o = Math.max(
87
- C,
88
- Math.floor(e.innerWidth || L)
82
+ d.style.left = "50%", d.style.bottom = "env(safe-area-inset-bottom, 0px)", d.style.maxWidth = `${A}px`, d.style.transform = "translateX(-50%)";
83
+ let K = A, U = ie;
84
+ const N = () => {
85
+ const n = Math.max(
86
+ W,
87
+ Math.floor(e.innerWidth || A)
89
88
  );
90
- d.style.width = `${Math.min(W, o)}px`, d.style.height = `${O}px`;
89
+ d.style.width = `${Math.min(K, n)}px`, d.style.height = `${U}px`;
91
90
  };
92
- D(), d.style.pointerEvents = "none";
93
- const r = _("modal", "ViceMe Danmaku dialog", "about:blank");
94
- r.dataset.src = R("modal").toString(), r.style.inset = "0", r.style.height = "100%", r.style.display = "none", r.style.pointerEvents = "none", g.append(f, d, r);
95
- const T = (o) => {
96
- I.has(o) && o.contentWindow?.postMessage(
91
+ N(), d.style.pointerEvents = "none";
92
+ const o = D("modal", "ViceMe Danmaku dialog", "about:blank");
93
+ o.dataset.src = _("modal").toString(), o.style.inset = "0", o.style.height = "100%", o.style.display = "none", o.style.pointerEvents = "none", p.append(g, d, o);
94
+ const M = (n) => {
95
+ x.has(n) && n.contentWindow?.postMessage(
97
96
  {
98
97
  source: "viceme-danmaku",
99
98
  action: "anchor-change",
100
99
  anchorKey: m.anchorKey
101
100
  },
102
- i
101
+ l
103
102
  );
104
- }, K = () => {
105
- T(f), T(d), r.getAttribute("src") !== "about:blank" && T(r);
106
- }, U = () => {
107
- if (w) return m;
108
- const o = G(e, t);
109
- return o.anchorKey !== m.anchorKey && (m = o, K()), m;
110
- }, v = () => {
111
- y !== void 0 && e.clearTimeout(y), y = e.setTimeout(U, se);
112
103
  }, z = () => {
113
- D(), v();
114
- }, E = (o) => {
115
- const l = o.currentTarget;
116
- l.getAttribute("src") !== "about:blank" && (I.add(l), T(l));
104
+ M(g), M(d), o.getAttribute("src") !== "about:blank" && M(o);
105
+ }, F = () => {
106
+ if (f) return m;
107
+ const n = Z(e, r);
108
+ return n.anchorKey !== m.anchorKey && (m = n, z()), m;
109
+ }, b = () => {
110
+ y !== void 0 && e.clearTimeout(y), y = e.setTimeout(F, ce);
111
+ }, B = () => {
112
+ N(), b();
113
+ }, w = (n) => {
114
+ const i = n.currentTarget;
115
+ i.getAttribute("src") !== "about:blank" && (x.add(i), M(i));
117
116
  };
118
- f.addEventListener("load", E), d.addEventListener("load", E), r.addEventListener("load", E);
119
- const F = (o = !1) => {
120
- u !== void 0 && (e.clearTimeout(u), u = void 0), r.style.display = "none", r.style.pointerEvents = "none", o && (S = "", M = !1, I.delete(r), r.src = "about:blank");
117
+ g.addEventListener("load", w), d.addEventListener("load", w), o.addEventListener("load", w);
118
+ const V = (n = !1) => {
119
+ u !== void 0 && (e.clearTimeout(u), u = void 0), o.style.display = "none", o.style.pointerEvents = "none", n && (T = "", L = !1, x.delete(o), o.src = "about:blank");
121
120
  };
122
- let V;
123
- const J = new Promise((o, l) => {
124
- V = o, b = e.setTimeout(() => {
125
- l(
126
- new H({
121
+ let $, q;
122
+ const ee = new Promise((n, i) => {
123
+ $ = n, q = i, E = e.setTimeout(() => {
124
+ i(
125
+ new P({
127
126
  code: "INTERNAL_ERROR",
128
127
  message: "Hosted danmaku frames did not become ready in time.",
129
128
  retryable: !0,
130
129
  capability: "danmaku"
131
130
  })
132
131
  );
133
- }, Y);
134
- }), B = (o) => {
135
- if (o.origin !== i) return;
136
- const l = o.source === f.contentWindow, k = o.source === d.contentWindow, s = o.source === r.contentWindow;
137
- if (!l && !k && !s) return;
138
- const c = o.data;
132
+ }, J);
133
+ }), G = (n) => {
134
+ if (n.origin !== l) return;
135
+ const i = n.source === g.contentWindow, k = n.source === d.contentWindow, s = n.source === o.contentWindow;
136
+ if (!i && !k && !s) return;
137
+ const c = n.data;
139
138
  if (!c || c.source !== "viceme-danmaku") return;
140
- const N = s ? "modal" : l ? "stage" : "controls";
139
+ const C = s ? "modal" : i ? "stage" : "controls";
141
140
  if (c.action === "frame-ready") {
142
- if (c.mode !== N) return;
143
- if (N === "modal") {
144
- if (c.frameToken !== S) return;
145
- M = !0, u !== void 0 && (e.clearTimeout(u), u = void 0), r.style.display === "block" && (r.style.pointerEvents = "auto");
141
+ if (c.mode !== C) return;
142
+ if (C === "modal") {
143
+ if (c.frameToken !== T) return;
144
+ L = !0, u !== void 0 && (e.clearTimeout(u), u = void 0), o.style.display === "block" && (o.style.pointerEvents = "auto");
146
145
  return;
147
146
  }
148
- x.add(N), x.has("stage") && x.has("controls") && !A && (A = !0, b !== void 0 && (e.clearTimeout(b), b = void 0), d.style.pointerEvents = "auto", V?.());
147
+ R.add(C), R.has("stage") && R.has("controls") && !I && (I = !0, E !== void 0 && (e.clearTimeout(E), E = void 0), d.style.pointerEvents = "auto", $?.());
149
148
  return;
150
149
  }
151
150
  if (c.action === "resize-controls" && k) {
152
- if (typeof c.width != "number" || !Number.isInteger(c.width) || c.width < C || c.width > L || typeof c.height != "number" || !Number.isInteger(c.height) || c.height < C || c.height > re)
151
+ if (typeof c.width != "number" || !Number.isInteger(c.width) || c.width < W || c.width > A || typeof c.height != "number" || !Number.isInteger(c.height) || c.height < W || c.height > le)
153
152
  return;
154
- W = c.width, O = c.height, D();
153
+ K = c.width, U = c.height, N();
155
154
  }
156
- if (c.action === "request-anchor" && T(s ? r : l ? f : d), c.action === "open-modal" && k) {
157
- if (!A) return;
158
- if (r.getAttribute("src") === "about:blank") {
159
- P += 1, S = String(P);
160
- const q = new URL(r.dataset.src ?? "about:blank");
161
- q.searchParams.set("frameToken", S), r.src = q.toString();
155
+ if (c.action === "request-anchor" && M(s ? o : i ? g : d), c.action === "open-modal" && k) {
156
+ if (!I) return;
157
+ if (o.getAttribute("src") === "about:blank") {
158
+ O += 1, T = String(O);
159
+ const X = new URL(o.dataset.src ?? "about:blank");
160
+ X.searchParams.set("frameToken", T), o.src = X.toString();
162
161
  }
163
- r.style.display = "block", r.style.pointerEvents = M ? "auto" : "none", M || (u !== void 0 && e.clearTimeout(u), u = e.setTimeout(() => F(!0), Y));
162
+ o.style.display = "block", o.style.pointerEvents = L ? "auto" : "none", L || (u !== void 0 && e.clearTimeout(u), u = e.setTimeout(() => V(!0), J));
164
163
  }
165
- c.action === "close-modal" && (s || k) && F(!M);
166
- }, Q = e.setInterval(U, ie), $ = () => {
167
- w || (w = !0, y !== void 0 && e.clearTimeout(y), b !== void 0 && e.clearTimeout(b), u !== void 0 && e.clearTimeout(u), e.clearInterval(Q), e.removeEventListener("message", B), e.removeEventListener("scroll", v), e.removeEventListener("resize", z), e.removeEventListener("popstate", v), e.removeEventListener("hashchange", v), f.removeEventListener("load", E), d.removeEventListener("load", E), r.removeEventListener("load", E), h.remove());
164
+ c.action === "close-modal" && (s || k) && V(!L);
165
+ }, te = e.setInterval(F, de), Y = () => {
166
+ q?.(S()), H();
167
+ }, H = () => {
168
+ f || (f = !0, y !== void 0 && e.clearTimeout(y), E !== void 0 && e.clearTimeout(E), u !== void 0 && e.clearTimeout(u), e.clearInterval(te), e.removeEventListener("message", G), e.removeEventListener("scroll", b), e.removeEventListener("resize", B), e.removeEventListener("popstate", b), e.removeEventListener("hashchange", b), g.removeEventListener("load", w), d.removeEventListener("load", w), o.removeEventListener("load", w), t.signal?.removeEventListener("abort", Y), h.remove());
168
169
  };
169
- e.addEventListener("message", B), e.addEventListener("scroll", v, { passive: !0 }), e.addEventListener("resize", z), e.addEventListener("popstate", v), e.addEventListener("hashchange", v);
170
170
  try {
171
- a.target.appendChild(h), K(), await J;
172
- } catch (o) {
173
- throw $(), o;
171
+ if (e.addEventListener("message", G), e.addEventListener("scroll", b, { passive: !0 }), e.addEventListener("resize", B), e.addEventListener("popstate", b), e.addEventListener("hashchange", b), t.signal?.addEventListener("abort", Y, { once: !0 }), t.signal?.aborted) throw S();
172
+ t.target.appendChild(h), z(), await ee;
173
+ } catch (n) {
174
+ throw H(), n;
174
175
  }
175
176
  return {
176
177
  capability: "danmaku",
177
- destroy: $
178
+ destroy: H
178
179
  };
179
180
  }
180
- const X = /* @__PURE__ */ new WeakMap();
181
- function de(n, a) {
182
- let t = X.get(n);
183
- t || (t = /* @__PURE__ */ new WeakMap(), X.set(n, t));
184
- const e = t.get(a.target);
181
+ const Q = /* @__PURE__ */ new WeakMap();
182
+ function fe(a, t) {
183
+ let r = Q.get(a);
184
+ r || (r = /* @__PURE__ */ new WeakMap(), Q.set(a, r));
185
+ const e = r.get(t.target);
185
186
  if (e) return e;
186
- const i = le(n, a).then((m) => {
187
- let p = !1;
188
- return {
187
+ const l = me(a, t).then((m) => {
188
+ let v = !1;
189
+ const f = {
189
190
  capability: "danmaku",
190
191
  destroy() {
191
- p || (p = !0, t.get(a.target) === i && t.delete(a.target), m.destroy());
192
+ v || (v = !0, t.signal?.removeEventListener("abort", f.destroy), r.get(t.target) === l && r.delete(t.target), m.destroy());
192
193
  }
193
194
  };
195
+ return t.signal?.addEventListener("abort", f.destroy, { once: !0 }), t.signal?.aborted && f.destroy(), f;
194
196
  }).catch((m) => {
195
- throw t.get(a.target) === i && t.delete(a.target), m;
197
+ throw r.get(t.target) === l && r.delete(t.target), m;
196
198
  });
197
- return t.set(a.target, i), i;
199
+ return r.set(t.target, l), l;
198
200
  }
199
201
  export {
200
- de as mountDanmaku
202
+ fe as mountDanmaku
201
203
  };
202
204
  //# sourceMappingURL=danmaku.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"danmaku.js","sources":["../src/core/build-endpoints.ts","../src/danmaku/anchor.ts","../src/danmaku/mount.ts","../src/danmaku/index.ts"],"sourcesContent":["declare const __VICEME_BUILD_CN_WIDGET_ORIGIN__: string | undefined;\ndeclare const __VICEME_BUILD_GLOBAL_WIDGET_ORIGIN__: string | undefined;\n\n/** Hosted Shop origins baked into immutable release artifacts. */\nexport const BUILD_WIDGET_ORIGINS = {\n cn:\n typeof __VICEME_BUILD_CN_WIDGET_ORIGIN__ === 'string'\n ? __VICEME_BUILD_CN_WIDGET_ORIGIN__\n : 'https://viceme.cn',\n global:\n typeof __VICEME_BUILD_GLOBAL_WIDGET_ORIGIN__ === 'string'\n ? __VICEME_BUILD_GLOBAL_WIDGET_ORIGIN__\n : 'https://viceme.ai',\n} as const;\n","export interface DanmakuPageAnchor {\n /** Stable page-and-position key sent to the hosted danmaku runtime. */\n anchorKey: string;\n /** Human-readable 10% scroll bucket, useful for diagnostics. */\n scrollBucket: string;\n}\n\n/**\n * Build a stable page-position anchor without exposing the page URL.\n *\n * Canonical URLs and SPA hash routes participate in the local hash. Only the\n * resulting opaque key leaves the host page.\n */\nexport function readDanmakuPageAnchor(\n windowObject: Window = window,\n documentObject: Document = document,\n): DanmakuPageAnchor {\n const pageUrl = canonicalPageUrl(windowObject, documentObject);\n const bucket = scrollBucket(windowObject, documentObject);\n return {\n anchorKey: `page:${hashString(pageUrl)}:scroll:${bucket}`,\n scrollBucket: bucket,\n };\n}\n\nfunction canonicalPageUrl(windowObject: Window, documentObject: Document): string {\n const canonical = documentObject.querySelector<HTMLLinkElement>('link[rel=\"canonical\"][href]');\n const rawUrl = canonical?.href || windowObject.location.href;\n try {\n const url = new URL(rawUrl, windowObject.location.href);\n url.username = '';\n url.password = '';\n if (canonical && !url.hash && windowObject.location.hash) {\n url.hash = windowObject.location.hash;\n }\n return url.toString();\n } catch {\n return windowObject.location.href;\n }\n}\n\nfunction scrollBucket(windowObject: Window, documentObject: Document): string {\n const root = documentObject.documentElement;\n const body = documentObject.body;\n const scrollTop =\n windowObject.scrollY || windowObject.pageYOffset || root.scrollTop || body?.scrollTop || 0;\n const scrollHeight = Math.max(\n root.scrollHeight,\n root.offsetHeight,\n root.clientHeight,\n body?.scrollHeight ?? 0,\n body?.offsetHeight ?? 0,\n );\n const maxScroll = Math.max(0, scrollHeight - windowObject.innerHeight);\n if (maxScroll <= 1) return '0-100';\n\n const percent = Math.max(0, Math.min(99, (scrollTop / maxScroll) * 100));\n const start = Math.min(90, Math.floor(percent / 10) * 10);\n return `${start}-${start + 10}`;\n}\n\n/** Deterministic 64-bit-style hash encoded as at most 16 base36 characters. */\nfunction hashString(value: string): string {\n let high = 0xdeadbeef ^ value.length;\n let low = 0x41c6ce57 ^ value.length;\n for (let index = 0; index < value.length; index += 1) {\n const character = value.charCodeAt(index);\n high = Math.imul(high ^ character, 2654435761);\n low = Math.imul(low ^ character, 1597334677);\n }\n high = Math.imul(high ^ (high >>> 16), 2246822507);\n high ^= Math.imul(low ^ (low >>> 13), 3266489909);\n low = Math.imul(low ^ (low >>> 16), 2246822507);\n low ^= Math.imul(high ^ (high >>> 13), 3266489909);\n return (\n (low >>> 0).toString(36).padStart(7, '0') + (high >>> 0).toString(36).padStart(7, '0')\n ).slice(0, 16);\n}\n","import type { ViceMeClient } from '../core/client.ts';\nimport { BUILD_WIDGET_ORIGINS } from '../core/build-endpoints.ts';\nimport { ViceMeError } from '../core/errors.ts';\nimport type { CapabilityMountHandle, CapabilityMountOptions } from '../loader/mount-handle.ts';\nimport { SDK_VERSION } from '../version.ts';\nimport { readDanmakuPageAnchor, type DanmakuPageAnchor } from './anchor.ts';\n\ntype DanmakuFrameMode = 'stage' | 'controls' | 'modal';\n\ninterface DanmakuBridgeMessage {\n source?: unknown;\n action?: unknown;\n frameToken?: unknown;\n mode?: unknown;\n width?: unknown;\n height?: unknown;\n}\n\nconst CONTROLS_MIN_SIZE = 32;\nconst CONTROLS_BAR_HEIGHT = 56;\nconst CONTROLS_MAX_HEIGHT = 360;\nconst CONTROLS_MAX_WIDTH = 480;\nconst ANCHOR_DEBOUNCE_MS = 120;\nconst LOCATION_POLL_MS = 1_000;\nexport const FRAME_READY_TIMEOUT_MS = 8_000;\n\nexport async function mount(\n client: ViceMeClient,\n options: CapabilityMountOptions,\n): Promise<CapabilityMountHandle> {\n await client.ready();\n if (!client.hasCapability('danmaku')) {\n throw new ViceMeError({\n code: 'CAPABILITY_DISABLED',\n message: 'Danmaku is not available in this SDK build.',\n retryable: false,\n capability: 'danmaku',\n });\n }\n\n const documentObject = options.target.ownerDocument;\n const windowObject = documentObject.defaultView;\n if (!windowObject) {\n throw new ViceMeError({\n code: 'CONFIG_INVALID',\n message: 'Danmaku requires a browser document.',\n retryable: false,\n capability: 'danmaku',\n });\n }\n\n const widgetOrigin = BUILD_WIDGET_ORIGINS[client.region];\n let currentAnchor = readDanmakuPageAnchor(windowObject, documentObject);\n const locale =\n documentObject.documentElement.lang.trim() || windowObject.navigator.language || 'en';\n let destroyed = false;\n let anchorTimer: number | undefined;\n let readyTimer: number | undefined;\n let modalReadyTimer: number | undefined;\n let initialFramesReady = false;\n let modalAttempt = 0;\n let modalFrameToken = '';\n let modalReady = false;\n const loadedFrames = new WeakSet<HTMLIFrameElement>();\n const readyModes = new Set<DanmakuFrameMode>();\n\n const portal = documentObject.createElement('div');\n portal.dataset.vicemeDanmaku = 'mounted';\n portal.style.all = 'initial';\n portal.style.position = 'fixed';\n portal.style.inset = '0';\n portal.style.width = '100%';\n portal.style.height = '100%';\n portal.style.pointerEvents = 'none';\n portal.style.zIndex = '2147483000';\n portal.style.contain = 'layout style size';\n\n const shadow = portal.attachShadow({ mode: 'open' });\n const root = documentObject.createElement('div');\n root.style.boxSizing = 'border-box';\n root.style.position = 'fixed';\n root.style.inset = '0';\n root.style.width = '100%';\n root.style.height = '100%';\n root.style.pointerEvents = 'none';\n shadow.append(root);\n\n const frameUrl = (mode: DanmakuFrameMode): URL => {\n const url = new URL('/embed/danmaku', widgetOrigin);\n url.searchParams.set('mode', mode);\n url.searchParams.set('workKey', client.workKey);\n url.searchParams.set('theme', options.theme);\n url.searchParams.set('locale', locale);\n url.searchParams.set('sdk', SDK_VERSION);\n url.searchParams.set('anchorKey', currentAnchor.anchorKey);\n return url;\n };\n\n const createFrame = (\n mode: DanmakuFrameMode,\n title: string,\n source: string,\n ): HTMLIFrameElement => {\n const frame = documentObject.createElement('iframe');\n frame.title = title;\n frame.src = source;\n frame.loading = 'eager';\n frame.referrerPolicy = 'no-referrer';\n frame.setAttribute('allowtransparency', 'true');\n frame.setAttribute(\n 'sandbox',\n 'allow-forms allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts',\n );\n frame.dataset.mode = mode;\n frame.style.boxSizing = 'border-box';\n frame.style.colorScheme = 'normal';\n frame.style.position = 'fixed';\n frame.style.margin = '0';\n frame.style.border = '0';\n frame.style.background = 'transparent';\n frame.style.width = '100%';\n frame.style.zIndex = '2147483000';\n return frame;\n };\n\n const stage = createFrame('stage', 'ViceMe Danmaku', frameUrl('stage').toString());\n stage.setAttribute('aria-hidden', 'true');\n stage.style.inset = '0';\n stage.style.height = '100%';\n stage.style.pointerEvents = 'none';\n\n const controls = createFrame(\n 'controls',\n 'ViceMe Danmaku controls',\n frameUrl('controls').toString(),\n );\n controls.style.left = '50%';\n controls.style.bottom = 'env(safe-area-inset-bottom, 0px)';\n controls.style.maxWidth = `${CONTROLS_MAX_WIDTH}px`;\n controls.style.transform = 'translateX(-50%)';\n let controlsRequestedWidth = CONTROLS_MAX_WIDTH;\n let controlsRequestedHeight = CONTROLS_BAR_HEIGHT;\n const applyControlsSize = (): void => {\n const viewportWidth = Math.max(\n CONTROLS_MIN_SIZE,\n Math.floor(windowObject.innerWidth || CONTROLS_MAX_WIDTH),\n );\n controls.style.width = `${Math.min(controlsRequestedWidth, viewportWidth)}px`;\n controls.style.height = `${controlsRequestedHeight}px`;\n };\n applyControlsSize();\n controls.style.pointerEvents = 'none';\n\n const modal = createFrame('modal', 'ViceMe Danmaku dialog', 'about:blank');\n modal.dataset.src = frameUrl('modal').toString();\n modal.style.inset = '0';\n modal.style.height = '100%';\n modal.style.display = 'none';\n modal.style.pointerEvents = 'none';\n\n root.append(stage, controls, modal);\n\n const postAnchor = (frame: HTMLIFrameElement): void => {\n if (!loadedFrames.has(frame)) return;\n frame.contentWindow?.postMessage(\n {\n source: 'viceme-danmaku',\n action: 'anchor-change',\n anchorKey: currentAnchor.anchorKey,\n },\n widgetOrigin,\n );\n };\n const postAnchorToMountedFrames = (): void => {\n postAnchor(stage);\n postAnchor(controls);\n if (modal.getAttribute('src') !== 'about:blank') postAnchor(modal);\n };\n\n const refreshAnchor = (): DanmakuPageAnchor => {\n if (destroyed) return currentAnchor;\n const next = readDanmakuPageAnchor(windowObject, documentObject);\n if (next.anchorKey !== currentAnchor.anchorKey) {\n currentAnchor = next;\n postAnchorToMountedFrames();\n }\n return currentAnchor;\n };\n const scheduleAnchorRefresh = (): void => {\n if (anchorTimer !== undefined) windowObject.clearTimeout(anchorTimer);\n anchorTimer = windowObject.setTimeout(refreshAnchor, ANCHOR_DEBOUNCE_MS);\n };\n const handleWindowResize = (): void => {\n applyControlsSize();\n scheduleAnchorRefresh();\n };\n\n const frameLoaded = (event: Event): void => {\n const frame = event.currentTarget as HTMLIFrameElement;\n if (frame.getAttribute('src') === 'about:blank') return;\n loadedFrames.add(frame);\n postAnchor(frame);\n };\n stage.addEventListener('load', frameLoaded);\n controls.addEventListener('load', frameLoaded);\n modal.addEventListener('load', frameLoaded);\n\n const hideModal = (resetFrame = false): void => {\n if (modalReadyTimer !== undefined) {\n windowObject.clearTimeout(modalReadyTimer);\n modalReadyTimer = undefined;\n }\n modal.style.display = 'none';\n modal.style.pointerEvents = 'none';\n if (resetFrame) {\n modalFrameToken = '';\n modalReady = false;\n loadedFrames.delete(modal);\n modal.src = 'about:blank';\n }\n };\n\n let resolveInitialFrames: (() => void) | undefined;\n const initialFrameReadiness = new Promise<void>((resolve, reject) => {\n resolveInitialFrames = resolve;\n readyTimer = windowObject.setTimeout(() => {\n reject(\n new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: 'Hosted danmaku frames did not become ready in time.',\n retryable: true,\n capability: 'danmaku',\n }),\n );\n }, FRAME_READY_TIMEOUT_MS);\n });\n\n const onMessage = (event: MessageEvent): void => {\n if (event.origin !== widgetOrigin) return;\n const fromStage = event.source === stage.contentWindow;\n const fromControls = event.source === controls.contentWindow;\n const fromModal = event.source === modal.contentWindow;\n if (!fromStage && !fromControls && !fromModal) return;\n\n const message = event.data as DanmakuBridgeMessage | null;\n if (!message || message.source !== 'viceme-danmaku') return;\n\n const sourceMode: DanmakuFrameMode = fromModal ? 'modal' : fromStage ? 'stage' : 'controls';\n if (message.action === 'frame-ready') {\n if (message.mode !== sourceMode) return;\n if (sourceMode === 'modal') {\n if (message.frameToken !== modalFrameToken) return;\n modalReady = true;\n if (modalReadyTimer !== undefined) {\n windowObject.clearTimeout(modalReadyTimer);\n modalReadyTimer = undefined;\n }\n if (modal.style.display === 'block') modal.style.pointerEvents = 'auto';\n return;\n }\n readyModes.add(sourceMode);\n if (readyModes.has('stage') && readyModes.has('controls') && !initialFramesReady) {\n initialFramesReady = true;\n if (readyTimer !== undefined) {\n windowObject.clearTimeout(readyTimer);\n readyTimer = undefined;\n }\n controls.style.pointerEvents = 'auto';\n resolveInitialFrames?.();\n }\n return;\n }\n if (message.action === 'resize-controls' && fromControls) {\n if (\n typeof message.width !== 'number' ||\n !Number.isInteger(message.width) ||\n message.width < CONTROLS_MIN_SIZE ||\n message.width > CONTROLS_MAX_WIDTH ||\n typeof message.height !== 'number' ||\n !Number.isInteger(message.height) ||\n message.height < CONTROLS_MIN_SIZE ||\n message.height > CONTROLS_MAX_HEIGHT\n ) {\n return;\n }\n controlsRequestedWidth = message.width;\n controlsRequestedHeight = message.height;\n applyControlsSize();\n }\n if (message.action === 'request-anchor') {\n postAnchor(fromModal ? modal : fromStage ? stage : controls);\n }\n if (message.action === 'open-modal' && fromControls) {\n if (!initialFramesReady) return;\n if (modal.getAttribute('src') === 'about:blank') {\n modalAttempt += 1;\n modalFrameToken = String(modalAttempt);\n const modalUrl = new URL(modal.dataset.src ?? 'about:blank');\n modalUrl.searchParams.set('frameToken', modalFrameToken);\n modal.src = modalUrl.toString();\n }\n modal.style.display = 'block';\n modal.style.pointerEvents = modalReady ? 'auto' : 'none';\n if (!modalReady) {\n if (modalReadyTimer !== undefined) windowObject.clearTimeout(modalReadyTimer);\n modalReadyTimer = windowObject.setTimeout(() => hideModal(true), FRAME_READY_TIMEOUT_MS);\n }\n }\n if (message.action === 'close-modal' && (fromModal || fromControls)) {\n hideModal(!modalReady);\n }\n };\n\n const locationPoll = windowObject.setInterval(refreshAnchor, LOCATION_POLL_MS);\n const cleanup = (): void => {\n if (destroyed) return;\n destroyed = true;\n if (anchorTimer !== undefined) windowObject.clearTimeout(anchorTimer);\n if (readyTimer !== undefined) windowObject.clearTimeout(readyTimer);\n if (modalReadyTimer !== undefined) windowObject.clearTimeout(modalReadyTimer);\n windowObject.clearInterval(locationPoll);\n windowObject.removeEventListener('message', onMessage);\n windowObject.removeEventListener('scroll', scheduleAnchorRefresh);\n windowObject.removeEventListener('resize', handleWindowResize);\n windowObject.removeEventListener('popstate', scheduleAnchorRefresh);\n windowObject.removeEventListener('hashchange', scheduleAnchorRefresh);\n stage.removeEventListener('load', frameLoaded);\n controls.removeEventListener('load', frameLoaded);\n modal.removeEventListener('load', frameLoaded);\n portal.remove();\n };\n\n windowObject.addEventListener('message', onMessage);\n windowObject.addEventListener('scroll', scheduleAnchorRefresh, { passive: true });\n windowObject.addEventListener('resize', handleWindowResize);\n windowObject.addEventListener('popstate', scheduleAnchorRefresh);\n windowObject.addEventListener('hashchange', scheduleAnchorRefresh);\n try {\n options.target.appendChild(portal);\n postAnchorToMountedFrames();\n await initialFrameReadiness;\n } catch (error) {\n cleanup();\n throw error;\n }\n\n return {\n capability: 'danmaku',\n destroy: cleanup,\n };\n}\n","import type { ViceMeClient } from '../core/client.ts';\nimport { mount } from './mount.ts';\n\nexport interface DanmakuMountOptions {\n target: Element;\n theme: 'light' | 'dark' | 'auto';\n}\n\nexport interface DanmakuMountHandle {\n readonly capability: 'danmaku';\n destroy(): void;\n}\n\nconst mounts = new WeakMap<ViceMeClient, WeakMap<Element, Promise<DanmakuMountHandle>>>();\n\n/** Explicit ESM/npm entry point; the CDN loader calls the same mount function. */\nexport function mountDanmaku(\n client: ViceMeClient,\n options: DanmakuMountOptions,\n): Promise<DanmakuMountHandle> {\n let byTarget = mounts.get(client);\n if (!byTarget) {\n byTarget = new WeakMap();\n mounts.set(client, byTarget);\n }\n const existing = byTarget.get(options.target);\n if (existing) return existing;\n\n const pending: Promise<DanmakuMountHandle> = mount(client, options)\n .then((raw) => {\n let destroyed = false;\n return {\n capability: 'danmaku' as const,\n destroy(): void {\n if (destroyed) return;\n destroyed = true;\n if (byTarget.get(options.target) === pending) byTarget.delete(options.target);\n raw.destroy();\n },\n };\n })\n .catch((error: unknown) => {\n if (byTarget.get(options.target) === pending) byTarget.delete(options.target);\n throw error;\n });\n byTarget.set(options.target, pending);\n return pending;\n}\n"],"names":["BUILD_WIDGET_ORIGINS","readDanmakuPageAnchor","windowObject","documentObject","pageUrl","canonicalPageUrl","bucket","scrollBucket","hashString","canonical","rawUrl","url","root","body","scrollTop","scrollHeight","maxScroll","percent","start","value","high","low","index","character","CONTROLS_MIN_SIZE","CONTROLS_BAR_HEIGHT","CONTROLS_MAX_HEIGHT","CONTROLS_MAX_WIDTH","ANCHOR_DEBOUNCE_MS","LOCATION_POLL_MS","FRAME_READY_TIMEOUT_MS","mount","client","options","ViceMeError","widgetOrigin","currentAnchor","locale","destroyed","anchorTimer","readyTimer","modalReadyTimer","initialFramesReady","modalAttempt","modalFrameToken","modalReady","loadedFrames","readyModes","portal","shadow","frameUrl","mode","SDK_VERSION","createFrame","title","source","frame","stage","controls","controlsRequestedWidth","controlsRequestedHeight","applyControlsSize","viewportWidth","modal","postAnchor","postAnchorToMountedFrames","refreshAnchor","next","scheduleAnchorRefresh","handleWindowResize","frameLoaded","event","hideModal","resetFrame","resolveInitialFrames","initialFrameReadiness","resolve","reject","onMessage","fromStage","fromControls","fromModal","message","sourceMode","modalUrl","locationPoll","cleanup","error","mounts","mountDanmaku","byTarget","existing","pending","raw"],"mappings":"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"}
1
+ {"version":3,"file":"danmaku.js","sources":["../src/danmaku/anchor.ts","../src/danmaku/mount.ts","../src/danmaku/index.ts"],"sourcesContent":["export interface DanmakuPageAnchor {\n /** Stable page-and-position key sent to the hosted danmaku runtime. */\n anchorKey: string;\n /** Human-readable 10% scroll bucket, useful for diagnostics. */\n scrollBucket: string;\n}\n\n/**\n * Build a stable page-position anchor without exposing the page URL.\n *\n * Canonical URLs and SPA hash routes participate in the local hash. Only the\n * resulting opaque key leaves the host page.\n */\nexport function readDanmakuPageAnchor(\n windowObject: Window = window,\n documentObject: Document = document,\n): DanmakuPageAnchor {\n const pageUrl = canonicalPageUrl(windowObject, documentObject);\n const bucket = scrollBucket(windowObject, documentObject);\n return {\n anchorKey: `page:${hashString(pageUrl)}:scroll:${bucket}`,\n scrollBucket: bucket,\n };\n}\n\nfunction canonicalPageUrl(windowObject: Window, documentObject: Document): string {\n const canonical = documentObject.querySelector<HTMLLinkElement>('link[rel=\"canonical\"][href]');\n const rawUrl = canonical?.href || windowObject.location.href;\n try {\n const url = new URL(rawUrl, windowObject.location.href);\n url.username = '';\n url.password = '';\n if (canonical && !url.hash && windowObject.location.hash) {\n url.hash = windowObject.location.hash;\n }\n return url.toString();\n } catch {\n return windowObject.location.href;\n }\n}\n\nfunction scrollBucket(windowObject: Window, documentObject: Document): string {\n const root = documentObject.documentElement;\n const body = documentObject.body;\n const scrollTop =\n windowObject.scrollY || windowObject.pageYOffset || root.scrollTop || body?.scrollTop || 0;\n const scrollHeight = Math.max(\n root.scrollHeight,\n root.offsetHeight,\n root.clientHeight,\n body?.scrollHeight ?? 0,\n body?.offsetHeight ?? 0,\n );\n const maxScroll = Math.max(0, scrollHeight - windowObject.innerHeight);\n if (maxScroll <= 1) return '0-100';\n\n const percent = Math.max(0, Math.min(99, (scrollTop / maxScroll) * 100));\n const start = Math.min(90, Math.floor(percent / 10) * 10);\n return `${start}-${start + 10}`;\n}\n\n/** Deterministic 64-bit-style hash encoded as at most 16 base36 characters. */\nfunction hashString(value: string): string {\n let high = 0xdeadbeef ^ value.length;\n let low = 0x41c6ce57 ^ value.length;\n for (let index = 0; index < value.length; index += 1) {\n const character = value.charCodeAt(index);\n high = Math.imul(high ^ character, 2654435761);\n low = Math.imul(low ^ character, 1597334677);\n }\n high = Math.imul(high ^ (high >>> 16), 2246822507);\n high ^= Math.imul(low ^ (low >>> 13), 3266489909);\n low = Math.imul(low ^ (low >>> 16), 2246822507);\n low ^= Math.imul(high ^ (high >>> 13), 3266489909);\n return (\n (low >>> 0).toString(36).padStart(7, '0') + (high >>> 0).toString(36).padStart(7, '0')\n ).slice(0, 16);\n}\n","import type { ViceMeClient } from '../core/client.ts';\nimport { BUILD_WIDGET_ORIGINS } from '../core/build-endpoints.ts';\nimport { clientDestroyed, ViceMeError } from '../core/errors.ts';\nimport type { CapabilityMountHandle, CapabilityMountOptions } from '../capability-mount.ts';\nimport { SDK_VERSION } from '../version.ts';\nimport { readDanmakuPageAnchor, type DanmakuPageAnchor } from './anchor.ts';\n\ntype DanmakuFrameMode = 'stage' | 'controls' | 'modal';\n\ninterface DanmakuBridgeMessage {\n source?: unknown;\n action?: unknown;\n frameToken?: unknown;\n mode?: unknown;\n width?: unknown;\n height?: unknown;\n}\n\nconst CONTROLS_MIN_SIZE = 32;\nconst CONTROLS_BAR_HEIGHT = 56;\nconst CONTROLS_MAX_HEIGHT = 360;\nconst CONTROLS_MAX_WIDTH = 480;\nconst ANCHOR_DEBOUNCE_MS = 120;\nconst LOCATION_POLL_MS = 1_000;\nexport const FRAME_READY_TIMEOUT_MS = 8_000;\n\nexport async function mount(\n client: ViceMeClient,\n options: CapabilityMountOptions,\n): Promise<CapabilityMountHandle> {\n if (options.signal?.aborted) throw clientDestroyed();\n await client.ready();\n if (options.signal?.aborted) throw clientDestroyed();\n if (!client.hasCapability('danmaku')) {\n throw new ViceMeError({\n code: 'CAPABILITY_DISABLED',\n message: 'Danmaku is not available in this SDK build.',\n retryable: false,\n capability: 'danmaku',\n });\n }\n\n const documentObject = options.target.ownerDocument;\n const windowObject = documentObject.defaultView;\n if (!windowObject) {\n throw new ViceMeError({\n code: 'CONFIG_INVALID',\n message: 'Danmaku requires a browser document.',\n retryable: false,\n capability: 'danmaku',\n });\n }\n\n const widgetOrigin = BUILD_WIDGET_ORIGINS[client.region];\n let currentAnchor = readDanmakuPageAnchor(windowObject, documentObject);\n const locale =\n documentObject.documentElement.lang.trim() || windowObject.navigator.language || 'en';\n let destroyed = false;\n let anchorTimer: number | undefined;\n let readyTimer: number | undefined;\n let modalReadyTimer: number | undefined;\n let initialFramesReady = false;\n let modalAttempt = 0;\n let modalFrameToken = '';\n let modalReady = false;\n const loadedFrames = new WeakSet<HTMLIFrameElement>();\n const readyModes = new Set<DanmakuFrameMode>();\n\n const portal = documentObject.createElement('div');\n portal.dataset.vicemeDanmaku = 'mounted';\n portal.style.all = 'initial';\n portal.style.position = 'fixed';\n portal.style.inset = '0';\n portal.style.width = '100%';\n portal.style.height = '100%';\n portal.style.pointerEvents = 'none';\n portal.style.zIndex = '2147483000';\n portal.style.contain = 'layout style size';\n\n const shadow = portal.attachShadow({ mode: 'open' });\n const root = documentObject.createElement('div');\n root.style.boxSizing = 'border-box';\n root.style.position = 'fixed';\n root.style.inset = '0';\n root.style.width = '100%';\n root.style.height = '100%';\n root.style.pointerEvents = 'none';\n shadow.append(root);\n\n const frameUrl = (mode: DanmakuFrameMode): URL => {\n const url = new URL('/embed/danmaku', widgetOrigin);\n url.searchParams.set('mode', mode);\n url.searchParams.set('workKey', client.workKey);\n url.searchParams.set('theme', options.theme);\n url.searchParams.set('locale', locale);\n url.searchParams.set('sdk', SDK_VERSION);\n url.searchParams.set('anchorKey', currentAnchor.anchorKey);\n return url;\n };\n\n const createFrame = (\n mode: DanmakuFrameMode,\n title: string,\n source: string,\n ): HTMLIFrameElement => {\n const frame = documentObject.createElement('iframe');\n frame.title = title;\n frame.src = source;\n frame.loading = 'eager';\n frame.referrerPolicy = 'no-referrer';\n frame.setAttribute('allowtransparency', 'true');\n frame.setAttribute(\n 'sandbox',\n 'allow-forms allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts',\n );\n frame.dataset.mode = mode;\n frame.style.boxSizing = 'border-box';\n frame.style.colorScheme = 'normal';\n frame.style.position = 'fixed';\n frame.style.margin = '0';\n frame.style.border = '0';\n frame.style.background = 'transparent';\n frame.style.width = '100%';\n frame.style.zIndex = '2147483000';\n return frame;\n };\n\n const stage = createFrame('stage', 'ViceMe Danmaku', frameUrl('stage').toString());\n stage.setAttribute('aria-hidden', 'true');\n stage.style.inset = '0';\n stage.style.height = '100%';\n stage.style.pointerEvents = 'none';\n\n const controls = createFrame(\n 'controls',\n 'ViceMe Danmaku controls',\n frameUrl('controls').toString(),\n );\n controls.style.left = '50%';\n controls.style.bottom = 'env(safe-area-inset-bottom, 0px)';\n controls.style.maxWidth = `${CONTROLS_MAX_WIDTH}px`;\n controls.style.transform = 'translateX(-50%)';\n let controlsRequestedWidth = CONTROLS_MAX_WIDTH;\n let controlsRequestedHeight = CONTROLS_BAR_HEIGHT;\n const applyControlsSize = (): void => {\n const viewportWidth = Math.max(\n CONTROLS_MIN_SIZE,\n Math.floor(windowObject.innerWidth || CONTROLS_MAX_WIDTH),\n );\n controls.style.width = `${Math.min(controlsRequestedWidth, viewportWidth)}px`;\n controls.style.height = `${controlsRequestedHeight}px`;\n };\n applyControlsSize();\n controls.style.pointerEvents = 'none';\n\n const modal = createFrame('modal', 'ViceMe Danmaku dialog', 'about:blank');\n modal.dataset.src = frameUrl('modal').toString();\n modal.style.inset = '0';\n modal.style.height = '100%';\n modal.style.display = 'none';\n modal.style.pointerEvents = 'none';\n\n root.append(stage, controls, modal);\n\n const postAnchor = (frame: HTMLIFrameElement): void => {\n if (!loadedFrames.has(frame)) return;\n frame.contentWindow?.postMessage(\n {\n source: 'viceme-danmaku',\n action: 'anchor-change',\n anchorKey: currentAnchor.anchorKey,\n },\n widgetOrigin,\n );\n };\n const postAnchorToMountedFrames = (): void => {\n postAnchor(stage);\n postAnchor(controls);\n if (modal.getAttribute('src') !== 'about:blank') postAnchor(modal);\n };\n\n const refreshAnchor = (): DanmakuPageAnchor => {\n if (destroyed) return currentAnchor;\n const next = readDanmakuPageAnchor(windowObject, documentObject);\n if (next.anchorKey !== currentAnchor.anchorKey) {\n currentAnchor = next;\n postAnchorToMountedFrames();\n }\n return currentAnchor;\n };\n const scheduleAnchorRefresh = (): void => {\n if (anchorTimer !== undefined) windowObject.clearTimeout(anchorTimer);\n anchorTimer = windowObject.setTimeout(refreshAnchor, ANCHOR_DEBOUNCE_MS);\n };\n const handleWindowResize = (): void => {\n applyControlsSize();\n scheduleAnchorRefresh();\n };\n\n const frameLoaded = (event: Event): void => {\n const frame = event.currentTarget as HTMLIFrameElement;\n if (frame.getAttribute('src') === 'about:blank') return;\n loadedFrames.add(frame);\n postAnchor(frame);\n };\n stage.addEventListener('load', frameLoaded);\n controls.addEventListener('load', frameLoaded);\n modal.addEventListener('load', frameLoaded);\n\n const hideModal = (resetFrame = false): void => {\n if (modalReadyTimer !== undefined) {\n windowObject.clearTimeout(modalReadyTimer);\n modalReadyTimer = undefined;\n }\n modal.style.display = 'none';\n modal.style.pointerEvents = 'none';\n if (resetFrame) {\n modalFrameToken = '';\n modalReady = false;\n loadedFrames.delete(modal);\n modal.src = 'about:blank';\n }\n };\n\n let resolveInitialFrames: (() => void) | undefined;\n let rejectInitialFrames: ((error: ViceMeError) => void) | undefined;\n const initialFrameReadiness = new Promise<void>((resolve, reject) => {\n resolveInitialFrames = resolve;\n rejectInitialFrames = reject;\n readyTimer = windowObject.setTimeout(() => {\n reject(\n new ViceMeError({\n code: 'INTERNAL_ERROR',\n message: 'Hosted danmaku frames did not become ready in time.',\n retryable: true,\n capability: 'danmaku',\n }),\n );\n }, FRAME_READY_TIMEOUT_MS);\n });\n\n const onMessage = (event: MessageEvent): void => {\n if (event.origin !== widgetOrigin) return;\n const fromStage = event.source === stage.contentWindow;\n const fromControls = event.source === controls.contentWindow;\n const fromModal = event.source === modal.contentWindow;\n if (!fromStage && !fromControls && !fromModal) return;\n\n const message = event.data as DanmakuBridgeMessage | null;\n if (!message || message.source !== 'viceme-danmaku') return;\n\n const sourceMode: DanmakuFrameMode = fromModal ? 'modal' : fromStage ? 'stage' : 'controls';\n if (message.action === 'frame-ready') {\n if (message.mode !== sourceMode) return;\n if (sourceMode === 'modal') {\n if (message.frameToken !== modalFrameToken) return;\n modalReady = true;\n if (modalReadyTimer !== undefined) {\n windowObject.clearTimeout(modalReadyTimer);\n modalReadyTimer = undefined;\n }\n if (modal.style.display === 'block') modal.style.pointerEvents = 'auto';\n return;\n }\n readyModes.add(sourceMode);\n if (readyModes.has('stage') && readyModes.has('controls') && !initialFramesReady) {\n initialFramesReady = true;\n if (readyTimer !== undefined) {\n windowObject.clearTimeout(readyTimer);\n readyTimer = undefined;\n }\n controls.style.pointerEvents = 'auto';\n resolveInitialFrames?.();\n }\n return;\n }\n if (message.action === 'resize-controls' && fromControls) {\n if (\n typeof message.width !== 'number' ||\n !Number.isInteger(message.width) ||\n message.width < CONTROLS_MIN_SIZE ||\n message.width > CONTROLS_MAX_WIDTH ||\n typeof message.height !== 'number' ||\n !Number.isInteger(message.height) ||\n message.height < CONTROLS_MIN_SIZE ||\n message.height > CONTROLS_MAX_HEIGHT\n ) {\n return;\n }\n controlsRequestedWidth = message.width;\n controlsRequestedHeight = message.height;\n applyControlsSize();\n }\n if (message.action === 'request-anchor') {\n postAnchor(fromModal ? modal : fromStage ? stage : controls);\n }\n if (message.action === 'open-modal' && fromControls) {\n if (!initialFramesReady) return;\n if (modal.getAttribute('src') === 'about:blank') {\n modalAttempt += 1;\n modalFrameToken = String(modalAttempt);\n const modalUrl = new URL(modal.dataset.src ?? 'about:blank');\n modalUrl.searchParams.set('frameToken', modalFrameToken);\n modal.src = modalUrl.toString();\n }\n modal.style.display = 'block';\n modal.style.pointerEvents = modalReady ? 'auto' : 'none';\n if (!modalReady) {\n if (modalReadyTimer !== undefined) windowObject.clearTimeout(modalReadyTimer);\n modalReadyTimer = windowObject.setTimeout(() => hideModal(true), FRAME_READY_TIMEOUT_MS);\n }\n }\n if (message.action === 'close-modal' && (fromModal || fromControls)) {\n hideModal(!modalReady);\n }\n };\n\n const locationPoll = windowObject.setInterval(refreshAnchor, LOCATION_POLL_MS);\n const onAbort = (): void => {\n rejectInitialFrames?.(clientDestroyed());\n cleanup();\n };\n const cleanup = (): void => {\n if (destroyed) return;\n destroyed = true;\n if (anchorTimer !== undefined) windowObject.clearTimeout(anchorTimer);\n if (readyTimer !== undefined) windowObject.clearTimeout(readyTimer);\n if (modalReadyTimer !== undefined) windowObject.clearTimeout(modalReadyTimer);\n windowObject.clearInterval(locationPoll);\n windowObject.removeEventListener('message', onMessage);\n windowObject.removeEventListener('scroll', scheduleAnchorRefresh);\n windowObject.removeEventListener('resize', handleWindowResize);\n windowObject.removeEventListener('popstate', scheduleAnchorRefresh);\n windowObject.removeEventListener('hashchange', scheduleAnchorRefresh);\n stage.removeEventListener('load', frameLoaded);\n controls.removeEventListener('load', frameLoaded);\n modal.removeEventListener('load', frameLoaded);\n options.signal?.removeEventListener('abort', onAbort);\n portal.remove();\n };\n\n try {\n windowObject.addEventListener('message', onMessage);\n windowObject.addEventListener('scroll', scheduleAnchorRefresh, { passive: true });\n windowObject.addEventListener('resize', handleWindowResize);\n windowObject.addEventListener('popstate', scheduleAnchorRefresh);\n windowObject.addEventListener('hashchange', scheduleAnchorRefresh);\n options.signal?.addEventListener('abort', onAbort, { once: true });\n if (options.signal?.aborted) throw clientDestroyed();\n options.target.appendChild(portal);\n postAnchorToMountedFrames();\n await initialFrameReadiness;\n } catch (error) {\n cleanup();\n throw error;\n }\n\n return {\n capability: 'danmaku',\n destroy: cleanup,\n };\n}\n","import type { ViceMeClient } from '../core/client.ts';\nimport { mount } from './mount.ts';\n\nexport interface DanmakuMountOptions {\n target: Element;\n theme: 'light' | 'dark' | 'auto';\n signal?: AbortSignal;\n}\n\nexport interface DanmakuMountHandle {\n readonly capability: 'danmaku';\n destroy(): void;\n}\n\nconst mounts = new WeakMap<ViceMeClient, WeakMap<Element, Promise<DanmakuMountHandle>>>();\n\n/** Explicit ESM/npm entry point; the CDN loader calls the same mount function. */\nexport function mountDanmaku(\n client: ViceMeClient,\n options: DanmakuMountOptions,\n): Promise<DanmakuMountHandle> {\n let byTarget = mounts.get(client);\n if (!byTarget) {\n byTarget = new WeakMap();\n mounts.set(client, byTarget);\n }\n const existing = byTarget.get(options.target);\n if (existing) return existing;\n\n const pending: Promise<DanmakuMountHandle> = mount(client, options)\n .then((raw) => {\n let destroyed = false;\n const handle: DanmakuMountHandle = {\n capability: 'danmaku' as const,\n destroy(): void {\n if (destroyed) return;\n destroyed = true;\n options.signal?.removeEventListener('abort', handle.destroy);\n if (byTarget.get(options.target) === pending) byTarget.delete(options.target);\n raw.destroy();\n },\n };\n options.signal?.addEventListener('abort', handle.destroy, { once: true });\n if (options.signal?.aborted) handle.destroy();\n return handle;\n })\n .catch((error: unknown) => {\n if (byTarget.get(options.target) === pending) byTarget.delete(options.target);\n throw error;\n });\n byTarget.set(options.target, pending);\n return pending;\n}\n"],"names":["readDanmakuPageAnchor","windowObject","documentObject","pageUrl","canonicalPageUrl","bucket","scrollBucket","hashString","canonical","rawUrl","url","root","body","scrollTop","scrollHeight","maxScroll","percent","start","value","high","low","index","character","CONTROLS_MIN_SIZE","CONTROLS_BAR_HEIGHT","CONTROLS_MAX_HEIGHT","CONTROLS_MAX_WIDTH","ANCHOR_DEBOUNCE_MS","LOCATION_POLL_MS","FRAME_READY_TIMEOUT_MS","mount","client","options","clientDestroyed","ViceMeError","widgetOrigin","BUILD_WIDGET_ORIGINS","currentAnchor","locale","destroyed","anchorTimer","readyTimer","modalReadyTimer","initialFramesReady","modalAttempt","modalFrameToken","modalReady","loadedFrames","readyModes","portal","shadow","frameUrl","mode","SDK_VERSION","createFrame","title","source","frame","stage","controls","controlsRequestedWidth","controlsRequestedHeight","applyControlsSize","viewportWidth","modal","postAnchor","postAnchorToMountedFrames","refreshAnchor","next","scheduleAnchorRefresh","handleWindowResize","frameLoaded","event","hideModal","resetFrame","resolveInitialFrames","rejectInitialFrames","initialFrameReadiness","resolve","reject","onMessage","fromStage","fromControls","fromModal","message","sourceMode","modalUrl","locationPoll","onAbort","cleanup","error","mounts","mountDanmaku","byTarget","existing","pending","raw","handle"],"mappings":"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"}