Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@fluidframework/container-loader

Package Overview
Dependencies
Maintainers
2
Versions
583
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fluidframework/container-loader - npm Package Compare versions

Comparing version 2.0.0-rc.4.0.6 to 2.0.0-rc.5.0.0

api-extractor/api-extractor-lint-bundle.json

2

api-extractor.json
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"extends": "../../../common/build/build-common/api-extractor-base.esm.primary.json"
"extends": "../../../common/build/build-common/api-extractor-base.esm.current.json"
}
# @fluidframework/container-loader
## 2.0.0-rc.5.0.0
### Minor Changes
- Update to TypeScript 5.4 ([#21214](https://github.com/microsoft/FluidFramework/pull/21214)) [0e6256c722](https://github.com/microsoft/FluidFramework/commit/0e6256c722d8bf024f4325bf02547daeeb18bfa6)
Update package implementations to use TypeScript 5.4.5.
- container-loader: IDetachedBlobStorage is deprecated and replaced with a default in memory store for detached blobs ([#21144](https://github.com/microsoft/FluidFramework/pull/21144)) [2eebaa1775](https://github.com/microsoft/FluidFramework/commit/2eebaa1775dba0a677a005ba36f6f946c6324c21)
IDetachedBlobStorage will be removed in a future release without a replacement.
When applications load a container without specifying ILoaderServices.detachedBlobStorage, an implementation which stores the blobs in memory will be injected by Fluid.
IDetachedBlobStorage as well as application-defined implementations of it are deprecated and support will be removed for them in a future update.
Applications are recommended to stop providing this property on ILoaderServices.
- Update to ES 2022 ([#21292](https://github.com/microsoft/FluidFramework/pull/21292)) [68921502f7](https://github.com/microsoft/FluidFramework/commit/68921502f79b1833c4cd6d0fe339bfb126a712c7)
Update tsconfig to target ES 2022.
## 2.0.0-rc.4.0.0

@@ -4,0 +25,0 @@

@@ -6,5 +6,5 @@ /*!

import { AttachState } from "@fluidframework/container-definitions";
import { ISummaryTree } from "@fluidframework/driver-definitions";
import { IDocumentStorageService } from "@fluidframework/driver-definitions/internal";
import { CombinedAppAndProtocolSummary } from "@fluidframework/driver-utils/internal";
import { ISummaryTree } from "@fluidframework/protocol-definitions";
import { IDetachedBlobStorage } from "./loader.js";

@@ -11,0 +11,0 @@ import type { SnapshotWithBlobs } from "./serializedStateManager.js";

@@ -6,4 +6,5 @@ /*!

import { TypedEventEmitter } from "@fluid-internal/client-utils";
import { IAudienceEvents, IAudienceOwner, ISelf } from "@fluidframework/container-definitions/internal";
import { IClient } from "@fluidframework/protocol-definitions";
import { IAudienceEvents, ISelf } from "@fluidframework/container-definitions";
import { IAudienceOwner } from "@fluidframework/container-definitions/internal";
import { IClient } from "@fluidframework/driver-definitions";
/**

@@ -10,0 +11,0 @@ * Audience represents all clients connected to the op stream.

@@ -5,6 +5,7 @@ /*!

*/
import { ICriticalContainerError, IDeltaQueue, ReadOnlyInfo } from "@fluidframework/container-definitions/internal";
import { ICriticalContainerError } from "@fluidframework/container-definitions";
import { IDeltaQueue, ReadOnlyInfo } from "@fluidframework/container-definitions/internal";
import { ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
import { IDocumentService } from "@fluidframework/driver-definitions/internal";
import { ConnectionMode, IClient, IClientConfiguration, IClientDetails, IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
import { ConnectionMode, IClient, IClientDetails } from "@fluidframework/driver-definitions";
import { IDocumentService, IClientConfiguration, IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";

@@ -11,0 +12,0 @@ import { IConnectionDetailsInternal, IConnectionManager, IConnectionManagerFactoryArgs, IConnectionStateChangeReason, ReconnectMode } from "./contracts.js";

@@ -13,3 +13,2 @@ "use strict";

const internal_3 = require("@fluidframework/driver-utils/internal");
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
const internal_4 = require("@fluidframework/telemetry-utils/internal");

@@ -38,3 +37,3 @@ const contracts_js_1 = require("./contracts.js");

permission: [],
user: { id: "storage-only client" },
user: { id: "storage-only client" }, // we need some "fake" ID here.
scopes: [],

@@ -55,3 +54,3 @@ };

this.claims = {
scopes: [protocol_definitions_1.ScopeType.DocRead],
scopes: [internal_2.ScopeType.DocRead],
};

@@ -497,3 +496,3 @@ this.mode = "read";

attempts: connectRepeatCount,
delay: delayMs,
delay: delayMs, // milliseconds
eventName: "DeltaConnectionFailureToConnect",

@@ -643,3 +642,3 @@ duration: (0, internal_4.formatTick)(client_utils_1.performance.now() - connectStartTime),

// But if we ask read, server can still give us write.
const readonly = !connection.claims.scopes.includes(protocol_definitions_1.ScopeType.DocWrite);
const readonly = !connection.claims.scopes.includes(internal_2.ScopeType.DocWrite);
if (connection.mode !== requestedMode) {

@@ -710,3 +709,3 @@ this.logger.sendTelemetryEvent({

const clearSignal = {
clientId: null,
clientId: null, // system message
content: JSON.stringify({

@@ -719,3 +718,3 @@ type: protocol_js_1.SignalType.Clear,

const clientJoinSignals = (connection.initialClients ?? []).map((priorClient) => ({
clientId: null,
clientId: null, // system signal
content: JSON.stringify({

@@ -876,3 +875,3 @@ type: protocol_js_1.SignalType.ClientJoin,

}
if (message.type === protocol_definitions_1.MessageType.ClientLeave) {
if (message.type === internal_2.MessageType.ClientLeave) {
const systemLeaveMessage = message;

@@ -879,0 +878,0 @@ const clientId = JSON.parse(systemLeaveMessage.data);

@@ -7,4 +7,4 @@ /*!

import { ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
import { IClient, ISequencedClient } from "@fluidframework/driver-definitions";
import { IAnyDriverError } from "@fluidframework/driver-definitions/internal";
import { IClient, ISequencedClient } from "@fluidframework/protocol-definitions";
import { type TelemetryEventCategory, ITelemetryLoggerExt, MonitoringContext } from "@fluidframework/telemetry-utils/internal";

@@ -11,0 +11,0 @@ import { ConnectionState } from "./connectionState.js";

@@ -412,4 +412,2 @@ "use strict";

else if (value === connectionState_js_1.ConnectionState.Disconnected) {
// Clear pending state immediately to prepare for reconnect
this._pendingClientId = undefined;
if (this.joinTimer.hasTimer) {

@@ -441,4 +439,10 @@ this.stopjoinTimer();

}
// Report transition before we propagate event across layers
// Report transition
this.handler.connectionStateChanged(this._connectionState, oldState, reason);
// Clear pending state immediately to prepare for reconnect
// Do it after calling connectionStateChanged() above, such that our telemetry contains pendingClientId on disconnect events
// and we can pair attempts to connect with disconnects (that's the only ID we have if connection did not move far enough before being disconnected)
if (value === connectionState_js_1.ConnectionState.Disconnected) {
this._pendingClientId = undefined;
}
}

@@ -476,3 +480,3 @@ get membership() {

}
(0, internal_1.assert)(!this.waitingForLeaveOp, "leave timer can't be set as we have not had access to quorum");
(0, internal_1.assert)(!this.waitingForLeaveOp, 0x99d /* leave timer can't be set as we have not had access to quorum */);
// This check is required for scenario of loading container from pending state, and ensuring there is no way

@@ -479,0 +483,0 @@ // old clientId is still in the quorum (very unlikely, but you never know)

@@ -8,4 +8,4 @@ /*!

import { FluidObject, IRequest, ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
import { IDocumentServiceFactory, IResolvedUrl, IUrlResolver } from "@fluidframework/driver-definitions/internal";
import { IClientDetails, IDocumentMessage, IQuorumClients, ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
import { IClientDetails, IQuorumClients } from "@fluidframework/driver-definitions";
import { IDocumentServiceFactory, IResolvedUrl, IUrlResolver, IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
import { ITelemetryLoggerExt, EventEmitterWithErrorHandling } from "@fluidframework/telemetry-utils/internal";

@@ -222,2 +222,3 @@ import { ConnectionState } from "./connectionState.js";

private get isInteractiveClient();
private supportGetSnapshotApi;
/**

@@ -224,0 +225,0 @@ * Get the code details that are currently specified for the container.

@@ -9,4 +9,4 @@ /*!

import { type ISignalEnvelope } from "@fluidframework/core-interfaces/internal";
import { IDocumentStorageService, ISnapshot } from "@fluidframework/driver-definitions/internal";
import { IClientDetails, IDocumentMessage, IQuorumClients, ISequencedDocumentMessage, ISnapshotTree, ISummaryContent, IVersion, MessageType } from "@fluidframework/protocol-definitions";
import { IClientDetails, IQuorumClients } from "@fluidframework/driver-definitions";
import { IDocumentStorageService, ISnapshot, IDocumentMessage, ISnapshotTree, ISummaryContent, IVersion, MessageType, ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";

@@ -13,0 +13,0 @@ /**

@@ -7,4 +7,4 @@ /*!

import { IDisposable } from "@fluidframework/core-interfaces";
import { FetchSource, IDocumentService, IDocumentStorageService, IDocumentStorageServicePolicies, ISnapshot, ISnapshotFetchOptions, ISummaryContext } from "@fluidframework/driver-definitions/internal";
import { ICreateBlobResponse, ISnapshotTree, ISummaryHandle, ISummaryTree, IVersion } from "@fluidframework/protocol-definitions";
import { ISummaryHandle, ISummaryTree } from "@fluidframework/driver-definitions";
import { FetchSource, IDocumentService, IDocumentStorageService, IDocumentStorageServicePolicies, ISnapshot, ISnapshotFetchOptions, ISummaryContext, ICreateBlobResponse, ISnapshotTree, IVersion } from "@fluidframework/driver-definitions/internal";
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";

@@ -32,2 +32,3 @@ import { IDetachedBlobStorage } from "./loader.js";

private readonly addProtocolSummaryIfMissing;
private readonly enableSummarizeProtocolTree;
private _storageService;

@@ -52,3 +53,3 @@ private _summarizeProtocolTree;

* upload, and fix it up with a protocol tree if needed
* @param forceEnableSummarizeProtocolTree - Enforce uploading a protocol summary regardless of the service's policy
* @param enableSummarizeProtocolTree - Enable uploading a protocol summary. Note: preference is given to service policy's "summarizeProtocolTree" before this value.
*/

@@ -61,3 +62,3 @@ constructor(detachedBlobStorage: IDetachedBlobStorage | undefined, logger: ITelemetryLoggerExt,

[id: string]: ArrayBufferLike | string;
}, loadingGroupIdSnapshotsFromPendingState: Record<string, ISnapshotInfo> | undefined, addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree, forceEnableSummarizeProtocolTree: boolean | undefined);
}, loadingGroupIdSnapshotsFromPendingState: Record<string, ISnapshotInfo> | undefined, addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree, enableSummarizeProtocolTree: boolean | undefined);
disposed: boolean;

@@ -64,0 +65,0 @@ dispose(error?: Error): void;

@@ -39,3 +39,3 @@ "use strict";

* upload, and fix it up with a protocol tree if needed
* @param forceEnableSummarizeProtocolTree - Enforce uploading a protocol summary regardless of the service's policy
* @param enableSummarizeProtocolTree - Enable uploading a protocol summary. Note: preference is given to service policy's "summarizeProtocolTree" before this value.
*/

@@ -48,3 +48,3 @@ constructor(

*/
blobContents = {}, loadingGroupIdSnapshotsFromPendingState, addProtocolSummaryIfMissing, forceEnableSummarizeProtocolTree) {
blobContents = {}, loadingGroupIdSnapshotsFromPendingState, addProtocolSummaryIfMissing, enableSummarizeProtocolTree) {
this.logger = logger;

@@ -54,6 +54,6 @@ this.blobContents = blobContents;

this.addProtocolSummaryIfMissing = addProtocolSummaryIfMissing;
this.enableSummarizeProtocolTree = enableSummarizeProtocolTree;
this._loadedGroupIdSnapshots = {};
this.disposed = false;
this._storageService = new BlobOnlyStorage(detachedBlobStorage, logger);
this._summarizeProtocolTree = forceEnableSummarizeProtocolTree;
}

@@ -70,8 +70,24 @@ dispose(error) {

const retriableStorage = (this._storageService = new retriableDocumentStorageService_js_1.RetriableDocumentStorageService(storageServiceP, this.logger));
this._summarizeProtocolTree =
this._summarizeProtocolTree ?? service.policies?.summarizeProtocolTree;
if (this.summarizeProtocolTree) {
// A storage service wrapper which intercept calls to uploadSummaryWithContext and ensure they include
// the protocol summary, provided single-commit summary is enabled.
this._storageService = new protocolTreeDocumentStorageService_js_1.ProtocolTreeStorageService(retriableStorage, (...props) => {
this.logger.sendTelemetryEvent({ eventName: "summarizeProtocolTreeEnabled" });
this._storageService = new protocolTreeDocumentStorageService_js_1.ProtocolTreeStorageService(retriableStorage, this.addProtocolSummaryIfMissing);
}
return this.addProtocolSummaryIfMissing(...props);
},
// A callback to ensure we fetch the most updated value of service.policies.summarizeProtocolTree, which could be set
// based on the response received from the service after connection is established.
() => {
// Determine whether or not container should upload the protocol summary along with the summary.
// This is determined based on what value is set for serve policy's summariProtocolTree value or the enableSummarizeProtocolTree
// retrievd from the loader options or monitoring context config.
const shouldSummarizeProtocolTree = service.policies?.summarizeProtocolTree ?? this.enableSummarizeProtocolTree ?? false;
if (this._summarizeProtocolTree !== shouldSummarizeProtocolTree) {
this.logger.sendTelemetryEvent({
eventName: "isSummarizeProtocolTreeEnabled",
details: { value: shouldSummarizeProtocolTree },
});
}
this._summarizeProtocolTree = shouldSummarizeProtocolTree;
return this._summarizeProtocolTree;
});
}

@@ -78,0 +94,0 @@ loadSnapshotFromSnapshotBlobs(snapshotBlobs) {

@@ -8,4 +8,4 @@ /*!

import { IErrorBase, ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
import { IContainerPackageInfo } from "@fluidframework/driver-definitions/internal";
import { ConnectionMode, IClientConfiguration, IClientDetails, IDocumentMessage, ISequencedDocumentMessage, ISignalClient, ISignalMessage } from "@fluidframework/protocol-definitions";
import { ConnectionMode, IClientDetails } from "@fluidframework/driver-definitions";
import { IContainerPackageInfo, IClientConfiguration, IDocumentMessage, ISignalClient, ISequencedDocumentMessage, ISignalMessage } from "@fluidframework/driver-definitions/internal";
export declare enum ReconnectMode {

@@ -12,0 +12,0 @@ Never = "Never",

@@ -5,7 +5,8 @@ /*!

*/
import { ICriticalContainerError, IDeltaManager, IDeltaManagerEvents, IDeltaQueue } from "@fluidframework/container-definitions/internal";
import { ICriticalContainerError } from "@fluidframework/container-definitions";
import { IDeltaManager, IDeltaManagerEvents, IDeltaQueue } from "@fluidframework/container-definitions/internal";
import { IEventProvider, ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
import { IThrottlingWarning } from "@fluidframework/core-interfaces/internal";
import { IDocumentService } from "@fluidframework/driver-definitions/internal";
import { ConnectionMode, IDocumentMessage, ISequencedDocumentMessage, ISignalMessage, MessageType } from "@fluidframework/protocol-definitions";
import { ConnectionMode } from "@fluidframework/driver-definitions";
import { IDocumentService, IDocumentMessage, MessageType, ISequencedDocumentMessage, ISignalMessage } from "@fluidframework/driver-definitions/internal";
import { type ITelemetryErrorEventExt, ITelemetryLoggerExt, EventEmitterWithErrorHandling } from "@fluidframework/telemetry-utils/internal";

@@ -100,6 +101,6 @@ import { IConnectionDetailsInternal, IConnectionManager, IConnectionManagerFactoryArgs, IConnectionStateChangeReason } from "./contracts.js";

get version(): string;
get serviceConfiguration(): import("@fluidframework/protocol-definitions").IClientConfiguration | undefined;
get serviceConfiguration(): import("@fluidframework/driver-definitions/internal").IClientConfiguration | undefined;
get outbound(): IDeltaQueue<IDocumentMessage[]>;
get readOnlyInfo(): import("@fluidframework/container-definitions/internal").ReadOnlyInfo;
get clientDetails(): import("@fluidframework/protocol-definitions").IClientDetails;
get clientDetails(): import("@fluidframework/driver-definitions").IClientDetails;
submit(type: MessageType, contents?: string, batch?: boolean, metadata?: any, compression?: string, referenceSequenceNumber?: number): number;

@@ -106,0 +107,0 @@ submitSignal(content: string, targetClientId?: string): void;

@@ -11,3 +11,2 @@ "use strict";

const internal_3 = require("@fluidframework/driver-utils/internal");
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
const internal_4 = require("@fluidframework/telemetry-utils/internal");

@@ -25,7 +24,7 @@ const uuid_1 = require("uuid");

switch (message.type) {
case protocol_definitions_1.MessageType.Propose:
case protocol_definitions_1.MessageType.Reject:
case protocol_definitions_1.MessageType.NoOp:
case internal_2.MessageType.Propose:
case internal_2.MessageType.Reject:
case internal_2.MessageType.NoOp:
case internal_3.MessageType2.Accept:
case protocol_definitions_1.MessageType.Summarize:
case internal_2.MessageType.Summarize:
return true;

@@ -138,3 +137,3 @@ default:

this.messageBuffer.push(message);
if (message.type === protocol_definitions_1.MessageType.NoOp) {
if (message.type === internal_2.MessageType.NoOp) {
this.noOpCount++;

@@ -192,10 +191,10 @@ }

// A bunch of useful sequence numbers to understand if we are holding some ops from processing
lastQueuedSequenceNumber: this.lastQueuedSequenceNumber,
lastProcessedSequenceNumber: this.lastProcessedSequenceNumber,
lastObserved: this.lastObservedSeqNumber,
lastQueuedSequenceNumber: this.lastQueuedSequenceNumber, // last sequential op
lastProcessedSequenceNumber: this.lastProcessedSequenceNumber, // same as above, but after processing
lastObserved: this.lastObservedSeqNumber, // last sequence we ever saw; may have gaps with above.
// connection info
...this.connectionManager.connectionVerboseProps,
pendingOps: this.pending.length,
pendingFirst: pendingSorted[0]?.sequenceNumber,
haveHandler: this.handler !== undefined,
pendingOps: this.pending.length, // Do we have any pending ops?
pendingFirst: pendingSorted[0]?.sequenceNumber, // is the first pending op the one that we are missing?
haveHandler: this.handler !== undefined, // do we have handler installed?
inboundLength: this.inbound.length,

@@ -646,3 +645,3 @@ inboundPaused: this.inbound.paused,

from,
to: last + 1,
to: last + 1, // exclusive, being consistent with the other telemetry / APIs
length: messages.length,

@@ -717,3 +716,3 @@ fetchReason: this.fetchReason,

// 2. Non-immediate noops (contents: null) can be sent by service without clientId
if (!isString && isClientMessage(message) && message.type !== protocol_definitions_1.MessageType.NoOp) {
if (!isString && isClientMessage(message) && message.type !== internal_2.MessageType.NoOp) {
throw new internal_4.DataCorruptionError("Mismatch in clientId", {

@@ -727,3 +726,3 @@ ...(0, internal_4.extractSafePropertiesFromMessage)(message),

message.contents !== "" &&
message.type !== protocol_definitions_1.MessageType.ClientLeave) {
message.type !== internal_2.MessageType.ClientLeave) {
message.contents = JSON.parse(message.contents);

@@ -735,3 +734,3 @@ }

this.connectionManager.clientId === message.clientId) {
if (message.type === protocol_definitions_1.MessageType.NoOp) {
if (message.type === internal_2.MessageType.NoOp) {
this.noOpCount--;

@@ -738,0 +737,0 @@ }

@@ -12,2 +12,3 @@ /*!

export { tryParseCompatibleResolvedUrl, IParsedUrl } from "./utils.js";
export { IBaseProtocolHandler, IScribeProtocolState, IQuorumSnapshot, QuorumClientsSnapshot, QuorumProposalsSnapshot, } from "./protocol/index.js";
//# sourceMappingURL=index.d.ts.map

@@ -16,2 +16,3 @@ /*!

// @alpha APIs
IBaseProtocolHandler,
ICodeDetailsLoader,

@@ -25,4 +26,8 @@ IDetachedBlobStorage,

IProtocolHandler,
IQuorumSnapshot,
IScribeProtocolState,
Loader,
ProtocolHandlerBuilder,
QuorumClientsSnapshot,
QuorumProposalsSnapshot,
resolveWithLocationRedirectionHandling,

@@ -29,0 +34,0 @@ tryParseCompatibleResolvedUrl,

@@ -7,4 +7,4 @@ /*!

import { FluidObject, IConfigProviderBase, IRequest, ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
import { IClientDetails } from "@fluidframework/driver-definitions";
import { IDocumentServiceFactory, IDocumentStorageService, IUrlResolver } from "@fluidframework/driver-definitions/internal";
import { IClientDetails } from "@fluidframework/protocol-definitions";
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";

@@ -11,0 +11,0 @@ import { Container } from "./container.js";

@@ -16,3 +16,4 @@ "use strict";

MemoryDetachedBlobStorageIdentifier in detachedStorage &&
detachedStorage[MemoryDetachedBlobStorageIdentifier] === MemoryDetachedBlobStorageIdentifier);
detachedStorage[MemoryDetachedBlobStorageIdentifier] ===
MemoryDetachedBlobStorageIdentifier);
}

@@ -33,5 +34,5 @@ function serializeMemoryDetachedBlobStorage(

}
(0, internal_1.assert)(detachedStorage.size === 0, "Blob storage already initialized");
(0, internal_1.assert)(detachedStorage.size === 0, 0x99e /* Blob storage already initialized */);
const maybeAttachmentBlobs = JSON.parse(attachmentBlobs);
(0, internal_1.assert)(Array.isArray(maybeAttachmentBlobs), "Invalid attachmentBlobs");
(0, internal_1.assert)(Array.isArray(maybeAttachmentBlobs), 0x99f /* Invalid attachmentBlobs */);
detachedStorage.initialize(maybeAttachmentBlobs);

@@ -38,0 +39,0 @@ }

@@ -7,3 +7,3 @@ /*!

import { IEvent } from "@fluidframework/core-interfaces";
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
export interface INoopSenderEvents extends IEvent {

@@ -10,0 +10,0 @@ (event: "wantsNoop", listener: () => void): any;

@@ -8,3 +8,3 @@ /*!

export declare const pkgName = "@fluidframework/container-loader";
export declare const pkgVersion = "2.0.0-rc.4.0.6";
export declare const pkgVersion = "2.0.0-rc.5.0.0";
//# sourceMappingURL=packageVersion.d.ts.map

@@ -11,3 +11,3 @@ "use strict";

exports.pkgName = "@fluidframework/container-loader";
exports.pkgVersion = "2.0.0-rc.4.0.6";
exports.pkgVersion = "2.0.0-rc.5.0.0";
//# sourceMappingURL=packageVersion.js.map

@@ -6,7 +6,7 @@ /*!

import { IAudienceOwner } from "@fluidframework/container-definitions/internal";
import { IProtocolHandler as IBaseProtocolHandler, IQuorumSnapshot, ProtocolOpHandler } from "@fluidframework/protocol-base";
import { IDocumentAttributes, IProcessMessageResult, ISequencedDocumentMessage, ISignalMessage } from "@fluidframework/protocol-definitions";
import { IDocumentAttributes, IProcessMessageResult, ISequencedDocumentMessage, ISignalMessage } from "@fluidframework/driver-definitions/internal";
import { IBaseProtocolHandler, IQuorumSnapshot, ProtocolOpHandler } from "./protocol/index.js";
export declare enum SignalType {
ClientJoin = "join",
ClientLeave = "leave",
ClientJoin = "join",// same value as MessageType.ClientJoin,
ClientLeave = "leave",// same value as MessageType.ClientLeave,
Clear = "clear"

@@ -13,0 +13,0 @@ }

@@ -8,5 +8,5 @@ "use strict";

exports.protocolHandlerShouldProcessSignal = exports.ProtocolHandler = exports.SignalType = void 0;
const internal_1 = require("@fluidframework/driver-utils/internal");
const protocol_base_1 = require("@fluidframework/protocol-base");
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
const internal_1 = require("@fluidframework/driver-definitions/internal");
const internal_2 = require("@fluidframework/driver-utils/internal");
const index_js_1 = require("./protocol/index.js");
// ADO: #1986: Start using enum from protocol-base.

@@ -19,3 +19,3 @@ var SignalType;

})(SignalType || (exports.SignalType = SignalType = {}));
class ProtocolHandler extends protocol_base_1.ProtocolOpHandler {
class ProtocolHandler extends index_js_1.ProtocolOpHandler {
constructor(attributes, quorumSnapshot, sendProposal, audience, shouldClientHaveLeft) {

@@ -40,3 +40,3 @@ super(attributes.minimumSequenceNumber, attributes.sequenceNumber, quorumSnapshot.members, quorumSnapshot.proposals, quorumSnapshot.values, sendProposal);

const client = this.quorum.getMember(message.clientId);
if (client === undefined && message.type !== protocol_definitions_1.MessageType.ClientJoin) {
if (client === undefined && message.type !== internal_1.MessageType.ClientJoin) {
// pre-0.58 error message: messageClientIdMissingFromQuorum

@@ -48,3 +48,3 @@ throw new Error("Remote message's clientId is missing from the quorum");

// document we don't need to blow up aggressively.
if (this.shouldClientHaveLeft(message.clientId) && !(0, internal_1.canBeCoalescedByService)(message)) {
if (this.shouldClientHaveLeft(message.clientId) && !(0, internal_2.canBeCoalescedByService)(message)) {
// pre-0.58 error message: messageClientIdShouldHaveLeft

@@ -51,0 +51,0 @@ throw new Error("Remote message's clientId already should have left");

@@ -6,4 +6,4 @@ /*!

import { IDisposable } from "@fluidframework/core-interfaces";
import { ISummaryTree } from "@fluidframework/driver-definitions";
import { IDocumentStorageService, ISummaryContext } from "@fluidframework/driver-definitions/internal";
import { ISummaryTree } from "@fluidframework/protocol-definitions";
/**

@@ -16,14 +16,21 @@ * A storage service wrapper whose sole job is to intercept calls to uploadSummaryWithContext and ensure they include

private readonly addProtocolSummaryIfMissing;
constructor(internalStorageService: IDocumentStorageService & IDisposable, addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree);
private readonly shouldSummarizeProtocolTree;
/**
*
* @param internalStorageService - Document storage service responsible to make api calls to the storage.
* @param addProtocolSummaryIfMissing - Function to add protocol summary tree to the summary. Used in scenarios where single-commit summaries are used.
* @param shouldSummarizeProtocolTree - Callback function to learn about the service preference on whether single-commit summaries are enabled.
*/
constructor(internalStorageService: IDocumentStorageService & IDisposable, addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree, shouldSummarizeProtocolTree: () => boolean);
get policies(): import("@fluidframework/driver-definitions/internal").IDocumentStorageServicePolicies | undefined;
get disposed(): boolean;
getSnapshotTree: (version?: import("@fluidframework/protocol-definitions").IVersion | undefined, scenarioName?: string | undefined) => Promise<import("@fluidframework/protocol-definitions").ISnapshotTree | null>;
getSnapshot: ((snapshotFetchOptions?: import("@fluidframework/driver-definitions/internal").ISnapshotFetchOptions | undefined) => Promise<import("@fluidframework/driver-definitions/internal").ISnapshot>) | undefined;
getVersions: (versionId: string | null, count: number, scenarioName?: string | undefined, fetchSource?: import("@fluidframework/driver-definitions/internal").FetchSource | undefined) => Promise<import("@fluidframework/protocol-definitions").IVersion[]>;
createBlob: (file: ArrayBufferLike) => Promise<import("@fluidframework/protocol-definitions").ICreateBlobResponse>;
readBlob: (id: string) => Promise<ArrayBufferLike>;
downloadSummary: (handle: import("@fluidframework/protocol-definitions").ISummaryHandle) => Promise<ISummaryTree>;
dispose: (error?: Error | undefined) => void;
getSnapshotTree: IDocumentStorageService["getSnapshotTree"];
getSnapshot: IDocumentStorageService["getSnapshot"];
getVersions: IDocumentStorageService["getVersions"];
createBlob: IDocumentStorageService["createBlob"];
readBlob: IDocumentStorageService["readBlob"];
downloadSummary: IDocumentStorageService["downloadSummary"];
dispose: IDisposable["dispose"];
uploadSummaryWithContext(summary: ISummaryTree, context: ISummaryContext): Promise<string>;
}
//# sourceMappingURL=protocolTreeDocumentStorageService.d.ts.map

@@ -13,12 +13,19 @@ "use strict";

class ProtocolTreeStorageService {
constructor(internalStorageService, addProtocolSummaryIfMissing) {
/**
*
* @param internalStorageService - Document storage service responsible to make api calls to the storage.
* @param addProtocolSummaryIfMissing - Function to add protocol summary tree to the summary. Used in scenarios where single-commit summaries are used.
* @param shouldSummarizeProtocolTree - Callback function to learn about the service preference on whether single-commit summaries are enabled.
*/
constructor(internalStorageService, addProtocolSummaryIfMissing, shouldSummarizeProtocolTree) {
this.internalStorageService = internalStorageService;
this.addProtocolSummaryIfMissing = addProtocolSummaryIfMissing;
this.getSnapshotTree = this.internalStorageService.getSnapshotTree.bind(this.internalStorageService);
this.getSnapshot = this.internalStorageService.getSnapshot?.bind(this.internalStorageService);
this.getVersions = this.internalStorageService.getVersions.bind(this.internalStorageService);
this.createBlob = this.internalStorageService.createBlob.bind(this.internalStorageService);
this.readBlob = this.internalStorageService.readBlob.bind(this.internalStorageService);
this.downloadSummary = this.internalStorageService.downloadSummary.bind(this.internalStorageService);
this.dispose = this.internalStorageService.dispose.bind(this.internalStorageService);
this.shouldSummarizeProtocolTree = shouldSummarizeProtocolTree;
this.getSnapshotTree = internalStorageService.getSnapshotTree.bind(internalStorageService);
this.getSnapshot = internalStorageService.getSnapshot?.bind(internalStorageService);
this.getVersions = internalStorageService.getVersions.bind(internalStorageService);
this.createBlob = internalStorageService.createBlob.bind(internalStorageService);
this.readBlob = internalStorageService.readBlob.bind(internalStorageService);
this.downloadSummary = internalStorageService.downloadSummary.bind(internalStorageService);
this.dispose = internalStorageService.dispose.bind(internalStorageService);
}

@@ -32,3 +39,5 @@ get policies() {

async uploadSummaryWithContext(summary, context) {
return this.internalStorageService.uploadSummaryWithContext(this.addProtocolSummaryIfMissing(summary), context);
return this.shouldSummarizeProtocolTree()
? this.internalStorageService.uploadSummaryWithContext(this.addProtocolSummaryIfMissing(summary), context)
: this.internalStorageService.uploadSummaryWithContext(summary, context);
}

@@ -35,0 +44,0 @@ }

@@ -6,4 +6,4 @@ /*!

import { IFluidCodeDetails } from "@fluidframework/container-definitions/internal";
import { ICommittedProposal } from "@fluidframework/protocol-definitions";
import { ICommittedProposal } from "@fluidframework/driver-definitions/internal";
export declare function initQuorumValuesFromCodeDetails(source: IFluidCodeDetails): [string, ICommittedProposal][];
//# sourceMappingURL=quorum.d.ts.map

@@ -6,4 +6,4 @@ /*!

import { IDisposable } from "@fluidframework/core-interfaces";
import { FetchSource, IDocumentStorageService, IDocumentStorageServicePolicies, ISnapshot, ISnapshotFetchOptions, ISummaryContext } from "@fluidframework/driver-definitions/internal";
import { ICreateBlobResponse, ISnapshotTree, ISummaryHandle, ISummaryTree, IVersion } from "@fluidframework/protocol-definitions";
import { ISummaryHandle, ISummaryTree } from "@fluidframework/driver-definitions";
import { FetchSource, IDocumentStorageService, IDocumentStorageServicePolicies, ISnapshot, ISnapshotFetchOptions, ISummaryContext, ICreateBlobResponse, ISnapshotTree, IVersion } from "@fluidframework/driver-definitions/internal";
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";

@@ -10,0 +10,0 @@ export declare class RetriableDocumentStorageService implements IDocumentStorageService, IDisposable {

@@ -16,3 +16,5 @@ "use strict";

this._disposed = false;
this.internalStorageServiceP.then((s) => (this.internalStorageService = s)).catch(() => { });
this.internalStorageServiceP
.then((s) => (this.internalStorageService = s))
.catch(() => { });
}

@@ -19,0 +21,0 @@ get policies() {

@@ -6,6 +6,5 @@ /*!

import { IGetPendingLocalStateProps, IRuntime } from "@fluidframework/container-definitions/internal";
import { IDocumentStorageService, IResolvedUrl, ISnapshot } from "@fluidframework/driver-definitions/internal";
import { ISequencedDocumentMessage, ISnapshotTree, IVersion } from "@fluidframework/protocol-definitions";
import type { IEventProvider, IEvent, ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
import { IDocumentStorageService, IResolvedUrl, ISnapshot, ISnapshotTree, IVersion, ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
import { MonitoringContext } from "@fluidframework/telemetry-utils/internal";
import type { ITelemetryBaseLogger, IEventProvider, IEvent } from "@fluidframework/core-interfaces";
import { ISerializableBlobContents } from "./containerStorageAdapter.js";

@@ -101,2 +100,3 @@ /**

private readonly containerDirty;
private readonly supportGetSnapshotApi;
private readonly processedOps;

@@ -116,3 +116,3 @@ private readonly mc;

*/
constructor(pendingLocalState: IPendingContainerState | undefined, subLogger: ITelemetryBaseLogger, storageAdapter: ISerializedStateManagerDocumentStorageService, _offlineLoadEnabled: boolean, containerEvent: IEventProvider<ISerializerEvent>, containerDirty: () => boolean);
constructor(pendingLocalState: IPendingContainerState | undefined, subLogger: ITelemetryBaseLogger, storageAdapter: ISerializedStateManagerDocumentStorageService, _offlineLoadEnabled: boolean, containerEvent: IEventProvider<ISerializerEvent>, containerDirty: () => boolean, supportGetSnapshotApi: () => boolean);
get offlineLoadEnabled(): boolean;

@@ -137,3 +137,3 @@ /**

*/
fetchSnapshot(specifiedVersion: string | undefined, supportGetSnapshotApi: boolean): Promise<{
fetchSnapshot(specifiedVersion: string | undefined): Promise<{
baseSnapshot: ISnapshotTree | ISnapshot;

@@ -140,0 +140,0 @@ version: IVersion | undefined;

@@ -31,3 +31,3 @@ "use strict";

*/
constructor(pendingLocalState, subLogger, storageAdapter, _offlineLoadEnabled, containerEvent, containerDirty) {
constructor(pendingLocalState, subLogger, storageAdapter, _offlineLoadEnabled, containerEvent, containerDirty, supportGetSnapshotApi) {
this.pendingLocalState = pendingLocalState;

@@ -37,2 +37,3 @@ this.storageAdapter = storageAdapter;

this.containerDirty = containerDirty;
this.supportGetSnapshotApi = supportGetSnapshotApi;
this.processedOps = [];

@@ -44,2 +45,5 @@ this.lastSavedOpSequenceNumber = 0;

});
// special case handle. Obtaining the last saved op seq num to avoid
// refreshing the snapshot before we have processed it. It could cause
// a subsequent stashing to have a newer snapshot than allowed.
if (pendingLocalState && pendingLocalState.savedOps.length > 0) {

@@ -80,5 +84,5 @@ const savedOpsSize = pendingLocalState.savedOps.length;

*/
async fetchSnapshot(specifiedVersion, supportGetSnapshotApi) {
async fetchSnapshot(specifiedVersion) {
if (this.pendingLocalState === undefined) {
const { baseSnapshot, version } = await getSnapshot(this.mc, this.storageAdapter, supportGetSnapshotApi, specifiedVersion);
const { baseSnapshot, version } = await getSnapshot(this.mc, this.storageAdapter, this.supportGetSnapshotApi(), specifiedVersion);
const baseSnapshotTree = (0, internal_3.getSnapshotTree)(baseSnapshot);

@@ -108,3 +112,3 @@ // non-interactive clients will not have any pending state we want to save

// Don't block on the refresh snapshot call - it is for the next time we serialize, not booting this incarnation
this.refreshSnapshotP = this.refreshLatestSnapshot(supportGetSnapshotApi);
this.refreshSnapshotP = this.refreshLatestSnapshot(this.supportGetSnapshotApi());
this.refreshSnapshotP.catch((e) => {

@@ -195,5 +199,3 @@ this.mc.logger.sendErrorEvent({

firstProcessedOpSequenceNumber,
newFirstProcessedOpSequenceNumber: this.processedOps.length === 0
? undefined
: this.processedOps[0].sequenceNumber,
newFirstProcessedOpSequenceNumber: this.processedOps.length === 0 ? undefined : this.processedOps[0].sequenceNumber,
});

@@ -228,4 +230,8 @@ }

eventName: "getPendingLocalState",
notifyImminentClosure: props.notifyImminentClosure,
processedOpsSize: this.processedOps.length,
details: {
notifyImminentClosure: props.notifyImminentClosure,
sessionExpiryTimerStarted: props.sessionExpiryTimerStarted,
snapshotSequenceNumber: props.snapshotSequenceNumber,
processedOpsSize: this.processedOps.length,
},
clientId,

@@ -257,5 +263,3 @@ }, async () => {

snapshotBlobs: this.snapshot.snapshotBlobs,
loadedGroupIdSnapshots: hasGroupIdSnapshots
? loadedGroupIdSnapshots
: undefined,
loadedGroupIdSnapshots: hasGroupIdSnapshots ? loadedGroupIdSnapshots : undefined,
savedOps: this.processedOps,

@@ -262,0 +266,0 @@ url: resolvedUrl.url,

@@ -5,5 +5,6 @@ /*!

*/
import { ISummaryTree } from "@fluidframework/driver-definitions";
import { IDocumentAttributes, ISnapshotTree } from "@fluidframework/driver-definitions/internal";
import { IDocumentStorageService, type ISnapshot } from "@fluidframework/driver-definitions/internal";
import { CombinedAppAndProtocolSummary, DeltaStreamConnectionForbiddenError } from "@fluidframework/driver-utils/internal";
import { IDocumentAttributes, ISnapshotTree, ISummaryTree } from "@fluidframework/protocol-definitions";
import { ISerializableBlobContents } from "./containerStorageAdapter.js";

@@ -10,0 +11,0 @@ import type { IPendingContainerState, IPendingDetachedContainerState, ISnapshotInfo, SnapshotWithBlobs } from "./serializedStateManager.js";

@@ -10,5 +10,5 @@ "use strict";

const internal_1 = require("@fluidframework/core-utils/internal");
const driver_definitions_1 = require("@fluidframework/driver-definitions");
const internal_2 = require("@fluidframework/driver-definitions/internal");
const internal_3 = require("@fluidframework/driver-utils/internal");
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
const internal_4 = require("@fluidframework/telemetry-utils/internal");

@@ -54,3 +54,3 @@ const uuid_1 = require("uuid");

const createNewSummary = {
type: protocol_definitions_1.SummaryType.Tree,
type: driver_definitions_1.SummaryType.Tree,
tree: {

@@ -82,3 +82,3 @@ ".protocol": protocolSummary,

switch (summaryObject.type) {
case protocol_definitions_1.SummaryType.Tree: {
case driver_definitions_1.SummaryType.Tree: {
const innerSnapshot = convertSummaryToSnapshotAndBlobs(summaryObject);

@@ -89,6 +89,6 @@ treeNode.trees[key] = innerSnapshot.baseSnapshot;

}
case protocol_definitions_1.SummaryType.Attachment:
case driver_definitions_1.SummaryType.Attachment:
treeNode.blobs[key] = summaryObject.id;
break;
case protocol_definitions_1.SummaryType.Blob: {
case driver_definitions_1.SummaryType.Blob: {
const blobId = (0, uuid_1.v4)();

@@ -102,3 +102,3 @@ treeNode.blobs[key] = blobId;

}
case protocol_definitions_1.SummaryType.Handle:
case driver_definitions_1.SummaryType.Handle:
throw new internal_4.LoggingError("No handles should be there in summary in detached container!!");

@@ -162,3 +162,3 @@ default: {

const combinedSummary = {
type: protocol_definitions_1.SummaryType.Tree,
type: driver_definitions_1.SummaryType.Tree,
tree: { ...appSummaryTree.tree },

@@ -165,0 +165,0 @@ };

@@ -6,5 +6,5 @@ /*!

import { AttachState } from "@fluidframework/container-definitions";
import { ISummaryTree } from "@fluidframework/driver-definitions";
import { IDocumentStorageService } from "@fluidframework/driver-definitions/internal";
import { CombinedAppAndProtocolSummary } from "@fluidframework/driver-utils/internal";
import { ISummaryTree } from "@fluidframework/protocol-definitions";
import { IDetachedBlobStorage } from "./loader.js";

@@ -11,0 +11,0 @@ import type { SnapshotWithBlobs } from "./serializedStateManager.js";

@@ -6,4 +6,5 @@ /*!

import { TypedEventEmitter } from "@fluid-internal/client-utils";
import { IAudienceEvents, IAudienceOwner, ISelf } from "@fluidframework/container-definitions/internal";
import { IClient } from "@fluidframework/protocol-definitions";
import { IAudienceEvents, ISelf } from "@fluidframework/container-definitions";
import { IAudienceOwner } from "@fluidframework/container-definitions/internal";
import { IClient } from "@fluidframework/driver-definitions";
/**

@@ -10,0 +11,0 @@ * Audience represents all clients connected to the op stream.

@@ -5,6 +5,7 @@ /*!

*/
import { ICriticalContainerError, IDeltaQueue, ReadOnlyInfo } from "@fluidframework/container-definitions/internal";
import { ICriticalContainerError } from "@fluidframework/container-definitions";
import { IDeltaQueue, ReadOnlyInfo } from "@fluidframework/container-definitions/internal";
import { ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
import { IDocumentService } from "@fluidframework/driver-definitions/internal";
import { ConnectionMode, IClient, IClientConfiguration, IClientDetails, IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
import { ConnectionMode, IClient, IClientDetails } from "@fluidframework/driver-definitions";
import { IDocumentService, IClientConfiguration, IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";

@@ -11,0 +12,0 @@ import { IConnectionDetailsInternal, IConnectionManager, IConnectionManagerFactoryArgs, IConnectionStateChangeReason, ReconnectMode } from "./contracts.js";

@@ -6,7 +6,6 @@ /*!

import { TypedEventEmitter, performance } from "@fluid-internal/client-utils";
import { LogLevel } from "@fluidframework/core-interfaces";
import { LogLevel, } from "@fluidframework/core-interfaces";
import { assert } from "@fluidframework/core-utils/internal";
import { DriverErrorTypes, } from "@fluidframework/driver-definitions/internal";
import { DriverErrorTypes, MessageType, ScopeType, } from "@fluidframework/driver-definitions/internal";
import { calculateMaxWaitTime, canRetryOnError, createGenericNetworkError, createWriteError, getRetryDelayFromError, isRuntimeMessage, logNetworkFailure, } from "@fluidframework/driver-utils/internal";
import { MessageType, ScopeType, } from "@fluidframework/protocol-definitions";
import { GenericError, UsageError, formatTick, generateStack, isFluidError, normalizeError, } from "@fluidframework/telemetry-utils/internal";

@@ -35,3 +34,3 @@ import { ReconnectMode, } from "./contracts.js";

permission: [],
user: { id: "storage-only client" },
user: { id: "storage-only client" }, // we need some "fake" ID here.
scopes: [],

@@ -493,3 +492,3 @@ };

attempts: connectRepeatCount,
delay: delayMs,
delay: delayMs, // milliseconds
eventName: "DeltaConnectionFailureToConnect",

@@ -705,3 +704,3 @@ duration: formatTick(performance.now() - connectStartTime),

const clearSignal = {
clientId: null,
clientId: null, // system message
content: JSON.stringify({

@@ -714,3 +713,3 @@ type: SignalType.Clear,

const clientJoinSignals = (connection.initialClients ?? []).map((priorClient) => ({
clientId: null,
clientId: null, // system signal
content: JSON.stringify({

@@ -717,0 +716,0 @@ type: SignalType.ClientJoin,

@@ -7,4 +7,4 @@ /*!

import { ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
import { IClient, ISequencedClient } from "@fluidframework/driver-definitions";
import { IAnyDriverError } from "@fluidframework/driver-definitions/internal";
import { IClient, ISequencedClient } from "@fluidframework/protocol-definitions";
import { type TelemetryEventCategory, ITelemetryLoggerExt, MonitoringContext } from "@fluidframework/telemetry-utils/internal";

@@ -11,0 +11,0 @@ import { ConnectionState } from "./connectionState.js";

@@ -407,4 +407,2 @@ /*!

else if (value === ConnectionState.Disconnected) {
// Clear pending state immediately to prepare for reconnect
this._pendingClientId = undefined;
if (this.joinTimer.hasTimer) {

@@ -436,4 +434,10 @@ this.stopjoinTimer();

}
// Report transition before we propagate event across layers
// Report transition
this.handler.connectionStateChanged(this._connectionState, oldState, reason);
// Clear pending state immediately to prepare for reconnect
// Do it after calling connectionStateChanged() above, such that our telemetry contains pendingClientId on disconnect events
// and we can pair attempts to connect with disconnects (that's the only ID we have if connection did not move far enough before being disconnected)
if (value === ConnectionState.Disconnected) {
this._pendingClientId = undefined;
}
}

@@ -471,3 +475,3 @@ get membership() {

}
assert(!this.waitingForLeaveOp, "leave timer can't be set as we have not had access to quorum");
assert(!this.waitingForLeaveOp, 0x99d /* leave timer can't be set as we have not had access to quorum */);
// This check is required for scenario of loading container from pending state, and ensuring there is no way

@@ -474,0 +478,0 @@ // old clientId is still in the quorum (very unlikely, but you never know)

@@ -8,4 +8,4 @@ /*!

import { FluidObject, IRequest, ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
import { IDocumentServiceFactory, IResolvedUrl, IUrlResolver } from "@fluidframework/driver-definitions/internal";
import { IClientDetails, IDocumentMessage, IQuorumClients, ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
import { IClientDetails, IQuorumClients } from "@fluidframework/driver-definitions";
import { IDocumentServiceFactory, IResolvedUrl, IUrlResolver, IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
import { ITelemetryLoggerExt, EventEmitterWithErrorHandling } from "@fluidframework/telemetry-utils/internal";

@@ -222,2 +222,3 @@ import { ConnectionState } from "./connectionState.js";

private get isInteractiveClient();
private supportGetSnapshotApi;
/**

@@ -224,0 +225,0 @@ * Get the code details that are currently specified for the container.

@@ -9,4 +9,4 @@ /*!

import { type ISignalEnvelope } from "@fluidframework/core-interfaces/internal";
import { IDocumentStorageService, ISnapshot } from "@fluidframework/driver-definitions/internal";
import { IClientDetails, IDocumentMessage, IQuorumClients, ISequencedDocumentMessage, ISnapshotTree, ISummaryContent, IVersion, MessageType } from "@fluidframework/protocol-definitions";
import { IClientDetails, IQuorumClients } from "@fluidframework/driver-definitions";
import { IDocumentStorageService, ISnapshot, IDocumentMessage, ISnapshotTree, ISummaryContent, IVersion, MessageType, ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";

@@ -13,0 +13,0 @@ /**

@@ -7,4 +7,4 @@ /*!

import { IDisposable } from "@fluidframework/core-interfaces";
import { FetchSource, IDocumentService, IDocumentStorageService, IDocumentStorageServicePolicies, ISnapshot, ISnapshotFetchOptions, ISummaryContext } from "@fluidframework/driver-definitions/internal";
import { ICreateBlobResponse, ISnapshotTree, ISummaryHandle, ISummaryTree, IVersion } from "@fluidframework/protocol-definitions";
import { ISummaryHandle, ISummaryTree } from "@fluidframework/driver-definitions";
import { FetchSource, IDocumentService, IDocumentStorageService, IDocumentStorageServicePolicies, ISnapshot, ISnapshotFetchOptions, ISummaryContext, ICreateBlobResponse, ISnapshotTree, IVersion } from "@fluidframework/driver-definitions/internal";
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";

@@ -32,2 +32,3 @@ import { IDetachedBlobStorage } from "./loader.js";

private readonly addProtocolSummaryIfMissing;
private readonly enableSummarizeProtocolTree;
private _storageService;

@@ -52,3 +53,3 @@ private _summarizeProtocolTree;

* upload, and fix it up with a protocol tree if needed
* @param forceEnableSummarizeProtocolTree - Enforce uploading a protocol summary regardless of the service's policy
* @param enableSummarizeProtocolTree - Enable uploading a protocol summary. Note: preference is given to service policy's "summarizeProtocolTree" before this value.
*/

@@ -61,3 +62,3 @@ constructor(detachedBlobStorage: IDetachedBlobStorage | undefined, logger: ITelemetryLoggerExt,

[id: string]: ArrayBufferLike | string;
}, loadingGroupIdSnapshotsFromPendingState: Record<string, ISnapshotInfo> | undefined, addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree, forceEnableSummarizeProtocolTree: boolean | undefined);
}, loadingGroupIdSnapshotsFromPendingState: Record<string, ISnapshotInfo> | undefined, addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree, enableSummarizeProtocolTree: boolean | undefined);
disposed: boolean;

@@ -64,0 +65,0 @@ dispose(error?: Error): void;

@@ -36,3 +36,3 @@ /*!

* upload, and fix it up with a protocol tree if needed
* @param forceEnableSummarizeProtocolTree - Enforce uploading a protocol summary regardless of the service's policy
* @param enableSummarizeProtocolTree - Enable uploading a protocol summary. Note: preference is given to service policy's "summarizeProtocolTree" before this value.
*/

@@ -45,3 +45,3 @@ constructor(

*/
blobContents = {}, loadingGroupIdSnapshotsFromPendingState, addProtocolSummaryIfMissing, forceEnableSummarizeProtocolTree) {
blobContents = {}, loadingGroupIdSnapshotsFromPendingState, addProtocolSummaryIfMissing, enableSummarizeProtocolTree) {
this.logger = logger;

@@ -51,6 +51,6 @@ this.blobContents = blobContents;

this.addProtocolSummaryIfMissing = addProtocolSummaryIfMissing;
this.enableSummarizeProtocolTree = enableSummarizeProtocolTree;
this._loadedGroupIdSnapshots = {};
this.disposed = false;
this._storageService = new BlobOnlyStorage(detachedBlobStorage, logger);
this._summarizeProtocolTree = forceEnableSummarizeProtocolTree;
}

@@ -67,8 +67,24 @@ dispose(error) {

const retriableStorage = (this._storageService = new RetriableDocumentStorageService(storageServiceP, this.logger));
this._summarizeProtocolTree =
this._summarizeProtocolTree ?? service.policies?.summarizeProtocolTree;
if (this.summarizeProtocolTree) {
// A storage service wrapper which intercept calls to uploadSummaryWithContext and ensure they include
// the protocol summary, provided single-commit summary is enabled.
this._storageService = new ProtocolTreeStorageService(retriableStorage, (...props) => {
this.logger.sendTelemetryEvent({ eventName: "summarizeProtocolTreeEnabled" });
this._storageService = new ProtocolTreeStorageService(retriableStorage, this.addProtocolSummaryIfMissing);
}
return this.addProtocolSummaryIfMissing(...props);
},
// A callback to ensure we fetch the most updated value of service.policies.summarizeProtocolTree, which could be set
// based on the response received from the service after connection is established.
() => {
// Determine whether or not container should upload the protocol summary along with the summary.
// This is determined based on what value is set for serve policy's summariProtocolTree value or the enableSummarizeProtocolTree
// retrievd from the loader options or monitoring context config.
const shouldSummarizeProtocolTree = service.policies?.summarizeProtocolTree ?? this.enableSummarizeProtocolTree ?? false;
if (this._summarizeProtocolTree !== shouldSummarizeProtocolTree) {
this.logger.sendTelemetryEvent({
eventName: "isSummarizeProtocolTreeEnabled",
details: { value: shouldSummarizeProtocolTree },
});
}
this._summarizeProtocolTree = shouldSummarizeProtocolTree;
return this._summarizeProtocolTree;
});
}

@@ -75,0 +91,0 @@ loadSnapshotFromSnapshotBlobs(snapshotBlobs) {

@@ -8,4 +8,4 @@ /*!

import { IErrorBase, ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
import { IContainerPackageInfo } from "@fluidframework/driver-definitions/internal";
import { ConnectionMode, IClientConfiguration, IClientDetails, IDocumentMessage, ISequencedDocumentMessage, ISignalClient, ISignalMessage } from "@fluidframework/protocol-definitions";
import { ConnectionMode, IClientDetails } from "@fluidframework/driver-definitions";
import { IContainerPackageInfo, IClientConfiguration, IDocumentMessage, ISignalClient, ISequencedDocumentMessage, ISignalMessage } from "@fluidframework/driver-definitions/internal";
export declare enum ReconnectMode {

@@ -12,0 +12,0 @@ Never = "Never",

@@ -5,7 +5,8 @@ /*!

*/
import { ICriticalContainerError, IDeltaManager, IDeltaManagerEvents, IDeltaQueue } from "@fluidframework/container-definitions/internal";
import { ICriticalContainerError } from "@fluidframework/container-definitions";
import { IDeltaManager, IDeltaManagerEvents, IDeltaQueue } from "@fluidframework/container-definitions/internal";
import { IEventProvider, ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
import { IThrottlingWarning } from "@fluidframework/core-interfaces/internal";
import { IDocumentService } from "@fluidframework/driver-definitions/internal";
import { ConnectionMode, IDocumentMessage, ISequencedDocumentMessage, ISignalMessage, MessageType } from "@fluidframework/protocol-definitions";
import { ConnectionMode } from "@fluidframework/driver-definitions";
import { IDocumentService, IDocumentMessage, MessageType, ISequencedDocumentMessage, ISignalMessage } from "@fluidframework/driver-definitions/internal";
import { type ITelemetryErrorEventExt, ITelemetryLoggerExt, EventEmitterWithErrorHandling } from "@fluidframework/telemetry-utils/internal";

@@ -100,6 +101,6 @@ import { IConnectionDetailsInternal, IConnectionManager, IConnectionManagerFactoryArgs, IConnectionStateChangeReason } from "./contracts.js";

get version(): string;
get serviceConfiguration(): import("@fluidframework/protocol-definitions").IClientConfiguration | undefined;
get serviceConfiguration(): import("@fluidframework/driver-definitions/internal").IClientConfiguration | undefined;
get outbound(): IDeltaQueue<IDocumentMessage[]>;
get readOnlyInfo(): import("@fluidframework/container-definitions/internal").ReadOnlyInfo;
get clientDetails(): import("@fluidframework/protocol-definitions").IClientDetails;
get clientDetails(): import("@fluidframework/driver-definitions").IClientDetails;
submit(type: MessageType, contents?: string, batch?: boolean, metadata?: any, compression?: string, referenceSequenceNumber?: number): number;

@@ -106,0 +107,0 @@ submitSignal(content: string, targetClientId?: string): void;

@@ -6,5 +6,4 @@ /*!

import { assert } from "@fluidframework/core-utils/internal";
import { DriverErrorTypes, } from "@fluidframework/driver-definitions/internal";
import { DriverErrorTypes, MessageType, } from "@fluidframework/driver-definitions/internal";
import { MessageType2, NonRetryableError, isRuntimeMessage, } from "@fluidframework/driver-utils/internal";
import { MessageType, } from "@fluidframework/protocol-definitions";
import { DataCorruptionError, DataProcessingError, UsageError, extractSafePropertiesFromMessage, isFluidError, normalizeError, safeRaiseEvent, EventEmitterWithErrorHandling, } from "@fluidframework/telemetry-utils/internal";

@@ -187,10 +186,10 @@ import { v4 as uuid } from "uuid";

// A bunch of useful sequence numbers to understand if we are holding some ops from processing
lastQueuedSequenceNumber: this.lastQueuedSequenceNumber,
lastProcessedSequenceNumber: this.lastProcessedSequenceNumber,
lastObserved: this.lastObservedSeqNumber,
lastQueuedSequenceNumber: this.lastQueuedSequenceNumber, // last sequential op
lastProcessedSequenceNumber: this.lastProcessedSequenceNumber, // same as above, but after processing
lastObserved: this.lastObservedSeqNumber, // last sequence we ever saw; may have gaps with above.
// connection info
...this.connectionManager.connectionVerboseProps,
pendingOps: this.pending.length,
pendingFirst: pendingSorted[0]?.sequenceNumber,
haveHandler: this.handler !== undefined,
pendingOps: this.pending.length, // Do we have any pending ops?
pendingFirst: pendingSorted[0]?.sequenceNumber, // is the first pending op the one that we are missing?
haveHandler: this.handler !== undefined, // do we have handler installed?
inboundLength: this.inbound.length,

@@ -641,3 +640,3 @@ inboundPaused: this.inbound.paused,

from,
to: last + 1,
to: last + 1, // exclusive, being consistent with the other telemetry / APIs
length: messages.length,

@@ -644,0 +643,0 @@ fetchReason: this.fetchReason,

@@ -12,2 +12,3 @@ /*!

export { tryParseCompatibleResolvedUrl, IParsedUrl } from "./utils.js";
export { IBaseProtocolHandler, IScribeProtocolState, IQuorumSnapshot, QuorumClientsSnapshot, QuorumProposalsSnapshot, } from "./protocol/index.js";
//# sourceMappingURL=index.d.ts.map

@@ -16,2 +16,3 @@ /*!

// @alpha APIs
IBaseProtocolHandler,
ICodeDetailsLoader,

@@ -25,4 +26,8 @@ IDetachedBlobStorage,

IProtocolHandler,
IQuorumSnapshot,
IScribeProtocolState,
Loader,
ProtocolHandlerBuilder,
QuorumClientsSnapshot,
QuorumProposalsSnapshot,
resolveWithLocationRedirectionHandling,

@@ -29,0 +34,0 @@ tryParseCompatibleResolvedUrl,

@@ -7,4 +7,4 @@ /*!

import { FluidObject, IConfigProviderBase, IRequest, ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
import { IClientDetails } from "@fluidframework/driver-definitions";
import { IDocumentServiceFactory, IDocumentStorageService, IUrlResolver } from "@fluidframework/driver-definitions/internal";
import { IClientDetails } from "@fluidframework/protocol-definitions";
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";

@@ -11,0 +11,0 @@ import { Container } from "./container.js";

@@ -13,3 +13,4 @@ /*!

MemoryDetachedBlobStorageIdentifier in detachedStorage &&
detachedStorage[MemoryDetachedBlobStorageIdentifier] === MemoryDetachedBlobStorageIdentifier);
detachedStorage[MemoryDetachedBlobStorageIdentifier] ===
MemoryDetachedBlobStorageIdentifier);
}

@@ -29,5 +30,5 @@ export function serializeMemoryDetachedBlobStorage(

}
assert(detachedStorage.size === 0, "Blob storage already initialized");
assert(detachedStorage.size === 0, 0x99e /* Blob storage already initialized */);
const maybeAttachmentBlobs = JSON.parse(attachmentBlobs);
assert(Array.isArray(maybeAttachmentBlobs), "Invalid attachmentBlobs");
assert(Array.isArray(maybeAttachmentBlobs), 0x99f /* Invalid attachmentBlobs */);
detachedStorage.initialize(maybeAttachmentBlobs);

@@ -34,0 +35,0 @@ }

@@ -7,3 +7,3 @@ /*!

import { IEvent } from "@fluidframework/core-interfaces";
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
export interface INoopSenderEvents extends IEvent {

@@ -10,0 +10,0 @@ (event: "wantsNoop", listener: () => void): any;

@@ -8,3 +8,3 @@ /*!

export declare const pkgName = "@fluidframework/container-loader";
export declare const pkgVersion = "2.0.0-rc.4.0.6";
export declare const pkgVersion = "2.0.0-rc.5.0.0";
//# sourceMappingURL=packageVersion.d.ts.map

@@ -8,3 +8,3 @@ /*!

export const pkgName = "@fluidframework/container-loader";
export const pkgVersion = "2.0.0-rc.4.0.6";
export const pkgVersion = "2.0.0-rc.5.0.0";
//# sourceMappingURL=packageVersion.js.map

@@ -6,7 +6,7 @@ /*!

import { IAudienceOwner } from "@fluidframework/container-definitions/internal";
import { IProtocolHandler as IBaseProtocolHandler, IQuorumSnapshot, ProtocolOpHandler } from "@fluidframework/protocol-base";
import { IDocumentAttributes, IProcessMessageResult, ISequencedDocumentMessage, ISignalMessage } from "@fluidframework/protocol-definitions";
import { IDocumentAttributes, IProcessMessageResult, ISequencedDocumentMessage, ISignalMessage } from "@fluidframework/driver-definitions/internal";
import { IBaseProtocolHandler, IQuorumSnapshot, ProtocolOpHandler } from "./protocol/index.js";
export declare enum SignalType {
ClientJoin = "join",
ClientLeave = "leave",
ClientJoin = "join",// same value as MessageType.ClientJoin,
ClientLeave = "leave",// same value as MessageType.ClientLeave,
Clear = "clear"

@@ -13,0 +13,0 @@ }

@@ -5,5 +5,5 @@ /*!

*/
import { MessageType, } from "@fluidframework/driver-definitions/internal";
import { canBeCoalescedByService } from "@fluidframework/driver-utils/internal";
import { ProtocolOpHandler, } from "@fluidframework/protocol-base";
import { MessageType, } from "@fluidframework/protocol-definitions";
import { ProtocolOpHandler } from "./protocol/index.js";
// ADO: #1986: Start using enum from protocol-base.

@@ -10,0 +10,0 @@ export var SignalType;

@@ -6,4 +6,4 @@ /*!

import { IDisposable } from "@fluidframework/core-interfaces";
import { ISummaryTree } from "@fluidframework/driver-definitions";
import { IDocumentStorageService, ISummaryContext } from "@fluidframework/driver-definitions/internal";
import { ISummaryTree } from "@fluidframework/protocol-definitions";
/**

@@ -16,14 +16,21 @@ * A storage service wrapper whose sole job is to intercept calls to uploadSummaryWithContext and ensure they include

private readonly addProtocolSummaryIfMissing;
constructor(internalStorageService: IDocumentStorageService & IDisposable, addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree);
private readonly shouldSummarizeProtocolTree;
/**
*
* @param internalStorageService - Document storage service responsible to make api calls to the storage.
* @param addProtocolSummaryIfMissing - Function to add protocol summary tree to the summary. Used in scenarios where single-commit summaries are used.
* @param shouldSummarizeProtocolTree - Callback function to learn about the service preference on whether single-commit summaries are enabled.
*/
constructor(internalStorageService: IDocumentStorageService & IDisposable, addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree, shouldSummarizeProtocolTree: () => boolean);
get policies(): import("@fluidframework/driver-definitions/internal").IDocumentStorageServicePolicies | undefined;
get disposed(): boolean;
getSnapshotTree: (version?: import("@fluidframework/protocol-definitions").IVersion | undefined, scenarioName?: string | undefined) => Promise<import("@fluidframework/protocol-definitions").ISnapshotTree | null>;
getSnapshot: ((snapshotFetchOptions?: import("@fluidframework/driver-definitions/internal").ISnapshotFetchOptions | undefined) => Promise<import("@fluidframework/driver-definitions/internal").ISnapshot>) | undefined;
getVersions: (versionId: string | null, count: number, scenarioName?: string | undefined, fetchSource?: import("@fluidframework/driver-definitions/internal").FetchSource | undefined) => Promise<import("@fluidframework/protocol-definitions").IVersion[]>;
createBlob: (file: ArrayBufferLike) => Promise<import("@fluidframework/protocol-definitions").ICreateBlobResponse>;
readBlob: (id: string) => Promise<ArrayBufferLike>;
downloadSummary: (handle: import("@fluidframework/protocol-definitions").ISummaryHandle) => Promise<ISummaryTree>;
dispose: (error?: Error | undefined) => void;
getSnapshotTree: IDocumentStorageService["getSnapshotTree"];
getSnapshot: IDocumentStorageService["getSnapshot"];
getVersions: IDocumentStorageService["getVersions"];
createBlob: IDocumentStorageService["createBlob"];
readBlob: IDocumentStorageService["readBlob"];
downloadSummary: IDocumentStorageService["downloadSummary"];
dispose: IDisposable["dispose"];
uploadSummaryWithContext(summary: ISummaryTree, context: ISummaryContext): Promise<string>;
}
//# sourceMappingURL=protocolTreeDocumentStorageService.d.ts.map

@@ -10,12 +10,19 @@ /*!

export class ProtocolTreeStorageService {
constructor(internalStorageService, addProtocolSummaryIfMissing) {
/**
*
* @param internalStorageService - Document storage service responsible to make api calls to the storage.
* @param addProtocolSummaryIfMissing - Function to add protocol summary tree to the summary. Used in scenarios where single-commit summaries are used.
* @param shouldSummarizeProtocolTree - Callback function to learn about the service preference on whether single-commit summaries are enabled.
*/
constructor(internalStorageService, addProtocolSummaryIfMissing, shouldSummarizeProtocolTree) {
this.internalStorageService = internalStorageService;
this.addProtocolSummaryIfMissing = addProtocolSummaryIfMissing;
this.getSnapshotTree = this.internalStorageService.getSnapshotTree.bind(this.internalStorageService);
this.getSnapshot = this.internalStorageService.getSnapshot?.bind(this.internalStorageService);
this.getVersions = this.internalStorageService.getVersions.bind(this.internalStorageService);
this.createBlob = this.internalStorageService.createBlob.bind(this.internalStorageService);
this.readBlob = this.internalStorageService.readBlob.bind(this.internalStorageService);
this.downloadSummary = this.internalStorageService.downloadSummary.bind(this.internalStorageService);
this.dispose = this.internalStorageService.dispose.bind(this.internalStorageService);
this.shouldSummarizeProtocolTree = shouldSummarizeProtocolTree;
this.getSnapshotTree = internalStorageService.getSnapshotTree.bind(internalStorageService);
this.getSnapshot = internalStorageService.getSnapshot?.bind(internalStorageService);
this.getVersions = internalStorageService.getVersions.bind(internalStorageService);
this.createBlob = internalStorageService.createBlob.bind(internalStorageService);
this.readBlob = internalStorageService.readBlob.bind(internalStorageService);
this.downloadSummary = internalStorageService.downloadSummary.bind(internalStorageService);
this.dispose = internalStorageService.dispose.bind(internalStorageService);
}

@@ -29,5 +36,7 @@ get policies() {

async uploadSummaryWithContext(summary, context) {
return this.internalStorageService.uploadSummaryWithContext(this.addProtocolSummaryIfMissing(summary), context);
return this.shouldSummarizeProtocolTree()
? this.internalStorageService.uploadSummaryWithContext(this.addProtocolSummaryIfMissing(summary), context)
: this.internalStorageService.uploadSummaryWithContext(summary, context);
}
}
//# sourceMappingURL=protocolTreeDocumentStorageService.js.map

@@ -6,4 +6,4 @@ /*!

import { IFluidCodeDetails } from "@fluidframework/container-definitions/internal";
import { ICommittedProposal } from "@fluidframework/protocol-definitions";
import { ICommittedProposal } from "@fluidframework/driver-definitions/internal";
export declare function initQuorumValuesFromCodeDetails(source: IFluidCodeDetails): [string, ICommittedProposal][];
//# sourceMappingURL=quorum.d.ts.map

@@ -6,4 +6,4 @@ /*!

import { IDisposable } from "@fluidframework/core-interfaces";
import { FetchSource, IDocumentStorageService, IDocumentStorageServicePolicies, ISnapshot, ISnapshotFetchOptions, ISummaryContext } from "@fluidframework/driver-definitions/internal";
import { ICreateBlobResponse, ISnapshotTree, ISummaryHandle, ISummaryTree, IVersion } from "@fluidframework/protocol-definitions";
import { ISummaryHandle, ISummaryTree } from "@fluidframework/driver-definitions";
import { FetchSource, IDocumentStorageService, IDocumentStorageServicePolicies, ISnapshot, ISnapshotFetchOptions, ISummaryContext, ICreateBlobResponse, ISnapshotTree, IVersion } from "@fluidframework/driver-definitions/internal";
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";

@@ -10,0 +10,0 @@ export declare class RetriableDocumentStorageService implements IDocumentStorageService, IDisposable {

@@ -13,3 +13,5 @@ /*!

this._disposed = false;
this.internalStorageServiceP.then((s) => (this.internalStorageService = s)).catch(() => { });
this.internalStorageServiceP
.then((s) => (this.internalStorageService = s))
.catch(() => { });
}

@@ -16,0 +18,0 @@ get policies() {

@@ -6,6 +6,5 @@ /*!

import { IGetPendingLocalStateProps, IRuntime } from "@fluidframework/container-definitions/internal";
import { IDocumentStorageService, IResolvedUrl, ISnapshot } from "@fluidframework/driver-definitions/internal";
import { ISequencedDocumentMessage, ISnapshotTree, IVersion } from "@fluidframework/protocol-definitions";
import type { IEventProvider, IEvent, ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
import { IDocumentStorageService, IResolvedUrl, ISnapshot, ISnapshotTree, IVersion, ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
import { MonitoringContext } from "@fluidframework/telemetry-utils/internal";
import type { ITelemetryBaseLogger, IEventProvider, IEvent } from "@fluidframework/core-interfaces";
import { ISerializableBlobContents } from "./containerStorageAdapter.js";

@@ -101,2 +100,3 @@ /**

private readonly containerDirty;
private readonly supportGetSnapshotApi;
private readonly processedOps;

@@ -116,3 +116,3 @@ private readonly mc;

*/
constructor(pendingLocalState: IPendingContainerState | undefined, subLogger: ITelemetryBaseLogger, storageAdapter: ISerializedStateManagerDocumentStorageService, _offlineLoadEnabled: boolean, containerEvent: IEventProvider<ISerializerEvent>, containerDirty: () => boolean);
constructor(pendingLocalState: IPendingContainerState | undefined, subLogger: ITelemetryBaseLogger, storageAdapter: ISerializedStateManagerDocumentStorageService, _offlineLoadEnabled: boolean, containerEvent: IEventProvider<ISerializerEvent>, containerDirty: () => boolean, supportGetSnapshotApi: () => boolean);
get offlineLoadEnabled(): boolean;

@@ -137,3 +137,3 @@ /**

*/
fetchSnapshot(specifiedVersion: string | undefined, supportGetSnapshotApi: boolean): Promise<{
fetchSnapshot(specifiedVersion: string | undefined): Promise<{
baseSnapshot: ISnapshotTree | ISnapshot;

@@ -140,0 +140,0 @@ version: IVersion | undefined;

@@ -10,3 +10,3 @@ /*!

import { PerformanceEvent, UsageError, createChildMonitoringContext, } from "@fluidframework/telemetry-utils/internal";
import { getBlobContentsFromTree } from "./containerStorageAdapter.js";
import { getBlobContentsFromTree, } from "./containerStorageAdapter.js";
import { convertSnapshotToSnapshotInfo, getDocumentAttributes } from "./utils.js";

@@ -29,3 +29,3 @@ /**

*/
constructor(pendingLocalState, subLogger, storageAdapter, _offlineLoadEnabled, containerEvent, containerDirty) {
constructor(pendingLocalState, subLogger, storageAdapter, _offlineLoadEnabled, containerEvent, containerDirty, supportGetSnapshotApi) {
this.pendingLocalState = pendingLocalState;

@@ -35,2 +35,3 @@ this.storageAdapter = storageAdapter;

this.containerDirty = containerDirty;
this.supportGetSnapshotApi = supportGetSnapshotApi;
this.processedOps = [];

@@ -42,2 +43,5 @@ this.lastSavedOpSequenceNumber = 0;

});
// special case handle. Obtaining the last saved op seq num to avoid
// refreshing the snapshot before we have processed it. It could cause
// a subsequent stashing to have a newer snapshot than allowed.
if (pendingLocalState && pendingLocalState.savedOps.length > 0) {

@@ -78,5 +82,5 @@ const savedOpsSize = pendingLocalState.savedOps.length;

*/
async fetchSnapshot(specifiedVersion, supportGetSnapshotApi) {
async fetchSnapshot(specifiedVersion) {
if (this.pendingLocalState === undefined) {
const { baseSnapshot, version } = await getSnapshot(this.mc, this.storageAdapter, supportGetSnapshotApi, specifiedVersion);
const { baseSnapshot, version } = await getSnapshot(this.mc, this.storageAdapter, this.supportGetSnapshotApi(), specifiedVersion);
const baseSnapshotTree = getSnapshotTree(baseSnapshot);

@@ -106,3 +110,3 @@ // non-interactive clients will not have any pending state we want to save

// Don't block on the refresh snapshot call - it is for the next time we serialize, not booting this incarnation
this.refreshSnapshotP = this.refreshLatestSnapshot(supportGetSnapshotApi);
this.refreshSnapshotP = this.refreshLatestSnapshot(this.supportGetSnapshotApi());
this.refreshSnapshotP.catch((e) => {

@@ -193,5 +197,3 @@ this.mc.logger.sendErrorEvent({

firstProcessedOpSequenceNumber,
newFirstProcessedOpSequenceNumber: this.processedOps.length === 0
? undefined
: this.processedOps[0].sequenceNumber,
newFirstProcessedOpSequenceNumber: this.processedOps.length === 0 ? undefined : this.processedOps[0].sequenceNumber,
});

@@ -226,4 +228,8 @@ }

eventName: "getPendingLocalState",
notifyImminentClosure: props.notifyImminentClosure,
processedOpsSize: this.processedOps.length,
details: {
notifyImminentClosure: props.notifyImminentClosure,
sessionExpiryTimerStarted: props.sessionExpiryTimerStarted,
snapshotSequenceNumber: props.snapshotSequenceNumber,
processedOpsSize: this.processedOps.length,
},
clientId,

@@ -255,5 +261,3 @@ }, async () => {

snapshotBlobs: this.snapshot.snapshotBlobs,
loadedGroupIdSnapshots: hasGroupIdSnapshots
? loadedGroupIdSnapshots
: undefined,
loadedGroupIdSnapshots: hasGroupIdSnapshots ? loadedGroupIdSnapshots : undefined,
savedOps: this.processedOps,

@@ -260,0 +264,0 @@ url: resolvedUrl.url,

@@ -8,5 +8,5 @@ // This file is read by tools that parse documentation comments conforming to the TSDoc standard.

"packageName": "@microsoft/api-extractor",
"packageVersion": "7.43.1"
"packageVersion": "7.45.1"
}
]
}

@@ -5,5 +5,6 @@ /*!

*/
import { ISummaryTree } from "@fluidframework/driver-definitions";
import { IDocumentAttributes, ISnapshotTree } from "@fluidframework/driver-definitions/internal";
import { IDocumentStorageService, type ISnapshot } from "@fluidframework/driver-definitions/internal";
import { CombinedAppAndProtocolSummary, DeltaStreamConnectionForbiddenError } from "@fluidframework/driver-utils/internal";
import { IDocumentAttributes, ISnapshotTree, ISummaryTree } from "@fluidframework/protocol-definitions";
import { ISerializableBlobContents } from "./containerStorageAdapter.js";

@@ -10,0 +11,0 @@ import type { IPendingContainerState, IPendingDetachedContainerState, ISnapshotInfo, SnapshotWithBlobs } from "./serializedStateManager.js";

@@ -5,7 +5,7 @@ /*!

*/
import { Uint8ArrayToString, bufferToString, stringToBuffer } from "@fluid-internal/client-utils";
import { Uint8ArrayToString, bufferToString, stringToBuffer, } from "@fluid-internal/client-utils";
import { assert, compareArrays, unreachableCase } from "@fluidframework/core-utils/internal";
import { DriverErrorTypes } from "@fluidframework/driver-definitions/internal";
import { SummaryType } from "@fluidframework/driver-definitions";
import { DriverErrorTypes, } from "@fluidframework/driver-definitions/internal";
import { isCombinedAppAndProtocolSummary, readAndParse, } from "@fluidframework/driver-utils/internal";
import { SummaryType, } from "@fluidframework/protocol-definitions";
import { LoggingError, UsageError } from "@fluidframework/telemetry-utils/internal";

@@ -12,0 +12,0 @@ import { v4 as uuid } from "uuid";

{
"name": "@fluidframework/container-loader",
"version": "2.0.0-rc.4.0.6",
"version": "2.0.0-rc.5.0.0",
"description": "Fluid container loader",

@@ -120,14 +120,14 @@ "homepage": "https://fluidframework.com",

"dependencies": {
"@fluid-internal/client-utils": ">=2.0.0-rc.4.0.6 <2.0.0-rc.4.1.0",
"@fluidframework/container-definitions": ">=2.0.0-rc.4.0.6 <2.0.0-rc.4.1.0",
"@fluidframework/core-interfaces": ">=2.0.0-rc.4.0.6 <2.0.0-rc.4.1.0",
"@fluidframework/core-utils": ">=2.0.0-rc.4.0.6 <2.0.0-rc.4.1.0",
"@fluidframework/driver-definitions": ">=2.0.0-rc.4.0.6 <2.0.0-rc.4.1.0",
"@fluidframework/driver-utils": ">=2.0.0-rc.4.0.6 <2.0.0-rc.4.1.0",
"@fluidframework/protocol-base": "^4.0.0",
"@fluidframework/protocol-definitions": "^3.2.0",
"@fluidframework/telemetry-utils": ">=2.0.0-rc.4.0.6 <2.0.0-rc.4.1.0",
"@fluid-internal/client-utils": ">=2.0.0-rc.5.0.0 <2.0.0-rc.5.1.0",
"@fluidframework/container-definitions": ">=2.0.0-rc.5.0.0 <2.0.0-rc.5.1.0",
"@fluidframework/core-interfaces": ">=2.0.0-rc.5.0.0 <2.0.0-rc.5.1.0",
"@fluidframework/core-utils": ">=2.0.0-rc.5.0.0 <2.0.0-rc.5.1.0",
"@fluidframework/driver-definitions": ">=2.0.0-rc.5.0.0 <2.0.0-rc.5.1.0",
"@fluidframework/driver-utils": ">=2.0.0-rc.5.0.0 <2.0.0-rc.5.1.0",
"@fluidframework/telemetry-utils": ">=2.0.0-rc.5.0.0 <2.0.0-rc.5.1.0",
"@types/events_pkg": "npm:@types/events@^3.0.0",
"@ungap/structured-clone": "^1.2.0",
"debug": "^4.3.4",
"double-ended-queue": "^2.1.0-0",
"events_pkg": "npm:events@^3.1.0",
"uuid": "^9.0.0"

@@ -137,11 +137,12 @@ },

"@arethetypeswrong/cli": "^0.15.2",
"@biomejs/biome": "^1.6.2",
"@fluid-internal/mocha-test-setup": ">=2.0.0-rc.4.0.6 <2.0.0-rc.4.1.0",
"@fluid-private/test-loader-utils": ">=2.0.0-rc.4.0.6 <2.0.0-rc.4.1.0",
"@fluid-tools/build-cli": "^0.38.0",
"@biomejs/biome": "^1.7.3",
"@fluid-internal/client-utils": ">=2.0.0-rc.5.0.0 <2.0.0-rc.5.1.0",
"@fluid-internal/mocha-test-setup": ">=2.0.0-rc.5.0.0 <2.0.0-rc.5.1.0",
"@fluid-private/test-loader-utils": ">=2.0.0-rc.5.0.0 <2.0.0-rc.5.1.0",
"@fluid-tools/build-cli": "^0.39.0",
"@fluidframework/build-common": "^2.0.3",
"@fluidframework/build-tools": "^0.38.0",
"@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.0.0-rc.3.0.0",
"@fluidframework/eslint-config-fluid": "^5.1.0",
"@microsoft/api-extractor": "^7.43.1",
"@fluidframework/build-tools": "^0.39.0",
"@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.0.0-rc.4.0.0",
"@fluidframework/eslint-config-fluid": "^5.3.0",
"@microsoft/api-extractor": "^7.45.1",
"@types/debug": "^4.1.5",

@@ -155,2 +156,3 @@ "@types/double-ended-queue": "^2.1.0",

"c8": "^8.0.1",
"concurrently": "^8.2.1",
"copyfiles": "^2.4.1",

@@ -166,15 +168,6 @@ "cross-env": "^7.0.3",

"sinon": "^17.0.1",
"typescript": "~5.1.6"
"typescript": "~5.4.5"
},
"typeValidation": {
"broken": {
"InterfaceDeclaration_IProtocolHandler": {
"forwardCompat": false,
"backCompat": false
},
"InterfaceDeclaration_IContainerExperimental": {
"forwardCompat": false,
"backCompat": false
}
}
"broken": {}
},

@@ -195,4 +188,11 @@ "scripts": {

"check:are-the-types-wrong": "attw --pack . --exclude-entrypoints ./internal/test/container ./internal/test/contracts ./internal/test/connectionManager ./internal/test/deltaManager ./internal/test/utils",
"check:biome": "biome check . --formatter-enabled=true",
"check:exports": "concurrently \"npm:check:exports:*\"",
"check:exports:bundle-release-tags": "api-extractor run --config api-extractor/api-extractor-lint-bundle.json",
"check:exports:cjs:legacy": "api-extractor run --config api-extractor/api-extractor-lint-legacy.cjs.json",
"check:exports:cjs:public": "api-extractor run --config api-extractor/api-extractor-lint-public.cjs.json",
"check:exports:esm:legacy": "api-extractor run --config api-extractor/api-extractor-lint-legacy.esm.json",
"check:exports:esm:public": "api-extractor run --config api-extractor/api-extractor-lint-public.esm.json",
"check:format": "npm run check:biome",
"check:prettier": "prettier --check . --cache --ignore-path ../../../.prettierignore",
"check:release-tags": "api-extractor run --local --config ./api-extractor-lint.json",
"ci:build:docs": "api-extractor run",

@@ -202,3 +202,4 @@ "clean": "rimraf --glob dist lib \"*.d.ts\" \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc",

"eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
"format": "fluid-build --task format .",
"format": "npm run format:biome",
"format:biome": "biome check . --formatter-enabled=true --apply",
"format:prettier": "prettier --write . --cache --ignore-path ../../../.prettierignore",

@@ -205,0 +206,0 @@ "lint": "fluid-build . --task lint",

@@ -8,5 +8,5 @@ /*!

import { assert } from "@fluidframework/core-utils/internal";
import { ISummaryTree } from "@fluidframework/driver-definitions";
import { IDocumentStorageService } from "@fluidframework/driver-definitions/internal";
import { CombinedAppAndProtocolSummary } from "@fluidframework/driver-utils/internal";
import { ISummaryTree } from "@fluidframework/protocol-definitions";

@@ -115,4 +115,7 @@ // eslint-disable-next-line import/no-deprecated

*/
// eslint-disable-next-line import/no-deprecated
readonly detachedBlobStorage?: Pick<IDetachedBlobStorage, "getBlobIds" | "readBlob" | "size">;
readonly detachedBlobStorage?: Pick<
// eslint-disable-next-line import/no-deprecated
IDetachedBlobStorage,
"getBlobIds" | "readBlob" | "size"
>;

@@ -164,3 +167,3 @@ /**

redirectTable: new Map<string, string>(),
}
}
: {

@@ -170,3 +173,3 @@ state: AttachState.Attaching,

blobs: "none",
};
};
setAttachmentData(currentData);

@@ -173,0 +176,0 @@ }

@@ -7,9 +7,6 @@ /*!

import { TypedEventEmitter } from "@fluid-internal/client-utils";
import {
IAudienceEvents,
IAudienceOwner,
ISelf,
} from "@fluidframework/container-definitions/internal";
import { IAudienceEvents, ISelf } from "@fluidframework/container-definitions";
import { IAudienceOwner } from "@fluidframework/container-definitions/internal";
import { assert } from "@fluidframework/core-utils/internal";
import { IClient } from "@fluidframework/protocol-definitions";
import { IClient } from "@fluidframework/driver-definitions";

@@ -35,3 +32,3 @@ /**

client: this.getMember(this._currentClientId),
};
};
}

@@ -38,0 +35,0 @@

@@ -9,3 +9,3 @@ /*!

import { assert } from "@fluidframework/core-utils/internal";
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";

@@ -26,3 +26,5 @@ /** @see CatchUpMonitor for usage */

private readonly opHandler = (message: Pick<ISequencedDocumentMessage, "sequenceNumber">) => {
private readonly opHandler = (
message: Pick<ISequencedDocumentMessage, "sequenceNumber">,
) => {
if (!this.caughtUp && message.sequenceNumber >= this.targetSeqNumber) {

@@ -29,0 +31,0 @@ this.caughtUp = true;

@@ -7,9 +7,11 @@ /*!

import { TypedEventEmitter, performance } from "@fluid-internal/client-utils";
import { ICriticalContainerError } from "@fluidframework/container-definitions";
import { IDeltaQueue, ReadOnlyInfo } from "@fluidframework/container-definitions/internal";
import {
ICriticalContainerError,
IDeltaQueue,
ReadOnlyInfo,
} from "@fluidframework/container-definitions/internal";
import { IDisposable, ITelemetryBaseProperties, LogLevel } from "@fluidframework/core-interfaces";
IDisposable,
ITelemetryBaseProperties,
LogLevel,
} from "@fluidframework/core-interfaces";
import { assert } from "@fluidframework/core-utils/internal";
import { ConnectionMode, IClient, IClientDetails } from "@fluidframework/driver-definitions";
import {

@@ -21,2 +23,13 @@ IDocumentDeltaConnection,

IAnyDriverError,
IClientConfiguration,
IDocumentMessage,
INack,
INackContent,
ISequencedDocumentSystemMessage,
ISignalClient,
ITokenClaims,
MessageType,
ScopeType,
ISequencedDocumentMessage,
ISignalMessage,
} from "@fluidframework/driver-definitions/internal";

@@ -33,18 +46,2 @@ import {

import {
ConnectionMode,
IClient,
IClientConfiguration,
IClientDetails,
IDocumentMessage,
INack,
INackContent,
ISequencedDocumentMessage,
ISequencedDocumentSystemMessage,
ISignalClient,
ISignalMessage,
ITokenClaims,
MessageType,
ScopeType,
} from "@fluidframework/protocol-definitions";
import {
ITelemetryLoggerExt,

@@ -314,3 +311,3 @@ GenericError,

sentOps: this.clientSequenceNumber,
};
};
}

@@ -745,3 +742,6 @@

*/
private triggerConnect(reason: IConnectionStateChangeReason, connectionMode: ConnectionMode) {
private triggerConnect(
reason: IConnectionStateChangeReason,
connectionMode: ConnectionMode,
) {
// reconnect() includes async awaits, and that causes potential race conditions

@@ -1194,3 +1194,6 @@ // where we might already have a connection. If it were to happen, it's possible that we will connect

private readonly opHandler = (documentId: string, messagesArg: ISequencedDocumentMessage[]) => {
private readonly opHandler = (
documentId: string,
messagesArg: ISequencedDocumentMessage[],
) => {
const messages = Array.isArray(messagesArg) ? messagesArg : [messagesArg];

@@ -1197,0 +1200,0 @@ this.props.incomingOpHandler(messages, "opHandler");

@@ -9,4 +9,4 @@ /*!

import { assert, Timer } from "@fluidframework/core-utils/internal";
import { IClient, ISequencedClient } from "@fluidframework/driver-definitions";
import { IAnyDriverError } from "@fluidframework/driver-definitions/internal";
import { IClient, ISequencedClient } from "@fluidframework/protocol-definitions";
import {

@@ -264,6 +264,3 @@ type TelemetryEventCategory,

// statement will overwrite current state).
assert(
this.catchUpMonitor === undefined,
0x3eb /* catchUpMonitor should be gone */,
);
assert(this.catchUpMonitor === undefined, 0x3eb /* catchUpMonitor should be gone */);
this.catchUpMonitor = new CatchUpMonitor(

@@ -657,5 +654,2 @@ this.deltaManager,

} else if (value === ConnectionState.Disconnected) {
// Clear pending state immediately to prepare for reconnect
this._pendingClientId = undefined;
if (this.joinTimer.hasTimer) {

@@ -689,4 +683,11 @@ this.stopjoinTimer();

// Report transition before we propagate event across layers
// Report transition
this.handler.connectionStateChanged(this._connectionState, oldState, reason);
// Clear pending state immediately to prepare for reconnect
// Do it after calling connectionStateChanged() above, such that our telemetry contains pendingClientId on disconnect events
// and we can pair attempts to connect with disconnects (that's the only ID we have if connection did not move far enough before being disconnected)
if (value === ConnectionState.Disconnected) {
this._pendingClientId = undefined;
}
}

@@ -738,3 +739,3 @@

!this.waitingForLeaveOp,
"leave timer can't be set as we have not had access to quorum",
0x99d /* leave timer can't be set as we have not had access to quorum */,
);

@@ -741,0 +742,0 @@

@@ -20,8 +20,7 @@ /*!

import { type ISignalEnvelope } from "@fluidframework/core-interfaces/internal";
import { IDocumentStorageService, ISnapshot } from "@fluidframework/driver-definitions/internal";
import { IClientDetails, IQuorumClients } from "@fluidframework/driver-definitions";
import {
IClientDetails,
IDocumentStorageService,
ISnapshot,
IDocumentMessage,
IQuorumClients,
ISequencedDocumentMessage,
ISnapshotTree,

@@ -31,3 +30,4 @@ ISummaryContent,

MessageType,
} from "@fluidframework/protocol-definitions";
ISequencedDocumentMessage,
} from "@fluidframework/driver-definitions/internal";
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";

@@ -34,0 +34,0 @@

@@ -10,2 +10,3 @@ /*!

import { assert } from "@fluidframework/core-utils/internal";
import { ISummaryHandle, ISummaryTree } from "@fluidframework/driver-definitions";
import {

@@ -19,11 +20,7 @@ FetchSource,

ISummaryContext,
} from "@fluidframework/driver-definitions/internal";
import { UsageError } from "@fluidframework/driver-utils/internal";
import {
ICreateBlobResponse,
ISnapshotTree,
ISummaryHandle,
ISummaryTree,
IVersion,
} from "@fluidframework/protocol-definitions";
} from "@fluidframework/driver-definitions/internal";
import { UsageError } from "@fluidframework/driver-utils/internal";
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";

@@ -54,3 +51,6 @@

export class ContainerStorageAdapter
implements ISerializedStateManagerDocumentStorageService, IDocumentStorageService, IDisposable
implements
ISerializedStateManagerDocumentStorageService,
IDocumentStorageService,
IDisposable
{

@@ -83,3 +83,3 @@ private _storageService: IDocumentStorageService & Partial<IDisposable>;

* upload, and fix it up with a protocol tree if needed
* @param forceEnableSummarizeProtocolTree - Enforce uploading a protocol summary regardless of the service's policy
* @param enableSummarizeProtocolTree - Enable uploading a protocol summary. Note: preference is given to service policy's "summarizeProtocolTree" before this value.
*/

@@ -96,6 +96,5 @@ public constructor(

private readonly addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree,
forceEnableSummarizeProtocolTree: boolean | undefined,
private readonly enableSummarizeProtocolTree: boolean | undefined,
) {
this._storageService = new BlobOnlyStorage(detachedBlobStorage, logger);
this._summarizeProtocolTree = forceEnableSummarizeProtocolTree;
}

@@ -120,11 +119,29 @@

this._summarizeProtocolTree =
this._summarizeProtocolTree ?? service.policies?.summarizeProtocolTree;
if (this.summarizeProtocolTree) {
this.logger.sendTelemetryEvent({ eventName: "summarizeProtocolTreeEnabled" });
this._storageService = new ProtocolTreeStorageService(
retriableStorage,
this.addProtocolSummaryIfMissing,
);
}
// A storage service wrapper which intercept calls to uploadSummaryWithContext and ensure they include
// the protocol summary, provided single-commit summary is enabled.
this._storageService = new ProtocolTreeStorageService(
retriableStorage,
(...props) => {
this.logger.sendTelemetryEvent({ eventName: "summarizeProtocolTreeEnabled" });
return this.addProtocolSummaryIfMissing(...props);
},
// A callback to ensure we fetch the most updated value of service.policies.summarizeProtocolTree, which could be set
// based on the response received from the service after connection is established.
() => {
// Determine whether or not container should upload the protocol summary along with the summary.
// This is determined based on what value is set for serve policy's summariProtocolTree value or the enableSummarizeProtocolTree
// retrievd from the loader options or monitoring context config.
const shouldSummarizeProtocolTree =
service.policies?.summarizeProtocolTree ?? this.enableSummarizeProtocolTree ?? false;
if (this._summarizeProtocolTree !== shouldSummarizeProtocolTree) {
this.logger.sendTelemetryEvent({
eventName: "isSummarizeProtocolTreeEnabled",
details: { value: shouldSummarizeProtocolTree },
});
}
this._summarizeProtocolTree = shouldSummarizeProtocolTree;
return this._summarizeProtocolTree;
},
);
}

@@ -165,5 +182,3 @@

const localSnapshot =
this.loadingGroupIdSnapshotsFromPendingState[
snapshotFetchOptions.loadingGroupIds[0]
];
this.loadingGroupIdSnapshotsFromPendingState[snapshotFetchOptions.loadingGroupIds[0]];
assert(localSnapshot !== undefined, 0x970 /* Local snapshot must be present */);

@@ -170,0 +185,0 @@ const attributes = await getDocumentAttributes(this, localSnapshot.baseSnapshot);

@@ -15,12 +15,11 @@ /*!

import { IErrorBase, ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
import { IContainerPackageInfo } from "@fluidframework/driver-definitions/internal";
import { ConnectionMode, IClientDetails } from "@fluidframework/driver-definitions";
import {
ConnectionMode,
IContainerPackageInfo,
IClientConfiguration,
IClientDetails,
IDocumentMessage,
ISignalClient,
ISequencedDocumentMessage,
ISignalClient,
ISignalMessage,
} from "@fluidframework/protocol-definitions";
} from "@fluidframework/driver-definitions/internal";

@@ -27,0 +26,0 @@ export enum ReconnectMode {

@@ -19,9 +19,8 @@ /*!

} from "@fluidframework/telemetry-utils/internal";
// This import style is necessary to ensure the emitted JS code works in both CJS and ESM.
import debugPkg from "debug";
import type { IDebugger } from "debug";
const { debug: registerDebug } = debugPkg;
import type { IDebugger } from "debug";
/**

@@ -28,0 +27,0 @@ * Implementation of debug logger

@@ -6,4 +6,4 @@ /*!

import { ICriticalContainerError } from "@fluidframework/container-definitions";
import {
ICriticalContainerError,
IDeltaManager,

@@ -20,2 +20,3 @@ IDeltaManagerEvents,

import { assert } from "@fluidframework/core-utils/internal";
import { ConnectionMode } from "@fluidframework/driver-definitions";
import {

@@ -25,2 +26,6 @@ IDocumentDeltaStorageService,

DriverErrorTypes,
IDocumentMessage,
MessageType,
ISequencedDocumentMessage,
ISignalMessage,
} from "@fluidframework/driver-definitions/internal";

@@ -33,9 +38,2 @@ import {

import {
ConnectionMode,
IDocumentMessage,
ISequencedDocumentMessage,
ISignalMessage,
MessageType,
} from "@fluidframework/protocol-definitions";
import {
type ITelemetryErrorEventExt,

@@ -77,3 +75,6 @@ type ITelemetryGenericEventExt,

(event: "closed" | "disposed", listener: (error?: ICriticalContainerError) => void);
(event: "connect", listener: (details: IConnectionDetailsInternal, opsBehind?: number) => void);
(
event: "connect",
listener: (details: IConnectionDetailsInternal, opsBehind?: number) => void,
);
(event: "establishingConnection", listener: (reason: IConnectionStateChangeReason) => void);

@@ -479,5 +480,3 @@ (

if (this.handler === undefined) {
throw new Error(
"Attempted to process an inbound signal without a handler attached",
);
throw new Error("Attempted to process an inbound signal without a handler attached");
}

@@ -1048,4 +1047,3 @@ this.handler.processSignal({

}
const clientSeqNumGap =
message.clientSequenceNumber - this.lastClientSequenceNumber - 1;
const clientSeqNumGap = message.clientSequenceNumber - this.lastClientSequenceNumber - 1;
this.noOpCount -= clientSeqNumGap;

@@ -1154,6 +1152,3 @@ if (this.noOpCount < 0) {

// very old cached (by client / driver) snapshot.
assert(
n === this.lastQueuedSequenceNumber,
0x0f2 /* "previouslyProcessedMessage" */,
);
assert(n === this.lastQueuedSequenceNumber, 0x0f2 /* "previouslyProcessedMessage" */);
assert(from > 1, 0x0f3 /* "not positive" */);

@@ -1160,0 +1155,0 @@ from--;

@@ -7,3 +7,6 @@ /*!

import { TypedEventEmitter, performance } from "@fluid-internal/client-utils";
import { IDeltaQueue, IDeltaQueueEvents } from "@fluidframework/container-definitions/internal";
import {
IDeltaQueue,
IDeltaQueueEvents,
} from "@fluidframework/container-definitions/internal";
import { assert } from "@fluidframework/core-utils/internal";

@@ -10,0 +13,0 @@ import Deque from "double-ended-queue";

@@ -19,3 +19,6 @@ /*!

*/
export class ThrottlingWarning extends LoggingError implements IThrottlingWarning, IFluidErrorBase {
export class ThrottlingWarning
extends LoggingError
implements IThrottlingWarning, IFluidErrorBase
{
/**

@@ -22,0 +25,0 @@ * {@inheritDoc @fluidframework/telemetry-utils#IFluidErrorBase.errorType}

@@ -24,1 +24,8 @@ /*!

export { tryParseCompatibleResolvedUrl, IParsedUrl } from "./utils.js";
export {
IBaseProtocolHandler,
IScribeProtocolState,
IQuorumSnapshot,
QuorumClientsSnapshot,
QuorumProposalsSnapshot,
} from "./protocol/index.js";

@@ -22,2 +22,3 @@ /*!

} from "@fluidframework/core-interfaces";
import { IClientDetails } from "@fluidframework/driver-definitions";
import {

@@ -29,3 +30,2 @@ IDocumentServiceFactory,

} from "@fluidframework/driver-definitions/internal";
import { IClientDetails } from "@fluidframework/protocol-definitions";
import {

@@ -32,0 +32,0 @@ ITelemetryLoggerExt,

@@ -8,4 +8,4 @@ /*!

import { IRequest } from "@fluidframework/core-interfaces";
import type { IErrorBase } from "@fluidframework/core-interfaces";
import { GenericError } from "@fluidframework/telemetry-utils/internal";
import type { IErrorBase } from "@fluidframework/core-interfaces";

@@ -12,0 +12,0 @@ /* eslint-disable jsdoc/check-indentation */

@@ -6,5 +6,6 @@ /*!

import type { ICreateBlobResponse } from "@fluidframework/protocol-definitions";
import { bufferToString, stringToBuffer } from "@fluid-internal/client-utils";
import { assert, isObject } from "@fluidframework/core-utils/internal";
import type { ICreateBlobResponse } from "@fluidframework/driver-definitions/internal";
// eslint-disable-next-line import/no-deprecated

@@ -29,3 +30,4 @@ import type { IDetachedBlobStorage } from "./loader.js";

MemoryDetachedBlobStorageIdentifier in detachedStorage &&
detachedStorage[MemoryDetachedBlobStorageIdentifier] === MemoryDetachedBlobStorageIdentifier
detachedStorage[MemoryDetachedBlobStorageIdentifier] ===
MemoryDetachedBlobStorageIdentifier
);

@@ -54,5 +56,5 @@ }

assert(detachedStorage.size === 0, "Blob storage already initialized");
assert(detachedStorage.size === 0, 0x99e /* Blob storage already initialized */);
const maybeAttachmentBlobs = JSON.parse(attachmentBlobs);
assert(Array.isArray(maybeAttachmentBlobs), "Invalid attachmentBlobs");
assert(Array.isArray(maybeAttachmentBlobs), 0x99f /* Invalid attachmentBlobs */);

@@ -59,0 +61,0 @@ detachedStorage.initialize(maybeAttachmentBlobs);

@@ -9,4 +9,4 @@ /*!

import { assert, Timer } from "@fluidframework/core-utils/internal";
import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
import { isRuntimeMessage } from "@fluidframework/driver-utils/internal";
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";

@@ -13,0 +13,0 @@ const defaultNoopTimeFrequency = 2000;

@@ -9,2 +9,2 @@ /*!

export const pkgName = "@fluidframework/container-loader";
export const pkgVersion = "2.0.0-rc.4.0.6";
export const pkgVersion = "2.0.0-rc.5.0.0";

@@ -7,17 +7,14 @@ /*!

import { IAudienceOwner } from "@fluidframework/container-definitions/internal";
import { canBeCoalescedByService } from "@fluidframework/driver-utils/internal";
import {
IProtocolHandler as IBaseProtocolHandler,
IQuorumSnapshot,
ProtocolOpHandler,
} from "@fluidframework/protocol-base";
import {
IDocumentAttributes,
IProcessMessageResult,
ISignalClient,
MessageType,
ISequencedDocumentMessage,
ISignalClient,
ISignalMessage,
MessageType,
} from "@fluidframework/protocol-definitions";
} from "@fluidframework/driver-definitions/internal";
import { canBeCoalescedByService } from "@fluidframework/driver-utils/internal";
import { IBaseProtocolHandler, IQuorumSnapshot, ProtocolOpHandler } from "./protocol/index.js";
// ADO: #1986: Start using enum from protocol-base.

@@ -24,0 +21,0 @@ export enum SignalType {

@@ -7,2 +7,3 @@ /*!

import { IDisposable } from "@fluidframework/core-interfaces";
import { ISummaryTree } from "@fluidframework/driver-definitions";
import {

@@ -12,3 +13,2 @@ IDocumentStorageService,

} from "@fluidframework/driver-definitions/internal";
import { ISummaryTree } from "@fluidframework/protocol-definitions";

@@ -20,6 +20,21 @@ /**

export class ProtocolTreeStorageService implements IDocumentStorageService, IDisposable {
/**
*
* @param internalStorageService - Document storage service responsible to make api calls to the storage.
* @param addProtocolSummaryIfMissing - Function to add protocol summary tree to the summary. Used in scenarios where single-commit summaries are used.
* @param shouldSummarizeProtocolTree - Callback function to learn about the service preference on whether single-commit summaries are enabled.
*/
constructor(
private readonly internalStorageService: IDocumentStorageService & IDisposable,
private readonly addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree,
) {}
private readonly shouldSummarizeProtocolTree: () => boolean,
) {
this.getSnapshotTree = internalStorageService.getSnapshotTree.bind(internalStorageService);
this.getSnapshot = internalStorageService.getSnapshot?.bind(internalStorageService);
this.getVersions = internalStorageService.getVersions.bind(internalStorageService);
this.createBlob = internalStorageService.createBlob.bind(internalStorageService);
this.readBlob = internalStorageService.readBlob.bind(internalStorageService);
this.downloadSummary = internalStorageService.downloadSummary.bind(internalStorageService);
this.dispose = internalStorageService.dispose.bind(internalStorageService);
}
public get policies() {

@@ -32,9 +47,9 @@ return this.internalStorageService.policies;

getSnapshotTree = this.internalStorageService.getSnapshotTree.bind(this.internalStorageService);
getSnapshot = this.internalStorageService.getSnapshot?.bind(this.internalStorageService);
getVersions = this.internalStorageService.getVersions.bind(this.internalStorageService);
createBlob = this.internalStorageService.createBlob.bind(this.internalStorageService);
readBlob = this.internalStorageService.readBlob.bind(this.internalStorageService);
downloadSummary = this.internalStorageService.downloadSummary.bind(this.internalStorageService);
dispose = this.internalStorageService.dispose.bind(this.internalStorageService);
getSnapshotTree: IDocumentStorageService["getSnapshotTree"];
getSnapshot: IDocumentStorageService["getSnapshot"];
getVersions: IDocumentStorageService["getVersions"];
createBlob: IDocumentStorageService["createBlob"];
readBlob: IDocumentStorageService["readBlob"];
downloadSummary: IDocumentStorageService["downloadSummary"];
dispose: IDisposable["dispose"];

@@ -45,7 +60,9 @@ async uploadSummaryWithContext(

): Promise<string> {
return this.internalStorageService.uploadSummaryWithContext(
this.addProtocolSummaryIfMissing(summary),
context,
);
return this.shouldSummarizeProtocolTree()
? this.internalStorageService.uploadSummaryWithContext(
this.addProtocolSummaryIfMissing(summary),
context,
)
: this.internalStorageService.uploadSummaryWithContext(summary, context);
}
}

@@ -7,3 +7,3 @@ /*!

import { IFluidCodeDetails } from "@fluidframework/container-definitions/internal";
import { ICommittedProposal } from "@fluidframework/protocol-definitions";
import { ICommittedProposal } from "@fluidframework/driver-definitions/internal";

@@ -10,0 +10,0 @@ export function initQuorumValuesFromCodeDetails(

@@ -8,2 +8,3 @@ /*!

import { assert } from "@fluidframework/core-utils/internal";
import { ISummaryHandle, ISummaryTree } from "@fluidframework/driver-definitions";
import {

@@ -16,11 +17,7 @@ FetchSource,

ISummaryContext,
} from "@fluidframework/driver-definitions/internal";
import { runWithRetry } from "@fluidframework/driver-utils/internal";
import {
ICreateBlobResponse,
ISnapshotTree,
ISummaryHandle,
ISummaryTree,
IVersion,
} from "@fluidframework/protocol-definitions";
} from "@fluidframework/driver-definitions/internal";
import { runWithRetry } from "@fluidframework/driver-utils/internal";
import {

@@ -39,3 +36,5 @@ ITelemetryLoggerExt,

) {
this.internalStorageServiceP.then((s) => (this.internalStorageService = s)).catch(() => {});
this.internalStorageServiceP
.then((s) => (this.internalStorageService = s))
.catch(() => {});
}

@@ -42,0 +41,0 @@

@@ -6,2 +6,3 @@ /*!

import { stringToBuffer } from "@fluid-internal/client-utils";
import {

@@ -11,3 +12,7 @@ IGetPendingLocalStateProps,

} from "@fluidframework/container-definitions/internal";
import { stringToBuffer } from "@fluid-internal/client-utils";
import type {
IEventProvider,
IEvent,
ITelemetryBaseLogger,
} from "@fluidframework/core-interfaces";
import { assert } from "@fluidframework/core-utils/internal";

@@ -19,10 +24,8 @@ import {

ISnapshot,
} from "@fluidframework/driver-definitions/internal";
import { getSnapshotTree } from "@fluidframework/driver-utils/internal";
import {
type IDocumentAttributes,
ISequencedDocumentMessage,
ISnapshotTree,
IVersion,
} from "@fluidframework/protocol-definitions";
ISequencedDocumentMessage,
} from "@fluidframework/driver-definitions/internal";
import { getSnapshotTree } from "@fluidframework/driver-utils/internal";
import {

@@ -34,4 +37,7 @@ MonitoringContext,

} from "@fluidframework/telemetry-utils/internal";
import type { ITelemetryBaseLogger, IEventProvider, IEvent } from "@fluidframework/core-interfaces";
import { ISerializableBlobContents, getBlobContentsFromTree } from "./containerStorageAdapter.js";
import {
ISerializableBlobContents,
getBlobContentsFromTree,
} from "./containerStorageAdapter.js";
import { convertSnapshotToSnapshotInfo, getDocumentAttributes } from "./utils.js";

@@ -155,2 +161,3 @@

private readonly containerDirty: () => boolean,
private readonly supportGetSnapshotApi: () => boolean,
) {

@@ -162,2 +169,5 @@ this.mc = createChildMonitoringContext({

// special case handle. Obtaining the last saved op seq num to avoid
// refreshing the snapshot before we have processed it. It could cause
// a subsequent stashing to have a newer snapshot than allowed.
if (pendingLocalState && pendingLocalState.savedOps.length > 0) {

@@ -202,6 +212,3 @@ const savedOpsSize = pendingLocalState.savedOps.length;

*/
public async fetchSnapshot(
specifiedVersion: string | undefined,
supportGetSnapshotApi: boolean,
) {
public async fetchSnapshot(specifiedVersion: string | undefined) {
if (this.pendingLocalState === undefined) {

@@ -211,3 +218,3 @@ const { baseSnapshot, version } = await getSnapshot(

this.storageAdapter,
supportGetSnapshotApi,
this.supportGetSnapshotApi(),
specifiedVersion,

@@ -222,6 +229,3 @@ );

);
const attributes = await getDocumentAttributes(
this.storageAdapter,
baseSnapshotTree,
);
const attributes = await getDocumentAttributes(this.storageAdapter, baseSnapshotTree);
this.snapshot = {

@@ -248,3 +252,3 @@ baseSnapshot: baseSnapshotTree,

// Don't block on the refresh snapshot call - it is for the next time we serialize, not booting this incarnation
this.refreshSnapshotP = this.refreshLatestSnapshot(supportGetSnapshotApi);
this.refreshSnapshotP = this.refreshLatestSnapshot(this.supportGetSnapshotApi());
this.refreshSnapshotP.catch((e) => {

@@ -343,6 +347,3 @@ this.mc.logger.sendErrorEvent({

// Remove the ops that are already part of the snapshot
this.processedOps.splice(
0,
snapshotSequenceNumber - firstProcessedOpSequenceNumber + 1,
);
this.processedOps.splice(0, snapshotSequenceNumber - firstProcessedOpSequenceNumber + 1);
this.snapshot = this.latestSnapshot;

@@ -355,5 +356,3 @@ this.latestSnapshot = undefined;

newFirstProcessedOpSequenceNumber:
this.processedOps.length === 0
? undefined
: this.processedOps[0].sequenceNumber,
this.processedOps.length === 0 ? undefined : this.processedOps[0].sequenceNumber,
});

@@ -404,4 +403,8 @@ }

eventName: "getPendingLocalState",
notifyImminentClosure: props.notifyImminentClosure,
processedOpsSize: this.processedOps.length,
details: {
notifyImminentClosure: props.notifyImminentClosure,
sessionExpiryTimerStarted: props.sessionExpiryTimerStarted,
snapshotSequenceNumber: props.snapshotSequenceNumber,
processedOpsSize: this.processedOps.length,
},
clientId,

@@ -411,5 +414,3 @@ },

if (!this.offlineLoadEnabled) {
throw new UsageError(
"Can't get pending local state unless offline load is enabled",
);
throw new UsageError("Can't get pending local state unless offline load is enabled");
}

@@ -437,5 +438,3 @@ assert(this.snapshot !== undefined, 0x8e5 /* no base data */);

snapshotBlobs: this.snapshot.snapshotBlobs,
loadedGroupIdSnapshots: hasGroupIdSnapshots
? loadedGroupIdSnapshots
: undefined,
loadedGroupIdSnapshots: hasGroupIdSnapshots ? loadedGroupIdSnapshots : undefined,
savedOps: this.processedOps,

@@ -539,3 +538,3 @@ url: resolvedUrl.url,

treeId: snapshot.snapshotTree.id,
};
};

@@ -542,0 +541,0 @@ if (snapshot === undefined && specifiedVersion !== undefined) {

@@ -6,6 +6,15 @@ /*!

import { Uint8ArrayToString, bufferToString, stringToBuffer } from "@fluid-internal/client-utils";
import {
Uint8ArrayToString,
bufferToString,
stringToBuffer,
} from "@fluid-internal/client-utils";
import { assert, compareArrays, unreachableCase } from "@fluidframework/core-utils/internal";
import { DriverErrorTypes } from "@fluidframework/driver-definitions/internal";
import { ISummaryTree, SummaryType } from "@fluidframework/driver-definitions";
import {
DriverErrorTypes,
IDocumentAttributes,
ISnapshotTree,
} from "@fluidframework/driver-definitions/internal";
import {
IDocumentStorageService,

@@ -20,8 +29,2 @@ type ISnapshot,

} from "@fluidframework/driver-utils/internal";
import {
IDocumentAttributes,
ISnapshotTree,
ISummaryTree,
SummaryType,
} from "@fluidframework/protocol-definitions";
import { LoggingError, UsageError } from "@fluidframework/telemetry-utils/internal";

@@ -95,3 +98,3 @@ import { v4 as uuid } from "uuid";

version: parsed.searchParams.get("version") ?? undefined,
}
}
: undefined;

@@ -187,3 +190,6 @@ }

export function convertSnapshotToSnapshotInfo(snapshot: ISnapshot): ISnapshotInfo {
assert(snapshot.sequenceNumber !== undefined, 0x93a /* Snapshot sequence number is missing */);
assert(
snapshot.sequenceNumber !== undefined,
0x93a /* Snapshot sequence number is missing */,
);
const snapshotBlobs: ISerializableBlobContents = {};

@@ -190,0 +196,0 @@ for (const [blobId, arrayBufferLike] of snapshot.blobContents.entries()) {

@@ -8,3 +8,5 @@ {

"outDir": "./lib",
"noUncheckedIndexedAccess": false,
"exactOptionalPropertyTypes": false,
},
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc