@symbo.ls/sdk 2.32.1 → 2.32.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.
package/dist/esm/index.js CHANGED
@@ -21885,12 +21885,54 @@ function isPlainObject(o) {
21885
21885
  return o && typeof o === "object" && !Array.isArray(o);
21886
21886
  }
21887
21887
  function deepEqual(a, b) {
21888
- try {
21889
- return JSON.stringify(a) === JSON.stringify(b);
21890
- } catch (err) {
21891
- console.warn("deepEqual error", err);
21888
+ if (Object.is(a, b)) {
21889
+ return true;
21890
+ }
21891
+ if (typeof a === "function" && typeof b === "function") {
21892
+ try {
21893
+ return a.toString() === b.toString();
21894
+ } catch {
21895
+ return false;
21896
+ }
21897
+ }
21898
+ if (typeof a === "function" || typeof b === "function") {
21892
21899
  return false;
21893
21900
  }
21901
+ if (a instanceof Date && b instanceof Date) {
21902
+ return a.getTime() === b.getTime();
21903
+ }
21904
+ if (a instanceof RegExp && b instanceof RegExp) {
21905
+ return String(a) === String(b);
21906
+ }
21907
+ if (Array.isArray(a) && Array.isArray(b)) {
21908
+ if (a.length !== b.length) {
21909
+ return false;
21910
+ }
21911
+ for (let i = 0; i < a.length; i++) {
21912
+ if (!deepEqual(a[i], b[i])) {
21913
+ return false;
21914
+ }
21915
+ }
21916
+ return true;
21917
+ }
21918
+ if (a && b && typeof a === "object" && typeof b === "object") {
21919
+ const aKeys = Object.keys(a);
21920
+ const bKeys = Object.keys(b);
21921
+ if (aKeys.length !== bKeys.length) {
21922
+ return false;
21923
+ }
21924
+ for (let i = 0; i < aKeys.length; i++) {
21925
+ const key = aKeys[i];
21926
+ if (!Object.hasOwn(b, key)) {
21927
+ return false;
21928
+ }
21929
+ if (!deepEqual(a[key], b[key])) {
21930
+ return false;
21931
+ }
21932
+ }
21933
+ return true;
21934
+ }
21935
+ return false;
21894
21936
  }
21895
21937
  function getRootMap(ydoc) {
21896
21938
  return ydoc.getMap("root");
@@ -28297,14 +28339,12 @@ function getParentPathsFromTuples(tuples = []) {
28297
28339
  "attr",
28298
28340
  "state",
28299
28341
  "scope",
28300
- "props",
28301
28342
  "define",
28302
28343
  "on",
28303
28344
  "extend",
28304
28345
  "extends",
28305
28346
  "childExtend",
28306
28347
  "childExtends",
28307
- "childProps",
28308
28348
  "children",
28309
28349
  "component",
28310
28350
  "context",
@@ -28525,6 +28565,118 @@ function computeOrdersForTuples(root, tuples = []) {
28525
28565
  return orders;
28526
28566
  }
28527
28567
 
28568
+ // src/utils/changePreprocessor.js
28569
+ function isPlainObject2(val) {
28570
+ return val && typeof val === "object" && !Array.isArray(val);
28571
+ }
28572
+ function getByPathSafe(root, path) {
28573
+ if (!root || typeof root.getByPath !== "function") {
28574
+ return null;
28575
+ }
28576
+ try {
28577
+ return root.getByPath(path);
28578
+ } catch {
28579
+ return null;
28580
+ }
28581
+ }
28582
+ function preprocessChanges(root, tuples = [], options = {}) {
28583
+ const expandTuple = (t) => {
28584
+ const [action, path, value2] = t || [];
28585
+ const isSchemaPath = Array.isArray(path) && path[0] === "schema";
28586
+ if (action === "delete") {
28587
+ return [t];
28588
+ }
28589
+ const canConsiderExpansion = action === "update" && Array.isArray(path) && (path.length === 1 || path.length === 2 || isSchemaPath && path.length === 3) && isPlainObject2(value2);
28590
+ if (!canConsiderExpansion) {
28591
+ return [t];
28592
+ }
28593
+ const prev = getByPathSafe(root, path) || {};
28594
+ const next = value2 || {};
28595
+ if (!isPlainObject2(prev) || !isPlainObject2(next)) {
28596
+ return [t];
28597
+ }
28598
+ const ops = diffJson(prev, next, []);
28599
+ if (!ops.length) {
28600
+ return [t];
28601
+ }
28602
+ const out = [];
28603
+ for (let i = 0; i < ops.length; i++) {
28604
+ const op = ops[i];
28605
+ const fullPath = [...path, ...op.path];
28606
+ const last2 = fullPath[fullPath.length - 1];
28607
+ if (op.action === "set") {
28608
+ out.push(["update", fullPath, op.value]);
28609
+ } else if (op.action === "del") {
28610
+ if (last2 !== "__order") {
28611
+ out.push(["delete", fullPath]);
28612
+ }
28613
+ }
28614
+ }
28615
+ return out;
28616
+ };
28617
+ const minimizeTuples = (input) => {
28618
+ const out = [];
28619
+ const seen2 = /* @__PURE__ */ new Set();
28620
+ for (let i = 0; i < input.length; i++) {
28621
+ const expanded = expandTuple(input[i]);
28622
+ for (let k = 0; k < expanded.length; k++) {
28623
+ const tuple = expanded[k];
28624
+ const isDelete = Array.isArray(tuple) && tuple[0] === "delete";
28625
+ const isOrderKey = isDelete && Array.isArray(tuple[1]) && tuple[1][tuple[1].length - 1] === "__order";
28626
+ if (!isOrderKey) {
28627
+ const key = JSON.stringify(tuple);
28628
+ if (!seen2.has(key)) {
28629
+ seen2.add(key);
28630
+ out.push(tuple);
28631
+ }
28632
+ }
28633
+ }
28634
+ }
28635
+ return out;
28636
+ };
28637
+ const granularChanges = (() => {
28638
+ try {
28639
+ const res = minimizeTuples(tuples);
28640
+ if (options.append && options.append.length) {
28641
+ res.push(...options.append);
28642
+ }
28643
+ return res;
28644
+ } catch {
28645
+ return Array.isArray(tuples) ? tuples.slice() : [];
28646
+ }
28647
+ })();
28648
+ const baseOrders = computeOrdersForTuples(root, granularChanges);
28649
+ const preferOrdersMap = /* @__PURE__ */ new Map();
28650
+ for (let i = 0; i < tuples.length; i++) {
28651
+ const t = tuples[i];
28652
+ if (!Array.isArray(t) || t.length < 3) {
28653
+ continue;
28654
+ }
28655
+ const [action, path, value2] = t;
28656
+ if (action !== "update" || !Array.isArray(path) || path.length !== 1 && path.length !== 2 || !isPlainObject2(value2)) {
28657
+ continue;
28658
+ }
28659
+ const keys2 = Object.keys(value2).filter((k) => k !== "__order");
28660
+ const key = JSON.stringify(path);
28661
+ preferOrdersMap.set(key, { path, keys: keys2 });
28662
+ }
28663
+ const mergedOrders = [];
28664
+ const seen = /* @__PURE__ */ new Set();
28665
+ preferOrdersMap.forEach((v, k) => {
28666
+ seen.add(k);
28667
+ mergedOrders.push(v);
28668
+ });
28669
+ for (let i = 0; i < baseOrders.length; i++) {
28670
+ const v = baseOrders[i];
28671
+ const k = JSON.stringify(v.path);
28672
+ if (!seen.has(k)) {
28673
+ seen.add(k);
28674
+ mergedOrders.push(v);
28675
+ }
28676
+ }
28677
+ return { granularChanges, orders: mergedOrders };
28678
+ }
28679
+
28528
28680
  // src/services/CollabService.js
28529
28681
  var CollabService = class extends BaseService {
28530
28682
  constructor(config) {
@@ -28662,8 +28814,8 @@ var CollabService = class extends BaseService {
28662
28814
  console.log(
28663
28815
  `[CollabService] Flushing ${this._pendingOps.length} offline operation batch(es)`
28664
28816
  );
28665
- this._pendingOps.forEach(({ changes, orders }) => {
28666
- this.socket.emit("ops", { changes, orders, ts: Date.now() });
28817
+ this._pendingOps.forEach(({ changes, granularChanges, orders }) => {
28818
+ this.socket.emit("ops", { changes, granularChanges, orders, ts: Date.now() });
28667
28819
  });
28668
28820
  this._pendingOps.length = 0;
28669
28821
  }
@@ -28705,94 +28857,24 @@ var CollabService = class extends BaseService {
28705
28857
  }
28706
28858
  /* ---------- data helpers ---------- */
28707
28859
  updateData(tuples, options = {}) {
28708
- var _a, _b;
28860
+ var _a, _b, _c;
28709
28861
  this._ensureStateManager();
28710
28862
  const { isUndo = false, isRedo = false } = options;
28711
28863
  if (!isUndo && !isRedo && !this._isUndoRedo) {
28712
28864
  this._trackForUndo(tuples, options);
28713
28865
  }
28714
- const processedTuples = (() => {
28715
- var _a2;
28716
- try {
28717
- const root = (_a2 = this._stateManager) == null ? void 0 : _a2.root;
28718
- const isPlainObject2 = (o) => o && typeof o === "object" && !Array.isArray(o);
28719
- const getByPath = (state2, path) => {
28720
- if (!state2 || typeof state2.getByPath !== "function") {
28721
- return null;
28722
- }
28723
- try {
28724
- return state2.getByPath(path);
28725
- } catch {
28726
- return null;
28727
- }
28728
- };
28729
- const expandTuple = (t) => {
28730
- const [action, path, value2] = t || [];
28731
- const isSchemaPath = Array.isArray(path) && path[0] === "schema";
28732
- if (action === "delete" || isSchemaPath) {
28733
- return [t];
28734
- }
28735
- const canConsiderExpansion = action === "update" && Array.isArray(path) && (path.length === 1 || path.length === 2) && isPlainObject2(value2);
28736
- if (!canConsiderExpansion) {
28737
- return [t];
28738
- }
28739
- const prev = getByPath(root, path) || {};
28740
- const next = value2 || {};
28741
- if (!isPlainObject2(prev) || !isPlainObject2(next)) {
28742
- return [t];
28743
- }
28744
- const ops = diffJson(prev, next, []);
28745
- if (!ops.length) {
28746
- return [];
28747
- }
28748
- const arr = [];
28749
- for (let j = 0; j < ops.length; j++) {
28750
- const op = ops[j];
28751
- const fullPath = [...path, ...op.path];
28752
- const last2 = fullPath[fullPath.length - 1];
28753
- if (op.action === "set") {
28754
- arr.push(["update", fullPath, op.value]);
28755
- } else if (op.action === "del") {
28756
- if (last2 !== "__order") {
28757
- arr.push(["delete", fullPath]);
28758
- }
28759
- }
28760
- }
28761
- return arr;
28762
- };
28763
- const minimizeTuples = (inputTuples) => {
28764
- const out = [];
28765
- for (let i = 0; i < inputTuples.length; i++) {
28766
- const expanded = expandTuple(inputTuples[i]);
28767
- for (let k = 0; k < expanded.length; k++) {
28768
- const tuple = expanded[k];
28769
- const isDelete = Array.isArray(tuple) && tuple[0] === "delete";
28770
- const isOrderKey = isDelete && Array.isArray(tuple[1]) && tuple[1][tuple[1].length - 1] === "__order";
28771
- if (!isOrderKey) {
28772
- out.push(tuple);
28773
- }
28774
- }
28775
- }
28776
- console.log(`Minimized tuples`, out);
28777
- return out;
28778
- };
28779
- console.log(`Processing tuples`, tuples);
28780
- return minimizeTuples(tuples);
28781
- } catch (err) {
28782
- console.warn(
28783
- "[CollabService] Minimal diff expansion failed \u2013 using original tuples",
28784
- err
28785
- );
28786
- return tuples;
28787
- }
28788
- })();
28866
+ const root = (_a = this._stateManager) == null ? void 0 : _a.root;
28867
+ const { granularChanges: processedTuples, orders } = preprocessChanges(
28868
+ root,
28869
+ tuples,
28870
+ options
28871
+ );
28789
28872
  if (options.append && options.append.length) {
28790
28873
  processedTuples.push(...options.append);
28791
28874
  }
28792
28875
  this._stateManager.applyChanges(tuples, { ...options });
28793
- const state = (_a = this._stateManager) == null ? void 0 : _a.root;
28876
+ const state = (_b = this._stateManager) == null ? void 0 : _b.root;
28794
28877
  const el = state == null ? void 0 : state.__element;
28795
- const orders = computeOrdersForTuples(state, processedTuples);
28796
28878
  const stringifiedGranularTuples = (el == null ? void 0 : el.call) ? el.call(
28797
28879
  "deepStringifyFunctions",
28798
28880
  processedTuples,
@@ -28805,16 +28887,18 @@ var CollabService = class extends BaseService {
28805
28887
  "deepStringifyFunctions",
28806
28888
  tuples,
28807
28889
  Array.isArray(tuples) ? [] : {}
28808
- ) : deepStringifyFunctions(
28809
- tuples,
28810
- Array.isArray(tuples) ? [] : {}
28811
- );
28890
+ ) : deepStringifyFunctions(tuples, Array.isArray(tuples) ? [] : {});
28812
28891
  if (!this.isConnected()) {
28813
28892
  console.warn("[CollabService] Not connected, queuing real-time update");
28814
- this._pendingOps.push({ changes: stringifiedTuples, granularChanges: stringifiedGranularTuples, orders, options });
28893
+ this._pendingOps.push({
28894
+ changes: stringifiedTuples,
28895
+ granularChanges: stringifiedGranularTuples,
28896
+ orders,
28897
+ options
28898
+ });
28815
28899
  return;
28816
28900
  }
28817
- if ((_b = this.socket) == null ? void 0 : _b.connected) {
28901
+ if ((_c = this.socket) == null ? void 0 : _c.connected) {
28818
28902
  console.log("[CollabService] Sending operations to the backend", {
28819
28903
  changes: stringifiedTuples,
28820
28904
  granularChanges: stringifiedGranularTuples,
@@ -29140,6 +29224,7 @@ var CollabService = class extends BaseService {
29140
29224
  };
29141
29225
 
29142
29226
  // src/services/ProjectService.js
29227
+ import { deepStringifyFunctions as deepStringifyFunctions2 } from "@domql/utils";
29143
29228
  var ProjectService = class extends BaseService {
29144
29229
  // ==================== PROJECT METHODS ====================
29145
29230
  async createProject(projectData) {
@@ -29672,12 +29757,15 @@ var ProjectService = class extends BaseService {
29672
29757
  }
29673
29758
  const { message, branch = "main", type = "patch" } = options;
29674
29759
  const state = this._context && this._context.state;
29675
- const derivedOrders = options.orders || (state ? computeOrdersForTuples(state, changes) : []);
29760
+ const { granularChanges, orders: preprocessorOrders } = preprocessChanges(state, changes, options);
29761
+ const derivedOrders = options.orders || (preprocessorOrders && preprocessorOrders.length ? preprocessorOrders : state ? computeOrdersForTuples(state, granularChanges) : []);
29762
+ const stringify = (val) => deepStringifyFunctions2(val, Array.isArray(val) ? [] : {});
29676
29763
  try {
29677
29764
  const response = await this._request(`/projects/${projectId}/changes`, {
29678
29765
  method: "POST",
29679
29766
  body: JSON.stringify({
29680
- changes,
29767
+ changes: stringify(changes),
29768
+ granularChanges: stringify(granularChanges),
29681
29769
  message,
29682
29770
  branch,
29683
29771
  type,
@@ -18170,12 +18170,54 @@ function isPlainObject(o) {
18170
18170
  return o && typeof o === "object" && !Array.isArray(o);
18171
18171
  }
18172
18172
  function deepEqual(a, b) {
18173
- try {
18174
- return JSON.stringify(a) === JSON.stringify(b);
18175
- } catch (err) {
18176
- console.warn("deepEqual error", err);
18173
+ if (Object.is(a, b)) {
18174
+ return true;
18175
+ }
18176
+ if (typeof a === "function" && typeof b === "function") {
18177
+ try {
18178
+ return a.toString() === b.toString();
18179
+ } catch {
18180
+ return false;
18181
+ }
18182
+ }
18183
+ if (typeof a === "function" || typeof b === "function") {
18177
18184
  return false;
18178
18185
  }
18186
+ if (a instanceof Date && b instanceof Date) {
18187
+ return a.getTime() === b.getTime();
18188
+ }
18189
+ if (a instanceof RegExp && b instanceof RegExp) {
18190
+ return String(a) === String(b);
18191
+ }
18192
+ if (Array.isArray(a) && Array.isArray(b)) {
18193
+ if (a.length !== b.length) {
18194
+ return false;
18195
+ }
18196
+ for (let i = 0; i < a.length; i++) {
18197
+ if (!deepEqual(a[i], b[i])) {
18198
+ return false;
18199
+ }
18200
+ }
18201
+ return true;
18202
+ }
18203
+ if (a && b && typeof a === "object" && typeof b === "object") {
18204
+ const aKeys = Object.keys(a);
18205
+ const bKeys = Object.keys(b);
18206
+ if (aKeys.length !== bKeys.length) {
18207
+ return false;
18208
+ }
18209
+ for (let i = 0; i < aKeys.length; i++) {
18210
+ const key = aKeys[i];
18211
+ if (!Object.hasOwn(b, key)) {
18212
+ return false;
18213
+ }
18214
+ if (!deepEqual(a[key], b[key])) {
18215
+ return false;
18216
+ }
18217
+ }
18218
+ return true;
18219
+ }
18220
+ return false;
18179
18221
  }
18180
18222
  function getRootMap(ydoc) {
18181
18223
  return ydoc.getMap("root");
@@ -24582,14 +24624,12 @@ function getParentPathsFromTuples(tuples = []) {
24582
24624
  "attr",
24583
24625
  "state",
24584
24626
  "scope",
24585
- "props",
24586
24627
  "define",
24587
24628
  "on",
24588
24629
  "extend",
24589
24630
  "extends",
24590
24631
  "childExtend",
24591
24632
  "childExtends",
24592
- "childProps",
24593
24633
  "children",
24594
24634
  "component",
24595
24635
  "context",
@@ -24810,6 +24850,118 @@ function computeOrdersForTuples(root, tuples = []) {
24810
24850
  return orders;
24811
24851
  }
24812
24852
 
24853
+ // src/utils/changePreprocessor.js
24854
+ function isPlainObject2(val) {
24855
+ return val && typeof val === "object" && !Array.isArray(val);
24856
+ }
24857
+ function getByPathSafe(root, path) {
24858
+ if (!root || typeof root.getByPath !== "function") {
24859
+ return null;
24860
+ }
24861
+ try {
24862
+ return root.getByPath(path);
24863
+ } catch {
24864
+ return null;
24865
+ }
24866
+ }
24867
+ function preprocessChanges(root, tuples = [], options = {}) {
24868
+ const expandTuple = (t) => {
24869
+ const [action, path, value2] = t || [];
24870
+ const isSchemaPath = Array.isArray(path) && path[0] === "schema";
24871
+ if (action === "delete") {
24872
+ return [t];
24873
+ }
24874
+ const canConsiderExpansion = action === "update" && Array.isArray(path) && (path.length === 1 || path.length === 2 || isSchemaPath && path.length === 3) && isPlainObject2(value2);
24875
+ if (!canConsiderExpansion) {
24876
+ return [t];
24877
+ }
24878
+ const prev = getByPathSafe(root, path) || {};
24879
+ const next = value2 || {};
24880
+ if (!isPlainObject2(prev) || !isPlainObject2(next)) {
24881
+ return [t];
24882
+ }
24883
+ const ops = diffJson(prev, next, []);
24884
+ if (!ops.length) {
24885
+ return [t];
24886
+ }
24887
+ const out = [];
24888
+ for (let i = 0; i < ops.length; i++) {
24889
+ const op = ops[i];
24890
+ const fullPath = [...path, ...op.path];
24891
+ const last2 = fullPath[fullPath.length - 1];
24892
+ if (op.action === "set") {
24893
+ out.push(["update", fullPath, op.value]);
24894
+ } else if (op.action === "del") {
24895
+ if (last2 !== "__order") {
24896
+ out.push(["delete", fullPath]);
24897
+ }
24898
+ }
24899
+ }
24900
+ return out;
24901
+ };
24902
+ const minimizeTuples = (input) => {
24903
+ const out = [];
24904
+ const seen2 = /* @__PURE__ */ new Set();
24905
+ for (let i = 0; i < input.length; i++) {
24906
+ const expanded = expandTuple(input[i]);
24907
+ for (let k = 0; k < expanded.length; k++) {
24908
+ const tuple = expanded[k];
24909
+ const isDelete = Array.isArray(tuple) && tuple[0] === "delete";
24910
+ const isOrderKey = isDelete && Array.isArray(tuple[1]) && tuple[1][tuple[1].length - 1] === "__order";
24911
+ if (!isOrderKey) {
24912
+ const key = JSON.stringify(tuple);
24913
+ if (!seen2.has(key)) {
24914
+ seen2.add(key);
24915
+ out.push(tuple);
24916
+ }
24917
+ }
24918
+ }
24919
+ }
24920
+ return out;
24921
+ };
24922
+ const granularChanges = (() => {
24923
+ try {
24924
+ const res = minimizeTuples(tuples);
24925
+ if (options.append && options.append.length) {
24926
+ res.push(...options.append);
24927
+ }
24928
+ return res;
24929
+ } catch {
24930
+ return Array.isArray(tuples) ? tuples.slice() : [];
24931
+ }
24932
+ })();
24933
+ const baseOrders = computeOrdersForTuples(root, granularChanges);
24934
+ const preferOrdersMap = /* @__PURE__ */ new Map();
24935
+ for (let i = 0; i < tuples.length; i++) {
24936
+ const t = tuples[i];
24937
+ if (!Array.isArray(t) || t.length < 3) {
24938
+ continue;
24939
+ }
24940
+ const [action, path, value2] = t;
24941
+ if (action !== "update" || !Array.isArray(path) || path.length !== 1 && path.length !== 2 || !isPlainObject2(value2)) {
24942
+ continue;
24943
+ }
24944
+ const keys2 = Object.keys(value2).filter((k) => k !== "__order");
24945
+ const key = JSON.stringify(path);
24946
+ preferOrdersMap.set(key, { path, keys: keys2 });
24947
+ }
24948
+ const mergedOrders = [];
24949
+ const seen = /* @__PURE__ */ new Set();
24950
+ preferOrdersMap.forEach((v, k) => {
24951
+ seen.add(k);
24952
+ mergedOrders.push(v);
24953
+ });
24954
+ for (let i = 0; i < baseOrders.length; i++) {
24955
+ const v = baseOrders[i];
24956
+ const k = JSON.stringify(v.path);
24957
+ if (!seen.has(k)) {
24958
+ seen.add(k);
24959
+ mergedOrders.push(v);
24960
+ }
24961
+ }
24962
+ return { granularChanges, orders: mergedOrders };
24963
+ }
24964
+
24813
24965
  // src/services/CollabService.js
24814
24966
  var CollabService = class extends BaseService {
24815
24967
  constructor(config) {
@@ -24947,8 +25099,8 @@ var CollabService = class extends BaseService {
24947
25099
  console.log(
24948
25100
  `[CollabService] Flushing ${this._pendingOps.length} offline operation batch(es)`
24949
25101
  );
24950
- this._pendingOps.forEach(({ changes, orders }) => {
24951
- this.socket.emit("ops", { changes, orders, ts: Date.now() });
25102
+ this._pendingOps.forEach(({ changes, granularChanges, orders }) => {
25103
+ this.socket.emit("ops", { changes, granularChanges, orders, ts: Date.now() });
24952
25104
  });
24953
25105
  this._pendingOps.length = 0;
24954
25106
  }
@@ -24990,94 +25142,24 @@ var CollabService = class extends BaseService {
24990
25142
  }
24991
25143
  /* ---------- data helpers ---------- */
24992
25144
  updateData(tuples, options = {}) {
24993
- var _a, _b;
25145
+ var _a, _b, _c;
24994
25146
  this._ensureStateManager();
24995
25147
  const { isUndo = false, isRedo = false } = options;
24996
25148
  if (!isUndo && !isRedo && !this._isUndoRedo) {
24997
25149
  this._trackForUndo(tuples, options);
24998
25150
  }
24999
- const processedTuples = (() => {
25000
- var _a2;
25001
- try {
25002
- const root = (_a2 = this._stateManager) == null ? void 0 : _a2.root;
25003
- const isPlainObject2 = (o) => o && typeof o === "object" && !Array.isArray(o);
25004
- const getByPath = (state2, path) => {
25005
- if (!state2 || typeof state2.getByPath !== "function") {
25006
- return null;
25007
- }
25008
- try {
25009
- return state2.getByPath(path);
25010
- } catch {
25011
- return null;
25012
- }
25013
- };
25014
- const expandTuple = (t) => {
25015
- const [action, path, value2] = t || [];
25016
- const isSchemaPath = Array.isArray(path) && path[0] === "schema";
25017
- if (action === "delete" || isSchemaPath) {
25018
- return [t];
25019
- }
25020
- const canConsiderExpansion = action === "update" && Array.isArray(path) && (path.length === 1 || path.length === 2) && isPlainObject2(value2);
25021
- if (!canConsiderExpansion) {
25022
- return [t];
25023
- }
25024
- const prev = getByPath(root, path) || {};
25025
- const next = value2 || {};
25026
- if (!isPlainObject2(prev) || !isPlainObject2(next)) {
25027
- return [t];
25028
- }
25029
- const ops = diffJson(prev, next, []);
25030
- if (!ops.length) {
25031
- return [];
25032
- }
25033
- const arr = [];
25034
- for (let j = 0; j < ops.length; j++) {
25035
- const op = ops[j];
25036
- const fullPath = [...path, ...op.path];
25037
- const last2 = fullPath[fullPath.length - 1];
25038
- if (op.action === "set") {
25039
- arr.push(["update", fullPath, op.value]);
25040
- } else if (op.action === "del") {
25041
- if (last2 !== "__order") {
25042
- arr.push(["delete", fullPath]);
25043
- }
25044
- }
25045
- }
25046
- return arr;
25047
- };
25048
- const minimizeTuples = (inputTuples) => {
25049
- const out = [];
25050
- for (let i = 0; i < inputTuples.length; i++) {
25051
- const expanded = expandTuple(inputTuples[i]);
25052
- for (let k = 0; k < expanded.length; k++) {
25053
- const tuple = expanded[k];
25054
- const isDelete = Array.isArray(tuple) && tuple[0] === "delete";
25055
- const isOrderKey = isDelete && Array.isArray(tuple[1]) && tuple[1][tuple[1].length - 1] === "__order";
25056
- if (!isOrderKey) {
25057
- out.push(tuple);
25058
- }
25059
- }
25060
- }
25061
- console.log(`Minimized tuples`, out);
25062
- return out;
25063
- };
25064
- console.log(`Processing tuples`, tuples);
25065
- return minimizeTuples(tuples);
25066
- } catch (err) {
25067
- console.warn(
25068
- "[CollabService] Minimal diff expansion failed \u2013 using original tuples",
25069
- err
25070
- );
25071
- return tuples;
25072
- }
25073
- })();
25151
+ const root = (_a = this._stateManager) == null ? void 0 : _a.root;
25152
+ const { granularChanges: processedTuples, orders } = preprocessChanges(
25153
+ root,
25154
+ tuples,
25155
+ options
25156
+ );
25074
25157
  if (options.append && options.append.length) {
25075
25158
  processedTuples.push(...options.append);
25076
25159
  }
25077
25160
  this._stateManager.applyChanges(tuples, { ...options });
25078
- const state = (_a = this._stateManager) == null ? void 0 : _a.root;
25161
+ const state = (_b = this._stateManager) == null ? void 0 : _b.root;
25079
25162
  const el = state == null ? void 0 : state.__element;
25080
- const orders = computeOrdersForTuples(state, processedTuples);
25081
25163
  const stringifiedGranularTuples = (el == null ? void 0 : el.call) ? el.call(
25082
25164
  "deepStringifyFunctions",
25083
25165
  processedTuples,
@@ -25090,16 +25172,18 @@ var CollabService = class extends BaseService {
25090
25172
  "deepStringifyFunctions",
25091
25173
  tuples,
25092
25174
  Array.isArray(tuples) ? [] : {}
25093
- ) : deepStringifyFunctions(
25094
- tuples,
25095
- Array.isArray(tuples) ? [] : {}
25096
- );
25175
+ ) : deepStringifyFunctions(tuples, Array.isArray(tuples) ? [] : {});
25097
25176
  if (!this.isConnected()) {
25098
25177
  console.warn("[CollabService] Not connected, queuing real-time update");
25099
- this._pendingOps.push({ changes: stringifiedTuples, granularChanges: stringifiedGranularTuples, orders, options });
25178
+ this._pendingOps.push({
25179
+ changes: stringifiedTuples,
25180
+ granularChanges: stringifiedGranularTuples,
25181
+ orders,
25182
+ options
25183
+ });
25100
25184
  return;
25101
25185
  }
25102
- if ((_b = this.socket) == null ? void 0 : _b.connected) {
25186
+ if ((_c = this.socket) == null ? void 0 : _c.connected) {
25103
25187
  console.log("[CollabService] Sending operations to the backend", {
25104
25188
  changes: stringifiedTuples,
25105
25189
  granularChanges: stringifiedGranularTuples,