floppy-disk 1.1.2 → 1.1.3-beta.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/README.md
CHANGED
|
@@ -19,13 +19,13 @@ import {
|
|
|
19
19
|
useMutation,
|
|
20
20
|
} from '@tanstack/react-query'; // 41 kB (gzipped: 11 kB)
|
|
21
21
|
|
|
22
|
-
import { createQuery, createMutation } from 'floppy-disk'; // 6.
|
|
22
|
+
import { createQuery, createMutation } from 'floppy-disk'; // 6.4 kB (gzipped: 2.3 kB) 🎉
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
- Using Zustand & React-Query: https://demo-zustand-react-query.vercel.app/
|
|
26
|
-
👉 Total: **309.
|
|
26
|
+
👉 Total: **309.22 kB** ~ gzipped 97.66 kB
|
|
27
27
|
- Using Floppy Disk: https://demo-floppy-disk.vercel.app/
|
|
28
|
-
👉 Total: **279.
|
|
28
|
+
👉 Total: **279.63 kB** ~ gzipped 89.35 kB
|
|
29
29
|
|
|
30
30
|
## Table of Contents
|
|
31
31
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { initStore } from '../vanilla';
|
|
2
|
+
describe('initStore', () => {
|
|
3
|
+
const initialData = {
|
|
4
|
+
counter: 0,
|
|
5
|
+
text: 'initial text',
|
|
6
|
+
};
|
|
7
|
+
const onFirstSubscribeMock = jest.fn();
|
|
8
|
+
const onSubscribeMock = jest.fn();
|
|
9
|
+
const onUnsubscribeMock = jest.fn();
|
|
10
|
+
const onLastUnsubscribeMock = jest.fn();
|
|
11
|
+
const mockStoreInitializer = jest.fn(() => initialData);
|
|
12
|
+
const options = {
|
|
13
|
+
onFirstSubscribe: onFirstSubscribeMock,
|
|
14
|
+
onSubscribe: onSubscribeMock,
|
|
15
|
+
onUnsubscribe: onUnsubscribeMock,
|
|
16
|
+
onLastUnsubscribe: onLastUnsubscribeMock,
|
|
17
|
+
};
|
|
18
|
+
let store;
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
store = initStore(mockStoreInitializer, options);
|
|
21
|
+
});
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
onFirstSubscribeMock.mockClear();
|
|
24
|
+
onSubscribeMock.mockClear();
|
|
25
|
+
onUnsubscribeMock.mockClear();
|
|
26
|
+
onLastUnsubscribeMock.mockClear();
|
|
27
|
+
});
|
|
28
|
+
it('should initialize the store with initial data', () => {
|
|
29
|
+
expect(store.get()).toEqual(initialData);
|
|
30
|
+
});
|
|
31
|
+
it('should call onFirstSubscribe & onSubscribe when subscriber is added', () => {
|
|
32
|
+
const subscriber1 = jest.fn();
|
|
33
|
+
const subscriber2 = jest.fn();
|
|
34
|
+
store.subscribe(subscriber1);
|
|
35
|
+
expect(onFirstSubscribeMock).toHaveBeenCalledWith(initialData);
|
|
36
|
+
expect(onSubscribeMock).toHaveBeenCalledWith(initialData);
|
|
37
|
+
store.subscribe(subscriber2);
|
|
38
|
+
expect(onFirstSubscribeMock).toHaveBeenCalledTimes(1);
|
|
39
|
+
expect(onSubscribeMock).toHaveBeenCalledWith(initialData);
|
|
40
|
+
});
|
|
41
|
+
it('should call onUnsubscribe & onLastUnsubscribe when subscriber is removed', () => {
|
|
42
|
+
const subscriber1 = jest.fn();
|
|
43
|
+
const subscriber2 = jest.fn();
|
|
44
|
+
const unsub1 = store.subscribe(subscriber1);
|
|
45
|
+
const unsub2 = store.subscribe(subscriber2);
|
|
46
|
+
unsub1();
|
|
47
|
+
expect(onUnsubscribeMock).toHaveBeenCalledWith(initialData);
|
|
48
|
+
expect(onLastUnsubscribeMock).not.toHaveBeenCalled();
|
|
49
|
+
unsub2();
|
|
50
|
+
expect(onUnsubscribeMock).toHaveBeenCalledWith(initialData);
|
|
51
|
+
expect(onLastUnsubscribeMock).toHaveBeenCalledTimes(1);
|
|
52
|
+
});
|
|
53
|
+
it('should update the store data when set is called with partial data', () => {
|
|
54
|
+
store.set({ counter: 1 });
|
|
55
|
+
expect(store.get().counter).toEqual(1);
|
|
56
|
+
expect(store.get().text).toEqual(initialData.text);
|
|
57
|
+
});
|
|
58
|
+
it('should call subscribers when set is called', () => {
|
|
59
|
+
const subscriber1 = jest.fn();
|
|
60
|
+
const subscriber2 = jest.fn();
|
|
61
|
+
store.subscribe(subscriber1);
|
|
62
|
+
store.subscribe(subscriber2);
|
|
63
|
+
store.set({ counter: 2 });
|
|
64
|
+
expect(subscriber1).toHaveBeenCalledWith(store.get());
|
|
65
|
+
expect(subscriber2).toHaveBeenCalledWith(store.get());
|
|
66
|
+
});
|
|
67
|
+
});
|
package/esm/vanilla.js
CHANGED
|
@@ -4,7 +4,6 @@ export const initStore = (initializer, options = {}) => {
|
|
|
4
4
|
const subscribers = new Map();
|
|
5
5
|
const getSubscribers = () => subscribers;
|
|
6
6
|
let data;
|
|
7
|
-
let keys;
|
|
8
7
|
const get = () => data;
|
|
9
8
|
const set = (value, silent = false) => {
|
|
10
9
|
const prevData = data;
|
|
@@ -19,6 +18,7 @@ export const initStore = (initializer, options = {}) => {
|
|
|
19
18
|
}
|
|
20
19
|
if (silent)
|
|
21
20
|
return;
|
|
21
|
+
const keys = Object.keys(data);
|
|
22
22
|
subscribers.forEach((selectDeps, fn) => {
|
|
23
23
|
if (!selectDeps) {
|
|
24
24
|
for (let i = 0, n = keys.length; i < n; i++) {
|
|
@@ -52,6 +52,5 @@ export const initStore = (initializer, options = {}) => {
|
|
|
52
52
|
};
|
|
53
53
|
};
|
|
54
54
|
data = initializer({ get, set });
|
|
55
|
-
keys = Object.keys(data);
|
|
56
55
|
return { get, set, subscribe, getSubscribers };
|
|
57
56
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vanilla_1 = require("../vanilla");
|
|
4
|
+
describe('initStore', () => {
|
|
5
|
+
const initialData = {
|
|
6
|
+
counter: 0,
|
|
7
|
+
text: 'initial text',
|
|
8
|
+
};
|
|
9
|
+
const onFirstSubscribeMock = jest.fn();
|
|
10
|
+
const onSubscribeMock = jest.fn();
|
|
11
|
+
const onUnsubscribeMock = jest.fn();
|
|
12
|
+
const onLastUnsubscribeMock = jest.fn();
|
|
13
|
+
const mockStoreInitializer = jest.fn(() => initialData);
|
|
14
|
+
const options = {
|
|
15
|
+
onFirstSubscribe: onFirstSubscribeMock,
|
|
16
|
+
onSubscribe: onSubscribeMock,
|
|
17
|
+
onUnsubscribe: onUnsubscribeMock,
|
|
18
|
+
onLastUnsubscribe: onLastUnsubscribeMock,
|
|
19
|
+
};
|
|
20
|
+
let store;
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
store = (0, vanilla_1.initStore)(mockStoreInitializer, options);
|
|
23
|
+
});
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
onFirstSubscribeMock.mockClear();
|
|
26
|
+
onSubscribeMock.mockClear();
|
|
27
|
+
onUnsubscribeMock.mockClear();
|
|
28
|
+
onLastUnsubscribeMock.mockClear();
|
|
29
|
+
});
|
|
30
|
+
it('should initialize the store with initial data', () => {
|
|
31
|
+
expect(store.get()).toEqual(initialData);
|
|
32
|
+
});
|
|
33
|
+
it('should call onFirstSubscribe & onSubscribe when subscriber is added', () => {
|
|
34
|
+
const subscriber1 = jest.fn();
|
|
35
|
+
const subscriber2 = jest.fn();
|
|
36
|
+
store.subscribe(subscriber1);
|
|
37
|
+
expect(onFirstSubscribeMock).toHaveBeenCalledWith(initialData);
|
|
38
|
+
expect(onSubscribeMock).toHaveBeenCalledWith(initialData);
|
|
39
|
+
store.subscribe(subscriber2);
|
|
40
|
+
expect(onFirstSubscribeMock).toHaveBeenCalledTimes(1);
|
|
41
|
+
expect(onSubscribeMock).toHaveBeenCalledWith(initialData);
|
|
42
|
+
});
|
|
43
|
+
it('should call onUnsubscribe & onLastUnsubscribe when subscriber is removed', () => {
|
|
44
|
+
const subscriber1 = jest.fn();
|
|
45
|
+
const subscriber2 = jest.fn();
|
|
46
|
+
const unsub1 = store.subscribe(subscriber1);
|
|
47
|
+
const unsub2 = store.subscribe(subscriber2);
|
|
48
|
+
unsub1();
|
|
49
|
+
expect(onUnsubscribeMock).toHaveBeenCalledWith(initialData);
|
|
50
|
+
expect(onLastUnsubscribeMock).not.toHaveBeenCalled();
|
|
51
|
+
unsub2();
|
|
52
|
+
expect(onUnsubscribeMock).toHaveBeenCalledWith(initialData);
|
|
53
|
+
expect(onLastUnsubscribeMock).toHaveBeenCalledTimes(1);
|
|
54
|
+
});
|
|
55
|
+
it('should update the store data when set is called with partial data', () => {
|
|
56
|
+
store.set({ counter: 1 });
|
|
57
|
+
expect(store.get().counter).toEqual(1);
|
|
58
|
+
expect(store.get().text).toEqual(initialData.text);
|
|
59
|
+
});
|
|
60
|
+
it('should call subscribers when set is called', () => {
|
|
61
|
+
const subscriber1 = jest.fn();
|
|
62
|
+
const subscriber2 = jest.fn();
|
|
63
|
+
store.subscribe(subscriber1);
|
|
64
|
+
store.subscribe(subscriber2);
|
|
65
|
+
store.set({ counter: 2 });
|
|
66
|
+
expect(subscriber1).toHaveBeenCalledWith(store.get());
|
|
67
|
+
expect(subscriber2).toHaveBeenCalledWith(store.get());
|
|
68
|
+
});
|
|
69
|
+
});
|
package/lib/vanilla.js
CHANGED
|
@@ -7,7 +7,6 @@ const initStore = (initializer, options = {}) => {
|
|
|
7
7
|
const subscribers = new Map();
|
|
8
8
|
const getSubscribers = () => subscribers;
|
|
9
9
|
let data;
|
|
10
|
-
let keys;
|
|
11
10
|
const get = () => data;
|
|
12
11
|
const set = (value, silent = false) => {
|
|
13
12
|
const prevData = data;
|
|
@@ -22,6 +21,7 @@ const initStore = (initializer, options = {}) => {
|
|
|
22
21
|
}
|
|
23
22
|
if (silent)
|
|
24
23
|
return;
|
|
24
|
+
const keys = Object.keys(data);
|
|
25
25
|
subscribers.forEach((selectDeps, fn) => {
|
|
26
26
|
if (!selectDeps) {
|
|
27
27
|
for (let i = 0, n = keys.length; i < n; i++) {
|
|
@@ -55,7 +55,6 @@ const initStore = (initializer, options = {}) => {
|
|
|
55
55
|
};
|
|
56
56
|
};
|
|
57
57
|
data = initializer({ get, set });
|
|
58
|
-
keys = Object.keys(data);
|
|
59
58
|
return { get, set, subscribe, getSubscribers };
|
|
60
59
|
};
|
|
61
60
|
exports.initStore = initStore;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "floppy-disk",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3-beta.1",
|
|
4
4
|
"description": "FloppyDisk - lightweight, simple, and powerful state management library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"state",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"prepare": "husky install",
|
|
38
|
-
"build:cjs": "tsc",
|
|
39
|
-
"build:es": "tsc -m esNext --outDir esm",
|
|
38
|
+
"build:cjs": "tsc -p tsconfig.prod.json",
|
|
39
|
+
"build:es": "tsc -p tsconfig.prod.json -m esNext --outDir esm",
|
|
40
40
|
"build": "yarn clean && yarn build:cjs && yarn build:es",
|
|
41
41
|
"clean": "rimraf lib esm",
|
|
42
42
|
"format": "prettier --check .",
|
|
@@ -44,24 +44,29 @@
|
|
|
44
44
|
"lint": "eslint .",
|
|
45
45
|
"lint:fix": "eslint . --fix",
|
|
46
46
|
"lint:types": "tsc --noEmit",
|
|
47
|
+
"test": "jest",
|
|
47
48
|
"semantic-release": "semantic-release"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
|
-
"@commitlint/cli": "^17.
|
|
51
|
-
"@commitlint/config-conventional": "^17.
|
|
51
|
+
"@commitlint/cli": "^17.7.1",
|
|
52
|
+
"@commitlint/config-conventional": "^17.7.0",
|
|
53
|
+
"@types/jest": "^29.5.3",
|
|
52
54
|
"@types/react": "^18.0.9",
|
|
53
55
|
"@types/react-dom": "^18.0.4",
|
|
54
|
-
"eslint": "^8.
|
|
55
|
-
"eslint-config-prettier": "^
|
|
56
|
+
"eslint": "^8.47.0",
|
|
57
|
+
"eslint-config-prettier": "^9.0.0",
|
|
56
58
|
"eslint-config-react-app": "^7.0.1",
|
|
57
|
-
"eslint-plugin-simple-import-sort": "^
|
|
59
|
+
"eslint-plugin-simple-import-sort": "^10.0.0",
|
|
58
60
|
"husky": "^8.0.1",
|
|
59
|
-
"
|
|
61
|
+
"jest": "^29.6.2",
|
|
62
|
+
"lint-staged": "^14.0.0",
|
|
60
63
|
"prettier": "^2.6.2",
|
|
61
64
|
"react": "^18.1.0",
|
|
62
65
|
"react-dom": "^18.1.0",
|
|
63
66
|
"rimraf": "^3.0.2",
|
|
64
67
|
"semantic-release": "^21.0.7",
|
|
68
|
+
"ts-jest": "^29.1.1",
|
|
69
|
+
"ts-node": "^10.9.1",
|
|
65
70
|
"typescript": "^4.6.4"
|
|
66
71
|
},
|
|
67
72
|
"peerDependencies": {
|