@fluidframework/tree 2.63.0-359962 → 2.63.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +81 -0
- package/api-report/tree.alpha.api.md +7 -8
- package/dist/codec/codec.d.ts +10 -27
- package/dist/codec/codec.d.ts.map +1 -1
- package/dist/codec/codec.js +9 -28
- package/dist/codec/codec.js.map +1 -1
- package/dist/codec/versioned/codec.d.ts +6 -5
- package/dist/codec/versioned/codec.d.ts.map +1 -1
- package/dist/codec/versioned/codec.js +4 -4
- package/dist/codec/versioned/codec.js.map +1 -1
- package/dist/core/tree/detachedFieldIndex.js +1 -1
- package/dist/core/tree/detachedFieldIndex.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexCodecs.js +1 -1
- package/dist/core/tree/detachedFieldIndexCodecs.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts +4 -3
- package/dist/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/codecs.js +2 -2
- package/dist/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js +1 -1
- package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/dist/feature-libraries/schema-index/codec.d.ts +6 -5
- package/dist/feature-libraries/schema-index/codec.d.ts.map +1 -1
- package/dist/feature-libraries/schema-index/codec.js +3 -3
- package/dist/feature-libraries/schema-index/codec.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/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js +4 -4
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.js +1 -1
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeCodecs.js +1 -1
- package/dist/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/dist/shared-tree/treeAlpha.d.ts +1 -1
- package/dist/shared-tree/treeAlpha.d.ts.map +1 -1
- package/dist/shared-tree/treeAlpha.js +1 -1
- package/dist/shared-tree/treeAlpha.js.map +1 -1
- package/dist/shared-tree/treeCheckout.js +1 -1
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/defaultResubmitMachine.d.ts.map +1 -1
- package/dist/shared-tree-core/defaultResubmitMachine.js +3 -2
- package/dist/shared-tree-core/defaultResubmitMachine.js.map +1 -1
- package/dist/simple-tree/api/storedSchema.d.ts +4 -3
- package/dist/simple-tree/api/storedSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/storedSchema.js +3 -3
- package/dist/simple-tree/api/storedSchema.js.map +1 -1
- package/dist/simple-tree/core/allowedTypes.d.ts.map +1 -1
- package/dist/simple-tree/core/allowedTypes.js +1 -1
- package/dist/simple-tree/core/allowedTypes.js.map +1 -1
- package/dist/simple-tree/prepareForInsertion.js +1 -1
- package/dist/simple-tree/prepareForInsertion.js.map +1 -1
- package/dist/treeFactory.d.ts.map +1 -1
- package/dist/treeFactory.js +13 -4
- package/dist/treeFactory.js.map +1 -1
- package/lib/codec/codec.d.ts +10 -27
- package/lib/codec/codec.d.ts.map +1 -1
- package/lib/codec/codec.js +8 -27
- package/lib/codec/codec.js.map +1 -1
- package/lib/codec/versioned/codec.d.ts +6 -5
- package/lib/codec/versioned/codec.d.ts.map +1 -1
- package/lib/codec/versioned/codec.js +4 -4
- package/lib/codec/versioned/codec.js.map +1 -1
- package/lib/core/tree/detachedFieldIndex.js +1 -1
- package/lib/core/tree/detachedFieldIndex.js.map +1 -1
- package/lib/core/tree/detachedFieldIndexCodecs.js +1 -1
- package/lib/core/tree/detachedFieldIndexCodecs.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts +4 -3
- package/lib/feature-libraries/chunked-forest/codec/codecs.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/codec/codecs.js +2 -2
- package/lib/feature-libraries/chunked-forest/codec/codecs.js.map +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js +1 -1
- package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
- package/lib/feature-libraries/schema-index/codec.d.ts +6 -5
- package/lib/feature-libraries/schema-index/codec.d.ts.map +1 -1
- package/lib/feature-libraries/schema-index/codec.js +3 -3
- package/lib/feature-libraries/schema-index/codec.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js +4 -4
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.js +1 -1
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/sharedTreeChangeCodecs.js +1 -1
- package/lib/shared-tree/sharedTreeChangeCodecs.js.map +1 -1
- package/lib/shared-tree/treeAlpha.d.ts +1 -1
- package/lib/shared-tree/treeAlpha.d.ts.map +1 -1
- package/lib/shared-tree/treeAlpha.js +1 -1
- package/lib/shared-tree/treeAlpha.js.map +1 -1
- package/lib/shared-tree/treeCheckout.js +1 -1
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/defaultResubmitMachine.d.ts.map +1 -1
- package/lib/shared-tree-core/defaultResubmitMachine.js +3 -2
- package/lib/shared-tree-core/defaultResubmitMachine.js.map +1 -1
- package/lib/simple-tree/api/storedSchema.d.ts +4 -3
- package/lib/simple-tree/api/storedSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/storedSchema.js +3 -3
- package/lib/simple-tree/api/storedSchema.js.map +1 -1
- package/lib/simple-tree/core/allowedTypes.d.ts.map +1 -1
- package/lib/simple-tree/core/allowedTypes.js +1 -1
- package/lib/simple-tree/core/allowedTypes.js.map +1 -1
- package/lib/simple-tree/prepareForInsertion.js +1 -1
- package/lib/simple-tree/prepareForInsertion.js.map +1 -1
- package/lib/treeFactory.d.ts.map +1 -1
- package/lib/treeFactory.js +13 -4
- package/lib/treeFactory.js.map +1 -1
- package/package.json +21 -20
- package/src/codec/codec.ts +11 -29
- package/src/codec/versioned/codec.ts +6 -6
- package/src/core/tree/detachedFieldIndex.ts +1 -1
- package/src/core/tree/detachedFieldIndexCodecs.ts +1 -1
- package/src/feature-libraries/chunked-forest/codec/codecs.ts +3 -3
- package/src/feature-libraries/default-schema/defaultFieldKinds.ts +1 -1
- package/src/feature-libraries/schema-index/codec.ts +5 -5
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +10 -4
- package/src/shared-tree/sharedTree.ts +1 -1
- package/src/shared-tree/sharedTreeChangeCodecs.ts +1 -1
- package/src/shared-tree/treeAlpha.ts +3 -9
- package/src/shared-tree/treeCheckout.ts +1 -1
- package/src/shared-tree-core/defaultResubmitMachine.ts +3 -2
- package/src/simple-tree/api/storedSchema.ts +5 -4
- package/src/simple-tree/core/allowedTypes.ts +4 -1
- package/src/simple-tree/prepareForInsertion.ts +1 -1
- package/src/treeFactory.ts +17 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"allowedTypes.js","sourceRoot":"","sources":["../../../src/simple-tree/core/allowedTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,qCAAqC,CAAC;AAEnE,OAAO,EAEN,wBAAwB,GACxB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EACN,WAAW,EACX,eAAe,GAGf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAuC,MAAM,eAAe,CAAC;AAC5E,OAAO,EACN,QAAQ,GAIR,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AA2D3D;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACtC,YAAkC;IAElC,2BAA2B,CAAC,YAAY,CAAC,CAAC;IAC1C,OAAO,YAAY,YAAY,6BAA6B,CAAC;AAC9D,CAAC;AAkFD;;;;;GAKG;AACH,MAAM,OAAO,6BAGZ,SAAQ,wBAAkD;IAgB1D,YACiB,KAAQ,EACR,WAAiC,EAAE;QAEnD,KAAK,EAAE,CAAC;QAHQ,UAAK,GAAL,KAAK,CAAG;QACR,aAAQ,GAAR,QAAQ,CAA2B;QAGnD,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAiC,CAAC;QAEvF,+FAA+F;QAC/F,wFAAwF;QACxF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAErC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACP,qBAAqB,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;QACF,CAAC;QAED,MAAM,KAAK,GAAG,6BAA6B,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAExD,IAAI,CAAC,YAAY,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE;YACjC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM;gBAC5B,CAAC,CAAC,6BAA6B,CAAC,MAAM,CACpC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBACzB,GAAG,IAAI;oBACP,IAAI,EAAE,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;iBACnC,CAAC,CAAC,EACH,IAAI,CAAC,QAAQ,CACb;gBACF,CAAC,CAAE,KAA2C,CAAC;YAChD,OAAO;gBACN,SAAS;gBACT,GAAG,EAAE,IAAI,GAAG,CAAC,SAAS,CAAC,gBAAgB,CAAC;gBACxC,WAAW,EAAE,IAAI,GAAG,CAAC,SAAS,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;aACzE,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC;IACd,CAAC;IAEM,QAAQ;QACd,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC;IAC1C,CAAC;IAEM,WAAW;QACjB,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC;IACpC,CAAC;IAEM,mBAAmB;QACzB,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,WAAW,CAAC;IAC5C,CAAC;IAEM,MAAM,CAAU,CAAC,MAAM,CAAC,WAAW,CAAC,CAQ1C,KAAyE;QAEzE,OAAO,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACnE,CAAC;IAEM,MAAM,CAAU,MAAM,CAQ5B,KAAyE;QAIzE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC;YACjE,MAAM,IAAI,SAAS,CAAC,wCAAwC,CAAC,CAAC;QAC/D,CAAC;IACF,CAAC;IAEO,MAAM,CAAC,KAAK,CACnB,MAAwC;QAExC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE;YAC/B,GAAG,EAAE,GAAG,EAAE;gBACT,MAAM,IAAI,UAAU,CAAC,oCAAoC,CAAC,CAAC;YAC5D,CAAC;YAED,GAAG,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;gBACnC,qCAAqC;gBACrC,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;oBAC/C,OAAO,SAAS,CAAC;gBAClB,CAAC;gBAED,yEAAyE;gBACzE,IAAI,QAAQ,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;oBACzC,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;gBACvD,CAAC;gBACD,mCAAmC;gBACnC,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAY,CAAC;YACjD,CAAC;YAED,GAAG,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;gBACzB,IAAI,QAAQ,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;oBACzC,OAAO,IAAI,CAAC;gBACb,CAAC;gBACD,mCAAmC;gBACnC,OAAO,QAAQ,IAAI,MAAM,CAAC;YAC3B,CAAC;YAED,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;gBACnB,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC3C,MAAM,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;gBACtE,OAAO,CAAC,GAAG,oBAAoB,EAAE,GAAG,UAAU,CAAC,CAAC;YACjD,CAAC;YAED,wBAAwB,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;gBAC9C,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,QAAQ,CAAC,EAAE,CAAC;oBAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,wBAAwB,CAAC,MAAM,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;oBACjF,OAAO;wBACN,GAAG,KAAK;wBACR,6GAA6G;wBAC7G,YAAY,EAAE,IAAI;wBAClB,QAAQ,EAAE,KAAK;qBACf,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACP,MAAM,KAAK,GAAG,MAAM,CAAC,wBAAwB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;oBAChE,OAAO;wBACN,GAAG,KAAK;wBACR,QAAQ,EAAE,KAAK;wBACf,6CAA6C;wBAC7C,UAAU,EAAE,KAAK;qBACjB,CAAC;gBACH,CAAC;YACF,CAAC;SACD,CAAC,CAAC;QACH,OAAO,KAAsD,CAAC;IAC/D,CAAC;IAEM,MAAM,CAAC,MAAM,CACnB,KAAQ,EACR,WAAiC,EAAE;QAEnC,MAAM,MAAM,GAAG,IAAI,6BAA6B,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAClE,OAAO,MAAuD,CAAC;IAChE,CAAC;IAEM,MAAM,CAAC,iBAAiB,CAC9B,KAAQ,EACR,WAAiC,EAAE;QAEnC,MAAM,cAAc,GAA2B,KAAK,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC1F,MAAM,MAAM,GAAG,6BAA6B,CAAC,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;QAC9E,OAAO,MAA2B,CAAC;IACpC,CAAC;IAEM,MAAM,CAAC,WAAW,CAEvB,KAAQ,EAAE,WAAiC,EAAE;QAC9C,MAAM,cAAc,GAA2B,KAAK,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;QAC1F,MAAM,MAAM,GAAG,6BAA6B,CAAC,MAAM,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;QAC9E,OAAO,MAAsC,CAAC;IAC/C,CAAC;CACD;AAgBD;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACrC,WAA4D;IAE5D,2BAA2B,CAAC,WAAW,CAAC,CAAC;IACzC,qJAAqJ;IACrJ,OAAO,OAAO,WAAW,KAAK,QAAQ,IAAI,UAAU,IAAI,WAAW,IAAI,MAAM,IAAI,WAAW,CAAC;AAC9F,CAAC;AAqBD;;GAEG;AACH,MAAM,CAAC,IAAI,mBAAwC,CAAC;AAEpD;;;;;;;;;GASG;AACH,MAAM,OAAO,aAAa;IAMzB,gBAAuB,CAAC;CACxB;AALA;IACC,mBAAmB,GAAG,GAAG,EAAE,CAAC,IAAI,aAAa,EAAE,CAAC;AACjD,CAAC,GAAA,CAAA;AA8DF;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAA2B;IAChE,OAAO,6BAA6B,CAAC,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,+BAA+B,CAC9C,IAAiC;IAEjC,OAAO,sBAAsB,CAAC,IAAI,CAAC;QAClC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC;YACA,QAAQ,EAAE,EAAE;YACZ,IAAI;SACJ,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,eAAe,GAAG,IAAI,OAAO,EAAkD,CAAC;AAEtF;;GAEG;AACH,MAAM,UAAU,6BAA6B,CAC5C,IAA0B;IAE1B,IAAI,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,wCAAwC;IACxC,0DAA0D;IAC1D,sMAAsM;IACtM,uHAAuH;IACvH,iJAAiJ;IACjJ,yFAAyF;IACzF,OAAO,WAAW,CAAC,eAAe,EAAE,IAAI,EAAE,GAAG,EAAE;QAC9C,2GAA2G;QAC3G,oGAAoG;QACpG,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,IAAI,IAAI,UAAU,IAAI,IAAI,CAAC,EAAE,+BAA+B,CAAC,CAAC;QAElF,MAAM,cAAc,GAA2B,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CACzF,+BAA+B,CAC/B,CAAC;QAEF,OAAO,6BAA6B,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,yCAAyC,CACxD,KAA2B;IAE3B,OAAO,6BAA6B,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,cAAc,GAAG,IAAI,OAAO,EAA0B,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAA2B,KAAkB;IAC9E,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC;QACpC,CAAC,CAAE,WAAW,CAAC,cAAc,EAAE,KAAK,EAAE,KAAK,CAAO;QAClD,CAAC,CAAC,KAAK,CAAC;IAET,2BAA2B,CAAC,eAAe,CAAC,CAAC;IAC7C,qBAAqB,CAAC,eAAe,CAAC,CAAC;IACvC,OAAO,eAAe,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,2BAA2B,CAC1C,MAA8E;IAE9E,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,UAAU,CACnB,6PAA6P,CAC7P,CAAC;IACH,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,qBAAqB,CACpC,MAAsB,EACtB,iBAAiB,GAAG,KAAK;IAEzB,kFAAkF;IAClF,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,OAAO;IACR,CAAC;IAED,MAAM,WAAW,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAElD,IAAI,iBAAiB,EAAE,CAAC;QACvB,WAAW,CAAC,iBAAiB,EAAE,CAAC;IACjC,CAAC;SAAM,CAAC;QACP,WAAW,CAAC,eAAe,EAAE,CAAC;IAC/B,CAAC;AACF,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\nimport { assert, Lazy } from \"@fluidframework/core-utils/internal\";\n\nimport {\n\ttype ErasedBaseType,\n\tErasedTypeImplementation,\n} from \"@fluidframework/core-interfaces/internal\";\n\nimport {\n\tgetOrCreate,\n\tisReadonlyArray,\n\ttype IsUnion,\n\ttype MakeNominal,\n} from \"../../util/index.js\";\nimport { isLazy, type FlexListToUnion, type LazyItem } from \"./flexList.js\";\nimport {\n\tNodeKind,\n\ttype InsertableTypedNode,\n\ttype NodeFromSchema,\n\ttype TreeNodeSchema,\n} from \"./treeNodeSchema.js\";\nimport { schemaAsTreeNodeValid } from \"./treeNodeValid.js\";\n\n/**\n * Schema for types allowed in some location in a tree (like a field, map entry or array).\n * @remarks\n * Type constraint used in schema declaration APIs.\n *\n * The order of types in the array is not significant.\n * Additionally, it is legal for users of this type to have the runtime and compile time order of items within this array not match.\n * Therefor to ensure type safety, these arrays should not be indexed, and instead just be iterated.\n *\n * Ideally this restriction would be modeled in the type itself, but it is not ergonomic to do so as there is no easy (when compared to arrays)\n * way to declare and manipulate unordered sets of types in TypeScript.\n *\n * Duplicate entries in this array are not allowed and will produce runtime errors.\n * Duplicate types are allowed,\n * but this must only be reflected in the type and not the runtime values.\n * This duplication can be used to encode the typing when the number of items in the array is not known at compile time\n * but some of the items are known to be present unconditionally.\n * For example, typing `[typeof A] | [typeof A, typeof B]` as `[typeof A, typeof B | typeof A]` is allowed,\n * and can produce more useful {@link Input} types.\n *\n * Due to one implementation of this being {@link AllowedTypesFull}, it is not safe to assume this is an array (as determined by `Array.isArray`).\n *\n * Code reading data from this should use {@link normalizeAllowedTypes} to ensure consistent handling, caching, nice errors etc.\n * @system @public\n */\nexport type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];\n\n/**\n * Stores annotations for an individual allowed type.\n * @remarks\n * Create using APIs on {@link SchemaFactoryAlpha}, like {@link SchemaStaticsAlpha.staged}.\n * @privateRemarks\n * Since this is sealed, users are not supposed to create instances of it directly.\n * Making it extend ErasedType could enforce that.\n * @alpha\n * @sealed\n */\nexport interface AnnotatedAllowedType<T = LazyItem<TreeNodeSchema>> {\n\t/**\n\t * Annotations for the allowed type.\n\t */\n\treadonly metadata: AllowedTypeMetadata;\n\t/**\n\t * The allowed type the annotations apply to in a particular schema.\n\t */\n\treadonly type: T;\n}\n\n/**\n * {@link AllowedTypesFull} but with the lazy schema references eagerly evaluated.\n * @sealed\n * @alpha\n */\nexport type AllowedTypesFullEvaluated = AllowedTypesFull<\n\treadonly AnnotatedAllowedType<TreeNodeSchema>[]\n>;\n\n/**\n * Checks if the input is an {@link AnnotatedAllowedTypes}.\n */\nexport function isAnnotatedAllowedTypes(\n\tallowedTypes: ImplicitAllowedTypes,\n): allowedTypes is AllowedTypesFullInternal {\n\tcheckForUninitializedSchema(allowedTypes);\n\treturn allowedTypes instanceof AnnotatedAllowedTypesInternal;\n}\n\n/**\n * Stores annotations for a set of allowed types.\n * @alpha\n * @sealed\n */\nexport interface AnnotatedAllowedTypes<T = readonly AnnotatedAllowedType[]>\n\textends ErasedBaseType<\"tree.AnnotatedAllowedTypes\"> {\n\t/**\n\t * Annotations that apply to a set of allowed types.\n\t */\n\treadonly metadata: AllowedTypesMetadata;\n\n\t/**\n\t * All the allowed types that the annotations apply to. The types themselves may also have individual annotations.\n\t */\n\treadonly types: T;\n\n\t/**\n\t * Get this {@link AnnotatedAllowedTypes} but with any lazy schema references eagerly evaluated.\n\t * @remarks\n\t * See {@link evaluateLazySchema} the implications of evaluating lazy schema references.\n\t */\n\tevaluate(): AllowedTypesFullEvaluated;\n\n\t/**\n\t * Get the allowed types as a set with any lazy schema references eagerly evaluated.\n\t * @remarks\n\t * See {@link evaluateLazySchema} the implications of evaluating lazy schema references.\n\t */\n\tevaluateSet(): ReadonlySet<TreeNodeSchema>;\n\n\t/**\n\t * Get the allowed types as a set of identifiers with any lazy schema references eagerly evaluated.\n\t * @remarks\n\t * See {@link evaluateLazySchema} the implications of evaluating lazy schema references.\n\t *\n\t * It is recommend to work in terms of {@link TreeNodeSchema}\n\t * rather than identifiers where possible since its more type safe and it is possible that two schema with the same identifier exist.\n\t */\n\tevaluateIdentifiers(): ReadonlySet<string>;\n}\n\n/**\n * Stores annotations for a set of allowed types.\n * @remarks\n * Most expressive form of AllowedTypes which any of the implicit types can be normalized to.\n * @alpha\n * @sealed\n */\nexport type AllowedTypesFull<\n\tT extends readonly AnnotatedAllowedType[] = readonly AnnotatedAllowedType[],\n> = AnnotatedAllowedTypes<T> & UnannotateAllowedTypesList<T>;\n\n/**\n * Creates an {@link AllowedTypesFull} type from a mixed array of annotated and unannotated allowed types.\n * @alpha\n * @sealed\n */\nexport type AllowedTypesFullFromMixed<\n\tT extends readonly (AnnotatedAllowedType | LazyItem<TreeNodeSchema>)[],\n> = UnannotateAllowedTypesList<T> & AnnotatedAllowedTypes<AnnotateAllowedTypesList<T>>;\n\n/**\n * The same as the built-in InstanceType, but works on classes with private constructors.\n * @privateRemarks\n * This is based on the trick in {@link https://stackoverflow.com/a/74657881}.\n */\ntype InstanceTypeRelaxed<TClass> = InstanceType<(new () => never) & TClass>;\n\n/**\n * {@link AllowedTypesFull} but with internal types.\n */\nexport type AllowedTypesFullInternal<\n\tT extends readonly AnnotatedAllowedType[] = readonly AnnotatedAllowedType[],\n> = AnnotatedAllowedTypesInternal<T> & UnannotateAllowedTypesList<T>;\n\ntype AllowedTypesFullInternalEvaluated = AllowedTypesFullInternal<\n\treadonly AnnotatedAllowedType<TreeNodeSchema>[]\n>;\n\n/**\n * The implementation of {@link AnnotatedAllowedTypes}. Also implements {@link AllowedTypesFull}.\n * @remarks\n * Due to TypeScript limitations, this class cannot directly state it implements {@link AllowedTypesFull}.\n * As a workaround for that, the static `create` method returns the intersection type.\n */\nexport class AnnotatedAllowedTypesInternal<\n\t\tT extends readonly AnnotatedAllowedType[] = readonly AnnotatedAllowedType[],\n\t>\n\textends ErasedTypeImplementation<AnnotatedAllowedTypes<T>>\n\timplements AnnotatedAllowedTypes<T>\n{\n\tpublic readonly unannotatedTypes: UnannotateAllowedTypesList<T>;\n\n\t/**\n\t * True if and only if there is at least one lazy schema reference in the types arrays.\n\t */\n\tprivate readonly isLazy: boolean;\n\n\tprivate readonly lazyEvaluate: Lazy<{\n\t\treadonly annotated: AllowedTypesFullInternalEvaluated;\n\t\treadonly set: ReadonlySet<TreeNodeSchema>;\n\t\treadonly identifiers: ReadonlySet<string>;\n\t}>;\n\n\tprivate constructor(\n\t\tpublic readonly types: T,\n\t\tpublic readonly metadata: AllowedTypesMetadata = {},\n\t) {\n\t\tsuper();\n\t\tthis.unannotatedTypes = types.map((type) => type.type) as typeof this.unannotatedTypes;\n\n\t\t// Since the array has been copied, mutations to it will not be handled correctly so freeze it.\n\t\t// Support for such mutations could be added at a later date by making more things lazy.\n\t\tObject.freeze(this.types);\n\t\tObject.freeze(this.unannotatedTypes);\n\n\t\tthis.isLazy = false;\n\t\tfor (const type of this.unannotatedTypes) {\n\t\t\tif (isLazy(type)) {\n\t\t\t\tthis.isLazy = true;\n\t\t\t} else {\n\t\t\t\tmarkSchemaMostDerived(type);\n\t\t\t}\n\t\t}\n\n\t\tconst proxy = AnnotatedAllowedTypesInternal.proxy(this);\n\n\t\tthis.lazyEvaluate = new Lazy(() => {\n\t\t\tconst annotated = this.isLazy\n\t\t\t\t? AnnotatedAllowedTypesInternal.create(\n\t\t\t\t\t\tthis.types.map((type) => ({\n\t\t\t\t\t\t\t...type,\n\t\t\t\t\t\t\ttype: evaluateLazySchema(type.type),\n\t\t\t\t\t\t})),\n\t\t\t\t\t\tthis.metadata,\n\t\t\t\t\t)\n\t\t\t\t: (proxy as AllowedTypesFullInternalEvaluated);\n\t\t\treturn {\n\t\t\t\tannotated,\n\t\t\t\tset: new Set(annotated.unannotatedTypes),\n\t\t\t\tidentifiers: new Set(annotated.unannotatedTypes.map((t) => t.identifier)),\n\t\t\t};\n\t\t});\n\n\t\treturn proxy;\n\t}\n\n\tpublic evaluate(): AllowedTypesFullInternalEvaluated {\n\t\treturn this.lazyEvaluate.value.annotated;\n\t}\n\n\tpublic evaluateSet(): ReadonlySet<TreeNodeSchema> {\n\t\treturn this.lazyEvaluate.value.set;\n\t}\n\n\tpublic evaluateIdentifiers(): ReadonlySet<string> {\n\t\treturn this.lazyEvaluate.value.identifiers;\n\t}\n\n\tpublic static override [Symbol.hasInstance]<\n\t\tTThis extends\n\t\t\t| (abstract new (\n\t\t\t\t\t...args: unknown[]\n\t\t\t ) => object)\n\t\t\t| typeof AnnotatedAllowedTypesInternal,\n\t>(\n\t\tthis: TThis,\n\t\tvalue: ErasedBaseType | InstanceTypeRelaxed<TThis> | ImplicitAllowedTypes,\n\t): value is InstanceTypeRelaxed<TThis> & AnnotatedAllowedTypesInternal & AllowedTypesFull {\n\t\treturn Object.prototype.isPrototypeOf.call(this.prototype, value);\n\t}\n\n\tpublic static override narrow<\n\t\tTThis extends\n\t\t\t| (abstract new (\n\t\t\t\t\t...args: unknown[]\n\t\t\t ) => object)\n\t\t\t| typeof AnnotatedAllowedTypesInternal,\n\t>(\n\t\tthis: TThis,\n\t\tvalue: ErasedBaseType | InstanceTypeRelaxed<TThis> | ImplicitAllowedTypes,\n\t): asserts value is InstanceTypeRelaxed<TThis> &\n\t\tAnnotatedAllowedTypesInternal &\n\t\tAllowedTypesFull {\n\t\tif (!Object.prototype.isPrototypeOf.call(this.prototype, value)) {\n\t\t\tthrow new TypeError(\"Invalid AnnotatedAllowedTypes instance\");\n\t\t}\n\t}\n\n\tprivate static proxy<const T extends readonly AnnotatedAllowedType[]>(\n\t\tresult: AnnotatedAllowedTypesInternal<T>,\n\t): AnnotatedAllowedTypesInternal<T> & AllowedTypesFull<T> {\n\t\tconst proxy = new Proxy(result, {\n\t\t\tset: () => {\n\t\t\t\tthrow new UsageError(\"AnnotatedAllowedTypes is immutable\");\n\t\t\t},\n\n\t\t\tget: (target, property, receiver) => {\n\t\t\t\t// Hide common array editing methods.\n\t\t\t\tif (property === \"push\" || property === \"pop\") {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\t// Forward array lookup and array methods to the unannotated types array.\n\t\t\t\tif (property in target.unannotatedTypes) {\n\t\t\t\t\treturn Reflect.get(target.unannotatedTypes, property);\n\t\t\t\t}\n\t\t\t\t// Forward anything else to target.\n\t\t\t\treturn Reflect.get(target, property) as unknown;\n\t\t\t},\n\n\t\t\thas: (target, property) => {\n\t\t\t\tif (property in target.unannotatedTypes) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// Forward anything else to target.\n\t\t\t\treturn property in target;\n\t\t\t},\n\n\t\t\townKeys: (target) => {\n\t\t\t\tconst targetKeys = Reflect.ownKeys(target);\n\t\t\t\tconst unannotatedTypesKeys = Reflect.ownKeys(target.unannotatedTypes);\n\t\t\t\treturn [...unannotatedTypesKeys, ...targetKeys];\n\t\t\t},\n\n\t\t\tgetOwnPropertyDescriptor: (target, property) => {\n\t\t\t\tif (Object.prototype.hasOwnProperty.call(target.unannotatedTypes, property)) {\n\t\t\t\t\tconst inner = Object.getOwnPropertyDescriptor(target.unannotatedTypes, property);\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...inner,\n\t\t\t\t\t\t// Since these properties are not on the target, make them non-configurable to confirm with proxy invariants.\n\t\t\t\t\t\tconfigurable: true,\n\t\t\t\t\t\twritable: false,\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\tconst inner = Object.getOwnPropertyDescriptor(target, property);\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...inner,\n\t\t\t\t\t\twritable: false,\n\t\t\t\t\t\t// Allow only array entries to be enumerable.\n\t\t\t\t\t\tenumerable: false,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t\treturn proxy as typeof result & UnannotateAllowedTypesList<T>;\n\t}\n\n\tpublic static create<const T extends readonly AnnotatedAllowedType[]>(\n\t\ttypes: T,\n\t\tmetadata: AllowedTypesMetadata = {},\n\t): AnnotatedAllowedTypesInternal<T> & AllowedTypesFull<T> {\n\t\tconst result = new AnnotatedAllowedTypesInternal(types, metadata);\n\t\treturn result as typeof result & UnannotateAllowedTypesList<T>;\n\t}\n\n\tpublic static createUnannotated<const T extends AllowedTypes>(\n\t\ttypes: T,\n\t\tmetadata: AllowedTypesMetadata = {},\n\t): AnnotatedAllowedTypesInternal & T {\n\t\tconst annotatedTypes: AnnotatedAllowedType[] = types.map(normalizeToAnnotatedAllowedType);\n\t\tconst result = AnnotatedAllowedTypesInternal.create(annotatedTypes, metadata);\n\t\treturn result as typeof result & T;\n\t}\n\n\tpublic static createMixed<\n\t\tconst T extends readonly (AnnotatedAllowedType | LazyItem<TreeNodeSchema>)[],\n\t>(types: T, metadata: AllowedTypesMetadata = {}): AllowedTypesFullFromMixed<T> {\n\t\tconst annotatedTypes: AnnotatedAllowedType[] = types.map(normalizeToAnnotatedAllowedType);\n\t\tconst result = AnnotatedAllowedTypesInternal.create(annotatedTypes, metadata);\n\t\treturn result as AllowedTypesFullFromMixed<T>;\n\t}\n}\n\n/**\n * Annotations that apply to a set of allowed types.\n * @remarks\n * Additional optionals may be added to this as non-breaking changes, so implementations of it should be simple object literals with no unlisted members.\n * @alpha\n * @input\n */\nexport interface AllowedTypesMetadata {\n\t/**\n\t * User defined metadata\n\t */\n\treadonly custom?: unknown;\n}\n\n/**\n * Checks if the given allowed type is annotated with {@link AllowedTypeMetadata}.\n */\nexport function isAnnotatedAllowedType(\n\tallowedType: AnnotatedAllowedType | LazyItem<TreeNodeSchema>,\n): allowedType is AnnotatedAllowedType {\n\tcheckForUninitializedSchema(allowedType);\n\t// Class based schema, and lazy schema references report type \"function\": filtering them out with typeof makes narrowing based on members mostly safe\n\treturn typeof allowedType === \"object\" && \"metadata\" in allowedType && \"type\" in allowedType;\n}\n\n/**\n * Annotations that apply to an individual allowed type.\n * @remarks\n * Additional optionals may be added to this as non-breaking changes, so implementations of it should be simple object literals with no unlisted members.\n * @alpha\n * @input\n */\nexport interface AllowedTypeMetadata {\n\t/**\n\t * User defined metadata\n\t */\n\treadonly custom?: unknown;\n\n\t/**\n\t * If defined, indicates that an allowed type is {@link SchemaStaticsAlpha.staged | staged}.\n\t */\n\treadonly stagedSchemaUpgrade?: SchemaUpgrade;\n}\n\n/**\n * Package internal {@link SchemaUpgrade} construction API.\n */\nexport let createSchemaUpgrade: () => SchemaUpgrade;\n\n/**\n * Unique token used to upgrade schemas and determine if a particular upgrade has been completed.\n * @remarks\n * Create using {@link SchemaStaticsAlpha.staged}.\n * @privateRemarks\n * TODO:#38722 implement runtime schema upgrades.\n * Until then, the class purely behaves mostly as a placeholder.\n * TODO: Consider allowing users to store a name for the upgrade to use in error messages.\n * @sealed @alpha\n */\nexport class SchemaUpgrade {\n\tprotected _typeCheck!: MakeNominal;\n\tstatic {\n\t\tcreateSchemaUpgrade = () => new SchemaUpgrade();\n\t}\n\n\tprivate constructor() {}\n}\n\n/**\n * Types of {@link TreeNode|TreeNodes} or {@link TreeLeafValue|TreeLeafValues} allowed at a location in a tree.\n * @remarks\n * Used by {@link TreeViewConfiguration} for the root and various kinds of {@link TreeNodeSchema} to specify their allowed child types.\n *\n * Use {@link SchemaFactory} to access leaf schema or declare new composite schema.\n *\n * Implicitly treats a single type as an array of one type.\n *\n * Arrays of schema can be used to specify multiple types are allowed, which result in unions of those types in the Tree APIs.\n *\n * When saved into variables, avoid type-erasing the details, as doing so loses the compile time schema awareness of APIs derived from the types.\n *\n * When referring to types that are declared after the definition of the `ImplicitAllowedTypes`, the schema can be wrapped in a lambda to allow the forward reference.\n * See {@link ValidateRecursiveSchema} for details on how to structure the `ImplicitAllowedTypes` instances when constructing recursive schema.\n *\n * Code reading data from this should use {@link normalizeAllowedTypes} to ensure consistent handling, caching, nice errors etc.\n *\n * @example Explicit use with strong typing\n * ```typescript\n * const sf = new SchemaFactory(\"myScope\");\n * const childTypes = [sf.number, sf.string] as const satisfies ImplicitAllowedTypes;\n * const config = new TreeViewConfiguration({ schema: childTypes });\n * ```\n *\n * @example Forward reference\n * ```typescript\n * const sf = new SchemaFactory(\"myScope\");\n * class A extends sf.array(\"example\", [() => B]) {}\n * class B extends sf.array(\"Inner\", sf.number) {}\n * ```\n * @public\n */\nexport type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;\n\n/**\n * Removes annotations from a list of allowed types that may contain annotations.\n * @system @alpha\n */\nexport type UnannotateAllowedTypesList<\n\tT extends readonly (AnnotatedAllowedType | LazyItem<TreeNodeSchema>)[],\n> = {\n\t[I in keyof T]: T[I] extends AnnotatedAllowedType<infer X> ? X : T[I];\n};\n\n/**\n * Add annotations to a list of allowed types that may or may not contain annotations.\n * @system @alpha\n */\nexport type AnnotateAllowedTypesList<\n\tT extends readonly (AnnotatedAllowedType | LazyItem<TreeNodeSchema>)[],\n> = {\n\t[I in keyof T]: T[I] extends AnnotatedAllowedType<unknown>\n\t\t? T[I]\n\t\t: AnnotatedAllowedType<T[I]>;\n};\n\n/**\n * Normalizes an {@link ImplicitAllowedTypes} to an {@link AllowedTypesFull}.\n * @alpha\n */\nexport function normalizeAllowedTypes(types: ImplicitAllowedTypes): AllowedTypesFull {\n\treturn normalizeAllowedTypesInternal(types);\n}\n\n/**\n * Normalizes an allowed type to an {@link AnnotatedAllowedType}, by adding empty annotations if they don't already exist.\n */\nexport function normalizeToAnnotatedAllowedType<T extends LazyItem<TreeNodeSchema>>(\n\ttype: T | AnnotatedAllowedType<T>,\n): AnnotatedAllowedType<T> {\n\treturn isAnnotatedAllowedType(type)\n\t\t? type\n\t\t: {\n\t\t\t\tmetadata: {},\n\t\t\t\ttype,\n\t\t\t};\n}\n\n/**\n * See note inside {@link normalizeAllowedTypesInternal}.\n */\nconst cachedNormalize = new WeakMap<ImplicitAllowedTypes, AllowedTypesFullInternal>();\n\n/**\n * Normalizes allowed types to an {@link AllowedTypesFullInternal}.\n */\nexport function normalizeAllowedTypesInternal(\n\ttype: ImplicitAllowedTypes,\n): AllowedTypesFullInternal {\n\tif (isAnnotatedAllowedTypes(type)) {\n\t\treturn type;\n\t}\n\n\t// This caching accomplishes two things:\n\t// 1. It avoids redundant computations for the same input.\n\t// 2. It provides a stable object identity for the output in case the input is normalized twice and other systems (such as unhydrated contexts) are cached based on the object identity of the output.\n\t// It is this second case which is the more important since creating the AnnotatedAllowedTypesInternal is rather cheap.\n\t// Adding this cache improved the performance of the \"large recursive union\" test (which mostly just constructs a TreeConfiguration) by ~5 times.\n\t// This cache is strictly a performance optimization: it is not required for correctness.\n\treturn getOrCreate(cachedNormalize, type, () => {\n\t\t// Due to more specific internal type, the above does not narrow sufficiently, so more narrowing is needed.\n\t\t// It is possible this will give a false error if a TreeNodeSchema which matches this check is used.\n\t\tassert(!(\"types\" in type && \"metadata\" in type), \"invalid AnnotatedAllowedTypes\");\n\n\t\tconst annotatedTypes: AnnotatedAllowedType[] = (isReadonlyArray(type) ? type : [type]).map(\n\t\t\tnormalizeToAnnotatedAllowedType,\n\t\t);\n\n\t\treturn AnnotatedAllowedTypesInternal.create(annotatedTypes);\n\t});\n}\n\n/**\n * Normalizes an {@link ImplicitAllowedTypes} to an {@link AllowedTypesFullInternalEvaluated} by eagerly evaluating any\n * lazy schema declarations and adding empty metadata if it doesn't already exist.\n *\n * @remarks Note: this must only be called after all required schemas have been declared, otherwise evaluation of\n * recursive schemas may fail.\n */\nexport function normalizeAndEvaluateAnnotatedAllowedTypes(\n\ttypes: ImplicitAllowedTypes,\n): AllowedTypesFullInternalEvaluated {\n\treturn normalizeAllowedTypesInternal(types).evaluate();\n}\n\nconst cachedLazyItem = new WeakMap<() => unknown, unknown>();\n\n/**\n * Returns the schema referenced by the {@link LazyItem}.\n * @remarks\n * Caches results to handle {@link LazyItem}s which compute their resulting schema.\n * @alpha\n */\nexport function evaluateLazySchema<T extends TreeNodeSchema>(value: LazyItem<T>): T {\n\tconst evaluatedSchema = isLazy(value)\n\t\t? (getOrCreate(cachedLazyItem, value, value) as T)\n\t\t: value;\n\n\tcheckForUninitializedSchema(evaluatedSchema);\n\tmarkSchemaMostDerived(evaluatedSchema);\n\treturn evaluatedSchema;\n}\n\n/**\n * Throws a UsageError if the provided schema is undefined, most likely due to being used before it was initialized.\n */\nexport function checkForUninitializedSchema(\n\tschema: ImplicitAllowedTypes | LazyItem<TreeNodeSchema> | AnnotatedAllowedType,\n): void {\n\tif (schema === undefined) {\n\t\tthrow new UsageError(\n\t\t\t`Encountered an undefined schema. This could indicate that some referenced schema has not yet been instantiated. Consider using a lazy schema reference (like \"() => schema\") or delaying the evaluation of the lazy reference if one is already being used.`,\n\t\t);\n\t}\n}\n\n/**\n * Indicates that the provided schema is the \"most derived\" version in its class hierarchy.\n *\n * @param oneTimeInitialize - If true this runs {@link TreeNodeValid.oneTimeInitialize} which does even more initialization and validation.\n * `oneTimeInitialize` can't safely be run until all transitively referenced schema are defined, so which cases can safely use it are more limited.\n * When legal for the caller to set this to true, it is preferred, but it is often not safe due to possible forward references.\n * @remarks\n * See {@link MostDerivedData} and {@link SchemaFactory} for details on what a \"most derived\" schema is and why it matters.\n *\n * This is a helper for invoking {@link TreeNodeValid.markMostDerived} for {@link TreeNodeSchema}.\n *\n * Calling this helps with error messages about invalid schema usage (See {@link SchemaFactory} for the rules, some of which this helps validate).\n * Typically this should be called for each schema as early as practical to improve error reporting for invalid usages of schema\n * (using two different schema derived from the same {@link SchemaFactory} produced base class).\n *\n * Note that construction of actual {@link TreeNode} instances or use of a schema transitively in a {@link TreeViewConfiguration} already do this,\n * so any calls to this that is unconditionally after that point for the given schema is not needed.\n * Instead most usages of this should be from those cases, and from miscellaneous cases where a schema is passed into an public API where theoretically someone could accidentally\n * pass in a base class of a schema instead of the most derived one.\n */\nexport function markSchemaMostDerived(\n\tschema: TreeNodeSchema,\n\toneTimeInitialize = false,\n): void {\n\t// Leaf schema are not classes, and thus do not need to be marked as most derived.\n\tif (schema.kind === NodeKind.Leaf) {\n\t\treturn;\n\t}\n\n\tconst schemaValid = schemaAsTreeNodeValid(schema);\n\n\tif (oneTimeInitialize) {\n\t\tschemaValid.oneTimeInitialize();\n\t} else {\n\t\tschemaValid.markMostDerived();\n\t}\n}\n\n/**\n * Type of tree node for a field of the given schema.\n * @public\n */\nexport type TreeNodeFromImplicitAllowedTypes<\n\tTSchema extends ImplicitAllowedTypes = TreeNodeSchema,\n> = TSchema extends TreeNodeSchema\n\t? NodeFromSchema<TSchema>\n\t: TSchema extends AllowedTypes\n\t\t? NodeFromSchema<FlexListToUnion<TSchema>>\n\t\t: unknown;\n\n/**\n * This type exists only to be linked from documentation to provide a single linkable place to document some details of\n * \"Input\" types and how they handle schema.\n *\n * When a schema is used to describe data which is an input into an API, the API is [contravariant](https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)) over the schema.\n * (See also, [TypeScript Variance Annotations](https://www.typescriptlang.org/docs/handbook/2/generics.html#variance-annotations)).\n *\n * Since these schema are expressed using TypeScript types, it is possible for the user of the API to provide non-exact values of these types which has implications that depended on the variance.\n *\n * Consider a field with schema type of `A | B` (where A and B are types of schema).\n *\n * - Reading the field behaves covariantly so {@link NodeFromSchema} of `<A | B>` is the same as `NodeFromSchema<A> | NodeFromSchema<B>`, indicating that either type of node can be read from the field.\n *\n * - Writing to the field behaves contravariantly. Since it is unknown if the node actually has a schema `A` or a schema `B`, the only legal values (known to be in schema regardless of which schema the underlying node has) are values which are legal for both `A & B`.\n *\n * Note that this is distinct from the case where the schema is `[A, B]`.\n * In this case it is known that the field allows both A and B (the field can be set to an A or a B value).\n * When `A | B` is used, the field might allow\n * A but not B (so assigning a B value would be out of schema),\n * B but not A (so assigning an A value would be out of schema)\n * or both A and B.\n *\n * This gets more extreme when given completely unspecified schema.\n * For example if a field is just provided {@link ImplicitFieldSchema}, nothing is known about the content of the field.\n * This means that reading the field (via {@link TreeFieldFromImplicitField}) can give any valid tree field content,\n * but there are no safe values which could be written to the field (since it is unknown what values would be out of schema) so {@link InsertableTreeFieldFromImplicitField} gives `never`.\n *\n * To implement this variance correctly, the computation of types for input and output have to use separate utilities\n * which take very different approaches when encountering non-exact schema like unions or `ImplicitFieldSchema`.\n * The utilities which behave contravariantly (as required to handle input correctly) link this documentation to indicate that this is how they behave.\n *\n * In addition to behaving contravariantly, these input type computation utilities often have further limitations.\n * This is due to TypeScript making it difficult to implement this contravariance exactly.\n * When faced with these implementation limitations these contravariant type computation utilities error on the side of producing overly strict requirements.\n * For example in the above case of `A | B`, the utilities might compute an allowed insertable type as `never` even if there happens to be a common value accepted by both `A` and `B`.\n * Future versions of the API can relax these requirements as the type computations are made more accurate.\n *\n * For a more concrete example: if {@link InsertableTreeFieldFromImplicitField} produced `never` for a schema `A | OptionalField<A>`,\n * a future version could instead return a more flexible but still safe type, like `A`.\n *\n * More generally: try to avoid providing non-exact schema, especially for the fields of other schema.\n * While these APIs attempt to handle such cases correctly, there are limitations and known bugs in this handling.\n * Code using non-exact schema is much more likely to have its compilation break due to updates of this package or even TypeScript,\n * and thus compilation breaks due to edge cases of non-exact schema handling, especially with recursive schema, are not considered breaking changes.\n * This may change as the API become more stable.\n *\n * @privateRemarks\n * There likely is a better way to share this documentation, but none was found at the time of writing.\n *\n * TODO: Once {@link InsertableField} is public, consider using it in the examples above.\n * @system @public\n */\nexport type Input<T extends never> = T;\n\n/**\n * Type of content that can be inserted into the tree for a node of the given schema.\n *\n * @see {@link Input}\n *\n * @typeparam TSchema - Schema to process.\n *\n * @privateRemarks\n * This is a bit overly conservative, since cases like `A | [A]` give never and could give `A`.\n * @public\n */\nexport type InsertableTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes> =\n\t[TSchema] extends [TreeNodeSchema]\n\t\t? InsertableTypedNode<TSchema>\n\t\t: [TSchema] extends [AllowedTypes]\n\t\t\t? InsertableTreeNodeFromAllowedTypes<TSchema>\n\t\t\t: never;\n\n/**\n * Type of content that can be inserted into the tree for a node of the given schema.\n *\n * @see {@link Input}\n *\n * @typeparam TList - AllowedTypes to process\n *\n * @privateRemarks\n * This loop is non-recursive to allow larger unions before hitting the recursion limit in TypeScript.\n * @system @public\n */\nexport type InsertableTreeNodeFromAllowedTypes<TList extends AllowedTypes> =\n\tIsUnion<TList> extends true\n\t\t? never\n\t\t: {\n\t\t\t\treadonly [Property in keyof TList]: [TList[Property]] extends [\n\t\t\t\t\tLazyItem<infer TSchema extends TreeNodeSchema>,\n\t\t\t\t]\n\t\t\t\t\t? InsertableTypedNode<TSchema>\n\t\t\t\t\t: never;\n\t\t\t}[NumberKeys<TList>];\n\n/**\n * Extracts the keys of `T` which are numbers.\n * @remarks\n * The keys are extracted as strings which can be used to index `T`.\n *\n * This handles cases like `{ x: 4 } & [5, 6]` returning `\"0\"` and `\"1\"`.\n * Such cases are difficult to handle since `keyof` includes `number` in such cases, but the type can not be indexed by `number`.\n * @system @public\n */\nexport type NumberKeys<\n\tT,\n\tTransformed = {\n\t\treadonly [Property in keyof T as number extends Property ? never : Property]: Property;\n\t},\n> = Transformed[`${number}` & keyof Transformed];\n"]}
|
|
1
|
+
{"version":3,"file":"allowedTypes.js","sourceRoot":"","sources":["../../../src/simple-tree/core/allowedTypes.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 { UsageError } from \"@fluidframework/telemetry-utils/internal\";\nimport { assert, Lazy } from \"@fluidframework/core-utils/internal\";\n\nimport {\n\ttype ErasedBaseType,\n\tErasedTypeImplementation,\n} from \"@fluidframework/core-interfaces/internal\";\n\nimport {\n\tgetOrCreate,\n\tisReadonlyArray,\n\ttype IsUnion,\n\ttype MakeNominal,\n} from \"../../util/index.js\";\nimport { isLazy, type FlexListToUnion, type LazyItem } from \"./flexList.js\";\nimport {\n\tNodeKind,\n\ttype InsertableTypedNode,\n\ttype NodeFromSchema,\n\ttype TreeNodeSchema,\n} from \"./treeNodeSchema.js\";\nimport { schemaAsTreeNodeValid } from \"./treeNodeValid.js\";\n\n/**\n * Schema for types allowed in some location in a tree (like a field, map entry or array).\n * @remarks\n * Type constraint used in schema declaration APIs.\n *\n * The order of types in the array is not significant.\n * Additionally, it is legal for users of this type to have the runtime and compile time order of items within this array not match.\n * Therefor to ensure type safety, these arrays should not be indexed, and instead just be iterated.\n *\n * Ideally this restriction would be modeled in the type itself, but it is not ergonomic to do so as there is no easy (when compared to arrays)\n * way to declare and manipulate unordered sets of types in TypeScript.\n *\n * Duplicate entries in this array are not allowed and will produce runtime errors.\n * Duplicate types are allowed,\n * but this must only be reflected in the type and not the runtime values.\n * This duplication can be used to encode the typing when the number of items in the array is not known at compile time\n * but some of the items are known to be present unconditionally.\n * For example, typing `[typeof A] | [typeof A, typeof B]` as `[typeof A, typeof B | typeof A]` is allowed,\n * and can produce more useful {@link Input} types.\n *\n * Due to one implementation of this being {@link AllowedTypesFull}, it is not safe to assume this is an array (as determined by `Array.isArray`).\n *\n * Code reading data from this should use {@link normalizeAllowedTypes} to ensure consistent handling, caching, nice errors etc.\n * @system @public\n */\nexport type AllowedTypes = readonly LazyItem<TreeNodeSchema>[];\n\n/**\n * Stores annotations for an individual allowed type.\n * @remarks\n * Create using APIs on {@link SchemaFactoryAlpha}, like {@link SchemaStaticsAlpha.staged}.\n * @privateRemarks\n * Since this is sealed, users are not supposed to create instances of it directly.\n * Making it extend ErasedType could enforce that.\n * @alpha\n * @sealed\n */\nexport interface AnnotatedAllowedType<T = LazyItem<TreeNodeSchema>> {\n\t/**\n\t * Annotations for the allowed type.\n\t */\n\treadonly metadata: AllowedTypeMetadata;\n\t/**\n\t * The allowed type the annotations apply to in a particular schema.\n\t */\n\treadonly type: T;\n}\n\n/**\n * {@link AllowedTypesFull} but with the lazy schema references eagerly evaluated.\n * @sealed\n * @alpha\n */\nexport type AllowedTypesFullEvaluated = AllowedTypesFull<\n\treadonly AnnotatedAllowedType<TreeNodeSchema>[]\n>;\n\n/**\n * Checks if the input is an {@link AnnotatedAllowedTypes}.\n */\nexport function isAnnotatedAllowedTypes(\n\tallowedTypes: ImplicitAllowedTypes,\n): allowedTypes is AllowedTypesFullInternal {\n\tcheckForUninitializedSchema(allowedTypes);\n\treturn allowedTypes instanceof AnnotatedAllowedTypesInternal;\n}\n\n/**\n * Stores annotations for a set of allowed types.\n * @alpha\n * @sealed\n */\nexport interface AnnotatedAllowedTypes<T = readonly AnnotatedAllowedType[]>\n\textends ErasedBaseType<\"tree.AnnotatedAllowedTypes\"> {\n\t/**\n\t * Annotations that apply to a set of allowed types.\n\t */\n\treadonly metadata: AllowedTypesMetadata;\n\n\t/**\n\t * All the allowed types that the annotations apply to. The types themselves may also have individual annotations.\n\t */\n\treadonly types: T;\n\n\t/**\n\t * Get this {@link AnnotatedAllowedTypes} but with any lazy schema references eagerly evaluated.\n\t * @remarks\n\t * See {@link evaluateLazySchema} the implications of evaluating lazy schema references.\n\t */\n\tevaluate(): AllowedTypesFullEvaluated;\n\n\t/**\n\t * Get the allowed types as a set with any lazy schema references eagerly evaluated.\n\t * @remarks\n\t * See {@link evaluateLazySchema} the implications of evaluating lazy schema references.\n\t */\n\tevaluateSet(): ReadonlySet<TreeNodeSchema>;\n\n\t/**\n\t * Get the allowed types as a set of identifiers with any lazy schema references eagerly evaluated.\n\t * @remarks\n\t * See {@link evaluateLazySchema} the implications of evaluating lazy schema references.\n\t *\n\t * It is recommend to work in terms of {@link TreeNodeSchema}\n\t * rather than identifiers where possible since its more type safe and it is possible that two schema with the same identifier exist.\n\t */\n\tevaluateIdentifiers(): ReadonlySet<string>;\n}\n\n/**\n * Stores annotations for a set of allowed types.\n * @remarks\n * Most expressive form of AllowedTypes which any of the implicit types can be normalized to.\n * @alpha\n * @sealed\n */\nexport type AllowedTypesFull<\n\tT extends readonly AnnotatedAllowedType[] = readonly AnnotatedAllowedType[],\n> = AnnotatedAllowedTypes<T> & UnannotateAllowedTypesList<T>;\n\n/**\n * Creates an {@link AllowedTypesFull} type from a mixed array of annotated and unannotated allowed types.\n * @alpha\n * @sealed\n */\nexport type AllowedTypesFullFromMixed<\n\tT extends readonly (AnnotatedAllowedType | LazyItem<TreeNodeSchema>)[],\n> = UnannotateAllowedTypesList<T> & AnnotatedAllowedTypes<AnnotateAllowedTypesList<T>>;\n\n/**\n * The same as the built-in InstanceType, but works on classes with private constructors.\n * @privateRemarks\n * This is based on the trick in {@link https://stackoverflow.com/a/74657881}.\n */\ntype InstanceTypeRelaxed<TClass> = InstanceType<(new () => never) & TClass>;\n\n/**\n * {@link AllowedTypesFull} but with internal types.\n */\nexport type AllowedTypesFullInternal<\n\tT extends readonly AnnotatedAllowedType[] = readonly AnnotatedAllowedType[],\n> = AnnotatedAllowedTypesInternal<T> & UnannotateAllowedTypesList<T>;\n\ntype AllowedTypesFullInternalEvaluated = AllowedTypesFullInternal<\n\treadonly AnnotatedAllowedType<TreeNodeSchema>[]\n>;\n\n/**\n * The implementation of {@link AnnotatedAllowedTypes}. Also implements {@link AllowedTypesFull}.\n * @remarks\n * Due to TypeScript limitations, this class cannot directly state it implements {@link AllowedTypesFull}.\n * As a workaround for that, the static `create` method returns the intersection type.\n */\nexport class AnnotatedAllowedTypesInternal<\n\t\tT extends readonly AnnotatedAllowedType[] = readonly AnnotatedAllowedType[],\n\t>\n\textends ErasedTypeImplementation<AnnotatedAllowedTypes<T>>\n\timplements AnnotatedAllowedTypes<T>\n{\n\tpublic readonly unannotatedTypes: UnannotateAllowedTypesList<T>;\n\n\t/**\n\t * True if and only if there is at least one lazy schema reference in the types arrays.\n\t */\n\tprivate readonly isLazy: boolean;\n\n\tprivate readonly lazyEvaluate: Lazy<{\n\t\treadonly annotated: AllowedTypesFullInternalEvaluated;\n\t\treadonly set: ReadonlySet<TreeNodeSchema>;\n\t\treadonly identifiers: ReadonlySet<string>;\n\t}>;\n\n\tprivate constructor(\n\t\tpublic readonly types: T,\n\t\tpublic readonly metadata: AllowedTypesMetadata = {},\n\t) {\n\t\tsuper();\n\t\tthis.unannotatedTypes = types.map((type) => type.type) as typeof this.unannotatedTypes;\n\n\t\t// Since the array has been copied, mutations to it will not be handled correctly so freeze it.\n\t\t// Support for such mutations could be added at a later date by making more things lazy.\n\t\tObject.freeze(this.types);\n\t\tObject.freeze(this.unannotatedTypes);\n\n\t\tthis.isLazy = false;\n\t\tfor (const type of this.unannotatedTypes) {\n\t\t\tif (isLazy(type)) {\n\t\t\t\tthis.isLazy = true;\n\t\t\t} else {\n\t\t\t\tmarkSchemaMostDerived(type);\n\t\t\t}\n\t\t}\n\n\t\tconst proxy = AnnotatedAllowedTypesInternal.proxy(this);\n\n\t\tthis.lazyEvaluate = new Lazy(() => {\n\t\t\tconst annotated = this.isLazy\n\t\t\t\t? AnnotatedAllowedTypesInternal.create(\n\t\t\t\t\t\tthis.types.map((type) => ({\n\t\t\t\t\t\t\t...type,\n\t\t\t\t\t\t\ttype: evaluateLazySchema(type.type),\n\t\t\t\t\t\t})),\n\t\t\t\t\t\tthis.metadata,\n\t\t\t\t\t)\n\t\t\t\t: (proxy as AllowedTypesFullInternalEvaluated);\n\t\t\treturn {\n\t\t\t\tannotated,\n\t\t\t\tset: new Set(annotated.unannotatedTypes),\n\t\t\t\tidentifiers: new Set(annotated.unannotatedTypes.map((t) => t.identifier)),\n\t\t\t};\n\t\t});\n\n\t\treturn proxy;\n\t}\n\n\tpublic evaluate(): AllowedTypesFullInternalEvaluated {\n\t\treturn this.lazyEvaluate.value.annotated;\n\t}\n\n\tpublic evaluateSet(): ReadonlySet<TreeNodeSchema> {\n\t\treturn this.lazyEvaluate.value.set;\n\t}\n\n\tpublic evaluateIdentifiers(): ReadonlySet<string> {\n\t\treturn this.lazyEvaluate.value.identifiers;\n\t}\n\n\tpublic static override [Symbol.hasInstance]<\n\t\tTThis extends\n\t\t\t| (abstract new (\n\t\t\t\t\t...args: unknown[]\n\t\t\t ) => object)\n\t\t\t| typeof AnnotatedAllowedTypesInternal,\n\t>(\n\t\tthis: TThis,\n\t\tvalue: ErasedBaseType | InstanceTypeRelaxed<TThis> | ImplicitAllowedTypes,\n\t): value is InstanceTypeRelaxed<TThis> & AnnotatedAllowedTypesInternal & AllowedTypesFull {\n\t\treturn Object.prototype.isPrototypeOf.call(this.prototype, value);\n\t}\n\n\tpublic static override narrow<\n\t\tTThis extends\n\t\t\t| (abstract new (\n\t\t\t\t\t...args: unknown[]\n\t\t\t ) => object)\n\t\t\t| typeof AnnotatedAllowedTypesInternal,\n\t>(\n\t\tthis: TThis,\n\t\tvalue: ErasedBaseType | InstanceTypeRelaxed<TThis> | ImplicitAllowedTypes,\n\t): asserts value is InstanceTypeRelaxed<TThis> &\n\t\tAnnotatedAllowedTypesInternal &\n\t\tAllowedTypesFull {\n\t\tif (!Object.prototype.isPrototypeOf.call(this.prototype, value)) {\n\t\t\tthrow new TypeError(\"Invalid AnnotatedAllowedTypes instance\");\n\t\t}\n\t}\n\n\tprivate static proxy<const T extends readonly AnnotatedAllowedType[]>(\n\t\tresult: AnnotatedAllowedTypesInternal<T>,\n\t): AnnotatedAllowedTypesInternal<T> & AllowedTypesFull<T> {\n\t\tconst proxy = new Proxy(result, {\n\t\t\tset: () => {\n\t\t\t\tthrow new UsageError(\"AnnotatedAllowedTypes is immutable\");\n\t\t\t},\n\n\t\t\tget: (target, property, receiver) => {\n\t\t\t\t// Hide common array editing methods.\n\t\t\t\tif (property === \"push\" || property === \"pop\") {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\t// Forward array lookup and array methods to the unannotated types array.\n\t\t\t\tif (property in target.unannotatedTypes) {\n\t\t\t\t\treturn Reflect.get(target.unannotatedTypes, property);\n\t\t\t\t}\n\t\t\t\t// Forward anything else to target.\n\t\t\t\treturn Reflect.get(target, property) as unknown;\n\t\t\t},\n\n\t\t\thas: (target, property) => {\n\t\t\t\tif (property in target.unannotatedTypes) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// Forward anything else to target.\n\t\t\t\treturn property in target;\n\t\t\t},\n\n\t\t\townKeys: (target) => {\n\t\t\t\tconst targetKeys = Reflect.ownKeys(target);\n\t\t\t\tconst unannotatedTypesKeys = Reflect.ownKeys(target.unannotatedTypes);\n\t\t\t\treturn [...unannotatedTypesKeys, ...targetKeys];\n\t\t\t},\n\n\t\t\tgetOwnPropertyDescriptor: (target, property) => {\n\t\t\t\tif (Object.prototype.hasOwnProperty.call(target.unannotatedTypes, property)) {\n\t\t\t\t\tconst inner = Object.getOwnPropertyDescriptor(target.unannotatedTypes, property);\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...inner,\n\t\t\t\t\t\t// Since these properties are not on the target, make them non-configurable to confirm with proxy invariants.\n\t\t\t\t\t\tconfigurable: true,\n\t\t\t\t\t\twritable: false,\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\tconst inner = Object.getOwnPropertyDescriptor(target, property);\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...inner,\n\t\t\t\t\t\twritable: false,\n\t\t\t\t\t\t// Allow only array entries to be enumerable.\n\t\t\t\t\t\tenumerable: false,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t\treturn proxy as typeof result & UnannotateAllowedTypesList<T>;\n\t}\n\n\tpublic static create<const T extends readonly AnnotatedAllowedType[]>(\n\t\ttypes: T,\n\t\tmetadata: AllowedTypesMetadata = {},\n\t): AnnotatedAllowedTypesInternal<T> & AllowedTypesFull<T> {\n\t\tconst result = new AnnotatedAllowedTypesInternal(types, metadata);\n\t\treturn result as typeof result & UnannotateAllowedTypesList<T>;\n\t}\n\n\tpublic static createUnannotated<const T extends AllowedTypes>(\n\t\ttypes: T,\n\t\tmetadata: AllowedTypesMetadata = {},\n\t): AnnotatedAllowedTypesInternal & T {\n\t\tconst annotatedTypes: AnnotatedAllowedType[] = types.map(normalizeToAnnotatedAllowedType);\n\t\tconst result = AnnotatedAllowedTypesInternal.create(annotatedTypes, metadata);\n\t\treturn result as typeof result & T;\n\t}\n\n\tpublic static createMixed<\n\t\tconst T extends readonly (AnnotatedAllowedType | LazyItem<TreeNodeSchema>)[],\n\t>(types: T, metadata: AllowedTypesMetadata = {}): AllowedTypesFullFromMixed<T> {\n\t\tconst annotatedTypes: AnnotatedAllowedType[] = types.map(normalizeToAnnotatedAllowedType);\n\t\tconst result = AnnotatedAllowedTypesInternal.create(annotatedTypes, metadata);\n\t\treturn result as AllowedTypesFullFromMixed<T>;\n\t}\n}\n\n/**\n * Annotations that apply to a set of allowed types.\n * @remarks\n * Additional optionals may be added to this as non-breaking changes, so implementations of it should be simple object literals with no unlisted members.\n * @alpha\n * @input\n */\nexport interface AllowedTypesMetadata {\n\t/**\n\t * User defined metadata\n\t */\n\treadonly custom?: unknown;\n}\n\n/**\n * Checks if the given allowed type is annotated with {@link AllowedTypeMetadata}.\n */\nexport function isAnnotatedAllowedType(\n\tallowedType: AnnotatedAllowedType | LazyItem<TreeNodeSchema>,\n): allowedType is AnnotatedAllowedType {\n\tcheckForUninitializedSchema(allowedType);\n\t// Class based schema, and lazy schema references report type \"function\": filtering them out with typeof makes narrowing based on members mostly safe\n\treturn typeof allowedType === \"object\" && \"metadata\" in allowedType && \"type\" in allowedType;\n}\n\n/**\n * Annotations that apply to an individual allowed type.\n * @remarks\n * Additional optionals may be added to this as non-breaking changes, so implementations of it should be simple object literals with no unlisted members.\n * @alpha\n * @input\n */\nexport interface AllowedTypeMetadata {\n\t/**\n\t * User defined metadata\n\t */\n\treadonly custom?: unknown;\n\n\t/**\n\t * If defined, indicates that an allowed type is {@link SchemaStaticsAlpha.staged | staged}.\n\t */\n\treadonly stagedSchemaUpgrade?: SchemaUpgrade;\n}\n\n/**\n * Package internal {@link SchemaUpgrade} construction API.\n */\nexport let createSchemaUpgrade: () => SchemaUpgrade;\n\n/**\n * Unique token used to upgrade schemas and determine if a particular upgrade has been completed.\n * @remarks\n * Create using {@link SchemaStaticsAlpha.staged}.\n * @privateRemarks\n * TODO:#38722 implement runtime schema upgrades.\n * Until then, the class purely behaves mostly as a placeholder.\n * TODO: Consider allowing users to store a name for the upgrade to use in error messages.\n * @sealed @alpha\n */\nexport class SchemaUpgrade {\n\tprotected _typeCheck!: MakeNominal;\n\tstatic {\n\t\tcreateSchemaUpgrade = () => new SchemaUpgrade();\n\t}\n\n\tprivate constructor() {}\n}\n\n/**\n * Types of {@link TreeNode|TreeNodes} or {@link TreeLeafValue|TreeLeafValues} allowed at a location in a tree.\n * @remarks\n * Used by {@link TreeViewConfiguration} for the root and various kinds of {@link TreeNodeSchema} to specify their allowed child types.\n *\n * Use {@link SchemaFactory} to access leaf schema or declare new composite schema.\n *\n * Implicitly treats a single type as an array of one type.\n *\n * Arrays of schema can be used to specify multiple types are allowed, which result in unions of those types in the Tree APIs.\n *\n * When saved into variables, avoid type-erasing the details, as doing so loses the compile time schema awareness of APIs derived from the types.\n *\n * When referring to types that are declared after the definition of the `ImplicitAllowedTypes`, the schema can be wrapped in a lambda to allow the forward reference.\n * See {@link ValidateRecursiveSchema} for details on how to structure the `ImplicitAllowedTypes` instances when constructing recursive schema.\n *\n * Code reading data from this should use {@link normalizeAllowedTypes} to ensure consistent handling, caching, nice errors etc.\n *\n * @example Explicit use with strong typing\n * ```typescript\n * const sf = new SchemaFactory(\"myScope\");\n * const childTypes = [sf.number, sf.string] as const satisfies ImplicitAllowedTypes;\n * const config = new TreeViewConfiguration({ schema: childTypes });\n * ```\n *\n * @example Forward reference\n * ```typescript\n * const sf = new SchemaFactory(\"myScope\");\n * class A extends sf.array(\"example\", [() => B]) {}\n * class B extends sf.array(\"Inner\", sf.number) {}\n * ```\n * @public\n */\nexport type ImplicitAllowedTypes = AllowedTypes | TreeNodeSchema;\n\n/**\n * Removes annotations from a list of allowed types that may contain annotations.\n * @system @alpha\n */\nexport type UnannotateAllowedTypesList<\n\tT extends readonly (AnnotatedAllowedType | LazyItem<TreeNodeSchema>)[],\n> = {\n\t[I in keyof T]: T[I] extends AnnotatedAllowedType<infer X> ? X : T[I];\n};\n\n/**\n * Add annotations to a list of allowed types that may or may not contain annotations.\n * @system @alpha\n */\nexport type AnnotateAllowedTypesList<\n\tT extends readonly (AnnotatedAllowedType | LazyItem<TreeNodeSchema>)[],\n> = {\n\t[I in keyof T]: T[I] extends AnnotatedAllowedType<unknown>\n\t\t? T[I]\n\t\t: AnnotatedAllowedType<T[I]>;\n};\n\n/**\n * Normalizes an {@link ImplicitAllowedTypes} to an {@link AllowedTypesFull}.\n * @alpha\n */\nexport function normalizeAllowedTypes(types: ImplicitAllowedTypes): AllowedTypesFull {\n\treturn normalizeAllowedTypesInternal(types);\n}\n\n/**\n * Normalizes an allowed type to an {@link AnnotatedAllowedType}, by adding empty annotations if they don't already exist.\n */\nexport function normalizeToAnnotatedAllowedType<T extends LazyItem<TreeNodeSchema>>(\n\ttype: T | AnnotatedAllowedType<T>,\n): AnnotatedAllowedType<T> {\n\treturn isAnnotatedAllowedType(type)\n\t\t? type\n\t\t: {\n\t\t\t\tmetadata: {},\n\t\t\t\ttype,\n\t\t\t};\n}\n\n/**\n * See note inside {@link normalizeAllowedTypesInternal}.\n */\nconst cachedNormalize = new WeakMap<ImplicitAllowedTypes, AllowedTypesFullInternal>();\n\n/**\n * Normalizes allowed types to an {@link AllowedTypesFullInternal}.\n */\nexport function normalizeAllowedTypesInternal(\n\ttype: ImplicitAllowedTypes,\n): AllowedTypesFullInternal {\n\tif (isAnnotatedAllowedTypes(type)) {\n\t\treturn type;\n\t}\n\n\t// This caching accomplishes two things:\n\t// 1. It avoids redundant computations for the same input.\n\t// 2. It provides a stable object identity for the output in case the input is normalized twice and other systems (such as unhydrated contexts) are cached based on the object identity of the output.\n\t// It is this second case which is the more important since creating the AnnotatedAllowedTypesInternal is rather cheap.\n\t// Adding this cache improved the performance of the \"large recursive union\" test (which mostly just constructs a TreeConfiguration) by ~5 times.\n\t// This cache is strictly a performance optimization: it is not required for correctness.\n\treturn getOrCreate(cachedNormalize, type, () => {\n\t\t// Due to more specific internal type, the above does not narrow sufficiently, so more narrowing is needed.\n\t\t// It is possible this will give a false error if a TreeNodeSchema which matches this check is used.\n\t\tassert(\n\t\t\t!(\"types\" in type && \"metadata\" in type),\n\t\t\t0xc7d /* invalid AnnotatedAllowedTypes */,\n\t\t);\n\n\t\tconst annotatedTypes: AnnotatedAllowedType[] = (isReadonlyArray(type) ? type : [type]).map(\n\t\t\tnormalizeToAnnotatedAllowedType,\n\t\t);\n\n\t\treturn AnnotatedAllowedTypesInternal.create(annotatedTypes);\n\t});\n}\n\n/**\n * Normalizes an {@link ImplicitAllowedTypes} to an {@link AllowedTypesFullInternalEvaluated} by eagerly evaluating any\n * lazy schema declarations and adding empty metadata if it doesn't already exist.\n *\n * @remarks Note: this must only be called after all required schemas have been declared, otherwise evaluation of\n * recursive schemas may fail.\n */\nexport function normalizeAndEvaluateAnnotatedAllowedTypes(\n\ttypes: ImplicitAllowedTypes,\n): AllowedTypesFullInternalEvaluated {\n\treturn normalizeAllowedTypesInternal(types).evaluate();\n}\n\nconst cachedLazyItem = new WeakMap<() => unknown, unknown>();\n\n/**\n * Returns the schema referenced by the {@link LazyItem}.\n * @remarks\n * Caches results to handle {@link LazyItem}s which compute their resulting schema.\n * @alpha\n */\nexport function evaluateLazySchema<T extends TreeNodeSchema>(value: LazyItem<T>): T {\n\tconst evaluatedSchema = isLazy(value)\n\t\t? (getOrCreate(cachedLazyItem, value, value) as T)\n\t\t: value;\n\n\tcheckForUninitializedSchema(evaluatedSchema);\n\tmarkSchemaMostDerived(evaluatedSchema);\n\treturn evaluatedSchema;\n}\n\n/**\n * Throws a UsageError if the provided schema is undefined, most likely due to being used before it was initialized.\n */\nexport function checkForUninitializedSchema(\n\tschema: ImplicitAllowedTypes | LazyItem<TreeNodeSchema> | AnnotatedAllowedType,\n): void {\n\tif (schema === undefined) {\n\t\tthrow new UsageError(\n\t\t\t`Encountered an undefined schema. This could indicate that some referenced schema has not yet been instantiated. Consider using a lazy schema reference (like \"() => schema\") or delaying the evaluation of the lazy reference if one is already being used.`,\n\t\t);\n\t}\n}\n\n/**\n * Indicates that the provided schema is the \"most derived\" version in its class hierarchy.\n *\n * @param oneTimeInitialize - If true this runs {@link TreeNodeValid.oneTimeInitialize} which does even more initialization and validation.\n * `oneTimeInitialize` can't safely be run until all transitively referenced schema are defined, so which cases can safely use it are more limited.\n * When legal for the caller to set this to true, it is preferred, but it is often not safe due to possible forward references.\n * @remarks\n * See {@link MostDerivedData} and {@link SchemaFactory} for details on what a \"most derived\" schema is and why it matters.\n *\n * This is a helper for invoking {@link TreeNodeValid.markMostDerived} for {@link TreeNodeSchema}.\n *\n * Calling this helps with error messages about invalid schema usage (See {@link SchemaFactory} for the rules, some of which this helps validate).\n * Typically this should be called for each schema as early as practical to improve error reporting for invalid usages of schema\n * (using two different schema derived from the same {@link SchemaFactory} produced base class).\n *\n * Note that construction of actual {@link TreeNode} instances or use of a schema transitively in a {@link TreeViewConfiguration} already do this,\n * so any calls to this that is unconditionally after that point for the given schema is not needed.\n * Instead most usages of this should be from those cases, and from miscellaneous cases where a schema is passed into an public API where theoretically someone could accidentally\n * pass in a base class of a schema instead of the most derived one.\n */\nexport function markSchemaMostDerived(\n\tschema: TreeNodeSchema,\n\toneTimeInitialize = false,\n): void {\n\t// Leaf schema are not classes, and thus do not need to be marked as most derived.\n\tif (schema.kind === NodeKind.Leaf) {\n\t\treturn;\n\t}\n\n\tconst schemaValid = schemaAsTreeNodeValid(schema);\n\n\tif (oneTimeInitialize) {\n\t\tschemaValid.oneTimeInitialize();\n\t} else {\n\t\tschemaValid.markMostDerived();\n\t}\n}\n\n/**\n * Type of tree node for a field of the given schema.\n * @public\n */\nexport type TreeNodeFromImplicitAllowedTypes<\n\tTSchema extends ImplicitAllowedTypes = TreeNodeSchema,\n> = TSchema extends TreeNodeSchema\n\t? NodeFromSchema<TSchema>\n\t: TSchema extends AllowedTypes\n\t\t? NodeFromSchema<FlexListToUnion<TSchema>>\n\t\t: unknown;\n\n/**\n * This type exists only to be linked from documentation to provide a single linkable place to document some details of\n * \"Input\" types and how they handle schema.\n *\n * When a schema is used to describe data which is an input into an API, the API is [contravariant](https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)) over the schema.\n * (See also, [TypeScript Variance Annotations](https://www.typescriptlang.org/docs/handbook/2/generics.html#variance-annotations)).\n *\n * Since these schema are expressed using TypeScript types, it is possible for the user of the API to provide non-exact values of these types which has implications that depended on the variance.\n *\n * Consider a field with schema type of `A | B` (where A and B are types of schema).\n *\n * - Reading the field behaves covariantly so {@link NodeFromSchema} of `<A | B>` is the same as `NodeFromSchema<A> | NodeFromSchema<B>`, indicating that either type of node can be read from the field.\n *\n * - Writing to the field behaves contravariantly. Since it is unknown if the node actually has a schema `A` or a schema `B`, the only legal values (known to be in schema regardless of which schema the underlying node has) are values which are legal for both `A & B`.\n *\n * Note that this is distinct from the case where the schema is `[A, B]`.\n * In this case it is known that the field allows both A and B (the field can be set to an A or a B value).\n * When `A | B` is used, the field might allow\n * A but not B (so assigning a B value would be out of schema),\n * B but not A (so assigning an A value would be out of schema)\n * or both A and B.\n *\n * This gets more extreme when given completely unspecified schema.\n * For example if a field is just provided {@link ImplicitFieldSchema}, nothing is known about the content of the field.\n * This means that reading the field (via {@link TreeFieldFromImplicitField}) can give any valid tree field content,\n * but there are no safe values which could be written to the field (since it is unknown what values would be out of schema) so {@link InsertableTreeFieldFromImplicitField} gives `never`.\n *\n * To implement this variance correctly, the computation of types for input and output have to use separate utilities\n * which take very different approaches when encountering non-exact schema like unions or `ImplicitFieldSchema`.\n * The utilities which behave contravariantly (as required to handle input correctly) link this documentation to indicate that this is how they behave.\n *\n * In addition to behaving contravariantly, these input type computation utilities often have further limitations.\n * This is due to TypeScript making it difficult to implement this contravariance exactly.\n * When faced with these implementation limitations these contravariant type computation utilities error on the side of producing overly strict requirements.\n * For example in the above case of `A | B`, the utilities might compute an allowed insertable type as `never` even if there happens to be a common value accepted by both `A` and `B`.\n * Future versions of the API can relax these requirements as the type computations are made more accurate.\n *\n * For a more concrete example: if {@link InsertableTreeFieldFromImplicitField} produced `never` for a schema `A | OptionalField<A>`,\n * a future version could instead return a more flexible but still safe type, like `A`.\n *\n * More generally: try to avoid providing non-exact schema, especially for the fields of other schema.\n * While these APIs attempt to handle such cases correctly, there are limitations and known bugs in this handling.\n * Code using non-exact schema is much more likely to have its compilation break due to updates of this package or even TypeScript,\n * and thus compilation breaks due to edge cases of non-exact schema handling, especially with recursive schema, are not considered breaking changes.\n * This may change as the API become more stable.\n *\n * @privateRemarks\n * There likely is a better way to share this documentation, but none was found at the time of writing.\n *\n * TODO: Once {@link InsertableField} is public, consider using it in the examples above.\n * @system @public\n */\nexport type Input<T extends never> = T;\n\n/**\n * Type of content that can be inserted into the tree for a node of the given schema.\n *\n * @see {@link Input}\n *\n * @typeparam TSchema - Schema to process.\n *\n * @privateRemarks\n * This is a bit overly conservative, since cases like `A | [A]` give never and could give `A`.\n * @public\n */\nexport type InsertableTreeNodeFromImplicitAllowedTypes<TSchema extends ImplicitAllowedTypes> =\n\t[TSchema] extends [TreeNodeSchema]\n\t\t? InsertableTypedNode<TSchema>\n\t\t: [TSchema] extends [AllowedTypes]\n\t\t\t? InsertableTreeNodeFromAllowedTypes<TSchema>\n\t\t\t: never;\n\n/**\n * Type of content that can be inserted into the tree for a node of the given schema.\n *\n * @see {@link Input}\n *\n * @typeparam TList - AllowedTypes to process\n *\n * @privateRemarks\n * This loop is non-recursive to allow larger unions before hitting the recursion limit in TypeScript.\n * @system @public\n */\nexport type InsertableTreeNodeFromAllowedTypes<TList extends AllowedTypes> =\n\tIsUnion<TList> extends true\n\t\t? never\n\t\t: {\n\t\t\t\treadonly [Property in keyof TList]: [TList[Property]] extends [\n\t\t\t\t\tLazyItem<infer TSchema extends TreeNodeSchema>,\n\t\t\t\t]\n\t\t\t\t\t? InsertableTypedNode<TSchema>\n\t\t\t\t\t: never;\n\t\t\t}[NumberKeys<TList>];\n\n/**\n * Extracts the keys of `T` which are numbers.\n * @remarks\n * The keys are extracted as strings which can be used to index `T`.\n *\n * This handles cases like `{ x: 4 } & [5, 6]` returning `\"0\"` and `\"1\"`.\n * Such cases are difficult to handle since `keyof` includes `number` in such cases, but the type can not be indexed by `number`.\n * @system @public\n */\nexport type NumberKeys<\n\tT,\n\tTransformed = {\n\t\treadonly [Property in keyof T as number extends Property ? never : Property]: Property;\n\t},\n> = Transformed[`${number}` & keyof Transformed];\n"]}
|
|
@@ -186,7 +186,7 @@ function hydrator(locatedNodes, forest) {
|
|
|
186
186
|
// Find or create one as necessary.
|
|
187
187
|
for (const { path, node } of batch.paths) {
|
|
188
188
|
const anchor = forest.anchors.track(path);
|
|
189
|
-
const anchorNode = forest.anchors.locate(anchor) ?? fail(
|
|
189
|
+
const anchorNode = forest.anchors.locate(anchor) ?? fail(0xc7b /* missing anchor */);
|
|
190
190
|
let flexNode = anchorNode.slots.get(flexTreeSlot);
|
|
191
191
|
if (flexNode === undefined) {
|
|
192
192
|
// the flex node must be created
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepareForInsertion.js","sourceRoot":"","sources":["../../src/simple-tree/prepareForInsertion.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 type {\n\tSchemaAndPolicy,\n\tIForestSubscription,\n\tUpPath,\n\tFieldKey,\n\tDetachedField,\n\tTreeFieldStoredSchema,\n\tTreeTypeSet,\n} from \"../core/index.js\";\nimport {\n\ttype FlexTreeContext,\n\tgetSchemaAndPolicy,\n\ttype FlexTreeHydratedContextMinimal,\n\tFieldKinds,\n\ttype FlexibleFieldContent,\n\ttype FlexibleNodeContent,\n\tthrowOutOfSchema,\n\tflexTreeSlot,\n\tContextSlot,\n\tgetOrCreateHydratedFlexTreeNode,\n\tassertFlexTreeEntityNotFreed,\n} from \"../feature-libraries/index.js\";\nimport type { ImplicitFieldSchema } from \"./fieldSchema.js\";\nimport {\n\ttype InsertableContent,\n\tunhydratedFlexTreeFromInsertable,\n} from \"./unhydratedFlexTreeFromInsertable.js\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\nimport { brand, type Mutable } from \"../util/index.js\";\nimport {\n\tgetKernel,\n\ttype ImplicitAllowedTypes,\n\ttype TreeNode,\n\ttype UnhydratedFlexTreeNode,\n} from \"./core/index.js\";\nimport { debugAssert, fail, oob } from \"@fluidframework/core-utils/internal\";\nimport { isFieldInSchema } from \"../feature-libraries/index.js\";\n\n/**\n * For now, schema validation for inserted content is always enabled.\n * @remarks\n * If this ends up being too much of a performance overhead, AND nothing depends on it (like staged allowed types likely will),\n * this could be changed.\n */\nconst validateSchema = true;\n\n/**\n * Prepare content from a user for insertion into a tree.\n * @remarks\n * This validates and converts the input, and if necessary invokes {@link prepareContentForHydration}.\n *\n * The next edit made to `destinationContext`'s forest must be the creation of a detached field containing this content,\n * (Triggering {@link ForestEvents.afterRootFieldCreated}) otherwise hydration will break.\n */\nexport function prepareForInsertion<TIn extends InsertableContent | undefined>(\n\tdata: TIn,\n\tschema: ImplicitFieldSchema,\n\tdestinationContext: FlexTreeContext,\n\tdestinationSchema: TreeFieldStoredSchema,\n): TIn extends undefined ? undefined : FlexibleNodeContent {\n\treturn prepareForInsertionContextless(\n\t\tdata,\n\t\tschema,\n\t\tgetSchemaAndPolicy(destinationContext),\n\t\tdestinationContext.isHydrated() ? destinationContext : undefined,\n\t\tdestinationSchema,\n\t);\n}\n\n/**\n * {@link prepareForInsertion} but batched for array content.\n * @remarks\n * This is for inserting items into an array, not a inserting a {@link TreeArrayNode} (that would use {@link prepareForInsertion}).\n *\n * The next edits made to `destinationContext`'s forest must be the creation of a detached field.\n * One edit for each item in `data`, in order.\n *\n * @privateRemarks\n * This has to be done as a single operation for all items in data\n * (as opposed to mapping {@link prepareForInsertion} over the array)\n * due to how the eventing in prepareContentForHydration works.\n */\nexport function prepareArrayContentForInsertion(\n\tdata: readonly InsertableContent[],\n\tschema: ImplicitAllowedTypes,\n\tdestinationContext: FlexTreeContext,\n\tdestinationSchema: TreeTypeSet,\n): FlexibleFieldContent {\n\tconst mapTrees: UnhydratedFlexTreeNode[] = data.map((item) =>\n\t\tunhydratedFlexTreeFromInsertable(item, schema),\n\t);\n\n\tvalidateAndPrepare(\n\t\tgetSchemaAndPolicy(destinationContext),\n\t\tdestinationContext.isHydrated() ? destinationContext : undefined,\n\t\t{\n\t\t\tkind: FieldKinds.sequence.identifier,\n\t\t\ttypes: destinationSchema,\n\t\t\tpersistedMetadata: undefined,\n\t\t},\n\t\tmapTrees,\n\t);\n\n\treturn mapTrees;\n}\n\n/**\n * Split out from {@link prepareForInsertion} as to allow use without a context.\n *\n * @param hydratedData - If specified, the `mapTrees` will be prepared for hydration into this context.\n * `undefined` when `mapTrees` are being inserted into an {@link Unhydrated} tree.\n *\n * @remarks\n * Adding this entry point is a workaround for initialize not currently having a context.\n */\nexport function prepareForInsertionContextless<TIn extends InsertableContent | undefined>(\n\tdata: TIn,\n\tschema: ImplicitFieldSchema,\n\tschemaAndPolicy: SchemaAndPolicy,\n\thydratedData: FlexTreeHydratedContextMinimal | undefined,\n\tdestinationSchema: TreeFieldStoredSchema,\n\tscheduleHydrationOverride?: HydrationScheduler,\n): TIn extends undefined ? undefined : FlexibleNodeContent {\n\tconst mapTree = unhydratedFlexTreeFromInsertable(data, schema);\n\n\tconst contentArray = mapTree === undefined ? [] : [mapTree];\n\tvalidateAndPrepare(\n\t\tschemaAndPolicy,\n\t\thydratedData,\n\t\tdestinationSchema,\n\t\tcontentArray,\n\t\tscheduleHydrationOverride,\n\t);\n\n\treturn mapTree;\n}\n\n/**\n * If hydrating, do a final validation against the schema and prepare the content for hydration.\n *\n * @param hydratedData - If specified, the `mapTrees` will be prepared for hydration into this context.\n * `undefined` when `mapTrees` are being inserted into an {@link Unhydrated} tree.\n */\nfunction validateAndPrepare(\n\tschemaAndPolicy: SchemaAndPolicy,\n\thydratedData: FlexTreeHydratedContextMinimal | undefined,\n\tfieldSchema: TreeFieldStoredSchema,\n\tmapTrees: readonly UnhydratedFlexTreeNode[],\n\tscheduleHydrationOverride?: HydrationScheduler,\n): void {\n\tif (hydratedData !== undefined) {\n\t\t// Run `prepareContentForHydration` before walking the tree in `isFieldInSchema`.\n\t\t// This ensures that when `isFieldInSchema` requests identifiers (or any other contextual defaults),\n\t\t// they were already creating used the more specific context we have access to from `hydratedData`.\n\t\tprepareContentForHydration(\n\t\t\tmapTrees,\n\t\t\tscheduleHydrationOverride ??\n\t\t\t\t((batch, doHydration) =>\n\t\t\t\t\tscheduleHydration(batch, hydratedData.checkout.forest, doHydration)),\n\t\t\thydratedData,\n\t\t);\n\t\t// TODO: AB#45723\n\t\t// Now that staged schema rely on this validation, its a bit odd we don't do it for insertion into unhydrated contexts.\n\t\t// We can't simply enable it for them however due to contextual default fields which would not have been created yet (see comment above).\n\t\t// Specifically at least clone can result in unhydrated trees which can end up violating their stored schema (but not view schema) just using the type safe APIs.\n\t\tif (validateSchema === true) {\n\t\t\tisFieldInSchema(mapTrees, fieldSchema, schemaAndPolicy, throwOutOfSchema);\n\t\t}\n\t}\n}\n\n/**\n * The path from the included node to the root of the content tree it was inserted as part of.\n */\ninterface RelativeNodePath {\n\treadonly path: UpPath;\n\treadonly node: TreeNode;\n}\n\n/**\n * {@link RelativeNodePath}s for every {@link TreeNode} in the content tree inserted as an atomic operation.\n */\ninterface LocatedNodesBatch {\n\t/**\n\t * UpPath shared by all {@link RelativeNodePath}s in this batch corresponding to the root of the inserted content.\n\t */\n\treadonly rootPath: Mutable<UpPath>;\n\treadonly paths: RelativeNodePath[];\n}\n\n/**\n * A dummy key value used in {@link LocatedNodesBatch.rootPath} which will be replaced with the actual detached field once it is known.\n */\nconst placeholderKey: DetachedField & FieldKey = brand(\"placeholder\" as const);\n\n/**\n * Records any {@link TreeNode}s in the given `content` tree and does the necessary bookkeeping to ensure they are synchronized with subsequent reads of the tree.\n * Additionally populates any {@link UnhydratedFlexTreeField.pendingDefault}s using the provided `context`.\n *\n * @remarks If the content tree contains has any associated {@link TreeNode}s, this function must be called just prior to inserting the content into the tree.\n * Specifically, no other content may be inserted into the tree between the invocation of this function and the insertion of `content`.\n * The insertion of `content` must occur or else this function will cause memory leaks.\n *\n * Exported for testing purposes: otherwise should not be used outside this module.\n * @param content - the content subsequence to be inserted, of which might deeply contain {@link TreeNode}s which need to be hydrated.\n * @param forest - the forest the content is being inserted into.\n */\nexport function prepareContentForHydration(\n\tcontent: readonly UnhydratedFlexTreeNode[],\n\tscheduler: HydrationScheduler,\n\tcontext: FlexTreeHydratedContextMinimal,\n): void {\n\tconst batches: LocatedNodesBatch[] = [];\n\tfor (const item of content) {\n\t\tconst batch: LocatedNodesBatch = {\n\t\t\trootPath: {\n\t\t\t\tparent: undefined,\n\t\t\t\tparentField: placeholderKey,\n\t\t\t\tparentIndex: 0,\n\t\t\t},\n\t\t\tpaths: [],\n\t\t};\n\t\tbatches.push(batch);\n\t\twalkMapTree(\n\t\t\titem,\n\t\t\tbatch.rootPath,\n\t\t\t(p, node) => {\n\t\t\t\tbatch.paths.push({ path: p, node });\n\t\t\t},\n\t\t\tcontext,\n\t\t);\n\t}\n\n\tconst doHydration = hydrator(batches, context.checkout.forest);\n\tscheduler(batches, doHydration);\n}\n\nfunction walkMapTree(\n\troot: UnhydratedFlexTreeNode,\n\tpath: UpPath,\n\tonVisitTreeNode: (path: UpPath, treeNode: TreeNode) => void,\n\tcontext: FlexTreeHydratedContextMinimal,\n): void {\n\tif (root.parentField.parent.parent !== undefined) {\n\t\tthrow new UsageError(\n\t\t\t\"Attempted to insert a node which is already under a parent. If this is desired, remove the node from its parent before inserting it elsewhere.\",\n\t\t);\n\t}\n\n\ttype Next = [path: UpPath, tree: UnhydratedFlexTreeNode];\n\tconst nexts: Next[] = [];\n\tfor (let next: Next | undefined = [path, root]; next !== undefined; next = nexts.pop()) {\n\t\tconst [p, node] = next;\n\t\tif (node !== undefined) {\n\t\t\tconst treeNode = node.treeNode;\n\t\t\tif (treeNode !== undefined) {\n\t\t\t\tonVisitTreeNode(p, treeNode);\n\t\t\t}\n\t\t}\n\n\t\tfor (const [key, field] of node.allFieldsLazy) {\n\t\t\tfield.fillPendingDefaults(context);\n\t\t\tfor (const [i, child] of field.children.entries()) {\n\t\t\t\tnexts.push([\n\t\t\t\t\t{\n\t\t\t\t\t\tparent: p,\n\t\t\t\t\t\tparentField: key,\n\t\t\t\t\t\tparentIndex: i,\n\t\t\t\t\t},\n\t\t\t\t\tchild,\n\t\t\t\t]);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * A function which can schedule hydration of batches of nodes to occur at a later time (which must be after they have been inserted into the tree).\n */\ntype HydrationScheduler = (\n\tlocatedNodes: readonly LocatedNodesBatch[],\n\t/**\n\t * Does the actual hydration. Should be called for each index in `locatedNodes` once the corresponding content has been inserted into the tree.\n\t */\n\tdoHydration: Hydrator,\n) => void;\n\n/**\n * Does the actual hydration.\n * The provided `attachPath` is the path the content is currently under (where it was attached in the tree).\n */\ntype Hydrator = (batch: LocatedNodesBatch, attachPath: UpPath) => void;\n\n/**\n * Register events which will hydrate batches of nodes when they are inserted.\n * The next edits to forest must be their insertions, in order, or data corruption can occur.\n * @param locatedNodes - the nodes to register with the forest.\n * Each index in this array expects its content to be added and produce its own `afterRootFieldCreated` event.\n * If array subsequence insertion is optimized to produce a single event, this will not work correctly as is, and will need to be modified to take in a single {@link LocatedNodesBatch}.\n */\nfunction scheduleHydration(\n\tlocatedNodes: readonly LocatedNodesBatch[],\n\tforest: IForestSubscription,\n\tdoHydration: Hydrator,\n): void {\n\t// Only subscribe to the event if there is at least one TreeNode tree to hydrate - this is not the case when inserting an empty array [].\n\tif (locatedNodes.length > 0) {\n\t\t// Creating a new array emits one event per element in the array, so listen to the event once for each element\n\t\tlet index = 0;\n\t\tconst off = forest.events.on(\"afterRootFieldCreated\", (fieldKey) => {\n\t\t\t// Indexing is safe here because of the length check above. This assumes the array has not been modified which should be the case.\n\t\t\tconst batch = locatedNodes[index] ?? oob();\n\t\t\tdoHydration(batch, { parent: undefined, parentField: fieldKey, parentIndex: 0 });\n\t\t\tif (++index === locatedNodes.length) {\n\t\t\t\toff();\n\t\t\t}\n\t\t});\n\t}\n}\n\n/**\n * Implementation of {@link Hydrator}.\n */\nfunction hydrator(\n\tlocatedNodes: readonly LocatedNodesBatch[],\n\tforest: IForestSubscription,\n): (batch: LocatedNodesBatch, attachedPath: UpPath) => void {\n\treturn (batch: LocatedNodesBatch, attachedPath: UpPath) => {\n\t\tconst context = forest.anchors.slots.get(ContextSlot) ?? fail(0xb41 /* missing context */);\n\n\t\t// Modify paths in batch to point to correct location:\n\t\tdebugAssert(() => batch.rootPath.parentField === placeholderKey);\n\t\tbatch.rootPath.parentField = attachedPath.parentField;\n\t\tbatch.rootPath.parent = attachedPath.parent;\n\t\tbatch.rootPath.parentIndex = attachedPath.parentIndex;\n\n\t\t// To hydrate a TreeNode, it must be associated with a HydratedFlexTreeNode.\n\t\t// Find or create one as necessary.\n\t\tfor (const { path, node } of batch.paths) {\n\t\t\tconst anchor = forest.anchors.track(path);\n\t\t\tconst anchorNode = forest.anchors.locate(anchor) ?? fail(\"missing anchor\");\n\n\t\t\tlet flexNode = anchorNode.slots.get(flexTreeSlot);\n\t\t\tif (flexNode === undefined) {\n\t\t\t\t// the flex node must be created\n\t\t\t\tconst cursor = forest.allocateCursor(\"getFlexNode\");\n\t\t\t\tforest.moveCursorToPath(anchorNode, cursor);\n\n\t\t\t\tflexNode = getOrCreateHydratedFlexTreeNode(context, cursor);\n\t\t\t\tcursor.free();\n\t\t\t\tassertFlexTreeEntityNotFreed(flexNode);\n\t\t\t}\n\n\t\t\tgetKernel(node).hydrate(flexNode);\n\t\t\tforest.anchors.forget(anchor);\n\t\t}\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"prepareForInsertion.js","sourceRoot":"","sources":["../../src/simple-tree/prepareForInsertion.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 type {\n\tSchemaAndPolicy,\n\tIForestSubscription,\n\tUpPath,\n\tFieldKey,\n\tDetachedField,\n\tTreeFieldStoredSchema,\n\tTreeTypeSet,\n} from \"../core/index.js\";\nimport {\n\ttype FlexTreeContext,\n\tgetSchemaAndPolicy,\n\ttype FlexTreeHydratedContextMinimal,\n\tFieldKinds,\n\ttype FlexibleFieldContent,\n\ttype FlexibleNodeContent,\n\tthrowOutOfSchema,\n\tflexTreeSlot,\n\tContextSlot,\n\tgetOrCreateHydratedFlexTreeNode,\n\tassertFlexTreeEntityNotFreed,\n} from \"../feature-libraries/index.js\";\nimport type { ImplicitFieldSchema } from \"./fieldSchema.js\";\nimport {\n\ttype InsertableContent,\n\tunhydratedFlexTreeFromInsertable,\n} from \"./unhydratedFlexTreeFromInsertable.js\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\nimport { brand, type Mutable } from \"../util/index.js\";\nimport {\n\tgetKernel,\n\ttype ImplicitAllowedTypes,\n\ttype TreeNode,\n\ttype UnhydratedFlexTreeNode,\n} from \"./core/index.js\";\nimport { debugAssert, fail, oob } from \"@fluidframework/core-utils/internal\";\nimport { isFieldInSchema } from \"../feature-libraries/index.js\";\n\n/**\n * For now, schema validation for inserted content is always enabled.\n * @remarks\n * If this ends up being too much of a performance overhead, AND nothing depends on it (like staged allowed types likely will),\n * this could be changed.\n */\nconst validateSchema = true;\n\n/**\n * Prepare content from a user for insertion into a tree.\n * @remarks\n * This validates and converts the input, and if necessary invokes {@link prepareContentForHydration}.\n *\n * The next edit made to `destinationContext`'s forest must be the creation of a detached field containing this content,\n * (Triggering {@link ForestEvents.afterRootFieldCreated}) otherwise hydration will break.\n */\nexport function prepareForInsertion<TIn extends InsertableContent | undefined>(\n\tdata: TIn,\n\tschema: ImplicitFieldSchema,\n\tdestinationContext: FlexTreeContext,\n\tdestinationSchema: TreeFieldStoredSchema,\n): TIn extends undefined ? undefined : FlexibleNodeContent {\n\treturn prepareForInsertionContextless(\n\t\tdata,\n\t\tschema,\n\t\tgetSchemaAndPolicy(destinationContext),\n\t\tdestinationContext.isHydrated() ? destinationContext : undefined,\n\t\tdestinationSchema,\n\t);\n}\n\n/**\n * {@link prepareForInsertion} but batched for array content.\n * @remarks\n * This is for inserting items into an array, not a inserting a {@link TreeArrayNode} (that would use {@link prepareForInsertion}).\n *\n * The next edits made to `destinationContext`'s forest must be the creation of a detached field.\n * One edit for each item in `data`, in order.\n *\n * @privateRemarks\n * This has to be done as a single operation for all items in data\n * (as opposed to mapping {@link prepareForInsertion} over the array)\n * due to how the eventing in prepareContentForHydration works.\n */\nexport function prepareArrayContentForInsertion(\n\tdata: readonly InsertableContent[],\n\tschema: ImplicitAllowedTypes,\n\tdestinationContext: FlexTreeContext,\n\tdestinationSchema: TreeTypeSet,\n): FlexibleFieldContent {\n\tconst mapTrees: UnhydratedFlexTreeNode[] = data.map((item) =>\n\t\tunhydratedFlexTreeFromInsertable(item, schema),\n\t);\n\n\tvalidateAndPrepare(\n\t\tgetSchemaAndPolicy(destinationContext),\n\t\tdestinationContext.isHydrated() ? destinationContext : undefined,\n\t\t{\n\t\t\tkind: FieldKinds.sequence.identifier,\n\t\t\ttypes: destinationSchema,\n\t\t\tpersistedMetadata: undefined,\n\t\t},\n\t\tmapTrees,\n\t);\n\n\treturn mapTrees;\n}\n\n/**\n * Split out from {@link prepareForInsertion} as to allow use without a context.\n *\n * @param hydratedData - If specified, the `mapTrees` will be prepared for hydration into this context.\n * `undefined` when `mapTrees` are being inserted into an {@link Unhydrated} tree.\n *\n * @remarks\n * Adding this entry point is a workaround for initialize not currently having a context.\n */\nexport function prepareForInsertionContextless<TIn extends InsertableContent | undefined>(\n\tdata: TIn,\n\tschema: ImplicitFieldSchema,\n\tschemaAndPolicy: SchemaAndPolicy,\n\thydratedData: FlexTreeHydratedContextMinimal | undefined,\n\tdestinationSchema: TreeFieldStoredSchema,\n\tscheduleHydrationOverride?: HydrationScheduler,\n): TIn extends undefined ? undefined : FlexibleNodeContent {\n\tconst mapTree = unhydratedFlexTreeFromInsertable(data, schema);\n\n\tconst contentArray = mapTree === undefined ? [] : [mapTree];\n\tvalidateAndPrepare(\n\t\tschemaAndPolicy,\n\t\thydratedData,\n\t\tdestinationSchema,\n\t\tcontentArray,\n\t\tscheduleHydrationOverride,\n\t);\n\n\treturn mapTree;\n}\n\n/**\n * If hydrating, do a final validation against the schema and prepare the content for hydration.\n *\n * @param hydratedData - If specified, the `mapTrees` will be prepared for hydration into this context.\n * `undefined` when `mapTrees` are being inserted into an {@link Unhydrated} tree.\n */\nfunction validateAndPrepare(\n\tschemaAndPolicy: SchemaAndPolicy,\n\thydratedData: FlexTreeHydratedContextMinimal | undefined,\n\tfieldSchema: TreeFieldStoredSchema,\n\tmapTrees: readonly UnhydratedFlexTreeNode[],\n\tscheduleHydrationOverride?: HydrationScheduler,\n): void {\n\tif (hydratedData !== undefined) {\n\t\t// Run `prepareContentForHydration` before walking the tree in `isFieldInSchema`.\n\t\t// This ensures that when `isFieldInSchema` requests identifiers (or any other contextual defaults),\n\t\t// they were already creating used the more specific context we have access to from `hydratedData`.\n\t\tprepareContentForHydration(\n\t\t\tmapTrees,\n\t\t\tscheduleHydrationOverride ??\n\t\t\t\t((batch, doHydration) =>\n\t\t\t\t\tscheduleHydration(batch, hydratedData.checkout.forest, doHydration)),\n\t\t\thydratedData,\n\t\t);\n\t\t// TODO: AB#45723\n\t\t// Now that staged schema rely on this validation, its a bit odd we don't do it for insertion into unhydrated contexts.\n\t\t// We can't simply enable it for them however due to contextual default fields which would not have been created yet (see comment above).\n\t\t// Specifically at least clone can result in unhydrated trees which can end up violating their stored schema (but not view schema) just using the type safe APIs.\n\t\tif (validateSchema === true) {\n\t\t\tisFieldInSchema(mapTrees, fieldSchema, schemaAndPolicy, throwOutOfSchema);\n\t\t}\n\t}\n}\n\n/**\n * The path from the included node to the root of the content tree it was inserted as part of.\n */\ninterface RelativeNodePath {\n\treadonly path: UpPath;\n\treadonly node: TreeNode;\n}\n\n/**\n * {@link RelativeNodePath}s for every {@link TreeNode} in the content tree inserted as an atomic operation.\n */\ninterface LocatedNodesBatch {\n\t/**\n\t * UpPath shared by all {@link RelativeNodePath}s in this batch corresponding to the root of the inserted content.\n\t */\n\treadonly rootPath: Mutable<UpPath>;\n\treadonly paths: RelativeNodePath[];\n}\n\n/**\n * A dummy key value used in {@link LocatedNodesBatch.rootPath} which will be replaced with the actual detached field once it is known.\n */\nconst placeholderKey: DetachedField & FieldKey = brand(\"placeholder\" as const);\n\n/**\n * Records any {@link TreeNode}s in the given `content` tree and does the necessary bookkeeping to ensure they are synchronized with subsequent reads of the tree.\n * Additionally populates any {@link UnhydratedFlexTreeField.pendingDefault}s using the provided `context`.\n *\n * @remarks If the content tree contains has any associated {@link TreeNode}s, this function must be called just prior to inserting the content into the tree.\n * Specifically, no other content may be inserted into the tree between the invocation of this function and the insertion of `content`.\n * The insertion of `content` must occur or else this function will cause memory leaks.\n *\n * Exported for testing purposes: otherwise should not be used outside this module.\n * @param content - the content subsequence to be inserted, of which might deeply contain {@link TreeNode}s which need to be hydrated.\n * @param forest - the forest the content is being inserted into.\n */\nexport function prepareContentForHydration(\n\tcontent: readonly UnhydratedFlexTreeNode[],\n\tscheduler: HydrationScheduler,\n\tcontext: FlexTreeHydratedContextMinimal,\n): void {\n\tconst batches: LocatedNodesBatch[] = [];\n\tfor (const item of content) {\n\t\tconst batch: LocatedNodesBatch = {\n\t\t\trootPath: {\n\t\t\t\tparent: undefined,\n\t\t\t\tparentField: placeholderKey,\n\t\t\t\tparentIndex: 0,\n\t\t\t},\n\t\t\tpaths: [],\n\t\t};\n\t\tbatches.push(batch);\n\t\twalkMapTree(\n\t\t\titem,\n\t\t\tbatch.rootPath,\n\t\t\t(p, node) => {\n\t\t\t\tbatch.paths.push({ path: p, node });\n\t\t\t},\n\t\t\tcontext,\n\t\t);\n\t}\n\n\tconst doHydration = hydrator(batches, context.checkout.forest);\n\tscheduler(batches, doHydration);\n}\n\nfunction walkMapTree(\n\troot: UnhydratedFlexTreeNode,\n\tpath: UpPath,\n\tonVisitTreeNode: (path: UpPath, treeNode: TreeNode) => void,\n\tcontext: FlexTreeHydratedContextMinimal,\n): void {\n\tif (root.parentField.parent.parent !== undefined) {\n\t\tthrow new UsageError(\n\t\t\t\"Attempted to insert a node which is already under a parent. If this is desired, remove the node from its parent before inserting it elsewhere.\",\n\t\t);\n\t}\n\n\ttype Next = [path: UpPath, tree: UnhydratedFlexTreeNode];\n\tconst nexts: Next[] = [];\n\tfor (let next: Next | undefined = [path, root]; next !== undefined; next = nexts.pop()) {\n\t\tconst [p, node] = next;\n\t\tif (node !== undefined) {\n\t\t\tconst treeNode = node.treeNode;\n\t\t\tif (treeNode !== undefined) {\n\t\t\t\tonVisitTreeNode(p, treeNode);\n\t\t\t}\n\t\t}\n\n\t\tfor (const [key, field] of node.allFieldsLazy) {\n\t\t\tfield.fillPendingDefaults(context);\n\t\t\tfor (const [i, child] of field.children.entries()) {\n\t\t\t\tnexts.push([\n\t\t\t\t\t{\n\t\t\t\t\t\tparent: p,\n\t\t\t\t\t\tparentField: key,\n\t\t\t\t\t\tparentIndex: i,\n\t\t\t\t\t},\n\t\t\t\t\tchild,\n\t\t\t\t]);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * A function which can schedule hydration of batches of nodes to occur at a later time (which must be after they have been inserted into the tree).\n */\ntype HydrationScheduler = (\n\tlocatedNodes: readonly LocatedNodesBatch[],\n\t/**\n\t * Does the actual hydration. Should be called for each index in `locatedNodes` once the corresponding content has been inserted into the tree.\n\t */\n\tdoHydration: Hydrator,\n) => void;\n\n/**\n * Does the actual hydration.\n * The provided `attachPath` is the path the content is currently under (where it was attached in the tree).\n */\ntype Hydrator = (batch: LocatedNodesBatch, attachPath: UpPath) => void;\n\n/**\n * Register events which will hydrate batches of nodes when they are inserted.\n * The next edits to forest must be their insertions, in order, or data corruption can occur.\n * @param locatedNodes - the nodes to register with the forest.\n * Each index in this array expects its content to be added and produce its own `afterRootFieldCreated` event.\n * If array subsequence insertion is optimized to produce a single event, this will not work correctly as is, and will need to be modified to take in a single {@link LocatedNodesBatch}.\n */\nfunction scheduleHydration(\n\tlocatedNodes: readonly LocatedNodesBatch[],\n\tforest: IForestSubscription,\n\tdoHydration: Hydrator,\n): void {\n\t// Only subscribe to the event if there is at least one TreeNode tree to hydrate - this is not the case when inserting an empty array [].\n\tif (locatedNodes.length > 0) {\n\t\t// Creating a new array emits one event per element in the array, so listen to the event once for each element\n\t\tlet index = 0;\n\t\tconst off = forest.events.on(\"afterRootFieldCreated\", (fieldKey) => {\n\t\t\t// Indexing is safe here because of the length check above. This assumes the array has not been modified which should be the case.\n\t\t\tconst batch = locatedNodes[index] ?? oob();\n\t\t\tdoHydration(batch, { parent: undefined, parentField: fieldKey, parentIndex: 0 });\n\t\t\tif (++index === locatedNodes.length) {\n\t\t\t\toff();\n\t\t\t}\n\t\t});\n\t}\n}\n\n/**\n * Implementation of {@link Hydrator}.\n */\nfunction hydrator(\n\tlocatedNodes: readonly LocatedNodesBatch[],\n\tforest: IForestSubscription,\n): (batch: LocatedNodesBatch, attachedPath: UpPath) => void {\n\treturn (batch: LocatedNodesBatch, attachedPath: UpPath) => {\n\t\tconst context = forest.anchors.slots.get(ContextSlot) ?? fail(0xb41 /* missing context */);\n\n\t\t// Modify paths in batch to point to correct location:\n\t\tdebugAssert(() => batch.rootPath.parentField === placeholderKey);\n\t\tbatch.rootPath.parentField = attachedPath.parentField;\n\t\tbatch.rootPath.parent = attachedPath.parent;\n\t\tbatch.rootPath.parentIndex = attachedPath.parentIndex;\n\n\t\t// To hydrate a TreeNode, it must be associated with a HydratedFlexTreeNode.\n\t\t// Find or create one as necessary.\n\t\tfor (const { path, node } of batch.paths) {\n\t\t\tconst anchor = forest.anchors.track(path);\n\t\t\tconst anchorNode = forest.anchors.locate(anchor) ?? fail(0xc7b /* missing anchor */);\n\n\t\t\tlet flexNode = anchorNode.slots.get(flexTreeSlot);\n\t\t\tif (flexNode === undefined) {\n\t\t\t\t// the flex node must be created\n\t\t\t\tconst cursor = forest.allocateCursor(\"getFlexNode\");\n\t\t\t\tforest.moveCursorToPath(anchorNode, cursor);\n\n\t\t\t\tflexNode = getOrCreateHydratedFlexTreeNode(context, cursor);\n\t\t\t\tcursor.free();\n\t\t\t\tassertFlexTreeEntityNotFreed(flexNode);\n\t\t\t}\n\n\t\t\tgetKernel(node).hydrate(flexNode);\n\t\t\tforest.anchors.forget(anchor);\n\t\t}\n\t};\n}\n"]}
|
package/lib/treeFactory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"treeFactory.d.ts","sourceRoot":"","sources":["../src/treeFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAMtB,MAAM,6CAA6C,CAAC;AAGrD,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAG1B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAIpD;;;;GAIG;AACH,MAAM,WAAW,WAAY,SAAQ,aAAa,EAAE,YAAY;CAAG;
|
|
1
|
+
{"version":3,"file":"treeFactory.d.ts","sourceRoot":"","sources":["../src/treeFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAMtB,MAAM,6CAA6C,CAAC;AAGrD,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAG1B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAIpD;;;;GAIG;AACH,MAAM,WAAW,WAAY,SAAQ,aAAa,EAAE,YAAY;CAAG;AA6DnE;;;;GAIG;AACH,eAAO,MAAM,UAAU,oDAA2B,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,wBAAwB,CACvC,OAAO,EAAE,qBAAqB,GAC5B,gBAAgB,CAAC,KAAK,CAAC,CAEzB;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,qBAAqB,GAC5B,iBAAiB,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAEpD;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,iBAAiB,GACxB,iBAAiB,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,CASpD"}
|
package/lib/treeFactory.js
CHANGED
|
@@ -19,10 +19,19 @@ function treeKernelFactory(options) {
|
|
|
19
19
|
if (args.idCompressor === undefined) {
|
|
20
20
|
throw new UsageError("IdCompressor must be enabled to use SharedTree");
|
|
21
21
|
}
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const { minVersionForCollab, ...otherOptions } = options;
|
|
23
|
+
const adjustedOptions = {
|
|
24
|
+
...otherOptions,
|
|
25
|
+
// Cases:
|
|
26
|
+
// A. If options specifies minVersionForCollab, it takes precedence over args.minVersionForCollab.
|
|
27
|
+
// This value is set when:
|
|
28
|
+
// - A customer using the declarative SharedTree API specifies the setting at the Shared Tree level.
|
|
29
|
+
// There is currently no way to set it via the declarative API, but it could be added in the future.
|
|
30
|
+
// - treeKernelFactory is invoked in a fuzz test with a specific minVersionForCollab
|
|
31
|
+
// B. Otherwise, we use args.minVersionForCollab, which is propagated from the ContainerRuntime.
|
|
32
|
+
// C. If neither specifies it, we fall back to a default value default of 2.0 since that is the oldest version that supports SharedTree.
|
|
33
|
+
minVersionForCollab: minVersionForCollab ?? args.minVersionForCollab ?? FluidClientVersion.v2_0,
|
|
34
|
+
};
|
|
26
35
|
return new SharedTreeKernel(new Breakable("SharedTree"), args.sharedObject, args.serializer, args.submitLocalMessage, args.lastSequenceNumber, args.logger, args.idCompressor, adjustedOptions);
|
|
27
36
|
}
|
|
28
37
|
return {
|
package/lib/treeFactory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"treeFactory.js","sourceRoot":"","sources":["../src/treeFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAGN,oBAAoB,GAKpB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAEtE,OAAO,EACN,gBAAgB,GAMhB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAExF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAStD;;;;;GAKG;AACH,SAAS,iBAAiB,CACzB,OAAkC;IAElC,SAAS,kBAAkB,CAAC,IAAgB;QAC3C,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,IAAI,UAAU,CAAC,gDAAgD,CAAC,CAAC;QACxE,CAAC;
|
|
1
|
+
{"version":3,"file":"treeFactory.js","sourceRoot":"","sources":["../src/treeFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAGN,oBAAoB,GAKpB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAEtE,OAAO,EACN,gBAAgB,GAMhB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAExF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAStD;;;;;GAKG;AACH,SAAS,iBAAiB,CACzB,OAAkC;IAElC,SAAS,kBAAkB,CAAC,IAAgB;QAC3C,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,IAAI,UAAU,CAAC,gDAAgD,CAAC,CAAC;QACxE,CAAC;QAED,MAAM,EAAE,mBAAmB,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC;QAEzD,MAAM,eAAe,GAAG;YACvB,GAAG,YAAY;YACf,SAAS;YACT,kGAAkG;YAClG,0BAA0B;YAC1B,oGAAoG;YACpG,sGAAsG;YACtG,oFAAoF;YACpF,gGAAgG;YAChG,wIAAwI;YACxI,mBAAmB,EAClB,mBAAmB,IAAI,IAAI,CAAC,mBAAmB,IAAI,kBAAkB,CAAC,IAAI;SAC3E,CAAC;QAEF,OAAO,IAAI,gBAAgB,CAC1B,IAAI,SAAS,CAAC,YAAY,CAAC,EAC3B,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,kBAAkB,EACvB,IAAI,CAAC,kBAAkB,EACvB,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,YAAY,EACjB,eAAe,CACf,CAAC;IACH,CAAC;IAED,OAAO;QACN,MAAM,EAAE,CAAC,IAAgB,EAAoC,EAAE;YAC9D,MAAM,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACnC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACpC,CAAC;QAED,KAAK,CAAC,QAAQ,CACb,IAAgB,EAChB,OAA+B;YAE/B,MAAM,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACnC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC1B,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACpC,CAAC;KACD,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,oBAAoB,CAAC,EAAE,CAAC,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,wBAAwB,CACvC,OAA8B;IAE9B,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,8BAA8B,CAC7C,OAA8B;IAE9B,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,oBAAoB,CACnC,OAA0B;IAE1B,MAAM,mBAAmB,GAA+B;QACvD,IAAI,EAAE,qBAAqB;QAC3B,UAAU,EAAE,oBAAoB;QAChC,sBAAsB,EAAE,mBAAmB;QAC3C,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC;KACnC,CAAC;IAEF,OAAO,oBAAoB,CAAQ,mBAAmB,CAAC,CAAC;AACzD,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IChannelStorageService } from \"@fluidframework/datastore-definitions/internal\";\nimport type { SharedObjectKind } from \"@fluidframework/shared-object-base\";\nimport {\n\ttype ISharedObject,\n\ttype ISharedObjectKind,\n\tmakeSharedObjectKind,\n\ttype KernelArgs,\n\ttype SharedKernelFactory,\n\ttype SharedObjectOptions,\n\ttype FactoryOut,\n} from \"@fluidframework/shared-object-base/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\tSharedTreeKernel,\n\ttype ITreePrivate,\n\ttype SharedTreeOptions,\n\ttype SharedTreeOptionsBeta,\n\ttype SharedTreeOptionsInternal,\n\ttype SharedTreeKernelView,\n} from \"./shared-tree/index.js\";\nimport { SharedTreeFactoryType, SharedTreeAttributes } from \"./sharedTreeAttributes.js\";\nimport type { ITree } from \"./simple-tree/index.js\";\nimport { Breakable } from \"./util/index.js\";\nimport { FluidClientVersion } from \"./codec/index.js\";\n\n/**\n * {@link ITreePrivate} extended with ISharedObject.\n * @remarks\n * This is used when integration testing this package with the Fluid runtime as it exposes the APIs the runtime consumes to manipulate the tree.\n */\nexport interface ISharedTree extends ISharedObject, ITreePrivate {}\n\n/**\n * Creates a factory for shared tree kernels with the given options.\n * @remarks\n * Exposes {@link ITreePrivate} to allow access to internals in tests without a cast.\n * Code exposing this beyond this package will need to update to a more public type.\n */\nfunction treeKernelFactory(\n\toptions: SharedTreeOptionsInternal,\n): SharedKernelFactory<SharedTreeKernelView> {\n\tfunction treeFromKernelArgs(args: KernelArgs): SharedTreeKernel {\n\t\tif (args.idCompressor === undefined) {\n\t\t\tthrow new UsageError(\"IdCompressor must be enabled to use SharedTree\");\n\t\t}\n\n\t\tconst { minVersionForCollab, ...otherOptions } = options;\n\n\t\tconst adjustedOptions = {\n\t\t\t...otherOptions,\n\t\t\t// Cases:\n\t\t\t// A. If options specifies minVersionForCollab, it takes precedence over args.minVersionForCollab.\n\t\t\t// This value is set when:\n\t\t\t// - A customer using the declarative SharedTree API specifies the setting at the Shared Tree level.\n\t\t\t// There is currently no way to set it via the declarative API, but it could be added in the future.\n\t\t\t// - treeKernelFactory is invoked in a fuzz test with a specific minVersionForCollab\n\t\t\t// B. Otherwise, we use args.minVersionForCollab, which is propagated from the ContainerRuntime.\n\t\t\t// C. If neither specifies it, we fall back to a default value default of 2.0 since that is the oldest version that supports SharedTree.\n\t\t\tminVersionForCollab:\n\t\t\t\tminVersionForCollab ?? args.minVersionForCollab ?? FluidClientVersion.v2_0,\n\t\t};\n\n\t\treturn new SharedTreeKernel(\n\t\t\tnew Breakable(\"SharedTree\"),\n\t\t\targs.sharedObject,\n\t\t\targs.serializer,\n\t\t\targs.submitLocalMessage,\n\t\t\targs.lastSequenceNumber,\n\t\t\targs.logger,\n\t\t\targs.idCompressor,\n\t\t\tadjustedOptions,\n\t\t);\n\t}\n\n\treturn {\n\t\tcreate: (args: KernelArgs): FactoryOut<SharedTreeKernelView> => {\n\t\t\tconst k = treeFromKernelArgs(args);\n\t\t\treturn { kernel: k, view: k.view };\n\t\t},\n\n\t\tasync loadCore(\n\t\t\targs: KernelArgs,\n\t\t\tstorage: IChannelStorageService,\n\t\t): Promise<FactoryOut<SharedTreeKernelView>> {\n\t\t\tconst k = treeFromKernelArgs(args);\n\t\t\tawait k.loadCore(storage);\n\t\t\treturn { kernel: k, view: k.view };\n\t\t},\n\t};\n}\n\n/**\n * SharedTree is a hierarchical data structure for collaboratively editing strongly typed JSON-like trees\n * of objects, arrays, and other data types.\n * @legacy @beta\n */\nexport const SharedTree = configuredSharedTree({});\n\n/**\n * {@link SharedTree} but allowing a non-default configuration.\n * @remarks\n * This is useful for debugging and testing.\n * For example it can be used to opt into extra validation or see if opting out of some optimizations fixes an issue.\n *\n * With great care, and knowledge of the support and stability of the options exposed here,\n * this can also be used to opt into some features early or for performance tuning.\n *\n * @example\n * ```typescript\n * import {\n * \tconfiguredSharedTreeBeta,\n * \tForestTypeReference,\n * } from \"fluid-framework/beta\";\n * const SharedTree = configuredSharedTree({\n * \tforest: ForestTypeReference,\n * });\n * ```\n * @privateRemarks\n * The Legacy `ISharedObjectKind<ITree>` type is omitted here for simplicity.\n * @beta\n */\nexport function configuredSharedTreeBeta(\n\toptions: SharedTreeOptionsBeta,\n): SharedObjectKind<ITree> {\n\treturn configuredSharedTree(options);\n}\n\n/**\n * {@link configuredSharedTreeBeta} including the legacy `ISharedObjectKind` type.\n * @privateRemarks\n * This is given a different export name (with legacy appended) to avoid the need to do the special reexport with different types from the fluid-framework package.\n * @legacy @beta\n */\nexport function configuredSharedTreeBetaLegacy(\n\toptions: SharedTreeOptionsBeta,\n): ISharedObjectKind<ITree> & SharedObjectKind<ITree> {\n\treturn configuredSharedTree(options);\n}\n\n/**\n * {@link configuredSharedTreeBetaLegacy} but including `@alpha` options.\n *\n * @example\n * ```typescript\n * import {\n * \tTreeCompressionStrategy,\n * \tconfiguredSharedTree,\n * \tFormatValidatorBasic,\n * \tForestTypeReference,\n * } from \"@fluidframework/tree/internal\";\n * const SharedTree = configuredSharedTree({\n * \tforest: ForestTypeReference,\n * \tjsonValidator: FormatValidatorBasic,\n * \ttreeEncodeType: TreeCompressionStrategy.Uncompressed,\n * });\n * ```\n * @privateRemarks\n * This should be legacy, but has to be internal due to no alpha+legacy being setup yet.\n *\n * This should be renamed to `configuredSharedTreeAlpha` to avoid colliding with the eventual public version which will have less options.\n * @internal\n */\nexport function configuredSharedTree(\n\toptions: SharedTreeOptions,\n): ISharedObjectKind<ITree> & SharedObjectKind<ITree> {\n\tconst sharedObjectOptions: SharedObjectOptions<ITree> = {\n\t\ttype: SharedTreeFactoryType,\n\t\tattributes: SharedTreeAttributes,\n\t\ttelemetryContextPrefix: \"fluid_sharedTree_\",\n\t\tfactory: treeKernelFactory(options),\n\t};\n\n\treturn makeSharedObjectKind<ITree>(sharedObjectOptions);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/tree",
|
|
3
|
-
"version": "2.63.0
|
|
3
|
+
"version": "2.63.0",
|
|
4
4
|
"description": "Distributed tree",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -101,39 +101,40 @@
|
|
|
101
101
|
"temp-directory": "nyc/.nyc_output"
|
|
102
102
|
},
|
|
103
103
|
"dependencies": {
|
|
104
|
-
"@fluid-internal/client-utils": "2.63.0
|
|
105
|
-
"@fluidframework/container-runtime": "2.63.0
|
|
106
|
-
"@fluidframework/core-interfaces": "2.63.0
|
|
107
|
-
"@fluidframework/core-utils": "2.63.0
|
|
108
|
-
"@fluidframework/datastore-definitions": "2.63.0
|
|
109
|
-
"@fluidframework/driver-definitions": "2.63.0
|
|
110
|
-
"@fluidframework/id-compressor": "2.63.0
|
|
111
|
-
"@fluidframework/runtime-definitions": "2.63.0
|
|
112
|
-
"@fluidframework/runtime-utils": "2.63.0
|
|
113
|
-
"@fluidframework/shared-object-base": "2.63.0
|
|
114
|
-
"@fluidframework/telemetry-utils": "2.63.0
|
|
104
|
+
"@fluid-internal/client-utils": "~2.63.0",
|
|
105
|
+
"@fluidframework/container-runtime": "~2.63.0",
|
|
106
|
+
"@fluidframework/core-interfaces": "~2.63.0",
|
|
107
|
+
"@fluidframework/core-utils": "~2.63.0",
|
|
108
|
+
"@fluidframework/datastore-definitions": "~2.63.0",
|
|
109
|
+
"@fluidframework/driver-definitions": "~2.63.0",
|
|
110
|
+
"@fluidframework/id-compressor": "~2.63.0",
|
|
111
|
+
"@fluidframework/runtime-definitions": "~2.63.0",
|
|
112
|
+
"@fluidframework/runtime-utils": "~2.63.0",
|
|
113
|
+
"@fluidframework/shared-object-base": "~2.63.0",
|
|
114
|
+
"@fluidframework/telemetry-utils": "~2.63.0",
|
|
115
115
|
"@sinclair/typebox": "^0.34.13",
|
|
116
116
|
"@tylerbu/sorted-btree-es6": "^1.8.0",
|
|
117
117
|
"@types/ungap__structured-clone": "^1.2.0",
|
|
118
118
|
"@ungap/structured-clone": "^1.2.0",
|
|
119
|
+
"semver-ts": "^1.0.3",
|
|
119
120
|
"uuid": "^11.1.0"
|
|
120
121
|
},
|
|
121
122
|
"devDependencies": {
|
|
122
123
|
"@arethetypeswrong/cli": "^0.17.1",
|
|
123
124
|
"@biomejs/biome": "~1.9.3",
|
|
124
|
-
"@fluid-internal/mocha-test-setup": "2.63.0
|
|
125
|
-
"@fluid-private/stochastic-test-utils": "2.63.0
|
|
126
|
-
"@fluid-private/test-dds-utils": "2.63.0
|
|
127
|
-
"@fluid-private/test-drivers": "2.63.0
|
|
125
|
+
"@fluid-internal/mocha-test-setup": "~2.63.0",
|
|
126
|
+
"@fluid-private/stochastic-test-utils": "~2.63.0",
|
|
127
|
+
"@fluid-private/test-dds-utils": "~2.63.0",
|
|
128
|
+
"@fluid-private/test-drivers": "~2.63.0",
|
|
128
129
|
"@fluid-tools/benchmark": "^0.51.0",
|
|
129
130
|
"@fluid-tools/build-cli": "^0.58.3",
|
|
130
131
|
"@fluidframework/build-common": "^2.0.3",
|
|
131
132
|
"@fluidframework/build-tools": "^0.58.3",
|
|
132
|
-
"@fluidframework/container-definitions": "2.63.0
|
|
133
|
-
"@fluidframework/container-loader": "2.63.0
|
|
133
|
+
"@fluidframework/container-definitions": "~2.63.0",
|
|
134
|
+
"@fluidframework/container-loader": "~2.63.0",
|
|
134
135
|
"@fluidframework/eslint-config-fluid": "^6.0.0",
|
|
135
|
-
"@fluidframework/test-runtime-utils": "2.63.0
|
|
136
|
-
"@fluidframework/test-utils": "2.63.0
|
|
136
|
+
"@fluidframework/test-runtime-utils": "~2.63.0",
|
|
137
|
+
"@fluidframework/test-utils": "~2.63.0",
|
|
137
138
|
"@fluidframework/tree-previous": "npm:@fluidframework/tree@2.62.0",
|
|
138
139
|
"@microsoft/api-extractor": "7.52.11",
|
|
139
140
|
"@types/diff": "^3.5.1",
|
package/src/codec/codec.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type { Static, TAnySchema, TSchema } from "@sinclair/typebox";
|
|
|
10
10
|
|
|
11
11
|
import type { ChangeEncodingContext } from "../core/index.js";
|
|
12
12
|
import type { JsonCompatibleReadOnly } from "../util/index.js";
|
|
13
|
+
import type { MinimumVersionForCollab } from "@fluidframework/runtime-definitions/internal";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Translates decoded data to encoded data.
|
|
@@ -151,7 +152,7 @@ export interface CodecWriteOptions extends ICodecOptions {
|
|
|
151
152
|
* Note that versions older than this should not result in data corruption if they access the data:
|
|
152
153
|
* the data's format should be versioned and if they can't handle the format they should error.
|
|
153
154
|
*/
|
|
154
|
-
readonly
|
|
155
|
+
readonly minVersionForCollab: MinimumVersionForCollab;
|
|
155
156
|
}
|
|
156
157
|
|
|
157
158
|
/**
|
|
@@ -286,7 +287,7 @@ export class MappedDependentFormatVersion<
|
|
|
286
287
|
{
|
|
287
288
|
public constructor(private readonly map: ReadonlyMap<TParentVersion, TChildVersion>) {}
|
|
288
289
|
public lookup(parent: TParentVersion): TChildVersion {
|
|
289
|
-
return this.map.get(parent) ?? fail(
|
|
290
|
+
return this.map.get(parent) ?? fail(0xc73 /* Unknown parent version */);
|
|
290
291
|
}
|
|
291
292
|
}
|
|
292
293
|
|
|
@@ -466,16 +467,6 @@ export function withSchemaValidation<
|
|
|
466
467
|
* For example, document if there is an encoding efficiency improvement of oping into that version or newer.
|
|
467
468
|
* Versions with no notable impact can be omitted.
|
|
468
469
|
*
|
|
469
|
-
* These use numeric values for easy threshold comparisons.
|
|
470
|
-
* Without zero padding, version 2.10 is treated as 2.1, which is numerically less than 2.2.
|
|
471
|
-
* Adding leading zeros to the minor version ensures correct comparisons.
|
|
472
|
-
* For example, version 2.20.0 is encoded as 2.020, and version 2.2.0 is encoded as 2.002.
|
|
473
|
-
* For example FF 2.20.0 is encoded as 2.020 and FF 2.2.0 is encoded as 2.002.
|
|
474
|
-
*
|
|
475
|
-
* Three digits was selected as that will likely be enough, while two digits could easily be too few.
|
|
476
|
-
* If three digits ends up being too few, minor releases of 1000 and higher
|
|
477
|
-
* could still be handled using something like 2.999_00001 without having to change the lower releases.
|
|
478
|
-
*
|
|
479
470
|
* This scheme assumes a single version will always be enough to communicate compatibility.
|
|
480
471
|
* For this to work, compatibility has to be strictly increasing.
|
|
481
472
|
* If this is violated (for example a subset of incompatible features from 3.x that are not in 3.0 are back ported to 2.x),
|
|
@@ -487,7 +478,7 @@ export function withSchemaValidation<
|
|
|
487
478
|
* For example, if needed, would adding more leading zeros to the minor version break things.
|
|
488
479
|
* @alpha
|
|
489
480
|
*/
|
|
490
|
-
export
|
|
481
|
+
export const FluidClientVersion = {
|
|
491
482
|
/**
|
|
492
483
|
* Fluid Framework Client 1.4 and newer.
|
|
493
484
|
* @remarks
|
|
@@ -497,8 +488,10 @@ export enum FluidClientVersion {
|
|
|
497
488
|
*/
|
|
498
489
|
// v1_4 = 1.004,
|
|
499
490
|
|
|
500
|
-
/**
|
|
501
|
-
|
|
491
|
+
/**
|
|
492
|
+
* Fluid Framework Client 2.0 and newer.
|
|
493
|
+
*/
|
|
494
|
+
v2_0: "2.0.0",
|
|
502
495
|
|
|
503
496
|
/** Fluid Framework Client 2.1 and newer. */
|
|
504
497
|
// If we think we might want to start allowing opting into something that landed in 2.1 (without opting into something newer),
|
|
@@ -509,19 +502,8 @@ export enum FluidClientVersion {
|
|
|
509
502
|
/** Fluid Framework Client 2.52 and newer. */
|
|
510
503
|
// New formats introduced in 2.52:
|
|
511
504
|
// - DetachedFieldIndex FormatV2
|
|
512
|
-
v2_52
|
|
513
|
-
|
|
514
|
-
/**
|
|
515
|
-
* Enable unreleased and unfinished features.
|
|
516
|
-
* @remarks
|
|
517
|
-
* Using this value can result in documents which can not be opened in future versions of the framework.
|
|
518
|
-
* It can also result in data corruption by enabling unfinished features which may not handle all cases correctly.
|
|
519
|
-
*
|
|
520
|
-
* This can be used with specific APIs when the caller has knowledge of what specific features those APIs will be opted into with it.
|
|
521
|
-
* This is useful for testing features before they are released, but should not be used in production code.
|
|
522
|
-
*/
|
|
523
|
-
EnableUnstableFeatures = Number.POSITIVE_INFINITY,
|
|
524
|
-
}
|
|
505
|
+
v2_52: "2.52.0",
|
|
506
|
+
} as const satisfies Record<string, MinimumVersionForCollab>;
|
|
525
507
|
|
|
526
508
|
/**
|
|
527
509
|
* An up to date version which includes all the important stable features.
|
|
@@ -532,7 +514,7 @@ export enum FluidClientVersion {
|
|
|
532
514
|
* Update as needed.
|
|
533
515
|
* TODO: Consider using packageVersion.ts to keep this current.
|
|
534
516
|
*/
|
|
535
|
-
export const currentVersion:
|
|
517
|
+
export const currentVersion: MinimumVersionForCollab = FluidClientVersion.v2_0;
|
|
536
518
|
|
|
537
519
|
export interface CodecTree {
|
|
538
520
|
readonly name: string;
|
|
@@ -14,12 +14,12 @@ import {
|
|
|
14
14
|
type IJsonCodec,
|
|
15
15
|
withSchemaValidation,
|
|
16
16
|
type FormatVersion,
|
|
17
|
-
type FluidClientVersion,
|
|
18
17
|
type CodecWriteOptions,
|
|
19
18
|
} from "../codec.js";
|
|
20
19
|
|
|
21
20
|
import { Versioned } from "./format.js";
|
|
22
21
|
import { pkgVersion } from "../../packageVersion.js";
|
|
22
|
+
import type { MinimumVersionForCollab } from "@fluidframework/runtime-definitions/internal";
|
|
23
23
|
|
|
24
24
|
export function makeVersionedCodec<
|
|
25
25
|
TDecoded,
|
|
@@ -45,7 +45,7 @@ export function makeVersionedCodec<
|
|
|
45
45
|
if (!supportedVersions.has(versioned.version)) {
|
|
46
46
|
throw new UsageError(
|
|
47
47
|
`Unsupported version ${versioned.version} encountered while decoding data. Supported versions for this data are: ${Array.from(supportedVersions).join(", ")}.
|
|
48
|
-
The client which encoded this data likely specified an "
|
|
48
|
+
The client which encoded this data likely specified an "minVersionForCollab" value which corresponds to a version newer than the version of this client ("${pkgVersion}").`,
|
|
49
49
|
);
|
|
50
50
|
}
|
|
51
51
|
const decoded = inner.decode(data, context);
|
|
@@ -103,7 +103,7 @@ export function makeVersionDispatchingCodec<TDecoded, TContext>(
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
/**
|
|
106
|
-
* Creates a codec which dispatches to the appropriate member of a codec family based on the `
|
|
106
|
+
* Creates a codec which dispatches to the appropriate member of a codec family based on the `minVersionForCollab` for encode and the
|
|
107
107
|
* version number in data it encounters for decode.
|
|
108
108
|
* @privateRemarks
|
|
109
109
|
* This is a two stage builder so the first stage can encapsulate all codec specific details and the second can bring in configuration.
|
|
@@ -115,17 +115,17 @@ export class ClientVersionDispatchingCodecBuilder<TDecoded, TContext> {
|
|
|
115
115
|
*/
|
|
116
116
|
private readonly family: ICodecFamily<TDecoded, TContext>,
|
|
117
117
|
/**
|
|
118
|
-
* A function which maps a {@link
|
|
118
|
+
* A function which maps a {@link MinimumVersionForCollab} to a version number for the codec family which is supported by that version.
|
|
119
119
|
* This can (and typically does) pick the newest version of the codec which is known to be compatible with the client version so that
|
|
120
120
|
* any improvements in newer versions of the codec can be used when allowed.
|
|
121
121
|
*/
|
|
122
|
-
private readonly versionMapping: (
|
|
122
|
+
private readonly versionMapping: (minVersionForCollab: MinimumVersionForCollab) => number,
|
|
123
123
|
) {}
|
|
124
124
|
|
|
125
125
|
public build(
|
|
126
126
|
options: CodecWriteOptions,
|
|
127
127
|
): IJsonCodec<TDecoded, JsonCompatibleReadOnly, JsonCompatibleReadOnly, TContext> {
|
|
128
|
-
const writeVersion = this.versionMapping(options.
|
|
128
|
+
const writeVersion = this.versionMapping(options.minVersionForCollab);
|
|
129
129
|
return makeVersionDispatchingCodec(this.family, { ...options, writeVersion });
|
|
130
130
|
}
|
|
131
131
|
}
|
|
@@ -84,7 +84,7 @@ export class DetachedFieldIndex {
|
|
|
84
84
|
) {
|
|
85
85
|
this.options = options ?? {
|
|
86
86
|
jsonValidator: FormatValidatorNoOp,
|
|
87
|
-
|
|
87
|
+
minVersionForCollab: FluidClientVersion.v2_0,
|
|
88
88
|
};
|
|
89
89
|
this.codec = makeDetachedFieldIndexCodec(revisionTagCodec, this.options, idCompressor);
|
|
90
90
|
}
|
|
@@ -30,7 +30,7 @@ export function makeDetachedFieldIndexCodec(
|
|
|
30
30
|
): IJsonCodec<DetachedFieldSummaryData> {
|
|
31
31
|
const family = makeDetachedFieldIndexCodecFamily(revisionTagCodec, options, idCompressor);
|
|
32
32
|
const writeVersion =
|
|
33
|
-
options.
|
|
33
|
+
options.minVersionForCollab < FluidClientVersion.v2_52 ? version1 : version2;
|
|
34
34
|
return makeVersionDispatchingCodec(family, { ...options, writeVersion });
|
|
35
35
|
}
|
|
36
36
|
|