@mborecki/react-create-store 0.0.4 → 1.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/lib/index.d.ts +2 -2
- package/lib/index.js +30 -37
- package/lib/index.js.map +1 -1
- package/package.json +15 -10
- package/src/index.test.tsx +75 -0
- package/src/index.tsx +1 -1
- package/tsconfig.json +6 -3
- package/vitest.config.ts +8 -0
package/lib/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
export
|
|
1
|
+
import React from "react";
|
|
2
|
+
export declare function createStore<T, A>(userReducer: (state: T, action: A) => T, initState: T, localStorageKey?: string): [React.FunctionComponent, () => React.Dispatch<A>, () => T];
|
package/lib/index.js
CHANGED
|
@@ -1,38 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
function useStore() {
|
|
33
|
-
return react_1.default.useContext(storeContext);
|
|
34
|
-
}
|
|
35
|
-
return [StoreProvider, useDispatch, useStore];
|
|
36
|
-
}
|
|
37
|
-
exports.default = createStore;
|
|
1
|
+
import React from "react";
|
|
2
|
+
export function createStore(userReducer, initState, localStorageKey) {
|
|
3
|
+
const dispathContext = React.createContext((value) => { });
|
|
4
|
+
const storeContext = React.createContext(initState);
|
|
5
|
+
if (localStorageKey) {
|
|
6
|
+
try {
|
|
7
|
+
initState = JSON.parse(window.localStorage.getItem(localStorageKey) || '') || initState;
|
|
8
|
+
}
|
|
9
|
+
catch { }
|
|
10
|
+
}
|
|
11
|
+
const reducer = (state, action) => {
|
|
12
|
+
const newState = userReducer(state, action);
|
|
13
|
+
if (localStorageKey) {
|
|
14
|
+
localStorage.setItem(localStorageKey, JSON.stringify(newState));
|
|
15
|
+
}
|
|
16
|
+
return newState;
|
|
17
|
+
};
|
|
18
|
+
const StoreProvider = ({ children }) => {
|
|
19
|
+
const [store, dispatch] = React.useReducer(reducer, initState);
|
|
20
|
+
return (React.createElement(dispathContext.Provider, { value: dispatch },
|
|
21
|
+
React.createElement(storeContext.Provider, { value: store }, children)));
|
|
22
|
+
};
|
|
23
|
+
function useDispatch() {
|
|
24
|
+
return React.useContext(dispathContext);
|
|
25
|
+
}
|
|
26
|
+
function useStore() {
|
|
27
|
+
return React.useContext(storeContext);
|
|
28
|
+
}
|
|
29
|
+
return [StoreProvider, useDispatch, useStore];
|
|
30
|
+
}
|
|
38
31
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,MAAM,UAAU,WAAW,CAAO,WAAuC,EAAE,SAAY,EAAE,eAAwB;IAE7G,MAAM,cAAc,GAA+B,KAAK,CAAC,aAAa,CAAC,CAAC,KAAQ,EAAE,EAAE,GAAE,CAAC,CAAC,CAAC;IACzF,MAAM,YAAY,GAAe,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAEhE,IAAI,eAAe,EAAE,CAAC;QAClB,IAAI,CAAC;YACD,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,IAAI,SAAS,CAAA;QAC3F,CAAC;QAAC,MAAM,CAAC,CAAC,CAAC;IACf,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,KAAQ,EAAE,MAAS,EAAE,EAAE;QACpC,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5C,IAAI,eAAe,EAAE,CAAC;YAClB,YAAY,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;QACnE,CAAC;QAED,OAAO,QAAQ,CAAC;IACpB,CAAC,CAAA;IAED,MAAM,aAAa,GAA4B,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC5D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;QAG9D,OAAO,CACH,oBAAC,cAAc,CAAC,QAAQ,IAAC,KAAK,EAAE,QAAQ;YACpC,oBAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,IAC9B,QAAQ,CACY,CACF,CAC9B,CAAA;IACL,CAAC,CAAA;IAED,SAAS,WAAW;QAChB,OAAO,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IAC5C,CAAC;IAED,SAAS,QAAQ;QACb,OAAO,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,CAAC,aAAa,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAA;AACjD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mborecki/react-create-store",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
|
-
"
|
|
7
|
-
"build": "rm -rf ./lib && tsc",
|
|
8
|
-
"prepare": "npm run build"
|
|
9
|
-
},
|
|
6
|
+
"type": "module",
|
|
10
7
|
"repository": {
|
|
11
8
|
"type": "git",
|
|
12
9
|
"url": "https://github.com/mborecki/react-utils.git",
|
|
@@ -19,9 +16,17 @@
|
|
|
19
16
|
},
|
|
20
17
|
"homepage": "https://github.com/mborecki/react-utils#readme",
|
|
21
18
|
"devDependencies": {
|
|
22
|
-
"@
|
|
23
|
-
"react": "^16.
|
|
24
|
-
"
|
|
19
|
+
"@testing-library/dom": "^10.4.2",
|
|
20
|
+
"@testing-library/react": "^16.3.3",
|
|
21
|
+
"@types/react": "^17.0.93",
|
|
22
|
+
"jsdom": "^30.1.1",
|
|
23
|
+
"react": "^19.2.7",
|
|
24
|
+
"typescript": "^5.9.3",
|
|
25
|
+
"vitest": "^5.0.2"
|
|
25
26
|
},
|
|
26
|
-
"gitHead": "
|
|
27
|
-
|
|
27
|
+
"gitHead": "2ac4b370fd16244d8d4a7aba12ae1b3068e12daa",
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "rm -rf ./lib && tsc",
|
|
30
|
+
"test": "vitest"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import {describe, test, expect, beforeAll, beforeEach, afterEach} from "vitest";
|
|
2
|
+
import { createStore } from "./index.js";
|
|
3
|
+
import {cleanup, fireEvent, getByText, render, screen} from '@testing-library/react'
|
|
4
|
+
import React, { PropsWithChildren } from "react";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
type Store = {
|
|
8
|
+
a: number
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type Action = {
|
|
12
|
+
value: number
|
|
13
|
+
}
|
|
14
|
+
const reducer = (state: Store, action: Action) => {
|
|
15
|
+
return {
|
|
16
|
+
...state,
|
|
17
|
+
a: action.value
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const [Provider, useDispatch, useStore] = createStore<Store, Action>(reducer, {a: 123});
|
|
21
|
+
|
|
22
|
+
describe('sanity check', () => {
|
|
23
|
+
test('should pass', () => {
|
|
24
|
+
expect(true).toBeTruthy();
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
describe('CreateStore', () => {
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
cleanup();
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
test('should print stored value', () => {
|
|
34
|
+
const MyComponent = () => {
|
|
35
|
+
const data = useStore();
|
|
36
|
+
return <div>
|
|
37
|
+
<div id="value">
|
|
38
|
+
{data.a}
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
render(<Provider>
|
|
44
|
+
<MyComponent />
|
|
45
|
+
</Provider>)
|
|
46
|
+
|
|
47
|
+
expect(screen.getByText('123')).toBeTruthy();
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
test('should update value', () => {
|
|
51
|
+
const MyComponent = () => {
|
|
52
|
+
const data = useStore();
|
|
53
|
+
const dispatch = useDispatch();
|
|
54
|
+
return <div>
|
|
55
|
+
<div>
|
|
56
|
+
<button data-testid="btn" onClick={() => dispatch({value: 666})} >change</button>
|
|
57
|
+
</div>
|
|
58
|
+
<div data-testid="value">
|
|
59
|
+
{data.a}
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
render(<Provider>
|
|
65
|
+
<MyComponent />
|
|
66
|
+
</Provider>)
|
|
67
|
+
|
|
68
|
+
expect(screen.getByText('123')).toBeTruthy();
|
|
69
|
+
|
|
70
|
+
fireEvent.click(screen.getByTestId('btn'));
|
|
71
|
+
|
|
72
|
+
expect(screen.getByText('666')).toBeTruthy();
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
})
|
package/src/index.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { Context } from "react";
|
|
2
2
|
|
|
3
|
-
export
|
|
3
|
+
export function createStore<T, A>(userReducer: (state: T, action: A) => T, initState: T, localStorageKey?: string)
|
|
4
4
|
: [React.FunctionComponent, () => React.Dispatch<A>, () => T] {
|
|
5
5
|
const dispathContext: Context<React.Dispatch<A>> = React.createContext((value: A) => {});
|
|
6
6
|
const storeContext: Context<T> = React.createContext(initState);
|
package/tsconfig.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
+
"rootDir": "./src/",
|
|
3
4
|
"outDir": "./lib",
|
|
4
|
-
"target": "
|
|
5
|
-
"module": "
|
|
5
|
+
"target": "ESnext",
|
|
6
|
+
"module": "nodenext",
|
|
6
7
|
"noImplicitAny": true,
|
|
7
8
|
"strictNullChecks": true,
|
|
8
9
|
"removeComments": true,
|
|
@@ -10,6 +11,7 @@
|
|
|
10
11
|
"sourceMap": true,
|
|
11
12
|
"jsx": "react",
|
|
12
13
|
"esModuleInterop": true,
|
|
14
|
+
"moduleResolution": "nodenext",
|
|
13
15
|
"typeRoots": [
|
|
14
16
|
"index.d.ts",
|
|
15
17
|
"node_modules/@types"
|
|
@@ -24,6 +26,7 @@
|
|
|
24
26
|
"./src/**/*.ts"
|
|
25
27
|
],
|
|
26
28
|
"exclude": [
|
|
27
|
-
"node_modules"
|
|
29
|
+
"node_modules",
|
|
30
|
+
"./src/**/*.test.tsx"
|
|
28
31
|
]
|
|
29
32
|
}
|