isthor 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/README.md +78 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +54 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# ⚡ Isthor
|
|
2
|
+
|
|
3
|
+
**Isthor** is a minimalist, type-safe, and reactive state management library for React, powered by **Zod** and **JavaScript Proxies**.
|
|
4
|
+
|
|
5
|
+
No Providers, no boilerplate, just pure reactivity.
|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
- **Runtime Validation**: Your state is always valid, thanks to Zod.
|
|
10
|
+
- **Invisible Reactivity**: Update state like a normal object; your UI reacts instantly.
|
|
11
|
+
- **Zero Boilerplate**: No context providers or complex actions needed.
|
|
12
|
+
- **Global & Decoupled**: Update state from anywhere, even outside React components.
|
|
13
|
+
|
|
14
|
+
## 🚀 Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
bun install isthor zod
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 🛠️ Usage
|
|
21
|
+
|
|
22
|
+
### 1. Define your store
|
|
23
|
+
|
|
24
|
+
Create a schema and initialize your store. It returns a tuple: the proxy object for updates and a hook for React components.
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
// store.ts
|
|
28
|
+
import isthor from "isthor";
|
|
29
|
+
import { z } from "zod";
|
|
30
|
+
|
|
31
|
+
const UserSchema = z.object({
|
|
32
|
+
name: z.string().min(2),
|
|
33
|
+
points: z.number(),
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export const [user, useUser] = isthor(UserSchema, {
|
|
37
|
+
name: "Zaqueu",
|
|
38
|
+
points: 0,
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2. Consume and Update in React
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { user, useUser } from "./store";
|
|
46
|
+
|
|
47
|
+
export default function App() {
|
|
48
|
+
const state = useUser(); // Reactive hook
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div>
|
|
52
|
+
<h1>{state.name}: {state.points}pts</h1>
|
|
53
|
+
|
|
54
|
+
{/* Update the object directly! */}
|
|
55
|
+
<button onClick={() => user.points++}>
|
|
56
|
+
Add Point
|
|
57
|
+
</button>
|
|
58
|
+
|
|
59
|
+
<input
|
|
60
|
+
onChange={(e) => (user.name = e.target.value)}
|
|
61
|
+
placeholder="Update name"
|
|
62
|
+
/>
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 🧠 How it works
|
|
69
|
+
|
|
70
|
+
Isthor uses a Proxy to intercept property assignments. When you change a value, it:
|
|
71
|
+
|
|
72
|
+
1. Validates the change against your Zod schema.
|
|
73
|
+
2. Updates the internal storage.
|
|
74
|
+
3. Notifies all subscribed hooks via a WeakMap-based observer system.
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
|
|
78
|
+
MIT © Zaqueu Nilton
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
const listeners = new WeakMap();
|
|
3
|
+
function notify(target) {
|
|
4
|
+
const subs = listeners.get(target);
|
|
5
|
+
if (subs) {
|
|
6
|
+
subs.forEach((callback) => callback());
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
function subscribe(target, callback) {
|
|
10
|
+
if (!listeners.has(target)) {
|
|
11
|
+
listeners.set(target, new Set());
|
|
12
|
+
}
|
|
13
|
+
listeners.get(target).add(callback);
|
|
14
|
+
return () => {
|
|
15
|
+
listeners.get(target)?.delete(callback);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export default function isthor(schema, initialData) {
|
|
19
|
+
let _storage = initialData ?? {};
|
|
20
|
+
const proxy = new Proxy(_storage, {
|
|
21
|
+
get(target, prop) {
|
|
22
|
+
return Reflect.get(target, prop);
|
|
23
|
+
},
|
|
24
|
+
set(target, prop, value) {
|
|
25
|
+
const key = prop;
|
|
26
|
+
try {
|
|
27
|
+
const fieldSchema = schema.shape[key];
|
|
28
|
+
if (fieldSchema) {
|
|
29
|
+
fieldSchema.parse(value);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
console.error(`⚡ Isthor: Erro de validação na chave "${String(prop)}":`, error);
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const success = Reflect.set(target, prop, value);
|
|
37
|
+
if (success) {
|
|
38
|
+
notify(proxy);
|
|
39
|
+
}
|
|
40
|
+
return success;
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
function useStore() {
|
|
44
|
+
const [, setTick] = useState(0);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
const unsub = subscribe(proxy, () => {
|
|
47
|
+
setTick((t) => t + 1);
|
|
48
|
+
});
|
|
49
|
+
return unsub;
|
|
50
|
+
}, []);
|
|
51
|
+
return proxy;
|
|
52
|
+
}
|
|
53
|
+
return [proxy, useStore];
|
|
54
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "isthor",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Minimalist reactive state management powered by Zod and Proxies.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc -w",
|
|
13
|
+
"prepublishOnly": "bun run build"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"react",
|
|
17
|
+
"state",
|
|
18
|
+
"management",
|
|
19
|
+
"zod",
|
|
20
|
+
"proxy",
|
|
21
|
+
"reactive"
|
|
22
|
+
],
|
|
23
|
+
"author": "Zaqueu Nilton",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"zod": "^3.0.0"
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"react": ">=16.8.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/react": "^18.0.0",
|
|
33
|
+
"react": "^18.0.0",
|
|
34
|
+
"typescript": "^5.0.0"
|
|
35
|
+
}
|
|
36
|
+
}
|