roboto-js 1.5.2 → 1.5.4

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.
@@ -940,9 +940,7 @@ var RbtApi = exports["default"] = /*#__PURE__*/function () {
940
940
  if (Array.isArray(response.data.items)) {
941
941
  //console.log('RBTAPI.query RESPONSE PRE', response.data.items);
942
942
  response.data.items = response.data.items.map(function (record) {
943
- return new _rbt_object["default"](record, _this3.axios, {
944
- isNew: true
945
- });
943
+ return new _rbt_object["default"](record, _this3.axios);
946
944
  });
947
945
  }
948
946
 
@@ -35,7 +35,7 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
35
35
  this.id_revision = record.id_revision;
36
36
  this.rpcMeta = {
37
37
  changes: [],
38
- isNew: options.isNew || false
38
+ isNew: options.isNew || record.revision == 0 || false
39
39
  };
40
40
  if (record.data) {
41
41
  this._data = this._deepUnpackJson(record.data);
@@ -87,6 +87,9 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
87
87
 
88
88
  if (options.merge) {
89
89
  var mergedValue = _lodash["default"].mergeWith({}, currentValue, value, function (objValue, srcValue) {
90
+ if (srcValue === undefined) {
91
+ return undefined; // Indicate to delete when merging
92
+ }
90
93
  if (_lodash["default"].isArray(objValue)) {
91
94
  return srcValue; // Customize merging behavior for arrays
92
95
  }
@@ -95,12 +98,22 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
95
98
  return srcValue;
96
99
  }
97
100
  });
101
+ // Process merged object to remove any keys set explicitly to undefined
102
+ Object.keys(mergedValue).forEach(function (key) {
103
+ if (mergedValue[key] === undefined) {
104
+ _lodash["default"].unset(mergedValue, key);
105
+ }
106
+ });
98
107
  if (!_lodash["default"].isEqual(currentValue, mergedValue)) {
99
108
  _lodash["default"].set(this._data, path, mergedValue); // Set the merged value at the deep path
100
109
  this._addChange(path);
101
110
  }
102
111
  } else {
103
- if (!_lodash["default"].isEqual(currentValue, value)) {
112
+ // If value is undefined and not merging, delete the key
113
+ if (value === undefined) {
114
+ _lodash["default"].unset(this._data, path);
115
+ this._addChange(path);
116
+ } else if (!_lodash["default"].isEqual(currentValue, value)) {
104
117
  _lodash["default"].set(this._data, path, value); // Set the value directly at the deep path
105
118
  this._addChange(path);
106
119
  }
@@ -145,7 +158,78 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
145
158
  });
146
159
  }
147
160
 
148
- // set(path, value, options = {}) {
161
+ //
162
+ // For Arrays
163
+ //
164
+ }, {
165
+ key: "setAppend",
166
+ value: function () {
167
+ var _setAppend = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(key, value) {
168
+ var options,
169
+ existingValue,
170
+ valuesToAdd,
171
+ mergedValues,
172
+ _args = arguments;
173
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
174
+ while (1) switch (_context.prev = _context.next) {
175
+ case 0:
176
+ options = _args.length > 2 && _args[2] !== undefined ? _args[2] : {};
177
+ existingValue = this.get(key) || []; // Get the existing value or default to an empty array
178
+ if (!Array.isArray(existingValue)) {
179
+ existingValue = []; // Ensure existingValue is an array if not already
180
+ }
181
+ valuesToAdd = Array.isArray(value) ? value : [value]; // Convert value to an array if it's not one
182
+ // Combine existingValue and valuesToAdd, filtering out duplicates
183
+ mergedValues = Array.from(new Set([].concat(_toConsumableArray(existingValue), _toConsumableArray(valuesToAdd))));
184
+ this.set(key, mergedValues, options); // Set the updated array back to the user data
185
+ case 6:
186
+ case "end":
187
+ return _context.stop();
188
+ }
189
+ }, _callee, this);
190
+ }));
191
+ function setAppend(_x, _x2) {
192
+ return _setAppend.apply(this, arguments);
193
+ }
194
+ return setAppend;
195
+ }()
196
+ }, {
197
+ key: "setRemove",
198
+ value: function () {
199
+ var _setRemove = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(key, value) {
200
+ var options,
201
+ existingValue,
202
+ valuesToRemove,
203
+ filteredValues,
204
+ _args2 = arguments;
205
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
206
+ while (1) switch (_context2.prev = _context2.next) {
207
+ case 0:
208
+ options = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : {};
209
+ existingValue = this.get(key) || []; // Get the existing value or default to an empty array
210
+ if (Array.isArray(existingValue)) {
211
+ _context2.next = 4;
212
+ break;
213
+ }
214
+ return _context2.abrupt("return");
215
+ case 4:
216
+ valuesToRemove = Array.isArray(value) ? value : [value]; // Convert value to an array if it's not one
217
+ // Filter out the values to remove from the existing value array
218
+ filteredValues = existingValue.filter(function (item) {
219
+ return !valuesToRemove.includes(item);
220
+ });
221
+ this.set(key, filteredValues); // Set the updated array back to the user data
222
+ case 7:
223
+ case "end":
224
+ return _context2.stop();
225
+ }
226
+ }, _callee2, this);
227
+ }));
228
+ function setRemove(_x3, _x4) {
229
+ return _setRemove.apply(this, arguments);
230
+ }
231
+ return setRemove;
232
+ }() // set(path, value, options = {}) {
149
233
  // const currentValue = _.get(this._data, path);
150
234
  //
151
235
  // // Check if merge is required
@@ -196,6 +280,32 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
196
280
  rpcMeta: this.rpcMeta
197
281
  });
198
282
  }
283
+ }, {
284
+ key: "toDeltaRecord",
285
+ value: function toDeltaRecord() {
286
+ var changes = this.rpcMeta.changes;
287
+
288
+ // Initialize deltaData as an empty object
289
+ var sourceData = this._data;
290
+ var deltaData = {};
291
+
292
+ // Populate deltaData only with keys specified in changes
293
+ changes.forEach(function (path) {
294
+ // default value explicitly set to undefined
295
+ var value = _lodash["default"].get(sourceData, path, undefined);
296
+ // Use _.set to ensure nested keys are correctly assigned
297
+ _lodash["default"].set(deltaData, path, value);
298
+ });
299
+
300
+ // mark as delta
301
+ this.rpcMeta.delta = true;
302
+ var clonedData = _lodash["default"].cloneDeep(this._internalData);
303
+ clonedData.data = deltaData;
304
+ return _objectSpread(_objectSpread({}, clonedData), {}, {
305
+ dataJson: JSON.stringify(deltaData),
306
+ rpcMeta: this.rpcMeta
307
+ });
308
+ }
199
309
  }, {
200
310
  key: "clone",
201
311
  value: function clone() {
@@ -215,36 +325,41 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
215
325
  }, {
216
326
  key: "save",
217
327
  value: function () {
218
- var _save = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
328
+ var _save = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
219
329
  var _response$data, _response$data2, record, response, _e$response;
220
- return _regeneratorRuntime().wrap(function _callee$(_context) {
221
- while (1) switch (_context.prev = _context.next) {
330
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
331
+ while (1) switch (_context3.prev = _context3.next) {
222
332
  case 0:
223
333
  if (this._internalData.type) {
224
- _context.next = 2;
334
+ _context3.next = 2;
225
335
  break;
226
336
  }
227
337
  throw new Error('Cannot save object without type');
228
338
  case 2:
229
- _context.prev = 2;
230
- record = this.toRecord();
231
- _context.next = 6;
339
+ _context3.prev = 2;
340
+ debugger;
341
+ if (this.rpcMeta.isNew) {
342
+ record = this.toRecord();
343
+ } else {
344
+ record = this.toDeltaRecord();
345
+ }
346
+ _context3.next = 7;
232
347
  return this._axios.post('/object_service/saveObject', [record]);
233
- case 6:
234
- response = _context.sent;
348
+ case 7:
349
+ response = _context3.sent;
235
350
  if (!(response.data.ok === false)) {
236
- _context.next = 9;
351
+ _context3.next = 10;
237
352
  break;
238
353
  }
239
354
  throw new Error(response.data.message);
240
- case 9:
355
+ case 10:
241
356
  if (!(((_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.result) == 'NO_CHANGES')) {
242
- _context.next = 12;
357
+ _context3.next = 13;
243
358
  break;
244
359
  }
245
360
  this.rpcMeta.isNew = false;
246
- return _context.abrupt("return", this);
247
- case 12:
361
+ return _context3.abrupt("return", this);
362
+ case 13:
248
363
  if ((_response$data2 = response.data) !== null && _response$data2 !== void 0 && _response$data2.newData) {
249
364
  // apply new incoming data
250
365
  this.setData(response.newData);
@@ -253,19 +368,19 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
253
368
  this.id_revision = response.data.id_revision;
254
369
  this.type = response.data.type;
255
370
  this.rpcMeta.isNew = false;
256
- return _context.abrupt("return", this);
257
- case 20:
258
- _context.prev = 20;
259
- _context.t0 = _context["catch"](2);
260
- console.log('RbtObject.save.error:', _context.t0 === null || _context.t0 === void 0 || (_e$response = _context.t0.response) === null || _e$response === void 0 ? void 0 : _e$response.data);
261
- this._error = _context.t0;
371
+ return _context3.abrupt("return", this);
372
+ case 21:
373
+ _context3.prev = 21;
374
+ _context3.t0 = _context3["catch"](2);
375
+ console.log('RbtObject.save.error:', _context3.t0 === null || _context3.t0 === void 0 || (_e$response = _context3.t0.response) === null || _e$response === void 0 ? void 0 : _e$response.data);
376
+ this._error = _context3.t0;
262
377
  //console.log(e.response.data);
263
- throw _context.t0;
264
- case 25:
378
+ throw _context3.t0;
379
+ case 26:
265
380
  case "end":
266
- return _context.stop();
381
+ return _context3.stop();
267
382
  }
268
- }, _callee, this, [[2, 20]]);
383
+ }, _callee3, this, [[2, 21]]);
269
384
  }));
270
385
  function save() {
271
386
  return _save.apply(this, arguments);
@@ -275,42 +390,42 @@ var RbtObject = exports["default"] = /*#__PURE__*/function () {
275
390
  }, {
276
391
  key: "delete",
277
392
  value: function () {
278
- var _delete2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
393
+ var _delete2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
279
394
  var record, response;
280
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
281
- while (1) switch (_context2.prev = _context2.next) {
395
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
396
+ while (1) switch (_context4.prev = _context4.next) {
282
397
  case 0:
283
398
  if (this._internalData.type) {
284
- _context2.next = 2;
399
+ _context4.next = 2;
285
400
  break;
286
401
  }
287
402
  throw new Error('Cannot delete object without type');
288
403
  case 2:
289
- _context2.prev = 2;
404
+ _context4.prev = 2;
290
405
  record = this.toRecord();
291
- _context2.next = 6;
406
+ _context4.next = 6;
292
407
  return this._axios.post('/object_service/deleteObject', [record]);
293
408
  case 6:
294
- response = _context2.sent;
409
+ response = _context4.sent;
295
410
  if (!(response.data.ok === false)) {
296
- _context2.next = 9;
411
+ _context4.next = 9;
297
412
  break;
298
413
  }
299
414
  throw new Error(response.data.message);
300
415
  case 9:
301
416
  this._internalData = response.data;
302
- return _context2.abrupt("return", this);
417
+ return _context4.abrupt("return", this);
303
418
  case 13:
304
- _context2.prev = 13;
305
- _context2.t0 = _context2["catch"](2);
419
+ _context4.prev = 13;
420
+ _context4.t0 = _context4["catch"](2);
306
421
  console.log('RbtObject.delete.error:');
307
- console.log(_context2.t0.response.data);
308
- throw _context2.t0;
422
+ console.log(_context4.t0.response.data);
423
+ throw _context4.t0;
309
424
  case 18:
310
425
  case "end":
311
- return _context2.stop();
426
+ return _context4.stop();
312
427
  }
313
- }, _callee2, this, [[2, 13]]);
428
+ }, _callee4, this, [[2, 13]]);
314
429
  }));
315
430
  function _delete() {
316
431
  return _delete2.apply(this, arguments);
@@ -9,6 +9,12 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "d
9
9
  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; }
10
10
  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); } }
11
11
  function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
12
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
13
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
14
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
15
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
16
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
17
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
12
18
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
13
19
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
14
20
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
@@ -77,6 +83,44 @@ var RbtUser = exports["default"] = /*#__PURE__*/function () {
77
83
  }
78
84
  });
79
85
  }
86
+
87
+ //
88
+ // For Arrays
89
+ //
90
+ }, {
91
+ key: "setAppend",
92
+ value: function setAppend(key, value) {
93
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
94
+ var existingValue = this.get(key) || []; // Get the existing value or default to an empty array
95
+ if (!Array.isArray(existingValue)) {
96
+ existingValue = []; // Ensure existingValue is an array if not already
97
+ }
98
+ var valuesToAdd = Array.isArray(value) ? value : [value]; // Convert value to an array if it's not one
99
+
100
+ // Combine existingValue and valuesToAdd, filtering out duplicates
101
+ var mergedValues = Array.from(new Set([].concat(_toConsumableArray(existingValue), _toConsumableArray(valuesToAdd))));
102
+ this.set(key, mergedValues, options); // Set the updated array back to the user data
103
+ }
104
+ }, {
105
+ key: "setRemove",
106
+ value: function setRemove(key, value) {
107
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
108
+ var existingValue = this.get(key) || []; // Get the existing value or default to an empty array
109
+ if (!Array.isArray(existingValue)) {
110
+ return; // If it's not an array, there's nothing to remove, so exit early
111
+ }
112
+ var valuesToRemove = Array.isArray(value) ? value : [value]; // Convert value to an array if it's not one
113
+
114
+ // Filter out the values to remove from the existing value array
115
+ var filteredValues = existingValue.filter(function (item) {
116
+ return !valuesToRemove.includes(item);
117
+ });
118
+ this.set(key, filteredValues); // Set the updated array back to the user data
119
+ }
120
+
121
+ //
122
+ //
123
+ //
80
124
  }, {
81
125
  key: "toRecord",
82
126
  value: function toRecord() {
@@ -522,9 +522,7 @@ export default class RbtApi {
522
522
  if (Array.isArray(response.data.items)) {
523
523
  //console.log('RBTAPI.query RESPONSE PRE', response.data.items);
524
524
  response.data.items = response.data.items.map(record => {
525
- return new RbtObject(record, this.axios, {
526
- isNew: true
527
- });
525
+ return new RbtObject(record, this.axios);
528
526
  });
529
527
  }
530
528
 
@@ -8,7 +8,7 @@ export default class RbtObject {
8
8
  this.id_revision = record.id_revision;
9
9
  this.rpcMeta = {
10
10
  changes: [],
11
- isNew: options.isNew || false
11
+ isNew: options.isNew || record.revision == 0 || false
12
12
  };
13
13
  if (record.data) {
14
14
  this._data = this._deepUnpackJson(record.data);
@@ -51,6 +51,9 @@ export default class RbtObject {
51
51
 
52
52
  if (options.merge) {
53
53
  const mergedValue = _.mergeWith({}, currentValue, value, (objValue, srcValue) => {
54
+ if (srcValue === undefined) {
55
+ return undefined; // Indicate to delete when merging
56
+ }
54
57
  if (_.isArray(objValue)) {
55
58
  return srcValue; // Customize merging behavior for arrays
56
59
  }
@@ -59,12 +62,22 @@ export default class RbtObject {
59
62
  return srcValue;
60
63
  }
61
64
  });
65
+ // Process merged object to remove any keys set explicitly to undefined
66
+ Object.keys(mergedValue).forEach(key => {
67
+ if (mergedValue[key] === undefined) {
68
+ _.unset(mergedValue, key);
69
+ }
70
+ });
62
71
  if (!_.isEqual(currentValue, mergedValue)) {
63
72
  _.set(this._data, path, mergedValue); // Set the merged value at the deep path
64
73
  this._addChange(path);
65
74
  }
66
75
  } else {
67
- if (!_.isEqual(currentValue, value)) {
76
+ // If value is undefined and not merging, delete the key
77
+ if (value === undefined) {
78
+ _.unset(this._data, path);
79
+ this._addChange(path);
80
+ } else if (!_.isEqual(currentValue, value)) {
68
81
  _.set(this._data, path, value); // Set the value directly at the deep path
69
82
  this._addChange(path);
70
83
  }
@@ -106,6 +119,33 @@ export default class RbtObject {
106
119
  });
107
120
  }
108
121
 
122
+ //
123
+ // For Arrays
124
+ //
125
+
126
+ async setAppend(key, value, options = {}) {
127
+ let existingValue = this.get(key) || []; // Get the existing value or default to an empty array
128
+ if (!Array.isArray(existingValue)) {
129
+ existingValue = []; // Ensure existingValue is an array if not already
130
+ }
131
+ const valuesToAdd = Array.isArray(value) ? value : [value]; // Convert value to an array if it's not one
132
+
133
+ // Combine existingValue and valuesToAdd, filtering out duplicates
134
+ const mergedValues = Array.from(new Set([...existingValue, ...valuesToAdd]));
135
+ this.set(key, mergedValues, options); // Set the updated array back to the user data
136
+ }
137
+ async setRemove(key, value, options = {}) {
138
+ let existingValue = this.get(key) || []; // Get the existing value or default to an empty array
139
+ if (!Array.isArray(existingValue)) {
140
+ return; // If it's not an array, there's nothing to remove, so exit early
141
+ }
142
+ const valuesToRemove = Array.isArray(value) ? value : [value]; // Convert value to an array if it's not one
143
+
144
+ // Filter out the values to remove from the existing value array
145
+ const filteredValues = existingValue.filter(item => !valuesToRemove.includes(item));
146
+ this.set(key, filteredValues); // Set the updated array back to the user data
147
+ }
148
+
109
149
  // set(path, value, options = {}) {
110
150
  // const currentValue = _.get(this._data, path);
111
151
  //
@@ -155,6 +195,31 @@ export default class RbtObject {
155
195
  rpcMeta: this.rpcMeta
156
196
  };
157
197
  }
198
+ toDeltaRecord() {
199
+ let changes = this.rpcMeta.changes;
200
+
201
+ // Initialize deltaData as an empty object
202
+ let sourceData = this._data;
203
+ let deltaData = {};
204
+
205
+ // Populate deltaData only with keys specified in changes
206
+ changes.forEach(path => {
207
+ // default value explicitly set to undefined
208
+ const value = _.get(sourceData, path, undefined);
209
+ // Use _.set to ensure nested keys are correctly assigned
210
+ _.set(deltaData, path, value);
211
+ });
212
+
213
+ // mark as delta
214
+ this.rpcMeta.delta = true;
215
+ const clonedData = _.cloneDeep(this._internalData);
216
+ clonedData.data = deltaData;
217
+ return {
218
+ ...clonedData,
219
+ dataJson: JSON.stringify(deltaData),
220
+ rpcMeta: this.rpcMeta
221
+ };
222
+ }
158
223
  clone() {
159
224
  // Create a deep copy of the current object's data
160
225
  const clonedData = _.cloneDeep(this._internalData);
@@ -174,7 +239,13 @@ export default class RbtObject {
174
239
  throw new Error('Cannot save object without type');
175
240
  }
176
241
  try {
177
- const record = this.toRecord();
242
+ debugger;
243
+ let record;
244
+ if (this.rpcMeta.isNew) {
245
+ record = this.toRecord();
246
+ } else {
247
+ record = this.toDeltaRecord();
248
+ }
178
249
  const response = await this._axios.post('/object_service/saveObject', [record]);
179
250
  if (response.data.ok === false) {
180
251
  throw new Error(response.data.message);
@@ -47,6 +47,38 @@ export default class RbtUser {
47
47
  }
48
48
  });
49
49
  }
50
+
51
+ //
52
+ // For Arrays
53
+ //
54
+
55
+ setAppend(key, value, options = {}) {
56
+ let existingValue = this.get(key) || []; // Get the existing value or default to an empty array
57
+ if (!Array.isArray(existingValue)) {
58
+ existingValue = []; // Ensure existingValue is an array if not already
59
+ }
60
+ const valuesToAdd = Array.isArray(value) ? value : [value]; // Convert value to an array if it's not one
61
+
62
+ // Combine existingValue and valuesToAdd, filtering out duplicates
63
+ const mergedValues = Array.from(new Set([...existingValue, ...valuesToAdd]));
64
+ this.set(key, mergedValues, options); // Set the updated array back to the user data
65
+ }
66
+ setRemove(key, value, options = {}) {
67
+ let existingValue = this.get(key) || []; // Get the existing value or default to an empty array
68
+ if (!Array.isArray(existingValue)) {
69
+ return; // If it's not an array, there's nothing to remove, so exit early
70
+ }
71
+ const valuesToRemove = Array.isArray(value) ? value : [value]; // Convert value to an array if it's not one
72
+
73
+ // Filter out the values to remove from the existing value array
74
+ const filteredValues = existingValue.filter(item => !valuesToRemove.includes(item));
75
+ this.set(key, filteredValues); // Set the updated array back to the user data
76
+ }
77
+
78
+ //
79
+ //
80
+ //
81
+
50
82
  toRecord() {
51
83
  return {
52
84
  ...this._internalData,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roboto-js",
3
- "version": "1.5.2",
3
+ "version": "1.5.4",
4
4
  "type": "module",
5
5
  "description": "",
6
6
  "main": "dist/cjs/index.cjs",
package/src/rbt_api.js CHANGED
@@ -597,7 +597,7 @@ export default class RbtApi {
597
597
  if (Array.isArray(response.data.items)) {
598
598
  //console.log('RBTAPI.query RESPONSE PRE', response.data.items);
599
599
  response.data.items = response.data.items.map(record => {
600
- return new RbtObject(record, this.axios, { isNew: true });
600
+ return new RbtObject(record, this.axios);
601
601
  });
602
602
  }
603
603
 
package/src/rbt_object.js CHANGED
@@ -10,7 +10,7 @@ export default class RbtObject {
10
10
  this.id_revision = record.id_revision;
11
11
  this.rpcMeta = {
12
12
  changes: [],
13
- isNew: options.isNew || false
13
+ isNew: options.isNew || record.revision == 0 || false
14
14
  };
15
15
 
16
16
  if(record.data){
@@ -57,6 +57,9 @@ export default class RbtObject {
57
57
 
58
58
  if (options.merge) {
59
59
  const mergedValue = _.mergeWith({}, currentValue, value, (objValue, srcValue) => {
60
+ if (srcValue === undefined) {
61
+ return undefined; // Indicate to delete when merging
62
+ }
60
63
  if (_.isArray(objValue)) {
61
64
  return srcValue; // Customize merging behavior for arrays
62
65
  }
@@ -65,12 +68,22 @@ export default class RbtObject {
65
68
  return srcValue;
66
69
  }
67
70
  });
71
+ // Process merged object to remove any keys set explicitly to undefined
72
+ Object.keys(mergedValue).forEach(key => {
73
+ if (mergedValue[key] === undefined) {
74
+ _.unset(mergedValue, key);
75
+ }
76
+ });
68
77
  if (!_.isEqual(currentValue, mergedValue)) {
69
78
  _.set(this._data, path, mergedValue); // Set the merged value at the deep path
70
79
  this._addChange(path);
71
80
  }
72
81
  } else {
73
- if (!_.isEqual(currentValue, value)) {
82
+ // If value is undefined and not merging, delete the key
83
+ if (value === undefined) {
84
+ _.unset(this._data, path);
85
+ this._addChange(path);
86
+ } else if (!_.isEqual(currentValue, value)) {
74
87
  _.set(this._data, path, value); // Set the value directly at the deep path
75
88
  this._addChange(path);
76
89
  }
@@ -115,6 +128,38 @@ export default class RbtObject {
115
128
  });
116
129
  }
117
130
 
131
+ //
132
+ // For Arrays
133
+ //
134
+
135
+ async setAppend(key, value, options = {}) {
136
+ let existingValue = this.get(key) || []; // Get the existing value or default to an empty array
137
+ if (!Array.isArray(existingValue)) {
138
+ existingValue = []; // Ensure existingValue is an array if not already
139
+ }
140
+
141
+ const valuesToAdd = Array.isArray(value) ? value : [value]; // Convert value to an array if it's not one
142
+
143
+ // Combine existingValue and valuesToAdd, filtering out duplicates
144
+ const mergedValues = Array.from(new Set([...existingValue, ...valuesToAdd]));
145
+
146
+ this.set(key, mergedValues, options); // Set the updated array back to the user data
147
+ }
148
+
149
+ async setRemove(key, value, options = {}) {
150
+ let existingValue = this.get(key) || []; // Get the existing value or default to an empty array
151
+ if (!Array.isArray(existingValue)) {
152
+ return; // If it's not an array, there's nothing to remove, so exit early
153
+ }
154
+
155
+ const valuesToRemove = Array.isArray(value) ? value : [value]; // Convert value to an array if it's not one
156
+
157
+ // Filter out the values to remove from the existing value array
158
+ const filteredValues = existingValue.filter(item => !valuesToRemove.includes(item));
159
+
160
+ this.set(key, filteredValues); // Set the updated array back to the user data
161
+
162
+ }
118
163
 
119
164
 
120
165
 
@@ -170,6 +215,34 @@ export default class RbtObject {
170
215
  };
171
216
  }
172
217
 
218
+ toDeltaRecord(){
219
+
220
+ let changes = this.rpcMeta.changes;
221
+
222
+ // Initialize deltaData as an empty object
223
+ let sourceData = this._data;
224
+ let deltaData = {};
225
+
226
+ // Populate deltaData only with keys specified in changes
227
+ changes.forEach(path => {
228
+ // default value explicitly set to undefined
229
+ const value = _.get(sourceData, path, undefined);
230
+ // Use _.set to ensure nested keys are correctly assigned
231
+ _.set(deltaData, path, value);
232
+ });
233
+
234
+ // mark as delta
235
+ this.rpcMeta.delta = true;
236
+ const clonedData = _.cloneDeep(this._internalData);
237
+ clonedData.data = deltaData;
238
+
239
+ return {
240
+ ...clonedData,
241
+ dataJson: JSON.stringify(deltaData),
242
+ rpcMeta: this.rpcMeta
243
+ }
244
+ }
245
+
173
246
  clone() {
174
247
  // Create a deep copy of the current object's data
175
248
  const clonedData = _.cloneDeep(this._internalData);
@@ -190,7 +263,17 @@ export default class RbtObject {
190
263
  }
191
264
 
192
265
  try {
193
- const record = this.toRecord();
266
+
267
+ debugger;
268
+ let record;
269
+ if(this.rpcMeta.isNew){
270
+ record = this.toRecord();
271
+ }
272
+ else{
273
+ record = this.toDeltaRecord();
274
+ }
275
+
276
+
194
277
  const response = await this._axios.post('/object_service/saveObject', [record]);
195
278
 
196
279
  if (response.data.ok === false) {
package/src/rbt_user.js CHANGED
@@ -58,6 +58,43 @@ export default class RbtUser {
58
58
  });
59
59
  }
60
60
 
61
+ //
62
+ // For Arrays
63
+ //
64
+
65
+ setAppend(key, value, options = {}) {
66
+ let existingValue = this.get(key) || []; // Get the existing value or default to an empty array
67
+ if (!Array.isArray(existingValue)) {
68
+ existingValue = []; // Ensure existingValue is an array if not already
69
+ }
70
+
71
+ const valuesToAdd = Array.isArray(value) ? value : [value]; // Convert value to an array if it's not one
72
+
73
+ // Combine existingValue and valuesToAdd, filtering out duplicates
74
+ const mergedValues = Array.from(new Set([...existingValue, ...valuesToAdd]));
75
+
76
+ this.set(key, mergedValues, options); // Set the updated array back to the user data
77
+ }
78
+
79
+ setRemove(key, value, options = {}) {
80
+ let existingValue = this.get(key) || []; // Get the existing value or default to an empty array
81
+ if (!Array.isArray(existingValue)) {
82
+ return; // If it's not an array, there's nothing to remove, so exit early
83
+ }
84
+
85
+ const valuesToRemove = Array.isArray(value) ? value : [value]; // Convert value to an array if it's not one
86
+
87
+ // Filter out the values to remove from the existing value array
88
+ const filteredValues = existingValue.filter(item => !valuesToRemove.includes(item));
89
+
90
+ this.set(key, filteredValues); // Set the updated array back to the user data
91
+
92
+ }
93
+
94
+ //
95
+ //
96
+ //
97
+
61
98
  toRecord() {
62
99
  return {
63
100
  ...this._internalData,