react-konva
Advanced tools
+33
-2
@@ -103,3 +103,34 @@ /** | ||
| applyNodeProps(stage.current, props, oldProps); | ||
| KonvaRenderer.updateContainer(React.createElement(Bridge, {}, props.children), fiberRef.current, null); | ||
| // ============================================================================= | ||
| // CRITICAL FIX - DO NOT REMOVE | ||
| // ============================================================================= | ||
| // This flushSyncFromReconciler wrapper is CRITICAL for React 19 compatibility. | ||
| // | ||
| // THE BUG: | ||
| // When using useSyncExternalStore (MobX, Zustand, etc.) with react-konva, | ||
| // parent component's useLayoutEffect couldn't find newly added Konva nodes. | ||
| // The nodes were added to the store, but not yet rendered to the canvas. | ||
| // | ||
| // ROOT CAUSE: | ||
| // React 19's updateContainer can defer Konva reconciler work to a later | ||
| // microtask. Combined with Bridge component (from its-fine) and Html components | ||
| // that create secondary React roots, this caused child components to render | ||
| // AFTER parent's useLayoutEffect completed. | ||
| // | ||
| // THE FIX: | ||
| // flushSyncFromReconciler forces ALL scheduled Konva reconciler work to | ||
| // complete synchronously within this useLayoutEffect, ensuring child | ||
| // components render before any parent effects run. | ||
| // | ||
| // WARNING - NOT COVERED BY TESTS: | ||
| // This bug CANNOT be reproduced in local test environments (Vitest/Playwright). | ||
| // It only manifests in production builds with specific conditions: | ||
| // - MobX/useSyncExternalStore for state management | ||
| // - Html components with secondary React roots using Bridge | ||
| // - Complex component hierarchies (multiple pages/stages) | ||
| // The fix was verified in Polotno production app. | ||
| // ============================================================================= | ||
| KonvaRenderer.flushSyncFromReconciler(() => { | ||
| KonvaRenderer.updateContainer(React.createElement(Bridge, {}, props.children), fiberRef.current, null); | ||
| }); | ||
| }); | ||
@@ -139,3 +170,3 @@ return React.createElement('div', { | ||
| export const Transformer = 'Transformer'; | ||
| export const version = '19.2.1'; | ||
| export const version = '19.2.2'; | ||
| // @ts-ignore | ||
@@ -142,0 +173,0 @@ export const KonvaRenderer = ReactFiberReconciler(HostConfig); |
@@ -90,8 +90,3 @@ import React from 'react'; | ||
| export const supportsMicrotasks = true; | ||
| // use this to schedule microtasks | ||
| // I don't know if we should do this in react-konva | ||
| // better to run schedule in sync mode | ||
| // so setState will call render imidiatly | ||
| // it may be not optimal | ||
| // but working in sync mode is simpler. | ||
| // Run microtasks synchronously for immediate updates | ||
| export const scheduleMicrotask = (fn) => { | ||
@@ -98,0 +93,0 @@ fn(); |
@@ -142,3 +142,34 @@ /** | ||
| (0, makeUpdates_js_1.applyNodeProps)(stage.current, props, oldProps); | ||
| exports.KonvaRenderer.updateContainer(react_1.default.createElement(Bridge, {}, props.children), fiberRef.current, null); | ||
| // ============================================================================= | ||
| // CRITICAL FIX - DO NOT REMOVE | ||
| // ============================================================================= | ||
| // This flushSyncFromReconciler wrapper is CRITICAL for React 19 compatibility. | ||
| // | ||
| // THE BUG: | ||
| // When using useSyncExternalStore (MobX, Zustand, etc.) with react-konva, | ||
| // parent component's useLayoutEffect couldn't find newly added Konva nodes. | ||
| // The nodes were added to the store, but not yet rendered to the canvas. | ||
| // | ||
| // ROOT CAUSE: | ||
| // React 19's updateContainer can defer Konva reconciler work to a later | ||
| // microtask. Combined with Bridge component (from its-fine) and Html components | ||
| // that create secondary React roots, this caused child components to render | ||
| // AFTER parent's useLayoutEffect completed. | ||
| // | ||
| // THE FIX: | ||
| // flushSyncFromReconciler forces ALL scheduled Konva reconciler work to | ||
| // complete synchronously within this useLayoutEffect, ensuring child | ||
| // components render before any parent effects run. | ||
| // | ||
| // WARNING - NOT COVERED BY TESTS: | ||
| // This bug CANNOT be reproduced in local test environments (Vitest/Playwright). | ||
| // It only manifests in production builds with specific conditions: | ||
| // - MobX/useSyncExternalStore for state management | ||
| // - Html components with secondary React roots using Bridge | ||
| // - Complex component hierarchies (multiple pages/stages) | ||
| // The fix was verified in Polotno production app. | ||
| // ============================================================================= | ||
| exports.KonvaRenderer.flushSyncFromReconciler(() => { | ||
| exports.KonvaRenderer.updateContainer(react_1.default.createElement(Bridge, {}, props.children), fiberRef.current, null); | ||
| }); | ||
| }); | ||
@@ -178,3 +209,3 @@ return react_1.default.createElement('div', { | ||
| exports.Transformer = 'Transformer'; | ||
| exports.version = '19.2.1'; | ||
| exports.version = '19.2.2'; | ||
| // @ts-ignore | ||
@@ -181,0 +212,0 @@ exports.KonvaRenderer = (0, react_reconciler_1.default)(HostConfig); |
@@ -146,8 +146,3 @@ "use strict"; | ||
| exports.supportsMicrotasks = true; | ||
| // use this to schedule microtasks | ||
| // I don't know if we should do this in react-konva | ||
| // better to run schedule in sync mode | ||
| // so setState will call render imidiatly | ||
| // it may be not optimal | ||
| // but working in sync mode is simpler. | ||
| // Run microtasks synchronously for immediate updates | ||
| const scheduleMicrotask = (fn) => { | ||
@@ -154,0 +149,0 @@ fn(); |
+1
-1
@@ -5,3 +5,3 @@ { | ||
| "description": "React binding to canvas element via Konva framework", | ||
| "version": "19.2.1", | ||
| "version": "19.2.2", | ||
| "keywords": [ | ||
@@ -8,0 +8,0 @@ "react", |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
75584
4.53%1495
3.6%