Skip to content

feat: add properties path tree to ObserverMapConfig in fast-html#7448

Merged
janechu merged 7 commits intomainfrom
users/janechu/add-observer-map-opt-in-properties
Apr 21, 2026
Merged

feat: add properties path tree to ObserverMapConfig in fast-html#7448
janechu merged 7 commits intomainfrom
users/janechu/add-observer-map-opt-in-properties

Conversation

@janechu
Copy link
Copy Markdown
Collaborator

@janechu janechu commented Apr 16, 2026

Pull Request

📖 Description

Adds a properties key to the ObserverMapConfig interface in @microsoft/fast-html so that developers can opt specific root properties and nested sub-paths in or out of automatic observer-map observation, rather than the current all-or-nothing approach.

Each path entry can be:

  • true — observe this path and all descendants
  • false — skip this path and all descendants
  • ObserverMapPathNode — an object with optional $observe boolean and child overrides, enabling alternating opt-in/opt-out to arbitrary depth

When properties is omitted (observerMap: {} or observerMap: "all"), current behavior is preserved. When properties is present but empty ({ properties: {} }), no root properties are observed.

🎫 Issues

👩‍💻 Reviewer Notes

Key areas to review:

  • observer-map.ts: New hasObservedPath helper and config filtering logic in defineProperties()
  • utilities.ts: Config threading through the proxy system (assignObservables, assignProxyToItemsInObject, assignProxy), particularly the set trap changes that skip notification for excluded properties
  • template.ts: New types (ObserverMapPathEntry, ObserverMapPathNode) and config extraction for ObserverMap constructor

📑 Test Plan

  • All 289 existing + new Chromium tests pass
  • New unit tests in observer-map.spec.ts covering:
    • Skipping unlisted root properties
    • Skipping false root properties
    • Observe-all with empty config ({})
    • Observe-nothing with empty properties ({ properties: {} })
  • New fixture tests in observer-map-properties/ covering:
    • Selective root property observation
    • Excluded subtrees (false)
    • Re-included leaf within $observe: false branch
    • Unlisted root properties remaining unobserved
    • Array observation with selective config
    • Empty config object backward compatibility

✅ Checklist

General

  • I have included a change request file using $ npm run change
  • I have added tests for my changes.
  • I have tested my changes.
  • I have updated the project documentation to reflect my changes.
  • I have read the CONTRIBUTING documentation and followed the standards for this project.

@janechu janechu marked this pull request as ready for review April 16, 2026 22:49
@janechu janechu requested a review from Copilot April 16, 2026 22:50
Copy link
Copy Markdown

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

Adds path-level configuration to @microsoft/fast-html’s observerMap option so templates can selectively observe specific root properties and nested subpaths, enabling granular opt-in/opt-out behavior while preserving the existing “observe all” default.

Changes:

  • Extends ObserverMapConfig with a properties path tree (ObserverMapPathEntry / ObserverMapPathNode) and threads config into ObserverMap.
  • Stamps $observe flags onto schema nodes and updates proxy/observation logic to skip excluded paths.
  • Adds unit + fixture coverage and updates public docs/API report to describe the new configuration.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/fast-html/src/components/template.ts Defines new observer-map config/types and passes config into ObserverMap.
packages/fast-html/src/components/observer-map.ts Implements config filtering at root and schema $observe stamping.
packages/fast-html/src/components/utilities.ts Updates proxy assignment and traps to respect schema $observe.
packages/fast-html/src/components/schema.ts Adds $observe?: boolean to schema nodes (used by observer-map stamping).
packages/fast-html/src/components/observer-map.spec.ts Adds unit tests for properties config behavior (observe all/none, skip roots).
packages/fast-html/test/fixtures/observer-map-properties/entry.html New fixture entry page for selective observer-map behavior.
packages/fast-html/test/fixtures/observer-map-properties/templates.html New fixture templates exercising included/excluded subpaths.
packages/fast-html/test/fixtures/observer-map-properties/state.json Fixture state for selective observation scenarios.
packages/fast-html/test/fixtures/observer-map-properties/main.ts Fixture element implementations + TemplateElement.options() config examples.
packages/fast-html/test/fixtures/observer-map-properties/index.html Generated fixture output used for hydration/fixture validation.
packages/fast-html/test/fixtures/observer-map-properties/fast-build.config.json Fixture build configuration for fast-build.
packages/fast-html/test/fixtures/observer-map-properties/observer-map-properties.spec.ts Playwright fixture tests validating selective observation end-to-end.
packages/fast-html/src/index.ts Re-exports new observer-map config types from the package entrypoint.
packages/fast-html/src/components/index.ts Re-exports new observer-map config types from components barrel.
packages/fast-html/docs/api-report.api.md Updates API report for new public types and constructor signature.
packages/fast-html/README.md Documents observerMap.properties path tree semantics and examples.
packages/fast-html/DESIGN.md Documents config resolution algorithm and $observe stamping behavior.
change/@microsoft-fast-html-2751da26-46f3-4c7d-ae10-4437c26b800b.json Adds a change file for the update (currently marked type: none).
Comments suppressed due to low confidence (1)

packages/fast-html/src/components/utilities.ts:1664

  • In the Proxy set trap, the $observe: false check short-circuits all assignments for excluded properties. This breaks the intended $observe:false + re-include-children scenario when the excluded property is replaced with a new object/array: the new value won’t be proxied and no notification will fire, so observed descendants (e.g. charts.activeChart) won’t update. Consider only short-circuiting when the property schema is excluded and has no observed descendants, and otherwise proxy/notify using the child property’s schema.
                const propName = typeof prop === "string" ? prop : String(prop);

                // If the schema marks this property as not observed, assign without proxying or notifying
                if (schemaProperties?.[propName]?.$observe === false) {
                    obj[prop] = value;
                    return true;
                }

                obj[prop] = assignObservables(
                    schema,
                    rootSchema,
                    value,
                    target,
                    rootProperty,
                );

                notifyObservables(proxy);

Comment thread packages/fast-html/src/components/utilities.ts
Comment thread change/@microsoft-fast-html-2751da26-46f3-4c7d-ae10-4437c26b800b.json Outdated
janechu and others added 7 commits April 16, 2026 16:44
Add a `properties` key to the `ObserverMapConfig` interface so that
developers can opt specific root properties and nested sub-paths in or
out of automatic observer-map observation, rather than the current
all-or-nothing approach.

Each path entry can be:
- `true` — observe this path and all descendants
- `false` — skip this path and all descendants
- An object with optional `$observe` boolean and child overrides

When `properties` is omitted, current behavior is preserved (all root
properties observed). When `properties` is present but empty, no root
properties are observed.

Resolves #7445

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the configEntry parameter that was threaded through 6+ proxy
functions with a one-time schema pre-processing pass. applyConfigToSchema
stamps $observe: false directly onto schema nodes, so the proxy system
can check schema.$observe instead of needing a separate config tree.

This eliminates:
- configEntry param from assignObservables, assignProxyToItemsInObject,
  assignProxy, assignObservablesToArray, assignProxyToItemsInArray
- 3 helper functions (getChildConfigEntry, shouldObserveAtPath,
  hasObservedDescendant) from utilities.ts
- All child-config resolution at every proxy set trap invocation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Update Data Flow diagram to show applyConfigToSchema step
- Update Schema and Observer Map section with  stamping details
- Add JSDoc to JSONSchemaCommon.$observe field

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix deleteProperty and set traps to check hasObservedSchemaDescendant
  before suppressing notifications. Properties with $observe: false that
  have re-included descendants now correctly notify on delete/replace.
- Update change file type from 'none' to 'prerelease' since this adds
  new public API surface (ObserverMapConfig.properties, exported types).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
pattern into a single `isSchemaExcluded()` function. This consolidates 5
call sites (property iteration in assignProxyToItemsInObject and
assignProxyToItemsInArray, set/deleteProperty traps in assignProxy,
and the proxy creation check) into one readable predicate.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@janechu janechu force-pushed the users/janechu/add-observer-map-opt-in-properties branch from ea817b1 to a442ae3 Compare April 16, 2026 23:45
@janechu janechu merged commit 0eb81e0 into main Apr 21, 2026
14 checks passed
@janechu janechu deleted the users/janechu/add-observer-map-opt-in-properties branch April 21, 2026 04:00
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.

feat: add properties path tree to ObserverMapConfig in fast-html

2 participants