@fluidframework/odsp-driver 2.117.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/CHANGELOG.md +92 -2
  2. package/README.md +53 -50
  3. package/api-extractor/api-extractor-lint-pointInTime.cjs.json +5 -0
  4. package/api-extractor/api-extractor-lint-pointInTime.esm.json +5 -0
  5. package/{api-extractor.json → api-extractor/api-extractor-model.json} +1 -1
  6. package/api-extractor/api-extractor-report.pointInTime.json +9 -0
  7. package/api-report/odsp-driver.legacy.alpha.api.md +28 -3
  8. package/api-report/odsp-driver.legacy.beta.api.md +28 -3
  9. package/api-report/odsp-driver.point-in-time.legacy.beta.api.md +117 -0
  10. package/dist/ReadBufferUtils.js +2 -1
  11. package/dist/ReadBufferUtils.js.map +1 -1
  12. package/dist/WriteBufferUtils.js +4 -6
  13. package/dist/WriteBufferUtils.js.map +1 -1
  14. package/dist/checkUrl.js +1 -2
  15. package/dist/checkUrl.js.map +1 -1
  16. package/dist/compactSnapshotParser.d.ts.map +1 -1
  17. package/dist/compactSnapshotParser.js +5 -4
  18. package/dist/compactSnapshotParser.js.map +1 -1
  19. package/dist/compactSnapshotWriter.js +1 -2
  20. package/dist/compactSnapshotWriter.js.map +1 -1
  21. package/dist/createFile/createFile.js +4 -5
  22. package/dist/createFile/createFile.js.map +1 -1
  23. package/dist/createFile/createNewContainerOnExistingFile.js +1 -2
  24. package/dist/createFile/createNewContainerOnExistingFile.js.map +1 -1
  25. package/dist/createFile/createNewUtils.d.ts.map +1 -1
  26. package/dist/createFile/createNewUtils.js +4 -5
  27. package/dist/createFile/createNewUtils.js.map +1 -1
  28. package/dist/createFile/index.js +1 -2
  29. package/dist/createFile/index.js.map +1 -1
  30. package/dist/createOdspCreateContainerRequest.js +1 -2
  31. package/dist/createOdspCreateContainerRequest.js.map +1 -1
  32. package/dist/createOdspUrl.js +1 -2
  33. package/dist/createOdspUrl.js.map +1 -1
  34. package/dist/epochTracker.d.ts.map +1 -1
  35. package/dist/epochTracker.js +17 -6
  36. package/dist/epochTracker.js.map +1 -1
  37. package/dist/fetchSnapshot.d.ts.map +1 -1
  38. package/dist/fetchSnapshot.js +5 -5
  39. package/dist/fetchSnapshot.js.map +1 -1
  40. package/dist/getFileLink.d.ts.map +1 -1
  41. package/dist/getQueryString.js +1 -2
  42. package/dist/getQueryString.js.map +1 -1
  43. package/dist/getUrlAndHeadersWithAuth.js +1 -2
  44. package/dist/getUrlAndHeadersWithAuth.js.map +1 -1
  45. package/dist/index.d.ts +3 -4
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +3 -5
  48. package/dist/index.js.map +1 -1
  49. package/dist/legacy.d.ts +4 -1
  50. package/dist/legacyAlpha.d.ts +4 -1
  51. package/dist/localOdspDriver/localOdspDeltaStorageService.js +2 -0
  52. package/dist/localOdspDriver/localOdspDeltaStorageService.js.map +1 -1
  53. package/dist/localOdspDriver/localOdspDocumentService.js +5 -1
  54. package/dist/localOdspDriver/localOdspDocumentService.js.map +1 -1
  55. package/dist/localOdspDriver/localOdspDocumentServiceFactory.js +2 -1
  56. package/dist/localOdspDriver/localOdspDocumentServiceFactory.js.map +1 -1
  57. package/dist/localOdspDriver/localOdspDocumentStorageManager.js +4 -1
  58. package/dist/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -1
  59. package/dist/mockify.js +2 -2
  60. package/dist/mockify.js.map +1 -1
  61. package/dist/odspCache.js +7 -8
  62. package/dist/odspCache.js.map +1 -1
  63. package/dist/odspDelayLoadedDeltaStream.d.ts.map +1 -1
  64. package/dist/odspDelayLoadedDeltaStream.js +42 -26
  65. package/dist/odspDelayLoadedDeltaStream.js.map +1 -1
  66. package/dist/odspDeltaStorageService.js +14 -1
  67. package/dist/odspDeltaStorageService.js.map +1 -1
  68. package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
  69. package/dist/odspDocumentDeltaConnection.js +58 -41
  70. package/dist/odspDocumentDeltaConnection.js.map +1 -1
  71. package/dist/odspDocumentService.js +16 -1
  72. package/dist/odspDocumentService.js.map +1 -1
  73. package/dist/odspDocumentServiceFactory.d.ts +30 -1
  74. package/dist/odspDocumentServiceFactory.d.ts.map +1 -1
  75. package/dist/odspDocumentServiceFactory.js +30 -2
  76. package/dist/odspDocumentServiceFactory.js.map +1 -1
  77. package/dist/odspDocumentServiceFactoryCore.d.ts +83 -3
  78. package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
  79. package/dist/odspDocumentServiceFactoryCore.js +38 -12
  80. package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
  81. package/dist/odspDocumentStorageManager.d.ts.map +1 -1
  82. package/dist/odspDocumentStorageManager.js +31 -13
  83. package/dist/odspDocumentStorageManager.js.map +1 -1
  84. package/dist/odspDocumentStorageServiceBase.js +23 -20
  85. package/dist/odspDocumentStorageServiceBase.js.map +1 -1
  86. package/dist/odspDriverUrlResolver.js +2 -2
  87. package/dist/odspDriverUrlResolver.js.map +1 -1
  88. package/dist/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
  89. package/dist/odspDriverUrlResolverForShareLink.js +6 -1
  90. package/dist/odspDriverUrlResolverForShareLink.js.map +1 -1
  91. package/dist/odspError.js +1 -2
  92. package/dist/odspError.js.map +1 -1
  93. package/dist/odspFluidFileLink.js +4 -4
  94. package/dist/odspFluidFileLink.js.map +1 -1
  95. package/dist/odspLayerCompatState.d.ts +8 -1
  96. package/dist/odspLayerCompatState.d.ts.map +1 -1
  97. package/dist/odspLayerCompatState.js +20 -1
  98. package/dist/odspLayerCompatState.js.map +1 -1
  99. package/dist/odspLocationRedirection.js +1 -2
  100. package/dist/odspLocationRedirection.js.map +1 -1
  101. package/dist/odspPublicUtils.js +1 -2
  102. package/dist/odspPublicUtils.js.map +1 -1
  103. package/dist/odspSnapshotParser.js +1 -2
  104. package/dist/odspSnapshotParser.js.map +1 -1
  105. package/dist/odspSummaryUploadManager.js +7 -0
  106. package/dist/odspSummaryUploadManager.js.map +1 -1
  107. package/dist/odspUrlHelper.js +6 -7
  108. package/dist/odspUrlHelper.js.map +1 -1
  109. package/dist/odspUtils.d.ts.map +1 -1
  110. package/dist/odspUtils.js +21 -21
  111. package/dist/odspUtils.js.map +1 -1
  112. package/dist/odspVersionManager/odspFileVersionFetcher.js +1 -2
  113. package/dist/odspVersionManager/odspFileVersionFetcher.js.map +1 -1
  114. package/dist/odspVersionManager/odspVersionManager.js +9 -8
  115. package/dist/odspVersionManager/odspVersionManager.js.map +1 -1
  116. package/dist/opsCaching.js +7 -1
  117. package/dist/opsCaching.js.map +1 -1
  118. package/dist/packageVersion.d.ts +1 -1
  119. package/dist/packageVersion.d.ts.map +1 -1
  120. package/dist/packageVersion.js +1 -1
  121. package/dist/packageVersion.js.map +1 -1
  122. package/dist/pointInTime.d.ts +15 -0
  123. package/dist/pointInTime.d.ts.map +1 -0
  124. package/dist/pointInTime.js +16 -0
  125. package/dist/pointInTime.js.map +1 -0
  126. package/dist/pointInTimeDriver/createPointInTimeDocumentService.d.ts +34 -0
  127. package/dist/pointInTimeDriver/createPointInTimeDocumentService.d.ts.map +1 -0
  128. package/dist/pointInTimeDriver/createPointInTimeDocumentService.js +101 -0
  129. package/dist/pointInTimeDriver/createPointInTimeDocumentService.js.map +1 -0
  130. package/dist/pointInTimeDriver/odspPointInTimeDocumentService.js +10 -6
  131. package/dist/pointInTimeDriver/odspPointInTimeDocumentService.js.map +1 -1
  132. package/dist/prefetchLatestSnapshot.js +1 -2
  133. package/dist/prefetchLatestSnapshot.js.map +1 -1
  134. package/dist/retryErrorsStorageAdapter.js +3 -1
  135. package/dist/retryErrorsStorageAdapter.js.map +1 -1
  136. package/dist/retryUtils.js +1 -2
  137. package/dist/retryUtils.js.map +1 -1
  138. package/dist/vroom.d.ts.map +1 -1
  139. package/dist/zipItDataRepresentationUtils.d.ts.map +1 -1
  140. package/dist/zipItDataRepresentationUtils.js +20 -15
  141. package/dist/zipItDataRepresentationUtils.js.map +1 -1
  142. package/lib/ReadBufferUtils.js +2 -1
  143. package/lib/ReadBufferUtils.js.map +1 -1
  144. package/lib/WriteBufferUtils.js +2 -4
  145. package/lib/WriteBufferUtils.js.map +1 -1
  146. package/lib/compactSnapshotParser.d.ts.map +1 -1
  147. package/lib/compactSnapshotParser.js +3 -2
  148. package/lib/compactSnapshotParser.js.map +1 -1
  149. package/lib/createFile/createNewUtils.d.ts.map +1 -1
  150. package/lib/createFile/createNewUtils.js +2 -2
  151. package/lib/createFile/createNewUtils.js.map +1 -1
  152. package/lib/epochTracker.d.ts.map +1 -1
  153. package/lib/epochTracker.js +15 -4
  154. package/lib/epochTracker.js.map +1 -1
  155. package/lib/fetchSnapshot.d.ts.map +1 -1
  156. package/lib/getFileLink.d.ts.map +1 -1
  157. package/lib/index.d.ts +3 -4
  158. package/lib/index.d.ts.map +1 -1
  159. package/lib/index.js +3 -6
  160. package/lib/index.js.map +1 -1
  161. package/lib/legacy.d.ts +5 -2
  162. package/lib/legacyAlpha.d.ts +5 -2
  163. package/lib/localOdspDriver/localOdspDeltaStorageService.js +2 -0
  164. package/lib/localOdspDriver/localOdspDeltaStorageService.js.map +1 -1
  165. package/lib/localOdspDriver/localOdspDocumentService.js +5 -1
  166. package/lib/localOdspDriver/localOdspDocumentService.js.map +1 -1
  167. package/lib/localOdspDriver/localOdspDocumentServiceFactory.js +2 -1
  168. package/lib/localOdspDriver/localOdspDocumentServiceFactory.js.map +1 -1
  169. package/lib/localOdspDriver/localOdspDocumentStorageManager.js +4 -1
  170. package/lib/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -1
  171. package/lib/odspCache.js +7 -8
  172. package/lib/odspCache.js.map +1 -1
  173. package/lib/odspDelayLoadedDeltaStream.d.ts.map +1 -1
  174. package/lib/odspDelayLoadedDeltaStream.js +42 -26
  175. package/lib/odspDelayLoadedDeltaStream.js.map +1 -1
  176. package/lib/odspDeltaStorageService.js +14 -1
  177. package/lib/odspDeltaStorageService.js.map +1 -1
  178. package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
  179. package/lib/odspDocumentDeltaConnection.js +58 -41
  180. package/lib/odspDocumentDeltaConnection.js.map +1 -1
  181. package/lib/odspDocumentService.js +16 -1
  182. package/lib/odspDocumentService.js.map +1 -1
  183. package/lib/odspDocumentServiceFactory.d.ts +30 -1
  184. package/lib/odspDocumentServiceFactory.d.ts.map +1 -1
  185. package/lib/odspDocumentServiceFactory.js +28 -1
  186. package/lib/odspDocumentServiceFactory.js.map +1 -1
  187. package/lib/odspDocumentServiceFactoryCore.d.ts +83 -3
  188. package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -1
  189. package/lib/odspDocumentServiceFactoryCore.js +39 -13
  190. package/lib/odspDocumentServiceFactoryCore.js.map +1 -1
  191. package/lib/odspDocumentStorageManager.d.ts.map +1 -1
  192. package/lib/odspDocumentStorageManager.js +32 -14
  193. package/lib/odspDocumentStorageManager.js.map +1 -1
  194. package/lib/odspDocumentStorageServiceBase.js +23 -20
  195. package/lib/odspDocumentStorageServiceBase.js.map +1 -1
  196. package/lib/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
  197. package/lib/odspDriverUrlResolverForShareLink.js +6 -1
  198. package/lib/odspDriverUrlResolverForShareLink.js.map +1 -1
  199. package/lib/odspLayerCompatState.d.ts +8 -1
  200. package/lib/odspLayerCompatState.d.ts.map +1 -1
  201. package/lib/odspLayerCompatState.js +20 -1
  202. package/lib/odspLayerCompatState.js.map +1 -1
  203. package/lib/odspSummaryUploadManager.js +7 -0
  204. package/lib/odspSummaryUploadManager.js.map +1 -1
  205. package/lib/odspUtils.d.ts.map +1 -1
  206. package/lib/odspVersionManager/odspVersionManager.js +7 -6
  207. package/lib/odspVersionManager/odspVersionManager.js.map +1 -1
  208. package/lib/opsCaching.js +7 -1
  209. package/lib/opsCaching.js.map +1 -1
  210. package/lib/packageVersion.d.ts +1 -1
  211. package/lib/packageVersion.d.ts.map +1 -1
  212. package/lib/packageVersion.js +1 -1
  213. package/lib/packageVersion.js.map +1 -1
  214. package/lib/pointInTime.d.ts +15 -0
  215. package/lib/pointInTime.d.ts.map +1 -0
  216. package/lib/pointInTime.js +12 -0
  217. package/lib/pointInTime.js.map +1 -0
  218. package/lib/pointInTimeDriver/createPointInTimeDocumentService.d.ts +34 -0
  219. package/lib/pointInTimeDriver/createPointInTimeDocumentService.d.ts.map +1 -0
  220. package/lib/pointInTimeDriver/createPointInTimeDocumentService.js +99 -0
  221. package/lib/pointInTimeDriver/createPointInTimeDocumentService.js.map +1 -0
  222. package/lib/pointInTimeDriver/odspPointInTimeDocumentService.js +10 -6
  223. package/lib/pointInTimeDriver/odspPointInTimeDocumentService.js.map +1 -1
  224. package/lib/public.d.ts +1 -1
  225. package/lib/retryErrorsStorageAdapter.js +3 -1
  226. package/lib/retryErrorsStorageAdapter.js.map +1 -1
  227. package/lib/vroom.d.ts.map +1 -1
  228. package/lib/zipItDataRepresentationUtils.d.ts.map +1 -1
  229. package/lib/zipItDataRepresentationUtils.js +10 -5
  230. package/lib/zipItDataRepresentationUtils.js.map +1 -1
  231. package/package.json +49 -54
  232. package/src/compactSnapshotParser.ts +6 -2
  233. package/src/createFile/createNewUtils.ts +6 -2
  234. package/src/index.ts +10 -6
  235. package/src/odspDocumentServiceFactory.ts +69 -1
  236. package/src/odspDocumentServiceFactoryCore.ts +105 -4
  237. package/src/odspDocumentStorageManager.ts +2 -2
  238. package/src/odspLayerCompatState.ts +29 -1
  239. package/src/odspVersionManager/DEV.md +9 -8
  240. package/src/packageVersion.ts +1 -1
  241. package/src/pointInTime.ts +30 -0
  242. package/src/pointInTimeDriver/createPointInTimeDocumentService.ts +193 -0
  243. package/src/zipItDataRepresentationUtils.ts +3 -3
  244. package/tsconfig.json +1 -1
  245. package/dist/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.d.ts +0 -41
  246. package/dist/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.d.ts.map +0 -1
  247. package/dist/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.js +0 -132
  248. package/dist/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.js.map +0 -1
  249. package/internal.d.ts +0 -11
  250. package/legacy/alpha.d.ts +0 -11
  251. package/legacy.d.ts +0 -11
  252. package/lib/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.d.ts +0 -41
  253. package/lib/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.d.ts.map +0 -1
  254. package/lib/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.js +0 -128
  255. package/lib/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.js.map +0 -1
  256. package/src/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.ts +0 -260
  257. /package/api-extractor/{api-extractor.current.json → api-extractor-report.current.json} +0 -0
  258. /package/api-extractor/{api-extractor.legacy.json → api-extractor-report.legacy.json} +0 -0
@@ -1,132 +0,0 @@
1
- "use strict";
2
- /*!
3
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
- * Licensed under the MIT License.
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.getOdspPointInTimeDocumentServiceFactory = void 0;
8
- const internal_1 = require("@fluidframework/telemetry-utils/internal");
9
- const epochTracker_js_1 = require("../epochTracker.js");
10
- const odspCache_js_1 = require("../odspCache.js");
11
- const odspDocumentServiceFactoryCore_js_1 = require("../odspDocumentServiceFactoryCore.js");
12
- const odspDriverUrlResolver_js_1 = require("../odspDriverUrlResolver.js");
13
- const odspUtils_js_1 = require("../odspUtils.js");
14
- const index_js_1 = require("../odspVersionManager/index.js");
15
- const odspPointInTimeDocumentService_js_1 = require("./odspPointInTimeDocumentService.js");
16
- class OdspPointInTimeDocumentServiceFactory extends odspDocumentServiceFactoryCore_js_1.OdspDocumentServiceFactoryCore {
17
- /**
18
- * Creates a point-in-time-capable ODSP document service factory.
19
- *
20
- * @param getStorageToken - Fetches storage access tokens.
21
- * @param getWebsocketToken - Fetches websocket access tokens, or `undefined` when unavailable.
22
- * @param persistedCache - Optional persisted ODSP cache.
23
- * @param hostPolicy - Optional host storage policy.
24
- */
25
- constructor(getStorageToken, getWebsocketToken, persistedCache, hostPolicy) {
26
- super(getStorageToken, getWebsocketToken, persistedCache, hostPolicy);
27
- this.getStorageTokenForVersions = getStorageToken;
28
- }
29
- /**
30
- * Creates a document service that reads its snapshot from the closest file version at or before
31
- * the target and its deltas from the live document, materializing a requested sequence number
32
- * through replay.
33
- *
34
- * @param resolvedUrl - The resolved ODSP document URL.
35
- * @param targetSequenceNumber - The sequence number at which to materialize the document.
36
- * @param logger - Optional telemetry logger.
37
- * @param clientIsSummarizer - Whether the requesting client is a summarizer.
38
- * @returns A read-only document service materialized at the requested sequence number.
39
- */
40
- async createPointInTimeDocumentService(resolvedUrl, targetSequenceNumber, logger, clientIsSummarizer) {
41
- const odspLogger = (0, odspUtils_js_1.createOdspLogger)(logger);
42
- const extLogger = (0, internal_1.createChildLogger)({ logger: odspLogger });
43
- const odspResolvedUrl = (0, odspUtils_js_1.getOdspResolvedUrl)(resolvedUrl);
44
- // Build ONE cache-and-tracker and thread its EpochTracker through every read this method
45
- // makes: the version-history reads that pick the base, the recoverable base snapshot, and the
46
- // live op stream. This shared tracker IS the lineage guard.
47
- //
48
- // ODSP stamps each response with the file's epoch; an EpochTracker instance pins itself to the
49
- // first epoch it sees and throws on any later divergence (see setEpoch / checkForEpochError in
50
- // epochTracker.ts).
51
- //
52
- // A fresh NonPersistentCache keeps this read-only historical load isolated from the factory's
53
- // shared cache, so a base file version's snapshot can never leak into a normal live load.
54
- const cacheAndTracker = (0, epochTracker_js_1.createOdspCacheAndTracker)(this.persistedCache, new odspCache_js_1.NonPersistentCache(), {
55
- resolvedUrl: odspResolvedUrl,
56
- docId: odspResolvedUrl.hashedDocumentId,
57
- fileVersion: odspResolvedUrl.fileVersion,
58
- }, extLogger, clientIsSummarizer);
59
- const versionManager = this.createVersionManager(odspResolvedUrl, extLogger, cacheAndTracker.epochTracker);
60
- const baseResult = await versionManager.findBaseForSeq(targetSequenceNumber);
61
- if (baseResult.kind === "noBaseVersion") {
62
- const oldestResolvedSequenceDetail = baseResult.oldestResolvedSeq === undefined
63
- ? ""
64
- : ` The oldest resolved file version is at sequence number ${baseResult.oldestResolvedSeq}.`;
65
- throw new internal_1.UsageError(`No ODSP file version is available at or before sequence number ${targetSequenceNumber}.${oldestResolvedSequenceDetail}`);
66
- }
67
- const recoverableResolvedUrl = await this.resolveFileVersion(resolvedUrl, baseResult.base.versionId);
68
- // Both services are created via createDocumentServiceCore with the shared cacheAndTracker, so
69
- // their reads validate against the same epoch - see the lineage-guard note above.
70
- const recoverableDocumentService = await this.createDocumentServiceCore(recoverableResolvedUrl, odspLogger, cacheAndTracker, clientIsSummarizer);
71
- const liveDocumentService = await this.createDocumentServiceCore(resolvedUrl, odspLogger, cacheAndTracker, clientIsSummarizer);
72
- return new odspPointInTimeDocumentService_js_1.OdspPointInTimeDocumentService(recoverableResolvedUrl, recoverableDocumentService, liveDocumentService, targetSequenceNumber);
73
- }
74
- /**
75
- * Builds an IOdspVersionManager for the given file, which enumerates the file's stored
76
- * versions and resolves the closest version at or before a target sequence number.
77
- *
78
- * @remarks
79
- * The caller passes in the shared {@link EpochTracker} so the version-history reads validate
80
- * against the same epoch as the recoverable and live document services - this is the lineage
81
- * guard used by `createPointInTimeDocumentService`.
82
- * The manager itself only needs the URL parts and an instrumented storage-token/auth-header
83
- * fetcher wired to that tracker.
84
- */
85
- createVersionManager(odspResolvedUrl, logger, epochTracker) {
86
- const urlParts = {
87
- siteUrl: odspResolvedUrl.siteUrl,
88
- driveId: odspResolvedUrl.driveId,
89
- itemId: odspResolvedUrl.itemId,
90
- };
91
- const getAuthHeader = (0, odspUtils_js_1.toInstrumentedOdspStorageTokenFetcher)(logger, urlParts, this.getStorageTokenForVersions);
92
- return (0, index_js_1.createOdspVersionManager)({
93
- urlParts,
94
- getAuthHeader,
95
- epochTracker,
96
- logger,
97
- });
98
- }
99
- async resolveFileVersion(resolvedUrl, fileVersion) {
100
- const odspResolvedUrl = (0, odspUtils_js_1.getOdspResolvedUrl)(resolvedUrl);
101
- const query = new URLSearchParams({
102
- driveId: odspResolvedUrl.driveId,
103
- itemId: odspResolvedUrl.itemId,
104
- fileVersion,
105
- });
106
- if (odspResolvedUrl.dataStorePath !== undefined) {
107
- query.set("path", odspResolvedUrl.dataStorePath);
108
- }
109
- if (odspResolvedUrl.codeHint?.containerPackageName !== undefined) {
110
- query.set("containerPackageName", odspResolvedUrl.codeHint.containerPackageName);
111
- }
112
- return new odspDriverUrlResolver_js_1.OdspDriverUrlResolver().resolve({
113
- url: `${odspResolvedUrl.siteUrl}?${query.toString()}`,
114
- });
115
- }
116
- }
117
- /**
118
- * Creates an ODSP document service factory that supports point-in-time loading.
119
- *
120
- * @param getStorageToken - Fetches storage access tokens.
121
- * @param getWebsocketToken - Fetches websocket access tokens, or `undefined` when unavailable.
122
- * @param persistedCache - Optional persisted ODSP cache.
123
- * @param hostPolicy - Optional host storage policy.
124
- * @returns An ODSP document service factory with point-in-time loading capability.
125
- *
126
- * @legacy @beta
127
- */
128
- function getOdspPointInTimeDocumentServiceFactory(getStorageToken, getWebsocketToken, persistedCache, hostPolicy) {
129
- return new OdspPointInTimeDocumentServiceFactory(getStorageToken, getWebsocketToken, persistedCache, hostPolicy);
130
- }
131
- exports.getOdspPointInTimeDocumentServiceFactory = getOdspPointInTimeDocumentServiceFactory;
132
- //# sourceMappingURL=odspPointInTimeDocumentServiceFactory.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"odspPointInTimeDocumentServiceFactory.js","sourceRoot":"","sources":["../../src/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.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 type { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport type {\n\tIDocumentService,\n\tIDocumentServiceFactory,\n\tIPersistedCache,\n\tIResolvedUrl,\n} from \"@fluidframework/driver-definitions/internal\";\nimport type {\n\tHostStoragePolicy,\n\tIOdspResolvedUrl,\n\tIOdspUrlParts,\n\tOdspResourceTokenFetchOptions,\n\tTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\tUsageError,\n\tcreateChildLogger,\n\ttype TelemetryLoggerExt,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { createOdspCacheAndTracker, type EpochTracker } from \"../epochTracker.js\";\nimport { NonPersistentCache } from \"../odspCache.js\";\nimport { OdspDocumentServiceFactoryCore } from \"../odspDocumentServiceFactoryCore.js\";\nimport { OdspDriverUrlResolver } from \"../odspDriverUrlResolver.js\";\nimport {\n\tcreateOdspLogger,\n\tgetOdspResolvedUrl,\n\ttoInstrumentedOdspStorageTokenFetcher,\n} from \"../odspUtils.js\";\nimport {\n\tcreateOdspVersionManager,\n\ttype IOdspVersionManager,\n} from \"../odspVersionManager/index.js\";\n\nimport { OdspPointInTimeDocumentService } from \"./odspPointInTimeDocumentService.js\";\n\n/**\n * An ODSP document service factory that supports point-in-time (sequence-number-based) loading.\n *\n * @remarks\n * The loader detects this capability structurally, so hosts can pass this factory directly to\n * `loadContainerToSequenceNumber`.\n *\n * @legacy @beta\n */\nexport interface IPointInTimeDocumentServiceFactory extends IDocumentServiceFactory {\n\t/**\n\t * Creates a document service that materializes the document at the requested sequence number.\n\t *\n\t * @param resolvedUrl - The resolved ODSP document URL.\n\t * @param targetSequenceNumber - The sequence number at which to materialize the document.\n\t * @param logger - Optional telemetry logger.\n\t * @param clientIsSummarizer - Whether the requesting client is a summarizer.\n\t * @returns A read-only document service materialized at the requested sequence number.\n\t */\n\tcreatePointInTimeDocumentService(\n\t\tresolvedUrl: IResolvedUrl,\n\t\ttargetSequenceNumber: number,\n\t\tlogger?: ITelemetryBaseLogger,\n\t\tclientIsSummarizer?: boolean,\n\t): Promise<IDocumentService>;\n}\n\nclass OdspPointInTimeDocumentServiceFactory\n\textends OdspDocumentServiceFactoryCore\n\timplements IPointInTimeDocumentServiceFactory\n{\n\t/**\n\t * The storage token fetcher, captured here because the base class keeps it private.\n\t */\n\tprivate readonly getStorageTokenForVersions: TokenFetcher<OdspResourceTokenFetchOptions>;\n\n\t/**\n\t * Creates a point-in-time-capable ODSP document service factory.\n\t *\n\t * @param getStorageToken - Fetches storage access tokens.\n\t * @param getWebsocketToken - Fetches websocket access tokens, or `undefined` when unavailable.\n\t * @param persistedCache - Optional persisted ODSP cache.\n\t * @param hostPolicy - Optional host storage policy.\n\t */\n\tconstructor(\n\t\tgetStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\t\tgetWebsocketToken: TokenFetcher<OdspResourceTokenFetchOptions> | undefined,\n\t\tpersistedCache?: IPersistedCache,\n\t\thostPolicy?: HostStoragePolicy,\n\t) {\n\t\tsuper(getStorageToken, getWebsocketToken, persistedCache, hostPolicy);\n\t\tthis.getStorageTokenForVersions = getStorageToken;\n\t}\n\n\t/**\n\t * Creates a document service that reads its snapshot from the closest file version at or before\n\t * the target and its deltas from the live document, materializing a requested sequence number\n\t * through replay.\n\t *\n\t * @param resolvedUrl - The resolved ODSP document URL.\n\t * @param targetSequenceNumber - The sequence number at which to materialize the document.\n\t * @param logger - Optional telemetry logger.\n\t * @param clientIsSummarizer - Whether the requesting client is a summarizer.\n\t * @returns A read-only document service materialized at the requested sequence number.\n\t */\n\tpublic async createPointInTimeDocumentService(\n\t\tresolvedUrl: IResolvedUrl,\n\t\ttargetSequenceNumber: number,\n\t\tlogger?: ITelemetryBaseLogger,\n\t\tclientIsSummarizer?: boolean,\n\t): Promise<IDocumentService> {\n\t\tconst odspLogger = createOdspLogger(logger);\n\t\tconst extLogger = createChildLogger({ logger: odspLogger });\n\t\tconst odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);\n\n\t\t// Build ONE cache-and-tracker and thread its EpochTracker through every read this method\n\t\t// makes: the version-history reads that pick the base, the recoverable base snapshot, and the\n\t\t// live op stream. This shared tracker IS the lineage guard.\n\t\t//\n\t\t// ODSP stamps each response with the file's epoch; an EpochTracker instance pins itself to the\n\t\t// first epoch it sees and throws on any later divergence (see setEpoch / checkForEpochError in\n\t\t// epochTracker.ts).\n\t\t//\n\t\t// A fresh NonPersistentCache keeps this read-only historical load isolated from the factory's\n\t\t// shared cache, so a base file version's snapshot can never leak into a normal live load.\n\t\tconst cacheAndTracker = createOdspCacheAndTracker(\n\t\t\tthis.persistedCache,\n\t\t\tnew NonPersistentCache(),\n\t\t\t{\n\t\t\t\tresolvedUrl: odspResolvedUrl,\n\t\t\t\tdocId: odspResolvedUrl.hashedDocumentId,\n\t\t\t\tfileVersion: odspResolvedUrl.fileVersion,\n\t\t\t},\n\t\t\textLogger,\n\t\t\tclientIsSummarizer,\n\t\t);\n\n\t\tconst versionManager = this.createVersionManager(\n\t\t\todspResolvedUrl,\n\t\t\textLogger,\n\t\t\tcacheAndTracker.epochTracker,\n\t\t);\n\t\tconst baseResult = await versionManager.findBaseForSeq(targetSequenceNumber);\n\t\tif (baseResult.kind === \"noBaseVersion\") {\n\t\t\tconst oldestResolvedSequenceDetail =\n\t\t\t\tbaseResult.oldestResolvedSeq === undefined\n\t\t\t\t\t? \"\"\n\t\t\t\t\t: ` The oldest resolved file version is at sequence number ${baseResult.oldestResolvedSeq}.`;\n\t\t\tthrow new UsageError(\n\t\t\t\t`No ODSP file version is available at or before sequence number ${targetSequenceNumber}.${oldestResolvedSequenceDetail}`,\n\t\t\t);\n\t\t}\n\n\t\tconst recoverableResolvedUrl = await this.resolveFileVersion(\n\t\t\tresolvedUrl,\n\t\t\tbaseResult.base.versionId,\n\t\t);\n\t\t// Both services are created via createDocumentServiceCore with the shared cacheAndTracker, so\n\t\t// their reads validate against the same epoch - see the lineage-guard note above.\n\t\tconst recoverableDocumentService = await this.createDocumentServiceCore(\n\t\t\trecoverableResolvedUrl,\n\t\t\todspLogger,\n\t\t\tcacheAndTracker,\n\t\t\tclientIsSummarizer,\n\t\t);\n\t\tconst liveDocumentService = await this.createDocumentServiceCore(\n\t\t\tresolvedUrl,\n\t\t\todspLogger,\n\t\t\tcacheAndTracker,\n\t\t\tclientIsSummarizer,\n\t\t);\n\t\treturn new OdspPointInTimeDocumentService(\n\t\t\trecoverableResolvedUrl,\n\t\t\trecoverableDocumentService,\n\t\t\tliveDocumentService,\n\t\t\ttargetSequenceNumber,\n\t\t);\n\t}\n\n\t/**\n\t * Builds an IOdspVersionManager for the given file, which enumerates the file's stored\n\t * versions and resolves the closest version at or before a target sequence number.\n\t *\n\t * @remarks\n\t * The caller passes in the shared {@link EpochTracker} so the version-history reads validate\n\t * against the same epoch as the recoverable and live document services - this is the lineage\n\t * guard used by `createPointInTimeDocumentService`.\n\t * The manager itself only needs the URL parts and an instrumented storage-token/auth-header\n\t * fetcher wired to that tracker.\n\t */\n\tprivate createVersionManager(\n\t\todspResolvedUrl: IOdspResolvedUrl,\n\t\tlogger: TelemetryLoggerExt,\n\t\tepochTracker: EpochTracker,\n\t): IOdspVersionManager {\n\t\tconst urlParts: IOdspUrlParts = {\n\t\t\tsiteUrl: odspResolvedUrl.siteUrl,\n\t\t\tdriveId: odspResolvedUrl.driveId,\n\t\t\titemId: odspResolvedUrl.itemId,\n\t\t};\n\t\tconst getAuthHeader = toInstrumentedOdspStorageTokenFetcher(\n\t\t\tlogger,\n\t\t\turlParts,\n\t\t\tthis.getStorageTokenForVersions,\n\t\t);\n\t\treturn createOdspVersionManager({\n\t\t\turlParts,\n\t\t\tgetAuthHeader,\n\t\t\tepochTracker,\n\t\t\tlogger,\n\t\t});\n\t}\n\n\tprivate async resolveFileVersion(\n\t\tresolvedUrl: IResolvedUrl,\n\t\tfileVersion: string,\n\t): Promise<IResolvedUrl> {\n\t\tconst odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);\n\t\tconst query = new URLSearchParams({\n\t\t\tdriveId: odspResolvedUrl.driveId,\n\t\t\titemId: odspResolvedUrl.itemId,\n\t\t\tfileVersion,\n\t\t});\n\t\tif (odspResolvedUrl.dataStorePath !== undefined) {\n\t\t\tquery.set(\"path\", odspResolvedUrl.dataStorePath);\n\t\t}\n\t\tif (odspResolvedUrl.codeHint?.containerPackageName !== undefined) {\n\t\t\tquery.set(\"containerPackageName\", odspResolvedUrl.codeHint.containerPackageName);\n\t\t}\n\t\treturn new OdspDriverUrlResolver().resolve({\n\t\t\turl: `${odspResolvedUrl.siteUrl}?${query.toString()}`,\n\t\t});\n\t}\n}\n\n/**\n * Creates an ODSP document service factory that supports point-in-time loading.\n *\n * @param getStorageToken - Fetches storage access tokens.\n * @param getWebsocketToken - Fetches websocket access tokens, or `undefined` when unavailable.\n * @param persistedCache - Optional persisted ODSP cache.\n * @param hostPolicy - Optional host storage policy.\n * @returns An ODSP document service factory with point-in-time loading capability.\n *\n * @legacy @beta\n */\nexport function getOdspPointInTimeDocumentServiceFactory(\n\tgetStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\tgetWebsocketToken: TokenFetcher<OdspResourceTokenFetchOptions> | undefined,\n\tpersistedCache?: IPersistedCache,\n\thostPolicy?: HostStoragePolicy,\n): IPointInTimeDocumentServiceFactory {\n\treturn new OdspPointInTimeDocumentServiceFactory(\n\t\tgetStorageToken,\n\t\tgetWebsocketToken,\n\t\tpersistedCache,\n\t\thostPolicy,\n\t);\n}\n"]}
package/internal.d.ts DELETED
@@ -1,11 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
-
6
- /*
7
- * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
8
- * Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outFileLegacyAlpha legacyAlpha --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
9
- */
10
-
11
- export * from "./lib/index.js";
package/legacy/alpha.d.ts DELETED
@@ -1,11 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
-
6
- /*
7
- * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
8
- * Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outFileLegacyAlpha legacyAlpha --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
9
- */
10
-
11
- export * from "../lib/legacyAlpha.js";
package/legacy.d.ts DELETED
@@ -1,11 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
-
6
- /*
7
- * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
8
- * Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outFileLegacyAlpha legacyAlpha --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
9
- */
10
-
11
- export * from "./lib/legacy.js";
@@ -1,41 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import type { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
6
- import type { IDocumentService, IDocumentServiceFactory, IPersistedCache, IResolvedUrl } from "@fluidframework/driver-definitions/internal";
7
- import type { HostStoragePolicy, OdspResourceTokenFetchOptions, TokenFetcher } from "@fluidframework/odsp-driver-definitions/internal";
8
- /**
9
- * An ODSP document service factory that supports point-in-time (sequence-number-based) loading.
10
- *
11
- * @remarks
12
- * The loader detects this capability structurally, so hosts can pass this factory directly to
13
- * `loadContainerToSequenceNumber`.
14
- *
15
- * @legacy @beta
16
- */
17
- export interface IPointInTimeDocumentServiceFactory extends IDocumentServiceFactory {
18
- /**
19
- * Creates a document service that materializes the document at the requested sequence number.
20
- *
21
- * @param resolvedUrl - The resolved ODSP document URL.
22
- * @param targetSequenceNumber - The sequence number at which to materialize the document.
23
- * @param logger - Optional telemetry logger.
24
- * @param clientIsSummarizer - Whether the requesting client is a summarizer.
25
- * @returns A read-only document service materialized at the requested sequence number.
26
- */
27
- createPointInTimeDocumentService(resolvedUrl: IResolvedUrl, targetSequenceNumber: number, logger?: ITelemetryBaseLogger, clientIsSummarizer?: boolean): Promise<IDocumentService>;
28
- }
29
- /**
30
- * Creates an ODSP document service factory that supports point-in-time loading.
31
- *
32
- * @param getStorageToken - Fetches storage access tokens.
33
- * @param getWebsocketToken - Fetches websocket access tokens, or `undefined` when unavailable.
34
- * @param persistedCache - Optional persisted ODSP cache.
35
- * @param hostPolicy - Optional host storage policy.
36
- * @returns An ODSP document service factory with point-in-time loading capability.
37
- *
38
- * @legacy @beta
39
- */
40
- export declare function getOdspPointInTimeDocumentServiceFactory(getStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>, getWebsocketToken: TokenFetcher<OdspResourceTokenFetchOptions> | undefined, persistedCache?: IPersistedCache, hostPolicy?: HostStoragePolicy): IPointInTimeDocumentServiceFactory;
41
- //# sourceMappingURL=odspPointInTimeDocumentServiceFactory.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"odspPointInTimeDocumentServiceFactory.d.ts","sourceRoot":"","sources":["../../src/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,KAAK,EACX,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,YAAY,EACZ,MAAM,6CAA6C,CAAC;AACrD,OAAO,KAAK,EACX,iBAAiB,EAGjB,6BAA6B,EAC7B,YAAY,EACZ,MAAM,kDAAkD,CAAC;AAuB1D;;;;;;;;GAQG;AACH,MAAM,WAAW,kCAAmC,SAAQ,uBAAuB;IAClF;;;;;;;;OAQG;IACH,gCAAgC,CAC/B,WAAW,EAAE,YAAY,EACzB,oBAAoB,EAAE,MAAM,EAC5B,MAAM,CAAC,EAAE,oBAAoB,EAC7B,kBAAkB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC7B;AA0KD;;;;;;;;;;GAUG;AACH,wBAAgB,wCAAwC,CACvD,eAAe,EAAE,YAAY,CAAC,6BAA6B,CAAC,EAC5D,iBAAiB,EAAE,YAAY,CAAC,6BAA6B,CAAC,GAAG,SAAS,EAC1E,cAAc,CAAC,EAAE,eAAe,EAChC,UAAU,CAAC,EAAE,iBAAiB,GAC5B,kCAAkC,CAOpC"}
@@ -1,128 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { UsageError, createChildLogger, } from "@fluidframework/telemetry-utils/internal";
6
- import { createOdspCacheAndTracker } from "../epochTracker.js";
7
- import { NonPersistentCache } from "../odspCache.js";
8
- import { OdspDocumentServiceFactoryCore } from "../odspDocumentServiceFactoryCore.js";
9
- import { OdspDriverUrlResolver } from "../odspDriverUrlResolver.js";
10
- import { createOdspLogger, getOdspResolvedUrl, toInstrumentedOdspStorageTokenFetcher, } from "../odspUtils.js";
11
- import { createOdspVersionManager, } from "../odspVersionManager/index.js";
12
- import { OdspPointInTimeDocumentService } from "./odspPointInTimeDocumentService.js";
13
- class OdspPointInTimeDocumentServiceFactory extends OdspDocumentServiceFactoryCore {
14
- /**
15
- * Creates a point-in-time-capable ODSP document service factory.
16
- *
17
- * @param getStorageToken - Fetches storage access tokens.
18
- * @param getWebsocketToken - Fetches websocket access tokens, or `undefined` when unavailable.
19
- * @param persistedCache - Optional persisted ODSP cache.
20
- * @param hostPolicy - Optional host storage policy.
21
- */
22
- constructor(getStorageToken, getWebsocketToken, persistedCache, hostPolicy) {
23
- super(getStorageToken, getWebsocketToken, persistedCache, hostPolicy);
24
- this.getStorageTokenForVersions = getStorageToken;
25
- }
26
- /**
27
- * Creates a document service that reads its snapshot from the closest file version at or before
28
- * the target and its deltas from the live document, materializing a requested sequence number
29
- * through replay.
30
- *
31
- * @param resolvedUrl - The resolved ODSP document URL.
32
- * @param targetSequenceNumber - The sequence number at which to materialize the document.
33
- * @param logger - Optional telemetry logger.
34
- * @param clientIsSummarizer - Whether the requesting client is a summarizer.
35
- * @returns A read-only document service materialized at the requested sequence number.
36
- */
37
- async createPointInTimeDocumentService(resolvedUrl, targetSequenceNumber, logger, clientIsSummarizer) {
38
- const odspLogger = createOdspLogger(logger);
39
- const extLogger = createChildLogger({ logger: odspLogger });
40
- const odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);
41
- // Build ONE cache-and-tracker and thread its EpochTracker through every read this method
42
- // makes: the version-history reads that pick the base, the recoverable base snapshot, and the
43
- // live op stream. This shared tracker IS the lineage guard.
44
- //
45
- // ODSP stamps each response with the file's epoch; an EpochTracker instance pins itself to the
46
- // first epoch it sees and throws on any later divergence (see setEpoch / checkForEpochError in
47
- // epochTracker.ts).
48
- //
49
- // A fresh NonPersistentCache keeps this read-only historical load isolated from the factory's
50
- // shared cache, so a base file version's snapshot can never leak into a normal live load.
51
- const cacheAndTracker = createOdspCacheAndTracker(this.persistedCache, new NonPersistentCache(), {
52
- resolvedUrl: odspResolvedUrl,
53
- docId: odspResolvedUrl.hashedDocumentId,
54
- fileVersion: odspResolvedUrl.fileVersion,
55
- }, extLogger, clientIsSummarizer);
56
- const versionManager = this.createVersionManager(odspResolvedUrl, extLogger, cacheAndTracker.epochTracker);
57
- const baseResult = await versionManager.findBaseForSeq(targetSequenceNumber);
58
- if (baseResult.kind === "noBaseVersion") {
59
- const oldestResolvedSequenceDetail = baseResult.oldestResolvedSeq === undefined
60
- ? ""
61
- : ` The oldest resolved file version is at sequence number ${baseResult.oldestResolvedSeq}.`;
62
- throw new UsageError(`No ODSP file version is available at or before sequence number ${targetSequenceNumber}.${oldestResolvedSequenceDetail}`);
63
- }
64
- const recoverableResolvedUrl = await this.resolveFileVersion(resolvedUrl, baseResult.base.versionId);
65
- // Both services are created via createDocumentServiceCore with the shared cacheAndTracker, so
66
- // their reads validate against the same epoch - see the lineage-guard note above.
67
- const recoverableDocumentService = await this.createDocumentServiceCore(recoverableResolvedUrl, odspLogger, cacheAndTracker, clientIsSummarizer);
68
- const liveDocumentService = await this.createDocumentServiceCore(resolvedUrl, odspLogger, cacheAndTracker, clientIsSummarizer);
69
- return new OdspPointInTimeDocumentService(recoverableResolvedUrl, recoverableDocumentService, liveDocumentService, targetSequenceNumber);
70
- }
71
- /**
72
- * Builds an IOdspVersionManager for the given file, which enumerates the file's stored
73
- * versions and resolves the closest version at or before a target sequence number.
74
- *
75
- * @remarks
76
- * The caller passes in the shared {@link EpochTracker} so the version-history reads validate
77
- * against the same epoch as the recoverable and live document services - this is the lineage
78
- * guard used by `createPointInTimeDocumentService`.
79
- * The manager itself only needs the URL parts and an instrumented storage-token/auth-header
80
- * fetcher wired to that tracker.
81
- */
82
- createVersionManager(odspResolvedUrl, logger, epochTracker) {
83
- const urlParts = {
84
- siteUrl: odspResolvedUrl.siteUrl,
85
- driveId: odspResolvedUrl.driveId,
86
- itemId: odspResolvedUrl.itemId,
87
- };
88
- const getAuthHeader = toInstrumentedOdspStorageTokenFetcher(logger, urlParts, this.getStorageTokenForVersions);
89
- return createOdspVersionManager({
90
- urlParts,
91
- getAuthHeader,
92
- epochTracker,
93
- logger,
94
- });
95
- }
96
- async resolveFileVersion(resolvedUrl, fileVersion) {
97
- const odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);
98
- const query = new URLSearchParams({
99
- driveId: odspResolvedUrl.driveId,
100
- itemId: odspResolvedUrl.itemId,
101
- fileVersion,
102
- });
103
- if (odspResolvedUrl.dataStorePath !== undefined) {
104
- query.set("path", odspResolvedUrl.dataStorePath);
105
- }
106
- if (odspResolvedUrl.codeHint?.containerPackageName !== undefined) {
107
- query.set("containerPackageName", odspResolvedUrl.codeHint.containerPackageName);
108
- }
109
- return new OdspDriverUrlResolver().resolve({
110
- url: `${odspResolvedUrl.siteUrl}?${query.toString()}`,
111
- });
112
- }
113
- }
114
- /**
115
- * Creates an ODSP document service factory that supports point-in-time loading.
116
- *
117
- * @param getStorageToken - Fetches storage access tokens.
118
- * @param getWebsocketToken - Fetches websocket access tokens, or `undefined` when unavailable.
119
- * @param persistedCache - Optional persisted ODSP cache.
120
- * @param hostPolicy - Optional host storage policy.
121
- * @returns An ODSP document service factory with point-in-time loading capability.
122
- *
123
- * @legacy @beta
124
- */
125
- export function getOdspPointInTimeDocumentServiceFactory(getStorageToken, getWebsocketToken, persistedCache, hostPolicy) {
126
- return new OdspPointInTimeDocumentServiceFactory(getStorageToken, getWebsocketToken, persistedCache, hostPolicy);
127
- }
128
- //# sourceMappingURL=odspPointInTimeDocumentServiceFactory.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"odspPointInTimeDocumentServiceFactory.js","sourceRoot":"","sources":["../../src/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.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 type { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport type {\n\tIDocumentService,\n\tIDocumentServiceFactory,\n\tIPersistedCache,\n\tIResolvedUrl,\n} from \"@fluidframework/driver-definitions/internal\";\nimport type {\n\tHostStoragePolicy,\n\tIOdspResolvedUrl,\n\tIOdspUrlParts,\n\tOdspResourceTokenFetchOptions,\n\tTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport {\n\tUsageError,\n\tcreateChildLogger,\n\ttype TelemetryLoggerExt,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { createOdspCacheAndTracker, type EpochTracker } from \"../epochTracker.js\";\nimport { NonPersistentCache } from \"../odspCache.js\";\nimport { OdspDocumentServiceFactoryCore } from \"../odspDocumentServiceFactoryCore.js\";\nimport { OdspDriverUrlResolver } from \"../odspDriverUrlResolver.js\";\nimport {\n\tcreateOdspLogger,\n\tgetOdspResolvedUrl,\n\ttoInstrumentedOdspStorageTokenFetcher,\n} from \"../odspUtils.js\";\nimport {\n\tcreateOdspVersionManager,\n\ttype IOdspVersionManager,\n} from \"../odspVersionManager/index.js\";\n\nimport { OdspPointInTimeDocumentService } from \"./odspPointInTimeDocumentService.js\";\n\n/**\n * An ODSP document service factory that supports point-in-time (sequence-number-based) loading.\n *\n * @remarks\n * The loader detects this capability structurally, so hosts can pass this factory directly to\n * `loadContainerToSequenceNumber`.\n *\n * @legacy @beta\n */\nexport interface IPointInTimeDocumentServiceFactory extends IDocumentServiceFactory {\n\t/**\n\t * Creates a document service that materializes the document at the requested sequence number.\n\t *\n\t * @param resolvedUrl - The resolved ODSP document URL.\n\t * @param targetSequenceNumber - The sequence number at which to materialize the document.\n\t * @param logger - Optional telemetry logger.\n\t * @param clientIsSummarizer - Whether the requesting client is a summarizer.\n\t * @returns A read-only document service materialized at the requested sequence number.\n\t */\n\tcreatePointInTimeDocumentService(\n\t\tresolvedUrl: IResolvedUrl,\n\t\ttargetSequenceNumber: number,\n\t\tlogger?: ITelemetryBaseLogger,\n\t\tclientIsSummarizer?: boolean,\n\t): Promise<IDocumentService>;\n}\n\nclass OdspPointInTimeDocumentServiceFactory\n\textends OdspDocumentServiceFactoryCore\n\timplements IPointInTimeDocumentServiceFactory\n{\n\t/**\n\t * The storage token fetcher, captured here because the base class keeps it private.\n\t */\n\tprivate readonly getStorageTokenForVersions: TokenFetcher<OdspResourceTokenFetchOptions>;\n\n\t/**\n\t * Creates a point-in-time-capable ODSP document service factory.\n\t *\n\t * @param getStorageToken - Fetches storage access tokens.\n\t * @param getWebsocketToken - Fetches websocket access tokens, or `undefined` when unavailable.\n\t * @param persistedCache - Optional persisted ODSP cache.\n\t * @param hostPolicy - Optional host storage policy.\n\t */\n\tconstructor(\n\t\tgetStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\t\tgetWebsocketToken: TokenFetcher<OdspResourceTokenFetchOptions> | undefined,\n\t\tpersistedCache?: IPersistedCache,\n\t\thostPolicy?: HostStoragePolicy,\n\t) {\n\t\tsuper(getStorageToken, getWebsocketToken, persistedCache, hostPolicy);\n\t\tthis.getStorageTokenForVersions = getStorageToken;\n\t}\n\n\t/**\n\t * Creates a document service that reads its snapshot from the closest file version at or before\n\t * the target and its deltas from the live document, materializing a requested sequence number\n\t * through replay.\n\t *\n\t * @param resolvedUrl - The resolved ODSP document URL.\n\t * @param targetSequenceNumber - The sequence number at which to materialize the document.\n\t * @param logger - Optional telemetry logger.\n\t * @param clientIsSummarizer - Whether the requesting client is a summarizer.\n\t * @returns A read-only document service materialized at the requested sequence number.\n\t */\n\tpublic async createPointInTimeDocumentService(\n\t\tresolvedUrl: IResolvedUrl,\n\t\ttargetSequenceNumber: number,\n\t\tlogger?: ITelemetryBaseLogger,\n\t\tclientIsSummarizer?: boolean,\n\t): Promise<IDocumentService> {\n\t\tconst odspLogger = createOdspLogger(logger);\n\t\tconst extLogger = createChildLogger({ logger: odspLogger });\n\t\tconst odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);\n\n\t\t// Build ONE cache-and-tracker and thread its EpochTracker through every read this method\n\t\t// makes: the version-history reads that pick the base, the recoverable base snapshot, and the\n\t\t// live op stream. This shared tracker IS the lineage guard.\n\t\t//\n\t\t// ODSP stamps each response with the file's epoch; an EpochTracker instance pins itself to the\n\t\t// first epoch it sees and throws on any later divergence (see setEpoch / checkForEpochError in\n\t\t// epochTracker.ts).\n\t\t//\n\t\t// A fresh NonPersistentCache keeps this read-only historical load isolated from the factory's\n\t\t// shared cache, so a base file version's snapshot can never leak into a normal live load.\n\t\tconst cacheAndTracker = createOdspCacheAndTracker(\n\t\t\tthis.persistedCache,\n\t\t\tnew NonPersistentCache(),\n\t\t\t{\n\t\t\t\tresolvedUrl: odspResolvedUrl,\n\t\t\t\tdocId: odspResolvedUrl.hashedDocumentId,\n\t\t\t\tfileVersion: odspResolvedUrl.fileVersion,\n\t\t\t},\n\t\t\textLogger,\n\t\t\tclientIsSummarizer,\n\t\t);\n\n\t\tconst versionManager = this.createVersionManager(\n\t\t\todspResolvedUrl,\n\t\t\textLogger,\n\t\t\tcacheAndTracker.epochTracker,\n\t\t);\n\t\tconst baseResult = await versionManager.findBaseForSeq(targetSequenceNumber);\n\t\tif (baseResult.kind === \"noBaseVersion\") {\n\t\t\tconst oldestResolvedSequenceDetail =\n\t\t\t\tbaseResult.oldestResolvedSeq === undefined\n\t\t\t\t\t? \"\"\n\t\t\t\t\t: ` The oldest resolved file version is at sequence number ${baseResult.oldestResolvedSeq}.`;\n\t\t\tthrow new UsageError(\n\t\t\t\t`No ODSP file version is available at or before sequence number ${targetSequenceNumber}.${oldestResolvedSequenceDetail}`,\n\t\t\t);\n\t\t}\n\n\t\tconst recoverableResolvedUrl = await this.resolveFileVersion(\n\t\t\tresolvedUrl,\n\t\t\tbaseResult.base.versionId,\n\t\t);\n\t\t// Both services are created via createDocumentServiceCore with the shared cacheAndTracker, so\n\t\t// their reads validate against the same epoch - see the lineage-guard note above.\n\t\tconst recoverableDocumentService = await this.createDocumentServiceCore(\n\t\t\trecoverableResolvedUrl,\n\t\t\todspLogger,\n\t\t\tcacheAndTracker,\n\t\t\tclientIsSummarizer,\n\t\t);\n\t\tconst liveDocumentService = await this.createDocumentServiceCore(\n\t\t\tresolvedUrl,\n\t\t\todspLogger,\n\t\t\tcacheAndTracker,\n\t\t\tclientIsSummarizer,\n\t\t);\n\t\treturn new OdspPointInTimeDocumentService(\n\t\t\trecoverableResolvedUrl,\n\t\t\trecoverableDocumentService,\n\t\t\tliveDocumentService,\n\t\t\ttargetSequenceNumber,\n\t\t);\n\t}\n\n\t/**\n\t * Builds an IOdspVersionManager for the given file, which enumerates the file's stored\n\t * versions and resolves the closest version at or before a target sequence number.\n\t *\n\t * @remarks\n\t * The caller passes in the shared {@link EpochTracker} so the version-history reads validate\n\t * against the same epoch as the recoverable and live document services - this is the lineage\n\t * guard used by `createPointInTimeDocumentService`.\n\t * The manager itself only needs the URL parts and an instrumented storage-token/auth-header\n\t * fetcher wired to that tracker.\n\t */\n\tprivate createVersionManager(\n\t\todspResolvedUrl: IOdspResolvedUrl,\n\t\tlogger: TelemetryLoggerExt,\n\t\tepochTracker: EpochTracker,\n\t): IOdspVersionManager {\n\t\tconst urlParts: IOdspUrlParts = {\n\t\t\tsiteUrl: odspResolvedUrl.siteUrl,\n\t\t\tdriveId: odspResolvedUrl.driveId,\n\t\t\titemId: odspResolvedUrl.itemId,\n\t\t};\n\t\tconst getAuthHeader = toInstrumentedOdspStorageTokenFetcher(\n\t\t\tlogger,\n\t\t\turlParts,\n\t\t\tthis.getStorageTokenForVersions,\n\t\t);\n\t\treturn createOdspVersionManager({\n\t\t\turlParts,\n\t\t\tgetAuthHeader,\n\t\t\tepochTracker,\n\t\t\tlogger,\n\t\t});\n\t}\n\n\tprivate async resolveFileVersion(\n\t\tresolvedUrl: IResolvedUrl,\n\t\tfileVersion: string,\n\t): Promise<IResolvedUrl> {\n\t\tconst odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);\n\t\tconst query = new URLSearchParams({\n\t\t\tdriveId: odspResolvedUrl.driveId,\n\t\t\titemId: odspResolvedUrl.itemId,\n\t\t\tfileVersion,\n\t\t});\n\t\tif (odspResolvedUrl.dataStorePath !== undefined) {\n\t\t\tquery.set(\"path\", odspResolvedUrl.dataStorePath);\n\t\t}\n\t\tif (odspResolvedUrl.codeHint?.containerPackageName !== undefined) {\n\t\t\tquery.set(\"containerPackageName\", odspResolvedUrl.codeHint.containerPackageName);\n\t\t}\n\t\treturn new OdspDriverUrlResolver().resolve({\n\t\t\turl: `${odspResolvedUrl.siteUrl}?${query.toString()}`,\n\t\t});\n\t}\n}\n\n/**\n * Creates an ODSP document service factory that supports point-in-time loading.\n *\n * @param getStorageToken - Fetches storage access tokens.\n * @param getWebsocketToken - Fetches websocket access tokens, or `undefined` when unavailable.\n * @param persistedCache - Optional persisted ODSP cache.\n * @param hostPolicy - Optional host storage policy.\n * @returns An ODSP document service factory with point-in-time loading capability.\n *\n * @legacy @beta\n */\nexport function getOdspPointInTimeDocumentServiceFactory(\n\tgetStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\tgetWebsocketToken: TokenFetcher<OdspResourceTokenFetchOptions> | undefined,\n\tpersistedCache?: IPersistedCache,\n\thostPolicy?: HostStoragePolicy,\n): IPointInTimeDocumentServiceFactory {\n\treturn new OdspPointInTimeDocumentServiceFactory(\n\t\tgetStorageToken,\n\t\tgetWebsocketToken,\n\t\tpersistedCache,\n\t\thostPolicy,\n\t);\n}\n"]}