@lowentry/react-redux 1.9.1 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/LeRed.jsx CHANGED
@@ -1174,7 +1174,7 @@ export const LeRed = (() =>
1174
1174
  setImageUrl(url + (urlHasQ ? '&' : '?') + (options?.queryParam || 'lowentryretryingimgversion') + '=' + (retries.current++));
1175
1175
  }, (typeof options?.delay === 'function') ? INT_LAX_ANY(options?.delay(retries.current), defaultDelay) : (INT_LAX_ANY(options?.delay, defaultDelay)));
1176
1176
  }
1177
- }, [url]);
1177
+ }, [url, options]);
1178
1178
 
1179
1179
  const onImageLoadErrorIgnored = LeRed.useCallback(() =>
1180
1180
  {
@@ -1188,11 +1188,19 @@ export const LeRed = (() =>
1188
1188
  };
1189
1189
 
1190
1190
  /**
1191
- * Allows you to easily obtain external data.
1191
+ * Allows you to easily convert promises to react hooks.
1192
+ *
1193
+ * The given callable should return promises. The returned promises can be an array, an object, or even a single promise. The returned data of this hook will match the promises it has operated on.
1194
+ *
1195
+ * The given comparingValues can be anything, this is used to detect whether the given promises have changed or not, and so whether new promises have to be generated and executed again.
1192
1196
  */
1193
- LeRed.useExternal = (url, options, hardcodedResponseFunction) =>
1197
+ LeRed.usePromises = (callable, comparingValues) =>
1194
1198
  {
1195
- const paramsRef = LeRed.useRef({url, options});
1199
+ const comparingValuesClone = LeUtils.clone(comparingValues);
1200
+ const comparingValuesRef = LeRed.useRef(comparingValuesClone);
1201
+ const latestComparingValuesRef = LeRed.useRef();
1202
+ latestComparingValuesRef.current = comparingValuesClone;
1203
+
1196
1204
  const [data, setData] = LeRed.useState(null);
1197
1205
  const [loading, setLoading] = LeRed.useState(true);
1198
1206
  const [error, setError] = LeRed.useState(null);
@@ -1203,82 +1211,120 @@ export const LeRed = (() =>
1203
1211
  setData(null);
1204
1212
  setError(null);
1205
1213
 
1206
- let urlStrings = [];
1207
- if(IS_OBJECT(url) || IS_ARRAY(url))
1214
+ try
1208
1215
  {
1209
- LeUtils.each(url, (urlString, key) =>
1216
+ const promises = callable();
1217
+
1218
+ let promisesKeyed = [];
1219
+ if(IS_OBJECT(promises) || IS_ARRAY(promises))
1220
+ {
1221
+ LeUtils.each(promises, (urlString, key) =>
1222
+ {
1223
+ promisesKeyed.push({promise, key});
1224
+ });
1225
+ }
1226
+ else
1227
+ {
1228
+ promisesKeyed.push({promises, key:undefined});
1229
+ }
1230
+
1231
+ let wrappedPromises = [];
1232
+ LeUtils.each(promisesKeyed, ({promise, key}) =>
1210
1233
  {
1211
- urlStrings.push({urlString:STRING(urlString), key});
1234
+ wrappedPromises.push(promise
1235
+ .then(async result => ({result, key})));
1212
1236
  });
1213
- }
1214
- else
1215
- {
1216
- urlStrings.push({urlString:STRING(url), key:undefined});
1217
- }
1218
-
1219
- let fetches = [];
1220
- LeUtils.each(urlStrings, ({urlString, key}) =>
1221
- {
1222
- fetches.push(LeUtils.fetch(urlString, {retries:3, ...(options ?? {})})
1223
- .then(async response =>
1237
+
1238
+ Promise.all(wrappedPromises)
1239
+ .then(resultObjects =>
1224
1240
  {
1225
- const data = await hardcodedResponseFunction(response);
1226
- if(typeof options?.verify === 'function')
1241
+ if(IS_OBJECT(promises))
1227
1242
  {
1228
- await options.verify(data, response);
1243
+ let results = {};
1244
+ LeUtils.each(resultObjects, ({result, key}) =>
1245
+ {
1246
+ results[key] = result;
1247
+ });
1248
+ return results;
1229
1249
  }
1230
- return {data, key};
1231
- }));
1232
- });
1233
-
1234
- Promise.all(fetches)
1235
- .then(values =>
1236
- {
1237
- if(IS_OBJECT(url))
1250
+ else if(IS_ARRAY(promises))
1251
+ {
1252
+ let results = [];
1253
+ LeUtils.each(resultObjects, ({result, key}) =>
1254
+ {
1255
+ results[key] = result;
1256
+ });
1257
+ return results;
1258
+ }
1259
+ return resultObjects.pop()?.result;
1260
+ })
1261
+ .then(results =>
1238
1262
  {
1239
- let result = {};
1240
- LeUtils.each(values, ({data, key}) =>
1263
+ if(!LeUtils.equals(latestComparingValuesRef.current, comparingValuesClone))
1241
1264
  {
1242
- result[key] = data;
1243
- });
1244
- return result;
1245
- }
1246
- else if(IS_ARRAY(url))
1265
+ // canceled
1266
+ return;
1267
+ }
1268
+ comparingValuesRef.current = comparingValuesClone;
1269
+ setLoading(false);
1270
+ setData(results);
1271
+ setError(null);
1272
+ })
1273
+ .catch(error =>
1247
1274
  {
1248
- let result = [];
1249
- LeUtils.each(values, ({data, key}) =>
1275
+ if(!LeUtils.equals(latestComparingValuesRef.current, comparingValuesClone))
1250
1276
  {
1251
- result[key] = data;
1252
- });
1253
- return result;
1254
- }
1255
- return values.pop()?.data;
1256
- })
1257
- .then(data =>
1277
+ // canceled
1278
+ return;
1279
+ }
1280
+ comparingValuesRef.current = comparingValuesClone;
1281
+ setLoading(false);
1282
+ setData(null);
1283
+ setError(LeUtils.purgeErrorMessage(error));
1284
+ });
1285
+
1286
+ return () =>
1258
1287
  {
1259
- paramsRef.current = {url, options};
1260
- setLoading(false);
1261
- setData(data);
1262
- setError(null);
1263
- })
1264
- .catch(error =>
1288
+ LeUtils.each(wrappedPromises, promise =>
1289
+ {
1290
+ try
1291
+ {
1292
+ promise?.cancel?.();
1293
+ }
1294
+ catch(e)
1295
+ {
1296
+ console.error('Failed to cancel the given promise:', e);
1297
+ }
1298
+
1299
+ try
1300
+ {
1301
+ promise?.remove?.();
1302
+ }
1303
+ catch(e)
1304
+ {
1305
+ console.error('Failed to remove the given promise:', e);
1306
+ }
1307
+ });
1308
+ };
1309
+ }
1310
+ catch(error)
1311
+ {
1312
+ LeUtils.setAnimationFrameTimeout(() =>
1265
1313
  {
1266
- paramsRef.current = {url, options};
1314
+ if(!LeUtils.equals(latestComparingValuesRef.current, comparingValuesClone))
1315
+ {
1316
+ // canceled
1317
+ return;
1318
+ }
1319
+ comparingValuesRef.current = comparingValuesClone;
1267
1320
  setLoading(false);
1268
1321
  setData(null);
1269
1322
  setError(LeUtils.purgeErrorMessage(error));
1270
1323
  });
1271
-
1272
- return () =>
1273
- {
1274
- LeUtils.each(fetches, fetch =>
1275
- {
1276
- fetch.remove();
1277
- });
1278
- };
1279
- }, [url, options]);
1324
+ }
1325
+ }, [comparingValuesClone]);
1280
1326
 
1281
- if(!LeUtils.equals(paramsRef.current, {url, options}))
1327
+ if(!LeUtils.equals(comparingValuesRef.current, comparingValuesClone))
1282
1328
  {
1283
1329
  return [null, true, null];
1284
1330
  }
@@ -1286,27 +1332,61 @@ export const LeRed = (() =>
1286
1332
  };
1287
1333
 
1288
1334
  /**
1289
- * Allows you to easily obtain external JSON data.
1335
+ * Allows you to easily obtain external data.
1290
1336
  */
1291
- LeRed.useExternalJson = (url, options) =>
1337
+ LeRed.useExternal = (url, options, responseFunction) =>
1292
1338
  {
1293
- return LeRed.useExternal(url, options, response => response.json());
1339
+ return LeRed.usePromises(() =>
1340
+ {
1341
+ const createFetch = (urlString) => LeUtils.fetch(STRING(urlString), {retries:3, ...(options ?? {})})
1342
+ .then(async response =>
1343
+ {
1344
+ const data = await responseFunction(response);
1345
+ if(typeof options?.verify === 'function')
1346
+ {
1347
+ await options.verify(data, response);
1348
+ }
1349
+ return data;
1350
+ });
1351
+
1352
+ if(IS_OBJECT(url))
1353
+ {
1354
+ let promises = {};
1355
+ LeUtils.each(url, (urlString, key) =>
1356
+ {
1357
+ promises[key] = createFetch(urlString);
1358
+ });
1359
+ return promises;
1360
+ }
1361
+ if(IS_ARRAY(url))
1362
+ {
1363
+ let promises = [];
1364
+ LeUtils.each(url, urlString =>
1365
+ {
1366
+ promises.push(createFetch(urlString));
1367
+ });
1368
+ return promises;
1369
+ }
1370
+ return createFetch(url);
1371
+ }, [url, options, responseFunction]);
1294
1372
  };
1295
1373
 
1296
1374
  /**
1297
- * Allows you to easily obtain external Blob data.
1375
+ * Allows you to easily obtain external JSON data.
1298
1376
  */
1299
- LeRed.useExternalBlob = (url, options) =>
1377
+ LeRed.useExternalJson = (url, options) =>
1300
1378
  {
1301
- return LeRed.useExternal(url, options, response => response.blob());
1379
+ const responseFunction = LeRed.useCallback(response => response.json(), []);
1380
+ return LeRed.useExternal(url, options, responseFunction);
1302
1381
  };
1303
1382
 
1304
1383
  /**
1305
- * Allows you to easily obtain external Uint8Array data.
1384
+ * Allows you to easily obtain external Blob data.
1306
1385
  */
1307
- LeRed.useExternalBytes = (url, options) =>
1386
+ LeRed.useExternalBlob = (url, options) =>
1308
1387
  {
1309
- return LeRed.useExternal(url, options, response => response.bytes());
1388
+ const responseFunction = LeRed.useCallback(response => response.blob(), []);
1389
+ return LeRed.useExternal(url, options, responseFunction);
1310
1390
  };
1311
1391
 
1312
1392
  /**
@@ -1314,7 +1394,8 @@ export const LeRed = (() =>
1314
1394
  */
1315
1395
  LeRed.useExternalArrayBuffer = (url, options) =>
1316
1396
  {
1317
- return LeRed.useExternal(url, options, response => response.arrayBuffer());
1397
+ const responseFunction = LeRed.useCallback(response => response.arrayBuffer(), []);
1398
+ return LeRed.useExternal(url, options, responseFunction);
1318
1399
  };
1319
1400
 
1320
1401
  /**
@@ -1322,7 +1403,8 @@ export const LeRed = (() =>
1322
1403
  */
1323
1404
  LeRed.useExternalString = (url, options) =>
1324
1405
  {
1325
- return LeRed.useExternal(url, options, response => response.text());
1406
+ const responseFunction = LeRed.useCallback(response => response.text(), []);
1407
+ return LeRed.useExternal(url, options, responseFunction);
1326
1408
  };
1327
1409
 
1328
1410
  /**
@@ -1330,7 +1412,8 @@ export const LeRed = (() =>
1330
1412
  */
1331
1413
  LeRed.useExternalFormData = (url, options) =>
1332
1414
  {
1333
- return LeRed.useExternal(url, options, response => response.formData());
1415
+ const responseFunction = LeRed.useCallback(response => response.formData(), []);
1416
+ return LeRed.useExternal(url, options, responseFunction);
1334
1417
  };
1335
1418
 
1336
1419