@fluidframework/container-loader 2.0.0-dev-rc.2.0.0.246488 → 2.0.0-dev-rc.3.0.0.250606

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 (177) hide show
  1. package/dist/attachment.d.ts +5 -8
  2. package/dist/attachment.d.ts.map +1 -1
  3. package/dist/attachment.js.map +1 -1
  4. package/dist/audience.d.ts.map +1 -1
  5. package/dist/audience.js.map +1 -1
  6. package/dist/catchUpMonitor.d.ts +1 -1
  7. package/dist/catchUpMonitor.d.ts.map +1 -1
  8. package/dist/catchUpMonitor.js.map +1 -1
  9. package/dist/connectionManager.d.ts +3 -3
  10. package/dist/connectionManager.d.ts.map +1 -1
  11. package/dist/connectionManager.js +1 -1
  12. package/dist/connectionManager.js.map +1 -1
  13. package/dist/connectionStateHandler.d.ts +3 -3
  14. package/dist/connectionStateHandler.d.ts.map +1 -1
  15. package/dist/connectionStateHandler.js.map +1 -1
  16. package/dist/container.d.ts +4 -43
  17. package/dist/container.d.ts.map +1 -1
  18. package/dist/container.js +24 -37
  19. package/dist/container.js.map +1 -1
  20. package/dist/containerContext.d.ts +17 -7
  21. package/dist/containerContext.d.ts.map +1 -1
  22. package/dist/containerContext.js +7 -2
  23. package/dist/containerContext.js.map +1 -1
  24. package/dist/containerStorageAdapter.d.ts +2 -2
  25. package/dist/containerStorageAdapter.d.ts.map +1 -1
  26. package/dist/containerStorageAdapter.js.map +1 -1
  27. package/dist/contracts.d.ts +3 -3
  28. package/dist/contracts.d.ts.map +1 -1
  29. package/dist/contracts.js.map +1 -1
  30. package/dist/debugLogger.d.ts.map +1 -1
  31. package/dist/debugLogger.js.map +1 -1
  32. package/dist/deltaManager.d.ts +5 -5
  33. package/dist/deltaManager.d.ts.map +1 -1
  34. package/dist/deltaManager.js +3 -3
  35. package/dist/deltaManager.js.map +1 -1
  36. package/dist/deltaQueue.d.ts +1 -1
  37. package/dist/deltaQueue.d.ts.map +1 -1
  38. package/dist/deltaQueue.js +1 -1
  39. package/dist/deltaQueue.js.map +1 -1
  40. package/dist/error.d.ts.map +1 -1
  41. package/dist/error.js.map +1 -1
  42. package/dist/loader.d.ts +3 -3
  43. package/dist/loader.d.ts.map +1 -1
  44. package/dist/loader.js +4 -4
  45. package/dist/loader.js.map +1 -1
  46. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts +1 -1
  47. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
  48. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  49. package/dist/noopHeuristic.d.ts +1 -1
  50. package/dist/noopHeuristic.d.ts.map +1 -1
  51. package/dist/noopHeuristic.js.map +1 -1
  52. package/dist/packageVersion.d.ts +1 -1
  53. package/dist/packageVersion.js +1 -1
  54. package/dist/packageVersion.js.map +1 -1
  55. package/dist/quorum.d.ts +1 -1
  56. package/dist/quorum.d.ts.map +1 -1
  57. package/dist/quorum.js.map +1 -1
  58. package/dist/retriableDocumentStorageService.d.ts +1 -1
  59. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  60. package/dist/retriableDocumentStorageService.js +1 -1
  61. package/dist/retriableDocumentStorageService.js.map +1 -1
  62. package/dist/serializedStateManager.d.ts +57 -18
  63. package/dist/serializedStateManager.d.ts.map +1 -1
  64. package/dist/serializedStateManager.js +71 -80
  65. package/dist/serializedStateManager.js.map +1 -1
  66. package/dist/utils.d.ts +5 -6
  67. package/dist/utils.d.ts.map +1 -1
  68. package/dist/utils.js +27 -11
  69. package/dist/utils.js.map +1 -1
  70. package/lib/attachment.d.ts +5 -8
  71. package/lib/attachment.d.ts.map +1 -1
  72. package/lib/attachment.js.map +1 -1
  73. package/lib/audience.d.ts.map +1 -1
  74. package/lib/audience.js.map +1 -1
  75. package/lib/catchUpMonitor.d.ts +1 -1
  76. package/lib/catchUpMonitor.d.ts.map +1 -1
  77. package/lib/catchUpMonitor.js.map +1 -1
  78. package/lib/connectionManager.d.ts +3 -3
  79. package/lib/connectionManager.d.ts.map +1 -1
  80. package/lib/connectionManager.js +3 -3
  81. package/lib/connectionManager.js.map +1 -1
  82. package/lib/connectionStateHandler.d.ts +3 -3
  83. package/lib/connectionStateHandler.d.ts.map +1 -1
  84. package/lib/connectionStateHandler.js.map +1 -1
  85. package/lib/container.d.ts +4 -43
  86. package/lib/container.d.ts.map +1 -1
  87. package/lib/container.js +27 -40
  88. package/lib/container.js.map +1 -1
  89. package/lib/containerContext.d.ts +17 -7
  90. package/lib/containerContext.d.ts.map +1 -1
  91. package/lib/containerContext.js +7 -2
  92. package/lib/containerContext.js.map +1 -1
  93. package/lib/containerStorageAdapter.d.ts +2 -2
  94. package/lib/containerStorageAdapter.d.ts.map +1 -1
  95. package/lib/containerStorageAdapter.js.map +1 -1
  96. package/lib/contracts.d.ts +3 -3
  97. package/lib/contracts.d.ts.map +1 -1
  98. package/lib/contracts.js.map +1 -1
  99. package/lib/debugLogger.d.ts.map +1 -1
  100. package/lib/debugLogger.js.map +1 -1
  101. package/lib/deltaManager.d.ts +5 -5
  102. package/lib/deltaManager.d.ts.map +1 -1
  103. package/lib/deltaManager.js +3 -3
  104. package/lib/deltaManager.js.map +1 -1
  105. package/lib/deltaQueue.d.ts +1 -1
  106. package/lib/deltaQueue.d.ts.map +1 -1
  107. package/lib/deltaQueue.js +1 -1
  108. package/lib/deltaQueue.js.map +1 -1
  109. package/lib/error.d.ts.map +1 -1
  110. package/lib/error.js.map +1 -1
  111. package/lib/loader.d.ts +3 -3
  112. package/lib/loader.d.ts.map +1 -1
  113. package/lib/loader.js +4 -4
  114. package/lib/loader.js.map +1 -1
  115. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts +1 -1
  116. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
  117. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  118. package/lib/noopHeuristic.d.ts +1 -1
  119. package/lib/noopHeuristic.d.ts.map +1 -1
  120. package/lib/noopHeuristic.js.map +1 -1
  121. package/lib/packageVersion.d.ts +1 -1
  122. package/lib/packageVersion.js +1 -1
  123. package/lib/packageVersion.js.map +1 -1
  124. package/lib/quorum.d.ts +1 -1
  125. package/lib/quorum.d.ts.map +1 -1
  126. package/lib/quorum.js.map +1 -1
  127. package/lib/retriableDocumentStorageService.d.ts +1 -1
  128. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  129. package/lib/retriableDocumentStorageService.js +1 -1
  130. package/lib/retriableDocumentStorageService.js.map +1 -1
  131. package/lib/serializedStateManager.d.ts +57 -18
  132. package/lib/serializedStateManager.d.ts.map +1 -1
  133. package/lib/serializedStateManager.js +68 -79
  134. package/lib/serializedStateManager.js.map +1 -1
  135. package/lib/test/attachment.spec.js +2 -2
  136. package/lib/test/attachment.spec.js.map +1 -1
  137. package/lib/test/catchUpMonitor.spec.js.map +1 -1
  138. package/lib/test/connectionStateHandler.spec.js +1 -1
  139. package/lib/test/connectionStateHandler.spec.js.map +1 -1
  140. package/lib/test/container.spec.js +1 -1
  141. package/lib/test/container.spec.js.map +1 -1
  142. package/lib/test/deltaManager.spec.js +2 -2
  143. package/lib/test/deltaManager.spec.js.map +1 -1
  144. package/lib/test/loader.spec.js +4 -4
  145. package/lib/test/loader.spec.js.map +1 -1
  146. package/lib/test/serializedStateManager.spec.js +10 -7
  147. package/lib/test/serializedStateManager.spec.js.map +1 -1
  148. package/lib/test/snapshotConversionTest.spec.js +12 -12
  149. package/lib/test/snapshotConversionTest.spec.js.map +1 -1
  150. package/lib/test/utils.spec.js +66 -1
  151. package/lib/test/utils.spec.js.map +1 -1
  152. package/lib/utils.d.ts +5 -6
  153. package/lib/utils.d.ts.map +1 -1
  154. package/lib/utils.js +26 -11
  155. package/lib/utils.js.map +1 -1
  156. package/package.json +18 -15
  157. package/src/attachment.ts +6 -6
  158. package/src/audience.ts +1 -1
  159. package/src/catchUpMonitor.ts +1 -1
  160. package/src/connectionManager.ts +15 -15
  161. package/src/connectionStateHandler.ts +4 -4
  162. package/src/container.ts +68 -125
  163. package/src/containerContext.ts +16 -9
  164. package/src/containerStorageAdapter.ts +3 -3
  165. package/src/contracts.ts +4 -4
  166. package/src/debugLogger.ts +1 -1
  167. package/src/deltaManager.ts +24 -24
  168. package/src/deltaQueue.ts +1 -1
  169. package/src/error.ts +1 -1
  170. package/src/loader.ts +22 -21
  171. package/src/location-redirection-utilities/resolveWithLocationRedirection.ts +1 -1
  172. package/src/noopHeuristic.ts +2 -2
  173. package/src/packageVersion.ts +1 -1
  174. package/src/quorum.ts +1 -1
  175. package/src/retriableDocumentStorageService.ts +2 -2
  176. package/src/serializedStateManager.ts +133 -116
  177. package/src/utils.ts +47 -18
@@ -1 +1 @@
1
- {"version":3,"file":"deltaManager.spec.js","sourceRoot":"","sources":["../../src/test/deltaManager.spec.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 { strict as assert } from \"assert\";\nimport { EventEmitter } from \"@fluid-internal/client-utils\";\nimport { MockDocumentDeltaConnection, MockDocumentService } from \"@fluid-private/test-loader-utils\";\nimport {\n\tITelemetryLoggerExt,\n\tcreateChildLogger,\n\tMockLogger,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n\tIClient,\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n\tMessageType,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDocumentDeltaStorageService } from \"@fluidframework/driver-definitions\";\nimport { SinonFakeTimers, useFakeTimers } from \"sinon\";\nimport { DeltaManager } from \"../deltaManager.js\";\nimport { NoopHeuristic } from \"../noopHeuristic.js\";\nimport { IConnectionManagerFactoryArgs } from \"../contracts.js\";\nimport { ConnectionManager } from \"../connectionManager.js\";\n\ndescribe(\"Loader\", () => {\n\tdescribe(\"Container Loader\", () => {\n\t\tdescribe(\"Delta Manager\", () => {\n\t\t\tlet clock: SinonFakeTimers;\n\t\t\tlet deltaManager: DeltaManager<ConnectionManager>;\n\t\t\tlet logger: ITelemetryLoggerExt;\n\t\t\tlet deltaConnection: MockDocumentDeltaConnection;\n\t\t\tlet clientSeqNumber = 0;\n\t\t\tlet emitter: EventEmitter;\n\t\t\tlet seq: number;\n\t\t\tlet expectedError: any;\n\t\t\tconst docId = \"docId\";\n\t\t\tconst submitEvent = \"test-submit\";\n\t\t\tconst expectedTimeout = 2000;\n\t\t\tconst noopCountFrequency = 300;\n\t\t\t// Stash the real setTimeout because sinon fake timers will hijack it.\n\t\t\tconst realSetTimeout = setTimeout;\n\n\t\t\tasync function startDeltaManager(\n\t\t\t\treconnectAllowed = true,\n\t\t\t\tdmLogger: ITelemetryLoggerExt = logger,\n\t\t\t\tdeltaStorageFactory?: () => IDocumentDeltaStorageService,\n\t\t\t) {\n\t\t\t\tconst service = new MockDocumentService(deltaStorageFactory, () => {\n\t\t\t\t\t// Always create new connection, as reusing old closed connection\n\t\t\t\t\t// Forces DM into infinite reconnection loop.\n\t\t\t\t\tdeltaConnection = new MockDocumentDeltaConnection(\"test\", (messages) =>\n\t\t\t\t\t\temitter.emit(submitEvent, messages),\n\t\t\t\t\t);\n\t\t\t\t\treturn deltaConnection;\n\t\t\t\t});\n\t\t\t\tconst client: Partial<IClient> = {\n\t\t\t\t\tmode: \"write\",\n\t\t\t\t\tdetails: { capabilities: { interactive: true } },\n\t\t\t\t};\n\n\t\t\t\tdeltaManager = new DeltaManager<ConnectionManager>(\n\t\t\t\t\t() => service,\n\t\t\t\t\tdmLogger,\n\t\t\t\t\t() => false,\n\t\t\t\t\t(props: IConnectionManagerFactoryArgs) =>\n\t\t\t\t\t\tnew ConnectionManager(\n\t\t\t\t\t\t\t() => service,\n\t\t\t\t\t\t\t() => false,\n\t\t\t\t\t\t\tclient as IClient,\n\t\t\t\t\t\t\treconnectAllowed,\n\t\t\t\t\t\t\tdmLogger,\n\t\t\t\t\t\t\tprops,\n\t\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\t\tconst noopHeuristic = new NoopHeuristic(expectedTimeout, noopCountFrequency);\n\n\t\t\t\tnoopHeuristic.on(\"wantsNoop\", () => {\n\t\t\t\t\tdeltaManager.submit(MessageType.NoOp);\n\t\t\t\t\tnoopHeuristic.notifyMessageSent();\n\t\t\t\t});\n\n\t\t\t\tawait deltaManager.attachOpHandler(0, 0, {\n\t\t\t\t\tprocess: (message) => noopHeuristic.notifyMessageProcessed(message),\n\t\t\t\t\tprocessSignal() {},\n\t\t\t\t});\n\n\t\t\t\tawait new Promise((resolve) => {\n\t\t\t\t\tdeltaManager.on(\"connect\", resolve);\n\t\t\t\t\tdeltaManager.connect({ reason: { text: \"test\" } });\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// function to yield control in the Javascript event loop.\n\t\t\tasync function yieldEventLoop(): Promise<void> {\n\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\trealSetTimeout(resolve, 0);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction generateOp(\n\t\t\t\ttype: MessageType = MessageType.Operation,\n\t\t\t): ISequencedDocumentMessage {\n\t\t\t\treturn {\n\t\t\t\t\tclientId: \"Some client ID\",\n\t\t\t\t\tclientSequenceNumber: ++clientSeqNumber,\n\t\t\t\t\tminimumSequenceNumber: 0,\n\t\t\t\t\tsequenceNumber: seq++,\n\t\t\t\t\ttype,\n\t\t\t\t} as any as ISequencedDocumentMessage;\n\t\t\t}\n\n\t\t\tasync function sendAndReceiveOps(count: number, type: MessageType) {\n\t\t\t\tfor (let num = 0; num < count; ++num) {\n\t\t\t\t\tassert(!deltaConnection.disposed, \"disposed\");\n\t\t\t\t\tdeltaManager.submit(type);\n\t\t\t\t\tdeltaConnection.emitOp(docId, [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tclientId: \"test\",\n\t\t\t\t\t\t\tclientSequenceNumber: ++clientSeqNumber,\n\t\t\t\t\t\t\tminimumSequenceNumber: 0,\n\t\t\t\t\t\t\tsequenceNumber: seq++,\n\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t} as any as ISequencedDocumentMessage,\n\t\t\t\t\t]);\n\t\t\t\t}\n\n\t\t\t\t// Yield the event loop because the inbound op will be processed asynchronously.\n\t\t\t\tawait yieldEventLoop();\n\t\t\t}\n\n\t\t\tasync function emitSequentialOps(count: number) {\n\t\t\t\tfor (let num = 0; num < count; ++num) {\n\t\t\t\t\tassert(!deltaConnection.disposed, \"disposed\");\n\t\t\t\t\tdeltaConnection.emitOp(docId, [generateOp()]);\n\t\t\t\t}\n\n\t\t\t\t// Yield the event loop because the inbound op will be processed asynchronously.\n\t\t\t\tawait yieldEventLoop();\n\t\t\t}\n\n\t\t\tasync function tickClock(tickValue: number) {\n\t\t\t\tclock.tick(tickValue);\n\n\t\t\t\t// Yield the event loop because the outbound op will be processed asynchronously.\n\t\t\t\tawait yieldEventLoop();\n\t\t\t}\n\n\t\t\tconst flushPromises = async () => new Promise((resolve) => process.nextTick(resolve));\n\n\t\t\tbefore(() => {\n\t\t\t\tclock = useFakeTimers();\n\t\t\t});\n\n\t\t\tbeforeEach(async () => {\n\t\t\t\tseq = 1;\n\t\t\t\tlogger = createChildLogger({ namespace: \"fluid:testDeltaManager\" });\n\t\t\t\temitter = new EventEmitter();\n\n\t\t\t\tclientSeqNumber = 0;\n\t\t\t\texpectedError = undefined;\n\t\t\t});\n\n\t\t\tafterEach(() => {\n\t\t\t\tclock.reset();\n\t\t\t});\n\n\t\t\tafter(() => {\n\t\t\t\tclock.restore();\n\t\t\t});\n\n\t\t\tdescribe(\"Update Minimum Sequence Number\", () => {\n\t\t\t\t// helper function asserting that there is exactly one well-formed no-op\n\t\t\t\tfunction assertOneValidNoOp(messages: IDocumentMessage[]) {\n\t\t\t\t\tassert.strictEqual(1, messages.length);\n\t\t\t\t\tassert.strictEqual(MessageType.NoOp, messages[0].type);\n\t\t\t\t\tassert.strictEqual(undefined, messages[0].contents);\n\t\t\t\t}\n\n\t\t\t\tit(\"Infinite frequency parameters disables periodic noops completely\", async () => {\n\t\t\t\t\tconst noopHeuristic = new NoopHeuristic(Infinity, Infinity);\n\n\t\t\t\t\tnoopHeuristic.on(\"wantsNoop\", () => {\n\t\t\t\t\t\tassert.fail(\"Heuristic shouldn't request noops with Infinite thresholds\");\n\t\t\t\t\t});\n\n\t\t\t\t\tfor (let num = 0; num < 1000; ++num) {\n\t\t\t\t\t\tnoopHeuristic.notifyMessageProcessed(generateOp());\n\t\t\t\t\t}\n\n\t\t\t\t\tawait tickClock(1000 * 1000);\n\t\t\t\t});\n\n\t\t\t\tit(\"Infinite time frequency will not generate noops at time intervals\", async () => {\n\t\t\t\t\tlet counter = 0;\n\t\t\t\t\tconst noopHeuristic = new NoopHeuristic(Infinity, 100);\n\t\t\t\t\tnoopHeuristic.on(\"wantsNoop\", () => {\n\t\t\t\t\t\tcounter++;\n\t\t\t\t\t\tnoopHeuristic.notifyMessageSent();\n\t\t\t\t\t});\n\t\t\t\t\tfor (let num = 0; num < 99; ++num) {\n\t\t\t\t\t\tnoopHeuristic.notifyMessageProcessed(generateOp());\n\t\t\t\t\t}\n\t\t\t\t\tawait tickClock(1000 * 1000);\n\t\t\t\t\tassert.equal(counter, 0, \"No noops requested after 99 ops\");\n\t\t\t\t\tnoopHeuristic.notifyMessageProcessed(generateOp());\n\t\t\t\t\tawait tickClock(1);\n\t\t\t\t\tassert.equal(counter, 1, \"One noop should be requested\");\n\t\t\t\t});\n\n\t\t\t\tit(\"Infinite op frequency will not generate noops at op intervals\", async () => {\n\t\t\t\t\tlet counter = 0;\n\t\t\t\t\tconst noopHeuristic = new NoopHeuristic(100, Infinity);\n\t\t\t\t\tnoopHeuristic.on(\"wantsNoop\", () => {\n\t\t\t\t\t\tcounter++;\n\t\t\t\t\t\tnoopHeuristic.notifyMessageSent();\n\t\t\t\t\t});\n\t\t\t\t\tfor (let num = 0; num < 1000; ++num) {\n\t\t\t\t\t\tnoopHeuristic.notifyMessageProcessed(generateOp());\n\t\t\t\t\t}\n\t\t\t\t\tassert.equal(counter, 0, \"No noops requested after 99 ops\");\n\t\t\t\t\tawait tickClock(100);\n\t\t\t\t\tassert.equal(counter, 1, \"One noop should be requested\");\n\t\t\t\t});\n\n\t\t\t\tit(\"1k op frequency will generate noop at op intervals\", async () => {\n\t\t\t\t\tlet counter = 0;\n\t\t\t\t\tconst noopHeuristic = new NoopHeuristic(Infinity, 1000);\n\t\t\t\t\tnoopHeuristic.on(\"wantsNoop\", () => {\n\t\t\t\t\t\tcounter++;\n\t\t\t\t\t\tnoopHeuristic.notifyMessageSent();\n\t\t\t\t\t});\n\t\t\t\t\tfor (let num = 0; num < 1000; ++num) {\n\t\t\t\t\t\tnoopHeuristic.notifyMessageProcessed(generateOp());\n\t\t\t\t\t}\n\t\t\t\t\tassert.equal(counter, 0, \"No noops requested after 999 ops\");\n\t\t\t\t\tawait tickClock(1);\n\t\t\t\t\tassert.equal(counter, 1, \"One noop should be requested\");\n\t\t\t\t});\n\n\t\t\t\tit(\"Should update after op count threshold\", async () => {\n\t\t\t\t\tlet runCount = 0;\n\t\t\t\t\tawait startDeltaManager();\n\t\t\t\t\temitter.on(submitEvent, (messages: IDocumentMessage[]) => {\n\t\t\t\t\t\tassertOneValidNoOp(messages);\n\t\t\t\t\t\trunCount++;\n\t\t\t\t\t});\n\n\t\t\t\t\tawait emitSequentialOps(noopCountFrequency - 1);\n\t\t\t\t\tawait tickClock(expectedTimeout - 1);\n\t\t\t\t\tassert.strictEqual(runCount, 0);\n\n\t\t\t\t\tawait emitSequentialOps(1);\n\t\t\t\t\tassert.strictEqual(runCount, 1);\n\n\t\t\t\t\tawait emitSequentialOps(noopCountFrequency - 1);\n\t\t\t\t\tawait tickClock(expectedTimeout - 1);\n\t\t\t\t\tassert.strictEqual(runCount, 1);\n\t\t\t\t});\n\n\t\t\t\tit(\"Should update after time threshold reached\", async () => {\n\t\t\t\t\tlet runCount = 0;\n\n\t\t\t\t\tawait startDeltaManager();\n\t\t\t\t\temitter.on(submitEvent, (messages: IDocumentMessage[]) => {\n\t\t\t\t\t\tassertOneValidNoOp(messages);\n\t\t\t\t\t\trunCount++;\n\t\t\t\t\t});\n\n\t\t\t\t\tawait emitSequentialOps(noopCountFrequency - 1);\n\t\t\t\t\tawait tickClock(expectedTimeout - 1);\n\t\t\t\t\tassert.strictEqual(runCount, 0);\n\n\t\t\t\t\t// should run after timeout\n\t\t\t\t\tawait tickClock(1);\n\t\t\t\t\tassert.strictEqual(runCount, 1);\n\n\t\t\t\t\t// Now timeout again should not cause noop\n\t\t\t\t\tawait tickClock(expectedTimeout);\n\t\t\t\t\tawait emitSequentialOps(noopCountFrequency - 1);\n\t\t\t\t\tassert.strictEqual(runCount, 1);\n\t\t\t\t});\n\n\t\t\t\tit(\"Should not update when receiving just no-ops even after timeout\", async () => {\n\t\t\t\t\tawait startDeltaManager();\n\t\t\t\t\temitter.on(submitEvent, (messages: IDocumentMessage[]) => {\n\t\t\t\t\t\tassertOneValidNoOp(messages);\n\t\t\t\t\t\tassert.fail(\"Should not send no-op.\");\n\t\t\t\t\t});\n\n\t\t\t\t\tawait emitSequentialOps(noopCountFrequency + 1);\n\t\t\t\t\tawait tickClock(expectedTimeout);\n\t\t\t\t});\n\n\t\t\t\tit(\"Should not update if op submitted during timeout\", async () => {\n\t\t\t\t\tconst ignoreContent = \"ignoreThisMessage\";\n\t\t\t\t\tlet canIgnore = true;\n\t\t\t\t\tawait startDeltaManager();\n\n\t\t\t\t\temitter.on(submitEvent, (messages: IDocumentMessage[]) => {\n\t\t\t\t\t\t// we can ignore our own op\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tmessages.length === 1 &&\n\t\t\t\t\t\t\tmessages[0].type === MessageType.Operation &&\n\t\t\t\t\t\t\tmessages[0].contents !== undefined &&\n\t\t\t\t\t\t\tJSON.parse(messages[0].contents as string) === ignoreContent &&\n\t\t\t\t\t\t\tcanIgnore\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tcanIgnore = false;\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tassert.fail(\"Should not send no-op.\");\n\t\t\t\t\t});\n\n\t\t\t\t\tawait emitSequentialOps(1);\n\t\t\t\t\tawait tickClock(expectedTimeout - 1);\n\t\t\t\t\tdeltaManager.submit(MessageType.Operation, ignoreContent);\n\t\t\t\t\tawait tickClock(1);\n\n\t\t\t\t\t// make extra sure\n\t\t\t\t\tawait tickClock(expectedTimeout);\n\t\t\t\t});\n\n\t\t\t\tit(\"Should throw error with gap in client seq num\", async () => {\n\t\t\t\t\tawait startDeltaManager();\n\n\t\t\t\t\tdeltaManager.inbound.on(\"error\", (error) => {\n\t\t\t\t\t\texpectedError = error;\n\t\t\t\t\t});\n\n\t\t\t\t\tawait sendAndReceiveOps(1, MessageType.Operation);\n\n\t\t\t\t\t// send op with gap in clientSeqNum\n\t\t\t\t\tdeltaConnection.emitOp(docId, [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tclientId: \"test\",\n\t\t\t\t\t\t\tclientSequenceNumber: clientSeqNumber + 2,\n\t\t\t\t\t\t\tminimumSequenceNumber: 0,\n\t\t\t\t\t\t\tsequenceNumber: seq++,\n\t\t\t\t\t\t\ttype: MessageType.Operation,\n\t\t\t\t\t\t} as any as ISequencedDocumentMessage,\n\t\t\t\t\t]);\n\n\t\t\t\t\tawait yieldEventLoop();\n\t\t\t\t\tassert.strictEqual(expectedError.message, \"gap in client sequence number: 1\");\n\t\t\t\t});\n\n\t\t\t\tit(\"Should pass with one noop sent, 0 received and one gap\", async () => {\n\t\t\t\t\tawait startDeltaManager();\n\n\t\t\t\t\tdeltaManager.inbound.on(\"error\", (error) => {\n\t\t\t\t\t\texpectedError = error;\n\t\t\t\t\t});\n\n\t\t\t\t\tawait sendAndReceiveOps(1, MessageType.Operation);\n\n\t\t\t\t\t// send 1 noop without receiving\n\t\t\t\t\tdeltaManager.submit(MessageType.NoOp);\n\n\t\t\t\t\t// send op with gap in clientSeqNum\n\t\t\t\t\tdeltaManager.submit(MessageType.Operation);\n\t\t\t\t\tdeltaConnection.emitOp(docId, [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tclientId: \"test\",\n\t\t\t\t\t\t\tclientSequenceNumber: clientSeqNumber + 2,\n\t\t\t\t\t\t\tminimumSequenceNumber: 0,\n\t\t\t\t\t\t\tsequenceNumber: seq,\n\t\t\t\t\t\t\ttype: MessageType.Operation,\n\t\t\t\t\t\t} as any as ISequencedDocumentMessage,\n\t\t\t\t\t]);\n\n\t\t\t\t\tawait yieldEventLoop();\n\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\tdeltaManager.lastMessage?.sequenceNumber,\n\t\t\t\t\t\tseq,\n\t\t\t\t\t\t\"discrepancy in last processed seqNum\",\n\t\t\t\t\t);\n\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\texpectedError,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t`Error should not happen : ${expectedError}`,\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t\tit(\"Should throw error with one noop sent and received, gap = 1\", async () => {\n\t\t\t\t\tawait startDeltaManager();\n\n\t\t\t\t\tdeltaManager.inbound.on(\"error\", (error) => {\n\t\t\t\t\t\texpectedError = error;\n\t\t\t\t\t});\n\n\t\t\t\t\tawait sendAndReceiveOps(1, MessageType.Operation);\n\t\t\t\t\tawait sendAndReceiveOps(1, MessageType.NoOp);\n\n\t\t\t\t\t// send op with gap in clientSeqNum\n\t\t\t\t\tdeltaConnection.emitOp(docId, [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tclientId: \"test\",\n\t\t\t\t\t\t\tclientSequenceNumber: clientSeqNumber + 2,\n\t\t\t\t\t\t\tminimumSequenceNumber: 0,\n\t\t\t\t\t\t\tsequenceNumber: seq,\n\t\t\t\t\t\t\ttype: MessageType.Operation,\n\t\t\t\t\t\t} as any as ISequencedDocumentMessage,\n\t\t\t\t\t]);\n\n\t\t\t\t\tawait yieldEventLoop();\n\t\t\t\t\tassert.strictEqual(expectedError.message, \"gap in client sequence number: 1\");\n\t\t\t\t});\n\n\t\t\t\tit(\"Should pass with 2 noop sent, 1 received, gap = 1\", async () => {\n\t\t\t\t\tawait startDeltaManager();\n\t\t\t\t\tdeltaManager.inbound.on(\"error\", (error) => {\n\t\t\t\t\t\texpectedError = error;\n\t\t\t\t\t});\n\n\t\t\t\t\tawait sendAndReceiveOps(1, MessageType.Operation);\n\t\t\t\t\tawait sendAndReceiveOps(1, MessageType.NoOp);\n\n\t\t\t\t\t// send second noop, without receiving\n\t\t\t\t\tdeltaManager.submit(MessageType.NoOp);\n\n\t\t\t\t\t// send op with gap in clientSeqNum\n\t\t\t\t\tdeltaManager.submit(MessageType.Operation);\n\t\t\t\t\tdeltaConnection.emitOp(docId, [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tclientId: \"test\",\n\t\t\t\t\t\t\tclientSequenceNumber: clientSeqNumber + 2,\n\t\t\t\t\t\t\tminimumSequenceNumber: 0,\n\t\t\t\t\t\t\tsequenceNumber: seq,\n\t\t\t\t\t\t\ttype: MessageType.Operation,\n\t\t\t\t\t\t} as any as ISequencedDocumentMessage,\n\t\t\t\t\t]);\n\n\t\t\t\t\tawait yieldEventLoop();\n\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\tdeltaManager.lastMessage?.sequenceNumber,\n\t\t\t\t\t\tseq,\n\t\t\t\t\t\t\"discrepancy in last processed seqNum\",\n\t\t\t\t\t);\n\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\texpectedError,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t`Error should not happen : ${expectedError}`,\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tdescribe(\"Readonly API\", () => {\n\t\t\t\tit(\"Should override readonly\", async () => {\n\t\t\t\t\tawait startDeltaManager();\n\n\t\t\t\t\t// TS 5.1.6: Workaround 'TS2339: Property 'readonly' does not exist on type 'never'.'\n\t\t\t\t\t//\n\t\t\t\t\t// After observering that 'forceReadonly' has been asserted to be both true and\n\t\t\t\t\t// false, TypeScript coerces 'connectionManager' to 'never'. Wrapping the\n\t\t\t\t\t// assertion in lambda avoids this.\n\t\t\t\t\tconst assertReadonlyIs = (expected: boolean) => {\n\t\t\t\t\t\tassert.strictEqual(deltaManager.readOnlyInfo.readonly, expected);\n\t\t\t\t\t};\n\n\t\t\t\t\tassertReadonlyIs(false);\n\n\t\t\t\t\tdeltaManager.connectionManager.forceReadonly(true);\n\t\t\t\t\tassertReadonlyIs(true);\n\n\t\t\t\t\tdeltaManager.connectionManager.forceReadonly(false);\n\t\t\t\t\tassertReadonlyIs(false);\n\t\t\t\t});\n\n\t\t\t\tit(\"Should raise readonly event when container was not readonly\", async () => {\n\t\t\t\t\tawait startDeltaManager();\n\t\t\t\t\tlet runCount = 0;\n\n\t\t\t\t\tdeltaManager.on(\"readonly\", (readonly: boolean) => {\n\t\t\t\t\t\tassert.strictEqual(readonly, true);\n\t\t\t\t\t\trunCount++;\n\t\t\t\t\t});\n\n\t\t\t\t\tdeltaManager.connectionManager.forceReadonly(true);\n\t\t\t\t\tassert.strictEqual(runCount, 1);\n\t\t\t\t});\n\n\t\t\t\tit(\"Shouldn't raise readonly event when container was already readonly\", async () => {\n\t\t\t\t\tawait startDeltaManager(false /* startDeltaManager */);\n\n\t\t\t\t\t// Closing underlying connection makes container readonly\n\t\t\t\t\tdeltaConnection.dispose();\n\t\t\t\t\tassert.strictEqual(deltaManager.readOnlyInfo.readonly, true);\n\n\t\t\t\t\tdeltaManager.on(\"readonly\", () => {\n\t\t\t\t\t\tassert.fail(\"Shouldn't be called\");\n\t\t\t\t\t});\n\n\t\t\t\t\tdeltaManager.connectionManager.forceReadonly(true);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit(\"Closed abort reason should be passed fetch abort signal\", async () => {\n\t\t\t\tconst mockLogger = new MockLogger();\n\t\t\t\tawait startDeltaManager(undefined, mockLogger.toTelemetryLogger(), () => ({\n\t\t\t\t\tfetchMessages: (\n\t\t\t\t\t\t_from: number,\n\t\t\t\t\t\t_to: number | undefined,\n\t\t\t\t\t\tabortSignal?: AbortSignal,\n\t\t\t\t\t\t_cachedOnly?: boolean,\n\t\t\t\t\t) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tread: async () => {\n\t\t\t\t\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\t\t\t\t\tabortSignal!.onabort = () => {\n\t\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\tthrow new Error(abortSignal?.reason);\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\n\t\t\t\t// Dispose will trigger abort\n\t\t\t\tdeltaManager.dispose();\n\t\t\t\tawait flushPromises();\n\n\t\t\t\tmockLogger.assertMatch([\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"DeltaManager_GetDeltasAborted\",\n\t\t\t\t\t\treason: \"DeltaManager is closed\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GetDeltas_Exception\",\n\t\t\t\t\t\terror: \"DeltaManager is closed\",\n\t\t\t\t\t},\n\t\t\t\t]);\n\t\t\t});\n\t\t});\n\t});\n});\n"]}
1
+ {"version":3,"file":"deltaManager.spec.js","sourceRoot":"","sources":["../../src/test/deltaManager.spec.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 { strict as assert } from \"assert\";\nimport { EventEmitter } from \"@fluid-internal/client-utils\";\nimport { MockDocumentDeltaConnection, MockDocumentService } from \"@fluid-private/test-loader-utils\";\nimport { IDocumentDeltaStorageService } from \"@fluidframework/driver-definitions\";\nimport {\n\tIClient,\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n\tMessageType,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n\tITelemetryLoggerExt,\n\tMockLogger,\n\tcreateChildLogger,\n} from \"@fluidframework/telemetry-utils\";\nimport { SinonFakeTimers, useFakeTimers } from \"sinon\";\nimport { ConnectionManager } from \"../connectionManager.js\";\nimport { IConnectionManagerFactoryArgs } from \"../contracts.js\";\nimport { DeltaManager } from \"../deltaManager.js\";\nimport { NoopHeuristic } from \"../noopHeuristic.js\";\n\ndescribe(\"Loader\", () => {\n\tdescribe(\"Container Loader\", () => {\n\t\tdescribe(\"Delta Manager\", () => {\n\t\t\tlet clock: SinonFakeTimers;\n\t\t\tlet deltaManager: DeltaManager<ConnectionManager>;\n\t\t\tlet logger: ITelemetryLoggerExt;\n\t\t\tlet deltaConnection: MockDocumentDeltaConnection;\n\t\t\tlet clientSeqNumber = 0;\n\t\t\tlet emitter: EventEmitter;\n\t\t\tlet seq: number;\n\t\t\tlet expectedError: any;\n\t\t\tconst docId = \"docId\";\n\t\t\tconst submitEvent = \"test-submit\";\n\t\t\tconst expectedTimeout = 2000;\n\t\t\tconst noopCountFrequency = 300;\n\t\t\t// Stash the real setTimeout because sinon fake timers will hijack it.\n\t\t\tconst realSetTimeout = setTimeout;\n\n\t\t\tasync function startDeltaManager(\n\t\t\t\treconnectAllowed = true,\n\t\t\t\tdmLogger: ITelemetryLoggerExt = logger,\n\t\t\t\tdeltaStorageFactory?: () => IDocumentDeltaStorageService,\n\t\t\t) {\n\t\t\t\tconst service = new MockDocumentService(deltaStorageFactory, () => {\n\t\t\t\t\t// Always create new connection, as reusing old closed connection\n\t\t\t\t\t// Forces DM into infinite reconnection loop.\n\t\t\t\t\tdeltaConnection = new MockDocumentDeltaConnection(\"test\", (messages) =>\n\t\t\t\t\t\temitter.emit(submitEvent, messages),\n\t\t\t\t\t);\n\t\t\t\t\treturn deltaConnection;\n\t\t\t\t});\n\t\t\t\tconst client: Partial<IClient> = {\n\t\t\t\t\tmode: \"write\",\n\t\t\t\t\tdetails: { capabilities: { interactive: true } },\n\t\t\t\t};\n\n\t\t\t\tdeltaManager = new DeltaManager<ConnectionManager>(\n\t\t\t\t\t() => service,\n\t\t\t\t\tdmLogger,\n\t\t\t\t\t() => false,\n\t\t\t\t\t(props: IConnectionManagerFactoryArgs) =>\n\t\t\t\t\t\tnew ConnectionManager(\n\t\t\t\t\t\t\t() => service,\n\t\t\t\t\t\t\t() => false,\n\t\t\t\t\t\t\tclient as IClient,\n\t\t\t\t\t\t\treconnectAllowed,\n\t\t\t\t\t\t\tdmLogger,\n\t\t\t\t\t\t\tprops,\n\t\t\t\t\t\t),\n\t\t\t\t);\n\n\t\t\t\tconst noopHeuristic = new NoopHeuristic(expectedTimeout, noopCountFrequency);\n\n\t\t\t\tnoopHeuristic.on(\"wantsNoop\", () => {\n\t\t\t\t\tdeltaManager.submit(MessageType.NoOp);\n\t\t\t\t\tnoopHeuristic.notifyMessageSent();\n\t\t\t\t});\n\n\t\t\t\tawait deltaManager.attachOpHandler(0, 0, {\n\t\t\t\t\tprocess: (message) => noopHeuristic.notifyMessageProcessed(message),\n\t\t\t\t\tprocessSignal() {},\n\t\t\t\t});\n\n\t\t\t\tawait new Promise((resolve) => {\n\t\t\t\t\tdeltaManager.on(\"connect\", resolve);\n\t\t\t\t\tdeltaManager.connect({ reason: { text: \"test\" } });\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// function to yield control in the Javascript event loop.\n\t\t\tasync function yieldEventLoop(): Promise<void> {\n\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\trealSetTimeout(resolve, 0);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction generateOp(\n\t\t\t\ttype: MessageType = MessageType.Operation,\n\t\t\t): ISequencedDocumentMessage {\n\t\t\t\treturn {\n\t\t\t\t\tclientId: \"Some client ID\",\n\t\t\t\t\tclientSequenceNumber: ++clientSeqNumber,\n\t\t\t\t\tminimumSequenceNumber: 0,\n\t\t\t\t\tsequenceNumber: seq++,\n\t\t\t\t\ttype,\n\t\t\t\t} as any as ISequencedDocumentMessage;\n\t\t\t}\n\n\t\t\tasync function sendAndReceiveOps(count: number, type: MessageType) {\n\t\t\t\tfor (let num = 0; num < count; ++num) {\n\t\t\t\t\tassert(!deltaConnection.disposed, \"disposed\");\n\t\t\t\t\tdeltaManager.submit(type);\n\t\t\t\t\tdeltaConnection.emitOp(docId, [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tclientId: \"test\",\n\t\t\t\t\t\t\tclientSequenceNumber: ++clientSeqNumber,\n\t\t\t\t\t\t\tminimumSequenceNumber: 0,\n\t\t\t\t\t\t\tsequenceNumber: seq++,\n\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t} as any as ISequencedDocumentMessage,\n\t\t\t\t\t]);\n\t\t\t\t}\n\n\t\t\t\t// Yield the event loop because the inbound op will be processed asynchronously.\n\t\t\t\tawait yieldEventLoop();\n\t\t\t}\n\n\t\t\tasync function emitSequentialOps(count: number) {\n\t\t\t\tfor (let num = 0; num < count; ++num) {\n\t\t\t\t\tassert(!deltaConnection.disposed, \"disposed\");\n\t\t\t\t\tdeltaConnection.emitOp(docId, [generateOp()]);\n\t\t\t\t}\n\n\t\t\t\t// Yield the event loop because the inbound op will be processed asynchronously.\n\t\t\t\tawait yieldEventLoop();\n\t\t\t}\n\n\t\t\tasync function tickClock(tickValue: number) {\n\t\t\t\tclock.tick(tickValue);\n\n\t\t\t\t// Yield the event loop because the outbound op will be processed asynchronously.\n\t\t\t\tawait yieldEventLoop();\n\t\t\t}\n\n\t\t\tconst flushPromises = async () => new Promise((resolve) => process.nextTick(resolve));\n\n\t\t\tbefore(() => {\n\t\t\t\tclock = useFakeTimers();\n\t\t\t});\n\n\t\t\tbeforeEach(async () => {\n\t\t\t\tseq = 1;\n\t\t\t\tlogger = createChildLogger({ namespace: \"fluid:testDeltaManager\" });\n\t\t\t\temitter = new EventEmitter();\n\n\t\t\t\tclientSeqNumber = 0;\n\t\t\t\texpectedError = undefined;\n\t\t\t});\n\n\t\t\tafterEach(() => {\n\t\t\t\tclock.reset();\n\t\t\t});\n\n\t\t\tafter(() => {\n\t\t\t\tclock.restore();\n\t\t\t});\n\n\t\t\tdescribe(\"Update Minimum Sequence Number\", () => {\n\t\t\t\t// helper function asserting that there is exactly one well-formed no-op\n\t\t\t\tfunction assertOneValidNoOp(messages: IDocumentMessage[]) {\n\t\t\t\t\tassert.strictEqual(1, messages.length);\n\t\t\t\t\tassert.strictEqual(MessageType.NoOp, messages[0].type);\n\t\t\t\t\tassert.strictEqual(undefined, messages[0].contents);\n\t\t\t\t}\n\n\t\t\t\tit(\"Infinite frequency parameters disables periodic noops completely\", async () => {\n\t\t\t\t\tconst noopHeuristic = new NoopHeuristic(Infinity, Infinity);\n\n\t\t\t\t\tnoopHeuristic.on(\"wantsNoop\", () => {\n\t\t\t\t\t\tassert.fail(\"Heuristic shouldn't request noops with Infinite thresholds\");\n\t\t\t\t\t});\n\n\t\t\t\t\tfor (let num = 0; num < 1000; ++num) {\n\t\t\t\t\t\tnoopHeuristic.notifyMessageProcessed(generateOp());\n\t\t\t\t\t}\n\n\t\t\t\t\tawait tickClock(1000 * 1000);\n\t\t\t\t});\n\n\t\t\t\tit(\"Infinite time frequency will not generate noops at time intervals\", async () => {\n\t\t\t\t\tlet counter = 0;\n\t\t\t\t\tconst noopHeuristic = new NoopHeuristic(Infinity, 100);\n\t\t\t\t\tnoopHeuristic.on(\"wantsNoop\", () => {\n\t\t\t\t\t\tcounter++;\n\t\t\t\t\t\tnoopHeuristic.notifyMessageSent();\n\t\t\t\t\t});\n\t\t\t\t\tfor (let num = 0; num < 99; ++num) {\n\t\t\t\t\t\tnoopHeuristic.notifyMessageProcessed(generateOp());\n\t\t\t\t\t}\n\t\t\t\t\tawait tickClock(1000 * 1000);\n\t\t\t\t\tassert.equal(counter, 0, \"No noops requested after 99 ops\");\n\t\t\t\t\tnoopHeuristic.notifyMessageProcessed(generateOp());\n\t\t\t\t\tawait tickClock(1);\n\t\t\t\t\tassert.equal(counter, 1, \"One noop should be requested\");\n\t\t\t\t});\n\n\t\t\t\tit(\"Infinite op frequency will not generate noops at op intervals\", async () => {\n\t\t\t\t\tlet counter = 0;\n\t\t\t\t\tconst noopHeuristic = new NoopHeuristic(100, Infinity);\n\t\t\t\t\tnoopHeuristic.on(\"wantsNoop\", () => {\n\t\t\t\t\t\tcounter++;\n\t\t\t\t\t\tnoopHeuristic.notifyMessageSent();\n\t\t\t\t\t});\n\t\t\t\t\tfor (let num = 0; num < 1000; ++num) {\n\t\t\t\t\t\tnoopHeuristic.notifyMessageProcessed(generateOp());\n\t\t\t\t\t}\n\t\t\t\t\tassert.equal(counter, 0, \"No noops requested after 99 ops\");\n\t\t\t\t\tawait tickClock(100);\n\t\t\t\t\tassert.equal(counter, 1, \"One noop should be requested\");\n\t\t\t\t});\n\n\t\t\t\tit(\"1k op frequency will generate noop at op intervals\", async () => {\n\t\t\t\t\tlet counter = 0;\n\t\t\t\t\tconst noopHeuristic = new NoopHeuristic(Infinity, 1000);\n\t\t\t\t\tnoopHeuristic.on(\"wantsNoop\", () => {\n\t\t\t\t\t\tcounter++;\n\t\t\t\t\t\tnoopHeuristic.notifyMessageSent();\n\t\t\t\t\t});\n\t\t\t\t\tfor (let num = 0; num < 1000; ++num) {\n\t\t\t\t\t\tnoopHeuristic.notifyMessageProcessed(generateOp());\n\t\t\t\t\t}\n\t\t\t\t\tassert.equal(counter, 0, \"No noops requested after 999 ops\");\n\t\t\t\t\tawait tickClock(1);\n\t\t\t\t\tassert.equal(counter, 1, \"One noop should be requested\");\n\t\t\t\t});\n\n\t\t\t\tit(\"Should update after op count threshold\", async () => {\n\t\t\t\t\tlet runCount = 0;\n\t\t\t\t\tawait startDeltaManager();\n\t\t\t\t\temitter.on(submitEvent, (messages: IDocumentMessage[]) => {\n\t\t\t\t\t\tassertOneValidNoOp(messages);\n\t\t\t\t\t\trunCount++;\n\t\t\t\t\t});\n\n\t\t\t\t\tawait emitSequentialOps(noopCountFrequency - 1);\n\t\t\t\t\tawait tickClock(expectedTimeout - 1);\n\t\t\t\t\tassert.strictEqual(runCount, 0);\n\n\t\t\t\t\tawait emitSequentialOps(1);\n\t\t\t\t\tassert.strictEqual(runCount, 1);\n\n\t\t\t\t\tawait emitSequentialOps(noopCountFrequency - 1);\n\t\t\t\t\tawait tickClock(expectedTimeout - 1);\n\t\t\t\t\tassert.strictEqual(runCount, 1);\n\t\t\t\t});\n\n\t\t\t\tit(\"Should update after time threshold reached\", async () => {\n\t\t\t\t\tlet runCount = 0;\n\n\t\t\t\t\tawait startDeltaManager();\n\t\t\t\t\temitter.on(submitEvent, (messages: IDocumentMessage[]) => {\n\t\t\t\t\t\tassertOneValidNoOp(messages);\n\t\t\t\t\t\trunCount++;\n\t\t\t\t\t});\n\n\t\t\t\t\tawait emitSequentialOps(noopCountFrequency - 1);\n\t\t\t\t\tawait tickClock(expectedTimeout - 1);\n\t\t\t\t\tassert.strictEqual(runCount, 0);\n\n\t\t\t\t\t// should run after timeout\n\t\t\t\t\tawait tickClock(1);\n\t\t\t\t\tassert.strictEqual(runCount, 1);\n\n\t\t\t\t\t// Now timeout again should not cause noop\n\t\t\t\t\tawait tickClock(expectedTimeout);\n\t\t\t\t\tawait emitSequentialOps(noopCountFrequency - 1);\n\t\t\t\t\tassert.strictEqual(runCount, 1);\n\t\t\t\t});\n\n\t\t\t\tit(\"Should not update when receiving just no-ops even after timeout\", async () => {\n\t\t\t\t\tawait startDeltaManager();\n\t\t\t\t\temitter.on(submitEvent, (messages: IDocumentMessage[]) => {\n\t\t\t\t\t\tassertOneValidNoOp(messages);\n\t\t\t\t\t\tassert.fail(\"Should not send no-op.\");\n\t\t\t\t\t});\n\n\t\t\t\t\tawait emitSequentialOps(noopCountFrequency + 1);\n\t\t\t\t\tawait tickClock(expectedTimeout);\n\t\t\t\t});\n\n\t\t\t\tit(\"Should not update if op submitted during timeout\", async () => {\n\t\t\t\t\tconst ignoreContent = \"ignoreThisMessage\";\n\t\t\t\t\tlet canIgnore = true;\n\t\t\t\t\tawait startDeltaManager();\n\n\t\t\t\t\temitter.on(submitEvent, (messages: IDocumentMessage[]) => {\n\t\t\t\t\t\t// we can ignore our own op\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tmessages.length === 1 &&\n\t\t\t\t\t\t\tmessages[0].type === MessageType.Operation &&\n\t\t\t\t\t\t\tmessages[0].contents !== undefined &&\n\t\t\t\t\t\t\tJSON.parse(messages[0].contents as string) === ignoreContent &&\n\t\t\t\t\t\t\tcanIgnore\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tcanIgnore = false;\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tassert.fail(\"Should not send no-op.\");\n\t\t\t\t\t});\n\n\t\t\t\t\tawait emitSequentialOps(1);\n\t\t\t\t\tawait tickClock(expectedTimeout - 1);\n\t\t\t\t\tdeltaManager.submit(MessageType.Operation, ignoreContent);\n\t\t\t\t\tawait tickClock(1);\n\n\t\t\t\t\t// make extra sure\n\t\t\t\t\tawait tickClock(expectedTimeout);\n\t\t\t\t});\n\n\t\t\t\tit(\"Should throw error with gap in client seq num\", async () => {\n\t\t\t\t\tawait startDeltaManager();\n\n\t\t\t\t\tdeltaManager.inbound.on(\"error\", (error) => {\n\t\t\t\t\t\texpectedError = error;\n\t\t\t\t\t});\n\n\t\t\t\t\tawait sendAndReceiveOps(1, MessageType.Operation);\n\n\t\t\t\t\t// send op with gap in clientSeqNum\n\t\t\t\t\tdeltaConnection.emitOp(docId, [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tclientId: \"test\",\n\t\t\t\t\t\t\tclientSequenceNumber: clientSeqNumber + 2,\n\t\t\t\t\t\t\tminimumSequenceNumber: 0,\n\t\t\t\t\t\t\tsequenceNumber: seq++,\n\t\t\t\t\t\t\ttype: MessageType.Operation,\n\t\t\t\t\t\t} as any as ISequencedDocumentMessage,\n\t\t\t\t\t]);\n\n\t\t\t\t\tawait yieldEventLoop();\n\t\t\t\t\tassert.strictEqual(expectedError.message, \"gap in client sequence number: 1\");\n\t\t\t\t});\n\n\t\t\t\tit(\"Should pass with one noop sent, 0 received and one gap\", async () => {\n\t\t\t\t\tawait startDeltaManager();\n\n\t\t\t\t\tdeltaManager.inbound.on(\"error\", (error) => {\n\t\t\t\t\t\texpectedError = error;\n\t\t\t\t\t});\n\n\t\t\t\t\tawait sendAndReceiveOps(1, MessageType.Operation);\n\n\t\t\t\t\t// send 1 noop without receiving\n\t\t\t\t\tdeltaManager.submit(MessageType.NoOp);\n\n\t\t\t\t\t// send op with gap in clientSeqNum\n\t\t\t\t\tdeltaManager.submit(MessageType.Operation);\n\t\t\t\t\tdeltaConnection.emitOp(docId, [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tclientId: \"test\",\n\t\t\t\t\t\t\tclientSequenceNumber: clientSeqNumber + 2,\n\t\t\t\t\t\t\tminimumSequenceNumber: 0,\n\t\t\t\t\t\t\tsequenceNumber: seq,\n\t\t\t\t\t\t\ttype: MessageType.Operation,\n\t\t\t\t\t\t} as any as ISequencedDocumentMessage,\n\t\t\t\t\t]);\n\n\t\t\t\t\tawait yieldEventLoop();\n\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\tdeltaManager.lastMessage?.sequenceNumber,\n\t\t\t\t\t\tseq,\n\t\t\t\t\t\t\"discrepancy in last processed seqNum\",\n\t\t\t\t\t);\n\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\texpectedError,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t`Error should not happen : ${expectedError}`,\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t\tit(\"Should throw error with one noop sent and received, gap = 1\", async () => {\n\t\t\t\t\tawait startDeltaManager();\n\n\t\t\t\t\tdeltaManager.inbound.on(\"error\", (error) => {\n\t\t\t\t\t\texpectedError = error;\n\t\t\t\t\t});\n\n\t\t\t\t\tawait sendAndReceiveOps(1, MessageType.Operation);\n\t\t\t\t\tawait sendAndReceiveOps(1, MessageType.NoOp);\n\n\t\t\t\t\t// send op with gap in clientSeqNum\n\t\t\t\t\tdeltaConnection.emitOp(docId, [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tclientId: \"test\",\n\t\t\t\t\t\t\tclientSequenceNumber: clientSeqNumber + 2,\n\t\t\t\t\t\t\tminimumSequenceNumber: 0,\n\t\t\t\t\t\t\tsequenceNumber: seq,\n\t\t\t\t\t\t\ttype: MessageType.Operation,\n\t\t\t\t\t\t} as any as ISequencedDocumentMessage,\n\t\t\t\t\t]);\n\n\t\t\t\t\tawait yieldEventLoop();\n\t\t\t\t\tassert.strictEqual(expectedError.message, \"gap in client sequence number: 1\");\n\t\t\t\t});\n\n\t\t\t\tit(\"Should pass with 2 noop sent, 1 received, gap = 1\", async () => {\n\t\t\t\t\tawait startDeltaManager();\n\t\t\t\t\tdeltaManager.inbound.on(\"error\", (error) => {\n\t\t\t\t\t\texpectedError = error;\n\t\t\t\t\t});\n\n\t\t\t\t\tawait sendAndReceiveOps(1, MessageType.Operation);\n\t\t\t\t\tawait sendAndReceiveOps(1, MessageType.NoOp);\n\n\t\t\t\t\t// send second noop, without receiving\n\t\t\t\t\tdeltaManager.submit(MessageType.NoOp);\n\n\t\t\t\t\t// send op with gap in clientSeqNum\n\t\t\t\t\tdeltaManager.submit(MessageType.Operation);\n\t\t\t\t\tdeltaConnection.emitOp(docId, [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tclientId: \"test\",\n\t\t\t\t\t\t\tclientSequenceNumber: clientSeqNumber + 2,\n\t\t\t\t\t\t\tminimumSequenceNumber: 0,\n\t\t\t\t\t\t\tsequenceNumber: seq,\n\t\t\t\t\t\t\ttype: MessageType.Operation,\n\t\t\t\t\t\t} as any as ISequencedDocumentMessage,\n\t\t\t\t\t]);\n\n\t\t\t\t\tawait yieldEventLoop();\n\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\tdeltaManager.lastMessage?.sequenceNumber,\n\t\t\t\t\t\tseq,\n\t\t\t\t\t\t\"discrepancy in last processed seqNum\",\n\t\t\t\t\t);\n\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\texpectedError,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t`Error should not happen : ${expectedError}`,\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tdescribe(\"Readonly API\", () => {\n\t\t\t\tit(\"Should override readonly\", async () => {\n\t\t\t\t\tawait startDeltaManager();\n\n\t\t\t\t\t// TS 5.1.6: Workaround 'TS2339: Property 'readonly' does not exist on type 'never'.'\n\t\t\t\t\t//\n\t\t\t\t\t// After observering that 'forceReadonly' has been asserted to be both true and\n\t\t\t\t\t// false, TypeScript coerces 'connectionManager' to 'never'. Wrapping the\n\t\t\t\t\t// assertion in lambda avoids this.\n\t\t\t\t\tconst assertReadonlyIs = (expected: boolean) => {\n\t\t\t\t\t\tassert.strictEqual(deltaManager.readOnlyInfo.readonly, expected);\n\t\t\t\t\t};\n\n\t\t\t\t\tassertReadonlyIs(false);\n\n\t\t\t\t\tdeltaManager.connectionManager.forceReadonly(true);\n\t\t\t\t\tassertReadonlyIs(true);\n\n\t\t\t\t\tdeltaManager.connectionManager.forceReadonly(false);\n\t\t\t\t\tassertReadonlyIs(false);\n\t\t\t\t});\n\n\t\t\t\tit(\"Should raise readonly event when container was not readonly\", async () => {\n\t\t\t\t\tawait startDeltaManager();\n\t\t\t\t\tlet runCount = 0;\n\n\t\t\t\t\tdeltaManager.on(\"readonly\", (readonly: boolean) => {\n\t\t\t\t\t\tassert.strictEqual(readonly, true);\n\t\t\t\t\t\trunCount++;\n\t\t\t\t\t});\n\n\t\t\t\t\tdeltaManager.connectionManager.forceReadonly(true);\n\t\t\t\t\tassert.strictEqual(runCount, 1);\n\t\t\t\t});\n\n\t\t\t\tit(\"Shouldn't raise readonly event when container was already readonly\", async () => {\n\t\t\t\t\tawait startDeltaManager(false /* startDeltaManager */);\n\n\t\t\t\t\t// Closing underlying connection makes container readonly\n\t\t\t\t\tdeltaConnection.dispose();\n\t\t\t\t\tassert.strictEqual(deltaManager.readOnlyInfo.readonly, true);\n\n\t\t\t\t\tdeltaManager.on(\"readonly\", () => {\n\t\t\t\t\t\tassert.fail(\"Shouldn't be called\");\n\t\t\t\t\t});\n\n\t\t\t\t\tdeltaManager.connectionManager.forceReadonly(true);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit(\"Closed abort reason should be passed fetch abort signal\", async () => {\n\t\t\t\tconst mockLogger = new MockLogger();\n\t\t\t\tawait startDeltaManager(undefined, mockLogger.toTelemetryLogger(), () => ({\n\t\t\t\t\tfetchMessages: (\n\t\t\t\t\t\t_from: number,\n\t\t\t\t\t\t_to: number | undefined,\n\t\t\t\t\t\tabortSignal?: AbortSignal,\n\t\t\t\t\t\t_cachedOnly?: boolean,\n\t\t\t\t\t) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tread: async () => {\n\t\t\t\t\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\t\t\t\t\tabortSignal!.onabort = () => {\n\t\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\tthrow new Error(abortSignal?.reason);\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\n\t\t\t\t// Dispose will trigger abort\n\t\t\t\tdeltaManager.dispose();\n\t\t\t\tawait flushPromises();\n\n\t\t\t\tmockLogger.assertMatch([\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"DeltaManager_GetDeltasAborted\",\n\t\t\t\t\t\treason: \"DeltaManager is closed\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"GetDeltas_Exception\",\n\t\t\t\t\t\terror: \"DeltaManager is closed\",\n\t\t\t\t\t},\n\t\t\t\t]);\n\t\t\t});\n\t\t});\n\t});\n});\n"]}
@@ -3,12 +3,12 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import assert from "assert";
6
- import { v4 as uuid } from "uuid";
7
- import { isFluidError } from "@fluidframework/telemetry-utils";
6
+ import { stringToBuffer } from "@fluid-internal/client-utils";
7
+ import { AttachState } from "@fluidframework/container-definitions";
8
8
  import { FluidErrorTypes } from "@fluidframework/core-interfaces";
9
9
  import { SummaryType } from "@fluidframework/protocol-definitions";
10
- import { AttachState } from "@fluidframework/container-definitions";
11
- import { stringToBuffer } from "@fluid-internal/client-utils";
10
+ import { isFluidError } from "@fluidframework/telemetry-utils";
11
+ import { v4 as uuid } from "uuid";
12
12
  import { Loader } from "../loader.js";
13
13
  const failProxy = () => {
14
14
  const proxy = new Proxy({}, {
@@ -1 +1 @@
1
- {"version":3,"file":"loader.spec.js","sourceRoot":"","sources":["../../src/test/loader.spec.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 \"assert\";\nimport { v4 as uuid } from \"uuid\";\nimport { isFluidError } from \"@fluidframework/telemetry-utils\";\nimport { FluidErrorTypes } from \"@fluidframework/core-interfaces\";\nimport { ICreateBlobResponse, SummaryType } from \"@fluidframework/protocol-definitions\";\nimport { AttachState, IRuntime } from \"@fluidframework/container-definitions\";\nimport { stringToBuffer } from \"@fluid-internal/client-utils\";\nimport {\n\tIDocumentService,\n\tIDocumentServiceFactory,\n\ttype IDocumentStorageService,\n\ttype IResolvedUrl,\n\ttype IUrlResolver,\n} from \"@fluidframework/driver-definitions\";\nimport { IDetachedBlobStorage, Loader } from \"../loader.js\";\nimport { IPendingDetachedContainerState } from \"../container.js\";\n\nconst failProxy = <T extends object>() => {\n\tconst proxy = new Proxy<T>({} as any as T, {\n\t\tget: (_, p) => {\n\t\t\tif (p === \"then\") {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tthrow Error(`${p.toString()} not implemented`);\n\t\t},\n\t});\n\treturn proxy;\n};\n\nconst failSometimeProxy = <T extends object>(handler: Partial<T>) => {\n\tconst proxy = new Proxy<T>(handler as T, {\n\t\tget: (t, p, r) => {\n\t\t\tif (p === \"then\") {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (p in handler) {\n\t\t\t\treturn Reflect.get(t, p, r);\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\treturn failProxy();\n\t\t},\n\t});\n\treturn proxy;\n};\n\nconst codeLoader = {\n\tload: async () => {\n\t\treturn {\n\t\t\tdetails: {\n\t\t\t\tpackage: \"none\",\n\t\t\t},\n\t\t\tmodule: {\n\t\t\t\tfluidExport: {\n\t\t\t\t\tIRuntimeFactory: {\n\t\t\t\t\t\tget IRuntimeFactory() {\n\t\t\t\t\t\t\treturn this;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tasync instantiateRuntime(context, existing) {\n\t\t\t\t\t\t\treturn failSometimeProxy<IRuntime>({\n\t\t\t\t\t\t\t\tcreateSummary: () => ({\n\t\t\t\t\t\t\t\t\ttree: {},\n\t\t\t\t\t\t\t\t\ttype: SummaryType.Tree,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tsetAttachState: () => {},\n\t\t\t\t\t\t\t\tgetPendingLocalState: () => ({\n\t\t\t\t\t\t\t\t\tpending: [],\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\ndescribe(\"loader unit test\", () => {\n\tit(\"rehydrateDetachedContainerFromSnapshot with invalid format\", async () => {\n\t\tconst loader = new Loader({\n\t\t\tcodeLoader: failProxy(),\n\t\t\tdocumentServiceFactory: failProxy(),\n\t\t\turlResolver: failProxy(),\n\t\t});\n\n\t\ttry {\n\t\t\tawait loader.rehydrateDetachedContainerFromSnapshot(`{\"foo\":\"bar\"}`);\n\t\t\tassert.fail(\"should fail\");\n\t\t} catch (e) {\n\t\t\tassert.strict(isFluidError(e), `should be a Fluid error: ${e}`);\n\t\t\tassert.strictEqual(e.errorType, FluidErrorTypes.usageError, \"should be a usage error\");\n\t\t}\n\t});\n\n\tit(\"rehydrateDetachedContainerFromSnapshot with valid format\", async () => {\n\t\tconst loader = new Loader({\n\t\t\tcodeLoader,\n\t\t\tdocumentServiceFactory: failProxy(),\n\t\t\turlResolver: failProxy(),\n\t\t});\n\t\tconst detached = await loader.createDetachedContainer({ package: \"none\" });\n\t\tconst detachedContainerState = detached.serialize();\n\t\tconst parsedState = JSON.parse(detachedContainerState) as IPendingDetachedContainerState;\n\t\tassert.strictEqual(parsedState.attached, false);\n\t\tassert.strictEqual(parsedState.hasAttachmentBlobs, false);\n\t\tassert.strictEqual(Object.keys(parsedState.snapshotBlobs).length, 4);\n\t\tassert.ok(parsedState.baseSnapshot);\n\t\tawait loader.rehydrateDetachedContainerFromSnapshot(detachedContainerState);\n\t});\n\n\tit(\"rehydrateDetachedContainerFromSnapshot with valid format and attachment blobs\", async () => {\n\t\tconst blobs = new Map<string, ArrayBufferLike>();\n\t\tconst detachedBlobStorage: IDetachedBlobStorage = {\n\t\t\tcreateBlob: async (file) => {\n\t\t\t\tconst response: ICreateBlobResponse = {\n\t\t\t\t\tid: uuid(),\n\t\t\t\t};\n\t\t\t\tblobs.set(response.id, file);\n\t\t\t\treturn response;\n\t\t\t},\n\t\t\tgetBlobIds: () => [...blobs.keys()],\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\treadBlob: async (id) => blobs.get(id)!,\n\t\t\tget size() {\n\t\t\t\treturn blobs.size;\n\t\t\t},\n\t\t};\n\t\tconst loader = new Loader({\n\t\t\tcodeLoader,\n\t\t\tdocumentServiceFactory: failProxy(),\n\t\t\turlResolver: failProxy(),\n\t\t\tdetachedBlobStorage,\n\t\t});\n\t\tconst detached = await loader.createDetachedContainer({ package: \"none\" });\n\t\tawait detachedBlobStorage.createBlob(stringToBuffer(\"whatever\", \"utf8\"));\n\t\tconst detachedContainerState = detached.serialize();\n\t\tconst parsedState = JSON.parse(detachedContainerState) as IPendingDetachedContainerState;\n\t\tassert.strictEqual(parsedState.attached, false);\n\t\tassert.strictEqual(parsedState.hasAttachmentBlobs, true);\n\t\tassert.strictEqual(Object.keys(parsedState.snapshotBlobs).length, 4);\n\t\tassert.ok(parsedState.baseSnapshot);\n\t\tawait loader.rehydrateDetachedContainerFromSnapshot(detachedContainerState);\n\t});\n\n\tit(\"serialize and rehydrateDetachedContainerFromSnapshot while attaching\", async () => {\n\t\tconst loader = new Loader({\n\t\t\tcodeLoader,\n\t\t\tdocumentServiceFactory: failProxy(),\n\t\t\turlResolver: failProxy(),\n\t\t\tconfigProvider: {\n\t\t\t\tgetRawConfig: (name) =>\n\t\t\t\t\tname === \"Fluid.Container.RetryOnAttachFailure\" ? true : undefined,\n\t\t\t},\n\t\t});\n\t\tconst detached = await loader.createDetachedContainer({ package: \"none\" });\n\t\tawait detached.attach({ url: \"none\" }).then(\n\t\t\t() => assert.fail(\"attach should fail\"),\n\t\t\t() => {},\n\t\t);\n\n\t\tassert.strictEqual(detached.closed, false);\n\t\tassert.strictEqual(detached.attachState, AttachState.Attaching);\n\n\t\tconst detachedContainerState = detached.serialize();\n\t\tconst parsedState = JSON.parse(detachedContainerState) as IPendingDetachedContainerState;\n\t\tassert.strictEqual(parsedState.attached, false);\n\t\tassert.strictEqual(parsedState.hasAttachmentBlobs, false);\n\t\tassert.strictEqual(Object.keys(parsedState.snapshotBlobs).length, 4);\n\t\tassert.deepStrictEqual(parsedState.pendingRuntimeState, { pending: [] });\n\t\tassert.ok(parsedState.baseSnapshot);\n\t\tawait loader.rehydrateDetachedContainerFromSnapshot(detachedContainerState);\n\t});\n\n\tit(\"serialize and rehydrateDetachedContainerFromSnapshot while attaching with valid format and attachment blobs\", async () => {\n\t\tconst blobs = new Map<string, ArrayBufferLike>();\n\t\tconst detachedBlobStorage: IDetachedBlobStorage = {\n\t\t\tcreateBlob: async (file) => {\n\t\t\t\tconst response: ICreateBlobResponse = {\n\t\t\t\t\tid: uuid(),\n\t\t\t\t};\n\t\t\t\tblobs.set(response.id, file);\n\t\t\t\treturn response;\n\t\t\t},\n\t\t\tgetBlobIds: () => [...blobs.keys()],\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\treadBlob: async (id) => blobs.get(id)!,\n\t\t\tget size() {\n\t\t\t\treturn blobs.size;\n\t\t\t},\n\t\t};\n\t\tconst resolvedUrl: IResolvedUrl = {\n\t\t\tid: uuid(),\n\t\t\tendpoints: {},\n\t\t\ttokens: {},\n\t\t\ttype: \"fluid\",\n\t\t\turl: \"none\",\n\t\t};\n\t\tconst loader = new Loader({\n\t\t\tcodeLoader,\n\t\t\tdocumentServiceFactory: failSometimeProxy<IDocumentServiceFactory>({\n\t\t\t\tcreateContainer: async () =>\n\t\t\t\t\tfailSometimeProxy<IDocumentService>({\n\t\t\t\t\t\tpolicies: {},\n\t\t\t\t\t\tresolvedUrl,\n\t\t\t\t\t\tconnectToStorage: async () =>\n\t\t\t\t\t\t\tfailSometimeProxy<IDocumentStorageService>({\n\t\t\t\t\t\t\t\tcreateBlob: async () => ({ id: uuid() }),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t}),\n\t\t\turlResolver: failSometimeProxy<IUrlResolver>({\n\t\t\t\tresolve: async () => resolvedUrl,\n\t\t\t}),\n\t\t\tdetachedBlobStorage,\n\t\t\tconfigProvider: {\n\t\t\t\tgetRawConfig: (name) =>\n\t\t\t\t\tname === \"Fluid.Container.RetryOnAttachFailure\" ? true : undefined,\n\t\t\t},\n\t\t});\n\t\tconst detached = await loader.createDetachedContainer({ package: \"none\" });\n\t\tawait detachedBlobStorage.createBlob(stringToBuffer(\"whatever\", \"utf8\"));\n\n\t\tawait detached.attach({ url: \"none\" }).then(\n\t\t\t() => assert.fail(\"attach should fail\"),\n\t\t\t() => {},\n\t\t);\n\n\t\tassert.strictEqual(detached.closed, false);\n\t\tassert.strictEqual(detached.attachState, AttachState.Attaching);\n\n\t\tconst detachedContainerState = detached.serialize();\n\t\tconst parsedState = JSON.parse(detachedContainerState) as IPendingDetachedContainerState;\n\t\tassert.strictEqual(parsedState.attached, false);\n\t\tassert.strictEqual(parsedState.hasAttachmentBlobs, true);\n\t\tassert.strictEqual(Object.keys(parsedState.snapshotBlobs).length, 4);\n\t\tassert.ok(parsedState.baseSnapshot);\n\t\tawait loader.rehydrateDetachedContainerFromSnapshot(detachedContainerState);\n\t});\n});\n"]}
1
+ {"version":3,"file":"loader.spec.js","sourceRoot":"","sources":["../../src/test/loader.spec.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 \"assert\";\nimport { stringToBuffer } from \"@fluid-internal/client-utils\";\nimport { AttachState, IRuntime } from \"@fluidframework/container-definitions\";\nimport { FluidErrorTypes } from \"@fluidframework/core-interfaces\";\nimport {\n\tIDocumentService,\n\tIDocumentServiceFactory,\n\ttype IDocumentStorageService,\n\ttype IResolvedUrl,\n\ttype IUrlResolver,\n} from \"@fluidframework/driver-definitions\";\nimport { ICreateBlobResponse, SummaryType } from \"@fluidframework/protocol-definitions\";\nimport { isFluidError } from \"@fluidframework/telemetry-utils\";\nimport { v4 as uuid } from \"uuid\";\nimport { IDetachedBlobStorage, Loader } from \"../loader.js\";\nimport type { IPendingDetachedContainerState } from \"../serializedStateManager.js\";\n\nconst failProxy = <T extends object>() => {\n\tconst proxy = new Proxy<T>({} as any as T, {\n\t\tget: (_, p) => {\n\t\t\tif (p === \"then\") {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tthrow Error(`${p.toString()} not implemented`);\n\t\t},\n\t});\n\treturn proxy;\n};\n\nconst failSometimeProxy = <T extends object>(handler: Partial<T>) => {\n\tconst proxy = new Proxy<T>(handler as T, {\n\t\tget: (t, p, r) => {\n\t\t\tif (p === \"then\") {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (p in handler) {\n\t\t\t\treturn Reflect.get(t, p, r);\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\t\t\treturn failProxy();\n\t\t},\n\t});\n\treturn proxy;\n};\n\nconst codeLoader = {\n\tload: async () => {\n\t\treturn {\n\t\t\tdetails: {\n\t\t\t\tpackage: \"none\",\n\t\t\t},\n\t\t\tmodule: {\n\t\t\t\tfluidExport: {\n\t\t\t\t\tIRuntimeFactory: {\n\t\t\t\t\t\tget IRuntimeFactory() {\n\t\t\t\t\t\t\treturn this;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tasync instantiateRuntime(context, existing) {\n\t\t\t\t\t\t\treturn failSometimeProxy<IRuntime>({\n\t\t\t\t\t\t\t\tcreateSummary: () => ({\n\t\t\t\t\t\t\t\t\ttree: {},\n\t\t\t\t\t\t\t\t\ttype: SummaryType.Tree,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tsetAttachState: () => {},\n\t\t\t\t\t\t\t\tgetPendingLocalState: () => ({\n\t\t\t\t\t\t\t\t\tpending: [],\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\ndescribe(\"loader unit test\", () => {\n\tit(\"rehydrateDetachedContainerFromSnapshot with invalid format\", async () => {\n\t\tconst loader = new Loader({\n\t\t\tcodeLoader: failProxy(),\n\t\t\tdocumentServiceFactory: failProxy(),\n\t\t\turlResolver: failProxy(),\n\t\t});\n\n\t\ttry {\n\t\t\tawait loader.rehydrateDetachedContainerFromSnapshot(`{\"foo\":\"bar\"}`);\n\t\t\tassert.fail(\"should fail\");\n\t\t} catch (e) {\n\t\t\tassert.strict(isFluidError(e), `should be a Fluid error: ${e}`);\n\t\t\tassert.strictEqual(e.errorType, FluidErrorTypes.usageError, \"should be a usage error\");\n\t\t}\n\t});\n\n\tit(\"rehydrateDetachedContainerFromSnapshot with valid format\", async () => {\n\t\tconst loader = new Loader({\n\t\t\tcodeLoader,\n\t\t\tdocumentServiceFactory: failProxy(),\n\t\t\turlResolver: failProxy(),\n\t\t});\n\t\tconst detached = await loader.createDetachedContainer({ package: \"none\" });\n\t\tconst detachedContainerState = detached.serialize();\n\t\tconst parsedState = JSON.parse(detachedContainerState) as IPendingDetachedContainerState;\n\t\tassert.strictEqual(parsedState.attached, false);\n\t\tassert.strictEqual(parsedState.hasAttachmentBlobs, false);\n\t\tassert.strictEqual(Object.keys(parsedState.snapshotBlobs).length, 4);\n\t\tassert.ok(parsedState.baseSnapshot);\n\t\tawait loader.rehydrateDetachedContainerFromSnapshot(detachedContainerState);\n\t});\n\n\tit(\"rehydrateDetachedContainerFromSnapshot with valid format and attachment blobs\", async () => {\n\t\tconst blobs = new Map<string, ArrayBufferLike>();\n\t\tconst detachedBlobStorage: IDetachedBlobStorage = {\n\t\t\tcreateBlob: async (file) => {\n\t\t\t\tconst response: ICreateBlobResponse = {\n\t\t\t\t\tid: uuid(),\n\t\t\t\t};\n\t\t\t\tblobs.set(response.id, file);\n\t\t\t\treturn response;\n\t\t\t},\n\t\t\tgetBlobIds: () => [...blobs.keys()],\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\treadBlob: async (id) => blobs.get(id)!,\n\t\t\tget size() {\n\t\t\t\treturn blobs.size;\n\t\t\t},\n\t\t};\n\t\tconst loader = new Loader({\n\t\t\tcodeLoader,\n\t\t\tdocumentServiceFactory: failProxy(),\n\t\t\turlResolver: failProxy(),\n\t\t\tdetachedBlobStorage,\n\t\t});\n\t\tconst detached = await loader.createDetachedContainer({ package: \"none\" });\n\t\tawait detachedBlobStorage.createBlob(stringToBuffer(\"whatever\", \"utf8\"));\n\t\tconst detachedContainerState = detached.serialize();\n\t\tconst parsedState = JSON.parse(detachedContainerState) as IPendingDetachedContainerState;\n\t\tassert.strictEqual(parsedState.attached, false);\n\t\tassert.strictEqual(parsedState.hasAttachmentBlobs, true);\n\t\tassert.strictEqual(Object.keys(parsedState.snapshotBlobs).length, 4);\n\t\tassert.ok(parsedState.baseSnapshot);\n\t\tawait loader.rehydrateDetachedContainerFromSnapshot(detachedContainerState);\n\t});\n\n\tit(\"serialize and rehydrateDetachedContainerFromSnapshot while attaching\", async () => {\n\t\tconst loader = new Loader({\n\t\t\tcodeLoader,\n\t\t\tdocumentServiceFactory: failProxy(),\n\t\t\turlResolver: failProxy(),\n\t\t\tconfigProvider: {\n\t\t\t\tgetRawConfig: (name) =>\n\t\t\t\t\tname === \"Fluid.Container.RetryOnAttachFailure\" ? true : undefined,\n\t\t\t},\n\t\t});\n\t\tconst detached = await loader.createDetachedContainer({ package: \"none\" });\n\t\tawait detached.attach({ url: \"none\" }).then(\n\t\t\t() => assert.fail(\"attach should fail\"),\n\t\t\t() => {},\n\t\t);\n\n\t\tassert.strictEqual(detached.closed, false);\n\t\tassert.strictEqual(detached.attachState, AttachState.Attaching);\n\n\t\tconst detachedContainerState = detached.serialize();\n\t\tconst parsedState = JSON.parse(detachedContainerState) as IPendingDetachedContainerState;\n\t\tassert.strictEqual(parsedState.attached, false);\n\t\tassert.strictEqual(parsedState.hasAttachmentBlobs, false);\n\t\tassert.strictEqual(Object.keys(parsedState.snapshotBlobs).length, 4);\n\t\tassert.deepStrictEqual(parsedState.pendingRuntimeState, { pending: [] });\n\t\tassert.ok(parsedState.baseSnapshot);\n\t\tawait loader.rehydrateDetachedContainerFromSnapshot(detachedContainerState);\n\t});\n\n\tit(\"serialize and rehydrateDetachedContainerFromSnapshot while attaching with valid format and attachment blobs\", async () => {\n\t\tconst blobs = new Map<string, ArrayBufferLike>();\n\t\tconst detachedBlobStorage: IDetachedBlobStorage = {\n\t\t\tcreateBlob: async (file) => {\n\t\t\t\tconst response: ICreateBlobResponse = {\n\t\t\t\t\tid: uuid(),\n\t\t\t\t};\n\t\t\t\tblobs.set(response.id, file);\n\t\t\t\treturn response;\n\t\t\t},\n\t\t\tgetBlobIds: () => [...blobs.keys()],\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\treadBlob: async (id) => blobs.get(id)!,\n\t\t\tget size() {\n\t\t\t\treturn blobs.size;\n\t\t\t},\n\t\t};\n\t\tconst resolvedUrl: IResolvedUrl = {\n\t\t\tid: uuid(),\n\t\t\tendpoints: {},\n\t\t\ttokens: {},\n\t\t\ttype: \"fluid\",\n\t\t\turl: \"none\",\n\t\t};\n\t\tconst loader = new Loader({\n\t\t\tcodeLoader,\n\t\t\tdocumentServiceFactory: failSometimeProxy<IDocumentServiceFactory>({\n\t\t\t\tcreateContainer: async () =>\n\t\t\t\t\tfailSometimeProxy<IDocumentService>({\n\t\t\t\t\t\tpolicies: {},\n\t\t\t\t\t\tresolvedUrl,\n\t\t\t\t\t\tconnectToStorage: async () =>\n\t\t\t\t\t\t\tfailSometimeProxy<IDocumentStorageService>({\n\t\t\t\t\t\t\t\tcreateBlob: async () => ({ id: uuid() }),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t}),\n\t\t\turlResolver: failSometimeProxy<IUrlResolver>({\n\t\t\t\tresolve: async () => resolvedUrl,\n\t\t\t}),\n\t\t\tdetachedBlobStorage,\n\t\t\tconfigProvider: {\n\t\t\t\tgetRawConfig: (name) =>\n\t\t\t\t\tname === \"Fluid.Container.RetryOnAttachFailure\" ? true : undefined,\n\t\t\t},\n\t\t});\n\t\tconst detached = await loader.createDetachedContainer({ package: \"none\" });\n\t\tawait detachedBlobStorage.createBlob(stringToBuffer(\"whatever\", \"utf8\"));\n\n\t\tawait detached.attach({ url: \"none\" }).then(\n\t\t\t() => assert.fail(\"attach should fail\"),\n\t\t\t() => {},\n\t\t);\n\n\t\tassert.strictEqual(detached.closed, false);\n\t\tassert.strictEqual(detached.attachState, AttachState.Attaching);\n\n\t\tconst detachedContainerState = detached.serialize();\n\t\tconst parsedState = JSON.parse(detachedContainerState) as IPendingDetachedContainerState;\n\t\tassert.strictEqual(parsedState.attached, false);\n\t\tassert.strictEqual(parsedState.hasAttachmentBlobs, true);\n\t\tassert.strictEqual(Object.keys(parsedState.snapshotBlobs).length, 4);\n\t\tassert.ok(parsedState.baseSnapshot);\n\t\tawait loader.rehydrateDetachedContainerFromSnapshot(detachedContainerState);\n\t});\n});\n"]}
@@ -3,9 +3,9 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { strict as assert } from "assert";
6
- import { createChildLogger } from "@fluidframework/telemetry-utils";
7
- import { MessageType, } from "@fluidframework/protocol-definitions";
8
6
  import { stringToBuffer } from "@fluid-internal/client-utils";
7
+ import { MessageType, } from "@fluidframework/protocol-definitions";
8
+ import { createChildLogger } from "@fluidframework/telemetry-utils";
9
9
  import { SerializedStateManager } from "../serializedStateManager.js";
10
10
  class MockStorageAdapter {
11
11
  constructor() {
@@ -114,8 +114,8 @@ describe("serializedStateManager", () => {
114
114
  };
115
115
  const storageAdapter = new MockStorageAdapter();
116
116
  const serializedStateManager = new SerializedStateManager(pendingLocalState, logger, storageAdapter, true);
117
- const { snapshotTree, version } = await serializedStateManager.fetchSnapshot(undefined, undefined);
118
- assert(snapshotTree);
117
+ const { baseSnapshot, version } = await serializedStateManager.fetchSnapshot(undefined, false);
118
+ assert(baseSnapshot);
119
119
  assert.strictEqual(version, undefined);
120
120
  const state = await serializedStateManager.getPendingLocalStateCore({ notifyImminentClosure: false }, "clientId", new MockRuntime(), resolvedUrl);
121
121
  assert.strictEqual(JSON.parse(state).baseSnapshot.id, "fromPending");
@@ -124,7 +124,10 @@ describe("serializedStateManager", () => {
124
124
  const storageAdapter = new MockStorageAdapter();
125
125
  const serializedStateManager = new SerializedStateManager(undefined, logger, storageAdapter, true);
126
126
  // equivalent to attach
127
- serializedStateManager.setSnapshot({ tree: { trees: {}, blobs: {} }, blobs: {} });
127
+ serializedStateManager.setSnapshot({
128
+ baseSnapshot: { trees: {}, blobs: {} },
129
+ snapshotBlobs: {},
130
+ });
128
131
  for (let num = 0; num < 10; ++num) {
129
132
  serializedStateManager.addProcessedOp(generateSavedOp());
130
133
  }
@@ -133,8 +136,8 @@ describe("serializedStateManager", () => {
133
136
  it("can fetch snapshot and get state from it", async () => {
134
137
  const storageAdapter = new MockStorageAdapter();
135
138
  const serializedStateManager = new SerializedStateManager(undefined, logger, storageAdapter, true);
136
- const { snapshotTree, version } = await serializedStateManager.fetchSnapshot(undefined, undefined);
137
- assert(snapshotTree);
139
+ const { baseSnapshot, version } = await serializedStateManager.fetchSnapshot(undefined, false);
140
+ assert(baseSnapshot);
138
141
  assert.strictEqual(version?.id, "test");
139
142
  assert.strictEqual(version.treeId, "test");
140
143
  const state = await serializedStateManager.getPendingLocalStateCore({ notifyImminentClosure: false }, "clientId", new MockRuntime(), resolvedUrl);
@@ -1 +1 @@
1
- {"version":3,"file":"serializedStateManager.spec.js","sourceRoot":"","sources":["../../src/test/serializedStateManager.spec.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 { strict as assert } from \"assert\";\nimport { ITelemetryLoggerExt, createChildLogger } from \"@fluidframework/telemetry-utils\";\nimport {\n\tIVersion,\n\tISnapshotTree,\n\tMessageType,\n\tISequencedDocumentMessage,\n\tIDocumentAttributes,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n\tFetchSource,\n\tIDocumentStorageService,\n\tIResolvedUrl,\n\tISnapshot,\n\tISnapshotFetchOptions,\n} from \"@fluidframework/driver-definitions\";\nimport { IGetPendingLocalStateProps, IRuntime } from \"@fluidframework/container-definitions\";\nimport { stringToBuffer } from \"@fluid-internal/client-utils\";\nimport { IPendingContainerState } from \"../container.js\";\nimport { SerializedStateManager } from \"../serializedStateManager.js\";\n\ntype ISerializedStateManagerDocumentStorageService = Pick<\n\tIDocumentStorageService,\n\t\"getSnapshot\" | \"getSnapshotTree\" | \"getVersions\" | \"readBlob\"\n>;\n\ninterface IPendingMessage {\n\ttype: \"message\";\n\treferenceSequenceNumber: number;\n\tcontent: string;\n}\n\nclass MockStorageAdapter implements ISerializedStateManagerDocumentStorageService {\n\tprivate readonly blobs = new Map<string, ArrayBufferLike>();\n\tprivate readonly snapshots: ISnapshotTree[] = [];\n\n\tconstructor() {\n\t\tconst baseSnapshot: ISnapshotTree = {\n\t\t\tid: \"SnapshotId\",\n\t\t\tblobs: {},\n\t\t\ttrees: {\n\t\t\t\t\".protocol\": {\n\t\t\t\t\tblobs: { attributes: \"attributesId\" },\n\t\t\t\t\ttrees: {},\n\t\t\t\t},\n\t\t\t\t\".app\": {\n\t\t\t\t\tblobs: {},\n\t\t\t\t\ttrees: {},\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\t\tthis.snapshots.push(baseSnapshot);\n\t\tthis.blobs.set(\n\t\t\t\"attributesId\",\n\t\t\tstringToBuffer(`{\"minimumSequenceNumber\" : 0, \"sequenceNumber\": 0}`, \"utf8\"),\n\t\t);\n\t}\n\n\tpublic async getSnapshot(\n\t\tsnapshotFetchOptions?: ISnapshotFetchOptions | undefined,\n\t): Promise<ISnapshot> {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\tpublic async getSnapshotTree(\n\t\tversion?: IVersion | undefined,\n\t\tscenarioName?: string | undefined,\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t): Promise<ISnapshotTree | null> {\n\t\tconst lastSnapshot = this.snapshots[this.snapshots.length - 1];\n\t\treturn lastSnapshot ?? null;\n\t}\n\n\tpublic async getVersions(\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tversionId: string | null,\n\t\tcount: number,\n\t\tscenarioName?: string | undefined,\n\t\tfetchSource?: FetchSource | undefined,\n\t): Promise<IVersion[]> {\n\t\treturn [{ id: \"test\", treeId: \"test\" }];\n\t}\n\tpublic async readBlob(id: string): Promise<ArrayBufferLike> {\n\t\treturn this.blobs.get(id) as ArrayBufferLike;\n\t}\n}\n\ntype ISerializedStateManagerRuntime = Pick<IRuntime, \"getPendingLocalState\">;\n\nclass MockRuntime implements ISerializedStateManagerRuntime {\n\tprivate pendingOps: IPendingMessage[] = [];\n\tpublic generatePendingOp(rfs) {\n\t\tthis.pendingOps.push({\n\t\t\ttype: \"message\",\n\t\t\treferenceSequenceNumber: rfs,\n\t\t\tcontent: \"\",\n\t\t});\n\t}\n\n\tpublic getPendingLocalState(props?: IGetPendingLocalStateProps | undefined): unknown {\n\t\tconst result = [...this.pendingOps];\n\t\tthis.pendingOps = [];\n\t\treturn { pending: result };\n\t}\n}\n\nconst resolvedUrl: IResolvedUrl = {\n\ttype: \"fluid\",\n\tid: \"\",\n\turl: \"test\",\n\ttokens: {},\n\tendpoints: {},\n};\n\nconst errorFn = (error: Error, expected: string): boolean => {\n\tassert.notStrictEqual(error.message, undefined, \"error is undefined\");\n\tassert.strictEqual(error.message, expected, `Unexpected error: ${error.message}`);\n\treturn true;\n};\n\nconst getAttributesFromPendingState = (\n\tpendingState: IPendingContainerState,\n): IDocumentAttributes => {\n\tif (pendingState.baseSnapshot === undefined) {\n\t\tthrow new Error(\"base snapshot should be valid\");\n\t}\n\tconst attributesId = pendingState.baseSnapshot.trees[\".protocol\"].blobs.attributes;\n\tconst attributes = pendingState.snapshotBlobs[attributesId];\n\treturn JSON.parse(attributes) as IDocumentAttributes;\n};\n\ndescribe(\"serializedStateManager\", () => {\n\tlet seq: number;\n\tlet logger: ITelemetryLoggerExt;\n\n\tfunction generateSavedOp(type: MessageType = MessageType.Operation): ISequencedDocumentMessage {\n\t\treturn {\n\t\t\tclientId: \"Some client ID\",\n\t\t\tminimumSequenceNumber: 0,\n\t\t\tsequenceNumber: seq++,\n\t\t\ttype,\n\t\t} as any as ISequencedDocumentMessage;\n\t}\n\n\tbeforeEach(async () => {\n\t\tseq = 1;\n\t\tlogger = createChildLogger({ namespace: \"fluid:testSerializedStateManager\" });\n\t});\n\n\tit(\"can't get pending local state when offline load disabled\", async () => {\n\t\tconst storageAdapter = new MockStorageAdapter();\n\t\tconst serializedStateManager = new SerializedStateManager(\n\t\t\tundefined,\n\t\t\tlogger,\n\t\t\tstorageAdapter,\n\t\t\tfalse,\n\t\t);\n\n\t\tawait assert.rejects(\n\t\t\tasync () =>\n\t\t\t\tserializedStateManager.getPendingLocalStateCore(\n\t\t\t\t\t{\n\t\t\t\t\t\tnotifyImminentClosure: false,\n\t\t\t\t\t},\n\t\t\t\t\t\"clientId\",\n\t\t\t\t\tnew MockRuntime(),\n\t\t\t\t\tresolvedUrl,\n\t\t\t\t),\n\t\t\t(error: Error) =>\n\t\t\t\terrorFn(error, \"Can't get pending local state unless offline load is enabled\"),\n\t\t\t\"container can get local state with offline load disabled\",\n\t\t);\n\t});\n\n\tit(\"can get snapshot from previous local state\", async () => {\n\t\tconst pendingLocalState: IPendingContainerState = {\n\t\t\tattached: true,\n\t\t\tbaseSnapshot: { id: \"fromPending\", blobs: {}, trees: {} },\n\t\t\tsnapshotBlobs: {},\n\t\t\tpendingRuntimeState: {},\n\t\t\tsavedOps: [],\n\t\t\turl: \"fluid\",\n\t\t};\n\t\tconst storageAdapter = new MockStorageAdapter();\n\t\tconst serializedStateManager = new SerializedStateManager(\n\t\t\tpendingLocalState,\n\t\t\tlogger,\n\t\t\tstorageAdapter,\n\t\t\ttrue,\n\t\t);\n\t\tconst { snapshotTree, version } = await serializedStateManager.fetchSnapshot(\n\t\t\tundefined,\n\t\t\tundefined,\n\t\t);\n\t\tassert(snapshotTree);\n\t\tassert.strictEqual(version, undefined);\n\t\tconst state = await serializedStateManager.getPendingLocalStateCore(\n\t\t\t{ notifyImminentClosure: false },\n\t\t\t\"clientId\",\n\t\t\tnew MockRuntime(),\n\t\t\tresolvedUrl,\n\t\t);\n\t\tassert.strictEqual(JSON.parse(state).baseSnapshot.id, \"fromPending\");\n\t});\n\n\tit(\"can get pending local state after attach\", async () => {\n\t\tconst storageAdapter = new MockStorageAdapter();\n\t\tconst serializedStateManager = new SerializedStateManager(\n\t\t\tundefined,\n\t\t\tlogger,\n\t\t\tstorageAdapter,\n\t\t\ttrue,\n\t\t);\n\t\t// equivalent to attach\n\t\tserializedStateManager.setSnapshot({ tree: { trees: {}, blobs: {} }, blobs: {} });\n\t\tfor (let num = 0; num < 10; ++num) {\n\t\t\tserializedStateManager.addProcessedOp(generateSavedOp());\n\t\t}\n\t\tawait serializedStateManager.getPendingLocalStateCore(\n\t\t\t{ notifyImminentClosure: false },\n\t\t\t\"clientId\",\n\t\t\tnew MockRuntime(),\n\t\t\tresolvedUrl,\n\t\t);\n\t});\n\n\tit(\"can fetch snapshot and get state from it\", async () => {\n\t\tconst storageAdapter = new MockStorageAdapter();\n\t\tconst serializedStateManager = new SerializedStateManager(\n\t\t\tundefined,\n\t\t\tlogger,\n\t\t\tstorageAdapter,\n\t\t\ttrue,\n\t\t);\n\t\tconst { snapshotTree, version } = await serializedStateManager.fetchSnapshot(\n\t\t\tundefined,\n\t\t\tundefined,\n\t\t);\n\t\tassert(snapshotTree);\n\t\tassert.strictEqual(version?.id, \"test\");\n\t\tassert.strictEqual(version.treeId, \"test\");\n\t\tconst state = await serializedStateManager.getPendingLocalStateCore(\n\t\t\t{ notifyImminentClosure: false },\n\t\t\t\"clientId\",\n\t\t\tnew MockRuntime(),\n\t\t\tresolvedUrl,\n\t\t);\n\t\tconst parsed = JSON.parse(state);\n\t\tassert.strictEqual(parsed.baseSnapshot.id, \"SnapshotId\");\n\t\tconst attributes = getAttributesFromPendingState(parsed);\n\t\tassert.strictEqual(attributes.sequenceNumber, 0);\n\t\tassert.strictEqual(attributes.minimumSequenceNumber, 0);\n\t});\n});\n"]}
1
+ {"version":3,"file":"serializedStateManager.spec.js","sourceRoot":"","sources":["../../src/test/serializedStateManager.spec.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 { strict as assert } from \"assert\";\nimport { stringToBuffer } from \"@fluid-internal/client-utils\";\nimport { IGetPendingLocalStateProps, IRuntime } from \"@fluidframework/container-definitions\";\nimport {\n\tFetchSource,\n\tIDocumentStorageService,\n\tIResolvedUrl,\n\tISnapshot,\n\tISnapshotFetchOptions,\n} from \"@fluidframework/driver-definitions\";\nimport {\n\tIDocumentAttributes,\n\tISequencedDocumentMessage,\n\tISnapshotTree,\n\tIVersion,\n\tMessageType,\n} from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLoggerExt, createChildLogger } from \"@fluidframework/telemetry-utils\";\nimport { type IPendingContainerState, SerializedStateManager } from \"../serializedStateManager.js\";\n\ntype ISerializedStateManagerDocumentStorageService = Pick<\n\tIDocumentStorageService,\n\t\"getSnapshot\" | \"getSnapshotTree\" | \"getVersions\" | \"readBlob\"\n>;\n\ninterface IPendingMessage {\n\ttype: \"message\";\n\treferenceSequenceNumber: number;\n\tcontent: string;\n}\n\nclass MockStorageAdapter implements ISerializedStateManagerDocumentStorageService {\n\tprivate readonly blobs = new Map<string, ArrayBufferLike>();\n\tprivate readonly snapshots: ISnapshotTree[] = [];\n\n\tconstructor() {\n\t\tconst baseSnapshot: ISnapshotTree = {\n\t\t\tid: \"SnapshotId\",\n\t\t\tblobs: {},\n\t\t\ttrees: {\n\t\t\t\t\".protocol\": {\n\t\t\t\t\tblobs: { attributes: \"attributesId\" },\n\t\t\t\t\ttrees: {},\n\t\t\t\t},\n\t\t\t\t\".app\": {\n\t\t\t\t\tblobs: {},\n\t\t\t\t\ttrees: {},\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\t\tthis.snapshots.push(baseSnapshot);\n\t\tthis.blobs.set(\n\t\t\t\"attributesId\",\n\t\t\tstringToBuffer(`{\"minimumSequenceNumber\" : 0, \"sequenceNumber\": 0}`, \"utf8\"),\n\t\t);\n\t}\n\n\tpublic async getSnapshot(\n\t\tsnapshotFetchOptions?: ISnapshotFetchOptions | undefined,\n\t): Promise<ISnapshot> {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\tpublic async getSnapshotTree(\n\t\tversion?: IVersion | undefined,\n\t\tscenarioName?: string | undefined,\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t): Promise<ISnapshotTree | null> {\n\t\tconst lastSnapshot = this.snapshots[this.snapshots.length - 1];\n\t\treturn lastSnapshot ?? null;\n\t}\n\n\tpublic async getVersions(\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tversionId: string | null,\n\t\tcount: number,\n\t\tscenarioName?: string | undefined,\n\t\tfetchSource?: FetchSource | undefined,\n\t): Promise<IVersion[]> {\n\t\treturn [{ id: \"test\", treeId: \"test\" }];\n\t}\n\tpublic async readBlob(id: string): Promise<ArrayBufferLike> {\n\t\treturn this.blobs.get(id) as ArrayBufferLike;\n\t}\n}\n\ntype ISerializedStateManagerRuntime = Pick<IRuntime, \"getPendingLocalState\">;\n\nclass MockRuntime implements ISerializedStateManagerRuntime {\n\tprivate pendingOps: IPendingMessage[] = [];\n\tpublic generatePendingOp(rfs) {\n\t\tthis.pendingOps.push({\n\t\t\ttype: \"message\",\n\t\t\treferenceSequenceNumber: rfs,\n\t\t\tcontent: \"\",\n\t\t});\n\t}\n\n\tpublic getPendingLocalState(props?: IGetPendingLocalStateProps | undefined): unknown {\n\t\tconst result = [...this.pendingOps];\n\t\tthis.pendingOps = [];\n\t\treturn { pending: result };\n\t}\n}\n\nconst resolvedUrl: IResolvedUrl = {\n\ttype: \"fluid\",\n\tid: \"\",\n\turl: \"test\",\n\ttokens: {},\n\tendpoints: {},\n};\n\nconst errorFn = (error: Error, expected: string): boolean => {\n\tassert.notStrictEqual(error.message, undefined, \"error is undefined\");\n\tassert.strictEqual(error.message, expected, `Unexpected error: ${error.message}`);\n\treturn true;\n};\n\nconst getAttributesFromPendingState = (\n\tpendingState: IPendingContainerState,\n): IDocumentAttributes => {\n\tif (pendingState.baseSnapshot === undefined) {\n\t\tthrow new Error(\"base snapshot should be valid\");\n\t}\n\tconst attributesId = pendingState.baseSnapshot.trees[\".protocol\"].blobs.attributes;\n\tconst attributes = pendingState.snapshotBlobs[attributesId];\n\treturn JSON.parse(attributes) as IDocumentAttributes;\n};\n\ndescribe(\"serializedStateManager\", () => {\n\tlet seq: number;\n\tlet logger: ITelemetryLoggerExt;\n\n\tfunction generateSavedOp(type: MessageType = MessageType.Operation): ISequencedDocumentMessage {\n\t\treturn {\n\t\t\tclientId: \"Some client ID\",\n\t\t\tminimumSequenceNumber: 0,\n\t\t\tsequenceNumber: seq++,\n\t\t\ttype,\n\t\t} as any as ISequencedDocumentMessage;\n\t}\n\n\tbeforeEach(async () => {\n\t\tseq = 1;\n\t\tlogger = createChildLogger({ namespace: \"fluid:testSerializedStateManager\" });\n\t});\n\n\tit(\"can't get pending local state when offline load disabled\", async () => {\n\t\tconst storageAdapter = new MockStorageAdapter();\n\t\tconst serializedStateManager = new SerializedStateManager(\n\t\t\tundefined,\n\t\t\tlogger,\n\t\t\tstorageAdapter,\n\t\t\tfalse,\n\t\t);\n\n\t\tawait assert.rejects(\n\t\t\tasync () =>\n\t\t\t\tserializedStateManager.getPendingLocalStateCore(\n\t\t\t\t\t{\n\t\t\t\t\t\tnotifyImminentClosure: false,\n\t\t\t\t\t},\n\t\t\t\t\t\"clientId\",\n\t\t\t\t\tnew MockRuntime(),\n\t\t\t\t\tresolvedUrl,\n\t\t\t\t),\n\t\t\t(error: Error) =>\n\t\t\t\terrorFn(error, \"Can't get pending local state unless offline load is enabled\"),\n\t\t\t\"container can get local state with offline load disabled\",\n\t\t);\n\t});\n\n\tit(\"can get snapshot from previous local state\", async () => {\n\t\tconst pendingLocalState: IPendingContainerState = {\n\t\t\tattached: true,\n\t\t\tbaseSnapshot: { id: \"fromPending\", blobs: {}, trees: {} },\n\t\t\tsnapshotBlobs: {},\n\t\t\tpendingRuntimeState: {},\n\t\t\tsavedOps: [],\n\t\t\turl: \"fluid\",\n\t\t};\n\t\tconst storageAdapter = new MockStorageAdapter();\n\t\tconst serializedStateManager = new SerializedStateManager(\n\t\t\tpendingLocalState,\n\t\t\tlogger,\n\t\t\tstorageAdapter,\n\t\t\ttrue,\n\t\t);\n\t\tconst { baseSnapshot, version } = await serializedStateManager.fetchSnapshot(\n\t\t\tundefined,\n\t\t\tfalse,\n\t\t);\n\t\tassert(baseSnapshot);\n\t\tassert.strictEqual(version, undefined);\n\t\tconst state = await serializedStateManager.getPendingLocalStateCore(\n\t\t\t{ notifyImminentClosure: false },\n\t\t\t\"clientId\",\n\t\t\tnew MockRuntime(),\n\t\t\tresolvedUrl,\n\t\t);\n\t\tassert.strictEqual(JSON.parse(state).baseSnapshot.id, \"fromPending\");\n\t});\n\n\tit(\"can get pending local state after attach\", async () => {\n\t\tconst storageAdapter = new MockStorageAdapter();\n\t\tconst serializedStateManager = new SerializedStateManager(\n\t\t\tundefined,\n\t\t\tlogger,\n\t\t\tstorageAdapter,\n\t\t\ttrue,\n\t\t);\n\t\t// equivalent to attach\n\t\tserializedStateManager.setSnapshot({\n\t\t\tbaseSnapshot: { trees: {}, blobs: {} },\n\t\t\tsnapshotBlobs: {},\n\t\t});\n\t\tfor (let num = 0; num < 10; ++num) {\n\t\t\tserializedStateManager.addProcessedOp(generateSavedOp());\n\t\t}\n\t\tawait serializedStateManager.getPendingLocalStateCore(\n\t\t\t{ notifyImminentClosure: false },\n\t\t\t\"clientId\",\n\t\t\tnew MockRuntime(),\n\t\t\tresolvedUrl,\n\t\t);\n\t});\n\n\tit(\"can fetch snapshot and get state from it\", async () => {\n\t\tconst storageAdapter = new MockStorageAdapter();\n\t\tconst serializedStateManager = new SerializedStateManager(\n\t\t\tundefined,\n\t\t\tlogger,\n\t\t\tstorageAdapter,\n\t\t\ttrue,\n\t\t);\n\t\tconst { baseSnapshot, version } = await serializedStateManager.fetchSnapshot(\n\t\t\tundefined,\n\t\t\tfalse,\n\t\t);\n\t\tassert(baseSnapshot);\n\t\tassert.strictEqual(version?.id, \"test\");\n\t\tassert.strictEqual(version.treeId, \"test\");\n\t\tconst state = await serializedStateManager.getPendingLocalStateCore(\n\t\t\t{ notifyImminentClosure: false },\n\t\t\t\"clientId\",\n\t\t\tnew MockRuntime(),\n\t\t\tresolvedUrl,\n\t\t);\n\t\tconst parsed = JSON.parse(state);\n\t\tassert.strictEqual(parsed.baseSnapshot.id, \"SnapshotId\");\n\t\tconst attributes = getAttributesFromPendingState(parsed);\n\t\tassert.strictEqual(attributes.sequenceNumber, 0);\n\t\tassert.strictEqual(attributes.minimumSequenceNumber, 0);\n\t});\n});\n"]}
@@ -52,28 +52,28 @@ describe("Dehydrate Container", () => {
52
52
  },
53
53
  },
54
54
  };
55
- it("Summary to snapshottree and snapshotBlobs conversion", async () => {
55
+ it("Summary to baseSnapshot and snapshotBlobs conversion", async () => {
56
56
  const combinedSummary = combineAppAndProtocolSummary(appSummary, protocolSummary);
57
- const { tree, blobs } = getSnapshotTreeAndBlobsFromSerializedContainer(combinedSummary);
58
- assert.strictEqual(Object.keys(tree.trees).length, 2, "2 trees should be there");
59
- assert.strictEqual(Object.keys(tree.trees[".protocol"].blobs).length, 2, "2 protocol blobs should be there.");
57
+ const { baseSnapshot, snapshotBlobs } = getSnapshotTreeAndBlobsFromSerializedContainer(combinedSummary);
58
+ assert.strictEqual(Object.keys(baseSnapshot.trees).length, 2, "2 trees should be there");
59
+ assert.strictEqual(Object.keys(baseSnapshot.trees[".protocol"].blobs).length, 2, "2 protocol blobs should be there.");
60
60
  // Validate the ".component" blob.
61
- const defaultDataStoreBlobId = tree.trees.default.blobs[".component"];
62
- const defaultDataStoreBlob = blobs[defaultDataStoreBlobId];
61
+ const defaultDataStoreBlobId = baseSnapshot.trees.default.blobs[".component"];
62
+ const defaultDataStoreBlob = snapshotBlobs[defaultDataStoreBlobId];
63
63
  assert.strict(defaultDataStoreBlob, "defaultDataStoreBlob undefined");
64
64
  assert.strictEqual(JSON.parse(defaultDataStoreBlob), "defaultDataStore", "The .component blob's content is incorrect");
65
65
  // Validate "root" sub-tree.
66
- const rootAttributesBlobId = tree.trees.default.trees.root.blobs.attributes;
67
- const rootAttributesBlob = blobs[rootAttributesBlobId];
66
+ const rootAttributesBlobId = baseSnapshot.trees.default.trees.root.blobs.attributes;
67
+ const rootAttributesBlob = snapshotBlobs[rootAttributesBlobId];
68
68
  assert.strict(rootAttributesBlob, "rootAttributesBlob undefined");
69
69
  assert.strictEqual(JSON.parse(rootAttributesBlob), "rootattributes", "The root sub-tree's content is incorrect");
70
- assert.strictEqual(tree.trees.default.trees.root.unreferenced, undefined, "The root sub-tree should not be marked as unreferenced");
70
+ assert.strictEqual(baseSnapshot.trees.default.trees.root.unreferenced, undefined, "The root sub-tree should not be marked as unreferenced");
71
71
  // Validate "unref" sub-tree.
72
- assert.strictEqual(tree.trees.default.trees.unref.unreferenced, true, "The unref sub-tree should be marked as unreferenced");
72
+ assert.strictEqual(baseSnapshot.trees.default.trees.unref.unreferenced, true, "The unref sub-tree should be marked as unreferenced");
73
73
  // Validate "groupId" sub-tree.
74
- assert.strictEqual(tree.trees.default.trees.groupId.groupId, "group", "The groupId sub-tree should have a groupId");
74
+ assert.strictEqual(baseSnapshot.trees.default.trees.groupId.groupId, "group", "The groupId sub-tree should have a groupId");
75
75
  // Validate "groupId" sub-tree.
76
- assert.strictEqual(tree.trees.default.trees.groupId.groupId, "group", "The groupId sub-tree should have a groupId");
76
+ assert.strictEqual(baseSnapshot.trees.default.trees.groupId.groupId, "group", "The groupId sub-tree should have a groupId");
77
77
  });
78
78
  });
79
79
  //# sourceMappingURL=snapshotConversionTest.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"snapshotConversionTest.spec.js","sourceRoot":"","sources":["../../src/test/snapshotConversionTest.spec.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 { strict as assert } from \"assert\";\nimport { ISummaryTree, SummaryType } from \"@fluidframework/protocol-definitions\";\nimport {\n\tcombineAppAndProtocolSummary,\n\tgetSnapshotTreeAndBlobsFromSerializedContainer,\n} from \"../utils.js\";\n\ndescribe(\"Dehydrate Container\", () => {\n\tconst protocolSummary: ISummaryTree = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: {\n\t\t\tattributes: {\n\t\t\t\ttype: SummaryType.Blob,\n\t\t\t\tcontent: JSON.stringify(\"attributes\"),\n\t\t\t},\n\t\t\tquorumValues: {\n\t\t\t\ttype: SummaryType.Blob,\n\t\t\t\tcontent: JSON.stringify(\"quorumValues\"),\n\t\t\t},\n\t\t},\n\t};\n\tconst appSummary: ISummaryTree = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: {\n\t\t\tdefault: {\n\t\t\t\ttype: SummaryType.Tree,\n\t\t\t\ttree: {\n\t\t\t\t\t\".component\": {\n\t\t\t\t\t\ttype: SummaryType.Blob,\n\t\t\t\t\t\tcontent: JSON.stringify(\"defaultDataStore\"),\n\t\t\t\t\t},\n\t\t\t\t\t\"root\": {\n\t\t\t\t\t\ttype: SummaryType.Tree,\n\t\t\t\t\t\ttree: {\n\t\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\t\ttype: SummaryType.Blob,\n\t\t\t\t\t\t\t\tcontent: JSON.stringify(\"rootattributes\"),\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\t\"unref\": {\n\t\t\t\t\t\ttype: SummaryType.Tree,\n\t\t\t\t\t\ttree: {},\n\t\t\t\t\t\tunreferenced: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"groupId\": {\n\t\t\t\t\t\ttype: SummaryType.Tree,\n\t\t\t\t\t\ttree: {},\n\t\t\t\t\t\tgroupId: \"group\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n\n\tit(\"Summary to snapshottree and snapshotBlobs conversion\", async () => {\n\t\tconst combinedSummary = combineAppAndProtocolSummary(appSummary, protocolSummary);\n\t\tconst { tree, blobs } = getSnapshotTreeAndBlobsFromSerializedContainer(combinedSummary);\n\n\t\tassert.strictEqual(Object.keys(tree.trees).length, 2, \"2 trees should be there\");\n\t\tassert.strictEqual(\n\t\t\tObject.keys(tree.trees[\".protocol\"].blobs).length,\n\t\t\t2,\n\t\t\t\"2 protocol blobs should be there.\",\n\t\t);\n\n\t\t// Validate the \".component\" blob.\n\t\tconst defaultDataStoreBlobId = tree.trees.default.blobs[\".component\"];\n\t\tconst defaultDataStoreBlob = blobs[defaultDataStoreBlobId];\n\t\tassert.strict(defaultDataStoreBlob, \"defaultDataStoreBlob undefined\");\n\t\tassert.strictEqual(\n\t\t\tJSON.parse(defaultDataStoreBlob),\n\t\t\t\"defaultDataStore\",\n\t\t\t\"The .component blob's content is incorrect\",\n\t\t);\n\n\t\t// Validate \"root\" sub-tree.\n\t\tconst rootAttributesBlobId = tree.trees.default.trees.root.blobs.attributes;\n\t\tconst rootAttributesBlob = blobs[rootAttributesBlobId];\n\t\tassert.strict(rootAttributesBlob, \"rootAttributesBlob undefined\");\n\t\tassert.strictEqual(\n\t\t\tJSON.parse(rootAttributesBlob),\n\t\t\t\"rootattributes\",\n\t\t\t\"The root sub-tree's content is incorrect\",\n\t\t);\n\t\tassert.strictEqual(\n\t\t\ttree.trees.default.trees.root.unreferenced,\n\t\t\tundefined,\n\t\t\t\"The root sub-tree should not be marked as unreferenced\",\n\t\t);\n\n\t\t// Validate \"unref\" sub-tree.\n\t\tassert.strictEqual(\n\t\t\ttree.trees.default.trees.unref.unreferenced,\n\t\t\ttrue,\n\t\t\t\"The unref sub-tree should be marked as unreferenced\",\n\t\t);\n\n\t\t// Validate \"groupId\" sub-tree.\n\t\tassert.strictEqual(\n\t\t\ttree.trees.default.trees.groupId.groupId,\n\t\t\t\"group\",\n\t\t\t\"The groupId sub-tree should have a groupId\",\n\t\t);\n\n\t\t// Validate \"groupId\" sub-tree.\n\t\tassert.strictEqual(\n\t\t\ttree.trees.default.trees.groupId.groupId,\n\t\t\t\"group\",\n\t\t\t\"The groupId sub-tree should have a groupId\",\n\t\t);\n\t});\n});\n"]}
1
+ {"version":3,"file":"snapshotConversionTest.spec.js","sourceRoot":"","sources":["../../src/test/snapshotConversionTest.spec.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 { strict as assert } from \"assert\";\nimport { ISummaryTree, SummaryType } from \"@fluidframework/protocol-definitions\";\nimport {\n\tcombineAppAndProtocolSummary,\n\tgetSnapshotTreeAndBlobsFromSerializedContainer,\n} from \"../utils.js\";\n\ndescribe(\"Dehydrate Container\", () => {\n\tconst protocolSummary: ISummaryTree = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: {\n\t\t\tattributes: {\n\t\t\t\ttype: SummaryType.Blob,\n\t\t\t\tcontent: JSON.stringify(\"attributes\"),\n\t\t\t},\n\t\t\tquorumValues: {\n\t\t\t\ttype: SummaryType.Blob,\n\t\t\t\tcontent: JSON.stringify(\"quorumValues\"),\n\t\t\t},\n\t\t},\n\t};\n\tconst appSummary: ISummaryTree = {\n\t\ttype: SummaryType.Tree,\n\t\ttree: {\n\t\t\tdefault: {\n\t\t\t\ttype: SummaryType.Tree,\n\t\t\t\ttree: {\n\t\t\t\t\t\".component\": {\n\t\t\t\t\t\ttype: SummaryType.Blob,\n\t\t\t\t\t\tcontent: JSON.stringify(\"defaultDataStore\"),\n\t\t\t\t\t},\n\t\t\t\t\t\"root\": {\n\t\t\t\t\t\ttype: SummaryType.Tree,\n\t\t\t\t\t\ttree: {\n\t\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\t\ttype: SummaryType.Blob,\n\t\t\t\t\t\t\t\tcontent: JSON.stringify(\"rootattributes\"),\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\t\"unref\": {\n\t\t\t\t\t\ttype: SummaryType.Tree,\n\t\t\t\t\t\ttree: {},\n\t\t\t\t\t\tunreferenced: true,\n\t\t\t\t\t},\n\t\t\t\t\t\"groupId\": {\n\t\t\t\t\t\ttype: SummaryType.Tree,\n\t\t\t\t\t\ttree: {},\n\t\t\t\t\t\tgroupId: \"group\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n\n\tit(\"Summary to baseSnapshot and snapshotBlobs conversion\", async () => {\n\t\tconst combinedSummary = combineAppAndProtocolSummary(appSummary, protocolSummary);\n\t\tconst { baseSnapshot, snapshotBlobs } =\n\t\t\tgetSnapshotTreeAndBlobsFromSerializedContainer(combinedSummary);\n\n\t\tassert.strictEqual(Object.keys(baseSnapshot.trees).length, 2, \"2 trees should be there\");\n\t\tassert.strictEqual(\n\t\t\tObject.keys(baseSnapshot.trees[\".protocol\"].blobs).length,\n\t\t\t2,\n\t\t\t\"2 protocol blobs should be there.\",\n\t\t);\n\n\t\t// Validate the \".component\" blob.\n\t\tconst defaultDataStoreBlobId = baseSnapshot.trees.default.blobs[\".component\"];\n\t\tconst defaultDataStoreBlob = snapshotBlobs[defaultDataStoreBlobId];\n\t\tassert.strict(defaultDataStoreBlob, \"defaultDataStoreBlob undefined\");\n\t\tassert.strictEqual(\n\t\t\tJSON.parse(defaultDataStoreBlob),\n\t\t\t\"defaultDataStore\",\n\t\t\t\"The .component blob's content is incorrect\",\n\t\t);\n\n\t\t// Validate \"root\" sub-tree.\n\t\tconst rootAttributesBlobId = baseSnapshot.trees.default.trees.root.blobs.attributes;\n\t\tconst rootAttributesBlob = snapshotBlobs[rootAttributesBlobId];\n\t\tassert.strict(rootAttributesBlob, \"rootAttributesBlob undefined\");\n\t\tassert.strictEqual(\n\t\t\tJSON.parse(rootAttributesBlob),\n\t\t\t\"rootattributes\",\n\t\t\t\"The root sub-tree's content is incorrect\",\n\t\t);\n\t\tassert.strictEqual(\n\t\t\tbaseSnapshot.trees.default.trees.root.unreferenced,\n\t\t\tundefined,\n\t\t\t\"The root sub-tree should not be marked as unreferenced\",\n\t\t);\n\n\t\t// Validate \"unref\" sub-tree.\n\t\tassert.strictEqual(\n\t\t\tbaseSnapshot.trees.default.trees.unref.unreferenced,\n\t\t\ttrue,\n\t\t\t\"The unref sub-tree should be marked as unreferenced\",\n\t\t);\n\n\t\t// Validate \"groupId\" sub-tree.\n\t\tassert.strictEqual(\n\t\t\tbaseSnapshot.trees.default.trees.groupId.groupId,\n\t\t\t\"group\",\n\t\t\t\"The groupId sub-tree should have a groupId\",\n\t\t);\n\n\t\t// Validate \"groupId\" sub-tree.\n\t\tassert.strictEqual(\n\t\t\tbaseSnapshot.trees.default.trees.groupId.groupId,\n\t\t\t\"group\",\n\t\t\t\"The groupId sub-tree should have a groupId\",\n\t\t);\n\t});\n});\n"]}
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { strict as assert } from "assert";
6
- import { runSingle } from "../utils.js";
6
+ import { getDocumentAttributes, runSingle } from "../utils.js";
7
7
  describe("container-loader utils", () => {
8
8
  describe("runSingle", () => {
9
9
  it("correctly calls internal func", async () => {
@@ -27,5 +27,70 @@ describe("container-loader utils", () => {
27
27
  .catch((e) => assert.strictEqual(e.message, "Subsequent calls cannot use different arguments."));
28
28
  });
29
29
  });
30
+ describe("getDocumentAttributes", () => {
31
+ it("returns default attributes when tree is undefined", async () => {
32
+ const storageMock = {
33
+ readBlob: async () => new ArrayBuffer(0),
34
+ };
35
+ const attributes = await getDocumentAttributes(storageMock, undefined);
36
+ assert.deepEqual(attributes, {
37
+ minimumSequenceNumber: 0,
38
+ sequenceNumber: 0,
39
+ });
40
+ });
41
+ it("returns attributes from the tree", async () => {
42
+ const tree = {
43
+ blobs: {
44
+ ".attributes": "someKey",
45
+ },
46
+ trees: {},
47
+ };
48
+ const expectedAttributes = {
49
+ minimumSequenceNumber: 10,
50
+ sequenceNumber: 20,
51
+ };
52
+ const storageMock = {
53
+ readBlob: async (key) => {
54
+ if (key === "someKey") {
55
+ const jsonStr = JSON.stringify(expectedAttributes);
56
+ return new TextEncoder().encode(jsonStr).buffer;
57
+ }
58
+ throw new Error("Wrong key");
59
+ },
60
+ };
61
+ const attributes = await getDocumentAttributes(storageMock, tree);
62
+ assert.strictEqual(attributes.minimumSequenceNumber, 10);
63
+ assert.strictEqual(attributes.sequenceNumber, 20);
64
+ });
65
+ it("returns attributes from previous tree format", async () => {
66
+ const tree = {
67
+ trees: {
68
+ ".protocol": {
69
+ blobs: {
70
+ attributes: "someKey",
71
+ },
72
+ trees: {},
73
+ },
74
+ },
75
+ blobs: {},
76
+ };
77
+ const expectedAttributes = {
78
+ minimumSequenceNumber: 10,
79
+ sequenceNumber: 20,
80
+ };
81
+ const storageMock = {
82
+ readBlob: async (key) => {
83
+ if (key === "someKey") {
84
+ const jsonStr = JSON.stringify(expectedAttributes);
85
+ return new TextEncoder().encode(jsonStr).buffer;
86
+ }
87
+ throw new Error("Wrong key");
88
+ },
89
+ };
90
+ const attributes = await getDocumentAttributes(storageMock, tree);
91
+ assert.strictEqual(attributes.minimumSequenceNumber, 10);
92
+ assert.strictEqual(attributes.sequenceNumber, 20);
93
+ });
94
+ });
30
95
  });
31
96
  //# sourceMappingURL=utils.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.spec.js","sourceRoot":"","sources":["../../src/test/utils.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACvC,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;YAC9C,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,EAAE,IAAY,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;YAEjF,MAAM,CAAC,WAAW,CAAC,MAAM,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;YACnD,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,EAAE,IAAY,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;YAEjF,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAExD,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAC3B,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;YAChC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACzC,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,EAAE,IAAY,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;YAEjF,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAExD,MAAM,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAC9B,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;YAChC,MAAM,EAAE;iBACN,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;iBACtC,KAAK,CAAC,CAAC,CAAQ,EAAE,EAAE,CACnB,MAAM,CAAC,WAAW,CACjB,CAAC,CAAC,OAAO,EACT,kDAAkD,CAClD,CACD,CAAC;QACJ,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"assert\";\nimport { runSingle } from \"../utils.js\";\n\ndescribe(\"container-loader utils\", () => {\n\tdescribe(\"runSingle\", () => {\n\t\tit(\"correctly calls internal func\", async () => {\n\t\t\tconst wrappedFunc = runSingle(async (base: number, plus: number) => base + plus);\n\n\t\t\tassert.strictEqual(await wrappedFunc(4, 1), 5);\n\t\t});\n\n\t\tit(\"returns same promise for same args\", async () => {\n\t\t\tconst wrappedFunc = runSingle(async (base: number, plus: number) => base + plus);\n\n\t\t\tconst [p1, p2] = [wrappedFunc(4, 1), wrappedFunc(4, 1)];\n\n\t\t\tassert.strictEqual(p2, p1);\n\t\t\tassert.strictEqual(await p1, 5);\n\t\t\tassert.strictEqual(await p2, 5);\n\t\t});\n\n\t\tit(\"fails for different args\", async () => {\n\t\t\tconst wrappedFunc = runSingle(async (base: number, plus: number) => base + plus);\n\n\t\t\tconst [p1, p2] = [wrappedFunc(4, 1), wrappedFunc(4, 2)];\n\n\t\t\tassert.notStrictEqual(p2, p1);\n\t\t\tassert.strictEqual(await p1, 5);\n\t\t\tawait p2\n\t\t\t\t.then(() => assert.fail(\"should fail\"))\n\t\t\t\t.catch((e: Error) =>\n\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\te.message,\n\t\t\t\t\t\t\"Subsequent calls cannot use different arguments.\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t});\n\t});\n});\n"]}
1
+ {"version":3,"file":"utils.spec.js","sourceRoot":"","sources":["../../src/test/utils.spec.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 { strict as assert } from \"assert\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { IDocumentAttributes, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { getDocumentAttributes, runSingle } from \"../utils.js\";\n\ndescribe(\"container-loader utils\", () => {\n\tdescribe(\"runSingle\", () => {\n\t\tit(\"correctly calls internal func\", async () => {\n\t\t\tconst wrappedFunc = runSingle(async (base: number, plus: number) => base + plus);\n\n\t\t\tassert.strictEqual(await wrappedFunc(4, 1), 5);\n\t\t});\n\n\t\tit(\"returns same promise for same args\", async () => {\n\t\t\tconst wrappedFunc = runSingle(async (base: number, plus: number) => base + plus);\n\n\t\t\tconst [p1, p2] = [wrappedFunc(4, 1), wrappedFunc(4, 1)];\n\n\t\t\tassert.strictEqual(p2, p1);\n\t\t\tassert.strictEqual(await p1, 5);\n\t\t\tassert.strictEqual(await p2, 5);\n\t\t});\n\n\t\tit(\"fails for different args\", async () => {\n\t\t\tconst wrappedFunc = runSingle(async (base: number, plus: number) => base + plus);\n\n\t\t\tconst [p1, p2] = [wrappedFunc(4, 1), wrappedFunc(4, 2)];\n\n\t\t\tassert.notStrictEqual(p2, p1);\n\t\t\tassert.strictEqual(await p1, 5);\n\t\t\tawait p2\n\t\t\t\t.then(() => assert.fail(\"should fail\"))\n\t\t\t\t.catch((e: Error) =>\n\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\te.message,\n\t\t\t\t\t\t\"Subsequent calls cannot use different arguments.\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t});\n\t});\n\n\tdescribe(\"getDocumentAttributes\", () => {\n\t\tit(\"returns default attributes when tree is undefined\", async () => {\n\t\t\tconst storageMock: Pick<IDocumentStorageService, \"readBlob\"> = {\n\t\t\t\treadBlob: async () => new ArrayBuffer(0),\n\t\t\t};\n\n\t\t\tconst attributes = await getDocumentAttributes(storageMock, undefined);\n\n\t\t\tassert.deepEqual(attributes, {\n\t\t\t\tminimumSequenceNumber: 0,\n\t\t\t\tsequenceNumber: 0,\n\t\t\t});\n\t\t});\n\n\t\tit(\"returns attributes from the tree\", async () => {\n\t\t\tconst tree: ISnapshotTree = {\n\t\t\t\tblobs: {\n\t\t\t\t\t\".attributes\": \"someKey\",\n\t\t\t\t},\n\t\t\t\ttrees: {},\n\t\t\t};\n\n\t\t\tconst expectedAttributes: IDocumentAttributes = {\n\t\t\t\tminimumSequenceNumber: 10,\n\t\t\t\tsequenceNumber: 20,\n\t\t\t};\n\n\t\t\tconst storageMock: Pick<IDocumentStorageService, \"readBlob\"> = {\n\t\t\t\treadBlob: async (key: string) => {\n\t\t\t\t\tif (key === \"someKey\") {\n\t\t\t\t\t\tconst jsonStr = JSON.stringify(expectedAttributes);\n\t\t\t\t\t\treturn new TextEncoder().encode(jsonStr).buffer;\n\t\t\t\t\t}\n\t\t\t\t\tthrow new Error(\"Wrong key\");\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tconst attributes = await getDocumentAttributes(storageMock, tree);\n\n\t\t\tassert.strictEqual(attributes.minimumSequenceNumber, 10);\n\t\t\tassert.strictEqual(attributes.sequenceNumber, 20);\n\t\t});\n\n\t\tit(\"returns attributes from previous tree format\", async () => {\n\t\t\tconst tree: ISnapshotTree = {\n\t\t\t\ttrees: {\n\t\t\t\t\t\".protocol\": {\n\t\t\t\t\t\tblobs: {\n\t\t\t\t\t\t\tattributes: \"someKey\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttrees: {},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tblobs: {},\n\t\t\t};\n\n\t\t\tconst expectedAttributes: IDocumentAttributes = {\n\t\t\t\tminimumSequenceNumber: 10,\n\t\t\t\tsequenceNumber: 20,\n\t\t\t};\n\n\t\t\tconst storageMock: Pick<IDocumentStorageService, \"readBlob\"> = {\n\t\t\t\treadBlob: async (key: string) => {\n\t\t\t\t\tif (key === \"someKey\") {\n\t\t\t\t\t\tconst jsonStr = JSON.stringify(expectedAttributes);\n\t\t\t\t\t\treturn new TextEncoder().encode(jsonStr).buffer;\n\t\t\t\t\t}\n\t\t\t\t\tthrow new Error(\"Wrong key\");\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tconst attributes = await getDocumentAttributes(storageMock, tree);\n\n\t\t\tassert.strictEqual(attributes.minimumSequenceNumber, 10);\n\t\t\tassert.strictEqual(attributes.sequenceNumber, 20);\n\t\t});\n\t});\n});\n"]}
package/lib/utils.d.ts CHANGED
@@ -2,10 +2,11 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { ISummaryTree, ISnapshotTree } from "@fluidframework/protocol-definitions";
5
+ import { IDocumentStorageService } from "@fluidframework/driver-definitions";
6
6
  import { CombinedAppAndProtocolSummary, DeltaStreamConnectionForbiddenError } from "@fluidframework/driver-utils";
7
+ import { IDocumentAttributes, ISnapshotTree, ISummaryTree } from "@fluidframework/protocol-definitions";
7
8
  import { ISerializableBlobContents } from "./containerStorageAdapter.js";
8
- import { IPendingDetachedContainerState } from "./container.js";
9
+ import type { IPendingDetachedContainerState, SnapshotWithBlobs } from "./serializedStateManager.js";
9
10
  export interface ISnapshotTreeWithBlobContents extends ISnapshotTree {
10
11
  blobsContents: {
11
12
  [path: string]: ArrayBufferLike;
@@ -56,10 +57,7 @@ export declare function tryParseCompatibleResolvedUrl(url: string): IParsedUrl |
56
57
  * @internal
57
58
  */
58
59
  export declare function combineAppAndProtocolSummary(appSummary: ISummaryTree, protocolSummary: ISummaryTree): CombinedAppAndProtocolSummary;
59
- export declare const getSnapshotTreeAndBlobsFromSerializedContainer: (detachedContainerSnapshot: ISummaryTree) => {
60
- tree: ISnapshotTree;
61
- blobs: ISerializableBlobContents;
62
- };
60
+ export declare const getSnapshotTreeAndBlobsFromSerializedContainer: (detachedContainerSnapshot: ISummaryTree) => SnapshotWithBlobs;
63
61
  export declare function getProtocolSnapshotTree(snapshot: ISnapshotTree): ISnapshotTree;
64
62
  export declare const combineSnapshotTreeAndSnapshotBlobs: (baseSnapshot: ISnapshotTree, snapshotBlobs: ISerializableBlobContents) => ISnapshotTreeWithBlobContents;
65
63
  export declare function isDeltaStreamConnectionForbiddenError(error: any): error is DeltaStreamConnectionForbiddenError;
@@ -69,4 +67,5 @@ export declare function getDetachedContainerStateFromSerializedContainer(seriali
69
67
  * If there are multiple calls they will all get the same promise to wait on.
70
68
  */
71
69
  export declare const runSingle: <A extends any[], R>(func: (...args: A) => Promise<R>) => (...args: A) => Promise<R>;
70
+ export declare function getDocumentAttributes(storage: Pick<IDocumentStorageService, "readBlob">, tree: ISnapshotTree | undefined): Promise<IDocumentAttributes>;
72
71
  //# sourceMappingURL=utils.d.ts.map