@aippy/runtime 0.4.2-dev.2 → 0.4.2-dev.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +15 -3
  2. package/dist/ai/errors.d.ts +1 -1
  3. package/dist/ai/index.d.ts +0 -1
  4. package/dist/ai/index.js +18 -21
  5. package/dist/bridge-D_-7nPNC.js +311 -0
  6. package/dist/container-message-DmIChz4h.js +56 -0
  7. package/dist/core/env.d.ts +2 -0
  8. package/dist/core/index.js +2 -2
  9. package/dist/core/parent-message.d.ts +5 -0
  10. package/dist/core/wallet-recharge.d.ts +16 -0
  11. package/dist/helper-BWszI06u.js +346 -0
  12. package/dist/{hooks-D5lkty5r.js → hooks-Ct9qEjM6.js} +1 -1
  13. package/dist/index/index.js +43 -42
  14. package/dist/index.d.ts +1 -0
  15. package/dist/ministore/app-authorization.d.ts +9 -0
  16. package/dist/ministore/authorization.d.ts +6 -0
  17. package/dist/ministore/consume.d.ts +3 -0
  18. package/dist/ministore/errors.d.ts +18 -0
  19. package/dist/ministore/index.d.ts +19 -0
  20. package/dist/ministore/index.js +915 -0
  21. package/dist/ministore/order.d.ts +1 -0
  22. package/dist/ministore/purchase.d.ts +5 -0
  23. package/dist/ministore/queries.d.ts +13 -0
  24. package/dist/ministore/recharge.d.ts +12 -0
  25. package/dist/ministore/transport.d.ts +14 -0
  26. package/dist/ministore/types.d.ts +166 -0
  27. package/dist/ministore/update-item.d.ts +3 -0
  28. package/dist/ministore/validation.d.ts +19 -0
  29. package/dist/ministore.d.ts +2 -0
  30. package/dist/user/bridge.d.ts +3 -8
  31. package/dist/user/config.d.ts +2 -0
  32. package/dist/user/index.js +2 -2
  33. package/dist/wallet-recharge-BqOljLWn.js +140 -0
  34. package/package.json +5 -1
  35. package/dist/ai/credits.d.ts +0 -12
  36. package/dist/bridge-CtB9L5kL.js +0 -259
  37. package/dist/container-message-ChLaG4Ke.js +0 -56
  38. package/dist/helper-CCuf-R6I.js +0 -405
package/README.md CHANGED
@@ -127,9 +127,20 @@ const image = await generateImage({
127
127
  console.log(image.image?.base64);
128
128
  ```
129
129
 
130
- The AI module adds `getCredits` and `deductCredits` in the unreleased source; published `@aippy/runtime@0.4.1` does not include them. Use them only after installing a published release containing both exports (`>= 0.4.2`), and verify the installed module declarations before importing.
131
-
132
- The server checks the balance atomically and prevents duplicate charges for the same event and amount; changed charge details return HTTP 409. Insufficient balance uses the existing runtime error, the host `container.message` notification, and a native `wallet.showRecharge` command on the shared iOS/Android `aippyListener`. Call credits functions from UI handlers with error handling. Use explicit deductions for custom actions; model generation already charges credits. See the [AI module](./src/ai/README.md) and `aippy-ai-sdk` skill for usage.
130
+ ### Ministore (Internal Test Only)
131
+
132
+ `@aippy/runtime/ministore` provides project entitlement catalogs, holdings,
133
+ mall GEM balance, authorization queries, explicit settlement and records.
134
+ The SDK and its Skill are not available to external creators and are not
135
+ advertised in system prompts. An installed export does not authorize public use.
136
+ App or approved website-parent confirmation uses the specified wallet.authorize
137
+ contract and stays separate from settlement. The synchronous support check is
138
+ native-only; parent confirmation needs a matching deployed website handler.
139
+ Non-native recharge hints do not wait for funds or resume settlement.
140
+ Real host support and service acceptance remain pending; no
141
+ package publication or external enablement is performed by this work.
142
+ See the [ministore module](./src/ministore/README.md) for the verified HTTP
143
+ contract, internal-consumer requirements and recovery rules.
133
144
 
134
145
  ## Packages
135
146
 
@@ -138,6 +149,7 @@ The server checks the balance atomically and prevents duplicate charges for the
138
149
  - `@aippy/runtime/utils` - Platform detection, performance monitoring, PWA utilities
139
150
  - `@aippy/runtime/audio` - iOS-compatible Web Audio API wrapper
140
151
  - `@aippy/runtime/ai` - AI SDK adapter wrapping `ai` package, routes through backend proxy
152
+ - `@aippy/runtime/ministore` - Project entitlements, GEM wallet and authorization (internal test only; App integration pending)
141
153
 
142
154
  ## Publishing
143
155
 
@@ -2,7 +2,7 @@ import { AISDKError } from 'ai';
2
2
  /**
3
3
  * Normalizes a backend error response into an AISDKError.
4
4
  * Extracts and sends appMessage to container if present in the error response.
5
- * Insufficient credits also asks the native host to open the recharge sheet.
5
+ * Insufficient quota also asks the native host to open the recharge sheet.
6
6
  * Uses [Aippy Runtime] prefix - these errors are NOT reported to LLM.
7
7
  */
8
8
  export declare function normalizeError(response: Response, body?: unknown): AISDKError;
@@ -41,6 +41,5 @@ export type { AippyOpenAIConfig } from './openai';
41
41
  export { aippyChatConfig, type AippyUseChatOptions, type AippyUIConfig, type AippyChatConfig, UI_CHAT_ENDPOINT, } from './ui';
42
42
  export { DEFAULT_BASE_URL, DEFAULT_UI_BASE_URL, DEFAULT_CHAT_MODEL, DEFAULT_CHAT_SYSTEM, resolveOpenAIConfig, resolveUIConfig, } from './shared';
43
43
  export { normalizeError } from './errors';
44
- export { getCredits, deductCredits, type CreditsRequestOptions, type DeductCreditsOptions, } from './credits';
45
44
  export { generateCharacter3D, generateMotion, type GenerateCharacter3DInput, type GenerateMotionInput, type ViggleAsset, } from './viggle/generate';
46
45
  export { type AIConfig, type AIConfigValue, type AIConfigItem, type NumberAIConfigItem, type BooleanAIConfigItem, type TextAIConfigItem, type EnumAIConfigItem, type AIConfigError, type AIConfigValues, validateAIConfig, parseAIConfig, loadAIConfig, getAIConfigValue, sendAIConfigToContainer, createAIConfig, } from './config';
package/dist/ai/index.js CHANGED
@@ -1,25 +1,22 @@
1
- import { D as r, d as i, e as n, c as A, U as C, a as t, b as g, m as I, h as f, i as _, j as p, k as E, g as T, l as U, n as d, p as D, r as l, f as L, s as m, v } from "../helper-CCuf-R6I.js";
2
- import "react";
3
- import "../bridge-CtB9L5kL.js";
1
+ import { D as o, d as r, e as i, c as n, U as A, a as C, b as g, j as I, g as f, h as t, i as _, l as E, n as T, p as U, r as p, f as D, s as l, v as L } from "../helper-BWszI06u.js";
2
+ import "../bridge-D_-7nPNC.js";
4
3
  export {
5
- r as DEFAULT_BASE_URL,
6
- i as DEFAULT_CHAT_MODEL,
7
- n as DEFAULT_CHAT_SYSTEM,
8
- A as DEFAULT_UI_BASE_URL,
9
- C as UI_CHAT_ENDPOINT,
10
- t as aippyAIProvider,
4
+ o as DEFAULT_BASE_URL,
5
+ r as DEFAULT_CHAT_MODEL,
6
+ i as DEFAULT_CHAT_SYSTEM,
7
+ n as DEFAULT_UI_BASE_URL,
8
+ A as UI_CHAT_ENDPOINT,
9
+ C as aippyAIProvider,
11
10
  g as aippyChatConfig,
12
11
  I as createAIConfig,
13
- f as deductCredits,
14
- _ as generateCharacter3D,
15
- p as generateMotion,
16
- E as getAIConfigValue,
17
- T as getCredits,
18
- U as loadAIConfig,
19
- d as normalizeError,
20
- D as parseAIConfig,
21
- l as resolveOpenAIConfig,
22
- L as resolveUIConfig,
23
- m as sendAIConfigToContainer,
24
- v as validateAIConfig
12
+ f as generateCharacter3D,
13
+ t as generateMotion,
14
+ _ as getAIConfigValue,
15
+ E as loadAIConfig,
16
+ T as normalizeError,
17
+ U as parseAIConfig,
18
+ p as resolveOpenAIConfig,
19
+ D as resolveUIConfig,
20
+ l as sendAIConfigToContainer,
21
+ L as validateAIConfig
25
22
  };
@@ -0,0 +1,311 @@
1
+ import { a as v } from "./runtime-CmoG3v2m.js";
2
+ import { r as b, s as q, i as w } from "./app-version-checker-Bz7FrEZz.js";
3
+ import { c as A, a as _ } from "./errors-B3bDbQbD.js";
4
+ const F = ".aippynow.com", k = "https://api.aippy.dev", S = "https://api.aippy.ai";
5
+ function ee(e) {
6
+ return e === k || e === S;
7
+ }
8
+ let p;
9
+ function j() {
10
+ if (p) return p;
11
+ let e = S;
12
+ if (typeof window < "u" && window.location) {
13
+ const n = window.location.hostname;
14
+ (n.endsWith(F) || n === "localhost" || n === "127.0.0.1") && (e = k);
15
+ }
16
+ return p = e, e;
17
+ }
18
+ function ne() {
19
+ p = void 0;
20
+ }
21
+ function I() {
22
+ if (typeof window > "u" || !window.parent || window.parent === window)
23
+ return;
24
+ const e = window.location?.ancestorOrigins?.[0] || (typeof document < "u" ? document.referrer : "");
25
+ if (e)
26
+ try {
27
+ const { origin: n, protocol: t } = new URL(e);
28
+ return t === "https:" || t === "http:" ? n : void 0;
29
+ } catch {
30
+ return;
31
+ }
32
+ }
33
+ function P(e) {
34
+ return !!e.data && typeof e.data == "object" && !Array.isArray(e.data);
35
+ }
36
+ function U(e, n = I()) {
37
+ return typeof window < "u" && !!n && e.source === window.parent && e.origin === n && P(e);
38
+ }
39
+ function N(e) {
40
+ if (typeof window > "u" || !P(e)) return !1;
41
+ const n = window.location?.origin;
42
+ return U(e) || !!n && n !== "null" && e.source === window && e.origin === n;
43
+ }
44
+ const m = {
45
+ apiBaseUrl: `${j()}/api`,
46
+ authToken: "",
47
+ currentUserId: null
48
+ };
49
+ function H(e) {
50
+ Object.assign(m, e);
51
+ }
52
+ function J(e) {
53
+ m.authToken = e;
54
+ }
55
+ function V(e) {
56
+ m.currentUserId = e;
57
+ }
58
+ function te() {
59
+ return m.currentUserId;
60
+ }
61
+ const O = 3e3, L = 50, f = 500, c = { uid: "", token: "" };
62
+ let l = null, h = !1, a = null, u = null;
63
+ function d(e) {
64
+ return !!e && typeof e == "object" && !Array.isArray(e);
65
+ }
66
+ function D(e) {
67
+ return typeof e == "string" && e !== "" ? e : typeof e == "number" && Number.isSafeInteger(e) && e > 0 ? String(e) : null;
68
+ }
69
+ function E(e) {
70
+ if (!d(e)) return null;
71
+ let n = e;
72
+ d(n.credentials) && (n = n.credentials), d(n.user) && n.token && (n = {
73
+ uid: n.user.uid || n.user.userId || n.user.id,
74
+ token: n.token,
75
+ apiBaseUrl: n.apiBaseUrl
76
+ });
77
+ const t = D(n.uid || n.userId || n.id), i = n.token || n.authToken;
78
+ if (!t || typeof i != "string" || i === "") return null;
79
+ const r = typeof n.apiBaseUrl == "string" ? n.apiBaseUrl : void 0, s = { uid: t, token: i, apiBaseUrl: r };
80
+ return V(t), J(i), r && H({ apiBaseUrl: r }), s;
81
+ }
82
+ function T(e) {
83
+ if (!d(e)) return null;
84
+ let n = e;
85
+ d(n.userInfo) && (n = n.userInfo), d(n.user) && (n = n.user);
86
+ const t = D(n.uid || n.userId || n.id);
87
+ if (!t) return null;
88
+ const i = { ...n, uid: t };
89
+ return l = i, h = !0, i;
90
+ }
91
+ function x(e = f) {
92
+ return a ? new Promise((n) => {
93
+ const t = a.resolve;
94
+ a.resolve = (i) => {
95
+ t(i), n(i);
96
+ };
97
+ }) : new Promise((n) => {
98
+ let t, i;
99
+ const r = {
100
+ resolve: (s) => {
101
+ clearTimeout(t), i?.cancel(), a === r && (a = null), n(s);
102
+ }
103
+ };
104
+ a = r, (async () => {
105
+ let s = window.webkit?.messageHandlers?.aippyListener;
106
+ if (s || (s = await M(1500)), a === r) {
107
+ if (!s) {
108
+ r.resolve(c);
109
+ return;
110
+ }
111
+ t = setTimeout(() => r.resolve(c), e), i = v.receiveChannel.once(
112
+ "user.credentials",
113
+ (o) => {
114
+ r.resolve(E(o) || c);
115
+ }
116
+ );
117
+ try {
118
+ s.postMessage({
119
+ command: "user.getCredentials",
120
+ parameters: JSON.stringify({
121
+ timestamp: Date.now(),
122
+ endpoint: "user.credentials"
123
+ })
124
+ });
125
+ } catch {
126
+ r.resolve(c);
127
+ }
128
+ }
129
+ })();
130
+ });
131
+ }
132
+ function z(e = f) {
133
+ return new Promise((n) => {
134
+ const t = I();
135
+ if (!w() || !t) {
136
+ n(c);
137
+ return;
138
+ }
139
+ const i = setTimeout(() => {
140
+ window.removeEventListener("message", r), n(c);
141
+ }, e), r = (s) => {
142
+ if (!U(s, t) || s.data.type !== "user-credentials-response")
143
+ return;
144
+ const o = E(s.data);
145
+ o && (clearTimeout(i), window.removeEventListener("message", r), n(o));
146
+ };
147
+ window.addEventListener("message", r);
148
+ try {
149
+ window.parent.postMessage(
150
+ { type: "user-credentials-request", timestamp: Date.now() },
151
+ t
152
+ );
153
+ } catch {
154
+ clearTimeout(i), window.removeEventListener("message", r), n(c);
155
+ }
156
+ });
157
+ }
158
+ const G = () => /Aippy\/[\d.]+\/\d+\/Android/i.test(navigator.userAgent);
159
+ async function M(e = 1500) {
160
+ if (!G())
161
+ return window.webkit?.messageHandlers?.aippyListener || null;
162
+ const n = Date.now();
163
+ for (; Date.now() - n < e; ) {
164
+ const t = window.webkit?.messageHandlers?.aippyListener;
165
+ if (t) return t;
166
+ await new Promise((i) => setTimeout(i, 50));
167
+ }
168
+ return null;
169
+ }
170
+ function W(e = !1, n = f) {
171
+ return h && l && !e ? Promise.resolve(l) : u ? new Promise((t) => {
172
+ const i = u.resolve;
173
+ u.resolve = (r) => {
174
+ i(r), t(r);
175
+ };
176
+ }) : new Promise((t) => {
177
+ let i, r;
178
+ const s = {
179
+ resolve: (o) => {
180
+ clearTimeout(i), r?.cancel(), u === s && (u = null), t(o);
181
+ }
182
+ };
183
+ u = s, (async () => {
184
+ let o = window.webkit?.messageHandlers?.aippyListener;
185
+ if (o || (o = await M(1500)), u === s) {
186
+ if (!o) {
187
+ s.resolve(null);
188
+ return;
189
+ }
190
+ i = setTimeout(() => s.resolve(null), n), r = v.receiveChannel.once("user.info", (B) => {
191
+ s.resolve(T(B));
192
+ });
193
+ try {
194
+ o.postMessage({
195
+ command: "user.getUserInfo",
196
+ parameters: JSON.stringify({
197
+ timestamp: Date.now(),
198
+ endpoint: "user.info"
199
+ })
200
+ });
201
+ } catch {
202
+ s.resolve(null);
203
+ }
204
+ }
205
+ })();
206
+ });
207
+ }
208
+ function C(e = f) {
209
+ return new Promise((n) => {
210
+ const t = I();
211
+ if (!w() || !t) {
212
+ n(null);
213
+ return;
214
+ }
215
+ const i = setTimeout(() => {
216
+ window.removeEventListener("message", r), n(null);
217
+ }, e), r = (s) => {
218
+ if (!U(s, t) || s.data.type !== "user-info-response")
219
+ return;
220
+ const o = T(s.data);
221
+ o && (clearTimeout(i), window.removeEventListener("message", r), n(o));
222
+ };
223
+ window.addEventListener("message", r);
224
+ try {
225
+ window.parent.postMessage(
226
+ { type: "user-info-request", timestamp: Date.now() },
227
+ t
228
+ );
229
+ } catch {
230
+ clearTimeout(i), window.removeEventListener("message", r), n(null);
231
+ }
232
+ });
233
+ }
234
+ async function R() {
235
+ const { envCheck: e } = b("userCredentials");
236
+ switch (e.type) {
237
+ case "new_app": {
238
+ const n = await x(O);
239
+ if (!n?.token)
240
+ throw A(
241
+ "Token unavailable in app",
242
+ _.PERMISSION_DENIED
243
+ );
244
+ return n.token;
245
+ }
246
+ case "iframe": {
247
+ const n = await z(L);
248
+ if (n?.token) return n.token;
249
+ throw q(
250
+ "Sign in to continue.Open this project in the app.",
251
+ "signin"
252
+ ), A(
253
+ "Token unavailable: User needs to login",
254
+ _.PERMISSION_DENIED
255
+ );
256
+ }
257
+ default:
258
+ return "";
259
+ }
260
+ }
261
+ async function X(e = !1) {
262
+ if (h && l && !e)
263
+ return l;
264
+ const { envCheck: n } = b("userInfo");
265
+ switch (n.type) {
266
+ case "new_app":
267
+ return await W(e, O);
268
+ case "iframe":
269
+ return await C(L);
270
+ default:
271
+ return l;
272
+ }
273
+ }
274
+ async function Y(e = f) {
275
+ return w() ? await C(e) : null;
276
+ }
277
+ function g(e) {
278
+ const n = E(e);
279
+ n && a && (a.resolve(n), a = null);
280
+ }
281
+ function y(e) {
282
+ const n = T(e);
283
+ u && (u.resolve(n), u = null);
284
+ }
285
+ function $() {
286
+ typeof window > "u" || (window.processUserCredentials = g, window.processUserInfo = y, window.addEventListener("message", (e) => {
287
+ N(e) && (e.data.type === "user-credentials" && g(e.data), e.data.type === "user-info" && y(e.data));
288
+ }));
289
+ }
290
+ $();
291
+ R().catch(() => {
292
+ });
293
+ const re = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
294
+ __proto__: null,
295
+ getAuthTokenAsync: R,
296
+ getUserInfoAsync: X,
297
+ getUserInfoFromParent: Y,
298
+ isInIframe: w,
299
+ processUserCredentials: g,
300
+ processUserInfo: y
301
+ }, Symbol.toStringTag, { value: "Module" }));
302
+ export {
303
+ ne as _,
304
+ I as a,
305
+ ee as b,
306
+ te as c,
307
+ re as d,
308
+ R as g,
309
+ U as i,
310
+ j as r
311
+ };
@@ -0,0 +1,56 @@
1
+ import { g as o, a as i } from "./bridge-D_-7nPNC.js";
2
+ const r = "0.4.2-dev.4", c = {
3
+ version: r
4
+ }, a = c.version, p = "@aippy/runtime";
5
+ function u() {
6
+ return {
7
+ name: p,
8
+ version: a,
9
+ buildTime: (/* @__PURE__ */ new Date()).toISOString()
10
+ };
11
+ }
12
+ function g(n) {
13
+ const { token: t, existingHeaders: s } = n, e = new Headers(s);
14
+ return e.set("Aippy-Runtime-Authorization", `Bearer ${t}`), e.set("Aippy-Runtime-SDK-Version", a), typeof navigator < "u" && navigator.userAgent && e.set("Aippy-Runtime-UA", navigator.userAgent), e;
15
+ }
16
+ async function m(n) {
17
+ const t = await o();
18
+ return g({ token: t, existingHeaders: n });
19
+ }
20
+ function y(n) {
21
+ if (!(typeof window > "u"))
22
+ try {
23
+ const t = window.webkit?.messageHandlers?.aippyListener;
24
+ if (t)
25
+ try {
26
+ const e = {
27
+ command: "container.message",
28
+ parameters: n
29
+ };
30
+ t.postMessage(e);
31
+ } catch {
32
+ console.warn("Failed to send container message to the native host");
33
+ }
34
+ const s = i();
35
+ if (s)
36
+ try {
37
+ const e = {
38
+ type: "container.message",
39
+ data: n
40
+ };
41
+ window.parent.postMessage(e, s);
42
+ } catch {
43
+ console.warn("Failed to send container message to the parent host");
44
+ }
45
+ } catch {
46
+ console.warn("Failed to send container message");
47
+ }
48
+ }
49
+ export {
50
+ p as S,
51
+ a as V,
52
+ m as a,
53
+ g as c,
54
+ u as g,
55
+ y as s
56
+ };
@@ -4,6 +4,8 @@
4
4
  * All environment-specific URLs live here — no other file should
5
5
  * hardcode aippy domain strings.
6
6
  */
7
+ /** @internal Runtime credentials may only be sent to these official API origins. */
8
+ export declare function isTrustedApiOrigin(origin: string): boolean;
7
9
  /**
8
10
  * Resolves the API base URL at runtime by inspecting the page hostname.
9
11
  *
@@ -1,7 +1,7 @@
1
1
  import { D as r, g as s, m as o } from "../config-B0A7gHQM.js";
2
- import { _ as t, r as i } from "../bridge-CtB9L5kL.js";
2
+ import { _ as t, r as i } from "../bridge-D_-7nPNC.js";
3
3
  import { A as R, a as E, E as c, b as m, c as A } from "../errors-B3bDbQbD.js";
4
- import { S as f, V as g, c as l, a as y, g as _, s as d } from "../container-message-ChLaG4Ke.js";
4
+ import { S as f, V as g, c as l, a as y, g as _, s as d } from "../container-message-DmIChz4h.js";
5
5
  import { A as D, C as O, R as F, a as I, p as S } from "../runtime-CmoG3v2m.js";
6
6
  export {
7
7
  D as AippyRuntime,
@@ -0,0 +1,5 @@
1
+ /** Browser-observed parent origin; never trust an origin supplied in a message. */
2
+ export declare function getParentOrigin(): string | undefined;
3
+ export declare function isParentMessage(event: MessageEvent, origin?: string | undefined): boolean;
4
+ /** Preserve native self-postMessage callbacks, but reject sibling/foreign frames. */
5
+ export declare function isHostMessage(event: MessageEvent): boolean;
@@ -0,0 +1,16 @@
1
+ /** Shared native recharge sheet tracking. No payment or balance is inferred here. */
2
+ export declare const WALLET_SHOW_RECHARGE = "wallet.showRecharge";
3
+ type Failure = 'unavailable' | 'busy' | 'cancelled' | 'timeout' | 'protocol' | 'bridge';
4
+ export declare class WalletRechargeError extends Error {
5
+ readonly type: Failure;
6
+ constructor(type: Failure, message: string);
7
+ }
8
+ /** AI keeps fire-and-forget behavior, but shares the sheet lifecycle with MiniStore. */
9
+ export declare function showNativeRecharge(): void;
10
+ /**
11
+ * At most one continuation owns a sheet. AI-only sheets may be joined.
12
+ * After timeout/abort, retain a drain-only listener until closed: no requestId
13
+ * exists, so opening another sheet earlier could mistake an old result for it.
14
+ */
15
+ export declare function waitForNativeRecharge(signal?: AbortSignal): Promise<boolean>;
16
+ export {};