Dependency updates only.
Dependency updates only.
Dependency updates only.
-
@fluidframework/react no longer supports CommonJS (#26575) 995c1e44aad
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.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
-
The exports of @fluid-experimental/tree-react-api have been moved to the new @fluidframework/react package and placed under its /alpha exports (#25542) b388c7b7f1
@fluid-experimental/tree-react-apihas been adjusted to align with Fluid Framework's API Support Levels. It has been renamed to@fluidframework/reactand all existing APIs are now available under@fluidframework/react/alpha.Since this package was under
@fluid-experimental, previously it implicitly made no guarantees. Now all the APIs are@alpha, which also amounts to making no guarantees but makes it possible to promote APIs to@betain the future to offer some stability.To accommodate this change, all users of this package will need to adjust:
- Package dependencies from
"@fluid-experimental/tree-react-api"to"@fluidframework/react". - Imports from
"@fluid-experimental/tree-react-api"to"@fluidframework/react/alpha".
- Package dependencies from
-
Added APIs for tracking observations of SharedTree content for automatic invalidation (#25459) 21d45d5948
TreeAlpha.trackObservationsandTreeAlpha.trackObservationsOncehave been added. These provide a way to run some operation which reads content from TreeNodes, then run a call back when anything observed by that operation changes.This functionality has also been exposed in the form of React hooks and React higher order components via the
@fluid-experimental/tree-react-apipackage. It is now possible to use these utilities to implement React applications which pass TreeNodes in their props and get all necessary invalidation from tree changes handled automatically. The recommended pattern for doing this is to usetreeDataObjectorTreeViewComponentat the root, thenwithTreeObservationsorwithMemoizedTreeObservationsfor any sub-components which read from TreeNodes. Alternatively more localized changes can be made by usingPropNodeto type erase TreeNodes passed in props, then use one of theusePropTreeNodeorusePropTreeRecordhooks to read from them.These APIs work with both hydrated and un-hydrated TreeNodes.
Here is a simple example of a React components which has an invalidation bug due to reading a mutable field from a TreeNode that was provided in a prop:
const builder = new SchemaFactory("example"); class Item extends builder.object("Item", { text: SchemaFactory.string }) {} const ItemComponentBug = ({ item }: { item: Item }): JSX.Element => ( <span>{item.text}</span> // Reading `text`, a mutable value from a React prop, causes an invalidation bug. );
This bug can now easily be fixed using
withTreeObservationsorwithMemoizedTreeObservations:const ItemComponent = withTreeObservations( ({ item }: { item: Item }): JSX.Element => <span>{item.text}</span>, );
For components which take in TreeNodes, but merely forward them and do not read their properties, they can use
PropTreeNodeas shown:const ItemParentComponent = ({ item }: { item: PropTreeNode<Item> }): JSX.Element => ( <ItemComponent item={item} /> );
If such a component reads from the TreeNode, it gets a compile error instead of an invalidation bug. In this case the invalidation bug would be that if
item.textis modified, the component would not re-render.const InvalidItemParentComponent = ({ item, }: { item: PropTreeNode<Item> }): JSX.Element => ( // @ts-expect-error PropTreeNode turns this invalidation bug into a compile error <span>{item.text}</span> );
To provide access to TreeNode content in only part of a component the
usePropTreeNodeorusePropTreeRecordhooks can be used.Here is a rather minimal example of how
TreeAlpha.trackObservationsOncecan be used:cachedFoo ??= TreeAlpha.trackObservationsOnce( () => { cachedFoo = undefined; }, () => nodeA.someChild.bar + nodeB.someChild.baz, ).result;
That is equivalent to doing the following:
if (cachedFoo === undefined) { cachedFoo = nodeA.someChild.bar + nodeB.someChild.baz; const invalidate = (): void => { cachedFoo = undefined; for (const u of unsubscribe) { u(); } }; const unsubscribe: (() => void)[] = [ TreeBeta.on(nodeA, "nodeChanged", (data) => { if (data.changedProperties.has("someChild")) { invalidate(); } }), TreeBeta.on(nodeB, "nodeChanged", (data) => { if (data.changedProperties.has("someChild")) { invalidate(); } }), TreeBeta.on(nodeA.someChild, "nodeChanged", (data) => { if (data.changedProperties.has("bar")) { invalidate(); } }), TreeBeta.on(nodeB.someChild, "nodeChanged", (data) => { if (data.changedProperties.has("baz")) { invalidate(); } }), ]; }
Here is more complete example showing how to use
TreeAlpha.trackObservationsOnceinvalidate a property derived from its tree fields.const factory = new SchemaFactory("com.example"); class Vector extends factory.object("Vector", { x: SchemaFactory.number, y: SchemaFactory.number, }) { #length: number | undefined = undefined; public length(): number { if (this.#length === undefined) { const result = TreeAlpha.trackObservationsOnce( () => { this.#length = undefined; }, () => Math.hypot(this.x, this.y), ); this.#length = result.result; } return this.#length; } } const vec = new Vector({ x: 3, y: 4 }); assert.equal(vec.length(), 5); vec.x = 0; assert.equal(vec.length(), 4);
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
-
New experimental objectIdNumber API (#21115) df2f139be8
A new
objectIdNumberhas been added, which is useful when you need an identifier which corresponds to an object identity. For example: when specifying a React "key" that corresponds to aTreeNode.
Dependency updates only.
Dependency updates only.
Dependency updates only.
-
Simplify experimental tree data object implementation (#23943) 00a56b79b3
The experimental tree data object in
tree-react-apihas been simplified in a way that is incompatible with its previous version, which usedSharedDirectoryat the root. The library now leverages a new data object that uses theSharedTreedirectly at the root. In addition to breaking compatibility with existing documents, these changes include some related simplifications to the APIs which are also breaking:- Removes the
keyproperty from the data object configuration. This key was used to inform where the SharedTree was parented beneath the root SharedDirectory, so it no longer serves a purpose. - Inlined the
ITreeDataObjectinterface intoIReactTreeDataObject.
- Removes the
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
Dependency updates only.
-
Update to TypeScript 5.4 (#21214) 0e6256c722
Update package implementations to use TypeScript 5.4.5.