@signaltree/core 4.0.7 → 4.0.9
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/LICENSE +54 -0
- package/README.md +84 -86
- package/package.json +2 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
BUSINESS SOURCE LICENSE 1.1
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Jonathan D Borgia
|
|
4
|
+
|
|
5
|
+
This Business Source License 1.1 ("License") governs the use of the software and associated documentation files (the "Software"). You are granted a limited license to use the Software under the terms of this License.
|
|
6
|
+
|
|
7
|
+
1. Definitions
|
|
8
|
+
|
|
9
|
+
"Change Date" means the date on which the Change License set out in section 6 will apply to the Software. The Change Date for this release is 2028-09-05.
|
|
10
|
+
|
|
11
|
+
"Change License" means the open source license that will apply to the Software on and after the Change Date. The Change License for this release is the MIT License.
|
|
12
|
+
|
|
13
|
+
"Licensor" means the copyright owner granting rights under this License (Jonathan D Borgia).
|
|
14
|
+
|
|
15
|
+
"You" ("Licensee") means an individual or legal entity exercising rights under this License who has not violated the terms of this License or had their rights terminated.
|
|
16
|
+
|
|
17
|
+
2. License Grant
|
|
18
|
+
|
|
19
|
+
Subject to the terms and conditions of this License, Licensor hereby grants You a non-exclusive, non-transferable, worldwide license to use, reproduce, display, perform, and distribute the Software, and to make modifications and derivative works for internal use, until the Change Date.
|
|
20
|
+
|
|
21
|
+
3. Commercial Use
|
|
22
|
+
|
|
23
|
+
You may use the Software in commercial applications, including for providing services, selling products that include the Software, or otherwise exploiting the Software commercially, subject to the other terms of this License.
|
|
24
|
+
|
|
25
|
+
4. Limitations and Conditions
|
|
26
|
+
|
|
27
|
+
a. You may not remove or alter this License, the copyright notice, or notices of the Change Date.
|
|
28
|
+
|
|
29
|
+
b. You may not publicly offer a modified version of the Software that would directly compete with Licensor's public offering of the Software if doing so would circumvent the intent of this License.
|
|
30
|
+
|
|
31
|
+
c. Except as expressly provided in this License, no rights are granted to You under any patent or trademark of Licensor.
|
|
32
|
+
|
|
33
|
+
5. Disclaimer and Limitation of Liability
|
|
34
|
+
|
|
35
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. TO THE FULLEST EXTENT PERMITTED BY LAW, LICENSOR WILL NOT BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY ARISING FROM OR RELATING TO THE SOFTWARE.
|
|
36
|
+
|
|
37
|
+
6. Change License
|
|
38
|
+
|
|
39
|
+
On and after the Change Date specified above, the Software will be licensed under the Change License (MIT License) on the same terms and conditions as set forth by that Change License.
|
|
40
|
+
|
|
41
|
+
7. Governing Law
|
|
42
|
+
|
|
43
|
+
This License will be governed by and construed in accordance with the laws of the State of New York, USA, without regard to conflict of law principles.
|
|
44
|
+
|
|
45
|
+
8. Accepting this License
|
|
46
|
+
|
|
47
|
+
You accept this License by copying, modifying, or distributing the Software or any portion thereof.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
LICENSE NOTE
|
|
52
|
+
|
|
53
|
+
- Original license file replaced on 2025-09-05 to Business Source License 1.1. Change Date: 2028-09-05. Change License: MIT.
|
|
54
|
+
or standard modifications for your own applications.
|
package/README.md
CHANGED
|
@@ -254,10 +254,10 @@ effect(() => {
|
|
|
254
254
|
|
|
255
255
|
### Performance optimization with memoization
|
|
256
256
|
|
|
257
|
-
|
|
257
|
+
Computed values become even more powerful with the built-in memoization enhancer:
|
|
258
258
|
|
|
259
259
|
```typescript
|
|
260
|
-
import { withMemoization } from '@signaltree/core';
|
|
260
|
+
import { signalTree, withMemoization } from '@signaltree/core';
|
|
261
261
|
|
|
262
262
|
const tree = signalTree({
|
|
263
263
|
items: Array.from({ length: 10000 }, (_, i) => ({
|
|
@@ -385,7 +385,7 @@ tree.$.config.settings.nested.set(false); // ✅ boolean
|
|
|
385
385
|
|
|
386
386
|
### 3) Manual state management
|
|
387
387
|
|
|
388
|
-
Core provides basic state updates
|
|
388
|
+
Core provides basic state updates. For advanced entity management, use the built-in `withEntities` enhancer:
|
|
389
389
|
|
|
390
390
|
```typescript
|
|
391
391
|
interface User {
|
|
@@ -419,7 +419,7 @@ const activeUsers = computed(() => tree.$.users().filter((user) => user.active))
|
|
|
419
419
|
|
|
420
420
|
### 4) Manual async state management
|
|
421
421
|
|
|
422
|
-
Core provides basic state updates
|
|
422
|
+
Core provides basic state updates. For advanced async helpers, use the built-in middleware functions (`createAsyncOperation`, `trackAsync`):
|
|
423
423
|
|
|
424
424
|
```typescript
|
|
425
425
|
const tree = signalTree({
|
|
@@ -466,40 +466,57 @@ class UsersComponent {
|
|
|
466
466
|
|
|
467
467
|
### 6) Enhancers and composition
|
|
468
468
|
|
|
469
|
-
SignalTree Core provides
|
|
469
|
+
SignalTree Core provides a complete set of built-in enhancers. Each enhancer is a focused, tree-shakeable extension that adds specific functionality.
|
|
470
470
|
|
|
471
|
-
#### Available Enhancers
|
|
471
|
+
#### Available Enhancers (All in @signaltree/core)
|
|
472
|
+
|
|
473
|
+
All enhancers are exported directly from `@signaltree/core`:
|
|
472
474
|
|
|
473
475
|
**Performance Enhancers:**
|
|
474
476
|
|
|
475
|
-
-
|
|
476
|
-
-
|
|
477
|
+
- `withBatching()` - Batch updates to reduce recomputation and rendering
|
|
478
|
+
- `withMemoization()` - Intelligent caching for expensive computations
|
|
479
|
+
- `withHighPerformanceBatching()` - Advanced batching for high-frequency updates
|
|
480
|
+
- `withHighPerformanceMemoization()` - Optimized memoization for large state trees
|
|
477
481
|
|
|
478
482
|
**Data Management:**
|
|
479
483
|
|
|
480
|
-
-
|
|
481
|
-
-
|
|
482
|
-
-
|
|
484
|
+
- `withEntities()` - Advanced CRUD operations for collections
|
|
485
|
+
- `createAsyncOperation()` - Async operation management with loading/error states
|
|
486
|
+
- `trackAsync()` - Track async operations in your state
|
|
487
|
+
- `withSerialization()` - State persistence and SSR support
|
|
488
|
+
- `withPersistence()` - Auto-save to localStorage/IndexedDB
|
|
483
489
|
|
|
484
490
|
**Development Tools:**
|
|
485
491
|
|
|
486
|
-
-
|
|
487
|
-
-
|
|
492
|
+
- `withDevTools()` - Redux DevTools integration
|
|
493
|
+
- `withTimeTravel()` - Undo/redo functionality
|
|
488
494
|
|
|
489
495
|
**Integration:**
|
|
490
496
|
|
|
491
|
-
-
|
|
492
|
-
-
|
|
493
|
-
-
|
|
497
|
+
- `withMiddleware()` - State interceptors and logging
|
|
498
|
+
- `createLoggingMiddleware()` - Built-in logging middleware
|
|
499
|
+
- `createValidationMiddleware()` - Built-in validation middleware
|
|
500
|
+
|
|
501
|
+
**Presets:**
|
|
502
|
+
|
|
503
|
+
- `createDevTree()` - Pre-configured development setup
|
|
504
|
+
- `TREE_PRESETS` - Common configuration patterns
|
|
505
|
+
|
|
506
|
+
#### Additional Packages
|
|
507
|
+
|
|
508
|
+
These are the **only** separate packages in the SignalTree ecosystem:
|
|
509
|
+
|
|
510
|
+
- **`@signaltree/ng-forms`** - Angular Forms integration (separate package)
|
|
511
|
+
- **`@signaltree/enterprise`** - Enterprise-scale optimizations for 500+ signals (separate package)
|
|
512
|
+
- **`@signaltree/callable-syntax`** - Build-time transform for callable syntax (dev dependency, separate package)
|
|
494
513
|
|
|
495
514
|
#### Composition Patterns
|
|
496
515
|
|
|
497
516
|
**Basic Enhancement:**
|
|
498
517
|
|
|
499
518
|
```typescript
|
|
500
|
-
import { signalTree } from '@signaltree/core';
|
|
501
|
-
import { withBatching } from '@signaltree/core';
|
|
502
|
-
import { withDevTools } from '@signaltree/core';
|
|
519
|
+
import { signalTree, withBatching, withDevTools } from '@signaltree/core';
|
|
503
520
|
|
|
504
521
|
// Apply enhancers in order
|
|
505
522
|
const tree = signalTree({ count: 0 }).with(
|
|
@@ -511,9 +528,7 @@ const tree = signalTree({ count: 0 }).with(
|
|
|
511
528
|
**Performance-Focused Stack:**
|
|
512
529
|
|
|
513
530
|
```typescript
|
|
514
|
-
import { signalTree, withBatching } from '@signaltree/core';
|
|
515
|
-
import { withMemoization } from '@signaltree/core';
|
|
516
|
-
import { withEntities } from '@signaltree/core';
|
|
531
|
+
import { signalTree, withBatching, withMemoization, withEntities } from '@signaltree/core';
|
|
517
532
|
|
|
518
533
|
const tree = signalTree({
|
|
519
534
|
products: [] as Product[],
|
|
@@ -537,8 +552,7 @@ products.selectBy((p) => p.category === 'electronics');
|
|
|
537
552
|
**Full-Stack Application:**
|
|
538
553
|
|
|
539
554
|
```typescript
|
|
540
|
-
import { withSerialization } from '@signaltree/core';
|
|
541
|
-
import { withTimeTravel } from '@signaltree/core';
|
|
555
|
+
import { signalTree, withSerialization, withTimeTravel } from '@signaltree/core';
|
|
542
556
|
|
|
543
557
|
const tree = signalTree({
|
|
544
558
|
user: null as User | null,
|
|
@@ -585,36 +599,34 @@ const tree = signalTree(state).with(
|
|
|
585
599
|
For common patterns, use presets that combine multiple enhancers:
|
|
586
600
|
|
|
587
601
|
```typescript
|
|
588
|
-
import {
|
|
602
|
+
import { createDevTree, TREE_PRESETS } from '@signaltree/core';
|
|
589
603
|
|
|
590
|
-
//
|
|
591
|
-
const
|
|
604
|
+
// Development preset includes: batching, memoization, devtools, time-travel
|
|
605
|
+
const devTree = createDevTree({
|
|
592
606
|
products: [] as Product[],
|
|
593
607
|
cart: { items: [], total: 0 },
|
|
594
608
|
});
|
|
595
609
|
|
|
596
|
-
//
|
|
597
|
-
const
|
|
598
|
-
metrics: { users: 0, revenue: 0 },
|
|
599
|
-
charts: { data: [] },
|
|
600
|
-
});
|
|
610
|
+
// Or use preset configurations
|
|
611
|
+
const customTree = signalTree(state, TREE_PRESETS.DASHBOARD);
|
|
601
612
|
```
|
|
602
613
|
|
|
603
614
|
#### Core Stubs
|
|
604
615
|
|
|
605
|
-
SignalTree Core includes
|
|
616
|
+
SignalTree Core includes all enhancer functionality built-in. No separate packages needed:
|
|
606
617
|
|
|
607
618
|
```typescript
|
|
619
|
+
import { signalTree, withEntities } from '@signaltree/core';
|
|
620
|
+
|
|
608
621
|
const tree = signalTree({ users: [] as User[] });
|
|
609
622
|
|
|
610
|
-
//
|
|
611
|
-
|
|
612
|
-
users.add(newUser); // Warns: "Method requires @signaltree/entities"
|
|
623
|
+
// Without enhancer - use manual CRUD
|
|
624
|
+
tree.$.users.update((users) => [...users, newUser]);
|
|
613
625
|
|
|
614
|
-
//
|
|
626
|
+
// With enhancer - use entity helpers
|
|
615
627
|
const enhanced = tree.with(withEntities());
|
|
616
|
-
const
|
|
617
|
-
|
|
628
|
+
const users = enhanced.entities<User>('users');
|
|
629
|
+
users.add(newUser); // ✅ Advanced CRUD operations
|
|
618
630
|
```
|
|
619
631
|
|
|
620
632
|
Core includes several performance optimizations:
|
|
@@ -775,9 +787,7 @@ tree.effect(() => console.log('State changed'));
|
|
|
775
787
|
### Performance-Enhanced Composition
|
|
776
788
|
|
|
777
789
|
```typescript
|
|
778
|
-
import { signalTree } from '@signaltree/core';
|
|
779
|
-
import { withBatching } from '@signaltree/core';
|
|
780
|
-
import { withMemoization } from '@signaltree/core';
|
|
790
|
+
import { signalTree, withBatching, withMemoization } from '@signaltree/core';
|
|
781
791
|
|
|
782
792
|
// Add performance optimizations
|
|
783
793
|
const tree = signalTree({
|
|
@@ -805,8 +815,7 @@ const filteredProducts = computed(() => {
|
|
|
805
815
|
### Data Management Composition
|
|
806
816
|
|
|
807
817
|
```typescript
|
|
808
|
-
import { signalTree } from '@signaltree/core';
|
|
809
|
-
import { withEntities } from '@signaltree/core';
|
|
818
|
+
import { signalTree, withEntities } from '@signaltree/core';
|
|
810
819
|
|
|
811
820
|
// Add data management capabilities (+2.77KB total)
|
|
812
821
|
const tree = signalTree({
|
|
@@ -834,12 +843,7 @@ const fetchUsers = tree.asyncAction(async () => api.getUsers(), {
|
|
|
834
843
|
### Full-Featured Development Composition
|
|
835
844
|
|
|
836
845
|
```typescript
|
|
837
|
-
import { signalTree } from '@signaltree/core';
|
|
838
|
-
import { withBatching } from '@signaltree/core';
|
|
839
|
-
import { withEntities } from '@signaltree/core';
|
|
840
|
-
import { withSerialization } from '@signaltree/core';
|
|
841
|
-
import { withTimeTravel } from '@signaltree/core';
|
|
842
|
-
import { withDevTools } from '@signaltree/core';
|
|
846
|
+
import { signalTree, withBatching, withEntities, withSerialization, withTimeTravel, withDevTools } from '@signaltree/core';
|
|
843
847
|
|
|
844
848
|
// Full development stack (example)
|
|
845
849
|
const tree = signalTree({
|
|
@@ -878,10 +882,7 @@ tree.save(); // Persistence
|
|
|
878
882
|
### Production-Ready Composition
|
|
879
883
|
|
|
880
884
|
```typescript
|
|
881
|
-
import { signalTree } from '@signaltree/core';
|
|
882
|
-
import { withBatching } from '@signaltree/core';
|
|
883
|
-
import { withEntities } from '@signaltree/core';
|
|
884
|
-
import { withSerialization } from '@signaltree/core';
|
|
885
|
+
import { signalTree, withBatching, withEntities, withSerialization } from '@signaltree/core';
|
|
885
886
|
|
|
886
887
|
// Production build (no dev tools)
|
|
887
888
|
const tree = signalTree(initialState).with(
|
|
@@ -902,9 +903,7 @@ const tree = signalTree(initialState).with(
|
|
|
902
903
|
### Conditional Enhancement
|
|
903
904
|
|
|
904
905
|
```typescript
|
|
905
|
-
import { signalTree } from '@signaltree/core';
|
|
906
|
-
import { withDevTools } from '@signaltree/core';
|
|
907
|
-
import { withTimeTravel } from '@signaltree/core';
|
|
906
|
+
import { signalTree, withBatching, withEntities, withDevTools, withTimeTravel } from '@signaltree/core';
|
|
908
907
|
|
|
909
908
|
const isDevelopment = process.env['NODE_ENV'] === 'development';
|
|
910
909
|
|
|
@@ -925,22 +924,19 @@ const tree = signalTree(state).with(
|
|
|
925
924
|
### Preset-Based Composition
|
|
926
925
|
|
|
927
926
|
```typescript
|
|
928
|
-
import {
|
|
927
|
+
import { createDevTree, TREE_PRESETS } from '@signaltree/core';
|
|
929
928
|
|
|
930
929
|
// Use presets for common patterns
|
|
931
|
-
const
|
|
930
|
+
const devTree = createDevTree({
|
|
932
931
|
products: [],
|
|
933
932
|
cart: { items: [], total: 0 },
|
|
934
933
|
user: null,
|
|
935
934
|
});
|
|
936
|
-
// Includes:
|
|
935
|
+
// Includes: batching, memoization, devtools, time-travel
|
|
937
936
|
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
filters: {},
|
|
942
|
-
});
|
|
943
|
-
// Includes: batching, memoization, devtools
|
|
937
|
+
// Or use preset configurations directly
|
|
938
|
+
const customTree = signalTree(state, TREE_PRESETS.PERFORMANCE);
|
|
939
|
+
// Includes: batching, memoization optimizations
|
|
944
940
|
```
|
|
945
941
|
|
|
946
942
|
### Measuring bundle size
|
|
@@ -1247,29 +1243,25 @@ tree.effect(fn); // Create reactive effects
|
|
|
1247
1243
|
tree.subscribe(fn); // Manual subscriptions
|
|
1248
1244
|
tree.destroy(); // Cleanup resources
|
|
1249
1245
|
|
|
1250
|
-
// Extended features (
|
|
1251
|
-
tree.entities<T>(key); // Entity helpers (
|
|
1252
|
-
|
|
1253
|
-
tree.asyncAction(fn, config?); // Create async action
|
|
1246
|
+
// Extended features (built into @signaltree/core)
|
|
1247
|
+
tree.entities<T>(key); // Entity helpers (use withEntities enhancer)
|
|
1248
|
+
tree.asyncAction(fn, config?); // Async operations (use createAsyncOperation helper)
|
|
1254
1249
|
```
|
|
1255
1250
|
|
|
1256
|
-
## Extending with
|
|
1251
|
+
## Extending with enhancers
|
|
1257
1252
|
|
|
1258
|
-
SignalTree Core
|
|
1253
|
+
SignalTree Core includes all enhancers built-in:
|
|
1259
1254
|
|
|
1260
1255
|
```typescript
|
|
1261
|
-
import { signalTree } from '@signaltree/core';
|
|
1262
|
-
import { withBatching } from '@signaltree/core';
|
|
1263
|
-
import { withMemoization } from '@signaltree/core';
|
|
1264
|
-
import { withTimeTravel } from '@signaltree/core';
|
|
1256
|
+
import { signalTree, withBatching, withMemoization, withTimeTravel } from '@signaltree/core';
|
|
1265
1257
|
|
|
1266
|
-
//
|
|
1258
|
+
// All enhancers available from @signaltree/core
|
|
1267
1259
|
const tree = signalTree(initialState).with(withBatching(), withMemoization(), withTimeTravel());
|
|
1268
1260
|
```
|
|
1269
1261
|
|
|
1270
|
-
### Available
|
|
1262
|
+
### Available enhancers
|
|
1271
1263
|
|
|
1272
|
-
All enhancers are
|
|
1264
|
+
All enhancers are included in `@signaltree/core`:
|
|
1273
1265
|
|
|
1274
1266
|
- **withBatching()** - Batch multiple updates for better performance
|
|
1275
1267
|
- **withMemoization()** - Intelligent caching & performance optimization
|
|
@@ -1278,8 +1270,8 @@ All enhancers are now consolidated in the core package:
|
|
|
1278
1270
|
- **withDevTools()** - Redux DevTools integration for debugging
|
|
1279
1271
|
- **withTimeTravel()** - Undo/redo functionality & state history
|
|
1280
1272
|
- **withSerialization()** - State persistence & SSR support
|
|
1281
|
-
- **
|
|
1282
|
-
- **
|
|
1273
|
+
- **createDevTree()** - Pre-configured development setup
|
|
1274
|
+
- **TREE_PRESETS** - Common configuration patterns (PERFORMANCE, DASHBOARD, etc.)
|
|
1283
1275
|
|
|
1284
1276
|
## When to use core only
|
|
1285
1277
|
|
|
@@ -1291,12 +1283,18 @@ Perfect for:
|
|
|
1291
1283
|
- ✅ Learning signal-based state management
|
|
1292
1284
|
- ✅ Applications with basic state needs
|
|
1293
1285
|
|
|
1294
|
-
Consider
|
|
1286
|
+
Consider enhancers when you need:
|
|
1287
|
+
|
|
1288
|
+
- ⚡ Performance optimization (withBatching, withMemoization)
|
|
1289
|
+
- 🐛 Advanced debugging (withDevTools, withTimeTravel)
|
|
1290
|
+
- � Entity management (withEntities)
|
|
1291
|
+
- 🔌 Middleware patterns (withMiddleware)
|
|
1292
|
+
|
|
1293
|
+
Consider separate packages when you need:
|
|
1295
1294
|
|
|
1296
|
-
-
|
|
1297
|
-
-
|
|
1298
|
-
-
|
|
1299
|
-
- 🔧 Middleware patterns (middleware)
|
|
1295
|
+
- 📝 Angular forms integration (@signaltree/ng-forms)
|
|
1296
|
+
- 🏢 Enterprise-scale optimizations (@signaltree/enterprise)
|
|
1297
|
+
- 🎯 Callable syntax transform (@signaltree/callable-syntax)
|
|
1300
1298
|
|
|
1301
1299
|
## Migration from NgRx
|
|
1302
1300
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signaltree/core",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.9",
|
|
4
4
|
"description": "Lightweight, type-safe signal-based state management for Angular. Core package providing hierarchical signal trees, basic entity management, and async actions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"tslib": "*"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@signaltree/shared": "
|
|
68
|
+
"@signaltree/shared": "0.0.1"
|
|
69
69
|
},
|
|
70
70
|
"files": [
|
|
71
71
|
"dist",
|