floppy-disk 2.0.0-beta.2 → 2.0.0-beta.3

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,337 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createQuery = void 0;
4
+ const hooks_1 = require("preact/hooks");
5
+ const utils_1 = require("../utils");
6
+ const create_stores_1 = require("./create-stores");
7
+ const getDecision = (value, param, { ifTrue, ifAlways }) => {
8
+ if (value === true || (typeof value === 'function' && value(param) === true)) {
9
+ ifTrue();
10
+ }
11
+ else if (value === 'always' || (typeof value === 'function' && value(param) === 'always')) {
12
+ ifAlways();
13
+ }
14
+ };
15
+ const DEFAULT_STALE_TIME = 3000; // 3 seconds
16
+ const INITIAL_QUERY_STATE = {
17
+ isWaiting: false,
18
+ isWaitingNextPage: false,
19
+ status: 'loading',
20
+ isLoading: true,
21
+ isSuccess: false,
22
+ isError: false,
23
+ isRefetching: false,
24
+ isRefetchError: false,
25
+ isPreviousData: false,
26
+ isOptimisticData: false,
27
+ data: null,
28
+ response: null,
29
+ responseUpdatedAt: null,
30
+ error: null,
31
+ errorUpdatedAt: null,
32
+ retryCount: 0,
33
+ isGoingToRetry: false,
34
+ pageParam: undefined,
35
+ pageParams: [undefined],
36
+ hasNextPage: false,
37
+ retryNextPageCount: 0,
38
+ isGoingToRetryNextPage: false,
39
+ };
40
+ const useQueryDefaultDeps = (state) => [
41
+ state.data,
42
+ state.error,
43
+ state.isWaitingNextPage,
44
+ state.hasNextPage,
45
+ ];
46
+ const createQuery = (queryFn, options = {}) => {
47
+ const { onFirstSubscribe = utils_1.noop, onSubscribe = utils_1.noop, onLastUnsubscribe = utils_1.noop, onBeforeChangeKey = utils_1.noop, defaultDeps = useQueryDefaultDeps, select = utils_1.identityFn, staleTime = DEFAULT_STALE_TIME, fetchOnMount = true, fetchOnWindowFocus = true, enabled = true, retry = 1, retryDelay = 3000, keepPreviousData, getNextPageParam = () => undefined, onSuccess = utils_1.noop, onError = utils_1.noop, onSettled = utils_1.noop, hashKeyFn = utils_1.hashStoreKey, ...createStoresOptions } = options;
48
+ const retryTimeoutId = new Map();
49
+ const retryNextPageTimeoutId = new Map();
50
+ const preventReplaceResponse = new Map(); // Prevent optimistic data to be replaced
51
+ const useQuery = (0, create_stores_1.createStores)(({ key: _key, get, set }) => {
52
+ const key = _key;
53
+ const getRetryProps = (error, retryCount) => {
54
+ const maxRetryCount = (typeof retry === 'function' ? retry(error, key) : retry) || 0;
55
+ const shouldRetry = retryCount < maxRetryCount;
56
+ const delay = (typeof retryDelay === 'function' ? retryDelay(error, key) : retryDelay) || 0;
57
+ return { shouldRetry, delay };
58
+ };
59
+ const forceFetch = () => {
60
+ const responseAllPages = [];
61
+ const newPageParams = [undefined];
62
+ let pageParam = undefined;
63
+ const { isWaiting, isLoading, pageParams } = get();
64
+ if (isWaiting || enabled === false || (typeof enabled === 'function' && !enabled(key)))
65
+ return;
66
+ if (isLoading)
67
+ set({ isWaiting: true });
68
+ else
69
+ set({ isWaiting: true, isRefetching: true });
70
+ const callQuery = () => {
71
+ if (get().isGoingToRetry) {
72
+ if (isLoading)
73
+ set({ isGoingToRetry: false, isWaiting: true });
74
+ else
75
+ set({ isGoingToRetry: false, isWaiting: true, isRefetching: true });
76
+ clearTimeout(retryTimeoutId.get(hashKeyFn(key)));
77
+ }
78
+ const stateBeforeCallQuery = { ...get(), pageParam };
79
+ preventReplaceResponse.set(hashKeyFn(key), false);
80
+ queryFn(key, stateBeforeCallQuery)
81
+ .then((response) => {
82
+ if (preventReplaceResponse.get(hashKeyFn(key))) {
83
+ set({ isWaiting: false });
84
+ return;
85
+ }
86
+ responseAllPages.push(response);
87
+ const newPageParam = getNextPageParam(response, responseAllPages.length);
88
+ newPageParams.push(newPageParam);
89
+ if (newPageParam !== undefined && newPageParams.length < pageParams.length) {
90
+ pageParam = newPageParam;
91
+ callQuery();
92
+ return;
93
+ }
94
+ set({
95
+ isWaiting: false,
96
+ status: 'success',
97
+ isLoading: false,
98
+ isSuccess: true,
99
+ isError: false,
100
+ isRefetching: false,
101
+ isRefetchError: false,
102
+ isPreviousData: false,
103
+ isOptimisticData: false,
104
+ data: responseAllPages.reduce((prev, responseCurrentPage) => {
105
+ return select(responseCurrentPage, { key, data: prev });
106
+ }, null),
107
+ response,
108
+ responseUpdatedAt: Date.now(),
109
+ error: null,
110
+ errorUpdatedAt: null,
111
+ retryCount: 0,
112
+ pageParam: newPageParam,
113
+ pageParams: newPageParams,
114
+ hasNextPage: newPageParam !== undefined,
115
+ });
116
+ onSuccess(response, stateBeforeCallQuery);
117
+ })
118
+ .catch((error) => {
119
+ const prevState = get();
120
+ const errorUpdatedAt = Date.now();
121
+ const { shouldRetry, delay } = getRetryProps(error, prevState.retryCount);
122
+ set(prevState.isSuccess
123
+ ? {
124
+ isWaiting: false,
125
+ isRefetching: false,
126
+ isRefetchError: true,
127
+ data: responseAllPages.length
128
+ ? responseAllPages.reduce((prev, response) => {
129
+ return select(response, { key, data: prev });
130
+ }, null)
131
+ : prevState.data,
132
+ error,
133
+ errorUpdatedAt,
134
+ isGoingToRetry: shouldRetry,
135
+ pageParam,
136
+ hasNextPage: pageParam !== undefined,
137
+ }
138
+ : {
139
+ isWaiting: false,
140
+ isError: true,
141
+ error,
142
+ errorUpdatedAt,
143
+ isGoingToRetry: shouldRetry,
144
+ pageParam,
145
+ hasNextPage: pageParam !== undefined,
146
+ });
147
+ if (shouldRetry) {
148
+ retryTimeoutId.set(hashKeyFn(key), window.setTimeout(() => {
149
+ set({ retryCount: prevState.retryCount + 1 });
150
+ callQuery();
151
+ }, delay));
152
+ }
153
+ onError(error, stateBeforeCallQuery);
154
+ })
155
+ .finally(() => {
156
+ onSettled(stateBeforeCallQuery);
157
+ });
158
+ };
159
+ callQuery();
160
+ };
161
+ const fetch = () => {
162
+ const { responseUpdatedAt } = get();
163
+ const isStale = Date.now() > Number(responseUpdatedAt) + staleTime;
164
+ if (!isStale)
165
+ return;
166
+ forceFetch();
167
+ };
168
+ const fetchNextPage = () => {
169
+ const state = get();
170
+ const { isLoading, isWaitingNextPage, data, hasNextPage, pageParam, pageParams } = state;
171
+ if (isLoading)
172
+ return forceFetch();
173
+ if (isWaitingNextPage || !hasNextPage)
174
+ return;
175
+ set({ isWaitingNextPage: true, isGoingToRetryNextPage: false });
176
+ clearTimeout(retryNextPageTimeoutId.get(hashKeyFn(key)));
177
+ queryFn(key, { ...state, pageParam })
178
+ .then((response) => {
179
+ const newPageParam = getNextPageParam(response, pageParams.length);
180
+ set({
181
+ isWaitingNextPage: false,
182
+ response,
183
+ responseUpdatedAt: Date.now(),
184
+ data: select(response, { key, data }),
185
+ pageParam: newPageParam,
186
+ pageParams: pageParams.concat(newPageParam),
187
+ hasNextPage: newPageParam !== undefined,
188
+ });
189
+ })
190
+ .catch((error) => {
191
+ const prevState = get();
192
+ const { shouldRetry, delay } = getRetryProps(error, prevState.retryNextPageCount);
193
+ set({
194
+ isWaitingNextPage: false,
195
+ isError: true,
196
+ error,
197
+ errorUpdatedAt: Date.now(),
198
+ isGoingToRetryNextPage: shouldRetry,
199
+ });
200
+ if (shouldRetry) {
201
+ retryNextPageTimeoutId.set(hashKeyFn(key), window.setTimeout(() => {
202
+ set({ retryNextPageCount: prevState.retryNextPageCount + 1 });
203
+ fetchNextPage();
204
+ }, delay));
205
+ }
206
+ });
207
+ };
208
+ return {
209
+ ...INITIAL_QUERY_STATE,
210
+ key,
211
+ fetch,
212
+ forceFetch,
213
+ fetchNextPage,
214
+ reset: () => set(INITIAL_QUERY_STATE),
215
+ optimisticUpdate: (response) => useQuery.optimisticUpdate({ key, response }),
216
+ };
217
+ }, (() => {
218
+ const fetchWindowFocusHandler = () => {
219
+ useQuery.getAllWithSubscriber().forEach((state) => {
220
+ getDecision(fetchOnWindowFocus, state.key, {
221
+ ifTrue: state.fetch,
222
+ ifAlways: state.forceFetch,
223
+ });
224
+ });
225
+ };
226
+ return {
227
+ ...createStoresOptions,
228
+ defaultDeps,
229
+ hashKeyFn,
230
+ onFirstSubscribe: (state) => {
231
+ if (typeof window !== 'undefined' && fetchOnWindowFocus) {
232
+ window.addEventListener('focus', fetchWindowFocusHandler);
233
+ }
234
+ onFirstSubscribe(state);
235
+ },
236
+ onSubscribe: (state) => {
237
+ getDecision(fetchOnMount, state.key, {
238
+ ifTrue: state.fetch,
239
+ ifAlways: state.forceFetch,
240
+ });
241
+ onSubscribe(state);
242
+ },
243
+ onLastUnsubscribe: (state) => {
244
+ if (typeof window !== 'undefined' && fetchOnWindowFocus) {
245
+ window.removeEventListener('focus', fetchWindowFocusHandler);
246
+ }
247
+ useQuery.set(state.key, { retryCount: 0, retryNextPageCount: 0 }, true);
248
+ clearTimeout(retryTimeoutId.get(hashKeyFn(state.key)));
249
+ clearTimeout(retryNextPageTimeoutId.get(hashKeyFn(state.key)));
250
+ onLastUnsubscribe(state);
251
+ },
252
+ onBeforeChangeKey: (nextKey, prevKey) => {
253
+ if (keepPreviousData) {
254
+ const nextData = useQuery.get(nextKey);
255
+ if (!nextData.data) {
256
+ const prevData = useQuery.get(prevKey);
257
+ if (prevData.data) {
258
+ useQuery.set(nextKey, {
259
+ data: prevData.data,
260
+ response: prevData.response,
261
+ isLoading: false,
262
+ isPreviousData: true,
263
+ }, true);
264
+ }
265
+ }
266
+ }
267
+ onBeforeChangeKey(nextKey, prevKey);
268
+ },
269
+ };
270
+ })());
271
+ useQuery.setInitialResponse = ({ key, response }) => {
272
+ // eslint-disable-next-line react-hooks/rules-of-hooks
273
+ (0, hooks_1.useState)(() => {
274
+ if (response === undefined)
275
+ return;
276
+ const newPageParam = getNextPageParam(response, 1);
277
+ useQuery.set(key, {
278
+ status: 'success',
279
+ isLoading: false,
280
+ isSuccess: true,
281
+ isError: false,
282
+ response,
283
+ responseUpdatedAt: Date.now(),
284
+ data: select(response, { key: key, data: null }),
285
+ pageParam: newPageParam,
286
+ pageParams: [undefined, newPageParam],
287
+ hasNextPage: newPageParam !== undefined,
288
+ });
289
+ });
290
+ };
291
+ useQuery.reset = () => {
292
+ useQuery.getStores().forEach((store) => {
293
+ store.set(INITIAL_QUERY_STATE);
294
+ });
295
+ };
296
+ useQuery.resetSpecificKey = (key) => {
297
+ const store = useQuery.getStore(key);
298
+ store.set(INITIAL_QUERY_STATE);
299
+ };
300
+ useQuery.invalidate = () => {
301
+ useQuery.getStores().forEach((store) => {
302
+ const { set, getSubscribers } = store;
303
+ set({ responseUpdatedAt: null });
304
+ if (getSubscribers().size > 0)
305
+ store.get().forceFetch();
306
+ });
307
+ };
308
+ useQuery.invalidateSpecificKey = (key) => {
309
+ const { set, getSubscribers } = useQuery.getStore(key);
310
+ set({ responseUpdatedAt: null });
311
+ if (getSubscribers().size > 0)
312
+ useQuery.get(key).forceFetch();
313
+ };
314
+ useQuery.optimisticUpdate = ({ key, response }) => {
315
+ const prevState = useQuery.get(key);
316
+ const optimisticResponse = typeof response === 'function'
317
+ ? response(prevState)
318
+ : response;
319
+ useQuery.set(key, {
320
+ isOptimisticData: true,
321
+ response: optimisticResponse,
322
+ data: select(optimisticResponse, { key: key, data: null }),
323
+ });
324
+ preventReplaceResponse.set(hashKeyFn(key), true);
325
+ const revert = () => {
326
+ useQuery.set(key, {
327
+ isOptimisticData: false,
328
+ response: prevState.response,
329
+ data: prevState.data,
330
+ });
331
+ };
332
+ const invalidate = () => useQuery.invalidateSpecificKey(key);
333
+ return { revert, invalidate };
334
+ };
335
+ return useQuery;
336
+ };
337
+ exports.createQuery = createQuery;
@@ -0,0 +1,28 @@
1
+ import { InitStoreOptions, SelectDeps, SetStoreData, StoreData, StoreInitializer, Subscribers } from '../vanilla';
2
+ export type WatchProps<T> = {
3
+ selectDeps?: SelectDeps<T>;
4
+ render: (state: T) => any;
5
+ };
6
+ export type UseStore<T extends StoreData> = {
7
+ /**
8
+ * @param selectDeps A function that return the dependency array (just like in `useEffect`), to trigger reactivity.
9
+ * Defaults to `undefined` (reactive to all state change) if you didn't set `defaultDeps` on `createStore`.
10
+ *
11
+ * IMPORTANT NOTE: `selectDeps` must not be changed after initialization.
12
+ */
13
+ (selectDeps?: SelectDeps<T>): T;
14
+ get: () => T;
15
+ set: (value: SetStoreData<T>, silent?: boolean) => void;
16
+ subscribe: (fn: (state: T) => void, selectDeps?: SelectDeps<T>) => () => void;
17
+ getSubscribers: () => Subscribers<T>;
18
+ /**
19
+ * Set default values inside a component.
20
+ *
21
+ * IMPORTANT NOTE: Put this on the root component or parent component, before any component subscribed!
22
+ */
23
+ setDefaultValues: (values: SetStoreData<T>) => void;
24
+ Watch: (props: WatchProps<T>) => any;
25
+ };
26
+ export declare const createStore: <T extends StoreData>(initializer: StoreInitializer<T>, options?: InitStoreOptions<T> & {
27
+ defaultDeps?: SelectDeps<T>;
28
+ }) => UseStore<T>;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createStore = void 0;
4
+ const hooks_1 = require("preact/hooks");
5
+ const vanilla_1 = require("../vanilla");
6
+ const createStore = (initializer, options = {}) => {
7
+ const { get, set, subscribe, getSubscribers } = (0, vanilla_1.initStore)(initializer, options);
8
+ const { defaultDeps } = options;
9
+ /**
10
+ * IMPORTANT NOTE: selectDeps function must not be changed after initialization.
11
+ */
12
+ const useStore = (selectDeps = defaultDeps) => {
13
+ const [state, setState] = (0, hooks_1.useState)(get);
14
+ // eslint-disable-next-line react-hooks/exhaustive-deps
15
+ (0, hooks_1.useEffect)(() => subscribe(setState, selectDeps), []);
16
+ return state;
17
+ };
18
+ useStore.get = get;
19
+ useStore.set = set;
20
+ useStore.subscribe = subscribe;
21
+ useStore.getSubscribers = getSubscribers;
22
+ useStore.setDefaultValues = (value) => {
23
+ // eslint-disable-next-line react-hooks/rules-of-hooks
24
+ (0, hooks_1.useState)(() => {
25
+ const subscribers = getSubscribers();
26
+ if (subscribers.size > 0) {
27
+ console.warn('Put setDefaultValues on the root component or parent component, before any component subscribed!');
28
+ }
29
+ set(value);
30
+ });
31
+ };
32
+ const Watch = ({ selectDeps, render }) => {
33
+ const store = useStore(selectDeps);
34
+ return render(store);
35
+ };
36
+ useStore.Watch = Watch;
37
+ return useStore;
38
+ };
39
+ exports.createStore = createStore;
@@ -0,0 +1,45 @@
1
+ import { InitStoreOptions, InitStoreReturn, SelectDeps, SetStoreData, StoreData, Subscribers } from '../vanilla';
2
+ import { WatchProps } from './create-store';
3
+ type Maybe<T> = T | null | undefined;
4
+ export type StoreKey = Record<string, any> | undefined;
5
+ export type StoresInitializer<TKey extends StoreKey = StoreKey, T extends StoreData = StoreData> = (api: {
6
+ key: TKey;
7
+ get: () => T;
8
+ set: (value: SetStoreData<T>, silent?: boolean) => void;
9
+ }) => T;
10
+ export type UseStores<TKey extends StoreKey = StoreKey, T extends StoreData = StoreData> = {
11
+ /**
12
+ * @param key (Optional) Store key, an object that will be hashed into a string as a store identifier.
13
+ *
14
+ * @param selectDeps A function that return the dependency array (just like in `useEffect`), to trigger reactivity.
15
+ * Defaults to `undefined` (reactive to all state change) if you didn't set `defaultDeps` on `createStores`.
16
+ *
17
+ * IMPORTANT NOTE: `selectDeps` must not be changed after initialization.
18
+ */
19
+ (...args: [Maybe<TKey>, SelectDeps<T>?] | [SelectDeps<T>?]): T;
20
+ get: (key?: Maybe<TKey>) => T;
21
+ getAll: () => T[];
22
+ getAllWithSubscriber: () => T[];
23
+ set: (key: Maybe<TKey>, value: SetStoreData<T>, silent?: boolean) => void;
24
+ setAll: (value: SetStoreData<T>, silent?: boolean) => void;
25
+ subscribe: (key: Maybe<TKey>, fn: (state: T) => void, selectDeps?: SelectDeps<T>) => () => void;
26
+ getSubscribers: (key: Maybe<TKey>) => Subscribers<T>;
27
+ getStore: (key?: Maybe<TKey>) => InitStoreReturn<T>;
28
+ getStores: () => Map<string, InitStoreReturn<T>>;
29
+ /**
30
+ * Set default values inside a component.
31
+ *
32
+ * IMPORTANT NOTE: Put this on the root component or parent component, before any component subscribed!
33
+ */
34
+ setDefaultValues: (key: Maybe<TKey>, values: SetStoreData<T>) => void;
35
+ Watch: (props: WatchProps<T> & {
36
+ storeKey?: Maybe<TKey>;
37
+ }) => any;
38
+ };
39
+ export type CreateStoresOptions<TKey extends StoreKey = StoreKey, T extends StoreData = StoreData> = InitStoreOptions<T> & {
40
+ onBeforeChangeKey?: (nextKey: TKey, prevKey: TKey) => void;
41
+ defaultDeps?: SelectDeps<T>;
42
+ hashKeyFn?: (obj: TKey) => string;
43
+ };
44
+ export declare const createStores: <TKey extends StoreKey = StoreKey, T extends StoreData = StoreData>(initializer: StoresInitializer<TKey, T>, options?: CreateStoresOptions<TKey, T>) => UseStores<TKey, T>;
45
+ export {};
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createStores = void 0;
4
+ const hooks_1 = require("preact/hooks");
5
+ const utils_1 = require("../utils");
6
+ const vanilla_1 = require("../vanilla");
7
+ const createStores = (initializer, options = {}) => {
8
+ const { onBeforeChangeKey = utils_1.noop, defaultDeps, hashKeyFn = utils_1.hashStoreKey } = options;
9
+ const stores = new Map();
10
+ const getStore = (_key) => {
11
+ const key = _key || {};
12
+ const normalizedKey = hashKeyFn(key);
13
+ if (!stores.has(normalizedKey)) {
14
+ stores.set(normalizedKey, (0, vanilla_1.initStore)((api) => initializer({ key, ...api }), options));
15
+ }
16
+ return stores.get(normalizedKey);
17
+ };
18
+ /**
19
+ * IMPORTANT NOTE: selectDeps function must not be changed after initialization.
20
+ */
21
+ const useStores = (...args) => {
22
+ const [_key, selectDeps = defaultDeps] = (typeof args[0] === 'function' ? [{}, args[0]] : args);
23
+ const key = _key || {};
24
+ const normalizedKey = hashKeyFn(key);
25
+ // eslint-disable-next-line react-hooks/exhaustive-deps
26
+ const { get, subscribe } = (0, hooks_1.useMemo)(() => getStore(key), [normalizedKey]);
27
+ const [state, setState] = (0, hooks_1.useState)(get);
28
+ const isFirstRender = (0, hooks_1.useRef)(true);
29
+ const prevKey = (0, hooks_1.useRef)(key);
30
+ (0, hooks_1.useEffect)(() => {
31
+ if (!isFirstRender.current) {
32
+ onBeforeChangeKey(key, prevKey.current);
33
+ setState(get);
34
+ }
35
+ isFirstRender.current = false;
36
+ prevKey.current = key;
37
+ const unsubs = subscribe(setState, selectDeps);
38
+ return unsubs;
39
+ // eslint-disable-next-line react-hooks/exhaustive-deps
40
+ }, [normalizedKey]);
41
+ return state;
42
+ };
43
+ useStores.get = (key) => {
44
+ const store = getStore(key);
45
+ return store.get();
46
+ };
47
+ useStores.getAll = () => {
48
+ const allStores = [];
49
+ stores.forEach((store) => {
50
+ allStores.push(store.get());
51
+ });
52
+ return allStores;
53
+ };
54
+ useStores.getAllWithSubscriber = () => {
55
+ const allStores = [];
56
+ stores.forEach((store) => {
57
+ const subscribers = store.getSubscribers();
58
+ if (subscribers.size > 0)
59
+ allStores.push(store.get());
60
+ });
61
+ return allStores;
62
+ };
63
+ useStores.set = (key, value, silent) => {
64
+ const store = getStore(key);
65
+ store.set(value, silent);
66
+ };
67
+ useStores.setAll = (value, silent) => {
68
+ stores.forEach((store) => {
69
+ store.set(value, silent);
70
+ });
71
+ };
72
+ useStores.subscribe = (key, fn, selectDeps) => {
73
+ const store = getStore(key);
74
+ return store.subscribe(fn, selectDeps);
75
+ };
76
+ useStores.getSubscribers = (key) => {
77
+ const store = getStore(key);
78
+ return store.getSubscribers();
79
+ };
80
+ useStores.getStore = (key) => getStore(key);
81
+ useStores.getStores = () => stores;
82
+ useStores.setDefaultValues = (key, value) => {
83
+ // eslint-disable-next-line react-hooks/rules-of-hooks
84
+ (0, hooks_1.useState)(() => {
85
+ const store = getStore(key);
86
+ const subscribers = store.getSubscribers();
87
+ if (subscribers.size > 0) {
88
+ console.warn('Put setDefaultValues on the root component or parent component, before any component subscribed!');
89
+ }
90
+ store.set(value);
91
+ });
92
+ };
93
+ const Watch = ({ storeKey, selectDeps, render }) => {
94
+ const store = useStores(storeKey, selectDeps);
95
+ return render(store);
96
+ };
97
+ useStores.Watch = Watch;
98
+ return useStores;
99
+ };
100
+ exports.createStores = createStores;
@@ -0,0 +1,5 @@
1
+ export * from './create-store';
2
+ export * from './create-stores';
3
+ export * from './create-query';
4
+ export * from './create-mutation';
5
+ export * from './with-context';
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./create-store"), exports);
5
+ tslib_1.__exportStar(require("./create-stores"), exports);
6
+ tslib_1.__exportStar(require("./create-query"), exports);
7
+ tslib_1.__exportStar(require("./create-mutation"), exports);
8
+ tslib_1.__exportStar(require("./with-context"), exports);
@@ -0,0 +1,6 @@
1
+ /// <reference types="react" />
2
+ import { ComponentChildren } from 'preact';
3
+ export declare const withContext: <T>(initFn: () => T) => readonly [({ children, onInitialize, }: {
4
+ children: ComponentChildren;
5
+ onInitialize?: ((value: T) => void) | undefined;
6
+ }) => import("react").JSX.Element, () => T | null];
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withContext = void 0;
4
+ const preact_1 = require("preact");
5
+ const hooks_1 = require("preact/hooks");
6
+ const withContext = (initFn) => {
7
+ const Context = (0, preact_1.createContext)(null);
8
+ const Provider = ({ children, onInitialize, }) => {
9
+ const [value] = (0, hooks_1.useState)(() => {
10
+ const store = initFn();
11
+ onInitialize && onInitialize(store);
12
+ return store;
13
+ });
14
+ // @ts-ignore
15
+ return React.createElement(Context.Provider, { value: value }, children);
16
+ };
17
+ const useCurrentContext = () => (0, hooks_1.useContext)(Context);
18
+ return [Provider, useCurrentContext];
19
+ };
20
+ exports.withContext = withContext;
@@ -0,0 +1,5 @@
1
+ export * from './create-store';
2
+ export * from './create-stores';
3
+ export * from './create-query';
4
+ export * from './create-mutation';
5
+ export * from './with-context';
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./create-store"), exports);
5
+ tslib_1.__exportStar(require("./create-stores"), exports);
6
+ tslib_1.__exportStar(require("./create-query"), exports);
7
+ tslib_1.__exportStar(require("./create-mutation"), exports);
8
+ tslib_1.__exportStar(require("./with-context"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "floppy-disk",
3
- "version": "2.0.0-beta.2",
3
+ "version": "2.0.0-beta.3",
4
4
  "description": "FloppyDisk - lightweight, simple, and powerful state management library",
5
5
  "keywords": [
6
6
  "state",
@@ -21,20 +21,42 @@
21
21
  "url": "https://github.com/afiiif/floppy-disk/issues"
22
22
  },
23
23
  "homepage": "https://github.com/afiiif/floppy-disk#readme",
24
- "main": "lib/index.js",
25
- "module": "esm/index.js",
26
24
  "sideEffects": false,
27
25
  "files": [
28
26
  "lib/",
29
27
  "esm/"
30
28
  ],
29
+ "main": "lib/index.js",
30
+ "module": "esm/index.js",
31
31
  "types": "lib/index.d.ts",
32
32
  "typings": "lib/index.d.ts",
33
+ "exports": {
34
+ "./package.json": "./package.json",
35
+ ".": {
36
+ "default": "./lib/index.js",
37
+ "types": "./lib/index.d.ts",
38
+ "module": "./esm/index.js",
39
+ "import": {
40
+ "default": "./esm/index.js",
41
+ "types": "./esm/index.d.ts"
42
+ }
43
+ },
44
+ "./preact": {
45
+ "default": "./lib/preact/index.js",
46
+ "types": "./lib/preact/index.d.ts",
47
+ "module": "./esm/preact/index.js",
48
+ "import": {
49
+ "default": "./esm/preact/index.js",
50
+ "types": "./esm/preact/index.d.ts"
51
+ }
52
+ }
53
+ },
33
54
  "scripts": {
34
55
  "prepare": "husky install",
35
56
  "build:cjs": "tsc -p tsconfig.prod.json",
36
57
  "build:es": "tsc -p tsconfig.prod.json -m esNext --outDir esm",
37
58
  "build": "yarn clean && yarn build:cjs && yarn build:es",
59
+ "prebuild": "ts-node ./scripts/preact.ts",
38
60
  "clean": "rimraf lib esm",
39
61
  "format": "prettier --check .",
40
62
  "format:fix": "prettier --write .",
@@ -44,10 +66,6 @@
44
66
  "test": "jest",
45
67
  "semantic-release": "semantic-release"
46
68
  },
47
- "peerDependencies": {
48
- "react": "^17.0.0 || ^18.0.0",
49
- "react-dom": "^17.0.0 || ^18.0.0"
50
- },
51
69
  "release": {
52
70
  "branches": [
53
71
  "main",