Skip to content

Releases: microsoft/FluidFramework

Fluid Framework v2.12.0 (minor)

17 Dec 21:44
f1be6e3
Compare
Choose a tag to compare

Contents

✨ New Features

New APIs to create and load containers without using the Loader object (#22902)

Overview

Provide standalone APIs to create and load containers instead of using the Loader object to do so. Before, hosts were supposed to create the Loader object first and then call methods on it to create and load containers. Now they can just utilize these APIs directly and get rid of the Loader object.

Use createDetachedContainer to create a detached container
export async function createDetachedContainer(
  createDetachedContainerProps: ICreateDetachedContainerProps,
): Promise<IContainer> {}

ICreateDetachedContainerProps are the properties that need to be supplied to the above API and include props like URL Resolver, IDocumentServiceFactory, etc., which were previously used to create the Loader object.

Use loadExistingContainer to load an existing container
export async function loadExistingContainer(
  loadExistingContainerProps: ILoadExistingContainerProps,
): Promise<IContainer> {}

ILoadExistingContainerProps are the properties that need to be supplied to the above API and include props like URL Resolver, IDocumentServiceFactory, etc., which were earlier used to create the Loader object.

Use rehydrateDetachedContainer to create a detached container from a serializedState of another container
export async function rehydrateDetachedContainer(
  rehydrateDetachedContainerProps: IRehydrateDetachedContainerProps,
): Promise<IContainer> {}

IRehydrateDetachedContainerProps are the properties that need to be supplied to the above API and include props like URL Resolver, IDocumentServiceFactory, etc., which were earlier used to create the Loader object.

Note on ICreateAndLoadContainerProps.

The props which were used to create the Loader object are now moved to the ICreateAndLoadContainerProps interface. ICreateDetachedContainerProps, ILoadExistingContainerProps and IRehydrateDetachedContainerProps which extends ICreateAndLoadContainerProps also contain some additional props which will be used to create and load containers like IFluidCodeDetails, IRequest, etc. Previously these were directly passed when calling APIs like Loader.createDetachedContainer, Loader.resolve and Loader.rehydrateDetachedContainerFromSnapshot on the Loader object. Also, ILoaderProps.ILoaderOptions are now replaced with ICreateAndLoadContainerProps.IContainerPolicies since there will be no concept of Loader.

Change details

Commit: 51a1728

Affected packages:

  • @fluidframework/azure-client
  • @fluidframework/container-definitions
  • @fluidframework/container-loader
  • @fluidframework/fluid-runner
  • @fluidframework/odsp-client
  • @fluid-experimental/property-dds
  • @fluid-private/test-end-to-end-tests
  • @fluidframework/test-utils
  • @fluidframework/tinylicious-client
  • @fluidframework/tree

⬆️ Table of contents

⚠️ Deprecations

SummarizerStopReason, ISummarizeEventProps, and ISummarizerEvents are now deprecated (#23217)

SummarizerStopReason, ISummarizeEventProps, and ISummarizerEvents have all been deprecated from the "@fluidframework/container-runtime" package. Please migrate all uses of these APIs to their counterparts in the "@fluidframework/container-runtime-definitions" package.

Change details

Commit: cd88ee2

Affected packages:

  • @fluidframework/container-runtime

⬆️ Table of contents

IContainerRuntimeOptions.enableGroupedBatching is now deprecated (#23260)

The IContainerRuntimeOptions.enableGroupedBatching property is deprecated and will be removed in version 2.20.0. This will mean that the grouped batching feature can no longer be disabled. In versions 2.20.0 and beyond, grouped batching is required for the proper functioning of the Fluid Framework.

The sole case where grouped batching will be disabled is for compatibility with older v1 clients, and this will be implemented without any need for the configurable IContainerRuntimeOptions.enableGroupedBatching option.

Change details

Commit: 49d8e75

Affected packages:

  • @fluidframework/container-runtime
  • @fluidframework/fluid-static

⬆️ Table of contents

IContainerRuntimeOptions.flushMode is now deprecated (#23288)

The IContainerRuntimeOptions.flushMode property is deprecated and will be removed in version 2.20.0.

Only the default value FlushMode.TurnBased is supported when calling ContainerRuntime.loadRuntime directly, so there's no need for consumers to pass this option in.

Change details

Commit: af1cd7b

Affected packages:

  • @fluidframework/container-runtime

⬆️ Table of contents

Merge-Tree and SharedString ISegment Deprecations (#23323)

The current ISegment interface over-exposes a number of properties which do not have an external use case, and any external usage could result in damage to the underlying merge-tree including data corruption.

The only use case that will continue to be supported is determining if a segment is removed. For this purpose we've added the free function segmentIsRemoved(segment: ISegment): boolean.

For example, checking if a segment is not removed would change as follows:

- if(segment.removedSeq === undefined){
+ if(!segmentIsRemoved(segment)){

The following properties are deprecated on ISegment and its implementations:

  • clientId
  • index
  • localMovedSeq
  • localRefs
  • localRemovedSeq
  • localSeq
  • movedClientsIds
  • movedSeq
  • movedSeqs
  • ordinal
  • removedClientIds
  • removedSeq
  • seq
  • wasMovedOnInsert

Additionally, the following types are also deprecated, and will become internal (i.e. users of the Fluid Framework will not have access to them):

  • IMergeNodeCommon
  • IMoveInfo
  • IRemovalInfo
  • LocalReferenceCollection

Change details

Commit: e8762e3

Affected packages:

  • @fluidframework/merge-tree
  • @fluidframework/sequence

⬆️ Table of contents

The ContainerRuntime class is now deprecated (#23331)

The class ContainerRuntime is deprecated and will no longer be exported starting in version 2.20.0.

There are two possible migration paths to stop using ContainerRuntime:

  • When using it as a type, replace it with an interface like IContainerRuntime
  • When using the static function ContainerRuntime.loadRuntime replace it with the free function loadContainerRuntime.

BaseContainerRuntimeFactory has some changes as well, since it exposed ContainerRuntime in several function signatures:

  • instantiateFirstTime - Takes the wider type IContainerRuntime instead of ContainerRuntime
  • instantiateFromExisting - Takes the wider type IContainerRuntime instead of ContainerRuntime
  • preInitialize - deprecated as well, since it returns ContainerRuntime

These functions should never be called directly anyway - use `BaseContai...

Read more

Fluid Framework v2.11.0 (minor)

03 Dec 01:03
a6b1b73
Compare
Choose a tag to compare

Contents

✨ New Features

Synchronous Child Datastore Creation (#23143)

Overview

This feature introduces a new pattern for creating datastores synchronously within the Fluid Framework. It allows for the synchronous creation of a child datastore from an existing datastore, provided that the child datastore is available synchronously via the existing datastore's registry and that the child's factory supports synchronous creation. This method also ensures strong typing for the consumer.

In this context, "child" refers specifically to the organization of factories and registries, not to any hierarchical or hosting relationship between datastores. The parent datastore does not control the runtime behaviors of the child datastore beyond its creation.

The synchronous creation of child datastores enhances the flexibility of datastore management within the Fluid Framework. It ensures type safety and provides a different way to manage datastores within a container. However, it is important to consider the overhead associated with datastores, as they are stored, summarized, garbage collected, loaded, and referenced independently. This overhead should be justified by the scenario's requirements.

Datastores offer increased capabilities, such as the ability to reference them via handles, allowing multiple references to exist and enabling those references to be moved, swapped, or changed. Additionally, datastores are garbage collected after becoming unreferenced, which can simplify final cleanup across clients. This is in contrast to subdirectories in a shared directory, which do not have native capabilities for referencing or garbage collection but are very low overhead to create.

Synchronous creation relies on both the factory and the datastore to support it. This means that asynchronous operations, such as resolving handles, some browser API calls, consensus-based operations, or other asynchronous tasks, cannot be performed during the creation flow. Therefore, synchronous child datastore creation is best limited to scenarios where the existing asynchronous process cannot be used, such as when a new datastore must be created in direct response to synchronous user input.

Key Benefits

  • Synchronous Creation: Allows for the immediate creation of child datastores without waiting for asynchronous operations.
  • Strong Typing: Ensures type safety and better developer experience by leveraging TypeScript's type system.

Use Cases

Example 1: Creating a Child Datastore

In this example, we demonstrate how to support creating a child datastore synchronously from a parent datastore.

/**
 * This is the parent DataObject, which is also a datastore. It has a
 * synchronous method to create child datastores, which could be called
 * in response to synchronous user input, like a key press.
 */
class ParentDataObject extends DataObject {
  createChild(name: string): ChildDataStore {
    assert(
      this.context.createChildDataStore !== undefined,
      "this.context.createChildDataStore",
    );

    const { entrypoint } = this.context.createChildDataStore(
      ChildDataStoreFactory.instance,
    );
    const dir = this.root.createSubDirectory("children");
    dir.set(name, entrypoint.handle);
    entrypoint.setProperty("childValue", name);

    return entrypoint;
  }

  getChild(name: string): IFluidHandle<ChildDataStore> | undefined {
    const dir = this.root.getSubDirectory("children");
    return dir?.get<IFluidHandle<ChildDataStore>>(name);
  }
}

For a complete example see the following test: https://github.com/microsoft/FluidFramework/blob/main/packages/test/local-server-tests/src/test/synchronousDataStoreCreation.spec.ts

Change details

Commit: 3426b43

Affected packages:

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

⬆️ Table of contents

Presence-related events now support the off event deregistration pattern (#23196)

Event subscriptions within @fluidframework/presence may now use off to deregister event listeners, including initial listeners provided to Notifications.

Some type names have shifted within the API though no consumers are expected to be using those types directly. The most visible rename is NotificationSubscribable to NotificationListenable. Other shifts are to use types now exported through @fluidframework/core-interfaces where the most notable is ISubscribable that is now Listenable.

Change details

Commit: f7be965

Affected packages:

  • @fluidframework/presence

⬆️ Table of contents

Presence updates are now grouped and throttled (#23075)

Presence updates are grouped together and throttled to prevent flooding the network with messages when presence values are rapidly updated. This means the presence infrastructure will not immediately broadcast updates but will broadcast them after a configurable delay.

The allowableUpdateLatencyMs property configures how long a local update may be delayed under normal circumstances, enabling grouping with other updates. The default allowableUpdateLatencyMs is 60 milliseconds but may be (1) specified during configuration of a States Workspace or Value Manager and/or (2) updated later using the controls member of a Workspace or Value Manager. The States Workspace configuration applies when a Value Manager does not have its own setting.

Notifications are never queued; they effectively always have an allowableUpdateLatencyMs of 0. However, they may be grouped with other updates that were already queued.

Note that due to throttling, clients receiving updates may not see updates for all values set by another. For example, with Latest*ValueManagers, the only value sent is the value at the time the outgoing grouped message is sent. Previous values set by the client will not be broadcast or seen by other clients.

Example

You can configure the grouping and throttling behavior using the allowableUpdateLatencyMs property as in the following example:

// Create and configure a states workspace
const stateWorkspace = presence.getStates(
  "app:v1states",
  {
    // This value manager has an allowable latency of 100ms.
    position: Latest({ x: 0, y: 0 }, { allowableUpdateLatencyMs: 100 }),
    // This value manager uses the workspace default allowable latency of 60ms.
    count: Latest({ num: 0 }),
  },
  // Set the default allowable latency for all value managers in this workspace to 200ms,
  // overriding the default value of 60ms.
  { allowableUpdateLatencyMs: 200 },
);

// Temporarily set count updates to send as soon as possible.
const countState = stateWorkspace.props.count;
countState.controls.allowableUpdateLatencyMs = 0;
countState.local = { num: 5000 };

// Reset the update latency to the workspace default of 60ms.
countState.controls.allowableUpdateLatencyMs = undefined;

Change details

Commit: abde76d

Affected packages:

  • @fluidframework/presence

⬆️ Table of contents

🌳 SharedTree DDS Changes

✨ New! Alpha APIs for indexing (#22491)

SharedTree now supports indexing via two new APIs, createSimpleTreeIndex and createIdentifierIndex.

createSimpleTreeIndex is used to create a `SimpleTre...

Read more

Fluid Framework v2.10.0 (minor)

19 Nov 05:04
50cb876
Compare
Choose a tag to compare

Contents

✨ New Features

New compareFluidHandle function for comparing FluidHandles (#22997)

The new compareFluidHandle function has been added to allow comparing handles without having to inspect their internals.

Change details

Commit: 8d47008

Affected packages:

  • @fluidframework/runtime-utils

⬆️ Table of contents

SharedString DDS annotateAdjustRange (#22751)

This update introduces a new feature to the SharedString DDS, allowing for the adjustment of properties over a specified range. The annotateAdjustRange method enables users to apply adjustments to properties within a given range, providing more flexibility and control over property modifications.

An adjustment is a modification applied to a property value within a specified range. Adjustments can be used to increment or decrement property values dynamically. They are particularly useful in scenarios where property values need to be updated based on user interactions or other events. For example, in a rich text editor, adjustments can be used for modifying indentation levels or font sizes, where multiple users could apply differing numerical adjustments.

Key Features and Use Cases:

  • Adjustments with Constraints: Adjustments can include optional minimum and maximum constraints to ensure the final value falls within specified bounds. This is particularly useful for maintaining consistent formatting in rich text editors.
  • Consistent Property Changes: The feature ensures that property changes are consistent, managing both local and remote changes effectively. This is essential for collaborative rich text editing where multiple users may be making adjustments simultaneously.
  • Rich Text Formatting: Adjustments can be used to modify text properties such as font size, indentation, or other formatting attributes dynamically based on user actions.

Configuration and Compatibility Requirements:

This feature is only available when the configuration Fluid.Sequence.mergeTreeEnableAnnotateAdjust is set to true. Additionally, all collaborating clients must have this feature enabled to use it. If any client does not have this feature enabled, it will lead to the client exiting collaboration. A future major version of Fluid will enable this feature by default.

Usage Example:

sharedString.annotateAdjustRange(start, end, {
  key: { value: 5, min: 0, max: 10 },
});

Change details

Commit: d54b9dd

Affected packages:

  • fluid-framework
  • @fluidframework/merge-tree
  • @fluidframework/sequence
  • @fluidframework/undo-redo

⬆️ Table of contents

🌳 SharedTree DDS Changes

Provide more comprehensive replacement to the commitApplied event (#22977)

Adds a new changed event to the (currently alpha) TreeBranchEvents that replaces the commitApplied event on TreeViewEvents. This new event is fired for both local and remote changes and maintains the existing functionality of commitApplied that is used for obtaining Revertibles.

Change details

Commit: e51c94d

Affected packages:

  • @fluidframework/tree

⬆️ Table of contents

SharedTree event listeners that implement Listenable now allow deregistration of event listeners via an off() function. (#23046)

The ability to deregister events via a callback returned by on() remains the same. Both strategies will remain supported and consumers of SharedTree events may choose which method of deregistration they prefer in a given instance.

// The new behavior
function deregisterViaOff(view: TreeView<MySchema>): {
	const listener = () => { /* ... */ };
	view.events.on("commitApplied", listener); // Register
	view.events.off("commitApplied", listener); // Deregister
}

// The existing behavior (still supported)
function deregisterViaCallback(view: TreeView<MySchema>): {
	const off = view.events.on("commitApplied", () => { /* ... */ }); // Register
	off(); // Deregister
}

Change details

Commit: c59225d

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

Allow constructing recursive maps from objects (#23070)

Previously only non-recursive maps could be constructed from objects. Now all maps nodes can constructed from objects:

class MapRecursive extends sf.mapRecursive("Map", [() => MapRecursive]) {}
{
  type _check = ValidateRecursiveSchema<typeof MapRecursive>;
}
// New:
const fromObject = new MapRecursive({ x: new MapRecursive() });
// Existing:
const fromIterator = new MapRecursive([["x", new MapRecursive()]]);
const fromMap = new MapRecursive(new Map([["x", new MapRecursive()]]));
const fromNothing = new MapRecursive();
const fromUndefined = new MapRecursive(undefined);

Change details

Commit: 0185a08

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

Fix typing bug in adaptEnum and enumFromStrings (#23077)

When using the return value from adaptEnum as a function, passing in a value who's type is a union no longer produced an incorrectly typed return value. This has been fixed.

Additionally enumFromStrings has improved the typing of its schema, ensuring the returned object's members have sufficiently specific types. Part of this improvement was fixing the .schema property to be a tuple over each of the schema where it was previously a tuple of a single combined schema due to a bug.

One side-effect of these fixes is that narrowing of the value field of a node typed from the .schema behaves slightly different, such that the node type is now a union instead of it being a single type with a .value that is a union. This means that narrowing based on .value property narrows which node type you have, not just the value property. This mainly matters when matching all c...

Read more

Fluid Framework v2.5.0 (minor)

05 Nov 07:33
54f2a18
Compare
Choose a tag to compare

Contents

✨ New Features

ISessionClient now exposes connectivity information

  1. ISessionClient has a new method, getConnectionStatus(), with two possible states: Connected and Disconnected. (#22833)

  2. ISessionClient's connectionId() member has been renamed to getConnectionId() for consistency. (#22973)

  3. IPresence event attendeeDisconnected is now implemented. (#22833)

Change details

Commits: aaece3, 6096657

Affected packages:

  • @fluid-experimental/presence

⬆️ Table of contents

🌳 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:

  1. Using SharedTree as an in-memory non-collaborative datastore.
  2. Importing and exporting data from a SharedTree to and from other services or storage locations (such as locally saved files).
  3. Testing various scenarios without relying on a service.
  4. Using SharedTree libraries for just the schema system and encode/decode support.

Change details

Commit: 18a23e8

Affected packages:

  • fluid-framework
  • @fluidframework/tree

⬆️ Table of contents

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 ...

Read more

Fluid Framework v2.4.0 (minor)

15 Oct 18:10
ffa02b5
Compare
Choose a tag to compare

Contents

🌳 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

⬆️ Table of contents

✨ 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

⬆️ Table of contents

✨ 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

⬆️ Table of contents

✨ 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

⬆️ Table of contents

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

⬆️ Table of contents

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...
Read more

build-tools v0.49.0 (minor)

15 Oct 16:51
3d5cbdc
Compare
Choose a tag to compare

This is a minor release.

build-tools v0.48.0 (minor)

15 Oct 16:50
7a7263c
Compare
Choose a tag to compare

This is a minor release.

build-tools v0.47.0 (minor)

08 Oct 16:56
ad35a7c
Compare
Choose a tag to compare

This is a minor release.

Fluid Framework v2.3.1 (patch)

01 Oct 22:58
b98a1b4
Compare
Choose a tag to compare

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)

01 Oct 22:52
567feff
Compare
Choose a tag to compare

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