@ateam-ai-mobile/expo 0.1.19 → 0.1.21
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/aiLive/provider.d.mts +20 -0
- package/dist/aiLive/provider.d.ts +20 -0
- package/dist/aiLive/provider.js +400 -0
- package/dist/aiLive/provider.js.map +1 -0
- package/dist/aiLive/provider.mjs +15 -0
- package/dist/aiLive/provider.mjs.map +1 -0
- package/dist/bootstrap.js +350 -3
- package/dist/bootstrap.js.map +1 -1
- package/dist/bootstrap.mjs +17 -12
- package/dist/bootstrap.mjs.map +1 -1
- package/dist/capabilities/index.d.mts +40 -1
- package/dist/capabilities/index.d.ts +40 -1
- package/dist/capabilities/index.js +50 -14
- package/dist/capabilities/index.js.map +1 -1
- package/dist/capabilities/index.mjs +49 -32
- package/dist/capabilities/index.mjs.map +1 -1
- package/dist/{chunk-42FP5DTO.mjs → chunk-2ZQEQJQ6.mjs} +1 -1
- package/dist/chunk-2ZQEQJQ6.mjs.map +1 -0
- package/dist/chunk-AE55BKYV.mjs +24 -0
- package/dist/chunk-AE55BKYV.mjs.map +1 -0
- package/dist/chunk-BAZFMTCC.mjs +815 -0
- package/dist/chunk-BAZFMTCC.mjs.map +1 -0
- package/dist/{chunk-Z5AI2SXX.mjs → chunk-C62NQA4F.mjs} +203 -1004
- package/dist/chunk-C62NQA4F.mjs.map +1 -0
- package/dist/{chunk-DE6Y4VRI.mjs → chunk-GA7DS3PA.mjs} +1 -1
- package/dist/{chunk-DE6Y4VRI.mjs.map → chunk-GA7DS3PA.mjs.map} +1 -1
- package/dist/chunk-GW7YGXOW.mjs +47 -0
- package/dist/chunk-GW7YGXOW.mjs.map +1 -0
- package/dist/chunk-JUBLG3PN.mjs +351 -0
- package/dist/chunk-JUBLG3PN.mjs.map +1 -0
- package/dist/{chunk-Z3P7RUCC.mjs → chunk-OEX4OKYQ.mjs} +13 -13
- package/dist/{chunk-6JX222YX.mjs → chunk-WQK6PUBN.mjs} +9 -2
- package/dist/chunk-WQK6PUBN.mjs.map +1 -0
- package/dist/device/createDeviceProvider.js.map +1 -1
- package/dist/device/createDeviceProvider.mjs +7 -6
- package/dist/device-bridge/index.mjs +8 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/push/index.d.mts +24 -0
- package/dist/push/index.d.ts +24 -0
- package/dist/push/index.js +224 -0
- package/dist/push/index.js.map +1 -0
- package/dist/push/index.mjs +174 -0
- package/dist/push/index.mjs.map +1 -0
- package/dist/push/silentSync.d.mts +8 -0
- package/dist/push/silentSync.d.ts +8 -0
- package/dist/push/silentSync.js +1075 -0
- package/dist/push/silentSync.js.map +1 -0
- package/dist/push/silentSync.mjs +67 -0
- package/dist/push/silentSync.mjs.map +1 -0
- package/dist/vision/index.d.mts +7 -1
- package/dist/vision/index.d.ts +7 -1
- package/dist/vision/index.js +8 -0
- package/dist/vision/index.js.map +1 -1
- package/dist/vision/index.mjs +3 -1
- package/ios/AdaVisionModule.swift +44 -1
- package/package.json +28 -6
- package/src/aiLive/provider.ts +242 -0
- package/src/aiLive/streamProtocol.ts +90 -0
- package/src/bootstrap.ts +7 -1
- package/src/capabilities/choices.ts +65 -0
- package/src/capabilities/config.ts +5 -4
- package/src/capabilities/index.ts +2 -0
- package/src/capabilities/picturesToAi.ts +40 -0
- package/src/capabilities/store.ts +38 -37
- package/src/index.ts +3 -0
- package/src/push/index.ts +18 -0
- package/src/push/messaging.ts +49 -0
- package/src/push/registration.ts +31 -0
- package/src/push/silentSync.ts +83 -0
- package/src/push/usePushNotifications.ts +224 -0
- package/src/vision/index.ts +14 -0
- package/dist/chunk-42FP5DTO.mjs.map +0 -1
- package/dist/chunk-6JX222YX.mjs.map +0 -1
- package/dist/chunk-Z5AI2SXX.mjs.map +0 -1
- /package/dist/{chunk-Z3P7RUCC.mjs.map → chunk-OEX4OKYQ.mjs.map} +0 -0
package/dist/bootstrap.js
CHANGED
|
@@ -175,7 +175,7 @@ __export(bootstrap_exports, {
|
|
|
175
175
|
bootstrapExpoAdas: () => bootstrapExpoAdas
|
|
176
176
|
});
|
|
177
177
|
module.exports = __toCommonJS(bootstrap_exports);
|
|
178
|
-
var
|
|
178
|
+
var import_core3 = require("@ateam-ai-mobile/core");
|
|
179
179
|
var import_plugin_runtime3 = require("@ateam-ai-mobile/plugin-runtime");
|
|
180
180
|
var import_ui2 = require("@ateam-ai-mobile/ui");
|
|
181
181
|
|
|
@@ -1901,6 +1901,12 @@ async function describe(id, maxLabels = 5) {
|
|
|
1901
1901
|
async function detectObjects(id, maxItems = 10, minConfidence = 0.25) {
|
|
1902
1902
|
return verb("detectObjects")(id, maxItems, minConfidence);
|
|
1903
1903
|
}
|
|
1904
|
+
async function jpegById(id, maxSide = 768, quality = 0.7) {
|
|
1905
|
+
if (native2 && typeof native2.jpegById !== "function") {
|
|
1906
|
+
throw new Error("sending pictures to AI needs a newer app build \u2014 this one cannot make a picture from a camera frame");
|
|
1907
|
+
}
|
|
1908
|
+
return verb("jpegById")(id, maxSide, quality);
|
|
1909
|
+
}
|
|
1904
1910
|
|
|
1905
1911
|
// src/maps/index.ts
|
|
1906
1912
|
var import_react_native3 = require("react-native");
|
|
@@ -2917,6 +2923,346 @@ function createDeviceProvider(config2) {
|
|
|
2917
2923
|
};
|
|
2918
2924
|
}
|
|
2919
2925
|
|
|
2926
|
+
// src/aiLive/provider.ts
|
|
2927
|
+
var import_core2 = require("@ateam-ai-mobile/core");
|
|
2928
|
+
|
|
2929
|
+
// src/aiLive/streamProtocol.ts
|
|
2930
|
+
var STREAM_PATH = "/ws/stream";
|
|
2931
|
+
var SUBPROTOCOL = "adas.v1";
|
|
2932
|
+
var HEADER_BYTES = 14;
|
|
2933
|
+
var ENVELOPE_VERSION = 1;
|
|
2934
|
+
var CLOSE = Object.freeze({
|
|
2935
|
+
AUTH_MISSING: 4001,
|
|
2936
|
+
AUTH_FAILED: 4002,
|
|
2937
|
+
NO_SUCH_WORKSPACE: 4003,
|
|
2938
|
+
NOT_ENTITLED: 4004,
|
|
2939
|
+
BAD_REQUEST: 4400,
|
|
2940
|
+
UNKNOWN_KIND: 4404,
|
|
2941
|
+
TIMEOUT: 4408,
|
|
2942
|
+
OVER_LIMIT: 4429,
|
|
2943
|
+
TOO_BIG: 1009,
|
|
2944
|
+
CONSUMER_FAILING: 1011
|
|
2945
|
+
});
|
|
2946
|
+
function encodeFrame({ seq, tCapture, payload }) {
|
|
2947
|
+
const out = new Uint8Array(HEADER_BYTES + payload.length);
|
|
2948
|
+
const v = new DataView(out.buffer);
|
|
2949
|
+
v.setUint8(0, ENVELOPE_VERSION);
|
|
2950
|
+
v.setUint8(1, 0);
|
|
2951
|
+
v.setUint32(2, seq >>> 0, false);
|
|
2952
|
+
v.setFloat64(6, tCapture, false);
|
|
2953
|
+
out.set(payload, HEADER_BYTES);
|
|
2954
|
+
return out;
|
|
2955
|
+
}
|
|
2956
|
+
function openMessage(kind) {
|
|
2957
|
+
return JSON.stringify({ type: "open", kind });
|
|
2958
|
+
}
|
|
2959
|
+
var CLOSE_MESSAGE = JSON.stringify({ type: "close" });
|
|
2960
|
+
function parseServerEvent(text2) {
|
|
2961
|
+
if (typeof text2 !== "string") return null;
|
|
2962
|
+
try {
|
|
2963
|
+
const m = JSON.parse(text2);
|
|
2964
|
+
return m && typeof m.event === "string" ? { event: m.event, data: m.data } : null;
|
|
2965
|
+
} catch {
|
|
2966
|
+
return null;
|
|
2967
|
+
}
|
|
2968
|
+
}
|
|
2969
|
+
var WHY = {
|
|
2970
|
+
[CLOSE.AUTH_MISSING]: "The login or the workspace was missing. Sign in again and try once more.",
|
|
2971
|
+
[CLOSE.AUTH_FAILED]: "The login was refused. Sign in again and try once more.",
|
|
2972
|
+
[CLOSE.NO_SUCH_WORKSPACE]: "This workspace was not found.",
|
|
2973
|
+
[CLOSE.NOT_ENTITLED]: "This workspace may not stream right now.",
|
|
2974
|
+
[CLOSE.TIMEOUT]: "The connection to the AI timed out.",
|
|
2975
|
+
[CLOSE.OVER_LIMIT]: "Too many cameras are sending to this workspace. Stop another one first.",
|
|
2976
|
+
[CLOSE.TOO_BIG]: "A picture was too big to send.",
|
|
2977
|
+
[CLOSE.CONSUMER_FAILING]: "The AI stopped taking pictures. Check the live session in AI Models."
|
|
2978
|
+
};
|
|
2979
|
+
function describeClose(code, reason) {
|
|
2980
|
+
if (code === CLOSE.BAD_REQUEST && reason) return reason;
|
|
2981
|
+
return WHY[code] || (reason ? reason : `The connection to the AI closed (${code}).`);
|
|
2982
|
+
}
|
|
2983
|
+
var B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
2984
|
+
var B64_INDEX = (() => {
|
|
2985
|
+
const t = new Int16Array(256).fill(-1);
|
|
2986
|
+
for (let i = 0; i < 64; i++) t[B64.charCodeAt(i)] = i;
|
|
2987
|
+
return t;
|
|
2988
|
+
})();
|
|
2989
|
+
function base64ToBytes(b64) {
|
|
2990
|
+
const clean = b64.replace(/[^A-Za-z0-9+/]/g, "");
|
|
2991
|
+
const out = new Uint8Array(Math.floor(clean.length * 3 / 4));
|
|
2992
|
+
let o = 0, acc = 0, bits = 0;
|
|
2993
|
+
for (let i = 0; i < clean.length; i++) {
|
|
2994
|
+
acc = acc << 6 | B64_INDEX[clean.charCodeAt(i)];
|
|
2995
|
+
bits += 6;
|
|
2996
|
+
if (bits >= 8) {
|
|
2997
|
+
bits -= 8;
|
|
2998
|
+
out[o++] = acc >> bits & 255;
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
return o === out.length ? out : out.subarray(0, o);
|
|
3002
|
+
}
|
|
3003
|
+
|
|
3004
|
+
// src/aiLive/provider.ts
|
|
3005
|
+
var PHONE_SLICE_USD = 0.5;
|
|
3006
|
+
var LIVE_KIND = "ai-models.live";
|
|
3007
|
+
var FRESH_MS2 = 3e3;
|
|
3008
|
+
var MAX_BUFFERED = 512 * 1024;
|
|
3009
|
+
var DEFAULT_CAMERA = { fps: 1, maxPx: 768 };
|
|
3010
|
+
var SESSION_UP = /* @__PURE__ */ new Set(["starting", "running", "degraded"]);
|
|
3011
|
+
async function defaultCallCp(method, params = {}) {
|
|
3012
|
+
const res = await (0, import_core2.mcpToolCall)("cp.ai_models_api", { method, params });
|
|
3013
|
+
if (res?.error) throw new Error(res.error.message || "AI Models refused the request");
|
|
3014
|
+
const out = (0, import_core2.unwrapMcpResult)(res?.result);
|
|
3015
|
+
if (res?.result?.isError) throw new Error(typeof out === "string" ? out : out?.message || out?.error || "AI Models refused the request");
|
|
3016
|
+
if (out && typeof out === "object" && out.ok === false) throw new Error(out.message || out.error || "AI Models refused the request");
|
|
3017
|
+
return out;
|
|
3018
|
+
}
|
|
3019
|
+
var defaultAiLiveDeps = () => ({
|
|
3020
|
+
callCp: defaultCallCp,
|
|
3021
|
+
WebSocketImpl: globalThis.WebSocket,
|
|
3022
|
+
wsBase: import_core2.getCoreWsUrl,
|
|
3023
|
+
token: import_core2.getToken,
|
|
3024
|
+
tenant: import_core2.getTenant,
|
|
3025
|
+
jpegById,
|
|
3026
|
+
now: Date.now,
|
|
3027
|
+
setInterval: (fn, ms) => setInterval(fn, ms),
|
|
3028
|
+
clearInterval: (h) => clearInterval(h)
|
|
3029
|
+
});
|
|
3030
|
+
var idle = () => ({ state: "idle", camera: null, sent: 0, skipped: 0, lastEpisode: null, lastError: null });
|
|
3031
|
+
function createAiLiveProvider(overrides = {}) {
|
|
3032
|
+
const deps = { ...defaultAiLiveDeps(), ...overrides };
|
|
3033
|
+
let owner = null;
|
|
3034
|
+
let snap = idle();
|
|
3035
|
+
let ws = null;
|
|
3036
|
+
let loop = null;
|
|
3037
|
+
let visual = null;
|
|
3038
|
+
let startedSession = false;
|
|
3039
|
+
let closingOnPurpose = false;
|
|
3040
|
+
let seq = 0;
|
|
3041
|
+
let busy = false;
|
|
3042
|
+
let gen = 0;
|
|
3043
|
+
let lastFrameId = null;
|
|
3044
|
+
let camera = DEFAULT_CAMERA;
|
|
3045
|
+
let lastOwner = null;
|
|
3046
|
+
const episodeCbs = /* @__PURE__ */ new Map();
|
|
3047
|
+
const snapCbs = /* @__PURE__ */ new Map();
|
|
3048
|
+
const sendingCbs = /* @__PURE__ */ new Set();
|
|
3049
|
+
let wasSending = false;
|
|
3050
|
+
const add = (m, who, cb) => {
|
|
3051
|
+
let set3 = m.get(who);
|
|
3052
|
+
if (!set3) {
|
|
3053
|
+
set3 = /* @__PURE__ */ new Set();
|
|
3054
|
+
m.set(who, set3);
|
|
3055
|
+
}
|
|
3056
|
+
set3.add(cb);
|
|
3057
|
+
return { unsubscribe: () => {
|
|
3058
|
+
set3.delete(cb);
|
|
3059
|
+
} };
|
|
3060
|
+
};
|
|
3061
|
+
const set2 = (patch) => {
|
|
3062
|
+
snap = { ...snap, ...patch };
|
|
3063
|
+
for (const cb of lastOwner && snapCbs.get(lastOwner) || []) {
|
|
3064
|
+
try {
|
|
3065
|
+
cb(snap);
|
|
3066
|
+
} catch {
|
|
3067
|
+
}
|
|
3068
|
+
}
|
|
3069
|
+
const sending = snap.state === "starting" || snap.state === "sending";
|
|
3070
|
+
if (sending !== wasSending) {
|
|
3071
|
+
wasSending = sending;
|
|
3072
|
+
for (const cb of sendingCbs) {
|
|
3073
|
+
try {
|
|
3074
|
+
cb();
|
|
3075
|
+
} catch {
|
|
3076
|
+
}
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3079
|
+
};
|
|
3080
|
+
function stopTimers() {
|
|
3081
|
+
if (loop != null) {
|
|
3082
|
+
deps.clearInterval(loop);
|
|
3083
|
+
loop = null;
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
3086
|
+
async function slot() {
|
|
3087
|
+
const mySeq = seq++;
|
|
3088
|
+
const g = gen;
|
|
3089
|
+
const sock = ws;
|
|
3090
|
+
const current = () => g === gen && ws === sock && sock?.readyState === 1;
|
|
3091
|
+
if (busy || !current()) {
|
|
3092
|
+
set2({ skipped: snap.skipped + 1 });
|
|
3093
|
+
return;
|
|
3094
|
+
}
|
|
3095
|
+
if ((sock.bufferedAmount || 0) > MAX_BUFFERED) {
|
|
3096
|
+
set2({ skipped: snap.skipped + 1 });
|
|
3097
|
+
return;
|
|
3098
|
+
}
|
|
3099
|
+
busy = true;
|
|
3100
|
+
try {
|
|
3101
|
+
const v = await visual.getSnapshot();
|
|
3102
|
+
if (!current()) return;
|
|
3103
|
+
const f = v?.latest;
|
|
3104
|
+
const id = f?.handle?.id;
|
|
3105
|
+
const t = Number(f?.timestamp);
|
|
3106
|
+
if (!id || id === lastFrameId || !(deps.now() - t < FRESH_MS2)) {
|
|
3107
|
+
set2({ skipped: snap.skipped + 1 });
|
|
3108
|
+
return;
|
|
3109
|
+
}
|
|
3110
|
+
const b64 = await deps.jpegById(id, camera.maxPx, 0.7);
|
|
3111
|
+
if (!current()) return;
|
|
3112
|
+
const frame = encodeFrame({ seq: mySeq, tCapture: t, payload: base64ToBytes(b64) });
|
|
3113
|
+
sock.send(frame.buffer);
|
|
3114
|
+
lastFrameId = id;
|
|
3115
|
+
set2({ sent: snap.sent + 1 });
|
|
3116
|
+
} catch (e) {
|
|
3117
|
+
if (g === gen) set2({ skipped: snap.skipped + 1, lastError: String(e?.message || e) });
|
|
3118
|
+
} finally {
|
|
3119
|
+
if (g === gen) busy = false;
|
|
3120
|
+
}
|
|
3121
|
+
}
|
|
3122
|
+
function openSocket() {
|
|
3123
|
+
return new Promise((resolve, reject) => {
|
|
3124
|
+
const token = deps.token();
|
|
3125
|
+
const tenant = deps.tenant();
|
|
3126
|
+
if (!token || !tenant) {
|
|
3127
|
+
reject(new Error("not signed in to a workspace"));
|
|
3128
|
+
return;
|
|
3129
|
+
}
|
|
3130
|
+
const url = `${deps.wsBase()}${STREAM_PATH}?tenant=${encodeURIComponent(tenant)}`;
|
|
3131
|
+
let opened = false;
|
|
3132
|
+
const sock = new deps.WebSocketImpl(url, [SUBPROTOCOL, `adas.bearer.${token}`]);
|
|
3133
|
+
ws = sock;
|
|
3134
|
+
sock.binaryType = "arraybuffer";
|
|
3135
|
+
sock.onopen = () => {
|
|
3136
|
+
try {
|
|
3137
|
+
sock.send(openMessage(LIVE_KIND));
|
|
3138
|
+
} catch (e) {
|
|
3139
|
+
reject(e);
|
|
3140
|
+
}
|
|
3141
|
+
};
|
|
3142
|
+
sock.onmessage = (m) => {
|
|
3143
|
+
const ev = parseServerEvent(m?.data);
|
|
3144
|
+
if (!ev) return;
|
|
3145
|
+
if (ev.event === "opened" && !opened) {
|
|
3146
|
+
opened = true;
|
|
3147
|
+
resolve();
|
|
3148
|
+
return;
|
|
3149
|
+
}
|
|
3150
|
+
if (ev.event === "episode" && ev.data && typeof ev.data === "object") {
|
|
3151
|
+
const episode = ev.data;
|
|
3152
|
+
set2({ lastEpisode: episode });
|
|
3153
|
+
for (const cb of owner && episodeCbs.get(owner) || []) {
|
|
3154
|
+
try {
|
|
3155
|
+
cb(episode);
|
|
3156
|
+
} catch {
|
|
3157
|
+
}
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
};
|
|
3161
|
+
sock.onerror = () => {
|
|
3162
|
+
};
|
|
3163
|
+
sock.onclose = (c) => {
|
|
3164
|
+
const why = describeClose(Number(c?.code), c?.reason);
|
|
3165
|
+
if (!opened) {
|
|
3166
|
+
reject(new Error(why));
|
|
3167
|
+
return;
|
|
3168
|
+
}
|
|
3169
|
+
if (closingOnPurpose || ws !== sock) return;
|
|
3170
|
+
void teardown("error", why);
|
|
3171
|
+
};
|
|
3172
|
+
});
|
|
3173
|
+
}
|
|
3174
|
+
async function teardown(state, lastError) {
|
|
3175
|
+
const hadSession = startedSession;
|
|
3176
|
+
startedSession = false;
|
|
3177
|
+
gen++;
|
|
3178
|
+
stopTimers();
|
|
3179
|
+
const sock = ws;
|
|
3180
|
+
ws = null;
|
|
3181
|
+
closingOnPurpose = true;
|
|
3182
|
+
try {
|
|
3183
|
+
if (sock && sock.readyState === 1) sock.send(CLOSE_MESSAGE);
|
|
3184
|
+
} catch {
|
|
3185
|
+
}
|
|
3186
|
+
try {
|
|
3187
|
+
sock?.close?.();
|
|
3188
|
+
} catch {
|
|
3189
|
+
}
|
|
3190
|
+
closingOnPurpose = false;
|
|
3191
|
+
const v = visual;
|
|
3192
|
+
visual = null;
|
|
3193
|
+
try {
|
|
3194
|
+
await v?.stop?.();
|
|
3195
|
+
} catch {
|
|
3196
|
+
}
|
|
3197
|
+
if (hadSession) {
|
|
3198
|
+
try {
|
|
3199
|
+
await deps.callCp("liveStop");
|
|
3200
|
+
} catch {
|
|
3201
|
+
}
|
|
3202
|
+
}
|
|
3203
|
+
owner = null;
|
|
3204
|
+
set2({ state, lastError });
|
|
3205
|
+
}
|
|
3206
|
+
return {
|
|
3207
|
+
async start(opts, who, ctx) {
|
|
3208
|
+
if (owner && owner !== who) throw Object.assign(new Error("aiLive: another screen is sending to AI right now. Close it first."), { code: "CONFLICT" });
|
|
3209
|
+
if (owner === who) return snap;
|
|
3210
|
+
const cam = opts?.camera === "front" ? "front" : "back";
|
|
3211
|
+
if (opts?.camera && opts.camera !== "front" && opts.camera !== "back") throw new Error(`aiLive: unknown camera "${String(opts.camera)}" \u2014 use "front" or "back"`);
|
|
3212
|
+
owner = who;
|
|
3213
|
+
lastOwner = who;
|
|
3214
|
+
visual = ctx.visual;
|
|
3215
|
+
gen++;
|
|
3216
|
+
seq = 0;
|
|
3217
|
+
lastFrameId = null;
|
|
3218
|
+
busy = false;
|
|
3219
|
+
snap = { ...idle(), camera: cam };
|
|
3220
|
+
set2({ state: "starting" });
|
|
3221
|
+
try {
|
|
3222
|
+
let session = (await deps.callCp("liveStatus"))?.session;
|
|
3223
|
+
if (!SESSION_UP.has(session?.state)) {
|
|
3224
|
+
session = (await deps.callCp("liveStart", { source: "phone", budgetSliceUsd: PHONE_SLICE_USD }))?.session;
|
|
3225
|
+
startedSession = true;
|
|
3226
|
+
}
|
|
3227
|
+
const c = session?.camera;
|
|
3228
|
+
camera = c && Number(c.fps) > 0 && Number(c.maxPx) > 0 ? { fps: Number(c.fps), maxPx: Number(c.maxPx) } : DEFAULT_CAMERA;
|
|
3229
|
+
await visual.start({ intent: "stream", facing: cam });
|
|
3230
|
+
await openSocket();
|
|
3231
|
+
loop = deps.setInterval(() => {
|
|
3232
|
+
void slot();
|
|
3233
|
+
}, Math.max(200, Math.round(1e3 / camera.fps)));
|
|
3234
|
+
set2({ state: "sending" });
|
|
3235
|
+
return snap;
|
|
3236
|
+
} catch (e) {
|
|
3237
|
+
await teardown("error", String(e?.message || e));
|
|
3238
|
+
throw e;
|
|
3239
|
+
}
|
|
3240
|
+
},
|
|
3241
|
+
async stop(who) {
|
|
3242
|
+
if (owner !== who) return;
|
|
3243
|
+
await teardown("stopped", null);
|
|
3244
|
+
},
|
|
3245
|
+
getSnapshot: (who) => lastOwner === who ? snap : idle(),
|
|
3246
|
+
onEpisode: (cb, who) => add(episodeCbs, who, cb),
|
|
3247
|
+
subscribe: (cb, who) => add(snapCbs, who, cb),
|
|
3248
|
+
forget(who) {
|
|
3249
|
+
episodeCbs.delete(who);
|
|
3250
|
+
snapCbs.delete(who);
|
|
3251
|
+
if (lastOwner === who && owner === null) {
|
|
3252
|
+
lastOwner = null;
|
|
3253
|
+
snap = idle();
|
|
3254
|
+
}
|
|
3255
|
+
},
|
|
3256
|
+
isSending: () => snap.state === "starting" || snap.state === "sending",
|
|
3257
|
+
subscribeSending(cb) {
|
|
3258
|
+
sendingCbs.add(cb);
|
|
3259
|
+
return { unsubscribe: () => {
|
|
3260
|
+
sendingCbs.delete(cb);
|
|
3261
|
+
} };
|
|
3262
|
+
}
|
|
3263
|
+
};
|
|
3264
|
+
}
|
|
3265
|
+
|
|
2920
3266
|
// src/oauth/expoOAuth.tsx
|
|
2921
3267
|
var import_react_native7 = require("react-native");
|
|
2922
3268
|
var import_google_signin = require("@react-native-google-signin/google-signin");
|
|
@@ -3008,14 +3354,15 @@ function bootstrapExpoAdas(opts) {
|
|
|
3008
3354
|
(0, import_ui2.setCallAudioProvider)(createCallAudioProvider());
|
|
3009
3355
|
if (opts.onReachabilityChange) {
|
|
3010
3356
|
const onReach = opts.onReachabilityChange;
|
|
3011
|
-
(0,
|
|
3357
|
+
(0, import_core3.setAcsReachabilityReporter)({ up: () => onReach(true), down: () => onReach(false) });
|
|
3012
3358
|
}
|
|
3013
3359
|
(0, import_plugin_runtime3.setDeviceStateProvider)(
|
|
3014
3360
|
createDeviceState({ connectivity: connectivity_exports, location: location_exports })
|
|
3015
3361
|
);
|
|
3362
|
+
(0, import_plugin_runtime3.setAiLiveProvider)(createAiLiveProvider());
|
|
3016
3363
|
(0, import_plugin_runtime3.registerPlatformDeviceTools)();
|
|
3017
3364
|
(0, import_ui2.setUIActionNavigator)(opts.navigateToPlugin);
|
|
3018
|
-
(0,
|
|
3365
|
+
(0, import_core3.initAdas)({
|
|
3019
3366
|
coreUrl: opts.urls.core,
|
|
3020
3367
|
...opts.urls.voice ? { voiceUrl: opts.urls.voice } : {},
|
|
3021
3368
|
...opts.urls.consumerAuth ? { consumerAuthUrl: opts.urls.consumerAuth } : {},
|