@talismn/util 0.5.2 → 0.5.5
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.
@@ -0,0 +1,45 @@
|
|
1
|
+
import { Observable } from "rxjs";
|
2
|
+
export type QueryStatus = "loading" | "loaded" | "error";
|
3
|
+
export type QueryResult<T, S extends QueryStatus = "loading" | "loaded" | "error"> = S extends "loading" ? {
|
4
|
+
status: "loading";
|
5
|
+
data: T | undefined;
|
6
|
+
error: undefined;
|
7
|
+
} : S extends "loaded" ? {
|
8
|
+
status: "loaded";
|
9
|
+
data: T;
|
10
|
+
error: undefined;
|
11
|
+
} : {
|
12
|
+
status: "error";
|
13
|
+
data: undefined;
|
14
|
+
error: unknown;
|
15
|
+
};
|
16
|
+
type QueryOptions<Output, Args> = {
|
17
|
+
namespace: string;
|
18
|
+
args: Args;
|
19
|
+
queryFn: (args: Args, signal: AbortSignal) => Promise<Output>;
|
20
|
+
defaultValue?: Output;
|
21
|
+
refreshInterval?: number;
|
22
|
+
serializer?: (args: Args) => string;
|
23
|
+
};
|
24
|
+
/**
|
25
|
+
* Creates a shared observable for executing queries with caching, loading states, and automatic refresh capabilities.
|
26
|
+
*
|
27
|
+
* @example
|
28
|
+
* ```typescript
|
29
|
+
* const userQuery$ = getQuery$({
|
30
|
+
* namespace: 'users',
|
31
|
+
* args: { userId: 123 },
|
32
|
+
* queryFn: async ({ userId }) => fetchUser(userId),
|
33
|
+
* defaultValue: null,
|
34
|
+
* refreshInterval: 30000
|
35
|
+
* });
|
36
|
+
*
|
37
|
+
* userQuery$.subscribe(result => {
|
38
|
+
* if (result.status === 'loaded') {
|
39
|
+
* console.log(result.data);
|
40
|
+
* }
|
41
|
+
* });
|
42
|
+
* ```
|
43
|
+
*/
|
44
|
+
export declare const getQuery$: <Output, Args>({ namespace, args, queryFn, defaultValue, refreshInterval, serializer, }: QueryOptions<Output, Args>) => Observable<QueryResult<Output>>;
|
45
|
+
export {};
|
@@ -3,6 +3,7 @@
|
|
3
3
|
var tailwindMerge = require('tailwind-merge');
|
4
4
|
var rxjs = require('rxjs');
|
5
5
|
var BigNumber = require('bignumber.js');
|
6
|
+
var lodashEs = require('lodash-es');
|
6
7
|
|
7
8
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
8
9
|
|
@@ -387,6 +388,82 @@ const getGenericErrorMessage = error => {
|
|
387
388
|
return String(error) || "Unknown error";
|
388
389
|
};
|
389
390
|
|
391
|
+
/**
|
392
|
+
* Creates a shared observable for executing queries with caching, loading states, and automatic refresh capabilities.
|
393
|
+
*
|
394
|
+
* @example
|
395
|
+
* ```typescript
|
396
|
+
* const userQuery$ = getQuery$({
|
397
|
+
* namespace: 'users',
|
398
|
+
* args: { userId: 123 },
|
399
|
+
* queryFn: async ({ userId }) => fetchUser(userId),
|
400
|
+
* defaultValue: null,
|
401
|
+
* refreshInterval: 30000
|
402
|
+
* });
|
403
|
+
*
|
404
|
+
* userQuery$.subscribe(result => {
|
405
|
+
* if (result.status === 'loaded') {
|
406
|
+
* console.log(result.data);
|
407
|
+
* }
|
408
|
+
* });
|
409
|
+
* ```
|
410
|
+
*/
|
411
|
+
const getQuery$ = ({
|
412
|
+
namespace,
|
413
|
+
args,
|
414
|
+
queryFn,
|
415
|
+
defaultValue,
|
416
|
+
refreshInterval,
|
417
|
+
serializer = args => JSON.stringify(args)
|
418
|
+
}) => {
|
419
|
+
return getSharedObservable(namespace, args, () => new rxjs.Observable(subscriber => {
|
420
|
+
const controller = new AbortController();
|
421
|
+
const result = new rxjs.BehaviorSubject({
|
422
|
+
status: "loading",
|
423
|
+
data: defaultValue,
|
424
|
+
error: undefined
|
425
|
+
});
|
426
|
+
|
427
|
+
// result subscription
|
428
|
+
const sub = result.pipe(rxjs.distinctUntilChanged(lodashEs.isEqual)).subscribe(subscriber);
|
429
|
+
|
430
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
431
|
+
let timeout = null;
|
432
|
+
|
433
|
+
// fetch result subscription
|
434
|
+
const run = () => {
|
435
|
+
if (controller.signal.aborted) return;
|
436
|
+
queryFn(args, controller.signal).then(data => {
|
437
|
+
if (controller.signal.aborted) return;
|
438
|
+
result.next({
|
439
|
+
status: "loaded",
|
440
|
+
data,
|
441
|
+
error: undefined
|
442
|
+
});
|
443
|
+
}).catch(error => {
|
444
|
+
if (controller.signal.aborted) return;
|
445
|
+
result.next({
|
446
|
+
status: "error",
|
447
|
+
data: undefined,
|
448
|
+
error
|
449
|
+
});
|
450
|
+
}).finally(() => {
|
451
|
+
if (controller.signal.aborted) return;
|
452
|
+
if (refreshInterval) timeout = setTimeout(run, refreshInterval);
|
453
|
+
});
|
454
|
+
};
|
455
|
+
run();
|
456
|
+
return () => {
|
457
|
+
sub.unsubscribe();
|
458
|
+
if (timeout) clearTimeout(timeout);
|
459
|
+
controller.abort(new Error("getQuery$ unsubscribed"));
|
460
|
+
};
|
461
|
+
}).pipe(rxjs.shareReplay({
|
462
|
+
refCount: true,
|
463
|
+
bufferSize: 1
|
464
|
+
})), serializer);
|
465
|
+
};
|
466
|
+
|
390
467
|
exports.BigMath = BigMath;
|
391
468
|
exports.Deferred = Deferred;
|
392
469
|
exports.MAX_DECIMALS_FORMAT = MAX_DECIMALS_FORMAT;
|
@@ -398,6 +475,7 @@ exports.firstThenDebounce = firstThenDebounce;
|
|
398
475
|
exports.formatDecimals = formatDecimals;
|
399
476
|
exports.formatPrice = formatPrice;
|
400
477
|
exports.getLoadable$ = getLoadable$;
|
478
|
+
exports.getQuery$ = getQuery$;
|
401
479
|
exports.getSharedObservable = getSharedObservable;
|
402
480
|
exports.hasOwnProperty = hasOwnProperty;
|
403
481
|
exports.isAbortError = isAbortError;
|
@@ -3,6 +3,7 @@
|
|
3
3
|
var tailwindMerge = require('tailwind-merge');
|
4
4
|
var rxjs = require('rxjs');
|
5
5
|
var BigNumber = require('bignumber.js');
|
6
|
+
var lodashEs = require('lodash-es');
|
6
7
|
|
7
8
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
8
9
|
|
@@ -387,6 +388,82 @@ const getGenericErrorMessage = error => {
|
|
387
388
|
return String(error) || "Unknown error";
|
388
389
|
};
|
389
390
|
|
391
|
+
/**
|
392
|
+
* Creates a shared observable for executing queries with caching, loading states, and automatic refresh capabilities.
|
393
|
+
*
|
394
|
+
* @example
|
395
|
+
* ```typescript
|
396
|
+
* const userQuery$ = getQuery$({
|
397
|
+
* namespace: 'users',
|
398
|
+
* args: { userId: 123 },
|
399
|
+
* queryFn: async ({ userId }) => fetchUser(userId),
|
400
|
+
* defaultValue: null,
|
401
|
+
* refreshInterval: 30000
|
402
|
+
* });
|
403
|
+
*
|
404
|
+
* userQuery$.subscribe(result => {
|
405
|
+
* if (result.status === 'loaded') {
|
406
|
+
* console.log(result.data);
|
407
|
+
* }
|
408
|
+
* });
|
409
|
+
* ```
|
410
|
+
*/
|
411
|
+
const getQuery$ = ({
|
412
|
+
namespace,
|
413
|
+
args,
|
414
|
+
queryFn,
|
415
|
+
defaultValue,
|
416
|
+
refreshInterval,
|
417
|
+
serializer = args => JSON.stringify(args)
|
418
|
+
}) => {
|
419
|
+
return getSharedObservable(namespace, args, () => new rxjs.Observable(subscriber => {
|
420
|
+
const controller = new AbortController();
|
421
|
+
const result = new rxjs.BehaviorSubject({
|
422
|
+
status: "loading",
|
423
|
+
data: defaultValue,
|
424
|
+
error: undefined
|
425
|
+
});
|
426
|
+
|
427
|
+
// result subscription
|
428
|
+
const sub = result.pipe(rxjs.distinctUntilChanged(lodashEs.isEqual)).subscribe(subscriber);
|
429
|
+
|
430
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
431
|
+
let timeout = null;
|
432
|
+
|
433
|
+
// fetch result subscription
|
434
|
+
const run = () => {
|
435
|
+
if (controller.signal.aborted) return;
|
436
|
+
queryFn(args, controller.signal).then(data => {
|
437
|
+
if (controller.signal.aborted) return;
|
438
|
+
result.next({
|
439
|
+
status: "loaded",
|
440
|
+
data,
|
441
|
+
error: undefined
|
442
|
+
});
|
443
|
+
}).catch(error => {
|
444
|
+
if (controller.signal.aborted) return;
|
445
|
+
result.next({
|
446
|
+
status: "error",
|
447
|
+
data: undefined,
|
448
|
+
error
|
449
|
+
});
|
450
|
+
}).finally(() => {
|
451
|
+
if (controller.signal.aborted) return;
|
452
|
+
if (refreshInterval) timeout = setTimeout(run, refreshInterval);
|
453
|
+
});
|
454
|
+
};
|
455
|
+
run();
|
456
|
+
return () => {
|
457
|
+
sub.unsubscribe();
|
458
|
+
if (timeout) clearTimeout(timeout);
|
459
|
+
controller.abort(new Error("getQuery$ unsubscribed"));
|
460
|
+
};
|
461
|
+
}).pipe(rxjs.shareReplay({
|
462
|
+
refCount: true,
|
463
|
+
bufferSize: 1
|
464
|
+
})), serializer);
|
465
|
+
};
|
466
|
+
|
390
467
|
exports.BigMath = BigMath;
|
391
468
|
exports.Deferred = Deferred;
|
392
469
|
exports.MAX_DECIMALS_FORMAT = MAX_DECIMALS_FORMAT;
|
@@ -398,6 +475,7 @@ exports.firstThenDebounce = firstThenDebounce;
|
|
398
475
|
exports.formatDecimals = formatDecimals;
|
399
476
|
exports.formatPrice = formatPrice;
|
400
477
|
exports.getLoadable$ = getLoadable$;
|
478
|
+
exports.getQuery$ = getQuery$;
|
401
479
|
exports.getSharedObservable = getSharedObservable;
|
402
480
|
exports.hasOwnProperty = hasOwnProperty;
|
403
481
|
exports.isAbortError = isAbortError;
|
package/dist/talismn-util.esm.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import { twMerge } from 'tailwind-merge';
|
2
|
-
import { concat, take, skip, debounceTime, shareReplay, Subject, tap, ReplaySubject, timer, switchMap, from, startWith, map, catchError, of } from 'rxjs';
|
2
|
+
import { concat, take, skip, debounceTime, shareReplay, Subject, tap, ReplaySubject, timer, switchMap, from, startWith, map, catchError, of, Observable, BehaviorSubject, distinctUntilChanged } from 'rxjs';
|
3
3
|
import BigNumber from 'bignumber.js';
|
4
|
+
import { isEqual } from 'lodash-es';
|
4
5
|
|
5
6
|
const addTrailingSlash = url => {
|
6
7
|
if (url.endsWith("/")) {
|
@@ -381,4 +382,80 @@ const getGenericErrorMessage = error => {
|
|
381
382
|
return String(error) || "Unknown error";
|
382
383
|
};
|
383
384
|
|
384
|
-
|
385
|
+
/**
|
386
|
+
* Creates a shared observable for executing queries with caching, loading states, and automatic refresh capabilities.
|
387
|
+
*
|
388
|
+
* @example
|
389
|
+
* ```typescript
|
390
|
+
* const userQuery$ = getQuery$({
|
391
|
+
* namespace: 'users',
|
392
|
+
* args: { userId: 123 },
|
393
|
+
* queryFn: async ({ userId }) => fetchUser(userId),
|
394
|
+
* defaultValue: null,
|
395
|
+
* refreshInterval: 30000
|
396
|
+
* });
|
397
|
+
*
|
398
|
+
* userQuery$.subscribe(result => {
|
399
|
+
* if (result.status === 'loaded') {
|
400
|
+
* console.log(result.data);
|
401
|
+
* }
|
402
|
+
* });
|
403
|
+
* ```
|
404
|
+
*/
|
405
|
+
const getQuery$ = ({
|
406
|
+
namespace,
|
407
|
+
args,
|
408
|
+
queryFn,
|
409
|
+
defaultValue,
|
410
|
+
refreshInterval,
|
411
|
+
serializer = args => JSON.stringify(args)
|
412
|
+
}) => {
|
413
|
+
return getSharedObservable(namespace, args, () => new Observable(subscriber => {
|
414
|
+
const controller = new AbortController();
|
415
|
+
const result = new BehaviorSubject({
|
416
|
+
status: "loading",
|
417
|
+
data: defaultValue,
|
418
|
+
error: undefined
|
419
|
+
});
|
420
|
+
|
421
|
+
// result subscription
|
422
|
+
const sub = result.pipe(distinctUntilChanged(isEqual)).subscribe(subscriber);
|
423
|
+
|
424
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
425
|
+
let timeout = null;
|
426
|
+
|
427
|
+
// fetch result subscription
|
428
|
+
const run = () => {
|
429
|
+
if (controller.signal.aborted) return;
|
430
|
+
queryFn(args, controller.signal).then(data => {
|
431
|
+
if (controller.signal.aborted) return;
|
432
|
+
result.next({
|
433
|
+
status: "loaded",
|
434
|
+
data,
|
435
|
+
error: undefined
|
436
|
+
});
|
437
|
+
}).catch(error => {
|
438
|
+
if (controller.signal.aborted) return;
|
439
|
+
result.next({
|
440
|
+
status: "error",
|
441
|
+
data: undefined,
|
442
|
+
error
|
443
|
+
});
|
444
|
+
}).finally(() => {
|
445
|
+
if (controller.signal.aborted) return;
|
446
|
+
if (refreshInterval) timeout = setTimeout(run, refreshInterval);
|
447
|
+
});
|
448
|
+
};
|
449
|
+
run();
|
450
|
+
return () => {
|
451
|
+
sub.unsubscribe();
|
452
|
+
if (timeout) clearTimeout(timeout);
|
453
|
+
controller.abort(new Error("getQuery$ unsubscribed"));
|
454
|
+
};
|
455
|
+
}).pipe(shareReplay({
|
456
|
+
refCount: true,
|
457
|
+
bufferSize: 1
|
458
|
+
})), serializer);
|
459
|
+
};
|
460
|
+
|
461
|
+
export { BigMath, Deferred, MAX_DECIMALS_FORMAT, REGEX_HEX_STRING, addTrailingSlash, classNames, cn, firstThenDebounce, formatDecimals, formatPrice, getLoadable$, getQuery$, getSharedObservable, hasOwnProperty, isAbortError, isArrayOf, isAscii, isBigInt, isBooleanTrue, isHexString, isNotNil, isPromise, isSubject, isTruthy, keepAlive, planckToTokens, replaySubjectFrom, sleep, splitSubject, throwAfter, tokensToPlanck, validateHexString };
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@talismn/util",
|
3
|
-
"version": "0.5.
|
3
|
+
"version": "0.5.5",
|
4
4
|
"author": "Talisman",
|
5
5
|
"homepage": "https://talisman.xyz",
|
6
6
|
"license": "GPL-3.0-or-later",
|
@@ -23,16 +23,18 @@
|
|
23
23
|
"dependencies": {
|
24
24
|
"bignumber.js": "^9.1.2",
|
25
25
|
"rxjs": "^7.8.1",
|
26
|
-
"tailwind-merge": "^2.5.4"
|
26
|
+
"tailwind-merge": "^2.5.4",
|
27
|
+
"lodash-es": "4.17.21"
|
27
28
|
},
|
28
29
|
"devDependencies": {
|
29
30
|
"@types/jest": "^29.5.14",
|
31
|
+
"@types/lodash-es": "4.17.12",
|
30
32
|
"eslint": "^8.57.1",
|
31
33
|
"jest": "^29.7.0",
|
32
34
|
"ts-jest": "^29.2.5",
|
33
35
|
"typescript": "^5.6.3",
|
34
36
|
"@talismn/eslint-config": "0.0.3",
|
35
|
-
"@talismn/tsconfig": "0.0.
|
37
|
+
"@talismn/tsconfig": "0.0.3"
|
36
38
|
},
|
37
39
|
"peerDependencies": {
|
38
40
|
"rxjs": ">= 7.8.1"
|