stoic-store 0.0.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/dist/index.d.ts +2 -0
- package/dist/index.js +206 -0
- package/dist/plugins.d.ts +16 -0
- package/dist/plugins.js +89 -0
- package/dist/stoic-CTcIKsRK.d.ts +62 -0
- package/dist/tools.d.ts +5 -0
- package/dist/tools.js +14 -0
- package/package.json +62 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as StoicPlugin, i as CircularDependencyError, n as ActionMeta, o as createStore, r as ActionStatus, t as ActionContext } from "./stoic-CTcIKsRK.js";
|
|
2
|
+
export { type ActionContext, type ActionMeta, type ActionStatus, CircularDependencyError, type StoicPlugin, createStore };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { useRef, useSyncExternalStore } from "react";
|
|
2
|
+
//#region src/stoic.ts
|
|
3
|
+
var CircularDependencyError = class extends Error {
|
|
4
|
+
constructor(cycle) {
|
|
5
|
+
super(`Circular dependency detected:\n${cycle.join(" → ")}`);
|
|
6
|
+
this.name = "CircularDependencyError";
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
function findDerivedDependencyCycle(derivedKeys, dependencies) {
|
|
10
|
+
const derivedKeySet = new Set(derivedKeys);
|
|
11
|
+
const status = /* @__PURE__ */ new Map();
|
|
12
|
+
const path = [];
|
|
13
|
+
const visit = (node) => {
|
|
14
|
+
status.set(node, "visiting");
|
|
15
|
+
path.push(node);
|
|
16
|
+
for (const dep of dependencies.get(node) ?? []) {
|
|
17
|
+
if (!derivedKeySet.has(dep)) continue;
|
|
18
|
+
const depStatus = status.get(dep);
|
|
19
|
+
if (depStatus === "visiting") return [...path.slice(path.indexOf(dep)), dep];
|
|
20
|
+
if (depStatus === void 0) {
|
|
21
|
+
const found = visit(dep);
|
|
22
|
+
if (found) return found;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
path.pop();
|
|
26
|
+
status.set(node, "done");
|
|
27
|
+
return null;
|
|
28
|
+
};
|
|
29
|
+
for (const key of derivedKeys) if (!status.has(key)) {
|
|
30
|
+
const cycle = visit(key);
|
|
31
|
+
if (cycle) return cycle;
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
function internal__createStore(config) {
|
|
36
|
+
let state = { ...config.state };
|
|
37
|
+
const derivedEntries = Object.entries(config.derived ?? {});
|
|
38
|
+
const derivedKeys = derivedEntries.map(([key]) => key);
|
|
39
|
+
const plugins = config.plugins ?? [];
|
|
40
|
+
const runHooks = (hook, ...args) => {
|
|
41
|
+
for (const p of plugins) p[hook]?.(...args);
|
|
42
|
+
};
|
|
43
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
44
|
+
const dependencies = /* @__PURE__ */ new Map();
|
|
45
|
+
const recomputeDerived = (dirty) => {
|
|
46
|
+
let recomputedAny = false;
|
|
47
|
+
for (const [key, fn] of derivedEntries) {
|
|
48
|
+
const deps = dependencies.get(key);
|
|
49
|
+
if (!(dirty === null || deps === void 0 || [...deps].some((d) => dirty.has(d)))) continue;
|
|
50
|
+
recomputedAny = true;
|
|
51
|
+
const trackedKeys = /* @__PURE__ */ new Set();
|
|
52
|
+
const proxiedState = new Proxy(state, { get(target, prop, receiver) {
|
|
53
|
+
if (typeof prop === "string") trackedKeys.add(prop);
|
|
54
|
+
return Reflect.get(target, prop, receiver);
|
|
55
|
+
} });
|
|
56
|
+
const prevValue = state[key];
|
|
57
|
+
const newValue = fn(proxiedState);
|
|
58
|
+
dependencies.set(key, trackedKeys);
|
|
59
|
+
state[key] = newValue;
|
|
60
|
+
if (dirty !== null && !Object.is(prevValue, newValue)) dirty.add(key);
|
|
61
|
+
}
|
|
62
|
+
if (recomputedAny) {
|
|
63
|
+
const cycle = findDerivedDependencyCycle(derivedKeys, dependencies);
|
|
64
|
+
if (cycle) throw new CircularDependencyError(cycle);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
recomputeDerived(null);
|
|
68
|
+
const getState = () => state;
|
|
69
|
+
const setState = (partial) => {
|
|
70
|
+
const prevState = state;
|
|
71
|
+
const next = typeof partial === "function" ? partial(state) : partial;
|
|
72
|
+
runHooks("beforeSetState", next);
|
|
73
|
+
state = {
|
|
74
|
+
...state,
|
|
75
|
+
...next
|
|
76
|
+
};
|
|
77
|
+
const dirty = /* @__PURE__ */ new Set();
|
|
78
|
+
for (const key of Object.keys(next)) if (!Object.is(prevState[key], state[key])) dirty.add(key);
|
|
79
|
+
recomputeDerived(dirty);
|
|
80
|
+
runHooks("afterSetState", state);
|
|
81
|
+
listeners.forEach((l) => {
|
|
82
|
+
l(state);
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
const subscribe = (listener) => {
|
|
86
|
+
listeners.add(listener);
|
|
87
|
+
return () => listeners.delete(listener);
|
|
88
|
+
};
|
|
89
|
+
const createActionRunner = (name, fn) => {
|
|
90
|
+
let meta = {
|
|
91
|
+
status: "idle",
|
|
92
|
+
error: void 0
|
|
93
|
+
};
|
|
94
|
+
const metaListeners = /* @__PURE__ */ new Set();
|
|
95
|
+
const setMeta = (next) => {
|
|
96
|
+
if (meta.status === next.status && meta.error === next.error) return;
|
|
97
|
+
meta = next;
|
|
98
|
+
metaListeners.forEach((l) => {
|
|
99
|
+
l(meta);
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
const runner = (...args) => {
|
|
103
|
+
const ctx = {
|
|
104
|
+
name,
|
|
105
|
+
args,
|
|
106
|
+
state: getState()
|
|
107
|
+
};
|
|
108
|
+
runHooks("beforeAction", ctx);
|
|
109
|
+
const finish = () => {
|
|
110
|
+
runHooks("afterAction", {
|
|
111
|
+
name,
|
|
112
|
+
args,
|
|
113
|
+
state: getState()
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
setMeta({
|
|
117
|
+
status: "pending",
|
|
118
|
+
error: void 0
|
|
119
|
+
});
|
|
120
|
+
let result;
|
|
121
|
+
try {
|
|
122
|
+
result = fn(setState, ...args);
|
|
123
|
+
} catch (err) {
|
|
124
|
+
finish();
|
|
125
|
+
setMeta({
|
|
126
|
+
status: "error",
|
|
127
|
+
error: err
|
|
128
|
+
});
|
|
129
|
+
throw err;
|
|
130
|
+
}
|
|
131
|
+
if (result instanceof Promise) return result.then((value) => {
|
|
132
|
+
finish();
|
|
133
|
+
setMeta({
|
|
134
|
+
status: "success",
|
|
135
|
+
error: void 0
|
|
136
|
+
});
|
|
137
|
+
return value;
|
|
138
|
+
}, (err) => {
|
|
139
|
+
finish();
|
|
140
|
+
setMeta({
|
|
141
|
+
status: "error",
|
|
142
|
+
error: err
|
|
143
|
+
});
|
|
144
|
+
throw err;
|
|
145
|
+
});
|
|
146
|
+
finish();
|
|
147
|
+
setMeta({
|
|
148
|
+
status: "success",
|
|
149
|
+
error: void 0
|
|
150
|
+
});
|
|
151
|
+
return result;
|
|
152
|
+
};
|
|
153
|
+
runner.getMeta = () => meta;
|
|
154
|
+
runner.subscribeMeta = (listener) => {
|
|
155
|
+
metaListeners.add(listener);
|
|
156
|
+
return () => metaListeners.delete(listener);
|
|
157
|
+
};
|
|
158
|
+
return runner;
|
|
159
|
+
};
|
|
160
|
+
const actions = ((map) => {
|
|
161
|
+
const result = {};
|
|
162
|
+
for (const [name, fn] of Object.entries(map)) result[name] = createActionRunner(name, fn);
|
|
163
|
+
return result;
|
|
164
|
+
});
|
|
165
|
+
const destroy = () => {
|
|
166
|
+
runHooks("onDestroy");
|
|
167
|
+
listeners.clear();
|
|
168
|
+
};
|
|
169
|
+
const store = {
|
|
170
|
+
getState,
|
|
171
|
+
setState,
|
|
172
|
+
subscribe,
|
|
173
|
+
actions,
|
|
174
|
+
destroy
|
|
175
|
+
};
|
|
176
|
+
runHooks("onInit", store);
|
|
177
|
+
return store;
|
|
178
|
+
}
|
|
179
|
+
function createStore(config) {
|
|
180
|
+
const store = internal__createStore(config);
|
|
181
|
+
function useStore(selector = (s) => s, equality = Object.is) {
|
|
182
|
+
const selectedRef = useRef(selector(store.getState()));
|
|
183
|
+
return useSyncExternalStore(store.subscribe, () => {
|
|
184
|
+
const next = selector(store.getState());
|
|
185
|
+
if (!equality(selectedRef.current, next)) selectedRef.current = next;
|
|
186
|
+
return selectedRef.current;
|
|
187
|
+
}, () => selector(store.getState()));
|
|
188
|
+
}
|
|
189
|
+
const actions = ((map) => {
|
|
190
|
+
const runners = store.actions(map);
|
|
191
|
+
for (const runner of Object.values(runners)) runner.useMeta = () => useSyncExternalStore(runner.subscribeMeta, runner.getMeta, runner.getMeta);
|
|
192
|
+
return runners;
|
|
193
|
+
});
|
|
194
|
+
return {
|
|
195
|
+
useStore,
|
|
196
|
+
getState: store.getState,
|
|
197
|
+
setState: store.setState,
|
|
198
|
+
subscribe: store.subscribe,
|
|
199
|
+
actions,
|
|
200
|
+
destroy: store.destroy
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
//#endregion
|
|
204
|
+
export { CircularDependencyError, createStore };
|
|
205
|
+
|
|
206
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { a as StoicPlugin } from "./stoic-CTcIKsRK.js";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/persist.d.ts
|
|
4
|
+
declare function persist<T extends object>(options: {
|
|
5
|
+
key: string;
|
|
6
|
+
storage?: () => Storage;
|
|
7
|
+
include?: (keyof T)[];
|
|
8
|
+
exclude?: (keyof T)[];
|
|
9
|
+
serialize?: (state: Partial<T>) => string;
|
|
10
|
+
deserialize?: (raw: string) => Partial<T>;
|
|
11
|
+
debounceMs?: number;
|
|
12
|
+
throttleMs?: number;
|
|
13
|
+
}): StoicPlugin<T, T>;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { persist };
|
|
16
|
+
//# sourceMappingURL=plugins.d.ts.map
|
package/dist/plugins.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
//#region src/plugins/persist.ts
|
|
2
|
+
function filterKeys(state, options) {
|
|
3
|
+
if (options.include) {
|
|
4
|
+
const result = {};
|
|
5
|
+
for (const key of options.include) result[key] = state[key];
|
|
6
|
+
return result;
|
|
7
|
+
}
|
|
8
|
+
if (options.exclude) {
|
|
9
|
+
const excluded = new Set(options.exclude);
|
|
10
|
+
const result = {};
|
|
11
|
+
for (const key of Object.keys(state)) if (!excluded.has(key)) result[key] = state[key];
|
|
12
|
+
return result;
|
|
13
|
+
}
|
|
14
|
+
return state;
|
|
15
|
+
}
|
|
16
|
+
function persist(options) {
|
|
17
|
+
if (options.include && options.exclude) throw new Error("persist: pass either `include` or `exclude`, not both");
|
|
18
|
+
if (options.debounceMs !== void 0 && options.throttleMs !== void 0) throw new Error("persist: pass either `debounceMs` or `throttleMs`, not both");
|
|
19
|
+
const getStorage = options.storage ?? (() => localStorage);
|
|
20
|
+
const doSerialize = options.serialize ?? JSON.stringify;
|
|
21
|
+
const doDeserialize = options.deserialize ?? JSON.parse;
|
|
22
|
+
const writeToStorage = (state) => {
|
|
23
|
+
try {
|
|
24
|
+
getStorage().setItem(options.key, doSerialize(filterKeys(state, options)));
|
|
25
|
+
} catch {
|
|
26
|
+
console.warn("Stoic persist plugin: failed to write state to storage");
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
let debounceTimer;
|
|
30
|
+
let pendingState;
|
|
31
|
+
let throttleTimer;
|
|
32
|
+
let lastWriteTime = 0;
|
|
33
|
+
return {
|
|
34
|
+
onInit(store) {
|
|
35
|
+
try {
|
|
36
|
+
const raw = getStorage().getItem(options.key);
|
|
37
|
+
if (raw != null) {
|
|
38
|
+
const parsed = doDeserialize(raw);
|
|
39
|
+
store.setState(filterKeys(parsed, options));
|
|
40
|
+
}
|
|
41
|
+
} catch {
|
|
42
|
+
console.warn("Stoic persist plugin: failed to read state from storage");
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
afterSetState(state) {
|
|
46
|
+
if (options.debounceMs !== void 0) {
|
|
47
|
+
pendingState = state;
|
|
48
|
+
if (debounceTimer !== void 0) clearTimeout(debounceTimer);
|
|
49
|
+
debounceTimer = setTimeout(() => {
|
|
50
|
+
debounceTimer = void 0;
|
|
51
|
+
writeToStorage(state);
|
|
52
|
+
}, options.debounceMs);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (options.throttleMs !== void 0) {
|
|
56
|
+
pendingState = state;
|
|
57
|
+
const elapsed = Date.now() - lastWriteTime;
|
|
58
|
+
if (elapsed >= options.throttleMs) {
|
|
59
|
+
lastWriteTime = Date.now();
|
|
60
|
+
writeToStorage(state);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (throttleTimer === void 0) throttleTimer = setTimeout(() => {
|
|
64
|
+
throttleTimer = void 0;
|
|
65
|
+
lastWriteTime = Date.now();
|
|
66
|
+
writeToStorage(pendingState);
|
|
67
|
+
}, options.throttleMs - elapsed);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
writeToStorage(state);
|
|
71
|
+
},
|
|
72
|
+
onDestroy() {
|
|
73
|
+
if (debounceTimer !== void 0) {
|
|
74
|
+
clearTimeout(debounceTimer);
|
|
75
|
+
debounceTimer = void 0;
|
|
76
|
+
writeToStorage(pendingState);
|
|
77
|
+
}
|
|
78
|
+
if (throttleTimer !== void 0) {
|
|
79
|
+
clearTimeout(throttleTimer);
|
|
80
|
+
throttleTimer = void 0;
|
|
81
|
+
writeToStorage(pendingState);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
export { persist };
|
|
88
|
+
|
|
89
|
+
//# sourceMappingURL=plugins.js.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
//#region src/stoic.d.ts
|
|
2
|
+
type Listener<T> = (state: T) => void;
|
|
3
|
+
type DerivedConfig<T, D> = { [K in keyof D]: (state: T & D) => D[K] };
|
|
4
|
+
declare class CircularDependencyError extends Error {
|
|
5
|
+
constructor(cycle: string[]);
|
|
6
|
+
}
|
|
7
|
+
type SetState<T, Full = T> = (partial: Partial<T> | ((s: Full) => Partial<T>)) => void;
|
|
8
|
+
type SyncActionFn<T, Full, A extends unknown[]> = (setState: SetState<T, Full>, ...args: A) => void;
|
|
9
|
+
type AsyncActionFn<T, Full, A extends unknown[]> = (setState: SetState<T, Full>, ...args: A) => Promise<void>;
|
|
10
|
+
type ActionStatus = "idle" | "pending" | "success" | "error";
|
|
11
|
+
type ActionMeta = {
|
|
12
|
+
status: ActionStatus;
|
|
13
|
+
error: unknown;
|
|
14
|
+
};
|
|
15
|
+
type ActionHandle<A extends unknown[], R> = ((...args: A) => R) & {
|
|
16
|
+
getMeta: () => ActionMeta;
|
|
17
|
+
subscribeMeta: (listener: (meta: ActionMeta) => void) => () => void;
|
|
18
|
+
};
|
|
19
|
+
type ActionMap<T, Full> = Record<string, SyncActionFn<T, Full, any> | AsyncActionFn<T, Full, any>>;
|
|
20
|
+
type ActionHandlesFor<M extends ActionMap<unknown, unknown>, T, Full> = { [K in keyof M]: M[K] extends AsyncActionFn<T, Full, infer A> ? ActionHandle<A, Promise<void>> : M[K] extends SyncActionFn<T, Full, infer A> ? ActionHandle<A, void> : never };
|
|
21
|
+
type StoicStore<T, Full = T> = {
|
|
22
|
+
getState: () => Full;
|
|
23
|
+
setState: SetState<T, Full>;
|
|
24
|
+
subscribe: (listener: Listener<Full>) => () => void;
|
|
25
|
+
actions<M extends ActionMap<T, Full>>(map: M): ActionHandlesFor<M, T, Full>;
|
|
26
|
+
destroy: () => void;
|
|
27
|
+
};
|
|
28
|
+
type ActionContext<Full = unknown> = {
|
|
29
|
+
name: string;
|
|
30
|
+
args: unknown[];
|
|
31
|
+
state: Full;
|
|
32
|
+
};
|
|
33
|
+
interface StoicPlugin<T extends object = object, Full extends object = T> {
|
|
34
|
+
onInit?(store: StoicStore<T, Full>): void;
|
|
35
|
+
beforeAction?(ctx: ActionContext<Full>): void;
|
|
36
|
+
afterAction?(ctx: ActionContext<Full>): void;
|
|
37
|
+
beforeSetState?(nextState: Partial<T>): void;
|
|
38
|
+
afterSetState?(state: Full): void;
|
|
39
|
+
onDestroy?(): void;
|
|
40
|
+
}
|
|
41
|
+
type UseStore<Full> = <U = Full>(selector?: (state: Full) => U, equality?: (a: U, b: U) => boolean) => U;
|
|
42
|
+
type ActionHandleWithHook<A extends unknown[], R> = ActionHandle<A, R> & {
|
|
43
|
+
useMeta: () => ActionMeta;
|
|
44
|
+
};
|
|
45
|
+
type ActionHandlesWithHookFor<M extends ActionMap<unknown, unknown>, T, Full> = { [K in keyof M]: M[K] extends AsyncActionFn<T, Full, infer A> ? ActionHandleWithHook<A, Promise<void>> : M[K] extends SyncActionFn<T, Full, infer A> ? ActionHandleWithHook<A, void> : never };
|
|
46
|
+
type StoicHookedStore<T, Full> = Omit<StoicStore<T, Full>, "actions"> & {
|
|
47
|
+
useStore: UseStore<Full>;
|
|
48
|
+
actions<M extends ActionMap<T, Full>>(map: M): ActionHandlesWithHookFor<M, T, Full>;
|
|
49
|
+
};
|
|
50
|
+
declare function createStore<T extends object>(config: {
|
|
51
|
+
state: T;
|
|
52
|
+
derived?: undefined;
|
|
53
|
+
plugins?: StoicPlugin<T, T>[];
|
|
54
|
+
}): StoicHookedStore<T, T>;
|
|
55
|
+
declare function createStore<T extends object, D extends object>(config: {
|
|
56
|
+
state: T;
|
|
57
|
+
derived: DerivedConfig<T, D>;
|
|
58
|
+
plugins?: StoicPlugin<T, T & D>[];
|
|
59
|
+
}): StoicHookedStore<T, T & D>;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { StoicPlugin as a, CircularDependencyError as i, ActionMeta as n, createStore as o, ActionStatus as r, ActionContext as t };
|
|
62
|
+
//# sourceMappingURL=stoic-CTcIKsRK.d.ts.map
|
package/dist/tools.d.ts
ADDED
package/dist/tools.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/tools/shallow.ts
|
|
2
|
+
function shallow(a, b) {
|
|
3
|
+
if (Object.is(a, b)) return true;
|
|
4
|
+
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) return false;
|
|
5
|
+
const keysA = Object.keys(a);
|
|
6
|
+
const keysB = Object.keys(b);
|
|
7
|
+
if (keysA.length !== keysB.length) return false;
|
|
8
|
+
for (const key of keysA) if (!Object.hasOwn(b, key) || !Object.is(a[key], b[key])) return false;
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { shallow };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=tools.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "stoic-store",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"description": "Minimal and powerful React state manager. Tiny, intuitive, and fully TypeScript-ready.",
|
|
6
|
+
"author": "peakercope <peakercope@gmail.com> (https://github.com/peakercope)",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"react",
|
|
10
|
+
"state",
|
|
11
|
+
"state-management",
|
|
12
|
+
"store",
|
|
13
|
+
"derived-state",
|
|
14
|
+
"typescript"
|
|
15
|
+
],
|
|
16
|
+
"homepage": "https://github.com/peakercope/stoic#readme",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/peakercope/stoic.git",
|
|
20
|
+
"directory": "packages/stoic"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/peakercope/stoic/issues"
|
|
24
|
+
},
|
|
25
|
+
"exports": {
|
|
26
|
+
".": "./dist/index.js",
|
|
27
|
+
"./plugins": "./dist/plugins.js",
|
|
28
|
+
"./tools": "./dist/tools.js",
|
|
29
|
+
"./package.json": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"sideEffects": false,
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"!dist/**/*.map"
|
|
36
|
+
],
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsdown",
|
|
42
|
+
"dev": "tsdown --watch",
|
|
43
|
+
"test": "vitest",
|
|
44
|
+
"typecheck": "tsc --noEmit"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"react": "^18.0.0",
|
|
48
|
+
"react-dom": "^18.0.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/react": "^18.0.0",
|
|
52
|
+
"@types/react-dom": "^18.0.0",
|
|
53
|
+
"@vitejs/plugin-react": "^6.0.1",
|
|
54
|
+
"@vitest/coverage-v8": "^4.1.9",
|
|
55
|
+
"happy-dom": "^20.8.4",
|
|
56
|
+
"react": "^18.0.0",
|
|
57
|
+
"react-dom": "^18.0.0",
|
|
58
|
+
"tsdown": "^0.22.3",
|
|
59
|
+
"vite": "^8.1.3",
|
|
60
|
+
"vitest": "^4.1.9"
|
|
61
|
+
}
|
|
62
|
+
}
|