github microsoft/FluidFramework client_v2.81.0
Fluid Framework v2.81.0 (minor)

8 hours ago

Contents

  • 🚨 Breaking Changes
    • directory: Path parameter added to cleared event (#26112)
  • 🌳 SharedTree DDS Changes
    • tree-agent: New type factory system for method and property bindings (#26167)
    • New text-editor example demonstrating SharedTree with Quill (#26217)
  • 🐛 Bug Fixes
    • Self attendee is announced via "attendeeConnected" (#26247)
  • ⚠️ Deprecations
    • getRevertible has moved onto ChangeMetadata (#26215)

🚨 Breaking Changes

directory: Path parameter added to cleared event (#26112)

The clear event for SharedDirectory did not include a path parameter indicating which directory was cleared. Therefore, the clear event is deprecated and will be removed in a future release. Instead use the cleared event.

Before:

sharedDirectory.on("clear", (local, target) => {
  // No way to know which subdirectory was cleared
});

After:

sharedDirectory.on("cleared", (path, local, target) => {
  // path tells you which directory was cleared (e.g., "/", "/subdir1", "/subdir2")
});

This change provides better observability by allowing listeners to distinguish between clear operations on different subdirectories within the SharedDirectory hierarchy.

Change details

Commit: 1ded6bf

Affected packages:

  • fluid-framework
  • @fluidframework/map

⬆️ Table of contents

🌳 SharedTree DDS Changes

tree-agent: New type factory system for method and property bindings (#26167)

The @fluidframework/tree-agent package now includes a custom type system (Type Factory) as an alternative to Zod for defining method and property types. This new system is available in the /alpha entry point and provides a familiar API for type definitions.

Key features

  • Familiar API: Use tf.string(), tf.object(), etc. - similar to Zod's syntax (where tf is aliased from typeFactory)
  • Same API surface: The existing expose, exposeProperty, and buildFunc methods work with both Zod and Type Factory types

Usage

Import from the alpha entry point to use Type Factory types:

import {
  typeFactory as tf,
  buildFunc,
  exposeMethodsSymbol,
} from "@fluidframework/tree-agent/alpha";
import { SchemaFactory } from "@fluidframework/tree";

const sf = new SchemaFactory("myApp");

class TodoList extends sf.object("TodoList", {
  items: sf.array(sf.string),
}) {
  public addItem(item: string): void {
    this.items.insertAtEnd(item);
  }

  public static [exposeMethodsSymbol](methods) {
    methods.expose(
      TodoList,
      "addItem",
      buildFunc({ returns: tf.void() }, ["item", tf.string()]),
    );
  }
}

Available types

All common types are supported:

  • Primitives: tf.string(), tf.number(), tf.boolean(), tf.void(), tf.undefined(), tf.null(), tf.unknown()
  • Collections: tf.array(elementType), tf.object({ shape }), tf.map(keyType, valueType), tf.record(keyType, valueType), tf.tuple([types])
  • Utilities: tf.union([types]), tf.literal(value), tf.optional(type), tf.readonly(type)
  • Schema references: tf.instanceOf(SchemaClass)

Migration from Zod

You can migrate gradually - both Zod and Type Factory types work in the same codebase:

Before (Zod):

import { z } from "zod";
import { buildFunc, exposeMethodsSymbol } from "@fluidframework/tree-agent";

methods.expose(
  MyClass,
  "myMethod",
  buildFunc({ returns: z.string() }, ["param", z.number()]),
);

After (Type Factory):

import {
  typeFactory as tf,
  buildFunc,
  exposeMethodsSymbol,
} from "@fluidframework/tree-agent/alpha";

methods.expose(
  MyClass,
  "myMethod",
  buildFunc({ returns: tf.string() }, ["param", tf.number()]),
);

Note on type safety

The Type Factory type system does not currently provide compile-time type checking, though this may be added in the future. For applications requiring strict compile-time validation, Zod types remain fully supported.

Change details

Commit: f09aa24

Affected packages:

  • @fluidframework/tree-agent

⬆️ Table of contents

New text-editor example demonstrating SharedTree with Quill (#26217)

This example showcases a collaborative text editor using SharedTree for data storage and Quill as the editor. It demonstrates using withMemoizedTreeObservations from @fluidframework/react for reactive updates when the tree changes.

Change details

Commit: a7abfac

Affected packages:

  • @fluid-example/text-editor

⬆️ Table of contents

🐛 Bug Fixes

Self attendee is announced via "attendeeConnected" (#26247)

Local attendee connection is now announced via "attendeeConnected" presence event.

Change details

Commit: f838524

Affected packages:

  • @fluidframework/presence

⬆️ Table of contents

⚠️ Deprecations

getRevertible has moved onto ChangeMetadata (#26215)

The getRevertible factory provided by the changed event is now exposed on the ChangeMetadata object instead of as the second callback parameter. The second parameter is deprecated and will be removed in a future release.

Why this change?

Keeping all per-change data on ChangeMetadata makes the API:

  1. Easier to discover.
  2. Easier to ignore.
  3. Require less parameter churn to use.
  4. Consistent with the getChange API, which is also only available on local commits.

Migration

Before (deprecated):

The getRevertible argument passed to the event had the following shape:

Data change Schema change
Local change () => Revertible undefined
Remote change undefined undefined
checkout.events.on("changed", (_data, getRevertible) => {
  if (getRevertible !== undefined) {
    const revertible = getRevertible();
    // ...
  }
});

After:

The new getRevertible property has the following shape:

Data change Schema change
Local change () => Revertible () => undefined
Remote change undefined undefined
checkout.events.on("changed", ({ getRevertible }) => {
  const revertible = getRevertible?.();
  if (revertible !== undefined) {
    // ...
  }
});

This applies potentially anywhere you listen to changed (for example on TreeViewAlpha.events/TreeBranchEvents).

Change details

Commit: 922f579

Affected packages:

  • @fluidframework/tree

⬆️ Table of contents

🛠️ Start Building Today!

Please continue to engage with us on GitHub Discussion and Issue pages as you adopt Fluid Framework!

Don't miss a new FluidFramework release

NewReleases is sending notifications on new releases.