@luxonis/visualizer-protobuf 2.0.2 → 2.2.0

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.
Files changed (60) hide show
  1. package/dist/apps/depthai-visualizer/src/components/Panel.d.ts.map +1 -1
  2. package/dist/apps/depthai-visualizer/src/components/Panel.js +13 -4
  3. package/dist/apps/depthai-visualizer/src/components/Panel.js.map +1 -1
  4. package/dist/apps/depthai-visualizer/src/components/PanelToolbar.d.ts.map +1 -1
  5. package/dist/apps/depthai-visualizer/src/components/PanelToolbar.js +3 -2
  6. package/dist/apps/depthai-visualizer/src/components/PanelToolbar.js.map +1 -1
  7. package/dist/apps/depthai-visualizer/src/connection/adapter.d.ts +6 -0
  8. package/dist/apps/depthai-visualizer/src/connection/adapter.d.ts.map +1 -1
  9. package/dist/apps/depthai-visualizer/src/connection/adapter.js +6 -0
  10. package/dist/apps/depthai-visualizer/src/connection/adapter.js.map +1 -1
  11. package/dist/apps/depthai-visualizer/src/connection/communicator.d.ts +12 -2
  12. package/dist/apps/depthai-visualizer/src/connection/communicator.d.ts.map +1 -1
  13. package/dist/apps/depthai-visualizer/src/connection/communicator.js +14 -22
  14. package/dist/apps/depthai-visualizer/src/connection/communicator.js.map +1 -1
  15. package/dist/apps/depthai-visualizer/src/connection/connection.d.ts +6 -0
  16. package/dist/apps/depthai-visualizer/src/connection/connection.d.ts.map +1 -1
  17. package/dist/apps/depthai-visualizer/src/connection/connection.js +7 -1
  18. package/dist/apps/depthai-visualizer/src/connection/connection.js.map +1 -1
  19. package/dist/apps/depthai-visualizer/src/connection/webrtc/bridge.d.ts.map +1 -1
  20. package/dist/apps/depthai-visualizer/src/connection/webrtc/bridge.js +90 -40
  21. package/dist/apps/depthai-visualizer/src/connection/webrtc/bridge.js.map +1 -1
  22. package/dist/apps/depthai-visualizer/src/connection/webrtc/worker-utils.d.ts +38 -3
  23. package/dist/apps/depthai-visualizer/src/connection/webrtc/worker-utils.d.ts.map +1 -1
  24. package/dist/apps/depthai-visualizer/src/connection/webrtc/worker-utils.js +54 -8
  25. package/dist/apps/depthai-visualizer/src/connection/webrtc/worker-utils.js.map +1 -1
  26. package/dist/apps/depthai-visualizer/src/connection/webrtc/worker.js +15 -0
  27. package/dist/apps/depthai-visualizer/src/connection/webrtc/worker.js.map +1 -1
  28. package/dist/apps/depthai-visualizer/src/connection/ws/worker-utils.d.ts +2 -1
  29. package/dist/apps/depthai-visualizer/src/connection/ws/worker-utils.d.ts.map +1 -1
  30. package/dist/apps/depthai-visualizer/src/connection/ws/worker-utils.js +28 -3
  31. package/dist/apps/depthai-visualizer/src/connection/ws/worker-utils.js.map +1 -1
  32. package/dist/apps/depthai-visualizer/src/utils/artificial-worker.d.ts +3 -0
  33. package/dist/apps/depthai-visualizer/src/utils/artificial-worker.d.ts.map +1 -1
  34. package/dist/apps/depthai-visualizer/src/utils/artificial-worker.js +10 -0
  35. package/dist/apps/depthai-visualizer/src/utils/artificial-worker.js.map +1 -1
  36. package/dist/{communicator-ZAqNuwq6.js → communicator-DKKKAI0H.js} +19 -29
  37. package/dist/{index-WSNQlHZC.js → index-1yvlF6NH.js} +3 -3
  38. package/dist/{index-B68UDyAv.js → index-B3F-eA-i.js} +255 -78
  39. package/dist/{index-B7v9Ptl2.js → index-B4j3EVf8.js} +3 -3
  40. package/dist/{index-uD6dIRaN.js → index-BZjzIIuE.js} +3 -3
  41. package/dist/{index-SWsY2eOm.js → index-BsdqQ862.js} +3 -3
  42. package/dist/{index-CsJJiZos.js → index-C6m30paN.js} +3 -3
  43. package/dist/{index-D502DL2z.js → index-CE1LH59a.js} +3 -3
  44. package/dist/{index-qrTNSyOQ.js → index-Cmp_Tjng.js} +4 -4
  45. package/dist/{index-CX_Do7kl.js → index-Cqzhj8jS.js} +3 -3
  46. package/dist/{index-C04gVVoP.js → index-D0g7yNKD.js} +3 -3
  47. package/dist/{index-CXwbrQKL.js → index-D7I7neMi.js} +3 -3
  48. package/dist/{index-CsyZMo6w.js → index-D_AhdZqi.js} +3 -3
  49. package/dist/{index-Ddm491YR.js → index-Dai0K-_7.js} +3 -3
  50. package/dist/{index-ByP7YJPY.js → index-DbIgJEn4.js} +3 -3
  51. package/dist/{index-T_ckFaRN.js → index-DkDTcHOl.js} +3 -3
  52. package/dist/{index-By6lF-Xz.js → index-DleEaqya.js} +3 -3
  53. package/dist/{index-BHmiJ5Qk.js → index-FdS8KlrP.js} +3 -3
  54. package/dist/{index-9D6nsmX0.js → index-MOg_zBJW.js} +3 -3
  55. package/dist/{index-CLESgVaD.js → index-SZgAiOi4.js} +3 -3
  56. package/dist/index.js +3 -3
  57. package/dist/{worker-ByVSTHSI.js → worker-CMZIJlQN.js} +66 -9
  58. package/dist/{worker-DlZ2xp8p.js → worker-DtDgSl3T.js} +2 -2
  59. package/dist/{worker-utils-BNThsbdN.js → worker-utils-BuUq1bP1.js} +29 -4
  60. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
- import { c as commonjsGlobal, g as getAugmentedNamespace, a as getDefaultExportFromCjs } from './worker-utils-BNThsbdN.js';
2
- import { T as Type$1, P as PointsAnnotationType$2, a as Profile, p as protobufsBySchema } from './communicator-ZAqNuwq6.js';
1
+ import { c as commonjsGlobal, g as getAugmentedNamespace, a as getDefaultExportFromCjs } from './worker-utils-BuUq1bP1.js';
2
+ import { T as Type$1, P as PointsAnnotationType$2, a as Profile, p as protobufsBySchema } from './communicator-DKKKAI0H.js';
3
3
  import * as React$1 from 'react';
4
4
  import React__default, { useContext, useRef, useLayoutEffect, createContext, useReducer, useState, useCallback, useMemo, forwardRef, createElement, Component, useEffect, useImperativeHandle, Fragment as Fragment$1, Suspense } from 'react';
5
5
  import { createStore, useStore } from 'zustand';
@@ -219,6 +219,22 @@ class FoxgloveWebSocketAdapter extends EventTarget {
219
219
  this.dispatchEvent(new Event("close"));
220
220
  }
221
221
  }
222
+ subscribe({
223
+ topics
224
+ }) {
225
+ this.#sendToWorker({
226
+ type: 'subscribe',
227
+ data: topics
228
+ });
229
+ }
230
+ unsubscribe({
231
+ topics
232
+ }) {
233
+ this.#sendToWorker({
234
+ type: 'unsubscribe',
235
+ data: topics
236
+ });
237
+ }
222
238
  async request({
223
239
  name,
224
240
  timeout = REQUEST_RESPONSE_TIMEOUT,
@@ -11859,22 +11875,74 @@ class EventEmitter {
11859
11875
  }
11860
11876
  }
11861
11877
 
11878
+ function makeChunks(data, chunkSize = 16 * 1024) {
11879
+ const chunks = [];
11880
+ const payloadSize = chunkSize - 4 - 4;
11881
+ const totalChunks = Math.ceil(data.byteLength / payloadSize);
11882
+ for (let i = 0; i < totalChunks; ++i) {
11883
+ const array = new Uint8Array(chunkSize);
11884
+ const view = new DataView(array.buffer);
11885
+ view.setInt32(0, totalChunks);
11886
+ view.setInt32(4, i);
11887
+ const sourceChunkLength = Math.min(payloadSize, data.byteLength - i * payloadSize);
11888
+ array.set(new Uint8Array(data.buffer, i * payloadSize, sourceChunkLength));
11889
+ chunks.push(view);
11890
+ }
11891
+ return chunks;
11892
+ }
11862
11893
  class WebRtcDataChannel {
11863
11894
  channel;
11895
+ withFragmentation;
11864
11896
  events = new EventEmitter();
11865
11897
  oldMessages = [];
11866
- constructor(channel) {
11898
+ buffer = new Uint8Array(0);
11899
+ constructor(channel, withFragmentation = false) {
11867
11900
  this.channel = channel;
11868
- this.channel.onerror = event => this.events.emit('error', [event]);
11869
- this.channel.onmessage = event => this.events.emit('message', [event]);
11870
- this.channel.onclose = event => this.events.emit('close', [event]);
11871
- this.channel.onopen = event => {
11901
+ this.withFragmentation = withFragmentation;
11902
+ this.channel.addEventListener('error', event => this.events.emit('error', [event]));
11903
+ this.channel.addEventListener('message', async (event) => {
11904
+ if (channel.label === 'ping-pong') {
11905
+ this.sendMessage('pong');
11906
+ }
11907
+ if (!this.withFragmentation) {
11908
+ this.events.emit('message', [event]);
11909
+ return;
11910
+ }
11911
+ const buffer = event.data instanceof ArrayBuffer ? event.data : await event.data.arrayBuffer();
11912
+ const view = new DataView(buffer);
11913
+ const totalChunks = view.getUint32(0);
11914
+ const chunkIndex = view.getUint32(4);
11915
+ const data = new Uint8Array(buffer, 8).slice(0);
11916
+ if (totalChunks !== 1) {
11917
+ this.appendChunk(data);
11918
+ if (totalChunks - 1 !== chunkIndex) {
11919
+ return;
11920
+ }
11921
+ }
11922
+ const completeData = totalChunks === 1 ? data : this.buffer;
11923
+ this.events.emit('message', [
11924
+ new MessageEvent('message', {
11925
+ data: completeData.buffer,
11926
+ }),
11927
+ ]);
11928
+ if (totalChunks !== 1) {
11929
+ this.buffer = new Uint8Array(0);
11930
+ }
11931
+ });
11932
+ this.channel.addEventListener('close', event => this.events.emit('close', [event]));
11933
+ this.channel.addEventListener('open', event => {
11872
11934
  this.events.emit('open', [event]);
11873
11935
  for (const message of this.oldMessages) {
11874
11936
  this.sendMessage(message);
11875
11937
  }
11876
11938
  this.oldMessages = [];
11877
- };
11939
+ });
11940
+ }
11941
+ appendChunk(bytes) {
11942
+ const newBuffer = new Uint8Array(this.buffer.byteLength + bytes.byteLength);
11943
+ newBuffer.set(this.buffer, 0);
11944
+ newBuffer.set(bytes, this.buffer.byteLength);
11945
+ this.buffer = newBuffer;
11878
11946
  }
11879
11947
  get raw() {
11880
11948
  return this.channel;
@@ -11884,24 +11952,50 @@ class WebRtcDataChannel {
11884
11952
  }
11885
11953
  sendMessage(message) {
11886
11954
  if (this.channel.readyState === 'open') {
11887
- this.channel.send(message);
11955
+ const chunks = message instanceof DataView && this.withFragmentation ? makeChunks(message) : [message];
11956
+ for (const chunk of chunks) {
11957
+ this.channel.send(chunk);
11958
+ }
11888
11959
  }
11889
11960
  else {
11890
11961
  this.oldMessages.push(message);
11891
11962
  }
11892
11963
  }
11893
11964
  /**
11965
+ * @deprecated Use `on` with `decode: true`
11966
+ *
11894
11967
  * This method does **not** filter messages. Use this method instead of {@link on}
11895
11968
  * **only** if you are sure that all messages sent over this channel will contain text.
11896
11969
  */
11897
11970
  onTextMessage(callback) {
11898
11971
  return this.events.on('message', async (event) => {
11899
- const buffer = await event.data.arrayBuffer();
11972
+ const buffer = event.data instanceof ArrayBuffer ? event.data : await event.data.arrayBuffer();
11900
11973
  const message = new TextDecoder('utf-8').decode(buffer);
11901
11974
  callback(message);
11902
11975
  });
11903
11976
  }
11904
- on = this.events.on.bind(this.events);
11977
+ on(event, callback) {
11978
+ const specificMessageEvents = ['message:binary', 'message:string', 'message:json'];
11979
+ if (!specificMessageEvents.includes(event)) {
11980
+ return this.events.on(event, callback);
11981
+ }
11982
+ return this.events.on('message', async (rawEvent) => {
11983
+ const buffer = rawEvent.data instanceof ArrayBuffer ? rawEvent.data : await rawEvent.data.arrayBuffer();
11984
+ if (event === 'message:binary') {
11985
+ const view = new DataView(buffer);
11986
+ callback(view);
11987
+ }
11988
+ else {
11989
+ const message = new TextDecoder('utf-8').decode(buffer);
11990
+ if (event === 'message:string') {
11991
+ callback(message);
11992
+ }
11993
+ else if (event === 'message:json') {
11994
+ callback(JSON.parse(message));
11995
+ }
11996
+ }
11997
+ });
11998
+ }
11905
11999
  }
11906
12000
 
11907
12001
  class WebRtcConnection {
@@ -11911,13 +12005,13 @@ class WebRtcConnection {
11911
12005
  events = new EventEmitter();
11912
12006
  onIceCandidate;
11913
12007
  onConnectionEstablished;
11914
- constructor(props) {
11915
- this.iceServers = props.iceServers;
11916
- this.onIceCandidate = props.onCandidate;
11917
- this.onConnectionEstablished = props.onConnectionEstablished;
11918
- this.#peerConnection = this.createPeerConnection();
12008
+ constructor(args) {
12009
+ this.iceServers = args.iceServers;
12010
+ this.onIceCandidate = args.onCandidate;
12011
+ this.onConnectionEstablished = args.onConnectionEstablished;
12012
+ this.#peerConnection = this.createPeerConnection(args.withFragmentation);
11919
12013
  }
11920
- createPeerConnection() {
12014
+ createPeerConnection(withFragmentation = false) {
11921
12015
  const config = {
11922
12016
  iceServers: this.iceServers ?? [],
11923
12017
  };
@@ -11945,13 +12039,10 @@ class WebRtcConnection {
11945
12039
  this.onIceCandidate(event.candidate);
11946
12040
  }
11947
12041
  };
11948
- connection.ondatachannel = event => {
11949
- const channel = new WebRtcDataChannel(event.channel);
11950
- if (channel.label === 'ping-pong') {
11951
- channel.on('message', () => channel.sendMessage('pong'));
11952
- }
12042
+ connection.addEventListener('datachannel', event => {
12043
+ const channel = new WebRtcDataChannel(event.channel, event.channel.label !== 'ping-pong' && withFragmentation);
11953
12044
  this.events.emit('data_channel', [channel]);
11954
- };
12045
+ });
11955
12046
  return connection;
11956
12047
  }
11957
12048
  get peerConnection() {
@@ -11959,7 +12050,7 @@ class WebRtcConnection {
11959
12050
  }
11960
12051
  createDataChannel(label, options) {
11961
12052
  const channel = this.#peerConnection.createDataChannel(label, options);
11962
- return new WebRtcDataChannel(channel);
12053
+ return new WebRtcDataChannel(channel, options?.withFragmentation);
11963
12054
  }
11964
12055
  setRemoteDescription(type, sdp) {
11965
12056
  return this.#peerConnection.setRemoteDescription({ type, sdp });
@@ -12087,9 +12178,9 @@ class WebRtcClient {
12087
12178
  // console.debug('[WebRTC] Offer accepted. Setting remote description..');
12088
12179
  await this.connection.setRemoteDescription(kind, candidate);
12089
12180
  // console.debug('[WebRTC] Set remote description');
12090
- for (const candidate of this.iceCandidates) {
12181
+ for (const iceCandidate of this.iceCandidates) {
12091
12182
  // console.debug('[WebRTC] Adding stored ICE candidate');
12092
- this.connection.addIceCandidate(JSON.parse(candidate));
12183
+ void this.connection.addIceCandidate(JSON.parse(iceCandidate));
12093
12184
  }
12094
12185
  this.iceCandidates = [];
12095
12186
  if (kind === 'offer') {
@@ -12139,6 +12230,7 @@ class WebRtcClient {
12139
12230
  });
12140
12231
  },
12141
12232
  onConnectionEstablished: () => this.disconnectSignalingServer('P2P connection established'),
12233
+ withFragmentation: this.config.withFragmentation,
12142
12234
  });
12143
12235
  this.events.emit('connection_established', [this.connection]);
12144
12236
  }
@@ -12154,14 +12246,29 @@ class WebRtcClient {
12154
12246
  // file, You can obtain one at http://mozilla.org/MPL/2.0/
12155
12247
 
12156
12248
  class ArtificialWorker extends EventTarget {
12249
+ #selfTarget = new EventTarget();
12250
+
12157
12251
  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
12158
12252
  postMessage(data, _transferable) {
12253
+ const event = new MessageEvent('message', {
12254
+ data
12255
+ });
12256
+ this.#selfTarget.dispatchEvent(event);
12257
+ }
12258
+
12259
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
12260
+ selfPostMessage(data, _transferable) {
12159
12261
  const event = new MessageEvent('message', {
12160
12262
  data
12161
12263
  });
12162
12264
  super.dispatchEvent(event);
12163
12265
  }
12164
12266
 
12267
+ // @ts-expect-error Make it typed
12268
+ selfAddEventListener(type, callback) {
12269
+ this.#selfTarget.addEventListener(type, callback);
12270
+ }
12271
+
12165
12272
  // @ts-expect-error Make it typed
12166
12273
  addEventListener(type, callback) {
12167
12274
  super.addEventListener(type, callback);
@@ -12182,7 +12289,7 @@ class WebRtcBridge extends ArtificialWorker {
12182
12289
  #systemChannel = null;
12183
12290
  constructor() {
12184
12291
  super();
12185
- this.#worker = new Worker(new URL("worker-ByVSTHSI.js", import.meta.url), {
12292
+ this.#worker = new Worker(new URL("worker-CMZIJlQN.js", import.meta.url), {
12186
12293
  type: "module"
12187
12294
  });
12188
12295
  this.#setupArtificialWorker();
@@ -12191,15 +12298,57 @@ class WebRtcBridge extends ArtificialWorker {
12191
12298
  this.#worker.terminate();
12192
12299
  }
12193
12300
  #setupArtificialWorker() {
12194
- this.addEventListener('message', event => {
12301
+ this.selfAddEventListener("message", event => {
12195
12302
  switch (event.data.type) {
12196
- case 'open':
12303
+ case "open":
12197
12304
  {
12198
- if ('config' in event.data.data) {
12199
- this.#createWebRtc(event.data.data.config);
12305
+ if ("config" in event.data.data) {
12306
+ this.#createWebRtc({
12307
+ withFragmentation: true,
12308
+ ...event.data.data.config
12309
+ });
12200
12310
  }
12201
12311
  break;
12202
12312
  }
12313
+ case "close":
12314
+ {
12315
+ this.#webrtc?.dispose("Client requested connection close");
12316
+ this.terminate();
12317
+ break;
12318
+ }
12319
+ case "send":
12320
+ {
12321
+ this.#worker.postMessage({
12322
+ kind: "rawSend",
12323
+ data: {
12324
+ message: event.data.data
12325
+ }
12326
+ });
12327
+ break;
12328
+ }
12329
+ case "call_service":
12330
+ {
12331
+ this.#worker.postMessage({
12332
+ kind: "serviceCall",
12333
+ data: {
12334
+ message: event.data.data
12335
+ }
12336
+ });
12337
+ break;
12338
+ }
12339
+ case "unsubscribe":
12340
+ case "subscribe":
12341
+ {
12342
+ this.#worker.postMessage({
12343
+ kind: event.data.type,
12344
+ data: {
12345
+ message: {
12346
+ topics: event.data.data
12347
+ }
12348
+ }
12349
+ });
12350
+ break;
12351
+ }
12203
12352
  }
12204
12353
  });
12205
12354
  }
@@ -12209,30 +12358,32 @@ class WebRtcBridge extends ArtificialWorker {
12209
12358
  this.#handleMessages();
12210
12359
  }
12211
12360
  #handleWebRtc(client) {
12361
+ client.on("error", error => console.error("WebRtc Client Failed", error));
12212
12362
  client.on("connection_established", connection => {
12213
12363
  connection.on("data_channel", channel => {
12214
- channel.on('close', () => {
12364
+ channel.on("close", () => {
12215
12365
  if (channel.label !== MESSAGE_CHANNEL_NAME && channel.label !== SYSTEM_CHANNEL_NAME) {
12216
12366
  return;
12217
12367
  }
12218
12368
  this.#worker.postMessage({
12219
12369
  kind: "connection",
12220
12370
  data: {
12221
- channel: channel.label === MESSAGE_CHANNEL_NAME ? 'message' : 'system',
12371
+ channel: channel.label === MESSAGE_CHANNEL_NAME ? "message" : "system",
12222
12372
  ready: false
12223
12373
  }
12224
12374
  });
12375
+ this.selfPostMessage({
12376
+ type: "close"
12377
+ });
12225
12378
  });
12226
12379
  if (channel.label === MESSAGE_CHANNEL_NAME) {
12227
12380
  this.#messageChannel = channel;
12228
- channel.on("message", async ({
12229
- data
12230
- }) => {
12231
- const operation = data.getUint8(0);
12232
- const action = operation === 0x01 ? 'message' : operation === 0x03 ? 'service_response' : 'other';
12233
- if (action === 'message') {
12234
- const subscriptionId = data.getUint32(1);
12235
- const payload = new DataView(data.buffer, data.byteOffset + 1 + 4 + 8);
12381
+ channel.on("message:binary", async view => {
12382
+ const operation = view.getUint8(0);
12383
+ const action = operation === 0x01 ? "message" : operation === 0x03 ? "service_response" : "other";
12384
+ if (action === "message") {
12385
+ const subscriptionId = view.getUint32(1);
12386
+ const payload = new DataView(view.buffer, view.byteOffset + 1 + 4 + 8);
12236
12387
  this.#worker.postMessage({
12237
12388
  kind: "genericMessage",
12238
12389
  data: {
@@ -12243,14 +12394,14 @@ class WebRtcBridge extends ArtificialWorker {
12243
12394
  }
12244
12395
  }, [payload.buffer]);
12245
12396
  } else {
12246
- const callId = data.getUint32(1 + 4); // op-code + service-id
12247
- const encodingLength = data.getUint32(1 + 4 + 4); // op-code + service-id + call-id
12248
- const payload = new DataView(data.buffer, data.byteOffset + 1 + 4 + 4 + 4 + encodingLength); // op-code + service-id + call-id + encoding-length
12397
+ const callId = view.getUint32(1 + 4); // op-code + service-id
12398
+ const encodingLength = view.getUint32(1 + 4 + 4); // op-code + service-id + call-id
12399
+ const payload = new DataView(view.buffer, view.byteOffset + 1 + 4 + 4 + 4 + encodingLength); // op-code + service-id + call-id + encoding-length
12249
12400
  this.#worker.postMessage({
12250
12401
  kind: "systemMessage",
12251
12402
  data: {
12252
12403
  message: {
12253
- op: 'serviceResponse',
12404
+ op: "serviceResponse",
12254
12405
  callId,
12255
12406
  data: payload
12256
12407
  }
@@ -12260,12 +12411,11 @@ class WebRtcBridge extends ArtificialWorker {
12260
12411
  });
12261
12412
  } else if (channel.label === SYSTEM_CHANNEL_NAME) {
12262
12413
  this.#systemChannel = channel;
12263
- channel.on("message", async event => {
12264
- const message = JSON.parse(event.data);
12414
+ channel.on("message:json", async data => {
12265
12415
  this.#worker.postMessage({
12266
12416
  kind: "systemMessage",
12267
12417
  data: {
12268
- message
12418
+ message: data
12269
12419
  }
12270
12420
  });
12271
12421
  });
@@ -12273,10 +12423,15 @@ class WebRtcBridge extends ArtificialWorker {
12273
12423
  this.#worker.postMessage({
12274
12424
  kind: "connection",
12275
12425
  data: {
12276
- channel: channel.label === MESSAGE_CHANNEL_NAME ? 'message' : 'system',
12426
+ channel: channel.label === MESSAGE_CHANNEL_NAME ? "message" : "system",
12277
12427
  ready: true
12278
12428
  }
12279
12429
  });
12430
+ if (this.#systemChannel?.raw.readyState === "open" && this.#messageChannel?.raw.readyState === "open") {
12431
+ this.selfPostMessage({
12432
+ type: "open"
12433
+ });
12434
+ }
12280
12435
  });
12281
12436
  connection.on("connection_closed", () => {
12282
12437
  this.#worker.postMessage({
@@ -12286,15 +12441,18 @@ class WebRtcBridge extends ArtificialWorker {
12286
12441
  ready: false
12287
12442
  }
12288
12443
  });
12444
+ this.selfPostMessage({
12445
+ type: "close"
12446
+ });
12289
12447
  });
12290
12448
  });
12291
12449
  }
12292
12450
  #handleMessages() {
12293
- this.#worker.addEventListener('message', event => {
12451
+ this.#worker.addEventListener("message", event => {
12294
12452
  switch (event.data.type) {
12295
- case 'send':
12453
+ case "send":
12296
12454
  {
12297
- const channel = event.data.data.channel === 'message' ? this.#messageChannel : this.#systemChannel;
12455
+ const channel = event.data.data.channel === "message" ? this.#messageChannel : this.#systemChannel;
12298
12456
  if (channel) {
12299
12457
  channel.sendMessage(event.data.data.data);
12300
12458
  }
@@ -12302,7 +12460,7 @@ class WebRtcBridge extends ArtificialWorker {
12302
12460
  }
12303
12461
  default:
12304
12462
  {
12305
- this.postMessage(event.data);
12463
+ this.selfPostMessage(event.data);
12306
12464
  }
12307
12465
  }
12308
12466
  });
@@ -12326,12 +12484,12 @@ class VisualizerConnection extends FoxgloveConnection {
12326
12484
  let finalWorker = worker;
12327
12485
  if (type === 'ws') {
12328
12486
  this.#url = data.connectionUrl;
12329
- finalWorker ??= new Worker(new URL("worker-DlZ2xp8p.js", import.meta.url), {
12487
+ finalWorker ??= new Worker(new URL("worker-DtDgSl3T.js", import.meta.url), {
12330
12488
  type: "module"
12331
12489
  });
12332
12490
  } else {
12333
12491
  this.#config = data.config;
12334
- finalWorker ??= new WebRtcBridge();
12492
+ finalWorker = new WebRtcBridge();
12335
12493
  }
12336
12494
  this.#open(finalWorker);
12337
12495
  }
@@ -12348,6 +12506,12 @@ class VisualizerConnection extends FoxgloveConnection {
12348
12506
  const response = await this.#adapter?.request(args);
12349
12507
  return response ?? null;
12350
12508
  }
12509
+ subscribe(args) {
12510
+ this.#adapter?.subscribe(args);
12511
+ }
12512
+ unsubscribe(args) {
12513
+ this.#adapter?.unsubscribe(args);
12514
+ }
12351
12515
 
12352
12516
  // eslint-disable-next-line no-restricted-syntax
12353
12517
  get connected() {
@@ -89511,7 +89675,7 @@ function legacy(parser) {
89511
89675
  return new LanguageSupport(StreamLanguage.define(parser));
89512
89676
  }
89513
89677
  function sql$1(dialectName) {
89514
- return import('./index-CsyZMo6w.js').then(m => m.sql({ dialect: m[dialectName] }));
89678
+ return import('./index-D_AhdZqi.js').then(m => m.sql({ dialect: m[dialectName] }));
89515
89679
  }
89516
89680
  /**
89517
89681
  An array of language descriptions for known language packages.
@@ -89522,7 +89686,7 @@ const languages = [
89522
89686
  name: "C",
89523
89687
  extensions: ["c", "h", "ino"],
89524
89688
  load() {
89525
- return import('./index-T_ckFaRN.js').then(m => m.cpp());
89689
+ return import('./index-DkDTcHOl.js').then(m => m.cpp());
89526
89690
  }
89527
89691
  }),
89528
89692
  /*@__PURE__*/LanguageDescription.of({
@@ -89530,7 +89694,7 @@ const languages = [
89530
89694
  alias: ["cpp"],
89531
89695
  extensions: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"],
89532
89696
  load() {
89533
- return import('./index-T_ckFaRN.js').then(m => m.cpp());
89697
+ return import('./index-DkDTcHOl.js').then(m => m.cpp());
89534
89698
  }
89535
89699
  }),
89536
89700
  /*@__PURE__*/LanguageDescription.of({
@@ -89550,7 +89714,7 @@ const languages = [
89550
89714
  name: "Go",
89551
89715
  extensions: ["go"],
89552
89716
  load() {
89553
- return import('./index-B7v9Ptl2.js').then(m => m.go());
89717
+ return import('./index-B4j3EVf8.js').then(m => m.go());
89554
89718
  }
89555
89719
  }),
89556
89720
  /*@__PURE__*/LanguageDescription.of({
@@ -89565,7 +89729,7 @@ const languages = [
89565
89729
  name: "Java",
89566
89730
  extensions: ["java"],
89567
89731
  load() {
89568
- return import('./index-WSNQlHZC.js').then(m => m.java());
89732
+ return import('./index-1yvlF6NH.js').then(m => m.java());
89569
89733
  }
89570
89734
  }),
89571
89735
  /*@__PURE__*/LanguageDescription.of({
@@ -89581,7 +89745,7 @@ const languages = [
89581
89745
  alias: ["json5"],
89582
89746
  extensions: ["json", "map"],
89583
89747
  load() {
89584
- return import('./index-BHmiJ5Qk.js').then(m => m.json());
89748
+ return import('./index-FdS8KlrP.js').then(m => m.json());
89585
89749
  }
89586
89750
  }),
89587
89751
  /*@__PURE__*/LanguageDescription.of({
@@ -89595,14 +89759,14 @@ const languages = [
89595
89759
  name: "LESS",
89596
89760
  extensions: ["less"],
89597
89761
  load() {
89598
- return import('./index-9D6nsmX0.js').then(m => m.less());
89762
+ return import('./index-MOg_zBJW.js').then(m => m.less());
89599
89763
  }
89600
89764
  }),
89601
89765
  /*@__PURE__*/LanguageDescription.of({
89602
89766
  name: "Liquid",
89603
89767
  extensions: ["liquid"],
89604
89768
  load() {
89605
- return import('./index-SWsY2eOm.js').then(m => m.liquid());
89769
+ return import('./index-BsdqQ862.js').then(m => m.liquid());
89606
89770
  }
89607
89771
  }),
89608
89772
  /*@__PURE__*/LanguageDescription.of({
@@ -89628,7 +89792,7 @@ const languages = [
89628
89792
  name: "PHP",
89629
89793
  extensions: ["php", "php3", "php4", "php5", "php7", "phtml"],
89630
89794
  load() {
89631
- return import('./index-D502DL2z.js').then(m => m.php());
89795
+ return import('./index-CE1LH59a.js').then(m => m.php());
89632
89796
  }
89633
89797
  }),
89634
89798
  /*@__PURE__*/LanguageDescription.of({
@@ -89645,28 +89809,28 @@ const languages = [
89645
89809
  extensions: ["BUILD", "bzl", "py", "pyw"],
89646
89810
  filename: /^(BUCK|BUILD)$/,
89647
89811
  load() {
89648
- return import('./index-CLESgVaD.js').then(m => m.python());
89812
+ return import('./index-SZgAiOi4.js').then(m => m.python());
89649
89813
  }
89650
89814
  }),
89651
89815
  /*@__PURE__*/LanguageDescription.of({
89652
89816
  name: "Rust",
89653
89817
  extensions: ["rs"],
89654
89818
  load() {
89655
- return import('./index-C04gVVoP.js').then(m => m.rust());
89819
+ return import('./index-D0g7yNKD.js').then(m => m.rust());
89656
89820
  }
89657
89821
  }),
89658
89822
  /*@__PURE__*/LanguageDescription.of({
89659
89823
  name: "Sass",
89660
89824
  extensions: ["sass"],
89661
89825
  load() {
89662
- return import('./index-CXwbrQKL.js').then(m => m.sass({ indented: true }));
89826
+ return import('./index-D7I7neMi.js').then(m => m.sass({ indented: true }));
89663
89827
  }
89664
89828
  }),
89665
89829
  /*@__PURE__*/LanguageDescription.of({
89666
89830
  name: "SCSS",
89667
89831
  extensions: ["scss"],
89668
89832
  load() {
89669
- return import('./index-CXwbrQKL.js').then(m => m.sass());
89833
+ return import('./index-D7I7neMi.js').then(m => m.sass());
89670
89834
  }
89671
89835
  }),
89672
89836
  /*@__PURE__*/LanguageDescription.of({
@@ -89697,7 +89861,7 @@ const languages = [
89697
89861
  name: "WebAssembly",
89698
89862
  extensions: ["wat", "wast"],
89699
89863
  load() {
89700
- return import('./index-ByP7YJPY.js').then(m => m.wast());
89864
+ return import('./index-DbIgJEn4.js').then(m => m.wast());
89701
89865
  }
89702
89866
  }),
89703
89867
  /*@__PURE__*/LanguageDescription.of({
@@ -89705,7 +89869,7 @@ const languages = [
89705
89869
  alias: ["rss", "wsdl", "xsd"],
89706
89870
  extensions: ["xml", "xsl", "xsd", "svg"],
89707
89871
  load() {
89708
- return import('./index-Ddm491YR.js').then(m => m.xml());
89872
+ return import('./index-Dai0K-_7.js').then(m => m.xml());
89709
89873
  }
89710
89874
  }),
89711
89875
  /*@__PURE__*/LanguageDescription.of({
@@ -89713,7 +89877,7 @@ const languages = [
89713
89877
  alias: ["yml"],
89714
89878
  extensions: ["yaml", "yml"],
89715
89879
  load() {
89716
- return import('./index-CX_Do7kl.js').then(m => m.yaml());
89880
+ return import('./index-Cqzhj8jS.js').then(m => m.yaml());
89717
89881
  }
89718
89882
  }),
89719
89883
  // Legacy modes ported from CodeMirror 5
@@ -90509,13 +90673,13 @@ const languages = [
90509
90673
  name: "Vue",
90510
90674
  extensions: ["vue"],
90511
90675
  load() {
90512
- return import('./index-By6lF-Xz.js').then(m => m.vue());
90676
+ return import('./index-DleEaqya.js').then(m => m.vue());
90513
90677
  }
90514
90678
  }),
90515
90679
  /*@__PURE__*/LanguageDescription.of({
90516
90680
  name: "Angular Template",
90517
90681
  load() {
90518
- return import('./index-CsJJiZos.js').then(m => m.angular());
90682
+ return import('./index-C6m30paN.js').then(m => m.angular());
90519
90683
  }
90520
90684
  })
90521
90685
  ];
@@ -161245,7 +161409,7 @@ const PanelAnnotationButton = ({
161245
161409
  const handleClick = React__default.useCallback(event => {
161246
161410
  event.preventDefault();
161247
161411
  onClick();
161248
- }, []);
161412
+ }, [onClick]);
161249
161413
  return /*#__PURE__*/React__default.createElement(DropdownMenuItem, {
161250
161414
  onClick: handleClick
161251
161415
  }, /*#__PURE__*/React__default.createElement(Flex, {
@@ -161276,6 +161440,7 @@ const PanelToolbar = ({
161276
161440
  return () => {
161277
161441
  clearInterval(interval);
161278
161442
  };
161443
+ // eslint-disable-next-line react-hooks/exhaustive-deps
161279
161444
  }, []);
161280
161445
  const [annotationsOpened, setAnnotationsOpened] = React__default.useState(false);
161281
161446
  const hasExtra = React__default.useMemo(() => detections.some(topic => topic.extra && !topic.enabled), [detections]);
@@ -161287,7 +161452,7 @@ const PanelToolbar = ({
161287
161452
  enabled: !topic.enabled
161288
161453
  })
161289
161454
  })));
161290
- }, [detections, setDetections]);
161455
+ }, [setDetections]);
161291
161456
 
161292
161457
  // TODO: show only when debug mode is ON
161293
161458
  const name = React__default.useMemo(() => {
@@ -161384,10 +161549,22 @@ const Panel = ({
161384
161549
  annotationTopics = [],
161385
161550
  extraAnnotationTopics = []
161386
161551
  }) => {
161552
+ const connections = useConnections();
161387
161553
  const [detections, setDetections] = React__default.useState([]);
161388
161554
  React__default.useEffect(() => {
161389
161555
  if (!disableAnnotations) {
161390
- setDetections(current => [...rawToAnnotations(annotationTopics, 'main', current), ...rawToAnnotations(extraAnnotationTopics, 'extra', current)]);
161556
+ setDetections(current => {
161557
+ const newAnnotations = [...rawToAnnotations(annotationTopics, 'main', current), ...rawToAnnotations(extraAnnotationTopics, 'extra', current)];
161558
+ for (const connection of connections) {
161559
+ connection.unsubscribe({
161560
+ topics: current.map(c => c.name)
161561
+ });
161562
+ connection.subscribe({
161563
+ topics: newAnnotations.filter(c => c.enabled).map(c => c.name)
161564
+ });
161565
+ }
161566
+ return newAnnotations;
161567
+ });
161391
161568
  }
161392
161569
  // eslint-disable-next-line react-hooks/exhaustive-deps
161393
161570
  }, [JSON.stringify(annotationTopics), JSON.stringify(extraAnnotationTopics)]);
@@ -161416,7 +161593,7 @@ const Panel = ({
161416
161593
  }, children))))));
161417
161594
  };
161418
161595
 
161419
- const ImagePanelComponent = /*#__PURE__*/React__default.lazy(async () => await import('./index-qrTNSyOQ.js'));
161596
+ const ImagePanelComponent = /*#__PURE__*/React__default.lazy(async () => await import('./index-Cmp_Tjng.js'));
161420
161597
  const ImagePanelBody = ({
161421
161598
  topic
161422
161599
  }) => {
@@ -161451,7 +161628,7 @@ const ImagePanel = /*#__PURE__*/React__default.memo(function ImagePanel(props) {
161451
161628
  // License, v2.0. If a copy of the MPL was not distributed with this
161452
161629
  // file, You can obtain one at http://mozilla.org/MPL/2.0/
161453
161630
 
161454
- const ThreeDeeRenderComponent = /*#__PURE__*/React__default.lazy(async () => await import('./index-uD6dIRaN.js'));
161631
+ const ThreeDeeRenderComponent = /*#__PURE__*/React__default.lazy(async () => await import('./index-BZjzIIuE.js'));
161455
161632
  const PointCloudPanelBody = ({
161456
161633
  topic
161457
161634
  }) => {