@layers/amba-react-native 4.0.4 → 4.0.6
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.cjs +82 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +118 -16
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +118 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +82 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -831,6 +831,18 @@ const notifications = {
|
|
|
831
831
|
//#region src/realtime.ts
|
|
832
832
|
const INITIAL_BACKOFF_MS = 500;
|
|
833
833
|
const MAX_BACKOFF_MS = 15e3;
|
|
834
|
+
const DEFAULT_API_URL = "https://api.amba.dev";
|
|
835
|
+
const DEFAULT_REALTIME_URL = "https://realtime.amba.host";
|
|
836
|
+
/**
|
|
837
|
+
* Resolve the base URL for live-update connections. Long-lived streams are
|
|
838
|
+
* served from a dedicated realtime host (no request-duration ceiling), so
|
|
839
|
+
* when the SDK points at the default production API the stream connects
|
|
840
|
+
* there instead. Any custom `apiUrl` (dev, staging, self-hosted, proxy)
|
|
841
|
+
* keeps live updates on that same origin — override semantics unchanged.
|
|
842
|
+
*/
|
|
843
|
+
function resolveRealtimeBaseUrl(baseUrl) {
|
|
844
|
+
return baseUrl.replace(/\/+$/, "") === DEFAULT_API_URL ? DEFAULT_REALTIME_URL : baseUrl;
|
|
845
|
+
}
|
|
834
846
|
/**
|
|
835
847
|
* Builder returned by `Amba.collection(name)`. Chain `.where(...)` to
|
|
836
848
|
* narrow, then `.subscribe(cb)` to start streaming.
|
|
@@ -854,7 +866,7 @@ var CollectionSubscription = class {
|
|
|
854
866
|
if (!this.ctx.authHeaders()) throw new Error("Amba.collection().subscribe() requires an authenticated session — call Amba.auth.signIn* first.");
|
|
855
867
|
const qs = Object.keys(this.filters).length > 0 ? `?where=${encodeURIComponent(JSON.stringify(this.filters))}` : "";
|
|
856
868
|
return openStream({
|
|
857
|
-
url: `${this.ctx.baseUrl}/v1/client/realtime/collections/${encodeURIComponent(this.name)}${qs}`,
|
|
869
|
+
url: `${resolveRealtimeBaseUrl(this.ctx.baseUrl)}/v1/client/realtime/collections/${encodeURIComponent(this.name)}${qs}`,
|
|
858
870
|
authHeaders: this.ctx.authHeaders,
|
|
859
871
|
onChange: cb,
|
|
860
872
|
options,
|
|
@@ -878,7 +890,7 @@ var ConversationSubscription = class {
|
|
|
878
890
|
subscribe(cb, options = {}) {
|
|
879
891
|
if (!this.ctx.authHeaders()) throw new Error("Amba.messaging.conversation().subscribe() requires an authenticated session — call Amba.auth.signIn* first.");
|
|
880
892
|
return openStream({
|
|
881
|
-
url: `${this.ctx.baseUrl}/v1/client/realtime/conversations/${encodeURIComponent(this.conversationId)}`,
|
|
893
|
+
url: `${resolveRealtimeBaseUrl(this.ctx.baseUrl)}/v1/client/realtime/conversations/${encodeURIComponent(this.conversationId)}`,
|
|
882
894
|
authHeaders: this.ctx.authHeaders,
|
|
883
895
|
onChange: cb,
|
|
884
896
|
options,
|
|
@@ -902,7 +914,7 @@ var GamificationSubscription = class {
|
|
|
902
914
|
subscribe(cb, options = {}) {
|
|
903
915
|
if (!this.ctx.authHeaders()) throw new Error("Amba.gamification.subscribe() requires an authenticated session — call Amba.auth.signIn* first.");
|
|
904
916
|
return openStream({
|
|
905
|
-
url: `${this.ctx.baseUrl}/v1/client/realtime/gamification`,
|
|
917
|
+
url: `${resolveRealtimeBaseUrl(this.ctx.baseUrl)}/v1/client/realtime/gamification`,
|
|
906
918
|
authHeaders: this.ctx.authHeaders,
|
|
907
919
|
onChange: cb,
|
|
908
920
|
options,
|
|
@@ -1138,7 +1150,7 @@ function delay(ms) {
|
|
|
1138
1150
|
//#endregion
|
|
1139
1151
|
//#region src/index.ts
|
|
1140
1152
|
/** SDK semver — burned in at build time. Bump alongside package.json. */
|
|
1141
|
-
const SDK_VERSION = "4.0.
|
|
1153
|
+
const SDK_VERSION = "4.0.6";
|
|
1142
1154
|
/**
|
|
1143
1155
|
* Default host that serves deployed functions. `Amba.functions.invoke(name)`
|
|
1144
1156
|
* targets `https://<projectId>.<DEFAULT_FUNCTIONS_HOST>/<name>` unless a
|
|
@@ -1190,6 +1202,58 @@ function notifyAuthSubscribers(session) {
|
|
|
1190
1202
|
if (typeof console !== "undefined") console.error("[amba] onAuthStateChange callback threw", err);
|
|
1191
1203
|
}
|
|
1192
1204
|
}
|
|
1205
|
+
function normalizeAuthProviderNames(value) {
|
|
1206
|
+
let normalized = value;
|
|
1207
|
+
if (typeof normalized === "string") {
|
|
1208
|
+
const trimmed = normalized.trim();
|
|
1209
|
+
if (trimmed === "") return [];
|
|
1210
|
+
try {
|
|
1211
|
+
normalized = JSON.parse(trimmed);
|
|
1212
|
+
} catch {
|
|
1213
|
+
return [normalized];
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
if (!Array.isArray(normalized)) {
|
|
1217
|
+
if (normalized && typeof normalized === "object") {
|
|
1218
|
+
const provider = normalized.provider;
|
|
1219
|
+
return typeof provider === "string" ? [provider] : [];
|
|
1220
|
+
}
|
|
1221
|
+
return [];
|
|
1222
|
+
}
|
|
1223
|
+
return normalized.map((entry) => {
|
|
1224
|
+
if (typeof entry === "string") {
|
|
1225
|
+
const trimmed = entry.trim();
|
|
1226
|
+
if (trimmed === "") return null;
|
|
1227
|
+
try {
|
|
1228
|
+
const parsed = JSON.parse(trimmed);
|
|
1229
|
+
if (parsed && typeof parsed === "object") {
|
|
1230
|
+
const provider = parsed.provider;
|
|
1231
|
+
return typeof provider === "string" ? provider : null;
|
|
1232
|
+
}
|
|
1233
|
+
} catch {
|
|
1234
|
+
return entry;
|
|
1235
|
+
}
|
|
1236
|
+
return entry;
|
|
1237
|
+
}
|
|
1238
|
+
if (entry && typeof entry === "object") {
|
|
1239
|
+
const provider = entry.provider;
|
|
1240
|
+
return typeof provider === "string" ? provider : null;
|
|
1241
|
+
}
|
|
1242
|
+
return null;
|
|
1243
|
+
}).filter((provider) => provider !== null);
|
|
1244
|
+
}
|
|
1245
|
+
function normalizeUserAuthProviders(user) {
|
|
1246
|
+
return {
|
|
1247
|
+
...user,
|
|
1248
|
+
auth_providers: normalizeAuthProviderNames(user.auth_providers)
|
|
1249
|
+
};
|
|
1250
|
+
}
|
|
1251
|
+
function normalizeAuthResult(result) {
|
|
1252
|
+
return {
|
|
1253
|
+
...result,
|
|
1254
|
+
user: normalizeUserAuthProviders(result.user)
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
1193
1257
|
async function notifyFromAuthResult(result) {
|
|
1194
1258
|
notifyAuthSubscribers(snapshotSession(result.user));
|
|
1195
1259
|
}
|
|
@@ -1206,7 +1270,7 @@ async function persistAuthResult(state_, result) {
|
|
|
1206
1270
|
});
|
|
1207
1271
|
}
|
|
1208
1272
|
async function postAuth(state_, path, body) {
|
|
1209
|
-
const result = (await state_.http.post(path, body)).data;
|
|
1273
|
+
const result = normalizeAuthResult((await state_.http.post(path, body)).data);
|
|
1210
1274
|
await persistAuthResult(state_, result);
|
|
1211
1275
|
await notifyFromAuthResult(result);
|
|
1212
1276
|
return result;
|
|
@@ -1238,7 +1302,7 @@ async function ensureAnonymousSession(state_) {
|
|
|
1238
1302
|
* Existing session tokens stay untouched.
|
|
1239
1303
|
*/
|
|
1240
1304
|
async function postUserNoRotate(state_, path, body) {
|
|
1241
|
-
return (await state_.http.post(path, body)).data.user;
|
|
1305
|
+
return normalizeUserAuthProviders((await state_.http.post(path, body)).data.user);
|
|
1242
1306
|
}
|
|
1243
1307
|
async function unlinkProvider(provider) {
|
|
1244
1308
|
const s = getState();
|
|
@@ -1298,6 +1362,8 @@ const P = {
|
|
|
1298
1362
|
pushSubscribe: "/v1/client/push/subscribe",
|
|
1299
1363
|
pushUnsubscribe: "/v1/client/push/unsubscribe",
|
|
1300
1364
|
entitlements: "/v1/client/entitlements",
|
|
1365
|
+
entitlementsRestore: "/v1/client/entitlements/restore",
|
|
1366
|
+
offerings: "/v1/client/offerings",
|
|
1301
1367
|
aiAnthropic: "/v1/client/ai/anthropic/messages",
|
|
1302
1368
|
config: "/v1/client/config",
|
|
1303
1369
|
flags: "/v1/client/flags",
|
|
@@ -1652,12 +1718,12 @@ const Amba = {
|
|
|
1652
1718
|
me: async () => {
|
|
1653
1719
|
const s = getState();
|
|
1654
1720
|
if (!s.identity.getSessionToken()) throw new AmbaApiError("UNAUTHORIZED", "no active session — call signIn* first");
|
|
1655
|
-
return (await s.http.get(P.authMe)).data;
|
|
1721
|
+
return normalizeUserAuthProviders((await s.http.get(P.authMe)).data);
|
|
1656
1722
|
},
|
|
1657
1723
|
getSession: async () => {
|
|
1658
1724
|
const s = getState();
|
|
1659
1725
|
if (!s.identity.isAuthenticated()) return null;
|
|
1660
|
-
return snapshotSession((await s.http.get(P.authMe)).data);
|
|
1726
|
+
return snapshotSession(normalizeUserAuthProviders((await s.http.get(P.authMe)).data));
|
|
1661
1727
|
},
|
|
1662
1728
|
getAnonymousId: async () => {
|
|
1663
1729
|
return getState().identity.getAnonymousId();
|
|
@@ -1674,7 +1740,7 @@ const Amba = {
|
|
|
1674
1740
|
const s = getState();
|
|
1675
1741
|
if (!s.identity.getSessionToken()) throw new AmbaApiError("UNAUTHORIZED", "no active session — call signIn* first");
|
|
1676
1742
|
const path = userId === void 0 || userId === null || userId === "" ? P.usersMe : `${P.users}/${encodePathSegment(userId)}`;
|
|
1677
|
-
return (await s.http.get(path)).data;
|
|
1743
|
+
return normalizeUserAuthProviders((await s.http.get(path)).data);
|
|
1678
1744
|
},
|
|
1679
1745
|
update: ((arg1, arg2) => {
|
|
1680
1746
|
const s = getState();
|
|
@@ -1682,7 +1748,7 @@ const Amba = {
|
|
|
1682
1748
|
const isById = typeof arg1 === "string";
|
|
1683
1749
|
const patch = isById ? arg2 ?? {} : arg1;
|
|
1684
1750
|
const path = isById ? `${P.users}/${encodePathSegment(arg1)}` : `${P.users}/me`;
|
|
1685
|
-
return s.http.patch(path, patch).then((env) => env.data);
|
|
1751
|
+
return s.http.patch(path, patch).then((env) => normalizeUserAuthProviders(env.data));
|
|
1686
1752
|
})
|
|
1687
1753
|
},
|
|
1688
1754
|
sessions: {
|
|
@@ -1960,8 +2026,14 @@ const Amba = {
|
|
|
1960
2026
|
},
|
|
1961
2027
|
has: async (entitlementId) => {
|
|
1962
2028
|
return (await getState().http.get(P.entitlements, { active_only: "true" })).data.some((e) => e.entitlement_id === entitlementId && e.is_active);
|
|
2029
|
+
},
|
|
2030
|
+
restore: async () => {
|
|
2031
|
+
return (await getState().http.post(P.entitlementsRestore, {})).data;
|
|
1963
2032
|
}
|
|
1964
2033
|
},
|
|
2034
|
+
offerings: async (offeringId) => {
|
|
2035
|
+
return (await getState().http.get(P.offerings, offeringId ? { offering_id: offeringId } : void 0)).data;
|
|
2036
|
+
},
|
|
1965
2037
|
ai: { anthropic: { messages: { create: async (request) => {
|
|
1966
2038
|
const env = await getState().http.post(P.aiAnthropic, request);
|
|
1967
2039
|
if (!env || typeof env !== "object" || env.data === void 0) throw new AmbaApiError("MALFORMED_RESPONSE", "AI response was not wrapped in the expected { data } envelope", env);
|