Skip to content

Releases: microsoft/FluidFramework

Fluid Framework v2.2.1 (patch)

18 Sep 22:25
54ff0da
Compare
Choose a tag to compare

What's Changed

  • [Port 2.2] 0x04f bug fix for SharedString and SharedMatrix (#22529) #22540
  • [main -> 2.2] build(client): Update typetests baselines to 2.2.0 #22268
  • [bump] client: 2.2.0 => 2.2.1 (patch) #22258
  • [main -> 2.2] ci: Bump marocchino/sticky-pull-request-comment action to latest version (2.9.0) #22262

Full Changelog: client_v2.2.0...client_v2.2.1

Fluid Framework v2.1.1 (patch)

18 Sep 22:24
f1c23fc
Compare
Choose a tag to compare

What's Changed

  • [Port 2.1] 0x04f bug fix for SharedString and SharedMatrix (#22529) #22539
  • Revert back PR #21785. Process ops by batches in remoteMessageProcessor and pendingStateManager #22509
  • [port 2.1]: Fix upload release report step #22168
  • [port 2.1] refactor(ci): Use Small pool for first stage of Test DDS Stress pipeline #21986
  • Update type tests for 2.1 release branch #21981
  • [bump] client: 2.1.0 => 2.1.1 (patch) #21978

Full Changelog: client_v2.1.0...client_v2.1.1

Fluid Framework v2.3.0 (minor)

17 Sep 03:40
c5359ba
Compare
Choose a tag to compare

Contents

✨ New Features

Experimental Presence package added (#22499)

@fluid-experimental/presence is now available for investigation. The new package is meant to support presence of collaborators connected to the same container. Use this library to quickly share simple, non-persisted data among all clients or send/receive fire and forget notifications.

API documentation for @fluid-experimental/presence is available at https://fluidframework.com/docs/apis/presence.

There are some limitations; see the README.md of installed package for most relevant notes.

We're just getting started. Please give it a go and share feedback.

Change details

Commit: 42b323c

Affected packages:

  • @fluid-experimental/presence

⬆️ Table of contents

🌳 SharedTree DDS changes

Refactor code for emitting events to make it easier to copy into other projects (#22275)

Factored event emitting utilities into their own file, events/emitter.ts. Applications wishing to use SharedTree's eventing library for custom events can copy this file (and its referenced utility function) as a starting point for defining and emitting their own custom events. See createEmitter's documentation for example usage.

Currently there are no published or officially supported versions of these utilities, but they are relatively simple, and can be copied and customized as needed.

Change details

Commit: 49849bb

Affected packages:

  • @fluidframework/tree

⬆️ Table of contents

A @beta version of nodeChanged which includes the list of properties has been added (#22229)

const factory = new SchemaFactory("example");
class Point2d extends factory.object("Point2d", {
  x: factory.number,
  y: factory.number,
}) {}

const point = new Point2d({ x: 0, y: 0 });

TreeBeta.on(point, "nodeChanged", (data) => {
  const changed: ReadonlySet<"x" | "y"> = data.changedProperties;
  if (changed.has("x")) {
    // ...
  }
});

The payload of the nodeChanged event emitted by SharedTree's TreeBeta includes a changedProperties property that indicates which properties of the node changed.

For object nodes, the list of properties uses the property identifiers defined in the schema, and not the persisted identifiers (or "stored keys") that can be provided through FieldProps when defining a schema. See the documentation for FieldProps for more details about the distinction between "property keys" and "stored keys".

For map nodes, every key that was added, removed, or updated by a change to the tree is included in the list of properties.

For array nodes, the set of properties will always be undefined: there is currently no API to get details about changes to an array.

Object nodes revieve strongly types sets of changed keys, allowing compile time detection of incorrect keys:

TreeBeta.on(point, "nodeChanged", (data) => {
  // @ts-expect-error Strong typing for changed properties of object nodes detects incorrect keys:
  if (data.changedProperties.has("z")) {
    // ...
  }
});

The existing stable "nodeChanged" event's callback now is given a parameter called unstable of type unknown which is used to indicate that additional data can be provided there. This could break existing code using "nodeChanged" in a particularly fragile way.

function f(optional?: number) {
  // ...
}
Tree.on(point, "nodeChanged", f); // Bad

Code like this which is implicitly discarding an optional argument from the function used as the listener will be broken. It can be fixed by using an inline lambda expression:

function f(optional?: number) {
  // ...
}
Tree.on(point, "nodeChanged", () => f()); // Safe

Change details

Commit: aae34dd

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

Make SharedTree usable with legacy APIs (#22320)

SharedTree was not previously exported in a way that made it usable with @fluidframework/aqueduct or other lower-level legacy APIs. This fixes that issue by making it consistent with other DDSes: such usages can import { SharedTree } from "@fluidframework/tree/legacy";.

Change details

Commit: bbdf869

Affected packages:

  • @fluidframework/tree

⬆️ Table of contents

Implicitly constructed object nodes now only consider own properties during validation (#22453)

When determining if some given data is compatible with a particular ObjectNode schema, both inherited and own properties were considered. However, when constructing the node from this data, only own properties were used. This allowed input which provided required values in inherited fields to pass validation. When the node was constructed, it would lack these fields, and end up out of schema. This has been fixed: both validation and node construction now only consider own properties.

This may cause some cases which previously exhibited data corruption to now throw a usage error reporting the data is incompatible. Such cases may need to copy data from the objects with inherited properties into new objects with own properties before constructing nodes from them.

Change details

Commit: 27faa56

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

Export SharedTree beta APIs from fluid-framework/beta (#22469)

fluid-framework/beta now contains the @beta APIs from @fluidframework/tree/beta.

Change details

Commit: c51f55c

Affected packages:

  • fluid-framework

⬆️ Table of contents

Add /alpha import path to @fluidframework/tree and fluid-framework packages (#22483)

@fluidframework/tree and fluid-framework now have a /alpha import path where their @alpha APIs are exported.

Change details

Commit: 12242cf

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

🐛 Bug Fixes

Restored old op processing behavior around batched ops to avoid potential regression (#22508)

There's a theoretical risk of indeterminate behavior due to a recent change to how batches of ops are processed. This fix reverses that change.

Pull Request #21785 updated the ContainerRuntime to hold onto the messages in an incoming batch until they've all arrived, and only then process the set of messages.

While the batch is being processed, the DeltaManager and ContainerRuntime's view of the latest sequence numbers will be out of sync. This may have unintended side effects, so out of an abundance of caution we're reversing this behavior until we can add the proper protections to ensure the system stays properly in sync.

Change details

Commit: 709f085

Affected packages:

  • @fluidframewor...
Read more

Fluid Framework v2.2.0 (minor)

19 Aug 18:37
6f4b15d
Compare
Choose a tag to compare

Contents

✨ New Features

New isFluidHandle type guard to check if an object is an IFluidHandle (#22029)

The isFluidHandle type guard function is now exported and can be used to detect which objects are IFluidHandles. Since IFluidHandle often needs special handling (for example when serializing since it's not JSON compatible), having a dedicated detection function for it is useful. Doing this detection was possible previously using the tree package's schema system via Tree.is(value, new SchemaFactory("").handle), but can now be done with just isFluidHandle(value).

Change details

Commit: 7827d10

Affected packages:

  • fluid-framework
  • @fluidframework/runtime-utils

⬆️ Table of contents

🌳 SharedTree DDS changes

✨ New! When unambiguous, ArrayNodes can now be constructed from Maps and MapNodes from arrays (#22036)

Since the types for ArrayNodes and MapNodes indicate they can be constructed from iterables, it should work, even if those iterables are themselves arrays or maps. To avoid this being a breaking change, a priority system was introduced. ArrayNodes will only be implicitly constructable from JavaScript Map objects in contexts where no MapNodes are allowed. Similarly MapNodes will only be implicitly constructable from JavaScript Array objects in contexts where no ArrayNodes are allowed.

In practice, the main case in which this is likely to matter is when implicitly constructing a map node. If you provide an array of key value pairs, this now works instead of erroring, as long as no ArrayNode is valid at that location in the tree.

class MyMapNode extends schemaFactory.map("x", schemaFactory.number) {}
class Root extends schemaFactory.object("root", { data: MyMapNode }) {}
// This now works (before it compiled, but error at runtime):
const fromArray = new Root({ data: [["x", 5]] });

Prior versions used to have to do:

new Root({ data: new MyMapNode([["x", 5]]) });

or:

new Root({ data: new Map([["x", 5]]) });

Both of these options still work: strictly more cases are allowed with this change.

Change details

Commit: 25e74f9

Affected packages:

  • @fluidframework/tree
  • fluid-framework

⬆️ Table of contents

✨ New! Record-typed objects can now be used to construct MapNodes (#22042)

You can now construct MapNodes from Record typed objects, similar to how maps are expressed in JSON.

Before this change, an Iterable<string, Child> was required, but now an object like {key1: Child1, key2: Child2} is allowed.

Full example using this new API:

class Schema extends schemaFactory.map("ExampleMap", schemaFactory.number) {}
const fromRecord = new Schema({ x: 5 });

This new feature makes it possible for schemas to construct a tree entirely from JSON-compatible objects using their constructors, as long as they do not require unhydrated nodes to differentiate ambiguous unions, or IFluidHandles (which themselves are not JSON compatible).

Due to limitations of TypeScript and recursive types, recursive maps do not advertise support for this feature in their typing, but it works at runtime.

Change details

Commit: 25deff3

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

Implicit TreeNode construction improvements (#21995)

ArrayNodes and MapNodes could always be explicitly constructed (using new) from iterables. The types also allowed using of iterables to implicitly construct array nodes and map nodes, but this did not work at runtime. This has been fixed for all cases except implicitly constructing an ArrayNode form an Iterable that is actually a Map, and implicitly constructing a MapNode from an Iterable that is actually an Array. These cases may be fixed in the future, but require additional work to ensure unions of array nodes and map nodes work correctly.

Additionally MapNodes can now be constructed from Iterator<readonly [string, content]> where previously the inner arrays had to be mutable.

Change details

Commit: 977f96c

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

Fix document-corrupting bug when rebasing over move compositions (#21993)

Before this fix, if multiple users concurrently performed moves (possibly by reverting prior moves), there was a chance that the document would become corrupted.

Change details

Commit: f3af9d1

Affected packages:

  • @fluidframework/tree

⬆️ Table of contents

Enforce use of TreeViewConfiguration's constructor (#22055)

TreeViewConfiguration is @sealed, meaning creating custom implementations of it such as assigning object literals to a `TreeViewConfiguratio...

Read more

build-tools v0.42.0 (minor)

02 Aug 19:22
6a60dce
Compare
Choose a tag to compare

This is a minor release.

Fluid Framework v2.0.0-rc.5.0.7 (patch)

26 Jul 02:35
6ddc26c
Compare
Choose a tag to compare

What's Changed

  • [bump] client: 2.0.0-rc.5.0.6 => 2.0.0 rc.5.0.7 #21829
  • [main > release/client/rc5]: Add snapshot key in epoch tracker in odsp driver (#21898) #21903
  • [main > release/client/rc5]: Extract serialized blobs from the ISnapshot instead of fetching from driver which could make network calls #21925

Full Changelog: client_v2.0.0-rc.5.0.6...client_v2.0.0-rc.5.0.7

Fluid Framework v2.0.6 (patch)

29 Jul 18:01
96906fd
Compare
Choose a tag to compare

What's Changed

  • [main > release/client/2.0]: Add snapshot key in epoch tracker in odsp driver (#21898) #21904
  • [main > release/client/2.0]: Extract serialized blobs from the ISnapshot instead of fetching from driver which could make network calls #21908 #21924
  • [bump] client: 2.0.5 => 2.0.6 (patch) #21842

Full Changelog: client_v2.0.5...client_v2.0.6

Fluid Framework v2.0.0-rc.4.0.10 (patch)

25 Jul 21:22
bdbf2b5
Compare
Choose a tag to compare

What's Changed

  • [main > release/client/rc]: RemoteDatastoreContext should handle snapshot with groupId with older loader #21950
  • [bump] client: 2.0.0-rc.4.0.9 => 2.0.0-rc.4.0.10 (patch) #21722

Full Changelog: client_v2.0.0-rc.4.0.9...client_v2.0.0-rc.4.0.10

Fluid Framework v2.1.0 (minor)

22 Jul 18:29
bfbef34
Compare
Choose a tag to compare

✨ New Features

Type guards for DDS types

In the 2.0 release of Fluid, the concrete class implementations for DDSes were hidden from Fluid's API surface. This made instanceof checks fail to work correctly. There were ways to work around this in application code, but they involved boilerplate which required more understanding of Fluid internals than should be necessary.

There is now a drop-in replacement to instanceof: the static .is() method to SharedObjectKind, which is available on all DDSes. For example:

// Works in Fluid Framework 1.0 but not in the initial release of Fluid Framework 2.0:
if (myObject instanceof SharedString) {
  // do something
}

// In Fluid Framework 2.1 and beyond, that code can now be written like so:
if (SharedString.is(myObject)) {
  // do something
}

Packages affected

  • @fluidframework/shared-object-base

🌳 SharedTree DDS changes

Using "delete" on tree fields now throws an error instead of not working correctly

TypeScript allows delete on object node optional fields if the exactOptionalPropertyTypes tsconfig setting is not enabled. This does not work correctly at runtime and now produces an informative error.

Packages affected

  • fluid-framework
  • @fluidframework/tree

Detect arrayNode iterator invalidation

When arrayNodes are edited concurrently during iteration, an error will be thrown.

Packages affected

  • @fluidframework/tree
  • fluid-framework

SharedTree content that is removed is now deleted

SharedTree now supports garbage collection so that removed content is not retained forever. This is an internal change and users of SharedTree won't need to adapt any existing code.

This change could cause errors with cross-version collaboration where an older client does not send data that a newer version may need. In this case, a "refresher data not found" error will be thrown.

Packages affected

  • @fluidframework/tree

tree: Improved performance for accessing identifiers in shortId API

Users should see improved performance when calling the Tree.shortId API. Identifier field keys are now cached in the schema for faster access.

Packages affected

  • fluid-framework
  • @fluidframework/tree

Improved error reporting

Several cases of invalid usage patterns for tree APIs have gained improved error reporting, as well as improved documentation on the APIs detailing what usage is supported. These improvements include:

  • Unsupported usages of schema classes: using more than one schema class derived from a single SchemaFactory generated base class. This used to hit internal asserts, but now has a descriptive user-facing UsageError. Most of this work was done in 9fb3dcf.

  • Improved detection of when prior exception may have left SharedTree in an invalid state. These cases now report a UsageError including a reference to the prior exception. This was mainly done in 9fb3dcf and b77d530.

Packages affected

  • fluid-framework
  • @fluidframework/tree

✨ New! Debug visualizers for TreeNodes in NodeJS and browsers

TreeNodes now have custom debug visualizers to improve the debug experience in NodeJS and in browsers. Note that custom formatters must be enabled in the browser developer tools for that visualizer to be used.

Packages affected

  • fluid-framework
  • @fluidframework/tree

🐛 Bug Fixes

tinylicious-client: Promote APIs from beta to public

Some tinylicious-client APIs were marked beta in previous releases. These APIs are now correctly marked public and also sealed to indicate they are not to be implemented externally to Fluid Framework and not changed.

Updated APIs:

Packages affected

  • @fluidframework/tinylicious-client

merge-tree: The Marker.fromJSONObject and TextSegment.fromJSONObject argument types have been corrected

Previously, the arguments of Marker.fromJSONObject and TextSegment.fromJSONObject were of type any. However, at runtime only certain types were expected and using other types would cause errors.

Now, the argument for the Marker implementation is of type IJSONSegment and the argument for the TextSegment implementation is of type string | IJSONSegment. This reflects actual runtime support.

This change should have no impact on existing code unless the code is using incorrect types. Such code already does not function and should be corrected.

Packages affected

  • @fluidframework/merge-tree

Some SharedDirectory/SharedMap-related APIs have been sealed

Note that this is a documentation only change. There is no runtime or type-level impact.

Some top-level APIs within @fluidframework/map and fluid-framework have been updated to reflect their sealed/readonly nature. That is, they are not to be implemented externally to Fluid Framework and not changed. This was already the case, but the documentation was not clear.

Updated APIs:

Packages affected

  • fluid-framework
  • @fluidframework/map

🛠️ Start Building Today!

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

build-tools v0.41.0 (minor)

25 Jul 22:16
115c8f4
Compare
Choose a tag to compare

This is a minor release.