@tinkerlandai/longplay-sdk 0.10.15 → 0.10.16-rc.1
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.
- package/CHANGELOG.md +6 -0
- package/README.md +13 -15
- package/README.zh-CN.md +14 -16
- package/dist/{ai-usage-C3dCagmQ.d.ts → ai-usage-DejUdb17.d.ts} +1 -1
- package/dist/{api-Cefn6AaL.d.ts → api-RQUBSSEJ.d.ts} +60 -26
- package/dist/{chunk-OZZMZH7X.js → chunk-26HU2HXU.js} +1 -1
- package/dist/{chunk-LUIKKMG5.js → chunk-2KANHIZO.js} +1 -1
- package/dist/{chunk-6RZKX552.js → chunk-6UD36E3L.js} +1 -1
- package/dist/{chunk-TPAQWTO4.js → chunk-BX7QZR2M.js} +1 -1
- package/dist/chunk-EEZLS2YP.js +1 -0
- package/dist/{chunk-VXY2C4AL.js → chunk-EIBEAG5L.js} +1 -1
- package/dist/chunk-EYQ5BRAU.js +1 -0
- package/dist/chunk-GSZRT3I7.js +1 -0
- package/dist/{chunk-VSMITXQD.js → chunk-LC2VUKYM.js} +1 -1
- package/dist/chunk-ML6EHT43.js +10 -0
- package/dist/chunk-N5E55U7R.js +1 -0
- package/dist/chunk-PFHS7HK3.js +17 -0
- package/dist/{chunk-V73OHOTK.js → chunk-RZ7DDZJW.js} +1 -1
- package/dist/chunk-T5COWMDA.js +1 -0
- package/dist/{chunk-RT35MPPD.js → chunk-VQBVZUIU.js} +1 -1
- package/dist/chunk-XJBCPOFT.js +6 -0
- package/dist/{configuration-sync-D2n_gGj6.d.ts → configuration-sync-C2jtm37f.d.ts} +97 -9
- package/dist/{content-WXHCWIUL.js → content-OCAX77JT.js} +1 -1
- package/dist/{funnel-local-client-9U-_hkEE.d.ts → funnel-local-client-P_R6FHVV.d.ts} +7995 -5523
- package/dist/{funnel-node-evaluation-DSSSmXHX.d.ts → funnel-node-evaluation-BLnJp8vj.d.ts} +11 -13
- package/dist/{funnel-process-client-BaHMeArI.d.ts → funnel-process-client-CY-GQ_SF.d.ts} +5498 -4539
- package/dist/funnel-runtime-host-IYOZOE37.js +1 -0
- package/dist/index.d.ts +1258 -273
- package/dist/index.js +1 -1
- package/dist/native-shell.js +1 -1
- package/dist/openrouter.d.ts +3 -3
- package/dist/openrouter.js +1 -1
- package/dist/page.d.ts +2 -2
- package/dist/page.js +1 -1
- package/dist/paywall-AT4PQ6U2.js +1 -0
- package/dist/popup.d.ts +11 -5
- package/dist/popup.js +1 -1
- package/dist/react-native.d.ts +1541 -7
- package/dist/react-native.js +1 -1
- package/dist/{screen-D81zCpfi.d.ts → screen-DRP7nsrQ.d.ts} +613 -357
- package/dist/screen-renderer-IZ3VJGU6.js +1 -0
- package/dist/server.d.ts +717 -9
- package/dist/server.js +1 -1
- package/dist/visual.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-33FQUT3Z.js +0 -179
- package/dist/chunk-E5ECPR6Z.js +0 -1
- package/dist/chunk-LHA6VWP7.js +0 -1
- package/dist/chunk-MOWYD2TV.js +0 -1
- package/dist/chunk-RQZ42NQJ.js +0 -6
- package/dist/chunk-VSJOHWDL.js +0 -17
- package/dist/chunk-XAHWOLRT.js +0 -1
- package/dist/funnel-runtime-host-WQ64FAME.js +0 -1
- package/dist/paywall-H4YN4FTL.js +0 -1
- package/dist/screen-renderer-NHJ6OQTF.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.10.16 — 2026-11-05
|
|
4
|
+
|
|
5
|
+
- Add bounded local display interactions, responsive presentation and brand fonts to the shared screen renderer, including billing controls and catalog-backed quantity sliders.
|
|
6
|
+
- Apply checkout availability consistently to native controls, static HTML and interactive HTML without rewriting authored content or dropping invalid capability data. Preserve live controls and local state across refreshes.
|
|
7
|
+
- Align structural and semantic screen validation across JavaScript, React Native, Swift, Kotlin, Python and Go. Wire protocol stays `0.10`; purchase authorization and runtime execution remain server-owned.
|
|
8
|
+
|
|
3
9
|
## 0.10.15 — 2026-11-04
|
|
4
10
|
|
|
5
11
|
- No API or behavior change from 0.10.14. This is the first release published through a release candidate (`0.10.15-rc.1` on npm `next`) before the stable version. The README describes the `next` and `latest` channels. Wire protocol stays `0.10`.
|
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<p>
|
|
2
|
-
<a href="https://longplayai.com">
|
|
3
|
-
<img src="https://longplayai.com/brand/indiana-mark.png" alt="Longplay" width="72" height="72" />
|
|
2
|
+
<a href="https://www.longplayai.com">
|
|
3
|
+
<img src="https://www.longplayai.com/site/brand/indiana-mark.png" alt="Longplay" width="72" height="72" />
|
|
4
4
|
</a>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
# @tinkerlandai/longplay-sdk
|
|
8
8
|
|
|
9
|
-
This source checkout is SDK 0.10.
|
|
9
|
+
This source checkout is SDK 0.10.14, protocol 0.10. These examples use `https://api.longplayai.com` with a Sandbox App and credentials issued by the production deployment. Sandbox still contains production data; do not reuse credentials from the separate test deployment. Confirm runtime readiness in [environment state](../../docs/development-status.md) before running them.
|
|
10
10
|
|
|
11
11
|
[简体中文](./README.zh-CN.md)
|
|
12
12
|
|
|
@@ -18,9 +18,7 @@ The Longplay business SDK groups its capabilities as **Identity, Commerce, exper
|
|
|
18
18
|
npm install --save-exact @tinkerlandai/longplay-sdk@latest
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
The first install resolves latest and saves an exact package.json version. Commit the lockfile and use npm ci for later builds.
|
|
22
|
-
|
|
23
|
-
IAM Funnel entries and their initial reliability fixes require SDK 0.10.5 or later. Select this release explicitly with `npm install --save-exact @tinkerlandai/longplay-sdk@0.10.5`; current mutable tags are recorded in the [release records](../../docs/sdk-releases.md).
|
|
21
|
+
The first install resolves latest and saves an exact package.json version. Commit the lockfile and use npm ci for later builds. [SDK distribution](../../docs/sdk-releases.md) records package availability; source changes do not publish artifacts. Existing versioned artifacts remain immutable.
|
|
24
22
|
|
|
25
23
|
This SDK requires HTTP protocol 0.10. The runtime must serve the same current protocol; 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).
|
|
26
24
|
|
|
@@ -31,7 +29,7 @@ The data/session layer handles public JSON, integrity checks and authenticated o
|
|
|
31
29
|
The classic-script entry reuses the npm browser implementation, with no bundler:
|
|
32
30
|
|
|
33
31
|
```sh
|
|
34
|
-
SDK_MODULE_URL="$(curl -fsS https://longplayai.com/sdk/module)" &&
|
|
32
|
+
SDK_MODULE_URL="$(curl -fsS https://cdn.longplayai.com/sdk/module)" &&
|
|
35
33
|
printf 'export * from "%s";\n' "$SDK_MODULE_URL" > longplay-sdk.js
|
|
36
34
|
```
|
|
37
35
|
|
|
@@ -57,7 +55,7 @@ printf 'export * from "%s";\n' "$SDK_MODULE_URL" > longplay-sdk.js
|
|
|
57
55
|
</script>
|
|
58
56
|
```
|
|
59
57
|
|
|
60
|
-
Commit the generated longplay-sdk.js to lock the immutable module URL; resolve it again only when upgrading. The optional classic loader at `https://longplayai.com/sdk.js` still follows Web releases and uses matching API/credentials. `Longplay.ready` provides every root browser export plus `createPageExperiments` and `createVisualExperiments`; replace npm imports below with destructuring those names. Loading activates no sessions, events or experiments. Server Keys remain on your backend; Funnel start/recovery and logout cleanup retain the existing contracts. Duplicate tags share readiness, failures reject the Promise and UI loads lazily. With `async`/`defer`, wait for the loader tag's load event before accessing `Longplay`. CSP must allow the script origin and API connections. Page experiments use the same script entry; explicitly create their clients and call `start()`. See [script distribution](../../docs/sdk-architecture.md#web-script-distribution) and [the complete integration example](https://longplayai.com/docs/javascript#script).
|
|
58
|
+
Commit the generated longplay-sdk.js to lock the immutable module URL; resolve it again only when upgrading. The optional classic loader at `https://cdn.longplayai.com/sdk.js` still follows Web releases and uses matching API/credentials. `Longplay.ready` provides every root browser export plus `createPageExperiments` and `createVisualExperiments`; replace npm imports below with destructuring those names. Loading activates no sessions, events or experiments. Server Keys remain on your backend; Funnel start/recovery and logout cleanup retain the existing contracts. Duplicate tags share readiness, failures reject the Promise and UI loads lazily. With `async`/`defer`, wait for the loader tag's load event before accessing `Longplay`. CSP must allow the script origin and API connections. Page experiments use the same script entry; explicitly create their clients and call `start()`. See [script distribution](../../docs/sdk-architecture.md#web-script-distribution) and [the complete integration example](https://www.longplayai.com/docs/sdk/javascript#script).
|
|
61
59
|
|
|
62
60
|
## React Native core
|
|
63
61
|
|
|
@@ -65,7 +63,7 @@ Use the independent `@tinkerlandai/longplay-react-native` package. The `@tinkerl
|
|
|
65
63
|
|
|
66
64
|
## Version compatibility and support
|
|
67
65
|
|
|
68
|
-
During `0.x`, only the current protocol is supported. Starting with `1.0`, compatibility is preserved within each stable major version. Once the next stable major is published, the preceding stable major remains supported for at least 12 calendar months, with at least 180 days' public notice before retirement. The later deadline applies. See the [support policy](https://longplayai.com/docs/
|
|
66
|
+
During `0.x`, only the current protocol is supported. Starting with `1.0`, compatibility is preserved within each stable major version. Once the next stable major is published, the preceding stable major remains supported for at least 12 calendar months, with at least 180 days' public notice before retirement. The later deadline applies. See the [support policy](https://www.longplayai.com/docs/guides/version-support#support-policy).
|
|
69
67
|
|
|
70
68
|
The SDK sends current protocol and SDK version headers and validates the protocol declared by successful responses. Old 0.x protocols are not converted into the current contract. Updating source code does not change an existing npm artifact or deploy a server.
|
|
71
69
|
|
|
@@ -86,7 +84,7 @@ The same package supports JavaScript and TypeScript and includes type declaratio
|
|
|
86
84
|
|
|
87
85
|
For an independent **Page, Popup or Banner resource**, import `createLongplay` and `mountContent` from the root entry, resolve it with `longplay.resolveContent(...)`, then mount the result. `/page` runs GB URL redirect experiments on an existing merchant page; `/visual` applies GB visual changes to that page. `/popup` exposes lower-level screen rendering and preview primitives. Its name does not select or resolve a Popup resource. The public import paths stay unchanged; see [entry ownership](../../docs/sdk-architecture.md#public-entry-points-and-capability-ownership).
|
|
88
86
|
|
|
89
|
-
The separate [Python server SDK](../python/README.md) provides synchronous and asynchronous Customer, holdings, entitlement-check and usage clients against the same current HTTP protocol. It is distributed from `https://longplayai.com/sdk/python` (not PyPI) and is not part of this npm package.
|
|
87
|
+
The separate [Python server SDK](../python/README.md) provides synchronous and asynchronous Customer, holdings, entitlement-check and usage clients against the same current HTTP protocol. It is distributed from `https://cdn.longplayai.com/sdk/python` (not PyPI) and is not part of this npm package.
|
|
90
88
|
|
|
91
89
|
The [Go server SDK](../go/README.md) provides the same initial capabilities with typed responses, Context cancellation and goroutine-safe client reuse. It is installed with `go get longplayai.com/sdk/go` through the default Go module proxy and shares the release version with the other business SDKs.
|
|
92
90
|
|
|
@@ -211,7 +209,7 @@ await process.detach();
|
|
|
211
209
|
|
|
212
210
|
Local execution needs the shared public configuration manager and a published configuration. Login binds the current Run to the account's existing Customer without replacing the Run, answers, history, pinned Version or deadlines. A new account can claim the Guest Customer in place. Another account cannot take over a bound Run; use a new process handle. Commercial assets and historical Customer ownership are preserved.
|
|
213
211
|
|
|
214
|
-
Web IAM hosts opt in with `createIamFunnelProcessEntries`. React Native exports `createFunnelProcess`; Swift and Kotlin expose `LongplayFunnelProcess` and `LongplayFunnelProcessBridge` over the same merchant backend. Native hosts retain their command-storage adapter and presentation session across login. See the [identity contract](../../docs/funnel-customer-get-or-create.md
|
|
212
|
+
Web IAM hosts opt in with `createIamFunnelProcessEntries`. React Native exports `createFunnelProcess`; Swift and Kotlin expose `LongplayFunnelProcess` and `LongplayFunnelProcessBridge` over the same merchant backend. Native hosts retain their command-storage adapter and presentation session across login. See the [identity contract](../../docs/funnel-customer-get-or-create.md#sdk-and-merchant-adapter) for storage, attribution and recovery details.
|
|
215
213
|
|
|
216
214
|
### Bucketing identity across independent consumers
|
|
217
215
|
|
|
@@ -219,7 +217,7 @@ Funnel, standalone Features and page experiments evaluate independently. Matchin
|
|
|
219
217
|
|
|
220
218
|
For Customer-based evaluation, `id` means the Longplay Customer UUID (`customer.id`); `externalUserId` means the merchant account ID (`customer.externalUserId`). Choose the experiment's `hashAttribute` explicitly when creating it and preserve that meaning in every consumer. Do not put the merchant account ID into `attributes.id`. Supply local attributes from your trusted backend's Customer data; `identify(customerToken)` authenticates requests but does not populate local bucketing attributes. These attributes are evaluation data, not authorization.
|
|
221
219
|
|
|
222
|
-
`setAttributes()` replaces the complete object, so retain the bucketing fields on every update. Anonymous page/visual experiments instead default `id` and `deviceId` to the shared first-party device cookie; they do not automatically match an account-based experiment. An open visual client rereads its payload every 60 seconds while visible, so a stopped experiment or disabled delivery reverts without a page reload. Sticky capabilities differ by adapter: managed Local Run instructions receive server state, while pure local tools require their existing host persistence adapter for durable Sticky. No new shared state is introduced. See the [architecture boundary](../../docs/growthbook-sdk-delivery.md
|
|
220
|
+
`setAttributes()` replaces the complete object, so retain the bucketing fields on every update. Anonymous page/visual experiments instead default `id` and `deviceId` to the shared first-party device cookie; they do not automatically match an account-based experiment. An open visual client rereads its payload every 60 seconds while visible, so a stopped experiment or disabled delivery reverts without a page reload. Sticky capabilities differ by adapter: managed Local Run instructions receive server state, while pure local tools require their existing host persistence adapter for durable Sticky. No new shared state is introduced. See the [architecture boundary](../../docs/growthbook-sdk-delivery.md#cross-consumer-evaluation-and-bucketing-identity).
|
|
223
221
|
|
|
224
222
|
### Server-side local Funnel evaluation
|
|
225
223
|
|
|
@@ -273,7 +271,7 @@ unsubscribe();
|
|
|
273
271
|
flags.destroy();
|
|
274
272
|
```
|
|
275
273
|
|
|
276
|
-
The selected environment's integration settings control behavior events, experiment exposures and Feature usage independently. New environments enable
|
|
274
|
+
The selected environment's integration settings control behavior events, experiment exposures and Feature usage independently. New environments enable behavior events, experiment exposures and Feature usage collection. `flush()` includes a `skipped` count for intentionally disabled collection. The database rechecks every batch, including direct SDK/server and Funnel ingestion. Running experiment/Bandit dependencies prevent incompatible collection changes. These controls do not delete history or affect commercial usage accounting.
|
|
277
275
|
|
|
278
276
|
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.
|
|
279
277
|
|
|
@@ -395,7 +393,7 @@ const host = await showFunnelRun(container, {
|
|
|
395
393
|
});
|
|
396
394
|
// Retain started.runToken in your host's secure credential storage.
|
|
397
395
|
// Restore the same Run: await flow.restore(originalRunToken).
|
|
398
|
-
host.destroy(); // Detach UI; accepted backend work
|
|
396
|
+
host.destroy(); // Detach UI; accepted backend work retains its server lifecycle.
|
|
399
397
|
started.controller.reset();
|
|
400
398
|
```
|
|
401
399
|
|
|
@@ -531,4 +529,4 @@ In `record_only` mode your backend owns payment execution, verifies its results
|
|
|
531
529
|
|
|
532
530
|
The Server entry exports `createMerchantBridgeHandler`, `createMerchantBridgeAuthorityResolver`, `signMerchantBridgeMessage` and `verifyMerchantBridgeMessage`. Supply backend signing keys, native authorization/CSRF, implemented capabilities/profiles and typed handlers. Set `resolveOperationAuthority: createMerchantBridgeAuthorityResolver(server)` so every financial/read command obtains fresh Longplay authority from the original operation API. A signed service request still requires confirmation and exact scope/Customer ownership; it cannot issue user sessions.
|
|
533
531
|
|
|
534
|
-
Handlers must durably reserve the original operation before external effects and retain the same provider idempotency key. The SDK's preceding lookup is not a concurrency lock. `operation.read` returns `found` or `not_received` without creating effects. Recover `RESULT_UNKNOWN` through that original operation; never infer permission from a browser quote or `pending`. Console discovery is configuration validation, not commercial completion. See the [merchant specification](https://longplayai.com/docs/merchant-execution) for exact fields and recovery.
|
|
532
|
+
Handlers must durably reserve the original operation before external effects and retain the same provider idempotency key. The SDK's preceding lookup is not a concurrency lock. `operation.read` returns `found` or `not_received` without creating effects. Recover `RESULT_UNKNOWN` through that original operation; never infer permission from a browser quote or `pending`. Console discovery is configuration validation, not commercial completion. See the [merchant specification](https://www.longplayai.com/docs/guides/merchant-execution) for exact fields and recovery.
|
package/README.zh-CN.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<p>
|
|
2
|
-
<a href="https://longplayai.com">
|
|
3
|
-
<img src="https://longplayai.com/brand/indiana-mark.png" alt="Longplay" width="72" height="72" />
|
|
2
|
+
<a href="https://www.longplayai.com">
|
|
3
|
+
<img src="https://www.longplayai.com/site/brand/indiana-mark.png" alt="Longplay" width="72" height="72" />
|
|
4
4
|
</a>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
[English](./README.md)
|
|
8
8
|
|
|
9
|
-
当前源码为 SDK 0.10.
|
|
9
|
+
当前源码为 SDK 0.10.14、协议 0.10。本页示例使用 `https://api.longplayai.com` 以及生产部署内签发的 Sandbox App/凭据。Sandbox 仍属于生产数据,不能复用独立测试部署的凭据。运行前核对[环境状态](../../docs/development-status.md),确认服务已就绪。
|
|
10
10
|
|
|
11
11
|
# @tinkerlandai/longplay-sdk
|
|
12
12
|
|
|
@@ -18,11 +18,9 @@
|
|
|
18
18
|
npm install --save-exact @tinkerlandai/longplay-sdk@latest
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
首次安装解析最新稳定版,--save-exact 将结果固定在 package.json。提交锁文件,后续构建使用 npm ci
|
|
21
|
+
首次安装解析最新稳定版,--save-exact 将结果固定在 package.json。提交锁文件,后续构建使用 npm ci。[SDK 分发](../../docs/sdk-releases.md)记录包版本;源码修改不代表已发布,已有版本产物保持不可变。
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
SDK 0.10.7 要求 HTTP 协议 0.10。服务端须使用同一当前协议,不提供旧协议兼容;发布包不会部署服务端。实际发布、标签与环境验收范围见 [SDK 发布总账](../../docs/sdk-releases.md) 和 [开发状态](../../docs/development-status.md)。
|
|
23
|
+
当前 SDK 要求 HTTP 协议 0.10。服务端须使用同一当前协议,不提供旧协议兼容;发布包不会部署服务端。实际发布、标签与环境验收范围见 [SDK 发布总账](../../docs/sdk-releases.md) 和 [开发状态](../../docs/development-status.md)。
|
|
26
24
|
|
|
27
25
|
数据/会话层负责公开 JSON、完整性校验和鉴权操作;展示宿主将会话接口接入打包的屏幕渲染器,渲染器消费已提供的数据并返回动作意图。客户端按需加载展示;`/server` 入口使用商户后端的受限 Server Key,不加载屏幕展示。SDK 本地检查不替代运行时授权或付款核实。后台 Preview 为同一个展示宿主提供模拟会话和数据。
|
|
28
26
|
|
|
@@ -31,7 +29,7 @@ SDK 0.10.7 要求 HTTP 协议 0.10。服务端须使用同一当前协议,不
|
|
|
31
29
|
普通 script 标签复用 npm 浏览器实现,无需打包工具:
|
|
32
30
|
|
|
33
31
|
```sh
|
|
34
|
-
SDK_MODULE_URL="$(curl -fsS https://longplayai.com/sdk/module)" &&
|
|
32
|
+
SDK_MODULE_URL="$(curl -fsS https://cdn.longplayai.com/sdk/module)" &&
|
|
35
33
|
printf 'export * from "%s";\n' "$SDK_MODULE_URL" > longplay-sdk.js
|
|
36
34
|
```
|
|
37
35
|
|
|
@@ -57,7 +55,7 @@ printf 'export * from "%s";\n' "$SDK_MODULE_URL" > longplay-sdk.js
|
|
|
57
55
|
</script>
|
|
58
56
|
```
|
|
59
57
|
|
|
60
|
-
提交生成的 longplay-sdk.js,即可锁定不可变模块地址;仅在升级时重新解析。经典脚本 `https://longplayai.com/sdk.js` 仍随 Web 发布更新,并配套使用同环境 API 和凭据。`Longplay.ready` 返回根入口的全部浏览器导出,以及 `createPageExperiments` / `createVisualExperiments`;下文 npm import 可替换为从该 Promise 解构同名函数。加载不自动创建会话、发送事件或启动实验。Server Key 留在后端,Funnel 启动恢复与退出清理沿用现有流程。重复标签共用 ready,失败会拒绝 Promise,UI 按需加载。加载标签使用普通 script;添加 async/defer 时先等标签 load 事件,再访问 `Longplay`。CSP 需允许脚本来源和 API 连接。页面实验也使用该统一入口,显式创建客户端并调用 `start()`。详见 [script 分发](../../docs/sdk-architecture.md#web-script-distribution)和[完整接入示例](https://longplayai.com/docs/javascript#script)。
|
|
58
|
+
提交生成的 longplay-sdk.js,即可锁定不可变模块地址;仅在升级时重新解析。经典脚本 `https://cdn.longplayai.com/sdk.js` 仍随 Web 发布更新,并配套使用同环境 API 和凭据。`Longplay.ready` 返回根入口的全部浏览器导出,以及 `createPageExperiments` / `createVisualExperiments`;下文 npm import 可替换为从该 Promise 解构同名函数。加载不自动创建会话、发送事件或启动实验。Server Key 留在后端,Funnel 启动恢复与退出清理沿用现有流程。重复标签共用 ready,失败会拒绝 Promise,UI 按需加载。加载标签使用普通 script;添加 async/defer 时先等标签 load 事件,再访问 `Longplay`。CSP 需允许脚本来源和 API 连接。页面实验也使用该统一入口,显式创建客户端并调用 `start()`。详见 [script 分发](../../docs/sdk-architecture.md#web-script-distribution)和[完整接入示例](https://www.longplayai.com/zh-hans/docs/sdk/javascript#script)。
|
|
61
59
|
|
|
62
60
|
## React Native 核心入口
|
|
63
61
|
|
|
@@ -75,7 +73,7 @@ Flow `commit_segment` 只包含固定 requestId、停车位置 nodeId/visit/
|
|
|
75
73
|
|
|
76
74
|
## 版本兼容与支持
|
|
77
75
|
|
|
78
|
-
当前 0.x 仅支持当前协议;1.0 起同一主版本内保持兼容。新稳定主版本发布后,旧稳定主版本至少继续支持 12 个日历月,停止支持提前至少 180 天公开通知,实际日期取两者中较晚者。详见 [版本与支持政策](../../docs/sdk-versioning-and-support.md) 和公开开发文档 `/docs/
|
|
76
|
+
当前 0.x 仅支持当前协议;1.0 起同一主版本内保持兼容。新稳定主版本发布后,旧稳定主版本至少继续支持 12 个日历月,停止支持提前至少 180 天公开通知,实际日期取两者中较晚者。详见 [版本与支持政策](../../docs/sdk-versioning-and-support.md) 和公开开发文档 `/zh-hans/docs/guides/version-support#support-policy`。
|
|
79
77
|
|
|
80
78
|
SDK 发送当前协议及 SDK 版本请求头,并校验成功响应的协议声明;旧 0.x 协议不会自动转换成当前协议。源码更新不会修改已有 npm 包,也不会自动部署服务端。
|
|
81
79
|
|
|
@@ -96,7 +94,7 @@ JavaScript 与 TypeScript 共用本包,声明文件随包提供。内部 `@ind
|
|
|
96
94
|
|
|
97
95
|
展示独立的 **Page、Popup 或 Banner 资源**,从主入口导入 `createLongplay` 和 `mountContent`,先用 `longplay.resolveContent(...)` 解析,再挂载结果。`/page` 用于商户现有页面的 GB 网址跳转实验,`/visual` 用于该页面的 GB 视觉修改;`/popup` 提供底层屏幕渲染与预览工具,不负责选择或解析 Popup 资源。现有公开导入路径保持不变,详见[入口职责](../../docs/sdk-architecture.md#public-entry-points-and-capability-ownership)。
|
|
98
96
|
|
|
99
|
-
独立的 [Python 服务端 SDK](../python/README.md) 使用同一当前 HTTP 协议,提供同步、异步 Customer、持仓/权益检查和用量上报。它从 `https://longplayai.com/sdk/python` 分发(不在 PyPI),不属于这个 npm 包。
|
|
97
|
+
独立的 [Python 服务端 SDK](../python/README.md) 使用同一当前 HTTP 协议,提供同步、异步 Customer、持仓/权益检查和用量上报。它从 `https://cdn.longplayai.com/sdk/python` 分发(不在 PyPI),不属于这个 npm 包。
|
|
100
98
|
|
|
101
99
|
[Go 服务端 SDK](../go/README.md) 提供同样的首版能力,使用类型化响应、Context 取消和 goroutine 并发复用客户端。通过 Go 默认模块代理以 `go get longplayai.com/sdk/go` 安装,与其他业务 SDK 共用发行版本。
|
|
102
100
|
|
|
@@ -191,7 +189,7 @@ Funnel、独立 Feature 和页面实验各自求值、各自使用结果。App
|
|
|
191
189
|
|
|
192
190
|
Customer 求值中的 `id` 是 Longplay Customer UUID(`customer.id`),`externalUserId` 是商户账号 ID(`customer.externalUserId`)。创建实验时明确选择 `hashAttribute`,每个消费方保持相同语义;不要把商户账号 ID 填进 `attributes.id`。本地属性来自可信后端给当前用户的 Customer 数据;`identify(customerToken)` 负责请求认证,不会自动补齐本地分桶属性。属性仅用于求值,不构成授权。
|
|
193
191
|
|
|
194
|
-
`setAttributes()` 替换整个对象,每次更新都保留分桶字段。匿名页面/视觉实验默认的 `id` 和 `deviceId` 来自共用的第一方设备 cookie,不自动与账号实验同组。已打开的页面在可见时每 60 秒重新读取视觉配置,实验停止或关闭投放后无需刷新页面即可撤销修改。各适配器的 Sticky 能力有区别:共用 Run 的 Local 指令读取服务端状态,纯本地工具的持久 Sticky 使用已有宿主适配器,不新增共享状态。完整要求见[架构边界](../../docs/growthbook-sdk-delivery.md
|
|
192
|
+
`setAttributes()` 替换整个对象,每次更新都保留分桶字段。匿名页面/视觉实验默认的 `id` 和 `deviceId` 来自共用的第一方设备 cookie,不自动与账号实验同组。已打开的页面在可见时每 60 秒重新读取视觉配置,实验停止或关闭投放后无需刷新页面即可撤销修改。各适配器的 Sticky 能力有区别:共用 Run 的 Local 指令读取服务端状态,纯本地工具的持久 Sticky 使用已有宿主适配器,不新增共享状态。完整要求见[架构边界](../../docs/growthbook-sdk-delivery.md#cross-consumer-evaluation-and-bucketing-identity)。
|
|
195
193
|
|
|
196
194
|
### 服务端 SDK 本地 Funnel 求值
|
|
197
195
|
|
|
@@ -218,7 +216,7 @@ const used = await session.evaluate({ track: true });
|
|
|
218
216
|
|
|
219
217
|
默认求值不触发曝光。仅在确实使用结果时传 `{ track: true }`,成功计算并保存 Sticky 后才调用已配置的 `onExperimentViewed`/`onFeatureUsage`,按本会话内的原生分配/值去重。回调接入已有事件 tracker,异常通过 `onError` 报告;事件送达与重试由 tracker 负责,不生成持久的曝光或使用回执。
|
|
220
218
|
|
|
221
|
-
含商业节点的混合图、资源/Bundle 输出、过期配置明确拒绝,不自动执行远程 `decide()
|
|
219
|
+
含商业节点的混合图、资源/Bundle 输出、过期配置明确拒绝,不自动执行远程 `decide()`。远程幂等、已提交回执和财务检查保持原义;本地结果不能代替发券、付款、权益或全局频控。使用前确认目标运行时支持相同协议与配置投递契约。
|
|
222
220
|
|
|
223
221
|
### 独立 Feature
|
|
224
222
|
|
|
@@ -264,7 +262,7 @@ Offering 固定 Product Version 的范围与层级。Paywall 固定已发布 Off
|
|
|
264
262
|
|
|
265
263
|
Stripe 环境的 `longplay` 模式由 Longplay 执行;`record_only` 返回交给商户后端执行的指令。两种模式都从验证后的 Stripe 事实写入财务与权益。支付方式收集本身不产生扣款、Invoice 或额外权益。报价/确认/读取使用各自持久操作 ID;同一请求编号不能更换输入。
|
|
266
264
|
|
|
267
|
-
|
|
265
|
+
包安装成功**不代表完整商业功能或生产环境已验收**。当前仍未接通的服务包括:
|
|
268
266
|
|
|
269
267
|
- 订阅批处理。冲突查询/重试已有对应服务,但仍需匹配部署及业务前置条件。
|
|
270
268
|
- Postpaid Billing Authorization、Billing Coupon 列表和账单调整确认。当前 AutoTopup consent 的准备/确认/撤销已有服务,不能据此推定其他授权类型可用。
|
|
@@ -287,7 +285,7 @@ npm 发布不部署 Web 服务、不应用数据库迁移,也不发布 Swift
|
|
|
287
285
|
|
|
288
286
|
## 共享公共配置
|
|
289
287
|
|
|
290
|
-
|
|
288
|
+
`createConfigurationSync({ origin, scope })`;`scope` 必须明确包含 `projectId`、`environment` 和 `environmentId`。将同一个实例作为 `configuration` 传给 `createLongplay`、Funnel start/Run controller 和 `createPageExperiments`,共用清单、文件缓存、并发请求和更新通知。`/server` 导出的 `createSynchronizedFunnelLocalEvaluator(configuration, funnelId)` 使用同一份规范 Funnel 文件与 GB 代次进行纯判断,保留仅可信服务端执行的边界。
|
|
291
289
|
|
|
292
290
|
公共配置由匹配运行端发布。公共文件不需要 Customer 凭据;业务操作沿用原凭据和服务端资格检查。完整调用见[英文说明](README.md#shared-public-configuration)。
|
|
293
291
|
|
|
@@ -376,4 +374,4 @@ export async function showBanner(
|
|
|
376
374
|
|
|
377
375
|
Server 入口导出 `createMerchantBridgeHandler`、`createMerchantBridgeAuthorityResolver`、`signMerchantBridgeMessage` 和 `verifyMerchantBridgeMessage`。配置后端签名密钥、原生授权/CSRF、实际已实现的能力与 profiles,并设置 `resolveOperationAuthority: createMerchantBridgeAuthorityResolver(server)`,每次从 Longplay 原操作 API 读取最新权限。服务签名仍需原确认事实和准确范围、Customer 归属,不能据此签发用户会话。
|
|
378
376
|
|
|
379
|
-
业务处理器必须在调用外部渠道前持久预留原 operationId,并使用稳定渠道幂等键;SDK 的先查询不能代替并发锁。`operation.read` 返回 `found` 或 `not_received`,严格只读。`RESULT_UNKNOWN` 只恢复原操作,不能根据浏览器报价或 pending 状态自行推断执行权限。Console 能力检查不证明商业完成。精确字段和恢复规则见[商户接入规范](https://longplayai.com/zh-hans/docs/merchant-execution)。
|
|
377
|
+
业务处理器必须在调用外部渠道前持久预留原 operationId,并使用稳定渠道幂等键;SDK 的先查询不能代替并发锁。`operation.read` 返回 `found` 或 `not_received`,严格只读。`RESULT_UNKNOWN` 只恢复原操作,不能根据浏览器报价或 pending 状态自行推断执行权限。Console 能力检查不证明商业完成。精确字段和恢复规则见[商户接入规范](https://www.longplayai.com/zh-hans/docs/guides/merchant-execution)。
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LanguageModelV4Usage, LanguageModelV4Middleware } from '@ai-sdk/provider';
|
|
2
|
-
import { F as FoundationApi, A as ApiInput } from './api-
|
|
2
|
+
import { F as FoundationApi, A as ApiInput } from './api-RQUBSSEJ.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
5
|
declare const tokenCounts: z.ZodObject<{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as StackNode } from './screen-
|
|
1
|
+
import { S as StackNode } from './screen-DRP7nsrQ.js';
|
|
2
2
|
import { z } from 'zod/v4';
|
|
3
3
|
import { z as z$1 } from 'zod';
|
|
4
4
|
|
|
@@ -3985,11 +3985,11 @@ declare const apiOperations: {
|
|
|
3985
3985
|
field: z$1.ZodEnum<{
|
|
3986
3986
|
quantity: "quantity";
|
|
3987
3987
|
currency: "currency";
|
|
3988
|
+
product: "product";
|
|
3988
3989
|
price: "price";
|
|
3989
3990
|
subscription: "subscription";
|
|
3990
3991
|
status: "status";
|
|
3991
3992
|
cancelAtPeriodEnd: "cancelAtPeriodEnd";
|
|
3992
|
-
product: "product";
|
|
3993
3993
|
periodStart: "periodStart";
|
|
3994
3994
|
periodEnd: "periodEnd";
|
|
3995
3995
|
trialEnd: "trialEnd";
|
|
@@ -4709,20 +4709,6 @@ declare const apiOperations: {
|
|
|
4709
4709
|
eventId: z$1.ZodString;
|
|
4710
4710
|
customerId: z$1.ZodUUID;
|
|
4711
4711
|
occurredAt: z$1.ZodISODateTime;
|
|
4712
|
-
}, z$1.core.$strict>, z$1.ZodObject<{
|
|
4713
|
-
type: z$1.ZodLiteral<"dispute.updated">;
|
|
4714
|
-
merchantDisputeId: z$1.ZodString;
|
|
4715
|
-
merchantInvoiceId: z$1.ZodString;
|
|
4716
|
-
status: z$1.ZodEnum<{
|
|
4717
|
-
funds_withdrawn: "funds_withdrawn";
|
|
4718
|
-
funds_reinstated: "funds_reinstated";
|
|
4719
|
-
}>;
|
|
4720
|
-
amountMinor: z$1.ZodNumber;
|
|
4721
|
-
currency: z$1.ZodString;
|
|
4722
|
-
provider: z$1.ZodLiteral<"merchant">;
|
|
4723
|
-
eventId: z$1.ZodString;
|
|
4724
|
-
customerId: z$1.ZodUUID;
|
|
4725
|
-
occurredAt: z$1.ZodISODateTime;
|
|
4726
4712
|
}, z$1.core.$strict>], "type">]>;
|
|
4727
4713
|
readonly response: z$1.ZodObject<{
|
|
4728
4714
|
requestId: z$1.ZodUUID;
|
|
@@ -12164,8 +12150,8 @@ declare const apiOperations: {
|
|
|
12164
12150
|
rows: z$1.ZodArray<z$1.ZodObject<{
|
|
12165
12151
|
id: z$1.ZodUUID;
|
|
12166
12152
|
sourceKind: z$1.ZodEnum<{
|
|
12167
|
-
usage: "usage";
|
|
12168
12153
|
product: "product";
|
|
12154
|
+
usage: "usage";
|
|
12169
12155
|
manual: "manual";
|
|
12170
12156
|
}>;
|
|
12171
12157
|
providerInvoiceId: z$1.ZodNullable<z$1.ZodString>;
|
|
@@ -12382,8 +12368,8 @@ declare const apiOperations: {
|
|
|
12382
12368
|
invoice: z$1.ZodObject<{
|
|
12383
12369
|
id: z$1.ZodUUID;
|
|
12384
12370
|
sourceKind: z$1.ZodEnum<{
|
|
12385
|
-
usage: "usage";
|
|
12386
12371
|
product: "product";
|
|
12372
|
+
usage: "usage";
|
|
12387
12373
|
manual: "manual";
|
|
12388
12374
|
}>;
|
|
12389
12375
|
providerInvoiceId: z$1.ZodNullable<z$1.ZodString>;
|
|
@@ -13446,14 +13432,30 @@ declare const apiOperations: {
|
|
|
13446
13432
|
schemaVersion: z$1.ZodLiteral<4>;
|
|
13447
13433
|
name: z$1.ZodString;
|
|
13448
13434
|
surface: z$1.ZodEnum<{
|
|
13449
|
-
paywall: "paywall";
|
|
13450
13435
|
popup: "popup";
|
|
13436
|
+
paywall: "paywall";
|
|
13451
13437
|
onboarding: "onboarding";
|
|
13452
13438
|
page: "page";
|
|
13453
13439
|
banner: "banner";
|
|
13454
13440
|
}>;
|
|
13455
13441
|
initialPageId: z$1.ZodOptional<z$1.ZodString>;
|
|
13456
13442
|
presentation: z$1.ZodDiscriminatedUnion<[z$1.ZodObject<{
|
|
13443
|
+
desktopWidth: z$1.ZodOptional<z$1.ZodObject<{
|
|
13444
|
+
min: z$1.ZodNumber;
|
|
13445
|
+
max: z$1.ZodNumber;
|
|
13446
|
+
viewport: z$1.ZodNumber;
|
|
13447
|
+
}, z$1.core.$strict>>;
|
|
13448
|
+
mobile: z$1.ZodOptional<z$1.ZodEnum<{
|
|
13449
|
+
sheet: "sheet";
|
|
13450
|
+
fullscreen: "fullscreen";
|
|
13451
|
+
}>>;
|
|
13452
|
+
backdrop: z$1.ZodOptional<z$1.ZodEnum<{
|
|
13453
|
+
none: "none";
|
|
13454
|
+
scrim: "scrim";
|
|
13455
|
+
dim: "dim";
|
|
13456
|
+
"strong-dim": "strong-dim";
|
|
13457
|
+
blur: "blur";
|
|
13458
|
+
}>>;
|
|
13457
13459
|
type: z$1.ZodLiteral<"modal">;
|
|
13458
13460
|
size: z$1.ZodEnum<{
|
|
13459
13461
|
sm: "sm";
|
|
@@ -13461,6 +13463,22 @@ declare const apiOperations: {
|
|
|
13461
13463
|
lg: "lg";
|
|
13462
13464
|
}>;
|
|
13463
13465
|
}, z$1.core.$strict>, z$1.ZodObject<{
|
|
13466
|
+
desktopWidth: z$1.ZodOptional<z$1.ZodObject<{
|
|
13467
|
+
min: z$1.ZodNumber;
|
|
13468
|
+
max: z$1.ZodNumber;
|
|
13469
|
+
viewport: z$1.ZodNumber;
|
|
13470
|
+
}, z$1.core.$strict>>;
|
|
13471
|
+
mobile: z$1.ZodOptional<z$1.ZodEnum<{
|
|
13472
|
+
sheet: "sheet";
|
|
13473
|
+
fullscreen: "fullscreen";
|
|
13474
|
+
}>>;
|
|
13475
|
+
backdrop: z$1.ZodOptional<z$1.ZodEnum<{
|
|
13476
|
+
none: "none";
|
|
13477
|
+
scrim: "scrim";
|
|
13478
|
+
dim: "dim";
|
|
13479
|
+
"strong-dim": "strong-dim";
|
|
13480
|
+
blur: "blur";
|
|
13481
|
+
}>>;
|
|
13464
13482
|
type: z$1.ZodLiteral<"sheet">;
|
|
13465
13483
|
size: z$1.ZodEnum<{
|
|
13466
13484
|
sm: "sm";
|
|
@@ -13477,11 +13495,11 @@ declare const apiOperations: {
|
|
|
13477
13495
|
background: z$1.ZodString;
|
|
13478
13496
|
text: z$1.ZodString;
|
|
13479
13497
|
radius: z$1.ZodEnum<{
|
|
13480
|
-
none: "none";
|
|
13481
|
-
full: "full";
|
|
13482
13498
|
sm: "sm";
|
|
13483
13499
|
md: "md";
|
|
13484
13500
|
lg: "lg";
|
|
13501
|
+
none: "none";
|
|
13502
|
+
full: "full";
|
|
13485
13503
|
}>;
|
|
13486
13504
|
font: z$1.ZodEnum<{
|
|
13487
13505
|
system: "system";
|
|
@@ -13489,6 +13507,14 @@ declare const apiOperations: {
|
|
|
13489
13507
|
rounded: "rounded";
|
|
13490
13508
|
mono: "mono";
|
|
13491
13509
|
}>;
|
|
13510
|
+
fontAssets: z$1.ZodOptional<z$1.ZodObject<{
|
|
13511
|
+
family: z$1.ZodString;
|
|
13512
|
+
faces: z$1.ZodArray<z$1.ZodObject<{
|
|
13513
|
+
url: z$1.ZodString;
|
|
13514
|
+
weight: z$1.ZodNumber;
|
|
13515
|
+
family: z$1.ZodOptional<z$1.ZodString>;
|
|
13516
|
+
}, z$1.core.$strict>>;
|
|
13517
|
+
}, z$1.core.$strict>>;
|
|
13492
13518
|
}, z$1.core.$strict>;
|
|
13493
13519
|
pages: z$1.ZodArray<z$1.ZodObject<{
|
|
13494
13520
|
id: z$1.ZodString;
|
|
@@ -13499,11 +13525,11 @@ declare const apiOperations: {
|
|
|
13499
13525
|
background: z$1.ZodString;
|
|
13500
13526
|
text: z$1.ZodString;
|
|
13501
13527
|
radius: z$1.ZodEnum<{
|
|
13502
|
-
none: "none";
|
|
13503
|
-
full: "full";
|
|
13504
13528
|
sm: "sm";
|
|
13505
13529
|
md: "md";
|
|
13506
13530
|
lg: "lg";
|
|
13531
|
+
none: "none";
|
|
13532
|
+
full: "full";
|
|
13507
13533
|
}>;
|
|
13508
13534
|
font: z$1.ZodEnum<{
|
|
13509
13535
|
system: "system";
|
|
@@ -13511,6 +13537,14 @@ declare const apiOperations: {
|
|
|
13511
13537
|
rounded: "rounded";
|
|
13512
13538
|
mono: "mono";
|
|
13513
13539
|
}>;
|
|
13540
|
+
fontAssets: z$1.ZodOptional<z$1.ZodObject<{
|
|
13541
|
+
family: z$1.ZodString;
|
|
13542
|
+
faces: z$1.ZodArray<z$1.ZodObject<{
|
|
13543
|
+
url: z$1.ZodString;
|
|
13544
|
+
weight: z$1.ZodNumber;
|
|
13545
|
+
family: z$1.ZodOptional<z$1.ZodString>;
|
|
13546
|
+
}, z$1.core.$strict>>;
|
|
13547
|
+
}, z$1.core.$strict>>;
|
|
13514
13548
|
}, z$1.core.$strict>>;
|
|
13515
13549
|
editorPosition: z$1.ZodOptional<z$1.ZodObject<{
|
|
13516
13550
|
x: z$1.ZodNumber;
|
|
@@ -14726,8 +14760,8 @@ declare const apiOperations: {
|
|
|
14726
14760
|
}, z$1.core.$strict>, z$1.ZodObject<{
|
|
14727
14761
|
type: z$1.ZodLiteral<"transaction">;
|
|
14728
14762
|
purpose: z$1.ZodEnum<{
|
|
14729
|
-
invoice: "invoice";
|
|
14730
14763
|
product: "product";
|
|
14764
|
+
invoice: "invoice";
|
|
14731
14765
|
}>;
|
|
14732
14766
|
productVersionId: z$1.ZodNullable<z$1.ZodUUID>;
|
|
14733
14767
|
productName: z$1.ZodNullable<z$1.ZodString>;
|
|
@@ -14847,8 +14881,8 @@ declare const apiOperations: {
|
|
|
14847
14881
|
invoice: z$1.ZodObject<{
|
|
14848
14882
|
id: z$1.ZodUUID;
|
|
14849
14883
|
sourceKind: z$1.ZodEnum<{
|
|
14850
|
-
usage: "usage";
|
|
14851
14884
|
product: "product";
|
|
14885
|
+
usage: "usage";
|
|
14852
14886
|
manual: "manual";
|
|
14853
14887
|
}>;
|
|
14854
14888
|
providerInvoiceId: z$1.ZodNullable<z$1.ZodString>;
|
|
@@ -16224,8 +16258,8 @@ declare const apiOperations: {
|
|
|
16224
16258
|
holdingStatus: z$1.ZodDefault<z$1.ZodEnum<{
|
|
16225
16259
|
"": "";
|
|
16226
16260
|
unavailable: "unavailable";
|
|
16227
|
-
active: "active";
|
|
16228
16261
|
none: "none";
|
|
16262
|
+
active: "active";
|
|
16229
16263
|
expired: "expired";
|
|
16230
16264
|
scheduled: "scheduled";
|
|
16231
16265
|
}>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{f as o}from"./chunk-
|
|
1
|
+
import{f as o}from"./chunk-PFHS7HK3.js";var n=class extends Error{constructor(t,s,y,i,r){super(s);this.code=t;this.status=y;this.requestId=i;this.name="IndianaError",this.reason=r?.reason;let e=o(t,y??0,{...r,retryAfter:r?.retryAfterSeconds===void 0?void 0:String(r.retryAfterSeconds)});this.retryable=e.retryable,this.recovery=e.recovery,this.retryAfterSeconds=e.retryAfterSeconds}code;status;requestId;commandRequestId;retryable;recovery;retryAfterSeconds;reason};export{n as a};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as d,b as ee,l as B,o as te}from"./chunk-E5ECPR6Z.js";import{b as Z}from"./chunk-VXY2C4AL.js";import{a as s}from"./chunk-OZZMZH7X.js";import{a as G}from"./chunk-DSPLGTQI.js";import{Ha as $,S as X,a as z,b as Y,c as K,d as Q,e as j,f as M,g as W,n as L,ua as a,wa as H}from"./chunk-RQZ42NQJ.js";var U=t=>{if(!Number.isSafeInteger(t)||t<0||t>=Number.MAX_SAFE_INTEGER)throw new s("INVALID_STATE","Installation sequence exhausted");return t+1},he=async t=>[...new Uint8Array(await crypto.subtle.digest("SHA-256",Uint8Array.from(t,e=>e.charCodeAt(0))))].map(e=>e.toString(16).padStart(2,"0")).join("");function _(t,e){return t.transaction(n=>{if(!Number.isSafeInteger(n.identitySeq)||n.identitySeq<0||!Number.isSafeInteger(n.addressSeq)||n.addressSeq<0||n.detachSeq!==null&&(!Number.isSafeInteger(n.detachSeq)||n.detachSeq<1||n.detachSeq>n.identitySeq))throw new s("INVALID_STATE","Installation journal is invalid");return e({...n})})}function ne(t,e,n){let i=null,c=0,o=0,l=0,y=Promise.resolve(),P=!1;if(t&&(!n||z.parse(t.scope).projectId!==n.projectId||t.scope.environment!==n.environment))throw new s("SCOPE_MISMATCH","Push installation belongs to another scope");let g=()=>{if(P)throw new s("CLOSED","SDK client was destroyed");if(!t)throw new s("NOT_CONFIGURED","Configure this client's native Push host first");return t},b=r=>{if(r!==c)throw new s("IDENTITY_CHANGED","Identity changed during Push operation")};async function D(r){let u=g();if(!u.sha256&&!globalThis.crypto?.subtle)throw new s("NOT_CONFIGURED","Configure native SHA-256 for this Push host");let p=u.sha256?await u.sha256(Uint8Array.from(r,I=>I.charCodeAt(0))):await he(r);if(!/^[a-f0-9]{64}$/.test(p))throw new s("INVALID_STATE","Push credential digest is invalid");return p}function m(r){let u=M.parse(r);if(u.installationId.toLowerCase()!==g().installationId.toLowerCase())throw new s("INVALID_RESPONSE","Push response belongs to another installation");return u}async function C(r,u){let p=g(),I={installationId:p.installationId,publicKey:p.publicKey,issuedAt:new Date().toISOString(),...u},S=await p.sign(W(r,p.scope,I));return{...I,signature:S}}let f=(r,u,p)=>e.requestWithCredential?e.requestWithCredential(r,u,p):e.request(r,u);async function w(){let r=g(),u=c,p=i?await(e.session?.access()??i):null,I=_(r,v=>v),S;if(I.detachSeq!==null){let v=I.detachSeq,V=Y.parse(await C("detach",{sequence:v,platform:r.platform}));try{let N=await e.request("push/installations/detach",{...r.scope,...V},"POST",{installationDetach:!0});if(!N||typeof N!="object"||!("installation"in N))throw new s("INVALID_RESPONSE","Push detach acknowledgement is invalid");let F=m(N.installation);if(F.bound||F.identitySeq!==v)throw new s("INVALID_RESPONSE","Push detach acknowledgement does not match its intent")}catch(N){if(N instanceof s&&N.status===404)S=N;else if(!(N instanceof s)||N.status!==412)throw N}S||_(r,N=>({...N,detachSeq:N.detachSeq===v?null:N.detachSeq}))}if(b(u),!p){if(S)throw S;return null}let q=a.bindPushInstallation,k=q.request.parse(await C("bind",{sequence:l,platform:r.platform,credentialDigest:await D(p)}));b(u);let R=q.response.parse(await f(q.path,k,p));b(u);let T=m(R.installation);if(!T.bound||T.identitySeq!==l)throw new s("INVALID_RESPONSE","Push binding acknowledgement does not match its intent");return S&&I.detachSeq!==null&&l>I.detachSeq&&_(r,v=>({...v,detachSeq:v.detachSeq===I.detachSeq?null:v.detachSeq})),T}async function E(){g();let r=c,u=i?await(e.session?.access()??i):null;if(!u)throw new s("NOT_IDENTIFIED","Identify before reading this installation");let p=a.readPushInstallation,I=p.request.parse(await C("read",{credentialDigest:await D(u)}));b(r);let S=p.response.parse(await f(p.path,I,u));return b(r),m(S.installation)}function h(r=w){let u=y.catch(()=>{}).then(r);return y=u,u.catch(p=>{try{t?.onError?.(p instanceof Error?p:new Error("Push synchronization failed"))}catch{}}),u}async function O(r,u,p){let I=g(),S=u.identity,q=u.observation,k=i?await(e.session?.access()??i):null;if(b(S),q!==o)throw new s("INVALID_STATE","Push observation changed during recovery");if(!k)throw new s("NOT_IDENTIFIED","Identify before recovering a Push address");if(!r.connectionId||!r.kind||!r.token||!["granted","provisional"].includes(r.permission))throw new s("INVALID_REQUEST","Recovery needs a provider token and notification permission");return await h(async()=>{if(b(S),await w(),b(S),q!==o)throw new s("INVALID_STATE","Push observation changed during recovery");let R=_(I,F=>p?F:{...F,addressSeq:U(F.addressSeq)}),v=await C(p?"recovery_confirm":"recovery_request",{...r,sequence:R.addressSeq,credentialDigest:await D(k),...p?{challenge:p}:{}}),V=p?Q.parse(v):K.parse(v);if(b(S),q!==o)throw new s("INVALID_STATE","Push observation changed during recovery");let N=await f(`push/installations/recovery/${p?"confirm":"request"}`,V,k);if(b(S),q!==o||_(I,F=>F).addressSeq!==R.addressSeq)throw new s("INVALID_STATE","Push observation changed during recovery");if(p){let F=a.updatePushAddress.response.parse(N),x=m(F.installation);if(!x.bound||x.identitySeq!==l||x.addressSeq!==R.addressSeq||x.connectionId!==r.connectionId||x.addressStatus!=="active")throw new s("INVALID_RESPONSE","Push recovery acknowledgement does not match its intent");return x}if(!N||typeof N!="object"||!("recovery"in N))throw new s("INVALID_RESPONSE","Push recovery acknowledgement is invalid");return j.parse(N.recovery)})}return{recoveryObserver(){g();let r={identity:c,observation:++o};return{async request(u){return j.parse(await O(u,r))},async confirm(u,p){return M.parse(await O(p,r,u))}}},identify(r){if(!t)return;l=_(t,p=>({...p,identitySeq:U(p.identitySeq)})).identitySeq,i=r,c++,o++},reset(){if(t)try{_(t,r=>{let u=U(r.identitySeq);return{...r,identitySeq:u,detachSeq:u}})}finally{i=null,c++,o++}},start(){t&&!P&&h()},destroy(){P=!0,i=null,c++,o++},async sync(){return await h()},read:E,async recover(){let r=g(),u=c,p=l;return o++,await h(async()=>{b(u);let I=await E();return b(u),l=_(r,q=>{if(q.identitySeq!==p)throw new s("IDENTITY_CHANGED","A newer installation intent exists");return{...q,identitySeq:U(Math.max(q.identitySeq,I.identitySeq)),addressSeq:Math.max(q.addressSeq,I.addressSeq)}}).identitySeq,await w()})},tokenObserver(){g();let r=++o,u=c;return async p=>{if(r!==o||u!==c)return null;let I=g(),S=i?await(e.session?.access()??i):null;if(!S)throw new s("NOT_IDENTIFIED","Identify before registering a Push token");if(await h(),b(u),r!==o)return null;let q=_(I,v=>({...v,addressSeq:U(v.addressSeq)})),k=a.updatePushAddress,R=k.request.parse(await C("address",{...p,sequence:q.addressSeq,credentialDigest:await D(S)}));if(b(u),r!==o)return null;let T=await f(k.path,R,S);return b(u),r!==o||_(I,v=>v).addressSeq!==q.addressSeq?null:m(k.response.parse(T).installation)}}}}function re(t,e){let n={async preference(i){let c=a.readMessagingPreference;return(await d(t,c,{channel:i})).preference},async setPreference(i){let c=a.setMessagingPreference;return(await d(t,c,i)).preference}};return{messaging:n,push:{sync:e.sync,read:e.read,recover:e.recover,tokenObserver:e.tokenObserver,recoveryObserver:e.recoveryObserver,async preference(){return n.preference("push")},async setPreference(i){return n.setPreference({...i,channel:"push"})}}}}function ie(t,e,n={}){let i=!1;function c(){if(i)throw new s("CLOSED","SDK client was destroyed")}let o=new Set,l=P=>{for(let g of o)try{g(P)}catch{}},y=t.session.subscribeIdentity(()=>{l(!!t.session.peek()),n.afterChange?.()},()=>{e()});return{assertActive:c,isIdentified:()=>!i&&!!t.session.peek(),methods:{subscribeIdentity(P){return c(),o.add(P),()=>{o.delete(P)}},identify(P){c();let g=typeof P=="string"?P:P.accessToken;if(!L.test(g))throw new s("INVALID_TOKEN","Browser SDK requires a customer session");n.beforeIdentify?.(g),t.identify(P)},reset(){if(!i)try{n.beforeReset?.()}finally{t.reset()}},destroy(){if(!i){i=!0,y(),o.clear();try{n.beforeDestroy?.(),e()}finally{t.dispose()}}}}}}function A(t){if(t!==null&&typeof t=="object"&&"customerId"in t)throw new s("INVALID_REQUEST","Customer requests use the verified session identity")}var ge={...a.readHoldings,request:a.readHoldings.request.omit({customerId:!0})};function se(t){return{async checkEntitlement(e){A(e);let n=a.checkEntitlement;return d(t,n,e)},async readHoldings(e={}){return d(t,ge,e)}}}function oe(t){return{async readLedger(e){let n=a.readLedger;return d(t,n,{query:e})},async readCreditStatement(e){A(e);let n=a.readCreditStatement;return d(t,n,e)},async quoteBalance(e){A(e);let n=a.quoteBalance;return d(t,n,{command:e})}}}function ae(t){return{async setupPayment(e){A(e);let n=a.setupPayment;return d(t,n,e)},async readPaymentSetup(e){A(e);let n=a.readPaymentSetup;return d(t,n,e)},async readBillingInvoice(e){A(e);let n=a.readBillingInvoice;return d(t,n,e)},async readBillingControls(e={}){A(e);let n=a.readBillingControls;return d(t,n,e)},async prepareBillingAuthorization(e){A(e);let n=a.prepareBillingAuthorization;return d(t,n,e)},async confirmBillingAuthorization(e){A(e);let n=a.confirmBillingAuthorization;return d(t,n,e)},async setBillingCoupons(e){A(e);let n=a.setBillingCoupons;return d(t,n,e,{request:"Invalid billing coupon list",response:"Invalid billing coupon receipt"})},async revokeBillingAuthorization(e){A(e);let n=a.revokeBillingAuthorization;return d(t,n,e)},async listBillingInvoices(e={after:null,limit:25}){A(e);let n=a.listBillingInvoices;return d(t,n,e)},async confirmBillingAdjustment(e){A(e);let n=a.confirmBillingAdjustment;return d(t,n,e)}}}function ce(t){return{async previewUpdate(e){A(e);let n=a.previewUpdate;return d(t,n,e)},async update(e){A(e);let n=a.update;return d(t,n,e)},async readSubscriptionUpdate(e){A(e);let n=a.readSubscriptionUpdate;return d(t,n,e)},async restoreNativePurchase(e){A(e);let n=a.restoreNativePurchase;return d(t,n,e)},async previewAttach(e){A(e);let n=a.previewAttach;return d(t,n,e)},async attach(e){A(e);let n=a.attach;return d(t,n,e)},async readSubscriptionOperation(e){A(e);let n=a.readSubscriptionOperation;return d(t,n,e)}}}function ue(t){return{async redeemReward(e){return A(e),(await d(t,a.redeemReward,{...e,requestId:e.requestId??crypto.randomUUID()},{request:"Invalid reward redemption",response:"Invalid reward receipt"})).redemption},async claimRewardProduct(e){return A(e),(await d(t,a.claimRewardProduct,e,{request:"Invalid reward product claim",response:"Invalid reward product checkout"})).checkout},async createReferralCode(e){return A(e),(await d(t,a.createReferralCode,{...e,requestId:e.requestId??crypto.randomUUID()},{request:"Invalid referral program",response:"Invalid referral code"})).referralCode},async redeemCoupon(e,n=crypto.randomUUID()){let i=await d(t,a.redeemCoupon,{code:e,requestId:n},{request:"Invalid coupon code",response:"Invalid Coupon receipt"});return{offer:i.offer,reason:i.reason}},async claimCoupon(e,n=crypto.randomUUID()){let i=await d(t,a.grantOffer,{couponId:e,requestId:n},{request:"Invalid Coupon claim",response:"Invalid Coupon receipt"});return{offer:i.offer,reason:i.reason}},async listOffers(){return(await d(t,a.listOffers,{},{response:"Invalid offers response"})).offers}}}function de(t){return{...se(t),...oe(t),...ae(t),...ce(t),...ue(t)}}function pe(t){return{async resolveContent(e){A(e);let n=a.resolveContent;return d(t,n,e)},async resolvePaywall(e){A(e);let n=a.resolvePaywall;return d(t,n,e)},async resolveOffering(e){A(e);let n=a.resolveOffering;return d(t,n,e)}}}var J=t=>new TextEncoder().encode(JSON.stringify(t)).length,le=16384;function fe(t,e){let n=0,i,c=f=>{i={config:structuredClone(f),until:Date.now()+3e4}},o=[],l=null,y;function P(){if(!e())throw new s("NOT_IDENTIFIED","Call identify before using Features or events")}function g(){y||!o.length||(y=setTimeout(()=>{y=void 0,D().catch(()=>{}).finally(g)},5e3),typeof y=="object"&&"unref"in y&&y.unref())}function b(f,w={},E={}){if(P(),i&&Date.now()<i.until&&!X(i.config,f))return;C();let h=a.trackEvents.request.parse({events:[{eventUuid:crypto.randomUUID(),timestamp:new Date().toISOString(),name:f,properties:w,...E}]}).events[0];if(J({events:[h]})>le)throw new s("INVALID_REQUEST","Event exceeds the delivery size limit");if(o.length>=500)throw new s("EVENT_QUEUE_FULL","Flush pending events before tracking more");o.push(structuredClone(h)),g()}async function D(f=!1){if(P(),l)return l;let w=n,E=(async()=>{let h={inserted:0,duplicates:0,rejected:0,skipped:0},O=o.length;for(;O&&w===n;){let r=[],u=J({events:[]});for(let S of o.slice(0,Math.min(O,100))){let q=J(S)+(r.length?1:0);if(r.length&&u+q>le)break;r.push(S),u+=q}let p=a.trackEvents,I=await d(t,p,{events:r},void 0,{keepalive:f});if(w!==n)throw new s("IDENTITY_CHANGED","Event identity changed during delivery");if(I.inserted+I.duplicates+I.rejected+I.skipped!==r.length)throw new s("INVALID_RESPONSE","Incomplete event acknowledgement");c(I.analyticsConfig),o.splice(0,r.length),O-=r.length,h.inserted+=I.inserted,h.duplicates+=I.duplicates,h.rejected+=I.rejected,h.skipped+=I.skipped}return h})();l=E;try{return await E}finally{l===E&&(l=null)}}let m;function C(){if(m||typeof document>"u")return;let f=()=>{document.visibilityState==="hidden"&&e()&&o.length&&D(!0).catch(()=>{})};document.addEventListener("visibilitychange",f),m=()=>document.removeEventListener("visibilitychange",f)}return{rememberConfiguration:c,track:b,flush:D,reset(){n++,i=void 0,clearTimeout(y),y=void 0,o=[],l=null},detachVisibility(){m?.(),m=void 0}}}function me(t){let e=t.merchandise;if(typeof t.merchandiseId=="string")return{internalId:t.merchandiseId};if(!(!e||typeof e!="object"||Array.isArray(e))){if(typeof e.internalId=="string")return{internalId:e.internalId};if(typeof e.externalId=="string")return{id:e.externalId};if(typeof e.id=="string")return{id:e.id}}}function we(t){let e=me(t),{merchandiseId:n,merchandise:i,...c}=t;return{...c,...e?{merchandise:e}:{}}}function ye(t,e,n,i,c){if(c&&i&&(c.scope.projectId!==i.projectId||c.scope.environment!==i.environment))throw new s("SCOPE_MISMATCH","Configuration belongs to another App/environment");let o=0,l=new Set;function y(){if(!e())throw new s("NOT_IDENTIFIED","Call identify before using Features or events")}async function P(g={}){c||y();let b=o,D=!1,m=async()=>{if(D||b!==o)throw new s("IDENTITY_CHANGED","Feature identity changed");let R=a.getFeatures,T=c?{scope:{projectId:c.scope.projectId,environment:c.scope.environment},payload:await c.features()}:await d(t,R,{});if(b!==o)throw new s("IDENTITY_CHANGED","Feature identity changed");if(i&&(T.scope.projectId!==i.projectId||T.scope.environment!==i.environment))throw new s("INVALID_RESPONSE","Feature response scope changed");return n.rememberConfiguration(T.payload.analyticsConfig),T},C=await m(),f=!0,w,E=R=>{try{g.onError?.(R)}catch{}},h=(R,T,v)=>{try{let V=me(v);n.track(R,T,V?{merchandise:V}:{})}catch(V){E(V)}},O=ee({assertUsable:c?.assertFeatures,scope:C.scope,attributes:g.attributes,onError:g.onError,load:async()=>f?(f=!1,C.payload):(await m()).payload,evaluateRemote:async R=>{if(b!==o)throw new s("IDENTITY_CHANGED","Feature identity changed");let T=a.evaluateFeatures,v=await d(t,T,{...R,attributes:we(R.attributes)});if(v.scope.projectId!==C.scope.projectId||v.scope.environment!==C.scope.environment)throw new s("INVALID_RESPONSE","Remote Feature response scope changed");return{generation:v.generation,evaluatedAt:v.evaluatedAt,expiresAt:v.expiresAt,features:v.features,...v.merchandiseContext?{merchandiseContext:v.merchandiseContext}:{}}},onExperimentViewed:(R,T,v)=>h("Experiment Viewed",{experimentId:R.key,variationId:T.key},v),onFeatureUsage:(R,T,v)=>h("Feature Evaluated",{feature:R,value:T.value,source:T.source,ruleId:T.ruleId,...T.experimentResult?{variationId:T.experimentResult.key}:{}},v)}),r=O.refresh;function u(){clearTimeout(w),!c&&(D||b!==o||!O.expiresAt||(w=setTimeout(()=>{p().catch(E)},Math.min(2147483647,Math.max(1e3,Date.parse(O.expiresAt)-Date.now()))),typeof w=="object"&&"unref"in w&&w.unref()))}async function p(){try{return await r()}finally{u()}}let I=()=>{D||p().catch(E)},S=O.subscribe(u),q=c?.subscribe(()=>{!D&&c.fresh&&p().catch(E)});function k(){D||(D=!0,clearTimeout(w),typeof window<"u"&&window.removeEventListener("focus",I),S(),q?.(),O.reset(),l.delete(k))}l.add(k);try{await O.init(),(g.attributes?.merchandise||g.attributes?.merchandiseId)&&await O.refreshRemote()}catch(R){throw k(),R}return u(),!c&&typeof window<"u"&&window.addEventListener("focus",I),Object.assign(O,{refresh:p,destroy:k})}return{features:P,reset(g){o++,g();for(let b of l)b()}}}import{z as ve}from"zod";function Ie(t,e){let n="source"in e?{funnelId:e.source.id,funnelVersionId:e.source.versionId}:"versionId"in e?{funnelId:e.funnelId,funnelVersionId:e.versionId}:e,i=ve.object({funnelId:H.shape.id,funnelVersionId:H.shape.versionId.optional()}).safeParse(n);if(!i.success)throw new s("INVALID_REQUEST","A valid Funnel source is required");let c=Object.freeze(i.data);function o(l){if("customerId"in l)throw new s("INVALID_REQUEST","Customer identity cannot be overridden");if("funnelId"in l&&l.funnelId!==void 0&&l.funnelId!==c.funnelId||"funnelVersionId"in l&&l.funnelVersionId!==void 0&&l.funnelVersionId!==c.funnelVersionId)throw new s("SCOPE_MISMATCH","The original Funnel source cannot change");return{...l,...c}}return{async claimCoupon(l,y=crypto.randomUUID()){let P=a.grantOffer,g=await d(t,P,o({couponId:l,requestId:y}));return{offer:g.offer,reason:g.reason}},async resolveOffering(l){let y=a.resolveOffering;return d(t,y,o(l))},async resolvePaywall(l){let y=a.resolvePaywall;return d(t,y,o(l))},async previewAttach(l){let y=a.previewAttach;return d(t,y,o(l))}}}function Dt(t){return Ae(t)}function Ae(t){let e=Z(t),n=e.request,i;try{i=ne(t.push,e,t.scope??t.configuration?.scope)}catch(y){throw e.dispose(),y}let c=ie(e,()=>{l.reset(o.reset),o.detachVisibility()},{beforeIdentify:i.identify,beforeReset:i.reset,afterChange:i.start,beforeDestroy:i.destroy}),o=fe(n,c.isIdentified),l=ye(n,c.isIdentified,o,t.scope,t.configuration);return{session:e.session,...re(n,i),...de(n),...pe(n),forFunnel(y){return c.assertActive(),Ie(n,y)},async features(y={}){return c.assertActive(),l.features(y)},track(y,P,g={}){return o.track(y,P,g)},flush(){return o.flush()},...c.methods}}function Ut(t){if(!L.test(t.customerToken))throw new s("INVALID_TOKEN","A customer credential is required");if(!t.scope)throw new s("INVALID_REQUEST","An explicit App and environment scope is required");let e=te({...t,scope:t.scope,apiKey:t.customerToken});return{async start(n){let i=await e.start(n),c=B({...t,runToken:i.runToken});c.identify(t.customerToken);let o=i.run.instruction?.type==="evaluate_segment"?await c.get():i;return{...i,...o,controller:c}}}}function Gt(t){if(!t.scope)throw new s("INVALID_CONFIGURATION","An explicit process App/environment scope is required");if(t.session!==void 0)throw new s("INVALID_CONFIGURATION","The merchant process adapter owns the session");let e=null,n,i=0,c=new Set,o=new Map,l=new Map;async function y(m){let C,f=new Promise((w,E)=>{C=setTimeout(()=>E(new s("TIMEOUT","Process bridge request timed out")),t.timeoutMs??35e3)});try{return await Promise.race([Promise.resolve().then(m),f])}finally{clearTimeout(C)}}function P(m){throw m instanceof s&&(m.status===401||m.reason==="CUSTOMER_BINDING_CONFLICT")&&(i++,n?.reset(),n=void 0,e=null,o.clear(),l.clear()),m}function g(m,C){if(C!==i)throw new s("IDENTITY_CHANGED","Process was detached during a request");let f=$.parse(m);if(f.scope.projectId!==t.scope.projectId||f.scope.environment!==t.scope.environment)throw new s("SCOPE_MISMATCH","Process response belongs to another App/environment");if(e&&(e.run.id!==f.run.id||e.run.source.versionId!==f.run.source.versionId||e.run.source.id!==f.run.source.id||e.run.runExpiresAt!==f.run.runExpiresAt||e.run.identity.startedAs!==f.run.identity.startedAs||e.run.identity.participantId!==f.run.identity.participantId||e.run.identity.binding&&f.run.identity.binding&&e.run.identity.binding.id!==f.run.identity.binding.id))throw new s("INVALID_RESPONSE","The process changed its Run or Customer binding");if(!e||f.run.revision>=e.run.revision){if(e?.run.identity.binding&&!f.run.identity.binding)throw new s("INVALID_RESPONSE","The process lost its Customer binding");e=f;for(let I of c)G(I,f.run);f.run.instruction?.type==="authentication_required"&&G(t.onAuthenticationRequired,f.run)}f.settlement?.accepted!==void 0&&l.set(f.settlement.requestId,f.settlement.accepted);let{identity:w,instruction:E,...h}=f.run,{contract:O,settlement:r,...u}=f,p=r&&(({accepted:I,...S})=>S)(r);return{...u,run:{...h,authenticated:w.binding!==null,instruction:E?.type==="authentication_required"?null:E},...p?{settlement:p}:{}}}let b=m=>(o.has(m)||o.set(m,e?.run.identity.binding?.id??null),o.get(m));async function D(m){let C=i,f=e?.run.identity.binding?.id??null,w=h=>{if(f!==(e?.run.identity.binding?.id??null))throw h;return P(h)};if(m.operation==="page_experiments"){if(!t.adapter.pageExperiments)throw new s("CAPABILITY_UNAVAILABLE","Process page experiments are unavailable",501);return y(()=>t.adapter.pageExperiments(m.release,m.usedReceiptIds)).catch(w)}let E;if(m.operation==="get"){let{operation:h,customerToken:O,...r}=m;E=await y(()=>t.adapter.get({...r,...r.settlementRequestId?{settlementBindingId:b(r.settlementRequestId)}:{}})).catch(w)}else if(m.operation==="review")E=await y(()=>t.adapter.review(m.receiptId)).catch(w);else{if(m.operation==="start")throw new s("INVALID_REQUEST","Use process.open for entry");{let{customerToken:h,...O}=m;E=await y(()=>t.adapter.command(O,b(O.requestId))).catch(w)}}return g(E,C)}return{get view(){return e?.run??null},get controller(){return n},async open(m){let C=i,f=await y(()=>t.adapter.open(m)).catch(P);if(g(f,C),!n){n=B({...t,runToken:f.runToken,process:{request:D,binding:b,restore(h){for(let[O,r]of Object.entries(h))o.set(O,r)}}});let w=n,E=w.submit;w.submit=async h=>{try{return await E(h)}catch(O){if(!(O instanceof s)||O.reason!=="IDENTITY_CONTEXT_CHANGED"||h.operation!=="submit"||h.input.type!=="screen"||o.get(h.requestId)!==null)throw O;await w.settle?.(h.requestId),await w.get();let r=w.view;if(l.get(h.requestId)!==!1||!r||r.id!==e?.run.id||r.nodeId!==h.nodeId||r.visit!==h.visit||!e?.run.identity.binding)throw O;return E({...h,requestId:crypto.randomUUID(),revision:r.revision})}}}await n.get();for(let w of n.pendingCommands??[])o.has(w.requestId)&&o.get(w.requestId)!==(e?.run.identity.binding?.id??null)&&await n.settle?.(w.requestId);return{run:e.run,controller:n}},async syncIdentity(){let m=i;g(await y(()=>t.adapter.syncIdentity()).catch(P),m),await n?.get();for(let C of n?.pendingCommands??[])o.has(C.requestId)&&o.get(C.requestId)!==(e?.run.identity.binding?.id??null)&&await n?.settle?.(C.requestId);return e.run},async detach(){i++,n?.reset(),n=void 0,e=null,o.clear(),l.clear(),await y(()=>t.adapter.detach())},forProcess(m){if(!e?.run.identity.binding)throw new s("UNAUTHENTICATED","Sign in before a commercial operation",401);return{runId:e.run.id,bindingId:e.run.identity.binding.id,receiptId:m}},subscribe(m){return c.add(m),()=>{c.delete(m)}},destroy(){i++,n?.reset(),n=void 0,e=null,o.clear(),l.clear(),c.clear()}}}export{Dt as a,Ae as b,Ut as c,Gt as d};
|
|
1
|
+
import{a as d,b as ee,l as B,o as te}from"./chunk-GSZRT3I7.js";import{b as Z}from"./chunk-EIBEAG5L.js";import{a as s}from"./chunk-26HU2HXU.js";import{a as G}from"./chunk-DSPLGTQI.js";import{Ha as $,S as X,a as z,b as Y,c as K,d as Q,e as j,f as M,g as W,n as L,ua as a,wa as H}from"./chunk-XJBCPOFT.js";var U=t=>{if(!Number.isSafeInteger(t)||t<0||t>=Number.MAX_SAFE_INTEGER)throw new s("INVALID_STATE","Installation sequence exhausted");return t+1},he=async t=>[...new Uint8Array(await crypto.subtle.digest("SHA-256",Uint8Array.from(t,e=>e.charCodeAt(0))))].map(e=>e.toString(16).padStart(2,"0")).join("");function _(t,e){return t.transaction(n=>{if(!Number.isSafeInteger(n.identitySeq)||n.identitySeq<0||!Number.isSafeInteger(n.addressSeq)||n.addressSeq<0||n.detachSeq!==null&&(!Number.isSafeInteger(n.detachSeq)||n.detachSeq<1||n.detachSeq>n.identitySeq))throw new s("INVALID_STATE","Installation journal is invalid");return e({...n})})}function ne(t,e,n){let i=null,c=0,o=0,l=0,y=Promise.resolve(),P=!1;if(t&&(!n||z.parse(t.scope).projectId!==n.projectId||t.scope.environment!==n.environment))throw new s("SCOPE_MISMATCH","Push installation belongs to another scope");let g=()=>{if(P)throw new s("CLOSED","SDK client was destroyed");if(!t)throw new s("NOT_CONFIGURED","Configure this client's native Push host first");return t},b=r=>{if(r!==c)throw new s("IDENTITY_CHANGED","Identity changed during Push operation")};async function D(r){let u=g();if(!u.sha256&&!globalThis.crypto?.subtle)throw new s("NOT_CONFIGURED","Configure native SHA-256 for this Push host");let p=u.sha256?await u.sha256(Uint8Array.from(r,I=>I.charCodeAt(0))):await he(r);if(!/^[a-f0-9]{64}$/.test(p))throw new s("INVALID_STATE","Push credential digest is invalid");return p}function m(r){let u=M.parse(r);if(u.installationId.toLowerCase()!==g().installationId.toLowerCase())throw new s("INVALID_RESPONSE","Push response belongs to another installation");return u}async function C(r,u){let p=g(),I={installationId:p.installationId,publicKey:p.publicKey,issuedAt:new Date().toISOString(),...u},S=await p.sign(W(r,p.scope,I));return{...I,signature:S}}let f=(r,u,p)=>e.requestWithCredential?e.requestWithCredential(r,u,p):e.request(r,u);async function w(){let r=g(),u=c,p=i?await(e.session?.access()??i):null,I=_(r,v=>v),S;if(I.detachSeq!==null){let v=I.detachSeq,V=Y.parse(await C("detach",{sequence:v,platform:r.platform}));try{let N=await e.request("push/installations/detach",{...r.scope,...V},"POST",{installationDetach:!0});if(!N||typeof N!="object"||!("installation"in N))throw new s("INVALID_RESPONSE","Push detach acknowledgement is invalid");let F=m(N.installation);if(F.bound||F.identitySeq!==v)throw new s("INVALID_RESPONSE","Push detach acknowledgement does not match its intent")}catch(N){if(N instanceof s&&N.status===404)S=N;else if(!(N instanceof s)||N.status!==412)throw N}S||_(r,N=>({...N,detachSeq:N.detachSeq===v?null:N.detachSeq}))}if(b(u),!p){if(S)throw S;return null}let q=a.bindPushInstallation,k=q.request.parse(await C("bind",{sequence:l,platform:r.platform,credentialDigest:await D(p)}));b(u);let R=q.response.parse(await f(q.path,k,p));b(u);let T=m(R.installation);if(!T.bound||T.identitySeq!==l)throw new s("INVALID_RESPONSE","Push binding acknowledgement does not match its intent");return S&&I.detachSeq!==null&&l>I.detachSeq&&_(r,v=>({...v,detachSeq:v.detachSeq===I.detachSeq?null:v.detachSeq})),T}async function E(){g();let r=c,u=i?await(e.session?.access()??i):null;if(!u)throw new s("NOT_IDENTIFIED","Identify before reading this installation");let p=a.readPushInstallation,I=p.request.parse(await C("read",{credentialDigest:await D(u)}));b(r);let S=p.response.parse(await f(p.path,I,u));return b(r),m(S.installation)}function h(r=w){let u=y.catch(()=>{}).then(r);return y=u,u.catch(p=>{try{t?.onError?.(p instanceof Error?p:new Error("Push synchronization failed"))}catch{}}),u}async function O(r,u,p){let I=g(),S=u.identity,q=u.observation,k=i?await(e.session?.access()??i):null;if(b(S),q!==o)throw new s("INVALID_STATE","Push observation changed during recovery");if(!k)throw new s("NOT_IDENTIFIED","Identify before recovering a Push address");if(!r.connectionId||!r.kind||!r.token||!["granted","provisional"].includes(r.permission))throw new s("INVALID_REQUEST","Recovery needs a provider token and notification permission");return await h(async()=>{if(b(S),await w(),b(S),q!==o)throw new s("INVALID_STATE","Push observation changed during recovery");let R=_(I,F=>p?F:{...F,addressSeq:U(F.addressSeq)}),v=await C(p?"recovery_confirm":"recovery_request",{...r,sequence:R.addressSeq,credentialDigest:await D(k),...p?{challenge:p}:{}}),V=p?Q.parse(v):K.parse(v);if(b(S),q!==o)throw new s("INVALID_STATE","Push observation changed during recovery");let N=await f(`push/installations/recovery/${p?"confirm":"request"}`,V,k);if(b(S),q!==o||_(I,F=>F).addressSeq!==R.addressSeq)throw new s("INVALID_STATE","Push observation changed during recovery");if(p){let F=a.updatePushAddress.response.parse(N),x=m(F.installation);if(!x.bound||x.identitySeq!==l||x.addressSeq!==R.addressSeq||x.connectionId!==r.connectionId||x.addressStatus!=="active")throw new s("INVALID_RESPONSE","Push recovery acknowledgement does not match its intent");return x}if(!N||typeof N!="object"||!("recovery"in N))throw new s("INVALID_RESPONSE","Push recovery acknowledgement is invalid");return j.parse(N.recovery)})}return{recoveryObserver(){g();let r={identity:c,observation:++o};return{async request(u){return j.parse(await O(u,r))},async confirm(u,p){return M.parse(await O(p,r,u))}}},identify(r){if(!t)return;l=_(t,p=>({...p,identitySeq:U(p.identitySeq)})).identitySeq,i=r,c++,o++},reset(){if(t)try{_(t,r=>{let u=U(r.identitySeq);return{...r,identitySeq:u,detachSeq:u}})}finally{i=null,c++,o++}},start(){t&&!P&&h()},destroy(){P=!0,i=null,c++,o++},async sync(){return await h()},read:E,async recover(){let r=g(),u=c,p=l;return o++,await h(async()=>{b(u);let I=await E();return b(u),l=_(r,q=>{if(q.identitySeq!==p)throw new s("IDENTITY_CHANGED","A newer installation intent exists");return{...q,identitySeq:U(Math.max(q.identitySeq,I.identitySeq)),addressSeq:Math.max(q.addressSeq,I.addressSeq)}}).identitySeq,await w()})},tokenObserver(){g();let r=++o,u=c;return async p=>{if(r!==o||u!==c)return null;let I=g(),S=i?await(e.session?.access()??i):null;if(!S)throw new s("NOT_IDENTIFIED","Identify before registering a Push token");if(await h(),b(u),r!==o)return null;let q=_(I,v=>({...v,addressSeq:U(v.addressSeq)})),k=a.updatePushAddress,R=k.request.parse(await C("address",{...p,sequence:q.addressSeq,credentialDigest:await D(S)}));if(b(u),r!==o)return null;let T=await f(k.path,R,S);return b(u),r!==o||_(I,v=>v).addressSeq!==q.addressSeq?null:m(k.response.parse(T).installation)}}}}function re(t,e){let n={async preference(i){let c=a.readMessagingPreference;return(await d(t,c,{channel:i})).preference},async setPreference(i){let c=a.setMessagingPreference;return(await d(t,c,i)).preference}};return{messaging:n,push:{sync:e.sync,read:e.read,recover:e.recover,tokenObserver:e.tokenObserver,recoveryObserver:e.recoveryObserver,async preference(){return n.preference("push")},async setPreference(i){return n.setPreference({...i,channel:"push"})}}}}function ie(t,e,n={}){let i=!1;function c(){if(i)throw new s("CLOSED","SDK client was destroyed")}let o=new Set,l=P=>{for(let g of o)try{g(P)}catch{}},y=t.session.subscribeIdentity(()=>{l(!!t.session.peek()),n.afterChange?.()},()=>{e()});return{assertActive:c,isIdentified:()=>!i&&!!t.session.peek(),methods:{subscribeIdentity(P){return c(),o.add(P),()=>{o.delete(P)}},identify(P){c();let g=typeof P=="string"?P:P.accessToken;if(!L.test(g))throw new s("INVALID_TOKEN","Browser SDK requires a customer session");n.beforeIdentify?.(g),t.identify(P)},reset(){if(!i)try{n.beforeReset?.()}finally{t.reset()}},destroy(){if(!i){i=!0,y(),o.clear();try{n.beforeDestroy?.(),e()}finally{t.dispose()}}}}}}function A(t){if(t!==null&&typeof t=="object"&&"customerId"in t)throw new s("INVALID_REQUEST","Customer requests use the verified session identity")}var ge={...a.readHoldings,request:a.readHoldings.request.omit({customerId:!0})};function se(t){return{async checkEntitlement(e){A(e);let n=a.checkEntitlement;return d(t,n,e)},async readHoldings(e={}){return d(t,ge,e)}}}function oe(t){return{async readLedger(e){let n=a.readLedger;return d(t,n,{query:e})},async readCreditStatement(e){A(e);let n=a.readCreditStatement;return d(t,n,e)},async quoteBalance(e){A(e);let n=a.quoteBalance;return d(t,n,{command:e})}}}function ae(t){return{async setupPayment(e){A(e);let n=a.setupPayment;return d(t,n,e)},async readPaymentSetup(e){A(e);let n=a.readPaymentSetup;return d(t,n,e)},async readBillingInvoice(e){A(e);let n=a.readBillingInvoice;return d(t,n,e)},async readBillingControls(e={}){A(e);let n=a.readBillingControls;return d(t,n,e)},async prepareBillingAuthorization(e){A(e);let n=a.prepareBillingAuthorization;return d(t,n,e)},async confirmBillingAuthorization(e){A(e);let n=a.confirmBillingAuthorization;return d(t,n,e)},async setBillingCoupons(e){A(e);let n=a.setBillingCoupons;return d(t,n,e,{request:"Invalid billing coupon list",response:"Invalid billing coupon receipt"})},async revokeBillingAuthorization(e){A(e);let n=a.revokeBillingAuthorization;return d(t,n,e)},async listBillingInvoices(e={after:null,limit:25}){A(e);let n=a.listBillingInvoices;return d(t,n,e)},async confirmBillingAdjustment(e){A(e);let n=a.confirmBillingAdjustment;return d(t,n,e)}}}function ce(t){return{async previewUpdate(e){A(e);let n=a.previewUpdate;return d(t,n,e)},async update(e){A(e);let n=a.update;return d(t,n,e)},async readSubscriptionUpdate(e){A(e);let n=a.readSubscriptionUpdate;return d(t,n,e)},async restoreNativePurchase(e){A(e);let n=a.restoreNativePurchase;return d(t,n,e)},async previewAttach(e){A(e);let n=a.previewAttach;return d(t,n,e)},async attach(e){A(e);let n=a.attach;return d(t,n,e)},async readSubscriptionOperation(e){A(e);let n=a.readSubscriptionOperation;return d(t,n,e)}}}function ue(t){return{async redeemReward(e){return A(e),(await d(t,a.redeemReward,{...e,requestId:e.requestId??crypto.randomUUID()},{request:"Invalid reward redemption",response:"Invalid reward receipt"})).redemption},async claimRewardProduct(e){return A(e),(await d(t,a.claimRewardProduct,e,{request:"Invalid reward product claim",response:"Invalid reward product checkout"})).checkout},async createReferralCode(e){return A(e),(await d(t,a.createReferralCode,{...e,requestId:e.requestId??crypto.randomUUID()},{request:"Invalid referral program",response:"Invalid referral code"})).referralCode},async redeemCoupon(e,n=crypto.randomUUID()){let i=await d(t,a.redeemCoupon,{code:e,requestId:n},{request:"Invalid coupon code",response:"Invalid Coupon receipt"});return{offer:i.offer,reason:i.reason}},async claimCoupon(e,n=crypto.randomUUID()){let i=await d(t,a.grantOffer,{couponId:e,requestId:n},{request:"Invalid Coupon claim",response:"Invalid Coupon receipt"});return{offer:i.offer,reason:i.reason}},async listOffers(){return(await d(t,a.listOffers,{},{response:"Invalid offers response"})).offers}}}function de(t){return{...se(t),...oe(t),...ae(t),...ce(t),...ue(t)}}function pe(t){return{async resolveContent(e){A(e);let n=a.resolveContent;return d(t,n,e)},async resolvePaywall(e){A(e);let n=a.resolvePaywall;return d(t,n,e)},async resolveOffering(e){A(e);let n=a.resolveOffering;return d(t,n,e)}}}var J=t=>new TextEncoder().encode(JSON.stringify(t)).length,le=16384;function fe(t,e){let n=0,i,c=f=>{i={config:structuredClone(f),until:Date.now()+3e4}},o=[],l=null,y;function P(){if(!e())throw new s("NOT_IDENTIFIED","Call identify before using Features or events")}function g(){y||!o.length||(y=setTimeout(()=>{y=void 0,D().catch(()=>{}).finally(g)},5e3),typeof y=="object"&&"unref"in y&&y.unref())}function b(f,w={},E={}){if(P(),i&&Date.now()<i.until&&!X(i.config,f))return;C();let h=a.trackEvents.request.parse({events:[{eventUuid:crypto.randomUUID(),timestamp:new Date().toISOString(),name:f,properties:w,...E}]}).events[0];if(J({events:[h]})>le)throw new s("INVALID_REQUEST","Event exceeds the delivery size limit");if(o.length>=500)throw new s("EVENT_QUEUE_FULL","Flush pending events before tracking more");o.push(structuredClone(h)),g()}async function D(f=!1){if(P(),l)return l;let w=n,E=(async()=>{let h={inserted:0,duplicates:0,rejected:0,skipped:0},O=o.length;for(;O&&w===n;){let r=[],u=J({events:[]});for(let S of o.slice(0,Math.min(O,100))){let q=J(S)+(r.length?1:0);if(r.length&&u+q>le)break;r.push(S),u+=q}let p=a.trackEvents,I=await d(t,p,{events:r},void 0,{keepalive:f});if(w!==n)throw new s("IDENTITY_CHANGED","Event identity changed during delivery");if(I.inserted+I.duplicates+I.rejected+I.skipped!==r.length)throw new s("INVALID_RESPONSE","Incomplete event acknowledgement");c(I.analyticsConfig),o.splice(0,r.length),O-=r.length,h.inserted+=I.inserted,h.duplicates+=I.duplicates,h.rejected+=I.rejected,h.skipped+=I.skipped}return h})();l=E;try{return await E}finally{l===E&&(l=null)}}let m;function C(){if(m||typeof document>"u")return;let f=()=>{document.visibilityState==="hidden"&&e()&&o.length&&D(!0).catch(()=>{})};document.addEventListener("visibilitychange",f),m=()=>document.removeEventListener("visibilitychange",f)}return{rememberConfiguration:c,track:b,flush:D,reset(){n++,i=void 0,clearTimeout(y),y=void 0,o=[],l=null},detachVisibility(){m?.(),m=void 0}}}function me(t){let e=t.merchandise;if(typeof t.merchandiseId=="string")return{internalId:t.merchandiseId};if(!(!e||typeof e!="object"||Array.isArray(e))){if(typeof e.internalId=="string")return{internalId:e.internalId};if(typeof e.externalId=="string")return{id:e.externalId};if(typeof e.id=="string")return{id:e.id}}}function we(t){let e=me(t),{merchandiseId:n,merchandise:i,...c}=t;return{...c,...e?{merchandise:e}:{}}}function ye(t,e,n,i,c){if(c&&i&&(c.scope.projectId!==i.projectId||c.scope.environment!==i.environment))throw new s("SCOPE_MISMATCH","Configuration belongs to another App/environment");let o=0,l=new Set;function y(){if(!e())throw new s("NOT_IDENTIFIED","Call identify before using Features or events")}async function P(g={}){c||y();let b=o,D=!1,m=async()=>{if(D||b!==o)throw new s("IDENTITY_CHANGED","Feature identity changed");let R=a.getFeatures,T=c?{scope:{projectId:c.scope.projectId,environment:c.scope.environment},payload:await c.features()}:await d(t,R,{});if(b!==o)throw new s("IDENTITY_CHANGED","Feature identity changed");if(i&&(T.scope.projectId!==i.projectId||T.scope.environment!==i.environment))throw new s("INVALID_RESPONSE","Feature response scope changed");return n.rememberConfiguration(T.payload.analyticsConfig),T},C=await m(),f=!0,w,E=R=>{try{g.onError?.(R)}catch{}},h=(R,T,v)=>{try{let V=me(v);n.track(R,T,V?{merchandise:V}:{})}catch(V){E(V)}},O=ee({assertUsable:c?.assertFeatures,scope:C.scope,attributes:g.attributes,onError:g.onError,load:async()=>f?(f=!1,C.payload):(await m()).payload,evaluateRemote:async R=>{if(b!==o)throw new s("IDENTITY_CHANGED","Feature identity changed");let T=a.evaluateFeatures,v=await d(t,T,{...R,attributes:we(R.attributes)});if(v.scope.projectId!==C.scope.projectId||v.scope.environment!==C.scope.environment)throw new s("INVALID_RESPONSE","Remote Feature response scope changed");return{generation:v.generation,evaluatedAt:v.evaluatedAt,expiresAt:v.expiresAt,features:v.features,...v.merchandiseContext?{merchandiseContext:v.merchandiseContext}:{}}},onExperimentViewed:(R,T,v)=>h("Experiment Viewed",{experimentId:R.key,variationId:T.key},v),onFeatureUsage:(R,T,v)=>h("Feature Evaluated",{feature:R,value:T.value,source:T.source,ruleId:T.ruleId,...T.experimentResult?{variationId:T.experimentResult.key}:{}},v)}),r=O.refresh;function u(){clearTimeout(w),!c&&(D||b!==o||!O.expiresAt||(w=setTimeout(()=>{p().catch(E)},Math.min(2147483647,Math.max(1e3,Date.parse(O.expiresAt)-Date.now()))),typeof w=="object"&&"unref"in w&&w.unref()))}async function p(){try{return await r()}finally{u()}}let I=()=>{D||p().catch(E)},S=O.subscribe(u),q=c?.subscribe(()=>{!D&&c.fresh&&p().catch(E)});function k(){D||(D=!0,clearTimeout(w),typeof window<"u"&&window.removeEventListener("focus",I),S(),q?.(),O.reset(),l.delete(k))}l.add(k);try{await O.init(),(g.attributes?.merchandise||g.attributes?.merchandiseId)&&await O.refreshRemote()}catch(R){throw k(),R}return u(),!c&&typeof window<"u"&&window.addEventListener("focus",I),Object.assign(O,{refresh:p,destroy:k})}return{features:P,reset(g){o++,g();for(let b of l)b()}}}import{z as ve}from"zod";function Ie(t,e){let n="source"in e?{funnelId:e.source.id,funnelVersionId:e.source.versionId}:"versionId"in e?{funnelId:e.funnelId,funnelVersionId:e.versionId}:e,i=ve.object({funnelId:H.shape.id,funnelVersionId:H.shape.versionId.optional()}).safeParse(n);if(!i.success)throw new s("INVALID_REQUEST","A valid Funnel source is required");let c=Object.freeze(i.data);function o(l){if("customerId"in l)throw new s("INVALID_REQUEST","Customer identity cannot be overridden");if("funnelId"in l&&l.funnelId!==void 0&&l.funnelId!==c.funnelId||"funnelVersionId"in l&&l.funnelVersionId!==void 0&&l.funnelVersionId!==c.funnelVersionId)throw new s("SCOPE_MISMATCH","The original Funnel source cannot change");return{...l,...c}}return{async claimCoupon(l,y=crypto.randomUUID()){let P=a.grantOffer,g=await d(t,P,o({couponId:l,requestId:y}));return{offer:g.offer,reason:g.reason}},async resolveOffering(l){let y=a.resolveOffering;return d(t,y,o(l))},async resolvePaywall(l){let y=a.resolvePaywall;return d(t,y,o(l))},async previewAttach(l){let y=a.previewAttach;return d(t,y,o(l))}}}function Dt(t){return Ae(t)}function Ae(t){let e=Z(t),n=e.request,i;try{i=ne(t.push,e,t.scope??t.configuration?.scope)}catch(y){throw e.dispose(),y}let c=ie(e,()=>{l.reset(o.reset),o.detachVisibility()},{beforeIdentify:i.identify,beforeReset:i.reset,afterChange:i.start,beforeDestroy:i.destroy}),o=fe(n,c.isIdentified),l=ye(n,c.isIdentified,o,t.scope,t.configuration);return{session:e.session,...re(n,i),...de(n),...pe(n),forFunnel(y){return c.assertActive(),Ie(n,y)},async features(y={}){return c.assertActive(),l.features(y)},track(y,P,g={}){return o.track(y,P,g)},flush(){return o.flush()},...c.methods}}function Ut(t){if(!L.test(t.customerToken))throw new s("INVALID_TOKEN","A customer credential is required");if(!t.scope)throw new s("INVALID_REQUEST","An explicit App and environment scope is required");let e=te({...t,scope:t.scope,apiKey:t.customerToken});return{async start(n){let i=await e.start(n),c=B({...t,runToken:i.runToken});c.identify(t.customerToken);let o=i.run.instruction?.type==="evaluate_segment"?await c.get():i;return{...i,...o,controller:c}}}}function Gt(t){if(!t.scope)throw new s("INVALID_CONFIGURATION","An explicit process App/environment scope is required");if(t.session!==void 0)throw new s("INVALID_CONFIGURATION","The merchant process adapter owns the session");let e=null,n,i=0,c=new Set,o=new Map,l=new Map;async function y(m){let C,f=new Promise((w,E)=>{C=setTimeout(()=>E(new s("TIMEOUT","Process bridge request timed out")),t.timeoutMs??35e3)});try{return await Promise.race([Promise.resolve().then(m),f])}finally{clearTimeout(C)}}function P(m){throw m instanceof s&&(m.status===401||m.reason==="CUSTOMER_BINDING_CONFLICT")&&(i++,n?.reset(),n=void 0,e=null,o.clear(),l.clear()),m}function g(m,C){if(C!==i)throw new s("IDENTITY_CHANGED","Process was detached during a request");let f=$.parse(m);if(f.scope.projectId!==t.scope.projectId||f.scope.environment!==t.scope.environment)throw new s("SCOPE_MISMATCH","Process response belongs to another App/environment");if(e&&(e.run.id!==f.run.id||e.run.source.versionId!==f.run.source.versionId||e.run.source.id!==f.run.source.id||e.run.runExpiresAt!==f.run.runExpiresAt||e.run.identity.startedAs!==f.run.identity.startedAs||e.run.identity.participantId!==f.run.identity.participantId||e.run.identity.binding&&f.run.identity.binding&&e.run.identity.binding.id!==f.run.identity.binding.id))throw new s("INVALID_RESPONSE","The process changed its Run or Customer binding");if(!e||f.run.revision>=e.run.revision){if(e?.run.identity.binding&&!f.run.identity.binding)throw new s("INVALID_RESPONSE","The process lost its Customer binding");e=f;for(let I of c)G(I,f.run);f.run.instruction?.type==="authentication_required"&&G(t.onAuthenticationRequired,f.run)}f.settlement?.accepted!==void 0&&l.set(f.settlement.requestId,f.settlement.accepted);let{identity:w,instruction:E,...h}=f.run,{contract:O,settlement:r,...u}=f,p=r&&(({accepted:I,...S})=>S)(r);return{...u,run:{...h,authenticated:w.binding!==null,instruction:E?.type==="authentication_required"?null:E},...p?{settlement:p}:{}}}let b=m=>(o.has(m)||o.set(m,e?.run.identity.binding?.id??null),o.get(m));async function D(m){let C=i,f=e?.run.identity.binding?.id??null,w=h=>{if(f!==(e?.run.identity.binding?.id??null))throw h;return P(h)};if(m.operation==="page_experiments"){if(!t.adapter.pageExperiments)throw new s("CAPABILITY_UNAVAILABLE","Process page experiments are unavailable",501);return y(()=>t.adapter.pageExperiments(m.release,m.usedReceiptIds)).catch(w)}let E;if(m.operation==="get"){let{operation:h,customerToken:O,...r}=m;E=await y(()=>t.adapter.get({...r,...r.settlementRequestId?{settlementBindingId:b(r.settlementRequestId)}:{}})).catch(w)}else if(m.operation==="review")E=await y(()=>t.adapter.review(m.receiptId)).catch(w);else{if(m.operation==="start")throw new s("INVALID_REQUEST","Use process.open for entry");{let{customerToken:h,...O}=m;E=await y(()=>t.adapter.command(O,b(O.requestId))).catch(w)}}return g(E,C)}return{get view(){return e?.run??null},get controller(){return n},async open(m){let C=i,f=await y(()=>t.adapter.open(m)).catch(P);if(g(f,C),!n){n=B({...t,runToken:f.runToken,process:{request:D,binding:b,restore(h){for(let[O,r]of Object.entries(h))o.set(O,r)}}});let w=n,E=w.submit;w.submit=async h=>{try{return await E(h)}catch(O){if(!(O instanceof s)||O.reason!=="IDENTITY_CONTEXT_CHANGED"||h.operation!=="submit"||h.input.type!=="screen"||o.get(h.requestId)!==null)throw O;await w.settle?.(h.requestId),await w.get();let r=w.view;if(l.get(h.requestId)!==!1||!r||r.id!==e?.run.id||r.nodeId!==h.nodeId||r.visit!==h.visit||!e?.run.identity.binding)throw O;return E({...h,requestId:crypto.randomUUID(),revision:r.revision})}}}await n.get();for(let w of n.pendingCommands??[])o.has(w.requestId)&&o.get(w.requestId)!==(e?.run.identity.binding?.id??null)&&await n.settle?.(w.requestId);return{run:e.run,controller:n}},async syncIdentity(){let m=i;g(await y(()=>t.adapter.syncIdentity()).catch(P),m),await n?.get();for(let C of n?.pendingCommands??[])o.has(C.requestId)&&o.get(C.requestId)!==(e?.run.identity.binding?.id??null)&&await n?.settle?.(C.requestId);return e.run},async detach(){i++,n?.reset(),n=void 0,e=null,o.clear(),l.clear(),await y(()=>t.adapter.detach())},forProcess(m){if(!e?.run.identity.binding)throw new s("UNAUTHENTICATED","Sign in before a commercial operation",401);return{runId:e.run.id,bindingId:e.run.identity.binding.id,receiptId:m}},subscribe(m){return c.add(m),()=>{c.delete(m)}},destroy(){i++,n?.reset(),n=void 0,e=null,o.clear(),l.clear(),c.clear()}}}export{Dt as a,Ae as b,Ut as c,Gt as d};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as u}from"./chunk-DSPLGTQI.js";import{cb as d}from"./chunk-
|
|
1
|
+
import{a as u}from"./chunk-DSPLGTQI.js";import{cb as d}from"./chunk-XJBCPOFT.js";function m(e){if(!/^[A-Za-z0-9_-]{1,64}$/.test(e))throw new Error("Invalid device cookie name");let t="";for(let i of document.cookie.split(";"))if(i.trim().startsWith(`${e}=`))try{t=decodeURIComponent(i.trim().slice(e.length+1))}catch{}return/^[A-Za-z0-9_-]{8,128}$/.test(t)||(t=crypto.randomUUID(),document.cookie=`${e}=${encodeURIComponent(t)}; path=/; max-age=${400*24*3600}; SameSite=Lax`),t}function y(){try{let e=sessionStorage.getItem("indiana_sid");return e||(e=crypto.randomUUID(),sessionStorage.setItem("indiana_sid",e)),e}catch{return}}function g(e=d){let t=new URL(e);if(t.protocol!=="https:"&&!(t.protocol==="http:"&&["localhost","127.0.0.1","[::1]"].includes(t.hostname))||t.username||t.password||t.search||t.hash)throw new Error("baseUrl must be an https origin without credentials");return t.origin}var o=new Set,s;function S(e){let t=()=>e();if(o.add(t),!s){let i=!0,a=history.pushState,p=history.replaceState,r=()=>{if(i)for(let n of[...o])o.has(n)&&u(n)},c=function(...n){a.apply(this,n),r()},h=function(...n){p.apply(this,n),r()};history.pushState=c,history.replaceState=h,addEventListener("popstate",r),addEventListener("hashchange",r),s=()=>{i=!1,history.pushState===c&&(history.pushState=a),history.replaceState===h&&(history.replaceState=p),removeEventListener("popstate",r),removeEventListener("hashchange",r)}}return()=>{o.delete(t)&&(o.size||(s?.(),s=void 0))}}export{m as a,y as b,g as c,S as d};
|