@fluidframework/react 0.41.4 → 2.63.0-358419
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +11 -0
- package/.mocharc.cjs +15 -0
- package/CHANGELOG.md +282 -0
- package/README.md +122 -273
- package/api-extractor/api-extractor-lint-alpha.cjs.json +5 -0
- package/api-extractor/api-extractor-lint-alpha.esm.json +5 -0
- package/api-extractor/api-extractor-lint-beta.cjs.json +5 -0
- package/api-extractor/api-extractor-lint-beta.esm.json +5 -0
- package/api-extractor/api-extractor-lint-bundle.json +5 -0
- package/api-extractor/api-extractor-lint-public.cjs.json +5 -0
- package/api-extractor/api-extractor-lint-public.esm.json +5 -0
- package/api-extractor-lint.json +4 -0
- package/api-extractor.json +2 -2
- package/api-report/react.alpha.api.md +114 -0
- package/api-report/react.beta.api.md +7 -0
- package/api-report/react.public.api.md +7 -0
- package/biome.jsonc +4 -0
- package/dist/alpha.d.ts +45 -0
- package/dist/beta.d.ts +15 -0
- package/dist/index.d.ts +11 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -17
- package/dist/index.js.map +1 -1
- package/dist/package.json +4 -0
- package/dist/propNode.d.ts +114 -0
- package/dist/propNode.d.ts.map +1 -0
- package/dist/propNode.js +43 -0
- package/dist/propNode.js.map +1 -0
- package/dist/public.d.ts +15 -0
- package/dist/reactSharedTreeView.d.ts +119 -0
- package/dist/reactSharedTreeView.d.ts.map +1 -0
- package/dist/reactSharedTreeView.js +206 -0
- package/dist/reactSharedTreeView.js.map +1 -0
- package/dist/simpleIdentifier.d.ts +19 -0
- package/dist/simpleIdentifier.d.ts.map +1 -0
- package/dist/simpleIdentifier.js +33 -0
- package/dist/simpleIdentifier.js.map +1 -0
- package/dist/useObservation.d.ts +83 -0
- package/dist/useObservation.d.ts.map +1 -0
- package/dist/useObservation.js +295 -0
- package/dist/useObservation.js.map +1 -0
- package/dist/useTree.d.ts +80 -0
- package/dist/useTree.d.ts.map +1 -0
- package/dist/useTree.js +137 -0
- package/dist/useTree.js.map +1 -0
- package/lib/alpha.d.ts +45 -0
- package/lib/beta.d.ts +15 -0
- package/lib/index.d.ts +16 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +4 -7
- package/lib/index.js.map +1 -1
- package/lib/package.json +4 -0
- package/lib/propNode.d.ts +114 -0
- package/lib/propNode.d.ts.map +1 -0
- package/lib/propNode.js +36 -0
- package/lib/propNode.js.map +1 -0
- package/lib/public.d.ts +15 -0
- package/lib/reactSharedTreeView.d.ts +119 -0
- package/lib/reactSharedTreeView.d.ts.map +1 -0
- package/lib/reactSharedTreeView.js +176 -0
- package/lib/reactSharedTreeView.js.map +1 -0
- package/lib/simpleIdentifier.d.ts +19 -0
- package/lib/simpleIdentifier.d.ts.map +1 -0
- package/lib/simpleIdentifier.js +29 -0
- package/lib/simpleIdentifier.js.map +1 -0
- package/lib/test/propNode.spec.js +120 -0
- package/lib/test/propNode.spec.js.map +1 -0
- package/lib/test/reactSharedTreeView.spec.js +71 -0
- package/lib/test/reactSharedTreeView.spec.js.map +1 -0
- package/lib/test/simpleIdentifier.spec.js +18 -0
- package/lib/test/simpleIdentifier.spec.js.map +1 -0
- package/lib/test/useObservation.spec.js +162 -0
- package/lib/test/useObservation.spec.js.map +1 -0
- package/lib/test/useTree.spec.js +165 -0
- package/lib/test/useTree.spec.js.map +1 -0
- package/lib/tsdoc-metadata.json +11 -0
- package/lib/useObservation.d.ts +83 -0
- package/lib/useObservation.d.ts.map +1 -0
- package/lib/useObservation.js +266 -0
- package/lib/useObservation.js.map +1 -0
- package/lib/useTree.d.ts +80 -0
- package/lib/useTree.d.ts.map +1 -0
- package/lib/useTree.js +105 -0
- package/lib/useTree.js.map +1 -0
- package/package.json +150 -51
- package/react.test-files.tar +0 -0
- package/src/index.ts +42 -7
- package/src/propNode.ts +164 -0
- package/src/reactSharedTreeView.tsx +327 -0
- package/src/simpleIdentifier.ts +31 -0
- package/src/useObservation.ts +376 -0
- package/src/useTree.ts +147 -0
- package/tsconfig.cjs.json +7 -0
- package/tsconfig.json +12 -15
- package/tsdoc.json +4 -0
- package/.eslintrc.js +0 -11
- package/dist/createContextFluid.d.ts +0 -7
- package/dist/createContextFluid.d.ts.map +0 -1
- package/dist/createContextFluid.js +0 -46
- package/dist/createContextFluid.js.map +0 -1
- package/dist/helpers/generateFluidObjectSchema.d.ts +0 -16
- package/dist/helpers/generateFluidObjectSchema.d.ts.map +0 -1
- package/dist/helpers/generateFluidObjectSchema.js +0 -75
- package/dist/helpers/generateFluidObjectSchema.js.map +0 -1
- package/dist/helpers/getFluidFromView.d.ts +0 -15
- package/dist/helpers/getFluidFromView.d.ts.map +0 -1
- package/dist/helpers/getFluidFromView.js +0 -30
- package/dist/helpers/getFluidFromView.js.map +0 -1
- package/dist/helpers/getFluidState.d.ts +0 -15
- package/dist/helpers/getFluidState.d.ts.map +0 -1
- package/dist/helpers/getFluidState.js +0 -47
- package/dist/helpers/getFluidState.js.map +0 -1
- package/dist/helpers/getSchema.d.ts +0 -13
- package/dist/helpers/getSchema.d.ts.map +0 -1
- package/dist/helpers/getSchema.js +0 -15
- package/dist/helpers/getSchema.js.map +0 -1
- package/dist/helpers/getViewFromFluid.d.ts +0 -18
- package/dist/helpers/getViewFromFluid.d.ts.map +0 -1
- package/dist/helpers/getViewFromFluid.js +0 -47
- package/dist/helpers/getViewFromFluid.js.map +0 -1
- package/dist/helpers/index.d.ts +0 -16
- package/dist/helpers/index.d.ts.map +0 -1
- package/dist/helpers/index.js +0 -28
- package/dist/helpers/index.js.map +0 -1
- package/dist/helpers/initializeState.d.ts +0 -22
- package/dist/helpers/initializeState.d.ts.map +0 -1
- package/dist/helpers/initializeState.js +0 -77
- package/dist/helpers/initializeState.js.map +0 -1
- package/dist/helpers/internalInterface.d.ts +0 -15
- package/dist/helpers/internalInterface.d.ts.map +0 -1
- package/dist/helpers/internalInterface.js +0 -7
- package/dist/helpers/internalInterface.js.map +0 -1
- package/dist/helpers/rootCallbackListener.d.ts +0 -24
- package/dist/helpers/rootCallbackListener.d.ts.map +0 -1
- package/dist/helpers/rootCallbackListener.js +0 -55
- package/dist/helpers/rootCallbackListener.js.map +0 -1
- package/dist/helpers/setComponentSchema.d.ts +0 -14
- package/dist/helpers/setComponentSchema.d.ts.map +0 -1
- package/dist/helpers/setComponentSchema.js +0 -18
- package/dist/helpers/setComponentSchema.js.map +0 -1
- package/dist/helpers/setFluidState.d.ts +0 -20
- package/dist/helpers/setFluidState.d.ts.map +0 -1
- package/dist/helpers/setFluidState.js +0 -94
- package/dist/helpers/setFluidState.js.map +0 -1
- package/dist/helpers/syncState.d.ts +0 -25
- package/dist/helpers/syncState.d.ts.map +0 -1
- package/dist/helpers/syncState.js +0 -98
- package/dist/helpers/syncState.js.map +0 -1
- package/dist/helpers/updateStateAndFluidObjectMap.d.ts +0 -29
- package/dist/helpers/updateStateAndFluidObjectMap.d.ts.map +0 -1
- package/dist/helpers/updateStateAndFluidObjectMap.js +0 -30
- package/dist/helpers/updateStateAndFluidObjectMap.js.map +0 -1
- package/dist/helpers/utils.d.ts +0 -12
- package/dist/helpers/utils.d.ts.map +0 -1
- package/dist/helpers/utils.js +0 -74
- package/dist/helpers/utils.js.map +0 -1
- package/dist/interface.d.ts +0 -444
- package/dist/interface.d.ts.map +0 -1
- package/dist/interface.js +0 -18
- package/dist/interface.js.map +0 -1
- package/dist/reactView.d.ts +0 -32
- package/dist/reactView.d.ts.map +0 -1
- package/dist/reactView.js +0 -79
- package/dist/reactView.js.map +0 -1
- package/dist/syncedDataObject.d.ts +0 -80
- package/dist/syncedDataObject.d.ts.map +0 -1
- package/dist/syncedDataObject.js +0 -249
- package/dist/syncedDataObject.js.map +0 -1
- package/dist/syncedObjects/array/fluidSyncedArray.d.ts +0 -11
- package/dist/syncedObjects/array/fluidSyncedArray.d.ts.map +0 -1
- package/dist/syncedObjects/array/fluidSyncedArray.js +0 -78
- package/dist/syncedObjects/array/fluidSyncedArray.js.map +0 -1
- package/dist/syncedObjects/array/index.d.ts +0 -7
- package/dist/syncedObjects/array/index.d.ts.map +0 -1
- package/dist/syncedObjects/array/index.js +0 -19
- package/dist/syncedObjects/array/index.js.map +0 -1
- package/dist/syncedObjects/array/interface.d.ts +0 -33
- package/dist/syncedObjects/array/interface.d.ts.map +0 -1
- package/dist/syncedObjects/array/interface.js +0 -3
- package/dist/syncedObjects/array/interface.js.map +0 -1
- package/dist/syncedObjects/array/syncedArray.d.ts +0 -30
- package/dist/syncedObjects/array/syncedArray.d.ts.map +0 -1
- package/dist/syncedObjects/array/syncedArray.js +0 -42
- package/dist/syncedObjects/array/syncedArray.js.map +0 -1
- package/dist/syncedObjects/counter/fluidSyncedCounter.d.ts +0 -11
- package/dist/syncedObjects/counter/fluidSyncedCounter.d.ts.map +0 -1
- package/dist/syncedObjects/counter/fluidSyncedCounter.js +0 -79
- package/dist/syncedObjects/counter/fluidSyncedCounter.js.map +0 -1
- package/dist/syncedObjects/counter/index.d.ts +0 -7
- package/dist/syncedObjects/counter/index.d.ts.map +0 -1
- package/dist/syncedObjects/counter/index.js +0 -19
- package/dist/syncedObjects/counter/index.js.map +0 -1
- package/dist/syncedObjects/counter/interface.d.ts +0 -32
- package/dist/syncedObjects/counter/interface.d.ts.map +0 -1
- package/dist/syncedObjects/counter/interface.js +0 -3
- package/dist/syncedObjects/counter/interface.js.map +0 -1
- package/dist/syncedObjects/counter/syncedCounter.d.ts +0 -29
- package/dist/syncedObjects/counter/syncedCounter.d.ts.map +0 -1
- package/dist/syncedObjects/counter/syncedCounter.js +0 -36
- package/dist/syncedObjects/counter/syncedCounter.js.map +0 -1
- package/dist/syncedObjects/index.d.ts +0 -9
- package/dist/syncedObjects/index.d.ts.map +0 -1
- package/dist/syncedObjects/index.js +0 -21
- package/dist/syncedObjects/index.js.map +0 -1
- package/dist/syncedObjects/object/index.d.ts +0 -7
- package/dist/syncedObjects/object/index.d.ts.map +0 -1
- package/dist/syncedObjects/object/index.js +0 -19
- package/dist/syncedObjects/object/index.js.map +0 -1
- package/dist/syncedObjects/object/interface.d.ts +0 -13
- package/dist/syncedObjects/object/interface.d.ts.map +0 -1
- package/dist/syncedObjects/object/interface.js +0 -7
- package/dist/syncedObjects/object/interface.js.map +0 -1
- package/dist/syncedObjects/object/syncedObject.d.ts +0 -22
- package/dist/syncedObjects/object/syncedObject.d.ts.map +0 -1
- package/dist/syncedObjects/object/syncedObject.js +0 -46
- package/dist/syncedObjects/object/syncedObject.js.map +0 -1
- package/dist/syncedObjects/string/index.d.ts +0 -7
- package/dist/syncedObjects/string/index.d.ts.map +0 -1
- package/dist/syncedObjects/string/index.js +0 -19
- package/dist/syncedObjects/string/index.js.map +0 -1
- package/dist/syncedObjects/string/interface.d.ts +0 -16
- package/dist/syncedObjects/string/interface.d.ts.map +0 -1
- package/dist/syncedObjects/string/interface.js +0 -7
- package/dist/syncedObjects/string/interface.js.map +0 -1
- package/dist/syncedObjects/string/syncedString.d.ts +0 -25
- package/dist/syncedObjects/string/syncedString.d.ts.map +0 -1
- package/dist/syncedObjects/string/syncedString.js +0 -53
- package/dist/syncedObjects/string/syncedString.js.map +0 -1
- package/dist/useReducerFluid.d.ts +0 -7
- package/dist/useReducerFluid.d.ts.map +0 -1
- package/dist/useReducerFluid.js +0 -219
- package/dist/useReducerFluid.js.map +0 -1
- package/dist/useStateFluid.d.ts +0 -10
- package/dist/useStateFluid.d.ts.map +0 -1
- package/dist/useStateFluid.js +0 -67
- package/dist/useStateFluid.js.map +0 -1
- package/lib/createContextFluid.js +0 -23
- package/lib/createContextFluid.js.map +0 -1
- package/lib/helpers/generateFluidObjectSchema.js +0 -71
- package/lib/helpers/generateFluidObjectSchema.js.map +0 -1
- package/lib/helpers/getFluidFromView.js +0 -26
- package/lib/helpers/getFluidFromView.js.map +0 -1
- package/lib/helpers/getFluidState.js +0 -43
- package/lib/helpers/getFluidState.js.map +0 -1
- package/lib/helpers/getSchema.js +0 -11
- package/lib/helpers/getSchema.js.map +0 -1
- package/lib/helpers/getViewFromFluid.js +0 -43
- package/lib/helpers/getViewFromFluid.js.map +0 -1
- package/lib/helpers/index.js +0 -16
- package/lib/helpers/index.js.map +0 -1
- package/lib/helpers/initializeState.js +0 -73
- package/lib/helpers/initializeState.js.map +0 -1
- package/lib/helpers/internalInterface.js +0 -6
- package/lib/helpers/internalInterface.js.map +0 -1
- package/lib/helpers/rootCallbackListener.js +0 -51
- package/lib/helpers/rootCallbackListener.js.map +0 -1
- package/lib/helpers/setComponentSchema.js +0 -14
- package/lib/helpers/setComponentSchema.js.map +0 -1
- package/lib/helpers/setFluidState.js +0 -90
- package/lib/helpers/setFluidState.js.map +0 -1
- package/lib/helpers/syncState.js +0 -94
- package/lib/helpers/syncState.js.map +0 -1
- package/lib/helpers/updateStateAndFluidObjectMap.js +0 -26
- package/lib/helpers/updateStateAndFluidObjectMap.js.map +0 -1
- package/lib/helpers/utils.js +0 -67
- package/lib/helpers/utils.js.map +0 -1
- package/lib/interface.js +0 -8
- package/lib/interface.js.map +0 -1
- package/lib/reactView.js +0 -56
- package/lib/reactView.js.map +0 -1
- package/lib/syncedDataObject.js +0 -245
- package/lib/syncedDataObject.js.map +0 -1
- package/lib/syncedObjects/array/fluidSyncedArray.js +0 -72
- package/lib/syncedObjects/array/fluidSyncedArray.js.map +0 -1
- package/lib/syncedObjects/array/index.js +0 -7
- package/lib/syncedObjects/array/index.js.map +0 -1
- package/lib/syncedObjects/array/interface.js +0 -2
- package/lib/syncedObjects/array/interface.js.map +0 -1
- package/lib/syncedObjects/array/syncedArray.js +0 -37
- package/lib/syncedObjects/array/syncedArray.js.map +0 -1
- package/lib/syncedObjects/counter/fluidSyncedCounter.js +0 -73
- package/lib/syncedObjects/counter/fluidSyncedCounter.js.map +0 -1
- package/lib/syncedObjects/counter/index.js +0 -7
- package/lib/syncedObjects/counter/index.js.map +0 -1
- package/lib/syncedObjects/counter/interface.js +0 -2
- package/lib/syncedObjects/counter/interface.js.map +0 -1
- package/lib/syncedObjects/counter/syncedCounter.js +0 -31
- package/lib/syncedObjects/counter/syncedCounter.js.map +0 -1
- package/lib/syncedObjects/index.js +0 -9
- package/lib/syncedObjects/index.js.map +0 -1
- package/lib/syncedObjects/object/index.js +0 -7
- package/lib/syncedObjects/object/index.js.map +0 -1
- package/lib/syncedObjects/object/interface.js +0 -6
- package/lib/syncedObjects/object/interface.js.map +0 -1
- package/lib/syncedObjects/object/syncedObject.js +0 -41
- package/lib/syncedObjects/object/syncedObject.js.map +0 -1
- package/lib/syncedObjects/string/index.js +0 -7
- package/lib/syncedObjects/string/index.js.map +0 -1
- package/lib/syncedObjects/string/interface.js +0 -6
- package/lib/syncedObjects/string/interface.js.map +0 -1
- package/lib/syncedObjects/string/syncedString.js +0 -48
- package/lib/syncedObjects/string/syncedString.js.map +0 -1
- package/lib/useReducerFluid.js +0 -196
- package/lib/useReducerFluid.js.map +0 -1
- package/lib/useStateFluid.js +0 -44
- package/lib/useStateFluid.js.map +0 -1
- package/src/createContextFluid.tsx +0 -33
- package/src/helpers/generateFluidObjectSchema.ts +0 -95
- package/src/helpers/getFluidFromView.ts +0 -38
- package/src/helpers/getFluidState.ts +0 -67
- package/src/helpers/getSchema.ts +0 -18
- package/src/helpers/getViewFromFluid.ts +0 -68
- package/src/helpers/index.tsx +0 -16
- package/src/helpers/initializeState.ts +0 -162
- package/src/helpers/internalInterface.ts +0 -16
- package/src/helpers/rootCallbackListener.ts +0 -104
- package/src/helpers/setComponentSchema.ts +0 -21
- package/src/helpers/setFluidState.ts +0 -116
- package/src/helpers/syncState.ts +0 -159
- package/src/helpers/updateStateAndFluidObjectMap.ts +0 -85
- package/src/helpers/utils.tsx +0 -109
- package/src/interface.ts +0 -617
- package/src/reactView.tsx +0 -108
- package/src/syncedDataObject.ts +0 -337
- package/src/syncedObjects/array/fluidSyncedArray.ts +0 -126
- package/src/syncedObjects/array/index.ts +0 -7
- package/src/syncedObjects/array/interface.ts +0 -45
- package/src/syncedObjects/array/syncedArray.ts +0 -65
- package/src/syncedObjects/counter/fluidSyncedCounter.ts +0 -122
- package/src/syncedObjects/counter/index.ts +0 -7
- package/src/syncedObjects/counter/interface.ts +0 -44
- package/src/syncedObjects/counter/syncedCounter.ts +0 -64
- package/src/syncedObjects/index.ts +0 -9
- package/src/syncedObjects/object/index.ts +0 -7
- package/src/syncedObjects/object/interface.ts +0 -14
- package/src/syncedObjects/object/syncedObject.ts +0 -55
- package/src/syncedObjects/string/index.ts +0 -7
- package/src/syncedObjects/string/interface.ts +0 -17
- package/src/syncedObjects/string/syncedString.ts +0 -61
- package/src/useReducerFluid.tsx +0 -436
- package/src/useStateFluid.tsx +0 -84
- package/tsconfig.esnext.json +0 -7
package/lib/useTree.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { Tree } from "@fluidframework/tree";
|
|
6
|
+
import { TreeAlpha } from "@fluidframework/tree/internal";
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
import { unwrapPropTreeNode, unwrapPropTreeRecord, } from "./propNode.js";
|
|
9
|
+
import { useObservation } from "./useObservation.js";
|
|
10
|
+
/**
|
|
11
|
+
* Custom hook which invalidates a React Component when there is a change in the subtree defined by `subtreeRoot`.
|
|
12
|
+
* This includes changes to the tree's content, but not changes to its parentage.
|
|
13
|
+
* See {@link @fluidframework/tree#TreeChangeEvents.treeChanged} for details.
|
|
14
|
+
* @remarks
|
|
15
|
+
* Consider using {@link useTreeObservations} instead which tracks what was observed and only invalidates if it changes.
|
|
16
|
+
* @alpha
|
|
17
|
+
*/
|
|
18
|
+
export function useTree(subtreeRoot) {
|
|
19
|
+
// Use a React effect hook to invalidate this component when the subtreeRoot changes.
|
|
20
|
+
// We do this by incrementing a counter, which is passed as a dependency to the effect hook.
|
|
21
|
+
const [invalidations, setInvalidations] = React.useState(0);
|
|
22
|
+
// React effect hook that increments the 'invalidation' counter whenever subtreeRoot or any of its children change.
|
|
23
|
+
React.useEffect(() => {
|
|
24
|
+
// Returns the cleanup function to be invoked when the component unmounts.
|
|
25
|
+
return Tree.on(subtreeRoot, "treeChanged", () => {
|
|
26
|
+
setInvalidations((i) => i + 1);
|
|
27
|
+
});
|
|
28
|
+
}, [invalidations, subtreeRoot]);
|
|
29
|
+
return invalidations;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Higher order component which wraps a component to use {@link useTreeObservations}.
|
|
33
|
+
*
|
|
34
|
+
* @remarks
|
|
35
|
+
* When passing TreeNodes in props, care must be taken to not observe their content outside of a context which does observation tracking (or manual invalidation).
|
|
36
|
+
* This wraps a component in such tracking.
|
|
37
|
+
*
|
|
38
|
+
* It is recommended that sub-components which take in TreeNodes, if not defined using this higher order components, take the nodes in as {@link PropTreeNode}s.
|
|
39
|
+
* Components defined using this higher order component can take in either raw TreeNodes or {@link PropTreeNode}s: the latter will be automatically unwrapped.
|
|
40
|
+
* @privateRemarks
|
|
41
|
+
* `React.FC` does not seem to be covariant over its input type, so to make use of this more ergonomic,
|
|
42
|
+
* the return type intersects the various ways this could be used (with or without PropTreeNode wrapping).
|
|
43
|
+
* @alpha
|
|
44
|
+
*/
|
|
45
|
+
export function withTreeObservations(component, options) {
|
|
46
|
+
return (props) => useTreeObservations(() => component(props), options);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* {@link withTreeObservations} wrapped with React.memo.
|
|
50
|
+
* @remarks
|
|
51
|
+
* There is no special logic here, just a convenience wrapper.
|
|
52
|
+
* @alpha
|
|
53
|
+
*/
|
|
54
|
+
export function withMemoizedTreeObservations(component, options) {
|
|
55
|
+
return React.memo(withTreeObservations(component, options), options?.propsAreEqual);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Custom hook which invalidates a React Component when there is a change in tree content observed during `trackDuring`.
|
|
59
|
+
*
|
|
60
|
+
* @param trackDuring - Called synchronously, and will have its tree observations tracked.
|
|
61
|
+
*
|
|
62
|
+
* @remarks
|
|
63
|
+
* This includes changes to the tree's content.
|
|
64
|
+
* Currently this will throw if observing a node's parentage to be undefined,
|
|
65
|
+
* and node status changes will not cause invalidation.
|
|
66
|
+
*
|
|
67
|
+
* For additional type safety to help avoid observing TreeNode content outside of this hook, see {@link PropTreeNode}.
|
|
68
|
+
* @alpha
|
|
69
|
+
*/
|
|
70
|
+
export function useTreeObservations(trackDuring, options) {
|
|
71
|
+
return useObservation((invalidate) => TreeAlpha.trackObservationsOnce(invalidate, trackDuring), options);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Custom hook for using a prop tree node.
|
|
75
|
+
*
|
|
76
|
+
* @param propNode - Input, automatically unwrapped TreeNode from a {@link PropTreeNode} if needed.
|
|
77
|
+
* @param trackDuring - Callback which reads from the node and returns a result.
|
|
78
|
+
* If the result is a TreeNode or {@link NodeRecord} it will be wrapped as a {@link PropTreeNode} or {@link PropTreeNodeRecord}, see {@link WrapNodes}.
|
|
79
|
+
*
|
|
80
|
+
* It is recommended that when returning data containing TreeNodes,
|
|
81
|
+
* use a format supported by {@link WrapNodes} or wrap the nodes manually using {@link toPropTreeNode}.
|
|
82
|
+
* This improves the type safety, reducing the risk of invalidation bugs due to untracked access of tree content contained in the return value.
|
|
83
|
+
*
|
|
84
|
+
* Note that is is fine to observe any node inside the callback, not just the provided node: all accesses will be tracked.
|
|
85
|
+
* The input node is just provided as a way to automatically unwrap the {@link PropTreeNode}
|
|
86
|
+
*
|
|
87
|
+
* @remarks
|
|
88
|
+
* Reads content using {@link useTreeObservations} to track dependencies.
|
|
89
|
+
* @alpha
|
|
90
|
+
*/
|
|
91
|
+
export function usePropTreeNode(propNode, trackDuring) {
|
|
92
|
+
const node = unwrapPropTreeNode(propNode);
|
|
93
|
+
const result = useTreeObservations(() => trackDuring(node));
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* {@link usePropTreeNode} but takes in a {@link PropTreeNodeRecord}.
|
|
98
|
+
* @alpha
|
|
99
|
+
*/
|
|
100
|
+
export function usePropTreeRecord(props, f) {
|
|
101
|
+
const record = unwrapPropTreeRecord(props);
|
|
102
|
+
const result = useTreeObservations(() => f(record));
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=useTree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTree.js","sourceRoot":"","sources":["../src/useTree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EACN,kBAAkB,EAClB,oBAAoB,GAKpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,cAAc,EAA2B,MAAM,qBAAqB,CAAC;AAE9E;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,WAAqB;IAC5C,qFAAqF;IACrF,4FAA4F;IAC5F,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE5D,mHAAmH;IACnH,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACpB,0EAA0E;QAC1E,OAAO,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,aAAa,EAAE,GAAG,EAAE;YAC/C,gBAAgB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC,CAAC;IAEjC,OAAO,aAAa,CAAC;AACtB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,oBAAoB,CACnC,SAAwB,EACxB,OAA4B;IAE5B,OAAO,CAAC,KAA2B,EAAmB,EAAE,CACvD,mBAAmB,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAY,CAAC,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B,CAC3C,SAAwB,EACxB,OAEC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;AACrF,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,CAClC,WAA0B,EAC1B,OAA4B;IAE5B,OAAO,cAAc,CACpB,CAAC,UAAU,EAAE,EAAE,CAAC,SAAS,CAAC,qBAAqB,CAAC,UAAU,EAAE,WAAW,CAAC,EACxE,OAAO,CACP,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,eAAe,CAC9B,QAA8B,EAC9B,WAAiC;IAEjC,MAAM,IAAI,GAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAE7C,MAAM,MAAM,GAAG,mBAAmB,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IAE5D,OAAO,MAA4B,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAChC,KAAQ,EACR,CAAiD;IAEjD,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAE3C,MAAM,MAAM,GAAG,mBAAmB,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAEpD,OAAO,MAA4B,CAAC;AACrC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { TreeLeafValue, TreeNode } from \"@fluidframework/tree\";\nimport { Tree } from \"@fluidframework/tree\";\nimport { TreeAlpha } from \"@fluidframework/tree/internal\";\nimport * as React from \"react\";\n\nimport {\n\tunwrapPropTreeNode,\n\tunwrapPropTreeRecord,\n\ttype PropTreeNodeRecord,\n\ttype PropTreeValue,\n\ttype UnwrapPropTreeNodeRecord,\n\ttype WrapNodes,\n} from \"./propNode.js\";\nimport { useObservation, type ObservationOptions } from \"./useObservation.js\";\n\n/**\n * Custom hook which invalidates a React Component when there is a change in the subtree defined by `subtreeRoot`.\n * This includes changes to the tree's content, but not changes to its parentage.\n * See {@link @fluidframework/tree#TreeChangeEvents.treeChanged} for details.\n * @remarks\n * Consider using {@link useTreeObservations} instead which tracks what was observed and only invalidates if it changes.\n * @alpha\n */\nexport function useTree(subtreeRoot: TreeNode): number {\n\t// Use a React effect hook to invalidate this component when the subtreeRoot changes.\n\t// We do this by incrementing a counter, which is passed as a dependency to the effect hook.\n\tconst [invalidations, setInvalidations] = React.useState(0);\n\n\t// React effect hook that increments the 'invalidation' counter whenever subtreeRoot or any of its children change.\n\tReact.useEffect(() => {\n\t\t// Returns the cleanup function to be invoked when the component unmounts.\n\t\treturn Tree.on(subtreeRoot, \"treeChanged\", () => {\n\t\t\tsetInvalidations((i) => i + 1);\n\t\t});\n\t}, [invalidations, subtreeRoot]);\n\n\treturn invalidations;\n}\n\n/**\n * Higher order component which wraps a component to use {@link useTreeObservations}.\n *\n * @remarks\n * When passing TreeNodes in props, care must be taken to not observe their content outside of a context which does observation tracking (or manual invalidation).\n * This wraps a component in such tracking.\n *\n * It is recommended that sub-components which take in TreeNodes, if not defined using this higher order components, take the nodes in as {@link PropTreeNode}s.\n * Components defined using this higher order component can take in either raw TreeNodes or {@link PropTreeNode}s: the latter will be automatically unwrapped.\n * @privateRemarks\n * `React.FC` does not seem to be covariant over its input type, so to make use of this more ergonomic,\n * the return type intersects the various ways this could be used (with or without PropTreeNode wrapping).\n * @alpha\n */\nexport function withTreeObservations<TIn>(\n\tcomponent: React.FC<TIn>,\n\toptions?: ObservationOptions,\n): React.FC<TIn> & React.FC<WrapNodes<TIn>> & React.FC<TIn | WrapNodes<TIn>> {\n\treturn (props: TIn | WrapNodes<TIn>): React.ReactNode =>\n\t\tuseTreeObservations(() => component(props as TIn), options);\n}\n\n/**\n * {@link withTreeObservations} wrapped with React.memo.\n * @remarks\n * There is no special logic here, just a convenience wrapper.\n * @alpha\n */\nexport function withMemoizedTreeObservations<TIn>(\n\tcomponent: React.FC<TIn>,\n\toptions?: ObservationOptions & {\n\t\treadonly propsAreEqual?: Parameters<typeof React.memo>[1];\n\t},\n): React.MemoExoticComponent<ReturnType<typeof withTreeObservations<TIn>>> {\n\treturn React.memo(withTreeObservations(component, options), options?.propsAreEqual);\n}\n\n/**\n * Custom hook which invalidates a React Component when there is a change in tree content observed during `trackDuring`.\n *\n * @param trackDuring - Called synchronously, and will have its tree observations tracked.\n *\n * @remarks\n * This includes changes to the tree's content.\n * Currently this will throw if observing a node's parentage to be undefined,\n * and node status changes will not cause invalidation.\n *\n * For additional type safety to help avoid observing TreeNode content outside of this hook, see {@link PropTreeNode}.\n * @alpha\n */\nexport function useTreeObservations<TResult>(\n\ttrackDuring: () => TResult,\n\toptions?: ObservationOptions,\n): TResult {\n\treturn useObservation(\n\t\t(invalidate) => TreeAlpha.trackObservationsOnce(invalidate, trackDuring),\n\t\toptions,\n\t);\n}\n\n/**\n * Custom hook for using a prop tree node.\n *\n * @param propNode - Input, automatically unwrapped TreeNode from a {@link PropTreeNode} if needed.\n * @param trackDuring - Callback which reads from the node and returns a result.\n * If the result is a TreeNode or {@link NodeRecord} it will be wrapped as a {@link PropTreeNode} or {@link PropTreeNodeRecord}, see {@link WrapNodes}.\n *\n * It is recommended that when returning data containing TreeNodes,\n * use a format supported by {@link WrapNodes} or wrap the nodes manually using {@link toPropTreeNode}.\n * This improves the type safety, reducing the risk of invalidation bugs due to untracked access of tree content contained in the return value.\n *\n * Note that is is fine to observe any node inside the callback, not just the provided node: all accesses will be tracked.\n * The input node is just provided as a way to automatically unwrap the {@link PropTreeNode}\n *\n * @remarks\n * Reads content using {@link useTreeObservations} to track dependencies.\n * @alpha\n */\nexport function usePropTreeNode<T extends TreeNode | TreeLeafValue, TResult>(\n\tpropNode: PropTreeValue<T> | T,\n\ttrackDuring: (node: T) => TResult,\n): WrapNodes<TResult> {\n\tconst node: T = unwrapPropTreeNode(propNode);\n\n\tconst result = useTreeObservations(() => trackDuring(node));\n\n\treturn result as WrapNodes<TResult>;\n}\n\n/**\n * {@link usePropTreeNode} but takes in a {@link PropTreeNodeRecord}.\n * @alpha\n */\nexport function usePropTreeRecord<const T extends PropTreeNodeRecord, TResult>(\n\tprops: T,\n\tf: (node: UnwrapPropTreeNodeRecord<T>) => TResult,\n): WrapNodes<TResult> {\n\tconst record = unwrapPropTreeRecord(props);\n\n\tconst result = useTreeObservations(() => f(record));\n\n\treturn result as WrapNodes<TResult>;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,63 +1,162 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/react",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.63.0-358419",
|
|
4
|
+
"description": "Utilities for integrating content powered by the Fluid Framework into React applications",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
|
-
"repository":
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/microsoft/FluidFramework.git",
|
|
9
|
+
"directory": "packages/framework/react"
|
|
10
|
+
},
|
|
7
11
|
"license": "MIT",
|
|
8
12
|
"author": "Microsoft and contributors",
|
|
9
13
|
"sideEffects": false,
|
|
14
|
+
"type": "module",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"import": {
|
|
18
|
+
"types": "./lib/public.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"require": {
|
|
22
|
+
"types": "./dist/public.d.ts",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"./alpha": {
|
|
27
|
+
"import": {
|
|
28
|
+
"types": "./lib/alpha.d.ts",
|
|
29
|
+
"default": "./lib/index.js"
|
|
30
|
+
},
|
|
31
|
+
"require": {
|
|
32
|
+
"types": "./dist/alpha.d.ts",
|
|
33
|
+
"default": "./dist/index.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"./beta": {
|
|
37
|
+
"import": {
|
|
38
|
+
"types": "./lib/beta.d.ts",
|
|
39
|
+
"default": "./lib/index.js"
|
|
40
|
+
},
|
|
41
|
+
"require": {
|
|
42
|
+
"types": "./dist/beta.d.ts",
|
|
43
|
+
"default": "./dist/index.js"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"./internal": {
|
|
47
|
+
"import": {
|
|
48
|
+
"types": "./lib/index.d.ts",
|
|
49
|
+
"default": "./lib/index.js"
|
|
50
|
+
},
|
|
51
|
+
"require": {
|
|
52
|
+
"types": "./dist/index.d.ts",
|
|
53
|
+
"default": "./dist/index.js"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
},
|
|
10
57
|
"main": "dist/index.js",
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
|
|
58
|
+
"types": "./dist/public.d.ts",
|
|
59
|
+
"c8": {
|
|
60
|
+
"all": true,
|
|
61
|
+
"cache-dir": "nyc/.cache",
|
|
62
|
+
"exclude": [
|
|
63
|
+
"src/test/**/*.*ts",
|
|
64
|
+
"dist/test/**/*.*js",
|
|
65
|
+
"lib/test/**/*.*js"
|
|
66
|
+
],
|
|
67
|
+
"exclude-after-remap": false,
|
|
68
|
+
"include": [
|
|
69
|
+
"src/**/*.*ts",
|
|
70
|
+
"dist/**/*.*js",
|
|
71
|
+
"lib/**/*.*js"
|
|
72
|
+
],
|
|
73
|
+
"report-dir": "nyc/report",
|
|
74
|
+
"reporter": [
|
|
75
|
+
"cobertura",
|
|
76
|
+
"html",
|
|
77
|
+
"text"
|
|
78
|
+
],
|
|
79
|
+
"temp-directory": "nyc/.nyc_output"
|
|
29
80
|
},
|
|
30
81
|
"dependencies": {
|
|
31
|
-
"@fluidframework/aqueduct": "
|
|
32
|
-
"@fluidframework/
|
|
33
|
-
"@fluidframework/
|
|
34
|
-
"@fluidframework/
|
|
35
|
-
"@fluidframework/
|
|
36
|
-
"@fluidframework/
|
|
37
|
-
"@fluidframework/
|
|
38
|
-
"
|
|
39
|
-
"@fluidframework/view-interfaces": "^0.41.4",
|
|
40
|
-
"react": "^16.10.2"
|
|
82
|
+
"@fluidframework/aqueduct": "2.63.0-358419",
|
|
83
|
+
"@fluidframework/core-interfaces": "2.63.0-358419",
|
|
84
|
+
"@fluidframework/datastore-definitions": "2.63.0-358419",
|
|
85
|
+
"@fluidframework/fluid-static": "2.63.0-358419",
|
|
86
|
+
"@fluidframework/runtime-definitions": "2.63.0-358419",
|
|
87
|
+
"@fluidframework/shared-object-base": "2.63.0-358419",
|
|
88
|
+
"@fluidframework/tree": "2.63.0-358419",
|
|
89
|
+
"react": "^18.3.1"
|
|
41
90
|
},
|
|
42
91
|
"devDependencies": {
|
|
43
|
-
"@
|
|
44
|
-
"@
|
|
45
|
-
"@
|
|
46
|
-
"@
|
|
47
|
-
"@
|
|
48
|
-
"@
|
|
49
|
-
"@
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
92
|
+
"@arethetypeswrong/cli": "^0.17.1",
|
|
93
|
+
"@biomejs/biome": "~1.9.3",
|
|
94
|
+
"@fluid-internal/mocha-test-setup": "2.63.0-358419",
|
|
95
|
+
"@fluid-tools/build-cli": "^0.58.3",
|
|
96
|
+
"@fluidframework/build-common": "^2.0.3",
|
|
97
|
+
"@fluidframework/build-tools": "^0.58.3",
|
|
98
|
+
"@fluidframework/eslint-config-fluid": "^6.0.0",
|
|
99
|
+
"@fluidframework/tinylicious-client": "2.63.0-358419",
|
|
100
|
+
"@microsoft/api-extractor": "7.52.11",
|
|
101
|
+
"@testing-library/react": "^16.3.0",
|
|
102
|
+
"@types/mocha": "^10.0.10",
|
|
103
|
+
"@types/node": "^18.19.0",
|
|
104
|
+
"@types/react": "^18.3.11",
|
|
105
|
+
"c8": "^10.1.3",
|
|
106
|
+
"concurrently": "^8.2.1",
|
|
107
|
+
"copyfiles": "^2.4.1",
|
|
108
|
+
"cross-env": "^7.0.3",
|
|
109
|
+
"eslint": "~8.55.0",
|
|
110
|
+
"eslint-config-prettier": "~9.0.0",
|
|
111
|
+
"global-jsdom": "^26.0.0",
|
|
112
|
+
"mocha": "^10.8.2",
|
|
113
|
+
"mocha-multi-reporters": "^1.5.1",
|
|
114
|
+
"rimraf": "^4.4.0",
|
|
115
|
+
"typescript": "~5.4.5"
|
|
116
|
+
},
|
|
117
|
+
"typeValidation": {
|
|
118
|
+
"disabled": true,
|
|
119
|
+
"broken": {},
|
|
120
|
+
"entrypoint": "internal"
|
|
121
|
+
},
|
|
122
|
+
"scripts": {
|
|
123
|
+
"api": "fluid-build . --task api",
|
|
124
|
+
"api-extractor:commonjs": "flub generate entrypoints --outDir ./dist",
|
|
125
|
+
"api-extractor:esnext": "flub generate entrypoints --outDir ./lib",
|
|
126
|
+
"build": "fluid-build . --task build",
|
|
127
|
+
"build:commonjs": "fluid-build . --task commonjs",
|
|
128
|
+
"build:compile": "fluid-build . --task compile",
|
|
129
|
+
"build:docs": "api-extractor run --local",
|
|
130
|
+
"build:esnext": "tsc --project ./tsconfig.json && copyfiles -f ../../../common/build/build-common/src/esm/package.json ./lib",
|
|
131
|
+
"build:test": "npm run build:test:esm && npm run build:test:cjs",
|
|
132
|
+
"build:test:cjs": "fluid-tsc commonjs --project ./src/test/tsconfig.cjs.json",
|
|
133
|
+
"build:test:esm": "tsc --project ./src/test/tsconfig.json",
|
|
134
|
+
"check:are-the-types-wrong": "attw --pack . --entrypoints .",
|
|
135
|
+
"check:biome": "biome check .",
|
|
136
|
+
"check:exports": "concurrently \"npm:check:exports:*\"",
|
|
137
|
+
"check:exports:bundle-release-tags": "api-extractor run --config api-extractor/api-extractor-lint-bundle.json",
|
|
138
|
+
"check:exports:cjs:alpha": "api-extractor run --config api-extractor/api-extractor-lint-alpha.cjs.json",
|
|
139
|
+
"check:exports:cjs:beta": "api-extractor run --config api-extractor/api-extractor-lint-beta.cjs.json",
|
|
140
|
+
"check:exports:cjs:public": "api-extractor run --config api-extractor/api-extractor-lint-public.cjs.json",
|
|
141
|
+
"check:exports:esm:alpha": "api-extractor run --config api-extractor/api-extractor-lint-alpha.esm.json",
|
|
142
|
+
"check:exports:esm:beta": "api-extractor run --config api-extractor/api-extractor-lint-beta.esm.json",
|
|
143
|
+
"check:exports:esm:public": "api-extractor run --config api-extractor/api-extractor-lint-public.esm.json",
|
|
144
|
+
"check:format": "npm run check:biome",
|
|
145
|
+
"ci:build:docs": "api-extractor run",
|
|
146
|
+
"clean": "rimraf --glob dist lib {alpha,beta,internal,legacy}.d.ts \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc",
|
|
147
|
+
"eslint": "eslint --format stylish src",
|
|
148
|
+
"eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
|
|
149
|
+
"format": "npm run format:biome",
|
|
150
|
+
"format:biome": "biome check . --write",
|
|
151
|
+
"lint": "fluid-build . --task lint",
|
|
152
|
+
"lint:fix": "fluid-build . --task eslint:fix --task format",
|
|
153
|
+
"pack:tests": "tar -cf ./react.test-files.tar ./src/test ./dist/test ./lib/test",
|
|
154
|
+
"test": "npm run test:mocha",
|
|
155
|
+
"test:coverage": "c8 npm test",
|
|
156
|
+
"test:mocha": "npm run test:mocha:esm && echo skipping cjs to avoid overhead - npm run test:mocha:cjs",
|
|
157
|
+
"test:mocha:cjs": "cross-env FLUID_TEST_MODULE_SYSTEM=CJS mocha",
|
|
158
|
+
"test:mocha:esm": "mocha",
|
|
159
|
+
"test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
|
|
160
|
+
"tsc": "fluid-tsc commonjs --project ./tsconfig.cjs.json && copyfiles -f ../../../common/build/build-common/src/cjs/package.json ./dist"
|
|
62
161
|
}
|
|
63
|
-
}
|
|
162
|
+
}
|
|
Binary file
|
package/src/index.ts
CHANGED
|
@@ -3,10 +3,45 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export
|
|
12
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Utilities for using SharedTree with React.
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export type {
|
|
12
|
+
IReactTreeDataObject,
|
|
13
|
+
TreeViewProps,
|
|
14
|
+
SchemaIncompatibleProps,
|
|
15
|
+
} from "./reactSharedTreeView.js";
|
|
16
|
+
export {
|
|
17
|
+
treeDataObject,
|
|
18
|
+
treeDataObjectInternal,
|
|
19
|
+
TreeViewComponent,
|
|
20
|
+
} from "./reactSharedTreeView.js";
|
|
21
|
+
export type { ObservationOptions } from "./useObservation.js";
|
|
22
|
+
export type {
|
|
23
|
+
NodeRecord,
|
|
24
|
+
PropTreeNode,
|
|
25
|
+
PropTreeNodeRecord,
|
|
26
|
+
PropTreeValue,
|
|
27
|
+
UnwrapPropTreeNode,
|
|
28
|
+
UnwrapPropTreeNodeRecord,
|
|
29
|
+
WrapPropTreeNodeRecord,
|
|
30
|
+
WrapNodes,
|
|
31
|
+
IsMappableObjectType,
|
|
32
|
+
} from "./propNode.js";
|
|
33
|
+
export {
|
|
34
|
+
toPropTreeNode,
|
|
35
|
+
toPropTreeRecord,
|
|
36
|
+
unwrapPropTreeNode,
|
|
37
|
+
unwrapPropTreeRecord,
|
|
38
|
+
} from "./propNode.js";
|
|
39
|
+
export {
|
|
40
|
+
useTree,
|
|
41
|
+
usePropTreeNode,
|
|
42
|
+
usePropTreeRecord,
|
|
43
|
+
useTreeObservations,
|
|
44
|
+
withTreeObservations,
|
|
45
|
+
withMemoizedTreeObservations,
|
|
46
|
+
} from "./useTree.js";
|
|
47
|
+
export { objectIdNumber } from "./simpleIdentifier.js";
|
package/src/propNode.ts
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ErasedType } from "@fluidframework/core-interfaces";
|
|
7
|
+
import type { TreeNode, TreeLeafValue } from "@fluidframework/tree";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A type erased TreeNode for use in react props.
|
|
11
|
+
* @remarks
|
|
12
|
+
* Read content from the node using {@link usePropTreeNode} or {@link usePropTreeRecord}.
|
|
13
|
+
*
|
|
14
|
+
* In events where tracking dependencies is not required, the node can be unwrapped using {@link unwrapPropTreeNode}.
|
|
15
|
+
*
|
|
16
|
+
* To convert a TreeNode to this type use {@link toPropTreeNode} or {@link toPropTreeRecord}.
|
|
17
|
+
* @alpha
|
|
18
|
+
*/
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
20
|
+
export interface PropTreeNode<T extends TreeNode> extends ErasedType<[T, "PropTreeNode"]> {}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Type TreeNodes in T as {@link PropTreeNode}s.
|
|
24
|
+
* @remarks
|
|
25
|
+
* This only handles a few cases (TreeNode, structurally typed objects fields and arrays) and leaves other types as is.
|
|
26
|
+
* Users which provide other types (e.g. maps) which contain TreeNodes will need to handle wrapping those themselves if the wrapping is desired.
|
|
27
|
+
*
|
|
28
|
+
* Users of this should not rely on a given use of TreeNode not being wrapped:
|
|
29
|
+
* future changes to this API may add more cases which are wrapped, and this will be considered a non-breaking change.
|
|
30
|
+
* @privateRemarks
|
|
31
|
+
* Covering all cases is impossible, and trying to cover more with recursive mapped types can break some of the types by losing methods, private members, etc.
|
|
32
|
+
* To mitigate this IsMappableObjectType is used for objects, and only mappable types, where the mapping actually impacted the type are modified.
|
|
33
|
+
*
|
|
34
|
+
* This is intended to cover the common cases, and users can handle other cases manually.
|
|
35
|
+
* See the tests for this for more details.
|
|
36
|
+
* @alpha
|
|
37
|
+
*/
|
|
38
|
+
export type WrapNodes<T> = T extends TreeNode
|
|
39
|
+
? PropTreeNode<T>
|
|
40
|
+
: T extends readonly (infer U)[]
|
|
41
|
+
? readonly WrapNodes<U>[]
|
|
42
|
+
: // `T extends (infer U)` distributes over unions, allowing WrapNodes<A|B> to be WrapNodes<A> | WrapNodes<B>.
|
|
43
|
+
T extends infer U
|
|
44
|
+
? IsMappableObjectType<
|
|
45
|
+
U,
|
|
46
|
+
{
|
|
47
|
+
[P in keyof U]: WrapNodes<U[P]>;
|
|
48
|
+
} extends U
|
|
49
|
+
? // Returning U in this case (when assignable to the mapped type) avoids flatting named interfaces when they are unchanged.
|
|
50
|
+
U
|
|
51
|
+
: {
|
|
52
|
+
[P in keyof U]: WrapNodes<U[P]>;
|
|
53
|
+
},
|
|
54
|
+
T
|
|
55
|
+
>
|
|
56
|
+
: T;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Detect if a type is a simple structural object.
|
|
60
|
+
* @remarks
|
|
61
|
+
* This returns the true case if the type is entirely defined by its set of public properties.
|
|
62
|
+
* More concretely, this indicates if creating a mapped type based on `T`
|
|
63
|
+
* will be lossy due to details mapped types cannot access.
|
|
64
|
+
*
|
|
65
|
+
* This is shallow, and distributes over unions.
|
|
66
|
+
*
|
|
67
|
+
* This also returns the true case for primitive types since mapping over them leaves them unchanged if doing so in a generic context:
|
|
68
|
+
* Mapping over a primitive does not leave them unchanged if done directly (not to a generic type parameter), but this can not detect that behavior.
|
|
69
|
+
* This is fine as the use for this is to detect when making a mapped type from a generic type parameter would be lossy.
|
|
70
|
+
* @system @alpha
|
|
71
|
+
*/
|
|
72
|
+
export type IsMappableObjectType<
|
|
73
|
+
T,
|
|
74
|
+
True = true,
|
|
75
|
+
False = false,
|
|
76
|
+
Mapped = {
|
|
77
|
+
[P in keyof T]: T[P];
|
|
78
|
+
},
|
|
79
|
+
> = [Mapped] extends [T] ? ([T] extends [Mapped] ? True : False) : False;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Casts a node from a {@link PropTreeNode} back to a TreeNode.
|
|
83
|
+
* @remarks
|
|
84
|
+
* This should only be done in scenarios where tracking observations is not required (such as event handlers),
|
|
85
|
+
* or when taking care to handle invalidation manually.
|
|
86
|
+
* @alpha
|
|
87
|
+
*/
|
|
88
|
+
export function unwrapPropTreeNode<T extends TreeNode | TreeLeafValue>(
|
|
89
|
+
propNode: PropTreeValue<T> | T,
|
|
90
|
+
): T {
|
|
91
|
+
return propNode as T;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* {@link unwrapPropTreeNode} but for a {@link PropTreeNodeRecord}.
|
|
96
|
+
* @alpha
|
|
97
|
+
*/
|
|
98
|
+
export function unwrapPropTreeRecord<T extends PropTreeNodeRecord>(
|
|
99
|
+
props: T,
|
|
100
|
+
): UnwrapPropTreeNodeRecord<T> {
|
|
101
|
+
return props as UnwrapPropTreeNodeRecord<T>;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* {@inheritdoc unwrapPropTreeNode}
|
|
106
|
+
* @alpha
|
|
107
|
+
*/
|
|
108
|
+
export type UnwrapPropTreeNode<T extends TreeLeafValue | PropTreeNode<TreeNode> | undefined> =
|
|
109
|
+
T extends PropTreeNode<infer Node> ? Node : T;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Record that can contain TreeNodes.
|
|
113
|
+
* @alpha
|
|
114
|
+
*/
|
|
115
|
+
export type NodeRecord = Record<string, TreeNode | TreeLeafValue>;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Type erase `TreeNode`s from a {@link NodeRecord} as a {@link PropTreeNode}.
|
|
119
|
+
* @alpha
|
|
120
|
+
*/
|
|
121
|
+
export type WrapPropTreeNodeRecord<T extends NodeRecord> = {
|
|
122
|
+
readonly [P in keyof T]: PropTreeValue<T[P]>;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Type erase `TreeNode`s from a {@link NodeRecord} as a {@link PropTreeNode}.
|
|
127
|
+
* @alpha
|
|
128
|
+
*/
|
|
129
|
+
export type UnwrapPropTreeNodeRecord<T extends PropTreeNodeRecord> = {
|
|
130
|
+
readonly [P in keyof T]: UnwrapPropTreeNode<T[P]>;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Type erase `TreeNode`s from a {@link NodeRecord} as a {@link PropTreeNode}.
|
|
135
|
+
* @alpha
|
|
136
|
+
*/
|
|
137
|
+
export type PropTreeNodeRecord = Record<
|
|
138
|
+
string,
|
|
139
|
+
TreeLeafValue | PropTreeNode<TreeNode> | undefined
|
|
140
|
+
>;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Type erase a `TreeNode` from a `TreeNode | TreeLeafValue` as a {@link PropTreeNode}.
|
|
144
|
+
* @alpha
|
|
145
|
+
*/
|
|
146
|
+
export type PropTreeValue<T extends TreeNode | TreeLeafValue | undefined> = T extends TreeNode
|
|
147
|
+
? PropTreeNode<T>
|
|
148
|
+
: T;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Type erase a TreeNode as a {@link PropTreeNode}.
|
|
152
|
+
* @alpha
|
|
153
|
+
*/
|
|
154
|
+
export function toPropTreeNode<T extends TreeNode | TreeLeafValue>(node: T): PropTreeValue<T> {
|
|
155
|
+
return node as unknown as PropTreeValue<T>;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Type erase a {@link NodeRecord} as a {@link PropTreeNodeRecord}.
|
|
160
|
+
* @alpha
|
|
161
|
+
*/
|
|
162
|
+
export function toPropTreeRecord<T extends NodeRecord>(node: T): WrapPropTreeNodeRecord<T> {
|
|
163
|
+
return node as unknown as WrapPropTreeNodeRecord<T>;
|
|
164
|
+
}
|