@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/README.md CHANGED
@@ -58,7 +58,7 @@ if (!target) throw new Error('ViceMe target missing');
58
58
 
59
59
  const results = await Promise.allSettled([
60
60
  mountDanmaku(client, { target, theme: 'auto' }),
61
- mountTip(client, { target, theme: 'auto' }),
61
+ mountTip(client, { target, theme: 'auto', presentation: 'integrated' }),
62
62
  ]);
63
63
  const mounted = results.flatMap((result) => (result.status === 'fulfilled' ? [result.value] : []));
64
64
 
@@ -68,6 +68,9 @@ client.destroy();
68
68
 
69
69
  Run those cleanup calls from the owning component's unmount path or another
70
70
  explicit lifecycle boundary, not from `pagehide` (which also covers bfcache).
71
+ The integrated presentation uses the danmaku bar as its only visible launcher
72
+ and opens the official Tip dialog. Standalone `mountTip()` remains inline by
73
+ default.
71
74
 
72
75
  `createViceMe` and `ready()` are purely local and never contact Shop. A live client reports
73
76
  build support for `danmaku` and `tip`; Shop remains authoritative for whether a
@@ -83,25 +86,68 @@ is `wrk_live_...`. Other Work key shapes are rejected locally.
83
86
 
84
87
  Access operations establish a short-lived, memory-only Work session on first
85
88
  use. They expose `client.auth`, `client.access`, and `client.checkout`; login,
86
- explicit follow, and hosted checkout remain ViceMe-owned UI. The host never
89
+ buyer recovery, and hosted checkout remain ViceMe-owned UI. The host never
87
90
  receives a general ViceMe session or payment credential. Tests can inject a
88
91
  deterministic transport and presenter through `@viceme-ai/sdk/testing`.
89
92
  Calling `client.destroy()` cancels in-flight access requests, closes the active
90
93
  SDK-owned sign-in or checkout layer, and rejects the interrupted call with
91
94
  `CLIENT_DESTROYED`; late responses cannot restore the in-memory Work token.
95
+ Request cancellation and timeouts remain effective until the parsed response is
96
+ delivered. Cancelling the client's optional `signal` preserves the caller's
97
+ `Error` reason for requests and interactive presentations; a request timeout
98
+ rejects with retryable `NETWORK_TIMEOUT`.
99
+ A cancelled response cannot establish a Work session even if its body has
100
+ already finished parsing.
101
+
102
+ Website Access v3 is negotiated during the first Access session request via
103
+ `supportedAccessProtocolVersions: [3]`. An unversioned server response retains
104
+ the legacy login/follow flow and CNY `amountCents` representation. V3 returns
105
+ CNY or USD `amountMinor` prices and feature `status`; `PENDING_CHANNEL` may have
106
+ no sale price and a non-null `pricingIntent`. The server decides which channels
107
+ are ready. GLOBAL supports access integration and login; missing payment
108
+ channels never fall back to CN or create an order.
109
+
110
+ V3 does not require, bind, or compare host Origin, including null/missing origins.
111
+ Official HTTPS Shop URLs and server-authoritative identity, Work, expiry, and
112
+ entitlement validation remain mandatory. Browser restrictions on Web Crypto,
113
+ frames, navigation, and storage can still require a first-party recovery step.
114
+
115
+ `access.require(featureKey)` handles buyer identification, checkout, and a fresh
116
+ access check. It never grants access from a payment or window message. V3 login
117
+ opens directly from the initiating action; `FOLLOW` executes in that same user
118
+ interaction without another confirmation. Shop owns automatic follow after an
119
+ authenticated login/payment; anonymous purchase skips both login and follow.
120
+
121
+ Optional recovery controls use the same protocol:
92
122
 
93
- The current Website Access release accepts any valid HTTP(S) host Origin and
94
- does not require DNS TXT verification. Session tokens remain bound to the
95
- Origin observed when they were issued, but that Origin is not compared with a
96
- registered allowlist. The hosted checkout iframe likewise has no parent-Origin
97
- `frame-ancestors` restriction; its signed launch context, expiry, official
98
- Shop URL, and server-authoritative entitlement checks remain enforced.
123
+ ```ts
124
+ await client.access.restorePurchase('download'); // Remains anonymous.
125
+ await client.access.claimPurchase('download'); // User explicitly chooses login and claim.
126
+ ```
99
127
 
100
- Website access login renders the work-bound WeChat QR code directly in the SDK
101
- layer. Paid access keeps desktop QR payment and WeChat JSAPI in that layer;
102
- mobile H5/WAP payment may open a provider page or app. The original page polls
103
- the server-authoritative access decision and closes the layer after entitlement
104
- is active. This behavior does not change the separate Tip Widget flow.
128
+ The official page owns purchase receipts, account selection, and claim consent.
129
+ The SDK obtains only a short-lived Work-scoped buyer or user credential through
130
+ PKCE challenge/result/exchange calls. These calls omit cookies. It does not
131
+ accept credentials from postMessage, query strings, or fragments. Explicit
132
+ claim replaces the current anonymous context only after a verified user
133
+ exchange; failed/cancelled claim keeps existing purchase authorization.
134
+
135
+ If an iframe cannot access first-party storage, “在当前页面继续” navigates to the
136
+ official page. Only the challenge, state, verifier, and selected feature/purpose
137
+ are saved in sessionStorage for at most five minutes. After returning, invoking
138
+ the same action or `require()` for the same feature resumes the authorized
139
+ recovery/claim handshake. No buyer/user token, recovery secret,
140
+ or payment result is persisted by the SDK. Unavailable navigation storage is
141
+ reported instead of pretending that a purchase was recovered.
142
+
143
+ Work-session refresh is single-flight and server expiry retries at most once.
144
+ Refreshing a Work session drops user/buyer context; the next authoritative
145
+ check can request recovery again. Logout, identity replacement, and destruction
146
+ invalidate late identity results. Authorization reads that race a session
147
+ change are retried against the current identity; successful mutations are not
148
+ replayed merely because another request refreshed a session. Both explicit
149
+ `destroy()` and caller cancellation stop bridge polling and close the layer;
150
+ the caller's `Error` reason remains intact.
105
151
 
106
152
  ```ts
107
153
  const decisions = await client.access.checkMany(['members', 'pro-tools']);
@@ -120,10 +166,12 @@ scroll bucket, and sends only the opaque anchor to the hosted iframe. Destroying
120
166
  the mount removes its nodes, listeners, debounce timer, and location poll.
121
167
 
122
168
  The Tip mount sends no amount, provider, token, or application ID. It enables
123
- interaction only after a trusted resize handshake. Shop resets its hosted
124
- payment surface on Escape before sending close; the SDK forwards sanitized
125
- close and paid notifications, and removes its iframe, timer, media listener,
126
- and message listener on destroy.
169
+ interaction only after a trusted resize handshake. In integrated mode it also
170
+ accepts open requests only from the matching trusted danmaku controls, then
171
+ restores focus there after close. Shop resets its hosted payment surface on
172
+ Escape before sending close; the SDK forwards sanitized close and paid
173
+ notifications, and removes its iframe, timer, media listener, and message
174
+ listener on destroy.
127
175
 
128
176
  ## Headless Tip
129
177
 
@@ -3,6 +3,8 @@ export interface CapabilityMountOptions {
3
3
  /** Mount host element; the capability owns its Shadow DOM subtree. */
4
4
  target: Element;
5
5
  theme: 'light' | 'dark' | 'auto';
6
+ /** Use the shared danmaku controls as the visible Tip launcher. */
7
+ presentation?: 'inline' | 'integrated';
6
8
  /** Abort a mount that has not completed and destroy it after completion. */
7
9
  signal?: AbortSignal;
8
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"capability-mount.d.ts","sourceRoot":"","sources":["../src/capability-mount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,WAAW,sBAAsB;IACrC,sEAAsE;IACtE,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,4EAA4E;IAC5E,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,+EAA+E;AAC/E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,MAAM,uBAAuB,GAAG,CACpC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,sBAAsB,KAC5B,OAAO,CAAC,qBAAqB,CAAC,CAAC"}
1
+ {"version":3,"file":"capability-mount.d.ts","sourceRoot":"","sources":["../src/capability-mount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,WAAW,sBAAsB;IACrC,sEAAsE;IACtE,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,mEAAmE;IACnE,YAAY,CAAC,EAAE,QAAQ,GAAG,YAAY,CAAC;IACvC,4EAA4E;IAC5E,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,+EAA+E;AAC/E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,MAAM,uBAAuB,GAAG,CACpC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,sBAAsB,KAC5B,OAAO,CAAC,qBAAqB,CAAC,CAAC"}