@layers/amba-web 4.0.3 → 4.0.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.
- package/dist/index.d.ts +84 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +80 -1
- package/dist/index.js.map +1 -1
- package/dist-rn/index.d.ts +84 -8
- package/dist-rn/index.js +80 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,16 @@ interface AmbaConfig {
|
|
|
19
19
|
* Defaults to `"https://api.amba.dev"`.
|
|
20
20
|
*/
|
|
21
21
|
apiUrl?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Base URL for `Amba.functions.invoke()`. Set this to call your deployed
|
|
24
|
+
* functions through a custom domain or a non-prod environment, e.g.
|
|
25
|
+
* `"https://api.example.com"` or `"https://<id>.staging.fn.amba.host"`.
|
|
26
|
+
* `invoke(name, body)` POSTs to `"<functionsBaseUrl>/<name>"`.
|
|
27
|
+
*
|
|
28
|
+
* When omitted, the SDK resolves the default host automatically on first
|
|
29
|
+
* use (one cached round-trip) — no configuration needed for production.
|
|
30
|
+
*/
|
|
31
|
+
functionsBaseUrl?: string;
|
|
22
32
|
/**
|
|
23
33
|
* If `true`, blocks all telemetry until `setConsent(granted)` is called.
|
|
24
34
|
* Required for SOC2 / GDPR strict modes.
|
|
@@ -267,17 +277,23 @@ interface ChallengeProgress {
|
|
|
267
277
|
claimed_at?: string | null;
|
|
268
278
|
}
|
|
269
279
|
interface CurrencyBalance {
|
|
270
|
-
|
|
271
|
-
|
|
280
|
+
currency_code: string;
|
|
281
|
+
name: string;
|
|
282
|
+
is_premium: boolean;
|
|
272
283
|
balance: number;
|
|
273
|
-
|
|
284
|
+
lifetime_earned: number;
|
|
285
|
+
lifetime_spent: number;
|
|
274
286
|
}
|
|
275
287
|
interface CurrencyTransaction {
|
|
276
288
|
id: string;
|
|
277
|
-
|
|
278
|
-
|
|
289
|
+
app_user_id?: string;
|
|
290
|
+
currency_code: string;
|
|
291
|
+
amount: number;
|
|
279
292
|
balance_after: number;
|
|
280
|
-
|
|
293
|
+
transaction_type?: string;
|
|
294
|
+
source?: string;
|
|
295
|
+
reference_id?: string | null;
|
|
296
|
+
idempotency_key?: string | null;
|
|
281
297
|
created_at: string;
|
|
282
298
|
}
|
|
283
299
|
interface InventoryItem {
|
|
@@ -688,6 +704,8 @@ interface LeagueCohortMember {
|
|
|
688
704
|
display_name?: string | null;
|
|
689
705
|
score: number;
|
|
690
706
|
rank: number;
|
|
707
|
+
/** `true` for the requesting user's own row (server-derived; no id leak). */
|
|
708
|
+
is_me?: boolean;
|
|
691
709
|
}
|
|
692
710
|
interface LeagueMembership {
|
|
693
711
|
cohort: LeagueCohort | null;
|
|
@@ -852,6 +870,13 @@ declare class AmbaApiError extends Error {
|
|
|
852
870
|
}
|
|
853
871
|
//#endregion
|
|
854
872
|
//#region src/index.d.ts
|
|
873
|
+
/** Options for `Amba.functions.invoke`. */
|
|
874
|
+
interface InvokeOptions {
|
|
875
|
+
/** HTTP method. Defaults to `"POST"`. */
|
|
876
|
+
method?: "POST" | "GET" | "PUT" | "PATCH" | "DELETE";
|
|
877
|
+
/** Extra headers merged on top of the injected auth headers. */
|
|
878
|
+
headers?: Record<string, string>;
|
|
879
|
+
}
|
|
855
880
|
/**
|
|
856
881
|
* Top-level SDK namespace.
|
|
857
882
|
*
|
|
@@ -1009,6 +1034,32 @@ declare const Amba: {
|
|
|
1009
1034
|
* code is `EMAIL_ALREADY_LINKED`.
|
|
1010
1035
|
*/
|
|
1011
1036
|
linkEmailOtp: (email: string, code: string) => Promise<User>;
|
|
1037
|
+
/**
|
|
1038
|
+
* Upgrade an anonymous (or any current) session by attaching an
|
|
1039
|
+
* email + password credential — converting the current user in place
|
|
1040
|
+
* to an email-identified account so its data (streak, library,
|
|
1041
|
+
* progress, `anonymous_id`) is preserved rather than minting a new
|
|
1042
|
+
* user.
|
|
1043
|
+
*
|
|
1044
|
+
* Guarantees (symmetric to `linkEmailOtp`):
|
|
1045
|
+
*
|
|
1046
|
+
* - **Same `user_id`** before and after.
|
|
1047
|
+
* - **Session token unchanged.** No rotation; `onAuthStateChange`
|
|
1048
|
+
* does NOT fire.
|
|
1049
|
+
* - **Idempotent.** Re-linking the same email to the same user
|
|
1050
|
+
* succeeds.
|
|
1051
|
+
* - **Collision.** If the email is already owned by a different user,
|
|
1052
|
+
* throws an error with `code = "EMAIL_ALREADY_LINKED"` and
|
|
1053
|
+
* `details.conflicting_user_id` populated.
|
|
1054
|
+
*
|
|
1055
|
+
* After linking, the user can sign in with `signInWithEmail(email,
|
|
1056
|
+
* password)`. Requires an active session — throws `UNAUTHORIZED`
|
|
1057
|
+
* otherwise.
|
|
1058
|
+
*
|
|
1059
|
+
* @returns the updated user record (with `email` set and
|
|
1060
|
+
* `email_verified = true`).
|
|
1061
|
+
*/
|
|
1062
|
+
linkEmailPassword: (email: string, password: string) => Promise<User>;
|
|
1012
1063
|
/**
|
|
1013
1064
|
* Detach the SMS-OTP identifier from the current session's user.
|
|
1014
1065
|
* Refused with `LAST_IDENTIFIER` if this would leave the account
|
|
@@ -1242,6 +1293,31 @@ declare const Amba: {
|
|
|
1242
1293
|
};
|
|
1243
1294
|
};
|
|
1244
1295
|
};
|
|
1296
|
+
/**
|
|
1297
|
+
* Invoke a deployed function by name, with the project's client key (and
|
|
1298
|
+
* the live session token, if any) injected automatically.
|
|
1299
|
+
*
|
|
1300
|
+
* This is the authenticated way to call your functions — prefer it over
|
|
1301
|
+
* hand-rolling `fetch` against a function URL, which leaves the call
|
|
1302
|
+
* unauthenticated (a footgun when the function holds secrets).
|
|
1303
|
+
*
|
|
1304
|
+
* @example
|
|
1305
|
+
* const result = await Amba.functions.invoke<{ ok: boolean }>(
|
|
1306
|
+
* 'send_welcome_email',
|
|
1307
|
+
* { to: 'user@example.com' },
|
|
1308
|
+
* );
|
|
1309
|
+
*
|
|
1310
|
+
* @param name The deployed function name.
|
|
1311
|
+
* @param body JSON-serializable request body (omitted for GET).
|
|
1312
|
+
* @param options Method + extra headers.
|
|
1313
|
+
* @returns The parsed JSON response (or the raw text if not JSON).
|
|
1314
|
+
* @throws AmbaApiError on a network failure or a non-2xx response. When
|
|
1315
|
+
* the function / router returns the standard `{ error: { code, message } }`
|
|
1316
|
+
* envelope, those surface as the thrown error's `code` + `message`.
|
|
1317
|
+
*/
|
|
1318
|
+
functions: {
|
|
1319
|
+
invoke: <T = unknown>(name: string, body?: unknown, options?: InvokeOptions) => Promise<T>;
|
|
1320
|
+
};
|
|
1245
1321
|
/** Remote config bundle. */
|
|
1246
1322
|
config: {
|
|
1247
1323
|
fetch: () => Promise<ConfigBundle>;
|
|
@@ -1559,7 +1635,7 @@ declare function getCoreWasm(): AmbaCoreWasm;
|
|
|
1559
1635
|
* `verify-sdk-version-coherence` GH action gates every publish on the
|
|
1560
1636
|
* pair agreeing (and matching the `web-v<X.Y.Z>` tag when tag-triggered).
|
|
1561
1637
|
*/
|
|
1562
|
-
declare const SDK_VERSION = "4.0.
|
|
1638
|
+
declare const SDK_VERSION = "4.0.4";
|
|
1563
1639
|
//#endregion
|
|
1564
|
-
export { Achievement, AchievementProgress, AiMessage, AiMessageRequest, AiMessageResponse, AiUsage, Amba, AmbaApiError, type AmbaApiErrorCode, AmbaConfig, AndFilter, AppSession, AuthResult, CatalogItem, Challenge, ChallengeProgress, CollectionSubscription, ConditionFilter, ConfigBundle, ConsumeRequest, ContentItem, Conversation, ConversationParticipant, ConversationSubscription, ConversationType, CreateConversationRequest, CurrencyBalance, CurrencyTransaction, DeepLink, DeepLinkCreate, DiagnosticsEnvironment, EntitlementSource, FeedItem, FeedResponse, Filter, FilterValue, FindOptions, FindResponse, FlagAssignment, Friendship, FriendshipState, Group, GroupCreate, GroupMember, GroupUpdate, InventoryItem, Leaderboard, LeaderboardEntry, LeagueCohort, LeagueCohortMember, LeagueCohortView, LeagueMembership, LeagueTier, LinkedIdentifier, ListMessagesOptions, MarkReadResult, MediaAsset, MediaListResponse, Message, type MessageChange, MessageType, NearestOptions, NearestResponse, NotFilter, OnboardingStatus, OrFilter, OrderBy, PingResult, PresignData, PullChangesCursor, PullChangesResult, PurchaseOption, PurchaseRequest, PurchaseResult, PushChangesResult, PushPlatform, PushToken, type RealtimeChange, ReferralClaim, ReferralCode, Report, ReportRequest, Review, ReviewCreate, ReviewUpdate, Role, type RowChangeOp, SDK_VERSION, SendMessageRequest, Session, SocialProvider, Store, Streak, type SubscribeOptions, SyncChange, SyncConflict, type Unsubscribe, User, UserEntitlement, XpBalance, XpTransaction, getCoreWasm };
|
|
1640
|
+
export { Achievement, AchievementProgress, AiMessage, AiMessageRequest, AiMessageResponse, AiUsage, Amba, AmbaApiError, type AmbaApiErrorCode, AmbaConfig, AndFilter, AppSession, AuthResult, CatalogItem, Challenge, ChallengeProgress, CollectionSubscription, ConditionFilter, ConfigBundle, ConsumeRequest, ContentItem, Conversation, ConversationParticipant, ConversationSubscription, ConversationType, CreateConversationRequest, CurrencyBalance, CurrencyTransaction, DeepLink, DeepLinkCreate, DiagnosticsEnvironment, EntitlementSource, FeedItem, FeedResponse, Filter, FilterValue, FindOptions, FindResponse, FlagAssignment, Friendship, FriendshipState, Group, GroupCreate, GroupMember, GroupUpdate, InventoryItem, InvokeOptions, Leaderboard, LeaderboardEntry, LeagueCohort, LeagueCohortMember, LeagueCohortView, LeagueMembership, LeagueTier, LinkedIdentifier, ListMessagesOptions, MarkReadResult, MediaAsset, MediaListResponse, Message, type MessageChange, MessageType, NearestOptions, NearestResponse, NotFilter, OnboardingStatus, OrFilter, OrderBy, PingResult, PresignData, PullChangesCursor, PullChangesResult, PurchaseOption, PurchaseRequest, PurchaseResult, PushChangesResult, PushPlatform, PushToken, type RealtimeChange, ReferralClaim, ReferralCode, Report, ReportRequest, Review, ReviewCreate, ReviewUpdate, Role, type RowChangeOp, SDK_VERSION, SendMessageRequest, Session, SocialProvider, Store, Streak, type SubscribeOptions, SyncChange, SyncConflict, type Unsubscribe, User, UserEntitlement, XpBalance, XpTransaction, getCoreWasm };
|
|
1565
1641
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/realtime.ts","../src/error.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/realtime.ts","../src/error.ts","../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;;AAQA;AA+BA;AAEA;AAEA;AA4BiB,UA/DA,UAAA,CA+DgB;EAMhB;EAgBA,SAAA,EAAO,MAAA;EASZ;EAEK,SAAA,EAAA,MAAA;EAMA;AAIjB;AAIA;AAIA;EAAqB,MAAA,CAAA,EAAA,MAAA;EAAkB;;;;AAEvC;AAKA;AASA;AAQA;AAaA;EASiB,gBAAS,CAAA,EAAA,MAGd;EAOA;AAQZ;AAYA;AAKA;EASiB,eAAO,CAAA,EAAA,OAAA;EAOP;EAoBA,KAAA,CAAA,EAAA,OAAY;EAKZ;EAgBL,aAAA,CAAA,EAAA,MAAA;AAEZ;AAmCiB,KAlQL,cAAA,GAkQgB,OAAA,GAAA,QAAA;AAWX,KA3QL,YAAA,GA2QwB,MAAA,GAAA,KAAA,GAAA,KAAA;AAUnB,UAnRA,IAAA,CAmRS;EAWT,EAAA,EAAA,MAAA;EAcA,KAAA,CAAA,EAAA,MAAA,GAAA,IAAe;EAWf;EAeA,KAAA,CAAA,EAAA,MAAA,GAAa,IAAA;EASb;EAMA,cAAA,CAAA,EAAc,OAAA;EAOd;EAUA,cAAA,CAAA,EAAA,OAAgB;EAUhB,YAAK,CAAA,EAAA,MAAA,GAAA,IAAA;EAML,UAAA,CAAA,EAAA,MAAc,GAAA,IAAA;EAWd,WAAA,CAAA,EAAA,MAAc,GAAA,IAAA;EAWd,YAAS,CAAA,EAAA,MAAA,GAAA,IAAA;EAeT,cAAA,EAAa,MAAA,EAAA;EAUb,UAAM,EAvZT,MAuZS,CAAA,MAAA,EAAA,OAAA,CAAA;EAgCN,aAAQ,CAAA,EAAA,MAAA;EAYR,YAAA,CAAA,EAAY,MAAA;EAOjB,UAAA,CAAA,EAAA,MAAe;EAEV,UAAA,CAAA,EAAU,MAAA;AAU3B;AAYA;AAOA;AAOA;AASA;AAEA;AAEA;AAWA;AA0BiB,UAphBA,gBAAA,CAohByB;EAYzB,QAAA,EAAA,SAAA,GAAkB,WAElB,GAAA,OAAA,GACJ,QAAM;EAIF,QAAA,EAAA,OAAA;EASA,iBAAc,EAAA,MAAA,GAAA,IAAA;AAW/B;AAUiB,UA/jBA,UAAA,CA+jBM;EAYN,aAAA,EAAA,MAAa;EAQb,aAAA,EAAY,MAAA;EAUZ,IAAA,EA1lBT,IA0lBS;EAWA,YAAM,CAAA,EAAA,MAAA,GAAA,IAAA;EAYN,UAAA,CAAA,EAAA,MAAY,GAAA,IAAA;AAQ7B;AAQA;AASA;AAYA;AAYA;AASA;AAQA;AAgBA;AAgBA;AAUiB,UAhtBA,OAAA,CAgtBY;EAQZ,YAAA,EAAA,MAAiB;EAMjB,YAAA,EAAA,MAAiB;EAWjB,IAAA,EAtuBT,IAsuBS;EAOA,SAAA,EAAA,MAAY;AAS7B;AAMiB,KAtvBL,WAAA,GAsvBuB,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,IAAA,GAAA,OAAA,EAAA;AAQlB,UA5vBA,eAAA,CA4vBgB;EAQhB,MAAA,EAAA,MAAA;EACP,EAAA,EAAA,MAAA;EACA,KAAA,CAAA,EAnwBA,WAmwBA;;AACmB,UAjwBZ,SAAA,CAiwBY;EAKZ,GAAA,EArwBV,MAqwBU,EAAA;AAgBjB;AAWiB,UA7xBA,QAAA,CA6xBe;MA5xB1B;;UAGW,SAAA;EChGL,GAAA,EDiGL,MCjGK;AAEZ;AAaiB,KDqFL,MAAA,GAAS,eCrFY,GDqFM,SCrFN,GDqFkB,QCrFlB,GDqF6B,SCrF7B;AAQrB,UD+EK,OAAA,CC/EM;EAMN,MAAA,EAAA,MAAA;EAYJ,SAAA,EAAA,KAAA,GAAA,MAAsB;;AAkBK,UDgDvB,WAAA,CChDuB;EAAf,MAAA,CAAA,EDiDd,MCjDc;EAAqC,KAAA,CAAA,EDkDpD,OClDoD,EAAA;EAAwB,KAAA,CAAA,EAAA,MAAA;EAAW,MAAA,CAAA,EAAA,MAAA;EAwJrF,MAAA,CAAA,EAAA,MAAA,EAAa;EAiBZ,eAAA,CAAA,EAAA,OAAA;;AAM0B,UDtHtB,YCsHsB,CAAA,CAAA,CAAA,CAAA;EAAd,IAAA,EDrHjB,CCqHiB,EAAA;EAAoC,WAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAwB,QAAA,EAAA,OAAA;;UD9GpE,UAAA;;;EEhIL,GAAA,EAAA,MAAA;EAoBC,GAAA,EAAA,MAAA;EACI,SAAA,EAAA,MAAA;EAGP,UAAA,EAAA,MAAA;EAJwB,KAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAK,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;;;ACuOtB,UH9GA,WAAA,CG8Ga;EAajB,SA++CZ,EAAA,MAAA;EAx+C2B,UAAA,EAAA,MAAA;EAAa,cAAA,EH/HvB,KG+HuB,CAAA,CAAA,MAAA,EAAA,MAAA,CAAA,CAAA;EA+JtB,QAAA,EAAA,MAAA;;AAasB,UHrSxB,SAAA,CGqSwB;EAAR,EAAA,EAAA,MAAA;EAQlB,KAAA,EAAA,MAAA;EAAR,QAAA,EH1SK,YG0SL;EAWQ,SAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAR,UAAA,EAAA,MAAA;;AAc6C,KH5TxC,iBAAA,GG4TwC,aAAA,GAAA,WAAA,GAAA,YAAA,GAAA,QAAA,GAAA,YAAA,GAAA,QAAA;AAcG,UHlUtC,eAAA,CGkUsC;EAAR,EAAA,EAAA,MAAA;EAeH,IAAA,EAAA,MAAA;EAUqB,SAAA,EAAA,OAAA;EAAR,MAAA,EHvV/C,iBGuV+C;EAcf,UAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAQqB,UAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAR,QAAA,EH1W3C,MG0W2C,CAAA,MAAA,EAAA,OAAA,CAAA;;AAqBH,UH1XnC,SAAA,CG0XmC;EAAR,IAAA,EAAA,MAAA;EAe7B,OAAA,EAAA,OAAA;;AAoC8C,UHxa5C,gBAAA,CGwa4C;EAAR,WAAA,EAAA,MAAA;EASU,SAAA,CAAA,EH/ajD,MG+aiD,CAAA,MAAA,EAAA,OAAA,CAAA;EAAR,QAAA,CAAA,EH9a1C,SG8a0C,EAAA;EA6BiB,UAAA,CAAA,EAAA,MAAA;EAAR,WAAA,CAAA,EAAA,MAAA;EAU5B,mBAAA,CAAA,EAAA,OAAA;;AAKE,UHpdrB,OAAA,CGodqB;EAAR,YAAA,EAAA,MAAA;EAKK,aAAA,EAAA,MAAA;EAAR,2BAAA,CAAA,EAAA,MAAA;EAKS,uBAAA,CAAA,EAAA,MAAA;;AAYS,UHne5B,iBAAA,CGme4B;EAAR,OAAA,EAAA,OAAA,EAAA;EAGW,KAAA,EHpevC,OGoeuC;EAKjB,WAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAR,KAAA,EAAA,MAAA;;;;;;;;;;;;;AAqFe,UH5iBrB,YAAA,CG4iBqB;EAAR,OAAA,EAAA,MAAA,GAAA,IAAA;EAAwB,MAAA,EH1iB5C,MG0iB4C,CAAA,MAAA,EAAA,OAAA,CAAA;;AAO1B,UH9iBX,cAAA,CG8iBW;EAAR,IAAA,EAAA,MAAA;EASmB,OAAA,EAAA,OAAA;EAqB2B,OAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAvB,OAAA,CAAA,EAAA,OAAA;;;AAW5B,KHvkBH,sBAAA,GGukBG,YAAA,GAAA,SAAA,GAAA,SAAA;AAAR,UHrkBU,UAAA,CGqkBV;EAM6D;;;;;;EAgBrD,EAAA,EAAA,OAAA;EAAR;;;;;EA8BA,iBAAA,EAAA,MAAA,GAAA,IAAA;EAWkC;EAAS,WAAA,EHrnBnC,sBGqnBmC,GAAA,IAAA;EAQhB;;;;EAUA,eAAA,EAAA,MAAA;EAAc;;;;EAUA,UAAA,EAAA,MAAA;EAKb;;;;EAUG,KAAA,EAAA,MAAA,GAAA,IAAA;;AAKS,UHjpB9B,WAAA,CGipB8B;EAKC,EAAA,EAAA,MAAA;EAKhB,GAAA,EAAA,MAAA;EACG,IAAA,EAAA,MAAA;EACX,WAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAW,QAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EACZ;EAAW,SAAA,EAAA,MAAA;EACd,QAAA,EAAA,OAAA;;AAYJ,UHhqBC,mBAAA,CGgqBD;EAAR,cAAA,EAAA,MAAA;EAeI,GAAA,EAAA,MAAA;EAAO,QAAA,EAAA,MAAA;EAGH,QAAA,EAAA,OAAA;EAAR,WAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;AAqC2B,UH7sBlB,SAAA,CG6sBkB;EAUE,EAAA,EAAA,MAAA;EAWU,GAAA,EAAA,MAAA;EAAR,IAAA,EAAA,MAAA;EA4BxB,WAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EACA,SAAA,EAAA,MAAA;EAAR,OAAA,EAAA,MAAA;EAaM,QAAA,EAAA,OAAA;EACE,MAAA,EAAA,OAAA;;AAWC,UH7wBC,iBAAA,CG6wBD;EAED,YAAA,EAAA,MAAA;EAAR,QAAA,EAAA,MAAA;EAOgC,SAAA,EAAA,OAAA;EAGN,OAAA,EAAA,OAAA;EAAR,YAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAGa,UAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;AAUV,UHxxBX,eAAA,CGwxBW;EAAR,aAAA,EAAA,MAAA;EAGW,IAAA,EAAA,MAAA;EAUZ,UAAA,EAAA,OAAA;EACA,OAAA,EAAA,MAAA;EAAR,eAAA,EAAA,MAAA;EAmCK,cAAA,EAAA,MAAA;;AACT,UH/zBU,mBAAA,CG+zBV;EAiFsB,EAAA,EAAA,MAAA;EAAR,WAAA,CAAA,EAAA,MAAA;EAOQ,aAAA,EAAA,MAAA;EAAR,MAAA,EAAA,MAAA;EAQiB,aAAA,EAAA,MAAA;EAAR,gBAAA,CAAA,EAAA,MAAA;EAqBF,MAAA,CAAA,EAAA,MAAA;EAAR,YAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EASU,eAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAR,UAAA,EAAA,MAAA;;AAEK,UHh7BV,aAAA,CGg7BU;EAMM,EAAA,EAAA,MAAA;EAAR,eAAA,EAAA,MAAA;EAEY,GAAA,EAAA,MAAA;EAAR,QAAA,EAAA,MAAA;EAEgB,WAAA,EAAA,MAAA;EAAR,QAAA,EAAA,OAAA;;AAEN,UHn7Bd,eAAA,CGm7Bc;EAMG,GAAA,EAAA,MAAA;EAAR,QAAA,CAAA,EAAA,MAAA;EAIX,YAAA,CAAA,EAAA,MAAA;;AAQiB,UH/7Bf,cAAA,CG+7Be;EAAR,OAAA,EAAA,MAAA;EAEiB,QAAA,EAAA,MAAA;;AAEX,UH57Bb,WAAA,CG47Ba;EAA0B,EAAA,EAAA,MAAA;EAAR,GAAA,EAAA,MAAA;EAInB,IAAA,EAAA,MAAA;EAAyB,MAAA,EAAA,MAAA;EAAR,SAAA,EAAA,MAAA;EAQR,SAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAR,OAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;AAKvB,UHn8BU,gBAAA,CGm8BV;EAKqC,IAAA,EAAA,MAAA;EAAR,OAAA,EAAA,MAAA;EAcV,YAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAR,UAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EASY,KAAA,EAAA,MAAA;;AAOF,UH59BX,KAAA,CG49BW;EAAR,EAAA,EAAA,MAAA;EAEsC,GAAA,EAAA,MAAA;EAAR,IAAA,EAAA,MAAA;;AAQ3C,UHh+BU,cAAA,CGg+BV;EAc2B,EAAA,EAAA,MAAA;EAAR,QAAA,EAAA,MAAA;EAEsB,GAAA,EAAA,MAAA;EAAR,IAAA,EAAA,MAAA;EAIK,WAAA,EAAA,MAAA;EAAR,QAAA,EAAA,MAAA;EAMP,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAR,QAAA,EAAA,OAAA;;AAEkB,UHj/BvB,cAAA,CGi/BuB;EAWzB,EAAA,EAAA,MAAA;EAAR,OAAA,EAAA,MAAA;EASwB,kBAAA,EAAA,MAAA;EAAR,MAAA,EAAA,MAAA;EAEW,YAAA,EAAA,MAAA;EAAR,OAAA,EAAA,OAAA;;AAMe,UHlgCxB,SAAA,CGkgCwB;EAMgB,OAAA,EAAA,MAAA;EAAR,QAAA,EAAA,MAAA;EAQC,aAAA,EAAA,MAAA;EAGH,aAAA,EAAA,MAAA;EAAR,gBAAA,EAAA,MAAA;EAEE,UAAA,EAAA,MAAA;EAGM;;;;;EAkBV,cAAA,EAAA,MAAA;;AAEC,UH7hCrB,aAAA,CG6hCqB;EAAsB,EAAA,EAAA,MAAA;EAAR,KAAA,EAAA,MAAA;EAEpB,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAGY,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAR,UAAA,EAAA,MAAA;;AAEN,UH1hCb,MAAA,CG0hCa;EAEC,EAAA,EAAA,MAAA;EAGyB;;;;EAkCjD,GAAA,EAAA,MAAA;EAU8B;EAAR,IAAA,EAAA,MAAA;EAYd;EACA,aAAA,EAAA,MAAA;EAAR;EAgBM,aAAA,EAAA,MAAA;EACE;EAAR,iBAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAiBQ,UAAA,EAAA,MAAA;EAAR;;;;;;EAwD2E,MAAA,EAAA,QAAA,GAAA,QAAA,GAAA,QAAA;EAAzB;;;;EAatB,iBAAA,EAAA,MAAA;;AAAgB,UH/pClC,QAAA,CG+pCkC;EAIF,EAAA,EAAA,MAAA;EAAR,QAAA,EAAA,MAAA;EAMuB,IAAA,EAAA,MAAA;EAAR,WAAA,EAAA,MAAA;EAE7B,SAAA,EAAA,MAAA;EAAuB,WAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAR,SAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAEJ,IAAA,EAAA,OAAA;EAAuB,UAAA,EAAA,MAAA;;AAE7B,UHnqCf,YAAA,CGmqCe;EAOE,IAAA,EHzqC1B,QGyqC0B,EAAA;EAAR,WAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;AAQa,KH3qC3B,eAAA,GG2qC2B,SAAA,GAAA,UAAA,GAAA,SAAA,GAAA,UAAA;AAAR,UHzqCd,UAAA,CGyqCc;EAEkB,EAAA,EAAA,MAAA;EAAR,OAAA,EAAA,MAAA;EAK1B,SAAA,EAAA,MAAA;EAAR,KAAA,EH5qCE,eG4qCF;EAWqB,UAAA,EAAA,MAAA;;AAMS,UHvrCpB,KAAA,CGurCoB;EAAR,EAAA,EAAA,MAAA;EAW2B,IAAA,EAAA,MAAA;EAAR,WAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAWjC,UAAA,CAAA,EAAA,MAAA,GAAA,IAAA;EAAR,UAAA,EAAA,MAAA;EAM+B,YAAA,EAAA,MAAA;EAAR,UAAA,EAAA,MAAA;EAE8B,UAAA,EAAA,MAAA;EAAR,QAAA,EAAA,OAAA;;AAQ7C,UHjtCU,WAAA,CGitCV;EASqC,QAAA,EAAA,MAAA;EAAR,OAAA,EAAA,MAAA;EAET,IAAA,EAAA,MAAA;EAAyB,SAAA,EAAA,MAAA;;AAMnB,UH3tChB,WAAA,CG2tCgB;EAAR,IAAA,EAAA,MAAA;EAEuB,WAAA,CAAA,EAAA,MAAA;EAAR,UAAA,CAAA,EAAA,MAAA;EAIR,QAAA,CAAA,EAAA,OAAA;;AAEA,UH5tCf,WAAA,CG4tCe;EAAR,IAAA,CAAA,EAAA,MAAA;EAAO,WAAA,CAAA,EAAA,MAAA;EAOf,UAAA,CAAA,EAAA,MAAW;EAYd,QAAA,CAAA,EAAA,OAAW;;KHtuCZ,gBAAA;KAEA,WAAA;UAEK,OAAA;;;;;;iBAMA;;;;UAKA,YAAA;;;SAGR;;;;;;;;;;;iBAWQ;;;;;;;;;;;UAYA,yBAAA;;SAER;;;;;;;;;UAUQ,kBAAA;;iBAEA;aACJ;;;UAII,mBAAA;;;;;;;;UASA,cAAA;;;;;;;;;;UAWA,uBAAA;;;;;;;UAUA,MAAA;;;;;;;;;;;UAYA,aAAA;;;;;UAQA,YAAA;;;;;;;;;UAUA,aAAA;;;;;;;;UAWA,MAAA;;;;;;;;;;;UAYA,YAAA;;;;;;;UAQA,YAAA;;;;;UAQA,IAAA;;;;;;UASA,WAAA;;;;;;;;;UAYA,WAAA;;;;;;;;;UAYA,QAAA;;;;;;;;UASA,cAAA;;;;;UAQA,gBAAA;;;;;;;;;;;;;UAgBA,UAAA;;;;;;;;;;;;;UAgBA,UAAA;;;;;;;;;UAUA,YAAA;;;;;;;UAQA,iBAAA;;aAEJ;;;UAII,iBAAA;WACN;;;;;;;;;UAUM,iBAAA;;;;UAOA,YAAA;;;;;;;;UASA,UAAA;;;;;UAMA,kBAAA;;;;;;;UAQA,gBAAA;UACP;UACA;;;;;UAMO,gBAAA;UACP;UACA;WACC;;UAKM,iBAAA;QACT;;;;;;;;;;;;UAeS,cAAA;;;;;;;;WAQN;;UAGM;QACT;;;;;;;AAx4BR;AA+BA;AAEA;AAEA;AA4BA;AAMA;AAgBA;AASA;AAEA;AAMA;AAIA;AAIA;AAIA;;;;;;AAEiB,KCtGL,WAAA,GDsGY,QAAA,GAAA,QAAA,GAAA,QAAA;AAKP,UCzGA,cD0GN,CAAA,IAAA,OACD,CAAA,CAAA;EAOO;EAQA,EAAA,ECxHX,WDwHqB;EAaV;AASjB;AAUA;AAQA;AAYA;AAKA;EASiB,GAAA,ECnLV,CDmLU;EAOA,SAAA,CAAA,EAAA,OAAA;AAoBjB;AAKiB,UC/MA,gBAAA,CD+Mc;EAgBnB;EAEK,MAAA,CAAA,EAAA,GAAA,GAAU,IAAA;EAmCV;EAWA,OAAA,CAAA,EAAA,CAAA,GAAA,EAAA,OAAmB,EAAA,GAAA,IAAA;AAUpC;AAWA;AAciB,KC1SL,WAAA,GD0SoB,GAAA,GAAA,IAAA;AAWhC;AAeA;AASA;AAMA;AAOiB,UCpVA,eAAA,CDoVW;EAUX,OAAA,EAAA,MAAA;EAUA,WAAK,EAAA,GAAA,GCtWD,MDsWC,CAAA,MAAA,EAAA,MAAA,CAAA,GAAA,IAAA;AAMtB;AAWA;AAWA;AAeA;AAUA;AAgCiB,cCjbJ,sBDibY,CAAA,IAAA,OAAA,CAAA,CAAA;EAYR,iBAAY,GAAA;EAOjB,iBAAA,IAAe;EAEV,iBAAU,OAAA;EAUV,WAAK,CAAA,GAAA,EC5cI,eD4cJ,EAAA,IAAA,EAAA,MAAA;EAYL;EAOA,KAAA,CAAA,MAAA,EAAW,MAAA,EAAA,KAAA,EAAA,OAAA,CAAA,EAAA,IAAA;EAOX;AASjB;AAEA;AAEA;EAWiB,SAAA,CAAA,EAAA,EAAA,CAAY,MAAA,EChfJ,cDmfhB,CCnf+B,CDmf/B,CAAA,EAAA,GAWQ,IAAA,EAAA,OAAO,CAAA,EC9fsC,gBD8ftC,CAAA,EC9f8D,WD8f9D;AAYxB;AAYA;AAOA;AASA;AAWA;AAUA;AAYA;AAQA;AAUiB,KCjcL,aDickB,CAAA,IAAA,OAAA,CAAA,GCjcW,cDicX,CCjc0B,CDic1B,CAAA;AAW9B;AAYA;AAQA;AAQA;AASA;AAYA;AAYA;AASA;AAQA;AAgBA;AAgBA;AAUA;AAQA;AAMA;AAWA;AAOiB,cCnlBJ,wBDmlBgB,CAAA,IAAA,OAAA,CAAA,CAAA;EASZ,iBAAU,GAAA;EAMV,iBAAA,cAAkB;EAQlB,WAAA,CAAA,GAAA,ECxmBS,eDymBhB,EAAA,cACA,EAAA,MAAU;EAMH,SAAA,CAAA,EAAA,EAAA,CAAA,MAAgB,EC5mBR,aD4mBQ,CC5mBM,CD4mBN,CAAA,EAAA,GAAA,IAAA,EAAA,OAAA,CAAA,EC5mB4B,gBD4mB5B,CAAA,EC5mBoD,WD4mBpD;;;;;;;AAp2BjC;AA+BA;AAEA;AAEA;AA4BA;AAMA;AAgBA;AASA;AAEA;AAMA;AAIA;AAIA;AAIA;;AAAuC,KExG3B,gBAAA,GFwG2B,cAAA,GAAA,WAAA,GAAA,WAAA,GAAA,UAAA,GAAA,cAAA,GAAA,kBAAA,GAAA,eAAA,GAAA,YAAA,GAAA,cAAA,GAAA,qBAAA,GAAA,iBAAA,GAAA,gBAAA,GAAA,kBAAA,GAAA,wBAAA,GAAA,0BAAA,GAAA,kBAAA,GAAA,eAAA,GAAA,CAAA,MAAA,GAAA,CAAA,CAAA,CAAA;AAAY,cEpFtC,YAAA,SAAqB,KAAA,CFoFiB;EAAW,SAAA,IAAA,EEnF7C,gBFmF6C;EAAS,SAAA,OAAA,CAAA,EAAA,OAAA;EAEtD,WAAO,CAAA,IAAA,EElFd,gBFkFc,EAAA,OAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAAA,OAAA;AAKxB;;;AAyDA;AAYiB,UGuEA,aAAA,CHvES;EAKT;EASA,MAAA,CAAA,EAAA,MAAO,GAAA,KAAA,GAAA,KAAA,GAAA,OAAA,GAAA,QAAA;EAOP;EAoBA,OAAA,CAAA,EGkCL,MHlCiB,CAAA,MAAA,EAAA,MAEnB,CAAA;AAGV;AAgBA;AAEA;AAmCA;AAWA;AAUA;AAWA;AAciB,cG7DJ,IH6DmB,EAAA;EAWf;AAejB;AASA;AAMA;AAOA;AAUA;EAUiB,SAAK,EAAA,CAAA,MAAA,EG1HM,UH0HN,EAAA,GG1HmB,OH0HnB,CAAA,IAAA,CAAA;EAML;EAWA,SAAA,SAAc,EAAA,MAAA;EAWd;EAeA,SAAA,WAAa,EAAA,MAAA;EAUb;EAgCA,SAAA,SAAQ,EAAA,MAAA,GAAA,SAAA;EAYR;EAOL,SAAA,eAAe,EAAA,OAAA;EAEV;EAUA,QAAK,EAAA,CAAA,OAAA,EAAA,OAAA,EAAA,GAAA,IAAA;EAYL;EAOA,MAAA,EAAA;IAOA;AASjB;AAEA;AAEA;AAWA;AA0BA;AAYA;AAOA;AASA;AAWA;AAUA;AAYA;AAQA;AAUA;AAWA;AAYA;AAQA;AAQA;AASA;IAYiB,KAAA,EAAA,CAAA,KAAW,EAAA,MAAA,EAAA,UAAA,CAAA,EGtST,MHsSS,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,OAqBX,CArBW,EAAA;MAYX,SAAQ,CAAA,EAAA,OAAA;IASR,CAAA,EAAA,GGzTV,OHyTwB,CAAA,IAAA,CAAA;EAQd,CAAA;EAgBA;EAgBA,IAAA,EAAA;IAUA,iBAAY,EAAA,GAAA,GGhWI,OHgWJ,CGhWY,UHgWZ,CAAA;IAQZ,eAAA,EAAiB,CAAA,KAAA,EAAA,MAErB,EAAA,QAAY,EAAA,MAAA,EAAA,GGlWlB,OHkWkB,CGlWV,UHkWU,CAAA;IAIR,eAAA,EAAiB,CAAA,KAAA,EAAA,MACvB,EAAA,QAAU,EAAA,MAAA,EAAA,GG5Vd,OH4Vc,CG5VN,UH4VM,CAAA;IAUJ;AAOjB;AASA;AAMA;AAQA;AAQA;IACU,eAAA,EAAA,CAAA,aAAA,EAAA,MAAA,EAAA,GG/X0C,OH+X1C,CG/XkD,UH+XlD,CAAA;IACA;;;AAMV;AAgBA;AAWA;2CGnZ+C,QAAQ;;;AFtevD;AAEA;AAaA;AAQA;AAMA;IAYa,eAAA,EAAA,CAAA,KAAsB,EAAA,MAAA,EAAA,GE4cS,OF5cT,CAAA,IAAA,CAAA;IAIT;;;;;;AAsK1B;IAiBa,cAAA,EAAA,CAAA,KAAA,EAAwB,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,GE2RoB,OF3RpB,CE2R4B,UF3R5B,CAAA;IAEX;;;;;;;;;IC1Od,aAAA,EAAgB,CAAA,KAAA,EAAA,MAAA,EAAA,GCihBc,ODjhBd,CAAA,IAAA,CAAA;IAoBf;;;;;mDCqgB0C,QAAQ;;;AA9R/D;AAaA;;;;;IAmLyC,gBAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GA2GI,OA3GJ,CAAA,IAAA,CAAA;IAAR;;;;;IAiC2B,eAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GAkFhB,OAlFgB,CAkFR,UAlFQ,CAAA;IAAR;;;;;;;IA6DW,WAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,GAoCxD,OApCwD,CAoChD,UApCgD,CAAA;IAAR;;;;;;;;;;;;;;;;;;;;;;;;;;;IA0KrB,UAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,GAlGmB,OAkGnB,CAlG2B,IAkG3B,CAAA;IAAR;;;;;IAqEJ,YAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,GA9JiC,OA8JjC,CA9JyC,IA8JzC,CAAA;IAAR;;;;;;;;;;;;;;;;;;;;;;;;;IAoGC,iBAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,QAAA,EAAA,MAAA,EAAA,GArOiD,OAqOjD,CArOyD,IAqOzD,CAAA;IACgB;;;;;;IAmBiB,YAAA,EAAA,GAAA,GA/OpB,OA+OoB,CA/OZ,IA+OY,CAAA;IAKd;IAAc,cAAA,EAAA,GAAA,GA/OlB,OA+OkB,CA/OV,IA+OU,CAAA;IAKd;IAAc,WAAA,EAAA,GAAA,GA/OrB,OA+OqB,CA/Ob,IA+Oa,CAAA;IAKb;IAAc,YAAA,EAAA,GAAA,GA/OrB,OA+OqB,CA/Ob,IA+Oa,CAAA;IAKf;;;;;;;;IAoBa,qBAAA,EAAA,GAAA,GA5PV,OA4PU,CA5PF,gBA4PE,EAAA,CAAA;IAKC,OAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,OAAA,EAAA,GA9PA,OA8PA,CAAA,IAAA,CAAA;IAKhB,OAAA,EAAA,GAAA,GA9PT,OA8PS,CA9PD,UA8PC,CAAA;IACG,EAAA,EAAA,GAAA,GA1PjB,OA0PiB,CA1PT,IA0PS,CAAA;IACX;;;;;;IAcR,UAAA,EAAA,GAAA,GA/PU,OA+PV,CA/PkB,OA+PlB,GAAA,IAAA,CAAA;IAAR;;;;;IAuDmC,cAAA,EAAA,GAAA,GA1Sb,OA0Sa,CAAA,MAAA,CAAA;IAAR;;;;;;;;;IAgE5B,iBAAA,EAAA,CAAA,EAAA,EAAA,CAAA,OAAA,EA5Va,OA4Vb,GAAA,IAAA,EAAA,GAAA,IAAA,EAAA,GAAA,CAAA,GAAA,GAAA,IAAA,CAAA;EAWS,CAAA;EAED;EAAR,KAAA,EAAA;IAOgC;;;;;IAgBX,GAAA,EAAA,CAAA,MAAA,CAAA,EAAA,MAAA,EAAA,GAhXM,OAgXN,CAhXc,IAgXd,CAAA;IAAR;;;;;;;;;;IA0IS,MAAA,EAAA;MAAR,CAAA,KAAA,EA/dP,OA+dO,CA/dC,IA+dD,CAAA,CAAA,EA/dS,OA+dT,CA/diB,IA+djB,CAAA;MAQiB,CAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EAteR,OAseQ,CAteA,IAseA,CAAA,CAAA,EAteQ,OAseR,CAtegB,IAsehB,CAAA;IAAR,CAAA;EAqBF,CAAA;EAAR;EASU,QAAA,EAAA;IAAR;IAEa,IAAA,EAAA,GAAA,GA/ff,OA+fe,CA/fP,UA+fO,EAAA,CAAA;IAAR;;;;;;IAUU,MAAA,EAAA,CAAA,SAAA,EAAA,MAAA,EAAA,GAhgBE,OAggBF,CAAA,IAAA,CAAA;EAEE,CAAA;EAAR;;;;;;;;;;;;;;;;EAkCD,UAAA,EAAA,CAAA,IAAA,OAAA,CAAA,CAAA,IAAA,EAAA,MAAA,EAAA,GA/gBa,sBA+gBb,CA/gBoC,CA+gBpC,CAAA;EAKf;EAAR,WAAA,EAAA;IAKqC,IAAA,EAAA,CAAA,IAAA,OAAA,CAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EA/gB7B,WA+gB6B,EAAA,GA9gBrC,OA8gBqC,CA9gB7B,YA8gB6B,CA9gBhB,CA8gBgB,CAAA,CAAA;IAAR,OAAA,EAAA,CAAA,IAAA,OAAA,CAAA,CAAA,IAAA,EAAA,MAAA,EAAA,EAAA,EAAA,MAAA,EAAA,GAxgBwB,OAwgBxB,CAxgBgC,CAwgBhC,CAAA;IAcV,MAAA,EAAA,CAAA,IAAA,OAAA,CAAA,CAAA,IAAA,EAAA,MAAA,EAAA,GAAA,EAjhBf,MAihBe,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,GAhhBnB,OAghBmB,CAhhBX,CAghBW,CAAA;IAAR,MAAA,EAAA,CAAA,IAAA,OAAA,CAAA,CAAA,IAAA,EAAA,MAAA,EAAA,EAAA,EAAA,MAAA,EAAA,GAAA,EAvgBP,MAugBO,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,GAtgBX,OAsgBW,CAtgBH,CAsgBG,CAAA;IASY,MAAA,EAAA,CAAA,IAAA,EAAA,MAAA,EAAA,EAAA,EAAA,MAAA,EAAA,GArgBvB,OAqgBuB,CAAA;MAAR,IAAA,EAAA;QAOM,OAAA,EAAA,OAAA;MAAR,CAAA;IAEsC,CAAA,CAAA;IAAR;;;;;;;;;;;;IAoCV,WAAA,EAAA,CAAA,IAAA,OAAA,CAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EA/hBzB,cA+hByB,EAAA,GA9hBjC,OA8hBiC,CA9hBzB,eA8hByB,CA9hBT,CA8hBS,CAAA,CAAA;IAWzB;;;;;IAWW,KAAA,EAAA,CAAA,IAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAziBe,MAyiBf,EAAA,GAziBwB,OAyiBxB,CAAA,MAAA,CAAA;IAMuB;IAAR,KAAA,EAAA;MAMgB,EAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EA7iBvB,WA6iBuB,EAAA,GA7iBT,MA6iBS;MAAR,EAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EAxiBf,WAwiBe,EAAA,GAxiBD,MAwiBC;MAQC,EAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EA3iBhB,WA2iBgB,EAAA,GA3iBF,MA2iBE;MAGH,GAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EAziBZ,WAyiBY,EAAA,GAziBE,MAyiBF;MAAR,EAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EApiBL,WAoiBK,EAAA,GApiBS,MAoiBT;MAEE,GAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EAjiBN,WAiiBM,EAAA,GAjiBQ,MAiiBR;MAGM,EAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EA/hBZ,WA+hBY,EAAA,EAAA,GA/hBI,MA+hBJ;MASL,KAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAniBJ,WAmiBI,EAAA,EAAA,GAniBY,MAmiBZ;MAOf,IAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,EAAA,GAriBoB,MAqiBpB;MAAsB,KAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,EAAA,GAhiBD,MAgiBC;MAAR,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,GA3hBT,MA2hBS;MAEJ,SAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,GA5hBF,MA4hBE;MAAR,GAAA,EAAA,CAAA,GAAA,OAAA,EA3hBL,MA2hBK,EAAA,EAAA,GA3hBM,MA2hBN;MAES,EAAA,EAAA,CAAA,GAAA,OAAA,EA5hBf,MA4hBe,EAAA,EAAA,GA5hBJ,MA4hBI;MAAsB,GAAA,EAAA,CAAA,MAAA,EA3hBxC,MA2hBwC,EAAA,GA3hB/B,MA2hB+B;IAAR,CAAA;EAEpB,CAAA;EAGY;EAAR,OAAA,EAAA;IAEE,OAAA,EAAA,CAAA,MAAA,EAAA;MAAR,MAAA,EAAA,MAAA;MAEC,QAAA,EAAA,MAAA;MAGyB,QAAA,EAAA,MAAA;MAAR,SAAA,EAAA,MAAA;MAiCjC,aAAA,CAAA,EAAA,MAAA;IACA,CAAA,EAAA,GA7jBP,OA6jBO,CA7jBC,WA6jBD,CAAA;IAAR;;;;IAuBQ,MAAA,EAAA,CAAA,MAAA,EAAA;MAAR,MAAA,EAAA,MAAA;MAgBM,IAAA,EArlBD,IAqlBC,GArlBM,IAqlBN;MACE,QAAA,CAAA,EAAA,MAAA;MAAR,aAAA,CAAA,EAAA,MAAA;IAiBQ,CAAA,EAAA,GApmBP,OAomBO,CApmBC,UAomBD,CAAA;IAAR;;;;;;IAwD2E,IAAA,EAAA,CAAA,MAAA,CAAA,EAAA,MAAA,EAAA,GAvnB/C,OAunB+C,CAvnBvC,iBAunBuC,CAAA;IAAzB;;;;;IAaE,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,GA1nBtB,OA0nBsB,CAAA,IAAA,CAAA;IAAR;;;;;;;;IAcb,QAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,GA7nBC,OA6nBD,CA7nBS,IA6nBT,CAAA;EAAuB,CAAA;EAAR;EAErB,IAAA,EAAA;IAOE;;;;;;;;IAe3B,WAAA,EAAA,CAAA,OAAA,EAznBQ,UAynBR,EAAA,EAAA,GAxnBA,OAwnBA,CAxnBQ,iBAwnBR,CAAA;IAWqB;;;;;;;IA4BrB,WAAA,EAAA,CAAA,KAAA,EAlpBM,iBAkpBN,EAAA,GAjpBA,OAipBA,CAjpBQ,iBAipBR,CAAA;EAM+B,CAAA;EAAR;EAE8B,IAAA,EAAA;IAAR,QAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,QAAA,EA9oBpC,YA8oBoC,EAAA,QAAA,CAAA,EAAA,MAAA,EAAA,GA5oB7C,OA4oB6C,CA5oBrC,SA4oBqC,CAAA;IAQrC,UAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GA7oBwB,OA6oBxB,CAAA,IAAA,CAAA;IAAR,SAAA,EAAA,GAAA,GA1oBkB,OA0oBlB,CA1oB0B,SA0oB1B,EAAA,CAAA;IASqC,SAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GAhpBN,OAgpBM,CAAA,IAAA,CAAA;IAAR,WAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GA7oBI,OA6oBJ,CAAA,IAAA,CAAA;EAET,CAAA;EAAyB;EAAR,YAAA,EAAA;IAMX,IAAA,EAAA,GAAA,GA9oBb,OA8oBa,CA9oBL,eA8oBK,EAAA,CAAA;IAAR,GAAA,EAAA,CAAA,IAAA,EAAA,MAAA,EAAA,GA3oBM,OA2oBN,CAAA,OAAA,CAAA;EAEuB,CAAA;EAAR;EAIR,EAAA,EAAA;IAAR,SAAA,EAAA;MAEQ,QAAA,EAAA;QAAR,MAAA,EAAA,CAAA,OAAA,EAzoBL,gBAyoBK,EAAA,GAxoBb,OAwoBa,CAxoBL,iBAwoBK,CAAA;MAAO,CAAA;IAOf,CAAA;EAYH,CAAA;;;;;;;;;;;;;;;;;;;;;;;;kEAxnBG,kBACT,QAAQ;;;;iBAiFM,QAAQ;;;;iBAOR,QAAQ;;;;;;0BAQC,QAAQ;;;;;;;;;;;;;;;;;;gBAqBlB,QAAQ;;;;kBASN,QAAQ;uBAEH,QAAQ;;;;qBAMV,QAAQ;yBAEJ,QAAQ;iCAEA,QAAQ;2BAEd,QAAQ;;;;sBAMb,QAAQ;8CAI3B,QAAQ;;;;oBAQS,QAAQ;6BAEC,QAAQ;wBAEX,oBAAkB,QAAQ;uBAI3B,mBAAiB,QAAQ;;;;0BAQxB,QAAQ;iDAK/B,QAAQ;gCAKqB,QAAQ;;;;;;;;;;;;cAc1B,QAAQ;;;;;;;kBASJ,QAAQ;;;;gBAOV,QAAQ;8CAEsB,QAAQ;gFAQnD,QAAQ;;;;sBAcW,QAAQ;oCAEM,QAAQ;iCAIX,QAAQ;;;;kBAMvB,QAAQ;oCAEU,QAAQ;;;;qDAWzC,QAAQ;;;;mBASQ,QAAQ;sBAEL,QAAQ;;;;;qCAMO,QAAQ;;;;;6CAMA,QAAQ;;;;;8CAQP;mCAGX,QAAQ;qCAEN;2CAGM;;;;;;;sCASL;;;;qBAOf,gBAAc,QAAQ;yBAEpB,QAAQ;gCAEC,gBAAc,QAAQ;4BAE5B;gCAGI,QAAQ;0BAEd,QAAQ;2BAEP;4CAGiB,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kCAiCzC,8BACR,QAAQ;;;;;;yBAUc,QAAQ;;;;;;;;mDAYtB,uBACR,QAAQ;;;;;;kDAgBF,wBACN,QAAQ;;;;;;;;+DAiBR,QAAQ;;;;;;;;;;;;gEAqBR,QAAQ;;;;;;0CAW+B,QAAQ;;;;;;;;;;;;;;;;;;;;uBAwBlC,oCAAqC,yBAAyB;;;;0BASlD,kBAAgB,QAAQ;6BAIrB,kBAAgB,QAAQ;qCAIlB,QAAQ;;;;oDAMO,QAAQ;qBAErC,iBAAe,QAAQ;gCAEZ,iBAAe,QAAQ;4BAE7B;;;;sBAON,QAAQ;2CAEa;;;;2BAMhB,QAAQ;qCAEE,QAAQ;iDAK1C,QAAQ;;;;gBAWK,QAAQ;;;;;yBAMC,QAAQ;;;;;;;;;iCAWW,QAAQ;;;;;;;;;;UAWjD,QAAQ;0BAMe,QAAQ;gDAEc,QAAQ;oDAQrD,QAAQ;;;;gCASqB,QAAQ;qBAEjB,mBAAiB,QAAQ;;;;qBAM3B,QAAQ;oCAEO,QAAQ;oBAIxB,QAAQ;oBAER,QAAQ;;;;iBAOhB,WAAA,CAAA,GAAe;;;;;;;;;cAYlB,WAAA"}
|
package/dist/index.js
CHANGED
|
@@ -259,6 +259,14 @@ var ConversationSubscription = class {
|
|
|
259
259
|
//#region src/index.ts
|
|
260
260
|
const DEFAULT_API_URL = "https://api.amba.dev";
|
|
261
261
|
/**
|
|
262
|
+
* Default host that serves deployed functions. `Amba.functions.invoke(name)`
|
|
263
|
+
* targets `https://<projectId>.<DEFAULT_FUNCTIONS_HOST>/<name>` unless a
|
|
264
|
+
* `functionsBaseUrl` override is configured. The `<projectId>` label is the
|
|
265
|
+
* server-resolved id (from `diagnostics.ping`), which the function router
|
|
266
|
+
* accepts directly.
|
|
267
|
+
*/
|
|
268
|
+
const DEFAULT_FUNCTIONS_HOST = "fn.amba.host";
|
|
269
|
+
/**
|
|
262
270
|
* Internal state — one instance per page. Created lazily by `Amba.configure()`.
|
|
263
271
|
*/
|
|
264
272
|
let coreInstance = null;
|
|
@@ -279,6 +287,15 @@ let _configuredProjectId = null;
|
|
|
279
287
|
let _configuredApiUrl = DEFAULT_API_URL;
|
|
280
288
|
let _configuredClientKey = null;
|
|
281
289
|
let _currentSessionToken = null;
|
|
290
|
+
/**
|
|
291
|
+
* Functions invocation state. `_configuredFunctionsBaseUrl` is the optional
|
|
292
|
+
* override from `Amba.configure({ functionsBaseUrl })`. When it's null, the
|
|
293
|
+
* default-host path resolves the project id once via `diagnostics.ping` and
|
|
294
|
+
* caches it in `_resolvedFunctionsProjectId` so subsequent invokes skip the
|
|
295
|
+
* round-trip. Both reset on every `configure()`.
|
|
296
|
+
*/
|
|
297
|
+
let _configuredFunctionsBaseUrl = null;
|
|
298
|
+
let _resolvedFunctionsProjectId = null;
|
|
282
299
|
function requireCore() {
|
|
283
300
|
if (!coreInstance) throw new AmbaApiError("NOT_INITIALIZED", "amba SDK not configured. Call Amba.configure({ projectId, clientKey }) at app start before any other API.");
|
|
284
301
|
return coreInstance;
|
|
@@ -332,6 +349,24 @@ function realtimeAuthHeaders() {
|
|
|
332
349
|
};
|
|
333
350
|
}
|
|
334
351
|
/**
|
|
352
|
+
* Resolve the full invocation URL for a deployed function.
|
|
353
|
+
*
|
|
354
|
+
* With `functionsBaseUrl` configured we POST to `<base>/<name>` verbatim
|
|
355
|
+
* (custom domains / non-prod). Otherwise we resolve the server-side project
|
|
356
|
+
* id once (via `diagnostics.ping`, cached) and target
|
|
357
|
+
* `https://<projectId>.fn.amba.host/<name>` — the function router accepts the
|
|
358
|
+
* project id as the host label directly.
|
|
359
|
+
*/
|
|
360
|
+
async function resolveFunctionUrl(name) {
|
|
361
|
+
if (_configuredFunctionsBaseUrl) return `${_configuredFunctionsBaseUrl.replace(/\/$/, "")}/${encodeURIComponent(name)}`;
|
|
362
|
+
if (!_resolvedFunctionsProjectId) {
|
|
363
|
+
const ping = await Amba.diagnostics.ping();
|
|
364
|
+
if (!ping.ok || !ping.server_project_id) throw new AmbaApiError("FUNCTIONS_HOST_UNRESOLVED", "Could not resolve the functions host for this project. Pass `functionsBaseUrl` to Amba.configure() to invoke functions explicitly.", ping);
|
|
365
|
+
_resolvedFunctionsProjectId = ping.server_project_id;
|
|
366
|
+
}
|
|
367
|
+
return `https://${_resolvedFunctionsProjectId}.${DEFAULT_FUNCTIONS_HOST}/${encodeURIComponent(name)}`;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
335
370
|
* Top-level SDK namespace.
|
|
336
371
|
*
|
|
337
372
|
* Stateless from the JS side — all state lives in the SDK runtime. Calling
|
|
@@ -370,6 +405,8 @@ const Amba = {
|
|
|
370
405
|
_configuredProjectId = config.projectId;
|
|
371
406
|
_configuredApiUrl = config.apiUrl ?? DEFAULT_API_URL;
|
|
372
407
|
_configuredClientKey = config.clientKey;
|
|
408
|
+
_configuredFunctionsBaseUrl = config.functionsBaseUrl ?? null;
|
|
409
|
+
_resolvedFunctionsProjectId = null;
|
|
373
410
|
},
|
|
374
411
|
get projectId() {
|
|
375
412
|
if (!_configuredProjectId) throw new AmbaApiError("NOT_INITIALIZED", "amba SDK not configured. Call Amba.configure({ projectId, clientKey }) at app start before any other API.");
|
|
@@ -451,6 +488,9 @@ const Amba = {
|
|
|
451
488
|
linkEmailOtp: async (email, code) => {
|
|
452
489
|
return await coreCall((c) => c.linkEmailOtp(email, code));
|
|
453
490
|
},
|
|
491
|
+
linkEmailPassword: async (email, password) => {
|
|
492
|
+
return await coreCall((c) => c.linkEmailPassword(email, password));
|
|
493
|
+
},
|
|
454
494
|
unlinkSmsOtp: async () => {
|
|
455
495
|
return await coreCall((c) => c.unlinkSmsOtp());
|
|
456
496
|
},
|
|
@@ -673,6 +713,45 @@ const Amba = {
|
|
|
673
713
|
ai: { anthropic: { messages: { create: async (request) => {
|
|
674
714
|
return await coreCall((c) => c.aiAnthropicMessages(encodeJson(request)));
|
|
675
715
|
} } } },
|
|
716
|
+
functions: { invoke: async (name, body, options) => {
|
|
717
|
+
requireCore();
|
|
718
|
+
if (!_configuredClientKey) throw new AmbaApiError("NOT_INITIALIZED", "amba SDK not configured. Call Amba.configure({ projectId, clientKey }) before Amba.functions.invoke().");
|
|
719
|
+
if (!name || name.trim() === "") throw new AmbaApiError("INVALID_ARGUMENT", "Amba.functions.invoke: a function name is required.");
|
|
720
|
+
const url = await resolveFunctionUrl(name);
|
|
721
|
+
const method = options?.method ?? "POST";
|
|
722
|
+
const headers = {
|
|
723
|
+
"X-Api-Key": _configuredClientKey,
|
|
724
|
+
...options?.headers ?? {}
|
|
725
|
+
};
|
|
726
|
+
if (_currentSessionToken) headers["Authorization"] = `Bearer ${_currentSessionToken}`;
|
|
727
|
+
let requestBody;
|
|
728
|
+
if (body !== void 0 && method !== "GET") {
|
|
729
|
+
headers["content-type"] = "application/json";
|
|
730
|
+
requestBody = JSON.stringify(body);
|
|
731
|
+
}
|
|
732
|
+
let resp;
|
|
733
|
+
try {
|
|
734
|
+
resp = await fetch(url, {
|
|
735
|
+
method,
|
|
736
|
+
headers,
|
|
737
|
+
body: requestBody
|
|
738
|
+
});
|
|
739
|
+
} catch (err) {
|
|
740
|
+
throw new AmbaApiError("NETWORK_ERROR", `Amba.functions.invoke("${name}") network error: ${String(err)}`);
|
|
741
|
+
}
|
|
742
|
+
const text = await resp.text();
|
|
743
|
+
let parsed = void 0;
|
|
744
|
+
if (text.length > 0) try {
|
|
745
|
+
parsed = JSON.parse(text);
|
|
746
|
+
} catch {
|
|
747
|
+
parsed = text;
|
|
748
|
+
}
|
|
749
|
+
if (!resp.ok) {
|
|
750
|
+
const envelope = parsed && typeof parsed === "object" ? parsed : void 0;
|
|
751
|
+
throw new AmbaApiError(typeof envelope?.error?.code === "string" ? envelope.error.code : `HTTP_${resp.status}`, typeof envelope?.error?.message === "string" ? envelope.error.message : typeof parsed === "string" && parsed.length > 0 ? parsed : `Amba.functions.invoke("${name}") failed with status ${resp.status}`, parsed);
|
|
752
|
+
}
|
|
753
|
+
return parsed;
|
|
754
|
+
} },
|
|
676
755
|
config: { fetch: async () => {
|
|
677
756
|
return await coreCall((c) => c.configFetch());
|
|
678
757
|
} },
|
|
@@ -842,7 +921,7 @@ function getCoreWasm() {
|
|
|
842
921
|
* `verify-sdk-version-coherence` GH action gates every publish on the
|
|
843
922
|
* pair agreeing (and matching the `web-v<X.Y.Z>` tag when tag-triggered).
|
|
844
923
|
*/
|
|
845
|
-
const SDK_VERSION = "4.0.
|
|
924
|
+
const SDK_VERSION = "4.0.4";
|
|
846
925
|
|
|
847
926
|
//#endregion
|
|
848
927
|
export { Amba, AmbaApiError, CollectionSubscription, ConversationSubscription, SDK_VERSION, getCoreWasm };
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["prefix: string","ctx: RealtimeContext","name: string","controller: AbortController | null","idx: number","dataLines: string[]","conversationId: string","coreInstance: AmbaCoreWasm | null","_configuredProjectId: string | null","_configuredApiUrl: string","_configuredClientKey: string | null","_currentSessionToken: string | null","wasmJsUrl: string","uploadHeaders: Record<string, string>"],"sources":["../src/storage-adapter.ts","../src/json.ts","../src/error.ts","../src/realtime.ts","../src/index.ts"],"sourcesContent":["/**\n * Browser localStorage adapter for SDK identity persistence.\n *\n * The SDK runtime currently re-seeds an `anonymous_id` on every page load.\n * This adapter is the documented home for storage-prefix handling so\n * customers can override the localStorage key prefix used by the\n * (eventual) identity cache.\n */\nexport class LocalStoragePersistence {\n constructor(private readonly prefix: string) {}\n\n /** Read everything we'd want to hydrate at init. No-op until wired through. */\n hydrate(): void {\n // Reserved for v0.2 — the SDK runtime will gain a persistence bridge\n // that calls into JS for read/write/list/delete.\n }\n\n read(key: string): string | null {\n if (typeof localStorage === \"undefined\") return null;\n return localStorage.getItem(`${this.prefix}:${key}`);\n }\n\n write(key: string, value: string): void {\n if (typeof localStorage === \"undefined\") return;\n localStorage.setItem(`${this.prefix}:${key}`, value);\n }\n\n delete(key: string): void {\n if (typeof localStorage === \"undefined\") return;\n localStorage.removeItem(`${this.prefix}:${key}`);\n }\n}\n","/**\n * JSON encode helper — guarantees stable serialization across browser\n * runtimes and provides a single hook for future schema validation.\n */\nexport function encodeJson(value: unknown): string {\n return JSON.stringify(value);\n}\n","/**\n * Typed error class for the amba SDK + helper that converts arbitrary\n * thrown values (native Error, plain objects, runtime-emitted errors)\n * into a stable `AmbaApiError` instance.\n *\n * Callers can `instanceof`-narrow safely, branch on `.code`, and pull\n * extra payload from `.details` (raw HTTP body, validation field paths,\n * etc.). The wrapper methods on `Amba` wrap every async call in\n * `toAmbaApiError`, so consumers see one error shape regardless of\n * which layer (network, runtime, validation) failed.\n */\n\n/**\n * Stable error codes surfaced by the SDK. Strings rather than an enum\n * so customers can extend with custom codes by simply throwing\n * `new AmbaApiError(\"MY_CODE\", \"...\")` without coordinating with this\n * package's TypeScript types.\n */\nexport type AmbaApiErrorCode =\n | \"UNAUTHORIZED\"\n | \"FORBIDDEN\"\n | \"NOT_FOUND\"\n | \"CONFLICT\"\n | \"RATE_LIMITED\"\n | \"VALIDATION_ERROR\"\n | \"NETWORK_ERROR\"\n | \"HTTP_ERROR\"\n | \"CIRCUIT_OPEN\"\n | \"CONSENT_NOT_GRANTED\"\n | \"NOT_INITIALIZED\"\n | \"INVALID_CONFIG\"\n | \"INVALID_ARGUMENT\"\n | \"PUSH_PERMISSION_DENIED\"\n | \"PUSH_REGISTRATION_FAILED\"\n | \"NOT_SANDBOX_TIER\"\n | \"UNKNOWN_ERROR\"\n | (string & {});\n\nexport class AmbaApiError extends Error {\n readonly code: AmbaApiErrorCode;\n readonly details?: unknown;\n constructor(\n code: AmbaApiErrorCode,\n message: string,\n details?: unknown,\n ) {\n super(message);\n this.name = \"AmbaApiError\";\n this.code = code;\n this.details = details;\n // Restore prototype chain when transpiled to ES5 targets — Error\n // subclasses lose their prototype otherwise and `instanceof` breaks.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Best-effort: pull a stable error code out of a Rust `AmbaError`\n * Display string. Used by `toAmbaApiError` when the underlying thrown\n * value is a generic `Error` produced by `wasm-bindgen`'s `JsError::new`.\n *\n * Keep in sync with `sdks/core/src/error.rs::AmbaError`'s `#[error]`\n * format strings — but the parser falls back to UNKNOWN_ERROR for any\n * pattern it doesn't recognize, so a stale match list isn't a footgun,\n * just a quality-of-life regression.\n */\nfunction codeFromMessage(message: string): AmbaApiErrorCode {\n // Cheapest checks first — most production errors are auth or HTTP.\n if (message.startsWith(\"Unauthorized\")) return \"UNAUTHORIZED\";\n if (message.startsWith(\"Forbidden\")) return \"FORBIDDEN\";\n if (message.startsWith(\"Not found\")) return \"NOT_FOUND\";\n if (message.startsWith(\"Conflict\")) return \"CONFLICT\";\n if (message.startsWith(\"Rate limited\")) return \"RATE_LIMITED\";\n if (message.startsWith(\"Validation error\")) return \"VALIDATION_ERROR\";\n if (message.startsWith(\"Network error\")) return \"NETWORK_ERROR\";\n if (message.startsWith(\"HTTP error\")) return \"HTTP_ERROR\";\n if (message.startsWith(\"Circuit breaker\")) return \"CIRCUIT_OPEN\";\n if (message.startsWith(\"Consent not granted\")) return \"CONSENT_NOT_GRANTED\";\n if (message.includes(\"not initialized\")) return \"NOT_INITIALIZED\";\n if (message.startsWith(\"Invalid configuration\")) return \"INVALID_CONFIG\";\n if (message.startsWith(\"Invalid argument\")) return \"INVALID_ARGUMENT\";\n return \"UNKNOWN_ERROR\";\n}\n\n/**\n * Coerce any thrown value into an `AmbaApiError`. Idempotent — passing\n * an existing `AmbaApiError` returns it unchanged so wrappers can stack\n * without re-wrapping.\n *\n * Heuristics:\n * 1. Existing `AmbaApiError` → returned as-is.\n * 2. Object with `.code` → use that code + `.message` + `.details`.\n * 3. `Error` (e.g. runtime-emitted error) → infer code from message prefix.\n * 4. Anything else → stringify and tag UNKNOWN_ERROR.\n */\nexport function toAmbaApiError(err: unknown): AmbaApiError {\n if (err instanceof AmbaApiError) return err;\n if (err && typeof err === \"object\") {\n const obj = err as { code?: unknown; message?: unknown; details?: unknown };\n if (typeof obj.code === \"string\") {\n return new AmbaApiError(\n obj.code,\n typeof obj.message === \"string\" ? obj.message : \"unknown\",\n obj.details,\n );\n }\n }\n if (err instanceof Error) {\n return new AmbaApiError(codeFromMessage(err.message), err.message);\n }\n return new AmbaApiError(\"UNKNOWN_ERROR\", String(err));\n}\n\n/**\n * Wrap a thunk so any thrown value becomes an `AmbaApiError`. The\n * wrapper methods on `Amba` use this to convert runtime-emitted errors\n * uniformly at the SDK boundary.\n */\nexport async function withAmbaError<T>(thunk: () => Promise<T>): Promise<T> {\n try {\n return await thunk();\n } catch (err) {\n throw toAmbaApiError(err);\n }\n}\n","/**\n * Live collection subscriptions for `@layers/amba-web` (PROTOTYPE — T13).\n *\n * Public surface is intentionally tiny and provider-agnostic:\n *\n * const unsub = Amba.collection(\"messages\")\n * .where(\"circle_id\", circleId)\n * .subscribe((change) => {\n * // change.op is \"INSERT\" | \"UPDATE\" | \"DELETE\"\n * // change.row is the affected row\n * });\n * unsub(); // stop listening\n *\n * The transport (a streamed HTTP response) and the server-side fan-out\n * mechanism are deliberately NOT named here — customers only ever see\n * `.subscribe()`. Internally this opens a long-lived streamed GET to the\n * realtime endpoint and reconnects with backoff if the connection drops.\n *\n * Delivery mirrors `Amba.collection.find()` exactly: you receive only rows\n * your session owns, optionally narrowed by `.where(...)` equality filters.\n */\n\nexport type RowChangeOp = \"INSERT\" | \"UPDATE\" | \"DELETE\";\n\nexport interface RealtimeChange<T = unknown> {\n /** Which kind of write happened. */\n op: RowChangeOp;\n /**\n * The affected row. For deletes this is a partial row (at minimum `id`).\n * If the row was too large to deliver inline, `truncated` is `true` and\n * `row` carries just `id` — re-fetch with `Amba.collection.find()` /\n * `findOne()` when you need the full body.\n */\n row: T;\n truncated?: boolean;\n}\n\nexport interface SubscribeOptions {\n /** Called once when the live connection is (re)established. */\n onOpen?: () => void;\n /** Called on a connection error before the SDK retries. */\n onError?: (err: unknown) => void;\n}\n\n/** Unsubscribe handle returned by `.subscribe(...)`. Call it to stop. */\nexport type Unsubscribe = () => void;\n\n/**\n * Resolved at call time so the latest session token is used. Returns the\n * auth headers, or `null` when there's no live session (subscribe throws).\n */\nexport interface RealtimeContext {\n baseUrl: string;\n authHeaders: () => Record<string, string> | null;\n}\n\nconst INITIAL_BACKOFF_MS = 500;\nconst MAX_BACKOFF_MS = 15_000;\n\n/**\n * Builder returned by `Amba.collection(name)`. Chain `.where(...)` to\n * narrow, then `.subscribe(cb)` to start streaming.\n */\nexport class CollectionSubscription<T = unknown> {\n private readonly filters: Record<string, unknown> = {};\n\n constructor(\n private readonly ctx: RealtimeContext,\n private readonly name: string,\n ) {}\n\n /** Add an equality filter. Chainable. All filters must match (AND). */\n where(column: string, value: unknown): this {\n this.filters[column] = value;\n return this;\n }\n\n /**\n * Start listening. `cb` fires once per matching row change. Returns an\n * unsubscribe handle — call it to close the connection.\n */\n subscribe(cb: (change: RealtimeChange<T>) => void, options: SubscribeOptions = {}): Unsubscribe {\n const headers = this.ctx.authHeaders();\n if (!headers) {\n throw new Error(\n \"Amba.collection().subscribe() requires an authenticated session — call Amba.auth.signIn*/verify* first.\",\n );\n }\n const qs =\n Object.keys(this.filters).length > 0\n ? `?where=${encodeURIComponent(JSON.stringify(this.filters))}`\n : \"\";\n const url = `${this.ctx.baseUrl}/v1/client/realtime/collections/${encodeURIComponent(\n this.name,\n )}${qs}`;\n return openStream<T>({\n url,\n authHeaders: this.ctx.authHeaders,\n onChange: cb,\n options,\n });\n }\n}\n\n/**\n * Inputs to a single realtime stream. The collection and conversation paths\n * differ only in how `url` is built; everything downstream (transport, frame\n * parsing, backoff/reconnect) is identical, so they share one implementation.\n */\ninterface StreamArgs<T> {\n url: string;\n authHeaders: () => Record<string, string> | null;\n onChange: (change: RealtimeChange<T>) => void;\n options: SubscribeOptions;\n}\n\n/**\n * Open a streamed GET to a realtime endpoint and dispatch row-change events\n * to `onChange`. Reconnects with exponential backoff until the returned\n * unsubscribe handle is invoked. Shared by both collection and conversation\n * subscriptions — the only thing that differs between them is the URL.\n *\n * Uses `fetch` + a streamed response body (rather than the browser's\n * native `EventSource`) because `EventSource` cannot set request headers —\n * which would force the session token into the URL query string, where it\n * would leak into access logs. Streaming `fetch` keeps auth in headers.\n */\nfunction openStream<T>(args: StreamArgs<T>): Unsubscribe {\n let stopped = false;\n let controller: AbortController | null = null;\n let backoff = INITIAL_BACKOFF_MS;\n\n const run = async (): Promise<void> => {\n while (!stopped) {\n controller = new AbortController();\n try {\n const headers = args.authHeaders();\n if (!headers) throw new Error(\"no active session\");\n const resp = await fetch(args.url, {\n method: \"GET\",\n headers: { ...headers, Accept: \"text/event-stream\" },\n signal: controller.signal,\n });\n if (!resp.ok || !resp.body) {\n throw new Error(`realtime connect failed: HTTP ${resp.status}`);\n }\n // Reset backoff only once the connection proves HEALTHY (first\n // frame received), not merely on a successful connect. A server\n // that accepts the connection then drops it immediately would\n // otherwise reset backoff every loop → a tight reconnect storm\n // with no exponential growth.\n await consume(resp.body, args, () => {\n backoff = INITIAL_BACKOFF_MS;\n args.options.onOpen?.();\n });\n } catch (err) {\n if (stopped) break;\n args.options.onError?.(err);\n }\n if (stopped) break;\n await delay(backoff);\n backoff = Math.min(backoff * 2, MAX_BACKOFF_MS);\n }\n };\n\n void run();\n\n return () => {\n stopped = true;\n controller?.abort();\n };\n}\n\nasync function consume<T>(\n body: ReadableStream<Uint8Array>,\n args: StreamArgs<T>,\n onFirstFrame: () => void,\n): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let sawFrame = false;\n for (;;) {\n const { done, value } = await reader.read();\n if (done) return;\n buffer += decoder.decode(value, { stream: true });\n let idx: number;\n while ((idx = buffer.indexOf(\"\\n\\n\")) !== -1) {\n const frame = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 2);\n if (!sawFrame) {\n sawFrame = true;\n onFirstFrame();\n }\n dispatchFrame<T>(frame, args.onChange);\n }\n }\n}\n\nfunction dispatchFrame<T>(frame: string, onChange: (change: RealtimeChange<T>) => void): void {\n let event = \"\";\n const dataLines: string[] = [];\n for (const line of frame.split(\"\\n\")) {\n if (line.startsWith(\":\")) continue; // keepalive comment\n if (line.startsWith(\"event:\")) event = line.slice(\"event:\".length).trim();\n else if (line.startsWith(\"data:\")) dataLines.push(line.slice(\"data:\".length).trim());\n }\n if (event !== \"change\") return; // ignore ready / error / heartbeat\n try {\n const payload = JSON.parse(dataLines.join(\"\\n\")) as {\n op: RowChangeOp;\n row: T;\n truncated?: boolean;\n };\n onChange({ op: payload.op, row: payload.row, truncated: payload.truncated });\n } catch {\n // malformed frame — skip rather than tear down the stream\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ── Messaging: live conversation subscriptions ─────────────────────────────\n\n/**\n * A live message change in a conversation. `op` is \"INSERT\" for a new\n * message; moderation removals arrive as \"DELETE\". For a delete (or when a\n * message was too large to deliver inline) `row` may be partial — re-fetch\n * with `Amba.messaging.listMessages(conversationId)` when you need the full\n * body.\n */\nexport type MessageChange<T = unknown> = RealtimeChange<T>;\n\n/**\n * Builder returned by `Amba.messaging.conversation(id)`. Call `.subscribe(cb)`\n * to receive new messages live instead of polling.\n *\n * const unsub = Amba.messaging\n * .conversation(conversationId)\n * .subscribe((change) => {\n * // change.op === \"INSERT\"; change.row is the new message\n * });\n * unsub(); // stop listening\n *\n * Delivery is scoped to conversation participants — you receive messages for\n * a conversation only if your session is a member of it. Reconnects with the\n * same exponential backoff as collection subscriptions.\n */\nexport class ConversationSubscription<T = unknown> {\n constructor(\n private readonly ctx: RealtimeContext,\n private readonly conversationId: string,\n ) {}\n\n subscribe(cb: (change: MessageChange<T>) => void, options: SubscribeOptions = {}): Unsubscribe {\n const headers = this.ctx.authHeaders();\n if (!headers) {\n throw new Error(\n \"Amba.messaging.conversation().subscribe() requires an authenticated session — call Amba.auth.signIn*/verify* first.\",\n );\n }\n const url = `${this.ctx.baseUrl}/v1/client/realtime/conversations/${encodeURIComponent(\n this.conversationId,\n )}`;\n return openStream<T>({\n url,\n authHeaders: this.ctx.authHeaders,\n onChange: cb,\n options,\n });\n }\n}\n","/**\n * @layers/amba-web — browser SDK for the amba platform.\n *\n * Exposes the full SDK 4.0 amba surface (34 modules) as idiomatic\n * TypeScript. All async operations return native Promises.\n *\n * @example\n * ```ts\n * import { Amba } from '@layers/amba-web';\n *\n * await Amba.configure({ projectId: 'proj_...', clientKey: 'amba_ck_...' });\n *\n * const session = await Amba.auth.signInAnonymously();\n * await Amba.events.track('app_opened', { source: 'deep_link' });\n *\n * const todos = await Amba.collections.find('todos', { limit: 20 });\n * await Amba.collections.insert('todos', { title: 'Buy milk' });\n * ```\n */\n\nimport init, { AmbaCoreWasm } from \"@layers/amba-core\";\n\nexport type * from \"./types\";\nimport type {\n AmbaConfig,\n AuthResult,\n User,\n FindOptions,\n FindResponse,\n Filter,\n FilterValue,\n ConfigBundle,\n FlagAssignment,\n PingResult,\n UserEntitlement,\n MediaAsset,\n MediaListResponse,\n PresignData,\n PushPlatform,\n PushToken,\n AiMessageRequest,\n AiMessageResponse,\n Achievement,\n AchievementProgress,\n Challenge,\n ChallengeProgress,\n CurrencyBalance,\n CurrencyTransaction,\n InventoryItem,\n PurchaseRequest,\n ConsumeRequest,\n Leaderboard,\n LeaderboardEntry,\n Store,\n PurchaseOption,\n PurchaseResult,\n XpBalance,\n XpTransaction,\n Streak,\n FeedResponse,\n Friendship,\n Group,\n GroupMember,\n GroupCreate,\n GroupUpdate,\n Conversation,\n Message,\n SendMessageRequest,\n CreateConversationRequest,\n ListMessagesOptions,\n MarkReadResult,\n ConversationParticipant,\n Report,\n ReportRequest,\n ReferralCode,\n ReferralClaim,\n Review,\n ReviewCreate,\n ReviewUpdate,\n Role,\n CatalogItem,\n ContentItem,\n DeepLink,\n DeepLinkCreate,\n OnboardingStatus,\n AppSession,\n SyncChange,\n PushChangesResult,\n PullChangesResult,\n PullChangesCursor,\n LeagueMembership,\n LeagueCohortView,\n NearestOptions,\n NearestResponse,\n LinkedIdentifier,\n} from \"./types\";\n\nimport { LocalStoragePersistence } from \"./storage-adapter\";\nimport { encodeJson } from \"./json\";\nimport { AmbaApiError, toAmbaApiError } from \"./error\";\nimport type { Session } from \"./types\";\nimport { CollectionSubscription, ConversationSubscription } from \"./realtime\";\n\nexport { AmbaApiError } from \"./error\";\nexport type { AmbaApiErrorCode } from \"./error\";\nexport { CollectionSubscription, ConversationSubscription } from \"./realtime\";\nexport type {\n RealtimeChange,\n MessageChange,\n RowChangeOp,\n SubscribeOptions,\n Unsubscribe,\n} from \"./realtime\";\n\nconst DEFAULT_API_URL = \"https://api.amba.dev\";\n\n/**\n * Internal state — one instance per page. Created lazily by `Amba.configure()`.\n */\nlet coreInstance: AmbaCoreWasm | null = null;\n\n/**\n * Stored at configure-time so `Amba.projectId` returns the configured\n * value without going through the engine. Cached only after the\n * core finishes initializing.\n */\nlet _configuredProjectId: string | null = null;\n\n/**\n * Realtime (`Amba.collection(name).subscribe`) needs the API base URL,\n * client key, and current session token in the TS layer to open the\n * streamed connection — the engine doesn't expose them back. We capture\n * the base URL + client key at configure-time and the session token from\n * every auth result (the engine rotates it internally on refresh; the\n * subscribe connection picks up the latest at connect time).\n */\nlet _configuredApiUrl: string = DEFAULT_API_URL;\nlet _configuredClientKey: string | null = null;\nlet _currentSessionToken: string | null = null;\n\nfunction requireCore(): AmbaCoreWasm {\n if (!coreInstance) {\n throw new AmbaApiError(\n \"NOT_INITIALIZED\",\n \"amba SDK not configured. Call Amba.configure({ projectId, clientKey }) at app start before any other API.\",\n );\n }\n return coreInstance;\n}\n\n/**\n * Run a single SDK-runtime call and rewrap any thrown value into a\n * stable `AmbaApiError`. Every method on `Amba` funnels through this\n * so callers see one error shape regardless of which layer failed\n * (network, validation, etc.). Sync `requireCore()` accessors\n * (e.g. the `anonymousId` getter) already throw the typed shape on\n * their own.\n */\nasync function coreCall<T>(fn: (c: AmbaCoreWasm) => Promise<T>): Promise<T> {\n try {\n return await fn(requireCore());\n } catch (err) {\n throw toAmbaApiError(err);\n }\n}\n\n/**\n * In-SDK auth-state pub/sub. `signIn*` / `signUp*` / `signOut` /\n * `refresh` call `notifyAuthSubscribers` after their underlying core\n * call resolves so subscribers always see a consistent `Session | null`\n * snapshot. Subscriber callbacks run synchronously inside the\n * notification path — keep them light; offload heavy work to your own\n * scheduler.\n */\ntype AuthSubscriber = (session: Session | null) => void;\nconst authSubscribers = new Set<AuthSubscriber>();\n\nfunction snapshotSession(user: User | null): Session | null {\n if (!user) return null;\n return {\n sessionToken: \"\",\n refreshToken: \"\",\n user,\n expiresAt: \"\",\n };\n}\n\nfunction notifyAuthSubscribers(session: Session | null): void {\n for (const cb of authSubscribers) {\n try {\n cb(session);\n } catch (err) {\n // Subscriber errors are isolated — one bad callback doesn't\n // block the rest. Surface in debug logs but don't rethrow into\n // the auth call path, which would mask the success result.\n if (typeof console !== \"undefined\") {\n console.error(\"[amba] onAuthStateChange callback threw\", err);\n }\n }\n }\n}\n\nasync function notifyFromAuthResult(result: AuthResult): Promise<void> {\n // Capture the session token for the realtime subscribe path (the engine\n // holds the canonical copy + auto-refreshes; this is the latest snapshot).\n if (result?.session_token) _currentSessionToken = result.session_token;\n notifyAuthSubscribers(snapshotSession(result.user));\n}\n\n/**\n * Build the auth headers for a realtime subscribe connection, or `null`\n * when there's no live session. Read lazily at connect-time so reconnects\n * pick up a rotated session token.\n */\nfunction realtimeAuthHeaders(): Record<string, string> | null {\n if (!_configuredClientKey || !_currentSessionToken) return null;\n return {\n \"X-Api-Key\": _configuredClientKey,\n Authorization: `Bearer ${_currentSessionToken}`,\n };\n}\n\n/**\n * Top-level SDK namespace.\n *\n * Stateless from the JS side — all state lives in the SDK runtime. Calling\n * `Amba.configure()` multiple times replaces the previous instance.\n */\nexport const Amba = {\n /**\n * Initialize the SDK. Must be called once at app start.\n *\n * Seeds an `anonymous_id` from localStorage (if present) or generates a\n * fresh one.\n */\n configure: async (config: AmbaConfig): Promise<void> => {\n if (!config.projectId || config.projectId.trim() === \"\") {\n throw new Error(\"Amba.configure: projectId is required\");\n }\n if (!config.clientKey || config.clientKey.trim() === \"\") {\n throw new Error(\"Amba.configure: clientKey is required\");\n }\n // wasm-pack --target web's auto-loader does `fetch(new URL(\"./amba_core_bg.wasm\", import.meta.url))`.\n // That resolves to a `file://` URL in Node, and Node's undici doesn't\n // support the `file:` scheme — throws `fetch failed: not implemented`.\n // In Node (server-rendering, Jest/Vitest under jsdom, customer-shoes\n // smoke), read the wasm via fs and pass the bytes to init() directly.\n // In browsers, default behavior fetches the wasm from the asset URL.\n const isNode =\n typeof process !== \"undefined\" &&\n !!(process.versions && process.versions.node);\n if (isNode) {\n const [\n { readFile },\n { fileURLToPath, pathToFileURL },\n { createRequire },\n ] = await Promise.all([\n import(\"node:fs/promises\"),\n import(\"node:url\"),\n import(\"node:module\"),\n ]);\n // Resolve the wasm path through @layers/amba-core's package\n // root so we follow the same module resolution as the .js glue\n // — works whether the consumer used a bundler or a raw `node`.\n //\n // Resolution strategy, in order:\n // 1. `import.meta.resolve` (Node ≥20.6, stable in 22). Async or sync\n // depending on Node version — both return a string when awaited.\n // 2. `require.resolve` via `createRequire(import.meta.url)`. Uses\n // Node's standard module resolution which honors pnpm's\n // `.pnpm/<pkg>@<ver>/node_modules/<pkg>` layout. The previous\n // `../node_modules/...` hard-coded fallback failed on pnpm.\n // This mirrors the Node SDK fix at `packages/node/src/index.ts:124`.\n const resolveFn = (\n import.meta as unknown as {\n resolve?: (s: string) => string | Promise<string>;\n }\n ).resolve;\n let wasmJsUrl: string;\n if (resolveFn) {\n wasmJsUrl = await resolveFn(\"@layers/amba-core/wasm\");\n } else {\n const req = createRequire(import.meta.url);\n // `require.resolve` returns a filesystem path; convert to a\n // file:// URL so `fileURLToPath` below works uniformly with the\n // `import.meta.resolve` branch.\n wasmJsUrl = pathToFileURL(\n req.resolve(\"@layers/amba-core/wasm\"),\n ).href;\n }\n const bytes = await readFile(fileURLToPath(wasmJsUrl));\n await init(bytes);\n } else {\n await init();\n }\n const persistence = new LocalStoragePersistence(\n config.storagePrefix ?? \"amba\",\n );\n persistence.hydrate(); // no-op for now; reserved for future identity-cache restoration\n\n // Wrap `AmbaCoreWasm.init`'s throw with `toAmbaApiError` so\n // configure() rejects with an `AmbaApiError` instance — same\n // contract as every method call. Without this, the engine's\n // post-#63 `JsValue` throws would surface to customers as plain\n // objects, breaking `e instanceof Error` checks in\n // configure-failure handlers. (Reported by Cursor BugBot on\n // PR #156, high.)\n try {\n coreInstance = AmbaCoreWasm.init(\n encodeJson({\n api_key: config.clientKey,\n base_url: config.apiUrl,\n project_id: config.projectId,\n sdk_platform: \"web\",\n sdk_wrapper_version: `amba-web/${SDK_VERSION}`,\n consent_required: config.consentRequired,\n debug: config.debug,\n }),\n globalThis.fetch.bind(globalThis),\n );\n } catch (err) {\n throw toAmbaApiError(err);\n }\n\n // Cache the projectId only after WASM init succeeds — leaving the\n // module in a half-initialized state would let `Amba.projectId`\n // return a value while every other method (which checks\n // `coreInstance` via `requireCore()`) correctly throws\n // `NOT_INITIALIZED`.\n _configuredProjectId = config.projectId;\n _configuredApiUrl = config.apiUrl ?? DEFAULT_API_URL;\n _configuredClientKey = config.clientKey;\n },\n\n /** Project id this SDK instance is scoped to. */\n get projectId(): string {\n if (!_configuredProjectId) {\n throw new AmbaApiError(\n \"NOT_INITIALIZED\",\n \"amba SDK not configured. Call Amba.configure({ projectId, clientKey }) at app start before any other API.\",\n );\n }\n return _configuredProjectId;\n },\n\n /** Anonymous id — stable per browser. */\n get anonymousId(): string {\n return requireCore().anonymousId();\n },\n\n /** Authenticated user id, if a session is live. */\n get appUserId(): string | undefined {\n return requireCore().appUserId() ?? undefined;\n },\n\n /** Whether a session token is currently held. */\n get isAuthenticated(): boolean {\n return requireCore().isAuthenticated();\n },\n\n /** Toggle verbose logging at runtime. */\n setDebug: (enabled: boolean): void => {\n requireCore().setDebug(enabled);\n },\n\n // ── Core 9 namespaces ─────────────────────────────────────────────\n\n /** Track engagement events. */\n events: {\n /**\n * Track an event.\n *\n * The default route writes to the engagement meter — events that\n * fan out to segments, workflows, and push. Pass\n * `{ telemetry: true }` for high-volume, fire-and-forget events\n * that DON'T need fan-out: UI button clicks, scroll-depth markers,\n * game-loop telemetry. Telemetry events are billed at $0.10 per 1M\n * overage vs $0.50 per 10K for engagement events — a ~500×\n * difference that mirrors the underlying compute cost.\n *\n * Telemetry events are persisted and queryable via analytics, but\n * skip segment recompute, streak qualification, currency grant\n * rules, and `last_seen_at` updates.\n *\n * @example\n * await Amba.events.track('purchase_completed', { amount: 9.99 });\n * await Amba.events.track('scroll_depth', { px: 1024 }, { telemetry: true });\n */\n track: async (\n event: string,\n properties?: Record<string, unknown>,\n options?: { telemetry?: boolean },\n ): Promise<void> => {\n await coreCall((c) => c.track(\n event,\n properties ? encodeJson(properties) : undefined,\n options?.telemetry,\n ));\n },\n },\n\n /** Authentication flows. */\n auth: {\n signInAnonymously: async (): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.signInAnonymously())) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n signInWithEmail: async (\n email: string,\n password: string,\n ): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.signInWithEmail(\n email,\n password,\n ))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n signUpWithEmail: async (\n email: string,\n password: string,\n ): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.signUpWithEmail(\n email,\n password,\n ))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n /**\n * Sign in with an Apple identity token (the JWT returned by Sign\n * in with Apple). Replaces the SDK 3.x polymorphic\n * `signInWithSocial('apple', token)` form — that surface is\n * removed in 4.0.\n */\n signInWithApple: async (identityToken: string): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.signInWithSocial(\n \"apple\",\n identityToken,\n ))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n /**\n * Sign in with a Google ID token (the JWT returned by Google\n * Sign-In). Replaces the SDK 3.x polymorphic\n * `signInWithSocial('google', token)` form — that surface is\n * removed in 4.0.\n */\n signInWithGoogle: async (idToken: string): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.signInWithSocial(\n \"google\",\n idToken,\n ))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n /**\n * Request a one-time passcode for `email`. The server emails a\n * 6-digit code; the user types it into the app, then call\n * `verifyEmailOtp(email, code)` to exchange for a session. Always\n * resolves successfully regardless of email registration — the\n * server uses uniform responses to prevent account enumeration.\n */\n requestEmailOtp: async (email: string): Promise<void> => {\n await coreCall((c) => c.requestEmailOtp(email));\n },\n /**\n * Exchange `(email, code)` for a session. Returns the same\n * `AuthResult` shape as `signInWithEmail` and persists tokens for\n * subsequent calls. Rejects with a single error code for every\n * failure mode (wrong/expired/exhausted) — the server intentionally\n * does not distinguish them to prevent enumeration.\n */\n verifyEmailOtp: async (email: string, code: string): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.verifyEmailOtp(email, code))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n /**\n * Request a one-time passcode by SMS. `phone` MUST be E.164\n * (starts with `+`, 8–15 total digits). The SDK rejects\n * anything else with a `VALIDATION_ERROR` before the network\n * call. Server sends a 6-digit code; user types it into the\n * app, then call `verifySmsOtp(phone, code)` to exchange for\n * a session. Always resolves successfully regardless of phone\n * registration — uniform responses prevent enumeration.\n */\n requestSmsOtp: async (phone: string): Promise<void> => {\n await coreCall((c) => c.requestSmsOtp(phone));\n },\n /**\n * Exchange `(phone, code)` for a session. Same shape +\n * failure semantics as `verifyEmailOtp`. Persists tokens for\n * subsequent calls.\n */\n verifySmsOtp: async (phone: string, code: string): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.verifySmsOtp(phone, code))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n /**\n * Request a magic-link email for `email`. The server emails the\n * link; the user clicks it, which delivers a one-time token back\n * to the app. Exchange that token for a session with\n * `verifyMagicLink(token)`. Always resolves successfully\n * regardless of email registration (uniform responses prevent\n * account enumeration).\n */\n requestMagicLink: async (email: string): Promise<void> => {\n await coreCall((c) => c.requestMagicLink(email));\n },\n /**\n * Exchange a magic-link `token` for a session. Returns the same\n * `AuthResult` shape as `signInWithEmail` and persists tokens for\n * subsequent calls.\n */\n verifyMagicLink: async (token: string): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.verifyMagicLink(token))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n /**\n * Link an additional auth provider to the current session — used to\n * upgrade an anonymous session to an identified one without losing\n * the user's data. `provider` is one of the supported identity\n * strings (e.g. `\"apple\"`, `\"google\"`); `credential` is the\n * provider-issued token (identity-token / id-token / OTP code).\n */\n linkAccount: async (\n provider: string,\n credential: string,\n ): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.linkAccount(\n provider,\n credential,\n ))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n\n /**\n * Attach a verified phone number to the **current session's user** —\n * without minting new tokens and without changing `user_id`.\n *\n * Flow: call `requestSmsOtp(phone)` first to mail the 6-digit code,\n * then call THIS instead of `verifySmsOtp` when the desired outcome\n * is \"decorate the current (often anonymous) user with this phone\"\n * rather than \"switch to the user who owns this phone\".\n *\n * Guarantees (symmetric to `linkEmailOtp`):\n *\n * - **Same `user_id`** before and after — collections, holds, XP,\n * `anonymous_id` all carry over.\n * - **Session token unchanged.** The existing token stays valid;\n * `onAuthStateChange` does NOT fire (no rotation).\n * - **Idempotent.** Re-linking the same phone to the same user\n * succeeds — no-op apart from `last_seen_at`.\n * - **Collision.** If the phone is already verified to a different\n * user, throws an error with `code = \"PHONE_ALREADY_LINKED\"` and\n * `details.conflicting_user_id` populated. The caller decides\n * whether to abort or switch identities via `verifySmsOtp`.\n *\n * Requires an active session — throws `UNAUTHORIZED` otherwise.\n *\n * @returns the updated user record (with `phone` set and\n * `phone_verified = true`).\n */\n linkSmsOtp: async (phone: string, code: string): Promise<User> => {\n return (await coreCall((c) => c.linkSmsOtp(phone, code))) as User;\n },\n\n /**\n * Attach a verified email to the current session's user. Symmetric\n * to `linkSmsOtp` — see that for the full guarantee list. Collision\n * code is `EMAIL_ALREADY_LINKED`.\n */\n linkEmailOtp: async (email: string, code: string): Promise<User> => {\n return (await coreCall((c) => c.linkEmailOtp(email, code))) as User;\n },\n\n /**\n * Detach the SMS-OTP identifier from the current session's user.\n * Refused with `LAST_IDENTIFIER` if this would leave the account\n * with no recoverable identifier (link another first, then unlink).\n * No token rotation.\n */\n unlinkSmsOtp: async (): Promise<User> => {\n return (await coreCall((c) => c.unlinkSmsOtp())) as User;\n },\n\n /** Detach the email-OTP identifier. Same guarantees as `unlinkSmsOtp`. */\n unlinkEmailOtp: async (): Promise<User> => {\n return (await coreCall((c) => c.unlinkEmailOtp())) as User;\n },\n\n /** Detach the Apple social identity from the current session's user. */\n unlinkApple: async (): Promise<User> => {\n return (await coreCall((c) => c.unlinkApple())) as User;\n },\n\n /** Detach the Google social identity from the current session's user. */\n unlinkGoogle: async (): Promise<User> => {\n return (await coreCall((c) => c.unlinkGoogle())) as User;\n },\n\n /**\n * Snapshot the identifier providers attached to the current\n * session's user. Lets a host app gate \"should I show the verify-\n * email prompt\" without a profile round-trip.\n *\n * Identifier values come back **masked** — raw values stay\n * server-side.\n */\n getCurrentIdentifiers: async (): Promise<LinkedIdentifier[]> => {\n return (await coreCall((c) => c.currentIdentifiers())) as LinkedIdentifier[];\n },\n signOut: async (rotateAnonymousId = false): Promise<void> => {\n await coreCall((c) => c.signOut(rotateAnonymousId));\n _currentSessionToken = null;\n notifyAuthSubscribers(null);\n },\n refresh: async (): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.refreshSession())) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n me: async (): Promise<User> => {\n return (await coreCall((c) => c.me())) as User;\n },\n\n /**\n * Snapshot the current session, or `null` if no session is live.\n * sessionToken/refreshToken/expiresAt come back as empty strings —\n * they're SDK-managed and not read-back-able from the core. Use\n * `Amba.isAuthenticated` if you only need the boolean.\n */\n getSession: async (): Promise<Session | null> => {\n const core = requireCore();\n if (!core.isAuthenticated()) return null;\n const user = (await coreCall((c) => c.me())) as User;\n return snapshotSession(user);\n },\n\n /**\n * Stable anonymous identifier (kept in memory by the SDK runtime).\n * Sync today, async for parity with the RN/native shape where the\n * platform may need to await a persistence read.\n */\n getAnonymousId: async (): Promise<string> => {\n return requireCore().anonymousId();\n },\n\n /**\n * Subscribe to session changes. Fires after every `signIn*`,\n * `signUp*`, `refresh`, and `signOut` call. Returns an\n * unsubscribe function — call it to remove the callback.\n *\n * Does NOT fire an initial snapshot when subscribed; call\n * `getSession()` once after subscribing if you need the\n * current state up front.\n */\n onAuthStateChange: (\n cb: (session: Session | null) => void,\n ): (() => void) => {\n authSubscribers.add(cb);\n return () => {\n authSubscribers.delete(cb);\n };\n },\n },\n\n /** Profile read/update (SDK 4.0). */\n users: {\n /**\n * Get a user profile. `userId` omitted → current user\n * (`GET /v1/client/users/me`); `userId` set → public-safe profile\n * of the other user (`GET /v1/client/users/{id}`).\n */\n get: async (userId?: string): Promise<User> => {\n return (await coreCall((c) => c.usersGet(\n userId ?? undefined,\n ))) as User;\n },\n /**\n * Update a profile. Two shapes:\n * - `update(patch)` — current user (`PATCH /users/me`).\n * - `update(userId, patch)` — admin-style cross-user update\n * (`PATCH /users/{id}`); the server requires the caller to\n * hold `users:write` and 403s otherwise.\n *\n * Allowed keys (both shapes): `display_name`, `avatar_url`,\n * `properties`, `timezone`.\n */\n update: (((\n arg1: string | Partial<User>,\n arg2?: Partial<User>,\n ): Promise<User> => {\n const isById = typeof arg1 === \"string\";\n const userId = isById ? (arg1 as string) : undefined;\n const patch = isById ? (arg2 ?? {}) : (arg1 as Partial<User>);\n return coreCall((c) => c.usersUpdate(\n userId ?? undefined,\n encodeJson(patch),\n )) as Promise<User>;\n }) as {\n (patch: Partial<User>): Promise<User>;\n (userId: string, patch: Partial<User>): Promise<User>;\n }),\n },\n\n /** List + revoke customer-recorded app sessions (SDK 4.0). */\n sessions: {\n /** `GET /v1/client/sessions` — list the caller's app sessions. */\n list: async (): Promise<AppSession[]> => {\n return (await coreCall((c) => c.sessionsList())) as AppSession[];\n },\n /**\n * `POST /v1/client/sessions/:id/end` — end the session with the\n * given id. The 4.0 `revoke` contract returns unit; customers who\n * need the ended row should use the lower-level `sessions.end`\n * helper on the core (not exposed on the public SDK).\n */\n revoke: async (sessionId: string): Promise<void> => {\n await coreCall((c) => c.sessionsRevoke(sessionId));\n },\n },\n\n /**\n * Live collection subscriptions (SDK 4.0). Returns a builder — chain\n * `.where(column, value)` to narrow, then `.subscribe(cb)` to start\n * receiving row changes. `subscribe` returns an unsubscribe handle.\n *\n * @example\n * const unsub = Amba.collection(\"messages\")\n * .where(\"circle_id\", circleId)\n * .subscribe((change) => {\n * // change.op: \"INSERT\" | \"UPDATE\" | \"DELETE\"; change.row: the row\n * });\n * // later: unsub();\n *\n * Delivery mirrors `Amba.collections.find()` — you only receive rows your\n * session owns. Requires an authenticated session.\n */\n collection: <T = unknown>(name: string): CollectionSubscription<T> =>\n new CollectionSubscription<T>(\n { baseUrl: _configuredApiUrl, authHeaders: realtimeAuthHeaders },\n name,\n ),\n\n /** Typed collection CRUD with auto-RLS. */\n collections: {\n find: async <T = unknown>(\n name: string,\n options: FindOptions = {},\n ): Promise<FindResponse<T>> => {\n return (await coreCall((c) => c.collectionsFind(\n name,\n encodeJson(options),\n ))) as FindResponse<T>;\n },\n findOne: async <T = unknown>(name: string, id: string): Promise<T> => {\n return (await coreCall((c) => c.collectionsFindOne(name, id))) as T;\n },\n insert: async <T = unknown>(\n name: string,\n row: Record<string, unknown>,\n ): Promise<T> => {\n return (await coreCall((c) => c.collectionsInsert(\n name,\n encodeJson(row),\n ))) as T;\n },\n update: async <T = unknown>(\n name: string,\n id: string,\n set: Record<string, unknown>,\n ): Promise<T> => {\n return (await coreCall((c) => c.collectionsUpdate(\n name,\n id,\n encodeJson(set),\n ))) as T;\n },\n delete: async (\n name: string,\n id: string,\n ): Promise<{ data: { deleted: boolean } }> => {\n return (await coreCall((c) => c.collectionsDelete(name, id))) as {\n data: { deleted: boolean };\n };\n },\n /**\n * Vector-search the collection (SDK 4.0). Returns the `k` nearest\n * neighbors of `options.query_vector` against the column named\n * `options.vector_field`. Distance metric and index strategy are\n * server-side; pass `options.filter` to narrow the candidate set\n * before ranking.\n *\n * Spec note: the canonical `findNearest(name, vector, k, filter?)`\n * shape omits the column name; the SDK widens the contract to a\n * single typed options object so `vector_field` is required and\n * unambiguous in TS.\n */\n findNearest: async <T = unknown>(\n name: string,\n options: NearestOptions,\n ): Promise<NearestResponse<T>> => {\n return (await coreCall((c) => c.collectionsFindNearest(\n name,\n encodeJson(options),\n ))) as NearestResponse<T>;\n },\n /**\n * Count rows in the collection (SDK 4.0). Pass an optional filter\n * to scope; omit it for the total. The server's response unwraps to\n * a bare number on the JS side.\n */\n count: async (name: string, filter?: Filter): Promise<number> => {\n return (await coreCall((c) => c.collectionsCount(\n name,\n filter ? encodeJson(filter) : undefined,\n ))) as number;\n },\n /** Filter DSL helpers — pass into `find({ filter: f })`. */\n where: {\n eq: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"eq\",\n value,\n }),\n ne: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"ne\",\n value,\n }),\n gt: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"gt\",\n value,\n }),\n gte: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"gte\",\n value,\n }),\n lt: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"lt\",\n value,\n }),\n lte: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"lte\",\n value,\n }),\n in: (column: string, values: FilterValue[]): Filter => ({\n column,\n op: \"in\",\n value: values,\n }),\n notIn: (column: string, values: FilterValue[]): Filter => ({\n column,\n op: \"not_in\",\n value: values,\n }),\n like: (column: string, pattern: string): Filter => ({\n column,\n op: \"like\",\n value: pattern,\n }),\n ilike: (column: string, pattern: string): Filter => ({\n column,\n op: \"ilike\",\n value: pattern,\n }),\n isNull: (column: string): Filter => ({ column, op: \"is_null\" }),\n isNotNull: (column: string): Filter => ({ column, op: \"is_not_null\" }),\n and: (...filters: Filter[]): Filter => ({ and: filters }),\n or: (...filters: Filter[]): Filter => ({ or: filters }),\n not: (filter: Filter): Filter => ({ not: filter }),\n },\n },\n\n /** Media uploads + CDN URL helpers. */\n storage: {\n presign: async (params: {\n bucket: string;\n filename: string;\n mimeType: string;\n sizeBytes: number;\n retentionDays?: number;\n }): Promise<PresignData> => {\n return (await coreCall((c) => c.storagePresign(\n params.bucket,\n params.filename,\n params.mimeType,\n params.sizeBytes,\n params.retentionDays ?? undefined,\n ))) as PresignData;\n },\n /**\n * Complete-flow upload: presign → PUT to R2 → commit.\n * Returns the finalized MediaAsset.\n */\n upload: async (params: {\n bucket: string;\n file: File | Blob;\n filename?: string;\n retentionDays?: number;\n }): Promise<MediaAsset> => {\n const filename =\n params.filename ??\n (\"name\" in params.file ? params.file.name : \"upload\");\n const mimeType = params.file.type || \"application/octet-stream\";\n const presign = await Amba.storage.presign({\n bucket: params.bucket,\n filename,\n mimeType,\n sizeBytes: params.file.size,\n retentionDays: params.retentionDays,\n });\n\n const uploadHeaders: Record<string, string> = {};\n for (const [k, v] of presign.upload_headers) {\n uploadHeaders[k] = v;\n }\n const putResp = await fetch(presign.upload_url, {\n method: \"PUT\",\n headers: uploadHeaders,\n body: params.file,\n });\n if (!putResp.ok) {\n throw new Error(`upload to R2 failed: status ${putResp.status}`);\n }\n\n return (await coreCall((c) => c.storageCommit(\n presign.upload_id,\n presign.asset_id,\n ))) as MediaAsset;\n },\n /**\n * List media assets (SDK 4.0). Pass `prefix` to scope to a key\n * prefix (filename / path-like). Without it, returns the caller's\n * full list. Server enforces RLS — only the calling user's assets\n * are returned.\n */\n list: async (prefix?: string): Promise<MediaListResponse> => {\n return (await coreCall((c) => c.storageList(\n prefix ?? undefined,\n ))) as MediaListResponse;\n },\n /**\n * Soft-delete the asset (SDK 4.0). Accepts the asset id returned\n * by `presign` / `commit` / `list`. The corresponding R2 object\n * is removed asynchronously on the server.\n */\n delete: async (assetId: string): Promise<void> => {\n await coreCall((c) => c.storageDelete(assetId));\n },\n /**\n * Download an asset's bytes (SDK 4.0). Returns a `Blob` wrapping\n * the Uint8Array returned by the engine, so consumers can\n * call `.text()` / `.arrayBuffer()` / `.stream()` directly or\n * pipe to a `URL.createObjectURL()` for preview. The two-step\n * fetch (asset metadata → CDN GET) is handled server-side on\n * the WASM side; this method is single-call from the consumer.\n */\n download: async (assetId: string): Promise<Blob> => {\n const bytes = (await coreCall((c) => c.storageDownload(\n assetId,\n ))) as Uint8Array;\n // `Blob` is universally available in browsers and Node 18+,\n // so no platform-shim needed. Type defaults to\n // `application/octet-stream` — the caller knows the real type\n // from their original upload metadata if they need it.\n // Cast through `BlobPart` — under newer @types/node typings,\n // `Uint8Array<ArrayBufferLike>` widens to `ArrayBufferLike`\n // which TS refuses to narrow back to `BlobPart`'s\n // `ArrayBufferView<ArrayBuffer>` constituent. The runtime\n // is fine — `Blob` accepts any TypedArray.\n return new Blob([bytes as unknown as BlobPart]);\n },\n },\n\n /** Offline change replay (SDK 4.0). */\n sync: {\n /**\n * Replay a batch of buffered mutations\n * (`POST /v1/client/sync`). The server applies them in order and\n * returns the count of successfully-applied changes plus any\n * per-row conflicts. Conflict resolution in 4.0 is always\n * server-wins; the `SyncConflict.resolution` field is reserved\n * for future strategies.\n */\n pushChanges: async (\n changes: SyncChange[],\n ): Promise<PushChangesResult> => {\n return (await coreCall((c) => c.syncPushChanges(\n encodeJson(changes),\n ))) as PushChangesResult;\n },\n /**\n * Pull remote-origin changes since the supplied cursor\n * (`GET /v1/client/sync`). Pass the `checkpoint_token` from the\n * previous `pushChanges` / `pullChanges` reply, and the\n * `entity_type` to scope to a single collection. On the first\n * call, omit `checkpoint_token` to receive the full backfill.\n */\n pullChanges: async (\n since: PullChangesCursor,\n ): Promise<PullChangesResult> => {\n return (await coreCall((c) => c.syncPullChanges(\n encodeJson(since),\n ))) as PullChangesResult;\n },\n },\n\n /** Push notifications. */\n push: {\n register: async (\n token: string,\n platform: PushPlatform,\n bundleId?: string,\n ): Promise<PushToken> => {\n return (await coreCall((c) => c.pushRegister(\n token,\n platform,\n bundleId ?? undefined,\n ))) as PushToken;\n },\n unregister: async (token: string): Promise<void> => {\n await coreCall((c) => c.pushUnregister(token));\n },\n getTokens: async (): Promise<PushToken[]> => {\n return (await coreCall((c) => c.pushGetTokens())) as PushToken[];\n },\n subscribe: async (topic: string): Promise<void> => {\n await coreCall((c) => c.pushSubscribe(topic));\n },\n unsubscribe: async (topic: string): Promise<void> => {\n await coreCall((c) => c.pushUnsubscribe(topic));\n },\n },\n\n /** RevenueCat/App Store/Stripe entitlements. */\n entitlements: {\n list: async (): Promise<UserEntitlement[]> => {\n return (await coreCall((c) => c.entitlementsList())) as UserEntitlement[];\n },\n has: async (name: string): Promise<boolean> => {\n return (await coreCall((c) => c.entitlementsHas(name))) as boolean;\n },\n },\n\n /** LLM proxy. */\n ai: {\n anthropic: {\n messages: {\n create: async (\n request: AiMessageRequest,\n ): Promise<AiMessageResponse> => {\n return (await coreCall((c) => c.aiAnthropicMessages(\n encodeJson(request),\n ))) as AiMessageResponse;\n },\n },\n },\n },\n\n /** Remote config bundle. */\n config: {\n fetch: async (): Promise<ConfigBundle> => {\n return (await coreCall((c) => c.configFetch())) as ConfigBundle;\n },\n },\n\n /** Server-evaluated feature flags. */\n flags: {\n fetch: async (): Promise<FlagAssignment[]> => {\n return (await coreCall((c) => c.flagsFetch())) as FlagAssignment[];\n },\n /**\n * Single-flag lookup (SDK 4.0). Wraps `GET /v1/client/flags/{key}`.\n * Returns `null` for unknown / disabled keys; other errors\n * (auth, rate-limit, network) propagate.\n */\n get: async (key: string): Promise<FlagAssignment | null> => {\n return (await coreCall((c) => c.flagsGet(key))) as FlagAssignment | null;\n },\n },\n\n /**\n * Wire-verify primitive. Call once after `configure()` to confirm\n * the SDK is talking to the right project with the right key.\n *\n * The response is entirely server-decided — none of the fields are\n * derived from request parameters — so it's trustworthy as a setup\n * check. Common usage:\n *\n * ```ts\n * const ping = await Amba.diagnostics.ping();\n * if (!ping.ok || ping.server_project_id !== expectedProjectId) {\n * throw new Error(`amba misconfigured: ${JSON.stringify(ping)}`);\n * }\n * ```\n */\n diagnostics: {\n ping: async (): Promise<PingResult> => {\n return (await coreCall((c) => c.diagnosticsPing())) as PingResult;\n },\n },\n\n // ── Gamification ──────────────────────────────────────────────────\n\n /** Achievement definitions + per-user progress. */\n achievements: {\n getAll: async (): Promise<Achievement[]> =>\n (await coreCall((c) => c.achievementsGetAll())) as Achievement[],\n getProgress: async (): Promise<AchievementProgress[]> =>\n (await coreCall((c) => c.achievementsGetProgress())) as AchievementProgress[],\n },\n\n /** Time-bounded challenges with rewards. */\n challenges: {\n getActive: async (): Promise<Challenge[]> =>\n (await coreCall((c) => c.challengesGetActive())) as Challenge[],\n get: async (id: string): Promise<Challenge> =>\n (await coreCall((c) => c.challengesGet(id))) as Challenge,\n getProgress: async (id: string): Promise<ChallengeProgress> =>\n (await coreCall((c) => c.challengesGetProgress(id))) as ChallengeProgress,\n claim: async (id: string): Promise<ChallengeProgress> =>\n (await coreCall((c) => c.challengesClaim(id))) as ChallengeProgress,\n },\n\n /** Virtual currency balances + ledger. */\n currencies: {\n getBalance: async (): Promise<CurrencyBalance[]> =>\n (await coreCall((c) => c.currenciesGetBalance())) as CurrencyBalance[],\n getTransactions: async (\n currencyKey: string,\n ): Promise<CurrencyTransaction[]> =>\n (await coreCall((c) => c.currenciesGetTransactions(\n currencyKey,\n ))) as CurrencyTransaction[],\n },\n\n /** User inventory items + purchase/consume. */\n inventory: {\n getItems: async (): Promise<InventoryItem[]> =>\n (await coreCall((c) => c.inventoryGetItems())) as InventoryItem[],\n getItem: async (id: string): Promise<InventoryItem> =>\n (await coreCall((c) => c.inventoryGetItem(id))) as InventoryItem,\n purchase: async (request: PurchaseRequest): Promise<InventoryItem> =>\n (await coreCall((c) => c.inventoryPurchase(\n encodeJson(request),\n ))) as InventoryItem,\n consume: async (request: ConsumeRequest): Promise<InventoryItem> =>\n (await coreCall((c) => c.inventoryConsume(\n encodeJson(request),\n ))) as InventoryItem,\n },\n\n /** Score rankings. */\n leaderboards: {\n get: async (key: string): Promise<Leaderboard> =>\n (await coreCall((c) => c.leaderboardsGet(key))) as Leaderboard,\n getEntries: async (\n key: string,\n limit?: number,\n ): Promise<LeaderboardEntry[]> =>\n (await coreCall((c) => c.leaderboardsGetEntries(\n key,\n limit ?? undefined,\n ))) as LeaderboardEntry[],\n getMyRank: async (key: string): Promise<LeaderboardEntry> =>\n (await coreCall((c) => c.leaderboardsGetMyRank(key))) as LeaderboardEntry,\n },\n\n /**\n * Tiered weekly leaderboard cohorts (SDK 4.0). Each user is bucketed\n * into a small cohort (~25 members) within their league tier; the\n * top scorers each week promote and the bottom scorers demote.\n */\n leagues: {\n /**\n * `GET /v1/client/leagues/me` — the caller's active-cohort\n * standing plus live rank/score and member count.\n */\n me: async (): Promise<LeagueMembership> => {\n return (await coreCall((c) => c.leaguesMe())) as LeagueMembership;\n },\n /**\n * `GET /v1/client/leagues/me/cohort` — the caller's cohort with\n * every member's anonymised standing (display name, score, rank).\n * Notably no user ids — the server strips them so a leaderboard\n * UI can render the cohort without exposing identities.\n */\n cohort: async (): Promise<LeagueCohortView> => {\n return (await coreCall((c) => c.leaguesCohort())) as LeagueCohortView;\n },\n },\n\n /** Purchase storefronts. */\n stores: {\n list: async (): Promise<Store[]> =>\n (await coreCall((c) => c.storesList())) as Store[],\n getPurchaseOptions: async (storeKey: string): Promise<PurchaseOption[]> =>\n (await coreCall((c) => c.storesGetPurchaseOptions(\n storeKey,\n ))) as PurchaseOption[],\n purchase: async (\n storeKey: string,\n purchaseOptionId: string,\n receipt: unknown,\n ): Promise<PurchaseResult> =>\n // `JSON.stringify(undefined)` returns the JS value `undefined`,\n // not a string — passing that to the WASM `storesPurchase` binding\n // crashes. Default the missing-receipt case to an empty object so\n // the server still receives valid JSON (BugBot Low 2026-05-19).\n (await coreCall((c) => c.storesPurchase(\n storeKey,\n purchaseOptionId,\n encodeJson(receipt ?? {}),\n ))) as PurchaseResult,\n },\n\n /** Experience points + level system. */\n xp: {\n getBalance: async (): Promise<XpBalance> =>\n (await coreCall((c) => c.xpGetBalance())) as XpBalance,\n getHistory: async (limit?: number): Promise<XpTransaction[]> =>\n (await coreCall((c) => c.xpGetHistory(\n limit ?? undefined,\n ))) as XpTransaction[],\n claim: async (grantKey: string): Promise<XpTransaction> =>\n (await coreCall((c) => c.xpClaim(grantKey))) as XpTransaction,\n },\n\n /** Daily-engagement streaks. */\n streaks: {\n getAll: async (): Promise<Streak[]> =>\n (await coreCall((c) => c.streaksGetAll())) as Streak[],\n qualify: async (streakKey: string): Promise<Streak> =>\n (await coreCall((c) => c.streaksQualify(streakKey))) as Streak,\n },\n\n // ── Social ─────────────────────────────────────────────────────────\n\n /** Activity feeds. */\n feeds: {\n getActivity: async (\n feed?: string,\n cursor?: string,\n ): Promise<FeedResponse> =>\n (await coreCall((c) => c.feedsGetActivity(\n feed ?? undefined,\n cursor ?? undefined,\n ))) as FeedResponse,\n },\n\n /** Friend graph + block list. */\n friends: {\n getList: async (): Promise<Friendship[]> =>\n (await coreCall((c) => c.friendsGetList())) as Friendship[],\n getFriends: async (): Promise<Friendship[]> =>\n (await coreCall((c) => c.friendsGetFriends())) as Friendship[],\n /**\n * Send a friend request to `userId` (SDK 4.0). Returns the\n * resulting `Friendship` row in `pending` state.\n */\n sendRequest: async (userId: string): Promise<Friendship> =>\n (await coreCall((c) => c.friendsSendRequest(userId))) as Friendship,\n /**\n * Accept a pending incoming friend request (SDK 4.0). Pass the\n * friendship id from `getList()`.\n */\n acceptRequest: async (friendshipId: string): Promise<Friendship> =>\n (await coreCall((c) => c.friendsAcceptRequest(\n friendshipId,\n ))) as Friendship,\n /**\n * Decline a pending incoming friend request (SDK 4.0). Removes\n * the pending row; idempotent.\n */\n declineRequest: async (friendshipId: string): Promise<void> => {\n await coreCall((c) => c.friendsDeclineRequest(friendshipId));\n },\n blockUser: async (userId: string): Promise<Friendship> =>\n (await coreCall((c) => c.friendsBlockUser(userId))) as Friendship,\n unblockUser: async (userId: string): Promise<void> => {\n await coreCall((c) => c.friendsUnblockUser(userId));\n },\n removeBlock: async (friendshipId: string): Promise<void> => {\n await coreCall((c) => c.friendsRemoveBlock(friendshipId));\n },\n /**\n * Unfriend by the other user's id (SDK 4.0). Wraps\n * `DELETE /v1/client/friends/by-user/{userId}`. Server preserves\n * blocked rows; use `unblockUser` to clear those. 404 propagates\n * as `AmbaApiError`.\n */\n removeFriend: async (userId: string): Promise<void> => {\n await coreCall((c) => c.friendsRemoveFriend(userId));\n },\n },\n\n /** Multi-user groups. */\n groups: {\n create: async (params: GroupCreate): Promise<Group> =>\n (await coreCall((c) => c.groupsCreate(encodeJson(params)))) as Group,\n get: async (id: string): Promise<Group> =>\n (await coreCall((c) => c.groupsGet(id))) as Group,\n update: async (id: string, patch: GroupUpdate): Promise<Group> =>\n (await coreCall((c) => c.groupsUpdate(id, encodeJson(patch)))) as Group,\n delete: async (id: string): Promise<void> => {\n await coreCall((c) => c.groupsDelete(id));\n },\n getMembers: async (id: string): Promise<GroupMember[]> =>\n (await coreCall((c) => c.groupsGetMembers(id))) as GroupMember[],\n join: async (id: string): Promise<GroupMember> =>\n (await coreCall((c) => c.groupsJoin(id))) as GroupMember,\n leave: async (id: string): Promise<void> => {\n await coreCall((c) => c.groupsLeave(id));\n },\n invite: async (id: string, userId: string): Promise<GroupMember> =>\n (await coreCall((c) => c.groupsInvite(id, userId))) as GroupMember,\n },\n\n /**\n * User-to-user direct messaging.\n *\n * Paths mirror the API exactly — see `apps/api/src/routes/client/messaging.ts`:\n *\n * | SDK method | API route |\n * | --------------------- | -------------------------------------------------------- |\n * | `createConversation` | POST `/v1/client/messaging/conversations` |\n * | `getConversations` | GET `/v1/client/messaging/conversations` |\n * | `listConversations` | (alias for `getConversations`) |\n * | `sendMessage` | POST `/v1/client/messaging/conversations/:id/messages` |\n * | `listMessages` | GET `/v1/client/messaging/conversations/:id/messages` |\n * | `markRead` | POST `/v1/client/messaging/conversations/:id/read` |\n *\n * Task #62 corrected `sendMessage`'s path (it previously POSTed to\n * `/messaging/messages`, a route that doesn't exist on the API), and\n * added the four missing helpers. The previous `getMessage(id)` helper\n * has been removed — there is no GET-by-id route on the server; the\n * shape consumers actually want is `listMessages(conversationId, opts)`.\n */\n messaging: {\n /**\n * `POST /v1/client/messaging/conversations` — create (or fetch the\n * existing direct) conversation. For `type: \"direct\"` with exactly\n * one other participant, the server returns the existing row if\n * one already exists between these two users — calls are\n * idempotent.\n */\n createConversation: async (\n request: CreateConversationRequest,\n ): Promise<Conversation> =>\n (await coreCall((c) => c.messagingCreateConversation(\n encodeJson(request),\n ))) as Conversation,\n\n /**\n * `GET /v1/client/messaging/conversations` — list the caller's\n * conversations. Canonical 4.0 name; the legacy `getConversations`\n * / `listConversations` are removed in 4.0 per the spec.\n */\n conversations: async (): Promise<Conversation[]> =>\n (await coreCall((c) => c.messagingGetConversations())) as Conversation[],\n\n /**\n * `POST /v1/client/messaging/conversations/:conversationId/messages`\n * — send a message into an existing conversation. The\n * `conversation_id` argument is a path parameter (not a body\n * field) — the previous SDK shape mistakenly placed it in the\n * body, which the API ignored because the route was wrong anyway.\n */\n sendMessage: async (\n conversationId: string,\n request: SendMessageRequest,\n ): Promise<Message> =>\n // The engine ABI takes a single JSON arg with\n // `conversation_id` inline — we provide a cleaner two-positional\n // shape to TS callers and re-fold conversation_id into the\n // payload here. The engine extracts it before posting.\n (await coreCall((c) => c.messagingSendMessage(\n encodeJson({ ...request, conversation_id: conversationId }),\n ))) as Message,\n\n /**\n * `GET /v1/client/messaging/conversations/:conversationId/messages`\n * — list messages in a conversation. Pagination uses `?limit=&offset=`\n * (the server's `parsePagination` clamps both; defaults to 50 / 0).\n */\n listMessages: async (\n conversationId: string,\n opts?: ListMessagesOptions,\n ): Promise<Message[]> =>\n (await coreCall((c) => c.messagingListMessages(\n conversationId,\n opts?.limit ?? undefined,\n opts?.offset ?? undefined,\n ))) as Message[],\n\n /**\n * `GET /v1/client/messaging/conversations/:conversationId/messages/:messageId`\n * — fetch a single message by id. Returns `null` when the message\n * doesn't exist or the caller can't see it. (SDK 4.0: Phase A\n * shipped the missing `amba_messaging_get_message` core symbol the\n * native SDKs were already trying to call.)\n */\n getMessage: async (\n conversationId: string,\n messageId: string,\n ): Promise<Message | null> => {\n return (await coreCall((c) => c.messagingGetMessage(\n conversationId,\n messageId,\n ))) as Message | null;\n },\n\n /**\n * `POST /v1/client/messaging/conversations/:conversationId/participants`\n * — add a participant to an existing conversation. The caller must\n * already be a participant (the server returns `403\n * NOT_A_PARTICIPANT` otherwise) — this is the peer-invite path.\n * Idempotent: re-adding an existing member returns the existing\n * participant row, not an error. Enables dynamic membership growth\n * (e.g. a circle whose members qualify over time). Server-side\n * membership management (admin/matchmaker) uses the admin\n * add-participant endpoint instead.\n */\n addParticipant: async (\n conversationId: string,\n userId: string,\n ): Promise<ConversationParticipant> =>\n (await coreCall((c) => c.messagingAddParticipant(\n conversationId,\n userId,\n ))) as ConversationParticipant,\n\n /**\n * `POST /v1/client/messaging/conversations/:conversationId/read`\n * — bump the caller's `last_read_at` for the conversation. Returns\n * the updated participant row.\n */\n markRead: async (conversationId: string): Promise<MarkReadResult> =>\n (await coreCall((c) => c.messagingMarkRead(\n conversationId,\n ))) as MarkReadResult,\n\n /**\n * Live message subscriptions (SDK 4.0). Returns a builder — call\n * `.subscribe(cb)` to receive new messages in a conversation live\n * instead of polling `listMessages`. `subscribe` returns an\n * unsubscribe handle.\n *\n * @example\n * const unsub = Amba.messaging\n * .conversation(conversationId)\n * .subscribe((change) => {\n * // change.op === \"INSERT\"; change.row is the new message\n * appendMessageToThread(change.row);\n * });\n * // later: unsub();\n *\n * Delivery is scoped to conversation participants — you receive a\n * conversation's messages only if your session is a member of it.\n * Requires an authenticated session.\n */\n conversation: <T = Message>(conversationId: string): ConversationSubscription<T> =>\n new ConversationSubscription<T>(\n { baseUrl: _configuredApiUrl, authHeaders: realtimeAuthHeaders },\n conversationId,\n ),\n },\n\n /** Report users / content for moderation. */\n moderation: {\n reportUser: async (request: ReportRequest): Promise<Report> =>\n (await coreCall((c) => c.moderationReportUser(\n encodeJson(request),\n ))) as Report,\n reportContent: async (request: ReportRequest): Promise<Report> =>\n (await coreCall((c) => c.moderationReportContent(\n encodeJson(request),\n ))) as Report,\n getReportStatus: async (id: string): Promise<Report> =>\n (await coreCall((c) => c.moderationGetReportStatus(id))) as Report,\n },\n\n /** User reviews of catalog items or other users. */\n reviews: {\n list: async (targetType: string, targetId: string): Promise<Review[]> =>\n (await coreCall((c) => c.reviewsList(targetType, targetId))) as Review[],\n create: async (params: ReviewCreate): Promise<Review> =>\n (await coreCall((c) => c.reviewsCreate(encodeJson(params)))) as Review,\n update: async (id: string, patch: ReviewUpdate): Promise<Review> =>\n (await coreCall((c) => c.reviewsUpdate(id, encodeJson(patch)))) as Review,\n delete: async (id: string): Promise<void> => {\n await coreCall((c) => c.reviewsDelete(id));\n },\n },\n\n /** RBAC roles + permission checks. */\n roles: {\n getMyRoles: async (): Promise<Role[]> =>\n (await coreCall((c) => c.rolesGetMyRoles())) as Role[],\n hasPermission: async (permission: string): Promise<boolean> =>\n (await coreCall((c) => c.rolesHasPermission(permission))) as boolean,\n },\n\n /** Referral codes + claim flow. */\n referrals: {\n getReferralCode: async (): Promise<ReferralCode> =>\n (await coreCall((c) => c.referralsGetReferralCode())) as ReferralCode,\n claimReferral: async (code: string): Promise<ReferralClaim> =>\n (await coreCall((c) => c.referralsClaimReferral(code))) as ReferralClaim,\n create: async (\n code?: string,\n maxUses?: number,\n ): Promise<ReferralCode> =>\n (await coreCall((c) => c.referralsCreate(\n code ?? undefined,\n maxUses ?? undefined,\n ))) as ReferralCode,\n },\n\n // ── Lifecycle ──────────────────────────────────────────────────────\n\n /** Read-only product catalog. */\n catalog: {\n list: async (): Promise<CatalogItem[]> =>\n (await coreCall((c) => c.catalogList())) as CatalogItem[],\n /**\n * Fetch a single catalog item by id (SDK 4.0).\n * `GET /v1/client/catalog/:id`.\n */\n get: async (id: string): Promise<CatalogItem> =>\n (await coreCall((c) => c.catalogGet(id))) as CatalogItem,\n },\n\n /** Developer-defined content items (daily quotes, lessons, etc.). */\n content: {\n /**\n * Get today's published item for `channel`. Defaults to `\"default\"`\n * so single-channel apps can call `Amba.content.today()` bare.\n * (Canonical 4.0 name; legacy `getToday` is removed.)\n */\n today: async (channel: string = \"default\"): Promise<ContentItem | null> =>\n (await coreCall((c) => c.contentGetToday(channel))) as ContentItem | null,\n /**\n * Paginated library list for `channel`. `options.limit` caps page size\n * (server default applies when omitted); `options.cursor` is the\n * opaque token returned by a prior response's `next_cursor`.\n * (Canonical 4.0 name; legacy `getLibrary` is removed.)\n */\n library: async (\n channel: string = \"default\",\n options?: { limit?: number; cursor?: string },\n ): Promise<ContentItem[]> =>\n (await coreCall((c) => c.contentGetLibrary(\n channel,\n options?.limit ?? undefined,\n options?.cursor ?? undefined,\n ))) as ContentItem[],\n item: async (id: string): Promise<ContentItem> =>\n (await coreCall((c) => c.contentGetItem(id))) as ContentItem,\n updateItem: async (id: string, state: unknown): Promise<ContentItem> =>\n (await coreCall((c) => c.contentUpdateItem(\n id,\n encodeJson(state),\n ))) as ContentItem,\n createItem: async (\n channel: string,\n item: unknown,\n ): Promise<ContentItem> =>\n (await coreCall((c) => c.contentCreateItem(\n channel,\n encodeJson(item),\n ))) as ContentItem,\n },\n\n /** Server-managed deep link records. */\n deepLinks: {\n get: async (shortCode: string): Promise<DeepLink> =>\n (await coreCall((c) => c.deepLinksGet(shortCode))) as DeepLink,\n create: async (params: DeepLinkCreate): Promise<DeepLink> =>\n (await coreCall((c) => c.deepLinksCreate(encodeJson(params)))) as DeepLink,\n },\n\n /** Step-by-step user onboarding flow. */\n onboarding: {\n getStatus: async (): Promise<OnboardingStatus> =>\n (await coreCall((c) => c.onboardingGetStatus())) as OnboardingStatus,\n nextStep: async (payload: unknown): Promise<OnboardingStatus> =>\n (await coreCall((c) => c.onboardingNextStep(\n encodeJson(payload),\n ))) as OnboardingStatus,\n skipStep: async (): Promise<OnboardingStatus> =>\n (await coreCall((c) => c.onboardingSkipStep())) as OnboardingStatus,\n complete: async (): Promise<OnboardingStatus> =>\n (await coreCall((c) => c.onboardingComplete())) as OnboardingStatus,\n },\n\n};\n\n/** Escape hatch — the raw SDK runtime handle, for namespaces not yet wrapped. */\nexport function getCoreWasm(): AmbaCoreWasm {\n return requireCore();\n}\n\n/**\n * Package version stamped at build time. Sent in the\n * `sdk_wrapper_version` header on every customer request.\n *\n * **Must match `package.json#version` exactly** — the\n * `verify-sdk-version-coherence` GH action gates every publish on the\n * pair agreeing (and matching the `web-v<X.Y.Z>` tag when tag-triggered).\n */\nexport const SDK_VERSION = \"4.0.3\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["prefix: string","ctx: RealtimeContext","name: string","controller: AbortController | null","idx: number","dataLines: string[]","conversationId: string","coreInstance: AmbaCoreWasm | null","_configuredProjectId: string | null","_configuredApiUrl: string","_configuredClientKey: string | null","_currentSessionToken: string | null","_configuredFunctionsBaseUrl: string | null","_resolvedFunctionsProjectId: string | null","wasmJsUrl: string","uploadHeaders: Record<string, string>","headers: Record<string, string>","requestBody: string | undefined","resp: Response","parsed: unknown"],"sources":["../src/storage-adapter.ts","../src/json.ts","../src/error.ts","../src/realtime.ts","../src/index.ts"],"sourcesContent":["/**\n * Browser localStorage adapter for SDK identity persistence.\n *\n * The SDK runtime currently re-seeds an `anonymous_id` on every page load.\n * This adapter is the documented home for storage-prefix handling so\n * customers can override the localStorage key prefix used by the\n * (eventual) identity cache.\n */\nexport class LocalStoragePersistence {\n constructor(private readonly prefix: string) {}\n\n /** Read everything we'd want to hydrate at init. No-op until wired through. */\n hydrate(): void {\n // Reserved for v0.2 — the SDK runtime will gain a persistence bridge\n // that calls into JS for read/write/list/delete.\n }\n\n read(key: string): string | null {\n if (typeof localStorage === \"undefined\") return null;\n return localStorage.getItem(`${this.prefix}:${key}`);\n }\n\n write(key: string, value: string): void {\n if (typeof localStorage === \"undefined\") return;\n localStorage.setItem(`${this.prefix}:${key}`, value);\n }\n\n delete(key: string): void {\n if (typeof localStorage === \"undefined\") return;\n localStorage.removeItem(`${this.prefix}:${key}`);\n }\n}\n","/**\n * JSON encode helper — guarantees stable serialization across browser\n * runtimes and provides a single hook for future schema validation.\n */\nexport function encodeJson(value: unknown): string {\n return JSON.stringify(value);\n}\n","/**\n * Typed error class for the amba SDK + helper that converts arbitrary\n * thrown values (native Error, plain objects, runtime-emitted errors)\n * into a stable `AmbaApiError` instance.\n *\n * Callers can `instanceof`-narrow safely, branch on `.code`, and pull\n * extra payload from `.details` (raw HTTP body, validation field paths,\n * etc.). The wrapper methods on `Amba` wrap every async call in\n * `toAmbaApiError`, so consumers see one error shape regardless of\n * which layer (network, runtime, validation) failed.\n */\n\n/**\n * Stable error codes surfaced by the SDK. Strings rather than an enum\n * so customers can extend with custom codes by simply throwing\n * `new AmbaApiError(\"MY_CODE\", \"...\")` without coordinating with this\n * package's TypeScript types.\n */\nexport type AmbaApiErrorCode =\n | \"UNAUTHORIZED\"\n | \"FORBIDDEN\"\n | \"NOT_FOUND\"\n | \"CONFLICT\"\n | \"RATE_LIMITED\"\n | \"VALIDATION_ERROR\"\n | \"NETWORK_ERROR\"\n | \"HTTP_ERROR\"\n | \"CIRCUIT_OPEN\"\n | \"CONSENT_NOT_GRANTED\"\n | \"NOT_INITIALIZED\"\n | \"INVALID_CONFIG\"\n | \"INVALID_ARGUMENT\"\n | \"PUSH_PERMISSION_DENIED\"\n | \"PUSH_REGISTRATION_FAILED\"\n | \"NOT_SANDBOX_TIER\"\n | \"UNKNOWN_ERROR\"\n | (string & {});\n\nexport class AmbaApiError extends Error {\n readonly code: AmbaApiErrorCode;\n readonly details?: unknown;\n constructor(\n code: AmbaApiErrorCode,\n message: string,\n details?: unknown,\n ) {\n super(message);\n this.name = \"AmbaApiError\";\n this.code = code;\n this.details = details;\n // Restore prototype chain when transpiled to ES5 targets — Error\n // subclasses lose their prototype otherwise and `instanceof` breaks.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Best-effort: pull a stable error code out of a Rust `AmbaError`\n * Display string. Used by `toAmbaApiError` when the underlying thrown\n * value is a generic `Error` produced by `wasm-bindgen`'s `JsError::new`.\n *\n * Keep in sync with `sdks/core/src/error.rs::AmbaError`'s `#[error]`\n * format strings — but the parser falls back to UNKNOWN_ERROR for any\n * pattern it doesn't recognize, so a stale match list isn't a footgun,\n * just a quality-of-life regression.\n */\nfunction codeFromMessage(message: string): AmbaApiErrorCode {\n // Cheapest checks first — most production errors are auth or HTTP.\n if (message.startsWith(\"Unauthorized\")) return \"UNAUTHORIZED\";\n if (message.startsWith(\"Forbidden\")) return \"FORBIDDEN\";\n if (message.startsWith(\"Not found\")) return \"NOT_FOUND\";\n if (message.startsWith(\"Conflict\")) return \"CONFLICT\";\n if (message.startsWith(\"Rate limited\")) return \"RATE_LIMITED\";\n if (message.startsWith(\"Validation error\")) return \"VALIDATION_ERROR\";\n if (message.startsWith(\"Network error\")) return \"NETWORK_ERROR\";\n if (message.startsWith(\"HTTP error\")) return \"HTTP_ERROR\";\n if (message.startsWith(\"Circuit breaker\")) return \"CIRCUIT_OPEN\";\n if (message.startsWith(\"Consent not granted\")) return \"CONSENT_NOT_GRANTED\";\n if (message.includes(\"not initialized\")) return \"NOT_INITIALIZED\";\n if (message.startsWith(\"Invalid configuration\")) return \"INVALID_CONFIG\";\n if (message.startsWith(\"Invalid argument\")) return \"INVALID_ARGUMENT\";\n return \"UNKNOWN_ERROR\";\n}\n\n/**\n * Coerce any thrown value into an `AmbaApiError`. Idempotent — passing\n * an existing `AmbaApiError` returns it unchanged so wrappers can stack\n * without re-wrapping.\n *\n * Heuristics:\n * 1. Existing `AmbaApiError` → returned as-is.\n * 2. Object with `.code` → use that code + `.message` + `.details`.\n * 3. `Error` (e.g. runtime-emitted error) → infer code from message prefix.\n * 4. Anything else → stringify and tag UNKNOWN_ERROR.\n */\nexport function toAmbaApiError(err: unknown): AmbaApiError {\n if (err instanceof AmbaApiError) return err;\n if (err && typeof err === \"object\") {\n const obj = err as { code?: unknown; message?: unknown; details?: unknown };\n if (typeof obj.code === \"string\") {\n return new AmbaApiError(\n obj.code,\n typeof obj.message === \"string\" ? obj.message : \"unknown\",\n obj.details,\n );\n }\n }\n if (err instanceof Error) {\n return new AmbaApiError(codeFromMessage(err.message), err.message);\n }\n return new AmbaApiError(\"UNKNOWN_ERROR\", String(err));\n}\n\n/**\n * Wrap a thunk so any thrown value becomes an `AmbaApiError`. The\n * wrapper methods on `Amba` use this to convert runtime-emitted errors\n * uniformly at the SDK boundary.\n */\nexport async function withAmbaError<T>(thunk: () => Promise<T>): Promise<T> {\n try {\n return await thunk();\n } catch (err) {\n throw toAmbaApiError(err);\n }\n}\n","/**\n * Live collection subscriptions for `@layers/amba-web` (PROTOTYPE — T13).\n *\n * Public surface is intentionally tiny and provider-agnostic:\n *\n * const unsub = Amba.collection(\"messages\")\n * .where(\"circle_id\", circleId)\n * .subscribe((change) => {\n * // change.op is \"INSERT\" | \"UPDATE\" | \"DELETE\"\n * // change.row is the affected row\n * });\n * unsub(); // stop listening\n *\n * The transport (a streamed HTTP response) and the server-side fan-out\n * mechanism are deliberately NOT named here — customers only ever see\n * `.subscribe()`. Internally this opens a long-lived streamed GET to the\n * realtime endpoint and reconnects with backoff if the connection drops.\n *\n * Delivery mirrors `Amba.collection.find()` exactly: you receive only rows\n * your session owns, optionally narrowed by `.where(...)` equality filters.\n */\n\nexport type RowChangeOp = \"INSERT\" | \"UPDATE\" | \"DELETE\";\n\nexport interface RealtimeChange<T = unknown> {\n /** Which kind of write happened. */\n op: RowChangeOp;\n /**\n * The affected row. For deletes this is a partial row (at minimum `id`).\n * If the row was too large to deliver inline, `truncated` is `true` and\n * `row` carries just `id` — re-fetch with `Amba.collection.find()` /\n * `findOne()` when you need the full body.\n */\n row: T;\n truncated?: boolean;\n}\n\nexport interface SubscribeOptions {\n /** Called once when the live connection is (re)established. */\n onOpen?: () => void;\n /** Called on a connection error before the SDK retries. */\n onError?: (err: unknown) => void;\n}\n\n/** Unsubscribe handle returned by `.subscribe(...)`. Call it to stop. */\nexport type Unsubscribe = () => void;\n\n/**\n * Resolved at call time so the latest session token is used. Returns the\n * auth headers, or `null` when there's no live session (subscribe throws).\n */\nexport interface RealtimeContext {\n baseUrl: string;\n authHeaders: () => Record<string, string> | null;\n}\n\nconst INITIAL_BACKOFF_MS = 500;\nconst MAX_BACKOFF_MS = 15_000;\n\n/**\n * Builder returned by `Amba.collection(name)`. Chain `.where(...)` to\n * narrow, then `.subscribe(cb)` to start streaming.\n */\nexport class CollectionSubscription<T = unknown> {\n private readonly filters: Record<string, unknown> = {};\n\n constructor(\n private readonly ctx: RealtimeContext,\n private readonly name: string,\n ) {}\n\n /** Add an equality filter. Chainable. All filters must match (AND). */\n where(column: string, value: unknown): this {\n this.filters[column] = value;\n return this;\n }\n\n /**\n * Start listening. `cb` fires once per matching row change. Returns an\n * unsubscribe handle — call it to close the connection.\n */\n subscribe(cb: (change: RealtimeChange<T>) => void, options: SubscribeOptions = {}): Unsubscribe {\n const headers = this.ctx.authHeaders();\n if (!headers) {\n throw new Error(\n \"Amba.collection().subscribe() requires an authenticated session — call Amba.auth.signIn*/verify* first.\",\n );\n }\n const qs =\n Object.keys(this.filters).length > 0\n ? `?where=${encodeURIComponent(JSON.stringify(this.filters))}`\n : \"\";\n const url = `${this.ctx.baseUrl}/v1/client/realtime/collections/${encodeURIComponent(\n this.name,\n )}${qs}`;\n return openStream<T>({\n url,\n authHeaders: this.ctx.authHeaders,\n onChange: cb,\n options,\n });\n }\n}\n\n/**\n * Inputs to a single realtime stream. The collection and conversation paths\n * differ only in how `url` is built; everything downstream (transport, frame\n * parsing, backoff/reconnect) is identical, so they share one implementation.\n */\ninterface StreamArgs<T> {\n url: string;\n authHeaders: () => Record<string, string> | null;\n onChange: (change: RealtimeChange<T>) => void;\n options: SubscribeOptions;\n}\n\n/**\n * Open a streamed GET to a realtime endpoint and dispatch row-change events\n * to `onChange`. Reconnects with exponential backoff until the returned\n * unsubscribe handle is invoked. Shared by both collection and conversation\n * subscriptions — the only thing that differs between them is the URL.\n *\n * Uses `fetch` + a streamed response body (rather than the browser's\n * native `EventSource`) because `EventSource` cannot set request headers —\n * which would force the session token into the URL query string, where it\n * would leak into access logs. Streaming `fetch` keeps auth in headers.\n */\nfunction openStream<T>(args: StreamArgs<T>): Unsubscribe {\n let stopped = false;\n let controller: AbortController | null = null;\n let backoff = INITIAL_BACKOFF_MS;\n\n const run = async (): Promise<void> => {\n while (!stopped) {\n controller = new AbortController();\n try {\n const headers = args.authHeaders();\n if (!headers) throw new Error(\"no active session\");\n const resp = await fetch(args.url, {\n method: \"GET\",\n headers: { ...headers, Accept: \"text/event-stream\" },\n signal: controller.signal,\n });\n if (!resp.ok || !resp.body) {\n throw new Error(`realtime connect failed: HTTP ${resp.status}`);\n }\n // Reset backoff only once the connection proves HEALTHY (first\n // frame received), not merely on a successful connect. A server\n // that accepts the connection then drops it immediately would\n // otherwise reset backoff every loop → a tight reconnect storm\n // with no exponential growth.\n await consume(resp.body, args, () => {\n backoff = INITIAL_BACKOFF_MS;\n args.options.onOpen?.();\n });\n } catch (err) {\n if (stopped) break;\n args.options.onError?.(err);\n }\n if (stopped) break;\n await delay(backoff);\n backoff = Math.min(backoff * 2, MAX_BACKOFF_MS);\n }\n };\n\n void run();\n\n return () => {\n stopped = true;\n controller?.abort();\n };\n}\n\nasync function consume<T>(\n body: ReadableStream<Uint8Array>,\n args: StreamArgs<T>,\n onFirstFrame: () => void,\n): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let sawFrame = false;\n for (;;) {\n const { done, value } = await reader.read();\n if (done) return;\n buffer += decoder.decode(value, { stream: true });\n let idx: number;\n while ((idx = buffer.indexOf(\"\\n\\n\")) !== -1) {\n const frame = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 2);\n if (!sawFrame) {\n sawFrame = true;\n onFirstFrame();\n }\n dispatchFrame<T>(frame, args.onChange);\n }\n }\n}\n\nfunction dispatchFrame<T>(frame: string, onChange: (change: RealtimeChange<T>) => void): void {\n let event = \"\";\n const dataLines: string[] = [];\n for (const line of frame.split(\"\\n\")) {\n if (line.startsWith(\":\")) continue; // keepalive comment\n if (line.startsWith(\"event:\")) event = line.slice(\"event:\".length).trim();\n else if (line.startsWith(\"data:\")) dataLines.push(line.slice(\"data:\".length).trim());\n }\n if (event !== \"change\") return; // ignore ready / error / heartbeat\n try {\n const payload = JSON.parse(dataLines.join(\"\\n\")) as {\n op: RowChangeOp;\n row: T;\n truncated?: boolean;\n };\n onChange({ op: payload.op, row: payload.row, truncated: payload.truncated });\n } catch {\n // malformed frame — skip rather than tear down the stream\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ── Messaging: live conversation subscriptions ─────────────────────────────\n\n/**\n * A live message change in a conversation. `op` is \"INSERT\" for a new\n * message; moderation removals arrive as \"DELETE\". For a delete (or when a\n * message was too large to deliver inline) `row` may be partial — re-fetch\n * with `Amba.messaging.listMessages(conversationId)` when you need the full\n * body.\n */\nexport type MessageChange<T = unknown> = RealtimeChange<T>;\n\n/**\n * Builder returned by `Amba.messaging.conversation(id)`. Call `.subscribe(cb)`\n * to receive new messages live instead of polling.\n *\n * const unsub = Amba.messaging\n * .conversation(conversationId)\n * .subscribe((change) => {\n * // change.op === \"INSERT\"; change.row is the new message\n * });\n * unsub(); // stop listening\n *\n * Delivery is scoped to conversation participants — you receive messages for\n * a conversation only if your session is a member of it. Reconnects with the\n * same exponential backoff as collection subscriptions.\n */\nexport class ConversationSubscription<T = unknown> {\n constructor(\n private readonly ctx: RealtimeContext,\n private readonly conversationId: string,\n ) {}\n\n subscribe(cb: (change: MessageChange<T>) => void, options: SubscribeOptions = {}): Unsubscribe {\n const headers = this.ctx.authHeaders();\n if (!headers) {\n throw new Error(\n \"Amba.messaging.conversation().subscribe() requires an authenticated session — call Amba.auth.signIn*/verify* first.\",\n );\n }\n const url = `${this.ctx.baseUrl}/v1/client/realtime/conversations/${encodeURIComponent(\n this.conversationId,\n )}`;\n return openStream<T>({\n url,\n authHeaders: this.ctx.authHeaders,\n onChange: cb,\n options,\n });\n }\n}\n","/**\n * @layers/amba-web — browser SDK for the amba platform.\n *\n * Exposes the full SDK 4.0 amba surface (34 modules) as idiomatic\n * TypeScript. All async operations return native Promises.\n *\n * @example\n * ```ts\n * import { Amba } from '@layers/amba-web';\n *\n * await Amba.configure({ projectId: 'proj_...', clientKey: 'amba_ck_...' });\n *\n * const session = await Amba.auth.signInAnonymously();\n * await Amba.events.track('app_opened', { source: 'deep_link' });\n *\n * const todos = await Amba.collections.find('todos', { limit: 20 });\n * await Amba.collections.insert('todos', { title: 'Buy milk' });\n * ```\n */\n\nimport init, { AmbaCoreWasm } from \"@layers/amba-core\";\n\nexport type * from \"./types\";\nimport type {\n AmbaConfig,\n AuthResult,\n User,\n FindOptions,\n FindResponse,\n Filter,\n FilterValue,\n ConfigBundle,\n FlagAssignment,\n PingResult,\n UserEntitlement,\n MediaAsset,\n MediaListResponse,\n PresignData,\n PushPlatform,\n PushToken,\n AiMessageRequest,\n AiMessageResponse,\n Achievement,\n AchievementProgress,\n Challenge,\n ChallengeProgress,\n CurrencyBalance,\n CurrencyTransaction,\n InventoryItem,\n PurchaseRequest,\n ConsumeRequest,\n Leaderboard,\n LeaderboardEntry,\n Store,\n PurchaseOption,\n PurchaseResult,\n XpBalance,\n XpTransaction,\n Streak,\n FeedResponse,\n Friendship,\n Group,\n GroupMember,\n GroupCreate,\n GroupUpdate,\n Conversation,\n Message,\n SendMessageRequest,\n CreateConversationRequest,\n ListMessagesOptions,\n MarkReadResult,\n ConversationParticipant,\n Report,\n ReportRequest,\n ReferralCode,\n ReferralClaim,\n Review,\n ReviewCreate,\n ReviewUpdate,\n Role,\n CatalogItem,\n ContentItem,\n DeepLink,\n DeepLinkCreate,\n OnboardingStatus,\n AppSession,\n SyncChange,\n PushChangesResult,\n PullChangesResult,\n PullChangesCursor,\n LeagueMembership,\n LeagueCohortView,\n NearestOptions,\n NearestResponse,\n LinkedIdentifier,\n} from \"./types\";\n\nimport { LocalStoragePersistence } from \"./storage-adapter\";\nimport { encodeJson } from \"./json\";\nimport { AmbaApiError, toAmbaApiError } from \"./error\";\nimport type { Session } from \"./types\";\nimport { CollectionSubscription, ConversationSubscription } from \"./realtime\";\n\nexport { AmbaApiError } from \"./error\";\nexport type { AmbaApiErrorCode } from \"./error\";\nexport { CollectionSubscription, ConversationSubscription } from \"./realtime\";\nexport type {\n RealtimeChange,\n MessageChange,\n RowChangeOp,\n SubscribeOptions,\n Unsubscribe,\n} from \"./realtime\";\n\nconst DEFAULT_API_URL = \"https://api.amba.dev\";\n\n/**\n * Default host that serves deployed functions. `Amba.functions.invoke(name)`\n * targets `https://<projectId>.<DEFAULT_FUNCTIONS_HOST>/<name>` unless a\n * `functionsBaseUrl` override is configured. The `<projectId>` label is the\n * server-resolved id (from `diagnostics.ping`), which the function router\n * accepts directly.\n */\nconst DEFAULT_FUNCTIONS_HOST = \"fn.amba.host\";\n\n/**\n * Internal state — one instance per page. Created lazily by `Amba.configure()`.\n */\nlet coreInstance: AmbaCoreWasm | null = null;\n\n/**\n * Stored at configure-time so `Amba.projectId` returns the configured\n * value without going through the engine. Cached only after the\n * core finishes initializing.\n */\nlet _configuredProjectId: string | null = null;\n\n/**\n * Realtime (`Amba.collection(name).subscribe`) needs the API base URL,\n * client key, and current session token in the TS layer to open the\n * streamed connection — the engine doesn't expose them back. We capture\n * the base URL + client key at configure-time and the session token from\n * every auth result (the engine rotates it internally on refresh; the\n * subscribe connection picks up the latest at connect time).\n */\nlet _configuredApiUrl: string = DEFAULT_API_URL;\nlet _configuredClientKey: string | null = null;\nlet _currentSessionToken: string | null = null;\n\n/**\n * Functions invocation state. `_configuredFunctionsBaseUrl` is the optional\n * override from `Amba.configure({ functionsBaseUrl })`. When it's null, the\n * default-host path resolves the project id once via `diagnostics.ping` and\n * caches it in `_resolvedFunctionsProjectId` so subsequent invokes skip the\n * round-trip. Both reset on every `configure()`.\n */\nlet _configuredFunctionsBaseUrl: string | null = null;\nlet _resolvedFunctionsProjectId: string | null = null;\n\nfunction requireCore(): AmbaCoreWasm {\n if (!coreInstance) {\n throw new AmbaApiError(\n \"NOT_INITIALIZED\",\n \"amba SDK not configured. Call Amba.configure({ projectId, clientKey }) at app start before any other API.\",\n );\n }\n return coreInstance;\n}\n\n/**\n * Run a single SDK-runtime call and rewrap any thrown value into a\n * stable `AmbaApiError`. Every method on `Amba` funnels through this\n * so callers see one error shape regardless of which layer failed\n * (network, validation, etc.). Sync `requireCore()` accessors\n * (e.g. the `anonymousId` getter) already throw the typed shape on\n * their own.\n */\nasync function coreCall<T>(fn: (c: AmbaCoreWasm) => Promise<T>): Promise<T> {\n try {\n return await fn(requireCore());\n } catch (err) {\n throw toAmbaApiError(err);\n }\n}\n\n/**\n * In-SDK auth-state pub/sub. `signIn*` / `signUp*` / `signOut` /\n * `refresh` call `notifyAuthSubscribers` after their underlying core\n * call resolves so subscribers always see a consistent `Session | null`\n * snapshot. Subscriber callbacks run synchronously inside the\n * notification path — keep them light; offload heavy work to your own\n * scheduler.\n */\ntype AuthSubscriber = (session: Session | null) => void;\nconst authSubscribers = new Set<AuthSubscriber>();\n\nfunction snapshotSession(user: User | null): Session | null {\n if (!user) return null;\n return {\n sessionToken: \"\",\n refreshToken: \"\",\n user,\n expiresAt: \"\",\n };\n}\n\nfunction notifyAuthSubscribers(session: Session | null): void {\n for (const cb of authSubscribers) {\n try {\n cb(session);\n } catch (err) {\n // Subscriber errors are isolated — one bad callback doesn't\n // block the rest. Surface in debug logs but don't rethrow into\n // the auth call path, which would mask the success result.\n if (typeof console !== \"undefined\") {\n console.error(\"[amba] onAuthStateChange callback threw\", err);\n }\n }\n }\n}\n\nasync function notifyFromAuthResult(result: AuthResult): Promise<void> {\n // Capture the session token for the realtime subscribe path (the engine\n // holds the canonical copy + auto-refreshes; this is the latest snapshot).\n if (result?.session_token) _currentSessionToken = result.session_token;\n notifyAuthSubscribers(snapshotSession(result.user));\n}\n\n/**\n * Build the auth headers for a realtime subscribe connection, or `null`\n * when there's no live session. Read lazily at connect-time so reconnects\n * pick up a rotated session token.\n */\nfunction realtimeAuthHeaders(): Record<string, string> | null {\n if (!_configuredClientKey || !_currentSessionToken) return null;\n return {\n \"X-Api-Key\": _configuredClientKey,\n Authorization: `Bearer ${_currentSessionToken}`,\n };\n}\n\n/**\n * Resolve the full invocation URL for a deployed function.\n *\n * With `functionsBaseUrl` configured we POST to `<base>/<name>` verbatim\n * (custom domains / non-prod). Otherwise we resolve the server-side project\n * id once (via `diagnostics.ping`, cached) and target\n * `https://<projectId>.fn.amba.host/<name>` — the function router accepts the\n * project id as the host label directly.\n */\nasync function resolveFunctionUrl(name: string): Promise<string> {\n if (_configuredFunctionsBaseUrl) {\n return `${_configuredFunctionsBaseUrl.replace(/\\/$/, \"\")}/${encodeURIComponent(name)}`;\n }\n if (!_resolvedFunctionsProjectId) {\n const ping = await Amba.diagnostics.ping();\n if (!ping.ok || !ping.server_project_id) {\n throw new AmbaApiError(\n \"FUNCTIONS_HOST_UNRESOLVED\",\n \"Could not resolve the functions host for this project. Pass `functionsBaseUrl` to Amba.configure() to invoke functions explicitly.\",\n ping,\n );\n }\n _resolvedFunctionsProjectId = ping.server_project_id;\n }\n return `https://${_resolvedFunctionsProjectId}.${DEFAULT_FUNCTIONS_HOST}/${encodeURIComponent(name)}`;\n}\n\n/** Options for `Amba.functions.invoke`. */\nexport interface InvokeOptions {\n /** HTTP method. Defaults to `\"POST\"`. */\n method?: \"POST\" | \"GET\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n /** Extra headers merged on top of the injected auth headers. */\n headers?: Record<string, string>;\n}\n\n/**\n * Top-level SDK namespace.\n *\n * Stateless from the JS side — all state lives in the SDK runtime. Calling\n * `Amba.configure()` multiple times replaces the previous instance.\n */\nexport const Amba = {\n /**\n * Initialize the SDK. Must be called once at app start.\n *\n * Seeds an `anonymous_id` from localStorage (if present) or generates a\n * fresh one.\n */\n configure: async (config: AmbaConfig): Promise<void> => {\n if (!config.projectId || config.projectId.trim() === \"\") {\n throw new Error(\"Amba.configure: projectId is required\");\n }\n if (!config.clientKey || config.clientKey.trim() === \"\") {\n throw new Error(\"Amba.configure: clientKey is required\");\n }\n // wasm-pack --target web's auto-loader does `fetch(new URL(\"./amba_core_bg.wasm\", import.meta.url))`.\n // That resolves to a `file://` URL in Node, and Node's undici doesn't\n // support the `file:` scheme — throws `fetch failed: not implemented`.\n // In Node (server-rendering, Jest/Vitest under jsdom, customer-shoes\n // smoke), read the wasm via fs and pass the bytes to init() directly.\n // In browsers, default behavior fetches the wasm from the asset URL.\n const isNode =\n typeof process !== \"undefined\" &&\n !!(process.versions && process.versions.node);\n if (isNode) {\n const [\n { readFile },\n { fileURLToPath, pathToFileURL },\n { createRequire },\n ] = await Promise.all([\n import(\"node:fs/promises\"),\n import(\"node:url\"),\n import(\"node:module\"),\n ]);\n // Resolve the wasm path through @layers/amba-core's package\n // root so we follow the same module resolution as the .js glue\n // — works whether the consumer used a bundler or a raw `node`.\n //\n // Resolution strategy, in order:\n // 1. `import.meta.resolve` (Node ≥20.6, stable in 22). Async or sync\n // depending on Node version — both return a string when awaited.\n // 2. `require.resolve` via `createRequire(import.meta.url)`. Uses\n // Node's standard module resolution which honors pnpm's\n // `.pnpm/<pkg>@<ver>/node_modules/<pkg>` layout. The previous\n // `../node_modules/...` hard-coded fallback failed on pnpm.\n // This mirrors the Node SDK fix at `packages/node/src/index.ts:124`.\n const resolveFn = (\n import.meta as unknown as {\n resolve?: (s: string) => string | Promise<string>;\n }\n ).resolve;\n let wasmJsUrl: string;\n if (resolveFn) {\n wasmJsUrl = await resolveFn(\"@layers/amba-core/wasm\");\n } else {\n const req = createRequire(import.meta.url);\n // `require.resolve` returns a filesystem path; convert to a\n // file:// URL so `fileURLToPath` below works uniformly with the\n // `import.meta.resolve` branch.\n wasmJsUrl = pathToFileURL(\n req.resolve(\"@layers/amba-core/wasm\"),\n ).href;\n }\n const bytes = await readFile(fileURLToPath(wasmJsUrl));\n await init(bytes);\n } else {\n await init();\n }\n const persistence = new LocalStoragePersistence(\n config.storagePrefix ?? \"amba\",\n );\n persistence.hydrate(); // no-op for now; reserved for future identity-cache restoration\n\n // Wrap `AmbaCoreWasm.init`'s throw with `toAmbaApiError` so\n // configure() rejects with an `AmbaApiError` instance — same\n // contract as every method call. Without this, the engine's\n // post-#63 `JsValue` throws would surface to customers as plain\n // objects, breaking `e instanceof Error` checks in\n // configure-failure handlers. (Reported by Cursor BugBot on\n // PR #156, high.)\n try {\n coreInstance = AmbaCoreWasm.init(\n encodeJson({\n api_key: config.clientKey,\n base_url: config.apiUrl,\n project_id: config.projectId,\n sdk_platform: \"web\",\n sdk_wrapper_version: `amba-web/${SDK_VERSION}`,\n consent_required: config.consentRequired,\n debug: config.debug,\n }),\n globalThis.fetch.bind(globalThis),\n );\n } catch (err) {\n throw toAmbaApiError(err);\n }\n\n // Cache the projectId only after WASM init succeeds — leaving the\n // module in a half-initialized state would let `Amba.projectId`\n // return a value while every other method (which checks\n // `coreInstance` via `requireCore()`) correctly throws\n // `NOT_INITIALIZED`.\n _configuredProjectId = config.projectId;\n _configuredApiUrl = config.apiUrl ?? DEFAULT_API_URL;\n _configuredClientKey = config.clientKey;\n _configuredFunctionsBaseUrl = config.functionsBaseUrl ?? null;\n // A fresh configure() may point at a different project — drop any cached\n // function-host resolution so the next invoke re-resolves.\n _resolvedFunctionsProjectId = null;\n },\n\n /** Project id this SDK instance is scoped to. */\n get projectId(): string {\n if (!_configuredProjectId) {\n throw new AmbaApiError(\n \"NOT_INITIALIZED\",\n \"amba SDK not configured. Call Amba.configure({ projectId, clientKey }) at app start before any other API.\",\n );\n }\n return _configuredProjectId;\n },\n\n /** Anonymous id — stable per browser. */\n get anonymousId(): string {\n return requireCore().anonymousId();\n },\n\n /** Authenticated user id, if a session is live. */\n get appUserId(): string | undefined {\n return requireCore().appUserId() ?? undefined;\n },\n\n /** Whether a session token is currently held. */\n get isAuthenticated(): boolean {\n return requireCore().isAuthenticated();\n },\n\n /** Toggle verbose logging at runtime. */\n setDebug: (enabled: boolean): void => {\n requireCore().setDebug(enabled);\n },\n\n // ── Core 9 namespaces ─────────────────────────────────────────────\n\n /** Track engagement events. */\n events: {\n /**\n * Track an event.\n *\n * The default route writes to the engagement meter — events that\n * fan out to segments, workflows, and push. Pass\n * `{ telemetry: true }` for high-volume, fire-and-forget events\n * that DON'T need fan-out: UI button clicks, scroll-depth markers,\n * game-loop telemetry. Telemetry events are billed at $0.10 per 1M\n * overage vs $0.50 per 10K for engagement events — a ~500×\n * difference that mirrors the underlying compute cost.\n *\n * Telemetry events are persisted and queryable via analytics, but\n * skip segment recompute, streak qualification, currency grant\n * rules, and `last_seen_at` updates.\n *\n * @example\n * await Amba.events.track('purchase_completed', { amount: 9.99 });\n * await Amba.events.track('scroll_depth', { px: 1024 }, { telemetry: true });\n */\n track: async (\n event: string,\n properties?: Record<string, unknown>,\n options?: { telemetry?: boolean },\n ): Promise<void> => {\n await coreCall((c) => c.track(\n event,\n properties ? encodeJson(properties) : undefined,\n options?.telemetry,\n ));\n },\n },\n\n /** Authentication flows. */\n auth: {\n signInAnonymously: async (): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.signInAnonymously())) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n signInWithEmail: async (\n email: string,\n password: string,\n ): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.signInWithEmail(\n email,\n password,\n ))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n signUpWithEmail: async (\n email: string,\n password: string,\n ): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.signUpWithEmail(\n email,\n password,\n ))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n /**\n * Sign in with an Apple identity token (the JWT returned by Sign\n * in with Apple). Replaces the SDK 3.x polymorphic\n * `signInWithSocial('apple', token)` form — that surface is\n * removed in 4.0.\n */\n signInWithApple: async (identityToken: string): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.signInWithSocial(\n \"apple\",\n identityToken,\n ))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n /**\n * Sign in with a Google ID token (the JWT returned by Google\n * Sign-In). Replaces the SDK 3.x polymorphic\n * `signInWithSocial('google', token)` form — that surface is\n * removed in 4.0.\n */\n signInWithGoogle: async (idToken: string): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.signInWithSocial(\n \"google\",\n idToken,\n ))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n /**\n * Request a one-time passcode for `email`. The server emails a\n * 6-digit code; the user types it into the app, then call\n * `verifyEmailOtp(email, code)` to exchange for a session. Always\n * resolves successfully regardless of email registration — the\n * server uses uniform responses to prevent account enumeration.\n */\n requestEmailOtp: async (email: string): Promise<void> => {\n await coreCall((c) => c.requestEmailOtp(email));\n },\n /**\n * Exchange `(email, code)` for a session. Returns the same\n * `AuthResult` shape as `signInWithEmail` and persists tokens for\n * subsequent calls. Rejects with a single error code for every\n * failure mode (wrong/expired/exhausted) — the server intentionally\n * does not distinguish them to prevent enumeration.\n */\n verifyEmailOtp: async (email: string, code: string): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.verifyEmailOtp(email, code))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n /**\n * Request a one-time passcode by SMS. `phone` MUST be E.164\n * (starts with `+`, 8–15 total digits). The SDK rejects\n * anything else with a `VALIDATION_ERROR` before the network\n * call. Server sends a 6-digit code; user types it into the\n * app, then call `verifySmsOtp(phone, code)` to exchange for\n * a session. Always resolves successfully regardless of phone\n * registration — uniform responses prevent enumeration.\n */\n requestSmsOtp: async (phone: string): Promise<void> => {\n await coreCall((c) => c.requestSmsOtp(phone));\n },\n /**\n * Exchange `(phone, code)` for a session. Same shape +\n * failure semantics as `verifyEmailOtp`. Persists tokens for\n * subsequent calls.\n */\n verifySmsOtp: async (phone: string, code: string): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.verifySmsOtp(phone, code))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n /**\n * Request a magic-link email for `email`. The server emails the\n * link; the user clicks it, which delivers a one-time token back\n * to the app. Exchange that token for a session with\n * `verifyMagicLink(token)`. Always resolves successfully\n * regardless of email registration (uniform responses prevent\n * account enumeration).\n */\n requestMagicLink: async (email: string): Promise<void> => {\n await coreCall((c) => c.requestMagicLink(email));\n },\n /**\n * Exchange a magic-link `token` for a session. Returns the same\n * `AuthResult` shape as `signInWithEmail` and persists tokens for\n * subsequent calls.\n */\n verifyMagicLink: async (token: string): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.verifyMagicLink(token))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n /**\n * Link an additional auth provider to the current session — used to\n * upgrade an anonymous session to an identified one without losing\n * the user's data. `provider` is one of the supported identity\n * strings (e.g. `\"apple\"`, `\"google\"`); `credential` is the\n * provider-issued token (identity-token / id-token / OTP code).\n */\n linkAccount: async (\n provider: string,\n credential: string,\n ): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.linkAccount(\n provider,\n credential,\n ))) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n\n /**\n * Attach a verified phone number to the **current session's user** —\n * without minting new tokens and without changing `user_id`.\n *\n * Flow: call `requestSmsOtp(phone)` first to mail the 6-digit code,\n * then call THIS instead of `verifySmsOtp` when the desired outcome\n * is \"decorate the current (often anonymous) user with this phone\"\n * rather than \"switch to the user who owns this phone\".\n *\n * Guarantees (symmetric to `linkEmailOtp`):\n *\n * - **Same `user_id`** before and after — collections, holds, XP,\n * `anonymous_id` all carry over.\n * - **Session token unchanged.** The existing token stays valid;\n * `onAuthStateChange` does NOT fire (no rotation).\n * - **Idempotent.** Re-linking the same phone to the same user\n * succeeds — no-op apart from `last_seen_at`.\n * - **Collision.** If the phone is already verified to a different\n * user, throws an error with `code = \"PHONE_ALREADY_LINKED\"` and\n * `details.conflicting_user_id` populated. The caller decides\n * whether to abort or switch identities via `verifySmsOtp`.\n *\n * Requires an active session — throws `UNAUTHORIZED` otherwise.\n *\n * @returns the updated user record (with `phone` set and\n * `phone_verified = true`).\n */\n linkSmsOtp: async (phone: string, code: string): Promise<User> => {\n return (await coreCall((c) => c.linkSmsOtp(phone, code))) as User;\n },\n\n /**\n * Attach a verified email to the current session's user. Symmetric\n * to `linkSmsOtp` — see that for the full guarantee list. Collision\n * code is `EMAIL_ALREADY_LINKED`.\n */\n linkEmailOtp: async (email: string, code: string): Promise<User> => {\n return (await coreCall((c) => c.linkEmailOtp(email, code))) as User;\n },\n\n /**\n * Upgrade an anonymous (or any current) session by attaching an\n * email + password credential — converting the current user in place\n * to an email-identified account so its data (streak, library,\n * progress, `anonymous_id`) is preserved rather than minting a new\n * user.\n *\n * Guarantees (symmetric to `linkEmailOtp`):\n *\n * - **Same `user_id`** before and after.\n * - **Session token unchanged.** No rotation; `onAuthStateChange`\n * does NOT fire.\n * - **Idempotent.** Re-linking the same email to the same user\n * succeeds.\n * - **Collision.** If the email is already owned by a different user,\n * throws an error with `code = \"EMAIL_ALREADY_LINKED\"` and\n * `details.conflicting_user_id` populated.\n *\n * After linking, the user can sign in with `signInWithEmail(email,\n * password)`. Requires an active session — throws `UNAUTHORIZED`\n * otherwise.\n *\n * @returns the updated user record (with `email` set and\n * `email_verified = true`).\n */\n linkEmailPassword: async (email: string, password: string): Promise<User> => {\n return (await coreCall((c) => c.linkEmailPassword(email, password))) as User;\n },\n\n /**\n * Detach the SMS-OTP identifier from the current session's user.\n * Refused with `LAST_IDENTIFIER` if this would leave the account\n * with no recoverable identifier (link another first, then unlink).\n * No token rotation.\n */\n unlinkSmsOtp: async (): Promise<User> => {\n return (await coreCall((c) => c.unlinkSmsOtp())) as User;\n },\n\n /** Detach the email-OTP identifier. Same guarantees as `unlinkSmsOtp`. */\n unlinkEmailOtp: async (): Promise<User> => {\n return (await coreCall((c) => c.unlinkEmailOtp())) as User;\n },\n\n /** Detach the Apple social identity from the current session's user. */\n unlinkApple: async (): Promise<User> => {\n return (await coreCall((c) => c.unlinkApple())) as User;\n },\n\n /** Detach the Google social identity from the current session's user. */\n unlinkGoogle: async (): Promise<User> => {\n return (await coreCall((c) => c.unlinkGoogle())) as User;\n },\n\n /**\n * Snapshot the identifier providers attached to the current\n * session's user. Lets a host app gate \"should I show the verify-\n * email prompt\" without a profile round-trip.\n *\n * Identifier values come back **masked** — raw values stay\n * server-side.\n */\n getCurrentIdentifiers: async (): Promise<LinkedIdentifier[]> => {\n return (await coreCall((c) => c.currentIdentifiers())) as LinkedIdentifier[];\n },\n signOut: async (rotateAnonymousId = false): Promise<void> => {\n await coreCall((c) => c.signOut(rotateAnonymousId));\n _currentSessionToken = null;\n notifyAuthSubscribers(null);\n },\n refresh: async (): Promise<AuthResult> => {\n const r = (await coreCall((c) => c.refreshSession())) as AuthResult;\n await notifyFromAuthResult(r);\n return r;\n },\n me: async (): Promise<User> => {\n return (await coreCall((c) => c.me())) as User;\n },\n\n /**\n * Snapshot the current session, or `null` if no session is live.\n * sessionToken/refreshToken/expiresAt come back as empty strings —\n * they're SDK-managed and not read-back-able from the core. Use\n * `Amba.isAuthenticated` if you only need the boolean.\n */\n getSession: async (): Promise<Session | null> => {\n const core = requireCore();\n if (!core.isAuthenticated()) return null;\n const user = (await coreCall((c) => c.me())) as User;\n return snapshotSession(user);\n },\n\n /**\n * Stable anonymous identifier (kept in memory by the SDK runtime).\n * Sync today, async for parity with the RN/native shape where the\n * platform may need to await a persistence read.\n */\n getAnonymousId: async (): Promise<string> => {\n return requireCore().anonymousId();\n },\n\n /**\n * Subscribe to session changes. Fires after every `signIn*`,\n * `signUp*`, `refresh`, and `signOut` call. Returns an\n * unsubscribe function — call it to remove the callback.\n *\n * Does NOT fire an initial snapshot when subscribed; call\n * `getSession()` once after subscribing if you need the\n * current state up front.\n */\n onAuthStateChange: (\n cb: (session: Session | null) => void,\n ): (() => void) => {\n authSubscribers.add(cb);\n return () => {\n authSubscribers.delete(cb);\n };\n },\n },\n\n /** Profile read/update (SDK 4.0). */\n users: {\n /**\n * Get a user profile. `userId` omitted → current user\n * (`GET /v1/client/users/me`); `userId` set → public-safe profile\n * of the other user (`GET /v1/client/users/{id}`).\n */\n get: async (userId?: string): Promise<User> => {\n return (await coreCall((c) => c.usersGet(\n userId ?? undefined,\n ))) as User;\n },\n /**\n * Update a profile. Two shapes:\n * - `update(patch)` — current user (`PATCH /users/me`).\n * - `update(userId, patch)` — admin-style cross-user update\n * (`PATCH /users/{id}`); the server requires the caller to\n * hold `users:write` and 403s otherwise.\n *\n * Allowed keys (both shapes): `display_name`, `avatar_url`,\n * `properties`, `timezone`.\n */\n update: (((\n arg1: string | Partial<User>,\n arg2?: Partial<User>,\n ): Promise<User> => {\n const isById = typeof arg1 === \"string\";\n const userId = isById ? (arg1 as string) : undefined;\n const patch = isById ? (arg2 ?? {}) : (arg1 as Partial<User>);\n return coreCall((c) => c.usersUpdate(\n userId ?? undefined,\n encodeJson(patch),\n )) as Promise<User>;\n }) as {\n (patch: Partial<User>): Promise<User>;\n (userId: string, patch: Partial<User>): Promise<User>;\n }),\n },\n\n /** List + revoke customer-recorded app sessions (SDK 4.0). */\n sessions: {\n /** `GET /v1/client/sessions` — list the caller's app sessions. */\n list: async (): Promise<AppSession[]> => {\n return (await coreCall((c) => c.sessionsList())) as AppSession[];\n },\n /**\n * `POST /v1/client/sessions/:id/end` — end the session with the\n * given id. The 4.0 `revoke` contract returns unit; customers who\n * need the ended row should use the lower-level `sessions.end`\n * helper on the core (not exposed on the public SDK).\n */\n revoke: async (sessionId: string): Promise<void> => {\n await coreCall((c) => c.sessionsRevoke(sessionId));\n },\n },\n\n /**\n * Live collection subscriptions (SDK 4.0). Returns a builder — chain\n * `.where(column, value)` to narrow, then `.subscribe(cb)` to start\n * receiving row changes. `subscribe` returns an unsubscribe handle.\n *\n * @example\n * const unsub = Amba.collection(\"messages\")\n * .where(\"circle_id\", circleId)\n * .subscribe((change) => {\n * // change.op: \"INSERT\" | \"UPDATE\" | \"DELETE\"; change.row: the row\n * });\n * // later: unsub();\n *\n * Delivery mirrors `Amba.collections.find()` — you only receive rows your\n * session owns. Requires an authenticated session.\n */\n collection: <T = unknown>(name: string): CollectionSubscription<T> =>\n new CollectionSubscription<T>(\n { baseUrl: _configuredApiUrl, authHeaders: realtimeAuthHeaders },\n name,\n ),\n\n /** Typed collection CRUD with auto-RLS. */\n collections: {\n find: async <T = unknown>(\n name: string,\n options: FindOptions = {},\n ): Promise<FindResponse<T>> => {\n return (await coreCall((c) => c.collectionsFind(\n name,\n encodeJson(options),\n ))) as FindResponse<T>;\n },\n findOne: async <T = unknown>(name: string, id: string): Promise<T> => {\n return (await coreCall((c) => c.collectionsFindOne(name, id))) as T;\n },\n insert: async <T = unknown>(\n name: string,\n row: Record<string, unknown>,\n ): Promise<T> => {\n return (await coreCall((c) => c.collectionsInsert(\n name,\n encodeJson(row),\n ))) as T;\n },\n update: async <T = unknown>(\n name: string,\n id: string,\n set: Record<string, unknown>,\n ): Promise<T> => {\n return (await coreCall((c) => c.collectionsUpdate(\n name,\n id,\n encodeJson(set),\n ))) as T;\n },\n delete: async (\n name: string,\n id: string,\n ): Promise<{ data: { deleted: boolean } }> => {\n return (await coreCall((c) => c.collectionsDelete(name, id))) as {\n data: { deleted: boolean };\n };\n },\n /**\n * Vector-search the collection (SDK 4.0). Returns the `k` nearest\n * neighbors of `options.query_vector` against the column named\n * `options.vector_field`. Distance metric and index strategy are\n * server-side; pass `options.filter` to narrow the candidate set\n * before ranking.\n *\n * Spec note: the canonical `findNearest(name, vector, k, filter?)`\n * shape omits the column name; the SDK widens the contract to a\n * single typed options object so `vector_field` is required and\n * unambiguous in TS.\n */\n findNearest: async <T = unknown>(\n name: string,\n options: NearestOptions,\n ): Promise<NearestResponse<T>> => {\n return (await coreCall((c) => c.collectionsFindNearest(\n name,\n encodeJson(options),\n ))) as NearestResponse<T>;\n },\n /**\n * Count rows in the collection (SDK 4.0). Pass an optional filter\n * to scope; omit it for the total. The server's response unwraps to\n * a bare number on the JS side.\n */\n count: async (name: string, filter?: Filter): Promise<number> => {\n return (await coreCall((c) => c.collectionsCount(\n name,\n filter ? encodeJson(filter) : undefined,\n ))) as number;\n },\n /** Filter DSL helpers — pass into `find({ filter: f })`. */\n where: {\n eq: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"eq\",\n value,\n }),\n ne: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"ne\",\n value,\n }),\n gt: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"gt\",\n value,\n }),\n gte: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"gte\",\n value,\n }),\n lt: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"lt\",\n value,\n }),\n lte: (column: string, value: FilterValue): Filter => ({\n column,\n op: \"lte\",\n value,\n }),\n in: (column: string, values: FilterValue[]): Filter => ({\n column,\n op: \"in\",\n value: values,\n }),\n notIn: (column: string, values: FilterValue[]): Filter => ({\n column,\n op: \"not_in\",\n value: values,\n }),\n like: (column: string, pattern: string): Filter => ({\n column,\n op: \"like\",\n value: pattern,\n }),\n ilike: (column: string, pattern: string): Filter => ({\n column,\n op: \"ilike\",\n value: pattern,\n }),\n isNull: (column: string): Filter => ({ column, op: \"is_null\" }),\n isNotNull: (column: string): Filter => ({ column, op: \"is_not_null\" }),\n and: (...filters: Filter[]): Filter => ({ and: filters }),\n or: (...filters: Filter[]): Filter => ({ or: filters }),\n not: (filter: Filter): Filter => ({ not: filter }),\n },\n },\n\n /** Media uploads + CDN URL helpers. */\n storage: {\n presign: async (params: {\n bucket: string;\n filename: string;\n mimeType: string;\n sizeBytes: number;\n retentionDays?: number;\n }): Promise<PresignData> => {\n return (await coreCall((c) => c.storagePresign(\n params.bucket,\n params.filename,\n params.mimeType,\n params.sizeBytes,\n params.retentionDays ?? undefined,\n ))) as PresignData;\n },\n /**\n * Complete-flow upload: presign → PUT to R2 → commit.\n * Returns the finalized MediaAsset.\n */\n upload: async (params: {\n bucket: string;\n file: File | Blob;\n filename?: string;\n retentionDays?: number;\n }): Promise<MediaAsset> => {\n const filename =\n params.filename ??\n (\"name\" in params.file ? params.file.name : \"upload\");\n const mimeType = params.file.type || \"application/octet-stream\";\n const presign = await Amba.storage.presign({\n bucket: params.bucket,\n filename,\n mimeType,\n sizeBytes: params.file.size,\n retentionDays: params.retentionDays,\n });\n\n const uploadHeaders: Record<string, string> = {};\n for (const [k, v] of presign.upload_headers) {\n uploadHeaders[k] = v;\n }\n const putResp = await fetch(presign.upload_url, {\n method: \"PUT\",\n headers: uploadHeaders,\n body: params.file,\n });\n if (!putResp.ok) {\n throw new Error(`upload to R2 failed: status ${putResp.status}`);\n }\n\n return (await coreCall((c) => c.storageCommit(\n presign.upload_id,\n presign.asset_id,\n ))) as MediaAsset;\n },\n /**\n * List media assets (SDK 4.0). Pass `prefix` to scope to a key\n * prefix (filename / path-like). Without it, returns the caller's\n * full list. Server enforces RLS — only the calling user's assets\n * are returned.\n */\n list: async (prefix?: string): Promise<MediaListResponse> => {\n return (await coreCall((c) => c.storageList(\n prefix ?? undefined,\n ))) as MediaListResponse;\n },\n /**\n * Soft-delete the asset (SDK 4.0). Accepts the asset id returned\n * by `presign` / `commit` / `list`. The corresponding R2 object\n * is removed asynchronously on the server.\n */\n delete: async (assetId: string): Promise<void> => {\n await coreCall((c) => c.storageDelete(assetId));\n },\n /**\n * Download an asset's bytes (SDK 4.0). Returns a `Blob` wrapping\n * the Uint8Array returned by the engine, so consumers can\n * call `.text()` / `.arrayBuffer()` / `.stream()` directly or\n * pipe to a `URL.createObjectURL()` for preview. The two-step\n * fetch (asset metadata → CDN GET) is handled server-side on\n * the WASM side; this method is single-call from the consumer.\n */\n download: async (assetId: string): Promise<Blob> => {\n const bytes = (await coreCall((c) => c.storageDownload(\n assetId,\n ))) as Uint8Array;\n // `Blob` is universally available in browsers and Node 18+,\n // so no platform-shim needed. Type defaults to\n // `application/octet-stream` — the caller knows the real type\n // from their original upload metadata if they need it.\n // Cast through `BlobPart` — under newer @types/node typings,\n // `Uint8Array<ArrayBufferLike>` widens to `ArrayBufferLike`\n // which TS refuses to narrow back to `BlobPart`'s\n // `ArrayBufferView<ArrayBuffer>` constituent. The runtime\n // is fine — `Blob` accepts any TypedArray.\n return new Blob([bytes as unknown as BlobPart]);\n },\n },\n\n /** Offline change replay (SDK 4.0). */\n sync: {\n /**\n * Replay a batch of buffered mutations\n * (`POST /v1/client/sync`). The server applies them in order and\n * returns the count of successfully-applied changes plus any\n * per-row conflicts. Conflict resolution in 4.0 is always\n * server-wins; the `SyncConflict.resolution` field is reserved\n * for future strategies.\n */\n pushChanges: async (\n changes: SyncChange[],\n ): Promise<PushChangesResult> => {\n return (await coreCall((c) => c.syncPushChanges(\n encodeJson(changes),\n ))) as PushChangesResult;\n },\n /**\n * Pull remote-origin changes since the supplied cursor\n * (`GET /v1/client/sync`). Pass the `checkpoint_token` from the\n * previous `pushChanges` / `pullChanges` reply, and the\n * `entity_type` to scope to a single collection. On the first\n * call, omit `checkpoint_token` to receive the full backfill.\n */\n pullChanges: async (\n since: PullChangesCursor,\n ): Promise<PullChangesResult> => {\n return (await coreCall((c) => c.syncPullChanges(\n encodeJson(since),\n ))) as PullChangesResult;\n },\n },\n\n /** Push notifications. */\n push: {\n register: async (\n token: string,\n platform: PushPlatform,\n bundleId?: string,\n ): Promise<PushToken> => {\n return (await coreCall((c) => c.pushRegister(\n token,\n platform,\n bundleId ?? undefined,\n ))) as PushToken;\n },\n unregister: async (token: string): Promise<void> => {\n await coreCall((c) => c.pushUnregister(token));\n },\n getTokens: async (): Promise<PushToken[]> => {\n return (await coreCall((c) => c.pushGetTokens())) as PushToken[];\n },\n subscribe: async (topic: string): Promise<void> => {\n await coreCall((c) => c.pushSubscribe(topic));\n },\n unsubscribe: async (topic: string): Promise<void> => {\n await coreCall((c) => c.pushUnsubscribe(topic));\n },\n },\n\n /** RevenueCat/App Store/Stripe entitlements. */\n entitlements: {\n list: async (): Promise<UserEntitlement[]> => {\n return (await coreCall((c) => c.entitlementsList())) as UserEntitlement[];\n },\n has: async (name: string): Promise<boolean> => {\n return (await coreCall((c) => c.entitlementsHas(name))) as boolean;\n },\n },\n\n /** LLM proxy. */\n ai: {\n anthropic: {\n messages: {\n create: async (\n request: AiMessageRequest,\n ): Promise<AiMessageResponse> => {\n return (await coreCall((c) => c.aiAnthropicMessages(\n encodeJson(request),\n ))) as AiMessageResponse;\n },\n },\n },\n },\n\n /**\n * Invoke a deployed function by name, with the project's client key (and\n * the live session token, if any) injected automatically.\n *\n * This is the authenticated way to call your functions — prefer it over\n * hand-rolling `fetch` against a function URL, which leaves the call\n * unauthenticated (a footgun when the function holds secrets).\n *\n * @example\n * const result = await Amba.functions.invoke<{ ok: boolean }>(\n * 'send_welcome_email',\n * { to: 'user@example.com' },\n * );\n *\n * @param name The deployed function name.\n * @param body JSON-serializable request body (omitted for GET).\n * @param options Method + extra headers.\n * @returns The parsed JSON response (or the raw text if not JSON).\n * @throws AmbaApiError on a network failure or a non-2xx response. When\n * the function / router returns the standard `{ error: { code, message } }`\n * envelope, those surface as the thrown error's `code` + `message`.\n */\n functions: {\n invoke: async <T = unknown>(\n name: string,\n body?: unknown,\n options?: InvokeOptions,\n ): Promise<T> => {\n // Enforce configured state (consistent with every other method) and\n // capture the client key the function router authenticates against.\n requireCore();\n if (!_configuredClientKey) {\n throw new AmbaApiError(\n \"NOT_INITIALIZED\",\n \"amba SDK not configured. Call Amba.configure({ projectId, clientKey }) before Amba.functions.invoke().\",\n );\n }\n if (!name || name.trim() === \"\") {\n throw new AmbaApiError(\n \"INVALID_ARGUMENT\",\n \"Amba.functions.invoke: a function name is required.\",\n );\n }\n\n const url = await resolveFunctionUrl(name);\n const method = options?.method ?? \"POST\";\n const headers: Record<string, string> = {\n \"X-Api-Key\": _configuredClientKey,\n ...(options?.headers ?? {}),\n };\n // Inject the live session token so the function runs in the end-user's\n // authenticated context. Anonymous (pre-sign-in) invokes still carry\n // the client key, which the router accepts for non-public functions.\n if (_currentSessionToken) {\n headers[\"Authorization\"] = `Bearer ${_currentSessionToken}`;\n }\n let requestBody: string | undefined;\n if (body !== undefined && method !== \"GET\") {\n headers[\"content-type\"] = \"application/json\";\n requestBody = JSON.stringify(body);\n }\n\n let resp: Response;\n try {\n resp = await fetch(url, { method, headers, body: requestBody });\n } catch (err) {\n throw new AmbaApiError(\n \"NETWORK_ERROR\",\n `Amba.functions.invoke(\"${name}\") network error: ${String(err)}`,\n );\n }\n\n const text = await resp.text();\n let parsed: unknown = undefined;\n if (text.length > 0) {\n try {\n parsed = JSON.parse(text);\n } catch {\n // Function returned non-JSON (e.g. plain text / HTML) — pass it\n // through verbatim rather than guessing a shape.\n parsed = text;\n }\n }\n\n if (!resp.ok) {\n const envelope =\n parsed && typeof parsed === \"object\"\n ? (parsed as { error?: { code?: unknown; message?: unknown } })\n : undefined;\n const code =\n typeof envelope?.error?.code === \"string\"\n ? envelope.error.code\n : `HTTP_${resp.status}`;\n const message =\n typeof envelope?.error?.message === \"string\"\n ? envelope.error.message\n : typeof parsed === \"string\" && parsed.length > 0\n ? parsed\n : `Amba.functions.invoke(\"${name}\") failed with status ${resp.status}`;\n throw new AmbaApiError(code, message, parsed);\n }\n\n return parsed as T;\n },\n },\n\n /** Remote config bundle. */\n config: {\n fetch: async (): Promise<ConfigBundle> => {\n return (await coreCall((c) => c.configFetch())) as ConfigBundle;\n },\n },\n\n /** Server-evaluated feature flags. */\n flags: {\n fetch: async (): Promise<FlagAssignment[]> => {\n return (await coreCall((c) => c.flagsFetch())) as FlagAssignment[];\n },\n /**\n * Single-flag lookup (SDK 4.0). Wraps `GET /v1/client/flags/{key}`.\n * Returns `null` for unknown / disabled keys; other errors\n * (auth, rate-limit, network) propagate.\n */\n get: async (key: string): Promise<FlagAssignment | null> => {\n return (await coreCall((c) => c.flagsGet(key))) as FlagAssignment | null;\n },\n },\n\n /**\n * Wire-verify primitive. Call once after `configure()` to confirm\n * the SDK is talking to the right project with the right key.\n *\n * The response is entirely server-decided — none of the fields are\n * derived from request parameters — so it's trustworthy as a setup\n * check. Common usage:\n *\n * ```ts\n * const ping = await Amba.diagnostics.ping();\n * if (!ping.ok || ping.server_project_id !== expectedProjectId) {\n * throw new Error(`amba misconfigured: ${JSON.stringify(ping)}`);\n * }\n * ```\n */\n diagnostics: {\n ping: async (): Promise<PingResult> => {\n return (await coreCall((c) => c.diagnosticsPing())) as PingResult;\n },\n },\n\n // ── Gamification ──────────────────────────────────────────────────\n\n /** Achievement definitions + per-user progress. */\n achievements: {\n getAll: async (): Promise<Achievement[]> =>\n (await coreCall((c) => c.achievementsGetAll())) as Achievement[],\n getProgress: async (): Promise<AchievementProgress[]> =>\n (await coreCall((c) => c.achievementsGetProgress())) as AchievementProgress[],\n },\n\n /** Time-bounded challenges with rewards. */\n challenges: {\n getActive: async (): Promise<Challenge[]> =>\n (await coreCall((c) => c.challengesGetActive())) as Challenge[],\n get: async (id: string): Promise<Challenge> =>\n (await coreCall((c) => c.challengesGet(id))) as Challenge,\n getProgress: async (id: string): Promise<ChallengeProgress> =>\n (await coreCall((c) => c.challengesGetProgress(id))) as ChallengeProgress,\n claim: async (id: string): Promise<ChallengeProgress> =>\n (await coreCall((c) => c.challengesClaim(id))) as ChallengeProgress,\n },\n\n /** Virtual currency balances + ledger. */\n currencies: {\n getBalance: async (): Promise<CurrencyBalance[]> =>\n (await coreCall((c) => c.currenciesGetBalance())) as CurrencyBalance[],\n getTransactions: async (\n currencyKey: string,\n ): Promise<CurrencyTransaction[]> =>\n (await coreCall((c) => c.currenciesGetTransactions(\n currencyKey,\n ))) as CurrencyTransaction[],\n },\n\n /** User inventory items + purchase/consume. */\n inventory: {\n getItems: async (): Promise<InventoryItem[]> =>\n (await coreCall((c) => c.inventoryGetItems())) as InventoryItem[],\n getItem: async (id: string): Promise<InventoryItem> =>\n (await coreCall((c) => c.inventoryGetItem(id))) as InventoryItem,\n purchase: async (request: PurchaseRequest): Promise<InventoryItem> =>\n (await coreCall((c) => c.inventoryPurchase(\n encodeJson(request),\n ))) as InventoryItem,\n consume: async (request: ConsumeRequest): Promise<InventoryItem> =>\n (await coreCall((c) => c.inventoryConsume(\n encodeJson(request),\n ))) as InventoryItem,\n },\n\n /** Score rankings. */\n leaderboards: {\n get: async (key: string): Promise<Leaderboard> =>\n (await coreCall((c) => c.leaderboardsGet(key))) as Leaderboard,\n getEntries: async (\n key: string,\n limit?: number,\n ): Promise<LeaderboardEntry[]> =>\n (await coreCall((c) => c.leaderboardsGetEntries(\n key,\n limit ?? undefined,\n ))) as LeaderboardEntry[],\n getMyRank: async (key: string): Promise<LeaderboardEntry> =>\n (await coreCall((c) => c.leaderboardsGetMyRank(key))) as LeaderboardEntry,\n },\n\n /**\n * Tiered weekly leaderboard cohorts (SDK 4.0). Each user is bucketed\n * into a small cohort (~25 members) within their league tier; the\n * top scorers each week promote and the bottom scorers demote.\n */\n leagues: {\n /**\n * `GET /v1/client/leagues/me` — the caller's active-cohort\n * standing plus live rank/score and member count.\n */\n me: async (): Promise<LeagueMembership> => {\n return (await coreCall((c) => c.leaguesMe())) as LeagueMembership;\n },\n /**\n * `GET /v1/client/leagues/me/cohort` — the caller's cohort with\n * every member's anonymised standing (display name, score, rank).\n * Notably no user ids — the server strips them so a leaderboard\n * UI can render the cohort without exposing identities.\n */\n cohort: async (): Promise<LeagueCohortView> => {\n return (await coreCall((c) => c.leaguesCohort())) as LeagueCohortView;\n },\n },\n\n /** Purchase storefronts. */\n stores: {\n list: async (): Promise<Store[]> =>\n (await coreCall((c) => c.storesList())) as Store[],\n getPurchaseOptions: async (storeKey: string): Promise<PurchaseOption[]> =>\n (await coreCall((c) => c.storesGetPurchaseOptions(\n storeKey,\n ))) as PurchaseOption[],\n purchase: async (\n storeKey: string,\n purchaseOptionId: string,\n receipt: unknown,\n ): Promise<PurchaseResult> =>\n // `JSON.stringify(undefined)` returns the JS value `undefined`,\n // not a string — passing that to the WASM `storesPurchase` binding\n // crashes. Default the missing-receipt case to an empty object so\n // the server still receives valid JSON (BugBot Low 2026-05-19).\n (await coreCall((c) => c.storesPurchase(\n storeKey,\n purchaseOptionId,\n encodeJson(receipt ?? {}),\n ))) as PurchaseResult,\n },\n\n /** Experience points + level system. */\n xp: {\n getBalance: async (): Promise<XpBalance> =>\n (await coreCall((c) => c.xpGetBalance())) as XpBalance,\n getHistory: async (limit?: number): Promise<XpTransaction[]> =>\n (await coreCall((c) => c.xpGetHistory(\n limit ?? undefined,\n ))) as XpTransaction[],\n claim: async (grantKey: string): Promise<XpTransaction> =>\n (await coreCall((c) => c.xpClaim(grantKey))) as XpTransaction,\n },\n\n /** Daily-engagement streaks. */\n streaks: {\n getAll: async (): Promise<Streak[]> =>\n (await coreCall((c) => c.streaksGetAll())) as Streak[],\n qualify: async (streakKey: string): Promise<Streak> =>\n (await coreCall((c) => c.streaksQualify(streakKey))) as Streak,\n },\n\n // ── Social ─────────────────────────────────────────────────────────\n\n /** Activity feeds. */\n feeds: {\n getActivity: async (\n feed?: string,\n cursor?: string,\n ): Promise<FeedResponse> =>\n (await coreCall((c) => c.feedsGetActivity(\n feed ?? undefined,\n cursor ?? undefined,\n ))) as FeedResponse,\n },\n\n /** Friend graph + block list. */\n friends: {\n getList: async (): Promise<Friendship[]> =>\n (await coreCall((c) => c.friendsGetList())) as Friendship[],\n getFriends: async (): Promise<Friendship[]> =>\n (await coreCall((c) => c.friendsGetFriends())) as Friendship[],\n /**\n * Send a friend request to `userId` (SDK 4.0). Returns the\n * resulting `Friendship` row in `pending` state.\n */\n sendRequest: async (userId: string): Promise<Friendship> =>\n (await coreCall((c) => c.friendsSendRequest(userId))) as Friendship,\n /**\n * Accept a pending incoming friend request (SDK 4.0). Pass the\n * friendship id from `getList()`.\n */\n acceptRequest: async (friendshipId: string): Promise<Friendship> =>\n (await coreCall((c) => c.friendsAcceptRequest(\n friendshipId,\n ))) as Friendship,\n /**\n * Decline a pending incoming friend request (SDK 4.0). Removes\n * the pending row; idempotent.\n */\n declineRequest: async (friendshipId: string): Promise<void> => {\n await coreCall((c) => c.friendsDeclineRequest(friendshipId));\n },\n blockUser: async (userId: string): Promise<Friendship> =>\n (await coreCall((c) => c.friendsBlockUser(userId))) as Friendship,\n unblockUser: async (userId: string): Promise<void> => {\n await coreCall((c) => c.friendsUnblockUser(userId));\n },\n removeBlock: async (friendshipId: string): Promise<void> => {\n await coreCall((c) => c.friendsRemoveBlock(friendshipId));\n },\n /**\n * Unfriend by the other user's id (SDK 4.0). Wraps\n * `DELETE /v1/client/friends/by-user/{userId}`. Server preserves\n * blocked rows; use `unblockUser` to clear those. 404 propagates\n * as `AmbaApiError`.\n */\n removeFriend: async (userId: string): Promise<void> => {\n await coreCall((c) => c.friendsRemoveFriend(userId));\n },\n },\n\n /** Multi-user groups. */\n groups: {\n create: async (params: GroupCreate): Promise<Group> =>\n (await coreCall((c) => c.groupsCreate(encodeJson(params)))) as Group,\n get: async (id: string): Promise<Group> =>\n (await coreCall((c) => c.groupsGet(id))) as Group,\n update: async (id: string, patch: GroupUpdate): Promise<Group> =>\n (await coreCall((c) => c.groupsUpdate(id, encodeJson(patch)))) as Group,\n delete: async (id: string): Promise<void> => {\n await coreCall((c) => c.groupsDelete(id));\n },\n getMembers: async (id: string): Promise<GroupMember[]> =>\n (await coreCall((c) => c.groupsGetMembers(id))) as GroupMember[],\n join: async (id: string): Promise<GroupMember> =>\n (await coreCall((c) => c.groupsJoin(id))) as GroupMember,\n leave: async (id: string): Promise<void> => {\n await coreCall((c) => c.groupsLeave(id));\n },\n invite: async (id: string, userId: string): Promise<GroupMember> =>\n (await coreCall((c) => c.groupsInvite(id, userId))) as GroupMember,\n },\n\n /**\n * User-to-user direct messaging.\n *\n * Paths mirror the API exactly — see `apps/api/src/routes/client/messaging.ts`:\n *\n * | SDK method | API route |\n * | --------------------- | -------------------------------------------------------- |\n * | `createConversation` | POST `/v1/client/messaging/conversations` |\n * | `getConversations` | GET `/v1/client/messaging/conversations` |\n * | `listConversations` | (alias for `getConversations`) |\n * | `sendMessage` | POST `/v1/client/messaging/conversations/:id/messages` |\n * | `listMessages` | GET `/v1/client/messaging/conversations/:id/messages` |\n * | `markRead` | POST `/v1/client/messaging/conversations/:id/read` |\n *\n * Task #62 corrected `sendMessage`'s path (it previously POSTed to\n * `/messaging/messages`, a route that doesn't exist on the API), and\n * added the four missing helpers. The previous `getMessage(id)` helper\n * has been removed — there is no GET-by-id route on the server; the\n * shape consumers actually want is `listMessages(conversationId, opts)`.\n */\n messaging: {\n /**\n * `POST /v1/client/messaging/conversations` — create (or fetch the\n * existing direct) conversation. For `type: \"direct\"` with exactly\n * one other participant, the server returns the existing row if\n * one already exists between these two users — calls are\n * idempotent.\n */\n createConversation: async (\n request: CreateConversationRequest,\n ): Promise<Conversation> =>\n (await coreCall((c) => c.messagingCreateConversation(\n encodeJson(request),\n ))) as Conversation,\n\n /**\n * `GET /v1/client/messaging/conversations` — list the caller's\n * conversations. Canonical 4.0 name; the legacy `getConversations`\n * / `listConversations` are removed in 4.0 per the spec.\n */\n conversations: async (): Promise<Conversation[]> =>\n (await coreCall((c) => c.messagingGetConversations())) as Conversation[],\n\n /**\n * `POST /v1/client/messaging/conversations/:conversationId/messages`\n * — send a message into an existing conversation. The\n * `conversation_id` argument is a path parameter (not a body\n * field) — the previous SDK shape mistakenly placed it in the\n * body, which the API ignored because the route was wrong anyway.\n */\n sendMessage: async (\n conversationId: string,\n request: SendMessageRequest,\n ): Promise<Message> =>\n // The engine ABI takes a single JSON arg with\n // `conversation_id` inline — we provide a cleaner two-positional\n // shape to TS callers and re-fold conversation_id into the\n // payload here. The engine extracts it before posting.\n (await coreCall((c) => c.messagingSendMessage(\n encodeJson({ ...request, conversation_id: conversationId }),\n ))) as Message,\n\n /**\n * `GET /v1/client/messaging/conversations/:conversationId/messages`\n * — list messages in a conversation. Pagination uses `?limit=&offset=`\n * (the server's `parsePagination` clamps both; defaults to 50 / 0).\n */\n listMessages: async (\n conversationId: string,\n opts?: ListMessagesOptions,\n ): Promise<Message[]> =>\n (await coreCall((c) => c.messagingListMessages(\n conversationId,\n opts?.limit ?? undefined,\n opts?.offset ?? undefined,\n ))) as Message[],\n\n /**\n * `GET /v1/client/messaging/conversations/:conversationId/messages/:messageId`\n * — fetch a single message by id. Returns `null` when the message\n * doesn't exist or the caller can't see it. (SDK 4.0: Phase A\n * shipped the missing `amba_messaging_get_message` core symbol the\n * native SDKs were already trying to call.)\n */\n getMessage: async (\n conversationId: string,\n messageId: string,\n ): Promise<Message | null> => {\n return (await coreCall((c) => c.messagingGetMessage(\n conversationId,\n messageId,\n ))) as Message | null;\n },\n\n /**\n * `POST /v1/client/messaging/conversations/:conversationId/participants`\n * — add a participant to an existing conversation. The caller must\n * already be a participant (the server returns `403\n * NOT_A_PARTICIPANT` otherwise) — this is the peer-invite path.\n * Idempotent: re-adding an existing member returns the existing\n * participant row, not an error. Enables dynamic membership growth\n * (e.g. a circle whose members qualify over time). Server-side\n * membership management (admin/matchmaker) uses the admin\n * add-participant endpoint instead.\n */\n addParticipant: async (\n conversationId: string,\n userId: string,\n ): Promise<ConversationParticipant> =>\n (await coreCall((c) => c.messagingAddParticipant(\n conversationId,\n userId,\n ))) as ConversationParticipant,\n\n /**\n * `POST /v1/client/messaging/conversations/:conversationId/read`\n * — bump the caller's `last_read_at` for the conversation. Returns\n * the updated participant row.\n */\n markRead: async (conversationId: string): Promise<MarkReadResult> =>\n (await coreCall((c) => c.messagingMarkRead(\n conversationId,\n ))) as MarkReadResult,\n\n /**\n * Live message subscriptions (SDK 4.0). Returns a builder — call\n * `.subscribe(cb)` to receive new messages in a conversation live\n * instead of polling `listMessages`. `subscribe` returns an\n * unsubscribe handle.\n *\n * @example\n * const unsub = Amba.messaging\n * .conversation(conversationId)\n * .subscribe((change) => {\n * // change.op === \"INSERT\"; change.row is the new message\n * appendMessageToThread(change.row);\n * });\n * // later: unsub();\n *\n * Delivery is scoped to conversation participants — you receive a\n * conversation's messages only if your session is a member of it.\n * Requires an authenticated session.\n */\n conversation: <T = Message>(conversationId: string): ConversationSubscription<T> =>\n new ConversationSubscription<T>(\n { baseUrl: _configuredApiUrl, authHeaders: realtimeAuthHeaders },\n conversationId,\n ),\n },\n\n /** Report users / content for moderation. */\n moderation: {\n reportUser: async (request: ReportRequest): Promise<Report> =>\n (await coreCall((c) => c.moderationReportUser(\n encodeJson(request),\n ))) as Report,\n reportContent: async (request: ReportRequest): Promise<Report> =>\n (await coreCall((c) => c.moderationReportContent(\n encodeJson(request),\n ))) as Report,\n getReportStatus: async (id: string): Promise<Report> =>\n (await coreCall((c) => c.moderationGetReportStatus(id))) as Report,\n },\n\n /** User reviews of catalog items or other users. */\n reviews: {\n list: async (targetType: string, targetId: string): Promise<Review[]> =>\n (await coreCall((c) => c.reviewsList(targetType, targetId))) as Review[],\n create: async (params: ReviewCreate): Promise<Review> =>\n (await coreCall((c) => c.reviewsCreate(encodeJson(params)))) as Review,\n update: async (id: string, patch: ReviewUpdate): Promise<Review> =>\n (await coreCall((c) => c.reviewsUpdate(id, encodeJson(patch)))) as Review,\n delete: async (id: string): Promise<void> => {\n await coreCall((c) => c.reviewsDelete(id));\n },\n },\n\n /** RBAC roles + permission checks. */\n roles: {\n getMyRoles: async (): Promise<Role[]> =>\n (await coreCall((c) => c.rolesGetMyRoles())) as Role[],\n hasPermission: async (permission: string): Promise<boolean> =>\n (await coreCall((c) => c.rolesHasPermission(permission))) as boolean,\n },\n\n /** Referral codes + claim flow. */\n referrals: {\n getReferralCode: async (): Promise<ReferralCode> =>\n (await coreCall((c) => c.referralsGetReferralCode())) as ReferralCode,\n claimReferral: async (code: string): Promise<ReferralClaim> =>\n (await coreCall((c) => c.referralsClaimReferral(code))) as ReferralClaim,\n create: async (\n code?: string,\n maxUses?: number,\n ): Promise<ReferralCode> =>\n (await coreCall((c) => c.referralsCreate(\n code ?? undefined,\n maxUses ?? undefined,\n ))) as ReferralCode,\n },\n\n // ── Lifecycle ──────────────────────────────────────────────────────\n\n /** Read-only product catalog. */\n catalog: {\n list: async (): Promise<CatalogItem[]> =>\n (await coreCall((c) => c.catalogList())) as CatalogItem[],\n /**\n * Fetch a single catalog item by id (SDK 4.0).\n * `GET /v1/client/catalog/:id`.\n */\n get: async (id: string): Promise<CatalogItem> =>\n (await coreCall((c) => c.catalogGet(id))) as CatalogItem,\n },\n\n /** Developer-defined content items (daily quotes, lessons, etc.). */\n content: {\n /**\n * Get today's published item for `channel`. Defaults to `\"default\"`\n * so single-channel apps can call `Amba.content.today()` bare.\n * (Canonical 4.0 name; legacy `getToday` is removed.)\n */\n today: async (channel: string = \"default\"): Promise<ContentItem | null> =>\n (await coreCall((c) => c.contentGetToday(channel))) as ContentItem | null,\n /**\n * Paginated library list for `channel`. `options.limit` caps page size\n * (server default applies when omitted); `options.cursor` is the\n * opaque token returned by a prior response's `next_cursor`.\n * (Canonical 4.0 name; legacy `getLibrary` is removed.)\n */\n library: async (\n channel: string = \"default\",\n options?: { limit?: number; cursor?: string },\n ): Promise<ContentItem[]> =>\n (await coreCall((c) => c.contentGetLibrary(\n channel,\n options?.limit ?? undefined,\n options?.cursor ?? undefined,\n ))) as ContentItem[],\n item: async (id: string): Promise<ContentItem> =>\n (await coreCall((c) => c.contentGetItem(id))) as ContentItem,\n updateItem: async (id: string, state: unknown): Promise<ContentItem> =>\n (await coreCall((c) => c.contentUpdateItem(\n id,\n encodeJson(state),\n ))) as ContentItem,\n createItem: async (\n channel: string,\n item: unknown,\n ): Promise<ContentItem> =>\n (await coreCall((c) => c.contentCreateItem(\n channel,\n encodeJson(item),\n ))) as ContentItem,\n },\n\n /** Server-managed deep link records. */\n deepLinks: {\n get: async (shortCode: string): Promise<DeepLink> =>\n (await coreCall((c) => c.deepLinksGet(shortCode))) as DeepLink,\n create: async (params: DeepLinkCreate): Promise<DeepLink> =>\n (await coreCall((c) => c.deepLinksCreate(encodeJson(params)))) as DeepLink,\n },\n\n /** Step-by-step user onboarding flow. */\n onboarding: {\n getStatus: async (): Promise<OnboardingStatus> =>\n (await coreCall((c) => c.onboardingGetStatus())) as OnboardingStatus,\n nextStep: async (payload: unknown): Promise<OnboardingStatus> =>\n (await coreCall((c) => c.onboardingNextStep(\n encodeJson(payload),\n ))) as OnboardingStatus,\n skipStep: async (): Promise<OnboardingStatus> =>\n (await coreCall((c) => c.onboardingSkipStep())) as OnboardingStatus,\n complete: async (): Promise<OnboardingStatus> =>\n (await coreCall((c) => c.onboardingComplete())) as OnboardingStatus,\n },\n\n};\n\n/** Escape hatch — the raw SDK runtime handle, for namespaces not yet wrapped. */\nexport function getCoreWasm(): AmbaCoreWasm {\n return requireCore();\n}\n\n/**\n * Package version stamped at build time. Sent in the\n * `sdk_wrapper_version` header on every customer request.\n *\n * **Must match `package.json#version` exactly** — the\n * `verify-sdk-version-coherence` GH action gates every publish on the\n * pair agreeing (and matching the `web-v<X.Y.Z>` tag when tag-triggered).\n */\nexport const SDK_VERSION = \"4.0.4\";\n"],"mappings":"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"}
|
package/dist-rn/index.d.ts
CHANGED
|
@@ -19,6 +19,16 @@ interface AmbaConfig {
|
|
|
19
19
|
* Defaults to `"https://api.amba.dev"`.
|
|
20
20
|
*/
|
|
21
21
|
apiUrl?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Base URL for `Amba.functions.invoke()`. Set this to call your deployed
|
|
24
|
+
* functions through a custom domain or a non-prod environment, e.g.
|
|
25
|
+
* `"https://api.example.com"` or `"https://<id>.staging.fn.amba.host"`.
|
|
26
|
+
* `invoke(name, body)` POSTs to `"<functionsBaseUrl>/<name>"`.
|
|
27
|
+
*
|
|
28
|
+
* When omitted, the SDK resolves the default host automatically on first
|
|
29
|
+
* use (one cached round-trip) — no configuration needed for production.
|
|
30
|
+
*/
|
|
31
|
+
functionsBaseUrl?: string;
|
|
22
32
|
/**
|
|
23
33
|
* If `true`, blocks all telemetry until `setConsent(granted)` is called.
|
|
24
34
|
* Required for SOC2 / GDPR strict modes.
|
|
@@ -267,17 +277,23 @@ interface ChallengeProgress {
|
|
|
267
277
|
claimed_at?: string | null;
|
|
268
278
|
}
|
|
269
279
|
interface CurrencyBalance {
|
|
270
|
-
|
|
271
|
-
|
|
280
|
+
currency_code: string;
|
|
281
|
+
name: string;
|
|
282
|
+
is_premium: boolean;
|
|
272
283
|
balance: number;
|
|
273
|
-
|
|
284
|
+
lifetime_earned: number;
|
|
285
|
+
lifetime_spent: number;
|
|
274
286
|
}
|
|
275
287
|
interface CurrencyTransaction {
|
|
276
288
|
id: string;
|
|
277
|
-
|
|
278
|
-
|
|
289
|
+
app_user_id?: string;
|
|
290
|
+
currency_code: string;
|
|
291
|
+
amount: number;
|
|
279
292
|
balance_after: number;
|
|
280
|
-
|
|
293
|
+
transaction_type?: string;
|
|
294
|
+
source?: string;
|
|
295
|
+
reference_id?: string | null;
|
|
296
|
+
idempotency_key?: string | null;
|
|
281
297
|
created_at: string;
|
|
282
298
|
}
|
|
283
299
|
interface InventoryItem {
|
|
@@ -688,6 +704,8 @@ interface LeagueCohortMember {
|
|
|
688
704
|
display_name?: string | null;
|
|
689
705
|
score: number;
|
|
690
706
|
rank: number;
|
|
707
|
+
/** `true` for the requesting user's own row (server-derived; no id leak). */
|
|
708
|
+
is_me?: boolean;
|
|
691
709
|
}
|
|
692
710
|
interface LeagueMembership {
|
|
693
711
|
cohort: LeagueCohort | null;
|
|
@@ -852,6 +870,13 @@ declare class AmbaApiError extends Error {
|
|
|
852
870
|
}
|
|
853
871
|
//#endregion
|
|
854
872
|
//#region src/index.d.ts
|
|
873
|
+
/** Options for `Amba.functions.invoke`. */
|
|
874
|
+
interface InvokeOptions {
|
|
875
|
+
/** HTTP method. Defaults to `"POST"`. */
|
|
876
|
+
method?: "POST" | "GET" | "PUT" | "PATCH" | "DELETE";
|
|
877
|
+
/** Extra headers merged on top of the injected auth headers. */
|
|
878
|
+
headers?: Record<string, string>;
|
|
879
|
+
}
|
|
855
880
|
/**
|
|
856
881
|
* Top-level SDK namespace.
|
|
857
882
|
*
|
|
@@ -1009,6 +1034,32 @@ declare const Amba: {
|
|
|
1009
1034
|
* code is `EMAIL_ALREADY_LINKED`.
|
|
1010
1035
|
*/
|
|
1011
1036
|
linkEmailOtp: (email: string, code: string) => Promise<User>;
|
|
1037
|
+
/**
|
|
1038
|
+
* Upgrade an anonymous (or any current) session by attaching an
|
|
1039
|
+
* email + password credential — converting the current user in place
|
|
1040
|
+
* to an email-identified account so its data (streak, library,
|
|
1041
|
+
* progress, `anonymous_id`) is preserved rather than minting a new
|
|
1042
|
+
* user.
|
|
1043
|
+
*
|
|
1044
|
+
* Guarantees (symmetric to `linkEmailOtp`):
|
|
1045
|
+
*
|
|
1046
|
+
* - **Same `user_id`** before and after.
|
|
1047
|
+
* - **Session token unchanged.** No rotation; `onAuthStateChange`
|
|
1048
|
+
* does NOT fire.
|
|
1049
|
+
* - **Idempotent.** Re-linking the same email to the same user
|
|
1050
|
+
* succeeds.
|
|
1051
|
+
* - **Collision.** If the email is already owned by a different user,
|
|
1052
|
+
* throws an error with `code = "EMAIL_ALREADY_LINKED"` and
|
|
1053
|
+
* `details.conflicting_user_id` populated.
|
|
1054
|
+
*
|
|
1055
|
+
* After linking, the user can sign in with `signInWithEmail(email,
|
|
1056
|
+
* password)`. Requires an active session — throws `UNAUTHORIZED`
|
|
1057
|
+
* otherwise.
|
|
1058
|
+
*
|
|
1059
|
+
* @returns the updated user record (with `email` set and
|
|
1060
|
+
* `email_verified = true`).
|
|
1061
|
+
*/
|
|
1062
|
+
linkEmailPassword: (email: string, password: string) => Promise<User>;
|
|
1012
1063
|
/**
|
|
1013
1064
|
* Detach the SMS-OTP identifier from the current session's user.
|
|
1014
1065
|
* Refused with `LAST_IDENTIFIER` if this would leave the account
|
|
@@ -1242,6 +1293,31 @@ declare const Amba: {
|
|
|
1242
1293
|
};
|
|
1243
1294
|
};
|
|
1244
1295
|
};
|
|
1296
|
+
/**
|
|
1297
|
+
* Invoke a deployed function by name, with the project's client key (and
|
|
1298
|
+
* the live session token, if any) injected automatically.
|
|
1299
|
+
*
|
|
1300
|
+
* This is the authenticated way to call your functions — prefer it over
|
|
1301
|
+
* hand-rolling `fetch` against a function URL, which leaves the call
|
|
1302
|
+
* unauthenticated (a footgun when the function holds secrets).
|
|
1303
|
+
*
|
|
1304
|
+
* @example
|
|
1305
|
+
* const result = await Amba.functions.invoke<{ ok: boolean }>(
|
|
1306
|
+
* 'send_welcome_email',
|
|
1307
|
+
* { to: 'user@example.com' },
|
|
1308
|
+
* );
|
|
1309
|
+
*
|
|
1310
|
+
* @param name The deployed function name.
|
|
1311
|
+
* @param body JSON-serializable request body (omitted for GET).
|
|
1312
|
+
* @param options Method + extra headers.
|
|
1313
|
+
* @returns The parsed JSON response (or the raw text if not JSON).
|
|
1314
|
+
* @throws AmbaApiError on a network failure or a non-2xx response. When
|
|
1315
|
+
* the function / router returns the standard `{ error: { code, message } }`
|
|
1316
|
+
* envelope, those surface as the thrown error's `code` + `message`.
|
|
1317
|
+
*/
|
|
1318
|
+
functions: {
|
|
1319
|
+
invoke: <T = unknown>(name: string, body?: unknown, options?: InvokeOptions) => Promise<T>;
|
|
1320
|
+
};
|
|
1245
1321
|
/** Remote config bundle. */
|
|
1246
1322
|
config: {
|
|
1247
1323
|
fetch: () => Promise<ConfigBundle>;
|
|
@@ -1559,7 +1635,7 @@ declare function getCoreWasm(): AmbaCoreWasm;
|
|
|
1559
1635
|
* `verify-sdk-version-coherence` GH action gates every publish on the
|
|
1560
1636
|
* pair agreeing (and matching the `web-v<X.Y.Z>` tag when tag-triggered).
|
|
1561
1637
|
*/
|
|
1562
|
-
declare const SDK_VERSION = "4.0.
|
|
1638
|
+
declare const SDK_VERSION = "4.0.4";
|
|
1563
1639
|
//#endregion
|
|
1564
|
-
export { Achievement, AchievementProgress, AiMessage, AiMessageRequest, AiMessageResponse, AiUsage, Amba, AmbaApiError, type AmbaApiErrorCode, AmbaConfig, AndFilter, AppSession, AuthResult, CatalogItem, Challenge, ChallengeProgress, CollectionSubscription, ConditionFilter, ConfigBundle, ConsumeRequest, ContentItem, Conversation, ConversationParticipant, ConversationSubscription, ConversationType, CreateConversationRequest, CurrencyBalance, CurrencyTransaction, DeepLink, DeepLinkCreate, DiagnosticsEnvironment, EntitlementSource, FeedItem, FeedResponse, Filter, FilterValue, FindOptions, FindResponse, FlagAssignment, Friendship, FriendshipState, Group, GroupCreate, GroupMember, GroupUpdate, InventoryItem, Leaderboard, LeaderboardEntry, LeagueCohort, LeagueCohortMember, LeagueCohortView, LeagueMembership, LeagueTier, LinkedIdentifier, ListMessagesOptions, MarkReadResult, MediaAsset, MediaListResponse, Message, type MessageChange, MessageType, NearestOptions, NearestResponse, NotFilter, OnboardingStatus, OrFilter, OrderBy, PingResult, PresignData, PullChangesCursor, PullChangesResult, PurchaseOption, PurchaseRequest, PurchaseResult, PushChangesResult, PushPlatform, PushToken, type RealtimeChange, ReferralClaim, ReferralCode, Report, ReportRequest, Review, ReviewCreate, ReviewUpdate, Role, type RowChangeOp, SDK_VERSION, SendMessageRequest, Session, SocialProvider, Store, Streak, type SubscribeOptions, SyncChange, SyncConflict, type Unsubscribe, User, UserEntitlement, XpBalance, XpTransaction, getCoreWasm };
|
|
1640
|
+
export { Achievement, AchievementProgress, AiMessage, AiMessageRequest, AiMessageResponse, AiUsage, Amba, AmbaApiError, type AmbaApiErrorCode, AmbaConfig, AndFilter, AppSession, AuthResult, CatalogItem, Challenge, ChallengeProgress, CollectionSubscription, ConditionFilter, ConfigBundle, ConsumeRequest, ContentItem, Conversation, ConversationParticipant, ConversationSubscription, ConversationType, CreateConversationRequest, CurrencyBalance, CurrencyTransaction, DeepLink, DeepLinkCreate, DiagnosticsEnvironment, EntitlementSource, FeedItem, FeedResponse, Filter, FilterValue, FindOptions, FindResponse, FlagAssignment, Friendship, FriendshipState, Group, GroupCreate, GroupMember, GroupUpdate, InventoryItem, InvokeOptions, Leaderboard, LeaderboardEntry, LeagueCohort, LeagueCohortMember, LeagueCohortView, LeagueMembership, LeagueTier, LinkedIdentifier, ListMessagesOptions, MarkReadResult, MediaAsset, MediaListResponse, Message, type MessageChange, MessageType, NearestOptions, NearestResponse, NotFilter, OnboardingStatus, OrFilter, OrderBy, PingResult, PresignData, PullChangesCursor, PullChangesResult, PurchaseOption, PurchaseRequest, PurchaseResult, PushChangesResult, PushPlatform, PushToken, type RealtimeChange, ReferralClaim, ReferralCode, Report, ReportRequest, Review, ReviewCreate, ReviewUpdate, Role, type RowChangeOp, SDK_VERSION, SendMessageRequest, Session, SocialProvider, Store, Streak, type SubscribeOptions, SyncChange, SyncConflict, type Unsubscribe, User, UserEntitlement, XpBalance, XpTransaction, getCoreWasm };
|
|
1565
1641
|
//# sourceMappingURL=index.d.ts.map
|
package/dist-rn/index.js
CHANGED
|
@@ -259,6 +259,14 @@ var ConversationSubscription = class {
|
|
|
259
259
|
//#region src/index.ts
|
|
260
260
|
const DEFAULT_API_URL = "https://api.amba.dev";
|
|
261
261
|
/**
|
|
262
|
+
* Default host that serves deployed functions. `Amba.functions.invoke(name)`
|
|
263
|
+
* targets `https://<projectId>.<DEFAULT_FUNCTIONS_HOST>/<name>` unless a
|
|
264
|
+
* `functionsBaseUrl` override is configured. The `<projectId>` label is the
|
|
265
|
+
* server-resolved id (from `diagnostics.ping`), which the function router
|
|
266
|
+
* accepts directly.
|
|
267
|
+
*/
|
|
268
|
+
const DEFAULT_FUNCTIONS_HOST = "fn.amba.host";
|
|
269
|
+
/**
|
|
262
270
|
* Internal state — one instance per page. Created lazily by `Amba.configure()`.
|
|
263
271
|
*/
|
|
264
272
|
let coreInstance = null;
|
|
@@ -279,6 +287,15 @@ let _configuredProjectId = null;
|
|
|
279
287
|
let _configuredApiUrl = DEFAULT_API_URL;
|
|
280
288
|
let _configuredClientKey = null;
|
|
281
289
|
let _currentSessionToken = null;
|
|
290
|
+
/**
|
|
291
|
+
* Functions invocation state. `_configuredFunctionsBaseUrl` is the optional
|
|
292
|
+
* override from `Amba.configure({ functionsBaseUrl })`. When it's null, the
|
|
293
|
+
* default-host path resolves the project id once via `diagnostics.ping` and
|
|
294
|
+
* caches it in `_resolvedFunctionsProjectId` so subsequent invokes skip the
|
|
295
|
+
* round-trip. Both reset on every `configure()`.
|
|
296
|
+
*/
|
|
297
|
+
let _configuredFunctionsBaseUrl = null;
|
|
298
|
+
let _resolvedFunctionsProjectId = null;
|
|
282
299
|
function requireCore() {
|
|
283
300
|
if (!coreInstance) throw new AmbaApiError("NOT_INITIALIZED", "amba SDK not configured. Call Amba.configure({ projectId, clientKey }) at app start before any other API.");
|
|
284
301
|
return coreInstance;
|
|
@@ -332,6 +349,24 @@ function realtimeAuthHeaders() {
|
|
|
332
349
|
};
|
|
333
350
|
}
|
|
334
351
|
/**
|
|
352
|
+
* Resolve the full invocation URL for a deployed function.
|
|
353
|
+
*
|
|
354
|
+
* With `functionsBaseUrl` configured we POST to `<base>/<name>` verbatim
|
|
355
|
+
* (custom domains / non-prod). Otherwise we resolve the server-side project
|
|
356
|
+
* id once (via `diagnostics.ping`, cached) and target
|
|
357
|
+
* `https://<projectId>.fn.amba.host/<name>` — the function router accepts the
|
|
358
|
+
* project id as the host label directly.
|
|
359
|
+
*/
|
|
360
|
+
async function resolveFunctionUrl(name) {
|
|
361
|
+
if (_configuredFunctionsBaseUrl) return `${_configuredFunctionsBaseUrl.replace(/\/$/, "")}/${encodeURIComponent(name)}`;
|
|
362
|
+
if (!_resolvedFunctionsProjectId) {
|
|
363
|
+
const ping = await Amba.diagnostics.ping();
|
|
364
|
+
if (!ping.ok || !ping.server_project_id) throw new AmbaApiError("FUNCTIONS_HOST_UNRESOLVED", "Could not resolve the functions host for this project. Pass `functionsBaseUrl` to Amba.configure() to invoke functions explicitly.", ping);
|
|
365
|
+
_resolvedFunctionsProjectId = ping.server_project_id;
|
|
366
|
+
}
|
|
367
|
+
return `https://${_resolvedFunctionsProjectId}.${DEFAULT_FUNCTIONS_HOST}/${encodeURIComponent(name)}`;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
335
370
|
* Top-level SDK namespace.
|
|
336
371
|
*
|
|
337
372
|
* Stateless from the JS side — all state lives in the SDK runtime. Calling
|
|
@@ -359,6 +394,8 @@ const Amba = {
|
|
|
359
394
|
_configuredProjectId = config.projectId;
|
|
360
395
|
_configuredApiUrl = config.apiUrl ?? DEFAULT_API_URL;
|
|
361
396
|
_configuredClientKey = config.clientKey;
|
|
397
|
+
_configuredFunctionsBaseUrl = config.functionsBaseUrl ?? null;
|
|
398
|
+
_resolvedFunctionsProjectId = null;
|
|
362
399
|
},
|
|
363
400
|
get projectId() {
|
|
364
401
|
if (!_configuredProjectId) throw new AmbaApiError("NOT_INITIALIZED", "amba SDK not configured. Call Amba.configure({ projectId, clientKey }) at app start before any other API.");
|
|
@@ -440,6 +477,9 @@ const Amba = {
|
|
|
440
477
|
linkEmailOtp: async (email, code) => {
|
|
441
478
|
return await coreCall((c) => c.linkEmailOtp(email, code));
|
|
442
479
|
},
|
|
480
|
+
linkEmailPassword: async (email, password) => {
|
|
481
|
+
return await coreCall((c) => c.linkEmailPassword(email, password));
|
|
482
|
+
},
|
|
443
483
|
unlinkSmsOtp: async () => {
|
|
444
484
|
return await coreCall((c) => c.unlinkSmsOtp());
|
|
445
485
|
},
|
|
@@ -662,6 +702,45 @@ const Amba = {
|
|
|
662
702
|
ai: { anthropic: { messages: { create: async (request) => {
|
|
663
703
|
return await coreCall((c) => c.aiAnthropicMessages(encodeJson(request)));
|
|
664
704
|
} } } },
|
|
705
|
+
functions: { invoke: async (name, body, options) => {
|
|
706
|
+
requireCore();
|
|
707
|
+
if (!_configuredClientKey) throw new AmbaApiError("NOT_INITIALIZED", "amba SDK not configured. Call Amba.configure({ projectId, clientKey }) before Amba.functions.invoke().");
|
|
708
|
+
if (!name || name.trim() === "") throw new AmbaApiError("INVALID_ARGUMENT", "Amba.functions.invoke: a function name is required.");
|
|
709
|
+
const url = await resolveFunctionUrl(name);
|
|
710
|
+
const method = options?.method ?? "POST";
|
|
711
|
+
const headers = {
|
|
712
|
+
"X-Api-Key": _configuredClientKey,
|
|
713
|
+
...options?.headers ?? {}
|
|
714
|
+
};
|
|
715
|
+
if (_currentSessionToken) headers["Authorization"] = `Bearer ${_currentSessionToken}`;
|
|
716
|
+
let requestBody;
|
|
717
|
+
if (body !== void 0 && method !== "GET") {
|
|
718
|
+
headers["content-type"] = "application/json";
|
|
719
|
+
requestBody = JSON.stringify(body);
|
|
720
|
+
}
|
|
721
|
+
let resp;
|
|
722
|
+
try {
|
|
723
|
+
resp = await fetch(url, {
|
|
724
|
+
method,
|
|
725
|
+
headers,
|
|
726
|
+
body: requestBody
|
|
727
|
+
});
|
|
728
|
+
} catch (err) {
|
|
729
|
+
throw new AmbaApiError("NETWORK_ERROR", `Amba.functions.invoke("${name}") network error: ${String(err)}`);
|
|
730
|
+
}
|
|
731
|
+
const text = await resp.text();
|
|
732
|
+
let parsed = void 0;
|
|
733
|
+
if (text.length > 0) try {
|
|
734
|
+
parsed = JSON.parse(text);
|
|
735
|
+
} catch {
|
|
736
|
+
parsed = text;
|
|
737
|
+
}
|
|
738
|
+
if (!resp.ok) {
|
|
739
|
+
const envelope = parsed && typeof parsed === "object" ? parsed : void 0;
|
|
740
|
+
throw new AmbaApiError(typeof envelope?.error?.code === "string" ? envelope.error.code : `HTTP_${resp.status}`, typeof envelope?.error?.message === "string" ? envelope.error.message : typeof parsed === "string" && parsed.length > 0 ? parsed : `Amba.functions.invoke("${name}") failed with status ${resp.status}`, parsed);
|
|
741
|
+
}
|
|
742
|
+
return parsed;
|
|
743
|
+
} },
|
|
665
744
|
config: { fetch: async () => {
|
|
666
745
|
return await coreCall((c) => c.configFetch());
|
|
667
746
|
} },
|
|
@@ -831,7 +910,7 @@ function getCoreWasm() {
|
|
|
831
910
|
* `verify-sdk-version-coherence` GH action gates every publish on the
|
|
832
911
|
* pair agreeing (and matching the `web-v<X.Y.Z>` tag when tag-triggered).
|
|
833
912
|
*/
|
|
834
|
-
const SDK_VERSION = "4.0.
|
|
913
|
+
const SDK_VERSION = "4.0.4";
|
|
835
914
|
|
|
836
915
|
//#endregion
|
|
837
916
|
export { Amba, AmbaApiError, CollectionSubscription, ConversationSubscription, SDK_VERSION, getCoreWasm };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@layers/amba-web",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.4",
|
|
4
4
|
"description": "amba SDK for browser apps — full SDK 4.0 surface (34 modules: auth + magic link, users, sessions, sync, collections + vector search, storage + list/delete/download, push, entitlements, flags, config, deep links, onboarding, content, messaging, friends, groups, feeds, reviews, moderation, roles, referrals, achievements, xp, streaks, challenges, leaderboards, leagues, currencies, inventory, stores, catalog, ai, diagnostics).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"sideEffects": false,
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@layers/amba-core": "^4.0.
|
|
35
|
+
"@layers/amba-core": "^4.0.4"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "^22.13.14",
|