Skip to content

DRAFT: Preliminary presence runtime schema validation support #23677

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

Closed

Conversation

tylerbutler
Copy link
Member

@tylerbutler tylerbutler commented Jan 28, 2025

Adds preliminary support for runtime validation of presence data. I am mostly interested in feedback about the signature changes, the types, and where I put them.

For ease of review, there are three commits that can be reviewed separately.

Update April 9

The change now incorporates some of the initial feedback.

  1. validator and controls are now part of an options object rather than direct function args.
  2. validator is always optional in Latest and LatestMap
  3. validators all have the same signature but are passed metadata that can be used to adjust behavior. The only metadata currently provided is a key property that will be set if the value being validated is from a ValueMap.

Not yet addressed:

  • Storing validated data locally and ensuring data sent over the network is never flagged as valid without validation.

@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 area: examples Changes that focus on our examples dependencies Pull requests that update a dependency file labels Jan 28, 2025
@tylerbutler tylerbutler force-pushed the presence-schema-validation branch from fbe458d to cdaeb15 Compare April 1, 2025 18:38
@@ -494,6 +517,7 @@ export function LatestMap<
Keys extends string | number = string | number,
RegistrationKey extends string = string,
>(
validator: ValueTypeSchemaValidatorForKey<T, Keys>,
Copy link
Member Author

Choose a reason for hiding this comment

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

Should be optional.

@jason-ha
Copy link
Contributor

jason-ha commented Apr 7, 2025

  ];

This is a tricky aspect.
Here we are providing access to the new value as a push to the customer. But we haven't validated the value.
A getter for value would be fine, but we'd have to adjust the return type to allow undefined or throw on failed validation.


Refers to: packages/framework/presence/src/latestValueManager.ts:195 in cdaeb15. [](commit_id = cdaeb15, deletion_comment = False)

@jason-ha
Copy link
Contributor

jason-ha commented Apr 7, 2025

  return [

Is the valid property effectively cleared here because we rebuild the entry in mergeValueDirectory?
Otherwise, nowhere is the valid state being cleared on update AFAICT. It could be done in the statestore. The implementation is a little hard to trace - I think the bottleneck may be mergeValueDirectory in presenceStates.ts.


Refers to: packages/framework/presence/src/latestValueManager.ts:188 in cdaeb15. [](commit_id = cdaeb15, deletion_comment = False)

* Contains the validated data, or `undefined` if the value has not been validated.
*/
// valid?: JsonDeserialized<TValue> | undefined;
valid?: TValue | undefined;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

valid can be added here but it will need to be removed from ClientUpdateEntry and any places calling with that.
It may be that we need to create a separate type for remote versus local value state.
Local value state which should be the only think that ever is sent as ClientUpdateEntry should never have valid (as we rely on caller to always provide confirming values).
So maybe the stripping of valid would just need to happen when generating the complete update in response to a join. (And eventually that should be less common code path when we start using targeted signals.)

> = (
key: Keys,
unvalidatedData: unknown,
) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

Is key useful? Required?
Maybe the validator functions should all follow (unvalidatedData: unknown, metadata: ...): T | undefined and we could stick extra info in metadata.
I function declared as (unvalidatedData: unknown): T | undefined should still be acceptable as validator.

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure I understand. Are you suggesting there be a single type for all validators, and pass metadata in the second
function arg that customer code can use to determine what logic to run?

Or are you thinking more like two different types that vary on the type/contents of the metadata arg?

I'm not clear how customer code can declare validators for each key, so I thought the validator for maps would use the
key to determine what validator to run (i.e. the map validator would return a value validator). Seems like that logic is still necessary, but would be moved inside the
customer's code to read the metadata and act accordingly?

Copy link
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:
  163664 links
    1315 destination URLs
    1547 URLs ignored
       0 warnings
       0 errors


@tylerbutler
Copy link
Member Author

Superseded by more recent PRs. Closing.

@tylerbutler tylerbutler deleted the presence-schema-validation branch June 18, 2025 18:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: examples Changes that focus on our examples area: framework Framework is a tag for issues involving the developer framework. Eg Aqueduct base: main PRs targeted against main branch dependencies Pull requests that update a dependency file public api change Changes to a public API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants