Skip to content

fix(client-presence): [BREAKING CHANGE] LatestMap keys limited to strings#25904

Merged
jason-ha merged 14 commits intomicrosoft:mainfrom
jason-ha:presence/map-key-validator
Dec 17, 2025
Merged

fix(client-presence): [BREAKING CHANGE] LatestMap keys limited to strings#25904
jason-ha merged 14 commits intomicrosoft:mainfrom
jason-ha:presence/map-key-validator

Conversation

@jason-ha
Copy link
Copy Markdown
Contributor

@jason-ha jason-ha commented Nov 22, 2025

Remove number as a possible type for LatestMap keys. All given keys are stored as string record entries at runtime and thus numbers become keys. To use "number" keys, string pattern ${number} can be used for the type.

Add keyValidator to support enabling consumers to only work with validated keys. A keyValidator is recommended anytime Keys type is not string.

A `keyValidator` may now be given when creating a `LatestMap` such that only validated keys are enumerated.
@jason-ha jason-ha requested a review from tylerbutler November 22, 2025 00:59
@github-actions github-actions bot added 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 Nov 22, 2025
Copy link
Copy Markdown
Member

@tylerbutler tylerbutler left a comment

Choose a reason for hiding this comment

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

If I understand correctly, there's no way for a user to access or enumerate keys for which the validator returns undefined. I can understand this behavior for iteration, but it seems odd that .get(invalidKey) is the same as .get(missingKey). In practice maybe that distinction doesn't matter much.

@jason-ha
Copy link
Copy Markdown
Contributor Author

If I understand correctly, there's no way for a user to access or enumerate keys for which the validator returns undefined. I can understand this behavior for iteration, but it seems odd that .get(invalidKey) is the same as .get(missingKey). In practice maybe that distinction doesn't matter much.

Good question. With a keyValidator, the difference would be that the keyValidator would be invoked. So, it could be written to snoop whether something was invalid or missing.
I think we'll need to see if there is desire for something nicer.

…testMap`

`number`s have always propagated as `string`s at runtime. Removal of specification makes API types reflect this.

Internally, `objectEntries` appears to fail to fully preserve key enumeration not that `number` is not possible.
@jason-ha jason-ha changed the title feat(client-presence): LatestMap key validation option fix(client-presence): [BREAKING CHANGE] LatestMap keys limited to strings Nov 25, 2025
@jason-ha jason-ha requested a review from tylerbutler November 25, 2025 21:06
@jason-ha jason-ha linked an issue Nov 25, 2025 that may be closed by this pull request
Copy link
Copy Markdown
Member

@tylerbutler tylerbutler left a comment

Choose a reason for hiding this comment

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

LGTM.

@jason-ha jason-ha marked this pull request as ready for review December 15, 2025 23:59
Copilot AI review requested due to automatic review settings December 15, 2025 23:59
@jason-ha jason-ha requested review from a team as code owners December 15, 2025 23:59
Copy link
Copy Markdown
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

This PR introduces a breaking change to the LatestMap API by restricting keys to string type only, removing support for number keys. Since keys are stored as strings at runtime, this change clarifies the actual behavior. Additionally, it adds a keyValidator option to enable runtime validation of custom key types.

Key Changes

  • Removed number from the Keys type parameter constraint across all LatestMap interfaces and types
  • Added KeySchemaValidator<Keys> type and keyValidator optional parameter to LatestMapArguments
  • Implemented key validation logic in getRemote() and update() methods to filter out invalid keys
  • Added comprehensive test coverage for the new keyValidator functionality

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/framework/presence/src/latestMapValueManager.ts Main implementation: removed number from Keys constraint, added KeySchemaValidator type, implemented key validation in getRemote and update methods
packages/framework/presence/src/exposedInternalTypes.ts Updated MapValueState interface to constrain Keys to string only
packages/framework/presence/src/index.ts Exported the new KeySchemaValidator type
packages/framework/presence/src/stateDatastore.ts Renamed generic parameter from TUpdateValue to TLocalUpdateValue for clarity
packages/framework/presence/src/internalTypes.ts Added documentation for the update method in ValueManager interface
packages/framework/presence/src/test/schemaValidation/valueManagers.spec.ts Added comprehensive tests for keyValidator including validation behavior, event handling for invalid keys, and iterator behavior
packages/framework/presence/src/test/latestMapValueManager.spec.ts Updated type parameters to use template literal type instead of number
packages/service-clients/end-to-end-tests/azure-client/src/test/multiprocess/childClient.tool.ts Removed second type parameter from LatestMap type annotations
packages/framework/presence/api-report/presence.legacy.alpha.api.md Updated API surface to reflect breaking changes
packages/framework/presence/api-report/presence.beta.api.md Updated API surface to reflect breaking changes
.changeset/modern-candies-clean.md Documented the breaking change with appropriate section marker

@jason-ha jason-ha enabled auto-merge (squash) December 17, 2025 00:49
@github-actions
Copy link
Copy Markdown
Contributor

🔗 No broken links found! ✅

Your attention to detail is admirable.

linkcheck output


> fluid-framework-docs-site@0.0.0 ci:check-links /home/runner/work/FluidFramework/FluidFramework/docs
> start-server-and-test "npm run serve -- --no-open" 3000 check-links

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

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

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

Crawling...

Stats:
  245432 links
    1786 destination URLs
    2025 URLs ignored
       0 warnings
       0 errors


@jason-ha jason-ha merged commit c1d91d8 into microsoft:main Dec 17, 2025
33 checks passed
@jason-ha jason-ha deleted the presence/map-key-validator branch January 6, 2026 00:00
anthony-murphy-agent pushed a commit to anthony-murphy-agent/FluidFramework that referenced this pull request Jan 14, 2026
…string`s (microsoft#25904)

Remove `number` as a possible type for `LatestMap` keys. All given keys
are stored as string record entries at runtime and thus numbers become
keys. To use "number" keys, string pattern `${number}` can be used for
the type.

Add `keyValidator` to support enabling consumers to only work with
validated keys. A `keyValidator` is recommended anytime `Keys` type is
not `string`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: framework Framework is a tag for issues involving the developer framework. Eg Aqueduct base: main PRs targeted against main branch changeset-present public api change Changes to a public API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

presence: Removal of number key support in LatestMap in v2.80

4 participants