or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdcontainer-lifecycle.mdindex.mdprotocol-quorum.mdutilities.md
tile.json

container-lifecycle.mddocs/

Container Lifecycle

The container lifecycle management functionality provides comprehensive APIs for creating, loading, and managing Fluid containers throughout their operational lifecycle.

Core Container Management

Loader Class

The main Loader class provides the primary interface for container operations.

class Loader implements IHostLoader {
  constructor(loaderProps: ILoaderProps);
  
  createDetachedContainer(
    codeDetails: IFluidCodeDetails, 
    createDetachedProps?: {
      canReconnect?: boolean;
      clientDetailsOverride?: IClientDetails;
    }
  ): Promise<IContainer>;
  
  rehydrateDetachedContainerFromSnapshot(
    snapshot: string, 
    createDetachedProps?: {
      canReconnect?: boolean;
      clientDetailsOverride?: IClientDetails;
    }
  ): Promise<IContainer>;
  
  resolve(request: IRequest, pendingLocalState?: string): Promise<IContainer>;
  
  readonly services: ILoaderServices;
}

Usage Example

import { Loader } from "@fluidframework/container-loader";
import type { ILoaderProps, IFluidCodeDetails } from "@fluidframework/container-loader";

// Create loader with required services
const loaderProps: ILoaderProps = {
  codeLoader: myCodeLoader,
  documentServiceFactory: myDocumentServiceFactory,
  urlResolver: myUrlResolver,
  configProvider: myConfigProvider,
  logger: myLogger
};

const loader = new Loader(loaderProps);

// Create a new detached container
const codeDetails: IFluidCodeDetails = {
  package: "my-fluid-package",
  config: {}
};

const detachedContainer = await loader.createDetachedContainer(codeDetails, {
  canReconnect: true,
  clientDetailsOverride: { capabilities: { interactive: true } }
});

// Load an existing container
const existingContainer = await loader.resolve({
  url: "https://myfluidservice.com/tenants/my-tenant/documents/my-doc"
});

Utility Functions

Container Creation Functions

These utility functions provide simplified APIs for common container operations.

function createDetachedContainer(
  createDetachedContainerProps: ICreateDetachedContainerProps
): Promise<IContainer>;

function loadExistingContainer(
  loadExistingContainerProps: ILoadExistingContainerProps
): Promise<IContainer>;

function rehydrateDetachedContainer(
  rehydrateDetachedContainerProps: IRehydrateDetachedContainerProps
): Promise<IContainer>;

function loadContainerPaused(
  loaderProps: ILoaderProps,
  request: IRequest,
  loadToSequenceNumber?: number,
  signal?: AbortSignal,
): Promise<IContainer>;

Usage Examples

import { 
  createDetachedContainer, 
  loadExistingContainer, 
  rehydrateDetachedContainer 
} from "@fluidframework/container-loader";
import type { 
  ICreateDetachedContainerProps,
  ILoadExistingContainerProps,
  IRehydrateDetachedContainerProps 
} from "@fluidframework/container-loader";

// Create detached container using utility function
const createProps: ICreateDetachedContainerProps = {
  codeDetails: { package: "my-package", config: {} },
  codeLoader: myCodeLoader,
  documentServiceFactory: myDocumentServiceFactory,
  urlResolver: myUrlResolver,
  allowReconnect: true
};

const newContainer = await createDetachedContainer(createProps);

// Load existing container using utility function
const loadProps: ILoadExistingContainerProps = {
  request: { url: "https://myfluidservice.com/documents/my-doc" },
  codeLoader: myCodeLoader,
  documentServiceFactory: myDocumentServiceFactory,
  urlResolver: myUrlResolver,
  pendingLocalState: serializedState
};

const loadedContainer = await loadExistingContainer(loadProps);

// Rehydrate container from serialized state
const rehydrateProps: IRehydrateDetachedContainerProps = {
  serializedState: snapshotString,
  codeLoader: myCodeLoader,
  documentServiceFactory: myDocumentServiceFactory,
  urlResolver: myUrlResolver
};

const rehydratedContainer = await rehydrateDetachedContainer(rehydrateProps);

Container State Management

function waitContainerToCatchUp(container: IContainer): Promise<boolean>;

This function waits for a container to finish catching up with the latest state from the service.

import { waitContainerToCatchUp } from "@fluidframework/container-loader";

// Wait for container to catch up after reconnection
const success = await waitContainerToCatchUp(container);
if (success) {
  console.log("Container is now up to date");
} else {
  console.log("Container failed to catch up");
}

Container Creation Interfaces

Base Configuration Interface

interface ICreateAndLoadContainerProps {
  readonly allowReconnect?: boolean | undefined;
  readonly clientDetailsOverride?: IClientDetails | undefined;
  readonly codeLoader: ICodeDetailsLoader;
  readonly configProvider?: IConfigProviderBase | undefined;
  readonly documentServiceFactory: IDocumentServiceFactory;
  readonly logger?: ITelemetryBaseLogger | undefined;
  readonly options?: IContainerPolicies | undefined;
  readonly protocolHandlerBuilder?: ProtocolHandlerBuilder | undefined;
  readonly scope?: FluidObject | undefined;
  readonly urlResolver: IUrlResolver;
}

Specific Operation Interfaces

interface ICreateDetachedContainerProps extends ICreateAndLoadContainerProps {
  readonly codeDetails: IFluidCodeDetails;
}

interface ILoadExistingContainerProps extends ICreateAndLoadContainerProps {
  readonly pendingLocalState?: string | undefined;
  readonly request: IRequest;
}

interface IRehydrateDetachedContainerProps extends ICreateAndLoadContainerProps {
  readonly serializedState: string;
}

Deprecated Code Loading Interfaces

Note: These interfaces are deprecated and maintained for backward compatibility only.

interface ICodeDetailsLoader extends Partial<IProvideFluidCodeDetailsComparer> {
  load(source: IFluidCodeDetails): Promise<IFluidModuleWithDetails>;
}

interface IFluidModuleWithDetails {
  details: IFluidCodeDetails;
  module: IFluidModule;
}

Container Lifecycle Patterns

Creating and Attaching Containers

// Create detached container
const detachedContainer = await createDetachedContainer({
  codeDetails: myCodeDetails,
  codeLoader: myCodeLoader,
  documentServiceFactory: myDocumentServiceFactory,
  urlResolver: myUrlResolver
});

// Work with detached container
const myDataObject = await detachedContainer.getEntryPoint();
await myDataObject.initialize();

// Attach to service when ready
await detachedContainer.attach(attachRequest);

Loading and Reconnection

// Load container with reconnection support
const container = await loadExistingContainer({
  request: myRequest,
  codeLoader: myCodeLoader,
  documentServiceFactory: myDocumentServiceFactory,
  urlResolver: myUrlResolver,
  allowReconnect: true
});

// Monitor connection state
container.on("connected", () => {
  console.log("Container connected");
});

container.on("disconnected", () => {
  console.log("Container disconnected, will attempt reconnection");
});

// Wait for container to catch up after reconnection
container.on("connected", async () => {
  const success = await waitContainerToCatchUp(container);
  if (success) {
    console.log("Container fully synchronized");
  }
});

Serialization and Rehydration

// Serialize container state for offline storage
const snapshot = detachedContainer.serialize();
await localStorage.setItem("containerSnapshot", snapshot);

// Later, rehydrate from stored state
const storedSnapshot = await localStorage.getItem("containerSnapshot");
if (storedSnapshot) {
  const rehydratedContainer = await rehydrateDetachedContainer({
    serializedState: storedSnapshot,
    codeLoader: myCodeLoader,
    documentServiceFactory: myDocumentServiceFactory,
    urlResolver: myUrlResolver
  });
}