CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-fluidframework--aqueduct

A library for building Fluid objects and Fluid containers within the Fluid Framework, providing base classes and factory patterns for collaborative data objects.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

data-objects.mddocs/

Data Objects

Core base classes for creating Fluid objects with different levels of built-in functionality. These abstract classes provide the foundation for building collaborative data objects with lifecycle management, provider integration, and varying degrees of built-in shared data structure support.

Capabilities

PureDataObject

The most basic data object base class providing essential functionality for Fluid object creation and lifecycle management.

/**
 * Bare-bones base class providing basic setup and factory initialization functionality.
 * Most developers should use DataObject instead unless creating another base data store class.
 * @typeParam I - The optional input types used to strongly type the data object
 */
abstract class PureDataObject<I extends DataObjectTypes = DataObjectTypes>
  extends TypedEventEmitter<I["Events"] & IEvent>
  implements IFluidLoadable, IProvideFluidHandle

Key Properties:

/** FluidDataStoreRuntime object for managing the data object */
protected readonly runtime: IFluidDataStoreRuntime;

/** Context for communicating with the IContainerRuntime */
protected readonly context: IFluidDataStoreContext;

/** FluidObject keyed providers for dependency injection */
protected readonly providers: AsyncFluidObjectProvider<I["OptionalProviders"]>;

/** Optional initial properties passed during creation */
protected initProps?: I["InitialState"];

/** Data store identifier */
public get id(): string;

/** IFluidLoadable implementation */
public get IFluidLoadable(): this;

/** IFluidHandle implementation */
public get IFluidHandle(): IFluidHandleInternal<this>;

/** Handle to the data store */
public get handle(): IFluidHandleInternal<this>;

Core Methods:

/** 
 * Ensure PureDataObject is fully initialized. Called automatically by factory.
 * @param existing - Whether this is loading from an existing data store
 */
public async finishInitialization(existing: boolean): Promise<void>;

/**
 * Handle requests to the data object. Returns this object for "/" and "" URLs.
 * @param req - The request to handle
 */
public async request(req: IRequest): Promise<IResponse>;

/**
 * Static factory method for getting data object from runtime
 * @param runtime - The FluidDataStoreRuntime
 */
public static async getDataObject(runtime: IFluidDataStoreRuntime): Promise<PureDataObject>;

Lifecycle Methods:

/** Called every time before initialization */
protected async preInitialize(): Promise<void>;

/**
 * Called only the first time a data object is initialized
 * @param props - Optional props passed during creation
 */
protected async initializingFirstTime(props?: I["InitialState"]): Promise<void>;

/** Called every time except the first time a data object is initialized */
protected async initializingFromExisting(): Promise<void>;

/** Called every time after initialization is complete */
protected async hasInitialized(): Promise<void>;

/** Internal initialization implementation - should not be overridden */
public async initializeInternal(existing: boolean): Promise<void>;

Usage Example:

class MyPureDataObject extends PureDataObject {
  protected async initializingFirstTime() {
    // Initialize any data structures or state for new instances
  }

  protected async initializingFromExisting() {
    // Load existing data structures or state
  }

  protected async hasInitialized() {
    // Perform final setup after initialization
  }
}

DataObject

Enhanced data object base class that extends PureDataObject with a built-in root SharedDirectory for easier data structure management.

/**
 * DataObject extends PureDataObject with a root directory for easier development.
 * Having a single root directory allows for easier development by automatically
 * registering any new DDS set on the root.
 * @typeParam I - The optional input types used to strongly type the data object
 */
abstract class DataObject<I extends DataObjectTypes = DataObjectTypes> extends PureDataObject<I>

Additional Properties:

/** 
 * The root SharedDirectory for storing handles to other data structures.
 * Automatically created and ready for use.
 */
protected get root(): ISharedDirectory;

Additional Methods:

/**
 * Override of initializeInternal that sets up the root directory
 * @param existing - Whether loading from existing data store
 */
public override async initializeInternal(existing: boolean): Promise<void>;

/**
 * Generates error messages for uninitialized items
 * @param item - Name of the uninitialized item
 */
protected getUninitializedErrorString(item: string): string;

Usage Example:

class ClickerDataObject extends DataObject {
  private _counter: SharedCounter | undefined;

  protected async initializingFirstTime() {
    // Create and store a SharedCounter in the root directory
    const counter = SharedCounter.create(this.runtime);
    this.root.set("clicks", counter.handle);
  }

  protected async hasInitialized() {
    // Retrieve the SharedCounter from the root directory
    const counterHandle = this.root.get<IFluidHandle<SharedCounter>>("clicks");
    this._counter = await counterHandle.get();
  }

  public get counter() {
    if (this._counter === undefined) {
      throw new Error(this.getUninitializedErrorString("counter"));
    }
    return this._counter;
  }
}

TreeDataObject

Advanced data object base class backed by a SharedTree for managing hierarchical, tree-structured collaborative data.

/**
 * A data object backed by a SharedTree for hierarchical data structures.
 * Implementers must apply appropriate view schemas to access tree data.
 * @typeParam TDataObjectTypes - The optional input types used to strongly type the data object
 */
abstract class TreeDataObject<TDataObjectTypes extends DataObjectTypes = DataObjectTypes>
  extends PureDataObject<TDataObjectTypes>

Key Properties:

/** 
 * The underlying SharedTree instance. Created once during initialization.
 * Access requires proper view schema application.
 */
protected get tree(): ITree;

Core Methods:

/**
 * Override of initializeInternal that sets up the SharedTree
 * @param existing - Whether loading from existing data store
 */
public override async initializeInternal(existing: boolean): Promise<void>;

Usage Example:

class DocumentDataObject extends TreeDataObject {
  private treeView: TreeViewWithEvents<typeof DocumentSchema> | undefined;

  protected override async initializingFirstTime(): Promise<void> {
    // Generate the schema-aware view of the tree for new documents
    this.treeView = this.tree.viewWith(DocumentSchema);
    
    // Initialize the tree with initial data
    this.treeView.initialize({
      title: "New Document",
      content: "",
      sections: []
    });
  }

  protected override async initializingFromExisting(): Promise<void> {
    // Generate the schema-aware view for existing documents
    this.treeView = this.tree.viewWith(DocumentSchema);
    
    // Ensure the loaded tree is compatible with the view schema
    if (!this.treeView.compatibility.canView) {
      throw new Error("Document schema is incompatible");
    }
  }

  public get document() {
    if (this.treeView === undefined) {
      throw new Error("Tree view not initialized");
    }
    return this.treeView.root;
  }
}

Supporting Types

DataObjectTypes

/**
 * Base generic input type for DataObject and PureDataObject configuration
 */
interface DataObjectTypes {
  /** Optional providers that will be injected via dependency injection */
  OptionalProviders?: FluidObject;
  /** Initial state type that the data object may receive during creation */
  InitialState?: any;
  /** Events that will be available in the EventForwarder */
  Events?: IEvent;
}

IDataObjectProps

/**
 * Construction properties passed to data object constructors
 */
interface IDataObjectProps<I extends DataObjectTypes = DataObjectTypes> {
  /** The FluidDataStoreRuntime for this data object */
  readonly runtime: IFluidDataStoreRuntime;
  /** The FluidDataStoreContext for container communication */
  readonly context: IFluidDataStoreContext;
  /** Resolved providers based on factory configuration */
  readonly providers: AsyncFluidObjectProvider<I["OptionalProviders"]>;
  /** Optional initial state passed during creation */
  readonly initProps?: I["InitialState"];
}

DataObjectKind

/**
 * Type representing an object that has a factory capable of creating data objects.
 * Used for strong typing in advanced scenarios.
 */
type DataObjectKind<T = unknown> = {
  readonly factory: IFluidDataStoreFactory;
} & (
  | {
      readonly makeCovariant?: T | undefined;
    }
  | (new (...args: never[]) => T)
);

createDataObjectKind

/**
 * Utility function for creating SharedObjectKind instances for data objects.
 * Used in advanced scenarios requiring SharedObjectKind compatibility.
 * @typeParam T - The kind of data object
 * @param factory - The data object factory
 * @returns Enhanced factory with SharedObjectKind capabilities
 */
function createDataObjectKind<T extends DataObjectKind>(
  factory: T
): T & SharedObjectKind<T extends DataObjectKind<infer I> ? I : unknown>;

docs

container-runtime-factories.md

data-object-factories.md

data-objects.md

index.md

tile.json