@fluidframework/odsp-driver 2.114.0 → 2.115.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/api-extractor/api-extractor-lint-legacyAlpha.cjs.json +5 -0
- package/api-extractor/api-extractor-lint-legacyAlpha.esm.json +5 -0
- package/api-extractor/api-extractor.legacy.json +5 -1
- package/api-report/odsp-driver.legacy.alpha.api.md +232 -0
- package/dist/getUrlAndHeadersWithAuth.d.ts +4 -0
- package/dist/getUrlAndHeadersWithAuth.d.ts.map +1 -1
- package/dist/getUrlAndHeadersWithAuth.js +4 -0
- package/dist/getUrlAndHeadersWithAuth.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +1 -1
- package/dist/legacyAlpha.d.ts +49 -0
- package/dist/odspVersionManager/odspFileVersionFetcher.d.ts +40 -1
- package/dist/odspVersionManager/odspFileVersionFetcher.d.ts.map +1 -1
- package/dist/odspVersionManager/odspFileVersionFetcher.js +52 -14
- package/dist/odspVersionManager/odspFileVersionFetcher.js.map +1 -1
- package/dist/odspVersionManager/odspVersionManager.d.ts +23 -45
- package/dist/odspVersionManager/odspVersionManager.d.ts.map +1 -1
- package/dist/odspVersionManager/odspVersionManager.js +68 -33
- package/dist/odspVersionManager/odspVersionManager.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pointInTimeDriver/odspPointInTimeDocumentService.d.ts +5 -0
- package/dist/pointInTimeDriver/odspPointInTimeDocumentService.d.ts.map +1 -1
- package/dist/pointInTimeDriver/odspPointInTimeDocumentService.js +6 -3
- package/dist/pointInTimeDriver/odspPointInTimeDocumentService.js.map +1 -1
- package/dist/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.d.ts +25 -33
- package/dist/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.d.ts.map +1 -1
- package/dist/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.js +62 -38
- package/dist/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.js.map +1 -1
- package/dist/public.d.ts +1 -1
- package/internal.d.ts +1 -1
- package/legacy/alpha.d.ts +11 -0
- package/legacy.d.ts +1 -1
- package/lib/getUrlAndHeadersWithAuth.d.ts +4 -0
- package/lib/getUrlAndHeadersWithAuth.d.ts.map +1 -1
- package/lib/getUrlAndHeadersWithAuth.js +4 -0
- package/lib/getUrlAndHeadersWithAuth.js.map +1 -1
- package/lib/index.d.ts +3 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -3
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +1 -1
- package/lib/legacyAlpha.d.ts +49 -0
- package/lib/odspVersionManager/odspFileVersionFetcher.d.ts +40 -1
- package/lib/odspVersionManager/odspFileVersionFetcher.d.ts.map +1 -1
- package/lib/odspVersionManager/odspFileVersionFetcher.js +53 -15
- package/lib/odspVersionManager/odspFileVersionFetcher.js.map +1 -1
- package/lib/odspVersionManager/odspVersionManager.d.ts +23 -45
- package/lib/odspVersionManager/odspVersionManager.d.ts.map +1 -1
- package/lib/odspVersionManager/odspVersionManager.js +68 -33
- package/lib/odspVersionManager/odspVersionManager.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pointInTimeDriver/odspPointInTimeDocumentService.d.ts +5 -0
- package/lib/pointInTimeDriver/odspPointInTimeDocumentService.d.ts.map +1 -1
- package/lib/pointInTimeDriver/odspPointInTimeDocumentService.js +6 -3
- package/lib/pointInTimeDriver/odspPointInTimeDocumentService.js.map +1 -1
- package/lib/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.d.ts +25 -33
- package/lib/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.d.ts.map +1 -1
- package/lib/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.js +62 -38
- package/lib/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.js.map +1 -1
- package/lib/public.d.ts +1 -1
- package/package.json +26 -14
- package/src/getUrlAndHeadersWithAuth.ts +4 -0
- package/src/index.ts +8 -3
- package/src/odspVersionManager/DEV.md +376 -54
- package/src/odspVersionManager/odspFileVersionFetcher.ts +111 -16
- package/src/odspVersionManager/odspVersionManager.ts +106 -68
- package/src/packageVersion.ts +1 -1
- package/src/pointInTimeDriver/odspPointInTimeDocumentService.ts +8 -4
- package/src/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.ts +123 -48
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
7
|
+
exports.getOdspPointInTimeDocumentServiceFactory = void 0;
|
|
8
8
|
const internal_1 = require("@fluidframework/telemetry-utils/internal");
|
|
9
9
|
const epochTracker_js_1 = require("../epochTracker.js");
|
|
10
10
|
const odspCache_js_1 = require("../odspCache.js");
|
|
@@ -13,20 +13,15 @@ const odspDriverUrlResolver_js_1 = require("../odspDriverUrlResolver.js");
|
|
|
13
13
|
const odspUtils_js_1 = require("../odspUtils.js");
|
|
14
14
|
const index_js_1 = require("../odspVersionManager/index.js");
|
|
15
15
|
const odspPointInTimeDocumentService_js_1 = require("./odspPointInTimeDocumentService.js");
|
|
16
|
-
/**
|
|
17
|
-
* ODSP document service factory that additionally supports point-in-time (sequence-number-based)
|
|
18
|
-
* loading.
|
|
19
|
-
*
|
|
20
|
-
* @remarks
|
|
21
|
-
* This extends {@link OdspDocumentServiceFactoryCore} with the ability to materialize a read-only
|
|
22
|
-
* document service at a requested Fluid sequence number. The loader detects this capability via the
|
|
23
|
-
* presence of {@link OdspPointInTimeDocumentServiceFactory.createPointInTimeDocumentService}, so
|
|
24
|
-
* hosts that want to load a container to a target sequence number must construct this factory
|
|
25
|
-
* (rather than the legacy `OdspDocumentServiceFactory`) and pass it to the loader.
|
|
26
|
-
*
|
|
27
|
-
* @internal
|
|
28
|
-
*/
|
|
29
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
|
+
*/
|
|
30
25
|
constructor(getStorageToken, getWebsocketToken, persistedCache, hostPolicy) {
|
|
31
26
|
super(getStorageToken, getWebsocketToken, persistedCache, hostPolicy);
|
|
32
27
|
this.getStorageTokenForVersions = getStorageToken;
|
|
@@ -35,9 +30,33 @@ class OdspPointInTimeDocumentServiceFactory extends odspDocumentServiceFactoryCo
|
|
|
35
30
|
* Creates a document service that reads its snapshot from the closest file version at or before
|
|
36
31
|
* the target and its deltas from the live document, materializing a requested sequence number
|
|
37
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.
|
|
38
39
|
*/
|
|
39
40
|
async createPointInTimeDocumentService(resolvedUrl, targetSequenceNumber, logger, clientIsSummarizer) {
|
|
40
|
-
const
|
|
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);
|
|
41
60
|
const baseResult = await versionManager.findBaseForSeq(targetSequenceNumber);
|
|
42
61
|
if (baseResult.kind === "noBaseVersion") {
|
|
43
62
|
const oldestResolvedSequenceDetail = baseResult.oldestResolvedSeq === undefined
|
|
@@ -46,8 +65,10 @@ class OdspPointInTimeDocumentServiceFactory extends odspDocumentServiceFactoryCo
|
|
|
46
65
|
throw new internal_1.UsageError(`No ODSP file version is available at or before sequence number ${targetSequenceNumber}.${oldestResolvedSequenceDetail}`);
|
|
47
66
|
}
|
|
48
67
|
const recoverableResolvedUrl = await this.resolveFileVersion(resolvedUrl, baseResult.base.versionId);
|
|
49
|
-
|
|
50
|
-
|
|
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);
|
|
51
72
|
return new odspPointInTimeDocumentService_js_1.OdspPointInTimeDocumentService(recoverableResolvedUrl, recoverableDocumentService, liveDocumentService, targetSequenceNumber);
|
|
52
73
|
}
|
|
53
74
|
/**
|
|
@@ -55,35 +76,24 @@ class OdspPointInTimeDocumentServiceFactory extends odspDocumentServiceFactoryCo
|
|
|
55
76
|
* versions and resolves the closest version at or before a target sequence number.
|
|
56
77
|
*
|
|
57
78
|
* @remarks
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* instrumented storage-token/auth-header
|
|
62
|
-
*
|
|
63
|
-
* snapshot for point-in-time loading.
|
|
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.
|
|
64
84
|
*/
|
|
65
|
-
|
|
66
|
-
const odspLogger = (0, odspUtils_js_1.createOdspLogger)(logger);
|
|
67
|
-
const extLogger = (0, internal_1.createChildLogger)({ logger: odspLogger });
|
|
68
|
-
const odspResolvedUrl = (0, odspUtils_js_1.getOdspResolvedUrl)(resolvedUrl);
|
|
85
|
+
createVersionManager(odspResolvedUrl, logger, epochTracker) {
|
|
69
86
|
const urlParts = {
|
|
70
87
|
siteUrl: odspResolvedUrl.siteUrl,
|
|
71
88
|
driveId: odspResolvedUrl.driveId,
|
|
72
89
|
itemId: odspResolvedUrl.itemId,
|
|
73
90
|
};
|
|
74
|
-
|
|
75
|
-
// NonPersistentCache is sufficient here.
|
|
76
|
-
const cacheAndTracker = (0, epochTracker_js_1.createOdspCacheAndTracker)(this.persistedCache, new odspCache_js_1.NonPersistentCache(), {
|
|
77
|
-
resolvedUrl: odspResolvedUrl,
|
|
78
|
-
docId: odspResolvedUrl.hashedDocumentId,
|
|
79
|
-
fileVersion: odspResolvedUrl.fileVersion,
|
|
80
|
-
}, extLogger, clientIsSummarizer);
|
|
81
|
-
const getAuthHeader = (0, odspUtils_js_1.toInstrumentedOdspStorageTokenFetcher)(extLogger, urlParts, this.getStorageTokenForVersions);
|
|
91
|
+
const getAuthHeader = (0, odspUtils_js_1.toInstrumentedOdspStorageTokenFetcher)(logger, urlParts, this.getStorageTokenForVersions);
|
|
82
92
|
return (0, index_js_1.createOdspVersionManager)({
|
|
83
93
|
urlParts,
|
|
84
94
|
getAuthHeader,
|
|
85
|
-
epochTracker
|
|
86
|
-
logger
|
|
95
|
+
epochTracker,
|
|
96
|
+
logger,
|
|
87
97
|
});
|
|
88
98
|
}
|
|
89
99
|
async resolveFileVersion(resolvedUrl, fileVersion) {
|
|
@@ -104,5 +114,19 @@ class OdspPointInTimeDocumentServiceFactory extends odspDocumentServiceFactoryCo
|
|
|
104
114
|
});
|
|
105
115
|
}
|
|
106
116
|
}
|
|
107
|
-
|
|
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 @alpha
|
|
127
|
+
*/
|
|
128
|
+
function getOdspPointInTimeDocumentServiceFactory(getStorageToken, getWebsocketToken, persistedCache, hostPolicy) {
|
|
129
|
+
return new OdspPointInTimeDocumentServiceFactory(getStorageToken, getWebsocketToken, persistedCache, hostPolicy);
|
|
130
|
+
}
|
|
131
|
+
exports.getOdspPointInTimeDocumentServiceFactory = getOdspPointInTimeDocumentServiceFactory;
|
|
108
132
|
//# sourceMappingURL=odspPointInTimeDocumentServiceFactory.js.map
|
|
@@ -1 +1 @@
|
|
|
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\tIPersistedCache,\n\tIResolvedUrl,\n} from \"@fluidframework/driver-definitions/internal\";\nimport type {\n\tHostStoragePolicy,\n\tIOdspUrlParts,\n\tOdspResourceTokenFetchOptions,\n\tTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\nimport { UsageError, createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { createOdspCacheAndTracker } 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 * ODSP document service factory that additionally supports point-in-time (sequence-number-based)\n * loading.\n *\n * @remarks\n * This extends {@link OdspDocumentServiceFactoryCore} with the ability to materialize a read-only\n * document service at a requested Fluid sequence number. The loader detects this capability via the\n * presence of {@link OdspPointInTimeDocumentServiceFactory.createPointInTimeDocumentService}, so\n * hosts that want to load a container to a target sequence number must construct this factory\n * (rather than the legacy `OdspDocumentServiceFactory`) and pass it to the loader.\n *\n * @internal\n */\nexport class OdspPointInTimeDocumentServiceFactory extends OdspDocumentServiceFactoryCore {\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\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\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 versionManager = await this.createVersionManager(\n\t\t\tresolvedUrl,\n\t\t\tlogger,\n\t\t\tclientIsSummarizer,\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\tconst recoverableDocumentService = await this.createDocumentService(\n\t\t\trecoverableResolvedUrl,\n\t\t\tlogger,\n\t\t\tclientIsSummarizer,\n\t\t);\n\t\tconst liveDocumentService = await this.createDocumentService(\n\t\t\tresolvedUrl,\n\t\t\tlogger,\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 * This wires up the plumbing the version manager needs to talk to ODSP: it resolves the URL to\n\t * its ODSP parts (site/drive/item), creates a scoped child logger, an epoch tracker (from a fresh\n\t * NonPersistentCache, since only the tracker is needed for consistency checks), and an\n\t * instrumented storage-token/auth-header fetcher. The resulting manager is used by\n\t * {@link OdspPointInTimeDocumentServiceFactory.createPointInTimeDocumentService} to pick the base\n\t * snapshot for point-in-time loading.\n\t */\n\tprivate async createVersionManager(\n\t\tresolvedUrl: IResolvedUrl,\n\t\tlogger?: ITelemetryBaseLogger,\n\t\tclientIsSummarizer?: boolean,\n\t): Promise<IOdspVersionManager> {\n\t\tconst odspLogger = createOdspLogger(logger);\n\t\tconst extLogger = createChildLogger({ logger: odspLogger });\n\t\tconst odspResolvedUrl = getOdspResolvedUrl(resolvedUrl);\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\t// Only the epochTracker from the returned cacheAndTracker is used below, so a fresh\n\t\t// NonPersistentCache is sufficient here.\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\t\tconst getAuthHeader = toInstrumentedOdspStorageTokenFetcher(\n\t\t\textLogger,\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: cacheAndTracker.epochTracker,\n\t\t\tlogger: extLogger,\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"]}
|
|
1
|
+
{"version":3,"file":"odspPointInTimeDocumentServiceFactory.js","sourceRoot":"","sources":["../../src/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAgBH,uEAIkD;AAElD,wDAAkF;AAClF,kDAAqD;AACrD,4FAAsF;AACtF,0EAAoE;AACpE,kDAIyB;AACzB,6DAGwC;AAExC,2FAAqF;AA6BrF,MAAM,qCACL,SAAQ,kEAA8B;IAQtC;;;;;;;OAOG;IACH,YACC,eAA4D,EAC5D,iBAA0E,EAC1E,cAAgC,EAChC,UAA8B;QAE9B,KAAK,CAAC,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;QACtE,IAAI,CAAC,0BAA0B,GAAG,eAAe,CAAC;IACnD,CAAC;IAED;;;;;;;;;;OAUG;IACI,KAAK,CAAC,gCAAgC,CAC5C,WAAyB,EACzB,oBAA4B,EAC5B,MAA6B,EAC7B,kBAA4B;QAE5B,MAAM,UAAU,GAAG,IAAA,+BAAgB,EAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,SAAS,GAAG,IAAA,4BAAiB,EAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAC5D,MAAM,eAAe,GAAG,IAAA,iCAAkB,EAAC,WAAW,CAAC,CAAC;QAExD,yFAAyF;QACzF,8FAA8F;QAC9F,4DAA4D;QAC5D,EAAE;QACF,+FAA+F;QAC/F,+FAA+F;QAC/F,oBAAoB;QACpB,EAAE;QACF,8FAA8F;QAC9F,0FAA0F;QAC1F,MAAM,eAAe,GAAG,IAAA,2CAAyB,EAChD,IAAI,CAAC,cAAc,EACnB,IAAI,iCAAkB,EAAE,EACxB;YACC,WAAW,EAAE,eAAe;YAC5B,KAAK,EAAE,eAAe,CAAC,gBAAgB;YACvC,WAAW,EAAE,eAAe,CAAC,WAAW;SACxC,EACD,SAAS,EACT,kBAAkB,CAClB,CAAC;QAEF,MAAM,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAC/C,eAAe,EACf,SAAS,EACT,eAAe,CAAC,YAAY,CAC5B,CAAC;QACF,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC;QAC7E,IAAI,UAAU,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YACzC,MAAM,4BAA4B,GACjC,UAAU,CAAC,iBAAiB,KAAK,SAAS;gBACzC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,2DAA2D,UAAU,CAAC,iBAAiB,GAAG,CAAC;YAC/F,MAAM,IAAI,qBAAU,CACnB,kEAAkE,oBAAoB,IAAI,4BAA4B,EAAE,CACxH,CAAC;QACH,CAAC;QAED,MAAM,sBAAsB,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAC3D,WAAW,EACX,UAAU,CAAC,IAAI,CAAC,SAAS,CACzB,CAAC;QACF,8FAA8F;QAC9F,kFAAkF;QAClF,MAAM,0BAA0B,GAAG,MAAM,IAAI,CAAC,yBAAyB,CACtE,sBAAsB,EACtB,UAAU,EACV,eAAe,EACf,kBAAkB,CAClB,CAAC;QACF,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC,yBAAyB,CAC/D,WAAW,EACX,UAAU,EACV,eAAe,EACf,kBAAkB,CAClB,CAAC;QACF,OAAO,IAAI,kEAA8B,CACxC,sBAAsB,EACtB,0BAA0B,EAC1B,mBAAmB,EACnB,oBAAoB,CACpB,CAAC;IACH,CAAC;IAED;;;;;;;;;;OAUG;IACK,oBAAoB,CAC3B,eAAiC,EACjC,MAA0B,EAC1B,YAA0B;QAE1B,MAAM,QAAQ,GAAkB;YAC/B,OAAO,EAAE,eAAe,CAAC,OAAO;YAChC,OAAO,EAAE,eAAe,CAAC,OAAO;YAChC,MAAM,EAAE,eAAe,CAAC,MAAM;SAC9B,CAAC;QACF,MAAM,aAAa,GAAG,IAAA,oDAAqC,EAC1D,MAAM,EACN,QAAQ,EACR,IAAI,CAAC,0BAA0B,CAC/B,CAAC;QACF,OAAO,IAAA,mCAAwB,EAAC;YAC/B,QAAQ;YACR,aAAa;YACb,YAAY;YACZ,MAAM;SACN,CAAC,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAC/B,WAAyB,EACzB,WAAmB;QAEnB,MAAM,eAAe,GAAG,IAAA,iCAAkB,EAAC,WAAW,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC;YACjC,OAAO,EAAE,eAAe,CAAC,OAAO;YAChC,MAAM,EAAE,eAAe,CAAC,MAAM;YAC9B,WAAW;SACX,CAAC,CAAC;QACH,IAAI,eAAe,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;YACjD,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,aAAa,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,eAAe,CAAC,QAAQ,EAAE,oBAAoB,KAAK,SAAS,EAAE,CAAC;YAClE,KAAK,CAAC,GAAG,CAAC,sBAAsB,EAAE,eAAe,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;QAClF,CAAC;QACD,OAAO,IAAI,gDAAqB,EAAE,CAAC,OAAO,CAAC;YAC1C,GAAG,EAAE,GAAG,eAAe,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE;SACrD,CAAC,CAAC;IACJ,CAAC;CACD;AAED;;;;;;;;;;GAUG;AACH,SAAgB,wCAAwC,CACvD,eAA4D,EAC5D,iBAA0E,EAC1E,cAAgC,EAChC,UAA8B;IAE9B,OAAO,IAAI,qCAAqC,CAC/C,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,UAAU,CACV,CAAC;AACH,CAAC;AAZD,4FAYC","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 @alpha\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 @alpha\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/dist/public.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
/*
|
|
7
7
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
8
|
-
* Generated by "flub generate entrypoints --resolutionConditions require --outFileLegacyBeta legacy --outDir ./dist" in @fluid-tools/build-cli.
|
|
8
|
+
* Generated by "flub generate entrypoints --resolutionConditions require --outFileLegacyBeta legacy --outFileLegacyAlpha legacyAlpha --outDir ./dist" in @fluid-tools/build-cli.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
export {}
|
package/internal.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
/*
|
|
7
7
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
8
|
-
* Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
|
|
8
|
+
* Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outFileLegacyAlpha legacyAlpha --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
export * from "./lib/index.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
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
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
/*
|
|
7
7
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
8
|
-
* Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
|
|
8
|
+
* Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outFileLegacyAlpha legacyAlpha --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
export * from "./lib/legacy.js";
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
+
/**
|
|
6
|
+
* Builds the request headers carrying the given Authorization header value.
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
5
9
|
export declare function getHeadersWithAuth(authHeader: string | null): {
|
|
6
10
|
[index: string]: string;
|
|
7
11
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getUrlAndHeadersWithAuth.d.ts","sourceRoot":"","sources":["../src/getUrlAndHeadersWithAuth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,wBAAgB,kBAAkB,CAEjC,UAAU,EAAE,MAAM,GAAG,IAAI,GACvB;IAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAM7B"}
|
|
1
|
+
{"version":3,"file":"getUrlAndHeadersWithAuth.d.ts","sourceRoot":"","sources":["../src/getUrlAndHeadersWithAuth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;GAGG;AACH,wBAAgB,kBAAkB,CAEjC,UAAU,EAAE,MAAM,GAAG,IAAI,GACvB;IAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAM7B"}
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
6
|
+
/**
|
|
7
|
+
* Builds the request headers carrying the given Authorization header value.
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
6
10
|
export function getHeadersWithAuth(
|
|
7
11
|
// eslint-disable-next-line @rushstack/no-new-null
|
|
8
12
|
authHeader) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getUrlAndHeadersWithAuth.js","sourceRoot":"","sources":["../src/getUrlAndHeadersWithAuth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAE7D,MAAM,UAAU,kBAAkB;AACjC,kDAAkD;AAClD,UAAyB;IAEzB,MAAM,CAAC,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAEzE,OAAO;QACN,aAAa,EAAE,UAAU;KACzB,CAAC;AACH,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nexport function getHeadersWithAuth(\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tauthHeader: string | null,\n): { [index: string]: string } {\n\tassert(!!authHeader, 0x936 /* authHeader should not be null or empty */);\n\n\treturn {\n\t\tAuthorization: authHeader,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"getUrlAndHeadersWithAuth.js","sourceRoot":"","sources":["../src/getUrlAndHeadersWithAuth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAE7D;;;GAGG;AACH,MAAM,UAAU,kBAAkB;AACjC,kDAAkD;AAClD,UAAyB;IAEzB,MAAM,CAAC,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAEzE,OAAO;QACN,aAAa,EAAE,UAAU;KACzB,CAAC;AACH,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\n/**\n * Builds the request headers carrying the given Authorization header value.\n * @internal\n */\nexport function getHeadersWithAuth(\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tauthHeader: string | null,\n): { [index: string]: string } {\n\tassert(!!authHeader, 0x936 /* authHeader should not be null or empty */);\n\n\treturn {\n\t\tAuthorization: authHeader,\n\t};\n}\n"]}
|
package/lib/index.d.ts
CHANGED
|
@@ -7,11 +7,12 @@ export { ClpCompliantAppHeader, type IClpCompliantAppHeader, type ISharingLinkHe
|
|
|
7
7
|
export { checkUrl } from "./checkUrl.js";
|
|
8
8
|
export { createOdspUrl } from "./createOdspUrl.js";
|
|
9
9
|
export { getHashedDocumentId, type ISnapshotContents } from "./odspPublicUtils.js";
|
|
10
|
-
export { getOdspUrlParts, isOdcUrl, isSpoUrl } from "./odspUrlHelper.js";
|
|
10
|
+
export { getApiRoot, getOdspUrlParts, isOdcUrl, isSpoUrl } from "./odspUrlHelper.js";
|
|
11
|
+
export { getHeadersWithAuth } from "./getUrlAndHeadersWithAuth.js";
|
|
11
12
|
export { prefetchLatestSnapshot } from "./prefetchLatestSnapshot.js";
|
|
12
13
|
export { createLocalOdspDocumentServiceFactory, OdspDocumentServiceFactory, } from "./odspDocumentServiceFactory.js";
|
|
13
14
|
export { OdspDocumentServiceFactoryCore } from "./odspDocumentServiceFactoryCore.js";
|
|
14
|
-
export {
|
|
15
|
+
export { getOdspPointInTimeDocumentServiceFactory, type IPointInTimeDocumentServiceFactory, } from "./pointInTimeDriver/odspPointInTimeDocumentServiceFactory.js";
|
|
15
16
|
export { createOdspCreateContainerRequest } from "./createOdspCreateContainerRequest.js";
|
|
16
17
|
export { OdspDriverUrlResolver } from "./odspDriverUrlResolver.js";
|
|
17
18
|
export { OdspDriverUrlResolverForShareLink, type ShareLinkFetcherProps, } from "./odspDriverUrlResolverForShareLink.js";
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EACN,qBAAqB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC9B,iBAAiB,GACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EACN,qBAAqB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC9B,iBAAiB,GACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,OAAO,EACN,qCAAqC,EACrC,0BAA0B,GAC1B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAErF,OAAO,EACN,wCAAwC,EACxC,KAAK,kCAAkC,GACvC,MAAM,8DAA8D,CAAC;AAItE,OAAO,EAAE,gCAAgC,EAAE,MAAM,uCAAuC,CAAC;AAGzF,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EACN,iCAAiC,EACjC,KAAK,qBAAqB,GAC1B,MAAM,wCAAwC,CAAC;AAGhD,OAAO,EACN,+BAA+B,EAC/B,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,GACrB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EACX,UAAU,EACV,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,GACzB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACX,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,iBAAiB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EACN,KAAK,0BAA0B,EAC/B,4BAA4B,GAC5B,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -9,14 +9,16 @@ export { ClpCompliantAppHeader, SharingLinkHeader, } from "./contractsPublic.js"
|
|
|
9
9
|
export { checkUrl } from "./checkUrl.js";
|
|
10
10
|
export { createOdspUrl } from "./createOdspUrl.js";
|
|
11
11
|
export { getHashedDocumentId } from "./odspPublicUtils.js";
|
|
12
|
-
export { getOdspUrlParts, isOdcUrl, isSpoUrl } from "./odspUrlHelper.js";
|
|
12
|
+
export { getApiRoot, getOdspUrlParts, isOdcUrl, isSpoUrl } from "./odspUrlHelper.js";
|
|
13
|
+
export { getHeadersWithAuth } from "./getUrlAndHeadersWithAuth.js";
|
|
13
14
|
// prefetch latest snapshot before container load
|
|
14
15
|
export { prefetchLatestSnapshot } from "./prefetchLatestSnapshot.js";
|
|
15
16
|
// Factory
|
|
16
17
|
export { createLocalOdspDocumentServiceFactory, OdspDocumentServiceFactory, } from "./odspDocumentServiceFactory.js";
|
|
17
18
|
export { OdspDocumentServiceFactoryCore } from "./odspDocumentServiceFactoryCore.js";
|
|
18
|
-
|
|
19
|
-
export {
|
|
19
|
+
/* eslint-disable import-x/no-internal-modules */
|
|
20
|
+
export { getOdspPointInTimeDocumentServiceFactory, } from "./pointInTimeDriver/odspPointInTimeDocumentServiceFactory.js";
|
|
21
|
+
/* eslint-enable import-x/no-internal-modules */
|
|
20
22
|
// File creation
|
|
21
23
|
export { createOdspCreateContainerRequest } from "./createOdspCreateContainerRequest.js";
|
|
22
24
|
// URI Resolver functionality, URI management
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY;AACZ,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EACN,qBAAqB,EAIrB,iBAAiB,GACjB,MAAM,sBAAsB,CAAC;AAE9B,eAAe;AACf,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAA0B,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY;AACZ,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EACN,qBAAqB,EAIrB,iBAAiB,GACjB,MAAM,sBAAsB,CAAC;AAE9B,eAAe;AACf,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAA0B,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,iDAAiD;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE,UAAU;AACV,OAAO,EACN,qCAAqC,EACrC,0BAA0B,GAC1B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AACrF,iDAAiD;AACjD,OAAO,EACN,wCAAwC,GAExC,MAAM,8DAA8D,CAAC;AACtE,gDAAgD;AAEhD,gBAAgB;AAChB,OAAO,EAAE,gCAAgC,EAAE,MAAM,uCAAuC,CAAC;AAEzF,6CAA6C;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EACN,iCAAiC,GAEjC,MAAM,wCAAwC,CAAC;AAEhD,oEAAoE;AACpE,OAAO,EACN,+BAA+B,EAC/B,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,GACrB,MAAM,wBAAwB,CAAC;AAchC,OAAO,EAAsB,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAEN,4BAA4B,GAC5B,MAAM,4BAA4B,CAAC;AAEpC,uBAAuB;AACvB,OAAO,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n// Constants\nexport { OdcApiSiteOrigin, OdcFileSiteOrigin } from \"./constants.js\";\n\nexport {\n\tClpCompliantAppHeader,\n\ttype IClpCompliantAppHeader,\n\ttype ISharingLinkHeader,\n\ttype OdspFluidDataStoreLocator,\n\tSharingLinkHeader,\n} from \"./contractsPublic.js\";\n\n// public utils\nexport { checkUrl } from \"./checkUrl.js\";\nexport { createOdspUrl } from \"./createOdspUrl.js\";\nexport { getHashedDocumentId, type ISnapshotContents } from \"./odspPublicUtils.js\";\nexport { getApiRoot, getOdspUrlParts, isOdcUrl, isSpoUrl } from \"./odspUrlHelper.js\";\nexport { getHeadersWithAuth } from \"./getUrlAndHeadersWithAuth.js\";\n\n// prefetch latest snapshot before container load\nexport { prefetchLatestSnapshot } from \"./prefetchLatestSnapshot.js\";\n\n// Factory\nexport {\n\tcreateLocalOdspDocumentServiceFactory,\n\tOdspDocumentServiceFactory,\n} from \"./odspDocumentServiceFactory.js\";\nexport { OdspDocumentServiceFactoryCore } from \"./odspDocumentServiceFactoryCore.js\";\n/* eslint-disable import-x/no-internal-modules */\nexport {\n\tgetOdspPointInTimeDocumentServiceFactory,\n\ttype IPointInTimeDocumentServiceFactory,\n} from \"./pointInTimeDriver/odspPointInTimeDocumentServiceFactory.js\";\n/* eslint-enable import-x/no-internal-modules */\n\n// File creation\nexport { createOdspCreateContainerRequest } from \"./createOdspCreateContainerRequest.js\";\n\n// URI Resolver functionality, URI management\nexport { OdspDriverUrlResolver } from \"./odspDriverUrlResolver.js\";\nexport {\n\tOdspDriverUrlResolverForShareLink,\n\ttype ShareLinkFetcherProps,\n} from \"./odspDriverUrlResolverForShareLink.js\";\n\n// It's used by URL resolve code, but also has some public functions\nexport {\n\tencodeOdspFluidDataStoreLocator,\n\tgetLocatorFromOdspUrl,\n\tlocatorQueryParamName,\n\tstoreLocatorInOdspUrl,\n} from \"./odspFluidFileLink.js\";\n\nexport type {\n\tIOdspCache,\n\tIPersistedFileCache,\n\tINonPersistentCache,\n\tIPrefetchSnapshotContents,\n} from \"./odspCache.js\";\nexport type {\n\tICacheAndTracker,\n\tEpochTracker,\n\tFetchType,\n\tFetchTypeInternal,\n} from \"./epochTracker.js\";\nexport { type IOdspResponse, isOdspResolvedUrl } from \"./odspUtils.js\";\nexport { SnapshotFormatSupportType } from \"./fetchSnapshot.js\";\nexport {\n\ttype ISnapshotContentsWithProps,\n\tparseCompactSnapshotResponse,\n} from \"./compactSnapshotParser.js\";\n\n// Layer Compat details\nexport { odspDriverCompatDetailsForLoader } from \"./odspLayerCompatState.js\";\n"]}
|
package/lib/legacy.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
/*
|
|
7
7
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
8
|
-
* Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
|
|
8
|
+
* Generated by "flub generate entrypoints --outFileLegacyBeta legacy --outFileLegacyAlpha legacyAlpha --outDir ./lib --node10TypeCompat" in @fluid-tools/build-cli.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
export {
|
|
@@ -0,0 +1,49 @@
|
|
|
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 {
|
|
12
|
+
// #region @legacyBeta APIs
|
|
13
|
+
EpochTracker,
|
|
14
|
+
FetchType,
|
|
15
|
+
FetchTypeInternal,
|
|
16
|
+
ICacheAndTracker,
|
|
17
|
+
INonPersistentCache,
|
|
18
|
+
IOdspCache,
|
|
19
|
+
IOdspResponse,
|
|
20
|
+
IPersistedFileCache,
|
|
21
|
+
IPrefetchSnapshotContents,
|
|
22
|
+
ISnapshotContents,
|
|
23
|
+
OdcApiSiteOrigin,
|
|
24
|
+
OdcFileSiteOrigin,
|
|
25
|
+
OdspDocumentServiceFactory,
|
|
26
|
+
OdspDocumentServiceFactoryCore,
|
|
27
|
+
OdspDriverUrlResolver,
|
|
28
|
+
OdspDriverUrlResolverForShareLink,
|
|
29
|
+
OdspFluidDataStoreLocator,
|
|
30
|
+
ShareLinkFetcherProps,
|
|
31
|
+
SnapshotFormatSupportType,
|
|
32
|
+
checkUrl,
|
|
33
|
+
createLocalOdspDocumentServiceFactory,
|
|
34
|
+
createOdspCreateContainerRequest,
|
|
35
|
+
createOdspUrl,
|
|
36
|
+
encodeOdspFluidDataStoreLocator,
|
|
37
|
+
getHashedDocumentId,
|
|
38
|
+
getLocatorFromOdspUrl,
|
|
39
|
+
isOdspResolvedUrl,
|
|
40
|
+
locatorQueryParamName,
|
|
41
|
+
prefetchLatestSnapshot,
|
|
42
|
+
storeLocatorInOdspUrl,
|
|
43
|
+
// #endregion
|
|
44
|
+
|
|
45
|
+
// #region @legacyAlpha APIs
|
|
46
|
+
IPointInTimeDocumentServiceFactory,
|
|
47
|
+
getOdspPointInTimeDocumentServiceFactory
|
|
48
|
+
// #endregion
|
|
49
|
+
} from "./index.js";
|
|
@@ -5,7 +5,46 @@
|
|
|
5
5
|
import type { IOdspUrlParts, InstrumentedStorageTokenFetcher } from "@fluidframework/odsp-driver-definitions/internal";
|
|
6
6
|
import type { TelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
|
|
7
7
|
import type { EpochTracker } from "../epochTracker.js";
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* A single ODSP file version, as listed by the file's version history.
|
|
10
|
+
*/
|
|
11
|
+
export interface OdspFileVersionRef {
|
|
12
|
+
/**
|
|
13
|
+
* The version's label (e.g. `"42.0"`), used to address the version when fetching it.
|
|
14
|
+
*/
|
|
15
|
+
readonly versionId: string;
|
|
16
|
+
/**
|
|
17
|
+
* Last-modified timestamp of this version, ISO-8601.
|
|
18
|
+
*/
|
|
19
|
+
readonly lastModifiedDateTime: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Provides a file's versions and resolves each version's Fluid sequence number. Injected into
|
|
23
|
+
* the version manager so the selection logic does not depend on how versions are fetched.
|
|
24
|
+
*/
|
|
25
|
+
export interface IOdspFileVersionFetcher {
|
|
26
|
+
/**
|
|
27
|
+
* Enumerate the file's versions, newest-first.
|
|
28
|
+
*/
|
|
29
|
+
listFileVersions(): Promise<OdspFileVersionRef[]>;
|
|
30
|
+
/**
|
|
31
|
+
* Resolve a single version's Fluid sequence number. Throws on failure rather than returning a
|
|
32
|
+
* wrong value.
|
|
33
|
+
*/
|
|
34
|
+
resolveSequenceNumber(versionId: string): Promise<number>;
|
|
35
|
+
/**
|
|
36
|
+
* Read the live document's current ODSP epoch (`x-fluid-epoch`), or `undefined`. Epoch identifies
|
|
37
|
+
* the file's binary lineage and changes on a version restore or download-then-reupload; compared
|
|
38
|
+
* with {@link IOdspFileVersionFetcher.getRecoverableVersionEpoch} to confirm a base is on the live
|
|
39
|
+
* document's lineage.
|
|
40
|
+
*/
|
|
41
|
+
getLiveDocumentEpoch(): Promise<string | undefined>;
|
|
42
|
+
/**
|
|
43
|
+
* Read the ODSP epoch of a specific file version, or `undefined`. See
|
|
44
|
+
* {@link IOdspFileVersionFetcher.getLiveDocumentEpoch}.
|
|
45
|
+
*/
|
|
46
|
+
getRecoverableVersionEpoch(versionId: string): Promise<string | undefined>;
|
|
47
|
+
}
|
|
9
48
|
/**
|
|
10
49
|
* Inputs needed to make authenticated requests against a specific ODSP file.
|
|
11
50
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"odspFileVersionFetcher.d.ts","sourceRoot":"","sources":["../../src/odspVersionManager/odspFileVersionFetcher.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"odspFileVersionFetcher.d.ts","sourceRoot":"","sources":["../../src/odspVersionManager/odspFileVersionFetcher.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,OAAO,KAAK,EACX,aAAa,EACb,+BAA+B,EAC/B,MAAM,kDAAkD,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAInF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAOvD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;CACtC;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACvC;;OAEG;IACH,gBAAgB,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAClD;;;OAGG;IACH,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1D;;;;;OAKG;IACH,oBAAoB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACpD;;;OAGG;IACH,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CAC3E;AAmBD;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,+BAA+B,CAAC;IACxD,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;CACpC;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAC3C,KAAK,EAAE,2BAA2B,GAChC,uBAAuB,CA+HzB"}
|
|
@@ -2,11 +2,22 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
+
/*
|
|
6
|
+
* An {@link IOdspFileVersionFetcher} backed by the ODSP REST APIs:
|
|
7
|
+
* - GET /_api/v2.1/.../versions -- enumerate the file's versions.
|
|
8
|
+
* - GET /_api/v2.1/.../versions/{label}/opStream/snapshots/trees/latest?blobs=2 -- fetch a version's
|
|
9
|
+
* snapshot and read its sequence number, parsed with the driver's snapshot parser.
|
|
10
|
+
* - GET /_api/v2.1/.../[versions/{label}/]opStream/snapshots/trees/latest?blobs=0 -- read a version's
|
|
11
|
+
* or the live document's ODSP epoch (`x-fluid-epoch`) to compare their lineage.
|
|
12
|
+
*/
|
|
13
|
+
import { NonRetryableError } from "@fluidframework/driver-utils/internal";
|
|
14
|
+
import { OdspErrorTypes } from "@fluidframework/odsp-driver-definitions/internal";
|
|
5
15
|
import { currentReadVersion, parseCompactSnapshotResponse } from "../compactSnapshotParser.js";
|
|
6
16
|
import { getHeadersWithAuth } from "../getUrlAndHeadersWithAuth.js";
|
|
7
17
|
import { convertOdspSnapshotToSnapshotTreeAndBlobs } from "../odspSnapshotParser.js";
|
|
8
18
|
import { getApiRoot } from "../odspUrlHelper.js";
|
|
9
|
-
import { getWithRetryForTokenRefresh } from "../odspUtils.js";
|
|
19
|
+
import { fetchArray, getWithRetryForTokenRefresh } from "../odspUtils.js";
|
|
20
|
+
import { pkgVersion as driverVersion } from "../packageVersion.js";
|
|
10
21
|
/**
|
|
11
22
|
* Create an {@link IOdspFileVersionFetcher} that talks to a specific ODSP file.
|
|
12
23
|
*/
|
|
@@ -38,18 +49,14 @@ export function createOdspFileVersionFetcher(props) {
|
|
|
38
49
|
return versions;
|
|
39
50
|
});
|
|
40
51
|
const resolveSequenceNumber = async (versionId) => getWithRetryForTokenRefresh(async (options) => {
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
// blob (which carries the sequence number) is included; `deltas=1` is intentionally omitted, as
|
|
44
|
-
// it would bundle the op stream and its op-level sequence numbers.
|
|
52
|
+
// The sequence number lives in the version snapshot's `.protocol/attributes` blob, so fetch the
|
|
53
|
+
// version-scoped snapshot with `blobs=2` to inline it. No op stream needed.
|
|
45
54
|
const url = `${getApiRoot(new URL(siteUrl))}/drives/${driveId}/items/${itemId}/versions/${encodeURIComponent(versionId)}/opStream/snapshots/trees/latest?blobs=2`;
|
|
46
55
|
const method = "GET";
|
|
47
56
|
const token = await getAuthHeader({ ...options, request: { url, method } }, "FileVersionSnapshot");
|
|
48
57
|
const headers = getHeadersWithAuth(token);
|
|
49
|
-
// The
|
|
50
|
-
//
|
|
51
|
-
// binary format version (as the driver's own snapshot fetch does) so the server cannot hand back
|
|
52
|
-
// a binary version this code's parser does not understand.
|
|
58
|
+
// The snapshot comes back as JSON or "ms-fluid" (ODSP's compact binary form). Accept both and
|
|
59
|
+
// pin the binary version (as the driver's snapshot fetch does) so the parser can read it.
|
|
53
60
|
headers.accept = `application/json, application/ms-fluid; v=${currentReadVersion}`;
|
|
54
61
|
const response = await epochTracker.fetch(url, { method, headers }, "treesLatest");
|
|
55
62
|
const contentType = response.headers.get("content-type") ?? "";
|
|
@@ -60,18 +67,49 @@ export function createOdspFileVersionFetcher(props) {
|
|
|
60
67
|
sequenceNumber =
|
|
61
68
|
convertOdspSnapshotToSnapshotTreeAndBlobs(snapshotJson).sequenceNumber;
|
|
62
69
|
}
|
|
63
|
-
else {
|
|
70
|
+
else if (contentType.includes("application/ms-fluid")) {
|
|
64
71
|
// ms-fluid framing: the compact binary form; read it with the driver's compact-snapshot parser.
|
|
65
72
|
const bytes = new Uint8Array(await response.content.arrayBuffer());
|
|
66
73
|
sequenceNumber = parseCompactSnapshotResponse(bytes, logger).sequenceNumber;
|
|
67
74
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
75
|
+
else {
|
|
76
|
+
// Neither framing (e.g. an HTML error page). Throw the driver's typed bad-response error
|
|
77
|
+
// (like fetchSnapshot.ts): canRetry=false stops the loader re-driving, while the
|
|
78
|
+
// incorrectServerResponse errorType still earns one wire-retry from getWithRetryForTokenRefresh.
|
|
79
|
+
throw new NonRetryableError(`ODSP file version ${versionId} snapshot returned an unexpected content-type`, OdspErrorTypes.incorrectServerResponse, { driverVersion, contentType, accept: headers.accept });
|
|
80
|
+
}
|
|
81
|
+
// The sequence number must be a non-negative integer; a missing or malformed one throws the same
|
|
82
|
+
// typed error as above rather than feeding a wrong value into base selection.
|
|
83
|
+
if (!(typeof sequenceNumber === "number" &&
|
|
84
|
+
Number.isInteger(sequenceNumber) &&
|
|
85
|
+
sequenceNumber >= 0)) {
|
|
86
|
+
throw new NonRetryableError(`ODSP file version ${versionId} snapshot has a missing or invalid sequenceNumber (${String(sequenceNumber)})`, OdspErrorTypes.incorrectServerResponse, { driverVersion, contentType, accept: headers.accept });
|
|
72
87
|
}
|
|
73
88
|
return sequenceNumber;
|
|
74
89
|
});
|
|
75
|
-
|
|
90
|
+
const itemRoot = `${getApiRoot(new URL(siteUrl))}/drives/${driveId}/items/${itemId}`;
|
|
91
|
+
// Reads the `x-fluid-epoch` header from `url`. Deliberately uses the raw fetch helper instead of
|
|
92
|
+
// `epochTracker.fetch`: the whole point is to COMPARE the base version's epoch against the live
|
|
93
|
+
// document's epoch, but the shared EpochTracker pins to the first epoch it sees and throws on the
|
|
94
|
+
// second (divergent) read - so it could never yield two epochs to compare. `fetchArray` also lets
|
|
95
|
+
// the body (JSON or ms-fluid binary) be consumed and discarded; only the header is needed.
|
|
96
|
+
const readEpoch = async (url, scenarioName) => getWithRetryForTokenRefresh(async (options) => {
|
|
97
|
+
const method = "GET";
|
|
98
|
+
const token = await getAuthHeader({ ...options, request: { url, method } }, scenarioName);
|
|
99
|
+
const headers = getHeadersWithAuth(token);
|
|
100
|
+
const response = await fetchArray(url, { method, headers });
|
|
101
|
+
return response.headers.get("x-fluid-epoch") ?? undefined;
|
|
102
|
+
});
|
|
103
|
+
const getLiveDocumentEpoch = async () =>
|
|
104
|
+
// The (unversioned) live snapshot endpoint is a current-file read, so its epoch is the live
|
|
105
|
+
// document's epoch. `blobs=0` keeps the response to the tree metadata.
|
|
106
|
+
readEpoch(`${itemRoot}/opStream/snapshots/trees/latest?blobs=0`, "LiveEpoch");
|
|
107
|
+
const getRecoverableVersionEpoch = async (versionId) => readEpoch(`${itemRoot}/versions/${encodeURIComponent(versionId)}/opStream/snapshots/trees/latest?blobs=0`, "FileVersionEpoch");
|
|
108
|
+
return {
|
|
109
|
+
listFileVersions,
|
|
110
|
+
resolveSequenceNumber,
|
|
111
|
+
getLiveDocumentEpoch,
|
|
112
|
+
getRecoverableVersionEpoch,
|
|
113
|
+
};
|
|
76
114
|
}
|
|
77
115
|
//# sourceMappingURL=odspFileVersionFetcher.js.map
|