floppy-disk 3.0.0-experimental.1 → 3.0.0
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/README.md +237 -685
- package/esm/index.d.mts +1 -0
- package/esm/index.mjs +1 -0
- package/esm/react/create-mutation.d.mts +151 -0
- package/esm/react/create-query.d.mts +344 -0
- package/esm/react/create-store.d.mts +28 -0
- package/esm/react/create-stores.d.mts +39 -0
- package/esm/react/use-isomorphic-layout-effect.d.mts +6 -0
- package/esm/react/use-mutation.d.mts +82 -0
- package/esm/react/use-store.d.mts +28 -0
- package/esm/react.d.mts +7 -0
- package/esm/react.mjs +697 -0
- package/esm/vanilla/basic.d.mts +13 -0
- package/esm/vanilla/hash.d.mts +7 -0
- package/esm/vanilla/store.d.mts +89 -0
- package/esm/vanilla.d.mts +3 -0
- package/esm/vanilla.mjs +82 -0
- package/index.d.ts +1 -0
- package/index.js +12 -0
- package/package.json +47 -45
- package/react/create-mutation.d.ts +151 -0
- package/react/create-query.d.ts +344 -0
- package/react/create-store.d.ts +28 -0
- package/react/create-stores.d.ts +39 -0
- package/react/use-isomorphic-layout-effect.d.ts +6 -0
- package/react/use-mutation.d.ts +82 -0
- package/react/use-store.d.ts +28 -0
- package/react.d.ts +7 -0
- package/react.js +705 -0
- package/ts_version_4.5_and_above_is_required.d.ts +0 -0
- package/vanilla/basic.d.ts +13 -0
- package/vanilla/hash.d.ts +7 -0
- package/vanilla/store.d.ts +89 -0
- package/vanilla.d.ts +3 -0
- package/vanilla.js +89 -0
- package/esm/index.d.ts +0 -8
- package/esm/index.js +0 -8
- package/esm/react/create-bi-direction-query.d.ts +0 -166
- package/esm/react/create-bi-direction-query.js +0 -74
- package/esm/react/create-mutation.d.ts +0 -39
- package/esm/react/create-mutation.js +0 -56
- package/esm/react/create-query.d.ts +0 -319
- package/esm/react/create-query.js +0 -434
- package/esm/react/create-store.d.ts +0 -38
- package/esm/react/create-store.js +0 -38
- package/esm/react/create-stores.d.ts +0 -61
- package/esm/react/create-stores.js +0 -99
- package/esm/react/with-context.d.ts +0 -5
- package/esm/react/with-context.js +0 -14
- package/esm/utils.d.ts +0 -24
- package/esm/utils.js +0 -31
- package/esm/vanilla/fetcher.d.ts +0 -27
- package/esm/vanilla/fetcher.js +0 -95
- package/esm/vanilla/init-store.d.ts +0 -24
- package/esm/vanilla/init-store.js +0 -51
- package/lib/index.d.ts +0 -8
- package/lib/index.js +0 -11
- package/lib/react/create-bi-direction-query.d.ts +0 -166
- package/lib/react/create-bi-direction-query.js +0 -78
- package/lib/react/create-mutation.d.ts +0 -39
- package/lib/react/create-mutation.js +0 -60
- package/lib/react/create-query.d.ts +0 -319
- package/lib/react/create-query.js +0 -438
- package/lib/react/create-store.d.ts +0 -38
- package/lib/react/create-store.js +0 -42
- package/lib/react/create-stores.d.ts +0 -61
- package/lib/react/create-stores.js +0 -104
- package/lib/react/with-context.d.ts +0 -5
- package/lib/react/with-context.js +0 -18
- package/lib/utils.d.ts +0 -24
- package/lib/utils.js +0 -39
- package/lib/vanilla/fetcher.d.ts +0 -27
- package/lib/vanilla/fetcher.js +0 -99
- package/lib/vanilla/init-store.d.ts +0 -24
- package/lib/vanilla/init-store.js +0 -55
- package/utils/package.json +0 -6
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
export declare const withContext: <T>(initFn: () => T) => readonly [({ children, onInitialize, }: {
|
|
3
|
-
children: ReactNode;
|
|
4
|
-
onInitialize?: ((value: T) => void) | undefined;
|
|
5
|
-
}) => import("react").FunctionComponentElement<import("react").ProviderProps<T | null>>, () => T | null];
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.withContext = void 0;
|
|
4
|
-
const react_1 = require("react");
|
|
5
|
-
const withContext = (initFn) => {
|
|
6
|
-
const Context = (0, react_1.createContext)(null);
|
|
7
|
-
const Provider = ({ children, onInitialize, }) => {
|
|
8
|
-
const [value] = (0, react_1.useState)(() => {
|
|
9
|
-
const store = initFn();
|
|
10
|
-
onInitialize && onInitialize(store);
|
|
11
|
-
return store;
|
|
12
|
-
});
|
|
13
|
-
return (0, react_1.createElement)(Context.Provider, { value, children });
|
|
14
|
-
};
|
|
15
|
-
const useCurrentContext = () => (0, react_1.useContext)(Context);
|
|
16
|
-
return [Provider, useCurrentContext];
|
|
17
|
-
};
|
|
18
|
-
exports.withContext = withContext;
|
package/lib/utils.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export type Maybe<T> = T | null | undefined;
|
|
2
|
-
/**
|
|
3
|
-
* Check if this runs on browser.
|
|
4
|
-
*/
|
|
5
|
-
export declare const isClient: boolean;
|
|
6
|
-
export declare const noop: () => void;
|
|
7
|
-
export declare const identityFn: <T>(value: T) => T;
|
|
8
|
-
/**
|
|
9
|
-
* Check if a value is not undefined and not null.
|
|
10
|
-
*
|
|
11
|
-
* ```ts
|
|
12
|
-
* const hasValue = (value: any) => value !== undefined && value !== null;
|
|
13
|
-
* ```
|
|
14
|
-
*/
|
|
15
|
-
export declare const hasValue: (value: any) => boolean;
|
|
16
|
-
/**
|
|
17
|
-
* If the value is a function, it will invoke the function.\
|
|
18
|
-
* If the value is not a function, it will just return it.
|
|
19
|
-
*/
|
|
20
|
-
export declare const getValue: <T, P extends any[]>(valueOrComputeValueFn: T | ((...params: P) => T), ...params: P) => T;
|
|
21
|
-
/**
|
|
22
|
-
* Create an Error instance with custom props.
|
|
23
|
-
*/
|
|
24
|
-
export declare const createError: (message: string, props: Record<string, any>) => Error & Record<string, any>;
|
package/lib/utils.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createError = exports.getValue = exports.hasValue = exports.identityFn = exports.noop = exports.isClient = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Check if this runs on browser.
|
|
6
|
-
*/
|
|
7
|
-
exports.isClient = typeof window !== 'undefined' && !('Deno' in window);
|
|
8
|
-
const noop = () => { };
|
|
9
|
-
exports.noop = noop;
|
|
10
|
-
const identityFn = (value) => value;
|
|
11
|
-
exports.identityFn = identityFn;
|
|
12
|
-
/**
|
|
13
|
-
* Check if a value is not undefined and not null.
|
|
14
|
-
*
|
|
15
|
-
* ```ts
|
|
16
|
-
* const hasValue = (value: any) => value !== undefined && value !== null;
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
const hasValue = (value) => value !== undefined && value !== null;
|
|
20
|
-
exports.hasValue = hasValue;
|
|
21
|
-
/**
|
|
22
|
-
* If the value is a function, it will invoke the function.\
|
|
23
|
-
* If the value is not a function, it will just return it.
|
|
24
|
-
*/
|
|
25
|
-
const getValue = (valueOrComputeValueFn, ...params) => {
|
|
26
|
-
if (typeof valueOrComputeValueFn === 'function') {
|
|
27
|
-
return valueOrComputeValueFn(...params);
|
|
28
|
-
}
|
|
29
|
-
return valueOrComputeValueFn;
|
|
30
|
-
};
|
|
31
|
-
exports.getValue = getValue;
|
|
32
|
-
/**
|
|
33
|
-
* Create an Error instance with custom props.
|
|
34
|
-
*/
|
|
35
|
-
const createError = (message, props) => {
|
|
36
|
-
const error = Object.assign(new Error(message), props);
|
|
37
|
-
return error;
|
|
38
|
-
};
|
|
39
|
-
exports.createError = createError;
|
package/lib/vanilla/fetcher.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
type FetcherOptions<TResponse = any> = {
|
|
2
|
-
url: string;
|
|
3
|
-
query?: string;
|
|
4
|
-
params?: Record<string, string | number | boolean> | null;
|
|
5
|
-
payload?: any;
|
|
6
|
-
interceptRequest?: (requestOptions: RequestInit & {
|
|
7
|
-
url: string;
|
|
8
|
-
}) => (RequestInit & {
|
|
9
|
-
url: string;
|
|
10
|
-
}) | Promise<RequestInit & {
|
|
11
|
-
url: string;
|
|
12
|
-
}>;
|
|
13
|
-
interceptResponse?: (response: TResponse) => TResponse | Promise<TResponse>;
|
|
14
|
-
} & RequestInit;
|
|
15
|
-
/**
|
|
16
|
-
* Experimental fetcher - abstraction layer for query/mutation function creator.
|
|
17
|
-
*
|
|
18
|
-
* Can be used for REST or GraphQL.
|
|
19
|
-
*
|
|
20
|
-
* Only work for JSON response only.
|
|
21
|
-
*
|
|
22
|
-
* @see https://floppy-disk.vercel.app/docs/experimental
|
|
23
|
-
*
|
|
24
|
-
* @returns A function to fetch data
|
|
25
|
-
*/
|
|
26
|
-
export declare const fetcher: <TResponse = any, TInput extends any[] = any[]>(options: FetcherOptions<TResponse> | ((...args: TInput) => FetcherOptions<TResponse>)) => (...args: TInput) => Promise<TResponse>;
|
|
27
|
-
export {};
|
package/lib/vanilla/fetcher.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.fetcher = void 0;
|
|
4
|
-
const utils_1 = require("../utils");
|
|
5
|
-
const encodeParams = (params) => Object.entries(params)
|
|
6
|
-
.filter(([, value]) => value !== undefined && value !== null)
|
|
7
|
-
.map((kv) => kv.map(encodeURIComponent).join('='))
|
|
8
|
-
.join('&');
|
|
9
|
-
/**
|
|
10
|
-
* Experimental fetcher - abstraction layer for query/mutation function creator.
|
|
11
|
-
*
|
|
12
|
-
* Can be used for REST or GraphQL.
|
|
13
|
-
*
|
|
14
|
-
* Only work for JSON response only.
|
|
15
|
-
*
|
|
16
|
-
* @see https://floppy-disk.vercel.app/docs/experimental
|
|
17
|
-
*
|
|
18
|
-
* @returns A function to fetch data
|
|
19
|
-
*/
|
|
20
|
-
const fetcher = (options) => async (...args) => {
|
|
21
|
-
const { url, query, params, payload, headers, interceptRequest = utils_1.identityFn, interceptResponse, ...rest } = (0, utils_1.getValue)(options, ...args);
|
|
22
|
-
let autoOptions = {};
|
|
23
|
-
let searchParams = params;
|
|
24
|
-
if (query) {
|
|
25
|
-
// GraphQL
|
|
26
|
-
autoOptions = {
|
|
27
|
-
method: 'POST',
|
|
28
|
-
body: JSON.stringify({ query, variables: payload || args[0] }),
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
else if (rest.method && rest.method.toLowerCase() !== 'get') {
|
|
32
|
-
// REST - Mutation
|
|
33
|
-
autoOptions = {
|
|
34
|
-
body: JSON.stringify(payload === undefined ? args[0] : payload),
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
// REST - Query
|
|
39
|
-
if (typeof options === 'object' && params === undefined)
|
|
40
|
-
searchParams = args[0];
|
|
41
|
-
}
|
|
42
|
-
const interceptedOptions = await interceptRequest({
|
|
43
|
-
url: searchParams ? [url, encodeParams(searchParams)].join('?') : url,
|
|
44
|
-
headers: { 'Content-Type': 'application/json', ...headers },
|
|
45
|
-
...autoOptions,
|
|
46
|
-
...rest,
|
|
47
|
-
});
|
|
48
|
-
const { url: finalUrl, ...finalOptions } = interceptedOptions;
|
|
49
|
-
const res = await fetch(finalUrl, finalOptions);
|
|
50
|
-
const contentType = res.headers.get('content-type');
|
|
51
|
-
const isJsonFile = /\.json(\?.+)?$/.test(finalUrl);
|
|
52
|
-
if (contentType?.includes('application/json') || isJsonFile) {
|
|
53
|
-
let resJson = await res.json();
|
|
54
|
-
if (query) {
|
|
55
|
-
if (resJson.errors) {
|
|
56
|
-
throw (0, utils_1.createError)('Error GraphQL response', {
|
|
57
|
-
status: res.status,
|
|
58
|
-
statusText: res.statusText,
|
|
59
|
-
response: resJson.errors,
|
|
60
|
-
request: interceptedOptions,
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
resJson = resJson.data;
|
|
64
|
-
}
|
|
65
|
-
if (res.ok) {
|
|
66
|
-
if (interceptResponse) {
|
|
67
|
-
try {
|
|
68
|
-
const finalResponse = await interceptResponse(resJson);
|
|
69
|
-
return finalResponse;
|
|
70
|
-
}
|
|
71
|
-
catch (error) {
|
|
72
|
-
throw (0, utils_1.createError)('Error intercept response', {
|
|
73
|
-
status: res.status,
|
|
74
|
-
statusText: res.statusText,
|
|
75
|
-
response: resJson,
|
|
76
|
-
error,
|
|
77
|
-
request: interceptedOptions,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return resJson;
|
|
82
|
-
}
|
|
83
|
-
throw (0, utils_1.createError)('Fetch error', {
|
|
84
|
-
status: res.status,
|
|
85
|
-
statusText: res.statusText,
|
|
86
|
-
response: resJson,
|
|
87
|
-
request: interceptedOptions,
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
const resText = await res.text().catch(() => undefined);
|
|
91
|
-
throw (0, utils_1.createError)('Response type is not a JSON', {
|
|
92
|
-
status: res.status,
|
|
93
|
-
statusText: res.statusText,
|
|
94
|
-
response: resText,
|
|
95
|
-
contentType,
|
|
96
|
-
request: interceptedOptions,
|
|
97
|
-
});
|
|
98
|
-
};
|
|
99
|
-
exports.fetcher = fetcher;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Maybe } from '../utils';
|
|
2
|
-
export type StoreState = Record<string, any>;
|
|
3
|
-
export type SetStoreState<T> = Partial<T> | ((state: T) => Partial<T>);
|
|
4
|
-
export type SelectDeps<T> = ((state: T) => any[]) | undefined | null;
|
|
5
|
-
export type Subscribers<T> = Map<(state: T) => void, SelectDeps<T>>;
|
|
6
|
-
export type StoreInitializer<T> = T | ((api: {
|
|
7
|
-
get: () => T;
|
|
8
|
-
set: (value: SetStoreState<T>, silent?: boolean) => void;
|
|
9
|
-
}) => T);
|
|
10
|
-
export type StoreEvent<T> = (state: T) => void;
|
|
11
|
-
export type InitStoreOptions<T> = {
|
|
12
|
-
intercept?: (nextState: T, prevState: T) => void | Maybe<Partial<T>>;
|
|
13
|
-
onFirstSubscribe?: StoreEvent<T>;
|
|
14
|
-
onSubscribe?: StoreEvent<T>;
|
|
15
|
-
onUnsubscribe?: StoreEvent<T>;
|
|
16
|
-
onLastUnsubscribe?: StoreEvent<T>;
|
|
17
|
-
};
|
|
18
|
-
export type InitStoreReturn<T> = {
|
|
19
|
-
get: () => T;
|
|
20
|
-
set: (value: SetStoreState<T>, silent?: boolean) => void;
|
|
21
|
-
subscribe: (fn: (state: T) => void, selectDeps?: SelectDeps<T>) => () => void;
|
|
22
|
-
getSubscribers: () => Subscribers<T>;
|
|
23
|
-
};
|
|
24
|
-
export declare const initStore: <T extends StoreState>(initializer: StoreInitializer<T>, options?: InitStoreOptions<T>) => InitStoreReturn<T>;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.initStore = void 0;
|
|
4
|
-
const utils_1 = require("../utils");
|
|
5
|
-
const initStore = (initializer, options = {}) => {
|
|
6
|
-
const { intercept, onFirstSubscribe = utils_1.noop, onSubscribe = utils_1.noop, onUnsubscribe = utils_1.noop, onLastUnsubscribe = utils_1.noop, } = options;
|
|
7
|
-
const subscribers = new Map();
|
|
8
|
-
const getSubscribers = () => subscribers;
|
|
9
|
-
let state;
|
|
10
|
-
const get = () => state;
|
|
11
|
-
const set = (value, silent = false) => {
|
|
12
|
-
const prevState = state;
|
|
13
|
-
state = { ...state, ...(0, utils_1.getValue)(value, state) };
|
|
14
|
-
if (intercept) {
|
|
15
|
-
state = { ...state, ...intercept(state, prevState) };
|
|
16
|
-
}
|
|
17
|
-
if (silent)
|
|
18
|
-
return;
|
|
19
|
-
const keys = Object.keys(state);
|
|
20
|
-
subscribers.forEach((selectDeps, fn) => {
|
|
21
|
-
if (!selectDeps) {
|
|
22
|
-
for (let i = 0, n = keys.length; i < n; i++) {
|
|
23
|
-
if (prevState[keys[i]] !== state[keys[i]]) {
|
|
24
|
-
fn(state);
|
|
25
|
-
break;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
const prevs = selectDeps(prevState);
|
|
31
|
-
const nexts = selectDeps(state);
|
|
32
|
-
for (let i = 0, n = prevs.length; i < n; i++) {
|
|
33
|
-
if (prevs[i] !== nexts[i]) {
|
|
34
|
-
fn(state);
|
|
35
|
-
break;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
};
|
|
40
|
-
const subscribe = (fn, selectDeps) => {
|
|
41
|
-
subscribers.set(fn, selectDeps);
|
|
42
|
-
if (subscribers.size === 1)
|
|
43
|
-
onFirstSubscribe(state);
|
|
44
|
-
onSubscribe(state);
|
|
45
|
-
return () => {
|
|
46
|
-
subscribers.delete(fn);
|
|
47
|
-
onUnsubscribe(state);
|
|
48
|
-
if (subscribers.size === 0)
|
|
49
|
-
onLastUnsubscribe(state);
|
|
50
|
-
};
|
|
51
|
-
};
|
|
52
|
-
state = (0, utils_1.getValue)(initializer, { get, set });
|
|
53
|
-
return { get, set, subscribe, getSubscribers };
|
|
54
|
-
};
|
|
55
|
-
exports.initStore = initStore;
|