state-jet 1.0.1 → 1.0.2
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 +14 -0
- package/dist/example/App.js +12 -0
- package/dist/src/crdt.js +14 -0
- package/dist/src/derived.js +11 -0
- package/dist/src/encryption.js +16 -0
- package/dist/src/index.js +17 -0
- package/dist/src/optimistic.js +10 -0
- package/dist/src/persistence.js +19 -0
- package/dist/{index.js → src/store.js} +6 -6
- package/package.json +5 -9
- /package/dist/{devtools.js → src/devtools.js} +0 -0
- /package/dist/{middleware.js → src/middleware.js} +0 -0
package/README.md
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# ⚡ fast-state: Ultra-Lightweight Global State for React
|
|
2
|
+
|
|
3
|
+
A zero-boilerplate, ultra-fast global state management library for React. No context, reducers, or providers—just simple reactive state.
|
|
4
|
+
|
|
5
|
+
## 🚀 Why fast-state?
|
|
6
|
+
- ✅ **No Context, No Providers** – Works outside React, reducing unnecessary re-renders.
|
|
7
|
+
- ✅ **Automatic Re-Renders** – Only components using specific state values update.
|
|
8
|
+
- ✅ **Super Lightweight** – Less than **1KB** minified!
|
|
9
|
+
- ✅ **SSR & Next.js Support** – Works on both client and server.
|
|
10
|
+
|
|
11
|
+
## 🛠 Installation
|
|
12
|
+
```bash
|
|
13
|
+
npm install state-jet
|
|
14
|
+
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = App;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const index_1 = require("../src/index");
|
|
6
|
+
const middleware_1 = require("../src/middleware");
|
|
7
|
+
const counter = (0, index_1.useStateGlobal)("counter", 0, { middleware: [middleware_1.loggerMiddleware] });
|
|
8
|
+
function App() {
|
|
9
|
+
const { undo, redo } = counter;
|
|
10
|
+
const count = counter.useStore();
|
|
11
|
+
return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => counter.set(count + 1), children: "+" }), (0, jsx_runtime_1.jsx)("button", { onClick: () => counter.set(count - 1), children: "-" }), (0, jsx_runtime_1.jsx)("button", { onClick: undo, children: "Undo" }), (0, jsx_runtime_1.jsx)("button", { onClick: redo, children: "Redo" }), (0, jsx_runtime_1.jsxs)("p", { children: ["Count: ", count] })] }));
|
|
12
|
+
}
|
package/dist/src/crdt.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.syncCRDT = exports.mergeCRDT = void 0;
|
|
4
|
+
const store_1 = require("./store");
|
|
5
|
+
const mergeCRDT = (localState, remoteState) => {
|
|
6
|
+
return Object.assign(Object.assign(Object.assign({}, localState), remoteState), { lastUpdated: Date.now() });
|
|
7
|
+
};
|
|
8
|
+
exports.mergeCRDT = mergeCRDT;
|
|
9
|
+
const syncCRDT = (key, remoteState) => {
|
|
10
|
+
const localState = (0, store_1.useStateGlobal)(key).useStore();
|
|
11
|
+
const merged = (0, exports.mergeCRDT)(localState, remoteState);
|
|
12
|
+
(0, store_1.useStateGlobal)(key).set(merged);
|
|
13
|
+
};
|
|
14
|
+
exports.syncCRDT = syncCRDT;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.derivedState = void 0;
|
|
4
|
+
const derivedState = (dependencies, computeFn) => {
|
|
5
|
+
const derived = { value: computeFn(...dependencies.map((d) => d.useStore())) };
|
|
6
|
+
dependencies.forEach(dep => dep.useStore().listeners.add(() => {
|
|
7
|
+
derived.value = computeFn(...dependencies.map(d => d.useStore()));
|
|
8
|
+
}));
|
|
9
|
+
return () => derived.value;
|
|
10
|
+
};
|
|
11
|
+
exports.derivedState = derivedState;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadEncryptedState = exports.saveEncryptedState = exports.decrypt = exports.encrypt = void 0;
|
|
4
|
+
const encrypt = (data) => btoa(JSON.stringify(data));
|
|
5
|
+
exports.encrypt = encrypt;
|
|
6
|
+
const decrypt = (data) => JSON.parse(atob(data));
|
|
7
|
+
exports.decrypt = decrypt;
|
|
8
|
+
const saveEncryptedState = (key, value) => {
|
|
9
|
+
localStorage.setItem(key, (0, exports.encrypt)(value));
|
|
10
|
+
};
|
|
11
|
+
exports.saveEncryptedState = saveEncryptedState;
|
|
12
|
+
const loadEncryptedState = (key) => {
|
|
13
|
+
const data = localStorage.getItem(key);
|
|
14
|
+
return data ? (0, exports.decrypt)(data) : null;
|
|
15
|
+
};
|
|
16
|
+
exports.loadEncryptedState = loadEncryptedState;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.syncCRDT = exports.loadEncryptedState = exports.saveEncryptedState = exports.decrypt = exports.encrypt = exports.optimisticUpdate = exports.restoreState = exports.saveState = exports.useStateGlobal = void 0;
|
|
4
|
+
var store_1 = require("./store");
|
|
5
|
+
Object.defineProperty(exports, "useStateGlobal", { enumerable: true, get: function () { return store_1.useStateGlobal; } });
|
|
6
|
+
var persistence_1 = require("./persistence");
|
|
7
|
+
Object.defineProperty(exports, "saveState", { enumerable: true, get: function () { return persistence_1.saveState; } });
|
|
8
|
+
Object.defineProperty(exports, "restoreState", { enumerable: true, get: function () { return persistence_1.restoreState; } });
|
|
9
|
+
var optimistic_1 = require("./optimistic");
|
|
10
|
+
Object.defineProperty(exports, "optimisticUpdate", { enumerable: true, get: function () { return optimistic_1.optimisticUpdate; } });
|
|
11
|
+
var encryption_1 = require("./encryption");
|
|
12
|
+
Object.defineProperty(exports, "encrypt", { enumerable: true, get: function () { return encryption_1.encrypt; } });
|
|
13
|
+
Object.defineProperty(exports, "decrypt", { enumerable: true, get: function () { return encryption_1.decrypt; } });
|
|
14
|
+
Object.defineProperty(exports, "saveEncryptedState", { enumerable: true, get: function () { return encryption_1.saveEncryptedState; } });
|
|
15
|
+
Object.defineProperty(exports, "loadEncryptedState", { enumerable: true, get: function () { return encryption_1.loadEncryptedState; } });
|
|
16
|
+
var crdt_1 = require("./crdt");
|
|
17
|
+
Object.defineProperty(exports, "syncCRDT", { enumerable: true, get: function () { return crdt_1.syncCRDT; } });
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.optimisticUpdate = void 0;
|
|
4
|
+
const optimisticUpdate = (setState, apiCall, fallback) => {
|
|
5
|
+
const prevState = setState.useStore();
|
|
6
|
+
setState.set(apiCall(prevState));
|
|
7
|
+
apiCall()
|
|
8
|
+
.catch(() => setState.set(fallback ? fallback(prevState) : prevState));
|
|
9
|
+
};
|
|
10
|
+
exports.optimisticUpdate = optimisticUpdate;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.restoreState = exports.saveState = void 0;
|
|
4
|
+
const saveState = (key, value, encrypt = false) => {
|
|
5
|
+
if (typeof window !== "undefined") {
|
|
6
|
+
let data = JSON.stringify(value);
|
|
7
|
+
if (encrypt)
|
|
8
|
+
data = btoa(data);
|
|
9
|
+
localStorage.setItem(key, data);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
exports.saveState = saveState;
|
|
13
|
+
const restoreState = (key) => {
|
|
14
|
+
if (typeof window !== "undefined") {
|
|
15
|
+
const data = localStorage.getItem(key);
|
|
16
|
+
return data ? JSON.parse(atob(data)) : undefined;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
exports.restoreState = restoreState;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.useStateGlobal = void 0;
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
const immer_1 = require("immer");
|
|
6
|
+
const persistence_1 = require("./persistence");
|
|
6
7
|
const devtools_1 = require("./devtools");
|
|
7
8
|
const store = new Map();
|
|
8
9
|
const pendingUpdates = new Map();
|
|
@@ -10,13 +11,10 @@ const history = {};
|
|
|
10
11
|
const useStateGlobal = (key, initialValue, options) => {
|
|
11
12
|
if (!store.has(key)) {
|
|
12
13
|
store.set(key, { value: initialValue, listeners: new Set() });
|
|
14
|
+
if (options === null || options === void 0 ? void 0 : options.persist)
|
|
15
|
+
(0, persistence_1.restoreState)(key);
|
|
13
16
|
}
|
|
14
|
-
const state =
|
|
15
|
-
if (!store.has(key)) {
|
|
16
|
-
store.set(key, { value: initialValue, listeners: new Set() });
|
|
17
|
-
}
|
|
18
|
-
return store.get(key);
|
|
19
|
-
}, [key]);
|
|
17
|
+
const state = store.get(key);
|
|
20
18
|
const undo = () => {
|
|
21
19
|
var _a;
|
|
22
20
|
if ((_a = history[key]) === null || _a === void 0 ? void 0 : _a.past.length) {
|
|
@@ -51,6 +49,8 @@ const useStateGlobal = (key, initialValue, options) => {
|
|
|
51
49
|
state.listeners.forEach((listener) => listener());
|
|
52
50
|
(0, devtools_1.notifyDevTools)(key, nextValue);
|
|
53
51
|
(0, devtools_1.measurePerformance)(key, () => { });
|
|
52
|
+
if (options === null || options === void 0 ? void 0 : options.persist)
|
|
53
|
+
(0, persistence_1.saveState)(key, nextValue, options.encrypt);
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
pendingUpdates.clear();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "state-jet",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Ultra-lightweight global state management for React",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -32,23 +32,22 @@
|
|
|
32
32
|
"test": "vitest",
|
|
33
33
|
"clean": "rm -rf dist/*",
|
|
34
34
|
"publish:npm": "npm publish --access public",
|
|
35
|
-
"lint": "eslint src --ext .ts,.tsx"
|
|
36
|
-
"prepare": "npm run clean && npm run build"
|
|
35
|
+
"lint": "eslint src --ext .ts,.tsx"
|
|
37
36
|
},
|
|
38
37
|
"devDependencies": {
|
|
38
|
+
"@types/react": "^19.0.3",
|
|
39
|
+
"@types/react-dom": "^19.0.2",
|
|
39
40
|
"eslint": "^8.57.1",
|
|
40
41
|
"immer": "^10.1.1",
|
|
41
42
|
"react": "19.0.0",
|
|
42
43
|
"react-dom": "19.0.0",
|
|
43
44
|
"typescript": "^5.7.3",
|
|
44
|
-
"use-sync-external-store": "^1.4.0",
|
|
45
45
|
"vitest": "^2.1.8"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"@types/react": ">=18.0.0",
|
|
49
49
|
"immer": ">=9.0.6",
|
|
50
|
-
"react": ">=18.0.0"
|
|
51
|
-
"use-sync-external-store": ">=1.2.0"
|
|
50
|
+
"react": ">=18.0.0"
|
|
52
51
|
},
|
|
53
52
|
"peerDependenciesMeta": {
|
|
54
53
|
"@types/react": {
|
|
@@ -59,9 +58,6 @@
|
|
|
59
58
|
},
|
|
60
59
|
"react": {
|
|
61
60
|
"optional": true
|
|
62
|
-
},
|
|
63
|
-
"use-sync-external-store": {
|
|
64
|
-
"optional": true
|
|
65
61
|
}
|
|
66
62
|
}
|
|
67
63
|
}
|
|
File without changes
|
|
File without changes
|