@cripty2001/utils 0.0.6 → 0.0.7

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,36 @@
1
+ import { Whispr } from "@cripty2001/whispr";
2
+ export type DispatcherStatePayload<T> = {
3
+ loading: true;
4
+ progress: number;
5
+ } | ({
6
+ loading: false;
7
+ } & ({
8
+ ok: true;
9
+ data: T;
10
+ } | {
11
+ ok: false;
12
+ error: Error;
13
+ }));
14
+ type DispatcherFunction<I, O> = (data: I, setProgress: (p: number) => void, signal: AbortSignal) => Promise<O>;
15
+ export declare class Dispatcher<I, O> {
16
+ private state;
17
+ private setState;
18
+ data: Whispr<DispatcherStatePayload<O>>;
19
+ filtered: Whispr<O | null>;
20
+ readonly DEBOUNCE_INTERVAL: number;
21
+ private readonly f;
22
+ private value;
23
+ private lastValue;
24
+ /**
25
+ * Create a new dispatcher
26
+ * @param value The whispr value that will trigger f call when changed. Using this pattern instead of exposing a dispatch method allow to return the full dispatcher to anyone, without having to worry about them messing it
27
+ * @param f The async function to call. It should return a promise that resolves to the data.
28
+ * @param DEBOUNCE_INTERVAL
29
+ *
30
+ * @remarks The value is deep checked for equality. The function will be called only if the value changed deeply
31
+ */
32
+ constructor(value: Whispr<I>, f: DispatcherFunction<I, O>, DEBOUNCE_INTERVAL?: number);
33
+ private reset;
34
+ private dispatch;
35
+ }
36
+ export {};
@@ -1,163 +1,123 @@
1
- import { Whispr, WhisprSetter } from "@cripty2001/whispr";
2
- import { sleep } from ".";
3
- import { isEqual } from "lodash";
4
-
5
- export type DispatcherStatePayload<T> =
6
- {
7
- loading: true,
8
- progress: number,
9
- } | (
10
- { loading: false } & (
11
- {
12
- ok: true;
13
- data: T
14
- } | {
15
- ok: false;
16
- error: Error
17
- }
18
- )
19
- )
20
-
21
- type DispatcherState<T> = {
22
- controller: AbortController;
23
- payload: DispatcherStatePayload<T>;
24
- }
25
-
26
- type DispatcherFunction<I, O> = (data: I, setProgress: (p: number) => void, signal: AbortSignal) => Promise<O>
27
- export class Dispatcher<I, O> {
28
- private state: Whispr<DispatcherState<O>>;
29
- private setState: WhisprSetter<DispatcherState<O>>;
30
-
31
- public data: Whispr<DispatcherStatePayload<O>>;
32
- public filtered: Whispr<O | null>;
33
-
34
- public readonly DEBOUNCE_INTERVAL;
35
- private readonly f: DispatcherFunction<I, O>;
36
-
37
- private value: Whispr<I>; // Value is a whispr that we are subscribed to. We must keep a reference to it to avoid the subscription being automatically canceled
38
- private lastValue: I | null = null; // Last value, to avoid useless dispatches
39
-
40
- /**
41
- * Create a new dispatcher
42
- * @param value The whispr value that will trigger f call when changed. Using this pattern instead of exposing a dispatch method allow to return the full dispatcher to anyone, without having to worry about them messing it
43
- * @param f The async function to call. It should return a promise that resolves to the data.
44
- * @param DEBOUNCE_INTERVAL
45
- *
46
- * @remarks The value is deep checked for equality. The function will be called only if the value changed deeply
47
- */
48
- constructor(value: Whispr<I>, f: DispatcherFunction<I, O>, DEBOUNCE_INTERVAL: number = 200) {
49
- // Initing state
50
- this.f = f;
51
- this.DEBOUNCE_INTERVAL = DEBOUNCE_INTERVAL;
52
- this.value = value;
53
-
54
- [this.state, this.setState] = Whispr.create<DispatcherState<O>>({
55
- controller: new AbortController(),
56
- payload: {
57
- loading: true,
58
- progress: 0,
59
- }
60
- });
61
-
62
- // Subscribing to input changes
63
- this.value.subscribe((v) => {
64
- if (this.lastValue !== null && isEqual(this.lastValue, v))
65
- return;
66
-
67
- this.lastValue = v;
68
- this.dispatch(v);
69
- });
70
-
71
- // Initing public derived whisprs
72
- this.data = Whispr
73
- .from({ state: this.state }, ({ state }) => state.payload);
74
-
75
- this.filtered = Whispr.from(
76
- {
77
- data: this.data
78
- },
79
- ({ data }) => {
80
- if (data.loading)
81
- return null;
82
- if (!data.ok)
83
- return null;
84
- return data.data;
85
- }
86
- )
87
- }
88
-
89
- private reset() {
90
- // Aborting previous request
91
- this.state.value.controller.abort();
92
-
93
- // Initing new abort controller
94
- const controller = new AbortController();
95
-
96
- // Resetting response state
97
- this.setState({
98
- controller,
99
- payload: {
100
- loading: true,
101
- progress: 0,
102
- }
103
- });
104
-
105
- // Creating generic state update function
106
- const updateState = (value: DispatcherStatePayload<O>) => {
107
- if (controller.signal.aborted) // Working on local controller, not global one. Old controller will change and be aborted on reset, global one will always be running
108
- return;
109
-
110
- this.setState({
111
- 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),
112
- payload: value,
113
- });
114
- }
115
-
116
- // Returning state update function
117
- return {
118
- commit: (data: O) => {
119
- updateState({
120
- loading: false,
121
- ok: true,
122
- data,
123
- });
124
- },
125
- raise: (error: Error) => {
126
- updateState({
127
- loading: false,
128
- ok: false,
129
- error,
130
- });
131
- },
132
- progress: (p: number) => {
133
- updateState({
134
- loading: true,
135
- progress: p,
136
- });
137
- },
138
- controller
139
- };
140
- };
141
-
142
- private dispatch(data: I): Promise<void> {
143
- const signals = this.reset();
144
-
145
- const toReturn = (async () => {
146
- // Debouncing rapid changes
147
- await sleep(this.DEBOUNCE_INTERVAL);
148
- if (signals.controller.signal.aborted)
149
- throw new DOMException('Debounced', 'AbortError');
150
-
151
- // Scheduling function execution
152
- return await this.f(data, signals.progress, signals.controller.signal)
153
- })()
154
- .then((res) => {
155
- signals.commit(res);
156
- })
157
- .catch((e) => {
158
- signals.raise(e instanceof Error ? e : new Error(JSON.stringify(e)));
159
- });
160
-
161
- return toReturn;
162
- }
163
- }
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Dispatcher = void 0;
4
+ const whispr_1 = require("@cripty2001/whispr");
5
+ const _1 = require(".");
6
+ const lodash_1 = require("lodash");
7
+ class Dispatcher {
8
+ state;
9
+ setState;
10
+ data;
11
+ filtered;
12
+ DEBOUNCE_INTERVAL;
13
+ f;
14
+ value; // Value is a whispr that we are subscribed to. We must keep a reference to it to avoid the subscription being automatically canceled
15
+ lastValue = null; // Last value, to avoid useless dispatches
16
+ /**
17
+ * Create a new dispatcher
18
+ * @param value The whispr value that will trigger f call when changed. Using this pattern instead of exposing a dispatch method allow to return the full dispatcher to anyone, without having to worry about them messing it
19
+ * @param f The async function to call. It should return a promise that resolves to the data.
20
+ * @param DEBOUNCE_INTERVAL
21
+ *
22
+ * @remarks The value is deep checked for equality. The function will be called only if the value changed deeply
23
+ */
24
+ constructor(value, f, DEBOUNCE_INTERVAL = 200) {
25
+ // Initing state
26
+ this.f = f;
27
+ this.DEBOUNCE_INTERVAL = DEBOUNCE_INTERVAL;
28
+ this.value = value;
29
+ [this.state, this.setState] = whispr_1.Whispr.create({
30
+ controller: new AbortController(),
31
+ payload: {
32
+ loading: true,
33
+ progress: 0,
34
+ }
35
+ });
36
+ // Subscribing to input changes
37
+ this.value.subscribe((v) => {
38
+ if (this.lastValue !== null && (0, lodash_1.isEqual)(this.lastValue, v))
39
+ return;
40
+ this.lastValue = v;
41
+ this.dispatch(v);
42
+ });
43
+ // Initing public derived whisprs
44
+ this.data = whispr_1.Whispr
45
+ .from({ state: this.state }, ({ state }) => state.payload);
46
+ this.filtered = whispr_1.Whispr.from({
47
+ data: this.data
48
+ }, ({ data }) => {
49
+ if (data.loading)
50
+ return null;
51
+ if (!data.ok)
52
+ return null;
53
+ return data.data;
54
+ });
55
+ }
56
+ reset() {
57
+ // Aborting previous request
58
+ this.state.value.controller.abort();
59
+ // Initing new abort controller
60
+ const controller = new AbortController();
61
+ // Resetting response state
62
+ this.setState({
63
+ controller,
64
+ payload: {
65
+ loading: true,
66
+ progress: 0,
67
+ }
68
+ });
69
+ // Creating generic state update function
70
+ const updateState = (value) => {
71
+ if (controller.signal.aborted) // Working on local controller, not global one. Old controller will change and be aborted on reset, global one will always be running
72
+ return;
73
+ this.setState({
74
+ 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),
75
+ payload: value,
76
+ });
77
+ };
78
+ // Returning state update function
79
+ return {
80
+ commit: (data) => {
81
+ updateState({
82
+ loading: false,
83
+ ok: true,
84
+ data,
85
+ });
86
+ },
87
+ raise: (error) => {
88
+ updateState({
89
+ loading: false,
90
+ ok: false,
91
+ error,
92
+ });
93
+ },
94
+ progress: (p) => {
95
+ updateState({
96
+ loading: true,
97
+ progress: p,
98
+ });
99
+ },
100
+ controller
101
+ };
102
+ }
103
+ ;
104
+ dispatch(data) {
105
+ const signals = this.reset();
106
+ const toReturn = (async () => {
107
+ // Debouncing rapid changes
108
+ await (0, _1.sleep)(this.DEBOUNCE_INTERVAL);
109
+ if (signals.controller.signal.aborted)
110
+ throw new DOMException('Debounced', 'AbortError');
111
+ // Scheduling function execution
112
+ return await this.f(data, signals.progress, signals.controller.signal);
113
+ })()
114
+ .then((res) => {
115
+ signals.commit(res);
116
+ })
117
+ .catch((e) => {
118
+ signals.raise(e instanceof Error ? e : new Error(JSON.stringify(e)));
119
+ });
120
+ return toReturn;
121
+ }
122
+ }
123
+ exports.Dispatcher = Dispatcher;
@@ -0,0 +1,11 @@
1
+ export type JSONEncodable = number | string | boolean | JSONEncodable[] | {
2
+ [key: string]: JSONEncodable;
3
+ };
4
+ export type TypeofArray<T extends any[]> = T extends (infer U)[] ? U : never;
5
+ export type TypeofRecord<T extends Record<string, any>> = T extends Record<string, infer U> ? U : never;
6
+ export declare function getRandom(_alphabeth: string, length: number): string;
7
+ export declare function getRandomId(length?: number): string;
8
+ export declare function getRandomOtp(length?: number, char?: boolean): string;
9
+ export declare function sleep(ms: number): Promise<void>;
10
+ export declare function parseHash(fields: string[]): URLSearchParams;
11
+ export declare function loop(cb: () => Promise<void>, interval: number, onError?: (e: any) => Promise<void>): Promise<void>;
package/dist/index.js ADDED
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRandom = getRandom;
4
+ exports.getRandomId = getRandomId;
5
+ exports.getRandomOtp = getRandomOtp;
6
+ exports.sleep = sleep;
7
+ exports.parseHash = parseHash;
8
+ exports.loop = loop;
9
+ function getRandom(_alphabeth, length) {
10
+ const alphabeth = _alphabeth.split("");
11
+ const toReturn = [];
12
+ while (toReturn.length < length) {
13
+ toReturn.push(alphabeth[Math.floor(Math.random() * alphabeth.length)]);
14
+ }
15
+ return toReturn.join("");
16
+ }
17
+ function getRandomId(length = 20) {
18
+ const ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
19
+ return getRandom(ALPHABET, length);
20
+ }
21
+ function getRandomOtp(length = 6, char = false) {
22
+ const ALPHABET = "0123456789" + (char ? "ABCDEFGHIJKLMNOPQRSTUVWXYZ" : "");
23
+ return getRandom(ALPHABET, length);
24
+ }
25
+ function sleep(ms) {
26
+ return new Promise((resolve) => setTimeout(resolve, ms));
27
+ }
28
+ function parseHash(fields) {
29
+ // Checking empty hash
30
+ if (window.location.hash === "")
31
+ return new URLSearchParams();
32
+ // Parsing hash
33
+ const data = new URLSearchParams(window.location.hash.replace(/^#/, "?"));
34
+ // Extracting fields
35
+ const toReturn = new URLSearchParams();
36
+ for (const field of fields) {
37
+ if (data.has(field)) {
38
+ toReturn.set(field, data.get(field));
39
+ data.delete(field);
40
+ }
41
+ }
42
+ // Reencoding hash without extracted fields
43
+ window.location.hash = `#${data.toString()}`;
44
+ // Returning extracted fields
45
+ return toReturn;
46
+ }
47
+ async function loop(cb, interval, onError = async (e) => { console.error(e); }) {
48
+ while (true) {
49
+ try {
50
+ await cb();
51
+ }
52
+ catch (e) {
53
+ await onError(e);
54
+ }
55
+ finally {
56
+ await sleep(interval);
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,26 @@
1
+ import { Whispr } from "@cripty2001/whispr";
2
+ /**
3
+ * Convert a Whispr value into a reactive react value, usable in function components with the standard react reactive system.
4
+ * If the value is not a Whispr, it is returned as is, thus allowing for progressive migration and adoption
5
+ * @param w A reactive react value or a Whispr containing it
6
+ * @param computer An optional function to compute the returned value. This is useful to extract a part of a larger whispr, or to compute a derived value. It is the analog of useMemo with a single dependency (the whispr itself)
7
+ * @returns A reactive react value
8
+ *
9
+ * @remarks The value is NOT REACTIVE, and the same applies to the computer, if any. Only changes to its content will trigger a change, not changes to the object itself.
10
+ *
11
+ * @example
12
+ * export default function MyComponent(props: { value: Whispr<string> }) {
13
+ * const value = useWhisprValue(props.value);
14
+ *
15
+ * return <div>{value}</div>;
16
+ * }
17
+ */
18
+ export declare function useWhisprValue<I, O = I>(w: Whispr<I>, computer?: (data: I) => O): O;
19
+ /**
20
+ * Wrap a (react) value into a Whispr, if it is not one already.
21
+ * @param data A Whispr or a normal (react reactable) value
22
+ * @returns The whispr'd value, or the original whispr if it was one (allow for incremental adoption)
23
+ *
24
+ * @remarks The returned whispr has already been ref-fed, so it can be directly used without worrying about react recreating it or similar bad things
25
+ */
26
+ export declare function useWhispr<T>(data: T | Whispr<T>): Whispr<T>;
@@ -1,69 +1,52 @@
1
- import { Whispr, type WhisprSetter } from "@cripty2001/whispr";
2
- import { useEffect, useRef, useState } from "react";
3
-
4
- import { isEqual } from "lodash";
5
-
6
- /**
7
- * Convert a Whispr value into a reactive react value, usable in function components with the standard react reactive system.
8
- * If the value is not a Whispr, it is returned as is, thus allowing for progressive migration and adoption
9
- * @param w A reactive react value or a Whispr containing it
10
- * @param computer An optional function to compute the returned value. This is useful to extract a part of a larger whispr, or to compute a derived value. It is the analog of useMemo with a single dependency (the whispr itself)
11
- * @returns A reactive react value
12
- *
13
- * @remarks The value is NOT REACTIVE, and the same applies to the computer, if any. Only changes to its content will trigger a change, not changes to the object itself.
14
- *
15
- * @example
16
- * export default function MyComponent(props: { value: Whispr<string> }) {
17
- * const value = useWhisprValue(props.value);
18
- *
19
- * return <div>{value}</div>;
20
- * }
21
- */
22
- export function useWhisprValue<I, O = I>(
23
- w: Whispr<I>,
24
- computer: (data: I) => O = (d) => d as unknown as O
25
- ): O {
26
- const value_w = useRef(
27
- Whispr.from(
28
- { w },
29
- ({ w }) => computer(w)
30
- )
31
- ).current;
32
-
33
- const [value, setValue] = useState(value_w.value);
34
-
35
- value_w.subscribe((newValue) => {
36
- if (isEqual(newValue, value))
37
- return;
38
-
39
- setValue(newValue);
40
- }, false); // Already got the initial value, and this will call syncronously generate a react warning as called on an not yet mounted component
41
-
42
- return value;
43
- }
44
-
45
- /**
46
- * Wrap a (react) value into a Whispr, if it is not one already.
47
- * @param data A Whispr or a normal (react reactable) value
48
- * @returns The whispr'd value, or the original whispr if it was one (allow for incremental adoption)
49
- *
50
- * @remarks The returned whispr has already been ref-fed, so it can be directly used without worrying about react recreating it or similar bad things
51
- */
52
- export function useWhispr<T>(data: T | Whispr<T>): Whispr<T> {
53
- const [w, setW] = useRef(Whispr.create(
54
- data instanceof Whispr ?
55
- data.value :
56
- data
57
- )).current;
58
-
59
- useEffect(() => {
60
- setW(data instanceof Whispr ? data.value : data);
61
- }, [data, setW]);
62
-
63
- // Hooks can't be called conditionally, so we need to do this check at the end
64
- if (data instanceof Whispr)
65
- return data;
66
-
67
- return w;
68
- }
69
-
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useWhisprValue = useWhisprValue;
4
+ exports.useWhispr = useWhispr;
5
+ const whispr_1 = require("@cripty2001/whispr");
6
+ const react_1 = require("react");
7
+ const lodash_1 = require("lodash");
8
+ /**
9
+ * Convert a Whispr value into a reactive react value, usable in function components with the standard react reactive system.
10
+ * If the value is not a Whispr, it is returned as is, thus allowing for progressive migration and adoption
11
+ * @param w A reactive react value or a Whispr containing it
12
+ * @param computer An optional function to compute the returned value. This is useful to extract a part of a larger whispr, or to compute a derived value. It is the analog of useMemo with a single dependency (the whispr itself)
13
+ * @returns A reactive react value
14
+ *
15
+ * @remarks The value is NOT REACTIVE, and the same applies to the computer, if any. Only changes to its content will trigger a change, not changes to the object itself.
16
+ *
17
+ * @example
18
+ * export default function MyComponent(props: { value: Whispr<string> }) {
19
+ * const value = useWhisprValue(props.value);
20
+ *
21
+ * return <div>{value}</div>;
22
+ * }
23
+ */
24
+ function useWhisprValue(w, computer = (d) => d) {
25
+ const value_w = (0, react_1.useRef)(whispr_1.Whispr.from({ w }, ({ w }) => computer(w))).current;
26
+ const [value, setValue] = (0, react_1.useState)(value_w.value);
27
+ value_w.subscribe((newValue) => {
28
+ if ((0, lodash_1.isEqual)(newValue, value))
29
+ return;
30
+ setValue(newValue);
31
+ }, false); // Already got the initial value, and this will call syncronously generate a react warning as called on an not yet mounted component
32
+ return value;
33
+ }
34
+ /**
35
+ * Wrap a (react) value into a Whispr, if it is not one already.
36
+ * @param data A Whispr or a normal (react reactable) value
37
+ * @returns The whispr'd value, or the original whispr if it was one (allow for incremental adoption)
38
+ *
39
+ * @remarks The returned whispr has already been ref-fed, so it can be directly used without worrying about react recreating it or similar bad things
40
+ */
41
+ function useWhispr(data) {
42
+ const [w, setW] = (0, react_1.useRef)(whispr_1.Whispr.create(data instanceof whispr_1.Whispr ?
43
+ data.value :
44
+ data)).current;
45
+ (0, react_1.useEffect)(() => {
46
+ setW(data instanceof whispr_1.Whispr ? data.value : data);
47
+ }, [data, setW]);
48
+ // Hooks can't be called conditionally, so we need to do this check at the end
49
+ if (data instanceof whispr_1.Whispr)
50
+ return data;
51
+ return w;
52
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cripty2001/utils",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
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": {
@@ -18,6 +18,9 @@
18
18
  "test": "echo \"Error: no test specified\" && exit 1",
19
19
  "build": "tsc"
20
20
  },
21
+ "files": [
22
+ "dist"
23
+ ],
21
24
  "devDependencies": {
22
25
  "@types/react": "^19.1.8",
23
26
  "react": "^19.1.8",
package/src/index.ts DELETED
@@ -1,73 +0,0 @@
1
- export type JSONEncodable = number | string | boolean | JSONEncodable[] | { [key: string]: JSONEncodable };
2
-
3
- export type TypeofArray<T extends any[]> = T extends (infer U)[] ? U : never;
4
- export type TypeofRecord<T extends Record<string, any>> = T extends Record<
5
- string,
6
- infer U
7
- >
8
- ? U
9
- : never;
10
-
11
- export function getRandom(_alphabeth: string, length: number): string {
12
- const alphabeth = _alphabeth.split("");
13
- const toReturn: string[] = [];
14
- while (toReturn.length < length) {
15
- toReturn.push(alphabeth[Math.floor(Math.random() * alphabeth.length)]);
16
- }
17
- return toReturn.join("");
18
- }
19
-
20
- export function getRandomId(length: number = 20): string {
21
- const ALPHABET =
22
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
23
- return getRandom(ALPHABET, length);
24
- }
25
-
26
- export function getRandomOtp(
27
- length: number = 6,
28
- char: boolean = false
29
- ): string {
30
- const ALPHABET = "0123456789" + (char ? "ABCDEFGHIJKLMNOPQRSTUVWXYZ" : "");
31
- return getRandom(ALPHABET, length);
32
- }
33
-
34
- export function sleep(ms: number): Promise<void> {
35
- return new Promise((resolve) => setTimeout(resolve, ms));
36
- }
37
-
38
- export function parseHash(fields: string[]): URLSearchParams {
39
- // Checking empty hash
40
- if (window.location.hash === "") return new URLSearchParams();
41
-
42
- // Parsing hash
43
- const data = new URLSearchParams(window.location.hash.replace(/^#/, "?"));
44
-
45
- // Extracting fields
46
- const toReturn: URLSearchParams = new URLSearchParams();
47
- for (const field of fields) {
48
- if (data.has(field)) {
49
- toReturn.set(field, data.get(field) as string);
50
- data.delete(field);
51
- }
52
- }
53
-
54
- // Reencoding hash without extracted fields
55
- window.location.hash = `#${data.toString()}`;
56
-
57
- // Returning extracted fields
58
- return toReturn;
59
- }
60
-
61
- export async function loop(cb: () => Promise<void>, interval: number, onError: (e: any) => Promise<void> = async (e) => { console.error(e) }): Promise<void> {
62
- while (true) {
63
- try {
64
- await cb();
65
- } catch (e) {
66
- await onError(e);
67
- }
68
- finally {
69
- await sleep(interval);
70
- }
71
- }
72
- }
73
-
package/tsconfig.json DELETED
@@ -1,14 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ESNext",
4
- "module": "NodeNext",
5
- "rootDir": "./src",
6
- "moduleResolution": "NodeNext",
7
- "declaration": true,
8
- "outDir": "./dist",
9
- "esModuleInterop": true,
10
- "forceConsistentCasingInFileNames": true,
11
- "strict": true,
12
- "skipLibCheck": true
13
- }
14
- }