@monetize.software/sdk-extension 3.0.0-alpha.2 → 3.0.0-alpha.20

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 (156) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -20
  3. package/dist/chunks/ar-7cgIM-Vl.js +2 -0
  4. package/dist/chunks/ar-7cgIM-Vl.js.map +1 -0
  5. package/dist/chunks/ar-B2Wg_IrC.js +126 -0
  6. package/dist/chunks/ar-B2Wg_IrC.js.map +1 -0
  7. package/dist/chunks/chrome-port-BEMjZQAH.js +2 -0
  8. package/dist/chunks/chrome-port-BEMjZQAH.js.map +1 -0
  9. package/dist/chunks/{chrome-port-DPFUj1MP.js → chrome-port-bfTUUDz_.js} +332 -211
  10. package/dist/chunks/chrome-port-bfTUUDz_.js.map +1 -0
  11. package/dist/chunks/cs-BNo9Dx0Q.js +122 -0
  12. package/dist/chunks/cs-BNo9Dx0Q.js.map +1 -0
  13. package/dist/chunks/cs-S05PC5AC.js +2 -0
  14. package/dist/chunks/cs-S05PC5AC.js.map +1 -0
  15. package/dist/chunks/da-Bi4zBG14.js +2 -0
  16. package/dist/chunks/da-Bi4zBG14.js.map +1 -0
  17. package/dist/chunks/da-Do9Lq6En.js +122 -0
  18. package/dist/chunks/da-Do9Lq6En.js.map +1 -0
  19. package/dist/chunks/de-C8pDZNvx.js +141 -0
  20. package/dist/chunks/de-C8pDZNvx.js.map +1 -0
  21. package/dist/chunks/de-nCDB6D2W.js +2 -0
  22. package/dist/chunks/de-nCDB6D2W.js.map +1 -0
  23. package/dist/chunks/el-BrKaa978.js +2 -0
  24. package/dist/chunks/el-BrKaa978.js.map +1 -0
  25. package/dist/chunks/el-DzMNX-_P.js +126 -0
  26. package/dist/chunks/el-DzMNX-_P.js.map +1 -0
  27. package/dist/chunks/es-B-Wtyzrl.js +2 -0
  28. package/dist/chunks/es-B-Wtyzrl.js.map +1 -0
  29. package/dist/chunks/es-YrKt-q4w.js +141 -0
  30. package/dist/chunks/es-YrKt-q4w.js.map +1 -0
  31. package/dist/chunks/fi-Bh44pwZ4.js +122 -0
  32. package/dist/chunks/fi-Bh44pwZ4.js.map +1 -0
  33. package/dist/chunks/fi-D1SGXjnO.js +2 -0
  34. package/dist/chunks/fi-D1SGXjnO.js.map +1 -0
  35. package/dist/chunks/fr-Bc0pw4ws.js +141 -0
  36. package/dist/chunks/fr-Bc0pw4ws.js.map +1 -0
  37. package/dist/chunks/fr-BhYf-iKk.js +2 -0
  38. package/dist/chunks/fr-BhYf-iKk.js.map +1 -0
  39. package/dist/chunks/he-BXAaFv6Y.js +2 -0
  40. package/dist/chunks/he-BXAaFv6Y.js.map +1 -0
  41. package/dist/chunks/he-Bfm-bhe3.js +126 -0
  42. package/dist/chunks/he-Bfm-bhe3.js.map +1 -0
  43. package/dist/chunks/hi-D-O-B9Dn.js +126 -0
  44. package/dist/chunks/hi-D-O-B9Dn.js.map +1 -0
  45. package/dist/chunks/hi-xblDO0O7.js +2 -0
  46. package/dist/chunks/hi-xblDO0O7.js.map +1 -0
  47. package/dist/chunks/hu-CmIuAbLL.js +122 -0
  48. package/dist/chunks/hu-CmIuAbLL.js.map +1 -0
  49. package/dist/chunks/hu-Wa46p0y4.js +2 -0
  50. package/dist/chunks/hu-Wa46p0y4.js.map +1 -0
  51. package/dist/chunks/id-CQEo5X94.js +2 -0
  52. package/dist/chunks/id-CQEo5X94.js.map +1 -0
  53. package/dist/chunks/id-DN7IES-A.js +122 -0
  54. package/dist/chunks/id-DN7IES-A.js.map +1 -0
  55. package/dist/chunks/it-8AYCm0xz.js +2 -0
  56. package/dist/chunks/it-8AYCm0xz.js.map +1 -0
  57. package/dist/chunks/it-Cz5Nmqx5.js +141 -0
  58. package/dist/chunks/it-Cz5Nmqx5.js.map +1 -0
  59. package/dist/chunks/ja-BH9BlBh2.js +145 -0
  60. package/dist/chunks/ja-BH9BlBh2.js.map +1 -0
  61. package/dist/chunks/ja-q-COVayn.js +2 -0
  62. package/dist/chunks/ja-q-COVayn.js.map +1 -0
  63. package/dist/chunks/ko-B6HRCscZ.js +2 -0
  64. package/dist/chunks/ko-B6HRCscZ.js.map +1 -0
  65. package/dist/chunks/ko-CYV9QuYs.js +145 -0
  66. package/dist/chunks/ko-CYV9QuYs.js.map +1 -0
  67. package/dist/chunks/nl-BvkB900D.js +141 -0
  68. package/dist/chunks/nl-BvkB900D.js.map +1 -0
  69. package/dist/chunks/nl-CAd6_xlm.js +2 -0
  70. package/dist/chunks/nl-CAd6_xlm.js.map +1 -0
  71. package/dist/chunks/no-3s9_ormb.js +122 -0
  72. package/dist/chunks/no-3s9_ormb.js.map +1 -0
  73. package/dist/chunks/no-CAmz6bz6.js +2 -0
  74. package/dist/chunks/no-CAmz6bz6.js.map +1 -0
  75. package/dist/chunks/pl-C9WTGQtb.js +122 -0
  76. package/dist/chunks/pl-C9WTGQtb.js.map +1 -0
  77. package/dist/chunks/pl-DqUSTCaF.js +2 -0
  78. package/dist/chunks/pl-DqUSTCaF.js.map +1 -0
  79. package/dist/chunks/port-name-CF4WQQ3-.js +2 -0
  80. package/dist/chunks/port-name-CF4WQQ3-.js.map +1 -0
  81. package/dist/chunks/port-name-ervLBWAQ.js +6 -0
  82. package/dist/chunks/port-name-ervLBWAQ.js.map +1 -0
  83. package/dist/chunks/pt-8ARZnH0_.js +2 -0
  84. package/dist/chunks/pt-8ARZnH0_.js.map +1 -0
  85. package/dist/chunks/pt-uFVUv_Op.js +141 -0
  86. package/dist/chunks/pt-uFVUv_Op.js.map +1 -0
  87. package/dist/chunks/ro-BrqQ8Au-.js +122 -0
  88. package/dist/chunks/ro-BrqQ8Au-.js.map +1 -0
  89. package/dist/chunks/ro-D-NMbp2F.js +2 -0
  90. package/dist/chunks/ro-D-NMbp2F.js.map +1 -0
  91. package/dist/chunks/ru-8gbHPh0g.js +2 -0
  92. package/dist/chunks/ru-8gbHPh0g.js.map +1 -0
  93. package/dist/chunks/ru-DK594dA8.js +144 -0
  94. package/dist/chunks/ru-DK594dA8.js.map +1 -0
  95. package/dist/chunks/sv-CHNH8-mq.js +122 -0
  96. package/dist/chunks/sv-CHNH8-mq.js.map +1 -0
  97. package/dist/chunks/sv-D8a8hmx9.js +2 -0
  98. package/dist/chunks/sv-D8a8hmx9.js.map +1 -0
  99. package/dist/chunks/th-DfjUK0Y7.js +2 -0
  100. package/dist/chunks/th-DfjUK0Y7.js.map +1 -0
  101. package/dist/chunks/th-l24Pm5q-.js +126 -0
  102. package/dist/chunks/th-l24Pm5q-.js.map +1 -0
  103. package/dist/chunks/tr-ADpigSY5.js +122 -0
  104. package/dist/chunks/tr-ADpigSY5.js.map +1 -0
  105. package/dist/chunks/tr-BdBpz4tL.js +2 -0
  106. package/dist/chunks/tr-BdBpz4tL.js.map +1 -0
  107. package/dist/chunks/uk-CGqo4jek.js +144 -0
  108. package/dist/chunks/uk-CGqo4jek.js.map +1 -0
  109. package/dist/chunks/uk-Cx1zv1ao.js +2 -0
  110. package/dist/chunks/uk-Cx1zv1ao.js.map +1 -0
  111. package/dist/chunks/vi-Dk9bTu6f.js +122 -0
  112. package/dist/chunks/vi-Dk9bTu6f.js.map +1 -0
  113. package/dist/chunks/vi-oe2dW21I.js +2 -0
  114. package/dist/chunks/vi-oe2dW21I.js.map +1 -0
  115. package/dist/chunks/zh-CwczPMPp.js +2 -0
  116. package/dist/chunks/zh-CwczPMPp.js.map +1 -0
  117. package/dist/chunks/zh-LDkEV2D9.js +145 -0
  118. package/dist/chunks/zh-LDkEV2D9.js.map +1 -0
  119. package/dist/content/PaywallUI.d.ts +1 -1
  120. package/dist/content/RemoteAuthClient.d.ts +8 -4
  121. package/dist/content/RemoteAuthClient.d.ts.map +1 -1
  122. package/dist/content/RemoteAuthClient.test-d.d.ts +2 -0
  123. package/dist/content/RemoteAuthClient.test-d.d.ts.map +1 -0
  124. package/dist/content/RemoteBillingClient.d.ts +36 -3
  125. package/dist/content/RemoteBillingClient.d.ts.map +1 -1
  126. package/dist/content/RemoteBillingClient.test-d.d.ts +2 -0
  127. package/dist/content/RemoteBillingClient.test-d.d.ts.map +1 -0
  128. package/dist/content/RemoteTrialStore.d.ts +2 -2
  129. package/dist/content.cjs +3 -3
  130. package/dist/content.cjs.map +1 -1
  131. package/dist/content.js +2441 -1059
  132. package/dist/content.js.map +1 -1
  133. package/dist/offscreen/server.d.ts +3 -3
  134. package/dist/offscreen/server.d.ts.map +1 -1
  135. package/dist/offscreen.cjs +1 -1
  136. package/dist/offscreen.cjs.map +1 -1
  137. package/dist/offscreen.js +18 -15
  138. package/dist/offscreen.js.map +1 -1
  139. package/dist/shared/messages.d.ts +28 -5
  140. package/dist/shared/messages.d.ts.map +1 -1
  141. package/dist/shared/port-name.d.ts +1 -0
  142. package/dist/shared/port-name.d.ts.map +1 -1
  143. package/dist/shared/protocol.d.ts +1 -1
  144. package/dist/shared/protocol.d.ts.map +1 -1
  145. package/dist/sw.cjs +1 -1
  146. package/dist/sw.cjs.map +1 -1
  147. package/dist/sw.js +14 -14
  148. package/dist/sw.js.map +1 -1
  149. package/package.json +39 -21
  150. package/dist/chunks/chrome-port-DPFUj1MP.js.map +0 -1
  151. package/dist/chunks/chrome-port-MoMohiHB.js +0 -2
  152. package/dist/chunks/chrome-port-MoMohiHB.js.map +0 -1
  153. package/dist/chunks/port-name-BPfQKtdb.js +0 -5
  154. package/dist/chunks/port-name-BPfQKtdb.js.map +0 -1
  155. package/dist/chunks/port-name-qwB109u9.js +0 -2
  156. package/dist/chunks/port-name-qwB109u9.js.map +0 -1
@@ -1,6 +1,6 @@
1
- import { BillingClient } from '../../../sdk/src/core/BillingClient';
2
- import { AuthClient } from '../../../sdk/src/core/auth';
3
- import { EventTracker } from '../../../sdk/src/core/EventTracker';
1
+ import { BillingClient } from '@monetize.software/sdk';
2
+ import { AuthClient } from '@monetize.software/sdk';
3
+ import { EventTracker } from '@monetize.software/sdk';
4
4
  import { OffscreenServerOptions } from './index';
5
5
  export declare class OffscreenServer {
6
6
  readonly billing: BillingClient;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/offscreen/server.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAKtD,qBAAa,eAAe;IAC1B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,SAAS,CAAC;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,eAAe,CAAsD;IAC7E,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,SAAS,CAA6B;gBAElC,IAAI,EAAE,sBAAsB;IAsBxC,OAAO,CAAC,uBAAuB;IAM/B,OAAO,CAAC,uBAAuB;IAuE/B;4EACwE;IACxE,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,oBAAoB;IA+C5B,OAAO,CAAC,gBAAgB;IAgBxB,oDAAoD;IACpD,KAAK,IAAI,IAAI;IASb,IAAI,IAAI,IAAI;CAab"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/offscreen/server.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAKtD,qBAAa,eAAe;IAC1B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,SAAS,CAAC;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,eAAe,CAAsD;IAC7E,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,SAAS,CAA6B;gBAElC,IAAI,EAAE,sBAAsB;IAsBxC,OAAO,CAAC,uBAAuB;IAM/B,OAAO,CAAC,uBAAuB;IA2E/B;4EACwE;IACxE,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,oBAAoB;IAgD5B,OAAO,CAAC,gBAAgB;IAsBxB,oDAAoD;IACpD,KAAK,IAAI,IAAI;IAiBb,IAAI,IAAI,IAAI;CAab"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./chunks/chrome-port-MoMohiHB.js"),d=require("./chunks/port-name-qwB109u9.js");class u{constructor(){this.handlers=new Map,this.channels=new Set,this.active=new WeakMap,this.on("handshake",()=>({protocolVersion:r.PROTOCOL_VERSION,offscreenReady:!0}))}on(e,t){this.handlers.set(e,t)}off(e){this.handlers.delete(e)}accept(e){this.channels.add(e),this.active.set(e,new Map),e.onMessage(t=>this.dispatch(e,t)),e.onDisconnect(()=>{this.channels.delete(e);const t=this.active.get(e);if(t)for(const s of t.values())s.abort();this.active.delete(e)})}broadcast(e,t){const s={type:"event",kind:e,payload:t};for(const i of this.channels)try{i.send(s)}catch(l){console.error("[sdk-extension] broadcast send failed",l)}}get connectionCount(){return this.channels.size}async dispatch(e,t){if(p(t)){const a=this.active.get(e),h=a?.get(t.id);h&&(h.abort(),a.delete(t.id));return}if(!g(t))return;const s=this.handlers.get(t.kind);if(!s){this.respondErr(e,t.id,new Error(`Unknown request kind: ${t.kind}`));return}const i=new AbortController,l=this.active.get(e);l?.set(t.id,i);try{const a=await s(t.params,{signal:i.signal});this.respondOk(e,t.id,a)}catch(a){this.respondErr(e,t.id,a)}finally{l?.delete(t.id)}}respondOk(e,t,s){try{e.send({type:"response",id:t,ok:!0,result:s})}catch(i){console.error("[sdk-extension] respond send failed",i)}}respondErr(e,t,s){try{e.send({type:"response",id:t,ok:!1,error:r.serializeError(s)})}catch(i){console.error("[sdk-extension] respond err send failed",i)}}}function g(n){return typeof n!="object"||n===null?!1:n.type==="request"}function p(n){return typeof n!="object"||n===null?!1:n.type==="cancel"}class f{constructor(e){this.transport=new u,this.connectListener=null,this.userUnsub=null,this.balanceUnsub=null,this.authUnsub=null,e.auth&&(this.auth=new r.AuthClient({paywallId:e.paywallId,apiOrigin:e.apiOrigin})),this.billing=new r.BillingClient({paywallId:e.paywallId,apiOrigin:e.apiOrigin,auth:this.auth}),this.tracker=y(e,this.billing),this.registerBillingHandlers(),this.auth&&this.registerAuthHandlers(this.auth),this.tracker&&this.registerTrackerHandlers(this.tracker),this.bridgeBroadcasts()}registerTrackerHandlers(e){this.transport.on("tracker.track",t=>{e.track(t.name,t.props)})}registerBillingHandlers(){this.transport.on("billing.bootstrap",async(t,s)=>this.billing.bootstrap({force:t.force,signal:s.signal})),this.transport.on("billing.getCachedBootstrap",()=>this.billing.getCachedBootstrap()),this.transport.on("billing.getVisitorId",async()=>this.billing.getVisitorId()),this.transport.on("billing.getUser",async(t,s)=>this.billing.getUser({force:t.force,signal:s.signal})),this.transport.on("billing.getCachedUser",()=>this.billing.getCachedUser()),this.transport.on("billing.getBalances",async(t,s)=>this.billing.getBalances({force:t.force,signal:s.signal})),this.transport.on("billing.getCachedBalances",()=>this.billing.getCachedBalances()),this.transport.on("billing.createCheckout",async(t,s)=>this.billing.createCheckout({...t,signal:s.signal})),this.transport.on("billing.listPurchases",async(t,s)=>this.billing.listPurchases({signal:s.signal})),this.transport.on("billing.cancelSubscription",async(t,s)=>this.billing.cancelSubscription({...t,signal:s.signal})),this.transport.on("billing.getIdentity",()=>this.billing.getIdentity()??null),this.transport.on("billing.setIdentity",t=>{this.billing.setIdentity(t.identity??void 0)});const e=this.billing.getStorage();this.transport.on("storage.get",async t=>e.getItem(t.key)),this.transport.on("storage.set",async t=>{await e.setItem(t.key,t.value)}),this.transport.on("storage.remove",async t=>{await e.removeItem(t.key)}),this.transport.on("trial.check",async t=>c(t.paywallId,()=>this.makeTrialStore(t.paywallId,t.config).check())),this.transport.on("trial.recordBlock",async t=>c(t.paywallId,()=>this.makeTrialStore(t.paywallId,t.config).recordBlock())),this.transport.on("trial.reset",async t=>c(t.paywallId,()=>this.makeTrialStore(t.paywallId,t.config).reset()))}makeTrialStore(e,t){return r.createTrialStore(this.billing.getStorage(),e,t)}registerAuthHandlers(e){this.transport.on("auth.signInWithEmail",async t=>e.signInWithEmail(t)),this.transport.on("auth.signUp",async t=>e.signUp(t)),this.transport.on("auth.signOut",async()=>e.signOut()),this.transport.on("auth.refresh",async()=>e.refresh()),this.transport.on("auth.getCachedSession",()=>e.getCachedSession()),this.transport.on("auth.requestPasswordReset",async t=>e.requestPasswordReset(t)),this.transport.on("auth.updatePassword",async t=>e.updatePassword(t)),this.transport.on("auth.sendOtp",async t=>e.sendOtp(t)),this.transport.on("auth.verifyOtp",async t=>e.verifyOtp(t)),this.transport.on("auth.resendConfirmation",async t=>e.resendConfirmation(t)),this.transport.on("auth.revokeAllSessions",async()=>e.revokeAllSessions()),this.transport.on("auth.oauthStart",async t=>{const{authorize_url:s,state:i}=await e.startOAuthFlow({provider:t.provider,scopes:t.scopes,userMeta:t.userMeta});return{authorizeUrl:s,state:i}}),this.transport.on("auth.oauthExchange",async t=>e.completeOAuthFlow({state:t.state,code:t.code})),this.transport.on("auth.getAccessToken",async()=>e.getAccessToken()),this.transport.on("auth.signInAnonymously",async t=>e.signInAnonymously({captchaToken:t.captchaToken,userMeta:t.userMeta,forceCaptcha:t.forceCaptcha}))}bridgeBroadcasts(){this.userUnsub=this.billing.onUserChange(e=>this.transport.broadcast("userChange",e),{immediate:"none"}),this.balanceUnsub=this.billing.onBalanceChange(e=>this.transport.broadcast("balancesChange",e),{immediate:"none"}),this.auth&&(this.authUnsub=this.auth.onAuthChange(e=>this.transport.broadcast("authChange",e)))}start(){this.connectListener||(this.connectListener=e=>{e.name===d.PORT_NAME&&this.transport.accept(r.portToChannel(e))},chrome.runtime.onConnect.addListener(this.connectListener))}stop(){this.connectListener&&(chrome.runtime.onConnect.removeListener(this.connectListener),this.connectListener=null),this.userUnsub?.(),this.balanceUnsub?.(),this.authUnsub?.(),this.userUnsub=null,this.balanceUnsub=null,this.authUnsub=null,this.tracker?.destroy()}}async function c(n,e){return typeof navigator<"u"&&navigator.locks?.request?navigator.locks.request(`@monetize.software/sdk-extension:trial:${n}`,e):e()}function y(n,e){if(n.analytics===!1)return;const t=typeof n.analytics=="object"&&n.analytics!==null?n.analytics:{},s=t.endpoint??`${e.apiOrigin}/api/v1/paywall/${e.paywallId}/events`;return new r.EventTracker({endpoint:s,paywallId:e.paywallId,capabilities:e.capabilities,getVisitorId:()=>e.getVisitorId(),getCachedVisitorId:()=>e.getCachedVisitorId(),getUserId:()=>e.getIdentity()?.userId??null,flushIntervalMs:t.flushIntervalMs,maxBufferSize:t.maxBufferSize})}let o=null;function b(n){if(typeof chrome>"u"||!chrome.runtime)throw new Error("@monetize.software/sdk-extension/offscreen requires chrome.runtime");return o||(o=new f(n),o.start(),o)}exports.startOffscreenServer=b;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./chunks/chrome-port-BEMjZQAH.js"),d=require("./chunks/port-name-CF4WQQ3-.js");class g{constructor(){this.handlers=new Map,this.channels=new Set,this.active=new WeakMap,this.on("handshake",()=>({protocolVersion:r.PROTOCOL_VERSION,offscreenReady:!0}))}on(e,t){this.handlers.set(e,t)}off(e){this.handlers.delete(e)}accept(e){this.channels.add(e),this.active.set(e,new Map),e.onMessage(t=>this.dispatch(e,t)),e.onDisconnect(()=>{this.channels.delete(e);const t=this.active.get(e);if(t)for(const s of t.values())s.abort();this.active.delete(e)})}broadcast(e,t){const s={type:"event",kind:e,payload:t};for(const i of this.channels)try{i.send(s)}catch(l){console.error("[sdk-extension] broadcast send failed",l)}}get connectionCount(){return this.channels.size}async dispatch(e,t){if(p(t)){const a=this.active.get(e),h=a?.get(t.id);h&&(h.abort(),a.delete(t.id));return}if(!u(t))return;const s=this.handlers.get(t.kind);if(!s){this.respondErr(e,t.id,new Error(`Unknown request kind: ${t.kind}`));return}const i=new AbortController,l=this.active.get(e);l?.set(t.id,i);try{const a=await s(t.params,{signal:i.signal});this.respondOk(e,t.id,a)}catch(a){this.respondErr(e,t.id,a)}finally{l?.delete(t.id)}}respondOk(e,t,s){try{e.send({type:"response",id:t,ok:!0,result:s})}catch(i){console.error("[sdk-extension] respond send failed",i)}}respondErr(e,t,s){try{e.send({type:"response",id:t,ok:!1,error:r.serializeError(s)})}catch(i){console.error("[sdk-extension] respond err send failed",i)}}}function u(n){return typeof n!="object"||n===null?!1:n.type==="request"}function p(n){return typeof n!="object"||n===null?!1:n.type==="cancel"}class y{constructor(e){this.transport=new g,this.connectListener=null,this.userUnsub=null,this.balanceUnsub=null,this.authUnsub=null,e.auth&&(this.auth=new r.AuthClient({paywallId:e.paywallId,apiOrigin:e.apiOrigin})),this.billing=new r.BillingClient({paywallId:e.paywallId,apiOrigin:e.apiOrigin,auth:this.auth}),this.tracker=f(e,this.billing),this.registerBillingHandlers(),this.auth&&this.registerAuthHandlers(this.auth),this.tracker&&this.registerTrackerHandlers(this.tracker),this.bridgeBroadcasts()}registerTrackerHandlers(e){this.transport.on("tracker.track",t=>{e.track(t.name,t.props)})}registerBillingHandlers(){this.transport.on("billing.bootstrap",async(t,s)=>this.billing.bootstrap({force:t.force,signal:s.signal})),this.transport.on("billing.getCachedBootstrap",()=>this.billing.getCachedBootstrap()),this.transport.on("billing.getVisitorId",async()=>this.billing.getVisitorId()),this.transport.on("billing.getUser",async(t,s)=>this.billing.getUser({force:t.force,signal:s.signal})),this.transport.on("billing.getCachedUser",()=>this.billing.getCachedUser()),this.transport.on("billing.getBalances",async(t,s)=>this.billing.getBalances({force:t.force,signal:s.signal})),this.transport.on("billing.getCachedBalances",()=>this.billing.getCachedBalances()),this.transport.on("billing.createCheckout",async(t,s)=>this.billing.createCheckout({...t,signal:s.signal})),this.transport.on("billing.listPurchases",async(t,s)=>this.billing.listPurchases({signal:s.signal})),this.transport.on("billing.cancelSubscription",async(t,s)=>this.billing.cancelSubscription({...t,signal:s.signal})),this.transport.on("billing.createSupportTicket",async t=>this.billing.createSupportTicket(t)),this.transport.on("billing.getIdentity",()=>this.billing.getIdentity()??null),this.transport.on("billing.setIdentity",t=>{this.billing.setIdentity(t.identity??void 0)});const e=this.billing.getStorage();this.transport.on("storage.get",async t=>e.getItem(t.key)),this.transport.on("storage.set",async t=>{await e.setItem(t.key,t.value)}),this.transport.on("storage.remove",async t=>{await e.removeItem(t.key)}),this.transport.on("trial.check",async t=>c(t.paywallId,()=>this.makeTrialStore(t.paywallId,t.config).check())),this.transport.on("trial.recordBlock",async t=>c(t.paywallId,()=>this.makeTrialStore(t.paywallId,t.config).recordBlock())),this.transport.on("trial.reset",async t=>c(t.paywallId,()=>this.makeTrialStore(t.paywallId,t.config).reset()))}makeTrialStore(e,t){return r.createTrialStore(this.billing.getStorage(),e,t)}registerAuthHandlers(e){this.transport.on("auth.signInWithEmail",async t=>e.signInWithEmail(t)),this.transport.on("auth.signUp",async t=>e.signUp(t)),this.transport.on("auth.signOut",async()=>e.signOut()),this.transport.on("auth.refresh",async()=>e.refresh()),this.transport.on("auth.getCachedSession",()=>e.getCachedSession()),this.transport.on("auth.requestPasswordReset",async t=>e.requestPasswordReset(t)),this.transport.on("auth.updatePassword",async t=>e.updatePassword(t)),this.transport.on("auth.sendOtp",async t=>e.sendOtp(t)),this.transport.on("auth.verifyOtp",async t=>e.verifyOtp(t)),this.transport.on("auth.resendConfirmation",async t=>e.resendConfirmation(t)),this.transport.on("auth.revokeAllSessions",async()=>e.revokeAllSessions()),this.transport.on("auth.getLastLogin",async()=>e.getLastLogin()),this.transport.on("auth.oauthStart",async t=>{const{authorize_url:s,state:i}=await e.startOAuthFlow({provider:t.provider,scopes:t.scopes,userMeta:t.userMeta});return{authorizeUrl:s,state:i}}),this.transport.on("auth.oauthExchange",async t=>e.completeOAuthFlow({state:t.state,code:t.code})),this.transport.on("auth.getAccessToken",async()=>e.getAccessToken()),this.transport.on("auth.signInAnonymously",async t=>e.signInAnonymously({captchaToken:t.captchaToken,userMeta:t.userMeta,forceNewAnon:t.forceNewAnon}))}bridgeBroadcasts(){this.userUnsub=this.billing.onUserChange(e=>this.transport.broadcast("userChange",e),{immediate:"none"}),this.balanceUnsub=this.billing.onBalanceChange(e=>this.transport.broadcast("balancesChange",e),{immediate:"none"}),this.auth&&(this.authUnsub=this.auth.onAuthChange((e,t)=>{e!=="INITIAL_SESSION"&&this.transport.broadcast("authChange",{event:e,session:t})}))}start(){this.connectListener||(this.connectListener=e=>{e.name===d.RELAY_PORT_NAME&&this.transport.accept(r.portToChannel(e))},chrome.runtime.onConnect.addListener(this.connectListener))}stop(){this.connectListener&&(chrome.runtime.onConnect.removeListener(this.connectListener),this.connectListener=null),this.userUnsub?.(),this.balanceUnsub?.(),this.authUnsub?.(),this.userUnsub=null,this.balanceUnsub=null,this.authUnsub=null,this.tracker?.destroy()}}async function c(n,e){return typeof navigator<"u"&&navigator.locks?.request?navigator.locks.request(`@monetize.software/sdk-extension:trial:${n}`,e):e()}function f(n,e){if(n.analytics===!1)return;const t=typeof n.analytics=="object"&&n.analytics!==null?n.analytics:{},s=t.endpoint??`${e.apiOrigin}/api/v1/paywall/${e.paywallId}/events`;return new r.EventTracker({endpoint:s,paywallId:e.paywallId,capabilities:e.capabilities,getVisitorId:()=>e.getVisitorId(),getCachedVisitorId:()=>e.getCachedVisitorId(),getUserId:()=>e.getIdentity()?.userId??null,flushIntervalMs:t.flushIntervalMs,maxBufferSize:t.maxBufferSize})}let o=null;function b(n){if(typeof chrome>"u"||!chrome.runtime)throw new Error("@monetize.software/sdk-extension/offscreen requires chrome.runtime");return o||(o=new y(n),o.start(),o)}exports.startOffscreenServer=b;
2
2
  //# sourceMappingURL=offscreen.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"offscreen.cjs","sources":["../src/shared/transport-server.ts","../src/offscreen/server.ts","../src/offscreen/index.ts"],"sourcesContent":["// Server-side транспорт. Один TransportServer слушает все каналы, которые\n// подключаются. В extension'е это offscreen, к которому SW проксирует\n// content-script'ы (один offscreen ↔ N каналов от SW, по одному на content).\n//\n// Контракт:\n// - on<K>(kind, handler) — регистрирует handler для request-типа. Один\n// handler на kind (overrideStatic диспатч): если переопределили — последний\n// выигрывает. Throw'ы ловятся и сериализуются в ResponseErr.\n// - broadcast<K>(kind, payload) — fan-out на все живые каналы. Используется\n// BillingClient'ом / AuthClient'ом, когда состояние меняется.\n// - accept(channel) — добавить канал в активный пул. Не делаем listenTo'у на\n// chrome.runtime.onConnect внутри shared-кода, чтобы тестировать без\n// chrome.* — это делает extension-side adapter (offscreen/sw).\n\nimport type {\n CancelEnvelope,\n EventEnvelope,\n EventKind,\n EventPayload,\n RequestEnvelope,\n RequestKind,\n RequestParams,\n RequestResult\n} from './protocol';\nimport { PROTOCOL_VERSION } from './protocol';\nimport { serializeError } from './errors';\nimport type { MessageChannel } from './channel';\n\nexport interface RequestContext {\n /** AbortSignal, который тригернётся при получении cancel-envelope от клиента.\n * Handler может пробросить его в underlying fetch для отмены сетевой\n * операции. Игнорировать тоже OK — старые handler'ы продолжат работать. */\n signal: AbortSignal;\n}\n\nexport type RequestHandler<K extends RequestKind> = (\n params: RequestParams<K>,\n ctx: RequestContext\n) => Promise<RequestResult<K>> | RequestResult<K>;\n\nexport class TransportServer {\n private handlers = new Map<RequestKind, RequestHandler<RequestKind>>();\n private channels = new Set<MessageChannel>();\n /** Активные запросы по каналам: channel → id → AbortController. На cancel\n * envelope ищем controller и abort'им его. На disconnect — abort всех. */\n private active = new WeakMap<MessageChannel, Map<string, AbortController>>();\n\n constructor() {\n // Built-in handshake handler — отвечает текущей версией протокола.\n // Клиент логирует mismatch на стороне TransportClient.ensureChannel,\n // не блокируем дальнейшие запросы (best-effort версионирование).\n this.on('handshake', () => ({\n protocolVersion: PROTOCOL_VERSION,\n offscreenReady: true\n }));\n }\n\n on<K extends RequestKind>(kind: K, handler: RequestHandler<K>): void {\n this.handlers.set(kind, handler as RequestHandler<RequestKind>);\n }\n\n off<K extends RequestKind>(kind: K): void {\n this.handlers.delete(kind);\n }\n\n /** Подключить канал. Сервер начинает обрабатывать запросы из него и\n * включает его в broadcast'ы. На disconnect автоматически удаляет +\n * abort'ит все in-flight handlers для этого канала. */\n accept(channel: MessageChannel): void {\n this.channels.add(channel);\n this.active.set(channel, new Map());\n channel.onMessage((env) => this.dispatch(channel, env));\n channel.onDisconnect(() => {\n this.channels.delete(channel);\n const inFlight = this.active.get(channel);\n if (inFlight) {\n for (const ctrl of inFlight.values()) ctrl.abort();\n }\n this.active.delete(channel);\n });\n }\n\n /** Fan-out события всем подключённым каналам. */\n broadcast<K extends EventKind>(kind: K, payload: EventPayload<K>): void {\n const envelope: EventEnvelope<EventPayload<K>> = { type: 'event', kind, payload };\n for (const channel of this.channels) {\n try {\n channel.send(envelope);\n } catch (e) {\n console.error('[sdk-extension] broadcast send failed', e);\n }\n }\n }\n\n /** Размер активного пула — для health-check / cleanup'а offscreen'а\n * (если 0, host может закрыть offscreen-документ). */\n get connectionCount(): number {\n return this.channels.size;\n }\n\n private async dispatch(channel: MessageChannel, raw: unknown): Promise<void> {\n if (isCancel(raw)) {\n const inFlight = this.active.get(channel);\n const ctrl = inFlight?.get(raw.id);\n if (ctrl) {\n ctrl.abort();\n inFlight!.delete(raw.id);\n }\n return;\n }\n if (!isRequest(raw)) return;\n const handler = this.handlers.get(raw.kind);\n if (!handler) {\n this.respondErr(channel, raw.id, new Error(`Unknown request kind: ${raw.kind}`));\n return;\n }\n const ctrl = new AbortController();\n const inFlight = this.active.get(channel);\n inFlight?.set(raw.id, ctrl);\n try {\n const result = await handler(raw.params as RequestParams<RequestKind>, {\n signal: ctrl.signal\n });\n this.respondOk(channel, raw.id, result);\n } catch (e) {\n // Если handler завершился через abort — клиент уже знает (он сам и\n // отменял). Респонс ошибки всё равно шлём; client-side pending уже\n // очищен, ничего не произойдёт. Безопаснее, чем пропустить response.\n this.respondErr(channel, raw.id, e);\n } finally {\n inFlight?.delete(raw.id);\n }\n }\n\n private respondOk(channel: MessageChannel, id: string, result: unknown): void {\n try {\n channel.send({ type: 'response', id, ok: true, result });\n } catch (e) {\n console.error('[sdk-extension] respond send failed', e);\n }\n }\n\n private respondErr(channel: MessageChannel, id: string, error: unknown): void {\n try {\n channel.send({ type: 'response', id, ok: false, error: serializeError(error) });\n } catch (e) {\n console.error('[sdk-extension] respond err send failed', e);\n }\n }\n}\n\nfunction isRequest(value: unknown): value is RequestEnvelope {\n if (typeof value !== 'object' || value === null) return false;\n return (value as { type?: unknown }).type === 'request';\n}\n\nfunction isCancel(value: unknown): value is CancelEnvelope {\n if (typeof value !== 'object' || value === null) return false;\n return (value as { type?: unknown }).type === 'cancel';\n}\n","// Offscreen-side server. Owns the real BillingClient + AuthClient (если\n// включён) — единственный source of truth для всего расширения. Регистрирует\n// handler'ы на TransportServer'е, принимает port'ы от SW через\n// chrome.runtime.onConnect, broadcast'ит userChange/authChange/balancesChange\n// при изменении состояния.\n//\n// Жизненный цикл: server создаётся один раз через startOffscreenServer().\n// Если SW рестартует — он пере-create'ит offscreen (если документ умер) или\n// откроет новый port (если документ жив). Server в обоих случаях accept'ит\n// новый канал, state переживает.\n//\n// OAuth flows. PKCE verifier хранится в offscreen'е между oauthStart и\n// oauthExchange request'ами. Content только открывает popup и ждёт code'а\n// (нативно, в своём frame'е) — verifier через runtime-границу не уходит.\n\nimport { BillingClient } from '@sdk/core/BillingClient';\nimport { AuthClient } from '@sdk/core/auth';\nimport { EventTracker } from '@sdk/core/EventTracker';\nimport { createTrialStore } from '@sdk/core/trial';\nimport type { TrialConfig } from '@sdk/core/types';\nimport type { OffscreenServerOptions } from './index';\nimport { TransportServer } from '../shared/transport-server';\nimport { portToChannel } from '../shared/chrome-port';\nimport { PORT_NAME } from '../shared/port-name';\n\nexport class OffscreenServer {\n readonly billing: BillingClient;\n readonly auth: AuthClient | undefined;\n readonly tracker: EventTracker | undefined;\n private readonly transport = new TransportServer();\n private connectListener: ((port: chrome.runtime.Port) => void) | null = null;\n private userUnsub: (() => void) | null = null;\n private balanceUnsub: (() => void) | null = null;\n private authUnsub: (() => void) | null = null;\n\n constructor(opts: OffscreenServerOptions) {\n if (opts.auth) {\n this.auth = new AuthClient({\n paywallId: opts.paywallId,\n apiOrigin: opts.apiOrigin\n });\n }\n\n this.billing = new BillingClient({\n paywallId: opts.paywallId,\n apiOrigin: opts.apiOrigin,\n auth: this.auth\n });\n\n this.tracker = createTrackerIfEnabled(opts, this.billing);\n\n this.registerBillingHandlers();\n if (this.auth) this.registerAuthHandlers(this.auth);\n if (this.tracker) this.registerTrackerHandlers(this.tracker);\n this.bridgeBroadcasts();\n }\n\n private registerTrackerHandlers(tracker: EventTracker): void {\n this.transport.on('tracker.track', (params) => {\n tracker.track(params.name, params.props);\n });\n }\n\n private registerBillingHandlers(): void {\n // ctx.signal пробрасывается в underlying fetch — отмена с content-стороны\n // (юзер закрыл модалку) реально кенселит сетевой запрос в offscreen'е,\n // не оставляя «зомби-fetch» висеть до timeout'а.\n this.transport.on('billing.bootstrap', async (params, ctx) =>\n this.billing.bootstrap({ force: params.force, signal: ctx.signal })\n );\n this.transport.on('billing.getCachedBootstrap', () =>\n this.billing.getCachedBootstrap()\n );\n\n this.transport.on('billing.getVisitorId', async () => this.billing.getVisitorId());\n\n this.transport.on('billing.getUser', async (params, ctx) =>\n this.billing.getUser({ force: params.force, signal: ctx.signal })\n );\n this.transport.on('billing.getCachedUser', () => this.billing.getCachedUser());\n\n this.transport.on('billing.getBalances', async (params, ctx) =>\n this.billing.getBalances({ force: params.force, signal: ctx.signal })\n );\n this.transport.on('billing.getCachedBalances', () => this.billing.getCachedBalances());\n\n this.transport.on('billing.createCheckout', async (params, ctx) =>\n this.billing.createCheckout({ ...params, signal: ctx.signal })\n );\n\n this.transport.on('billing.listPurchases', async (_params, ctx) =>\n this.billing.listPurchases({ signal: ctx.signal })\n );\n this.transport.on('billing.cancelSubscription', async (params, ctx) =>\n this.billing.cancelSubscription({ ...params, signal: ctx.signal })\n );\n\n this.transport.on('billing.getIdentity', () => this.billing.getIdentity() ?? null);\n this.transport.on('billing.setIdentity', (params) => {\n this.billing.setIdentity(params.identity ?? undefined);\n });\n\n // Storage proxy. Любой consumer через `billing.getStorage()` ходит сюда;\n // state живёт в offscreen'овском localStorage = single source of truth.\n const storage = this.billing.getStorage();\n this.transport.on('storage.get', async (params) => storage.getItem(params.key));\n this.transport.on('storage.set', async (params) => {\n await storage.setItem(params.key, params.value);\n });\n this.transport.on('storage.remove', async (params) => {\n await storage.removeItem(params.key);\n });\n\n // Trial-store с атомарным recordBlock через navigator.locks. Каждый\n // вызов recordBlock сериализуется по ключу `trial:<paywallId>` —\n // две вкладки одновременно не могут получить одинаковый snapshot и\n // оба записать decrement, drift'а нет.\n this.transport.on('trial.check', async (params) =>\n withTrialLock(params.paywallId, () =>\n this.makeTrialStore(params.paywallId, params.config).check()\n )\n );\n this.transport.on('trial.recordBlock', async (params) =>\n withTrialLock(params.paywallId, () =>\n this.makeTrialStore(params.paywallId, params.config).recordBlock()\n )\n );\n this.transport.on('trial.reset', async (params) =>\n withTrialLock(params.paywallId, () =>\n this.makeTrialStore(params.paywallId, params.config).reset()\n )\n );\n }\n\n /** Каждый trial-handler создаёт свежий store — он stateless, читает\n * state из storage. Кешировать инстансы смысла нет (storage = SoT). */\n private makeTrialStore(paywallId: string, config: TrialConfig) {\n return createTrialStore(this.billing.getStorage(), paywallId, config);\n }\n\n private registerAuthHandlers(auth: AuthClient): void {\n this.transport.on('auth.signInWithEmail', async (params) =>\n auth.signInWithEmail(params)\n );\n this.transport.on('auth.signUp', async (params) => auth.signUp(params));\n this.transport.on('auth.signOut', async () => auth.signOut());\n this.transport.on('auth.refresh', async () => auth.refresh());\n this.transport.on('auth.getCachedSession', () => auth.getCachedSession());\n this.transport.on('auth.requestPasswordReset', async (params) =>\n auth.requestPasswordReset(params)\n );\n this.transport.on('auth.updatePassword', async (params) =>\n auth.updatePassword(params)\n );\n this.transport.on('auth.sendOtp', async (params) => auth.sendOtp(params));\n this.transport.on('auth.verifyOtp', async (params) => auth.verifyOtp(params));\n this.transport.on('auth.resendConfirmation', async (params) =>\n auth.resendConfirmation(params)\n );\n this.transport.on('auth.revokeAllSessions', async () => auth.revokeAllSessions());\n\n // OAuth split-API (Phase 4.5). Verifier живёт внутри AuthClient'а\n // между двумя этими request'ами, content только открывает popup и\n // ждёт code'а. Никакого state в SDK-extension'овском offscreen-server —\n // всё в самом AuthClient'е.\n this.transport.on('auth.oauthStart', async (params) => {\n const { authorize_url, state } = await auth.startOAuthFlow({\n provider: params.provider,\n scopes: params.scopes,\n userMeta: params.userMeta\n });\n return { authorizeUrl: authorize_url, state };\n });\n this.transport.on('auth.oauthExchange', async (params) =>\n auth.completeOAuthFlow({ state: params.state, code: params.code })\n );\n this.transport.on('auth.getAccessToken', async () => auth.getAccessToken());\n\n this.transport.on('auth.signInAnonymously', async (params) =>\n auth.signInAnonymously({\n captchaToken: params.captchaToken,\n userMeta: params.userMeta,\n forceCaptcha: params.forceCaptcha\n })\n );\n }\n\n private bridgeBroadcasts(): void {\n this.userUnsub = this.billing.onUserChange(\n (user) => this.transport.broadcast('userChange', user),\n { immediate: 'none' }\n );\n this.balanceUnsub = this.billing.onBalanceChange(\n (balances) => this.transport.broadcast('balancesChange', balances),\n { immediate: 'none' }\n );\n if (this.auth) {\n this.authUnsub = this.auth.onAuthChange((session) =>\n this.transport.broadcast('authChange', session)\n );\n }\n }\n\n /** Старт listener'а на chrome.runtime.onConnect. */\n start(): void {\n if (this.connectListener) return;\n this.connectListener = (port) => {\n if (port.name !== PORT_NAME) return;\n this.transport.accept(portToChannel(port));\n };\n chrome.runtime.onConnect.addListener(this.connectListener);\n }\n\n stop(): void {\n if (this.connectListener) {\n chrome.runtime.onConnect.removeListener(this.connectListener);\n this.connectListener = null;\n }\n this.userUnsub?.();\n this.balanceUnsub?.();\n this.authUnsub?.();\n this.userUnsub = null;\n this.balanceUnsub = null;\n this.authUnsub = null;\n this.tracker?.destroy();\n }\n}\n\n/** Сериализует операции trial по ключу — atomically read-modify-write\n * внутри offscreen. navigator.locks доступен в offscreen-контексте (Chrome\n * 69+), для browsers без него — fallback на прямой call (race возможна,\n * но это совсем legacy-кейс). */\nasync function withTrialLock<T>(paywallId: string, fn: () => Promise<T>): Promise<T> {\n if (typeof navigator !== 'undefined' && navigator.locks?.request) {\n return navigator.locks.request(`@monetize.software/sdk-extension:trial:${paywallId}`, fn);\n }\n return fn();\n}\n\nfunction createTrackerIfEnabled(\n opts: OffscreenServerOptions,\n billing: BillingClient\n): EventTracker | undefined {\n if (opts.analytics === false) return undefined;\n const cfg = typeof opts.analytics === 'object' && opts.analytics !== null ? opts.analytics : {};\n const endpoint =\n cfg.endpoint ?? `${billing.apiOrigin}/api/v1/paywall/${billing.paywallId}/events`;\n return new EventTracker({\n endpoint,\n paywallId: billing.paywallId,\n capabilities: billing.capabilities,\n getVisitorId: () => billing.getVisitorId(),\n getCachedVisitorId: () => billing.getCachedVisitorId(),\n getUserId: () => billing.getIdentity()?.userId ?? null,\n flushIntervalMs: cfg.flushIntervalMs,\n maxBufferSize: cfg.maxBufferSize\n });\n}\n","// Offscreen page entry. Owns real BillingClient (и в Phase 4+ — AuthClient,\n// EventTracker) — единственный source of truth для всего расширения.\n//\n// Импортируется в `offscreen.html`:\n// <script type=\"module\">\n// import { startOffscreenServer } from '@monetize.software/sdk-extension/offscreen';\n// startOffscreenServer({ paywallId: '123', apiOrigin: 'https://...' });\n// </script>\n\nimport { OffscreenServer } from './server';\n\nexport interface OffscreenServerOptions {\n paywallId: string;\n apiOrigin?: string;\n /** Если true — offscreen-server создаёт собственный AuthClient и\n * подключает его к BillingClient для Bearer-авторизации. Сессия\n * хранится в offscreen'овском localStorage и шарится между всеми\n * surface'ами расширения через broadcast authChange. */\n auth?: boolean;\n /** Аналитика. По умолчанию включена; передай false чтобы отключить\n * целиком. Объект — кастомные параметры (endpoint, batch). EventTracker\n * один на расширение, все content track() forward'ятся в него. */\n analytics?:\n | boolean\n | {\n endpoint?: string;\n flushIntervalMs?: number;\n maxBufferSize?: number;\n };\n}\n\nlet active: OffscreenServer | null = null;\n\nexport function startOffscreenServer(opts: OffscreenServerOptions): OffscreenServer {\n if (typeof chrome === 'undefined' || !chrome.runtime) {\n throw new Error('@monetize.software/sdk-extension/offscreen requires chrome.runtime');\n }\n if (active) {\n // Двойной запуск — может случиться, если host подгружает offscreen-bootstrap\n // дважды (HMR в dev, или ошибка с двойным <script>). Возвращаем существующий\n // инстанс — re-creating дёрнул бы повторный listener на runtime.onConnect.\n return active;\n }\n active = new OffscreenServer(opts);\n active.start();\n return active;\n}\n\nexport type { OffscreenServer };\n"],"names":["TransportServer","PROTOCOL_VERSION","kind","handler","channel","env","inFlight","ctrl","payload","envelope","e","raw","isCancel","isRequest","result","id","error","serializeError","value","OffscreenServer","opts","AuthClient","BillingClient","createTrackerIfEnabled","tracker","params","ctx","_params","storage","withTrialLock","paywallId","config","createTrialStore","auth","authorize_url","state","user","balances","session","port","PORT_NAME","portToChannel","fn","billing","cfg","endpoint","EventTracker","active","startOffscreenServer"],"mappings":"gLAwCO,MAAMA,CAAgB,CAO3B,aAAc,CANd,KAAQ,aAAe,IACvB,KAAQ,aAAe,IAGvB,KAAQ,WAAa,QAMnB,KAAK,GAAG,YAAa,KAAO,CAC1B,gBAAiBC,EAAAA,iBACjB,eAAgB,EAAA,EAChB,CACJ,CAEA,GAA0BC,EAASC,EAAkC,CACnE,KAAK,SAAS,IAAID,EAAMC,CAAsC,CAChE,CAEA,IAA2BD,EAAe,CACxC,KAAK,SAAS,OAAOA,CAAI,CAC3B,CAKA,OAAOE,EAA+B,CACpC,KAAK,SAAS,IAAIA,CAAO,EACzB,KAAK,OAAO,IAAIA,EAAS,IAAI,GAAK,EAClCA,EAAQ,UAAWC,GAAQ,KAAK,SAASD,EAASC,CAAG,CAAC,EACtDD,EAAQ,aAAa,IAAM,CACzB,KAAK,SAAS,OAAOA,CAAO,EAC5B,MAAME,EAAW,KAAK,OAAO,IAAIF,CAAO,EACxC,GAAIE,EACF,UAAWC,KAAQD,EAAS,OAAA,IAAe,MAAA,EAE7C,KAAK,OAAO,OAAOF,CAAO,CAC5B,CAAC,CACH,CAGA,UAA+BF,EAASM,EAAgC,CACtE,MAAMC,EAA2C,CAAE,KAAM,QAAS,KAAAP,EAAM,QAAAM,CAAA,EACxE,UAAWJ,KAAW,KAAK,SACzB,GAAI,CACFA,EAAQ,KAAKK,CAAQ,CACvB,OAASC,EAAG,CACV,QAAQ,MAAM,wCAAyCA,CAAC,CAC1D,CAEJ,CAIA,IAAI,iBAA0B,CAC5B,OAAO,KAAK,SAAS,IACvB,CAEA,MAAc,SAASN,EAAyBO,EAA6B,CAC3E,GAAIC,EAASD,CAAG,EAAG,CACjB,MAAML,EAAW,KAAK,OAAO,IAAIF,CAAO,EAClCG,EAAOD,GAAU,IAAIK,EAAI,EAAE,EAC7BJ,IACFA,EAAK,MAAA,EACLD,EAAU,OAAOK,EAAI,EAAE,GAEzB,MACF,CACA,GAAI,CAACE,EAAUF,CAAG,EAAG,OACrB,MAAMR,EAAU,KAAK,SAAS,IAAIQ,EAAI,IAAI,EAC1C,GAAI,CAACR,EAAS,CACZ,KAAK,WAAWC,EAASO,EAAI,GAAI,IAAI,MAAM,yBAAyBA,EAAI,IAAI,EAAE,CAAC,EAC/E,MACF,CACA,MAAMJ,EAAO,IAAI,gBACXD,EAAW,KAAK,OAAO,IAAIF,CAAO,EACxCE,GAAU,IAAIK,EAAI,GAAIJ,CAAI,EAC1B,GAAI,CACF,MAAMO,EAAS,MAAMX,EAAQQ,EAAI,OAAsC,CACrE,OAAQJ,EAAK,MAAA,CACd,EACD,KAAK,UAAUH,EAASO,EAAI,GAAIG,CAAM,CACxC,OAASJ,EAAG,CAIV,KAAK,WAAWN,EAASO,EAAI,GAAID,CAAC,CACpC,QAAA,CACEJ,GAAU,OAAOK,EAAI,EAAE,CACzB,CACF,CAEQ,UAAUP,EAAyBW,EAAYD,EAAuB,CAC5E,GAAI,CACFV,EAAQ,KAAK,CAAE,KAAM,WAAY,GAAAW,EAAI,GAAI,GAAM,OAAAD,EAAQ,CACzD,OAASJ,EAAG,CACV,QAAQ,MAAM,sCAAuCA,CAAC,CACxD,CACF,CAEQ,WAAWN,EAAyBW,EAAYC,EAAsB,CAC5E,GAAI,CACFZ,EAAQ,KAAK,CAAE,KAAM,WAAY,GAAAW,EAAI,GAAI,GAAO,MAAOE,iBAAeD,CAAK,CAAA,CAAG,CAChF,OAASN,EAAG,CACV,QAAQ,MAAM,0CAA2CA,CAAC,CAC5D,CACF,CACF,CAEA,SAASG,EAAUK,EAA0C,CAC3D,OAAI,OAAOA,GAAU,UAAYA,IAAU,KAAa,GAChDA,EAA6B,OAAS,SAChD,CAEA,SAASN,EAASM,EAAyC,CACzD,OAAI,OAAOA,GAAU,UAAYA,IAAU,KAAa,GAChDA,EAA6B,OAAS,QAChD,CCtIO,MAAMC,CAAgB,CAU3B,YAAYC,EAA8B,CAN1C,KAAiB,UAAY,IAAIpB,EACjC,KAAQ,gBAAgE,KACxE,KAAQ,UAAiC,KACzC,KAAQ,aAAoC,KAC5C,KAAQ,UAAiC,KAGnCoB,EAAK,OACP,KAAK,KAAO,IAAIC,aAAW,CACzB,UAAWD,EAAK,UAChB,UAAWA,EAAK,SAAA,CACjB,GAGH,KAAK,QAAU,IAAIE,gBAAc,CAC/B,UAAWF,EAAK,UAChB,UAAWA,EAAK,UAChB,KAAM,KAAK,IAAA,CACZ,EAED,KAAK,QAAUG,EAAuBH,EAAM,KAAK,OAAO,EAExD,KAAK,wBAAA,EACD,KAAK,MAAM,KAAK,qBAAqB,KAAK,IAAI,EAC9C,KAAK,SAAS,KAAK,wBAAwB,KAAK,OAAO,EAC3D,KAAK,iBAAA,CACP,CAEQ,wBAAwBI,EAA6B,CAC3D,KAAK,UAAU,GAAG,gBAAkBC,GAAW,CAC7CD,EAAQ,MAAMC,EAAO,KAAMA,EAAO,KAAK,CACzC,CAAC,CACH,CAEQ,yBAAgC,CAItC,KAAK,UAAU,GAAG,oBAAqB,MAAOA,EAAQC,IACpD,KAAK,QAAQ,UAAU,CAAE,MAAOD,EAAO,MAAO,OAAQC,EAAI,OAAQ,CAAA,EAEpE,KAAK,UAAU,GAAG,6BAA8B,IAC9C,KAAK,QAAQ,mBAAA,CAAmB,EAGlC,KAAK,UAAU,GAAG,uBAAwB,SAAY,KAAK,QAAQ,cAAc,EAEjF,KAAK,UAAU,GAAG,kBAAmB,MAAOD,EAAQC,IAClD,KAAK,QAAQ,QAAQ,CAAE,MAAOD,EAAO,MAAO,OAAQC,EAAI,OAAQ,CAAA,EAElE,KAAK,UAAU,GAAG,wBAAyB,IAAM,KAAK,QAAQ,eAAe,EAE7E,KAAK,UAAU,GAAG,sBAAuB,MAAOD,EAAQC,IACtD,KAAK,QAAQ,YAAY,CAAE,MAAOD,EAAO,MAAO,OAAQC,EAAI,OAAQ,CAAA,EAEtE,KAAK,UAAU,GAAG,4BAA6B,IAAM,KAAK,QAAQ,mBAAmB,EAErF,KAAK,UAAU,GAAG,yBAA0B,MAAOD,EAAQC,IACzD,KAAK,QAAQ,eAAe,CAAE,GAAGD,EAAQ,OAAQC,EAAI,MAAA,CAAQ,CAAA,EAG/D,KAAK,UAAU,GAAG,wBAAyB,MAAOC,EAASD,IACzD,KAAK,QAAQ,cAAc,CAAE,OAAQA,EAAI,MAAA,CAAQ,CAAA,EAEnD,KAAK,UAAU,GAAG,6BAA8B,MAAOD,EAAQC,IAC7D,KAAK,QAAQ,mBAAmB,CAAE,GAAGD,EAAQ,OAAQC,EAAI,MAAA,CAAQ,CAAA,EAGnE,KAAK,UAAU,GAAG,sBAAuB,IAAM,KAAK,QAAQ,YAAA,GAAiB,IAAI,EACjF,KAAK,UAAU,GAAG,sBAAwBD,GAAW,CACnD,KAAK,QAAQ,YAAYA,EAAO,UAAY,MAAS,CACvD,CAAC,EAID,MAAMG,EAAU,KAAK,QAAQ,WAAA,EAC7B,KAAK,UAAU,GAAG,cAAe,MAAOH,GAAWG,EAAQ,QAAQH,EAAO,GAAG,CAAC,EAC9E,KAAK,UAAU,GAAG,cAAe,MAAOA,GAAW,CACjD,MAAMG,EAAQ,QAAQH,EAAO,IAAKA,EAAO,KAAK,CAChD,CAAC,EACD,KAAK,UAAU,GAAG,iBAAkB,MAAOA,GAAW,CACpD,MAAMG,EAAQ,WAAWH,EAAO,GAAG,CACrC,CAAC,EAMD,KAAK,UAAU,GAAG,cAAe,MAAOA,GACtCI,EAAcJ,EAAO,UAAW,IAC9B,KAAK,eAAeA,EAAO,UAAWA,EAAO,MAAM,EAAE,MAAA,CAAM,CAC7D,EAEF,KAAK,UAAU,GAAG,oBAAqB,MAAOA,GAC5CI,EAAcJ,EAAO,UAAW,IAC9B,KAAK,eAAeA,EAAO,UAAWA,EAAO,MAAM,EAAE,YAAA,CAAY,CACnE,EAEF,KAAK,UAAU,GAAG,cAAe,MAAOA,GACtCI,EAAcJ,EAAO,UAAW,IAC9B,KAAK,eAAeA,EAAO,UAAWA,EAAO,MAAM,EAAE,MAAA,CAAM,CAC7D,CAEJ,CAIQ,eAAeK,EAAmBC,EAAqB,CAC7D,OAAOC,EAAAA,iBAAiB,KAAK,QAAQ,WAAA,EAAcF,EAAWC,CAAM,CACtE,CAEQ,qBAAqBE,EAAwB,CACnD,KAAK,UAAU,GAAG,uBAAwB,MAAOR,GAC/CQ,EAAK,gBAAgBR,CAAM,CAAA,EAE7B,KAAK,UAAU,GAAG,cAAe,MAAOA,GAAWQ,EAAK,OAAOR,CAAM,CAAC,EACtE,KAAK,UAAU,GAAG,eAAgB,SAAYQ,EAAK,SAAS,EAC5D,KAAK,UAAU,GAAG,eAAgB,SAAYA,EAAK,SAAS,EAC5D,KAAK,UAAU,GAAG,wBAAyB,IAAMA,EAAK,kBAAkB,EACxE,KAAK,UAAU,GAAG,4BAA6B,MAAOR,GACpDQ,EAAK,qBAAqBR,CAAM,CAAA,EAElC,KAAK,UAAU,GAAG,sBAAuB,MAAOA,GAC9CQ,EAAK,eAAeR,CAAM,CAAA,EAE5B,KAAK,UAAU,GAAG,eAAgB,MAAOA,GAAWQ,EAAK,QAAQR,CAAM,CAAC,EACxE,KAAK,UAAU,GAAG,iBAAkB,MAAOA,GAAWQ,EAAK,UAAUR,CAAM,CAAC,EAC5E,KAAK,UAAU,GAAG,0BAA2B,MAAOA,GAClDQ,EAAK,mBAAmBR,CAAM,CAAA,EAEhC,KAAK,UAAU,GAAG,yBAA0B,SAAYQ,EAAK,mBAAmB,EAMhF,KAAK,UAAU,GAAG,kBAAmB,MAAOR,GAAW,CACrD,KAAM,CAAE,cAAAS,EAAe,MAAAC,CAAA,EAAU,MAAMF,EAAK,eAAe,CACzD,SAAUR,EAAO,SACjB,OAAQA,EAAO,OACf,SAAUA,EAAO,QAAA,CAClB,EACD,MAAO,CAAE,aAAcS,EAAe,MAAAC,CAAA,CACxC,CAAC,EACD,KAAK,UAAU,GAAG,qBAAsB,MAAOV,GAC7CQ,EAAK,kBAAkB,CAAE,MAAOR,EAAO,MAAO,KAAMA,EAAO,IAAA,CAAM,CAAA,EAEnE,KAAK,UAAU,GAAG,sBAAuB,SAAYQ,EAAK,gBAAgB,EAE1E,KAAK,UAAU,GAAG,yBAA0B,MAAOR,GACjDQ,EAAK,kBAAkB,CACrB,aAAcR,EAAO,aACrB,SAAUA,EAAO,SACjB,aAAcA,EAAO,YAAA,CACtB,CAAA,CAEL,CAEQ,kBAAyB,CAC/B,KAAK,UAAY,KAAK,QAAQ,aAC3BW,GAAS,KAAK,UAAU,UAAU,aAAcA,CAAI,EACrD,CAAE,UAAW,MAAA,CAAO,EAEtB,KAAK,aAAe,KAAK,QAAQ,gBAC9BC,GAAa,KAAK,UAAU,UAAU,iBAAkBA,CAAQ,EACjE,CAAE,UAAW,MAAA,CAAO,EAElB,KAAK,OACP,KAAK,UAAY,KAAK,KAAK,aAAcC,GACvC,KAAK,UAAU,UAAU,aAAcA,CAAO,CAAA,EAGpD,CAGA,OAAc,CACR,KAAK,kBACT,KAAK,gBAAmBC,GAAS,CAC3BA,EAAK,OAASC,aAClB,KAAK,UAAU,OAAOC,EAAAA,cAAcF,CAAI,CAAC,CAC3C,EACA,OAAO,QAAQ,UAAU,YAAY,KAAK,eAAe,EAC3D,CAEA,MAAa,CACP,KAAK,kBACP,OAAO,QAAQ,UAAU,eAAe,KAAK,eAAe,EAC5D,KAAK,gBAAkB,MAEzB,KAAK,YAAA,EACL,KAAK,eAAA,EACL,KAAK,YAAA,EACL,KAAK,UAAY,KACjB,KAAK,aAAe,KACpB,KAAK,UAAY,KACjB,KAAK,SAAS,QAAA,CAChB,CACF,CAMA,eAAeV,EAAiBC,EAAmBY,EAAkC,CACnF,OAAI,OAAO,UAAc,KAAe,UAAU,OAAO,QAChD,UAAU,MAAM,QAAQ,0CAA0CZ,CAAS,GAAIY,CAAE,EAEnFA,EAAA,CACT,CAEA,SAASnB,EACPH,EACAuB,EAC0B,CAC1B,GAAIvB,EAAK,YAAc,GAAO,OAC9B,MAAMwB,EAAM,OAAOxB,EAAK,WAAc,UAAYA,EAAK,YAAc,KAAOA,EAAK,UAAY,CAAA,EACvFyB,EACJD,EAAI,UAAY,GAAGD,EAAQ,SAAS,mBAAmBA,EAAQ,SAAS,UAC1E,OAAO,IAAIG,EAAAA,aAAa,CACtB,SAAAD,EACA,UAAWF,EAAQ,UACnB,aAAcA,EAAQ,aACtB,aAAc,IAAMA,EAAQ,aAAA,EAC5B,mBAAoB,IAAMA,EAAQ,mBAAA,EAClC,UAAW,IAAMA,EAAQ,YAAA,GAAe,QAAU,KAClD,gBAAiBC,EAAI,gBACrB,cAAeA,EAAI,aAAA,CACpB,CACH,CClOA,IAAIG,EAAiC,KAE9B,SAASC,EAAqB5B,EAA+C,CAClF,GAAI,OAAO,OAAW,KAAe,CAAC,OAAO,QAC3C,MAAM,IAAI,MAAM,oEAAoE,EAEtF,OAAI2B,IAMJA,EAAS,IAAI5B,EAAgBC,CAAI,EACjC2B,EAAO,MAAA,EACAA,EACT"}
1
+ {"version":3,"file":"offscreen.cjs","sources":["../src/shared/transport-server.ts","../src/offscreen/server.ts","../src/offscreen/index.ts"],"sourcesContent":["// Server-side транспорт. Один TransportServer слушает все каналы, которые\n// подключаются. В extension'е это offscreen, к которому SW проксирует\n// content-script'ы (один offscreen ↔ N каналов от SW, по одному на content).\n//\n// Контракт:\n// - on<K>(kind, handler) — регистрирует handler для request-типа. Один\n// handler на kind (overrideStatic диспатч): если переопределили — последний\n// выигрывает. Throw'ы ловятся и сериализуются в ResponseErr.\n// - broadcast<K>(kind, payload) — fan-out на все живые каналы. Используется\n// BillingClient'ом / AuthClient'ом, когда состояние меняется.\n// - accept(channel) — добавить канал в активный пул. Не делаем listenTo'у на\n// chrome.runtime.onConnect внутри shared-кода, чтобы тестировать без\n// chrome.* — это делает extension-side adapter (offscreen/sw).\n\nimport type {\n CancelEnvelope,\n EventEnvelope,\n EventKind,\n EventPayload,\n RequestEnvelope,\n RequestKind,\n RequestParams,\n RequestResult\n} from './protocol';\nimport { PROTOCOL_VERSION } from './protocol';\nimport { serializeError } from './errors';\nimport type { MessageChannel } from './channel';\n\nexport interface RequestContext {\n /** AbortSignal, который тригернётся при получении cancel-envelope от клиента.\n * Handler может пробросить его в underlying fetch для отмены сетевой\n * операции. Игнорировать тоже OK — старые handler'ы продолжат работать. */\n signal: AbortSignal;\n}\n\nexport type RequestHandler<K extends RequestKind> = (\n params: RequestParams<K>,\n ctx: RequestContext\n) => Promise<RequestResult<K>> | RequestResult<K>;\n\nexport class TransportServer {\n private handlers = new Map<RequestKind, RequestHandler<RequestKind>>();\n private channels = new Set<MessageChannel>();\n /** Активные запросы по каналам: channel → id → AbortController. На cancel\n * envelope ищем controller и abort'им его. На disconnect — abort всех. */\n private active = new WeakMap<MessageChannel, Map<string, AbortController>>();\n\n constructor() {\n // Built-in handshake handler — отвечает текущей версией протокола.\n // Клиент логирует mismatch на стороне TransportClient.ensureChannel,\n // не блокируем дальнейшие запросы (best-effort версионирование).\n this.on('handshake', () => ({\n protocolVersion: PROTOCOL_VERSION,\n offscreenReady: true\n }));\n }\n\n on<K extends RequestKind>(kind: K, handler: RequestHandler<K>): void {\n this.handlers.set(kind, handler as RequestHandler<RequestKind>);\n }\n\n off<K extends RequestKind>(kind: K): void {\n this.handlers.delete(kind);\n }\n\n /** Подключить канал. Сервер начинает обрабатывать запросы из него и\n * включает его в broadcast'ы. На disconnect автоматически удаляет +\n * abort'ит все in-flight handlers для этого канала. */\n accept(channel: MessageChannel): void {\n this.channels.add(channel);\n this.active.set(channel, new Map());\n channel.onMessage((env) => this.dispatch(channel, env));\n channel.onDisconnect(() => {\n this.channels.delete(channel);\n const inFlight = this.active.get(channel);\n if (inFlight) {\n for (const ctrl of inFlight.values()) ctrl.abort();\n }\n this.active.delete(channel);\n });\n }\n\n /** Fan-out события всем подключённым каналам. */\n broadcast<K extends EventKind>(kind: K, payload: EventPayload<K>): void {\n const envelope: EventEnvelope<EventPayload<K>> = { type: 'event', kind, payload };\n for (const channel of this.channels) {\n try {\n channel.send(envelope);\n } catch (e) {\n console.error('[sdk-extension] broadcast send failed', e);\n }\n }\n }\n\n /** Размер активного пула — для health-check / cleanup'а offscreen'а\n * (если 0, host может закрыть offscreen-документ). */\n get connectionCount(): number {\n return this.channels.size;\n }\n\n private async dispatch(channel: MessageChannel, raw: unknown): Promise<void> {\n if (isCancel(raw)) {\n const inFlight = this.active.get(channel);\n const ctrl = inFlight?.get(raw.id);\n if (ctrl) {\n ctrl.abort();\n inFlight!.delete(raw.id);\n }\n return;\n }\n if (!isRequest(raw)) return;\n const handler = this.handlers.get(raw.kind);\n if (!handler) {\n this.respondErr(channel, raw.id, new Error(`Unknown request kind: ${raw.kind}`));\n return;\n }\n const ctrl = new AbortController();\n const inFlight = this.active.get(channel);\n inFlight?.set(raw.id, ctrl);\n try {\n const result = await handler(raw.params as RequestParams<RequestKind>, {\n signal: ctrl.signal\n });\n this.respondOk(channel, raw.id, result);\n } catch (e) {\n // Если handler завершился через abort — клиент уже знает (он сам и\n // отменял). Респонс ошибки всё равно шлём; client-side pending уже\n // очищен, ничего не произойдёт. Безопаснее, чем пропустить response.\n this.respondErr(channel, raw.id, e);\n } finally {\n inFlight?.delete(raw.id);\n }\n }\n\n private respondOk(channel: MessageChannel, id: string, result: unknown): void {\n try {\n channel.send({ type: 'response', id, ok: true, result });\n } catch (e) {\n console.error('[sdk-extension] respond send failed', e);\n }\n }\n\n private respondErr(channel: MessageChannel, id: string, error: unknown): void {\n try {\n channel.send({ type: 'response', id, ok: false, error: serializeError(error) });\n } catch (e) {\n console.error('[sdk-extension] respond err send failed', e);\n }\n }\n}\n\nfunction isRequest(value: unknown): value is RequestEnvelope {\n if (typeof value !== 'object' || value === null) return false;\n return (value as { type?: unknown }).type === 'request';\n}\n\nfunction isCancel(value: unknown): value is CancelEnvelope {\n if (typeof value !== 'object' || value === null) return false;\n return (value as { type?: unknown }).type === 'cancel';\n}\n","// Offscreen-side server. Owns the real BillingClient + AuthClient (если\n// включён) — единственный source of truth для всего расширения. Регистрирует\n// handler'ы на TransportServer'е, принимает port'ы от SW через\n// chrome.runtime.onConnect, broadcast'ит userChange/authChange/balancesChange\n// при изменении состояния.\n//\n// Жизненный цикл: server создаётся один раз через startOffscreenServer().\n// Если SW рестартует — он пере-create'ит offscreen (если документ умер) или\n// откроет новый port (если документ жив). Server в обоих случаях accept'ит\n// новый канал, state переживает.\n//\n// OAuth flows. PKCE verifier хранится в offscreen'е между oauthStart и\n// oauthExchange request'ами. Content только открывает popup и ждёт code'а\n// (нативно, в своём frame'е) — verifier через runtime-границу не уходит.\n\nimport { BillingClient } from '@sdk/core/BillingClient';\nimport { AuthClient } from '@sdk/core/auth';\nimport { EventTracker } from '@sdk/core/EventTracker';\nimport { createTrialStore } from '@sdk/core/trial';\nimport type { TrialConfig } from '@sdk/core/types';\nimport type { OffscreenServerOptions } from './index';\nimport { TransportServer } from '../shared/transport-server';\nimport { portToChannel } from '../shared/chrome-port';\nimport { RELAY_PORT_NAME } from '../shared/port-name';\n\nexport class OffscreenServer {\n readonly billing: BillingClient;\n readonly auth: AuthClient | undefined;\n readonly tracker: EventTracker | undefined;\n private readonly transport = new TransportServer();\n private connectListener: ((port: chrome.runtime.Port) => void) | null = null;\n private userUnsub: (() => void) | null = null;\n private balanceUnsub: (() => void) | null = null;\n private authUnsub: (() => void) | null = null;\n\n constructor(opts: OffscreenServerOptions) {\n if (opts.auth) {\n this.auth = new AuthClient({\n paywallId: opts.paywallId,\n apiOrigin: opts.apiOrigin\n });\n }\n\n this.billing = new BillingClient({\n paywallId: opts.paywallId,\n apiOrigin: opts.apiOrigin,\n auth: this.auth\n });\n\n this.tracker = createTrackerIfEnabled(opts, this.billing);\n\n this.registerBillingHandlers();\n if (this.auth) this.registerAuthHandlers(this.auth);\n if (this.tracker) this.registerTrackerHandlers(this.tracker);\n this.bridgeBroadcasts();\n }\n\n private registerTrackerHandlers(tracker: EventTracker): void {\n this.transport.on('tracker.track', (params) => {\n tracker.track(params.name, params.props);\n });\n }\n\n private registerBillingHandlers(): void {\n // ctx.signal пробрасывается в underlying fetch — отмена с content-стороны\n // (юзер закрыл модалку) реально кенселит сетевой запрос в offscreen'е,\n // не оставляя «зомби-fetch» висеть до timeout'а.\n this.transport.on('billing.bootstrap', async (params, ctx) =>\n this.billing.bootstrap({ force: params.force, signal: ctx.signal })\n );\n this.transport.on('billing.getCachedBootstrap', () =>\n this.billing.getCachedBootstrap()\n );\n\n this.transport.on('billing.getVisitorId', async () => this.billing.getVisitorId());\n\n this.transport.on('billing.getUser', async (params, ctx) =>\n this.billing.getUser({ force: params.force, signal: ctx.signal })\n );\n this.transport.on('billing.getCachedUser', () => this.billing.getCachedUser());\n\n this.transport.on('billing.getBalances', async (params, ctx) =>\n this.billing.getBalances({ force: params.force, signal: ctx.signal })\n );\n this.transport.on('billing.getCachedBalances', () => this.billing.getCachedBalances());\n\n this.transport.on('billing.createCheckout', async (params, ctx) =>\n this.billing.createCheckout({ ...params, signal: ctx.signal })\n );\n\n this.transport.on('billing.listPurchases', async (_params, ctx) =>\n this.billing.listPurchases({ signal: ctx.signal })\n );\n this.transport.on('billing.cancelSubscription', async (params, ctx) =>\n this.billing.cancelSubscription({ ...params, signal: ctx.signal })\n );\n\n this.transport.on('billing.createSupportTicket', async (params) =>\n this.billing.createSupportTicket(params)\n );\n\n this.transport.on('billing.getIdentity', () => this.billing.getIdentity() ?? null);\n this.transport.on('billing.setIdentity', (params) => {\n this.billing.setIdentity(params.identity ?? undefined);\n });\n\n // Storage proxy. Любой consumer через `billing.getStorage()` ходит сюда;\n // state живёт в offscreen'овском localStorage = single source of truth.\n const storage = this.billing.getStorage();\n this.transport.on('storage.get', async (params) => storage.getItem(params.key));\n this.transport.on('storage.set', async (params) => {\n await storage.setItem(params.key, params.value);\n });\n this.transport.on('storage.remove', async (params) => {\n await storage.removeItem(params.key);\n });\n\n // Trial-store с атомарным recordBlock через navigator.locks. Каждый\n // вызов recordBlock сериализуется по ключу `trial:<paywallId>` —\n // две вкладки одновременно не могут получить одинаковый snapshot и\n // оба записать decrement, drift'а нет.\n this.transport.on('trial.check', async (params) =>\n withTrialLock(params.paywallId, () =>\n this.makeTrialStore(params.paywallId, params.config).check()\n )\n );\n this.transport.on('trial.recordBlock', async (params) =>\n withTrialLock(params.paywallId, () =>\n this.makeTrialStore(params.paywallId, params.config).recordBlock()\n )\n );\n this.transport.on('trial.reset', async (params) =>\n withTrialLock(params.paywallId, () =>\n this.makeTrialStore(params.paywallId, params.config).reset()\n )\n );\n }\n\n /** Каждый trial-handler создаёт свежий store — он stateless, читает\n * state из storage. Кешировать инстансы смысла нет (storage = SoT). */\n private makeTrialStore(paywallId: string, config: TrialConfig) {\n return createTrialStore(this.billing.getStorage(), paywallId, config);\n }\n\n private registerAuthHandlers(auth: AuthClient): void {\n this.transport.on('auth.signInWithEmail', async (params) =>\n auth.signInWithEmail(params)\n );\n this.transport.on('auth.signUp', async (params) => auth.signUp(params));\n this.transport.on('auth.signOut', async () => auth.signOut());\n this.transport.on('auth.refresh', async () => auth.refresh());\n this.transport.on('auth.getCachedSession', () => auth.getCachedSession());\n this.transport.on('auth.requestPasswordReset', async (params) =>\n auth.requestPasswordReset(params)\n );\n this.transport.on('auth.updatePassword', async (params) =>\n auth.updatePassword(params)\n );\n this.transport.on('auth.sendOtp', async (params) => auth.sendOtp(params));\n this.transport.on('auth.verifyOtp', async (params) => auth.verifyOtp(params));\n this.transport.on('auth.resendConfirmation', async (params) =>\n auth.resendConfirmation(params)\n );\n this.transport.on('auth.revokeAllSessions', async () => auth.revokeAllSessions());\n this.transport.on('auth.getLastLogin', async () => auth.getLastLogin());\n\n // OAuth split-API (Phase 4.5). Verifier живёт внутри AuthClient'а\n // между двумя этими request'ами, content только открывает popup и\n // ждёт code'а. Никакого state в SDK-extension'овском offscreen-server —\n // всё в самом AuthClient'е.\n this.transport.on('auth.oauthStart', async (params) => {\n const { authorize_url, state } = await auth.startOAuthFlow({\n provider: params.provider,\n scopes: params.scopes,\n userMeta: params.userMeta\n });\n return { authorizeUrl: authorize_url, state };\n });\n this.transport.on('auth.oauthExchange', async (params) =>\n auth.completeOAuthFlow({ state: params.state, code: params.code })\n );\n this.transport.on('auth.getAccessToken', async () => auth.getAccessToken());\n\n this.transport.on('auth.signInAnonymously', async (params) =>\n auth.signInAnonymously({\n captchaToken: params.captchaToken,\n userMeta: params.userMeta,\n forceNewAnon: params.forceNewAnon\n })\n );\n }\n\n private bridgeBroadcasts(): void {\n this.userUnsub = this.billing.onUserChange(\n (user) => this.transport.broadcast('userChange', user),\n { immediate: 'none' }\n );\n this.balanceUnsub = this.billing.onBalanceChange(\n (balances) => this.transport.broadcast('balancesChange', balances),\n { immediate: 'none' }\n );\n if (this.auth) {\n // INITIAL_SESSION НЕ broadcast'им: это per-subscriber synthetic event,\n // RemoteAuthClient на content-side выдаёт его сам сразу после resolve\n // своего hydrate-promise'а (через getCachedSession-запрос). Иначе один\n // ре-connect content'а породит дубль INITIAL_SESSION'а на каждого\n // listener'а в нём.\n this.authUnsub = this.auth.onAuthChange((event, session) => {\n if (event === 'INITIAL_SESSION') return;\n this.transport.broadcast('authChange', { event, session });\n });\n }\n }\n\n /** Старт listener'а на chrome.runtime.onConnect. */\n start(): void {\n if (this.connectListener) return;\n // Принимаем только SW relay-port (RELAY_PORT_NAME). chrome.runtime.connect\n // от popup/content/side-panel доставляется во ВСЕ extension contexts с\n // onConnect listener'ом — включая offscreen напрямую, минуя SW. Если бы\n // мы принимали PORT_NAME, на одно popup.connect() в offscreen прилетало\n // бы ДВА port'а (SW relay + direct popup), и один send из popup\n // дублировался: SW relay постит msg → handler #1, direct popup port\n // получает тот же msg → handler #2. SW же использует отдельное имя\n // RELAY_PORT_NAME для своего connect к offscreen.\n this.connectListener = (port) => {\n if (port.name !== RELAY_PORT_NAME) return;\n this.transport.accept(portToChannel(port));\n };\n chrome.runtime.onConnect.addListener(this.connectListener);\n }\n\n stop(): void {\n if (this.connectListener) {\n chrome.runtime.onConnect.removeListener(this.connectListener);\n this.connectListener = null;\n }\n this.userUnsub?.();\n this.balanceUnsub?.();\n this.authUnsub?.();\n this.userUnsub = null;\n this.balanceUnsub = null;\n this.authUnsub = null;\n this.tracker?.destroy();\n }\n}\n\n/** Сериализует операции trial по ключу — atomically read-modify-write\n * внутри offscreen. navigator.locks доступен в offscreen-контексте (Chrome\n * 69+), для browsers без него — fallback на прямой call (race возможна,\n * но это совсем legacy-кейс). */\nasync function withTrialLock<T>(paywallId: string, fn: () => Promise<T>): Promise<T> {\n if (typeof navigator !== 'undefined' && navigator.locks?.request) {\n return navigator.locks.request(`@monetize.software/sdk-extension:trial:${paywallId}`, fn);\n }\n return fn();\n}\n\nfunction createTrackerIfEnabled(\n opts: OffscreenServerOptions,\n billing: BillingClient\n): EventTracker | undefined {\n if (opts.analytics === false) return undefined;\n const cfg = typeof opts.analytics === 'object' && opts.analytics !== null ? opts.analytics : {};\n const endpoint =\n cfg.endpoint ?? `${billing.apiOrigin}/api/v1/paywall/${billing.paywallId}/events`;\n return new EventTracker({\n endpoint,\n paywallId: billing.paywallId,\n capabilities: billing.capabilities,\n getVisitorId: () => billing.getVisitorId(),\n getCachedVisitorId: () => billing.getCachedVisitorId(),\n getUserId: () => billing.getIdentity()?.userId ?? null,\n flushIntervalMs: cfg.flushIntervalMs,\n maxBufferSize: cfg.maxBufferSize\n });\n}\n","// Offscreen page entry. Owns real BillingClient (и в Phase 4+ — AuthClient,\n// EventTracker) — единственный source of truth для всего расширения.\n//\n// Импортируется в `offscreen.html`:\n// <script type=\"module\">\n// import { startOffscreenServer } from '@monetize.software/sdk-extension/offscreen';\n// startOffscreenServer({ paywallId: '123', apiOrigin: 'https://...' });\n// </script>\n\nimport { OffscreenServer } from './server';\n\nexport interface OffscreenServerOptions {\n paywallId: string;\n apiOrigin?: string;\n /** Если true — offscreen-server создаёт собственный AuthClient и\n * подключает его к BillingClient для Bearer-авторизации. Сессия\n * хранится в offscreen'овском localStorage и шарится между всеми\n * surface'ами расширения через broadcast authChange. */\n auth?: boolean;\n /** Аналитика. По умолчанию включена; передай false чтобы отключить\n * целиком. Объект — кастомные параметры (endpoint, batch). EventTracker\n * один на расширение, все content track() forward'ятся в него. */\n analytics?:\n | boolean\n | {\n endpoint?: string;\n flushIntervalMs?: number;\n maxBufferSize?: number;\n };\n}\n\nlet active: OffscreenServer | null = null;\n\nexport function startOffscreenServer(opts: OffscreenServerOptions): OffscreenServer {\n if (typeof chrome === 'undefined' || !chrome.runtime) {\n throw new Error('@monetize.software/sdk-extension/offscreen requires chrome.runtime');\n }\n if (active) {\n // Двойной запуск — может случиться, если host подгружает offscreen-bootstrap\n // дважды (HMR в dev, или ошибка с двойным <script>). Возвращаем существующий\n // инстанс — re-creating дёрнул бы повторный listener на runtime.onConnect.\n return active;\n }\n active = new OffscreenServer(opts);\n active.start();\n return active;\n}\n\nexport type { OffscreenServer };\n"],"names":["TransportServer","PROTOCOL_VERSION","kind","handler","channel","env","inFlight","ctrl","payload","envelope","e","raw","isCancel","isRequest","result","id","error","serializeError","value","OffscreenServer","opts","AuthClient","BillingClient","createTrackerIfEnabled","tracker","params","ctx","_params","storage","withTrialLock","paywallId","config","createTrialStore","auth","authorize_url","state","user","balances","event","session","port","RELAY_PORT_NAME","portToChannel","fn","billing","cfg","endpoint","EventTracker","active","startOffscreenServer"],"mappings":"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"}
package/dist/offscreen.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as h, s as d, A as g, B as u, c as p, p as f, E as y } from "./chunks/chrome-port-DPFUj1MP.js";
2
- import { P as b } from "./chunks/port-name-BPfQKtdb.js";
1
+ import { a as h, s as d, A as g, B as u, c as p, p as f, E as y } from "./chunks/chrome-port-bfTUUDz_.js";
2
+ import { R as b } from "./chunks/port-name-ervLBWAQ.js";
3
3
  class k {
4
4
  constructor() {
5
5
  this.handlers = /* @__PURE__ */ new Map(), this.channels = /* @__PURE__ */ new Set(), this.active = /* @__PURE__ */ new WeakMap(), this.on("handshake", () => ({
@@ -41,7 +41,7 @@ class k {
41
41
  return this.channels.size;
42
42
  }
43
43
  async dispatch(e, t) {
44
- if (C(t)) {
44
+ if (w(t)) {
45
45
  const r = this.active.get(e), c = r?.get(t.id);
46
46
  c && (c.abort(), r.delete(t.id));
47
47
  return;
@@ -83,10 +83,10 @@ class k {
83
83
  function I(n) {
84
84
  return typeof n != "object" || n === null ? !1 : n.type === "request";
85
85
  }
86
- function C(n) {
86
+ function w(n) {
87
87
  return typeof n != "object" || n === null ? !1 : n.type === "cancel";
88
88
  }
89
- class w {
89
+ class m {
90
90
  constructor(e) {
91
91
  this.transport = new k(), this.connectListener = null, this.userUnsub = null, this.balanceUnsub = null, this.authUnsub = null, e.auth && (this.auth = new g({
92
92
  paywallId: e.paywallId,
@@ -95,7 +95,7 @@ class w {
95
95
  paywallId: e.paywallId,
96
96
  apiOrigin: e.apiOrigin,
97
97
  auth: this.auth
98
- }), this.tracker = m(e, this.billing), this.registerBillingHandlers(), this.auth && this.registerAuthHandlers(this.auth), this.tracker && this.registerTrackerHandlers(this.tracker), this.bridgeBroadcasts();
98
+ }), this.tracker = C(e, this.billing), this.registerBillingHandlers(), this.auth && this.registerAuthHandlers(this.auth), this.tracker && this.registerTrackerHandlers(this.tracker), this.bridgeBroadcasts();
99
99
  }
100
100
  registerTrackerHandlers(e) {
101
101
  this.transport.on("tracker.track", (t) => {
@@ -124,6 +124,9 @@ class w {
124
124
  ), this.transport.on(
125
125
  "billing.cancelSubscription",
126
126
  async (t, s) => this.billing.cancelSubscription({ ...t, signal: s.signal })
127
+ ), this.transport.on(
128
+ "billing.createSupportTicket",
129
+ async (t) => this.billing.createSupportTicket(t)
127
130
  ), this.transport.on("billing.getIdentity", () => this.billing.getIdentity() ?? null), this.transport.on("billing.setIdentity", (t) => {
128
131
  this.billing.setIdentity(t.identity ?? void 0);
129
132
  });
@@ -170,7 +173,7 @@ class w {
170
173
  ), this.transport.on("auth.sendOtp", async (t) => e.sendOtp(t)), this.transport.on("auth.verifyOtp", async (t) => e.verifyOtp(t)), this.transport.on(
171
174
  "auth.resendConfirmation",
172
175
  async (t) => e.resendConfirmation(t)
173
- ), this.transport.on("auth.revokeAllSessions", async () => e.revokeAllSessions()), this.transport.on("auth.oauthStart", async (t) => {
176
+ ), this.transport.on("auth.revokeAllSessions", async () => e.revokeAllSessions()), this.transport.on("auth.getLastLogin", async () => e.getLastLogin()), this.transport.on("auth.oauthStart", async (t) => {
174
177
  const { authorize_url: s, state: i } = await e.startOAuthFlow({
175
178
  provider: t.provider,
176
179
  scopes: t.scopes,
@@ -185,7 +188,7 @@ class w {
185
188
  async (t) => e.signInAnonymously({
186
189
  captchaToken: t.captchaToken,
187
190
  userMeta: t.userMeta,
188
- forceCaptcha: t.forceCaptcha
191
+ forceNewAnon: t.forceNewAnon
189
192
  })
190
193
  );
191
194
  }
@@ -196,9 +199,9 @@ class w {
196
199
  ), this.balanceUnsub = this.billing.onBalanceChange(
197
200
  (e) => this.transport.broadcast("balancesChange", e),
198
201
  { immediate: "none" }
199
- ), this.auth && (this.authUnsub = this.auth.onAuthChange(
200
- (e) => this.transport.broadcast("authChange", e)
201
- ));
202
+ ), this.auth && (this.authUnsub = this.auth.onAuthChange((e, t) => {
203
+ e !== "INITIAL_SESSION" && this.transport.broadcast("authChange", { event: e, session: t });
204
+ }));
202
205
  }
203
206
  /** Старт listener'а на chrome.runtime.onConnect. */
204
207
  start() {
@@ -213,7 +216,7 @@ class w {
213
216
  async function l(n, e) {
214
217
  return typeof navigator < "u" && navigator.locks?.request ? navigator.locks.request(`@monetize.software/sdk-extension:trial:${n}`, e) : e();
215
218
  }
216
- function m(n, e) {
219
+ function C(n, e) {
217
220
  if (n.analytics === !1) return;
218
221
  const t = typeof n.analytics == "object" && n.analytics !== null ? n.analytics : {}, s = t.endpoint ?? `${e.apiOrigin}/api/v1/paywall/${e.paywallId}/events`;
219
222
  return new y({
@@ -228,12 +231,12 @@ function m(n, e) {
228
231
  });
229
232
  }
230
233
  let a = null;
231
- function U(n) {
234
+ function O(n) {
232
235
  if (typeof chrome > "u" || !chrome.runtime)
233
236
  throw new Error("@monetize.software/sdk-extension/offscreen requires chrome.runtime");
234
- return a || (a = new w(n), a.start(), a);
237
+ return a || (a = new m(n), a.start(), a);
235
238
  }
236
239
  export {
237
- U as startOffscreenServer
240
+ O as startOffscreenServer
238
241
  };
239
242
  //# sourceMappingURL=offscreen.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"offscreen.js","sources":["../src/shared/transport-server.ts","../src/offscreen/server.ts","../src/offscreen/index.ts"],"sourcesContent":["// Server-side транспорт. Один TransportServer слушает все каналы, которые\n// подключаются. В extension'е это offscreen, к которому SW проксирует\n// content-script'ы (один offscreen ↔ N каналов от SW, по одному на content).\n//\n// Контракт:\n// - on<K>(kind, handler) — регистрирует handler для request-типа. Один\n// handler на kind (overrideStatic диспатч): если переопределили — последний\n// выигрывает. Throw'ы ловятся и сериализуются в ResponseErr.\n// - broadcast<K>(kind, payload) — fan-out на все живые каналы. Используется\n// BillingClient'ом / AuthClient'ом, когда состояние меняется.\n// - accept(channel) — добавить канал в активный пул. Не делаем listenTo'у на\n// chrome.runtime.onConnect внутри shared-кода, чтобы тестировать без\n// chrome.* — это делает extension-side adapter (offscreen/sw).\n\nimport type {\n CancelEnvelope,\n EventEnvelope,\n EventKind,\n EventPayload,\n RequestEnvelope,\n RequestKind,\n RequestParams,\n RequestResult\n} from './protocol';\nimport { PROTOCOL_VERSION } from './protocol';\nimport { serializeError } from './errors';\nimport type { MessageChannel } from './channel';\n\nexport interface RequestContext {\n /** AbortSignal, который тригернётся при получении cancel-envelope от клиента.\n * Handler может пробросить его в underlying fetch для отмены сетевой\n * операции. Игнорировать тоже OK — старые handler'ы продолжат работать. */\n signal: AbortSignal;\n}\n\nexport type RequestHandler<K extends RequestKind> = (\n params: RequestParams<K>,\n ctx: RequestContext\n) => Promise<RequestResult<K>> | RequestResult<K>;\n\nexport class TransportServer {\n private handlers = new Map<RequestKind, RequestHandler<RequestKind>>();\n private channels = new Set<MessageChannel>();\n /** Активные запросы по каналам: channel → id → AbortController. На cancel\n * envelope ищем controller и abort'им его. На disconnect — abort всех. */\n private active = new WeakMap<MessageChannel, Map<string, AbortController>>();\n\n constructor() {\n // Built-in handshake handler — отвечает текущей версией протокола.\n // Клиент логирует mismatch на стороне TransportClient.ensureChannel,\n // не блокируем дальнейшие запросы (best-effort версионирование).\n this.on('handshake', () => ({\n protocolVersion: PROTOCOL_VERSION,\n offscreenReady: true\n }));\n }\n\n on<K extends RequestKind>(kind: K, handler: RequestHandler<K>): void {\n this.handlers.set(kind, handler as RequestHandler<RequestKind>);\n }\n\n off<K extends RequestKind>(kind: K): void {\n this.handlers.delete(kind);\n }\n\n /** Подключить канал. Сервер начинает обрабатывать запросы из него и\n * включает его в broadcast'ы. На disconnect автоматически удаляет +\n * abort'ит все in-flight handlers для этого канала. */\n accept(channel: MessageChannel): void {\n this.channels.add(channel);\n this.active.set(channel, new Map());\n channel.onMessage((env) => this.dispatch(channel, env));\n channel.onDisconnect(() => {\n this.channels.delete(channel);\n const inFlight = this.active.get(channel);\n if (inFlight) {\n for (const ctrl of inFlight.values()) ctrl.abort();\n }\n this.active.delete(channel);\n });\n }\n\n /** Fan-out события всем подключённым каналам. */\n broadcast<K extends EventKind>(kind: K, payload: EventPayload<K>): void {\n const envelope: EventEnvelope<EventPayload<K>> = { type: 'event', kind, payload };\n for (const channel of this.channels) {\n try {\n channel.send(envelope);\n } catch (e) {\n console.error('[sdk-extension] broadcast send failed', e);\n }\n }\n }\n\n /** Размер активного пула — для health-check / cleanup'а offscreen'а\n * (если 0, host может закрыть offscreen-документ). */\n get connectionCount(): number {\n return this.channels.size;\n }\n\n private async dispatch(channel: MessageChannel, raw: unknown): Promise<void> {\n if (isCancel(raw)) {\n const inFlight = this.active.get(channel);\n const ctrl = inFlight?.get(raw.id);\n if (ctrl) {\n ctrl.abort();\n inFlight!.delete(raw.id);\n }\n return;\n }\n if (!isRequest(raw)) return;\n const handler = this.handlers.get(raw.kind);\n if (!handler) {\n this.respondErr(channel, raw.id, new Error(`Unknown request kind: ${raw.kind}`));\n return;\n }\n const ctrl = new AbortController();\n const inFlight = this.active.get(channel);\n inFlight?.set(raw.id, ctrl);\n try {\n const result = await handler(raw.params as RequestParams<RequestKind>, {\n signal: ctrl.signal\n });\n this.respondOk(channel, raw.id, result);\n } catch (e) {\n // Если handler завершился через abort — клиент уже знает (он сам и\n // отменял). Респонс ошибки всё равно шлём; client-side pending уже\n // очищен, ничего не произойдёт. Безопаснее, чем пропустить response.\n this.respondErr(channel, raw.id, e);\n } finally {\n inFlight?.delete(raw.id);\n }\n }\n\n private respondOk(channel: MessageChannel, id: string, result: unknown): void {\n try {\n channel.send({ type: 'response', id, ok: true, result });\n } catch (e) {\n console.error('[sdk-extension] respond send failed', e);\n }\n }\n\n private respondErr(channel: MessageChannel, id: string, error: unknown): void {\n try {\n channel.send({ type: 'response', id, ok: false, error: serializeError(error) });\n } catch (e) {\n console.error('[sdk-extension] respond err send failed', e);\n }\n }\n}\n\nfunction isRequest(value: unknown): value is RequestEnvelope {\n if (typeof value !== 'object' || value === null) return false;\n return (value as { type?: unknown }).type === 'request';\n}\n\nfunction isCancel(value: unknown): value is CancelEnvelope {\n if (typeof value !== 'object' || value === null) return false;\n return (value as { type?: unknown }).type === 'cancel';\n}\n","// Offscreen-side server. Owns the real BillingClient + AuthClient (если\n// включён) — единственный source of truth для всего расширения. Регистрирует\n// handler'ы на TransportServer'е, принимает port'ы от SW через\n// chrome.runtime.onConnect, broadcast'ит userChange/authChange/balancesChange\n// при изменении состояния.\n//\n// Жизненный цикл: server создаётся один раз через startOffscreenServer().\n// Если SW рестартует — он пере-create'ит offscreen (если документ умер) или\n// откроет новый port (если документ жив). Server в обоих случаях accept'ит\n// новый канал, state переживает.\n//\n// OAuth flows. PKCE verifier хранится в offscreen'е между oauthStart и\n// oauthExchange request'ами. Content только открывает popup и ждёт code'а\n// (нативно, в своём frame'е) — verifier через runtime-границу не уходит.\n\nimport { BillingClient } from '@sdk/core/BillingClient';\nimport { AuthClient } from '@sdk/core/auth';\nimport { EventTracker } from '@sdk/core/EventTracker';\nimport { createTrialStore } from '@sdk/core/trial';\nimport type { TrialConfig } from '@sdk/core/types';\nimport type { OffscreenServerOptions } from './index';\nimport { TransportServer } from '../shared/transport-server';\nimport { portToChannel } from '../shared/chrome-port';\nimport { PORT_NAME } from '../shared/port-name';\n\nexport class OffscreenServer {\n readonly billing: BillingClient;\n readonly auth: AuthClient | undefined;\n readonly tracker: EventTracker | undefined;\n private readonly transport = new TransportServer();\n private connectListener: ((port: chrome.runtime.Port) => void) | null = null;\n private userUnsub: (() => void) | null = null;\n private balanceUnsub: (() => void) | null = null;\n private authUnsub: (() => void) | null = null;\n\n constructor(opts: OffscreenServerOptions) {\n if (opts.auth) {\n this.auth = new AuthClient({\n paywallId: opts.paywallId,\n apiOrigin: opts.apiOrigin\n });\n }\n\n this.billing = new BillingClient({\n paywallId: opts.paywallId,\n apiOrigin: opts.apiOrigin,\n auth: this.auth\n });\n\n this.tracker = createTrackerIfEnabled(opts, this.billing);\n\n this.registerBillingHandlers();\n if (this.auth) this.registerAuthHandlers(this.auth);\n if (this.tracker) this.registerTrackerHandlers(this.tracker);\n this.bridgeBroadcasts();\n }\n\n private registerTrackerHandlers(tracker: EventTracker): void {\n this.transport.on('tracker.track', (params) => {\n tracker.track(params.name, params.props);\n });\n }\n\n private registerBillingHandlers(): void {\n // ctx.signal пробрасывается в underlying fetch — отмена с content-стороны\n // (юзер закрыл модалку) реально кенселит сетевой запрос в offscreen'е,\n // не оставляя «зомби-fetch» висеть до timeout'а.\n this.transport.on('billing.bootstrap', async (params, ctx) =>\n this.billing.bootstrap({ force: params.force, signal: ctx.signal })\n );\n this.transport.on('billing.getCachedBootstrap', () =>\n this.billing.getCachedBootstrap()\n );\n\n this.transport.on('billing.getVisitorId', async () => this.billing.getVisitorId());\n\n this.transport.on('billing.getUser', async (params, ctx) =>\n this.billing.getUser({ force: params.force, signal: ctx.signal })\n );\n this.transport.on('billing.getCachedUser', () => this.billing.getCachedUser());\n\n this.transport.on('billing.getBalances', async (params, ctx) =>\n this.billing.getBalances({ force: params.force, signal: ctx.signal })\n );\n this.transport.on('billing.getCachedBalances', () => this.billing.getCachedBalances());\n\n this.transport.on('billing.createCheckout', async (params, ctx) =>\n this.billing.createCheckout({ ...params, signal: ctx.signal })\n );\n\n this.transport.on('billing.listPurchases', async (_params, ctx) =>\n this.billing.listPurchases({ signal: ctx.signal })\n );\n this.transport.on('billing.cancelSubscription', async (params, ctx) =>\n this.billing.cancelSubscription({ ...params, signal: ctx.signal })\n );\n\n this.transport.on('billing.getIdentity', () => this.billing.getIdentity() ?? null);\n this.transport.on('billing.setIdentity', (params) => {\n this.billing.setIdentity(params.identity ?? undefined);\n });\n\n // Storage proxy. Любой consumer через `billing.getStorage()` ходит сюда;\n // state живёт в offscreen'овском localStorage = single source of truth.\n const storage = this.billing.getStorage();\n this.transport.on('storage.get', async (params) => storage.getItem(params.key));\n this.transport.on('storage.set', async (params) => {\n await storage.setItem(params.key, params.value);\n });\n this.transport.on('storage.remove', async (params) => {\n await storage.removeItem(params.key);\n });\n\n // Trial-store с атомарным recordBlock через navigator.locks. Каждый\n // вызов recordBlock сериализуется по ключу `trial:<paywallId>` —\n // две вкладки одновременно не могут получить одинаковый snapshot и\n // оба записать decrement, drift'а нет.\n this.transport.on('trial.check', async (params) =>\n withTrialLock(params.paywallId, () =>\n this.makeTrialStore(params.paywallId, params.config).check()\n )\n );\n this.transport.on('trial.recordBlock', async (params) =>\n withTrialLock(params.paywallId, () =>\n this.makeTrialStore(params.paywallId, params.config).recordBlock()\n )\n );\n this.transport.on('trial.reset', async (params) =>\n withTrialLock(params.paywallId, () =>\n this.makeTrialStore(params.paywallId, params.config).reset()\n )\n );\n }\n\n /** Каждый trial-handler создаёт свежий store — он stateless, читает\n * state из storage. Кешировать инстансы смысла нет (storage = SoT). */\n private makeTrialStore(paywallId: string, config: TrialConfig) {\n return createTrialStore(this.billing.getStorage(), paywallId, config);\n }\n\n private registerAuthHandlers(auth: AuthClient): void {\n this.transport.on('auth.signInWithEmail', async (params) =>\n auth.signInWithEmail(params)\n );\n this.transport.on('auth.signUp', async (params) => auth.signUp(params));\n this.transport.on('auth.signOut', async () => auth.signOut());\n this.transport.on('auth.refresh', async () => auth.refresh());\n this.transport.on('auth.getCachedSession', () => auth.getCachedSession());\n this.transport.on('auth.requestPasswordReset', async (params) =>\n auth.requestPasswordReset(params)\n );\n this.transport.on('auth.updatePassword', async (params) =>\n auth.updatePassword(params)\n );\n this.transport.on('auth.sendOtp', async (params) => auth.sendOtp(params));\n this.transport.on('auth.verifyOtp', async (params) => auth.verifyOtp(params));\n this.transport.on('auth.resendConfirmation', async (params) =>\n auth.resendConfirmation(params)\n );\n this.transport.on('auth.revokeAllSessions', async () => auth.revokeAllSessions());\n\n // OAuth split-API (Phase 4.5). Verifier живёт внутри AuthClient'а\n // между двумя этими request'ами, content только открывает popup и\n // ждёт code'а. Никакого state в SDK-extension'овском offscreen-server —\n // всё в самом AuthClient'е.\n this.transport.on('auth.oauthStart', async (params) => {\n const { authorize_url, state } = await auth.startOAuthFlow({\n provider: params.provider,\n scopes: params.scopes,\n userMeta: params.userMeta\n });\n return { authorizeUrl: authorize_url, state };\n });\n this.transport.on('auth.oauthExchange', async (params) =>\n auth.completeOAuthFlow({ state: params.state, code: params.code })\n );\n this.transport.on('auth.getAccessToken', async () => auth.getAccessToken());\n\n this.transport.on('auth.signInAnonymously', async (params) =>\n auth.signInAnonymously({\n captchaToken: params.captchaToken,\n userMeta: params.userMeta,\n forceCaptcha: params.forceCaptcha\n })\n );\n }\n\n private bridgeBroadcasts(): void {\n this.userUnsub = this.billing.onUserChange(\n (user) => this.transport.broadcast('userChange', user),\n { immediate: 'none' }\n );\n this.balanceUnsub = this.billing.onBalanceChange(\n (balances) => this.transport.broadcast('balancesChange', balances),\n { immediate: 'none' }\n );\n if (this.auth) {\n this.authUnsub = this.auth.onAuthChange((session) =>\n this.transport.broadcast('authChange', session)\n );\n }\n }\n\n /** Старт listener'а на chrome.runtime.onConnect. */\n start(): void {\n if (this.connectListener) return;\n this.connectListener = (port) => {\n if (port.name !== PORT_NAME) return;\n this.transport.accept(portToChannel(port));\n };\n chrome.runtime.onConnect.addListener(this.connectListener);\n }\n\n stop(): void {\n if (this.connectListener) {\n chrome.runtime.onConnect.removeListener(this.connectListener);\n this.connectListener = null;\n }\n this.userUnsub?.();\n this.balanceUnsub?.();\n this.authUnsub?.();\n this.userUnsub = null;\n this.balanceUnsub = null;\n this.authUnsub = null;\n this.tracker?.destroy();\n }\n}\n\n/** Сериализует операции trial по ключу — atomically read-modify-write\n * внутри offscreen. navigator.locks доступен в offscreen-контексте (Chrome\n * 69+), для browsers без него — fallback на прямой call (race возможна,\n * но это совсем legacy-кейс). */\nasync function withTrialLock<T>(paywallId: string, fn: () => Promise<T>): Promise<T> {\n if (typeof navigator !== 'undefined' && navigator.locks?.request) {\n return navigator.locks.request(`@monetize.software/sdk-extension:trial:${paywallId}`, fn);\n }\n return fn();\n}\n\nfunction createTrackerIfEnabled(\n opts: OffscreenServerOptions,\n billing: BillingClient\n): EventTracker | undefined {\n if (opts.analytics === false) return undefined;\n const cfg = typeof opts.analytics === 'object' && opts.analytics !== null ? opts.analytics : {};\n const endpoint =\n cfg.endpoint ?? `${billing.apiOrigin}/api/v1/paywall/${billing.paywallId}/events`;\n return new EventTracker({\n endpoint,\n paywallId: billing.paywallId,\n capabilities: billing.capabilities,\n getVisitorId: () => billing.getVisitorId(),\n getCachedVisitorId: () => billing.getCachedVisitorId(),\n getUserId: () => billing.getIdentity()?.userId ?? null,\n flushIntervalMs: cfg.flushIntervalMs,\n maxBufferSize: cfg.maxBufferSize\n });\n}\n","// Offscreen page entry. Owns real BillingClient (и в Phase 4+ — AuthClient,\n// EventTracker) — единственный source of truth для всего расширения.\n//\n// Импортируется в `offscreen.html`:\n// <script type=\"module\">\n// import { startOffscreenServer } from '@monetize.software/sdk-extension/offscreen';\n// startOffscreenServer({ paywallId: '123', apiOrigin: 'https://...' });\n// </script>\n\nimport { OffscreenServer } from './server';\n\nexport interface OffscreenServerOptions {\n paywallId: string;\n apiOrigin?: string;\n /** Если true — offscreen-server создаёт собственный AuthClient и\n * подключает его к BillingClient для Bearer-авторизации. Сессия\n * хранится в offscreen'овском localStorage и шарится между всеми\n * surface'ами расширения через broadcast authChange. */\n auth?: boolean;\n /** Аналитика. По умолчанию включена; передай false чтобы отключить\n * целиком. Объект — кастомные параметры (endpoint, batch). EventTracker\n * один на расширение, все content track() forward'ятся в него. */\n analytics?:\n | boolean\n | {\n endpoint?: string;\n flushIntervalMs?: number;\n maxBufferSize?: number;\n };\n}\n\nlet active: OffscreenServer | null = null;\n\nexport function startOffscreenServer(opts: OffscreenServerOptions): OffscreenServer {\n if (typeof chrome === 'undefined' || !chrome.runtime) {\n throw new Error('@monetize.software/sdk-extension/offscreen requires chrome.runtime');\n }\n if (active) {\n // Двойной запуск — может случиться, если host подгружает offscreen-bootstrap\n // дважды (HMR в dev, или ошибка с двойным <script>). Возвращаем существующий\n // инстанс — re-creating дёрнул бы повторный listener на runtime.onConnect.\n return active;\n }\n active = new OffscreenServer(opts);\n active.start();\n return active;\n}\n\nexport type { OffscreenServer };\n"],"names":["TransportServer","PROTOCOL_VERSION","kind","handler","channel","env","inFlight","ctrl","payload","envelope","e","raw","isCancel","isRequest","result","id","error","serializeError","value","OffscreenServer","opts","AuthClient","BillingClient","createTrackerIfEnabled","tracker","params","ctx","_params","storage","withTrialLock","paywallId","config","createTrialStore","auth","authorize_url","state","user","balances","session","port","PORT_NAME","portToChannel","fn","billing","cfg","endpoint","EventTracker","active","startOffscreenServer"],"mappings":"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"}
1
+ {"version":3,"file":"offscreen.js","sources":["../src/shared/transport-server.ts","../src/offscreen/server.ts","../src/offscreen/index.ts"],"sourcesContent":["// Server-side транспорт. Один TransportServer слушает все каналы, которые\n// подключаются. В extension'е это offscreen, к которому SW проксирует\n// content-script'ы (один offscreen ↔ N каналов от SW, по одному на content).\n//\n// Контракт:\n// - on<K>(kind, handler) — регистрирует handler для request-типа. Один\n// handler на kind (overrideStatic диспатч): если переопределили — последний\n// выигрывает. Throw'ы ловятся и сериализуются в ResponseErr.\n// - broadcast<K>(kind, payload) — fan-out на все живые каналы. Используется\n// BillingClient'ом / AuthClient'ом, когда состояние меняется.\n// - accept(channel) — добавить канал в активный пул. Не делаем listenTo'у на\n// chrome.runtime.onConnect внутри shared-кода, чтобы тестировать без\n// chrome.* — это делает extension-side adapter (offscreen/sw).\n\nimport type {\n CancelEnvelope,\n EventEnvelope,\n EventKind,\n EventPayload,\n RequestEnvelope,\n RequestKind,\n RequestParams,\n RequestResult\n} from './protocol';\nimport { PROTOCOL_VERSION } from './protocol';\nimport { serializeError } from './errors';\nimport type { MessageChannel } from './channel';\n\nexport interface RequestContext {\n /** AbortSignal, который тригернётся при получении cancel-envelope от клиента.\n * Handler может пробросить его в underlying fetch для отмены сетевой\n * операции. Игнорировать тоже OK — старые handler'ы продолжат работать. */\n signal: AbortSignal;\n}\n\nexport type RequestHandler<K extends RequestKind> = (\n params: RequestParams<K>,\n ctx: RequestContext\n) => Promise<RequestResult<K>> | RequestResult<K>;\n\nexport class TransportServer {\n private handlers = new Map<RequestKind, RequestHandler<RequestKind>>();\n private channels = new Set<MessageChannel>();\n /** Активные запросы по каналам: channel → id → AbortController. На cancel\n * envelope ищем controller и abort'им его. На disconnect — abort всех. */\n private active = new WeakMap<MessageChannel, Map<string, AbortController>>();\n\n constructor() {\n // Built-in handshake handler — отвечает текущей версией протокола.\n // Клиент логирует mismatch на стороне TransportClient.ensureChannel,\n // не блокируем дальнейшие запросы (best-effort версионирование).\n this.on('handshake', () => ({\n protocolVersion: PROTOCOL_VERSION,\n offscreenReady: true\n }));\n }\n\n on<K extends RequestKind>(kind: K, handler: RequestHandler<K>): void {\n this.handlers.set(kind, handler as RequestHandler<RequestKind>);\n }\n\n off<K extends RequestKind>(kind: K): void {\n this.handlers.delete(kind);\n }\n\n /** Подключить канал. Сервер начинает обрабатывать запросы из него и\n * включает его в broadcast'ы. На disconnect автоматически удаляет +\n * abort'ит все in-flight handlers для этого канала. */\n accept(channel: MessageChannel): void {\n this.channels.add(channel);\n this.active.set(channel, new Map());\n channel.onMessage((env) => this.dispatch(channel, env));\n channel.onDisconnect(() => {\n this.channels.delete(channel);\n const inFlight = this.active.get(channel);\n if (inFlight) {\n for (const ctrl of inFlight.values()) ctrl.abort();\n }\n this.active.delete(channel);\n });\n }\n\n /** Fan-out события всем подключённым каналам. */\n broadcast<K extends EventKind>(kind: K, payload: EventPayload<K>): void {\n const envelope: EventEnvelope<EventPayload<K>> = { type: 'event', kind, payload };\n for (const channel of this.channels) {\n try {\n channel.send(envelope);\n } catch (e) {\n console.error('[sdk-extension] broadcast send failed', e);\n }\n }\n }\n\n /** Размер активного пула — для health-check / cleanup'а offscreen'а\n * (если 0, host может закрыть offscreen-документ). */\n get connectionCount(): number {\n return this.channels.size;\n }\n\n private async dispatch(channel: MessageChannel, raw: unknown): Promise<void> {\n if (isCancel(raw)) {\n const inFlight = this.active.get(channel);\n const ctrl = inFlight?.get(raw.id);\n if (ctrl) {\n ctrl.abort();\n inFlight!.delete(raw.id);\n }\n return;\n }\n if (!isRequest(raw)) return;\n const handler = this.handlers.get(raw.kind);\n if (!handler) {\n this.respondErr(channel, raw.id, new Error(`Unknown request kind: ${raw.kind}`));\n return;\n }\n const ctrl = new AbortController();\n const inFlight = this.active.get(channel);\n inFlight?.set(raw.id, ctrl);\n try {\n const result = await handler(raw.params as RequestParams<RequestKind>, {\n signal: ctrl.signal\n });\n this.respondOk(channel, raw.id, result);\n } catch (e) {\n // Если handler завершился через abort — клиент уже знает (он сам и\n // отменял). Респонс ошибки всё равно шлём; client-side pending уже\n // очищен, ничего не произойдёт. Безопаснее, чем пропустить response.\n this.respondErr(channel, raw.id, e);\n } finally {\n inFlight?.delete(raw.id);\n }\n }\n\n private respondOk(channel: MessageChannel, id: string, result: unknown): void {\n try {\n channel.send({ type: 'response', id, ok: true, result });\n } catch (e) {\n console.error('[sdk-extension] respond send failed', e);\n }\n }\n\n private respondErr(channel: MessageChannel, id: string, error: unknown): void {\n try {\n channel.send({ type: 'response', id, ok: false, error: serializeError(error) });\n } catch (e) {\n console.error('[sdk-extension] respond err send failed', e);\n }\n }\n}\n\nfunction isRequest(value: unknown): value is RequestEnvelope {\n if (typeof value !== 'object' || value === null) return false;\n return (value as { type?: unknown }).type === 'request';\n}\n\nfunction isCancel(value: unknown): value is CancelEnvelope {\n if (typeof value !== 'object' || value === null) return false;\n return (value as { type?: unknown }).type === 'cancel';\n}\n","// Offscreen-side server. Owns the real BillingClient + AuthClient (если\n// включён) — единственный source of truth для всего расширения. Регистрирует\n// handler'ы на TransportServer'е, принимает port'ы от SW через\n// chrome.runtime.onConnect, broadcast'ит userChange/authChange/balancesChange\n// при изменении состояния.\n//\n// Жизненный цикл: server создаётся один раз через startOffscreenServer().\n// Если SW рестартует — он пере-create'ит offscreen (если документ умер) или\n// откроет новый port (если документ жив). Server в обоих случаях accept'ит\n// новый канал, state переживает.\n//\n// OAuth flows. PKCE verifier хранится в offscreen'е между oauthStart и\n// oauthExchange request'ами. Content только открывает popup и ждёт code'а\n// (нативно, в своём frame'е) — verifier через runtime-границу не уходит.\n\nimport { BillingClient } from '@sdk/core/BillingClient';\nimport { AuthClient } from '@sdk/core/auth';\nimport { EventTracker } from '@sdk/core/EventTracker';\nimport { createTrialStore } from '@sdk/core/trial';\nimport type { TrialConfig } from '@sdk/core/types';\nimport type { OffscreenServerOptions } from './index';\nimport { TransportServer } from '../shared/transport-server';\nimport { portToChannel } from '../shared/chrome-port';\nimport { RELAY_PORT_NAME } from '../shared/port-name';\n\nexport class OffscreenServer {\n readonly billing: BillingClient;\n readonly auth: AuthClient | undefined;\n readonly tracker: EventTracker | undefined;\n private readonly transport = new TransportServer();\n private connectListener: ((port: chrome.runtime.Port) => void) | null = null;\n private userUnsub: (() => void) | null = null;\n private balanceUnsub: (() => void) | null = null;\n private authUnsub: (() => void) | null = null;\n\n constructor(opts: OffscreenServerOptions) {\n if (opts.auth) {\n this.auth = new AuthClient({\n paywallId: opts.paywallId,\n apiOrigin: opts.apiOrigin\n });\n }\n\n this.billing = new BillingClient({\n paywallId: opts.paywallId,\n apiOrigin: opts.apiOrigin,\n auth: this.auth\n });\n\n this.tracker = createTrackerIfEnabled(opts, this.billing);\n\n this.registerBillingHandlers();\n if (this.auth) this.registerAuthHandlers(this.auth);\n if (this.tracker) this.registerTrackerHandlers(this.tracker);\n this.bridgeBroadcasts();\n }\n\n private registerTrackerHandlers(tracker: EventTracker): void {\n this.transport.on('tracker.track', (params) => {\n tracker.track(params.name, params.props);\n });\n }\n\n private registerBillingHandlers(): void {\n // ctx.signal пробрасывается в underlying fetch — отмена с content-стороны\n // (юзер закрыл модалку) реально кенселит сетевой запрос в offscreen'е,\n // не оставляя «зомби-fetch» висеть до timeout'а.\n this.transport.on('billing.bootstrap', async (params, ctx) =>\n this.billing.bootstrap({ force: params.force, signal: ctx.signal })\n );\n this.transport.on('billing.getCachedBootstrap', () =>\n this.billing.getCachedBootstrap()\n );\n\n this.transport.on('billing.getVisitorId', async () => this.billing.getVisitorId());\n\n this.transport.on('billing.getUser', async (params, ctx) =>\n this.billing.getUser({ force: params.force, signal: ctx.signal })\n );\n this.transport.on('billing.getCachedUser', () => this.billing.getCachedUser());\n\n this.transport.on('billing.getBalances', async (params, ctx) =>\n this.billing.getBalances({ force: params.force, signal: ctx.signal })\n );\n this.transport.on('billing.getCachedBalances', () => this.billing.getCachedBalances());\n\n this.transport.on('billing.createCheckout', async (params, ctx) =>\n this.billing.createCheckout({ ...params, signal: ctx.signal })\n );\n\n this.transport.on('billing.listPurchases', async (_params, ctx) =>\n this.billing.listPurchases({ signal: ctx.signal })\n );\n this.transport.on('billing.cancelSubscription', async (params, ctx) =>\n this.billing.cancelSubscription({ ...params, signal: ctx.signal })\n );\n\n this.transport.on('billing.createSupportTicket', async (params) =>\n this.billing.createSupportTicket(params)\n );\n\n this.transport.on('billing.getIdentity', () => this.billing.getIdentity() ?? null);\n this.transport.on('billing.setIdentity', (params) => {\n this.billing.setIdentity(params.identity ?? undefined);\n });\n\n // Storage proxy. Любой consumer через `billing.getStorage()` ходит сюда;\n // state живёт в offscreen'овском localStorage = single source of truth.\n const storage = this.billing.getStorage();\n this.transport.on('storage.get', async (params) => storage.getItem(params.key));\n this.transport.on('storage.set', async (params) => {\n await storage.setItem(params.key, params.value);\n });\n this.transport.on('storage.remove', async (params) => {\n await storage.removeItem(params.key);\n });\n\n // Trial-store с атомарным recordBlock через navigator.locks. Каждый\n // вызов recordBlock сериализуется по ключу `trial:<paywallId>` —\n // две вкладки одновременно не могут получить одинаковый snapshot и\n // оба записать decrement, drift'а нет.\n this.transport.on('trial.check', async (params) =>\n withTrialLock(params.paywallId, () =>\n this.makeTrialStore(params.paywallId, params.config).check()\n )\n );\n this.transport.on('trial.recordBlock', async (params) =>\n withTrialLock(params.paywallId, () =>\n this.makeTrialStore(params.paywallId, params.config).recordBlock()\n )\n );\n this.transport.on('trial.reset', async (params) =>\n withTrialLock(params.paywallId, () =>\n this.makeTrialStore(params.paywallId, params.config).reset()\n )\n );\n }\n\n /** Каждый trial-handler создаёт свежий store — он stateless, читает\n * state из storage. Кешировать инстансы смысла нет (storage = SoT). */\n private makeTrialStore(paywallId: string, config: TrialConfig) {\n return createTrialStore(this.billing.getStorage(), paywallId, config);\n }\n\n private registerAuthHandlers(auth: AuthClient): void {\n this.transport.on('auth.signInWithEmail', async (params) =>\n auth.signInWithEmail(params)\n );\n this.transport.on('auth.signUp', async (params) => auth.signUp(params));\n this.transport.on('auth.signOut', async () => auth.signOut());\n this.transport.on('auth.refresh', async () => auth.refresh());\n this.transport.on('auth.getCachedSession', () => auth.getCachedSession());\n this.transport.on('auth.requestPasswordReset', async (params) =>\n auth.requestPasswordReset(params)\n );\n this.transport.on('auth.updatePassword', async (params) =>\n auth.updatePassword(params)\n );\n this.transport.on('auth.sendOtp', async (params) => auth.sendOtp(params));\n this.transport.on('auth.verifyOtp', async (params) => auth.verifyOtp(params));\n this.transport.on('auth.resendConfirmation', async (params) =>\n auth.resendConfirmation(params)\n );\n this.transport.on('auth.revokeAllSessions', async () => auth.revokeAllSessions());\n this.transport.on('auth.getLastLogin', async () => auth.getLastLogin());\n\n // OAuth split-API (Phase 4.5). Verifier живёт внутри AuthClient'а\n // между двумя этими request'ами, content только открывает popup и\n // ждёт code'а. Никакого state в SDK-extension'овском offscreen-server —\n // всё в самом AuthClient'е.\n this.transport.on('auth.oauthStart', async (params) => {\n const { authorize_url, state } = await auth.startOAuthFlow({\n provider: params.provider,\n scopes: params.scopes,\n userMeta: params.userMeta\n });\n return { authorizeUrl: authorize_url, state };\n });\n this.transport.on('auth.oauthExchange', async (params) =>\n auth.completeOAuthFlow({ state: params.state, code: params.code })\n );\n this.transport.on('auth.getAccessToken', async () => auth.getAccessToken());\n\n this.transport.on('auth.signInAnonymously', async (params) =>\n auth.signInAnonymously({\n captchaToken: params.captchaToken,\n userMeta: params.userMeta,\n forceNewAnon: params.forceNewAnon\n })\n );\n }\n\n private bridgeBroadcasts(): void {\n this.userUnsub = this.billing.onUserChange(\n (user) => this.transport.broadcast('userChange', user),\n { immediate: 'none' }\n );\n this.balanceUnsub = this.billing.onBalanceChange(\n (balances) => this.transport.broadcast('balancesChange', balances),\n { immediate: 'none' }\n );\n if (this.auth) {\n // INITIAL_SESSION НЕ broadcast'им: это per-subscriber synthetic event,\n // RemoteAuthClient на content-side выдаёт его сам сразу после resolve\n // своего hydrate-promise'а (через getCachedSession-запрос). Иначе один\n // ре-connect content'а породит дубль INITIAL_SESSION'а на каждого\n // listener'а в нём.\n this.authUnsub = this.auth.onAuthChange((event, session) => {\n if (event === 'INITIAL_SESSION') return;\n this.transport.broadcast('authChange', { event, session });\n });\n }\n }\n\n /** Старт listener'а на chrome.runtime.onConnect. */\n start(): void {\n if (this.connectListener) return;\n // Принимаем только SW relay-port (RELAY_PORT_NAME). chrome.runtime.connect\n // от popup/content/side-panel доставляется во ВСЕ extension contexts с\n // onConnect listener'ом — включая offscreen напрямую, минуя SW. Если бы\n // мы принимали PORT_NAME, на одно popup.connect() в offscreen прилетало\n // бы ДВА port'а (SW relay + direct popup), и один send из popup\n // дублировался: SW relay постит msg → handler #1, direct popup port\n // получает тот же msg → handler #2. SW же использует отдельное имя\n // RELAY_PORT_NAME для своего connect к offscreen.\n this.connectListener = (port) => {\n if (port.name !== RELAY_PORT_NAME) return;\n this.transport.accept(portToChannel(port));\n };\n chrome.runtime.onConnect.addListener(this.connectListener);\n }\n\n stop(): void {\n if (this.connectListener) {\n chrome.runtime.onConnect.removeListener(this.connectListener);\n this.connectListener = null;\n }\n this.userUnsub?.();\n this.balanceUnsub?.();\n this.authUnsub?.();\n this.userUnsub = null;\n this.balanceUnsub = null;\n this.authUnsub = null;\n this.tracker?.destroy();\n }\n}\n\n/** Сериализует операции trial по ключу — atomically read-modify-write\n * внутри offscreen. navigator.locks доступен в offscreen-контексте (Chrome\n * 69+), для browsers без него — fallback на прямой call (race возможна,\n * но это совсем legacy-кейс). */\nasync function withTrialLock<T>(paywallId: string, fn: () => Promise<T>): Promise<T> {\n if (typeof navigator !== 'undefined' && navigator.locks?.request) {\n return navigator.locks.request(`@monetize.software/sdk-extension:trial:${paywallId}`, fn);\n }\n return fn();\n}\n\nfunction createTrackerIfEnabled(\n opts: OffscreenServerOptions,\n billing: BillingClient\n): EventTracker | undefined {\n if (opts.analytics === false) return undefined;\n const cfg = typeof opts.analytics === 'object' && opts.analytics !== null ? opts.analytics : {};\n const endpoint =\n cfg.endpoint ?? `${billing.apiOrigin}/api/v1/paywall/${billing.paywallId}/events`;\n return new EventTracker({\n endpoint,\n paywallId: billing.paywallId,\n capabilities: billing.capabilities,\n getVisitorId: () => billing.getVisitorId(),\n getCachedVisitorId: () => billing.getCachedVisitorId(),\n getUserId: () => billing.getIdentity()?.userId ?? null,\n flushIntervalMs: cfg.flushIntervalMs,\n maxBufferSize: cfg.maxBufferSize\n });\n}\n","// Offscreen page entry. Owns real BillingClient (и в Phase 4+ — AuthClient,\n// EventTracker) — единственный source of truth для всего расширения.\n//\n// Импортируется в `offscreen.html`:\n// <script type=\"module\">\n// import { startOffscreenServer } from '@monetize.software/sdk-extension/offscreen';\n// startOffscreenServer({ paywallId: '123', apiOrigin: 'https://...' });\n// </script>\n\nimport { OffscreenServer } from './server';\n\nexport interface OffscreenServerOptions {\n paywallId: string;\n apiOrigin?: string;\n /** Если true — offscreen-server создаёт собственный AuthClient и\n * подключает его к BillingClient для Bearer-авторизации. Сессия\n * хранится в offscreen'овском localStorage и шарится между всеми\n * surface'ами расширения через broadcast authChange. */\n auth?: boolean;\n /** Аналитика. По умолчанию включена; передай false чтобы отключить\n * целиком. Объект — кастомные параметры (endpoint, batch). EventTracker\n * один на расширение, все content track() forward'ятся в него. */\n analytics?:\n | boolean\n | {\n endpoint?: string;\n flushIntervalMs?: number;\n maxBufferSize?: number;\n };\n}\n\nlet active: OffscreenServer | null = null;\n\nexport function startOffscreenServer(opts: OffscreenServerOptions): OffscreenServer {\n if (typeof chrome === 'undefined' || !chrome.runtime) {\n throw new Error('@monetize.software/sdk-extension/offscreen requires chrome.runtime');\n }\n if (active) {\n // Двойной запуск — может случиться, если host подгружает offscreen-bootstrap\n // дважды (HMR в dev, или ошибка с двойным <script>). Возвращаем существующий\n // инстанс — re-creating дёрнул бы повторный listener на runtime.onConnect.\n return active;\n }\n active = new OffscreenServer(opts);\n active.start();\n return active;\n}\n\nexport type { OffscreenServer };\n"],"names":["TransportServer","PROTOCOL_VERSION","kind","handler","channel","env","inFlight","ctrl","payload","envelope","e","raw","isCancel","isRequest","result","id","error","serializeError","value","OffscreenServer","opts","AuthClient","BillingClient","createTrackerIfEnabled","tracker","params","ctx","_params","storage","withTrialLock","paywallId","config","createTrialStore","auth","authorize_url","state","user","balances","event","session","port","RELAY_PORT_NAME","portToChannel","fn","billing","cfg","endpoint","EventTracker","active","startOffscreenServer"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { Balance, CheckoutResult, Identity, PaywallBootstrap, PaywallPrice, PaywallPurchaseDetailed, PaywallUser, TrialConfig, TrialStatus } from '../../../sdk/src/core/types';
2
- import { AuthSession, OAuthProvider, OtpVerifyType, SignUpResult } from '../../../sdk/src/core/auth';
1
+ import { Balance, CheckoutResult, Identity, PaywallBootstrap, PaywallPrice, PaywallPurchaseDetailed, PaywallUser, TrialConfig, TrialStatus } from '@monetize.software/sdk';
2
+ import { AuthChangeEvent, AuthSession, LastLogin, OAuthProvider, OtpVerifyType, SignUpResult } from '@monetize.software/sdk';
3
3
  declare module './protocol' {
4
4
  interface RequestParamsMap {
5
5
  handshake: {
@@ -43,6 +43,16 @@ declare module './protocol' {
43
43
  identity: Identity | null;
44
44
  };
45
45
  'billing.getVisitorId': void;
46
+ /** File-объекты переживают chrome.runtime structured-clone через port'ы
47
+ * (SW forward'ит as-is). Лимиты на размер (10MB/файл, 5 файлов) валидирует
48
+ * SDK перед отправкой и backend ещё раз — оба чтобы не зашибить SW heap'ом
49
+ * при злоупотреблении. */
50
+ 'billing.createSupportTicket': {
51
+ subject: string;
52
+ content: string;
53
+ email?: string;
54
+ files?: File[];
55
+ };
46
56
  'auth.signInWithEmail': {
47
57
  email: string;
48
58
  password: string;
@@ -96,14 +106,17 @@ declare module './protocol' {
96
106
  /** Анонимный sign-in через offscreen AuthClient. `captchaToken`
97
107
  * опциональный — bootloaded на будущее (когда сервер вернёт
98
108
  * challenge_required и потребует proof-of-something). Сейчас сервер
99
- * его не проверяет, поле резерв на forward-compat. `forceCaptcha`
109
+ * его не проверяет, поле резерв на forward-compat. `forceNewAnon`
100
110
  * обходит idempotent + resume шаги и сразу делает /signin (создаёт
101
111
  * нового anon-user'а — нужно при switch-account flow'е). */
102
112
  'auth.signInAnonymously': {
103
113
  captchaToken?: string;
104
114
  userMeta?: Record<string, string>;
105
- forceCaptcha?: boolean;
115
+ forceNewAnon?: boolean;
106
116
  };
117
+ /** Last-used auth method + email per-paywall — для UI бейджа «Last used»
118
+ * в AuthPanel. Storage живёт в offscreen'е, читаем через transport. */
119
+ 'auth.getLastLogin': void;
107
120
  'tracker.track': {
108
121
  name: string;
109
122
  props?: Record<string, unknown>;
@@ -157,6 +170,12 @@ declare module './protocol' {
157
170
  'billing.getIdentity': Identity | null;
158
171
  'billing.setIdentity': void;
159
172
  'billing.getVisitorId': string;
173
+ 'billing.createSupportTicket': {
174
+ ticket: {
175
+ id: number;
176
+ status: string;
177
+ };
178
+ };
160
179
  'auth.signInWithEmail': AuthSession;
161
180
  'auth.signUp': SignUpResult;
162
181
  'auth.signOut': void;
@@ -175,6 +194,7 @@ declare module './protocol' {
175
194
  'auth.oauthExchange': AuthSession;
176
195
  'auth.getAccessToken': string | null;
177
196
  'auth.signInAnonymously': AuthSession;
197
+ 'auth.getLastLogin': LastLogin | null;
178
198
  'tracker.track': void;
179
199
  'storage.get': string | null;
180
200
  'storage.set': void;
@@ -187,7 +207,10 @@ declare module './protocol' {
187
207
  declare module './protocol' {
188
208
  interface EventPayloadMap {
189
209
  userChange: PaywallUser;
190
- authChange: AuthSession | null;
210
+ authChange: {
211
+ event: AuthChangeEvent;
212
+ session: AuthSession | null;
213
+ };
191
214
  balancesChange: ReadonlyArray<Balance>;
192
215
  }
193
216
  }
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/shared/messages.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/shared/messages.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,3 @@
1
1
  export declare const PORT_NAME = "@monetize.software/sdk-extension";
2
+ export declare const RELAY_PORT_NAME = "@monetize.software/sdk-extension/relay";
2
3
  //# sourceMappingURL=port-name.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"port-name.d.ts","sourceRoot":"","sources":["../../src/shared/port-name.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,SAAS,qCAAqC,CAAC"}
1
+ {"version":3,"file":"port-name.d.ts","sourceRoot":"","sources":["../../src/shared/port-name.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,SAAS,qCAAqC,CAAC;AAS5D,eAAO,MAAM,eAAe,2CAA2C,CAAC"}
@@ -9,7 +9,7 @@ export interface CancelEnvelope {
9
9
  type: 'cancel';
10
10
  id: string;
11
11
  }
12
- export type RequestKind = 'billing.bootstrap' | 'billing.getCachedBootstrap' | 'billing.getUser' | 'billing.getCachedUser' | 'billing.getBalances' | 'billing.getCachedBalances' | 'billing.createCheckout' | 'billing.listPurchases' | 'billing.cancelSubscription' | 'billing.getIdentity' | 'billing.setIdentity' | 'billing.getVisitorId' | 'auth.signInWithEmail' | 'auth.signUp' | 'auth.signOut' | 'auth.getCachedSession' | 'auth.refresh' | 'auth.requestPasswordReset' | 'auth.updatePassword' | 'auth.sendOtp' | 'auth.verifyOtp' | 'auth.resendConfirmation' | 'auth.revokeAllSessions' | 'auth.oauthStart' | 'auth.oauthExchange' | 'auth.getAccessToken' | 'auth.signInAnonymously' | 'tracker.track' | 'storage.get' | 'storage.set' | 'storage.remove' | 'trial.check' | 'trial.recordBlock' | 'trial.reset' | 'handshake' | 'subscribe' | 'unsubscribe';
12
+ export type RequestKind = 'billing.bootstrap' | 'billing.getCachedBootstrap' | 'billing.getUser' | 'billing.getCachedUser' | 'billing.getBalances' | 'billing.getCachedBalances' | 'billing.createCheckout' | 'billing.listPurchases' | 'billing.cancelSubscription' | 'billing.getIdentity' | 'billing.setIdentity' | 'billing.getVisitorId' | 'billing.createSupportTicket' | 'auth.signInWithEmail' | 'auth.signUp' | 'auth.signOut' | 'auth.getCachedSession' | 'auth.refresh' | 'auth.requestPasswordReset' | 'auth.updatePassword' | 'auth.sendOtp' | 'auth.verifyOtp' | 'auth.resendConfirmation' | 'auth.revokeAllSessions' | 'auth.oauthStart' | 'auth.oauthExchange' | 'auth.getAccessToken' | 'auth.signInAnonymously' | 'auth.getLastLogin' | 'tracker.track' | 'storage.get' | 'storage.set' | 'storage.remove' | 'trial.check' | 'trial.recordBlock' | 'trial.reset' | 'handshake' | 'subscribe' | 'unsubscribe';
13
13
  export interface RequestEnvelope<P = unknown> {
14
14
  type: 'request';
15
15
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/shared/protocol.ts"],"names":[],"mappings":"AAgBA;;mDAEmD;AACnD,eAAO,MAAM,gBAAgB,EAAG,CAAU,CAAC;AAI3C;;uBAEuB;AACvB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,MAAM,WAAW,GAEnB,mBAAmB,GACnB,4BAA4B,GAC5B,iBAAiB,GACjB,uBAAuB,GACvB,qBAAqB,GACrB,2BAA2B,GAC3B,wBAAwB,GACxB,uBAAuB,GACvB,4BAA4B,GAC5B,qBAAqB,GACrB,qBAAqB,GACrB,sBAAsB,GAEtB,sBAAsB,GACtB,aAAa,GACb,cAAc,GACd,uBAAuB,GACvB,cAAc,GACd,2BAA2B,GAC3B,qBAAqB,GACrB,cAAc,GACd,gBAAgB,GAChB,yBAAyB,GACzB,wBAAwB,GACxB,iBAAiB,GACjB,oBAAoB,GACpB,qBAAqB,GACrB,wBAAwB,GAExB,eAAe,GAIf,aAAa,GACb,aAAa,GACb,gBAAgB,GAIhB,aAAa,GACb,mBAAmB,GACnB,aAAa,GAEb,WAAW,GACX,WAAW,GACX,aAAa,CAAC;AAElB,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,CAAC,CAAC;CACX;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,OAAO;IACrC,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,CAAC,CAAC;CACX;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,eAAe,CAAC;CACxB;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;AAIxE,MAAM,MAAM,SAAS,GACjB,YAAY,GACZ,YAAY,GACZ,gBAAgB,CAAC;AAErB,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,OAAO;IACxC,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,CAAC,CAAC;CACZ;AAID;;yEAEyE;AACzE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,MAAM,MAAM,QAAQ,GAChB,eAAe,GACf,gBAAgB,GAChB,aAAa,GACb,cAAc,CAAC;AAInB,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,WAAW,IAC7C,CAAC,SAAS,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;AAEnE,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,WAAW,IAC7C,CAAC,SAAS,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;AAEnE,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,SAAS,IAC1C,CAAC,SAAS,MAAM,eAAe,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;AAMjE,MAAM,WAAW,gBAAgB;CAAG;AACpC,MAAM,WAAW,gBAAgB;CAAG;AACpC,MAAM,WAAW,eAAe;CAAG"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/shared/protocol.ts"],"names":[],"mappings":"AAgBA;;mDAEmD;AACnD,eAAO,MAAM,gBAAgB,EAAG,CAAU,CAAC;AAI3C;;uBAEuB;AACvB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,MAAM,WAAW,GAEnB,mBAAmB,GACnB,4BAA4B,GAC5B,iBAAiB,GACjB,uBAAuB,GACvB,qBAAqB,GACrB,2BAA2B,GAC3B,wBAAwB,GACxB,uBAAuB,GACvB,4BAA4B,GAC5B,qBAAqB,GACrB,qBAAqB,GACrB,sBAAsB,GACtB,6BAA6B,GAE7B,sBAAsB,GACtB,aAAa,GACb,cAAc,GACd,uBAAuB,GACvB,cAAc,GACd,2BAA2B,GAC3B,qBAAqB,GACrB,cAAc,GACd,gBAAgB,GAChB,yBAAyB,GACzB,wBAAwB,GACxB,iBAAiB,GACjB,oBAAoB,GACpB,qBAAqB,GACrB,wBAAwB,GACxB,mBAAmB,GAEnB,eAAe,GAIf,aAAa,GACb,aAAa,GACb,gBAAgB,GAIhB,aAAa,GACb,mBAAmB,GACnB,aAAa,GAEb,WAAW,GACX,WAAW,GACX,aAAa,CAAC;AAElB,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,CAAC,CAAC;CACX;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,OAAO;IACrC,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,CAAC,CAAC;CACX;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,eAAe,CAAC;CACxB;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;AAIxE,MAAM,MAAM,SAAS,GACjB,YAAY,GACZ,YAAY,GACZ,gBAAgB,CAAC;AAErB,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,OAAO;IACxC,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,CAAC,CAAC;CACZ;AAID;;yEAEyE;AACzE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,MAAM,MAAM,QAAQ,GAChB,eAAe,GACf,gBAAgB,GAChB,aAAa,GACb,cAAc,CAAC;AAInB,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,WAAW,IAC7C,CAAC,SAAS,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;AAEnE,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,WAAW,IAC7C,CAAC,SAAS,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;AAEnE,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,SAAS,IAC1C,CAAC,SAAS,MAAM,eAAe,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;AAMjE,MAAM,WAAW,gBAAgB;CAAG;AACpC,MAAM,WAAW,gBAAgB;CAAG;AACpC,MAAM,WAAW,eAAe;CAAG"}