Port text-editor to shared example setup - #28259
Craig Macomber (Microsoft) (CraigMacomber) merged 5 commits into
Conversation
|
Hi! Thank you for opening this PR. Want me to review it? Based on the diff (693 lines, 19 files), I've queued these reviewers:
How this works
|
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The only remaining comment is a minor test-coverage nit, with no approval-blocking issues identified.
Review effort: Lite
Findings: None
What changed in this PR
Migrates the text editor to shared ServiceClient startup infrastructure and reusable loading/error views while preserving collaboration and Devtools behavior.
Changes:
- Supports session, ephemeral, and Tinylicious services.
- Reuses React roots across startup transitions.
- Updates tests, documentation, webpack configuration, and dependencies.
| File | Description |
|---|---|
pnpm-lock.yaml |
Updates workspace dependency links. |
examples/utils/example-utils/src/test/exampleApp.spec.ts |
Tests startup views and service selection. |
examples/utils/example-utils/src/index.ts |
Exports shared startup views. |
examples/utils/example-utils/src/exampleApp.ts |
Adds shared views and React root reuse. |
examples/data-objects/text-editor/webpack.config.cjs |
Uses shared webpack configuration. |
examples/data-objects/text-editor/tests/textEditor.test.ts |
Adds multi-service collaboration coverage. |
examples/data-objects/text-editor/src/test/app.test.tsx |
Updates component test fixtures. |
examples/data-objects/text-editor/src/app.tsx |
Migrates to ServiceClient and Devtools setup. |
examples/data-objects/text-editor/README.md |
Documents services and compatibility limitations. |
examples/data-objects/text-editor/package.json |
Updates scripts and dependencies. |
examples/data-objects/inventory-app/src/index.ts |
Adds shared loading and error handling. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
🔗 No broken links found! ✅ Your attention to detail is admirable. linkcheck output |
Bundle size comparisonBase commit: Notable changesNo bundles changed by ≥ 500 bytes parsed. Per-bundle deltas
|
Joshua Smithrud (Josmithr)
left a comment
There was a problem hiding this comment.
Left some suggestions, but overall looks good.
| "fluid-framework": minor | ||
| "__section": feature | ||
| --- | ||
|
|
There was a problem hiding this comment.
|
|
||
| Collect container telemetry through ServiceClient | ||
|
|
||
| The alpha `ServiceOptions` interface now accepts an optional `logger`. |
There was a problem hiding this comment.
Nit: API docs link (assuming they're available)?
| // eslint-disable-next-line import-x/no-internal-modules -- TODO: migrate to `FormattedText` with explicit parameterization. | ||
| import { FormattedTextDefault } from "@fluidframework/tree/internal"; | ||
| import type { IFluidContainer } from "fluid-framework"; | ||
| import { configuredSharedTree, FormattedTextDefault } from "@fluidframework/tree/internal"; |
There was a problem hiding this comment.
Nit: do we need to import this from the internal entrypoint?
There was a problem hiding this comment.
And actually, since we're importing other things from fluid-framework, do we need to be importing anything from tree directly at all?
| const TextEditorDataStore = defineDataStore<TextEditorData, ITree>({ | ||
| type: "text-editor", | ||
| registry: sharedObjectRegistryFromIterable([SharedTree]), | ||
| instantiateFirstTime: async (rootCreator, creator) => | ||
| instantiateTreeFirstTime(rootCreator, creator, SharedTree, { | ||
| config: treeConfig, | ||
| initializer: () => createInitialRoot(), | ||
| }), | ||
| endpoint: getTinyliciousEndpoint(), | ||
| }; | ||
| view: async (tree) => ({ tree, treeView: asAlpha(tree.viewWith(treeConfig)) }), | ||
| }); | ||
|
|
||
| interface TextEditorData { | ||
| tree: ITree; | ||
| treeView: TreeViewAlpha<typeof TextEditorRoot>; | ||
| } |
There was a problem hiding this comment.
Nit: docs (since this is an example)?
| * Generates a fresh {@link UserId}. | ||
| * | ||
| * Random so simulated users stay unique in the document's audience even across page | ||
| * Random so simulated users stay unique across page |
There was a problem hiding this comment.
Nit
| * Random so simulated users stay unique across page | |
| * @remarks | |
| * This is random so simulated users stay unique across page |
| const { container, treeView } = await loadExistingContainer(client, containerId); | ||
| return { id, container, treeView }; | ||
| } | ||
| type ConnectUser = (containerId: string) => Promise<UserView>; |
There was a problem hiding this comment.
Nit: docs (since this is an example)?
| } | ||
| type ConnectUser = (containerId: string) => Promise<UserView>; | ||
|
|
||
| async function initFluid(): Promise<{ |
There was a problem hiding this comment.
Not necessarily for this PR, but we should probably rename this to "initializeFluid" or "initializeFluidContainer" or something to better follow our guidelines.
| containerId: string; | ||
| devtoolsLogger: IDevtoolsLogger; | ||
| initialUsers: UserView[]; | ||
| connectUser: ConnectUser; |
There was a problem hiding this comment.
Nit: param docs?
| return { id: makeUserId(), container: loaded, treeView: loaded.data.treeView }; | ||
| }; | ||
| const rawContainerId = location.hash.slice(1); | ||
| if (rawContainerId.length > 0 && !/^[\dA-Za-z-]{3,64}$/.test(rawContainerId)) { |
There was a problem hiding this comment.
Docs here would probably be useful. IMO regex_s should always be at least minimally documented.
| @@ -3,67 +3,27 @@ | |||
| * Licensed under the MIT License. | |||
There was a problem hiding this comment.
So much simpler!!
|
I'm going to merge this, and make a new PR addressing all of your excellent feedback. |
1126100
into
microsoft:main
Description
Migrate text-editor to the shared ServiceClient and webpack setup used by inventory-app.
Devtools support required an extension to ServiceClient to support a logger which is included.
Add shared loading and error views with service-specific troubleshooting, and use them in both examples. Reuse the React root across startup transitions so guidance remains visible while connections retry.
Validation included interactive use of both examples suing this new pattern and checking dev tools work were working.
Reviewer Guidance
The review process is outlined in the pull request guidelines.