@lynx-js/react

0.111.2

Patch Changes

  • Optimize componentAtIndex by a few hundreds microseconds: avoiding manipulate __pendingListUpdates unless SnapshotInstance tree is changed (#1201)

  • Support alog of component rendering on production for better error reporting. Enable it by using REACT_ALOG=true rspeedy dev/build or defining __ALOG__ to true in lynx.config.js: (#1164)

    export default defineConfig({
      // ...
      source: {
        define: {
          __ALOG__: true,
        },
      },
    });
  • Make preact/debug work with @lynx-js/react. (#1222)

  • Introduce @lynx-js/react/debug which would include debugging warnings and error messages for common mistakes found. (#1250)

    Add the import to @lynx-js/react/debug at the first line of the entry:

    import '@lynx-js/react/debug';
    import { root } from '@lynx-js/react';
    
    import { App } from './App.jsx';
    
    root.render(<App />);
  • <list-item/> deferred now accepts an object with unmountRecycled property to control unmounting behavior when the item is recycled. (#1302)

    For example, you can use it like this:

    <list-item defer={{ unmountRecycled: true }} item-key='1'>
      <WillBeUnmountIfRecycled />
    </list-item>;

    Now the component will be unmounted when it is recycled, which can help with performance in certain scenarios.

  • Avoid some unexpected __SetAttribute in hydrate when undefined is passed as an attribute value to intrinsic elements, for example: (#1318)

    <image async-mode={undefined} />;

0.111.1

Patch Changes

  • Wrap the main thread renderPage in preact act to ensure that the effects are flushed. (#1170)

0.111.0

Minor Changes

  • Allow some <list-item/>s to be deferred and rendered in the background thread. (#204)

    Use the following syntax:

    <list>
    -  <list-item item-key="...">
    +  <list-item item-key="..." defer>
          <SomeHeavyComponent />
      </list-item>
    </list>

    You should render your heavyweight components with the defer attribute to avoid blocking the main thread.

Patch Changes

  • Add missing alias of @lynx-js/react and preact in testing library, it will fix the Failed to resolve import "@lynx-js/react/internal" error in node_modules. (#1182)

  • Allow any types of dataProcessors in lynx.registerDataProcessors. (#1200)

  • Make loadLazyBundle being able to render the content on the first screen of the background thread. (#1212)

  • Fixed: An issue where the lynxViewDidUpdate callback did not trigger when data was updated from native. (#1171)

    Notice:

    • Even if no data changes are actually processed after calling updateData(), the lynxViewDidUpdate callback will still be triggered.
    • Only one lynxViewDidUpdate callback will be triggered per render cycle. Consequently, if multiple updateData() calls are made within a single cycle but the data updates are batched, the number of lynxViewDidUpdate callbacks triggered may be less than the number of updateData() calls.
  • Supports act in testing library. (#1182)

    import { act } from '@lynx-js/react/testing-library';
    
    act(() => {
      // ...
    });

0.110.1

Patch Changes

  • Fix a memory leak when using <list/>. (#1144)

0.110.0

Minor Changes

  • Fixed closure variable capture issue in effect hooks to prevent stale values and ensured proper execution order between refs, effects, and event handlers. (#770)

    Breaking Changes:

    • The execution timing of ref, useEffect() callback, componentDidMount, componentDidUpdate, componentWillUnmount and the callback of setState have been moved forward. These effects will now execute before hydration is complete, rather than waiting for the main thread update to complete.
    • For components inside <list />, ref callbacks will now be triggered during background thread rendering, regardless of component visibility. If your code depends on component visibility timing, use main-thread:ref instead of regular ref.

Patch Changes

  • Fixed two memory leaks: (#1071)

    1. When JSX is rendered on the main thread and removed, FiberElement can still be referenced by __root.__jsx through props.children;

    2. When the SnapshotInstance tree is removed from the root node, its child nodes form a cycle reference because the __previousSibling and __nextSibling properties point to each other, thus causing a FiberElement leak.

  • Optimize the error message when snapshots cannot be found in the main thread. (#1083)

  • Fix a problem causing MainThreadRefs to not be updated correctly during hydration when they are set to main-thread:refs. (#1001)

  • Add snapshot id report when throwing snapshotPatchApply failed: ctx not found error. (#1107)

  • Fix a bug in ReactLynx Testing Library that rendered snapshot of inline style was normalized incorrectly (eg. flex:1 was normalized to flex: 1 1 0%; incorrectly). (#1040)

0.109.2

Patch Changes

  • Support for locating errors in the source code directly on the device when exceptions occur when using MTS. (#1019)

    This requires Lynx engine v3.4 or later.

  • Fix the "main-thread.js exception: ReferenceError: __webpack_require__ is not defined" error in HMR. (#985)

    This error occurred when setting output.iife: true, which is the default value in @lynx-js/rspeedy v0.9.8.

0.109.1

Patch Changes

  • Support the 'main-thread' directive as an alias for 'main thread'. (#970)

  • Reduce calls to __AddInlineStyle by pass non-literal object directly to __SetInlineStyles. (#941)

0.109.0

Minor Changes

  • Support MTS functions running on the first screen. (#840)

Patch Changes

  • Fix type error when using Suspense with "jsx": "react-jsx". (#854)

  • Support lazy bundle in ReactLynx testing library. (#869)

  • Fix a bug in HMR that snapshots are always updated because the same unique ID check is not performed correctly. (#869)

  • Fix missing types of key on components when using "jsx": "react-jsx". (#872)

0.108.1

Patch Changes

  • Bump swc_core v23.2.0. (#827)

0.108.0

Minor Changes

  • Reverts #239: "batch multiple patches for main thread communication" (#649)

    This reverts the change that batched updates sent to the main thread in a single render pass.

Patch Changes

  • Add support for batch rendering in <list> with async resolution of sub-tree properties and element trees. (#624)

    Use the experimental-batch-render-strategy attribute of <list>:

    <list
      /**
       * Batch render strategy:
       * 0: (Default) Disabled - No batch rendering
       * 1: Basic - Only batch rendering enabled
       * 2: Property Resolution - Batch render with async property resolution for list item subtree
       * 3: Full Resolution - Batch render with async property and element tree resolution for list item subtree
       */
      experimental-batch-render-strategy={3}
    >
    </list>;
  • rename @lynx-js/test-environment to @lynx-js/testing-environment (#704)

  • Auto import @lynx-js/react/experimental/lazy/import when using import(url) (#667)

  • Auto import @lynx-js/react/experimental/lazy/import when using <component is={url} /> (#666)

  • Fixed a race condition when updating states and GlobalProps simultaneously. (#707)

    This fix prevents the "Attempt to render more than one <page />" error from occurring during normal application usage.

  • Fix error like Unterminated string constant when using multi-line JSX StringLiteral. (#654)

0.107.1

Patch Changes

  • Fix error OnPipelineStart arg count must == 1 on app load. (#669)

0.107.0

Minor Changes

  • Some of the timing keys are renamed to match the naming convention of the Lynx Engine. (#438)

    • update_set_state_trigger -> updateSetStateTrigger
    • update_diff_vdom_start -> updateDiffVdomStart
    • update_diff_vdom_end -> updateDiffVdomEnd
    • diff_vdom_start -> diffVdomStart
    • diff_vdom_end -> diffVdomEnd
    • pack_changes_start -> packChangesStart
    • pack_changes_end -> packChangesEnd
    • parse_changes_start -> parseChangesStart
    • parse_changes_end -> parseChangesEnd
    • patch_changes_start -> patchChangesStart
    • patch_changes_end -> patchChangesEnd
    • hydrate_parse_snapshot_start -> hydrateParseSnapshotStart
    • hydrate_parse_snapshot_end -> hydrateParseSnapshotEnd
    • mts_render_start -> mtsRenderStart
    • mts_render_end -> mtsRenderEnd

Patch Changes

  • Add testing library for ReactLynx (#74)

  • Refactor: Improved naming for list operation related types. Renamed UpdateAction interface to ListOperations. (#592)

  • Support using "jsx": "react-jsx" along with "jsxImportSource": "@lynx-js/react" in tsconfig.json. (#545)

    {
      "compilerOptions": {
        "jsx": "react-jsx",
        "jsxImportSource": "@lynx-js/react"
      }
    }

    This configuration enhances TypeScript definitions for standard JSX elements, providing type errors for unsupported elements like <div> or <button>.

  • fix: JSX elements with dynamic key={expr} now wrapped in wrapper element to prevent merging. (#547)

0.106.5

Patch Changes

  • Fix lynx.loadLazyBundle is not a function (#568)

  • fix: flushDelayedLifecycleEvents stack overflow error (#540)

0.106.4

Patch Changes

  • Disable MTS HMR functionality temporarily to address stability issues. This is a temporary fix while we work on a more robust solution. (#512)

0.106.3

Patch Changes

  • Do some global var initialize in hydrate, which fixes error like cannot read property '-21' of undefined and some style issue. (#461)

  • fix: ensure ref lifecycle events run after firstScreen in the background thread (#434)

    This patch fixes an issue where ref lifecycle events were running before firstScreen events in the background thread async render mode, which could cause refs to be undefined when components try to access them.

0.106.2

Patch Changes

  • fix: prevent multiple firstScreen events when reloading before jsReady (#377)

  • Optimize the bundle size by eliminating unnecessary code when the lazy bundle is not utilized. (#284)

0.106.1

Patch Changes

  • Fix a stack underflow issue when running on PrimJS. (#326)

0.106.0

Minor Changes

  • Improved rendering performance by batching updates sent to the main thread in a single render pass. This optimization reduces redundant layout operations on the main thread, accelerates rendering, and prevents screen flickering. (#239)

    BREAKING CHANGE: This commit changes the behavior of Timing API. Previously, timing events were fired for each update individually. With the new batching mechanism, timing events related to the rendering pipeline will now be triggered once per render cycle rather than for each individual update, affecting applications that rely on the previous timing behavior.

Patch Changes

  • Add missing typing for useErrorBoundary. (#263)

    You can now use useErrorBoundary it in TypeScript like this:

    import { useErrorBoundary } from '@lynx-js/react';
  • Modified the format of data sent from background threads to the main thread. (#207)

  • Support Lynx SSR. (#60)

0.105.2

Patch Changes

  • Support new css properties: offset-path and offset-distance (#152)

  • Fix 'SystemInfo is not defined' error when using MTS and not importing anything manually from the react package. (#172)

  • Fix not a function error when using lazy bundle without MTS. (#170)

  • fix: gesture config not processed correctly (#175)

    const pan = Gesture.Pan().minDistance(100);

    After this commit, gesture config like minDistance should work as expected.

0.105.1

Patch Changes

  • Support NPM provenance. (#30)

  • feat: add compiler only version of addComponentElement, it does not support spread props but have no runtime overhead, use it by: (#15)

    pluginReactLynx({
      compat: {
        addComponentElement: {
          compilerOnly: true,
        },
      },
    });
  • Fix error createRef is not a function (#16)

  • Support MIXED target for worklet, it will be used by unit testing frameworks, etc. (#27)

  • Support return value for runOnBackground() and runOnMainThread(). (#119)

    Now you can get the return value from runOnBackground() and runOnMainThread(), which enables more flexible data flow between the main thread and the background thread.

    import { runOnBackground } from '@lynx-js/react';
    
    const onTap = async () => {
      'main thread';
      const text = await runOnBackground(() => {
        'background only';
        return 'Hello, world!';
      })();
      console.log(text);
    };

0.105.0

Minor Changes

  • 1abf8f0: Support estimated-main-axis-size-px

    NOTE: This changes behavior of transformReactLynx so certain features (like lazy bundle) will be BROKEN if version mismatch.

  • 1abf8f0: Support JSXSpread on <list-item/> component.

    NOTE: This changes behavior of transformReactLynx so certain features (like lazy bundle) will be BROKEN if version mismatch.

Patch Changes

  • 1abf8f0: Update readme.
  • 1abf8f0: Save some bytes if <page/> is not used.
  • 1abf8f0: Should escape newline character in jsx

0.104.1

Patch Changes

  • 9ce9ec0: Fix argument cannot be accessed correctly in default exported MTS functions.

  • 99a4de6: Change TypeScript configuration to improve tree-shaking by setting verbatimModuleSyntax: false.

    This change allows the bundler to properly remove unused imports and type-only imports, resulting in smaller bundle sizes. For example:

    // These imports will be removed from the final bundle
    import type { Foo } from 'xyz';
    import { type Bar } from 'xyz';
    import { xyz } from 'xyz'; // When xyz is not used

    See TypeScript - verbatimModuleSyntax for details.

0.104.0

Minor Changes

  • 575e804: Remove misleading API createRoot

Patch Changes

  • 797ff68: Workaround the cannot find module './snapshot/event.js' error avoid tree-shaking event.js in development.
  • 1bf9271: fix(react): default compat in transform to false

0.103.5

Patch Changes

  • 74e0ea3: Supports new __MAIN_THREAD__ and __BACKGROUND__ macro as an alternative to __LEPUS__ and __JS__.

0.103.4

Patch Changes

  • 89a9f7a: Improve the speed of MTS.

0.103.3

Patch Changes

  • 4e94846: Fix variables being renamed in MTS.

  • 297c6ea: Fix the issue that when runOnBackground()'s parameter is not legal, it will still report an error in the rendering process of the background thread even though it won't actually be called.

    function App() {
      const f = undefined;
    
      function mts() {
        'main thread';
        // throws in background rendering
        f && runOnBackground(f)();
      }
    }
  • 763ad4e: Stop reporting ctx id in the ctx not found error.

  • 480611d: Avoid error from changing theme.

  • 3bf5830: Avoid overriding processEvalResult.

0.103.2

Patch Changes

  • 580ce54: Fix snapshot not found in HMR updates.

0.103.1

Patch Changes

  • 80a4e38: Use hooks useLynxGlobalEventListener to make useInitData addListener as early as possible. This will fix the issue that onDataChanged has been called before the event listener is added.
  • 8aa3979: Fix generating wrong JavaScript when using a variable multiple times in the main thread script.
  • 318245e: Avoid snapshot ID conflict between different templates and bundles.
  • b520862: Remove unnecessary sideEffects to reduce bundle size.
  • 7cd840c: Integrate with @lynx-js/types.

0.103.0

Minor Changes

  • a30c83d: Add compat.removeComponentAttrRegex.

    import { pluginReactLynx } from '@lynx-js/react-rsbuild-plugin';
    import { defineConfig } from '@lynx-js/rspeedy';
    
    export default defineConfig({
      plugins: [
        pluginReactLynx({
          compat: {
            removeComponentAttrRegex: 'YOUR REGEX',
          },
        }),
      ],
    });

    NOTE: This feature is deprecated and will be removed in the future. Use codemod instead.

  • 5f8d492: Deprecate compat.simplifyCtorLikeReactLynx2

Patch Changes

  • ca3a639: Fix cssId collision issue when hash generated @jsxCSSId for jsx snapshot hit the range of auto increased cssId of @file.

  • 8fbea78: Fix 'main thread' and 'background only' directives not working in export default declarations.

  • ff18049: Bump swc_core v0.109.2.

    This would add /*#__PURE__*/ to the output of TypeScript enum. See swc-project/swc#9558 for details.

0.102.0

Minor Changes

  • e3be842: Fix some attribute updating of nodes in list does not take effect
  • 2e6b549: Add ability to be compat with pre-0.99 version of ReactLynx

Patch Changes

  • 75725cb: Fix a memory leak in MTS.
  • 09e0ec0: Reduce the size of background.js.
  • 9e40f33: Slightly improve MTS execution speed.
  • f24599e: Fix the infinite mount and unmount loops of lazy bundle when its JS file fails to execute.

0.101.0

Minor Changes

  • 6730c58: Change the snapshot transform result by adding cssId and entryName.

    Remove Scoped CSS(Default) Scoped CSS
    
    createSnapshot(
      $uid,
      $create,
      $update,
      $slot,
      /** cssId */ undefined,
      /** entryName */ globDynamicComponentEntry
    );
            
    
    createSnapshot(
      $uid,
      $create,
      $update,
      $slot,
      /** cssId */ 0x3da39a,
      /** entryName */ globDynamicComponentEntry
    );
            

    This requires @lynx-js/react-rsbuild-plugin v0.5.1 to work.

    • Inject globDynamicComponentEntry for background script. (#311)
    • Inject globDynamicComponentEntry for main thread script. (#312)
  • efbb7d4: Support Gesture.

    Gesture Handler is a set of gesture handling capabilities built on top of the Main Thread Script. It currently supports drag, inertial scrolling, long press, and tap gestures for <view>, <scroll-view>, <list>, and <text>. In the future, it will also support multi-finger zoom, multi-finger rotation, and other gesture capabilities.

    import { useGesture, PanGesture } from '@lynx-js/gesture-runtime';
    
    function App() {
      const pan = useGesture(PanGesture);
    
      pan
        .onBegin((event, stateManager) => {
          'main thread';
          // some logic
        })
        .onUpdate((event, stateManager) => {
          'main thread';
          // some logic
        })
        .onEnd((event, stateManager) => {
          'main thread';
          // some logic
        });
    
      return <view main-thread:gesture={pan}></view>;
    }

Patch Changes

  • b2032eb: Better DCE.

    Now DCE can remove dead branch:

    function f() {
      if (__LEPUS__) {
        return;
      }
    
      console.log('not __LEPUS__'); // This can be removed now
    }
  • 45edafa: Support using import() with variables.

0.100.0

Minor Changes

  • 587a782: Release @lynx-js/react v0.100.0

Patch Changes

  • a335490: Fix an issue where events might not fire after calling ReloadTemplate.