@fluidframework/matrix 2.1.0-276985 → 2.1.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.
Files changed (88) hide show
  1. package/.eslintrc.cjs +2 -5
  2. package/CHANGELOG.md +4 -0
  3. package/api-extractor/api-extractor.current.json +5 -0
  4. package/api-extractor/api-extractor.legacy.json +1 -1
  5. package/api-extractor.json +1 -1
  6. package/api-report/matrix.legacy.public.api.md +9 -0
  7. package/dist/handlecache.d.ts +7 -3
  8. package/dist/handlecache.d.ts.map +1 -1
  9. package/dist/handlecache.js +25 -7
  10. package/dist/handlecache.js.map +1 -1
  11. package/dist/handletable.d.ts +3 -1
  12. package/dist/handletable.d.ts.map +1 -1
  13. package/dist/handletable.js.map +1 -1
  14. package/dist/legacy.d.ts +1 -1
  15. package/dist/matrix.d.ts +2 -1
  16. package/dist/matrix.d.ts.map +1 -1
  17. package/dist/matrix.js +23 -9
  18. package/dist/matrix.js.map +1 -1
  19. package/dist/packageVersion.d.ts +1 -1
  20. package/dist/packageVersion.d.ts.map +1 -1
  21. package/dist/packageVersion.js +1 -1
  22. package/dist/packageVersion.js.map +1 -1
  23. package/dist/permutationvector.d.ts +5 -5
  24. package/dist/permutationvector.d.ts.map +1 -1
  25. package/dist/permutationvector.js +11 -4
  26. package/dist/permutationvector.js.map +1 -1
  27. package/dist/public.d.ts +1 -1
  28. package/dist/range.d.ts.map +1 -1
  29. package/dist/range.js.map +1 -1
  30. package/dist/runtime.d.ts.map +1 -1
  31. package/dist/runtime.js.map +1 -1
  32. package/dist/serialization.d.ts.map +1 -1
  33. package/dist/serialization.js.map +1 -1
  34. package/dist/sparsearray2d.d.ts +9 -5
  35. package/dist/sparsearray2d.d.ts.map +1 -1
  36. package/dist/sparsearray2d.js +27 -7
  37. package/dist/sparsearray2d.js.map +1 -1
  38. package/dist/undoprovider.d.ts.map +1 -1
  39. package/dist/undoprovider.js +10 -3
  40. package/dist/undoprovider.js.map +1 -1
  41. package/internal.d.ts +1 -1
  42. package/legacy.d.ts +1 -1
  43. package/lib/handlecache.d.ts +7 -3
  44. package/lib/handlecache.d.ts.map +1 -1
  45. package/lib/handlecache.js +25 -7
  46. package/lib/handlecache.js.map +1 -1
  47. package/lib/handletable.d.ts +3 -1
  48. package/lib/handletable.d.ts.map +1 -1
  49. package/lib/handletable.js.map +1 -1
  50. package/lib/legacy.d.ts +1 -1
  51. package/lib/matrix.d.ts +2 -1
  52. package/lib/matrix.d.ts.map +1 -1
  53. package/lib/matrix.js +23 -9
  54. package/lib/matrix.js.map +1 -1
  55. package/lib/packageVersion.d.ts +1 -1
  56. package/lib/packageVersion.d.ts.map +1 -1
  57. package/lib/packageVersion.js +1 -1
  58. package/lib/packageVersion.js.map +1 -1
  59. package/lib/permutationvector.d.ts +5 -5
  60. package/lib/permutationvector.d.ts.map +1 -1
  61. package/lib/permutationvector.js +11 -4
  62. package/lib/permutationvector.js.map +1 -1
  63. package/lib/public.d.ts +1 -1
  64. package/lib/range.d.ts.map +1 -1
  65. package/lib/range.js.map +1 -1
  66. package/lib/runtime.d.ts.map +1 -1
  67. package/lib/runtime.js.map +1 -1
  68. package/lib/serialization.d.ts.map +1 -1
  69. package/lib/serialization.js.map +1 -1
  70. package/lib/sparsearray2d.d.ts +9 -5
  71. package/lib/sparsearray2d.d.ts.map +1 -1
  72. package/lib/sparsearray2d.js +27 -7
  73. package/lib/sparsearray2d.js.map +1 -1
  74. package/lib/undoprovider.d.ts.map +1 -1
  75. package/lib/undoprovider.js +10 -3
  76. package/lib/undoprovider.js.map +1 -1
  77. package/package.json +36 -30
  78. package/src/handlecache.ts +31 -16
  79. package/src/handletable.ts +11 -9
  80. package/src/matrix.ts +80 -50
  81. package/src/packageVersion.ts +1 -1
  82. package/src/permutationvector.ts +38 -23
  83. package/src/range.ts +1 -1
  84. package/src/runtime.ts +5 -2
  85. package/src/serialization.ts +4 -2
  86. package/src/sparsearray2d.ts +55 -36
  87. package/src/undoprovider.ts +26 -18
  88. package/tsconfig.json +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"range.d.ts","sourceRoot":"","sources":["../src/range.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAOvD"}
1
+ {"version":3,"file":"range.d.ts","sourceRoot":"","sources":["../src/range.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAO9D"}
package/dist/range.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"range.js","sourceRoot":"","sources":["../src/range.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;GAEG;AACH,SAAgB,WAAW,CAAC,KAAa,EAAE,KAAa;IACvD,4EAA4E;IAC5E,MAAM,MAAM,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,iCAAiC;IAE7D,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;QACrB,MAAM,IAAI,UAAU,CAAC,gCAAgC,CAAC,CAAC;IACxD,CAAC;AACF,CAAC;AAPD,kCAOC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Ensures that 0 \\<= 'value' \\< 'limit'. Throws a RangeError otherwise.\n */\nexport function ensureRange(value: number, limit: number) {\n\t// Coerce 'value' to Uint32 so that we can range check with a single branch.\n\tconst _value = value >>> 0; // eslint-disable-line no-bitwise\n\n\tif (_value >= limit) {\n\t\tthrow new RangeError(\"Invalid (row, col) coordinate.\");\n\t}\n}\n"]}
1
+ {"version":3,"file":"range.js","sourceRoot":"","sources":["../src/range.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;GAEG;AACH,SAAgB,WAAW,CAAC,KAAa,EAAE,KAAa;IACvD,4EAA4E;IAC5E,MAAM,MAAM,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,iCAAiC;IAE7D,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;QACrB,MAAM,IAAI,UAAU,CAAC,gCAAgC,CAAC,CAAC;IACxD,CAAC;AACF,CAAC;AAPD,kCAOC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Ensures that 0 \\<= 'value' \\< 'limit'. Throws a RangeError otherwise.\n */\nexport function ensureRange(value: number, limit: number): void {\n\t// Coerce 'value' to Uint32 so that we can range check with a single branch.\n\tconst _value = value >>> 0; // eslint-disable-line no-bitwise\n\n\tif (_value >= limit) {\n\t\tthrow new RangeError(\"Invalid (row, col) coordinate.\");\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EAAE,KAAK,aAAa,EAAqC,MAAM,aAAa,CAAC;AAGpF;;;;;GAKG;AACH,qBAAa,mBAAoB,YAAW,eAAe,CAAC,aAAa,CAAC;IACzE,OAAc,IAAI,SAAoD;IAEtE,gBAAuB,UAAU,EAAE,kBAAkB,CAInD;IAEF,IAAW,IAAI,WAEd;IAED,IAAW,UAAU,uBAEpB;IAED;;OAEG;IACU,IAAI,CAChB,OAAO,EAAE,sBAAsB,EAC/B,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,kBAAkB,GAC5B,OAAO,CAAC,aAAa,GAAG,QAAQ,CAAC;IAM7B,MAAM,CAAC,QAAQ,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,QAAQ;CAKrF;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,0LAA6D,CAAC;AAEvF;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,GAAG,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EAAE,KAAK,aAAa,EAAqC,MAAM,aAAa,CAAC;AAGpF;;;;;GAKG;AACH,qBAAa,mBAAoB,YAAW,eAAe,CAAC,aAAa,CAAC;IACzE,OAAc,IAAI,SAAoD;IAEtE,gBAAuB,UAAU,EAAE,kBAAkB,CAInD;IAEF,IAAW,IAAI,IAAI,MAAM,CAExB;IAED,IAAW,UAAU,IAAI,kBAAkB,CAE1C;IAED;;OAEG;IACU,IAAI,CAChB,OAAO,EAAE,sBAAsB,EAC/B,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,kBAAkB,GAC5B,OAAO,CAAC,aAAa,GAAG,QAAQ,CAAC;IAM7B,MAAM,CAAC,QAAQ,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,QAAQ;CAKrF;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,0LAA6D,CAAC;AAEvF;;;;;;;GAOG;AAIH,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,GAAG,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AASH,0EAAqF;AAErF,2CAAoF;AACpF,2DAAiD;AAEjD;;;;;GAKG;AACH,MAAa,mBAAmB;IAS/B,IAAW,IAAI;QACd,OAAO,mBAAmB,CAAC,IAAI,CAAC;IACjC,CAAC;IAED,IAAW,UAAU;QACpB,OAAO,mBAAmB,CAAC,UAAU,CAAC;IACvC,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAChB,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAE9B,MAAM,MAAM,GAAG,IAAI,wBAAiB,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QAC9D,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC;IACf,CAAC;IAEM,MAAM,CAAC,QAAgC,EAAE,EAAU;QACzD,MAAM,MAAM,GAAG,IAAI,wBAAiB,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACpE,MAAM,CAAC,eAAe,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC;;AAnCF,kDAoCC;AAnCc,wBAAI,GAAG,gDAAgD,CAAC;AAE/C,8BAAU,GAAuB;IACvD,IAAI,EAAE,mBAAmB,CAAC,IAAI;IAC9B,qBAAqB,EAAE,KAAK;IAC5B,cAAc,EAAE,8BAAU;CAC1B,CAAC;AA+BH;;;;GAIG;AACU,QAAA,YAAY,GAAG,IAAA,iCAAsB,EAAgB,mBAAmB,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIChannel,\n\tIChannelAttributes,\n\tIChannelFactory,\n\tIFluidDataStoreRuntime,\n\tIChannelServices,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { createSharedObjectKind } from \"@fluidframework/shared-object-base/internal\";\n\nimport { type ISharedMatrix, SharedMatrix as SharedMatrixClass } from \"./matrix.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * {@link @fluidframework/datastore-definitions#IChannelFactory} for {@link ISharedMatrix}.\n * @legacy\n * @alpha\n * @deprecated - Use `SharedMatrix.getFactory` instead.\n */\nexport class SharedMatrixFactory implements IChannelFactory<ISharedMatrix> {\n\tpublic static Type = \"https://graph.microsoft.com/types/sharedmatrix\";\n\n\tpublic static readonly Attributes: IChannelAttributes = {\n\t\ttype: SharedMatrixFactory.Type,\n\t\tsnapshotFormatVersion: \"0.1\",\n\t\tpackageVersion: pkgVersion,\n\t};\n\n\tpublic get type() {\n\t\treturn SharedMatrixFactory.Type;\n\t}\n\n\tpublic get attributes() {\n\t\treturn SharedMatrixFactory.Attributes;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n\t */\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\tservices: IChannelServices,\n\t\tattributes: IChannelAttributes,\n\t): Promise<ISharedMatrix & IChannel> {\n\t\tconst matrix = new SharedMatrixClass(runtime, id, attributes);\n\t\tawait matrix.load(services);\n\t\treturn matrix;\n\t}\n\n\tpublic create(document: IFluidDataStoreRuntime, id: string): ISharedMatrix & IChannel {\n\t\tconst matrix = new SharedMatrixClass(document, id, this.attributes);\n\t\tmatrix.initializeLocal();\n\t\treturn matrix;\n\t}\n}\n\n/**\n * Entrypoint for {@link ISharedMatrix} creation.\n * @legacy\n * @alpha\n */\nexport const SharedMatrix = createSharedObjectKind<ISharedMatrix>(SharedMatrixFactory);\n\n/**\n * Convenience alias for {@link ISharedMatrix}. Prefer to use {@link ISharedMatrix} when referring to\n * SharedMatrix as a type.\n * @legacy\n * @alpha\n * @privateRemarks\n * This alias is for legacy compat from when the SharedMatrix class was exported as public.\n */\nexport type SharedMatrix<T = any> = ISharedMatrix<T>;\n"]}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AASH,0EAAqF;AAErF,2CAAoF;AACpF,2DAAiD;AAEjD;;;;;GAKG;AACH,MAAa,mBAAmB;IAS/B,IAAW,IAAI;QACd,OAAO,mBAAmB,CAAC,IAAI,CAAC;IACjC,CAAC;IAED,IAAW,UAAU;QACpB,OAAO,mBAAmB,CAAC,UAAU,CAAC;IACvC,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAChB,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAE9B,MAAM,MAAM,GAAG,IAAI,wBAAiB,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;QAC9D,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC;IACf,CAAC;IAEM,MAAM,CAAC,QAAgC,EAAE,EAAU;QACzD,MAAM,MAAM,GAAG,IAAI,wBAAiB,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACpE,MAAM,CAAC,eAAe,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IACf,CAAC;;AAnCF,kDAoCC;AAnCc,wBAAI,GAAG,gDAAgD,CAAC;AAE/C,8BAAU,GAAuB;IACvD,IAAI,EAAE,mBAAmB,CAAC,IAAI;IAC9B,qBAAqB,EAAE,KAAK;IAC5B,cAAc,EAAE,8BAAU;CAC1B,CAAC;AA+BH;;;;GAIG;AACU,QAAA,YAAY,GAAG,IAAA,iCAAsB,EAAgB,mBAAmB,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIChannel,\n\tIChannelAttributes,\n\tIChannelFactory,\n\tIFluidDataStoreRuntime,\n\tIChannelServices,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { createSharedObjectKind } from \"@fluidframework/shared-object-base/internal\";\n\nimport { type ISharedMatrix, SharedMatrix as SharedMatrixClass } from \"./matrix.js\";\nimport { pkgVersion } from \"./packageVersion.js\";\n\n/**\n * {@link @fluidframework/datastore-definitions#IChannelFactory} for {@link ISharedMatrix}.\n * @legacy\n * @alpha\n * @deprecated - Use `SharedMatrix.getFactory` instead.\n */\nexport class SharedMatrixFactory implements IChannelFactory<ISharedMatrix> {\n\tpublic static Type = \"https://graph.microsoft.com/types/sharedmatrix\";\n\n\tpublic static readonly Attributes: IChannelAttributes = {\n\t\ttype: SharedMatrixFactory.Type,\n\t\tsnapshotFormatVersion: \"0.1\",\n\t\tpackageVersion: pkgVersion,\n\t};\n\n\tpublic get type(): string {\n\t\treturn SharedMatrixFactory.Type;\n\t}\n\n\tpublic get attributes(): IChannelAttributes {\n\t\treturn SharedMatrixFactory.Attributes;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n\t */\n\tpublic async load(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\tservices: IChannelServices,\n\t\tattributes: IChannelAttributes,\n\t): Promise<ISharedMatrix & IChannel> {\n\t\tconst matrix = new SharedMatrixClass(runtime, id, attributes);\n\t\tawait matrix.load(services);\n\t\treturn matrix;\n\t}\n\n\tpublic create(document: IFluidDataStoreRuntime, id: string): ISharedMatrix & IChannel {\n\t\tconst matrix = new SharedMatrixClass(document, id, this.attributes);\n\t\tmatrix.initializeLocal();\n\t\treturn matrix;\n\t}\n}\n\n/**\n * Entrypoint for {@link ISharedMatrix} creation.\n * @legacy\n * @alpha\n */\nexport const SharedMatrix = createSharedObjectKind<ISharedMatrix>(SharedMatrixFactory);\n\n/**\n * Convenience alias for {@link ISharedMatrix}. Prefer to use {@link ISharedMatrix} when referring to\n * SharedMatrix as a type.\n * @legacy\n * @alpha\n * @privateRemarks\n * This alias is for legacy compat from when the SharedMatrix class was exported as public.\n */\n// Changing this to `unknown` would be a breaking change.\n// TODO: if possible, transition SharedMatrix to not use `any`.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type SharedMatrix<T = any> = ISharedMatrix<T>;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../src/serialization.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EACN,sBAAsB,EACtB,YAAY,EACZ,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAE/E,eAAO,MAAM,aAAa,cACjB,YAAY,QACd,MAAM,YACF,aAAa,CAAC,CAAC,cACb,gBAAgB,kBACuC,CAAC;AAErE,wBAAsB,eAAe,CACpC,OAAO,EAAE,sBAAsB,EAC/B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,gBAAgB,gBAM5B"}
1
+ {"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../src/serialization.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EACN,sBAAsB,EACtB,YAAY,EACZ,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAE/E,eAAO,MAAM,aAAa,cACjB,YAAY,QACd,MAAM,YACF,aAAa,CAAC,CAAC,cACb,gBAAgB,KAC1B,aAAgF,CAAC;AAEpF,wBAAsB,eAAe,CACpC,OAAO,EAAE,sBAAsB,EAC/B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,gBAAgB,GAG1B,OAAO,CAAC,GAAG,CAAC,CAKd"}
@@ -1 +1 @@
1
- {"version":3,"file":"serialization.js","sourceRoot":"","sources":["../src/serialization.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAA8D;AAM9D,oEAAsE;AAG/D,MAAM,aAAa,GAAG,CAC5B,MAAoB,EACpB,IAAY,EACZ,QAAyB,EACzB,UAA4B,EAC3B,EAAE,CAAC,IAAI,wBAAa,CAAC,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AALxD,QAAA,aAAa,iBAK2C;AAE9D,KAAK,UAAU,eAAe,CACpC,OAA+B,EAC/B,IAAY,EACZ,UAA4B;IAE5B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,IAAA,6BAAc,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1C,+DAA+D;IAC/D,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AATD,0CASC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { bufferToString } from \"@fluid-internal/client-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport {\n\tIChannelStorageService,\n\tSerializable,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { BlobTreeEntry } from \"@fluidframework/driver-utils/internal\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\n\nexport const serializeBlob = <T>(\n\thandle: IFluidHandle,\n\tpath: string,\n\tsnapshot: Serializable<T>,\n\tserializer: IFluidSerializer,\n) => new BlobTreeEntry(path, serializer.stringify(snapshot, handle));\n\nexport async function deserializeBlob(\n\tstorage: IChannelStorageService,\n\tpath: string,\n\tserializer: IFluidSerializer,\n) {\n\tconst blob = await storage.readBlob(path);\n\tconst utf8 = bufferToString(blob, \"utf8\");\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\treturn serializer.parse(utf8);\n}\n"]}
1
+ {"version":3,"file":"serialization.js","sourceRoot":"","sources":["../src/serialization.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAA8D;AAM9D,oEAAsE;AAG/D,MAAM,aAAa,GAAG,CAC5B,MAAoB,EACpB,IAAY,EACZ,QAAyB,EACzB,UAA4B,EACZ,EAAE,CAAC,IAAI,wBAAa,CAAC,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AALvE,QAAA,aAAa,iBAK0D;AAE7E,KAAK,UAAU,eAAe,CACpC,OAA+B,EAC/B,IAAY,EACZ,UAA4B;IAI5B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,IAAA,6BAAc,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1C,+DAA+D;IAC/D,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAXD,0CAWC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { bufferToString } from \"@fluid-internal/client-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport {\n\tIChannelStorageService,\n\tSerializable,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { BlobTreeEntry } from \"@fluidframework/driver-utils/internal\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\n\nexport const serializeBlob = <T>(\n\thandle: IFluidHandle,\n\tpath: string,\n\tsnapshot: Serializable<T>,\n\tserializer: IFluidSerializer,\n): BlobTreeEntry => new BlobTreeEntry(path, serializer.stringify(snapshot, handle));\n\nexport async function deserializeBlob(\n\tstorage: IChannelStorageService,\n\tpath: string,\n\tserializer: IFluidSerializer,\n\t// Allowing parsed content to remain in its original (any) form.\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n): Promise<any> {\n\tconst blob = await storage.readBlob(path);\n\tconst utf8 = bufferToString(blob, \"utf8\");\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\treturn serializer.parse(utf8);\n}\n"]}
@@ -2,9 +2,9 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { IMatrixReader, IMatrixWriter } from "@tiny-calc/nano";
5
+ import { IMatrixReader, IMatrixWriter, type IMatrixProducer } from "@tiny-calc/nano";
6
6
  type RecurArrayHelper<T> = RecurArray<T> | T;
7
- type RecurArray<T> = RecurArrayHelper<T>[];
7
+ export type RecurArray<T> = RecurArrayHelper<T>[];
8
8
  type UA<T> = (T | undefined)[];
9
9
  /**
10
10
  * A sparse 4 billion x 4 billion array stored as 16x16 tiles.
@@ -15,7 +15,7 @@ export declare class SparseArray2D<T> implements IMatrixReader<T | undefined>, I
15
15
  readonly rowCount = 4294967295;
16
16
  readonly colCount = 4294967295;
17
17
  getCell(row: number, col: number): T | undefined;
18
- get matrixProducer(): any;
18
+ get matrixProducer(): IMatrixProducer<T>;
19
19
  setCell(row: number, col: number, value: T | undefined): void;
20
20
  /**
21
21
  * Invokes the given 'callback' for each key in a 16 x 16 tile at the indicated row.
@@ -47,9 +47,13 @@ export declare class SparseArray2D<T> implements IMatrixReader<T | undefined>, I
47
47
  * level being traversed.)
48
48
  */
49
49
  private forEachInCol;
50
- /** Clears the all cells contained within the specified span of rows. */
50
+ /**
51
+ * Clears the all cells contained within the specified span of rows.
52
+ */
51
53
  clearRows(rowStart: number, rowCount: number): void;
52
- /** Clears the all cells contained within the specifed span of cols. */
54
+ /**
55
+ * Clears the all cells contained within the specifed span of cols.
56
+ */
53
57
  clearCols(colStart: number, colCount: number): void;
54
58
  private getLevel;
55
59
  snapshot(): UA<UA<UA<UA<UA<T>>>>>;
@@ -1 +1 @@
1
- {"version":3,"file":"sparsearray2d.d.ts","sourceRoot":"","sources":["../src/sparsearray2d.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAmC/D,KAAK,gBAAgB,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAC7C,KAAK,UAAU,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;AAS3C,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;AAE/B;;GAEG;AACH,qBAAa,aAAa,CAAC,CAAC,CAC3B,YAAW,aAAa,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,aAAa,CAAC,CAAC,GAAG,SAAS,CAAC;IAEzD,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,GAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAe;IAEtE,SAAgB,QAAQ,cAAc;IACtC,SAAgB,QAAQ,cAAc;IAE/B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAoBvD,IAAW,cAAc,QAGxB;IAEM,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS;IAW7D;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAOvB;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAOvB;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IAapB;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IAapB,wEAAwE;IACjE,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IA0BnD,uEAAuE;IAChE,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IA0BnD,OAAO,CAAC,QAAQ;IAMT,QAAQ;WAID,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;CAGzC"}
1
+ {"version":3,"file":"sparsearray2d.d.ts","sourceRoot":"","sources":["../src/sparsearray2d.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAuCrF,KAAK,gBAAgB,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAC7C,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;AAWlD,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;AAE/B;;GAEG;AACH,qBAAa,aAAa,CAAC,CAAC,CAC3B,YAAW,aAAa,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,aAAa,CAAC,CAAC,GAAG,SAAS,CAAC;IAEzD,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,GAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAe;IAEtE,SAAgB,QAAQ,cAAc;IACtC,SAAgB,QAAQ,cAAc;IAE/B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAoBvD,IAAW,cAAc,IAAI,eAAe,CAAC,CAAC,CAAC,CAI9C;IAEM,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,GAAG,IAAI;IAWpE;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAOvB;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAOvB;;;;;;OAMG;IAIH,OAAO,CAAC,YAAY;IAapB;;;;;;OAMG;IAIH,OAAO,CAAC,YAAY;IAapB;;OAEG;IACI,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IA0B1D;;OAEG;IACI,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IA0B1D,OAAO,CAAC,QAAQ;IAQT,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;WAI1B,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;CAG5D"}
@@ -10,7 +10,9 @@ exports.SparseArray2D = void 0;
10
10
  //
11
11
  // (Lookup table ~17% faster than inlining the bit-twiddling on Node v12 x64)
12
12
  // (Array<T> ~2% faster than typed array on Node v12 x64)
13
- const x8ToInterlacedX16 = new Array(256).fill(0).map((value, i) => {
13
+ const x8ToInterlacedX16 = Array.from({ length: 256 })
14
+ .fill(0)
15
+ .map((value, i) => {
14
16
  let j = i;
15
17
  j = (j | (j << 4)) & 0x0f0f; // .... 7654 .... 3210
16
18
  j = (j | (j << 2)) & 0x3333; // ..76 ..54 ..32 ..10
@@ -25,13 +27,18 @@ const byte2 = (x32) => (x32 << 16) >>> 24;
25
27
  const byte3 = (x32) => (x32 << 24) >>> 24;
26
28
  // Given a uint16 returns the corresponding uint32 integer where 0s are
27
29
  // interleaved between the original bits. (e.g., 1111... -> 01010101...).
28
- const interlaceBitsX16 = (x16) => (x8ToInterlacedX16[byte2(x16)] << 16) | x8ToInterlacedX16[byte3(x16)];
30
+ const interlaceBitsX16 = (x16) =>
31
+ // TODO Non null asserting, why is this not null?
32
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
33
+ (x8ToInterlacedX16[byte2(x16)] << 16) | x8ToInterlacedX16[byte3(x16)];
29
34
  const r0ToMorton16 = (row) => (interlaceBitsX16(row) << 1) >>> 0;
30
35
  const c0ToMorton16 = (col) => interlaceBitsX16(col) >>> 0;
31
36
  // Given a 2D uint16 coordinate returns the corresponding unt32 Morton coded
32
37
  // coordinate. (See https://en.wikipedia.org/wiki/Z-order_curve)
33
38
  const r0c0ToMorton2x16 = (row, col) => (r0ToMorton16(row) | c0ToMorton16(col)) >>> 0;
34
- /** Undo JSON serialization's coercion of 'undefined' to null. */
39
+ /**
40
+ * Undo JSON serialization's coercion of 'undefined' to null.
41
+ */
35
42
  // eslint-disable-next-line @rushstack/no-new-null -- Private use of 'null' to preserve 'undefined'
36
43
  const nullToUndefined = (array) => array.map((value) => {
37
44
  return value === null ? undefined : Array.isArray(value) ? nullToUndefined(value) : value;
@@ -64,7 +71,8 @@ class SparseArray2D {
64
71
  return undefined;
65
72
  }
66
73
  get matrixProducer() {
67
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
74
+ // Cast is needed to satisfy the interface declaration while also not returning
75
+ // an IMatrixProducer for this class.
68
76
  return undefined;
69
77
  }
70
78
  setCell(row, col, value) {
@@ -107,6 +115,9 @@ class SparseArray2D {
107
115
  * (Note that 'rowBits' is the appropriate byte from 'r0ToMorton16' for the current
108
116
  * level being traversed.)
109
117
  */
118
+ // The suppression is needed because forEachInRow is called in a loop, and expected to
119
+ // use various abstractions on UA<T> at each level of the loop.
120
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
110
121
  forEachInRow(currentLevel, rowBits, callback) {
111
122
  this.forEachKeyInRow(rowBits, (key) => {
112
123
  const nextLevel = currentLevel[key];
@@ -122,6 +133,9 @@ class SparseArray2D {
122
133
  * (Note that 'colBits' is the appropriate byte from 'c0ToMorton16' for the current
123
134
  * level being traversed.)
124
135
  */
136
+ // The suppression is needed because forEachInRow is called in a loop, and expected to
137
+ // use various abstractions on UA<T> at each level of the loop.
138
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
125
139
  forEachInCol(currentLevel, colBits, callback) {
126
140
  this.forEachKeyInCol(colBits, (key) => {
127
141
  const nextLevel = currentLevel[key];
@@ -130,7 +144,9 @@ class SparseArray2D {
130
144
  }
131
145
  });
132
146
  }
133
- /** Clears the all cells contained within the specified span of rows. */
147
+ /**
148
+ * Clears the all cells contained within the specified span of rows.
149
+ */
134
150
  clearRows(rowStart, rowCount) {
135
151
  const rowEnd = rowStart + rowCount;
136
152
  for (let row = rowStart; row < rowEnd; row++) {
@@ -155,7 +171,9 @@ class SparseArray2D {
155
171
  }
156
172
  }
157
173
  }
158
- /** Clears the all cells contained within the specifed span of cols. */
174
+ /**
175
+ * Clears the all cells contained within the specifed span of cols.
176
+ */
159
177
  clearCols(colStart, colCount) {
160
178
  const colEnd = colStart + colCount;
161
179
  for (let col = colStart; col < colEnd; col++) {
@@ -182,7 +200,9 @@ class SparseArray2D {
182
200
  }
183
201
  getLevel(parent, subKey) {
184
202
  const level = parent[subKey];
185
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
203
+ // Using new Array is needed because the array created with Array.from does not
204
+ // satisfy (T|undefined)[].
205
+ // eslint-disable-next-line unicorn/no-new-array
186
206
  return level ?? (parent[subKey] = new Array(256).fill(undefined));
187
207
  }
188
208
  snapshot() {
@@ -1 +1 @@
1
- {"version":3,"file":"sparsearray2d.js","sourceRoot":"","sources":["../src/sparsearray2d.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\n/* eslint-disable no-bitwise */\n\nimport { IMatrixReader, IMatrixWriter } from \"@tiny-calc/nano\";\n\n// Build a lookup table that maps a uint8 to the corresponding uint16 where 0s\n// are interleaved between the original bits. (e.g., 1111... -> 01010101...).\n//\n// (Lookup table ~17% faster than inlining the bit-twiddling on Node v12 x64)\n// (Array<T> ~2% faster than typed array on Node v12 x64)\nconst x8ToInterlacedX16 = new Array(256).fill(0).map((value, i) => {\n\tlet j = i;\n\tj = (j | (j << 4)) & 0x0f0f; // .... 7654 .... 3210\n\tj = (j | (j << 2)) & 0x3333; // ..76 ..54 ..32 ..10\n\tj = (j | (j << 1)) & 0x5555; // .7.6 .5.4 .3.2 .1.0\n\treturn j;\n});\n\n// Selects individual bytes from a given 32b integer. The left shift are used to\n// clear upper bits (faster than using masks on Node 10 x64).\nconst byte0 = (x32: number) => x32 >>> 24;\nconst byte1 = (x32: number) => (x32 << 8) >>> 24;\nconst byte2 = (x32: number) => (x32 << 16) >>> 24;\nconst byte3 = (x32: number) => (x32 << 24) >>> 24;\n\n// Given a uint16 returns the corresponding uint32 integer where 0s are\n// interleaved between the original bits. (e.g., 1111... -> 01010101...).\nconst interlaceBitsX16 = (x16: number) =>\n\t(x8ToInterlacedX16[byte2(x16)] << 16) | x8ToInterlacedX16[byte3(x16)];\n\nconst r0ToMorton16 = (row: number) => (interlaceBitsX16(row) << 1) >>> 0;\nconst c0ToMorton16 = (col: number) => interlaceBitsX16(col) >>> 0;\n\n// Given a 2D uint16 coordinate returns the corresponding unt32 Morton coded\n// coordinate. (See https://en.wikipedia.org/wiki/Z-order_curve)\nconst r0c0ToMorton2x16 = (row: number, col: number) =>\n\t(r0ToMorton16(row) | c0ToMorton16(col)) >>> 0;\n\ntype RecurArrayHelper<T> = RecurArray<T> | T;\ntype RecurArray<T> = RecurArrayHelper<T>[];\n\n/** Undo JSON serialization's coercion of 'undefined' to null. */\n// eslint-disable-next-line @rushstack/no-new-null -- Private use of 'null' to preserve 'undefined'\nconst nullToUndefined = <T>(array: RecurArray<T | null>): RecurArray<T | undefined> =>\n\tarray.map((value) => {\n\t\treturn value === null ? undefined : Array.isArray(value) ? nullToUndefined(value) : value;\n\t});\n\ntype UA<T> = (T | undefined)[];\n\n/**\n * A sparse 4 billion x 4 billion array stored as 16x16 tiles.\n */\nexport class SparseArray2D<T>\n\timplements IMatrixReader<T | undefined>, IMatrixWriter<T | undefined>\n{\n\tconstructor(private readonly root: UA<UA<UA<UA<UA<T>>>>> = [undefined]) {}\n\n\tpublic readonly rowCount = 0xffffffff;\n\tpublic readonly colCount = 0xffffffff;\n\n\tpublic getCell(row: number, col: number): T | undefined {\n\t\tconst keyHi = r0c0ToMorton2x16(row >>> 16, col >>> 16);\n\t\tconst level0 = this.root[keyHi];\n\t\tif (level0 !== undefined) {\n\t\t\tconst keyLo = r0c0ToMorton2x16(row, col);\n\t\t\tconst level1 = level0[byte0(keyLo)];\n\t\t\tif (level1 !== undefined) {\n\t\t\t\tconst level2 = level1[byte1(keyLo)];\n\t\t\t\tif (level2 !== undefined) {\n\t\t\t\t\tconst level3 = level2[byte2(keyLo)];\n\t\t\t\t\tif (level3 !== undefined) {\n\t\t\t\t\t\treturn level3[byte3(keyLo)];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tpublic get matrixProducer() {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\treturn undefined as any;\n\t}\n\n\tpublic setCell(row: number, col: number, value: T | undefined) {\n\t\tconst keyHi = r0c0ToMorton2x16(row >>> 16, col >>> 16);\n\t\tconst keyLo = r0c0ToMorton2x16(row, col);\n\n\t\tconst level0 = this.getLevel(this.root, keyHi);\n\t\tconst level1 = this.getLevel(level0, byte0(keyLo));\n\t\tconst level2 = this.getLevel(level1, byte1(keyLo));\n\t\tconst level3 = this.getLevel(level2, byte2(keyLo));\n\t\tlevel3[byte3(keyLo)] = value;\n\t}\n\n\t/**\n\t * Invokes the given 'callback' for each key in a 16 x 16 tile at the indicated row.\n\t *\n\t * (Note that 'rowBits' is the appropriate byte from 'r0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\tprivate forEachKeyInRow(rowBits: number, callback: (key: number) => void) {\n\t\tfor (let col = 0; col < 16; col++) {\n\t\t\t// Perf: Potentially faster to replace 'c0ToMorton16()' with a short look up table?\n\t\t\tcallback((rowBits | c0ToMorton16(col)) >>> 0);\n\t\t}\n\t}\n\n\t/**\n\t * Invokes the given 'callback' for each key in a 16 x 16 tile at the indicated col.\n\t *\n\t * (Note that 'colBits' is the appropriate byte from 'c0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\tprivate forEachKeyInCol(col: number, callback: (key: number) => void) {\n\t\tfor (let row = 0; row < 16; row++) {\n\t\t\t// Perf: Potentially faster to replace 'r0ToMorton16()' with a short look up table?\n\t\t\tcallback((r0ToMorton16(row) | col) >>> 0);\n\t\t}\n\t}\n\n\t/**\n\t * Invokes the give 'callback' with the next 'level' array for each populated region\n\t * of the given row in the 'currentLevel'.\n\t *\n\t * (Note that 'rowBits' is the appropriate byte from 'r0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\tprivate forEachInRow<V extends UA<any>, U extends UA<V>>(\n\t\tcurrentLevel: U,\n\t\trowBits: number,\n\t\tcallback: (level: V) => void,\n\t) {\n\t\tthis.forEachKeyInRow(rowBits, (key) => {\n\t\t\tconst nextLevel = currentLevel[key];\n\t\t\tif (nextLevel !== undefined) {\n\t\t\t\tcallback(nextLevel);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Invokes the give 'callback' with the next 'level' array for each populated region\n\t * of the given col in the 'currentLevel'.\n\t *\n\t * (Note that 'colBits' is the appropriate byte from 'c0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\tprivate forEachInCol<V extends UA<any>, U extends UA<V>>(\n\t\tcurrentLevel: U,\n\t\tcolBits: number,\n\t\tcallback: (level: V) => void,\n\t) {\n\t\tthis.forEachKeyInCol(colBits, (key) => {\n\t\t\tconst nextLevel = currentLevel[key];\n\t\t\tif (nextLevel !== undefined) {\n\t\t\t\tcallback(nextLevel);\n\t\t\t}\n\t\t});\n\t}\n\n\t/** Clears the all cells contained within the specified span of rows. */\n\tpublic clearRows(rowStart: number, rowCount: number) {\n\t\tconst rowEnd = rowStart + rowCount;\n\t\tfor (let row = rowStart; row < rowEnd; row++) {\n\t\t\tconst rowHi = r0ToMorton16(row >>> 16);\n\n\t\t\t// The top level of tree is a 64k x 64k tile. We need to scan all 64k entries.\n\t\t\tfor (let colHi = 0; colHi < 0x10000; colHi++) {\n\t\t\t\tconst keyHi = (rowHi | c0ToMorton16(colHi)) >>> 0;\n\t\t\t\tconst level0 = this.root[keyHi];\n\t\t\t\tif (level0 !== undefined) {\n\t\t\t\t\t// The remainder of the tree is divided in 16 x 16 tiles.\n\t\t\t\t\tconst rowLo = r0ToMorton16(row);\n\t\t\t\t\tthis.forEachInRow(level0, byte0(rowLo), (level1) => {\n\t\t\t\t\t\tthis.forEachInRow(level1, byte1(rowLo), (level2) => {\n\t\t\t\t\t\t\tthis.forEachInRow(level2, byte2(rowLo), (level3) => {\n\t\t\t\t\t\t\t\tthis.forEachKeyInRow(byte3(rowLo), (key) => {\n\t\t\t\t\t\t\t\t\tlevel3[key] = undefined;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Clears the all cells contained within the specifed span of cols. */\n\tpublic clearCols(colStart: number, colCount: number) {\n\t\tconst colEnd = colStart + colCount;\n\t\tfor (let col = colStart; col < colEnd; col++) {\n\t\t\tconst colHi = c0ToMorton16(col >>> 16);\n\n\t\t\t// The top level of tree is a 64k x 64k tile. We need to scan all 64k entries.\n\t\t\tfor (let rowHi = 0; rowHi < 0x10000; rowHi++) {\n\t\t\t\tconst keyHi = (colHi | r0ToMorton16(rowHi)) >>> 0;\n\t\t\t\tconst level0 = this.root[keyHi];\n\t\t\t\tif (level0 !== undefined) {\n\t\t\t\t\t// The remainder of the tree is divided in 16 x 16 tiles.\n\t\t\t\t\tconst colLo = c0ToMorton16(col);\n\t\t\t\t\tthis.forEachInCol(level0, byte0(colLo), (level1) => {\n\t\t\t\t\t\tthis.forEachInCol(level1, byte1(colLo), (level2) => {\n\t\t\t\t\t\t\tthis.forEachInCol(level2, byte2(colLo), (level3) => {\n\t\t\t\t\t\t\t\tthis.forEachKeyInCol(byte3(colLo), (key) => {\n\t\t\t\t\t\t\t\t\tlevel3[key] = undefined;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getLevel<T>(parent: UA<UA<T>>, subKey: number) {\n\t\tconst level = parent[subKey];\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\treturn level ?? (parent[subKey] = new Array(256).fill(undefined));\n\t}\n\n\tpublic snapshot() {\n\t\treturn this.root;\n\t}\n\n\tpublic static load<T>(data: RecurArray<T>) {\n\t\treturn new SparseArray2D<T>(nullToUndefined<T>(data) as SparseArray2D<T>[\"root\"]);\n\t}\n}\n"]}
1
+ {"version":3,"file":"sparsearray2d.js","sourceRoot":"","sources":["../src/sparsearray2d.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\n/* eslint-disable no-bitwise */\n\nimport { IMatrixReader, IMatrixWriter, type IMatrixProducer } from \"@tiny-calc/nano\";\n\n// Build a lookup table that maps a uint8 to the corresponding uint16 where 0s\n// are interleaved between the original bits. (e.g., 1111... -> 01010101...).\n//\n// (Lookup table ~17% faster than inlining the bit-twiddling on Node v12 x64)\n// (Array<T> ~2% faster than typed array on Node v12 x64)\nconst x8ToInterlacedX16 = Array.from({ length: 256 })\n\t.fill(0)\n\t.map((value, i) => {\n\t\tlet j = i;\n\t\tj = (j | (j << 4)) & 0x0f0f; // .... 7654 .... 3210\n\t\tj = (j | (j << 2)) & 0x3333; // ..76 ..54 ..32 ..10\n\t\tj = (j | (j << 1)) & 0x5555; // .7.6 .5.4 .3.2 .1.0\n\t\treturn j;\n\t});\n\n// Selects individual bytes from a given 32b integer. The left shift are used to\n// clear upper bits (faster than using masks on Node 10 x64).\nconst byte0 = (x32: number): number => x32 >>> 24;\nconst byte1 = (x32: number): number => (x32 << 8) >>> 24;\nconst byte2 = (x32: number): number => (x32 << 16) >>> 24;\nconst byte3 = (x32: number): number => (x32 << 24) >>> 24;\n\n// Given a uint16 returns the corresponding uint32 integer where 0s are\n// interleaved between the original bits. (e.g., 1111... -> 01010101...).\nconst interlaceBitsX16 = (x16: number): number =>\n\t// TODO Non null asserting, why is this not null?\n\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t(x8ToInterlacedX16[byte2(x16)]! << 16) | x8ToInterlacedX16[byte3(x16)]!;\n\nconst r0ToMorton16 = (row: number): number => (interlaceBitsX16(row) << 1) >>> 0;\nconst c0ToMorton16 = (col: number): number => interlaceBitsX16(col) >>> 0;\n\n// Given a 2D uint16 coordinate returns the corresponding unt32 Morton coded\n// coordinate. (See https://en.wikipedia.org/wiki/Z-order_curve)\nconst r0c0ToMorton2x16 = (row: number, col: number): number =>\n\t(r0ToMorton16(row) | c0ToMorton16(col)) >>> 0;\n\ntype RecurArrayHelper<T> = RecurArray<T> | T;\nexport type RecurArray<T> = RecurArrayHelper<T>[];\n\n/**\n * Undo JSON serialization's coercion of 'undefined' to null.\n */\n// eslint-disable-next-line @rushstack/no-new-null -- Private use of 'null' to preserve 'undefined'\nconst nullToUndefined = <T>(array: RecurArray<T | null>): RecurArray<T | undefined> =>\n\tarray.map((value) => {\n\t\treturn value === null ? undefined : Array.isArray(value) ? nullToUndefined(value) : value;\n\t});\n\ntype UA<T> = (T | undefined)[];\n\n/**\n * A sparse 4 billion x 4 billion array stored as 16x16 tiles.\n */\nexport class SparseArray2D<T>\n\timplements IMatrixReader<T | undefined>, IMatrixWriter<T | undefined>\n{\n\tconstructor(private readonly root: UA<UA<UA<UA<UA<T>>>>> = [undefined]) {}\n\n\tpublic readonly rowCount = 0xffffffff;\n\tpublic readonly colCount = 0xffffffff;\n\n\tpublic getCell(row: number, col: number): T | undefined {\n\t\tconst keyHi = r0c0ToMorton2x16(row >>> 16, col >>> 16);\n\t\tconst level0 = this.root[keyHi];\n\t\tif (level0 !== undefined) {\n\t\t\tconst keyLo = r0c0ToMorton2x16(row, col);\n\t\t\tconst level1 = level0[byte0(keyLo)];\n\t\t\tif (level1 !== undefined) {\n\t\t\t\tconst level2 = level1[byte1(keyLo)];\n\t\t\t\tif (level2 !== undefined) {\n\t\t\t\t\tconst level3 = level2[byte2(keyLo)];\n\t\t\t\t\tif (level3 !== undefined) {\n\t\t\t\t\t\treturn level3[byte3(keyLo)];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tpublic get matrixProducer(): IMatrixProducer<T> {\n\t\t// Cast is needed to satisfy the interface declaration while also not returning\n\t\t// an IMatrixProducer for this class.\n\t\treturn undefined as unknown as IMatrixProducer<T>;\n\t}\n\n\tpublic setCell(row: number, col: number, value: T | undefined): void {\n\t\tconst keyHi = r0c0ToMorton2x16(row >>> 16, col >>> 16);\n\t\tconst keyLo = r0c0ToMorton2x16(row, col);\n\n\t\tconst level0 = this.getLevel(this.root, keyHi);\n\t\tconst level1 = this.getLevel(level0, byte0(keyLo));\n\t\tconst level2 = this.getLevel(level1, byte1(keyLo));\n\t\tconst level3 = this.getLevel(level2, byte2(keyLo));\n\t\tlevel3[byte3(keyLo)] = value;\n\t}\n\n\t/**\n\t * Invokes the given 'callback' for each key in a 16 x 16 tile at the indicated row.\n\t *\n\t * (Note that 'rowBits' is the appropriate byte from 'r0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\tprivate forEachKeyInRow(rowBits: number, callback: (key: number) => void): void {\n\t\tfor (let col = 0; col < 16; col++) {\n\t\t\t// Perf: Potentially faster to replace 'c0ToMorton16()' with a short look up table?\n\t\t\tcallback((rowBits | c0ToMorton16(col)) >>> 0);\n\t\t}\n\t}\n\n\t/**\n\t * Invokes the given 'callback' for each key in a 16 x 16 tile at the indicated col.\n\t *\n\t * (Note that 'colBits' is the appropriate byte from 'c0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\tprivate forEachKeyInCol(col: number, callback: (key: number) => void): void {\n\t\tfor (let row = 0; row < 16; row++) {\n\t\t\t// Perf: Potentially faster to replace 'r0ToMorton16()' with a short look up table?\n\t\t\tcallback((r0ToMorton16(row) | col) >>> 0);\n\t\t}\n\t}\n\n\t/**\n\t * Invokes the give 'callback' with the next 'level' array for each populated region\n\t * of the given row in the 'currentLevel'.\n\t *\n\t * (Note that 'rowBits' is the appropriate byte from 'r0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\t// The suppression is needed because forEachInRow is called in a loop, and expected to\n\t// use various abstractions on UA<T> at each level of the loop.\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tprivate forEachInRow<V extends UA<any>, U extends UA<V>>(\n\t\tcurrentLevel: U,\n\t\trowBits: number,\n\t\tcallback: (level: V) => void,\n\t): void {\n\t\tthis.forEachKeyInRow(rowBits, (key) => {\n\t\t\tconst nextLevel = currentLevel[key];\n\t\t\tif (nextLevel !== undefined) {\n\t\t\t\tcallback(nextLevel);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Invokes the give 'callback' with the next 'level' array for each populated region\n\t * of the given col in the 'currentLevel'.\n\t *\n\t * (Note that 'colBits' is the appropriate byte from 'c0ToMorton16' for the current\n\t * level being traversed.)\n\t */\n\t// The suppression is needed because forEachInRow is called in a loop, and expected to\n\t// use various abstractions on UA<T> at each level of the loop.\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tprivate forEachInCol<V extends UA<any>, U extends UA<V>>(\n\t\tcurrentLevel: U,\n\t\tcolBits: number,\n\t\tcallback: (level: V) => void,\n\t): void {\n\t\tthis.forEachKeyInCol(colBits, (key) => {\n\t\t\tconst nextLevel = currentLevel[key];\n\t\t\tif (nextLevel !== undefined) {\n\t\t\t\tcallback(nextLevel);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Clears the all cells contained within the specified span of rows.\n\t */\n\tpublic clearRows(rowStart: number, rowCount: number): void {\n\t\tconst rowEnd = rowStart + rowCount;\n\t\tfor (let row = rowStart; row < rowEnd; row++) {\n\t\t\tconst rowHi = r0ToMorton16(row >>> 16);\n\n\t\t\t// The top level of tree is a 64k x 64k tile. We need to scan all 64k entries.\n\t\t\tfor (let colHi = 0; colHi < 0x10000; colHi++) {\n\t\t\t\tconst keyHi = (rowHi | c0ToMorton16(colHi)) >>> 0;\n\t\t\t\tconst level0 = this.root[keyHi];\n\t\t\t\tif (level0 !== undefined) {\n\t\t\t\t\t// The remainder of the tree is divided in 16 x 16 tiles.\n\t\t\t\t\tconst rowLo = r0ToMorton16(row);\n\t\t\t\t\tthis.forEachInRow(level0, byte0(rowLo), (level1) => {\n\t\t\t\t\t\tthis.forEachInRow(level1, byte1(rowLo), (level2) => {\n\t\t\t\t\t\t\tthis.forEachInRow(level2, byte2(rowLo), (level3) => {\n\t\t\t\t\t\t\t\tthis.forEachKeyInRow(byte3(rowLo), (key) => {\n\t\t\t\t\t\t\t\t\tlevel3[key] = undefined;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Clears the all cells contained within the specifed span of cols.\n\t */\n\tpublic clearCols(colStart: number, colCount: number): void {\n\t\tconst colEnd = colStart + colCount;\n\t\tfor (let col = colStart; col < colEnd; col++) {\n\t\t\tconst colHi = c0ToMorton16(col >>> 16);\n\n\t\t\t// The top level of tree is a 64k x 64k tile. We need to scan all 64k entries.\n\t\t\tfor (let rowHi = 0; rowHi < 0x10000; rowHi++) {\n\t\t\t\tconst keyHi = (colHi | r0ToMorton16(rowHi)) >>> 0;\n\t\t\t\tconst level0 = this.root[keyHi];\n\t\t\t\tif (level0 !== undefined) {\n\t\t\t\t\t// The remainder of the tree is divided in 16 x 16 tiles.\n\t\t\t\t\tconst colLo = c0ToMorton16(col);\n\t\t\t\t\tthis.forEachInCol(level0, byte0(colLo), (level1) => {\n\t\t\t\t\t\tthis.forEachInCol(level1, byte1(colLo), (level2) => {\n\t\t\t\t\t\t\tthis.forEachInCol(level2, byte2(colLo), (level3) => {\n\t\t\t\t\t\t\t\tthis.forEachKeyInCol(byte3(colLo), (key) => {\n\t\t\t\t\t\t\t\t\tlevel3[key] = undefined;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getLevel<T>(parent: UA<UA<T>>, subKey: number): UA<T> {\n\t\tconst level = parent[subKey];\n\t\t// Using new Array is needed because the array created with Array.from does not\n\t\t// satisfy (T|undefined)[].\n\t\t// eslint-disable-next-line unicorn/no-new-array\n\t\treturn level ?? (parent[subKey] = new Array<T | undefined>(256).fill(undefined));\n\t}\n\n\tpublic snapshot(): UA<UA<UA<UA<UA<T>>>>> {\n\t\treturn this.root;\n\t}\n\n\tpublic static load<T>(data: RecurArray<T>): SparseArray2D<T> {\n\t\treturn new SparseArray2D<T>(nullToUndefined<T>(data) as SparseArray2D<T>[\"root\"]);\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"undoprovider.d.ts","sourceRoot":"","sources":["../src/undoprovider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,2BAA2B,EAI3B,yBAAyB,EAKzB,MAAM,qCAAqC,CAAC;AAE7C,OAAO,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAsB,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,qBAAa,kBAAkB;IAS7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IANxB,OAAO,CAAC,YAAY,CAAC,CAA6B;IAClD,OAAO,CAAC,SAAS,CAAC,CAAqB;IACvC,OAAO,CAAC,0BAA0B,CAAC,CAAgB;gBAGjC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,yBAAyB;IAG5C,MAAM,CAAC,SAAS,EAAE,2BAA2B;IAuDpD,OAAO,CAAC,cAAc;CAgDtB;AAED,qBAAa,kBAAkB,CAAC,CAAC;IAE/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAHJ,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,iBAAiB;IA0BzC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;CAoBrE"}
1
+ {"version":3,"file":"undoprovider.d.ts","sourceRoot":"","sources":["../src/undoprovider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,2BAA2B,EAI3B,yBAAyB,EAKzB,MAAM,qCAAqC,CAAC;AAE7C,OAAO,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAsB,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,qBAAa,kBAAkB;IAS7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IANxB,OAAO,CAAC,YAAY,CAAC,CAA6B;IAClD,OAAO,CAAC,SAAS,CAAC,CAAqB;IACvC,OAAO,CAAC,0BAA0B,CAAC,CAAgB;gBAGjC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,yBAAyB;IAG5C,MAAM,CAAC,SAAS,EAAE,2BAA2B,GAAG,IAAI;IAwD3D,OAAO,CAAC,cAAc;CAuDtB;AAED,qBAAa,kBAAkB,CAAC,CAAC;IAE/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAHJ,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,iBAAiB;IA0BzC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI;CAoB5E"}
@@ -37,17 +37,20 @@ class VectorUndoProvider {
37
37
  // the tracking group provides one.
38
38
  const trackingGroup = (removeTrackingGroup =
39
39
  this.currentRemoveTrackingGroup ?? new internal_2.TrackingGroup());
40
- deltaArgs.deltaSegments.forEach((d) => d.segment.trackingCollection.link(trackingGroup));
40
+ for (const d of deltaArgs.deltaSegments)
41
+ d.segment.trackingCollection.link(trackingGroup);
41
42
  }
42
43
  switch (deltaArgs.operation) {
43
44
  case internal_2.MergeTreeDeltaType.REMOVE:
44
- case internal_2.MergeTreeDeltaType.INSERT:
45
+ case internal_2.MergeTreeDeltaType.INSERT: {
45
46
  if (this.currentOp !== deltaArgs.operation) {
46
47
  this.pushRevertible(revertibles, removeTrackingGroup);
47
48
  }
48
49
  break;
49
- default:
50
+ }
51
+ default: {
50
52
  throw new Error("operation type not revertible");
53
+ }
51
54
  }
52
55
  // If we are in the process of reverting, set 'currentOp' to remind ourselves not to push
53
56
  // another revertible until `IRevertable.revert()` finishes the current op and clears this
@@ -66,6 +69,8 @@ class VectorUndoProvider {
66
69
  try {
67
70
  if (removedTrackingGroup !== undefined) {
68
71
  while (removedTrackingGroup.size > 0) {
72
+ // TODO Non null asserting, why is this not null?
73
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
69
74
  const tracked = removedTrackingGroup.tracked[0];
70
75
  removedTrackingGroup.unlink(tracked);
71
76
  // if there are groups tracked, this in a revert of a remove.
@@ -88,6 +93,8 @@ class VectorUndoProvider {
88
93
  discard: () => {
89
94
  if (removedTrackingGroup !== undefined) {
90
95
  while (removedTrackingGroup.size > 0) {
96
+ // TODO Non null asserting, why is this not null?
97
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
91
98
  removedTrackingGroup.unlink(removedTrackingGroup.tracked[0]);
92
99
  }
93
100
  }
@@ -1 +1 @@
1
- {"version":3,"file":"undoprovider.js","sourceRoot":"","sources":["../src/undoprovider.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIMergeTreeDeltaCallbackArgs,\n\tITrackingGroup,\n\tMergeTreeDeltaRevertible,\n\tMergeTreeDeltaType,\n\tMergeTreeRevertibleDriver,\n\tTrackingGroup,\n\tappendToMergeTreeDeltaRevertibles,\n\tdiscardMergeTreeDeltaRevertible,\n\trevertMergeTreeDeltaRevertibles,\n} from \"@fluidframework/merge-tree/internal\";\n\nimport { Handle, isHandleValid } from \"./handletable.js\";\nimport { SharedMatrix } from \"./matrix.js\";\nimport { MatrixItem } from \"./ops.js\";\nimport { PermutationSegment, PermutationVector } from \"./permutationvector.js\";\nimport { IUndoConsumer } from \"./types.js\";\n\nexport class VectorUndoProvider {\n\t// 'currentGroup' and 'currentOp' are used while applying an IRevertable.revert() to coalesce\n\t// the recorded into a single IRevertable / tracking group as they move between the undo <->\n\t// redo stacks.\n\tprivate currentGroup?: MergeTreeDeltaRevertible[];\n\tprivate currentOp?: MergeTreeDeltaType;\n\tprivate currentRemoveTrackingGroup?: TrackingGroup;\n\n\tconstructor(\n\t\tprivate readonly manager: IUndoConsumer,\n\t\tprivate readonly driver: MergeTreeRevertibleDriver,\n\t) {}\n\n\tpublic record(deltaArgs: IMergeTreeDeltaCallbackArgs) {\n\t\tif (deltaArgs.deltaSegments.length > 0) {\n\t\t\t// If we are in the process of reverting, the `IRevertible.revert()` will provide the tracking\n\t\t\t// group so that we can preserve the original segment ranges as a single op/group as we move\n\t\t\t// ops between the undo <-> redo stacks.\n\t\t\tconst revertibles: MergeTreeDeltaRevertible[] = this.currentGroup ?? [];\n\t\t\tappendToMergeTreeDeltaRevertibles(deltaArgs, revertibles);\n\n\t\t\t// For SharedMatrix, each IRevertibles always holds a single row/col operation.\n\t\t\t// Therefore, 'currentOp' must either be undefined or equal to the current op.\n\t\t\tassert(\n\t\t\t\tthis.currentOp === undefined || this.currentOp === deltaArgs.operation,\n\t\t\t\t0x02a /* \"On vector undo, unexpected 'currentOp' type/state!\" */,\n\t\t\t);\n\t\t\tlet removeTrackingGroup: TrackingGroup | undefined;\n\t\t\tif (deltaArgs.operation === MergeTreeDeltaType.REMOVE) {\n\t\t\t\t// for removed segment we need a tracking group.\n\t\t\t\t// this is for a few reason:\n\t\t\t\t// 1. the handle for the row/column on the removed segment is still allocated,\n\t\t\t\t//\t\tand needs to be in order to process unacked ops sent before the remove.\n\t\t\t\t// 2. handles are freed on unlink(zamboni), but that also clears the row/column data.\n\t\t\t\t//\t\twhich we don't want to happen, so we can re-insert the cells when the row/col comes back.\n\t\t\t\t//\t\tthe tracking group prevents unlink.\n\t\t\t\t// 3. when we re-insert we need to find the old segment and clear their handles\n\t\t\t\t//\t\tso the new segment takes them over. there is no efficient look-up for this.\n\t\t\t\t//\t\tthe tracking group provides one.\n\t\t\t\tconst trackingGroup = (removeTrackingGroup =\n\t\t\t\t\tthis.currentRemoveTrackingGroup ?? new TrackingGroup());\n\t\t\t\tdeltaArgs.deltaSegments.forEach((d) =>\n\t\t\t\t\td.segment.trackingCollection.link(trackingGroup),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tswitch (deltaArgs.operation) {\n\t\t\t\tcase MergeTreeDeltaType.REMOVE:\n\t\t\t\tcase MergeTreeDeltaType.INSERT:\n\t\t\t\t\tif (this.currentOp !== deltaArgs.operation) {\n\t\t\t\t\t\tthis.pushRevertible(revertibles, removeTrackingGroup);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new Error(\"operation type not revertible\");\n\t\t\t}\n\n\t\t\t// If we are in the process of reverting, set 'currentOp' to remind ourselves not to push\n\t\t\t// another revertible until `IRevertable.revert()` finishes the current op and clears this\n\t\t\t// field.\n\t\t\tif (this.currentGroup !== undefined) {\n\t\t\t\tthis.currentOp ??= deltaArgs.operation;\n\t\t\t\tthis.currentRemoveTrackingGroup ??= removeTrackingGroup;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate pushRevertible(\n\t\trevertibles: MergeTreeDeltaRevertible[],\n\t\tremovedTrackingGroup: ITrackingGroup | undefined,\n\t) {\n\t\tconst reverter = {\n\t\t\trevert: () => {\n\t\t\t\tassert(\n\t\t\t\t\tthis.currentGroup === undefined && this.currentOp === undefined,\n\t\t\t\t\t0x02b /* \"Must not nest calls to IRevertible.revert()\" */,\n\t\t\t\t);\n\n\t\t\t\tthis.currentGroup = [];\n\n\t\t\t\ttry {\n\t\t\t\t\tif (removedTrackingGroup !== undefined) {\n\t\t\t\t\t\twhile (removedTrackingGroup.size > 0) {\n\t\t\t\t\t\t\tconst tracked = removedTrackingGroup.tracked[0];\n\t\t\t\t\t\t\tremovedTrackingGroup.unlink(tracked);\n\t\t\t\t\t\t\t// if there are groups tracked, this in a revert of a remove.\n\t\t\t\t\t\t\t// this means we are about to re-insert the row/column\n\t\t\t\t\t\t\t// with the same handle. We reuse the handle so the row/columns cells\n\t\t\t\t\t\t\t// get re-inserted too.\n\t\t\t\t\t\t\t// since a new segment will have the handle, we need to\n\t\t\t\t\t\t\t// remove it from the removed segment which was tracked\n\t\t\t\t\t\t\t(tracked as PermutationSegment).reset();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\trevertMergeTreeDeltaRevertibles(this.driver, revertibles);\n\t\t\t\t} finally {\n\t\t\t\t\tthis.currentOp = undefined;\n\t\t\t\t\tthis.currentGroup = undefined;\n\t\t\t\t\tthis.currentRemoveTrackingGroup = undefined;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdiscard: () => {\n\t\t\t\tif (removedTrackingGroup !== undefined) {\n\t\t\t\t\twhile (removedTrackingGroup.size > 0) {\n\t\t\t\t\t\tremovedTrackingGroup.unlink(removedTrackingGroup.tracked[0]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdiscardMergeTreeDeltaRevertible(revertibles);\n\t\t\t},\n\t\t};\n\n\t\tthis.manager.pushToCurrentOperation(reverter);\n\n\t\treturn reverter;\n\t}\n}\n\nexport class MatrixUndoProvider<T> {\n\tconstructor(\n\t\tprivate readonly consumer: IUndoConsumer,\n\t\tprivate readonly matrix: SharedMatrix<T>,\n\t\tprivate readonly rows: PermutationVector,\n\t\tprivate readonly cols: PermutationVector,\n\t) {\n\t\trows.undo = new VectorUndoProvider(consumer, {\n\t\t\tannotateRange() {\n\t\t\t\tthrow new Error(\"not implemented\");\n\t\t\t},\n\t\t\tinsertFromSpec(pos, spec) {\n\t\t\t\tmatrix._undoRemoveRows(pos, spec);\n\t\t\t},\n\t\t\tremoveRange(start, end) {\n\t\t\t\tmatrix.removeRows(start, end - start);\n\t\t\t},\n\t\t});\n\t\tcols.undo = new VectorUndoProvider(consumer, {\n\t\t\tannotateRange() {\n\t\t\t\tthrow new Error(\"not implemented\");\n\t\t\t},\n\t\t\tinsertFromSpec(pos, spec) {\n\t\t\t\tmatrix._undoRemoveCols(pos, spec);\n\t\t\t},\n\t\t\tremoveRange(start, end) {\n\t\t\t\tmatrix.removeCols(start, end - start);\n\t\t\t},\n\t\t});\n\t}\n\n\tcellSet(rowHandle: Handle, colHandle: Handle, oldValue: MatrixItem<T>) {\n\t\tassert(\n\t\t\tisHandleValid(rowHandle) && isHandleValid(colHandle),\n\t\t\t0x02c /* \"On cellSet(), invalid row and/or column handles!\" */,\n\t\t);\n\n\t\tif (this.consumer !== undefined) {\n\t\t\tthis.consumer.pushToCurrentOperation({\n\t\t\t\trevert: () => {\n\t\t\t\t\tconst row = this.rows.handleToPosition(rowHandle);\n\t\t\t\t\tconst col = this.cols.handleToPosition(colHandle);\n\t\t\t\t\t// if the row/column no longer exists, we cannot set the cell\n\t\t\t\t\tif (row < this.matrix.rowCount && col < this.matrix.colCount) {\n\t\t\t\t\t\tthis.matrix.setCell(row, col, oldValue);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tdiscard: () => {},\n\t\t\t});\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"undoprovider.js","sourceRoot":"","sources":["../src/undoprovider.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIMergeTreeDeltaCallbackArgs,\n\tITrackingGroup,\n\tMergeTreeDeltaRevertible,\n\tMergeTreeDeltaType,\n\tMergeTreeRevertibleDriver,\n\tTrackingGroup,\n\tappendToMergeTreeDeltaRevertibles,\n\tdiscardMergeTreeDeltaRevertible,\n\trevertMergeTreeDeltaRevertibles,\n} from \"@fluidframework/merge-tree/internal\";\n\nimport { Handle, isHandleValid } from \"./handletable.js\";\nimport { SharedMatrix } from \"./matrix.js\";\nimport { MatrixItem } from \"./ops.js\";\nimport { PermutationSegment, PermutationVector } from \"./permutationvector.js\";\nimport { IUndoConsumer } from \"./types.js\";\n\nexport class VectorUndoProvider {\n\t// 'currentGroup' and 'currentOp' are used while applying an IRevertable.revert() to coalesce\n\t// the recorded into a single IRevertable / tracking group as they move between the undo <->\n\t// redo stacks.\n\tprivate currentGroup?: MergeTreeDeltaRevertible[];\n\tprivate currentOp?: MergeTreeDeltaType;\n\tprivate currentRemoveTrackingGroup?: TrackingGroup;\n\n\tconstructor(\n\t\tprivate readonly manager: IUndoConsumer,\n\t\tprivate readonly driver: MergeTreeRevertibleDriver,\n\t) {}\n\n\tpublic record(deltaArgs: IMergeTreeDeltaCallbackArgs): void {\n\t\tif (deltaArgs.deltaSegments.length > 0) {\n\t\t\t// If we are in the process of reverting, the `IRevertible.revert()` will provide the tracking\n\t\t\t// group so that we can preserve the original segment ranges as a single op/group as we move\n\t\t\t// ops between the undo <-> redo stacks.\n\t\t\tconst revertibles: MergeTreeDeltaRevertible[] = this.currentGroup ?? [];\n\t\t\tappendToMergeTreeDeltaRevertibles(deltaArgs, revertibles);\n\n\t\t\t// For SharedMatrix, each IRevertibles always holds a single row/col operation.\n\t\t\t// Therefore, 'currentOp' must either be undefined or equal to the current op.\n\t\t\tassert(\n\t\t\t\tthis.currentOp === undefined || this.currentOp === deltaArgs.operation,\n\t\t\t\t0x02a /* \"On vector undo, unexpected 'currentOp' type/state!\" */,\n\t\t\t);\n\t\t\tlet removeTrackingGroup: TrackingGroup | undefined;\n\t\t\tif (deltaArgs.operation === MergeTreeDeltaType.REMOVE) {\n\t\t\t\t// for removed segment we need a tracking group.\n\t\t\t\t// this is for a few reason:\n\t\t\t\t// 1. the handle for the row/column on the removed segment is still allocated,\n\t\t\t\t//\t\tand needs to be in order to process unacked ops sent before the remove.\n\t\t\t\t// 2. handles are freed on unlink(zamboni), but that also clears the row/column data.\n\t\t\t\t//\t\twhich we don't want to happen, so we can re-insert the cells when the row/col comes back.\n\t\t\t\t//\t\tthe tracking group prevents unlink.\n\t\t\t\t// 3. when we re-insert we need to find the old segment and clear their handles\n\t\t\t\t//\t\tso the new segment takes them over. there is no efficient look-up for this.\n\t\t\t\t//\t\tthe tracking group provides one.\n\t\t\t\tconst trackingGroup = (removeTrackingGroup =\n\t\t\t\t\tthis.currentRemoveTrackingGroup ?? new TrackingGroup());\n\t\t\t\tfor (const d of deltaArgs.deltaSegments)\n\t\t\t\t\td.segment.trackingCollection.link(trackingGroup);\n\t\t\t}\n\n\t\t\tswitch (deltaArgs.operation) {\n\t\t\t\tcase MergeTreeDeltaType.REMOVE:\n\t\t\t\tcase MergeTreeDeltaType.INSERT: {\n\t\t\t\t\tif (this.currentOp !== deltaArgs.operation) {\n\t\t\t\t\t\tthis.pushRevertible(revertibles, removeTrackingGroup);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdefault: {\n\t\t\t\t\tthrow new Error(\"operation type not revertible\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we are in the process of reverting, set 'currentOp' to remind ourselves not to push\n\t\t\t// another revertible until `IRevertable.revert()` finishes the current op and clears this\n\t\t\t// field.\n\t\t\tif (this.currentGroup !== undefined) {\n\t\t\t\tthis.currentOp ??= deltaArgs.operation;\n\t\t\t\tthis.currentRemoveTrackingGroup ??= removeTrackingGroup;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate pushRevertible(\n\t\trevertibles: MergeTreeDeltaRevertible[],\n\t\tremovedTrackingGroup: ITrackingGroup | undefined,\n\t): {\n\t\trevert: () => void;\n\t\tdiscard: () => void;\n\t} {\n\t\tconst reverter = {\n\t\t\trevert: (): void => {\n\t\t\t\tassert(\n\t\t\t\t\tthis.currentGroup === undefined && this.currentOp === undefined,\n\t\t\t\t\t0x02b /* \"Must not nest calls to IRevertible.revert()\" */,\n\t\t\t\t);\n\n\t\t\t\tthis.currentGroup = [];\n\n\t\t\t\ttry {\n\t\t\t\t\tif (removedTrackingGroup !== undefined) {\n\t\t\t\t\t\twhile (removedTrackingGroup.size > 0) {\n\t\t\t\t\t\t\t// TODO Non null asserting, why is this not null?\n\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\t\t\tconst tracked = removedTrackingGroup.tracked[0]!;\n\t\t\t\t\t\t\tremovedTrackingGroup.unlink(tracked);\n\t\t\t\t\t\t\t// if there are groups tracked, this in a revert of a remove.\n\t\t\t\t\t\t\t// this means we are about to re-insert the row/column\n\t\t\t\t\t\t\t// with the same handle. We reuse the handle so the row/columns cells\n\t\t\t\t\t\t\t// get re-inserted too.\n\t\t\t\t\t\t\t// since a new segment will have the handle, we need to\n\t\t\t\t\t\t\t// remove it from the removed segment which was tracked\n\t\t\t\t\t\t\t(tracked as PermutationSegment).reset();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\trevertMergeTreeDeltaRevertibles(this.driver, revertibles);\n\t\t\t\t} finally {\n\t\t\t\t\tthis.currentOp = undefined;\n\t\t\t\t\tthis.currentGroup = undefined;\n\t\t\t\t\tthis.currentRemoveTrackingGroup = undefined;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdiscard: (): void => {\n\t\t\t\tif (removedTrackingGroup !== undefined) {\n\t\t\t\t\twhile (removedTrackingGroup.size > 0) {\n\t\t\t\t\t\t// TODO Non null asserting, why is this not null?\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\t\tremovedTrackingGroup.unlink(removedTrackingGroup.tracked[0]!);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdiscardMergeTreeDeltaRevertible(revertibles);\n\t\t\t},\n\t\t};\n\n\t\tthis.manager.pushToCurrentOperation(reverter);\n\n\t\treturn reverter;\n\t}\n}\n\nexport class MatrixUndoProvider<T> {\n\tconstructor(\n\t\tprivate readonly consumer: IUndoConsumer,\n\t\tprivate readonly matrix: SharedMatrix<T>,\n\t\tprivate readonly rows: PermutationVector,\n\t\tprivate readonly cols: PermutationVector,\n\t) {\n\t\trows.undo = new VectorUndoProvider(consumer, {\n\t\t\tannotateRange(): void {\n\t\t\t\tthrow new Error(\"not implemented\");\n\t\t\t},\n\t\t\tinsertFromSpec(pos, spec): void {\n\t\t\t\tmatrix._undoRemoveRows(pos, spec);\n\t\t\t},\n\t\t\tremoveRange(start, end): void {\n\t\t\t\tmatrix.removeRows(start, end - start);\n\t\t\t},\n\t\t});\n\t\tcols.undo = new VectorUndoProvider(consumer, {\n\t\t\tannotateRange(): void {\n\t\t\t\tthrow new Error(\"not implemented\");\n\t\t\t},\n\t\t\tinsertFromSpec(pos, spec): void {\n\t\t\t\tmatrix._undoRemoveCols(pos, spec);\n\t\t\t},\n\t\t\tremoveRange(start, end): void {\n\t\t\t\tmatrix.removeCols(start, end - start);\n\t\t\t},\n\t\t});\n\t}\n\n\tcellSet(rowHandle: Handle, colHandle: Handle, oldValue: MatrixItem<T>): void {\n\t\tassert(\n\t\t\tisHandleValid(rowHandle) && isHandleValid(colHandle),\n\t\t\t0x02c /* \"On cellSet(), invalid row and/or column handles!\" */,\n\t\t);\n\n\t\tif (this.consumer !== undefined) {\n\t\t\tthis.consumer.pushToCurrentOperation({\n\t\t\t\trevert: () => {\n\t\t\t\t\tconst row = this.rows.handleToPosition(rowHandle);\n\t\t\t\t\tconst col = this.cols.handleToPosition(colHandle);\n\t\t\t\t\t// if the row/column no longer exists, we cannot set the cell\n\t\t\t\t\tif (row < this.matrix.rowCount && col < this.matrix.colCount) {\n\t\t\t\t\t\tthis.matrix.setCell(row, col, oldValue);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tdiscard: () => {},\n\t\t\t});\n\t\t}\n\t}\n}\n"]}
package/internal.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  /*
7
7
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
8
- * Generated by "flub generate entrypoints" in @fluidframework/build-tools.
8
+ * Generated by "flub generate entrypoints" in @fluid-tools/build-cli.
9
9
  */
10
10
 
11
11
  export * from "./lib/index.js";
package/legacy.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  /*
7
7
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
8
- * Generated by "flub generate entrypoints" in @fluidframework/build-tools.
8
+ * Generated by "flub generate entrypoints" in @fluid-tools/build-cli.
9
9
  */
10
10
 
11
11
  export * from "./lib/legacy.js";
@@ -26,13 +26,17 @@ export declare class HandleCache implements IVectorConsumer<Handle> {
26
26
  * the result with 'isValidHandle(..)' to see if a handle has been allocated for
27
27
  * the given position.
28
28
  *
29
- * Throws a 'RangeError' if the provided 'position' is out-of-bounds wrt. the
29
+ * @throws A 'RangeError' if the provided 'position' is out-of-bounds with regards to the
30
30
  * PermutationVector's length.
31
31
  */
32
32
  getHandle(position: number): Handle;
33
- /** Update the cache when a handle has been allocated for a given position. */
33
+ /**
34
+ * Update the cache when a handle has been allocated for a given position.
35
+ */
34
36
  addHandle(position: number, handle: Handle): void;
35
- /** Used by 'CacheMiss()' to retrieve handles for a range of positions. */
37
+ /**
38
+ * Used by {@link HandleCache.cacheMiss} to retrieve handles for a range of positions.
39
+ */
36
40
  private getHandles;
37
41
  private cacheMiss;
38
42
  itemsChanged(start: number, removedCount: number, insertedCount: number): void;
@@ -1 +1 @@
1
- {"version":3,"file":"handlecache.d.ts","sourceRoot":"","sources":["../src/handlecache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAsB,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG/E;;;;;GAKG;AACH,qBAAa,WAAY,YAAW,eAAe,CAAC,MAAM,CAAC;aAI9B,MAAM,EAAE,iBAAiB;IAHrD,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,KAAK,CAAK;gBAEU,MAAM,EAAE,iBAAiB;IAErD;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAIhB;;;;;;;OAOG;IACI,SAAS,CAAC,QAAQ,EAAE,MAAM;IAajC,8EAA8E;IACvE,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAajD,0EAA0E;IAC1E,OAAO,CAAC,UAAU;IAiBlB,OAAO,CAAC,SAAS;IA4BjB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI;CAoB9E"}
1
+ {"version":3,"file":"handlecache.d.ts","sourceRoot":"","sources":["../src/handlecache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAsB,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG/E;;;;;GAKG;AACH,qBAAa,WAAY,YAAW,eAAe,CAAC,MAAM,CAAC;aAI9B,MAAM,EAAE,iBAAiB;IAHrD,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,KAAK,CAAK;gBAEU,MAAM,EAAE,iBAAiB;IAErD;;;OAGG;IACH,OAAO,CAAC,QAAQ;IAIhB;;;;;;;OAOG;IACI,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAiB1C;;OAEG;IACI,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAexD;;OAEG;IACH,OAAO,CAAC,UAAU;IAiBlB,OAAO,CAAC,SAAS;IAiCjB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI;CAoB9E"}
@@ -30,7 +30,7 @@ export class HandleCache {
30
30
  * the result with 'isValidHandle(..)' to see if a handle has been allocated for
31
31
  * the given position.
32
32
  *
33
- * Throws a 'RangeError' if the provided 'position' is out-of-bounds wrt. the
33
+ * @throws A 'RangeError' if the provided 'position' is out-of-bounds with regards to the
34
34
  * PermutationVector's length.
35
35
  */
36
36
  getHandle(position) {
@@ -40,18 +40,29 @@ export class HandleCache {
40
40
  // Perf: A cache hit implies that 'position' was in bounds. Therefore, we can defer
41
41
  // checking that 'position' is in bounds until 'cacheMiss(..)'. This yields an
42
42
  // ~40% speedup when the position is in the cache (node v12 x64).
43
- return index < this.handles.length ? this.handles[index] : this.cacheMiss(position);
43
+ const handle = this.handles[index];
44
+ if (handle !== undefined) {
45
+ return handle;
46
+ }
47
+ return this.cacheMiss(position);
44
48
  }
45
- /** Update the cache when a handle has been allocated for a given position. */
49
+ /**
50
+ * Update the cache when a handle has been allocated for a given position.
51
+ */
46
52
  addHandle(position, handle) {
47
53
  assert(isHandleValid(handle), 0x017 /* "Trying to add invalid handle!" */);
48
54
  const index = this.getIndex(position);
49
55
  if (index < this.handles.length) {
50
- assert(!isHandleValid(this.handles[index]), 0x018 /* "Trying to insert handle into position with already valid handle!" */);
56
+ assert(
57
+ // Non null asserting, above we checked that the index is less than the length.
58
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
59
+ !isHandleValid(this.handles[index]), 0x018 /* "Trying to insert handle into position with already valid handle!" */);
51
60
  this.handles[index] = handle;
52
61
  }
53
62
  }
54
- /** Used by 'CacheMiss()' to retrieve handles for a range of positions. */
63
+ /**
64
+ * Used by {@link HandleCache.cacheMiss} to retrieve handles for a range of positions.
65
+ */
55
66
  getHandles(start, end) {
56
67
  // TODO: This can be accelerated substantially using 'walkSegments()'. The only catch
57
68
  // is that
@@ -75,13 +86,20 @@ export class HandleCache {
75
86
  // the cache to the next MergeTree segment boundary (within the limits of
76
87
  // the handle cache).
77
88
  if (_position < this.start) {
78
- this.handles = this.getHandles(_position, this.start).concat(this.handles);
89
+ this.handles = [...this.getHandles(_position, this.start), ...this.handles];
79
90
  this.start = _position;
91
+ // TODO why are we non null asserting here?
92
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
80
93
  return this.handles[0];
81
94
  }
82
95
  else {
83
96
  ensureRange(_position, this.vector.getLength());
84
- this.handles = this.handles.concat(this.getHandles(this.start + this.handles.length, _position + 1));
97
+ this.handles = [
98
+ ...this.handles,
99
+ ...this.getHandles(this.start + this.handles.length, _position + 1),
100
+ ];
101
+ // TODO why are we non null asserting here?
102
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
85
103
  return this.handles[this.handles.length - 1];
86
104
  }
87
105
  }
@@ -1 +1 @@
1
- {"version":3,"file":"handlecache.js","sourceRoot":"","sources":["../src/handlecache.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\n/* eslint-disable no-bitwise */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { IVectorConsumer } from \"@tiny-calc/nano\";\n\nimport { Handle, isHandleValid } from \"./handletable.js\";\nimport { PermutationSegment, PermutationVector } from \"./permutationvector.js\";\nimport { ensureRange } from \"./range.js\";\n\n/**\n * Used by PermutationVector to cache position -\\> handle lookups.\n *\n * Perf: Possibly, this should eventually be inlined into PermutationVector itself, but\n * so far there's no measurable perf penalty for being a separate object (node 12 x64)\n */\nexport class HandleCache implements IVectorConsumer<Handle> {\n\tprivate handles: Handle[] = [];\n\tprivate start = 0;\n\n\tconstructor(public readonly vector: PermutationVector) {}\n\n\t/**\n\t * Returns the index of the given position in the 'handles' array as a Uint32.\n\t * (If the position is not in the array, returns an integer greater than 'handles.length').\n\t */\n\tprivate getIndex(position: number) {\n\t\treturn (position - this.start) >>> 0;\n\t}\n\n\t/**\n\t * Returns the handle currently assigned to the given 'position' (if any). Check\n\t * the result with 'isValidHandle(..)' to see if a handle has been allocated for\n\t * the given position.\n\t *\n\t * Throws a 'RangeError' if the provided 'position' is out-of-bounds wrt. the\n\t * PermutationVector's length.\n\t */\n\tpublic getHandle(position: number) {\n\t\tconst index = this.getIndex(position);\n\n\t\t// Perf: To encourage inlining, handling of the 'cacheMiss(..)' case has been extracted\n\t\t// to a separate method.\n\n\t\t// Perf: A cache hit implies that 'position' was in bounds. Therefore, we can defer\n\t\t// checking that 'position' is in bounds until 'cacheMiss(..)'. This yields an\n\t\t// ~40% speedup when the position is in the cache (node v12 x64).\n\n\t\treturn index < this.handles.length ? this.handles[index] : this.cacheMiss(position);\n\t}\n\n\t/** Update the cache when a handle has been allocated for a given position. */\n\tpublic addHandle(position: number, handle: Handle) {\n\t\tassert(isHandleValid(handle), 0x017 /* \"Trying to add invalid handle!\" */);\n\n\t\tconst index = this.getIndex(position);\n\t\tif (index < this.handles.length) {\n\t\t\tassert(\n\t\t\t\t!isHandleValid(this.handles[index]),\n\t\t\t\t0x018 /* \"Trying to insert handle into position with already valid handle!\" */,\n\t\t\t);\n\t\t\tthis.handles[index] = handle;\n\t\t}\n\t}\n\n\t/** Used by 'CacheMiss()' to retrieve handles for a range of positions. */\n\tprivate getHandles(start: number, end: number) {\n\t\t// TODO: This can be accelerated substantially using 'walkSegments()'. The only catch\n\t\t// is that\n\n\t\tconst handles: Handle[] = [];\n\t\tconst { vector } = this;\n\n\t\tfor (let pos = start; pos < end; pos++) {\n\t\t\tconst { segment, offset } = vector.getContainingSegment(pos);\n\t\t\tconst asPerm = segment as PermutationSegment;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\thandles.push(asPerm.start + offset!);\n\t\t}\n\n\t\treturn handles;\n\t}\n\n\tprivate cacheMiss(position: number) {\n\t\t// Coercing 'position' to an Uint32 allows us to handle a negative 'position' value\n\t\t// with the same logic that handles 'position' >= length.\n\t\tconst _position = position >>> 0;\n\n\t\t// TODO: To bound memory usage, there should be a limit on the maximum size of\n\t\t// handle[].\n\n\t\t// TODO: To reduce MergeTree lookups, this code should opportunistically grow\n\t\t// the cache to the next MergeTree segment boundary (within the limits of\n\t\t// the handle cache).\n\n\t\tif (_position < this.start) {\n\t\t\tthis.handles = this.getHandles(_position, this.start).concat(this.handles);\n\t\t\tthis.start = _position;\n\t\t\treturn this.handles[0];\n\t\t} else {\n\t\t\tensureRange(_position, this.vector.getLength());\n\n\t\t\tthis.handles = this.handles.concat(\n\t\t\t\tthis.getHandles(this.start + this.handles.length, _position + 1),\n\t\t\t);\n\t\t\treturn this.handles[this.handles.length - 1];\n\t\t}\n\t}\n\n\t// #region IVectorConsumer\n\n\titemsChanged(start: number, removedCount: number, insertedCount: number): void {\n\t\t// If positions were inserted/removed, our current policy is to trim the array\n\t\t// at the beginning of the invalidate range and lazily repopulate the handles\n\t\t// on demand.\n\t\t//\n\t\t// Some alternatives to consider that preserve the previously cached handles\n\t\t// that are still valid:\n\t\t//\n\t\t// * Eagerly populate the 'handles[]' with the newly insert values (currently guaranteed\n\t\t// to be Handle.unallocated, so we don't even need to look them up.)\n\t\t//\n\t\t// * Use a sentinel value or other mechanism to allow \"holes\" in the cache.\n\n\t\tconst index = this.getIndex(start);\n\t\tif (index < this.handles.length) {\n\t\t\tthis.handles.length = index;\n\t\t}\n\t}\n\n\t// #endregion IVectorConsumer\n}\n"]}
1
+ {"version":3,"file":"handlecache.js","sourceRoot":"","sources":["../src/handlecache.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\n/* eslint-disable no-bitwise */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport { IVectorConsumer } from \"@tiny-calc/nano\";\n\nimport { Handle, isHandleValid } from \"./handletable.js\";\nimport { PermutationSegment, PermutationVector } from \"./permutationvector.js\";\nimport { ensureRange } from \"./range.js\";\n\n/**\n * Used by PermutationVector to cache position -\\> handle lookups.\n *\n * Perf: Possibly, this should eventually be inlined into PermutationVector itself, but\n * so far there's no measurable perf penalty for being a separate object (node 12 x64)\n */\nexport class HandleCache implements IVectorConsumer<Handle> {\n\tprivate handles: Handle[] = [];\n\tprivate start = 0;\n\n\tconstructor(public readonly vector: PermutationVector) {}\n\n\t/**\n\t * Returns the index of the given position in the 'handles' array as a Uint32.\n\t * (If the position is not in the array, returns an integer greater than 'handles.length').\n\t */\n\tprivate getIndex(position: number): number {\n\t\treturn (position - this.start) >>> 0;\n\t}\n\n\t/**\n\t * Returns the handle currently assigned to the given 'position' (if any). Check\n\t * the result with 'isValidHandle(..)' to see if a handle has been allocated for\n\t * the given position.\n\t *\n\t * @throws A 'RangeError' if the provided 'position' is out-of-bounds with regards to the\n\t * PermutationVector's length.\n\t */\n\tpublic getHandle(position: number): Handle {\n\t\tconst index = this.getIndex(position);\n\n\t\t// Perf: To encourage inlining, handling of the 'cacheMiss(..)' case has been extracted\n\t\t// to a separate method.\n\n\t\t// Perf: A cache hit implies that 'position' was in bounds. Therefore, we can defer\n\t\t// checking that 'position' is in bounds until 'cacheMiss(..)'. This yields an\n\t\t// ~40% speedup when the position is in the cache (node v12 x64).\n\n\t\tconst handle = this.handles[index];\n\t\tif (handle !== undefined) {\n\t\t\treturn handle;\n\t\t}\n\t\treturn this.cacheMiss(position);\n\t}\n\n\t/**\n\t * Update the cache when a handle has been allocated for a given position.\n\t */\n\tpublic addHandle(position: number, handle: Handle): void {\n\t\tassert(isHandleValid(handle), 0x017 /* \"Trying to add invalid handle!\" */);\n\n\t\tconst index = this.getIndex(position);\n\t\tif (index < this.handles.length) {\n\t\t\tassert(\n\t\t\t\t// Non null asserting, above we checked that the index is less than the length.\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t!isHandleValid(this.handles[index]!),\n\t\t\t\t0x018 /* \"Trying to insert handle into position with already valid handle!\" */,\n\t\t\t);\n\t\t\tthis.handles[index] = handle;\n\t\t}\n\t}\n\n\t/**\n\t * Used by {@link HandleCache.cacheMiss} to retrieve handles for a range of positions.\n\t */\n\tprivate getHandles(start: number, end: number): Handle[] {\n\t\t// TODO: This can be accelerated substantially using 'walkSegments()'. The only catch\n\t\t// is that\n\n\t\tconst handles: Handle[] = [];\n\t\tconst { vector } = this;\n\n\t\tfor (let pos = start; pos < end; pos++) {\n\t\t\tconst { segment, offset } = vector.getContainingSegment(pos);\n\t\t\tconst asPerm = segment as PermutationSegment;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\thandles.push(asPerm.start + offset!);\n\t\t}\n\n\t\treturn handles;\n\t}\n\n\tprivate cacheMiss(position: number): Handle {\n\t\t// Coercing 'position' to an Uint32 allows us to handle a negative 'position' value\n\t\t// with the same logic that handles 'position' >= length.\n\t\tconst _position = position >>> 0;\n\n\t\t// TODO: To bound memory usage, there should be a limit on the maximum size of\n\t\t// handle[].\n\n\t\t// TODO: To reduce MergeTree lookups, this code should opportunistically grow\n\t\t// the cache to the next MergeTree segment boundary (within the limits of\n\t\t// the handle cache).\n\n\t\tif (_position < this.start) {\n\t\t\tthis.handles = [...this.getHandles(_position, this.start), ...this.handles];\n\t\t\tthis.start = _position;\n\t\t\t// TODO why are we non null asserting here?\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\treturn this.handles[0]!;\n\t\t} else {\n\t\t\tensureRange(_position, this.vector.getLength());\n\n\t\t\tthis.handles = [\n\t\t\t\t...this.handles,\n\t\t\t\t...this.getHandles(this.start + this.handles.length, _position + 1),\n\t\t\t];\n\t\t\t// TODO why are we non null asserting here?\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\treturn this.handles[this.handles.length - 1]!;\n\t\t}\n\t}\n\n\t// #region IVectorConsumer\n\n\titemsChanged(start: number, removedCount: number, insertedCount: number): void {\n\t\t// If positions were inserted/removed, our current policy is to trim the array\n\t\t// at the beginning of the invalidate range and lazily repopulate the handles\n\t\t// on demand.\n\t\t//\n\t\t// Some alternatives to consider that preserve the previously cached handles\n\t\t// that are still valid:\n\t\t//\n\t\t// * Eagerly populate the 'handles[]' with the newly insert values (currently guaranteed\n\t\t// to be Handle.unallocated, so we don't even need to look them up.)\n\t\t//\n\t\t// * Use a sentinel value or other mechanism to allow \"holes\" in the cache.\n\n\t\tconst index = this.getIndex(start);\n\t\tif (index < this.handles.length) {\n\t\t\tthis.handles.length = index;\n\t\t}\n\t}\n\n\t// #endregion IVectorConsumer\n}\n"]}
@@ -7,7 +7,9 @@ export declare const enum Handle {
7
7
  * Sentinel representing the absence of a valid handle.
8
8
  */
9
9
  none = 0,
10
- /** Minimum valid handle. */
10
+ /**
11
+ * Minimum valid handle.
12
+ */
11
13
  valid = 1,
12
14
  /**
13
15
  * Sentinel representing an unallocated Handle. Used by PermutationVector
@@ -1 +1 @@
1
- {"version":3,"file":"handletable.d.ts","sourceRoot":"","sources":["../src/handletable.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,0BAAkB,MAAM;IACvB;;OAEG;IACH,IAAI,IAAI;IAER,4BAA4B;IAC5B,KAAK,IAAI;IAET;;;OAGG;IACH,WAAW,cAAc;CACzB;AAED,eAAO,MAAM,aAAa,WAAY,MAAM,YAA2B,CAAC;AAExE;;GAEG;AACH,qBAAa,WAAW,CAAC,CAAC;IAIN,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE,CAAC,MAAM,GAAG,CAAC,CAAC,EAAQ;IAE1D,KAAK;IAOZ;;OAEG;IACI,QAAQ,IAAI,MAAM;IAmBzB;;OAEG;IACI,YAAY,CAAC,KAAK,EAAE,MAAM;IAQjC;;OAEG;IACI,IAAI,CAAC,MAAM,EAAE,MAAM;IAK1B;;OAEG;IACI,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC;IAI7B;;OAEG;IACI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAMnC,OAAO,KAAK,IAAI,GAEf;IACD,OAAO,KAAK,IAAI,QAEf;IAEM,iBAAiB;WAIV,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE;CAG1C"}
1
+ {"version":3,"file":"handletable.d.ts","sourceRoot":"","sources":["../src/handletable.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,0BAAkB,MAAM;IACvB;;OAEG;IACH,IAAI,IAAI;IAER;;OAEG;IACH,KAAK,IAAI;IAET;;;OAGG;IACH,WAAW,cAAc;CACzB;AAED,eAAO,MAAM,aAAa,WAAY,MAAM,KAAG,OAAiC,CAAC;AAEjF;;GAEG;AACH,qBAAa,WAAW,CAAC,CAAC;IAIN,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE,CAAC,MAAM,GAAG,CAAC,CAAC,EAAQ;IAE1D,KAAK,IAAI,IAAI;IAOpB;;OAEG;IACI,QAAQ,IAAI,MAAM;IAmBzB;;OAEG;IACI,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW;IAQ/C;;OAEG;IACI,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKjC;;OAEG;IACI,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC;IAI7B;;OAEG;IACI,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAM1C,OAAO,KAAK,IAAI,GAEf;IACD,OAAO,KAAK,IAAI,QAEf;IAEM,iBAAiB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE;WAI5B,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC;CAG3D"}