@symbo.ls/sdk 2.32.30 → 2.33.2

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.
@@ -27,6 +27,31 @@ var import_rootEventBus = require("../state/rootEventBus.js");
27
27
  var import_validation = require("../utils/validation.js");
28
28
  var import_utils = require("@domql/utils");
29
29
  var import_changePreprocessor = require("../utils/changePreprocessor.js");
30
+ const FUNCTION_META_KEYS = ["node", "__ref", "__element", "parent", "parse"];
31
+ function stringifyFunctionsForTransport(value, seen = /* @__PURE__ */ new WeakMap()) {
32
+ if (value === null || typeof value !== "object") {
33
+ return typeof value === "function" ? value.toString() : value;
34
+ }
35
+ if (seen.has(value)) {
36
+ return seen.get(value);
37
+ }
38
+ const clone = Array.isArray(value) ? [] : {};
39
+ seen.set(value, clone);
40
+ if (Array.isArray(value)) {
41
+ for (let i = 0; i < value.length; i++) {
42
+ clone[i] = stringifyFunctionsForTransport(value[i], seen);
43
+ }
44
+ return clone;
45
+ }
46
+ const keys = Object.keys(value);
47
+ for (let i = 0; i < keys.length; i++) {
48
+ const key = keys[i];
49
+ if (!FUNCTION_META_KEYS.includes(key)) {
50
+ clone[key] = stringifyFunctionsForTransport(value[key], seen);
51
+ }
52
+ }
53
+ return clone;
54
+ }
30
55
  class CollabService extends import_BaseService.BaseService {
31
56
  constructor(config) {
32
57
  super(config);
@@ -335,7 +360,7 @@ class CollabService extends import_BaseService.BaseService {
335
360
  }
336
361
  /* ---------- data helpers ---------- */
337
362
  updateData(tuples, options = {}) {
338
- var _a, _b, _c;
363
+ var _a, _b;
339
364
  this._ensureStateManager();
340
365
  const { isUndo = false, isRedo = false } = options;
341
366
  if (!isUndo && !isRedo && !this._isUndoRedo) {
@@ -351,21 +376,10 @@ class CollabService extends import_BaseService.BaseService {
351
376
  processedTuples.push(...options.append);
352
377
  }
353
378
  this._stateManager.applyChanges(tuples, { ...options });
354
- const state = (_b = this._stateManager) == null ? void 0 : _b.root;
355
- const el = state == null ? void 0 : state.__element;
356
- const stringifiedGranularTuples = (el == null ? void 0 : el.call) ? el.call(
357
- "deepStringifyFunctions",
358
- processedTuples,
359
- Array.isArray(processedTuples) ? [] : {}
360
- ) : (0, import_utils.deepStringifyFunctions)(
361
- processedTuples,
362
- Array.isArray(processedTuples) ? [] : {}
379
+ const stringifiedGranularTuples = stringifyFunctionsForTransport(
380
+ processedTuples
363
381
  );
364
- const stringifiedTuples = (el == null ? void 0 : el.call) ? el.call(
365
- "deepStringifyFunctions",
366
- tuples,
367
- Array.isArray(tuples) ? [] : {}
368
- ) : (0, import_utils.deepStringifyFunctions)(tuples, Array.isArray(tuples) ? [] : {});
382
+ const stringifiedTuples = stringifyFunctionsForTransport(tuples);
369
383
  const { message } = options;
370
384
  if (!this.isConnected()) {
371
385
  console.warn("[CollabService] Not connected, queuing real-time update");
@@ -377,7 +391,7 @@ class CollabService extends import_BaseService.BaseService {
377
391
  });
378
392
  return;
379
393
  }
380
- if ((_c = this.socket) == null ? void 0 : _c.connected) {
394
+ if ((_b = this.socket) == null ? void 0 : _b.connected) {
381
395
  const ts = Date.now();
382
396
  console.log("[CollabService] Sending operations to the backend", {
383
397
  changes: stringifiedTuples,
@@ -167,14 +167,14 @@ function computeOrdersForTuples(root, tuples = []) {
167
167
  }
168
168
  const [action, path] = t;
169
169
  const p = normalizePath(path);
170
- if (!Array.isArray(p) || p.length < 3) {
170
+ if (!Array.isArray(p) || p.length < 2) {
171
171
  continue;
172
172
  }
173
173
  if (p[0] === "schema") {
174
174
  continue;
175
175
  }
176
- const [typeName, containerKey, childKey] = p;
177
- const containerPath = [typeName, containerKey];
176
+ const containerPath = p.slice(0, -1);
177
+ const childKey = p[p.length - 1];
178
178
  const key = JSON.stringify(containerPath);
179
179
  if (!pendingChildrenByContainer.has(key)) {
180
180
  pendingChildrenByContainer.set(key, /* @__PURE__ */ new Set());
@@ -259,12 +259,47 @@ function computeOrdersForTuples(root, tuples = []) {
259
259
  }
260
260
  const pending = pendingChildrenByContainer.get(k);
261
261
  if (pending && pending.size) {
262
- const existing = new Set(v.keys);
262
+ const existingKeys = v.keys;
263
+ const existingSet = new Set(existingKeys);
264
+ const META_KEYS = /* @__PURE__ */ new Set([
265
+ "style",
266
+ "class",
267
+ "text",
268
+ "html",
269
+ "content",
270
+ "data",
271
+ "attr",
272
+ "state",
273
+ "scope",
274
+ "define",
275
+ "on",
276
+ "extend",
277
+ "extends",
278
+ "childExtend",
279
+ "childExtends",
280
+ "children",
281
+ "component",
282
+ "context",
283
+ "tag",
284
+ "key",
285
+ "__order",
286
+ "if"
287
+ ]);
288
+ let firstMetaIndex = existingKeys.length;
289
+ for (let j = 0; j < existingKeys.length; j++) {
290
+ if (META_KEYS.has(existingKeys[j])) {
291
+ firstMetaIndex = j;
292
+ break;
293
+ }
294
+ }
263
295
  for (const child of pending) {
264
- if (existing.has(child)) {
296
+ if (existingSet.has(child)) {
265
297
  continue;
266
298
  }
267
- v.keys.push(child);
299
+ const insertIndex = firstMetaIndex;
300
+ existingKeys.splice(insertIndex, 0, child);
301
+ existingSet.add(child);
302
+ firstMetaIndex++;
268
303
  }
269
304
  }
270
305
  seen.add(k);
package/dist/esm/index.js CHANGED
@@ -42782,14 +42782,14 @@ function computeOrdersForTuples(root, tuples = []) {
42782
42782
  }
42783
42783
  const [action, path] = t4;
42784
42784
  const p3 = normalizePath(path);
42785
- if (!Array.isArray(p3) || p3.length < 3) {
42785
+ if (!Array.isArray(p3) || p3.length < 2) {
42786
42786
  continue;
42787
42787
  }
42788
42788
  if (p3[0] === "schema") {
42789
42789
  continue;
42790
42790
  }
42791
- const [typeName, containerKey, childKey] = p3;
42792
- const containerPath = [typeName, containerKey];
42791
+ const containerPath = p3.slice(0, -1);
42792
+ const childKey = p3[p3.length - 1];
42793
42793
  const key = JSON.stringify(containerPath);
42794
42794
  if (!pendingChildrenByContainer.has(key)) {
42795
42795
  pendingChildrenByContainer.set(key, /* @__PURE__ */ new Set());
@@ -42874,12 +42874,47 @@ function computeOrdersForTuples(root, tuples = []) {
42874
42874
  }
42875
42875
  const pending = pendingChildrenByContainer.get(k3);
42876
42876
  if (pending && pending.size) {
42877
- const existing = new Set(v3.keys);
42877
+ const existingKeys = v3.keys;
42878
+ const existingSet = new Set(existingKeys);
42879
+ const META_KEYS = /* @__PURE__ */ new Set([
42880
+ "style",
42881
+ "class",
42882
+ "text",
42883
+ "html",
42884
+ "content",
42885
+ "data",
42886
+ "attr",
42887
+ "state",
42888
+ "scope",
42889
+ "define",
42890
+ "on",
42891
+ "extend",
42892
+ "extends",
42893
+ "childExtend",
42894
+ "childExtends",
42895
+ "children",
42896
+ "component",
42897
+ "context",
42898
+ "tag",
42899
+ "key",
42900
+ "__order",
42901
+ "if"
42902
+ ]);
42903
+ let firstMetaIndex = existingKeys.length;
42904
+ for (let j3 = 0; j3 < existingKeys.length; j3++) {
42905
+ if (META_KEYS.has(existingKeys[j3])) {
42906
+ firstMetaIndex = j3;
42907
+ break;
42908
+ }
42909
+ }
42878
42910
  for (const child of pending) {
42879
- if (existing.has(child)) {
42911
+ if (existingSet.has(child)) {
42880
42912
  continue;
42881
42913
  }
42882
- v3.keys.push(child);
42914
+ const insertIndex = firstMetaIndex;
42915
+ existingKeys.splice(insertIndex, 0, child);
42916
+ existingSet.add(child);
42917
+ firstMetaIndex++;
42883
42918
  }
42884
42919
  }
42885
42920
  seen.add(k3);
@@ -43066,6 +43101,31 @@ function preprocessChanges(root, tuples = [], options = {}) {
43066
43101
  }
43067
43102
 
43068
43103
  // src/services/CollabService.js
43104
+ var FUNCTION_META_KEYS = ["node", "__ref", "__element", "parent", "parse"];
43105
+ function stringifyFunctionsForTransport(value2, seen = /* @__PURE__ */ new WeakMap()) {
43106
+ if (value2 === null || typeof value2 !== "object") {
43107
+ return typeof value2 === "function" ? value2.toString() : value2;
43108
+ }
43109
+ if (seen.has(value2)) {
43110
+ return seen.get(value2);
43111
+ }
43112
+ const clone = Array.isArray(value2) ? [] : {};
43113
+ seen.set(value2, clone);
43114
+ if (Array.isArray(value2)) {
43115
+ for (let i3 = 0; i3 < value2.length; i3++) {
43116
+ clone[i3] = stringifyFunctionsForTransport(value2[i3], seen);
43117
+ }
43118
+ return clone;
43119
+ }
43120
+ const keys2 = Object.keys(value2);
43121
+ for (let i3 = 0; i3 < keys2.length; i3++) {
43122
+ const key = keys2[i3];
43123
+ if (!FUNCTION_META_KEYS.includes(key)) {
43124
+ clone[key] = stringifyFunctionsForTransport(value2[key], seen);
43125
+ }
43126
+ }
43127
+ return clone;
43128
+ }
43069
43129
  var CollabService = class extends BaseService {
43070
43130
  constructor(config) {
43071
43131
  super(config);
@@ -43374,7 +43434,7 @@ var CollabService = class extends BaseService {
43374
43434
  }
43375
43435
  /* ---------- data helpers ---------- */
43376
43436
  updateData(tuples, options = {}) {
43377
- var _a2, _b, _c;
43437
+ var _a2, _b;
43378
43438
  this._ensureStateManager();
43379
43439
  const { isUndo = false, isRedo = false } = options;
43380
43440
  if (!isUndo && !isRedo && !this._isUndoRedo) {
@@ -43390,21 +43450,10 @@ var CollabService = class extends BaseService {
43390
43450
  processedTuples.push(...options.append);
43391
43451
  }
43392
43452
  this._stateManager.applyChanges(tuples, { ...options });
43393
- const state = (_b = this._stateManager) == null ? void 0 : _b.root;
43394
- const el = state == null ? void 0 : state.__element;
43395
- const stringifiedGranularTuples = (el == null ? void 0 : el.call) ? el.call(
43396
- "deepStringifyFunctions",
43397
- processedTuples,
43398
- Array.isArray(processedTuples) ? [] : {}
43399
- ) : deepStringifyFunctions(
43400
- processedTuples,
43401
- Array.isArray(processedTuples) ? [] : {}
43453
+ const stringifiedGranularTuples = stringifyFunctionsForTransport(
43454
+ processedTuples
43402
43455
  );
43403
- const stringifiedTuples = (el == null ? void 0 : el.call) ? el.call(
43404
- "deepStringifyFunctions",
43405
- tuples,
43406
- Array.isArray(tuples) ? [] : {}
43407
- ) : deepStringifyFunctions(tuples, Array.isArray(tuples) ? [] : {});
43456
+ const stringifiedTuples = stringifyFunctionsForTransport(tuples);
43408
43457
  const { message } = options;
43409
43458
  if (!this.isConnected()) {
43410
43459
  console.warn("[CollabService] Not connected, queuing real-time update");
@@ -43416,7 +43465,7 @@ var CollabService = class extends BaseService {
43416
43465
  });
43417
43466
  return;
43418
43467
  }
43419
- if ((_c = this.socket) == null ? void 0 : _c.connected) {
43468
+ if ((_b = this.socket) == null ? void 0 : _b.connected) {
43420
43469
  const ts = Date.now();
43421
43470
  console.log("[CollabService] Sending operations to the backend", {
43422
43471
  changes: stringifiedTuples,
@@ -24857,14 +24857,14 @@ function computeOrdersForTuples(root, tuples = []) {
24857
24857
  }
24858
24858
  const [action, path] = t;
24859
24859
  const p = normalizePath(path);
24860
- if (!Array.isArray(p) || p.length < 3) {
24860
+ if (!Array.isArray(p) || p.length < 2) {
24861
24861
  continue;
24862
24862
  }
24863
24863
  if (p[0] === "schema") {
24864
24864
  continue;
24865
24865
  }
24866
- const [typeName, containerKey, childKey] = p;
24867
- const containerPath = [typeName, containerKey];
24866
+ const containerPath = p.slice(0, -1);
24867
+ const childKey = p[p.length - 1];
24868
24868
  const key = JSON.stringify(containerPath);
24869
24869
  if (!pendingChildrenByContainer.has(key)) {
24870
24870
  pendingChildrenByContainer.set(key, /* @__PURE__ */ new Set());
@@ -24949,12 +24949,47 @@ function computeOrdersForTuples(root, tuples = []) {
24949
24949
  }
24950
24950
  const pending = pendingChildrenByContainer.get(k);
24951
24951
  if (pending && pending.size) {
24952
- const existing = new Set(v.keys);
24952
+ const existingKeys = v.keys;
24953
+ const existingSet = new Set(existingKeys);
24954
+ const META_KEYS = /* @__PURE__ */ new Set([
24955
+ "style",
24956
+ "class",
24957
+ "text",
24958
+ "html",
24959
+ "content",
24960
+ "data",
24961
+ "attr",
24962
+ "state",
24963
+ "scope",
24964
+ "define",
24965
+ "on",
24966
+ "extend",
24967
+ "extends",
24968
+ "childExtend",
24969
+ "childExtends",
24970
+ "children",
24971
+ "component",
24972
+ "context",
24973
+ "tag",
24974
+ "key",
24975
+ "__order",
24976
+ "if"
24977
+ ]);
24978
+ let firstMetaIndex = existingKeys.length;
24979
+ for (let j = 0; j < existingKeys.length; j++) {
24980
+ if (META_KEYS.has(existingKeys[j])) {
24981
+ firstMetaIndex = j;
24982
+ break;
24983
+ }
24984
+ }
24953
24985
  for (const child of pending) {
24954
- if (existing.has(child)) {
24986
+ if (existingSet.has(child)) {
24955
24987
  continue;
24956
24988
  }
24957
- v.keys.push(child);
24989
+ const insertIndex = firstMetaIndex;
24990
+ existingKeys.splice(insertIndex, 0, child);
24991
+ existingSet.add(child);
24992
+ firstMetaIndex++;
24958
24993
  }
24959
24994
  }
24960
24995
  seen.add(k);
@@ -25141,6 +25176,31 @@ function preprocessChanges(root, tuples = [], options = {}) {
25141
25176
  }
25142
25177
 
25143
25178
  // src/services/CollabService.js
25179
+ var FUNCTION_META_KEYS = ["node", "__ref", "__element", "parent", "parse"];
25180
+ function stringifyFunctionsForTransport(value2, seen = /* @__PURE__ */ new WeakMap()) {
25181
+ if (value2 === null || typeof value2 !== "object") {
25182
+ return typeof value2 === "function" ? value2.toString() : value2;
25183
+ }
25184
+ if (seen.has(value2)) {
25185
+ return seen.get(value2);
25186
+ }
25187
+ const clone = Array.isArray(value2) ? [] : {};
25188
+ seen.set(value2, clone);
25189
+ if (Array.isArray(value2)) {
25190
+ for (let i = 0; i < value2.length; i++) {
25191
+ clone[i] = stringifyFunctionsForTransport(value2[i], seen);
25192
+ }
25193
+ return clone;
25194
+ }
25195
+ const keys2 = Object.keys(value2);
25196
+ for (let i = 0; i < keys2.length; i++) {
25197
+ const key = keys2[i];
25198
+ if (!FUNCTION_META_KEYS.includes(key)) {
25199
+ clone[key] = stringifyFunctionsForTransport(value2[key], seen);
25200
+ }
25201
+ }
25202
+ return clone;
25203
+ }
25144
25204
  var CollabService = class extends BaseService {
25145
25205
  constructor(config) {
25146
25206
  super(config);
@@ -25449,7 +25509,7 @@ var CollabService = class extends BaseService {
25449
25509
  }
25450
25510
  /* ---------- data helpers ---------- */
25451
25511
  updateData(tuples, options = {}) {
25452
- var _a, _b, _c;
25512
+ var _a, _b;
25453
25513
  this._ensureStateManager();
25454
25514
  const { isUndo = false, isRedo = false } = options;
25455
25515
  if (!isUndo && !isRedo && !this._isUndoRedo) {
@@ -25465,21 +25525,10 @@ var CollabService = class extends BaseService {
25465
25525
  processedTuples.push(...options.append);
25466
25526
  }
25467
25527
  this._stateManager.applyChanges(tuples, { ...options });
25468
- const state = (_b = this._stateManager) == null ? void 0 : _b.root;
25469
- const el = state == null ? void 0 : state.__element;
25470
- const stringifiedGranularTuples = (el == null ? void 0 : el.call) ? el.call(
25471
- "deepStringifyFunctions",
25472
- processedTuples,
25473
- Array.isArray(processedTuples) ? [] : {}
25474
- ) : deepStringifyFunctions(
25475
- processedTuples,
25476
- Array.isArray(processedTuples) ? [] : {}
25528
+ const stringifiedGranularTuples = stringifyFunctionsForTransport(
25529
+ processedTuples
25477
25530
  );
25478
- const stringifiedTuples = (el == null ? void 0 : el.call) ? el.call(
25479
- "deepStringifyFunctions",
25480
- tuples,
25481
- Array.isArray(tuples) ? [] : {}
25482
- ) : deepStringifyFunctions(tuples, Array.isArray(tuples) ? [] : {});
25531
+ const stringifiedTuples = stringifyFunctionsForTransport(tuples);
25483
25532
  const { message } = options;
25484
25533
  if (!this.isConnected()) {
25485
25534
  console.warn("[CollabService] Not connected, queuing real-time update");
@@ -25491,7 +25540,7 @@ var CollabService = class extends BaseService {
25491
25540
  });
25492
25541
  return;
25493
25542
  }
25494
- if ((_c = this.socket) == null ? void 0 : _c.connected) {
25543
+ if ((_b = this.socket) == null ? void 0 : _b.connected) {
25495
25544
  const ts = Date.now();
25496
25545
  console.log("[CollabService] Sending operations to the backend", {
25497
25546
  changes: stringifiedTuples,
@@ -926,14 +926,14 @@ function computeOrdersForTuples(root, tuples = []) {
926
926
  }
927
927
  const [action, path] = t;
928
928
  const p = normalizePath(path);
929
- if (!Array.isArray(p) || p.length < 3) {
929
+ if (!Array.isArray(p) || p.length < 2) {
930
930
  continue;
931
931
  }
932
932
  if (p[0] === "schema") {
933
933
  continue;
934
934
  }
935
- const [typeName, containerKey, childKey] = p;
936
- const containerPath = [typeName, containerKey];
935
+ const containerPath = p.slice(0, -1);
936
+ const childKey = p[p.length - 1];
937
937
  const key = JSON.stringify(containerPath);
938
938
  if (!pendingChildrenByContainer.has(key)) {
939
939
  pendingChildrenByContainer.set(key, /* @__PURE__ */ new Set());
@@ -1018,12 +1018,47 @@ function computeOrdersForTuples(root, tuples = []) {
1018
1018
  }
1019
1019
  const pending = pendingChildrenByContainer.get(k);
1020
1020
  if (pending && pending.size) {
1021
- const existing = new Set(v.keys);
1021
+ const existingKeys = v.keys;
1022
+ const existingSet = new Set(existingKeys);
1023
+ const META_KEYS = /* @__PURE__ */ new Set([
1024
+ "style",
1025
+ "class",
1026
+ "text",
1027
+ "html",
1028
+ "content",
1029
+ "data",
1030
+ "attr",
1031
+ "state",
1032
+ "scope",
1033
+ "define",
1034
+ "on",
1035
+ "extend",
1036
+ "extends",
1037
+ "childExtend",
1038
+ "childExtends",
1039
+ "children",
1040
+ "component",
1041
+ "context",
1042
+ "tag",
1043
+ "key",
1044
+ "__order",
1045
+ "if"
1046
+ ]);
1047
+ let firstMetaIndex = existingKeys.length;
1048
+ for (let j = 0; j < existingKeys.length; j++) {
1049
+ if (META_KEYS.has(existingKeys[j])) {
1050
+ firstMetaIndex = j;
1051
+ break;
1052
+ }
1053
+ }
1022
1054
  for (const child of pending) {
1023
- if (existing.has(child)) {
1055
+ if (existingSet.has(child)) {
1024
1056
  continue;
1025
1057
  }
1026
- v.keys.push(child);
1058
+ const insertIndex = firstMetaIndex;
1059
+ existingKeys.splice(insertIndex, 0, child);
1060
+ existingSet.add(child);
1061
+ firstMetaIndex++;
1027
1062
  }
1028
1063
  }
1029
1064
  seen.add(k);
@@ -42782,14 +42782,14 @@ function computeOrdersForTuples(root, tuples = []) {
42782
42782
  }
42783
42783
  const [action, path] = t4;
42784
42784
  const p3 = normalizePath(path);
42785
- if (!Array.isArray(p3) || p3.length < 3) {
42785
+ if (!Array.isArray(p3) || p3.length < 2) {
42786
42786
  continue;
42787
42787
  }
42788
42788
  if (p3[0] === "schema") {
42789
42789
  continue;
42790
42790
  }
42791
- const [typeName, containerKey, childKey] = p3;
42792
- const containerPath = [typeName, containerKey];
42791
+ const containerPath = p3.slice(0, -1);
42792
+ const childKey = p3[p3.length - 1];
42793
42793
  const key = JSON.stringify(containerPath);
42794
42794
  if (!pendingChildrenByContainer.has(key)) {
42795
42795
  pendingChildrenByContainer.set(key, /* @__PURE__ */ new Set());
@@ -42874,12 +42874,47 @@ function computeOrdersForTuples(root, tuples = []) {
42874
42874
  }
42875
42875
  const pending = pendingChildrenByContainer.get(k3);
42876
42876
  if (pending && pending.size) {
42877
- const existing = new Set(v3.keys);
42877
+ const existingKeys = v3.keys;
42878
+ const existingSet = new Set(existingKeys);
42879
+ const META_KEYS = /* @__PURE__ */ new Set([
42880
+ "style",
42881
+ "class",
42882
+ "text",
42883
+ "html",
42884
+ "content",
42885
+ "data",
42886
+ "attr",
42887
+ "state",
42888
+ "scope",
42889
+ "define",
42890
+ "on",
42891
+ "extend",
42892
+ "extends",
42893
+ "childExtend",
42894
+ "childExtends",
42895
+ "children",
42896
+ "component",
42897
+ "context",
42898
+ "tag",
42899
+ "key",
42900
+ "__order",
42901
+ "if"
42902
+ ]);
42903
+ let firstMetaIndex = existingKeys.length;
42904
+ for (let j3 = 0; j3 < existingKeys.length; j3++) {
42905
+ if (META_KEYS.has(existingKeys[j3])) {
42906
+ firstMetaIndex = j3;
42907
+ break;
42908
+ }
42909
+ }
42878
42910
  for (const child of pending) {
42879
- if (existing.has(child)) {
42911
+ if (existingSet.has(child)) {
42880
42912
  continue;
42881
42913
  }
42882
- v3.keys.push(child);
42914
+ const insertIndex = firstMetaIndex;
42915
+ existingKeys.splice(insertIndex, 0, child);
42916
+ existingSet.add(child);
42917
+ firstMetaIndex++;
42883
42918
  }
42884
42919
  }
42885
42920
  seen.add(k3);
@@ -43066,6 +43101,31 @@ function preprocessChanges(root, tuples = [], options = {}) {
43066
43101
  }
43067
43102
 
43068
43103
  // src/services/CollabService.js
43104
+ var FUNCTION_META_KEYS = ["node", "__ref", "__element", "parent", "parse"];
43105
+ function stringifyFunctionsForTransport(value2, seen = /* @__PURE__ */ new WeakMap()) {
43106
+ if (value2 === null || typeof value2 !== "object") {
43107
+ return typeof value2 === "function" ? value2.toString() : value2;
43108
+ }
43109
+ if (seen.has(value2)) {
43110
+ return seen.get(value2);
43111
+ }
43112
+ const clone = Array.isArray(value2) ? [] : {};
43113
+ seen.set(value2, clone);
43114
+ if (Array.isArray(value2)) {
43115
+ for (let i3 = 0; i3 < value2.length; i3++) {
43116
+ clone[i3] = stringifyFunctionsForTransport(value2[i3], seen);
43117
+ }
43118
+ return clone;
43119
+ }
43120
+ const keys2 = Object.keys(value2);
43121
+ for (let i3 = 0; i3 < keys2.length; i3++) {
43122
+ const key = keys2[i3];
43123
+ if (!FUNCTION_META_KEYS.includes(key)) {
43124
+ clone[key] = stringifyFunctionsForTransport(value2[key], seen);
43125
+ }
43126
+ }
43127
+ return clone;
43128
+ }
43069
43129
  var CollabService = class extends BaseService {
43070
43130
  constructor(config) {
43071
43131
  super(config);
@@ -43374,7 +43434,7 @@ var CollabService = class extends BaseService {
43374
43434
  }
43375
43435
  /* ---------- data helpers ---------- */
43376
43436
  updateData(tuples, options = {}) {
43377
- var _a2, _b, _c;
43437
+ var _a2, _b;
43378
43438
  this._ensureStateManager();
43379
43439
  const { isUndo = false, isRedo = false } = options;
43380
43440
  if (!isUndo && !isRedo && !this._isUndoRedo) {
@@ -43390,21 +43450,10 @@ var CollabService = class extends BaseService {
43390
43450
  processedTuples.push(...options.append);
43391
43451
  }
43392
43452
  this._stateManager.applyChanges(tuples, { ...options });
43393
- const state = (_b = this._stateManager) == null ? void 0 : _b.root;
43394
- const el = state == null ? void 0 : state.__element;
43395
- const stringifiedGranularTuples = (el == null ? void 0 : el.call) ? el.call(
43396
- "deepStringifyFunctions",
43397
- processedTuples,
43398
- Array.isArray(processedTuples) ? [] : {}
43399
- ) : deepStringifyFunctions(
43400
- processedTuples,
43401
- Array.isArray(processedTuples) ? [] : {}
43453
+ const stringifiedGranularTuples = stringifyFunctionsForTransport(
43454
+ processedTuples
43402
43455
  );
43403
- const stringifiedTuples = (el == null ? void 0 : el.call) ? el.call(
43404
- "deepStringifyFunctions",
43405
- tuples,
43406
- Array.isArray(tuples) ? [] : {}
43407
- ) : deepStringifyFunctions(tuples, Array.isArray(tuples) ? [] : {});
43456
+ const stringifiedTuples = stringifyFunctionsForTransport(tuples);
43408
43457
  const { message } = options;
43409
43458
  if (!this.isConnected()) {
43410
43459
  console.warn("[CollabService] Not connected, queuing real-time update");
@@ -43416,7 +43465,7 @@ var CollabService = class extends BaseService {
43416
43465
  });
43417
43466
  return;
43418
43467
  }
43419
- if ((_c = this.socket) == null ? void 0 : _c.connected) {
43468
+ if ((_b = this.socket) == null ? void 0 : _b.connected) {
43420
43469
  const ts = Date.now();
43421
43470
  console.log("[CollabService] Sending operations to the backend", {
43422
43471
  changes: stringifiedTuples,
@@ -220,14 +220,14 @@ function computeOrdersForTuples(root, tuples = []) {
220
220
  }
221
221
  const [action, path] = t;
222
222
  const p = normalizePath(path);
223
- if (!Array.isArray(p) || p.length < 3) {
223
+ if (!Array.isArray(p) || p.length < 2) {
224
224
  continue;
225
225
  }
226
226
  if (p[0] === "schema") {
227
227
  continue;
228
228
  }
229
- const [typeName, containerKey, childKey] = p;
230
- const containerPath = [typeName, containerKey];
229
+ const containerPath = p.slice(0, -1);
230
+ const childKey = p[p.length - 1];
231
231
  const key = JSON.stringify(containerPath);
232
232
  if (!pendingChildrenByContainer.has(key)) {
233
233
  pendingChildrenByContainer.set(key, /* @__PURE__ */ new Set());
@@ -312,12 +312,47 @@ function computeOrdersForTuples(root, tuples = []) {
312
312
  }
313
313
  const pending = pendingChildrenByContainer.get(k);
314
314
  if (pending && pending.size) {
315
- const existing = new Set(v.keys);
315
+ const existingKeys = v.keys;
316
+ const existingSet = new Set(existingKeys);
317
+ const META_KEYS = /* @__PURE__ */ new Set([
318
+ "style",
319
+ "class",
320
+ "text",
321
+ "html",
322
+ "content",
323
+ "data",
324
+ "attr",
325
+ "state",
326
+ "scope",
327
+ "define",
328
+ "on",
329
+ "extend",
330
+ "extends",
331
+ "childExtend",
332
+ "childExtends",
333
+ "children",
334
+ "component",
335
+ "context",
336
+ "tag",
337
+ "key",
338
+ "__order",
339
+ "if"
340
+ ]);
341
+ let firstMetaIndex = existingKeys.length;
342
+ for (let j = 0; j < existingKeys.length; j++) {
343
+ if (META_KEYS.has(existingKeys[j])) {
344
+ firstMetaIndex = j;
345
+ break;
346
+ }
347
+ }
316
348
  for (const child of pending) {
317
- if (existing.has(child)) {
349
+ if (existingSet.has(child)) {
318
350
  continue;
319
351
  }
320
- v.keys.push(child);
352
+ const insertIndex = firstMetaIndex;
353
+ existingKeys.splice(insertIndex, 0, child);
354
+ existingSet.add(child);
355
+ firstMetaIndex++;
321
356
  }
322
357
  }
323
358
  seen.add(k);
@@ -144,14 +144,14 @@ function computeOrdersForTuples(root, tuples = []) {
144
144
  }
145
145
  const [action, path] = t;
146
146
  const p = normalizePath(path);
147
- if (!Array.isArray(p) || p.length < 3) {
147
+ if (!Array.isArray(p) || p.length < 2) {
148
148
  continue;
149
149
  }
150
150
  if (p[0] === "schema") {
151
151
  continue;
152
152
  }
153
- const [typeName, containerKey, childKey] = p;
154
- const containerPath = [typeName, containerKey];
153
+ const containerPath = p.slice(0, -1);
154
+ const childKey = p[p.length - 1];
155
155
  const key = JSON.stringify(containerPath);
156
156
  if (!pendingChildrenByContainer.has(key)) {
157
157
  pendingChildrenByContainer.set(key, /* @__PURE__ */ new Set());
@@ -236,12 +236,47 @@ function computeOrdersForTuples(root, tuples = []) {
236
236
  }
237
237
  const pending = pendingChildrenByContainer.get(k);
238
238
  if (pending && pending.size) {
239
- const existing = new Set(v.keys);
239
+ const existingKeys = v.keys;
240
+ const existingSet = new Set(existingKeys);
241
+ const META_KEYS = /* @__PURE__ */ new Set([
242
+ "style",
243
+ "class",
244
+ "text",
245
+ "html",
246
+ "content",
247
+ "data",
248
+ "attr",
249
+ "state",
250
+ "scope",
251
+ "define",
252
+ "on",
253
+ "extend",
254
+ "extends",
255
+ "childExtend",
256
+ "childExtends",
257
+ "children",
258
+ "component",
259
+ "context",
260
+ "tag",
261
+ "key",
262
+ "__order",
263
+ "if"
264
+ ]);
265
+ let firstMetaIndex = existingKeys.length;
266
+ for (let j = 0; j < existingKeys.length; j++) {
267
+ if (META_KEYS.has(existingKeys[j])) {
268
+ firstMetaIndex = j;
269
+ break;
270
+ }
271
+ }
240
272
  for (const child of pending) {
241
- if (existing.has(child)) {
273
+ if (existingSet.has(child)) {
242
274
  continue;
243
275
  }
244
- v.keys.push(child);
276
+ const insertIndex = firstMetaIndex;
277
+ existingKeys.splice(insertIndex, 0, child);
278
+ existingSet.add(child);
279
+ firstMetaIndex++;
245
280
  }
246
281
  }
247
282
  seen.add(k);
@@ -5,6 +5,31 @@ import { rootBus } from "../state/rootEventBus.js";
5
5
  import { validateParams } from "../utils/validation.js";
6
6
  import { deepStringifyFunctions } from "@domql/utils";
7
7
  import { preprocessChanges } from "../utils/changePreprocessor.js";
8
+ const FUNCTION_META_KEYS = ["node", "__ref", "__element", "parent", "parse"];
9
+ function stringifyFunctionsForTransport(value, seen = /* @__PURE__ */ new WeakMap()) {
10
+ if (value === null || typeof value !== "object") {
11
+ return typeof value === "function" ? value.toString() : value;
12
+ }
13
+ if (seen.has(value)) {
14
+ return seen.get(value);
15
+ }
16
+ const clone = Array.isArray(value) ? [] : {};
17
+ seen.set(value, clone);
18
+ if (Array.isArray(value)) {
19
+ for (let i = 0; i < value.length; i++) {
20
+ clone[i] = stringifyFunctionsForTransport(value[i], seen);
21
+ }
22
+ return clone;
23
+ }
24
+ const keys = Object.keys(value);
25
+ for (let i = 0; i < keys.length; i++) {
26
+ const key = keys[i];
27
+ if (!FUNCTION_META_KEYS.includes(key)) {
28
+ clone[key] = stringifyFunctionsForTransport(value[key], seen);
29
+ }
30
+ }
31
+ return clone;
32
+ }
8
33
  class CollabService extends BaseService {
9
34
  constructor(config) {
10
35
  super(config);
@@ -313,7 +338,7 @@ class CollabService extends BaseService {
313
338
  }
314
339
  /* ---------- data helpers ---------- */
315
340
  updateData(tuples, options = {}) {
316
- var _a, _b, _c;
341
+ var _a, _b;
317
342
  this._ensureStateManager();
318
343
  const { isUndo = false, isRedo = false } = options;
319
344
  if (!isUndo && !isRedo && !this._isUndoRedo) {
@@ -329,21 +354,10 @@ class CollabService extends BaseService {
329
354
  processedTuples.push(...options.append);
330
355
  }
331
356
  this._stateManager.applyChanges(tuples, { ...options });
332
- const state = (_b = this._stateManager) == null ? void 0 : _b.root;
333
- const el = state == null ? void 0 : state.__element;
334
- const stringifiedGranularTuples = (el == null ? void 0 : el.call) ? el.call(
335
- "deepStringifyFunctions",
336
- processedTuples,
337
- Array.isArray(processedTuples) ? [] : {}
338
- ) : deepStringifyFunctions(
339
- processedTuples,
340
- Array.isArray(processedTuples) ? [] : {}
357
+ const stringifiedGranularTuples = stringifyFunctionsForTransport(
358
+ processedTuples
341
359
  );
342
- const stringifiedTuples = (el == null ? void 0 : el.call) ? el.call(
343
- "deepStringifyFunctions",
344
- tuples,
345
- Array.isArray(tuples) ? [] : {}
346
- ) : deepStringifyFunctions(tuples, Array.isArray(tuples) ? [] : {});
360
+ const stringifiedTuples = stringifyFunctionsForTransport(tuples);
347
361
  const { message } = options;
348
362
  if (!this.isConnected()) {
349
363
  console.warn("[CollabService] Not connected, queuing real-time update");
@@ -355,7 +369,7 @@ class CollabService extends BaseService {
355
369
  });
356
370
  return;
357
371
  }
358
- if ((_c = this.socket) == null ? void 0 : _c.connected) {
372
+ if ((_b = this.socket) == null ? void 0 : _b.connected) {
359
373
  const ts = Date.now();
360
374
  console.log("[CollabService] Sending operations to the backend", {
361
375
  changes: stringifiedTuples,
@@ -143,14 +143,14 @@ function computeOrdersForTuples(root, tuples = []) {
143
143
  }
144
144
  const [action, path] = t;
145
145
  const p = normalizePath(path);
146
- if (!Array.isArray(p) || p.length < 3) {
146
+ if (!Array.isArray(p) || p.length < 2) {
147
147
  continue;
148
148
  }
149
149
  if (p[0] === "schema") {
150
150
  continue;
151
151
  }
152
- const [typeName, containerKey, childKey] = p;
153
- const containerPath = [typeName, containerKey];
152
+ const containerPath = p.slice(0, -1);
153
+ const childKey = p[p.length - 1];
154
154
  const key = JSON.stringify(containerPath);
155
155
  if (!pendingChildrenByContainer.has(key)) {
156
156
  pendingChildrenByContainer.set(key, /* @__PURE__ */ new Set());
@@ -235,12 +235,47 @@ function computeOrdersForTuples(root, tuples = []) {
235
235
  }
236
236
  const pending = pendingChildrenByContainer.get(k);
237
237
  if (pending && pending.size) {
238
- const existing = new Set(v.keys);
238
+ const existingKeys = v.keys;
239
+ const existingSet = new Set(existingKeys);
240
+ const META_KEYS = /* @__PURE__ */ new Set([
241
+ "style",
242
+ "class",
243
+ "text",
244
+ "html",
245
+ "content",
246
+ "data",
247
+ "attr",
248
+ "state",
249
+ "scope",
250
+ "define",
251
+ "on",
252
+ "extend",
253
+ "extends",
254
+ "childExtend",
255
+ "childExtends",
256
+ "children",
257
+ "component",
258
+ "context",
259
+ "tag",
260
+ "key",
261
+ "__order",
262
+ "if"
263
+ ]);
264
+ let firstMetaIndex = existingKeys.length;
265
+ for (let j = 0; j < existingKeys.length; j++) {
266
+ if (META_KEYS.has(existingKeys[j])) {
267
+ firstMetaIndex = j;
268
+ break;
269
+ }
270
+ }
239
271
  for (const child of pending) {
240
- if (existing.has(child)) {
272
+ if (existingSet.has(child)) {
241
273
  continue;
242
274
  }
243
- v.keys.push(child);
275
+ const insertIndex = firstMetaIndex;
276
+ existingKeys.splice(insertIndex, 0, child);
277
+ existingSet.add(child);
278
+ firstMetaIndex++;
244
279
  }
245
280
  }
246
281
  seen.add(k);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbo.ls/sdk",
3
- "version": "2.32.30",
3
+ "version": "2.33.2",
4
4
  "type": "module",
5
5
  "main": "dist/esm/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -46,12 +46,12 @@
46
46
  "test:user": "cross-env NODE_ENV=$NODE_ENV npx tape integration-tests/index.js integration-tests/user/*.test.js | tap-spec"
47
47
  },
48
48
  "dependencies": {
49
- "@domql/element": "^2.32.30",
50
- "@domql/utils": "^2.32.30",
49
+ "@domql/element": "^2.33.2",
50
+ "@domql/utils": "^2.33.2",
51
51
  "@grafana/faro-web-sdk": "^1.19.0",
52
52
  "@grafana/faro-web-tracing": "^1.19.0",
53
- "@symbo.ls/router": "^2.32.30",
54
- "@symbo.ls/socket": "^2.32.30",
53
+ "@symbo.ls/router": "^2.33.2",
54
+ "@symbo.ls/socket": "^2.33.2",
55
55
  "acorn": "^8.14.0",
56
56
  "acorn-walk": "^8.3.4",
57
57
  "dexie": "^4.0.11",
@@ -73,5 +73,5 @@
73
73
  "tap-spec": "^5.0.0",
74
74
  "tape": "^5.9.0"
75
75
  },
76
- "gitHead": "1f4b829d823a7b42486c0e8f7dca5660bf466c19"
76
+ "gitHead": "57240a2eaa9945f0e889bd40005e331b602c467b"
77
77
  }
@@ -6,6 +6,41 @@ import { validateParams } from '../utils/validation.js'
6
6
  import { deepStringifyFunctions } from '@domql/utils'
7
7
  import { preprocessChanges } from '../utils/changePreprocessor.js'
8
8
 
9
+ // Helper: clone a value while converting all functions to strings. This is
10
+ // tailored for collab payloads (tuples / granularChanges) and is more robust
11
+ // for nested array shapes than the generic DOMQL helper.
12
+ const FUNCTION_META_KEYS = ['node', '__ref', '__element', 'parent', 'parse']
13
+
14
+ function stringifyFunctionsForTransport (value, seen = new WeakMap()) {
15
+ if (value === null || typeof value !== 'object') {
16
+ return typeof value === 'function' ? value.toString() : value
17
+ }
18
+
19
+ if (seen.has(value)) {
20
+ return seen.get(value)
21
+ }
22
+
23
+ const clone = Array.isArray(value) ? [] : {}
24
+ seen.set(value, clone)
25
+
26
+ if (Array.isArray(value)) {
27
+ for (let i = 0; i < value.length; i++) {
28
+ clone[i] = stringifyFunctionsForTransport(value[i], seen)
29
+ }
30
+ return clone
31
+ }
32
+
33
+ const keys = Object.keys(value)
34
+ for (let i = 0; i < keys.length; i++) {
35
+ const key = keys[i]
36
+ if (!FUNCTION_META_KEYS.includes(key)) {
37
+ clone[key] = stringifyFunctionsForTransport(value[key], seen)
38
+ }
39
+ }
40
+
41
+ return clone
42
+ }
43
+
9
44
  export class CollabService extends BaseService {
10
45
  constructor(config) {
11
46
  super(config)
@@ -410,29 +445,13 @@ export class CollabService extends BaseService {
410
445
  // Apply changes to local state tree immediately.
411
446
  this._stateManager.applyChanges(tuples, { ...options })
412
447
 
413
- const state = this._stateManager?.root
414
- const el = state?.__element
415
-
416
- // orders already derived by preprocessor
417
-
418
- const stringifiedGranularTuples = el?.call
419
- ? el.call(
420
- 'deepStringifyFunctions',
421
- processedTuples,
422
- Array.isArray(processedTuples) ? [] : {}
423
- )
424
- : deepStringifyFunctions(
425
- processedTuples,
426
- Array.isArray(processedTuples) ? [] : {}
427
- )
448
+ // Use a dedicated helper that correctly handles nested array structures
449
+ // such as granular tuples while also avoiding DOM / state metadata keys.
450
+ const stringifiedGranularTuples = stringifyFunctionsForTransport(
451
+ processedTuples
452
+ )
428
453
 
429
- const stringifiedTuples = el?.call
430
- ? el.call(
431
- 'deepStringifyFunctions',
432
- tuples,
433
- Array.isArray(tuples) ? [] : {}
434
- )
435
- : deepStringifyFunctions(tuples, Array.isArray(tuples) ? [] : {})
454
+ const stringifiedTuples = stringifyFunctionsForTransport(tuples)
436
455
 
437
456
  const { message } = options
438
457
 
@@ -125,20 +125,24 @@ function extractTopLevelKeysFromCode (code) {
125
125
 
126
126
  export function computeOrdersForTuples (root, tuples = []) {
127
127
  // Pre-scan tuples to collect child keys that will be added/updated for each
128
- // data container (e.g. ['pages', '/']). This lets us include keys created in
129
- // the same batch even if they are not yet present in the state object when
130
- // we compute orders.
128
+ // container object. This lets us include keys created in the same batch even
129
+ // if they are not yet present in the state object when we compute orders.
131
130
  const pendingChildrenByContainer = new Map()
132
131
  for (let i = 0; i < tuples.length; i++) {
133
132
  const t = tuples[i]
134
133
  if (!Array.isArray(t)) { continue }
135
134
  const [action, path] = t
136
135
  const p = normalizePath(path)
137
- if (!Array.isArray(p) || p.length < 3) { continue }
136
+ if (!Array.isArray(p) || p.length < 2) { continue }
138
137
  // Ignore schema edits here – we want actual data container child keys
139
138
  if (p[0] === 'schema') { continue }
140
- const [typeName, containerKey, childKey] = p
141
- const containerPath = [typeName, containerKey]
139
+
140
+ // Treat the immediate parent as the container and the final segment as the
141
+ // child key, regardless of depth. This ensures nested containers such as
142
+ // ['components', 'Comp1', 'MainContent', 'TXButton'] correctly record
143
+ // 'TXButton' as a child of ['components', 'Comp1', 'MainContent'].
144
+ const containerPath = p.slice(0, -1)
145
+ const childKey = p[p.length - 1]
142
146
  const key = JSON.stringify(containerPath)
143
147
  if (!pendingChildrenByContainer.has(key)) {
144
148
  pendingChildrenByContainer.set(key, new Set())
@@ -228,10 +232,33 @@ export function computeOrdersForTuples (root, tuples = []) {
228
232
  // Merge in any pending children (for containers without schema edits)
229
233
  const pending = pendingChildrenByContainer.get(k)
230
234
  if (pending && pending.size) {
231
- const existing = new Set(v.keys)
235
+ const existingKeys = v.keys
236
+ const existingSet = new Set(existingKeys)
237
+
238
+ // Meta keys such as 'props' and 'text' should typically stay at the end
239
+ // of the order. When inserting brand-new children we try to place them
240
+ // before the first meta key so that structural children appear first.
241
+ const META_KEYS = new Set([
242
+ 'style', 'class', 'text', 'html', 'content', 'data', 'attr', 'state', 'scope',
243
+ 'define', 'on', 'extend', 'extends', 'childExtend', 'childExtends',
244
+ 'children', 'component', 'context', 'tag', 'key', '__order', 'if'
245
+ ])
246
+
247
+ let firstMetaIndex = existingKeys.length
248
+ for (let j = 0; j < existingKeys.length; j++) {
249
+ if (META_KEYS.has(existingKeys[j])) {
250
+ firstMetaIndex = j
251
+ break
252
+ }
253
+ }
254
+
232
255
  for (const child of pending) {
233
- if (existing.has(child)) { continue }
234
- v.keys.push(child)
256
+ if (existingSet.has(child)) { continue }
257
+ const insertIndex = firstMetaIndex
258
+ existingKeys.splice(insertIndex, 0, child)
259
+ existingSet.add(child)
260
+ // Keep subsequent new children grouped together in front of meta keys
261
+ firstMetaIndex++
235
262
  }
236
263
  }
237
264
  seen.add(k)