@fluidframework/test-utils 2.0.0-internal.1.2.0.93071 → 2.0.0-internal.1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/loaderContainerTracker.d.ts +16 -8
- package/dist/loaderContainerTracker.d.ts.map +1 -1
- package/dist/loaderContainerTracker.js +16 -8
- package/dist/loaderContainerTracker.js.map +1 -1
- package/dist/localCodeLoader.d.ts.map +1 -1
- package/dist/localCodeLoader.js +6 -14
- package/dist/localCodeLoader.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/testFluidObject.d.ts +16 -9
- package/dist/testFluidObject.d.ts.map +1 -1
- package/dist/testFluidObject.js +16 -9
- package/dist/testFluidObject.js.map +1 -1
- package/dist/testObjectProvider.d.ts.map +1 -1
- package/dist/testObjectProvider.js +3 -6
- package/dist/testObjectProvider.js.map +1 -1
- package/package.json +21 -21
- package/src/loaderContainerTracker.ts +17 -9
- package/src/localCodeLoader.ts +6 -14
- package/src/packageVersion.ts +1 -1
- package/src/testFluidObject.ts +16 -9
- package/src/testObjectProvider.ts +4 -6
|
@@ -43,14 +43,22 @@ export declare class LoaderContainerTracker implements IOpProcessingController {
|
|
|
43
43
|
ensureSynchronizedWithTimeout?(timeoutDuration: number | undefined, ...containers: IContainer[]): Promise<void>;
|
|
44
44
|
/**
|
|
45
45
|
* Make sure all the tracked containers are synchronized.
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* -
|
|
52
|
-
*
|
|
53
|
-
*
|
|
46
|
+
*
|
|
47
|
+
* No isDirty (non-readonly) containers
|
|
48
|
+
*
|
|
49
|
+
* No extra clientId in quorum of any container that is not tracked and still opened.
|
|
50
|
+
*
|
|
51
|
+
* - i.e. no pending Join/Leave message.
|
|
52
|
+
*
|
|
53
|
+
* No unresolved proposal (minSeqNum \>= lastProposalSeqNum)
|
|
54
|
+
*
|
|
55
|
+
* lastSequenceNumber of all container is the same
|
|
56
|
+
*
|
|
57
|
+
* clientSequenceNumberObserved is the same as clientSequenceNumber sent
|
|
58
|
+
*
|
|
59
|
+
* - this overlaps with !isDirty, but include task scheduler ops.
|
|
60
|
+
*
|
|
61
|
+
* - Trailing NoOp is tracked and don't count as pending ops.
|
|
54
62
|
*/
|
|
55
63
|
private processSynchronized;
|
|
56
64
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loaderContainerTracker.d.ts","sourceRoot":"","sources":["../src/loaderContainerTracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,UAAU,EAAe,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAK7F,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAyB/D,qBAAa,sBAAuB,YAAW,uBAAuB;IAItD,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IAHlD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0C;IACrE,OAAO,CAAC,kBAAkB,CAAa;gBAEV,qBAAqB,GAAE,OAAe;IAEnE;;;OAGG;IACI,GAAG,CAAC,UAAU,SAAS,WAAW,EAAE,MAAM,EAAE,UAAU;IAiB7D;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAoBpB;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAsC1B,OAAO,CAAC,iBAAiB;IAQzB;;OAEG;IACI,KAAK;IAUZ;;OAEG;IACU,kBAAkB,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE;
|
|
1
|
+
{"version":3,"file":"loaderContainerTracker.d.ts","sourceRoot":"","sources":["../src/loaderContainerTracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,UAAU,EAAe,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAK7F,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAyB/D,qBAAa,sBAAuB,YAAW,uBAAuB;IAItD,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IAHlD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0C;IACrE,OAAO,CAAC,kBAAkB,CAAa;gBAEV,qBAAqB,GAAE,OAAe;IAEnE;;;OAGG;IACI,GAAG,CAAC,UAAU,SAAS,WAAW,EAAE,MAAM,EAAE,UAAU;IAiB7D;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAoBpB;;;;;;OAMG;IACH,OAAO,CAAC,kBAAkB;IAsC1B,OAAO,CAAC,iBAAiB;IAQzB;;OAEG;IACI,KAAK;IAUZ;;OAEG;IACU,kBAAkB,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3E;;OAEG;IACU,6BAA6B,CAAC,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,UAAU,EAAE,UAAU,EAAE;IAI5G;;;;;;;;;;;;;;;;;;OAkBG;YACW,mBAAmB;IA0EjC;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;;;;OAKG;IACH,OAAO,CAAC,4BAA4B;IA0CpC;;;;;;;OAOG;YACW,qBAAqB;IA6BnC;;;OAGG;YACW,oBAAoB;IAclC;;OAEG;IACI,gBAAgB,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE;IAgBnD;;;OAGG;IACU,eAAe,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE;IAexD;;;;OAIG;IACU,eAAe,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE;IAIxD;;;;OAIG;IACU,eAAe,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE;IAIxD;;OAEG;YACW,YAAY;IAqC1B;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;OAEG;IACH,OAAO,CAAC,UAAU;IA8DlB;;;;OAIG;IACH,OAAO,CAAC,aAAa;CAIxB"}
|
|
@@ -141,14 +141,22 @@ class LoaderContainerTracker {
|
|
|
141
141
|
}
|
|
142
142
|
/**
|
|
143
143
|
* Make sure all the tracked containers are synchronized.
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
* -
|
|
150
|
-
*
|
|
151
|
-
*
|
|
144
|
+
*
|
|
145
|
+
* No isDirty (non-readonly) containers
|
|
146
|
+
*
|
|
147
|
+
* No extra clientId in quorum of any container that is not tracked and still opened.
|
|
148
|
+
*
|
|
149
|
+
* - i.e. no pending Join/Leave message.
|
|
150
|
+
*
|
|
151
|
+
* No unresolved proposal (minSeqNum \>= lastProposalSeqNum)
|
|
152
|
+
*
|
|
153
|
+
* lastSequenceNumber of all container is the same
|
|
154
|
+
*
|
|
155
|
+
* clientSequenceNumberObserved is the same as clientSequenceNumber sent
|
|
156
|
+
*
|
|
157
|
+
* - this overlaps with !isDirty, but include task scheduler ops.
|
|
158
|
+
*
|
|
159
|
+
* - Trailing NoOp is tracked and don't count as pending ops.
|
|
152
160
|
*/
|
|
153
161
|
async processSynchronized(timeoutDuration, ...containers) {
|
|
154
162
|
const start = Date.now();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loaderContainerTracker.js","sourceRoot":"","sources":["../src/loaderContainerTracker.ts"],"names":[],"mappings":";AAAA;;;GAGG;AACH,kEAAkE;;;AAElE,+DAAsD;AAGtD,+DAAuE;AACvE,+EAAgH;AAChH,mCAAgC;AAEhC,iDAA8D;AAE9D,MAAM,OAAO,GAAG,aAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACpC,MAAM,SAAS,GAAG,aAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAEvC,0CAA0C;AAC1C,MAAM,iBAAiB,GAAG,CAAC,GAAG,IAAI,CAAC;AAkBnC,MAAa,sBAAsB;IAI/B,YAA6B,wBAAiC,KAAK;QAAtC,0BAAqB,GAArB,qBAAqB,CAAiB;QAHlD,eAAU,GAAG,IAAI,GAAG,EAA+B,CAAC;QAC7D,uBAAkB,GAAW,CAAC,CAAC;IAE+B,CAAC;IAEvE;;;OAGG;IACI,GAAG,CAAiC,MAAkB;QACzD,oFAAoF;QACpF,MAAM,KAAK,GAAG,CAA0B,EAA2B,EAAE,EAAE;YACnE,MAAM,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAChC,OAAO,KAAK,EAAE,GAAG,IAAS,EAAE,EAAE;gBAC1B,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;gBACzC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;gBAC7B,OAAO,SAAS,CAAC;YACrB,CAAC,CAAC;QACN,CAAC,CAAC;QACF,sDAAsD;QACtD,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,CAAC,uBAAuB,GAAG,KAAK,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;QACvE,MAAM,CAAC,sCAAsC,GAAG,KAAK,CAAC,MAAM,CAAC,sCAAsC,CAAC,CAAC;QACrG,qDAAqD;IACzD,CAAC;IAED;;;;OAIG;IACK,YAAY,CAAC,SAAqB;QACtC,oBAAoB;QACpB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,aAAa,CAAC,YAAY,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE;YAAE,OAAO;SAAE;QAE9G,8CAA8C;QAC9C,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;YAAE,OAAO;SAAE;QAE/C,MAAM,MAAM,GAAG;YACX,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI;YAC3B,MAAM,EAAE,KAAK;YACb,kBAAkB,EAAE,CAAC;YACrB,aAAa,EAAE,CAAC;YAChB,YAAY,EAAE,CAAC;SAClB,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAClC,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED;;;;;;OAMG;IACK,kBAAkB,CAAC,SAAqB,EAAE,MAAuB;QACrE,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;YAClD,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE;gBACxB,IAAI,IAAA,sCAAuB,EAAC,GAAG,CAAC,EAAE;oBAC9B,gCAAgC;oBAChC,IAAI,MAAM,CAAC,aAAa,KAAK,CAAC,EAAE;wBAC5B,8FAA8F;wBAC9F,MAAM,CAAC,kBAAkB,GAAG,GAAG,CAAC,oBAAoB,CAAC;qBACxD;oBACD,MAAM,CAAC,aAAa,EAAE,CAAC;iBAC1B;qBAAM;oBACH,6FAA6F;oBAC7F,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;iBAC5B;aACJ;QACL,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE;YAClD,gEAAgE;YAChE,IAAI,IAAA,sCAAuB,EAAC,OAAO,CAAC;mBAC7B,OAAO,CAAC,QAAQ,KAAM,SAAuB,CAAC,QAAQ;mBACtD,MAAM,CAAC,aAAa,KAAK,CAAC;mBAC1B,MAAM,CAAC,kBAAkB,IAAI,OAAO,CAAC,oBAAoB,EAC9D;gBACE,mEAAmE;gBACnE,2CAA2C;gBAC3C,MAAM,qBAAqB,GAAG,MAAM,CAAC,kBAAkB,CAAC;gBACxD,MAAM,CAAC,kBAAkB,GAAG,OAAO,CAAC,oBAAoB,GAAG,CAAC,CAAC;gBAC7D,MAAM,CAAC,aAAa,IAAI,CAAC,MAAM,CAAC,kBAAkB,GAAG,qBAAqB,CAAC,CAAC;aAC/E;QACL,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;YAC9B,uBAAuB;YACvB,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,iBAAiB,CAAC,SAAqB;QAC3C,SAAS,CAAC,EAAE,CAAC,qBAAqB,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;YACpD,IAAI,QAAQ,CAAC,cAAc,GAAG,IAAI,CAAC,kBAAkB,EAAE;gBACnD,IAAI,CAAC,kBAAkB,GAAG,QAAQ,CAAC,cAAc,CAAC;aACrD;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACI,KAAK;QACR,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC;QAC5B,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE;YAC5C,SAAS,CAAC,KAAK,EAAE,CAAC;SACrB;QACD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAExB,6CAA6C;IACjD,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,kBAAkB,CAAC,GAAG,UAAwB;QACvD,MAAM,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,GAAG,UAAU,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,6BAA6B,CAAE,eAAmC,EAAE,GAAG,UAAwB;QACxG,MAAM,IAAI,CAAC,mBAAmB,CAAC,eAAe,EAAE,GAAG,UAAU,CAAC,CAAC;IACnE,CAAC;IAED;;;;;;;;;;OAUG;IACK,KAAK,CAAC,mBAAmB,CAAC,eAAmC,EAAE,GAAG,UAAwB;QAC9F,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,UAAU,CAAC,CAAC;QAErD,IAAI,iCAAiC,GAAG,KAAK,CAAC;QAC9C,iDAAiD;QACjD,OAAO,IAAI,EAAE;YACT,MAAM,iBAAiB,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;YACzD,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE;gBAAE,MAAM;aAAE;YAE9C,0GAA0G;YAC1G,MAAM,eAAe,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;gBACnD,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;gBACpC,OAAO,YAAY,CAAC,YAAY,CAAC,QAAQ,KAAK,IAAI,IAAI,OAAO,CAAC;YAClE,CAAC,CAAC,CAAC;YACH,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC9B,kCAAkC;gBAClC,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;gBACjE,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE;oBAC7B,IAAI,IAAI,CAAC,4BAA4B,CAAC,iBAAiB,CAAC,EAAE;wBACtD,uBAAuB;wBACvB,MAAM;qBACT;oBACD,IAAI,CAAC,iCAAiC,EAAE;wBACpC,yBAAyB;wBACzB,iCAAiC,GAAG,IAAI,CAAC;wBACzC,SAAS,CAAC,0CAA0C,CAAC,CAAC;wBACtD,MAAM,IAAA,2BAAY,EAAC,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE;4BAC7D,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,iBAAiB;4BACxF,QAAQ,EAAE,qDAAqD;yBAClE,CAAC,CAAC;qBACN;iBACJ;qBAAM;oBACH,iCAAiC,GAAG,KAAK,CAAC;oBAC1C,MAAM,IAAA,2BAAY,EAAC,IAAI,CAAC,qBAAqB,CAAC,cAAc,CAAC,EAAE;wBACvD,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,iBAAiB;wBAC5F,QAAQ,EAAE,iDAAiD;qBAC9D,CAAC,CAAC;iBACN;aACJ;iBAAM;gBACH,0CAA0C;gBAC1C,oEAAoE;gBACpE,SAAS,CAAC,iCAAiC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACxG,iCAAiC,GAAG,KAAK,CAAC;gBAC1C,MAAM,gBAAgB,GAAG,eAAe,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC;gBACtG,MAAM,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAC3D,CAAC,IAAA,6BAAc,EACX,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,EAC7C;wBACI,UAAU,EAAE,gBAAgB;wBAC5B,QAAQ,EAAE,4CAA4C;qBACzD,CACJ;oBACD,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;iBAClD,CACJ,CAAC,CAAC,CAAC;aACP;YAED,+FAA+F;YAC/F,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACrE;QAED,uCAAuC;QACvC,uFAAuF;QACvF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;YACtB,MAAM,IAAA,2BAAY,EAAC,IAAI,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,EAAE;gBACjD,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,iBAAiB;gBACxF,QAAQ,EAAE,uDAAuD;aACpE,CAAC,CAAC;SACN;QAED,SAAS,CAAC,cAAc,CAAC,CAAC;IAC9B,CAAC;IAED;;;;;OAKG;IACK,iBAAiB,CAAC,iBAA+B;QACrD,0FAA0F;QAC1F,iBAAiB;QACjB,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACpF,MAAM,cAAc,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAE,SAAuB,CAAC,QAAQ,CAAC,CAAC;QAE7F,MAAM,cAAc,GAAgC,EAAE,CAAC;QACvD,iBAAiB,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YACpC,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;YAC1C,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;YACrC,MAAM,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;gBAC7C,oBAAoB;gBACpB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE;oBAAE,OAAO;iBAAE;gBAC/F,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;oBACpC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;iBACjC;YACL,CAAC,CAAC,CAAC;YAEH,IAAI,eAAe,CAAC,IAAI,KAAK,CAAC,EAAE;gBAC5B,cAAc,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;aACrD;QACL,CAAC,CAAC,CAAC;QACH,OAAO,cAAc,CAAC;IAC1B,CAAC;IAED;;;;;OAKG;IACK,4BAA4B,CAAC,iBAA+B;QAChE,+FAA+F;QAC/F,iEAAiE;QACjE,uGAAuG;QACvG,iGAAiG;QACjG,qEAAqE;QAErE,MAAM,kCAAkC,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,EAAE;YAC7E,IAAI,SAAS,CAAC,YAAY,CAAC,YAAY,CAAC,QAAQ,KAAK,IAAI,EAAE;gBACvD,4FAA4F;gBAC5F,6FAA6F;gBAC7F,OAAO,IAAI,CAAC;aACf;YACD,yDAAyD;YACzD,IAAI,YAAY,GAAI,SAAS,CAAC,YAAoB,CAAC;YACnD,oEAAoE;YACpE,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC;YAC1D,sGAAsG;YACtG,IAAI,CAAC,CAAC,sBAAsB,IAAI,YAAY,CAAC,EAAE;gBAC3C,YAAY,GAAG,YAAY,CAAC,iBAAiB,CAAC;aACjD;YACD,IAAA,qBAAM,EAAC,sBAAsB,IAAI,YAAY,EAAE,yBAAyB,CAAC,CAAC;YAC1E,IAAA,qBAAM,EAAC,8BAA8B,IAAI,YAAY,EAAE,yBAAyB,CAAC,CAAC;YAClF,OAAO,YAAY,CAAC,oBAAoB;gBACnC,YAAY,CAAC,4BAAuC,GAAG,aAAa,CAAC;QAC9E,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,kCAAkC,EAAE;YACrC,OAAO,KAAK,CAAC;SAChB;QAED,MAAM,SAAS,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,qBAAqB,CAAC;QAC1E,IAAI,SAAS,GAAG,IAAI,CAAC,kBAAkB,EAAE;YACrC,kCAAkC;YAClC,OAAO,KAAK,CAAC;SAChB;QAED,wEAAwE;QACxE,MAAM,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,kBAAkB,CAAC;QACpE,OAAO,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,kBAAkB,KAAK,MAAM,CAAC,CAAC;IACxF,CAAC;IAED;;;;;;;OAOG;IACK,KAAK,CAAC,qBAAqB,CAAC,cAA2C;QAC3E,MAAM,kBAAkB,GACpB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAE,CAAe,CAAC,SAAS,CAAC,CAAC;QAC/F,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE,EAAE;YACzE,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBACjC,MAAM,OAAO,GAAG,GAAG,EAAE;oBACjB,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;oBAC/D,SAAS,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;gBACvD,CAAC,CAAC;gBACF,MAAM,OAAO,GAAG,CAAC,QAAgB,EAAE,EAAE;oBACjC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACjC,IAAI,eAAe,CAAC,IAAI,KAAK,CAAC,EAAE;wBAC5B,OAAO,EAAE,CAAC;wBACV,OAAO,EAAE,CAAC;qBACb;gBACL,CAAC,CAAC;gBACF,oEAAoE;gBACpE,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC,KAAK,CAAC;gBACpD,SAAS,CAAC,GAAG,KAAK,iCAAiC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;gBACzF,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;gBAC9D,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;gBAClD,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;oBACxB,OAAO,EAAE,CAAC;oBACV,OAAO,EAAE,CAAC;gBACd,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC,CAAC;IACR,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,oBAAoB,CAAC,iBAA+B;QAC9D,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACjC,MAAM,OAAO,GAAG,GAAG,EAAE;gBACjB,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;oBACxB,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAChD,CAAC,CAAC,CAAC;gBACH,OAAO,EAAE,CAAC;YACd,CAAC,CAAC;YACF,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBACxB,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/C,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACI,gBAAgB,CAAC,GAAG,UAAwB;QAC/C,MAAM,OAAO,GAAiB,EAAE,CAAC;QACjC,MAAM,iBAAiB,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACzD,KAAK,MAAM,SAAS,IAAI,iBAAiB,EAAE;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC9C,IAAI,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,MAAK,IAAI,EAAE;gBACzB,SAAS,CAAC,GAAG,MAAM,CAAC,KAAK,qBAAqB,CAAC,CAAC;gBAChD,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;gBACxC,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACzC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACxB,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;aACzB;SACJ;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,eAAe,CAAC,GAAG,UAAwB;QACpD,MAAM,MAAM,GAAoB,EAAE,CAAC;QACnC,MAAM,iBAAiB,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACzD,KAAK,MAAM,SAAS,IAAI,iBAAiB,EAAE;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC9C,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;gBACxC,SAAS,CAAC,GAAG,MAAM,CAAC,KAAK,oBAAoB,CAAC,CAAC;gBAC/C,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;gBACpD,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;gBACrD,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;aACxB;SACJ;QACD,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,eAAe,CAAC,GAAG,UAAwB;QACpD,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACxF,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,eAAe,CAAC,GAAG,UAAwB;QACpD,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IACzF,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY,CAAI,UAAwB,EAAE,QAAmD;QACvG,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,UAAU,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAqB,EAAE,CAAC;QAErC,MAAM,iBAAiB,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACzD,MAAM,eAAe,GAAG,IAAI,GAAG,EAAsB,CAAC;QACtD,MAAM,OAAO,GAAmB,EAAE,CAAC;QACnC,KAAK,MAAM,SAAS,IAAI,iBAAiB,EAAE;YACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;YAElC,uGAAuG;YACvG,mCAAmC;YACnC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;YACjE,KAAK,CAAC,MAAM,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACvB;QAED,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;YACzC,SAAS,CAAC,0BAA0B,CAAC,CAAC;YACtC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACrE;QAED,wDAAwD;QACxD,8CAA8C;QAC9C,IAAI,eAAe,CAAC,IAAI,EAAE;YACtB,SAAS,CAAC,uBAAuB,CAAC,CAAC;YACnC,GAAG;gBACC,MAAM,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;aACtD,QAAQ,eAAe,CAAC,IAAI,EAAE;SAClC;QAED,sBAAsB;QACtB,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QAEpC,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;IAED;;;;;;OAMG;IACK,iBAAiB,CAAC,SAAqB,EAAE,eAAwC;QACrF,MAAM,UAAU,GAAG,CAAC,QAA4B,EAAE,EAAE;YAChD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;gBAC5B,IAAI,CAAC,IAAA,sCAAuB,EAAC,OAAO,CAAC,EAAE;oBACnC,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;iBAChE;aACJ;QACL,CAAC,CAAC;QACF,MAAM,SAAS,GAAG,CAAC,OAAkC,EAAE,EAAE;YACrD,IAAI,CAAC,IAAA,sCAAuB,EAAC,OAAO,CAAC;mBAC9B,OAAO,CAAC,QAAQ,KAAM,SAAuB,CAAC,QAAQ;mBACtD,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,oBAAoB,EAAE;gBACpE,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;aACrC;QACL,CAAC,CAAC;QAEF,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACrD,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAErD,OAAO,GAAG,EAAE;YACR,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YACtD,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC1D,CAAC,CAAC;IACN,CAAC;IAED;;OAEG;IACK,UAAU,CAAC,SAAqB,EAAE,KAAa;QACnD,IAAI,OAAO,CAAC,OAAO,EAAE;YACjB,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,WAAgB,EAAE,EAAE;;gBACzD,IAAI;oBACA,IAAI,IAAI,KAAK,kCAAW,CAAC,SAAS,EAAE;wBAChC,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE;4BAAE,OAAO,WAAW,CAAC;yBAAE;wBAC5D,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;qBACtC;oBACD,IAAI,OAAO,GAAG,EAAE,CAAC;oBAEjB,2DAA2D;oBAC3D,6CAA6C;oBAC7C,IAAI,QAAQ,GAAG,OAAO,WAAW,KAAK,QAAQ,CAAC,CAAC;wBAC5C,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;oBAC1C,OAAO,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI,EAAE;wBAChD,IAAI,CAAA,MAAA,QAAQ,CAAC,QAAQ,0CAAE,OAAO,MAAK,SAAS,EAAE;4BAC1C,OAAO,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;4BAC3C,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;yBACzC;6BAAM,IAAI,CAAA,MAAA,QAAQ,CAAC,OAAO,0CAAE,OAAO,MAAK,SAAS,EAAE;4BAChD,OAAO,IAAI,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;4BAC1C,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC;yBACxC;6BAAM;4BACH,MAAM;yBACT;qBACJ;oBACD,IAAI,OAAO,EAAE;wBACT,OAAO,GAAG,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;qBACnD;oBACD,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;iBACnC;gBAAC,OAAO,CAAM,EAAE;oBACb,OAAO,GAAG,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;iBACrC;YACL,CAAC,CAAC;YACF,OAAO,CAAC,GAAG,KAAK,oBAAqB,SAAuB,CAAC,QAAQ,EAAE,CAAC,CAAC;YACzE,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;gBAClD,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE;oBACxB,OAAO,CAAC,GAAG,KAAK,kBAAkB;0BAC5B,QAAQ,GAAG,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG;0BAC1D,QAAQ,GAAG,CAAC,uBAAuB,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG;0BAC7D,GAAG,GAAG,CAAC,IAAI,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;iBACrE;YACL,CAAC,CAAC,CAAC;YACH,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,EAAE;gBACvC,OAAO,CAAC,GAA8B,EAAE,EAAE;oBACtC,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,KAAM,SAAuB,CAAC,QAAQ,CAAC,CAAC;wBAClE,QAAQ,GAAG,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;oBAC3E,OAAO,CAAC,GAAG,KAAK,KAAK,IAAI,UAAU,GAAG,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG;0BACzE,GAAG,SAAS,SAAS,GAAG,CAAC,qBAAqB,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG;0BACxE,GAAG,GAAG,CAAC,IAAI,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACtE,CAAC,CAAC;YACN,CAAC,CAAC;YACF,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;YACpE,SAAS,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;YAClE,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;gBAC7C,OAAO,CAAC,GAAG,KAAK,oBAAoB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC5D,CAAC,CAAC,CAAC;YACH,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE;gBAC/C,OAAO,CAAC,GAAG,KAAK,UAAU,MAAM,EAAE,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;SACN;IACL,CAAC;IAED;;;;OAIG;IACK,aAAa,CAAC,UAAwB;QAC1C,MAAM,iBAAiB,GAAG,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;QACpG,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACtE,CAAC;CACJ;AAziBD,wDAyiBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n/* eslint-disable @typescript-eslint/strict-boolean-expressions */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { IContainer, IDeltaQueue, IHostLoader } from \"@fluidframework/container-definitions\";\nimport { Container } from \"@fluidframework/container-loader\";\nimport { canBeCoalescedByService } from \"@fluidframework/driver-utils\";\nimport { IDocumentMessage, ISequencedDocumentMessage, MessageType } from \"@fluidframework/protocol-definitions\";\nimport { debug } from \"./debug\";\nimport { IOpProcessingController } from \"./testObjectProvider\";\nimport { timeoutAwait, timeoutPromise } from \"./timeoutUtils\";\n\nconst debugOp = debug.extend(\"ops\");\nconst debugWait = debug.extend(\"wait\");\n\n// set the maximum timeout value as 5 mins\nconst defaultMaxTimeout = 5 * 6000;\n\ninterface ContainerRecord {\n // A short number for debug output\n index: number;\n\n // LoaderContainerTracker paused state\n paused: boolean;\n\n // Tracking trailing no-op that may or may be acked by the server so we can discount them\n // See issue #5629\n startTrailingNoOps: number;\n trailingNoOps: number;\n\n // Track last proposal to ensure no unresolved proposal\n lastProposal: number;\n}\n\nexport class LoaderContainerTracker implements IOpProcessingController {\n private readonly containers = new Map<IContainer, ContainerRecord>();\n private lastProposalSeqNum: number = 0;\n\n constructor(private readonly syncSummarizerClients: boolean = false) {}\n\n /**\n * Add a loader to start to track any container created from them\n * @param loader - loader to start tracking any container created.\n */\n public add<LoaderType extends IHostLoader>(loader: LoaderType) {\n // TODO: Expose Loader API to able to intercept container creation (See issue #5114)\n const patch = <T, C extends IContainer>(fn: (...args) => Promise<C>) => {\n const boundFn = fn.bind(loader);\n return async (...args: T[]) => {\n const container = await boundFn(...args);\n this.addContainer(container);\n return container;\n };\n };\n /* eslint-disable @typescript-eslint/unbound-method */\n loader.resolve = patch(loader.resolve);\n loader.createDetachedContainer = patch(loader.createDetachedContainer);\n loader.rehydrateDetachedContainerFromSnapshot = patch(loader.rehydrateDetachedContainerFromSnapshot);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Utility function to add container to be tracked.\n *\n * @param container - container to add\n */\n private addContainer(container: IContainer) {\n // ignore summarizer\n if (!container.deltaManager.clientDetails.capabilities.interactive && !this.syncSummarizerClients) { return; }\n\n // don't add container that is already tracked\n if (this.containers.has(container)) { return; }\n\n const record = {\n index: this.containers.size,\n paused: false,\n startTrailingNoOps: 0,\n trailingNoOps: 0,\n lastProposal: 0,\n };\n this.containers.set(container, record);\n this.trackTrailingNoOps(container, record);\n this.trackLastProposal(container);\n this.setupTrace(container, record.index);\n }\n\n /**\n * Keep track of the trailing NoOp that was sent so we can discount them in the clientSequenceNumber tracking.\n * The server might coalesce them with other ops, or a single NoOp, or delay it if it don't think it is necessary.\n *\n * @param container - the container to track\n * @param record - the record to update the trailing op information\n */\n private trackTrailingNoOps(container: IContainer, record: ContainerRecord) {\n container.deltaManager.outbound.on(\"op\", (messages) => {\n for (const msg of messages) {\n if (canBeCoalescedByService(msg)) {\n // Track the NoOp that was sent.\n if (record.trailingNoOps === 0) {\n // record the starting sequence number of the trailing no ops if we haven't been tracking yet.\n record.startTrailingNoOps = msg.clientSequenceNumber;\n }\n record.trailingNoOps++;\n } else {\n // Other ops has been sent. We would like to see those ack'ed, so no more need to track NoOps\n record.trailingNoOps = 0;\n }\n }\n });\n\n container.deltaManager.inbound.on(\"push\", (message) => {\n // Received the no op back, update the record if we are tracking\n if (canBeCoalescedByService(message)\n && message.clientId === (container as Container).clientId\n && record.trailingNoOps !== 0\n && record.startTrailingNoOps <= message.clientSequenceNumber\n ) {\n // NoOp might have coalesced and skipped ahead some sequence number\n // update the record and skip ahead as well\n const oldStartTrailingNoOps = record.startTrailingNoOps;\n record.startTrailingNoOps = message.clientSequenceNumber + 1;\n record.trailingNoOps -= (record.startTrailingNoOps - oldStartTrailingNoOps);\n }\n });\n\n container.on(\"disconnected\", () => {\n // reset on disconnect.\n record.trailingNoOps = 0;\n });\n }\n\n private trackLastProposal(container: IContainer) {\n container.on(\"codeDetailsProposed\", (value, proposal) => {\n if (proposal.sequenceNumber > this.lastProposalSeqNum) {\n this.lastProposalSeqNum = proposal.sequenceNumber;\n }\n });\n }\n\n /**\n * Reset the tracker, closing all containers and stop tracking them.\n */\n public reset() {\n this.lastProposalSeqNum = 0;\n for (const container of this.containers.keys()) {\n container.close();\n }\n this.containers.clear();\n\n // REVIEW: do we need to unpatch the loaders?\n }\n\n /**\n * Ensure all tracked containers are synchronized\n */\n public async ensureSynchronized(...containers: IContainer[]) {\n await this.processSynchronized(undefined, ...containers);\n }\n\n /**\n * Ensure all tracked containers are synchronized with a time limit\n */\n public async ensureSynchronizedWithTimeout?(timeoutDuration: number | undefined, ...containers: IContainer[]) {\n await this.processSynchronized(timeoutDuration, ...containers);\n }\n\n /**\n * Make sure all the tracked containers are synchronized.\n * - No isDirty (non-readonly) containers\n * - No extra clientId in quorum of any container that is not tracked and still opened.\n * - i.e. no pending Join/Leave message.\n * - No unresolved proposal (minSeqNum \\>= lastProposalSeqNum)\n * - lastSequenceNumber of all container is the same\n * - clientSequenceNumberObserved is the same as clientSequenceNumber sent\n * - this overlaps with !isDirty, but include task scheduler ops.\n * - Trailing NoOp is tracked and don't count as pending ops.\n */\n private async processSynchronized(timeoutDuration: number | undefined, ...containers: IContainer[]) {\n const start = Date.now();\n const resumed = this.resumeProcessing(...containers);\n\n let waitingSequenceNumberSynchronized = false;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const containersToApply = this.getContainers(containers);\n if (containersToApply.length === 0) { break; }\n\n // Ignore readonly dirty containers, because it can't sent up and nothing can be done about it being dirty\n const dirtyContainers = containersToApply.filter((c) => {\n const { deltaManager, isDirty } = c;\n return deltaManager.readOnlyInfo.readonly !== true && isDirty;\n });\n if (dirtyContainers.length === 0) {\n // Wait for all the leave messages\n const pendingClients = this.getPendingClients(containersToApply);\n if (pendingClients.length === 0) {\n if (this.isSequenceNumberSynchronized(containersToApply)) {\n // done, we are in sync\n break;\n }\n if (!waitingSequenceNumberSynchronized) {\n // Only write it out once\n waitingSequenceNumberSynchronized = true;\n debugWait(\"Waiting for sequence number synchronized\");\n await timeoutAwait(this.waitForAnyInboundOps(containersToApply), {\n durationMs: timeoutDuration ? timeoutDuration - (Date.now() - start) : defaultMaxTimeout,\n errorMsg: \"Timeout on waiting for sequence number synchronized\",\n });\n }\n } else {\n waitingSequenceNumberSynchronized = false;\n await timeoutAwait(this.waitForPendingClients(pendingClients), {\n durationMs: timeoutDuration ? timeoutDuration - (Date.now() - start) : defaultMaxTimeout,\n errorMsg: \"Timeout on waiting for pending join or leave op\",\n });\n }\n } else {\n // Wait for all the containers to be saved\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n debugWait(`Waiting container to be saved ${dirtyContainers.map((c) => this.containers.get(c)!.index)}`);\n waitingSequenceNumberSynchronized = false;\n const remainedDuration = timeoutDuration ? timeoutDuration - (Date.now() - start) : defaultMaxTimeout;\n await Promise.all(dirtyContainers.map(async (c) => Promise.race(\n [timeoutPromise(\n (resolve) => c.once(\"saved\", () => resolve()),\n {\n durationMs: remainedDuration,\n errorMsg: \"Timeout on waiting a container to be saved\",\n },\n ),\n new Promise((resolve) => c.once(\"closed\", resolve)),\n ],\n )));\n }\n\n // yield a turn to allow side effect of the ops we just processed execute before we check again\n await new Promise<void>((resolve) => { setTimeout(resolve, 0); });\n }\n\n // Pause all container that was resumed\n // don't call pause if resumed is empty and pause everything, which is not what we want\n if (resumed.length !== 0) {\n await timeoutAwait(this.pauseProcessing(...resumed), {\n durationMs: timeoutDuration ? timeoutDuration - (Date.now() - start) : defaultMaxTimeout,\n errorMsg: \"Timeout on waiting for pausing all resumed containers\",\n });\n }\n\n debugWait(\"Synchronized\");\n }\n\n /**\n * Utility to calculate the set of clientId per container in quorum that is NOT associated with\n * any container we tracked, indicating there is a pending join or leave op that we need to wait.\n *\n * @param containersToApply - the set of containers to check\n */\n private getPendingClients(containersToApply: IContainer[]) {\n // All the clientId we track should be a superset of the quorum, otherwise, we are missing\n // leave messages\n const openedDocuments = Array.from(this.containers.keys()).filter((c) => !c.closed);\n const openedClientId = openedDocuments.map((container) => (container as Container).clientId);\n\n const pendingClients: [IContainer, Set<string>][] = [];\n containersToApply.forEach((container) => {\n const pendingClientId = new Set<string>();\n const quorum = container.getQuorum();\n quorum.getMembers().forEach((client, clientId) => {\n // ignore summarizer\n if (!client.client.details.capabilities.interactive && !this.syncSummarizerClients) { return; }\n if (!openedClientId.includes(clientId)) {\n pendingClientId.add(clientId);\n }\n });\n\n if (pendingClientId.size !== 0) {\n pendingClients.push([container, pendingClientId]);\n }\n });\n return pendingClients;\n }\n\n /**\n * Utility to check synchronization based on sequence number\n * See ensureSynchronized for more detail\n *\n * @param containersToApply - the set of containers to check\n */\n private isSequenceNumberSynchronized(containersToApply: IContainer[]) {\n // clientSequenceNumber check detects ops in flight, both on the wire and in the outbound queue\n // We need both client sequence number and isDirty check because:\n // - Currently isDirty flag ignores ops for task scheduler, so we need the client sequence number check\n // - But isDirty flags include ops during forceReadonly and disconnected, because we don't submit\n // the ops in the first place, clientSequenceNumber is not assigned\n\n const isClientSequenceNumberSynchronized = containersToApply.every((container) => {\n if (container.deltaManager.readOnlyInfo.readonly === true) {\n // Ignore readonly container. the clientSeqNum and clientSeqNumObserved might be out of sync\n // because we transition to readonly when outbound is not empty or the in transit op got lost\n return true;\n }\n // Note that in read only mode, the op won't be submitted\n let deltaManager = (container.deltaManager as any);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { trailingNoOps } = this.containers.get(container)!;\n // Back-compat: clientSequenceNumber & clientSequenceNumberObserved moved to ConnectionManager in 0.53\n if (!(\"clientSequenceNumber\" in deltaManager)) {\n deltaManager = deltaManager.connectionManager;\n }\n assert(\"clientSequenceNumber\" in deltaManager, \"no clientSequenceNumber\");\n assert(\"clientSequenceNumberObserved\" in deltaManager, \"no clientSequenceNumber\");\n return deltaManager.clientSequenceNumber ===\n (deltaManager.clientSequenceNumberObserved as number) + trailingNoOps;\n });\n\n if (!isClientSequenceNumberSynchronized) {\n return false;\n }\n\n const minSeqNum = containersToApply[0].deltaManager.minimumSequenceNumber;\n if (minSeqNum < this.lastProposalSeqNum) {\n // There is an unresolved proposal\n return false;\n }\n\n // Check to see if all the container has process the same number of ops.\n const seqNum = containersToApply[0].deltaManager.lastSequenceNumber;\n return containersToApply.every((c) => c.deltaManager.lastSequenceNumber === seqNum);\n }\n\n /**\n * Utility to wait for any clientId in quorum that is NOT associated with any container we\n * tracked, indicating there is a pending join or leave op that we need to wait.\n *\n * Note that this function doesn't account for container that got added after we started waiting\n *\n * @param containersToApply - the set of containers to wait for any inbound ops for\n */\n private async waitForPendingClients(pendingClients: [IContainer, Set<string>][]) {\n const unconnectedClients =\n Array.from(this.containers.keys()).filter((c) => !c.closed && !(c as Container).connected);\n return Promise.all(pendingClients.map(async ([container, pendingClientId]) => {\n return new Promise<void>((resolve) => {\n const cleanup = () => {\n unconnectedClients.forEach((c) => c.off(\"connected\", handler));\n container.getQuorum().off(\"removeMember\", handler);\n };\n const handler = (clientId: string) => {\n pendingClientId.delete(clientId);\n if (pendingClientId.size === 0) {\n cleanup();\n resolve();\n }\n };\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const index = this.containers.get(container)!.index;\n debugWait(`${index}: Waiting for pending clients ${Array.from(pendingClientId.keys())}`);\n unconnectedClients.forEach((c) => c.on(\"connected\", handler));\n container.getQuorum().on(\"removeMember\", handler);\n container.on(\"closed\", () => {\n cleanup();\n resolve();\n });\n });\n }));\n }\n\n /**\n * Utility to wait for any inbound ops from a set of containers\n * @param containersToApply - the set of containers to wait for any inbound ops for\n */\n private async waitForAnyInboundOps(containersToApply: IContainer[]) {\n return new Promise<void>((resolve) => {\n const handler = () => {\n containersToApply.map((c) => {\n c.deltaManager.inbound.off(\"push\", handler);\n });\n resolve();\n };\n containersToApply.map((c) => {\n c.deltaManager.inbound.on(\"push\", handler);\n });\n });\n }\n\n /**\n * Resume all queue activities on all paused tracked containers and return them\n */\n public resumeProcessing(...containers: IContainer[]) {\n const resumed: IContainer[] = [];\n const containersToApply = this.getContainers(containers);\n for (const container of containersToApply) {\n const record = this.containers.get(container);\n if (record?.paused === true) {\n debugWait(`${record.index}: container resumed`);\n container.deltaManager.inbound.resume();\n container.deltaManager.outbound.resume();\n resumed.push(container);\n record.paused = false;\n }\n }\n return resumed;\n }\n\n /**\n * Pause all queue activities on the containers given, or all tracked containers\n * Any containers given that is not tracked will be ignored.\n */\n public async pauseProcessing(...containers: IContainer[]) {\n const pauseP: Promise<void>[] = [];\n const containersToApply = this.getContainers(containers);\n for (const container of containersToApply) {\n const record = this.containers.get(container);\n if (record !== undefined && !record.paused) {\n debugWait(`${record.index}: container paused`);\n pauseP.push(container.deltaManager.inbound.pause());\n pauseP.push(container.deltaManager.outbound.pause());\n record.paused = true;\n }\n }\n await Promise.all(pauseP);\n }\n\n /**\n * Pause all queue activities on all tracked containers, and resume only\n * inbound to process ops until it is idle. All queues are left in the paused state\n * after the function\n */\n public async processIncoming(...containers: IContainer[]) {\n return this.processQueue(containers, (container) => container.deltaManager.inbound);\n }\n\n /**\n * Pause all queue activities on all tracked containers, and resume only\n * outbound to process ops until it is idle. All queues are left in the paused state\n * after the function\n */\n public async processOutgoing(...containers: IContainer[]) {\n return this.processQueue(containers, (container) => container.deltaManager.outbound);\n }\n\n /**\n * Implementation of processIncoming and processOutgoing\n */\n private async processQueue<U>(containers: IContainer[], getQueue: (container: IContainer) => IDeltaQueue<U>) {\n await this.pauseProcessing(...containers);\n const resumed: IDeltaQueue<U>[] = [];\n\n const containersToApply = this.getContainers(containers);\n const inflightTracker = new Map<IContainer, number>();\n const cleanup: (() => void)[] = [];\n for (const container of containersToApply) {\n const queue = getQueue(container);\n\n // track the outgoing ops (if any) to make sure they make the round trip to at least to the same client\n // to make sure they are sequenced.\n cleanup.push(this.setupInOutTracker(container, inflightTracker));\n queue.resume();\n resumed.push(queue);\n }\n\n while (resumed.some((queue) => !queue.idle)) {\n debugWait(\"Wait until queue is idle\");\n await new Promise<void>((resolve) => { setTimeout(resolve, 0); });\n }\n\n // Make sure all the op that we sent out are acked first\n // This is no op if we are processing incoming\n if (inflightTracker.size) {\n debugWait(\"Wait for inflight ops\");\n do {\n await this.waitForAnyInboundOps(containersToApply);\n } while (inflightTracker.size);\n }\n\n // remove the handlers\n cleanup.forEach((clean) => clean());\n\n await Promise.all(resumed.map(async (queue) => queue.pause()));\n }\n\n /**\n * Utility to set up listener to track the outbound ops until it round trip back\n * Returns a function to remove the handler after it is done.\n *\n * @param container - the container to setup\n * @param inflightTracker - a map to track the clientSequenceNumber per container it expect to get ops back\n */\n private setupInOutTracker(container: IContainer, inflightTracker: Map<IContainer, number>) {\n const outHandler = (messages: IDocumentMessage[]) => {\n for (const message of messages) {\n if (!canBeCoalescedByService(message)) {\n inflightTracker.set(container, message.clientSequenceNumber);\n }\n }\n };\n const inHandler = (message: ISequencedDocumentMessage) => {\n if (!canBeCoalescedByService(message)\n && message.clientId === (container as Container).clientId\n && inflightTracker.get(container) === message.clientSequenceNumber) {\n inflightTracker.delete(container);\n }\n };\n\n container.deltaManager.outbound.on(\"op\", outHandler);\n container.deltaManager.inbound.on(\"push\", inHandler);\n\n return () => {\n container.deltaManager.outbound.off(\"op\", outHandler);\n container.deltaManager.inbound.off(\"push\", inHandler);\n };\n }\n\n /**\n * Setup debug traces for connection and ops\n */\n private setupTrace(container: IContainer, index: number) {\n if (debugOp.enabled) {\n const getContentsString = (type: string, msgContents: any) => {\n try {\n if (type !== MessageType.Operation) {\n if (typeof msgContents === \"string\") { return msgContents; }\n return JSON.stringify(msgContents);\n }\n let address = \"\";\n\n // contents comes in the wire as JSON string (\"push\" event)\n // But already parsed when apply (\"op\" event)\n let contents = typeof msgContents === \"string\" ?\n JSON.parse(msgContents) : msgContents;\n while (contents !== undefined && contents !== null) {\n if (contents.contents?.address !== undefined) {\n address += `/${contents.contents.address}`;\n contents = contents.contents.contents;\n } else if (contents.content?.address !== undefined) {\n address += `/${contents.content.address}`;\n contents = contents.content.contents;\n } else {\n break;\n }\n }\n if (address) {\n return `${address} ${JSON.stringify(contents)}`;\n }\n return JSON.stringify(contents);\n } catch (e: any) {\n return `${e.message}: ${e.stack}`;\n }\n };\n debugOp(`${index}: ADD: clientId: ${(container as Container).clientId}`);\n container.deltaManager.outbound.on(\"op\", (messages) => {\n for (const msg of messages) {\n debugOp(`${index}: OUT: `\n + `cli: ${msg.clientSequenceNumber.toString().padStart(3)} `\n + `rsq: ${msg.referenceSequenceNumber.toString().padStart(3)} `\n + `${msg.type} ${getContentsString(msg.type, msg.contents)}`);\n }\n });\n const getInboundHandler = (type: string) => {\n return (msg: ISequencedDocumentMessage) => {\n const clientSeq = msg.clientId === (container as Container).clientId ?\n `cli: ${msg.clientSequenceNumber.toString().padStart(3)}` : \" \";\n debugOp(`${index}: ${type}: seq: ${msg.sequenceNumber.toString().padStart(3)} `\n + `${clientSeq} min: ${msg.minimumSequenceNumber.toString().padStart(3)} `\n + `${msg.type} ${getContentsString(msg.type, msg.contents)}`);\n };\n };\n container.deltaManager.inbound.on(\"push\", getInboundHandler(\"IN \"));\n container.deltaManager.inbound.on(\"op\", getInboundHandler(\"OP \"));\n container.deltaManager.on(\"connect\", (details) => {\n debugOp(`${index}: CON: clientId: ${details.clientId}`);\n });\n container.deltaManager.on(\"disconnect\", (reason) => {\n debugOp(`${index}: DIS: ${reason}`);\n });\n }\n }\n\n /**\n * Filter out the opened containers based on param.\n * @param containers - The container to filter to. If the array is empty, it means don't filter and return\n * all open containers.\n */\n private getContainers(containers: IContainer[]) {\n const containersToApply = containers.length === 0 ? Array.from(this.containers.keys()) : containers;\n return containersToApply.filter((container) => !container.closed);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"loaderContainerTracker.js","sourceRoot":"","sources":["../src/loaderContainerTracker.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/* eslint-disable @typescript-eslint/strict-boolean-expressions */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { IContainer, IDeltaQueue, IHostLoader } from \"@fluidframework/container-definitions\";\nimport { Container } from \"@fluidframework/container-loader\";\nimport { canBeCoalescedByService } from \"@fluidframework/driver-utils\";\nimport { IDocumentMessage, ISequencedDocumentMessage, MessageType } from \"@fluidframework/protocol-definitions\";\nimport { debug } from \"./debug\";\nimport { IOpProcessingController } from \"./testObjectProvider\";\nimport { timeoutAwait, timeoutPromise } from \"./timeoutUtils\";\n\nconst debugOp = debug.extend(\"ops\");\nconst debugWait = debug.extend(\"wait\");\n\n// set the maximum timeout value as 5 mins\nconst defaultMaxTimeout = 5 * 6000;\n\ninterface ContainerRecord {\n // A short number for debug output\n index: number;\n\n // LoaderContainerTracker paused state\n paused: boolean;\n\n // Tracking trailing no-op that may or may be acked by the server so we can discount them\n // See issue #5629\n startTrailingNoOps: number;\n trailingNoOps: number;\n\n // Track last proposal to ensure no unresolved proposal\n lastProposal: number;\n}\n\nexport class LoaderContainerTracker implements IOpProcessingController {\n private readonly containers = new Map<IContainer, ContainerRecord>();\n private lastProposalSeqNum: number = 0;\n\n constructor(private readonly syncSummarizerClients: boolean = false) {}\n\n /**\n * Add a loader to start to track any container created from them\n * @param loader - loader to start tracking any container created.\n */\n public add<LoaderType extends IHostLoader>(loader: LoaderType) {\n // TODO: Expose Loader API to able to intercept container creation (See issue #5114)\n const patch = <T, C extends IContainer>(fn: (...args) => Promise<C>) => {\n const boundFn = fn.bind(loader);\n return async (...args: T[]) => {\n const container = await boundFn(...args);\n this.addContainer(container);\n return container;\n };\n };\n /* eslint-disable @typescript-eslint/unbound-method */\n loader.resolve = patch(loader.resolve);\n loader.createDetachedContainer = patch(loader.createDetachedContainer);\n loader.rehydrateDetachedContainerFromSnapshot = patch(loader.rehydrateDetachedContainerFromSnapshot);\n /* eslint-enable @typescript-eslint/unbound-method */\n }\n\n /**\n * Utility function to add container to be tracked.\n *\n * @param container - container to add\n */\n private addContainer(container: IContainer) {\n // ignore summarizer\n if (!container.deltaManager.clientDetails.capabilities.interactive && !this.syncSummarizerClients) { return; }\n\n // don't add container that is already tracked\n if (this.containers.has(container)) { return; }\n\n const record = {\n index: this.containers.size,\n paused: false,\n startTrailingNoOps: 0,\n trailingNoOps: 0,\n lastProposal: 0,\n };\n this.containers.set(container, record);\n this.trackTrailingNoOps(container, record);\n this.trackLastProposal(container);\n this.setupTrace(container, record.index);\n }\n\n /**\n * Keep track of the trailing NoOp that was sent so we can discount them in the clientSequenceNumber tracking.\n * The server might coalesce them with other ops, or a single NoOp, or delay it if it don't think it is necessary.\n *\n * @param container - the container to track\n * @param record - the record to update the trailing op information\n */\n private trackTrailingNoOps(container: IContainer, record: ContainerRecord) {\n container.deltaManager.outbound.on(\"op\", (messages) => {\n for (const msg of messages) {\n if (canBeCoalescedByService(msg)) {\n // Track the NoOp that was sent.\n if (record.trailingNoOps === 0) {\n // record the starting sequence number of the trailing no ops if we haven't been tracking yet.\n record.startTrailingNoOps = msg.clientSequenceNumber;\n }\n record.trailingNoOps++;\n } else {\n // Other ops has been sent. We would like to see those ack'ed, so no more need to track NoOps\n record.trailingNoOps = 0;\n }\n }\n });\n\n container.deltaManager.inbound.on(\"push\", (message) => {\n // Received the no op back, update the record if we are tracking\n if (canBeCoalescedByService(message)\n && message.clientId === (container as Container).clientId\n && record.trailingNoOps !== 0\n && record.startTrailingNoOps <= message.clientSequenceNumber\n ) {\n // NoOp might have coalesced and skipped ahead some sequence number\n // update the record and skip ahead as well\n const oldStartTrailingNoOps = record.startTrailingNoOps;\n record.startTrailingNoOps = message.clientSequenceNumber + 1;\n record.trailingNoOps -= (record.startTrailingNoOps - oldStartTrailingNoOps);\n }\n });\n\n container.on(\"disconnected\", () => {\n // reset on disconnect.\n record.trailingNoOps = 0;\n });\n }\n\n private trackLastProposal(container: IContainer) {\n container.on(\"codeDetailsProposed\", (value, proposal) => {\n if (proposal.sequenceNumber > this.lastProposalSeqNum) {\n this.lastProposalSeqNum = proposal.sequenceNumber;\n }\n });\n }\n\n /**\n * Reset the tracker, closing all containers and stop tracking them.\n */\n public reset() {\n this.lastProposalSeqNum = 0;\n for (const container of this.containers.keys()) {\n container.close();\n }\n this.containers.clear();\n\n // REVIEW: do we need to unpatch the loaders?\n }\n\n /**\n * Ensure all tracked containers are synchronized\n */\n public async ensureSynchronized(...containers: IContainer[]): Promise<void> {\n await this.processSynchronized(undefined, ...containers);\n }\n\n /**\n * Ensure all tracked containers are synchronized with a time limit\n */\n public async ensureSynchronizedWithTimeout?(timeoutDuration: number | undefined, ...containers: IContainer[]) {\n await this.processSynchronized(timeoutDuration, ...containers);\n }\n\n /**\n * Make sure all the tracked containers are synchronized.\n *\n * No isDirty (non-readonly) containers\n *\n * No extra clientId in quorum of any container that is not tracked and still opened.\n *\n * - i.e. no pending Join/Leave message.\n *\n * No unresolved proposal (minSeqNum \\>= lastProposalSeqNum)\n *\n * lastSequenceNumber of all container is the same\n *\n * clientSequenceNumberObserved is the same as clientSequenceNumber sent\n *\n * - this overlaps with !isDirty, but include task scheduler ops.\n *\n * - Trailing NoOp is tracked and don't count as pending ops.\n */\n private async processSynchronized(timeoutDuration: number | undefined, ...containers: IContainer[]) {\n const start = Date.now();\n const resumed = this.resumeProcessing(...containers);\n\n let waitingSequenceNumberSynchronized = false;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const containersToApply = this.getContainers(containers);\n if (containersToApply.length === 0) { break; }\n\n // Ignore readonly dirty containers, because it can't sent up and nothing can be done about it being dirty\n const dirtyContainers = containersToApply.filter((c) => {\n const { deltaManager, isDirty } = c;\n return deltaManager.readOnlyInfo.readonly !== true && isDirty;\n });\n if (dirtyContainers.length === 0) {\n // Wait for all the leave messages\n const pendingClients = this.getPendingClients(containersToApply);\n if (pendingClients.length === 0) {\n if (this.isSequenceNumberSynchronized(containersToApply)) {\n // done, we are in sync\n break;\n }\n if (!waitingSequenceNumberSynchronized) {\n // Only write it out once\n waitingSequenceNumberSynchronized = true;\n debugWait(\"Waiting for sequence number synchronized\");\n await timeoutAwait(this.waitForAnyInboundOps(containersToApply), {\n durationMs: timeoutDuration ? timeoutDuration - (Date.now() - start) : defaultMaxTimeout,\n errorMsg: \"Timeout on waiting for sequence number synchronized\",\n });\n }\n } else {\n waitingSequenceNumberSynchronized = false;\n await timeoutAwait(this.waitForPendingClients(pendingClients), {\n durationMs: timeoutDuration ? timeoutDuration - (Date.now() - start) : defaultMaxTimeout,\n errorMsg: \"Timeout on waiting for pending join or leave op\",\n });\n }\n } else {\n // Wait for all the containers to be saved\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n debugWait(`Waiting container to be saved ${dirtyContainers.map((c) => this.containers.get(c)!.index)}`);\n waitingSequenceNumberSynchronized = false;\n const remainedDuration = timeoutDuration ? timeoutDuration - (Date.now() - start) : defaultMaxTimeout;\n await Promise.all(dirtyContainers.map(async (c) => Promise.race(\n [timeoutPromise(\n (resolve) => c.once(\"saved\", () => resolve()),\n {\n durationMs: remainedDuration,\n errorMsg: \"Timeout on waiting a container to be saved\",\n },\n ),\n new Promise((resolve) => c.once(\"closed\", resolve)),\n ],\n )));\n }\n\n // yield a turn to allow side effect of the ops we just processed execute before we check again\n await new Promise<void>((resolve) => { setTimeout(resolve, 0); });\n }\n\n // Pause all container that was resumed\n // don't call pause if resumed is empty and pause everything, which is not what we want\n if (resumed.length !== 0) {\n await timeoutAwait(this.pauseProcessing(...resumed), {\n durationMs: timeoutDuration ? timeoutDuration - (Date.now() - start) : defaultMaxTimeout,\n errorMsg: \"Timeout on waiting for pausing all resumed containers\",\n });\n }\n\n debugWait(\"Synchronized\");\n }\n\n /**\n * Utility to calculate the set of clientId per container in quorum that is NOT associated with\n * any container we tracked, indicating there is a pending join or leave op that we need to wait.\n *\n * @param containersToApply - the set of containers to check\n */\n private getPendingClients(containersToApply: IContainer[]) {\n // All the clientId we track should be a superset of the quorum, otherwise, we are missing\n // leave messages\n const openedDocuments = Array.from(this.containers.keys()).filter((c) => !c.closed);\n const openedClientId = openedDocuments.map((container) => (container as Container).clientId);\n\n const pendingClients: [IContainer, Set<string>][] = [];\n containersToApply.forEach((container) => {\n const pendingClientId = new Set<string>();\n const quorum = container.getQuorum();\n quorum.getMembers().forEach((client, clientId) => {\n // ignore summarizer\n if (!client.client.details.capabilities.interactive && !this.syncSummarizerClients) { return; }\n if (!openedClientId.includes(clientId)) {\n pendingClientId.add(clientId);\n }\n });\n\n if (pendingClientId.size !== 0) {\n pendingClients.push([container, pendingClientId]);\n }\n });\n return pendingClients;\n }\n\n /**\n * Utility to check synchronization based on sequence number\n * See ensureSynchronized for more detail\n *\n * @param containersToApply - the set of containers to check\n */\n private isSequenceNumberSynchronized(containersToApply: IContainer[]) {\n // clientSequenceNumber check detects ops in flight, both on the wire and in the outbound queue\n // We need both client sequence number and isDirty check because:\n // - Currently isDirty flag ignores ops for task scheduler, so we need the client sequence number check\n // - But isDirty flags include ops during forceReadonly and disconnected, because we don't submit\n // the ops in the first place, clientSequenceNumber is not assigned\n\n const isClientSequenceNumberSynchronized = containersToApply.every((container) => {\n if (container.deltaManager.readOnlyInfo.readonly === true) {\n // Ignore readonly container. the clientSeqNum and clientSeqNumObserved might be out of sync\n // because we transition to readonly when outbound is not empty or the in transit op got lost\n return true;\n }\n // Note that in read only mode, the op won't be submitted\n let deltaManager = (container.deltaManager as any);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { trailingNoOps } = this.containers.get(container)!;\n // Back-compat: clientSequenceNumber & clientSequenceNumberObserved moved to ConnectionManager in 0.53\n if (!(\"clientSequenceNumber\" in deltaManager)) {\n deltaManager = deltaManager.connectionManager;\n }\n assert(\"clientSequenceNumber\" in deltaManager, \"no clientSequenceNumber\");\n assert(\"clientSequenceNumberObserved\" in deltaManager, \"no clientSequenceNumber\");\n return deltaManager.clientSequenceNumber ===\n (deltaManager.clientSequenceNumberObserved as number) + trailingNoOps;\n });\n\n if (!isClientSequenceNumberSynchronized) {\n return false;\n }\n\n const minSeqNum = containersToApply[0].deltaManager.minimumSequenceNumber;\n if (minSeqNum < this.lastProposalSeqNum) {\n // There is an unresolved proposal\n return false;\n }\n\n // Check to see if all the container has process the same number of ops.\n const seqNum = containersToApply[0].deltaManager.lastSequenceNumber;\n return containersToApply.every((c) => c.deltaManager.lastSequenceNumber === seqNum);\n }\n\n /**\n * Utility to wait for any clientId in quorum that is NOT associated with any container we\n * tracked, indicating there is a pending join or leave op that we need to wait.\n *\n * Note that this function doesn't account for container that got added after we started waiting\n *\n * @param containersToApply - the set of containers to wait for any inbound ops for\n */\n private async waitForPendingClients(pendingClients: [IContainer, Set<string>][]) {\n const unconnectedClients =\n Array.from(this.containers.keys()).filter((c) => !c.closed && !(c as Container).connected);\n return Promise.all(pendingClients.map(async ([container, pendingClientId]) => {\n return new Promise<void>((resolve) => {\n const cleanup = () => {\n unconnectedClients.forEach((c) => c.off(\"connected\", handler));\n container.getQuorum().off(\"removeMember\", handler);\n };\n const handler = (clientId: string) => {\n pendingClientId.delete(clientId);\n if (pendingClientId.size === 0) {\n cleanup();\n resolve();\n }\n };\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const index = this.containers.get(container)!.index;\n debugWait(`${index}: Waiting for pending clients ${Array.from(pendingClientId.keys())}`);\n unconnectedClients.forEach((c) => c.on(\"connected\", handler));\n container.getQuorum().on(\"removeMember\", handler);\n container.on(\"closed\", () => {\n cleanup();\n resolve();\n });\n });\n }));\n }\n\n /**\n * Utility to wait for any inbound ops from a set of containers\n * @param containersToApply - the set of containers to wait for any inbound ops for\n */\n private async waitForAnyInboundOps(containersToApply: IContainer[]) {\n return new Promise<void>((resolve) => {\n const handler = () => {\n containersToApply.map((c) => {\n c.deltaManager.inbound.off(\"push\", handler);\n });\n resolve();\n };\n containersToApply.map((c) => {\n c.deltaManager.inbound.on(\"push\", handler);\n });\n });\n }\n\n /**\n * Resume all queue activities on all paused tracked containers and return them\n */\n public resumeProcessing(...containers: IContainer[]) {\n const resumed: IContainer[] = [];\n const containersToApply = this.getContainers(containers);\n for (const container of containersToApply) {\n const record = this.containers.get(container);\n if (record?.paused === true) {\n debugWait(`${record.index}: container resumed`);\n container.deltaManager.inbound.resume();\n container.deltaManager.outbound.resume();\n resumed.push(container);\n record.paused = false;\n }\n }\n return resumed;\n }\n\n /**\n * Pause all queue activities on the containers given, or all tracked containers\n * Any containers given that is not tracked will be ignored.\n */\n public async pauseProcessing(...containers: IContainer[]) {\n const pauseP: Promise<void>[] = [];\n const containersToApply = this.getContainers(containers);\n for (const container of containersToApply) {\n const record = this.containers.get(container);\n if (record !== undefined && !record.paused) {\n debugWait(`${record.index}: container paused`);\n pauseP.push(container.deltaManager.inbound.pause());\n pauseP.push(container.deltaManager.outbound.pause());\n record.paused = true;\n }\n }\n await Promise.all(pauseP);\n }\n\n /**\n * Pause all queue activities on all tracked containers, and resume only\n * inbound to process ops until it is idle. All queues are left in the paused state\n * after the function\n */\n public async processIncoming(...containers: IContainer[]) {\n return this.processQueue(containers, (container) => container.deltaManager.inbound);\n }\n\n /**\n * Pause all queue activities on all tracked containers, and resume only\n * outbound to process ops until it is idle. All queues are left in the paused state\n * after the function\n */\n public async processOutgoing(...containers: IContainer[]) {\n return this.processQueue(containers, (container) => container.deltaManager.outbound);\n }\n\n /**\n * Implementation of processIncoming and processOutgoing\n */\n private async processQueue<U>(containers: IContainer[], getQueue: (container: IContainer) => IDeltaQueue<U>) {\n await this.pauseProcessing(...containers);\n const resumed: IDeltaQueue<U>[] = [];\n\n const containersToApply = this.getContainers(containers);\n const inflightTracker = new Map<IContainer, number>();\n const cleanup: (() => void)[] = [];\n for (const container of containersToApply) {\n const queue = getQueue(container);\n\n // track the outgoing ops (if any) to make sure they make the round trip to at least to the same client\n // to make sure they are sequenced.\n cleanup.push(this.setupInOutTracker(container, inflightTracker));\n queue.resume();\n resumed.push(queue);\n }\n\n while (resumed.some((queue) => !queue.idle)) {\n debugWait(\"Wait until queue is idle\");\n await new Promise<void>((resolve) => { setTimeout(resolve, 0); });\n }\n\n // Make sure all the op that we sent out are acked first\n // This is no op if we are processing incoming\n if (inflightTracker.size) {\n debugWait(\"Wait for inflight ops\");\n do {\n await this.waitForAnyInboundOps(containersToApply);\n } while (inflightTracker.size);\n }\n\n // remove the handlers\n cleanup.forEach((clean) => clean());\n\n await Promise.all(resumed.map(async (queue) => queue.pause()));\n }\n\n /**\n * Utility to set up listener to track the outbound ops until it round trip back\n * Returns a function to remove the handler after it is done.\n *\n * @param container - the container to setup\n * @param inflightTracker - a map to track the clientSequenceNumber per container it expect to get ops back\n */\n private setupInOutTracker(container: IContainer, inflightTracker: Map<IContainer, number>) {\n const outHandler = (messages: IDocumentMessage[]) => {\n for (const message of messages) {\n if (!canBeCoalescedByService(message)) {\n inflightTracker.set(container, message.clientSequenceNumber);\n }\n }\n };\n const inHandler = (message: ISequencedDocumentMessage) => {\n if (!canBeCoalescedByService(message)\n && message.clientId === (container as Container).clientId\n && inflightTracker.get(container) === message.clientSequenceNumber) {\n inflightTracker.delete(container);\n }\n };\n\n container.deltaManager.outbound.on(\"op\", outHandler);\n container.deltaManager.inbound.on(\"push\", inHandler);\n\n return () => {\n container.deltaManager.outbound.off(\"op\", outHandler);\n container.deltaManager.inbound.off(\"push\", inHandler);\n };\n }\n\n /**\n * Setup debug traces for connection and ops\n */\n private setupTrace(container: IContainer, index: number) {\n if (debugOp.enabled) {\n const getContentsString = (type: string, msgContents: any) => {\n try {\n if (type !== MessageType.Operation) {\n if (typeof msgContents === \"string\") { return msgContents; }\n return JSON.stringify(msgContents);\n }\n let address = \"\";\n\n // contents comes in the wire as JSON string (\"push\" event)\n // But already parsed when apply (\"op\" event)\n let contents = typeof msgContents === \"string\" ?\n JSON.parse(msgContents) : msgContents;\n while (contents !== undefined && contents !== null) {\n if (contents.contents?.address !== undefined) {\n address += `/${contents.contents.address}`;\n contents = contents.contents.contents;\n } else if (contents.content?.address !== undefined) {\n address += `/${contents.content.address}`;\n contents = contents.content.contents;\n } else {\n break;\n }\n }\n if (address) {\n return `${address} ${JSON.stringify(contents)}`;\n }\n return JSON.stringify(contents);\n } catch (e: any) {\n return `${e.message}: ${e.stack}`;\n }\n };\n debugOp(`${index}: ADD: clientId: ${(container as Container).clientId}`);\n container.deltaManager.outbound.on(\"op\", (messages) => {\n for (const msg of messages) {\n debugOp(`${index}: OUT: `\n + `cli: ${msg.clientSequenceNumber.toString().padStart(3)} `\n + `rsq: ${msg.referenceSequenceNumber.toString().padStart(3)} `\n + `${msg.type} ${getContentsString(msg.type, msg.contents)}`);\n }\n });\n const getInboundHandler = (type: string) => {\n return (msg: ISequencedDocumentMessage) => {\n const clientSeq = msg.clientId === (container as Container).clientId ?\n `cli: ${msg.clientSequenceNumber.toString().padStart(3)}` : \" \";\n debugOp(`${index}: ${type}: seq: ${msg.sequenceNumber.toString().padStart(3)} `\n + `${clientSeq} min: ${msg.minimumSequenceNumber.toString().padStart(3)} `\n + `${msg.type} ${getContentsString(msg.type, msg.contents)}`);\n };\n };\n container.deltaManager.inbound.on(\"push\", getInboundHandler(\"IN \"));\n container.deltaManager.inbound.on(\"op\", getInboundHandler(\"OP \"));\n container.deltaManager.on(\"connect\", (details) => {\n debugOp(`${index}: CON: clientId: ${details.clientId}`);\n });\n container.deltaManager.on(\"disconnect\", (reason) => {\n debugOp(`${index}: DIS: ${reason}`);\n });\n }\n }\n\n /**\n * Filter out the opened containers based on param.\n * @param containers - The container to filter to. If the array is empty, it means don't filter and return\n * all open containers.\n */\n private getContainers(containers: IContainer[]) {\n const containersToApply = containers.length === 0 ? Array.from(this.containers.keys()) : containers;\n return containersToApply.filter((container) => !container.closed);\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localCodeLoader.d.ts","sourceRoot":"","sources":["../src/localCodeLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACH,sBAAsB,EACtB,YAAY,EACZ,gCAAgC,EAChC,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EAC1B,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EAAyB,6BAA6B,EACzD,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAEhF,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAE7E,oBAAY,yBAAyB,GAAG,OAAO,CAC3C,sBAAsB,GACtB,6BAA6B,GAC7B,8BAA8B,GAC9B,gCAAgC,CAAC,CAAC;AAGtC,oBAAY,eAAe,GAAG,yBAAyB,GAAG,YAAY,CAAC;AAEvE;;;GAGG;AACH,qBAAa,eAAgB,YAAW,kBAAkB;IACtD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA8C;gBAG5E,cAAc,EAAE,QAAQ,CAAC,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC,EAC9D,cAAc,CAAC,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"localCodeLoader.d.ts","sourceRoot":"","sources":["../src/localCodeLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACH,sBAAsB,EACtB,YAAY,EACZ,gCAAgC,EAChC,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EAC1B,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EAAyB,6BAA6B,EACzD,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAEhF,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAE7E,oBAAY,yBAAyB,GAAG,OAAO,CAC3C,sBAAsB,GACtB,6BAA6B,GAC7B,8BAA8B,GAC9B,gCAAgC,CAAC,CAAC;AAGtC,oBAAY,eAAe,GAAG,yBAAyB,GAAG,YAAY,CAAC;AAEvE;;;GAGG;AACH,qBAAa,eAAgB,YAAW,kBAAkB;IACtD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA8C;gBAG5E,cAAc,EAAE,QAAQ,CAAC,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC,EAC9D,cAAc,CAAC,EAAE,wBAAwB;IA8C7C;;;;OAIG;IACU,IAAI,CACb,MAAM,EAAE,iBAAiB,GAC1B,OAAO,CAAC,uBAAuB,CAAC;CActC"}
|
package/dist/localCodeLoader.js
CHANGED
|
@@ -22,14 +22,10 @@ class LocalCodeLoader {
|
|
|
22
22
|
// Store the entry point against a unique id in the fluidPackageCache.
|
|
23
23
|
// For code details containing a package name, use the package name as the id.
|
|
24
24
|
// For code details containing a Fluid package, create a unique id from the package name and version.
|
|
25
|
-
let pkgId;
|
|
26
25
|
const source = entry[0];
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
else {
|
|
31
|
-
pkgId = `${source.package.name}@${source.package.version}`;
|
|
32
|
-
}
|
|
26
|
+
const pkgId = typeof source.package === "string"
|
|
27
|
+
? source.package
|
|
28
|
+
: `${source.package.name}@${source.package.version}`;
|
|
33
29
|
let fluidModule = entry[1];
|
|
34
30
|
if ((fluidModule === null || fluidModule === void 0 ? void 0 : fluidModule.fluidExport) === undefined) {
|
|
35
31
|
const maybeExport = fluidModule;
|
|
@@ -61,13 +57,9 @@ class LocalCodeLoader {
|
|
|
61
57
|
// Get the entry point for from the fluidPackageCache for the given code details.
|
|
62
58
|
// For code details containing a package name, use the package name as the id.
|
|
63
59
|
// For code details containing a Fluid package, create a unique id from the package name and version.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
pkdId = `${source.package.name}@${source.package.version}`;
|
|
70
|
-
}
|
|
60
|
+
const pkdId = typeof source.package === "string"
|
|
61
|
+
? source.package
|
|
62
|
+
: `${source.package.name}@${source.package.version}`;
|
|
71
63
|
const entryPoint = this.fluidPackageCache.get(pkdId);
|
|
72
64
|
if (entryPoint === undefined) {
|
|
73
65
|
throw new Error(`Cannot find package ${pkdId}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localCodeLoader.js","sourceRoot":"","sources":["../src/localCodeLoader.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;AAEH,oDAA4B;AAC5B,uDAAuF;AAYvF,iEAAuE;AAYvE;;;GAGG;AACH,MAAa,eAAe;IAGxB,YACI,cAA8D,EAC9D,cAAyC;QAJ5B,sBAAiB,GAAG,IAAI,GAAG,EAAmC,CAAC;QAM5E,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE;YAChC,sEAAsE;YACtE,8EAA8E;YAC9E,qGAAqG;YACrG,
|
|
1
|
+
{"version":3,"file":"localCodeLoader.js","sourceRoot":"","sources":["../src/localCodeLoader.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;AAEH,oDAA4B;AAC5B,uDAAuF;AAYvF,iEAAuE;AAYvE;;;GAGG;AACH,MAAa,eAAe;IAGxB,YACI,cAA8D,EAC9D,cAAyC;QAJ5B,sBAAiB,GAAG,IAAI,GAAG,EAAmC,CAAC;QAM5E,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE;YAChC,sEAAsE;YACtE,8EAA8E;YAC9E,qGAAqG;YACrG,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,KAAK,GAAG,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ;gBAC5C,CAAC,CAAC,MAAM,CAAC,OAAO;gBAChB,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACzD,IAAI,WAAW,GAAG,KAAK,CAAC,CAAC,CAAiB,CAAC;YAC3C,IAAI,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,WAAW,MAAK,SAAS,EAAE;gBACxC,MAAM,WAAW,GAAG,WAAwC,CAAC;gBAE7D,IAAI,WAAW,CAAC,eAAe,KAAK,SAAS,EAAE;oBAC3C,WAAW,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;iBAC9C;qBAAM;oBACH,IAAA,gBAAM,EAAC,WAAW,CAAC,sBAAsB,KAAK,SAAS,CAAC,CAAC;oBACzD,MAAM,cAAc,GAAG,IAAA,sCAAsB,EAAC,SAAS,EAAE,WAAW,CAAC,sBAAsB,CAAC,CAAC;oBAC7F,MAAM,mBAAmB,GAAG,KAAK,EAAE,OAAiB,EAAE,OAA8B,EAAE,EAAE,CACpF,OAAO,CAAC,mBAAmB,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;oBACvD,WAAW,GAAG;wBACV,WAAW,kCACH,WAAW,KACf,eAAe,EACX,IAAI,sDAA2C,CAC3C,cAAc,EACd,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EACxD,SAAS,EACT,CAAC,mBAAmB,CAAC,EACrB,cAAc,CACjB,GACR;qBACJ,CAAC;iBACL;aACJ;YAED,MAAM,cAAc,GAAG;gBACnB,MAAM,EAAE,WAAW;gBACnB,OAAO,EAAE,MAAM;aAClB,CAAC;YAEF,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;SACrD;IACL,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,IAAI,CACb,MAAyB;QAEzB,iFAAiF;QACjF,8EAA8E;QAC9E,qGAAqG;QACrG,MAAM,KAAK,GAAG,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ;YAC5C,CAAC,CAAC,MAAM,CAAC,OAAO;YAChB,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QAEzD,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,UAAU,KAAK,SAAS,EAAE;YAC1B,MAAM,IAAI,KAAK,CAAC,uBAAuB,KAAK,EAAE,CAAC,CAAC;SACnD;QACD,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ;AAxED,0CAwEC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport assert from \"assert\";\nimport { ContainerRuntimeFactoryWithDefaultDataStore } from \"@fluidframework/aqueduct\";\nimport {\n IProvideRuntimeFactory,\n IFluidModule,\n IProvideFluidCodeDetailsComparer,\n IFluidCodeDetails,\n ICodeDetailsLoader,\n IFluidModuleWithDetails,\n} from \"@fluidframework/container-definitions\";\nimport { IRequest } from \"@fluidframework/core-interfaces\";\nimport { IContainerRuntimeBase, IProvideFluidDataStoreFactory,\n IProvideFluidDataStoreRegistry } from \"@fluidframework/runtime-definitions\";\nimport { createDataStoreFactory } from \"@fluidframework/runtime-utils\";\nimport { IContainerRuntimeOptions } from \"@fluidframework/container-runtime\";\n\nexport type SupportedExportInterfaces = Partial<\n IProvideRuntimeFactory &\n IProvideFluidDataStoreFactory &\n IProvideFluidDataStoreRegistry &\n IProvideFluidCodeDetailsComparer>;\n\n// Represents the entry point for a Fluid container.\nexport type fluidEntryPoint = SupportedExportInterfaces | IFluidModule;\n\n/**\n * A simple code loader that caches a mapping of package name to a Fluid entry point.\n * On load, it retrieves the entry point matching the package name in the given code details.\n */\nexport class LocalCodeLoader implements ICodeDetailsLoader {\n private readonly fluidPackageCache = new Map<string, IFluidModuleWithDetails>();\n\n constructor(\n packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n runtimeOptions?: IContainerRuntimeOptions,\n ) {\n for (const entry of packageEntries) {\n // Store the entry point against a unique id in the fluidPackageCache.\n // For code details containing a package name, use the package name as the id.\n // For code details containing a Fluid package, create a unique id from the package name and version.\n const source = entry[0];\n const pkgId = typeof source.package === \"string\"\n ? source.package\n : `${source.package.name}@${source.package.version}`;\n let fluidModule = entry[1] as IFluidModule;\n if (fluidModule?.fluidExport === undefined) {\n const maybeExport = fluidModule as SupportedExportInterfaces;\n\n if (maybeExport.IRuntimeFactory !== undefined) {\n fluidModule = { fluidExport: maybeExport };\n } else {\n assert(maybeExport.IFluidDataStoreFactory !== undefined);\n const defaultFactory = createDataStoreFactory(\"default\", maybeExport.IFluidDataStoreFactory);\n const innerRequestHandler = async (request: IRequest, runtime: IContainerRuntimeBase) =>\n runtime.IFluidHandleContext.resolveHandle(request);\n fluidModule = {\n fluidExport: {\n ... maybeExport,\n IRuntimeFactory:\n new ContainerRuntimeFactoryWithDefaultDataStore(\n defaultFactory,\n [[defaultFactory.type, Promise.resolve(defaultFactory)]],\n undefined,\n [innerRequestHandler],\n runtimeOptions,\n ),\n },\n };\n }\n }\n\n const runtimeFactory = {\n module: fluidModule,\n details: source,\n };\n\n this.fluidPackageCache.set(pkgId, runtimeFactory);\n }\n }\n\n /**\n * It finds the entry point for the package name in the given source and return it\n * as a Fluid module.\n * @param source - Details of where to find chaincode\n */\n public async load(\n source: IFluidCodeDetails,\n ): Promise<IFluidModuleWithDetails> {\n // Get the entry point for from the fluidPackageCache for the given code details.\n // For code details containing a package name, use the package name as the id.\n // For code details containing a Fluid package, create a unique id from the package name and version.\n const pkdId = typeof source.package === \"string\"\n ? source.package\n : `${source.package.name}@${source.package.version}`;\n\n const entryPoint = this.fluidPackageCache.get(pkdId);\n if (entryPoint === undefined) {\n throw new Error(`Cannot find package ${pkdId}`);\n }\n return entryPoint;\n }\n}\n"]}
|
package/dist/packageVersion.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export declare const pkgName = "@fluidframework/test-utils";
|
|
8
|
-
export declare const pkgVersion = "2.0.0-internal.1.2.
|
|
8
|
+
export declare const pkgVersion = "2.0.0-internal.1.2.1";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,+BAA+B,CAAC;AACpD,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,+BAA+B,CAAC;AACpD,eAAO,MAAM,UAAU,yBAAyB,CAAC"}
|
package/dist/packageVersion.js
CHANGED
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.pkgVersion = exports.pkgName = void 0;
|
|
10
10
|
exports.pkgName = "@fluidframework/test-utils";
|
|
11
|
-
exports.pkgVersion = "2.0.0-internal.1.2.
|
|
11
|
+
exports.pkgVersion = "2.0.0-internal.1.2.1";
|
|
12
12
|
//# sourceMappingURL=packageVersion.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,4BAA4B,CAAC;AACvC,QAAA,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,4BAA4B,CAAC;AACvC,QAAA,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/test-utils\";\nexport const pkgVersion = \"2.0.0-internal.1.2.1\";\n"]}
|
|
@@ -46,17 +46,24 @@ export declare type ChannelFactoryRegistry = Iterable<[string | undefined, IChan
|
|
|
46
46
|
* with the object factories in the entry list. All the entries with an id other than undefined are passed to the
|
|
47
47
|
* Fluid object so that it can create a shared object for each.
|
|
48
48
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
49
|
+
* @example
|
|
50
|
+
* The following will create a Fluid object that creates and loads a SharedString and SharedDirectory.
|
|
51
|
+
* It will add SparseMatrix to the data store's factory so that it can be created later.
|
|
52
|
+
*
|
|
53
|
+
* ```typescript
|
|
54
|
+
* new TestFluidObjectFactory([
|
|
55
|
+
* [ "sharedString", SharedString.getFactory() ],
|
|
56
|
+
* [ "sharedDirectory", SharedDirectory.getFactory() ],
|
|
57
|
+
* [ undefined, SparseMatrix.getFactory() ],
|
|
58
|
+
* ]);
|
|
59
|
+
* ```
|
|
56
60
|
*
|
|
57
61
|
* The SharedString and SharedDirectory can be retrieved via getSharedObject() on the TestFluidObject as follows:
|
|
58
|
-
*
|
|
59
|
-
*
|
|
62
|
+
*
|
|
63
|
+
* ```typescript
|
|
64
|
+
* sharedString = testFluidObject.getSharedObject<SharedString>("sharedString");
|
|
65
|
+
* sharedDir = testFluidObject.getSharedObject<SharedDirectory>("sharedDirectory");
|
|
66
|
+
* ```
|
|
60
67
|
*/
|
|
61
68
|
export declare class TestFluidObjectFactory implements IFluidDataStoreFactory {
|
|
62
69
|
private readonly factoryEntries;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testFluidObject.d.ts","sourceRoot":"","sources":["../src/testFluidObject.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAqB,qBAAqB,EAAuB,MAAM,2BAA2B,CAAC;AAC1G,OAAO,EAAa,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACH,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACzB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAChG,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,gBAAgB;aAmChC,OAAO,EAAE,sBAAsB;aAC/B,OAAO,EAAE,sBAAsB;aAC/B,OAAO,EAAE,sBAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,iBAAiB;WArClB,IAAI,CACpB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EAC5C,QAAQ,EAAE,OAAO;IAQrB,IAAW,gBAAgB,SAE1B;IAED,IAAW,cAAc,SAExB;IAED,IAAW,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,CAA6B;IAE7D,IAAI,EAAG,UAAU,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IAEjD;;;;;;OAMG;gBAEiB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC9B,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC;IAKpE;;;OAGG;IACU,eAAe,CAAC,CAAC,GAAG,GAAG,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAehD,OAAO,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;YAI7C,UAAU;CAc3B;AAED,oBAAY,sBAAsB,GAAG,QAAQ,CAAC,CAAC,MAAM,GAAG,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;AAErF
|
|
1
|
+
{"version":3,"file":"testFluidObject.d.ts","sourceRoot":"","sources":["../src/testFluidObject.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAqB,qBAAqB,EAAuB,MAAM,2BAA2B,CAAC;AAC1G,OAAO,EAAa,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACH,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACzB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAChG,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,gBAAgB;aAmChC,OAAO,EAAE,sBAAsB;aAC/B,OAAO,EAAE,sBAAsB;aAC/B,OAAO,EAAE,sBAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,iBAAiB;WArClB,IAAI,CACpB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EAC5C,QAAQ,EAAE,OAAO;IAQrB,IAAW,gBAAgB,SAE1B;IAED,IAAW,cAAc,SAExB;IAED,IAAW,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,CAA6B;IAE7D,IAAI,EAAG,UAAU,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IAEjD;;;;;;OAMG;gBAEiB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC9B,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC;IAKpE;;;OAGG;IACU,eAAe,CAAC,CAAC,GAAG,GAAG,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAehD,OAAO,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;YAI7C,UAAU;CAc3B;AAED,oBAAY,sBAAsB,GAAG,QAAQ,CAAC,CAAC,MAAM,GAAG,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC;AAErF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,sBAAuB,YAAW,sBAAsB;IASrD,OAAO,CAAC,QAAQ,CAAC,cAAc;aACvB,IAAI;IATxB,IAAW,sBAAsB,SAAmB;IAEpD;;;;;OAKG;gBAC0B,cAAc,EAAE,sBAAsB,EAC/C,IAAI,SAA2B;IAEtC,oBAAoB,CAC7B,OAAO,EAAE,sBAAsB,EAC/B,QAAQ,EAAE,OAAO,GAClB,OAAO,CAAC,qBAAqB,CAAC;CAwCpC"}
|
package/dist/testFluidObject.js
CHANGED
|
@@ -77,17 +77,24 @@ exports.TestFluidObject = TestFluidObject;
|
|
|
77
77
|
* with the object factories in the entry list. All the entries with an id other than undefined are passed to the
|
|
78
78
|
* Fluid object so that it can create a shared object for each.
|
|
79
79
|
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
80
|
+
* @example
|
|
81
|
+
* The following will create a Fluid object that creates and loads a SharedString and SharedDirectory.
|
|
82
|
+
* It will add SparseMatrix to the data store's factory so that it can be created later.
|
|
83
|
+
*
|
|
84
|
+
* ```typescript
|
|
85
|
+
* new TestFluidObjectFactory([
|
|
86
|
+
* [ "sharedString", SharedString.getFactory() ],
|
|
87
|
+
* [ "sharedDirectory", SharedDirectory.getFactory() ],
|
|
88
|
+
* [ undefined, SparseMatrix.getFactory() ],
|
|
89
|
+
* ]);
|
|
90
|
+
* ```
|
|
87
91
|
*
|
|
88
92
|
* The SharedString and SharedDirectory can be retrieved via getSharedObject() on the TestFluidObject as follows:
|
|
89
|
-
*
|
|
90
|
-
*
|
|
93
|
+
*
|
|
94
|
+
* ```typescript
|
|
95
|
+
* sharedString = testFluidObject.getSharedObject<SharedString>("sharedString");
|
|
96
|
+
* sharedDir = testFluidObject.getSharedObject<SharedDirectory>("sharedDirectory");
|
|
97
|
+
* ```
|
|
91
98
|
*/
|
|
92
99
|
class TestFluidObjectFactory {
|
|
93
100
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testFluidObject.js","sourceRoot":"","sources":["../src/testFluidObject.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 { defaultFluidObjectRequestHandler } from \"@fluidframework/aqueduct\";\nimport { IRequest, IResponse, IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { FluidObjectHandle, FluidDataStoreRuntime, mixinRequestHandler } from \"@fluidframework/datastore\";\nimport { SharedMap, ISharedMap } from \"@fluidframework/map\";\nimport {\n IFluidDataStoreContext,\n IFluidDataStoreFactory,\n IFluidDataStoreChannel,\n} from \"@fluidframework/runtime-definitions\";\nimport { IFluidDataStoreRuntime, IChannelFactory } from \"@fluidframework/datastore-definitions\";\nimport { ITestFluidObject } from \"./interfaces\";\n\n/**\n * A test Fluid object that will create a shared object for each key-value pair in the factoryEntries passed to load.\n * The shared objects can be retrieved by passing the key of the entry to getSharedObject.\n * It exposes the IFluidDataStoreContext and IFluidDataStoreRuntime.\n */\nexport class TestFluidObject implements ITestFluidObject {\n public static async load(\n runtime: IFluidDataStoreRuntime,\n channel: IFluidDataStoreChannel,\n context: IFluidDataStoreContext,\n factoryEntries: Map<string, IChannelFactory>,\n existing: boolean,\n ) {\n const fluidObject = new TestFluidObject(runtime, channel, context, factoryEntries);\n await fluidObject.initialize(existing);\n\n return fluidObject;\n }\n\n public get ITestFluidObject() {\n return this;\n }\n\n public get IFluidLoadable() {\n return this;\n }\n\n public get handle(): IFluidHandle<this> { return this.innerHandle; }\n\n public root!: ISharedMap;\n private readonly innerHandle: IFluidHandle<this>;\n\n /**\n * Creates a new TestFluidObject.\n * @param runtime - The data store runtime.\n * @param context - The data store context.\n * @param factoryEntries - A list of id to IChannelFactory mapping. For each item in the list,\n * a shared object is created which can be retrieved by calling getSharedObject() with the id;\n */\n constructor(\n public readonly runtime: IFluidDataStoreRuntime,\n public readonly channel: IFluidDataStoreChannel,\n public readonly context: IFluidDataStoreContext,\n private readonly factoryEntriesMap: Map<string, IChannelFactory>,\n ) {\n this.innerHandle = new FluidObjectHandle(this, \"\", runtime.objectsRoutingContext);\n }\n\n /**\n * Retrieves a shared object with the given id.\n * @param id - The id of the shared object to retrieve.\n */\n public async getSharedObject<T = any>(id: string): Promise<T> {\n if (this.factoryEntriesMap === undefined) {\n throw new Error(\"Shared objects were not provided during creation.\");\n }\n\n for (const key of this.factoryEntriesMap.keys()) {\n if (key === id) {\n const handle = this.root.get<IFluidHandle>(id);\n return handle?.get() as unknown as T;\n }\n }\n\n throw new Error(`Shared object with id ${id} not found.`);\n }\n\n public async request(request: IRequest): Promise<IResponse> {\n return defaultFluidObjectRequestHandler(this, request);\n }\n\n private async initialize(existing: boolean) {\n if (!existing) {\n this.root = SharedMap.create(this.runtime, \"root\");\n\n this.factoryEntriesMap.forEach((sharedObjectFactory: IChannelFactory, key: string) => {\n const sharedObject = this.runtime.createChannel(key, sharedObjectFactory.type);\n this.root.set(key, sharedObject.handle);\n });\n\n this.root.bindToContext();\n }\n\n this.root = await this.runtime.getChannel(\"root\") as ISharedMap;\n }\n}\n\nexport type ChannelFactoryRegistry = Iterable<[string | undefined, IChannelFactory]>;\n\n/**\n * Creates a factory for a TestFluidObject with the given object factory entries. It creates a data store runtime\n * with the object factories in the entry list. All the entries with an id other than undefined are passed to the\n * Fluid object so that it can create a shared object for each.\n *\n * For example, the following will create a Fluid object that creates and loads a SharedString and SharedDirectory. It\n * will add SparseMatrix to the data store's factory so that it can be created later.\n * new TestFluidObjectFactory([\n * [ \"sharedString\", SharedString.getFactory() ],\n * [ \"sharedDirectory\", SharedDirectory.getFactory() ],\n* [ undefined, SparseMatrix.getFactory() ],\n * ]);\n *\n * The SharedString and SharedDirectory can be retrieved via getSharedObject() on the TestFluidObject as follows:\n * sharedString = testFluidObject.getSharedObject<SharedString>(\"sharedString\");\n * sharedDir = testFluidObject.getSharedObject<SharedDirectory>(\"sharedDirectory\");\n */\nexport class TestFluidObjectFactory implements IFluidDataStoreFactory {\n public get IFluidDataStoreFactory() { return this; }\n\n /**\n * Creates a new TestFluidObjectFactory.\n * @param factoryEntries - A list of id to IChannelFactory mapping. It creates a data store runtime with each\n * IChannelFactory. Entries with string ids are passed to the Fluid object so that it can create a shared object\n * for it.\n */\n constructor(private readonly factoryEntries: ChannelFactoryRegistry,\n public readonly type = \"TestFluidObjectFactory\") { }\n\n public async instantiateDataStore(\n context: IFluidDataStoreContext,\n existing: boolean,\n ): Promise<FluidDataStoreRuntime> {\n const dataTypes = new Map<string, IChannelFactory>();\n\n // Add SharedMap's factory which will be used to create the root map.\n const sharedMapFactory = SharedMap.getFactory();\n dataTypes.set(sharedMapFactory.type, sharedMapFactory);\n\n // Add the object factories to the list to be sent to data store runtime.\n for (const entry of this.factoryEntries) {\n const factory = entry[1];\n dataTypes.set(factory.type, factory);\n }\n\n // Create a map from the factory entries with entries that don't have the id as undefined. This will be\n // passed to the Fluid object.\n const factoryEntriesMapForObject = new Map<string, IChannelFactory>();\n for (const entry of this.factoryEntries) {\n const id = entry[0];\n if (id !== undefined) {\n factoryEntriesMapForObject.set(id, entry[1]);\n }\n }\n\n const runtimeClass = mixinRequestHandler(\n async (request: IRequest) => {\n const router = await routerP;\n return router.request(request);\n });\n\n const runtime = new runtimeClass(context, dataTypes, existing);\n const routerP = TestFluidObject.load(\n runtime,\n runtime,\n context,\n factoryEntriesMapForObject,\n existing,\n );\n\n return runtime;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"testFluidObject.js","sourceRoot":"","sources":["../src/testFluidObject.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 { defaultFluidObjectRequestHandler } from \"@fluidframework/aqueduct\";\nimport { IRequest, IResponse, IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { FluidObjectHandle, FluidDataStoreRuntime, mixinRequestHandler } from \"@fluidframework/datastore\";\nimport { SharedMap, ISharedMap } from \"@fluidframework/map\";\nimport {\n IFluidDataStoreContext,\n IFluidDataStoreFactory,\n IFluidDataStoreChannel,\n} from \"@fluidframework/runtime-definitions\";\nimport { IFluidDataStoreRuntime, IChannelFactory } from \"@fluidframework/datastore-definitions\";\nimport { ITestFluidObject } from \"./interfaces\";\n\n/**\n * A test Fluid object that will create a shared object for each key-value pair in the factoryEntries passed to load.\n * The shared objects can be retrieved by passing the key of the entry to getSharedObject.\n * It exposes the IFluidDataStoreContext and IFluidDataStoreRuntime.\n */\nexport class TestFluidObject implements ITestFluidObject {\n public static async load(\n runtime: IFluidDataStoreRuntime,\n channel: IFluidDataStoreChannel,\n context: IFluidDataStoreContext,\n factoryEntries: Map<string, IChannelFactory>,\n existing: boolean,\n ) {\n const fluidObject = new TestFluidObject(runtime, channel, context, factoryEntries);\n await fluidObject.initialize(existing);\n\n return fluidObject;\n }\n\n public get ITestFluidObject() {\n return this;\n }\n\n public get IFluidLoadable() {\n return this;\n }\n\n public get handle(): IFluidHandle<this> { return this.innerHandle; }\n\n public root!: ISharedMap;\n private readonly innerHandle: IFluidHandle<this>;\n\n /**\n * Creates a new TestFluidObject.\n * @param runtime - The data store runtime.\n * @param context - The data store context.\n * @param factoryEntries - A list of id to IChannelFactory mapping. For each item in the list,\n * a shared object is created which can be retrieved by calling getSharedObject() with the id;\n */\n constructor(\n public readonly runtime: IFluidDataStoreRuntime,\n public readonly channel: IFluidDataStoreChannel,\n public readonly context: IFluidDataStoreContext,\n private readonly factoryEntriesMap: Map<string, IChannelFactory>,\n ) {\n this.innerHandle = new FluidObjectHandle(this, \"\", runtime.objectsRoutingContext);\n }\n\n /**\n * Retrieves a shared object with the given id.\n * @param id - The id of the shared object to retrieve.\n */\n public async getSharedObject<T = any>(id: string): Promise<T> {\n if (this.factoryEntriesMap === undefined) {\n throw new Error(\"Shared objects were not provided during creation.\");\n }\n\n for (const key of this.factoryEntriesMap.keys()) {\n if (key === id) {\n const handle = this.root.get<IFluidHandle>(id);\n return handle?.get() as unknown as T;\n }\n }\n\n throw new Error(`Shared object with id ${id} not found.`);\n }\n\n public async request(request: IRequest): Promise<IResponse> {\n return defaultFluidObjectRequestHandler(this, request);\n }\n\n private async initialize(existing: boolean) {\n if (!existing) {\n this.root = SharedMap.create(this.runtime, \"root\");\n\n this.factoryEntriesMap.forEach((sharedObjectFactory: IChannelFactory, key: string) => {\n const sharedObject = this.runtime.createChannel(key, sharedObjectFactory.type);\n this.root.set(key, sharedObject.handle);\n });\n\n this.root.bindToContext();\n }\n\n this.root = await this.runtime.getChannel(\"root\") as ISharedMap;\n }\n}\n\nexport type ChannelFactoryRegistry = Iterable<[string | undefined, IChannelFactory]>;\n\n/**\n * Creates a factory for a TestFluidObject with the given object factory entries. It creates a data store runtime\n * with the object factories in the entry list. All the entries with an id other than undefined are passed to the\n * Fluid object so that it can create a shared object for each.\n *\n * @example\n * The following will create a Fluid object that creates and loads a SharedString and SharedDirectory.\n * It will add SparseMatrix to the data store's factory so that it can be created later.\n *\n * ```typescript\n * new TestFluidObjectFactory([\n * [ \"sharedString\", SharedString.getFactory() ],\n * [ \"sharedDirectory\", SharedDirectory.getFactory() ],\n * [ undefined, SparseMatrix.getFactory() ],\n * ]);\n * ```\n *\n * The SharedString and SharedDirectory can be retrieved via getSharedObject() on the TestFluidObject as follows:\n *\n * ```typescript\n * sharedString = testFluidObject.getSharedObject<SharedString>(\"sharedString\");\n * sharedDir = testFluidObject.getSharedObject<SharedDirectory>(\"sharedDirectory\");\n * ```\n */\nexport class TestFluidObjectFactory implements IFluidDataStoreFactory {\n public get IFluidDataStoreFactory() { return this; }\n\n /**\n * Creates a new TestFluidObjectFactory.\n * @param factoryEntries - A list of id to IChannelFactory mapping. It creates a data store runtime with each\n * IChannelFactory. Entries with string ids are passed to the Fluid object so that it can create a shared object\n * for it.\n */\n constructor(private readonly factoryEntries: ChannelFactoryRegistry,\n public readonly type = \"TestFluidObjectFactory\") { }\n\n public async instantiateDataStore(\n context: IFluidDataStoreContext,\n existing: boolean,\n ): Promise<FluidDataStoreRuntime> {\n const dataTypes = new Map<string, IChannelFactory>();\n\n // Add SharedMap's factory which will be used to create the root map.\n const sharedMapFactory = SharedMap.getFactory();\n dataTypes.set(sharedMapFactory.type, sharedMapFactory);\n\n // Add the object factories to the list to be sent to data store runtime.\n for (const entry of this.factoryEntries) {\n const factory = entry[1];\n dataTypes.set(factory.type, factory);\n }\n\n // Create a map from the factory entries with entries that don't have the id as undefined. This will be\n // passed to the Fluid object.\n const factoryEntriesMapForObject = new Map<string, IChannelFactory>();\n for (const entry of this.factoryEntries) {\n const id = entry[0];\n if (id !== undefined) {\n factoryEntriesMapForObject.set(id, entry[1]);\n }\n }\n\n const runtimeClass = mixinRequestHandler(\n async (request: IRequest) => {\n const router = await routerP;\n return router.request(request);\n });\n\n const runtime = new runtimeClass(context, dataTypes, existing);\n const routerP = TestFluidObject.load(\n runtime,\n runtime,\n context,\n factoryEntriesMapForObject,\n existing,\n );\n\n return runtime;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testObjectProvider.d.ts","sourceRoot":"","sources":["../src/testObjectProvider.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"testObjectProvider.d.ts","sourceRoot":"","sources":["../src/testObjectProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -263,12 +263,9 @@ class TestObjectProvider {
|
|
|
263
263
|
async ensureSynchronized(timeoutDuration) {
|
|
264
264
|
var _a, _b;
|
|
265
265
|
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
else {
|
|
270
|
-
return (_b = (_a = this._loaderContainerTracker).ensureSynchronizedWithTimeout) === null || _b === void 0 ? void 0 : _b.call(_a, timeoutDuration);
|
|
271
|
-
}
|
|
266
|
+
return !timeoutDuration
|
|
267
|
+
? this._loaderContainerTracker.ensureSynchronized()
|
|
268
|
+
: (_b = (_a = this._loaderContainerTracker).ensureSynchronizedWithTimeout) === null || _b === void 0 ? void 0 : _b.call(_a, timeoutDuration);
|
|
272
269
|
}
|
|
273
270
|
async waitContainerToCatchUp(container) {
|
|
274
271
|
// The original waitContainerToCatchUp() from container loader uses either Container.resume()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testObjectProvider.js","sourceRoot":"","sources":["../src/testObjectProvider.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 { IContainer, IHostLoader, IFluidCodeDetails } from \"@fluidframework/container-definitions\";\nimport { ITelemetryGenericEvent, ITelemetryBaseLogger, ITelemetryBaseEvent } from \"@fluidframework/common-definitions\";\nimport {\n ILoaderProps,\n Loader,\n waitContainerToCatchUp as waitContainerToCatchUp_original,\n} from \"@fluidframework/container-loader\";\nimport { IContainerRuntimeOptions } from \"@fluidframework/container-runtime\";\nimport { IRequestHeader } from \"@fluidframework/core-interfaces\";\nimport { IDocumentServiceFactory, IResolvedUrl, IUrlResolver } from \"@fluidframework/driver-definitions\";\nimport { ensureFluidResolvedUrl } from \"@fluidframework/driver-utils\";\nimport { ITestDriver, TestDriverTypes } from \"@fluidframework/test-driver-definitions\";\nimport { v4 as uuid } from \"uuid\";\nimport { ChildLogger, MultiSinkLogger, TelemetryLogger } from \"@fluidframework/telemetry-utils\";\nimport { LoaderContainerTracker } from \"./loaderContainerTracker\";\nimport { fluidEntryPoint, LocalCodeLoader } from \"./localCodeLoader\";\nimport { createAndAttachContainer } from \"./localLoader\";\nimport { ChannelFactoryRegistry } from \"./testFluidObject\";\n\nconst defaultCodeDetails: IFluidCodeDetails = {\n package: \"defaultTestPackage\",\n config: {},\n};\n\nexport interface IOpProcessingController {\n processIncoming(...containers: IContainer[]): Promise<void>;\n processOutgoing(...containers: IContainer[]): Promise<void>;\n pauseProcessing(...containers: IContainer[]): Promise<void>;\n resumeProcessing(...containers: IContainer[]): void;\n}\n\nexport interface ITestObjectProvider {\n createFluidEntryPoint: (testContainerConfig?: ITestContainerConfig) => fluidEntryPoint;\n createLoader(\n packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n loaderProps?: Partial<ILoaderProps>,\n ): IHostLoader;\n createContainer(entryPoint: fluidEntryPoint, loaderProps?: Partial<ILoaderProps>): Promise<IContainer>;\n loadContainer(\n entryPoint: fluidEntryPoint,\n loaderProps?: Partial<ILoaderProps>,\n requestHeader?: IRequestHeader,\n ): Promise<IContainer>;\n\n /**\n * Used to create a test Container. The Loader/ContainerRuntime/DataRuntime might be different versioned.\n * In generateLocalCompatTest(), this Container and its runtime will be arbitrarily-versioned.\n */\n makeTestLoader(testContainerConfig?: ITestContainerConfig): IHostLoader;\n makeTestContainer(testContainerConfig?: ITestContainerConfig): Promise<IContainer>;\n loadTestContainer(testContainerConfig?: ITestContainerConfig, requestHeader?: IRequestHeader): Promise<IContainer>;\n /**\n *\n * @param url - Resolved container URL\n */\n updateDocumentId(url: IResolvedUrl | undefined): void;\n\n logger: ITelemetryBaseLogger;\n documentServiceFactory: IDocumentServiceFactory;\n urlResolver: IUrlResolver;\n defaultCodeDetails: IFluidCodeDetails;\n opProcessingController: IOpProcessingController;\n\n ensureSynchronized(timeoutDuration?: number): Promise<void>;\n reset(): void;\n\n documentId: string;\n driver: ITestDriver;\n}\n\nexport enum DataObjectFactoryType {\n Primed, // default\n Test,\n}\n\nexport interface ITestContainerConfig {\n /** TestFluidDataObject instead of PrimedDataStore */\n fluidDataObjectType?: DataObjectFactoryType;\n\n /** An array of channel name and DDS factory pair to create on container creation time */\n registry?: ChannelFactoryRegistry;\n\n /** Container runtime options for the container instance */\n runtimeOptions?: IContainerRuntimeOptions;\n\n /** Loader options for the loader used to create containers */\n loaderProps?: Partial<ILoaderProps>;\n}\n\nexport const createDocumentId = (): string => uuid();\n\ninterface IDocumentIdStrategy {\n get(): string;\n update(resolvedUrl?: IResolvedUrl): void;\n reset(): void;\n}\n\n/**\n * Document ID is treated differently by test drivers. The key difference is in generating\n * a new container ID and accessing the container in multi-instance test cases.\n */\nfunction getDocumentIdStrategy(type?: TestDriverTypes): IDocumentIdStrategy {\n let documentId = createDocumentId();\n switch (type) {\n case \"odsp\":\n return {\n get: () => documentId,\n update: () => { }, // do not update the document ID in odsp test cases\n reset: () => { documentId = createDocumentId(); },\n };\n default:\n return {\n get: () => documentId,\n update: (resolvedUrl?: IResolvedUrl) => {\n // Extract the document ID from the resolved container's URL and reset the ID property\n ensureFluidResolvedUrl(resolvedUrl);\n documentId = resolvedUrl.id ?? documentId;\n },\n reset: () => { documentId = createDocumentId(); },\n };\n }\n}\n\n/**\n * This class tracks events. It allows specifying expected events, which will be looked for in order.\n * It also tracks all unexpected errors.\n * At any point you call reportAndClearTrackedEvents which will provide all unexpected errors, and\n * any expected events that have not occurred.\n */\nexport class EventAndErrorTrackingLogger extends TelemetryLogger {\n constructor(private readonly baseLogger: ITelemetryBaseLogger) {\n super();\n }\n\n private readonly expectedEvents: ({ index: number; event: ITelemetryGenericEvent | undefined; } | undefined)[] = [];\n private readonly unexpectedErrors: ITelemetryBaseEvent[] = [];\n\n public registerExpectedEvent(... orderedExpectedEvents: ITelemetryGenericEvent[]) {\n if (this.expectedEvents.length !== 0) {\n // we don't have to error here. just no reason not to. given the events must be\n // ordered it could be tricky to figure out problems around multiple registrations.\n throw new Error(\n \"Expected events already registered.\\n\"\n + \"Call reportAndClearTrackedEvents to clear them before registering more\");\n }\n this.expectedEvents.push(... orderedExpectedEvents.map((event, index) => ({ index, event })));\n }\n\n send(event: ITelemetryBaseEvent): void {\n const ee = this.expectedEvents[0]?.event;\n if (ee?.eventName === event.eventName) {\n let matches = true;\n for (const key of Object.keys(ee)) {\n if (ee[key] !== event[key]) {\n matches = false;\n break;\n }\n }\n if (matches) {\n // we found an expected event\n // so remove it from the list of expected events\n // and if it is an error, change it to generic\n // this helps keep our telemetry clear of\n // expected errors.\n this.expectedEvents.shift();\n if (event.category === \"error\") {\n event.category = \"generic\";\n }\n }\n }\n if (event.category === \"error\") {\n this.unexpectedErrors.push(event);\n }\n\n this.baseLogger.send(event);\n }\n\n public reportAndClearTrackedEvents() {\n const expectedNotFound = this.expectedEvents.splice(0, this.expectedEvents.length);\n const unexpectedErrors = this.unexpectedErrors.splice(0, this.unexpectedErrors.length);\n return {\n expectedNotFound,\n unexpectedErrors,\n };\n }\n}\n\n/**\n * Shared base class for test object provider. Contain code for loader and container creation and loading\n */\nexport class TestObjectProvider implements ITestObjectProvider {\n private _loaderContainerTracker = new LoaderContainerTracker();\n private _documentServiceFactory: IDocumentServiceFactory | undefined;\n private _urlResolver: IUrlResolver | undefined;\n private _logger: EventAndErrorTrackingLogger | undefined;\n private readonly _documentIdStrategy: IDocumentIdStrategy;\n // Since documentId doesn't change we can only create/make one container. Call the load functions instead.\n private _documentCreated = false;\n\n /**\n * Manage objects for loading and creating container, including the driver, loader, and OpProcessingController\n * @param createFluidEntryPoint - callback to create a fluidEntryPoint, with an optional set of channel name\n * and factory for TestFluidObject\n */\n constructor(\n public readonly LoaderConstructor: typeof Loader,\n public readonly driver: ITestDriver,\n public readonly createFluidEntryPoint: (testContainerConfig?: ITestContainerConfig) => fluidEntryPoint,\n ) {\n this._documentIdStrategy = getDocumentIdStrategy(driver.type);\n }\n\n get logger(): EventAndErrorTrackingLogger {\n if (this._logger === undefined) {\n this._logger = new EventAndErrorTrackingLogger(\n ChildLogger.create(getTestLogger?.(), undefined,\n {\n all: {\n driverType: this.driver.type,\n driverEndpointName: this.driver.endpointName,\n driverTenantName: this.driver.tenantName,\n driverUserIndex: this.driver.userIndex,\n },\n }));\n }\n return this._logger;\n }\n\n set logger(logger: EventAndErrorTrackingLogger) {\n this._logger = logger;\n }\n\n get documentServiceFactory() {\n if (!this._documentServiceFactory) {\n this._documentServiceFactory = this.driver.createDocumentServiceFactory();\n }\n return this._documentServiceFactory;\n }\n\n get urlResolver() {\n if (!this._urlResolver) {\n this._urlResolver = this.driver.createUrlResolver();\n }\n return this._urlResolver;\n }\n\n get documentId() {\n return this._documentIdStrategy.get();\n }\n\n get defaultCodeDetails() {\n return defaultCodeDetails;\n }\n\n get opProcessingController(): IOpProcessingController {\n return this._loaderContainerTracker;\n }\n\n /**\n * Create a loader. Containers created/loaded through this loader will be added to the OpProcessingController.\n *\n * Only the version of the loader will vary based on compat config. The version of\n * containerRuntime/dataRuntime used in fluidEntryPoint will be used as is from what is passed in.\n *\n * @param packageEntries - list of code details and fluidEntryPoint pairs.\n */\n public createLoader(\n packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n loaderProps?: Partial<ILoaderProps>,\n ) {\n const multiSinkLogger = new MultiSinkLogger();\n multiSinkLogger.addLogger(this.logger);\n if (loaderProps?.logger !== undefined) {\n multiSinkLogger.addLogger(loaderProps.logger);\n }\n\n const loader = new this.LoaderConstructor({\n ... loaderProps,\n logger: multiSinkLogger,\n codeLoader: loaderProps?.codeLoader ?? new LocalCodeLoader(packageEntries),\n urlResolver: loaderProps?.urlResolver ?? this.urlResolver,\n documentServiceFactory: loaderProps?.documentServiceFactory ?? this.documentServiceFactory,\n });\n this._loaderContainerTracker.add(loader);\n return loader;\n }\n\n /**\n * Create a container using a default document id and code details.\n * Container created is automatically added to the OpProcessingController to manage op flow\n *\n * Only the version of the loader will vary based on compat config. The version of\n * containerRuntime/dataRuntime used in fluidEntryPoint will be used as is from what is passed in.\n *\n * @param packageEntries - list of code details and fluidEntryPoint pairs.\n */\n public async createContainer(entryPoint: fluidEntryPoint, loaderProps?: Partial<ILoaderProps>) {\n if (this._documentCreated) {\n throw new Error(\n \"Only one container/document can be created. To load the container/document use loadContainer\");\n }\n const loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n const container = await createAndAttachContainer(\n defaultCodeDetails,\n loader,\n this.driver.createCreateNewRequest(this.documentId),\n );\n this._documentCreated = true;\n // r11s driver will generate a new ID for the new container.\n // update the document ID with the actual ID of the attached container.\n this._documentIdStrategy.update(container.resolvedUrl);\n return container;\n }\n\n public async loadContainer(\n entryPoint: fluidEntryPoint,\n loaderProps?: Partial<ILoaderProps>,\n requestHeader?: IRequestHeader): Promise<IContainer> {\n const loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n return loader.resolve({ url: await this.driver.createContainerUrl(this.documentId), headers: requestHeader });\n }\n\n /**\n * Make a test loader. Containers created/loaded through this loader will be added to the OpProcessingController.\n * The version of the loader/containerRuntime/dataRuntime may vary based on compat config of the current run\n * @param testContainerConfig - optional configuring the test Container\n */\n public makeTestLoader(testContainerConfig?: ITestContainerConfig) {\n return this.createLoader(\n [[defaultCodeDetails, this.createFluidEntryPoint(testContainerConfig)]],\n testContainerConfig?.loaderProps,\n );\n }\n\n /**\n * Make a container using a default document id and code details\n * Container loaded is automatically added to the OpProcessingController to manage op flow\n * @param testContainerConfig - optional configuring the test Container\n */\n public async makeTestContainer(testContainerConfig?: ITestContainerConfig): Promise<IContainer> {\n if (this._documentCreated) {\n throw new Error(\n \"Only one container/document can be created. To load the container/document use loadTestContainer\");\n }\n const loader = this.makeTestLoader(testContainerConfig);\n const container =\n await createAndAttachContainer(\n defaultCodeDetails,\n loader,\n this.driver.createCreateNewRequest(this.documentId));\n this._documentCreated = true;\n // r11s driver will generate a new ID for the new container.\n // update the document ID with the actual ID of the attached container.\n this._documentIdStrategy.update(container.resolvedUrl);\n return container;\n }\n\n /**\n * Load a container using a default document id and code details.\n * IContainer loaded is automatically added to the OpProcessingController to manage op flow\n * @param testContainerConfig - optional configuring the test Container\n * @param requestHeader - optional headers to be supplied to the loader\n */\n public async loadTestContainer(\n testContainerConfig?: ITestContainerConfig,\n requestHeader?: IRequestHeader,\n ): Promise<IContainer> {\n const loader = this.makeTestLoader(testContainerConfig);\n const container = await loader.resolve({\n url: await this.driver.createContainerUrl(this.documentId),\n headers: requestHeader,\n });\n await this.waitContainerToCatchUp(container);\n\n return container;\n }\n\n public reset() {\n this._loaderContainerTracker.reset();\n this._documentServiceFactory = undefined;\n this._urlResolver = undefined;\n this._documentIdStrategy.reset();\n const logError = getUnexpectedLogErrorException(this._logger);\n if (logError) {\n throw logError;\n }\n this._logger = undefined;\n this._documentCreated = false;\n }\n\n public async ensureSynchronized(timeoutDuration?: number) {\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n if (!timeoutDuration) {\n return this._loaderContainerTracker.ensureSynchronized();\n } else {\n return this._loaderContainerTracker.ensureSynchronizedWithTimeout?.(timeoutDuration);\n }\n }\n\n public async waitContainerToCatchUp(container: IContainer) {\n // The original waitContainerToCatchUp() from container loader uses either Container.resume()\n // or Container.connect() as part of its implementation. However, resume() was deprecated\n // and eventually replaced with connect(). To avoid issues during LTS compatibility testing\n // with older container versions issues, we use resume() when connect() is unavailable.\n if ((container as any).connect === undefined) {\n (container as any).connect = (container as any).resume;\n }\n\n return waitContainerToCatchUp_original(container);\n }\n\n updateDocumentId(resolvedUrl: IResolvedUrl | undefined) {\n this._documentIdStrategy.update(resolvedUrl);\n }\n\n public resetLoaderContainerTracker(syncSummarizerClients: boolean = false) {\n this._loaderContainerTracker.reset();\n this._loaderContainerTracker = new LoaderContainerTracker(syncSummarizerClients);\n }\n}\n\nexport function getUnexpectedLogErrorException(logger: EventAndErrorTrackingLogger | undefined, prefix?: string) {\n if (logger === undefined) {\n return;\n }\n const results = logger.reportAndClearTrackedEvents();\n if (results.unexpectedErrors.length > 0) {\n return new Error(\n `${prefix ?? \"\"}Unexpected Errors in Logs:\\n${JSON.stringify(results.unexpectedErrors, undefined, 2)}`);\n }\n if (results.expectedNotFound.length > 0) {\n return new Error(\n `${prefix ?? \"\"}Expected Events not found:\\n${JSON.stringify(results.expectedNotFound, undefined, 2)}`);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"testObjectProvider.js","sourceRoot":"","sources":["../src/testObjectProvider.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 { IContainer, IHostLoader, IFluidCodeDetails } from \"@fluidframework/container-definitions\";\nimport { ITelemetryGenericEvent, ITelemetryBaseLogger, ITelemetryBaseEvent } from \"@fluidframework/common-definitions\";\nimport {\n ILoaderProps,\n Loader,\n waitContainerToCatchUp as waitContainerToCatchUp_original,\n} from \"@fluidframework/container-loader\";\nimport { IContainerRuntimeOptions } from \"@fluidframework/container-runtime\";\nimport { IRequestHeader } from \"@fluidframework/core-interfaces\";\nimport { IDocumentServiceFactory, IResolvedUrl, IUrlResolver } from \"@fluidframework/driver-definitions\";\nimport { ensureFluidResolvedUrl } from \"@fluidframework/driver-utils\";\nimport { ITestDriver, TestDriverTypes } from \"@fluidframework/test-driver-definitions\";\nimport { v4 as uuid } from \"uuid\";\nimport { ChildLogger, MultiSinkLogger, TelemetryLogger } from \"@fluidframework/telemetry-utils\";\nimport { LoaderContainerTracker } from \"./loaderContainerTracker\";\nimport { fluidEntryPoint, LocalCodeLoader } from \"./localCodeLoader\";\nimport { createAndAttachContainer } from \"./localLoader\";\nimport { ChannelFactoryRegistry } from \"./testFluidObject\";\n\nconst defaultCodeDetails: IFluidCodeDetails = {\n package: \"defaultTestPackage\",\n config: {},\n};\n\nexport interface IOpProcessingController {\n processIncoming(...containers: IContainer[]): Promise<void>;\n processOutgoing(...containers: IContainer[]): Promise<void>;\n pauseProcessing(...containers: IContainer[]): Promise<void>;\n resumeProcessing(...containers: IContainer[]): void;\n}\n\nexport interface ITestObjectProvider {\n createFluidEntryPoint: (testContainerConfig?: ITestContainerConfig) => fluidEntryPoint;\n createLoader(\n packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n loaderProps?: Partial<ILoaderProps>,\n ): IHostLoader;\n createContainer(entryPoint: fluidEntryPoint, loaderProps?: Partial<ILoaderProps>): Promise<IContainer>;\n loadContainer(\n entryPoint: fluidEntryPoint,\n loaderProps?: Partial<ILoaderProps>,\n requestHeader?: IRequestHeader,\n ): Promise<IContainer>;\n\n /**\n * Used to create a test Container. The Loader/ContainerRuntime/DataRuntime might be different versioned.\n * In generateLocalCompatTest(), this Container and its runtime will be arbitrarily-versioned.\n */\n makeTestLoader(testContainerConfig?: ITestContainerConfig): IHostLoader;\n makeTestContainer(testContainerConfig?: ITestContainerConfig): Promise<IContainer>;\n loadTestContainer(testContainerConfig?: ITestContainerConfig, requestHeader?: IRequestHeader): Promise<IContainer>;\n /**\n *\n * @param url - Resolved container URL\n */\n updateDocumentId(url: IResolvedUrl | undefined): void;\n\n logger: ITelemetryBaseLogger;\n documentServiceFactory: IDocumentServiceFactory;\n urlResolver: IUrlResolver;\n defaultCodeDetails: IFluidCodeDetails;\n opProcessingController: IOpProcessingController;\n\n ensureSynchronized(timeoutDuration?: number): Promise<void>;\n reset(): void;\n\n documentId: string;\n driver: ITestDriver;\n}\n\nexport enum DataObjectFactoryType {\n Primed, // default\n Test,\n}\n\nexport interface ITestContainerConfig {\n /** TestFluidDataObject instead of PrimedDataStore */\n fluidDataObjectType?: DataObjectFactoryType;\n\n /** An array of channel name and DDS factory pair to create on container creation time */\n registry?: ChannelFactoryRegistry;\n\n /** Container runtime options for the container instance */\n runtimeOptions?: IContainerRuntimeOptions;\n\n /** Loader options for the loader used to create containers */\n loaderProps?: Partial<ILoaderProps>;\n}\n\nexport const createDocumentId = (): string => uuid();\n\ninterface IDocumentIdStrategy {\n get(): string;\n update(resolvedUrl?: IResolvedUrl): void;\n reset(): void;\n}\n\n/**\n * Document ID is treated differently by test drivers. The key difference is in generating\n * a new container ID and accessing the container in multi-instance test cases.\n */\nfunction getDocumentIdStrategy(type?: TestDriverTypes): IDocumentIdStrategy {\n let documentId = createDocumentId();\n switch (type) {\n case \"odsp\":\n return {\n get: () => documentId,\n update: () => { }, // do not update the document ID in odsp test cases\n reset: () => { documentId = createDocumentId(); },\n };\n default:\n return {\n get: () => documentId,\n update: (resolvedUrl?: IResolvedUrl) => {\n // Extract the document ID from the resolved container's URL and reset the ID property\n ensureFluidResolvedUrl(resolvedUrl);\n documentId = resolvedUrl.id ?? documentId;\n },\n reset: () => { documentId = createDocumentId(); },\n };\n }\n}\n\n/**\n * This class tracks events. It allows specifying expected events, which will be looked for in order.\n * It also tracks all unexpected errors.\n * At any point you call reportAndClearTrackedEvents which will provide all unexpected errors, and\n * any expected events that have not occurred.\n */\nexport class EventAndErrorTrackingLogger extends TelemetryLogger {\n constructor(private readonly baseLogger: ITelemetryBaseLogger) {\n super();\n }\n\n private readonly expectedEvents: ({ index: number; event: ITelemetryGenericEvent | undefined; } | undefined)[] = [];\n private readonly unexpectedErrors: ITelemetryBaseEvent[] = [];\n\n public registerExpectedEvent(... orderedExpectedEvents: ITelemetryGenericEvent[]) {\n if (this.expectedEvents.length !== 0) {\n // we don't have to error here. just no reason not to. given the events must be\n // ordered it could be tricky to figure out problems around multiple registrations.\n throw new Error(\n \"Expected events already registered.\\n\"\n + \"Call reportAndClearTrackedEvents to clear them before registering more\");\n }\n this.expectedEvents.push(... orderedExpectedEvents.map((event, index) => ({ index, event })));\n }\n\n send(event: ITelemetryBaseEvent): void {\n const ee = this.expectedEvents[0]?.event;\n if (ee?.eventName === event.eventName) {\n let matches = true;\n for (const key of Object.keys(ee)) {\n if (ee[key] !== event[key]) {\n matches = false;\n break;\n }\n }\n if (matches) {\n // we found an expected event\n // so remove it from the list of expected events\n // and if it is an error, change it to generic\n // this helps keep our telemetry clear of\n // expected errors.\n this.expectedEvents.shift();\n if (event.category === \"error\") {\n event.category = \"generic\";\n }\n }\n }\n if (event.category === \"error\") {\n this.unexpectedErrors.push(event);\n }\n\n this.baseLogger.send(event);\n }\n\n public reportAndClearTrackedEvents() {\n const expectedNotFound = this.expectedEvents.splice(0, this.expectedEvents.length);\n const unexpectedErrors = this.unexpectedErrors.splice(0, this.unexpectedErrors.length);\n return {\n expectedNotFound,\n unexpectedErrors,\n };\n }\n}\n\n/**\n * Shared base class for test object provider. Contain code for loader and container creation and loading\n */\nexport class TestObjectProvider implements ITestObjectProvider {\n private _loaderContainerTracker = new LoaderContainerTracker();\n private _documentServiceFactory: IDocumentServiceFactory | undefined;\n private _urlResolver: IUrlResolver | undefined;\n private _logger: EventAndErrorTrackingLogger | undefined;\n private readonly _documentIdStrategy: IDocumentIdStrategy;\n // Since documentId doesn't change we can only create/make one container. Call the load functions instead.\n private _documentCreated = false;\n\n /**\n * Manage objects for loading and creating container, including the driver, loader, and OpProcessingController\n * @param createFluidEntryPoint - callback to create a fluidEntryPoint, with an optional set of channel name\n * and factory for TestFluidObject\n */\n constructor(\n public readonly LoaderConstructor: typeof Loader,\n public readonly driver: ITestDriver,\n public readonly createFluidEntryPoint: (testContainerConfig?: ITestContainerConfig) => fluidEntryPoint,\n ) {\n this._documentIdStrategy = getDocumentIdStrategy(driver.type);\n }\n\n get logger(): EventAndErrorTrackingLogger {\n if (this._logger === undefined) {\n this._logger = new EventAndErrorTrackingLogger(\n ChildLogger.create(getTestLogger?.(), undefined,\n {\n all: {\n driverType: this.driver.type,\n driverEndpointName: this.driver.endpointName,\n driverTenantName: this.driver.tenantName,\n driverUserIndex: this.driver.userIndex,\n },\n }));\n }\n return this._logger;\n }\n\n set logger(logger: EventAndErrorTrackingLogger) {\n this._logger = logger;\n }\n\n get documentServiceFactory() {\n if (!this._documentServiceFactory) {\n this._documentServiceFactory = this.driver.createDocumentServiceFactory();\n }\n return this._documentServiceFactory;\n }\n\n get urlResolver() {\n if (!this._urlResolver) {\n this._urlResolver = this.driver.createUrlResolver();\n }\n return this._urlResolver;\n }\n\n get documentId() {\n return this._documentIdStrategy.get();\n }\n\n get defaultCodeDetails() {\n return defaultCodeDetails;\n }\n\n get opProcessingController(): IOpProcessingController {\n return this._loaderContainerTracker;\n }\n\n /**\n * Create a loader. Containers created/loaded through this loader will be added to the OpProcessingController.\n *\n * Only the version of the loader will vary based on compat config. The version of\n * containerRuntime/dataRuntime used in fluidEntryPoint will be used as is from what is passed in.\n *\n * @param packageEntries - list of code details and fluidEntryPoint pairs.\n */\n public createLoader(\n packageEntries: Iterable<[IFluidCodeDetails, fluidEntryPoint]>,\n loaderProps?: Partial<ILoaderProps>,\n ) {\n const multiSinkLogger = new MultiSinkLogger();\n multiSinkLogger.addLogger(this.logger);\n if (loaderProps?.logger !== undefined) {\n multiSinkLogger.addLogger(loaderProps.logger);\n }\n\n const loader = new this.LoaderConstructor({\n ... loaderProps,\n logger: multiSinkLogger,\n codeLoader: loaderProps?.codeLoader ?? new LocalCodeLoader(packageEntries),\n urlResolver: loaderProps?.urlResolver ?? this.urlResolver,\n documentServiceFactory: loaderProps?.documentServiceFactory ?? this.documentServiceFactory,\n });\n this._loaderContainerTracker.add(loader);\n return loader;\n }\n\n /**\n * Create a container using a default document id and code details.\n * Container created is automatically added to the OpProcessingController to manage op flow\n *\n * Only the version of the loader will vary based on compat config. The version of\n * containerRuntime/dataRuntime used in fluidEntryPoint will be used as is from what is passed in.\n *\n * @param packageEntries - list of code details and fluidEntryPoint pairs.\n */\n public async createContainer(entryPoint: fluidEntryPoint, loaderProps?: Partial<ILoaderProps>) {\n if (this._documentCreated) {\n throw new Error(\n \"Only one container/document can be created. To load the container/document use loadContainer\");\n }\n const loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n const container = await createAndAttachContainer(\n defaultCodeDetails,\n loader,\n this.driver.createCreateNewRequest(this.documentId),\n );\n this._documentCreated = true;\n // r11s driver will generate a new ID for the new container.\n // update the document ID with the actual ID of the attached container.\n this._documentIdStrategy.update(container.resolvedUrl);\n return container;\n }\n\n public async loadContainer(\n entryPoint: fluidEntryPoint,\n loaderProps?: Partial<ILoaderProps>,\n requestHeader?: IRequestHeader): Promise<IContainer> {\n const loader = this.createLoader([[defaultCodeDetails, entryPoint]], loaderProps);\n return loader.resolve({ url: await this.driver.createContainerUrl(this.documentId), headers: requestHeader });\n }\n\n /**\n * Make a test loader. Containers created/loaded through this loader will be added to the OpProcessingController.\n * The version of the loader/containerRuntime/dataRuntime may vary based on compat config of the current run\n * @param testContainerConfig - optional configuring the test Container\n */\n public makeTestLoader(testContainerConfig?: ITestContainerConfig) {\n return this.createLoader(\n [[defaultCodeDetails, this.createFluidEntryPoint(testContainerConfig)]],\n testContainerConfig?.loaderProps,\n );\n }\n\n /**\n * Make a container using a default document id and code details\n * Container loaded is automatically added to the OpProcessingController to manage op flow\n * @param testContainerConfig - optional configuring the test Container\n */\n public async makeTestContainer(testContainerConfig?: ITestContainerConfig): Promise<IContainer> {\n if (this._documentCreated) {\n throw new Error(\n \"Only one container/document can be created. To load the container/document use loadTestContainer\");\n }\n const loader = this.makeTestLoader(testContainerConfig);\n const container =\n await createAndAttachContainer(\n defaultCodeDetails,\n loader,\n this.driver.createCreateNewRequest(this.documentId));\n this._documentCreated = true;\n // r11s driver will generate a new ID for the new container.\n // update the document ID with the actual ID of the attached container.\n this._documentIdStrategy.update(container.resolvedUrl);\n return container;\n }\n\n /**\n * Load a container using a default document id and code details.\n * IContainer loaded is automatically added to the OpProcessingController to manage op flow\n * @param testContainerConfig - optional configuring the test Container\n * @param requestHeader - optional headers to be supplied to the loader\n */\n public async loadTestContainer(\n testContainerConfig?: ITestContainerConfig,\n requestHeader?: IRequestHeader,\n ): Promise<IContainer> {\n const loader = this.makeTestLoader(testContainerConfig);\n const container = await loader.resolve({\n url: await this.driver.createContainerUrl(this.documentId),\n headers: requestHeader,\n });\n await this.waitContainerToCatchUp(container);\n\n return container;\n }\n\n public reset() {\n this._loaderContainerTracker.reset();\n this._documentServiceFactory = undefined;\n this._urlResolver = undefined;\n this._documentIdStrategy.reset();\n const logError = getUnexpectedLogErrorException(this._logger);\n if (logError) {\n throw logError;\n }\n this._logger = undefined;\n this._documentCreated = false;\n }\n\n public async ensureSynchronized(timeoutDuration?: number): Promise<void> {\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n return !timeoutDuration\n ? this._loaderContainerTracker.ensureSynchronized()\n : this._loaderContainerTracker.ensureSynchronizedWithTimeout?.(timeoutDuration);\n }\n\n public async waitContainerToCatchUp(container: IContainer) {\n // The original waitContainerToCatchUp() from container loader uses either Container.resume()\n // or Container.connect() as part of its implementation. However, resume() was deprecated\n // and eventually replaced with connect(). To avoid issues during LTS compatibility testing\n // with older container versions issues, we use resume() when connect() is unavailable.\n if ((container as any).connect === undefined) {\n (container as any).connect = (container as any).resume;\n }\n\n return waitContainerToCatchUp_original(container);\n }\n\n updateDocumentId(resolvedUrl: IResolvedUrl | undefined) {\n this._documentIdStrategy.update(resolvedUrl);\n }\n\n public resetLoaderContainerTracker(syncSummarizerClients: boolean = false) {\n this._loaderContainerTracker.reset();\n this._loaderContainerTracker = new LoaderContainerTracker(syncSummarizerClients);\n }\n}\n\nexport function getUnexpectedLogErrorException(logger: EventAndErrorTrackingLogger | undefined, prefix?: string) {\n if (logger === undefined) {\n return;\n }\n const results = logger.reportAndClearTrackedEvents();\n if (results.unexpectedErrors.length > 0) {\n return new Error(\n `${prefix ?? \"\"}Unexpected Errors in Logs:\\n${JSON.stringify(results.unexpectedErrors, undefined, 2)}`);\n }\n if (results.expectedNotFound.length > 0) {\n return new Error(\n `${prefix ?? \"\"}Expected Events not found:\\n${JSON.stringify(results.expectedNotFound, undefined, 2)}`);\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/test-utils",
|
|
3
|
-
"version": "2.0.0-internal.1.2.
|
|
3
|
+
"version": "2.0.0-internal.1.2.1",
|
|
4
4
|
"description": "Utilities for Fluid tests",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -55,28 +55,28 @@
|
|
|
55
55
|
"temp-directory": "nyc/.nyc_output"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@fluidframework/aqueduct": "2.0.0-internal.1.2.
|
|
58
|
+
"@fluidframework/aqueduct": "^2.0.0-internal.1.2.1",
|
|
59
59
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
60
60
|
"@fluidframework/common-utils": "^1.0.0",
|
|
61
|
-
"@fluidframework/container-definitions": "2.0.0-internal.1.2.
|
|
62
|
-
"@fluidframework/container-loader": "2.0.0-internal.1.2.
|
|
63
|
-
"@fluidframework/container-runtime": "2.0.0-internal.1.2.
|
|
64
|
-
"@fluidframework/container-runtime-definitions": "2.0.0-internal.1.2.
|
|
65
|
-
"@fluidframework/core-interfaces": "2.0.0-internal.1.2.
|
|
66
|
-
"@fluidframework/datastore": "2.0.0-internal.1.2.
|
|
67
|
-
"@fluidframework/datastore-definitions": "2.0.0-internal.1.2.
|
|
68
|
-
"@fluidframework/driver-definitions": "2.0.0-internal.1.2.
|
|
69
|
-
"@fluidframework/driver-utils": "2.0.0-internal.1.2.
|
|
70
|
-
"@fluidframework/local-driver": "2.0.0-internal.1.2.
|
|
71
|
-
"@fluidframework/map": "2.0.0-internal.1.2.
|
|
61
|
+
"@fluidframework/container-definitions": "^2.0.0-internal.1.2.1",
|
|
62
|
+
"@fluidframework/container-loader": "^2.0.0-internal.1.2.1",
|
|
63
|
+
"@fluidframework/container-runtime": "^2.0.0-internal.1.2.1",
|
|
64
|
+
"@fluidframework/container-runtime-definitions": "^2.0.0-internal.1.2.1",
|
|
65
|
+
"@fluidframework/core-interfaces": "^2.0.0-internal.1.2.1",
|
|
66
|
+
"@fluidframework/datastore": "^2.0.0-internal.1.2.1",
|
|
67
|
+
"@fluidframework/datastore-definitions": "^2.0.0-internal.1.2.1",
|
|
68
|
+
"@fluidframework/driver-definitions": "^2.0.0-internal.1.2.1",
|
|
69
|
+
"@fluidframework/driver-utils": "^2.0.0-internal.1.2.1",
|
|
70
|
+
"@fluidframework/local-driver": "^2.0.0-internal.1.2.1",
|
|
71
|
+
"@fluidframework/map": "^2.0.0-internal.1.2.1",
|
|
72
72
|
"@fluidframework/protocol-definitions": "^1.0.0",
|
|
73
|
-
"@fluidframework/request-handler": "2.0.0-internal.1.2.
|
|
74
|
-
"@fluidframework/routerlicious-driver": "2.0.0-internal.1.2.
|
|
75
|
-
"@fluidframework/runtime-definitions": "2.0.0-internal.1.2.
|
|
76
|
-
"@fluidframework/runtime-utils": "2.0.0-internal.1.2.
|
|
77
|
-
"@fluidframework/telemetry-utils": "2.0.0-internal.1.2.
|
|
78
|
-
"@fluidframework/test-driver-definitions": "2.0.0-internal.1.2.
|
|
79
|
-
"@fluidframework/test-runtime-utils": "2.0.0-internal.1.2.
|
|
73
|
+
"@fluidframework/request-handler": "^2.0.0-internal.1.2.1",
|
|
74
|
+
"@fluidframework/routerlicious-driver": "^2.0.0-internal.1.2.1",
|
|
75
|
+
"@fluidframework/runtime-definitions": "^2.0.0-internal.1.2.1",
|
|
76
|
+
"@fluidframework/runtime-utils": "^2.0.0-internal.1.2.1",
|
|
77
|
+
"@fluidframework/telemetry-utils": "^2.0.0-internal.1.2.1",
|
|
78
|
+
"@fluidframework/test-driver-definitions": "^2.0.0-internal.1.2.1",
|
|
79
|
+
"@fluidframework/test-runtime-utils": "^2.0.0-internal.1.2.1",
|
|
80
80
|
"best-random": "^1.0.0",
|
|
81
81
|
"debug": "^4.1.1",
|
|
82
82
|
"uuid": "^8.3.1"
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"devDependencies": {
|
|
85
85
|
"@fluidframework/build-common": "^1.0.0",
|
|
86
86
|
"@fluidframework/build-tools": "^0.4.4000",
|
|
87
|
-
"@fluidframework/eslint-config-fluid": "^0.
|
|
87
|
+
"@fluidframework/eslint-config-fluid": "^1.0.0",
|
|
88
88
|
"@fluidframework/test-utils-previous": "npm:@fluidframework/test-utils@^1.0.0",
|
|
89
89
|
"@microsoft/api-extractor": "^7.22.2",
|
|
90
90
|
"@rushstack/eslint-config": "^2.5.1",
|
|
@@ -156,7 +156,7 @@ export class LoaderContainerTracker implements IOpProcessingController {
|
|
|
156
156
|
/**
|
|
157
157
|
* Ensure all tracked containers are synchronized
|
|
158
158
|
*/
|
|
159
|
-
public async ensureSynchronized(...containers: IContainer[]) {
|
|
159
|
+
public async ensureSynchronized(...containers: IContainer[]): Promise<void> {
|
|
160
160
|
await this.processSynchronized(undefined, ...containers);
|
|
161
161
|
}
|
|
162
162
|
|
|
@@ -169,14 +169,22 @@ export class LoaderContainerTracker implements IOpProcessingController {
|
|
|
169
169
|
|
|
170
170
|
/**
|
|
171
171
|
* Make sure all the tracked containers are synchronized.
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
* -
|
|
178
|
-
*
|
|
179
|
-
*
|
|
172
|
+
*
|
|
173
|
+
* No isDirty (non-readonly) containers
|
|
174
|
+
*
|
|
175
|
+
* No extra clientId in quorum of any container that is not tracked and still opened.
|
|
176
|
+
*
|
|
177
|
+
* - i.e. no pending Join/Leave message.
|
|
178
|
+
*
|
|
179
|
+
* No unresolved proposal (minSeqNum \>= lastProposalSeqNum)
|
|
180
|
+
*
|
|
181
|
+
* lastSequenceNumber of all container is the same
|
|
182
|
+
*
|
|
183
|
+
* clientSequenceNumberObserved is the same as clientSequenceNumber sent
|
|
184
|
+
*
|
|
185
|
+
* - this overlaps with !isDirty, but include task scheduler ops.
|
|
186
|
+
*
|
|
187
|
+
* - Trailing NoOp is tracked and don't count as pending ops.
|
|
180
188
|
*/
|
|
181
189
|
private async processSynchronized(timeoutDuration: number | undefined, ...containers: IContainer[]) {
|
|
182
190
|
const start = Date.now();
|
package/src/localCodeLoader.ts
CHANGED
|
@@ -43,14 +43,10 @@ export class LocalCodeLoader implements ICodeDetailsLoader {
|
|
|
43
43
|
// Store the entry point against a unique id in the fluidPackageCache.
|
|
44
44
|
// For code details containing a package name, use the package name as the id.
|
|
45
45
|
// For code details containing a Fluid package, create a unique id from the package name and version.
|
|
46
|
-
let pkgId: string;
|
|
47
|
-
|
|
48
46
|
const source = entry[0];
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
pkgId = `${source.package.name}@${source.package.version}`;
|
|
53
|
-
}
|
|
47
|
+
const pkgId = typeof source.package === "string"
|
|
48
|
+
? source.package
|
|
49
|
+
: `${source.package.name}@${source.package.version}`;
|
|
54
50
|
let fluidModule = entry[1] as IFluidModule;
|
|
55
51
|
if (fluidModule?.fluidExport === undefined) {
|
|
56
52
|
const maybeExport = fluidModule as SupportedExportInterfaces;
|
|
@@ -98,13 +94,9 @@ export class LocalCodeLoader implements ICodeDetailsLoader {
|
|
|
98
94
|
// Get the entry point for from the fluidPackageCache for the given code details.
|
|
99
95
|
// For code details containing a package name, use the package name as the id.
|
|
100
96
|
// For code details containing a Fluid package, create a unique id from the package name and version.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
pkdId = source.package;
|
|
105
|
-
} else {
|
|
106
|
-
pkdId = `${source.package.name}@${source.package.version}`;
|
|
107
|
-
}
|
|
97
|
+
const pkdId = typeof source.package === "string"
|
|
98
|
+
? source.package
|
|
99
|
+
: `${source.package.name}@${source.package.version}`;
|
|
108
100
|
|
|
109
101
|
const entryPoint = this.fluidPackageCache.get(pkdId);
|
|
110
102
|
if (entryPoint === undefined) {
|
package/src/packageVersion.ts
CHANGED
package/src/testFluidObject.ts
CHANGED
|
@@ -109,17 +109,24 @@ export type ChannelFactoryRegistry = Iterable<[string | undefined, IChannelFacto
|
|
|
109
109
|
* with the object factories in the entry list. All the entries with an id other than undefined are passed to the
|
|
110
110
|
* Fluid object so that it can create a shared object for each.
|
|
111
111
|
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
112
|
+
* @example
|
|
113
|
+
* The following will create a Fluid object that creates and loads a SharedString and SharedDirectory.
|
|
114
|
+
* It will add SparseMatrix to the data store's factory so that it can be created later.
|
|
115
|
+
*
|
|
116
|
+
* ```typescript
|
|
117
|
+
* new TestFluidObjectFactory([
|
|
118
|
+
* [ "sharedString", SharedString.getFactory() ],
|
|
119
|
+
* [ "sharedDirectory", SharedDirectory.getFactory() ],
|
|
120
|
+
* [ undefined, SparseMatrix.getFactory() ],
|
|
121
|
+
* ]);
|
|
122
|
+
* ```
|
|
119
123
|
*
|
|
120
124
|
* The SharedString and SharedDirectory can be retrieved via getSharedObject() on the TestFluidObject as follows:
|
|
121
|
-
*
|
|
122
|
-
*
|
|
125
|
+
*
|
|
126
|
+
* ```typescript
|
|
127
|
+
* sharedString = testFluidObject.getSharedObject<SharedString>("sharedString");
|
|
128
|
+
* sharedDir = testFluidObject.getSharedObject<SharedDirectory>("sharedDirectory");
|
|
129
|
+
* ```
|
|
123
130
|
*/
|
|
124
131
|
export class TestFluidObjectFactory implements IFluidDataStoreFactory {
|
|
125
132
|
public get IFluidDataStoreFactory() { return this; }
|
|
@@ -393,13 +393,11 @@ export class TestObjectProvider implements ITestObjectProvider {
|
|
|
393
393
|
this._documentCreated = false;
|
|
394
394
|
}
|
|
395
395
|
|
|
396
|
-
public async ensureSynchronized(timeoutDuration?: number) {
|
|
396
|
+
public async ensureSynchronized(timeoutDuration?: number): Promise<void> {
|
|
397
397
|
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
return this._loaderContainerTracker.ensureSynchronizedWithTimeout?.(timeoutDuration);
|
|
402
|
-
}
|
|
398
|
+
return !timeoutDuration
|
|
399
|
+
? this._loaderContainerTracker.ensureSynchronized()
|
|
400
|
+
: this._loaderContainerTracker.ensureSynchronizedWithTimeout?.(timeoutDuration);
|
|
403
401
|
}
|
|
404
402
|
|
|
405
403
|
public async waitContainerToCatchUp(container: IContainer) {
|