@pulse-js/core 0.2.1 → 0.3.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 CHANGED
@@ -1,172 +1,97 @@
1
1
  <div align="center">
2
-
3
2
  <img width="200" height="200" alt="logo" src="https://raw.githubusercontent.com/ZtaMDev/Pulse/refs/heads/main/pulse.svg" />
4
3
 
5
- # Pulse-JS
4
+ # Pulse-JS v2.0
6
5
 
7
- [![npm version](https://img.shields.io/npm/v/@pulse-js/core.svg)](https://www.npmjs.com/package/@pulse-js/core)
6
+ [![npm version](https://img.shields.io/npm/v/@pulse-js/core.svg?color=blue)](https://www.npmjs.com/package/@pulse-js/core)
8
7
 
9
- > A semantic reactivity system for modern applications. Separate reactive data (sources) from business conditions (guards) with a declarative, composable, and observable approach.
8
+ > A semantic reactivity system for modern applications. Separate reactive state (pulse) from business conditions (guards) with a declarative, composable, and proxied approach.
10
9
 
11
10
  Official [Documentation](https://pulse-js.vercel.app)
12
11
 
13
- Pulse differs from traditional signals or state managers by treating `Conditions` as first-class citizens. Instead of embedding complex boolean logic inside components or selectors, you define **Semantic Guards** that can be observed, composed, and debugged independently.
12
+ Pulse differs from traditional signals or state managers by treating `Conditions` as first-class citizens. Instead of embedding complex boolean logic inside components, you define **Semantic Guards** that are observed, composed, and debugged independently.
14
13
 
15
14
  </div>
16
15
 
17
16
  ## Installation
18
17
 
19
- ```bash
20
- npm install @pulse-js/core @pulse-js/tools
21
- ```
22
-
23
- ### or
24
-
25
18
  ```bash
26
19
  bun add @pulse-js/core @pulse-js/tools
27
20
  ```
28
21
 
29
- Pulse works with React via adapters like `@pulse-js/react`.
30
-
31
- ```bash
32
- bun add @pulse-js/react
33
- ```
34
-
35
22
  ## Core Concepts
36
23
 
37
- ### Sources (Refined Data)
24
+ ### Pulse Objects (Universal Reactivity)
38
25
 
39
- Sources are the primitive containers for your application state. They hold values and notify dependents when those values change.
26
+ `pulse()` creates a deep reactive Proxy. Use it for complex objects and arrays. Track property access automatically and mutate state directly.
40
27
 
41
28
  ```typescript
42
- import { source } from "@pulse-js/core";
29
+ import { pulse } from "@pulse-js/core";
30
+
31
+ const user = pulse({
32
+ name: "Alice",
33
+ role: "admin",
34
+ increment() {
35
+ this.stats.clicks++;
36
+ },
37
+ stats: { clicks: 0 },
38
+ });
43
39
 
44
- // Create a source
45
- const user = source({ name: "Alice", id: 1 });
46
- const rawCount = source(0);
40
+ // Mutate directly - it's reactive!
41
+ user.name = "Bob";
42
+ user.increment();
43
+ ```
47
44
 
48
- // Read the value (dependencies are tracked automatically if called inside a Guard)
49
- console.log(user());
45
+ ### Sources (Primitive Records)
50
46
 
51
- // Update the value
52
- user.set({ name: "Bob", id: 1 });
47
+ Sources are primitive containers for your application state. They hold values and notify dependents when those values change.
53
48
 
54
- // Update using a callback
55
- rawCount.update((n) => n + 1);
49
+ ```typescript
50
+ import { source } from "@pulse-js/core";
51
+ const count = source(0);
52
+ count.set(5);
56
53
  ```
57
54
 
58
55
  ### Guards (Semantic Logic)
59
56
 
60
- Guards represent business rules or derivations. A Guard is not just a boolean: it is a **Semantic Guard**—an observable rule with context. They track their own state including `status` (ok, fail, pending) and `reason` (why it failed).
57
+ Guards represent business rules or derivations. They act as high-performance **Selectors** with built-in dependency tracking and rich failure context.
61
58
 
62
59
  ```typescript
63
60
  import { guard } from "@pulse-js/core";
64
61
 
65
- // Synchronous Guard
66
- const isAdmin = guard("is-admin", () => {
62
+ const isAuthorized = guard("auth-check", async () => {
67
63
  const u = user();
68
- if (u.role !== "admin") return false; // Implicitly sets status to 'fail'
69
- return true;
70
- });
71
-
72
- // Guards can be checked explicitly
73
- if (isAdmin.ok()) {
74
- // Grant access
75
- } else {
76
- console.log(isAdmin.reason()); // e.g. "is-admin failed"
77
- }
78
- ```
79
-
80
- ### Computed Values
81
-
82
- You can derive new data from sources or other guards using `compute`. It works like a memoized transformation that automatically re-evaluates when dependencies change.
83
-
84
- ```typescript
85
- import { compute } from "@pulse-js/core";
86
-
87
- const fullName = compute("full-name", [firstName, lastName], (first, last) => {
88
- return `${first} ${last}`;
89
- });
90
- ```
91
-
92
- ### Async Guards & Race Control
93
-
94
- Pulse handles asynchronous logic natively. Guards can return Promises, and their status will automatically transition from `pending` to `ok` or `fail`.
95
-
96
- Pulse implements internal **runId versioning** to automatically cancel stale async evaluations if the underlying sources change multiple times before a promise resolves, preventing race conditions.
97
-
98
- ```typescript
99
- const isServerOnline = guard("check-server", async () => {
100
- const response = await fetch("/health");
101
- if (!response.ok) throw new Error("Server unreachable");
64
+ if (!u) return false;
102
65
  return true;
103
66
  });
104
67
  ```
105
68
 
106
69
  ### Explanable Guards
107
70
 
108
- For complex conditions, you can call `.explain()` to get a structured tree of the current status, failure reason, and the status of all direct dependencies.
71
+ Get a structured tree of the current status, failure reasons, and the status of all direct dependencies.
109
72
 
110
73
  ```ts
111
74
  const explanation = canCheckout.explain();
112
- console.log(explanation);
113
- // { status: 'fail', reason: 'auth failed', dependencies: [...] }
75
+ // { status: 'fail', reason: { code: 'AUTH', message: '...' }, dependencies: [...] }
114
76
  ```
115
77
 
116
- ## Server-Side Rendering (SSR)
117
-
118
- Pulse is designed with SSR in mind. It supports isomorphic rendering where async guards can be evaluated on the server, their state serialized, and then hydrated on the client.
119
-
120
- ### Server Side
121
-
122
- ```typescript
123
- import { evaluate } from "@pulse-js/core";
124
-
125
- // 1. Evaluate critical guards on the server
126
- const hydrationState = await evaluate([isUserAuthenticated, appSettings]);
127
-
128
- // 2. Serialize this state into your HTML
129
- const html = `
130
- <script>window.__PULSE_STATE__ = ${JSON.stringify(hydrationState)}</script>
131
- `;
132
- ```
133
-
134
- ### Client Side (Hydration)
135
-
136
- ```typescript
137
- import { hydrate } from "@pulse-js/core";
138
-
139
- // 1. Hydrate before rendering
140
- hydrate(window.__PULSE_STATE__);
141
- ```
142
-
143
- ### Mental Model
144
-
145
- Compare Pulse primitives:
146
-
147
- | Concept | Can be async | Has state | Observable | Purpose |
148
- | :---------- | :----------: | :-------: | :--------: | :----------------------------------- |
149
- | **Source** | ❌ | ❌ | ✅ | Reactive data (facts). |
150
- | **Guard** | ✅ | ✅ | ✅ | Business rules (conditioned truths). |
151
- | **Compute** | ❌ | ❌ | ✅ | Pure transformations (derivations). |
152
-
153
78
  ## Framework Integrations
154
79
 
155
- Pulse provides official adapters for major frameworks to ensure seamless integration.
80
+ Pulse provides official adapters for all major frameworks.
156
81
 
157
- | Framework | Package | Documentation |
158
- | :--------- | :----------------- | :----------------------------------------------------------- |
159
- | **React** | `@pulse-js/react` | [Read Docs](https://pulse-js.vercel.app/integrations/react) |
160
- | **Vue** | `@pulse-js/vue` | [Read Docs](https://pulse-js.vercel.app/integrations/vue) |
161
- | **Svelte** | `@pulse-js/svelte` | [Read Docs](https://pulse-js.vercel.app/integrations/svelte) |
82
+ | Framework | Package | Status |
83
+ | :----------- | :------------------- | :----- |
84
+ | **Astro** | `@pulse-js/astro` | NEW |
85
+ | **React** | `@pulse-js/react` | Stable |
86
+ | **Vue** | `@pulse-js/vue` | Stable |
87
+ | **Svelte** | `@pulse-js/svelte` | Stable |
88
+ | **TanStack** | `@pulse-js/tanstack` | NEW |
162
89
 
163
90
  ## Developer Tools
164
91
 
165
- Debug your reactive graph with **[Pulse Tools](https://pulse-js.vercel.app/guides/devtools/)**, a powerful framework-agnostic inspector.
166
-
167
- ### Features
92
+ Debug your reactive graph with **[Pulse Tools](https://pulse-js.vercel.app/guides/devtools/)**, a decoupled Agent-Client inspector.
168
93
 
169
- - **Component Tree**: Visualize your entire guard dependency graph.
170
- - **Editable Logic**: Update source values directly from the UI to test logic branches.
171
- - **Time Travel**: (Coming Soon) Replay state changes.
94
+ - **Agent-Client Architecture**: Isolated UI that doesn't restart your app.
95
+ - **Dependency Graph**: Visualize how your guards are connected.
96
+ - **Glassmorphism UI**: A premium, draggable development experience.
172
97
  - **Zero Config**: Works out of the box with `@pulse-js/tools`.