@viceme-ai/sdk 0.6.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +65 -17
  2. package/dist/capability-mount.d.ts +2 -0
  3. package/dist/capability-mount.d.ts.map +1 -1
  4. package/dist/chunks/client-DbPCnwf-.js +1471 -0
  5. package/dist/chunks/client-DbPCnwf-.js.map +1 -0
  6. package/dist/chunks/integration-CTsnJ8mN.js +38 -0
  7. package/dist/chunks/integration-CTsnJ8mN.js.map +1 -0
  8. package/dist/chunks/version-DXLLix7K.js +6 -0
  9. package/dist/chunks/{version-BJiUVcir.js.map → version-DXLLix7K.js.map} +1 -1
  10. package/dist/core/access-bridge.d.ts +17 -0
  11. package/dist/core/access-bridge.d.ts.map +1 -0
  12. package/dist/core/capabilities.d.ts +12 -2
  13. package/dist/core/capabilities.d.ts.map +1 -1
  14. package/dist/core/client.d.ts.map +1 -1
  15. package/dist/core/presentation.d.ts +10 -1
  16. package/dist/core/presentation.d.ts.map +1 -1
  17. package/dist/danmaku/mount.d.ts.map +1 -1
  18. package/dist/danmaku.js +117 -91
  19. package/dist/danmaku.js.map +1 -1
  20. package/dist/engagement/integration.d.ts +15 -0
  21. package/dist/engagement/integration.d.ts.map +1 -0
  22. package/dist/generated/public-contract.d.ts +260 -12
  23. package/dist/generated/public-contract.d.ts.map +1 -1
  24. package/dist/index.js +29 -27
  25. package/dist/index.js.map +1 -1
  26. package/dist/loader/auto-loader.d.ts.map +1 -1
  27. package/dist/manifest.json +37 -28
  28. package/dist/session/session.d.ts +36 -3
  29. package/dist/session/session.d.ts.map +1 -1
  30. package/dist/testing.js +1 -1
  31. package/dist/tip/index.d.ts +2 -0
  32. package/dist/tip/index.d.ts.map +1 -1
  33. package/dist/tip/mount.d.ts.map +1 -1
  34. package/dist/tip.js +211 -194
  35. package/dist/tip.js.map +1 -1
  36. package/dist/transport/transport.d.ts +2 -0
  37. package/dist/transport/transport.d.ts.map +1 -1
  38. package/dist/version.d.ts +1 -1
  39. package/dist/viceme.min.js +51 -8
  40. package/dist/viceme.min.js.map +1 -1
  41. package/package.json +1 -1
  42. package/dist/chunks/client-DEg6YouY.js +0 -1027
  43. package/dist/chunks/client-DEg6YouY.js.map +0 -1
  44. package/dist/chunks/version-BJiUVcir.js +0 -6
package/dist/danmaku.js CHANGED
@@ -1,14 +1,15 @@
1
- import { B as re } from "./chunks/build-endpoints-NrDmg6jf.js";
2
- import { c as S, V as P } from "./chunks/errors-C7DfLKcF.js";
3
- import { S as ae } from "./chunks/version-BJiUVcir.js";
1
+ import { B as oe } from "./chunks/build-endpoints-NrDmg6jf.js";
2
+ import { c as A, V as P } from "./chunks/errors-C7DfLKcF.js";
3
+ import { S as se } from "./chunks/version-DXLLix7K.js";
4
+ import { r as ie, h as le, o as ce } from "./chunks/integration-CTsnJ8mN.js";
4
5
  function Z(a = window, t = document) {
5
- const r = ne(a, t), e = oe(a, t);
6
+ const r = de(a, t), e = me(a, t);
6
7
  return {
7
- anchorKey: `page:${se(r)}:scroll:${e}`,
8
+ anchorKey: `page:${he(r)}:scroll:${e}`,
8
9
  scrollBucket: e
9
10
  };
10
11
  }
11
- function ne(a, t) {
12
+ function de(a, t) {
12
13
  const r = t.querySelector('link[rel="canonical"][href]'), e = r?.href || a.location.href;
13
14
  try {
14
15
  const l = new URL(e, a.location.href);
@@ -17,7 +18,7 @@ function ne(a, t) {
17
18
  return a.location.href;
18
19
  }
19
20
  }
20
- function oe(a, t) {
21
+ function me(a, t) {
21
22
  const r = t.documentElement, e = t.body, l = a.scrollY || a.pageYOffset || r.scrollTop || e?.scrollTop || 0, m = Math.max(
22
23
  r.scrollHeight,
23
24
  r.offsetHeight,
@@ -26,10 +27,10 @@ function oe(a, t) {
26
27
  e?.offsetHeight ?? 0
27
28
  ), v = Math.max(0, m - a.innerHeight);
28
29
  if (v <= 1) return "0-100";
29
- const f = Math.max(0, Math.min(99, l / v * 100)), y = Math.min(90, Math.floor(f / 10) * 10);
30
+ const u = Math.max(0, Math.min(99, l / v * 100)), y = Math.min(90, Math.floor(u / 10) * 10);
30
31
  return `${y}-${y + 10}`;
31
32
  }
32
- function se(a) {
33
+ function he(a) {
33
34
  let t = 3735928559 ^ a.length, r = 1103547991 ^ a.length;
34
35
  for (let e = 0; e < a.length; e += 1) {
35
36
  const l = a.charCodeAt(e);
@@ -37,10 +38,15 @@ function se(a) {
37
38
  }
38
39
  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);
39
40
  }
40
- const W = 32, ie = 56, le = 360, A = 480, ce = 120, de = 1e3, J = 8e3;
41
- async function me(a, t) {
42
- if (t.signal?.aborted) throw S();
43
- if (await a.ready(), t.signal?.aborted) throw S();
41
+ const b = 32, J = 12, j = 56, ue = 360, ge = 328, fe = 340, ye = 120, pe = 1e3, ee = 8e3, be = ["source", "action", "workKey"];
42
+ function ve(a, t) {
43
+ if (typeof a != "object" || a === null || Array.isArray(a)) return !1;
44
+ const r = Object.keys(a);
45
+ return r.length === t.length && t.every((e) => r.includes(e));
46
+ }
47
+ async function Ee(a, t) {
48
+ if (t.signal?.aborted) throw A();
49
+ if (await a.ready(), t.signal?.aborted) throw A();
44
50
  if (!a.hasCapability("danmaku"))
45
51
  throw new P({
46
52
  code: "CAPABILITY_DISABLED",
@@ -56,42 +62,42 @@ async function me(a, t) {
56
62
  retryable: !1,
57
63
  capability: "danmaku"
58
64
  });
59
- const l = re[a.region];
65
+ const l = oe[a.region];
60
66
  let m = Z(e, r);
61
67
  const v = r.documentElement.lang.trim() || e.navigator.language || "en";
62
- let f = !1, y, E, u, I = !1, O = 0, T = "", L = !1;
63
- const x = /* @__PURE__ */ new WeakSet(), R = /* @__PURE__ */ new Set(), h = r.createElement("div");
68
+ let u = !1, y, T, g, I = !1, U = 0, R = "", L = !1, _;
69
+ const x = /* @__PURE__ */ new WeakSet(), O = /* @__PURE__ */ new Set(), h = r.createElement("div");
64
70
  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 j = h.attachShadow({ mode: "open" }), p = r.createElement("div");
66
- 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);
67
- const _ = (n) => {
68
- const i = new URL("/embed/danmaku", l);
69
- 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;
70
- }, D = (n, i, k) => {
71
- const s = r.createElement("iframe");
72
- return s.title = i, s.src = k, s.loading = "eager", s.referrerPolicy = "no-referrer", s.setAttribute("allowtransparency", "true"), s.setAttribute(
71
+ const re = h.attachShadow({ mode: "open" }), p = r.createElement("div");
72
+ 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", re.append(p);
73
+ const D = (n) => {
74
+ const c = new URL("/embed/danmaku", l);
75
+ return c.searchParams.set("mode", n), c.searchParams.set("workKey", a.workKey), c.searchParams.set("theme", t.theme), c.searchParams.set("locale", v), c.searchParams.set("sdk", se), c.searchParams.set("anchorKey", m.anchorKey), c;
76
+ }, N = (n, c, w) => {
77
+ const i = r.createElement("iframe");
78
+ return i.title = c, i.src = w, i.loading = "eager", i.referrerPolicy = "no-referrer", i.setAttribute("allowtransparency", "true"), i.setAttribute(
73
79
  "sandbox",
74
80
  "allow-forms allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"
75
- ), 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;
76
- }, g = D("stage", "ViceMe Danmaku", _("stage").toString());
77
- g.setAttribute("aria-hidden", "true"), g.style.inset = "0", g.style.height = "100%", g.style.pointerEvents = "none";
78
- const d = D(
81
+ ), i.dataset.mode = n, i.style.boxSizing = "border-box", i.style.colorScheme = "normal", i.style.position = "fixed", i.style.margin = "0", i.style.border = "0", i.style.background = "transparent", i.style.width = "100%", i.style.zIndex = "2147483000", i;
82
+ }, f = N("stage", "ViceMe Danmaku", D("stage").toString());
83
+ f.setAttribute("aria-hidden", "true"), f.style.inset = "0", f.style.height = "100%", f.style.pointerEvents = "none";
84
+ const d = N(
79
85
  "controls",
80
86
  "ViceMe Danmaku controls",
81
- _("controls").toString()
87
+ D("controls").toString()
82
88
  );
83
- d.style.left = "50%", d.style.bottom = "env(safe-area-inset-bottom, 0px)", d.style.maxWidth = `${A}px`, d.style.transform = "translateX(-50%)";
84
- let K = A, U = ie;
85
- const N = () => {
89
+ d.style.left = "50%", d.style.bottom = "env(safe-area-inset-bottom, 0px)", d.style.transform = "translateX(-50%)";
90
+ let W = !1, G = j;
91
+ const C = () => {
86
92
  const n = Math.max(
87
- W,
88
- Math.floor(e.innerWidth || A)
93
+ b,
94
+ Math.floor(e.innerWidth || b)
89
95
  );
90
- d.style.width = `${Math.min(K, n)}px`, d.style.height = `${U}px`;
96
+ d.style.width = `${W ? b : n}px`, d.style.height = `${G}px`;
91
97
  };
92
- N(), d.style.pointerEvents = "none";
93
- const o = D("modal", "ViceMe Danmaku dialog", "about:blank");
94
- 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);
98
+ C(), d.style.pointerEvents = "none";
99
+ const s = N("modal", "ViceMe Danmaku dialog", "about:blank");
100
+ s.dataset.src = D("modal").toString(), s.style.inset = "0", s.style.height = "100%", s.style.display = "none", s.style.pointerEvents = "none", p.append(f, d, s);
95
101
  const M = (n) => {
96
102
  x.has(n) && n.contentWindow?.postMessage(
97
103
  {
@@ -102,27 +108,37 @@ async function me(a, t) {
102
108
  l
103
109
  );
104
110
  }, z = () => {
105
- M(g), M(d), o.getAttribute("src") !== "about:blank" && M(o);
106
- }, F = () => {
107
- if (f) return m;
111
+ M(f), M(d), s.getAttribute("src") !== "about:blank" && M(s);
112
+ }, F = (n) => {
113
+ d.contentWindow?.postMessage(
114
+ {
115
+ source: "viceme-engagement",
116
+ action: "tip-availability",
117
+ available: n,
118
+ workKey: a.workKey
119
+ },
120
+ l
121
+ );
122
+ }, B = () => {
123
+ if (u) return m;
108
124
  const n = Z(e, r);
109
125
  return n.anchorKey !== m.anchorKey && (m = n, z()), m;
110
- }, b = () => {
111
- y !== void 0 && e.clearTimeout(y), y = e.setTimeout(F, ce);
112
- }, B = () => {
113
- N(), b();
114
- }, w = (n) => {
115
- const i = n.currentTarget;
116
- i.getAttribute("src") !== "about:blank" && (x.add(i), M(i));
126
+ }, E = () => {
127
+ y !== void 0 && e.clearTimeout(y), y = e.setTimeout(B, ye);
128
+ }, V = () => {
129
+ C(), E();
130
+ }, k = (n) => {
131
+ const c = n.currentTarget;
132
+ c.getAttribute("src") !== "about:blank" && (x.add(c), M(c));
117
133
  };
118
- g.addEventListener("load", w), d.addEventListener("load", w), o.addEventListener("load", w);
119
- const V = (n = !1) => {
120
- 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");
134
+ f.addEventListener("load", k), d.addEventListener("load", k), s.addEventListener("load", k);
135
+ const Y = (n = !1) => {
136
+ g !== void 0 && (e.clearTimeout(g), g = void 0), s.style.display = "none", s.style.pointerEvents = "none", n && (R = "", L = !1, x.delete(s), s.src = "about:blank");
121
137
  };
122
138
  let $, q;
123
- const ee = new Promise((n, i) => {
124
- $ = n, q = i, E = e.setTimeout(() => {
125
- i(
139
+ const ae = new Promise((n, c) => {
140
+ $ = n, q = c, T = e.setTimeout(() => {
141
+ c(
126
142
  new P({
127
143
  code: "INTERNAL_ERROR",
128
144
  message: "Hosted danmaku frames did not become ready in time.",
@@ -130,47 +146,57 @@ async function me(a, t) {
130
146
  capability: "danmaku"
131
147
  })
132
148
  );
133
- }, J);
134
- }), G = (n) => {
149
+ }, ee);
150
+ }), X = (n) => {
135
151
  if (n.origin !== l) return;
136
- const i = n.source === g.contentWindow, k = n.source === d.contentWindow, s = n.source === o.contentWindow;
137
- if (!i && !k && !s) return;
138
- const c = n.data;
139
- if (!c || c.source !== "viceme-danmaku") return;
140
- const C = s ? "modal" : i ? "stage" : "controls";
141
- if (c.action === "frame-ready") {
142
- if (c.mode !== C) return;
143
- if (C === "modal") {
144
- if (c.frameToken !== T) return;
145
- L = !0, u !== void 0 && (e.clearTimeout(u), u = void 0), o.style.display === "block" && (o.style.pointerEvents = "auto");
152
+ const c = n.source === f.contentWindow, w = n.source === d.contentWindow, i = n.source === s.contentWindow;
153
+ if (!c && !w && !i) return;
154
+ const o = n.data;
155
+ if (w && ve(o, be) && o.source === "viceme-engagement" && o.workKey === a.workKey) {
156
+ o.action === "request-tip-availability" ? F(le(a, t.target)) : o.action === "open-tip" && I && ce(a, t.target);
157
+ return;
158
+ }
159
+ if (!o || o.source !== "viceme-danmaku") return;
160
+ const K = i ? "modal" : c ? "stage" : "controls";
161
+ if (o.action === "frame-ready") {
162
+ if (o.mode !== K) return;
163
+ if (K === "modal") {
164
+ if (o.frameToken !== R) return;
165
+ L = !0, g !== void 0 && (e.clearTimeout(g), g = void 0), s.style.display === "block" && (s.style.pointerEvents = "auto");
146
166
  return;
147
167
  }
148
- 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", $?.());
168
+ O.add(K), O.has("stage") && O.has("controls") && !I && (I = !0, T !== void 0 && (e.clearTimeout(T), T = void 0), d.style.pointerEvents = "auto", $?.());
149
169
  return;
150
170
  }
151
- if (c.action === "resize-controls" && k) {
152
- 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)
171
+ if (o.action === "resize-controls" && w) {
172
+ if (typeof o.width != "number" || !Number.isSafeInteger(o.width) || o.width < b || typeof o.height != "number" || !Number.isSafeInteger(o.height) || o.height < b || o.height > ue)
153
173
  return;
154
- K = c.width, U = c.height, N();
174
+ const S = o.width === b && o.height <= b + J;
175
+ if (!S && o.height < j) return;
176
+ W = S, G = S ? b + J : o.height === ge ? fe : o.height, C();
155
177
  }
156
- if (c.action === "request-anchor" && M(s ? o : i ? g : d), c.action === "open-modal" && k) {
178
+ if (o.action === "request-anchor" && M(i ? s : c ? f : d), o.action === "open-modal" && w) {
157
179
  if (!I) return;
158
- if (o.getAttribute("src") === "about:blank") {
159
- O += 1, T = String(O);
160
- const X = new URL(o.dataset.src ?? "about:blank");
161
- X.searchParams.set("frameToken", T), o.src = X.toString();
180
+ if (s.getAttribute("src") === "about:blank") {
181
+ U += 1, R = String(U);
182
+ const S = new URL(s.dataset.src ?? "about:blank");
183
+ S.searchParams.set("frameToken", R), s.src = S.toString();
162
184
  }
163
- o.style.display = "block", o.style.pointerEvents = L ? "auto" : "none", L || (u !== void 0 && e.clearTimeout(u), u = e.setTimeout(() => V(!0), J));
185
+ s.style.display = "block", s.style.pointerEvents = L ? "auto" : "none", L || (g !== void 0 && e.clearTimeout(g), g = e.setTimeout(() => Y(!0), ee));
164
186
  }
165
- c.action === "close-modal" && (s || k) && V(!L);
166
- }, te = e.setInterval(F, de), Y = () => {
167
- q?.(S()), H();
187
+ o.action === "close-modal" && (i || w) && Y(!L);
188
+ }, ne = e.setInterval(B, pe), Q = () => {
189
+ q?.(A()), H();
168
190
  }, H = () => {
169
- 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());
191
+ u || (u = !0, y !== void 0 && e.clearTimeout(y), T !== void 0 && e.clearTimeout(T), g !== void 0 && e.clearTimeout(g), e.clearInterval(ne), e.removeEventListener("message", X), e.removeEventListener("scroll", E), e.removeEventListener("resize", V), e.removeEventListener("popstate", E), e.removeEventListener("hashchange", E), f.removeEventListener("load", k), d.removeEventListener("load", k), s.removeEventListener("load", k), _?.(), _ = void 0, t.signal?.removeEventListener("abort", Q), h.remove());
170
192
  };
171
193
  try {
172
- 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();
173
- t.target.appendChild(h), z(), await ee;
194
+ if (e.addEventListener("message", X), e.addEventListener("scroll", E, { passive: !0 }), e.addEventListener("resize", V), e.addEventListener("popstate", E), e.addEventListener("hashchange", E), t.signal?.addEventListener("abort", Q, { once: !0 }), t.signal?.aborted) throw A();
195
+ if (t.target.appendChild(h), z(), await ae, u || t.signal?.aborted) throw A();
196
+ _ = ie(a, t.target, {
197
+ focus: () => d.focus(),
198
+ setTipAvailable: F
199
+ });
174
200
  } catch (n) {
175
201
  throw H(), n;
176
202
  }
@@ -179,27 +205,27 @@ async function me(a, t) {
179
205
  destroy: H
180
206
  };
181
207
  }
182
- const Q = /* @__PURE__ */ new WeakMap();
183
- function ge(a, t) {
184
- let r = Q.get(a);
185
- r || (r = /* @__PURE__ */ new WeakMap(), Q.set(a, r));
208
+ const te = /* @__PURE__ */ new WeakMap();
209
+ function Le(a, t) {
210
+ let r = te.get(a);
211
+ r || (r = /* @__PURE__ */ new WeakMap(), te.set(a, r));
186
212
  const e = r.get(t.target);
187
213
  if (e) return e;
188
- const l = me(a, t).then((m) => {
214
+ const l = Ee(a, t).then((m) => {
189
215
  let v = !1;
190
- const f = {
216
+ const u = {
191
217
  capability: "danmaku",
192
218
  destroy() {
193
- v || (v = !0, t.signal?.removeEventListener("abort", f.destroy), r.get(t.target) === l && r.delete(t.target), m.destroy());
219
+ v || (v = !0, t.signal?.removeEventListener("abort", u.destroy), r.get(t.target) === l && r.delete(t.target), m.destroy());
194
220
  }
195
221
  };
196
- return t.signal?.addEventListener("abort", f.destroy, { once: !0 }), t.signal?.aborted && f.destroy(), f;
222
+ return t.signal?.addEventListener("abort", u.destroy, { once: !0 }), t.signal?.aborted && u.destroy(), u;
197
223
  }).catch((m) => {
198
224
  throw r.get(t.target) === l && r.delete(t.target), m;
199
225
  });
200
226
  return r.set(t.target, l), l;
201
227
  }
202
228
  export {
203
- ge as mountDanmaku
229
+ Le as mountDanmaku
204
230
  };
205
231
  //# sourceMappingURL=danmaku.js.map
@@ -1 +1 @@
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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"}
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 {\n hasIntegratedTip,\n openIntegratedTip,\n registerIntegratedDanmaku,\n} from '../engagement/integration.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 workKey?: unknown;\n}\n\nconst CONTROLS_MIN_SIZE = 32;\nconst CONTROLS_BOTTOM_GAP = 12;\nconst CONTROLS_BAR_HEIGHT = 56;\nconst CONTROLS_MAX_HEIGHT = 360;\nconst CONTROLS_LEGACY_MORE_HEIGHT = 328;\nconst CONTROLS_MORE_HEIGHT = 340;\nconst ANCHOR_DEBOUNCE_MS = 120;\nconst LOCATION_POLL_MS = 1_000;\nexport const FRAME_READY_TIMEOUT_MS = 8_000;\nconst ENGAGEMENT_REQUEST_KEYS = ['source', 'action', 'workKey'];\n\nfunction isStrictRecord(value: unknown, keys: string[]): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const actualKeys = Object.keys(value);\n return actualKeys.length === keys.length && keys.every((key) => actualKeys.includes(key));\n}\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 let unregisterIntegration: (() => void) | undefined;\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.transform = 'translateX(-50%)';\n let controlsCompact = false;\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_MIN_SIZE),\n );\n controls.style.width = `${controlsCompact ? CONTROLS_MIN_SIZE : 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 const postTipAvailability = (available: boolean): void => {\n controls.contentWindow?.postMessage(\n {\n source: 'viceme-engagement',\n action: 'tip-availability',\n available,\n workKey: client.workKey,\n },\n widgetOrigin,\n );\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 (\n fromControls &&\n isStrictRecord(message, ENGAGEMENT_REQUEST_KEYS) &&\n message.source === 'viceme-engagement' &&\n message.workKey === client.workKey\n ) {\n if (message.action === 'request-tip-availability') {\n postTipAvailability(hasIntegratedTip(client, options.target));\n } else if (message.action === 'open-tip' && initialFramesReady) {\n openIntegratedTip(client, options.target);\n }\n return;\n }\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.isSafeInteger(message.width) ||\n message.width < CONTROLS_MIN_SIZE ||\n typeof message.height !== 'number' ||\n !Number.isSafeInteger(message.height) ||\n message.height < CONTROLS_MIN_SIZE ||\n message.height > CONTROLS_MAX_HEIGHT\n ) {\n return;\n }\n const compact =\n message.width === CONTROLS_MIN_SIZE &&\n message.height <= CONTROLS_MIN_SIZE + CONTROLS_BOTTOM_GAP;\n if (!compact && message.height < CONTROLS_BAR_HEIGHT) return;\n controlsCompact = compact;\n controlsRequestedHeight = compact\n ? CONTROLS_MIN_SIZE + CONTROLS_BOTTOM_GAP\n : message.height === CONTROLS_LEGACY_MORE_HEIGHT\n ? CONTROLS_MORE_HEIGHT\n : 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 unregisterIntegration?.();\n unregisterIntegration = undefined;\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 if (destroyed || options.signal?.aborted) throw clientDestroyed();\n unregisterIntegration = registerIntegratedDanmaku(client, options.target, {\n focus: () => controls.focus(),\n setTipAvailable: postTipAvailability,\n });\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_BOTTOM_GAP","CONTROLS_BAR_HEIGHT","CONTROLS_MAX_HEIGHT","CONTROLS_LEGACY_MORE_HEIGHT","CONTROLS_MORE_HEIGHT","ANCHOR_DEBOUNCE_MS","LOCATION_POLL_MS","FRAME_READY_TIMEOUT_MS","ENGAGEMENT_REQUEST_KEYS","isStrictRecord","keys","actualKeys","key","mount","client","options","clientDestroyed","ViceMeError","widgetOrigin","BUILD_WIDGET_ORIGINS","currentAnchor","locale","destroyed","anchorTimer","readyTimer","modalReadyTimer","initialFramesReady","modalAttempt","modalFrameToken","modalReady","unregisterIntegration","loadedFrames","readyModes","portal","shadow","frameUrl","mode","SDK_VERSION","createFrame","title","source","frame","stage","controls","controlsCompact","controlsRequestedHeight","applyControlsSize","viewportWidth","modal","postAnchor","postAnchorToMountedFrames","postTipAvailability","available","refreshAnchor","next","scheduleAnchorRefresh","handleWindowResize","frameLoaded","event","hideModal","resetFrame","resolveInitialFrames","rejectInitialFrames","initialFrameReadiness","resolve","reject","onMessage","fromStage","fromControls","fromModal","message","hasIntegratedTip","openIntegratedTip","sourceMode","compact","modalUrl","locationPoll","onAbort","cleanup","registerIntegratedDanmaku","error","mounts","mountDanmaku","byTarget","existing","pending","raw","handle"],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { ViceMeClient } from '../core/client.ts';
2
+ interface DanmakuIntegration {
3
+ focus(): void;
4
+ setTipAvailable(available: boolean): void;
5
+ }
6
+ interface TipIntegration {
7
+ open(): void;
8
+ }
9
+ export declare function registerIntegratedDanmaku(client: ViceMeClient, target: Element, danmaku: DanmakuIntegration): () => void;
10
+ export declare function registerIntegratedTip(client: ViceMeClient, target: Element, tip: TipIntegration): () => void;
11
+ export declare function hasIntegratedTip(client: ViceMeClient, target: Element): boolean;
12
+ export declare function openIntegratedTip(client: ViceMeClient, target: Element): void;
13
+ export declare function focusIntegratedDanmaku(client: ViceMeClient, target: Element): void;
14
+ export {};
15
+ //# sourceMappingURL=integration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../src/engagement/integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,UAAU,kBAAkB;IAC1B,KAAK,IAAI,IAAI,CAAC;IACd,eAAe,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3C;AAED,UAAU,cAAc;IACtB,IAAI,IAAI,IAAI,CAAC;CACd;AA2BD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,kBAAkB,GAC1B,MAAM,IAAI,CAUZ;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,OAAO,EACf,GAAG,EAAE,cAAc,GAClB,MAAM,IAAI,CAWZ;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAE/E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAE7E;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAElF"}