Contents
- 🚨 Breaking Changes
- directory: Path parameter added to
clearedevent (#26112)
- directory: Path parameter added to
- 🌳 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
getRevertiblehas moved ontoChangeMetadata(#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 (wheretfis aliased fromtypeFactory) - Same API surface: The existing
expose,exposeProperty, andbuildFuncmethods 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:
- Easier to discover.
- Easier to ignore.
- Require less parameter churn to use.
- Consistent with the
getChangeAPI, 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!