@intrig/next 1.0.7 → 1.0.11
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/eslint.config.cjs +19 -0
- package/jest.config.ts +10 -0
- package/package.json +3 -6
- package/project.json +20 -0
- package/src/extra/{index.d.ts → index.ts} +2 -2
- package/src/extra/useAsNetworkState.ts +53 -0
- package/src/extra/{useAsPromise.d.ts → useAsPromise.ts} +58 -7
- package/src/extra/useLocalReducer.ts +61 -0
- package/src/extra/{useResolvedCachedValue.d.ts → useResolvedCachedValue.ts} +39 -7
- package/src/extra/{useResolvedValue.d.ts → useResolvedValue.ts} +39 -7
- package/src/extra.ts +190 -0
- package/src/{index.d.ts → index.ts} +1 -1
- package/src/intrig-context.ts +64 -0
- package/src/intrig-layout.tsx +18 -0
- package/src/intrig-middleware.spec.ts +9 -0
- package/src/intrig-middleware.ts +31 -0
- package/src/intrig-provider.tsx +454 -0
- package/src/logger.ts +13 -0
- package/src/media-type-utils.ts +184 -0
- package/src/{network-state.d.ts → network-state.tsx} +174 -92
- package/tsconfig.json +28 -0
- package/tsconfig.lib.json +10 -0
- package/tsconfig.spec.json +14 -0
- package/src/extra/index.js +0 -5
- package/src/extra/index.js.map +0 -1
- package/src/extra/useAsNetworkState.d.ts +0 -13
- package/src/extra/useAsNetworkState.js +0 -41
- package/src/extra/useAsNetworkState.js.map +0 -1
- package/src/extra/useAsPromise.js +0 -30
- package/src/extra/useAsPromise.js.map +0 -1
- package/src/extra/useLocalReducer.d.ts +0 -6
- package/src/extra/useLocalReducer.js +0 -50
- package/src/extra/useLocalReducer.js.map +0 -1
- package/src/extra/useResolvedCachedValue.js +0 -15
- package/src/extra/useResolvedCachedValue.js.map +0 -1
- package/src/extra/useResolvedValue.js +0 -17
- package/src/extra/useResolvedValue.js.map +0 -1
- package/src/extra.d.ts +0 -52
- package/src/extra.js +0 -92
- package/src/extra.js.map +0 -1
- package/src/index.js +0 -4
- package/src/index.js.map +0 -1
- package/src/intrig-context.d.ts +0 -42
- package/src/intrig-context.js +0 -21
- package/src/intrig-context.js.map +0 -1
- package/src/intrig-middleware.d.ts +0 -2
- package/src/intrig-middleware.js +0 -24
- package/src/intrig-middleware.js.map +0 -1
- package/src/intrig-provider.d.ts +0 -102
- package/src/intrig-provider.js +0 -296
- package/src/intrig-provider.js.map +0 -1
- package/src/logger.d.ts +0 -7
- package/src/logger.js +0 -11
- package/src/logger.js.map +0 -1
- package/src/media-type-utils.d.ts +0 -4
- package/src/media-type-utils.js +0 -121
- package/src/media-type-utils.js.map +0 -1
- package/src/network-state.js +0 -185
- package/src/network-state.js.map +0 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const baseConfig = require('../../eslint.base.config.js');
|
|
2
|
+
|
|
3
|
+
module.exports = [
|
|
4
|
+
...baseConfig,
|
|
5
|
+
{
|
|
6
|
+
files: ['**/*.json'],
|
|
7
|
+
rules: {
|
|
8
|
+
'@nx/dependency-checks': [
|
|
9
|
+
'error',
|
|
10
|
+
{
|
|
11
|
+
ignoredFiles: ['{projectRoot}/eslint.config.{js,cjs,mjs}'],
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
languageOptions: {
|
|
16
|
+
parser: require('jsonc-eslint-parser'),
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
];
|
package/jest.config.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
displayName: '@intrig/client-next',
|
|
3
|
+
preset: '../../jest.preset.js',
|
|
4
|
+
testEnvironment: 'node',
|
|
5
|
+
transform: {
|
|
6
|
+
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
|
|
7
|
+
},
|
|
8
|
+
moduleFileExtensions: ['ts', 'js', 'html'],
|
|
9
|
+
coverageDirectory: '../../coverage/lib/client-next',
|
|
10
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intrig/next",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Placeholder module for autogenerated intrig next.js boilerplate",
|
|
6
6
|
"dependencies": {
|
|
@@ -35,8 +35,5 @@
|
|
|
35
35
|
"import": "./src/*.js",
|
|
36
36
|
"types": "./src/*.d.ts"
|
|
37
37
|
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
"main": "./src/index.js",
|
|
41
|
-
"types": "./src/index.d.ts"
|
|
42
|
-
}
|
|
38
|
+
}
|
|
39
|
+
}
|
package/project.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "client-next",
|
|
3
|
+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
+
"sourceRoot": "lib/client-next/src",
|
|
5
|
+
"projectType": "library",
|
|
6
|
+
"tags": [],
|
|
7
|
+
"targets": {
|
|
8
|
+
"build": {
|
|
9
|
+
"executor": "@nx/js:tsc",
|
|
10
|
+
"outputs": ["{options.outputPath}"],
|
|
11
|
+
"options": {
|
|
12
|
+
"outputPath": "dist/lib/client-next",
|
|
13
|
+
"tsConfig": "lib/client-next/tsconfig.lib.json",
|
|
14
|
+
"packageJson": "lib/client-next/package.json",
|
|
15
|
+
"main": "lib/client-next/src/index.ts",
|
|
16
|
+
"assets": ["lib/client-next/*.md"]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { error, init, NetworkState, pending, success } from '@intrig/next/network-state';
|
|
2
|
+
import { useCallback, useId, useMemo } from 'react';
|
|
3
|
+
import { useIntrigContext } from '@intrig/next/intrig-context';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A custom hook that integrates a promise-based operation with a network state management system.
|
|
7
|
+
* Tracks the network state (e.g., pending, success, error) for a given asynchronous function.
|
|
8
|
+
*
|
|
9
|
+
* @param fn A promise-based function that performs an asynchronous operation.
|
|
10
|
+
* @param key An optional string key to identify the network state uniquely. Defaults to 'default'.
|
|
11
|
+
* @return A tuple containing:
|
|
12
|
+
* 1. The current network state of the operation.
|
|
13
|
+
* 2. A function to execute the provided asynchronous operation.
|
|
14
|
+
* 3. A function to reset the network state back to the initial state.
|
|
15
|
+
*/
|
|
16
|
+
export function useAsNetworkState<T, F extends ((...args: any) => Promise<T>)>(fn: F, key: string = 'default'): [NetworkState<T>, (...params: Parameters<F>) => void, () => void] {
|
|
17
|
+
let id = useId();
|
|
18
|
+
|
|
19
|
+
let context = useIntrigContext();
|
|
20
|
+
|
|
21
|
+
const networkState = useMemo(() => {
|
|
22
|
+
return context.state?.[`promiseState:${id}:${key}}`] ?? init()
|
|
23
|
+
}, [context.state?.[`promiseState:${id}:${key}}`]]);
|
|
24
|
+
|
|
25
|
+
const dispatch = useCallback(
|
|
26
|
+
(state: NetworkState<T>) => {
|
|
27
|
+
context.dispatch({ key, operation: id, source: 'promiseState', state });
|
|
28
|
+
},
|
|
29
|
+
[key, context.dispatch]
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const execute = useCallback((...args: Parameters<F>) => {
|
|
33
|
+
dispatch(pending())
|
|
34
|
+
return fn(...args).then(
|
|
35
|
+
(data) => {
|
|
36
|
+
dispatch(success(data))
|
|
37
|
+
},
|
|
38
|
+
(e) => {
|
|
39
|
+
dispatch(error(e))
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
}, []);
|
|
43
|
+
|
|
44
|
+
const clear = useCallback(() => {
|
|
45
|
+
dispatch(init())
|
|
46
|
+
}, []);
|
|
47
|
+
|
|
48
|
+
return [
|
|
49
|
+
networkState,
|
|
50
|
+
execute,
|
|
51
|
+
clear
|
|
52
|
+
]
|
|
53
|
+
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BinaryFunctionHook,
|
|
3
|
+
BinaryHookOptions,
|
|
4
|
+
BinaryProduceHook,
|
|
5
|
+
ConstantHook, IntrigHook, IntrigHookOptions, isError, isSuccess, isValidationError, UnaryFunctionHook,
|
|
6
|
+
UnaryHookOptions,
|
|
7
|
+
UnaryProduceHook,
|
|
8
|
+
UnitHook,
|
|
9
|
+
UnitHookOptions
|
|
10
|
+
} from '@intrig/next/network-state';
|
|
11
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
12
|
+
|
|
2
13
|
/**
|
|
3
14
|
* Transforms a unit hook into a promise, enabling asynchronous usage of the hook's lifecycle or events.
|
|
4
15
|
*
|
|
@@ -7,7 +18,8 @@ import { BinaryFunctionHook, BinaryHookOptions, BinaryProduceHook, ConstantHook,
|
|
|
7
18
|
* @return {[() => Promise<never>, () => void]} A tuple containing a function that returns a promise resolving with the hook's completion
|
|
8
19
|
* result or rejecting with an error, and a function to clean up the hook's resources when no longer needed.
|
|
9
20
|
*/
|
|
10
|
-
export
|
|
21
|
+
export function useAsPromise<E>(hook: UnitHook<E>, options: UnitHookOptions): [() => Promise<never>, () => void];
|
|
22
|
+
|
|
11
23
|
/**
|
|
12
24
|
* Converts a constant hook into a promise-based interface that can be invoked and reset.
|
|
13
25
|
*
|
|
@@ -15,7 +27,8 @@ export declare function useAsPromise<E>(hook: UnitHook<E>, options: UnitHookOpti
|
|
|
15
27
|
* @param {UnitHookOptions} options - Configuration options for the hook behavior.
|
|
16
28
|
* @return {[() => Promise<T>, () => void]} A tuple where the first element is a function that returns a promise resolving with the hook value, and the second element is a reset function.
|
|
17
29
|
*/
|
|
18
|
-
export
|
|
30
|
+
export function useAsPromise<T, E>(hook: ConstantHook<T, E>, options: UnitHookOptions): [() => Promise<T>, () => void];
|
|
31
|
+
|
|
19
32
|
/**
|
|
20
33
|
* Wraps the provided hook function to return a promise-based API, offering more flexibility
|
|
21
34
|
* in asynchronous operations. This utility converts the hook into a callable function that
|
|
@@ -27,7 +40,8 @@ export declare function useAsPromise<T, E>(hook: ConstantHook<T, E>, options: Un
|
|
|
27
40
|
* is a function that takes the hook's parameters and returns a `Promise`, and the second element
|
|
28
41
|
* is a cleanup function for resource management.
|
|
29
42
|
*/
|
|
30
|
-
export
|
|
43
|
+
export function useAsPromise<P, E>(hook: UnaryProduceHook<P, E>, options?: UnaryHookOptions<P>): [(params: P) => Promise<never>, () => void];
|
|
44
|
+
|
|
31
45
|
/**
|
|
32
46
|
* Allows the usage of a hook's asynchronous behavior as a Promise.
|
|
33
47
|
*
|
|
@@ -37,7 +51,8 @@ export declare function useAsPromise<P, E>(hook: UnaryProduceHook<P, E>, options
|
|
|
37
51
|
* - A function that accepts parameters and returns a Promise resolving to the hook's result.
|
|
38
52
|
* - A cleanup function to properly dispose of the hook when no longer needed.
|
|
39
53
|
*/
|
|
40
|
-
export
|
|
54
|
+
export function useAsPromise<P, T, E>( hook: UnaryFunctionHook<P, T, E>, options?: UnaryHookOptions<P>): [(params: P) => Promise<T>, () => void];
|
|
55
|
+
|
|
41
56
|
/**
|
|
42
57
|
* Converts a binary hook into a promise-based function, allowing the hook to be used asynchronously.
|
|
43
58
|
*
|
|
@@ -48,7 +63,8 @@ export declare function useAsPromise<P, T, E>(hook: UnaryFunctionHook<P, T, E>,
|
|
|
48
63
|
* @param {BinaryHookOptions<P, B>} [options] Optional configuration for the binary hook.
|
|
49
64
|
* @return {[(body: B, params: P) => Promise<never>, () => void]} A tuple where the first element is a function that returns a promise and the second is a cleanup function.
|
|
50
65
|
*/
|
|
51
|
-
export
|
|
66
|
+
export function useAsPromise<P, B, E>(hook: BinaryProduceHook<P, B, E>, options?: BinaryHookOptions<P, B>): [(body: B, params: P) => Promise<never>, () => void];
|
|
67
|
+
|
|
52
68
|
/**
|
|
53
69
|
* Wraps a binary function hook into a promise-based interface.
|
|
54
70
|
*
|
|
@@ -56,4 +72,39 @@ export declare function useAsPromise<P, B, E>(hook: BinaryProduceHook<P, B, E>,
|
|
|
56
72
|
* @param {BinaryHookOptions<P, B>} [options] Optional configuration options for the hook.
|
|
57
73
|
* @return {[function(B, P): Promise<T>, function(): void]} Returns a tuple containing a function that invokes the hook and returns a promise, and a cleanup function to dispose of the hook's resources.
|
|
58
74
|
*/
|
|
59
|
-
export
|
|
75
|
+
export function useAsPromise<P, B, T, E>(hook: BinaryFunctionHook<P, B, T, E>, options?: BinaryHookOptions<P, B>): [(body: B, params: P) => Promise<T>, () => void];
|
|
76
|
+
|
|
77
|
+
// **Implementation**
|
|
78
|
+
export function useAsPromise<P, B, T, E>(
|
|
79
|
+
hook: IntrigHook<P, B, T, E>,
|
|
80
|
+
options?: IntrigHookOptions<P, B>
|
|
81
|
+
): [(...args: any[]) => Promise<T>, () => void] { // <- Compatible return type
|
|
82
|
+
const resolveRef = useRef<(value: T) => void>();
|
|
83
|
+
const rejectRef = useRef<(reason?: any) => void>();
|
|
84
|
+
|
|
85
|
+
let [state, dispatch, clear] = hook(options as any); // Casting to `any` to match all overloads
|
|
86
|
+
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
if (isSuccess(state)) {
|
|
89
|
+
resolveRef.current?.(state.data);
|
|
90
|
+
clear();
|
|
91
|
+
} else if (isError(state)) {
|
|
92
|
+
rejectRef.current?.(state.error);
|
|
93
|
+
clear();
|
|
94
|
+
}
|
|
95
|
+
}, [state]);
|
|
96
|
+
|
|
97
|
+
const promiseFn = useCallback((...args: any[]) => {
|
|
98
|
+
return new Promise<T>((resolve, reject) => {
|
|
99
|
+
resolveRef.current = resolve;
|
|
100
|
+
rejectRef.current = reject;
|
|
101
|
+
|
|
102
|
+
let dispatchState = (dispatch as any)(...args);
|
|
103
|
+
if (isValidationError(dispatchState)) {
|
|
104
|
+
reject(dispatchState.error);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}, [dispatch]);
|
|
108
|
+
|
|
109
|
+
return [promiseFn, clear];
|
|
110
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { useIntrigContext } from '@intrig/next/intrig-context';
|
|
2
|
+
import { useCallback, useMemo } from 'react';
|
|
3
|
+
import { error, init, isInit, isSuccess, NetworkState, success } from '@intrig/next/network-state';
|
|
4
|
+
|
|
5
|
+
export interface LocalReducerOptions<T, E> {
|
|
6
|
+
initState?: T;
|
|
7
|
+
key?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function isPromise<T>(item: any): item is Promise<T> {
|
|
11
|
+
return !!item && typeof item.then === 'function' && typeof item.catch === 'function';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function useLocalReducer<T, E, F extends (event: E, curState?: T) => T | Promise<T>>(fn: F, options: LocalReducerOptions<T, E>) {
|
|
15
|
+
let context = useIntrigContext();
|
|
16
|
+
|
|
17
|
+
const key = useMemo(() => {
|
|
18
|
+
return options.key ?? 'default';
|
|
19
|
+
}, []);
|
|
20
|
+
|
|
21
|
+
const networkState: NetworkState<T> = useMemo(() => {
|
|
22
|
+
return context.state?.[`localState:reduce:${key}`] ?? init()
|
|
23
|
+
}, [context.state?.[`localState:reduce:${key}`]]);
|
|
24
|
+
|
|
25
|
+
const dispatch = useCallback(
|
|
26
|
+
(state: NetworkState<T>) => {
|
|
27
|
+
context.dispatch({ key, operation: 'reduce', source: 'localState', state });
|
|
28
|
+
},
|
|
29
|
+
[key, context.dispatch]
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const execute = useCallback((event: E) => {
|
|
33
|
+
try {
|
|
34
|
+
if (isSuccess(networkState)) {
|
|
35
|
+
let data = fn(event, networkState.data);
|
|
36
|
+
if (isPromise(data)) {
|
|
37
|
+
dispatch(init());
|
|
38
|
+
data.then(data => dispatch(success(data)));
|
|
39
|
+
} else {
|
|
40
|
+
dispatch(success(data));
|
|
41
|
+
}
|
|
42
|
+
} else if (isInit(networkState)) {
|
|
43
|
+
let data1 = fn(event, options.initState);
|
|
44
|
+
if (isPromise(data1)) {
|
|
45
|
+
dispatch(init());
|
|
46
|
+
data1.then(data => dispatch(success(data)));
|
|
47
|
+
} else {
|
|
48
|
+
dispatch(success(data1));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
} catch (e) {
|
|
52
|
+
dispatch(error(e));
|
|
53
|
+
}
|
|
54
|
+
}, [networkState, dispatch, fn]);
|
|
55
|
+
|
|
56
|
+
const clear = useCallback(() => {
|
|
57
|
+
dispatch(init())
|
|
58
|
+
}, []);
|
|
59
|
+
|
|
60
|
+
return [networkState, execute, clear]
|
|
61
|
+
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BinaryFunctionHook,
|
|
3
|
+
BinaryHookOptions,
|
|
4
|
+
BinaryProduceHook,
|
|
5
|
+
ConstantHook, IntrigHook, IntrigHookOptions, isSuccess, UnaryFunctionHook,
|
|
6
|
+
UnaryHookOptions,
|
|
7
|
+
UnaryProduceHook,
|
|
8
|
+
UnitHook,
|
|
9
|
+
UnitHookOptions
|
|
10
|
+
} from '@intrig/next/network-state';
|
|
11
|
+
import { useEffect, useState } from 'react';
|
|
12
|
+
|
|
2
13
|
/**
|
|
3
14
|
* Resolves and caches the computed value of a given hook.
|
|
4
15
|
*
|
|
@@ -6,7 +17,8 @@ import { BinaryFunctionHook, BinaryHookOptions, BinaryProduceHook, ConstantHook,
|
|
|
6
17
|
* @param {UnitHookOptions} options - Options to customize the behavior of the hook resolution and caching process.
|
|
7
18
|
* @return {undefined} This function does not return a value.
|
|
8
19
|
*/
|
|
9
|
-
export
|
|
20
|
+
export function useResolvedCachedValue<E>(hook: UnitHook<E>, options: UnitHookOptions): undefined;
|
|
21
|
+
|
|
10
22
|
/**
|
|
11
23
|
* Resolves and retrieves a cached value by utilizing a specified hook and options.
|
|
12
24
|
*
|
|
@@ -14,7 +26,8 @@ export declare function useResolvedCachedValue<E>(hook: UnitHook<E>, options: Un
|
|
|
14
26
|
* @param {UnitHookOptions} options - Options controlling the behavior or configuration of the hook.
|
|
15
27
|
* @return {T | undefined} The resolved cached value or undefined if the value couldn't be determined.
|
|
16
28
|
*/
|
|
17
|
-
export
|
|
29
|
+
export function useResolvedCachedValue<T, E>(hook: ConstantHook<T, E>, options: UnitHookOptions): T | undefined;
|
|
30
|
+
|
|
18
31
|
/**
|
|
19
32
|
* Resolves and caches the value produced by the specified hook.
|
|
20
33
|
* This utility helps in managing hook-driven computational results within a component context by caching
|
|
@@ -24,7 +37,8 @@ export declare function useResolvedCachedValue<T, E>(hook: ConstantHook<T, E>, o
|
|
|
24
37
|
* @param {UnaryHookOptions<P>} options - The configuration options that control how the hook is executed.
|
|
25
38
|
* @return {undefined} Returns undefined since the resolution and caching of the value are managed internally.
|
|
26
39
|
*/
|
|
27
|
-
export
|
|
40
|
+
export function useResolvedCachedValue<P, E>(hook: UnaryProduceHook<P, E>, options: UnaryHookOptions<P>): undefined;
|
|
41
|
+
|
|
28
42
|
/**
|
|
29
43
|
* Resolves a cached value using the provided hook and options.
|
|
30
44
|
*
|
|
@@ -33,7 +47,8 @@ export declare function useResolvedCachedValue<P, E>(hook: UnaryProduceHook<P, E
|
|
|
33
47
|
* @param {UnaryHookOptions<P>} options - Configuration settings or arguments required by the hook to retrieve the cached value.
|
|
34
48
|
* @return {T | undefined} A value of type T if resolved successfully, or undefined if not available.
|
|
35
49
|
*/
|
|
36
|
-
export
|
|
50
|
+
export function useResolvedCachedValue<P, T, E>(hook: UnaryFunctionHook<P, T, E>, options: UnaryHookOptions<P>): T | undefined;
|
|
51
|
+
|
|
37
52
|
/**
|
|
38
53
|
* Resolves and caches the value produced by the provided binary hook function.
|
|
39
54
|
* This function ensures that the hook's resolved value is reused efficiently across invocations
|
|
@@ -43,7 +58,8 @@ export declare function useResolvedCachedValue<P, T, E>(hook: UnaryFunctionHook<
|
|
|
43
58
|
* @param {BinaryHookOptions<P, B>} options - Configuration options for controlling the behavior of the hook and its caching mechanism.
|
|
44
59
|
* @return {undefined} - Returns undefined as the resolution is managed internally via the hook's lifecycle.
|
|
45
60
|
*/
|
|
46
|
-
export
|
|
61
|
+
export function useResolvedCachedValue<P, B, E>(hook: BinaryProduceHook<P, B, E>, options: BinaryHookOptions<P, B>): undefined;
|
|
62
|
+
|
|
47
63
|
/**
|
|
48
64
|
* A hook utility function that resolves and caches a value based on the given binary function hook and options.
|
|
49
65
|
*
|
|
@@ -51,4 +67,20 @@ export declare function useResolvedCachedValue<P, B, E>(hook: BinaryProduceHook<
|
|
|
51
67
|
* @param {BinaryHookOptions<P, B>} options - The options object containing parameters and configuration for the hook.
|
|
52
68
|
* @return {T | undefined} The resolved and cached value, or undefined if it cannot be resolved.
|
|
53
69
|
*/
|
|
54
|
-
export
|
|
70
|
+
export function useResolvedCachedValue<P, B, T, E>(hook: BinaryFunctionHook<P, B, T, E>, options: BinaryHookOptions<P, B>): T | undefined;
|
|
71
|
+
|
|
72
|
+
// **Implementation**
|
|
73
|
+
export function useResolvedCachedValue<P, B, T, E>(hook: IntrigHook<P, B, T, E>, options: IntrigHookOptions<P, B>): T | undefined {
|
|
74
|
+
const [cachedValue, setCachedValue] = useState<T | undefined>();
|
|
75
|
+
|
|
76
|
+
let [state] = hook(options as any); // Ensure compatibility with different hook types
|
|
77
|
+
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (isSuccess(state)) {
|
|
80
|
+
setCachedValue(state.data);
|
|
81
|
+
}
|
|
82
|
+
// Do not clear cached value if state is unsuccessful
|
|
83
|
+
}, [state]);
|
|
84
|
+
|
|
85
|
+
return cachedValue;
|
|
86
|
+
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BinaryFunctionHook,
|
|
3
|
+
BinaryHookOptions,
|
|
4
|
+
BinaryProduceHook,
|
|
5
|
+
ConstantHook, IntrigHook, IntrigHookOptions, isSuccess, UnaryFunctionHook,
|
|
6
|
+
UnaryHookOptions,
|
|
7
|
+
UnaryProduceHook,
|
|
8
|
+
UnitHook,
|
|
9
|
+
UnitHookOptions
|
|
10
|
+
} from '@intrig/next/network-state';
|
|
11
|
+
import { useEffect, useState } from 'react';
|
|
12
|
+
|
|
2
13
|
/**
|
|
3
14
|
* A function that resolves the value provided by a unit hook based on specified options.
|
|
4
15
|
*
|
|
@@ -6,7 +17,8 @@ import { BinaryFunctionHook, BinaryHookOptions, BinaryProduceHook, ConstantHook,
|
|
|
6
17
|
* @param {UnitHookOptions} options - Configuration options to control how the unit hook is resolved.
|
|
7
18
|
* @return {undefined} Returns undefined after resolving the unit hook value.
|
|
8
19
|
*/
|
|
9
|
-
export
|
|
20
|
+
export function useResolvedValue<E>(hook: UnitHook<E>, options: UnitHookOptions): undefined;
|
|
21
|
+
|
|
10
22
|
/**
|
|
11
23
|
* Resolves the value of a given constant hook based on the provided options.
|
|
12
24
|
*
|
|
@@ -14,7 +26,7 @@ export declare function useResolvedValue<E>(hook: UnitHook<E>, options: UnitHook
|
|
|
14
26
|
* @param {UnitHookOptions} options - The options used to configure the resolution of the hook value.
|
|
15
27
|
* @return {T | undefined} The resolved value of the hook or undefined if the hook cannot be resolved.
|
|
16
28
|
*/
|
|
17
|
-
export
|
|
29
|
+
export function useResolvedValue<T, E>(hook: ConstantHook<T, E>, options: UnitHookOptions): T | undefined;
|
|
18
30
|
/**
|
|
19
31
|
* This function is a utility hook that evaluates and resolves the value of the provided hook function.
|
|
20
32
|
* It takes a hook function and its corresponding options as arguments to produce side effects or state updates.
|
|
@@ -23,7 +35,8 @@ export declare function useResolvedValue<T, E>(hook: ConstantHook<T, E>, options
|
|
|
23
35
|
* @param {UnaryHookOptions<P>} options - Configuration options for the hook, such as parameters or behaviors.
|
|
24
36
|
* @return {undefined} This function does not return a value; it operates through side effects or resolves implicitly.
|
|
25
37
|
*/
|
|
26
|
-
export
|
|
38
|
+
export function useResolvedValue<P, E>(hook: UnaryProduceHook<P, E>, options: UnaryHookOptions<P>): undefined;
|
|
39
|
+
|
|
27
40
|
/**
|
|
28
41
|
* A custom hook that provides a resolved value based on the provided unary function hook and options.
|
|
29
42
|
*
|
|
@@ -31,7 +44,8 @@ export declare function useResolvedValue<P, E>(hook: UnaryProduceHook<P, E>, opt
|
|
|
31
44
|
* @param {UnaryHookOptions<P>} options - The configuration object containing parameters for the unary hook execution.
|
|
32
45
|
* @return {T | undefined} The resolved value of type T if successful, or undefined if no value is resolved.
|
|
33
46
|
*/
|
|
34
|
-
export
|
|
47
|
+
export function useResolvedValue<P, T, E>(hook: UnaryFunctionHook<P, T, E>, options: UnaryHookOptions<P>): T | undefined;
|
|
48
|
+
|
|
35
49
|
/**
|
|
36
50
|
* A custom hook that processes a binary produce hook and its options to produce a resolved value.
|
|
37
51
|
*
|
|
@@ -39,7 +53,8 @@ export declare function useResolvedValue<P, T, E>(hook: UnaryFunctionHook<P, T,
|
|
|
39
53
|
* @param {BinaryHookOptions<P, B>} options - The options provided to the binary hook for processing.
|
|
40
54
|
* @return {undefined} Returns `undefined` after the hook is resolved.
|
|
41
55
|
*/
|
|
42
|
-
export
|
|
56
|
+
export function useResolvedValue<P, B, E>(hook: BinaryProduceHook<P, B, E>, options: BinaryHookOptions<P, B>): undefined;
|
|
57
|
+
|
|
43
58
|
/**
|
|
44
59
|
* Resolves a value based on the provided binary function hook and options.
|
|
45
60
|
*
|
|
@@ -47,4 +62,21 @@ export declare function useResolvedValue<P, B, E>(hook: BinaryProduceHook<P, B,
|
|
|
47
62
|
* @param {BinaryHookOptions<P, B>} options - Configuration options for the binary function hook.
|
|
48
63
|
* @return {T | undefined} The resolved value of type T, or undefined if the resolution fails.
|
|
49
64
|
*/
|
|
50
|
-
export
|
|
65
|
+
export function useResolvedValue<P, B, T, E>(hook: BinaryFunctionHook<P, B, T, E>, options: BinaryHookOptions<P, B>): T | undefined;
|
|
66
|
+
|
|
67
|
+
// **Implementation**
|
|
68
|
+
export function useResolvedValue<P, B, T, E>(hook: IntrigHook<P, B, T, E>, options: IntrigHookOptions<P, B>): T | undefined {
|
|
69
|
+
const [value, setValue] = useState<T | undefined>();
|
|
70
|
+
|
|
71
|
+
let [state] = hook(options as any); // Ensure compatibility with different hook types
|
|
72
|
+
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (isSuccess(state)) {
|
|
75
|
+
setValue(state.data);
|
|
76
|
+
} else {
|
|
77
|
+
setValue(undefined);
|
|
78
|
+
}
|
|
79
|
+
}, [state]); // Add `state` to the dependency array to ensure updates
|
|
80
|
+
|
|
81
|
+
return value;
|
|
82
|
+
}
|
package/src/extra.ts
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
import {
|
|
3
|
+
BinaryFunctionHook,
|
|
4
|
+
BinaryHookOptions,
|
|
5
|
+
BinaryProduceHook,
|
|
6
|
+
ConstantHook,
|
|
7
|
+
error,
|
|
8
|
+
init, IntrigHook, IntrigHookOptions,
|
|
9
|
+
isError,
|
|
10
|
+
isSuccess,
|
|
11
|
+
isValidationError,
|
|
12
|
+
NetworkState,
|
|
13
|
+
pending,
|
|
14
|
+
success, UnaryFunctionHook, UnaryHookOptions, UnaryProduceHook,
|
|
15
|
+
UnitHook,
|
|
16
|
+
UnitHookOptions
|
|
17
|
+
} from '@intrig/next/network-state';
|
|
18
|
+
import { useCallback, useEffect, useId, useMemo, useReducer, useRef, useState } from 'react';
|
|
19
|
+
import { useIntrigContext } from '@intrig/next/intrig-context';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Converts a given hook into a promise-based function.
|
|
23
|
+
*
|
|
24
|
+
* @param {IntrigHook<P, B, T>} hook - The hook function to be converted.
|
|
25
|
+
* @param options
|
|
26
|
+
*
|
|
27
|
+
* @return {[(...params: Parameters<ReturnType<IntrigHook<P, B, T>>[1]>) => Promise<T>, () => void]}
|
|
28
|
+
* Returns a tuple containing a function that invokes the hook as a promise and a function to clear the state.
|
|
29
|
+
*/
|
|
30
|
+
export function useAsPromise<E>(hook: UnitHook<E>, options: UnitHookOptions): [() => Promise<never>, () => void];
|
|
31
|
+
export function useAsPromise<T, E>(hook: ConstantHook<T, E>, options: UnitHookOptions): [() => Promise<T>, () => void];
|
|
32
|
+
export function useAsPromise<P, E>(hook: UnaryProduceHook<P, E>, options?: UnaryHookOptions<P>): [(params: P) => Promise<never>, () => void];
|
|
33
|
+
export function useAsPromise<P, T, E>( hook: UnaryFunctionHook<P, T, E>, options?: UnaryHookOptions<P>): [(params: P) => Promise<T>, () => void];
|
|
34
|
+
export function useAsPromise<P, B, E>(hook: BinaryProduceHook<P, B, E>, options?: BinaryHookOptions<P, B>): [(body: B, params: P) => Promise<never>, () => void];
|
|
35
|
+
export function useAsPromise<P, B, T, E>(hook: BinaryFunctionHook<P, B, T, E>, options?: BinaryHookOptions<P, B>): [(body: B, params: P) => Promise<T>, () => void];
|
|
36
|
+
|
|
37
|
+
// **Implementation**
|
|
38
|
+
export function useAsPromise<P, B, T, E>(
|
|
39
|
+
hook: IntrigHook<P, B, T, E>,
|
|
40
|
+
options?: IntrigHookOptions<P, B>
|
|
41
|
+
): [(...args: any[]) => Promise<T>, () => void] { // <- Compatible return type
|
|
42
|
+
const resolveRef = useRef<(value: T) => void>();
|
|
43
|
+
const rejectRef = useRef<(reason?: any) => void>();
|
|
44
|
+
|
|
45
|
+
let [state, dispatch, clear] = hook(options as any); // Casting to `any` to match all overloads
|
|
46
|
+
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (isSuccess(state)) {
|
|
49
|
+
resolveRef.current?.(state.data);
|
|
50
|
+
clear();
|
|
51
|
+
} else if (isError(state)) {
|
|
52
|
+
rejectRef.current?.(state.error);
|
|
53
|
+
clear();
|
|
54
|
+
}
|
|
55
|
+
}, [state]);
|
|
56
|
+
|
|
57
|
+
const promiseFn = useCallback((...args: any[]) => {
|
|
58
|
+
return new Promise<T>((resolve, reject) => {
|
|
59
|
+
resolveRef.current = resolve;
|
|
60
|
+
rejectRef.current = reject;
|
|
61
|
+
|
|
62
|
+
let dispatchState = (dispatch as any)(...args);
|
|
63
|
+
if (isValidationError(dispatchState)) {
|
|
64
|
+
reject(dispatchState.error);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}, [dispatch]);
|
|
68
|
+
|
|
69
|
+
return [promiseFn, clear];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* A custom hook that manages and returns the network state of a promise-based function,
|
|
74
|
+
* providing a way to execute the function and clear its state.
|
|
75
|
+
*
|
|
76
|
+
* @param fn The promise-based function whose network state is to be managed. It should be a function that returns a promise.
|
|
77
|
+
* @param key An optional identifier for the network state. Defaults to 'default'.
|
|
78
|
+
* @return A tuple containing the current network state, a function to execute the promise, and a function to clear the state.
|
|
79
|
+
*/
|
|
80
|
+
export function useAsNetworkState<T, F extends ((...args: any) => Promise<T>)>(fn: F, key: string = 'default'): [NetworkState<T>, (...params: Parameters<F>) => void, () => void] {
|
|
81
|
+
let id = useId();
|
|
82
|
+
|
|
83
|
+
let context = useIntrigContext();
|
|
84
|
+
|
|
85
|
+
const networkState = useMemo(() => {
|
|
86
|
+
return context.state?.[`promiseState:${id}:${key}}`] ?? init()
|
|
87
|
+
}, [context.state?.[`promiseState:${id}:${key}}`]]);
|
|
88
|
+
|
|
89
|
+
const dispatch = useCallback(
|
|
90
|
+
(state: NetworkState<T>) => {
|
|
91
|
+
context.dispatch({ key, operation: id, source: 'promiseState', state });
|
|
92
|
+
},
|
|
93
|
+
[key, context.dispatch]
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const execute = useCallback((...args: Parameters<F>) => {
|
|
97
|
+
dispatch(pending())
|
|
98
|
+
return fn(...args).then(
|
|
99
|
+
(data) => {
|
|
100
|
+
dispatch(success(data))
|
|
101
|
+
},
|
|
102
|
+
(e) => {
|
|
103
|
+
dispatch(error(e))
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
}, []);
|
|
107
|
+
|
|
108
|
+
const clear = useCallback(() => {
|
|
109
|
+
dispatch(init())
|
|
110
|
+
}, []);
|
|
111
|
+
|
|
112
|
+
return [
|
|
113
|
+
networkState,
|
|
114
|
+
execute,
|
|
115
|
+
clear
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* A custom hook that resolves the value from the provided hook's state and updates it whenever the state changes.
|
|
121
|
+
*
|
|
122
|
+
* @param {IntrigHook<P, B, T>} hook - The hook that provides the state to observe and resolve data from.
|
|
123
|
+
* @param options
|
|
124
|
+
* @return {T | undefined} The resolved value from the hook's state or undefined if the state is not successful.
|
|
125
|
+
*/
|
|
126
|
+
export function useResolvedValue<E>(hook: UnitHook<E>, options: UnitHookOptions): undefined;
|
|
127
|
+
|
|
128
|
+
export function useResolvedValue<T, E>(hook: ConstantHook<T, E>, options: UnitHookOptions): T | undefined;
|
|
129
|
+
|
|
130
|
+
export function useResolvedValue<P, E>(hook: UnaryProduceHook<P, E>, options: UnaryHookOptions<P>): undefined;
|
|
131
|
+
|
|
132
|
+
export function useResolvedValue<P, T, E>(hook: UnaryFunctionHook<P, T, E>, options: UnaryHookOptions<P>): T | undefined;
|
|
133
|
+
|
|
134
|
+
export function useResolvedValue<P, B, E>(hook: BinaryProduceHook<P, B, E>, options: BinaryHookOptions<P, B>): undefined;
|
|
135
|
+
|
|
136
|
+
export function useResolvedValue<P, B, T, E>(hook: BinaryFunctionHook<P, B, T, E>, options: BinaryHookOptions<P, B>): T | undefined;
|
|
137
|
+
|
|
138
|
+
// **Implementation**
|
|
139
|
+
export function useResolvedValue<P, B, T, E>(hook: IntrigHook<P, B, T, E>, options: IntrigHookOptions<P, B>): T | undefined {
|
|
140
|
+
const [value, setValue] = useState<T | undefined>();
|
|
141
|
+
|
|
142
|
+
let [state] = hook(options as any); // Ensure compatibility with different hook types
|
|
143
|
+
|
|
144
|
+
useEffect(() => {
|
|
145
|
+
if (isSuccess(state)) {
|
|
146
|
+
setValue(state.data);
|
|
147
|
+
} else {
|
|
148
|
+
setValue(undefined);
|
|
149
|
+
}
|
|
150
|
+
}, [state]); // Add `state` to the dependency array to ensure updates
|
|
151
|
+
|
|
152
|
+
return value;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* A custom hook that resolves and caches the value from a successful state provided by the given hook.
|
|
158
|
+
* The state is updated only when it is in a successful state.
|
|
159
|
+
*
|
|
160
|
+
* @param {IntrigHook<P, B, T>} hook - The hook that provides the state to observe and cache data from.
|
|
161
|
+
* @param options
|
|
162
|
+
* @return {T | undefined} The cached value from the hook's state or undefined if the state is not successful.
|
|
163
|
+
*/
|
|
164
|
+
export function useResolvedCachedValue<E>(hook: UnitHook<E>, options: UnitHookOptions): undefined;
|
|
165
|
+
|
|
166
|
+
export function useResolvedCachedValue<T, E>(hook: ConstantHook<T, E>, options: UnitHookOptions): T | undefined;
|
|
167
|
+
|
|
168
|
+
export function useResolvedCachedValue<P, E>(hook: UnaryProduceHook<P, E>, options: UnaryHookOptions<P>): undefined;
|
|
169
|
+
|
|
170
|
+
export function useResolvedCachedValue<P, T, E>(hook: UnaryFunctionHook<P, T, E>, options: UnaryHookOptions<P>): T | undefined;
|
|
171
|
+
|
|
172
|
+
export function useResolvedCachedValue<P, B, E>(hook: BinaryProduceHook<P, B, E>, options: BinaryHookOptions<P, B>): undefined;
|
|
173
|
+
|
|
174
|
+
export function useResolvedCachedValue<P, B, T, E>(hook: BinaryFunctionHook<P, B, T, E>, options: BinaryHookOptions<P, B>): T | undefined;
|
|
175
|
+
|
|
176
|
+
// **Implementation**
|
|
177
|
+
export function useResolvedCachedValue<P, B, T, E>(hook: IntrigHook<P, B, T, E>, options: IntrigHookOptions<P, B>): T | undefined {
|
|
178
|
+
const [cachedValue, setCachedValue] = useState<T | undefined>();
|
|
179
|
+
|
|
180
|
+
let [state] = hook(options as any); // Ensure compatibility with different hook types
|
|
181
|
+
|
|
182
|
+
useEffect(() => {
|
|
183
|
+
if (isSuccess(state)) {
|
|
184
|
+
setCachedValue(state.data);
|
|
185
|
+
}
|
|
186
|
+
// Do not clear cached value if state is unsuccessful
|
|
187
|
+
}, [state]);
|
|
188
|
+
|
|
189
|
+
return cachedValue;
|
|
190
|
+
}
|