@fluidframework/map 2.0.0-rc.2.0.1 → 2.0.0-rc.3.0.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 (129) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/api-report/map.api.md +17 -158
  3. package/dist/directory.d.ts +7 -51
  4. package/dist/directory.d.ts.map +1 -1
  5. package/dist/directory.js +39 -107
  6. package/dist/directory.js.map +1 -1
  7. package/dist/directoryFactory.d.ts +54 -0
  8. package/dist/directoryFactory.d.ts.map +1 -0
  9. package/dist/directoryFactory.js +91 -0
  10. package/dist/directoryFactory.js.map +1 -0
  11. package/dist/index.d.ts +3 -45
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +7 -55
  14. package/dist/index.js.map +1 -1
  15. package/dist/interfaces.d.ts +7 -57
  16. package/dist/interfaces.d.ts.map +1 -1
  17. package/dist/interfaces.js.map +1 -1
  18. package/dist/internalInterfaces.d.ts +50 -1
  19. package/dist/internalInterfaces.d.ts.map +1 -1
  20. package/dist/internalInterfaces.js.map +1 -1
  21. package/dist/legacy.d.ts +25 -0
  22. package/dist/localValues.d.ts +1 -1
  23. package/dist/localValues.d.ts.map +1 -1
  24. package/dist/localValues.js +6 -6
  25. package/dist/localValues.js.map +1 -1
  26. package/dist/map.d.ts +4 -36
  27. package/dist/map.d.ts.map +1 -1
  28. package/dist/map.js +9 -60
  29. package/dist/map.js.map +1 -1
  30. package/dist/mapFactory.d.ts +52 -0
  31. package/dist/mapFactory.d.ts.map +1 -0
  32. package/dist/mapFactory.js +71 -0
  33. package/dist/mapFactory.js.map +1 -0
  34. package/dist/mapKernel.d.ts +3 -3
  35. package/dist/mapKernel.d.ts.map +1 -1
  36. package/dist/mapKernel.js +14 -14
  37. package/dist/mapKernel.js.map +1 -1
  38. package/dist/packageVersion.d.ts +1 -1
  39. package/dist/packageVersion.js +1 -1
  40. package/dist/packageVersion.js.map +1 -1
  41. package/dist/public.d.ts +12 -0
  42. package/internal.d.ts +11 -0
  43. package/legacy.d.ts +11 -0
  44. package/lib/directory.d.ts +7 -51
  45. package/lib/directory.d.ts.map +1 -1
  46. package/lib/directory.js +6 -73
  47. package/lib/directory.js.map +1 -1
  48. package/lib/directoryFactory.d.ts +54 -0
  49. package/lib/directoryFactory.d.ts.map +1 -0
  50. package/lib/directoryFactory.js +87 -0
  51. package/lib/directoryFactory.js.map +1 -0
  52. package/lib/index.d.ts +3 -45
  53. package/lib/index.d.ts.map +1 -1
  54. package/lib/index.js +2 -50
  55. package/lib/index.js.map +1 -1
  56. package/lib/interfaces.d.ts +7 -57
  57. package/lib/interfaces.d.ts.map +1 -1
  58. package/lib/interfaces.js.map +1 -1
  59. package/lib/internalInterfaces.d.ts +50 -1
  60. package/lib/internalInterfaces.d.ts.map +1 -1
  61. package/lib/internalInterfaces.js.map +1 -1
  62. package/lib/legacy.d.ts +25 -0
  63. package/lib/localValues.d.ts +1 -1
  64. package/lib/localValues.d.ts.map +1 -1
  65. package/lib/localValues.js +1 -1
  66. package/lib/localValues.js.map +1 -1
  67. package/lib/map.d.ts +4 -36
  68. package/lib/map.d.ts.map +1 -1
  69. package/lib/map.js +4 -54
  70. package/lib/map.js.map +1 -1
  71. package/lib/mapFactory.d.ts +52 -0
  72. package/lib/mapFactory.d.ts.map +1 -0
  73. package/lib/mapFactory.js +67 -0
  74. package/lib/mapFactory.js.map +1 -0
  75. package/lib/mapKernel.d.ts +3 -3
  76. package/lib/mapKernel.d.ts.map +1 -1
  77. package/lib/mapKernel.js +2 -2
  78. package/lib/mapKernel.js.map +1 -1
  79. package/lib/packageVersion.d.ts +1 -1
  80. package/lib/packageVersion.js +1 -1
  81. package/lib/packageVersion.js.map +1 -1
  82. package/lib/public.d.ts +12 -0
  83. package/package.json +105 -59
  84. package/src/directory.ts +16 -100
  85. package/src/directoryFactory.ts +120 -0
  86. package/src/index.ts +2 -73
  87. package/src/interfaces.ts +7 -62
  88. package/src/internalInterfaces.ts +55 -2
  89. package/src/localValues.ts +6 -5
  90. package/src/map.ts +8 -71
  91. package/src/mapFactory.ts +101 -0
  92. package/src/mapKernel.ts +13 -9
  93. package/src/packageVersion.ts +1 -1
  94. package/api-extractor-cjs.json +0 -8
  95. package/dist/map-alpha.d.ts +0 -898
  96. package/dist/map-beta.d.ts +0 -195
  97. package/dist/map-public.d.ts +0 -195
  98. package/dist/map-untrimmed.d.ts +0 -912
  99. package/lib/map-alpha.d.ts +0 -898
  100. package/lib/map-beta.d.ts +0 -195
  101. package/lib/map-public.d.ts +0 -195
  102. package/lib/map-untrimmed.d.ts +0 -912
  103. package/lib/test/memory/directory.spec.js +0 -71
  104. package/lib/test/memory/directory.spec.js.map +0 -1
  105. package/lib/test/memory/map.spec.js +0 -71
  106. package/lib/test/memory/map.spec.js.map +0 -1
  107. package/lib/test/mocha/directory.order.spec.js +0 -422
  108. package/lib/test/mocha/directory.order.spec.js.map +0 -1
  109. package/lib/test/mocha/directory.snapshot.spec.js +0 -111
  110. package/lib/test/mocha/directory.snapshot.spec.js.map +0 -1
  111. package/lib/test/mocha/directory.spec.js +0 -1406
  112. package/lib/test/mocha/directory.spec.js.map +0 -1
  113. package/lib/test/mocha/directoryEquivalenceUtils.js +0 -36
  114. package/lib/test/mocha/directoryEquivalenceUtils.js.map +0 -1
  115. package/lib/test/mocha/directoryFuzzTests.spec.js +0 -337
  116. package/lib/test/mocha/directoryFuzzTests.spec.js.map +0 -1
  117. package/lib/test/mocha/dirname.cjs +0 -16
  118. package/lib/test/mocha/dirname.cjs.map +0 -1
  119. package/lib/test/mocha/map.fuzz.spec.js +0 -114
  120. package/lib/test/mocha/map.fuzz.spec.js.map +0 -1
  121. package/lib/test/mocha/map.spec.js +0 -685
  122. package/lib/test/mocha/map.spec.js.map +0 -1
  123. package/lib/test/mocha/rebasing.spec.js +0 -158
  124. package/lib/test/mocha/rebasing.spec.js.map +0 -1
  125. package/lib/test/mocha/reconnection.spec.js +0 -327
  126. package/lib/test/mocha/reconnection.spec.js.map +0 -1
  127. package/lib/test/types/validateMapPrevious.generated.js +0 -66
  128. package/lib/test/types/validateMapPrevious.generated.js.map +0 -1
  129. /package/{dist → lib}/tsdoc-metadata.json +0 -0
@@ -1,71 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { MockFluidDataStoreRuntime } from "@fluidframework/test-runtime-utils";
6
- import { benchmarkMemory } from "@fluid-tools/benchmark";
7
- import { DirectoryFactory, SharedDirectory } from "../../directory.js";
8
- function createLocalDirectory(id) {
9
- const directory = new SharedDirectory(id, new MockFluidDataStoreRuntime(), DirectoryFactory.Attributes);
10
- return directory;
11
- }
12
- describe("SharedDirectory memory usage", () => {
13
- // IMPORTANT: variables scoped to the test suite are a big problem for memory-profiling tests
14
- // because they won't be out of scope when we garbage-collect between runs of the same test,
15
- // and that will skew measurements. Tests should allocate all the memory they need using local
16
- // variables scoped to the test function itself, so several iterations of a given test can
17
- // measure from the same baseline (as much as possible).
18
- beforeEach(async () => {
19
- // CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables
20
- // whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.
21
- // See the comment at the top of the test suite for more details.
22
- });
23
- afterEach(() => {
24
- // CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables
25
- // whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.
26
- // See the comment at the top of the test suite for more details.
27
- });
28
- benchmarkMemory(new (class {
29
- constructor() {
30
- this.title = "Create empty directory";
31
- this.minSampleCount = 500;
32
- this.dir = createLocalDirectory("testDirectory");
33
- }
34
- async run() {
35
- this.dir = createLocalDirectory("testDirectory");
36
- }
37
- })());
38
- const numbersOfEntriesForTests = [1000, 10000, 100000];
39
- for (const x of numbersOfEntriesForTests) {
40
- benchmarkMemory(new (class {
41
- constructor() {
42
- this.title = `Add ${x} integers to a local directory`;
43
- this.dir = createLocalDirectory("testDirectory");
44
- }
45
- async run() {
46
- for (let i = 0; i < x; i++) {
47
- this.dir.set(i.toString().padStart(6, "0"), i);
48
- }
49
- }
50
- beforeIteration() {
51
- this.dir = createLocalDirectory("testDirectory");
52
- }
53
- })());
54
- benchmarkMemory(new (class {
55
- constructor() {
56
- this.title = `Add ${x} integers to a local directory, clear it`;
57
- this.dir = createLocalDirectory("testDirectory");
58
- }
59
- async run() {
60
- for (let i = 0; i < x; i++) {
61
- this.dir.set(i.toString().padStart(6, "0"), i);
62
- }
63
- this.dir.clear();
64
- }
65
- beforeIteration() {
66
- this.dir = createLocalDirectory("testDirectory");
67
- }
68
- })());
69
- }
70
- });
71
- //# sourceMappingURL=directory.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"directory.spec.js","sourceRoot":"","sources":["../../../src/test/memory/directory.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAqB,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAEvE,SAAS,oBAAoB,CAAC,EAAU;IACvC,MAAM,SAAS,GAAG,IAAI,eAAe,CACpC,EAAE,EACF,IAAI,yBAAyB,EAAE,EAC/B,gBAAgB,CAAC,UAAU,CAC3B,CAAC;IACF,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC7C,6FAA6F;IAC7F,4FAA4F;IAC5F,8FAA8F;IAC9F,0FAA0F;IAC1F,wDAAwD;IAExD,UAAU,CAAC,KAAK,IAAI,EAAE;QACrB,gGAAgG;QAChG,8FAA8F;QAC9F,iEAAiE;IAClE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACd,gGAAgG;QAChG,8FAA8F;QAC9F,iEAAiE;IAClE,CAAC,CAAC,CAAC;IAEH,eAAe,CACd,IAAI,CAAC;QAAA;YACY,UAAK,GAAG,wBAAwB,CAAC;YACjC,mBAAc,GAAG,GAAG,CAAC;YAE7B,QAAG,GAAoB,oBAAoB,CAAC,eAAe,CAAC,CAAC;QAKtE,CAAC;QAHO,KAAK,CAAC,GAAG;YACf,IAAI,CAAC,GAAG,GAAG,oBAAoB,CAAC,eAAe,CAAC,CAAC;QAClD,CAAC;KACD,CAAC,EAAE,CACJ,CAAC;IAEF,MAAM,wBAAwB,GAAG,CAAC,IAAI,EAAE,KAAM,EAAE,MAAO,CAAC,CAAC;IAEzD,KAAK,MAAM,CAAC,IAAI,wBAAwB,EAAE;QACzC,eAAe,CACd,IAAI,CAAC;YAAA;gBACY,UAAK,GAAG,OAAO,CAAC,gCAAgC,CAAC;gBACzD,QAAG,GAAoB,oBAAoB,CAAC,eAAe,CAAC,CAAC;YAWtE,CAAC;YATO,KAAK,CAAC,GAAG;gBACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;oBAC3B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;iBAC/C;YACF,CAAC;YAEM,eAAe;gBACrB,IAAI,CAAC,GAAG,GAAG,oBAAoB,CAAC,eAAe,CAAC,CAAC;YAClD,CAAC;SACD,CAAC,EAAE,CACJ,CAAC;QAEF,eAAe,CACd,IAAI,CAAC;YAAA;gBACY,UAAK,GAAG,OAAO,CAAC,0CAA0C,CAAC;gBACnE,QAAG,GAAoB,oBAAoB,CAAC,eAAe,CAAC,CAAC;YAYtE,CAAC;YAVO,KAAK,CAAC,GAAG;gBACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;oBAC3B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;iBAC/C;gBACD,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YAClB,CAAC;YAEM,eAAe;gBACrB,IAAI,CAAC,GAAG,GAAG,oBAAoB,CAAC,eAAe,CAAC,CAAC;YAClD,CAAC;SACD,CAAC,EAAE,CACJ,CAAC;KACF;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { MockFluidDataStoreRuntime } from \"@fluidframework/test-runtime-utils\";\nimport { benchmarkMemory, IMemoryTestObject } from \"@fluid-tools/benchmark\";\nimport { DirectoryFactory, SharedDirectory } from \"../../directory.js\";\n\nfunction createLocalDirectory(id: string): SharedDirectory {\n\tconst directory = new SharedDirectory(\n\t\tid,\n\t\tnew MockFluidDataStoreRuntime(),\n\t\tDirectoryFactory.Attributes,\n\t);\n\treturn directory;\n}\n\ndescribe(\"SharedDirectory memory usage\", () => {\n\t// IMPORTANT: variables scoped to the test suite are a big problem for memory-profiling tests\n\t// because they won't be out of scope when we garbage-collect between runs of the same test,\n\t// and that will skew measurements. Tests should allocate all the memory they need using local\n\t// variables scoped to the test function itself, so several iterations of a given test can\n\t// measure from the same baseline (as much as possible).\n\n\tbeforeEach(async () => {\n\t\t// CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables\n\t\t// whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.\n\t\t// See the comment at the top of the test suite for more details.\n\t});\n\n\tafterEach(() => {\n\t\t// CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables\n\t\t// whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.\n\t\t// See the comment at the top of the test suite for more details.\n\t});\n\n\tbenchmarkMemory(\n\t\tnew (class implements IMemoryTestObject {\n\t\t\tpublic readonly title = \"Create empty directory\";\n\t\t\tpublic readonly minSampleCount = 500;\n\n\t\t\tprivate dir: SharedDirectory = createLocalDirectory(\"testDirectory\");\n\n\t\t\tpublic async run(): Promise<void> {\n\t\t\t\tthis.dir = createLocalDirectory(\"testDirectory\");\n\t\t\t}\n\t\t})(),\n\t);\n\n\tconst numbersOfEntriesForTests = [1000, 10_000, 100_000];\n\n\tfor (const x of numbersOfEntriesForTests) {\n\t\tbenchmarkMemory(\n\t\t\tnew (class implements IMemoryTestObject {\n\t\t\t\tpublic readonly title = `Add ${x} integers to a local directory`;\n\t\t\t\tprivate dir: SharedDirectory = createLocalDirectory(\"testDirectory\");\n\n\t\t\t\tpublic async run(): Promise<void> {\n\t\t\t\t\tfor (let i = 0; i < x; i++) {\n\t\t\t\t\t\tthis.dir.set(i.toString().padStart(6, \"0\"), i);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tpublic beforeIteration(): void {\n\t\t\t\t\tthis.dir = createLocalDirectory(\"testDirectory\");\n\t\t\t\t}\n\t\t\t})(),\n\t\t);\n\n\t\tbenchmarkMemory(\n\t\t\tnew (class implements IMemoryTestObject {\n\t\t\t\tpublic readonly title = `Add ${x} integers to a local directory, clear it`;\n\t\t\t\tprivate dir: SharedDirectory = createLocalDirectory(\"testDirectory\");\n\n\t\t\t\tpublic async run(): Promise<void> {\n\t\t\t\t\tfor (let i = 0; i < x; i++) {\n\t\t\t\t\t\tthis.dir.set(i.toString().padStart(6, \"0\"), i);\n\t\t\t\t\t}\n\t\t\t\t\tthis.dir.clear();\n\t\t\t\t}\n\n\t\t\t\tpublic beforeIteration(): void {\n\t\t\t\t\tthis.dir = createLocalDirectory(\"testDirectory\");\n\t\t\t\t}\n\t\t\t})(),\n\t\t);\n\t}\n});\n"]}
@@ -1,71 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { MockFluidDataStoreRuntime } from "@fluidframework/test-runtime-utils";
6
- import { benchmarkMemory } from "@fluid-tools/benchmark";
7
- import { MapFactory, SharedMap } from "../../map.js";
8
- function createLocalMap(id) {
9
- const map = new SharedMap(id, new MockFluidDataStoreRuntime(), MapFactory.Attributes);
10
- return map;
11
- }
12
- describe("SharedMap memory usage", () => {
13
- // IMPORTANT: variables scoped to the test suite are a big problem for memory-profiling tests
14
- // because they won't be out of scope when we garbage-collect between runs of the same test,
15
- // and that will skew measurements. Tests should allocate all the memory they need using local
16
- // variables scoped to the test function itself, so several iterations of a given test can
17
- // measure from the same baseline (as much as possible).
18
- beforeEach(async () => {
19
- // CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables
20
- // whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.
21
- // See the comment at the top of the test suite for more details.
22
- });
23
- afterEach(() => {
24
- // CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables
25
- // whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.
26
- // See the comment at the top of the test suite for more details.
27
- });
28
- benchmarkMemory(new (class {
29
- constructor() {
30
- this.title = "Create empty map";
31
- this.minSampleCount = 500;
32
- this.map = createLocalMap("testMap");
33
- }
34
- async run() {
35
- this.map = createLocalMap("testMap");
36
- }
37
- })());
38
- const numbersOfEntriesForTests = [1000, 10000, 100000];
39
- for (const x of numbersOfEntriesForTests) {
40
- benchmarkMemory(new (class {
41
- constructor() {
42
- this.title = `Add ${x} integers to a local map`;
43
- this.map = createLocalMap("testMap");
44
- }
45
- async run() {
46
- for (let i = 0; i < x; i++) {
47
- this.map.set(i.toString().padStart(6, "0"), i);
48
- }
49
- }
50
- beforeIteration() {
51
- this.map = createLocalMap("testMap");
52
- }
53
- })());
54
- benchmarkMemory(new (class {
55
- constructor() {
56
- this.title = `Add ${x} integers to a local map, clear it`;
57
- this.map = createLocalMap("testMap");
58
- }
59
- async run() {
60
- for (let i = 0; i < x; i++) {
61
- this.map.set(i.toString().padStart(6, "0"), i);
62
- }
63
- this.map.clear();
64
- }
65
- beforeIteration() {
66
- this.map = createLocalMap("testMap");
67
- }
68
- })());
69
- }
70
- });
71
- //# sourceMappingURL=map.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"map.spec.js","sourceRoot":"","sources":["../../../src/test/memory/map.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAqB,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAErD,SAAS,cAAc,CAAC,EAAU;IACjC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,EAAE,EAAE,IAAI,yBAAyB,EAAE,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IACtF,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACvC,6FAA6F;IAC7F,4FAA4F;IAC5F,8FAA8F;IAC9F,0FAA0F;IAC1F,wDAAwD;IAExD,UAAU,CAAC,KAAK,IAAI,EAAE;QACrB,gGAAgG;QAChG,8FAA8F;QAC9F,iEAAiE;IAClE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACd,gGAAgG;QAChG,8FAA8F;QAC9F,iEAAiE;IAClE,CAAC,CAAC,CAAC;IAEH,eAAe,CACd,IAAI,CAAC;QAAA;YACY,UAAK,GAAG,kBAAkB,CAAC;YAC3B,mBAAc,GAAG,GAAG,CAAC;YAE7B,QAAG,GAAc,cAAc,CAAC,SAAS,CAAC,CAAC;QAKpD,CAAC;QAHO,KAAK,CAAC,GAAG;YACf,IAAI,CAAC,GAAG,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC;KACD,CAAC,EAAE,CACJ,CAAC;IAEF,MAAM,wBAAwB,GAAG,CAAC,IAAI,EAAE,KAAM,EAAE,MAAO,CAAC,CAAC;IAEzD,KAAK,MAAM,CAAC,IAAI,wBAAwB,EAAE;QACzC,eAAe,CACd,IAAI,CAAC;YAAA;gBACY,UAAK,GAAG,OAAO,CAAC,0BAA0B,CAAC;gBACnD,QAAG,GAAc,cAAc,CAAC,SAAS,CAAC,CAAC;YAWpD,CAAC;YATO,KAAK,CAAC,GAAG;gBACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;oBAC3B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;iBAC/C;YACF,CAAC;YAEM,eAAe;gBACrB,IAAI,CAAC,GAAG,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;YACtC,CAAC;SACD,CAAC,EAAE,CACJ,CAAC;QAEF,eAAe,CACd,IAAI,CAAC;YAAA;gBACY,UAAK,GAAG,OAAO,CAAC,oCAAoC,CAAC;gBAC7D,QAAG,GAAc,cAAc,CAAC,SAAS,CAAC,CAAC;YAYpD,CAAC;YAVO,KAAK,CAAC,GAAG;gBACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;oBAC3B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;iBAC/C;gBACD,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YAClB,CAAC;YAEM,eAAe;gBACrB,IAAI,CAAC,GAAG,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;YACtC,CAAC;SACD,CAAC,EAAE,CACJ,CAAC;KACF;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { MockFluidDataStoreRuntime } from \"@fluidframework/test-runtime-utils\";\nimport { benchmarkMemory, IMemoryTestObject } from \"@fluid-tools/benchmark\";\nimport { MapFactory, SharedMap } from \"../../map.js\";\n\nfunction createLocalMap(id: string): SharedMap {\n\tconst map = new SharedMap(id, new MockFluidDataStoreRuntime(), MapFactory.Attributes);\n\treturn map;\n}\n\ndescribe(\"SharedMap memory usage\", () => {\n\t// IMPORTANT: variables scoped to the test suite are a big problem for memory-profiling tests\n\t// because they won't be out of scope when we garbage-collect between runs of the same test,\n\t// and that will skew measurements. Tests should allocate all the memory they need using local\n\t// variables scoped to the test function itself, so several iterations of a given test can\n\t// measure from the same baseline (as much as possible).\n\n\tbeforeEach(async () => {\n\t\t// CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables\n\t\t// whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.\n\t\t// See the comment at the top of the test suite for more details.\n\t});\n\n\tafterEach(() => {\n\t\t// CAREFUL: usually beforeEach/afterEach hooks are used to initialize or interact with variables\n\t\t// whose scope is the encompasing test suite, but that's a problem for memory-profiling tests.\n\t\t// See the comment at the top of the test suite for more details.\n\t});\n\n\tbenchmarkMemory(\n\t\tnew (class implements IMemoryTestObject {\n\t\t\tpublic readonly title = \"Create empty map\";\n\t\t\tpublic readonly minSampleCount = 500;\n\n\t\t\tprivate map: SharedMap = createLocalMap(\"testMap\");\n\n\t\t\tpublic async run(): Promise<void> {\n\t\t\t\tthis.map = createLocalMap(\"testMap\");\n\t\t\t}\n\t\t})(),\n\t);\n\n\tconst numbersOfEntriesForTests = [1000, 10_000, 100_000];\n\n\tfor (const x of numbersOfEntriesForTests) {\n\t\tbenchmarkMemory(\n\t\t\tnew (class implements IMemoryTestObject {\n\t\t\t\tpublic readonly title = `Add ${x} integers to a local map`;\n\t\t\t\tprivate map: SharedMap = createLocalMap(\"testMap\");\n\n\t\t\t\tpublic async run(): Promise<void> {\n\t\t\t\t\tfor (let i = 0; i < x; i++) {\n\t\t\t\t\t\tthis.map.set(i.toString().padStart(6, \"0\"), i);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tpublic beforeIteration(): void {\n\t\t\t\t\tthis.map = createLocalMap(\"testMap\");\n\t\t\t\t}\n\t\t\t})(),\n\t\t);\n\n\t\tbenchmarkMemory(\n\t\t\tnew (class implements IMemoryTestObject {\n\t\t\t\tpublic readonly title = `Add ${x} integers to a local map, clear it`;\n\t\t\t\tprivate map: SharedMap = createLocalMap(\"testMap\");\n\n\t\t\t\tpublic async run(): Promise<void> {\n\t\t\t\t\tfor (let i = 0; i < x; i++) {\n\t\t\t\t\t\tthis.map.set(i.toString().padStart(6, \"0\"), i);\n\t\t\t\t\t}\n\t\t\t\t\tthis.map.clear();\n\t\t\t\t}\n\n\t\t\t\tpublic beforeIteration(): void {\n\t\t\t\t\tthis.map = createLocalMap(\"testMap\");\n\t\t\t\t}\n\t\t\t})(),\n\t\t);\n\t}\n});\n"]}
@@ -1,422 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { strict as assert } from "node:assert";
6
- import { MockContainerRuntimeFactory, MockContainerRuntimeFactoryForReconnection, MockFluidDataStoreRuntime, MockSharedObjectServices, MockStorage, } from "@fluidframework/test-runtime-utils";
7
- import { AttachState } from "@fluidframework/container-definitions";
8
- import { DirectoryFactory, SharedDirectory, } from "../../directory.js";
9
- function createConnectedDirectory(id, runtimeFactory) {
10
- const dataStoreRuntime = new MockFluidDataStoreRuntime();
11
- const containerRuntime = runtimeFactory.createContainerRuntime(dataStoreRuntime);
12
- const services = {
13
- deltaConnection: dataStoreRuntime.createDeltaConnection(),
14
- objectStorage: new MockStorage(),
15
- };
16
- const directory = new SharedDirectory(id, dataStoreRuntime, DirectoryFactory.Attributes);
17
- directory.connect(services);
18
- return directory;
19
- }
20
- class TestSharedDirectory extends SharedDirectory {
21
- testApplyStashedOp(content) {
22
- this.lastMetadata = undefined;
23
- this.applyStashedOp(content);
24
- return this.lastMetadata;
25
- }
26
- submitLocalMessage(op, localOpMetadata) {
27
- this.lastMetadata = localOpMetadata;
28
- super.submitLocalMessage(op, localOpMetadata);
29
- }
30
- }
31
- async function populate(directory, content) {
32
- const storage = new MockSharedObjectServices({
33
- header: JSON.stringify(content),
34
- });
35
- return directory.load(storage);
36
- }
37
- function assertDirectoryIterationOrder(directory, expectedDirNames) {
38
- const actualDirNames = [];
39
- for (const [subdirName, subdirObject] of directory.subdirectories()) {
40
- actualDirNames.push(subdirName);
41
- }
42
- assert.deepEqual(actualDirNames, expectedDirNames);
43
- }
44
- describe("Directory Iteration Order", () => {
45
- describe("Local state", () => {
46
- let directory;
47
- let dataStoreRuntime;
48
- beforeEach("createDirectory", async () => {
49
- dataStoreRuntime = new MockFluidDataStoreRuntime({ attachState: AttachState.Detached });
50
- directory = new SharedDirectory("directory", dataStoreRuntime, DirectoryFactory.Attributes);
51
- });
52
- it("create subdirectories", () => {
53
- directory.createSubDirectory("b");
54
- directory.createSubDirectory("a");
55
- directory.createSubDirectory("c");
56
- assertDirectoryIterationOrder(directory, ["b", "a", "c"]);
57
- });
58
- it("create nested subdirectories", () => {
59
- directory.createSubDirectory("c").createSubDirectory("c-a");
60
- directory.createSubDirectory("a").createSubDirectory("a-b");
61
- directory.createSubDirectory("a").createSubDirectory("a-a");
62
- directory.createSubDirectory("b");
63
- directory.createSubDirectory("c").createSubDirectory("c-c");
64
- directory.createSubDirectory("a").createSubDirectory("a-c");
65
- directory.createSubDirectory("c").createSubDirectory("c-b");
66
- assertDirectoryIterationOrder(directory, ["c", "a", "b"]);
67
- assert.notEqual(directory.getWorkingDirectory("/a"), undefined);
68
- assertDirectoryIterationOrder(directory.getWorkingDirectory("/a"), [
69
- "a-b",
70
- "a-a",
71
- "a-c",
72
- ]);
73
- assert.notEqual(directory.getWorkingDirectory("/b"), undefined);
74
- assertDirectoryIterationOrder(directory.getWorkingDirectory("/b"), []);
75
- assert.notEqual(directory.getWorkingDirectory("/c"), undefined);
76
- assertDirectoryIterationOrder(directory.getWorkingDirectory("/c"), [
77
- "c-a",
78
- "c-c",
79
- "c-b",
80
- ]);
81
- });
82
- it("delete subdirectories", () => {
83
- directory.createSubDirectory("c").createSubDirectory("c-a");
84
- directory.createSubDirectory("a").createSubDirectory("a-b");
85
- directory.createSubDirectory("a").createSubDirectory("a-a");
86
- directory.createSubDirectory("b");
87
- directory.createSubDirectory("c").createSubDirectory("c-c");
88
- directory.createSubDirectory("a").createSubDirectory("a-c");
89
- directory.createSubDirectory("c").createSubDirectory("c-b");
90
- directory.deleteSubDirectory("a");
91
- assertDirectoryIterationOrder(directory, ["c", "b"]);
92
- directory.createSubDirectory("a");
93
- assertDirectoryIterationOrder(directory, ["c", "b", "a"]);
94
- directory.getWorkingDirectory("/c")?.createSubDirectory("c-d");
95
- directory.getWorkingDirectory("/c")?.deleteSubDirectory("c-c");
96
- assertDirectoryIterationOrder(directory.getWorkingDirectory("/c"), [
97
- "c-a",
98
- "c-b",
99
- "c-d",
100
- ]);
101
- });
102
- });
103
- describe("Connected state", () => {
104
- let containerRuntimeFactory;
105
- let directory1;
106
- let directory2;
107
- beforeEach("createDirectories", async () => {
108
- containerRuntimeFactory = new MockContainerRuntimeFactory();
109
- // Create the first directory.
110
- directory1 = createConnectedDirectory("directory1", containerRuntimeFactory);
111
- // Create the second directory.
112
- directory2 = createConnectedDirectory("directory2", containerRuntimeFactory);
113
- });
114
- it("Remote messages have no conflict with the local pending ops", () => {
115
- directory1.createSubDirectory("a");
116
- directory1.createSubDirectory("b").createSubDirectory("b-b");
117
- directory2.createSubDirectory("c");
118
- directory2.createSubDirectory("d");
119
- directory1.deleteSubDirectory("a");
120
- directory2.createSubDirectory("b").createSubDirectory("b-a");
121
- containerRuntimeFactory.processSomeMessages(3);
122
- assertDirectoryIterationOrder(directory1, ["b"]);
123
- assertDirectoryIterationOrder(directory2, ["a", "b", "c", "d"]);
124
- containerRuntimeFactory.processSomeMessages(2);
125
- assertDirectoryIterationOrder(directory1, ["b", "c", "d"]);
126
- assertDirectoryIterationOrder(directory2, ["a", "b", "c", "d"]);
127
- containerRuntimeFactory.processAllMessages();
128
- assertDirectoryIterationOrder(directory1, ["b", "c", "d"]);
129
- assertDirectoryIterationOrder(directory2, ["b", "c", "d"]);
130
- assert(directory1.getWorkingDirectory("b"));
131
- assert(directory2.getWorkingDirectory("b"));
132
- assertDirectoryIterationOrder(directory1.getWorkingDirectory("b"), [
133
- "b-b",
134
- "b-a",
135
- ]);
136
- assertDirectoryIterationOrder(directory2.getWorkingDirectory("b"), [
137
- "b-b",
138
- "b-a",
139
- ]);
140
- });
141
- it("Remote messages have conflicts with the local pending ops", () => {
142
- directory1.createSubDirectory("b");
143
- directory2.createSubDirectory("a");
144
- directory2.createSubDirectory("b");
145
- containerRuntimeFactory.processSomeMessages(3);
146
- assertDirectoryIterationOrder(directory1, ["b", "a"]);
147
- assertDirectoryIterationOrder(directory2, ["b", "a"]);
148
- directory1.createSubDirectory("d").createSubDirectory("d-b");
149
- directory2.createSubDirectory("d").createSubDirectory("d-a");
150
- containerRuntimeFactory.processSomeMessages(4);
151
- assertDirectoryIterationOrder(directory1, ["b", "a", "d"]);
152
- assertDirectoryIterationOrder(directory2, ["b", "a", "d"]);
153
- assert.notEqual(directory1.getWorkingDirectory("/d"), undefined);
154
- assertDirectoryIterationOrder(directory1.getWorkingDirectory("/d"), ["d-b", "d-a"]);
155
- assert.notEqual(directory2.getWorkingDirectory("/d"), undefined);
156
- assertDirectoryIterationOrder(directory2.getWorkingDirectory("/d"), ["d-b", "d-a"]);
157
- directory1.deleteSubDirectory("d");
158
- directory2.getWorkingDirectory("/d")?.createSubDirectory("d-c");
159
- assertDirectoryIterationOrder(directory1, ["b", "a"]);
160
- assertDirectoryIterationOrder(directory2, ["b", "a", "d"]);
161
- assertDirectoryIterationOrder(directory2.getWorkingDirectory("/d"), ["d-b", "d-a", "d-c"]);
162
- containerRuntimeFactory.processAllMessages();
163
- assertDirectoryIterationOrder(directory1, ["b", "a"]);
164
- assertDirectoryIterationOrder(directory2, ["b", "a"]);
165
- });
166
- });
167
- describe("Serialization/Load", () => {
168
- let directory1;
169
- it("can be compatible with the old format summary", async () => {
170
- const dataStoreRuntime = new MockFluidDataStoreRuntime({
171
- attachState: AttachState.Detached,
172
- });
173
- directory1 = new SharedDirectory("directory", dataStoreRuntime, DirectoryFactory.Attributes);
174
- await populate(directory1, {
175
- storage: {
176
- key1: {
177
- type: "Plain",
178
- value: "val1",
179
- },
180
- key2: {
181
- type: "Plain",
182
- value: "val2",
183
- },
184
- },
185
- subdirectories: {
186
- b: {
187
- storage: {
188
- testKey: {
189
- type: "Plain",
190
- value: "testValue",
191
- },
192
- testKey2: {
193
- type: "Plain",
194
- value: "testValue2",
195
- },
196
- },
197
- },
198
- c: {
199
- storage: {
200
- testKey3: {
201
- type: "Plain",
202
- value: "testValue3",
203
- },
204
- },
205
- },
206
- a: {
207
- storage: {},
208
- },
209
- },
210
- });
211
- assertDirectoryIterationOrder(directory1, ["b", "c", "a"]);
212
- });
213
- it("can be compatible with the new format summary", async () => {
214
- const dataStoreRuntime = new MockFluidDataStoreRuntime({
215
- attachState: AttachState.Detached,
216
- });
217
- directory1 = new SharedDirectory("directory", dataStoreRuntime, DirectoryFactory.Attributes);
218
- await populate(directory1, {
219
- storage: {
220
- key1: {
221
- type: "Plain",
222
- value: "val1",
223
- },
224
- key2: {
225
- type: "Plain",
226
- value: "val2",
227
- },
228
- },
229
- subdirectories: {
230
- b: {
231
- storage: {
232
- testKey: {
233
- type: "Plain",
234
- value: "testValue",
235
- },
236
- testKey2: {
237
- type: "Plain",
238
- value: "testValue2",
239
- },
240
- },
241
- ci: {
242
- csn: 4,
243
- ccIds: ["client1"],
244
- },
245
- },
246
- c: {
247
- storage: {
248
- testKey3: {
249
- type: "Plain",
250
- value: "testValue3",
251
- },
252
- },
253
- subdirectories: {
254
- c_b: {
255
- storage: {},
256
- ci: {
257
- csn: 5,
258
- ccIds: ["client1"],
259
- },
260
- },
261
- c_a: {
262
- storage: {},
263
- ci: {
264
- csn: 6,
265
- ccIds: ["client1"],
266
- },
267
- },
268
- },
269
- ci: {
270
- csn: 2,
271
- ccIds: ["client2"],
272
- ccsn: 1,
273
- },
274
- },
275
- a: {
276
- storage: {},
277
- ci: {
278
- csn: 4,
279
- ccIds: ["client2"],
280
- },
281
- },
282
- },
283
- ci: {
284
- csn: 1,
285
- ccIds: ["client1", "client2"],
286
- },
287
- });
288
- assertDirectoryIterationOrder(directory1, ["c", "b", "a"]);
289
- assert(directory1.getWorkingDirectory("/c"));
290
- assertDirectoryIterationOrder(directory1.getWorkingDirectory("/c"), ["c_b", "c_a"]);
291
- });
292
- it("serialize the contents, load it into another directory and maintain the order", async () => {
293
- directory1 = new SharedDirectory("dir1", new MockFluidDataStoreRuntime(), DirectoryFactory.Attributes);
294
- directory1.createSubDirectory("c");
295
- directory1.createSubDirectory("b");
296
- directory1.createSubDirectory("a");
297
- const containerRuntimeFactory = new MockContainerRuntimeFactory();
298
- const dataStoreRuntime = new MockFluidDataStoreRuntime();
299
- const containerRuntime = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime);
300
- const services = MockSharedObjectServices.createFromSummary(directory1.getAttachSummary().summary);
301
- services.deltaConnection = dataStoreRuntime.createDeltaConnection();
302
- const directory2 = new SharedDirectory("map2", dataStoreRuntime, DirectoryFactory.Attributes);
303
- await directory2.load(services);
304
- assertDirectoryIterationOrder(directory2, ["c", "b", "a"]);
305
- });
306
- it("can be compatible with the detached scenario", async () => {
307
- // It is to reproduce the regression bug causing the corruption of the summarization, indicated by 0x85c
308
- // https://dev.azure.com/fluidframework/internal/_workitems/edit/7013
309
- const runtimeFactory = new MockContainerRuntimeFactory();
310
- const dataStoreRuntime = new MockFluidDataStoreRuntime();
311
- runtimeFactory.createContainerRuntime(dataStoreRuntime);
312
- const factory = SharedDirectory.getFactory();
313
- const summaryContent = '{"blobs":[],"content":{"ci":{"csn":0,"ccIds":[]},"subdirectories":{"detached1":{"ci":{"csn":0,"ccIds":["97cd0b77-34b1-46a8-bbe2-5fbefb3e014b"]}},"detached2":{"ci":{"csn":0,"ccIds":["97cd0b77-34b1-46a8-bbe2-5fbefb3e014b"]}},"detached3":{"ci":{"csn":-1,"ccIds":["97cd0b77-34b1-46a8-bbe2-5fbefb3e014b"]}}}}}';
314
- const summary = {
315
- type: 1,
316
- tree: {
317
- header: {
318
- type: 2,
319
- content: summaryContent,
320
- },
321
- },
322
- };
323
- const directory = await factory.load(dataStoreRuntime, "A", {
324
- deltaConnection: dataStoreRuntime.createDeltaConnection(),
325
- objectStorage: MockStorage.createFromSummary(summary),
326
- }, factory.attributes);
327
- await directory.summarize();
328
- });
329
- });
330
- describe("Reconnection", () => {
331
- let containerRuntimeFactory;
332
- let containerRuntime1;
333
- let containerRuntime2;
334
- let directory1;
335
- let directory2;
336
- beforeEach("createDirectories", async () => {
337
- containerRuntimeFactory = new MockContainerRuntimeFactoryForReconnection();
338
- // Create the first SharedDirectory
339
- const dataStoreRuntime1 = new MockFluidDataStoreRuntime();
340
- containerRuntime1 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime1);
341
- const services1 = {
342
- deltaConnection: dataStoreRuntime1.createDeltaConnection(),
343
- objectStorage: new MockStorage(),
344
- };
345
- directory1 = new SharedDirectory("dir1", dataStoreRuntime1, DirectoryFactory.Attributes);
346
- directory1.connect(services1);
347
- // Create the second SharedDirectory
348
- const dataStoreRuntime2 = new MockFluidDataStoreRuntime();
349
- containerRuntime2 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime2);
350
- const services2 = {
351
- deltaConnection: dataStoreRuntime2.createDeltaConnection(),
352
- objectStorage: new MockStorage(),
353
- };
354
- directory2 = new SharedDirectory("dir1", dataStoreRuntime2, DirectoryFactory.Attributes);
355
- directory2.connect(services2);
356
- });
357
- it("Can resend unacked ops on reconnection and impact the order", async () => {
358
- directory1.createSubDirectory("a");
359
- directory1.createSubDirectory("b");
360
- directory2.createSubDirectory("c");
361
- directory2.createSubDirectory("b");
362
- // Disconnect and reconnect the first client
363
- containerRuntime1.connected = false;
364
- containerRuntime1.connected = true;
365
- containerRuntimeFactory.processAllMessages();
366
- assertDirectoryIterationOrder(directory1, ["c", "b", "a"]);
367
- assertDirectoryIterationOrder(directory2, ["c", "b", "a"]);
368
- });
369
- it("can maintain order when a client disconnects in the meanwhile", async () => {
370
- directory1.createSubDirectory("c");
371
- containerRuntimeFactory.processAllMessages();
372
- // Disconnect the first client
373
- containerRuntime1.connected = false;
374
- directory1.createSubDirectory("a");
375
- directory2.createSubDirectory("d");
376
- directory2.createSubDirectory("b");
377
- // Reconnect the first client.
378
- containerRuntime1.connected = true;
379
- assertDirectoryIterationOrder(directory1, ["c", "a"]);
380
- assertDirectoryIterationOrder(directory2, ["c", "d", "b"]);
381
- containerRuntimeFactory.processAllMessages();
382
- assertDirectoryIterationOrder(directory1, ["c", "d", "b", "a"]);
383
- assertDirectoryIterationOrder(directory2, ["c", "d", "b", "a"]);
384
- });
385
- });
386
- describe("Op Processing", () => {
387
- let directory;
388
- beforeEach("createDirectory", async () => {
389
- const dataStoreRuntime = new MockFluidDataStoreRuntime();
390
- directory = new TestSharedDirectory("dir1", dataStoreRuntime, DirectoryFactory.Attributes);
391
- });
392
- it("applyStashedOp", async () => {
393
- const op1 = {
394
- type: "createSubDirectory",
395
- path: "./",
396
- subdirName: "c",
397
- };
398
- const op2 = {
399
- type: "createSubDirectory",
400
- path: "./",
401
- subdirName: "b",
402
- };
403
- const op3 = {
404
- type: "createSubDirectory",
405
- path: "./",
406
- subdirName: "a",
407
- };
408
- const op4 = {
409
- type: "deleteSubDirectory",
410
- path: "./",
411
- subdirName: "b",
412
- };
413
- directory.testApplyStashedOp(op1);
414
- directory.testApplyStashedOp(op2);
415
- directory.testApplyStashedOp(op3);
416
- assertDirectoryIterationOrder(directory, ["c", "b", "a"]);
417
- directory.testApplyStashedOp(op4);
418
- assertDirectoryIterationOrder(directory, ["c", "a"]);
419
- });
420
- });
421
- });
422
- //# sourceMappingURL=directory.order.spec.js.map