Skip to content

Add tree context API#26432

Open
noencke wants to merge 4 commits intomicrosoft:mainfrom
noencke:tree-context
Open

Add tree context API#26432
noencke wants to merge 4 commits intomicrosoft:mainfrom
noencke:tree-context

Conversation

@noencke
Copy link
Contributor

@noencke noencke commented Feb 12, 2026

This adds a new tree static function Tree.context(node) which yields a new type: a TreeContext. A TreeContext is a further generalization of branch and view. So the hierarchy (from most general to most specific) is now:

TreeContext - A place for functions that don't require the caller to have hydrated/attached content - i.e., the ST DDS / Fluid are not necessarily reachable.
TreeBranch - A place for functions that do require the caller to have hydrated content, and can reach the ST/Fluid.
TreeView - A schematized tree branch

Accordingly, you use isBranch() to downcast a TreeContext to a TreeBranch, and then hasRootSchema to downcast a TreeBranch to a TreeView.

TreeContext is now the home of runTransaction, since runTransaction can operate on both hydrated and unhydrated nodes - in the latter case, it simply runs the transaction delegate. This lets you do Tree.context(node).runTransaction(...) without having to worry about whether node is hydrated or not. Note that this "upcasted" version of runTransaction does not have any options (like labels, or constraints) because those don't make sense until you downcast to a branch.

Tree.branch is now deprecated in favor of Tree.context() + context.isBranch(). This is slightly more verbose for some situations but it is trivial for a consumer to write a helper to replicate the previous behavior of Tree.branch if they want the one-liner. By removing Tree.branch, we avoid an awkward naming dilemma: most other Tree.* functions are single nouns which retrieve that noun, and the same is true for branch - but "branch" is also a verb, which makes it sound like the API is forking.

@noencke noencke requested a review from a team as a code owner February 12, 2026 20:11
Copilot AI review requested due to automatic review settings February 12, 2026 20:11
@noencke noencke requested a review from a team as a code owner February 12, 2026 20:11
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new TreeAlpha.context(node) API that provides a unified interface for working with both hydrated (in-document) and unhydrated (newly created) tree nodes. The key innovation is the introduction of a three-tier hierarchy: TreeContextAlpha (most general) → TreeBranchAlphaTreeViewAlpha (most specific), where each level adds capabilities that require more context.

Changes:

  • Adds TreeContextAlpha interface with runTransaction, runTransactionAsync, and isBranch() methods that work for both hydrated and unhydrated nodes
  • Deprecates TreeAlpha.branch() in favor of the new TreeAlpha.context() + context.isBranch() pattern
  • Refactors transaction types to introduce a WithValue<T> interface that simplifies the transaction API for common cases

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/dds/tree/src/simple-tree/api/tree.ts Defines TreeContextAlpha interface and updates TreeBranchAlpha to extend it; adds deprecation notice to TreeAlpha.branch
packages/dds/tree/src/shared-tree/treeAlpha.ts Implements TreeAlpha.context() and UnhydratedTreeContext class for unhydrated nodes
packages/dds/tree/src/shared-tree/schematizingTreeView.ts Implements isBranch() method on SchematizingSimpleTreeView
packages/dds/tree/src/simple-tree/api/transactionTypes.ts Introduces WithValue<T> interface and refactors transaction result types to use it
packages/dds/tree/src/test/simple-tree/treeBranch.spec.ts Adds comprehensive test suite for branch functionality (new file)
packages/dds/tree/src/test/simple-tree/api/treeNodeApi.spec.ts Adds tests for the new context() API
packages/dds/tree/src/simple-tree/api/index.ts Exports new TreeContextAlpha and WithValue types
packages/dds/tree/src/simple-tree/index.ts Exports new types from api layer
packages/dds/tree/src/index.ts Exports new types to public API surface
packages/dds/tree/api-report/tree.alpha.api.md API report reflecting new types and deprecations
packages/framework/fluid-framework/api-report/fluid-framework.alpha.api.md API report for fluid-framework package
.changeset/green-sides-watch.md Changeset documentation with migration guide

private static wrapTransactionResult<TValue>(
value: WithValue<TValue> | void,
): TransactionResultExt<TValue, TValue> | TransactionResult {
if (value?.value !== undefined) {
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition value?.value !== undefined will incorrectly treat {value: 0}, {value: false}, {value: ""}, and {value: null} as if no value was returned. This should check value !== undefined && "value" in value instead to properly distinguish between a void return and a WithValue return.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh? Am I crazy, or are you?

@github-actions
Copy link
Contributor

🔗 No broken links found! ✅

Your attention to detail is admirable.

linkcheck output


> fluid-framework-docs-site@0.0.0 ci:check-links /home/runner/work/FluidFramework/FluidFramework/docs
> start-server-and-test "npm run serve -- --no-open" 3000 check-links

1: starting server using command "npm run serve -- --no-open"
and when url "[ 'http://127.0.0.1:3000' ]" is responding with HTTP status code 200
running tests using command "npm run check-links"


> fluid-framework-docs-site@0.0.0 serve
> docusaurus serve --no-open

[SUCCESS] Serving "build" directory at: http://localhost:3000/

> fluid-framework-docs-site@0.0.0 check-links
> linkcheck http://localhost:3000 --skip-file skipped-urls.txt

Crawling...

Stats:
  257699 links
    1822 destination URLs
    2063 URLs ignored
       0 warnings
       0 errors


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants