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