@fluidframework/container-loader 2.116.1 → 2.118.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.
@@ -24,8 +24,9 @@ import {
24
24
  * This is distinct from normal container loading. The supplied
25
25
  * {@link IContainerDriverServices.documentServiceFactory} must be able to materialize the document
26
26
  * at {@link ILoadContainerToSequenceNumberProps.loadToSequenceNumber} - i.e. it must implement the
27
- * point-in-time capability the loader detects. For ODSP, pass an
28
- * `IPointInTimeDocumentServiceFactory` created by `getOdspPointInTimeDocumentServiceFactory`.
27
+ * point-in-time capability the loader detects. For ODSP, call
28
+ * `createOdspDocumentServiceFactory` with the implementation imported from
29
+ * `@fluidframework/odsp-driver/legacy/point-in-time`.
29
30
  *
30
31
  * @legacy @beta
31
32
  */
@@ -58,9 +59,9 @@ export interface ILoadContainerToSequenceNumberProps
58
59
  * The supplied {@link IContainerDriverServices.documentServiceFactory} must support point-in-time
59
60
  * loading: it must be able to serve a snapshot at or before
60
61
  * {@link ILoadContainerToSequenceNumberProps.loadToSequenceNumber} and replay the document forward
61
- * through that sequence number. For ODSP, pass the result of
62
- * `getOdspPointInTimeDocumentServiceFactory` (from `@fluidframework/odsp-driver`) directly - the
63
- * loader materializes the point-in-time view itself, so no wrapping or decoration is required.
62
+ * through that sequence number. For ODSP, inject `createPointInTimeDocumentService` from the
63
+ * dedicated point-in-time entrypoint through `createOdspDocumentServiceFactory` options. The loader
64
+ * materializes the point-in-time view itself, so no wrapping or decoration is required.
64
65
  *
65
66
  * @param props - The load options, point-in-time-capable driver services, target sequence number, and
66
67
  * optional cancellation signal.
@@ -81,7 +82,7 @@ export async function loadContainerToSequenceNumber(
81
82
  const capableFactory = asPointInTimeCapableFactory(documentServiceFactory);
82
83
  if (capableFactory === undefined) {
83
84
  throw new UsageError(
84
- "The provided documentServiceFactory does not support point-in-time loading. For ODSP, pass the result of getOdspPointInTimeDocumentServiceFactory.",
85
+ "The provided documentServiceFactory does not support point-in-time loading. For ODSP, call createOdspDocumentServiceFactory with a point-in-time implementation.",
85
86
  );
86
87
  }
87
88
 
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-loader";
9
- export const pkgVersion = "2.116.1";
9
+ export const pkgVersion = "2.118.0";
@@ -9,12 +9,23 @@ This flow consumes a sequence number. It does not create or resolve version mark
9
9
  The host calls:
10
10
 
11
11
  ```ts
12
+ import { createOdspDocumentServiceFactory } from "@fluidframework/odsp-driver/legacy";
13
+ import { createPointInTimeDocumentService } from "@fluidframework/odsp-driver/legacy/point-in-time";
14
+
15
+ const documentServiceFactory = createOdspDocumentServiceFactory({
16
+ getStorageToken,
17
+ getWebsocketToken,
18
+ persistedCache,
19
+ hostPolicy,
20
+ pointInTimeDocumentServiceImplementation: createPointInTimeDocumentService,
21
+ });
22
+
12
23
  const historicalContainer = await loadContainerToSequenceNumber({
13
24
  request,
14
25
  loadToSequenceNumber,
15
26
  codeLoader,
16
27
  urlResolver,
17
- documentServiceFactory: getOdspPointInTimeDocumentServiceFactory(/* credentials */),
28
+ documentServiceFactory,
18
29
  logger,
19
30
  signal,
20
31
  });
@@ -76,6 +87,28 @@ That service must satisfy the following:
76
87
 
77
88
  The loader detects this capability structurally so callers pass the driver's factory directly. The adapter is internal and cannot create new containers.
78
89
 
90
+ ### Capability typing and validation boundary
91
+
92
+ The point-in-time capability is not part of the general `IDocumentServiceFactory` contract. Fluid
93
+ therefore owns both runtime checks needed to bridge the optional capability:
94
+
95
+ - The host imports `createPointInTimeDocumentService` from the dedicated ODSP point-in-time entrypoint
96
+ and injects it through `createOdspDocumentServiceFactory` options.
97
+ - `asPointInTimeCapableFactory` performs the cross-driver structural check at the loader boundary.
98
+ `loadContainerToSequenceNumber` uses this check before constructing its internal adapter.
99
+
100
+ A host should not repeat the capability check or cast a general factory. It passes the configured
101
+ ODSP factory directly to `loadContainerToSequenceNumber`. Keeping detection in Fluid also gives
102
+ non-ODSP drivers one generic loader boundary to satisfy without exposing their implementation details
103
+ to hosts.
104
+
105
+ If the host-facing orchestration moves to the proposed feature package, the private generic
106
+ capability interface, `asPointInTimeCapableFactory`, and
107
+ `PointInTimeDocumentServiceFactory` move with it. The ODSP public interface, construction helper,
108
+ and implementation remain in `@fluidframework/odsp-driver`. The capability should move into a
109
+ shared driver contract only if multiple drivers need a public compile-time type; structural
110
+ detection is sufficient for the current single-provider alpha API.
111
+
79
112
  ## Package ownership and planned extraction
80
113
 
81
114
  The current placement in `@fluidframework/container-loader` was explicitly described as
@@ -118,7 +151,7 @@ be regenerated rather than edited by hand.
118
151
  | Current owner | What remains | Why |
119
152
  | --- | --- | --- |
120
153
  | `@fluidframework/container-loader` | `loadContainerPaused` and its general loading machinery | This is the driver-agnostic loader primitive. It predates point-in-time loading and is also used by non-ODSP callers. The feature package should compose it rather than duplicate loader internals. |
121
- | `@fluidframework/odsp-driver` | `pointInTimeDriver/`, `odspVersionManager/`, and `getOdspPointInTimeDocumentServiceFactory` | These components depend on ODSP file-version APIs, resolved URLs, caches, storage policies, and epoch tracking. Moving them would either leak ODSP internals into the feature package or duplicate driver construction logic. |
154
+ | `@fluidframework/odsp-driver` | The optional point-in-time capability on `OdspDocumentServiceFactoryCore`, `pointInTimeDriver/`, and `odspVersionManager/` | These components depend on ODSP file-version APIs, resolved URLs, caches, storage policies, and epoch tracking. Moving them would either leak ODSP internals into the feature package or duplicate driver construction logic. |
122
155
  | `@fluidframework/container-runtime` | `versionMarks/` resolver implementation and runtime hooks | Capture and locator resolution are driver-agnostic but tightly coupled to outbound batching, pending state, inbound processing, and the runtime lifecycle. They produce the sequence number consumed by the feature package; they do not perform historical loading. |
123
156
 
124
157
  The new package should not import ODSP directly. Its contract remains capability-based so another
@@ -150,7 +183,14 @@ must not make container-loader depend on ODSP or merge mark resolution into cont
150
183
 
151
184
  ## ODSP implementation
152
185
 
153
- ODSP resolves the closest recoverable driveItem version at or before the target. It then composes:
186
+ `OdspDocumentServiceFactoryCore` exposes the optional `createPointInTimeDocumentService` capability
187
+ only when the consumer supplies an implementation. ODSP owns that implementation in the dedicated
188
+ `@fluidframework/odsp-driver/legacy/point-in-time` entrypoint, while the consumer controls whether the
189
+ feature enters its dependency graph. The consumer injects the implementation through
190
+ `createOdspDocumentServiceFactory` options.
191
+
192
+ For each point-in-time request, ODSP resolves the closest recoverable driveItem version at or before
193
+ the target. It then composes:
154
194
 
155
195
  - storage from that file version;
156
196
  - bounded delta storage from the live document;
@@ -179,7 +219,10 @@ Like normal storage catch-up, retriable network failures may retry for an extend
179
219
  | `loadContainerToSequenceNumber.ts` | Validates the target and driver capability, installs the adapter, and starts the paused load. |
180
220
  | `pointInTimeServices.ts` | Defines the structural driver capability and adapts it to `IDocumentServiceFactory`. |
181
221
  | `loadPaused.ts` | Loads read-only, replays to the exact target, pauses processing, disconnects, and handles cancellation. |
182
- | `packages/drivers/odsp-driver/src/pointInTimeDriver/odspPointInTimeDocumentServiceFactory.ts` | Selects the ODSP base version and creates the historical service with shared epoch tracking. |
222
+ | `packages/drivers/odsp-driver/src/odspDocumentServiceFactory.ts` | Accepts and installs a consumer-supplied PIT implementation and constructs a typed capable factory. |
223
+ | `packages/drivers/odsp-driver/src/odspDocumentServiceFactoryCore.ts` | Defines the injection contract and delegates to the implementation only when supplied. |
224
+ | `packages/drivers/odsp-driver/src/pointInTime.ts` | Dedicated consumer-imported feature entrypoint. |
225
+ | `packages/drivers/odsp-driver/src/pointInTimeDriver/createPointInTimeDocumentService.ts` | Owns ODSP base selection, shared epoch tracking, and historical/live service composition. |
183
226
  | `packages/drivers/odsp-driver/src/pointInTimeDriver/odspPointInTimeDocumentService.ts` | Recombines historical storage with bounded live delta storage and enforces storage-only behavior. |
184
227
 
185
228
  ## Test map