@fluidframework/matrix 2.3.0-288113 → 2.3.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 +4 -0
- package/dist/handlecache.d.ts.map +1 -1
- package/dist/handlecache.js +2 -13
- package/dist/handlecache.js.map +1 -1
- package/dist/matrix.d.ts.map +1 -1
- package/dist/matrix.js +0 -4
- package/dist/matrix.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/permutationvector.d.ts.map +1 -1
- package/dist/permutationvector.js +0 -2
- package/dist/permutationvector.js.map +1 -1
- package/dist/sparsearray2d.d.ts.map +1 -1
- package/dist/sparsearray2d.js +1 -4
- package/dist/sparsearray2d.js.map +1 -1
- package/dist/undoprovider.d.ts.map +1 -1
- package/dist/undoprovider.js +0 -4
- package/dist/undoprovider.js.map +1 -1
- package/lib/handlecache.d.ts.map +1 -1
- package/lib/handlecache.js +2 -13
- package/lib/handlecache.js.map +1 -1
- package/lib/matrix.d.ts.map +1 -1
- package/lib/matrix.js +0 -4
- package/lib/matrix.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/permutationvector.d.ts.map +1 -1
- package/lib/permutationvector.js +0 -2
- package/lib/permutationvector.js.map +1 -1
- package/lib/sparsearray2d.d.ts.map +1 -1
- package/lib/sparsearray2d.js +1 -4
- package/lib/sparsearray2d.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/lib/undoprovider.d.ts.map +1 -1
- package/lib/undoprovider.js +0 -4
- package/lib/undoprovider.js.map +1 -1
- package/package.json +23 -22
- package/src/handlecache.ts +4 -14
- package/src/matrix.ts +2 -6
- package/src/packageVersion.ts +1 -1
- package/src/permutationvector.ts +1 -3
- package/src/sparsearray2d.ts +1 -3
- package/src/undoprovider.ts +2 -6
- package/tsconfig.json +1 -0
package/lib/sparsearray2d.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sparsearray2d.js","sourceRoot":"","sources":["../src/sparsearray2d.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,8EAA8E;AAC9E,6EAA6E;AAC7E,EAAE;AACF,6EAA6E;AAC7E,yDAAyD;AACzD,MAAM,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;KACnD,IAAI,CAAC,CAAC,CAAC;KACP,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;IACjB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,sBAAsB;IACnD,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,sBAAsB;IACnD,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,sBAAsB;IACnD,OAAO,CAAC,CAAC;AACV,CAAC,CAAC,CAAC;AAEJ,iFAAiF;AACjF,6DAA6D;AAC7D,MAAM,KAAK,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC;AAClD,MAAM,KAAK,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;AACzD,MAAM,KAAK,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;AAC1D,MAAM,KAAK,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;AAE1D,uEAAuE;AACvE,yEAAyE;AACzE,MAAM,gBAAgB,GAAG,CAAC,GAAW,EAAU,EAAE;AAChD,iDAAiD;AACjD,oEAAoE;AACpE,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAE,CAAC;AAEzE,MAAM,YAAY,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;AACjF,MAAM,YAAY,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAE1E,4EAA4E;AAC5E,iEAAiE;AACjE,MAAM,gBAAgB,GAAG,CAAC,GAAW,EAAE,GAAW,EAAU,EAAE,CAC7D,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AAK/C;;GAEG;AACH,mGAAmG;AACnG,MAAM,eAAe,GAAG,CAAI,KAA2B,EAA6B,EAAE,CACrF,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;IACnB,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3F,CAAC,CAAC,CAAC;AAIJ;;GAEG;AACH,MAAM,OAAO,aAAa;IAGzB,YAA6B,OAA8B,CAAC,SAAS,CAAC;QAAzC,SAAI,GAAJ,IAAI,CAAqC;QAEtD,aAAQ,GAAG,UAAU,CAAC;QACtB,aAAQ,GAAG,UAAU,CAAC;IAHmC,CAAC;IAKnE,OAAO,CAAC,GAAW,EAAE,GAAW;QACtC,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACzC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YACpC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;gBACpC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;oBACpC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;wBAC1B,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;oBAC7B,CAAC;gBACF,CAAC;YACF,CAAC;QACF,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,IAAW,cAAc;QACxB,+EAA+E;QAC/E,qCAAqC;QACrC,OAAO,SAA0C,CAAC;IACnD,CAAC;IAEM,OAAO,CAAC,GAAW,EAAE,GAAW,EAAE,KAAoB;QAC5D,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAEzC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC;IAC9B,CAAC;IAED;;;;;OAKG;IACK,eAAe,CAAC,OAAe,EAAE,QAA+B;QACvE,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;YACnC,mFAAmF;YACnF,QAAQ,CAAC,CAAC,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/C,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACK,eAAe,CAAC,GAAW,EAAE,QAA+B;QACnE,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC;YACnC,mFAAmF;YACnF,QAAQ,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACH,sFAAsF;IACtF,+DAA+D;IAC/D,8DAA8D;IACtD,YAAY,CACnB,YAAe,EACf,OAAe,EACf,QAA4B;QAE5B,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACrC,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC7B,QAAQ,CAAC,SAAS,CAAC,CAAC;YACrB,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,sFAAsF;IACtF,+DAA+D;IAC/D,8DAA8D;IACtD,YAAY,CACnB,YAAe,EACf,OAAe,EACf,QAA4B;QAE5B,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACrC,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC7B,QAAQ,CAAC,SAAS,CAAC,CAAC;YACrB,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,SAAS,CAAC,QAAgB,EAAE,QAAgB;QAClD,MAAM,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;QACnC,KAAK,IAAI,GAAG,GAAG,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;YAEvC,+EAA+E;YAC/E,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC9C,MAAM,KAAK,GAAG,CAAC,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;gBAClD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBAC1B,yDAAyD;oBACzD,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;oBAChC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE;wBAClD,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE;4BAClD,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE;gCAClD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE;oCAC1C,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;gCACzB,CAAC,CAAC,CAAC;4BACJ,CAAC,CAAC,CAAC;wBACJ,CAAC,CAAC,CAAC;oBACJ,CAAC,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED;;OAEG;IACI,SAAS,CAAC,QAAgB,EAAE,QAAgB;QAClD,MAAM,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;QACnC,KAAK,IAAI,GAAG,GAAG,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;YAEvC,+EAA+E;YAC/E,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC9C,MAAM,KAAK,GAAG,CAAC,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;gBAClD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBAC1B,yDAAyD;oBACzD,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;oBAChC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE;wBAClD,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE;4BAClD,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE;gCAClD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE;oCAC1C,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;gCACzB,CAAC,CAAC,CAAC;4BACJ,CAAC,CAAC,CAAC;wBACJ,CAAC,CAAC,CAAC;oBACJ,CAAC,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAEO,QAAQ,CAAI,MAAiB,EAAE,MAAc;QACpD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7B,+EAA+E;QAC/E,2BAA2B;QAC3B,gDAAgD;QAChD,OAAO,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,KAAK,CAAgB,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAClF,CAAC;IAEM,QAAQ;QACd,OAAO,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;IAEM,MAAM,CAAC,IAAI,CAAI,IAAmB;QACxC,OAAO,IAAI,aAAa,CAAI,eAAe,CAAI,IAAI,CAA6B,CAAC,CAAC;IACnF,CAAC;CACD","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
|
+
{"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(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"]}
|
package/lib/tsdoc-metadata.json
CHANGED
|
@@ -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,GAAG,IAAI;IAwD3D,OAAO,CAAC,cAAc;
|
|
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;CAmDtB;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"}
|
package/lib/undoprovider.js
CHANGED
|
@@ -66,8 +66,6 @@ export class VectorUndoProvider {
|
|
|
66
66
|
try {
|
|
67
67
|
if (removedTrackingGroup !== undefined) {
|
|
68
68
|
while (removedTrackingGroup.size > 0) {
|
|
69
|
-
// TODO Non null asserting, why is this not null?
|
|
70
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
71
69
|
const tracked = removedTrackingGroup.tracked[0];
|
|
72
70
|
removedTrackingGroup.unlink(tracked);
|
|
73
71
|
// if there are groups tracked, this in a revert of a remove.
|
|
@@ -90,8 +88,6 @@ export class VectorUndoProvider {
|
|
|
90
88
|
discard: () => {
|
|
91
89
|
if (removedTrackingGroup !== undefined) {
|
|
92
90
|
while (removedTrackingGroup.size > 0) {
|
|
93
|
-
// TODO Non null asserting, why is this not null?
|
|
94
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
95
91
|
removedTrackingGroup.unlink(removedTrackingGroup.tracked[0]);
|
|
96
92
|
}
|
|
97
93
|
}
|
package/lib/undoprovider.js.map
CHANGED
|
@@ -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): 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"]}
|
|
1
|
+
{"version":3,"file":"undoprovider.js","sourceRoot":"","sources":["../src/undoprovider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAC7D,OAAO,EAIN,kBAAkB,EAElB,aAAa,EACb,iCAAiC,EACjC,+BAA+B,EAC/B,+BAA+B,GAC/B,MAAM,qCAAqC,CAAC;AAE7C,OAAO,EAAU,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAMzD,MAAM,OAAO,kBAAkB;IAQ9B,YACkB,OAAsB,EACtB,MAAiC;QADjC,YAAO,GAAP,OAAO,CAAe;QACtB,WAAM,GAAN,MAAM,CAA2B;IAChD,CAAC;IAEG,MAAM,CAAC,SAAsC;QACnD,IAAI,SAAS,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,8FAA8F;YAC9F,4FAA4F;YAC5F,wCAAwC;YACxC,MAAM,WAAW,GAA+B,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;YACxE,iCAAiC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YAE1D,+EAA+E;YAC/E,8EAA8E;YAC9E,MAAM,CACL,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS,EACtE,KAAK,CAAC,0DAA0D,CAChE,CAAC;YACF,IAAI,mBAA8C,CAAC;YACnD,IAAI,SAAS,CAAC,SAAS,KAAK,kBAAkB,CAAC,MAAM,EAAE,CAAC;gBACvD,gDAAgD;gBAChD,4BAA4B;gBAC5B,8EAA8E;gBAC9E,2EAA2E;gBAC3E,qFAAqF;gBACrF,6FAA6F;gBAC7F,uCAAuC;gBACvC,+EAA+E;gBAC/E,+EAA+E;gBAC/E,oCAAoC;gBACpC,MAAM,aAAa,GAAG,CAAC,mBAAmB;oBACzC,IAAI,CAAC,0BAA0B,IAAI,IAAI,aAAa,EAAE,CAAC,CAAC;gBACzD,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,aAAa;oBACtC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACnD,CAAC;YAED,QAAQ,SAAS,CAAC,SAAS,EAAE,CAAC;gBAC7B,KAAK,kBAAkB,CAAC,MAAM,CAAC;gBAC/B,KAAK,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;oBAChC,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS,EAAE,CAAC;wBAC5C,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;oBACvD,CAAC;oBACD,MAAM;gBACP,CAAC;gBAED,OAAO,CAAC,CAAC,CAAC;oBACT,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBAClD,CAAC;YACF,CAAC;YAED,yFAAyF;YACzF,0FAA0F;YAC1F,SAAS;YACT,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;gBACrC,IAAI,CAAC,SAAS,KAAd,IAAI,CAAC,SAAS,GAAK,SAAS,CAAC,SAAS,EAAC;gBACvC,IAAI,CAAC,0BAA0B,KAA/B,IAAI,CAAC,0BAA0B,GAAK,mBAAmB,EAAC;YACzD,CAAC;QACF,CAAC;IACF,CAAC;IAEO,cAAc,CACrB,WAAuC,EACvC,oBAAgD;QAKhD,MAAM,QAAQ,GAAG;YAChB,MAAM,EAAE,GAAS,EAAE;gBAClB,MAAM,CACL,IAAI,CAAC,YAAY,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAC/D,KAAK,CAAC,mDAAmD,CACzD,CAAC;gBAEF,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;gBAEvB,IAAI,CAAC;oBACJ,IAAI,oBAAoB,KAAK,SAAS,EAAE,CAAC;wBACxC,OAAO,oBAAoB,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;4BACtC,MAAM,OAAO,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;4BAChD,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;4BACrC,6DAA6D;4BAC7D,sDAAsD;4BACtD,qEAAqE;4BACrE,uBAAuB;4BACvB,uDAAuD;4BACvD,wDAAwD;4BACvD,OAA8B,CAAC,KAAK,EAAE,CAAC;wBACzC,CAAC;oBACF,CAAC;oBACD,+BAA+B,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;gBAC3D,CAAC;wBAAS,CAAC;oBACV,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;oBAC3B,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;oBAC9B,IAAI,CAAC,0BAA0B,GAAG,SAAS,CAAC;gBAC7C,CAAC;YACF,CAAC;YACD,OAAO,EAAE,GAAS,EAAE;gBACnB,IAAI,oBAAoB,KAAK,SAAS,EAAE,CAAC;oBACxC,OAAO,oBAAoB,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;wBACtC,oBAAoB,CAAC,MAAM,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC9D,CAAC;gBACF,CAAC;gBACD,+BAA+B,CAAC,WAAW,CAAC,CAAC;YAC9C,CAAC;SACD,CAAC;QAEF,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC;QAE9C,OAAO,QAAQ,CAAC;IACjB,CAAC;CACD;AAED,MAAM,OAAO,kBAAkB;IAC9B,YACkB,QAAuB,EACvB,MAAuB,EACvB,IAAuB,EACvB,IAAuB;QAHvB,aAAQ,GAAR,QAAQ,CAAe;QACvB,WAAM,GAAN,MAAM,CAAiB;QACvB,SAAI,GAAJ,IAAI,CAAmB;QACvB,SAAI,GAAJ,IAAI,CAAmB;QAExC,IAAI,CAAC,IAAI,GAAG,IAAI,kBAAkB,CAAC,QAAQ,EAAE;YAC5C,aAAa;gBACZ,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACpC,CAAC;YACD,cAAc,CAAC,GAAG,EAAE,IAAI;gBACvB,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACnC,CAAC;YACD,WAAW,CAAC,KAAK,EAAE,GAAG;gBACrB,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,CAAC,CAAC;YACvC,CAAC;SACD,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,IAAI,kBAAkB,CAAC,QAAQ,EAAE;YAC5C,aAAa;gBACZ,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACpC,CAAC;YACD,cAAc,CAAC,GAAG,EAAE,IAAI;gBACvB,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACnC,CAAC;YACD,WAAW,CAAC,KAAK,EAAE,GAAG;gBACrB,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,CAAC,CAAC;YACvC,CAAC;SACD,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,SAAiB,EAAE,SAAiB,EAAE,QAAuB;QACpE,MAAM,CACL,aAAa,CAAC,SAAS,CAAC,IAAI,aAAa,CAAC,SAAS,CAAC,EACpD,KAAK,CAAC,wDAAwD,CAC9D,CAAC;QAEF,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC;gBACpC,MAAM,EAAE,GAAG,EAAE;oBACZ,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;oBAClD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;oBAClD,6DAA6D;oBAC7D,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;wBAC9D,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;oBACzC,CAAC;gBACF,CAAC;gBACD,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;aACjB,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;CACD","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\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\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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/matrix",
|
|
3
|
-
"version": "2.3.0
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Distributed matrix",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -63,17 +63,17 @@
|
|
|
63
63
|
"temp-directory": "nyc/.nyc_output"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@fluid-internal/client-utils": "2.3.0
|
|
67
|
-
"@fluidframework/core-interfaces": "2.3.0
|
|
68
|
-
"@fluidframework/core-utils": "2.3.0
|
|
69
|
-
"@fluidframework/datastore-definitions": "2.3.0
|
|
70
|
-
"@fluidframework/driver-definitions": "2.3.0
|
|
71
|
-
"@fluidframework/driver-utils": "2.3.0
|
|
72
|
-
"@fluidframework/merge-tree": "2.3.0
|
|
73
|
-
"@fluidframework/runtime-definitions": "2.3.0
|
|
74
|
-
"@fluidframework/runtime-utils": "2.3.0
|
|
75
|
-
"@fluidframework/shared-object-base": "2.3.0
|
|
76
|
-
"@fluidframework/telemetry-utils": "2.3.0
|
|
66
|
+
"@fluid-internal/client-utils": "~2.3.0",
|
|
67
|
+
"@fluidframework/core-interfaces": "~2.3.0",
|
|
68
|
+
"@fluidframework/core-utils": "~2.3.0",
|
|
69
|
+
"@fluidframework/datastore-definitions": "~2.3.0",
|
|
70
|
+
"@fluidframework/driver-definitions": "~2.3.0",
|
|
71
|
+
"@fluidframework/driver-utils": "~2.3.0",
|
|
72
|
+
"@fluidframework/merge-tree": "~2.3.0",
|
|
73
|
+
"@fluidframework/runtime-definitions": "~2.3.0",
|
|
74
|
+
"@fluidframework/runtime-utils": "~2.3.0",
|
|
75
|
+
"@fluidframework/shared-object-base": "~2.3.0",
|
|
76
|
+
"@fluidframework/telemetry-utils": "~2.3.0",
|
|
77
77
|
"@tiny-calc/nano": "0.0.0-alpha.5",
|
|
78
78
|
"double-ended-queue": "^2.1.0-0",
|
|
79
79
|
"tslib": "^1.10.0"
|
|
@@ -81,18 +81,18 @@
|
|
|
81
81
|
"devDependencies": {
|
|
82
82
|
"@arethetypeswrong/cli": "^0.15.2",
|
|
83
83
|
"@biomejs/biome": "~1.8.3",
|
|
84
|
-
"@fluid-internal/mocha-test-setup": "2.3.0
|
|
85
|
-
"@fluid-private/stochastic-test-utils": "2.3.0
|
|
86
|
-
"@fluid-private/test-dds-utils": "2.3.0
|
|
84
|
+
"@fluid-internal/mocha-test-setup": "~2.3.0",
|
|
85
|
+
"@fluid-private/stochastic-test-utils": "~2.3.0",
|
|
86
|
+
"@fluid-private/test-dds-utils": "~2.3.0",
|
|
87
87
|
"@fluid-tools/benchmark": "^0.50.0",
|
|
88
|
-
"@fluid-tools/build-cli": "^0.
|
|
88
|
+
"@fluid-tools/build-cli": "^0.46.0",
|
|
89
89
|
"@fluidframework/build-common": "^2.0.3",
|
|
90
|
-
"@fluidframework/build-tools": "^0.
|
|
91
|
-
"@fluidframework/container-definitions": "2.3.0
|
|
92
|
-
"@fluidframework/eslint-config-fluid": "^5.
|
|
90
|
+
"@fluidframework/build-tools": "^0.46.0",
|
|
91
|
+
"@fluidframework/container-definitions": "~2.3.0",
|
|
92
|
+
"@fluidframework/eslint-config-fluid": "^5.4.0",
|
|
93
93
|
"@fluidframework/matrix-previous": "npm:@fluidframework/matrix@2.2.0",
|
|
94
|
-
"@fluidframework/test-runtime-utils": "2.3.0
|
|
95
|
-
"@microsoft/api-extractor": "
|
|
94
|
+
"@fluidframework/test-runtime-utils": "~2.3.0",
|
|
95
|
+
"@microsoft/api-extractor": "7.47.8",
|
|
96
96
|
"@tiny-calc/micro": "0.0.0-alpha.5",
|
|
97
97
|
"@types/double-ended-queue": "^2.1.0",
|
|
98
98
|
"@types/mocha": "^9.1.1",
|
|
@@ -115,7 +115,8 @@
|
|
|
115
115
|
"typescript": "~5.4.5"
|
|
116
116
|
},
|
|
117
117
|
"typeValidation": {
|
|
118
|
-
"broken": {}
|
|
118
|
+
"broken": {},
|
|
119
|
+
"entrypoint": "internal"
|
|
119
120
|
},
|
|
120
121
|
"scripts": {
|
|
121
122
|
"api": "fluid-build . --task api",
|
package/src/handlecache.ts
CHANGED
|
@@ -50,11 +50,7 @@ export class HandleCache implements IVectorConsumer<Handle> {
|
|
|
50
50
|
// checking that 'position' is in bounds until 'cacheMiss(..)'. This yields an
|
|
51
51
|
// ~40% speedup when the position is in the cache (node v12 x64).
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
if (handle !== undefined) {
|
|
55
|
-
return handle;
|
|
56
|
-
}
|
|
57
|
-
return this.cacheMiss(position);
|
|
53
|
+
return index < this.handles.length ? this.handles[index] : this.cacheMiss(position);
|
|
58
54
|
}
|
|
59
55
|
|
|
60
56
|
/**
|
|
@@ -66,9 +62,7 @@ export class HandleCache implements IVectorConsumer<Handle> {
|
|
|
66
62
|
const index = this.getIndex(position);
|
|
67
63
|
if (index < this.handles.length) {
|
|
68
64
|
assert(
|
|
69
|
-
|
|
70
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
71
|
-
!isHandleValid(this.handles[index]!),
|
|
65
|
+
!isHandleValid(this.handles[index]),
|
|
72
66
|
0x018 /* "Trying to insert handle into position with already valid handle!" */,
|
|
73
67
|
);
|
|
74
68
|
this.handles[index] = handle;
|
|
@@ -110,9 +104,7 @@ export class HandleCache implements IVectorConsumer<Handle> {
|
|
|
110
104
|
if (_position < this.start) {
|
|
111
105
|
this.handles = [...this.getHandles(_position, this.start), ...this.handles];
|
|
112
106
|
this.start = _position;
|
|
113
|
-
|
|
114
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
115
|
-
return this.handles[0]!;
|
|
107
|
+
return this.handles[0];
|
|
116
108
|
} else {
|
|
117
109
|
ensureRange(_position, this.vector.getLength());
|
|
118
110
|
|
|
@@ -120,9 +112,7 @@ export class HandleCache implements IVectorConsumer<Handle> {
|
|
|
120
112
|
...this.handles,
|
|
121
113
|
...this.getHandles(this.start + this.handles.length, _position + 1),
|
|
122
114
|
];
|
|
123
|
-
|
|
124
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
125
|
-
return this.handles[this.handles.length - 1]!;
|
|
115
|
+
return this.handles[this.handles.length - 1];
|
|
126
116
|
}
|
|
127
117
|
}
|
|
128
118
|
|
package/src/matrix.ts
CHANGED
|
@@ -621,9 +621,7 @@ export class SharedMatrix<T = any>
|
|
|
621
621
|
const rowCount = inserted.cachedLength;
|
|
622
622
|
for (let row = rowStart; row < rowStart + rowCount; row++, rowHandle++) {
|
|
623
623
|
for (let col = 0; col < this.colCount; col++) {
|
|
624
|
-
|
|
625
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
626
|
-
const colHandle = this.colHandles.getHandle(col)!;
|
|
624
|
+
const colHandle = this.colHandles.getHandle(col);
|
|
627
625
|
const value = this.cells.getCell(rowHandle, colHandle);
|
|
628
626
|
if (this.isAttached() && value !== undefined && value !== null) {
|
|
629
627
|
this.sendSetCellOp(row, col, value, rowHandle, colHandle);
|
|
@@ -647,9 +645,7 @@ export class SharedMatrix<T = any>
|
|
|
647
645
|
const colCount = inserted.cachedLength;
|
|
648
646
|
for (let col = colStart; col < colStart + colCount; col++, colHandle++) {
|
|
649
647
|
for (let row = 0; row < this.rowCount; row++) {
|
|
650
|
-
|
|
651
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
652
|
-
const rowHandle = this.rowHandles.getHandle(row)!;
|
|
648
|
+
const rowHandle = this.rowHandles.getHandle(row);
|
|
653
649
|
const value = this.cells.getCell(rowHandle, colHandle);
|
|
654
650
|
if (this.isAttached() && value !== undefined && value !== null) {
|
|
655
651
|
this.sendSetCellOp(row, col, value, rowHandle, colHandle);
|
package/src/packageVersion.ts
CHANGED
package/src/permutationvector.ts
CHANGED
|
@@ -170,9 +170,7 @@ export class PermutationVector extends Client {
|
|
|
170
170
|
0x027 /* "Trying to get handle of out-of-bounds position!" */,
|
|
171
171
|
);
|
|
172
172
|
|
|
173
|
-
|
|
174
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
175
|
-
return this.handleCache.getHandle(pos)!;
|
|
173
|
+
return this.handleCache.getHandle(pos);
|
|
176
174
|
}
|
|
177
175
|
|
|
178
176
|
public getAllocatedHandle(pos: number): Handle {
|
package/src/sparsearray2d.ts
CHANGED
|
@@ -32,9 +32,7 @@ const byte3 = (x32: number): number => (x32 << 24) >>> 24;
|
|
|
32
32
|
// Given a uint16 returns the corresponding uint32 integer where 0s are
|
|
33
33
|
// interleaved between the original bits. (e.g., 1111... -> 01010101...).
|
|
34
34
|
const interlaceBitsX16 = (x16: number): number =>
|
|
35
|
-
|
|
36
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
37
|
-
(x8ToInterlacedX16[byte2(x16)]! << 16) | x8ToInterlacedX16[byte3(x16)]!;
|
|
35
|
+
(x8ToInterlacedX16[byte2(x16)] << 16) | x8ToInterlacedX16[byte3(x16)];
|
|
38
36
|
|
|
39
37
|
const r0ToMorton16 = (row: number): number => (interlaceBitsX16(row) << 1) >>> 0;
|
|
40
38
|
const c0ToMorton16 = (col: number): number => interlaceBitsX16(col) >>> 0;
|
package/src/undoprovider.ts
CHANGED
|
@@ -110,9 +110,7 @@ export class VectorUndoProvider {
|
|
|
110
110
|
try {
|
|
111
111
|
if (removedTrackingGroup !== undefined) {
|
|
112
112
|
while (removedTrackingGroup.size > 0) {
|
|
113
|
-
|
|
114
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
115
|
-
const tracked = removedTrackingGroup.tracked[0]!;
|
|
113
|
+
const tracked = removedTrackingGroup.tracked[0];
|
|
116
114
|
removedTrackingGroup.unlink(tracked);
|
|
117
115
|
// if there are groups tracked, this in a revert of a remove.
|
|
118
116
|
// this means we are about to re-insert the row/column
|
|
@@ -133,9 +131,7 @@ export class VectorUndoProvider {
|
|
|
133
131
|
discard: (): void => {
|
|
134
132
|
if (removedTrackingGroup !== undefined) {
|
|
135
133
|
while (removedTrackingGroup.size > 0) {
|
|
136
|
-
|
|
137
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
138
|
-
removedTrackingGroup.unlink(removedTrackingGroup.tracked[0]!);
|
|
134
|
+
removedTrackingGroup.unlink(removedTrackingGroup.tracked[0]);
|
|
139
135
|
}
|
|
140
136
|
}
|
|
141
137
|
discardMergeTreeDeltaRevertible(revertibles);
|