@fluidframework/odsp-driver 2.0.0-dev-rc.1.0.0.232845 → 2.0.0-dev-rc.2.0.0.246488
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +18 -3
- package/{.mocharc.js → .mocharc.cjs} +1 -1
- package/CHANGELOG.md +44 -0
- package/{api-extractor-esm.json → api-extractor-cjs.json} +5 -1
- package/api-extractor-lint.json +1 -1
- package/api-extractor.json +1 -1
- package/api-report/odsp-driver.api.md +11 -12
- package/dist/ReadBufferUtils.d.ts.map +1 -1
- package/dist/ReadBufferUtils.js.map +1 -1
- package/dist/WriteBufferUtils.d.ts +1 -1
- package/dist/WriteBufferUtils.d.ts.map +1 -1
- package/dist/WriteBufferUtils.js +12 -12
- package/dist/WriteBufferUtils.js.map +1 -1
- package/dist/checkUrl.d.ts.map +1 -1
- package/dist/checkUrl.js +5 -3
- package/dist/checkUrl.js.map +1 -1
- package/dist/compactSnapshotParser.d.ts.map +1 -1
- package/dist/compactSnapshotParser.js +87 -69
- package/dist/compactSnapshotParser.js.map +1 -1
- package/dist/compactSnapshotWriter.d.ts.map +1 -1
- package/dist/compactSnapshotWriter.js +25 -19
- package/dist/compactSnapshotWriter.js.map +1 -1
- package/dist/contracts.d.ts +10 -4
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/createFile.d.ts +3 -3
- package/dist/createFile.d.ts.map +1 -1
- package/dist/createFile.js +30 -27
- package/dist/createFile.js.map +1 -1
- package/dist/createNewContainerOnExistingFile.d.ts +2 -2
- package/dist/createNewContainerOnExistingFile.d.ts.map +1 -1
- package/dist/createNewContainerOnExistingFile.js +14 -14
- package/dist/createNewContainerOnExistingFile.js.map +1 -1
- package/dist/createNewModule.d.ts +2 -2
- package/dist/createNewModule.d.ts.map +1 -1
- package/dist/createNewModule.js +4 -4
- package/dist/createNewModule.js.map +1 -1
- package/dist/createNewUtils.d.ts +2 -2
- package/dist/createNewUtils.d.ts.map +1 -1
- package/dist/createNewUtils.js +12 -8
- package/dist/createNewUtils.js.map +1 -1
- package/dist/createOdspCreateContainerRequest.d.ts.map +1 -1
- package/dist/createOdspCreateContainerRequest.js +6 -2
- package/dist/createOdspCreateContainerRequest.js.map +1 -1
- package/dist/createOdspUrl.d.ts +1 -1
- package/dist/createOdspUrl.d.ts.map +1 -1
- package/dist/createOdspUrl.js.map +1 -1
- package/dist/epochTracker.d.ts +10 -9
- package/dist/epochTracker.d.ts.map +1 -1
- package/dist/epochTracker.js +66 -43
- package/dist/epochTracker.js.map +1 -1
- package/dist/fetchSnapshot.d.ts +11 -8
- package/dist/fetchSnapshot.d.ts.map +1 -1
- package/dist/fetchSnapshot.js +79 -58
- package/dist/fetchSnapshot.js.map +1 -1
- package/dist/getFileLink.d.ts.map +1 -1
- package/dist/getFileLink.js +24 -17
- package/dist/getFileLink.js.map +1 -1
- package/dist/getQueryString.d.ts.map +1 -1
- package/dist/getQueryString.js +6 -0
- package/dist/getQueryString.js.map +1 -1
- package/dist/index.d.ts +19 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +44 -44
- package/dist/index.js.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentService.d.ts +1 -1
- package/dist/localOdspDriver/localOdspDocumentService.d.ts.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentService.js +5 -5
- package/dist/localOdspDriver/localOdspDocumentService.js.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentServiceFactory.d.ts +8 -6
- package/dist/localOdspDriver/localOdspDocumentServiceFactory.d.ts.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentServiceFactory.js +10 -9
- package/dist/localOdspDriver/localOdspDocumentServiceFactory.js.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentStorageManager.d.ts +1 -1
- package/dist/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentStorageManager.js +6 -6
- package/dist/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -1
- package/dist/odsp-driver-alpha.d.ts +27 -12
- package/dist/odsp-driver-beta.d.ts +1 -2
- package/dist/odsp-driver-public.d.ts +1 -2
- package/dist/odsp-driver-untrimmed.d.ts +29 -12
- package/dist/odspCache.d.ts +3 -3
- package/dist/odspCache.d.ts.map +1 -1
- package/dist/odspCache.js +3 -4
- package/dist/odspCache.js.map +1 -1
- package/dist/odspDelayLoadedDeltaStream.d.ts +7 -5
- package/dist/odspDelayLoadedDeltaStream.d.ts.map +1 -1
- package/dist/odspDelayLoadedDeltaStream.js +41 -28
- package/dist/odspDelayLoadedDeltaStream.js.map +1 -1
- package/dist/odspDeltaStorageService.d.ts +7 -7
- package/dist/odspDeltaStorageService.d.ts.map +1 -1
- package/dist/odspDeltaStorageService.js +5 -5
- package/dist/odspDeltaStorageService.js.map +1 -1
- package/dist/odspDocumentDeltaConnection.d.ts +1 -1
- package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/dist/odspDocumentDeltaConnection.js +41 -23
- package/dist/odspDocumentDeltaConnection.js.map +1 -1
- package/dist/odspDocumentService.d.ts +6 -4
- package/dist/odspDocumentService.d.ts.map +1 -1
- package/dist/odspDocumentService.js +19 -16
- package/dist/odspDocumentService.js.map +1 -1
- package/dist/odspDocumentServiceFactory.d.ts +6 -1
- package/dist/odspDocumentServiceFactory.d.ts.map +1 -1
- package/dist/odspDocumentServiceFactory.js +9 -4
- package/dist/odspDocumentServiceFactory.js.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.d.ts +4 -4
- package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.js +26 -22
- package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
- package/dist/odspDocumentServiceFactoryWithCodeSplit.d.ts +1 -1
- package/dist/odspDocumentServiceFactoryWithCodeSplit.d.ts.map +1 -1
- package/dist/odspDocumentServiceFactoryWithCodeSplit.js +2 -2
- package/dist/odspDocumentServiceFactoryWithCodeSplit.js.map +1 -1
- package/dist/odspDocumentStorageManager.d.ts +15 -9
- package/dist/odspDocumentStorageManager.d.ts.map +1 -1
- package/dist/odspDocumentStorageManager.js +219 -181
- package/dist/odspDocumentStorageManager.js.map +1 -1
- package/dist/odspDocumentStorageServiceBase.d.ts +2 -4
- package/dist/odspDocumentStorageServiceBase.d.ts.map +1 -1
- package/dist/odspDocumentStorageServiceBase.js +32 -29
- package/dist/odspDocumentStorageServiceBase.js.map +1 -1
- package/dist/odspDriverUrlResolver.d.ts +5 -1
- package/dist/odspDriverUrlResolver.d.ts.map +1 -1
- package/dist/odspDriverUrlResolver.js +27 -24
- package/dist/odspDriverUrlResolver.js.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.d.ts +17 -6
- package/dist/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.js +49 -39
- package/dist/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/dist/odspError.d.ts +1 -1
- package/dist/odspError.d.ts.map +1 -1
- package/dist/odspError.js +5 -5
- package/dist/odspError.js.map +1 -1
- package/dist/odspFluidFileLink.d.ts +1 -1
- package/dist/odspFluidFileLink.d.ts.map +1 -1
- package/dist/odspFluidFileLink.js +2 -2
- package/dist/odspFluidFileLink.js.map +1 -1
- package/dist/odspLocationRedirection.js +2 -2
- package/dist/odspLocationRedirection.js.map +1 -1
- package/dist/odspPublicUtils.d.ts +3 -0
- package/dist/odspPublicUtils.d.ts.map +1 -1
- package/dist/odspPublicUtils.js +3 -0
- package/dist/odspPublicUtils.js.map +1 -1
- package/dist/odspSnapshotParser.d.ts +1 -1
- package/dist/odspSnapshotParser.d.ts.map +1 -1
- package/dist/odspSnapshotParser.js +3 -2
- package/dist/odspSnapshotParser.js.map +1 -1
- package/dist/odspSummaryUploadManager.d.ts +1 -1
- package/dist/odspSummaryUploadManager.d.ts.map +1 -1
- package/dist/odspSummaryUploadManager.js +9 -6
- package/dist/odspSummaryUploadManager.js.map +1 -1
- package/dist/odspUrlHelper.d.ts.map +1 -1
- package/dist/odspUrlHelper.js +1 -2
- package/dist/odspUrlHelper.js.map +1 -1
- package/dist/odspUtils.d.ts +19 -7
- package/dist/odspUtils.d.ts.map +1 -1
- package/dist/odspUtils.js +61 -31
- package/dist/odspUtils.js.map +1 -1
- package/dist/opsCaching.d.ts +1 -1
- package/dist/opsCaching.d.ts.map +1 -1
- package/dist/opsCaching.js +2 -1
- package/dist/opsCaching.js.map +1 -1
- package/dist/package.json +3 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/prefetchLatestSnapshot.d.ts +2 -2
- package/dist/prefetchLatestSnapshot.d.ts.map +1 -1
- package/dist/prefetchLatestSnapshot.js +17 -12
- package/dist/prefetchLatestSnapshot.js.map +1 -1
- package/dist/retryErrorsStorageAdapter.d.ts +0 -1
- package/dist/retryErrorsStorageAdapter.d.ts.map +1 -1
- package/dist/retryErrorsStorageAdapter.js +2 -5
- package/dist/retryErrorsStorageAdapter.js.map +1 -1
- package/dist/retryUtils.d.ts.map +1 -1
- package/dist/retryUtils.js +6 -2
- package/dist/retryUtils.js.map +1 -1
- package/dist/socketModule.d.ts.map +1 -1
- package/dist/socketModule.js +2 -0
- package/dist/socketModule.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/vroom.d.ts +2 -2
- package/dist/vroom.d.ts.map +1 -1
- package/dist/vroom.js +5 -5
- package/dist/vroom.js.map +1 -1
- package/dist/zipItDataRepresentationUtils.d.ts +1 -1
- package/dist/zipItDataRepresentationUtils.d.ts.map +1 -1
- package/dist/zipItDataRepresentationUtils.js +15 -11
- package/dist/zipItDataRepresentationUtils.js.map +1 -1
- package/lib/{ReadBufferUtils.d.mts → ReadBufferUtils.d.ts} +1 -1
- package/lib/ReadBufferUtils.d.ts.map +1 -0
- package/lib/{ReadBufferUtils.mjs → ReadBufferUtils.js} +1 -1
- package/lib/ReadBufferUtils.js.map +1 -0
- package/lib/{WriteBufferUtils.d.mts → WriteBufferUtils.d.ts} +2 -2
- package/lib/WriteBufferUtils.d.ts.map +1 -0
- package/lib/{WriteBufferUtils.mjs → WriteBufferUtils.js} +2 -2
- package/lib/WriteBufferUtils.js.map +1 -0
- package/lib/{checkUrl.d.mts → checkUrl.d.ts} +1 -1
- package/lib/checkUrl.d.ts.map +1 -0
- package/lib/{checkUrl.mjs → checkUrl.js} +5 -3
- package/lib/checkUrl.js.map +1 -0
- package/lib/{compactSnapshotParser.d.mts → compactSnapshotParser.d.ts} +1 -1
- package/lib/compactSnapshotParser.d.ts.map +1 -0
- package/lib/{compactSnapshotParser.mjs → compactSnapshotParser.js} +61 -43
- package/lib/compactSnapshotParser.js.map +1 -0
- package/lib/{compactSnapshotWriter.d.mts → compactSnapshotWriter.d.ts} +1 -1
- package/lib/compactSnapshotWriter.d.ts.map +1 -0
- package/lib/{compactSnapshotWriter.mjs → compactSnapshotWriter.js} +13 -7
- package/lib/compactSnapshotWriter.js.map +1 -0
- package/lib/{constants.d.mts → constants.d.ts} +1 -1
- package/lib/constants.d.ts.map +1 -0
- package/lib/{constants.mjs → constants.js} +1 -1
- package/lib/constants.js.map +1 -0
- package/lib/{contracts.d.mts → contracts.d.ts} +11 -5
- package/lib/contracts.d.ts.map +1 -0
- package/lib/{contracts.mjs → contracts.js} +1 -1
- package/lib/contracts.js.map +1 -0
- package/lib/{contractsPublic.d.mts → contractsPublic.d.ts} +1 -1
- package/lib/contractsPublic.d.ts.map +1 -0
- package/lib/{contractsPublic.mjs → contractsPublic.js} +1 -1
- package/lib/contractsPublic.js.map +1 -0
- package/lib/{createFile.d.mts → createFile.d.ts} +4 -4
- package/lib/createFile.d.ts.map +1 -0
- package/lib/{createFile.mjs → createFile.js} +15 -12
- package/lib/createFile.js.map +1 -0
- package/lib/{createNewContainerOnExistingFile.d.mts → createNewContainerOnExistingFile.d.ts} +3 -3
- package/lib/createNewContainerOnExistingFile.d.ts.map +1 -0
- package/lib/{createNewContainerOnExistingFile.mjs → createNewContainerOnExistingFile.js} +7 -7
- package/lib/createNewContainerOnExistingFile.js.map +1 -0
- package/lib/{createNewModule.mjs → createNewModule.d.ts} +3 -3
- package/lib/createNewModule.d.ts.map +1 -0
- package/lib/{createNewModule.d.mts → createNewModule.js} +3 -3
- package/lib/createNewModule.js.map +1 -0
- package/lib/{createNewUtils.d.mts → createNewUtils.d.ts} +3 -3
- package/lib/createNewUtils.d.ts.map +1 -0
- package/lib/{createNewUtils.mjs → createNewUtils.js} +9 -5
- package/lib/createNewUtils.js.map +1 -0
- package/lib/{createOdspCreateContainerRequest.d.mts → createOdspCreateContainerRequest.d.ts} +5 -1
- package/lib/createOdspCreateContainerRequest.d.ts.map +1 -0
- package/lib/{createOdspCreateContainerRequest.mjs → createOdspCreateContainerRequest.js} +6 -2
- package/lib/createOdspCreateContainerRequest.js.map +1 -0
- package/lib/{createOdspUrl.d.mts → createOdspUrl.d.ts} +2 -2
- package/lib/createOdspUrl.d.ts.map +1 -0
- package/lib/{createOdspUrl.mjs → createOdspUrl.js} +1 -1
- package/lib/createOdspUrl.js.map +1 -0
- package/lib/{epochTracker.d.mts → epochTracker.d.ts} +11 -10
- package/lib/epochTracker.d.ts.map +1 -0
- package/lib/{epochTracker.mjs → epochTracker.js} +56 -33
- package/lib/epochTracker.js.map +1 -0
- package/lib/{fetch.d.mts → fetch.d.ts} +1 -1
- package/lib/fetch.d.ts.map +1 -0
- package/lib/{fetch.mjs → fetch.js} +1 -1
- package/lib/fetch.js.map +1 -0
- package/lib/{fetchSnapshot.d.mts → fetchSnapshot.d.ts} +12 -9
- package/lib/fetchSnapshot.d.ts.map +1 -0
- package/lib/{fetchSnapshot.mjs → fetchSnapshot.js} +61 -40
- package/lib/fetchSnapshot.js.map +1 -0
- package/lib/{getFileLink.d.mts → getFileLink.d.ts} +1 -1
- package/lib/getFileLink.d.ts.map +1 -0
- package/lib/{getFileLink.mjs → getFileLink.js} +14 -7
- package/lib/getFileLink.js.map +1 -0
- package/lib/{getQueryString.d.mts → getQueryString.d.ts} +5 -1
- package/lib/getQueryString.d.ts.map +1 -0
- package/lib/{getQueryString.mjs → getQueryString.js} +7 -1
- package/lib/getQueryString.js.map +1 -0
- package/lib/{getUrlAndHeadersWithAuth.d.mts → getUrlAndHeadersWithAuth.d.ts} +1 -1
- package/lib/getUrlAndHeadersWithAuth.d.ts.map +1 -0
- package/lib/{getUrlAndHeadersWithAuth.mjs → getUrlAndHeadersWithAuth.js} +1 -1
- package/lib/getUrlAndHeadersWithAuth.js.map +1 -0
- package/lib/{index.d.mts → index.d.ts} +20 -20
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +29 -0
- package/lib/index.js.map +1 -0
- package/lib/localOdspDriver/{localOdspDeltaStorageService.d.mts → localOdspDeltaStorageService.d.ts} +1 -1
- package/lib/localOdspDriver/localOdspDeltaStorageService.d.ts.map +1 -0
- package/lib/localOdspDriver/{localOdspDeltaStorageService.mjs → localOdspDeltaStorageService.js} +1 -1
- package/lib/localOdspDriver/localOdspDeltaStorageService.js.map +1 -0
- package/lib/localOdspDriver/{localOdspDocumentService.d.mts → localOdspDocumentService.d.ts} +2 -2
- package/lib/localOdspDriver/localOdspDocumentService.d.ts.map +1 -0
- package/lib/localOdspDriver/{localOdspDocumentService.mjs → localOdspDocumentService.js} +4 -4
- package/lib/localOdspDriver/localOdspDocumentService.js.map +1 -0
- package/lib/localOdspDriver/{localOdspDocumentServiceFactory.d.mts → localOdspDocumentServiceFactory.d.ts} +9 -7
- package/lib/localOdspDriver/localOdspDocumentServiceFactory.d.ts.map +1 -0
- package/lib/localOdspDriver/{localOdspDocumentServiceFactory.mjs → localOdspDocumentServiceFactory.js} +9 -8
- package/lib/localOdspDriver/localOdspDocumentServiceFactory.js.map +1 -0
- package/lib/localOdspDriver/{localOdspDocumentStorageManager.d.mts → localOdspDocumentStorageManager.d.ts} +2 -2
- package/lib/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -0
- package/lib/localOdspDriver/{localOdspDocumentStorageManager.mjs → localOdspDocumentStorageManager.js} +4 -4
- package/lib/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -0
- package/lib/{odsp-driver-alpha.d.mts → odsp-driver-alpha.d.ts} +27 -12
- package/lib/{odsp-driver-public.d.mts → odsp-driver-beta.d.ts} +1 -2
- package/lib/{odsp-driver-beta.d.mts → odsp-driver-public.d.ts} +1 -2
- package/lib/{odsp-driver-untrimmed.d.mts → odsp-driver-untrimmed.d.ts} +29 -12
- package/lib/{odspCache.d.mts → odspCache.d.ts} +8 -4
- package/lib/odspCache.d.ts.map +1 -0
- package/lib/{odspCache.mjs → odspCache.js} +6 -3
- package/lib/odspCache.js.map +1 -0
- package/lib/{odspDelayLoadedDeltaStream.d.mts → odspDelayLoadedDeltaStream.d.ts} +8 -6
- package/lib/odspDelayLoadedDeltaStream.d.ts.map +1 -0
- package/lib/{odspDelayLoadedDeltaStream.mjs → odspDelayLoadedDeltaStream.js} +33 -20
- package/lib/odspDelayLoadedDeltaStream.js.map +1 -0
- package/lib/{odspDeltaStorageService.d.mts → odspDeltaStorageService.d.ts} +8 -8
- package/lib/odspDeltaStorageService.d.ts.map +1 -0
- package/lib/{odspDeltaStorageService.mjs → odspDeltaStorageService.js} +5 -5
- package/lib/odspDeltaStorageService.js.map +1 -0
- package/lib/{odspDocumentDeltaConnection.d.mts → odspDocumentDeltaConnection.d.ts} +2 -2
- package/lib/odspDocumentDeltaConnection.d.ts.map +1 -0
- package/lib/{odspDocumentDeltaConnection.mjs → odspDocumentDeltaConnection.js} +34 -16
- package/lib/odspDocumentDeltaConnection.js.map +1 -0
- package/lib/{odspDocumentService.d.mts → odspDocumentService.d.ts} +7 -5
- package/lib/odspDocumentService.d.ts.map +1 -0
- package/lib/{odspDocumentService.mjs → odspDocumentService.js} +16 -11
- package/lib/odspDocumentService.js.map +1 -0
- package/lib/{odspDocumentServiceFactory.d.mts → odspDocumentServiceFactory.d.ts} +7 -2
- package/lib/odspDocumentServiceFactory.d.ts.map +1 -0
- package/lib/{odspDocumentServiceFactory.mjs → odspDocumentServiceFactory.js} +9 -3
- package/lib/odspDocumentServiceFactory.js.map +1 -0
- package/lib/{odspDocumentServiceFactoryCore.d.mts → odspDocumentServiceFactoryCore.d.ts} +5 -5
- package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -0
- package/lib/{odspDocumentServiceFactoryCore.mjs → odspDocumentServiceFactoryCore.js} +23 -17
- package/lib/odspDocumentServiceFactoryCore.js.map +1 -0
- package/lib/{odspDocumentServiceFactoryWithCodeSplit.d.mts → odspDocumentServiceFactoryWithCodeSplit.d.ts} +2 -2
- package/lib/odspDocumentServiceFactoryWithCodeSplit.d.ts.map +1 -0
- package/lib/{odspDocumentServiceFactoryWithCodeSplit.mjs → odspDocumentServiceFactoryWithCodeSplit.js} +2 -2
- package/lib/odspDocumentServiceFactoryWithCodeSplit.js.map +1 -0
- package/lib/{odspDocumentStorageManager.d.mts → odspDocumentStorageManager.d.ts} +16 -10
- package/lib/odspDocumentStorageManager.d.ts.map +1 -0
- package/lib/{odspDocumentStorageManager.mjs → odspDocumentStorageManager.js} +207 -167
- package/lib/odspDocumentStorageManager.js.map +1 -0
- package/lib/{odspDocumentStorageServiceBase.d.mts → odspDocumentStorageServiceBase.d.ts} +3 -5
- package/lib/odspDocumentStorageServiceBase.d.ts.map +1 -0
- package/lib/{odspDocumentStorageServiceBase.mjs → odspDocumentStorageServiceBase.js} +32 -29
- package/lib/odspDocumentStorageServiceBase.js.map +1 -0
- package/lib/{odspDriverUrlResolver.d.mts → odspDriverUrlResolver.d.ts} +6 -2
- package/lib/odspDriverUrlResolver.d.ts.map +1 -0
- package/lib/{odspDriverUrlResolver.mjs → odspDriverUrlResolver.js} +24 -17
- package/lib/odspDriverUrlResolver.js.map +1 -0
- package/lib/{odspDriverUrlResolverForShareLink.d.mts → odspDriverUrlResolverForShareLink.d.ts} +18 -7
- package/lib/odspDriverUrlResolverForShareLink.d.ts.map +1 -0
- package/lib/{odspDriverUrlResolverForShareLink.mjs → odspDriverUrlResolverForShareLink.js} +41 -27
- package/lib/odspDriverUrlResolverForShareLink.js.map +1 -0
- package/lib/{odspError.d.mts → odspError.d.ts} +2 -2
- package/lib/odspError.d.ts.map +1 -0
- package/lib/{odspError.mjs → odspError.js} +4 -4
- package/lib/odspError.js.map +1 -0
- package/lib/{odspFluidFileLink.d.mts → odspFluidFileLink.d.ts} +2 -2
- package/lib/odspFluidFileLink.d.ts.map +1 -0
- package/lib/{odspFluidFileLink.mjs → odspFluidFileLink.js} +2 -2
- package/lib/odspFluidFileLink.js.map +1 -0
- package/lib/{odspLocationRedirection.d.mts → odspLocationRedirection.d.ts} +1 -1
- package/lib/odspLocationRedirection.d.ts.map +1 -0
- package/lib/{odspLocationRedirection.mjs → odspLocationRedirection.js} +2 -2
- package/lib/odspLocationRedirection.js.map +1 -0
- package/lib/{odspPublicUtils.d.mts → odspPublicUtils.d.ts} +4 -1
- package/lib/odspPublicUtils.d.ts.map +1 -0
- package/lib/{odspPublicUtils.mjs → odspPublicUtils.js} +4 -1
- package/lib/odspPublicUtils.js.map +1 -0
- package/lib/{odspSnapshotParser.d.mts → odspSnapshotParser.d.ts} +2 -2
- package/lib/odspSnapshotParser.d.ts.map +1 -0
- package/lib/{odspSnapshotParser.mjs → odspSnapshotParser.js} +4 -3
- package/lib/odspSnapshotParser.js.map +1 -0
- package/lib/{odspSummaryUploadManager.d.mts → odspSummaryUploadManager.d.ts} +2 -2
- package/lib/odspSummaryUploadManager.d.ts.map +1 -0
- package/lib/{odspSummaryUploadManager.mjs → odspSummaryUploadManager.js} +8 -5
- package/lib/odspSummaryUploadManager.js.map +1 -0
- package/lib/{odspUrlHelper.d.mts → odspUrlHelper.d.ts} +1 -1
- package/lib/odspUrlHelper.d.ts.map +1 -0
- package/lib/{odspUrlHelper.mjs → odspUrlHelper.js} +2 -3
- package/lib/odspUrlHelper.js.map +1 -0
- package/lib/{odspUtils.d.mts → odspUtils.d.ts} +20 -8
- package/lib/odspUtils.d.ts.map +1 -0
- package/lib/{odspUtils.mjs → odspUtils.js} +45 -17
- package/lib/odspUtils.js.map +1 -0
- package/lib/{opsCaching.d.mts → opsCaching.d.ts} +2 -2
- package/lib/opsCaching.d.ts.map +1 -0
- package/lib/{opsCaching.mjs → opsCaching.js} +3 -2
- package/lib/opsCaching.js.map +1 -0
- package/lib/{packageVersion.d.mts → packageVersion.d.ts} +2 -2
- package/lib/packageVersion.d.ts.map +1 -0
- package/lib/{packageVersion.mjs → packageVersion.js} +2 -2
- package/lib/packageVersion.js.map +1 -0
- package/lib/{prefetchLatestSnapshot.d.mts → prefetchLatestSnapshot.d.ts} +3 -3
- package/lib/prefetchLatestSnapshot.d.ts.map +1 -0
- package/lib/{prefetchLatestSnapshot.mjs → prefetchLatestSnapshot.js} +16 -11
- package/lib/prefetchLatestSnapshot.js.map +1 -0
- package/lib/{retryErrorsStorageAdapter.d.mts → retryErrorsStorageAdapter.d.ts} +1 -2
- package/lib/retryErrorsStorageAdapter.d.ts.map +1 -0
- package/lib/{retryErrorsStorageAdapter.mjs → retryErrorsStorageAdapter.js} +2 -5
- package/lib/retryErrorsStorageAdapter.js.map +1 -0
- package/lib/{retryUtils.d.mts → retryUtils.d.ts} +1 -1
- package/lib/retryUtils.d.ts.map +1 -0
- package/lib/{retryUtils.mjs → retryUtils.js} +6 -2
- package/lib/retryUtils.js.map +1 -0
- package/lib/{socketModule.d.mts → socketModule.d.ts} +1 -1
- package/lib/socketModule.d.ts.map +1 -0
- package/lib/{socketModule.mjs → socketModule.js} +3 -1
- package/lib/socketModule.js.map +1 -0
- package/lib/test/buildOdspShareLinkReqParams.spec.js +25 -0
- package/lib/test/buildOdspShareLinkReqParams.spec.js.map +1 -0
- package/lib/test/createNewUtilsTests.spec.js +221 -0
- package/lib/test/createNewUtilsTests.spec.js.map +1 -0
- package/lib/test/deltaStorageService.spec.js +176 -0
- package/lib/test/deltaStorageService.spec.js.map +1 -0
- package/lib/test/epochTests.spec.js +340 -0
- package/lib/test/epochTests.spec.js.map +1 -0
- package/lib/test/epochTestsWithRedemption.spec.js +119 -0
- package/lib/test/epochTestsWithRedemption.spec.js.map +1 -0
- package/lib/test/fetchSnapshot.spec.js +412 -0
- package/lib/test/fetchSnapshot.spec.js.map +1 -0
- package/lib/test/getFileLink.spec.js +62 -0
- package/lib/test/getFileLink.spec.js.map +1 -0
- package/lib/test/getUrlAndHeadersWithAuth.spec.js +66 -0
- package/lib/test/getUrlAndHeadersWithAuth.spec.js.map +1 -0
- package/lib/test/getVersions.spec.js +284 -0
- package/lib/test/getVersions.spec.js.map +1 -0
- package/lib/test/joinSessionCacheTests.spec.js +53 -0
- package/lib/test/joinSessionCacheTests.spec.js.map +1 -0
- package/lib/test/joinSessionPeriodicCall.spec.js +158 -0
- package/lib/test/joinSessionPeriodicCall.spec.js.map +1 -0
- package/lib/test/jsonSnapshotFormatTests.spec.js +107 -0
- package/lib/test/jsonSnapshotFormatTests.spec.js.map +1 -0
- package/lib/test/localOdspDriver.spec.js +177 -0
- package/lib/test/localOdspDriver.spec.js.map +1 -0
- package/lib/test/mockFetch.js +61 -0
- package/lib/test/mockFetch.js.map +1 -0
- package/lib/test/odspCreateContainer.spec.js +116 -0
- package/lib/test/odspCreateContainer.spec.js.map +1 -0
- package/lib/test/odspDriverResolverTest.spec.js +289 -0
- package/lib/test/odspDriverResolverTest.spec.js.map +1 -0
- package/lib/test/odspDriverUrlResolverForShareLink.spec.js +287 -0
- package/lib/test/odspDriverUrlResolverForShareLink.spec.js.map +1 -0
- package/lib/test/odspError.spec.js +299 -0
- package/lib/test/odspError.spec.js.map +1 -0
- package/lib/test/opsCaching.spec.js +357 -0
- package/lib/test/opsCaching.spec.js.map +1 -0
- package/lib/test/prefetchSnapshotTests.spec.js +420 -0
- package/lib/test/prefetchSnapshotTests.spec.js.map +1 -0
- package/lib/test/snapshotFormatTests.spec.js +218 -0
- package/lib/test/snapshotFormatTests.spec.js.map +1 -0
- package/lib/test/socketTests/deltaConnectionUpdateTests.spec.js +152 -0
- package/lib/test/socketTests/deltaConnectionUpdateTests.spec.js.map +1 -0
- package/lib/test/socketTests/socketMock.js +109 -0
- package/lib/test/socketTests/socketMock.js.map +1 -0
- package/lib/test/socketTests/socketTests.spec.js +256 -0
- package/lib/test/socketTests/socketTests.spec.js.map +1 -0
- package/lib/test/tokenFetch.spec.js +39 -0
- package/lib/test/tokenFetch.spec.js.map +1 -0
- package/lib/test/types/validateOdspDriverPrevious.generated.js +96 -0
- package/lib/test/types/validateOdspDriverPrevious.generated.js.map +1 -0
- package/lib/test/zipItDataRepresentationTests.spec.js +207 -0
- package/lib/test/zipItDataRepresentationTests.spec.js.map +1 -0
- package/lib/{vroom.d.mts → vroom.d.ts} +3 -3
- package/lib/vroom.d.ts.map +1 -0
- package/lib/{vroom.mjs → vroom.js} +4 -4
- package/lib/vroom.js.map +1 -0
- package/lib/{zipItDataRepresentationUtils.d.mts → zipItDataRepresentationUtils.d.ts} +2 -2
- package/lib/zipItDataRepresentationUtils.d.ts.map +1 -0
- package/lib/{zipItDataRepresentationUtils.mjs → zipItDataRepresentationUtils.js} +17 -9
- package/lib/zipItDataRepresentationUtils.js.map +1 -0
- package/package.json +90 -31
- package/src/ReadBufferUtils.ts +7 -7
- package/src/WriteBufferUtils.ts +13 -9
- package/src/checkUrl.ts +4 -2
- package/src/compactSnapshotParser.ts +87 -52
- package/src/compactSnapshotWriter.ts +19 -12
- package/src/contracts.ts +16 -4
- package/src/createFile.ts +16 -13
- package/src/createNewContainerOnExistingFile.ts +8 -8
- package/src/createNewModule.ts +2 -2
- package/src/createNewUtils.ts +19 -9
- package/src/createOdspCreateContainerRequest.ts +2 -1
- package/src/createOdspUrl.ts +1 -1
- package/src/epochTracker.ts +90 -55
- package/src/fetchSnapshot.ts +104 -47
- package/src/getFileLink.ts +21 -13
- package/src/getQueryString.ts +3 -0
- package/src/index.ts +27 -19
- package/src/localOdspDriver/localOdspDocumentService.ts +3 -3
- package/src/localOdspDriver/localOdspDocumentServiceFactory.ts +12 -11
- package/src/localOdspDriver/localOdspDocumentStorageManager.ts +5 -5
- package/src/odspCache.ts +13 -9
- package/src/odspDelayLoadedDeltaStream.ts +54 -33
- package/src/odspDeltaStorageService.ts +17 -16
- package/src/odspDocumentDeltaConnection.ts +52 -34
- package/src/odspDocumentService.ts +23 -20
- package/src/odspDocumentServiceFactory.ts +7 -2
- package/src/odspDocumentServiceFactoryCore.ts +25 -18
- package/src/odspDocumentServiceFactoryWithCodeSplit.ts +1 -1
- package/src/odspDocumentStorageManager.ts +276 -216
- package/src/odspDocumentStorageServiceBase.ts +45 -43
- package/src/odspDriverUrlResolver.ts +39 -24
- package/src/odspDriverUrlResolverForShareLink.ts +51 -31
- package/src/odspError.ts +4 -4
- package/src/odspFluidFileLink.ts +3 -3
- package/src/odspLocationRedirection.ts +1 -1
- package/src/odspPublicUtils.ts +3 -0
- package/src/odspSnapshotParser.ts +4 -3
- package/src/odspSummaryUploadManager.ts +21 -9
- package/src/odspUrlHelper.ts +2 -3
- package/src/odspUtils.ts +73 -30
- package/src/opsCaching.ts +13 -12
- package/src/packageVersion.ts +1 -1
- package/src/prefetchLatestSnapshot.ts +24 -15
- package/src/retryErrorsStorageAdapter.ts +4 -8
- package/src/retryUtils.ts +6 -2
- package/src/socketModule.ts +2 -0
- package/src/vroom.ts +6 -6
- package/src/zipItDataRepresentationUtils.ts +63 -35
- package/tsconfig.cjs.json +7 -0
- package/tsconfig.json +2 -5
- package/lib/ReadBufferUtils.d.mts.map +0 -1
- package/lib/ReadBufferUtils.mjs.map +0 -1
- package/lib/WriteBufferUtils.d.mts.map +0 -1
- package/lib/WriteBufferUtils.mjs.map +0 -1
- package/lib/checkUrl.d.mts.map +0 -1
- package/lib/checkUrl.mjs.map +0 -1
- package/lib/compactSnapshotParser.d.mts.map +0 -1
- package/lib/compactSnapshotParser.mjs.map +0 -1
- package/lib/compactSnapshotWriter.d.mts.map +0 -1
- package/lib/compactSnapshotWriter.mjs.map +0 -1
- package/lib/constants.d.mts.map +0 -1
- package/lib/constants.mjs.map +0 -1
- package/lib/contracts.d.mts.map +0 -1
- package/lib/contracts.mjs.map +0 -1
- package/lib/contractsPublic.d.mts.map +0 -1
- package/lib/contractsPublic.mjs.map +0 -1
- package/lib/createFile.d.mts.map +0 -1
- package/lib/createFile.mjs.map +0 -1
- package/lib/createNewContainerOnExistingFile.d.mts.map +0 -1
- package/lib/createNewContainerOnExistingFile.mjs.map +0 -1
- package/lib/createNewModule.d.mts.map +0 -1
- package/lib/createNewModule.mjs.map +0 -1
- package/lib/createNewUtils.d.mts.map +0 -1
- package/lib/createNewUtils.mjs.map +0 -1
- package/lib/createOdspCreateContainerRequest.d.mts.map +0 -1
- package/lib/createOdspCreateContainerRequest.mjs.map +0 -1
- package/lib/createOdspUrl.d.mts.map +0 -1
- package/lib/createOdspUrl.mjs.map +0 -1
- package/lib/epochTracker.d.mts.map +0 -1
- package/lib/epochTracker.mjs.map +0 -1
- package/lib/fetch.d.mts.map +0 -1
- package/lib/fetch.mjs.map +0 -1
- package/lib/fetchSnapshot.d.mts.map +0 -1
- package/lib/fetchSnapshot.mjs.map +0 -1
- package/lib/getFileLink.d.mts.map +0 -1
- package/lib/getFileLink.mjs.map +0 -1
- package/lib/getQueryString.d.mts.map +0 -1
- package/lib/getQueryString.mjs.map +0 -1
- package/lib/getUrlAndHeadersWithAuth.d.mts.map +0 -1
- package/lib/getUrlAndHeadersWithAuth.mjs.map +0 -1
- package/lib/index.d.mts.map +0 -1
- package/lib/index.mjs +0 -22
- package/lib/index.mjs.map +0 -1
- package/lib/localOdspDriver/localOdspDeltaStorageService.d.mts.map +0 -1
- package/lib/localOdspDriver/localOdspDeltaStorageService.mjs.map +0 -1
- package/lib/localOdspDriver/localOdspDocumentService.d.mts.map +0 -1
- package/lib/localOdspDriver/localOdspDocumentService.mjs.map +0 -1
- package/lib/localOdspDriver/localOdspDocumentServiceFactory.d.mts.map +0 -1
- package/lib/localOdspDriver/localOdspDocumentServiceFactory.mjs.map +0 -1
- package/lib/localOdspDriver/localOdspDocumentStorageManager.d.mts.map +0 -1
- package/lib/localOdspDriver/localOdspDocumentStorageManager.mjs.map +0 -1
- package/lib/odspCache.d.mts.map +0 -1
- package/lib/odspCache.mjs.map +0 -1
- package/lib/odspDelayLoadedDeltaStream.d.mts.map +0 -1
- package/lib/odspDelayLoadedDeltaStream.mjs.map +0 -1
- package/lib/odspDeltaStorageService.d.mts.map +0 -1
- package/lib/odspDeltaStorageService.mjs.map +0 -1
- package/lib/odspDocumentDeltaConnection.d.mts.map +0 -1
- package/lib/odspDocumentDeltaConnection.mjs.map +0 -1
- package/lib/odspDocumentService.d.mts.map +0 -1
- package/lib/odspDocumentService.mjs.map +0 -1
- package/lib/odspDocumentServiceFactory.d.mts.map +0 -1
- package/lib/odspDocumentServiceFactory.mjs.map +0 -1
- package/lib/odspDocumentServiceFactoryCore.d.mts.map +0 -1
- package/lib/odspDocumentServiceFactoryCore.mjs.map +0 -1
- package/lib/odspDocumentServiceFactoryWithCodeSplit.d.mts.map +0 -1
- package/lib/odspDocumentServiceFactoryWithCodeSplit.mjs.map +0 -1
- package/lib/odspDocumentStorageManager.d.mts.map +0 -1
- package/lib/odspDocumentStorageManager.mjs.map +0 -1
- package/lib/odspDocumentStorageServiceBase.d.mts.map +0 -1
- package/lib/odspDocumentStorageServiceBase.mjs.map +0 -1
- package/lib/odspDriverUrlResolver.d.mts.map +0 -1
- package/lib/odspDriverUrlResolver.mjs.map +0 -1
- package/lib/odspDriverUrlResolverForShareLink.d.mts.map +0 -1
- package/lib/odspDriverUrlResolverForShareLink.mjs.map +0 -1
- package/lib/odspError.d.mts.map +0 -1
- package/lib/odspError.mjs.map +0 -1
- package/lib/odspFluidFileLink.d.mts.map +0 -1
- package/lib/odspFluidFileLink.mjs.map +0 -1
- package/lib/odspLocationRedirection.d.mts.map +0 -1
- package/lib/odspLocationRedirection.mjs.map +0 -1
- package/lib/odspPublicUtils.d.mts.map +0 -1
- package/lib/odspPublicUtils.mjs.map +0 -1
- package/lib/odspSnapshotParser.d.mts.map +0 -1
- package/lib/odspSnapshotParser.mjs.map +0 -1
- package/lib/odspSummaryUploadManager.d.mts.map +0 -1
- package/lib/odspSummaryUploadManager.mjs.map +0 -1
- package/lib/odspUrlHelper.d.mts.map +0 -1
- package/lib/odspUrlHelper.mjs.map +0 -1
- package/lib/odspUtils.d.mts.map +0 -1
- package/lib/odspUtils.mjs.map +0 -1
- package/lib/opsCaching.d.mts.map +0 -1
- package/lib/opsCaching.mjs.map +0 -1
- package/lib/packageVersion.d.mts.map +0 -1
- package/lib/packageVersion.mjs.map +0 -1
- package/lib/prefetchLatestSnapshot.d.mts.map +0 -1
- package/lib/prefetchLatestSnapshot.mjs.map +0 -1
- package/lib/retryErrorsStorageAdapter.d.mts.map +0 -1
- package/lib/retryErrorsStorageAdapter.mjs.map +0 -1
- package/lib/retryUtils.d.mts.map +0 -1
- package/lib/retryUtils.mjs.map +0 -1
- package/lib/socketModule.d.mts.map +0 -1
- package/lib/socketModule.mjs.map +0 -1
- package/lib/vroom.d.mts.map +0 -1
- package/lib/vroom.mjs.map +0 -1
- package/lib/zipItDataRepresentationUtils.d.mts.map +0 -1
- package/lib/zipItDataRepresentationUtils.mjs.map +0 -1
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { strict as assert } from "node:assert";
|
|
6
|
+
import { MockLogger } from "@fluidframework/telemetry-utils";
|
|
7
|
+
import { delay } from "@fluidframework/core-utils";
|
|
8
|
+
import { OdspDeltaStorageWithCache } from "../odspDeltaStorageService.js";
|
|
9
|
+
import { OpsCache } from "../opsCaching.js";
|
|
10
|
+
class MockCache {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.writeCount = 0;
|
|
13
|
+
this.opsWritten = 0;
|
|
14
|
+
this.data = {};
|
|
15
|
+
}
|
|
16
|
+
async write(batchNumber, data) {
|
|
17
|
+
this.writeCount++;
|
|
18
|
+
this.data[batchNumber] = JSON.parse(data);
|
|
19
|
+
for (const op of this.data[batchNumber]) {
|
|
20
|
+
// JSON.serialize converts undefined to null
|
|
21
|
+
if (op !== null) {
|
|
22
|
+
this.opsWritten++;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async read(batchNumber) {
|
|
27
|
+
const content = this.data[batchNumber];
|
|
28
|
+
if (content === undefined) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
return JSON.stringify(content);
|
|
32
|
+
}
|
|
33
|
+
remove() {
|
|
34
|
+
// Do not reset this.writeCount such that we can test that writes happened, but later on data was cleared
|
|
35
|
+
this.writeCount++;
|
|
36
|
+
this.opsWritten++;
|
|
37
|
+
this.data = {};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function validate(mockCache, expected, cache, initialSeq) {
|
|
41
|
+
assert.deepEqual(mockCache.data, JSON.parse(JSON.stringify(expected)));
|
|
42
|
+
const expectedArr = [];
|
|
43
|
+
for (const values of Object.values(expected)) {
|
|
44
|
+
for (const op of values) {
|
|
45
|
+
if (op !== undefined) {
|
|
46
|
+
expectedArr.push(op);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
let result = await cache.get(initialSeq + 1, undefined);
|
|
51
|
+
assert.deepEqual(result, expectedArr);
|
|
52
|
+
if (initialSeq >= 10) {
|
|
53
|
+
result = await cache.get(1, 10);
|
|
54
|
+
assert(result.length === 0);
|
|
55
|
+
}
|
|
56
|
+
// Asking for one too early should result in empty result, as hit miss should result in no ops.
|
|
57
|
+
if (initialSeq > 0) {
|
|
58
|
+
result = await cache.get(initialSeq, undefined);
|
|
59
|
+
assert(result.length === 0);
|
|
60
|
+
}
|
|
61
|
+
if (expectedArr.length > 0) {
|
|
62
|
+
const last = expectedArr[expectedArr.length - 1].sequenceNumber + 1;
|
|
63
|
+
result = await cache.get(last, undefined);
|
|
64
|
+
assert(result.length === 0);
|
|
65
|
+
result = await cache.get(last + 10, undefined);
|
|
66
|
+
assert(result.length === 0);
|
|
67
|
+
result = await cache.get(initialSeq + 2, last);
|
|
68
|
+
assert.deepEqual(result, expectedArr.slice(1));
|
|
69
|
+
result = await cache.get(initialSeq + 2, last + 100000);
|
|
70
|
+
assert.deepEqual(result, expectedArr.slice(1));
|
|
71
|
+
result = await cache.get(initialSeq + 2, last - 1);
|
|
72
|
+
assert.deepEqual(result, expectedArr.slice(1, -1));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function runTestNoTimer(batchSize, initialSeq, mockData, expected, initialWritesExpected, totalOpsWritten) {
|
|
76
|
+
const mockCache = new MockCache();
|
|
77
|
+
const logger = new MockLogger();
|
|
78
|
+
const cache = new OpsCache(initialSeq, logger.toTelemetryLogger(), mockCache, batchSize, -1, // timerGranularity
|
|
79
|
+
10);
|
|
80
|
+
cache.addOps(mockData);
|
|
81
|
+
const writes = mockCache.writeCount;
|
|
82
|
+
assert.equal(writes, initialWritesExpected, "initialWrites should match");
|
|
83
|
+
// Validate that writing same ops is not going to change anything
|
|
84
|
+
cache.addOps(mockData);
|
|
85
|
+
assert.equal(writes, mockCache.writeCount);
|
|
86
|
+
await validate(mockCache, expected, cache, initialSeq);
|
|
87
|
+
// ensure all ops are flushed properly
|
|
88
|
+
cache.flushOps();
|
|
89
|
+
assert.equal(mockCache.opsWritten, totalOpsWritten ?? mockData.length);
|
|
90
|
+
// ensure adding same ops and flushing again is doing nothing
|
|
91
|
+
cache.addOps(mockData);
|
|
92
|
+
cache.flushOps();
|
|
93
|
+
assert.equal(mockCache.opsWritten, totalOpsWritten ?? mockData.length, "ops written does not match");
|
|
94
|
+
logger.assertMatchNone([{ category: "error" }]);
|
|
95
|
+
}
|
|
96
|
+
export async function runTestWithTimer(batchSize, initialSeq, mockData, expected, initialWritesExpected, totalWritesExpected, totalOpsWritten) {
|
|
97
|
+
const mockCache = new MockCache();
|
|
98
|
+
const logger = new MockLogger();
|
|
99
|
+
const cache = new OpsCache(initialSeq, logger.toTelemetryLogger(), mockCache, batchSize, 1, // timerGranularity
|
|
100
|
+
10);
|
|
101
|
+
cache.addOps(mockData);
|
|
102
|
+
assert.equal(mockCache.writeCount, initialWritesExpected);
|
|
103
|
+
await validate(mockCache, expected, cache, initialSeq);
|
|
104
|
+
while (mockCache.writeCount < totalWritesExpected) {
|
|
105
|
+
await delay(1);
|
|
106
|
+
}
|
|
107
|
+
assert.equal(mockCache.writeCount, totalWritesExpected);
|
|
108
|
+
assert.equal(mockCache.opsWritten, totalOpsWritten ?? mockData.length);
|
|
109
|
+
logger.assertMatchNone([{ category: "error" }]);
|
|
110
|
+
}
|
|
111
|
+
export async function runTest(batchSize, initialSeq, mockData, expected, initialWritesExpected, totalWritesExpected, totalOpsWritten) {
|
|
112
|
+
await runTestNoTimer(batchSize, initialSeq, mockData, expected, initialWritesExpected, totalOpsWritten);
|
|
113
|
+
await runTestWithTimer(batchSize, initialSeq, mockData, expected, initialWritesExpected, totalWritesExpected, totalOpsWritten);
|
|
114
|
+
}
|
|
115
|
+
describe("OpsCache", () => {
|
|
116
|
+
const mockData1 = [
|
|
117
|
+
{ sequenceNumber: 105, data: "105" },
|
|
118
|
+
{ sequenceNumber: 110, data: "110" },
|
|
119
|
+
{ sequenceNumber: 115, data: "115" },
|
|
120
|
+
{ sequenceNumber: 120, data: "120" },
|
|
121
|
+
{ sequenceNumber: 125, data: "125" },
|
|
122
|
+
{ sequenceNumber: 130, data: "130" },
|
|
123
|
+
{ sequenceNumber: 135, data: "135" },
|
|
124
|
+
{ sequenceNumber: 140, data: "140" },
|
|
125
|
+
{ sequenceNumber: 145, data: "140" },
|
|
126
|
+
];
|
|
127
|
+
it("1 element in each batch of 5 should not commit", async () => {
|
|
128
|
+
await runTest(5, 100, mockData1, {}, 0, 9);
|
|
129
|
+
});
|
|
130
|
+
it("2 element in each batch of 10 should not commit", async () => {
|
|
131
|
+
await runTest(10, 100, mockData1, {}, 0, 4, 8);
|
|
132
|
+
});
|
|
133
|
+
it("6 sequential elements with batch of 5 should commit 1 batch", async () => {
|
|
134
|
+
await runTest(5, 100, [
|
|
135
|
+
{ sequenceNumber: 101, data: "101" },
|
|
136
|
+
{ sequenceNumber: 102, data: "102" },
|
|
137
|
+
{ sequenceNumber: 103, data: "103" },
|
|
138
|
+
{ sequenceNumber: 104, data: "104" },
|
|
139
|
+
{ sequenceNumber: 105, data: "105" },
|
|
140
|
+
], {
|
|
141
|
+
"5_20": [
|
|
142
|
+
undefined,
|
|
143
|
+
{ sequenceNumber: 101, data: "101" },
|
|
144
|
+
{ sequenceNumber: 102, data: "102" },
|
|
145
|
+
{ sequenceNumber: 103, data: "103" },
|
|
146
|
+
{ sequenceNumber: 104, data: "104" },
|
|
147
|
+
],
|
|
148
|
+
}, 1, 2);
|
|
149
|
+
});
|
|
150
|
+
it("Epmty ops at beginning and end of batch should cause the batch to not be cached", async () => {
|
|
151
|
+
await runTest(5, 100, [
|
|
152
|
+
{ sequenceNumber: 101, data: "101" },
|
|
153
|
+
{ sequenceNumber: 102, data: "102" },
|
|
154
|
+
{ sequenceNumber: 103, data: "103" },
|
|
155
|
+
], {}, 0, 0, 0);
|
|
156
|
+
});
|
|
157
|
+
it("Epmty ops at just the beginning should still cause the batch to be cached", async () => {
|
|
158
|
+
await runTest(5, 100, [
|
|
159
|
+
{ sequenceNumber: 101, data: "101" },
|
|
160
|
+
{ sequenceNumber: 102, data: "102" },
|
|
161
|
+
{ sequenceNumber: 103, data: "103" },
|
|
162
|
+
{ sequenceNumber: 104, data: "104" },
|
|
163
|
+
], {
|
|
164
|
+
"5_20": [
|
|
165
|
+
undefined,
|
|
166
|
+
{ sequenceNumber: 101, data: "101" },
|
|
167
|
+
{ sequenceNumber: 102, data: "102" },
|
|
168
|
+
{ sequenceNumber: 103, data: "103" },
|
|
169
|
+
{ sequenceNumber: 104, data: "104" },
|
|
170
|
+
],
|
|
171
|
+
}, 1, 1, 4);
|
|
172
|
+
});
|
|
173
|
+
const mockData3 = [
|
|
174
|
+
{ sequenceNumber: 102, data: "102" },
|
|
175
|
+
{ sequenceNumber: 103, data: "103" },
|
|
176
|
+
];
|
|
177
|
+
it("3 sequential elements with batch of 2 and offset of 1 should commit 2 batches", async () => {
|
|
178
|
+
await runTest(2, 101, mockData3, {
|
|
179
|
+
"2_51": [
|
|
180
|
+
{ sequenceNumber: 102, data: "102" },
|
|
181
|
+
{ sequenceNumber: 103, data: "103" },
|
|
182
|
+
],
|
|
183
|
+
}, 1, 1);
|
|
184
|
+
});
|
|
185
|
+
it("with batch size of 1 all ops should commit in own batch", async () => {
|
|
186
|
+
await runTest(1, 101, mockData3, {
|
|
187
|
+
"1_102": [{ sequenceNumber: 102, data: "102" }],
|
|
188
|
+
"1_103": [{ sequenceNumber: 103, data: "103" }],
|
|
189
|
+
}, 2, 2);
|
|
190
|
+
});
|
|
191
|
+
it("Too many ops", async () => {
|
|
192
|
+
await runTest(5, 100, [
|
|
193
|
+
{ sequenceNumber: 105, data: "105" },
|
|
194
|
+
{ sequenceNumber: 106, data: "106" },
|
|
195
|
+
{ sequenceNumber: 107, data: "107" },
|
|
196
|
+
{ sequenceNumber: 108, data: "108" },
|
|
197
|
+
{ sequenceNumber: 109, data: "109" },
|
|
198
|
+
{ sequenceNumber: 110, data: "110" },
|
|
199
|
+
{ sequenceNumber: 111, data: "111" },
|
|
200
|
+
{ sequenceNumber: 112, data: "112" },
|
|
201
|
+
{ sequenceNumber: 113, data: "113" },
|
|
202
|
+
{ sequenceNumber: 114, data: "114" },
|
|
203
|
+
{ sequenceNumber: 115, data: "115" },
|
|
204
|
+
], {}, 3, 3);
|
|
205
|
+
});
|
|
206
|
+
it("Gap in ops", async () => {
|
|
207
|
+
const mockCache = new MockCache();
|
|
208
|
+
const initialSeq = 100;
|
|
209
|
+
const mockData = [
|
|
210
|
+
{ sequenceNumber: 101, data: "101" },
|
|
211
|
+
{ sequenceNumber: 102, data: "102" },
|
|
212
|
+
{ sequenceNumber: 103, data: "103" },
|
|
213
|
+
{ sequenceNumber: 104, data: "104" },
|
|
214
|
+
{ sequenceNumber: 105, data: "105" },
|
|
215
|
+
{ sequenceNumber: 106, data: "106" },
|
|
216
|
+
// Gap:
|
|
217
|
+
// { sequenceNumber: 107, data: "107" },
|
|
218
|
+
{ sequenceNumber: 108, data: "108" },
|
|
219
|
+
{ sequenceNumber: 109, data: "109" },
|
|
220
|
+
// Start a new butch - that's where we had bug!
|
|
221
|
+
{ sequenceNumber: 110, data: "110" },
|
|
222
|
+
{ sequenceNumber: 111, data: "111" },
|
|
223
|
+
];
|
|
224
|
+
const logger = new MockLogger();
|
|
225
|
+
const cache = new OpsCache(initialSeq, logger.toTelemetryLogger(), mockCache, 5 /* batchSize */, -1, // timerGranularity
|
|
226
|
+
100);
|
|
227
|
+
cache.addOps(mockData);
|
|
228
|
+
cache.flushOps();
|
|
229
|
+
const result = await cache.get(initialSeq + 1, undefined);
|
|
230
|
+
assert.deepEqual(result, [
|
|
231
|
+
{ sequenceNumber: 101, data: "101" },
|
|
232
|
+
{ sequenceNumber: 102, data: "102" },
|
|
233
|
+
{ sequenceNumber: 103, data: "103" },
|
|
234
|
+
{ sequenceNumber: 104, data: "104" },
|
|
235
|
+
{ sequenceNumber: 105, data: "105" },
|
|
236
|
+
{ sequenceNumber: 106, data: "106" },
|
|
237
|
+
]);
|
|
238
|
+
logger.assertMatchNone([{ category: "error" }]);
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
describe("OdspDeltaStorageWithCache", () => {
|
|
242
|
+
async function readAll(stream) {
|
|
243
|
+
const ops = [];
|
|
244
|
+
// eslint-disable-next-line no-constant-condition
|
|
245
|
+
while (true) {
|
|
246
|
+
const result = await stream.read();
|
|
247
|
+
if (result.done) {
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
ops.push(...result.value);
|
|
251
|
+
}
|
|
252
|
+
return ops;
|
|
253
|
+
}
|
|
254
|
+
function createOps(fromArg, length) {
|
|
255
|
+
const ops = [];
|
|
256
|
+
let from = fromArg;
|
|
257
|
+
const to = from + length;
|
|
258
|
+
while (from < to) {
|
|
259
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
260
|
+
ops.push({ sequenceNumber: from });
|
|
261
|
+
from++;
|
|
262
|
+
}
|
|
263
|
+
return ops;
|
|
264
|
+
}
|
|
265
|
+
function filterOps(ops, from, to) {
|
|
266
|
+
return ops.filter((op) => op.sequenceNumber >= from && op.sequenceNumber < to);
|
|
267
|
+
}
|
|
268
|
+
function validateOps(ops, from, to) {
|
|
269
|
+
if (to < from) {
|
|
270
|
+
assert(ops.length === 0);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
assert(ops.length === to - from);
|
|
274
|
+
assert(ops.length === 0 || ops[0].sequenceNumber === from);
|
|
275
|
+
assert(ops.length === 0 || ops[ops.length - 1].sequenceNumber === to - 1);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
async function testStorage(fromTotal, toTotal, cacheOnly, opsFromSnapshot, opsFromCache, opsFromStorage, concurrency = 1, batchSize = 100) {
|
|
279
|
+
const snapshotOps = createOps(fromTotal, opsFromSnapshot);
|
|
280
|
+
const cachedOps = createOps(fromTotal + opsFromSnapshot, opsFromCache);
|
|
281
|
+
const storageOps = createOps(fromTotal + opsFromSnapshot + opsFromCache, opsFromStorage);
|
|
282
|
+
let totalOps = opsFromSnapshot + opsFromCache + (cacheOnly ? 0 : opsFromStorage);
|
|
283
|
+
const actualTo = toTotal ?? fromTotal + totalOps;
|
|
284
|
+
assert(actualTo <= fromTotal + totalOps); // code will deadlock if that's not the case
|
|
285
|
+
const askingOps = actualTo - fromTotal;
|
|
286
|
+
totalOps = Math.min(totalOps, askingOps);
|
|
287
|
+
let opsToCache = [];
|
|
288
|
+
const logger = new MockLogger();
|
|
289
|
+
const storage = new OdspDeltaStorageWithCache(snapshotOps, logger.toTelemetryLogger(), batchSize, concurrency,
|
|
290
|
+
// getFromStorage
|
|
291
|
+
async (from, to) => {
|
|
292
|
+
return { messages: filterOps(storageOps, from, to), partialResult: false };
|
|
293
|
+
},
|
|
294
|
+
// getCached
|
|
295
|
+
async (from, to) => filterOps(cachedOps, from, to),
|
|
296
|
+
// requestFromSocket
|
|
297
|
+
(from, to) => { },
|
|
298
|
+
// opsReceived
|
|
299
|
+
(ops) => opsToCache.push(...ops), () => ({ isFirstSnapshotFromNetwork: false }));
|
|
300
|
+
const stream = storage.fetchMessages(fromTotal, toTotal, undefined, // abortSignal
|
|
301
|
+
cacheOnly);
|
|
302
|
+
const opsAll = await readAll(stream);
|
|
303
|
+
validateOps(opsAll, fromTotal, fromTotal + totalOps);
|
|
304
|
+
if (cacheOnly) {
|
|
305
|
+
assert(opsToCache.length === 0);
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
opsToCache = opsToCache.sort((a, b) => a.sequenceNumber - b.sequenceNumber);
|
|
309
|
+
validateOps(opsToCache, fromTotal + opsFromSnapshot + opsFromCache, fromTotal + totalOps);
|
|
310
|
+
}
|
|
311
|
+
logger.assertMatchNone([{ category: "error" }]);
|
|
312
|
+
}
|
|
313
|
+
it("basic permutations", async () => {
|
|
314
|
+
await testStorage(105, undefined, false, 0, 0, 0);
|
|
315
|
+
await testStorage(105, undefined, false, 110, 0, 0);
|
|
316
|
+
await testStorage(105, undefined, false, 110, 245, 0);
|
|
317
|
+
await testStorage(105, undefined, false, 110, 245, 1000);
|
|
318
|
+
await testStorage(105, undefined, false, 110, 9001, 8002);
|
|
319
|
+
await testStorage(105, undefined, false, 0, 245, 0);
|
|
320
|
+
await testStorage(105, undefined, false, 0, 9000, 0);
|
|
321
|
+
await testStorage(105, undefined, false, 0, 245, 150);
|
|
322
|
+
await testStorage(105, undefined, false, 110, 0, 150);
|
|
323
|
+
await testStorage(105, undefined, false, 0, 0, 150);
|
|
324
|
+
});
|
|
325
|
+
it("cached", async () => {
|
|
326
|
+
await testStorage(105, undefined, true, 0, 0, 0);
|
|
327
|
+
await testStorage(105, undefined, true, 110, 0, 0);
|
|
328
|
+
await testStorage(105, undefined, true, 110, 245, 0);
|
|
329
|
+
await testStorage(105, undefined, true, 1001, 8001, 0);
|
|
330
|
+
await testStorage(105, undefined, true, 110, 245, 1000);
|
|
331
|
+
await testStorage(105, undefined, true, 0, 245, 0);
|
|
332
|
+
await testStorage(105, undefined, true, 0, 245, 150);
|
|
333
|
+
await testStorage(105, undefined, true, 110, 0, 150);
|
|
334
|
+
await testStorage(105, undefined, true, 0, 0, 150);
|
|
335
|
+
});
|
|
336
|
+
it("fixed to", async () => {
|
|
337
|
+
await testStorage(105, 105 + 110, false, 110, 0, 0);
|
|
338
|
+
await testStorage(105, 105 + 110 + 245, false, 110, 245, 0);
|
|
339
|
+
await testStorage(105, 105 + 110 + 245 + 500, false, 110, 245, 1000);
|
|
340
|
+
await testStorage(105, 105 + 245 + 150, false, 0, 245, 150);
|
|
341
|
+
await testStorage(105, 105 + 110 + 150, false, 110, 0, 150);
|
|
342
|
+
await testStorage(105, 105 + 140, false, 0, 0, 150);
|
|
343
|
+
});
|
|
344
|
+
it("concurency", async () => {
|
|
345
|
+
await testStorage(105, undefined, false, 0, 0, 0, 2);
|
|
346
|
+
await testStorage(105, undefined, false, 110, 0, 0, 2);
|
|
347
|
+
await testStorage(105, undefined, false, 110, 245, 0, 2);
|
|
348
|
+
await testStorage(105, undefined, false, 110, 245, 1000, 2);
|
|
349
|
+
await testStorage(105, undefined, false, 110, 9001, 8002, 2);
|
|
350
|
+
await testStorage(105, undefined, false, 0, 245, 0, 2);
|
|
351
|
+
await testStorage(105, undefined, false, 0, 9000, 0, 2);
|
|
352
|
+
await testStorage(105, undefined, false, 0, 245, 150, 2);
|
|
353
|
+
await testStorage(105, undefined, false, 110, 0, 150, 2);
|
|
354
|
+
await testStorage(105, undefined, false, 0, 0, 150, 2);
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
//# sourceMappingURL=opsCaching.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opsCaching.spec.js","sourceRoot":"","sources":["../../src/test/opsCaching.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 \"node:assert\";\nimport { MockLogger } from \"@fluidframework/telemetry-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { IStream } from \"@fluidframework/driver-definitions\";\nimport { delay } from \"@fluidframework/core-utils\";\nimport { OdspDeltaStorageWithCache } from \"../odspDeltaStorageService.js\";\nimport { OpsCache, ICache, IMessage, CacheEntry } from \"../opsCaching.js\";\nimport { OdspDocumentStorageService } from \"../odspDocumentStorageManager.js\";\n\nexport type MyDataInput = IMessage & { data: string };\n\nclass MockCache implements ICache {\n\tpublic writeCount = 0;\n\tpublic opsWritten = 0;\n\n\tpublic async write(batchNumber: string, data: string): Promise<void> {\n\t\tthis.writeCount++;\n\t\tthis.data[batchNumber] = JSON.parse(data);\n\t\tfor (const op of this.data[batchNumber] as CacheEntry) {\n\t\t\t// JSON.serialize converts undefined to null\n\t\t\tif (op !== null) {\n\t\t\t\tthis.opsWritten++;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic async read(batchNumber: string): Promise<string | undefined> {\n\t\tconst content = this.data[batchNumber];\n\t\tif (content === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn JSON.stringify(content);\n\t}\n\n\tpublic remove(): void {\n\t\t// Do not reset this.writeCount such that we can test that writes happened, but later on data was cleared\n\t\tthis.writeCount++;\n\t\tthis.opsWritten++;\n\t\tthis.data = {};\n\t}\n\n\tpublic data: { [key: string]: unknown } = {};\n}\n\nasync function validate(\n\tmockCache: MockCache,\n\texpected: { [key: number]: (MyDataInput | undefined)[] },\n\tcache: OpsCache,\n\tinitialSeq: number,\n): Promise<void> {\n\tassert.deepEqual(mockCache.data, JSON.parse(JSON.stringify(expected)));\n\n\tconst expectedArr: MyDataInput[] = [];\n\tfor (const values of Object.values(expected)) {\n\t\tfor (const op of values) {\n\t\t\tif (op !== undefined) {\n\t\t\t\texpectedArr.push(op);\n\t\t\t}\n\t\t}\n\t}\n\n\tlet result = await cache.get(initialSeq + 1, undefined);\n\tassert.deepEqual(result, expectedArr);\n\n\tif (initialSeq >= 10) {\n\t\tresult = await cache.get(1, 10);\n\t\tassert(result.length === 0);\n\t}\n\n\t// Asking for one too early should result in empty result, as hit miss should result in no ops.\n\tif (initialSeq > 0) {\n\t\tresult = await cache.get(initialSeq, undefined);\n\t\tassert(result.length === 0);\n\t}\n\n\tif (expectedArr.length > 0) {\n\t\tconst last = expectedArr[expectedArr.length - 1].sequenceNumber + 1;\n\n\t\tresult = await cache.get(last, undefined);\n\t\tassert(result.length === 0);\n\n\t\tresult = await cache.get(last + 10, undefined);\n\t\tassert(result.length === 0);\n\n\t\tresult = await cache.get(initialSeq + 2, last);\n\t\tassert.deepEqual(result, expectedArr.slice(1));\n\n\t\tresult = await cache.get(initialSeq + 2, last + 100000);\n\t\tassert.deepEqual(result, expectedArr.slice(1));\n\n\t\tresult = await cache.get(initialSeq + 2, last - 1);\n\t\tassert.deepEqual(result, expectedArr.slice(1, -1));\n\t}\n}\n\nasync function runTestNoTimer(\n\tbatchSize: number,\n\tinitialSeq: number,\n\tmockData: MyDataInput[],\n\texpected: { [key: number]: (MyDataInput | undefined)[] },\n\tinitialWritesExpected: number,\n\ttotalOpsWritten?: number,\n): Promise<void> {\n\tconst mockCache = new MockCache();\n\tconst logger = new MockLogger();\n\tconst cache = new OpsCache(\n\t\tinitialSeq,\n\t\tlogger.toTelemetryLogger(),\n\t\tmockCache,\n\t\tbatchSize,\n\t\t-1, // timerGranularity\n\t\t10, // totalOpsToCache\n\t);\n\n\tcache.addOps(mockData);\n\n\tconst writes = mockCache.writeCount;\n\tassert.equal(writes, initialWritesExpected, \"initialWrites should match\");\n\n\t// Validate that writing same ops is not going to change anything\n\tcache.addOps(mockData);\n\tassert.equal(writes, mockCache.writeCount);\n\n\tawait validate(mockCache, expected, cache, initialSeq);\n\n\t// ensure all ops are flushed properly\n\tcache.flushOps();\n\tassert.equal(mockCache.opsWritten, totalOpsWritten ?? mockData.length);\n\n\t// ensure adding same ops and flushing again is doing nothing\n\tcache.addOps(mockData);\n\tcache.flushOps();\n\tassert.equal(\n\t\tmockCache.opsWritten,\n\t\ttotalOpsWritten ?? mockData.length,\n\t\t\"ops written does not match\",\n\t);\n\tlogger.assertMatchNone([{ category: \"error\" }]);\n}\n\nexport async function runTestWithTimer(\n\tbatchSize: number,\n\tinitialSeq: number,\n\tmockData: MyDataInput[],\n\texpected: { [key: number]: (MyDataInput | undefined)[] },\n\tinitialWritesExpected: number,\n\ttotalWritesExpected: number,\n\ttotalOpsWritten?: number,\n): Promise<void> {\n\tconst mockCache = new MockCache();\n\tconst logger = new MockLogger();\n\tconst cache = new OpsCache(\n\t\tinitialSeq,\n\t\tlogger.toTelemetryLogger(),\n\t\tmockCache,\n\t\tbatchSize,\n\t\t1, // timerGranularity\n\t\t10, // totalOpsToCache\n\t);\n\n\tcache.addOps(mockData);\n\tassert.equal(mockCache.writeCount, initialWritesExpected);\n\tawait validate(mockCache, expected, cache, initialSeq);\n\n\twhile (mockCache.writeCount < totalWritesExpected) {\n\t\tawait delay(1);\n\t}\n\tassert.equal(mockCache.writeCount, totalWritesExpected);\n\tassert.equal(mockCache.opsWritten, totalOpsWritten ?? mockData.length);\n\tlogger.assertMatchNone([{ category: \"error\" }]);\n}\n\nexport async function runTest(\n\tbatchSize: number,\n\tinitialSeq: number,\n\tmockData: MyDataInput[],\n\texpected: { [key: string]: (MyDataInput | undefined)[] },\n\tinitialWritesExpected: number,\n\ttotalWritesExpected: number,\n\ttotalOpsWritten?: number,\n): Promise<void> {\n\tawait runTestNoTimer(\n\t\tbatchSize,\n\t\tinitialSeq,\n\t\tmockData,\n\t\texpected,\n\t\tinitialWritesExpected,\n\t\ttotalOpsWritten,\n\t);\n\tawait runTestWithTimer(\n\t\tbatchSize,\n\t\tinitialSeq,\n\t\tmockData,\n\t\texpected,\n\t\tinitialWritesExpected,\n\t\ttotalWritesExpected,\n\t\ttotalOpsWritten,\n\t);\n}\n\ndescribe(\"OpsCache\", () => {\n\tconst mockData1: MyDataInput[] = [\n\t\t{ sequenceNumber: 105, data: \"105\" },\n\t\t{ sequenceNumber: 110, data: \"110\" },\n\t\t{ sequenceNumber: 115, data: \"115\" },\n\t\t{ sequenceNumber: 120, data: \"120\" },\n\t\t{ sequenceNumber: 125, data: \"125\" },\n\t\t{ sequenceNumber: 130, data: \"130\" },\n\t\t{ sequenceNumber: 135, data: \"135\" },\n\t\t{ sequenceNumber: 140, data: \"140\" },\n\t\t{ sequenceNumber: 145, data: \"140\" },\n\t];\n\n\tit(\"1 element in each batch of 5 should not commit\", async () => {\n\t\tawait runTest(5, 100, mockData1, {}, 0, 9);\n\t});\n\n\tit(\"2 element in each batch of 10 should not commit\", async () => {\n\t\tawait runTest(10, 100, mockData1, {}, 0, 4, 8);\n\t});\n\n\tit(\"6 sequential elements with batch of 5 should commit 1 batch\", async () => {\n\t\tawait runTest(\n\t\t\t5,\n\t\t\t100,\n\t\t\t[\n\t\t\t\t{ sequenceNumber: 101, data: \"101\" },\n\t\t\t\t{ sequenceNumber: 102, data: \"102\" },\n\t\t\t\t{ sequenceNumber: 103, data: \"103\" },\n\t\t\t\t{ sequenceNumber: 104, data: \"104\" },\n\t\t\t\t{ sequenceNumber: 105, data: \"105\" },\n\t\t\t],\n\t\t\t{\n\t\t\t\t\"5_20\": [\n\t\t\t\t\tundefined,\n\t\t\t\t\t{ sequenceNumber: 101, data: \"101\" },\n\t\t\t\t\t{ sequenceNumber: 102, data: \"102\" },\n\t\t\t\t\t{ sequenceNumber: 103, data: \"103\" },\n\t\t\t\t\t{ sequenceNumber: 104, data: \"104\" },\n\t\t\t\t],\n\t\t\t},\n\t\t\t1,\n\t\t\t2,\n\t\t);\n\t});\n\n\tit(\"Epmty ops at beginning and end of batch should cause the batch to not be cached\", async () => {\n\t\tawait runTest(\n\t\t\t5,\n\t\t\t100,\n\t\t\t[\n\t\t\t\t{ sequenceNumber: 101, data: \"101\" },\n\t\t\t\t{ sequenceNumber: 102, data: \"102\" },\n\t\t\t\t{ sequenceNumber: 103, data: \"103\" },\n\t\t\t],\n\t\t\t{},\n\t\t\t0,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t});\n\n\tit(\"Epmty ops at just the beginning should still cause the batch to be cached\", async () => {\n\t\tawait runTest(\n\t\t\t5,\n\t\t\t100,\n\t\t\t[\n\t\t\t\t{ sequenceNumber: 101, data: \"101\" },\n\t\t\t\t{ sequenceNumber: 102, data: \"102\" },\n\t\t\t\t{ sequenceNumber: 103, data: \"103\" },\n\t\t\t\t{ sequenceNumber: 104, data: \"104\" },\n\t\t\t],\n\t\t\t{\n\t\t\t\t\"5_20\": [\n\t\t\t\t\tundefined,\n\t\t\t\t\t{ sequenceNumber: 101, data: \"101\" },\n\t\t\t\t\t{ sequenceNumber: 102, data: \"102\" },\n\t\t\t\t\t{ sequenceNumber: 103, data: \"103\" },\n\t\t\t\t\t{ sequenceNumber: 104, data: \"104\" },\n\t\t\t\t],\n\t\t\t},\n\t\t\t1,\n\t\t\t1,\n\t\t\t4,\n\t\t);\n\t});\n\n\tconst mockData3: MyDataInput[] = [\n\t\t{ sequenceNumber: 102, data: \"102\" },\n\t\t{ sequenceNumber: 103, data: \"103\" },\n\t];\n\n\tit(\"3 sequential elements with batch of 2 and offset of 1 should commit 2 batches\", async () => {\n\t\tawait runTest(\n\t\t\t2,\n\t\t\t101,\n\t\t\tmockData3,\n\t\t\t{\n\t\t\t\t\"2_51\": [\n\t\t\t\t\t{ sequenceNumber: 102, data: \"102\" },\n\t\t\t\t\t{ sequenceNumber: 103, data: \"103\" },\n\t\t\t\t],\n\t\t\t},\n\t\t\t1,\n\t\t\t1,\n\t\t);\n\t});\n\n\tit(\"with batch size of 1 all ops should commit in own batch\", async () => {\n\t\tawait runTest(\n\t\t\t1,\n\t\t\t101,\n\t\t\tmockData3,\n\t\t\t{\n\t\t\t\t\"1_102\": [{ sequenceNumber: 102, data: \"102\" }],\n\t\t\t\t\"1_103\": [{ sequenceNumber: 103, data: \"103\" }],\n\t\t\t},\n\t\t\t2,\n\t\t\t2,\n\t\t);\n\t});\n\n\tit(\"Too many ops\", async () => {\n\t\tawait runTest(\n\t\t\t5,\n\t\t\t100,\n\t\t\t[\n\t\t\t\t{ sequenceNumber: 105, data: \"105\" },\n\t\t\t\t{ sequenceNumber: 106, data: \"106\" },\n\t\t\t\t{ sequenceNumber: 107, data: \"107\" },\n\t\t\t\t{ sequenceNumber: 108, data: \"108\" },\n\t\t\t\t{ sequenceNumber: 109, data: \"109\" },\n\t\t\t\t{ sequenceNumber: 110, data: \"110\" },\n\t\t\t\t{ sequenceNumber: 111, data: \"111\" },\n\t\t\t\t{ sequenceNumber: 112, data: \"112\" },\n\t\t\t\t{ sequenceNumber: 113, data: \"113\" },\n\t\t\t\t{ sequenceNumber: 114, data: \"114\" },\n\t\t\t\t{ sequenceNumber: 115, data: \"115\" },\n\t\t\t],\n\t\t\t{},\n\t\t\t3,\n\t\t\t3,\n\t\t);\n\t});\n\n\tit(\"Gap in ops\", async () => {\n\t\tconst mockCache = new MockCache();\n\t\tconst initialSeq = 100;\n\n\t\tconst mockData: MyDataInput[] = [\n\t\t\t{ sequenceNumber: 101, data: \"101\" },\n\t\t\t{ sequenceNumber: 102, data: \"102\" },\n\t\t\t{ sequenceNumber: 103, data: \"103\" },\n\t\t\t{ sequenceNumber: 104, data: \"104\" },\n\t\t\t{ sequenceNumber: 105, data: \"105\" },\n\t\t\t{ sequenceNumber: 106, data: \"106\" },\n\t\t\t// Gap:\n\t\t\t// { sequenceNumber: 107, data: \"107\" },\n\t\t\t{ sequenceNumber: 108, data: \"108\" },\n\t\t\t{ sequenceNumber: 109, data: \"109\" },\n\t\t\t// Start a new butch - that's where we had bug!\n\t\t\t{ sequenceNumber: 110, data: \"110\" },\n\t\t\t{ sequenceNumber: 111, data: \"111\" },\n\t\t];\n\t\tconst logger = new MockLogger();\n\t\tconst cache = new OpsCache(\n\t\t\tinitialSeq,\n\t\t\tlogger.toTelemetryLogger(),\n\t\t\tmockCache,\n\t\t\t5 /* batchSize */,\n\t\t\t-1, // timerGranularity\n\t\t\t100, // totalOpsToCache\n\t\t);\n\n\t\tcache.addOps(mockData);\n\t\tcache.flushOps();\n\n\t\tconst result = await cache.get(initialSeq + 1, undefined);\n\t\tassert.deepEqual(result, [\n\t\t\t{ sequenceNumber: 101, data: \"101\" },\n\t\t\t{ sequenceNumber: 102, data: \"102\" },\n\t\t\t{ sequenceNumber: 103, data: \"103\" },\n\t\t\t{ sequenceNumber: 104, data: \"104\" },\n\t\t\t{ sequenceNumber: 105, data: \"105\" },\n\t\t\t{ sequenceNumber: 106, data: \"106\" },\n\t\t]);\n\t\tlogger.assertMatchNone([{ category: \"error\" }]);\n\t});\n});\n\ndescribe(\"OdspDeltaStorageWithCache\", () => {\n\tasync function readAll(\n\t\tstream: IStream<ISequencedDocumentMessage[]>,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\t\t// eslint-disable-next-line no-constant-condition\n\t\twhile (true) {\n\t\t\tconst result = await stream.read();\n\t\t\tif (result.done) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tops.push(...result.value);\n\t\t}\n\t\treturn ops;\n\t}\n\n\tfunction createOps(fromArg: number, length: number): ISequencedDocumentMessage[] {\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\t\tlet from = fromArg;\n\t\tconst to = from + length;\n\t\twhile (from < to) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\tops.push({ sequenceNumber: from } as ISequencedDocumentMessage);\n\t\t\tfrom++;\n\t\t}\n\t\treturn ops;\n\t}\n\n\tfunction filterOps(\n\t\tops: ISequencedDocumentMessage[],\n\t\tfrom: number,\n\t\tto: number,\n\t): ISequencedDocumentMessage[] {\n\t\treturn ops.filter((op) => op.sequenceNumber >= from && op.sequenceNumber < to);\n\t}\n\n\tfunction validateOps(ops: ISequencedDocumentMessage[], from: number, to: number): void {\n\t\tif (to < from) {\n\t\t\tassert(ops.length === 0);\n\t\t} else {\n\t\t\tassert(ops.length === to - from);\n\t\t\tassert(ops.length === 0 || ops[0].sequenceNumber === from);\n\t\t\tassert(ops.length === 0 || ops[ops.length - 1].sequenceNumber === to - 1);\n\t\t}\n\t}\n\n\tasync function testStorage(\n\t\tfromTotal: number,\n\t\ttoTotal: number | undefined,\n\t\tcacheOnly: boolean,\n\t\topsFromSnapshot: number,\n\t\topsFromCache: number,\n\t\topsFromStorage: number,\n\t\tconcurrency = 1,\n\t\tbatchSize = 100,\n\t): Promise<void> {\n\t\tconst snapshotOps = createOps(fromTotal, opsFromSnapshot);\n\t\tconst cachedOps = createOps(fromTotal + opsFromSnapshot, opsFromCache);\n\t\tconst storageOps = createOps(fromTotal + opsFromSnapshot + opsFromCache, opsFromStorage);\n\n\t\tlet totalOps = opsFromSnapshot + opsFromCache + (cacheOnly ? 0 : opsFromStorage);\n\t\tconst actualTo = toTotal ?? fromTotal + totalOps;\n\t\tassert(actualTo <= fromTotal + totalOps); // code will deadlock if that's not the case\n\t\tconst askingOps = actualTo - fromTotal;\n\t\ttotalOps = Math.min(totalOps, askingOps);\n\n\t\tlet opsToCache: ISequencedDocumentMessage[] = [];\n\t\tconst logger = new MockLogger();\n\t\tconst storage = new OdspDeltaStorageWithCache(\n\t\t\tsnapshotOps,\n\t\t\tlogger.toTelemetryLogger(),\n\t\t\tbatchSize,\n\t\t\tconcurrency,\n\t\t\t// getFromStorage\n\t\t\tasync (from: number, to: number) => {\n\t\t\t\treturn { messages: filterOps(storageOps, from, to), partialResult: false };\n\t\t\t},\n\t\t\t// getCached\n\t\t\tasync (from: number, to: number) => filterOps(cachedOps, from, to),\n\t\t\t// requestFromSocket\n\t\t\t(from: number, to: number) => {},\n\t\t\t// opsReceived\n\t\t\t(ops: ISequencedDocumentMessage[]) => opsToCache.push(...ops),\n\t\t\t() => ({ isFirstSnapshotFromNetwork: false }) as unknown as OdspDocumentStorageService,\n\t\t);\n\n\t\tconst stream = storage.fetchMessages(\n\t\t\tfromTotal,\n\t\t\ttoTotal,\n\t\t\tundefined, // abortSignal\n\t\t\tcacheOnly,\n\t\t);\n\n\t\tconst opsAll = await readAll(stream);\n\n\t\tvalidateOps(opsAll, fromTotal, fromTotal + totalOps);\n\t\tif (cacheOnly) {\n\t\t\tassert(opsToCache.length === 0);\n\t\t} else {\n\t\t\topsToCache = opsToCache.sort((a, b) => a.sequenceNumber - b.sequenceNumber);\n\t\t\tvalidateOps(\n\t\t\t\topsToCache,\n\t\t\t\tfromTotal + opsFromSnapshot + opsFromCache,\n\t\t\t\tfromTotal + totalOps,\n\t\t\t);\n\t\t}\n\t\tlogger.assertMatchNone([{ category: \"error\" }]);\n\t}\n\n\tit(\"basic permutations\", async () => {\n\t\tawait testStorage(105, undefined, false, 0, 0, 0);\n\t\tawait testStorage(105, undefined, false, 110, 0, 0);\n\t\tawait testStorage(105, undefined, false, 110, 245, 0);\n\t\tawait testStorage(105, undefined, false, 110, 245, 1000);\n\t\tawait testStorage(105, undefined, false, 110, 9001, 8002);\n\n\t\tawait testStorage(105, undefined, false, 0, 245, 0);\n\t\tawait testStorage(105, undefined, false, 0, 9000, 0);\n\t\tawait testStorage(105, undefined, false, 0, 245, 150);\n\n\t\tawait testStorage(105, undefined, false, 110, 0, 150);\n\t\tawait testStorage(105, undefined, false, 0, 0, 150);\n\t});\n\n\tit(\"cached\", async () => {\n\t\tawait testStorage(105, undefined, true, 0, 0, 0);\n\t\tawait testStorage(105, undefined, true, 110, 0, 0);\n\t\tawait testStorage(105, undefined, true, 110, 245, 0);\n\t\tawait testStorage(105, undefined, true, 1001, 8001, 0);\n\t\tawait testStorage(105, undefined, true, 110, 245, 1000);\n\n\t\tawait testStorage(105, undefined, true, 0, 245, 0);\n\t\tawait testStorage(105, undefined, true, 0, 245, 150);\n\n\t\tawait testStorage(105, undefined, true, 110, 0, 150);\n\t\tawait testStorage(105, undefined, true, 0, 0, 150);\n\t});\n\n\tit(\"fixed to\", async () => {\n\t\tawait testStorage(105, 105 + 110, false, 110, 0, 0);\n\t\tawait testStorage(105, 105 + 110 + 245, false, 110, 245, 0);\n\t\tawait testStorage(105, 105 + 110 + 245 + 500, false, 110, 245, 1000);\n\n\t\tawait testStorage(105, 105 + 245 + 150, false, 0, 245, 150);\n\n\t\tawait testStorage(105, 105 + 110 + 150, false, 110, 0, 150);\n\t\tawait testStorage(105, 105 + 140, false, 0, 0, 150);\n\t});\n\n\tit(\"concurency\", async () => {\n\t\tawait testStorage(105, undefined, false, 0, 0, 0, 2);\n\t\tawait testStorage(105, undefined, false, 110, 0, 0, 2);\n\t\tawait testStorage(105, undefined, false, 110, 245, 0, 2);\n\t\tawait testStorage(105, undefined, false, 110, 245, 1000, 2);\n\t\tawait testStorage(105, undefined, false, 110, 9001, 8002, 2);\n\n\t\tawait testStorage(105, undefined, false, 0, 245, 0, 2);\n\t\tawait testStorage(105, undefined, false, 0, 9000, 0, 2);\n\t\tawait testStorage(105, undefined, false, 0, 245, 150, 2);\n\n\t\tawait testStorage(105, undefined, false, 110, 0, 150, 2);\n\t\tawait testStorage(105, undefined, false, 0, 0, 150, 2);\n\t});\n});\n"]}
|