roboto-js 1.6.18 → 1.7.1

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.
@@ -6,6 +6,10 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports["default"] = void 0;
7
7
  var _lodash = _interopRequireDefault(require("lodash"));
8
8
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
9
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
10
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
11
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
12
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
9
13
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
10
14
  function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
11
15
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
@@ -43,15 +47,27 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
43
47
  } else {
44
48
  this._data = record.dataJson ? this._deepUnpackJson(record.dataJson) : {};
45
49
  }
46
- if (options.websocketClient && this.id) {
50
+ if (options.websocketClient && this.id && options.enableRealtime) {
47
51
  this._realtime = true;
48
52
  this._ws = options.websocketClient;
49
53
  this._subscribeToRealtime(this._ws);
54
+ } else if (options.websocketClient && this.id) {
55
+ // Store websocket client for potential later use, but don't auto-subscribe
56
+ this._ws = options.websocketClient;
57
+ }
58
+
59
+ // If enableRealtime is requested but no websocketClient provided, try to initialize lazily
60
+ if (options.enableRealtime && this.id && !this._realtime) {
61
+ this._initRealtime();
50
62
  }
51
63
  this._eventHandlers = {
52
64
  change: [],
53
65
  save: []
54
66
  };
67
+
68
+ // Debounce properties for WebSocket broadcasting
69
+ this._broadcastDebounceTimer = null;
70
+ this._pendingBroadcasts = new Map(); // path -> value
55
71
  }
56
72
  _createClass(RbtObject, [{
57
73
  key: "get",
@@ -117,16 +133,34 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
117
133
  if (!_lodash["default"].isEqual(currentValue, mergedValue)) {
118
134
  _lodash["default"].set(this._data, path, mergedValue); // Set the merged value at the deep path
119
135
  this._addChange(path);
136
+ // Trigger local change events for any registered handlers
137
+ this._trigger('change', {
138
+ path: path,
139
+ value: mergedValue,
140
+ options: options
141
+ });
120
142
  }
121
143
  } else {
122
144
  // If value is undefined and not merging, delete the key
123
145
  if (value === undefined) {
124
146
  _lodash["default"].unset(this._data, path);
125
147
  this._addChange(path);
148
+ // Trigger local change events for any registered handlers
149
+ this._trigger('change', {
150
+ path: path,
151
+ value: undefined,
152
+ options: options
153
+ });
126
154
  } else if (!_lodash["default"].isEqual(currentValue, value)) {
127
155
  _lodash["default"].set(this._data, path, value); // Set the value directly at the deep path
128
156
  this._addChange(path);
129
157
  this._broadcastChange(path, value);
158
+ // Trigger local change events for any registered handlers
159
+ this._trigger('change', {
160
+ path: path,
161
+ value: value,
162
+ options: options
163
+ });
130
164
  }
131
165
  }
132
166
  }
@@ -156,6 +190,12 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
156
190
  if (!_lodash["default"].isEqual(currentValue, mergedValue)) {
157
191
  _lodash["default"].set(_this2._data, path, mergedValue);
158
192
  _this2._addChange(path);
193
+ // Trigger change event for this path
194
+ _this2._trigger('change', {
195
+ path: path,
196
+ value: mergedValue,
197
+ options: options
198
+ });
159
199
  }
160
200
  } else if (!_lodash["default"].isEqual(currentValue, newValue)) {
161
201
  _lodash["default"].setWith(_this2._data, path, newValue, function (nsValue, key, nsObject, nsPath) {
@@ -165,6 +205,12 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
165
205
  return nsValue;
166
206
  });
167
207
  _this2._addChange(path);
208
+ // Trigger change event for this path
209
+ _this2._trigger('change', {
210
+ path: path,
211
+ value: newValue,
212
+ options: options
213
+ });
168
214
  }
169
215
  });
170
216
  }
@@ -451,13 +497,18 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
451
497
  }, {
452
498
  key: "_initRealtime",
453
499
  value: function _initRealtime() {
454
- var _this$_axios;
455
500
  if (this._realtime || !this._axios) return;
456
501
 
457
- // Lazily pull WebSocket from parent API (injected via axios instance)
458
- var api = (_this$_axios = this._axios) === null || _this$_axios === void 0 ? void 0 : _this$_axios.__rbtApiInstance;
459
- if (!api || typeof api.getWebSocketClient !== 'function') return;
460
- var ws = api.getWebSocketClient();
502
+ // Use stored websocket client if available
503
+ var ws = this._ws;
504
+
505
+ // Otherwise, lazily pull WebSocket from parent API (injected via axios instance)
506
+ if (!ws) {
507
+ var _this$_axios;
508
+ var api = (_this$_axios = this._axios) === null || _this$_axios === void 0 ? void 0 : _this$_axios.__rbtApiInstance;
509
+ if (!api || typeof api.getWebSocketClient !== 'function') return;
510
+ ws = api.getWebSocketClient();
511
+ }
461
512
  if (!ws || this._realtime) return;
462
513
  this._ws = ws;
463
514
  this._realtime = true;
@@ -466,7 +517,13 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
466
517
  }, {
467
518
  key: "_subscribeToRealtime",
468
519
  value: function _subscribeToRealtime(ws) {
469
- var _this3 = this;
520
+ var _this$_axios2,
521
+ _this3 = this;
522
+ // Track subscription for reconnection
523
+ var api = (_this$_axios2 = this._axios) === null || _this$_axios2 === void 0 ? void 0 : _this$_axios2.__rbtApiInstance;
524
+ if (api && typeof api._trackSubscription === 'function') {
525
+ api._trackSubscription(this.id);
526
+ }
470
527
  if (ws.readyState === 1) {
471
528
  ws.send(JSON.stringify({
472
529
  type: 'subscribe',
@@ -481,31 +538,58 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
481
538
  });
482
539
  }
483
540
  ws.addEventListener('message', function (event) {
484
- var msg = JSON.parse(event.data);
485
- if (msg.objectId !== _this3.id) return;
486
- if (msg.type === 'update') {
487
- _lodash["default"].set(_this3._data, msg.delta.path, msg.delta.value);
488
- _this3._trigger('change', msg.delta);
489
- } else if (msg.type === 'save') {
490
- _this3._trigger('save', msg.revision || {});
541
+ try {
542
+ var msg = JSON.parse(event.data);
543
+ if (msg.objectId !== _this3.id) return;
544
+ if (msg.type === 'update') {
545
+ if (msg.delta && msg.delta.path !== undefined) {
546
+ _lodash["default"].set(_this3._data, msg.delta.path, msg.delta.value);
547
+
548
+ // Add metadata to indicate if this is state sync vs live update
549
+ var changeData = _objectSpread(_objectSpread({}, msg.delta), {}, {
550
+ isStateSync: msg.isStateSync || false,
551
+ source: msg.isStateSync ? 'state-sync' : 'realtime',
552
+ userId: msg.userId || msg.delta.userId || null
553
+ });
554
+ _this3._trigger('change', changeData);
555
+ if (msg.isStateSync) {
556
+ console.log('[RbtObject] Applied state sync:', msg.delta.path, '=', msg.delta.value);
557
+ }
558
+ } else {
559
+ console.warn('[RbtObject] Received update message without valid delta:', msg);
560
+ }
561
+ } else if (msg.type === 'save') {
562
+ _this3._trigger('save', msg.revision || {});
563
+ }
564
+ } catch (error) {
565
+ console.error('[RbtObject] Error processing WebSocket message:', error, event.data);
491
566
  }
492
567
  });
493
568
  }
569
+
570
+ // General change handler for both local and remote changes
494
571
  }, {
495
- key: "onRealtimeChange",
496
- value: function onRealtimeChange(cb) {
572
+ key: "onChange",
573
+ value: function onChange(cb) {
497
574
  this._eventHandlers.change.push(cb);
498
- this._initRealtime(); // lazy connect
575
+ // Auto-initialize realtime if this object has WebSocket capability
576
+ if (this._ws && !this._realtime) {
577
+ this._initRealtime();
578
+ }
499
579
  }
580
+
581
+ // General save handler for both local and remote saves
500
582
  }, {
501
- key: "onRealtimeSave",
502
- value: function onRealtimeSave(cb) {
583
+ key: "onSave",
584
+ value: function onSave(cb) {
503
585
  this._eventHandlers.save.push(cb);
504
- this._initRealtime(); // lazy connect
586
+ // Note: Does not initialize realtime connection
505
587
  }
506
588
  }, {
507
589
  key: "_trigger",
508
590
  value: function _trigger(type, data) {
591
+ var _this$_eventHandlers$;
592
+ console.log('[AgentProviderSync] _trigger called:', type, 'handlers:', (_this$_eventHandlers$ = this._eventHandlers[type]) === null || _this$_eventHandlers$ === void 0 ? void 0 : _this$_eventHandlers$.length, 'data:', data);
509
593
  var _iterator = _createForOfIteratorHelper(this._eventHandlers[type] || []),
510
594
  _step;
511
595
  try {
@@ -522,16 +606,69 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
522
606
  }, {
523
607
  key: "_broadcastChange",
524
608
  value: function _broadcastChange(path, value) {
525
- if (this._realtime && this._ws && this._ws.readyState === 1) {
526
- this._ws.send(JSON.stringify({
527
- type: 'update',
528
- objectId: this.id,
529
- delta: {
530
- path: path,
531
- value: value
532
- }
533
- }));
609
+ var _this4 = this;
610
+ if (!this._realtime || !this._ws || this._ws.readyState !== 1) {
611
+ return;
612
+ }
613
+
614
+ // Store the pending broadcast
615
+ this._pendingBroadcasts.set(path, value);
616
+
617
+ // Clear existing timer if any
618
+ if (this._broadcastDebounceTimer) {
619
+ clearTimeout(this._broadcastDebounceTimer);
620
+ }
621
+
622
+ // Set new debounced timer
623
+ this._broadcastDebounceTimer = setTimeout(function () {
624
+ _this4._flushPendingBroadcasts();
625
+ }, 300);
626
+ }
627
+ }, {
628
+ key: "_flushPendingBroadcasts",
629
+ value: function _flushPendingBroadcasts() {
630
+ if (!this._realtime || !this._ws || this._ws.readyState !== 1) {
631
+ this._pendingBroadcasts.clear();
632
+ return;
633
+ }
634
+
635
+ // Send all pending broadcasts
636
+ var _iterator2 = _createForOfIteratorHelper(this._pendingBroadcasts),
637
+ _step2;
638
+ try {
639
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
640
+ var _step2$value = _slicedToArray(_step2.value, 2),
641
+ path = _step2$value[0],
642
+ value = _step2$value[1];
643
+ this._ws.send(JSON.stringify({
644
+ type: 'update',
645
+ objectId: this.id,
646
+ delta: {
647
+ path: path,
648
+ value: value
649
+ }
650
+ }));
651
+ }
652
+
653
+ // Clear pending broadcasts and timer
654
+ } catch (err) {
655
+ _iterator2.e(err);
656
+ } finally {
657
+ _iterator2.f();
658
+ }
659
+ this._pendingBroadcasts.clear();
660
+ this._broadcastDebounceTimer = null;
661
+ }
662
+
663
+ // Cleanup method to clear any pending debounced broadcasts
664
+ }, {
665
+ key: "_cleanup",
666
+ value: function _cleanup() {
667
+ if (this._broadcastDebounceTimer) {
668
+ clearTimeout(this._broadcastDebounceTimer);
669
+ this._broadcastDebounceTimer = null;
534
670
  }
671
+ this._pendingBroadcasts.clear();
535
672
  }
536
673
  }]);
537
674
  return RbtObject;
package/dist/esm/index.js CHANGED
@@ -8,7 +8,7 @@ export { RbtApi, RbtObject, RbtFile
8
8
  };
9
9
  export default class Roboto {
10
10
  getVersion() {
11
- return '1.6.17';
11
+ return '1.7.0';
12
12
  }
13
13
  constructor({
14
14
  host,
@@ -182,6 +182,14 @@ export default class Roboto {
182
182
  return this.api.query(type, params);
183
183
  }
184
184
 
185
+ // WebSocket methods
186
+ getWebSocketClient() {
187
+ return this.api.getWebSocketClient();
188
+ }
189
+ closeWebSocket() {
190
+ return this.api.closeWebSocket();
191
+ }
192
+
185
193
  //
186
194
  //
187
195
  //