@tinkerlandai/indiana-sdk 0.8.4 → 0.8.5
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 +9 -1
- package/README.md +32 -3
- package/README.zh-CN.md +32 -3
- package/dist/chunk-3KQHKRZJ.js +1 -0
- package/dist/chunk-6A5WWFNS.js +10 -0
- package/dist/{chunk-F2GOIBDQ.js → chunk-A3XRIG53.js} +1 -1
- package/dist/{chunk-663UOBHL.js → chunk-FGIGKO7A.js} +1 -1
- package/dist/chunk-HEBQUICQ.js +4 -0
- package/dist/{chunk-3F2NQOR2.js → chunk-SUXAWRR6.js} +1 -1
- package/dist/chunk-WWUUVURR.js +1 -0
- package/dist/{content-2FCUY6XX.js → content-DDMDNRCV.js} +1 -1
- package/dist/funnel-runtime-host-QK6WDRPS.js +1 -0
- package/dist/index.js +1 -1
- package/dist/native-shell.js +1 -1
- package/dist/openrouter.js +1 -1
- package/dist/page.js +1 -1
- package/dist/{paywall-734GWAS4.js → paywall-4QT3JYD4.js} +1 -1
- package/dist/react-native.js +1 -1
- package/dist/server.js +1 -1
- package/dist/{src-CLEFCTAU.js → src-EG7RWDDY.js} +1 -1
- package/dist/visual.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-EJTBSGLV.js +0 -10
- package/dist/chunk-EXCPE2XH.js +0 -1
- package/dist/chunk-RZBZ6LCT.js +0 -4
- package/dist/chunk-SSHUBTT3.js +0 -1
- package/dist/funnel-runtime-host-ENRTSXPJ.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,13 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
Release facts and artifact evidence: [SDK release ledger](../../docs/sdk-releases.md).
|
|
4
4
|
|
|
5
|
+
## 0.8.5 — 2026-10-27
|
|
6
|
+
|
|
7
|
+
- Add direct browser script loading through `/sdk.js`, sharing the npm browser APIs and page/visual experiment factories without requiring a bundler. Website deployment distributes this entry independently of npm publication.
|
|
8
|
+
- Keep IAM release markers attached through host updates, group render-signature queries, and recover bounded visual work without duplicate exposure events.
|
|
9
|
+
- Disable Funnel Back navigation until the current presentation is rendered, and include the SDK version in experiment-event requests.
|
|
10
|
+
- Synchronize the packaged Web, iOS and Android renderers while retaining HTTP protocol 0.8.
|
|
11
|
+
|
|
5
12
|
## 0.8.4 — 2026-10-26
|
|
6
13
|
|
|
7
14
|
- Add `prepareContent` and `preparePopup` to render authorized content before the opening click and reveal the same iframe on demand.
|
|
8
15
|
- 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
16
|
- 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
17
|
- Synchronize the packaged Web, iOS and Android renderers. Retain HTTP protocol 0.8 and server authority over Funnel acceptance and commercial operations.
|
|
11
|
-
-
|
|
18
|
+
- Carry the committed Merchandise context through Feature evaluation, page experiments, Analytics events and Coupon applicability; refresh the generated native Paywall schema.
|
|
19
|
+
- Include the committed Android Push recovery proofs, visual target diagnostics and Paywall/Funnel focus restoration fixes.
|
|
12
20
|
|
|
13
21
|
## 0.8.3 — 2026-10-26
|
|
14
22
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @tinkerlandai/indiana-sdk
|
|
2
2
|
|
|
3
|
-
These examples use SDK 0.8.
|
|
3
|
+
These examples use SDK 0.8.4 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,13 +9,42 @@ 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.
|
|
12
|
+
npm install --save-exact @tinkerlandai/indiana-sdk@0.8.4
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
SDK 0.8.
|
|
15
|
+
SDK 0.8.4 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
|
|
|
19
|
+
## Plain HTML / script installation
|
|
20
|
+
|
|
21
|
+
The classic-script entry reuses the npm browser implementation, with no bundler:
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<script src="https://dev.tinker.cash/sdk.js"></script>
|
|
25
|
+
<script type="module">
|
|
26
|
+
const {
|
|
27
|
+
createIndiana,
|
|
28
|
+
createPaywallSession,
|
|
29
|
+
showPaywall,
|
|
30
|
+
createFunnelRunController,
|
|
31
|
+
showFunnelRun,
|
|
32
|
+
mountContent,
|
|
33
|
+
} = await Indiana.ready;
|
|
34
|
+
const client = createIndiana({
|
|
35
|
+
baseUrl: "https://api.dev.tinker.cash",
|
|
36
|
+
scope: { projectId: "<APP_UUID>", environment: "sandbox" },
|
|
37
|
+
});
|
|
38
|
+
// Obtain customerToken from your authenticated backend session endpoint.
|
|
39
|
+
// client.identify(customerToken);
|
|
40
|
+
// await client.readHoldings();
|
|
41
|
+
// client.track("page_viewed", { page: location.pathname });
|
|
42
|
+
// await client.flush();
|
|
43
|
+
</script>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Production uses `https://tinker.cash/sdk.js` and its matching API/credentials. `Indiana.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 `Indiana`. 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://tinker.cash/docs/javascript#script).
|
|
47
|
+
|
|
19
48
|
## React Native core
|
|
20
49
|
|
|
21
50
|
Use the independent `@tinkerlandai/indiana-react-native` package. The `@tinkerlandai/indiana-sdk/react-native` subpath shares the same implementation. Both support Customer Token identity, holdings, entitlement checks and usage reporting through your authenticated backend. It requires no DOM or native UI/store bridge. See [mobile SDK installation and examples](../../docs/mobile-sdk.md).
|
package/README.zh-CN.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[English](./README.md)
|
|
2
2
|
|
|
3
|
-
本页使用 SDK 0.8.
|
|
3
|
+
本页使用 SDK 0.8.4、`https://api.dev.tinker.cash` 与测试 App 凭据(协议 0.8)。切换前核对[环境状态](../../docs/development-status.md)。SDK 默认仍指向生产 API,本页示例必须显式设置 `baseUrl`。
|
|
4
4
|
|
|
5
5
|
# @tinkerlandai/indiana-sdk
|
|
6
6
|
|
|
@@ -9,13 +9,42 @@
|
|
|
9
9
|
**IAM 的源码扫描、生成、校验和上传属于独立构建包 `@tinkerlandai/indiana-iam`。** 普通业务 SDK 只保留 GB visual 应用页面变更所需的运行时 release 绑定。完整定义见 [SDK 边界](../../docs/sdk-architecture.md) 与 [IAM 构建包](../iam/README.md)。
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
|
-
npm install --save-exact @tinkerlandai/indiana-sdk@0.8.
|
|
12
|
+
npm install --save-exact @tinkerlandai/indiana-sdk@0.8.4
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
SDK 0.8.
|
|
15
|
+
SDK 0.8.4 要求 HTTP 协议 0.8。安装版本须与运行服务匹配;发布包不会部署服务端。实际发布、标签与环境验收范围见 [SDK 发布总账](../../docs/sdk-releases.md) 和 [开发状态](../../docs/development-status.md)。
|
|
16
16
|
|
|
17
17
|
数据/会话层负责公开 JSON、完整性校验和鉴权操作;展示宿主将会话接口接入打包的屏幕渲染器,渲染器消费已提供的数据并返回动作意图。客户端按需加载展示;`/server` 入口使用商户后端的受限 Server Key,不加载屏幕展示。SDK 本地检查不替代运行时授权或付款核实。后台 Preview 为同一个展示宿主提供模拟会话和数据。
|
|
18
18
|
|
|
19
|
+
## 普通 HTML / script 接入
|
|
20
|
+
|
|
21
|
+
普通 script 标签复用 npm 浏览器实现,无需打包工具:
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<script src="https://dev.tinker.cash/sdk.js"></script>
|
|
25
|
+
<script type="module">
|
|
26
|
+
const {
|
|
27
|
+
createIndiana,
|
|
28
|
+
createPaywallSession,
|
|
29
|
+
showPaywall,
|
|
30
|
+
createFunnelRunController,
|
|
31
|
+
showFunnelRun,
|
|
32
|
+
mountContent,
|
|
33
|
+
} = await Indiana.ready;
|
|
34
|
+
const client = createIndiana({
|
|
35
|
+
baseUrl: "https://api.dev.tinker.cash",
|
|
36
|
+
scope: { projectId: "<APP_UUID>", environment: "sandbox" },
|
|
37
|
+
});
|
|
38
|
+
// 从验证登录后的自有后端接口获取 customerToken。
|
|
39
|
+
// client.identify(customerToken);
|
|
40
|
+
// await client.readHoldings();
|
|
41
|
+
// client.track("page_viewed", { page: location.pathname });
|
|
42
|
+
// await client.flush();
|
|
43
|
+
</script>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
生产脚本为 `https://tinker.cash/sdk.js`,配套使用同环境 API 和凭据。`Indiana.ready` 返回根入口的全部浏览器导出,以及 `createPageExperiments` / `createVisualExperiments`;下文 npm import 可替换为从该 Promise 解构同名函数。加载不自动创建会话、发送事件或启动实验。Server Key 留在后端,Funnel 启动恢复与退出清理沿用现有流程。重复标签共用 ready,失败会拒绝 Promise,UI 按需加载。加载标签使用普通 script;添加 async/defer 时先等标签 load 事件,再访问 Indiana。CSP 需允许脚本来源和 API 连接。页面实验也使用该统一入口,显式创建客户端并调用 `start()`。详见 [script 分发](../../docs/sdk-architecture.md#web-script-distribution)和[完整接入示例](https://tinker.cash/docs/javascript#script)。
|
|
47
|
+
|
|
19
48
|
## React Native 核心入口
|
|
20
49
|
|
|
21
50
|
React Native 使用独立包 `@tinkerlandai/indiana-react-native`,原 `@tinkerlandai/indiana-sdk/react-native` 子入口共用同一实现。两者均支持 Customer Token 身份接入、权益读取和经业务后端转发的用量上报。此入口无需 DOM,不包含原生 UI 或内购桥接。参见[移动端 SDK 安装与示例](../../docs/mobile-sdk.md)。
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{o as E,p as L,s as R}from"./chunk-6A5WWFNS.js";import{a as e}from"./chunk-SOQO2RDZ.js";import{a as P,j as C,m as D,p as j}from"./chunk-LMR2TM3X.js";import{b}from"./chunk-OBYJWIRB.js";import{a as U,b as M}from"./chunk-WWUUVURR.js";var H=Symbol("IndianaNoContent");function Q(u,q,k=URL){let l=u.configuration?.scope,A=u.scope??(l&&{projectId:l.projectId,environment:l.environment}),s=A?b.parse(A):void 0;if(s&&l&&(s.projectId!==l.projectId||s.environment!==l.environment))throw new e("SCOPE_MISMATCH","Configuration belongs to another App/environment");let i=new k(u.baseUrl??M);if(i.username||i.password||i.search||i.hash)throw new e("INVALID_URL","baseUrl must not contain credentials, query, or fragment");if(i.protocol!=="https:"&&!(i.protocol==="http:"&&["localhost","127.0.0.1","[::1]"].includes(i.hostname)))throw new e("INVALID_URL","Use HTTPS, or HTTP on localhost during development");let V=u.fetch??globalThis.fetch.bind(globalThis),p=u.timeoutMs??1e4;if(!Number.isFinite(p)||p<1||p>12e4)throw new e("INVALID_TIMEOUT","timeoutMs must be between 1 and 120000");let m=null,f=0,h=null,w=new Set;function O(){f+=1,m=null,h=null;for(let a of w)a.abort();w.clear()}async function K(a,x={},T="POST",v={}){let d=v.installationDetach===!0;if(d&&(a!=="push/installations/detach"||T!=="POST"))throw new e("INVALID_REQUEST","Installation authority only detaches this installation");if(!m&&!d)throw new e("NOT_IDENTIFIED","Call identify with a server-issued customer token first");let y=f,o=new AbortController;d||w.add(o);let g=()=>!d&&y!==f?new e("IDENTITY_CHANGED","Customer identity changed while the request was in flight"):new e("TIMEOUT","Indiana request timed out"),S,F=new Promise((n,r)=>{S=()=>r(g()),o.signal.addEventListener("abort",S,{once:!0})}),X=setTimeout(()=>o.abort(),p),$=async()=>{let n=await V(`${i.href.replace(/\/$/,"")}/api/v1/${a}`,{method:T,headers:{"Content-Type":"application/json",...d?{}:{Authorization:`Bearer ${m}`},[E]:R.current,[L]:U.version,...s?{"X-Indiana-Project":s.projectId,"X-Indiana-Environment":s.environment}:{}},body:T==="POST"?JSON.stringify(x):void 0,signal:o.signal,credentials:"omit",cache:"no-store",redirect:"error",...v.keepalive?{keepalive:!0}:{}});if(o.signal.aborted)throw g();let r;try{r=n.status===204?H:await n.json()}catch{throw o.signal.aborted?g():new e(n.ok?"INVALID_RESPONSE":"HTTP_ERROR","The gateway returned an unreadable response",n.status,n.headers.get("X-Request-Id")??void 0)}if(o.signal.aborted)throw g();if(!d&&y!==f)throw new e("IDENTITY_CHANGED","Customer identity changed while the request was in flight");if(!n.ok){let t=D.safeParse(r),c=t.success&&(!P.safeParse(t.data.error.code).success||C(t.data.error.code,n.status)),N=c?t.data.error.code:"HTTP_ERROR",_=j(N,n.status,{retryAfter:n.headers.get("Retry-After"),recovery:c?t.data.error.recovery:void 0,reason:c?t.data.error.reason:void 0});throw new e(N,c?t.data.error.message:"Indiana request failed",n.status,n.headers.get("X-Request-Id")??(t.success?t.data.requestId:void 0),{..._,...t.success&&t.data.error.retryable===!1?{retryable:!1}:{},..._.retryAfterSeconds===void 0&&t.success&&t.data.error.retryAfterSeconds!==void 0?{retryAfterSeconds:t.data.error.retryAfterSeconds}:{}})}if(n.headers.get(E)!==R.current)throw new e("PROTOCOL_MISMATCH","Response protocol does not match this SDK");if(s&&r!==H){let t=r&&typeof r=="object"&&"scope"in r?r:r&&typeof r=="object"&&"configuration"in r?r.configuration:null;if(!t||typeof t!="object"||!("scope"in t))throw new e("INVALID_RESPONSE","Response is missing its App/environment scope");let c=b.safeParse(t.scope);if(!c.success||c.data.projectId!==s.projectId||c.data.environment!==s.environment)throw new e("SCOPE_MISMATCH","Response scope does not match this SDK instance")}let I=n.headers.get("X-Indiana-Telemetry-Subject");if(I){if(!/^[a-f0-9]{64}$/.test(I))throw new e("INVALID_RESPONSE","Invalid telemetry identity");h!==I&&(h=I,q?.(h))}return r};try{return await Promise.race([$(),F])}catch(n){throw!d&&y!==f?new e("IDENTITY_CHANGED","Customer identity changed while the request was in flight"):n instanceof e?n:new e(o.signal.aborted?"TIMEOUT":"NETWORK_ERROR",o.signal.aborted?"Indiana request timed out":"Unable to read the Indiana response")}finally{clearTimeout(X),o.signal.removeEventListener("abort",S),w.delete(o)}}return{subjectKey:()=>h,identify(a){if(!a.trim()||/\s/.test(a)||a.length>4096)throw new e("INVALID_TOKEN","A nonempty server-issued token is required");O(),m=a},reset:O,request:K}}export{Q as a};
|