[Preview NG] Add typed preview message protocol with validators#3474
[Preview NG] Add typed preview message protocol with validators#3474jeremywiebe merged 4 commits intomainfrom
Conversation
🗄️ Schema Change: No Changes ✅ |
🛠️ Item Splitting: No Changes ✅ |
|
Size Change: 0 B Total Size: 499 kB ℹ️ View Unchanged
|
ee718e7 to
65e0894
Compare
90e2d9d to
2ea7fb6
Compare
npm Snapshot: PublishedGood news!! We've packaged up the latest commit from this PR (7a3dded) and published it to npm. You Example: pnpm add @khanacademy/perseus@PR3474If you are working in Khan Academy's frontend, you can run the below command. ./dev/tools/bump_perseus_version.ts -t PR3474If you are working in Khan Academy's webapp, you can run the below command. ./dev/tools/bump_perseus_version.js -t PR3474 |
5557535 to
2ab6750
Compare
…iew message types and validation functions with tests
2ab6750 to
ab31f4a
Compare
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.
Tip: disable this comment in your organization's Code Review settings.
| * identifier to be from a Perseus preview host. | ||
| * | ||
| * @param message - Unknown message to validate | ||
| * @returns True if message is a valid ParentToIframeMessage |
There was a problem hiding this comment.
Since these two functions are equivalent, does that mean that this scaffolding is here for future changes that would cause them to diverge? If such future changes are not expected in the near term, perhaps a comment somewhere on this page explaining the expected nature of the changes?
There was a problem hiding this comment.
Yes. These two function are used in upcoming PRs to filter and type check messages coming into a context via postMessage().
I wanted to make the PRs as small as possible so they are by themselves in a PR. I'd like to avoid hedging these comments and just state them as they'll be in the final state if that's ok.
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @khanacademy/perseus-editor@30.3.0 ### Minor Changes - [#3474](#3474) [`b78e2ce5c3`](b78e2ce) Thanks [@jeremywiebe](https://github.com/jeremywiebe)! - Add typed preview message protocol with message types, validators, and tests ### Patch Changes - Updated dependencies \[[`2f2724d244`](2f2724d), [`27e66ce3a6`](27e66ce), [`b8ed10349d`](b8ed103)]: - @khanacademy/perseus-core@24.1.1 - @khanacademy/perseus@77.2.2 - @khanacademy/keypad-context@3.2.43 - @khanacademy/kmath@2.4.1 - @khanacademy/math-input@26.4.14 - @khanacademy/perseus-linter@4.9.4 - @khanacademy/perseus-score@8.6.1 ## @khanacademy/keypad-context@3.2.43 ### Patch Changes - Updated dependencies \[[`2f2724d244`](2f2724d)]: - @khanacademy/perseus-core@24.1.1 ## @khanacademy/kmath@2.4.1 ### Patch Changes - Updated dependencies \[[`2f2724d244`](2f2724d)]: - @khanacademy/perseus-core@24.1.1 ## @khanacademy/math-input@26.4.14 ### Patch Changes - Updated dependencies \[[`2f2724d244`](2f2724d)]: - @khanacademy/perseus-core@24.1.1 - @khanacademy/keypad-context@3.2.43 ## @khanacademy/perseus@77.2.2 ### Patch Changes - [#3491](#3491) [`27e66ce3a6`](27e66ce) Thanks [@ivyolamit](https://github.com/ivyolamit)! - Interactive Graph: Fix Asymptote Line Thickness on Keyboard Focus for exponential and logarithm - [#3489](#3489) [`b8ed10349d`](b8ed103) Thanks [@ivyolamit](https://github.com/ivyolamit)! - Interactive Graph: Fix Asymptote Drag Handle Blocked by Curve Line for Logarithm and Exponential - Updated dependencies \[[`2f2724d244`](2f2724d)]: - @khanacademy/perseus-core@24.1.1 - @khanacademy/keypad-context@3.2.43 - @khanacademy/kmath@2.4.1 - @khanacademy/math-input@26.4.14 - @khanacademy/perseus-linter@4.9.4 - @khanacademy/perseus-score@8.6.1 ## @khanacademy/perseus-core@24.1.1 ### Patch Changes - [#3480](#3480) [`2f2724d244`](2f2724d) Thanks [@benchristel](https://github.com/benchristel)! - Hide exports that aren't used in frontend from the documentation. ## @khanacademy/perseus-linter@4.9.4 ### Patch Changes - Updated dependencies \[[`2f2724d244`](2f2724d)]: - @khanacademy/perseus-core@24.1.1 - @khanacademy/kmath@2.4.1 ## @khanacademy/perseus-score@8.6.1 ### Patch Changes - Updated dependencies \[[`2f2724d244`](2f2724d)]: - @khanacademy/perseus-core@24.1.1 - @khanacademy/kmath@2.4.1
…#3492) ## Summary: _This PR is part of a series building a typed, hook-based preview system for the Perseus editor. The new system replaces the untyped window.iframeDataStore + raw postMessage(string) communication with structured, validated message passing via usePreviewHost and usePreviewClient hooks. The new system is being built alongside the old one — no existing behaviour changes until the final PR in the series flips the switch._ * #3464 * #3467 * #3474 --- Adds `sanitizeApiOptions()` and `sanitizePreviewData()` which strip non-serializable values (function callbacks, React components) from preview data before it's sent via `postMessage`. The structured clone algorithm used by `postMessage` can't handle functions, so they need to be removed before sending. `sanitizeApiOptions()` destructures `APIOptions` to remove known non-serializable fields (`onFocusChange`, `trackInteraction`, `imagePreloader`, `nativeKeypadProxy`, placeholder components, etc.) and returns only the serializable remainder. `sanitizePreviewData()` wraps this for all preview content types — question, hint, article, and article-all. The article-all case currently sanitizes per-section since each `ArticlePreviewData` carries its own `apiOptions`; this will be simplified when we restructure the preview data types in a later PR. Purely additive — no existing behaviour is changed. **Depends on:** #3474 Issue: LEMS-3741 ## Test plan: `pnpm test` Author: jeremywiebe Reviewers: jeremywiebe, claude[bot], mark-fitzgerald, catandthemachines Required Reviewers: Approved By: mark-fitzgerald Checks: ⏭️ 1 check has been skipped, ✅ 10 checks were successful Pull Request URL: #3492
Summary:
This PR is part of a series building a typed, hook-based preview system for the Perseus editor. The new system replaces the untyped window.iframeDataStore + raw postMessage(string) communication with structured, validated message passing via usePreviewHost and usePreviewClient hooks. The new system is being built alongside the old one — no existing behaviour changes until the final PR in the series flips the switch.
Adds the typed message protocol that will underpin a new hook-based preview system for the Perseus editor. These types will allow us to understand and more easily control the data that is being sent between the editor and the preview iframe (in both directions). Purely additive — no existing behavior is changed.
The existing
message-types.tsdefined data types for preview content but had no structure for the messages themselves. This PR adds aPREVIEW_MESSAGE_SOURCEconstant, base interfaces for structured messages, typed message definitions for both directions (iframe-to-parent and parent-to-iframe), and union types for use in message event handlers. New type guards inmessage-validators.tssafely narrow unknownpostMessageevents.All existing types and the preview renderer are untouched — the new protocol types will be consumed by hooks in subsequent PRs.
Issue: LEMS-3741
Test plan:
pnpm test