@liveblocks/server 1.5.0-rc1 → 1.5.0-rc2

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/index.cjs CHANGED
@@ -1640,21 +1640,17 @@ var Storage = class {
1640
1640
  }
1641
1641
  }
1642
1642
  async createChildAsListItem(op2, node) {
1643
- let fix;
1644
1643
  const intent2 = _nullishCoalesce(op2.intent, () => ( "insert"));
1645
1644
  if (intent2 === "insert") {
1646
- const insertedParentKey = await this.insertIntoList(op2.id, node);
1647
- if (insertedParentKey !== node.parentKey) {
1648
- op2 = { ...op2, parentKey: insertedParentKey };
1649
- fix = {
1650
- type: _core.OpCode.SET_PARENT_KEY,
1651
- id: op2.id,
1652
- parentKey: insertedParentKey
1653
- };
1654
- return accept(op2, fix);
1655
- }
1656
- return accept(op2);
1645
+ return this.acceptAndFix(
1646
+ op2,
1647
+ node,
1648
+ await this.insertIntoList(op2.id, node)
1649
+ );
1650
+ } else if (intent2 === "push") {
1651
+ return this.acceptAndFix(op2, node, await this.appendToList(op2.id, node));
1657
1652
  } else if (intent2 === "set") {
1653
+ let fix;
1658
1654
  const deletedId = op2.deletedId !== void 0 && op2.deletedId !== op2.id && _optionalChain([this, 'access', _47 => _47.loadedDriver, 'access', _48 => _48.get_node, 'call', _49 => _49(op2.deletedId), 'optionalAccess', _50 => _50.parentId]) === node.parentId ? op2.deletedId : void 0;
1659
1655
  if (deletedId !== void 0) {
1660
1656
  await this.loadedDriver.delete_node(deletedId);
@@ -1671,28 +1667,24 @@ var Storage = class {
1671
1667
  }
1672
1668
  await this.loadedDriver.set_child(op2.id, node, true);
1673
1669
  return accept(op2, fix);
1674
- } else if (intent2 === "push") {
1675
- const lastPos = this.loadedDriver.get_last_sibling(node.parentId);
1676
- const guessedKey = _core.asPos.call(void 0, node.parentKey);
1677
- const pushedKey = lastPos === void 0 || guessedKey > lastPos ? guessedKey : _core.makePosition.call(void 0, lastPos);
1678
- await this.loadedDriver.set_child(op2.id, {
1679
- ...node,
1680
- parentKey: pushedKey
1681
- });
1682
- if (pushedKey !== node.parentKey) {
1683
- op2 = { ...op2, parentKey: pushedKey };
1684
- fix = {
1685
- type: _core.OpCode.SET_PARENT_KEY,
1686
- id: op2.id,
1687
- parentKey: pushedKey
1688
- };
1689
- return accept(op2, fix);
1690
- }
1691
- return accept(op2);
1692
1670
  } else {
1693
1671
  return _core.assertNever.call(void 0, intent2, "Invalid intent");
1694
1672
  }
1695
1673
  }
1674
+ /**
1675
+ * Accept a freshly placed list item. If the server chose a different
1676
+ * position in the end (conflict resolution), broadcast only the corrected Op
1677
+ * to all clients and send a "fix" op back to the originating client.
1678
+ */
1679
+ acceptAndFix(op2, node, finalKey) {
1680
+ if (finalKey !== node.parentKey) {
1681
+ return accept(
1682
+ { ...op2, parentKey: finalKey },
1683
+ { type: _core.OpCode.SET_PARENT_KEY, id: op2.id, parentKey: finalKey }
1684
+ );
1685
+ }
1686
+ return accept(op2);
1687
+ }
1696
1688
  async applyDeleteObjectKeyOp(op2) {
1697
1689
  await this.loadedDriver.delete_child_key(op2.id, op2.key);
1698
1690
  return accept(op2);
@@ -1738,6 +1730,26 @@ var Storage = class {
1738
1730
  await this.loadedDriver.set_child(id, node);
1739
1731
  return node.parentKey;
1740
1732
  }
1733
+ /**
1734
+ * Server-authoritative append: places the node strictly after every existing
1735
+ * sibling under its list parent. If the client's preferred key already sorts
1736
+ * after the current last sibling it's kept as-is (guaranteed free, since
1737
+ * it's beyond the max); otherwise the node is placed right after the last
1738
+ * sibling. Because Ops are processed serially, the chosen key is always
1739
+ * free, so concurrent pushes never collide.
1740
+ *
1741
+ * Returns the final key that was used for the insertion.
1742
+ */
1743
+ async appendToList(id, node) {
1744
+ const lastPos = this.loadedDriver.get_last_sibling(node.parentId);
1745
+ const preferredPos = _core.asPos.call(void 0, node.parentKey);
1746
+ const finalKey = lastPos === void 0 || preferredPos > lastPos ? preferredPos : _core.makePosition.call(void 0, lastPos);
1747
+ await this.loadedDriver.set_child(
1748
+ id,
1749
+ finalKey !== node.parentKey ? { ...node, parentKey: finalKey } : node
1750
+ );
1751
+ return finalKey;
1752
+ }
1741
1753
  /**
1742
1754
  * Tries to move a node to the given position under the same parent. If
1743
1755
  * a conflicting sibling node already exist at this position, it will use