Skip to content

refactor(container-runtime): structured return types for serializeOp and getLocalState#26541

Open
anthony-murphy-agent wants to merge 3 commits intomicrosoft:mainfrom
anthony-murphy-agent:refactor/structured-return-types
Open

refactor(container-runtime): structured return types for serializeOp and getLocalState#26541
anthony-murphy-agent wants to merge 3 commits intomicrosoft:mainfrom
anthony-murphy-agent:refactor/structured-return-types

Conversation

@anthony-murphy-agent
Copy link
Contributor

@anthony-murphy-agent anthony-murphy-agent commented Feb 25, 2026

Summary

  • Change serializeOp() to return { content: string } instead of a raw string
  • Change PendingStateManager.getLocalState() to return { pending: IPendingLocalState } instead of a bare IPendingLocalState
  • Update all callers and tests to use the new structured return types

These structured return types make it straightforward to extend these functions with additional metadata in the future without further signature changes. Specifically, the staging mode pending state work in #26475 needs to add stagedHandleCache to both return types — by landing the structural change first, that PR can focus on the substantive feature logic without a large mechanical diff touching many test files.

Test plan

  • build:esnext passes for @fluidframework/container-runtime and all dependencies
  • CI validation

🤖 Generated with Claude Code

…Op and getLocalState

Change `serializeOp()` to return `{ content: string }` instead of a raw
string, and `PendingStateManager.getLocalState()` to return
`{ pending: IPendingLocalState }` instead of a bare `IPendingLocalState`.

These structured return types make it straightforward to extend these
functions with additional metadata in the future without further
signature changes.

Co-Authored-By: anthony-murphy <anthony.murphy@microsoft.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@anthony-murphy-agent
Copy link
Contributor Author

/azp run Build - api-markdown-documenter, Build - benchmark-tool, Build - build-common, Build - build-tools, Build - client packages, Build - common-utils, Build - eslint-config-fluid, Build - eslint-plugin-fluid, Build - protocol-definitions, Build site

@anthony-murphy-agent
Copy link
Contributor Author

/azp run Build - test-tools, repo-policy-check, server-gitrest, server-gitssh, server-historian, server-routerlicious

@azure-pipelines
Copy link

Commenter does not have sufficient privileges for PR 26541 in repo microsoft/FluidFramework

1 similar comment
@azure-pipelines
Copy link

Commenter does not have sufficient privileges for PR 26541 in repo microsoft/FluidFramework

@anthony-murphy
Copy link
Contributor

/azp run Build - api-markdown-documenter, Build - benchmark-tool, Build - build-common, Build - build-tools, Build - client packages, Build - common-utils, Build - eslint-config-fluid, Build - eslint-plugin-fluid, Build - protocol-definitions, Build site

@anthony-murphy
Copy link
Contributor

/azp run Build - test-tools, repo-policy-check, server-gitrest, server-gitssh, server-historian, server-routerlicious

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

1 similar comment
@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

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

Refactors container-runtime op serialization and pending state plumbing to return structured objects instead of raw values, enabling future extension (e.g., adding staging-mode metadata) without another broad mechanical signature change.

Changes:

  • Updated serializeOp() to return { content: string } and adjusted all call sites/tests to use .content.
  • Updated PendingStateManager.getLocalState() to return { pending: IPendingLocalState } and adjusted all call sites/tests to use .pending.
  • Updated runtime pending-state assembly to consume the new getLocalState() shape.

Reviewed changes

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

Show a summary per file
File Description
packages/runtime/container-runtime/src/opLifecycle/opSerialization.ts Changes serializeOp() to return a structured object { content }.
packages/runtime/container-runtime/src/opLifecycle/outbox.ts Adapts outbound message creation to use serializeOp(...).content.
packages/runtime/container-runtime/src/opLifecycle/batchManager.ts Updates rollback telemetry payload to use serializeOp(...).content.
packages/runtime/container-runtime/src/pendingStateManager.ts Wraps local pending state return value as { pending: ... } and updates stored op content to use .content.
packages/runtime/container-runtime/src/containerRuntime.ts Destructures { pending } from getLocalState() when building IPendingRuntimeState.
packages/runtime/container-runtime/src/test/opLifecycle/outbox.spec.ts Updates test helper serialization usage to .content.
packages/runtime/container-runtime/src/test/opLifecycle/opSerialization.spec.ts Updates assertions for the new { content } return shape.
packages/runtime/container-runtime/src/test/pendingStateManager.spec.ts Updates pending state access paths to .pending.pendingStates / .pending.
packages/runtime/container-runtime/src/test/containerRuntime.spec.ts Updates pending state assertions to .pending.pendingStates.

Fix line-length formatting issues flagged by biome check.

Co-Authored-By: anthony-murphy <anthony.murphy@microsoft.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@anthony-murphy-agent
Copy link
Contributor Author

After the latest push (formatting fixes for biome), the following Azure Pipelines need to be triggered. Please copy and post these commands:

/azp run Build - client packages
/azp run Build - api-markdown-documenter
/azp run Build - benchmark-tool
/azp run Build - build-common
/azp run Build - build-tools
/azp run Build - common-utils
/azp run Build - eslint-config-fluid
/azp run Build - eslint-plugin-fluid
/azp run Build - protocol-definitions
/azp run Build - test-tools
/azp run repo-policy-check
/azp run server-gitrest
/azp run server-gitssh
/azp run server-historian
/azp run server-routerlicious

@anthony-murphy
Copy link
Contributor

/azp run Build - client packages
/azp run Build - api-markdown-documenter
/azp run Build - benchmark-tool
/azp run Build - build-common
/azp run Build - build-tools
/azp run Build - common-utils
/azp run Build - eslint-config-fluid
/azp run Build - eslint-plugin-fluid
/azp run Build - protocol-definitions
/azp run Build - test-tools

@azure-pipelines
Copy link

No pipelines are associated with this pull request.

@anthony-murphy
Copy link
Contributor

/azp run repo-policy-check
/azp run server-gitrest
/azp run server-gitssh
/azp run server-historian
/azp run server-routerlicious

@azure-pipelines
Copy link

No pipelines are associated with this pull request.

@anthony-murphy
Copy link
Contributor

/azp run Build - api-markdown-documenter, Build - benchmark-tool, Build - build-common, Build - build-tools, Build - client packages, Build - common-utils, Build - eslint-config-fluid, Build - eslint-plugin-fluid, Build - protocol-definitions, Build site

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@anthony-murphy
Copy link
Contributor

/azp run Build - test-tools, repo-policy-check, server-gitrest, server-gitssh, server-historian, server-routerlicious

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

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

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Comment on lines 1713 to +1719
const state = pendingStateManager.getLocalState();

assert.notStrictEqual(state, undefined, "expect pending local state");
assert.strictEqual(state?.pendingStates.length, 1, "expect 1 pending message");
assert.strictEqual(state?.pending.pendingStates.length, 1, "expect 1 pending message");
assert.deepStrictEqual(
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
JSON.parse(state?.pendingStates?.[0].content).contents.contents,
JSON.parse(state?.pending.pendingStates?.[0].content).contents.contents,
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

In this file there are still PendingStateManager proxy mocks that implement getLocalState with the old return shape (returning IPendingLocalState or undefined). With the new getLocalState(): { pending: IPendingLocalState } signature (and ContainerRuntime.getPendingLocalState destructuring { pending }), those tests will either throw (when undefined is returned) or produce pending === undefined, causing assertions to fail. Update the mocks to return { pending: { pendingStates: ... } } (and for the “no pending state” case, return an empty pendingStates array rather than undefined).

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.

Good catch! I understand the feedback: the PendingStateManager proxy mocks in containerRuntime.spec.ts that implement getLocalState still return the old shape (IPendingLocalState or undefined), but they need to return the new { pending: IPendingLocalState } wrapper object. I'll investigate the mock locations and update them to match the new return type.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in f6b87b7. Updated all three PendingStateManager proxy mocks in containerRuntime.spec.ts:

  1. The "no pending state" mock (line ~2256) now returns { pending: { pendingStates: [] } } instead of undefined
  2. The "getPendingLocalState" test mock (line ~2302) now returns { pending: { pendingStates } } instead of { pendingStates }
  3. The "sessionExpiryTimerStarted" test mock (line ~2373) now returns { pending: { pendingStates } } instead of { pendingStates }

Also removed the now-unused IPendingLocalState import. Build passes locally.

…te shape

Update three proxy mocks in containerRuntime.spec.ts to return
`{ pending: { pendingStates } }` instead of the old `IPendingLocalState`
shape. Remove unused IPendingLocalState import.

Co-Authored-By: anthony-murphy <anthony.murphy@microsoft.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@anthony-murphy-agent
Copy link
Contributor Author

After the latest push (mock fixes for review feedback), the following Azure Pipelines need to be triggered. Please copy and post these commands:

/azp run Build - client packages
/azp run Build - api-markdown-documenter
/azp run Build - benchmark-tool
/azp run Build - build-common
/azp run Build - build-tools
/azp run Build - common-utils
/azp run Build - eslint-config-fluid
/azp run Build - eslint-plugin-fluid
/azp run Build - protocol-definitions
/azp run Build - test-tools
/azp run repo-policy-check
/azp run server-gitrest
/azp run server-gitssh
/azp run server-historian
/azp run server-routerlicious

@anthony-murphy
Copy link
Contributor

/azp run Build - api-markdown-documenter, Build - benchmark-tool, Build - build-common, Build - build-tools, Build - client packages, Build - common-utils, Build - eslint-config-fluid, Build - eslint-plugin-fluid, Build - protocol-definitions, Build site

@anthony-murphy
Copy link
Contributor

/azp run Build - test-tools, repo-policy-check, server-gitrest, server-gitssh, server-historian, server-routerlicious

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

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

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

@anthony-murphy
Copy link
Contributor

/azp run Build - api-markdown-documenter, Build - benchmark-tool, Build - build-common, Build - build-tools, Build - client packages, Build - common-utils, Build - eslint-config-fluid, Build - eslint-plugin-fluid, Build - protocol-definitions, Build site

@anthony-murphy
Copy link
Contributor

/azp run Build - test-tools, repo-policy-check, server-gitrest, server-gitssh, server-historian, server-routerlicious

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

1 similar comment
@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

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