@tinkerlandai/indiana-sdk 0.8.3 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +44 -3
  3. package/README.zh-CN.md +8 -0
  4. package/dist/{ai-usage-BV-FlgWr.d.ts → ai-usage-DUlre7JC.d.ts} +1 -1
  5. package/dist/{api-B3FIE41b.d.ts → api-XDc4pRlN.d.ts} +63 -10
  6. package/dist/chunk-3F2NQOR2.js +1 -0
  7. package/dist/{chunk-BNU6IG3F.js → chunk-663UOBHL.js} +1 -1
  8. package/dist/chunk-BUDTHBFF.js +173 -0
  9. package/dist/chunk-EJTBSGLV.js +10 -0
  10. package/dist/{chunk-SHSNIJJM.js → chunk-F2GOIBDQ.js} +1 -1
  11. package/dist/chunk-RZBZ6LCT.js +4 -0
  12. package/dist/{chunk-2QPETWDX.js → chunk-SSHUBTT3.js} +1 -1
  13. package/dist/chunk-SSLZKIIU.js +1 -0
  14. package/dist/{configuration-sync-DNvKXHk-.d.ts → configuration-sync-Ce3dShy7.d.ts} +6 -1
  15. package/dist/content-2FCUY6XX.js +1 -0
  16. package/dist/{customer-page-WUQVK_tp.d.ts → customer-page-9B97Qdt_.d.ts} +21 -1
  17. package/dist/{funnel-local-client-wbz-4gFx.d.ts → funnel-local-client-CUGavICI.d.ts} +43 -23
  18. package/dist/{funnel-runtime-host-C5P5JTV3.js → funnel-runtime-host-ENRTSXPJ.js} +1 -1
  19. package/dist/index.d.ts +76 -26
  20. package/dist/index.js +1 -1
  21. package/dist/native-shell.js +1 -1
  22. package/dist/openrouter.d.ts +2 -2
  23. package/dist/openrouter.js +1 -1
  24. package/dist/page.d.ts +1 -1
  25. package/dist/page.js +1 -1
  26. package/dist/paywall-734GWAS4.js +1 -0
  27. package/dist/popup.d.ts +14 -4
  28. package/dist/popup.js +1 -1
  29. package/dist/react-native.d.ts +1 -1
  30. package/dist/react-native.js +1 -1
  31. package/dist/screen-renderer-DLXDQQKK.js +1 -0
  32. package/dist/server.d.ts +13 -13
  33. package/dist/server.js +1 -1
  34. package/dist/src-CLEFCTAU.js +1 -0
  35. package/dist/visual.js +2 -2
  36. package/package.json +1 -1
  37. package/dist/chunk-ANOOBDW5.js +0 -350
  38. package/dist/chunk-X747SY26.js +0 -4
  39. package/dist/chunk-Y32NPIYY.js +0 -1
  40. package/dist/chunk-ZT66RIFU.js +0 -10
  41. package/dist/content-J3FKZTGT.js +0 -1
  42. package/dist/paywall-3GIRKSHN.js +0 -1
  43. package/dist/screen-renderer-5FPYVSPW.js +0 -1
  44. package/dist/src-BMJCIMIF.js +0 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  Release facts and artifact evidence: [SDK release ledger](../../docs/sdk-releases.md).
4
4
 
5
+ ## 0.8.4 — 2026-10-26
6
+
7
+ - Add `prepareContent` and `preparePopup` to render authorized content before the opening click and reveal the same iframe on demand.
8
+ - Prepare bounded HTML DOM templates for supplied pages and Product variants; update variable text in place while preserving styles, images and unrelated content. Reuse inactive variants with empty variable slots.
9
+ - Prepare Local Funnel rule definitions once per pure segment and send advance signals without waiting for advisory prediction downloads. Late predictions remain fenced by Run position and identity.
10
+ - Synchronize the packaged Web, iOS and Android renderers. Retain HTTP protocol 0.8 and server authority over Funnel acceptance and commercial operations.
11
+ - Refresh generated native Paywall Coupon applicability schemas from the current Merchandise contract.
12
+
5
13
  ## 0.8.3 — 2026-10-26
6
14
 
7
15
  - Refresh sanitized custom HTML fallback content when Product availability changes.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @tinkerlandai/indiana-sdk
2
2
 
3
- These examples use SDK 0.8.1 with `https://api.dev.tinker.cash` and test App credentials (protocol 0.8). Check [environment state](../../docs/development-status.md) before switching. The SDK default remains the production API, so set `baseUrl` explicitly for these examples.
3
+ These examples use SDK 0.8.3 with `https://api.dev.tinker.cash` and test App credentials (protocol 0.8). Check [environment state](../../docs/development-status.md) before switching. The SDK default remains the production API, so set `baseUrl` explicitly for these examples.
4
4
 
5
5
  [简体中文](./README.zh-CN.md)
6
6
 
@@ -9,10 +9,10 @@ The Indiana business SDK groups its capabilities as **Identity, Commerce, Growth
9
9
  **IAM source scanning, generation, validation and upload belong to the independent build package `@tinkerlandai/indiana-iam`.** This business SDK retains only the runtime release binding used by GB visual changes. See [SDK boundaries](../../docs/sdk-architecture.md) and the [IAM package](../iam/README.md).
10
10
 
11
11
  ```sh
12
- npm install --save-exact @tinkerlandai/indiana-sdk@0.8.1
12
+ npm install --save-exact @tinkerlandai/indiana-sdk@0.8.3
13
13
  ```
14
14
 
15
- SDK 0.8.1 requires HTTP protocol 0.8. Install a version that matches your runtime; publishing a package does not deploy the server. Publication and accepted environment scope are recorded in the [release ledger](../../docs/sdk-releases.md) and [development status](../../docs/development-status.md).
15
+ SDK 0.8.3 requires HTTP protocol 0.8. Install a version that matches your runtime; publishing a package does not deploy the server. Publication and accepted environment scope are recorded in the [release ledger](../../docs/sdk-releases.md) and [development status](../../docs/development-status.md).
16
16
 
17
17
  The data/session layer handles public JSON, integrity checks and authenticated operations. The presentation host composes that layer with the packaged screen renderer; the renderer receives supplied data and emits action intents. Client display entry points load presentation lazily. The `/server` entry has no screen presentation dependency and uses a scoped Server Key only on your backend. A local SDK guard never replaces runtime authorization or verified payment completion. Console preview supplies simulated data/session results to the same presentation host.
18
18
 
@@ -217,6 +217,26 @@ The selected environment's integration settings control behavior events, experim
217
217
 
218
218
  Flags default to local evaluation; Owner/Admin can switch each flag to server evaluation. Server-evaluated flags deliver only keys and results, using the caller's fallback until the first result arrives. Attribute changes immediately discard old results. List hashes are not a secrecy boundary. Local Funnels cannot depend on server-evaluated flags; mode switches also check active historical Runs. `identify` / `reset` release the previous identity's Feature instances and event queue.
219
219
 
220
+ Merchandise targeting resolves a trusted item in the selected App/environment. Register its attributes and maintain the
221
+ item in Console, then pass a reference rather than item metadata. The SDK resolves the initial SKU before returning;
222
+ after switching items, await context refresh before reading the next decision. Item experiments use `merchandiseId`
223
+ (the internal UUID) without a Customer fallback; Customer experiments keep their own bucketing identity.
224
+
225
+ ```ts
226
+ const merchandiseFlags = await indiana.features({
227
+ attributes: { ...bucketingIdentity, merchandise: { id: "sku-outdoor" } },
228
+ });
229
+ merchandiseFlags.setAttributes({
230
+ ...bucketingIdentity,
231
+ merchandise: { id: "sku-indoor" },
232
+ });
233
+ await merchandiseFlags.refreshRemote();
234
+ const eligible = merchandiseFlags.isOn("item-promotion");
235
+ indiana.track("Item Viewed", {}, { merchandise: { id: "sku-indoor" } });
236
+ await indiana.flush();
237
+ merchandiseFlags.destroy();
238
+ ```
239
+
220
240
  Offering pins the Product Version scope and hierarchy. Paywall pins a published Offering Version and independently chooses its displayed Product subset, groups, ordering, and default selection. `createPaywallStartClient`, `createPaywallSession`, and `showPaywall` use a standalone Paywall Session. After payment, read Entitlements again. Your backend still authorizes requests and consumes usage idempotently.
221
241
 
222
242
  ## Commercial capabilities and current service boundaries
@@ -378,3 +398,24 @@ export async function showBanner(
378
398
  ```
379
399
 
380
400
  Provide every declared action handler. `onContinue` uses `intent.requestId` as its backend idempotency key; `retryAction()` reuses that intent after a failure. Call `destroy()` on unmount, sign-out or account change. The host renders content and emits intents; your backend still authorizes and executes business actions.
401
+
402
+ To remove module loading, document preparation and iframe startup from the opening click, resolve the current Customer's content earlier and prepare it explicitly:
403
+
404
+ ```ts
405
+ import { prepareContent } from "@tinkerlandai/indiana-sdk";
406
+
407
+ const lifetime = new AbortController();
408
+ const popup = await prepareContent(container, {
409
+ content, // Already resolved with kind: "popup" for this Customer.
410
+ actions: { continue: onContinue },
411
+ onError: console.error,
412
+ signal: lifetime.signal,
413
+ });
414
+ openButton.addEventListener("click", () => popup.show(), {
415
+ signal: lifetime.signal,
416
+ });
417
+ // On unmount, sign-out or account/scope change:
418
+ // lifetime.abort();
419
+ ```
420
+
421
+ Preparation waits for the first render without opening the dialog or running actions. `show()` reveals the same iframe and is idempotent; destroy and prepare a fresh handle for another presentation. Abort also cancels preparation while it is pending. This does not pre-authorize business operations or guarantee that images have decoded. For low-level ScreenDocument rendering, `/popup` provides `preparePopup(document, options)` with `ready`, `show()` and `destroy()`.
package/README.zh-CN.md CHANGED
@@ -206,6 +206,10 @@ flags.destroy();
206
206
 
207
207
  每个 flag 默认本地计算,Owner/Admin 可切换为服务器计算。服务器 flag 只下发键与结果,首次结果到达前使用调用方默认值;属性变化立即丢弃旧结果。名单哈希不等于保密,敏感规则应使用服务器计算。本地 Funnel 不得依赖服务器 flag,切换时也会校验仍在运行的历史版本。`identify` / `reset` 会释放旧身份的功能实例和事件队列。
208
208
 
209
+ 商品定向使用当前 App/环境的可信商品主档。在 Console 登记属性并维护商品后,传入 `merchandise: { id: "sku-outdoor" }` 引用;SDK 在返回 Feature 客户端之前解析商品。切换商品后,先调用 `setAttributes({ ...bucketingIdentity, merchandise: { id: "sku-indoor" } })`,再等待 `refreshRemote()` 后读取决策。商品实验使用服务端解析的 `merchandiseId`(内部 UUID),不能回退到人的分桶标识。请求中的商品属性不能覆盖主档。
210
+
211
+ 自定义商品事件可调用 `indiana.track("Item Viewed", {}, { merchandise: { id: "sku-indoor" } })`,再 `flush()`。Customer 身份、商品引用和实验分桶单位分别记录;事件不构成订单或收入回执。
212
+
209
213
  Offering 固定 Product Version 的范围与层级。Paywall 固定已发布 Offering Version,并独立选择显示的 Product 子集、分组、顺序和默认项。`createPaywallStartClient`、`createPaywallSession`、`showPaywall` 使用独立 Paywall Session,不创建占位 Funnel。付款完成后重新查询权益,业务后端仍须重新鉴权并幂等扣减用量。
210
214
 
211
215
  ## Web 商业能力与当前服务边界
@@ -299,3 +303,7 @@ export async function showBanner(
299
303
  ```
300
304
 
301
305
  每个声明动作都需要同名 handler。`onContinue` 用 `intent.requestId` 作为业务后端的幂等键;失败后 `retryAction()` 重用原意图。卸载、退出或换号时调用 `destroy()`。宿主只渲染和发出意图,业务后端仍负责鉴权与执行。
306
+
307
+ 需要加快点击打开时,可提前为当前 Customer 读取内容,再调用根入口的 `prepareContent(container, options)`,参数与 `mountContent` 相同。它提前加载展示模块、校验文档并启动 iframe,等首次渲染后返回句柄;点击时同步调用 `handle.show()`,直接显示同一个 iframe。准备期间不打开弹窗、不抢焦点、不执行动作。句柄用于一次展示,重复 `show()` 不重复挂载;下一次展示需重新准备。
308
+
309
+ 可传入 `signal: abortController.signal`,在卸载、退出或切换 Customer/App/环境时 `abortController.abort()`,连同仍在等待的准备一起取消并释放资源。预渲染不代替业务鉴权,也不保证图片已完成解码。直接持有已授权 ScreenDocument 的低层接入可使用 `/popup` 的 `preparePopup(document, options)`;句柄立即返回,提供 `ready`、`show()` 和 `destroy()`。
@@ -1,5 +1,5 @@
1
1
  import { LanguageModelV4Usage, LanguageModelV4Middleware } from '@ai-sdk/provider';
2
- import { F as FoundationApi, A as ApiInput } from './api-B3FIE41b.js';
2
+ import { F as FoundationApi, A as ApiInput } from './api-XDc4pRlN.js';
3
3
  import { z } from 'zod';
4
4
 
5
5
  declare const tokenCounts: z.ZodObject<{
@@ -1650,6 +1650,10 @@ declare const apiOperations: {
1650
1650
  stickyBucketUsed: z$1.ZodOptional<z$1.ZodBoolean>;
1651
1651
  }, z$1.core.$strict>>;
1652
1652
  }, z$1.core.$strict>>;
1653
+ merchandiseContext: z$1.ZodOptional<z$1.ZodObject<{
1654
+ merchandiseId: z$1.ZodUUID;
1655
+ merchandise: z$1.ZodRecord<z$1.ZodString, z$1.ZodJSONSchema>;
1656
+ }, z$1.core.$strict>>;
1653
1657
  }, z$1.core.$strict>;
1654
1658
  };
1655
1659
  readonly trackEvents: {
@@ -1663,6 +1667,11 @@ declare const apiOperations: {
1663
1667
  eventUuid: z$1.ZodUUID;
1664
1668
  timestamp: z$1.ZodISODateTime;
1665
1669
  name: z$1.ZodString;
1670
+ merchandise: z$1.ZodOptional<z$1.ZodUnion<readonly [z$1.ZodObject<{
1671
+ id: z$1.ZodString;
1672
+ }, z$1.core.$strict>, z$1.ZodObject<{
1673
+ internalId: z$1.ZodUUID;
1674
+ }, z$1.core.$strict>]>>;
1666
1675
  properties: z$1.ZodDefault<z$1.ZodRecord<z$1.ZodString, z$1.ZodJSONSchema>>;
1667
1676
  deviceId: z$1.ZodOptional<z$1.ZodString>;
1668
1677
  sessionId: z$1.ZodOptional<z$1.ZodString>;
@@ -10851,13 +10860,22 @@ declare const apiOperations: {
10851
10860
  }, z$1.core.$strict>, z$1.ZodObject<{
10852
10861
  type: z$1.ZodLiteral<"plans">;
10853
10862
  planIds: z$1.ZodArray<z$1.ZodUUID>;
10863
+ }, z$1.core.$strict>, z$1.ZodObject<{
10864
+ type: z$1.ZodLiteral<"merchandise">;
10865
+ scope: z$1.ZodObject<{
10866
+ type: z$1.ZodEnum<{
10867
+ selected: "selected";
10868
+ all: "all";
10869
+ condition: "condition";
10870
+ }>;
10871
+ }, z$1.core.$strict>;
10854
10872
  }, z$1.core.$strict>], "type">;
10855
10873
  }, z$1.core.$strict>;
10856
10874
  }, z$1.core.$strict>>;
10857
10875
  reason: z$1.ZodNullable<z$1.ZodEnum<{
10858
10876
  unavailable: "unavailable";
10859
- claim_disabled: "claim_disabled";
10860
10877
  inactive: "inactive";
10878
+ claim_disabled: "claim_disabled";
10861
10879
  outside_window: "outside_window";
10862
10880
  not_targeted: "not_targeted";
10863
10881
  not_first_purchase: "not_first_purchase";
@@ -10951,6 +10969,15 @@ declare const apiOperations: {
10951
10969
  }, z$1.core.$strict>, z$1.ZodObject<{
10952
10970
  type: z$1.ZodLiteral<"plans">;
10953
10971
  planIds: z$1.ZodArray<z$1.ZodUUID>;
10972
+ }, z$1.core.$strict>, z$1.ZodObject<{
10973
+ type: z$1.ZodLiteral<"merchandise">;
10974
+ scope: z$1.ZodObject<{
10975
+ type: z$1.ZodEnum<{
10976
+ selected: "selected";
10977
+ all: "all";
10978
+ condition: "condition";
10979
+ }>;
10980
+ }, z$1.core.$strict>;
10954
10981
  }, z$1.core.$strict>], "type">;
10955
10982
  }, z$1.core.$strict>;
10956
10983
  }, z$1.core.$strict>>;
@@ -11049,13 +11076,22 @@ declare const apiOperations: {
11049
11076
  }, z$1.core.$strict>, z$1.ZodObject<{
11050
11077
  type: z$1.ZodLiteral<"plans">;
11051
11078
  planIds: z$1.ZodArray<z$1.ZodUUID>;
11079
+ }, z$1.core.$strict>, z$1.ZodObject<{
11080
+ type: z$1.ZodLiteral<"merchandise">;
11081
+ scope: z$1.ZodObject<{
11082
+ type: z$1.ZodEnum<{
11083
+ selected: "selected";
11084
+ all: "all";
11085
+ condition: "condition";
11086
+ }>;
11087
+ }, z$1.core.$strict>;
11052
11088
  }, z$1.core.$strict>], "type">;
11053
11089
  }, z$1.core.$strict>;
11054
11090
  }, z$1.core.$strict>>;
11055
11091
  reason: z$1.ZodNullable<z$1.ZodEnum<{
11056
11092
  unavailable: "unavailable";
11057
- claim_disabled: "claim_disabled";
11058
11093
  inactive: "inactive";
11094
+ claim_disabled: "claim_disabled";
11059
11095
  outside_window: "outside_window";
11060
11096
  not_targeted: "not_targeted";
11061
11097
  not_first_purchase: "not_first_purchase";
@@ -11070,14 +11106,20 @@ declare const apiOperations: {
11070
11106
  readonly permission: "billing:write";
11071
11107
  readonly audience: "server";
11072
11108
  /** A stable merchant event records paid Coupon use; this does not verify a provider or grant subscription access. */
11073
- readonly request: z$1.ZodObject<{
11109
+ readonly request: z$1.ZodUnion<readonly [z$1.ZodObject<{
11110
+ productVersionId: z$1.ZodUUID;
11111
+ subscriptionId: z$1.ZodString;
11074
11112
  customerId: z$1.ZodUUID;
11075
11113
  eventId: z$1.ZodString;
11076
11114
  grantId: z$1.ZodUUID;
11077
- productVersionId: z$1.ZodUUID;
11078
- subscriptionId: z$1.ZodString;
11079
11115
  occurredAt: z$1.ZodISODateTime;
11080
- }, z$1.core.$strict>;
11116
+ }, z$1.core.$strict>, z$1.ZodObject<{
11117
+ merchandiseId: z$1.ZodUUID;
11118
+ customerId: z$1.ZodUUID;
11119
+ eventId: z$1.ZodString;
11120
+ grantId: z$1.ZodUUID;
11121
+ occurredAt: z$1.ZodISODateTime;
11122
+ }, z$1.core.$strict>]>;
11081
11123
  readonly response: z$1.ZodObject<{
11082
11124
  requestId: z$1.ZodUUID;
11083
11125
  scope: z$1.ZodObject<{
@@ -11087,19 +11129,30 @@ declare const apiOperations: {
11087
11129
  live: "live";
11088
11130
  }>;
11089
11131
  }, z$1.core.$strict>;
11090
- receipt: z$1.ZodObject<{
11132
+ receipt: z$1.ZodUnion<readonly [z$1.ZodObject<{
11133
+ productVersionId: z$1.ZodUUID;
11134
+ subscriptionId: z$1.ZodString;
11091
11135
  customerId: z$1.ZodUUID;
11092
11136
  eventId: z$1.ZodString;
11093
11137
  grantId: z$1.ZodUUID;
11094
- productVersionId: z$1.ZodUUID;
11095
- subscriptionId: z$1.ZodString;
11096
11138
  occurredAt: z$1.ZodISODateTime;
11097
11139
  id: z$1.ZodUUID;
11098
11140
  couponId: z$1.ZodUUID;
11099
11141
  status: z$1.ZodLiteral<"redeemed">;
11100
11142
  source: z$1.ZodLiteral<"merchant">;
11101
11143
  recordedAt: z$1.ZodISODateTime;
11102
- }, z$1.core.$strict>;
11144
+ }, z$1.core.$strict>, z$1.ZodObject<{
11145
+ merchandiseId: z$1.ZodUUID;
11146
+ customerId: z$1.ZodUUID;
11147
+ eventId: z$1.ZodString;
11148
+ grantId: z$1.ZodUUID;
11149
+ occurredAt: z$1.ZodISODateTime;
11150
+ id: z$1.ZodUUID;
11151
+ couponId: z$1.ZodUUID;
11152
+ status: z$1.ZodLiteral<"redeemed">;
11153
+ source: z$1.ZodLiteral<"merchant">;
11154
+ recordedAt: z$1.ZodISODateTime;
11155
+ }, z$1.core.$strict>]>;
11103
11156
  }, z$1.core.$strict>;
11104
11157
  };
11105
11158
  };
@@ -0,0 +1 @@
1
+ import{a as on,b as an,c as sn,d as un}from"./chunk-GRLMT5PR.js";import{a as we}from"./chunk-VVV3JNS3.js";import{a as re}from"./chunk-SSHUBTT3.js";import{$e as Ue,Aj as Xe,Bk as rn,Je as Me,Vg as z,Yi as ee,af as qe,df as Ge,eh as Je,ej as Ye,gh as U,gk as en,hh as Be,lh as Se,lj as ge,mh as L,nh as je,oh as ze,oj as Ze,ph as He,qh as $e,th as Ke,vh as Qe,yk as nn,zj as We,zk as tn}from"./chunk-EJTBSGLV.js";import{a as p}from"./chunk-SOQO2RDZ.js";import{b as Le,h as pe}from"./chunk-OBYJWIRB.js";import{a as te}from"./chunk-EXCPE2XH.js";import{b as fe}from"./chunk-RRII2DMC.js";import{h as Ve,l as ke}from"./chunk-KQCTDXVD.js";function Tn(n){let e=null,t=null,d=0,s=0,g=!1,i=new Set,o=null,r=null,a=new Set,h=()=>{for(let m of a)try{m()}catch{}},u={attributes:fe.parse(n.attributes??{}),onFeatureUsage:n.onFeatureUsage?(m,S)=>{!i.has(m)&&(!e||!("analyticsConfig"in e)||e.analyticsConfig.featureUsageEnabled)&&n.onFeatureUsage(m,structuredClone(S),structuredClone(u.attributes))}:void 0,onExperimentViewed:n.onExperimentViewed?(m,S)=>(!e||!("analyticsConfig"in e)||e.analyticsConfig.experimentViewsEnabled)&&n.onExperimentViewed(structuredClone(m),structuredClone(S),structuredClone(u.attributes)):void 0,stickyBucketAssignmentDocs:structuredClone(n.stickyBucketAssignmentDocs),saveStickyBucketAssignmentDoc:n.saveStickyBucketAssignmentDoc?m=>n.saveStickyBucketAssignmentDoc(structuredClone(m)):void 0,trackedFeatureUsage:{},trackedExperiments:new Set},F=()=>({value:null,source:"unknownFeature",on:!1,off:!0,ruleId:""});function N(m,S=new Set){return i.has(m)?!o||!o.features[m]||["unknownFeature","cyclicPrerequisite"].includes(o.features[m].source):S.has(m)?!1:(S.add(m),(e?.features[m]?.rules??[]).some(R=>[...R.parentConditions??[],...(R.tracks??[]).flatMap(C=>C.experiment.parentConditions??[])].some(C=>N(C.id,S))))}let O=m=>{if(n.assertUsable?.(e?.generation),!e)throw new Error("Initialize the Feature client before evaluation");if(e.expiresAt&&Date.parse(e.expiresAt)<=Date.now())throw new Error("Feature configuration expired; refresh before evaluation");return o?.expiresAt&&Date.parse(o.expiresAt)<=Date.now()&&(o=null,u.features=e.features),i.has(m)?!o||o.expiresAt&&Date.parse(o.expiresAt)<=Date.now()?F():structuredClone(o.features[m]??F()):n.evaluateRemote&&(u.attributes?.merchandise||u.attributes?.merchandiseId)&&!g||N(m)?F():structuredClone(ke(m,u))};async function c(){if(!e||!i.size&&!u.attributes?.merchandise&&!u.attributes?.merchandiseId)return;if(!n.evaluateRemote){if(i.size)throw new Error("Remote Feature evaluation requires a server loader");return}let m=s;if(r?.revision===m)return r.loading;let S=d,R=e,C=[...i],P=(async()=>{let T=Ge.parse(await n.evaluateRemote({attributes:structuredClone(u.attributes),features:C}));if(!(S!==d||m!==s||R!==e)){if(n.assertUsable?.(R.generation),T.generation!==R.generation)throw new Error("Feature configuration changed; refresh before evaluation");if(C.some(_=>!Object.hasOwn(T.features,_))||Object.keys(T.features).some(_=>!i.has(_)))throw new Error("Invalid remote Feature results");if(u.attributes?.merchandise||u.attributes?.merchandiseId){if(!T.merchandiseContext)throw new Error("Server did not resolve merchandise context");u.attributes=fe.parse({...u.attributes,...T.merchandiseContext}),g=!0}o=structuredClone(T),u.features={...R.features,...Object.fromEntries(Object.entries(o.features).map(([_,G])=>[_,{defaultValue:G.value}]))},h()}})();r={revision:m,loading:P};try{await P}finally{r?.loading===P&&(r=null)}}function y(){c().catch(m=>{try{n.onError?.(m)}catch{}})}async function l(){if(t)return t;let m=d,S=(async()=>{let R=await n.load(),C="remoteFeatures"in R?Ue.parse(R):null,P=C??pe.parse(R);if(P.scope.projectId!==n.scope.projectId||P.scope.environment!==n.scope.environment)throw new Error("Feature payload scope changed");if(m!==d)throw new Error("Feature client was reset");if(n.assertUsable&&e?.generation===P.generation){let{evaluatedAt:_,expiresAt:G,...J}=e,{evaluatedAt:Y,expiresAt:q,...Z}=P;if(L(J)!==L(Z))throw new Error("Immutable Feature generation changed content");return e.evaluatedAt=P.evaluatedAt,e.expiresAt=P.expiresAt,h(),(!o||o.expiresAt&&Date.parse(o.expiresAt)<=Date.now())&&y(),structuredClone(e)}let T=new Set(C?.remoteFeatures??[]);if([...T].some(_=>Object.hasOwn(P.features,_)))throw new Error("Remote Feature definitions must not be delivered locally");return e&&"analyticsConfig"in e&&"analyticsConfig"in P&&!e.analyticsConfig.experimentViewsEnabled&&C?.analyticsConfig.experimentViewsEnabled&&u.trackedExperiments?.clear(),e=structuredClone(P),i=T,o=null,r=null,s++,u.features=e.features,u.savedGroups=Ve(e.savedGroups),u.trackedFeatureUsage={},h(),y(),structuredClone(e)})();t=S;try{return await S}finally{t===S&&(t=null)}}return{init:l,refresh:l,refreshRemote:c,get generation(){return e?.generation??null},get expiresAt(){return e?.expiresAt??null},subscribe(m){return a.add(m),()=>{a.delete(m)}},setAttributes(m){let S=fe.parse(m);(u.attributes?.merchandise||u.attributes?.merchandiseId||m.merchandise||m.merchandiseId)&&u.trackedExperiments?.clear(),u.attributes=S,s++,g=!1,o=null,r=null,u.features=e?.features??{},u.trackedFeatureUsage={},h(),y()},evalFeature:O,isOn(m){return O(m).on},isOff(m){return O(m).off},getFeatureValue(m,S){let R=O(m).value;return structuredClone(R===null?S:R)},reset(){d++,s++,t=null,r=null,e=null,o=null,i.clear(),u.features={},u.savedGroups={},u.stickyBucketAssignmentDocs={},u.attributes={},u.trackedFeatureUsage={},u.trackedExperiments?.clear(),h()}}}function ln(n){let e,t,d=()=>new p("COMMAND_STORAGE_INVALID","Durable command storage is unavailable"),s=Promise.resolve().then(async()=>{if(e=n.storage??globalThis.localStorage,t=n.locks??globalThis.navigator?.locks,!e||!t||!globalThis.crypto?.subtle)throw d();let o=new TextEncoder().encode(JSON.stringify([new URL(n.baseUrl??te).href,n.runToken])),r=new Uint8Array(await crypto.subtle.digest("SHA-256",o));return"indiana.funnel.commands.v1."+Array.from(r,a=>a.toString(16).padStart(2,"0")).join("")});s.catch(()=>{});async function g(o){try{let r=await s;return await t.request(r,{mode:"exclusive"},()=>o(r))}catch(r){throw r instanceof p?r:d()}}function i(o){let r=e.getItem(o);if(r===null)return{revision:0,entry:null};if(r.length>1048576)throw d();let a=JSON.parse(r);if(!a||typeof a!="object"||!("revision"in a)||!("entry"in a)||!Number.isSafeInteger(a.revision)||Number(a.revision)<0)throw d();return{revision:Number(a.revision),entry:a.entry}}return{read:()=>g(i),write:(o,r)=>g(a=>{if(i(a).revision!==o)return null;if(!Number.isSafeInteger(o+1))throw d();return e.setItem(a,JSON.stringify({revision:o+1,entry:r})),o+1})}}async function ye(n,e){let{funnelRuntimeDeliverySchema:t}=await import("./src-CLEFCTAU.js"),d=t.safeParse(e);if(!d.success)throw new p("INVALID_RESPONSE","Funnel response contract changed");let s=d.data;if(n.scope&&(s.scope.projectId!==n.scope.projectId||s.scope.environment!==n.scope.environment))throw new p("SCOPE_MISMATCH","Funnel scope changed");return s}async function Pe(n,e,t){if(Number(n.headers.get("content-length"))>e)throw t.error("limit");let d=n.body?.getReader();if(!d)throw t.error("missing");let s=[],g=0;try{for(;;){t.signal?.throwIfAborted();let r=await d.read();if(r.done)break;if(g+=r.value.length,g>e)throw t.error("limit");s.push(r.value)}}finally{await d.cancel().catch(()=>{})}t.signal?.throwIfAborted();let i=new Uint8Array(g),o=0;for(let r of s)i.set(r,o),o+=r.length;return i}async function cn(n,e,t){return new TextDecoder("utf-8",{fatal:!0}).decode(await Pe(n,e,t))}function he(n,e){let t=typeof n=="string"?new TextEncoder().encode(n):n;return t.byteLength===e.byteLength&&je(t)===e.sha256}async function Ie(n,e){let t=Ke.parse(e),{artifact:d,environmentId:s}=t.content,g=new URL(n.baseUrl??te).origin,i=new URL(d.url,g);if(i.origin!==g||i.username||i.password||i.search||i.hash||i.pathname!==`/api/v1/configuration/${s}/artifacts/${d.sha256}`)throw new p("INVALID_RESPONSE","Public Paywall locator is not trusted");let o=new AbortController,r=setTimeout(()=>o.abort(),U.initializationMs);try{let a=await(n.fetch??globalThis.fetch)(i,{method:"GET",credentials:"omit",redirect:"error",cache:"default",signal:o.signal});if(!a.ok||!a.headers.get("content-type")?.toLowerCase().startsWith("application/json")||Number(a.headers.get("content-length"))>d.byteLength)throw new p("INVALID_RESPONSE","Public Paywall is unavailable");let h=await Pe(a,d.byteLength,{signal:o.signal,error:u=>new p("INVALID_RESPONSE",u==="missing"?"Public Paywall body is missing":"Public Paywall exceeds its byte limit")});if(!he(h,d))throw new p("INVALID_RESPONSE","Public Paywall digest or size changed");return Qe(t,JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(h)))}finally{clearTimeout(r)}}var se=(n,e)=>new p(n,e);function $n(n){return nn(n,se)}async function Fe(n,e,{predict:t=!0}={}){let d=e.instruction;if(d?.type!=="evaluate_segment")throw new Error("Local segment instruction required");if(!n)throw new p("CONFIGURATION_UNAVAILABLE","Local execution requires public configuration");if(n.scope.environmentId!==d.environmentId)throw new p("SCOPE_MISMATCH","Evaluation environment changed");let s=null,g;if(t)try{let i=await n.funnel(e.source.id,e.source.versionId);g=i.manifest.generation,s=bn(n,e,i)}catch{s=null}return g??=n.snapshot?.generation??(await n.refresh()).generation,{advance:{policyRevision:d.policyRevision,generation:g},prediction:s}}function bn(n,e,t){let d=e.instruction;if(d?.type!=="evaluate_segment"||!t.growth||t.control.evaluationMode!=="local"||t.control.evaluationRevision!==d.policyRevision)return null;let{analyticsConfig:s,remoteFeatures:g,...i}=t.growth,o=We({scope:{projectId:n.scope.projectId,environment:n.scope.environment},funnelId:e.source.id,versionId:e.source.versionId,evaluationMode:"local",evaluationRevision:d.policyRevision,document:t.document,payload:pe.parse(i)}),r=Sn(o,t.document,{...e,...d}),a=r.steps.at(-1),h=r.boundary??(a?.result.port==="value"?{nodeId:a.nodeId,visit:e.visit+r.steps.length-1}:null);return h?{runId:e.id,from:{nodeId:e.nodeId,visit:e.visit,revision:e.revision},nodeId:h.nodeId,visit:h.visit,terminal:!r.boundary}:null}function Sn(n,e,t){return rn(n,e,t,se)}import{z as B}from"zod";var dn=z.refine(n=>!["start","get","review"].includes(n.operation)&&!("customerToken"in n),"Persist only the original mutation, without credentials").transform(n=>{if(n.operation==="start"||n.operation==="get"||n.operation==="review")throw new p("COMMAND_STORAGE_INVALID","Stored mutation required");return n}),mn=B.strictObject({schemaVersion:B.literal(1),scope:Le,runId:B.uuid(),funnelId:B.uuid(),versionId:B.uuid(),command:dn.optional(),closeCommand:dn.refine(n=>n.operation==="close").optional(),purchase:B.strictObject({receiptId:B.uuid(),operationId:B.uuid(),generation:B.number().int().nonnegative()}).optional(),closed:B.literal(!0).optional()}).refine(n=>!n.closeCommand||n.command&&n.command.operation!=="close"&&n.command.requestId!==n.closeCommand.requestId,"Close requires a separate request identity").refine(n=>n.command!==void 0||n.purchase!==void 0,"A recovery record requires an original obligation"),k=()=>new p("COMMAND_STORAGE_CONFLICT","Another host changed this Run's pending command"),ve=(n,e)=>JSON.stringify(n)===JSON.stringify(e);function fn(n){let e=0,t=null,d=r=>JSON.stringify([r.scope,r.runId,r.funnelId,r.versionId]),s=Promise.resolve();async function g(){let r=await n.read();if(!Number.isSafeInteger(r.revision)||r.revision<0)throw new p("COMMAND_STORAGE_INVALID","Invalid command storage revision");return{revision:r.revision,entry:r.entry===null?null:mn.parse(r.entry)}}function i(r){let a=s.then(r);return s=a.catch(()=>{}),a}async function o(r){for(let a=0;a<4;a++){let h=await g();if(h.entry&&t!==null&&d(h.entry)!==t)throw k();let u=r(h.entry,h.revision);if(ve(h.entry,u)){e=h.revision;return}let F=await n.write(h.revision,u);if(F!==null){if(!Number.isSafeInteger(F)||F<=h.revision)throw k();e=F;return}}throw k()}return{bind(r){let a=JSON.stringify([r.scope,r.runId,r.funnelId,r.versionId]);if(t!==null&&t!==a)throw k();t=a},async load(){let r=await g();return e=r.revision,t=r.entry?d(r.entry):null,r.entry},retain(r){let a=mn.parse(r),h=a.command;return!h||t!==null&&d(a)!==t?Promise.reject(k()):(t??=d(a),i(()=>o((u,F)=>{if(u&&!ve(d(u),d(a)))throw k();if(!u){if(F!==e&&h.operation!=="close")throw k();return a}if(!u.command)return{...u,command:h,...h.operation==="close"?{closed:!0}:{}};if(h.operation==="close"&&u.command.operation!=="close"){if(u.command.requestId===h.requestId||u.closeCommand&&!ve(u.closeCommand,h))throw k();return{...u,closeCommand:h,closed:!0}}if(!ve(u.command,h))throw k();return u})))},observePurchase(r,a,h){return i(()=>o((u,F)=>{if(!u&&F!==e||u&&d(u)!==d({...r,schemaVersion:1}))throw k();if(u?.purchase&&u.purchase.generation>a.generation)return u;if(u?.purchase&&u.purchase.generation===a.generation&&u.purchase.operationId!==a.operationId)throw k();return h?!u?.purchase||u.purchase.operationId!==a.operationId?u:u.command?{...u,purchase:void 0}:null:{schemaVersion:1,...r,...u,purchase:a}}))},settle(r){return i(()=>o(a=>a?a.command&&"requestId"in a.command&&a.command.requestId===r?a.closeCommand?{...a,command:a.closeCommand,closeCommand:void 0}:a.purchase?{...a,command:void 0}:null:a.closeCommand&&"requestId"in a.closeCommand&&a.closeCommand.requestId===r?{...a,closeCommand:void 0}:a:null))}}}function rt(n,e){return e.type==="id"?n.customerId===e.value:n.externalUserId===e.value}function oe(n,e){if(n===e)return!0;if(Array.isArray(n)||Array.isArray(e))return Array.isArray(n)&&Array.isArray(e)&&n.length===e.length&&n.every((s,g)=>oe(s,e[g]));if(!n||!e||typeof n!="object"||typeof e!="object")return!1;let t=Object.entries(n),d=Object.entries(e);return t.length===d.length&&t.every(([s,g])=>Object.hasOwn(e,s)&&oe(g,Reflect.get(e,s)))}function pn(n){let e=null,t=0,d=!1,s,g=0,i=new Set;return{get view(){return e},get generation(){return t},get disposed(){return d},get customerToken(){return s},get readSequence(){return g},nextRead(){return++g},assertCurrent(o,r="Run identity changed during the request"){if(o!==t||d)throw new p("IDENTITY_CHANGED",r)},assertRun(o){if(e&&(o.id!==e.id||o.source.type!==e.source.type||o.source.id!==e.source.id||o.source.versionId!==e.source.versionId||o.locale!==e.locale||!oe(o.parameters,e.parameters)))throw new p("INVALID_RESPONSE","Run version changed");if(n&&o.source.id!==n)throw new p("INVALID_RESPONSE","Run belongs to another Funnel")},publish(o,r,a,h,u){if(!(o.operation==="review"&&e&&e!==a&&r.run.revision<=e.revision)&&!(e&&r.run.revision===e.revision&&h!==void 0&&h<g)&&(o.operation==="review"&&!r.run.stopped&&["running","waiting"].includes(r.run.status)&&e&&r.run.nodeId===e.nodeId&&r.run.visit===e.visit&&r.run.revision===e.revision&&(r.run.screen=e.screen,(e.paywall?.quote?.operationId===r.review?.activeOperationId||!e.paywall?.quote&&r.review?.activeOperationId===null)&&(r.run.paywall=e.paywall)),!(e?.paywall&&r.run.paywall&&e.paywall.receiptId===r.run.paywall.receiptId&&(r.run.paywall.selectionGeneration??0)<(e.paywall.selectionGeneration??0)))){if(!e||r.run.revision>=e.revision)e=r.run;else if(!u)return;if(e)for(let F of i)try{F(structuredClone(e))}catch{}}},identify(o){if(!/^gg_ct_[A-Za-z0-9_-]{43}$/.test(o))throw new p("INVALID_TOKEN","Customer credential required");t++,s=o},subscribe(o){return i.add(o),()=>i.delete(o)},reset(){d=!0,t++,s=void 0,e=null,i.clear()}}}function K(n){let{customerToken:e,...t}=n;return t}var Pn=n=>!(n instanceof p)||n.status===void 0||n.status>=500||[401,425].includes(n.status);function gn({options:n,journal:e,state:t,call:d}){let s=null,g=null,i=!1,o={command:null,close:null},r=!1,a,h=null,u=e?e.load().then(y=>{if(t.disposed)throw new p("IDENTITY_CHANGED","Controller was reset during command restoration");if(h=y,!y)return;if(n.scope&&(y.scope.projectId!==n.scope.projectId||y.scope.environment!==n.scope.environment))throw new p("SCOPE_MISMATCH","Pending command belongs to another scope");if(a=y.purchase,i=y.closed===!0,!y.command)return;let l=z.parse(y.command);if(l.operation==="start"||l.operation==="get"||l.operation==="review")throw new p("COMMAND_STORAGE_INVALID","Stored mutation required");s=l,y.closeCommand&&(g=y.closeCommand,i=!0),l.operation==="close"&&(i=!0),r=!0}):Promise.resolve();u.catch(()=>{});async function F(y=s){if(e&&await u,!y)throw new p("INVALID_REQUEST","No command is pending");let l=y,m=t.generation;if(e){if(!t.view||!n.scope)throw new p("COMMAND_STORAGE_INVALID","Read the original scoped Run before persisting a mutation");await e.retain({schemaVersion:1,scope:n.scope,runId:t.view.id,funnelId:t.view.source.id,versionId:t.view.source.versionId,command:K(l)})}if(m!==t.generation||s!==l&&g!==l)throw new p("IDENTITY_CHANGED","Run changed before command dispatch");let S={...l,...t.customerToken?{customerToken:t.customerToken}:{}},R=r;r=!0;try{return await d(S,C=>{if(!C.settlement)throw new p("INVALID_RESPONSE","Exact command settlement is missing");if(C.settlement.requestId!==l.requestId)throw new p("INVALID_RESPONSE","Command settlement identity changed");if(m===t.generation&&(s===l||g===l)&&C.run.pendingRequest?.requestId!==l.requestId&&C.settlement.state==="settled"&&(!i||l.operation==="close"||C.settlement?.state==="settled"&&!["running","waiting"].includes(C.run.status))){let P=()=>m!==t.generation||s!==l&&g!==l?!1:(s===l&&(s=null),g===l&&(g=null),r=s!==null,h=null,!0);return e?e.settle(l.requestId).then(P):P()}return!1})}catch(C){throw m===t.generation&&s===l&&!R&&!Pn(C)&&(e&&await e.settle(l.requestId),m===t.generation&&s===l&&(s=null,r=!1,h=null)),C}}function N(y){let l=z.parse(y);if(l.operation==="start"||l.operation==="get"||l.operation==="review")throw new p("INVALID_REQUEST","Mutation required");if(i&&l.operation!=="close"){if(s?.requestId===l.requestId)return c(l.requestId);throw new p("COMMAND_PENDING","Close preserves the original recovery record; settle it by identity")}if(l.operation==="close"&&s?.operation!=="close"){if(i=!0,g&&JSON.stringify(K(g))!==JSON.stringify(K(l)))throw new p("COMMAND_PENDING","Retry the original Close");return g??=l,o.close?o.close:O(g,"close")}if(s){if(JSON.stringify(K(s))!==JSON.stringify(K(l)))throw new p("COMMAND_PENDING","Retry the original command before sending another");if(o.command)return o.command}else s=l,r=!1;return O(s,"command")}function O(y,l){let m=F(y);o[l]=m;let S=()=>{o[l]===m&&(o[l]=null)};return m.then(S,S),m}async function c(y){let l=await d({operation:"get",settlementRequestId:y,...t.customerToken?{customerToken:t.customerToken}:{}});if(l.settlement?.requestId!==y)throw new p("INVALID_RESPONSE","Exact command settlement is missing");return l.settlement.state==="settled"&&(e&&await e.settle(y),s?.requestId===y&&(s=null,r=!1),g?.requestId===y&&(g=null)),l}return{ready:u,get pending(){return s},get closing(){return g},get closeRequested(){return i},get inFlight(){return o.command},get closeFlight(){return o.close},get purchase(){return a},assertBinding(y){if(h&&(y.run.id!==h.runId||y.run.source.id!==h.funnelId||y.run.source.versionId!==h.versionId))throw new p("SCOPE_MISMATCH","Stored command belongs to another Run or Version")},observePurchase(y,l,m,S){e?.bind({scope:l.scope,runId:l.run.id,funnelId:l.run.source.id,versionId:l.run.source.versionId}),e&&!n.scope&&(n.scope=l.scope);let R=l.run.paywall,C=R??l.purchase,P=C?.operation,T=l.settlement&&(!R||R.purchaseRequestId===l.settlement.requestId)&&(!a||a.operationId===l.settlement.operationId)?l.settlement:void 0,_=P?.operationId??C?.quote?.operationId??T?.operationId,G=C?.receiptId??T?.receiptId,J=R?.selectionGeneration??a?.generation??0;if(e&&_&&G&&y.operation!=="review"&&(!t.view||l.run.revision>=t.view.revision)&&(S===void 0||S>=t.readSequence)&&(!a||J>=a.generation)){let Y={receiptId:G,operationId:_,generation:J},q=P?.status==="complete"||C?.canReselect===!0;return e.observePurchase({scope:l.scope,runId:l.run.id,funnelId:l.run.source.id,versionId:l.run.source.versionId},Y,q).then(()=>{t.assertCurrent(m),q?a?.operationId===Y.operationId&&(a=void 0):a=Y})}},stop(){i=!0},submit:N,executePending:F,settle:c,reset(){s=null,g=null,o.close=null,r=!1,o.command=null}}}function wn(n){if(n={...n},typeof n.runToken!="string"||!/^gg_fr_[A-Za-z0-9_-]{43}$/.test(n.runToken))throw new p("INVALID_TOKEN","Run credential required");if(n.serverKey&&(typeof window<"u"||!/^gg_sk_[A-Za-z0-9_-]{32,128}$/.test(n.serverKey)))throw new p("SERVER_ONLY","Run Server-Key proof belongs to the merchant backend");let e=re({...n,...n.serverKey?{fetch:(c,y)=>{let l=new Headers(y?.headers),m=typeof y?.body=="string"?JSON.parse(y.body):null;return m!==null&&typeof m=="object"&&"customerToken"in m&&typeof m.customerToken=="string"&&m.customerToken.length>0||l.set(Ze,n.serverKey),(n.fetch??globalThis.fetch)(c,{...y,headers:l})}}:{},timeoutMs:n.timeoutMs??35e3});e.identify(n.runToken);let t=pn(n.funnelId),d=null,s=n.funnelCommandStorage??(typeof window<"u"&&window.isSecureContext?ln(n):void 0),g=s&&fn(s),i=gn({options:n,journal:g,state:t,call:o});async function o(c,y,l){let m=t.generation,S=()=>t.assertCurrent(m);g&&await i.ready,S();let R=t.view,C=ge.parse(await ye(n,await e.request("funnels",z.parse(c))));if(c.operation==="review"&&!C.review)throw new p("INVALID_RESPONSE","Historical projection is missing");if(S(),C.runToken&&C.runToken!==n.runToken)throw new p("INVALID_RESPONSE","Run credential changed");let P=c.operation==="get"?c.settlementRequestId:"requestId"in c&&c.operation!=="start"?c.requestId:void 0;if(P&&C.settlement?.requestId!==P)throw new p("INVALID_RESPONSE","Exact command settlement is missing or belongs to another command");i.assertBinding(C),t.assertRun(C.run);let T=i.observePurchase(c,C,m,l);if(T&&await T,!C.run.stopped&&["running","waiting"].includes(C.run.status)&&c.operation==="get"&&c.settlementRequestId)return C;let _=y?.(C),G=typeof _=="boolean"?_:_?await _:!1;return S(),["running","waiting"].includes(C.run.status)||i.stop(),t.publish(c,C,R,l,G),C}let r=i.submit,a=null,h=new WeakMap;function u(c){let y=h.get(c);if(y)return y;let l=N(c);return h.set(c,l),l}let F=!1;async function N(c){let y=await c;if(y.run.instruction?.type!=="evaluate_segment")return y;if(a)return a;F=!0;let l=t.generation,m=(async()=>{for(let S=0;S<32&&y.run.instruction?.type==="evaluate_segment";S++){if(i.pending||i.closeRequested)return y;let R=y.run;if(y.run.instruction?.type==="evaluate_segment"){let{advance:P}=await Fe(n.configuration,R,{predict:!1});if(l!==t.generation)throw new p("IDENTITY_CHANGED","Run identity changed during segment calculation");if(i.pending||i.closeRequested)return y;if(t.view&&(t.view.revision!==R.revision||t.view.visit!==R.visit||t.view.nodeId!==R.nodeId))return o({operation:"get",...t.customerToken?{customerToken:t.customerToken}:{}});let T=!0;Fe(n.configuration,R).then(({prediction:_})=>{T&&l===t.generation&&!i.closeRequested&&t.view?.id===R.id&&!t.view.stopped&&t.view.nodeId===R.nodeId&&t.view.visit===R.visit&&t.view.revision===R.revision&&(d=_)}).catch(()=>{});try{y=await r({operation:"commit_segment",requestId:Ye(R.id,R.visit,`segment:${R.revision}`),nodeId:R.nodeId,visit:R.visit,revision:R.revision,...P})}finally{T=!1,d=null}}}return y})();a=m;try{return await m}finally{a===m&&(a=null)}}let O={get configuration(){return F?n.configuration:void 0},get configurationReady(){return!0},get view(){return t.view?structuredClone(t.view):null},get pendingCommand(){let c=i.closing??i.pending;return c?structuredClone(K(c)):null},get pendingCommands(){return[i.pending,i.closing].filter(c=>c!==null).map(c=>structuredClone(K(c)))},get pendingPurchase(){return i.purchase?structuredClone(i.purchase):null},get prediction(){let c=t.view;return d&&c&&!c.stopped&&["running","waiting"].includes(c.status)&&c.id===d.runId&&c.nodeId===d.from.nodeId&&c.visit===d.from.visit&&c.revision===d.from.revision&&!i.closeRequested?structuredClone(d):null},settle:i.settle,get webViewUrl(){return"bundled"},resolvePaywall(c){return Ie(n,c)},review(c){return o({operation:"review",...c?{receiptId:c}:{},...t.customerToken?{customerToken:t.customerToken}:{}},void 0,t.nextRead())},async get(c,y){g&&await i.ready,y??=i.purchase&&{receiptId:i.purchase.receiptId,operationId:i.purchase.operationId};let l=t.nextRead();return u(o({operation:"get",...c?{data:c}:{},...y?{purchase:y}:{},...t.customerToken?{customerToken:t.customerToken}:{}},void 0,l))},resume(c=t.view?.pendingRequest?.requestId){return c?i.closeRequested?O.settle(c):i.pending?.requestId===c?u(r(i.pending)):u(r({operation:"resume",requestId:c})):Promise.reject(new p("INVALID_REQUEST","No interrupted command is available"))},submit(c){return u(r(c))},retry(){return i.closeFlight?i.closeFlight:i.closing?i.executePending(i.closing):i.closeRequested&&i.pending?O.settle(i.pending.requestId):i.inFlight?u(i.inFlight):i.pending?u(r(i.pending)):Promise.reject(new p("INVALID_REQUEST","No command is pending"))},identify(c){t.identify(c),d=null,e.identify(n.runToken)},subscribe:t.subscribe,reset(){t.reset(),i.reset(),d=null,e.reset()}};return O}async function Et(n,e){if(!/^gg_ct_[A-Za-z0-9_-]{43}$/.test(e.customerToken))throw new p("INVALID_TOKEN","A verified Customer credential is required");let t=re(n);t.identify(e.customerToken);let d=ee.resolvePaywall.request.parse({funnelId:e.funnelId,funnelVersionId:e.funnelVersionId,selector:e.paywallVersionId?{type:"version",versionId:e.paywallVersionId}:{type:"paywall",paywallId:e.paywallId},commerce:e.commerce,locale:e.locale,...e.requirement?{requirement:e.requirement}:{}}),s=null,g=!1,i=null,o=null,r=null,a=null;async function h(){if(g)throw new p("IDENTITY_CHANGED","Paywall is closed");let N=ee.resolvePaywall,O=await we(t.request,N,{...d,selector:s?{type:"version",versionId:s.id}:d.selector}),c={paywall:await Ie(n,O.paywall)};if(g)throw new p("IDENTITY_CHANGED","Paywall is closed");if(e.paywallVersionId?c.paywall.id!==e.paywallVersionId:c.paywall.paywallId!==e.paywallId)throw new p("INVALID_RESPONSE","The requested Paywall changed");if(s&&(!on(c.paywall,s)||c.paywall.paywallId!==s.paywallId))throw new p("INVALID_RESPONSE","The pinned Paywall or Offering Version changed");return s=c.paywall,structuredClone(s)}async function u(N){if(!i)throw new p("INVALID_REQUEST","A quoted purchase is required");let O=N==="read"?ee.readSubscriptionOperation:ee.attach,c=await we(t.request,O,{operationId:i.operationId,...N==="read"?{}:{intent:N}});return an(c.operation,{operationId:i.operationId,currency:d.commerce.currency},"The purchase operation changed"),o=un(o,c.operation),structuredClone(o)}let F={get view(){return s?structuredClone(s):null},get quote(){return i?structuredClone(i):null},get operation(){return o?structuredClone(o):null},get webViewUrl(){return"bundled"},refresh:h,async preview(N){if(!s)throw new p("INVALID_REQUEST","Load the Paywall first");let O=s.document.buttons[N.actionId];if(O?.type!=="checkout")throw new p("INVALID_REQUEST","Choose an authored purchase action");let c=Me(O.product,N.selection,s.capabilities);if(!c)throw new p("PRODUCT_UNAVAILABLE","Choose an available Product");let y=ee.previewAttach.request.parse({funnelId:d.funnelId,funnelVersionId:d.funnelVersionId,requestId:N.requestId,plans:[{productVersionId:c}],provider:d.commerce.provider,currency:d.commerce.currency,...N.offerId?{offerId:N.offerId}:{},...N.nativeOffer?{nativeOffer:N.nativeOffer}:{}}),l=JSON.stringify(y);if(r&&r!==l&&(!o||o.status==="pending"))throw new p("COMMAND_PENDING","Finish or cancel the original purchase before changing it");if(r===l){if(a)return a;if(i)return structuredClone(i)}r=l;let m=(async()=>{let S=ee.previewAttach,R=await we(t.request,S,y);return sn(R.quote,{productVersionId:c,currency:d.commerce.currency,provider:d.commerce.provider},"The purchase quote changed its selected Product or presentment"),i=R.quote,o=null,structuredClone(i)})();a=m;try{return await m}finally{a===m&&(a=null)}},confirm:()=>u("confirm"),cancel:()=>u("cancel"),read:()=>u("read"),destroy(){g=!0,t.reset(),s=null,i=null,o=null,r=null}};return await h(),F}import{z as Nn}from"zod";import{z as ue}from"zod";var Fn=ue.record(ue.string().regex(/^[a-f0-9]{64}$/),ue.strictObject({at:ue.number(),text:ue.string()})),yn=2*1048576,En=100;function An(){try{return typeof window>"u"?void 0:window.localStorage}catch{return}}function hn(n,e){let t=e===void 0?An():e,d=Promise.resolve();async function s(i){if(!t)return null;let o;try{return await Promise.race([Promise.resolve().then(()=>t.getItem(i)),new Promise(r=>{o=setTimeout(()=>r(null),En)})])}catch{return null}finally{clearTimeout(o)}}async function g(){try{let i=await s(`${n}:artifacts`);if(i&&i.length<=yn)return Fn.parse(JSON.parse(i))}catch{}return{}}return{async readManifest(){return s(n)},writeManifest(i){Promise.resolve().then(()=>t?.setItem(n,i)).catch(()=>{})},async readArtifact(i){let o=(await g())[i];return o&&Date.now()>=o.at&&Date.now()-o.at<=U.retentionMs?o.text:void 0},writeArtifact(i,o){t&&(d=d.catch(()=>{}).then(async()=>{let r=await g(),a=Date.now();r[i]={at:a,text:o};let h={},u=2,F=0;for(let[N,O]of Object.entries(r).sort(([,c],[,y])=>y.at-c.at)){if(O.at>a||a-O.at>U.retentionMs)continue;let c=new TextEncoder().encode(JSON.stringify({[N]:O})).byteLength;u+c>yn||F>=128||(h[N]=O,u+=c,F++)}await t.setItem(`${n}:artifacts`,JSON.stringify(h))}).catch(()=>{}))}}}var b=(n,e)=>new p(n,e),Q=()=>performance.now(),In=n=>{typeof n=="object"&&"unref"in n&&n.unref()};function Mt(n){let e=Be.parse(n.scope),t=new URL(n.origin??te);if(t.username||t.password||t.search||t.hash||t.pathname!=="/"||t.protocol!=="https:"&&!(t.protocol==="http:"&&["localhost","127.0.0.1","[::1]"].includes(t.hostname)))throw b("INVALID_URL","Configuration requires a trusted HTTPS origin");let d=new Set([t.origin,...(n.assetOrigins??[]).map(w=>{let f=new URL(w);if(f.protocol!=="https:"||f.username||f.password||f.search||f.hash||f.pathname!=="/")throw b("INVALID_URL","Invalid configuration asset origin");return f.origin})]),s=n.fetch??globalThis.fetch.bind(globalThis),g=`/api/v1/configuration/${e.environmentId}`,i=`indiana:configuration:1:${t.origin}:${L(e)}`,o=hn(i,n.storage),r,a=0,h=0,u=!1,F=!1,N=0,O=0,c,y,l,m,S=0,R=new Set,C=new Set,P=new Map,T=new Map,_=0,G=!1;function J(){for(let w of R)try{w()}catch{}}function Y(w){try{n.onError?.(w)}catch{}}let q=()=>!F&&!u&&!!r&&Q()<a&&Date.now()<h;function Z(){if(!q())throw b("CONFIGURATION_EXPIRED","Refresh configuration before using it")}function Ee(w,f){let I=new TextEncoder().encode(f).byteLength;if(!P.has(w)){for(;P.size&&(P.size>=128||_+I>U.maxCacheBytes);){let v=P.entries().next().value;_-=new TextEncoder().encode(v[1]).byteLength,P.delete(v[0])}P.set(w,f),_+=I}}function Ae(w,f,I){return cn(w,f,{signal:I,error:v=>b("INVALID_RESPONSE",v==="missing"?"Configuration body is missing":"Configuration exceeds its byte limit")})}function Ne(w){let f=new URL(w,t);if(!d.has(f.origin)||f.username||f.password||f.hash||f.search)throw b("INVALID_URL","Configuration artifact origin is not trusted");return f.href}async function Re(w,f,I=!1){let v=await s(Ne(w),{method:"GET",credentials:"omit",redirect:"error",cache:I?"default":"no-cache",signal:f,headers:{}});if(v.status===429){let E=v.headers.get("retry-after")??"";S=/^\d+$/.test(E)?Number(E)*1e3:Math.max(0,Date.parse(E)-Date.now())||15e3}if(!v.ok&&v.status!==304)throw b(`CONFIGURATION_HTTP_${v.status}`,"Configuration synchronization failed");return v}function Rn(w,f,I){let v=Date.parse(w.headers.get("x-indiana-config-validated-at")??""),E=Date.parse(w.headers.get("x-indiana-config-valid-until")??""),D=Date.parse(w.headers.get("date")??""),A=w.headers.get("age"),M=A!==null&&/^\d+(\.\d+)?$/.test(A)?Number(A)*1e3:NaN;if(![v,E,D,M].every(Number.isFinite)||E<=v||E-v>U.maxControlAgeMs||v>D+1e3)throw b("INVALID_RESPONSE","Configuration freshness evidence is invalid");let x=Math.min(E-v,I.maxControlAgeSeconds*1e3,U.maxControlAgeMs)-Math.max(M,D-v,0)-(Q()-f);if(x<=0)throw b("CONFIGURATION_EXPIRED","Configuration validation expired in transit");return Q()+x}function Ce(){if(clearTimeout(l),clearTimeout(m),F||!R.size)return;q()&&(m=setTimeout(()=>{q()?Ce():J()},Math.max(1,a-Q())),In(m));let w=O?Math.min(15e3,1e3*2**Math.min(O-1,4)):Math.min(15e3,(r?.policy.refreshIntervalSeconds??15)*1e3);l=setTimeout(()=>{ne().catch(Y)},Math.max(S,w*(.8+Math.random()*.2))),In(l)}async function ne(){if(F)throw b("CONFIGURATION_DISPOSED","Configuration manager was destroyed");if(c)return c;let w=N,f=new AbortController;y=f;let I=(async()=>{if(!G){G=!0;try{let me=await o.readManifest();if(me&&!r){let j=Se.parse(JSON.parse(me));L(j.scope)===L(e)&&(r=j)}}catch{}}f.signal.throwIfAborted();let A=r,M=Q(),V=await Re(g,f.signal);V.status===304&&(!A||!V.headers.has("x-indiana-config-validated-at")||!V.headers.has("x-indiana-config-valid-until")||!V.headers.has("age"))&&(V=await Re(g,f.signal));let x=V.status===304?A:Se.parse(JSON.parse(await Ae(V,U.maxManifestBytes,f.signal))),{generation:H,...$}=x,W=V.headers.get("etag");if(L(x.scope)!==L(e)||ze($)!==H||W!==`"${H}"`&&W!==`W/"${H}"`)throw b("INVALID_RESPONSE","Configuration scope or content identity changed");if(A&&(x.revision<A.revision||x.revision===A.revision&&x.generation!==A.generation))throw b("INVALID_RESPONSE","Configuration revision moved backwards or changed identity");for(let[me,j]of Object.entries(A?.funnels??{})){let X=x.funnels[me];if(X&&(X.controlRevision<j.controlRevision||X.evaluationRevision<j.evaluationRevision||X.controlRevision===j.controlRevision&&X.state!==j.state||X.evaluationRevision===j.evaluationRevision&&X.evaluationMode!==j.evaluationMode))throw b("INVALID_RESPONSE","Funnel control revision changed identity")}let xe=Rn(V,M,x.policy);if(f.signal.throwIfAborted(),w!==N)throw b("CONFIGURATION_DISPOSED","Configuration scope changed");return r=x,a=xe,h=Date.now()+Math.max(0,xe-Q()),u=!1,O=0,S=0,o.writeManifest(L(x)),J(),structuredClone(x)})(),v=setTimeout(()=>f.abort(b("CONFIGURATION_UNAVAILABLE","Configuration initialization timed out")),U.initializationMs),E=new Promise((A,M)=>f.signal.addEventListener("abort",()=>M(f.signal.reason),{once:!0})),D=Promise.race([I,E]).catch(A=>{throw O++,(A instanceof Nn.ZodError||A instanceof SyntaxError||A instanceof p&&["CONFIGURATION_HTTP_404","CONFIGURATION_HTTP_410","INVALID_RESPONSE"].includes(A.code))&&(a=0,u=!0,J()),A}).finally(()=>{clearTimeout(v),c===D&&(c=void 0),Ce()});return c=D,D}async function le(w){let f=w.sha256,I=H=>he(H,w);Ne(w.url);let v=P.get(f);if(v&&I(v))return P.delete(f),P.set(f,v),v;if(T.has(f))return T.get(f);let E=new AbortController;C.add(E);let D=N,A=(async()=>{try{let W=await o.readArtifact(f);if(W&&I(W))return Ee(f,W),W}catch{}E.signal.throwIfAborted();let H=await Re(w.url,E.signal,!0),$=await Ae(H,w.byteLength,E.signal);if(!I($))throw b("INVALID_RESPONSE","Configuration artifact digest or size mismatch");if(F||D!==N)throw b("CONFIGURATION_DISPOSED","Configuration scope changed");return Ee(f,$),o.writeArtifact(f,$),$})(),M=setTimeout(()=>E.abort(b("CONFIGURATION_UNAVAILABLE","Configuration artifact timed out")),U.initializationMs),V=new Promise((H,$)=>E.signal.addEventListener("abort",()=>$(E.signal.reason),{once:!0})),x=Promise.race([A,V]).finally(()=>{clearTimeout(M),C.delete(E),T.delete(f)});return T.set(f,x),x}async function ce(){return q()||await ne(),Z(),r}async function ie(w){let f,I=new Promise((v,E)=>{f=setTimeout(()=>E(b("CONFIGURATION_UNAVAILABLE","Configuration initialization timed out")),U.initializationMs)});try{return await Promise.race([w(),I])}finally{clearTimeout(f)}}function ae(w,f){if(Z(),r?.generation!==w.generation)throw b("CONFIGURATION_CHANGED","Configuration changed while preparing a snapshot");if(f&&r.funnels[f]?.state!=="active")throw b("FUNNEL_STOPPED","Funnel is paused or unavailable")}async function Oe(w){let f=w.gb.features;if(!f)throw b("CONFIGURATION_UNAVAILABLE","Public Feature delivery is disabled");let I=w.artifacts[f];if(I.formatVersion!==1)throw b("UNSUPPORTED_SCHEMA","Unsupported public GB configuration format");let v=qe.parse(JSON.parse(await le(I)));if(L(v.scope)!==L({projectId:e.projectId,environment:e.environment})||v.generation!==I.generation||v.remoteFeatures.some(E=>Object.hasOwn(v.features,E)))throw b("INVALID_RESPONSE","Public GB configuration scope or generation is invalid");return ae(w),{...v,evaluatedAt:new Date().toISOString(),expiresAt:new Date(Date.now()+Math.max(0,a-Q())).toISOString()}}async function Te(w,f){let I=await ce(),v=I.funnels[w];f&&(!v||v.evaluationMode==="local"&&!v.versions[f])&&(c&&await c,I=await ne()),ae(I,w);let E=I.funnels[w];if(E.evaluationMode!=="local")throw b("EVALUATION_MODE","This Funnel executes at Indiana; public graph loading is disabled");let D=f??E.currentVersionId,A=E.versions[D];if(!A)throw b("CONFIGURATION_UNAVAILABLE","Pinned Funnel Version is unavailable");if(I.artifacts[A.artifact].formatVersion!==3)throw b("UNSUPPORTED_SCHEMA","Unsupported public Funnel format");let[M,V]=await Promise.all([le(I.artifacts[A.artifact]).then(x=>$e(JSON.parse(x))),E.evaluationMode==="local"?Oe(I):void 0]);if(V&&L(He(M,V))!==L(A.dependencies))throw b("INVALID_RESPONSE","Funnel and GB dependency contract do not match");return ae(I,w),{document:M,growth:V,versionId:D,control:structuredClone(E),manifest:structuredClone(I)}}async function _e(w,f){try{return await Te(w,f)}catch(I){if(!(I instanceof p)||!(I.code==="CONFIGURATION_CHANGED"||I.code==="CONFIGURATION_HTTP_404"&&q()))throw I;let v=r?.generation;if(c&&await c,await ne(),I.code!=="CONFIGURATION_CHANGED"&&r?.generation===v)throw I;return Te(w,f)}}function be(){u=!0,J(),ne().catch(Y)}let de=()=>{(typeof document>"u"||document.visibilityState==="visible")&&be()};function Cn(w){if(F)throw b("CONFIGURATION_DISPOSED","Configuration manager was destroyed");return R.add(w),R.size===1&&(typeof window<"u"&&(window.addEventListener("online",be),window.addEventListener("focus",de),document.addEventListener("visibilitychange",de)),Ce()),()=>{R.delete(w),R.size||(clearTimeout(l),clearTimeout(m),De())}}function De(){typeof window<"u"&&(window.removeEventListener("online",be),window.removeEventListener("focus",de),document.removeEventListener("visibilitychange",de))}return{scope:Object.freeze({...e}),refresh:ne,subscribe:Cn,assertFresh:Z,assertFeatures(w){Z();let f=r.gb.features;if(!f)throw b("CONFIGURATION_UNAVAILABLE","Public Feature delivery is disabled");if(w!==void 0&&r.artifacts[f].generation!==w)throw b("CONFIGURATION_CHANGED","Refresh changed Feature configuration before evaluation")},get fresh(){return q()},get snapshot(){return r?structuredClone(r):null},get remainingMs(){return q()?Math.max(0,a-Q()):0},async features(){return ie(async()=>Oe(await ce()))},pageExperiments:()=>ie(async()=>{let w=await ce(),f=w.gb.pageExperiments;if(!f)throw b("CONFIGURATION_UNAVAILABLE","Public page experiments are disabled");let I=w.artifacts[f];if(I.formatVersion!==1)throw b("UNSUPPORTED_SCHEMA","Unsupported page experiment format");let v=en.parse(JSON.parse(await le(I)));if(v.environmentId!==e.environmentId||v.generation!==I.generation)throw b("INVALID_RESPONSE","Page experiment scope or generation changed");return ae(w),v}),funnel:(w,f)=>ie(()=>_e(w,f)),paywall:(w,f)=>ie(async()=>{let I=await ce(),v=I.paywalls?.[w];if(!v||!f&&v.state!=="published")throw b("PAYWALL_UNAVAILABLE","Published Paywall is unavailable");let E=f??v.currentVersionId,D=v.versions[E],A=D&&I.artifacts[D.artifact];if(!A||A.kind!=="paywall"||A.formatVersion!==1)throw b("UNSUPPORTED_SCHEMA","Public Paywall format is unavailable");let M=Je.parse(JSON.parse(await le(A)));return ae(I),{document:M,versionId:E,version:D.version,control:structuredClone(v),manifest:structuredClone(I)}}),async localFunnel(w,f){let I=await ie(()=>_e(w,f));if(!I.growth)throw b("EVALUATION_MODE","This Funnel requires remote execution");let{analyticsConfig:v,remoteFeatures:E,...D}=I.growth;return Xe({scope:{projectId:e.projectId,environment:e.environment},funnelId:w,versionId:I.versionId,evaluationMode:"local",evaluationRevision:I.control.evaluationRevision,document:I.document,payload:D})},assertFunnel(w,f,I){Z();let v=r.funnels[w];if(!v||v.state!=="active")throw b("FUNNEL_STOPPED","Funnel is paused or unavailable");if(v.evaluationMode!=="local")throw b("EVALUATION_MODE","This Funnel now executes at Indiana");if(f!==void 0&&v.controlRevision!==f)throw b("RUN_RECONCILIATION_REQUIRED","Reconcile the original Run after a control change");if(I!==void 0&&!v.versions[I])throw b("CONFIGURATION_UNAVAILABLE","Pinned Funnel Version is unavailable")},destroy(){if(!F){F=!0,N++,a=0,y?.abort(b("CONFIGURATION_DISPOSED","Configuration manager was destroyed")),clearTimeout(l),clearTimeout(m),De(),J(),R.clear();for(let w of C)w.abort(b("CONFIGURATION_DISPOSED","Configuration manager was destroyed"));P.clear(),_=0}}}}function Jt(n,e,t){return tn(n,e,t,se)}function vn(n){let e=/^gg_ct_[A-Za-z0-9_-]{32,128}$/.test(n.apiKey);if(typeof window<"u"&&!e)throw new p("SERVER_ONLY","Funnel starts are issued by your backend");if(!e&&!/^gg_sk_[A-Za-z0-9_-]{32,128}$/.test(n.apiKey))throw new p("INVALID_TOKEN","A customer credential or server API key is required");let t=re({...n,timeoutMs:n.timeoutMs??35e3});return t.identify(n.apiKey),{async start(d){let s=z.safeParse({...d,operation:"start"});if(!s.success||s.data.operation!=="start"||(e?s.data.customer!==void 0:s.data.customer===void 0))throw new p("INVALID_REQUEST","Invalid current Funnel start");let g=s.data,i=ge.safeParse(await ye(n,await t.request("funnels",g)));if(!i.success||!i.data.runToken)throw new p("INVALID_RESPONSE","Funnel start credentials are missing");let o=i.data;if(o.run.source.id!==g.funnelId||o.run.locale!==(g.locale??"en")||!oe(o.run.parameters,g.parameters??{})||(g.customer?!o.customerId||g.customer.type==="id"&&o.customerId!==g.customer.value:o.customerId!==void 0))throw new p("INVALID_RESPONSE","Funnel start contract changed");return{...o,runToken:o.runToken}}}}async function Xt(n){n={...n};let e=n.configuration;if(!e)throw new p("CONFIGURATION_UNAVAILABLE","Local conditions require public configuration");let t={projectId:e.scope.projectId,environment:e.scope.environment};if(n.scope&&L(t)!==L(n.scope))throw new p("SCOPE_MISMATCH","Configuration and transport scopes differ");if((await e.funnel(n.funnelId)).control.evaluationMode!=="local")throw new p("EVALUATION_MODE","This Funnel uses Remote evaluation");let s=/^gg_sk_[A-Za-z0-9_-]{32,128}$/.test(n.credential);if(s?!n.customerId:n.customerId!==void 0)throw new p("INVALID_REQUEST","Only Server-Key starts name their Customer");let g=vn({...n,scope:t,apiKey:n.credential}),i=o=>{let r=wn({...n,scope:t,runToken:o,...s?{serverKey:n.credential}:{}});return s||r.identify(n.credential),r};return{async start(o){let r=await g.start({...o,funnelId:n.funnelId,...s?{customer:{type:"id",value:n.customerId}}:{}}),a=i(r.runToken),h=await a.get();return{...r,...h,controller:a}},async restore(o){let r=i(o),a=await r.get();if(a.run.source.id!==n.funnelId)throw r.reset(),new p("SCOPE_MISMATCH","Run belongs to another Funnel");return{...a,runToken:o,controller:r}}}}export{Tn as a,ye as b,se as c,$n as d,Sn as e,ln as f,rt as g,oe as h,wn as i,Et as j,Mt as k,Jt as l,vn as m,Xt as n};
@@ -1 +1 @@
1
- import{Ki as N,f as U,h as j,i as x,j as R,k,n as F}from"./chunk-ZT66RIFU.js";import{a as r}from"./chunk-SOQO2RDZ.js";import{b as H}from"./chunk-OBYJWIRB.js";var T=s=>{if(!Number.isSafeInteger(s)||s<0||s>=Number.MAX_SAFE_INTEGER)throw new r("INVALID_STATE","Installation sequence exhausted");return s+1},G=async s=>[...new Uint8Array(await crypto.subtle.digest("SHA-256",Uint8Array.from(s,p=>p.charCodeAt(0))))].map(p=>p.toString(16).padStart(2,"0")).join("");function w(s,p){return s.transaction(l=>{if(!Number.isSafeInteger(l.identitySeq)||l.identitySeq<0||!Number.isSafeInteger(l.addressSeq)||l.addressSeq<0||l.detachSeq!==null&&(!Number.isSafeInteger(l.detachSeq)||l.detachSeq<1||l.detachSeq>l.identitySeq))throw new r("INVALID_STATE","Installation journal is invalid");return p({...l})})}function K(s,p,l){let P=null,S=0,h=0,I=0,L=Promise.resolve();if(s&&(!l||H.parse(s.scope).projectId!==l.projectId||s.scope.environment!==l.environment))throw new r("SCOPE_MISMATCH","Push installation belongs to another scope");let y=()=>{if(!s)throw new r("NOT_CONFIGURED","Configure this client's native Push host first");return s},d=e=>{if(e!==S)throw new r("IDENTITY_CHANGED","Identity changed during Push operation")};async function D(e){let t=y();if(!t.sha256&&!globalThis.crypto?.subtle)throw new r("NOT_CONFIGURED","Configure native SHA-256 for this Push host");let n=t.sha256?await t.sha256(Uint8Array.from(e,i=>i.charCodeAt(0))):await G(e);if(!/^[a-f0-9]{64}$/.test(n))throw new r("INVALID_STATE","Push credential digest is invalid");return n}function v(e){let t=k.parse(e);if(t.installationId.toLowerCase()!==y().installationId.toLowerCase())throw new r("INVALID_RESPONSE","Push response belongs to another installation");return t}async function E(e,t){let n=y(),i={installationId:n.installationId,publicKey:n.publicKey,issuedAt:new Date().toISOString(),...t},o=await n.sign(F(e,n.scope,i));return{...i,signature:o}}async function _(){let e=y(),t=S,n=P,i=w(e,u=>u),o;if(i.detachSeq!==null){let u=i.detachSeq,O=U.parse(await E("detach",{sequence:u,platform:e.platform}));try{let a=await p.request("push/installations/detach",{...e.scope,...O},"POST",{installationDetach:!0});if(!a||typeof a!="object"||!("installation"in a))throw new r("INVALID_RESPONSE","Push detach acknowledgement is invalid");let f=v(a.installation);if(f.bound||f.identitySeq!==u)throw new r("INVALID_RESPONSE","Push detach acknowledgement does not match its intent")}catch(a){if(a instanceof r&&a.status===404)o=a;else if(!(a instanceof r)||a.status!==412)throw a}o||w(e,a=>({...a,detachSeq:a.detachSeq===u?null:a.detachSeq}))}if(d(t),!n){if(o)throw o;return null}let c=N.bindPushInstallation,q=c.request.parse(await E("bind",{sequence:I,platform:e.platform,credentialDigest:await D(n)}));d(t);let m=c.response.parse(await p.request(c.path,q));d(t);let g=v(m.installation);if(!g.bound||g.identitySeq!==I)throw new r("INVALID_RESPONSE","Push binding acknowledgement does not match its intent");return o&&i.detachSeq!==null&&I>i.detachSeq&&w(e,u=>({...u,detachSeq:u.detachSeq===i.detachSeq?null:u.detachSeq})),g}async function C(){y();let e=S,t=P;if(!t)throw new r("NOT_IDENTIFIED","Identify before reading this installation");let n=N.readPushInstallation,i=n.request.parse(await E("read",{credentialDigest:await D(t)}));d(e);let o=n.response.parse(await p.request(n.path,i));return d(e),v(o.installation)}function A(e=_){let t=L.catch(()=>{}).then(e);return L=t,t.catch(n=>{try{s?.onError?.(n instanceof Error?n:new Error("Push synchronization failed"))}catch{}}),t}async function V(e,t,n){let i=y(),o=t.identity,c=t.observation,q=P;if(d(o),c!==h)throw new r("INVALID_STATE","Push observation changed during recovery");if(!q)throw new r("NOT_IDENTIFIED","Identify before recovering a Push address");if(!e.connectionId||!e.kind||!e.token||!["granted","provisional"].includes(e.permission))throw new r("INVALID_REQUEST","Recovery needs a provider token and notification permission");return await A(async()=>{if(d(o),await _(),d(o),c!==h)throw new r("INVALID_STATE","Push observation changed during recovery");let m=w(i,f=>n?f:{...f,addressSeq:T(f.addressSeq)}),u=await E(n?"recovery_confirm":"recovery_request",{...e,sequence:m.addressSeq,credentialDigest:await D(q),...n?{challenge:n}:{}}),O=n?x.parse(u):j.parse(u);if(d(o),c!==h)throw new r("INVALID_STATE","Push observation changed during recovery");let a=await p.request(`push/installations/recovery/${n?"confirm":"request"}`,O);if(d(o),c!==h||w(i,f=>f).addressSeq!==m.addressSeq)throw new r("INVALID_STATE","Push observation changed during recovery");if(n){let f=N.updatePushAddress.response.parse(a),b=v(f.installation);if(!b.bound||b.identitySeq!==I||b.addressSeq!==m.addressSeq||b.connectionId!==e.connectionId||b.addressStatus!=="active")throw new r("INVALID_RESPONSE","Push recovery acknowledgement does not match its intent");return b}if(!a||typeof a!="object"||!("recovery"in a))throw new r("INVALID_RESPONSE","Push recovery acknowledgement is invalid");return R.parse(a.recovery)})}return{recoveryObserver(){y();let e={identity:S,observation:++h};return{async request(t){return R.parse(await V(t,e))},async confirm(t,n){return k.parse(await V(n,e,t))}}},identify(e){if(!s)return;I=w(s,n=>({...n,identitySeq:T(n.identitySeq)})).identitySeq,P=e,S++,h++},reset(){if(s)try{w(s,e=>{let t=T(e.identitySeq);return{...e,identitySeq:t,detachSeq:t}})}finally{P=null,S++,h++}},start(){s&&A()},async sync(){return await A()},read:C,async recover(){let e=y(),t=S,n=I;return h++,await A(async()=>{d(t);let i=await C();return d(t),I=w(e,c=>{if(c.identitySeq!==n)throw new r("IDENTITY_CHANGED","A newer installation intent exists");return{...c,identitySeq:T(Math.max(c.identitySeq,i.identitySeq)),addressSeq:Math.max(c.addressSeq,i.addressSeq)}}).identitySeq,await _()})},tokenObserver(){y();let e=++h,t=S;return async n=>{if(e!==h||t!==S)return null;let i=y(),o=P;if(!o)throw new r("NOT_IDENTIFIED","Identify before registering a Push token");if(await A(),d(t),e!==h)return null;let c=w(i,u=>({...u,addressSeq:T(u.addressSeq)})),q=N.updatePushAddress,m=q.request.parse(await E("address",{...n,sequence:c.addressSeq,credentialDigest:await D(o)}));if(d(t),e!==h)return null;let g=q.response.parse(await p.request(q.path,m));return d(t),v(g.installation)}}}}export{K as a};
1
+ import{Yi as N,f as U,h as j,i as x,j as R,k,n as F}from"./chunk-EJTBSGLV.js";import{a as r}from"./chunk-SOQO2RDZ.js";import{b as H}from"./chunk-OBYJWIRB.js";var T=s=>{if(!Number.isSafeInteger(s)||s<0||s>=Number.MAX_SAFE_INTEGER)throw new r("INVALID_STATE","Installation sequence exhausted");return s+1},G=async s=>[...new Uint8Array(await crypto.subtle.digest("SHA-256",Uint8Array.from(s,p=>p.charCodeAt(0))))].map(p=>p.toString(16).padStart(2,"0")).join("");function w(s,p){return s.transaction(l=>{if(!Number.isSafeInteger(l.identitySeq)||l.identitySeq<0||!Number.isSafeInteger(l.addressSeq)||l.addressSeq<0||l.detachSeq!==null&&(!Number.isSafeInteger(l.detachSeq)||l.detachSeq<1||l.detachSeq>l.identitySeq))throw new r("INVALID_STATE","Installation journal is invalid");return p({...l})})}function K(s,p,l){let P=null,S=0,h=0,I=0,L=Promise.resolve();if(s&&(!l||H.parse(s.scope).projectId!==l.projectId||s.scope.environment!==l.environment))throw new r("SCOPE_MISMATCH","Push installation belongs to another scope");let y=()=>{if(!s)throw new r("NOT_CONFIGURED","Configure this client's native Push host first");return s},d=e=>{if(e!==S)throw new r("IDENTITY_CHANGED","Identity changed during Push operation")};async function D(e){let t=y();if(!t.sha256&&!globalThis.crypto?.subtle)throw new r("NOT_CONFIGURED","Configure native SHA-256 for this Push host");let n=t.sha256?await t.sha256(Uint8Array.from(e,i=>i.charCodeAt(0))):await G(e);if(!/^[a-f0-9]{64}$/.test(n))throw new r("INVALID_STATE","Push credential digest is invalid");return n}function v(e){let t=k.parse(e);if(t.installationId.toLowerCase()!==y().installationId.toLowerCase())throw new r("INVALID_RESPONSE","Push response belongs to another installation");return t}async function E(e,t){let n=y(),i={installationId:n.installationId,publicKey:n.publicKey,issuedAt:new Date().toISOString(),...t},o=await n.sign(F(e,n.scope,i));return{...i,signature:o}}async function _(){let e=y(),t=S,n=P,i=w(e,u=>u),o;if(i.detachSeq!==null){let u=i.detachSeq,O=U.parse(await E("detach",{sequence:u,platform:e.platform}));try{let a=await p.request("push/installations/detach",{...e.scope,...O},"POST",{installationDetach:!0});if(!a||typeof a!="object"||!("installation"in a))throw new r("INVALID_RESPONSE","Push detach acknowledgement is invalid");let f=v(a.installation);if(f.bound||f.identitySeq!==u)throw new r("INVALID_RESPONSE","Push detach acknowledgement does not match its intent")}catch(a){if(a instanceof r&&a.status===404)o=a;else if(!(a instanceof r)||a.status!==412)throw a}o||w(e,a=>({...a,detachSeq:a.detachSeq===u?null:a.detachSeq}))}if(d(t),!n){if(o)throw o;return null}let c=N.bindPushInstallation,q=c.request.parse(await E("bind",{sequence:I,platform:e.platform,credentialDigest:await D(n)}));d(t);let m=c.response.parse(await p.request(c.path,q));d(t);let g=v(m.installation);if(!g.bound||g.identitySeq!==I)throw new r("INVALID_RESPONSE","Push binding acknowledgement does not match its intent");return o&&i.detachSeq!==null&&I>i.detachSeq&&w(e,u=>({...u,detachSeq:u.detachSeq===i.detachSeq?null:u.detachSeq})),g}async function C(){y();let e=S,t=P;if(!t)throw new r("NOT_IDENTIFIED","Identify before reading this installation");let n=N.readPushInstallation,i=n.request.parse(await E("read",{credentialDigest:await D(t)}));d(e);let o=n.response.parse(await p.request(n.path,i));return d(e),v(o.installation)}function A(e=_){let t=L.catch(()=>{}).then(e);return L=t,t.catch(n=>{try{s?.onError?.(n instanceof Error?n:new Error("Push synchronization failed"))}catch{}}),t}async function V(e,t,n){let i=y(),o=t.identity,c=t.observation,q=P;if(d(o),c!==h)throw new r("INVALID_STATE","Push observation changed during recovery");if(!q)throw new r("NOT_IDENTIFIED","Identify before recovering a Push address");if(!e.connectionId||!e.kind||!e.token||!["granted","provisional"].includes(e.permission))throw new r("INVALID_REQUEST","Recovery needs a provider token and notification permission");return await A(async()=>{if(d(o),await _(),d(o),c!==h)throw new r("INVALID_STATE","Push observation changed during recovery");let m=w(i,f=>n?f:{...f,addressSeq:T(f.addressSeq)}),u=await E(n?"recovery_confirm":"recovery_request",{...e,sequence:m.addressSeq,credentialDigest:await D(q),...n?{challenge:n}:{}}),O=n?x.parse(u):j.parse(u);if(d(o),c!==h)throw new r("INVALID_STATE","Push observation changed during recovery");let a=await p.request(`push/installations/recovery/${n?"confirm":"request"}`,O);if(d(o),c!==h||w(i,f=>f).addressSeq!==m.addressSeq)throw new r("INVALID_STATE","Push observation changed during recovery");if(n){let f=N.updatePushAddress.response.parse(a),b=v(f.installation);if(!b.bound||b.identitySeq!==I||b.addressSeq!==m.addressSeq||b.connectionId!==e.connectionId||b.addressStatus!=="active")throw new r("INVALID_RESPONSE","Push recovery acknowledgement does not match its intent");return b}if(!a||typeof a!="object"||!("recovery"in a))throw new r("INVALID_RESPONSE","Push recovery acknowledgement is invalid");return R.parse(a.recovery)})}return{recoveryObserver(){y();let e={identity:S,observation:++h};return{async request(t){return R.parse(await V(t,e))},async confirm(t,n){return k.parse(await V(n,e,t))}}},identify(e){if(!s)return;I=w(s,n=>({...n,identitySeq:T(n.identitySeq)})).identitySeq,P=e,S++,h++},reset(){if(s)try{w(s,e=>{let t=T(e.identitySeq);return{...e,identitySeq:t,detachSeq:t}})}finally{P=null,S++,h++}},start(){s&&A()},async sync(){return await A()},read:C,async recover(){let e=y(),t=S,n=I;return h++,await A(async()=>{d(t);let i=await C();return d(t),I=w(e,c=>{if(c.identitySeq!==n)throw new r("IDENTITY_CHANGED","A newer installation intent exists");return{...c,identitySeq:T(Math.max(c.identitySeq,i.identitySeq)),addressSeq:Math.max(c.addressSeq,i.addressSeq)}}).identitySeq,await _()})},tokenObserver(){y();let e=++h,t=S;return async n=>{if(e!==h||t!==S)return null;let i=y(),o=P;if(!o)throw new r("NOT_IDENTIFIED","Identify before registering a Push token");if(await A(),d(t),e!==h)return null;let c=w(i,u=>({...u,addressSeq:T(u.addressSeq)})),q=N.updatePushAddress,m=q.request.parse(await E("address",{...n,sequence:c.addressSeq,credentialDigest:await D(o)}));if(d(t),e!==h)return null;let g=q.response.parse(await p.request(q.path,m));return d(t),v(g.installation)}}}}export{K as a};