@cripty2001/utils 0.0.254 → 0.0.256

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.
@@ -1,21 +1,25 @@
1
1
  import { Whispr } from "@cripty2001/whispr";
2
- export type DispatcherStatePayload<T> = {
2
+ export type DispatcherStatePayloadResponse<O> = {
3
3
  loading: true;
4
4
  progress: number;
5
5
  } | ({
6
6
  loading: false;
7
7
  } & ({
8
8
  ok: true;
9
- data: T;
9
+ data: O;
10
10
  } | {
11
11
  ok: false;
12
12
  error: Error;
13
13
  }));
14
+ export type DispatcherStatePayload<I, O> = {
15
+ input: I;
16
+ output: DispatcherStatePayloadResponse<O>;
17
+ };
14
18
  type DispatcherFunction<I, O> = (data: I, setProgress: (p: number) => void, signal: AbortSignal) => Promise<O>;
15
19
  export declare class Dispatcher<I, O> {
16
20
  private state;
17
21
  private setState;
18
- data: Whispr<DispatcherStatePayload<O>>;
22
+ data: Whispr<DispatcherStatePayload<I, O>>;
19
23
  filtered: Whispr<O | null>;
20
24
  readonly DEBOUNCE_INTERVAL: number;
21
25
  private readonly f;
@@ -32,6 +36,10 @@ export declare class Dispatcher<I, O> {
32
36
  * @remarks Data updating flag is set in a synchronous way. This means that in the event your DEBOUNCE_INTERVAL is near infinity, you still get the data set to updating true immediately when you update the value. It just wait like this forever
33
37
  */
34
38
  constructor(value: Whispr<I>, f: DispatcherFunction<I, O>, DEBOUNCE_INTERVAL?: number);
39
+ /**
40
+ * Re-execute the dispatcher, ignoring both the debounce interval and the input deduplication
41
+ */
42
+ refresh(): void;
35
43
  private reset;
36
44
  private dispatch;
37
45
  }
@@ -31,8 +31,11 @@ class Dispatcher {
31
31
  [this.state, this.setState] = whispr_1.Whispr.create({
32
32
  controller: new AbortController(),
33
33
  payload: {
34
- loading: true,
35
- progress: 0,
34
+ input: value.value,
35
+ output: {
36
+ loading: true,
37
+ progress: 0,
38
+ },
36
39
  }
37
40
  });
38
41
  // Subscribing to input changes
@@ -47,14 +50,20 @@ class Dispatcher {
47
50
  .from({ state: this.state }, ({ state }) => state.payload);
48
51
  this.filtered = whispr_1.Whispr.from({
49
52
  data: this.data
50
- }, ({ data }) => {
51
- if (data.loading)
53
+ }, ({ data: { output: response } }) => {
54
+ if (response.loading)
52
55
  return null;
53
- if (!data.ok)
56
+ if (!response.ok)
54
57
  return null;
55
- return data.data;
58
+ return response.data;
56
59
  });
57
60
  }
61
+ /**
62
+ * Re-execute the dispatcher, ignoring both the debounce interval and the input deduplication
63
+ */
64
+ refresh() {
65
+ this.dispatch(this.value.value);
66
+ }
58
67
  reset() {
59
68
  // Aborting previous request
60
69
  this.state.value.controller.abort();
@@ -64,8 +73,11 @@ class Dispatcher {
64
73
  this.setState({
65
74
  controller,
66
75
  payload: {
67
- loading: true,
68
- progress: 0,
76
+ input: this.value.value,
77
+ output: {
78
+ loading: true,
79
+ progress: 0,
80
+ },
69
81
  }
70
82
  });
71
83
  // Creating generic state update function
@@ -74,7 +86,10 @@ class Dispatcher {
74
86
  return;
75
87
  this.setState({
76
88
  controller: this.state.value.controller, // Keeping the effective controller, not the internal old one (even if, in practice, they should be the same, if everything worked well),
77
- payload: value,
89
+ payload: {
90
+ input: this.value.value,
91
+ output: value,
92
+ }
78
93
  });
79
94
  };
80
95
  // Returning state update function
@@ -1,11 +1,11 @@
1
1
  import type React from "react";
2
2
  import type { Dispatcher } from "../Dispatcher";
3
- export type LoaderProps<T> = {
4
- data: Dispatcher<unknown, T>;
3
+ export type LoaderProps<I, O> = {
4
+ data: Dispatcher<I, O>;
5
5
  children: (props: {
6
- data: T;
6
+ data: O;
7
7
  }) => React.ReactNode;
8
8
  loader?: React.ReactNode;
9
- showRefreshing?: boolean;
9
+ computeRefreshKey?: (input: I) => string;
10
10
  };
11
- export default function Loader<T>(props: LoaderProps<T>): React.JSX.Element;
11
+ export default function Loader<I, O>(props: LoaderProps<I, O>): React.JSX.Element;
@@ -19,22 +19,21 @@ if (typeof document !== 'undefined') {
19
19
  }
20
20
  }
21
21
  function Loader(props) {
22
- const prev = (0, react_1.useRef)({ loading: true, progress: 0 });
23
- const state = (0, react_whispr_1.useWhisprValue)(props.data.data);
24
- if (!state.loading) {
25
- prev.current = state;
22
+ const ck = props.computeRefreshKey ?? ((input) => JSON.stringify(input));
23
+ const active = (0, react_1.useRef)({
24
+ input: undefined,
25
+ output: { loading: true, progress: 0 }
26
+ });
27
+ const incoming = (0, react_whispr_1.useWhisprValue)(props.data.data);
28
+ if (ck(active.current.input) !== ck(incoming.input) ||
29
+ !incoming.output.loading) {
30
+ active.current = incoming;
26
31
  }
27
- const data = (0, react_1.useMemo)(() => {
28
- if (props.showRefreshing)
29
- return state;
30
- if (state.loading && prev.current !== null)
31
- return prev.current;
32
- return state;
33
- }, [state.loading, prev.current, props.showRefreshing]);
34
- return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(Content, { data: data, children: props.children, loader: props.loader }) }));
32
+ return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(Content, { data: active.current, children: props.children, loader: props.loader }) }));
35
33
  }
36
34
  function Content({ data, children, loader }) {
37
- if (data.loading)
35
+ const result = data.output;
36
+ if (result.loading)
38
37
  return loader ?? ((0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100vh' }, children: (0, jsx_runtime_1.jsx)("div", { style: {
39
38
  animation: 'spin 1s linear infinite',
40
39
  borderRadius: '9999px',
@@ -43,7 +42,7 @@ function Content({ data, children, loader }) {
43
42
  borderTop: '2px solid #111827',
44
43
  borderBottom: '2px solid #111827'
45
44
  } }) }));
46
- if (!data.ok)
47
- return (0, jsx_runtime_1.jsx)("div", { style: { color: '#ef4444' }, children: data.error.message });
48
- return children({ data: data.data });
45
+ if (!result.ok)
46
+ return (0, jsx_runtime_1.jsx)("div", { style: { color: '#ef4444' }, children: result.error.message });
47
+ return children({ data: result.data });
49
48
  }
@@ -244,27 +244,20 @@ function useAsync(data, debouce, interval, f) {
244
244
  setInput(data); // Debouncing already handled by dispatcher
245
245
  }
246
246
  }, [data, setInput]);
247
- // Initing refresh bundle
248
- const timer = useSafeRef(() => interval !== null ?
249
- (0, _1.getClock)(interval) :
250
- whispr_1.Whispr.create(0)[0]);
251
- const [refresh, setRefresh] = useSafeRef(() => whispr_1.Whispr.create(Math.random()));
252
- const bundle = useSafeRef(() => whispr_1.Whispr.from({
253
- input,
254
- timer,
255
- refresh
256
- }, ({ input, timer, refresh }) => ({
257
- data: input,
258
- timer,
259
- refresh
260
- })));
261
247
  // Initing dispatcher
262
- const dispatcher = useSafeRef(() => new Dispatcher_1.Dispatcher(bundle, (i, p, s) => f(i.data, p, s), debouce));
248
+ const dispatcher = useSafeRef(() => new Dispatcher_1.Dispatcher(input, (i, p, s) => f(i, p, s), debouce));
249
+ // Starting refresher
250
+ const clock = useClock(interval ?
251
+ interval :
252
+ Number.MAX_SAFE_INTEGER);
253
+ (0, react_1.useEffect)(() => {
254
+ dispatcher.refresh();
255
+ }, [clock, dispatcher]);
263
256
  // Returning dispatcher and refresh function
264
257
  return [
265
258
  dispatcher,
266
259
  () => {
267
- setRefresh(Math.random());
260
+ dispatcher.refresh();
268
261
  }
269
262
  ];
270
263
  }
@@ -295,8 +288,8 @@ function useAsync(data, debouce, interval, f) {
295
288
  function useAsyncEffect(f, data, debounce = 200) {
296
289
  const [dispatcher] = useAsync(data, debounce, null, f);
297
290
  useOnWhispr(dispatcher.data, (data) => {
298
- if (!data.loading && !data.ok) {
299
- throw data.error;
291
+ if (!data.output.loading && !data.output.ok) {
292
+ throw data.output.error;
300
293
  }
301
294
  }, true);
302
295
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cripty2001/utils",
3
- "version": "0.0.254",
3
+ "version": "0.0.256",
4
4
  "description": "Internal Set of utils. If you need them use them, otherwise go to the next package ;)",
5
5
  "homepage": "https://github.com/cripty2001/utils#readme",
6
6
  "bugs": {