@lynx-js/react 0.114.0 → 0.114.1

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,39 @@
1
1
  # @lynx-js/react
2
2
 
3
+ ## 0.114.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Add `event.stopPropagation` and `event.stopImmediatePropagation` in MTS, to help with event propagation control ([#1835](https://github.com/lynx-family/lynx-stack/pull/1835))
8
+
9
+ ```tsx
10
+ function App() {
11
+ function handleInnerTap(event: MainThread.TouchEvent) {
12
+ 'main thread';
13
+ event.stopPropagation();
14
+ // Or stop immediate propagation with
15
+ // event.stopImmediatePropagation();
16
+ }
17
+
18
+ // OuterTap will not be triggered
19
+ return (
20
+ <view main-thread:bindtap={handleOuterTap}>
21
+ <view main-thread:bindtap={handleInnerTap}>
22
+ <text>Hello, world</text>
23
+ </view>
24
+ </view>
25
+ );
26
+ }
27
+ ```
28
+
29
+ Note, if this feature is used in [Lazy Loading Standalone Project](https://lynxjs.org/react/code-splitting.html#lazy-loading-standalone-project), both the Producer and the Consumer should update to latest version of `@lynx-js/react` to make sure the feature is available.
30
+
31
+ - Fix the "ReferenceError: Node is not defined" error. ([#1850](https://github.com/lynx-family/lynx-stack/pull/1850))
32
+
33
+ This error would happen when upgrading to `@testing-library/jest-dom` [v6.9.0](https://github.com/testing-library/jest-dom/releases/tag/v6.9.0).
34
+
35
+ - fix: optimize main thread event error message ([#1838](https://github.com/lynx-family/lynx-stack/pull/1838))
36
+
3
37
  ## 0.114.0
4
38
 
5
39
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynx-js/react",
3
- "version": "0.114.0",
3
+ "version": "0.114.1",
4
4
  "description": "ReactLynx is a framework for developing Lynx applications with familiar React.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -175,7 +175,7 @@
175
175
  },
176
176
  "devDependencies": {
177
177
  "@lynx-js/types": "3.4.11",
178
- "@microsoft/api-extractor": "7.52.13",
178
+ "@microsoft/api-extractor": "7.52.15",
179
179
  "@types/react": "^18.3.24"
180
180
  },
181
181
  "peerDependencies": {
@@ -2,10 +2,10 @@
2
2
  > @lynx-js/react-refresh@0.1.0 build /home/runner/work/lynx-stack/lynx-stack/packages/react/refresh
3
3
  > rslib build
4
4
 
5
- Rslib v0.13.3
5
+ Rslib v0.15.0
6
6
 
7
7
  info build started...
8
- ready built in 0.20 s
8
+ ready built in 0.14 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"}
@@ -606,10 +606,12 @@ const env = {
606
606
  await builtinEnvironments.jsdom.setup(fakeGlobal, {});
607
607
  const lynxTestingEnv1 = new LynxTestingEnv(fakeGlobal.jsdom);
608
608
  global1.lynxTestingEnv = lynxTestingEnv1;
609
+ global1.Node = lynxTestingEnv1.jsdom.window.Node;
609
610
  return {
610
611
  teardown (global1) {
611
612
  delete global1.lynxTestingEnv;
612
613
  delete global1.jsdom;
614
+ delete global1.Node;
613
615
  }
614
616
  };
615
617
  }
@@ -21,7 +21,8 @@ const createVitestConfig = async (options)=>{
21
21
  const runtimeDir = path.dirname(vitest_config_require.resolve(`${runtimePkgName}/package.json`));
22
22
  const runtimeOSSDir = path.dirname(vitest_config_require.resolve(`${runtimeOSSPkgName}/package.json`, {
23
23
  paths: [
24
- runtimeDir
24
+ runtimeDir,
25
+ vitest_config_dirname
25
26
  ]
26
27
  }));
27
28
  const preactDir = path.dirname(vitest_config_require.resolve('preact/package.json', {
@@ -38,7 +39,8 @@ const createVitestConfig = async (options)=>{
38
39
  find: new RegExp('^' + name + '$'),
39
40
  replacement: vitest_config_require.resolve(name, {
40
41
  paths: [
41
- resolveDir
42
+ resolveDir,
43
+ vitest_config_dirname
42
44
  ]
43
45
  })
44
46
  });