@shopify/react-native-skia 2.2.15 → 2.2.16

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.
@@ -26,10 +26,20 @@ MetalWindowContext::MetalWindowContext(GrDirectContext *directContext,
26
26
  _layer.drawableSize = CGSizeMake(width, height);
27
27
  BOOL supportsWideColor = NO;
28
28
  if (useP3ColorSpace) {
29
+ #if !TARGET_OS_OSX
29
30
  if (@available(iOS 10.0, *)) {
30
31
  supportsWideColor = [UIScreen mainScreen].traitCollection.displayGamut ==
31
32
  UIDisplayGamutP3;
32
33
  }
34
+ #else
35
+ if (@available(macOS 10.12, *)) {
36
+ NSScreen *screen = [NSScreen mainScreen];
37
+ NSColorSpace *displayP3 = [NSColorSpace displayP3ColorSpace];
38
+ if (screen.colorSpace && displayP3) {
39
+ supportsWideColor = [screen.colorSpace isEqual:displayP3];
40
+ }
41
+ }
42
+ #endif // !TARGET_OS_OSX
33
43
  }
34
44
  if (supportsWideColor) {
35
45
  CGColorSpaceRef colorSpace =
@@ -275,21 +275,17 @@ public:
275
275
  JsiSkImage(std::shared_ptr<RNSkPlatformContext> context,
276
276
  const sk_sp<SkImage> image)
277
277
  : JsiSkWrappingSkPtrHostObject<SkImage>(std::move(context),
278
- std::move(image)),
279
- _deletionHandler() {
278
+ std::move(image)) {
280
279
  // Drain any pending deletions when creating new images
281
280
  ThreadSafeDeletion<SkImage>::drainDeletionQueue();
282
281
  }
283
282
 
284
283
  ~JsiSkImage() override {
285
284
  // Handle thread-safe deletion
286
- auto objectToDelete = _deletionHandler.handleDeletion(getObject());
287
- if (!objectToDelete) {
288
- // Object was queued for deletion on another thread
289
- // Clear it to prevent base class destructor from deleting it
290
- setObject(nullptr);
291
- }
292
- // If objectToDelete is not null, base destructor will handle cleanup
285
+ _deletionHandler.handleDeletion(getObject());
286
+ // Always clear the object to prevent base class destructor from deleting it
287
+ // handleDeletion takes full responsibility for the object's lifetime
288
+ setObject(nullptr);
293
289
  }
294
290
 
295
291
  size_t getMemoryPressure() const override {
@@ -44,13 +44,10 @@ public:
44
44
 
45
45
  ~JsiSkSurface() override {
46
46
  // Handle thread-safe deletion
47
- auto objectToDelete = _deletionHandler.handleDeletion(getObject());
48
- if (!objectToDelete) {
49
- // Object was queued for deletion on another thread
50
- // Clear it to prevent base class destructor from deleting it
51
- setObject(nullptr);
52
- }
53
- // If objectToDelete is not null, base destructor will handle cleanup
47
+ _deletionHandler.handleDeletion(getObject());
48
+ // Always clear the object to prevent base class destructor from deleting it
49
+ // handleDeletion takes full responsibility for the object's lifetime
50
+ setObject(nullptr);
54
51
  }
55
52
 
56
53
  EXPORT_JSI_API_TYPENAME(JsiSkSurface, Surface)
@@ -32,18 +32,18 @@ public:
32
32
 
33
33
  /**
34
34
  * Handles deletion of the object. If we're on the wrong thread,
35
- * queues it for later deletion. Returns nullptr if object was queued,
36
- * or the object itself if it should be deleted immediately.
35
+ * queues it for later deletion. Otherwise, allows immediate deletion.
36
+ * The object is always considered handled after this call.
37
37
  */
38
- sk_sp<T> handleDeletion(sk_sp<T> object) {
38
+ void handleDeletion(sk_sp<T> object) {
39
39
  if (!object) {
40
- return nullptr;
40
+ return;
41
41
  }
42
42
 
43
43
  #ifdef DISABLE_THREAD_SAFE_DELETION
44
- // When disabled, always return the object for immediate deletion
44
+ // When disabled, allow immediate deletion
45
45
  // This will likely cause crashes when objects are deleted on wrong thread
46
- return object;
46
+ return;
47
47
  #else
48
48
  // Always try to drain the queue when handling deletions
49
49
  drainDeletionQueue();
@@ -53,11 +53,11 @@ public:
53
53
  // Queue for deletion on the correct thread
54
54
  std::lock_guard<std::mutex> lock(_queueMutex);
55
55
  _deletionQueue.push({object, _creationThreadId});
56
- return nullptr; // Signal that object was queued
56
+ return;
57
57
  }
58
58
 
59
- // We're on the correct thread, return object for immediate deletion
60
- return object;
59
+ // We're on the correct thread, allow immediate deletion via destructor
60
+ return;
61
61
  #endif
62
62
  }
63
63
 
@@ -2,7 +2,7 @@ import type { Server, WebSocket } from "ws";
2
2
  declare global {
3
3
  var testServer: Server;
4
4
  var testClient: WebSocket;
5
- var testOS: "ios" | "android" | "web" | "node";
5
+ var testOS: "ios" | "android" | "web" | "node" | "macos";
6
6
  var testArch: "paper" | "fabric";
7
7
  }
8
8
  declare const globalSetup: () => Promise<void>;
@@ -1,7 +1,7 @@
1
1
  import type { FC, RefObject } from "react";
2
2
  import React from "react";
3
3
  import type { MeasureInWindowOnSuccessCallback, MeasureOnSuccessCallback, ViewProps } from "react-native";
4
- import { type SharedValue } from "react-native-reanimated";
4
+ import type { SharedValue } from "react-native-reanimated";
5
5
  import type { SkImage, SkRect, SkSize } from "../skia/types";
6
6
  export interface CanvasRef extends FC<CanvasProps> {
7
7
  makeImageSnapshot(rect?: SkRect): SkImage;
@@ -11,6 +11,7 @@ var _SkiaPictureViewNativeComponent = _interopRequireDefault(require("../specs/S
11
11
  var _Reconciler = require("../sksg/Reconciler");
12
12
  var _skia = require("../skia");
13
13
  var _Platform = require("../Platform");
14
+ var _external = require("../external");
14
15
  var _global;
15
16
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
17
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
@@ -18,6 +19,7 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
18
19
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
19
20
  const useCanvasRef = () => (0, _react.useRef)(null);
20
21
  exports.useCanvasRef = useCanvasRef;
22
+ const useReanimatedFrame = !_external.HAS_REANIMATED_3 ? () => {} : _ReanimatedProxy.default.useFrameCallback;
21
23
  const useCanvasSize = userRef => {
22
24
  const ourRef = useCanvasRef();
23
25
  const ref = userRef !== null && userRef !== void 0 ? userRef : ourRef;
@@ -71,39 +73,26 @@ const Canvas = ({
71
73
 
72
74
  // Root
73
75
  const root = (0, _react.useMemo)(() => new _Reconciler.SkiaSGRoot(_skia.Skia, nativeId), [nativeId]);
74
- const updateSize = (0, _react.useCallback)(value => {
75
- if (onSize) {
76
- onSize.value = value;
77
- }
78
- }, [onSize]);
76
+ useReanimatedFrame(() => {
77
+ "worklet";
78
+ }, !!onSize);
79
79
  (0, _react.useEffect)(() => {
80
80
  if (onSize) {
81
- const {
82
- runOnJS
83
- } = _ReanimatedProxy.default;
84
- const uiOnSize = _ReanimatedProxy.default.makeMutable({
85
- width: 0,
86
- height: 0
87
- });
88
81
  _ReanimatedProxy.default.runOnUI(() => {
89
82
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
90
83
  // @ts-expect-error
91
- global[`__onSize_${nativeId}`] = uiOnSize;
92
- uiOnSize.addListener(nativeId, value => {
93
- runOnJS(updateSize)(value);
94
- });
84
+ global[`__onSize_${nativeId}`] = onSize;
95
85
  })();
96
86
  return () => {
97
87
  _ReanimatedProxy.default.runOnUI(() => {
98
88
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
99
89
  // @ts-expect-error
100
90
  delete global[`__onSize_${nativeId}`];
101
- uiOnSize.removeListener(nativeId);
102
91
  })();
103
92
  };
104
93
  }
105
94
  return undefined;
106
- }, [onSize, nativeId, updateSize]);
95
+ }, [onSize, nativeId]);
107
96
 
108
97
  // Render effects
109
98
  (0, _react.useLayoutEffect)(() => {
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_ReanimatedProxy","_interopRequireDefault","_SkiaViewNativeId","_SkiaPictureViewNativeComponent","_Reconciler","_skia","_Platform","_global","e","__esModule","default","_getRequireWildcardCache","WeakMap","r","t","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","_extends","assign","bind","arguments","length","apply","useCanvasRef","useRef","exports","useCanvasSize","userRef","ourRef","ref","size","setSize","useState","width","height","useLayoutEffect","current","measure","_x","_y","isFabric","Boolean","global","nativeFabricUIManager","Canvas","debug","opaque","children","onSize","colorSpace","onLayout","viewProps","console","error","viewRef","nativeId","useMemo","SkiaViewNativeId","root","SkiaSGRoot","Skia","updateSize","useCallback","value","useEffect","runOnJS","Rea","uiOnSize","makeMutable","runOnUI","addListener","removeListener","undefined","render","unmount","useImperativeHandle","makeImageSnapshot","rect","SkiaViewApi","makeImageSnapshotAsync","redraw","requestRedraw","getNativeId","callback","_viewRef$current","measureInWindow","_viewRef$current2","onLayoutWeb","Platform","OS","nativeEvent","layout","createElement","collapsable","nativeID"],"sources":["Canvas.tsx"],"sourcesContent":["import type { FC, RefObject } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n LayoutChangeEvent,\n MeasureInWindowOnSuccessCallback,\n MeasureOnSuccessCallback,\n View,\n ViewProps,\n} from \"react-native\";\nimport { type SharedValue } from \"react-native-reanimated\";\n\nimport Rea from \"../external/reanimated/ReanimatedProxy\";\nimport { SkiaViewNativeId } from \"../views/SkiaViewNativeId\";\nimport SkiaPictureViewNativeComponent from \"../specs/SkiaPictureViewNativeComponent\";\nimport type { SkImage, SkRect, SkSize } from \"../skia/types\";\nimport { SkiaSGRoot } from \"../sksg/Reconciler\";\nimport { Skia } from \"../skia\";\nimport { Platform } from \"../Platform\";\n\nexport interface CanvasRef extends FC<CanvasProps> {\n makeImageSnapshot(rect?: SkRect): SkImage;\n makeImageSnapshotAsync(rect?: SkRect): Promise<SkImage>;\n redraw(): void;\n getNativeId(): number;\n measure(callback: MeasureOnSuccessCallback): void;\n measureInWindow(callback: MeasureInWindowOnSuccessCallback): void;\n}\n\nexport const useCanvasRef = () => useRef<CanvasRef>(null);\n\nexport const useCanvasSize = (userRef?: RefObject<CanvasRef | null>) => {\n const ourRef = useCanvasRef();\n const ref = userRef ?? ourRef;\n const [size, setSize] = useState<SkSize>({ width: 0, height: 0 });\n useLayoutEffect(() => {\n if (ref.current) {\n ref.current.measure((_x, _y, width, height) => {\n setSize({ width, height });\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return { ref, size };\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const isFabric = Boolean((global as any)?.nativeFabricUIManager);\n\nexport interface CanvasProps extends Omit<ViewProps, \"onLayout\"> {\n debug?: boolean;\n opaque?: boolean;\n onSize?: SharedValue<SkSize>;\n colorSpace?: \"p3\" | \"srgb\";\n ref?: React.Ref<CanvasRef>;\n __destroyWebGLContextAfterRender?: boolean;\n}\n\nexport const Canvas = ({\n debug,\n opaque,\n children,\n onSize,\n colorSpace = \"p3\",\n ref,\n // Here know this is a type error but this is done on purpose to check it at runtime\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n onLayout,\n ...viewProps\n}: CanvasProps) => {\n if (onLayout && isFabric) {\n console.error(\n // eslint-disable-next-line max-len\n \"<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://shopify.github.io/react-native-skia/docs/canvas/overview/#getting-the-canvas-size\"\n );\n }\n const viewRef = useRef<View>(null);\n // Native ID\n const nativeId = useMemo(() => {\n return SkiaViewNativeId.current++;\n }, []);\n\n // Root\n const root = useMemo(() => new SkiaSGRoot(Skia, nativeId), [nativeId]);\n\n const updateSize = useCallback(\n (value: SkSize) => {\n if (onSize) {\n onSize.value = value;\n }\n },\n [onSize]\n );\n useEffect(() => {\n if (onSize) {\n const { runOnJS } = Rea;\n const uiOnSize = Rea.makeMutable({ width: 0, height: 0 });\n Rea.runOnUI(() => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n global[`__onSize_${nativeId}`] = uiOnSize;\n uiOnSize.addListener(nativeId, (value) => {\n runOnJS(updateSize)(value);\n });\n })();\n return () => {\n Rea.runOnUI(() => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n delete global[`__onSize_${nativeId}`];\n uiOnSize.removeListener(nativeId);\n })();\n };\n }\n return undefined;\n }, [onSize, nativeId, updateSize]);\n\n // Render effects\n useLayoutEffect(() => {\n root.render(children);\n }, [children, root, nativeId]);\n\n useEffect(() => {\n return () => {\n root.unmount();\n };\n }, [root]);\n\n // Component methods\n useImperativeHandle(\n ref,\n () =>\n ({\n makeImageSnapshot: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshot(nativeId, rect);\n },\n makeImageSnapshotAsync: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshotAsync(nativeId, rect);\n },\n redraw: () => {\n SkiaViewApi.requestRedraw(nativeId);\n },\n getNativeId: () => {\n return nativeId;\n },\n measure: (callback) => {\n viewRef.current?.measure(callback);\n },\n measureInWindow: (callback) => {\n viewRef.current?.measureInWindow(callback);\n },\n } as CanvasRef)\n );\n\n const onLayoutWeb = useCallback(\n (e: LayoutChangeEvent) => {\n if (onLayout) {\n onLayout(e);\n }\n if (Platform.OS === \"web\" && onSize) {\n const { width, height } = e.nativeEvent.layout;\n onSize.value = { width, height };\n }\n },\n [onLayout, onSize]\n );\n\n return (\n <SkiaPictureViewNativeComponent\n ref={viewRef}\n collapsable={false}\n nativeID={`${nativeId}`}\n debug={debug}\n opaque={opaque}\n colorSpace={colorSpace}\n onLayout={onLayoutWeb}\n {...viewProps}\n />\n );\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_ReanimatedProxy","_interopRequireDefault","_SkiaViewNativeId","_SkiaPictureViewNativeComponent","_Reconciler","_skia","_Platform","_external","_global","e","__esModule","default","_getRequireWildcardCache","WeakMap","r","t","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","_extends","assign","bind","arguments","length","apply","useCanvasRef","useRef","exports","useReanimatedFrame","HAS_REANIMATED_3","Rea","useFrameCallback","useCanvasSize","userRef","ourRef","ref","size","setSize","useState","width","height","useLayoutEffect","current","measure","_x","_y","isFabric","Boolean","global","nativeFabricUIManager","Canvas","debug","opaque","children","onSize","colorSpace","onLayout","viewProps","console","error","viewRef","nativeId","useMemo","SkiaViewNativeId","root","SkiaSGRoot","Skia","useEffect","runOnUI","undefined","render","unmount","useImperativeHandle","makeImageSnapshot","rect","SkiaViewApi","makeImageSnapshotAsync","redraw","requestRedraw","getNativeId","callback","_viewRef$current","measureInWindow","_viewRef$current2","onLayoutWeb","useCallback","Platform","OS","nativeEvent","layout","value","createElement","collapsable","nativeID"],"sources":["Canvas.tsx"],"sourcesContent":["import type { FC, RefObject } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n LayoutChangeEvent,\n MeasureInWindowOnSuccessCallback,\n MeasureOnSuccessCallback,\n View,\n ViewProps,\n} from \"react-native\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\nimport Rea from \"../external/reanimated/ReanimatedProxy\";\nimport { SkiaViewNativeId } from \"../views/SkiaViewNativeId\";\nimport SkiaPictureViewNativeComponent from \"../specs/SkiaPictureViewNativeComponent\";\nimport type { SkImage, SkRect, SkSize } from \"../skia/types\";\nimport { SkiaSGRoot } from \"../sksg/Reconciler\";\nimport { Skia } from \"../skia\";\nimport { Platform } from \"../Platform\";\nimport { HAS_REANIMATED_3 } from \"../external\";\n\nexport interface CanvasRef extends FC<CanvasProps> {\n makeImageSnapshot(rect?: SkRect): SkImage;\n makeImageSnapshotAsync(rect?: SkRect): Promise<SkImage>;\n redraw(): void;\n getNativeId(): number;\n measure(callback: MeasureOnSuccessCallback): void;\n measureInWindow(callback: MeasureInWindowOnSuccessCallback): void;\n}\n\nexport const useCanvasRef = () => useRef<CanvasRef>(null);\n\nconst useReanimatedFrame = !HAS_REANIMATED_3 ? () => {} : Rea.useFrameCallback;\n\nexport const useCanvasSize = (userRef?: RefObject<CanvasRef | null>) => {\n const ourRef = useCanvasRef();\n const ref = userRef ?? ourRef;\n const [size, setSize] = useState<SkSize>({ width: 0, height: 0 });\n useLayoutEffect(() => {\n if (ref.current) {\n ref.current.measure((_x, _y, width, height) => {\n setSize({ width, height });\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return { ref, size };\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const isFabric = Boolean((global as any)?.nativeFabricUIManager);\n\nexport interface CanvasProps extends Omit<ViewProps, \"onLayout\"> {\n debug?: boolean;\n opaque?: boolean;\n onSize?: SharedValue<SkSize>;\n colorSpace?: \"p3\" | \"srgb\";\n ref?: React.Ref<CanvasRef>;\n __destroyWebGLContextAfterRender?: boolean;\n}\n\nexport const Canvas = ({\n debug,\n opaque,\n children,\n onSize,\n colorSpace = \"p3\",\n ref,\n // Here know this is a type error but this is done on purpose to check it at runtime\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n onLayout,\n ...viewProps\n}: CanvasProps) => {\n if (onLayout && isFabric) {\n console.error(\n // eslint-disable-next-line max-len\n \"<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://shopify.github.io/react-native-skia/docs/canvas/overview/#getting-the-canvas-size\"\n );\n }\n const viewRef = useRef<View>(null);\n // Native ID\n const nativeId = useMemo(() => {\n return SkiaViewNativeId.current++;\n }, []);\n\n // Root\n const root = useMemo(() => new SkiaSGRoot(Skia, nativeId), [nativeId]);\n\n useReanimatedFrame(() => {\n \"worklet\";\n }, !!onSize);\n useEffect(() => {\n if (onSize) {\n Rea.runOnUI(() => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n global[`__onSize_${nativeId}`] = onSize;\n })();\n return () => {\n Rea.runOnUI(() => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n delete global[`__onSize_${nativeId}`];\n })();\n };\n }\n return undefined;\n }, [onSize, nativeId]);\n\n // Render effects\n useLayoutEffect(() => {\n root.render(children);\n }, [children, root, nativeId]);\n\n useEffect(() => {\n return () => {\n root.unmount();\n };\n }, [root]);\n\n // Component methods\n useImperativeHandle(\n ref,\n () =>\n ({\n makeImageSnapshot: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshot(nativeId, rect);\n },\n makeImageSnapshotAsync: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshotAsync(nativeId, rect);\n },\n redraw: () => {\n SkiaViewApi.requestRedraw(nativeId);\n },\n getNativeId: () => {\n return nativeId;\n },\n measure: (callback) => {\n viewRef.current?.measure(callback);\n },\n measureInWindow: (callback) => {\n viewRef.current?.measureInWindow(callback);\n },\n } as CanvasRef)\n );\n\n const onLayoutWeb = useCallback(\n (e: LayoutChangeEvent) => {\n if (onLayout) {\n onLayout(e);\n }\n if (Platform.OS === \"web\" && onSize) {\n const { width, height } = e.nativeEvent.layout;\n onSize.value = { width, height };\n }\n },\n [onLayout, onSize]\n );\n\n return (\n <SkiaPictureViewNativeComponent\n ref={viewRef}\n collapsable={false}\n nativeID={`${nativeId}`}\n debug={debug}\n opaque={opaque}\n colorSpace={colorSpace}\n onLayout={onLayoutWeb}\n {...viewProps}\n />\n );\n};\n"],"mappings":"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","ignoreList":[]}
@@ -3,7 +3,7 @@ import type { Server, WebSocket } from "ws";
3
3
  import type * as SkiaExports from "../../index";
4
4
  import type { SkImage, SkFont, Skia, SkCanvas } from "../../skia/types";
5
5
  import { SkiaSGRoot } from "../../sksg/Reconciler";
6
- type TestOS = "ios" | "android" | "web" | "node";
6
+ type TestOS = "ios" | "android" | "web" | "node" | "macos";
7
7
  declare global {
8
8
  var testServer: Server;
9
9
  var testClient: WebSocket;
@@ -2,7 +2,7 @@ import type { Server, WebSocket } from "ws";
2
2
  declare global {
3
3
  var testServer: Server;
4
4
  var testClient: WebSocket;
5
- var testOS: "ios" | "android" | "web" | "node";
5
+ var testOS: "ios" | "android" | "web" | "node" | "macos";
6
6
  var testArch: "paper" | "fabric";
7
7
  }
8
8
  declare const globalSetup: () => Promise<void>;
@@ -1,7 +1,7 @@
1
1
  import type { FC, RefObject } from "react";
2
2
  import React from "react";
3
3
  import type { MeasureInWindowOnSuccessCallback, MeasureOnSuccessCallback, ViewProps } from "react-native";
4
- import { type SharedValue } from "react-native-reanimated";
4
+ import type { SharedValue } from "react-native-reanimated";
5
5
  import type { SkImage, SkRect, SkSize } from "../skia/types";
6
6
  export interface CanvasRef extends FC<CanvasProps> {
7
7
  makeImageSnapshot(rect?: SkRect): SkImage;
@@ -7,7 +7,9 @@ import SkiaPictureViewNativeComponent from "../specs/SkiaPictureViewNativeCompon
7
7
  import { SkiaSGRoot } from "../sksg/Reconciler";
8
8
  import { Skia } from "../skia";
9
9
  import { Platform } from "../Platform";
10
+ import { HAS_REANIMATED_3 } from "../external";
10
11
  export const useCanvasRef = () => useRef(null);
12
+ const useReanimatedFrame = !HAS_REANIMATED_3 ? () => {} : Rea.useFrameCallback;
11
13
  export const useCanvasSize = userRef => {
12
14
  const ourRef = useCanvasRef();
13
15
  const ref = userRef !== null && userRef !== void 0 ? userRef : ourRef;
@@ -60,39 +62,26 @@ export const Canvas = ({
60
62
 
61
63
  // Root
62
64
  const root = useMemo(() => new SkiaSGRoot(Skia, nativeId), [nativeId]);
63
- const updateSize = useCallback(value => {
64
- if (onSize) {
65
- onSize.value = value;
66
- }
67
- }, [onSize]);
65
+ useReanimatedFrame(() => {
66
+ "worklet";
67
+ }, !!onSize);
68
68
  useEffect(() => {
69
69
  if (onSize) {
70
- const {
71
- runOnJS
72
- } = Rea;
73
- const uiOnSize = Rea.makeMutable({
74
- width: 0,
75
- height: 0
76
- });
77
70
  Rea.runOnUI(() => {
78
71
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
79
72
  // @ts-expect-error
80
- global[`__onSize_${nativeId}`] = uiOnSize;
81
- uiOnSize.addListener(nativeId, value => {
82
- runOnJS(updateSize)(value);
83
- });
73
+ global[`__onSize_${nativeId}`] = onSize;
84
74
  })();
85
75
  return () => {
86
76
  Rea.runOnUI(() => {
87
77
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
88
78
  // @ts-expect-error
89
79
  delete global[`__onSize_${nativeId}`];
90
- uiOnSize.removeListener(nativeId);
91
80
  })();
92
81
  };
93
82
  }
94
83
  return undefined;
95
- }, [onSize, nativeId, updateSize]);
84
+ }, [onSize, nativeId]);
96
85
 
97
86
  // Render effects
98
87
  useLayoutEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"names":["React","useCallback","useEffect","useImperativeHandle","useLayoutEffect","useMemo","useRef","useState","Rea","SkiaViewNativeId","SkiaPictureViewNativeComponent","SkiaSGRoot","Skia","Platform","useCanvasRef","useCanvasSize","userRef","ourRef","ref","size","setSize","width","height","current","measure","_x","_y","isFabric","Boolean","_global","global","nativeFabricUIManager","Canvas","debug","opaque","children","onSize","colorSpace","onLayout","viewProps","console","error","viewRef","nativeId","root","updateSize","value","runOnJS","uiOnSize","makeMutable","runOnUI","addListener","removeListener","undefined","render","unmount","makeImageSnapshot","rect","SkiaViewApi","makeImageSnapshotAsync","redraw","requestRedraw","getNativeId","callback","_viewRef$current","measureInWindow","_viewRef$current2","onLayoutWeb","e","OS","nativeEvent","layout","createElement","_extends","collapsable","nativeID"],"sources":["Canvas.tsx"],"sourcesContent":["import type { FC, RefObject } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n LayoutChangeEvent,\n MeasureInWindowOnSuccessCallback,\n MeasureOnSuccessCallback,\n View,\n ViewProps,\n} from \"react-native\";\nimport { type SharedValue } from \"react-native-reanimated\";\n\nimport Rea from \"../external/reanimated/ReanimatedProxy\";\nimport { SkiaViewNativeId } from \"../views/SkiaViewNativeId\";\nimport SkiaPictureViewNativeComponent from \"../specs/SkiaPictureViewNativeComponent\";\nimport type { SkImage, SkRect, SkSize } from \"../skia/types\";\nimport { SkiaSGRoot } from \"../sksg/Reconciler\";\nimport { Skia } from \"../skia\";\nimport { Platform } from \"../Platform\";\n\nexport interface CanvasRef extends FC<CanvasProps> {\n makeImageSnapshot(rect?: SkRect): SkImage;\n makeImageSnapshotAsync(rect?: SkRect): Promise<SkImage>;\n redraw(): void;\n getNativeId(): number;\n measure(callback: MeasureOnSuccessCallback): void;\n measureInWindow(callback: MeasureInWindowOnSuccessCallback): void;\n}\n\nexport const useCanvasRef = () => useRef<CanvasRef>(null);\n\nexport const useCanvasSize = (userRef?: RefObject<CanvasRef | null>) => {\n const ourRef = useCanvasRef();\n const ref = userRef ?? ourRef;\n const [size, setSize] = useState<SkSize>({ width: 0, height: 0 });\n useLayoutEffect(() => {\n if (ref.current) {\n ref.current.measure((_x, _y, width, height) => {\n setSize({ width, height });\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return { ref, size };\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const isFabric = Boolean((global as any)?.nativeFabricUIManager);\n\nexport interface CanvasProps extends Omit<ViewProps, \"onLayout\"> {\n debug?: boolean;\n opaque?: boolean;\n onSize?: SharedValue<SkSize>;\n colorSpace?: \"p3\" | \"srgb\";\n ref?: React.Ref<CanvasRef>;\n __destroyWebGLContextAfterRender?: boolean;\n}\n\nexport const Canvas = ({\n debug,\n opaque,\n children,\n onSize,\n colorSpace = \"p3\",\n ref,\n // Here know this is a type error but this is done on purpose to check it at runtime\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n onLayout,\n ...viewProps\n}: CanvasProps) => {\n if (onLayout && isFabric) {\n console.error(\n // eslint-disable-next-line max-len\n \"<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://shopify.github.io/react-native-skia/docs/canvas/overview/#getting-the-canvas-size\"\n );\n }\n const viewRef = useRef<View>(null);\n // Native ID\n const nativeId = useMemo(() => {\n return SkiaViewNativeId.current++;\n }, []);\n\n // Root\n const root = useMemo(() => new SkiaSGRoot(Skia, nativeId), [nativeId]);\n\n const updateSize = useCallback(\n (value: SkSize) => {\n if (onSize) {\n onSize.value = value;\n }\n },\n [onSize]\n );\n useEffect(() => {\n if (onSize) {\n const { runOnJS } = Rea;\n const uiOnSize = Rea.makeMutable({ width: 0, height: 0 });\n Rea.runOnUI(() => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n global[`__onSize_${nativeId}`] = uiOnSize;\n uiOnSize.addListener(nativeId, (value) => {\n runOnJS(updateSize)(value);\n });\n })();\n return () => {\n Rea.runOnUI(() => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n delete global[`__onSize_${nativeId}`];\n uiOnSize.removeListener(nativeId);\n })();\n };\n }\n return undefined;\n }, [onSize, nativeId, updateSize]);\n\n // Render effects\n useLayoutEffect(() => {\n root.render(children);\n }, [children, root, nativeId]);\n\n useEffect(() => {\n return () => {\n root.unmount();\n };\n }, [root]);\n\n // Component methods\n useImperativeHandle(\n ref,\n () =>\n ({\n makeImageSnapshot: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshot(nativeId, rect);\n },\n makeImageSnapshotAsync: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshotAsync(nativeId, rect);\n },\n redraw: () => {\n SkiaViewApi.requestRedraw(nativeId);\n },\n getNativeId: () => {\n return nativeId;\n },\n measure: (callback) => {\n viewRef.current?.measure(callback);\n },\n measureInWindow: (callback) => {\n viewRef.current?.measureInWindow(callback);\n },\n } as CanvasRef)\n );\n\n const onLayoutWeb = useCallback(\n (e: LayoutChangeEvent) => {\n if (onLayout) {\n onLayout(e);\n }\n if (Platform.OS === \"web\" && onSize) {\n const { width, height } = e.nativeEvent.layout;\n onSize.value = { width, height };\n }\n },\n [onLayout, onSize]\n );\n\n return (\n <SkiaPictureViewNativeComponent\n ref={viewRef}\n collapsable={false}\n nativeID={`${nativeId}`}\n debug={debug}\n opaque={opaque}\n colorSpace={colorSpace}\n onLayout={onLayoutWeb}\n {...viewProps}\n />\n );\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","useCallback","useEffect","useImperativeHandle","useLayoutEffect","useMemo","useRef","useState","Rea","SkiaViewNativeId","SkiaPictureViewNativeComponent","SkiaSGRoot","Skia","Platform","HAS_REANIMATED_3","useCanvasRef","useReanimatedFrame","useFrameCallback","useCanvasSize","userRef","ourRef","ref","size","setSize","width","height","current","measure","_x","_y","isFabric","Boolean","_global","global","nativeFabricUIManager","Canvas","debug","opaque","children","onSize","colorSpace","onLayout","viewProps","console","error","viewRef","nativeId","root","runOnUI","undefined","render","unmount","makeImageSnapshot","rect","SkiaViewApi","makeImageSnapshotAsync","redraw","requestRedraw","getNativeId","callback","_viewRef$current","measureInWindow","_viewRef$current2","onLayoutWeb","e","OS","nativeEvent","layout","value","createElement","_extends","collapsable","nativeID"],"sources":["Canvas.tsx"],"sourcesContent":["import type { FC, RefObject } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n LayoutChangeEvent,\n MeasureInWindowOnSuccessCallback,\n MeasureOnSuccessCallback,\n View,\n ViewProps,\n} from \"react-native\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\nimport Rea from \"../external/reanimated/ReanimatedProxy\";\nimport { SkiaViewNativeId } from \"../views/SkiaViewNativeId\";\nimport SkiaPictureViewNativeComponent from \"../specs/SkiaPictureViewNativeComponent\";\nimport type { SkImage, SkRect, SkSize } from \"../skia/types\";\nimport { SkiaSGRoot } from \"../sksg/Reconciler\";\nimport { Skia } from \"../skia\";\nimport { Platform } from \"../Platform\";\nimport { HAS_REANIMATED_3 } from \"../external\";\n\nexport interface CanvasRef extends FC<CanvasProps> {\n makeImageSnapshot(rect?: SkRect): SkImage;\n makeImageSnapshotAsync(rect?: SkRect): Promise<SkImage>;\n redraw(): void;\n getNativeId(): number;\n measure(callback: MeasureOnSuccessCallback): void;\n measureInWindow(callback: MeasureInWindowOnSuccessCallback): void;\n}\n\nexport const useCanvasRef = () => useRef<CanvasRef>(null);\n\nconst useReanimatedFrame = !HAS_REANIMATED_3 ? () => {} : Rea.useFrameCallback;\n\nexport const useCanvasSize = (userRef?: RefObject<CanvasRef | null>) => {\n const ourRef = useCanvasRef();\n const ref = userRef ?? ourRef;\n const [size, setSize] = useState<SkSize>({ width: 0, height: 0 });\n useLayoutEffect(() => {\n if (ref.current) {\n ref.current.measure((_x, _y, width, height) => {\n setSize({ width, height });\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return { ref, size };\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const isFabric = Boolean((global as any)?.nativeFabricUIManager);\n\nexport interface CanvasProps extends Omit<ViewProps, \"onLayout\"> {\n debug?: boolean;\n opaque?: boolean;\n onSize?: SharedValue<SkSize>;\n colorSpace?: \"p3\" | \"srgb\";\n ref?: React.Ref<CanvasRef>;\n __destroyWebGLContextAfterRender?: boolean;\n}\n\nexport const Canvas = ({\n debug,\n opaque,\n children,\n onSize,\n colorSpace = \"p3\",\n ref,\n // Here know this is a type error but this is done on purpose to check it at runtime\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n onLayout,\n ...viewProps\n}: CanvasProps) => {\n if (onLayout && isFabric) {\n console.error(\n // eslint-disable-next-line max-len\n \"<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://shopify.github.io/react-native-skia/docs/canvas/overview/#getting-the-canvas-size\"\n );\n }\n const viewRef = useRef<View>(null);\n // Native ID\n const nativeId = useMemo(() => {\n return SkiaViewNativeId.current++;\n }, []);\n\n // Root\n const root = useMemo(() => new SkiaSGRoot(Skia, nativeId), [nativeId]);\n\n useReanimatedFrame(() => {\n \"worklet\";\n }, !!onSize);\n useEffect(() => {\n if (onSize) {\n Rea.runOnUI(() => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n global[`__onSize_${nativeId}`] = onSize;\n })();\n return () => {\n Rea.runOnUI(() => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n delete global[`__onSize_${nativeId}`];\n })();\n };\n }\n return undefined;\n }, [onSize, nativeId]);\n\n // Render effects\n useLayoutEffect(() => {\n root.render(children);\n }, [children, root, nativeId]);\n\n useEffect(() => {\n return () => {\n root.unmount();\n };\n }, [root]);\n\n // Component methods\n useImperativeHandle(\n ref,\n () =>\n ({\n makeImageSnapshot: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshot(nativeId, rect);\n },\n makeImageSnapshotAsync: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshotAsync(nativeId, rect);\n },\n redraw: () => {\n SkiaViewApi.requestRedraw(nativeId);\n },\n getNativeId: () => {\n return nativeId;\n },\n measure: (callback) => {\n viewRef.current?.measure(callback);\n },\n measureInWindow: (callback) => {\n viewRef.current?.measureInWindow(callback);\n },\n } as CanvasRef)\n );\n\n const onLayoutWeb = useCallback(\n (e: LayoutChangeEvent) => {\n if (onLayout) {\n onLayout(e);\n }\n if (Platform.OS === \"web\" && onSize) {\n const { width, height } = e.nativeEvent.layout;\n onSize.value = { width, height };\n }\n },\n [onLayout, onSize]\n );\n\n return (\n <SkiaPictureViewNativeComponent\n ref={viewRef}\n collapsable={false}\n nativeID={`${nativeId}`}\n debug={debug}\n opaque={opaque}\n colorSpace={colorSpace}\n onLayout={onLayoutWeb}\n {...viewProps}\n />\n );\n};\n"],"mappings":"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","ignoreList":[]}
@@ -3,7 +3,7 @@ import type { Server, WebSocket } from "ws";
3
3
  import type * as SkiaExports from "../../index";
4
4
  import type { SkImage, SkFont, Skia, SkCanvas } from "../../skia/types";
5
5
  import { SkiaSGRoot } from "../../sksg/Reconciler";
6
- type TestOS = "ios" | "android" | "web" | "node";
6
+ type TestOS = "ios" | "android" | "web" | "node" | "macos";
7
7
  declare global {
8
8
  var testServer: Server;
9
9
  var testClient: WebSocket;
@@ -2,7 +2,7 @@ import type { Server, WebSocket } from "ws";
2
2
  declare global {
3
3
  var testServer: Server;
4
4
  var testClient: WebSocket;
5
- var testOS: "ios" | "android" | "web" | "node";
5
+ var testOS: "ios" | "android" | "web" | "node" | "macos";
6
6
  var testArch: "paper" | "fabric";
7
7
  }
8
8
  declare const globalSetup: () => Promise<void>;
@@ -1,7 +1,7 @@
1
1
  import type { FC, RefObject } from "react";
2
2
  import React from "react";
3
3
  import type { MeasureInWindowOnSuccessCallback, MeasureOnSuccessCallback, ViewProps } from "react-native";
4
- import { type SharedValue } from "react-native-reanimated";
4
+ import type { SharedValue } from "react-native-reanimated";
5
5
  import type { SkImage, SkRect, SkSize } from "../skia/types";
6
6
  export interface CanvasRef extends FC<CanvasProps> {
7
7
  makeImageSnapshot(rect?: SkRect): SkImage;
@@ -3,7 +3,7 @@ import type { Server, WebSocket } from "ws";
3
3
  import type * as SkiaExports from "../../index";
4
4
  import type { SkImage, SkFont, Skia, SkCanvas } from "../../skia/types";
5
5
  import { SkiaSGRoot } from "../../sksg/Reconciler";
6
- type TestOS = "ios" | "android" | "web" | "node";
6
+ type TestOS = "ios" | "android" | "web" | "node" | "macos";
7
7
  declare global {
8
8
  var testServer: Server;
9
9
  var testClient: WebSocket;
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "setup-skia-web": "scripts/setup-canvaskit.js"
9
9
  },
10
10
  "title": "React Native Skia",
11
- "version": "2.2.15",
11
+ "version": "2.2.16",
12
12
  "description": "High-performance React Native Graphics using Skia",
13
13
  "main": "lib/module/index.js",
14
14
  "react-native": "src/index.ts",
@@ -4,12 +4,14 @@ import { WebSocketServer } from "ws";
4
4
  declare global {
5
5
  var testServer: Server;
6
6
  var testClient: WebSocket;
7
- var testOS: "ios" | "android" | "web" | "node";
7
+ var testOS: "ios" | "android" | "web" | "node" | "macos";
8
8
  var testArch: "paper" | "fabric";
9
9
  }
10
10
 
11
- const isOS = (os: string): os is "android" | "ios" | "web" => {
12
- return ["ios", "android", "web"].indexOf(os) !== -1;
11
+ const isOS = (
12
+ os: string
13
+ ): os is "android" | "ios" | "web" | "node" | "macos" => {
14
+ return ["ios", "android", "web", "node", "macos"].indexOf(os) !== -1;
13
15
  };
14
16
 
15
17
  const isArch = (arc: string): arc is "paper" | "fabric" => {
@@ -15,7 +15,7 @@ import type {
15
15
  View,
16
16
  ViewProps,
17
17
  } from "react-native";
18
- import { type SharedValue } from "react-native-reanimated";
18
+ import type { SharedValue } from "react-native-reanimated";
19
19
 
20
20
  import Rea from "../external/reanimated/ReanimatedProxy";
21
21
  import { SkiaViewNativeId } from "../views/SkiaViewNativeId";
@@ -24,6 +24,7 @@ import type { SkImage, SkRect, SkSize } from "../skia/types";
24
24
  import { SkiaSGRoot } from "../sksg/Reconciler";
25
25
  import { Skia } from "../skia";
26
26
  import { Platform } from "../Platform";
27
+ import { HAS_REANIMATED_3 } from "../external";
27
28
 
28
29
  export interface CanvasRef extends FC<CanvasProps> {
29
30
  makeImageSnapshot(rect?: SkRect): SkImage;
@@ -36,6 +37,8 @@ export interface CanvasRef extends FC<CanvasProps> {
36
37
 
37
38
  export const useCanvasRef = () => useRef<CanvasRef>(null);
38
39
 
40
+ const useReanimatedFrame = !HAS_REANIMATED_3 ? () => {} : Rea.useFrameCallback;
41
+
39
42
  export const useCanvasSize = (userRef?: RefObject<CanvasRef | null>) => {
40
43
  const ourRef = useCanvasRef();
41
44
  const ref = userRef ?? ourRef;
@@ -91,37 +94,26 @@ export const Canvas = ({
91
94
  // Root
92
95
  const root = useMemo(() => new SkiaSGRoot(Skia, nativeId), [nativeId]);
93
96
 
94
- const updateSize = useCallback(
95
- (value: SkSize) => {
96
- if (onSize) {
97
- onSize.value = value;
98
- }
99
- },
100
- [onSize]
101
- );
97
+ useReanimatedFrame(() => {
98
+ "worklet";
99
+ }, !!onSize);
102
100
  useEffect(() => {
103
101
  if (onSize) {
104
- const { runOnJS } = Rea;
105
- const uiOnSize = Rea.makeMutable({ width: 0, height: 0 });
106
102
  Rea.runOnUI(() => {
107
103
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
108
104
  // @ts-expect-error
109
- global[`__onSize_${nativeId}`] = uiOnSize;
110
- uiOnSize.addListener(nativeId, (value) => {
111
- runOnJS(updateSize)(value);
112
- });
105
+ global[`__onSize_${nativeId}`] = onSize;
113
106
  })();
114
107
  return () => {
115
108
  Rea.runOnUI(() => {
116
109
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
117
110
  // @ts-expect-error
118
111
  delete global[`__onSize_${nativeId}`];
119
- uiOnSize.removeListener(nativeId);
120
112
  })();
121
113
  };
122
114
  }
123
115
  return undefined;
124
- }, [onSize, nativeId, updateSize]);
116
+ }, [onSize, nativeId]);
125
117
 
126
118
  // Render effects
127
119
  useLayoutEffect(() => {
@@ -21,7 +21,7 @@ import { SkiaObject } from "./e2e/setup";
21
21
 
22
22
  jest.setTimeout(180 * 1000);
23
23
 
24
- type TestOS = "ios" | "android" | "web" | "node";
24
+ type TestOS = "ios" | "android" | "web" | "node" | "macos";
25
25
 
26
26
  declare global {
27
27
  var testServer: Server;