refactor(thermidor): interface-owned caches with cascade dispose#7914
refactor(thermidor): interface-owned caches with cascade dispose#7914jfcere-coveo wants to merge 10 commits into
Conversation
|
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
There was a problem hiding this comment.
Pull request overview
This PR refactors Thermidor’s interface lifecycle and caching model by moving feature-module caches (slices/actions/selectors) from module-level Maps into per-interface InterfaceCacheRegistry instances, and by having the Engine track interfaces so Engine.dispose() can cascade disposal.
Changes:
- Introduces
InterfaceCacheRegistryand updates internalgetOrCreate*factories to cache per interface handle (rather than globally bystateId). - Updates
BaseInterface,ComposedInterface, andEngineto support interface registration/deregistration and disposal semantics. - Updates public controllers/actions/mutators/selectors and tests to pass interface handles instead of
stateIdstrings; removes legacy loader utilities.
Reviewed changes
Copilot reviewed 112 out of 112 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/thermidor/src/public/interfaces/search.ts | Build path updated to adopt slices using the constructed interface handle. |
| packages/thermidor/src/public/interfaces/generative.ts | Builds generative interface then adopts slice via interface-scoped cache factory. |
| packages/thermidor/src/public/interfaces/compose.ts | Adds composed-owned cache registry, disposal guard, and engine registration. |
| packages/thermidor/src/public/interfaces/compose.test.ts | Updates composed interface facade scoping expectations and naming. |
| packages/thermidor/src/public/controllers/search-box/search-box-controller.ts | Controllers now adopt slices/selectors/actions via interface handle instead of stateId. |
| packages/thermidor/src/public/controllers/search-box/search-box-controller.test.ts | Adjusts selector usage to getQuery(searchInterface) signature. |
| packages/thermidor/src/public/controllers/result-list/result-list-controller.ts | Uses interface handle for slice + selectors. |
| packages/thermidor/src/public/controllers/result-list/result-list-controller.test.ts | Updates action factory calls to accept the interface handle. |
| packages/thermidor/src/public/controllers/product-list/product-list-controller.ts | Uses interface handle for slice + selectors. |
| packages/thermidor/src/public/controllers/pagination/pagination-controller.ts | Uses interface handle for slice/actions/selectors; removes Dispatchable casting. |
| packages/thermidor/src/public/controllers/converse/converse-controller.ts | Adopts generative slice via interface handle; runtime config now uses handles. |
| packages/thermidor/src/public/controllers/converse/converse-controller.test.ts | Updates generative action factory calls to accept interface handle. |
| packages/thermidor/src/public/controllers/controllers-integration.test.ts | Updates pagination actions to accept search/composed interface handles. |
| packages/thermidor/src/public/controllers/cart/cart-controller.ts | Adopts cart slice and uses selectors/actions via interface handle. |
| packages/thermidor/src/public/controllers/cart/cart-controller.test.ts | Updates cart/search-box factories to accept interface handle. |
| packages/thermidor/src/public/actions/search-parameters/search-parameters-actions.ts | Uses interface handle for slice adoption and actions factory. |
| packages/thermidor/src/public/actions/search-box/search-box-state-getter.ts | Uses interface handle for slice adoption and selectors factory. |
| packages/thermidor/src/public/actions/search-box/search-box-actions.ts | Uses interface handle for slice adoption and actions factory. |
| packages/thermidor/src/public/actions/search-box/search-box-actions.test.ts | Updates selectors factory calls to accept interface handle. |
| packages/thermidor/src/public/actions/cart/cart-actions.ts | Uses interface handle for slice adoption and actions factory. |
| packages/thermidor/src/public/actions/cart/cart-actions.test.ts | Updates selectors factory calls to accept interface handle. |
| packages/thermidor/src/index.ts | Exports new InterfaceHandle type. |
| packages/thermidor/src/core/internal/triggers/triggers-slice.ts | Migrates slice cache into interface-owned registry. |
| packages/thermidor/src/core/internal/triggers/triggers-actions.ts | Migrates actions cache into interface-owned registry. |
| packages/thermidor/src/core/internal/sort/sort-slice.ts | Migrates slice cache into interface-owned registry; injects actions dependency. |
| packages/thermidor/src/core/internal/sort/sort-selectors.ts | Migrates selectors cache into interface-owned registry. |
| packages/thermidor/src/core/internal/sort/sort-actions.ts | Migrates actions cache into interface-owned registry. |
| packages/thermidor/src/core/internal/search-parameters/search-parameters-slice.ts | Migrates slice cache into interface-owned registry; injects actions dependency. |
| packages/thermidor/src/core/internal/search-parameters/search-parameters-selectors.ts | Migrates selectors cache into interface-owned registry. |
| packages/thermidor/src/core/internal/search-parameters/search-parameters-actions.ts | Migrates actions cache into interface-owned registry. |
| packages/thermidor/src/core/internal/search-box/search-box-slice.ts | Migrates slice cache into interface-owned registry; injects actions dependency. |
| packages/thermidor/src/core/internal/search-box/search-box-slice.test.ts | Updates tests to build minimal interfaces and call new factory signatures. |
| packages/thermidor/src/core/internal/search-box/search-box-selectors.ts | Migrates selectors cache into interface-owned registry. |
| packages/thermidor/src/core/internal/search-box/search-box-actions.ts | Migrates actions cache into interface-owned registry. |
| packages/thermidor/src/core/internal/result-list/result-list-slice.ts | Migrates slice cache into interface-owned registry; injects actions/hydrate dependencies. |
| packages/thermidor/src/core/internal/result-list/result-list-slice.test.ts | Updates tests to use interface handles and hydrate action factory. |
| packages/thermidor/src/core/internal/result-list/result-list-selectors.ts | Migrates selectors cache into interface-owned registry. |
| packages/thermidor/src/core/internal/result-list/result-list-actions.ts | Migrates actions cache into interface-owned registry. |
| packages/thermidor/src/core/internal/query-correction/query-correction-slice.ts | Migrates slice cache into interface-owned registry; injects actions dependency. |
| packages/thermidor/src/core/internal/query-correction/query-correction-actions.ts | Migrates actions cache into interface-owned registry. |
| packages/thermidor/src/core/internal/product-list/product-list-slice.ts | Migrates slice cache into interface-owned registry; injects actions/hydrate dependencies. |
| packages/thermidor/src/core/internal/product-list/product-list-selectors.ts | Migrates selectors cache into interface-owned registry. |
| packages/thermidor/src/core/internal/product-list/product-list-actions.ts | Migrates actions cache into interface-owned registry. |
| packages/thermidor/src/core/internal/pagination/pagination-slice.ts | Migrates slice cache into interface-owned registry; injects actions/hydrate dependencies. |
| packages/thermidor/src/core/internal/pagination/pagination-slice.test.ts | Updates tests for new handle-based factories and hydrate dependency. |
| packages/thermidor/src/core/internal/pagination/pagination-selectors.ts | Migrates selectors cache into interface-owned registry. |
| packages/thermidor/src/core/internal/pagination/pagination-actions.ts | Migrates actions cache into interface-owned registry. |
| packages/thermidor/src/core/internal/generative/generative-slice.ts | Migrates slice cache into interface-owned registry; injects actions dependency. |
| packages/thermidor/src/core/internal/generative/generative-selectors.ts | Migrates selectors cache into interface-owned registry. |
| packages/thermidor/src/core/internal/generative/generative-actions.ts | Migrates actions cache into interface-owned registry. |
| packages/thermidor/src/core/internal/facets/facets-slice.ts | Migrates slice cache into interface-owned registry; injects actions/hydrate dependencies. |
| packages/thermidor/src/core/internal/facets/facets-slice.test.ts | Updates tests for new handle-based factories and hydrate dependency. |
| packages/thermidor/src/core/internal/facets/facets-selectors.ts | Migrates selectors cache into interface-owned registry. |
| packages/thermidor/src/core/internal/facets/facets-actions.ts | Migrates actions cache into interface-owned registry. |
| packages/thermidor/src/core/internal/cart/cart-slice.ts | Migrates slice cache into interface-owned registry; injects actions dependency. |
| packages/thermidor/src/core/internal/cart/cart-slice.test.ts | Updates tests to create interface handle and inject actions into slice creation. |
| packages/thermidor/src/core/internal/cart/cart-selectors.ts | Migrates selectors cache into interface-owned registry. |
| packages/thermidor/src/core/internal/cart/cart-actions.ts | Migrates actions cache into interface-owned registry. |
| packages/thermidor/src/core/internal/api/search/search-thunk.ts | Uses scope interface handle for thunk naming and slice adoption; response handler now takes a handle. |
| packages/thermidor/src/core/internal/api/search/search-thunk-slice.ts | Migrates endpoint slice/selectors caches into interface-owned registry. |
| packages/thermidor/src/core/internal/api/search/search-response-handler.ts | Response handler now scopes action factories by interface handle. |
| packages/thermidor/src/core/internal/api/search/search-request-selector.ts | Uses scopeInterface for sharable selectors and baseInterface for base selectors. |
| packages/thermidor/src/core/internal/api/search/commerce-search-thunk.ts | Uses scope interface handle for thunk naming and slice adoption; response handler now takes a handle. |
| packages/thermidor/src/core/internal/api/search/commerce-search-thunk-slice.ts | Migrates commerce endpoint slice/selectors caches into interface-owned registry. |
| packages/thermidor/src/core/internal/api/search/commerce-search-response-handler.ts | Response handler now scopes action factories by interface handle. |
| packages/thermidor/src/core/internal/api/search/commerce-search-request-selector.ts | Uses scopeInterface for sharable selectors and baseInterface for base selectors. |
| packages/thermidor/src/core/internal/api/query-suggest/query-suggest-thunk.ts | Thunk type now uses scopeInterface stateId. |
| packages/thermidor/src/core/internal/api/conversation-endpoint/conversation-endpoint-request-selector.ts | Request selector now accepts interface handles for generative/cart selectors. |
| packages/thermidor/src/core/internal/api/commerce-query-suggest/commerce-query-suggest-thunk.ts | Thunk type now uses scopeInterface stateId. |
| packages/thermidor/src/core/interface/utils/interface-types.ts | Introduces InterfaceHandle; updates facade scoping contract to pass handles. |
| packages/thermidor/src/core/interface/utils/get-handle-internals.ts | Returns {engine,stateId,cacheRegistry} for both base and composed handles. |
| packages/thermidor/src/core/interface/search-box/search-box-selectors.ts | Public selector now requires an interface handle to resolve the cached selector. |
| packages/thermidor/src/core/interface/search-box/search-box-selectors.test.ts | Updates tests to use a created interface handle for selector and slice adoption. |
| packages/thermidor/src/core/interface/search-box/search-box-mutators.ts | Mutator now requires an interface handle (no default id). |
| packages/thermidor/src/core/interface/search-box/search-box-mutators.test.ts | Updates tests to pass interface handle to mutator + selector. |
| packages/thermidor/src/core/interface/search-box/search-box-loader.ts | Removes loader utility (no longer needed with interface-owned caches). |
| packages/thermidor/src/core/interface/search-box/search-box-loader.test.ts | Removes loader tests. |
| packages/thermidor/src/core/interface/result-list/result-list-selectors.ts | Public selector now requires an interface handle. |
| packages/thermidor/src/core/interface/result-list/result-list-selectors.test.ts | Updates tests to use interface handle and new mutator signature. |
| packages/thermidor/src/core/interface/result-list/result-list-mutators.ts | Mutator now requires an interface handle (no default id). |
| packages/thermidor/src/core/interface/result-list/result-list-mutators.test.ts | Updates tests to pass interface handle to mutator + selector. |
| packages/thermidor/src/core/interface/result-list/result-list-loader.ts | Removes loader utility (no longer needed with interface-owned caches). |
| packages/thermidor/src/core/interface/result-list/result-list-loader.test.ts | Removes loader tests. |
| packages/thermidor/src/core/interface/pagination/pagination-selectors.ts | Public selectors now require an interface handle. |
| packages/thermidor/src/core/interface/pagination/pagination-selectors.test.ts | Updates tests to use interface handle and new mutator signature. |
| packages/thermidor/src/core/interface/pagination/pagination-mutators.ts | Mutators now require an interface handle (no shared default actions). |
| packages/thermidor/src/core/interface/pagination/pagination-mutators.test.ts | Updates tests to pass interface handle to mutators + selectors. |
| packages/thermidor/src/core/interface/generative/generative-loader.ts | Removes loader utility (slice adoption done via interface factories). |
| packages/thermidor/src/core/interface/generative/generative-hydration.ts | Hydration snapshot + hydrate action caching now keyed by interface handle; updates snapshot storage API. |
| packages/thermidor/src/core/interface/generative/generative-hydration.test.ts | Updates tests to create real interfaces and use handle-based hydrate action caching. |
| packages/thermidor/src/core/interface/facets/facets-selectors.test.ts | Updates tests to adopt slice using interface handle while exercising selectors. |
| packages/thermidor/src/core/interface/facets/facets-mutators.ts | Mutator now requires an interface handle (no default actions). |
| packages/thermidor/src/core/interface/facets/facets-mutators.test.ts | Updates tests for new mutator signature; currently very permissive assertions. |
| packages/thermidor/src/core/interface/engine/engine.ts | Adds interface tracking + cascade dispose; updates hydration snapshot storage to track interface handle. |
| packages/thermidor/src/core/interface/engine/engine.test.ts | Updates tests for new selector/mutator signatures and interface handle creation. |
| packages/thermidor/src/core/interface/engine/engine-dispose.test.ts | Updates dispose tests for new selector/mutator signatures and handle creation. |
| packages/thermidor/src/core/interface/cart/cart-selectors.ts | Removes re-exports and keeps handle-based internal selector access. |
| packages/thermidor/src/core/interface/cart/cart-mutators.ts | Mutators now require an interface handle (no default id). |
| packages/thermidor/src/core/interface/cart/cart-mutators.test.ts | Updates tests for new mutator signature; currently very permissive assertions. |
| packages/thermidor/src/core/interface/cart/cart-loader.ts | Removes loader utility (slice adoption done via interface factories). |
| packages/thermidor/src/core/interface/cart/cart-loader.test.ts | Removes loader tests. |
| packages/thermidor/src/core/interface/cache/interface-cache-registry.ts | New per-interface cache registry with typed keys and disposal guards. |
| packages/thermidor/src/core/interface/base-interface.ts | Adds cache registry ownership and engine registration; changes facade scoping to use handles. |
| packages/thermidor/src/core/interface/base-interface.test.ts | Updates base interface tests for composed scoping and updated error messages. |
| packages/thermidor/src/core/interface/api/generative-endpoint/generative-runtime.ts | Runtime config now accepts interface handles for request scoping. |
| packages/thermidor/src/core/index.ts | Removes exports of deprecated loader utilities. |
| packages/thermidor/.kiro/steering/class-member-ordering.md | Adds thermidor-specific class member ordering convention. |
| .kiro/specs/interface-owned-caches-and-cascade-dispose/tasks.md | Adds implementation plan/spec documentation for the feature. |
| .kiro/specs/interface-owned-caches-and-cascade-dispose/requirements.md | Adds requirements for interface-owned caches and cascade disposal. |
| .kiro/specs/interface-owned-caches-and-cascade-dispose/design.md | Adds detailed design doc for the new caching/disposal architecture. |
| .kiro/specs/interface-owned-caches-and-cascade-dispose/.config.kiro | Adds spec configuration metadata. |
Comments suppressed due to low confidence (1)
packages/thermidor/src/core/interface/engine/engine.ts:122
- After
Engine.dispose(), the Engine instance still retains references to the Redux store, root reducer, and adopted slices, which can keep a large object graph alive if the Engine object itself remains referenced. Nulling these fields (as previously done) helps release memory earlier and better matches the PR’s memory-management goals.
this.#interfaces.clear();
this.#hydrationSnapshots.clear();
this.#navigatorContextProvider = undefined;
fullEngineWrappers.delete(this);
}
@coveo/atomic
@coveo/atomic-hosted-page
@coveo/atomic-legacy
@coveo/atomic-react
@coveo/auth
@coveo/bueno
@coveo/create-atomic
@coveo/create-atomic-component
@coveo/create-atomic-component-project
@coveo/create-atomic-result-component
@coveo/create-atomic-rollup-plugin
@coveo/headless
@coveo/headless-react
@coveo/shopify
commit: |
Summary
Module-level
Mapcaches (slices, actions, selectors) are moved to per-interface ownership via a newInterfaceCacheRegistry. Each interface disposes its own caches ondispose(), andEngine.dispose()cascades to all registered interfaces — ensuring no orphaned state after teardown.What changed
InterfaceCacheRegistryclass with typedCacheKey<T>branded symbols and agetOrCreate<T>(key, factory)methodInterfaceHandlestructural type replacing unsafeas unknown ascastsaddInterface/removeInterfaceSet, cascadedispose()to all(interfaceId: string)to(iface: InterfaceHandle), extract internals viagetHandleInternalsWhere to focus the review
src/core/interface/cache/interface-cache-registry.tssrc/core/interface/base-interface.tssrc/public/interfaces/compose.tssrc/core/interface/engine/engine.tsaddInterface/removeInterface, cascade disposesrc/core/interface/utils/interface-types.tsInterfaceHandle, updatedEndpointStateScopesrc/core/interface/utils/get-handle-internals.tscacheRegistryThe remaining ~60 files are mechanical: same migration pattern applied per feature module (remove Map, add CacheKey, use
getHandleInternals) + call-site updates passingifaceinstead ofstateId.