or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

container-runtime-factories.mddata-object-factories.mddata-objects.mdindex.md
tile.json

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>;