Skip to content

Commit 32cc2c7

Browse files
Abe27342Abram Sanderson
andauthored
Promote minimal SharedTree branch APIs to beta (#25744)
## Description This PR promotes the minimal set of APIs necessary to enable local branching flows in SharedTree. --------- Co-authored-by: Abram Sanderson <absander@microsoft.com>
1 parent 7f9a6f7 commit 32cc2c7

File tree

17 files changed

+220
-65
lines changed

17 files changed

+220
-65
lines changed

.changeset/crazy-carrots-mate.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
"fluid-framework": minor
3+
"@fluidframework/tree": minor
4+
"@fluidframework/tree-agent": minor
5+
"__section": feature
6+
---
7+
A minimal set of branching APIs has been promoted to beta.
8+
9+
The following APIs have been promoted to beta in `@fluidframework/tree`:
10+
11+
- `TreeBranch.fork()`
12+
- `TreeBranch.merge()`
13+
- `TreeBranch.rebaseOnto()`
14+
- `TreeBranch.dispose()`
15+
- `TreeView.fork()`
16+
17+
These APIs enable applications to implement basic local branching flows.

packages/dds/tree/api-report/tree.alpha.api.md

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ export const ArrayNodeSchema: {
117117
// @alpha
118118
export function asAlpha<TSchema extends ImplicitFieldSchema>(view: TreeView<TSchema>): TreeViewAlpha<TSchema>;
119119

120+
// @beta
121+
export function asBeta<TSchema extends ImplicitFieldSchema>(view: TreeView<TSchema>): TreeViewBeta<TSchema>;
122+
120123
// @alpha @deprecated
121124
export function asTreeViewAlpha<TSchema extends ImplicitFieldSchema>(view: TreeView<TSchema>): TreeViewAlpha<TSchema>;
122125

@@ -1347,7 +1350,7 @@ export const Tree: Tree;
13471350

13481351
// @alpha @sealed @system
13491352
export interface TreeAlpha {
1350-
branch(node: TreeNode): TreeBranch | undefined;
1353+
branch(node: TreeNode): TreeBranchAlpha | undefined;
13511354
child(node: TreeNode, key: string | number): TreeNode | TreeLeafValue | undefined;
13521355
children(node: TreeNode): Iterable<[propertyKey: string | number, child: TreeNode | TreeLeafValue]>;
13531356
create<const TSchema extends ImplicitFieldSchema | UnsafeUnknownSchema>(schema: UnsafeUnknownSchema extends TSchema ? ImplicitFieldSchema : TSchema & ImplicitFieldSchema, data: InsertableField<TSchema>): Unhydrated<TSchema extends ImplicitFieldSchema ? TreeFieldFromImplicitField<TSchema> : TreeNode | TreeLeafValue | undefined>;
@@ -1412,14 +1415,20 @@ export interface TreeBeta {
14121415
// @beta
14131416
export const TreeBeta: TreeBeta;
14141417

1415-
// @alpha @sealed
1418+
// @beta @sealed
14161419
export interface TreeBranch extends IDisposable {
14171420
dispose(error?: Error): void;
1418-
readonly events: Listenable_2<TreeBranchEvents>;
14191421
fork(): TreeBranch;
1420-
hasRootSchema<TSchema extends ImplicitFieldSchema>(schema: TSchema): this is TreeViewAlpha<TSchema>;
14211422
merge(branch: TreeBranch, disposeMerged?: boolean): void;
14221423
rebaseOnto(branch: TreeBranch): void;
1424+
}
1425+
1426+
// @alpha @sealed
1427+
export interface TreeBranchAlpha extends TreeBranch {
1428+
readonly events: Listenable_2<TreeBranchEvents>;
1429+
// (undocumented)
1430+
fork(): TreeBranchAlpha;
1431+
hasRootSchema<TSchema extends ImplicitFieldSchema>(schema: TSchema): this is TreeViewAlpha<TSchema>;
14231432
runTransaction<TSuccessValue, TFailureValue>(transaction: () => TransactionCallbackStatus<TSuccessValue, TFailureValue>, params?: RunTransactionParams): TransactionResultExt<TSuccessValue, TFailureValue>;
14241433
runTransaction(transaction: () => VoidTransactionCallbackStatus | void, params?: RunTransactionParams): TransactionResult;
14251434
}
@@ -1599,7 +1608,7 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
15991608
}
16001609

16011610
// @alpha @sealed
1602-
export interface TreeViewAlpha<in out TSchema extends ImplicitFieldSchema | UnsafeUnknownSchema> extends Omit<TreeView<ReadSchema<TSchema>>, "root" | "initialize">, TreeBranch {
1611+
export interface TreeViewAlpha<in out TSchema extends ImplicitFieldSchema | UnsafeUnknownSchema> extends Omit<TreeViewBeta<ReadSchema<TSchema>>, "root" | "initialize" | "fork">, TreeBranchAlpha {
16031612
// (undocumented)
16041613
readonly events: Listenable_2<TreeViewEvents & TreeBranchEvents>;
16051614
// (undocumented)
@@ -1611,6 +1620,12 @@ export interface TreeViewAlpha<in out TSchema extends ImplicitFieldSchema | Unsa
16111620
set root(newRoot: InsertableField<TSchema>);
16121621
}
16131622

1623+
// @beta @sealed
1624+
export interface TreeViewBeta<in out TSchema extends ImplicitFieldSchema> extends TreeView<TSchema>, TreeBranch {
1625+
// (undocumented)
1626+
fork(): ReturnType<TreeBranch["fork"]> & TreeViewBeta<TSchema>;
1627+
}
1628+
16141629
// @public @sealed
16151630
export class TreeViewConfiguration<const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
16161631
constructor(props: ITreeViewConfiguration<TSchema>);

packages/dds/tree/api-report/tree.beta.api.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ type ApplyKindInput<T, Kind extends FieldKind, DefaultsAreOptional extends boole
7070
Kind
7171
] extends [FieldKind.Required] ? T : [Kind] extends [FieldKind.Optional] ? T | undefined : [Kind] extends [FieldKind.Identifier] ? DefaultsAreOptional extends true ? T | undefined : T : never;
7272

73+
// @beta
74+
export function asBeta<TSchema extends ImplicitFieldSchema>(view: TreeView<TSchema>): TreeViewBeta<TSchema>;
75+
7376
// @public
7477
export enum CommitKind {
7578
Default = 0,
@@ -672,6 +675,14 @@ export interface TreeBeta {
672675
// @beta
673676
export const TreeBeta: TreeBeta;
674677

678+
// @beta @sealed
679+
export interface TreeBranch extends IDisposable {
680+
dispose(error?: Error): void;
681+
fork(): TreeBranch;
682+
merge(branch: TreeBranch, disposeMerged?: boolean): void;
683+
rebaseOnto(branch: TreeBranch): void;
684+
}
685+
675686
// @public @sealed
676687
export interface TreeChangeEvents {
677688
nodeChanged(unstable?: unknown): void;
@@ -795,6 +806,12 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
795806
upgradeSchema(): void;
796807
}
797808

809+
// @beta @sealed
810+
export interface TreeViewBeta<in out TSchema extends ImplicitFieldSchema> extends TreeView<TSchema>, TreeBranch {
811+
// (undocumented)
812+
fork(): ReturnType<TreeBranch["fork"]> & TreeViewBeta<TSchema>;
813+
}
814+
798815
// @public @sealed
799816
export class TreeViewConfiguration<const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
800817
constructor(props: ITreeViewConfiguration<TSchema>);

packages/dds/tree/api-report/tree.legacy.beta.api.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ type ApplyKindInput<T, Kind extends FieldKind, DefaultsAreOptional extends boole
7070
Kind
7171
] extends [FieldKind.Required] ? T : [Kind] extends [FieldKind.Optional] ? T | undefined : [Kind] extends [FieldKind.Identifier] ? DefaultsAreOptional extends true ? T | undefined : T : never;
7272

73+
// @beta
74+
export function asBeta<TSchema extends ImplicitFieldSchema>(view: TreeView<TSchema>): TreeViewBeta<TSchema>;
75+
7376
// @public
7477
export enum CommitKind {
7578
Default = 0,
@@ -684,6 +687,14 @@ export interface TreeBeta {
684687
// @beta
685688
export const TreeBeta: TreeBeta;
686689

690+
// @beta @sealed
691+
export interface TreeBranch extends IDisposable {
692+
dispose(error?: Error): void;
693+
fork(): TreeBranch;
694+
merge(branch: TreeBranch, disposeMerged?: boolean): void;
695+
rebaseOnto(branch: TreeBranch): void;
696+
}
697+
687698
// @public @sealed
688699
export interface TreeChangeEvents {
689700
nodeChanged(unstable?: unknown): void;
@@ -807,6 +818,12 @@ export interface TreeView<in out TSchema extends ImplicitFieldSchema> extends ID
807818
upgradeSchema(): void;
808819
}
809820

821+
// @beta @sealed
822+
export interface TreeViewBeta<in out TSchema extends ImplicitFieldSchema> extends TreeView<TSchema>, TreeBranch {
823+
// (undocumented)
824+
fork(): ReturnType<TreeBranch["fork"]> & TreeViewBeta<TSchema>;
825+
}
826+
810827
// @public @sealed
811828
export class TreeViewConfiguration<const TSchema extends ImplicitFieldSchema = ImplicitFieldSchema> implements Required<ITreeViewConfiguration<TSchema>> {
812829
constructor(props: ITreeViewConfiguration<TSchema>);

packages/dds/tree/src/api.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import {
77
type TreeView,
88
type TreeViewAlpha,
9+
type TreeViewBeta,
910
type ImplicitFieldSchema,
1011
// eslint-disable-next-line import/no-deprecated
1112
asTreeViewAlpha,
@@ -28,3 +29,13 @@ export function asAlpha<TSchema extends ImplicitFieldSchema>(
2829
// eslint-disable-next-line import/no-deprecated
2930
return asTreeViewAlpha(view);
3031
}
32+
33+
/**
34+
* Retrieve the {@link TreeViewBeta | beta API} for a {@link TreeView}.
35+
* @beta
36+
*/
37+
export function asBeta<TSchema extends ImplicitFieldSchema>(
38+
view: TreeView<TSchema>,
39+
): TreeViewBeta<TSchema> {
40+
return view as TreeViewBeta<TSchema>;
41+
}

packages/dds/tree/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export {
165165
singletonSchema,
166166
type UnsafeUnknownSchema,
167167
type TreeViewAlpha,
168+
type TreeViewBeta,
168169
type InsertableField,
169170
type Insertable,
170171
type InsertableContent,
@@ -235,6 +236,7 @@ export {
235236
type InsertableTreeNodeFromAllowedTypes,
236237
type Input,
237238
type TreeBranch,
239+
type TreeBranchAlpha,
238240
type TreeBranchEvents,
239241
asTreeViewAlpha,
240242
type NodeSchemaOptions,
@@ -338,4 +340,4 @@ export type { MapNodeInsertableData } from "./simple-tree/index.js";
338340
export { JsonAsTree } from "./jsonDomainSchema.js";
339341
export { FluidSerializableAsTree } from "./serializableDomainSchema.js";
340342
export { TableSchema, type System_TableSchema } from "./tableSchema.js";
341-
export { asAlpha } from "./api.js";
343+
export { asAlpha, asBeta } from "./api.js";

packages/dds/tree/src/shared-tree/schematizingTreeView.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ import {
7171

7272
import { canInitialize, initialize, initializerFromChunk } from "./schematizeTree.js";
7373
import type { ITreeCheckout, TreeCheckout } from "./treeCheckout.js";
74+
import type { TreeBranchAlpha } from "../simple-tree/index.js";
7475

7576
/**
7677
* Creating multiple tree views from the same checkout is not supported. This slot is used to detect if one already
@@ -513,15 +514,16 @@ export class SchematizingSimpleTreeView<
513514

514515
// #region Branching
515516

516-
public fork(): ReturnType<TreeBranch["fork"]> & SchematizingSimpleTreeView<TRootSchema> {
517+
public fork(): ReturnType<TreeBranchAlpha["fork"]> &
518+
SchematizingSimpleTreeView<TRootSchema> {
517519
return this.checkout.branch().viewWith(this.config);
518520
}
519521

520-
public merge(context: TreeBranch, disposeMerged = true): void {
522+
public merge(context: TreeBranchAlpha, disposeMerged = true): void {
521523
this.checkout.merge(getCheckout(context), disposeMerged);
522524
}
523525

524-
public rebaseOnto(context: TreeBranch): void {
526+
public rebaseOnto(context: TreeBranchAlpha): void {
525527
getCheckout(context).rebase(this.checkout);
526528
}
527529

packages/dds/tree/src/shared-tree/treeAlpha.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ import {
8585
type Observer,
8686
withObservation,
8787
} from "../feature-libraries/index.js";
88+
import type { TreeBranchAlpha } from "../simple-tree/index.js";
8889
import { independentInitializedView, type ViewContent } from "./independentView.js";
8990
import { SchematizingSimpleTreeView, ViewSlot } from "./schematizingTreeView.js";
9091
import { isFluidHandle } from "@fluidframework/runtime-utils";
@@ -230,7 +231,7 @@ export interface TreeAlpha {
230231
* This does not fork a new branch, but rather retrieves the _existing_ branch for the node.
231232
* To create a new branch, use e.g. {@link TreeBranch.fork | `myBranch.fork()`}.
232233
*/
233-
branch(node: TreeNode): TreeBranch | undefined;
234+
branch(node: TreeNode): TreeBranchAlpha | undefined;
234235

235236
/**
236237
* Construct tree content that is compatible with the field defined by the provided `schema`.
@@ -755,7 +756,7 @@ export const TreeAlpha: TreeAlpha = {
755756
return result;
756757
},
757758

758-
branch(node: TreeNode): TreeBranch | undefined {
759+
branch(node: TreeNode): TreeBranchAlpha | undefined {
759760
const kernel = getKernel(node);
760761
if (!kernel.isHydrated()) {
761762
return undefined;

packages/dds/tree/src/simple-tree/api/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ export type {
1919
TreeViewEvents,
2020
SchemaCompatibilityStatus,
2121
TreeViewAlpha,
22+
TreeViewBeta,
2223
TreeBranch,
24+
TreeBranchAlpha,
2325
TreeBranchEvents,
2426
ITreeAlpha,
2527
} from "./tree.js";

0 commit comments

Comments
 (0)