@signaltree/core 1.1.9 β 2.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 +121 -91
- package/fesm2022/signaltree-core.mjs +688 -326
- package/fesm2022/signaltree-core.mjs.map +1 -1
- package/index.d.ts +102 -46
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
#
|
|
1
|
+
# SignalTree Core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Foundation package for SignalTree. Provides recursive typing, deep nesting support, and strong performance.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## What is @signaltree/core?
|
|
6
6
|
|
|
7
|
-
SignalTree Core is
|
|
7
|
+
SignalTree Core is a lightweight (about 7.25KB gzipped) package that provides:
|
|
8
8
|
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
9
|
+
- Recursive typing with deep nesting and accurate type inference
|
|
10
|
+
- Fast operations with subβmillisecond measurements at 5β20+ levels
|
|
11
|
+
- Strong TypeScript safety across nested structures
|
|
12
|
+
- Memory efficiency via structural sharing and lazy signals
|
|
13
|
+
- Small API surface with zero-cost abstractions
|
|
14
|
+
- Compact bundle size suited for production
|
|
15
15
|
|
|
16
|
-
###
|
|
16
|
+
### Depth performance (Sept 2025, averaged)
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Indicative measurements across different depths:
|
|
19
19
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
|
|
|
20
|
+
| Depth level | Avg time | Type safety | Range |
|
|
21
|
+
| ----------- | -------- | ----------- | ------------- |
|
|
22
|
+
| 5 levels | 0.061ms | β
| 0.041β0.133ms |
|
|
23
|
+
| 10 levels | 0.109ms | β
| 0.060β0.181ms |
|
|
24
|
+
| 15 levels | 0.098ms | β
| 0.088β0.126ms |
|
|
25
|
+
| 20+ levels | 0.103ms | β
| 0.100β0.106ms |
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Note: Results vary by environment; figures are averaged across multiple runs.
|
|
28
28
|
|
|
29
|
-
##
|
|
29
|
+
## Quick start
|
|
30
30
|
|
|
31
31
|
### Installation
|
|
32
32
|
|
|
@@ -34,12 +34,12 @@ _Revolutionary achievement: Performance remains sub-millisecond with consistent
|
|
|
34
34
|
npm install @signaltree/core
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
###
|
|
37
|
+
### Deep nesting example
|
|
38
38
|
|
|
39
39
|
```typescript
|
|
40
40
|
import { signalTree } from '@signaltree/core';
|
|
41
41
|
|
|
42
|
-
//
|
|
42
|
+
// Strong type inference at deep nesting levels
|
|
43
43
|
const tree = signalTree({
|
|
44
44
|
enterprise: {
|
|
45
45
|
divisions: {
|
|
@@ -58,7 +58,7 @@ const tree = signalTree({
|
|
|
58
58
|
tests: {
|
|
59
59
|
extreme: {
|
|
60
60
|
depth: 15,
|
|
61
|
-
performance: 0.
|
|
61
|
+
performance: 0.098, // ms (averaged)
|
|
62
62
|
typeInference: true,
|
|
63
63
|
},
|
|
64
64
|
},
|
|
@@ -78,21 +78,24 @@ const tree = signalTree({
|
|
|
78
78
|
},
|
|
79
79
|
});
|
|
80
80
|
|
|
81
|
-
//
|
|
81
|
+
// Type inference at deep nesting levels
|
|
82
82
|
const performance = tree.$.enterprise.divisions.technology.departments.engineering.teams.frontend.projects.signaltree.releases.v1.features.recursiveTyping.validation.tests.extreme.performance();
|
|
83
83
|
|
|
84
|
-
console.log(`
|
|
84
|
+
console.log(`Performance: ${performance}ms`); // ~0.098ms (averaged)
|
|
85
85
|
|
|
86
86
|
// Type-safe updates at unlimited depth
|
|
87
87
|
tree.$.enterprise.divisions.technology.departments.engineering.teams.frontend.projects.signaltree.releases.v1.features.recursiveTyping.validation.tests.extreme.depth.set(25); // Perfect type safety!
|
|
88
|
-
|
|
89
|
-
Note: Prefer calling signals to read their current value (e.g. `tree.$.path.to.value()`). The older `unwrap()` helper is still present for compatibility but using the callable signal form is the recommended approach for new code and examples.
|
|
90
88
|
```
|
|
91
89
|
|
|
92
|
-
### Basic
|
|
90
|
+
### Basic usage
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { signalTree } from '@signaltree/core';
|
|
93
94
|
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
// Create a simple tree
|
|
96
|
+
const tree = signalTree({
|
|
97
|
+
count: 0,
|
|
98
|
+
message: 'Hello World',
|
|
96
99
|
});
|
|
97
100
|
|
|
98
101
|
// Read values (these are Angular signals)
|
|
@@ -103,23 +106,22 @@ console.log(tree.$.message()); // 'Hello World'
|
|
|
103
106
|
tree.$.count.set(5);
|
|
104
107
|
tree.$.message.set('Updated!');
|
|
105
108
|
|
|
106
|
-
// Use in Angular
|
|
109
|
+
// Use in an Angular component
|
|
107
110
|
@Component({
|
|
108
|
-
template: `
|
|
111
|
+
template: ` <div>Count: {{ tree.$.count() }}</div>
|
|
109
112
|
<div>Message: {{ tree.$.message() }}</div>
|
|
110
113
|
<button (click)="increment()">+1</button>`,
|
|
111
114
|
})
|
|
112
115
|
class SimpleComponent {
|
|
113
|
-
tree = tree;
|
|
116
|
+
tree = tree;
|
|
114
117
|
|
|
115
|
-
increment() {
|
|
116
|
-
this.tree.$.count.update((n) => n + 1);
|
|
117
|
-
}
|
|
118
|
+
increment() {
|
|
119
|
+
this.tree.$.count.update((n) => n + 1);
|
|
120
|
+
}
|
|
118
121
|
}
|
|
122
|
+
```
|
|
119
123
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
### Intermediate Usage (Nested State)
|
|
124
|
+
### Intermediate usage (nested state)
|
|
123
125
|
|
|
124
126
|
```typescript
|
|
125
127
|
// Create hierarchical state
|
|
@@ -155,9 +157,9 @@ effect(() => {
|
|
|
155
157
|
console.log('Loading started...');
|
|
156
158
|
}
|
|
157
159
|
});
|
|
158
|
-
|
|
160
|
+
```
|
|
159
161
|
|
|
160
|
-
### Advanced
|
|
162
|
+
### Advanced usage (full state tree)
|
|
161
163
|
|
|
162
164
|
```typescript
|
|
163
165
|
interface AppState {
|
|
@@ -211,13 +213,13 @@ tree.update(state => ({
|
|
|
211
213
|
notifications: [
|
|
212
214
|
...state.ui.notifications,
|
|
213
215
|
// Get entire state as plain object
|
|
214
|
-
const currentState = tree
|
|
216
|
+
const currentState = tree.unwrap();
|
|
215
217
|
console.log('Current app state:', currentState);
|
|
216
218
|
```
|
|
217
219
|
|
|
218
|
-
##
|
|
220
|
+
## Core features
|
|
219
221
|
|
|
220
|
-
### 1
|
|
222
|
+
### 1) Hierarchical signal trees
|
|
221
223
|
|
|
222
224
|
Create deeply nested reactive state with automatic type inference:
|
|
223
225
|
|
|
@@ -234,7 +236,7 @@ tree.$.settings.theme.set('light'); // type-checked value
|
|
|
234
236
|
tree.$.todos.update((todos) => [...todos, newTodo]); // array operations
|
|
235
237
|
```
|
|
236
238
|
|
|
237
|
-
### 2
|
|
239
|
+
### 2) TypeScript inference
|
|
238
240
|
|
|
239
241
|
SignalTree provides complete type inference without manual typing:
|
|
240
242
|
|
|
@@ -260,7 +262,7 @@ tree.$.config.theme.set('light'); // β Type error ('dark' const)
|
|
|
260
262
|
tree.$.config.settings.nested.set(false); // β
boolean
|
|
261
263
|
```
|
|
262
264
|
|
|
263
|
-
### 3
|
|
265
|
+
### 3) Manual state management
|
|
264
266
|
|
|
265
267
|
Core provides basic state updates - entity management requires `@signaltree/entities`:
|
|
266
268
|
|
|
@@ -294,7 +296,7 @@ const userById = (id: string) => computed(() => tree.$.users().find((user) => us
|
|
|
294
296
|
const activeUsers = computed(() => tree.$.users().filter((user) => user.active));
|
|
295
297
|
```
|
|
296
298
|
|
|
297
|
-
### 4
|
|
299
|
+
### 4) Manual async state management
|
|
298
300
|
|
|
299
301
|
Core provides basic state updates - async helpers require `@signaltree/async`:
|
|
300
302
|
|
|
@@ -339,7 +341,35 @@ class UsersComponent {
|
|
|
339
341
|
}
|
|
340
342
|
```
|
|
341
343
|
|
|
342
|
-
### 5
|
|
344
|
+
### 5) Performance considerations
|
|
345
|
+
|
|
346
|
+
### 6) Enhancers and composition
|
|
347
|
+
|
|
348
|
+
Enhancers are optional, treeβshakable extensions that augment a `SignalTree` via `tree.with(...)`.
|
|
349
|
+
|
|
350
|
+
- `createEnhancer(meta, fn)` attaches metadata to an enhancer function
|
|
351
|
+
- Metadata fields: `name`, `requires`, `provides`
|
|
352
|
+
- Enhancers may mutate the passed tree (preferred) or return a new object
|
|
353
|
+
- A topological sort orders enhancers that declare metadata; on cycles, fallback to user order in debug mode
|
|
354
|
+
|
|
355
|
+
Examples:
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
import { signalTree } from '@signaltree/core';
|
|
359
|
+
import { withBatching } from '@signaltree/batching';
|
|
360
|
+
import { withDevtools } from '@signaltree/devtools';
|
|
361
|
+
|
|
362
|
+
// Apply in explicit order
|
|
363
|
+
const tree = signalTree({ count: 0 }).with(withBatching, withDevtools);
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Presets can provide composed enhancers for quicker onboarding:
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
import { createDevTree } from '@signaltree/presets';
|
|
370
|
+
const { enhancer } = createDevTree();
|
|
371
|
+
const tree = signalTree({ count: 0 }).with(enhancer);
|
|
372
|
+
```
|
|
343
373
|
|
|
344
374
|
Core includes several performance optimizations:
|
|
345
375
|
|
|
@@ -374,9 +404,9 @@ tree.update((state) => ({
|
|
|
374
404
|
}));
|
|
375
405
|
```
|
|
376
406
|
|
|
377
|
-
##
|
|
407
|
+
## Error handling examples
|
|
378
408
|
|
|
379
|
-
### Manual
|
|
409
|
+
### Manual async error handling
|
|
380
410
|
|
|
381
411
|
```typescript
|
|
382
412
|
const tree = signalTree({
|
|
@@ -437,7 +467,7 @@ class ErrorHandlingComponent {
|
|
|
437
467
|
}
|
|
438
468
|
```
|
|
439
469
|
|
|
440
|
-
### State
|
|
470
|
+
### State update error handling
|
|
441
471
|
|
|
442
472
|
```typescript
|
|
443
473
|
const tree = signalTree({
|
|
@@ -475,7 +505,7 @@ function safeUpdateItem(id: string, updates: Partial<Item>) {
|
|
|
475
505
|
}
|
|
476
506
|
```
|
|
477
507
|
|
|
478
|
-
##
|
|
508
|
+
## Package composition patterns
|
|
479
509
|
|
|
480
510
|
### Basic Composition
|
|
481
511
|
|
|
@@ -487,33 +517,33 @@ const tree = signalTree({
|
|
|
487
517
|
state: 'initial',
|
|
488
518
|
});
|
|
489
519
|
|
|
490
|
-
// Extend with additional packages via
|
|
491
|
-
const enhancedTree = tree.
|
|
520
|
+
// Extend with additional packages via .with(...)
|
|
521
|
+
const enhancedTree = tree.with(
|
|
492
522
|
// Add features as needed
|
|
493
523
|
someFeatureFunction()
|
|
494
524
|
);
|
|
495
525
|
```
|
|
496
526
|
|
|
497
|
-
### Modular
|
|
527
|
+
### Modular enhancement pattern
|
|
498
528
|
|
|
499
529
|
```typescript
|
|
500
530
|
// Start minimal, add features as needed
|
|
501
531
|
let tree = signalTree(initialState);
|
|
502
532
|
|
|
503
533
|
if (isDevelopment) {
|
|
504
|
-
tree = tree.
|
|
534
|
+
tree = tree.with(withDevTools());
|
|
505
535
|
}
|
|
506
536
|
|
|
507
537
|
if (needsPerformance) {
|
|
508
|
-
tree = tree.
|
|
538
|
+
tree = tree.with(withBatching(), withMemoization());
|
|
509
539
|
}
|
|
510
540
|
|
|
511
541
|
if (needsTimeTravel) {
|
|
512
|
-
tree = tree.
|
|
542
|
+
tree = tree.with(withTimeTravel());
|
|
513
543
|
}
|
|
514
544
|
```
|
|
515
545
|
|
|
516
|
-
### Service-
|
|
546
|
+
### Service-based pattern
|
|
517
547
|
|
|
518
548
|
```typescript
|
|
519
549
|
@Injectable()
|
|
@@ -546,11 +576,11 @@ class AppStateService {
|
|
|
546
576
|
}
|
|
547
577
|
```
|
|
548
578
|
|
|
549
|
-
##
|
|
579
|
+
## Performance benchmarks
|
|
550
580
|
|
|
551
|
-
>
|
|
581
|
+
> Subβmillisecond operations across common core functions
|
|
552
582
|
|
|
553
|
-
### Recursive
|
|
583
|
+
### Recursive depth scaling (illustrative)
|
|
554
584
|
|
|
555
585
|
| **Depth Level** | **Execution Time** | **Scaling Factor** | **Type Inference** | **Memory Usage** |
|
|
556
586
|
| -------------------------- | ------------------ | ------------------ | ------------------ | ---------------- |
|
|
@@ -559,9 +589,9 @@ class AppStateService {
|
|
|
559
589
|
| **Extreme (15 levels)** | **0.021ms** | **1.75x** | β
Perfect | ~1.3MB |
|
|
560
590
|
| **Unlimited (20+ levels)** | 0.023ms | 1.92x | β
Perfect | ~1.4MB |
|
|
561
591
|
|
|
562
|
-
|
|
592
|
+
Note: Scaling depends on state shape and hardware.
|
|
563
593
|
|
|
564
|
-
###
|
|
594
|
+
### Example operation timings
|
|
565
595
|
|
|
566
596
|
| Operation | SignalTree Core | Notes |
|
|
567
597
|
| --------------------------- | --------------- | ---------------- |
|
|
@@ -572,16 +602,16 @@ _Exceptional scaling: Only 92% performance overhead for 4x depth increase_
|
|
|
572
602
|
| Computation (cached) | **0.094ms** | Memoized result |
|
|
573
603
|
| Memory per 1K entities | **1.2MB** | Measured usage |
|
|
574
604
|
|
|
575
|
-
###
|
|
605
|
+
### Feature impact
|
|
576
606
|
|
|
577
607
|
| Feature | SignalTree Core | With Extensions | Notes |
|
|
578
608
|
| ------------------- | ----------------- | ---------------------- | ---------------------- |
|
|
579
609
|
| Batching efficiency | Standard | **455.8x improvement** | vs non-batched |
|
|
580
610
|
| Memoization speedup | Basic | **197.9x speedup** | vs non-memoized |
|
|
581
611
|
| Memory efficiency | **Optimized** | **Further optimized** | Lazy signals + cleanup |
|
|
582
|
-
| Bundle impact | **
|
|
612
|
+
| Bundle impact | **7.1KB gzipped** | **+15KB max** | Tree-shakeable |
|
|
583
613
|
|
|
584
|
-
### Developer
|
|
614
|
+
### Developer experience (core)
|
|
585
615
|
|
|
586
616
|
| Metric | SignalTree Core | Traditional State Mgmt | **Improvement** |
|
|
587
617
|
| ----------------------- | --------------- | ---------------------- | --------------- |
|
|
@@ -590,7 +620,7 @@ _Exceptional scaling: Only 92% performance overhead for 4x depth increase_
|
|
|
590
620
|
| Setup complexity | **Minimal** | Complex | **Simplified** |
|
|
591
621
|
| API surface | **Small** | Large | **Focused** |
|
|
592
622
|
|
|
593
|
-
### Memory
|
|
623
|
+
### Memory usage comparison
|
|
594
624
|
|
|
595
625
|
| Operation | SignalTree Core | NgRx | Akita | Native Signals |
|
|
596
626
|
| ------------------------ | --------------- | ------ | ------ | -------------- |
|
|
@@ -598,7 +628,7 @@ _Exceptional scaling: Only 92% performance overhead for 4x depth increase_
|
|
|
598
628
|
| 10K entities | 8.1MB | 28.5MB | 22.1MB | 15.2MB |
|
|
599
629
|
| Deep nesting (10 levels) | 145KB | 890KB | 720KB | 340KB |
|
|
600
630
|
|
|
601
|
-
### TypeScript
|
|
631
|
+
### TypeScript inference speed
|
|
602
632
|
|
|
603
633
|
```typescript
|
|
604
634
|
// SignalTree: Instant inference
|
|
@@ -612,7 +642,7 @@ interface State { deeply: { nested: { state: { with: { types: string } } } } }
|
|
|
612
642
|
const store: Store<State> = ...; // Requires manual interface definition
|
|
613
643
|
```
|
|
614
644
|
|
|
615
|
-
##
|
|
645
|
+
## Example
|
|
616
646
|
|
|
617
647
|
```typescript
|
|
618
648
|
// Complete user management component
|
|
@@ -730,16 +760,16 @@ class UserManagerComponent implements OnInit {
|
|
|
730
760
|
}));
|
|
731
761
|
|
|
732
762
|
// Get entire state as plain object
|
|
733
|
-
const currentState = tree
|
|
763
|
+
const currentState = tree.unwrap();
|
|
734
764
|
console.log('Current app state:', currentState);
|
|
735
765
|
|
|
736
766
|
```
|
|
737
767
|
});
|
|
738
768
|
```
|
|
739
769
|
|
|
740
|
-
##
|
|
770
|
+
## Core features
|
|
741
771
|
|
|
742
|
-
### Hierarchical
|
|
772
|
+
### Hierarchical signal trees
|
|
743
773
|
|
|
744
774
|
```typescript
|
|
745
775
|
const tree = signalTree({
|
|
@@ -754,7 +784,7 @@ tree.$.settings.theme.set('light');
|
|
|
754
784
|
tree.$.todos.update((todos) => [...todos, newTodo]);
|
|
755
785
|
```
|
|
756
786
|
|
|
757
|
-
### Manual
|
|
787
|
+
### Manual entity management
|
|
758
788
|
|
|
759
789
|
```typescript
|
|
760
790
|
// Manual CRUD operations
|
|
@@ -780,7 +810,7 @@ const allTodos = computed(() => tree.$.todos());
|
|
|
780
810
|
const todoCount = computed(() => tree.$.todos().length);
|
|
781
811
|
```
|
|
782
812
|
|
|
783
|
-
### Manual
|
|
813
|
+
### Manual async state management
|
|
784
814
|
|
|
785
815
|
```typescript
|
|
786
816
|
async function loadUsers() {
|
|
@@ -802,7 +832,7 @@ async function handleLoadUsers() {
|
|
|
802
832
|
}
|
|
803
833
|
```
|
|
804
834
|
|
|
805
|
-
### Reactive
|
|
835
|
+
### Reactive effects
|
|
806
836
|
|
|
807
837
|
```typescript
|
|
808
838
|
// Create reactive effects
|
|
@@ -816,7 +846,7 @@ const unsubscribe = tree.subscribe((state) => {
|
|
|
816
846
|
});
|
|
817
847
|
```
|
|
818
848
|
|
|
819
|
-
##
|
|
849
|
+
## Core API reference
|
|
820
850
|
|
|
821
851
|
### signalTree()
|
|
822
852
|
|
|
@@ -830,7 +860,7 @@ const tree = signalTree(initialState, config?);
|
|
|
830
860
|
// State access
|
|
831
861
|
tree.$.property(); // Read signal value
|
|
832
862
|
tree.$.property.set(value); // Update signal
|
|
833
|
-
//
|
|
863
|
+
tree.unwrap(); // Get plain object
|
|
834
864
|
|
|
835
865
|
// Tree operations
|
|
836
866
|
tree.update(updater); // Update entire tree
|
|
@@ -844,7 +874,7 @@ tree.asyncAction(fn, config?); // Async actions (requires @signaltree/async)
|
|
|
844
874
|
tree.asyncAction(fn, config?); // Create async action
|
|
845
875
|
```
|
|
846
876
|
|
|
847
|
-
##
|
|
877
|
+
## Extending with optional packages
|
|
848
878
|
|
|
849
879
|
SignalTree Core can be extended with additional features:
|
|
850
880
|
|
|
@@ -854,11 +884,11 @@ import { withBatching } from '@signaltree/batching';
|
|
|
854
884
|
import { withMemoization } from '@signaltree/memoization';
|
|
855
885
|
import { withTimeTravel } from '@signaltree/time-travel';
|
|
856
886
|
|
|
857
|
-
// Compose features using
|
|
858
|
-
const tree = signalTree(initialState).
|
|
887
|
+
// Compose features using .with(...)
|
|
888
|
+
const tree = signalTree(initialState).with(withBatching(), withMemoization(), withTimeTravel());
|
|
859
889
|
```
|
|
860
890
|
|
|
861
|
-
### Available
|
|
891
|
+
### Available extensions
|
|
862
892
|
|
|
863
893
|
- **@signaltree/batching** (+1.1KB gzipped) - Batch multiple updates
|
|
864
894
|
- **@signaltree/memoization** (+1.7KB gzipped) - Intelligent caching & performance
|
|
@@ -869,9 +899,9 @@ const tree = signalTree(initialState).pipe(withBatching(), withMemoization(), wi
|
|
|
869
899
|
- **@signaltree/time-travel** (+1.5KB gzipped) - Undo/redo functionality
|
|
870
900
|
- **@signaltree/ng-forms** (+3.4KB gzipped) - Complete Angular forms integration
|
|
871
901
|
- **@signaltree/serialization** (+3.6KB gzipped) - State persistence & SSR support
|
|
872
|
-
- **@signaltree/presets** (+0.
|
|
902
|
+
- **@signaltree/presets** (+0.8KB gzipped) - Environment-based configurations
|
|
873
903
|
|
|
874
|
-
##
|
|
904
|
+
## When to use core only
|
|
875
905
|
|
|
876
906
|
Perfect for:
|
|
877
907
|
|
|
@@ -888,7 +918,7 @@ Consider extensions when you need:
|
|
|
888
918
|
- π Complex forms (ng-forms)
|
|
889
919
|
- π§ Middleware patterns (middleware)
|
|
890
920
|
|
|
891
|
-
##
|
|
921
|
+
## Migration from NgRx
|
|
892
922
|
|
|
893
923
|
```typescript
|
|
894
924
|
// Step 1: Create parallel tree
|
|
@@ -904,7 +934,7 @@ users = this.tree.$.users;
|
|
|
904
934
|
// Step 3: Replace effects with manual async operations
|
|
905
935
|
// Before (NgRx)
|
|
906
936
|
loadUsers$ = createEffect(() =>
|
|
907
|
-
this.actions$.
|
|
937
|
+
this.actions$.with(
|
|
908
938
|
ofType(loadUsers),
|
|
909
939
|
switchMap(() => this.api.getUsers())
|
|
910
940
|
)
|
|
@@ -926,7 +956,7 @@ loadUsers = tree.asyncAction(() => api.getUsers(), {
|
|
|
926
956
|
});
|
|
927
957
|
```
|
|
928
958
|
|
|
929
|
-
##
|
|
959
|
+
## Examples
|
|
930
960
|
|
|
931
961
|
### Simple Counter
|
|
932
962
|
|
|
@@ -996,7 +1026,7 @@ class UsersComponent {
|
|
|
996
1026
|
}
|
|
997
1027
|
```
|
|
998
1028
|
|
|
999
|
-
##
|
|
1029
|
+
## Available extension packages
|
|
1000
1030
|
|
|
1001
1031
|
Extend the core with optional feature packages:
|
|
1002
1032
|
|
|
@@ -1018,7 +1048,7 @@ Extend the core with optional feature packages:
|
|
|
1018
1048
|
|
|
1019
1049
|
### Integration & Convenience
|
|
1020
1050
|
|
|
1021
|
-
- **[@signaltree/presets](../presets)** (+0.
|
|
1051
|
+
- **[@signaltree/presets](../presets)** (+0.8KB gzipped) - Pre-configured setups for common patterns
|
|
1022
1052
|
- **[@signaltree/ng-forms](../ng-forms)** (+3.4KB gzipped) - Complete Angular Forms integration
|
|
1023
1053
|
|
|
1024
1054
|
### Quick Start with Extensions
|
|
@@ -1034,7 +1064,7 @@ npm install @signaltree/core @signaltree/batching @signaltree/memoization @signa
|
|
|
1034
1064
|
npm install @signaltree/core @signaltree/batching @signaltree/memoization @signaltree/middleware @signaltree/async @signaltree/entities @signaltree/devtools @signaltree/time-travel @signaltree/presets @signaltree/ng-forms
|
|
1035
1065
|
```
|
|
1036
1066
|
|
|
1037
|
-
##
|
|
1067
|
+
## Links
|
|
1038
1068
|
|
|
1039
1069
|
- [SignalTree Documentation](https://signaltree.io)
|
|
1040
1070
|
- [GitHub Repository](https://github.com/JBorgia/signaltree)
|
|
@@ -1043,7 +1073,7 @@ npm install @signaltree/core @signaltree/batching @signaltree/memoization @signa
|
|
|
1043
1073
|
|
|
1044
1074
|
## π License
|
|
1045
1075
|
|
|
1046
|
-
MIT License - see the [LICENSE](../../LICENSE) file for details.
|
|
1076
|
+
MIT License with AI Training Restriction - see the [LICENSE](../../LICENSE) file for details.
|
|
1047
1077
|
|
|
1048
1078
|
---
|
|
1049
1079
|
|