@rlabs-inc/signals 0.1.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 ADDED
@@ -0,0 +1,307 @@
1
+ # @rlabs-inc/signals
2
+
3
+ **Ultra-lightweight fine-grained reactivity for TypeScript**
4
+
5
+ A standalone reactive primitives library inspired by Svelte 5 runes, Solid.js, and Vue reactivity. Zero dependencies. ~700 lines of pure TypeScript.
6
+
7
+ ## Features
8
+
9
+ - **Fine-grained reactivity** - Only effects that read a signal re-run when it changes
10
+ - **Deep reactivity** - Objects and arrays are automatically deeply reactive
11
+ - **Lazy deriveds** - Computed values only recompute when read
12
+ - **Batching** - Group updates to prevent multiple re-runs
13
+ - **Reactive collections** - ReactiveMap, ReactiveSet, and reactiveArray
14
+ - **Zero dependencies** - Pure TypeScript, works everywhere
15
+ - **Tiny** - ~5KB minified
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ bun add @rlabs-inc/signals
21
+ # or
22
+ npm install @rlabs-inc/signals
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ```typescript
28
+ import { signal, effect, derived, state } from '@rlabs-inc/signals'
29
+
30
+ // Simple signal
31
+ const count = signal(0)
32
+
33
+ // Effect runs when dependencies change
34
+ effect(() => {
35
+ console.log('Count:', count.value)
36
+ })
37
+ // Logs: "Count: 0"
38
+
39
+ count.value = 1
40
+ // Logs: "Count: 1"
41
+
42
+ // Derived values
43
+ const doubled = derived(() => count.value * 2)
44
+ console.log(doubled.value) // 2
45
+
46
+ // Deep reactivity with state()
47
+ const user = state({
48
+ name: 'John',
49
+ address: {
50
+ city: 'NYC'
51
+ }
52
+ })
53
+
54
+ effect(() => {
55
+ console.log('City:', user.address.city)
56
+ })
57
+ // Logs: "City: NYC"
58
+
59
+ user.address.city = 'LA'
60
+ // Logs: "City: LA"
61
+ ```
62
+
63
+ ## API Reference
64
+
65
+ ### signal(initial, options?)
66
+
67
+ Create a reactive signal that holds a value.
68
+
69
+ ```typescript
70
+ const count = signal(0)
71
+ console.log(count.value) // 0
72
+
73
+ count.value = 5
74
+ console.log(count.value) // 5
75
+
76
+ // With custom equality
77
+ const obj = signal({ x: 1 }, {
78
+ equals: (a, b) => a.x === b.x
79
+ })
80
+ ```
81
+
82
+ ### effect(fn)
83
+
84
+ Create a reactive effect that re-runs when dependencies change.
85
+
86
+ ```typescript
87
+ const name = signal('John')
88
+
89
+ const dispose = effect(() => {
90
+ console.log('Hello,', name.value)
91
+
92
+ // Optional cleanup function
93
+ return () => {
94
+ console.log('Cleaning up...')
95
+ }
96
+ })
97
+
98
+ name.value = 'Jane' // Effect re-runs
99
+
100
+ dispose() // Stop the effect
101
+ ```
102
+
103
+ ### derived(fn, options?)
104
+
105
+ Create a computed/derived value that updates automatically.
106
+
107
+ ```typescript
108
+ const count = signal(5)
109
+ const doubled = derived(() => count.value * 2)
110
+
111
+ console.log(doubled.value) // 10
112
+
113
+ count.value = 10
114
+ console.log(doubled.value) // 20
115
+
116
+ // Alias: derived.by() (Svelte compatibility)
117
+ const tripled = derived.by(() => count.value * 3)
118
+ ```
119
+
120
+ ### state(initial)
121
+
122
+ Create a deeply reactive state object. All nested properties are automatically reactive.
123
+
124
+ ```typescript
125
+ const app = state({
126
+ user: {
127
+ name: 'John',
128
+ preferences: {
129
+ theme: 'dark'
130
+ }
131
+ },
132
+ items: [1, 2, 3]
133
+ })
134
+
135
+ effect(() => {
136
+ console.log(app.user.preferences.theme)
137
+ })
138
+
139
+ app.user.preferences.theme = 'light' // Triggers effect
140
+ app.items.push(4) // Arrays are reactive too
141
+ ```
142
+
143
+ ### batch(fn)
144
+
145
+ Batch multiple updates into a single reaction cycle.
146
+
147
+ ```typescript
148
+ const a = signal(1)
149
+ const b = signal(2)
150
+
151
+ effect(() => {
152
+ console.log('Sum:', a.value + b.value)
153
+ })
154
+ // Logs: "Sum: 3"
155
+
156
+ batch(() => {
157
+ a.value = 10
158
+ b.value = 20
159
+ })
160
+ // Logs: "Sum: 30" (only once, not twice)
161
+ ```
162
+
163
+ ### untrack(fn)
164
+
165
+ Read signals without creating dependencies.
166
+
167
+ ```typescript
168
+ const a = signal(1)
169
+ const b = signal(2)
170
+
171
+ effect(() => {
172
+ console.log('a:', a.value) // Creates dependency
173
+ untrack(() => {
174
+ console.log('b:', b.value) // Does NOT create dependency
175
+ })
176
+ })
177
+
178
+ b.value = 100 // Effect does NOT re-run
179
+ a.value = 100 // Effect re-runs
180
+ ```
181
+
182
+ ### watch(source, callback, options?)
183
+
184
+ Watch a signal and call callback when it changes.
185
+
186
+ ```typescript
187
+ const count = signal(0)
188
+
189
+ const dispose = watch(
190
+ () => count.value,
191
+ (newValue, oldValue) => {
192
+ console.log(`Changed from ${oldValue} to ${newValue}`)
193
+ }
194
+ )
195
+
196
+ count.value = 1 // Logs: "Changed from 0 to 1"
197
+
198
+ // With immediate option
199
+ watch(
200
+ () => count.value,
201
+ (value) => console.log('Value:', value),
202
+ { immediate: true }
203
+ )
204
+ // Logs immediately: "Value: 1"
205
+ ```
206
+
207
+ ### ReactiveMap
208
+
209
+ A reactive Map that triggers updates on modifications.
210
+
211
+ ```typescript
212
+ const map = new ReactiveMap<string, number>()
213
+
214
+ effect(() => {
215
+ console.log('Value:', map.get('key'))
216
+ })
217
+
218
+ map.set('key', 42) // Triggers effect
219
+ ```
220
+
221
+ ### ReactiveSet
222
+
223
+ A reactive Set that triggers updates on modifications.
224
+
225
+ ```typescript
226
+ const set = new ReactiveSet<string>()
227
+
228
+ effect(() => {
229
+ console.log('Has item:', set.has('item'))
230
+ })
231
+
232
+ set.add('item') // Triggers effect
233
+ ```
234
+
235
+ ### reactiveArray(initial?)
236
+
237
+ Create a reactive array with fine-grained reactivity.
238
+
239
+ ```typescript
240
+ const items = reactiveArray([1, 2, 3])
241
+
242
+ effect(() => {
243
+ console.log('First:', items[0])
244
+ console.log('Length:', items.length)
245
+ })
246
+
247
+ items[0] = 10 // Triggers effect
248
+ items.push(4) // Triggers effect
249
+ ```
250
+
251
+ ### Utilities
252
+
253
+ ```typescript
254
+ // Create read-only view
255
+ const count = signal(0)
256
+ const ro = readonly(count)
257
+ // ro.value = 5 // TypeScript error
258
+
259
+ // Read without tracking (alias for untrack)
260
+ const value = peek(() => count.value)
261
+
262
+ // Check if value is reactive
263
+ isReactive(someObject)
264
+
265
+ // Get raw object from reactive proxy
266
+ const raw = toRaw(reactiveObject)
267
+
268
+ // Create effect scope
269
+ const scope = effectScope()
270
+ scope.run(() => {
271
+ effect(() => { /* ... */ })
272
+ effect(() => { /* ... */ })
273
+ })
274
+ scope.stop() // Disposes all effects
275
+ ```
276
+
277
+ ## Comparison with Svelte 5
278
+
279
+ | Svelte 5 | @rlabs-inc/signals |
280
+ |----------|-------------------|
281
+ | `$state(value)` | `signal(value)` or `state(obj)` |
282
+ | `$derived(expr)` | `derived(() => expr)` |
283
+ | `$derived.by(fn)` | `derived.by(fn)` or `derived(fn)` |
284
+ | `$effect(fn)` | `effect(fn)` |
285
+ | `SvelteMap` | `ReactiveMap` |
286
+ | `SvelteSet` | `ReactiveSet` |
287
+
288
+ **Key differences:**
289
+ - No compiler needed - works with plain TypeScript
290
+ - Use `.value` to read/write signals (like Vue/Solid)
291
+ - No Happy DOM or browser environment required
292
+
293
+ ## Why?
294
+
295
+ We built this because:
296
+ 1. We love Svelte 5's reactivity model
297
+ 2. We wanted to use it outside Svelte components
298
+ 3. We didn't want the overhead of Happy DOM for server-side usage
299
+ 4. We needed a lightweight solution for libraries like [FatherStateDB](https://github.com/rlabs-inc/fatherstatedb)
300
+
301
+ ## License
302
+
303
+ MIT
304
+
305
+ ---
306
+
307
+ Built with ❤️ by RLabs Inc.
@@ -0,0 +1,268 @@
1
+ /** Cleanup function returned by effects */
2
+ export type CleanupFn = () => void;
3
+ /** Effect function that may return a cleanup */
4
+ export type EffectFn = () => void | CleanupFn;
5
+ /** Equality function for comparing values */
6
+ export type EqualityFn<T> = (a: T, b: T) => boolean;
7
+ /** A reactive signal that holds a value */
8
+ export interface Signal<T> {
9
+ readonly value: T;
10
+ }
11
+ /** A writable reactive signal */
12
+ export interface WritableSignal<T> extends Signal<T> {
13
+ value: T;
14
+ }
15
+ /** A derived/computed signal (read-only) */
16
+ export interface Derived<T> extends Signal<T> {
17
+ readonly value: T;
18
+ }
19
+ /** Options for creating a signal */
20
+ export interface SignalOptions<T> {
21
+ equals?: EqualityFn<T>;
22
+ }
23
+ /** Default equality check using Object.is */
24
+ export declare const defaultEquals: <T>(a: T, b: T) => boolean;
25
+ /** Shallow equality for objects/arrays */
26
+ export declare const shallowEquals: <T>(a: T, b: T) => boolean;
27
+ /**
28
+ * Create a reactive signal
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * const count = signal(0)
33
+ * console.log(count.value) // 0
34
+ * count.value = 1
35
+ * console.log(count.value) // 1
36
+ * ```
37
+ */
38
+ export declare function signal<T>(initial: T, options?: SignalOptions<T>): WritableSignal<T>;
39
+ /**
40
+ * Create a reactive effect that re-runs when dependencies change
41
+ *
42
+ * @returns Dispose function to stop the effect
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * const count = signal(0)
47
+ * const dispose = effect(() => {
48
+ * console.log('Count:', count.value)
49
+ * })
50
+ * // Logs: "Count: 0"
51
+ *
52
+ * count.value = 1
53
+ * // Logs: "Count: 1"
54
+ *
55
+ * dispose() // Stop the effect
56
+ * ```
57
+ */
58
+ export declare function effect(fn: EffectFn): CleanupFn;
59
+ /**
60
+ * Create a derived/computed value that automatically updates
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * const count = signal(0)
65
+ * const doubled = derived(() => count.value * 2)
66
+ * console.log(doubled.value) // 0
67
+ *
68
+ * count.value = 5
69
+ * console.log(doubled.value) // 10
70
+ * ```
71
+ */
72
+ export declare function derived<T>(fn: () => T, options?: SignalOptions<T>): Derived<T>;
73
+ export declare namespace derived {
74
+ var by: typeof derived;
75
+ }
76
+ /**
77
+ * Batch multiple updates into a single reaction cycle
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * const a = signal(1)
82
+ * const b = signal(2)
83
+ *
84
+ * effect(() => console.log(a.value + b.value))
85
+ * // Logs: 3
86
+ *
87
+ * batch(() => {
88
+ * a.value = 10
89
+ * b.value = 20
90
+ * })
91
+ * // Logs: 30 (only once, not twice)
92
+ * ```
93
+ */
94
+ export declare function batch<T>(fn: () => T): T;
95
+ /**
96
+ * Read signals without creating dependencies
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * const a = signal(1)
101
+ * const b = signal(2)
102
+ *
103
+ * effect(() => {
104
+ * console.log(a.value) // Creates dependency
105
+ * untrack(() => {
106
+ * console.log(b.value) // Does NOT create dependency
107
+ * })
108
+ * })
109
+ * ```
110
+ */
111
+ export declare function untrack<T>(fn: () => T): T;
112
+ /**
113
+ * Create a deeply reactive state object
114
+ * All nested properties are automatically reactive
115
+ *
116
+ * @example
117
+ * ```ts
118
+ * const user = state({
119
+ * name: 'John',
120
+ * address: {
121
+ * city: 'NYC'
122
+ * }
123
+ * })
124
+ *
125
+ * effect(() => {
126
+ * console.log(user.address.city)
127
+ * })
128
+ * // Logs: "NYC"
129
+ *
130
+ * user.address.city = 'LA'
131
+ * // Logs: "LA"
132
+ * ```
133
+ */
134
+ export declare function state<T extends object>(initial: T): T;
135
+ /**
136
+ * Get the raw (non-reactive) version of a reactive object
137
+ */
138
+ export declare function toRaw<T>(proxy: T): T;
139
+ /**
140
+ * Check if a value is a reactive proxy
141
+ */
142
+ export declare function isReactive(value: unknown): boolean;
143
+ /**
144
+ * A reactive Map that triggers updates on modifications
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * const map = new ReactiveMap<string, number>()
149
+ *
150
+ * effect(() => {
151
+ * console.log('Size:', map.size)
152
+ * console.log('Has foo:', map.has('foo'))
153
+ * })
154
+ *
155
+ * map.set('foo', 42) // Triggers effect
156
+ * ```
157
+ */
158
+ export declare class ReactiveMap<K, V> extends Map<K, V> {
159
+ #private;
160
+ constructor(entries?: Iterable<readonly [K, V]> | null);
161
+ get size(): number;
162
+ has(key: K): boolean;
163
+ get(key: K): V | undefined;
164
+ set(key: K, value: V): this;
165
+ delete(key: K): boolean;
166
+ clear(): void;
167
+ forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
168
+ keys(): MapIterator<K>;
169
+ values(): MapIterator<V>;
170
+ entries(): MapIterator<[K, V]>;
171
+ [Symbol.iterator](): MapIterator<[K, V]>;
172
+ }
173
+ /**
174
+ * A reactive Set that triggers updates on modifications
175
+ *
176
+ * @example
177
+ * ```ts
178
+ * const set = new ReactiveSet<string>()
179
+ *
180
+ * effect(() => {
181
+ * console.log('Size:', set.size)
182
+ * console.log('Has foo:', set.has('foo'))
183
+ * })
184
+ *
185
+ * set.add('foo') // Triggers effect
186
+ * ```
187
+ */
188
+ export declare class ReactiveSet<T> extends Set<T> {
189
+ #private;
190
+ constructor(values?: Iterable<T> | null);
191
+ get size(): number;
192
+ has(value: T): boolean;
193
+ add(value: T): this;
194
+ delete(value: T): boolean;
195
+ clear(): void;
196
+ forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: any): void;
197
+ keys(): SetIterator<T>;
198
+ values(): SetIterator<T>;
199
+ entries(): SetIterator<[T, T]>;
200
+ [Symbol.iterator](): SetIterator<T>;
201
+ }
202
+ /**
203
+ * Create a reactive array with fine-grained reactivity
204
+ *
205
+ * @example
206
+ * ```ts
207
+ * const items = reactiveArray([1, 2, 3])
208
+ *
209
+ * effect(() => {
210
+ * console.log('Length:', items.length)
211
+ * console.log('First:', items[0])
212
+ * })
213
+ *
214
+ * items.push(4) // Triggers effect
215
+ * items[0] = 10 // Triggers effect
216
+ * ```
217
+ */
218
+ export declare function reactiveArray<T>(initial?: T[]): T[];
219
+ /**
220
+ * Create an effect scope for grouping and disposing multiple effects
221
+ *
222
+ * @example
223
+ * ```ts
224
+ * const scope = effectScope()
225
+ *
226
+ * scope.run(() => {
227
+ * effect(() => console.log('Effect 1'))
228
+ * effect(() => console.log('Effect 2'))
229
+ * })
230
+ *
231
+ * scope.stop() // Disposes all effects in the scope
232
+ * ```
233
+ */
234
+ export declare function effectScope(): {
235
+ run<T>(fn: () => T): T | undefined;
236
+ stop(): void;
237
+ readonly active: boolean;
238
+ };
239
+ /**
240
+ * Watch a signal or derived and call callback when it changes
241
+ * Like effect but only runs the callback, not for initial subscription
242
+ *
243
+ * @example
244
+ * ```ts
245
+ * const count = signal(0)
246
+ *
247
+ * watch(
248
+ * () => count.value,
249
+ * (newValue, oldValue) => {
250
+ * console.log(`Changed from ${oldValue} to ${newValue}`)
251
+ * }
252
+ * )
253
+ *
254
+ * count.value = 1 // Logs: "Changed from 0 to 1"
255
+ * ```
256
+ */
257
+ export declare function watch<T>(source: () => T, callback: (newValue: T, oldValue: T | undefined) => void | CleanupFn, options?: {
258
+ immediate?: boolean;
259
+ }): CleanupFn;
260
+ /**
261
+ * Create a readonly signal from a writable signal
262
+ */
263
+ export declare function readonly<T>(sig: WritableSignal<T>): Signal<T>;
264
+ /**
265
+ * Compute a value once without reactivity
266
+ */
267
+ export declare function peek<T>(fn: () => T): T;
268
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}