Skip to content
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

Allow more cases in Tree.is #20973

Merged
merged 5 commits into from
May 10, 2024
Merged

Conversation

CraigMacomber
Copy link
Contributor

@CraigMacomber CraigMacomber commented May 3, 2024

Description

This makes 3 changes to Tree.is:

  1. calling Tree.is(node, SchemaNotUsedInTreeSchema) is no longer an error. This undocumented edge case could have been problematic, and is inconsistent since it would not fire if node was not a TreeNode.
  2. Tree.is now takes in ImplicitAllowedTypes, making cases like Tree.is(x, [schema.number, schema.string]) valid. THis is more performant and more concise then doing two separate checks and ORing them together. This also allows checking a node against an ImplicitAllowedTypes pulled from a FieldSchema which could be handy for some generic code.
  3. The implementation of Tree.schema and Tree.is have been rewritten to not rely on flex-schema as much, and fast path non-TreeNode inputs. This should make it more maintainable and more performant.

Interestingly #2 above is the only case that couldn't be covered by instanceof (assuming TypeScript 5.3): we could make instanceof do all narrowing currently done with Tree.is, except for this new case. The presence of this case thus seems to motivate keeping Tree.is if for no reason other than it can support this additional pattern which instancof cannot.

Reviewer Guidance

The review process is outlined on this wiki page.

This is a public API change, and thus needs extra review on the API and how it will impact customers.

@CraigMacomber CraigMacomber requested a review from a team as a code owner May 3, 2024 17:40
@github-actions github-actions bot added area: dds Issues related to distributed data structures area: dds: tree area: framework Framework is a tag for issues involving the developer framework. Eg Aqueduct public api change Changes to a public API base: main PRs targeted against main branch labels May 3, 2024
@msfluid-bot
Copy link
Collaborator

msfluid-bot commented May 3, 2024

@fluid-example/bundle-size-tests: +182 Bytes
Metric NameBaseline SizeCompare SizeSize Diff
aqueduct.js 455.86 KB 455.86 KB No change
azureClient.js 552.43 KB 552.43 KB No change
connectionState.js 680 Bytes 680 Bytes No change
containerRuntime.js 258.9 KB 258.9 KB No change
fluidFramework.js 358 KB 358.09 KB +91 Bytes
loader.js 133.16 KB 133.16 KB No change
map.js 41.4 KB 41.4 KB No change
matrix.js 143.64 KB 143.64 KB No change
odspClient.js 520.77 KB 520.77 KB No change
odspDriver.js 97.1 KB 97.1 KB No change
odspPrefetchSnapshot.js 41.98 KB 41.98 KB No change
sharedString.js 161.32 KB 161.32 KB No change
sharedTree.js 357.99 KB 358.08 KB +91 Bytes
Total Size 3.2 MB 3.2 MB +182 Bytes

Baseline commit: 5a15835

Generated by 🚫 dangerJS against ffabda2

@CraigMacomber CraigMacomber marked this pull request as draft May 3, 2024 20:00
@CraigMacomber CraigMacomber marked this pull request as ready for review May 9, 2024 22:16
if (actualSchema === undefined) {
return false;
}
if (isReadonlyArray<LazyItem<TreeNodeSchema>>(schema)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you want to use normalizeAllowedTypes here to avoid manually handling the array and lazies?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I started with that approach, but it incurs a lot more overhead in both the single item case and the array case. This avoids allocating the set, gets an early return on a match, avoids boxing single items into an array, avoids a bunch of calls, and extra loop etc. The code for this approach is only slightly larger.

Normalize is mainly used in places where we can cache the result and reuse it, which is not the case here (unless we wend with a different API, and returned a node filter predicate).

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it, sounds good. I wonder if we could get the benefits of the early return and no Set() allocation by using a generator that returns an iterator of the normalized schema. Something to try, later, if we find ourselves doing this same kind of thing in multiple places.

packages/dds/tree/src/simple-tree/treeApi.ts Outdated Show resolved Hide resolved
packages/dds/tree/src/simple-tree/treeApi.ts Show resolved Hide resolved
@CraigMacomber CraigMacomber merged commit 6dae7eb into microsoft:main May 10, 2024
30 checks passed
@CraigMacomber CraigMacomber deleted the isMore branch May 10, 2024 16:22
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 area: framework Framework is a tag for issues involving the developer framework. Eg Aqueduct base: main PRs targeted against main branch public api change Changes to a public API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants