@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
@@ -1,1027 +0,0 @@
1
- import { a as L, V as b, c as v, i as G } from "./errors-C7DfLKcF.js";
2
- import { a as q, B as j } from "./build-endpoints-NrDmg6jf.js";
3
- import { S as W, A as H } from "./version-BJiUVcir.js";
4
- const V = /* @__PURE__ */ new Set(["cn", "global"]), z = {
5
- cn: q.cn,
6
- global: q.global
7
- };
8
- function pe(t) {
9
- return z[t];
10
- }
11
- function B(t) {
12
- return typeof t == "string" && /^wrk_(?:test|live)_[A-Za-z0-9_-]{4,119}$/.test(t);
13
- }
14
- function Y(t) {
15
- return typeof t == "string" && V.has(t);
16
- }
17
- function ye(t) {
18
- if (typeof t != "object" || t === null)
19
- throw L("createViceMe expects a configuration object.");
20
- const e = t, i = /* @__PURE__ */ new Set(["workKey", "region", "signal"]);
21
- for (const r of Object.keys(e))
22
- if (!i.has(r))
23
- throw L(`Unknown configuration field "${r}".`);
24
- if (!B(e.workKey))
25
- throw L(
26
- 'Configuration field "workKey" must start with "wrk_test_" or "wrk_live_".'
27
- );
28
- if (!Y(e.region))
29
- throw L('Configuration field "region" must be "cn" or "global".');
30
- if (e.signal !== void 0 && !(e.signal instanceof AbortSignal))
31
- throw L('Configuration field "signal" must be an AbortSignal.');
32
- return {
33
- workKey: e.workKey,
34
- region: e.region,
35
- signal: e.signal
36
- };
37
- }
38
- const $ = {
39
- CREATED: ["READY", "DESTROYED"],
40
- READY: ["DEGRADED", "DESTROYED"],
41
- DEGRADED: ["DESTROYED"],
42
- DESTROYED: []
43
- };
44
- class Q {
45
- #e = "CREATED";
46
- #t = /* @__PURE__ */ new Set();
47
- get state() {
48
- return this.#e;
49
- }
50
- get destroyed() {
51
- return this.#e === "DESTROYED";
52
- }
53
- transition(e) {
54
- if (e !== this.#e) {
55
- if (!$[this.#e].includes(e))
56
- throw new b({
57
- code: "INTERNAL_ERROR",
58
- message: `Illegal lifecycle transition ${this.#e} -> ${e}.`,
59
- retryable: !1
60
- });
61
- this.#e = e;
62
- for (const i of this.#t) i(e);
63
- }
64
- }
65
- /** Any operation on a destroyed client must fail closed with this guard. */
66
- assertAlive() {
67
- if (this.destroyed) throw v();
68
- }
69
- subscribe(e) {
70
- return this.#t.add(e), () => {
71
- this.#t.delete(e);
72
- };
73
- }
74
- clearListeners() {
75
- this.#t.clear();
76
- }
77
- }
78
- function X(t, e) {
79
- if (typeof t != "object" || t === null)
80
- throw R();
81
- const i = t;
82
- if (typeof i.workKey != "string" || !Array.isArray(i.capabilities) || !i.capabilities.every((c) => typeof c == "string"))
83
- throw R();
84
- if (i.workKey !== e)
85
- throw new b({
86
- code: "WORK_NOT_FOUND",
87
- message: "Work-session response did not match the requested work key.",
88
- retryable: !1
89
- });
90
- const r = {
91
- work: {
92
- key: i.workKey,
93
- capabilities: i.capabilities
94
- }
95
- };
96
- if (typeof i.token == "string" && (r.token = i.token), typeof i.expiresAt == "string") {
97
- const c = new Date(i.expiresAt).getTime();
98
- Number.isNaN(c) || (r.expiresAt = c);
99
- }
100
- return r;
101
- }
102
- function R() {
103
- return new b({
104
- code: "INTERNAL_ERROR",
105
- message: "Malformed work-session response.",
106
- retryable: !0
107
- });
108
- }
109
- function J() {
110
- return new b({
111
- code: "SESSION_EXPIRED",
112
- message: "The work session was invalidated before it completed.",
113
- retryable: !0
114
- });
115
- }
116
- class Z {
117
- #e;
118
- #t;
119
- #i;
120
- #r;
121
- #n = 0;
122
- #a = !1;
123
- constructor(e) {
124
- this.#e = e, this.#t = e.now ?? (() => Date.now());
125
- }
126
- get snapshot() {
127
- return this.#i;
128
- }
129
- /** True when the cached snapshot's server-provided expiry has passed. */
130
- #s() {
131
- const e = this.#i?.expiresAt;
132
- return e !== void 0 && e <= this.#t();
133
- }
134
- /**
135
- * Establish (or return the established) public session.
136
- *
137
- * A cached snapshot is reused only while it is unexpired; an expired
138
- * snapshot is dropped and re-authenticated. Concurrent callers share one
139
- * in-flight request (single flight).
140
- */
141
- establish() {
142
- if (this.#a) return Promise.reject(v());
143
- if (this.#i) {
144
- if (!this.#s()) return Promise.resolve(this.#i);
145
- this.#i = void 0;
146
- }
147
- if (this.#r) return this.#r;
148
- const e = this.#n, i = this.#e.transport.request({
149
- method: "POST",
150
- path: "/v1/public/work-sdk/sessions",
151
- body: { workKey: this.#e.workKey },
152
- signal: this.#e.signal,
153
- timeoutMs: this.#e.timeoutMs
154
- }).then((r) => {
155
- this.#c(e);
156
- const c = X(r.body, this.#e.workKey);
157
- return this.#c(e), this.#i = c, c;
158
- }).finally(() => {
159
- this.#r === i && (this.#r = void 0);
160
- });
161
- return this.#r = i, i;
162
- }
163
- async request(e) {
164
- const i = await this.establish();
165
- if (!i.token) throw R();
166
- try {
167
- return await this.#l(e, i);
168
- } catch (r) {
169
- if (this.#a) throw v();
170
- if (!(r instanceof b) || r.code !== "SESSION_EXPIRED") throw r;
171
- this.#i === i && this.invalidate();
172
- const c = await this.establish();
173
- if (!c.token) throw R();
174
- return this.#l(e, c);
175
- }
176
- }
177
- authenticate(e) {
178
- if (this.#o(), !this.#i) throw R();
179
- this.#i = {
180
- ...this.#i,
181
- userToken: e.userToken,
182
- user: e.user
183
- };
184
- }
185
- async signOut() {
186
- this.#o(), this.invalidate(), await this.establish();
187
- }
188
- /** Drop the token; next `establish()` re-authenticates. */
189
- invalidate() {
190
- this.#n += 1, this.#i = void 0, this.#r = void 0;
191
- }
192
- /** Hard cleanup: forget the token and pending work. */
193
- destroy() {
194
- this.#a || (this.#a = !0, this.#n += 1, this.#i = void 0, this.#r = void 0);
195
- }
196
- #o() {
197
- if (this.#a) throw v();
198
- }
199
- #c(e) {
200
- if (this.#o(), e !== this.#n) throw J();
201
- }
202
- async #l(e, i) {
203
- this.#o();
204
- try {
205
- const r = await this.#e.transport.request({
206
- ...e,
207
- authorization: i.token,
208
- userAuthorization: i.userToken,
209
- signal: this.#e.signal
210
- });
211
- return this.#o(), r;
212
- } catch (r) {
213
- throw this.#a ? v() : r;
214
- }
215
- }
216
- }
217
- const K = "viceme-access-layer", P = 50;
218
- function ee(t) {
219
- switch (t) {
220
- case "SIGN_IN":
221
- return {
222
- description: "",
223
- label: "授权"
224
- };
225
- case "FOLLOW":
226
- return {
227
- description: "",
228
- label: "关注"
229
- };
230
- case "CHECKOUT":
231
- return {
232
- description: "",
233
- label: "打开支付"
234
- };
235
- }
236
- }
237
- function te(t) {
238
- if (!G(t)) return "操作未完成,请重试。";
239
- switch (t.code) {
240
- case "CONFIG_INVALID":
241
- return "微信授权配置无效,请稍后重试。";
242
- case "AUTH_CANCELLED":
243
- return "微信授权已取消,请重试。";
244
- case "SESSION_EXPIRED":
245
- return "授权会话已过期,请重试。";
246
- case "NETWORK_TIMEOUT":
247
- return "网络连接超时,请重试。";
248
- default:
249
- return t.requestId ? `操作未完成,请重试。请求 ID:${t.requestId}` : "操作未完成,请重试。";
250
- }
251
- }
252
- function ie() {
253
- if (customElements.get(K)) return;
254
- class t extends HTMLElement {
255
- interaction;
256
- connectedCallback() {
257
- const i = ee(this.interaction.action), r = this.attachShadow({ mode: "open" });
258
- r.innerHTML = `
259
- <style>
260
- :host {
261
- position: fixed;
262
- inset: 0;
263
- z-index: 2147483000;
264
- display: grid;
265
- align-items: end;
266
- color: #18181b;
267
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
268
- font-size: 16px;
269
- line-height: 1.5;
270
- }
271
- [data-viceme='backdrop'] {
272
- position: absolute;
273
- inset: 0;
274
- border: 0;
275
- border-radius: 0;
276
- background: transparent;
277
- }
278
- [data-viceme='panel'] {
279
- position: relative;
280
- box-sizing: border-box;
281
- display: flex;
282
- width: 100%;
283
- max-height: min(92dvh, 46rem);
284
- flex-direction: column;
285
- overflow: auto;
286
- border-radius: 1.25rem 1.25rem 0 0;
287
- background: #ffffff;
288
- color: #18181b;
289
- padding: 3.75rem 1.25rem calc(1.25rem + env(safe-area-inset-bottom));
290
- box-shadow: 0 -1rem 3rem rgb(0 0 0 / 18%);
291
- }
292
- [data-viceme='content'] { display: flex; min-height: 0; flex-direction: column; }
293
- [data-viceme='close'] {
294
- position: absolute;
295
- top: 0.75rem;
296
- left: 0.75rem;
297
- width: 2.75rem;
298
- height: 2.75rem;
299
- border: 0;
300
- border-radius: 999px;
301
- padding: 0;
302
- background: transparent;
303
- color: #52525b;
304
- font-size: 2rem;
305
- font-weight: 400;
306
- line-height: 1;
307
- }
308
- [data-viceme='description'] { margin: 0.75rem 0 1.25rem; color: #71717a; line-height: 1.6; }
309
- [data-viceme='profile'] {
310
- display: none;
311
- margin: 0;
312
- border: 1px solid #e4e4e7;
313
- border-radius: 1rem;
314
- padding: 1.5rem;
315
- background: #ffffff;
316
- box-shadow: 0 0.75rem 2rem rgb(0 0 0 / 6%);
317
- text-align: center;
318
- }
319
- [data-viceme='profile'][data-visible='true'] { display: block; }
320
- [data-viceme='avatar'] {
321
- display: block;
322
- width: 5.5rem;
323
- height: 5.5rem;
324
- margin: 0 auto 1rem;
325
- border-radius: 999px;
326
- object-fit: cover;
327
- background: #f4f4f5;
328
- }
329
- [data-viceme='avatar-fallback'] {
330
- display: grid;
331
- width: 5.5rem;
332
- height: 5.5rem;
333
- margin: 0 auto 1rem;
334
- place-items: center;
335
- border-radius: 999px;
336
- background: #f4f4f5;
337
- color: #18181b;
338
- font-size: 2rem;
339
- font-weight: 700;
340
- }
341
- [data-viceme='avatar'][hidden], [data-viceme='avatar-fallback'][hidden] { display: none; }
342
- [data-viceme='profile-summary'] {
343
- display: flex;
344
- min-width: 0;
345
- align-items: baseline;
346
- justify-content: center;
347
- gap: 0.5rem;
348
- }
349
- [data-viceme='profile-name'] { margin: 0; font-size: 1.375rem; font-weight: 700; }
350
- [data-viceme='profile-separator'], [data-viceme='profile-stats'] {
351
- color: #71717a;
352
- }
353
- [data-viceme='profile-description'] {
354
- margin: 0.25rem 0 0;
355
- overflow-wrap: anywhere;
356
- color: #71717a;
357
- }
358
- [data-viceme='profile-description']:empty { display: none; }
359
- [data-viceme='profile-stats'] {
360
- margin: 0;
361
- font-size: 0.875rem;
362
- }
363
- [data-viceme='profile-header'] { min-width: 0; }
364
- [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='description'] { display: none; }
365
- [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='profile'][data-visible='true'] {
366
- display: block;
367
- border: 0;
368
- padding: 0;
369
- background: transparent;
370
- box-shadow: none;
371
- text-align: center;
372
- }
373
- [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='profile-name'] {
374
- font-size: 1.125rem;
375
- }
376
- [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='profile-description'] {
377
- margin-top: 0.75rem;
378
- line-height: 1.625;
379
- }
380
- [data-viceme='panel'][data-action='SIGN_IN'] [data-viceme='action'] {
381
- width: 100%;
382
- }
383
- [data-viceme='actions'] {
384
- display: flex;
385
- justify-content: flex-end;
386
- gap: 0.75rem;
387
- margin-top: 1.25rem;
388
- }
389
- button {
390
- box-sizing: border-box;
391
- display: inline-flex;
392
- height: 3.25rem;
393
- align-items: center;
394
- justify-content: center;
395
- border-radius: 0.75rem;
396
- padding: 0.625rem 1rem;
397
- font: 600 1rem/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
398
- cursor: pointer;
399
- }
400
- button:focus-visible, iframe:focus-visible { outline: 2px solid #18181b; outline-offset: 2px; }
401
- [data-viceme='action'] {
402
- width: min(11rem, 48%);
403
- border: 1px solid #18181b;
404
- background: #18181b;
405
- color: #ffffff;
406
- }
407
- [data-viceme='action']:hover { background: #3f3f46; border-color: #3f3f46; }
408
- [data-viceme='actions'][data-single='true'] [data-viceme='action'] { width: 100%; }
409
- button:disabled { cursor: wait; opacity: 0.5; }
410
- button[hidden] { display: none; }
411
- [data-viceme='error'] { margin: 0.75rem 0 0; color: #b91c1c; font-size: 0.875rem; }
412
- [data-viceme='error']:empty { display: none; }
413
- [data-viceme='frame'] {
414
- display: none;
415
- width: 100%;
416
- min-height: 0;
417
- flex: 1 1 auto;
418
- border: 0;
419
- border-radius: 0.75rem;
420
- background: #ffffff;
421
- }
422
- [data-viceme='panel'][data-frame='true'] {
423
- height: min(92dvh, 46rem);
424
- max-height: 92dvh;
425
- overflow: hidden;
426
- }
427
- [data-viceme='panel'][data-frame='true'] [data-viceme='content'] { display: none; }
428
- [data-viceme='panel'][data-frame='true'] [data-viceme='frame'] { display: block; }
429
- @media (min-width: 48rem) {
430
- :host { place-items: center; padding: 1.5rem; }
431
- [data-viceme='panel'] {
432
- width: min(24rem, 100%);
433
- border-radius: 1.25rem;
434
- padding: 3.75rem 1.25rem 1.25rem;
435
- box-shadow: 0 1.5rem 4rem rgb(0 0 0 / 24%);
436
- }
437
- [data-viceme='panel'][data-frame='true'] { width: min(30rem, 100%); }
438
- [data-viceme='panel'][data-action='SIGN_IN'] { width: min(30rem, 100%); }
439
- [data-viceme='panel'][data-action='CHECKOUT'][data-frame='true'] {
440
- width: min(42rem, 100%);
441
- }
442
- }
443
- @media (prefers-reduced-motion: no-preference) {
444
- [data-viceme='panel'] { animation: viceme-enter 160ms ease-out; }
445
- @keyframes viceme-enter { from { opacity: 0; transform: translateY(1rem); } }
446
- }
447
- </style>
448
- <button data-viceme="backdrop" type="button" tabindex="-1" aria-label="关闭"></button>
449
- <section data-viceme="panel" role="dialog" aria-modal="true" aria-label="ViceMe 授权">
450
- <button data-viceme="close" type="button" aria-label="关闭">×</button>
451
- <div data-viceme="content">
452
- <p data-viceme="description"></p>
453
- <section data-viceme="profile" aria-label="创作者">
454
- <div data-viceme="profile-header">
455
- <img data-viceme="avatar" hidden />
456
- <span data-viceme="avatar-fallback" aria-hidden="true"></span>
457
- <div data-viceme="profile-summary">
458
- <p data-viceme="profile-name"></p>
459
- <span data-viceme="profile-separator" aria-hidden="true">·</span>
460
- <p data-viceme="profile-stats"></p>
461
- </div>
462
- </div>
463
- <p data-viceme="profile-description"></p>
464
- </section>
465
- <p data-viceme="error" role="alert" aria-live="polite"></p>
466
- <div data-viceme="actions">
467
- <button data-viceme="action" type="button"></button>
468
- </div>
469
- </div>
470
- <iframe data-viceme="frame" title="" referrerpolicy="no-referrer" allow="payment"></iframe>
471
- </section>
472
- `;
473
- const c = r.querySelector("[data-viceme='panel']");
474
- c.dataset.action = this.interaction.action, c.dataset.frame = "false";
475
- const O = r.querySelector("[data-viceme='description']");
476
- O.textContent = i.description;
477
- const f = r.querySelector("[data-viceme='action']"), U = f.parentElement, N = r.querySelector("[data-viceme='close']"), T = r.querySelector("[data-viceme='backdrop']"), C = r.querySelector("[data-viceme='error']"), S = r.querySelector("[data-viceme='frame']"), M = r.querySelector("[data-viceme='profile']"), x = r.querySelector("[data-viceme='avatar']"), n = r.querySelector("[data-viceme='avatar-fallback']"), o = r.querySelector("[data-viceme='profile-name']"), l = r.querySelector(
478
- "[data-viceme='profile-description']"
479
- ), a = r.querySelector("[data-viceme='profile-stats']");
480
- f.textContent = i.label, f.hidden = !1, U.dataset.single = "true";
481
- const d = i.label;
482
- S.title = this.interaction.action === "SIGN_IN" ? "登录授权" : "支付";
483
- const u = this.interaction.followTarget;
484
- if (u) {
485
- c.setAttribute(
486
- "aria-label",
487
- this.interaction.action === "SIGN_IN" ? `授权 ${u.displayName}` : `关注 ${u.displayName}`
488
- ), M.dataset.visible = "true", o.textContent = u.displayName;
489
- const s = [...u.description ?? ""];
490
- l.textContent = s.length > P ? `${s.slice(0, P).join("")}…` : s.join(""), s.length > P && (l.title = u.description), a.textContent = `${u.workCount} 个作品`, n.textContent = u.displayName.trim().slice(0, 1) || "V", u.avatarUrl && (x.src = u.avatarUrl, x.alt = `${u.displayName}的头像`, x.hidden = !1, n.hidden = !0);
491
- }
492
- let p = null, w = !1;
493
- const I = (s) => {
494
- w || (w = !0, this.interaction.signal?.removeEventListener("abort", y), this.dispatchEvent(new CustomEvent("viceme:access-layer-close", { detail: s })));
495
- }, y = () => {
496
- p?.cancel(), I("dismissed");
497
- };
498
- this.interaction.signal?.addEventListener("abort", y, { once: !0 }), this.interaction.signal?.aborted && queueMicrotask(y), T.addEventListener("click", y), N.addEventListener("click", y), this.addEventListener("keydown", (s) => {
499
- if (s.key === "Escape" && y(), s.key === "Tab") {
500
- if (s.preventDefault(), p?.type === "frame") {
501
- S.focus();
502
- return;
503
- }
504
- const m = [N, ...f.hidden ? [] : [f]].filter((_) => !_.disabled && !_.hidden);
505
- if (m.length === 0) return;
506
- const D = m.indexOf(r.activeElement), E = s.shiftKey ? -1 : 1;
507
- m[(D + E + m.length) % m.length]?.focus();
508
- }
509
- });
510
- const A = async () => {
511
- f.disabled = !0, f.setAttribute("aria-busy", "true"), f.textContent = "正在打开…", C.textContent = "";
512
- try {
513
- const s = await this.interaction.perform();
514
- if (w || this.interaction.signal?.aborted) {
515
- s.type !== "completed" && s.cancel();
516
- return;
517
- }
518
- s.type === "frame" ? (p = s, c.dataset.frame = "true", S.src = s.url, S.focus(), await s.completion) : s.type === "external" && (p = s, await s.completion), I("acted");
519
- } catch (s) {
520
- if (w) return;
521
- p?.cancel(), p = null, c.dataset.frame = "false", S.removeAttribute("src"), C.textContent = te(s), f.hidden = !1, f.disabled = !1, f.removeAttribute("aria-busy"), f.textContent = d, f.focus();
522
- }
523
- };
524
- f.addEventListener("click", A), queueMicrotask(() => f.focus());
525
- }
526
- }
527
- customElements.define(K, t);
528
- }
529
- const re = async (t) => {
530
- if (typeof document > "u" || typeof customElements > "u" || t.signal?.aborted) return "dismissed";
531
- ie();
532
- const e = document.createElement(K);
533
- e.interaction = t;
534
- const i = document.documentElement.style.overflow, r = document.activeElement instanceof HTMLElement ? document.activeElement : null;
535
- document.documentElement.style.overflow = "hidden", document.body.append(e);
536
- try {
537
- return await new Promise((c) => {
538
- e.addEventListener(
539
- "viceme:access-layer-close",
540
- (O) => c(O.detail),
541
- { once: !0 }
542
- );
543
- });
544
- } finally {
545
- e.remove(), document.documentElement.style.overflow = i, r?.focus();
546
- }
547
- };
548
- function k(t) {
549
- if (typeof t != "object" || t === null) throw h();
550
- return t;
551
- }
552
- function h() {
553
- return new b({
554
- code: "INTERNAL_ERROR",
555
- message: "Malformed public API response.",
556
- retryable: !0
557
- });
558
- }
559
- function ae(t) {
560
- const e = k(t);
561
- if (typeof e.id != "string" || !(typeof e.displayName == "string" || e.displayName === null) || !(typeof e.avatarUrl == "string" || e.avatarUrl === null))
562
- throw h();
563
- return {
564
- subject: e.id,
565
- nickname: e.displayName,
566
- avatarUrl: e.avatarUrl
567
- };
568
- }
569
- function F(t) {
570
- const e = k(t);
571
- if (typeof e.following != "boolean" || !(typeof e.followedAt == "string" || e.followedAt === null))
572
- throw h();
573
- const i = k(e.creator);
574
- if (typeof i.displayName != "string" || !(typeof i.avatarUrl == "string" || i.avatarUrl === null) || !(typeof i.description == "string" || i.description === null) || !Number.isInteger(i.publishedWorkCount) || i.publishedWorkCount < 0)
575
- throw h();
576
- return {
577
- following: e.following,
578
- followedAt: e.followedAt,
579
- target: {
580
- kind: "CREATOR",
581
- displayName: i.displayName,
582
- avatarUrl: i.avatarUrl,
583
- description: i.description,
584
- workCount: i.publishedWorkCount
585
- }
586
- };
587
- }
588
- function ne(t) {
589
- const e = k(t), i = /* @__PURE__ */ new Set([
590
- "PUBLIC",
591
- "OWNER",
592
- "FOLLOWING",
593
- "ENTITLED",
594
- "AUTH_REQUIRED",
595
- "FOLLOW_REQUIRED",
596
- "PURCHASE_REQUIRED",
597
- "FEATURE_NOT_FOUND",
598
- "FEATURE_DISABLED"
599
- ]), r = /* @__PURE__ */ new Set([null, "SIGN_IN", "FOLLOW", "CHECKOUT"]);
600
- if (typeof e.allowed != "boolean" || typeof e.reason != "string" || !i.has(e.reason) || !r.has(e.nextAction))
601
- throw h();
602
- return {
603
- allowed: e.allowed,
604
- reason: e.reason,
605
- nextAction: e.nextAction
606
- };
607
- }
608
- function oe(t) {
609
- const e = k(t);
610
- if (typeof e.featureKey != "string" || !/^[a-z][a-z0-9_-]{1,63}$/.test(e.featureKey) || typeof e.title != "string" || e.title.trim().length === 0 || e.title.length > 120 || !(e.policyType === "PUBLIC" || e.policyType === "FOLLOW_OWNER" || e.policyType === "WORK_ENTITLEMENT"))
611
- throw h();
612
- const i = e.price === null ? null : k(e.price);
613
- if (i !== null && (!Number.isInteger(i.amountCents) || i.amountCents <= 0 || i.currency !== "CNY") || e.policyType === "WORK_ENTITLEMENT" != (i !== null))
614
- throw h();
615
- return {
616
- featureKey: e.featureKey,
617
- title: e.title,
618
- policy: { type: e.policyType },
619
- price: i === null ? null : { amountCents: i.amountCents, currency: "CNY" }
620
- };
621
- }
622
- function se() {
623
- const t = crypto.getRandomValues(new Uint8Array(32));
624
- return ce(t);
625
- }
626
- function ce(t) {
627
- let e = "";
628
- for (const i of t) e += String.fromCharCode(i);
629
- return btoa(e).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
630
- }
631
- function le() {
632
- return typeof document < "u" && document.documentElement.lang.toLowerCase() === "en-us" ? "en-US" : "zh-CN";
633
- }
634
- function de(t) {
635
- const e = () => new b({
636
- code: "AUTH_CANCELLED",
637
- message: "The interactive action was cancelled.",
638
- retryable: !1
639
- }), i = (n) => {
640
- if (t.signal.aborted) return Promise.reject(v());
641
- let o;
642
- const l = new Promise((d, u) => {
643
- o = () => u(v()), t.signal.addEventListener("abort", o, { once: !0 }), t.signal.aborted && o();
644
- });
645
- let a;
646
- try {
647
- a = (t.presenter ?? re)({
648
- ...n,
649
- signal: t.signal
650
- });
651
- } catch (d) {
652
- a = Promise.reject(d);
653
- }
654
- return Promise.race([a, l]).then((d) => {
655
- if (t.signal.aborted) throw v();
656
- return d;
657
- }).finally(() => {
658
- o && t.signal.removeEventListener("abort", o);
659
- });
660
- }, r = (n, o, l, a, d, u) => {
661
- if (typeof window > "u")
662
- throw new b({
663
- code: "CONFIG_INVALID",
664
- message: "Interactive access requires a browser window.",
665
- retryable: !1
666
- });
667
- let p = !0, w, I;
668
- const y = () => {
669
- p && (p = !1, window.removeEventListener("message", s));
670
- }, A = new Promise((g, m) => {
671
- w = g, I = m;
672
- }), s = (g) => {
673
- if (!p || g.origin !== o || typeof g.data != "object" || g.data === null) return;
674
- const m = g.data;
675
- if (!(m.workKey !== t.workKey || m.channel !== l)) {
676
- if (m.type === `viceme:${a}:ready`) {
677
- g.source && "postMessage" in g.source && g.source.postMessage(
678
- {
679
- type: `viceme:${a}:init`,
680
- workKey: t.workKey,
681
- channel: l,
682
- ...d
683
- },
684
- o
685
- );
686
- return;
687
- }
688
- if (m.type === `viceme:${a}:cancelled`) {
689
- y(), I(e());
690
- return;
691
- }
692
- m.type === `viceme:${a}:complete` && (y(), u(m).then(w, I));
693
- }
694
- };
695
- return window.addEventListener("message", s), {
696
- type: "frame",
697
- url: n,
698
- completion: A,
699
- cancel() {
700
- y(), w();
701
- }
702
- };
703
- }, c = async () => {
704
- if (await t.ready(), typeof window > "u")
705
- throw new b({
706
- code: "CONFIG_INVALID",
707
- message: "Interactive access requires a browser window.",
708
- retryable: !1
709
- });
710
- const n = se(), o = new URL("/sdk/login", t.widgetOrigin);
711
- o.search = new URLSearchParams({
712
- workKey: t.workKey,
713
- channel: n,
714
- parentOrigin: window.location.origin,
715
- locale: le()
716
- }).toString();
717
- const l = t.session.snapshot?.token;
718
- if (!l) throw h();
719
- return r(
720
- o.toString(),
721
- t.widgetOrigin,
722
- n,
723
- "auth",
724
- { workSessionToken: l },
725
- async (a) => {
726
- if (typeof a.userToken != "string")
727
- throw h();
728
- t.session.authenticate({ userToken: a.userToken, user: ae(a.user) });
729
- }
730
- );
731
- }, O = async () => (await t.ready(), F(
732
- (await t.session.request({ method: "GET", path: "/v1/public/work-sdk/follow" })).body
733
- )), f = async () => (await t.ready(), F(
734
- (await t.session.request({ method: "PUT", path: "/v1/public/work-sdk/follow" })).body
735
- )), U = {
736
- async getState() {
737
- await t.ready();
738
- const n = t.session.snapshot?.user ?? null;
739
- return { authenticated: n !== null, user: n };
740
- },
741
- async signIn() {
742
- if (await i({
743
- featureKey: "auth",
744
- reason: "AUTH_REQUIRED",
745
- action: "SIGN_IN",
746
- perform: c
747
- }) === "dismissed") throw e();
748
- return this.getState();
749
- },
750
- async signOut() {
751
- await t.ready(), await t.session.signOut();
752
- }
753
- }, N = {
754
- getState: O,
755
- follow: f,
756
- unfollow: async () => {
757
- throw new b({
758
- code: "CAPABILITY_DISABLED",
759
- message: "Unfollow is not exposed by website access.",
760
- retryable: !1
761
- });
762
- }
763
- }, T = async (n) => {
764
- await t.ready();
765
- const o = k(
766
- (await t.session.request({
767
- method: "POST",
768
- path: "/v1/public/work-sdk/access/check",
769
- body: { featureKeys: n }
770
- })).body
771
- ), l = k(o.decisions);
772
- return Object.fromEntries(
773
- Object.entries(l).map(([a, d]) => [a, ne(d)])
774
- );
775
- }, C = async (n, o = {}) => {
776
- await t.ready();
777
- const l = {
778
- featureKey: n,
779
- locale: o.locale ?? "zh-CN"
780
- }, a = k(
781
- (await t.session.request({
782
- method: "POST",
783
- path: "/v1/public/work-sdk/checkout",
784
- body: l
785
- })).body
786
- );
787
- if (typeof a.checkoutUrl != "string" || typeof a.alreadyOwned != "boolean" || !(a.expiresAt === null || typeof a.expiresAt == "string" && !Number.isNaN(Date.parse(a.expiresAt))) || a.alreadyOwned !== (a.expiresAt === null))
788
- throw h();
789
- let d;
790
- try {
791
- d = new URL(a.checkoutUrl);
792
- } catch {
793
- throw h();
794
- }
795
- if (!a.alreadyOwned && (d.protocol !== "https:" || d.origin !== t.widgetOrigin))
796
- throw h();
797
- return {
798
- checkoutUrl: a.checkoutUrl,
799
- alreadyOwned: a.alreadyOwned,
800
- expiresAt: a.expiresAt
801
- };
802
- }, S = (n, o) => {
803
- if (n.alreadyOwned) return { type: "completed" };
804
- const l = Date.parse(n.expiresAt);
805
- if (typeof window > "u")
806
- throw new b({
807
- code: "CONFIG_INVALID",
808
- message: "Hosted checkout requires a browser window.",
809
- retryable: !1
810
- });
811
- let a = !0, d, u, p, w;
812
- const I = new Promise((E, _) => {
813
- p = E, w = _;
814
- }), y = () => {
815
- d && clearTimeout(d), u && clearTimeout(u), document.removeEventListener("visibilitychange", m);
816
- }, A = () => {
817
- a && (a = !1, y(), w(
818
- new b({
819
- code: "SESSION_EXPIRED",
820
- message: "Hosted checkout session expired.",
821
- retryable: !0
822
- })
823
- ));
824
- }, s = () => {
825
- if (!a || document.visibilityState === "hidden") return;
826
- const E = l - t.now();
827
- if (E <= 0) {
828
- A();
829
- return;
830
- }
831
- d = setTimeout(() => {
832
- g();
833
- }, Math.min(1500, E));
834
- }, g = async () => {
835
- if (a)
836
- try {
837
- const E = (await T([o]))[o];
838
- if (!E) throw h();
839
- if (E.allowed) {
840
- a = !1, y(), p();
841
- return;
842
- }
843
- s();
844
- } catch (E) {
845
- a = !1, y(), w(E);
846
- }
847
- };
848
- function m() {
849
- if (a) {
850
- if (document.visibilityState === "hidden") {
851
- d && clearTimeout(d), d = void 0;
852
- return;
853
- }
854
- s();
855
- }
856
- }
857
- document.addEventListener("visibilitychange", m);
858
- const D = l - t.now();
859
- return D <= 0 ? A() : (u = setTimeout(A, D), s()), {
860
- type: "frame",
861
- url: n.checkoutUrl,
862
- completion: I,
863
- cancel() {
864
- a && (a = !1, y(), p());
865
- }
866
- };
867
- };
868
- return { auth: U, follow: N, access: {
869
- async getFeatures() {
870
- await t.ready();
871
- const n = k(
872
- (await t.session.request({
873
- method: "GET",
874
- path: "/v1/public/work-sdk/access/features"
875
- })).body
876
- );
877
- if (!Array.isArray(n.features) || n.features.length > 100)
878
- throw h();
879
- return n.features.map(oe);
880
- },
881
- async check(n) {
882
- const l = (await T([n]))[n];
883
- if (!l) throw h();
884
- return l;
885
- },
886
- checkMany: T,
887
- async require(n) {
888
- let o = await this.check(n);
889
- for (let l = 0; !o.allowed && o.nextAction && l < 3; l += 1) {
890
- const a = o.nextAction, d = a === "FOLLOW" ? (await N.getState()).target : void 0, u = a === "CHECKOUT" ? await C(n) : void 0;
891
- if (u?.alreadyOwned) {
892
- o = await this.check(n);
893
- continue;
894
- }
895
- if (await i({
896
- featureKey: n,
897
- reason: o.reason,
898
- action: a,
899
- ...d ? { followTarget: d } : {},
900
- perform: async () => a === "SIGN_IN" ? c() : a === "FOLLOW" ? (await N.follow(), { type: "completed" }) : S(u, n)
901
- }) === "dismissed") return o;
902
- o = await this.check(n);
903
- }
904
- return o;
905
- },
906
- async refresh() {
907
- await t.ready();
908
- }
909
- }, checkout: {
910
- async open(n) {
911
- const o = await C(n.featureKey, n);
912
- if (o.alreadyOwned) return o;
913
- if (await i({
914
- featureKey: n.featureKey,
915
- reason: "PURCHASE_REQUIRED",
916
- action: "CHECKOUT",
917
- perform: async () => S(o, n.featureKey)
918
- }) === "dismissed") throw e();
919
- return o;
920
- }
921
- } };
922
- }
923
- class ue extends DOMException {
924
- constructor() {
925
- super("ViceMe client destroyed.", "AbortError");
926
- }
927
- }
928
- class we {
929
- #e = new Q();
930
- #t;
931
- #i;
932
- #r = new AbortController();
933
- #n;
934
- auth;
935
- access;
936
- checkout;
937
- /** Detaches the caller-signal listener; undefined when none was attached. */
938
- #a;
939
- constructor(e) {
940
- this.#i = e.config, this.#t = new Z({
941
- workKey: e.config.workKey,
942
- transport: e.transport,
943
- signal: this.#r.signal,
944
- ...e.now !== void 0 ? { now: e.now } : {}
945
- });
946
- const i = de({
947
- session: this.#t,
948
- workKey: e.config.workKey,
949
- widgetOrigin: j[e.config.region],
950
- now: e.now ?? (() => Date.now()),
951
- presenter: e.presenter,
952
- signal: this.#r.signal,
953
- ready: () => this.#s()
954
- });
955
- this.auth = i.auth, this.access = i.access, this.checkout = i.checkout;
956
- const r = e.config.signal;
957
- if (r) {
958
- const c = () => {
959
- this.#r.abort(
960
- r.reason instanceof Error ? r.reason : new DOMException("Caller signal aborted.", "AbortError")
961
- );
962
- };
963
- r.aborted ? c() : (r.addEventListener("abort", c, { once: !0 }), this.#a = () => {
964
- r.removeEventListener("abort", c);
965
- });
966
- }
967
- }
968
- get version() {
969
- return W;
970
- }
971
- get workKey() {
972
- return this.#i.workKey;
973
- }
974
- get region() {
975
- return this.#i.region;
976
- }
977
- get state() {
978
- return this.#e.state;
979
- }
980
- /** Internal: public API major, used by the loader registry namespace. */
981
- get apiMajor() {
982
- return H;
983
- }
984
- ready() {
985
- return this.#e.destroyed ? Promise.reject(v()) : (this.#n || (this.#e.transition("READY"), this.#n = Promise.resolve()), this.#n);
986
- }
987
- async #s() {
988
- if (this.#e.destroyed) throw v();
989
- await this.ready();
990
- try {
991
- if (await this.#t.establish(), this.#e.destroyed) throw v();
992
- } catch (e) {
993
- throw this.#e.destroyed ? v() : (this.#t.invalidate(), e);
994
- }
995
- }
996
- hasCapability(e) {
997
- if (this.#e.destroyed) return !1;
998
- const i = this.#t.snapshot?.work.capabilities;
999
- return e === "danmaku" || e === "tip" || i?.includes(e) === !0;
1000
- }
1001
- /** Names of capabilities enabled for this work (empty before `ready()`). */
1002
- get capabilities() {
1003
- return this.#t.snapshot?.work.capabilities ?? [];
1004
- }
1005
- /**
1006
- * Internal: mark one capability unavailable without taking down the client
1007
- * (loader uses this when a feature chunk fails after the core is READY).
1008
- */
1009
- markDegraded() {
1010
- this.#e.state === "READY" && this.#e.transition("DEGRADED");
1011
- }
1012
- /** Internal: session snapshot access for capability modules. */
1013
- get sessionSnapshot() {
1014
- return this.#t.snapshot;
1015
- }
1016
- destroy() {
1017
- this.#e.destroyed || (this.#e.transition("DESTROYED"), this.#r.abort(new ue()), this.#t.destroy(), this.#e.clearListeners(), this.#n = void 0, this.#a?.(), this.#a = void 0);
1018
- }
1019
- }
1020
- export {
1021
- we as V,
1022
- Y as a,
1023
- B as i,
1024
- pe as r,
1025
- ye as v
1026
- };
1027
- //# sourceMappingURL=client-DEg6YouY.js.map