@formant/data-sdk 0.0.129 → 0.0.130

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
- function delay(ms) {
19235
- return new Promise((resolve) => setTimeout(resolve, ms));
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
- class DataChannel {
19238
- constructor(dataChannel) {
19239
- __publicField(this, "ready", false);
19240
- __publicField(this, "listeners", []);
19241
- __publicField(this, "openListeners", []);
19242
- __publicField(this, "closeListeners", []);
19243
- __publicField(this, "errorListeners", []);
19244
- __publicField(this, "binaryListeners", []);
19245
- __publicField(this, "error");
19246
- __publicField(this, "decoder", new TextDecoder());
19247
- this.dataChannel = dataChannel;
19248
- this.dataChannel.binaryType = "arraybuffer";
19249
- this.dataChannel.onopen = () => {
19250
- this.ready = true;
19251
- this.openListeners.forEach((listener) => listener());
19252
- };
19253
- this.dataChannel.onclose = () => {
19254
- this.ready = false;
19255
- this.closeListeners.forEach((listener) => listener());
19256
- };
19257
- this.dataChannel.onerror = (e) => {
19258
- console.error(e);
19259
- this.error = "An error occurred in DataChannel";
19260
- this.errorListeners.forEach((listener) => listener(e));
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
- removeOpenListener(listener) {
19277
- this.openListeners = this.openListeners.filter((_) => _ !== listener);
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
- addCloseListener(listener) {
19280
- this.closeListeners.push(listener);
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
- removeCloseListener(listener) {
19283
- this.closeListeners = this.closeListeners.filter((l) => l !== listener);
19304
+ clear() {
19305
+ this.entries.clear();
19306
+ [...this.metadata.values()].forEach((value) => value.generating = false);
19284
19307
  }
19285
- addErrorListener(listener) {
19286
- this.errorListeners.push(listener);
19308
+ clearKey(key) {
19309
+ this.metadata.delete(key);
19310
+ this.entries.delete(key);
19287
19311
  }
19288
- removeErrorListener(listener) {
19289
- this.errorListeners = this.errorListeners.filter((l) => l !== listener);
19312
+ keyToCacheKey(key) {
19313
+ return JSON.stringify(key);
19290
19314
  }
19291
- async waitTilReady() {
19292
- if (this.ready) {
19293
- return true;
19315
+ deleteOldestEntry() {
19316
+ if (this.metadata.size < 1) {
19317
+ return;
19294
19318
  }
19295
- const p = new Promise((resolve, reject) => {
19296
- let a2 = window.setInterval(() => {
19297
- if (this.ready) {
19298
- window.clearInterval(a2);
19299
- resolve(true);
19300
- }
19301
- if (this.error) {
19302
- reject(this.error);
19303
- }
19304
- }, 10);
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
- return p;
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
- send(data) {
19309
- if (!this.ready) {
19310
- throw new Error("Connection has been closed");
19311
- }
19312
- this.dataChannel.send(data);
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
- sendBinary(data) {
19315
- if (!this.ready) {
19316
- throw new Error("Connection has been closed");
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
- this.dataChannel.send(data);
19319
- }
19320
- addListener(listener) {
19321
- this.listeners.push(listener);
19366
+ return filterDataByType(data, type);
19322
19367
  }
19323
- removeListener(listener) {
19324
- const i = this.listeners.indexOf(listener);
19325
- if (i === -1) {
19326
- throw new Error("Could not find data channel listener to remove");
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 (this.error) {
19329
- throw new Error(this.error);
19382
+ if (!data || data === "too much data") {
19383
+ return data;
19330
19384
  }
19331
- this.listeners.splice(i, 1);
19385
+ if (latestOnly) {
19386
+ return data;
19387
+ }
19388
+ return filterDataByTime(data, start, end);
19332
19389
  }
19333
- addBinaryListener(listener) {
19334
- this.binaryListeners.push(listener);
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
- removeBinaryListener(listener) {
19337
- const i = this.binaryListeners.indexOf(listener);
19338
- if (i === -1) {
19339
- throw new Error("Could not find data channel listener to remove");
19340
- }
19341
- if (this.error) {
19342
- throw new Error(this.error);
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
- class CaptureStream {
19348
- constructor(captureSession) {
19349
- __publicField(this, "token");
19350
- this.captureSession = captureSession;
19409
+ const queryStore = new QueryStore();
19410
+ class App {
19411
+ static sendAppMessage(message) {
19412
+ window.parent.postMessage(message, "*");
19351
19413
  }
19352
- async ingestJSON(value) {
19353
- if (!this.token) {
19354
- const result = await fetch(
19355
- `${FORMANT_API_URL}/v1/admin/capture-sessions/${this.captureSession.code}/authenticate`,
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
- await fetch(`${FORMANT_API_URL}/v1/ingest`, {
19364
- method: "POST",
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
- class Manipulator {
19379
- constructor(device, config) {
19380
- __publicField(this, "currentListeners", []);
19381
- __publicField(this, "onRealtimeMessage", (_peerId, message) => {
19382
- if (message.payload.jointState) {
19383
- this.currentListeners.forEach((listener) => {
19384
- if (message.payload.jointState)
19385
- listener(message.payload.jointState);
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
- async addCurrentJointStateListener(listener) {
19405
- this.currentListeners.push(listener);
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
- addOpenListener(listener) {
19417
- defined(this.channel, "channel not initalized").addOpenListener(listener);
19446
+ static goToTime(date) {
19447
+ this.sendAppMessage({
19448
+ type: "go_to_time",
19449
+ time: date.getTime()
19450
+ });
19418
19451
  }
19419
- removeOpenListener(listener) {
19420
- defined(this.channel, "channel not initalized").removeOpenListener(
19421
- listener
19422
- );
19452
+ static goToDevice(deviceId) {
19453
+ this.sendAppMessage({
19454
+ type: "go_to_device",
19455
+ deviceId
19456
+ });
19423
19457
  }
19424
- addCloseListener(listener) {
19425
- defined(this.channel, "channel not initalized").addCloseListener(listener);
19458
+ static showMessage(message) {
19459
+ this.sendAppMessage({ type: "show_message", message });
19426
19460
  }
19427
- removeCloseListener(listener) {
19428
- defined(this.channel, "channel not initalized").removeCloseListener(
19429
- listener
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
- addErrorListener(listener) {
19433
- defined(this.channel, "channel not initalized").addErrorListener(listener);
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
- removeErrorListener(listener) {
19436
- defined(this.channel, "channel not initalized").removeErrorListener(
19437
- listener
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
- class BinaryRequestDataChannel extends RequestDataChannel {
19442
- constructor() {
19443
- super(...arguments);
19444
- __publicField(this, "RESPONSE_SUCCESS_BYTE", 0);
19445
- __publicField(this, "decoder", new TextDecoder());
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
- generateBinaryId() {
19448
- const id = new Uint8Array(16);
19449
- for (let i = 0; i < id.length; i++) {
19450
- id[i] = Math.floor(Math.random() * 256);
19505
+ static setupModuleMenus(menus) {
19506
+ const moduleName2 = this.getCurrentModuleContext();
19507
+ if (!moduleName2) {
19508
+ throw new Error("No module context");
19451
19509
  }
19452
- return id;
19510
+ this.sendAppMessage({
19511
+ type: "setup_module_menus",
19512
+ module: moduleName2,
19513
+ menus
19514
+ });
19453
19515
  }
19454
- async initialize() {
19455
- this.channel = await this.device.createCustomDataChannel(this.channel_name);
19456
- this.channel.addBinaryListener((message) => {
19457
- const binaryId = message.slice(0, 16);
19458
- const id = binaryId.toString();
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
- if (this.requestIdToResponseMap.has(id)) {
19467
- this.requestIdToResponseMap.set(id, response);
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
- async request(data) {
19472
- if (!this.channel) {
19473
- await this.initialize();
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
- const { channel, requestIdToResponseMap, timeout } = this;
19479
- await channel.waitTilReady();
19480
- const binaryId = this.generateBinaryId();
19481
- const id = binaryId.toString();
19482
- requestIdToResponseMap.set(id, true);
19483
- channel.sendBinary(new Uint8Array([...binaryId, ...data]));
19484
- const start = new Date().getTime();
19485
- while (new Date().getTime() < start + timeout) {
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
- class TextRequestDataChannel extends RequestDataChannel {
19514
- generateTextId() {
19515
- return Math.random().toString(36).substring(2) + "-" + Math.random().toString(36).substring(2);
19516
- }
19517
- async initialize() {
19518
- this.channel = await this.device.createCustomDataChannel(this.channel_name);
19519
- this.channel.addListener((message) => {
19520
- const response = JSON.parse(message);
19521
- const { id, data, error } = response;
19522
- if (!id) {
19523
- throw new Error("Invalid response");
19524
- }
19525
- if (!data && !error) {
19526
- throw new Error("Invalid response");
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
- if (this.requestIdToResponseMap.has(id)) {
19529
- this.requestIdToResponseMap.set(id, response);
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
- async request(data) {
19534
- if (!this.channel) {
19535
- await this.initialize();
19536
- }
19537
- if (!this.channel) {
19538
- throw new Error("Failed to create channel");
19539
- }
19540
- const { channel, requestIdToResponseMap, timeout } = this;
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
- const urlParams$1 = new URLSearchParams(window.location.search);
19580
- const rtcClientVersion = urlParams$1.get("rtc_client");
19581
- const SessionType = {
19582
- Teleop: 1,
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 getLatestTelemetry() {
19598
- const data = await fetch(
19599
- `${FORMANT_API_URL}/v1/queries/stream-current-value`,
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
- const telemetry = await data.json();
19612
- return telemetry.items;
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 getFileUrl(fileId) {
19643
- const result = await fetch(`${FORMANT_API_URL}/v1/admin/files/query`, {
19644
- method: "POST",
19645
- body: JSON.stringify({
19646
- fileIds: [fileId]
19647
- }),
19648
- headers: {
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
- const files = await result.json();
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 (rtcClient.isReady) {
19702
- while (!rtcClient.isReady()) {
19703
- await delay(100);
19704
- }
19651
+ if (!_Authentication.isShareToken) {
19652
+ userId = tokenData.sub;
19705
19653
  }
19706
- const peers = await rtcClient.getPeers();
19707
- const devicePeer = peers.find((_) => _.deviceId === this.id);
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
- });
19654
+ if (tokenData["formant:claims"] && tokenData["formant:claims"].userId) {
19655
+ userId = tokenData["formant:claims"].userId;
19793
19656
  }
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
- })
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
+ }
19813
19667
  );
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
19668
+ const data = await result.json();
19669
+ if (result.status !== 200) {
19670
+ throw new Error(data.message);
19936
19671
  }
19672
+ _Authentication.currentUser = data;
19937
19673
  }
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
- );
19674
+ _Authentication.token = token;
19675
+ _Authentication.waitingForAuth.forEach((_) => _(true));
19676
+ } catch (e) {
19677
+ console.error(e);
19678
+ _Authentication.waitingForAuth.forEach((_) => _(false));
19999
19679
  }
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);
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;
20017
19699
  }
20018
- );
20019
- });
20020
- await p.waitTilReady();
20021
- return p;
20022
- }
20023
- createCustomRequestDataChannel(channelName, timeout = 3e3) {
20024
- return new TextRequestDataChannel(this, channelName, timeout);
19700
+ }, 1e3 * 60 * 60);
19701
+ }
20025
19702
  }
20026
- createCustomBinaryRequestDataChannel(channelName, timeout = 3e3) {
20027
- return new BinaryRequestDataChannel(this, channelName, timeout);
19703
+ static isAuthenticated() {
19704
+ return _Authentication.token !== void 0;
20028
19705
  }
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);
19706
+ static getCurrentUser() {
19707
+ return _Authentication.currentUser;
20044
19708
  }
20045
- async getTelemetry(streamNameOrStreamNames, start, end, tags) {
20046
- return await Fleet.getTelemetry(
20047
- this.id,
20048
- streamNameOrStreamNames,
20049
- start,
20050
- end,
20051
- tags
20052
- );
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
+ }
20053
19719
  }
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
- }
19720
+ static async listenForRefresh() {
19721
+ App.addAccessTokenRefreshListener((token) => {
19722
+ this.loginWithToken(token);
20079
19723
  });
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;
19724
+ setInterval(async () => {
19725
+ App.refreshAuthToken();
19726
+ }, 1e3 * 60 * 60);
20084
19727
  }
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
- }
20102
- }
20103
- );
20104
- const interventionJson = await intervention.json();
20105
- return interventionJson;
19728
+ };
19729
+ let Authentication = _Authentication;
19730
+ __publicField(Authentication, "token");
19731
+ __publicField(Authentication, "refreshToken");
19732
+ __publicField(Authentication, "currentUser");
19733
+ __publicField(Authentication, "currentOrganization");
19734
+ __publicField(Authentication, "isShareToken", false);
19735
+ __publicField(Authentication, "defaultDeviceId");
19736
+ __publicField(Authentication, "waitingForAuth", []);
19737
+ function delay(ms) {
19738
+ return new Promise((resolve) => setTimeout(resolve, ms));
19739
+ }
19740
+ class DataChannel {
19741
+ constructor(dataChannel) {
19742
+ __publicField(this, "ready", false);
19743
+ __publicField(this, "listeners", []);
19744
+ __publicField(this, "openListeners", []);
19745
+ __publicField(this, "closeListeners", []);
19746
+ __publicField(this, "errorListeners", []);
19747
+ __publicField(this, "binaryListeners", []);
19748
+ __publicField(this, "error");
19749
+ __publicField(this, "decoder", new TextDecoder());
19750
+ this.dataChannel = dataChannel;
19751
+ this.dataChannel.binaryType = "arraybuffer";
19752
+ this.dataChannel.onopen = () => {
19753
+ this.ready = true;
19754
+ this.openListeners.forEach((listener) => listener());
19755
+ };
19756
+ this.dataChannel.onclose = () => {
19757
+ this.ready = false;
19758
+ this.closeListeners.forEach((listener) => listener());
19759
+ };
19760
+ this.dataChannel.onerror = (e) => {
19761
+ console.error(e);
19762
+ this.error = "An error occurred in DataChannel";
19763
+ this.errorListeners.forEach((listener) => listener(e));
19764
+ };
19765
+ this.dataChannel.onmessage = (m) => {
19766
+ this.listeners.forEach((_) => {
19767
+ const d = new Uint8Array(m.data);
19768
+ const s = this.decoder.decode(d);
19769
+ _(s);
19770
+ });
19771
+ this.binaryListeners.forEach((_) => {
19772
+ _(new Uint8Array(m.data));
19773
+ });
19774
+ };
20106
19775
  }
20107
- async addInterventionResponse(interventionId, interventionType, data) {
20108
- const response = await fetch(
20109
- `${FORMANT_API_URL}/v1/admin/intervention-responses`,
20110
- {
20111
- method: "POST",
20112
- body: JSON.stringify({
20113
- interventionId,
20114
- interventionType,
20115
- data
20116
- }),
20117
- headers: {
20118
- "Content-Type": "application/json",
20119
- Authorization: "Bearer " + Authentication.token
20120
- }
20121
- }
20122
- );
20123
- const interventionResponse = await response.json();
20124
- return interventionResponse;
19776
+ addOpenListener(listener) {
19777
+ this.openListeners.push(listener);
20125
19778
  }
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;
19779
+ removeOpenListener(listener) {
19780
+ this.openListeners = this.openListeners.filter((_) => _ !== listener);
20137
19781
  }
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
- });
19782
+ addCloseListener(listener) {
19783
+ this.closeListeners.push(listener);
20153
19784
  }
20154
- async getDeviceId() {
20155
- let result = await fetch(`${this.peerUrl}/configuration`);
20156
- const cfg = await result.json();
20157
- return cfg.agent_config.id;
19785
+ removeCloseListener(listener) {
19786
+ this.closeListeners = this.closeListeners.filter((l) => l !== listener);
20158
19787
  }
20159
- async getConfiguration() {
20160
- let result = await fetch(`${this.peerUrl}/configuration`);
20161
- const cfg = await result.json();
20162
- return cfg.agent_config.document;
19788
+ addErrorListener(listener) {
19789
+ this.errorListeners.push(listener);
20163
19790
  }
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
- }
19791
+ removeErrorListener(listener) {
19792
+ this.errorListeners = this.errorListeners.filter((l) => l !== listener);
20170
19793
  }
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`);
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);
19803
+ }
19804
+ if (this.error) {
19805
+ reject(this.error);
19806
+ }
19807
+ }, 10);
19808
+ });
19809
+ return p;
19810
+ }
19811
+ send(data) {
19812
+ if (!this.ready) {
19813
+ throw new Error("Connection has been closed");
20176
19814
  }
19815
+ this.dataChannel.send(data);
20177
19816
  }
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
- );
19817
+ sendBinary(data) {
19818
+ if (!this.ready) {
19819
+ throw new Error("Connection has been closed");
20194
19820
  }
19821
+ this.dataChannel.send(data);
20195
19822
  }
20196
- addRealtimeListener(listener) {
20197
- this.realtimeListeners.push(listener);
19823
+ addListener(listener) {
19824
+ this.listeners.push(listener);
20198
19825
  }
20199
- removeRealtimeListener(listener) {
20200
- const i = this.realtimeListeners.indexOf(listener);
19826
+ removeListener(listener) {
19827
+ const i = this.listeners.indexOf(listener);
20201
19828
  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
- }
19829
+ throw new Error("Could not find data channel listener to remove");
20223
19830
  }
20224
- for (const _ of (_c = document2.teleop.customStreams) != null ? _c : []) {
20225
- if (_.rtcStreamType === "h264-video-frame") {
20226
- streams.push({
20227
- name: _.name
20228
- });
20229
- }
19831
+ if (this.error) {
19832
+ throw new Error(this.error);
20230
19833
  }
20231
- return streams;
19834
+ this.listeners.splice(i, 1);
20232
19835
  }
20233
- async getRealtimeManipulators() {
20234
- var _a;
20235
- const document2 = await this.getConfiguration();
20236
- const manipulators = [];
20237
- for (const _ of (_a = document2.teleop.rosStreams) != null ? _a : []) {
20238
- if (_.topicType == "sensor_msgs/JointState") {
20239
- manipulators.push(
20240
- new Manipulator(this, {
20241
- currentJointStateStream: { name: _.topicName },
20242
- plannedJointStateStream: _.plannedTopic ? { name: _.plannedTopic } : void 0,
20243
- planValidStream: _.planValidTopic ? { name: _.planValidTopic } : void 0,
20244
- endEffectorStream: _.endEffectorTopic ? { name: _.endEffectorTopic } : void 0,
20245
- endEffectorLinkName: _.endEffectorLinkName,
20246
- baseReferenceFrame: _.baseReferenceFrame,
20247
- localFrame: _.localFrame
20248
- })
20249
- );
20250
- }
20251
- }
20252
- return manipulators;
19836
+ addBinaryListener(listener) {
19837
+ this.binaryListeners.push(listener);
20253
19838
  }
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
- });
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);
20265
19848
  }
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
- });
19849
+ }
19850
+ class CaptureStream {
19851
+ constructor(captureSession) {
19852
+ __publicField(this, "token");
19853
+ this.captureSession = captureSession;
20277
19854
  }
20278
- async startListeningToRealtimeDataStream(stream) {
20279
- const client = defined(
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"
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"
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
19877
+ }
20288
19878
  });
20289
19879
  }
20290
- async stopListeningToRealtimeDataStream(stream) {
20291
- const client = defined(
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"
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
+ }
20300
19891
  });
19892
+ this.device = device;
19893
+ this.config = config;
20301
19894
  }
20302
- async enableRealtimeTelemetryPriorityIngestion(streamName) {
20303
- const client = defined(
20304
- this.rtcClient,
20305
- "Realtime connection has not been started"
19895
+ async synchronize() {
19896
+ this.device.addRealtimeListener(this.onRealtimeMessage);
19897
+ this.device.startListeningToRealtimeDataStream(
19898
+ this.config.currentJointStateStream
20306
19899
  );
20307
- const devicePeer = await this.getRemotePeer();
20308
- client.controlRemoteStream(defined(devicePeer).id, {
20309
- streamName,
20310
- enablePriorityUpload: true,
20311
- pipeline: "telemetry"
20312
- });
20313
19900
  }
20314
- async disableRealtimeTelemetryPriorityIngestion(streamName) {
20315
- const client = defined(
20316
- this.rtcClient,
20317
- "Realtime connection has not been started"
19901
+ async desynchronize() {
19902
+ this.device.removeRealtimeListener(this.onRealtimeMessage);
19903
+ this.device.stopListeningToRealtimeDataStream(
19904
+ this.config.currentJointStateStream
20318
19905
  );
20319
- const devicePeer = await this.getRemotePeer();
20320
- client.controlRemoteStream(defined(devicePeer).id, {
20321
- streamName,
20322
- enablePriorityUpload: false,
20323
- pipeline: "telemetry"
20324
- });
20325
- }
20326
- async getRemotePeer() {
20327
- return {
20328
- id: this.peerUrl,
20329
- organizationId: "",
20330
- deviceId: this.id,
20331
- capabilities: [],
20332
- capabilitySet: {}
20333
- };
20334
19906
  }
20335
- async stopRealtimeConnection() {
20336
- if (this.rtcClient) {
20337
- await this.rtcClient.disconnect(this.id);
20338
- } else {
20339
- throw new Error(`Realtime connection hasn't been started for ${this.id}`);
20340
- }
19907
+ async addCurrentJointStateListener(listener) {
19908
+ this.currentListeners.push(listener);
20341
19909
  }
20342
- async createCustomDataChannel(channelName, rtcConfig) {
20343
- const client = defined(
20344
- this.rtcClient,
20345
- "Realtime connection has not been started"
20346
- );
20347
- const devicePeer = await this.getRemotePeer();
20348
- const p = await new Promise((resolve) => {
20349
- client.createCustomDataChannel(
20350
- defined(devicePeer).id,
20351
- channelName,
20352
- {
20353
- ordered: true,
20354
- ...rtcConfig
20355
- },
20356
- false,
20357
- (_peerId, channel) => {
20358
- const dataChannel = new DataChannel(channel);
20359
- resolve(dataChannel);
20360
- }
20361
- );
20362
- });
20363
- await p.waitTilReady();
20364
- return p;
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;
20365
19918
  }
20366
- createCustomRequestDataChannel(channelName, timeout = 3e3) {
20367
- return new TextRequestDataChannel(this, channelName, timeout);
19919
+ addOpenListener(listener) {
19920
+ defined(this.channel, "channel not initalized").addOpenListener(listener);
20368
19921
  }
20369
- createCustomBinaryRequestDataChannel(channelName, timeout = 3e3) {
20370
- return new BinaryRequestDataChannel(this, channelName, timeout);
19922
+ removeOpenListener(listener) {
19923
+ defined(this.channel, "channel not initalized").removeOpenListener(
19924
+ listener
19925
+ );
20371
19926
  }
20372
- }
20373
- const _Fleet$1 = class {
20374
- static async setDefaultDevice(deviceId) {
20375
- _Fleet$1.defaultDeviceId = deviceId;
19927
+ addCloseListener(listener) {
19928
+ defined(this.channel, "channel not initalized").addCloseListener(listener);
20376
19929
  }
20377
- static async getCurrentDevice() {
20378
- if (!Authentication.token) {
20379
- throw new Error("Not authenticated");
20380
- }
20381
- if (!_Fleet$1.defaultDeviceId) {
20382
- throw new Error("No known default device");
20383
- }
20384
- const data = await fetch(
20385
- `${FORMANT_API_URL}/v1/admin/device-details/query`,
20386
- {
20387
- method: "POST",
20388
- headers: {
20389
- "Content-Type": "application/json",
20390
- Authorization: "Bearer " + Authentication.token
20391
- }
20392
- }
20393
- );
20394
- const devices = await data.json();
20395
- const device = devices.items.find(
20396
- (_) => _.id === _Fleet$1.defaultDeviceId
20397
- );
20398
- const name = device.name;
20399
- const context = new Device(
20400
- _Fleet$1.defaultDeviceId,
20401
- name,
20402
- defined(Authentication.currentOrganization)
19930
+ removeCloseListener(listener) {
19931
+ defined(this.channel, "channel not initalized").removeCloseListener(
19932
+ listener
20403
19933
  );
20404
- _Fleet$1.knownContext.push(new WeakRef(context));
20405
- return context;
20406
19934
  }
20407
- static async getPeerDevice(url) {
20408
- const peer = new PeerDevice(url);
20409
- peer.id = await peer.getDeviceId();
20410
- return peer;
19935
+ addErrorListener(listener) {
19936
+ defined(this.channel, "channel not initalized").addErrorListener(listener);
20411
19937
  }
20412
- static async getDevice(deviceId) {
20413
- if (!Authentication.token) {
20414
- throw new Error("Not authenticated");
20415
- }
20416
- const data = await fetch(
20417
- `${FORMANT_API_URL}/v1/admin/devices/${deviceId}`,
20418
- {
20419
- method: "GET",
20420
- headers: {
20421
- "Content-Type": "application/json",
20422
- Authorization: "Bearer " + Authentication.token
20423
- }
20424
- }
19938
+ removeErrorListener(listener) {
19939
+ defined(this.channel, "channel not initalized").removeErrorListener(
19940
+ listener
20425
19941
  );
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
19942
  }
20432
- static async getDevices() {
20433
- if (!Authentication.token) {
20434
- throw new Error("Not authenticated");
20435
- }
20436
- const data = await fetch(
20437
- `${FORMANT_API_URL}/v1/admin/device-details/query`,
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
- }
20446
- );
20447
- const devices = await data.json();
20448
- devices.items;
20449
- return devices.items.map(
20450
- (_) => new Device(_.id, _.name, _.organizationId)
20451
- );
19943
+ }
19944
+ class BinaryRequestDataChannel extends RequestDataChannel {
19945
+ constructor() {
19946
+ super(...arguments);
19947
+ __publicField(this, "RESPONSE_SUCCESS_BYTE", 0);
19948
+ __publicField(this, "decoder", new TextDecoder());
20452
19949
  }
20453
- static async queryDevices(query) {
20454
- if (!Authentication.token) {
20455
- throw new Error("Not authenticated");
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
- const data = await fetch(`${FORMANT_API_URL}/v1/admin/devices/query`, {
20458
- method: "POST",
20459
- body: JSON.stringify(query),
20460
- headers: {
20461
- "Content-Type": "application/json",
20462
- Authorization: "Bearer " + Authentication.token
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
- static async getOnlineDevices() {
20471
- if (!Authentication.token) {
20472
- throw new Error("Not authenticated");
19974
+ async request(data) {
19975
+ if (!this.channel) {
19976
+ await this.initialize();
20473
19977
  }
20474
- const data = await fetch(`${FORMANT_API_URL}/v1/queries/online-devices`, {
20475
- method: "GET",
20476
- headers: {
20477
- "Content-Type": "application/json",
20478
- Authorization: "Bearer " + Authentication.token
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
- const devices = await data.json();
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
- static async getPeers() {
20487
- if (!Authentication.token) {
20488
- throw new Error("Not authenticated");
20489
- }
20490
- const rtcClient = new dist.exports.RtcClient({
20491
- signalingClient: new dist.exports.SignalingPromiseClient(FORMANT_API_URL, null, null),
20492
- getToken: async () => {
20493
- return defined(
20494
- Authentication.token,
20495
- "Realtime when user isn't authorized"
20496
- );
20497
- },
20498
- receive: () => {
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
- static async getRealtimeSessions() {
20504
- if (!Authentication.token) {
20505
- throw new Error("Not authenticated");
20036
+ async request(data) {
20037
+ if (!this.channel) {
20038
+ await this.initialize();
20506
20039
  }
20507
- const rtcClient = new dist.exports.RtcClient({
20508
- signalingClient: new dist.exports.SignalingPromiseClient(FORMANT_API_URL, null, null),
20509
- getToken: async () => {
20510
- return defined(
20511
- Authentication.token,
20512
- "Realtime when user isn't authorized"
20513
- );
20514
- },
20515
- receive: () => {
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
- return await rtcClient.getSessions();
20079
+ throw new Error("Text request datachannel request timed out");
20519
20080
  }
20520
- static async getRealtimeDevices() {
20521
- if (!Authentication.token) {
20522
- throw new Error("Not authenticated");
20523
- }
20524
- const data = await fetch(`${FORMANT_API_URL}/v1/signaling/peers`, {
20525
- method: "GET",
20526
- headers: {
20527
- "Content-Type": "application/json",
20528
- Authorization: "Bearer " + Authentication.token
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
- const devices = await data.json();
20532
- const onlineIds = devices.items.map(
20533
- (_) => _.deviceId
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
- static async getLatestTelemetry(deviceIdOrDeviceIds) {
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
- static async getTelemetry(deviceIdOrDeviceIds, streamNameOrStreamNames, start, end, tags) {
20560
- let deviceIds = deviceIdOrDeviceIds;
20561
- if (!Array.isArray(deviceIdOrDeviceIds)) {
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 telemetry = await data.json();
20583
- return telemetry.items;
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
- static async getFileUrl(uuid) {
20586
- const data = await fetch(`${FORMANT_API_URL}/v1/admin/files/query`, {
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: [uuid]
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 result = await data.json();
20597
- if (result.fileUrls.length === 0) {
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
- static async queryTelemetry(query) {
20603
- if (!Authentication.token) {
20604
- throw new Error("Not authenticated");
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
- static async aggregateTelemetry(query) {
20617
- if (!Authentication.token) {
20618
- throw new Error("Not authenticated");
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
- static async queryEvents(query) {
20631
- if (!Authentication.token) {
20632
- throw new Error("Not authenticated");
20633
- }
20634
- const data = await fetch(`${FORMANT_API_URL}/v1/admin/events/query`, {
20635
- method: "POST",
20636
- body: JSON.stringify(query),
20637
- headers: {
20638
- "Content-Type": "application/json",
20639
- Authorization: "Bearer " + Authentication.token
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
- return (await data.json()).items;
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
- return (await data.json()).items;
20233
+ const devicePeer = await this.getRemotePeer();
20234
+ client.send(defined(devicePeer).id, message, config);
20659
20235
  }
20660
- static async getInterventions() {
20661
- if (!Authentication.token) {
20662
- throw new Error("Not authenticated");
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
- const interventions = await fetch(
20665
- `${FORMANT_API_URL}/v1/admin/intervention-requests`,
20666
- {
20667
- method: "GET",
20668
- headers: {
20669
- "Content-Type": "application/json",
20670
- Authorization: "Bearer " + Authentication.token
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 (await interventions.json()).items;
20270
+ }
20271
+ return streams;
20675
20272
  }
20676
- static async getCurrentGroup() {
20677
- if (!Authentication.token) {
20678
- throw new Error("Not authenticated");
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
- let urlParams2 = new URLSearchParams("");
20681
- if (typeof window !== "undefined") {
20682
- urlParams2 = new URLSearchParams(window.location.search);
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 groupId = urlParams2.get("group");
20685
- if (groupId === null || groupId.trim() === "") {
20686
- return void 0;
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
- const response = await fetch(
20689
- `${FORMANT_API_URL}/v1/admin/groups/` + groupId,
20690
- {
20691
- headers: {
20692
- "Content-Type": "application/json",
20693
- Authorization: "Bearer " + Authentication.token
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 { tagKey, tagValue } = await response.json();
20698
- const devices = await this.queryDevices({
20699
- tags: { [tagKey]: [tagValue] },
20700
- enabled: true,
20701
- type: "default"
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
- static async getAnnotationCount(query) {
20706
- const tagKey = query.tagKey;
20707
- delete query.tagKey, delete query.aggregate;
20708
- const annotations = await this.queryEvents({
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 annotationCounter = validAnnotations.reduce((prev, current) => {
20716
- const value = current.tags[tagKey];
20717
- if (value in prev) {
20718
- prev[value] += 1;
20719
- return prev;
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
- let Fleet$1 = _Fleet$1;
20728
- __publicField(Fleet$1, "defaultDeviceId");
20729
- __publicField(Fleet$1, "knownContext", []);
20730
- const millisecond = 1;
20731
- const second = 1e3;
20732
- const minute = 60 * second;
20733
- const hour = 60 * minute;
20734
- const day = 24 * hour;
20735
- const week = 7 * day;
20736
- const month = 30 * day;
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
- get(key, generator) {
20777
- const cacheKey = this.keyToCacheKey(key);
20778
- const entry = this.entries.get(cacheKey);
20779
- const metadata = this.metadata.get(cacheKey);
20780
- if ((entry === void 0 || metadata && (metadata == null ? void 0 : metadata.expiration.getTime()) < Date.now()) && !(metadata == null ? void 0 : metadata.generating) && generator) {
20781
- this.generate(key, generator());
20782
- }
20783
- if (entry === void 0 && metadata && metadata.lastValue !== void 0) {
20784
- return metadata.lastValue;
20785
- }
20786
- return entry;
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
- set(key, value) {
20789
- const cacheKey = this.keyToCacheKey(key);
20790
- this.metadata.set(cacheKey, {
20791
- generating: false,
20792
- expiration: new Date(Date.now() + this.timeout),
20793
- lastValue: value
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
- clear() {
20801
- this.entries.clear();
20802
- [...this.metadata.values()].forEach((value) => value.generating = false);
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
- clearKey(key) {
20805
- this.metadata.delete(key);
20806
- this.entries.delete(key);
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
- keyToCacheKey(key) {
20809
- return JSON.stringify(key);
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
- deleteOldestEntry() {
20812
- if (this.metadata.size < 1) {
20813
- return;
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
- generate(key, promise) {
20821
- const cacheKey = this.keyToCacheKey(key);
20822
- const existingMetadata = this.metadata.get(cacheKey) || {};
20823
- this.metadata.set(cacheKey, {
20824
- ...existingMetadata,
20825
- generating: true,
20826
- expiration: new Date(Date.now() + this.timeout)
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
- class QueryStore {
20842
- constructor() {
20843
- __publicField(this, "queryStoreCache", new StoreCache({
20844
- capacity: 1e4,
20845
- timeout: 20 * duration.second
20846
- }));
20847
- __publicField(this, "liveQueryStoreCache", new StoreCache({
20848
- capacity: 1e4,
20849
- timeout: 200 * duration.millisecond
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
- moduleQuery(filter, name, type, start, end, latestOnly = false) {
20853
- const q = {
20854
- ...filter,
20855
- names: [name],
20856
- types: [type]
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
- return filterDataByType(data, type);
20863
- }
20864
- query(filter, start, end, latestOnly = false) {
20865
- const q = {
20866
- ...filter,
20867
- start: startOfMinute(start).toISOString(),
20868
- end: latestOnly ? end.toISOString() : addMinutes(roundToNearestMinutes(end), 1).toISOString(),
20869
- latestOnly
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
- data = this.queryCache(q);
20877
- }
20878
- if (!data || data === "too much data") {
20879
- return data;
20471
+ d = data;
20880
20472
  }
20881
- if (latestOnly) {
20882
- return data;
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
- return filterDataByTime(data, start, end);
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
- queryCache(query) {
20887
- return this.queryStoreCache.get(query, async () => {
20888
- try {
20889
- return await Fleet$1.queryTelemetry(query);
20890
- } catch (error) {
20891
- throw error;
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
- liveQueryCache(query) {
20896
- return this.liveQueryStoreCache.get(query, async () => {
20897
- try {
20898
- return await Fleet$1.queryTelemetry(query);
20899
- } catch (error) {
20900
- throw error;
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 queryStore = new QueryStore();
20906
- class App {
20907
- static sendAppMessage(message) {
20908
- window.parent.postMessage(message, "*");
20909
- }
20910
- static getCurrentModuleContext() {
20911
- let urlParams2 = new URLSearchParams("");
20912
- if (typeof window !== "undefined") {
20913
- urlParams2 = new URLSearchParams(window.location.search);
20914
- }
20915
- const moduleName2 = urlParams2.get("module");
20916
- return moduleName2;
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
- static async getCurrentModuleConfiguration() {
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/module-configurations/` + configurationId,
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 moduleConfiguration = await response.json();
20937
- return moduleConfiguration.configuration;
20938
- }
20939
- static isModule() {
20940
- return this.getCurrentModuleContext() !== null;
20941
- }
20942
- static goToTime(date) {
20943
- this.sendAppMessage({
20944
- type: "go_to_time",
20945
- time: date.getTime()
20946
- });
20947
- }
20948
- static goToDevice(deviceId) {
20949
- this.sendAppMessage({
20950
- type: "go_to_device",
20951
- deviceId
20952
- });
20953
- }
20954
- static showMessage(message) {
20955
- this.sendAppMessage({ type: "show_message", message });
20626
+ const interventionResponse = await response.json();
20627
+ return interventionResponse;
20956
20628
  }
20957
- static requestModuleData() {
20958
- const moduleName2 = this.getCurrentModuleContext();
20959
- if (!moduleName2) {
20960
- throw new Error("No module context");
20961
- }
20962
- this.sendAppMessage({
20963
- type: "request_module_data",
20964
- module: moduleName2
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));
20965
20638
  });
20639
+ this.peerUrl = peerUrl;
20966
20640
  }
20967
- static setModuleDateTimeRange(beforeInMilliseconds, afterInMilliseconds) {
20968
- const moduleName2 = this.getCurrentModuleContext();
20969
- if (!moduleName2) {
20970
- throw new Error("No module context");
20971
- }
20972
- this.sendAppMessage({
20973
- type: "set_module_data_time_range",
20974
- module: moduleName2,
20975
- before: beforeInMilliseconds,
20976
- after: afterInMilliseconds || 0
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;
20977
20655
  });
20978
20656
  }
20979
- static refreshAuthToken() {
20980
- const moduleName2 = this.getCurrentModuleContext();
20981
- if (!moduleName2) {
20982
- throw new Error("No module context");
20983
- }
20984
- this.sendAppMessage({
20985
- type: "refresh_auth_token",
20986
- module: moduleName2
20987
- });
20657
+ async getDeviceId() {
20658
+ let result = await fetch(`${this.peerUrl}/configuration`);
20659
+ const cfg = await result.json();
20660
+ return cfg.agent_config.id;
20988
20661
  }
20989
- static sendChannelData(channel, data) {
20990
- const moduleName2 = this.getCurrentModuleContext();
20991
- if (!moduleName2) {
20992
- throw new Error("No module context");
20993
- }
20994
- this.sendAppMessage({
20995
- type: "send_channel_data",
20996
- source: moduleName2,
20997
- channel,
20998
- data
20999
- });
20662
+ async getConfiguration() {
20663
+ let result = await fetch(`${this.peerUrl}/configuration`);
20664
+ const cfg = await result.json();
20665
+ return cfg.agent_config.document;
21000
20666
  }
21001
- static setupModuleMenus(menus) {
21002
- const moduleName2 = this.getCurrentModuleContext();
21003
- if (!moduleName2) {
21004
- throw new Error("No module context");
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`);
21005
20672
  }
21006
- this.sendAppMessage({
21007
- type: "setup_module_menus",
21008
- module: moduleName2,
21009
- menus
21010
- });
21011
- }
21012
- static addMenuListener(handler) {
21013
- window.addEventListener("message", (event) => {
21014
- const msg = event.data;
21015
- if (msg.type === "module_menu_item_clicked") {
21016
- handler(msg.menu);
21017
- }
21018
- });
21019
- }
21020
- static addAccessTokenRefreshListener(handler) {
21021
- window.addEventListener("message", (event) => {
21022
- const msg = event.data;
21023
- if (msg.type === "auth_token") {
21024
- handler(msg.token);
21025
- }
21026
- });
21027
20673
  }
21028
- static addModuleDataListener(handler) {
21029
- const moduleName2 = this.getCurrentModuleContext();
21030
- if (moduleName2) {
21031
- this.sendAppMessage({ type: "request_module_data", module: moduleName2 });
20674
+ getRealtimePing() {
20675
+ if (this.rtcClient && this.remoteDevicePeerId) {
20676
+ return this.rtcClient.getPing(this.remoteDevicePeerId);
20677
+ } else {
20678
+ throw new Error(`Realtime connection hasn't been started`);
21032
20679
  }
21033
- window.addEventListener("message", (event) => {
21034
- const msg = event.data;
21035
- if (msg.type === "module_data") {
21036
- handler({
21037
- streams: msg.streams,
21038
- time: msg.time,
21039
- queryRange: msg.queryRange
21040
- });
21041
- }
21042
- });
21043
- }
21044
- static addStreamListener(streamName, streamType, handler) {
21045
- const listener = (event) => {
21046
- const msg = event.data;
21047
- if (msg.type === "module_data") {
21048
- const { start, end } = msg.queryRange;
21049
- handler(
21050
- queryStore.moduleQuery(
21051
- {},
21052
- streamName,
21053
- streamType,
21054
- new Date(start),
21055
- new Date(end),
21056
- false
21057
- )
21058
- );
21059
- }
21060
- };
21061
- window.addEventListener("message", listener);
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
- });
21071
20680
  }
21072
- static addChannelDataListener(channel, handler) {
21073
- window.addEventListener("message", (event) => {
21074
- const msg = event.data;
21075
- if (msg.type === "channel_data" && msg.channel === channel) {
21076
- handler({
21077
- source: msg.source,
21078
- data: msg.data
21079
- });
21080
- }
21081
- });
21082
- }
21083
- static requestOverviewDevices(handler) {
21084
- this.sendAppMessage({ type: "request_devices" });
21085
- window.addEventListener("message", (event) => {
21086
- const msg = event.data;
21087
- handler(msg);
21088
- });
21089
- }
21090
- static async prompt(schema, options) {
21091
- return new Promise((resolve) => {
21092
- const promptId = Math.random().toString();
21093
- this.sendAppMessage({
21094
- type: "prompt",
21095
- promptId,
21096
- schema,
21097
- okText: options == null ? void 0 : options.okText,
21098
- cancelText: options == null ? void 0 : options.cancelText
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);
21108
- });
21109
- }
21110
- }
21111
- const _Authentication = class {
21112
- static async login(email, password) {
21113
- try {
21114
- const result = await fetch(`${FORMANT_API_URL}/v1/admin/auth/login`, {
21115
- method: "POST",
21116
- body: JSON.stringify({ email, password }),
21117
- headers: {
21118
- "Content-Type": "application/json"
21119
- }
20681
+ async startRealtimeConnection(sessionType) {
20682
+ if (!this.rtcClient) {
20683
+ const rtcClient = new dist.exports.RtcClient({
20684
+ lanOnlyMode: true,
20685
+ receive: this.handleMessage,
20686
+ sessionType
21120
20687
  });
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
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}`
21128
20696
  );
21129
- return auth.authentication;
21130
- } catch (e) {
21131
- _Authentication.waitingForAuth.forEach((_) => _(false));
21132
- _Authentication.waitingForAuth = [];
21133
- return Promise.reject(e);
21134
20697
  }
21135
20698
  }
21136
- static async loginWithToken(token, refreshToken) {
21137
- const tokenData = JSON.parse(atob(token.split(".")[1]));
21138
- try {
21139
- let userId;
21140
- _Authentication.isShareToken = tokenData["formant:claims"] && tokenData["formant:claims"].type == "share";
21141
- if (tokenData["formant:claims"]) {
21142
- _Authentication.currentOrganization = tokenData["formant:claims"].organizationId;
21143
- }
21144
- if (tokenData["custom:organization_id"]) {
21145
- _Authentication.currentOrganization = tokenData["custom:organization_id"];
20699
+ addRealtimeListener(listener) {
20700
+ this.realtimeListeners.push(listener);
20701
+ }
20702
+ removeRealtimeListener(listener) {
20703
+ const i = this.realtimeListeners.indexOf(listener);
20704
+ if (i === -1) {
20705
+ throw new Error("Could not find realtime listener to remove");
20706
+ }
20707
+ this.realtimeListeners.splice(i, 1);
20708
+ }
20709
+ async getRealtimeVideoStreams() {
20710
+ var _a, _b, _c;
20711
+ const document2 = await this.getConfiguration();
20712
+ const streams = [];
20713
+ for (const _ of (_a = document2.teleop.hardwareStreams) != null ? _a : []) {
20714
+ if (_.rtcStreamType === "h264-video-frame") {
20715
+ streams.push({
20716
+ name: _.name
20717
+ });
21146
20718
  }
21147
- if (!_Authentication.isShareToken) {
21148
- userId = tokenData.sub;
20719
+ }
20720
+ for (const _ of (_b = document2.teleop.rosStreams) != null ? _b : []) {
20721
+ if (_.topicType == "formant/H264VideoFrame") {
20722
+ streams.push({
20723
+ name: _.topicName
20724
+ });
21149
20725
  }
21150
- if (tokenData["formant:claims"] && tokenData["formant:claims"].userId) {
21151
- userId = tokenData["formant:claims"].userId;
20726
+ }
20727
+ for (const _ of (_c = document2.teleop.customStreams) != null ? _c : []) {
20728
+ if (_.rtcStreamType === "h264-video-frame") {
20729
+ streams.push({
20730
+ name: _.name
20731
+ });
21152
20732
  }
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
- }
20733
+ }
20734
+ return streams;
20735
+ }
20736
+ async getRealtimeManipulators() {
20737
+ var _a;
20738
+ const document2 = await this.getConfiguration();
20739
+ const manipulators = [];
20740
+ for (const _ of (_a = document2.teleop.rosStreams) != null ? _a : []) {
20741
+ if (_.topicType == "sensor_msgs/JointState") {
20742
+ manipulators.push(
20743
+ new Manipulator(this, {
20744
+ currentJointStateStream: { name: _.topicName },
20745
+ plannedJointStateStream: _.plannedTopic ? { name: _.plannedTopic } : void 0,
20746
+ planValidStream: _.planValidTopic ? { name: _.planValidTopic } : void 0,
20747
+ endEffectorStream: _.endEffectorTopic ? { name: _.endEffectorTopic } : void 0,
20748
+ endEffectorLinkName: _.endEffectorLinkName,
20749
+ baseReferenceFrame: _.baseReferenceFrame,
20750
+ localFrame: _.localFrame
20751
+ })
21163
20752
  );
21164
- const data = await result.json();
21165
- if (result.status !== 200) {
21166
- throw new Error(data.message);
21167
- }
21168
- _Authentication.currentUser = data;
21169
20753
  }
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
20754
  }
20755
+ return manipulators;
21198
20756
  }
21199
- static isAuthenticated() {
21200
- return _Authentication.token !== void 0;
20757
+ async startListeningToRealtimeVideo(stream) {
20758
+ const client = defined(
20759
+ this.rtcClient,
20760
+ "Realtime connection has not been started"
20761
+ );
20762
+ const devicePeer = await this.getRemotePeer();
20763
+ client.controlRemoteStream(defined(devicePeer).id, {
20764
+ streamName: stream.name,
20765
+ enable: true,
20766
+ pipeline: "rtc"
20767
+ });
21201
20768
  }
21202
- static getCurrentUser() {
21203
- return _Authentication.currentUser;
20769
+ async stopListeningToRealtimeVideo(stream) {
20770
+ const client = defined(
20771
+ this.rtcClient,
20772
+ "Realtime connection has not been started"
20773
+ );
20774
+ const devicePeer = await this.getRemotePeer();
20775
+ client.controlRemoteStream(defined(devicePeer).id, {
20776
+ streamName: stream.name,
20777
+ enable: false,
20778
+ pipeline: "rtc"
20779
+ });
21204
20780
  }
21205
- static async waitTilAuthenticated() {
21206
- if (_Authentication.token !== void 0) {
21207
- return true;
20781
+ async startListeningToRealtimeDataStream(stream) {
20782
+ const client = defined(
20783
+ this.rtcClient,
20784
+ "Realtime connection has not been started"
20785
+ );
20786
+ const devicePeer = await this.getRemotePeer();
20787
+ client.controlRemoteStream(defined(devicePeer).id, {
20788
+ streamName: stream.name,
20789
+ enable: true,
20790
+ pipeline: "rtc"
20791
+ });
20792
+ }
20793
+ async stopListeningToRealtimeDataStream(stream) {
20794
+ const client = defined(
20795
+ this.rtcClient,
20796
+ "Realtime connection has not been started"
20797
+ );
20798
+ const devicePeer = await this.getRemotePeer();
20799
+ client.controlRemoteStream(defined(devicePeer).id, {
20800
+ streamName: stream.name,
20801
+ enable: false,
20802
+ pipeline: "rtc"
20803
+ });
20804
+ }
20805
+ async enableRealtimeTelemetryPriorityIngestion(streamName) {
20806
+ const client = defined(
20807
+ this.rtcClient,
20808
+ "Realtime connection has not been started"
20809
+ );
20810
+ const devicePeer = await this.getRemotePeer();
20811
+ client.controlRemoteStream(defined(devicePeer).id, {
20812
+ streamName,
20813
+ enablePriorityUpload: true,
20814
+ pipeline: "telemetry"
20815
+ });
20816
+ }
20817
+ async disableRealtimeTelemetryPriorityIngestion(streamName) {
20818
+ const client = defined(
20819
+ this.rtcClient,
20820
+ "Realtime connection has not been started"
20821
+ );
20822
+ const devicePeer = await this.getRemotePeer();
20823
+ client.controlRemoteStream(defined(devicePeer).id, {
20824
+ streamName,
20825
+ enablePriorityUpload: false,
20826
+ pipeline: "telemetry"
20827
+ });
20828
+ }
20829
+ async getRemotePeer() {
20830
+ return {
20831
+ id: this.peerUrl,
20832
+ organizationId: "",
20833
+ deviceId: this.id,
20834
+ capabilities: [],
20835
+ capabilitySet: {}
20836
+ };
20837
+ }
20838
+ async stopRealtimeConnection() {
20839
+ if (this.rtcClient) {
20840
+ await this.rtcClient.disconnect(this.id);
21208
20841
  } else {
21209
- return new Promise((resolve) => {
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
- static async listenForRefresh() {
21217
- App.addAccessTokenRefreshListener((token) => {
21218
- this.loginWithToken(token);
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
- setInterval(async () => {
21221
- App.refreshAuthToken();
21222
- }, 1e3 * 60 * 60);
20866
+ await p.waitTilReady();
20867
+ return p;
21223
20868
  }
21224
- };
21225
- let Authentication = _Authentication;
21226
- __publicField(Authentication, "token");
21227
- __publicField(Authentication, "refreshToken");
21228
- __publicField(Authentication, "currentUser");
21229
- __publicField(Authentication, "currentOrganization");
21230
- __publicField(Authentication, "isShareToken", false);
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;