@signaltree/core 4.0.13 → 4.0.16
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 +353 -0
- package/package.json +2 -8
package/README.md
CHANGED
|
@@ -1451,6 +1451,359 @@ import {
|
|
|
1451
1451
|
} from '@signaltree/core';
|
|
1452
1452
|
```
|
|
1453
1453
|
|
|
1454
|
+
## Companion Packages
|
|
1455
|
+
|
|
1456
|
+
While `@signaltree/core` includes comprehensive built-in enhancers for most use cases, the SignalTree ecosystem also provides specialized companion packages for specific needs:
|
|
1457
|
+
|
|
1458
|
+
### 📝 @signaltree/ng-forms
|
|
1459
|
+
|
|
1460
|
+
**Angular Forms integration for SignalTree (Angular 17+)**
|
|
1461
|
+
|
|
1462
|
+
Seamlessly connect Angular Forms with your SignalTree state for two-way data binding, validation, and form control.
|
|
1463
|
+
|
|
1464
|
+
```bash
|
|
1465
|
+
npm install @signaltree/ng-forms
|
|
1466
|
+
```
|
|
1467
|
+
|
|
1468
|
+
**Features:**
|
|
1469
|
+
|
|
1470
|
+
- 🔗 Two-way binding between forms and SignalTree state
|
|
1471
|
+
- ✅ Built-in validation integration
|
|
1472
|
+
- 🎯 Type-safe form controls
|
|
1473
|
+
- 🔄 Automatic sync between form state and tree state
|
|
1474
|
+
- 📊 Form status tracking (valid, pristine, touched, etc.)
|
|
1475
|
+
- ⚡ Native Signal Forms support (Angular 20.3+)
|
|
1476
|
+
- 🔧 Legacy bridge for Angular 17-19 (deprecated, will be removed with Angular 21)
|
|
1477
|
+
|
|
1478
|
+
**Signal Forms (Angular 20.3+ recommended)**
|
|
1479
|
+
|
|
1480
|
+
Use Angular's Signal Forms `connect()` API directly with SignalTree:
|
|
1481
|
+
|
|
1482
|
+
```ts
|
|
1483
|
+
import { toWritableSignal } from '@signaltree/core';
|
|
1484
|
+
|
|
1485
|
+
const tree = signalTree({
|
|
1486
|
+
user: { name: '', email: '' },
|
|
1487
|
+
});
|
|
1488
|
+
|
|
1489
|
+
// Leaves are WritableSignal<T>
|
|
1490
|
+
nameControl.connect(tree.$.user.name);
|
|
1491
|
+
|
|
1492
|
+
// Convert a slice to a WritableSignal<T>
|
|
1493
|
+
const userSignal = toWritableSignal(tree.$.user);
|
|
1494
|
+
userGroupControl.connect(userSignal);
|
|
1495
|
+
```
|
|
1496
|
+
|
|
1497
|
+
The `@signaltree/ng-forms` package supports Angular 17+ and will prefer `connect()` when available (Angular 20.3+). Angular 17-19 uses a legacy bridge that will be deprecated when Angular 21 is released.
|
|
1498
|
+
|
|
1499
|
+
**Quick Example:**
|
|
1500
|
+
|
|
1501
|
+
```typescript
|
|
1502
|
+
import { signalTree } from '@signaltree/core';
|
|
1503
|
+
import { bindFormToTree } from '@signaltree/ng-forms';
|
|
1504
|
+
|
|
1505
|
+
const tree = signalTree({
|
|
1506
|
+
user: { name: '', email: '', age: 0 },
|
|
1507
|
+
});
|
|
1508
|
+
|
|
1509
|
+
@Component({
|
|
1510
|
+
template: `
|
|
1511
|
+
<form [formGroup]="form">
|
|
1512
|
+
<input formControlName="name" />
|
|
1513
|
+
<input formControlName="email" type="email" />
|
|
1514
|
+
<input formControlName="age" type="number" />
|
|
1515
|
+
</form>
|
|
1516
|
+
`,
|
|
1517
|
+
})
|
|
1518
|
+
class UserFormComponent {
|
|
1519
|
+
form = new FormGroup({
|
|
1520
|
+
name: new FormControl(''),
|
|
1521
|
+
email: new FormControl(''),
|
|
1522
|
+
age: new FormControl(0),
|
|
1523
|
+
});
|
|
1524
|
+
|
|
1525
|
+
constructor() {
|
|
1526
|
+
// Automatically sync form with tree state
|
|
1527
|
+
bindFormToTree(this.form, tree.$.user);
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
```
|
|
1531
|
+
|
|
1532
|
+
**When to use:**
|
|
1533
|
+
|
|
1534
|
+
- Building forms with Angular Reactive Forms
|
|
1535
|
+
- Need validation integration
|
|
1536
|
+
- Two-way data binding between forms and state
|
|
1537
|
+
- Complex form scenarios with nested form groups
|
|
1538
|
+
|
|
1539
|
+
**Learn more:** [npm package](https://www.npmjs.com/package/@signaltree/ng-forms)
|
|
1540
|
+
|
|
1541
|
+
---
|
|
1542
|
+
|
|
1543
|
+
### 🏢 @signaltree/enterprise
|
|
1544
|
+
|
|
1545
|
+
**Enterprise-scale optimizations for large applications**
|
|
1546
|
+
|
|
1547
|
+
Advanced performance optimizations designed for applications with 500+ signals and complex state trees.
|
|
1548
|
+
|
|
1549
|
+
```bash
|
|
1550
|
+
npm install @signaltree/enterprise
|
|
1551
|
+
```
|
|
1552
|
+
|
|
1553
|
+
**Features:**
|
|
1554
|
+
|
|
1555
|
+
- ⚡ PathIndex for O(k) lookup time regardless of tree size
|
|
1556
|
+
- 🗜️ Advanced memory optimization algorithms
|
|
1557
|
+
- 📊 Performance profiling and monitoring
|
|
1558
|
+
- 🔍 Efficient path-based signal resolution
|
|
1559
|
+
- 🎯 Optimized for large-scale applications
|
|
1560
|
+
|
|
1561
|
+
**Quick Example:**
|
|
1562
|
+
|
|
1563
|
+
```typescript
|
|
1564
|
+
import { signalTree } from '@signaltree/core';
|
|
1565
|
+
import { withEnterpriseOptimizations } from '@signaltree/enterprise';
|
|
1566
|
+
|
|
1567
|
+
const tree = signalTree({
|
|
1568
|
+
// Large application state with hundreds of signals
|
|
1569
|
+
modules: {
|
|
1570
|
+
auth: {
|
|
1571
|
+
/* ... */
|
|
1572
|
+
},
|
|
1573
|
+
data: {
|
|
1574
|
+
/* ... */
|
|
1575
|
+
},
|
|
1576
|
+
ui: {
|
|
1577
|
+
/* ... */
|
|
1578
|
+
},
|
|
1579
|
+
// ... many more modules
|
|
1580
|
+
},
|
|
1581
|
+
}).with(
|
|
1582
|
+
withEnterpriseOptimizations({
|
|
1583
|
+
enablePathIndex: true,
|
|
1584
|
+
enableMemoryOptimizations: true,
|
|
1585
|
+
enablePerformanceMonitoring: true,
|
|
1586
|
+
})
|
|
1587
|
+
);
|
|
1588
|
+
```
|
|
1589
|
+
|
|
1590
|
+
**Performance Benefits:**
|
|
1591
|
+
|
|
1592
|
+
- **Constant-time lookups:** O(k) lookup where k is path depth, not total signal count
|
|
1593
|
+
- **Memory efficiency:** Up to 40% reduction in memory usage for large trees
|
|
1594
|
+
- **Faster updates:** Optimized update batching for high-frequency scenarios
|
|
1595
|
+
|
|
1596
|
+
**When to use:**
|
|
1597
|
+
|
|
1598
|
+
- Applications with 500+ signals
|
|
1599
|
+
- Complex nested state structures (10+ levels deep)
|
|
1600
|
+
- High-frequency state updates
|
|
1601
|
+
- Enterprise-scale applications with performance requirements
|
|
1602
|
+
- Need detailed performance profiling
|
|
1603
|
+
|
|
1604
|
+
**Learn more:** [npm package](https://www.npmjs.com/package/@signaltree/enterprise)
|
|
1605
|
+
|
|
1606
|
+
---
|
|
1607
|
+
|
|
1608
|
+
### 🛡️ @signaltree/guardrails
|
|
1609
|
+
|
|
1610
|
+
**Development-only performance monitoring and debugging**
|
|
1611
|
+
|
|
1612
|
+
Comprehensive development tools for detecting performance issues, memory leaks, and anti-patterns during development. **Zero production overhead** via conditional exports.
|
|
1613
|
+
|
|
1614
|
+
```bash
|
|
1615
|
+
npm install --save-dev @signaltree/guardrails
|
|
1616
|
+
```
|
|
1617
|
+
|
|
1618
|
+
**Features:**
|
|
1619
|
+
|
|
1620
|
+
- 🔥 Hot-path detection - identifies frequently accessed signals
|
|
1621
|
+
- 💾 Memory leak detection - tracks signal cleanup issues
|
|
1622
|
+
- 📊 Performance budgets - enforces performance thresholds
|
|
1623
|
+
- ⚠️ Anti-pattern warnings - detects common mistakes
|
|
1624
|
+
- 📈 Real-time performance metrics
|
|
1625
|
+
- 🎯 Zero production overhead (no-op in production builds)
|
|
1626
|
+
|
|
1627
|
+
**Quick Example:**
|
|
1628
|
+
|
|
1629
|
+
```typescript
|
|
1630
|
+
import { signalTree } from '@signaltree/core';
|
|
1631
|
+
import { withGuardrails } from '@signaltree/guardrails';
|
|
1632
|
+
|
|
1633
|
+
const tree = signalTree({
|
|
1634
|
+
users: [] as User[],
|
|
1635
|
+
posts: [] as Post[],
|
|
1636
|
+
}).with(
|
|
1637
|
+
withGuardrails({
|
|
1638
|
+
hotPathThreshold: 100, // Warn if signal accessed >100 times/sec
|
|
1639
|
+
memoryLeakThreshold: 50, // Warn if >50 uncleaned signals
|
|
1640
|
+
budgets: {
|
|
1641
|
+
updateTime: 16, // Warn if updates take >16ms
|
|
1642
|
+
signalCount: 1000, // Warn if >1000 signals created
|
|
1643
|
+
},
|
|
1644
|
+
})
|
|
1645
|
+
);
|
|
1646
|
+
|
|
1647
|
+
// Development warnings will appear in console
|
|
1648
|
+
// Production builds get no-op functions (0 overhead)
|
|
1649
|
+
```
|
|
1650
|
+
|
|
1651
|
+
**Development Features:**
|
|
1652
|
+
|
|
1653
|
+
```typescript
|
|
1654
|
+
import { getPerformanceMetrics, getHotPaths, checkMemoryLeaks } from '@signaltree/guardrails';
|
|
1655
|
+
|
|
1656
|
+
// Get detailed performance metrics
|
|
1657
|
+
const metrics = getPerformanceMetrics();
|
|
1658
|
+
console.log('Update time:', metrics.avgUpdateTime);
|
|
1659
|
+
console.log('Signal count:', metrics.totalSignals);
|
|
1660
|
+
|
|
1661
|
+
// Identify hot paths
|
|
1662
|
+
const hotPaths = getHotPaths();
|
|
1663
|
+
console.log('Most accessed signals:', hotPaths);
|
|
1664
|
+
|
|
1665
|
+
// Check for memory leaks
|
|
1666
|
+
const leaks = checkMemoryLeaks();
|
|
1667
|
+
if (leaks.length > 0) {
|
|
1668
|
+
console.warn('Potential memory leaks:', leaks);
|
|
1669
|
+
}
|
|
1670
|
+
```
|
|
1671
|
+
|
|
1672
|
+
**Conditional Exports (Zero Production Overhead):**
|
|
1673
|
+
|
|
1674
|
+
```json
|
|
1675
|
+
{
|
|
1676
|
+
"exports": {
|
|
1677
|
+
".": {
|
|
1678
|
+
"development": "./dist/index.js",
|
|
1679
|
+
"production": "./dist/noop.js"
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
```
|
|
1684
|
+
|
|
1685
|
+
In production builds, all guardrails functions become no-ops with zero runtime cost.
|
|
1686
|
+
|
|
1687
|
+
**When to use:**
|
|
1688
|
+
|
|
1689
|
+
- During active development
|
|
1690
|
+
- Performance optimization phase
|
|
1691
|
+
- Debugging state management issues
|
|
1692
|
+
- Team onboarding and code reviews
|
|
1693
|
+
- CI/CD performance regression detection
|
|
1694
|
+
|
|
1695
|
+
**Learn more:** [npm package](https://www.npmjs.com/package/@signaltree/guardrails)
|
|
1696
|
+
|
|
1697
|
+
---
|
|
1698
|
+
|
|
1699
|
+
### 🎯 @signaltree/callable-syntax
|
|
1700
|
+
|
|
1701
|
+
**Build-time transform for callable signal syntax**
|
|
1702
|
+
|
|
1703
|
+
A TypeScript transformer that enables callable syntax sugar for setting signal values. This is **purely a developer experience enhancement** with zero runtime overhead.
|
|
1704
|
+
|
|
1705
|
+
```bash
|
|
1706
|
+
npm install --save-dev @signaltree/callable-syntax
|
|
1707
|
+
```
|
|
1708
|
+
|
|
1709
|
+
**Features:**
|
|
1710
|
+
|
|
1711
|
+
- 🍬 Syntactic sugar for signal updates
|
|
1712
|
+
- ⚡ Zero runtime overhead (build-time transform)
|
|
1713
|
+
- ✅ Full TypeScript type safety
|
|
1714
|
+
- 🔧 Works with any build tool (Rollup, Webpack, esbuild, etc.)
|
|
1715
|
+
- 📝 Optional - use direct `.set/.update` if preferred
|
|
1716
|
+
|
|
1717
|
+
**Syntax Transformation:**
|
|
1718
|
+
|
|
1719
|
+
```typescript
|
|
1720
|
+
// With callable-syntax transform
|
|
1721
|
+
tree.$.name('Jane'); // Transformed to: tree.$.name.set('Jane')
|
|
1722
|
+
tree.$.count((n) => n + 1); // Transformed to: tree.$.count.update((n) => n + 1)
|
|
1723
|
+
|
|
1724
|
+
// Reading always works directly (no transform needed)
|
|
1725
|
+
const name = tree.$.name(); // Direct Angular signal API
|
|
1726
|
+
```
|
|
1727
|
+
|
|
1728
|
+
**Setup (tsconfig.json):**
|
|
1729
|
+
|
|
1730
|
+
```json
|
|
1731
|
+
{
|
|
1732
|
+
"compilerOptions": {
|
|
1733
|
+
"plugins": [{ "transform": "@signaltree/callable-syntax" }]
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
```
|
|
1737
|
+
|
|
1738
|
+
**Setup (Rollup):**
|
|
1739
|
+
|
|
1740
|
+
```javascript
|
|
1741
|
+
import { callableSyntaxTransform } from '@signaltree/callable-syntax/rollup';
|
|
1742
|
+
|
|
1743
|
+
export default {
|
|
1744
|
+
plugins: [callableSyntaxTransform()],
|
|
1745
|
+
};
|
|
1746
|
+
```
|
|
1747
|
+
|
|
1748
|
+
**Important Notes:**
|
|
1749
|
+
|
|
1750
|
+
- **Optional:** You can always use direct `.set(value)` or `.update(fn)` syntax
|
|
1751
|
+
- **Build-time only:** No runtime code is added to your bundle
|
|
1752
|
+
- **Function-valued leaves:** When storing functions, use `.set(fn)` directly
|
|
1753
|
+
- **Type-safe:** Full TypeScript support via module augmentation
|
|
1754
|
+
|
|
1755
|
+
**When to use:**
|
|
1756
|
+
|
|
1757
|
+
- Prefer shorter, more concise syntax
|
|
1758
|
+
- Team convention favors callable style
|
|
1759
|
+
- Migrating from other signal libraries with similar syntax
|
|
1760
|
+
- Want familiar DX without runtime overhead
|
|
1761
|
+
|
|
1762
|
+
**When to skip:**
|
|
1763
|
+
|
|
1764
|
+
- Team prefers explicit `.set/.update` syntax
|
|
1765
|
+
- Build pipeline doesn't support transformers
|
|
1766
|
+
- Storing functions as signal values (use direct `.set`)
|
|
1767
|
+
|
|
1768
|
+
**Learn more:** [npm package](https://www.npmjs.com/package/@signaltree/callable-syntax)
|
|
1769
|
+
|
|
1770
|
+
---
|
|
1771
|
+
|
|
1772
|
+
## Package Selection Guide
|
|
1773
|
+
|
|
1774
|
+
**Start with just `@signaltree/core`** - it includes comprehensive enhancers for most applications:
|
|
1775
|
+
|
|
1776
|
+
- Performance optimization (batching, memoization)
|
|
1777
|
+
- Data management (entities, async operations)
|
|
1778
|
+
- Development tools (devtools, time-travel)
|
|
1779
|
+
- State persistence (serialization)
|
|
1780
|
+
|
|
1781
|
+
**Add companion packages when you need:**
|
|
1782
|
+
|
|
1783
|
+
| Package | When to Add | Bundle Impact |
|
|
1784
|
+
| ----------------------------- | ---------------------------------- | ---------------- |
|
|
1785
|
+
| `@signaltree/ng-forms` | Angular Reactive Forms integration | ~10KB gzipped |
|
|
1786
|
+
| `@signaltree/enterprise` | 500+ signals, large-scale apps | ~8KB gzipped |
|
|
1787
|
+
| `@signaltree/guardrails` | Development performance monitoring | 0KB (dev-only) |
|
|
1788
|
+
| `@signaltree/callable-syntax` | Prefer callable syntax sugar | 0KB (build-time) |
|
|
1789
|
+
|
|
1790
|
+
**Typical Installation Patterns:**
|
|
1791
|
+
|
|
1792
|
+
```bash
|
|
1793
|
+
# Basic application
|
|
1794
|
+
npm install @signaltree/core
|
|
1795
|
+
|
|
1796
|
+
# Application with forms
|
|
1797
|
+
npm install @signaltree/core @signaltree/ng-forms
|
|
1798
|
+
|
|
1799
|
+
# Large enterprise application
|
|
1800
|
+
npm install @signaltree/core @signaltree/enterprise
|
|
1801
|
+
|
|
1802
|
+
# Development with all tools
|
|
1803
|
+
npm install @signaltree/core @signaltree/enterprise @signaltree/ng-forms
|
|
1804
|
+
npm install --save-dev @signaltree/guardrails @signaltree/callable-syntax
|
|
1805
|
+
```
|
|
1806
|
+
|
|
1454
1807
|
## Links
|
|
1455
1808
|
|
|
1456
1809
|
- [SignalTree Documentation](https://signaltree.io)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signaltree/core",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.16",
|
|
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,
|
|
@@ -56,13 +56,7 @@
|
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"@angular/core": "^20.3.0",
|
|
59
|
-
"
|
|
60
|
-
"@rollup/plugin-commonjs": "*",
|
|
61
|
-
"@rollup/plugin-node-resolve": "*",
|
|
62
|
-
"@rollup/plugin-typescript": "*",
|
|
63
|
-
"rollup": "*",
|
|
64
|
-
"rollup-plugin-dts": "*",
|
|
65
|
-
"tslib": "*"
|
|
59
|
+
"tslib": "^2.0.0"
|
|
66
60
|
},
|
|
67
61
|
"files": [
|
|
68
62
|
"dist",
|