Conversation
The `saveContainerState` method was removed from the `CanvasRenderer`, `TerminalRenderer`, and `VDOMRenderer` classes. This method was not being used in any of these renderers.
Replaces `linkNodes` with `createGroupFromNodes` for creating a group from rendered output within the `createUnique` function. This change improves encapsulation and clarifies the internal rendering process. Adds several new tests for the `unique` component, covering scenarios such as: - Components moving repeatedly without re-running `onSetup`. - Components returning multiple elements, strings, or nothing. - Components correctly updating plain props after moving.
This commit introduces a new experiment named `unique-test` to explore unique component behavior with transitions. The experiment includes: - An `index.html` file for the basic page structure. - A `package.json` file with dependencies for Retend and Vite. - `App.tsx` which demonstrates `createUnique` with `UniqueTransition` for animating elements. - `WithParentTransitions.tsx` showcases nested `UniqueTransition` components and dialog animations. - `main.ts` and `router.ts` for application entry point and routing setup. - `tsconfig.json` and `vite.config.ts` for project configuration. Additionally, this commit refactors `retend-utils` to rename `createUniqueTransition` to `UniqueTransition` for better clarity and consistency. The internal implementation has also been updated to align with the new component structure.
Introduce helper functions for save, restore, and dispose logic. Update the component to utilize these functions, enhancing code organization and readability. Add `activeHandle` and `isStable` properties to the `UniqueCtx` for better state management.
The `#handleData` WeakMap was used to store data associated with handles, but this data was never actually used and could be removed.
The `Unique` component's state management has been refactored to utilize the renderer's `save` and `restore` methods. This allows for more efficient and robust handling of component state when moving between different render targets or during re-renders. Key changes: - Introduced `idOfLastSavedHandle` to `UniqueCtx` to track the identifier of the last saved handle. - Modified `save` function to call `renderer.save` and store the returned ID. - Modified `restore` function to call `renderer.restore` with the stored ID. - Updated `onSetup` and the cleanup function within `createUnique` to correctly use the new save/restore mechanism. - Removed obsolete `transfer` methods from `VDOMRenderer` and `DOMRenderer` as they are no longer needed. - Removed `restoreContainerState` from `CanvasRenderer`, `TerminalRenderer`, and `dom-ops.js`. - Added a new `MissingScopeError` to provide better context for scope-related issues.
Changed the internal representation of element rects from an array to a Map, associating each element with its boundingClientRect. This simplifies state management and ensures correct mapping between elements and their dimensions during transitions. Also removed unnecessary Symbol and related property accessors.
Reset `idOfLastSavedHandle` to null after restoring a saved handle. This ensures that subsequent calls to `save()` correctly trigger the `moveFns` after pending setup effects have been run.
Introduce `pendingNodes` to the unique instance to correctly defer DOM writes when transitions are occurring. This ensures that DOM operations are batched and applied in the correct order, preventing potential rendering glitches during updates.
Store whether an animation was playing before being paused, so that it can be resumed correctly after the transition.
Adds a spinning animation to the Box component when it's connected to the DOM. This uses the `onConnected` lifecycle hook and CSS animations.
The `createUniqueTransition` factory function has been renamed to `UniqueTransition` and is now a component. This change aligns with the naming convention of other utility components and provides a more intuitive API. The `UniqueTransition` component should be used within a `createUnique` component to animate its children when the unique instance moves within the DOM tree. The component supports FLIP animations and various transition properties.
Introduces a new OXLint rule to disallow `Cell.derived()` calls directly within JSX expressions. This promotes cleaner code by encouraging the hoisting of derived cells to the component scope. The rule has been added to the OXLint configurations for `docs`, `retend-start`, and `retend-web-devtools`. The `Panel.tsx` component has been refactored to use this new pattern.
The `props` cell was being created outside of the `withState` function. This caused it to be destroyed when the parent context was destroyed, leading to unexpected behavior. By moving the creation of `props` inside `withState`, it now persists within the unique state's context, ensuring it remains available as long as the unique state is active.
The `journey` array now stores tuples of `[handle, UniqueProps<any>]` instead of just `handle`. This allows for the restoration of previous props when a unique instance is removed, ensuring the correct state is maintained.
The plugin incorrectly flagged the usage of `Cell` within `Cell.derived` and `Cell.derivedAsync` as an error. This commit adds checks to prevent such false positives by examining the parent AST nodes.
This commit modifies the UniqueTransition component to correctly capture and restore CSSTransition animations in addition to CSSAnimation. The `saveState` function now collects CSSTransitions alongside CSSAnimations. The `restoreTransition` function iterates through these saved CSSTransitions and applies them to their respective targets, ensuring animations that are not CSSAnimations are preserved.
This change refactors how child nodes are processed in `Block` components. Previously, `createGroupFromNodes` was used, which could lead to issues with unique component re-rendering across different routing layers. The new implementation directly creates a group and links nodes, ensuring proper handling of unique components when navigating between routes and outlets. This is demonstrated in new tests added to `matching.spec.tsx` and `unique.spec.tsx`.
Verify that unique components maintain synchronization when navigating back and forth through nested route outlets.
Introduced a new `flattenNodes` utility function to handle the flattening of arrays and groups of nodes returned from component renders. This simplifies the logic within the `For` component and ensures consistent handling of various node structures.
The whitespace in the router outlet rendering has been adjusted for better readability.
Applies a priority of -1 to listeners in `For`, `If`, and `Switch` components. This ensures that these components' listeners are processed after other, potentially higher-priority, listeners, preventing unexpected re-renders or race conditions.
This commit introduces a new experiment focused on testing the 'retend-utils' package. It sets up a new Vite project within the 'experiments' directory, including necessary configuration files, HTML, CSS, and TypeScript entry points. The experiment leverages various hooks and components from 'retend-utils' and 'retend-server' to demonstrate their functionality in a real-world application context. This includes examples for: - Element bounding and window size tracking. - Media query matching. - Live date display. - Network status monitoring. - Local and session storage integration. - Router locking and navigation. - Input component usage. - Fluid list rendering. - Cursor position tracking. - Scope management. - `onSetup`, `onConnected`, and `onMounted
Adds handling for `nodeType === 11` (DocumentFragment) within `flattenJSXChildren`, allowing hydration of components that return document fragments. Includes a new test case to verify this functionality.
This commit refactors the `getTopLevelJsxComponents` function to properly handle exported functions and variables. It now correctly identifies top-level components declared within `export default` and `export named` statements, ensuring that components defined in these common patterns are recognized. The logic for identifying component candidates has been improved to iterate through declarations within export statements and then check if these declarations are indeed functions or variable declarations that could represent components. Additionally, a check for `BlockStatement` type has been added to ensure that only functions with a body block are processed, preventing errors with arrow functions not immediately returning JSX. This also implicitly handles cases where a component might not have a function body.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
retend | e4b19e2 | Commit Preview URL Branch Preview URL |
Mar 21 2026, 04:44 PM |
Review Summary by QodoRefactor createUnique to hook-based pattern with UniqueTransition component
WalkthroughsDescription• **Refactored createUnique to use hook-based onMove() pattern** instead of onSave/onRestore options, enabling more flexible state preservation during component transitions • **Replaced createUniqueTransition factory with composable UniqueTransition component** that wraps children and integrates with createUnique via the onMove() hook • **Removed <retend-unique-instance> wrapper element** and replaced container state management with handle-based snapshot system using renderer.save() and renderer.restore() • **Updated renderer interfaces** across DOM, VDOM, and CLI renderers to use numeric IDs for snapshot management instead of custom data objects • **Fixed async component setup lifecycle** by moving unsuspend() and enable() calls inside onSetup() callback in Await component • **Enhanced linting rules** with new noDerivedInJsx rule to prevent inline Cell.derived() in JSX, and improved component detection for exported declarations • **Added comprehensive test coverage** for onMove() hook functionality, router-specific unique components, and hydration scenarios • **Added utility testing experiments** with new utils-testing and unique-test workspaces demonstrating lifecycle hooks, scope context, storage hooks, and unique component animations • **Optimized devtools performance** by hoisting derived cell creation outside of loops in PositionDropdown and Panel components • **Added DocumentFragment support** to JSX flattening and improved serialized comment pair detection for ranges • **Updated documentation** to reflect new onMove() hook pattern and UniqueTransition component-based approach Diagramflowchart LR
A["createUnique<br/>with onMove hook"] -- "replaces" --> B["Old createUnique<br/>with onSave/onRestore"]
C["UniqueTransition<br/>component"] -- "replaces" --> D["createUniqueTransition<br/>factory"]
A -- "uses" --> E["renderer.save()<br/>renderer.restore()"]
C -- "integrates via" --> A
F["Enhanced Linting<br/>no-derived-in-jsx"] -- "prevents" --> G["Inline Cell.derived<br/>in JSX"]
H["New Test Experiments<br/>utils-testing<br/>unique-test"] -- "demonstrates" --> A
File Changes1. packages/retend/source/library/unique.js
|
Code Review by Qodo
1.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 47a2606b1e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 47a2606b1e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Adds a cleanup function to the `onMove` hook to remove the callback from the set when the component unmounts. This prevents memory leaks and ensures correct behavior when components are conditionally rendered.
Wrap route updates in a `Cell.batch` call to ensure they are processed atomically. This prevents potential race conditions and ensures UI consistency.
retend
retend-oxlint-plugin
retend-server
retend-start
retend-utils
retend-web
retend-web-devtools
commit: |
The `idOfLastSavedHandle` variable was not being reset to `null` after being used to restore a renderer state. This could lead to incorrect state restoration in subsequent operations. This commit ensures that the variable is reset after each usage to prevent potential bugs.
Adds a check to ensure `onMove` callback in `UniqueTransition` only runs when the renderer is a `DOMRenderer`. This prevents unnecessary operations when working with non-DOM renderers. Additionally, this commit refactors the `createUnique` function to ensure `instance.state.node.disable()` and `instance.idOfLastSavedHandle` are only set when the current handle is the last one in the journey. This prevents premature state disabling when an older handle is being removed.
Implements placeholder methods for saving and restoring terminal states. These methods currently return default values and do nothing, as their full implementation is not yet required.
Refactors
createUniqueto use a hook-based pattern and replacescreateUniqueTransitionwith a composableUniqueTransitioncomponent.Breaking Changes
createUniqueoptionsparameter (onSave,onRestore,container)onMove()hook for state preservation<retend-unique-instance>wrappercreateUniqueTransition→UniqueTransitionMigration
onSave/onRestorewithonMove()hookcreateUniqueTransition(fn, opts)withcreateUnique(fn)+<UniqueTransition>retend-unique-instanceimport { onMove } from 'retend',import { UniqueTransition } from 'retend-utils/components'