@signaltree/guardrails 4.0.12
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/CHANGELOG.md +15 -0
- package/README.md +51 -0
- package/dist/factories/index.cjs +922 -0
- package/dist/factories/index.cjs.map +1 -0
- package/dist/factories/index.d.cts +48 -0
- package/dist/factories/index.d.ts +48 -0
- package/dist/factories/index.js +914 -0
- package/dist/factories/index.js.map +1 -0
- package/dist/index.cjs +783 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +44 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +780 -0
- package/dist/index.js.map +1 -0
- package/dist/noop.cjs +31 -0
- package/dist/noop.cjs.map +1 -0
- package/dist/noop.d.cts +19 -0
- package/dist/noop.d.ts +19 -0
- package/dist/noop.js +28 -0
- package/dist/noop.js.map +1 -0
- package/dist/types-DfZ9n1yX.d.cts +255 -0
- package/dist/types-DfZ9n1yX.d.ts +255 -0
- package/package.json +76 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { SignalTree } from '@signaltree/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SignalTree Guardrails - Type Definitions
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
interface GuardrailsConfig<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
9
|
+
/** Behavior mode: warn (console), throw (errors), or silent (collect only) */
|
|
10
|
+
mode?: 'warn' | 'throw' | 'silent';
|
|
11
|
+
/** Enable/disable guardrails */
|
|
12
|
+
enabled?: boolean | (() => boolean);
|
|
13
|
+
/** Performance budget limits */
|
|
14
|
+
budgets?: {
|
|
15
|
+
/** Max milliseconds per update (default: 16) */
|
|
16
|
+
maxUpdateTime?: number;
|
|
17
|
+
/** Max memory in MB (default: 50) */
|
|
18
|
+
maxMemory?: number;
|
|
19
|
+
/** Max recomputations per second (default: 100) */
|
|
20
|
+
maxRecomputations?: number;
|
|
21
|
+
/** Max tree nesting depth (default: 10) */
|
|
22
|
+
maxTreeDepth?: number;
|
|
23
|
+
/** Alert when % of budget used (default: 0.8) */
|
|
24
|
+
alertThreshold?: number;
|
|
25
|
+
};
|
|
26
|
+
/** Hot path analysis configuration */
|
|
27
|
+
hotPaths?: {
|
|
28
|
+
/** Enable hot path detection */
|
|
29
|
+
enabled?: boolean;
|
|
30
|
+
/** Updates/second to consider "hot" (default: 10) */
|
|
31
|
+
threshold?: number;
|
|
32
|
+
/** Track top N hot paths (default: 5) */
|
|
33
|
+
topN?: number;
|
|
34
|
+
/** Track downstream effects */
|
|
35
|
+
trackDownstream?: boolean;
|
|
36
|
+
/** Time window for rate calculation in ms (default: 1000) */
|
|
37
|
+
windowMs?: number;
|
|
38
|
+
};
|
|
39
|
+
/** Memory leak detection */
|
|
40
|
+
memoryLeaks?: {
|
|
41
|
+
/** Enable memory leak detection */
|
|
42
|
+
enabled?: boolean;
|
|
43
|
+
/** Check interval in ms (default: 5000) */
|
|
44
|
+
checkInterval?: number;
|
|
45
|
+
/** Max signals before warning (default: 100) */
|
|
46
|
+
retentionThreshold?: number;
|
|
47
|
+
/** Growth rate % to trigger warning (default: 0.2) */
|
|
48
|
+
growthRate?: number;
|
|
49
|
+
/** Track signals never read */
|
|
50
|
+
trackUnread?: boolean;
|
|
51
|
+
};
|
|
52
|
+
/** Custom rules */
|
|
53
|
+
customRules?: GuardrailRule<T>[];
|
|
54
|
+
/** Intent-aware suppression */
|
|
55
|
+
suppression?: {
|
|
56
|
+
/** Auto-suppress for these intents */
|
|
57
|
+
autoSuppress?: Array<'hydrate' | 'reset' | 'bulk' | 'migration' | 'time-travel' | 'serialization'>;
|
|
58
|
+
/** Honor suppressGuardrails metadata flag */
|
|
59
|
+
respectMetadata?: boolean;
|
|
60
|
+
};
|
|
61
|
+
/** Read/write analysis */
|
|
62
|
+
analysis?: {
|
|
63
|
+
/** Forbid reading entire tree root */
|
|
64
|
+
forbidRootRead?: boolean;
|
|
65
|
+
/** Forbid reading slice roots */
|
|
66
|
+
forbidSliceRootRead?: boolean | string[];
|
|
67
|
+
/** Max dependencies per computed */
|
|
68
|
+
maxDepsPerComputed?: number;
|
|
69
|
+
/** Warn on parent replacement */
|
|
70
|
+
warnParentReplace?: boolean;
|
|
71
|
+
/** Min diff ratio to justify parent replace (default: 0.8) */
|
|
72
|
+
minDiffForParentReplace?: number;
|
|
73
|
+
/** Detect thrashing */
|
|
74
|
+
detectThrashing?: boolean;
|
|
75
|
+
/** Max reruns per second before thrashing */
|
|
76
|
+
maxRerunsPerSecond?: number;
|
|
77
|
+
};
|
|
78
|
+
/** Reporting configuration */
|
|
79
|
+
reporting?: {
|
|
80
|
+
/** Report interval in ms (default: 5000) */
|
|
81
|
+
interval?: number;
|
|
82
|
+
/** Console output: false, true, or 'verbose' */
|
|
83
|
+
console?: boolean | 'verbose';
|
|
84
|
+
/** Custom reporter function */
|
|
85
|
+
customReporter?: (report: GuardrailsReport) => void;
|
|
86
|
+
/** Aggregate similar warnings */
|
|
87
|
+
aggregateWarnings?: boolean;
|
|
88
|
+
/** Max issues per report */
|
|
89
|
+
maxIssuesPerReport?: number;
|
|
90
|
+
};
|
|
91
|
+
/** Tree identifier for multi-tree scenarios */
|
|
92
|
+
treeId?: string;
|
|
93
|
+
}
|
|
94
|
+
interface UpdateMetadata {
|
|
95
|
+
/** Intent of the update */
|
|
96
|
+
intent?: 'hydrate' | 'reset' | 'bulk' | 'migration' | 'user' | 'system';
|
|
97
|
+
/** Source of the update */
|
|
98
|
+
source?: 'serialization' | 'time-travel' | 'devtools' | 'user' | 'system';
|
|
99
|
+
/** Suppress guardrails for this update */
|
|
100
|
+
suppressGuardrails?: boolean;
|
|
101
|
+
/** Timestamp */
|
|
102
|
+
timestamp?: number;
|
|
103
|
+
/** Correlation ID for related updates */
|
|
104
|
+
correlationId?: string;
|
|
105
|
+
/** Additional metadata */
|
|
106
|
+
[key: string]: unknown;
|
|
107
|
+
}
|
|
108
|
+
interface GuardrailRule<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
109
|
+
/** Rule name */
|
|
110
|
+
name: string;
|
|
111
|
+
/** Description */
|
|
112
|
+
description?: string;
|
|
113
|
+
/** Test function */
|
|
114
|
+
test: (context: RuleContext<T>) => boolean | Promise<boolean>;
|
|
115
|
+
/** Error message or message function */
|
|
116
|
+
message: string | ((context: RuleContext<T>) => string);
|
|
117
|
+
/** Severity level */
|
|
118
|
+
severity?: 'error' | 'warning' | 'info';
|
|
119
|
+
/** Optional fix function */
|
|
120
|
+
fix?: (context: RuleContext<T>) => void;
|
|
121
|
+
/** Tags for filtering/grouping */
|
|
122
|
+
tags?: string[];
|
|
123
|
+
}
|
|
124
|
+
interface RuleContext<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
125
|
+
/** Path to the value */
|
|
126
|
+
path: string[];
|
|
127
|
+
/** New value */
|
|
128
|
+
value: unknown;
|
|
129
|
+
/** Previous value */
|
|
130
|
+
oldValue?: unknown;
|
|
131
|
+
/** Update metadata */
|
|
132
|
+
metadata?: UpdateMetadata;
|
|
133
|
+
/** The tree instance */
|
|
134
|
+
tree: SignalTree<T>;
|
|
135
|
+
/** Update duration in ms */
|
|
136
|
+
duration?: number;
|
|
137
|
+
/** Diff ratio (0-1) */
|
|
138
|
+
diffRatio?: number;
|
|
139
|
+
/** Recomputation count */
|
|
140
|
+
recomputeCount?: number;
|
|
141
|
+
/** Downstream effects count */
|
|
142
|
+
downstreamEffects?: number;
|
|
143
|
+
/** Is signal unread */
|
|
144
|
+
isUnread?: boolean;
|
|
145
|
+
/** Runtime statistics */
|
|
146
|
+
stats: RuntimeStats;
|
|
147
|
+
}
|
|
148
|
+
interface RuntimeStats {
|
|
149
|
+
/** Total update count */
|
|
150
|
+
updateCount: number;
|
|
151
|
+
/** Total update time in ms */
|
|
152
|
+
totalUpdateTime: number;
|
|
153
|
+
/** Average update time in ms */
|
|
154
|
+
avgUpdateTime: number;
|
|
155
|
+
/** P50 update time in ms */
|
|
156
|
+
p50UpdateTime: number;
|
|
157
|
+
/** P95 update time in ms */
|
|
158
|
+
p95UpdateTime: number;
|
|
159
|
+
/** P99 update time in ms */
|
|
160
|
+
p99UpdateTime: number;
|
|
161
|
+
/** Max update time in ms */
|
|
162
|
+
maxUpdateTime: number;
|
|
163
|
+
/** Total recomputation count */
|
|
164
|
+
recomputationCount: number;
|
|
165
|
+
/** Recomputations per second */
|
|
166
|
+
recomputationsPerSecond: number;
|
|
167
|
+
/** Total signal count */
|
|
168
|
+
signalCount: number;
|
|
169
|
+
/** Signal retention */
|
|
170
|
+
signalRetention: number;
|
|
171
|
+
/** Unread signal count */
|
|
172
|
+
unreadSignalCount: number;
|
|
173
|
+
/** Memory growth rate */
|
|
174
|
+
memoryGrowthRate: number;
|
|
175
|
+
/** Hot path count */
|
|
176
|
+
hotPathCount: number;
|
|
177
|
+
/** Violation count */
|
|
178
|
+
violationCount: number;
|
|
179
|
+
}
|
|
180
|
+
interface GuardrailIssue {
|
|
181
|
+
/** Issue type */
|
|
182
|
+
type: 'budget' | 'hot-path' | 'memory' | 'rule' | 'analysis';
|
|
183
|
+
/** Severity */
|
|
184
|
+
severity: 'error' | 'warning' | 'info';
|
|
185
|
+
/** Message */
|
|
186
|
+
message: string;
|
|
187
|
+
/** Path */
|
|
188
|
+
path?: string;
|
|
189
|
+
/** Occurrence count */
|
|
190
|
+
count: number;
|
|
191
|
+
/** Diff ratio if applicable */
|
|
192
|
+
diffRatio?: number;
|
|
193
|
+
/** Additional metadata */
|
|
194
|
+
metadata?: Record<string, unknown>;
|
|
195
|
+
}
|
|
196
|
+
interface HotPath {
|
|
197
|
+
/** Path */
|
|
198
|
+
path: string;
|
|
199
|
+
/** Updates per second */
|
|
200
|
+
updatesPerSecond: number;
|
|
201
|
+
/** Heat score (0-100) */
|
|
202
|
+
heatScore: number;
|
|
203
|
+
/** Downstream effects count */
|
|
204
|
+
downstreamEffects: number;
|
|
205
|
+
/** Average duration in ms */
|
|
206
|
+
avgDuration: number;
|
|
207
|
+
/** P95 duration in ms */
|
|
208
|
+
p95Duration: number;
|
|
209
|
+
}
|
|
210
|
+
interface BudgetStatus {
|
|
211
|
+
/** Update time budget */
|
|
212
|
+
updateTime: BudgetItem;
|
|
213
|
+
/** Memory budget */
|
|
214
|
+
memory: BudgetItem;
|
|
215
|
+
/** Recomputation budget */
|
|
216
|
+
recomputations: BudgetItem;
|
|
217
|
+
}
|
|
218
|
+
interface BudgetItem {
|
|
219
|
+
/** Current value */
|
|
220
|
+
current: number;
|
|
221
|
+
/** Budget limit */
|
|
222
|
+
limit: number;
|
|
223
|
+
/** Usage percentage */
|
|
224
|
+
usage: number;
|
|
225
|
+
/** Status */
|
|
226
|
+
status: 'ok' | 'warning' | 'exceeded';
|
|
227
|
+
}
|
|
228
|
+
interface GuardrailsReport {
|
|
229
|
+
/** Report timestamp */
|
|
230
|
+
timestamp: number;
|
|
231
|
+
/** Tree ID if configured */
|
|
232
|
+
treeId?: string;
|
|
233
|
+
/** Issues detected */
|
|
234
|
+
issues: GuardrailIssue[];
|
|
235
|
+
/** Hot paths */
|
|
236
|
+
hotPaths: HotPath[];
|
|
237
|
+
/** Budget status */
|
|
238
|
+
budgets: BudgetStatus;
|
|
239
|
+
/** Runtime statistics */
|
|
240
|
+
stats: RuntimeStats;
|
|
241
|
+
/** Recommendations */
|
|
242
|
+
recommendations: string[];
|
|
243
|
+
}
|
|
244
|
+
interface GuardrailsAPI {
|
|
245
|
+
/** Get current report */
|
|
246
|
+
getReport(): GuardrailsReport;
|
|
247
|
+
/** Get runtime stats */
|
|
248
|
+
getStats(): RuntimeStats;
|
|
249
|
+
/** Suppress guardrails during function execution */
|
|
250
|
+
suppress(fn: () => void): void;
|
|
251
|
+
/** Dispose and cleanup */
|
|
252
|
+
dispose(): void;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export type { BudgetStatus as B, GuardrailsConfig as G, HotPath as H, RuleContext as R, UpdateMetadata as U, GuardrailRule as a, RuntimeStats as b, GuardrailIssue as c, BudgetItem as d, GuardrailsReport as e, GuardrailsAPI as f };
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@signaltree/guardrails",
|
|
3
|
+
"version": "4.0.12",
|
|
4
|
+
"description": "Development-only performance monitoring and anti-pattern detection for SignalTree",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"development": {
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"require": "./dist/index.cjs"
|
|
16
|
+
},
|
|
17
|
+
"production": {
|
|
18
|
+
"import": "./dist/noop.js",
|
|
19
|
+
"require": "./dist/noop.cjs"
|
|
20
|
+
},
|
|
21
|
+
"default": "./dist/noop.js"
|
|
22
|
+
},
|
|
23
|
+
"./factories": {
|
|
24
|
+
"types": "./dist/factories/index.d.ts",
|
|
25
|
+
"development": {
|
|
26
|
+
"import": "./dist/factories/index.js",
|
|
27
|
+
"require": "./dist/factories/index.cjs"
|
|
28
|
+
},
|
|
29
|
+
"production": {
|
|
30
|
+
"import": "./dist/noop.js",
|
|
31
|
+
"require": "./dist/noop.cjs"
|
|
32
|
+
},
|
|
33
|
+
"default": "./dist/noop.js"
|
|
34
|
+
},
|
|
35
|
+
"./package.json": "./package.json"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"README.md",
|
|
40
|
+
"CHANGELOG.md"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsup",
|
|
44
|
+
"test": "jest",
|
|
45
|
+
"test:watch": "jest --watch",
|
|
46
|
+
"test:coverage": "jest --coverage",
|
|
47
|
+
"lint": "eslint src --ext .ts",
|
|
48
|
+
"type-check": "tsc --noEmit"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"@signaltree/core": "^4.0.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@signaltree/core": "workspace:*",
|
|
55
|
+
"@signaltree/shared": "workspace:*",
|
|
56
|
+
"@signaltree/types": "workspace:*",
|
|
57
|
+
"tsup": "^8.0.0"
|
|
58
|
+
},
|
|
59
|
+
"keywords": [
|
|
60
|
+
"signaltree",
|
|
61
|
+
"state-management",
|
|
62
|
+
"performance",
|
|
63
|
+
"development-tools",
|
|
64
|
+
"guardrails",
|
|
65
|
+
"monitoring",
|
|
66
|
+
"angular",
|
|
67
|
+
"signals"
|
|
68
|
+
],
|
|
69
|
+
"author": "SignalTree Team",
|
|
70
|
+
"license": "MIT",
|
|
71
|
+
"repository": {
|
|
72
|
+
"type": "git",
|
|
73
|
+
"url": "https://github.com/signaltree/signaltree.git",
|
|
74
|
+
"directory": "packages/guardrails"
|
|
75
|
+
}
|
|
76
|
+
}
|