@fluidframework/datastore 2.0.0-internal.7.3.0 → 2.0.0-internal.7.4.1
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-lint.json +13 -0
- package/api-extractor.json +9 -1
- package/api-report/datastore.api.md +7 -6
- package/dist/dataStoreRuntime.d.ts +14 -8
- package/dist/dataStoreRuntime.d.ts.map +1 -1
- package/dist/dataStoreRuntime.js +40 -11
- package/dist/dataStoreRuntime.js.map +1 -1
- package/dist/datastore-alpha.d.ts +270 -0
- package/dist/datastore-beta.d.ts +87 -0
- package/dist/datastore-public.d.ts +87 -0
- package/dist/datastore-untrimmed.d.ts +337 -0
- package/dist/fluidHandle.d.ts +1 -2
- package/dist/fluidHandle.d.ts.map +1 -1
- package/dist/fluidHandle.js +1 -2
- package/dist/fluidHandle.js.map +1 -1
- package/dist/localChannelContext.d.ts +2 -2
- package/dist/localChannelContext.d.ts.map +1 -1
- package/dist/localChannelContext.js +4 -9
- package/dist/localChannelContext.js.map +1 -1
- package/lib/dataStoreRuntime.d.ts +14 -8
- package/lib/dataStoreRuntime.d.ts.map +1 -1
- package/lib/dataStoreRuntime.js +40 -11
- package/lib/dataStoreRuntime.js.map +1 -1
- package/lib/datastore-alpha.d.ts +270 -0
- package/lib/datastore-beta.d.ts +87 -0
- package/lib/datastore-public.d.ts +87 -0
- package/lib/datastore-untrimmed.d.ts +337 -0
- package/lib/fluidHandle.d.ts +1 -2
- package/lib/fluidHandle.d.ts.map +1 -1
- package/lib/fluidHandle.js +1 -2
- package/lib/fluidHandle.js.map +1 -1
- package/lib/localChannelContext.d.ts +2 -2
- package/lib/localChannelContext.d.ts.map +1 -1
- package/lib/localChannelContext.js +4 -9
- package/lib/localChannelContext.js.map +1 -1
- package/package.json +42 -19
- package/src/dataStoreRuntime.ts +53 -20
- package/src/fluidHandle.ts +1 -2
- package/src/localChannelContext.ts +3 -12
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { AttachState } from '@fluidframework/container-definitions';
|
|
2
|
+
import { FluidObject } from '@fluidframework/core-interfaces';
|
|
3
|
+
import { IAudience } from '@fluidframework/container-definitions';
|
|
4
|
+
import { IChannel } from '@fluidframework/datastore-definitions';
|
|
5
|
+
import { IChannelFactory } from '@fluidframework/datastore-definitions';
|
|
6
|
+
import { IClientDetails } from '@fluidframework/protocol-definitions';
|
|
7
|
+
import { IDeltaManager } from '@fluidframework/container-definitions';
|
|
8
|
+
import { IDocumentMessage } from '@fluidframework/protocol-definitions';
|
|
9
|
+
import { IFluidDataStoreChannel } from '@fluidframework/runtime-definitions';
|
|
10
|
+
import { IFluidDataStoreContext } from '@fluidframework/runtime-definitions';
|
|
11
|
+
import { IFluidDataStoreRuntime } from '@fluidframework/datastore-definitions';
|
|
12
|
+
import { IFluidDataStoreRuntimeEvents } from '@fluidframework/datastore-definitions';
|
|
13
|
+
import { IFluidHandle } from '@fluidframework/core-interfaces';
|
|
14
|
+
import { IFluidHandleContext } from '@fluidframework/core-interfaces';
|
|
15
|
+
import { IGarbageCollectionData } from '@fluidframework/runtime-definitions';
|
|
16
|
+
import { IIdCompressor } from '@fluidframework/runtime-definitions';
|
|
17
|
+
import { IInboundSignalMessage } from '@fluidframework/runtime-definitions';
|
|
18
|
+
import { ILoaderOptions } from '@fluidframework/container-definitions';
|
|
19
|
+
import { IQuorumClients } from '@fluidframework/protocol-definitions';
|
|
20
|
+
import { IRequest } from '@fluidframework/core-interfaces';
|
|
21
|
+
import { IResponse } from '@fluidframework/core-interfaces';
|
|
22
|
+
import { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';
|
|
23
|
+
import { ISummaryTreeWithStats } from '@fluidframework/runtime-definitions';
|
|
24
|
+
import { ITelemetryContext } from '@fluidframework/runtime-definitions';
|
|
25
|
+
import { ITelemetryLoggerExt } from '@fluidframework/telemetry-utils';
|
|
26
|
+
import { TypedEventEmitter } from '@fluid-internal/client-utils';
|
|
27
|
+
import { VisibilityState } from '@fluidframework/runtime-definitions';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @alpha
|
|
31
|
+
*/
|
|
32
|
+
export declare enum DataStoreMessageType {
|
|
33
|
+
Attach = "attach",
|
|
34
|
+
ChannelOp = "op"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Base data store class
|
|
39
|
+
* @alpha
|
|
40
|
+
*/
|
|
41
|
+
export declare class FluidDataStoreRuntime extends TypedEventEmitter<IFluidDataStoreRuntimeEvents> implements IFluidDataStoreChannel, IFluidDataStoreRuntime, IFluidHandleContext {
|
|
42
|
+
private readonly dataStoreContext;
|
|
43
|
+
private readonly sharedObjectRegistry;
|
|
44
|
+
/**
|
|
45
|
+
* @deprecated Instantiate the class using its constructor instead.
|
|
46
|
+
*
|
|
47
|
+
* Loads the data store runtime
|
|
48
|
+
* @param context - The data store context
|
|
49
|
+
* @param sharedObjectRegistry - The registry of shared objects used by this data store
|
|
50
|
+
* @param existing - If loading from an existing file.
|
|
51
|
+
*/
|
|
52
|
+
static load(context: IFluidDataStoreContext, sharedObjectRegistry: ISharedObjectRegistry, existing: boolean): FluidDataStoreRuntime;
|
|
53
|
+
/**
|
|
54
|
+
* {@inheritDoc @fluidframework/datastore-definitions#IFluidDataStoreRuntime.entryPoint}
|
|
55
|
+
*/
|
|
56
|
+
readonly entryPoint: IFluidHandle<FluidObject>;
|
|
57
|
+
/**
|
|
58
|
+
* @deprecated Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
|
|
59
|
+
*/
|
|
60
|
+
get IFluidRouter(): this;
|
|
61
|
+
get connected(): boolean;
|
|
62
|
+
get clientId(): string | undefined;
|
|
63
|
+
get clientDetails(): IClientDetails;
|
|
64
|
+
get isAttached(): boolean;
|
|
65
|
+
get attachState(): AttachState;
|
|
66
|
+
get absolutePath(): string;
|
|
67
|
+
get routeContext(): IFluidHandleContext;
|
|
68
|
+
get idCompressor(): IIdCompressor | undefined;
|
|
69
|
+
get IFluidHandleContext(): this;
|
|
70
|
+
get rootRoutingContext(): this;
|
|
71
|
+
get channelsRoutingContext(): this;
|
|
72
|
+
get objectsRoutingContext(): this;
|
|
73
|
+
private _disposed;
|
|
74
|
+
get disposed(): boolean;
|
|
75
|
+
private readonly contexts;
|
|
76
|
+
private readonly pendingAttach;
|
|
77
|
+
private readonly deferredAttached;
|
|
78
|
+
private readonly localChannelContextQueue;
|
|
79
|
+
private readonly notBoundedChannelContextSet;
|
|
80
|
+
private _attachState;
|
|
81
|
+
visibilityState: VisibilityState;
|
|
82
|
+
private readonly pendingHandlesToMakeVisible;
|
|
83
|
+
readonly id: string;
|
|
84
|
+
readonly options: ILoaderOptions;
|
|
85
|
+
readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
|
|
86
|
+
private readonly quorum;
|
|
87
|
+
private readonly audience;
|
|
88
|
+
private readonly mc;
|
|
89
|
+
get logger(): ITelemetryLoggerExt;
|
|
90
|
+
/**
|
|
91
|
+
* If the summarizer makes local changes, a telemetry event is logged. This has the potential to be very noisy.
|
|
92
|
+
* So, adding a count of how many telemetry events are logged per data store context. This can be
|
|
93
|
+
* controlled via feature flags.
|
|
94
|
+
*/
|
|
95
|
+
private localChangesTelemetryCount;
|
|
96
|
+
/**
|
|
97
|
+
* Invokes the given callback and expects that no ops are submitted
|
|
98
|
+
* until execution finishes. If an op is submitted, an error will be raised.
|
|
99
|
+
*
|
|
100
|
+
* Can be disabled by feature gate `Fluid.ContainerRuntime.DisableOpReentryCheck`
|
|
101
|
+
*
|
|
102
|
+
* @param callback - the callback to be invoked
|
|
103
|
+
*/
|
|
104
|
+
ensureNoDataModelChanges<T>(callback: () => T): T;
|
|
105
|
+
/**
|
|
106
|
+
* Create an instance of a DataStore runtime.
|
|
107
|
+
*
|
|
108
|
+
* @param dataStoreContext - Context object for the runtime.
|
|
109
|
+
* @param sharedObjectRegistry - The registry of shared objects that this data store will be able to instantiate.
|
|
110
|
+
* @param existing - Pass 'true' if loading this datastore from an existing file; pass 'false' otherwise.
|
|
111
|
+
* @param provideEntryPoint - Function to initialize the entryPoint object for the data store runtime. The
|
|
112
|
+
* handle to this data store runtime will point to the object returned by this function. If this function is not
|
|
113
|
+
* provided, the handle will be left undefined. This is here so we can start making handles a first-class citizen
|
|
114
|
+
* and the primary way of interacting with some Fluid objects, and should be used if possible.
|
|
115
|
+
*/
|
|
116
|
+
constructor(dataStoreContext: IFluidDataStoreContext, sharedObjectRegistry: ISharedObjectRegistry, existing: boolean, provideEntryPoint: (runtime: IFluidDataStoreRuntime) => Promise<FluidObject>);
|
|
117
|
+
dispose(): void;
|
|
118
|
+
resolveHandle(request: IRequest): Promise<IResponse>;
|
|
119
|
+
request(request: IRequest): Promise<IResponse>;
|
|
120
|
+
getChannel(id: string): Promise<IChannel>;
|
|
121
|
+
/**
|
|
122
|
+
* Api which allows caller to create the channel first and then add it to the runtime.
|
|
123
|
+
* The channel type should be present in the registry, otherwise the runtime would reject
|
|
124
|
+
* the channel. Also the runtime used to create the channel object should be same to which
|
|
125
|
+
* it is added.
|
|
126
|
+
* @param channel - channel which needs to be added to the runtime.
|
|
127
|
+
*/
|
|
128
|
+
addChannel(channel: IChannel): void;
|
|
129
|
+
createChannel(id: string | undefined, type: string): IChannel;
|
|
130
|
+
private createChannelContext;
|
|
131
|
+
/**
|
|
132
|
+
* Binds a channel with the runtime. If the runtime is attached we will attach the channel right away.
|
|
133
|
+
* If the runtime is not attached we will defer the attach until the runtime attaches.
|
|
134
|
+
* @param channel - channel to be registered.
|
|
135
|
+
*/
|
|
136
|
+
bindChannel(channel: IChannel): void;
|
|
137
|
+
/**
|
|
138
|
+
* This function is called when a data store becomes root. It does the following:
|
|
139
|
+
*
|
|
140
|
+
* 1. Marks the data store locally visible in the container.
|
|
141
|
+
*
|
|
142
|
+
* 2. Attaches the graph of all the handles bound to it.
|
|
143
|
+
*
|
|
144
|
+
* 3. Calls into the data store context to mark it visible in the container too. If the container is globally
|
|
145
|
+
* visible, it will mark us globally visible. Otherwise, it will mark us globally visible when it becomes
|
|
146
|
+
* globally visible.
|
|
147
|
+
*/
|
|
148
|
+
makeVisibleAndAttachGraph(): void;
|
|
149
|
+
/**
|
|
150
|
+
* This function is called when a handle to this data store is added to a visible DDS.
|
|
151
|
+
*/
|
|
152
|
+
attachGraph(): void;
|
|
153
|
+
bind(handle: IFluidHandle): void;
|
|
154
|
+
setConnectionState(connected: boolean, clientId?: string): void;
|
|
155
|
+
getQuorum(): IQuorumClients;
|
|
156
|
+
getAudience(): IAudience;
|
|
157
|
+
uploadBlob(blob: ArrayBufferLike, signal?: AbortSignal): Promise<IFluidHandle<ArrayBufferLike>>;
|
|
158
|
+
private createRemoteChannelContext;
|
|
159
|
+
process(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
|
|
160
|
+
processSignal(message: IInboundSignalMessage, local: boolean): void;
|
|
161
|
+
private isChannelAttached;
|
|
162
|
+
/**
|
|
163
|
+
* Returns the outbound routes of this channel. Currently, all contexts in this channel are considered
|
|
164
|
+
* referenced and are hence outbound. This will change when we have root and non-root channel contexts.
|
|
165
|
+
* The only root contexts will be considered as referenced.
|
|
166
|
+
*/
|
|
167
|
+
private getOutboundRoutes;
|
|
168
|
+
/**
|
|
169
|
+
* Updates the GC nodes of this channel. It does the following:
|
|
170
|
+
* - Adds a back route to self to all its child GC nodes.
|
|
171
|
+
* - Adds a node for this channel.
|
|
172
|
+
* @param builder - The builder that contains the GC nodes for this channel's children.
|
|
173
|
+
*/
|
|
174
|
+
private updateGCNodes;
|
|
175
|
+
/**
|
|
176
|
+
* Generates data used for garbage collection. This includes a list of GC nodes that represent this channel
|
|
177
|
+
* including any of its child channel contexts. Each node has a set of outbound routes to other GC nodes in the
|
|
178
|
+
* document. It does the following:
|
|
179
|
+
*
|
|
180
|
+
* 1. Calls into each child context to get its GC data.
|
|
181
|
+
*
|
|
182
|
+
* 2. Prefixes the child context's id to the GC nodes in the child's GC data. This makes sure that the node can be
|
|
183
|
+
* identified as belonging to the child.
|
|
184
|
+
*
|
|
185
|
+
* 3. Adds a GC node for this channel to the nodes received from the children. All these nodes together represent
|
|
186
|
+
* the GC data of this channel.
|
|
187
|
+
*
|
|
188
|
+
* @param fullGC - true to bypass optimizations and force full generation of GC data.
|
|
189
|
+
*/
|
|
190
|
+
getGCData(fullGC?: boolean): Promise<IGarbageCollectionData>;
|
|
191
|
+
/**
|
|
192
|
+
* After GC has run, called to notify this channel of routes that are used in it. It calls the child contexts to
|
|
193
|
+
* update their used routes.
|
|
194
|
+
* @param usedRoutes - The routes that are used in all contexts in this channel.
|
|
195
|
+
*/
|
|
196
|
+
updateUsedRoutes(usedRoutes: string[]): void;
|
|
197
|
+
/**
|
|
198
|
+
* Called when a new outbound reference is added to another node. This is used by garbage collection to identify
|
|
199
|
+
* all references added in the system.
|
|
200
|
+
* @param srcHandle - The handle of the node that added the reference.
|
|
201
|
+
* @param outboundHandle - The handle of the outbound node that is referenced.
|
|
202
|
+
*/
|
|
203
|
+
private addedGCOutboundReference;
|
|
204
|
+
/**
|
|
205
|
+
* Returns a summary at the current sequence number.
|
|
206
|
+
* @param fullTree - true to bypass optimizations and force a full summary tree
|
|
207
|
+
* @param trackState - This tells whether we should track state from this summary.
|
|
208
|
+
* @param telemetryContext - summary data passed through the layers for telemetry purposes
|
|
209
|
+
*/
|
|
210
|
+
summarize(fullTree?: boolean, trackState?: boolean, telemetryContext?: ITelemetryContext): Promise<ISummaryTreeWithStats>;
|
|
211
|
+
getAttachSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats;
|
|
212
|
+
submitMessage(type: DataStoreMessageType, content: any, localOpMetadata: unknown): void;
|
|
213
|
+
/**
|
|
214
|
+
* Submits the signal to be sent to other clients.
|
|
215
|
+
* @param type - Type of the signal.
|
|
216
|
+
* @param content - Content of the signal.
|
|
217
|
+
* @param targetClientId - When specified, the signal is only sent to the provided client id.
|
|
218
|
+
*/
|
|
219
|
+
submitSignal(type: string, content: any, targetClientId?: string): void;
|
|
220
|
+
/**
|
|
221
|
+
* Will return when the data store is attached.
|
|
222
|
+
*/
|
|
223
|
+
waitAttached(): Promise<void>;
|
|
224
|
+
/**
|
|
225
|
+
* Attach channel should only be called after the data store has been attached
|
|
226
|
+
*/
|
|
227
|
+
private attachChannel;
|
|
228
|
+
private submitChannelOp;
|
|
229
|
+
private submit;
|
|
230
|
+
/**
|
|
231
|
+
* For messages of type MessageType.Operation, finds the right channel and asks it to resubmit the message.
|
|
232
|
+
* For all other messages, just submit it again.
|
|
233
|
+
* This typically happens when we reconnect and there are unacked messages.
|
|
234
|
+
* @param content - The content of the original message.
|
|
235
|
+
* @param localOpMetadata - The local metadata associated with the original message.
|
|
236
|
+
*/
|
|
237
|
+
reSubmit(type: DataStoreMessageType, content: any, localOpMetadata: unknown): void;
|
|
238
|
+
/**
|
|
239
|
+
* Revert a local op.
|
|
240
|
+
* @param content - The content of the original message.
|
|
241
|
+
* @param localOpMetadata - The local metadata associated with the original message.
|
|
242
|
+
*/
|
|
243
|
+
rollback?(type: DataStoreMessageType, content: any, localOpMetadata: unknown): void;
|
|
244
|
+
applyStashedOp(content: any): Promise<unknown>;
|
|
245
|
+
private setChannelDirty;
|
|
246
|
+
private processChannelOp;
|
|
247
|
+
private attachListener;
|
|
248
|
+
private verifyNotClosed;
|
|
249
|
+
/**
|
|
250
|
+
* Summarizer client should not have local changes. These changes can become part of the summary and can break
|
|
251
|
+
* eventual consistency. For example, the next summary (say at ref seq# 100) may contain these changes whereas
|
|
252
|
+
* other clients that are up-to-date till seq# 100 may not have them yet.
|
|
253
|
+
*/
|
|
254
|
+
private identifyLocalChangeInSummarizer;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Handle for a shared {@link @fluidframework/core-interfaces#FluidObject}.
|
|
259
|
+
* @internal
|
|
260
|
+
*/
|
|
261
|
+
export declare class FluidObjectHandle<T extends FluidObject = FluidObject> implements IFluidHandle {
|
|
262
|
+
protected readonly value: T | Promise<T>;
|
|
263
|
+
readonly path: string;
|
|
264
|
+
readonly routeContext: IFluidHandleContext;
|
|
265
|
+
private readonly pendingHandlesToMakeVisible;
|
|
266
|
+
/**
|
|
267
|
+
* {@inheritDoc @fluidframework/core-interfaces#IFluidHandle.absolutePath}
|
|
268
|
+
*/
|
|
269
|
+
readonly absolutePath: string;
|
|
270
|
+
/**
|
|
271
|
+
* {@inheritDoc @fluidframework/core-interfaces#IProvideFluidHandle.IFluidHandle}
|
|
272
|
+
*/
|
|
273
|
+
get IFluidHandle(): IFluidHandle;
|
|
274
|
+
/**
|
|
275
|
+
* {@inheritDoc @fluidframework/core-interfaces#IFluidHandle.isAttached}
|
|
276
|
+
*/
|
|
277
|
+
get isAttached(): boolean;
|
|
278
|
+
/**
|
|
279
|
+
* Tells whether the object of this handle is visible in the container locally or globally.
|
|
280
|
+
*/
|
|
281
|
+
private get visible();
|
|
282
|
+
/**
|
|
283
|
+
* Tracks whether this handle is locally visible in the container.
|
|
284
|
+
*/
|
|
285
|
+
private locallyVisible;
|
|
286
|
+
/**
|
|
287
|
+
* Creates a new `FluidObjectHandle`.
|
|
288
|
+
*
|
|
289
|
+
* @param value - The {@link @fluidframework/core-interfaces#FluidObject} object this handle is for.
|
|
290
|
+
* @param path - The path to this handle relative to the `routeContext`.
|
|
291
|
+
* @param routeContext - The parent {@link @fluidframework/core-interfaces#IFluidHandleContext} that has a route
|
|
292
|
+
* to this handle.
|
|
293
|
+
*/
|
|
294
|
+
constructor(value: T | Promise<T>, path: string, routeContext: IFluidHandleContext);
|
|
295
|
+
/**
|
|
296
|
+
* {@inheritDoc @fluidframework/core-interfaces#IFluidHandle.get}
|
|
297
|
+
*/
|
|
298
|
+
get(): Promise<any>;
|
|
299
|
+
/**
|
|
300
|
+
* {@inheritDoc @fluidframework/core-interfaces#IFluidHandle.attachGraph }
|
|
301
|
+
*/
|
|
302
|
+
attachGraph(): void;
|
|
303
|
+
/**
|
|
304
|
+
* {@inheritDoc @fluidframework/core-interfaces#IFluidHandle.bind}
|
|
305
|
+
*/
|
|
306
|
+
bind(handle: IFluidHandle): void;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* @alpha
|
|
311
|
+
*/
|
|
312
|
+
export declare interface ISharedObjectRegistry {
|
|
313
|
+
get(name: string): IChannelFactory | undefined;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Mixin class that adds request handler to FluidDataStoreRuntime
|
|
318
|
+
* Request handler is only called when data store can't resolve request, i.e. for custom requests.
|
|
319
|
+
* @param Base - base class, inherits from FluidDataStoreRuntime
|
|
320
|
+
* @param requestHandler - request handler to mix in
|
|
321
|
+
* @internal
|
|
322
|
+
*/
|
|
323
|
+
export declare const mixinRequestHandler: (requestHandler: (request: IRequest, runtime: FluidDataStoreRuntime) => Promise<IResponse>, Base?: typeof FluidDataStoreRuntime) => typeof FluidDataStoreRuntime;
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Mixin class that adds await for DataObject to finish initialization before we proceed to summary.
|
|
327
|
+
* @param handler - handler that returns info about blob to be added to summary.
|
|
328
|
+
* Or undefined not to add anything to summary.
|
|
329
|
+
* @param Base - base class, inherits from FluidDataStoreRuntime
|
|
330
|
+
* @internal
|
|
331
|
+
*/
|
|
332
|
+
export declare const mixinSummaryHandler: (handler: (runtime: FluidDataStoreRuntime) => Promise<{
|
|
333
|
+
path: string[];
|
|
334
|
+
content: string;
|
|
335
|
+
} | undefined>, Base?: typeof FluidDataStoreRuntime) => typeof FluidDataStoreRuntime;
|
|
336
|
+
|
|
337
|
+
export { }
|
package/lib/fluidHandle.d.ts
CHANGED
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
import { IFluidHandle, IFluidHandleContext, FluidObject } from "@fluidframework/core-interfaces";
|
|
6
6
|
/**
|
|
7
7
|
* Handle for a shared {@link @fluidframework/core-interfaces#FluidObject}.
|
|
8
|
-
*
|
|
9
|
-
* @public
|
|
8
|
+
* @internal
|
|
10
9
|
*/
|
|
11
10
|
export declare class FluidObjectHandle<T extends FluidObject = FluidObject> implements IFluidHandle {
|
|
12
11
|
protected readonly value: T | Promise<T>;
|
package/lib/fluidHandle.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidHandle.d.ts","sourceRoot":"","sources":["../src/fluidHandle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAGjG
|
|
1
|
+
{"version":3,"file":"fluidHandle.d.ts","sourceRoot":"","sources":["../src/fluidHandle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAGjG;;;GAGG;AACH,qBAAa,iBAAiB,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,CAAE,YAAW,YAAY;IAuDzF,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;aACxB,IAAI,EAAE,MAAM;aACZ,YAAY,EAAE,mBAAmB;IAxDlD,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAgC;IAE5E;;OAEG;IACH,SAAgB,YAAY,EAAE,MAAM,CAAC;IAErC;;OAEG;IACH,IAAW,YAAY,IAAI,YAAY,CAEtC;IAED;;OAEG;IACH,IAAW,UAAU,IAAI,OAAO,CAE/B;IAED;;OAEG;IACH,OAAO,KAAK,OAAO,GAclB;IAED;;OAEG;IACH,OAAO,CAAC,cAAc,CAAkB;IAExC;;;;;;;OAOG;gBAEiB,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EACxB,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,mBAAmB;IAKlD;;OAEG;IACU,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IAKhC;;OAEG;IACI,WAAW,IAAI,IAAI;IAa1B;;OAEG;IACI,IAAI,CAAC,MAAM,EAAE,YAAY;CAQhC"}
|
package/lib/fluidHandle.js
CHANGED
package/lib/fluidHandle.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidHandle.js","sourceRoot":"","sources":["../src/fluidHandle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAE1E
|
|
1
|
+
{"version":3,"file":"fluidHandle.js","sourceRoot":"","sources":["../src/fluidHandle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAE1E;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IAQ7B;;OAEG;IACH,IAAW,YAAY;QACtB,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;OAEG;IACH,IAAW,UAAU;QACpB,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,IAAY,OAAO;QAClB;;;;;;;;;;;WAWG;QACH,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,cAAc,CAAC;IAC/C,CAAC;IAOD;;;;;;;OAOG;IACH,YACoB,KAAqB,EACxB,IAAY,EACZ,YAAiC;QAF9B,UAAK,GAAL,KAAK,CAAgB;QACxB,SAAI,GAAJ,IAAI,CAAQ;QACZ,iBAAY,GAAZ,YAAY,CAAqB;QAxDjC,gCAA2B,GAAsB,IAAI,GAAG,EAAE,CAAC;QAwC5E;;WAEG;QACK,mBAAc,GAAY,KAAK,CAAC;QAevC,IAAI,CAAC,YAAY,GAAG,yBAAyB,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACxE,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,GAAG;QACf,yGAAyG;QACzG,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED;;OAEG;IACI,WAAW;QACjB,IAAI,IAAI,CAAC,OAAO,EAAE;YACjB,OAAO;SACP;QAED,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,2BAA2B,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YACnD,MAAM,CAAC,WAAW,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,2BAA2B,CAAC,KAAK,EAAE,CAAC;QACzC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;IACjC,CAAC;IAED;;OAEG;IACI,IAAI,CAAC,MAAoB;QAC/B,8EAA8E;QAC9E,IAAI,IAAI,CAAC,OAAO,EAAE;YACjB,MAAM,CAAC,WAAW,EAAE,CAAC;YACrB,OAAO;SACP;QACD,IAAI,CAAC,2BAA2B,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IFluidHandle, IFluidHandleContext, FluidObject } from \"@fluidframework/core-interfaces\";\nimport { generateHandleContextPath } from \"@fluidframework/runtime-utils\";\n\n/**\n * Handle for a shared {@link @fluidframework/core-interfaces#FluidObject}.\n * @internal\n */\nexport class FluidObjectHandle<T extends FluidObject = FluidObject> implements IFluidHandle {\n\tprivate readonly pendingHandlesToMakeVisible: Set<IFluidHandle> = new Set();\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#IFluidHandle.absolutePath}\n\t */\n\tpublic readonly absolutePath: string;\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#IProvideFluidHandle.IFluidHandle}\n\t */\n\tpublic get IFluidHandle(): IFluidHandle {\n\t\treturn this;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#IFluidHandle.isAttached}\n\t */\n\tpublic get isAttached(): boolean {\n\t\treturn this.routeContext.isAttached;\n\t}\n\n\t/**\n\t * Tells whether the object of this handle is visible in the container locally or globally.\n\t */\n\tprivate get visible(): boolean {\n\t\t/**\n\t\t * If the object of this handle is attached, it is visible in the container. Ideally, checking local visibility\n\t\t * should be enough for a handle. However, there are scenarios where the object becomes locally visible but the\n\t\t * handle does not know this - This will happen is attachGraph is never called on the handle. Couple of examples\n\t\t * where this can happen:\n\t\t *\n\t\t * 1. Handles to DDS other than the default handle won't know if the DDS becomes visible after the handle was\n\t\t * created.\n\t\t *\n\t\t * 2. Handles to root data stores will never know that it was visible because the handle will not be stores in\n\t\t * another DDS and so, attachGraph will never be called on it.\n\t\t */\n\t\treturn this.isAttached || this.locallyVisible;\n\t}\n\n\t/**\n\t * Tracks whether this handle is locally visible in the container.\n\t */\n\tprivate locallyVisible: boolean = false;\n\n\t/**\n\t * Creates a new `FluidObjectHandle`.\n\t *\n\t * @param value - The {@link @fluidframework/core-interfaces#FluidObject} object this handle is for.\n\t * @param path - The path to this handle relative to the `routeContext`.\n\t * @param routeContext - The parent {@link @fluidframework/core-interfaces#IFluidHandleContext} that has a route\n\t * to this handle.\n\t */\n\tconstructor(\n\t\tprotected readonly value: T | Promise<T>,\n\t\tpublic readonly path: string,\n\t\tpublic readonly routeContext: IFluidHandleContext,\n\t) {\n\t\tthis.absolutePath = generateHandleContextPath(path, this.routeContext);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#IFluidHandle.get}\n\t */\n\tpublic async get(): Promise<any> {\n\t\t// Note that this return works whether we received a T or a Promise<T> for this.value in the constructor.\n\t\treturn this.value;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#IFluidHandle.attachGraph }\n\t */\n\tpublic attachGraph(): void {\n\t\tif (this.visible) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.locallyVisible = true;\n\t\tthis.pendingHandlesToMakeVisible.forEach((handle) => {\n\t\t\thandle.attachGraph();\n\t\t});\n\t\tthis.pendingHandlesToMakeVisible.clear();\n\t\tthis.routeContext.attachGraph();\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/core-interfaces#IFluidHandle.bind}\n\t */\n\tpublic bind(handle: IFluidHandle) {\n\t\t// If this handle is visible, attach the graph of the incoming handle as well.\n\t\tif (this.visible) {\n\t\t\thandle.attachGraph();\n\t\t\treturn;\n\t\t}\n\t\tthis.pendingHandlesToMakeVisible.add(handle);\n\t}\n}\n"]}
|
|
@@ -56,8 +56,8 @@ export declare class RehydratedLocalChannelContext extends LocalChannelContextBa
|
|
|
56
56
|
private sanitizeSnapshot;
|
|
57
57
|
}
|
|
58
58
|
export declare class LocalChannelContext extends LocalChannelContextBase {
|
|
59
|
-
private readonly dirtyFn;
|
|
60
59
|
readonly channel: IChannel;
|
|
61
|
-
|
|
60
|
+
private readonly dirtyFn;
|
|
61
|
+
constructor(channel: IChannel, runtime: IFluidDataStoreRuntime, dataStoreContext: IFluidDataStoreContext, storageService: IDocumentStorageService, logger: ITelemetryLoggerExt, submitFn: (content: any, localOpMetadata: unknown) => void, dirtyFn: (address: string) => void, addedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void);
|
|
62
62
|
}
|
|
63
63
|
//# sourceMappingURL=localChannelContext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localChannelContext.d.ts","sourceRoot":"","sources":["../src/localChannelContext.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"localChannelContext.d.ts","sourceRoot":"","sources":["../src/localChannelContext.ts"],"names":[],"mappings":"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"}
|
|
@@ -165,19 +165,14 @@ export class RehydratedLocalChannelContext extends LocalChannelContextBase {
|
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
export class LocalChannelContext extends LocalChannelContextBase {
|
|
168
|
-
constructor(
|
|
169
|
-
|
|
170
|
-
const factory = registry.get(type);
|
|
171
|
-
if (factory === undefined) {
|
|
172
|
-
throw new Error(`Channel Factory ${type} not registered`);
|
|
173
|
-
}
|
|
174
|
-
const channel = factory.create(runtime, id);
|
|
175
|
-
super(id, runtime, new Lazy(() => {
|
|
168
|
+
constructor(channel, runtime, dataStoreContext, storageService, logger, submitFn, dirtyFn, addedGCOutboundReferenceFn) {
|
|
169
|
+
super(channel.id, runtime, new Lazy(() => {
|
|
176
170
|
return createChannelServiceEndpoints(dataStoreContext.connected, submitFn, this.dirtyFn, addedGCOutboundReferenceFn, storageService, logger);
|
|
177
171
|
}), Promise.resolve(channel), channel);
|
|
178
172
|
this.channel = channel;
|
|
173
|
+
this.channel = channel;
|
|
179
174
|
this.dirtyFn = () => {
|
|
180
|
-
dirtyFn(id);
|
|
175
|
+
dirtyFn(channel.id);
|
|
181
176
|
};
|
|
182
177
|
}
|
|
183
178
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localChannelContext.js","sourceRoot":"","sources":["../src/localChannelContext.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\n// eslint-disable-next-line import/no-internal-modules\nimport cloneDeep from \"lodash/cloneDeep\";\nimport { DataProcessingError, ITelemetryLoggerExt } from \"@fluidframework/telemetry-utils\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { IChannel, IFluidDataStoreRuntime } from \"@fluidframework/datastore-definitions\";\nimport {\n\tIFluidDataStoreContext,\n\tIGarbageCollectionData,\n\tISummarizeResult,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { assert, Lazy, LazyPromise } from \"@fluidframework/core-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport {\n\tChannelServiceEndpoints,\n\tcreateChannelServiceEndpoints,\n\tIChannelContext,\n\tloadChannel,\n\tloadChannelFactoryAndAttributes,\n\tsummarizeChannel,\n\tsummarizeChannelAsync,\n} from \"./channelContext\";\nimport { ISharedObjectRegistry } from \"./dataStoreRuntime\";\n\n/**\n * Channel context for a locally created channel\n */\nexport abstract class LocalChannelContextBase implements IChannelContext {\n\tprivate globallyVisible = false;\n\tprotected readonly pending: ISequencedDocumentMessage[] = [];\n\tconstructor(\n\t\tprotected readonly id: string,\n\t\tprotected readonly runtime: IFluidDataStoreRuntime,\n\t\tprotected readonly services: Lazy<ChannelServiceEndpoints>,\n\t\tprivate readonly channelP: Promise<IChannel>,\n\t\tprivate _channel?: IChannel,\n\t) {\n\t\tassert(!this.id.includes(\"/\"), 0x30f /* Channel context ID cannot contain slashes */);\n\t}\n\n\tpublic async getChannel(): Promise<IChannel> {\n\t\tif (this._channel === undefined) {\n\t\t\treturn this.channelP.then((c) => (this._channel = c));\n\t\t}\n\t\treturn this.channelP;\n\t}\n\n\tpublic get isLoaded(): boolean {\n\t\treturn this._channel !== undefined;\n\t}\n\n\tpublic setConnectionState(connected: boolean, clientId?: string) {\n\t\t// Connection events are ignored if the data store is not yet globallyVisible or loaded\n\t\tif (this.globallyVisible && this.isLoaded) {\n\t\t\tthis.services.value.deltaConnection.setConnectionState(connected);\n\t\t}\n\t}\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2d3 /* \"Local channel must be globally visible when processing op\" */,\n\t\t);\n\n\t\t// A local channel may not be loaded in case where we rehydrate the container from a snapshot because of\n\t\t// delay loading. So after the container is attached and some other client joins which start generating\n\t\t// ops for this channel. So not loaded local channel can still receive ops and we store them to process later.\n\t\tif (this.isLoaded) {\n\t\t\tthis.services.value.deltaConnection.process(message, local, localOpMetadata);\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tlocal === false,\n\t\t\t\t0x189 /* \"Should always be remote because a local dds shouldn't generate ops before loading\" */,\n\t\t\t);\n\t\t\tthis.pending.push(message);\n\t\t}\n\t}\n\n\tpublic reSubmit(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x18a /* \"Channel should be loaded to resubmit ops\" */);\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2d4 /* \"Local channel must be globally visible when resubmitting op\" */,\n\t\t);\n\t\tthis.services.value.deltaConnection.reSubmit(content, localOpMetadata);\n\t}\n\tpublic rollback(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x2ee /* \"Channel should be loaded to rollback ops\" */);\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2ef /* \"Local channel must be globally visible when rolling back op\" */,\n\t\t);\n\t\tthis.services.value.deltaConnection.rollback(content, localOpMetadata);\n\t}\n\n\tpublic applyStashedOp() {\n\t\tthrow new Error(\"no stashed ops on local channel\");\n\t}\n\n\t/**\n\t * Returns a summary at the current sequence number.\n\t * @param fullTree - true to bypass optimizations and force a full summary tree\n\t * @param trackState - This tells whether we should track state from this summary.\n\t * @param telemetryContext - summary data passed through the layers for telemetry purposes\n\t */\n\tpublic async summarize(\n\t\tfullTree: boolean = false,\n\t\ttrackState: boolean = false,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummarizeResult> {\n\t\tconst channel = await this.getChannel();\n\t\treturn summarizeChannelAsync(channel, fullTree, trackState, telemetryContext);\n\t}\n\n\tpublic getAttachSummary(telemetryContext?: ITelemetryContext): ISummarizeResult {\n\t\tassert(\n\t\t\tthis._channel !== undefined,\n\t\t\t0x18d /* \"Channel should be loaded to take snapshot\" */,\n\t\t);\n\t\treturn summarizeChannel(\n\t\t\tthis._channel,\n\t\t\ttrue /* fullTree */,\n\t\t\tfalse /* trackState */,\n\t\t\ttelemetryContext,\n\t\t);\n\t}\n\n\tpublic makeVisible(): void {\n\t\tif (this.globallyVisible) {\n\t\t\tthrow new Error(\"Channel is already globally visible\");\n\t\t}\n\n\t\tif (this.isLoaded) {\n\t\t\tassert(!!this._channel, 0x192 /* \"Channel should be there if loaded!!\" */);\n\t\t\tthis._channel.connect(this.services.value);\n\t\t}\n\t\tthis.globallyVisible = true;\n\t}\n\n\t/**\n\t * Returns the data used for garbage collection. This includes a list of GC nodes that represent this context.\n\t * Each node has a set of outbound routes to other GC nodes in the document. This should be called only after\n\t * the context has loaded.\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tpublic async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n\t\tconst channel = await this.getChannel();\n\t\treturn channel.getGCData(fullGC);\n\t}\n\n\tpublic updateUsedRoutes(usedRoutes: string[]) {\n\t\t/**\n\t\t * Currently, DDSes are always considered referenced and are not garbage collected.\n\t\t * Once we have GC at DDS level, this channel context's used routes will be updated as per the passed\n\t\t * value. See - https://github.com/microsoft/FluidFramework/issues/4611\n\t\t */\n\t}\n}\n\nexport class RehydratedLocalChannelContext extends LocalChannelContextBase {\n\tprivate readonly dirtyFn: () => void;\n\tconstructor(\n\t\tid: string,\n\t\tregistry: ISharedObjectRegistry,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tdataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tsubmitFn: (content: any, localOpMetadata: unknown) => void,\n\t\tdirtyFn: (address: string) => void,\n\t\taddedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n\t\tprivate readonly snapshotTree: ISnapshotTree,\n\t) {\n\t\tsuper(\n\t\t\tid,\n\t\t\truntime,\n\t\t\tnew Lazy(() => {\n\t\t\t\tconst blobMap: Map<string, ArrayBufferLike> = new Map<string, ArrayBufferLike>();\n\t\t\t\tconst clonedSnapshotTree = cloneDeep(this.snapshotTree);\n\t\t\t\t// 0.47 back-compat Need to sanitize if snapshotTree.blobs still contains blob contents too.\n\t\t\t\t// This is for older snapshot which is generated by loader <=0.47 version which still contains\n\t\t\t\t// the contents within blobs. After a couple of revisions we can remove it.\n\t\t\t\tif (this.isSnapshotInOldFormatAndCollectBlobs(clonedSnapshotTree, blobMap)) {\n\t\t\t\t\tthis.sanitizeSnapshot(clonedSnapshotTree);\n\t\t\t\t}\n\t\t\t\treturn createChannelServiceEndpoints(\n\t\t\t\t\tdataStoreContext.connected,\n\t\t\t\t\tsubmitFn,\n\t\t\t\t\tthis.dirtyFn,\n\t\t\t\t\taddedGCOutboundReferenceFn,\n\t\t\t\t\tstorageService,\n\t\t\t\t\tlogger,\n\t\t\t\t\tclonedSnapshotTree,\n\t\t\t\t\tblobMap,\n\t\t\t\t);\n\t\t\t}),\n\t\t\tnew LazyPromise<IChannel>(async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst { attributes, factory } = await loadChannelFactoryAndAttributes(\n\t\t\t\t\t\tdataStoreContext,\n\t\t\t\t\t\tthis.services.value,\n\t\t\t\t\t\tthis.id,\n\t\t\t\t\t\tregistry,\n\t\t\t\t\t);\n\t\t\t\t\tconst channel = await loadChannel(\n\t\t\t\t\t\truntime,\n\t\t\t\t\t\tattributes,\n\t\t\t\t\t\tfactory,\n\t\t\t\t\t\tthis.services.value,\n\t\t\t\t\t\tlogger,\n\t\t\t\t\t\tthis.id,\n\t\t\t\t\t);\n\t\t\t\t\t// Send all pending messages to the channel\n\t\t\t\t\tfor (const message of this.pending) {\n\t\t\t\t\t\tthis.services.value.deltaConnection.process(\n\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\tundefined /* localOpMetadata */,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn channel;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthrow DataProcessingError.wrapIfUnrecognized(\n\t\t\t\t\t\terr,\n\t\t\t\t\t\t\"rehydratedLocalChannelContextFailedToLoadChannel\",\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\n\t\tthis.dirtyFn = () => {\n\t\t\tdirtyFn(id);\n\t\t};\n\t}\n\n\tprivate isSnapshotInOldFormatAndCollectBlobs(\n\t\tsnapshotTree: ISnapshotTree,\n\t\tblobMap: Map<string, ArrayBufferLike>,\n\t): boolean {\n\t\tlet sanitize = false;\n\t\tconst blobsContents: { [path: string]: ArrayBufferLike } = (snapshotTree as any)\n\t\t\t.blobsContents;\n\t\tObject.entries(blobsContents).forEach(([key, value]) => {\n\t\t\tblobMap.set(key, value);\n\t\t\tif (snapshotTree.blobs[key] !== undefined) {\n\t\t\t\tsanitize = true;\n\t\t\t}\n\t\t});\n\t\tfor (const value of Object.values(snapshotTree.trees)) {\n\t\t\tsanitize = sanitize || this.isSnapshotInOldFormatAndCollectBlobs(value, blobMap);\n\t\t}\n\t\treturn sanitize;\n\t}\n\n\tprivate sanitizeSnapshot(snapshotTree: ISnapshotTree) {\n\t\tconst blobMapInitial = new Map(Object.entries(snapshotTree.blobs));\n\t\tfor (const [blobName, blobId] of blobMapInitial.entries()) {\n\t\t\tconst blobValue = blobMapInitial.get(blobId);\n\t\t\tif (blobValue === undefined) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\t\tdelete snapshotTree.blobs[blobName];\n\t\t\t}\n\t\t}\n\t\tfor (const value of Object.values(snapshotTree.trees)) {\n\t\t\tthis.sanitizeSnapshot(value);\n\t\t}\n\t}\n}\n\nexport class LocalChannelContext extends LocalChannelContextBase {\n\tprivate readonly dirtyFn: () => void;\n\tpublic readonly channel: IChannel;\n\tconstructor(\n\t\tid: string,\n\t\tregistry: ISharedObjectRegistry,\n\t\ttype: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tdataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tsubmitFn: (content: any, localOpMetadata: unknown) => void,\n\t\tdirtyFn: (address: string) => void,\n\t\taddedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n\t) {\n\t\tassert(type !== undefined, 0x209 /* \"Factory Type should be defined\" */);\n\t\tconst factory = registry.get(type);\n\t\tif (factory === undefined) {\n\t\t\tthrow new Error(`Channel Factory ${type} not registered`);\n\t\t}\n\t\tconst channel = factory.create(runtime, id);\n\t\tsuper(\n\t\t\tid,\n\t\t\truntime,\n\t\t\tnew Lazy(() => {\n\t\t\t\treturn createChannelServiceEndpoints(\n\t\t\t\t\tdataStoreContext.connected,\n\t\t\t\t\tsubmitFn,\n\t\t\t\t\tthis.dirtyFn,\n\t\t\t\t\taddedGCOutboundReferenceFn,\n\t\t\t\t\tstorageService,\n\t\t\t\t\tlogger,\n\t\t\t\t);\n\t\t\t}),\n\t\t\tPromise.resolve(channel),\n\t\t\tchannel,\n\t\t);\n\t\tthis.channel = channel;\n\n\t\tthis.dirtyFn = () => {\n\t\t\tdirtyFn(id);\n\t\t};\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"localChannelContext.js","sourceRoot":"","sources":["../src/localChannelContext.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\n// eslint-disable-next-line import/no-internal-modules\nimport cloneDeep from \"lodash/cloneDeep\";\nimport { DataProcessingError, ITelemetryLoggerExt } from \"@fluidframework/telemetry-utils\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { IChannel, IFluidDataStoreRuntime } from \"@fluidframework/datastore-definitions\";\nimport {\n\tIFluidDataStoreContext,\n\tIGarbageCollectionData,\n\tISummarizeResult,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { assert, Lazy, LazyPromise } from \"@fluidframework/core-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport {\n\tChannelServiceEndpoints,\n\tcreateChannelServiceEndpoints,\n\tIChannelContext,\n\tloadChannel,\n\tloadChannelFactoryAndAttributes,\n\tsummarizeChannel,\n\tsummarizeChannelAsync,\n} from \"./channelContext\";\nimport { ISharedObjectRegistry } from \"./dataStoreRuntime\";\n\n/**\n * Channel context for a locally created channel\n */\nexport abstract class LocalChannelContextBase implements IChannelContext {\n\tprivate globallyVisible = false;\n\tprotected readonly pending: ISequencedDocumentMessage[] = [];\n\tconstructor(\n\t\tprotected readonly id: string,\n\t\tprotected readonly runtime: IFluidDataStoreRuntime,\n\t\tprotected readonly services: Lazy<ChannelServiceEndpoints>,\n\t\tprivate readonly channelP: Promise<IChannel>,\n\t\tprivate _channel?: IChannel,\n\t) {\n\t\tassert(!this.id.includes(\"/\"), 0x30f /* Channel context ID cannot contain slashes */);\n\t}\n\n\tpublic async getChannel(): Promise<IChannel> {\n\t\tif (this._channel === undefined) {\n\t\t\treturn this.channelP.then((c) => (this._channel = c));\n\t\t}\n\t\treturn this.channelP;\n\t}\n\n\tpublic get isLoaded(): boolean {\n\t\treturn this._channel !== undefined;\n\t}\n\n\tpublic setConnectionState(connected: boolean, clientId?: string) {\n\t\t// Connection events are ignored if the data store is not yet globallyVisible or loaded\n\t\tif (this.globallyVisible && this.isLoaded) {\n\t\t\tthis.services.value.deltaConnection.setConnectionState(connected);\n\t\t}\n\t}\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2d3 /* \"Local channel must be globally visible when processing op\" */,\n\t\t);\n\n\t\t// A local channel may not be loaded in case where we rehydrate the container from a snapshot because of\n\t\t// delay loading. So after the container is attached and some other client joins which start generating\n\t\t// ops for this channel. So not loaded local channel can still receive ops and we store them to process later.\n\t\tif (this.isLoaded) {\n\t\t\tthis.services.value.deltaConnection.process(message, local, localOpMetadata);\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tlocal === false,\n\t\t\t\t0x189 /* \"Should always be remote because a local dds shouldn't generate ops before loading\" */,\n\t\t\t);\n\t\t\tthis.pending.push(message);\n\t\t}\n\t}\n\n\tpublic reSubmit(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x18a /* \"Channel should be loaded to resubmit ops\" */);\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2d4 /* \"Local channel must be globally visible when resubmitting op\" */,\n\t\t);\n\t\tthis.services.value.deltaConnection.reSubmit(content, localOpMetadata);\n\t}\n\tpublic rollback(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x2ee /* \"Channel should be loaded to rollback ops\" */);\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2ef /* \"Local channel must be globally visible when rolling back op\" */,\n\t\t);\n\t\tthis.services.value.deltaConnection.rollback(content, localOpMetadata);\n\t}\n\n\tpublic applyStashedOp() {\n\t\tthrow new Error(\"no stashed ops on local channel\");\n\t}\n\n\t/**\n\t * Returns a summary at the current sequence number.\n\t * @param fullTree - true to bypass optimizations and force a full summary tree\n\t * @param trackState - This tells whether we should track state from this summary.\n\t * @param telemetryContext - summary data passed through the layers for telemetry purposes\n\t */\n\tpublic async summarize(\n\t\tfullTree: boolean = false,\n\t\ttrackState: boolean = false,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummarizeResult> {\n\t\tconst channel = await this.getChannel();\n\t\treturn summarizeChannelAsync(channel, fullTree, trackState, telemetryContext);\n\t}\n\n\tpublic getAttachSummary(telemetryContext?: ITelemetryContext): ISummarizeResult {\n\t\tassert(\n\t\t\tthis._channel !== undefined,\n\t\t\t0x18d /* \"Channel should be loaded to take snapshot\" */,\n\t\t);\n\t\treturn summarizeChannel(\n\t\t\tthis._channel,\n\t\t\ttrue /* fullTree */,\n\t\t\tfalse /* trackState */,\n\t\t\ttelemetryContext,\n\t\t);\n\t}\n\n\tpublic makeVisible(): void {\n\t\tif (this.globallyVisible) {\n\t\t\tthrow new Error(\"Channel is already globally visible\");\n\t\t}\n\n\t\tif (this.isLoaded) {\n\t\t\tassert(!!this._channel, 0x192 /* \"Channel should be there if loaded!!\" */);\n\t\t\tthis._channel.connect(this.services.value);\n\t\t}\n\t\tthis.globallyVisible = true;\n\t}\n\n\t/**\n\t * Returns the data used for garbage collection. This includes a list of GC nodes that represent this context.\n\t * Each node has a set of outbound routes to other GC nodes in the document. This should be called only after\n\t * the context has loaded.\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tpublic async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n\t\tconst channel = await this.getChannel();\n\t\treturn channel.getGCData(fullGC);\n\t}\n\n\tpublic updateUsedRoutes(usedRoutes: string[]) {\n\t\t/**\n\t\t * Currently, DDSes are always considered referenced and are not garbage collected.\n\t\t * Once we have GC at DDS level, this channel context's used routes will be updated as per the passed\n\t\t * value. See - https://github.com/microsoft/FluidFramework/issues/4611\n\t\t */\n\t}\n}\n\nexport class RehydratedLocalChannelContext extends LocalChannelContextBase {\n\tprivate readonly dirtyFn: () => void;\n\tconstructor(\n\t\tid: string,\n\t\tregistry: ISharedObjectRegistry,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tdataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tsubmitFn: (content: any, localOpMetadata: unknown) => void,\n\t\tdirtyFn: (address: string) => void,\n\t\taddedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n\t\tprivate readonly snapshotTree: ISnapshotTree,\n\t) {\n\t\tsuper(\n\t\t\tid,\n\t\t\truntime,\n\t\t\tnew Lazy(() => {\n\t\t\t\tconst blobMap: Map<string, ArrayBufferLike> = new Map<string, ArrayBufferLike>();\n\t\t\t\tconst clonedSnapshotTree = cloneDeep(this.snapshotTree);\n\t\t\t\t// 0.47 back-compat Need to sanitize if snapshotTree.blobs still contains blob contents too.\n\t\t\t\t// This is for older snapshot which is generated by loader <=0.47 version which still contains\n\t\t\t\t// the contents within blobs. After a couple of revisions we can remove it.\n\t\t\t\tif (this.isSnapshotInOldFormatAndCollectBlobs(clonedSnapshotTree, blobMap)) {\n\t\t\t\t\tthis.sanitizeSnapshot(clonedSnapshotTree);\n\t\t\t\t}\n\t\t\t\treturn createChannelServiceEndpoints(\n\t\t\t\t\tdataStoreContext.connected,\n\t\t\t\t\tsubmitFn,\n\t\t\t\t\tthis.dirtyFn,\n\t\t\t\t\taddedGCOutboundReferenceFn,\n\t\t\t\t\tstorageService,\n\t\t\t\t\tlogger,\n\t\t\t\t\tclonedSnapshotTree,\n\t\t\t\t\tblobMap,\n\t\t\t\t);\n\t\t\t}),\n\t\t\tnew LazyPromise<IChannel>(async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst { attributes, factory } = await loadChannelFactoryAndAttributes(\n\t\t\t\t\t\tdataStoreContext,\n\t\t\t\t\t\tthis.services.value,\n\t\t\t\t\t\tthis.id,\n\t\t\t\t\t\tregistry,\n\t\t\t\t\t);\n\t\t\t\t\tconst channel = await loadChannel(\n\t\t\t\t\t\truntime,\n\t\t\t\t\t\tattributes,\n\t\t\t\t\t\tfactory,\n\t\t\t\t\t\tthis.services.value,\n\t\t\t\t\t\tlogger,\n\t\t\t\t\t\tthis.id,\n\t\t\t\t\t);\n\t\t\t\t\t// Send all pending messages to the channel\n\t\t\t\t\tfor (const message of this.pending) {\n\t\t\t\t\t\tthis.services.value.deltaConnection.process(\n\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\tundefined /* localOpMetadata */,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn channel;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthrow DataProcessingError.wrapIfUnrecognized(\n\t\t\t\t\t\terr,\n\t\t\t\t\t\t\"rehydratedLocalChannelContextFailedToLoadChannel\",\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\n\t\tthis.dirtyFn = () => {\n\t\t\tdirtyFn(id);\n\t\t};\n\t}\n\n\tprivate isSnapshotInOldFormatAndCollectBlobs(\n\t\tsnapshotTree: ISnapshotTree,\n\t\tblobMap: Map<string, ArrayBufferLike>,\n\t): boolean {\n\t\tlet sanitize = false;\n\t\tconst blobsContents: { [path: string]: ArrayBufferLike } = (snapshotTree as any)\n\t\t\t.blobsContents;\n\t\tObject.entries(blobsContents).forEach(([key, value]) => {\n\t\t\tblobMap.set(key, value);\n\t\t\tif (snapshotTree.blobs[key] !== undefined) {\n\t\t\t\tsanitize = true;\n\t\t\t}\n\t\t});\n\t\tfor (const value of Object.values(snapshotTree.trees)) {\n\t\t\tsanitize = sanitize || this.isSnapshotInOldFormatAndCollectBlobs(value, blobMap);\n\t\t}\n\t\treturn sanitize;\n\t}\n\n\tprivate sanitizeSnapshot(snapshotTree: ISnapshotTree) {\n\t\tconst blobMapInitial = new Map(Object.entries(snapshotTree.blobs));\n\t\tfor (const [blobName, blobId] of blobMapInitial.entries()) {\n\t\t\tconst blobValue = blobMapInitial.get(blobId);\n\t\t\tif (blobValue === undefined) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\t\tdelete snapshotTree.blobs[blobName];\n\t\t\t}\n\t\t}\n\t\tfor (const value of Object.values(snapshotTree.trees)) {\n\t\t\tthis.sanitizeSnapshot(value);\n\t\t}\n\t}\n}\n\nexport class LocalChannelContext extends LocalChannelContextBase {\n\tprivate readonly dirtyFn: () => void;\n\tconstructor(\n\t\tpublic readonly channel: IChannel,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tdataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tsubmitFn: (content: any, localOpMetadata: unknown) => void,\n\t\tdirtyFn: (address: string) => void,\n\t\taddedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n\t) {\n\t\tsuper(\n\t\t\tchannel.id,\n\t\t\truntime,\n\t\t\tnew Lazy(() => {\n\t\t\t\treturn createChannelServiceEndpoints(\n\t\t\t\t\tdataStoreContext.connected,\n\t\t\t\t\tsubmitFn,\n\t\t\t\t\tthis.dirtyFn,\n\t\t\t\t\taddedGCOutboundReferenceFn,\n\t\t\t\t\tstorageService,\n\t\t\t\t\tlogger,\n\t\t\t\t);\n\t\t\t}),\n\t\t\tPromise.resolve(channel),\n\t\t\tchannel,\n\t\t);\n\t\tthis.channel = channel;\n\n\t\tthis.dirtyFn = () => {\n\t\t\tdirtyFn(channel.id);\n\t\t};\n\t}\n}\n"]}
|