Skip to content

Cleanup unhydrated tree and tree import code more generally #24740

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 31, 2025

Conversation

CraigMacomber
Copy link
Contributor

Description

Cleanups split out of #24739

Reviewer Guidance

The review process is outlined on this wiki page.

@Copilot Copilot AI review requested due to automatic review settings May 30, 2025 20:39
@CraigMacomber CraigMacomber requested a review from a team as a code owner May 30, 2025 20:39
@github-actions github-actions bot added area: dds Issues related to distributed data structures area: dds: tree base: main PRs targeted against main branch labels May 30, 2025
Copy link
Contributor

@Copilot 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 cleans up and refactors tree import and unhydrated tree code as part of the overall project maintenance. Key changes include updating error message patterns in verbose tree imports, refining type definitions (e.g. for flexible node content), and updating test cases to reflect these changes.

Reviewed Changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/dds/tree/src/test/simple-tree/api/treeNodeApi.spec.ts Added tests for various error cases in verbose tree imports with updated error messages.
packages/dds/tree/src/test/simple-tree/api/create.spec.ts Updated test cases to differentiate failure messages for unknown and out-of-schema inputs.
packages/dds/tree/src/test/shared-tree/schematizingTreeView.spec.ts Removed the unused nodeKeyManager parameter from helper function calls.
packages/dds/tree/src/simple-tree/toStoredSchema.ts Refactored type definitions by enforcing readonly maps for field kinds conversion.
packages/dds/tree/src/simple-tree/toMapTree.ts Changed internal helper function names and logic without altering external behavior.
packages/dds/tree/src/simple-tree/node-kinds/map/mapNode.ts Updated the return type for the editor method to reflect flexible node content.
packages/dds/tree/src/simple-tree/node-kinds/array/arrayNode.ts Adjusted private method return types to use flexible field content.
packages/dds/tree/src/simple-tree/api/verboseTree.ts & customTree.ts Updated error handling and introduced an unknown type error helper for consistency.
packages/dds/tree/src/feature-libraries Various updates to type definitions, adapters, and context adjustments to improve type safety.
packages/dds/tree/src/core/tree/mapTree.ts Refactored deep copy logic to improve immutability and added an assertion for empty field checks.
Comments suppressed due to low confidence (1)

packages/dds/tree/src/test/simple-tree/api/create.spec.ts:29

  • [nitpick] The error validation in the 'Failure: unknown schema' test uses validateAssertionError, while other tests use validateUsageError, which might lead to inconsistencies in error handling. Consider reviewing and unifying the expected error type across similar tests.
assert.throws(() => createFromCursor(SchemaFactory.number, cursor), (e: Error) => validateAssertionError(e, /Tree does not conform to schema/),

if (field.length > 0) {
const newField: ExclusiveMapTree[] = [];
for (const child of field) {
const childClone: ExclusiveMapTree = { ...child, fields: new Map() };
const childClone = create(child, new Map());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the use of spread here and below broke when using implementations of where type or value as a getter (not enumerable) or there were other enumerable properties which should not be copied.

spread was used to avoid including the value property when not present, but that has been reimplemented in create above.

@@ -36,17 +39,32 @@ export interface ExclusiveMapTree extends NodeData, MapTree {
* @privateRemarks This is implemented iteratively (rather than recursively, which is much simpler)
* to avoid the possibility of a stack overflow for very deep trees.
*/
export function deepCopyMapTree(mapTree: MapTree): ExclusiveMapTree {
type Next = [fields: ExclusiveMapTree["fields"], sourceFields: MapTree["fields"]];
export function deepCopyMapTree(mapTree: MinimalMapTreeNodeView): ExclusiveMapTree {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This can now copy from any MinimalMapTreeNodeView: an interface UnhydratedFlexTree nodes start implementing in #24739

@@ -448,7 +448,7 @@ export interface SequenceFieldEditBuilder<TContent> {
* @param index - The index of the first removed element.
* @param count - The number of elements to remove.
*/
remove(index: number, count: number): void;
remove(index: number, count: number): TRemoved;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The unhydrated flex tree implements returning the results from remove. This allows that to be expressed more clearly.

@@ -45,7 +45,7 @@ export function inSchemaOrThrow(maybeError: SchemaValidationError | undefined):
* Deeply checks that the provided node complies with the schema based on its identifier.
*/
export function isNodeInSchema(
node: MapTree,
node: MinimalMapTreeNodeView,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

More general type, so it can apply to unhydrated flex tree nodes in #24739

@@ -231,3 +232,9 @@ export function replaceHandles<T>(tree: unknown, replacer: HandleConverter<T>):
}
});
}

export function unknownTypeError(type: string): never {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Some new tests for verbose tree show its possible to hit an assert, which has been replaced with this usage error. #24739 ends up adding a second case which needs this same error so its broken out into a reusable function.

Copy link
Contributor

Choose a reason for hiding this comment

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

Function docs? 😁

Comment on lines 436 to 437
/**
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

Any docs we can add to this? Alternatively, can we remove the blank comment block?

extends MapTreeNodeViewGeneric<MinimalMapTreeNodeView> {}

{
type _check1 = requireAssignableTo<MapTree, MinimalMapTreeNodeView>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: a quick comment explaining the type checks would probably be good.

Comment on lines 70 to 81
export function mapTreeWithField(
children: ExclusiveMapTree[],
key = rootFieldKey,
type = aboveRootPlaceholder,
): MapTree {
return {
type,
fields: mapTreeFieldsWithField(children, key),
};
}

export function mapTreeFieldsWithField<T extends readonly unknown[]>(
Copy link
Contributor

Choose a reason for hiding this comment

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

Docs?

@@ -72,6 +72,8 @@ export function stackTreeFieldCursor<TNode>(
return cursor;
}

export type Field<TNode> = Pick<readonly TNode[], typeof Symbol.iterator | "length" | number>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Docs?

CraigMacomber and others added 4 commits May 30, 2025 16:20
Co-authored-by: Joshua Smithrud <54606601+Josmithr@users.noreply.github.com>
Co-authored-by: Joshua Smithrud <54606601+Josmithr@users.noreply.github.com>
Co-authored-by: Joshua Smithrud <54606601+Josmithr@users.noreply.github.com>
Co-authored-by: Joshua Smithrud <54606601+Josmithr@users.noreply.github.com>
@CraigMacomber CraigMacomber merged commit 0762660 into microsoft:main May 31, 2025
33 checks passed
@CraigMacomber CraigMacomber deleted the ToMapTreeCleanup branch May 31, 2025 01:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: dds: tree area: dds Issues related to distributed data structures base: main PRs targeted against main branch
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants