@tinkerlandai/indiana-sdk 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +18 -13
- package/README.zh-CN.md +7 -4
- package/THIRD_PARTY_NOTICES.md +28 -0
- package/dist/{ai-usage-D_mBF5Gp.d.ts → ai-usage-D9xVKhvu.d.ts} +11 -0
- package/dist/chunk-2UFPTDCV.js +4 -0
- package/dist/chunk-LFNFVYC2.js +1 -0
- package/dist/chunk-PVJKOUNE.js +11 -0
- package/dist/chunk-TZ6REIUE.js +17 -0
- package/dist/chunk-VTSEZ4GI.js +1 -0
- package/dist/chunk-ZT523F45.js +1 -0
- package/dist/funnel-runtime-host-4PQY2MFC.js +1 -0
- package/dist/{funnel-runtime-start-CQhy2kx1.d.ts → funnel-runtime-start-B93fV5gJ.d.ts} +6 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +1 -1
- package/dist/native-shell.js +1 -1
- package/dist/openrouter.d.ts +1 -1
- package/dist/openrouter.js +1 -1
- package/dist/page.d.ts +1 -0
- package/dist/page.js +1 -4
- package/dist/{paywall-Y3FIG43H.js → paywall-M5CIDUIT.js} +1 -1
- package/dist/popup.js +6 -5
- package/dist/server.d.ts +2 -2
- package/dist/server.js +1 -1
- package/dist/src-XEDJAKEB.js +1 -0
- package/dist/visual-editor-agent-PYMKMPY3.js +1 -0
- package/dist/visual.d.ts +38 -0
- package/dist/visual.js +1 -0
- package/package.json +6 -1
- package/dist/chunk-CRJJ4EA2.js +0 -1
- package/dist/chunk-D37O6FAW.js +0 -11
- package/dist/chunk-G5ZGWOLJ.js +0 -1
- package/dist/chunk-MJG7X7LM.js +0 -17
- package/dist/funnel-runtime-host-X7AGEGHN.js +0 -1
- package/dist/src-RZJKF6LQ.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
Release facts and artifact evidence: [SDK release ledger](../../docs/sdk-releases.md). Earlier personal-package versions are preserved in [@houzhen888/groove-grow history](../../docs/sdk-changelog-groove-grow.md). The two packages have independent version histories.
|
|
4
4
|
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
- Separate remote Screen navigation (10 seconds), bridge handshake (5 seconds) and first render (5 seconds) startup budgets. Count visible time only, identify the timed-out phase and cancel timers/listeners on render or disposal. A slow valid document no longer consumes the bridge budget before it loads.
|
|
8
|
+
|
|
9
|
+
## 0.4.0 — 2026-10-18
|
|
10
|
+
|
|
11
|
+
- Use protocol 0.4 with environment-scoped behavior, experiment-exposure and Feature-usage collection policies. New required delivery and tracking acknowledgement fields require a matching service release.
|
|
12
|
+
- Acknowledge disabled categories through `skipped`; preserve UUID/timestamp replay identity and keep database enforcement authoritative. Collection settings do not delete history or affect billable usage.
|
|
13
|
+
- Cache SDK collection hints for 30 seconds and refresh on demand after expiry. Identity changes clear hints; re-enabling collection resumes eligible exposure/Feature-usage recording without repeating visual changes.
|
|
14
|
+
- Publish on `beta`; keep `latest` unchanged. Production and native package/store rollout remain separate.
|
|
15
|
+
|
|
5
16
|
## 0.3.1 — 2026-10-17
|
|
6
17
|
|
|
7
18
|
- Make English the default package README and include a separately linked Simplified Chinese translation.
|
package/README.md
CHANGED
|
@@ -2,30 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
[简体中文](./README.zh-CN.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Version `0.4.0` uses protocol `0.4` for environment analytics collection controls and requires a matching Indiana server and database deployment. It is distributed on the `beta` tag; the `latest` tag remains unchanged.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Indiana's JavaScript and TypeScript SDK for browsers, Node.js, screen rendering, and optional AI usage integrations. Version `0.4.0` uses protocol `0.4` and requires a matching Indiana server and database deployment.
|
|
8
|
+
|
|
9
|
+
Protocol `0.4` includes collection policy in Feature/page/visual delivery and `skipped` tracking acknowledgements. Disabled collection keeps existing history and does not change billable usage. SDKs cache the policy for 30 seconds; the database checks each batch. Older `0.x` clients, including requests without a protocol header, are rejected before business operations run.
|
|
8
10
|
|
|
9
11
|
```sh
|
|
10
|
-
npm install @tinkerlandai/indiana-sdk@0.
|
|
12
|
+
npm install @tinkerlandai/indiana-sdk@0.4.0
|
|
11
13
|
```
|
|
12
14
|
|
|
13
15
|
## Version compatibility and support
|
|
14
16
|
|
|
15
17
|
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://tinker.cash/docs/release-notes#support-policy).
|
|
16
18
|
|
|
17
|
-
Version `0.
|
|
19
|
+
Version `0.4.0` sends protocol and SDK version headers and validates the protocol declared by successful responses. Headerless historical clients retain the fixed identity `0.2`; they do not follow the current protocol automatically. Updating source code does not change an existing npm artifact or deploy a server.
|
|
18
20
|
|
|
19
|
-
## One package,
|
|
21
|
+
## One package, seven entry points
|
|
20
22
|
|
|
21
|
-
| Import
|
|
22
|
-
|
|
|
23
|
-
| `@tinkerlandai/indiana-sdk`
|
|
24
|
-
| `@tinkerlandai/indiana-sdk/server`
|
|
25
|
-
| `@tinkerlandai/indiana-sdk/popup`
|
|
26
|
-
| `@tinkerlandai/indiana-sdk/openrouter`
|
|
27
|
-
| `@tinkerlandai/indiana-sdk/native-shell` | Static Funnel shell assets for native WebViews
|
|
28
|
-
| `@tinkerlandai/indiana-sdk/page`
|
|
23
|
+
| Import | Purpose |
|
|
24
|
+
| ---------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
25
|
+
| `@tinkerlandai/indiana-sdk` | Browser Customer, Funnel, Feature, and standalone Paywall clients |
|
|
26
|
+
| `@tinkerlandai/indiana-sdk/server` | Trusted Node.js backend, Customer Sessions, business writes, and Funnel decisions |
|
|
27
|
+
| `@tinkerlandai/indiana-sdk/popup` | Standalone screen rendering, sanitization, and previews |
|
|
28
|
+
| `@tinkerlandai/indiana-sdk/openrouter` | Optional OpenRouter usage integration; requires its peer dependency |
|
|
29
|
+
| `@tinkerlandai/indiana-sdk/native-shell` | Static Funnel shell assets for native WebViews |
|
|
30
|
+
| `@tinkerlandai/indiana-sdk/page` | Anonymous website URL experiments using a public App environment ID |
|
|
31
|
+
| `@tinkerlandai/indiana-sdk/visual` | Anonymous visual experiments and exposure collection using a public environment ID |
|
|
29
32
|
|
|
30
33
|
The same package supports JavaScript and TypeScript and includes type declarations. Internal `@indiana/contracts` code is bundled; consumers do not install private workspace packages. Swift and Kotlin use their own package ecosystems and are released separately.
|
|
31
34
|
|
|
@@ -118,6 +121,8 @@ unsubscribe();
|
|
|
118
121
|
flags.destroy();
|
|
119
122
|
```
|
|
120
123
|
|
|
124
|
+
In the unpublished 0.4 candidate, the selected environment's integration settings control behavior events, experiment exposures and Feature usage independently. New environments enable only exposure collection; existing environments retain all three. `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.
|
|
125
|
+
|
|
121
126
|
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.
|
|
122
127
|
|
|
123
128
|
Offering pins the Product Version scope and hierarchy. Paywall pins a published Offering Version and independently chooses its displayed Product subset, groups, ordering, and default selection. `createPaywallStartClient`, `createPaywallSession`, and `showPaywall` use a standalone Paywall Session. After payment, read Entitlements again. Your backend still authorizes requests and consumes usage idempotently.
|
package/README.zh-CN.md
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
# @tinkerlandai/indiana-sdk
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
SDK `0.4.0` 使用协议 `0.4`,通过 `beta` 标签分发,`latest` 保持不变。服务端与数据库必须使用匹配的版本。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
当前环境的接入设置分别控制行为事件、实验曝光和 Feature 求值记录。新环境默认只开启实验曝光,已有环境保持三类全部开启。`flush()` 的 `skipped` 表示配置明确关闭的采集;SDK 将配置缓存 30 秒,数据库对每批再次检查。运行中的实验/Bandit 所需采集不能关闭。开关不删除历史,也不影响业务计费用量。
|
|
8
|
+
|
|
9
|
+
Indiana 的 JavaScript/TypeScript SDK,包含浏览器、Node.js、屏幕渲染与可选 AI 用量集成。0.x 服务只接受当前协议;旧 0.x 请求和固定为 0.2 的无版本头请求会在业务执行前被拒绝。
|
|
8
10
|
|
|
9
11
|
```sh
|
|
10
|
-
npm install @tinkerlandai/indiana-sdk@0.
|
|
12
|
+
npm install @tinkerlandai/indiana-sdk@0.4.0
|
|
11
13
|
```
|
|
12
14
|
|
|
13
15
|
## 版本兼容与支持
|
|
@@ -16,7 +18,7 @@ npm install @tinkerlandai/indiana-sdk@0.3.1
|
|
|
16
18
|
|
|
17
19
|
0.3.0 发送协议及 SDK 版本请求头,并校验成功响应的协议声明。历史 0.2.0 不发送这些请求头;服务端将无版本头的请求固定识别为 0.2,不自动跟随新协议。源码更新不会修改已有 npm 包,也不会自动部署服务端。
|
|
18
20
|
|
|
19
|
-
## 一个 npm
|
|
21
|
+
## 一个 npm 包,七个入口
|
|
20
22
|
|
|
21
23
|
| 导入入口 | 用途 |
|
|
22
24
|
| ---------------------------------------- | ----------------------------------------------------------- |
|
|
@@ -26,6 +28,7 @@ npm install @tinkerlandai/indiana-sdk@0.3.1
|
|
|
26
28
|
| `@tinkerlandai/indiana-sdk/openrouter` | 可选 OpenRouter 用量集成,需要安装对应 peer dependency |
|
|
27
29
|
| `@tinkerlandai/indiana-sdk/native-shell` | 原生 WebView 的静态 Funnel shell 资源;不代表商店购买验收 |
|
|
28
30
|
| `@tinkerlandai/indiana-sdk/page` | 匿名商户页面的网址实验;使用公开的 App environment ID |
|
|
31
|
+
| `@tinkerlandai/indiana-sdk/visual` | 匿名商户页面的视觉实验及曝光采集;使用公开的环境 ID |
|
|
29
32
|
|
|
30
33
|
JavaScript 与 TypeScript 共用本包,声明文件随包提供。内部 `@indiana/contracts` 在构建时内联,接入方无需安装私有包。Swift 和 Kotlin 使用各自的包管理生态,不在本次 npm 发布范围内。
|
|
31
34
|
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -44,3 +44,31 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
44
44
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
45
45
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
46
46
|
THE SOFTWARE.
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# dom-mutator 0.7.0
|
|
50
|
+
|
|
51
|
+
GrowthBook declarative DOM mutations use the original `dom-mutator` package.
|
|
52
|
+
Source: https://github.com/growthbook/dom-mutator
|
|
53
|
+
|
|
54
|
+
MIT License
|
|
55
|
+
|
|
56
|
+
Copyright (c) 2021 Jeremy Dorn
|
|
57
|
+
|
|
58
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
59
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
60
|
+
in the Software without restriction, including without limitation the rights
|
|
61
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
62
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
63
|
+
furnished to do so, subject to the following conditions:
|
|
64
|
+
|
|
65
|
+
The above copyright notice and this permission notice shall be included in all
|
|
66
|
+
copies or substantial portions of the Software.
|
|
67
|
+
|
|
68
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
69
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
70
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
71
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
72
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
73
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
74
|
+
SOFTWARE.
|
|
@@ -197,6 +197,11 @@ declare const apiOperations: {
|
|
|
197
197
|
name: z.ZodOptional<z.ZodString>;
|
|
198
198
|
phase: z.ZodOptional<z.ZodString>;
|
|
199
199
|
}, z.core.$strict>>;
|
|
200
|
+
analyticsConfig: z.ZodObject<{
|
|
201
|
+
eventsEnabled: z.ZodBoolean;
|
|
202
|
+
experimentViewsEnabled: z.ZodBoolean;
|
|
203
|
+
featureUsageEnabled: z.ZodBoolean;
|
|
204
|
+
}, z.core.$strict>;
|
|
200
205
|
remoteFeatures: z.ZodArray<z.ZodString>;
|
|
201
206
|
}, z.core.$strict>;
|
|
202
207
|
}, z.core.$strict>;
|
|
@@ -282,6 +287,12 @@ declare const apiOperations: {
|
|
|
282
287
|
inserted: z.ZodNumber;
|
|
283
288
|
duplicates: z.ZodNumber;
|
|
284
289
|
rejected: z.ZodNumber;
|
|
290
|
+
skipped: z.ZodNumber;
|
|
291
|
+
analyticsConfig: z.ZodObject<{
|
|
292
|
+
eventsEnabled: z.ZodBoolean;
|
|
293
|
+
experimentViewsEnabled: z.ZodBoolean;
|
|
294
|
+
featureUsageEnabled: z.ZodBoolean;
|
|
295
|
+
}, z.core.$strict>;
|
|
285
296
|
}, z.core.$strict>;
|
|
286
297
|
};
|
|
287
298
|
readonly readBalanceSource: {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{c as U,d as L,g as A}from"./chunk-TZ6REIUE.js";function T(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 V(){try{let e=sessionStorage.getItem("indiana_sid");return e||(e=crypto.randomUUID(),sessionStorage.setItem("indiana_sid",e)),e}catch{return}}function $(e){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 v=new Set,x;function D(e){if(v.add(e),!x){let t=history.pushState,i=history.replaceState,r=()=>{for(let s of v)s()},o=function(...s){t.apply(this,s),r()},c=function(...s){i.apply(this,s),r()};history.pushState=o,history.replaceState=c,addEventListener("popstate",r),addEventListener("hashchange",r),x=()=>{history.pushState===o&&(history.pushState=t),history.replaceState===c&&(history.replaceState=i),removeEventListener("popstate",r),removeEventListener("hashchange",r)}}return()=>{v.delete(e),v.size||(x?.(),x=void 0)}}var C="__indiana_visual_editor",d;function M(e,t){if(d&&d.origin===e&&d.environmentId===t&&d.expiresAt>Date.now())return d;try{let i=new URL(location.href).searchParams.get(C);if(!i||i.length>2048)return null;let r=JSON.parse(i);return r.origin!==e||r.environmentId!==t||!/^[a-f0-9-]{36}$/i.test(r.nonce)||r.expiresAt<=Date.now()||r.expiresAt>Date.now()+900*1e3?null:(d=r,r)}catch{return null}}function O(e,t){return!!M(e,t)}function Q(){let e=new URL(location.href);e.searchParams.delete(C),history.replaceState(history.state,"",e.href)}/*!
|
|
2
|
+
Portions ported from GrowthBook sdk-js @ ed29827 (GrowthBook.ts auto experiments, util.ts mergeQueryStrings,
|
|
3
|
+
plugins/auto-attributes.ts). Copyright (c) GrowthBook, Inc. MIT License.
|
|
4
|
+
*/function z(e,t){let i,r;try{i=new URL(e),r=new URL(t)}catch{return t}return i.searchParams.forEach((o,c)=>{r.searchParams.has(c)||r.searchParams.set(c,o)}),r.toString()}function W(e,t){let i=navigator.userAgent,r=new URLSearchParams(t.search),o={};for(let c of["source","medium","campaign","term","content"]){let s=r.get(`utm_${c}`);s!==null&&(o[`utm${c[0].toUpperCase()}${c.slice(1)}`]=s)}return{id:e,deviceId:e,url:t.href,path:t.pathname,host:t.host,query:t.search,pageTitle:typeof document>"u"?"":document.title,browser:/Edg/.test(i)?"edge":/Chrome/.test(i)?"chrome":/Firefox/.test(i)?"firefox":/Safari/.test(i)?"safari":"unknown",deviceType:/Mobi/.test(i)?"mobile":"desktop",...o}}function F(e){let t=e;if(!(!!t&&typeof t=="object"&&typeof t.environmentId=="string"&&typeof t.trackExposures=="boolean"&&/^[a-f0-9]{64}$/.test(t.generation??"")&&Array.isArray(t.experiments)&&t.experiments.length<=100&&t.experiments.every(r=>!!r&&!["namespace","status","url","groups"].some(o=>Object.hasOwn(r,o))&&(r.hashVersion===void 0||r.hashVersion===2)&&typeof r.key=="string"&&Array.isArray(r.variations)&&r.variations.length>=2&&r.variations.every(o=>!!o&&typeof o.urlRedirect=="string")&&(r.urlPatterns===void 0||Array.isArray(r.urlPatterns)))&&!!t.savedGroups&&typeof t.savedGroups=="object"&&!Array.isArray(t.savedGroups)))throw new Error("Invalid page experiment payload");return t}function ee(e){let t=$(e.baseUrl);if(!/^[0-9a-f-]{36}$/i.test(e.environmentId))throw new Error("environmentId must be the App environment ID");let i=e.fetch??globalThis.fetch.bind(globalThis),r=`${t}/api/v1/page-experiments/${e.environmentId}`,o=T(e.deviceIdCookie??"indiana_did"),c=V(),s=null,R={...e.attributes??{}},m="",E=!1,I=new Map,P=[],g;function _(n){return n.length?i(`${r}/events`,{method:"POST",body:JSON.stringify({events:n}),headers:{"Content-Type":"text/plain"},keepalive:!0,credentials:"omit"}).then(()=>{}).catch(a=>e.log?.("Exposure not sent",{error:a})):Promise.resolve()}function f(){return clearTimeout(g),g=void 0,_(P.splice(0,20))}let l={trackedExperiments:new Set,log:e.log,onExperimentViewed:(n,a)=>{e.trackExposures===!1||s?.trackExposures===!1||(P.push({eventUuid:crypto.randomUUID(),timestamp:new Date().toISOString(),deviceId:o,...c?{sessionId:c}:{},url:location.href,pageTitle:document.title.slice(0,512),experimentKey:n.key,variationKey:a.key}),g||(g=setTimeout(()=>{f()},1e3)))}},N=()=>{l.url=location.href,l.attributes={...W(o,location),...R}};function G(n){if(!e.disableCrossOriginUrlRedirects)return!1;try{let a=new URL(location.href);return n.variations.some(u=>{if(!u.urlRedirect)return!1;let y=new URL(u.urlRedirect);return y.protocol!==a.protocol||y.host!==a.host})}catch{return!0}}function J(n,a){m=n;let u=e.navigate??(p=>location.replace(p)),y=e.navigateDelay??(e.navigate?0:100),q=e.maxNavigateDelay??1e3;Promise.all([Promise.race([a,new Promise(p=>setTimeout(p,q))]),new Promise(p=>setTimeout(p,y))]).then(()=>{E||u(n)})}function h(){if(!(!s||E||O(t,e.environmentId))){N();for(let n of s.experiments){if(G(n)){e.log?.("Auto experiment blocked",{id:n.key});continue}let a;try{a=A(n,l)}catch(u){e.log?.("Skipping page experiment",{id:n.key,error:String(u)});continue}if(I.set(n.key,a),!!a.inExperiment){if(a.value.urlRedirect){let u=n.persistQueryString?z(location.href,a.value.urlRedirect):a.value.urlRedirect;U(u,n.urlPatterns??[])?e.log?.("Skipping redirect because original URL matches redirect URL",{id:n.key}):u!==m&&J(u,f())}break}}}}let w="",H=()=>{location.href!==w&&(w=location.href,m="",h())},b;function j(){b??=D(H),addEventListener("pagehide",S)}let S=()=>{f()};async function k(){let n=await i(r,{cache:"no-cache",credentials:"omit"});if(!n.ok)throw new Error(`Page experiments unavailable (${n.status})`);let a=F(await n.json());if(a.environmentId.toLowerCase()!==e.environmentId.toLowerCase())throw new Error("Page experiment payload scope changed");s?.trackExposures===!1&&a.trackExposures&&l.trackedExperiments?.clear(),s=a,l.savedGroups=L(a.savedGroups)}return{async start(){await k(),j(),w=location.href,h()},async refresh(){await k(),m="",h()},setAttributes(n){R={...n},h()},getResults(){return new Map(I)},get generation(){return s?.generation??null},destroy(){E=!0,b?.(),removeEventListener("pagehide",S),f()}}}export{T as a,V as b,$ as c,D as d,M as e,Q as f,z as g,W as h,F as i,ee as j};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Y as S,_b as C,gc as k,jc as L,mc as T,nc as v,oc as j,rc as R,yi as V}from"./chunk-PVJKOUNE.js";var U={name:"@tinkerlandai/indiana-sdk",version:"0.4.0",description:"Framework-independent Indiana SDK for customer identity, entitlements, credits, offers and growth surfaces.",license:"UNLICENSED",repository:{type:"git",url:"git+https://github.com/tinkerlandai/Indiana.git",directory:"packages/sdk"},engines:{node:">=22"},publishConfig:{access:"public",tag:"beta"},type:"module",sideEffects:!1,files:["dist","README.md","README.zh-CN.md","CHANGELOG.md","THIRD_PARTY_NOTICES.md"],exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./popup":{types:"./dist/popup.d.ts",import:"./dist/popup.js"},"./server":{types:"./dist/server.d.ts",import:"./dist/server.js"},"./openrouter":{types:"./dist/openrouter.d.ts",import:"./dist/openrouter.js"},"./native-shell":{types:"./dist/native-shell.d.ts",import:"./dist/native-shell.js"},"./page":{types:"./dist/page.d.ts",import:"./dist/page.js"},"./visual":{types:"./dist/visual.d.ts",import:"./dist/visual.js"}},scripts:{build:"tsup",prepack:"pnpm run build",typecheck:"tsc --noEmit"},dependencies:{"@ai-sdk/provider":"4.0.26","@types/json-schema":"7.0.15","css-tree":"^3.2.1","dom-mutator":"0.7.0",dompurify:"^3.4.15",zod:"4.6.5"},devDependencies:{"@indiana/contracts":"workspace:*","@openrouter/sdk":"^1.4.25","@types/css-tree":"^3.2.0",ai:"7.0.136",tsup:"^8.5.1",typescript:"^5.9.3"},peerDependencies:{"@openrouter/sdk":"^1.4.25"},peerDependenciesMeta:{"@openrouter/sdk":{optional:!0}}};var e=class extends Error{constructor(h,d,n,N,i){super(d);this.code=h;this.status=n;this.requestId=N;this.name="IndianaError",this.reason=i?.reason;let c=T(h,n??0,{...i,retryAfter:i?.retryAfterSeconds===void 0?void 0:String(i.retryAfterSeconds)});this.retryable=c.retryable,this.recovery=c.recovery,this.retryAfterSeconds=c.retryAfterSeconds}code;status;requestId;retryable;recovery;retryAfterSeconds;reason},$=Symbol("IndianaNoContent");function J(l,A){let h=l.webView??"hosted";if(!["hosted","embedded"].includes(h))throw new e("INVALID_REQUEST","Invalid Web View mode");let d=l.scope?S.parse(l.scope):void 0,n=new URL(l.baseUrl);if(n.username||n.password||n.search||n.hash)throw new e("INVALID_URL","baseUrl must not contain credentials, query, or fragment");if(n.protocol!=="https:"&&!(n.protocol==="http:"&&["localhost","127.0.0.1","[::1]"].includes(n.hostname)))throw new e("INVALID_URL","Use HTTPS, or HTTP on localhost during development");let N=l.fetch??globalThis.fetch.bind(globalThis),i=l.timeoutMs??1e4;if(!Number.isFinite(i)||i<=0||i>12e4)throw new e("INVALID_TIMEOUT","timeoutMs must be between 1 and 120000");let c=null,b,u=0,p=null,f=new Set;function D(){u+=1,c=null,p=null;for(let s of f)s.abort();f.clear()}async function M(s,q={},O="POST",H={}){if(!c)throw new e("NOT_IDENTIFIED","Call identify with a server-issued customer token first");let g=u,o=new AbortController;f.add(o);let y=()=>g!==u?new e("IDENTITY_CHANGED","Customer identity changed while the request was in flight"):new e("TIMEOUT","Indiana request timed out"),I,x=new Promise((r,a)=>{I=()=>a(y()),o.signal.addEventListener("abort",I,{once:!0})}),K=setTimeout(()=>o.abort(),i),G=async()=>{let r=await N(`${n.href.replace(/\/$/,"")}/api/v1/${s}`,{method:O,headers:{"Content-Type":"application/json",Authorization:`Bearer ${c}`,[v]:R.current,[j]:U.version,...d?{"X-Indiana-Project":d.projectId,"X-Indiana-Environment":d.environment}:{}},body:O==="POST"?JSON.stringify(q):void 0,signal:o.signal,credentials:"omit",cache:"no-store",redirect:"error",...H.keepalive?{keepalive:!0}:{}});if(o.signal.aborted)throw y();let a;try{a=r.status===204?$:await r.json()}catch{throw o.signal.aborted?y():new e(r.ok?"INVALID_RESPONSE":"HTTP_ERROR","The gateway returned an unreadable response",r.status,r.headers.get("X-Request-Id")??void 0)}if(o.signal.aborted)throw y();if(g!==u)throw new e("IDENTITY_CHANGED","Customer identity changed while the request was in flight");if(!r.ok){let t=L.safeParse(a),m=t.success&&(!C.safeParse(t.data.error.code).success||k(t.data.error.code,r.status)),_=m?t.data.error.code:"HTTP_ERROR",P=T(_,r.status,{retryAfter:r.headers.get("Retry-After"),recovery:m?t.data.error.recovery:void 0,reason:m?t.data.error.reason:void 0});throw new e(_,m?t.data.error.message:"Indiana request failed",r.status,r.headers.get("X-Request-Id")??(t.success?t.data.requestId:void 0),{...P,...t.success&&t.data.error.retryable===!1?{retryable:!1}:{},...P.retryAfterSeconds===void 0&&t.success&&t.data.error.retryAfterSeconds!==void 0?{retryAfterSeconds:t.data.error.retryAfterSeconds}:{}})}if(r.headers.get(v)!==R.current)throw new e("PROTOCOL_MISMATCH","Response protocol does not match this SDK");if(d&&a&&typeof a=="object"&&"scope"in a){let t=S.safeParse(a.scope);if(!t.success||t.data.projectId!==d.projectId||t.data.environment!==d.environment)throw new e("SCOPE_MISMATCH","Response scope does not match this SDK instance")}let E=r.headers.get("X-Indiana-Web-View");if(E){if(!/^\/web-view\/renderer\/[a-f0-9]{64}$/.test(E))throw new e("INVALID_RESPONSE","Invalid Web View renderer metadata");b=E}let w=r.headers.get("X-Indiana-Telemetry-Subject");if(w){if(!/^[a-f0-9]{64}$/.test(w))throw new e("INVALID_RESPONSE","Invalid telemetry identity");p!==w&&(p=w,A?.(p))}return a};try{return await Promise.race([G(),x])}catch(r){throw g!==u?new e("IDENTITY_CHANGED","Customer identity changed while the request was in flight"):r instanceof e?r:new e(o.signal.aborted?"TIMEOUT":"NETWORK_ERROR",o.signal.aborted?"Indiana request timed out":"Unable to read the Indiana response")}finally{clearTimeout(K),o.signal.removeEventListener("abort",I),f.delete(o)}}return{subjectKey:()=>p,screenUrl(s){if(!V.safeParse(s).success)throw new e("INVALID_RESPONSE","Invalid published screen render address");return new URL(s,n).href},webViewUrl(){if(h!=="embedded"){if(!b)throw new e("INVALID_RESPONSE","The gateway did not provide a hosted Web View renderer");return new URL(b,n).href}},identify(s){if(!s.trim()||/\s/.test(s)||s.length>4096)throw new e("INVALID_TOKEN","A nonempty server-issued token is required");D(),c=s},reset:D,request:M}}export{e as a,J as b};
|