Skip to content

Releases: microsoft/FluidFramework

Fluid Framework v2.82.0 (minor)

04 Feb 20:59
7c6d4d4

Choose a tag to compare

Contents

🌳 SharedTree DDS Changes

Add "push" as alias for insertAtEnd on TreeArrayNode (#26260)

Adds push as an alias to make the API more intuitive and reduce friction for both LLM-generated code and developers familiar with JavaScript array semantics.

Usage

import { TreeArrayNode } from "@fluidframework/tree";

// `inventory` is a TreeArrayNode from your schema.
inventory.push({ name: "Apples", quantity: 3 });

// Insert multiple items in one call.
inventory.push(
  TreeArrayNode.spread([
    { name: "Oranges", quantity: 2 },
    { name: "Bananas", quantity: 5 },
  ]),
);

Change details

Commit: e2ed71b

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

Adds optional "label" parameter to runTransaction for grouping changes (#25938)

Transaction labels can be used to group multiple changes for undo/redo, where groups of changes with the same label can be undone together. When multiple labels are used in nested transactions, only the outermost label will be used.

The following example demonstrates how to implement label-based undo/redo grouping. It listens to the changed event on the checkout to collect all commits with the same label into a group. When undoLatestGroup() is called, all transactions in that group are reverted together with a single operation.

interface LabeledGroup {
  label: unknown;
  revertibles: { revert(): void }[];
}

const undoGroups: LabeledGroup[] = [];

// The callback on the "changed" event can be used to group the commits.
view.checkout.events.on("changed", (meta, getRevertible) => {
  // Only process local edits, not remote changes or Undo/Redo operations
  if (getRevertible !== undefined && meta.kind === CommitKind.Default) {
    const label = meta.label;
    const revertible = getRevertible();

    // Check if the latest group contains the same label.
    const latestGroup = undoGroups[undoGroups.length - 1];
    if (
      label !== undefined &&
      latestGroup !== undefined &&
      label === latestGroup.label
    ) {
      latestGroup.revertibles.push(revertible);
    } else {
      undoGroups.push({ label, revertibles: [revertible] });
    }
  }
});

const undoLatestGroup = () => {
  const latestGroup =
    undoGroups.pop() ?? fail("There are currently no undo groups.");
  for (const revertible of latestGroup.revertibles.reverse()) {
    revertible.revert();
  }
};

// Group multiple transactions with the same label
view.runTransaction(
  () => {
    view.root.content = 1;
  },
  { label: "EditGroup" },
);
view.runTransaction(
  () => {
    view.root.content = 2;
  },
  { label: "EditGroup" },
);
view.runTransaction(
  () => {
    view.root.content = 3;
  },
  { label: "EditGroup" },
);

// This would undo all three transactions together.
undoLatestGroup();
// view.root.content is now back to 0 (the initial state).

Change details

Commit: cca4db2

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

Fix bug in multi-step move of array elements (#26344)

A multi-step move can be authored by moving the same array element multiple times within the scope of a single transaction. Such multi-step would lead to errors in the following scenarios:

  • Reverting a multi-step move would fail with error code 0x92a on the peer attempting the revert, thus putting the peer in a broken read-only state without corrupting the document.
  • If the set of pending edits generated by a peer included an edit with a multi-step move, followed by further edits to any of the moved items, reconciling these edits with concurrent edits sequenced earlier could lead to a document corruption with error code 0x9c7.

These operations are now safe.

Change details

Commit: 1bca56c

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

Promote MinimumVersionForCollab to beta (#26342)

Promotes the MinimumVersionForCollab type to beta, and adds option to configuredSharedTreeBeta for specifying it when creating a new SharedTree.

This allows users to opt into new features and optimizations that are only available when certain minimum version thresholds are guaranteed. For more details, see FluidClientVersion

Example usage

// Configure SharedTree DDS to limit the features it requires of collaborators and future document users to only those available in version `2.80.0` and later, overriding the `MinimumVersionForCollab` provided by the runtime (default: "2.0.0").
// Edits made to this DDS by this client might cause clients older than the specified version to be unable to open the document and/or error out of collaboration sessions.
const SharedTree = configuredSharedTreeBeta({
  minVersionForCollab: FluidClientVersion.v2_80,
});

Change details

Commit: 2bb53c5

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

Promote TableSchema APIs to beta (#26339)

Promotes the SharedTree TableSchema from alpha to beta. These APIs can now be imported via @fluidframework/tree/beta. Documents from before this are not supported with the beta version of the schema to ensure orphan cell invariants can be guaranteed.

Change details

Commit: 36a625a

Affected packages:

  • fluid-framework
  • @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!

Fluid Framework v2.81.1 (patch)

28 Jan 21:06
845a623

Choose a tag to compare

What's Changed

  • fix: tree agent rendering of fluid handles (#26292) #26305
  • [bump] client: 2.81.0 => 2.81.1 (patch) and type tests upgrade #26264

Full Changelog: client_v2.81.0...client_v2.81.1

Fluid Framework v2.81.0 (minor)

21 Jan 02:53
55a7af3

Choose a tag to compare

Contents

🚨 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!

Fluid Framework v2.80.0 (minor)

06 Jan 21:37
bffbb3b

Choose a tag to compare

Contents

🚨 Breaking Changes

Removal of number key support in LatestMap (#25904)

number keys have never been successfully propagated as numbers at runtime and this type clarification makes that clear. See issue 25919 for more details.

Change details

Commit: c1d91d8

Affected packages:

  • @fluidframework/presence

⬆️ Table of contents

Added layerIncompatibilityError to FluidErrorTypes, ContainerErrorTypes, DriverErrorTypes and OdspErrorTypes (#26068)

The Fluid error type layerIncompatibilityError is added to FluidErrorTypes and is now @legacy @beta. It is also added to ContainerErrorTypes, DriverErrorTypes and OdspErrorTypes which extend FluidErrorTypes. layerIncompatibilityError was added as @legacy @Alpha in version 2.72.0. The corresponding interface ILayerIncompatibilityError for errors of type layerIncompatibilityError is now also @legacy @beta.

See this issue for more details.

Change details

Commit: a8532bd

Affected packages:

  • @fluidframework/container-definitions
  • @fluidframework/core-interfaces
  • @fluidframework/driver-definitions
  • @fluidframework/odsp-driver-definitions

⬆️ Table of contents

TreeBranch operations throw when called during transactions (#26097)

This breaking change only affects the behavior of TreeBranch methods (currently released as beta).

  • Invoking TreeBranch.fork() now throws an error if a transaction is ongoing on the branch.
  • Invoking TreeBranch.merge(sourceBranch) now throws an error if a transaction is ongoing on the source branch. As before, it also throws an error if a transaction is ongoing on the target (i.e., this) branch.
  • Invoking TreeBranch.rebaseOnto(targetBranch) now throws an error if a transaction is ongoing on the target branch. As before, it also throws an error if a transaction is ongoing on the source (i.e., this) branch.

These new restrictions insulate branches and their dependents from experiencing incomplete transaction changes. This is important because incomplete transaction changes may not uphold application invariants.

In scenarios that experience the new errors, application authors should consider whether the ongoing transaction can safely be closed before invoking these methods.

Change details

Commit: 33b1ec0

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

map: Emit valueChanged events for deleted keys after a clear operation (#26102)

When a clear op is processed on SharedMap, valueChanged events are now emitted for each key that was deleted. Previously, only the clear event was emitted with no subsequent valueChanged events.

Change details

Commit: 7c9be0e

Affected packages:

  • @fluidframework/map

⬆️ Table of contents

🐛 Bug Fixes

Attendee status fixes on reconnect (#26111)

Fix "Connected" status for Attendees when local client reconnects (intermittent connection or transition from read-only to read-write connection). This includes no longer emitting incorrect "attendeeDisconnected" events.

Change details

Commit: 836f22f

Affected packages:

  • @fluidframework/presence

⬆️ Table of contents

Legacy API Changes

Types not intended for consumer implementation/extension are now @Sealed (#26024)

The following types are now explicitly marked as @sealed to indicate that they are not intended for consumer implementation or extension.

  • MockFluidDataStoreRuntime class in @fluidframework/test-runtime-utils
  • IFluidParentContext interface in @fluidframework/runtime-definitions
  • IFluidDataStoreContext interface in @fluidframework/runtime-definitions
  • IFluidDataStoreContextDetached interface in @fluidframework/runtime-definitions

Change details

Commit: 75a3861

Affected packages:

  • @fluidframework/runtime-definitions
  • @fluidframework/test-runtime-utils

⬆️ Table of contents

🛠️ Start Building Today!

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

Fluid Framework v2.74.0 (minor)

15 Dec 21:46
c15438c

Choose a tag to compare

Contents

🌳 SharedTree DDS Changes

Fixed bug in sending of revert edits after an aborted transaction (#25978)

Aborting a transaction used to put the tree in a state that would trigger an assert when sending some undo/redo edits to peers. This would prevent some undo/redo edits from being sent and would put the tree in a broken state that prevented any further edits. This issue could not have caused document corruption, so reopening the document was a possible remedy. Aborting a transaction no longer puts the tree in such a state, so it is safe to perform undo/redo edits after that.

Change details

Commit: 93ec6c7

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

⚠️ Deprecations

ai-collab library has been removed (#26008)

The team is no longer pursuing this direction for SharedTree-based collaboration with AI agents. This library is now considered deprecated. No future versions of this library will be published.

Change details

Commit: b084ac5

Affected packages:

⬆️ Table of contents

Legacy API Changes

Some keys in IFluidCodeDetailsConfig are now reserved for Fluid Framework use (#25641)

The keys of IFluidCodeDetailsConfig (the type of the config property on IFluidCodeDetails) used to be entirely free for consumer use. Going forward, keys with the "FluidFramework." prefix are reserved for Fluid Framework's internal use.

We do not expect this to affect any consumers.

Change details

Commit: 1eaf526

Affected packages:

  • @fluidframework/container-definitions

⬆️ Table of contents

🛠️ Start Building Today!

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

Fluid Framework v2.73.0 (minor)

24 Nov 22:05
d5a73d3

Choose a tag to compare

Contents

🌳 SharedTree DDS Changes

Schema snapshot compatibility checker (#25861)

This change adds alpha APIs for creating snapshots of view schema and testing their compatibility for the purposes of schema migrations.

New APIs:

  • checkCompatibility - Checks the compatibility of the view schema which created the document against the view schema being used to open it.
  • importCompatibilitySchemaSnapshot - Parse a JSON representation of a tree schema into a concrete schema.
  • exportCompatibilitySchemaSnapshot - Returns a JSON representation of the tree schema for snapshot compatibility checking.

Example: Current view schema vs. historical view schema

An application author is developing an app that has a schema for storing 2D Points. They wish to maintain backwards compatibility in future versions and avoid changing their view schema in a way that breaks this behavior. When introducing a new initial schema, they persists a snapshot using exportCompatibilitySchemaSnapshot:

const factory = new SchemaFactory("test");

// The past view schema, for the purposes of illustration. This wouldn't normally appear as a concrete schema in the test
// checking compatibility, but rather would be loaded from a snapshot.
class Point2D extends factory.object("Point", {
  x: factory.number,
  y: factory.number,
}) {}
const viewSchema = new TreeViewConfiguration({ schema: Point2D });
const encodedSchema = JSON.stringify(
  exportCompatibilitySchemaSnapshot(viewSchema),
);
fs.writeFileSync("PointSchema.json", encodedSchema);

Next they create a regression test to ensure that the current view schema can read content written by the original view schema (SchemaCompatibilityStatus.canUpgrade). Initially currentViewSchema === Point2D:

const encodedSchema = JSON.parse(fs.readFileSync("PointSchema.json", "utf8"));
const oldViewSchema = importCompatibilitySchemaSnapshot(encodedSchema);

// Check to see if the document created by the historical view schema can be opened with the current view schema
const compatibilityStatus = checkCompatibility(
  oldViewSchema,
  currentViewSchema,
);

// Check to see if the document created by the historical view schema can be opened with the current view schema
const backwardsCompatibilityStatus = checkCompatibility(
  oldViewSchema,
  currentViewSchema,
);

// z is not present in Point2D, so the schema must be upgraded
assert.equal(backwardsCompatibilityStatus.canView, false);

// The schema can be upgraded to add the new optional field
assert.equal(backwardsCompatibilityStatus.canUpgrade, true);

Additionally, they a regression test to ensure that older view schemas can read content written by the current view schema (SchemaCompatibilityStatus.canView):

// Test what the old version of the application would do with a tree using the new schema:
const forwardsCompatibilityStatus = checkCompatibility(
  currentViewSchema,
  oldViewSchema,
);

// If the old schema set allowUnknownOptionalFields, this would be true, but since it did not,
// this assert will fail, detecting the forwards compatibility break:
// this means these two versions of the application cannot collaborate on content using these schema.
assert.equal(forwardsCompatibilityStatus.canView, true);

Later in the application development cycle, the application author decides they want to change their Point2D to a Point3D, adding an extra field:

// Build the current view schema
const schemaFactory = new SchemaFactory("test");
class Point3D extends schemaFactory.object("Point", {
  x: factory.number,
  y: factory.number,

  // The current schema has a new optional field that was not present on Point2D
  z: factory.optional(factory.number),
}) {}

The test first compatibility test will pass as the Point2D schema is upgradeable to a Point3D schema. However, the second compatibility test fill fail as an application using the Point2D view schema cannot collaborate on content authored using the Point3D schema.

Change details

Commit: e5be416

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

🛠️ Start Building Today!

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

Fluid Framework v2.72.0 (minor)

11 Nov 02:20
06083ca

Choose a tag to compare

Contents

✨ New Features

Expose staged, types, stagedRecursive and typesRecursive on SchemaFactoryBeta (#25779)

These APIs were previously only available on SchemaFactoryAlpha, but are now available on SchemaFactoryBeta.

Change details

Commit: 75d7f11

Affected packages:

  • @fluidframework/tree

⬆️ Table of contents

🌳 SharedTree DDS Changes

formatVersion removed from the options passed to configuredSharedTree (#25752)

Note: this change may break users of alpha APIs. See below for details.

SharedTreeOptions (which is passed to configuredSharedTree) no longer includes a formatVersion: SharedTreeFormatVersion[keyof SharedTreeFormatVersion] field. The concept of SharedTreeFormatVersion has been removed altogether. Instead, users are expected to leverage the already existing minVersionForCollab field.

For migration purposes, the mapping from SharedTreeFormatVersion to minVersionForCollab is as follows:

  • SharedTreeFormatVersion.v1: no supported equivalent
  • SharedTreeFormatVersion.v2: no supported equivalent
  • SharedTreeFormatVersion.v3: minVersionForCollab: FluidClientVersion.v2_0
  • SharedTreeFormatVersion.v5: minVersionForCollab: FluidClientVersion.v2_43
  • SharedTreeFormatVersion.vSharedBranches: minVersionForCollab: FluidClientVersion.v2_43 + SharedTreeOptions.enableSharedBranches

The values for which there is no supported equivalent minVersionForCollab were never given official support. Contact the Fluid Framework team if you need help migrating away from them.

Change details

Commit: df53390

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

Legacy API Changes

Added a new Fluid error type layerIncompatibilityError (#25784)

A new Fluid error type layerIncompatibilityError is added to FluidErrorTypesAlpha as @legacy @Alpha. This will be moved to FluidErrorTypes as @legacy @beta in a future legacy breaking release. It will also be added to ContainerErrorTypes since it extends FluidErrorTypes.

Change details

Commit: 01d568b

Affected packages:

  • @fluidframework/core-interfaces
  • @fluidframework/container-definitions

⬆️ Table of contents

🛠️ Start Building Today!

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

Fluid Framework v2.71.0 (minor)

03 Nov 21:41
a5456fd

Choose a tag to compare

Contents

✨ New Features

delete keyword support for ObjectNodes (#25738)

Added support for using the delete keyword to remove content under optional fields for ObjectNodes.

// This is now equivalent to node.foo = undefined
delete node.foo;

Change details

Commit: 31dca54

Affected packages:

  • @fluidframework/tree

⬆️ Table of contents

🌳 SharedTree DDS Changes

Add IndependentTree API (#25785)

New IndependentTreeAlpha and IndependentTreeBeta APIs provide similar utility to the existing alpha IndependentView API, except providing access to the ViewableTree.

This allows for multiple views (in sequence, not concurrently) to be created to test things like schema upgrades and incompatible view schema much more easily (see example below). For IndependentTreeAlpha, this also provides access to exportVerbose and exportSimpleSchema from ITreeAlpha.

An example of how to use createIndependentTreeBeta to create multiple views to test a schema upgrade:

const tree = createIndependentTreeBeta();

const stagedConfig = new TreeViewConfiguration({
  schema: SchemaFactoryAlpha.types([
    SchemaFactory.number,
    SchemaFactoryAlpha.staged(SchemaFactory.string),
  ]),
});
const afterConfig = new TreeViewConfigurationAlpha({
  schema: [SchemaFactory.number, SchemaFactory.string],
});

// Initialize tree
{
  const view = tree.viewWith(stagedConfig);
  view.initialize(1);
  view.dispose();
}

// Do schema upgrade
{
  const view = tree.viewWith(afterConfig);
  view.upgradeSchema();
  view.root = "A";
  view.dispose();
}

// Can still view tree with staged schema
{
  const view = tree.viewWith(stagedConfig);
  assert.equal(view.root, "A");
  view.dispose();
}

Change details

Commit: 21c4245

Affected packages:

  • fluid-framework
  • @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!

Fluid Framework v2.70.0 (minor)

28 Oct 21:13
151d310

Choose a tag to compare

Contents

🚨 Breaking Changes

Deprecated properties have been removed from IRuntimeStorageService and IContainerStorageService (#25708)

The following deprecated properties have been removed from IRuntimeStorageService:

  • createBlob
  • dispose
  • disposed
  • downloadSummary
  • getSnapshot
  • getSnapshotTree
  • getVersions
  • policies
  • uploadSummaryWithContext

The following deprecated properties have been removed from IContainerStorageService:

  • dispose
  • disposed
  • downloadSummary

Please see this Github issue for more details.

Change details

Commit: 82c936e

Affected packages:

  • @fluidframework/container-definitions
  • @fluidframework/runtime-definitions

⬆️ Table of contents

getSnapshotTree is now required in IChannelStorageService (#25707)

The getSnapshotTree property was added as optional to IChannelStorageService in version 2.51.0. It is now a required property. See this github issue for more details.

Change details

Commit: d1c4c0a

Affected packages:

  • @fluidframework/datastore-definitions
  • @fluidframework/test-runtime-utils

⬆️ Table of contents

Deprecated property processCore has been removed from SharedObject (#25749)

The deprecated property processCore has been removed from SharedObject.

Please see this github issue for more details.

Change details

Commit: a33a2e3

Affected packages:

  • @fluidframework/ordered-collection
  • @fluidframework/register-collection
  • @fluidframework/shared-object-base

⬆️ Table of contents

Remove submitMessage from FluidDataStoreRuntime and MockFluidDataStoreRuntime (#25755)

As needed, access submitMessage via IFluidDataStoreContext/IFluidParentContext. See #24406 for details.

Change details

Commit: 88860f3

Affected packages:

  • @fluidframework/datastore
  • @fluidframework/test-runtime-utils

⬆️ Table of contents

✨ New Features

Promote core devtools APIs from alpha to beta (#25695)

The primary devtools APIs may now be imported from /beta. This includes:

  • initializeDevtools - Initialize the devtools singleton
  • tryGetFluidDevtools - Get the existing devtools instance if initialized
  • IFluidDevtools - Main devtools interface for registering containers
  • ContainerDevtoolsProps - Properties for registering containers with devtools

For example:

import {
  initializeDevtools,
  tryGetFluidDevtools,
  type IFluidDevtools,
  type ContainerDevtoolsProps,
} from "@fluidframework/devtools-core/beta";

// Initialize devtools
const devtools = initializeDevtools();

// Register a container
devtools.registerContainerDevtools({
  containerKey: "my-container",
  container: myContainer,
});

Change details

Commit: 7c8e203

Affected packages:

  • @fluidframework/devtools-core

⬆️ Table of contents

Added Tree.ensureSchema (#25740)

This helper function allows content to be tagged with a schema type before being inserted into the tree. This allows content that would otherwise be ambiguous to be well-defined, without having to wrap it in a node constructor.

Example:

const sf = new SchemaFactory("example");
class Dog extends sf.object("Dog", { name: sf.string() }) {}
class Cat extends sf.object("Cat", { name: sf.string() }) {}
class Root extends sf.object("Root", { pet: [Dog, Cat] }) {}
// ...
const pet = { name: "Max" };
view.root.pet = pet; // Error: `pet` is ambiguous - is it a Dog or a Cat?
view.root.pet = new Dog(pet); // This works, but has the overhead of creating a Dog node before the insertion actually happens.
TreeAlpha.ensureSchema(Dog, pet); // Instead, this tags the `pet` object as a Dog...
view.root.pet = pet; // So now there is no error for a normal insertion - it's a Dog.

This function works by leveraging the new schemaSymbol, which is also available for use. See its documentation for more information.

Change details

Commit: 8213407

Affected packages:

  • @fluidframework/tree

⬆️ Table of contents

A minimal set of branching APIs has been promoted to beta. (#25744)

The following APIs have been promoted to beta in @fluidframework/tree:

  • TreeBranch.fork()
  • TreeBranch.merge()
  • TreeBranch.rebaseOnto()
  • TreeBranch.dispose()
  • TreeView.fork()

These APIs enable applications to implement basic local branching flows.

Change details

Commit: 32cc2c7

Affected packages:

  • fluid-framework
  • @fluidframework/tree
  • @fluidframework/tree-agent

⬆️ Table of contents

Improved join scalability (#25371)

Protocol for attendees joining has been updated to more efficiently accommodate a larger number of attendees, including when few-to-none have write access.

Change details

Commit: 98dadd3

Affected packages:

  • @fluidframework/presence

⬆️ Table of contents

🌳 SharedTree DDS Changes

Update TableSchema APIs (alpha) to accept SchemaFactoryBeta in addition to SchemaFactoryAlpha ([#25613](https://github.com/microso...

Read more

Fluid Framework v2.63.0 (minor)

14 Oct 18:23
4b609d4

Choose a tag to compare

Contents

🌳 SharedTree DDS Changes

Add FluidSerializableAsTree domain for representing trees of serializable data (alpha) (#25604)

Like JsonAsTree, but also supports Fluid Handles.

Change details

Commit: 46e6dce

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

Promote Record node types and factories to beta (#25606)

Record tree node schema may now be declared using SchemaFactoryBeta in addition to SchemaFactoryAlpha.

Change details

Commit: 2e2de30

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

Add TreeBeta.create (#25623)

Adds TreeBeta.create, which is a more stable version of the existing TreeAlpha.create. The only difference is the new TreeBeta.create does not support the @alpha UnsafeUnknownSchema option.

Change details

Commit: 376c2d1

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

Alpha APIs for annotated allowed types have been refactored (#25595)

Staged allowed types must now be run through SchemaFactoryAlpha.types to convert them into an AllowedTypes. This change also means that it is now possible to use the produced AllowedTypesFull in non-alpha APIs since it implements AllowedTypes.

Reading data out of ImplicitAllowedTypes should now be done via normalizeAllowedTypes which now returns a AllowedTypesFull providing access to all the data in a friendly format.

Change details

Commit: c6ba37e

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

Promote importConcise and exportConcise to beta (#25629)

importConcise and exportConcise were previously available via TreeAlpha. They may now also be accessed via TreeBeta.

Note that the beta form of importConcise does not support UnsafeUnknownSchema.

Change details

Commit: b5d4602

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

Stabilize allowUnknownOptionalFields to beta (#25638)

When constructing object node schema with SchemaFactoryBeta.object or SchemaFactoryBeta.objectRecursive you can now provide the allowUnknownOptionalFields option as well as other metadata which were previously only available in SchemaFactoryAlpha.objectAlpha and SchemaFactoryAlpha.objectRecursive.

Additionally the alpha interface SchemaFactoryObjectOptions has been renamed to ObjectSchemaOptionsAlpha to better align with the other related types.

Change details

Commit: b7222d1

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

Add SchemaFactoryAlpha.typesRecursive and SchemaFactoryAlpha.stagedRecursive (#25199)

With these new APIs, it is now possible to stage changes to recursive types.

Change details

Commit: 931e986

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

MinimumVersionForCollab is now used in place of tree's alpha FluidClientVersion (#25402)

FluidClientVersion: No longer used as the type for Fluid Client versions in APIs/codecs (for example, oldestCompatibleClient). Additionally, FluidClientVersion is now a const object with members that declare specific MinimumVersionForCollab versions. These are intended to be used with APIs that require a version (such as TreeAlpha.exportCompressed).

CodecWriteOptions and SharedTreeOptions: oldestCompatibleClient has been replaced by minVersionForCollab. See migration guide below.

TreeAlpha.exportCompressed: The options parameter previously had oldestCompatibleClient and now has minVersionForCollab. Migrating requires a rename. Existing FluidClientVersion.* values are now MinimumClientVersions.

Migrating

If an application is calling loadContainerRuntime directly and previously specified the minimum client version when initializing Shared Tree like:

    const factory = configuredSharedTree({ ..., oldestCompatibleClient: FluidClientVersion.v2_52 });

Then the new implementation depends on how the application initializes Fluid.

Applications using AzureClient/OdspClient

If an application is using the declarative model (for example, AzureClient/OdspClient), it should continue to call configuredSharedTree but specify minVersionForCollab instead:

    const factory = configuredSharedTree({ ..., minVersionForCollab: "2.52.0" });
Applications calling loadContainerRuntime

If an application is initializing the ContainerRuntime directly, it should now specify the minVersionForCollab there:

    const runtime = await loadContainerRuntime({ ..., minVersionForCollab: "2.52.0" });

Change details

Commit: 7f59e31

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

🛠️ Start Building Today!

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