@zeix/cause-effect 0.15.2 → 0.16.1
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/.ai-context.md +254 -0
- package/.cursorrules +54 -0
- package/.github/copilot-instructions.md +132 -0
- package/CLAUDE.md +319 -0
- package/README.md +136 -166
- package/eslint.config.js +1 -1
- package/index.dev.js +263 -262
- package/index.js +1 -1
- package/index.ts +24 -23
- package/package.json +1 -1
- package/src/computed.ts +54 -44
- package/src/diff.ts +24 -21
- package/src/effect.ts +15 -12
- package/src/errors.ts +8 -0
- package/src/signal.ts +6 -6
- package/src/state.ts +44 -48
- package/src/store.ts +236 -309
- package/src/system.ts +122 -0
- package/src/util.ts +3 -12
- package/test/batch.test.ts +18 -11
- package/test/benchmark.test.ts +4 -4
- package/test/computed.test.ts +508 -72
- package/test/effect.test.ts +61 -61
- package/test/match.test.ts +25 -25
- package/test/resolve.test.ts +16 -16
- package/test/signal.test.ts +9 -9
- package/test/state.test.ts +212 -25
- package/test/store.test.ts +1007 -1357
- package/test/util/dependency-graph.ts +1 -1
- package/types/index.d.ts +9 -9
- package/types/src/collection.d.ts +26 -0
- package/types/src/computed.d.ts +9 -9
- package/types/src/diff.d.ts +7 -7
- package/types/src/effect.d.ts +3 -3
- package/types/src/errors.d.ts +4 -1
- package/types/src/state.d.ts +5 -5
- package/types/src/store.d.ts +29 -44
- package/types/src/system.d.ts +44 -0
- package/types/src/util.d.ts +1 -2
- package/src/scheduler.ts +0 -172
package/.ai-context.md
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# AI Context for Cause & Effect
|
|
2
|
+
|
|
3
|
+
## What is Cause & Effect?
|
|
4
|
+
|
|
5
|
+
Cause & Effect is a modern reactive state management library for JavaScript/TypeScript that implements the signals pattern. It provides fine-grained reactivity with automatic dependency tracking, making it easy to build responsive applications with predictable state updates.
|
|
6
|
+
|
|
7
|
+
## Core Architecture
|
|
8
|
+
|
|
9
|
+
### Signal Types
|
|
10
|
+
- **Signal**: Base interface with `.get()` method for value access
|
|
11
|
+
- **State**: Mutable signals for primitive values (numbers, strings, booleans)
|
|
12
|
+
- **Store**: Mutable signals for objects with individually reactive properties
|
|
13
|
+
- **Computed**: Read-only derived signals with automatic memoization, reducer-like capabilities and asyc handling
|
|
14
|
+
- **Effect**: Side effect handlers that react to signal changes
|
|
15
|
+
|
|
16
|
+
### Key Principles
|
|
17
|
+
1. **Functional Programming**: Immutable by default, pure functions
|
|
18
|
+
2. **Type Safety**: Full TypeScript support with strict type constraints
|
|
19
|
+
3. **Performance**: Minimal re-computations through dependency tracking
|
|
20
|
+
4. **Async Support**: Built-in cancellation with AbortSignal
|
|
21
|
+
5. **Tree-shaking**: Optimized for minimal bundle size
|
|
22
|
+
|
|
23
|
+
## Project Structure
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
cause-effect/
|
|
27
|
+
├── src/
|
|
28
|
+
│ ├── signal.ts # Base signal types and utilities
|
|
29
|
+
│ ├── state.ts # Mutable state signals (createState)
|
|
30
|
+
│ ├── store.ts # Object stores with reactive properties
|
|
31
|
+
│ ├── computed.ts # Computed/derived signals (createComputed)
|
|
32
|
+
│ ├── effect.ts # Effect system (createEffect)
|
|
33
|
+
│ ├── system.ts # Core reactivity (watchers, batching, subscriptions)
|
|
34
|
+
│ ├── resolve.ts # Helper for extracting signal values
|
|
35
|
+
│ ├── match.ts # Pattern matching utility
|
|
36
|
+
│ ├── diff.ts # Object comparison utilities
|
|
37
|
+
│ ├── errors.ts # Custom error classes
|
|
38
|
+
│ └── util.ts # Utilities and constants
|
|
39
|
+
├── index.ts # Main export file
|
|
40
|
+
├── types/index.d.ts # TypeScript declarations
|
|
41
|
+
└── package.json # NPM package configuration
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## API Patterns
|
|
45
|
+
|
|
46
|
+
### Signal Creation
|
|
47
|
+
```typescript
|
|
48
|
+
// State signals for primitives
|
|
49
|
+
const count = createState(42)
|
|
50
|
+
const name = createState('Alice')
|
|
51
|
+
const actions = createState<'increment' | 'decrement' | 'reset'>('reset')
|
|
52
|
+
|
|
53
|
+
// Store signals for objects
|
|
54
|
+
const user = createStore({ name: 'Alice', age: 30 })
|
|
55
|
+
|
|
56
|
+
// Computed signals for derived values
|
|
57
|
+
const doubled = createComputed(() => count.get() * 2)
|
|
58
|
+
|
|
59
|
+
// Computed with reducer-like capabilities (access to previous value)
|
|
60
|
+
const counter = createComputed((prev) => {
|
|
61
|
+
const action = actions.get()
|
|
62
|
+
switch (action) {
|
|
63
|
+
case 'increment': return prev + 1
|
|
64
|
+
case 'decrement': return prev - 1
|
|
65
|
+
case 'reset': return 0
|
|
66
|
+
default: return prev
|
|
67
|
+
}
|
|
68
|
+
}, 0) // Initial value
|
|
69
|
+
|
|
70
|
+
// Async computed with access to previous value
|
|
71
|
+
const userData = createComputed(async (prev, abort) => {
|
|
72
|
+
const id = userId.get()
|
|
73
|
+
if (!id) return prev // Keep previous data if no user ID
|
|
74
|
+
const response = await fetch(`/users/${id}`, { signal: abort })
|
|
75
|
+
return response.json()
|
|
76
|
+
})
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Reactivity
|
|
80
|
+
```typescript
|
|
81
|
+
// Effects react to signal changes
|
|
82
|
+
createEffect(() => {
|
|
83
|
+
console.log(`Count: ${count.get()}`)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
// Async effects with automatic cancellation
|
|
87
|
+
createEffect(async (abort) => {
|
|
88
|
+
const response = await fetch('/api', { signal: abort })
|
|
89
|
+
return response.json()
|
|
90
|
+
})
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Value Access Patterns
|
|
94
|
+
```typescript
|
|
95
|
+
// All signals use .get() for value access
|
|
96
|
+
const value = signal.get()
|
|
97
|
+
|
|
98
|
+
// Mutable signals have .set() and .update()
|
|
99
|
+
state.set(newValue)
|
|
100
|
+
state.update(current => current + 1)
|
|
101
|
+
|
|
102
|
+
// Store properties are individually reactive
|
|
103
|
+
user.name.set("Bob") // Only name watchers trigger
|
|
104
|
+
user.age.update(age => age + 1) // Only age watchers trigger
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Coding Conventions
|
|
108
|
+
|
|
109
|
+
### TypeScript Style
|
|
110
|
+
- Generic constraints: `T extends {}` to exclude null/undefined
|
|
111
|
+
- Use `const` for immutable values
|
|
112
|
+
- Function overloads for complex type scenarios
|
|
113
|
+
- JSDoc comments on all public APIs
|
|
114
|
+
- Pure function annotations: `/*#__PURE__*/` for tree-shaking
|
|
115
|
+
|
|
116
|
+
### Naming Conventions
|
|
117
|
+
- Factory functions: `create*` prefix (createState, createStore, createComputed)
|
|
118
|
+
- Type predicates: `is*` prefix (isSignal, isState, isComputed)
|
|
119
|
+
- Type constants: `TYPE_*` format (TYPE_STATE, TYPE_STORE, TYPE_COMPUTED)
|
|
120
|
+
- Utility constants: UPPER_CASE (UNSET)
|
|
121
|
+
|
|
122
|
+
### Error Handling
|
|
123
|
+
- Custom error classes in `src/errors.ts`
|
|
124
|
+
- Descriptive error messages with context
|
|
125
|
+
- Input validation at public API boundaries
|
|
126
|
+
- Use `UNSET` symbol for uninitialized/pending states
|
|
127
|
+
|
|
128
|
+
## Performance Considerations
|
|
129
|
+
|
|
130
|
+
### Optimization Patterns
|
|
131
|
+
- Dependency tracking with `Set<Watcher>` for O(1) operations
|
|
132
|
+
- Batched updates to minimize effect re-runs
|
|
133
|
+
- Shallow equality checks with `isEqual()` utility
|
|
134
|
+
- Memoization in computed signals prevents unnecessary recalculations
|
|
135
|
+
- Tree-shaking friendly with pure function annotations
|
|
136
|
+
|
|
137
|
+
### Memory Management
|
|
138
|
+
- Automatic cleanup of watchers when effects are disposed
|
|
139
|
+
- WeakMap usage for object-to-signal mappings where appropriate
|
|
140
|
+
- AbortSignal integration for canceling async operations
|
|
141
|
+
|
|
142
|
+
## Common Implementation Patterns
|
|
143
|
+
|
|
144
|
+
### State Management
|
|
145
|
+
```typescript
|
|
146
|
+
// Simple state
|
|
147
|
+
const loading = createState(false)
|
|
148
|
+
const error = createState('') // Empty string means no error
|
|
149
|
+
|
|
150
|
+
// Complex state with stores
|
|
151
|
+
const appState = createStore({
|
|
152
|
+
user: { id: 1, name: "Alice" },
|
|
153
|
+
settings: { theme: "dark", notifications: true }
|
|
154
|
+
})
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Derived State
|
|
158
|
+
```typescript
|
|
159
|
+
// Reducer-like pattern for state machines
|
|
160
|
+
const appState = createComputed((currentState) => {
|
|
161
|
+
const event = events.get()
|
|
162
|
+
switch (currentState) {
|
|
163
|
+
case 'idle':
|
|
164
|
+
return event === 'start' ? 'loading' : 'idle'
|
|
165
|
+
case 'loading':
|
|
166
|
+
return event === 'success' ? 'loaded' : event === 'error' ? 'error' : 'loading'
|
|
167
|
+
case 'loaded':
|
|
168
|
+
return event === 'refresh' ? 'loading' : 'loaded'
|
|
169
|
+
case 'error':
|
|
170
|
+
return event === 'retry' ? 'loading' : 'error'
|
|
171
|
+
default:
|
|
172
|
+
return 'idle'
|
|
173
|
+
}
|
|
174
|
+
}, 'idle') // Initial state
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Async Operations
|
|
178
|
+
```typescript
|
|
179
|
+
// Computed with async data fetching
|
|
180
|
+
const userData = createComputed(async (oldValue, abort) => {
|
|
181
|
+
const id = userId.get()
|
|
182
|
+
if (!id) return oldValue // Retain previous data when no ID
|
|
183
|
+
const response = await fetch(`/users/${id}`, { signal: abort })
|
|
184
|
+
if (!response.ok) throw new Error('Failed to fetch user')
|
|
185
|
+
return response.json()
|
|
186
|
+
})
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Error Handling
|
|
190
|
+
```typescript
|
|
191
|
+
// Handle loading/error states
|
|
192
|
+
createEffect(() => {
|
|
193
|
+
match(resolve({ userData }), {
|
|
194
|
+
ok: ({ userData }) => console.log('User:', userData),
|
|
195
|
+
nil: () => console.log('Loading...'),
|
|
196
|
+
err: (errors) => console.error('Error:', errors[0])
|
|
197
|
+
})
|
|
198
|
+
})
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Helper Functions Usage
|
|
202
|
+
```typescript
|
|
203
|
+
// Extract values from multiple signals
|
|
204
|
+
const result = resolve({ name, age, email })
|
|
205
|
+
|
|
206
|
+
// Pattern matching for discriminated unions
|
|
207
|
+
match(result, {
|
|
208
|
+
ok: (values) => console.log('Success:', values),
|
|
209
|
+
nil: () => console.log('Some values pending'),
|
|
210
|
+
err: (errors) => console.error('Errors:', errors)
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
// Object diffing
|
|
214
|
+
const changes = diff(oldUser, newUser)
|
|
215
|
+
console.log('Changed:', changes.change)
|
|
216
|
+
console.log('Added:', changes.add)
|
|
217
|
+
console.log('Removed:', changes.remove)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Build and Development
|
|
221
|
+
|
|
222
|
+
### Tools
|
|
223
|
+
- **Runtime**: Bun (also works with Node.js)
|
|
224
|
+
- **Build**: Bun build with TypeScript compilation
|
|
225
|
+
- **Testing**: Bun test runner
|
|
226
|
+
- **Linting**: Biome for code formatting and linting
|
|
227
|
+
|
|
228
|
+
### Package Configuration
|
|
229
|
+
- ES modules only (`"type": "module"`)
|
|
230
|
+
- Dual exports: TypeScript source and compiled JavaScript
|
|
231
|
+
- Tree-shaking friendly with proper sideEffects configuration
|
|
232
|
+
- TypeScript declarations generated automatically
|
|
233
|
+
|
|
234
|
+
## Key Design Decisions
|
|
235
|
+
|
|
236
|
+
### Why Signals?
|
|
237
|
+
- Fine-grained reactivity (update only what changed)
|
|
238
|
+
- Explicit dependency tracking (no hidden dependencies)
|
|
239
|
+
- Composable and testable
|
|
240
|
+
- Framework agnostic
|
|
241
|
+
|
|
242
|
+
### Why TypeScript-First?
|
|
243
|
+
- Better developer experience with autocomplete
|
|
244
|
+
- Compile-time error catching
|
|
245
|
+
- Self-documenting APIs
|
|
246
|
+
- Better refactoring support
|
|
247
|
+
|
|
248
|
+
### Why Functional Approach?
|
|
249
|
+
- Predictable behavior
|
|
250
|
+
- Easier testing
|
|
251
|
+
- Better composition
|
|
252
|
+
- Minimal API surface
|
|
253
|
+
|
|
254
|
+
When working with this codebase, focus on maintaining the established patterns, ensuring type safety, and optimizing for performance while keeping the API simple and predictable.
|
package/.cursorrules
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Cause & Effect - Reactive State Management Library
|
|
2
|
+
|
|
3
|
+
## Project Type
|
|
4
|
+
TypeScript/JavaScript reactive state management library using signals pattern
|
|
5
|
+
|
|
6
|
+
## Core Concepts
|
|
7
|
+
- Signals: Base reactive primitives with .get() method
|
|
8
|
+
- State: createState() for primitives/simple values
|
|
9
|
+
- Store: createStore() for objects with reactive properties
|
|
10
|
+
- Computed: createComputed() for derived/memoized values
|
|
11
|
+
- Effects: createEffect() for side effects
|
|
12
|
+
|
|
13
|
+
## Code Style
|
|
14
|
+
- Use const for immutable values
|
|
15
|
+
- Generic constraints: T extends {} (excludes null/undefined)
|
|
16
|
+
- Factory functions: create* prefix
|
|
17
|
+
- Type predicates: is* prefix
|
|
18
|
+
- Constants: TYPE_* or UPPER_CASE
|
|
19
|
+
- Pure functions marked with /*#__PURE__*/ comment
|
|
20
|
+
|
|
21
|
+
## Key Patterns
|
|
22
|
+
- All signals have .get() method
|
|
23
|
+
- Mutable signals have .set(value) and .update(fn)
|
|
24
|
+
- Store properties auto-become reactive signals
|
|
25
|
+
- Computed callbacks receive oldValue as first parameter for reducer patterns
|
|
26
|
+
- Async computed and effect callbacks receive AbortSignal for async cancellation
|
|
27
|
+
- Use UNSET symbol for uninitialized states
|
|
28
|
+
- Batch updates for performance
|
|
29
|
+
- JSDoc comments on all public APIs
|
|
30
|
+
|
|
31
|
+
## File Structure
|
|
32
|
+
- src/signal.ts - Base signal types
|
|
33
|
+
- src/state.ts - Mutable state signals
|
|
34
|
+
- src/store.ts - Object stores
|
|
35
|
+
- src/computed.ts - Computed signals
|
|
36
|
+
- src/effect.ts - Effect system
|
|
37
|
+
- src/system.ts - Core reactivity (watchers, batching)
|
|
38
|
+
- index.ts - Main exports
|
|
39
|
+
|
|
40
|
+
## Error Handling
|
|
41
|
+
- Custom error classes in src/errors.ts
|
|
42
|
+
- Validate inputs, throw descriptive errors
|
|
43
|
+
- Support AbortSignal in async operations
|
|
44
|
+
|
|
45
|
+
## Performance
|
|
46
|
+
- Use Set<Watcher> for subscriptions
|
|
47
|
+
- Shallow equality with isEqual() utility
|
|
48
|
+
- Tree-shaking friendly code
|
|
49
|
+
- Minimize effect re-runs
|
|
50
|
+
|
|
51
|
+
## Build
|
|
52
|
+
- Bun build tool and runtime
|
|
53
|
+
- ES modules only
|
|
54
|
+
- TypeScript with declaration files
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Copilot Instructions for Cause & Effect
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
Cause & Effect is a reactive state management library for JavaScript/TypeScript that provides signals-based reactivity. The library is built with modern JavaScript/TypeScript and follows functional programming principles with a focus on performance and type safety.
|
|
6
|
+
|
|
7
|
+
## Core Architecture
|
|
8
|
+
|
|
9
|
+
- **Signals**: Base reactive primitives with `.get()` method
|
|
10
|
+
- **State**: Mutable signals for primitive values (`createState()`)
|
|
11
|
+
- **Store**: Mutable signals for objects with reactive properties (`createStore()`)
|
|
12
|
+
- **Computed**: Derived read-only signals with memoization, reducer-like capabilities and async support (`createComputed()`)
|
|
13
|
+
- **Effects**: Side effect handlers that react to signal changes (`createEffect()`)
|
|
14
|
+
|
|
15
|
+
## Key Files Structure
|
|
16
|
+
|
|
17
|
+
- `src/signal.ts` - Base signal types and utilities
|
|
18
|
+
- `src/state.ts` - Mutable state signals
|
|
19
|
+
- `src/store.ts` - Object stores with reactive properties
|
|
20
|
+
- `src/computed.ts` - Computed/derived signals
|
|
21
|
+
- `src/effect.ts` - Effect system
|
|
22
|
+
- `src/system.ts` - Core reactivity system (watchers, batching)
|
|
23
|
+
- `src/util.ts` - Utility functions and constants
|
|
24
|
+
- `index.ts` - Main export file
|
|
25
|
+
|
|
26
|
+
## Coding Conventions
|
|
27
|
+
|
|
28
|
+
### TypeScript Style
|
|
29
|
+
- Use `const` for immutable values, prefer immutability
|
|
30
|
+
- Generic constraints: `T extends {}` to exclude nullish values
|
|
31
|
+
- Function overloads for complex type inference
|
|
32
|
+
- Pure functions marked with `/*#__PURE__*/` for tree-shaking
|
|
33
|
+
- JSDoc comments for all public APIs
|
|
34
|
+
|
|
35
|
+
### Naming Conventions
|
|
36
|
+
- Factory functions: `create*` (e.g., `createState`, `createStore`)
|
|
37
|
+
- Type predicates: `is*` (e.g., `isSignal`, `isState`)
|
|
38
|
+
- Constants: `TYPE_*` for type tags, `UPPER_CASE` for values
|
|
39
|
+
- Private variables: use descriptive names, no underscore prefix
|
|
40
|
+
|
|
41
|
+
### Error Handling
|
|
42
|
+
- Custom error classes in `src/errors.ts`
|
|
43
|
+
- Validate inputs and throw descriptive errors
|
|
44
|
+
- Use `UNSET` symbol for uninitialized/pending states
|
|
45
|
+
- Support AbortSignal for cancellation in async operations
|
|
46
|
+
|
|
47
|
+
### Performance Patterns
|
|
48
|
+
- Use `Set<Watcher>` for efficient subscription management
|
|
49
|
+
- Batch updates to minimize effect re-runs
|
|
50
|
+
- Memoization in computed signals
|
|
51
|
+
- Shallow equality checks with `isEqual()` utility
|
|
52
|
+
- Tree-shaking friendly with pure function annotations
|
|
53
|
+
|
|
54
|
+
### API Design Principles
|
|
55
|
+
- All signals have `.get()` method for value access
|
|
56
|
+
- Mutable signals have `.set(value)` and `.update(fn)` methods
|
|
57
|
+
- Store properties are automatically reactive signals
|
|
58
|
+
- Effects receive AbortSignal for async cancellation
|
|
59
|
+
- Helper functions like `resolve()`, `match()`, `diff()` for ergonomics
|
|
60
|
+
|
|
61
|
+
### Testing Patterns
|
|
62
|
+
- Use Bun test runner
|
|
63
|
+
- Test reactivity chains and dependency tracking
|
|
64
|
+
- Test async cancellation behavior
|
|
65
|
+
- Test error conditions and edge cases
|
|
66
|
+
|
|
67
|
+
## Common Code Patterns
|
|
68
|
+
|
|
69
|
+
### Creating Signals
|
|
70
|
+
```typescript
|
|
71
|
+
// State for primitives
|
|
72
|
+
const count = createState(42)
|
|
73
|
+
const name = createState('Alice')
|
|
74
|
+
const actions = createState<'increment' | 'decrement'>('increment')
|
|
75
|
+
|
|
76
|
+
// Store for objects
|
|
77
|
+
const user = createStore({ name: 'Alice', age: 30 })
|
|
78
|
+
|
|
79
|
+
// Computed for derived values
|
|
80
|
+
const doubled = createComputed(() => count.get() * 2)
|
|
81
|
+
|
|
82
|
+
// Computed with reducer-like capabilities
|
|
83
|
+
const counter = createComputed((prev) => {
|
|
84
|
+
const action = actions.get()
|
|
85
|
+
return action === 'increment' ? prev + 1 : prev - 1
|
|
86
|
+
}, 0) // Initial value
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Reactivity
|
|
90
|
+
```typescript
|
|
91
|
+
// Effects run when dependencies change
|
|
92
|
+
createEffect(() => {
|
|
93
|
+
console.log(`Count is ${count.get()}`)
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
// Async effects with cancellation
|
|
97
|
+
createEffect(async (abort) => {
|
|
98
|
+
const response = await fetch('/api', { signal: abort })
|
|
99
|
+
return response.json()
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
// Async computed with old value access
|
|
103
|
+
const userData = createComputed(async (prev, abort) => {
|
|
104
|
+
if (!userId.get()) return prev // Keep previous data if no user
|
|
105
|
+
const response = await fetch(`/users/${userId.get()}`, { signal: abort })
|
|
106
|
+
return response.json()
|
|
107
|
+
})
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Type Safety
|
|
111
|
+
```typescript
|
|
112
|
+
// Use proper generic constraints
|
|
113
|
+
function createSignal<T extends {}>(value: T): Signal<T>
|
|
114
|
+
|
|
115
|
+
// Type predicates for runtime checks
|
|
116
|
+
function isSignal<T extends {}>(value: unknown): value is Signal<T>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Build System
|
|
120
|
+
- Uses Bun as build tool and runtime
|
|
121
|
+
- TypeScript compilation with declaration files
|
|
122
|
+
- Minified production build
|
|
123
|
+
- ES modules only (`"type": "module"`)
|
|
124
|
+
|
|
125
|
+
## When suggesting code:
|
|
126
|
+
1. Follow the established patterns for signal creation and usage
|
|
127
|
+
2. Use proper TypeScript types and generics
|
|
128
|
+
3. Include JSDoc for public APIs
|
|
129
|
+
4. Consider performance implications
|
|
130
|
+
5. Handle errors appropriately
|
|
131
|
+
6. Support async operations with AbortSignal when relevant
|
|
132
|
+
7. Use the established utility functions (`UNSET`, `isEqual`, etc.)
|