Releases: microsoft/FluidFramework
Fluid Framework v2.5.0 (minor)
Contents
- ✨ New Features
- 🌳 SharedTree DDS changes
- ✨ New! Alpha APIs for tree data import and export (#22566)
- Typing has been improved when an exact TypeScript type for a schema is not provided (#22763)
- A
.schema
member has been added to the alpha enum schema APIs (#22874) - The strictness of input tree types when inexact schemas are provided has been improved (#22874)
- TreeNodeSchemaClass now specifies its TNode as TreeNode (#22938)
- Array and Map nodes can now be explicitly constructed with undefined or no argument (#22946)
- SharedTree branching API has been improved (#22970)
- 🐛 Bug Fixes
⚠️ Deprecations- Other Changes
✨ New Features
ISessionClient now exposes connectivity information (#22973)
ISessionClient
has a new method,getConnectionStatus()
, with two possible states:Connected
andDisconnected
.ISessionClient
'sconnectionId()
member has been renamed togetConnectionId()
for consistency.IPresence
eventattendeeDisconnected
is now implemented.
Change details
Commit: 6096657
Affected packages:
- @fluid-experimental/presence
🌳 SharedTree DDS changes
✨ New! Alpha APIs for tree data import and export (#22566)
A collection of new @alpha
APIs for importing and exporting tree content and schema from SharedTrees has been added to TreeAlpha
. These include import and export APIs for VerboseTree
, ConciseTree
and compressed tree formats.
TreeAlpha.create
is also added to allow constructing trees with a more general API instead of having to use the schema constructor directly (since that doesn't handle polymorphic roots, or non-schema aware code).
The function independentInitializedView
has been added to provide a way to combine data from the existing extractPersistedSchema
and new TreeAlpha.exportCompressed
back into a TreeView
in a way which can support safely importing data which could have been exported with a different schema. This allows replicating the schema evolution process for Fluid documents stored in a service, but entirely locally without involving any collaboration services. independentView
has also been added, which is similar but handles the case of creating a new view without an existing schema or tree.
Together these APIs address several use-cases:
- Using SharedTree as an in-memory non-collaborative datastore.
- Importing and exporting data from a SharedTree to and from other services or storage locations (such as locally saved files).
- Testing various scenarios without relying on a service.
- Using SharedTree libraries for just the schema system and encode/decode support.
Change details
Commit: 18a23e8
Affected packages:
- fluid-framework
- @fluidframework/tree
Typing has been improved when an exact TypeScript type for a schema is not provided (#22763)
The Tree APIs are designed to be used in a strongly typed way, with the full TypeScript type for the schema always being provided. Due to limitations of the TypeScript language, there was no practical way to prevent less descriptive types, like TreeNodeSchema
or ImplicitFieldSchema
, from being used where the type of a specific schema was intended. Code which does this will encounter several issues with tree APIs, and this change fixes some of those issues. This change mainly fixes that NodeFromSchema<TreeNodeSchema>
used to return unknown
and now returns TreeNode | TreeLeafValue
.
This change by itself seems mostly harmless, as it just improves the precision of the typing in this one edge case. Unfortunately, there are other typing bugs which complicate the situation, causing APIs for inserting data into the tree to also behave poorly when given non-specific types like TreeNodeSchema
. These APIs include cases like TreeView.initialize
.
This incorrectly allowed some usage like taking a type-erased schema and initial tree pair, creating a view of type TreeView<ImplicitFieldSchema>
, then initializing it. With the typing being partly fixed, some unsafe inputs are still allowed when trying to initialize such a view, but some are now prevented.
This use-case of modifying trees in code not that is not strongly typed by the exact schema was not intended to be supported. Despite this, it did mostly work in some cases, and has some real use-cases (like tests looping over test data consisting of pairs of schema and initial trees). To help mitigate the impact of this change, some experimental @alpha
APIs have been introduced to help address these previously unsupported but somewhat working use-cases.
Before this change:
import { TinyliciousClient } from "@fluidframework/tinylicious-client";
import {
SchemaFactory,
SharedTree,
TreeViewConfiguration,
type TreeNodeSchema,
} from "fluid-framework";
// Create a ITree instance
const tinyliciousClient = new TinyliciousClient();
const { container } = await tinyliciousClient.createContainer(
{ initialObjects: {} },
"2",
);
const tree = await container.create(SharedTree);
const schemaFactory = new SchemaFactory("demo");
// Bad: This loses the schema aware type information. `: TreeNodeSchema` should be omitted to preserve strong typing.
const schema: TreeNodeSchema = schemaFactory.array(schemaFactory.number);
const config = new TreeViewConfiguration({ schema });
// This view is typed as `TreeView<TreeNodeSchema>`, which does not work well since it's missing the actual schema type information.
const view = tree.viewWith(config);
// Root is typed as `unknown` allowing invalid assignment operations.
view.root = "invalid";
view.root = {};
// Since all assignments are allowed, valid ones still work:
view.root = [];
After this change:
// Root is now typed as `TreeNode | TreeLeafValue`, still allowing some invalid assignment operations.
// In the future this should be prevented as well, since the type of the setter in this case should be `never`.
view.root = "invalid";
// This no longer compiles:
view.root = {};
// This also no longer compiles despite being valid at runtime:
view.root = [];
For code that wants to continue using an unsafe API, which can result in runtime errors if the data does not follow the schema, a new alternative has been added to address this use-case. A special type UnsafeUnknownSchema
can now be used to opt into allowing all valid trees to be provided. Note that this leaves ensuring the data is in schema up to the user. For now these adjusted APIs can be accessed by casting the view to TreeViewAlpha<UnsafeUnknownSchema>
. If stabilized, this option will be added to TreeView
directly.
const viewAlpha = view as TreeViewAlpha<UnsafeUnknownSchema>;
viewAlpha.initialize([]);
viewAlpha.root = [];
Additionally, this seems to have negatively impacted co-recursive schema which declare a co-recursive array as the first schema in the co-recursive cycle. Like the TypeScript language our schema system is built on, we don't guarantee exactly which recursive type will compile, but will do our best to ensure useful recursive schema can be created easily. In this case a slight change may be required to some recursive schema to get them to compile again:
For example this schema used to compile:
class A extends sf.arrayRecursive("A", [() =>...
Fluid Framework v2.4.0 (minor)
Contents
- 🌳 SharedTree DDS changes
- ✨ New! Alpha SharedTree branching APIs (#22550)
- ✨ New! Alpha API for providing SharedTree configuration options (#22701)
- ✨ New! Alpha APIs for producing SharedTree schema from enums (#20035)
- ✨ New! Alpha API for snapshotting Schema (#22733)
- Expose the view schema from the TreeView interface (#22547)
- Metadata can now be associated with Field Schema (#22564)
- Unhydrated SharedTree nodes now emit change events when edited (#22661)
- Non-leaf field access has been optimized (#22717)
- 🐛 Bug Fixes
⚠️ Deprecations
🌳 SharedTree DDS changes
✨ New! Alpha SharedTree branching APIs (#22550)
Several APIs have been added to allow for creating and coordinating "version-control"-style branches of the SharedTree. Use the getBranch
entry point function to acquire a branch. For example:
function makeEditOnBranch(mainView: TreeView<typeof MySchema>) {
mainView.root.myData = 3;
const mainBranch = getBranch(mainView); // This function accepts either a view of a SharedTree (acquired e.g. via `sharedTree.viewWith(...)`) or a `SharedTree` directly.
const forkBranch = mainBranch.branch(); // This creates a new branch based on the existing branch.
const forkView = forkBranch.viewWith(
new TreeViewConfiguration({ schema: MySchema }),
); // Acquire a view of the forked branch in order to read or edit its tree.
forkView.root.myData = 4; // Set the value on the fork branch to be 4. The main branch still has a value of 3.
mainBranch.merge(forkBranch); // Merging the fork changes into the main branch causes the main branch to have a value of 4.
// Note: The main branch (and therefore, also the `forkView`) is automatically disposed by the merge.
// To prevent this, use `mainBranch.merge(forkBranch, false)`.
}
Merging any number of commits into a target branch (via the TreeBranch.merge
method) generates a revertible for each commit on the target branch. See #22644 for more information about revertible support in the branching APIs.
Change details
Commit: 8f4587c
Affected packages:
- fluid-framework
- @fluidframework/tree
✨ New! Alpha API for providing SharedTree configuration options (#22701)
A new alpha configuredSharedTree
had been added. This allows providing configuration options, primarily for debugging, testing and evaluation of upcoming features. The resulting configured SharedTree
object can then be used in-place of the regular SharedTree
imported from fluid-framework
.
import {
ForestType,
TreeCompressionStrategy,
configuredSharedTree,
typeboxValidator,
} from "@fluid-framework/alpha";
// Maximum debuggability and validation enabled:
const SharedTree = configuredSharedTree({
forest: ForestType.Expensive,
jsonValidator: typeboxValidator,
treeEncodeType: TreeCompressionStrategy.Uncompressed,
});
// Opts into the under development optimized tree storage planned to be the eventual default implementation:
const SharedTree = configuredSharedTree({
forest: ForestType.Optimized,
});
Change details
Commit: 40d3648
Affected packages:
- fluid-framework
- @fluidframework/tree
✨ New! Alpha APIs for producing SharedTree schema from enums (#20035)
adaptEnum
and enumFromStrings
have been added to @fluidframework/tree/alpha
and fluid-framework/alpha
. These unstable alpha APIs are relatively simple helpers on-top of public APIs (source: schemaCreationUtilities.ts): thus if these change or stable alternatives are needed, an application can replicate this functionality using these implementations as an example.
Change details
Commit: 5f9bbe0
Affected packages:
- fluid-framework
- @fluidframework/tree
✨ New! Alpha API for snapshotting Schema (#22733)
extractPersistedSchema
can now be used to extra a JSON-compatible representation of the subset of a schema that gets stored in documents. This can be used write tests which snapshot an applications schema. Such tests can be used to detect schema changes which could would impact document compatibility, and can be combined with the new comparePersistedSchema
to measure what kind of compatibility impact the schema change has.
Change details
Commit: 920a65f
Affected packages:
- fluid-framework
- @fluidframework/tree
Expose the view schema from the TreeView interface (#22547)
Users of TreeView can now access the type-safe view schema directly on the view object via TreeView.schema
. This allows users to avoid passing the schema around in addition to the view in scenarios where both are needed. It also avoids scenarios in which code wants to accept both a view and its schema and thus must constrain both to be of the same schema type.
Change details
Commit: 2aa29d9
Affected packages:
- @fluidframework/tree
Metadata can now be associated with Field Schema (#22564)
Users of TreeView can now specify metadata when creating Field Schema. This includes system-understood metadata, i.e., description
.
Example:
class Point extends schemaFactory.object("Point", {
x: schemaFactory.required(schemaFactory.number, {
metadata: { description: "The horizontal component of the point." },
}),
y: schemaFactory.required(schemaFactory.number, {
metadata: { description: "The vertical component of the point." },
}),
}) {}
Functionality like the experimental conversion of Tree Schema to JSON Schema (getJsonSchema
) can leverage such system-understood metadata to generate useful information. In the case of the description
property, this is mapped directly to the description
property supported by JSON Schema.
Custom, user-defined properties can also be specified. These properties will not be leveraged by the system by default, but can be used as a handy means of associating common application-specific properties with Field Schema.
Example:
An application is implementing search functionality. By default, the app author wishes for all app content to be indexable by search, unless otherwise specified. They can leverage schema metadata to decorate fields that should be ignored by search, and leverage that information when walking the tree during a search.
interface AppMetadata {
/**
* Whether or not the field should be ignored by search.
* @defaultValue `false`
*/
searchIgnore?: boolean;
}
class Note extends schemaFactory.object("Note", {
position: schemaFactory.required(Point, {
metadata: {
description: "The position of the upper-left cor...
build-tools v0.49.0 (minor)
This is a minor release.
build-tools v0.48.0 (minor)
This is a minor release.
build-tools v0.47.0 (minor)
This is a minor release.
Fluid Framework v2.3.1 (patch)
What's Changed
- [bump] client: 2.3.0 => 2.3.1 (patch)
#22690
- [main > release/client/2.3]: Handle Location redirection for getSharingInformation call (#22551)
#22619
- [port 2.3]: Avoid two leading slashes in the request to create a new file (#22563)
#22591
- fix(release/client/2.3): Update version argument in package promotion command to correct parameter
#22584
Full Changelog: client_v2.3.0...client_v2.3.1
Fluid Framework v2.2.2 (patch)
What's Changed
- [v2.2] Port #22508 and prereqs (ContainerRuntime: Process incoming batches op-by-op instead of waiting for the whole batch)
#22654
- [main > release/client/2.2]: Handle Location redirection for getSharingInformation call (#22551)
#22620
- [port 2.2]: Avoid two leading slashes in the request to create a new file (#22563)
#22590
- Manually bump client release branch from 2.2.1 to 2.2.2
#22573
Full Changelog: client_v2.2.1...client_v2.2.2
Fluid Framework v2.1.2 (patch)
What's Changed
- [main > release/client/2.1]: Handle Location redirection for getSharingInformation call (#22551)
#22621
- [port 2.1]: Avoid two leading slashes in the request to create a new file (#22563)
#22589
- Manually bump client release branch from 2.1.1 to 2.1.2
#22571
Full Changelog: client_v2.1.1...client_v2.1.2
Fluid Framework v2.0.9 (patch)
What's Changed
- [main > release/client/2.0]: Handle Location redirection for getSharingInformation call (#22551)
#22622
- [bump] client: 2.0.8 => 2.0.9 (patch)
#22606
Full Changelog: client_v2.0.8...client_v2.0.9
Fluid Framework v2.0.0-rc.5.0.8 (patch)
What's Changed
- [main > release/client/rc.5.0]: Handle Location redirection for getSharingInformation call (#22551)
#22577
- [Port 2.0.0-rc.5.0] Hide part of code behind feature flag (#22529)
#22534
- [bump] client: 2.0.0-rc.5.0.7 => 2.0.0-rc.5.0.8 (patch)
#22034
Full Changelog: client_v2.0.0-rc.5.0.7...client_v2.0.0-rc.5.0.8