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

index.mddocs/

@fluidframework/aqueduct

@fluidframework/aqueduct is the foundational library for building Fluid objects and Fluid containers within the Fluid Framework. It provides base classes, factory patterns, and container runtime utilities that enable developers to quickly create collaborative, real-time applications. The library serves as a thin abstraction layer over core Fluid Framework interfaces, offering three tiers of data objects and corresponding factories for different architectural needs.

Package Information

  • Package Name: @fluidframework/aqueduct
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @fluidframework/aqueduct

Core Imports

import { 
  DataObject, 
  PureDataObject, 
  TreeDataObject,
  DataObjectFactory,
  PureDataObjectFactory,
  TreeDataObjectFactory,
  ContainerRuntimeFactoryWithDefaultDataStore
} from "@fluidframework/aqueduct";

For CommonJS:

const { 
  DataObject, 
  PureDataObject, 
  DataObjectFactory,
  ContainerRuntimeFactoryWithDefaultDataStore 
} = require("@fluidframework/aqueduct");

Basic Usage

import { DataObject, DataObjectFactory, ContainerRuntimeFactoryWithDefaultDataStore } from "@fluidframework/aqueduct";
import { SharedCounter } from "@fluidframework/counter";
import type { IFluidHandle } from "@fluidframework/core-interfaces";

// 1. Create a data object by extending DataObject
class ClickerDataObject extends DataObject {
  private _counter: SharedCounter | undefined;

  protected async initializingFirstTime() {
    const counter = SharedCounter.create(this.runtime);
    this.root.set("clicks", counter.handle);
  }

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

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

// 2. Create a factory for the data object
const ClickerFactory = new DataObjectFactory({
  type: "clicker",
  ctor: ClickerDataObject,
  sharedObjects: [SharedCounter.getFactory()],
});

// 3. Create a container runtime factory
export const fluidExport = new ContainerRuntimeFactoryWithDefaultDataStore({
  defaultFactory: ClickerFactory,
  registryEntries: [ClickerFactory.registryEntry],
});

Architecture

@fluidframework/aqueduct is built around several key architectural patterns:

  • Data Object Hierarchy: Three-tier inheritance model providing different levels of functionality and complexity
  • Factory Pattern: Dedicated factory classes for instantiating and managing data objects and containers
  • Runtime Management: Container runtime factories that bootstrap and manage Fluid container lifecycles
  • Provider System: Dependency injection mechanism for optional services and functionality
  • Lifecycle Management: Structured initialization patterns for both new and existing data objects

Capabilities

Data Objects

Core base classes for creating Fluid objects with different levels of built-in functionality, from minimal to full-featured with shared data structures.

abstract class PureDataObject<I extends DataObjectTypes = DataObjectTypes>
abstract class DataObject<I extends DataObjectTypes = DataObjectTypes> extends PureDataObject<I>
abstract class TreeDataObject<TDataObjectTypes extends DataObjectTypes = DataObjectTypes> extends PureDataObject<TDataObjectTypes>

Data Objects

Data Object Factories

Factory classes for instantiating, managing, and creating data objects with proper runtime configuration and shared object registration.

class PureDataObjectFactory<TObj extends PureDataObject<I>, I extends DataObjectTypes = DataObjectTypes>
class DataObjectFactory<TObj extends DataObject<I>, I extends DataObjectTypes = DataObjectTypes> extends PureDataObjectFactory<TObj, I>
class TreeDataObjectFactory<TDataObject extends TreeDataObject<TDataObjectTypes>, TDataObjectTypes extends DataObjectTypes = DataObjectTypes>

Data Object Factories

Container Runtime Factories

Factory classes for creating and managing container runtimes, providing the infrastructure for hosting and coordinating multiple data objects within Fluid containers.

class BaseContainerRuntimeFactory extends RuntimeFactoryHelper
class ContainerRuntimeFactoryWithDefaultDataStore extends BaseContainerRuntimeFactory

Container Runtime Factories

Utility Functions

Helper functions and utilities for advanced data object creation and management patterns.

/**
 * Utility for creating SharedObjectKind instances for data objects.
 * @internal
 */
function createDataObjectKind<T extends DataObjectKind>(
  factory: T
): T & SharedObjectKind<T extends DataObjectKind<infer I> ? I : unknown>

Types

Core Types

interface DataObjectTypes {
  OptionalProviders?: FluidObject;
  InitialState?: any;
  Events?: IEvent;
}

interface IDataObjectProps<I extends DataObjectTypes = DataObjectTypes> {
  readonly runtime: IFluidDataStoreRuntime;
  readonly context: IFluidDataStoreContext;
  readonly providers: AsyncFluidObjectProvider<I["OptionalProviders"]>;
  readonly initProps?: I["InitialState"];
}

type DataObjectKind<T = unknown> = {
  readonly factory: IFluidDataStoreFactory;
} & (
  | {
      readonly makeCovariant?: T | undefined;
    }
  | (new (...args: never[]) => T)
);

Factory Configuration Types

interface DataObjectFactoryProps<TObj extends PureDataObject<I>, I extends DataObjectTypes = DataObjectTypes> {
  readonly type: string;
  readonly ctor: new (props: IDataObjectProps<I>) => TObj;
  readonly sharedObjects?: readonly IChannelFactory[];
  readonly optionalProviders?: FluidObjectSymbolProvider<I["OptionalProviders"]>;
  readonly registryEntries?: NamedFluidDataStoreRegistryEntries;
  readonly runtimeClass?: typeof FluidDataStoreRuntime;
  readonly policies?: Partial<IFluidDataStorePolicies>;
}

interface BaseContainerRuntimeFactoryProps {
  registryEntries: NamedFluidDataStoreRegistryEntries;
  dependencyContainer?: IFluidDependencySynthesizer;
  requestHandlers?: RuntimeRequestHandler[];
  runtimeOptions?: IContainerRuntimeOptions;
  provideEntryPoint: (runtime: IContainerRuntime) => Promise<FluidObject>;
  minVersionForCollab?: MinimumVersionForCollab | undefined;
}

interface ContainerRuntimeFactoryWithDefaultDataStoreProps {
  defaultFactory: IFluidDataStoreFactory;
  registryEntries: NamedFluidDataStoreRegistryEntries;
  dependencyContainer?: IFluidDependencySynthesizer;
  requestHandlers?: RuntimeRequestHandler[];
  runtimeOptions?: IContainerRuntimeOptions;
  provideEntryPoint?: (runtime: IContainerRuntime) => Promise<FluidObject>;
}

External Type References

The following types are from other Fluid Framework packages and are used in the @fluidframework/aqueduct API:

// From @fluidframework/core-interfaces
interface FluidObject {
  [key: string]: any;
}

interface IEvent {
  [key: string]: any;
}

interface IRequest {
  url: string;
  headers?: { [key: string]: any };
}

interface IResponse {
  mimeType: string;
  status: number;
  value: any;
}

interface IFluidHandle<T = any> {
  get(): Promise<T>;
  bind(handle: IFluidHandle): void;
}

interface IFluidHandleInternal<T = any> extends IFluidHandle<T> {
  // Internal implementation details
}

// From @fluidframework/datastore-definitions
interface IFluidDataStoreRuntime {
  id: string;
  entryPoint: IFluidHandle;
  createChannel(id: string, type: string): any;
  getChannel(id: string): Promise<any>;
  bindToContext(): void;
}

interface IFluidDataStoreContext {
  containerRuntime: any;
  packagePath: readonly string[];
  scope: FluidObject;
  createProps?: any;
}

// From @fluidframework/runtime-definitions
interface IFluidDataStoreFactory {
  type: string;
  instantiateDataStore(context: IFluidDataStoreContext, existing: boolean): Promise<any>;
}

type NamedFluidDataStoreRegistryEntries = [string, Promise<IFluidDataStoreFactory>][];
type NamedFluidDataStoreRegistryEntry = [string, Promise<IFluidDataStoreFactory>];

// From @fluidframework/map
interface ISharedDirectory {
  set(key: string, value: any): void;
  get<T>(key: string): T | undefined;
  // Additional SharedDirectory methods...
}

// From @fluidframework/tree
interface ITree {
  viewWith<T>(schema: T): any;
  // Additional SharedTree methods...
}

// From @fluidframework/synthesize  
type AsyncFluidObjectProvider<T> = {
  [K in keyof T]: Promise<T[K] | undefined>;
};

type FluidObjectSymbolProvider<T> = {
  [K in keyof T]: symbol;
};

// From @fluidframework/container-runtime
interface IContainerRuntime {
  createDataStore(type: string): Promise<any>;
  getAliasedDataStoreEntryPoint(alias: string): Promise<IFluidHandle | undefined>;
}

interface IContainerRuntimeOptions {
  summaryOptions?: any;
  gcOptions?: any;
  compressionOptions?: any;
  [key: string]: any;
}

// From @fluidframework/datastore
class FluidDataStoreRuntime {
  constructor(...args: any[]);
}

interface IFluidDataStorePolicies {
  gcOptions?: any;
  [key: string]: any;
}

interface IChannelFactory {
  type: string;
  create(runtime: any, id?: string): any;
}

// From @fluidframework/request-handler (deprecated)
type RuntimeRequestHandler = (request: IRequest, runtime: any) => Promise<IResponse | undefined>;

// From @fluidframework/container-runtime-definitions
type MinimumVersionForCollab = string;

// From @fluidframework/synthesize
interface IFluidDependencySynthesizer {
  synthesize<T>(providers: any, scope: any): any;
}

// From @fluidframework/shared-object-base
type SharedObjectKind<T = unknown> = {
  readonly factory: any;
};