@fluid-experimental/tree 2.23.0 → 2.30.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/CHANGELOG.md +9 -0
- package/api-report/experimental-tree.alpha.api.md +1 -0
- package/dist/EditLog.d.ts +4 -0
- package/dist/EditLog.d.ts.map +1 -1
- package/dist/EditLog.js.map +1 -1
- package/dist/migration-shim/migrationDeltaHandler.d.ts +1 -1
- package/dist/migration-shim/migrationDeltaHandler.d.ts.map +1 -1
- package/dist/migration-shim/migrationDeltaHandler.js +8 -1
- package/dist/migration-shim/migrationDeltaHandler.js.map +1 -1
- package/dist/migration-shim/sharedTreeDeltaHandler.d.ts +1 -2
- package/dist/migration-shim/sharedTreeDeltaHandler.d.ts.map +1 -1
- package/dist/migration-shim/sharedTreeDeltaHandler.js +8 -1
- package/dist/migration-shim/sharedTreeDeltaHandler.js.map +1 -1
- package/lib/EditLog.d.ts +4 -0
- package/lib/EditLog.d.ts.map +1 -1
- package/lib/EditLog.js.map +1 -1
- package/lib/migration-shim/migrationDeltaHandler.d.ts +1 -1
- package/lib/migration-shim/migrationDeltaHandler.d.ts.map +1 -1
- package/lib/migration-shim/migrationDeltaHandler.js +8 -1
- package/lib/migration-shim/migrationDeltaHandler.js.map +1 -1
- package/lib/migration-shim/sharedTreeDeltaHandler.d.ts +1 -2
- package/lib/migration-shim/sharedTreeDeltaHandler.d.ts.map +1 -1
- package/lib/migration-shim/sharedTreeDeltaHandler.js +8 -1
- package/lib/migration-shim/sharedTreeDeltaHandler.js.map +1 -1
- package/package.json +25 -35
- package/src/EditLog.ts +5 -0
- package/src/migration-shim/migrationDeltaHandler.ts +10 -3
- package/src/migration-shim/sharedTreeDeltaHandler.ts +10 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @fluid-experimental/tree
|
|
2
2
|
|
|
3
|
+
## 2.30.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- The OrderedEditSet interface now has a getLocalEdits method ([#23244](https://github.com/microsoft/FluidFramework/pull/23244)) [429c0b717f](https://github.com/microsoft/FluidFramework/commit/429c0b717f37d18da0311dd69fcfc3bd10fea13c)
|
|
8
|
+
|
|
9
|
+
Previously, `EditLog` was imported to cast to this type for access to the `getLocalEdits` method. In addition, the
|
|
10
|
+
`./test/EditLog` export has been removed.
|
|
11
|
+
|
|
3
12
|
## 2.23.0
|
|
4
13
|
|
|
5
14
|
Dependency updates only.
|
|
@@ -496,6 +496,7 @@ export interface OrderedEditSet<TChange = unknown> {
|
|
|
496
496
|
getIdAtIndex(index: number): EditId;
|
|
497
497
|
// (undocumented)
|
|
498
498
|
getIndexOfId(editId: EditId): number;
|
|
499
|
+
getLocalEdits(): Iterable<Edit<TChange>>;
|
|
499
500
|
readonly length: number;
|
|
500
501
|
// @deprecated (undocumented)
|
|
501
502
|
tryGetEdit(editId: EditId): Promise<Edit<TChange> | undefined>;
|
package/dist/EditLog.d.ts
CHANGED
|
@@ -59,6 +59,10 @@ export interface OrderedEditSet<TChange = unknown> {
|
|
|
59
59
|
* @deprecated this will be removed in favor of {@link OrderedEditSet.tryGetEditAtIndex}
|
|
60
60
|
*/
|
|
61
61
|
getEditInSessionAtIndex(index: number): Edit<TChange>;
|
|
62
|
+
/**
|
|
63
|
+
* Gets all local edits.
|
|
64
|
+
*/
|
|
65
|
+
getLocalEdits(): Iterable<Edit<TChange>>;
|
|
62
66
|
}
|
|
63
67
|
/**
|
|
64
68
|
* Server-provided metadata for edits that have been sequenced.
|
package/dist/EditLog.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditLog.d.ts","sourceRoot":"","sources":["../src/EditLog.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAG/E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElG;;;;;GAKG;AACH,MAAM,WAAW,cAAc,CAAC,OAAO,GAAG,OAAO;IAChD;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAEpC;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAErC;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAEpC;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAEpD;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IAE5D;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IAE5D;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;IAE/D;;;OAGG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAEtD;;;OAGG;IACH,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"EditLog.d.ts","sourceRoot":"","sources":["../src/EditLog.ts"],"names":[],"mappings":"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"}
|
package/dist/EditLog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditLog.js","sourceRoot":"","sources":["../src/EditLog.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAAiE;AAEjE,kEAA4E;AAE5E,gEAAkD;AAGlD,2CAAmC;AAiJnC;;GAEG;AACH,SAAgB,iBAAiB,CAAU,IAAmB;IAI7D,MAAM,aAAa,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;IACjD,OAAO,aAAa,CAAC,EAAE,CAAC;IACxB,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,aAAa,EAAE,CAAC;AACvC,CAAC;AAPD,8CAOC;AAED;;;;GAIG;AACH,SAAgB,oCAAoC,CAAC,OAAyC;IAC7F,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE/B,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;QAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,eAAe,EAAE,CAAC;QACnB,CAAC;IACF,CAAC,CAAC,CAAC;IAEH,OAAO,eAAe,CAAC;AACxB,CAAC;AAXD,oFAWC;AAwBD;;;;;;;GAOG;AACH,MAAa,OAA2B,SAAQ,gCAAiC;IAchF;;;OAGG;IACH,IAAW,0BAA0B;QACpC,OAAO,IAAI,CAAC,2BAA2B,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,IAAW,iBAAiB;QAC3B,OAAO,IAAI,CAAC,kBAAkB,CAAC;IAChC,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,YACC,UAAwD,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,EACtE,MAA4B,EAC7C,oBAA0D,EAAE,EAC3C,eAAe,QAAQ,EACvB,oBAAoB,YAAY,GAAG,CAAC,EACrD,uBAAuD,EAAE;QAEzD,KAAK,EAAE,CAAC;QANS,WAAM,GAAN,MAAM,CAAsB;QAE5B,iBAAY,GAAZ,YAAY,CAAW;QACvB,sBAAiB,GAAjB,iBAAiB,CAAmB;QA/C9C,sBAAiB,GAAG,CAAC,CAAC;QAGtB,uBAAkB,GAAG,CAAC,CAAC;QAEd,mBAAc,GAAoB,EAAE,CAAC;QACrC,eAAU,GAAoB,EAAE,CAAC;QAEjC,eAAU,GAAG,IAAI,GAAG,EAAyB,CAAC;QACvD,gCAA2B,GAAG,CAAC,CAAC;QACvB,uBAAkB,GAAG,IAAI,GAAG,EAA6B,CAAC;QAC1D,0BAAqB,GAAG,IAAI,GAAG,EAAuB,CAAC;QAwCvE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAExC,KAAK,MAAM,OAAO,IAAI,iBAAiB,EAAE,CAAC;YACzC,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC;QAED,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;YAC/B,IAAI,YAAY,GAAG,CAAC,IAAI,iBAAiB,GAAG,CAAC,EAAE,CAAC;gBAC/C,IAAA,gBAAI,EAAC,2DAA2D,CAAC,CAAC;YACnE,CAAC;YACD,IAAI,CAAC,qBAAqB,GAAG,IAAI,wBAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACjD,KAAK,MAAM,OAAO,IAAI,oBAAoB,EAAE,CAAC;gBAC5C,IAAI,CAAC,2BAA2B,CAAC,OAAO,CAAC,CAAC;YAC3C,CAAC;QACF,CAAC;QAED,UAAU,CAAC,OAAO,CAAC,CAAC,iBAAiB,EAAE,EAAE;YACxC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,GAAG,iBAAiB,CAAC;YAEnD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1B,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;oBAC7C,MAAM,SAAS,GAAG,aAAa,GAAG,KAAK,CAAC;oBACxC,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;oBAC9B,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;oBAC1C,MAAM,iBAAiB,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBAClD,IAAA,iBAAM,EAAC,iBAAiB,KAAK,SAAS,EAAE,KAAK,CAAC,2BAA2B,CAAC,CAAC;oBAC3E,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC/D,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,8DAA8D;gBAC9D,gFAAgF;gBAChF,uDAAuD;gBACvD,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,SAAS,EAAE,+BAA+B,EAAE,CAAC,CAAC;YAC7E,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACI,wBAAwB,CAAC,OAAkC;QACjE,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrC,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACH,IAAW,iBAAiB;QAC3B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC5C,CAAC;IAED;;;OAGG;IACI,2BAA2B,CAAC,OAA4B;QAC9D,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,IAAW,mBAAmB;QAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,IAAW,MAAM;QAChB,OAAO,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,kBAAkB,CAAC;IAC9D,CAAC;IAED;;OAEG;IACH,IAAW,sBAAsB;QAChC,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,IAAW,kBAAkB;QAC5B,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,IAAW,OAAO;QACjB,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5F,CAAC;IAED;;OAEG;IACI,WAAW,CAAC,MAAc;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1C,OAAO,KAAK,EAAE,OAAO,IAAI,KAAK,CAAC;IAChC,CAAC;IAED;;OAEG;IACI,mBAAmB,CAAC,QAAgB;QAC1C,OAAO,QAAQ,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC;IAC/C,CAAC;IAED;;OAEG;IACI,eAAe,CAAC,MAAc;QACpC,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;YACzB,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,IAAA,gBAAI,EAAC,gBAAgB,CAAC,CAAC;YACxF,IAAA,iBAAM,EAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,gCAAgC,CAAC,CAAC;YACnE,OAAO,CACN,IAAI,CAAC,2BAA2B;gBAChC,IAAI,CAAC,sBAAsB;gBAC3B,WAAW,CAAC,aAAa;gBACzB,UAAU,CAAC,aAAa,CACxB,CAAC;QACH,CAAC;QACD,OAAO,WAAW,CAAC,KAAK,CAAC;IAC1B,CAAC;IAED;;OAEG;IACI,gBAAgB,CAAC,MAAc;QACrC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAA,gBAAI,EAAC,oCAAoC,CAAC,CAAC;IAClF,CAAC;IAED;;OAEG;IACI,YAAY,CAAC,MAAc;QACjC,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,IAAA,gBAAI,EAAC,gBAAgB,CAAC,CAAC;IAC/D,CAAC;IAED;;OAEG;IACI,YAAY,CAAC,KAAa;QAChC,IAAI,IAAI,CAAC,2BAA2B,GAAG,IAAI,CAAC,sBAAsB,IAAI,KAAK,EAAE,CAAC;YAC7E,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,CAAC,EAAE,CAAC;QAChE,CAAC;QAED,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,GAAG,IAAI,CAAC,2BAA2B,CAAC,CAAC,EAAE,CAAC;IACzE,CAAC;IAED;;OAEG;IACI,iBAAiB,CAAC,KAAa;QACrC,IAAI,IAAI,CAAC,2BAA2B,GAAG,IAAI,CAAC,sBAAsB,IAAI,KAAK,EAAE,CAAC;YAC7E,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,GAAG,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACtE,CAAC;IAED;;OAEG;IACI,gBAAgB,CAAC,MAAc;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC3C,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,CAAC;IAED;;OAEG;IACI,kBAAkB;QACxB,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC;IAChF,CAAC;IAED;;;;OAIG;IACI,gBAAgB,CAAC,IAAmB,EAAE,OAA8B;QAC1E,IAAI,CAAC,wBAAwB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC7E,CAAC;IAED;;;;OAIG;IACI,CAAC,aAAa;QACpB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpC,MAAM,IAAI,CAAC;QACZ,CAAC;IACF,CAAC;IAED;;;OAGG;IACK,wBAAwB,CAC/B,IAAmB,EACnB,IAAyB,EACzB,oBAA4B,CAAC;QAE7B,IAAA,iBAAM,EACL,iBAAiB,IAAI,IAAI,CAAC,kBAAkB,EAC5C,KAAK,CAAC,wEAAwE,CAC9E,CAAC;QACF,IAAI,CAAC,kBAAkB,GAAG,iBAAiB,CAAC;QAE5C,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;QACpB,yCAAyC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,2BAA2B,GAAG,IAAI,CAAC,sBAAsB,CAAC;QAE7E,iDAAiD;QACjD,MAAM,iBAAiB,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClD,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;YACrC,0DAA0D;YAC1D,IAAA,iBAAM,EAAC,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC,2BAA2B,CAAC,CAAC;YACrE,6EAA6E;YAC7E,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,IAAA,gBAAI,EAAC,yBAAyB,CAAC,CAAC;YACtF,IAAA,iBAAM,EAAC,cAAc,KAAK,EAAE,EAAE,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE/B,MAAM,eAAe,GAA2B;YAC/C,KAAK;YACL,OAAO,EAAE,KAAK;YACd,YAAY,EAAE,IAAI;SAClB,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;QACzC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,qBAAqB,EAAE,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QAC7D,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,iBAAiB,KAAK,SAAS,CAAC,CAAC;QAE3D,6DAA6D;QAC7D,IAAI,IAAI,CAAC,qBAAqB,KAAK,SAAS,IAAI,IAAI,CAAC,sBAAsB,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvG,IAAI,CAAC,UAAU,EAAE,CAAC;QACnB,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,YAAY,CAAC,IAAmB;QACtC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,MAAM,WAAW,GAAuB;YACvC,aAAa,EAAE,IAAI,CAAC,iBAAiB,EAAE;YACvC,OAAO,EAAE,IAAI;SACb,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IAEO,OAAO,CAAC,SAAwB,EAAE,OAAgB,EAAE,QAAiB;QAC5E,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC/C,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QACvC,CAAC;IACF,CAAC;IAEO,UAAU;QACjB,IAAA,iBAAM,EACL,IAAI,CAAC,qBAAqB,KAAK,SAAS,EACxC,KAAK,CAAC,2EAA2E,CACjF,CAAC;QAEF,MAAM,gBAAgB,GACrB,IAAI,CAAC,qBAAqB,CAAC,mBAAmB,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5E,IAAA,gBAAI,EAAC,gDAAgD,CAAC,CAAC;QACxD,4DAA4D;QAC5D,MAAM,sBAAsB,GAAG,gBAAgB,GAAG,IAAI,CAAC,0BAA0B,CAAC;QAElF,IAAI,sBAAsB,GAAG,CAAC,EAAE,CAAC;YAChC,kGAAkG;YAClG,MAAM,2BAA2B,GAAG,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,YAAY,CAAC;YACpF,MAAM,oBAAoB,GAAG,IAAI,CAAC,GAAG,CAAC,sBAAsB,EAAE,2BAA2B,CAAC,CAAC;YAC3F,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAClD,OAAO,CAAC,oBAAoB,CAAC,CAAC;YAC/B,CAAC;YAED,4DAA4D;YAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;YACzE,IAAI,CAAC,2BAA2B,IAAI,oBAAoB,CAAC;YAEzD,yEAAyE;YACzE,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YAEhE,0FAA0F;YAC1F,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;QAC3E,CAAC;IACF,CAAC;IAED;;OAEG;IACI,MAAM,CAA4B,KAAyC;QACjF,8GAA8G;QAC9G,2GAA2G;QAC3G,OAAO,IAAA,wBAAa,EAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC;IAcM,iBAAiB,CACvB,YAAiG;QAEjG,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QACxD,OAAO,YAAY,KAAK,SAAS;YAChC,CAAC,CAAC;gBACA,UAAU,EACT,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC;oBAC/B,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC;wBACA;4BACC,0CAA0C;4BAC1C,aAAa,EAAE,CAAC;4BAChB,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;yBAC5D;qBACD;gBACJ,OAAO;aACP;YACF,CAAC,CAAC;gBACA,UAAU,EACT,IAAI,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC;oBAC/B,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC;wBACA;4BACC,0CAA0C;4BAC1C,aAAa,EAAE,CAAC;4BAChB,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;yBAC9D;qBACD;gBACJ,OAAO;aACP,CAAC;IACL,CAAC;IAED,kDAAkD;IAClD;;OAEG;IACI,KAAK,CAAC,UAAU,CAAC,MAAc;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC3C,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,cAAc,CAAC,KAAa;QACxC,OAAO,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,IAAA,gBAAI,EAAC,gBAAgB,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACI,uBAAuB,CAAC,KAAa;QAC3C,OAAO,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,IAAA,gBAAI,EAAC,gBAAgB,CAAC,CAAC;IAChE,CAAC;CACD;AAjbD,0BAibC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { TypedEventEmitter } from '@fluid-internal/client-utils';\nimport type { IEvent } from '@fluidframework/core-interfaces';\nimport { assert, compareArrays } from '@fluidframework/core-utils/internal';\nimport { ITelemetryLoggerExt } from '@fluidframework/telemetry-utils/internal';\nimport { BTree } from '@tylerbu/sorted-btree-es6';\n\nimport type { ChangeCompressor } from './ChangeCompression.js';\nimport { fail } from './Common.js';\nimport type { EditId } from './Identifiers.js';\nimport type { StringInterner } from './StringInterner.js';\nimport { Edit, EditLogSummary, EditWithoutId, FluidEditHandle } from './persisted-types/index.js';\n\n/**\n * An ordered set of Edits associated with a SharedTree.\n * Supports fast lookup of edits by ID and enforces idempotence.\n * @sealed\n * @alpha\n */\nexport interface OrderedEditSet<TChange = unknown> {\n\t/**\n\t * The length of this `OrderedEditSet`.\n\t */\n\treadonly length: number;\n\n\t/**\n\t * The edit IDs of all edits in the log.\n\t */\n\treadonly editIds: readonly EditId[];\n\n\t/**\n\t * @returns the index of the edit with the given editId within this `OrderedEditSet`.\n\t */\n\tgetIndexOfId(editId: EditId): number;\n\n\t/**\n\t * @returns the id of the edit at the given index within this 'OrderedEditSet'.\n\t */\n\tgetIdAtIndex(index: number): EditId;\n\n\t/**\n\t * @returns the index of the edit with the given editId within this `OrderedEditSet`, or `undefined` if no such edit exists.\n\t */\n\ttryGetIndexOfId(editId: EditId): number | undefined;\n\n\t/**\n\t * @returns the edit at the given index within this `OrderedEditSet`.\n\t */\n\ttryGetEditAtIndex(index: number): Edit<TChange> | undefined;\n\n\t/**\n\t * @returns the edit with the given identifier within this `OrderedEditSet`.\n\t */\n\ttryGetEditFromId(editId: EditId): Edit<TChange> | undefined;\n\n\t/**\n\t * @returns the Edit associated with the EditId or undefined if there is no such edit in the set.\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\ttryGetEdit(editId: EditId): Promise<Edit<TChange> | undefined>;\n\n\t/**\n\t * @returns the edit at the given index within this `OrderedEditSet`.\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs.\n\t */\n\tgetEditAtIndex(index: number): Promise<Edit<TChange>>;\n\n\t/**\n\t * @returns the edit at the given index. Must have been added to the log during the current session.\n\t * @deprecated this will be removed in favor of {@link OrderedEditSet.tryGetEditAtIndex}\n\t */\n\tgetEditInSessionAtIndex(index: number): Edit<TChange>;\n}\n\n/**\n * Server-provided metadata for edits that have been sequenced.\n */\nexport interface EditSequencingInfo {\n\t/**\n\t * The server-assigned sequence number of the op.\n\t */\n\treadonly sequenceNumber: number;\n\t/**\n\t * Last known sequenced edit at the time this op was issued.\n\t */\n\treadonly referenceSequenceNumber: number;\n}\n\n/**\n * Server-provided metadata for edits that have been sequenced.\n */\nexport interface MessageSequencingInfo extends EditSequencingInfo {\n\t/**\n\t * Last sequenced edit that all clients are guaranteed to be aware of.\n\t * If not specified, then some clients have not seen any edits yet.\n\t */\n\treadonly minimumSequenceNumber?: number;\n}\n\n/**\n * Metadata for a sequenced edit.\n */\nexport interface SequencedOrderedEditId {\n\treadonly isLocal: false;\n\treadonly index: number;\n\t/**\n\t * Information about the edit's relationship to other sequenced edits.\n\t * Undefined iff the edit was loaded from a summary.\n\t */\n\treadonly sequenceInfo?: EditSequencingInfo;\n}\n\n/**\n * Metadata for a local edit.\n */\nexport interface LocalOrderedEditId {\n\treadonly isLocal: true;\n\treadonly localSequence: number;\n}\n\n/**\n * Metadata for an edit.\n */\nexport type OrderedEditId = SequencedOrderedEditId | LocalOrderedEditId;\n\n/**\n * Compressor+interner pair used for encoding an {@link EditLog} into a summary.\n * @internal\n */\nexport interface EditLogEncoder {\n\tcompressor: ChangeCompressor;\n\tinterner: StringInterner;\n}\n\n/**\n * A sequence of edits that may or may not need to be downloaded into the EditLog from an external service\n * @deprecated Edit virtualization is no longer supported.\n */\nexport interface EditChunk<TChange> {\n\thandle?: EditHandle<TChange>;\n\tedits?: EditWithoutId<TChange>[];\n}\n/**\n * EditHandles are used to load edit chunks stored outside of the EditLog.\n * This is typically implemented by a wrapper around an IFluidHandle<ArrayBufferLike>.\n * @deprecated Edit virtualization is no longer supported.\n * @internal\n */\nexport interface EditHandle<TChange> {\n\treadonly get: () => Promise<EditWithoutId<TChange>[]>;\n\treadonly baseHandle: FluidEditHandle;\n}\n\n/**\n * Returns an object that separates an Edit into two fields, id and editWithoutId.\n */\nexport function separateEditAndId<TChange>(edit: Edit<TChange>): {\n\tid: EditId;\n\teditWithoutId: EditWithoutId<TChange>;\n} {\n\tconst editWithoutId = { ...edit, id: undefined };\n\tdelete editWithoutId.id;\n\treturn { id: edit.id, editWithoutId };\n}\n\n/**\n * @param summary - The edit log summary to parse.\n * @returns the number of handles saved to the provided edit log summary.\n * @deprecated Edit virtualization is no longer supported.\n */\nexport function getNumberOfHandlesFromEditLogSummary(summary: EditLogSummary<unknown, unknown>): number {\n\tconst { editChunks } = summary;\n\n\tlet numberOfHandles = 0;\n\teditChunks.forEach(({ chunk }) => {\n\t\tif (!Array.isArray(chunk)) {\n\t\t\tnumberOfHandles++;\n\t\t}\n\t});\n\n\treturn numberOfHandles;\n}\n\n/**\n * Event fired when an edit is added to an `EditLog`.\n * @param edit - The edit that was added to the log\n * @param isLocal - true iff this edit was generated locally\n */\nexport type EditAddedHandler<TChange> = (edit: Edit<TChange>, isLocal: boolean, wasLocal: boolean) => void;\n\n/**\n * Event fired before edits are evicted from the edit log. It takes in a count of the number of edits to evict\n * starting from the oldest in memory edit. To get the edit itself, call {@link EditLog.getEditAtIndex}.\n * The edit index corresponds to the count + {@link EditLog.earliestAvailableEditIndex}.\n */\nexport type EditEvictionHandler = (editsToEvict: number) => void;\n\n/**\n * Events which may be emitted by {@link EditLog}\n * @alpha\n */\nexport interface IEditLogEvents extends IEvent {\n\t(event: 'unexpectedHistoryChunk', listener: () => void);\n}\n\n/**\n * The edit history log for SharedTree.\n * Contains only completed edits (no in-progress edits).\n * Ordered first by locality (acked or local), then by time of insertion.\n * May not contain more than one edit with the same ID.\n * @sealed\n * @alpha\n */\nexport class EditLog<TChange = unknown> extends TypedEventEmitter<IEditLogEvents> implements OrderedEditSet<TChange> {\n\tprivate localEditSequence = 0;\n\n\tprivate readonly sequenceNumberToIndex?: BTree<number, number>;\n\tprivate _minSequenceNumber = 0;\n\n\tprivate readonly sequencedEdits: Edit<TChange>[] = [];\n\tprivate readonly localEdits: Edit<TChange>[] = [];\n\n\tprivate readonly allEditIds = new Map<EditId, OrderedEditId>();\n\tprivate _earliestAvailableEditIndex = 0;\n\tprivate readonly _editAddedHandlers = new Set<EditAddedHandler<TChange>>();\n\tprivate readonly _editEvictionHandlers = new Set<EditEvictionHandler>();\n\n\t/**\n\t * @returns The index of the earliest edit stored in this log.\n\t * Edit indices are unique and strictly increasing within the session.\n\t */\n\tpublic get earliestAvailableEditIndex(): number {\n\t\treturn this._earliestAvailableEditIndex;\n\t}\n\n\t/**\n\t * @returns The sequence number of the latest edit known by all nodes.\n\t */\n\tpublic get minSequenceNumber(): number {\n\t\treturn this._minSequenceNumber;\n\t}\n\n\t/**\n\t * Construct an `EditLog` using the given options.\n\t * @param summary - An edit log summary used to populate the edit log.\n\t * @param logger - An optional logger to record telemetry/errors\n\t * @param editAddedHandlers - Optional handlers that are called when edits are added.\n\t * @param targetLength - The target number of sequenced edits that the log will try to store in memory.\n\t * Depending on eviction frequency and the collaboration window, there can be more edits in memory at a given time.\n\t * Edits greater than or equal to the `minSequenceNumber` (aka in the collaboration window) are not evicted.\n\t * @param evictionFrequency - The rate at which edits are evicted from memory. This is a factor of the editLogSize.\n\t * For example, with the default frequency of inMemoryHistorySize * 2 and a size of 10, the log will evict once it reaches 20 sequenced edits\n\t * down to 10 edits, also keeping any that are still in the collaboration window.\n\t * @param editEvictionHandlers - Handlers that are called before edits are evicted from memory. This provides a chance for\n\t * callers to work with the edits before they are lost.\n\t */\n\tpublic constructor(\n\t\tsummary: EditLogSummary<TChange, EditHandle<TChange>> = { editIds: [], editChunks: [] },\n\t\tprivate readonly logger?: ITelemetryLoggerExt,\n\t\teditAddedHandlers: readonly EditAddedHandler<TChange>[] = [],\n\t\tprivate readonly targetLength = Infinity,\n\t\tprivate readonly evictionFrequency = targetLength * 2,\n\t\teditEvictionHandlers: readonly EditEvictionHandler[] = []\n\t) {\n\t\tsuper();\n\t\tconst { editChunks, editIds } = summary;\n\n\t\tfor (const handler of editAddedHandlers) {\n\t\t\tthis.registerEditAddedHandler(handler);\n\t\t}\n\n\t\tif (targetLength !== Infinity) {\n\t\t\tif (targetLength < 0 || evictionFrequency < 0) {\n\t\t\t\tfail('targetLength and evictionFrequency should not be negative');\n\t\t\t}\n\t\t\tthis.sequenceNumberToIndex = new BTree([[0, 0]]);\n\t\t\tfor (const handler of editEvictionHandlers) {\n\t\t\t\tthis.registerEditEvictionHandler(handler);\n\t\t\t}\n\t\t}\n\n\t\teditChunks.forEach((editChunkOrHandle) => {\n\t\t\tconst { startRevision, chunk } = editChunkOrHandle;\n\n\t\t\tif (Array.isArray(chunk)) {\n\t\t\t\tfor (const [index, edit] of chunk.entries()) {\n\t\t\t\t\tconst editIndex = startRevision + index;\n\t\t\t\t\tconst id = editIds[editIndex];\n\t\t\t\t\tthis.sequencedEdits.push({ id, ...edit });\n\t\t\t\t\tconst encounteredEditId = this.allEditIds.get(id);\n\t\t\t\t\tassert(encounteredEditId === undefined, 0x60a /* Duplicate acked edit. */);\n\t\t\t\t\tthis.allEditIds.set(id, { isLocal: false, index: editIndex });\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Ignore any edit handles, these edits are now unrecoverable.\n\t\t\t\t// This should instead download the edit chunk and store them but history is not\n\t\t\t\t// being used so we're going with the simpler solution.\n\t\t\t\tthis.logger?.sendErrorEvent({ eventName: 'UnexpectedEditHandleInSummary' });\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Registers a handler for when an edit is added to this `EditLog`.\n\t * @returns A callback which can be invoked to unregister this handler.\n\t */\n\tpublic registerEditAddedHandler(handler: EditAddedHandler<TChange>): () => void {\n\t\tthis._editAddedHandlers.add(handler);\n\t\treturn () => this._editAddedHandlers.delete(handler);\n\t}\n\n\t/**\n\t * @returns the `EditAddedHandler`s registered on this `EditLog`.\n\t */\n\tpublic get editAddedHandlers(): readonly EditAddedHandler<TChange>[] {\n\t\treturn Array.from(this._editAddedHandlers);\n\t}\n\n\t/**\n\t * Registers a handler that is called before an edit is evicted from this `EditLog`.\n\t * @returns A callback which can be invoked to unregister this handler.\n\t */\n\tpublic registerEditEvictionHandler(handler: EditEvictionHandler): () => void {\n\t\tthis._editEvictionHandlers.add(handler);\n\t\treturn () => this._editEvictionHandlers.delete(handler);\n\t}\n\n\t/**\n\t * @returns the `EditEvictedHandler`s registered on this `EditLog`.\n\t */\n\tpublic get editEvictedHandlers(): readonly EditEvictionHandler[] {\n\t\treturn Array.from(this._editEvictionHandlers);\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.length}\n\t */\n\tpublic get length(): number {\n\t\treturn this.numberOfSequencedEdits + this.numberOfLocalEdits;\n\t}\n\n\t/**\n\t * The number of sequenced (acked) edits in the log.\n\t */\n\tpublic get numberOfSequencedEdits(): number {\n\t\treturn this.sequencedEdits.length;\n\t}\n\n\t/**\n\t * The number of local (unacked) edits in the log.\n\t */\n\tpublic get numberOfLocalEdits(): number {\n\t\treturn this.localEdits.length;\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.editIds}\n\t */\n\tpublic get editIds(): EditId[] {\n\t\treturn this.sequencedEdits.map(({ id }) => id).concat(this.localEdits.map(({ id }) => id));\n\t}\n\n\t/**\n\t * @returns true iff the edit is contained in this 'EditLog' and it is a local edit (not sequenced).\n\t */\n\tpublic isLocalEdit(editId: EditId): boolean {\n\t\tconst entry = this.allEditIds.get(editId);\n\t\treturn entry?.isLocal ?? false;\n\t}\n\n\t/**\n\t * @returns true iff the revision is a sequenced revision (not local).\n\t */\n\tpublic isSequencedRevision(revision: number): boolean {\n\t\treturn revision <= this.sequencedEdits.length;\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.tryGetIndexOfId}\n\t */\n\tpublic tryGetIndexOfId(editId: EditId): number | undefined {\n\t\tconst orderedEdit = this.allEditIds.get(editId);\n\t\tif (orderedEdit === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (orderedEdit.isLocal) {\n\t\t\tconst firstLocal = this.allEditIds.get(this.localEdits[0].id) ?? fail('edit not found');\n\t\t\tassert(firstLocal.isLocal, 0x60b /* local edit should be local */);\n\t\t\treturn (\n\t\t\t\tthis._earliestAvailableEditIndex +\n\t\t\t\tthis.numberOfSequencedEdits +\n\t\t\t\torderedEdit.localSequence -\n\t\t\t\tfirstLocal.localSequence\n\t\t\t);\n\t\t}\n\t\treturn orderedEdit.index;\n\t}\n\n\t/**\n\t * @returns Edit metadata for the edit with the given `editId`.\n\t */\n\tpublic getOrderedEditId(editId: EditId): OrderedEditId {\n\t\treturn this.allEditIds.get(editId) ?? fail('All edits should exist in this map');\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.getIndexOfId}\n\t */\n\tpublic getIndexOfId(editId: EditId): number {\n\t\treturn this.tryGetIndexOfId(editId) ?? fail('edit not found');\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.getIdAtIndex}\n\t */\n\tpublic getIdAtIndex(index: number): EditId {\n\t\tif (this._earliestAvailableEditIndex + this.numberOfSequencedEdits <= index) {\n\t\t\treturn this.localEdits[index - this.numberOfSequencedEdits].id;\n\t\t}\n\n\t\treturn this.sequencedEdits[index - this._earliestAvailableEditIndex].id;\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.tryGetEditAtIndex}\n\t */\n\tpublic tryGetEditAtIndex(index: number): Edit<TChange> | undefined {\n\t\tif (this._earliestAvailableEditIndex + this.numberOfSequencedEdits <= index) {\n\t\t\treturn this.localEdits[index - this.numberOfSequencedEdits];\n\t\t}\n\n\t\treturn this.sequencedEdits[index - this._earliestAvailableEditIndex];\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.tryGetEditFromId}\n\t */\n\tpublic tryGetEditFromId(editId: EditId): Edit<TChange> | undefined {\n\t\tconst index = this.tryGetIndexOfId(editId);\n\t\treturn index !== undefined ? this.tryGetEditAtIndex(index) : undefined;\n\t}\n\n\t/**\n\t * Sequences all local edits.\n\t */\n\tpublic sequenceLocalEdits(): void {\n\t\tthis.localEdits.slice().forEach((edit) => this.addSequencedEditInternal(edit));\n\t}\n\n\t/**\n\t * Adds a sequenced (non-local) edit to the edit log.\n\t * If the id of the supplied edit matches a local edit already present in the log, the local edit will be replaced.\n\t *\n\t */\n\tpublic addSequencedEdit(edit: Edit<TChange>, message: MessageSequencingInfo): void {\n\t\tthis.addSequencedEditInternal(edit, message, message.minimumSequenceNumber);\n\t}\n\n\t/**\n\t * Returns all local edits from this EditLog\n\t * This is useful for op format upgrades, which might warrant re-submission of these ops using the new format.\n\t * See the breaking change documentation for more information.\n\t */\n\tpublic *getLocalEdits(): Iterable<Edit<TChange>> {\n\t\tfor (const edit of this.localEdits) {\n\t\t\tyield edit;\n\t\t}\n\t}\n\n\t/**\n\t * Adds a sequenced (non-local) edit to the edit log.\n\t * If the id of the supplied edit matches a local edit already present in the log, the local edit will be replaced.\n\t */\n\tprivate addSequencedEditInternal(\n\t\tedit: Edit<TChange>,\n\t\tinfo?: EditSequencingInfo,\n\t\tminSequenceNumber: number = 0\n\t): void {\n\t\tassert(\n\t\t\tminSequenceNumber >= this._minSequenceNumber,\n\t\t\t0x60c /* Sequenced edits should carry a monotonically increasing min number */\n\t\t);\n\t\tthis._minSequenceNumber = minSequenceNumber;\n\n\t\tconst { id } = edit;\n\t\t// The index of the sequenced edit to add\n\t\tconst index = this._earliestAvailableEditIndex + this.numberOfSequencedEdits;\n\n\t\t// Remove the edit from local edits if it exists.\n\t\tconst encounteredEditId = this.allEditIds.get(id);\n\t\tif (encounteredEditId !== undefined) {\n\t\t\t// New edit already exits: it must have been a local edit.\n\t\t\tassert(encounteredEditId.isLocal, 0x60d /* Duplicate acked edit. */);\n\t\t\t// Remove it from localEdits. Due to ordering requirements, it must be first.\n\t\t\tconst oldLocalEditId = this.localEdits.shift()?.id ?? fail('Local edit should exist');\n\t\t\tassert(oldLocalEditId === id, 0x60e /* Causal ordering should be upheld */);\n\t\t}\n\n\t\tthis.sequencedEdits.push(edit);\n\n\t\tconst sequencedEditId: SequencedOrderedEditId = {\n\t\t\tindex,\n\t\t\tisLocal: false,\n\t\t\tsequenceInfo: info,\n\t\t};\n\t\tthis.allEditIds.set(id, sequencedEditId);\n\t\tif (info !== undefined) {\n\t\t\tthis.sequenceNumberToIndex?.set(info.sequenceNumber, index);\n\t\t}\n\t\tthis.emitAdd(edit, false, encounteredEditId !== undefined);\n\n\t\t// Check if any edits need to be evicted due to this addition\n\t\tif (this.sequenceNumberToIndex !== undefined && this.numberOfSequencedEdits >= this.evictionFrequency) {\n\t\t\tthis.evictEdits();\n\t\t}\n\t}\n\n\t/**\n\t * Adds a non-sequenced (local) edit to the edit log.\n\t * Duplicate edits are ignored.\n\t */\n\tpublic addLocalEdit(edit: Edit<TChange>): void {\n\t\tthis.localEdits.push(edit);\n\t\tconst localEditId: LocalOrderedEditId = {\n\t\t\tlocalSequence: this.localEditSequence++,\n\t\t\tisLocal: true,\n\t\t};\n\t\tthis.allEditIds.set(edit.id, localEditId);\n\t\tthis.emitAdd(edit, true, false);\n\t}\n\n\tprivate emitAdd(editAdded: Edit<TChange>, isLocal: boolean, wasLocal: boolean): void {\n\t\tfor (const handler of this._editAddedHandlers) {\n\t\t\thandler(editAdded, isLocal, wasLocal);\n\t\t}\n\t}\n\n\tprivate evictEdits(): void {\n\t\tassert(\n\t\t\tthis.sequenceNumberToIndex !== undefined,\n\t\t\t0x60f /* Edits should never be evicted if the target length is set to infinity */\n\t\t);\n\n\t\tconst minSequenceIndex =\n\t\t\tthis.sequenceNumberToIndex.getPairOrNextHigher(this._minSequenceNumber)?.[1] ??\n\t\t\tfail('No index associated with that sequence number.');\n\t\t// Exclude any edits in the collab window from being evicted\n\t\tconst numberOfEvictableEdits = minSequenceIndex - this.earliestAvailableEditIndex;\n\n\t\tif (numberOfEvictableEdits > 0) {\n\t\t\t// Evict either all but the target log size or the number of evictable edits, whichever is smaller\n\t\t\tconst numberOfDesiredEditsToEvict = this.numberOfSequencedEdits - this.targetLength;\n\t\t\tconst numberOfEditsToEvict = Math.min(numberOfEvictableEdits, numberOfDesiredEditsToEvict);\n\t\t\tfor (const handler of this._editEvictionHandlers) {\n\t\t\t\thandler(numberOfEditsToEvict);\n\t\t\t}\n\n\t\t\t// Remove the edits and move up the earliest available index\n\t\t\tconst removedEdits = this.sequencedEdits.splice(0, numberOfEditsToEvict);\n\t\t\tthis._earliestAvailableEditIndex += numberOfEditsToEvict;\n\n\t\t\t// On eviction, we need to remove the IDs of edits that have been evicted\n\t\t\tremovedEdits.forEach((edit) => this.allEditIds.delete(edit.id));\n\n\t\t\t// The minSequenceNumber is strictly increasing so we can clear sequence numbers before it\n\t\t\tthis.sequenceNumberToIndex.deleteRange(0, this._minSequenceNumber, false);\n\t\t}\n\t}\n\n\t/**\n\t * @returns true iff this `EditLog` and `other` are equivalent, regardless of locality.\n\t */\n\tpublic equals<TOtherChangeTypesInternal>(other: EditLog<TOtherChangeTypesInternal>): boolean {\n\t\t// TODO #45414: We should also be deep comparing the list of changes in the edit. This is not straightforward.\n\t\t// We can use our edit validation code when we write it since it will need to do deep walks of the changes.\n\t\treturn compareArrays(this.editIds, other.editIds);\n\t}\n\n\t/**\n\t * @returns the summary of this `OrderedEditSet` that can be used to reconstruct the edit set.\n\t */\n\tpublic getEditLogSummary(): EditLogSummary<TChange, FluidEditHandle>;\n\n\t/**\n\t * @param compressEdit - a function which compresses edits\n\t * @returns the summary of this `OrderedEditSet` that can be used to reconstruct the edit set.\n\t */\n\tpublic getEditLogSummary<TCompressedChange>(\n\t\tcompressEdit: (edit: Pick<Edit<TChange>, 'changes'>) => Pick<Edit<TCompressedChange>, 'changes'>\n\t): EditLogSummary<TCompressedChange, FluidEditHandle>;\n\tpublic getEditLogSummary<TCompressedChange>(\n\t\tcompressEdit?: (edit: Pick<Edit<TChange>, 'changes'>) => Pick<Edit<TCompressedChange>, 'changes'>\n\t): EditLogSummary<TChange, FluidEditHandle> | EditLogSummary<TCompressedChange, FluidEditHandle> {\n\t\tconst editIds = this.sequencedEdits.map(({ id }) => id);\n\t\treturn compressEdit !== undefined\n\t\t\t? {\n\t\t\t\t\teditChunks:\n\t\t\t\t\t\tthis.sequencedEdits.length === 0\n\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t// Store all edits within a single \"chunk\"\n\t\t\t\t\t\t\t\t\t\tstartRevision: 0,\n\t\t\t\t\t\t\t\t\t\tchunk: this.sequencedEdits.map((edit) => compressEdit(edit)),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\teditIds,\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\teditChunks:\n\t\t\t\t\t\tthis.sequencedEdits.length === 0\n\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t// Store all edits within a single \"chunk\"\n\t\t\t\t\t\t\t\t\t\tstartRevision: 0,\n\t\t\t\t\t\t\t\t\t\tchunk: this.sequencedEdits.map(({ changes }) => ({ changes })),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\teditIds,\n\t\t\t\t};\n\t}\n\n\t// APIS DEPRECATED DUE TO HISTORY'S PEACEFUL DEATH\n\t/**\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\tpublic async tryGetEdit(editId: EditId): Promise<Edit<TChange> | undefined> {\n\t\tconst index = this.tryGetIndexOfId(editId);\n\t\treturn index !== undefined ? this.tryGetEditAtIndex(index) : undefined;\n\t}\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\tpublic async getEditAtIndex(index: number): Promise<Edit<TChange>> {\n\t\treturn this.tryGetEditAtIndex(index) ?? fail('Edit not found');\n\t}\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\tpublic getEditInSessionAtIndex(index: number): Edit<TChange> {\n\t\treturn this.tryGetEditAtIndex(index) ?? fail('Edit not found');\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"EditLog.js","sourceRoot":"","sources":["../src/EditLog.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { TypedEventEmitter } from '@fluid-internal/client-utils';\nimport type { IEvent } from '@fluidframework/core-interfaces';\nimport { assert, compareArrays } from '@fluidframework/core-utils/internal';\nimport { ITelemetryLoggerExt } from '@fluidframework/telemetry-utils/internal';\nimport { BTree } from '@tylerbu/sorted-btree-es6';\n\nimport type { ChangeCompressor } from './ChangeCompression.js';\nimport { fail } from './Common.js';\nimport type { EditId } from './Identifiers.js';\nimport type { StringInterner } from './StringInterner.js';\nimport { Edit, EditLogSummary, EditWithoutId, FluidEditHandle } from './persisted-types/index.js';\n\n/**\n * An ordered set of Edits associated with a SharedTree.\n * Supports fast lookup of edits by ID and enforces idempotence.\n * @sealed\n * @alpha\n */\nexport interface OrderedEditSet<TChange = unknown> {\n\t/**\n\t * The length of this `OrderedEditSet`.\n\t */\n\treadonly length: number;\n\n\t/**\n\t * The edit IDs of all edits in the log.\n\t */\n\treadonly editIds: readonly EditId[];\n\n\t/**\n\t * @returns the index of the edit with the given editId within this `OrderedEditSet`.\n\t */\n\tgetIndexOfId(editId: EditId): number;\n\n\t/**\n\t * @returns the id of the edit at the given index within this 'OrderedEditSet'.\n\t */\n\tgetIdAtIndex(index: number): EditId;\n\n\t/**\n\t * @returns the index of the edit with the given editId within this `OrderedEditSet`, or `undefined` if no such edit exists.\n\t */\n\ttryGetIndexOfId(editId: EditId): number | undefined;\n\n\t/**\n\t * @returns the edit at the given index within this `OrderedEditSet`.\n\t */\n\ttryGetEditAtIndex(index: number): Edit<TChange> | undefined;\n\n\t/**\n\t * @returns the edit with the given identifier within this `OrderedEditSet`.\n\t */\n\ttryGetEditFromId(editId: EditId): Edit<TChange> | undefined;\n\n\t/**\n\t * @returns the Edit associated with the EditId or undefined if there is no such edit in the set.\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\ttryGetEdit(editId: EditId): Promise<Edit<TChange> | undefined>;\n\n\t/**\n\t * @returns the edit at the given index within this `OrderedEditSet`.\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs.\n\t */\n\tgetEditAtIndex(index: number): Promise<Edit<TChange>>;\n\n\t/**\n\t * @returns the edit at the given index. Must have been added to the log during the current session.\n\t * @deprecated this will be removed in favor of {@link OrderedEditSet.tryGetEditAtIndex}\n\t */\n\tgetEditInSessionAtIndex(index: number): Edit<TChange>;\n\n\t/**\n\t * Gets all local edits.\n\t */\n\tgetLocalEdits(): Iterable<Edit<TChange>>;\n}\n\n/**\n * Server-provided metadata for edits that have been sequenced.\n */\nexport interface EditSequencingInfo {\n\t/**\n\t * The server-assigned sequence number of the op.\n\t */\n\treadonly sequenceNumber: number;\n\t/**\n\t * Last known sequenced edit at the time this op was issued.\n\t */\n\treadonly referenceSequenceNumber: number;\n}\n\n/**\n * Server-provided metadata for edits that have been sequenced.\n */\nexport interface MessageSequencingInfo extends EditSequencingInfo {\n\t/**\n\t * Last sequenced edit that all clients are guaranteed to be aware of.\n\t * If not specified, then some clients have not seen any edits yet.\n\t */\n\treadonly minimumSequenceNumber?: number;\n}\n\n/**\n * Metadata for a sequenced edit.\n */\nexport interface SequencedOrderedEditId {\n\treadonly isLocal: false;\n\treadonly index: number;\n\t/**\n\t * Information about the edit's relationship to other sequenced edits.\n\t * Undefined iff the edit was loaded from a summary.\n\t */\n\treadonly sequenceInfo?: EditSequencingInfo;\n}\n\n/**\n * Metadata for a local edit.\n */\nexport interface LocalOrderedEditId {\n\treadonly isLocal: true;\n\treadonly localSequence: number;\n}\n\n/**\n * Metadata for an edit.\n */\nexport type OrderedEditId = SequencedOrderedEditId | LocalOrderedEditId;\n\n/**\n * Compressor+interner pair used for encoding an {@link EditLog} into a summary.\n * @internal\n */\nexport interface EditLogEncoder {\n\tcompressor: ChangeCompressor;\n\tinterner: StringInterner;\n}\n\n/**\n * A sequence of edits that may or may not need to be downloaded into the EditLog from an external service\n * @deprecated Edit virtualization is no longer supported.\n */\nexport interface EditChunk<TChange> {\n\thandle?: EditHandle<TChange>;\n\tedits?: EditWithoutId<TChange>[];\n}\n/**\n * EditHandles are used to load edit chunks stored outside of the EditLog.\n * This is typically implemented by a wrapper around an IFluidHandle<ArrayBufferLike>.\n * @deprecated Edit virtualization is no longer supported.\n * @internal\n */\nexport interface EditHandle<TChange> {\n\treadonly get: () => Promise<EditWithoutId<TChange>[]>;\n\treadonly baseHandle: FluidEditHandle;\n}\n\n/**\n * Returns an object that separates an Edit into two fields, id and editWithoutId.\n */\nexport function separateEditAndId<TChange>(edit: Edit<TChange>): {\n\tid: EditId;\n\teditWithoutId: EditWithoutId<TChange>;\n} {\n\tconst editWithoutId = { ...edit, id: undefined };\n\tdelete editWithoutId.id;\n\treturn { id: edit.id, editWithoutId };\n}\n\n/**\n * @param summary - The edit log summary to parse.\n * @returns the number of handles saved to the provided edit log summary.\n * @deprecated Edit virtualization is no longer supported.\n */\nexport function getNumberOfHandlesFromEditLogSummary(summary: EditLogSummary<unknown, unknown>): number {\n\tconst { editChunks } = summary;\n\n\tlet numberOfHandles = 0;\n\teditChunks.forEach(({ chunk }) => {\n\t\tif (!Array.isArray(chunk)) {\n\t\t\tnumberOfHandles++;\n\t\t}\n\t});\n\n\treturn numberOfHandles;\n}\n\n/**\n * Event fired when an edit is added to an `EditLog`.\n * @param edit - The edit that was added to the log\n * @param isLocal - true iff this edit was generated locally\n */\nexport type EditAddedHandler<TChange> = (edit: Edit<TChange>, isLocal: boolean, wasLocal: boolean) => void;\n\n/**\n * Event fired before edits are evicted from the edit log. It takes in a count of the number of edits to evict\n * starting from the oldest in memory edit. To get the edit itself, call {@link EditLog.getEditAtIndex}.\n * The edit index corresponds to the count + {@link EditLog.earliestAvailableEditIndex}.\n */\nexport type EditEvictionHandler = (editsToEvict: number) => void;\n\n/**\n * Events which may be emitted by {@link EditLog}\n * @alpha\n */\nexport interface IEditLogEvents extends IEvent {\n\t(event: 'unexpectedHistoryChunk', listener: () => void);\n}\n\n/**\n * The edit history log for SharedTree.\n * Contains only completed edits (no in-progress edits).\n * Ordered first by locality (acked or local), then by time of insertion.\n * May not contain more than one edit with the same ID.\n * @sealed\n * @alpha\n */\nexport class EditLog<TChange = unknown> extends TypedEventEmitter<IEditLogEvents> implements OrderedEditSet<TChange> {\n\tprivate localEditSequence = 0;\n\n\tprivate readonly sequenceNumberToIndex?: BTree<number, number>;\n\tprivate _minSequenceNumber = 0;\n\n\tprivate readonly sequencedEdits: Edit<TChange>[] = [];\n\tprivate readonly localEdits: Edit<TChange>[] = [];\n\n\tprivate readonly allEditIds = new Map<EditId, OrderedEditId>();\n\tprivate _earliestAvailableEditIndex = 0;\n\tprivate readonly _editAddedHandlers = new Set<EditAddedHandler<TChange>>();\n\tprivate readonly _editEvictionHandlers = new Set<EditEvictionHandler>();\n\n\t/**\n\t * @returns The index of the earliest edit stored in this log.\n\t * Edit indices are unique and strictly increasing within the session.\n\t */\n\tpublic get earliestAvailableEditIndex(): number {\n\t\treturn this._earliestAvailableEditIndex;\n\t}\n\n\t/**\n\t * @returns The sequence number of the latest edit known by all nodes.\n\t */\n\tpublic get minSequenceNumber(): number {\n\t\treturn this._minSequenceNumber;\n\t}\n\n\t/**\n\t * Construct an `EditLog` using the given options.\n\t * @param summary - An edit log summary used to populate the edit log.\n\t * @param logger - An optional logger to record telemetry/errors\n\t * @param editAddedHandlers - Optional handlers that are called when edits are added.\n\t * @param targetLength - The target number of sequenced edits that the log will try to store in memory.\n\t * Depending on eviction frequency and the collaboration window, there can be more edits in memory at a given time.\n\t * Edits greater than or equal to the `minSequenceNumber` (aka in the collaboration window) are not evicted.\n\t * @param evictionFrequency - The rate at which edits are evicted from memory. This is a factor of the editLogSize.\n\t * For example, with the default frequency of inMemoryHistorySize * 2 and a size of 10, the log will evict once it reaches 20 sequenced edits\n\t * down to 10 edits, also keeping any that are still in the collaboration window.\n\t * @param editEvictionHandlers - Handlers that are called before edits are evicted from memory. This provides a chance for\n\t * callers to work with the edits before they are lost.\n\t */\n\tpublic constructor(\n\t\tsummary: EditLogSummary<TChange, EditHandle<TChange>> = { editIds: [], editChunks: [] },\n\t\tprivate readonly logger?: ITelemetryLoggerExt,\n\t\teditAddedHandlers: readonly EditAddedHandler<TChange>[] = [],\n\t\tprivate readonly targetLength = Infinity,\n\t\tprivate readonly evictionFrequency = targetLength * 2,\n\t\teditEvictionHandlers: readonly EditEvictionHandler[] = []\n\t) {\n\t\tsuper();\n\t\tconst { editChunks, editIds } = summary;\n\n\t\tfor (const handler of editAddedHandlers) {\n\t\t\tthis.registerEditAddedHandler(handler);\n\t\t}\n\n\t\tif (targetLength !== Infinity) {\n\t\t\tif (targetLength < 0 || evictionFrequency < 0) {\n\t\t\t\tfail('targetLength and evictionFrequency should not be negative');\n\t\t\t}\n\t\t\tthis.sequenceNumberToIndex = new BTree([[0, 0]]);\n\t\t\tfor (const handler of editEvictionHandlers) {\n\t\t\t\tthis.registerEditEvictionHandler(handler);\n\t\t\t}\n\t\t}\n\n\t\teditChunks.forEach((editChunkOrHandle) => {\n\t\t\tconst { startRevision, chunk } = editChunkOrHandle;\n\n\t\t\tif (Array.isArray(chunk)) {\n\t\t\t\tfor (const [index, edit] of chunk.entries()) {\n\t\t\t\t\tconst editIndex = startRevision + index;\n\t\t\t\t\tconst id = editIds[editIndex];\n\t\t\t\t\tthis.sequencedEdits.push({ id, ...edit });\n\t\t\t\t\tconst encounteredEditId = this.allEditIds.get(id);\n\t\t\t\t\tassert(encounteredEditId === undefined, 0x60a /* Duplicate acked edit. */);\n\t\t\t\t\tthis.allEditIds.set(id, { isLocal: false, index: editIndex });\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Ignore any edit handles, these edits are now unrecoverable.\n\t\t\t\t// This should instead download the edit chunk and store them but history is not\n\t\t\t\t// being used so we're going with the simpler solution.\n\t\t\t\tthis.logger?.sendErrorEvent({ eventName: 'UnexpectedEditHandleInSummary' });\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Registers a handler for when an edit is added to this `EditLog`.\n\t * @returns A callback which can be invoked to unregister this handler.\n\t */\n\tpublic registerEditAddedHandler(handler: EditAddedHandler<TChange>): () => void {\n\t\tthis._editAddedHandlers.add(handler);\n\t\treturn () => this._editAddedHandlers.delete(handler);\n\t}\n\n\t/**\n\t * @returns the `EditAddedHandler`s registered on this `EditLog`.\n\t */\n\tpublic get editAddedHandlers(): readonly EditAddedHandler<TChange>[] {\n\t\treturn Array.from(this._editAddedHandlers);\n\t}\n\n\t/**\n\t * Registers a handler that is called before an edit is evicted from this `EditLog`.\n\t * @returns A callback which can be invoked to unregister this handler.\n\t */\n\tpublic registerEditEvictionHandler(handler: EditEvictionHandler): () => void {\n\t\tthis._editEvictionHandlers.add(handler);\n\t\treturn () => this._editEvictionHandlers.delete(handler);\n\t}\n\n\t/**\n\t * @returns the `EditEvictedHandler`s registered on this `EditLog`.\n\t */\n\tpublic get editEvictedHandlers(): readonly EditEvictionHandler[] {\n\t\treturn Array.from(this._editEvictionHandlers);\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.length}\n\t */\n\tpublic get length(): number {\n\t\treturn this.numberOfSequencedEdits + this.numberOfLocalEdits;\n\t}\n\n\t/**\n\t * The number of sequenced (acked) edits in the log.\n\t */\n\tpublic get numberOfSequencedEdits(): number {\n\t\treturn this.sequencedEdits.length;\n\t}\n\n\t/**\n\t * The number of local (unacked) edits in the log.\n\t */\n\tpublic get numberOfLocalEdits(): number {\n\t\treturn this.localEdits.length;\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.editIds}\n\t */\n\tpublic get editIds(): EditId[] {\n\t\treturn this.sequencedEdits.map(({ id }) => id).concat(this.localEdits.map(({ id }) => id));\n\t}\n\n\t/**\n\t * @returns true iff the edit is contained in this 'EditLog' and it is a local edit (not sequenced).\n\t */\n\tpublic isLocalEdit(editId: EditId): boolean {\n\t\tconst entry = this.allEditIds.get(editId);\n\t\treturn entry?.isLocal ?? false;\n\t}\n\n\t/**\n\t * @returns true iff the revision is a sequenced revision (not local).\n\t */\n\tpublic isSequencedRevision(revision: number): boolean {\n\t\treturn revision <= this.sequencedEdits.length;\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.tryGetIndexOfId}\n\t */\n\tpublic tryGetIndexOfId(editId: EditId): number | undefined {\n\t\tconst orderedEdit = this.allEditIds.get(editId);\n\t\tif (orderedEdit === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (orderedEdit.isLocal) {\n\t\t\tconst firstLocal = this.allEditIds.get(this.localEdits[0].id) ?? fail('edit not found');\n\t\t\tassert(firstLocal.isLocal, 0x60b /* local edit should be local */);\n\t\t\treturn (\n\t\t\t\tthis._earliestAvailableEditIndex +\n\t\t\t\tthis.numberOfSequencedEdits +\n\t\t\t\torderedEdit.localSequence -\n\t\t\t\tfirstLocal.localSequence\n\t\t\t);\n\t\t}\n\t\treturn orderedEdit.index;\n\t}\n\n\t/**\n\t * @returns Edit metadata for the edit with the given `editId`.\n\t */\n\tpublic getOrderedEditId(editId: EditId): OrderedEditId {\n\t\treturn this.allEditIds.get(editId) ?? fail('All edits should exist in this map');\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.getIndexOfId}\n\t */\n\tpublic getIndexOfId(editId: EditId): number {\n\t\treturn this.tryGetIndexOfId(editId) ?? fail('edit not found');\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.getIdAtIndex}\n\t */\n\tpublic getIdAtIndex(index: number): EditId {\n\t\tif (this._earliestAvailableEditIndex + this.numberOfSequencedEdits <= index) {\n\t\t\treturn this.localEdits[index - this.numberOfSequencedEdits].id;\n\t\t}\n\n\t\treturn this.sequencedEdits[index - this._earliestAvailableEditIndex].id;\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.tryGetEditAtIndex}\n\t */\n\tpublic tryGetEditAtIndex(index: number): Edit<TChange> | undefined {\n\t\tif (this._earliestAvailableEditIndex + this.numberOfSequencedEdits <= index) {\n\t\t\treturn this.localEdits[index - this.numberOfSequencedEdits];\n\t\t}\n\n\t\treturn this.sequencedEdits[index - this._earliestAvailableEditIndex];\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.tryGetEditFromId}\n\t */\n\tpublic tryGetEditFromId(editId: EditId): Edit<TChange> | undefined {\n\t\tconst index = this.tryGetIndexOfId(editId);\n\t\treturn index !== undefined ? this.tryGetEditAtIndex(index) : undefined;\n\t}\n\n\t/**\n\t * Sequences all local edits.\n\t */\n\tpublic sequenceLocalEdits(): void {\n\t\tthis.localEdits.slice().forEach((edit) => this.addSequencedEditInternal(edit));\n\t}\n\n\t/**\n\t * Adds a sequenced (non-local) edit to the edit log.\n\t * If the id of the supplied edit matches a local edit already present in the log, the local edit will be replaced.\n\t *\n\t */\n\tpublic addSequencedEdit(edit: Edit<TChange>, message: MessageSequencingInfo): void {\n\t\tthis.addSequencedEditInternal(edit, message, message.minimumSequenceNumber);\n\t}\n\n\t/**\n\t * Returns all local edits from this EditLog\n\t * This is useful for op format upgrades, which might warrant re-submission of these ops using the new format.\n\t * See the breaking change documentation for more information.\n\t */\n\tpublic *getLocalEdits(): Iterable<Edit<TChange>> {\n\t\tfor (const edit of this.localEdits) {\n\t\t\tyield edit;\n\t\t}\n\t}\n\n\t/**\n\t * Adds a sequenced (non-local) edit to the edit log.\n\t * If the id of the supplied edit matches a local edit already present in the log, the local edit will be replaced.\n\t */\n\tprivate addSequencedEditInternal(\n\t\tedit: Edit<TChange>,\n\t\tinfo?: EditSequencingInfo,\n\t\tminSequenceNumber: number = 0\n\t): void {\n\t\tassert(\n\t\t\tminSequenceNumber >= this._minSequenceNumber,\n\t\t\t0x60c /* Sequenced edits should carry a monotonically increasing min number */\n\t\t);\n\t\tthis._minSequenceNumber = minSequenceNumber;\n\n\t\tconst { id } = edit;\n\t\t// The index of the sequenced edit to add\n\t\tconst index = this._earliestAvailableEditIndex + this.numberOfSequencedEdits;\n\n\t\t// Remove the edit from local edits if it exists.\n\t\tconst encounteredEditId = this.allEditIds.get(id);\n\t\tif (encounteredEditId !== undefined) {\n\t\t\t// New edit already exits: it must have been a local edit.\n\t\t\tassert(encounteredEditId.isLocal, 0x60d /* Duplicate acked edit. */);\n\t\t\t// Remove it from localEdits. Due to ordering requirements, it must be first.\n\t\t\tconst oldLocalEditId = this.localEdits.shift()?.id ?? fail('Local edit should exist');\n\t\t\tassert(oldLocalEditId === id, 0x60e /* Causal ordering should be upheld */);\n\t\t}\n\n\t\tthis.sequencedEdits.push(edit);\n\n\t\tconst sequencedEditId: SequencedOrderedEditId = {\n\t\t\tindex,\n\t\t\tisLocal: false,\n\t\t\tsequenceInfo: info,\n\t\t};\n\t\tthis.allEditIds.set(id, sequencedEditId);\n\t\tif (info !== undefined) {\n\t\t\tthis.sequenceNumberToIndex?.set(info.sequenceNumber, index);\n\t\t}\n\t\tthis.emitAdd(edit, false, encounteredEditId !== undefined);\n\n\t\t// Check if any edits need to be evicted due to this addition\n\t\tif (this.sequenceNumberToIndex !== undefined && this.numberOfSequencedEdits >= this.evictionFrequency) {\n\t\t\tthis.evictEdits();\n\t\t}\n\t}\n\n\t/**\n\t * Adds a non-sequenced (local) edit to the edit log.\n\t * Duplicate edits are ignored.\n\t */\n\tpublic addLocalEdit(edit: Edit<TChange>): void {\n\t\tthis.localEdits.push(edit);\n\t\tconst localEditId: LocalOrderedEditId = {\n\t\t\tlocalSequence: this.localEditSequence++,\n\t\t\tisLocal: true,\n\t\t};\n\t\tthis.allEditIds.set(edit.id, localEditId);\n\t\tthis.emitAdd(edit, true, false);\n\t}\n\n\tprivate emitAdd(editAdded: Edit<TChange>, isLocal: boolean, wasLocal: boolean): void {\n\t\tfor (const handler of this._editAddedHandlers) {\n\t\t\thandler(editAdded, isLocal, wasLocal);\n\t\t}\n\t}\n\n\tprivate evictEdits(): void {\n\t\tassert(\n\t\t\tthis.sequenceNumberToIndex !== undefined,\n\t\t\t0x60f /* Edits should never be evicted if the target length is set to infinity */\n\t\t);\n\n\t\tconst minSequenceIndex =\n\t\t\tthis.sequenceNumberToIndex.getPairOrNextHigher(this._minSequenceNumber)?.[1] ??\n\t\t\tfail('No index associated with that sequence number.');\n\t\t// Exclude any edits in the collab window from being evicted\n\t\tconst numberOfEvictableEdits = minSequenceIndex - this.earliestAvailableEditIndex;\n\n\t\tif (numberOfEvictableEdits > 0) {\n\t\t\t// Evict either all but the target log size or the number of evictable edits, whichever is smaller\n\t\t\tconst numberOfDesiredEditsToEvict = this.numberOfSequencedEdits - this.targetLength;\n\t\t\tconst numberOfEditsToEvict = Math.min(numberOfEvictableEdits, numberOfDesiredEditsToEvict);\n\t\t\tfor (const handler of this._editEvictionHandlers) {\n\t\t\t\thandler(numberOfEditsToEvict);\n\t\t\t}\n\n\t\t\t// Remove the edits and move up the earliest available index\n\t\t\tconst removedEdits = this.sequencedEdits.splice(0, numberOfEditsToEvict);\n\t\t\tthis._earliestAvailableEditIndex += numberOfEditsToEvict;\n\n\t\t\t// On eviction, we need to remove the IDs of edits that have been evicted\n\t\t\tremovedEdits.forEach((edit) => this.allEditIds.delete(edit.id));\n\n\t\t\t// The minSequenceNumber is strictly increasing so we can clear sequence numbers before it\n\t\t\tthis.sequenceNumberToIndex.deleteRange(0, this._minSequenceNumber, false);\n\t\t}\n\t}\n\n\t/**\n\t * @returns true iff this `EditLog` and `other` are equivalent, regardless of locality.\n\t */\n\tpublic equals<TOtherChangeTypesInternal>(other: EditLog<TOtherChangeTypesInternal>): boolean {\n\t\t// TODO #45414: We should also be deep comparing the list of changes in the edit. This is not straightforward.\n\t\t// We can use our edit validation code when we write it since it will need to do deep walks of the changes.\n\t\treturn compareArrays(this.editIds, other.editIds);\n\t}\n\n\t/**\n\t * @returns the summary of this `OrderedEditSet` that can be used to reconstruct the edit set.\n\t */\n\tpublic getEditLogSummary(): EditLogSummary<TChange, FluidEditHandle>;\n\n\t/**\n\t * @param compressEdit - a function which compresses edits\n\t * @returns the summary of this `OrderedEditSet` that can be used to reconstruct the edit set.\n\t */\n\tpublic getEditLogSummary<TCompressedChange>(\n\t\tcompressEdit: (edit: Pick<Edit<TChange>, 'changes'>) => Pick<Edit<TCompressedChange>, 'changes'>\n\t): EditLogSummary<TCompressedChange, FluidEditHandle>;\n\tpublic getEditLogSummary<TCompressedChange>(\n\t\tcompressEdit?: (edit: Pick<Edit<TChange>, 'changes'>) => Pick<Edit<TCompressedChange>, 'changes'>\n\t): EditLogSummary<TChange, FluidEditHandle> | EditLogSummary<TCompressedChange, FluidEditHandle> {\n\t\tconst editIds = this.sequencedEdits.map(({ id }) => id);\n\t\treturn compressEdit !== undefined\n\t\t\t? {\n\t\t\t\t\teditChunks:\n\t\t\t\t\t\tthis.sequencedEdits.length === 0\n\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t// Store all edits within a single \"chunk\"\n\t\t\t\t\t\t\t\t\t\tstartRevision: 0,\n\t\t\t\t\t\t\t\t\t\tchunk: this.sequencedEdits.map((edit) => compressEdit(edit)),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\teditIds,\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\teditChunks:\n\t\t\t\t\t\tthis.sequencedEdits.length === 0\n\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t// Store all edits within a single \"chunk\"\n\t\t\t\t\t\t\t\t\t\tstartRevision: 0,\n\t\t\t\t\t\t\t\t\t\tchunk: this.sequencedEdits.map(({ changes }) => ({ changes })),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\teditIds,\n\t\t\t\t};\n\t}\n\n\t// APIS DEPRECATED DUE TO HISTORY'S PEACEFUL DEATH\n\t/**\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\tpublic async tryGetEdit(editId: EditId): Promise<Edit<TChange> | undefined> {\n\t\tconst index = this.tryGetIndexOfId(editId);\n\t\treturn index !== undefined ? this.tryGetEditAtIndex(index) : undefined;\n\t}\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\tpublic async getEditAtIndex(index: number): Promise<Edit<TChange>> {\n\t\treturn this.tryGetEditAtIndex(index) ?? fail('Edit not found');\n\t}\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\tpublic getEditInSessionAtIndex(index: number): Edit<TChange> {\n\t\treturn this.tryGetEditAtIndex(index) ?? fail('Edit not found');\n\t}\n}\n"]}
|
|
@@ -31,7 +31,7 @@ export declare class MigrationShimDeltaHandler implements IShimDeltaHandler {
|
|
|
31
31
|
isUsingOldV1(): boolean;
|
|
32
32
|
isUsingNewV2(): boolean;
|
|
33
33
|
attachTreeDeltaHandler(treeDeltaHandler: IDeltaHandler): void;
|
|
34
|
-
process
|
|
34
|
+
private process;
|
|
35
35
|
processMessages(messagesCollection: IRuntimeMessageCollection): void;
|
|
36
36
|
setConnectionState(connected: boolean): void;
|
|
37
37
|
reSubmit(contents: unknown, localOpMetadata: unknown): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrationDeltaHandler.d.ts","sourceRoot":"","sources":["../../src/migration-shim/migrationDeltaHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAC7G,OAAO,EAAe,KAAK,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAC1G,OAAO,KAAK,EAAE,yBAAyB,
|
|
1
|
+
{"version":3,"file":"migrationDeltaHandler.d.ts","sourceRoot":"","sources":["../../src/migration-shim/migrationDeltaHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAC7G,OAAO,EAAe,KAAK,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAC1G,OAAO,KAAK,EAAE,yBAAyB,EAA2B,MAAM,8CAA8C,CAAC;AAEvH,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGtE;;;;;;;;GAQG;AACH,qBAAa,yBAA0B,YAAW,iBAAiB;aAKjD,gBAAgB,EAAE,CACjC,OAAO,EAAE,yBAAyB,EAClC,KAAK,EAAE,OAAO,EACd,eAAe,EAAE,OAAO,KACpB,OAAO;IACZ,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAV5B,OAAO,CAAC,iBAAiB,CAAC,CAAgB;IAC1C,OAAO,CAAC,cAAc,CAAC,CAAgB;gBAGtB,gBAAgB,EAAE,CACjC,OAAO,EAAE,yBAAyB,EAClC,KAAK,EAAE,OAAO,EACd,eAAe,EAAE,OAAO,KACpB,OAAO,EACK,kBAAkB,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,EAClD,UAAU,EAAE,kBAAkB;IAGzC,mBAAmB,IAAI,OAAO;IAIrC,OAAO,KAAK,gBAAgB,GAI3B;IAED,OAAO,CAAC,SAAS,CAAS;IAC1B,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAEM,YAAY,IAAI,IAAI;IAIpB,gBAAgB,IAAI,OAAO;IAM3B,YAAY,IAAI,OAAO;IAIvB,YAAY,IAAI,OAAO;IAOvB,sBAAsB,CAAC,gBAAgB,EAAE,aAAa,GAAG,IAAI;IAWpE,OAAO,CAAC,OAAO;IA2BR,eAAe,CAAC,kBAAkB,EAAE,yBAAyB,GAAG,IAAI;IAOpE,kBAAkB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAI5C,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;IAa3D,cAAc,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAcvC,QAAQ,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;IAQnE,OAAO,CAAC,yBAAyB;IAIjC;;;;;OAKG;IACH,OAAO,CAAC,YAAY;CAmBpB"}
|
|
@@ -79,8 +79,15 @@ class MigrationShimDeltaHandler {
|
|
|
79
79
|
if (this.shouldDropOp(contents)) {
|
|
80
80
|
return;
|
|
81
81
|
}
|
|
82
|
+
const messagesContent = [
|
|
83
|
+
{
|
|
84
|
+
contents,
|
|
85
|
+
localOpMetadata,
|
|
86
|
+
clientSequenceNumber: message.clientSequenceNumber,
|
|
87
|
+
},
|
|
88
|
+
];
|
|
82
89
|
// Another thought, flatten the IShimDeltaHandler and the MigrationShim into one class
|
|
83
|
-
return this.treeDeltaHandler.
|
|
90
|
+
return this.treeDeltaHandler.processMessages({ envelope: message, messagesContent, local });
|
|
84
91
|
}
|
|
85
92
|
processMessages(messagesCollection) {
|
|
86
93
|
const { envelope, messagesContent, local } = messagesCollection;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrationDeltaHandler.js","sourceRoot":"","sources":["../../src/migration-shim/migrationDeltaHandler.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from '@fluidframework/core-utils/internal';\nimport { type IChannelAttributes, type IDeltaHandler } from '@fluidframework/datastore-definitions/internal';\nimport { MessageType, type ISequencedDocumentMessage } from '@fluidframework/driver-definitions/internal';\nimport type { IRuntimeMessageCollection } from '@fluidframework/runtime-definitions/internal';\n\nimport { type IOpContents, type IShimDeltaHandler } from './types.js';\nimport { attributesMatch, isBarrierOp, isStampedOp } from './utils.js';\n\n/**\n * Handles incoming and outgoing deltas/ops for the Migration Shim distributed data structure.\n * Intercepts processing of ops to allow for migration, and swapping from LegacySharedTree to new SharedTree\n *\n * Able to process v1 and v2 ops, differentiate between them, understand the various states and drop v1 ops after\n * migration.\n *\n * TODO: After the MSN of the barrier op, it needs to process v2 ops without needing to check for the v2 stamp.\n */\nexport class MigrationShimDeltaHandler implements IShimDeltaHandler {\n\tprivate legacyTreeHandler?: IDeltaHandler;\n\tprivate newTreeHandler?: IDeltaHandler;\n\tpublic constructor(\n\t\t// Maybe it would be better to pass in a different interface?\n\t\tpublic readonly processMigrateOp: (\n\t\t\tmessage: ISequencedDocumentMessage,\n\t\t\tlocal: boolean,\n\t\t\tlocalOpMetadata: unknown\n\t\t) => boolean,\n\t\tprivate readonly submitLocalMessage: (message: IOpContents) => void,\n\t\tprivate readonly attributes: IChannelAttributes\n\t) {}\n\t// Introduction of invariant, we always expect an old handler.\n\tpublic hasTreeDeltaHandler(): boolean {\n\t\treturn this.legacyTreeHandler !== undefined;\n\t}\n\n\tprivate get treeDeltaHandler(): IDeltaHandler {\n\t\tconst handler = this.newTreeHandler ?? this.legacyTreeHandler;\n\t\tassert(handler !== undefined, 0x7e2 /* No handler to process op */);\n\t\treturn handler;\n\t}\n\n\tprivate _attached = false;\n\tpublic get attached(): boolean {\n\t\treturn this._attached;\n\t}\n\n\tpublic markAttached(): void {\n\t\tthis._attached = true;\n\t}\n\n\tpublic isPreAttachState(): boolean {\n\t\tconst preAttach = this.legacyTreeHandler === undefined && this.newTreeHandler === undefined;\n\t\tassert(!preAttach || !this.attached, 0x82a /* Should not be attached in preAttach state */);\n\t\treturn preAttach;\n\t}\n\n\tpublic isUsingOldV1(): boolean {\n\t\treturn this.legacyTreeHandler !== undefined && this.newTreeHandler === undefined;\n\t}\n\n\tpublic isUsingNewV2(): boolean {\n\t\tconst isUsingV2 = this.legacyTreeHandler !== undefined && this.newTreeHandler !== undefined;\n\t\tassert(!isUsingV2 || this.attached, 0x82b /* Should be attached if in v2 state */);\n\t\treturn isUsingV2;\n\t}\n\n\t// Allow for the handler to be swapped out for the new SharedTree's handler\n\tpublic attachTreeDeltaHandler(treeDeltaHandler: IDeltaHandler): void {\n\t\tassert(!this.isUsingNewV2(), 0x7e3 /* Can't swap tree handlers more than once! */);\n\t\tif (this.isPreAttachState()) {\n\t\t\tthis.legacyTreeHandler = treeDeltaHandler;\n\t\t\treturn;\n\t\t}\n\t\tassert(this.isUsingOldV1(), 0x7e4 /* Can only swap handlers after the old handler is loaded */);\n\t\tthis.newTreeHandler = treeDeltaHandler;\n\t\tassert(this.isUsingNewV2(), 0x7e5 /* Should be using new handler after swap */);\n\t}\n\n\tpublic process(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void {\n\t\t// This allows us to process the migrate op and prevent the shared object from processing the wrong ops\n\t\tassert(!this.isPreAttachState(), 0x82c /* Can't process ops before attaching tree handler */);\n\t\tif (message.type !== MessageType.Operation) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst contents = message.contents as IOpContents;\n\t\tif (this.isInV1StateAndIsBarrierOp(contents)) {\n\t\t\tthis.processMigrateOp(message, local, localOpMetadata);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.shouldDropOp(contents)) {\n\t\t\treturn;\n\t\t}\n\t\t// Another thought, flatten the IShimDeltaHandler and the MigrationShim into one class\n\t\treturn this.treeDeltaHandler.process(message, local, localOpMetadata);\n\t}\n\n\tpublic processMessages(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, messagesContent, local } = messagesCollection;\n\t\tfor (const { contents, localOpMetadata, clientSequenceNumber } of messagesContent) {\n\t\t\tthis.process({ ...envelope, contents, clientSequenceNumber }, local, localOpMetadata);\n\t\t}\n\t}\n\n\tpublic setConnectionState(connected: boolean): void {\n\t\treturn this.treeDeltaHandler.setConnectionState(connected);\n\t}\n\n\tpublic reSubmit(contents: unknown, localOpMetadata: unknown): void {\n\t\tconst opContents = contents as IOpContents;\n\t\tif (this.isInV1StateAndIsBarrierOp(opContents)) {\n\t\t\tthis.submitLocalMessage(opContents);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.shouldDropOp(opContents)) {\n\t\t\treturn;\n\t\t}\n\t\treturn this.treeDeltaHandler.reSubmit(contents, localOpMetadata);\n\t}\n\n\tpublic applyStashedOp(contents: unknown): void {\n\t\tconst opContents = contents as IOpContents;\n\t\tif (this.isInV1StateAndIsBarrierOp(opContents)) {\n\t\t\tthis.submitLocalMessage(opContents);\n\t\t\treturn;\n\t\t}\n\n\t\tassert(\n\t\t\t!this.shouldDropOp(opContents),\n\t\t\t0x8aa /* MigrationShim should not be able to apply v1 ops as they shouldn't have been created locally. */\n\t\t);\n\t\tthis.treeDeltaHandler.applyStashedOp(contents);\n\t}\n\n\tpublic rollback?(contents: unknown, localOpMetadata: unknown): void {\n\t\tconst opContents = contents as IOpContents;\n\t\tif (isBarrierOp(opContents)) {\n\t\t\tthrow new Error('MigrationShim does not support rollback of barrier ops');\n\t\t}\n\t\treturn this.treeDeltaHandler.rollback?.(contents, localOpMetadata);\n\t}\n\n\tprivate isInV1StateAndIsBarrierOp(contents: IOpContents): boolean {\n\t\treturn this.isUsingOldV1() && isBarrierOp(contents);\n\t}\n\n\t/**\n\t * We should drop an op when we are v2 state and the op is a v1 op or a migrate op.\n\t *\n\t * @param contents - op contents we expect to interrogate, this could be anything\n\t * @returns whether or not we should drop the op\n\t */\n\tprivate shouldDropOp(contents: IOpContents): boolean {\n\t\tassert(!this.isPreAttachState(), 0x82d /* Can't process ops before attaching tree handler */);\n\t\t// Don't drop ops when we are in v1 state\n\t\tif (this.isUsingOldV1()) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Drop v1 ops when in v2 state\n\t\tif (!isStampedOp(contents)) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Don't drop v2 ops in v2 state\n\t\tassert(\n\t\t\tattributesMatch(contents.fluidMigrationStamp, this.attributes),\n\t\t\t0x82e /* Unexpected v2 op with mismatched attributes */\n\t\t);\n\t\treturn false;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"migrationDeltaHandler.js","sourceRoot":"","sources":["../../src/migration-shim/migrationDeltaHandler.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from '@fluidframework/core-utils/internal';\nimport { type IChannelAttributes, type IDeltaHandler } from '@fluidframework/datastore-definitions/internal';\nimport { MessageType, type ISequencedDocumentMessage } from '@fluidframework/driver-definitions/internal';\nimport type { IRuntimeMessageCollection, IRuntimeMessagesContent } from '@fluidframework/runtime-definitions/internal';\n\nimport { type IOpContents, type IShimDeltaHandler } from './types.js';\nimport { attributesMatch, isBarrierOp, isStampedOp } from './utils.js';\n\n/**\n * Handles incoming and outgoing deltas/ops for the Migration Shim distributed data structure.\n * Intercepts processing of ops to allow for migration, and swapping from LegacySharedTree to new SharedTree\n *\n * Able to process v1 and v2 ops, differentiate between them, understand the various states and drop v1 ops after\n * migration.\n *\n * TODO: After the MSN of the barrier op, it needs to process v2 ops without needing to check for the v2 stamp.\n */\nexport class MigrationShimDeltaHandler implements IShimDeltaHandler {\n\tprivate legacyTreeHandler?: IDeltaHandler;\n\tprivate newTreeHandler?: IDeltaHandler;\n\tpublic constructor(\n\t\t// Maybe it would be better to pass in a different interface?\n\t\tpublic readonly processMigrateOp: (\n\t\t\tmessage: ISequencedDocumentMessage,\n\t\t\tlocal: boolean,\n\t\t\tlocalOpMetadata: unknown\n\t\t) => boolean,\n\t\tprivate readonly submitLocalMessage: (message: IOpContents) => void,\n\t\tprivate readonly attributes: IChannelAttributes\n\t) {}\n\t// Introduction of invariant, we always expect an old handler.\n\tpublic hasTreeDeltaHandler(): boolean {\n\t\treturn this.legacyTreeHandler !== undefined;\n\t}\n\n\tprivate get treeDeltaHandler(): IDeltaHandler {\n\t\tconst handler = this.newTreeHandler ?? this.legacyTreeHandler;\n\t\tassert(handler !== undefined, 0x7e2 /* No handler to process op */);\n\t\treturn handler;\n\t}\n\n\tprivate _attached = false;\n\tpublic get attached(): boolean {\n\t\treturn this._attached;\n\t}\n\n\tpublic markAttached(): void {\n\t\tthis._attached = true;\n\t}\n\n\tpublic isPreAttachState(): boolean {\n\t\tconst preAttach = this.legacyTreeHandler === undefined && this.newTreeHandler === undefined;\n\t\tassert(!preAttach || !this.attached, 0x82a /* Should not be attached in preAttach state */);\n\t\treturn preAttach;\n\t}\n\n\tpublic isUsingOldV1(): boolean {\n\t\treturn this.legacyTreeHandler !== undefined && this.newTreeHandler === undefined;\n\t}\n\n\tpublic isUsingNewV2(): boolean {\n\t\tconst isUsingV2 = this.legacyTreeHandler !== undefined && this.newTreeHandler !== undefined;\n\t\tassert(!isUsingV2 || this.attached, 0x82b /* Should be attached if in v2 state */);\n\t\treturn isUsingV2;\n\t}\n\n\t// Allow for the handler to be swapped out for the new SharedTree's handler\n\tpublic attachTreeDeltaHandler(treeDeltaHandler: IDeltaHandler): void {\n\t\tassert(!this.isUsingNewV2(), 0x7e3 /* Can't swap tree handlers more than once! */);\n\t\tif (this.isPreAttachState()) {\n\t\t\tthis.legacyTreeHandler = treeDeltaHandler;\n\t\t\treturn;\n\t\t}\n\t\tassert(this.isUsingOldV1(), 0x7e4 /* Can only swap handlers after the old handler is loaded */);\n\t\tthis.newTreeHandler = treeDeltaHandler;\n\t\tassert(this.isUsingNewV2(), 0x7e5 /* Should be using new handler after swap */);\n\t}\n\n\tprivate process(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void {\n\t\t// This allows us to process the migrate op and prevent the shared object from processing the wrong ops\n\t\tassert(!this.isPreAttachState(), 0x82c /* Can't process ops before attaching tree handler */);\n\t\tif (message.type !== MessageType.Operation) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst contents = message.contents as IOpContents;\n\t\tif (this.isInV1StateAndIsBarrierOp(contents)) {\n\t\t\tthis.processMigrateOp(message, local, localOpMetadata);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.shouldDropOp(contents)) {\n\t\t\treturn;\n\t\t}\n\t\tconst messagesContent: IRuntimeMessagesContent[] = [\n\t\t\t{\n\t\t\t\tcontents,\n\t\t\t\tlocalOpMetadata,\n\t\t\t\tclientSequenceNumber: message.clientSequenceNumber,\n\t\t\t},\n\t\t];\n\t\t// Another thought, flatten the IShimDeltaHandler and the MigrationShim into one class\n\t\treturn this.treeDeltaHandler.processMessages({ envelope: message, messagesContent, local });\n\t}\n\n\tpublic processMessages(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, messagesContent, local } = messagesCollection;\n\t\tfor (const { contents, localOpMetadata, clientSequenceNumber } of messagesContent) {\n\t\t\tthis.process({ ...envelope, contents, clientSequenceNumber }, local, localOpMetadata);\n\t\t}\n\t}\n\n\tpublic setConnectionState(connected: boolean): void {\n\t\treturn this.treeDeltaHandler.setConnectionState(connected);\n\t}\n\n\tpublic reSubmit(contents: unknown, localOpMetadata: unknown): void {\n\t\tconst opContents = contents as IOpContents;\n\t\tif (this.isInV1StateAndIsBarrierOp(opContents)) {\n\t\t\tthis.submitLocalMessage(opContents);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.shouldDropOp(opContents)) {\n\t\t\treturn;\n\t\t}\n\t\treturn this.treeDeltaHandler.reSubmit(contents, localOpMetadata);\n\t}\n\n\tpublic applyStashedOp(contents: unknown): void {\n\t\tconst opContents = contents as IOpContents;\n\t\tif (this.isInV1StateAndIsBarrierOp(opContents)) {\n\t\t\tthis.submitLocalMessage(opContents);\n\t\t\treturn;\n\t\t}\n\n\t\tassert(\n\t\t\t!this.shouldDropOp(opContents),\n\t\t\t0x8aa /* MigrationShim should not be able to apply v1 ops as they shouldn't have been created locally. */\n\t\t);\n\t\tthis.treeDeltaHandler.applyStashedOp(contents);\n\t}\n\n\tpublic rollback?(contents: unknown, localOpMetadata: unknown): void {\n\t\tconst opContents = contents as IOpContents;\n\t\tif (isBarrierOp(opContents)) {\n\t\t\tthrow new Error('MigrationShim does not support rollback of barrier ops');\n\t\t}\n\t\treturn this.treeDeltaHandler.rollback?.(contents, localOpMetadata);\n\t}\n\n\tprivate isInV1StateAndIsBarrierOp(contents: IOpContents): boolean {\n\t\treturn this.isUsingOldV1() && isBarrierOp(contents);\n\t}\n\n\t/**\n\t * We should drop an op when we are v2 state and the op is a v1 op or a migrate op.\n\t *\n\t * @param contents - op contents we expect to interrogate, this could be anything\n\t * @returns whether or not we should drop the op\n\t */\n\tprivate shouldDropOp(contents: IOpContents): boolean {\n\t\tassert(!this.isPreAttachState(), 0x82d /* Can't process ops before attaching tree handler */);\n\t\t// Don't drop ops when we are in v1 state\n\t\tif (this.isUsingOldV1()) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Drop v1 ops when in v2 state\n\t\tif (!isStampedOp(contents)) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Don't drop v2 ops in v2 state\n\t\tassert(\n\t\t\tattributesMatch(contents.fluidMigrationStamp, this.attributes),\n\t\t\t0x82e /* Unexpected v2 op with mismatched attributes */\n\t\t);\n\t\treturn false;\n\t}\n}\n"]}
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { type IChannelAttributes, type IDeltaHandler } from '@fluidframework/datastore-definitions/internal';
|
|
6
|
-
import { type ISequencedDocumentMessage } from '@fluidframework/driver-definitions/internal';
|
|
7
6
|
import type { IRuntimeMessageCollection } from '@fluidframework/runtime-definitions/internal';
|
|
8
7
|
import { type IShimDeltaHandler } from './types.js';
|
|
9
8
|
/**
|
|
@@ -25,7 +24,7 @@ export declare class SharedTreeShimDeltaHandler implements IShimDeltaHandler {
|
|
|
25
24
|
markAttached(): void;
|
|
26
25
|
attachTreeDeltaHandler(handler: IDeltaHandler): void;
|
|
27
26
|
hasTreeDeltaHandler(): boolean;
|
|
28
|
-
process
|
|
27
|
+
private process;
|
|
29
28
|
processMessages(messagesCollection: IRuntimeMessageCollection): void;
|
|
30
29
|
setConnectionState(connected: boolean): void;
|
|
31
30
|
reSubmit(contents: unknown, localOpMetadata: unknown): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharedTreeDeltaHandler.d.ts","sourceRoot":"","sources":["../../src/migration-shim/sharedTreeDeltaHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,gDAAgD,CAAC;
|
|
1
|
+
{"version":3,"file":"sharedTreeDeltaHandler.d.ts","sourceRoot":"","sources":["../../src/migration-shim/sharedTreeDeltaHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAE7G,OAAO,KAAK,EAAE,yBAAyB,EAA2B,MAAM,8CAA8C,CAAC;AAEvH,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGtE;;;;;;;;GAQG;AACH,qBAAa,0BAA2B,YAAW,iBAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,kBAAkB;IAElE,OAAO,CAAC,QAAQ,CAAC,CAAgB;IACjC,OAAO,KAAK,OAAO,GAIlB;IAED,OAAO,CAAC,SAAS,CAAS;IAC1B,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAEM,YAAY,IAAI,IAAI;IAIpB,sBAAsB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAKpD,mBAAmB,IAAI,OAAO;IAIrC,OAAO,CAAC,OAAO;IAsBR,eAAe,CAAC,kBAAkB,EAAE,yBAAyB,GAAG,IAAI;IAQpE,kBAAkB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAK5C,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;IAS3D,cAAc,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAQ9C;;;OAGG;IACI,QAAQ,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;IAQnE;;;;OAIG;IACH,OAAO,CAAC,YAAY;CAYpB"}
|
|
@@ -51,7 +51,14 @@ class SharedTreeShimDeltaHandler {
|
|
|
51
51
|
if (this.shouldDropOp(contents)) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
const messagesContent = [
|
|
55
|
+
{
|
|
56
|
+
contents,
|
|
57
|
+
localOpMetadata,
|
|
58
|
+
clientSequenceNumber: message.clientSequenceNumber,
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
return this.handler.processMessages({ envelope: message, messagesContent, local });
|
|
55
62
|
}
|
|
56
63
|
processMessages(messagesCollection) {
|
|
57
64
|
const { envelope, messagesContent, local } = messagesCollection;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharedTreeDeltaHandler.js","sourceRoot":"","sources":["../../src/migration-shim/sharedTreeDeltaHandler.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAA6D;AAE7D,0EAA0G;AAI1G,yCAA0D;AAE1D;;;;;;;;GAQG;AACH,MAAa,0BAA0B;IACtC,YAAoC,UAA8B;QAA9B,eAAU,GAAV,UAAU,CAAoB;QAS1D,cAAS,GAAG,KAAK,CAAC;IAT2C,CAAC;IAGtE,IAAY,OAAO;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAA,iBAAM,EAAC,OAAO,KAAK,SAAS,EAAE,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACpE,OAAO,OAAO,CAAC;IAChB,CAAC;IAGD,IAAW,QAAQ;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;IAEM,YAAY;QAClB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACvB,CAAC;IAEM,sBAAsB,CAAC,OAAsB;QACnD,IAAA,iBAAM,EAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,KAAK,CAAC,0CAA0C,CAAC,CAAC;QACtF,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IACzB,CAAC;IAEM,mBAAmB;QACzB,OAAO,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC;IACpC,CAAC;
|
|
1
|
+
{"version":3,"file":"sharedTreeDeltaHandler.js","sourceRoot":"","sources":["../../src/migration-shim/sharedTreeDeltaHandler.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from '@fluidframework/core-utils/internal';\nimport { type IChannelAttributes, type IDeltaHandler } from '@fluidframework/datastore-definitions/internal';\nimport { MessageType, type ISequencedDocumentMessage } from '@fluidframework/driver-definitions/internal';\nimport type { IRuntimeMessageCollection, IRuntimeMessagesContent } from '@fluidframework/runtime-definitions/internal';\n\nimport { type IOpContents, type IShimDeltaHandler } from './types.js';\nimport { attributesMatch, isStampedOp } from './utils.js';\n\n/**\n * Handles incoming and outgoing deltas/ops for the SharedTreeShim distributed data structure.\n * This serves as an adapter to the real DeltaHandler, filter/process migration ops\n *\n * This should just have the ability to drop v1 & migrate ops, and process v2 ops. There may be an opportunity to\n * combine this class with the MigrationShimDeltaHandler, but for now the classes are separated. Once it is clear what\n * exact code can be shared between the two classes is and how it can be merge, we may figure out a way of merging\n * MigrationShimDeltaHandler and SharedTreeShimDeltaHandler.\n */\nexport class SharedTreeShimDeltaHandler implements IShimDeltaHandler {\n\tpublic constructor(private readonly attributes: IChannelAttributes) {}\n\n\tprivate _handler?: IDeltaHandler;\n\tprivate get handler(): IDeltaHandler {\n\t\tconst handler = this._handler;\n\t\tassert(handler !== undefined, 0x7eb /* No handler to process op */);\n\t\treturn handler;\n\t}\n\n\tprivate _attached = false;\n\tpublic get attached(): boolean {\n\t\treturn this._attached;\n\t}\n\n\tpublic markAttached(): void {\n\t\tthis._attached = true;\n\t}\n\n\tpublic attachTreeDeltaHandler(handler: IDeltaHandler): void {\n\t\tassert(this._handler === undefined, 0x7ec /* Should only be able to connect once! */);\n\t\tthis._handler = handler;\n\t}\n\n\tpublic hasTreeDeltaHandler(): boolean {\n\t\treturn this._handler !== undefined;\n\t}\n\n\tprivate process(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void {\n\t\t// This allows us to process the migrate op and prevent the shared object from processing the wrong ops\n\t\t// Drop v1 ops\n\t\tassert(this.hasTreeDeltaHandler(), 0x831 /* Can't process ops before attaching tree handler */);\n\n\t\tif (message.type !== MessageType.Operation) {\n\t\t\treturn;\n\t\t}\n\t\tconst contents = message.contents as IOpContents;\n\t\tif (this.shouldDropOp(contents)) {\n\t\t\treturn;\n\t\t}\n\t\tconst messagesContent: IRuntimeMessagesContent[] = [\n\t\t\t{\n\t\t\t\tcontents,\n\t\t\t\tlocalOpMetadata,\n\t\t\t\tclientSequenceNumber: message.clientSequenceNumber,\n\t\t\t},\n\t\t];\n\t\treturn this.handler.processMessages({ envelope: message, messagesContent, local });\n\t}\n\n\tpublic processMessages(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, messagesContent, local } = messagesCollection;\n\t\tfor (const { contents, localOpMetadata, clientSequenceNumber } of messagesContent) {\n\t\t\tthis.process({ ...envelope, contents, clientSequenceNumber }, local, localOpMetadata);\n\t\t}\n\t}\n\n\t// No idea whether any of the below 4 methods work as expected\n\tpublic setConnectionState(connected: boolean): void {\n\t\treturn this.handler.setConnectionState(connected);\n\t}\n\n\t// Resubmitting v1 ops should fail. We should not be resubmitting v1 ops.\n\tpublic reSubmit(contents: unknown, localOpMetadata: unknown): void {\n\t\tassert(\n\t\t\t!this.shouldDropOp(contents as IOpContents),\n\t\t\t0x832 /* Should not be able to rollback v1 ops as they shouldn't have been created locally. */\n\t\t);\n\t\treturn this.handler.reSubmit(contents, localOpMetadata);\n\t}\n\n\t// We are not capable of applying stashed v1 ops.\n\tpublic applyStashedOp(contents: unknown): void {\n\t\tassert(\n\t\t\t!this.shouldDropOp(contents as IOpContents),\n\t\t\t0x8ab /* SharedTreeShim should not be able to apply v1 ops as they shouldn't have been created locally. */\n\t\t);\n\t\tthis.handler.applyStashedOp(contents);\n\t}\n\n\t/**\n\t * We cannot rollback v1 ops, we have already migrated and are in v2 state, thus we should not be able to generate.\n\t * v1 ops\n\t */\n\tpublic rollback?(contents: unknown, localOpMetadata: unknown): void {\n\t\tassert(\n\t\t\t!this.shouldDropOp(contents as IOpContents),\n\t\t\t0x833 /* Should not be able to rollback v1 ops as they shouldn't have been created locally. */\n\t\t);\n\t\treturn this.handler.rollback?.(contents, localOpMetadata);\n\t}\n\n\t/**\n\t * The SharedTreeShimDeltaHandler is already in a v2 state. Thus it should drop all v1 and migrate ops.\n\t * @param contents - the interrogable op contents to figure out if this is a v1 op, a migrate op, or a v2 op.\n\t * @returns whether or not the op is a v1 or migrate op and should be dropped/ignored.\n\t */\n\tprivate shouldDropOp(contents: IOpContents): boolean {\n\t\tif (!isStampedOp(contents)) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Don't drop v2 ops in v2 state\n\t\tassert(\n\t\t\tattributesMatch(contents.fluidMigrationStamp, this.attributes),\n\t\t\t0x834 /* Unexpected v2 op with mismatched attributes */\n\t\t);\n\t\treturn false;\n\t}\n}\n"]}
|
package/lib/EditLog.d.ts
CHANGED
|
@@ -59,6 +59,10 @@ export interface OrderedEditSet<TChange = unknown> {
|
|
|
59
59
|
* @deprecated this will be removed in favor of {@link OrderedEditSet.tryGetEditAtIndex}
|
|
60
60
|
*/
|
|
61
61
|
getEditInSessionAtIndex(index: number): Edit<TChange>;
|
|
62
|
+
/**
|
|
63
|
+
* Gets all local edits.
|
|
64
|
+
*/
|
|
65
|
+
getLocalEdits(): Iterable<Edit<TChange>>;
|
|
62
66
|
}
|
|
63
67
|
/**
|
|
64
68
|
* Server-provided metadata for edits that have been sequenced.
|
package/lib/EditLog.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditLog.d.ts","sourceRoot":"","sources":["../src/EditLog.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAG/E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElG;;;;;GAKG;AACH,MAAM,WAAW,cAAc,CAAC,OAAO,GAAG,OAAO;IAChD;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAEpC;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAErC;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAEpC;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAEpD;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IAE5D;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IAE5D;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;IAE/D;;;OAGG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAEtD;;;OAGG;IACH,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"EditLog.d.ts","sourceRoot":"","sources":["../src/EditLog.ts"],"names":[],"mappings":"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"}
|
package/lib/EditLog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditLog.js","sourceRoot":"","sources":["../src/EditLog.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { TypedEventEmitter } from '@fluid-internal/client-utils';\nimport type { IEvent } from '@fluidframework/core-interfaces';\nimport { assert, compareArrays } from '@fluidframework/core-utils/internal';\nimport { ITelemetryLoggerExt } from '@fluidframework/telemetry-utils/internal';\nimport { BTree } from '@tylerbu/sorted-btree-es6';\n\nimport type { ChangeCompressor } from './ChangeCompression.js';\nimport { fail } from './Common.js';\nimport type { EditId } from './Identifiers.js';\nimport type { StringInterner } from './StringInterner.js';\nimport { Edit, EditLogSummary, EditWithoutId, FluidEditHandle } from './persisted-types/index.js';\n\n/**\n * An ordered set of Edits associated with a SharedTree.\n * Supports fast lookup of edits by ID and enforces idempotence.\n * @sealed\n * @alpha\n */\nexport interface OrderedEditSet<TChange = unknown> {\n\t/**\n\t * The length of this `OrderedEditSet`.\n\t */\n\treadonly length: number;\n\n\t/**\n\t * The edit IDs of all edits in the log.\n\t */\n\treadonly editIds: readonly EditId[];\n\n\t/**\n\t * @returns the index of the edit with the given editId within this `OrderedEditSet`.\n\t */\n\tgetIndexOfId(editId: EditId): number;\n\n\t/**\n\t * @returns the id of the edit at the given index within this 'OrderedEditSet'.\n\t */\n\tgetIdAtIndex(index: number): EditId;\n\n\t/**\n\t * @returns the index of the edit with the given editId within this `OrderedEditSet`, or `undefined` if no such edit exists.\n\t */\n\ttryGetIndexOfId(editId: EditId): number | undefined;\n\n\t/**\n\t * @returns the edit at the given index within this `OrderedEditSet`.\n\t */\n\ttryGetEditAtIndex(index: number): Edit<TChange> | undefined;\n\n\t/**\n\t * @returns the edit with the given identifier within this `OrderedEditSet`.\n\t */\n\ttryGetEditFromId(editId: EditId): Edit<TChange> | undefined;\n\n\t/**\n\t * @returns the Edit associated with the EditId or undefined if there is no such edit in the set.\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\ttryGetEdit(editId: EditId): Promise<Edit<TChange> | undefined>;\n\n\t/**\n\t * @returns the edit at the given index within this `OrderedEditSet`.\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs.\n\t */\n\tgetEditAtIndex(index: number): Promise<Edit<TChange>>;\n\n\t/**\n\t * @returns the edit at the given index. Must have been added to the log during the current session.\n\t * @deprecated this will be removed in favor of {@link OrderedEditSet.tryGetEditAtIndex}\n\t */\n\tgetEditInSessionAtIndex(index: number): Edit<TChange>;\n}\n\n/**\n * Server-provided metadata for edits that have been sequenced.\n */\nexport interface EditSequencingInfo {\n\t/**\n\t * The server-assigned sequence number of the op.\n\t */\n\treadonly sequenceNumber: number;\n\t/**\n\t * Last known sequenced edit at the time this op was issued.\n\t */\n\treadonly referenceSequenceNumber: number;\n}\n\n/**\n * Server-provided metadata for edits that have been sequenced.\n */\nexport interface MessageSequencingInfo extends EditSequencingInfo {\n\t/**\n\t * Last sequenced edit that all clients are guaranteed to be aware of.\n\t * If not specified, then some clients have not seen any edits yet.\n\t */\n\treadonly minimumSequenceNumber?: number;\n}\n\n/**\n * Metadata for a sequenced edit.\n */\nexport interface SequencedOrderedEditId {\n\treadonly isLocal: false;\n\treadonly index: number;\n\t/**\n\t * Information about the edit's relationship to other sequenced edits.\n\t * Undefined iff the edit was loaded from a summary.\n\t */\n\treadonly sequenceInfo?: EditSequencingInfo;\n}\n\n/**\n * Metadata for a local edit.\n */\nexport interface LocalOrderedEditId {\n\treadonly isLocal: true;\n\treadonly localSequence: number;\n}\n\n/**\n * Metadata for an edit.\n */\nexport type OrderedEditId = SequencedOrderedEditId | LocalOrderedEditId;\n\n/**\n * Compressor+interner pair used for encoding an {@link EditLog} into a summary.\n * @internal\n */\nexport interface EditLogEncoder {\n\tcompressor: ChangeCompressor;\n\tinterner: StringInterner;\n}\n\n/**\n * A sequence of edits that may or may not need to be downloaded into the EditLog from an external service\n * @deprecated Edit virtualization is no longer supported.\n */\nexport interface EditChunk<TChange> {\n\thandle?: EditHandle<TChange>;\n\tedits?: EditWithoutId<TChange>[];\n}\n/**\n * EditHandles are used to load edit chunks stored outside of the EditLog.\n * This is typically implemented by a wrapper around an IFluidHandle<ArrayBufferLike>.\n * @deprecated Edit virtualization is no longer supported.\n * @internal\n */\nexport interface EditHandle<TChange> {\n\treadonly get: () => Promise<EditWithoutId<TChange>[]>;\n\treadonly baseHandle: FluidEditHandle;\n}\n\n/**\n * Returns an object that separates an Edit into two fields, id and editWithoutId.\n */\nexport function separateEditAndId<TChange>(edit: Edit<TChange>): {\n\tid: EditId;\n\teditWithoutId: EditWithoutId<TChange>;\n} {\n\tconst editWithoutId = { ...edit, id: undefined };\n\tdelete editWithoutId.id;\n\treturn { id: edit.id, editWithoutId };\n}\n\n/**\n * @param summary - The edit log summary to parse.\n * @returns the number of handles saved to the provided edit log summary.\n * @deprecated Edit virtualization is no longer supported.\n */\nexport function getNumberOfHandlesFromEditLogSummary(summary: EditLogSummary<unknown, unknown>): number {\n\tconst { editChunks } = summary;\n\n\tlet numberOfHandles = 0;\n\teditChunks.forEach(({ chunk }) => {\n\t\tif (!Array.isArray(chunk)) {\n\t\t\tnumberOfHandles++;\n\t\t}\n\t});\n\n\treturn numberOfHandles;\n}\n\n/**\n * Event fired when an edit is added to an `EditLog`.\n * @param edit - The edit that was added to the log\n * @param isLocal - true iff this edit was generated locally\n */\nexport type EditAddedHandler<TChange> = (edit: Edit<TChange>, isLocal: boolean, wasLocal: boolean) => void;\n\n/**\n * Event fired before edits are evicted from the edit log. It takes in a count of the number of edits to evict\n * starting from the oldest in memory edit. To get the edit itself, call {@link EditLog.getEditAtIndex}.\n * The edit index corresponds to the count + {@link EditLog.earliestAvailableEditIndex}.\n */\nexport type EditEvictionHandler = (editsToEvict: number) => void;\n\n/**\n * Events which may be emitted by {@link EditLog}\n * @alpha\n */\nexport interface IEditLogEvents extends IEvent {\n\t(event: 'unexpectedHistoryChunk', listener: () => void);\n}\n\n/**\n * The edit history log for SharedTree.\n * Contains only completed edits (no in-progress edits).\n * Ordered first by locality (acked or local), then by time of insertion.\n * May not contain more than one edit with the same ID.\n * @sealed\n * @alpha\n */\nexport class EditLog<TChange = unknown> extends TypedEventEmitter<IEditLogEvents> implements OrderedEditSet<TChange> {\n\tprivate localEditSequence = 0;\n\n\tprivate readonly sequenceNumberToIndex?: BTree<number, number>;\n\tprivate _minSequenceNumber = 0;\n\n\tprivate readonly sequencedEdits: Edit<TChange>[] = [];\n\tprivate readonly localEdits: Edit<TChange>[] = [];\n\n\tprivate readonly allEditIds = new Map<EditId, OrderedEditId>();\n\tprivate _earliestAvailableEditIndex = 0;\n\tprivate readonly _editAddedHandlers = new Set<EditAddedHandler<TChange>>();\n\tprivate readonly _editEvictionHandlers = new Set<EditEvictionHandler>();\n\n\t/**\n\t * @returns The index of the earliest edit stored in this log.\n\t * Edit indices are unique and strictly increasing within the session.\n\t */\n\tpublic get earliestAvailableEditIndex(): number {\n\t\treturn this._earliestAvailableEditIndex;\n\t}\n\n\t/**\n\t * @returns The sequence number of the latest edit known by all nodes.\n\t */\n\tpublic get minSequenceNumber(): number {\n\t\treturn this._minSequenceNumber;\n\t}\n\n\t/**\n\t * Construct an `EditLog` using the given options.\n\t * @param summary - An edit log summary used to populate the edit log.\n\t * @param logger - An optional logger to record telemetry/errors\n\t * @param editAddedHandlers - Optional handlers that are called when edits are added.\n\t * @param targetLength - The target number of sequenced edits that the log will try to store in memory.\n\t * Depending on eviction frequency and the collaboration window, there can be more edits in memory at a given time.\n\t * Edits greater than or equal to the `minSequenceNumber` (aka in the collaboration window) are not evicted.\n\t * @param evictionFrequency - The rate at which edits are evicted from memory. This is a factor of the editLogSize.\n\t * For example, with the default frequency of inMemoryHistorySize * 2 and a size of 10, the log will evict once it reaches 20 sequenced edits\n\t * down to 10 edits, also keeping any that are still in the collaboration window.\n\t * @param editEvictionHandlers - Handlers that are called before edits are evicted from memory. This provides a chance for\n\t * callers to work with the edits before they are lost.\n\t */\n\tpublic constructor(\n\t\tsummary: EditLogSummary<TChange, EditHandle<TChange>> = { editIds: [], editChunks: [] },\n\t\tprivate readonly logger?: ITelemetryLoggerExt,\n\t\teditAddedHandlers: readonly EditAddedHandler<TChange>[] = [],\n\t\tprivate readonly targetLength = Infinity,\n\t\tprivate readonly evictionFrequency = targetLength * 2,\n\t\teditEvictionHandlers: readonly EditEvictionHandler[] = []\n\t) {\n\t\tsuper();\n\t\tconst { editChunks, editIds } = summary;\n\n\t\tfor (const handler of editAddedHandlers) {\n\t\t\tthis.registerEditAddedHandler(handler);\n\t\t}\n\n\t\tif (targetLength !== Infinity) {\n\t\t\tif (targetLength < 0 || evictionFrequency < 0) {\n\t\t\t\tfail('targetLength and evictionFrequency should not be negative');\n\t\t\t}\n\t\t\tthis.sequenceNumberToIndex = new BTree([[0, 0]]);\n\t\t\tfor (const handler of editEvictionHandlers) {\n\t\t\t\tthis.registerEditEvictionHandler(handler);\n\t\t\t}\n\t\t}\n\n\t\teditChunks.forEach((editChunkOrHandle) => {\n\t\t\tconst { startRevision, chunk } = editChunkOrHandle;\n\n\t\t\tif (Array.isArray(chunk)) {\n\t\t\t\tfor (const [index, edit] of chunk.entries()) {\n\t\t\t\t\tconst editIndex = startRevision + index;\n\t\t\t\t\tconst id = editIds[editIndex];\n\t\t\t\t\tthis.sequencedEdits.push({ id, ...edit });\n\t\t\t\t\tconst encounteredEditId = this.allEditIds.get(id);\n\t\t\t\t\tassert(encounteredEditId === undefined, 0x60a /* Duplicate acked edit. */);\n\t\t\t\t\tthis.allEditIds.set(id, { isLocal: false, index: editIndex });\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Ignore any edit handles, these edits are now unrecoverable.\n\t\t\t\t// This should instead download the edit chunk and store them but history is not\n\t\t\t\t// being used so we're going with the simpler solution.\n\t\t\t\tthis.logger?.sendErrorEvent({ eventName: 'UnexpectedEditHandleInSummary' });\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Registers a handler for when an edit is added to this `EditLog`.\n\t * @returns A callback which can be invoked to unregister this handler.\n\t */\n\tpublic registerEditAddedHandler(handler: EditAddedHandler<TChange>): () => void {\n\t\tthis._editAddedHandlers.add(handler);\n\t\treturn () => this._editAddedHandlers.delete(handler);\n\t}\n\n\t/**\n\t * @returns the `EditAddedHandler`s registered on this `EditLog`.\n\t */\n\tpublic get editAddedHandlers(): readonly EditAddedHandler<TChange>[] {\n\t\treturn Array.from(this._editAddedHandlers);\n\t}\n\n\t/**\n\t * Registers a handler that is called before an edit is evicted from this `EditLog`.\n\t * @returns A callback which can be invoked to unregister this handler.\n\t */\n\tpublic registerEditEvictionHandler(handler: EditEvictionHandler): () => void {\n\t\tthis._editEvictionHandlers.add(handler);\n\t\treturn () => this._editEvictionHandlers.delete(handler);\n\t}\n\n\t/**\n\t * @returns the `EditEvictedHandler`s registered on this `EditLog`.\n\t */\n\tpublic get editEvictedHandlers(): readonly EditEvictionHandler[] {\n\t\treturn Array.from(this._editEvictionHandlers);\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.length}\n\t */\n\tpublic get length(): number {\n\t\treturn this.numberOfSequencedEdits + this.numberOfLocalEdits;\n\t}\n\n\t/**\n\t * The number of sequenced (acked) edits in the log.\n\t */\n\tpublic get numberOfSequencedEdits(): number {\n\t\treturn this.sequencedEdits.length;\n\t}\n\n\t/**\n\t * The number of local (unacked) edits in the log.\n\t */\n\tpublic get numberOfLocalEdits(): number {\n\t\treturn this.localEdits.length;\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.editIds}\n\t */\n\tpublic get editIds(): EditId[] {\n\t\treturn this.sequencedEdits.map(({ id }) => id).concat(this.localEdits.map(({ id }) => id));\n\t}\n\n\t/**\n\t * @returns true iff the edit is contained in this 'EditLog' and it is a local edit (not sequenced).\n\t */\n\tpublic isLocalEdit(editId: EditId): boolean {\n\t\tconst entry = this.allEditIds.get(editId);\n\t\treturn entry?.isLocal ?? false;\n\t}\n\n\t/**\n\t * @returns true iff the revision is a sequenced revision (not local).\n\t */\n\tpublic isSequencedRevision(revision: number): boolean {\n\t\treturn revision <= this.sequencedEdits.length;\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.tryGetIndexOfId}\n\t */\n\tpublic tryGetIndexOfId(editId: EditId): number | undefined {\n\t\tconst orderedEdit = this.allEditIds.get(editId);\n\t\tif (orderedEdit === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (orderedEdit.isLocal) {\n\t\t\tconst firstLocal = this.allEditIds.get(this.localEdits[0].id) ?? fail('edit not found');\n\t\t\tassert(firstLocal.isLocal, 0x60b /* local edit should be local */);\n\t\t\treturn (\n\t\t\t\tthis._earliestAvailableEditIndex +\n\t\t\t\tthis.numberOfSequencedEdits +\n\t\t\t\torderedEdit.localSequence -\n\t\t\t\tfirstLocal.localSequence\n\t\t\t);\n\t\t}\n\t\treturn orderedEdit.index;\n\t}\n\n\t/**\n\t * @returns Edit metadata for the edit with the given `editId`.\n\t */\n\tpublic getOrderedEditId(editId: EditId): OrderedEditId {\n\t\treturn this.allEditIds.get(editId) ?? fail('All edits should exist in this map');\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.getIndexOfId}\n\t */\n\tpublic getIndexOfId(editId: EditId): number {\n\t\treturn this.tryGetIndexOfId(editId) ?? fail('edit not found');\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.getIdAtIndex}\n\t */\n\tpublic getIdAtIndex(index: number): EditId {\n\t\tif (this._earliestAvailableEditIndex + this.numberOfSequencedEdits <= index) {\n\t\t\treturn this.localEdits[index - this.numberOfSequencedEdits].id;\n\t\t}\n\n\t\treturn this.sequencedEdits[index - this._earliestAvailableEditIndex].id;\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.tryGetEditAtIndex}\n\t */\n\tpublic tryGetEditAtIndex(index: number): Edit<TChange> | undefined {\n\t\tif (this._earliestAvailableEditIndex + this.numberOfSequencedEdits <= index) {\n\t\t\treturn this.localEdits[index - this.numberOfSequencedEdits];\n\t\t}\n\n\t\treturn this.sequencedEdits[index - this._earliestAvailableEditIndex];\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.tryGetEditFromId}\n\t */\n\tpublic tryGetEditFromId(editId: EditId): Edit<TChange> | undefined {\n\t\tconst index = this.tryGetIndexOfId(editId);\n\t\treturn index !== undefined ? this.tryGetEditAtIndex(index) : undefined;\n\t}\n\n\t/**\n\t * Sequences all local edits.\n\t */\n\tpublic sequenceLocalEdits(): void {\n\t\tthis.localEdits.slice().forEach((edit) => this.addSequencedEditInternal(edit));\n\t}\n\n\t/**\n\t * Adds a sequenced (non-local) edit to the edit log.\n\t * If the id of the supplied edit matches a local edit already present in the log, the local edit will be replaced.\n\t *\n\t */\n\tpublic addSequencedEdit(edit: Edit<TChange>, message: MessageSequencingInfo): void {\n\t\tthis.addSequencedEditInternal(edit, message, message.minimumSequenceNumber);\n\t}\n\n\t/**\n\t * Returns all local edits from this EditLog\n\t * This is useful for op format upgrades, which might warrant re-submission of these ops using the new format.\n\t * See the breaking change documentation for more information.\n\t */\n\tpublic *getLocalEdits(): Iterable<Edit<TChange>> {\n\t\tfor (const edit of this.localEdits) {\n\t\t\tyield edit;\n\t\t}\n\t}\n\n\t/**\n\t * Adds a sequenced (non-local) edit to the edit log.\n\t * If the id of the supplied edit matches a local edit already present in the log, the local edit will be replaced.\n\t */\n\tprivate addSequencedEditInternal(\n\t\tedit: Edit<TChange>,\n\t\tinfo?: EditSequencingInfo,\n\t\tminSequenceNumber: number = 0\n\t): void {\n\t\tassert(\n\t\t\tminSequenceNumber >= this._minSequenceNumber,\n\t\t\t0x60c /* Sequenced edits should carry a monotonically increasing min number */\n\t\t);\n\t\tthis._minSequenceNumber = minSequenceNumber;\n\n\t\tconst { id } = edit;\n\t\t// The index of the sequenced edit to add\n\t\tconst index = this._earliestAvailableEditIndex + this.numberOfSequencedEdits;\n\n\t\t// Remove the edit from local edits if it exists.\n\t\tconst encounteredEditId = this.allEditIds.get(id);\n\t\tif (encounteredEditId !== undefined) {\n\t\t\t// New edit already exits: it must have been a local edit.\n\t\t\tassert(encounteredEditId.isLocal, 0x60d /* Duplicate acked edit. */);\n\t\t\t// Remove it from localEdits. Due to ordering requirements, it must be first.\n\t\t\tconst oldLocalEditId = this.localEdits.shift()?.id ?? fail('Local edit should exist');\n\t\t\tassert(oldLocalEditId === id, 0x60e /* Causal ordering should be upheld */);\n\t\t}\n\n\t\tthis.sequencedEdits.push(edit);\n\n\t\tconst sequencedEditId: SequencedOrderedEditId = {\n\t\t\tindex,\n\t\t\tisLocal: false,\n\t\t\tsequenceInfo: info,\n\t\t};\n\t\tthis.allEditIds.set(id, sequencedEditId);\n\t\tif (info !== undefined) {\n\t\t\tthis.sequenceNumberToIndex?.set(info.sequenceNumber, index);\n\t\t}\n\t\tthis.emitAdd(edit, false, encounteredEditId !== undefined);\n\n\t\t// Check if any edits need to be evicted due to this addition\n\t\tif (this.sequenceNumberToIndex !== undefined && this.numberOfSequencedEdits >= this.evictionFrequency) {\n\t\t\tthis.evictEdits();\n\t\t}\n\t}\n\n\t/**\n\t * Adds a non-sequenced (local) edit to the edit log.\n\t * Duplicate edits are ignored.\n\t */\n\tpublic addLocalEdit(edit: Edit<TChange>): void {\n\t\tthis.localEdits.push(edit);\n\t\tconst localEditId: LocalOrderedEditId = {\n\t\t\tlocalSequence: this.localEditSequence++,\n\t\t\tisLocal: true,\n\t\t};\n\t\tthis.allEditIds.set(edit.id, localEditId);\n\t\tthis.emitAdd(edit, true, false);\n\t}\n\n\tprivate emitAdd(editAdded: Edit<TChange>, isLocal: boolean, wasLocal: boolean): void {\n\t\tfor (const handler of this._editAddedHandlers) {\n\t\t\thandler(editAdded, isLocal, wasLocal);\n\t\t}\n\t}\n\n\tprivate evictEdits(): void {\n\t\tassert(\n\t\t\tthis.sequenceNumberToIndex !== undefined,\n\t\t\t0x60f /* Edits should never be evicted if the target length is set to infinity */\n\t\t);\n\n\t\tconst minSequenceIndex =\n\t\t\tthis.sequenceNumberToIndex.getPairOrNextHigher(this._minSequenceNumber)?.[1] ??\n\t\t\tfail('No index associated with that sequence number.');\n\t\t// Exclude any edits in the collab window from being evicted\n\t\tconst numberOfEvictableEdits = minSequenceIndex - this.earliestAvailableEditIndex;\n\n\t\tif (numberOfEvictableEdits > 0) {\n\t\t\t// Evict either all but the target log size or the number of evictable edits, whichever is smaller\n\t\t\tconst numberOfDesiredEditsToEvict = this.numberOfSequencedEdits - this.targetLength;\n\t\t\tconst numberOfEditsToEvict = Math.min(numberOfEvictableEdits, numberOfDesiredEditsToEvict);\n\t\t\tfor (const handler of this._editEvictionHandlers) {\n\t\t\t\thandler(numberOfEditsToEvict);\n\t\t\t}\n\n\t\t\t// Remove the edits and move up the earliest available index\n\t\t\tconst removedEdits = this.sequencedEdits.splice(0, numberOfEditsToEvict);\n\t\t\tthis._earliestAvailableEditIndex += numberOfEditsToEvict;\n\n\t\t\t// On eviction, we need to remove the IDs of edits that have been evicted\n\t\t\tremovedEdits.forEach((edit) => this.allEditIds.delete(edit.id));\n\n\t\t\t// The minSequenceNumber is strictly increasing so we can clear sequence numbers before it\n\t\t\tthis.sequenceNumberToIndex.deleteRange(0, this._minSequenceNumber, false);\n\t\t}\n\t}\n\n\t/**\n\t * @returns true iff this `EditLog` and `other` are equivalent, regardless of locality.\n\t */\n\tpublic equals<TOtherChangeTypesInternal>(other: EditLog<TOtherChangeTypesInternal>): boolean {\n\t\t// TODO #45414: We should also be deep comparing the list of changes in the edit. This is not straightforward.\n\t\t// We can use our edit validation code when we write it since it will need to do deep walks of the changes.\n\t\treturn compareArrays(this.editIds, other.editIds);\n\t}\n\n\t/**\n\t * @returns the summary of this `OrderedEditSet` that can be used to reconstruct the edit set.\n\t */\n\tpublic getEditLogSummary(): EditLogSummary<TChange, FluidEditHandle>;\n\n\t/**\n\t * @param compressEdit - a function which compresses edits\n\t * @returns the summary of this `OrderedEditSet` that can be used to reconstruct the edit set.\n\t */\n\tpublic getEditLogSummary<TCompressedChange>(\n\t\tcompressEdit: (edit: Pick<Edit<TChange>, 'changes'>) => Pick<Edit<TCompressedChange>, 'changes'>\n\t): EditLogSummary<TCompressedChange, FluidEditHandle>;\n\tpublic getEditLogSummary<TCompressedChange>(\n\t\tcompressEdit?: (edit: Pick<Edit<TChange>, 'changes'>) => Pick<Edit<TCompressedChange>, 'changes'>\n\t): EditLogSummary<TChange, FluidEditHandle> | EditLogSummary<TCompressedChange, FluidEditHandle> {\n\t\tconst editIds = this.sequencedEdits.map(({ id }) => id);\n\t\treturn compressEdit !== undefined\n\t\t\t? {\n\t\t\t\t\teditChunks:\n\t\t\t\t\t\tthis.sequencedEdits.length === 0\n\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t// Store all edits within a single \"chunk\"\n\t\t\t\t\t\t\t\t\t\tstartRevision: 0,\n\t\t\t\t\t\t\t\t\t\tchunk: this.sequencedEdits.map((edit) => compressEdit(edit)),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\teditIds,\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\teditChunks:\n\t\t\t\t\t\tthis.sequencedEdits.length === 0\n\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t// Store all edits within a single \"chunk\"\n\t\t\t\t\t\t\t\t\t\tstartRevision: 0,\n\t\t\t\t\t\t\t\t\t\tchunk: this.sequencedEdits.map(({ changes }) => ({ changes })),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\teditIds,\n\t\t\t\t};\n\t}\n\n\t// APIS DEPRECATED DUE TO HISTORY'S PEACEFUL DEATH\n\t/**\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\tpublic async tryGetEdit(editId: EditId): Promise<Edit<TChange> | undefined> {\n\t\tconst index = this.tryGetIndexOfId(editId);\n\t\treturn index !== undefined ? this.tryGetEditAtIndex(index) : undefined;\n\t}\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\tpublic async getEditAtIndex(index: number): Promise<Edit<TChange>> {\n\t\treturn this.tryGetEditAtIndex(index) ?? fail('Edit not found');\n\t}\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\tpublic getEditInSessionAtIndex(index: number): Edit<TChange> {\n\t\treturn this.tryGetEditAtIndex(index) ?? fail('Edit not found');\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"EditLog.js","sourceRoot":"","sources":["../src/EditLog.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { TypedEventEmitter } from '@fluid-internal/client-utils';\nimport type { IEvent } from '@fluidframework/core-interfaces';\nimport { assert, compareArrays } from '@fluidframework/core-utils/internal';\nimport { ITelemetryLoggerExt } from '@fluidframework/telemetry-utils/internal';\nimport { BTree } from '@tylerbu/sorted-btree-es6';\n\nimport type { ChangeCompressor } from './ChangeCompression.js';\nimport { fail } from './Common.js';\nimport type { EditId } from './Identifiers.js';\nimport type { StringInterner } from './StringInterner.js';\nimport { Edit, EditLogSummary, EditWithoutId, FluidEditHandle } from './persisted-types/index.js';\n\n/**\n * An ordered set of Edits associated with a SharedTree.\n * Supports fast lookup of edits by ID and enforces idempotence.\n * @sealed\n * @alpha\n */\nexport interface OrderedEditSet<TChange = unknown> {\n\t/**\n\t * The length of this `OrderedEditSet`.\n\t */\n\treadonly length: number;\n\n\t/**\n\t * The edit IDs of all edits in the log.\n\t */\n\treadonly editIds: readonly EditId[];\n\n\t/**\n\t * @returns the index of the edit with the given editId within this `OrderedEditSet`.\n\t */\n\tgetIndexOfId(editId: EditId): number;\n\n\t/**\n\t * @returns the id of the edit at the given index within this 'OrderedEditSet'.\n\t */\n\tgetIdAtIndex(index: number): EditId;\n\n\t/**\n\t * @returns the index of the edit with the given editId within this `OrderedEditSet`, or `undefined` if no such edit exists.\n\t */\n\ttryGetIndexOfId(editId: EditId): number | undefined;\n\n\t/**\n\t * @returns the edit at the given index within this `OrderedEditSet`.\n\t */\n\ttryGetEditAtIndex(index: number): Edit<TChange> | undefined;\n\n\t/**\n\t * @returns the edit with the given identifier within this `OrderedEditSet`.\n\t */\n\ttryGetEditFromId(editId: EditId): Edit<TChange> | undefined;\n\n\t/**\n\t * @returns the Edit associated with the EditId or undefined if there is no such edit in the set.\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\ttryGetEdit(editId: EditId): Promise<Edit<TChange> | undefined>;\n\n\t/**\n\t * @returns the edit at the given index within this `OrderedEditSet`.\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs.\n\t */\n\tgetEditAtIndex(index: number): Promise<Edit<TChange>>;\n\n\t/**\n\t * @returns the edit at the given index. Must have been added to the log during the current session.\n\t * @deprecated this will be removed in favor of {@link OrderedEditSet.tryGetEditAtIndex}\n\t */\n\tgetEditInSessionAtIndex(index: number): Edit<TChange>;\n\n\t/**\n\t * Gets all local edits.\n\t */\n\tgetLocalEdits(): Iterable<Edit<TChange>>;\n}\n\n/**\n * Server-provided metadata for edits that have been sequenced.\n */\nexport interface EditSequencingInfo {\n\t/**\n\t * The server-assigned sequence number of the op.\n\t */\n\treadonly sequenceNumber: number;\n\t/**\n\t * Last known sequenced edit at the time this op was issued.\n\t */\n\treadonly referenceSequenceNumber: number;\n}\n\n/**\n * Server-provided metadata for edits that have been sequenced.\n */\nexport interface MessageSequencingInfo extends EditSequencingInfo {\n\t/**\n\t * Last sequenced edit that all clients are guaranteed to be aware of.\n\t * If not specified, then some clients have not seen any edits yet.\n\t */\n\treadonly minimumSequenceNumber?: number;\n}\n\n/**\n * Metadata for a sequenced edit.\n */\nexport interface SequencedOrderedEditId {\n\treadonly isLocal: false;\n\treadonly index: number;\n\t/**\n\t * Information about the edit's relationship to other sequenced edits.\n\t * Undefined iff the edit was loaded from a summary.\n\t */\n\treadonly sequenceInfo?: EditSequencingInfo;\n}\n\n/**\n * Metadata for a local edit.\n */\nexport interface LocalOrderedEditId {\n\treadonly isLocal: true;\n\treadonly localSequence: number;\n}\n\n/**\n * Metadata for an edit.\n */\nexport type OrderedEditId = SequencedOrderedEditId | LocalOrderedEditId;\n\n/**\n * Compressor+interner pair used for encoding an {@link EditLog} into a summary.\n * @internal\n */\nexport interface EditLogEncoder {\n\tcompressor: ChangeCompressor;\n\tinterner: StringInterner;\n}\n\n/**\n * A sequence of edits that may or may not need to be downloaded into the EditLog from an external service\n * @deprecated Edit virtualization is no longer supported.\n */\nexport interface EditChunk<TChange> {\n\thandle?: EditHandle<TChange>;\n\tedits?: EditWithoutId<TChange>[];\n}\n/**\n * EditHandles are used to load edit chunks stored outside of the EditLog.\n * This is typically implemented by a wrapper around an IFluidHandle<ArrayBufferLike>.\n * @deprecated Edit virtualization is no longer supported.\n * @internal\n */\nexport interface EditHandle<TChange> {\n\treadonly get: () => Promise<EditWithoutId<TChange>[]>;\n\treadonly baseHandle: FluidEditHandle;\n}\n\n/**\n * Returns an object that separates an Edit into two fields, id and editWithoutId.\n */\nexport function separateEditAndId<TChange>(edit: Edit<TChange>): {\n\tid: EditId;\n\teditWithoutId: EditWithoutId<TChange>;\n} {\n\tconst editWithoutId = { ...edit, id: undefined };\n\tdelete editWithoutId.id;\n\treturn { id: edit.id, editWithoutId };\n}\n\n/**\n * @param summary - The edit log summary to parse.\n * @returns the number of handles saved to the provided edit log summary.\n * @deprecated Edit virtualization is no longer supported.\n */\nexport function getNumberOfHandlesFromEditLogSummary(summary: EditLogSummary<unknown, unknown>): number {\n\tconst { editChunks } = summary;\n\n\tlet numberOfHandles = 0;\n\teditChunks.forEach(({ chunk }) => {\n\t\tif (!Array.isArray(chunk)) {\n\t\t\tnumberOfHandles++;\n\t\t}\n\t});\n\n\treturn numberOfHandles;\n}\n\n/**\n * Event fired when an edit is added to an `EditLog`.\n * @param edit - The edit that was added to the log\n * @param isLocal - true iff this edit was generated locally\n */\nexport type EditAddedHandler<TChange> = (edit: Edit<TChange>, isLocal: boolean, wasLocal: boolean) => void;\n\n/**\n * Event fired before edits are evicted from the edit log. It takes in a count of the number of edits to evict\n * starting from the oldest in memory edit. To get the edit itself, call {@link EditLog.getEditAtIndex}.\n * The edit index corresponds to the count + {@link EditLog.earliestAvailableEditIndex}.\n */\nexport type EditEvictionHandler = (editsToEvict: number) => void;\n\n/**\n * Events which may be emitted by {@link EditLog}\n * @alpha\n */\nexport interface IEditLogEvents extends IEvent {\n\t(event: 'unexpectedHistoryChunk', listener: () => void);\n}\n\n/**\n * The edit history log for SharedTree.\n * Contains only completed edits (no in-progress edits).\n * Ordered first by locality (acked or local), then by time of insertion.\n * May not contain more than one edit with the same ID.\n * @sealed\n * @alpha\n */\nexport class EditLog<TChange = unknown> extends TypedEventEmitter<IEditLogEvents> implements OrderedEditSet<TChange> {\n\tprivate localEditSequence = 0;\n\n\tprivate readonly sequenceNumberToIndex?: BTree<number, number>;\n\tprivate _minSequenceNumber = 0;\n\n\tprivate readonly sequencedEdits: Edit<TChange>[] = [];\n\tprivate readonly localEdits: Edit<TChange>[] = [];\n\n\tprivate readonly allEditIds = new Map<EditId, OrderedEditId>();\n\tprivate _earliestAvailableEditIndex = 0;\n\tprivate readonly _editAddedHandlers = new Set<EditAddedHandler<TChange>>();\n\tprivate readonly _editEvictionHandlers = new Set<EditEvictionHandler>();\n\n\t/**\n\t * @returns The index of the earliest edit stored in this log.\n\t * Edit indices are unique and strictly increasing within the session.\n\t */\n\tpublic get earliestAvailableEditIndex(): number {\n\t\treturn this._earliestAvailableEditIndex;\n\t}\n\n\t/**\n\t * @returns The sequence number of the latest edit known by all nodes.\n\t */\n\tpublic get minSequenceNumber(): number {\n\t\treturn this._minSequenceNumber;\n\t}\n\n\t/**\n\t * Construct an `EditLog` using the given options.\n\t * @param summary - An edit log summary used to populate the edit log.\n\t * @param logger - An optional logger to record telemetry/errors\n\t * @param editAddedHandlers - Optional handlers that are called when edits are added.\n\t * @param targetLength - The target number of sequenced edits that the log will try to store in memory.\n\t * Depending on eviction frequency and the collaboration window, there can be more edits in memory at a given time.\n\t * Edits greater than or equal to the `minSequenceNumber` (aka in the collaboration window) are not evicted.\n\t * @param evictionFrequency - The rate at which edits are evicted from memory. This is a factor of the editLogSize.\n\t * For example, with the default frequency of inMemoryHistorySize * 2 and a size of 10, the log will evict once it reaches 20 sequenced edits\n\t * down to 10 edits, also keeping any that are still in the collaboration window.\n\t * @param editEvictionHandlers - Handlers that are called before edits are evicted from memory. This provides a chance for\n\t * callers to work with the edits before they are lost.\n\t */\n\tpublic constructor(\n\t\tsummary: EditLogSummary<TChange, EditHandle<TChange>> = { editIds: [], editChunks: [] },\n\t\tprivate readonly logger?: ITelemetryLoggerExt,\n\t\teditAddedHandlers: readonly EditAddedHandler<TChange>[] = [],\n\t\tprivate readonly targetLength = Infinity,\n\t\tprivate readonly evictionFrequency = targetLength * 2,\n\t\teditEvictionHandlers: readonly EditEvictionHandler[] = []\n\t) {\n\t\tsuper();\n\t\tconst { editChunks, editIds } = summary;\n\n\t\tfor (const handler of editAddedHandlers) {\n\t\t\tthis.registerEditAddedHandler(handler);\n\t\t}\n\n\t\tif (targetLength !== Infinity) {\n\t\t\tif (targetLength < 0 || evictionFrequency < 0) {\n\t\t\t\tfail('targetLength and evictionFrequency should not be negative');\n\t\t\t}\n\t\t\tthis.sequenceNumberToIndex = new BTree([[0, 0]]);\n\t\t\tfor (const handler of editEvictionHandlers) {\n\t\t\t\tthis.registerEditEvictionHandler(handler);\n\t\t\t}\n\t\t}\n\n\t\teditChunks.forEach((editChunkOrHandle) => {\n\t\t\tconst { startRevision, chunk } = editChunkOrHandle;\n\n\t\t\tif (Array.isArray(chunk)) {\n\t\t\t\tfor (const [index, edit] of chunk.entries()) {\n\t\t\t\t\tconst editIndex = startRevision + index;\n\t\t\t\t\tconst id = editIds[editIndex];\n\t\t\t\t\tthis.sequencedEdits.push({ id, ...edit });\n\t\t\t\t\tconst encounteredEditId = this.allEditIds.get(id);\n\t\t\t\t\tassert(encounteredEditId === undefined, 0x60a /* Duplicate acked edit. */);\n\t\t\t\t\tthis.allEditIds.set(id, { isLocal: false, index: editIndex });\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Ignore any edit handles, these edits are now unrecoverable.\n\t\t\t\t// This should instead download the edit chunk and store them but history is not\n\t\t\t\t// being used so we're going with the simpler solution.\n\t\t\t\tthis.logger?.sendErrorEvent({ eventName: 'UnexpectedEditHandleInSummary' });\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Registers a handler for when an edit is added to this `EditLog`.\n\t * @returns A callback which can be invoked to unregister this handler.\n\t */\n\tpublic registerEditAddedHandler(handler: EditAddedHandler<TChange>): () => void {\n\t\tthis._editAddedHandlers.add(handler);\n\t\treturn () => this._editAddedHandlers.delete(handler);\n\t}\n\n\t/**\n\t * @returns the `EditAddedHandler`s registered on this `EditLog`.\n\t */\n\tpublic get editAddedHandlers(): readonly EditAddedHandler<TChange>[] {\n\t\treturn Array.from(this._editAddedHandlers);\n\t}\n\n\t/**\n\t * Registers a handler that is called before an edit is evicted from this `EditLog`.\n\t * @returns A callback which can be invoked to unregister this handler.\n\t */\n\tpublic registerEditEvictionHandler(handler: EditEvictionHandler): () => void {\n\t\tthis._editEvictionHandlers.add(handler);\n\t\treturn () => this._editEvictionHandlers.delete(handler);\n\t}\n\n\t/**\n\t * @returns the `EditEvictedHandler`s registered on this `EditLog`.\n\t */\n\tpublic get editEvictedHandlers(): readonly EditEvictionHandler[] {\n\t\treturn Array.from(this._editEvictionHandlers);\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.length}\n\t */\n\tpublic get length(): number {\n\t\treturn this.numberOfSequencedEdits + this.numberOfLocalEdits;\n\t}\n\n\t/**\n\t * The number of sequenced (acked) edits in the log.\n\t */\n\tpublic get numberOfSequencedEdits(): number {\n\t\treturn this.sequencedEdits.length;\n\t}\n\n\t/**\n\t * The number of local (unacked) edits in the log.\n\t */\n\tpublic get numberOfLocalEdits(): number {\n\t\treturn this.localEdits.length;\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.editIds}\n\t */\n\tpublic get editIds(): EditId[] {\n\t\treturn this.sequencedEdits.map(({ id }) => id).concat(this.localEdits.map(({ id }) => id));\n\t}\n\n\t/**\n\t * @returns true iff the edit is contained in this 'EditLog' and it is a local edit (not sequenced).\n\t */\n\tpublic isLocalEdit(editId: EditId): boolean {\n\t\tconst entry = this.allEditIds.get(editId);\n\t\treturn entry?.isLocal ?? false;\n\t}\n\n\t/**\n\t * @returns true iff the revision is a sequenced revision (not local).\n\t */\n\tpublic isSequencedRevision(revision: number): boolean {\n\t\treturn revision <= this.sequencedEdits.length;\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.tryGetIndexOfId}\n\t */\n\tpublic tryGetIndexOfId(editId: EditId): number | undefined {\n\t\tconst orderedEdit = this.allEditIds.get(editId);\n\t\tif (orderedEdit === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (orderedEdit.isLocal) {\n\t\t\tconst firstLocal = this.allEditIds.get(this.localEdits[0].id) ?? fail('edit not found');\n\t\t\tassert(firstLocal.isLocal, 0x60b /* local edit should be local */);\n\t\t\treturn (\n\t\t\t\tthis._earliestAvailableEditIndex +\n\t\t\t\tthis.numberOfSequencedEdits +\n\t\t\t\torderedEdit.localSequence -\n\t\t\t\tfirstLocal.localSequence\n\t\t\t);\n\t\t}\n\t\treturn orderedEdit.index;\n\t}\n\n\t/**\n\t * @returns Edit metadata for the edit with the given `editId`.\n\t */\n\tpublic getOrderedEditId(editId: EditId): OrderedEditId {\n\t\treturn this.allEditIds.get(editId) ?? fail('All edits should exist in this map');\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.getIndexOfId}\n\t */\n\tpublic getIndexOfId(editId: EditId): number {\n\t\treturn this.tryGetIndexOfId(editId) ?? fail('edit not found');\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.getIdAtIndex}\n\t */\n\tpublic getIdAtIndex(index: number): EditId {\n\t\tif (this._earliestAvailableEditIndex + this.numberOfSequencedEdits <= index) {\n\t\t\treturn this.localEdits[index - this.numberOfSequencedEdits].id;\n\t\t}\n\n\t\treturn this.sequencedEdits[index - this._earliestAvailableEditIndex].id;\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.tryGetEditAtIndex}\n\t */\n\tpublic tryGetEditAtIndex(index: number): Edit<TChange> | undefined {\n\t\tif (this._earliestAvailableEditIndex + this.numberOfSequencedEdits <= index) {\n\t\t\treturn this.localEdits[index - this.numberOfSequencedEdits];\n\t\t}\n\n\t\treturn this.sequencedEdits[index - this._earliestAvailableEditIndex];\n\t}\n\n\t/**\n\t * {@inheritDoc OrderedEditSet.tryGetEditFromId}\n\t */\n\tpublic tryGetEditFromId(editId: EditId): Edit<TChange> | undefined {\n\t\tconst index = this.tryGetIndexOfId(editId);\n\t\treturn index !== undefined ? this.tryGetEditAtIndex(index) : undefined;\n\t}\n\n\t/**\n\t * Sequences all local edits.\n\t */\n\tpublic sequenceLocalEdits(): void {\n\t\tthis.localEdits.slice().forEach((edit) => this.addSequencedEditInternal(edit));\n\t}\n\n\t/**\n\t * Adds a sequenced (non-local) edit to the edit log.\n\t * If the id of the supplied edit matches a local edit already present in the log, the local edit will be replaced.\n\t *\n\t */\n\tpublic addSequencedEdit(edit: Edit<TChange>, message: MessageSequencingInfo): void {\n\t\tthis.addSequencedEditInternal(edit, message, message.minimumSequenceNumber);\n\t}\n\n\t/**\n\t * Returns all local edits from this EditLog\n\t * This is useful for op format upgrades, which might warrant re-submission of these ops using the new format.\n\t * See the breaking change documentation for more information.\n\t */\n\tpublic *getLocalEdits(): Iterable<Edit<TChange>> {\n\t\tfor (const edit of this.localEdits) {\n\t\t\tyield edit;\n\t\t}\n\t}\n\n\t/**\n\t * Adds a sequenced (non-local) edit to the edit log.\n\t * If the id of the supplied edit matches a local edit already present in the log, the local edit will be replaced.\n\t */\n\tprivate addSequencedEditInternal(\n\t\tedit: Edit<TChange>,\n\t\tinfo?: EditSequencingInfo,\n\t\tminSequenceNumber: number = 0\n\t): void {\n\t\tassert(\n\t\t\tminSequenceNumber >= this._minSequenceNumber,\n\t\t\t0x60c /* Sequenced edits should carry a monotonically increasing min number */\n\t\t);\n\t\tthis._minSequenceNumber = minSequenceNumber;\n\n\t\tconst { id } = edit;\n\t\t// The index of the sequenced edit to add\n\t\tconst index = this._earliestAvailableEditIndex + this.numberOfSequencedEdits;\n\n\t\t// Remove the edit from local edits if it exists.\n\t\tconst encounteredEditId = this.allEditIds.get(id);\n\t\tif (encounteredEditId !== undefined) {\n\t\t\t// New edit already exits: it must have been a local edit.\n\t\t\tassert(encounteredEditId.isLocal, 0x60d /* Duplicate acked edit. */);\n\t\t\t// Remove it from localEdits. Due to ordering requirements, it must be first.\n\t\t\tconst oldLocalEditId = this.localEdits.shift()?.id ?? fail('Local edit should exist');\n\t\t\tassert(oldLocalEditId === id, 0x60e /* Causal ordering should be upheld */);\n\t\t}\n\n\t\tthis.sequencedEdits.push(edit);\n\n\t\tconst sequencedEditId: SequencedOrderedEditId = {\n\t\t\tindex,\n\t\t\tisLocal: false,\n\t\t\tsequenceInfo: info,\n\t\t};\n\t\tthis.allEditIds.set(id, sequencedEditId);\n\t\tif (info !== undefined) {\n\t\t\tthis.sequenceNumberToIndex?.set(info.sequenceNumber, index);\n\t\t}\n\t\tthis.emitAdd(edit, false, encounteredEditId !== undefined);\n\n\t\t// Check if any edits need to be evicted due to this addition\n\t\tif (this.sequenceNumberToIndex !== undefined && this.numberOfSequencedEdits >= this.evictionFrequency) {\n\t\t\tthis.evictEdits();\n\t\t}\n\t}\n\n\t/**\n\t * Adds a non-sequenced (local) edit to the edit log.\n\t * Duplicate edits are ignored.\n\t */\n\tpublic addLocalEdit(edit: Edit<TChange>): void {\n\t\tthis.localEdits.push(edit);\n\t\tconst localEditId: LocalOrderedEditId = {\n\t\t\tlocalSequence: this.localEditSequence++,\n\t\t\tisLocal: true,\n\t\t};\n\t\tthis.allEditIds.set(edit.id, localEditId);\n\t\tthis.emitAdd(edit, true, false);\n\t}\n\n\tprivate emitAdd(editAdded: Edit<TChange>, isLocal: boolean, wasLocal: boolean): void {\n\t\tfor (const handler of this._editAddedHandlers) {\n\t\t\thandler(editAdded, isLocal, wasLocal);\n\t\t}\n\t}\n\n\tprivate evictEdits(): void {\n\t\tassert(\n\t\t\tthis.sequenceNumberToIndex !== undefined,\n\t\t\t0x60f /* Edits should never be evicted if the target length is set to infinity */\n\t\t);\n\n\t\tconst minSequenceIndex =\n\t\t\tthis.sequenceNumberToIndex.getPairOrNextHigher(this._minSequenceNumber)?.[1] ??\n\t\t\tfail('No index associated with that sequence number.');\n\t\t// Exclude any edits in the collab window from being evicted\n\t\tconst numberOfEvictableEdits = minSequenceIndex - this.earliestAvailableEditIndex;\n\n\t\tif (numberOfEvictableEdits > 0) {\n\t\t\t// Evict either all but the target log size or the number of evictable edits, whichever is smaller\n\t\t\tconst numberOfDesiredEditsToEvict = this.numberOfSequencedEdits - this.targetLength;\n\t\t\tconst numberOfEditsToEvict = Math.min(numberOfEvictableEdits, numberOfDesiredEditsToEvict);\n\t\t\tfor (const handler of this._editEvictionHandlers) {\n\t\t\t\thandler(numberOfEditsToEvict);\n\t\t\t}\n\n\t\t\t// Remove the edits and move up the earliest available index\n\t\t\tconst removedEdits = this.sequencedEdits.splice(0, numberOfEditsToEvict);\n\t\t\tthis._earliestAvailableEditIndex += numberOfEditsToEvict;\n\n\t\t\t// On eviction, we need to remove the IDs of edits that have been evicted\n\t\t\tremovedEdits.forEach((edit) => this.allEditIds.delete(edit.id));\n\n\t\t\t// The minSequenceNumber is strictly increasing so we can clear sequence numbers before it\n\t\t\tthis.sequenceNumberToIndex.deleteRange(0, this._minSequenceNumber, false);\n\t\t}\n\t}\n\n\t/**\n\t * @returns true iff this `EditLog` and `other` are equivalent, regardless of locality.\n\t */\n\tpublic equals<TOtherChangeTypesInternal>(other: EditLog<TOtherChangeTypesInternal>): boolean {\n\t\t// TODO #45414: We should also be deep comparing the list of changes in the edit. This is not straightforward.\n\t\t// We can use our edit validation code when we write it since it will need to do deep walks of the changes.\n\t\treturn compareArrays(this.editIds, other.editIds);\n\t}\n\n\t/**\n\t * @returns the summary of this `OrderedEditSet` that can be used to reconstruct the edit set.\n\t */\n\tpublic getEditLogSummary(): EditLogSummary<TChange, FluidEditHandle>;\n\n\t/**\n\t * @param compressEdit - a function which compresses edits\n\t * @returns the summary of this `OrderedEditSet` that can be used to reconstruct the edit set.\n\t */\n\tpublic getEditLogSummary<TCompressedChange>(\n\t\tcompressEdit: (edit: Pick<Edit<TChange>, 'changes'>) => Pick<Edit<TCompressedChange>, 'changes'>\n\t): EditLogSummary<TCompressedChange, FluidEditHandle>;\n\tpublic getEditLogSummary<TCompressedChange>(\n\t\tcompressEdit?: (edit: Pick<Edit<TChange>, 'changes'>) => Pick<Edit<TCompressedChange>, 'changes'>\n\t): EditLogSummary<TChange, FluidEditHandle> | EditLogSummary<TCompressedChange, FluidEditHandle> {\n\t\tconst editIds = this.sequencedEdits.map(({ id }) => id);\n\t\treturn compressEdit !== undefined\n\t\t\t? {\n\t\t\t\t\teditChunks:\n\t\t\t\t\t\tthis.sequencedEdits.length === 0\n\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t// Store all edits within a single \"chunk\"\n\t\t\t\t\t\t\t\t\t\tstartRevision: 0,\n\t\t\t\t\t\t\t\t\t\tchunk: this.sequencedEdits.map((edit) => compressEdit(edit)),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\teditIds,\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\teditChunks:\n\t\t\t\t\t\tthis.sequencedEdits.length === 0\n\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t// Store all edits within a single \"chunk\"\n\t\t\t\t\t\t\t\t\t\tstartRevision: 0,\n\t\t\t\t\t\t\t\t\t\tchunk: this.sequencedEdits.map(({ changes }) => ({ changes })),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\teditIds,\n\t\t\t\t};\n\t}\n\n\t// APIS DEPRECATED DUE TO HISTORY'S PEACEFUL DEATH\n\t/**\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\tpublic async tryGetEdit(editId: EditId): Promise<Edit<TChange> | undefined> {\n\t\tconst index = this.tryGetIndexOfId(editId);\n\t\treturn index !== undefined ? this.tryGetEditAtIndex(index) : undefined;\n\t}\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported. Don't use the asynchronous APIs. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\tpublic async getEditAtIndex(index: number): Promise<Edit<TChange>> {\n\t\treturn this.tryGetEditAtIndex(index) ?? fail('Edit not found');\n\t}\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported. Instead, use {@link OrderedEditSet.tryGetEditFromId}.\n\t */\n\tpublic getEditInSessionAtIndex(index: number): Edit<TChange> {\n\t\treturn this.tryGetEditAtIndex(index) ?? fail('Edit not found');\n\t}\n}\n"]}
|
|
@@ -31,7 +31,7 @@ export declare class MigrationShimDeltaHandler implements IShimDeltaHandler {
|
|
|
31
31
|
isUsingOldV1(): boolean;
|
|
32
32
|
isUsingNewV2(): boolean;
|
|
33
33
|
attachTreeDeltaHandler(treeDeltaHandler: IDeltaHandler): void;
|
|
34
|
-
process
|
|
34
|
+
private process;
|
|
35
35
|
processMessages(messagesCollection: IRuntimeMessageCollection): void;
|
|
36
36
|
setConnectionState(connected: boolean): void;
|
|
37
37
|
reSubmit(contents: unknown, localOpMetadata: unknown): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrationDeltaHandler.d.ts","sourceRoot":"","sources":["../../src/migration-shim/migrationDeltaHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAC7G,OAAO,EAAe,KAAK,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAC1G,OAAO,KAAK,EAAE,yBAAyB,
|
|
1
|
+
{"version":3,"file":"migrationDeltaHandler.d.ts","sourceRoot":"","sources":["../../src/migration-shim/migrationDeltaHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAC7G,OAAO,EAAe,KAAK,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAC1G,OAAO,KAAK,EAAE,yBAAyB,EAA2B,MAAM,8CAA8C,CAAC;AAEvH,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGtE;;;;;;;;GAQG;AACH,qBAAa,yBAA0B,YAAW,iBAAiB;aAKjD,gBAAgB,EAAE,CACjC,OAAO,EAAE,yBAAyB,EAClC,KAAK,EAAE,OAAO,EACd,eAAe,EAAE,OAAO,KACpB,OAAO;IACZ,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAV5B,OAAO,CAAC,iBAAiB,CAAC,CAAgB;IAC1C,OAAO,CAAC,cAAc,CAAC,CAAgB;gBAGtB,gBAAgB,EAAE,CACjC,OAAO,EAAE,yBAAyB,EAClC,KAAK,EAAE,OAAO,EACd,eAAe,EAAE,OAAO,KACpB,OAAO,EACK,kBAAkB,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,EAClD,UAAU,EAAE,kBAAkB;IAGzC,mBAAmB,IAAI,OAAO;IAIrC,OAAO,KAAK,gBAAgB,GAI3B;IAED,OAAO,CAAC,SAAS,CAAS;IAC1B,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAEM,YAAY,IAAI,IAAI;IAIpB,gBAAgB,IAAI,OAAO;IAM3B,YAAY,IAAI,OAAO;IAIvB,YAAY,IAAI,OAAO;IAOvB,sBAAsB,CAAC,gBAAgB,EAAE,aAAa,GAAG,IAAI;IAWpE,OAAO,CAAC,OAAO;IA2BR,eAAe,CAAC,kBAAkB,EAAE,yBAAyB,GAAG,IAAI;IAOpE,kBAAkB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAI5C,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;IAa3D,cAAc,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAcvC,QAAQ,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;IAQnE,OAAO,CAAC,yBAAyB;IAIjC;;;;;OAKG;IACH,OAAO,CAAC,YAAY;CAmBpB"}
|
|
@@ -76,8 +76,15 @@ export class MigrationShimDeltaHandler {
|
|
|
76
76
|
if (this.shouldDropOp(contents)) {
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
|
+
const messagesContent = [
|
|
80
|
+
{
|
|
81
|
+
contents,
|
|
82
|
+
localOpMetadata,
|
|
83
|
+
clientSequenceNumber: message.clientSequenceNumber,
|
|
84
|
+
},
|
|
85
|
+
];
|
|
79
86
|
// Another thought, flatten the IShimDeltaHandler and the MigrationShim into one class
|
|
80
|
-
return this.treeDeltaHandler.
|
|
87
|
+
return this.treeDeltaHandler.processMessages({ envelope: message, messagesContent, local });
|
|
81
88
|
}
|
|
82
89
|
processMessages(messagesCollection) {
|
|
83
90
|
const { envelope, messagesContent, local } = messagesCollection;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrationDeltaHandler.js","sourceRoot":"","sources":["../../src/migration-shim/migrationDeltaHandler.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from '@fluidframework/core-utils/internal';\nimport { type IChannelAttributes, type IDeltaHandler } from '@fluidframework/datastore-definitions/internal';\nimport { MessageType, type ISequencedDocumentMessage } from '@fluidframework/driver-definitions/internal';\nimport type { IRuntimeMessageCollection } from '@fluidframework/runtime-definitions/internal';\n\nimport { type IOpContents, type IShimDeltaHandler } from './types.js';\nimport { attributesMatch, isBarrierOp, isStampedOp } from './utils.js';\n\n/**\n * Handles incoming and outgoing deltas/ops for the Migration Shim distributed data structure.\n * Intercepts processing of ops to allow for migration, and swapping from LegacySharedTree to new SharedTree\n *\n * Able to process v1 and v2 ops, differentiate between them, understand the various states and drop v1 ops after\n * migration.\n *\n * TODO: After the MSN of the barrier op, it needs to process v2 ops without needing to check for the v2 stamp.\n */\nexport class MigrationShimDeltaHandler implements IShimDeltaHandler {\n\tprivate legacyTreeHandler?: IDeltaHandler;\n\tprivate newTreeHandler?: IDeltaHandler;\n\tpublic constructor(\n\t\t// Maybe it would be better to pass in a different interface?\n\t\tpublic readonly processMigrateOp: (\n\t\t\tmessage: ISequencedDocumentMessage,\n\t\t\tlocal: boolean,\n\t\t\tlocalOpMetadata: unknown\n\t\t) => boolean,\n\t\tprivate readonly submitLocalMessage: (message: IOpContents) => void,\n\t\tprivate readonly attributes: IChannelAttributes\n\t) {}\n\t// Introduction of invariant, we always expect an old handler.\n\tpublic hasTreeDeltaHandler(): boolean {\n\t\treturn this.legacyTreeHandler !== undefined;\n\t}\n\n\tprivate get treeDeltaHandler(): IDeltaHandler {\n\t\tconst handler = this.newTreeHandler ?? this.legacyTreeHandler;\n\t\tassert(handler !== undefined, 0x7e2 /* No handler to process op */);\n\t\treturn handler;\n\t}\n\n\tprivate _attached = false;\n\tpublic get attached(): boolean {\n\t\treturn this._attached;\n\t}\n\n\tpublic markAttached(): void {\n\t\tthis._attached = true;\n\t}\n\n\tpublic isPreAttachState(): boolean {\n\t\tconst preAttach = this.legacyTreeHandler === undefined && this.newTreeHandler === undefined;\n\t\tassert(!preAttach || !this.attached, 0x82a /* Should not be attached in preAttach state */);\n\t\treturn preAttach;\n\t}\n\n\tpublic isUsingOldV1(): boolean {\n\t\treturn this.legacyTreeHandler !== undefined && this.newTreeHandler === undefined;\n\t}\n\n\tpublic isUsingNewV2(): boolean {\n\t\tconst isUsingV2 = this.legacyTreeHandler !== undefined && this.newTreeHandler !== undefined;\n\t\tassert(!isUsingV2 || this.attached, 0x82b /* Should be attached if in v2 state */);\n\t\treturn isUsingV2;\n\t}\n\n\t// Allow for the handler to be swapped out for the new SharedTree's handler\n\tpublic attachTreeDeltaHandler(treeDeltaHandler: IDeltaHandler): void {\n\t\tassert(!this.isUsingNewV2(), 0x7e3 /* Can't swap tree handlers more than once! */);\n\t\tif (this.isPreAttachState()) {\n\t\t\tthis.legacyTreeHandler = treeDeltaHandler;\n\t\t\treturn;\n\t\t}\n\t\tassert(this.isUsingOldV1(), 0x7e4 /* Can only swap handlers after the old handler is loaded */);\n\t\tthis.newTreeHandler = treeDeltaHandler;\n\t\tassert(this.isUsingNewV2(), 0x7e5 /* Should be using new handler after swap */);\n\t}\n\n\tpublic process(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void {\n\t\t// This allows us to process the migrate op and prevent the shared object from processing the wrong ops\n\t\tassert(!this.isPreAttachState(), 0x82c /* Can't process ops before attaching tree handler */);\n\t\tif (message.type !== MessageType.Operation) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst contents = message.contents as IOpContents;\n\t\tif (this.isInV1StateAndIsBarrierOp(contents)) {\n\t\t\tthis.processMigrateOp(message, local, localOpMetadata);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.shouldDropOp(contents)) {\n\t\t\treturn;\n\t\t}\n\t\t// Another thought, flatten the IShimDeltaHandler and the MigrationShim into one class\n\t\treturn this.treeDeltaHandler.process(message, local, localOpMetadata);\n\t}\n\n\tpublic processMessages(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, messagesContent, local } = messagesCollection;\n\t\tfor (const { contents, localOpMetadata, clientSequenceNumber } of messagesContent) {\n\t\t\tthis.process({ ...envelope, contents, clientSequenceNumber }, local, localOpMetadata);\n\t\t}\n\t}\n\n\tpublic setConnectionState(connected: boolean): void {\n\t\treturn this.treeDeltaHandler.setConnectionState(connected);\n\t}\n\n\tpublic reSubmit(contents: unknown, localOpMetadata: unknown): void {\n\t\tconst opContents = contents as IOpContents;\n\t\tif (this.isInV1StateAndIsBarrierOp(opContents)) {\n\t\t\tthis.submitLocalMessage(opContents);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.shouldDropOp(opContents)) {\n\t\t\treturn;\n\t\t}\n\t\treturn this.treeDeltaHandler.reSubmit(contents, localOpMetadata);\n\t}\n\n\tpublic applyStashedOp(contents: unknown): void {\n\t\tconst opContents = contents as IOpContents;\n\t\tif (this.isInV1StateAndIsBarrierOp(opContents)) {\n\t\t\tthis.submitLocalMessage(opContents);\n\t\t\treturn;\n\t\t}\n\n\t\tassert(\n\t\t\t!this.shouldDropOp(opContents),\n\t\t\t0x8aa /* MigrationShim should not be able to apply v1 ops as they shouldn't have been created locally. */\n\t\t);\n\t\tthis.treeDeltaHandler.applyStashedOp(contents);\n\t}\n\n\tpublic rollback?(contents: unknown, localOpMetadata: unknown): void {\n\t\tconst opContents = contents as IOpContents;\n\t\tif (isBarrierOp(opContents)) {\n\t\t\tthrow new Error('MigrationShim does not support rollback of barrier ops');\n\t\t}\n\t\treturn this.treeDeltaHandler.rollback?.(contents, localOpMetadata);\n\t}\n\n\tprivate isInV1StateAndIsBarrierOp(contents: IOpContents): boolean {\n\t\treturn this.isUsingOldV1() && isBarrierOp(contents);\n\t}\n\n\t/**\n\t * We should drop an op when we are v2 state and the op is a v1 op or a migrate op.\n\t *\n\t * @param contents - op contents we expect to interrogate, this could be anything\n\t * @returns whether or not we should drop the op\n\t */\n\tprivate shouldDropOp(contents: IOpContents): boolean {\n\t\tassert(!this.isPreAttachState(), 0x82d /* Can't process ops before attaching tree handler */);\n\t\t// Don't drop ops when we are in v1 state\n\t\tif (this.isUsingOldV1()) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Drop v1 ops when in v2 state\n\t\tif (!isStampedOp(contents)) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Don't drop v2 ops in v2 state\n\t\tassert(\n\t\t\tattributesMatch(contents.fluidMigrationStamp, this.attributes),\n\t\t\t0x82e /* Unexpected v2 op with mismatched attributes */\n\t\t);\n\t\treturn false;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"migrationDeltaHandler.js","sourceRoot":"","sources":["../../src/migration-shim/migrationDeltaHandler.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from '@fluidframework/core-utils/internal';\nimport { type IChannelAttributes, type IDeltaHandler } from '@fluidframework/datastore-definitions/internal';\nimport { MessageType, type ISequencedDocumentMessage } from '@fluidframework/driver-definitions/internal';\nimport type { IRuntimeMessageCollection, IRuntimeMessagesContent } from '@fluidframework/runtime-definitions/internal';\n\nimport { type IOpContents, type IShimDeltaHandler } from './types.js';\nimport { attributesMatch, isBarrierOp, isStampedOp } from './utils.js';\n\n/**\n * Handles incoming and outgoing deltas/ops for the Migration Shim distributed data structure.\n * Intercepts processing of ops to allow for migration, and swapping from LegacySharedTree to new SharedTree\n *\n * Able to process v1 and v2 ops, differentiate between them, understand the various states and drop v1 ops after\n * migration.\n *\n * TODO: After the MSN of the barrier op, it needs to process v2 ops without needing to check for the v2 stamp.\n */\nexport class MigrationShimDeltaHandler implements IShimDeltaHandler {\n\tprivate legacyTreeHandler?: IDeltaHandler;\n\tprivate newTreeHandler?: IDeltaHandler;\n\tpublic constructor(\n\t\t// Maybe it would be better to pass in a different interface?\n\t\tpublic readonly processMigrateOp: (\n\t\t\tmessage: ISequencedDocumentMessage,\n\t\t\tlocal: boolean,\n\t\t\tlocalOpMetadata: unknown\n\t\t) => boolean,\n\t\tprivate readonly submitLocalMessage: (message: IOpContents) => void,\n\t\tprivate readonly attributes: IChannelAttributes\n\t) {}\n\t// Introduction of invariant, we always expect an old handler.\n\tpublic hasTreeDeltaHandler(): boolean {\n\t\treturn this.legacyTreeHandler !== undefined;\n\t}\n\n\tprivate get treeDeltaHandler(): IDeltaHandler {\n\t\tconst handler = this.newTreeHandler ?? this.legacyTreeHandler;\n\t\tassert(handler !== undefined, 0x7e2 /* No handler to process op */);\n\t\treturn handler;\n\t}\n\n\tprivate _attached = false;\n\tpublic get attached(): boolean {\n\t\treturn this._attached;\n\t}\n\n\tpublic markAttached(): void {\n\t\tthis._attached = true;\n\t}\n\n\tpublic isPreAttachState(): boolean {\n\t\tconst preAttach = this.legacyTreeHandler === undefined && this.newTreeHandler === undefined;\n\t\tassert(!preAttach || !this.attached, 0x82a /* Should not be attached in preAttach state */);\n\t\treturn preAttach;\n\t}\n\n\tpublic isUsingOldV1(): boolean {\n\t\treturn this.legacyTreeHandler !== undefined && this.newTreeHandler === undefined;\n\t}\n\n\tpublic isUsingNewV2(): boolean {\n\t\tconst isUsingV2 = this.legacyTreeHandler !== undefined && this.newTreeHandler !== undefined;\n\t\tassert(!isUsingV2 || this.attached, 0x82b /* Should be attached if in v2 state */);\n\t\treturn isUsingV2;\n\t}\n\n\t// Allow for the handler to be swapped out for the new SharedTree's handler\n\tpublic attachTreeDeltaHandler(treeDeltaHandler: IDeltaHandler): void {\n\t\tassert(!this.isUsingNewV2(), 0x7e3 /* Can't swap tree handlers more than once! */);\n\t\tif (this.isPreAttachState()) {\n\t\t\tthis.legacyTreeHandler = treeDeltaHandler;\n\t\t\treturn;\n\t\t}\n\t\tassert(this.isUsingOldV1(), 0x7e4 /* Can only swap handlers after the old handler is loaded */);\n\t\tthis.newTreeHandler = treeDeltaHandler;\n\t\tassert(this.isUsingNewV2(), 0x7e5 /* Should be using new handler after swap */);\n\t}\n\n\tprivate process(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void {\n\t\t// This allows us to process the migrate op and prevent the shared object from processing the wrong ops\n\t\tassert(!this.isPreAttachState(), 0x82c /* Can't process ops before attaching tree handler */);\n\t\tif (message.type !== MessageType.Operation) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst contents = message.contents as IOpContents;\n\t\tif (this.isInV1StateAndIsBarrierOp(contents)) {\n\t\t\tthis.processMigrateOp(message, local, localOpMetadata);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.shouldDropOp(contents)) {\n\t\t\treturn;\n\t\t}\n\t\tconst messagesContent: IRuntimeMessagesContent[] = [\n\t\t\t{\n\t\t\t\tcontents,\n\t\t\t\tlocalOpMetadata,\n\t\t\t\tclientSequenceNumber: message.clientSequenceNumber,\n\t\t\t},\n\t\t];\n\t\t// Another thought, flatten the IShimDeltaHandler and the MigrationShim into one class\n\t\treturn this.treeDeltaHandler.processMessages({ envelope: message, messagesContent, local });\n\t}\n\n\tpublic processMessages(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, messagesContent, local } = messagesCollection;\n\t\tfor (const { contents, localOpMetadata, clientSequenceNumber } of messagesContent) {\n\t\t\tthis.process({ ...envelope, contents, clientSequenceNumber }, local, localOpMetadata);\n\t\t}\n\t}\n\n\tpublic setConnectionState(connected: boolean): void {\n\t\treturn this.treeDeltaHandler.setConnectionState(connected);\n\t}\n\n\tpublic reSubmit(contents: unknown, localOpMetadata: unknown): void {\n\t\tconst opContents = contents as IOpContents;\n\t\tif (this.isInV1StateAndIsBarrierOp(opContents)) {\n\t\t\tthis.submitLocalMessage(opContents);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.shouldDropOp(opContents)) {\n\t\t\treturn;\n\t\t}\n\t\treturn this.treeDeltaHandler.reSubmit(contents, localOpMetadata);\n\t}\n\n\tpublic applyStashedOp(contents: unknown): void {\n\t\tconst opContents = contents as IOpContents;\n\t\tif (this.isInV1StateAndIsBarrierOp(opContents)) {\n\t\t\tthis.submitLocalMessage(opContents);\n\t\t\treturn;\n\t\t}\n\n\t\tassert(\n\t\t\t!this.shouldDropOp(opContents),\n\t\t\t0x8aa /* MigrationShim should not be able to apply v1 ops as they shouldn't have been created locally. */\n\t\t);\n\t\tthis.treeDeltaHandler.applyStashedOp(contents);\n\t}\n\n\tpublic rollback?(contents: unknown, localOpMetadata: unknown): void {\n\t\tconst opContents = contents as IOpContents;\n\t\tif (isBarrierOp(opContents)) {\n\t\t\tthrow new Error('MigrationShim does not support rollback of barrier ops');\n\t\t}\n\t\treturn this.treeDeltaHandler.rollback?.(contents, localOpMetadata);\n\t}\n\n\tprivate isInV1StateAndIsBarrierOp(contents: IOpContents): boolean {\n\t\treturn this.isUsingOldV1() && isBarrierOp(contents);\n\t}\n\n\t/**\n\t * We should drop an op when we are v2 state and the op is a v1 op or a migrate op.\n\t *\n\t * @param contents - op contents we expect to interrogate, this could be anything\n\t * @returns whether or not we should drop the op\n\t */\n\tprivate shouldDropOp(contents: IOpContents): boolean {\n\t\tassert(!this.isPreAttachState(), 0x82d /* Can't process ops before attaching tree handler */);\n\t\t// Don't drop ops when we are in v1 state\n\t\tif (this.isUsingOldV1()) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Drop v1 ops when in v2 state\n\t\tif (!isStampedOp(contents)) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Don't drop v2 ops in v2 state\n\t\tassert(\n\t\t\tattributesMatch(contents.fluidMigrationStamp, this.attributes),\n\t\t\t0x82e /* Unexpected v2 op with mismatched attributes */\n\t\t);\n\t\treturn false;\n\t}\n}\n"]}
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { type IChannelAttributes, type IDeltaHandler } from '@fluidframework/datastore-definitions/internal';
|
|
6
|
-
import { type ISequencedDocumentMessage } from '@fluidframework/driver-definitions/internal';
|
|
7
6
|
import type { IRuntimeMessageCollection } from '@fluidframework/runtime-definitions/internal';
|
|
8
7
|
import { type IShimDeltaHandler } from './types.js';
|
|
9
8
|
/**
|
|
@@ -25,7 +24,7 @@ export declare class SharedTreeShimDeltaHandler implements IShimDeltaHandler {
|
|
|
25
24
|
markAttached(): void;
|
|
26
25
|
attachTreeDeltaHandler(handler: IDeltaHandler): void;
|
|
27
26
|
hasTreeDeltaHandler(): boolean;
|
|
28
|
-
process
|
|
27
|
+
private process;
|
|
29
28
|
processMessages(messagesCollection: IRuntimeMessageCollection): void;
|
|
30
29
|
setConnectionState(connected: boolean): void;
|
|
31
30
|
reSubmit(contents: unknown, localOpMetadata: unknown): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharedTreeDeltaHandler.d.ts","sourceRoot":"","sources":["../../src/migration-shim/sharedTreeDeltaHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,gDAAgD,CAAC;
|
|
1
|
+
{"version":3,"file":"sharedTreeDeltaHandler.d.ts","sourceRoot":"","sources":["../../src/migration-shim/sharedTreeDeltaHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAE7G,OAAO,KAAK,EAAE,yBAAyB,EAA2B,MAAM,8CAA8C,CAAC;AAEvH,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGtE;;;;;;;;GAQG;AACH,qBAAa,0BAA2B,YAAW,iBAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,kBAAkB;IAElE,OAAO,CAAC,QAAQ,CAAC,CAAgB;IACjC,OAAO,KAAK,OAAO,GAIlB;IAED,OAAO,CAAC,SAAS,CAAS;IAC1B,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAEM,YAAY,IAAI,IAAI;IAIpB,sBAAsB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAKpD,mBAAmB,IAAI,OAAO;IAIrC,OAAO,CAAC,OAAO;IAsBR,eAAe,CAAC,kBAAkB,EAAE,yBAAyB,GAAG,IAAI;IAQpE,kBAAkB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAK5C,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;IAS3D,cAAc,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAQ9C;;;OAGG;IACI,QAAQ,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;IAQnE;;;;OAIG;IACH,OAAO,CAAC,YAAY;CAYpB"}
|
|
@@ -48,7 +48,14 @@ export class SharedTreeShimDeltaHandler {
|
|
|
48
48
|
if (this.shouldDropOp(contents)) {
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
const messagesContent = [
|
|
52
|
+
{
|
|
53
|
+
contents,
|
|
54
|
+
localOpMetadata,
|
|
55
|
+
clientSequenceNumber: message.clientSequenceNumber,
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
return this.handler.processMessages({ envelope: message, messagesContent, local });
|
|
52
59
|
}
|
|
53
60
|
processMessages(messagesCollection) {
|
|
54
61
|
const { envelope, messagesContent, local } = messagesCollection;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharedTreeDeltaHandler.js","sourceRoot":"","sources":["../../src/migration-shim/sharedTreeDeltaHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAE7D,OAAO,EAAE,WAAW,EAAkC,MAAM,6CAA6C,CAAC;AAI1G,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;;;;GAQG;AACH,MAAM,OAAO,0BAA0B;IACtC,YAAoC,UAA8B;QAA9B,eAAU,GAAV,UAAU,CAAoB;QAS1D,cAAS,GAAG,KAAK,CAAC;IAT2C,CAAC;IAGtE,IAAY,OAAO;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACpE,OAAO,OAAO,CAAC;IAChB,CAAC;IAGD,IAAW,QAAQ;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;IAEM,YAAY;QAClB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACvB,CAAC;IAEM,sBAAsB,CAAC,OAAsB;QACnD,MAAM,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,KAAK,CAAC,0CAA0C,CAAC,CAAC;QACtF,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IACzB,CAAC;IAEM,mBAAmB;QACzB,OAAO,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC;IACpC,CAAC;
|
|
1
|
+
{"version":3,"file":"sharedTreeDeltaHandler.js","sourceRoot":"","sources":["../../src/migration-shim/sharedTreeDeltaHandler.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from '@fluidframework/core-utils/internal';\nimport { type IChannelAttributes, type IDeltaHandler } from '@fluidframework/datastore-definitions/internal';\nimport { MessageType, type ISequencedDocumentMessage } from '@fluidframework/driver-definitions/internal';\nimport type { IRuntimeMessageCollection, IRuntimeMessagesContent } from '@fluidframework/runtime-definitions/internal';\n\nimport { type IOpContents, type IShimDeltaHandler } from './types.js';\nimport { attributesMatch, isStampedOp } from './utils.js';\n\n/**\n * Handles incoming and outgoing deltas/ops for the SharedTreeShim distributed data structure.\n * This serves as an adapter to the real DeltaHandler, filter/process migration ops\n *\n * This should just have the ability to drop v1 & migrate ops, and process v2 ops. There may be an opportunity to\n * combine this class with the MigrationShimDeltaHandler, but for now the classes are separated. Once it is clear what\n * exact code can be shared between the two classes is and how it can be merge, we may figure out a way of merging\n * MigrationShimDeltaHandler and SharedTreeShimDeltaHandler.\n */\nexport class SharedTreeShimDeltaHandler implements IShimDeltaHandler {\n\tpublic constructor(private readonly attributes: IChannelAttributes) {}\n\n\tprivate _handler?: IDeltaHandler;\n\tprivate get handler(): IDeltaHandler {\n\t\tconst handler = this._handler;\n\t\tassert(handler !== undefined, 0x7eb /* No handler to process op */);\n\t\treturn handler;\n\t}\n\n\tprivate _attached = false;\n\tpublic get attached(): boolean {\n\t\treturn this._attached;\n\t}\n\n\tpublic markAttached(): void {\n\t\tthis._attached = true;\n\t}\n\n\tpublic attachTreeDeltaHandler(handler: IDeltaHandler): void {\n\t\tassert(this._handler === undefined, 0x7ec /* Should only be able to connect once! */);\n\t\tthis._handler = handler;\n\t}\n\n\tpublic hasTreeDeltaHandler(): boolean {\n\t\treturn this._handler !== undefined;\n\t}\n\n\tprivate process(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void {\n\t\t// This allows us to process the migrate op and prevent the shared object from processing the wrong ops\n\t\t// Drop v1 ops\n\t\tassert(this.hasTreeDeltaHandler(), 0x831 /* Can't process ops before attaching tree handler */);\n\n\t\tif (message.type !== MessageType.Operation) {\n\t\t\treturn;\n\t\t}\n\t\tconst contents = message.contents as IOpContents;\n\t\tif (this.shouldDropOp(contents)) {\n\t\t\treturn;\n\t\t}\n\t\tconst messagesContent: IRuntimeMessagesContent[] = [\n\t\t\t{\n\t\t\t\tcontents,\n\t\t\t\tlocalOpMetadata,\n\t\t\t\tclientSequenceNumber: message.clientSequenceNumber,\n\t\t\t},\n\t\t];\n\t\treturn this.handler.processMessages({ envelope: message, messagesContent, local });\n\t}\n\n\tpublic processMessages(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, messagesContent, local } = messagesCollection;\n\t\tfor (const { contents, localOpMetadata, clientSequenceNumber } of messagesContent) {\n\t\t\tthis.process({ ...envelope, contents, clientSequenceNumber }, local, localOpMetadata);\n\t\t}\n\t}\n\n\t// No idea whether any of the below 4 methods work as expected\n\tpublic setConnectionState(connected: boolean): void {\n\t\treturn this.handler.setConnectionState(connected);\n\t}\n\n\t// Resubmitting v1 ops should fail. We should not be resubmitting v1 ops.\n\tpublic reSubmit(contents: unknown, localOpMetadata: unknown): void {\n\t\tassert(\n\t\t\t!this.shouldDropOp(contents as IOpContents),\n\t\t\t0x832 /* Should not be able to rollback v1 ops as they shouldn't have been created locally. */\n\t\t);\n\t\treturn this.handler.reSubmit(contents, localOpMetadata);\n\t}\n\n\t// We are not capable of applying stashed v1 ops.\n\tpublic applyStashedOp(contents: unknown): void {\n\t\tassert(\n\t\t\t!this.shouldDropOp(contents as IOpContents),\n\t\t\t0x8ab /* SharedTreeShim should not be able to apply v1 ops as they shouldn't have been created locally. */\n\t\t);\n\t\tthis.handler.applyStashedOp(contents);\n\t}\n\n\t/**\n\t * We cannot rollback v1 ops, we have already migrated and are in v2 state, thus we should not be able to generate.\n\t * v1 ops\n\t */\n\tpublic rollback?(contents: unknown, localOpMetadata: unknown): void {\n\t\tassert(\n\t\t\t!this.shouldDropOp(contents as IOpContents),\n\t\t\t0x833 /* Should not be able to rollback v1 ops as they shouldn't have been created locally. */\n\t\t);\n\t\treturn this.handler.rollback?.(contents, localOpMetadata);\n\t}\n\n\t/**\n\t * The SharedTreeShimDeltaHandler is already in a v2 state. Thus it should drop all v1 and migrate ops.\n\t * @param contents - the interrogable op contents to figure out if this is a v1 op, a migrate op, or a v2 op.\n\t * @returns whether or not the op is a v1 or migrate op and should be dropped/ignored.\n\t */\n\tprivate shouldDropOp(contents: IOpContents): boolean {\n\t\tif (!isStampedOp(contents)) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Don't drop v2 ops in v2 state\n\t\tassert(\n\t\t\tattributesMatch(contents.fluidMigrationStamp, this.attributes),\n\t\t\t0x834 /* Unexpected v2 op with mismatched attributes */\n\t\t);\n\t\treturn false;\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluid-experimental/tree",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.30.0",
|
|
4
4
|
"description": "Distributed tree",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -22,33 +22,23 @@
|
|
|
22
22
|
"types": "./dist/index.d.ts",
|
|
23
23
|
"default": "./dist/index.js"
|
|
24
24
|
}
|
|
25
|
-
},
|
|
26
|
-
"./test/EditLog": {
|
|
27
|
-
"import": {
|
|
28
|
-
"types": "./lib/EditLog.d.ts",
|
|
29
|
-
"default": "./lib/EditLog.js"
|
|
30
|
-
},
|
|
31
|
-
"require": {
|
|
32
|
-
"types": "./dist/EditLog.d.ts",
|
|
33
|
-
"default": "./dist/EditLog.js"
|
|
34
|
-
}
|
|
35
25
|
}
|
|
36
26
|
},
|
|
37
27
|
"main": "lib/index.js",
|
|
38
28
|
"types": "lib/index.d.ts",
|
|
39
29
|
"dependencies": {
|
|
40
|
-
"@fluid-internal/client-utils": "~2.
|
|
41
|
-
"@fluidframework/container-definitions": "~2.
|
|
42
|
-
"@fluidframework/core-interfaces": "~2.
|
|
43
|
-
"@fluidframework/core-utils": "~2.
|
|
44
|
-
"@fluidframework/datastore-definitions": "~2.
|
|
45
|
-
"@fluidframework/driver-definitions": "~2.
|
|
46
|
-
"@fluidframework/id-compressor": "~2.
|
|
47
|
-
"@fluidframework/runtime-definitions": "~2.
|
|
48
|
-
"@fluidframework/runtime-utils": "~2.
|
|
49
|
-
"@fluidframework/shared-object-base": "~2.
|
|
50
|
-
"@fluidframework/telemetry-utils": "~2.
|
|
51
|
-
"@fluidframework/tree": "~2.
|
|
30
|
+
"@fluid-internal/client-utils": "~2.30.0",
|
|
31
|
+
"@fluidframework/container-definitions": "~2.30.0",
|
|
32
|
+
"@fluidframework/core-interfaces": "~2.30.0",
|
|
33
|
+
"@fluidframework/core-utils": "~2.30.0",
|
|
34
|
+
"@fluidframework/datastore-definitions": "~2.30.0",
|
|
35
|
+
"@fluidframework/driver-definitions": "~2.30.0",
|
|
36
|
+
"@fluidframework/id-compressor": "~2.30.0",
|
|
37
|
+
"@fluidframework/runtime-definitions": "~2.30.0",
|
|
38
|
+
"@fluidframework/runtime-utils": "~2.30.0",
|
|
39
|
+
"@fluidframework/shared-object-base": "~2.30.0",
|
|
40
|
+
"@fluidframework/telemetry-utils": "~2.30.0",
|
|
41
|
+
"@fluidframework/tree": "~2.30.0",
|
|
52
42
|
"@tylerbu/sorted-btree-es6": "^1.8.0",
|
|
53
43
|
"buffer": "^6.0.3",
|
|
54
44
|
"denque": "^1.5.1",
|
|
@@ -58,20 +48,20 @@
|
|
|
58
48
|
"devDependencies": {
|
|
59
49
|
"@arethetypeswrong/cli": "^0.17.1",
|
|
60
50
|
"@biomejs/biome": "~1.9.3",
|
|
61
|
-
"@fluid-internal/mocha-test-setup": "~2.
|
|
62
|
-
"@fluid-private/stochastic-test-utils": "~2.
|
|
63
|
-
"@fluid-private/test-drivers": "~2.
|
|
51
|
+
"@fluid-internal/mocha-test-setup": "~2.30.0",
|
|
52
|
+
"@fluid-private/stochastic-test-utils": "~2.30.0",
|
|
53
|
+
"@fluid-private/test-drivers": "~2.30.0",
|
|
64
54
|
"@fluid-tools/benchmark": "^0.50.0",
|
|
65
55
|
"@fluidframework/build-common": "^2.0.3",
|
|
66
56
|
"@fluidframework/build-tools": "^0.54.0",
|
|
67
|
-
"@fluidframework/container-definitions": "~2.
|
|
68
|
-
"@fluidframework/container-loader": "~2.
|
|
69
|
-
"@fluidframework/container-runtime": "~2.
|
|
57
|
+
"@fluidframework/container-definitions": "~2.30.0",
|
|
58
|
+
"@fluidframework/container-loader": "~2.30.0",
|
|
59
|
+
"@fluidframework/container-runtime": "~2.30.0",
|
|
70
60
|
"@fluidframework/eslint-config-fluid": "^5.7.3",
|
|
71
|
-
"@fluidframework/runtime-utils": "~2.
|
|
72
|
-
"@fluidframework/test-runtime-utils": "~2.
|
|
73
|
-
"@fluidframework/test-utils": "~2.
|
|
74
|
-
"@fluidframework/undo-redo": "~2.
|
|
61
|
+
"@fluidframework/runtime-utils": "~2.30.0",
|
|
62
|
+
"@fluidframework/test-runtime-utils": "~2.30.0",
|
|
63
|
+
"@fluidframework/test-utils": "~2.30.0",
|
|
64
|
+
"@fluidframework/undo-redo": "~2.30.0",
|
|
75
65
|
"@microsoft/api-extractor": "7.47.8",
|
|
76
66
|
"@types/chai": "^4.0.0",
|
|
77
67
|
"@types/lru-cache": "^5.1.0",
|
|
@@ -86,7 +76,7 @@
|
|
|
86
76
|
"env-cmd": "^10.1.0",
|
|
87
77
|
"eslint": "~8.55.0",
|
|
88
78
|
"eslint-config-prettier": "~9.0.0",
|
|
89
|
-
"mocha": "^10.2
|
|
79
|
+
"mocha": "^10.8.2",
|
|
90
80
|
"mocha-multi-reporters": "^1.5.1",
|
|
91
81
|
"moment": "^2.21.0",
|
|
92
82
|
"prettier": "~3.0.3",
|
|
@@ -103,7 +93,7 @@
|
|
|
103
93
|
"build:compile": "fluid-build . --task compile",
|
|
104
94
|
"build:docs": "api-extractor run --local",
|
|
105
95
|
"build:esnext": "tsc --project ./tsconfig.esnext.json",
|
|
106
|
-
"check:are-the-types-wrong": "attw --pack .
|
|
96
|
+
"check:are-the-types-wrong": "attw --pack .",
|
|
107
97
|
"check:biome": "biome check .",
|
|
108
98
|
"check:exports": "concurrently \"npm:check:exports:*\"",
|
|
109
99
|
"check:exports:bundle-release-tags": "api-extractor run --config api-extractor/api-extractor-lint-bundle.json",
|
package/src/EditLog.ts
CHANGED
|
@@ -74,6 +74,11 @@ export interface OrderedEditSet<TChange = unknown> {
|
|
|
74
74
|
* @deprecated this will be removed in favor of {@link OrderedEditSet.tryGetEditAtIndex}
|
|
75
75
|
*/
|
|
76
76
|
getEditInSessionAtIndex(index: number): Edit<TChange>;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Gets all local edits.
|
|
80
|
+
*/
|
|
81
|
+
getLocalEdits(): Iterable<Edit<TChange>>;
|
|
77
82
|
}
|
|
78
83
|
|
|
79
84
|
/**
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { assert } from '@fluidframework/core-utils/internal';
|
|
7
7
|
import { type IChannelAttributes, type IDeltaHandler } from '@fluidframework/datastore-definitions/internal';
|
|
8
8
|
import { MessageType, type ISequencedDocumentMessage } from '@fluidframework/driver-definitions/internal';
|
|
9
|
-
import type { IRuntimeMessageCollection } from '@fluidframework/runtime-definitions/internal';
|
|
9
|
+
import type { IRuntimeMessageCollection, IRuntimeMessagesContent } from '@fluidframework/runtime-definitions/internal';
|
|
10
10
|
|
|
11
11
|
import { type IOpContents, type IShimDeltaHandler } from './types.js';
|
|
12
12
|
import { attributesMatch, isBarrierOp, isStampedOp } from './utils.js';
|
|
@@ -81,7 +81,7 @@ export class MigrationShimDeltaHandler implements IShimDeltaHandler {
|
|
|
81
81
|
assert(this.isUsingNewV2(), 0x7e5 /* Should be using new handler after swap */);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
private process(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void {
|
|
85
85
|
// This allows us to process the migrate op and prevent the shared object from processing the wrong ops
|
|
86
86
|
assert(!this.isPreAttachState(), 0x82c /* Can't process ops before attaching tree handler */);
|
|
87
87
|
if (message.type !== MessageType.Operation) {
|
|
@@ -97,8 +97,15 @@ export class MigrationShimDeltaHandler implements IShimDeltaHandler {
|
|
|
97
97
|
if (this.shouldDropOp(contents)) {
|
|
98
98
|
return;
|
|
99
99
|
}
|
|
100
|
+
const messagesContent: IRuntimeMessagesContent[] = [
|
|
101
|
+
{
|
|
102
|
+
contents,
|
|
103
|
+
localOpMetadata,
|
|
104
|
+
clientSequenceNumber: message.clientSequenceNumber,
|
|
105
|
+
},
|
|
106
|
+
];
|
|
100
107
|
// Another thought, flatten the IShimDeltaHandler and the MigrationShim into one class
|
|
101
|
-
return this.treeDeltaHandler.
|
|
108
|
+
return this.treeDeltaHandler.processMessages({ envelope: message, messagesContent, local });
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
public processMessages(messagesCollection: IRuntimeMessageCollection): void {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { assert } from '@fluidframework/core-utils/internal';
|
|
7
7
|
import { type IChannelAttributes, type IDeltaHandler } from '@fluidframework/datastore-definitions/internal';
|
|
8
8
|
import { MessageType, type ISequencedDocumentMessage } from '@fluidframework/driver-definitions/internal';
|
|
9
|
-
import type { IRuntimeMessageCollection } from '@fluidframework/runtime-definitions/internal';
|
|
9
|
+
import type { IRuntimeMessageCollection, IRuntimeMessagesContent } from '@fluidframework/runtime-definitions/internal';
|
|
10
10
|
|
|
11
11
|
import { type IOpContents, type IShimDeltaHandler } from './types.js';
|
|
12
12
|
import { attributesMatch, isStampedOp } from './utils.js';
|
|
@@ -48,7 +48,7 @@ export class SharedTreeShimDeltaHandler implements IShimDeltaHandler {
|
|
|
48
48
|
return this._handler !== undefined;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
private process(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void {
|
|
52
52
|
// This allows us to process the migrate op and prevent the shared object from processing the wrong ops
|
|
53
53
|
// Drop v1 ops
|
|
54
54
|
assert(this.hasTreeDeltaHandler(), 0x831 /* Can't process ops before attaching tree handler */);
|
|
@@ -60,7 +60,14 @@ export class SharedTreeShimDeltaHandler implements IShimDeltaHandler {
|
|
|
60
60
|
if (this.shouldDropOp(contents)) {
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
63
|
-
|
|
63
|
+
const messagesContent: IRuntimeMessagesContent[] = [
|
|
64
|
+
{
|
|
65
|
+
contents,
|
|
66
|
+
localOpMetadata,
|
|
67
|
+
clientSequenceNumber: message.clientSequenceNumber,
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
return this.handler.processMessages({ envelope: message, messagesContent, local });
|
|
64
71
|
}
|
|
65
72
|
|
|
66
73
|
public processMessages(messagesCollection: IRuntimeMessageCollection): void {
|