@symbo.ls/sdk 2.31.37 → 2.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -9166,7 +9166,7 @@ var require_dexie = __commonJS({
9166
9166
  });
9167
9167
  }
9168
9168
  }
9169
- var DEXIE_VERSION = "4.2.0";
9169
+ var DEXIE_VERSION = "4.2.1";
9170
9170
  var maxString = String.fromCharCode(65535);
9171
9171
  var minKey = -Infinity;
9172
9172
  var INVALID_KEY_ARGUMENT = "Invalid key provided. Keys must be of type string, number, Date or Array<string | number | Date>.";
@@ -9291,6 +9291,73 @@ var require_dexie = __commonJS({
9291
9291
  return res;
9292
9292
  });
9293
9293
  }
9294
+ var PropModification2 = (function() {
9295
+ function PropModification3(spec) {
9296
+ this["@@propmod"] = spec;
9297
+ }
9298
+ PropModification3.prototype.execute = function(value2) {
9299
+ var _a2;
9300
+ var spec = this["@@propmod"];
9301
+ if (spec.add !== void 0) {
9302
+ var term = spec.add;
9303
+ if (isArray3(term)) {
9304
+ return __spreadArray(__spreadArray([], isArray3(value2) ? value2 : [], true), term, true).sort();
9305
+ }
9306
+ if (typeof term === "number")
9307
+ return (Number(value2) || 0) + term;
9308
+ if (typeof term === "bigint") {
9309
+ try {
9310
+ return BigInt(value2) + term;
9311
+ } catch (_b) {
9312
+ return BigInt(0) + term;
9313
+ }
9314
+ }
9315
+ throw new TypeError("Invalid term ".concat(term));
9316
+ }
9317
+ if (spec.remove !== void 0) {
9318
+ var subtrahend_1 = spec.remove;
9319
+ if (isArray3(subtrahend_1)) {
9320
+ return isArray3(value2) ? value2.filter(function(item) {
9321
+ return !subtrahend_1.includes(item);
9322
+ }).sort() : [];
9323
+ }
9324
+ if (typeof subtrahend_1 === "number")
9325
+ return Number(value2) - subtrahend_1;
9326
+ if (typeof subtrahend_1 === "bigint") {
9327
+ try {
9328
+ return BigInt(value2) - subtrahend_1;
9329
+ } catch (_c) {
9330
+ return BigInt(0) - subtrahend_1;
9331
+ }
9332
+ }
9333
+ throw new TypeError("Invalid subtrahend ".concat(subtrahend_1));
9334
+ }
9335
+ var prefixToReplace = (_a2 = spec.replacePrefix) === null || _a2 === void 0 ? void 0 : _a2[0];
9336
+ if (prefixToReplace && typeof value2 === "string" && value2.startsWith(prefixToReplace)) {
9337
+ return spec.replacePrefix[1] + value2.substring(prefixToReplace.length);
9338
+ }
9339
+ return value2;
9340
+ };
9341
+ return PropModification3;
9342
+ })();
9343
+ function applyUpdateSpec(obj, changes) {
9344
+ var keyPaths = keys2(changes);
9345
+ var numKeys = keyPaths.length;
9346
+ var anythingModified = false;
9347
+ for (var i = 0; i < numKeys; ++i) {
9348
+ var keyPath = keyPaths[i];
9349
+ var value2 = changes[keyPath];
9350
+ var origValue = getByKeyPath(obj, keyPath);
9351
+ if (value2 instanceof PropModification2) {
9352
+ setByKeyPath(obj, keyPath, value2.execute(origValue));
9353
+ anythingModified = true;
9354
+ } else if (origValue !== value2) {
9355
+ setByKeyPath(obj, keyPath, value2);
9356
+ anythingModified = true;
9357
+ }
9358
+ }
9359
+ return anythingModified;
9360
+ }
9294
9361
  var Table = (function() {
9295
9362
  function Table2() {
9296
9363
  }
@@ -9486,6 +9553,28 @@ var require_dexie = __commonJS({
9486
9553
  return lastResult;
9487
9554
  });
9488
9555
  };
9556
+ Table2.prototype.upsert = function(key, modifications) {
9557
+ var _this = this;
9558
+ var keyPath = this.schema.primKey.keyPath;
9559
+ return this._trans("readwrite", function(trans) {
9560
+ return _this.core.get({ trans, key }).then(function(existing) {
9561
+ var obj = existing !== null && existing !== void 0 ? existing : {};
9562
+ applyUpdateSpec(obj, modifications);
9563
+ if (keyPath)
9564
+ setByKeyPath(obj, keyPath, key);
9565
+ return _this.core.mutate({
9566
+ trans,
9567
+ type: "put",
9568
+ values: [obj],
9569
+ keys: [key],
9570
+ upsert: true,
9571
+ updates: { keys: [key], changeSpecs: [modifications] }
9572
+ }).then(function(res) {
9573
+ return res.numFailures ? DexiePromise.reject(res.failures[0]) : !!existing;
9574
+ });
9575
+ });
9576
+ });
9577
+ };
9489
9578
  Table2.prototype.update = function(keyOrObject, modifications) {
9490
9579
  if (typeof keyOrObject === "object" && !isArray3(keyOrObject)) {
9491
9580
  var key = getByKeyPath(keyOrObject, this.schema.primKey.keyPath);
@@ -9848,55 +9937,6 @@ var require_dexie = __commonJS({
9848
9937
  }
9849
9938
  });
9850
9939
  }
9851
- var PropModification2 = (function() {
9852
- function PropModification3(spec) {
9853
- this["@@propmod"] = spec;
9854
- }
9855
- PropModification3.prototype.execute = function(value2) {
9856
- var _a2;
9857
- var spec = this["@@propmod"];
9858
- if (spec.add !== void 0) {
9859
- var term = spec.add;
9860
- if (isArray3(term)) {
9861
- return __spreadArray(__spreadArray([], isArray3(value2) ? value2 : [], true), term, true).sort();
9862
- }
9863
- if (typeof term === "number")
9864
- return (Number(value2) || 0) + term;
9865
- if (typeof term === "bigint") {
9866
- try {
9867
- return BigInt(value2) + term;
9868
- } catch (_b) {
9869
- return BigInt(0) + term;
9870
- }
9871
- }
9872
- throw new TypeError("Invalid term ".concat(term));
9873
- }
9874
- if (spec.remove !== void 0) {
9875
- var subtrahend_1 = spec.remove;
9876
- if (isArray3(subtrahend_1)) {
9877
- return isArray3(value2) ? value2.filter(function(item) {
9878
- return !subtrahend_1.includes(item);
9879
- }).sort() : [];
9880
- }
9881
- if (typeof subtrahend_1 === "number")
9882
- return Number(value2) - subtrahend_1;
9883
- if (typeof subtrahend_1 === "bigint") {
9884
- try {
9885
- return BigInt(value2) - subtrahend_1;
9886
- } catch (_c) {
9887
- return BigInt(0) - subtrahend_1;
9888
- }
9889
- }
9890
- throw new TypeError("Invalid subtrahend ".concat(subtrahend_1));
9891
- }
9892
- var prefixToReplace = (_a2 = spec.replacePrefix) === null || _a2 === void 0 ? void 0 : _a2[0];
9893
- if (prefixToReplace && typeof value2 === "string" && value2.startsWith(prefixToReplace)) {
9894
- return spec.replacePrefix[1] + value2.substring(prefixToReplace.length);
9895
- }
9896
- return value2;
9897
- };
9898
- return PropModification3;
9899
- })();
9900
9940
  var Collection = (function() {
9901
9941
  function Collection2() {
9902
9942
  }
@@ -10176,23 +10216,8 @@ var require_dexie = __commonJS({
10176
10216
  if (typeof changes === "function") {
10177
10217
  modifyer = changes;
10178
10218
  } else {
10179
- var keyPaths = keys2(changes);
10180
- var numKeys = keyPaths.length;
10181
10219
  modifyer = function(item) {
10182
- var anythingModified = false;
10183
- for (var i = 0; i < numKeys; ++i) {
10184
- var keyPath = keyPaths[i];
10185
- var val = changes[keyPath];
10186
- var origVal = getByKeyPath(item, keyPath);
10187
- if (val instanceof PropModification2) {
10188
- setByKeyPath(item, keyPath, val.execute(origVal));
10189
- anythingModified = true;
10190
- } else if (origVal !== val) {
10191
- setByKeyPath(item, keyPath, val);
10192
- anythingModified = true;
10193
- }
10194
- }
10195
- return anythingModified;
10220
+ return applyUpdateSpec(item, changes);
10196
10221
  };
10197
10222
  }
10198
10223
  var coreTable = ctx.table.core;
@@ -12196,8 +12221,8 @@ var require_dexie = __commonJS({
12196
12221
  state.vcFired = true;
12197
12222
  db.on("versionchange").fire(ev);
12198
12223
  });
12199
- idbdb.onclose = wrap(function(ev) {
12200
- db.on("close").fire(ev);
12224
+ idbdb.onclose = wrap(function() {
12225
+ db.close({ disableAutoOpen: false });
12201
12226
  });
12202
12227
  if (wasCreated)
12203
12228
  _onDatabaseCreated(db._deps, dbName);
@@ -28245,6 +28270,281 @@ var validateParams = {
28245
28270
 
28246
28271
  // src/services/CollabService.js
28247
28272
  import { deepStringifyFunctions } from "@domql/utils";
28273
+
28274
+ // src/utils/ordering.js
28275
+ function isObjectLike(val) {
28276
+ return val && typeof val === "object" && !Array.isArray(val);
28277
+ }
28278
+ function normalizePath(path) {
28279
+ if (Array.isArray(path)) {
28280
+ return path;
28281
+ }
28282
+ if (typeof path === "string") {
28283
+ return [path];
28284
+ }
28285
+ return [];
28286
+ }
28287
+ function getParentPathsFromTuples(tuples = []) {
28288
+ const seen = /* @__PURE__ */ new Set();
28289
+ const parents = [];
28290
+ const META_KEYS = /* @__PURE__ */ new Set([
28291
+ "style",
28292
+ "class",
28293
+ "text",
28294
+ "html",
28295
+ "content",
28296
+ "data",
28297
+ "attr",
28298
+ "state",
28299
+ "scope",
28300
+ "props",
28301
+ "define",
28302
+ "on",
28303
+ "extend",
28304
+ "extends",
28305
+ "childExtend",
28306
+ "childExtends",
28307
+ "childProps",
28308
+ "children",
28309
+ "component",
28310
+ "context",
28311
+ "tag",
28312
+ "key",
28313
+ "__order",
28314
+ "if"
28315
+ ]);
28316
+ for (let i = 0; i < tuples.length; i++) {
28317
+ const tuple = tuples[i];
28318
+ if (!Array.isArray(tuple) || tuple.length < 2) {
28319
+ continue;
28320
+ }
28321
+ const path = normalizePath(tuple[1]);
28322
+ if (!path.length) {
28323
+ continue;
28324
+ }
28325
+ if (path[0] === "schema") {
28326
+ continue;
28327
+ }
28328
+ const immediateParent = path.slice(0, -1);
28329
+ if (immediateParent.length) {
28330
+ const key = JSON.stringify(immediateParent);
28331
+ if (!seen.has(key)) {
28332
+ seen.add(key);
28333
+ parents.push(immediateParent);
28334
+ }
28335
+ }
28336
+ const last2 = path[path.length - 1];
28337
+ if (META_KEYS.has(last2) && path.length >= 2) {
28338
+ const containerParent = path.slice(0, -2);
28339
+ if (containerParent.length) {
28340
+ const key2 = JSON.stringify(containerParent);
28341
+ if (!seen.has(key2)) {
28342
+ seen.add(key2);
28343
+ parents.push(containerParent);
28344
+ }
28345
+ }
28346
+ }
28347
+ for (let j = 0; j < path.length; j++) {
28348
+ const seg = path[j];
28349
+ if (!META_KEYS.has(seg)) {
28350
+ continue;
28351
+ }
28352
+ const containerParent2 = path.slice(0, j);
28353
+ if (!containerParent2.length) {
28354
+ continue;
28355
+ }
28356
+ const key3 = JSON.stringify(containerParent2);
28357
+ if (!seen.has(key3)) {
28358
+ seen.add(key3);
28359
+ parents.push(containerParent2);
28360
+ }
28361
+ }
28362
+ }
28363
+ return parents;
28364
+ }
28365
+ function computeOrdersFromState(root, parentPaths = []) {
28366
+ if (!root || typeof root.getByPath !== "function") {
28367
+ return [];
28368
+ }
28369
+ const orders = [];
28370
+ const EXCLUDE_KEYS = /* @__PURE__ */ new Set(["__order"]);
28371
+ for (let i = 0; i < parentPaths.length; i++) {
28372
+ const parentPath = parentPaths[i];
28373
+ const obj = (() => {
28374
+ try {
28375
+ return root.getByPath(parentPath);
28376
+ } catch {
28377
+ return null;
28378
+ }
28379
+ })();
28380
+ if (!isObjectLike(obj)) {
28381
+ continue;
28382
+ }
28383
+ const keys2 = Object.keys(obj).filter((k) => !EXCLUDE_KEYS.has(k));
28384
+ orders.push({ path: parentPath, keys: keys2 });
28385
+ }
28386
+ return orders;
28387
+ }
28388
+ function normaliseSchemaCode(code) {
28389
+ if (typeof code !== "string" || !code.length) {
28390
+ return "";
28391
+ }
28392
+ return code.replaceAll("/////n", "\n").replaceAll("/////tilde", "`");
28393
+ }
28394
+ function extractTopLevelKeysFromCode(code) {
28395
+ const src = normaliseSchemaCode(code);
28396
+ if (!src) {
28397
+ return [];
28398
+ }
28399
+ const idx = src.indexOf("export default");
28400
+ if (idx === -1) {
28401
+ return [];
28402
+ }
28403
+ let i = src.indexOf("{", idx);
28404
+ if (i === -1) {
28405
+ return [];
28406
+ }
28407
+ const keys2 = [];
28408
+ let depth = 0;
28409
+ let inStr = false;
28410
+ let strCh = "";
28411
+ let inEsc = false;
28412
+ for (; i < src.length; i++) {
28413
+ const ch = src[i];
28414
+ if (inStr) {
28415
+ if (inEsc) {
28416
+ inEsc = false;
28417
+ } else if (ch === "\\") {
28418
+ inEsc = true;
28419
+ } else if (ch === strCh) {
28420
+ inStr = false;
28421
+ strCh = "";
28422
+ }
28423
+ continue;
28424
+ }
28425
+ if (ch === '"' || ch === "'" || ch === "`") {
28426
+ inStr = true;
28427
+ strCh = ch;
28428
+ continue;
28429
+ }
28430
+ if (ch === "{") {
28431
+ depth++;
28432
+ continue;
28433
+ }
28434
+ if (ch === "}") {
28435
+ depth--;
28436
+ if (depth === 0) {
28437
+ break;
28438
+ }
28439
+ continue;
28440
+ }
28441
+ if (depth !== 1) {
28442
+ continue;
28443
+ }
28444
+ if (/[A-Za-z_$]/u.test(ch)) {
28445
+ let j = i;
28446
+ while (j < src.length && /[A-Za-z0-9_$]/u.test(src[j])) {
28447
+ j++;
28448
+ }
28449
+ let k = j;
28450
+ while (k < src.length && /\s/u.test(src[k])) {
28451
+ k++;
28452
+ }
28453
+ if (src[k] === ":") {
28454
+ const key = src.slice(i, j);
28455
+ keys2.push(key);
28456
+ }
28457
+ i = j;
28458
+ continue;
28459
+ }
28460
+ }
28461
+ if (!keys2.length) {
28462
+ const bodyStart = src.indexOf("{", idx);
28463
+ const bodyEnd = src.lastIndexOf("}");
28464
+ if (bodyStart === -1 || bodyEnd === -1 || bodyEnd <= bodyStart) {
28465
+ return Array.from(new Set(keys2));
28466
+ }
28467
+ const body = src.slice(bodyStart + 1, bodyEnd);
28468
+ const re2 = /(?:[A-Za-z_$][A-Za-z0-9_$]*|"[^"]+"|'[^']+')\s*:/gu;
28469
+ for (const m of body.matchAll(re2)) {
28470
+ const raw = m[0].split(":")[0].trim();
28471
+ const key = raw[0] === '"' || raw[0] === "'" ? raw.slice(1, -1) : raw;
28472
+ keys2.push(key);
28473
+ }
28474
+ }
28475
+ return Array.from(new Set(keys2));
28476
+ }
28477
+ function computeOrdersForTuples(root, tuples = []) {
28478
+ const preferredOrderMap = /* @__PURE__ */ new Map();
28479
+ for (let i = 0; i < tuples.length; i++) {
28480
+ const t = tuples[i];
28481
+ if (!Array.isArray(t)) {
28482
+ continue;
28483
+ }
28484
+ const [action, path, value2] = t;
28485
+ const p = normalizePath(path);
28486
+ if (action !== "update" || !Array.isArray(p) || p.length < 3) {
28487
+ continue;
28488
+ }
28489
+ if (p[0] !== "schema") {
28490
+ continue;
28491
+ }
28492
+ const [, type, key] = p;
28493
+ const containerPath = [type, key];
28494
+ const uses = value2 && Array.isArray(value2.uses) ? value2.uses : null;
28495
+ const code = value2 && value2.code;
28496
+ const obj = (() => {
28497
+ try {
28498
+ return root && typeof root.getByPath === "function" ? root.getByPath(containerPath) : null;
28499
+ } catch {
28500
+ return null;
28501
+ }
28502
+ })();
28503
+ if (!obj) {
28504
+ continue;
28505
+ }
28506
+ const present = new Set(Object.keys(obj));
28507
+ const EXCLUDE_KEYS = /* @__PURE__ */ new Set(["__order"]);
28508
+ const codeKeys = extractTopLevelKeysFromCode(code);
28509
+ let resolved = [];
28510
+ if (Array.isArray(codeKeys) && codeKeys.length) {
28511
+ resolved = codeKeys.filter((k) => present.has(k) && !EXCLUDE_KEYS.has(k));
28512
+ }
28513
+ if (resolved.length && Array.isArray(uses) && uses.length) {
28514
+ for (let u = 0; u < uses.length; u++) {
28515
+ const keyName = uses[u];
28516
+ if (present.has(keyName) && !EXCLUDE_KEYS.has(keyName) && !resolved.includes(keyName)) {
28517
+ resolved.push(keyName);
28518
+ }
28519
+ }
28520
+ }
28521
+ if (resolved.length) {
28522
+ preferredOrderMap.set(JSON.stringify(containerPath), { path: containerPath, keys: resolved });
28523
+ }
28524
+ }
28525
+ const parents = getParentPathsFromTuples(tuples);
28526
+ const orders = [];
28527
+ const seen = /* @__PURE__ */ new Set();
28528
+ preferredOrderMap.forEach((v) => {
28529
+ const k = JSON.stringify(v.path);
28530
+ if (!seen.has(k)) {
28531
+ seen.add(k);
28532
+ orders.push(v);
28533
+ }
28534
+ });
28535
+ const fallbackOrders = computeOrdersFromState(root, parents);
28536
+ for (let i = 0; i < fallbackOrders.length; i++) {
28537
+ const v = fallbackOrders[i];
28538
+ const k = JSON.stringify(v.path);
28539
+ if (!seen.has(k)) {
28540
+ seen.add(k);
28541
+ orders.push(v);
28542
+ }
28543
+ }
28544
+ return orders;
28545
+ }
28546
+
28547
+ // src/services/CollabService.js
28248
28548
  var CollabService = class extends BaseService {
28249
28549
  constructor(config) {
28250
28550
  super(config);
@@ -28382,8 +28682,8 @@ var CollabService = class extends BaseService {
28382
28682
  console.log(
28383
28683
  `[CollabService] Flushing ${this._pendingOps.length} offline operation batch(es)`
28384
28684
  );
28385
- this._pendingOps.forEach(({ tuples }) => {
28386
- this.socket.emit("ops", { changes: tuples, ts: Date.now() });
28685
+ this._pendingOps.forEach(({ changes, orders }) => {
28686
+ this.socket.emit("ops", { changes, orders, ts: Date.now() });
28387
28687
  });
28388
28688
  this._pendingOps.length = 0;
28389
28689
  }
@@ -28428,24 +28728,118 @@ var CollabService = class extends BaseService {
28428
28728
  }
28429
28729
  /* ---------- data helpers ---------- */
28430
28730
  updateData(tuples, options = {}) {
28431
- var _a;
28731
+ var _a, _b;
28432
28732
  this._ensureStateManager();
28433
28733
  const { isUndo = false, isRedo = false } = options;
28434
28734
  if (!isUndo && !isRedo && !this._isUndoRedo) {
28435
28735
  this._trackForUndo(tuples, options);
28436
28736
  }
28737
+ const processedTuples = (() => {
28738
+ var _a2;
28739
+ try {
28740
+ const root = (_a2 = this._stateManager) == null ? void 0 : _a2.root;
28741
+ const isPlainObject2 = (o) => o && typeof o === "object" && !Array.isArray(o);
28742
+ const getByPath = (state2, path) => {
28743
+ if (!state2 || typeof state2.getByPath !== "function") {
28744
+ return null;
28745
+ }
28746
+ try {
28747
+ return state2.getByPath(path);
28748
+ } catch {
28749
+ return null;
28750
+ }
28751
+ };
28752
+ const expandTuple = (t) => {
28753
+ const [action, path, value2] = t || [];
28754
+ const isSchemaPath = Array.isArray(path) && path[0] === "schema";
28755
+ if (action === "delete" || isSchemaPath) {
28756
+ return [t];
28757
+ }
28758
+ const canConsiderExpansion = action === "update" && Array.isArray(path) && (path.length === 1 || path.length === 2) && isPlainObject2(value2);
28759
+ if (!canConsiderExpansion) {
28760
+ return [t];
28761
+ }
28762
+ const prev = getByPath(root, path) || {};
28763
+ const next = value2 || {};
28764
+ if (!isPlainObject2(prev) || !isPlainObject2(next)) {
28765
+ return [t];
28766
+ }
28767
+ const ops = diffJson(prev, next, []);
28768
+ if (!ops.length) {
28769
+ return [];
28770
+ }
28771
+ const arr = [];
28772
+ for (let j = 0; j < ops.length; j++) {
28773
+ const op = ops[j];
28774
+ const fullPath = [...path, ...op.path];
28775
+ const last2 = fullPath[fullPath.length - 1];
28776
+ if (op.action === "set") {
28777
+ arr.push(["update", fullPath, op.value]);
28778
+ } else if (op.action === "del") {
28779
+ if (last2 !== "__order") {
28780
+ arr.push(["delete", fullPath]);
28781
+ }
28782
+ }
28783
+ }
28784
+ return arr;
28785
+ };
28786
+ const minimizeTuples = (inputTuples) => {
28787
+ const out = [];
28788
+ for (let i = 0; i < inputTuples.length; i++) {
28789
+ const expanded = expandTuple(inputTuples[i]);
28790
+ for (let k = 0; k < expanded.length; k++) {
28791
+ const tuple = expanded[k];
28792
+ const isDelete = Array.isArray(tuple) && tuple[0] === "delete";
28793
+ const isOrderKey = isDelete && Array.isArray(tuple[1]) && tuple[1][tuple[1].length - 1] === "__order";
28794
+ if (!isOrderKey) {
28795
+ out.push(tuple);
28796
+ }
28797
+ }
28798
+ }
28799
+ console.log(`Minimized tuples`, out);
28800
+ return out;
28801
+ };
28802
+ console.log(`Processing tuples`, tuples);
28803
+ return minimizeTuples(tuples);
28804
+ } catch (err) {
28805
+ console.warn(
28806
+ "[CollabService] Minimal diff expansion failed \u2013 using original tuples",
28807
+ err
28808
+ );
28809
+ return tuples;
28810
+ }
28811
+ })();
28437
28812
  if (options.append && options.append.length) {
28438
- tuples.push(...options.append);
28813
+ processedTuples.push(...options.append);
28439
28814
  }
28440
28815
  this._stateManager.applyChanges(tuples, { ...options });
28441
- tuples = deepStringifyFunctions(tuples, []);
28816
+ const state = (_a = this._stateManager) == null ? void 0 : _a.root;
28817
+ const el = state == null ? void 0 : state.__element;
28818
+ const orders = computeOrdersForTuples(state, processedTuples);
28819
+ const stringifiedTuples = (el == null ? void 0 : el.call) ? el.call(
28820
+ "deepStringifyFunctions",
28821
+ processedTuples,
28822
+ Array.isArray(processedTuples) ? [] : {}
28823
+ ) : deepStringifyFunctions(
28824
+ processedTuples,
28825
+ Array.isArray(processedTuples) ? [] : {}
28826
+ );
28442
28827
  if (!this.isConnected()) {
28443
28828
  console.warn("[CollabService] Not connected, queuing real-time update");
28444
- this._pendingOps.push({ tuples, options });
28829
+ this._pendingOps.push({ changes: stringifiedTuples, orders, options });
28445
28830
  return;
28446
28831
  }
28447
- if ((_a = this.socket) == null ? void 0 : _a.connected) {
28448
- this.socket.emit("ops", { changes: tuples, ts: Date.now() });
28832
+ if ((_b = this.socket) == null ? void 0 : _b.connected) {
28833
+ console.log("[CollabService] Sending operations to the backend", {
28834
+ changes: stringifiedTuples,
28835
+ orders,
28836
+ ts: Date.now()
28837
+ });
28838
+ this.socket.emit("ops", {
28839
+ changes: stringifiedTuples,
28840
+ orders,
28841
+ ts: Date.now()
28842
+ });
28449
28843
  }
28450
28844
  return { success: true };
28451
28845
  }
@@ -29290,6 +29684,8 @@ var ProjectService = class extends BaseService {
29290
29684
  throw new Error("Changes must be an array");
29291
29685
  }
29292
29686
  const { message, branch = "main", type = "patch" } = options;
29687
+ const state = this._context && this._context.state;
29688
+ const derivedOrders = options.orders || (state ? computeOrdersForTuples(state, changes) : []);
29293
29689
  try {
29294
29690
  const response = await this._request(`/projects/${projectId}/changes`, {
29295
29691
  method: "POST",
@@ -29297,7 +29693,8 @@ var ProjectService = class extends BaseService {
29297
29693
  changes,
29298
29694
  message,
29299
29695
  branch,
29300
- type
29696
+ type,
29697
+ ...derivedOrders && derivedOrders.length ? { orders: derivedOrders } : {}
29301
29698
  }),
29302
29699
  methodName: "applyProjectChanges"
29303
29700
  });