Skip to content

feat(tree): add alpha Component utilities for open-polymorphic schema#27628

Open
CraigMacomber wants to merge 10 commits into
microsoft:mainfrom
CraigMacomber:componet
Open

feat(tree): add alpha Component utilities for open-polymorphic schema#27628
CraigMacomber wants to merge 10 commits into
microsoft:mainfrom
CraigMacomber:componet

Conversation

@CraigMacomber

Copy link
Copy Markdown
Contributor

Description

Promotes the Component composition namespace out of the openPolymorphism.integration.ts test file and into @fluidframework/tree as a new @alpha API (also re-exported from fluid-framework). This pattern was previously validated only by the open-polymorphism examples; it's now a supported (alpha) part of the package because an app depends on it.

Component provides utilities for composing independently authored application "components" that contribute to a shared configuration — useful for "open polymorphism" schema patterns where the set of allowed types for a field or collection can be extended by separate libraries. Each component is a Component.Factory that receives a lazy reference to the composed configuration and returns the content it contributes; Component.composeComponents combines them into a Component.ComposedComponents.

Changes:

  • New packages/dds/tree/src/simple-tree/api/componentApi.ts with the @alpha-tagged, fully documented Component namespace, exporting only what's needed (Factory, LazyArray, Configurable, composeComponents, ComposedComponents); the Config implementation class stays internal.
  • Exported from @fluidframework/tree and (via the alpha entrypoint) fluid-framework; API reports updated.
  • The integration test now imports Component instead of defining it locally.
  • New focused unit tests in componentApi.spec.ts supplementing the existing example/integration tests.
  • Fixed a latent caching bug in getConfigured (it previously ran configure on every call; now cached via getOrCreate).
  • Changeset added.

Reviewer Guidance

The review process is outlined on this wiki page.

  • The Component namespace is generic (not tied to tree types) but lives under simple-tree/api alongside other schema-composition utilities. Feedback welcome on placement and on the generic Component name for a top-level @alpha export.
  • Configurable / getConfigured are part of the proposed API but aren't exercised by the integration examples (they're now covered by unit tests). Let me know if they should be trimmed to keep the surface minimal.

Promote the Component composition namespace from the openPolymorphism integration test into @fluidframework/tree as an @Alpha API, re-exported from fluid-framework. Adds unit tests, documentation, API report updates, and a changeset.
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Hi! Thank you for opening this PR. Want me to review it?

Based on the diff (1346 lines, 8 files), I've queued these reviewers:

  • Correctness — logic errors, race conditions, lifecycle issues
  • Security — vulnerabilities, secret exposure, injection
  • API Compatibility — breaking changes, release tags, type design
  • Performance — algorithmic regressions, memory leaks
  • Testing — coverage gaps, hollow tests

How this works

  • Adjust the reviewer set by ticking/unticking boxes above. Reviewer toggles alone don't trigger anything.

  • Tick Start review below to dispatch the review fleet.

  • After review finishes, tick Start review again to request another run — it auto-resets after each dispatch.

  • This comment updates as new commits land; your reviewer selections are preserved.

  • Start review

Comment thread packages/dds/tree/src/componentApi.ts
Comment thread packages/dds/tree/src/componentApi.ts Outdated
Comment thread packages/dds/tree/src/test/openPolymorphism.integration.ts
@CraigMacomber CraigMacomber marked this pull request as ready for review July 8, 2026 22:22
@CraigMacomber CraigMacomber requested review from a team as code owners July 8, 2026 22:22
Copilot AI review requested due to automatic review settings July 8, 2026 22:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🔗 No broken links found! ✅

Your attention to detail is admirable.

linkcheck output

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-website@0.0.0 serve
> docusaurus serve --no-open

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

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

Crawling...

Stats:
  294296 links
    1937 destination URLs
    2187 URLs ignored
       0 warnings
       0 errors


type MyAppComponent = Component.Factory<Composed, MyAppComponentContent>;

// A simple item type, with the required statics.
class MyItem extends sf.object("MyItem", {}) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should this implement MyStatics?

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Bundle size comparison

Base commit: 541fb974a8c83efc941264c28cba4278b3eb7f39
Head commit: c4a9224b9b3e9ec642f311138086e5efbb9775c8

Notable changes

No bundles changed by ≥ 500 bytes parsed.

Per-bundle deltas

@fluid-example/bundle-size-tests

  • azureClient.js: parsed 619098 → 619154 (+56), gzip 164826 → 164873 (+47)
  • odspClient.js: parsed 591824 → 591880 (+56), gzip 158912 → 158955 (+43)
  • aqueduct.js: parsed 525587 → 525622 (+35), gzip 140710 → 140740 (+30)
  • fluidFramework.js: parsed 392824 → 392845 (+21), gzip 111523 → 111539 (+16)
  • sharedTree.js: parsed 382211 → 382225 (+14), gzip 108913 → 108924 (+11)
  • containerRuntime.js: parsed 303937 → 303951 (+14), gzip 83213 → 83222 (+9)
  • sharedString.js: parsed 175984 → 175991 (+7), gzip 49445 → 49453 (+8)
  • experimentalSharedTree.js: parsed 160798 → 160798 (0), gzip 45804 → 45804 (0)
  • matrix.js: parsed 159845 → 159852 (+7), gzip 45411 → 45418 (+7)
  • loader.js: parsed 145256 → 145270 (+14), gzip 39063 → 39076 (+13)
  • odspDriver.js: parsed 104329 → 104350 (+21), gzip 32646 → 32656 (+10)
  • directory.js: parsed 66616 → 66623 (+7), gzip 18532 → 18540 (+8)
  • 748.js: parsed 58793 → 58793 (0), gzip 17827 → 17827 (0)
  • map.js: parsed 46709 → 46716 (+7), gzip 14310 → 14318 (+8)
  • odspPrefetchSnapshot.js: parsed 45642 → 45656 (+14), gzip 15277 → 15285 (+8)
  • 985.js: parsed 44491 → 44491 (0), gzip 13726 → 13726 (0)
  • summarizerDelayLoadedModule.js: parsed 30749 → 30749 (0), gzip 7753 → 7753 (0)
  • socketModule.js: parsed 26476 → 26483 (+7), gzip 7885 → 7893 (+8)
  • createNewModule.js: parsed 12480 → 12480 (0), gzip 4786 → 4786 (0)
  • summaryModule.js: parsed 3797 → 3797 (0), gzip 1860 → 1860 (0)
  • connectionState.js: parsed 724 → 724 (0), gzip 429 → 429 (0)
  • sharedTreeAttributes.js: parsed 666 → 673 (+7), gzip 432 → 442 (+10)
  • debugAssert.js: parsed 429 → 429 (0), gzip 299 → 299 (0)
  • FluidFramework-HashFallback.js: parsed 422 → 422 (0), gzip 316 → 316 (0)

@@ -0,0 +1,316 @@
/*!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Obviously not for this PR, but I wonder how easy it would be to expose a more restrictive, but easier to understand model on top of this that is explicitly Tree schema focused for the common use cases. We're trying to offer a lot of flexibility below, but I imagine the vast majority of users who would want to leverage a pattern like this for SharedTree would:
a) not need a lot of the flexibility
b) find leveraging them complex / potentially confusing.

If we offered a TreeComponent API layer above this that was more prescriptive, it might give the average user an easier onboarding experience, and then they could move to the lower level alternatives as needed to address complex scenarios.

Just a thought.

@Josmithr Josmithr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This seems reasonable to expose as alpha. I think we'd really want to get a lot of user feedback before promoting further though.

Long term, this also doesn't seem like it really belongs in SharedTree. Maybe a SharedTree-specific wrapper (like I suggested here) would want to live in this package long term, but this seems general enough to live somewhere else.

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.

3 participants