lib0 1.0.0-rc.7 → 1.0.0-rc.9
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/package.json +6 -5
- package/src/broadcastchannel.js +6 -1
- package/src/delta/delta.js +117 -61
- package/src/environment.js +8 -0
- package/src/schema.js +1 -1
- package/src/trait/equality.js +1 -1
- package/src/trait/fingerprint.js +1 -1
- package/types/delta/delta.d.ts +25 -1
- package/types/environment.d.ts +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lib0",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.9",
|
|
4
4
|
"description": "",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"type": "module",
|
|
@@ -272,6 +272,7 @@
|
|
|
272
272
|
"devDependencies": {
|
|
273
273
|
"@types/node": "^24.11.0",
|
|
274
274
|
"c8": "^10.1.3",
|
|
275
|
+
"dpdm": "^4.0.1",
|
|
275
276
|
"standard": "^17.1.0",
|
|
276
277
|
"typescript": "^5.9.3"
|
|
277
278
|
},
|
|
@@ -280,15 +281,15 @@
|
|
|
280
281
|
"types": "rm -rf types && tsc -p tsconfig.build.json",
|
|
281
282
|
"dist": "npm run clean && npm run types",
|
|
282
283
|
"debug": "npm run gentesthtml && node ./src/bin/0serve.js -o test.html",
|
|
283
|
-
"test": "c8 --check-coverage --lines
|
|
284
|
+
"test": "c8 --check-coverage --lines 97 --branches 96 --functions 94 --statements 97 node --unhandled-rejections=strict ./src/test.js",
|
|
285
|
+
"test:deno": "deno run -A src/test.js",
|
|
284
286
|
"test-inspect": "node --inspect-brk --unhandled-rejections=strict ./src/test.js --repetition-time 50",
|
|
285
|
-
"test-extensive": "
|
|
287
|
+
"test-extensive": "node ./src/test.js --repetition-time 1000 --extensive",
|
|
286
288
|
"test:bundle": "esbuild bundle.test.js --bundle --outfile=dist/bundle.test.js --analyze --minify && wc -c dist/bundle.test.js",
|
|
287
289
|
"trace-deopt": "clear && node --trace-deopt src/test.js",
|
|
288
290
|
"trace-opt": "clear && node --trace-opt src/test.js",
|
|
289
|
-
"lint": "tsc && standard",
|
|
291
|
+
"lint": "tsc && standard && npx dpdm --exit-code circular:1 --warning false --tree false src/test.js",
|
|
290
292
|
"gendocs": "node ./bin/gendocs.js",
|
|
291
|
-
"release": "npm run dist && np --test-script dist",
|
|
292
293
|
"version": "npm run clean && npm run dist && git add README.md",
|
|
293
294
|
"postpublish": "npm run clean",
|
|
294
295
|
"gentesthtml": "node ./src/bin/gentesthtml.js --script src/test.js > test.html"
|
package/src/broadcastchannel.js
CHANGED
|
@@ -44,6 +44,10 @@ class LocalStoragePolyfill {
|
|
|
44
44
|
* @type {null|function({data:Uint8Array}):void}
|
|
45
45
|
*/
|
|
46
46
|
this.onmessage = null
|
|
47
|
+
/**
|
|
48
|
+
* @type {null|((this: BroadcastChannel, ev: MessageEvent) => any)}
|
|
49
|
+
*/
|
|
50
|
+
this.onmessageerror = null
|
|
47
51
|
/**
|
|
48
52
|
* @param {any} e
|
|
49
53
|
*/
|
|
@@ -79,8 +83,9 @@ const getChannel = room =>
|
|
|
79
83
|
/**
|
|
80
84
|
* @param {{data:ArrayBuffer}} e
|
|
81
85
|
*/
|
|
82
|
-
/* c8 ignore next */
|
|
86
|
+
/* c8 ignore next 3 */
|
|
83
87
|
bc.onmessage = e => subs.forEach(sub => sub(e.data, 'broadcastchannel'))
|
|
88
|
+
bc.onmessageerror = e => console.error('broadcastchannel error', e)
|
|
84
89
|
return {
|
|
85
90
|
bc, subs
|
|
86
91
|
}
|
package/src/delta/delta.js
CHANGED
|
@@ -972,6 +972,9 @@ class DeltaData {
|
|
|
972
972
|
* >}
|
|
973
973
|
*/
|
|
974
974
|
this.children = /** @type {any} */ (list.create())
|
|
975
|
+
/**
|
|
976
|
+
* All child-ops sizes combined. Note that delete-ops also have a length
|
|
977
|
+
*/
|
|
975
978
|
this.childCnt = 0
|
|
976
979
|
/**
|
|
977
980
|
* @type {any}
|
|
@@ -982,6 +985,10 @@ class DeltaData {
|
|
|
982
985
|
*/
|
|
983
986
|
this._fingerprint = null
|
|
984
987
|
this.isDone = false
|
|
988
|
+
/**
|
|
989
|
+
* Is the final document and does not contain delete, modify, or retain ops.
|
|
990
|
+
*/
|
|
991
|
+
this.isFinal = false
|
|
985
992
|
}
|
|
986
993
|
}
|
|
987
994
|
|
|
@@ -1461,9 +1468,21 @@ export class DeltaBuilder extends Delta {
|
|
|
1461
1468
|
}
|
|
1462
1469
|
|
|
1463
1470
|
/**
|
|
1471
|
+
* Apply other delta on this op. The result is the merged op of both of them.
|
|
1472
|
+
*
|
|
1473
|
+
* a.apply(b.apply(c))
|
|
1474
|
+
*
|
|
1475
|
+
* is equivalent to
|
|
1476
|
+
*
|
|
1477
|
+
* a.apply(b).apply(c)
|
|
1478
|
+
*
|
|
1479
|
+
* @todo fuzz test the above property
|
|
1480
|
+
*
|
|
1464
1481
|
* @param {Delta<Conf>?} other
|
|
1482
|
+
* @param {{ final?: boolean }} opts -- experimental
|
|
1483
|
+
* @return {Delta<Conf>}
|
|
1465
1484
|
*/
|
|
1466
|
-
apply (other) {
|
|
1485
|
+
apply (other, { final = this.isFinal } = {}) {
|
|
1467
1486
|
if (other == null) return this
|
|
1468
1487
|
modDeltaCheck(this)
|
|
1469
1488
|
this.$schema?.expect(other)
|
|
@@ -1486,8 +1505,13 @@ export class DeltaBuilder extends Delta {
|
|
|
1486
1505
|
this.attrs[op.key] = op.clone()
|
|
1487
1506
|
} else if ($deleteAttrOp.check(op)) {
|
|
1488
1507
|
op.prevValue = c?.value
|
|
1489
|
-
|
|
1490
|
-
|
|
1508
|
+
if (final) {
|
|
1509
|
+
// @ts-ignore
|
|
1510
|
+
delete this.attrs[op.key]
|
|
1511
|
+
} else {
|
|
1512
|
+
// @ts-ignore
|
|
1513
|
+
this.attrs[op.key] = op.clone()
|
|
1514
|
+
}
|
|
1491
1515
|
}
|
|
1492
1516
|
}
|
|
1493
1517
|
// apply children
|
|
@@ -1495,6 +1519,9 @@ export class DeltaBuilder extends Delta {
|
|
|
1495
1519
|
* @type {ChildrenOpAny?}
|
|
1496
1520
|
*/
|
|
1497
1521
|
let opsI = this.children.start
|
|
1522
|
+
if ($deleteOp.check(opsI)) {
|
|
1523
|
+
opsI = opNextUndeleted(opsI)
|
|
1524
|
+
}
|
|
1498
1525
|
let offset = 0
|
|
1499
1526
|
/**
|
|
1500
1527
|
* At the end, we will try to merge this op, and op.next op with their respective previous op.
|
|
@@ -1506,57 +1533,63 @@ export class DeltaBuilder extends Delta {
|
|
|
1506
1533
|
*/
|
|
1507
1534
|
const maybeMergeable = []
|
|
1508
1535
|
/**
|
|
1509
|
-
*
|
|
1510
|
-
* @param {
|
|
1511
|
-
* @return {
|
|
1536
|
+
* Schedule an op to be merged later
|
|
1537
|
+
* @param {ChildrenOpAny?} op
|
|
1538
|
+
* @return {ChildrenOpAny}
|
|
1512
1539
|
*/
|
|
1513
1540
|
const scheduleForMerge = op => {
|
|
1514
1541
|
op && maybeMergeable.push(op)
|
|
1515
|
-
return op
|
|
1542
|
+
return /** @type {any} */ (op)
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
/**
|
|
1546
|
+
* Split opsI at the current offset - ensuring that we can insert safely at the current position
|
|
1547
|
+
*/
|
|
1548
|
+
const splitHere = () => {
|
|
1549
|
+
if (offset > 0 && opsI != null) {
|
|
1550
|
+
const rightPart = scheduleForMerge(opsI.clone(offset))
|
|
1551
|
+
opsI._splice(offset, opsI.length - offset)
|
|
1552
|
+
list.insertBetween(this.children, opsI, opsI.next || null, rightPart)
|
|
1553
|
+
offset = 0
|
|
1554
|
+
opsI = rightPart
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
/**
|
|
1558
|
+
* @param {ChildrenOpAny} op
|
|
1559
|
+
*/
|
|
1560
|
+
const insertClonedOp = op => {
|
|
1561
|
+
splitHere()
|
|
1562
|
+
list.insertBetween(this.children, opsI == null ? this.children.end : opsI.prev, opsI, scheduleForMerge(op.clone()))
|
|
1563
|
+
this.childCnt += op.length
|
|
1516
1564
|
}
|
|
1517
|
-
other.children
|
|
1565
|
+
for (const op of other.children) {
|
|
1566
|
+
if (opsI?.length === offset) {
|
|
1567
|
+
opsI = opNextUndeleted(opsI)
|
|
1568
|
+
offset = 0
|
|
1569
|
+
}
|
|
1518
1570
|
if ($textOp.check(op) || $insertOp.check(op)) {
|
|
1519
|
-
|
|
1520
|
-
list.insertBetween(this.children, opsI == null ? this.children.end : opsI.prev, opsI, scheduleForMerge(op.clone()))
|
|
1521
|
-
} else {
|
|
1522
|
-
// @todo inmplement "splitHelper" and "insertHelper" - I'm splitting all the time and
|
|
1523
|
-
// forget to update opsI
|
|
1524
|
-
if (opsI == null) error.unexpectedCase()
|
|
1525
|
-
const cpy = scheduleForMerge(opsI.clone(offset))
|
|
1526
|
-
opsI._splice(offset, opsI.length - offset)
|
|
1527
|
-
list.insertBetween(this.children, opsI, opsI.next || null, cpy)
|
|
1528
|
-
list.insertBetween(this.children, opsI, cpy || null, scheduleForMerge(op.clone()))
|
|
1529
|
-
opsI = cpy
|
|
1530
|
-
offset = 0
|
|
1531
|
-
}
|
|
1532
|
-
this.childCnt += op.insert.length
|
|
1571
|
+
insertClonedOp(op)
|
|
1533
1572
|
} else if ($retainOp.check(op)) {
|
|
1534
1573
|
let retainLen = op.length
|
|
1535
|
-
|
|
1536
|
-
if (offset > 0 && opsI != null && op.format != null && !$deleteOp.check(opsI) && !object.every(op.format, (v, k) => fun.equalityDeep(v, /** @type {InsertOp<any>|RetainOp|ModifyOp} */ (opsI).format?.[k] || null))) {
|
|
1574
|
+
if (offset > 0 && opsI != null && op.format != null && !$deleteOp.check(opsI) && (/** @type {InsertOp<any>|RetainOp|ModifyOp} */ (opsI).format == null || !fun.equalityDeep(opsI.format, op.format))) {
|
|
1537
1575
|
// need to split current op
|
|
1538
|
-
|
|
1539
|
-
opsI._splice(offset, opsI.length - offset)
|
|
1540
|
-
list.insertBetween(this.children, opsI, opsI.next || null, cpy)
|
|
1541
|
-
opsI = cpy
|
|
1542
|
-
offset = 0
|
|
1576
|
+
splitHere()
|
|
1543
1577
|
}
|
|
1544
|
-
|
|
1545
1578
|
while (opsI != null && opsI.length - offset <= retainLen) {
|
|
1546
|
-
op.format != null
|
|
1579
|
+
if (op.format != null) {
|
|
1580
|
+
updateOpFormat(opsI, op.format)
|
|
1581
|
+
scheduleForMerge(opsI)
|
|
1582
|
+
}
|
|
1547
1583
|
retainLen -= opsI.length - offset
|
|
1548
|
-
opsI = opsI
|
|
1584
|
+
opsI = opNextUndeleted(opsI)
|
|
1549
1585
|
offset = 0
|
|
1550
1586
|
}
|
|
1551
|
-
|
|
1552
1587
|
if (opsI != null) {
|
|
1553
1588
|
if (op.format != null && retainLen > 0) {
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
opsI.
|
|
1557
|
-
|
|
1558
|
-
updateOpFormat(opsI, op.format)
|
|
1559
|
-
opsI = cpy
|
|
1589
|
+
offset = retainLen
|
|
1590
|
+
splitHere()
|
|
1591
|
+
updateOpFormat(/** @type {ChildrenOpAny} */ (opsI.prev), op.format)
|
|
1592
|
+
scheduleForMerge(opsI.prev)
|
|
1560
1593
|
} else {
|
|
1561
1594
|
offset += retainLen
|
|
1562
1595
|
}
|
|
@@ -1571,17 +1604,22 @@ export class DeltaBuilder extends Delta {
|
|
|
1571
1604
|
list.pushEnd(this.children, scheduleForMerge(new DeleteOp(remainingLen, null)))
|
|
1572
1605
|
this.childCnt += remainingLen
|
|
1573
1606
|
break
|
|
1574
|
-
} else if ($
|
|
1575
|
-
const delLen = opsI.length - offset
|
|
1576
|
-
|
|
1577
|
-
|
|
1607
|
+
} else if ($retainOp.check(opsI)) { // retain ⇒ splice retain, insert delete
|
|
1608
|
+
const delLen = math.min(opsI.length - offset, remainingLen)
|
|
1609
|
+
opsI._splice(offset, delLen)
|
|
1610
|
+
this.childCnt -= delLen
|
|
1611
|
+
if (opsI.length === 0) {
|
|
1612
|
+
list.remove(this.children, opsI)
|
|
1613
|
+
opsI = opNextUndeleted(opsI)
|
|
1614
|
+
offset = 0
|
|
1615
|
+
}
|
|
1616
|
+
if (opsI?.length === offset) {
|
|
1617
|
+
opsI = opNextUndeleted(opsI)
|
|
1578
1618
|
offset = 0
|
|
1579
|
-
opsI = opsI.next
|
|
1580
|
-
} else {
|
|
1581
|
-
offset += remainingLen
|
|
1582
1619
|
}
|
|
1620
|
+
insertClonedOp(new DeleteOp(delLen, null))
|
|
1583
1621
|
remainingLen -= delLen
|
|
1584
|
-
} else { // insert / embed /
|
|
1622
|
+
} else if (!$deleteOp.check(opsI)) { // insert / embed / modify ⇒ replace
|
|
1585
1623
|
// case1: delete o fully
|
|
1586
1624
|
// case2: delete some part of beginning
|
|
1587
1625
|
// case3: delete some part of end
|
|
@@ -1590,38 +1628,38 @@ export class DeltaBuilder extends Delta {
|
|
|
1590
1628
|
this.childCnt -= delLen
|
|
1591
1629
|
if (opsI.length === delLen) {
|
|
1592
1630
|
// case 1
|
|
1593
|
-
offset = 0
|
|
1594
1631
|
list.remove(this.children, opsI)
|
|
1595
|
-
scheduleForMerge(opsI = opsI
|
|
1632
|
+
scheduleForMerge(opsI = opNextUndeleted(opsI))
|
|
1633
|
+
offset = 0
|
|
1596
1634
|
} else if (offset === 0) {
|
|
1597
1635
|
// case 2
|
|
1598
1636
|
offset = 0
|
|
1599
|
-
opsI._splice(
|
|
1637
|
+
opsI._splice(offset, delLen)
|
|
1600
1638
|
} else if (offset + delLen === opsI.length) {
|
|
1601
1639
|
// case 3
|
|
1602
1640
|
opsI._splice(offset, delLen)
|
|
1641
|
+
opsI = opNextUndeleted(opsI)
|
|
1603
1642
|
offset = 0
|
|
1604
|
-
opsI = opsI.next
|
|
1605
1643
|
} else {
|
|
1606
1644
|
// case 4
|
|
1607
1645
|
opsI._splice(offset, delLen)
|
|
1608
1646
|
}
|
|
1609
1647
|
remainingLen -= delLen
|
|
1648
|
+
} else {
|
|
1649
|
+
error.unexpectedCase()
|
|
1610
1650
|
}
|
|
1611
1651
|
}
|
|
1612
1652
|
} else if ($modifyOp.check(op)) {
|
|
1613
1653
|
if (opsI == null) {
|
|
1614
1654
|
list.pushEnd(this.children, op.clone())
|
|
1615
1655
|
this.childCnt += 1
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
opsI._modValue.apply(/** @type {any} */ (op.value))
|
|
1620
|
-
opsI = opsI.next
|
|
1656
|
+
} else if ($modifyOp.check(opsI)) {
|
|
1657
|
+
opsI._modValue.apply(/** @type {any} */ (op.value), { final })
|
|
1658
|
+
opsI = opNextUndeleted(opsI)
|
|
1621
1659
|
} else if ($insertOp.check(opsI)) {
|
|
1622
|
-
opsI._modValue(offset).apply(op.value)
|
|
1660
|
+
opsI._modValue(offset).apply(op.value, { final })
|
|
1623
1661
|
if (opsI.length === ++offset) {
|
|
1624
|
-
opsI = opsI
|
|
1662
|
+
opsI = opNextUndeleted(opsI)
|
|
1625
1663
|
offset = 0
|
|
1626
1664
|
}
|
|
1627
1665
|
} else if ($retainOp.check(opsI)) {
|
|
@@ -1631,7 +1669,9 @@ export class DeltaBuilder extends Delta {
|
|
|
1631
1669
|
list.insertBetween(this.children, opsI.prev, opsI, cpy) // insert skipped len
|
|
1632
1670
|
offset = 0
|
|
1633
1671
|
}
|
|
1634
|
-
|
|
1672
|
+
const insertModOp = scheduleForMerge(op.clone())
|
|
1673
|
+
opsI.format && updateOpFormat(insertModOp, opsI.format)
|
|
1674
|
+
list.insertBetween(this.children, opsI.prev, opsI, insertModOp) // insert skipped len
|
|
1635
1675
|
if (opsI.length === 1) {
|
|
1636
1676
|
list.remove(this.children, opsI)
|
|
1637
1677
|
} else {
|
|
@@ -1646,7 +1686,7 @@ export class DeltaBuilder extends Delta {
|
|
|
1646
1686
|
} else {
|
|
1647
1687
|
error.unexpectedCase()
|
|
1648
1688
|
}
|
|
1649
|
-
}
|
|
1689
|
+
}
|
|
1650
1690
|
// iterate backwards, to ensure that we merge all content
|
|
1651
1691
|
for (let i = maybeMergeable.length - 1; i >= 0; i--) {
|
|
1652
1692
|
const op = maybeMergeable[i]
|
|
@@ -1660,6 +1700,9 @@ export class DeltaBuilder extends Delta {
|
|
|
1660
1700
|
}
|
|
1661
1701
|
|
|
1662
1702
|
/**
|
|
1703
|
+
* Rebase this op against a concurrent op. We can apply this op on a doc that already applied
|
|
1704
|
+
* `other` op.
|
|
1705
|
+
*
|
|
1663
1706
|
* @param {DeltaAny} other
|
|
1664
1707
|
* @param {boolean} priority
|
|
1665
1708
|
*/
|
|
@@ -1863,12 +1906,23 @@ const updateOpFormat = (op, formatUpdate) => {
|
|
|
1863
1906
|
/** @type {any} */ (op).format = object.assign({}, op.format, { [k]: v })
|
|
1864
1907
|
} else if (op.format != null) {
|
|
1865
1908
|
const { [k]: _, ...rest } = op.format
|
|
1866
|
-
;/** @type {any} */ (op).format = rest
|
|
1909
|
+
;/** @type {any} */ (op).format = object.isEmpty(rest) ? null : rest
|
|
1867
1910
|
}
|
|
1868
1911
|
}
|
|
1869
1912
|
}
|
|
1870
1913
|
}
|
|
1871
1914
|
|
|
1915
|
+
/**
|
|
1916
|
+
* @param {ChildrenOpAny?} op
|
|
1917
|
+
*/
|
|
1918
|
+
const opNextUndeleted = op => {
|
|
1919
|
+
op = op?.next || null
|
|
1920
|
+
while (op != null && $deleteOp.check(op)) {
|
|
1921
|
+
op = op.next
|
|
1922
|
+
}
|
|
1923
|
+
return op
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1872
1926
|
/**
|
|
1873
1927
|
* @template {DeltaConf} Conf
|
|
1874
1928
|
* @extends {s.Schema<Delta<Conf>>}
|
|
@@ -2361,6 +2415,8 @@ export const diff = (d1, d2) => {
|
|
|
2361
2415
|
error.unexpectedCase()
|
|
2362
2416
|
}
|
|
2363
2417
|
}
|
|
2418
|
+
// @todo instead of applying, we want to first exec d, then formattingDiff - we need a merge
|
|
2419
|
+
// function!
|
|
2364
2420
|
d.apply(formattingDiff)
|
|
2365
2421
|
}
|
|
2366
2422
|
for (const attr2 of d2.attrs) {
|
package/src/environment.js
CHANGED
|
@@ -13,6 +13,14 @@ import * as f from './function.js'
|
|
|
13
13
|
/* c8 ignore next */
|
|
14
14
|
export const isNode = /* @__PURE__ */(() => typeof process !== 'undefined' && process.release && /node|io\.js/.test(process.release.name) && Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]')()
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* True iff this script is running in deno
|
|
18
|
+
* @type {boolean}
|
|
19
|
+
*/
|
|
20
|
+
/* c8 ignore next 2 */
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
export const isDeno = /* @__PURE__ */(() => typeof Deno !== 'undefined')()
|
|
23
|
+
|
|
16
24
|
/* c8 ignore next */
|
|
17
25
|
export const isBrowser = /* @__PURE__ */(() => typeof window !== 'undefined' && typeof document !== 'undefined' && !isNode)()
|
|
18
26
|
/* c8 ignore next */
|
package/src/schema.js
CHANGED
|
@@ -487,7 +487,7 @@ export class $StringTemplate extends Schema {
|
|
|
487
487
|
check (o, err) {
|
|
488
488
|
const c = this._r.exec(o) != null
|
|
489
489
|
/* c8 ignore next */
|
|
490
|
-
!c && err?.extend(null, this._r.toString(), o+'', 'String doesn\'t match string template.')
|
|
490
|
+
!c && err?.extend(null, this._r.toString(), o + '', 'String doesn\'t match string template.')
|
|
491
491
|
return c
|
|
492
492
|
}
|
|
493
493
|
}
|
package/src/trait/equality.js
CHANGED
package/src/trait/fingerprint.js
CHANGED
|
@@ -2,7 +2,7 @@ import * as encoding from '../encoding.js'
|
|
|
2
2
|
import * as rabin from '../hash/rabin.js'
|
|
3
3
|
import * as buffer from '../buffer.js'
|
|
4
4
|
|
|
5
|
-
export const FingerprintTraitSymbol = Symbol('
|
|
5
|
+
export const FingerprintTraitSymbol = Symbol.for('0:fingerprint')
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* When implementing this trait, it is recommended to write some sort of "magic number" first to
|
package/types/delta/delta.d.ts
CHANGED
|
@@ -658,10 +658,27 @@ export class DeltaBuilder<Conf extends DeltaConf = {}, FixedConf extends boolean
|
|
|
658
658
|
attrs: AddToAttrs<DeltaConfGetAttrs<Conf>, Key, D>;
|
|
659
659
|
}>, FixedConf>;
|
|
660
660
|
/**
|
|
661
|
+
* Apply other delta on this op. The result is the merged op of both of them.
|
|
662
|
+
*
|
|
663
|
+
* a.apply(b.apply(c))
|
|
664
|
+
*
|
|
665
|
+
* is equivalent to
|
|
666
|
+
*
|
|
667
|
+
* a.apply(b).apply(c)
|
|
668
|
+
*
|
|
669
|
+
* @todo fuzz test the above property
|
|
670
|
+
*
|
|
661
671
|
* @param {Delta<Conf>?} other
|
|
672
|
+
* @param {{ final?: boolean }} opts -- experimental
|
|
673
|
+
* @return {Delta<Conf>}
|
|
662
674
|
*/
|
|
663
|
-
apply(other: Delta<Conf> | null
|
|
675
|
+
apply(other: Delta<Conf> | null, { final }?: {
|
|
676
|
+
final?: boolean;
|
|
677
|
+
}): Delta<Conf>;
|
|
664
678
|
/**
|
|
679
|
+
* Rebase this op against a concurrent op. We can apply this op on a doc that already applied
|
|
680
|
+
* `other` op.
|
|
681
|
+
*
|
|
665
682
|
* @param {DeltaAny} other
|
|
666
683
|
* @param {boolean} priority
|
|
667
684
|
*/
|
|
@@ -1119,6 +1136,9 @@ declare class DeltaData<Name extends string, Attrs extends { [K in string | numb
|
|
|
1119
1136
|
* >}
|
|
1120
1137
|
*/
|
|
1121
1138
|
children: list.List<(Text extends true ? (RetainOp | TextOp | DeleteOp<any>) : never) | (RetainOp | InsertOp<Children> | DeleteOp<any> | (Delta extends Children ? ModifyOp<Extract<Children, Delta>> : never))>;
|
|
1139
|
+
/**
|
|
1140
|
+
* All child-ops sizes combined. Note that delete-ops also have a length
|
|
1141
|
+
*/
|
|
1122
1142
|
childCnt: number;
|
|
1123
1143
|
/**
|
|
1124
1144
|
* @type {any}
|
|
@@ -1129,6 +1149,10 @@ declare class DeltaData<Name extends string, Attrs extends { [K in string | numb
|
|
|
1129
1149
|
*/
|
|
1130
1150
|
_fingerprint: string | null;
|
|
1131
1151
|
isDone: boolean;
|
|
1152
|
+
/**
|
|
1153
|
+
* Is the final document and does not contain delete, modify, or retain ops.
|
|
1154
|
+
*/
|
|
1155
|
+
isFinal: boolean;
|
|
1132
1156
|
}
|
|
1133
1157
|
import * as prng from '../prng.js';
|
|
1134
1158
|
export {};
|
package/types/environment.d.ts
CHANGED