@formant/data-sdk 0.0.128 → 0.0.130
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/data-sdk.es.js +1435 -1845
- package/dist/data-sdk.umd.js +26 -26
- package/dist/types/data-sdk/src/{fleet.d.ts → Fleet.d.ts} +4 -0
- package/dist/types/data-sdk/src/main.d.ts +1 -0
- package/dist/types/data-sdk/src/model/IAnnotationQuery.d.ts +7 -0
- package/dist/types/data-sdk/src/model/JsonSchema.d.ts +2 -3
- package/package.json +1 -1
package/dist/data-sdk.es.js
CHANGED
|
@@ -4,6 +4,7 @@ var __publicField = (obj, key, value) => {
|
|
|
4
4
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
return value;
|
|
6
6
|
};
|
|
7
|
+
import { startOfMinute, addMinutes, roundToNearestMinutes, addSeconds } from "date-fns";
|
|
7
8
|
var dist = { exports: {} };
|
|
8
9
|
/*! For license information please see index.js.LICENSE.txt */
|
|
9
10
|
(function(module, exports) {
|
|
@@ -19230,1321 +19231,879 @@ const envLocal = urlParams$2.get("formant_local");
|
|
|
19230
19231
|
if (envLocal) {
|
|
19231
19232
|
FORMANT_API_URL = "https://api.formant.local";
|
|
19232
19233
|
}
|
|
19233
|
-
|
|
19234
|
-
|
|
19234
|
+
const millisecond = 1;
|
|
19235
|
+
const second = 1e3;
|
|
19236
|
+
const minute = 60 * second;
|
|
19237
|
+
const hour = 60 * minute;
|
|
19238
|
+
const day = 24 * hour;
|
|
19239
|
+
const week = 7 * day;
|
|
19240
|
+
const month = 30 * day;
|
|
19241
|
+
const year = 365 * day;
|
|
19242
|
+
const duration = {
|
|
19243
|
+
millisecond,
|
|
19244
|
+
second,
|
|
19245
|
+
minute,
|
|
19246
|
+
hour,
|
|
19247
|
+
day,
|
|
19248
|
+
week,
|
|
19249
|
+
month,
|
|
19250
|
+
year
|
|
19251
|
+
};
|
|
19252
|
+
function filterDataByType(datas, type) {
|
|
19253
|
+
return datas.filter((_) => _.type === type);
|
|
19235
19254
|
}
|
|
19236
|
-
|
|
19237
|
-
|
|
19238
|
-
|
|
19239
|
-
|
|
19240
|
-
|
|
19241
|
-
|
|
19242
|
-
|
|
19243
|
-
|
|
19244
|
-
|
|
19245
|
-
|
|
19246
|
-
|
|
19247
|
-
|
|
19248
|
-
|
|
19249
|
-
|
|
19250
|
-
|
|
19251
|
-
|
|
19252
|
-
|
|
19253
|
-
|
|
19254
|
-
|
|
19255
|
-
|
|
19256
|
-
this
|
|
19257
|
-
|
|
19258
|
-
|
|
19259
|
-
|
|
19260
|
-
};
|
|
19261
|
-
this.dataChannel.onmessage = (m) => {
|
|
19262
|
-
this.listeners.forEach((_) => {
|
|
19263
|
-
const d = new Uint8Array(m.data);
|
|
19264
|
-
const s = this.decoder.decode(d);
|
|
19265
|
-
_(s);
|
|
19266
|
-
});
|
|
19267
|
-
this.binaryListeners.forEach((_) => {
|
|
19268
|
-
_(new Uint8Array(m.data));
|
|
19269
|
-
});
|
|
19270
|
-
};
|
|
19271
|
-
}
|
|
19272
|
-
addOpenListener(listener) {
|
|
19273
|
-
this.openListeners.push(listener);
|
|
19255
|
+
function filterDataByTime(datas, start, end) {
|
|
19256
|
+
const startTime = start.getTime();
|
|
19257
|
+
const endTime = end.getTime();
|
|
19258
|
+
return datas.map((data) => ({
|
|
19259
|
+
...data,
|
|
19260
|
+
points: data.points.filter(
|
|
19261
|
+
([timestamp]) => timestamp >= startTime && timestamp < endTime
|
|
19262
|
+
)
|
|
19263
|
+
})).filter(({ points }) => points.length > 0);
|
|
19264
|
+
}
|
|
19265
|
+
function fork(_) {
|
|
19266
|
+
return void 0;
|
|
19267
|
+
}
|
|
19268
|
+
class StoreCache {
|
|
19269
|
+
constructor({
|
|
19270
|
+
capacity,
|
|
19271
|
+
timeout
|
|
19272
|
+
} = {}) {
|
|
19273
|
+
__publicField(this, "entries", /* @__PURE__ */ new Map());
|
|
19274
|
+
__publicField(this, "metadata", /* @__PURE__ */ new Map());
|
|
19275
|
+
__publicField(this, "capacity");
|
|
19276
|
+
__publicField(this, "timeout");
|
|
19277
|
+
this.capacity = capacity || 1e4;
|
|
19278
|
+
this.timeout = timeout || duration.minute;
|
|
19274
19279
|
}
|
|
19275
|
-
|
|
19276
|
-
|
|
19280
|
+
get(key, generator) {
|
|
19281
|
+
const cacheKey = this.keyToCacheKey(key);
|
|
19282
|
+
const entry = this.entries.get(cacheKey);
|
|
19283
|
+
const metadata = this.metadata.get(cacheKey);
|
|
19284
|
+
if ((entry === void 0 || metadata && (metadata == null ? void 0 : metadata.expiration.getTime()) < Date.now()) && !(metadata == null ? void 0 : metadata.generating) && generator) {
|
|
19285
|
+
this.generate(key, generator());
|
|
19286
|
+
}
|
|
19287
|
+
if (entry === void 0 && metadata && metadata.lastValue !== void 0) {
|
|
19288
|
+
return metadata.lastValue;
|
|
19289
|
+
}
|
|
19290
|
+
return entry;
|
|
19277
19291
|
}
|
|
19278
|
-
|
|
19279
|
-
this.
|
|
19292
|
+
set(key, value) {
|
|
19293
|
+
const cacheKey = this.keyToCacheKey(key);
|
|
19294
|
+
this.metadata.set(cacheKey, {
|
|
19295
|
+
generating: false,
|
|
19296
|
+
expiration: new Date(Date.now() + this.timeout),
|
|
19297
|
+
lastValue: value
|
|
19298
|
+
});
|
|
19299
|
+
this.entries.set(cacheKey, value);
|
|
19300
|
+
if (this.metadata.size > this.capacity) {
|
|
19301
|
+
this.deleteOldestEntry();
|
|
19302
|
+
}
|
|
19280
19303
|
}
|
|
19281
|
-
|
|
19282
|
-
this.
|
|
19304
|
+
clear() {
|
|
19305
|
+
this.entries.clear();
|
|
19306
|
+
[...this.metadata.values()].forEach((value) => value.generating = false);
|
|
19283
19307
|
}
|
|
19284
|
-
|
|
19285
|
-
this.
|
|
19308
|
+
clearKey(key) {
|
|
19309
|
+
this.metadata.delete(key);
|
|
19310
|
+
this.entries.delete(key);
|
|
19286
19311
|
}
|
|
19287
|
-
|
|
19288
|
-
|
|
19312
|
+
keyToCacheKey(key) {
|
|
19313
|
+
return JSON.stringify(key);
|
|
19289
19314
|
}
|
|
19290
|
-
|
|
19291
|
-
if (this.
|
|
19292
|
-
return
|
|
19315
|
+
deleteOldestEntry() {
|
|
19316
|
+
if (this.metadata.size < 1) {
|
|
19317
|
+
return;
|
|
19293
19318
|
}
|
|
19294
|
-
const
|
|
19295
|
-
|
|
19296
|
-
|
|
19297
|
-
|
|
19298
|
-
|
|
19299
|
-
|
|
19300
|
-
|
|
19301
|
-
|
|
19302
|
-
|
|
19303
|
-
|
|
19319
|
+
const [key] = [...this.metadata.entries()].reduce(
|
|
19320
|
+
([oldestKey, oldestEntry], [thisKey, entry]) => entry.expiration.getTime() < oldestEntry.expiration.getTime() ? [thisKey, entry] : [oldestKey, oldestEntry]
|
|
19321
|
+
);
|
|
19322
|
+
this.clearKey(key);
|
|
19323
|
+
}
|
|
19324
|
+
generate(key, promise) {
|
|
19325
|
+
const cacheKey = this.keyToCacheKey(key);
|
|
19326
|
+
const existingMetadata = this.metadata.get(cacheKey) || {};
|
|
19327
|
+
this.metadata.set(cacheKey, {
|
|
19328
|
+
...existingMetadata,
|
|
19329
|
+
generating: true,
|
|
19330
|
+
expiration: new Date(Date.now() + this.timeout)
|
|
19304
19331
|
});
|
|
19305
|
-
|
|
19332
|
+
setTimeout(() => {
|
|
19333
|
+
fork(
|
|
19334
|
+
promise.then((value) => {
|
|
19335
|
+
const metadata = this.metadata.get(cacheKey);
|
|
19336
|
+
const canceled = !(metadata == null ? void 0 : metadata.generating);
|
|
19337
|
+
if (!canceled) {
|
|
19338
|
+
this.set(key, value);
|
|
19339
|
+
}
|
|
19340
|
+
})
|
|
19341
|
+
);
|
|
19342
|
+
}, 0);
|
|
19306
19343
|
}
|
|
19307
|
-
|
|
19308
|
-
|
|
19309
|
-
|
|
19310
|
-
|
|
19311
|
-
|
|
19344
|
+
}
|
|
19345
|
+
class QueryStore {
|
|
19346
|
+
constructor() {
|
|
19347
|
+
__publicField(this, "queryStoreCache", new StoreCache({
|
|
19348
|
+
capacity: 1e4,
|
|
19349
|
+
timeout: 20 * duration.second
|
|
19350
|
+
}));
|
|
19351
|
+
__publicField(this, "liveQueryStoreCache", new StoreCache({
|
|
19352
|
+
capacity: 1e4,
|
|
19353
|
+
timeout: 200 * duration.millisecond
|
|
19354
|
+
}));
|
|
19312
19355
|
}
|
|
19313
|
-
|
|
19314
|
-
|
|
19315
|
-
|
|
19356
|
+
moduleQuery(filter, name, type, start, end, latestOnly = false) {
|
|
19357
|
+
const q = {
|
|
19358
|
+
...filter,
|
|
19359
|
+
names: [name],
|
|
19360
|
+
types: [type]
|
|
19361
|
+
};
|
|
19362
|
+
const data = this.query(q, start, end, latestOnly);
|
|
19363
|
+
if (data === void 0 || data === "too much data") {
|
|
19364
|
+
return data;
|
|
19316
19365
|
}
|
|
19317
|
-
|
|
19318
|
-
}
|
|
19319
|
-
addListener(listener) {
|
|
19320
|
-
this.listeners.push(listener);
|
|
19366
|
+
return filterDataByType(data, type);
|
|
19321
19367
|
}
|
|
19322
|
-
|
|
19323
|
-
const
|
|
19324
|
-
|
|
19325
|
-
|
|
19368
|
+
query(filter, start, end, latestOnly = false) {
|
|
19369
|
+
const q = {
|
|
19370
|
+
...filter,
|
|
19371
|
+
start: startOfMinute(start).toISOString(),
|
|
19372
|
+
end: latestOnly ? end.toISOString() : addMinutes(roundToNearestMinutes(end), 1).toISOString(),
|
|
19373
|
+
latestOnly
|
|
19374
|
+
};
|
|
19375
|
+
const isLive = end > addSeconds(new Date(), -20);
|
|
19376
|
+
let data;
|
|
19377
|
+
if (isLive) {
|
|
19378
|
+
data = this.liveQueryCache(q);
|
|
19379
|
+
} else {
|
|
19380
|
+
data = this.queryCache(q);
|
|
19326
19381
|
}
|
|
19327
|
-
if (
|
|
19328
|
-
|
|
19382
|
+
if (!data || data === "too much data") {
|
|
19383
|
+
return data;
|
|
19329
19384
|
}
|
|
19330
|
-
|
|
19385
|
+
if (latestOnly) {
|
|
19386
|
+
return data;
|
|
19387
|
+
}
|
|
19388
|
+
return filterDataByTime(data, start, end);
|
|
19331
19389
|
}
|
|
19332
|
-
|
|
19333
|
-
this.
|
|
19390
|
+
queryCache(query) {
|
|
19391
|
+
return this.queryStoreCache.get(query, async () => {
|
|
19392
|
+
try {
|
|
19393
|
+
return await Fleet.queryTelemetry(query);
|
|
19394
|
+
} catch (error) {
|
|
19395
|
+
throw error;
|
|
19396
|
+
}
|
|
19397
|
+
});
|
|
19334
19398
|
}
|
|
19335
|
-
|
|
19336
|
-
|
|
19337
|
-
|
|
19338
|
-
|
|
19339
|
-
|
|
19340
|
-
|
|
19341
|
-
|
|
19342
|
-
}
|
|
19343
|
-
this.binaryListeners.splice(i, 1);
|
|
19399
|
+
liveQueryCache(query) {
|
|
19400
|
+
return this.liveQueryStoreCache.get(query, async () => {
|
|
19401
|
+
try {
|
|
19402
|
+
return await Fleet.queryTelemetry(query);
|
|
19403
|
+
} catch (error) {
|
|
19404
|
+
throw error;
|
|
19405
|
+
}
|
|
19406
|
+
});
|
|
19344
19407
|
}
|
|
19345
19408
|
}
|
|
19346
|
-
|
|
19347
|
-
|
|
19348
|
-
|
|
19349
|
-
|
|
19409
|
+
const queryStore = new QueryStore();
|
|
19410
|
+
class App {
|
|
19411
|
+
static sendAppMessage(message) {
|
|
19412
|
+
window.parent.postMessage(message, "*");
|
|
19350
19413
|
}
|
|
19351
|
-
|
|
19352
|
-
|
|
19353
|
-
|
|
19354
|
-
|
|
19355
|
-
{
|
|
19356
|
-
method: "POST"
|
|
19357
|
-
}
|
|
19358
|
-
);
|
|
19359
|
-
const authInfo = await result.json();
|
|
19360
|
-
this.token = authInfo.token;
|
|
19414
|
+
static getCurrentModuleContext() {
|
|
19415
|
+
let urlParams2 = new URLSearchParams("");
|
|
19416
|
+
if (typeof window !== "undefined") {
|
|
19417
|
+
urlParams2 = new URLSearchParams(window.location.search);
|
|
19361
19418
|
}
|
|
19362
|
-
|
|
19363
|
-
|
|
19364
|
-
body: JSON.stringify({
|
|
19365
|
-
deviceId: this.captureSession.deviceId,
|
|
19366
|
-
name: this.captureSession.streamName,
|
|
19367
|
-
type: "json",
|
|
19368
|
-
points: [[Date.now(), JSON.stringify(value)]]
|
|
19369
|
-
}),
|
|
19370
|
-
headers: {
|
|
19371
|
-
"Content-Type": "application/json",
|
|
19372
|
-
Authorization: "Bearer " + this.token
|
|
19373
|
-
}
|
|
19374
|
-
});
|
|
19419
|
+
const moduleName2 = urlParams2.get("module");
|
|
19420
|
+
return moduleName2;
|
|
19375
19421
|
}
|
|
19376
|
-
|
|
19377
|
-
|
|
19378
|
-
|
|
19379
|
-
|
|
19380
|
-
|
|
19381
|
-
|
|
19382
|
-
|
|
19383
|
-
|
|
19384
|
-
|
|
19385
|
-
|
|
19422
|
+
static async getCurrentModuleConfiguration() {
|
|
19423
|
+
let urlParams2 = new URLSearchParams("");
|
|
19424
|
+
if (typeof window !== "undefined") {
|
|
19425
|
+
urlParams2 = new URLSearchParams(window.location.search);
|
|
19426
|
+
}
|
|
19427
|
+
const configurationId = urlParams2.get("configuration");
|
|
19428
|
+
if (configurationId === null || configurationId.trim() === "") {
|
|
19429
|
+
return void 0;
|
|
19430
|
+
}
|
|
19431
|
+
const response = await fetch(
|
|
19432
|
+
`${FORMANT_API_URL}/v1/admin/module-configurations/` + configurationId,
|
|
19433
|
+
{
|
|
19434
|
+
headers: {
|
|
19435
|
+
"Content-Type": "application/json",
|
|
19436
|
+
Authorization: "Bearer " + Authentication.token
|
|
19437
|
+
}
|
|
19386
19438
|
}
|
|
19387
|
-
});
|
|
19388
|
-
this.device = device;
|
|
19389
|
-
this.config = config;
|
|
19390
|
-
}
|
|
19391
|
-
async synchronize() {
|
|
19392
|
-
this.device.addRealtimeListener(this.onRealtimeMessage);
|
|
19393
|
-
this.device.startListeningToRealtimeDataStream(
|
|
19394
|
-
this.config.currentJointStateStream
|
|
19395
|
-
);
|
|
19396
|
-
}
|
|
19397
|
-
async desynchronize() {
|
|
19398
|
-
this.device.removeRealtimeListener(this.onRealtimeMessage);
|
|
19399
|
-
this.device.stopListeningToRealtimeDataStream(
|
|
19400
|
-
this.config.currentJointStateStream
|
|
19401
19439
|
);
|
|
19440
|
+
const moduleConfiguration = await response.json();
|
|
19441
|
+
return moduleConfiguration.configuration;
|
|
19402
19442
|
}
|
|
19403
|
-
|
|
19404
|
-
this.
|
|
19405
|
-
}
|
|
19406
|
-
}
|
|
19407
|
-
class RequestDataChannel {
|
|
19408
|
-
constructor(device, channel_name, timeout) {
|
|
19409
|
-
__publicField(this, "channel");
|
|
19410
|
-
__publicField(this, "requestIdToResponseMap", /* @__PURE__ */ new Map());
|
|
19411
|
-
this.device = device;
|
|
19412
|
-
this.channel_name = channel_name;
|
|
19413
|
-
this.timeout = timeout;
|
|
19443
|
+
static isModule() {
|
|
19444
|
+
return this.getCurrentModuleContext() !== null;
|
|
19414
19445
|
}
|
|
19415
|
-
|
|
19416
|
-
|
|
19446
|
+
static goToTime(date) {
|
|
19447
|
+
this.sendAppMessage({
|
|
19448
|
+
type: "go_to_time",
|
|
19449
|
+
time: date.getTime()
|
|
19450
|
+
});
|
|
19417
19451
|
}
|
|
19418
|
-
|
|
19419
|
-
|
|
19420
|
-
|
|
19421
|
-
|
|
19452
|
+
static goToDevice(deviceId) {
|
|
19453
|
+
this.sendAppMessage({
|
|
19454
|
+
type: "go_to_device",
|
|
19455
|
+
deviceId
|
|
19456
|
+
});
|
|
19422
19457
|
}
|
|
19423
|
-
|
|
19424
|
-
|
|
19458
|
+
static showMessage(message) {
|
|
19459
|
+
this.sendAppMessage({ type: "show_message", message });
|
|
19425
19460
|
}
|
|
19426
|
-
|
|
19427
|
-
|
|
19428
|
-
|
|
19429
|
-
|
|
19461
|
+
static requestModuleData() {
|
|
19462
|
+
const moduleName2 = this.getCurrentModuleContext();
|
|
19463
|
+
if (!moduleName2) {
|
|
19464
|
+
throw new Error("No module context");
|
|
19465
|
+
}
|
|
19466
|
+
this.sendAppMessage({
|
|
19467
|
+
type: "request_module_data",
|
|
19468
|
+
module: moduleName2
|
|
19469
|
+
});
|
|
19430
19470
|
}
|
|
19431
|
-
|
|
19432
|
-
|
|
19471
|
+
static setModuleDateTimeRange(beforeInMilliseconds, afterInMilliseconds) {
|
|
19472
|
+
const moduleName2 = this.getCurrentModuleContext();
|
|
19473
|
+
if (!moduleName2) {
|
|
19474
|
+
throw new Error("No module context");
|
|
19475
|
+
}
|
|
19476
|
+
this.sendAppMessage({
|
|
19477
|
+
type: "set_module_data_time_range",
|
|
19478
|
+
module: moduleName2,
|
|
19479
|
+
before: beforeInMilliseconds,
|
|
19480
|
+
after: afterInMilliseconds || 0
|
|
19481
|
+
});
|
|
19433
19482
|
}
|
|
19434
|
-
|
|
19435
|
-
|
|
19436
|
-
|
|
19437
|
-
|
|
19483
|
+
static refreshAuthToken() {
|
|
19484
|
+
const moduleName2 = this.getCurrentModuleContext();
|
|
19485
|
+
if (!moduleName2) {
|
|
19486
|
+
throw new Error("No module context");
|
|
19487
|
+
}
|
|
19488
|
+
this.sendAppMessage({
|
|
19489
|
+
type: "refresh_auth_token",
|
|
19490
|
+
module: moduleName2
|
|
19491
|
+
});
|
|
19438
19492
|
}
|
|
19439
|
-
|
|
19440
|
-
|
|
19441
|
-
|
|
19442
|
-
|
|
19443
|
-
|
|
19444
|
-
|
|
19493
|
+
static sendChannelData(channel, data) {
|
|
19494
|
+
const moduleName2 = this.getCurrentModuleContext();
|
|
19495
|
+
if (!moduleName2) {
|
|
19496
|
+
throw new Error("No module context");
|
|
19497
|
+
}
|
|
19498
|
+
this.sendAppMessage({
|
|
19499
|
+
type: "send_channel_data",
|
|
19500
|
+
source: moduleName2,
|
|
19501
|
+
channel,
|
|
19502
|
+
data
|
|
19503
|
+
});
|
|
19445
19504
|
}
|
|
19446
|
-
|
|
19447
|
-
const
|
|
19448
|
-
|
|
19449
|
-
|
|
19505
|
+
static setupModuleMenus(menus) {
|
|
19506
|
+
const moduleName2 = this.getCurrentModuleContext();
|
|
19507
|
+
if (!moduleName2) {
|
|
19508
|
+
throw new Error("No module context");
|
|
19450
19509
|
}
|
|
19451
|
-
|
|
19510
|
+
this.sendAppMessage({
|
|
19511
|
+
type: "setup_module_menus",
|
|
19512
|
+
module: moduleName2,
|
|
19513
|
+
menus
|
|
19514
|
+
});
|
|
19452
19515
|
}
|
|
19453
|
-
|
|
19454
|
-
|
|
19455
|
-
|
|
19456
|
-
|
|
19457
|
-
|
|
19458
|
-
if (id.length === 0) {
|
|
19459
|
-
throw new Error("Invalid response");
|
|
19460
|
-
}
|
|
19461
|
-
const response = message.slice(16);
|
|
19462
|
-
if (response.length === 0) {
|
|
19463
|
-
throw new Error("Invalid response");
|
|
19516
|
+
static addMenuListener(handler) {
|
|
19517
|
+
window.addEventListener("message", (event) => {
|
|
19518
|
+
const msg = event.data;
|
|
19519
|
+
if (msg.type === "module_menu_item_clicked") {
|
|
19520
|
+
handler(msg.menu);
|
|
19464
19521
|
}
|
|
19465
|
-
|
|
19466
|
-
|
|
19522
|
+
});
|
|
19523
|
+
}
|
|
19524
|
+
static addAccessTokenRefreshListener(handler) {
|
|
19525
|
+
window.addEventListener("message", (event) => {
|
|
19526
|
+
const msg = event.data;
|
|
19527
|
+
if (msg.type === "auth_token") {
|
|
19528
|
+
handler(msg.token);
|
|
19467
19529
|
}
|
|
19468
19530
|
});
|
|
19469
19531
|
}
|
|
19470
|
-
|
|
19471
|
-
|
|
19472
|
-
|
|
19473
|
-
|
|
19474
|
-
if (!this.channel) {
|
|
19475
|
-
throw new Error("Failed to create channel");
|
|
19532
|
+
static addModuleDataListener(handler) {
|
|
19533
|
+
const moduleName2 = this.getCurrentModuleContext();
|
|
19534
|
+
if (moduleName2) {
|
|
19535
|
+
this.sendAppMessage({ type: "request_module_data", module: moduleName2 });
|
|
19476
19536
|
}
|
|
19477
|
-
|
|
19478
|
-
|
|
19479
|
-
|
|
19480
|
-
|
|
19481
|
-
|
|
19482
|
-
|
|
19483
|
-
|
|
19484
|
-
|
|
19485
|
-
await delay(50);
|
|
19486
|
-
if (requestIdToResponseMap.has(id)) {
|
|
19487
|
-
const response = requestIdToResponseMap.get(id);
|
|
19488
|
-
if (response !== true) {
|
|
19489
|
-
requestIdToResponseMap.delete(id);
|
|
19490
|
-
const success = response[0] === this.RESPONSE_SUCCESS_BYTE;
|
|
19491
|
-
const payload = response.slice(1);
|
|
19492
|
-
if (success) {
|
|
19493
|
-
return payload;
|
|
19494
|
-
} else {
|
|
19495
|
-
console.error({
|
|
19496
|
-
name: "AdapterError",
|
|
19497
|
-
message: this.decoder.decode(payload)
|
|
19498
|
-
});
|
|
19499
|
-
throw new Error("Binary request datachannel adapter error");
|
|
19500
|
-
}
|
|
19501
|
-
}
|
|
19537
|
+
window.addEventListener("message", (event) => {
|
|
19538
|
+
const msg = event.data;
|
|
19539
|
+
if (msg.type === "module_data") {
|
|
19540
|
+
handler({
|
|
19541
|
+
streams: msg.streams,
|
|
19542
|
+
time: msg.time,
|
|
19543
|
+
queryRange: msg.queryRange
|
|
19544
|
+
});
|
|
19502
19545
|
}
|
|
19503
|
-
}
|
|
19504
|
-
requestIdToResponseMap.delete(id);
|
|
19505
|
-
console.error({
|
|
19506
|
-
name: "TimeoutError",
|
|
19507
|
-
message: `Request timed out after ${timeout / 1e3} seconds`
|
|
19508
19546
|
});
|
|
19509
|
-
throw new Error("Binary request data channel request timed out");
|
|
19510
19547
|
}
|
|
19511
|
-
|
|
19512
|
-
|
|
19513
|
-
|
|
19514
|
-
|
|
19515
|
-
|
|
19516
|
-
|
|
19517
|
-
|
|
19518
|
-
|
|
19519
|
-
|
|
19520
|
-
|
|
19521
|
-
|
|
19522
|
-
|
|
19523
|
-
|
|
19524
|
-
|
|
19525
|
-
|
|
19548
|
+
static addStreamListener(streamName, streamType, handler) {
|
|
19549
|
+
const listener = (event) => {
|
|
19550
|
+
const msg = event.data;
|
|
19551
|
+
if (msg.type === "module_data") {
|
|
19552
|
+
const { start, end } = msg.queryRange;
|
|
19553
|
+
handler(
|
|
19554
|
+
queryStore.moduleQuery(
|
|
19555
|
+
{},
|
|
19556
|
+
streamName,
|
|
19557
|
+
streamType,
|
|
19558
|
+
new Date(start),
|
|
19559
|
+
new Date(end),
|
|
19560
|
+
false
|
|
19561
|
+
)
|
|
19562
|
+
);
|
|
19526
19563
|
}
|
|
19527
|
-
|
|
19528
|
-
|
|
19564
|
+
};
|
|
19565
|
+
window.addEventListener("message", listener);
|
|
19566
|
+
return () => window.removeEventListener("message", listener);
|
|
19567
|
+
}
|
|
19568
|
+
static addModuleConfigurationListener(handler) {
|
|
19569
|
+
window.addEventListener("message", (event) => {
|
|
19570
|
+
const msg = event.data;
|
|
19571
|
+
if (msg.type === "module_configuration") {
|
|
19572
|
+
handler(msg);
|
|
19529
19573
|
}
|
|
19530
19574
|
});
|
|
19531
19575
|
}
|
|
19532
|
-
|
|
19533
|
-
|
|
19534
|
-
|
|
19535
|
-
|
|
19536
|
-
|
|
19537
|
-
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
await channel.waitTilReady();
|
|
19541
|
-
const id = this.generateTextId();
|
|
19542
|
-
requestIdToResponseMap.set(id, true);
|
|
19543
|
-
channel.send(
|
|
19544
|
-
JSON.stringify({
|
|
19545
|
-
id,
|
|
19546
|
-
data
|
|
19547
|
-
})
|
|
19548
|
-
);
|
|
19549
|
-
const start = new Date().getTime();
|
|
19550
|
-
while (new Date().getTime() < start + timeout) {
|
|
19551
|
-
await delay(50);
|
|
19552
|
-
if (requestIdToResponseMap.has(id)) {
|
|
19553
|
-
const response = requestIdToResponseMap.get(id);
|
|
19554
|
-
if (response !== true) {
|
|
19555
|
-
requestIdToResponseMap.delete(id);
|
|
19556
|
-
const { data: data2, error } = response;
|
|
19557
|
-
if (data2) {
|
|
19558
|
-
return data2;
|
|
19559
|
-
}
|
|
19560
|
-
if (error) {
|
|
19561
|
-
console.error({
|
|
19562
|
-
name: "AdapterError",
|
|
19563
|
-
message: error
|
|
19564
|
-
});
|
|
19565
|
-
throw new Error("Text request datachannel adapter error");
|
|
19566
|
-
}
|
|
19567
|
-
}
|
|
19576
|
+
static addChannelDataListener(channel, handler) {
|
|
19577
|
+
window.addEventListener("message", (event) => {
|
|
19578
|
+
const msg = event.data;
|
|
19579
|
+
if (msg.type === "channel_data" && msg.channel === channel) {
|
|
19580
|
+
handler({
|
|
19581
|
+
source: msg.source,
|
|
19582
|
+
data: msg.data
|
|
19583
|
+
});
|
|
19568
19584
|
}
|
|
19569
|
-
}
|
|
19570
|
-
requestIdToResponseMap.delete(id);
|
|
19571
|
-
console.error({
|
|
19572
|
-
name: "TimeoutError",
|
|
19573
|
-
message: `Request timed out after ${timeout / 1e3} seconds`
|
|
19574
19585
|
});
|
|
19575
|
-
throw new Error("Text request datachannel request timed out");
|
|
19576
19586
|
}
|
|
19577
|
-
|
|
19578
|
-
|
|
19579
|
-
|
|
19580
|
-
const
|
|
19581
|
-
|
|
19582
|
-
Observe: 3
|
|
19583
|
-
};
|
|
19584
|
-
class Device {
|
|
19585
|
-
constructor(id, name, organizationId) {
|
|
19586
|
-
__publicField(this, "rtcClient");
|
|
19587
|
-
__publicField(this, "remoteDevicePeerId");
|
|
19588
|
-
__publicField(this, "realtimeListeners", []);
|
|
19589
|
-
__publicField(this, "handleMessage", (peerId, message) => {
|
|
19590
|
-
this.realtimeListeners.forEach((_) => _(peerId, message));
|
|
19587
|
+
static requestOverviewDevices(handler) {
|
|
19588
|
+
this.sendAppMessage({ type: "request_devices" });
|
|
19589
|
+
window.addEventListener("message", (event) => {
|
|
19590
|
+
const msg = event.data;
|
|
19591
|
+
handler(msg);
|
|
19591
19592
|
});
|
|
19592
|
-
this.id = id;
|
|
19593
|
-
this.name = name;
|
|
19594
|
-
this.organizationId = organizationId;
|
|
19595
19593
|
}
|
|
19596
|
-
async
|
|
19597
|
-
|
|
19598
|
-
|
|
19599
|
-
{
|
|
19594
|
+
static async prompt(schema, options) {
|
|
19595
|
+
return new Promise((resolve) => {
|
|
19596
|
+
const promptId = Math.random().toString();
|
|
19597
|
+
this.sendAppMessage({
|
|
19598
|
+
type: "prompt",
|
|
19599
|
+
promptId,
|
|
19600
|
+
schema,
|
|
19601
|
+
okText: options == null ? void 0 : options.okText,
|
|
19602
|
+
cancelText: options == null ? void 0 : options.cancelText
|
|
19603
|
+
});
|
|
19604
|
+
const handler = (event) => {
|
|
19605
|
+
const msg = event.data;
|
|
19606
|
+
if (msg.type === "prompt_response" && msg.promptId === promptId) {
|
|
19607
|
+
resolve(msg.data);
|
|
19608
|
+
}
|
|
19609
|
+
window.removeEventListener("message", handler);
|
|
19610
|
+
};
|
|
19611
|
+
window.addEventListener("message", handler);
|
|
19612
|
+
});
|
|
19613
|
+
}
|
|
19614
|
+
}
|
|
19615
|
+
const _Authentication = class {
|
|
19616
|
+
static async login(email, password) {
|
|
19617
|
+
try {
|
|
19618
|
+
const result = await fetch(`${FORMANT_API_URL}/v1/admin/auth/login`, {
|
|
19600
19619
|
method: "POST",
|
|
19601
|
-
body: JSON.stringify({
|
|
19602
|
-
deviceIds: [this.id]
|
|
19603
|
-
}),
|
|
19620
|
+
body: JSON.stringify({ email, password }),
|
|
19604
19621
|
headers: {
|
|
19605
|
-
"Content-Type": "application/json"
|
|
19606
|
-
Authorization: "Bearer " + Authentication.token
|
|
19622
|
+
"Content-Type": "application/json"
|
|
19607
19623
|
}
|
|
19624
|
+
});
|
|
19625
|
+
const auth = await result.json();
|
|
19626
|
+
if (result.status !== 200) {
|
|
19627
|
+
throw new Error(auth.message);
|
|
19608
19628
|
}
|
|
19609
|
-
|
|
19610
|
-
|
|
19611
|
-
|
|
19612
|
-
}
|
|
19613
|
-
async getConfiguration() {
|
|
19614
|
-
let result = await fetch(`${FORMANT_API_URL}/v1/admin/devices/${this.id}`, {
|
|
19615
|
-
method: "GET",
|
|
19616
|
-
headers: {
|
|
19617
|
-
"Content-Type": "application/json",
|
|
19618
|
-
Authorization: "Bearer " + Authentication.token
|
|
19619
|
-
}
|
|
19620
|
-
});
|
|
19621
|
-
const device = await result.json();
|
|
19622
|
-
if (!device.state.reportedConfiguration) {
|
|
19623
|
-
throw new Error(
|
|
19624
|
-
"Device has no configuration, has it ever been turned on?"
|
|
19629
|
+
await _Authentication.loginWithToken(
|
|
19630
|
+
auth.authentication.accessToken,
|
|
19631
|
+
auth.authentication.refreshToken
|
|
19625
19632
|
);
|
|
19633
|
+
return auth.authentication;
|
|
19634
|
+
} catch (e) {
|
|
19635
|
+
_Authentication.waitingForAuth.forEach((_) => _(false));
|
|
19636
|
+
_Authentication.waitingForAuth = [];
|
|
19637
|
+
return Promise.reject(e);
|
|
19626
19638
|
}
|
|
19627
|
-
const version = device.state.reportedConfiguration.version;
|
|
19628
|
-
result = await fetch(
|
|
19629
|
-
`${FORMANT_API_URL}/v1/admin/devices/${this.id}/configurations/${version}`,
|
|
19630
|
-
{
|
|
19631
|
-
method: "GET",
|
|
19632
|
-
headers: {
|
|
19633
|
-
"Content-Type": "application/json",
|
|
19634
|
-
Authorization: "Bearer " + Authentication.token
|
|
19635
|
-
}
|
|
19636
|
-
}
|
|
19637
|
-
);
|
|
19638
|
-
const config = await result.json();
|
|
19639
|
-
return config.document;
|
|
19640
19639
|
}
|
|
19641
|
-
async
|
|
19642
|
-
const
|
|
19643
|
-
|
|
19644
|
-
|
|
19645
|
-
|
|
19646
|
-
|
|
19647
|
-
|
|
19648
|
-
"Content-Type": "application/json",
|
|
19649
|
-
Authorization: "Bearer " + Authentication.token
|
|
19640
|
+
static async loginWithToken(token, refreshToken) {
|
|
19641
|
+
const tokenData = JSON.parse(atob(token.split(".")[1]));
|
|
19642
|
+
try {
|
|
19643
|
+
let userId;
|
|
19644
|
+
_Authentication.isShareToken = tokenData["formant:claims"] && tokenData["formant:claims"].type == "share";
|
|
19645
|
+
if (tokenData["formant:claims"]) {
|
|
19646
|
+
_Authentication.currentOrganization = tokenData["formant:claims"].organizationId;
|
|
19650
19647
|
}
|
|
19651
|
-
|
|
19652
|
-
|
|
19653
|
-
return files.fileUrls;
|
|
19654
|
-
}
|
|
19655
|
-
getRealtimeStatus() {
|
|
19656
|
-
if (this.rtcClient && this.remoteDevicePeerId) {
|
|
19657
|
-
return this.rtcClient.getConnectionStatus(this.remoteDevicePeerId);
|
|
19658
|
-
} else {
|
|
19659
|
-
throw new Error(`Realtime connection hasn't been started for ${this.id}`);
|
|
19660
|
-
}
|
|
19661
|
-
}
|
|
19662
|
-
getRealtimePing() {
|
|
19663
|
-
if (this.rtcClient && this.remoteDevicePeerId) {
|
|
19664
|
-
return this.rtcClient.getPing(this.remoteDevicePeerId);
|
|
19665
|
-
} else {
|
|
19666
|
-
throw new Error(`Realtime connection hasn't been started for ${this.id}`);
|
|
19667
|
-
}
|
|
19668
|
-
}
|
|
19669
|
-
async startRealtimeConnection(sessionType) {
|
|
19670
|
-
if (!this.rtcClient) {
|
|
19671
|
-
let rtcClient;
|
|
19672
|
-
if (rtcClientVersion === "1") {
|
|
19673
|
-
rtcClient = new dist.exports.RtcClientV1({
|
|
19674
|
-
signalingClient: new dist.exports.RtcSignalingClient(
|
|
19675
|
-
FORMANT_API_URL + "/v1/signaling"
|
|
19676
|
-
),
|
|
19677
|
-
getToken: async () => defined(
|
|
19678
|
-
Authentication.token,
|
|
19679
|
-
"Realtime when user isn't authorized"
|
|
19680
|
-
),
|
|
19681
|
-
receive: this.handleMessage
|
|
19682
|
-
});
|
|
19683
|
-
} else {
|
|
19684
|
-
rtcClient = new dist.exports.RtcClient({
|
|
19685
|
-
signalingClient: new dist.exports.SignalingPromiseClient(
|
|
19686
|
-
FORMANT_API_URL,
|
|
19687
|
-
null,
|
|
19688
|
-
null
|
|
19689
|
-
),
|
|
19690
|
-
getToken: async () => {
|
|
19691
|
-
return defined(
|
|
19692
|
-
Authentication.token,
|
|
19693
|
-
"Realtime when user isn't authorized"
|
|
19694
|
-
);
|
|
19695
|
-
},
|
|
19696
|
-
receive: this.handleMessage,
|
|
19697
|
-
sessionType
|
|
19698
|
-
});
|
|
19648
|
+
if (tokenData["custom:organization_id"]) {
|
|
19649
|
+
_Authentication.currentOrganization = tokenData["custom:organization_id"];
|
|
19699
19650
|
}
|
|
19700
|
-
if (
|
|
19701
|
-
|
|
19702
|
-
await delay(100);
|
|
19703
|
-
}
|
|
19651
|
+
if (!_Authentication.isShareToken) {
|
|
19652
|
+
userId = tokenData.sub;
|
|
19704
19653
|
}
|
|
19705
|
-
|
|
19706
|
-
|
|
19707
|
-
if (!devicePeer) {
|
|
19708
|
-
throw new Error("Cannot find peer, is the robot offline?");
|
|
19709
|
-
}
|
|
19710
|
-
this.remoteDevicePeerId = devicePeer.id;
|
|
19711
|
-
await rtcClient.connect(this.remoteDevicePeerId);
|
|
19712
|
-
while (rtcClient.getConnectionStatus(this.remoteDevicePeerId) !== "connected") {
|
|
19713
|
-
await delay(100);
|
|
19714
|
-
}
|
|
19715
|
-
this.rtcClient = rtcClient;
|
|
19716
|
-
} else {
|
|
19717
|
-
throw new Error(
|
|
19718
|
-
`Already created realtime connection to device ${this.id}`
|
|
19719
|
-
);
|
|
19720
|
-
}
|
|
19721
|
-
}
|
|
19722
|
-
async sendRealtimeMessage(message, config = {
|
|
19723
|
-
channelLabel: "stream.reliable"
|
|
19724
|
-
}) {
|
|
19725
|
-
const client = defined(
|
|
19726
|
-
this.rtcClient,
|
|
19727
|
-
"Realtime connection has not been started"
|
|
19728
|
-
);
|
|
19729
|
-
const devicePeer = await this.getRemotePeer();
|
|
19730
|
-
client.send(defined(devicePeer).id, message, config);
|
|
19731
|
-
}
|
|
19732
|
-
addRealtimeListener(listener) {
|
|
19733
|
-
this.realtimeListeners.push(listener);
|
|
19734
|
-
}
|
|
19735
|
-
removeRealtimeListener(listener) {
|
|
19736
|
-
const i = this.realtimeListeners.indexOf(listener);
|
|
19737
|
-
if (i === -1) {
|
|
19738
|
-
throw new Error("Could not find realtime listener to remove");
|
|
19739
|
-
}
|
|
19740
|
-
this.realtimeListeners.splice(i, 1);
|
|
19741
|
-
}
|
|
19742
|
-
async getRealtimeAudioStreams() {
|
|
19743
|
-
var _a, _b, _c, _d, _e, _f;
|
|
19744
|
-
const document2 = await this.getConfiguration();
|
|
19745
|
-
const streams = [];
|
|
19746
|
-
for (const _ of (_b = (_a = document2.teleop) == null ? void 0 : _a.hardwareStreams) != null ? _b : []) {
|
|
19747
|
-
if (_.rtcStreamType === "audio-chunk") {
|
|
19748
|
-
streams.push({
|
|
19749
|
-
name: _.name
|
|
19750
|
-
});
|
|
19751
|
-
}
|
|
19752
|
-
}
|
|
19753
|
-
for (const _ of (_d = (_c = document2.teleop) == null ? void 0 : _c.rosStreams) != null ? _d : []) {
|
|
19754
|
-
if (_.topicType == "audio_common_msgs/AudioData") {
|
|
19755
|
-
streams.push({
|
|
19756
|
-
name: _.topicName
|
|
19757
|
-
});
|
|
19758
|
-
}
|
|
19759
|
-
}
|
|
19760
|
-
for (const _ of (_f = (_e = document2.teleop) == null ? void 0 : _e.customStreams) != null ? _f : []) {
|
|
19761
|
-
if (_.rtcStreamType === "audio-chunk") {
|
|
19762
|
-
streams.push({
|
|
19763
|
-
name: _.name
|
|
19764
|
-
});
|
|
19765
|
-
}
|
|
19766
|
-
}
|
|
19767
|
-
return streams;
|
|
19768
|
-
}
|
|
19769
|
-
async getRealtimeVideoStreams() {
|
|
19770
|
-
var _a, _b, _c, _d, _e, _f;
|
|
19771
|
-
const document2 = await this.getConfiguration();
|
|
19772
|
-
const streams = [];
|
|
19773
|
-
for (const _ of (_b = (_a = document2.teleop) == null ? void 0 : _a.hardwareStreams) != null ? _b : []) {
|
|
19774
|
-
if (_.rtcStreamType === "h264-video-frame") {
|
|
19775
|
-
streams.push({
|
|
19776
|
-
name: _.name
|
|
19777
|
-
});
|
|
19778
|
-
}
|
|
19779
|
-
}
|
|
19780
|
-
for (const _ of (_d = (_c = document2.teleop) == null ? void 0 : _c.rosStreams) != null ? _d : []) {
|
|
19781
|
-
if (_.topicType == "formant/H264VideoFrame") {
|
|
19782
|
-
streams.push({
|
|
19783
|
-
name: _.topicName
|
|
19784
|
-
});
|
|
19785
|
-
}
|
|
19786
|
-
}
|
|
19787
|
-
for (const _ of (_f = (_e = document2.teleop) == null ? void 0 : _e.customStreams) != null ? _f : []) {
|
|
19788
|
-
if (_.rtcStreamType === "h264-video-frame") {
|
|
19789
|
-
streams.push({
|
|
19790
|
-
name: _.name
|
|
19791
|
-
});
|
|
19792
|
-
}
|
|
19793
|
-
}
|
|
19794
|
-
return streams;
|
|
19795
|
-
}
|
|
19796
|
-
async getRealtimeManipulators() {
|
|
19797
|
-
var _a;
|
|
19798
|
-
const document2 = await this.getConfiguration();
|
|
19799
|
-
const manipulators = [];
|
|
19800
|
-
for (const _ of (_a = document2.teleop.rosStreams) != null ? _a : []) {
|
|
19801
|
-
if (_.topicType == "sensor_msgs/JointState") {
|
|
19802
|
-
manipulators.push(
|
|
19803
|
-
new Manipulator(this, {
|
|
19804
|
-
currentJointStateStream: { name: _.topicName },
|
|
19805
|
-
plannedJointStateStream: _.plannedTopic ? { name: _.plannedTopic } : void 0,
|
|
19806
|
-
planValidStream: _.planValidTopic ? { name: _.planValidTopic } : void 0,
|
|
19807
|
-
endEffectorStream: _.endEffectorTopic ? { name: _.endEffectorTopic } : void 0,
|
|
19808
|
-
endEffectorLinkName: _.endEffectorLinkName,
|
|
19809
|
-
baseReferenceFrame: _.baseReferenceFrame,
|
|
19810
|
-
localFrame: _.localFrame
|
|
19811
|
-
})
|
|
19812
|
-
);
|
|
19813
|
-
}
|
|
19814
|
-
}
|
|
19815
|
-
return manipulators;
|
|
19816
|
-
}
|
|
19817
|
-
async startListeningToRealtimeVideo(stream) {
|
|
19818
|
-
const client = defined(
|
|
19819
|
-
this.rtcClient,
|
|
19820
|
-
"Realtime connection has not been started"
|
|
19821
|
-
);
|
|
19822
|
-
const devicePeer = await this.getRemotePeer();
|
|
19823
|
-
client.controlRemoteStream(defined(devicePeer).id, {
|
|
19824
|
-
streamName: stream.name,
|
|
19825
|
-
enable: true,
|
|
19826
|
-
pipeline: "rtc"
|
|
19827
|
-
});
|
|
19828
|
-
}
|
|
19829
|
-
async stopListeningToRealtimeVideo(stream) {
|
|
19830
|
-
const client = defined(
|
|
19831
|
-
this.rtcClient,
|
|
19832
|
-
"Realtime connection has not been started"
|
|
19833
|
-
);
|
|
19834
|
-
const devicePeer = await this.getRemotePeer();
|
|
19835
|
-
client.controlRemoteStream(defined(devicePeer).id, {
|
|
19836
|
-
streamName: stream.name,
|
|
19837
|
-
enable: false,
|
|
19838
|
-
pipeline: "rtc"
|
|
19839
|
-
});
|
|
19840
|
-
}
|
|
19841
|
-
async startListeningToRealtimeDataStream(stream) {
|
|
19842
|
-
const client = defined(
|
|
19843
|
-
this.rtcClient,
|
|
19844
|
-
"Realtime connection has not been started"
|
|
19845
|
-
);
|
|
19846
|
-
const devicePeer = await this.getRemotePeer();
|
|
19847
|
-
client.controlRemoteStream(defined(devicePeer).id, {
|
|
19848
|
-
streamName: stream.name,
|
|
19849
|
-
enable: true,
|
|
19850
|
-
pipeline: "rtc"
|
|
19851
|
-
});
|
|
19852
|
-
}
|
|
19853
|
-
async stopListeningToRealtimeDataStream(stream) {
|
|
19854
|
-
const client = defined(
|
|
19855
|
-
this.rtcClient,
|
|
19856
|
-
"Realtime connection has not been started"
|
|
19857
|
-
);
|
|
19858
|
-
const devicePeer = await this.getRemotePeer();
|
|
19859
|
-
client.controlRemoteStream(defined(devicePeer).id, {
|
|
19860
|
-
streamName: stream.name,
|
|
19861
|
-
enable: false,
|
|
19862
|
-
pipeline: "rtc"
|
|
19863
|
-
});
|
|
19864
|
-
}
|
|
19865
|
-
async enableRealtimeTelemetryPriorityIngestion(streamName) {
|
|
19866
|
-
const client = defined(
|
|
19867
|
-
this.rtcClient,
|
|
19868
|
-
"Realtime connection has not been started"
|
|
19869
|
-
);
|
|
19870
|
-
const devicePeer = await this.getRemotePeer();
|
|
19871
|
-
client.controlRemoteStream(defined(devicePeer).id, {
|
|
19872
|
-
streamName,
|
|
19873
|
-
enablePriorityUpload: true,
|
|
19874
|
-
pipeline: "telemetry"
|
|
19875
|
-
});
|
|
19876
|
-
}
|
|
19877
|
-
async changeStreamAudioType(streamName, newFormat) {
|
|
19878
|
-
const client = defined(
|
|
19879
|
-
this.rtcClient,
|
|
19880
|
-
"Realtime connection has not been started"
|
|
19881
|
-
);
|
|
19882
|
-
const devicePeer = await this.getRemotePeer();
|
|
19883
|
-
client.controlRemoteStream(defined(devicePeer).id, {
|
|
19884
|
-
streamName,
|
|
19885
|
-
setAudioFormat: newFormat
|
|
19886
|
-
});
|
|
19887
|
-
}
|
|
19888
|
-
async disableRealtimeTelemetryPriorityIngestion(streamName) {
|
|
19889
|
-
const client = defined(
|
|
19890
|
-
this.rtcClient,
|
|
19891
|
-
"Realtime connection has not been started"
|
|
19892
|
-
);
|
|
19893
|
-
const devicePeer = await this.getRemotePeer();
|
|
19894
|
-
client.controlRemoteStream(defined(devicePeer).id, {
|
|
19895
|
-
streamName,
|
|
19896
|
-
enablePriorityUpload: false,
|
|
19897
|
-
pipeline: "telemetry"
|
|
19898
|
-
});
|
|
19899
|
-
}
|
|
19900
|
-
async getRemotePeer() {
|
|
19901
|
-
const peers = await defined(
|
|
19902
|
-
this.rtcClient,
|
|
19903
|
-
"Realtime connection has not been started"
|
|
19904
|
-
).getPeers();
|
|
19905
|
-
const devicePeer = peers.find((_) => _.deviceId === this.id);
|
|
19906
|
-
return defined(
|
|
19907
|
-
devicePeer,
|
|
19908
|
-
"Could not find remote peer for device " + this.id
|
|
19909
|
-
);
|
|
19910
|
-
}
|
|
19911
|
-
async stopRealtimeConnection() {
|
|
19912
|
-
if (this.rtcClient) {
|
|
19913
|
-
await this.rtcClient.disconnect(this.id);
|
|
19914
|
-
} else {
|
|
19915
|
-
throw new Error(`Realtime connection hasn't been started for ${this.id}`);
|
|
19916
|
-
}
|
|
19917
|
-
}
|
|
19918
|
-
async isInRealtimeSession() {
|
|
19919
|
-
let peers = await Fleet.getPeers();
|
|
19920
|
-
let sessions = await Fleet.getRealtimeSessions();
|
|
19921
|
-
let peer = peers.find((_) => _.deviceId === this.id);
|
|
19922
|
-
if (peer) {
|
|
19923
|
-
return sessions[peer.id].length > 0;
|
|
19924
|
-
}
|
|
19925
|
-
return false;
|
|
19926
|
-
}
|
|
19927
|
-
async getAvailableCommands() {
|
|
19928
|
-
const result = await fetch(
|
|
19929
|
-
`${FORMANT_API_URL}/v1/admin/command-templates/`,
|
|
19930
|
-
{
|
|
19931
|
-
method: "GET",
|
|
19932
|
-
headers: {
|
|
19933
|
-
"Content-Type": "application/json",
|
|
19934
|
-
Authorization: "Bearer " + Authentication.token
|
|
19935
|
-
}
|
|
19936
|
-
}
|
|
19937
|
-
);
|
|
19938
|
-
const commands = await result.json();
|
|
19939
|
-
return commands.items.map((i) => ({
|
|
19940
|
-
name: i.name,
|
|
19941
|
-
id: i.id,
|
|
19942
|
-
command: i.command,
|
|
19943
|
-
description: i.description,
|
|
19944
|
-
parameterEnabled: i.parameterEnabled,
|
|
19945
|
-
parameterValue: i.parameterValue,
|
|
19946
|
-
parameterMeta: i.parameterMeta,
|
|
19947
|
-
enabled: i.enabled
|
|
19948
|
-
}));
|
|
19949
|
-
}
|
|
19950
|
-
async sendCommand(name, data, time, metadata) {
|
|
19951
|
-
var _a;
|
|
19952
|
-
const commands = await this.getAvailableCommands();
|
|
19953
|
-
const command = commands.find((_) => _.name === name);
|
|
19954
|
-
if (!command) {
|
|
19955
|
-
throw new Error(`Could not find command with name "${name}"`);
|
|
19956
|
-
}
|
|
19957
|
-
let d;
|
|
19958
|
-
if (data === void 0) {
|
|
19959
|
-
if (command.parameterEnabled && command.parameterValue) {
|
|
19960
|
-
d = command.parameterValue;
|
|
19961
|
-
} else {
|
|
19962
|
-
throw new Error(
|
|
19963
|
-
"Command has no default parameter value, you must provide one"
|
|
19964
|
-
);
|
|
19965
|
-
}
|
|
19966
|
-
} else {
|
|
19967
|
-
d = data;
|
|
19968
|
-
}
|
|
19969
|
-
let parameter = {
|
|
19970
|
-
value: d,
|
|
19971
|
-
scrubberTime: (time || new Date()).toISOString(),
|
|
19972
|
-
meta: {
|
|
19973
|
-
...command.parameterMeta,
|
|
19974
|
-
...metadata
|
|
19975
|
-
}
|
|
19976
|
-
};
|
|
19977
|
-
await fetch(`${FORMANT_API_URL}/v1/admin/commands`, {
|
|
19978
|
-
method: "POST",
|
|
19979
|
-
body: JSON.stringify({
|
|
19980
|
-
commandTemplateId: command.id,
|
|
19981
|
-
organizationId: this.organizationId,
|
|
19982
|
-
deviceId: this.id,
|
|
19983
|
-
command: command.command,
|
|
19984
|
-
parameter,
|
|
19985
|
-
userId: (_a = Authentication.currentUser) == null ? void 0 : _a.id
|
|
19986
|
-
}),
|
|
19987
|
-
headers: {
|
|
19988
|
-
"Content-Type": "application/json",
|
|
19989
|
-
Authorization: "Bearer " + Authentication.token
|
|
19990
|
-
}
|
|
19991
|
-
});
|
|
19992
|
-
}
|
|
19993
|
-
async createCustomDataChannel(channelName, rtcConfig) {
|
|
19994
|
-
if (rtcClientVersion === "1") {
|
|
19995
|
-
throw new Error(
|
|
19996
|
-
"createCustomDataChannel is not supported in rtcClientVersion 1"
|
|
19997
|
-
);
|
|
19998
|
-
}
|
|
19999
|
-
const client = defined(
|
|
20000
|
-
this.rtcClient,
|
|
20001
|
-
"Realtime connection has not been started"
|
|
20002
|
-
);
|
|
20003
|
-
const devicePeer = await this.getRemotePeer();
|
|
20004
|
-
const p = await new Promise((resolve) => {
|
|
20005
|
-
client.createCustomDataChannel(
|
|
20006
|
-
defined(devicePeer).id,
|
|
20007
|
-
channelName,
|
|
20008
|
-
{
|
|
20009
|
-
ordered: true,
|
|
20010
|
-
...rtcConfig
|
|
20011
|
-
},
|
|
20012
|
-
false,
|
|
20013
|
-
(_peerId, channel) => {
|
|
20014
|
-
const dataChannel = new DataChannel(channel);
|
|
20015
|
-
resolve(dataChannel);
|
|
20016
|
-
}
|
|
20017
|
-
);
|
|
20018
|
-
});
|
|
20019
|
-
await p.waitTilReady();
|
|
20020
|
-
return p;
|
|
20021
|
-
}
|
|
20022
|
-
createCustomRequestDataChannel(channelName, timeout = 3e3) {
|
|
20023
|
-
return new TextRequestDataChannel(this, channelName, timeout);
|
|
20024
|
-
}
|
|
20025
|
-
createCustomBinaryRequestDataChannel(channelName, timeout = 3e3) {
|
|
20026
|
-
return new BinaryRequestDataChannel(this, channelName, timeout);
|
|
20027
|
-
}
|
|
20028
|
-
async createCaptureStream(streamName) {
|
|
20029
|
-
const result = await fetch(`${FORMANT_API_URL}/v1/admin/capture-sessions`, {
|
|
20030
|
-
method: "POST",
|
|
20031
|
-
body: JSON.stringify({
|
|
20032
|
-
deviceId: this.id,
|
|
20033
|
-
streamName,
|
|
20034
|
-
tags: {}
|
|
20035
|
-
}),
|
|
20036
|
-
headers: {
|
|
20037
|
-
"Content-Type": "application/json",
|
|
20038
|
-
Authorization: "Bearer " + Authentication.token
|
|
20039
|
-
}
|
|
20040
|
-
});
|
|
20041
|
-
const captureSession = await result.json();
|
|
20042
|
-
return new CaptureStream(captureSession);
|
|
20043
|
-
}
|
|
20044
|
-
async getTelemetry(streamNameOrStreamNames, start, end, tags) {
|
|
20045
|
-
return await Fleet.getTelemetry(
|
|
20046
|
-
this.id,
|
|
20047
|
-
streamNameOrStreamNames,
|
|
20048
|
-
start,
|
|
20049
|
-
end,
|
|
20050
|
-
tags
|
|
20051
|
-
);
|
|
20052
|
-
}
|
|
20053
|
-
async getTelemetryStreams() {
|
|
20054
|
-
var _a, _b;
|
|
20055
|
-
const config = await this.getConfiguration();
|
|
20056
|
-
const result = await fetch(
|
|
20057
|
-
`${FORMANT_API_URL}/v1/queries/metadata/stream-names`,
|
|
20058
|
-
{
|
|
20059
|
-
method: "POST",
|
|
20060
|
-
body: JSON.stringify({
|
|
20061
|
-
deviceIds: [this.id]
|
|
20062
|
-
}),
|
|
20063
|
-
headers: {
|
|
20064
|
-
"Content-Type": "application/json",
|
|
20065
|
-
Authorization: "Bearer " + Authentication.token
|
|
20066
|
-
}
|
|
20067
|
-
}
|
|
20068
|
-
);
|
|
20069
|
-
const disabledList = [];
|
|
20070
|
-
const onDemandList = [];
|
|
20071
|
-
(_b = (_a = config.telemetry) == null ? void 0 : _a.streams) == null ? void 0 : _b.forEach((_) => {
|
|
20072
|
-
if (_.disabled !== true) {
|
|
20073
|
-
disabledList.push(_.name);
|
|
20074
|
-
}
|
|
20075
|
-
if (_.onDemand === true) {
|
|
20076
|
-
onDemandList.push(_.name);
|
|
20077
|
-
}
|
|
20078
|
-
});
|
|
20079
|
-
console.log(onDemandList);
|
|
20080
|
-
const data = await result.json();
|
|
20081
|
-
let streamNames = data.items.filter((_) => !disabledList.includes(_)).map((_) => ({ name: _, onDemand: onDemandList.includes(_) }));
|
|
20082
|
-
return streamNames;
|
|
20083
|
-
}
|
|
20084
|
-
async createInterventionRequest(message, interventionType, interventionRequest, tags) {
|
|
20085
|
-
const intervention = await fetch(
|
|
20086
|
-
`${FORMANT_API_URL}/v1/admin/intervention-requests`,
|
|
20087
|
-
{
|
|
20088
|
-
method: "POST",
|
|
20089
|
-
body: JSON.stringify({
|
|
20090
|
-
message,
|
|
20091
|
-
interventionType,
|
|
20092
|
-
time: new Date().toISOString(),
|
|
20093
|
-
deviceId: this.id,
|
|
20094
|
-
tags,
|
|
20095
|
-
data: interventionRequest
|
|
20096
|
-
}),
|
|
20097
|
-
headers: {
|
|
20098
|
-
"Content-Type": "application/json",
|
|
20099
|
-
Authorization: "Bearer " + Authentication.token
|
|
20100
|
-
}
|
|
19654
|
+
if (tokenData["formant:claims"] && tokenData["formant:claims"].userId) {
|
|
19655
|
+
userId = tokenData["formant:claims"].userId;
|
|
20101
19656
|
}
|
|
20102
|
-
|
|
20103
|
-
|
|
20104
|
-
|
|
20105
|
-
|
|
20106
|
-
|
|
20107
|
-
|
|
20108
|
-
|
|
20109
|
-
|
|
20110
|
-
|
|
20111
|
-
|
|
20112
|
-
|
|
20113
|
-
|
|
20114
|
-
|
|
20115
|
-
|
|
20116
|
-
headers: {
|
|
20117
|
-
"Content-Type": "application/json",
|
|
20118
|
-
Authorization: "Bearer " + Authentication.token
|
|
19657
|
+
if (userId) {
|
|
19658
|
+
const result = await fetch(
|
|
19659
|
+
`${FORMANT_API_URL}/v1/admin/users/${userId}`,
|
|
19660
|
+
{
|
|
19661
|
+
method: "GET",
|
|
19662
|
+
headers: {
|
|
19663
|
+
"Content-Type": "application/json",
|
|
19664
|
+
Authorization: "Bearer " + token
|
|
19665
|
+
}
|
|
19666
|
+
}
|
|
19667
|
+
);
|
|
19668
|
+
const data = await result.json();
|
|
19669
|
+
if (result.status !== 200) {
|
|
19670
|
+
throw new Error(data.message);
|
|
20119
19671
|
}
|
|
19672
|
+
_Authentication.currentUser = data;
|
|
20120
19673
|
}
|
|
20121
|
-
|
|
20122
|
-
|
|
20123
|
-
|
|
20124
|
-
|
|
20125
|
-
|
|
20126
|
-
class PeerDevice {
|
|
20127
|
-
constructor(peerUrl) {
|
|
20128
|
-
__publicField(this, "rtcClient");
|
|
20129
|
-
__publicField(this, "remoteDevicePeerId");
|
|
20130
|
-
__publicField(this, "realtimeListeners", []);
|
|
20131
|
-
__publicField(this, "id");
|
|
20132
|
-
__publicField(this, "handleMessage", (peerId, message) => {
|
|
20133
|
-
this.realtimeListeners.forEach((_) => _(peerId, message));
|
|
20134
|
-
});
|
|
20135
|
-
this.peerUrl = peerUrl;
|
|
20136
|
-
}
|
|
20137
|
-
async getLatestTelemetry() {
|
|
20138
|
-
const data = await fetch(`${this.peerUrl}/telemetry`);
|
|
20139
|
-
const telemetry = await data.json();
|
|
20140
|
-
const entries = Object.entries(telemetry);
|
|
20141
|
-
return entries.map(([stream, latestValue]) => {
|
|
20142
|
-
const v = {
|
|
20143
|
-
deviceId: this.id,
|
|
20144
|
-
streamName: stream,
|
|
20145
|
-
streamType: "json",
|
|
20146
|
-
currentValue: latestValue,
|
|
20147
|
-
currentValueTime: latestValue.timestamp,
|
|
20148
|
-
tags: {}
|
|
20149
|
-
};
|
|
20150
|
-
return v;
|
|
20151
|
-
});
|
|
20152
|
-
}
|
|
20153
|
-
async getDeviceId() {
|
|
20154
|
-
let result = await fetch(`${this.peerUrl}/configuration`);
|
|
20155
|
-
const cfg = await result.json();
|
|
20156
|
-
return cfg.agent_config.id;
|
|
20157
|
-
}
|
|
20158
|
-
async getConfiguration() {
|
|
20159
|
-
let result = await fetch(`${this.peerUrl}/configuration`);
|
|
20160
|
-
const cfg = await result.json();
|
|
20161
|
-
return cfg.agent_config.document;
|
|
20162
|
-
}
|
|
20163
|
-
getRealtimeStatus() {
|
|
20164
|
-
if (this.rtcClient && this.remoteDevicePeerId) {
|
|
20165
|
-
return this.rtcClient.getConnectionStatus(this.remoteDevicePeerId);
|
|
20166
|
-
} else {
|
|
20167
|
-
throw new Error(`Realtime connection hasn't been started`);
|
|
20168
|
-
}
|
|
20169
|
-
}
|
|
20170
|
-
getRealtimePing() {
|
|
20171
|
-
if (this.rtcClient && this.remoteDevicePeerId) {
|
|
20172
|
-
return this.rtcClient.getPing(this.remoteDevicePeerId);
|
|
20173
|
-
} else {
|
|
20174
|
-
throw new Error(`Realtime connection hasn't been started`);
|
|
19674
|
+
_Authentication.token = token;
|
|
19675
|
+
_Authentication.waitingForAuth.forEach((_) => _(true));
|
|
19676
|
+
} catch (e) {
|
|
19677
|
+
console.error(e);
|
|
19678
|
+
_Authentication.waitingForAuth.forEach((_) => _(false));
|
|
20175
19679
|
}
|
|
20176
|
-
|
|
20177
|
-
|
|
20178
|
-
|
|
20179
|
-
|
|
20180
|
-
|
|
20181
|
-
|
|
20182
|
-
|
|
20183
|
-
|
|
20184
|
-
|
|
20185
|
-
|
|
20186
|
-
|
|
20187
|
-
|
|
20188
|
-
|
|
20189
|
-
|
|
20190
|
-
|
|
20191
|
-
|
|
20192
|
-
|
|
19680
|
+
_Authentication.waitingForAuth = [];
|
|
19681
|
+
if (refreshToken) {
|
|
19682
|
+
_Authentication.refreshToken = refreshToken;
|
|
19683
|
+
setInterval(async () => {
|
|
19684
|
+
if (_Authentication.refreshToken) {
|
|
19685
|
+
const result = await fetch(
|
|
19686
|
+
`${FORMANT_API_URL}/v1/admin/auth/refresh`,
|
|
19687
|
+
{
|
|
19688
|
+
method: "POST",
|
|
19689
|
+
headers: {
|
|
19690
|
+
"Content-Type": "application/json"
|
|
19691
|
+
},
|
|
19692
|
+
body: JSON.stringify({
|
|
19693
|
+
refreshToken: _Authentication.refreshToken
|
|
19694
|
+
})
|
|
19695
|
+
}
|
|
19696
|
+
);
|
|
19697
|
+
const refreshData = await result.json();
|
|
19698
|
+
_Authentication.token = refreshData.authentication.accessToken;
|
|
19699
|
+
}
|
|
19700
|
+
}, 1e3 * 60 * 60);
|
|
20193
19701
|
}
|
|
20194
19702
|
}
|
|
20195
|
-
|
|
20196
|
-
|
|
19703
|
+
static isAuthenticated() {
|
|
19704
|
+
return _Authentication.token !== void 0;
|
|
20197
19705
|
}
|
|
20198
|
-
|
|
20199
|
-
|
|
20200
|
-
if (i === -1) {
|
|
20201
|
-
throw new Error("Could not find realtime listener to remove");
|
|
20202
|
-
}
|
|
20203
|
-
this.realtimeListeners.splice(i, 1);
|
|
19706
|
+
static getCurrentUser() {
|
|
19707
|
+
return _Authentication.currentUser;
|
|
20204
19708
|
}
|
|
20205
|
-
async
|
|
20206
|
-
|
|
20207
|
-
|
|
20208
|
-
|
|
20209
|
-
|
|
20210
|
-
|
|
20211
|
-
|
|
20212
|
-
name: _.name
|
|
20213
|
-
});
|
|
20214
|
-
}
|
|
20215
|
-
}
|
|
20216
|
-
for (const _ of (_b = document2.teleop.rosStreams) != null ? _b : []) {
|
|
20217
|
-
if (_.topicType == "formant/H264VideoFrame") {
|
|
20218
|
-
streams.push({
|
|
20219
|
-
name: _.topicName
|
|
20220
|
-
});
|
|
20221
|
-
}
|
|
20222
|
-
}
|
|
20223
|
-
for (const _ of (_c = document2.teleop.customStreams) != null ? _c : []) {
|
|
20224
|
-
if (_.rtcStreamType === "h264-video-frame") {
|
|
20225
|
-
streams.push({
|
|
20226
|
-
name: _.name
|
|
19709
|
+
static async waitTilAuthenticated() {
|
|
19710
|
+
if (_Authentication.token !== void 0) {
|
|
19711
|
+
return true;
|
|
19712
|
+
} else {
|
|
19713
|
+
return new Promise((resolve) => {
|
|
19714
|
+
_Authentication.waitingForAuth.push(function(result) {
|
|
19715
|
+
resolve(result);
|
|
20227
19716
|
});
|
|
20228
|
-
}
|
|
20229
|
-
}
|
|
20230
|
-
return streams;
|
|
20231
|
-
}
|
|
20232
|
-
async getRealtimeManipulators() {
|
|
20233
|
-
var _a;
|
|
20234
|
-
const document2 = await this.getConfiguration();
|
|
20235
|
-
const manipulators = [];
|
|
20236
|
-
for (const _ of (_a = document2.teleop.rosStreams) != null ? _a : []) {
|
|
20237
|
-
if (_.topicType == "sensor_msgs/JointState") {
|
|
20238
|
-
manipulators.push(
|
|
20239
|
-
new Manipulator(this, {
|
|
20240
|
-
currentJointStateStream: { name: _.topicName },
|
|
20241
|
-
plannedJointStateStream: _.plannedTopic ? { name: _.plannedTopic } : void 0,
|
|
20242
|
-
planValidStream: _.planValidTopic ? { name: _.planValidTopic } : void 0,
|
|
20243
|
-
endEffectorStream: _.endEffectorTopic ? { name: _.endEffectorTopic } : void 0,
|
|
20244
|
-
endEffectorLinkName: _.endEffectorLinkName,
|
|
20245
|
-
baseReferenceFrame: _.baseReferenceFrame,
|
|
20246
|
-
localFrame: _.localFrame
|
|
20247
|
-
})
|
|
20248
|
-
);
|
|
20249
|
-
}
|
|
19717
|
+
});
|
|
20250
19718
|
}
|
|
20251
|
-
return manipulators;
|
|
20252
|
-
}
|
|
20253
|
-
async startListeningToRealtimeVideo(stream) {
|
|
20254
|
-
const client = defined(
|
|
20255
|
-
this.rtcClient,
|
|
20256
|
-
"Realtime connection has not been started"
|
|
20257
|
-
);
|
|
20258
|
-
const devicePeer = await this.getRemotePeer();
|
|
20259
|
-
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20260
|
-
streamName: stream.name,
|
|
20261
|
-
enable: true,
|
|
20262
|
-
pipeline: "rtc"
|
|
20263
|
-
});
|
|
20264
19719
|
}
|
|
20265
|
-
async
|
|
20266
|
-
|
|
20267
|
-
this.
|
|
20268
|
-
"Realtime connection has not been started"
|
|
20269
|
-
);
|
|
20270
|
-
const devicePeer = await this.getRemotePeer();
|
|
20271
|
-
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20272
|
-
streamName: stream.name,
|
|
20273
|
-
enable: false,
|
|
20274
|
-
pipeline: "rtc"
|
|
19720
|
+
static async listenForRefresh() {
|
|
19721
|
+
App.addAccessTokenRefreshListener((token) => {
|
|
19722
|
+
this.loginWithToken(token);
|
|
20275
19723
|
});
|
|
19724
|
+
setInterval(async () => {
|
|
19725
|
+
App.refreshAuthToken();
|
|
19726
|
+
}, 1e3 * 60 * 60);
|
|
20276
19727
|
}
|
|
20277
|
-
|
|
20278
|
-
|
|
20279
|
-
|
|
20280
|
-
|
|
20281
|
-
|
|
20282
|
-
|
|
20283
|
-
|
|
20284
|
-
|
|
20285
|
-
|
|
20286
|
-
|
|
20287
|
-
|
|
19728
|
+
};
|
|
19729
|
+
let Authentication = _Authentication;
|
|
19730
|
+
__publicField(Authentication, "token");
|
|
19731
|
+
__publicField(Authentication, "refreshToken");
|
|
19732
|
+
__publicField(Authentication, "currentUser");
|
|
19733
|
+
__publicField(Authentication, "currentOrganization");
|
|
19734
|
+
__publicField(Authentication, "isShareToken", false);
|
|
19735
|
+
__publicField(Authentication, "defaultDeviceId");
|
|
19736
|
+
__publicField(Authentication, "waitingForAuth", []);
|
|
19737
|
+
function delay(ms) {
|
|
19738
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
19739
|
+
}
|
|
19740
|
+
class DataChannel {
|
|
19741
|
+
constructor(dataChannel) {
|
|
19742
|
+
__publicField(this, "ready", false);
|
|
19743
|
+
__publicField(this, "listeners", []);
|
|
19744
|
+
__publicField(this, "openListeners", []);
|
|
19745
|
+
__publicField(this, "closeListeners", []);
|
|
19746
|
+
__publicField(this, "errorListeners", []);
|
|
19747
|
+
__publicField(this, "binaryListeners", []);
|
|
19748
|
+
__publicField(this, "error");
|
|
19749
|
+
__publicField(this, "decoder", new TextDecoder());
|
|
19750
|
+
this.dataChannel = dataChannel;
|
|
19751
|
+
this.dataChannel.binaryType = "arraybuffer";
|
|
19752
|
+
this.dataChannel.onopen = () => {
|
|
19753
|
+
this.ready = true;
|
|
19754
|
+
this.openListeners.forEach((listener) => listener());
|
|
19755
|
+
};
|
|
19756
|
+
this.dataChannel.onclose = () => {
|
|
19757
|
+
this.ready = false;
|
|
19758
|
+
this.closeListeners.forEach((listener) => listener());
|
|
19759
|
+
};
|
|
19760
|
+
this.dataChannel.onerror = (e) => {
|
|
19761
|
+
console.error(e);
|
|
19762
|
+
this.error = "An error occurred in DataChannel";
|
|
19763
|
+
this.errorListeners.forEach((listener) => listener(e));
|
|
19764
|
+
};
|
|
19765
|
+
this.dataChannel.onmessage = (m) => {
|
|
19766
|
+
this.listeners.forEach((_) => {
|
|
19767
|
+
const d = new Uint8Array(m.data);
|
|
19768
|
+
const s = this.decoder.decode(d);
|
|
19769
|
+
_(s);
|
|
19770
|
+
});
|
|
19771
|
+
this.binaryListeners.forEach((_) => {
|
|
19772
|
+
_(new Uint8Array(m.data));
|
|
19773
|
+
});
|
|
19774
|
+
};
|
|
20288
19775
|
}
|
|
20289
|
-
|
|
20290
|
-
|
|
20291
|
-
this.rtcClient,
|
|
20292
|
-
"Realtime connection has not been started"
|
|
20293
|
-
);
|
|
20294
|
-
const devicePeer = await this.getRemotePeer();
|
|
20295
|
-
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20296
|
-
streamName: stream.name,
|
|
20297
|
-
enable: false,
|
|
20298
|
-
pipeline: "rtc"
|
|
20299
|
-
});
|
|
19776
|
+
addOpenListener(listener) {
|
|
19777
|
+
this.openListeners.push(listener);
|
|
20300
19778
|
}
|
|
20301
|
-
|
|
20302
|
-
|
|
20303
|
-
this.rtcClient,
|
|
20304
|
-
"Realtime connection has not been started"
|
|
20305
|
-
);
|
|
20306
|
-
const devicePeer = await this.getRemotePeer();
|
|
20307
|
-
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20308
|
-
streamName,
|
|
20309
|
-
enablePriorityUpload: true,
|
|
20310
|
-
pipeline: "telemetry"
|
|
20311
|
-
});
|
|
19779
|
+
removeOpenListener(listener) {
|
|
19780
|
+
this.openListeners = this.openListeners.filter((_) => _ !== listener);
|
|
20312
19781
|
}
|
|
20313
|
-
|
|
20314
|
-
|
|
20315
|
-
this.rtcClient,
|
|
20316
|
-
"Realtime connection has not been started"
|
|
20317
|
-
);
|
|
20318
|
-
const devicePeer = await this.getRemotePeer();
|
|
20319
|
-
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20320
|
-
streamName,
|
|
20321
|
-
enablePriorityUpload: false,
|
|
20322
|
-
pipeline: "telemetry"
|
|
20323
|
-
});
|
|
19782
|
+
addCloseListener(listener) {
|
|
19783
|
+
this.closeListeners.push(listener);
|
|
20324
19784
|
}
|
|
20325
|
-
|
|
20326
|
-
|
|
20327
|
-
id: this.peerUrl,
|
|
20328
|
-
organizationId: "",
|
|
20329
|
-
deviceId: this.id,
|
|
20330
|
-
capabilities: [],
|
|
20331
|
-
capabilitySet: {}
|
|
20332
|
-
};
|
|
19785
|
+
removeCloseListener(listener) {
|
|
19786
|
+
this.closeListeners = this.closeListeners.filter((l) => l !== listener);
|
|
20333
19787
|
}
|
|
20334
|
-
|
|
20335
|
-
|
|
20336
|
-
await this.rtcClient.disconnect(this.id);
|
|
20337
|
-
} else {
|
|
20338
|
-
throw new Error(`Realtime connection hasn't been started for ${this.id}`);
|
|
20339
|
-
}
|
|
19788
|
+
addErrorListener(listener) {
|
|
19789
|
+
this.errorListeners.push(listener);
|
|
20340
19790
|
}
|
|
20341
|
-
|
|
20342
|
-
|
|
20343
|
-
|
|
20344
|
-
|
|
20345
|
-
)
|
|
20346
|
-
|
|
20347
|
-
|
|
20348
|
-
|
|
20349
|
-
|
|
20350
|
-
|
|
20351
|
-
|
|
20352
|
-
|
|
20353
|
-
...rtcConfig
|
|
20354
|
-
},
|
|
20355
|
-
false,
|
|
20356
|
-
(_peerId, channel) => {
|
|
20357
|
-
const dataChannel = new DataChannel(channel);
|
|
20358
|
-
resolve(dataChannel);
|
|
19791
|
+
removeErrorListener(listener) {
|
|
19792
|
+
this.errorListeners = this.errorListeners.filter((l) => l !== listener);
|
|
19793
|
+
}
|
|
19794
|
+
async waitTilReady() {
|
|
19795
|
+
if (this.ready) {
|
|
19796
|
+
return true;
|
|
19797
|
+
}
|
|
19798
|
+
const p = new Promise((resolve, reject) => {
|
|
19799
|
+
let a2 = window.setInterval(() => {
|
|
19800
|
+
if (this.ready) {
|
|
19801
|
+
window.clearInterval(a2);
|
|
19802
|
+
resolve(true);
|
|
20359
19803
|
}
|
|
20360
|
-
|
|
19804
|
+
if (this.error) {
|
|
19805
|
+
reject(this.error);
|
|
19806
|
+
}
|
|
19807
|
+
}, 10);
|
|
20361
19808
|
});
|
|
20362
|
-
await p.waitTilReady();
|
|
20363
19809
|
return p;
|
|
20364
19810
|
}
|
|
20365
|
-
|
|
20366
|
-
|
|
19811
|
+
send(data) {
|
|
19812
|
+
if (!this.ready) {
|
|
19813
|
+
throw new Error("Connection has been closed");
|
|
19814
|
+
}
|
|
19815
|
+
this.dataChannel.send(data);
|
|
20367
19816
|
}
|
|
20368
|
-
|
|
20369
|
-
|
|
19817
|
+
sendBinary(data) {
|
|
19818
|
+
if (!this.ready) {
|
|
19819
|
+
throw new Error("Connection has been closed");
|
|
19820
|
+
}
|
|
19821
|
+
this.dataChannel.send(data);
|
|
20370
19822
|
}
|
|
20371
|
-
|
|
20372
|
-
|
|
20373
|
-
static async setDefaultDevice(deviceId) {
|
|
20374
|
-
_Fleet$1.defaultDeviceId = deviceId;
|
|
19823
|
+
addListener(listener) {
|
|
19824
|
+
this.listeners.push(listener);
|
|
20375
19825
|
}
|
|
20376
|
-
|
|
20377
|
-
|
|
20378
|
-
|
|
19826
|
+
removeListener(listener) {
|
|
19827
|
+
const i = this.listeners.indexOf(listener);
|
|
19828
|
+
if (i === -1) {
|
|
19829
|
+
throw new Error("Could not find data channel listener to remove");
|
|
20379
19830
|
}
|
|
20380
|
-
if (
|
|
20381
|
-
throw new Error(
|
|
19831
|
+
if (this.error) {
|
|
19832
|
+
throw new Error(this.error);
|
|
20382
19833
|
}
|
|
20383
|
-
|
|
20384
|
-
|
|
20385
|
-
|
|
20386
|
-
|
|
20387
|
-
|
|
20388
|
-
|
|
20389
|
-
|
|
19834
|
+
this.listeners.splice(i, 1);
|
|
19835
|
+
}
|
|
19836
|
+
addBinaryListener(listener) {
|
|
19837
|
+
this.binaryListeners.push(listener);
|
|
19838
|
+
}
|
|
19839
|
+
removeBinaryListener(listener) {
|
|
19840
|
+
const i = this.binaryListeners.indexOf(listener);
|
|
19841
|
+
if (i === -1) {
|
|
19842
|
+
throw new Error("Could not find data channel listener to remove");
|
|
19843
|
+
}
|
|
19844
|
+
if (this.error) {
|
|
19845
|
+
throw new Error(this.error);
|
|
19846
|
+
}
|
|
19847
|
+
this.binaryListeners.splice(i, 1);
|
|
19848
|
+
}
|
|
19849
|
+
}
|
|
19850
|
+
class CaptureStream {
|
|
19851
|
+
constructor(captureSession) {
|
|
19852
|
+
__publicField(this, "token");
|
|
19853
|
+
this.captureSession = captureSession;
|
|
19854
|
+
}
|
|
19855
|
+
async ingestJSON(value) {
|
|
19856
|
+
if (!this.token) {
|
|
19857
|
+
const result = await fetch(
|
|
19858
|
+
`${FORMANT_API_URL}/v1/admin/capture-sessions/${this.captureSession.code}/authenticate`,
|
|
19859
|
+
{
|
|
19860
|
+
method: "POST"
|
|
20390
19861
|
}
|
|
19862
|
+
);
|
|
19863
|
+
const authInfo = await result.json();
|
|
19864
|
+
this.token = authInfo.token;
|
|
19865
|
+
}
|
|
19866
|
+
await fetch(`${FORMANT_API_URL}/v1/ingest`, {
|
|
19867
|
+
method: "POST",
|
|
19868
|
+
body: JSON.stringify({
|
|
19869
|
+
deviceId: this.captureSession.deviceId,
|
|
19870
|
+
name: this.captureSession.streamName,
|
|
19871
|
+
type: "json",
|
|
19872
|
+
points: [[Date.now(), JSON.stringify(value)]]
|
|
19873
|
+
}),
|
|
19874
|
+
headers: {
|
|
19875
|
+
"Content-Type": "application/json",
|
|
19876
|
+
Authorization: "Bearer " + this.token
|
|
20391
19877
|
}
|
|
19878
|
+
});
|
|
19879
|
+
}
|
|
19880
|
+
}
|
|
19881
|
+
class Manipulator {
|
|
19882
|
+
constructor(device, config) {
|
|
19883
|
+
__publicField(this, "currentListeners", []);
|
|
19884
|
+
__publicField(this, "onRealtimeMessage", (_peerId, message) => {
|
|
19885
|
+
if (message.payload.jointState) {
|
|
19886
|
+
this.currentListeners.forEach((listener) => {
|
|
19887
|
+
if (message.payload.jointState)
|
|
19888
|
+
listener(message.payload.jointState);
|
|
19889
|
+
});
|
|
19890
|
+
}
|
|
19891
|
+
});
|
|
19892
|
+
this.device = device;
|
|
19893
|
+
this.config = config;
|
|
19894
|
+
}
|
|
19895
|
+
async synchronize() {
|
|
19896
|
+
this.device.addRealtimeListener(this.onRealtimeMessage);
|
|
19897
|
+
this.device.startListeningToRealtimeDataStream(
|
|
19898
|
+
this.config.currentJointStateStream
|
|
20392
19899
|
);
|
|
20393
|
-
|
|
20394
|
-
|
|
20395
|
-
|
|
20396
|
-
|
|
20397
|
-
|
|
20398
|
-
const context = new Device(
|
|
20399
|
-
_Fleet$1.defaultDeviceId,
|
|
20400
|
-
name,
|
|
20401
|
-
defined(Authentication.currentOrganization)
|
|
19900
|
+
}
|
|
19901
|
+
async desynchronize() {
|
|
19902
|
+
this.device.removeRealtimeListener(this.onRealtimeMessage);
|
|
19903
|
+
this.device.stopListeningToRealtimeDataStream(
|
|
19904
|
+
this.config.currentJointStateStream
|
|
20402
19905
|
);
|
|
20403
|
-
_Fleet$1.knownContext.push(new WeakRef(context));
|
|
20404
|
-
return context;
|
|
20405
19906
|
}
|
|
20406
|
-
|
|
20407
|
-
|
|
20408
|
-
peer.id = await peer.getDeviceId();
|
|
20409
|
-
return peer;
|
|
19907
|
+
async addCurrentJointStateListener(listener) {
|
|
19908
|
+
this.currentListeners.push(listener);
|
|
20410
19909
|
}
|
|
20411
|
-
|
|
20412
|
-
|
|
20413
|
-
|
|
20414
|
-
|
|
20415
|
-
|
|
20416
|
-
|
|
20417
|
-
|
|
20418
|
-
|
|
20419
|
-
headers: {
|
|
20420
|
-
"Content-Type": "application/json",
|
|
20421
|
-
Authorization: "Bearer " + Authentication.token
|
|
20422
|
-
}
|
|
20423
|
-
}
|
|
20424
|
-
);
|
|
20425
|
-
const device = await data.json();
|
|
20426
|
-
const name = device.name;
|
|
20427
|
-
const context = new Device(deviceId, name, device.organizationId);
|
|
20428
|
-
_Fleet$1.knownContext.push(new WeakRef(context));
|
|
20429
|
-
return context;
|
|
19910
|
+
}
|
|
19911
|
+
class RequestDataChannel {
|
|
19912
|
+
constructor(device, channel_name, timeout) {
|
|
19913
|
+
__publicField(this, "channel");
|
|
19914
|
+
__publicField(this, "requestIdToResponseMap", /* @__PURE__ */ new Map());
|
|
19915
|
+
this.device = device;
|
|
19916
|
+
this.channel_name = channel_name;
|
|
19917
|
+
this.timeout = timeout;
|
|
20430
19918
|
}
|
|
20431
|
-
|
|
20432
|
-
|
|
20433
|
-
|
|
20434
|
-
|
|
20435
|
-
|
|
20436
|
-
|
|
20437
|
-
{
|
|
20438
|
-
method: "POST",
|
|
20439
|
-
body: JSON.stringify({ enabled: true, type: "default" }),
|
|
20440
|
-
headers: {
|
|
20441
|
-
"Content-Type": "application/json",
|
|
20442
|
-
Authorization: "Bearer " + Authentication.token
|
|
20443
|
-
}
|
|
20444
|
-
}
|
|
19919
|
+
addOpenListener(listener) {
|
|
19920
|
+
defined(this.channel, "channel not initalized").addOpenListener(listener);
|
|
19921
|
+
}
|
|
19922
|
+
removeOpenListener(listener) {
|
|
19923
|
+
defined(this.channel, "channel not initalized").removeOpenListener(
|
|
19924
|
+
listener
|
|
20445
19925
|
);
|
|
20446
|
-
|
|
20447
|
-
|
|
20448
|
-
|
|
20449
|
-
|
|
19926
|
+
}
|
|
19927
|
+
addCloseListener(listener) {
|
|
19928
|
+
defined(this.channel, "channel not initalized").addCloseListener(listener);
|
|
19929
|
+
}
|
|
19930
|
+
removeCloseListener(listener) {
|
|
19931
|
+
defined(this.channel, "channel not initalized").removeCloseListener(
|
|
19932
|
+
listener
|
|
20450
19933
|
);
|
|
20451
19934
|
}
|
|
20452
|
-
|
|
20453
|
-
|
|
20454
|
-
|
|
20455
|
-
|
|
20456
|
-
|
|
20457
|
-
|
|
20458
|
-
body: JSON.stringify(query),
|
|
20459
|
-
headers: {
|
|
20460
|
-
"Content-Type": "application/json",
|
|
20461
|
-
Authorization: "Bearer " + Authentication.token
|
|
20462
|
-
}
|
|
20463
|
-
});
|
|
20464
|
-
const devices = await data.json();
|
|
20465
|
-
return devices.items.map(
|
|
20466
|
-
(_) => new Device(_.id, _.name, _.organizationId)
|
|
19935
|
+
addErrorListener(listener) {
|
|
19936
|
+
defined(this.channel, "channel not initalized").addErrorListener(listener);
|
|
19937
|
+
}
|
|
19938
|
+
removeErrorListener(listener) {
|
|
19939
|
+
defined(this.channel, "channel not initalized").removeErrorListener(
|
|
19940
|
+
listener
|
|
20467
19941
|
);
|
|
20468
19942
|
}
|
|
20469
|
-
|
|
20470
|
-
|
|
20471
|
-
|
|
19943
|
+
}
|
|
19944
|
+
class BinaryRequestDataChannel extends RequestDataChannel {
|
|
19945
|
+
constructor() {
|
|
19946
|
+
super(...arguments);
|
|
19947
|
+
__publicField(this, "RESPONSE_SUCCESS_BYTE", 0);
|
|
19948
|
+
__publicField(this, "decoder", new TextDecoder());
|
|
19949
|
+
}
|
|
19950
|
+
generateBinaryId() {
|
|
19951
|
+
const id = new Uint8Array(16);
|
|
19952
|
+
for (let i = 0; i < id.length; i++) {
|
|
19953
|
+
id[i] = Math.floor(Math.random() * 256);
|
|
20472
19954
|
}
|
|
20473
|
-
|
|
20474
|
-
|
|
20475
|
-
|
|
20476
|
-
|
|
20477
|
-
|
|
19955
|
+
return id;
|
|
19956
|
+
}
|
|
19957
|
+
async initialize() {
|
|
19958
|
+
this.channel = await this.device.createCustomDataChannel(this.channel_name);
|
|
19959
|
+
this.channel.addBinaryListener((message) => {
|
|
19960
|
+
const binaryId = message.slice(0, 16);
|
|
19961
|
+
const id = binaryId.toString();
|
|
19962
|
+
if (id.length === 0) {
|
|
19963
|
+
throw new Error("Invalid response");
|
|
19964
|
+
}
|
|
19965
|
+
const response = message.slice(16);
|
|
19966
|
+
if (response.length === 0) {
|
|
19967
|
+
throw new Error("Invalid response");
|
|
19968
|
+
}
|
|
19969
|
+
if (this.requestIdToResponseMap.has(id)) {
|
|
19970
|
+
this.requestIdToResponseMap.set(id, response);
|
|
20478
19971
|
}
|
|
20479
19972
|
});
|
|
20480
|
-
const devices = await data.json();
|
|
20481
|
-
const onlineIds = devices.items;
|
|
20482
|
-
const allDevices = await _Fleet$1.getDevices();
|
|
20483
|
-
return allDevices.filter((_) => onlineIds.includes(_.id));
|
|
20484
19973
|
}
|
|
20485
|
-
|
|
20486
|
-
if (!
|
|
20487
|
-
|
|
19974
|
+
async request(data) {
|
|
19975
|
+
if (!this.channel) {
|
|
19976
|
+
await this.initialize();
|
|
20488
19977
|
}
|
|
20489
|
-
|
|
20490
|
-
|
|
20491
|
-
|
|
20492
|
-
|
|
20493
|
-
|
|
20494
|
-
|
|
20495
|
-
|
|
20496
|
-
|
|
20497
|
-
|
|
19978
|
+
if (!this.channel) {
|
|
19979
|
+
throw new Error("Failed to create channel");
|
|
19980
|
+
}
|
|
19981
|
+
const { channel, requestIdToResponseMap, timeout } = this;
|
|
19982
|
+
await channel.waitTilReady();
|
|
19983
|
+
const binaryId = this.generateBinaryId();
|
|
19984
|
+
const id = binaryId.toString();
|
|
19985
|
+
requestIdToResponseMap.set(id, true);
|
|
19986
|
+
channel.sendBinary(new Uint8Array([...binaryId, ...data]));
|
|
19987
|
+
const start = new Date().getTime();
|
|
19988
|
+
while (new Date().getTime() < start + timeout) {
|
|
19989
|
+
await delay(50);
|
|
19990
|
+
if (requestIdToResponseMap.has(id)) {
|
|
19991
|
+
const response = requestIdToResponseMap.get(id);
|
|
19992
|
+
if (response !== true) {
|
|
19993
|
+
requestIdToResponseMap.delete(id);
|
|
19994
|
+
const success = response[0] === this.RESPONSE_SUCCESS_BYTE;
|
|
19995
|
+
const payload = response.slice(1);
|
|
19996
|
+
if (success) {
|
|
19997
|
+
return payload;
|
|
19998
|
+
} else {
|
|
19999
|
+
console.error({
|
|
20000
|
+
name: "AdapterError",
|
|
20001
|
+
message: this.decoder.decode(payload)
|
|
20002
|
+
});
|
|
20003
|
+
throw new Error("Binary request datachannel adapter error");
|
|
20004
|
+
}
|
|
20005
|
+
}
|
|
20498
20006
|
}
|
|
20007
|
+
}
|
|
20008
|
+
requestIdToResponseMap.delete(id);
|
|
20009
|
+
console.error({
|
|
20010
|
+
name: "TimeoutError",
|
|
20011
|
+
message: `Request timed out after ${timeout / 1e3} seconds`
|
|
20499
20012
|
});
|
|
20500
|
-
|
|
20013
|
+
throw new Error("Binary request data channel request timed out");
|
|
20501
20014
|
}
|
|
20502
|
-
|
|
20503
|
-
|
|
20504
|
-
|
|
20505
|
-
|
|
20506
|
-
|
|
20507
|
-
|
|
20508
|
-
|
|
20509
|
-
|
|
20510
|
-
|
|
20511
|
-
|
|
20512
|
-
|
|
20513
|
-
|
|
20514
|
-
|
|
20015
|
+
}
|
|
20016
|
+
class TextRequestDataChannel extends RequestDataChannel {
|
|
20017
|
+
generateTextId() {
|
|
20018
|
+
return Math.random().toString(36).substring(2) + "-" + Math.random().toString(36).substring(2);
|
|
20019
|
+
}
|
|
20020
|
+
async initialize() {
|
|
20021
|
+
this.channel = await this.device.createCustomDataChannel(this.channel_name);
|
|
20022
|
+
this.channel.addListener((message) => {
|
|
20023
|
+
const response = JSON.parse(message);
|
|
20024
|
+
const { id, data, error } = response;
|
|
20025
|
+
if (!id) {
|
|
20026
|
+
throw new Error("Invalid response");
|
|
20027
|
+
}
|
|
20028
|
+
if (!data && !error) {
|
|
20029
|
+
throw new Error("Invalid response");
|
|
20030
|
+
}
|
|
20031
|
+
if (this.requestIdToResponseMap.has(id)) {
|
|
20032
|
+
this.requestIdToResponseMap.set(id, response);
|
|
20515
20033
|
}
|
|
20516
20034
|
});
|
|
20517
|
-
return await rtcClient.getSessions();
|
|
20518
20035
|
}
|
|
20519
|
-
|
|
20520
|
-
if (!
|
|
20521
|
-
|
|
20036
|
+
async request(data) {
|
|
20037
|
+
if (!this.channel) {
|
|
20038
|
+
await this.initialize();
|
|
20522
20039
|
}
|
|
20523
|
-
|
|
20524
|
-
|
|
20525
|
-
|
|
20526
|
-
|
|
20527
|
-
|
|
20040
|
+
if (!this.channel) {
|
|
20041
|
+
throw new Error("Failed to create channel");
|
|
20042
|
+
}
|
|
20043
|
+
const { channel, requestIdToResponseMap, timeout } = this;
|
|
20044
|
+
await channel.waitTilReady();
|
|
20045
|
+
const id = this.generateTextId();
|
|
20046
|
+
requestIdToResponseMap.set(id, true);
|
|
20047
|
+
channel.send(
|
|
20048
|
+
JSON.stringify({
|
|
20049
|
+
id,
|
|
20050
|
+
data
|
|
20051
|
+
})
|
|
20052
|
+
);
|
|
20053
|
+
const start = new Date().getTime();
|
|
20054
|
+
while (new Date().getTime() < start + timeout) {
|
|
20055
|
+
await delay(50);
|
|
20056
|
+
if (requestIdToResponseMap.has(id)) {
|
|
20057
|
+
const response = requestIdToResponseMap.get(id);
|
|
20058
|
+
if (response !== true) {
|
|
20059
|
+
requestIdToResponseMap.delete(id);
|
|
20060
|
+
const { data: data2, error } = response;
|
|
20061
|
+
if (data2) {
|
|
20062
|
+
return data2;
|
|
20063
|
+
}
|
|
20064
|
+
if (error) {
|
|
20065
|
+
console.error({
|
|
20066
|
+
name: "AdapterError",
|
|
20067
|
+
message: error
|
|
20068
|
+
});
|
|
20069
|
+
throw new Error("Text request datachannel adapter error");
|
|
20070
|
+
}
|
|
20071
|
+
}
|
|
20528
20072
|
}
|
|
20073
|
+
}
|
|
20074
|
+
requestIdToResponseMap.delete(id);
|
|
20075
|
+
console.error({
|
|
20076
|
+
name: "TimeoutError",
|
|
20077
|
+
message: `Request timed out after ${timeout / 1e3} seconds`
|
|
20529
20078
|
});
|
|
20530
|
-
|
|
20531
|
-
const onlineIds = devices.items.map(
|
|
20532
|
-
(_) => _.deviceId
|
|
20533
|
-
);
|
|
20534
|
-
const allDevices = await _Fleet$1.getDevices();
|
|
20535
|
-
return allDevices.filter((_) => onlineIds.includes(_.id));
|
|
20079
|
+
throw new Error("Text request datachannel request timed out");
|
|
20536
20080
|
}
|
|
20537
|
-
|
|
20538
|
-
|
|
20539
|
-
|
|
20540
|
-
|
|
20541
|
-
|
|
20081
|
+
}
|
|
20082
|
+
const urlParams$1 = new URLSearchParams(window.location.search);
|
|
20083
|
+
const rtcClientVersion = urlParams$1.get("rtc_client");
|
|
20084
|
+
const SessionType = {
|
|
20085
|
+
Teleop: 1,
|
|
20086
|
+
Observe: 3
|
|
20087
|
+
};
|
|
20088
|
+
class Device {
|
|
20089
|
+
constructor(id, name, organizationId) {
|
|
20090
|
+
__publicField(this, "rtcClient");
|
|
20091
|
+
__publicField(this, "remoteDevicePeerId");
|
|
20092
|
+
__publicField(this, "realtimeListeners", []);
|
|
20093
|
+
__publicField(this, "handleMessage", (peerId, message) => {
|
|
20094
|
+
this.realtimeListeners.forEach((_) => _(peerId, message));
|
|
20095
|
+
});
|
|
20096
|
+
this.id = id;
|
|
20097
|
+
this.name = name;
|
|
20098
|
+
this.organizationId = organizationId;
|
|
20099
|
+
}
|
|
20100
|
+
async getLatestTelemetry() {
|
|
20542
20101
|
const data = await fetch(
|
|
20543
20102
|
`${FORMANT_API_URL}/v1/queries/stream-current-value`,
|
|
20544
20103
|
{
|
|
20545
20104
|
method: "POST",
|
|
20546
20105
|
body: JSON.stringify({
|
|
20547
|
-
deviceIds
|
|
20106
|
+
deviceIds: [this.id]
|
|
20548
20107
|
}),
|
|
20549
20108
|
headers: {
|
|
20550
20109
|
"Content-Type": "application/json",
|
|
@@ -20555,755 +20114,765 @@ const _Fleet$1 = class {
|
|
|
20555
20114
|
const telemetry = await data.json();
|
|
20556
20115
|
return telemetry.items;
|
|
20557
20116
|
}
|
|
20558
|
-
|
|
20559
|
-
let
|
|
20560
|
-
|
|
20561
|
-
deviceIds = [deviceIdOrDeviceIds];
|
|
20562
|
-
}
|
|
20563
|
-
let streamNames = streamNameOrStreamNames;
|
|
20564
|
-
if (!Array.isArray(streamNameOrStreamNames)) {
|
|
20565
|
-
streamNames = [streamNameOrStreamNames];
|
|
20566
|
-
}
|
|
20567
|
-
const data = await fetch(`${FORMANT_API_URL}/v1/queries/queries`, {
|
|
20568
|
-
method: "POST",
|
|
20569
|
-
body: JSON.stringify({
|
|
20570
|
-
deviceIds,
|
|
20571
|
-
end: end.toISOString(),
|
|
20572
|
-
names: streamNames,
|
|
20573
|
-
start: start.toISOString(),
|
|
20574
|
-
tags
|
|
20575
|
-
}),
|
|
20117
|
+
async getConfiguration() {
|
|
20118
|
+
let result = await fetch(`${FORMANT_API_URL}/v1/admin/devices/${this.id}`, {
|
|
20119
|
+
method: "GET",
|
|
20576
20120
|
headers: {
|
|
20577
20121
|
"Content-Type": "application/json",
|
|
20578
20122
|
Authorization: "Bearer " + Authentication.token
|
|
20579
20123
|
}
|
|
20580
20124
|
});
|
|
20581
|
-
const
|
|
20582
|
-
|
|
20125
|
+
const device = await result.json();
|
|
20126
|
+
if (!device.state.reportedConfiguration) {
|
|
20127
|
+
throw new Error(
|
|
20128
|
+
"Device has no configuration, has it ever been turned on?"
|
|
20129
|
+
);
|
|
20130
|
+
}
|
|
20131
|
+
const version = device.state.reportedConfiguration.version;
|
|
20132
|
+
result = await fetch(
|
|
20133
|
+
`${FORMANT_API_URL}/v1/admin/devices/${this.id}/configurations/${version}`,
|
|
20134
|
+
{
|
|
20135
|
+
method: "GET",
|
|
20136
|
+
headers: {
|
|
20137
|
+
"Content-Type": "application/json",
|
|
20138
|
+
Authorization: "Bearer " + Authentication.token
|
|
20139
|
+
}
|
|
20140
|
+
}
|
|
20141
|
+
);
|
|
20142
|
+
const config = await result.json();
|
|
20143
|
+
return config.document;
|
|
20583
20144
|
}
|
|
20584
|
-
|
|
20585
|
-
const
|
|
20145
|
+
async getFileUrl(fileId) {
|
|
20146
|
+
const result = await fetch(`${FORMANT_API_URL}/v1/admin/files/query`, {
|
|
20586
20147
|
method: "POST",
|
|
20587
20148
|
body: JSON.stringify({
|
|
20588
|
-
fileIds: [
|
|
20149
|
+
fileIds: [fileId]
|
|
20589
20150
|
}),
|
|
20590
20151
|
headers: {
|
|
20591
20152
|
"Content-Type": "application/json",
|
|
20592
20153
|
Authorization: "Bearer " + Authentication.token
|
|
20593
20154
|
}
|
|
20594
20155
|
});
|
|
20595
|
-
const
|
|
20596
|
-
|
|
20597
|
-
throw new Error("File not found");
|
|
20598
|
-
}
|
|
20599
|
-
return result.fileUrls[0];
|
|
20156
|
+
const files = await result.json();
|
|
20157
|
+
return files.fileUrls;
|
|
20600
20158
|
}
|
|
20601
|
-
|
|
20602
|
-
if (
|
|
20603
|
-
|
|
20159
|
+
getRealtimeStatus() {
|
|
20160
|
+
if (this.rtcClient && this.remoteDevicePeerId) {
|
|
20161
|
+
return this.rtcClient.getConnectionStatus(this.remoteDevicePeerId);
|
|
20162
|
+
} else {
|
|
20163
|
+
throw new Error(`Realtime connection hasn't been started for ${this.id}`);
|
|
20604
20164
|
}
|
|
20605
|
-
const data = await fetch(`${FORMANT_API_URL}/v1/queries/queries`, {
|
|
20606
|
-
method: "POST",
|
|
20607
|
-
body: JSON.stringify(query),
|
|
20608
|
-
headers: {
|
|
20609
|
-
"Content-Type": "application/json",
|
|
20610
|
-
Authorization: "Bearer " + Authentication.token
|
|
20611
|
-
}
|
|
20612
|
-
});
|
|
20613
|
-
return (await data.json()).items;
|
|
20614
20165
|
}
|
|
20615
|
-
|
|
20616
|
-
if (
|
|
20617
|
-
|
|
20166
|
+
getRealtimePing() {
|
|
20167
|
+
if (this.rtcClient && this.remoteDevicePeerId) {
|
|
20168
|
+
return this.rtcClient.getPing(this.remoteDevicePeerId);
|
|
20169
|
+
} else {
|
|
20170
|
+
throw new Error(`Realtime connection hasn't been started for ${this.id}`);
|
|
20618
20171
|
}
|
|
20619
|
-
const data = await fetch(`${FORMANT_API_URL}/v1/queries/queries`, {
|
|
20620
|
-
method: "POST",
|
|
20621
|
-
body: JSON.stringify(query),
|
|
20622
|
-
headers: {
|
|
20623
|
-
"Content-Type": "application/json",
|
|
20624
|
-
Authorization: "Bearer " + Authentication.token
|
|
20625
|
-
}
|
|
20626
|
-
});
|
|
20627
|
-
return (await data.json()).aggregates;
|
|
20628
20172
|
}
|
|
20629
|
-
|
|
20630
|
-
if (!
|
|
20631
|
-
|
|
20632
|
-
|
|
20633
|
-
|
|
20634
|
-
|
|
20635
|
-
|
|
20636
|
-
|
|
20637
|
-
|
|
20638
|
-
|
|
20173
|
+
async startRealtimeConnection(sessionType) {
|
|
20174
|
+
if (!this.rtcClient) {
|
|
20175
|
+
let rtcClient;
|
|
20176
|
+
if (rtcClientVersion === "1") {
|
|
20177
|
+
rtcClient = new dist.exports.RtcClientV1({
|
|
20178
|
+
signalingClient: new dist.exports.RtcSignalingClient(
|
|
20179
|
+
FORMANT_API_URL + "/v1/signaling"
|
|
20180
|
+
),
|
|
20181
|
+
getToken: async () => defined(
|
|
20182
|
+
Authentication.token,
|
|
20183
|
+
"Realtime when user isn't authorized"
|
|
20184
|
+
),
|
|
20185
|
+
receive: this.handleMessage
|
|
20186
|
+
});
|
|
20187
|
+
} else {
|
|
20188
|
+
rtcClient = new dist.exports.RtcClient({
|
|
20189
|
+
signalingClient: new dist.exports.SignalingPromiseClient(
|
|
20190
|
+
FORMANT_API_URL,
|
|
20191
|
+
null,
|
|
20192
|
+
null
|
|
20193
|
+
),
|
|
20194
|
+
getToken: async () => {
|
|
20195
|
+
return defined(
|
|
20196
|
+
Authentication.token,
|
|
20197
|
+
"Realtime when user isn't authorized"
|
|
20198
|
+
);
|
|
20199
|
+
},
|
|
20200
|
+
receive: this.handleMessage,
|
|
20201
|
+
sessionType
|
|
20202
|
+
});
|
|
20639
20203
|
}
|
|
20640
|
-
|
|
20641
|
-
|
|
20642
|
-
|
|
20643
|
-
static async getEvent(uuid) {
|
|
20644
|
-
if (!Authentication.token) {
|
|
20645
|
-
throw new Error("Not authenticated");
|
|
20646
|
-
}
|
|
20647
|
-
const data = await fetch(
|
|
20648
|
-
`${FORMANT_API_URL}/v1/admin/events/query/id=${uuid}`,
|
|
20649
|
-
{
|
|
20650
|
-
method: "GET",
|
|
20651
|
-
headers: {
|
|
20652
|
-
"Content-Type": "application/json",
|
|
20653
|
-
Authorization: "Bearer " + Authentication.token
|
|
20204
|
+
if (rtcClient.isReady) {
|
|
20205
|
+
while (!rtcClient.isReady()) {
|
|
20206
|
+
await delay(100);
|
|
20654
20207
|
}
|
|
20655
20208
|
}
|
|
20209
|
+
const peers = await rtcClient.getPeers();
|
|
20210
|
+
const devicePeer = peers.find((_) => _.deviceId === this.id);
|
|
20211
|
+
if (!devicePeer) {
|
|
20212
|
+
throw new Error("Cannot find peer, is the robot offline?");
|
|
20213
|
+
}
|
|
20214
|
+
this.remoteDevicePeerId = devicePeer.id;
|
|
20215
|
+
await rtcClient.connect(this.remoteDevicePeerId);
|
|
20216
|
+
while (rtcClient.getConnectionStatus(this.remoteDevicePeerId) !== "connected") {
|
|
20217
|
+
await delay(100);
|
|
20218
|
+
}
|
|
20219
|
+
this.rtcClient = rtcClient;
|
|
20220
|
+
} else {
|
|
20221
|
+
throw new Error(
|
|
20222
|
+
`Already created realtime connection to device ${this.id}`
|
|
20223
|
+
);
|
|
20224
|
+
}
|
|
20225
|
+
}
|
|
20226
|
+
async sendRealtimeMessage(message, config = {
|
|
20227
|
+
channelLabel: "stream.reliable"
|
|
20228
|
+
}) {
|
|
20229
|
+
const client = defined(
|
|
20230
|
+
this.rtcClient,
|
|
20231
|
+
"Realtime connection has not been started"
|
|
20656
20232
|
);
|
|
20657
|
-
|
|
20233
|
+
const devicePeer = await this.getRemotePeer();
|
|
20234
|
+
client.send(defined(devicePeer).id, message, config);
|
|
20658
20235
|
}
|
|
20659
|
-
|
|
20660
|
-
|
|
20661
|
-
|
|
20236
|
+
addRealtimeListener(listener) {
|
|
20237
|
+
this.realtimeListeners.push(listener);
|
|
20238
|
+
}
|
|
20239
|
+
removeRealtimeListener(listener) {
|
|
20240
|
+
const i = this.realtimeListeners.indexOf(listener);
|
|
20241
|
+
if (i === -1) {
|
|
20242
|
+
throw new Error("Could not find realtime listener to remove");
|
|
20662
20243
|
}
|
|
20663
|
-
|
|
20664
|
-
`${FORMANT_API_URL}/v1/admin/intervention-requests`,
|
|
20665
|
-
{
|
|
20666
|
-
method: "GET",
|
|
20667
|
-
headers: {
|
|
20668
|
-
"Content-Type": "application/json",
|
|
20669
|
-
Authorization: "Bearer " + Authentication.token
|
|
20670
|
-
}
|
|
20671
|
-
}
|
|
20672
|
-
);
|
|
20673
|
-
return (await interventions.json()).items;
|
|
20244
|
+
this.realtimeListeners.splice(i, 1);
|
|
20674
20245
|
}
|
|
20675
|
-
|
|
20676
|
-
|
|
20677
|
-
|
|
20246
|
+
async getRealtimeAudioStreams() {
|
|
20247
|
+
var _a, _b, _c, _d, _e, _f;
|
|
20248
|
+
const document2 = await this.getConfiguration();
|
|
20249
|
+
const streams = [];
|
|
20250
|
+
for (const _ of (_b = (_a = document2.teleop) == null ? void 0 : _a.hardwareStreams) != null ? _b : []) {
|
|
20251
|
+
if (_.rtcStreamType === "audio-chunk") {
|
|
20252
|
+
streams.push({
|
|
20253
|
+
name: _.name
|
|
20254
|
+
});
|
|
20255
|
+
}
|
|
20256
|
+
}
|
|
20257
|
+
for (const _ of (_d = (_c = document2.teleop) == null ? void 0 : _c.rosStreams) != null ? _d : []) {
|
|
20258
|
+
if (_.topicType == "audio_common_msgs/AudioData") {
|
|
20259
|
+
streams.push({
|
|
20260
|
+
name: _.topicName
|
|
20261
|
+
});
|
|
20262
|
+
}
|
|
20263
|
+
}
|
|
20264
|
+
for (const _ of (_f = (_e = document2.teleop) == null ? void 0 : _e.customStreams) != null ? _f : []) {
|
|
20265
|
+
if (_.rtcStreamType === "audio-chunk") {
|
|
20266
|
+
streams.push({
|
|
20267
|
+
name: _.name
|
|
20268
|
+
});
|
|
20269
|
+
}
|
|
20678
20270
|
}
|
|
20679
|
-
|
|
20680
|
-
|
|
20681
|
-
|
|
20271
|
+
return streams;
|
|
20272
|
+
}
|
|
20273
|
+
async getRealtimeVideoStreams() {
|
|
20274
|
+
var _a, _b, _c, _d, _e, _f;
|
|
20275
|
+
const document2 = await this.getConfiguration();
|
|
20276
|
+
const streams = [];
|
|
20277
|
+
for (const _ of (_b = (_a = document2.teleop) == null ? void 0 : _a.hardwareStreams) != null ? _b : []) {
|
|
20278
|
+
if (_.rtcStreamType === "h264-video-frame") {
|
|
20279
|
+
streams.push({
|
|
20280
|
+
name: _.name
|
|
20281
|
+
});
|
|
20282
|
+
}
|
|
20682
20283
|
}
|
|
20683
|
-
const
|
|
20684
|
-
|
|
20685
|
-
|
|
20284
|
+
for (const _ of (_d = (_c = document2.teleop) == null ? void 0 : _c.rosStreams) != null ? _d : []) {
|
|
20285
|
+
if (_.topicType == "formant/H264VideoFrame") {
|
|
20286
|
+
streams.push({
|
|
20287
|
+
name: _.topicName
|
|
20288
|
+
});
|
|
20289
|
+
}
|
|
20686
20290
|
}
|
|
20687
|
-
const
|
|
20688
|
-
|
|
20689
|
-
|
|
20690
|
-
|
|
20691
|
-
|
|
20692
|
-
Authorization: "Bearer " + Authentication.token
|
|
20693
|
-
}
|
|
20291
|
+
for (const _ of (_f = (_e = document2.teleop) == null ? void 0 : _e.customStreams) != null ? _f : []) {
|
|
20292
|
+
if (_.rtcStreamType === "h264-video-frame") {
|
|
20293
|
+
streams.push({
|
|
20294
|
+
name: _.name
|
|
20295
|
+
});
|
|
20694
20296
|
}
|
|
20695
|
-
);
|
|
20696
|
-
const { tagKey, tagValue } = await response.json();
|
|
20697
|
-
const devices = await this.queryDevices({
|
|
20698
|
-
tags: { [tagKey]: [tagValue] },
|
|
20699
|
-
enabled: true,
|
|
20700
|
-
type: "default"
|
|
20701
|
-
});
|
|
20702
|
-
return devices;
|
|
20703
|
-
}
|
|
20704
|
-
};
|
|
20705
|
-
let Fleet$1 = _Fleet$1;
|
|
20706
|
-
__publicField(Fleet$1, "defaultDeviceId");
|
|
20707
|
-
__publicField(Fleet$1, "knownContext", []);
|
|
20708
|
-
function toInteger(dirtyNumber) {
|
|
20709
|
-
if (dirtyNumber === null || dirtyNumber === true || dirtyNumber === false) {
|
|
20710
|
-
return NaN;
|
|
20711
|
-
}
|
|
20712
|
-
var number = Number(dirtyNumber);
|
|
20713
|
-
if (isNaN(number)) {
|
|
20714
|
-
return number;
|
|
20715
|
-
}
|
|
20716
|
-
return number < 0 ? Math.ceil(number) : Math.floor(number);
|
|
20717
|
-
}
|
|
20718
|
-
function requiredArgs(required, args) {
|
|
20719
|
-
if (args.length < required) {
|
|
20720
|
-
throw new TypeError(required + " argument" + (required > 1 ? "s" : "") + " required, but only " + args.length + " present");
|
|
20721
|
-
}
|
|
20722
|
-
}
|
|
20723
|
-
function _typeof(obj) {
|
|
20724
|
-
"@babel/helpers - typeof";
|
|
20725
|
-
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
|
|
20726
|
-
_typeof = function _typeof2(obj2) {
|
|
20727
|
-
return typeof obj2;
|
|
20728
|
-
};
|
|
20729
|
-
} else {
|
|
20730
|
-
_typeof = function _typeof2(obj2) {
|
|
20731
|
-
return obj2 && typeof Symbol === "function" && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2;
|
|
20732
|
-
};
|
|
20733
|
-
}
|
|
20734
|
-
return _typeof(obj);
|
|
20735
|
-
}
|
|
20736
|
-
function toDate(argument) {
|
|
20737
|
-
requiredArgs(1, arguments);
|
|
20738
|
-
var argStr = Object.prototype.toString.call(argument);
|
|
20739
|
-
if (argument instanceof Date || _typeof(argument) === "object" && argStr === "[object Date]") {
|
|
20740
|
-
return new Date(argument.getTime());
|
|
20741
|
-
} else if (typeof argument === "number" || argStr === "[object Number]") {
|
|
20742
|
-
return new Date(argument);
|
|
20743
|
-
} else {
|
|
20744
|
-
if ((typeof argument === "string" || argStr === "[object String]") && typeof console !== "undefined") {
|
|
20745
|
-
console.warn("Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use `parseISO` to parse strings. See: https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#string-arguments");
|
|
20746
|
-
console.warn(new Error().stack);
|
|
20747
20297
|
}
|
|
20748
|
-
return
|
|
20298
|
+
return streams;
|
|
20749
20299
|
}
|
|
20750
|
-
|
|
20751
|
-
|
|
20752
|
-
|
|
20753
|
-
|
|
20754
|
-
|
|
20755
|
-
|
|
20756
|
-
|
|
20757
|
-
|
|
20758
|
-
|
|
20759
|
-
|
|
20760
|
-
|
|
20761
|
-
|
|
20762
|
-
|
|
20763
|
-
|
|
20764
|
-
|
|
20765
|
-
|
|
20766
|
-
|
|
20767
|
-
}
|
|
20768
|
-
|
|
20769
|
-
|
|
20770
|
-
round: Math.round,
|
|
20771
|
-
floor: Math.floor,
|
|
20772
|
-
trunc: function trunc(value) {
|
|
20773
|
-
return value < 0 ? Math.ceil(value) : Math.floor(value);
|
|
20300
|
+
async getRealtimeManipulators() {
|
|
20301
|
+
var _a;
|
|
20302
|
+
const document2 = await this.getConfiguration();
|
|
20303
|
+
const manipulators = [];
|
|
20304
|
+
for (const _ of (_a = document2.teleop.rosStreams) != null ? _a : []) {
|
|
20305
|
+
if (_.topicType == "sensor_msgs/JointState") {
|
|
20306
|
+
manipulators.push(
|
|
20307
|
+
new Manipulator(this, {
|
|
20308
|
+
currentJointStateStream: { name: _.topicName },
|
|
20309
|
+
plannedJointStateStream: _.plannedTopic ? { name: _.plannedTopic } : void 0,
|
|
20310
|
+
planValidStream: _.planValidTopic ? { name: _.planValidTopic } : void 0,
|
|
20311
|
+
endEffectorStream: _.endEffectorTopic ? { name: _.endEffectorTopic } : void 0,
|
|
20312
|
+
endEffectorLinkName: _.endEffectorLinkName,
|
|
20313
|
+
baseReferenceFrame: _.baseReferenceFrame,
|
|
20314
|
+
localFrame: _.localFrame
|
|
20315
|
+
})
|
|
20316
|
+
);
|
|
20317
|
+
}
|
|
20318
|
+
}
|
|
20319
|
+
return manipulators;
|
|
20774
20320
|
}
|
|
20775
|
-
|
|
20776
|
-
|
|
20777
|
-
|
|
20778
|
-
|
|
20779
|
-
|
|
20780
|
-
|
|
20781
|
-
|
|
20782
|
-
|
|
20783
|
-
|
|
20784
|
-
|
|
20785
|
-
}
|
|
20786
|
-
function roundToNearestMinutes(dirtyDate, options) {
|
|
20787
|
-
var _options$nearestTo;
|
|
20788
|
-
if (arguments.length < 1) {
|
|
20789
|
-
throw new TypeError("1 argument required, but only none provided present");
|
|
20321
|
+
async startListeningToRealtimeVideo(stream) {
|
|
20322
|
+
const client = defined(
|
|
20323
|
+
this.rtcClient,
|
|
20324
|
+
"Realtime connection has not been started"
|
|
20325
|
+
);
|
|
20326
|
+
const devicePeer = await this.getRemotePeer();
|
|
20327
|
+
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20328
|
+
streamName: stream.name,
|
|
20329
|
+
enable: true,
|
|
20330
|
+
pipeline: "rtc"
|
|
20331
|
+
});
|
|
20790
20332
|
}
|
|
20791
|
-
|
|
20792
|
-
|
|
20793
|
-
|
|
20333
|
+
async stopListeningToRealtimeVideo(stream) {
|
|
20334
|
+
const client = defined(
|
|
20335
|
+
this.rtcClient,
|
|
20336
|
+
"Realtime connection has not been started"
|
|
20337
|
+
);
|
|
20338
|
+
const devicePeer = await this.getRemotePeer();
|
|
20339
|
+
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20340
|
+
streamName: stream.name,
|
|
20341
|
+
enable: false,
|
|
20342
|
+
pipeline: "rtc"
|
|
20343
|
+
});
|
|
20794
20344
|
}
|
|
20795
|
-
|
|
20796
|
-
|
|
20797
|
-
|
|
20798
|
-
|
|
20799
|
-
|
|
20800
|
-
|
|
20801
|
-
|
|
20802
|
-
|
|
20803
|
-
|
|
20804
|
-
|
|
20805
|
-
|
|
20806
|
-
const minute = 60 * second;
|
|
20807
|
-
const hour = 60 * minute;
|
|
20808
|
-
const day = 24 * hour;
|
|
20809
|
-
const week = 7 * day;
|
|
20810
|
-
const month = 30 * day;
|
|
20811
|
-
const year = 365 * day;
|
|
20812
|
-
const duration = {
|
|
20813
|
-
millisecond,
|
|
20814
|
-
second,
|
|
20815
|
-
minute,
|
|
20816
|
-
hour,
|
|
20817
|
-
day,
|
|
20818
|
-
week,
|
|
20819
|
-
month,
|
|
20820
|
-
year
|
|
20821
|
-
};
|
|
20822
|
-
function filterDataByType(datas, type) {
|
|
20823
|
-
return datas.filter((_) => _.type === type);
|
|
20824
|
-
}
|
|
20825
|
-
function filterDataByTime(datas, start, end) {
|
|
20826
|
-
const startTime = start.getTime();
|
|
20827
|
-
const endTime = end.getTime();
|
|
20828
|
-
return datas.map((data) => ({
|
|
20829
|
-
...data,
|
|
20830
|
-
points: data.points.filter(
|
|
20831
|
-
([timestamp]) => timestamp >= startTime && timestamp < endTime
|
|
20832
|
-
)
|
|
20833
|
-
})).filter(({ points }) => points.length > 0);
|
|
20834
|
-
}
|
|
20835
|
-
function fork(_) {
|
|
20836
|
-
return void 0;
|
|
20837
|
-
}
|
|
20838
|
-
class StoreCache {
|
|
20839
|
-
constructor({
|
|
20840
|
-
capacity,
|
|
20841
|
-
timeout
|
|
20842
|
-
} = {}) {
|
|
20843
|
-
__publicField(this, "entries", /* @__PURE__ */ new Map());
|
|
20844
|
-
__publicField(this, "metadata", /* @__PURE__ */ new Map());
|
|
20845
|
-
__publicField(this, "capacity");
|
|
20846
|
-
__publicField(this, "timeout");
|
|
20847
|
-
this.capacity = capacity || 1e4;
|
|
20848
|
-
this.timeout = timeout || duration.minute;
|
|
20345
|
+
async startListeningToRealtimeDataStream(stream) {
|
|
20346
|
+
const client = defined(
|
|
20347
|
+
this.rtcClient,
|
|
20348
|
+
"Realtime connection has not been started"
|
|
20349
|
+
);
|
|
20350
|
+
const devicePeer = await this.getRemotePeer();
|
|
20351
|
+
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20352
|
+
streamName: stream.name,
|
|
20353
|
+
enable: true,
|
|
20354
|
+
pipeline: "rtc"
|
|
20355
|
+
});
|
|
20849
20356
|
}
|
|
20850
|
-
|
|
20851
|
-
const
|
|
20852
|
-
|
|
20853
|
-
|
|
20854
|
-
|
|
20855
|
-
|
|
20856
|
-
|
|
20857
|
-
|
|
20858
|
-
|
|
20859
|
-
|
|
20860
|
-
|
|
20357
|
+
async stopListeningToRealtimeDataStream(stream) {
|
|
20358
|
+
const client = defined(
|
|
20359
|
+
this.rtcClient,
|
|
20360
|
+
"Realtime connection has not been started"
|
|
20361
|
+
);
|
|
20362
|
+
const devicePeer = await this.getRemotePeer();
|
|
20363
|
+
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20364
|
+
streamName: stream.name,
|
|
20365
|
+
enable: false,
|
|
20366
|
+
pipeline: "rtc"
|
|
20367
|
+
});
|
|
20861
20368
|
}
|
|
20862
|
-
|
|
20863
|
-
const
|
|
20864
|
-
|
|
20865
|
-
|
|
20866
|
-
|
|
20867
|
-
|
|
20369
|
+
async enableRealtimeTelemetryPriorityIngestion(streamName) {
|
|
20370
|
+
const client = defined(
|
|
20371
|
+
this.rtcClient,
|
|
20372
|
+
"Realtime connection has not been started"
|
|
20373
|
+
);
|
|
20374
|
+
const devicePeer = await this.getRemotePeer();
|
|
20375
|
+
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20376
|
+
streamName,
|
|
20377
|
+
enablePriorityUpload: true,
|
|
20378
|
+
pipeline: "telemetry"
|
|
20868
20379
|
});
|
|
20869
|
-
this.entries.set(cacheKey, value);
|
|
20870
|
-
if (this.metadata.size > this.capacity) {
|
|
20871
|
-
this.deleteOldestEntry();
|
|
20872
|
-
}
|
|
20873
20380
|
}
|
|
20874
|
-
|
|
20875
|
-
|
|
20876
|
-
|
|
20381
|
+
async changeStreamAudioType(streamName, newFormat) {
|
|
20382
|
+
const client = defined(
|
|
20383
|
+
this.rtcClient,
|
|
20384
|
+
"Realtime connection has not been started"
|
|
20385
|
+
);
|
|
20386
|
+
const devicePeer = await this.getRemotePeer();
|
|
20387
|
+
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20388
|
+
streamName,
|
|
20389
|
+
setAudioFormat: newFormat
|
|
20390
|
+
});
|
|
20877
20391
|
}
|
|
20878
|
-
|
|
20879
|
-
|
|
20880
|
-
|
|
20392
|
+
async disableRealtimeTelemetryPriorityIngestion(streamName) {
|
|
20393
|
+
const client = defined(
|
|
20394
|
+
this.rtcClient,
|
|
20395
|
+
"Realtime connection has not been started"
|
|
20396
|
+
);
|
|
20397
|
+
const devicePeer = await this.getRemotePeer();
|
|
20398
|
+
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20399
|
+
streamName,
|
|
20400
|
+
enablePriorityUpload: false,
|
|
20401
|
+
pipeline: "telemetry"
|
|
20402
|
+
});
|
|
20881
20403
|
}
|
|
20882
|
-
|
|
20883
|
-
|
|
20404
|
+
async getRemotePeer() {
|
|
20405
|
+
const peers = await defined(
|
|
20406
|
+
this.rtcClient,
|
|
20407
|
+
"Realtime connection has not been started"
|
|
20408
|
+
).getPeers();
|
|
20409
|
+
const devicePeer = peers.find((_) => _.deviceId === this.id);
|
|
20410
|
+
return defined(
|
|
20411
|
+
devicePeer,
|
|
20412
|
+
"Could not find remote peer for device " + this.id
|
|
20413
|
+
);
|
|
20884
20414
|
}
|
|
20885
|
-
|
|
20886
|
-
if (this.
|
|
20887
|
-
|
|
20415
|
+
async stopRealtimeConnection() {
|
|
20416
|
+
if (this.rtcClient) {
|
|
20417
|
+
await this.rtcClient.disconnect(this.id);
|
|
20418
|
+
} else {
|
|
20419
|
+
throw new Error(`Realtime connection hasn't been started for ${this.id}`);
|
|
20888
20420
|
}
|
|
20889
|
-
const [key] = [...this.metadata.entries()].reduce(
|
|
20890
|
-
([oldestKey, oldestEntry], [thisKey, entry]) => entry.expiration.getTime() < oldestEntry.expiration.getTime() ? [thisKey, entry] : [oldestKey, oldestEntry]
|
|
20891
|
-
);
|
|
20892
|
-
this.clearKey(key);
|
|
20893
20421
|
}
|
|
20894
|
-
|
|
20895
|
-
|
|
20896
|
-
|
|
20897
|
-
|
|
20898
|
-
|
|
20899
|
-
|
|
20900
|
-
|
|
20901
|
-
|
|
20902
|
-
setTimeout(() => {
|
|
20903
|
-
fork(
|
|
20904
|
-
promise.then((value) => {
|
|
20905
|
-
const metadata = this.metadata.get(cacheKey);
|
|
20906
|
-
const canceled = !(metadata == null ? void 0 : metadata.generating);
|
|
20907
|
-
if (!canceled) {
|
|
20908
|
-
this.set(key, value);
|
|
20909
|
-
}
|
|
20910
|
-
})
|
|
20911
|
-
);
|
|
20912
|
-
}, 0);
|
|
20422
|
+
async isInRealtimeSession() {
|
|
20423
|
+
let peers = await Fleet.getPeers();
|
|
20424
|
+
let sessions = await Fleet.getRealtimeSessions();
|
|
20425
|
+
let peer = peers.find((_) => _.deviceId === this.id);
|
|
20426
|
+
if (peer) {
|
|
20427
|
+
return sessions[peer.id].length > 0;
|
|
20428
|
+
}
|
|
20429
|
+
return false;
|
|
20913
20430
|
}
|
|
20914
|
-
|
|
20915
|
-
|
|
20916
|
-
|
|
20917
|
-
|
|
20918
|
-
|
|
20919
|
-
|
|
20920
|
-
|
|
20921
|
-
|
|
20922
|
-
|
|
20923
|
-
|
|
20431
|
+
async getAvailableCommands() {
|
|
20432
|
+
const result = await fetch(
|
|
20433
|
+
`${FORMANT_API_URL}/v1/admin/command-templates/`,
|
|
20434
|
+
{
|
|
20435
|
+
method: "GET",
|
|
20436
|
+
headers: {
|
|
20437
|
+
"Content-Type": "application/json",
|
|
20438
|
+
Authorization: "Bearer " + Authentication.token
|
|
20439
|
+
}
|
|
20440
|
+
}
|
|
20441
|
+
);
|
|
20442
|
+
const commands = await result.json();
|
|
20443
|
+
return commands.items.map((i) => ({
|
|
20444
|
+
name: i.name,
|
|
20445
|
+
id: i.id,
|
|
20446
|
+
command: i.command,
|
|
20447
|
+
description: i.description,
|
|
20448
|
+
parameterEnabled: i.parameterEnabled,
|
|
20449
|
+
parameterValue: i.parameterValue,
|
|
20450
|
+
parameterMeta: i.parameterMeta,
|
|
20451
|
+
enabled: i.enabled
|
|
20924
20452
|
}));
|
|
20925
20453
|
}
|
|
20926
|
-
|
|
20927
|
-
|
|
20928
|
-
|
|
20929
|
-
|
|
20930
|
-
|
|
20931
|
-
|
|
20932
|
-
const data = this.query(q, start, end, latestOnly);
|
|
20933
|
-
if (data === void 0 || data === "too much data") {
|
|
20934
|
-
return data;
|
|
20454
|
+
async sendCommand(name, data, time, metadata) {
|
|
20455
|
+
var _a;
|
|
20456
|
+
const commands = await this.getAvailableCommands();
|
|
20457
|
+
const command = commands.find((_) => _.name === name);
|
|
20458
|
+
if (!command) {
|
|
20459
|
+
throw new Error(`Could not find command with name "${name}"`);
|
|
20935
20460
|
}
|
|
20936
|
-
|
|
20937
|
-
|
|
20938
|
-
|
|
20939
|
-
|
|
20940
|
-
|
|
20941
|
-
|
|
20942
|
-
|
|
20943
|
-
|
|
20944
|
-
|
|
20945
|
-
const isLive = end > addSeconds(new Date(), -20);
|
|
20946
|
-
let data;
|
|
20947
|
-
if (isLive) {
|
|
20948
|
-
data = this.liveQueryCache(q);
|
|
20461
|
+
let d;
|
|
20462
|
+
if (data === void 0) {
|
|
20463
|
+
if (command.parameterEnabled && command.parameterValue) {
|
|
20464
|
+
d = command.parameterValue;
|
|
20465
|
+
} else {
|
|
20466
|
+
throw new Error(
|
|
20467
|
+
"Command has no default parameter value, you must provide one"
|
|
20468
|
+
);
|
|
20469
|
+
}
|
|
20949
20470
|
} else {
|
|
20950
|
-
|
|
20951
|
-
}
|
|
20952
|
-
if (!data || data === "too much data") {
|
|
20953
|
-
return data;
|
|
20471
|
+
d = data;
|
|
20954
20472
|
}
|
|
20955
|
-
|
|
20956
|
-
|
|
20473
|
+
let parameter = {
|
|
20474
|
+
value: d,
|
|
20475
|
+
scrubberTime: (time || new Date()).toISOString(),
|
|
20476
|
+
meta: {
|
|
20477
|
+
...command.parameterMeta,
|
|
20478
|
+
...metadata
|
|
20479
|
+
}
|
|
20480
|
+
};
|
|
20481
|
+
await fetch(`${FORMANT_API_URL}/v1/admin/commands`, {
|
|
20482
|
+
method: "POST",
|
|
20483
|
+
body: JSON.stringify({
|
|
20484
|
+
commandTemplateId: command.id,
|
|
20485
|
+
organizationId: this.organizationId,
|
|
20486
|
+
deviceId: this.id,
|
|
20487
|
+
command: command.command,
|
|
20488
|
+
parameter,
|
|
20489
|
+
userId: (_a = Authentication.currentUser) == null ? void 0 : _a.id
|
|
20490
|
+
}),
|
|
20491
|
+
headers: {
|
|
20492
|
+
"Content-Type": "application/json",
|
|
20493
|
+
Authorization: "Bearer " + Authentication.token
|
|
20494
|
+
}
|
|
20495
|
+
});
|
|
20496
|
+
}
|
|
20497
|
+
async createCustomDataChannel(channelName, rtcConfig) {
|
|
20498
|
+
if (rtcClientVersion === "1") {
|
|
20499
|
+
throw new Error(
|
|
20500
|
+
"createCustomDataChannel is not supported in rtcClientVersion 1"
|
|
20501
|
+
);
|
|
20957
20502
|
}
|
|
20958
|
-
|
|
20503
|
+
const client = defined(
|
|
20504
|
+
this.rtcClient,
|
|
20505
|
+
"Realtime connection has not been started"
|
|
20506
|
+
);
|
|
20507
|
+
const devicePeer = await this.getRemotePeer();
|
|
20508
|
+
const p = await new Promise((resolve) => {
|
|
20509
|
+
client.createCustomDataChannel(
|
|
20510
|
+
defined(devicePeer).id,
|
|
20511
|
+
channelName,
|
|
20512
|
+
{
|
|
20513
|
+
ordered: true,
|
|
20514
|
+
...rtcConfig
|
|
20515
|
+
},
|
|
20516
|
+
false,
|
|
20517
|
+
(_peerId, channel) => {
|
|
20518
|
+
const dataChannel = new DataChannel(channel);
|
|
20519
|
+
resolve(dataChannel);
|
|
20520
|
+
}
|
|
20521
|
+
);
|
|
20522
|
+
});
|
|
20523
|
+
await p.waitTilReady();
|
|
20524
|
+
return p;
|
|
20959
20525
|
}
|
|
20960
|
-
|
|
20961
|
-
return this
|
|
20962
|
-
|
|
20963
|
-
|
|
20964
|
-
|
|
20965
|
-
|
|
20526
|
+
createCustomRequestDataChannel(channelName, timeout = 3e3) {
|
|
20527
|
+
return new TextRequestDataChannel(this, channelName, timeout);
|
|
20528
|
+
}
|
|
20529
|
+
createCustomBinaryRequestDataChannel(channelName, timeout = 3e3) {
|
|
20530
|
+
return new BinaryRequestDataChannel(this, channelName, timeout);
|
|
20531
|
+
}
|
|
20532
|
+
async createCaptureStream(streamName) {
|
|
20533
|
+
const result = await fetch(`${FORMANT_API_URL}/v1/admin/capture-sessions`, {
|
|
20534
|
+
method: "POST",
|
|
20535
|
+
body: JSON.stringify({
|
|
20536
|
+
deviceId: this.id,
|
|
20537
|
+
streamName,
|
|
20538
|
+
tags: {}
|
|
20539
|
+
}),
|
|
20540
|
+
headers: {
|
|
20541
|
+
"Content-Type": "application/json",
|
|
20542
|
+
Authorization: "Bearer " + Authentication.token
|
|
20966
20543
|
}
|
|
20967
20544
|
});
|
|
20545
|
+
const captureSession = await result.json();
|
|
20546
|
+
return new CaptureStream(captureSession);
|
|
20968
20547
|
}
|
|
20969
|
-
|
|
20970
|
-
return
|
|
20971
|
-
|
|
20972
|
-
|
|
20973
|
-
|
|
20974
|
-
|
|
20548
|
+
async getTelemetry(streamNameOrStreamNames, start, end, tags) {
|
|
20549
|
+
return await Fleet.getTelemetry(
|
|
20550
|
+
this.id,
|
|
20551
|
+
streamNameOrStreamNames,
|
|
20552
|
+
start,
|
|
20553
|
+
end,
|
|
20554
|
+
tags
|
|
20555
|
+
);
|
|
20556
|
+
}
|
|
20557
|
+
async getTelemetryStreams() {
|
|
20558
|
+
var _a, _b;
|
|
20559
|
+
const config = await this.getConfiguration();
|
|
20560
|
+
const result = await fetch(
|
|
20561
|
+
`${FORMANT_API_URL}/v1/queries/metadata/stream-names`,
|
|
20562
|
+
{
|
|
20563
|
+
method: "POST",
|
|
20564
|
+
body: JSON.stringify({
|
|
20565
|
+
deviceIds: [this.id]
|
|
20566
|
+
}),
|
|
20567
|
+
headers: {
|
|
20568
|
+
"Content-Type": "application/json",
|
|
20569
|
+
Authorization: "Bearer " + Authentication.token
|
|
20570
|
+
}
|
|
20571
|
+
}
|
|
20572
|
+
);
|
|
20573
|
+
const disabledList = [];
|
|
20574
|
+
const onDemandList = [];
|
|
20575
|
+
(_b = (_a = config.telemetry) == null ? void 0 : _a.streams) == null ? void 0 : _b.forEach((_) => {
|
|
20576
|
+
if (_.disabled !== true) {
|
|
20577
|
+
disabledList.push(_.name);
|
|
20578
|
+
}
|
|
20579
|
+
if (_.onDemand === true) {
|
|
20580
|
+
onDemandList.push(_.name);
|
|
20975
20581
|
}
|
|
20976
20582
|
});
|
|
20583
|
+
console.log(onDemandList);
|
|
20584
|
+
const data = await result.json();
|
|
20585
|
+
let streamNames = data.items.filter((_) => !disabledList.includes(_)).map((_) => ({ name: _, onDemand: onDemandList.includes(_) }));
|
|
20586
|
+
return streamNames;
|
|
20977
20587
|
}
|
|
20978
|
-
|
|
20979
|
-
const
|
|
20980
|
-
|
|
20981
|
-
|
|
20982
|
-
|
|
20983
|
-
|
|
20984
|
-
|
|
20985
|
-
|
|
20986
|
-
|
|
20987
|
-
|
|
20988
|
-
|
|
20989
|
-
|
|
20990
|
-
|
|
20588
|
+
async createInterventionRequest(message, interventionType, interventionRequest, tags) {
|
|
20589
|
+
const intervention = await fetch(
|
|
20590
|
+
`${FORMANT_API_URL}/v1/admin/intervention-requests`,
|
|
20591
|
+
{
|
|
20592
|
+
method: "POST",
|
|
20593
|
+
body: JSON.stringify({
|
|
20594
|
+
message,
|
|
20595
|
+
interventionType,
|
|
20596
|
+
time: new Date().toISOString(),
|
|
20597
|
+
deviceId: this.id,
|
|
20598
|
+
tags,
|
|
20599
|
+
data: interventionRequest
|
|
20600
|
+
}),
|
|
20601
|
+
headers: {
|
|
20602
|
+
"Content-Type": "application/json",
|
|
20603
|
+
Authorization: "Bearer " + Authentication.token
|
|
20604
|
+
}
|
|
20605
|
+
}
|
|
20606
|
+
);
|
|
20607
|
+
const interventionJson = await intervention.json();
|
|
20608
|
+
return interventionJson;
|
|
20991
20609
|
}
|
|
20992
|
-
|
|
20993
|
-
let urlParams2 = new URLSearchParams("");
|
|
20994
|
-
if (typeof window !== "undefined") {
|
|
20995
|
-
urlParams2 = new URLSearchParams(window.location.search);
|
|
20996
|
-
}
|
|
20997
|
-
const configurationId = urlParams2.get("configuration");
|
|
20998
|
-
if (configurationId === null || configurationId.trim() === "") {
|
|
20999
|
-
return void 0;
|
|
21000
|
-
}
|
|
20610
|
+
async addInterventionResponse(interventionId, interventionType, data) {
|
|
21001
20611
|
const response = await fetch(
|
|
21002
|
-
`${FORMANT_API_URL}/v1/admin/
|
|
20612
|
+
`${FORMANT_API_URL}/v1/admin/intervention-responses`,
|
|
21003
20613
|
{
|
|
20614
|
+
method: "POST",
|
|
20615
|
+
body: JSON.stringify({
|
|
20616
|
+
interventionId,
|
|
20617
|
+
interventionType,
|
|
20618
|
+
data
|
|
20619
|
+
}),
|
|
21004
20620
|
headers: {
|
|
21005
20621
|
"Content-Type": "application/json",
|
|
21006
20622
|
Authorization: "Bearer " + Authentication.token
|
|
21007
20623
|
}
|
|
21008
20624
|
}
|
|
21009
20625
|
);
|
|
21010
|
-
const
|
|
21011
|
-
return
|
|
21012
|
-
}
|
|
21013
|
-
static isModule() {
|
|
21014
|
-
return this.getCurrentModuleContext() !== null;
|
|
21015
|
-
}
|
|
21016
|
-
static goToTime(date) {
|
|
21017
|
-
this.sendAppMessage({
|
|
21018
|
-
type: "go_to_time",
|
|
21019
|
-
time: date.getTime()
|
|
21020
|
-
});
|
|
21021
|
-
}
|
|
21022
|
-
static goToDevice(deviceId) {
|
|
21023
|
-
this.sendAppMessage({
|
|
21024
|
-
type: "go_to_device",
|
|
21025
|
-
deviceId
|
|
21026
|
-
});
|
|
21027
|
-
}
|
|
21028
|
-
static showMessage(message) {
|
|
21029
|
-
this.sendAppMessage({ type: "show_message", message });
|
|
20626
|
+
const interventionResponse = await response.json();
|
|
20627
|
+
return interventionResponse;
|
|
21030
20628
|
}
|
|
21031
|
-
|
|
21032
|
-
|
|
21033
|
-
|
|
21034
|
-
|
|
21035
|
-
|
|
21036
|
-
this
|
|
21037
|
-
|
|
21038
|
-
|
|
20629
|
+
}
|
|
20630
|
+
class PeerDevice {
|
|
20631
|
+
constructor(peerUrl) {
|
|
20632
|
+
__publicField(this, "rtcClient");
|
|
20633
|
+
__publicField(this, "remoteDevicePeerId");
|
|
20634
|
+
__publicField(this, "realtimeListeners", []);
|
|
20635
|
+
__publicField(this, "id");
|
|
20636
|
+
__publicField(this, "handleMessage", (peerId, message) => {
|
|
20637
|
+
this.realtimeListeners.forEach((_) => _(peerId, message));
|
|
21039
20638
|
});
|
|
20639
|
+
this.peerUrl = peerUrl;
|
|
21040
20640
|
}
|
|
21041
|
-
|
|
21042
|
-
const
|
|
21043
|
-
|
|
21044
|
-
|
|
21045
|
-
|
|
21046
|
-
|
|
21047
|
-
|
|
21048
|
-
|
|
21049
|
-
|
|
21050
|
-
|
|
20641
|
+
async getLatestTelemetry() {
|
|
20642
|
+
const data = await fetch(`${this.peerUrl}/telemetry`);
|
|
20643
|
+
const telemetry = await data.json();
|
|
20644
|
+
const entries = Object.entries(telemetry);
|
|
20645
|
+
return entries.map(([stream, latestValue]) => {
|
|
20646
|
+
const v = {
|
|
20647
|
+
deviceId: this.id,
|
|
20648
|
+
streamName: stream,
|
|
20649
|
+
streamType: "json",
|
|
20650
|
+
currentValue: latestValue,
|
|
20651
|
+
currentValueTime: latestValue.timestamp,
|
|
20652
|
+
tags: {}
|
|
20653
|
+
};
|
|
20654
|
+
return v;
|
|
21051
20655
|
});
|
|
21052
20656
|
}
|
|
21053
|
-
|
|
21054
|
-
|
|
21055
|
-
|
|
21056
|
-
|
|
21057
|
-
}
|
|
21058
|
-
this.sendAppMessage({
|
|
21059
|
-
type: "refresh_auth_token",
|
|
21060
|
-
module: moduleName2
|
|
21061
|
-
});
|
|
20657
|
+
async getDeviceId() {
|
|
20658
|
+
let result = await fetch(`${this.peerUrl}/configuration`);
|
|
20659
|
+
const cfg = await result.json();
|
|
20660
|
+
return cfg.agent_config.id;
|
|
21062
20661
|
}
|
|
21063
|
-
|
|
21064
|
-
|
|
21065
|
-
|
|
21066
|
-
|
|
21067
|
-
}
|
|
21068
|
-
this.sendAppMessage({
|
|
21069
|
-
type: "send_channel_data",
|
|
21070
|
-
source: moduleName2,
|
|
21071
|
-
channel,
|
|
21072
|
-
data
|
|
21073
|
-
});
|
|
20662
|
+
async getConfiguration() {
|
|
20663
|
+
let result = await fetch(`${this.peerUrl}/configuration`);
|
|
20664
|
+
const cfg = await result.json();
|
|
20665
|
+
return cfg.agent_config.document;
|
|
21074
20666
|
}
|
|
21075
|
-
|
|
21076
|
-
|
|
21077
|
-
|
|
21078
|
-
|
|
20667
|
+
getRealtimeStatus() {
|
|
20668
|
+
if (this.rtcClient && this.remoteDevicePeerId) {
|
|
20669
|
+
return this.rtcClient.getConnectionStatus(this.remoteDevicePeerId);
|
|
20670
|
+
} else {
|
|
20671
|
+
throw new Error(`Realtime connection hasn't been started`);
|
|
21079
20672
|
}
|
|
21080
|
-
this.sendAppMessage({
|
|
21081
|
-
type: "setup_module_menus",
|
|
21082
|
-
module: moduleName2,
|
|
21083
|
-
menus
|
|
21084
|
-
});
|
|
21085
20673
|
}
|
|
21086
|
-
|
|
21087
|
-
|
|
21088
|
-
|
|
21089
|
-
|
|
21090
|
-
|
|
21091
|
-
}
|
|
21092
|
-
});
|
|
21093
|
-
}
|
|
21094
|
-
static addAccessTokenRefreshListener(handler) {
|
|
21095
|
-
window.addEventListener("message", (event) => {
|
|
21096
|
-
const msg = event.data;
|
|
21097
|
-
if (msg.type === "auth_token") {
|
|
21098
|
-
handler(msg.token);
|
|
21099
|
-
}
|
|
21100
|
-
});
|
|
21101
|
-
}
|
|
21102
|
-
static addModuleDataListener(handler) {
|
|
21103
|
-
const moduleName2 = this.getCurrentModuleContext();
|
|
21104
|
-
if (moduleName2) {
|
|
21105
|
-
this.sendAppMessage({ type: "request_module_data", module: moduleName2 });
|
|
20674
|
+
getRealtimePing() {
|
|
20675
|
+
if (this.rtcClient && this.remoteDevicePeerId) {
|
|
20676
|
+
return this.rtcClient.getPing(this.remoteDevicePeerId);
|
|
20677
|
+
} else {
|
|
20678
|
+
throw new Error(`Realtime connection hasn't been started`);
|
|
21106
20679
|
}
|
|
21107
|
-
window.addEventListener("message", (event) => {
|
|
21108
|
-
const msg = event.data;
|
|
21109
|
-
if (msg.type === "module_data") {
|
|
21110
|
-
handler({
|
|
21111
|
-
streams: msg.streams,
|
|
21112
|
-
time: msg.time,
|
|
21113
|
-
queryRange: msg.queryRange
|
|
21114
|
-
});
|
|
21115
|
-
}
|
|
21116
|
-
});
|
|
21117
|
-
}
|
|
21118
|
-
static addStreamListener(streamName, streamType, handler) {
|
|
21119
|
-
const listener = (event) => {
|
|
21120
|
-
const msg = event.data;
|
|
21121
|
-
if (msg.type === "module_data") {
|
|
21122
|
-
const { start, end } = msg.queryRange;
|
|
21123
|
-
handler(
|
|
21124
|
-
queryStore.moduleQuery(
|
|
21125
|
-
{},
|
|
21126
|
-
streamName,
|
|
21127
|
-
streamType,
|
|
21128
|
-
new Date(start),
|
|
21129
|
-
new Date(end),
|
|
21130
|
-
false
|
|
21131
|
-
)
|
|
21132
|
-
);
|
|
21133
|
-
}
|
|
21134
|
-
};
|
|
21135
|
-
window.addEventListener("message", listener);
|
|
21136
|
-
return () => window.removeEventListener("message", listener);
|
|
21137
|
-
}
|
|
21138
|
-
static addModuleConfigurationListener(handler) {
|
|
21139
|
-
window.addEventListener("message", (event) => {
|
|
21140
|
-
const msg = event.data;
|
|
21141
|
-
if (msg.type === "module_configuration") {
|
|
21142
|
-
handler(msg);
|
|
21143
|
-
}
|
|
21144
|
-
});
|
|
21145
|
-
}
|
|
21146
|
-
static addChannelDataListener(channel, handler) {
|
|
21147
|
-
window.addEventListener("message", (event) => {
|
|
21148
|
-
const msg = event.data;
|
|
21149
|
-
if (msg.type === "channel_data" && msg.channel === channel) {
|
|
21150
|
-
handler({
|
|
21151
|
-
source: msg.source,
|
|
21152
|
-
data: msg.data
|
|
21153
|
-
});
|
|
21154
|
-
}
|
|
21155
|
-
});
|
|
21156
|
-
}
|
|
21157
|
-
static requestOverviewDevices(handler) {
|
|
21158
|
-
this.sendAppMessage({ type: "request_devices" });
|
|
21159
|
-
window.addEventListener("message", (event) => {
|
|
21160
|
-
const msg = event.data;
|
|
21161
|
-
handler(msg);
|
|
21162
|
-
});
|
|
21163
|
-
}
|
|
21164
|
-
static async prompt(schema, options) {
|
|
21165
|
-
return new Promise((resolve) => {
|
|
21166
|
-
const promptId = Math.random().toString();
|
|
21167
|
-
this.sendAppMessage({
|
|
21168
|
-
type: "prompt",
|
|
21169
|
-
promptId,
|
|
21170
|
-
schema,
|
|
21171
|
-
okText: options == null ? void 0 : options.okText,
|
|
21172
|
-
cancelText: options == null ? void 0 : options.cancelText
|
|
21173
|
-
});
|
|
21174
|
-
const handler = (event) => {
|
|
21175
|
-
const msg = event.data;
|
|
21176
|
-
if (msg.type === "prompt_response" && msg.promptId === promptId) {
|
|
21177
|
-
resolve(msg.data);
|
|
21178
|
-
}
|
|
21179
|
-
window.removeEventListener("message", handler);
|
|
21180
|
-
};
|
|
21181
|
-
window.addEventListener("message", handler);
|
|
21182
|
-
});
|
|
21183
20680
|
}
|
|
21184
|
-
|
|
21185
|
-
|
|
21186
|
-
|
|
21187
|
-
|
|
21188
|
-
|
|
21189
|
-
|
|
21190
|
-
body: JSON.stringify({ email, password }),
|
|
21191
|
-
headers: {
|
|
21192
|
-
"Content-Type": "application/json"
|
|
21193
|
-
}
|
|
20681
|
+
async startRealtimeConnection(sessionType) {
|
|
20682
|
+
if (!this.rtcClient) {
|
|
20683
|
+
const rtcClient = new dist.exports.RtcClient({
|
|
20684
|
+
lanOnlyMode: true,
|
|
20685
|
+
receive: this.handleMessage,
|
|
20686
|
+
sessionType
|
|
21194
20687
|
});
|
|
21195
|
-
|
|
21196
|
-
|
|
21197
|
-
|
|
20688
|
+
await rtcClient.connectLan(this.peerUrl);
|
|
20689
|
+
while (rtcClient.getConnectionStatus(this.peerUrl) !== "connected") {
|
|
20690
|
+
await delay(100);
|
|
21198
20691
|
}
|
|
21199
|
-
|
|
21200
|
-
|
|
21201
|
-
|
|
20692
|
+
this.rtcClient = rtcClient;
|
|
20693
|
+
} else {
|
|
20694
|
+
throw new Error(
|
|
20695
|
+
`Already created realtime connection to device ${this.id}`
|
|
21202
20696
|
);
|
|
21203
|
-
return auth.authentication;
|
|
21204
|
-
} catch (e) {
|
|
21205
|
-
_Authentication.waitingForAuth.forEach((_) => _(false));
|
|
21206
|
-
_Authentication.waitingForAuth = [];
|
|
21207
|
-
return Promise.reject(e);
|
|
21208
20697
|
}
|
|
21209
20698
|
}
|
|
21210
|
-
|
|
21211
|
-
|
|
21212
|
-
|
|
21213
|
-
|
|
21214
|
-
|
|
21215
|
-
|
|
21216
|
-
|
|
21217
|
-
|
|
21218
|
-
|
|
21219
|
-
|
|
20699
|
+
addRealtimeListener(listener) {
|
|
20700
|
+
this.realtimeListeners.push(listener);
|
|
20701
|
+
}
|
|
20702
|
+
removeRealtimeListener(listener) {
|
|
20703
|
+
const i = this.realtimeListeners.indexOf(listener);
|
|
20704
|
+
if (i === -1) {
|
|
20705
|
+
throw new Error("Could not find realtime listener to remove");
|
|
20706
|
+
}
|
|
20707
|
+
this.realtimeListeners.splice(i, 1);
|
|
20708
|
+
}
|
|
20709
|
+
async getRealtimeVideoStreams() {
|
|
20710
|
+
var _a, _b, _c;
|
|
20711
|
+
const document2 = await this.getConfiguration();
|
|
20712
|
+
const streams = [];
|
|
20713
|
+
for (const _ of (_a = document2.teleop.hardwareStreams) != null ? _a : []) {
|
|
20714
|
+
if (_.rtcStreamType === "h264-video-frame") {
|
|
20715
|
+
streams.push({
|
|
20716
|
+
name: _.name
|
|
20717
|
+
});
|
|
21220
20718
|
}
|
|
21221
|
-
|
|
21222
|
-
|
|
20719
|
+
}
|
|
20720
|
+
for (const _ of (_b = document2.teleop.rosStreams) != null ? _b : []) {
|
|
20721
|
+
if (_.topicType == "formant/H264VideoFrame") {
|
|
20722
|
+
streams.push({
|
|
20723
|
+
name: _.topicName
|
|
20724
|
+
});
|
|
21223
20725
|
}
|
|
21224
|
-
|
|
21225
|
-
|
|
20726
|
+
}
|
|
20727
|
+
for (const _ of (_c = document2.teleop.customStreams) != null ? _c : []) {
|
|
20728
|
+
if (_.rtcStreamType === "h264-video-frame") {
|
|
20729
|
+
streams.push({
|
|
20730
|
+
name: _.name
|
|
20731
|
+
});
|
|
21226
20732
|
}
|
|
21227
|
-
|
|
21228
|
-
|
|
21229
|
-
|
|
21230
|
-
|
|
21231
|
-
|
|
21232
|
-
|
|
21233
|
-
|
|
21234
|
-
|
|
21235
|
-
|
|
21236
|
-
|
|
20733
|
+
}
|
|
20734
|
+
return streams;
|
|
20735
|
+
}
|
|
20736
|
+
async getRealtimeManipulators() {
|
|
20737
|
+
var _a;
|
|
20738
|
+
const document2 = await this.getConfiguration();
|
|
20739
|
+
const manipulators = [];
|
|
20740
|
+
for (const _ of (_a = document2.teleop.rosStreams) != null ? _a : []) {
|
|
20741
|
+
if (_.topicType == "sensor_msgs/JointState") {
|
|
20742
|
+
manipulators.push(
|
|
20743
|
+
new Manipulator(this, {
|
|
20744
|
+
currentJointStateStream: { name: _.topicName },
|
|
20745
|
+
plannedJointStateStream: _.plannedTopic ? { name: _.plannedTopic } : void 0,
|
|
20746
|
+
planValidStream: _.planValidTopic ? { name: _.planValidTopic } : void 0,
|
|
20747
|
+
endEffectorStream: _.endEffectorTopic ? { name: _.endEffectorTopic } : void 0,
|
|
20748
|
+
endEffectorLinkName: _.endEffectorLinkName,
|
|
20749
|
+
baseReferenceFrame: _.baseReferenceFrame,
|
|
20750
|
+
localFrame: _.localFrame
|
|
20751
|
+
})
|
|
21237
20752
|
);
|
|
21238
|
-
const data = await result.json();
|
|
21239
|
-
if (result.status !== 200) {
|
|
21240
|
-
throw new Error(data.message);
|
|
21241
|
-
}
|
|
21242
|
-
_Authentication.currentUser = data;
|
|
21243
20753
|
}
|
|
21244
|
-
_Authentication.token = token;
|
|
21245
|
-
_Authentication.waitingForAuth.forEach((_) => _(true));
|
|
21246
|
-
} catch (e) {
|
|
21247
|
-
console.error(e);
|
|
21248
|
-
_Authentication.waitingForAuth.forEach((_) => _(false));
|
|
21249
|
-
}
|
|
21250
|
-
_Authentication.waitingForAuth = [];
|
|
21251
|
-
if (refreshToken) {
|
|
21252
|
-
_Authentication.refreshToken = refreshToken;
|
|
21253
|
-
setInterval(async () => {
|
|
21254
|
-
if (_Authentication.refreshToken) {
|
|
21255
|
-
const result = await fetch(
|
|
21256
|
-
`${FORMANT_API_URL}/v1/admin/auth/refresh`,
|
|
21257
|
-
{
|
|
21258
|
-
method: "POST",
|
|
21259
|
-
headers: {
|
|
21260
|
-
"Content-Type": "application/json"
|
|
21261
|
-
},
|
|
21262
|
-
body: JSON.stringify({
|
|
21263
|
-
refreshToken: _Authentication.refreshToken
|
|
21264
|
-
})
|
|
21265
|
-
}
|
|
21266
|
-
);
|
|
21267
|
-
const refreshData = await result.json();
|
|
21268
|
-
_Authentication.token = refreshData.authentication.accessToken;
|
|
21269
|
-
}
|
|
21270
|
-
}, 1e3 * 60 * 60);
|
|
21271
20754
|
}
|
|
20755
|
+
return manipulators;
|
|
21272
20756
|
}
|
|
21273
|
-
|
|
21274
|
-
|
|
20757
|
+
async startListeningToRealtimeVideo(stream) {
|
|
20758
|
+
const client = defined(
|
|
20759
|
+
this.rtcClient,
|
|
20760
|
+
"Realtime connection has not been started"
|
|
20761
|
+
);
|
|
20762
|
+
const devicePeer = await this.getRemotePeer();
|
|
20763
|
+
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20764
|
+
streamName: stream.name,
|
|
20765
|
+
enable: true,
|
|
20766
|
+
pipeline: "rtc"
|
|
20767
|
+
});
|
|
21275
20768
|
}
|
|
21276
|
-
|
|
21277
|
-
|
|
20769
|
+
async stopListeningToRealtimeVideo(stream) {
|
|
20770
|
+
const client = defined(
|
|
20771
|
+
this.rtcClient,
|
|
20772
|
+
"Realtime connection has not been started"
|
|
20773
|
+
);
|
|
20774
|
+
const devicePeer = await this.getRemotePeer();
|
|
20775
|
+
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20776
|
+
streamName: stream.name,
|
|
20777
|
+
enable: false,
|
|
20778
|
+
pipeline: "rtc"
|
|
20779
|
+
});
|
|
21278
20780
|
}
|
|
21279
|
-
|
|
21280
|
-
|
|
21281
|
-
|
|
20781
|
+
async startListeningToRealtimeDataStream(stream) {
|
|
20782
|
+
const client = defined(
|
|
20783
|
+
this.rtcClient,
|
|
20784
|
+
"Realtime connection has not been started"
|
|
20785
|
+
);
|
|
20786
|
+
const devicePeer = await this.getRemotePeer();
|
|
20787
|
+
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20788
|
+
streamName: stream.name,
|
|
20789
|
+
enable: true,
|
|
20790
|
+
pipeline: "rtc"
|
|
20791
|
+
});
|
|
20792
|
+
}
|
|
20793
|
+
async stopListeningToRealtimeDataStream(stream) {
|
|
20794
|
+
const client = defined(
|
|
20795
|
+
this.rtcClient,
|
|
20796
|
+
"Realtime connection has not been started"
|
|
20797
|
+
);
|
|
20798
|
+
const devicePeer = await this.getRemotePeer();
|
|
20799
|
+
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20800
|
+
streamName: stream.name,
|
|
20801
|
+
enable: false,
|
|
20802
|
+
pipeline: "rtc"
|
|
20803
|
+
});
|
|
20804
|
+
}
|
|
20805
|
+
async enableRealtimeTelemetryPriorityIngestion(streamName) {
|
|
20806
|
+
const client = defined(
|
|
20807
|
+
this.rtcClient,
|
|
20808
|
+
"Realtime connection has not been started"
|
|
20809
|
+
);
|
|
20810
|
+
const devicePeer = await this.getRemotePeer();
|
|
20811
|
+
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20812
|
+
streamName,
|
|
20813
|
+
enablePriorityUpload: true,
|
|
20814
|
+
pipeline: "telemetry"
|
|
20815
|
+
});
|
|
20816
|
+
}
|
|
20817
|
+
async disableRealtimeTelemetryPriorityIngestion(streamName) {
|
|
20818
|
+
const client = defined(
|
|
20819
|
+
this.rtcClient,
|
|
20820
|
+
"Realtime connection has not been started"
|
|
20821
|
+
);
|
|
20822
|
+
const devicePeer = await this.getRemotePeer();
|
|
20823
|
+
client.controlRemoteStream(defined(devicePeer).id, {
|
|
20824
|
+
streamName,
|
|
20825
|
+
enablePriorityUpload: false,
|
|
20826
|
+
pipeline: "telemetry"
|
|
20827
|
+
});
|
|
20828
|
+
}
|
|
20829
|
+
async getRemotePeer() {
|
|
20830
|
+
return {
|
|
20831
|
+
id: this.peerUrl,
|
|
20832
|
+
organizationId: "",
|
|
20833
|
+
deviceId: this.id,
|
|
20834
|
+
capabilities: [],
|
|
20835
|
+
capabilitySet: {}
|
|
20836
|
+
};
|
|
20837
|
+
}
|
|
20838
|
+
async stopRealtimeConnection() {
|
|
20839
|
+
if (this.rtcClient) {
|
|
20840
|
+
await this.rtcClient.disconnect(this.id);
|
|
21282
20841
|
} else {
|
|
21283
|
-
|
|
21284
|
-
_Authentication.waitingForAuth.push(function(result) {
|
|
21285
|
-
resolve(result);
|
|
21286
|
-
});
|
|
21287
|
-
});
|
|
20842
|
+
throw new Error(`Realtime connection hasn't been started for ${this.id}`);
|
|
21288
20843
|
}
|
|
21289
20844
|
}
|
|
21290
|
-
|
|
21291
|
-
|
|
21292
|
-
this.
|
|
20845
|
+
async createCustomDataChannel(channelName, rtcConfig) {
|
|
20846
|
+
const client = defined(
|
|
20847
|
+
this.rtcClient,
|
|
20848
|
+
"Realtime connection has not been started"
|
|
20849
|
+
);
|
|
20850
|
+
const devicePeer = await this.getRemotePeer();
|
|
20851
|
+
const p = await new Promise((resolve) => {
|
|
20852
|
+
client.createCustomDataChannel(
|
|
20853
|
+
defined(devicePeer).id,
|
|
20854
|
+
channelName,
|
|
20855
|
+
{
|
|
20856
|
+
ordered: true,
|
|
20857
|
+
...rtcConfig
|
|
20858
|
+
},
|
|
20859
|
+
false,
|
|
20860
|
+
(_peerId, channel) => {
|
|
20861
|
+
const dataChannel = new DataChannel(channel);
|
|
20862
|
+
resolve(dataChannel);
|
|
20863
|
+
}
|
|
20864
|
+
);
|
|
21293
20865
|
});
|
|
21294
|
-
|
|
21295
|
-
|
|
21296
|
-
}, 1e3 * 60 * 60);
|
|
20866
|
+
await p.waitTilReady();
|
|
20867
|
+
return p;
|
|
21297
20868
|
}
|
|
21298
|
-
|
|
21299
|
-
|
|
21300
|
-
|
|
21301
|
-
|
|
21302
|
-
|
|
21303
|
-
|
|
21304
|
-
|
|
21305
|
-
__publicField(Authentication, "defaultDeviceId");
|
|
21306
|
-
__publicField(Authentication, "waitingForAuth", []);
|
|
20869
|
+
createCustomRequestDataChannel(channelName, timeout = 3e3) {
|
|
20870
|
+
return new TextRequestDataChannel(this, channelName, timeout);
|
|
20871
|
+
}
|
|
20872
|
+
createCustomBinaryRequestDataChannel(channelName, timeout = 3e3) {
|
|
20873
|
+
return new BinaryRequestDataChannel(this, channelName, timeout);
|
|
20874
|
+
}
|
|
20875
|
+
}
|
|
21307
20876
|
const _Fleet = class {
|
|
21308
20877
|
static async setDefaultDevice(deviceId) {
|
|
21309
20878
|
_Fleet.defaultDeviceId = deviceId;
|
|
@@ -21636,6 +21205,27 @@ const _Fleet = class {
|
|
|
21636
21205
|
});
|
|
21637
21206
|
return devices;
|
|
21638
21207
|
}
|
|
21208
|
+
static async getAnnotationCount(query) {
|
|
21209
|
+
const tagKey = query.tagKey;
|
|
21210
|
+
delete query.tagKey, delete query.aggregate;
|
|
21211
|
+
const annotations = await this.queryEvents({
|
|
21212
|
+
...query,
|
|
21213
|
+
eventTypes: ["annotation"]
|
|
21214
|
+
});
|
|
21215
|
+
const validAnnotations = annotations.filter(
|
|
21216
|
+
(_) => !!_.tags && Object.keys(_.tags).includes(tagKey)
|
|
21217
|
+
);
|
|
21218
|
+
const annotationCounter = validAnnotations.reduce((prev, current) => {
|
|
21219
|
+
const value = current.tags[tagKey];
|
|
21220
|
+
if (value in prev) {
|
|
21221
|
+
prev[value] += 1;
|
|
21222
|
+
return prev;
|
|
21223
|
+
}
|
|
21224
|
+
prev[value] = 1;
|
|
21225
|
+
return prev;
|
|
21226
|
+
}, {});
|
|
21227
|
+
return annotationCounter;
|
|
21228
|
+
}
|
|
21639
21229
|
};
|
|
21640
21230
|
let Fleet = _Fleet;
|
|
21641
21231
|
__publicField(Fleet, "defaultDeviceId");
|