state-jet 1.0.6 → 1.0.8
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 +23 -11
- package/dist/crdt.js +7 -12
- package/dist/derived.js +1 -5
- package/dist/devtools.js +4 -11
- package/dist/encryption.js +6 -13
- package/dist/global.js +12 -0
- package/dist/hooks.js +4 -6
- package/dist/index.js +5 -17
- package/dist/middleware.js +11 -29
- package/dist/optimistic.js +1 -5
- package/dist/persistence.js +2 -7
- package/dist/store.js +21 -27
- package/dist/types/crdt.d.ts +3 -0
- package/dist/types/crdt.d.ts.map +1 -0
- package/dist/types/derived.d.ts +2 -0
- package/dist/types/derived.d.ts.map +1 -0
- package/dist/types/devtools.d.ts +5 -0
- package/dist/types/devtools.d.ts.map +1 -0
- package/dist/types/encryption.d.ts +5 -0
- package/dist/types/encryption.d.ts.map +1 -0
- package/dist/types/global.d.ts +2 -0
- package/dist/types/global.d.ts.map +1 -0
- package/dist/types/hooks.d.ts +3 -0
- package/dist/types/hooks.d.ts.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/middleware.d.ts +12 -0
- package/dist/types/middleware.d.ts.map +1 -0
- package/dist/types/optimistic.d.ts +2 -0
- package/dist/types/optimistic.d.ts.map +1 -0
- package/dist/types/persistence.d.ts +3 -0
- package/dist/types/persistence.d.ts.map +1 -0
- package/dist/types/store.d.ts +13 -0
- package/dist/types/store.d.ts.map +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -27,14 +27,26 @@ function Counter() {
|
|
|
27
27
|
|
|
28
28
|
## ⚡ Comparison Table
|
|
29
29
|
|
|
30
|
-
|Feature|Redux|Recoil|MobX|Jotai|state-jet|
|
|
31
|
-
|
|
32
|
-
|Setup Required
|
|
33
|
-
|Bundle Size
|
|
34
|
-
|Reactivity
|
|
35
|
-
|Renders Only Affected
|
|
36
|
-
|Derived/Computed State
|
|
37
|
-
|Optimistic Updates
|
|
38
|
-
|Undo/Redo
|
|
39
|
-
|
|
|
40
|
-
|
|
30
|
+
| Feature | Redux | Recoil | MobX | Jotai | Zustand | state-jet |
|
|
31
|
+
| ------------------------ | ----------- | --------- | ------------- | --------- | ---------------------- | --------------------- |
|
|
32
|
+
| Setup Required | ✅ Yes | ✅ Yes | ⚠️ Yes | ❌ No | ⚠️ Minimal | ❌ No |
|
|
33
|
+
| Bundle Size | 🚀 Large | 🚀 Medium | ⚡ Small | ⚡ Small | ⚡ Small | 🔥 Ultra-Small |
|
|
34
|
+
| Reactivity | ⚠️ Reducers | ✅ Atoms | ✅ Proxy-Based | ✅ Signals | ✅ Proxy-Based | ✅ Signal-Like |
|
|
35
|
+
| Renders Only Affected | ❌ No | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
|
|
36
|
+
| Derived/Computed State | ❌ No | ✅ Yes | ✅ Yes | ✅ Yes | ⚠️ Manual Selectors | ✅ Yes (Automatic) |
|
|
37
|
+
| Optimistic Updates | ❌ No | ❌ No | ❌ No | ❌ No | ⚠️ Requires Middleware | ✅ Built-in |
|
|
38
|
+
| Undo/Redo | ❌ No | ❌ No | ❌ No | ❌ No | ⚠️ Requires Middleware | ✅ Built-in | |
|
|
39
|
+
| CRDT Conflict Resolution | ❌ No | ❌ No | ❌ No | ❌ No | ❌ No | ✅ Yes |
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
## ⚡ Why state-jet Is More Advanced Than Zustand
|
|
43
|
+
|
|
44
|
+
**No Proxies Needed** → Zustand uses proxies for state updates, but state-jet uses signals, making it even faster.
|
|
45
|
+
**Derived State Is Automatic** → No need for selectors; state updates only trigger where necessary.
|
|
46
|
+
**Optimistic Updates & Rollback** → Unlike Zustand, state-jet has built-in support for instant UI updates and auto-revert on failures.
|
|
47
|
+
**Multi-Tab Sync** → WebSocket and IndexedDB syncing, so global state persists across browser tabs and devices.
|
|
48
|
+
**CRDT Support** → Automatic conflict resolution for real-time apps, something even Zustand lacks.
|
|
49
|
+
|
|
50
|
+
✅ Conclusion
|
|
51
|
+
|
|
52
|
+
If you need the simplest, fastest, and most advanced state management solution for React, state-jet beats Redux, Recoil, MobX, Jotai, and even Zustand in performance, reactivity, and developer experience. 🚀
|
package/dist/crdt.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const store_1 = require("./store");
|
|
5
|
-
const mergeCRDT = (localState, remoteState) => {
|
|
6
|
-
return Object.assign(Object.assign(Object.assign({}, localState), remoteState), { lastUpdated: Date.now() });
|
|
1
|
+
import { useStateGlobal } from "./store";
|
|
2
|
+
export const mergeCRDT = (localState, remoteState) => {
|
|
3
|
+
return { ...localState, ...remoteState, lastUpdated: Date.now() };
|
|
7
4
|
};
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
(0, store_1.useStateGlobal)(key).set(merged);
|
|
5
|
+
export const syncCRDT = (key, remoteState) => {
|
|
6
|
+
const localState = useStateGlobal(key).useStore();
|
|
7
|
+
const merged = mergeCRDT(localState, remoteState);
|
|
8
|
+
useStateGlobal(key).set(merged);
|
|
13
9
|
};
|
|
14
|
-
exports.syncCRDT = syncCRDT;
|
package/dist/derived.js
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.derivedState = void 0;
|
|
4
|
-
const derivedState = (dependencies, computeFn) => {
|
|
1
|
+
export const derivedState = (dependencies, computeFn) => {
|
|
5
2
|
const derived = { value: computeFn(...dependencies.map((d) => d.useStore())) };
|
|
6
3
|
dependencies.forEach(dep => dep.useStore().listeners.add(() => {
|
|
7
4
|
derived.value = computeFn(...dependencies.map(d => d.useStore()));
|
|
8
5
|
}));
|
|
9
6
|
return () => derived.value;
|
|
10
7
|
};
|
|
11
|
-
exports.derivedState = derivedState;
|
package/dist/devtools.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.redoState = exports.undoState = exports.measurePerformance = exports.notifyDevTools = void 0;
|
|
4
1
|
const stateHistory = {};
|
|
5
2
|
const stateIndex = {};
|
|
6
3
|
const performanceData = {};
|
|
7
4
|
const devtoolsEnabled = typeof window !== "undefined" && window.__STATE_JET_DEVTOOLS__;
|
|
8
|
-
const notifyDevTools = (key, value) => {
|
|
5
|
+
export const notifyDevTools = (key, value) => {
|
|
9
6
|
if (!stateHistory[key])
|
|
10
7
|
stateHistory[key] = [];
|
|
11
8
|
if (stateIndex[key] === undefined)
|
|
@@ -18,8 +15,7 @@ const notifyDevTools = (key, value) => {
|
|
|
18
15
|
window.__STATE_JET_DEVTOOLS__.updateState(key, value, stateHistory[key]);
|
|
19
16
|
}
|
|
20
17
|
};
|
|
21
|
-
|
|
22
|
-
const measurePerformance = (key, callback) => {
|
|
18
|
+
export const measurePerformance = (key, callback) => {
|
|
23
19
|
const start = performance.now();
|
|
24
20
|
callback();
|
|
25
21
|
const duration = performance.now() - start;
|
|
@@ -30,18 +26,15 @@ const measurePerformance = (key, callback) => {
|
|
|
30
26
|
window.__STATE_JET_DEVTOOLS__.updatePerformance(key, duration);
|
|
31
27
|
}
|
|
32
28
|
};
|
|
33
|
-
|
|
34
|
-
const undoState = (key) => {
|
|
29
|
+
export const undoState = (key) => {
|
|
35
30
|
if (stateIndex[key] > 0) {
|
|
36
31
|
stateIndex[key]--;
|
|
37
32
|
return stateHistory[key][stateIndex[key]];
|
|
38
33
|
}
|
|
39
34
|
};
|
|
40
|
-
|
|
41
|
-
const redoState = (key) => {
|
|
35
|
+
export const redoState = (key) => {
|
|
42
36
|
if (stateIndex[key] < stateHistory[key].length - 1) {
|
|
43
37
|
stateIndex[key]++;
|
|
44
38
|
return stateHistory[key][stateIndex[key]];
|
|
45
39
|
}
|
|
46
40
|
};
|
|
47
|
-
exports.redoState = redoState;
|
package/dist/encryption.js
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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));
|
|
1
|
+
export const encrypt = (data) => btoa(JSON.stringify(data));
|
|
2
|
+
export const decrypt = (data) => JSON.parse(atob(data));
|
|
3
|
+
export const saveEncryptedState = (key, value) => {
|
|
4
|
+
localStorage.setItem(key, encrypt(value));
|
|
10
5
|
};
|
|
11
|
-
|
|
12
|
-
const loadEncryptedState = (key) => {
|
|
6
|
+
export const loadEncryptedState = (key) => {
|
|
13
7
|
const data = localStorage.getItem(key);
|
|
14
|
-
return data ?
|
|
8
|
+
return data ? decrypt(data) : null;
|
|
15
9
|
};
|
|
16
|
-
exports.loadEncryptedState = loadEncryptedState;
|
package/dist/global.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const getGlobalThis = () => {
|
|
2
|
+
if (typeof globalThis === 'object' && globalThis)
|
|
3
|
+
return globalThis;
|
|
4
|
+
if (typeof self === 'object' && self)
|
|
5
|
+
return self;
|
|
6
|
+
if (typeof window === 'object' && window)
|
|
7
|
+
return window;
|
|
8
|
+
if (typeof this === 'object' && this)
|
|
9
|
+
return this;
|
|
10
|
+
throw new Error('Unable to locate global `this`');
|
|
11
|
+
};
|
|
12
|
+
export const globalObject = getGlobalThis();
|
package/dist/hooks.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useSyncExternalStore = useSyncExternalStore;
|
|
4
|
-
const react_1 = require("react");
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
5
2
|
function useSyncExternalStore(subscribe, getSnapshot) {
|
|
6
3
|
// State to hold the current snapshot of the store
|
|
7
|
-
const [snapshot, setSnapshot] =
|
|
4
|
+
const [snapshot, setSnapshot] = useState(getSnapshot());
|
|
8
5
|
// Effect to subscribe to the external store
|
|
9
|
-
|
|
6
|
+
useEffect(() => {
|
|
10
7
|
// Function to update the snapshot when the store changes
|
|
11
8
|
const handleStoreChange = () => {
|
|
12
9
|
setSnapshot(getSnapshot());
|
|
@@ -23,3 +20,4 @@ function useSyncExternalStore(subscribe, getSnapshot) {
|
|
|
23
20
|
// Return the current snapshot
|
|
24
21
|
return snapshot;
|
|
25
22
|
}
|
|
23
|
+
export { useSyncExternalStore };
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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; } });
|
|
1
|
+
export { useStateGlobal } from "./store";
|
|
2
|
+
export { saveState, restoreState } from "./persistence";
|
|
3
|
+
export { optimisticUpdate } from "./optimistic";
|
|
4
|
+
export { encrypt, decrypt, saveEncryptedState, loadEncryptedState } from "./encryption";
|
|
5
|
+
export { syncCRDT } from "./crdt";
|
package/dist/middleware.js
CHANGED
|
@@ -1,36 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.debounceMiddleware = exports.reducerMiddleware = exports.optimisticMiddleware = exports.validateAgeMiddleware = exports.apiSyncMiddleware = exports.loggerMiddleware = void 0;
|
|
13
|
-
const loggerMiddleware = (key, prev, next) => {
|
|
1
|
+
export const loggerMiddleware = (key, prev, next) => {
|
|
14
2
|
console.log(`[state-jet] ${key}: ${prev} → ${next}`);
|
|
15
3
|
};
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
exports.apiSyncMiddleware = apiSyncMiddleware;
|
|
21
|
-
const validateAgeMiddleware = (key, prev, next) => {
|
|
4
|
+
export const apiSyncMiddleware = async (key, prev, next) => {
|
|
5
|
+
await fetch("/api/sync", { method: "POST", body: JSON.stringify({ key, next }) });
|
|
6
|
+
};
|
|
7
|
+
export const validateAgeMiddleware = (key, prev, next) => {
|
|
22
8
|
if (key === "age" && next < 0) {
|
|
23
9
|
console.warn("Age cannot be negative!");
|
|
24
10
|
return prev;
|
|
25
11
|
}
|
|
26
12
|
return next;
|
|
27
13
|
};
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return (key, prev, next, set) => __awaiter(void 0, void 0, void 0, function* () {
|
|
14
|
+
export const optimisticMiddleware = (apiUrl) => {
|
|
15
|
+
return async (key, prev, next, set) => {
|
|
31
16
|
set(next); // Optimistically update state
|
|
32
17
|
try {
|
|
33
|
-
|
|
18
|
+
await fetch(apiUrl, {
|
|
34
19
|
method: "POST",
|
|
35
20
|
body: JSON.stringify({ key, value: next }),
|
|
36
21
|
headers: { "Content-Type": "application/json" },
|
|
@@ -40,10 +25,9 @@ const optimisticMiddleware = (apiUrl) => {
|
|
|
40
25
|
console.warn(`[state-jet] Rollback: Failed to sync ${key}`);
|
|
41
26
|
set(prev); // Rollback state on failure
|
|
42
27
|
}
|
|
43
|
-
}
|
|
28
|
+
};
|
|
44
29
|
};
|
|
45
|
-
|
|
46
|
-
const reducerMiddleware = (key, prev, action) => {
|
|
30
|
+
export const reducerMiddleware = (key, prev, action) => {
|
|
47
31
|
switch (action.type) {
|
|
48
32
|
case "INCREMENT":
|
|
49
33
|
return prev + 1;
|
|
@@ -55,8 +39,7 @@ const reducerMiddleware = (key, prev, action) => {
|
|
|
55
39
|
return prev;
|
|
56
40
|
}
|
|
57
41
|
};
|
|
58
|
-
|
|
59
|
-
const debounceMiddleware = (delay) => {
|
|
42
|
+
export const debounceMiddleware = (delay) => {
|
|
60
43
|
let timer;
|
|
61
44
|
return (key, prev, next) => {
|
|
62
45
|
clearTimeout(timer);
|
|
@@ -66,4 +49,3 @@ const debounceMiddleware = (delay) => {
|
|
|
66
49
|
return prev; // Prevent immediate update
|
|
67
50
|
};
|
|
68
51
|
};
|
|
69
|
-
exports.debounceMiddleware = debounceMiddleware;
|
package/dist/optimistic.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.optimisticUpdate = void 0;
|
|
4
|
-
const optimisticUpdate = (setState, apiCall, fallback) => {
|
|
1
|
+
export const optimisticUpdate = (setState, apiCall, fallback) => {
|
|
5
2
|
const prevState = setState.useStore();
|
|
6
3
|
setState.set(apiCall(prevState));
|
|
7
4
|
apiCall()
|
|
8
5
|
.catch(() => setState.set(fallback ? fallback(prevState) : prevState));
|
|
9
6
|
};
|
|
10
|
-
exports.optimisticUpdate = optimisticUpdate;
|
package/dist/persistence.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.restoreState = exports.saveState = void 0;
|
|
4
|
-
const saveState = (key, value, encrypt = false) => {
|
|
1
|
+
export const saveState = (key, value, encrypt = false) => {
|
|
5
2
|
if (typeof window !== "undefined") {
|
|
6
3
|
let data = JSON.stringify(value);
|
|
7
4
|
if (encrypt)
|
|
@@ -9,11 +6,9 @@ const saveState = (key, value, encrypt = false) => {
|
|
|
9
6
|
localStorage.setItem(key, data);
|
|
10
7
|
}
|
|
11
8
|
};
|
|
12
|
-
|
|
13
|
-
const restoreState = (key) => {
|
|
9
|
+
export const restoreState = (key) => {
|
|
14
10
|
if (typeof window !== "undefined") {
|
|
15
11
|
const data = localStorage.getItem(key);
|
|
16
12
|
return data ? JSON.parse(atob(data)) : undefined;
|
|
17
13
|
}
|
|
18
14
|
};
|
|
19
|
-
exports.restoreState = restoreState;
|
package/dist/store.js
CHANGED
|
@@ -1,33 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const hooks_1 = require("./hooks");
|
|
7
|
-
const devtools_1 = require("./devtools");
|
|
1
|
+
import { produce } from "immer";
|
|
2
|
+
import { saveState, restoreState } from "./persistence";
|
|
3
|
+
import { useSyncExternalStore } from './hooks';
|
|
4
|
+
import { notifyDevTools, undoState, redoState, measurePerformance } from "./devtools";
|
|
5
|
+
import { globalObject } from "./global";
|
|
8
6
|
const store = new Map();
|
|
9
7
|
const pendingUpdates = new Map();
|
|
10
8
|
const history = {};
|
|
11
|
-
const useStateGlobal = (key, initialValue, options) => {
|
|
9
|
+
export const useStateGlobal = (key, initialValue, options) => {
|
|
12
10
|
if (!store.has(key)) {
|
|
13
11
|
store.set(key, { value: initialValue, listeners: new Set() });
|
|
14
|
-
if (options
|
|
15
|
-
|
|
12
|
+
if (options?.persist)
|
|
13
|
+
restoreState(key);
|
|
16
14
|
}
|
|
17
15
|
const state = store.get(key);
|
|
18
16
|
const undo = () => {
|
|
19
|
-
|
|
20
|
-
if ((_a = history[key]) === null || _a === void 0 ? void 0 : _a.past.length) {
|
|
17
|
+
if (history[key]?.past.length) {
|
|
21
18
|
history[key].future.unshift(history[key].present);
|
|
22
19
|
history[key].present = history[key].past.pop();
|
|
23
20
|
state.value = history[key].present;
|
|
24
21
|
state.listeners.forEach((listener) => listener());
|
|
25
|
-
|
|
22
|
+
undoState(key);
|
|
26
23
|
}
|
|
27
24
|
};
|
|
28
25
|
const batchUpdate = () => {
|
|
29
26
|
pendingUpdates.forEach((newValue, key) => {
|
|
30
|
-
var _a;
|
|
31
27
|
let nextValue = newValue;
|
|
32
28
|
let stateValue = state.value;
|
|
33
29
|
if (!history[key]) {
|
|
@@ -36,45 +32,44 @@ const useStateGlobal = (key, initialValue, options) => {
|
|
|
36
32
|
history[key].past.push(stateValue);
|
|
37
33
|
history[key].present = newValue;
|
|
38
34
|
history[key].future = [];
|
|
39
|
-
|
|
35
|
+
options?.middleware?.forEach((mw) => {
|
|
40
36
|
const result = mw(key, stateValue, nextValue);
|
|
41
37
|
if (result !== undefined)
|
|
42
38
|
nextValue = result;
|
|
43
39
|
});
|
|
44
40
|
if (typeof nextValue === "function") {
|
|
45
|
-
state.value =
|
|
41
|
+
state.value = produce(state.value, nextValue);
|
|
46
42
|
}
|
|
47
43
|
else if (stateValue !== nextValue) {
|
|
48
44
|
state.value = nextValue;
|
|
49
45
|
state.listeners.forEach((listener) => listener());
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (options
|
|
53
|
-
|
|
46
|
+
notifyDevTools(key, nextValue);
|
|
47
|
+
measurePerformance(key, () => { });
|
|
48
|
+
if (options?.persist)
|
|
49
|
+
saveState(key, nextValue, options.encrypt);
|
|
54
50
|
}
|
|
55
51
|
});
|
|
56
52
|
pendingUpdates.clear();
|
|
57
53
|
};
|
|
58
54
|
const redo = () => {
|
|
59
|
-
|
|
60
|
-
if ((_a = history[key]) === null || _a === void 0 ? void 0 : _a.future.length) {
|
|
55
|
+
if (history[key]?.future.length) {
|
|
61
56
|
history[key].past.push(history[key].present);
|
|
62
57
|
history[key].present = history[key].future.shift();
|
|
63
58
|
state.value = history[key].present;
|
|
64
59
|
state.listeners.forEach((listener) => listener());
|
|
65
|
-
|
|
60
|
+
redoState(key);
|
|
66
61
|
}
|
|
67
62
|
};
|
|
68
63
|
const useStore = () => {
|
|
69
|
-
return
|
|
64
|
+
return useSyncExternalStore((callback) => {
|
|
70
65
|
state.listeners.add(callback);
|
|
71
66
|
return () => state.listeners.delete(callback);
|
|
72
67
|
}, () => state.value);
|
|
73
68
|
};
|
|
74
69
|
const set = (newValue) => {
|
|
75
70
|
pendingUpdates.set(key, newValue);
|
|
76
|
-
if (window
|
|
77
|
-
window.requestAnimationFrame(batchUpdate);
|
|
71
|
+
if (globalObject?.window?.requestAnimationFrame)
|
|
72
|
+
globalObject.window.requestAnimationFrame(batchUpdate);
|
|
78
73
|
};
|
|
79
74
|
return {
|
|
80
75
|
useStore,
|
|
@@ -83,4 +78,3 @@ const useStateGlobal = (key, initialValue, options) => {
|
|
|
83
78
|
redo
|
|
84
79
|
};
|
|
85
80
|
};
|
|
86
|
-
exports.useStateGlobal = useStateGlobal;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crdt.d.ts","sourceRoot":"","sources":["../../src/crdt.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,SAAS,GAAI,YAAY,GAAG,EAAE,aAAa,GAAG,QAE1D,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM,EAAE,aAAa,GAAG,SAIrD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derived.d.ts","sourceRoot":"","sources":["../../src/derived.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,GAAI,cAAc,KAAK,CAAC,GAAG,CAAC,EAAE,WAAW,QAAQ,cAQzE,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const notifyDevTools: (key: string, value: any) => void;
|
|
2
|
+
export declare const measurePerformance: (key: string, callback: () => void) => void;
|
|
3
|
+
export declare const undoState: (key: string) => any;
|
|
4
|
+
export declare const redoState: (key: string) => any;
|
|
5
|
+
//# sourceMappingURL=devtools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devtools.d.ts","sourceRoot":"","sources":["../../src/devtools.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,EAAE,OAAO,GAAG,SAarD,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,KAAK,MAAM,EAAE,UAAU,MAAM,IAAI,SAWnE,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,KAAK,MAAM,QAKpC,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,KAAK,MAAM,QAKpC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const encrypt: (data: any) => string;
|
|
2
|
+
export declare const decrypt: (data: any) => any;
|
|
3
|
+
export declare const saveEncryptedState: (key: string, value: any) => void;
|
|
4
|
+
export declare const loadEncryptedState: (key: string) => any;
|
|
5
|
+
//# sourceMappingURL=encryption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../../src/encryption.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,GAAI,MAAM,GAAG,WAA+B,CAAC;AACjE,eAAO,MAAM,OAAO,GAAI,MAAM,GAAG,QAA2B,CAAC;AAE7D,eAAO,MAAM,kBAAkB,GAAI,KAAK,MAAM,EAAE,OAAO,GAAG,SAEzD,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,KAAK,MAAM,QAG7C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global.d.ts","sourceRoot":"","sources":["../../src/global.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,YAAY,EAAE,GAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":"AAEA,iBAAS,oBAAoB,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,OAyBvE;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { useStateGlobal } from "./store";
|
|
2
|
+
export { saveState, restoreState } from "./persistence";
|
|
3
|
+
export { optimisticUpdate } from "./optimistic";
|
|
4
|
+
export { encrypt, decrypt, saveEncryptedState, loadEncryptedState } from "./encryption";
|
|
5
|
+
export { syncCRDT } from "./crdt";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const loggerMiddleware: (key: string, prev: number, next: number) => void;
|
|
2
|
+
export declare const apiSyncMiddleware: (key: string, prev: number, next: number) => Promise<void>;
|
|
3
|
+
export declare const validateAgeMiddleware: (key: string, prev: number, next: number) => number;
|
|
4
|
+
export declare const optimisticMiddleware: (apiUrl: string) => (key: string, prev: number, next: number, set: any) => Promise<void>;
|
|
5
|
+
type Action<T> = {
|
|
6
|
+
type: string;
|
|
7
|
+
payload?: T;
|
|
8
|
+
};
|
|
9
|
+
export declare const reducerMiddleware: (key: string, prev: number, action: Action<any>) => number;
|
|
10
|
+
export declare const debounceMiddleware: (delay: number) => (key: string, prev: number, next: any) => number;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/middleware.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,MAAM,SAEvE,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAU,KAAK,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,MAAM,kBAE9E,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,KAAK,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,MAAM,WAM5E,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,MACjC,KAAK,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,MAAM,EAAE,KAAK,GAAG,kBAclE,CAAC;AAEF,KAAK,MAAM,CAAC,CAAC,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC;AAE/C,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,EAAE,MAAM,MAAM,EAAE,QAAQ,MAAM,CAAC,GAAG,CAAC,WAW/E,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO,MAAM,MAEpC,KAAK,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,GAAG,WAO7C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optimistic.d.ts","sourceRoot":"","sources":["../../src/optimistic.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,GAAI,UAAU,GAAG,EAAE,SAAS,GAAG,EAAE,UAAU,GAAG,SAMxE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../src/persistence.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,GAAI,KAAK,MAAM,EAAE,OAAO,GAAG,EAAE,iBAAe,SAMjE,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,QAKvC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type Middleware<T> = (key: string, prev: T, next: T) => T | void;
|
|
2
|
+
export declare const useStateGlobal: <T>(key: string, initialValue?: T, options?: {
|
|
3
|
+
middleware?: Middleware<T>[];
|
|
4
|
+
persist?: boolean;
|
|
5
|
+
encrypt?: boolean;
|
|
6
|
+
}) => {
|
|
7
|
+
useStore: () => any;
|
|
8
|
+
set: (newValue: T) => void;
|
|
9
|
+
undo: () => void;
|
|
10
|
+
redo: () => void;
|
|
11
|
+
};
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"AAOA,KAAK,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;AAMjE,eAAO,MAAM,cAAc,GAAI,CAAC,EAC5B,KAAK,MAAM,EACX,eAAe,CAAC,EAChB,UAAU;IAAE,UAAU,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE;;oBAkEzD,CAAC;;;CAW3B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "state-jet",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Ultra-lightweight global state management for React",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
6
|
+
"types": "dist/types/index.d.ts",
|
|
7
7
|
"module": "dist/index.mjs",
|
|
8
8
|
"files": [
|
|
9
9
|
"dist"
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"build": "tsc",
|
|
37
37
|
"test": "vitest",
|
|
38
38
|
"clean": "rm -rf dist/*",
|
|
39
|
+
"prepare": "npm run build",
|
|
39
40
|
"publish:npm": "npm publish --access public",
|
|
40
41
|
"lint": "eslint src --ext .ts,.tsx"
|
|
41
42
|
},
|