@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.
Files changed (3) hide show
  1. package/LICENSE +54 -0
  2. package/README.md +84 -86
  3. 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
- When combined with `@signaltree/memoization`, computed values become even more powerful:
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 - entity management requires `@signaltree/entities`:
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 - async helpers are now provided via `@signaltree/middleware` helpers:
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 the foundation, but its real power comes from composable enhancers. Each enhancer is a focused, tree-shakeable extension that adds specific functionality.
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
- - `@signaltree/batching` - Batch updates to reduce recomputation and rendering
476
- - `@signaltree/memoization` - Intelligent caching for expensive computations
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
- - `@signaltree/entities` - Advanced CRUD operations for collections
481
- - Async helpers are provided via `@signaltree/middleware` (createAsyncOperation / trackAsync)
482
- - `@signaltree/serialization` - State persistence and SSR support
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
- - `@signaltree/devtools` - Redux DevTools integration
487
- - `@signaltree/time-travel` - Undo/redo functionality
492
+ - `withDevTools()` - Redux DevTools integration
493
+ - `withTimeTravel()` - Undo/redo functionality
488
494
 
489
495
  **Integration:**
490
496
 
491
- - `@signaltree/ng-forms` - Angular Forms integration
492
- - `@signaltree/middleware` - State interceptors and logging
493
- - `@signaltree/presets` - Pre-configured common patterns
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 { ecommercePreset, dashboardPreset } from '@signaltree/core';
602
+ import { createDevTree, TREE_PRESETS } from '@signaltree/core';
589
603
 
590
- // E-commerce preset includes: entities, async, batching, serialization
591
- const ecommerceTree = ecommercePreset({
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
- // Dashboard preset includes: batching, memoization, devtools
597
- const dashboardTree = dashboardPreset({
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 lightweight stubs for all enhancer methods. This allows you to write code that uses advanced features, and the methods will warn when the actual enhancer isn't installed:
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
- // Works but warns: "Feature requires @signaltree/entities"
611
- const users = tree.entities<User>('users');
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
- // Install the enhancer to enable full functionality
626
+ // With enhancer - use entity helpers
615
627
  const enhanced = tree.with(withEntities());
616
- const realUsers = enhanced.entities<User>('users');
617
- realUsers.add(newUser); // ✅ Works perfectly
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 { ecommercePreset, dashboardPreset } from '@signaltree/core';
927
+ import { createDevTree, TREE_PRESETS } from '@signaltree/core';
929
928
 
930
929
  // Use presets for common patterns
931
- const ecommerceTree = ecommercePreset({
930
+ const devTree = createDevTree({
932
931
  products: [],
933
932
  cart: { items: [], total: 0 },
934
933
  user: null,
935
934
  });
936
- // Includes: entities, async, batching, serialization
935
+ // Includes: batching, memoization, devtools, time-travel
937
936
 
938
- const dashboardTree = dashboardPreset({
939
- metrics: {},
940
- charts: [],
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 (require additional packages)
1251
- tree.entities<T>(key); // Entity helpers (requires @signaltree/entities)
1252
- // tree.asyncAction(fn, config?) example removed use middleware helpers instead
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 optional packages
1251
+ ## Extending with enhancers
1257
1252
 
1258
- SignalTree Core can be extended with additional features:
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
- // Compose features using .with(...)
1258
+ // All enhancers available from @signaltree/core
1267
1259
  const tree = signalTree(initialState).with(withBatching(), withMemoization(), withTimeTravel());
1268
1260
  ```
1269
1261
 
1270
- ### Available extensions
1262
+ ### Available enhancers
1271
1263
 
1272
- All enhancers are now consolidated in the core package:
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
- - **ecommercePreset()** - Pre-configured setup for e-commerce applications
1282
- - **dashboardPreset()** - Pre-configured setup for dashboard applications
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 extensions when you need:
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
- - Performance optimization (batching, memoization)
1297
- - 🐛 Advanced debugging (devtools, time-travel)
1298
- - 📝 Complex forms (ng-forms)
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.7",
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": "workspace:*"
68
+ "@signaltree/shared": "0.0.1"
69
69
  },
70
70
  "files": [
71
71
  "dist",