@shopify/react-native-skia 2.4.16 → 2.4.18

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.
Files changed (52) hide show
  1. package/android/CMakeLists.txt +30 -0
  2. package/lib/commonjs/Platform/Platform.web.js +1 -2
  3. package/lib/commonjs/Platform/Platform.web.js.map +1 -1
  4. package/lib/commonjs/external/reanimated/buffers.js.map +1 -1
  5. package/lib/commonjs/external/reanimated/interpolators.d.ts +1 -4
  6. package/lib/commonjs/renderer/Canvas.js +4 -3
  7. package/lib/commonjs/renderer/Canvas.js.map +1 -1
  8. package/lib/commonjs/renderer/components/Group.js +1 -2
  9. package/lib/commonjs/renderer/components/Group.js.map +1 -1
  10. package/lib/commonjs/renderer/components/shapes/FitBox.js +1 -2
  11. package/lib/commonjs/renderer/components/shapes/FitBox.js.map +1 -1
  12. package/lib/commonjs/skia/types/ContourMeasure.js.map +1 -1
  13. package/lib/commonjs/skia/types/RuntimeEffect/RuntimeEffect.js.map +1 -1
  14. package/lib/commonjs/skia/web/JsiSkParagraphStyle.js +2 -2
  15. package/lib/commonjs/skia/web/JsiSkParagraphStyle.js.map +1 -1
  16. package/lib/commonjs/sksg/Recorder/commands/ColorFilters.js.map +1 -1
  17. package/lib/commonjs/sksg/Recorder/commands/ImageFilters.js.map +1 -1
  18. package/lib/commonjs/sksg/Recorder/commands/PathEffects.js.map +1 -1
  19. package/lib/commonjs/sksg/Recorder/commands/Shaders.js.map +1 -1
  20. package/lib/commonjs/views/SkiaPictureView.web.js +4 -4
  21. package/lib/commonjs/views/SkiaPictureView.web.js.map +1 -1
  22. package/lib/commonjs/web/WithSkiaWeb.js +1 -2
  23. package/lib/commonjs/web/WithSkiaWeb.js.map +1 -1
  24. package/lib/module/external/reanimated/buffers.js.map +1 -1
  25. package/lib/module/external/reanimated/interpolators.d.ts +1 -4
  26. package/lib/module/renderer/Canvas.js +3 -1
  27. package/lib/module/renderer/Canvas.js.map +1 -1
  28. package/lib/module/skia/types/ContourMeasure.js.map +1 -1
  29. package/lib/module/skia/types/RuntimeEffect/RuntimeEffect.js.map +1 -1
  30. package/lib/module/skia/web/JsiSkParagraphStyle.js +2 -2
  31. package/lib/module/skia/web/JsiSkParagraphStyle.js.map +1 -1
  32. package/lib/module/sksg/Recorder/commands/ColorFilters.js.map +1 -1
  33. package/lib/module/sksg/Recorder/commands/ImageFilters.js.map +1 -1
  34. package/lib/module/sksg/Recorder/commands/PathEffects.js.map +1 -1
  35. package/lib/module/sksg/Recorder/commands/Shaders.js.map +1 -1
  36. package/lib/module/views/SkiaPictureView.web.js +3 -2
  37. package/lib/module/views/SkiaPictureView.web.js.map +1 -1
  38. package/lib/typescript/lib/module/renderer/Canvas.d.ts +1 -1
  39. package/lib/typescript/lib/module/views/SkiaPictureView.d.ts +1 -1
  40. package/lib/typescript/src/external/reanimated/interpolators.d.ts +1 -4
  41. package/package.json +16 -12
  42. package/react-native-skia.podspec +48 -10
  43. package/scripts/install-skia.mjs +95 -45
  44. package/src/external/reanimated/buffers.ts +1 -1
  45. package/src/renderer/Canvas.tsx +3 -2
  46. package/src/skia/types/ContourMeasure.tsx +1 -2
  47. package/src/skia/types/RuntimeEffect/RuntimeEffect.ts +1 -2
  48. package/src/sksg/Recorder/commands/ColorFilters.ts +3 -2
  49. package/src/sksg/Recorder/commands/ImageFilters.ts +3 -2
  50. package/src/sksg/Recorder/commands/PathEffects.ts +3 -2
  51. package/src/sksg/Recorder/commands/Shaders.ts +3 -2
  52. package/src/views/SkiaPictureView.web.tsx +4 -1
@@ -8,6 +8,12 @@ import { fileURLToPath } from "url";
8
8
 
9
9
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
10
 
11
+ // Allow skipping download via environment variable (useful for CI builds)
12
+ if (process.env.SKIP_SKIA_DOWNLOAD === '1' || process.env.SKIP_SKIA_DOWNLOAD === 'true') {
13
+ console.log("⏭️ Skipping Skia download (SKIP_SKIA_DOWNLOAD is set)");
14
+ process.exit(0);
15
+ }
16
+
11
17
  const repo = "shopify/react-native-skia";
12
18
 
13
19
  const packageJsonPath = path.join(__dirname, "..", "package.json");
@@ -42,13 +48,24 @@ const updateSkiaChecksums = (checksums, graphite = false) => {
42
48
 
43
49
  const GRAPHITE = !!process.env.SK_GRAPHITE;
44
50
  const prefix = GRAPHITE ? "skia-graphite" : "skia";
51
+
52
+ // Build artifact names based on platform and Graphite mode
45
53
  const names = [
46
54
  `${prefix}-android-arm`,
47
55
  `${prefix}-android-arm-64`,
48
56
  `${prefix}-android-arm-x64`,
49
57
  `${prefix}-android-arm-x86`,
50
- `${prefix}-apple-xcframeworks`,
58
+ `${prefix}-apple-ios-xcframeworks`,
59
+ `${prefix}-apple-macos-xcframeworks`,
51
60
  ];
61
+
62
+ // Add tvOS only for non-Graphite builds
63
+ if (!GRAPHITE) {
64
+ names.push(`${prefix}-apple-tvos-xcframeworks`);
65
+ }
66
+
67
+ // Note: macCatalyst is now included in the iOS xcframeworks, no separate download needed
68
+
52
69
  if (GRAPHITE) {
53
70
  names.push(`${prefix}-headers`);
54
71
  }
@@ -347,11 +364,18 @@ const calculateLibraryChecksums = () => {
347
364
  }
348
365
  }
349
366
 
350
- // Apple frameworks
351
- const appleDir = path.join(libsDir, "apple");
352
- const appleChecksum = calculateDirectoryChecksum(appleDir);
353
- if (appleChecksum) {
354
- checksums["apple-xcframeworks"] = appleChecksum;
367
+ // Apple platforms - calculate separate checksums for each platform
368
+ // Note: maccatalyst is included in iOS xcframeworks, not a separate artifact
369
+ const applePlatforms = GRAPHITE
370
+ ? ["ios", "macos"]
371
+ : ["ios", "tvos", "macos"];
372
+
373
+ for (const platform of applePlatforms) {
374
+ const platformDir = path.join(libsDir, "apple", platform);
375
+ const checksum = calculateDirectoryChecksum(platformDir);
376
+ if (checksum) {
377
+ checksums[`apple-${platform}-xcframeworks`] = checksum;
378
+ }
355
379
  }
356
380
 
357
381
  return checksums;
@@ -401,10 +425,16 @@ const areBinariesInstalled = () => {
401
425
  }
402
426
  }
403
427
 
404
- // Check for Apple frameworks
405
- const appleDir = path.join(libsDir, "apple");
406
- if (!fs.existsSync(appleDir) || fs.readdirSync(appleDir).length === 0) {
407
- return false;
428
+ // Check for Apple platform frameworks
429
+ const applePlatforms = GRAPHITE
430
+ ? ["ios", "macos"]
431
+ : ["ios", "tvos", "macos", "maccatalyst"];
432
+
433
+ for (const platform of applePlatforms) {
434
+ const platformDir = path.join(libsDir, "apple", platform);
435
+ if (!fs.existsSync(platformDir) || fs.readdirSync(platformDir).length === 0) {
436
+ return false;
437
+ }
408
438
  }
409
439
 
410
440
  return true;
@@ -524,45 +554,65 @@ const main = async () => {
524
554
  }
525
555
  });
526
556
 
527
- // Create apple directory structure
557
+ // Create apple directory structure - now per-platform
528
558
  const appleDir = path.join(libsDir, "apple");
529
- // The tar file extracts to skia-apple-xcframeworks/apple
530
- const appleSrcDir = path.join(
531
- artifactsDir,
532
- `${prefix}-apple-xcframeworks`,
533
- "apple"
534
- );
535
- if (fs.existsSync(appleSrcDir)) {
536
- fs.mkdirSync(appleDir, { recursive: true });
537
-
538
- // Copy all xcframeworks
539
- fs.readdirSync(appleSrcDir).forEach((item) => {
540
- const srcPath = path.join(appleSrcDir, item);
541
- const destPath = path.join(appleDir, item);
542
-
543
- if (fs.lstatSync(srcPath).isDirectory()) {
544
- // Copy directory recursively
545
- const copyDir = (src, dest) => {
546
- fs.mkdirSync(dest, { recursive: true });
547
- fs.readdirSync(src).forEach((file) => {
548
- const srcFile = path.join(src, file);
549
- const destFile = path.join(dest, file);
550
- if (fs.lstatSync(srcFile).isDirectory()) {
551
- copyDir(srcFile, destFile);
552
- } else {
553
- fs.copyFileSync(srcFile, destFile);
554
- }
555
- });
556
- };
557
- copyDir(srcPath, destPath);
558
- } else {
559
- fs.copyFileSync(srcPath, destPath);
560
- }
561
- });
562
- }
559
+ fs.mkdirSync(appleDir, { recursive: true });
560
+
561
+ // Define the platform artifacts to process
562
+ // Note: maccatalyst is included in iOS xcframeworks, not a separate artifact
563
+ const applePlatformArtifacts = GRAPHITE
564
+ ? [
565
+ { artifact: `${prefix}-apple-ios-xcframeworks`, srcSubdir: "ios", dest: "ios" },
566
+ { artifact: `${prefix}-apple-macos-xcframeworks`, srcSubdir: "macos", dest: "macos" },
567
+ ]
568
+ : [
569
+ { artifact: `${prefix}-apple-ios-xcframeworks`, srcSubdir: "ios", dest: "ios" },
570
+ { artifact: `${prefix}-apple-tvos-xcframeworks`, srcSubdir: "tvos", dest: "tvos" },
571
+ { artifact: `${prefix}-apple-macos-xcframeworks`, srcSubdir: "macos", dest: "macos" },
572
+ ];
573
+
574
+ applePlatformArtifacts.forEach(({ artifact, srcSubdir, dest }) => {
575
+ // The tar file extracts to artifact_name/srcSubdir (e.g., skia-apple-ios-xcframeworks/ios)
576
+ const appleSrcDir = path.join(artifactsDir, artifact, srcSubdir);
577
+ const destDir = path.join(appleDir, dest);
578
+
579
+ console.log(` Checking ${appleSrcDir} -> ${destDir}`);
580
+ if (fs.existsSync(appleSrcDir)) {
581
+ console.log(` ✓ Copying ${artifact}/${srcSubdir}`);
582
+ fs.mkdirSync(destDir, { recursive: true });
583
+
584
+ // Copy all xcframeworks
585
+ fs.readdirSync(appleSrcDir).forEach((item) => {
586
+ const srcPath = path.join(appleSrcDir, item);
587
+ const destPath = path.join(destDir, item);
588
+
589
+ if (fs.lstatSync(srcPath).isDirectory()) {
590
+ // Copy directory recursively
591
+ const copyDir = (src, dest) => {
592
+ fs.mkdirSync(dest, { recursive: true });
593
+ fs.readdirSync(src).forEach((file) => {
594
+ const srcFile = path.join(src, file);
595
+ const destFile = path.join(dest, file);
596
+ if (fs.lstatSync(srcFile).isDirectory()) {
597
+ copyDir(srcFile, destFile);
598
+ } else {
599
+ fs.copyFileSync(srcFile, destFile);
600
+ }
601
+ });
602
+ };
603
+ copyDir(srcPath, destPath);
604
+ } else {
605
+ fs.copyFileSync(srcPath, destPath);
606
+ }
607
+ });
608
+ } else {
609
+ console.log(` ✗ Source directory not found: ${appleSrcDir}`);
610
+ }
611
+ });
563
612
 
564
613
  // Create or remove Graphite marker files based on build type
565
614
  const androidMarkerFile = path.join(androidDir, "graphite.enabled");
615
+ // Apple marker file stays at the apple root level (libs/apple/graphite.enabled)
566
616
  const appleMarkerFile = path.join(appleDir, "graphite.enabled");
567
617
 
568
618
  if (GRAPHITE) {
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useMemo } from "react";
2
- import type { WorkletFunction } from "react-native-reanimated/lib/typescript/commonTypes";
2
+ import type { WorkletFunction } from "react-native-worklets";
3
3
 
4
4
  import type { SkColor, SkHostRect, SkPoint, SkRSXform } from "../../skia/types";
5
5
  import { Skia } from "../../skia";
@@ -15,7 +15,7 @@ import type {
15
15
  View,
16
16
  ViewProps,
17
17
  } from "react-native";
18
- import type { AnimatedRef, 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";
@@ -113,7 +113,8 @@ export const Canvas = ({
113
113
  // @ts-expect-error
114
114
  measure(viewRef.current.canvasRef)
115
115
  : { width: 0, height: 0 }
116
- : measure(viewRef as AnimatedRef<View>);
116
+ : // eslint-disable-next-line @typescript-eslint/no-explicit-any
117
+ measure(viewRef as any);
117
118
  if (result) {
118
119
  const { width, height } = result;
119
120
  if (onSize.value.width !== width || onSize.value.height !== height) {
@@ -36,8 +36,7 @@ export interface SkContourMeasure extends SkJSIInstance<"ContourMeasure"> {
36
36
  length(): number;
37
37
  }
38
38
 
39
- export interface SkContourMeasureIter
40
- extends SkJSIInstance<"ContourMeasureIter"> {
39
+ export interface SkContourMeasureIter extends SkJSIInstance<"ContourMeasureIter"> {
41
40
  /**
42
41
  * Iterates through contours in path, returning a contour-measure object for each contour
43
42
  * in the path. Returns null when it is done.
@@ -10,8 +10,7 @@ export interface SkSLUniform {
10
10
  isInteger: boolean;
11
11
  }
12
12
 
13
- export interface SkRuntimeShaderBuilder
14
- extends SkJSIInstance<"RuntimeShaderBuilder"> {
13
+ export interface SkRuntimeShaderBuilder extends SkJSIInstance<"RuntimeShaderBuilder"> {
15
14
  setUniform(name: string, value: readonly number[]): void;
16
15
  }
17
16
 
@@ -27,8 +27,9 @@ type Props = {
27
27
  [NodeType.SRGBToLinearGammaColorFilter]: Record<string, never>;
28
28
  };
29
29
 
30
- interface PushColorFilter<T extends keyof Props>
31
- extends Command<CommandType.PushColorFilter> {
30
+ interface PushColorFilter<
31
+ T extends keyof Props,
32
+ > extends Command<CommandType.PushColorFilter> {
32
33
  colorFilterType: T;
33
34
  props: Props[T];
34
35
  }
@@ -224,8 +224,9 @@ type Props = {
224
224
  [NodeType.RuntimeShaderImageFilter]: RuntimeShaderImageFilterProps;
225
225
  };
226
226
 
227
- interface PushImageFilter<T extends keyof Props>
228
- extends Command<CommandType.PushImageFilter> {
227
+ interface PushImageFilter<
228
+ T extends keyof Props,
229
+ > extends Command<CommandType.PushImageFilter> {
229
230
  imageFilterType: T;
230
231
  props: Props[T];
231
232
  }
@@ -121,8 +121,9 @@ type Props = {
121
121
  [NodeType.Line2DPathEffect]: Line2DPathEffectProps;
122
122
  };
123
123
 
124
- interface PushPathEffect<T extends keyof Props>
125
- extends Command<CommandType.PushPathEffect> {
124
+ interface PushPathEffect<
125
+ T extends keyof Props,
126
+ > extends Command<CommandType.PushPathEffect> {
126
127
  pathEffectType: T;
127
128
  props: Props[T];
128
129
  }
@@ -257,8 +257,9 @@ type Props = {
257
257
  [NodeType.Blend]: BlendProps;
258
258
  };
259
259
 
260
- interface PushShader<T extends keyof Props>
261
- extends Command<CommandType.PushShader> {
260
+ interface PushShader<
261
+ T extends keyof Props,
262
+ > extends Command<CommandType.PushShader> {
262
263
  shaderType: T;
263
264
  props: Props[T];
264
265
  children: number;
@@ -419,7 +419,10 @@ export const SkiaPictureView = (props: SkiaPictureViewProps) => {
419
419
  const { debug = false, ref: _ref, ...viewProps } = props;
420
420
  return (
421
421
  <Platform.View {...viewProps} onLayout={onLayoutEvent}>
422
- <canvas ref={canvasRef} style={{ display: "flex", flex: 1 }} />
422
+ <canvas
423
+ ref={canvasRef}
424
+ style={{ display: "block", width: "100%", height: "100%" }}
425
+ />
423
426
  </Platform.View>
424
427
  );
425
428
  };