8000 Releases · microsoft/FluidFramework · GitHub
[go: up one dir, main page]

Skip to content

Releases: microsoft/FluidFramework

Fluid Framework v2.90.0 (minor)

03 Mar 04:02
da8ba9a

Choose a tag to compare

Contents

🚨 Breaking Changes

@fluidframework/react no longer supports CommonJS (#26575)

CommonJS support has been removed from @fluidframework/react. This package currently only has alpha APIs, so this opportunity was taken to simplify and modernize it while we still can.

Change details

Commit: 995c1e4

Affected packages:

  • @fluidframework/react

⬆️ Table of contents

🌳 SharedTree DDS Changes

Promote checkSchemaCompatibilitySnapshots to beta (#26346)

checkSchemaCompatibilitySnapshots has been promoted to @beta. It is recommended that all SharedTree applications use this API to write schema compatibility tests.

Usage should look something like:

import fs from "node:fs";
import path from "node:path";

import { snapshotSchemaCompatibility } from "@fluidframework/tree/beta";

// The TreeViewConfiguration the application uses, which contains the application's schema.
import { treeViewConfiguration } from "./schema.js";
// The next version of the application which will be released.
import { packageVersion } from "./version.js";

// Provide some way to run the check in "update" mode when updating snapshots is intended.
const regenerateSnapshots = process.argv.includes("--snapshot");

// Setup the actual test. In this case using Mocha syntax.
describe("schema", () => {
  it("schema compatibility", () => {
    // Select a path to save the snapshots in.
    // This will depend on how your application organizes its test data.
    const snapshotDirectory = path.join(
      import.meta.dirname,
      "../../../src/test/snapshotCompatibilityCheckerExample/schema-snapshots",
    );
    snapshotSchemaCompatibility({
      snapshotDirectory,
      fileSystem: { ...fs, ...path },
      version: packageVersion,
      minVersionForCollaboration: "2.0.0",
      schema: treeViewConfiguration,
      mode: regenerateSnapshots ? "update" : "assert",
    });
  });
});

Change details

Commit: cb22046

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

Added new TreeAlpha.context(node) API (#26432)

This release introduces a node-scoped context that works for both hydrated and unhydrated TreeNodes. The new TreeContextAlpha interface exposes runTransaction / runTransactionAsync methods and an isBranch() type guard. TreeBranchAlpha now extends TreeContextAlpha, so you can keep using branch APIs when available.

Migration

If you previously used TreeAlpha.branch(node) to discover a branch, switch to TreeAlpha.context(node) and check isBranch():

import { TreeAlpha } from "@fluidframework/tree/alpha";

const context = TreeAlpha.context(node);
if (context.isBranch()) {
  // Same branch APIs as before
  context.fork();
}

TreeAlpha.branch(node) is now deprecated. Prefer the context API above.

New transaction entry point

You can now run transactions from a node context, regardless of whether the node is hydrated:

// A synchronous transaction without a return value
const context = TreeAlpha.context(node);
context.runTransaction(() => {
  node.count += 1;
});
// An asynchronous transaction with a return value
const context = TreeAlpha.context(node);
const result = await context.runTransactionAsync(async () => {
  await doWork(node);
  return { value: node.foo };
});

Change details

Commit: ffa62f4

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

Add alpha TextAsTree domain for collaboratively editable text (#26568)

A newly exported TextAsTree alpha namespace has been added with an initial version of collaboratively editable text. Users of SharedTree can add TextAsTree.Tree nodes to their tree to experiment with it.

Change details

Commit: 06736bd

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

⚠️ Deprecations

Deprecated DDS implementation classes (#26501)

The following DDS implementation classes are now deprecated and will be removed in a future release:

  • ConsensusRegisterCollectionClass — use ConsensusRegisterCollectionFactory to create instances and IConsensusRegisterCollection for typing
  • ConsensusOrderedCollection — use IConsensusOrderedCollection for typing
  • ConsensusQueueClass — use the ConsensusQueue singleton to create instances and IConsensusOrderedCollection for typing

Change details

Commit: 583a96c

Affected packages:

  • @fluidframework/register-collection
  • @fluidframework/ordered-collection

⬆️ 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.83.0 (minor)

18 Feb 17:56
ac0066e

Choose a tag to compare

Contents

🌳 SharedTree DDS Changes

Fix false positive error from FormatValidator (#26372)

Users of the alpha API FormatValidatorBasic could hit an "Invalid JSON." error when parsing data. This would occur where the result of evaluating "MinimumVersionForCollab < 2.74.0" differed between the client encoding the data and the client decoding it. For example opening an old document with a new client that sets MinimumVersionForCollab = 2.74.0 would throw this error. This has been fixed: this case will no longer throw.

Change details

Commit: adad917

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

Improve error messages when failing to construct nodes (#26388)

The error messages when constructing tree nodes have been improved. Several cases now list not only the schema identifiers, but also schema names which can help when there are identifier collisions and make it easier to find the implementations. Additionally some cases which did not include what schema were encountered and which were allowed now include both.

Change details

Commit: 862a65e

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

New beta ExtensibleUnionNode API (#26438)

The new ExtensibleUnionNode API allows for creation of unions which can tolerate future additions not yet known to the current code.

const sf = new SchemaFactoryBeta("extensibleUnionNodeExample.items");
class ItemA extends sf.object("A", { x: sf.string }) {}
class ItemB extends sf.object("B", { x: sf.number }) {}

class AnyItem extends ExtensibleUnionNode.createSchema(
  [ItemA, ItemB], // Future versions may add more members here
  sf,
  "ExtensibleUnion",
) {}
// Instances of the union are created using `create`.
const anyItem = AnyItem.create(new ItemA({ x: "hello" }));
// Reading the content from the union is done via the `union` property,
// which can be `undefined` to handle the case where a future version of this schema allows a type unknown to the current version.
const childNode: ItemA | ItemB | undefined = anyItem.union;
// To determine which member of the union was present, its schema can be inspected:
const aSchema = Tree.schema(childNode ?? assert.fail("No child"));
assert.equal(aSchema, ItemA);

Change details

Commit: 05f716f

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.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 10000 @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:

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
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 be D28D fore, 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!

0