react-native-fast-image 8.6.31 → 8.6.33

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/README.md CHANGED
@@ -176,7 +176,7 @@ e.g. `onProgress={e => console.log(e.nativeEvent.loaded / e.nativeEvent.total)}`
176
176
 
177
177
  ### `onLoad?: (event) => void`
178
178
 
179
- Called on a successful image fetch. Called with the width and height of the loaded image.
179
+ Called on a successful image fetch. Called with the width and height of the image itself, not of the view (on iOS, in points: an `@2x` asset reports half its pixel size).
180
180
 
181
181
  e.g. `onLoad={e => console.log(e.nativeEvent.width, e.nativeEvent.height)}`
182
182
 
@@ -4,6 +4,8 @@ import android.graphics.drawable.Drawable;
4
4
 
5
5
  import com.bumptech.glide.load.DataSource;
6
6
  import com.bumptech.glide.load.engine.GlideException;
7
+ import com.bumptech.glide.load.model.GlideUrl;
8
+ import com.bumptech.glide.request.Request;
7
9
  import com.bumptech.glide.request.RequestListener;
8
10
  import com.bumptech.glide.request.target.ImageViewTarget;
9
11
  import com.bumptech.glide.request.target.Target;
@@ -17,16 +19,11 @@ public class FastImageRequestListener implements RequestListener<Drawable> {
17
19
  static final String REACT_ON_LOAD_EVENT = "onFastImageLoad";
18
20
  static final String REACT_ON_LOAD_END_EVENT = "onFastImageLoadEnd";
19
21
  private final String key;
22
+ private final FastImageSource source;
20
23
 
21
- FastImageRequestListener(String key) {
24
+ FastImageRequestListener(String key, FastImageSource source) {
22
25
  this.key = key;
23
- }
24
-
25
- private static WritableMap mapFromResource(Drawable resource) {
26
- WritableMap resourceData = new WritableNativeMap();
27
- resourceData.putInt("width", resource.getIntrinsicWidth());
28
- resourceData.putInt("height", resource.getIntrinsicHeight());
29
- return resourceData;
26
+ this.source = source;
30
27
  }
31
28
 
32
29
  @Override
@@ -48,19 +45,41 @@ public class FastImageRequestListener implements RequestListener<Drawable> {
48
45
  }
49
46
 
50
47
  @Override
51
- public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
48
+ public boolean onResourceReady(Drawable resource, Object model, final Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
52
49
  if (!(target instanceof ImageViewTarget)) {
53
50
  return false;
54
51
  }
55
- FastImageViewWithUrl view = (FastImageViewWithUrl) ((ImageViewTarget) target).getView();
52
+ final FastImageViewWithUrl view = (FastImageViewWithUrl) ((ImageViewTarget) target).getView();
53
+ boolean local = !(model instanceof GlideUrl);
54
+ int[] size = FastImageSourceSize.get(resource, model, local,
55
+ dataSource == DataSource.RESOURCE_DISK_CACHE);
56
+ if (size != null) {
57
+ sendLoad(view, size);
58
+ return false;
59
+ }
60
+ // A local image whose size isn't known: read it from the image first,
61
+ // unless the view starts another load meanwhile.
62
+ final Request request = target.getRequest();
63
+ FastImageSourceSize.readLocal(view.getContext(), source, resource, model, new FastImageSourceSize.Callback() {
64
+ @Override
65
+ public void onSize(int[] size) {
66
+ if (target.getRequest() == request) sendLoad(view, size);
67
+ }
68
+ });
69
+ return false;
70
+ }
71
+
72
+ private static void sendLoad(FastImageViewWithUrl view, int[] size) {
56
73
  ReactContext context = FastImageViewManager.getReactContext(view.getContext());
57
74
  if (context == null) {
58
- return false;
75
+ return;
59
76
  }
60
77
  RCTEventEmitter eventEmitter = context.getJSModule(RCTEventEmitter.class);
61
78
  int viewId = view.getId();
62
- eventEmitter.receiveEvent(viewId, REACT_ON_LOAD_EVENT, mapFromResource(resource));
79
+ WritableMap event = new WritableNativeMap();
80
+ event.putInt("width", size[0]);
81
+ event.putInt("height", size[1]);
82
+ eventEmitter.receiveEvent(viewId, REACT_ON_LOAD_EVENT, event);
63
83
  eventEmitter.receiveEvent(viewId, REACT_ON_LOAD_END_EVENT, new WritableNativeMap());
64
- return false;
65
84
  }
66
85
  }
@@ -0,0 +1,21 @@
1
+ package com.dylanvann.fastimage;
2
+
3
+ import com.facebook.react.uimanager.LayoutShadowNode;
4
+ import com.facebook.react.uimanager.UIViewOperationQueue;
5
+
6
+ // Legacy architecture only. React Native only lays out a view when its frame
7
+ // changes, so a view that stays 0×0 at its parent's origin is never laid out,
8
+ // and Glide waits for its size forever (#865). When the computed size is zero,
9
+ // tell the view, so it can lay itself out and load as it does on the New
10
+ // Architecture. Remove with legacy architecture support.
11
+ public class FastImageShadowNode extends LayoutShadowNode {
12
+ static final Object ZERO_LAYOUT = new Object();
13
+
14
+ @Override
15
+ public void onCollectExtraUpdates(UIViewOperationQueue uiViewOperationQueue) {
16
+ super.onCollectExtraUpdates(uiViewOperationQueue);
17
+ if (Math.round(getLayoutWidth()) == 0 && Math.round(getLayoutHeight()) == 0) {
18
+ uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), ZERO_LAYOUT);
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,237 @@
1
+ package com.dylanvann.fastimage;
2
+
3
+ import android.content.Context;
4
+ import android.graphics.BitmapFactory;
5
+ import android.graphics.drawable.Drawable;
6
+ import android.net.Uri;
7
+ import android.os.Handler;
8
+ import android.os.Looper;
9
+ import android.util.Base64;
10
+ import android.util.LruCache;
11
+ import android.widget.ImageView;
12
+
13
+ import androidx.annotation.Nullable;
14
+
15
+ import com.bumptech.glide.Glide;
16
+ import com.bumptech.glide.load.ImageHeaderParserUtils;
17
+ import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy;
18
+ import com.bumptech.glide.load.resource.gif.GifDrawable;
19
+ import com.bumptech.glide.request.RequestOptions;
20
+
21
+ import java.io.ByteArrayInputStream;
22
+ import java.io.IOException;
23
+ import java.io.InputStream;
24
+ import java.nio.ByteBuffer;
25
+ import java.util.concurrent.Executor;
26
+ import java.util.concurrent.Executors;
27
+
28
+ // Works out an image's own size for onLoad, as iOS reports it (#608). Glide
29
+ // decodes images to fit the view, so the loaded drawable is usually smaller
30
+ // than the image.
31
+ final class FastImageSourceSize {
32
+ // Sizes of recently decoded images, for loads from the memory cache, which
33
+ // don't decode.
34
+ private static final LruCache<String, int[]> SIZES = new LruCache<>(500);
35
+ private static final Executor EXECUTOR = Executors.newSingleThreadExecutor();
36
+ private static final Handler MAIN = new Handler(Looper.getMainLooper());
37
+
38
+ private FastImageSourceSize() {
39
+ }
40
+
41
+ // Wraps the downsample strategy Glide would use, to record the image's
42
+ // size (after EXIF rotation) when Glide decodes it. Views loading the same
43
+ // image at the same size share one decode, which uses the first view's
44
+ // options, so the size is recorded by image rather than by request.
45
+ static final class Capture extends DownsampleStrategy {
46
+ private final DownsampleStrategy strategy;
47
+ private final String key;
48
+ private boolean recorded;
49
+
50
+ Capture(DownsampleStrategy strategy, String key) {
51
+ this.strategy = strategy;
52
+ this.key = key;
53
+ }
54
+
55
+ @Override
56
+ public float getScaleFactor(int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight) {
57
+ // Called again with the sampled size; the first call has the image's.
58
+ if (!recorded) {
59
+ recorded = true;
60
+ SIZES.put(key, new int[]{sourceWidth, sourceHeight});
61
+ }
62
+ return strategy.getScaleFactor(sourceWidth, sourceHeight, requestedWidth, requestedHeight);
63
+ }
64
+
65
+ @Override
66
+ public SampleSizeRounding getSampleSizeRounding(int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight) {
67
+ return strategy.getSampleSizeRounding(sourceWidth, sourceHeight, requestedWidth, requestedHeight);
68
+ }
69
+
70
+ // Glide's memory cache keys include the strategy, so match the wrapped
71
+ // one to keep sharing cached images between views.
72
+ @Override
73
+ public boolean equals(Object o) {
74
+ return o instanceof Capture && ((Capture) o).strategy.equals(strategy);
75
+ }
76
+
77
+ @Override
78
+ public int hashCode() {
79
+ return strategy.hashCode();
80
+ }
81
+ }
82
+
83
+ // What RequestBuilder.into(ImageView) applies for the view's scale type
84
+ // (it leaves a transformation that's already set alone), with the
85
+ // downsample strategy it implies wrapped by capture.
86
+ static RequestOptions scaleTypeOptions(@Nullable ImageView.ScaleType scaleType, Capture capture) {
87
+ RequestOptions options = new RequestOptions();
88
+ if (scaleType != null) {
89
+ switch (scaleType) {
90
+ case CENTER_CROP:
91
+ options = options.optionalCenterCrop();
92
+ break;
93
+ case CENTER_INSIDE:
94
+ case FIT_XY:
95
+ options = options.optionalCenterInside();
96
+ break;
97
+ case FIT_CENTER:
98
+ case FIT_START:
99
+ case FIT_END:
100
+ options = options.optionalFitCenter();
101
+ break;
102
+ default:
103
+ break;
104
+ }
105
+ }
106
+ return options.downsample(capture);
107
+ }
108
+
109
+ static Capture capture(@Nullable ImageView.ScaleType scaleType, Object model) {
110
+ return new Capture(strategy(scaleType), String.valueOf(model));
111
+ }
112
+
113
+ private static DownsampleStrategy strategy(@Nullable ImageView.ScaleType scaleType) {
114
+ if (scaleType == null) return DownsampleStrategy.DEFAULT;
115
+ switch (scaleType) {
116
+ case CENTER_CROP:
117
+ return DownsampleStrategy.CENTER_OUTSIDE;
118
+ case CENTER_INSIDE:
119
+ case FIT_XY:
120
+ return DownsampleStrategy.CENTER_INSIDE;
121
+ case FIT_CENTER:
122
+ case FIT_START:
123
+ case FIT_END:
124
+ return DownsampleStrategy.FIT_CENTER;
125
+ default:
126
+ return DownsampleStrategy.DEFAULT;
127
+ }
128
+ }
129
+
130
+ // The image's size, or null when it has to be read from a local image's
131
+ // header first (see readLocal).
132
+ @Nullable
133
+ static int[] get(Drawable resource, Object model, boolean local, boolean fromResourceCache) {
134
+ String key = String.valueOf(model);
135
+ if (resource instanceof GifDrawable) {
136
+ // Glide decodes GIFs itself (sampled to fit the view), without the
137
+ // downsample strategy; their header has the size.
138
+ int[] size = gifSize((GifDrawable) resource);
139
+ if (size != null) return size;
140
+ } else if (fromResourceCache) {
141
+ // Glide caches local images already resized for the view, and the
142
+ // decode from there recorded the resized size.
143
+ SIZES.remove(key);
144
+ return null;
145
+ } else {
146
+ int[] size = SIZES.get(key);
147
+ if (size != null) return size;
148
+ if (local) return null;
149
+ }
150
+ return new int[]{resource.getIntrinsicWidth(), resource.getIntrinsicHeight()};
151
+ }
152
+
153
+ @Nullable
154
+ private static int[] gifSize(GifDrawable gif) {
155
+ ByteBuffer buffer = gif.getBuffer();
156
+ if (buffer == null || buffer.limit() < 10) return null;
157
+ // The logical screen width and height (little-endian) follow the
158
+ // 6-byte signature.
159
+ int width = (buffer.get(6) & 0xff) | (buffer.get(7) & 0xff) << 8;
160
+ int height = (buffer.get(8) & 0xff) | (buffer.get(9) & 0xff) << 8;
161
+ return new int[]{width, height};
162
+ }
163
+
164
+ interface Callback {
165
+ void onSize(int[] size);
166
+ }
167
+
168
+ // Reads a local image's size from its header, off the main thread.
169
+ static void readLocal(Context context, final FastImageSource source, final Drawable resource, final Object model, final Callback callback) {
170
+ final Context appContext = context.getApplicationContext();
171
+ EXECUTOR.execute(new Runnable() {
172
+ @Override
173
+ public void run() {
174
+ int[] size = readBounds(appContext, source);
175
+ if (size != null) {
176
+ SIZES.put(String.valueOf(model), size);
177
+ } else {
178
+ size = new int[]{resource.getIntrinsicWidth(), resource.getIntrinsicHeight()};
179
+ }
180
+ final int[] result = size;
181
+ MAIN.post(new Runnable() {
182
+ @Override
183
+ public void run() {
184
+ callback.onSize(result);
185
+ }
186
+ });
187
+ }
188
+ });
189
+ }
190
+
191
+ @Nullable
192
+ private static int[] readBounds(Context context, FastImageSource source) {
193
+ try {
194
+ BitmapFactory.Options options = new BitmapFactory.Options();
195
+ options.inJustDecodeBounds = true;
196
+ InputStream stream = open(context, source);
197
+ try {
198
+ BitmapFactory.decodeStream(stream, null, options);
199
+ } finally {
200
+ stream.close();
201
+ }
202
+ if (options.outWidth <= 0 || options.outHeight <= 0) return null;
203
+ int orientation;
204
+ stream = open(context, source);
205
+ try {
206
+ Glide glide = Glide.get(context);
207
+ orientation = ImageHeaderParserUtils.getOrientation(
208
+ glide.getRegistry().getImageHeaderParsers(), stream, glide.getArrayPool());
209
+ } finally {
210
+ stream.close();
211
+ }
212
+ // EXIF orientations 5 to 8 rotate by 90 or 270 degrees.
213
+ boolean rotated = orientation >= 5 && orientation <= 8;
214
+ return rotated
215
+ ? new int[]{options.outHeight, options.outWidth}
216
+ : new int[]{options.outWidth, options.outHeight};
217
+ } catch (IOException | RuntimeException e) {
218
+ return null;
219
+ }
220
+ }
221
+
222
+ private static InputStream open(Context context, FastImageSource source) throws IOException {
223
+ if (source.isBase64Resource()) {
224
+ String data = source.getSource();
225
+ byte[] bytes = Base64.decode(data.substring(data.indexOf(',') + 1), Base64.DEFAULT);
226
+ return new ByteArrayInputStream(bytes);
227
+ }
228
+ Uri uri = source.getUri();
229
+ String path = uri.getPath();
230
+ if ("file".equals(uri.getScheme()) && path != null && path.startsWith("/android_asset/")) {
231
+ return context.getAssets().open(path.substring("/android_asset/".length()));
232
+ }
233
+ InputStream stream = context.getContentResolver().openInputStream(uri);
234
+ if (stream == null) throw new IOException("Can't open " + uri);
235
+ return stream;
236
+ }
237
+ }
@@ -18,6 +18,7 @@ import com.facebook.react.bridge.ReadableMap;
18
18
  import com.facebook.react.bridge.WritableMap;
19
19
  import com.facebook.react.bridge.WritableNativeMap;
20
20
  import com.facebook.react.common.MapBuilder;
21
+ import com.facebook.react.uimanager.LayoutShadowNode;
21
22
  import com.facebook.react.uimanager.SimpleViewManager;
22
23
  import com.facebook.react.bridge.ReactContext;
23
24
  import com.facebook.react.uimanager.ThemedReactContext;
@@ -190,6 +191,18 @@ class FastImageViewManager extends SimpleViewManager<FastImageViewWithUrl> imple
190
191
 
191
192
  }
192
193
 
194
+ // Legacy architecture only; the New Architecture doesn't use shadow nodes.
195
+ @NonNull
196
+ @Override
197
+ public LayoutShadowNode createShadowNodeInstance() {
198
+ return new FastImageShadowNode();
199
+ }
200
+
201
+ @Override
202
+ public void updateExtraData(@NonNull FastImageViewWithUrl view, Object extraData) {
203
+ if (extraData == FastImageShadowNode.ZERO_LAYOUT) view.onZeroLayout();
204
+ }
205
+
193
206
  @Override
194
207
  protected void onAfterUpdateTransaction(@NonNull FastImageViewWithUrl view) {
195
208
  super.onAfterUpdateTransaction(view);
@@ -9,6 +9,7 @@ import android.graphics.drawable.Drawable;
9
9
 
10
10
  import androidx.annotation.Nullable;
11
11
  import androidx.appcompat.widget.AppCompatImageView;
12
+ import androidx.core.view.ViewCompat;
12
13
 
13
14
  import com.bumptech.glide.RequestBuilder;
14
15
  import com.bumptech.glide.RequestManager;
@@ -48,6 +49,14 @@ class FastImageViewWithUrl extends AppCompatImageView {
48
49
  mDefaultSource = source;
49
50
  }
50
51
 
52
+ // Legacy architecture only (see FastImageShadowNode): the view's layout is
53
+ // 0×0 at its parent's origin, which React Native never applies. Lay it out
54
+ // at that size, as the New Architecture does, so Glide stops waiting for a
55
+ // size and loads it (#865).
56
+ void onZeroLayout() {
57
+ if (!ViewCompat.isLaidOut(this)) layout(0, 0, 0, 0);
58
+ }
59
+
51
60
  // Glide crops or fits the bitmap for the scale type when it loads, so a
52
61
  // new resizeMode needs a reload to take effect (#762).
53
62
  public void setResizeMode(ScaleType scaleType) {
@@ -143,6 +152,9 @@ class FastImageViewWithUrl extends AppCompatImageView {
143
152
  }
144
153
 
145
154
  if (requestManager != null) {
155
+ // Records the image's own size when Glide decodes it, for onLoad.
156
+ Object model = imageSource == null ? null : imageSource.getSourceForLoad();
157
+ FastImageSourceSize.Capture capture = FastImageSourceSize.capture(getScaleType(), model);
146
158
  RequestBuilder<Drawable> builder =
147
159
  requestManager
148
160
  // This will make this work for remote and local images. e.g.
@@ -151,14 +163,17 @@ class FastImageViewWithUrl extends AppCompatImageView {
151
163
  // - res:/
152
164
  // - android.resource://
153
165
  // - data:image/png;base64
154
- .load(imageSource == null ? null : imageSource.getSourceForLoad())
166
+ .load(model)
155
167
  .apply(FastImageViewConverter
156
168
  .getOptions(getContext(), imageSource, mSource)
157
169
  .placeholder(mDefaultSource) // show until loaded
158
- .fallback(mDefaultSource)); // null will not be treated as error
170
+ .fallback(mDefaultSource)) // null will not be treated as error
171
+ // What into() would apply for the scale type, with
172
+ // the size capture.
173
+ .apply(FastImageSourceSize.scaleTypeOptions(getScaleType(), capture));
159
174
 
160
175
  if (key != null)
161
- builder.listener(new FastImageRequestListener(key));
176
+ builder.listener(new FastImageRequestListener(key, imageSource));
162
177
 
163
178
  builder.into(this);
164
179
  }
package/dist/index.cjs.js CHANGED
@@ -1,214 +1,153 @@
1
- 'use strict';
2
-
3
- var _extends = require('@babel/runtime/helpers/extends');
4
- var React = require('react');
5
- var reactNative = require('react-native');
6
-
7
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
-
9
- var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends);
10
- var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
11
-
12
- // from ViewStyle so the types also work with older React Native types, where
13
- // it's string.
14
-
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+ //#endregion
23
+ let react = require("react");
24
+ react = __toESM(react);
25
+ let react_native = require("react-native");
26
+ //#region src/index.tsx
15
27
  const resizeMode = {
16
- contain: 'contain',
17
- cover: 'cover',
18
- stretch: 'stretch',
19
- center: 'center'
28
+ contain: "contain",
29
+ cover: "cover",
30
+ stretch: "stretch",
31
+ center: "center"
20
32
  };
21
33
  const priority = {
22
- low: 'low',
23
- normal: 'normal',
24
- high: 'high'
34
+ low: "low",
35
+ normal: "normal",
36
+ high: "high"
25
37
  };
26
38
  const cacheControl = {
27
- // Ignore headers, use uri as cache key, fetch only if not in cache.
28
- immutable: 'immutable',
29
- // Respect http headers, no aggressive caching.
30
- web: 'web',
31
- // Only load from cache.
32
- cacheOnly: 'cacheOnly'
39
+ immutable: "immutable",
40
+ web: "web",
41
+ cacheOnly: "cacheOnly"
42
+ };
43
+ const resolveDefaultSource = (defaultSource) => {
44
+ if (!defaultSource) return null;
45
+ if (react_native.Platform.OS === "android") {
46
+ const resolved = react_native.Image.resolveAssetSource(defaultSource);
47
+ if (resolved) return resolved.uri;
48
+ return null;
49
+ }
50
+ return defaultSource;
33
51
  };
34
-
35
- const resolveDefaultSource = defaultSource => {
36
- if (!defaultSource) {
37
- return null;
38
- }
39
-
40
- if (reactNative.Platform.OS === 'android') {
41
- // Android receives a URI string, and resolves into a Drawable using RN's methods.
42
- const resolved = reactNative.Image.resolveAssetSource(defaultSource);
43
-
44
- if (resolved) {
45
- return resolved.uri;
46
- }
47
-
48
- return null;
49
- } // iOS or other number mapped assets
50
- // In iOS the number is passed, and bridged automatically into a UIImage
51
-
52
-
53
- return defaultSource;
54
- }; // Finds tintColor in a style prop, where the last style that sets it wins, as
55
- // with StyleSheet.flatten, but without flattening (which allocates a merged
56
- // object for an array style on every render).
57
-
58
-
59
52
  function tintColorFromStyle(style) {
60
- if (Array.isArray(style)) {
61
- for (let i = style.length - 1; i >= 0; i--) {
62
- const found = tintColorFromStyle(style[i]);
63
- if (found !== undefined) return found;
64
- }
65
-
66
- return undefined;
67
- }
68
-
69
- if (typeof style === 'number') {
70
- // A registered style from StyleSheet.create on older React Native.
71
- const flattened = reactNative.StyleSheet.flatten(style);
72
- return flattened ? flattened.tintColor : undefined;
73
- }
74
-
75
- return style && typeof style === 'object' ? style.tintColor : undefined;
76
- } // A copy of the source without `cache`.
77
-
78
-
53
+ if (Array.isArray(style)) {
54
+ for (let i = style.length - 1; i >= 0; i--) {
55
+ const found = tintColorFromStyle(style[i]);
56
+ if (found !== void 0) return found;
57
+ }
58
+ return;
59
+ }
60
+ if (typeof style === "number") {
61
+ const flattened = react_native.StyleSheet.flatten(style);
62
+ return flattened ? flattened.tintColor : void 0;
63
+ }
64
+ return style && typeof style === "object" ? style.tintColor : void 0;
65
+ }
79
66
  function withoutCache(source) {
80
- const {
81
- cache: _cache,
82
- ...rest
83
- } = source || {};
84
- return rest;
67
+ const { cache: _cache, ...rest } = source || {};
68
+ return rest;
85
69
  }
86
-
87
- function FastImageBase({
88
- source,
89
- defaultSource,
90
- tintColor,
91
- onLoadStart,
92
- onProgress,
93
- onLoad,
94
- onError,
95
- onLoadEnd,
96
- style,
97
- fallback,
98
- children,
99
- resizeMode = 'cover',
100
- forwardedRef,
101
- // On the wrapper, so the layout is relative to the parent (the image view
102
- // inside always has x and y of 0).
103
- onLayout,
104
- // On the wrapper, which would otherwise still take touches. With
105
- // 'box-none' the image is part of the box, so it ignores touches too.
106
- pointerEvents,
107
- ...viewProps
108
- }) {
109
- // Touchables pass onClick to their child (React Native 0.73+, for
110
- // accessibility clicks). It goes on the wrapper: the image view doesn't
111
- // support it on iOS, which crashed (#1020). Older React Native types don't
112
- // include it.
113
- const {
114
- onClick,
115
- ...props
116
- } = viewProps;
117
- const wrapperProps = {
118
- onLayout,
119
- onClick,
120
- pointerEvents
121
- };
122
- const imageProps = { ...props,
123
- pointerEvents: pointerEvents === 'box-none' ? 'none' : undefined
124
- }; // tintColor can also be set in style, as with React Native's Image. The
125
- // prop wins.
126
-
127
- const resolvedTintColor = tintColor != null ? tintColor : tintColorFromStyle(style);
128
-
129
- if (fallback) {
130
- // Remove `cache`, which React Native's Image doesn't support. A
131
- // require()d source is a number: pass it through (spreading it gave {}).
132
- const cleanedSource = typeof source === 'number' ? source : withoutCache(source);
133
- const resolvedSource = reactNative.Image.resolveAssetSource(cleanedSource);
134
- return /*#__PURE__*/React__default['default'].createElement(reactNative.View, _extends__default['default']({
135
- style: [styles.imageContainer, style]
136
- }, wrapperProps, {
137
- ref: forwardedRef
138
- }), /*#__PURE__*/React__default['default'].createElement(reactNative.Image, _extends__default['default']({}, imageProps, {
139
- style: [styles.fallbackImage, {
140
- tintColor: resolvedTintColor
141
- }],
142
- source: resolvedSource,
143
- defaultSource: defaultSource,
144
- onLoadStart: onLoadStart,
145
- onProgress: onProgress,
146
- onLoad: onLoad,
147
- onError: onError,
148
- onLoadEnd: onLoadEnd,
149
- resizeMode: resizeMode
150
- })), children);
151
- }
152
-
153
- const resolvedSource = reactNative.Image.resolveAssetSource(source);
154
- const resolvedDefaultSource = resolveDefaultSource(defaultSource);
155
- return /*#__PURE__*/React__default['default'].createElement(reactNative.View, _extends__default['default']({
156
- style: [styles.imageContainer, style]
157
- }, wrapperProps, {
158
- ref: forwardedRef
159
- }), /*#__PURE__*/React__default['default'].createElement(FastImageView, _extends__default['default']({}, imageProps, {
160
- tintColor: resolvedTintColor,
161
- style: reactNative.StyleSheet.absoluteFill,
162
- source: resolvedSource,
163
- defaultSource: resolvedDefaultSource,
164
- onFastImageLoadStart: onLoadStart,
165
- onFastImageProgress: onProgress,
166
- onFastImageLoad: onLoad,
167
- onFastImageError: onError,
168
- onFastImageLoadEnd: onLoadEnd,
169
- resizeMode: resizeMode
170
- })), children);
70
+ function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgress, onLoad, onError, onLoadEnd, style, fallback, children, resizeMode = "cover", forwardedRef, onLayout, pointerEvents, ...viewProps }) {
71
+ const { onClick, ...props } = viewProps;
72
+ const wrapperProps = {
73
+ onLayout,
74
+ onClick,
75
+ pointerEvents
76
+ };
77
+ const imageProps = {
78
+ ...props,
79
+ pointerEvents: pointerEvents === "box-none" ? "none" : void 0
80
+ };
81
+ const resolvedTintColor = tintColor != null ? tintColor : tintColorFromStyle(style);
82
+ if (fallback) {
83
+ const cleanedSource = typeof source === "number" ? source : withoutCache(source);
84
+ const resolvedSource = react_native.Image.resolveAssetSource(cleanedSource);
85
+ return /* @__PURE__ */ react.default.createElement(react_native.View, {
86
+ style: [styles.imageContainer, style],
87
+ ...wrapperProps,
88
+ ref: forwardedRef
89
+ }, /* @__PURE__ */ react.default.createElement(react_native.Image, {
90
+ ...imageProps,
91
+ style: [styles.fallbackImage, { tintColor: resolvedTintColor }],
92
+ source: resolvedSource,
93
+ defaultSource,
94
+ onLoadStart,
95
+ onProgress,
96
+ onLoad,
97
+ onError,
98
+ onLoadEnd,
99
+ resizeMode
100
+ }), children);
101
+ }
102
+ const resolvedSource = react_native.Image.resolveAssetSource(source);
103
+ const resolvedDefaultSource = resolveDefaultSource(defaultSource);
104
+ return /* @__PURE__ */ react.default.createElement(react_native.View, {
105
+ style: [styles.imageContainer, style],
106
+ ...wrapperProps,
107
+ ref: forwardedRef
108
+ }, /* @__PURE__ */ react.default.createElement(FastImageView, {
109
+ ...imageProps,
110
+ tintColor: resolvedTintColor,
111
+ style: react_native.StyleSheet.absoluteFill,
112
+ source: resolvedSource,
113
+ defaultSource: resolvedDefaultSource,
114
+ onFastImageLoadStart: onLoadStart,
115
+ onFastImageProgress: onProgress,
116
+ onFastImageLoad: onLoad,
117
+ onFastImageError: onError,
118
+ onFastImageLoadEnd: onLoadEnd,
119
+ resizeMode
120
+ }), children);
171
121
  }
172
-
173
- const FastImageMemo = /*#__PURE__*/React.memo(FastImageBase);
174
- const FastImageComponent = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PURE__*/React__default['default'].createElement(FastImageMemo, _extends__default['default']({
175
- forwardedRef: ref
176
- }, props)));
177
- FastImageComponent.displayName = 'FastImage';
122
+ const FastImageMemo = (0, react.memo)(FastImageBase);
123
+ const FastImageComponent = (0, react.forwardRef)((props, ref) => /* @__PURE__ */ react.default.createElement(FastImageMemo, {
124
+ forwardedRef: ref,
125
+ ...props
126
+ }));
127
+ FastImageComponent.displayName = "FastImage";
178
128
  const FastImage = FastImageComponent;
179
129
  FastImage.resizeMode = resizeMode;
180
130
  FastImage.cacheControl = cacheControl;
181
131
  FastImage.priority = priority;
182
-
183
- FastImage.preload = sources => reactNative.NativeModules.FastImageView.preload(sources);
184
-
185
- FastImage.clearMemoryCache = () => reactNative.NativeModules.FastImageView.clearMemoryCache();
186
-
187
- FastImage.clearDiskCache = () => reactNative.NativeModules.FastImageView.clearDiskCache();
188
-
189
- const styles = reactNative.StyleSheet.create({
190
- // React Native's Image sizes itself from a require()d source's width and
191
- // height unless the style sets them, which would override absoluteFill.
192
- fallbackImage: {
193
- position: 'absolute',
194
- top: 0,
195
- left: 0,
196
- width: '100%',
197
- height: '100%'
198
- },
199
- imageContainer: {
200
- overflow: 'hidden'
201
- }
202
- }); // Types of requireNativeComponent are not correct.
203
-
204
- const FastImageView = reactNative.requireNativeComponent('FastImageView', FastImage, {
205
- nativeOnly: {
206
- onFastImageLoadStart: true,
207
- onFastImageProgress: true,
208
- onFastImageLoad: true,
209
- onFastImageError: true,
210
- onFastImageLoadEnd: true
211
- }
132
+ FastImage.preload = (sources) => react_native.NativeModules.FastImageView.preload(sources);
133
+ FastImage.clearMemoryCache = () => react_native.NativeModules.FastImageView.clearMemoryCache();
134
+ FastImage.clearDiskCache = () => react_native.NativeModules.FastImageView.clearDiskCache();
135
+ const styles = react_native.StyleSheet.create({
136
+ fallbackImage: {
137
+ position: "absolute",
138
+ top: 0,
139
+ left: 0,
140
+ width: "100%",
141
+ height: "100%"
142
+ },
143
+ imageContainer: { overflow: "hidden" }
212
144
  });
213
-
145
+ const FastImageView = (0, react_native.requireNativeComponent)("FastImageView", FastImage, { nativeOnly: {
146
+ onFastImageLoadStart: true,
147
+ onFastImageProgress: true,
148
+ onFastImageLoad: true,
149
+ onFastImageError: true,
150
+ onFastImageLoadEnd: true
151
+ } });
152
+ //#endregion
214
153
  module.exports = FastImage;
package/dist/index.d.ts CHANGED
@@ -1,26 +1,26 @@
1
1
  import React from 'react';
2
2
  import { LayoutChangeEvent, StyleProp, ViewStyle, ImageRequireSource, AccessibilityProps, ViewProps } from 'react-native';
3
- declare type ColorValue = NonNullable<ViewStyle['backgroundColor']>;
4
- export declare type ResizeMode = 'contain' | 'cover' | 'stretch' | 'center';
3
+ type ColorValue = NonNullable<ViewStyle['backgroundColor']>;
4
+ export type ResizeMode = 'contain' | 'cover' | 'stretch' | 'center';
5
5
  declare const resizeMode: {
6
- readonly contain: "contain";
7
- readonly cover: "cover";
8
- readonly stretch: "stretch";
9
- readonly center: "center";
6
+ readonly contain: 'contain';
7
+ readonly cover: 'cover';
8
+ readonly stretch: 'stretch';
9
+ readonly center: 'center';
10
10
  };
11
- export declare type Priority = 'low' | 'normal' | 'high';
11
+ export type Priority = 'low' | 'normal' | 'high';
12
12
  declare const priority: {
13
- readonly low: "low";
14
- readonly normal: "normal";
15
- readonly high: "high";
13
+ readonly low: 'low';
14
+ readonly normal: 'normal';
15
+ readonly high: 'high';
16
16
  };
17
- export declare type Cache = 'immutable' | 'web' | 'cacheOnly';
17
+ export type Cache = 'immutable' | 'web' | 'cacheOnly';
18
18
  declare const cacheControl: {
19
- readonly immutable: "immutable";
20
- readonly web: "web";
21
- readonly cacheOnly: "cacheOnly";
19
+ readonly immutable: 'immutable';
20
+ readonly web: 'web';
21
+ readonly cacheOnly: 'cacheOnly';
22
22
  };
23
- export declare type Source = {
23
+ export type Source = {
24
24
  uri?: string;
25
25
  headers?: {
26
26
  [key: string]: string;
@@ -103,4 +103,3 @@ export interface FastImageStaticProperties {
103
103
  }
104
104
  declare const FastImage: React.ComponentType<FastImageProps> & FastImageStaticProperties;
105
105
  export default FastImage;
106
- //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,207 +1,130 @@
1
- import _extends from '@babel/runtime/helpers/extends';
2
- import React, { forwardRef, memo } from 'react';
3
- import { NativeModules, StyleSheet, requireNativeComponent, Image, View, Platform } from 'react-native';
4
-
5
- // from ViewStyle so the types also work with older React Native types, where
6
- // it's string.
7
-
1
+ import React, { forwardRef, memo } from "react";
2
+ import { Image, NativeModules, Platform, StyleSheet, View, requireNativeComponent } from "react-native";
3
+ //#region src/index.tsx
8
4
  const resizeMode = {
9
- contain: 'contain',
10
- cover: 'cover',
11
- stretch: 'stretch',
12
- center: 'center'
5
+ contain: "contain",
6
+ cover: "cover",
7
+ stretch: "stretch",
8
+ center: "center"
13
9
  };
14
10
  const priority = {
15
- low: 'low',
16
- normal: 'normal',
17
- high: 'high'
11
+ low: "low",
12
+ normal: "normal",
13
+ high: "high"
18
14
  };
19
15
  const cacheControl = {
20
- // Ignore headers, use uri as cache key, fetch only if not in cache.
21
- immutable: 'immutable',
22
- // Respect http headers, no aggressive caching.
23
- web: 'web',
24
- // Only load from cache.
25
- cacheOnly: 'cacheOnly'
16
+ immutable: "immutable",
17
+ web: "web",
18
+ cacheOnly: "cacheOnly"
19
+ };
20
+ const resolveDefaultSource = (defaultSource) => {
21
+ if (!defaultSource) return null;
22
+ if (Platform.OS === "android") {
23
+ const resolved = Image.resolveAssetSource(defaultSource);
24
+ if (resolved) return resolved.uri;
25
+ return null;
26
+ }
27
+ return defaultSource;
26
28
  };
27
-
28
- const resolveDefaultSource = defaultSource => {
29
- if (!defaultSource) {
30
- return null;
31
- }
32
-
33
- if (Platform.OS === 'android') {
34
- // Android receives a URI string, and resolves into a Drawable using RN's methods.
35
- const resolved = Image.resolveAssetSource(defaultSource);
36
-
37
- if (resolved) {
38
- return resolved.uri;
39
- }
40
-
41
- return null;
42
- } // iOS or other number mapped assets
43
- // In iOS the number is passed, and bridged automatically into a UIImage
44
-
45
-
46
- return defaultSource;
47
- }; // Finds tintColor in a style prop, where the last style that sets it wins, as
48
- // with StyleSheet.flatten, but without flattening (which allocates a merged
49
- // object for an array style on every render).
50
-
51
-
52
29
  function tintColorFromStyle(style) {
53
- if (Array.isArray(style)) {
54
- for (let i = style.length - 1; i >= 0; i--) {
55
- const found = tintColorFromStyle(style[i]);
56
- if (found !== undefined) return found;
57
- }
58
-
59
- return undefined;
60
- }
61
-
62
- if (typeof style === 'number') {
63
- // A registered style from StyleSheet.create on older React Native.
64
- const flattened = StyleSheet.flatten(style);
65
- return flattened ? flattened.tintColor : undefined;
66
- }
67
-
68
- return style && typeof style === 'object' ? style.tintColor : undefined;
69
- } // A copy of the source without `cache`.
70
-
71
-
30
+ if (Array.isArray(style)) {
31
+ for (let i = style.length - 1; i >= 0; i--) {
32
+ const found = tintColorFromStyle(style[i]);
33
+ if (found !== void 0) return found;
34
+ }
35
+ return;
36
+ }
37
+ if (typeof style === "number") {
38
+ const flattened = StyleSheet.flatten(style);
39
+ return flattened ? flattened.tintColor : void 0;
40
+ }
41
+ return style && typeof style === "object" ? style.tintColor : void 0;
42
+ }
72
43
  function withoutCache(source) {
73
- const {
74
- cache: _cache,
75
- ...rest
76
- } = source || {};
77
- return rest;
44
+ const { cache: _cache, ...rest } = source || {};
45
+ return rest;
78
46
  }
79
-
80
- function FastImageBase({
81
- source,
82
- defaultSource,
83
- tintColor,
84
- onLoadStart,
85
- onProgress,
86
- onLoad,
87
- onError,
88
- onLoadEnd,
89
- style,
90
- fallback,
91
- children,
92
- resizeMode = 'cover',
93
- forwardedRef,
94
- // On the wrapper, so the layout is relative to the parent (the image view
95
- // inside always has x and y of 0).
96
- onLayout,
97
- // On the wrapper, which would otherwise still take touches. With
98
- // 'box-none' the image is part of the box, so it ignores touches too.
99
- pointerEvents,
100
- ...viewProps
101
- }) {
102
- // Touchables pass onClick to their child (React Native 0.73+, for
103
- // accessibility clicks). It goes on the wrapper: the image view doesn't
104
- // support it on iOS, which crashed (#1020). Older React Native types don't
105
- // include it.
106
- const {
107
- onClick,
108
- ...props
109
- } = viewProps;
110
- const wrapperProps = {
111
- onLayout,
112
- onClick,
113
- pointerEvents
114
- };
115
- const imageProps = { ...props,
116
- pointerEvents: pointerEvents === 'box-none' ? 'none' : undefined
117
- }; // tintColor can also be set in style, as with React Native's Image. The
118
- // prop wins.
119
-
120
- const resolvedTintColor = tintColor != null ? tintColor : tintColorFromStyle(style);
121
-
122
- if (fallback) {
123
- // Remove `cache`, which React Native's Image doesn't support. A
124
- // require()d source is a number: pass it through (spreading it gave {}).
125
- const cleanedSource = typeof source === 'number' ? source : withoutCache(source);
126
- const resolvedSource = Image.resolveAssetSource(cleanedSource);
127
- return /*#__PURE__*/React.createElement(View, _extends({
128
- style: [styles.imageContainer, style]
129
- }, wrapperProps, {
130
- ref: forwardedRef
131
- }), /*#__PURE__*/React.createElement(Image, _extends({}, imageProps, {
132
- style: [styles.fallbackImage, {
133
- tintColor: resolvedTintColor
134
- }],
135
- source: resolvedSource,
136
- defaultSource: defaultSource,
137
- onLoadStart: onLoadStart,
138
- onProgress: onProgress,
139
- onLoad: onLoad,
140
- onError: onError,
141
- onLoadEnd: onLoadEnd,
142
- resizeMode: resizeMode
143
- })), children);
144
- }
145
-
146
- const resolvedSource = Image.resolveAssetSource(source);
147
- const resolvedDefaultSource = resolveDefaultSource(defaultSource);
148
- return /*#__PURE__*/React.createElement(View, _extends({
149
- style: [styles.imageContainer, style]
150
- }, wrapperProps, {
151
- ref: forwardedRef
152
- }), /*#__PURE__*/React.createElement(FastImageView, _extends({}, imageProps, {
153
- tintColor: resolvedTintColor,
154
- style: StyleSheet.absoluteFill,
155
- source: resolvedSource,
156
- defaultSource: resolvedDefaultSource,
157
- onFastImageLoadStart: onLoadStart,
158
- onFastImageProgress: onProgress,
159
- onFastImageLoad: onLoad,
160
- onFastImageError: onError,
161
- onFastImageLoadEnd: onLoadEnd,
162
- resizeMode: resizeMode
163
- })), children);
47
+ function FastImageBase({ source, defaultSource, tintColor, onLoadStart, onProgress, onLoad, onError, onLoadEnd, style, fallback, children, resizeMode = "cover", forwardedRef, onLayout, pointerEvents, ...viewProps }) {
48
+ const { onClick, ...props } = viewProps;
49
+ const wrapperProps = {
50
+ onLayout,
51
+ onClick,
52
+ pointerEvents
53
+ };
54
+ const imageProps = {
55
+ ...props,
56
+ pointerEvents: pointerEvents === "box-none" ? "none" : void 0
57
+ };
58
+ const resolvedTintColor = tintColor != null ? tintColor : tintColorFromStyle(style);
59
+ if (fallback) {
60
+ const cleanedSource = typeof source === "number" ? source : withoutCache(source);
61
+ const resolvedSource = Image.resolveAssetSource(cleanedSource);
62
+ return /* @__PURE__ */ React.createElement(View, {
63
+ style: [styles.imageContainer, style],
64
+ ...wrapperProps,
65
+ ref: forwardedRef
66
+ }, /* @__PURE__ */ React.createElement(Image, {
67
+ ...imageProps,
68
+ style: [styles.fallbackImage, { tintColor: resolvedTintColor }],
69
+ source: resolvedSource,
70
+ defaultSource,
71
+ onLoadStart,
72
+ onProgress,
73
+ onLoad,
74
+ onError,
75
+ onLoadEnd,
76
+ resizeMode
77
+ }), children);
78
+ }
79
+ const resolvedSource = Image.resolveAssetSource(source);
80
+ const resolvedDefaultSource = resolveDefaultSource(defaultSource);
81
+ return /* @__PURE__ */ React.createElement(View, {
82
+ style: [styles.imageContainer, style],
83
+ ...wrapperProps,
84
+ ref: forwardedRef
85
+ }, /* @__PURE__ */ React.createElement(FastImageView, {
86
+ ...imageProps,
87
+ tintColor: resolvedTintColor,
88
+ style: StyleSheet.absoluteFill,
89
+ source: resolvedSource,
90
+ defaultSource: resolvedDefaultSource,
91
+ onFastImageLoadStart: onLoadStart,
92
+ onFastImageProgress: onProgress,
93
+ onFastImageLoad: onLoad,
94
+ onFastImageError: onError,
95
+ onFastImageLoadEnd: onLoadEnd,
96
+ resizeMode
97
+ }), children);
164
98
  }
165
-
166
- const FastImageMemo = /*#__PURE__*/memo(FastImageBase);
167
- const FastImageComponent = /*#__PURE__*/forwardRef((props, ref) => /*#__PURE__*/React.createElement(FastImageMemo, _extends({
168
- forwardedRef: ref
169
- }, props)));
170
- FastImageComponent.displayName = 'FastImage';
99
+ const FastImageMemo = memo(FastImageBase);
100
+ const FastImageComponent = forwardRef((props, ref) => /* @__PURE__ */ React.createElement(FastImageMemo, {
101
+ forwardedRef: ref,
102
+ ...props
103
+ }));
104
+ FastImageComponent.displayName = "FastImage";
171
105
  const FastImage = FastImageComponent;
172
106
  FastImage.resizeMode = resizeMode;
173
107
  FastImage.cacheControl = cacheControl;
174
108
  FastImage.priority = priority;
175
-
176
- FastImage.preload = sources => NativeModules.FastImageView.preload(sources);
177
-
109
+ FastImage.preload = (sources) => NativeModules.FastImageView.preload(sources);
178
110
  FastImage.clearMemoryCache = () => NativeModules.FastImageView.clearMemoryCache();
179
-
180
111
  FastImage.clearDiskCache = () => NativeModules.FastImageView.clearDiskCache();
181
-
182
112
  const styles = StyleSheet.create({
183
- // React Native's Image sizes itself from a require()d source's width and
184
- // height unless the style sets them, which would override absoluteFill.
185
- fallbackImage: {
186
- position: 'absolute',
187
- top: 0,
188
- left: 0,
189
- width: '100%',
190
- height: '100%'
191
- },
192
- imageContainer: {
193
- overflow: 'hidden'
194
- }
195
- }); // Types of requireNativeComponent are not correct.
196
-
197
- const FastImageView = requireNativeComponent('FastImageView', FastImage, {
198
- nativeOnly: {
199
- onFastImageLoadStart: true,
200
- onFastImageProgress: true,
201
- onFastImageLoad: true,
202
- onFastImageError: true,
203
- onFastImageLoadEnd: true
204
- }
113
+ fallbackImage: {
114
+ position: "absolute",
115
+ top: 0,
116
+ left: 0,
117
+ width: "100%",
118
+ height: "100%"
119
+ },
120
+ imageContainer: { overflow: "hidden" }
205
121
  });
206
-
207
- export default FastImage;
122
+ const FastImageView = requireNativeComponent("FastImageView", FastImage, { nativeOnly: {
123
+ onFastImageLoadStart: true,
124
+ onFastImageProgress: true,
125
+ onFastImageLoad: true,
126
+ onFastImageError: true,
127
+ onFastImageLoadEnd: true
128
+ } });
129
+ //#endregion
130
+ export { FastImage as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-fast-image",
3
- "version": "8.6.31",
3
+ "version": "8.6.33",
4
4
  "description": "🚩 FastImage, performant React Native image component.",
5
5
  "keywords": [
6
6
  "cache",
@@ -23,48 +23,43 @@
23
23
  "module": "dist/index.js",
24
24
  "typings": "dist/index.d.ts",
25
25
  "files": [
26
- "android",
27
- "!android/build",
28
- "ios",
29
- "!ios/build",
26
+ "android/build.gradle",
27
+ "android/src/main",
28
+ "ios/FastImage",
29
+ "ios/FastImage.xcodeproj/project.pbxproj",
30
+ "ios/FastImage.xcodeproj/xcshareddata",
30
31
  "dist",
31
32
  "RNFastImage.podspec"
32
33
  ],
33
34
  "scripts": {
34
- "build": "dv-scripts build && cp src/index.js.flow dist/index.js.flow && cp src/index.js.flow dist/index.cjs.js.flow",
35
+ "build": "rm -rf dist && tsc -p tsconfig.build.json && rolldown -c && cp src/index.js.flow dist/index.js.flow && cp src/index.js.flow dist/index.cjs.js.flow",
35
36
  "lint": "oxlint",
36
- "release": "dv-scripts release",
37
- "test": "dv-scripts test",
37
+ "release": "semantic-release",
38
+ "test": "bun test",
39
+ "typecheck": "tsc -p tsconfig.json",
38
40
  "format": "oxfmt",
39
41
  "format:check": "oxfmt --check"
40
42
  },
41
43
  "packageManager": "bun@1.4.2",
42
- "jest": {
43
- "modulePathIgnorePatterns": [
44
- "ReactNativeFastImageExample*",
45
- "ReactNativeFastImageExampleServer*"
46
- ],
47
- "preset": "react-native"
48
- },
49
44
  "resolutions": {
50
- "@jest/create-cache-key-function": "^27"
45
+ "@types/react": "^17.0.14"
51
46
  },
52
47
  "devDependencies": {
53
- "@babel/core": "^7.14.6",
54
- "@babel/runtime": "^7.14.6",
55
- "@types/jest": "^26.0.24",
48
+ "@semantic-release/changelog": "7.0.0",
49
+ "@semantic-release/git": "11.0.1",
50
+ "@types/bun": "^1.4.2",
56
51
  "@types/react": "^17.0.14",
57
52
  "@types/react-native": "^0.69.5",
58
53
  "@types/react-test-renderer": "^17.0.1",
59
- "dv-scripts": "^1.6.0",
60
54
  "maestro-runner": "1.1.27",
61
- "metro-react-native-babel-preset": "^0.66.1",
62
55
  "oxfmt": "0.70.0",
63
56
  "oxlint": "1.85.0",
57
+ "pretty-format": "^30.5.1",
64
58
  "react": "17.0.2",
65
- "react-native": "0.64.2",
66
59
  "react-test-renderer": "17.0.2",
67
- "typescript": "^4.3.5"
60
+ "rolldown": "1.2.11",
61
+ "semantic-release": "25.0.9",
62
+ "typescript": "7.0.2"
68
63
  },
69
64
  "peerDependencies": {
70
65
  "react": "^17 || ^18 || ^19",
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=index.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.tsx"],"names":[],"mappings":""}