@lynx-js/react-canary 0.114.0 → 0.114.1-canary-20250928-a35a2452

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @lynx-js/react
2
2
 
3
+ ## 0.114.1-canary-20250928082931-a35a2452e5355bda3c475f9a750a86085e0cf56a
4
+
5
+ ### Patch Changes
6
+
7
+ - fix: optimize main thread event error message ([#1838](https://github.com/lynx-family/lynx-stack/pull/1838))
8
+
3
9
  ## 0.114.0
4
10
 
5
11
  ### Minor Changes
@@ -73,10 +79,10 @@
73
79
  - Add `animate` API in Main Thread Script(MTS), so you can now control a CSS animation imperatively ([#1534](https://github.com/lynx-family/lynx-stack/pull/1534))
74
80
 
75
81
  ```ts
76
- import type { MainThread } from '@lynx-js/types';
82
+ import type { MainThread } from "@lynx-js/types";
77
83
 
78
84
  function startAnimation(ele: MainThread.Element) {
79
- 'main thread';
85
+ "main thread";
80
86
  const animation = ele.animate([{ opacity: 0 }, { opacity: 1 }], {
81
87
  duration: 3000,
82
88
  });
@@ -105,7 +111,7 @@
105
111
  - Supports `recyclable` attribute in `<list-item>` to control whether the list item is recyclable. The `recyclable` attribute depends on Lynx Engine 3.4 or later. ([#1388](https://github.com/lynx-family/lynx-stack/pull/1388))
106
112
 
107
113
  ```jsx
108
- <list-item recyclable={false} />;
114
+ <list-item recyclable={false} />
109
115
  ```
110
116
 
111
117
  - feat: Support using a host element as direct child of Suspense ([#1455](https://github.com/lynx-family/lynx-stack/pull/1455))
@@ -126,7 +132,7 @@
126
132
 
127
133
  ```ts
128
134
  function handleTap() {
129
- 'main thread';
135
+ "main thread";
130
136
  // The following check always returned false before this fix
131
137
  if (myHandleTap) {
132
138
  runOnBackground(myHandleTap)();
@@ -187,10 +193,10 @@
187
193
  Add the import to `@lynx-js/react/debug` at the first line of the entry:
188
194
 
189
195
  ```js
190
- import '@lynx-js/react/debug';
191
- import { root } from '@lynx-js/react';
196
+ import "@lynx-js/react/debug";
197
+ import { root } from "@lynx-js/react";
192
198
 
193
- import { App } from './App.jsx';
199
+ import { App } from "./App.jsx";
194
200
 
195
201
  root.render(<App />);
196
202
  ```
@@ -200,9 +206,9 @@
200
206
  For example, you can use it like this:
201
207
 
202
208
  ```jsx
203
- <list-item defer={{ unmountRecycled: true }} item-key='1'>
209
+ <list-item defer={{ unmountRecycled: true }} item-key="1">
204
210
  <WillBeUnmountIfRecycled />
205
- </list-item>;
211
+ </list-item>
206
212
  ```
207
213
 
208
214
  Now the component will be unmounted when it is recycled, which can help with performance in certain scenarios.
@@ -210,7 +216,7 @@
210
216
  - Avoid some unexpected `__SetAttribute` in hydrate when `undefined` is passed as an attribute value to intrinsic elements, for example: ([#1318](https://github.com/lynx-family/lynx-stack/pull/1318))
211
217
 
212
218
  ```jsx
213
- <image async-mode={undefined} />;
219
+ <image async-mode={undefined} />
214
220
  ```
215
221
 
216
222
  ## 0.111.1
@@ -256,7 +262,7 @@
256
262
  - Supports `act` in testing library. ([#1182](https://github.com/lynx-family/lynx-stack/pull/1182))
257
263
 
258
264
  ```js
259
- import { act } from '@lynx-js/react/testing-library';
265
+ import { act } from "@lynx-js/react/testing-library";
260
266
 
261
267
  act(() => {
262
268
  // ...
@@ -362,8 +368,7 @@
362
368
  * 3: Full Resolution - Batch render with async property and element tree resolution for list item subtree
363
369
  */
364
370
  experimental-batch-render-strategy={3}
365
- >
366
- </list>;
371
+ ></list>
367
372
  ```
368
373
 
369
374
  - rename @lynx-js/test-environment to @lynx-js/testing-environment ([#704](https://github.com/lynx-family/lynx-stack/pull/704))
@@ -481,7 +486,7 @@
481
486
  You can now use `useErrorBoundary` it in TypeScript like this:
482
487
 
483
488
  ```tsx
484
- import { useErrorBoundary } from '@lynx-js/react';
489
+ import { useErrorBoundary } from "@lynx-js/react";
485
490
  ```
486
491
 
487
492
  - Modified the format of data sent from background threads to the main thread. ([#207](https://github.com/lynx-family/lynx-stack/pull/207))
@@ -533,13 +538,13 @@
533
538
  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.
534
539
 
535
540
  ```js
536
- import { runOnBackground } from '@lynx-js/react';
541
+ import { runOnBackground } from "@lynx-js/react";
537
542
 
538
543
  const onTap = async () => {
539
- 'main thread';
544
+ "main thread";
540
545
  const text = await runOnBackground(() => {
541
- 'background only';
542
- return 'Hello, world!';
546
+ "background only";
547
+ return "Hello, world!";
543
548
  })();
544
549
  console.log(text);
545
550
  };
@@ -574,9 +579,9 @@
574
579
 
575
580
  ```ts
576
581
  // These imports will be removed from the final bundle
577
- import type { Foo } from 'xyz';
578
- import { type Bar } from 'xyz';
579
- import { xyz } from 'xyz'; // When xyz is not used
582
+ import type { Foo } from "xyz";
583
+ import { type Bar } from "xyz";
584
+ import { xyz } from "xyz"; // When xyz is not used
580
585
  ```
581
586
 
582
587
  See [TypeScript - verbatimModuleSyntax](https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax) for details.
@@ -616,7 +621,7 @@
616
621
  const f = undefined;
617
622
 
618
623
  function mts() {
619
- 'main thread';
624
+ "main thread";
620
625
  // throws in background rendering
621
626
  f && runOnBackground(f)();
622
627
  }
@@ -650,14 +655,14 @@
650
655
  - a30c83d: Add `compat.removeComponentAttrRegex`.
651
656
 
652
657
  ```js
653
- import { pluginReactLynx } from '@lynx-js/react-rsbuild-plugin';
654
- import { defineConfig } from '@lynx-js/rspeedy';
658
+ import { pluginReactLynx } from "@lynx-js/react-rsbuild-plugin";
659
+ import { defineConfig } from "@lynx-js/rspeedy";
655
660
 
656
661
  export default defineConfig({
657
662
  plugins: [
658
663
  pluginReactLynx({
659
664
  compat: {
660
- removeComponentAttrRegex: 'YOUR REGEX',
665
+ removeComponentAttrRegex: "YOUR REGEX",
661
666
  },
662
667
  }),
663
668
  ],
@@ -743,22 +748,22 @@
743
748
  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.
744
749
 
745
750
  ```tsx
746
- import { useGesture, PanGesture } from '@lynx-js/gesture-runtime';
751
+ import { useGesture, PanGesture } from "@lynx-js/gesture-runtime";
747
752
 
748
753
  function App() {
749
754
  const pan = useGesture(PanGesture);
750
755
 
751
756
  pan
752
757
  .onBegin((event, stateManager) => {
753
- 'main thread';
758
+ "main thread";
754
759
  // some logic
755
760
  })
756
761
  .onUpdate((event, stateManager) => {
757
- 'main thread';
762
+ "main thread";
758
763
  // some logic
759
764
  })
760
765
  .onEnd((event, stateManager) => {
761
- 'main thread';
766
+ "main thread";
762
767
  // some logic
763
768
  });
764
769
 
@@ -778,7 +783,7 @@
778
783
  return;
779
784
  }
780
785
 
781
- console.log('not __LEPUS__'); // This can be removed now
786
+ console.log("not __LEPUS__"); // This can be removed now
782
787
  }
783
788
  ```
784
789
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynx-js/react-canary",
3
- "version": "0.114.0",
3
+ "version": "0.114.1-canary-20250928-a35a2452",
4
4
  "description": "ReactLynx is a framework for developing Lynx applications with familiar React.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -5,7 +5,7 @@
5
5
  Rslib v0.13.3
6
6
 
7
7
  info build started...
8
- ready built in 0.20 s
8
+ ready built in 0.12 s
9
9
 
10
10
  File (esm) Size 
11
11
  dist/index.js 11.1 kB
@@ -0,0 +1 @@
1
+ export declare function describeInvalidValue(value: unknown): string;
@@ -0,0 +1,25 @@
1
+ // Copyright 2025 The Lynx Authors. All rights reserved.
2
+ // Licensed under the Apache License Version 2.0 that can be found in the
3
+ // LICENSE file in the root directory of this source tree.
4
+ export function describeInvalidValue(value) {
5
+ if (value === null) {
6
+ return 'null';
7
+ }
8
+ if (value === undefined) {
9
+ return 'undefined';
10
+ }
11
+ if (typeof value === 'function') {
12
+ return `function ${value.name || '(anonymous)'}`;
13
+ }
14
+ if (typeof value === 'string') {
15
+ return `string "${value}"`;
16
+ }
17
+ if (typeof value === 'number' || typeof value === 'bigint' || typeof value === 'boolean') {
18
+ return `${typeof value} ${String(value)}`;
19
+ }
20
+ if (typeof value === 'symbol') {
21
+ return `symbol ${String(value)}`;
22
+ }
23
+ return `unexpected ${typeof value}`;
24
+ }
25
+ //# sourceMappingURL=describeInvalidValue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describeInvalidValue.js","sourceRoot":"","sources":["../../src/debug/describeInvalidValue.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,yEAAyE;AACzE,0DAA0D;AAE1D,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;QAChC,OAAO,YAAY,KAAK,CAAC,IAAI,IAAI,aAAa,EAAE,CAAC;IACnD,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,WAAW,KAAK,GAAG,CAAC;IAC7B,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QACzF,OAAO,GAAG,OAAO,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;IAC5C,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,UAAU,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;IACnC,CAAC;IACD,OAAO,cAAc,OAAO,KAAK,EAAE,CAAC;AACtC,CAAC"}
@@ -2,13 +2,34 @@
2
2
  // Licensed under the Apache License Version 2.0 that can be found in the
3
3
  // LICENSE file in the root directory of this source tree.
4
4
  import { onWorkletCtxUpdate } from '@lynx-js/react/worklet-runtime/bindings';
5
+ import { describeInvalidValue } from '../debug/describeInvalidValue.js';
5
6
  import { isMainThreadHydrating } from '../lifecycle/patch/isMainThreadHydrating.js';
6
7
  import { SnapshotInstance } from '../snapshot.js';
8
+ function formatEventAttribute(workletType, eventType, eventName) {
9
+ const suffix = eventType.endsWith('Event') ? eventType.slice(0, -'Event'.length) : eventType;
10
+ return `${workletType}:${suffix}${eventName}`;
11
+ }
12
+ function reportInvalidWorkletValue(snapshot, elementIndex, workletType, eventType, eventName, value) {
13
+ const eventAttr = formatEventAttribute(workletType, eventType, eventName);
14
+ const element = snapshot.__elements?.[elementIndex];
15
+ const elementTag = element ? __GetTag(element) : 'unknown';
16
+ const elementId = snapshot.__id;
17
+ const snapshotName = snapshot.type;
18
+ const message = `"${eventAttr}" on <${elementTag}> (snapshot ${elementId} "${snapshotName}") expected `
19
+ + 'a main-thread function but received '
20
+ + `${describeInvalidValue(value)}. Did you forget to add a "main thread" directive to the handler?`;
21
+ lynx.reportError(new Error(message));
22
+ }
7
23
  function updateWorkletEvent(snapshot, expIndex, oldValue, elementIndex, workletType, eventType, eventName) {
8
24
  if (!snapshot.__elements) {
9
25
  return;
10
26
  }
11
- const value = (snapshot.__values[expIndex] || undefined) ?? {};
27
+ const rawValue = snapshot.__values[expIndex];
28
+ if (__DEV__ && rawValue !== null && rawValue !== undefined && typeof rawValue !== 'object') {
29
+ reportInvalidWorkletValue(snapshot, elementIndex, workletType, eventType, eventName, rawValue);
30
+ return;
31
+ }
32
+ const value = (rawValue ?? {});
12
33
  value._workletType = workletType;
13
34
  if (workletType === 'main-thread') {
14
35
  onWorkletCtxUpdate(value, oldValue, isMainThreadHydrating, snapshot.__elements[elementIndex]);
@@ -1 +1 @@
1
- {"version":3,"file":"workletEvent.js","sourceRoot":"","sources":["../../src/snapshot/workletEvent.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,yEAAyE;AACzE,0DAA0D;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAG7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,SAAS,kBAAkB,CACzB,QAA0B,EAC1B,QAAgB,EAChB,QAAiB,EACjB,YAAoB,EACpB,WAAmB,EACnB,SAAiB,EACjB,SAAiB;IAEjB,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACzB,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,QAAQ,CAAC,QAAS,CAAC,QAAQ,CAAY,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;IAC3E,KAAK,CAAC,YAAY,GAAG,WAAW,CAAC;IAEjC,IAAI,WAAW,KAAK,aAAa,EAAE,CAAC;QAClC,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,qBAAqB,EAAE,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAE,CAAC,CAAC;QAC/F,MAAM,KAAK,GAAG;YACZ,IAAI,EAAE,SAAS;YACf,KAAK;SACN,CAAC;QACF,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAE,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"workletEvent.js","sourceRoot":"","sources":["../../src/snapshot/workletEvent.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,yEAAyE;AACzE,0DAA0D;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAG7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,SAAS,oBAAoB,CAAC,WAAmB,EAAE,SAAiB,EAAE,SAAiB;IACrF,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7F,OAAO,GAAG,WAAW,IAAI,MAAM,GAAG,SAAS,EAAE,CAAC;AAChD,CAAC;AAED,SAAS,yBAAyB,CAChC,QAA0B,EAC1B,YAAoB,EACpB,WAAmB,EACnB,SAAiB,EACjB,SAAiB,EACjB,KAAc;IAEd,MAAM,SAAS,GAAG,oBAAoB,CAAC,WAAW,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAC1E,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC;IAChC,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,SAAS,SAAS,UAAU,eAAe,SAAS,KAAK,YAAY,cAAc;UACnG,sCAAsC;UACtC,GAAG,oBAAoB,CAAC,KAAK,CAAC,mEAAmE,CAAC;IACtG,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,kBAAkB,CACzB,QAA0B,EAC1B,QAAgB,EAChB,QAAiB,EACjB,YAAoB,EACpB,WAAmB,EACnB,SAAiB,EACjB,SAAiB;IAEjB,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACzB,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAS,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,OAAO,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC3F,yBAAyB,CAAC,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC/F,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAY,CAAC;IAC1C,KAAK,CAAC,YAAY,GAAG,WAAW,CAAC;IAEjC,IAAI,WAAW,KAAK,aAAa,EAAE,CAAC;QAClC,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,qBAAqB,EAAE,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAE,CAAC,CAAC;QAC/F,MAAM,KAAK,GAAG;YACZ,IAAI,EAAE,SAAS;YACf,KAAK;SACN,CAAC;QACF,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAE,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC"}