ng-form-devtools 0.1.0 → 0.1.2

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 ADDED
@@ -0,0 +1,82 @@
1
+ # ng-form-devtools
2
+
3
+ `ng-form-devtools` helps you inspect Angular forms during development.
4
+ It adds runtime form tracking to your app, creates structured snapshots, and provides the bridge for an upcoming Chrome DevTools experience focused on Angular forms.
5
+
6
+ ## Current Status
7
+
8
+ `ng-form-devtools` is currently a work in progress. Feedback, ideas, and bug reports are very welcome.
9
+ The API and overall behavior are planned to be considered stable starting with `v1.0.0`.
10
+
11
+ The Chrome DevTools integration is also still evolving. A dedicated Chrome plugin is planned and this package already contains the foundation for that upcoming extension.
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npm install ng-form-devtools
17
+ ```
18
+
19
+ ## Minimal Setup
20
+
21
+ ```ts
22
+ import { provideExperimentalZonelessChangeDetection } from '@angular/core';
23
+ import { bootstrapApplication } from '@angular/platform-browser';
24
+ import { provideFormDevtools } from 'ng-form-devtools';
25
+
26
+ bootstrapApplication(AppComponent, {
27
+ providers: [
28
+ provideExperimentalZonelessChangeDetection(),
29
+ provideFormDevtools({ bridge: 'window-message' })
30
+ ]
31
+ });
32
+ ```
33
+
34
+ Track a form inside an injection context:
35
+
36
+ ```ts
37
+ import { Component } from '@angular/core';
38
+ import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
39
+ import { track } from 'ng-form-devtools';
40
+
41
+ @Component({
42
+ standalone: true,
43
+ imports: [ReactiveFormsModule],
44
+ template: `<form [formGroup]="form"></form>`
45
+ })
46
+ export class ExampleFormComponent {
47
+ private readonly formBuilder = new FormBuilder();
48
+
49
+ readonly form = this.formBuilder.group({
50
+ firstName: [''],
51
+ lastName: ['']
52
+ });
53
+
54
+ private readonly _tracked = track(this.form, 'profileForm');
55
+ }
56
+ ```
57
+
58
+ ## Local Demo And Documentation
59
+
60
+ If you want to explore the project locally, clone the repository, install dependencies, and start the example app:
61
+
62
+ ```bash
63
+ npm install
64
+ npm run dev
65
+ ```
66
+
67
+ The example app currently acts as the easiest hands-on documentation for the package.
68
+
69
+ To test the Chrome DevTools integration locally:
70
+
71
+ 1. Run `npm run build:extension:chrome-devtools`.
72
+ 2. Open `chrome://extensions`.
73
+ 3. Enable Developer Mode.
74
+ 4. Click `Load unpacked`.
75
+ 5. Select `dist/extensions/chrome-devtools`.
76
+ 6. Open the example app in Chrome.
77
+ 7. Open Chrome DevTools and switch to the `Angular Forms` panel.
78
+
79
+ ## More Information
80
+
81
+ - Repository: [github.com/timtilch/ng-form-devtools](https://github.com/timtilch/ng-form-devtools)
82
+ - Issues and feedback: [github.com/timtilch/ng-form-devtools/issues](https://github.com/timtilch/ng-form-devtools/issues)
@@ -0,0 +1,533 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, inject, ApplicationRef, DestroyRef, Injectable, makeEnvironmentProviders, assertInInjectionContext } from '@angular/core';
3
+ import { ReplaySubject, Subscription, merge } from 'rxjs';
4
+ import { FormControl, FormArray, FormRecord, FormGroup } from '@angular/forms';
5
+
6
+ function serializeControlPath(path) {
7
+ if (path.length === 0) {
8
+ return 'root';
9
+ }
10
+ return path.map((segment) => (typeof segment === 'number' ? `[${segment}]` : segment)).join('.');
11
+ }
12
+ function walkControlTree(root, visitor) {
13
+ visitor(root);
14
+ for (const child of root.children) {
15
+ walkControlTree(child, visitor);
16
+ }
17
+ }
18
+
19
+ const NG_FORM_DEVTOOLS_SOURCE = 'NG_FORM_DEVTOOLS';
20
+ const NG_FORM_DEVTOOLS_EXTENSION_SOURCE = 'NG_FORM_DEVTOOLS_EXTENSION';
21
+ function toDebugControlNode(control) {
22
+ return {
23
+ id: control.id,
24
+ name: control.name,
25
+ type: control.kind,
26
+ path: serializeControlPath(control.path),
27
+ value: control.value,
28
+ valid: control.valid,
29
+ invalid: control.invalid,
30
+ status: control.status,
31
+ touched: control.touched,
32
+ dirty: control.dirty,
33
+ disabled: control.disabled,
34
+ errors: control.errors,
35
+ children: control.children.map((child) => toDebugControlNode(child))
36
+ };
37
+ }
38
+ function toDebugFormSnapshot(snapshot) {
39
+ return {
40
+ formId: snapshot.id,
41
+ formName: snapshot.name,
42
+ source: snapshot.source,
43
+ timestamp: snapshot.timestamp,
44
+ capturedAt: snapshot.capturedAt,
45
+ root: toDebugControlNode(snapshot.root)
46
+ };
47
+ }
48
+ function createFormRegisteredMessage(snapshot) {
49
+ return {
50
+ source: NG_FORM_DEVTOOLS_SOURCE,
51
+ type: 'FORM_REGISTERED',
52
+ payload: {
53
+ formId: snapshot.id,
54
+ formName: snapshot.name,
55
+ source: snapshot.source
56
+ }
57
+ };
58
+ }
59
+ function createFormSnapshotMessage(snapshot) {
60
+ return {
61
+ source: NG_FORM_DEVTOOLS_SOURCE,
62
+ type: 'FORM_SNAPSHOT',
63
+ payload: toDebugFormSnapshot(snapshot)
64
+ };
65
+ }
66
+ function createFormRemovedMessage(formId) {
67
+ return {
68
+ source: NG_FORM_DEVTOOLS_SOURCE,
69
+ type: 'FORM_REMOVED',
70
+ payload: {
71
+ formId
72
+ }
73
+ };
74
+ }
75
+ function isDevtoolsMessage(value) {
76
+ if (!isRecord(value)) {
77
+ return false;
78
+ }
79
+ return (value['source'] === NG_FORM_DEVTOOLS_SOURCE &&
80
+ (value['type'] === 'FORM_REGISTERED' ||
81
+ value['type'] === 'FORM_SNAPSHOT' ||
82
+ value['type'] === 'FORM_REMOVED'));
83
+ }
84
+ function createRequestStateMessage() {
85
+ return {
86
+ source: NG_FORM_DEVTOOLS_EXTENSION_SOURCE,
87
+ type: 'REQUEST_STATE'
88
+ };
89
+ }
90
+ function createApplySnapshotMessage(snapshot) {
91
+ return {
92
+ source: NG_FORM_DEVTOOLS_EXTENSION_SOURCE,
93
+ type: 'APPLY_SNAPSHOT',
94
+ payload: snapshot
95
+ };
96
+ }
97
+ function isRequestStateMessage(value) {
98
+ return (isRecord(value) &&
99
+ value['source'] === NG_FORM_DEVTOOLS_EXTENSION_SOURCE &&
100
+ value['type'] === 'REQUEST_STATE');
101
+ }
102
+ function isApplySnapshotMessage(value) {
103
+ return (isRecord(value) &&
104
+ value['source'] === NG_FORM_DEVTOOLS_EXTENSION_SOURCE &&
105
+ value['type'] === 'APPLY_SNAPSHOT' &&
106
+ isDebugFormSnapshot(value['payload']));
107
+ }
108
+ function isDebugFormSnapshot(value) {
109
+ return (isRecord(value) &&
110
+ typeof value['formId'] === 'string' &&
111
+ typeof value['formName'] === 'string' &&
112
+ (value['source'] === 'reactive' || value['source'] === 'signal') &&
113
+ typeof value['timestamp'] === 'number' &&
114
+ typeof value['capturedAt'] === 'string' &&
115
+ isDebugControlNode(value['root']));
116
+ }
117
+ function isDebugControlNode(value) {
118
+ return (isRecord(value) &&
119
+ typeof value['id'] === 'string' &&
120
+ typeof value['name'] === 'string' &&
121
+ (value['type'] === 'group' || value['type'] === 'control' || value['type'] === 'array') &&
122
+ typeof value['path'] === 'string' &&
123
+ typeof value['valid'] === 'boolean' &&
124
+ typeof value['invalid'] === 'boolean' &&
125
+ typeof value['status'] === 'string' &&
126
+ typeof value['touched'] === 'boolean' &&
127
+ typeof value['dirty'] === 'boolean' &&
128
+ typeof value['disabled'] === 'boolean' &&
129
+ Array.isArray(value['children']) &&
130
+ value['children'].every((child) => isDebugControlNode(child)));
131
+ }
132
+ function isRecord(value) {
133
+ return typeof value === 'object' && value !== null;
134
+ }
135
+
136
+ function createTrackedFormSnapshot(input) {
137
+ const timestamp = input.timestamp ?? Date.now();
138
+ return {
139
+ ...input,
140
+ timestamp,
141
+ capturedAt: input.capturedAt ?? new Date(timestamp).toISOString()
142
+ };
143
+ }
144
+
145
+ const noopFormDevtoolsBridge = {
146
+ emit: () => undefined,
147
+ onRequestState: () => () => undefined,
148
+ onApplySnapshot: () => () => undefined
149
+ };
150
+ const windowPostMessageFormDevtoolsBridge = {
151
+ emit(message) {
152
+ if (typeof window === 'undefined') {
153
+ return;
154
+ }
155
+ window.postMessage(message, '*');
156
+ },
157
+ onRequestState(handler) {
158
+ if (typeof window === 'undefined') {
159
+ return () => undefined;
160
+ }
161
+ const listener = (event) => {
162
+ if (event.source !== window || !isRequestStateMessage(event.data)) {
163
+ return;
164
+ }
165
+ handler();
166
+ };
167
+ window.addEventListener('message', listener);
168
+ return () => {
169
+ window.removeEventListener('message', listener);
170
+ };
171
+ },
172
+ onApplySnapshot(handler) {
173
+ if (typeof window === 'undefined') {
174
+ return () => undefined;
175
+ }
176
+ const listener = (event) => {
177
+ if (event.source !== window || !isApplySnapshotMessage(event.data)) {
178
+ return;
179
+ }
180
+ handler(event.data);
181
+ };
182
+ window.addEventListener('message', listener);
183
+ return () => {
184
+ window.removeEventListener('message', listener);
185
+ };
186
+ }
187
+ };
188
+ const FORM_DEVTOOLS_BRIDGE = new InjectionToken('FORM_DEVTOOLS_BRIDGE', {
189
+ factory: () => noopFormDevtoolsBridge
190
+ });
191
+
192
+ const FORM_DEVTOOLS_OPTIONS = new InjectionToken('FORM_DEVTOOLS_OPTIONS', {
193
+ factory: () => ({ bridge: 'off' })
194
+ });
195
+
196
+ function applyReactiveFormSnapshot(control, snapshot) {
197
+ restoreControl(control, snapshot);
198
+ control.updateValueAndValidity({ emitEvent: false });
199
+ }
200
+ function restoreControl(control, snapshot) {
201
+ if (!snapshot.disabled && control.disabled) {
202
+ control.enable({ emitEvent: false });
203
+ }
204
+ if (control instanceof FormControl) {
205
+ control.setValue(snapshot.value, { emitEvent: false });
206
+ }
207
+ else if (control instanceof FormArray) {
208
+ syncFormArrayLength(control, snapshot.children);
209
+ snapshot.children.forEach((childSnapshot, index) => {
210
+ const childControl = control.at(index);
211
+ if (childControl) {
212
+ restoreControl(childControl, childSnapshot);
213
+ }
214
+ });
215
+ }
216
+ else if (control instanceof FormRecord || control instanceof FormGroup) {
217
+ const childControls = control.controls;
218
+ snapshot.children.forEach((childSnapshot) => {
219
+ const childControl = childControls[childSnapshot.name];
220
+ if (childControl) {
221
+ restoreControl(childControl, childSnapshot);
222
+ }
223
+ });
224
+ }
225
+ syncInteractionState(control, snapshot);
226
+ if (snapshot.disabled && control.enabled) {
227
+ control.disable({ emitEvent: false });
228
+ }
229
+ control.updateValueAndValidity({
230
+ onlySelf: true,
231
+ emitEvent: false
232
+ });
233
+ }
234
+ function syncFormArrayLength(array, snapshots) {
235
+ while (array.length > snapshots.length) {
236
+ array.removeAt(array.length - 1, { emitEvent: false });
237
+ }
238
+ const template = array.at(0);
239
+ while (array.length < snapshots.length) {
240
+ const snapshot = snapshots[array.length];
241
+ array.push(createChildControl(snapshot, template), { emitEvent: false });
242
+ }
243
+ }
244
+ function createChildControl(snapshot, template) {
245
+ if (template && matchesSnapshotType(template, snapshot)) {
246
+ return cloneControl(template);
247
+ }
248
+ return createControlFromSnapshot(snapshot);
249
+ }
250
+ function matchesSnapshotType(control, snapshot) {
251
+ if (control instanceof FormArray) {
252
+ return snapshot.type === 'array';
253
+ }
254
+ if (control instanceof FormRecord || control instanceof FormGroup) {
255
+ return snapshot.type === 'group';
256
+ }
257
+ return snapshot.type === 'control';
258
+ }
259
+ function cloneControl(control) {
260
+ if (control instanceof FormControl) {
261
+ return new FormControl(control.getRawValue(), createControlOptions(control));
262
+ }
263
+ if (control instanceof FormArray) {
264
+ return new FormArray(control.controls.map((child) => cloneControl(child)), createControlOptions(control));
265
+ }
266
+ if (control instanceof FormRecord) {
267
+ return new FormRecord(cloneControlMap(control.controls), createControlOptions(control));
268
+ }
269
+ if (control instanceof FormGroup) {
270
+ return new FormGroup(cloneControlMap(control.controls), createControlOptions(control));
271
+ }
272
+ return new FormControl(control.getRawValue(), createControlOptions(control));
273
+ }
274
+ function createControlFromSnapshot(snapshot) {
275
+ if (snapshot.type === 'array') {
276
+ return new FormArray(snapshot.children.map((child) => createControlFromSnapshot(child)));
277
+ }
278
+ if (snapshot.type === 'group') {
279
+ return new FormGroup(Object.fromEntries(snapshot.children.map((child) => [child.name, createControlFromSnapshot(child)])));
280
+ }
281
+ return new FormControl(snapshot.value);
282
+ }
283
+ function cloneControlMap(controls) {
284
+ return Object.fromEntries(Object.entries(controls).map(([name, child]) => [name, cloneControl(child)]));
285
+ }
286
+ function syncInteractionState(control, snapshot) {
287
+ if (control instanceof FormControl) {
288
+ if (snapshot.touched) {
289
+ control.markAsTouched({ onlySelf: true, emitEvent: false });
290
+ }
291
+ else {
292
+ control.markAsUntouched({ emitEvent: false });
293
+ }
294
+ if (snapshot.dirty) {
295
+ control.markAsDirty({ onlySelf: true, emitEvent: false });
296
+ }
297
+ else {
298
+ control.markAsPristine({ emitEvent: false });
299
+ }
300
+ return;
301
+ }
302
+ if (snapshot.touched) {
303
+ control.markAsTouched({ onlySelf: true, emitEvent: false });
304
+ }
305
+ if (snapshot.dirty) {
306
+ control.markAsDirty({ onlySelf: true, emitEvent: false });
307
+ }
308
+ }
309
+ function createControlOptions(control) {
310
+ const options = {};
311
+ if (control.validator) {
312
+ options.validators = control.validator;
313
+ }
314
+ if (control.asyncValidator) {
315
+ options.asyncValidators = control.asyncValidator;
316
+ }
317
+ if (control.updateOn !== 'change') {
318
+ options.updateOn = control.updateOn;
319
+ }
320
+ return Object.keys(options).length > 0 ? options : null;
321
+ }
322
+
323
+ function createReactiveFormSnapshot(form, formId, name) {
324
+ return createTrackedFormSnapshot({
325
+ id: formId,
326
+ name,
327
+ source: 'reactive',
328
+ root: createControlSnapshot(form, name, [])
329
+ });
330
+ }
331
+ function createControlSnapshot(control, name, path) {
332
+ return {
333
+ id: serializeControlPath(path),
334
+ name,
335
+ path,
336
+ kind: resolveControlKind(control),
337
+ value: control.getRawValue(),
338
+ status: control.status,
339
+ valid: control.valid,
340
+ invalid: control.invalid,
341
+ touched: control.touched,
342
+ dirty: control.dirty,
343
+ disabled: control.disabled,
344
+ errors: control.errors,
345
+ children: collectChildren(control, path)
346
+ };
347
+ }
348
+ function collectChildren(control, path) {
349
+ if (control instanceof FormGroup || control instanceof FormRecord) {
350
+ return Object.entries(control.controls).map(([name, child]) => createControlSnapshot(child, name, [...path, name]));
351
+ }
352
+ if (control instanceof FormArray) {
353
+ return control.controls.map((child, index) => createControlSnapshot(child, `[${index}]`, [...path, index]));
354
+ }
355
+ return [];
356
+ }
357
+ function resolveControlKind(control) {
358
+ if (control instanceof FormArray) {
359
+ return 'array';
360
+ }
361
+ if (control instanceof FormGroup || control instanceof FormRecord) {
362
+ return 'group';
363
+ }
364
+ if (control instanceof FormControl) {
365
+ return 'control';
366
+ }
367
+ return 'control';
368
+ }
369
+
370
+ class FormDevtools {
371
+ applicationRef = inject(ApplicationRef);
372
+ bridge = inject(FORM_DEVTOOLS_BRIDGE);
373
+ destroyRef = inject(DestroyRef);
374
+ entriesByControl = new WeakMap();
375
+ entriesById = new Map();
376
+ nextFormId = 0;
377
+ domRefreshScheduled = false;
378
+ constructor() {
379
+ const stopRequestState = this.bridge.onRequestState?.(() => this.emitAllSnapshots());
380
+ const stopApplySnapshot = this.bridge.onApplySnapshot?.((message) => this.applySnapshot(message));
381
+ if (stopRequestState) {
382
+ this.destroyRef.onDestroy(stopRequestState);
383
+ }
384
+ if (stopApplySnapshot) {
385
+ this.destroyRef.onDestroy(stopApplySnapshot);
386
+ }
387
+ }
388
+ track(form, options = {}) {
389
+ const name = options.name ?? 'form';
390
+ const entry = this.ensureEntry(form, name);
391
+ entry.refs += 1;
392
+ let stopped = false;
393
+ const stop = () => {
394
+ if (stopped) {
395
+ return;
396
+ }
397
+ stopped = true;
398
+ const current = this.entriesByControl.get(form);
399
+ if (!current) {
400
+ return;
401
+ }
402
+ current.refs -= 1;
403
+ if (current.refs <= 0) {
404
+ current.subscription.unsubscribe();
405
+ current.stream.complete();
406
+ this.entriesByControl.delete(form);
407
+ this.entriesById.delete(current.id);
408
+ this.bridge.emit(createFormRemovedMessage(current.id));
409
+ }
410
+ };
411
+ options.destroyRef?.onDestroy(stop);
412
+ return stop;
413
+ }
414
+ snapshot$(form) {
415
+ const entry = this.entriesByControl.get(form);
416
+ if (!entry) {
417
+ throw new Error('FormDevtools.snapshot$ was called before the form was tracked. Call track() first.');
418
+ }
419
+ return entry.stream;
420
+ }
421
+ ensureEntry(form, name) {
422
+ const existing = this.entriesByControl.get(form);
423
+ if (existing) {
424
+ if (existing.name !== name) {
425
+ existing.name = name;
426
+ this.pushSnapshot(form, existing);
427
+ }
428
+ return existing;
429
+ }
430
+ const stream = new ReplaySubject(1);
431
+ const entry = {
432
+ id: this.createFormId(),
433
+ name,
434
+ form,
435
+ refs: 0,
436
+ stream,
437
+ subscription: Subscription.EMPTY
438
+ };
439
+ this.entriesByControl.set(form, entry);
440
+ this.entriesById.set(entry.id, entry);
441
+ const initialSnapshot = this.createSnapshot(form, entry);
442
+ stream.next(initialSnapshot);
443
+ this.bridge.emit(createFormRegisteredMessage(initialSnapshot));
444
+ this.bridge.emit(createFormSnapshotMessage(initialSnapshot));
445
+ entry.subscription = merge(form.valueChanges, form.statusChanges).subscribe(() => this.pushSnapshot(form, entry));
446
+ return entry;
447
+ }
448
+ pushSnapshot(form, entry) {
449
+ const snapshot = this.createSnapshot(form, entry);
450
+ entry.stream.next(snapshot);
451
+ this.bridge.emit(createFormSnapshotMessage(snapshot));
452
+ }
453
+ createSnapshot(form, entry) {
454
+ return createReactiveFormSnapshot(form, entry.id, entry.name);
455
+ }
456
+ createFormId() {
457
+ this.nextFormId += 1;
458
+ return `ng-form-${this.nextFormId}`;
459
+ }
460
+ emitAllSnapshots() {
461
+ for (const entry of this.entriesById.values()) {
462
+ const snapshot = this.createSnapshot(entry.form, entry);
463
+ entry.stream.next(snapshot);
464
+ this.bridge.emit(createFormRegisteredMessage(snapshot));
465
+ this.bridge.emit(createFormSnapshotMessage(snapshot));
466
+ }
467
+ }
468
+ applySnapshot(message) {
469
+ const entry = this.entriesById.get(message.payload.formId);
470
+ if (!entry || message.payload.source !== 'reactive') {
471
+ return;
472
+ }
473
+ applyReactiveFormSnapshot(entry.form, message.payload.root);
474
+ this.scheduleDomRefresh();
475
+ }
476
+ scheduleDomRefresh() {
477
+ if (this.domRefreshScheduled) {
478
+ return;
479
+ }
480
+ this.domRefreshScheduled = true;
481
+ queueMicrotask(() => {
482
+ this.domRefreshScheduled = false;
483
+ this.applicationRef.tick();
484
+ });
485
+ }
486
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FormDevtools, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
487
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FormDevtools, providedIn: 'root' });
488
+ }
489
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FormDevtools, decorators: [{
490
+ type: Injectable,
491
+ args: [{ providedIn: 'root' }]
492
+ }], ctorParameters: () => [] });
493
+
494
+ function provideFormDevtools(options = {}) {
495
+ const bridge = resolveBridge(options.bridge);
496
+ return makeEnvironmentProviders([
497
+ {
498
+ provide: FORM_DEVTOOLS_OPTIONS,
499
+ useValue: {
500
+ bridge: 'off',
501
+ ...options
502
+ }
503
+ },
504
+ {
505
+ provide: FORM_DEVTOOLS_BRIDGE,
506
+ useValue: bridge
507
+ }
508
+ ]);
509
+ }
510
+ function resolveBridge(bridge) {
511
+ if (bridge === undefined || bridge === 'off') {
512
+ return noopFormDevtoolsBridge;
513
+ }
514
+ if (bridge === 'window-message') {
515
+ return windowPostMessageFormDevtoolsBridge;
516
+ }
517
+ return bridge;
518
+ }
519
+
520
+ function track(form, name) {
521
+ assertInInjectionContext(track);
522
+ return inject(FormDevtools).track(form, {
523
+ name,
524
+ destroyRef: inject(DestroyRef)
525
+ });
526
+ }
527
+
528
+ /**
529
+ * Generated bundle index. Do not edit.
530
+ */
531
+
532
+ export { FORM_DEVTOOLS_BRIDGE, FORM_DEVTOOLS_OPTIONS, FormDevtools, NG_FORM_DEVTOOLS_EXTENSION_SOURCE, NG_FORM_DEVTOOLS_SOURCE, createApplySnapshotMessage, createFormRegisteredMessage, createFormRemovedMessage, createFormSnapshotMessage, createRequestStateMessage, createTrackedFormSnapshot, isApplySnapshotMessage, isDebugFormSnapshot, isDevtoolsMessage, isRequestStateMessage, noopFormDevtoolsBridge, provideFormDevtools, serializeControlPath, toDebugControlNode, toDebugFormSnapshot, track, walkControlTree, windowPostMessageFormDevtoolsBridge };
533
+ //# sourceMappingURL=ng-form-devtools.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-form-devtools.mjs","sources":["../../src/lib/tree-utils.ts","../../src/lib/devtools-message.ts","../../src/lib/form-snapshot.ts","../../src/lib/form-devtools.bridge.ts","../../src/lib/form-devtools.options.ts","../../src/lib/apply-reactive-form-snapshot.ts","../../src/lib/reactive-forms-snapshot.ts","../../src/lib/form-devtools.service.ts","../../src/lib/provide-form-devtools.ts","../../src/lib/track.ts","../../src/ng-form-devtools.ts"],"sourcesContent":["import { ControlPathSegment, ControlSnapshot } from './control-snapshot';\n\nexport function serializeControlPath(path: readonly ControlPathSegment[]): string {\n if (path.length === 0) {\n return 'root';\n }\n\n return path.map((segment) => (typeof segment === 'number' ? `[${segment}]` : segment)).join('.');\n}\n\nexport function walkControlTree(\n root: ControlSnapshot,\n visitor: (control: ControlSnapshot) => void\n): void {\n visitor(root);\n\n for (const child of root.children) {\n walkControlTree(child, visitor);\n }\n}\n","import { ControlKind, ControlSnapshot, ControlStatus } from './control-snapshot';\nimport { TrackedFormSnapshot } from './form-snapshot';\nimport { serializeControlPath } from './tree-utils';\n\nexport const NG_FORM_DEVTOOLS_SOURCE = 'NG_FORM_DEVTOOLS';\nexport const NG_FORM_DEVTOOLS_EXTENSION_SOURCE = 'NG_FORM_DEVTOOLS_EXTENSION';\n\nexport interface DebugControlNode {\n id: string;\n name: string;\n type: ControlKind;\n path: string;\n value: unknown;\n valid: boolean;\n invalid: boolean;\n status: ControlStatus;\n touched: boolean;\n dirty: boolean;\n disabled: boolean;\n errors: Record<string, unknown> | null;\n children: readonly DebugControlNode[];\n}\n\nexport interface DebugFormSnapshot {\n formId: string;\n formName: string;\n source: 'reactive' | 'signal';\n timestamp: number;\n capturedAt: string;\n root: DebugControlNode;\n}\n\nexport interface FormRegisteredMessage {\n source: typeof NG_FORM_DEVTOOLS_SOURCE;\n type: 'FORM_REGISTERED';\n payload: {\n formId: string;\n formName: string;\n source: 'reactive' | 'signal';\n };\n}\n\nexport interface FormSnapshotMessage {\n source: typeof NG_FORM_DEVTOOLS_SOURCE;\n type: 'FORM_SNAPSHOT';\n payload: DebugFormSnapshot;\n}\n\nexport interface FormRemovedMessage {\n source: typeof NG_FORM_DEVTOOLS_SOURCE;\n type: 'FORM_REMOVED';\n payload: {\n formId: string;\n };\n}\n\nexport interface RequestStateMessage {\n source: typeof NG_FORM_DEVTOOLS_EXTENSION_SOURCE;\n type: 'REQUEST_STATE';\n}\n\nexport interface ApplySnapshotMessage {\n source: typeof NG_FORM_DEVTOOLS_EXTENSION_SOURCE;\n type: 'APPLY_SNAPSHOT';\n payload: DebugFormSnapshot;\n}\n\nexport type DevtoolsMessage = FormRegisteredMessage | FormSnapshotMessage | FormRemovedMessage;\n\nexport type DevtoolsBridgeInboundMessage = RequestStateMessage | ApplySnapshotMessage;\n\nexport function toDebugControlNode(control: ControlSnapshot): DebugControlNode {\n return {\n id: control.id,\n name: control.name,\n type: control.kind,\n path: serializeControlPath(control.path),\n value: control.value,\n valid: control.valid,\n invalid: control.invalid,\n status: control.status,\n touched: control.touched,\n dirty: control.dirty,\n disabled: control.disabled,\n errors: control.errors,\n children: control.children.map((child) => toDebugControlNode(child))\n };\n}\n\nexport function toDebugFormSnapshot(snapshot: TrackedFormSnapshot): DebugFormSnapshot {\n return {\n formId: snapshot.id,\n formName: snapshot.name,\n source: snapshot.source,\n timestamp: snapshot.timestamp,\n capturedAt: snapshot.capturedAt,\n root: toDebugControlNode(snapshot.root)\n };\n}\n\nexport function createFormRegisteredMessage(snapshot: TrackedFormSnapshot): FormRegisteredMessage {\n return {\n source: NG_FORM_DEVTOOLS_SOURCE,\n type: 'FORM_REGISTERED',\n payload: {\n formId: snapshot.id,\n formName: snapshot.name,\n source: snapshot.source\n }\n };\n}\n\nexport function createFormSnapshotMessage(snapshot: TrackedFormSnapshot): FormSnapshotMessage {\n return {\n source: NG_FORM_DEVTOOLS_SOURCE,\n type: 'FORM_SNAPSHOT',\n payload: toDebugFormSnapshot(snapshot)\n };\n}\n\nexport function createFormRemovedMessage(formId: string): FormRemovedMessage {\n return {\n source: NG_FORM_DEVTOOLS_SOURCE,\n type: 'FORM_REMOVED',\n payload: {\n formId\n }\n };\n}\n\nexport function isDevtoolsMessage(value: unknown): value is DevtoolsMessage {\n if (!isRecord(value)) {\n return false;\n }\n\n return (\n value['source'] === NG_FORM_DEVTOOLS_SOURCE &&\n (value['type'] === 'FORM_REGISTERED' ||\n value['type'] === 'FORM_SNAPSHOT' ||\n value['type'] === 'FORM_REMOVED')\n );\n}\n\nexport function createRequestStateMessage(): RequestStateMessage {\n return {\n source: NG_FORM_DEVTOOLS_EXTENSION_SOURCE,\n type: 'REQUEST_STATE'\n };\n}\n\nexport function createApplySnapshotMessage(snapshot: DebugFormSnapshot): ApplySnapshotMessage {\n return {\n source: NG_FORM_DEVTOOLS_EXTENSION_SOURCE,\n type: 'APPLY_SNAPSHOT',\n payload: snapshot\n };\n}\n\nexport function isRequestStateMessage(value: unknown): value is RequestStateMessage {\n return (\n isRecord(value) &&\n value['source'] === NG_FORM_DEVTOOLS_EXTENSION_SOURCE &&\n value['type'] === 'REQUEST_STATE'\n );\n}\n\nexport function isApplySnapshotMessage(value: unknown): value is ApplySnapshotMessage {\n return (\n isRecord(value) &&\n value['source'] === NG_FORM_DEVTOOLS_EXTENSION_SOURCE &&\n value['type'] === 'APPLY_SNAPSHOT' &&\n isDebugFormSnapshot(value['payload'])\n );\n}\n\nexport function isDebugFormSnapshot(value: unknown): value is DebugFormSnapshot {\n return (\n isRecord(value) &&\n typeof value['formId'] === 'string' &&\n typeof value['formName'] === 'string' &&\n (value['source'] === 'reactive' || value['source'] === 'signal') &&\n typeof value['timestamp'] === 'number' &&\n typeof value['capturedAt'] === 'string' &&\n isDebugControlNode(value['root'])\n );\n}\n\nfunction isDebugControlNode(value: unknown): value is DebugControlNode {\n return (\n isRecord(value) &&\n typeof value['id'] === 'string' &&\n typeof value['name'] === 'string' &&\n (value['type'] === 'group' || value['type'] === 'control' || value['type'] === 'array') &&\n typeof value['path'] === 'string' &&\n typeof value['valid'] === 'boolean' &&\n typeof value['invalid'] === 'boolean' &&\n typeof value['status'] === 'string' &&\n typeof value['touched'] === 'boolean' &&\n typeof value['dirty'] === 'boolean' &&\n typeof value['disabled'] === 'boolean' &&\n Array.isArray(value['children']) &&\n value['children'].every((child) => isDebugControlNode(child))\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n","import { ControlSnapshot } from './control-snapshot';\n\nexport interface TrackedFormSnapshot {\n id: string;\n name: string;\n source: 'reactive' | 'signal';\n timestamp: number;\n capturedAt: string;\n root: ControlSnapshot;\n}\n\nexport interface CreateTrackedFormSnapshotInput {\n id: string;\n name: string;\n source: 'reactive' | 'signal';\n timestamp?: number;\n root: ControlSnapshot;\n capturedAt?: string;\n}\n\nexport function createTrackedFormSnapshot(\n input: CreateTrackedFormSnapshotInput\n): TrackedFormSnapshot {\n const timestamp = input.timestamp ?? Date.now();\n\n return {\n ...input,\n timestamp,\n capturedAt: input.capturedAt ?? new Date(timestamp).toISOString()\n };\n}\n","import { InjectionToken } from '@angular/core';\nimport {\n ApplySnapshotMessage,\n DevtoolsMessage,\n isApplySnapshotMessage,\n isRequestStateMessage\n} from './devtools-message';\n\nexport interface FormDevtoolsBridge {\n emit(message: DevtoolsMessage): void;\n onRequestState?(handler: () => void): VoidFunction;\n onApplySnapshot?(handler: (message: ApplySnapshotMessage) => void): VoidFunction;\n}\n\nexport const noopFormDevtoolsBridge: FormDevtoolsBridge = {\n emit: () => undefined,\n onRequestState: () => () => undefined,\n onApplySnapshot: () => () => undefined\n};\n\nexport const windowPostMessageFormDevtoolsBridge: FormDevtoolsBridge = {\n emit(message): void {\n if (typeof window === 'undefined') {\n return;\n }\n\n window.postMessage(message, '*');\n },\n onRequestState(handler): VoidFunction {\n if (typeof window === 'undefined') {\n return () => undefined;\n }\n\n const listener = (event: MessageEvent<unknown>) => {\n if (event.source !== window || !isRequestStateMessage(event.data)) {\n return;\n }\n\n handler();\n };\n\n window.addEventListener('message', listener);\n\n return () => {\n window.removeEventListener('message', listener);\n };\n },\n onApplySnapshot(handler): VoidFunction {\n if (typeof window === 'undefined') {\n return () => undefined;\n }\n\n const listener = (event: MessageEvent<unknown>) => {\n if (event.source !== window || !isApplySnapshotMessage(event.data)) {\n return;\n }\n\n handler(event.data);\n };\n\n window.addEventListener('message', listener);\n\n return () => {\n window.removeEventListener('message', listener);\n };\n }\n};\n\nexport const FORM_DEVTOOLS_BRIDGE = new InjectionToken<FormDevtoolsBridge>('FORM_DEVTOOLS_BRIDGE', {\n factory: () => noopFormDevtoolsBridge\n});\n","import { InjectionToken } from '@angular/core';\nimport { FormDevtoolsBridge } from './form-devtools.bridge';\n\nexport type FormDevtoolsBridgeMode = 'off' | 'window-message';\n\nexport interface FormDevtoolsOptions {\n bridge?: FormDevtoolsBridgeMode | FormDevtoolsBridge;\n}\n\nexport const FORM_DEVTOOLS_OPTIONS = new InjectionToken<FormDevtoolsOptions>(\n 'FORM_DEVTOOLS_OPTIONS',\n {\n factory: () => ({ bridge: 'off' })\n }\n);\n","import {\n AbstractControl,\n AbstractControlOptions,\n FormArray,\n FormControl,\n FormGroup,\n FormRecord\n} from '@angular/forms';\nimport { DebugControlNode } from './devtools-message';\n\nexport function applyReactiveFormSnapshot(\n control: AbstractControl,\n snapshot: DebugControlNode\n): void {\n restoreControl(control, snapshot);\n control.updateValueAndValidity({ emitEvent: false });\n}\n\nfunction restoreControl(control: AbstractControl, snapshot: DebugControlNode): void {\n if (!snapshot.disabled && control.disabled) {\n control.enable({ emitEvent: false });\n }\n\n if (control instanceof FormControl) {\n control.setValue(snapshot.value, { emitEvent: false });\n } else if (control instanceof FormArray) {\n syncFormArrayLength(control, snapshot.children);\n\n snapshot.children.forEach((childSnapshot, index) => {\n const childControl = control.at(index);\n\n if (childControl) {\n restoreControl(childControl, childSnapshot);\n }\n });\n } else if (control instanceof FormRecord || control instanceof FormGroup) {\n const childControls = control.controls as Record<string, AbstractControl>;\n\n snapshot.children.forEach((childSnapshot) => {\n const childControl = childControls[childSnapshot.name];\n\n if (childControl) {\n restoreControl(childControl, childSnapshot);\n }\n });\n }\n\n syncInteractionState(control, snapshot);\n\n if (snapshot.disabled && control.enabled) {\n control.disable({ emitEvent: false });\n }\n\n control.updateValueAndValidity({\n onlySelf: true,\n emitEvent: false\n });\n}\n\nfunction syncFormArrayLength(array: FormArray, snapshots: readonly DebugControlNode[]): void {\n while (array.length > snapshots.length) {\n array.removeAt(array.length - 1, { emitEvent: false });\n }\n\n const template = array.at(0);\n\n while (array.length < snapshots.length) {\n const snapshot = snapshots[array.length];\n array.push(createChildControl(snapshot, template), { emitEvent: false });\n }\n}\n\nfunction createChildControl(\n snapshot: DebugControlNode,\n template?: AbstractControl\n): AbstractControl {\n if (template && matchesSnapshotType(template, snapshot)) {\n return cloneControl(template);\n }\n\n return createControlFromSnapshot(snapshot);\n}\n\nfunction matchesSnapshotType(control: AbstractControl, snapshot: DebugControlNode): boolean {\n if (control instanceof FormArray) {\n return snapshot.type === 'array';\n }\n\n if (control instanceof FormRecord || control instanceof FormGroup) {\n return snapshot.type === 'group';\n }\n\n return snapshot.type === 'control';\n}\n\nfunction cloneControl(control: AbstractControl): AbstractControl {\n if (control instanceof FormControl) {\n return new FormControl(control.getRawValue(), createControlOptions(control));\n }\n\n if (control instanceof FormArray) {\n return new FormArray(\n control.controls.map((child) => cloneControl(child)),\n createControlOptions(control)\n );\n }\n\n if (control instanceof FormRecord) {\n return new FormRecord(\n cloneControlMap(control.controls as Record<string, AbstractControl>),\n createControlOptions(control)\n );\n }\n\n if (control instanceof FormGroup) {\n return new FormGroup(\n cloneControlMap(control.controls as Record<string, AbstractControl>),\n createControlOptions(control)\n );\n }\n\n return new FormControl(control.getRawValue(), createControlOptions(control));\n}\n\nfunction createControlFromSnapshot(snapshot: DebugControlNode): AbstractControl {\n if (snapshot.type === 'array') {\n return new FormArray(snapshot.children.map((child) => createControlFromSnapshot(child)));\n }\n\n if (snapshot.type === 'group') {\n return new FormGroup(\n Object.fromEntries(\n snapshot.children.map((child) => [child.name, createControlFromSnapshot(child)])\n )\n );\n }\n\n return new FormControl(snapshot.value);\n}\n\nfunction cloneControlMap(\n controls: Record<string, AbstractControl>\n): Record<string, AbstractControl> {\n return Object.fromEntries(\n Object.entries(controls).map(([name, child]) => [name, cloneControl(child)])\n );\n}\n\nfunction syncInteractionState(control: AbstractControl, snapshot: DebugControlNode): void {\n if (control instanceof FormControl) {\n if (snapshot.touched) {\n control.markAsTouched({ onlySelf: true, emitEvent: false });\n } else {\n control.markAsUntouched({ emitEvent: false });\n }\n\n if (snapshot.dirty) {\n control.markAsDirty({ onlySelf: true, emitEvent: false });\n } else {\n control.markAsPristine({ emitEvent: false });\n }\n\n return;\n }\n\n if (snapshot.touched) {\n control.markAsTouched({ onlySelf: true, emitEvent: false });\n }\n\n if (snapshot.dirty) {\n control.markAsDirty({ onlySelf: true, emitEvent: false });\n }\n}\n\nfunction createControlOptions(control: AbstractControl): AbstractControlOptions | null {\n const options: AbstractControlOptions = {};\n\n if (control.validator) {\n options.validators = control.validator;\n }\n\n if (control.asyncValidator) {\n options.asyncValidators = control.asyncValidator;\n }\n\n if (control.updateOn !== 'change') {\n options.updateOn = control.updateOn;\n }\n\n return Object.keys(options).length > 0 ? options : null;\n}\n","import { AbstractControl, FormArray, FormControl, FormGroup, FormRecord } from '@angular/forms';\nimport { ControlPathSegment, ControlSnapshot } from './control-snapshot';\nimport { TrackedFormSnapshot, createTrackedFormSnapshot } from './form-snapshot';\nimport { serializeControlPath } from './tree-utils';\n\nexport function createReactiveFormSnapshot(\n form: AbstractControl,\n formId: string,\n name: string\n): TrackedFormSnapshot {\n return createTrackedFormSnapshot({\n id: formId,\n name,\n source: 'reactive',\n root: createControlSnapshot(form, name, [])\n });\n}\n\nfunction createControlSnapshot(\n control: AbstractControl,\n name: string,\n path: readonly ControlPathSegment[]\n): ControlSnapshot {\n return {\n id: serializeControlPath(path),\n name,\n path,\n kind: resolveControlKind(control),\n value: control.getRawValue(),\n status: control.status,\n valid: control.valid,\n invalid: control.invalid,\n touched: control.touched,\n dirty: control.dirty,\n disabled: control.disabled,\n errors: control.errors as Record<string, unknown> | null,\n children: collectChildren(control, path)\n };\n}\n\nfunction collectChildren(\n control: AbstractControl,\n path: readonly ControlPathSegment[]\n): readonly ControlSnapshot[] {\n if (control instanceof FormGroup || control instanceof FormRecord) {\n return Object.entries(control.controls).map(([name, child]) =>\n createControlSnapshot(child, name, [...path, name])\n );\n }\n\n if (control instanceof FormArray) {\n return control.controls.map((child, index) =>\n createControlSnapshot(child, `[${index}]`, [...path, index])\n );\n }\n\n return [];\n}\n\nfunction resolveControlKind(control: AbstractControl): 'control' | 'group' | 'array' {\n if (control instanceof FormArray) {\n return 'array';\n }\n\n if (control instanceof FormGroup || control instanceof FormRecord) {\n return 'group';\n }\n\n if (control instanceof FormControl) {\n return 'control';\n }\n\n return 'control';\n}\n","import { ApplicationRef, DestroyRef, Injectable, inject } from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\nimport { Observable, ReplaySubject, Subscription, merge } from 'rxjs';\nimport {\n ApplySnapshotMessage,\n createFormRegisteredMessage,\n createFormRemovedMessage,\n createFormSnapshotMessage\n} from './devtools-message';\nimport { TrackedFormSnapshot } from './form-snapshot';\nimport { applyReactiveFormSnapshot } from './apply-reactive-form-snapshot';\nimport { FORM_DEVTOOLS_BRIDGE } from './form-devtools.bridge';\nimport { createReactiveFormSnapshot } from './reactive-forms-snapshot';\n\nexport interface TrackFormOptions {\n name?: string;\n destroyRef?: DestroyRef;\n}\n\ninterface TrackedEntry {\n id: string;\n name: string;\n form: AbstractControl;\n refs: number;\n stream: ReplaySubject<TrackedFormSnapshot>;\n subscription: Subscription;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class FormDevtools {\n private readonly applicationRef = inject(ApplicationRef);\n private readonly bridge = inject(FORM_DEVTOOLS_BRIDGE);\n private readonly destroyRef = inject(DestroyRef);\n private readonly entriesByControl = new WeakMap<AbstractControl, TrackedEntry>();\n private readonly entriesById = new Map<string, TrackedEntry>();\n private nextFormId = 0;\n private domRefreshScheduled = false;\n\n constructor() {\n const stopRequestState = this.bridge.onRequestState?.(() => this.emitAllSnapshots());\n const stopApplySnapshot = this.bridge.onApplySnapshot?.((message) =>\n this.applySnapshot(message)\n );\n\n if (stopRequestState) {\n this.destroyRef.onDestroy(stopRequestState);\n }\n\n if (stopApplySnapshot) {\n this.destroyRef.onDestroy(stopApplySnapshot);\n }\n }\n\n track(form: AbstractControl, options: TrackFormOptions = {}): VoidFunction {\n const name = options.name ?? 'form';\n const entry = this.ensureEntry(form, name);\n\n entry.refs += 1;\n let stopped = false;\n\n const stop = () => {\n if (stopped) {\n return;\n }\n\n stopped = true;\n\n const current = this.entriesByControl.get(form);\n\n if (!current) {\n return;\n }\n\n current.refs -= 1;\n\n if (current.refs <= 0) {\n current.subscription.unsubscribe();\n current.stream.complete();\n this.entriesByControl.delete(form);\n this.entriesById.delete(current.id);\n this.bridge.emit(createFormRemovedMessage(current.id));\n }\n };\n\n options.destroyRef?.onDestroy(stop);\n\n return stop;\n }\n\n snapshot$(form: AbstractControl): Observable<TrackedFormSnapshot> {\n const entry = this.entriesByControl.get(form);\n\n if (!entry) {\n throw new Error(\n 'FormDevtools.snapshot$ was called before the form was tracked. Call track() first.'\n );\n }\n\n return entry.stream;\n }\n\n private ensureEntry(form: AbstractControl, name: string): TrackedEntry {\n const existing = this.entriesByControl.get(form);\n\n if (existing) {\n if (existing.name !== name) {\n existing.name = name;\n this.pushSnapshot(form, existing);\n }\n\n return existing;\n }\n\n const stream = new ReplaySubject<TrackedFormSnapshot>(1);\n const entry: TrackedEntry = {\n id: this.createFormId(),\n name,\n form,\n refs: 0,\n stream,\n subscription: Subscription.EMPTY\n };\n\n this.entriesByControl.set(form, entry);\n this.entriesById.set(entry.id, entry);\n const initialSnapshot = this.createSnapshot(form, entry);\n stream.next(initialSnapshot);\n this.bridge.emit(createFormRegisteredMessage(initialSnapshot));\n this.bridge.emit(createFormSnapshotMessage(initialSnapshot));\n entry.subscription = merge(form.valueChanges, form.statusChanges).subscribe(() =>\n this.pushSnapshot(form, entry)\n );\n\n return entry;\n }\n\n private pushSnapshot(form: AbstractControl, entry: TrackedEntry): void {\n const snapshot = this.createSnapshot(form, entry);\n entry.stream.next(snapshot);\n this.bridge.emit(createFormSnapshotMessage(snapshot));\n }\n\n private createSnapshot(form: AbstractControl, entry: TrackedEntry): TrackedFormSnapshot {\n return createReactiveFormSnapshot(form, entry.id, entry.name);\n }\n\n private createFormId(): string {\n this.nextFormId += 1;\n\n return `ng-form-${this.nextFormId}`;\n }\n\n private emitAllSnapshots(): void {\n for (const entry of this.entriesById.values()) {\n const snapshot = this.createSnapshot(entry.form, entry);\n entry.stream.next(snapshot);\n this.bridge.emit(createFormRegisteredMessage(snapshot));\n this.bridge.emit(createFormSnapshotMessage(snapshot));\n }\n }\n\n private applySnapshot(message: ApplySnapshotMessage): void {\n const entry = this.entriesById.get(message.payload.formId);\n\n if (!entry || message.payload.source !== 'reactive') {\n return;\n }\n\n applyReactiveFormSnapshot(entry.form, message.payload.root);\n this.scheduleDomRefresh();\n }\n\n private scheduleDomRefresh(): void {\n if (this.domRefreshScheduled) {\n return;\n }\n\n this.domRefreshScheduled = true;\n\n queueMicrotask(() => {\n this.domRefreshScheduled = false;\n this.applicationRef.tick();\n });\n }\n}\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport {\n FORM_DEVTOOLS_BRIDGE,\n FormDevtoolsBridge,\n noopFormDevtoolsBridge,\n windowPostMessageFormDevtoolsBridge\n} from './form-devtools.bridge';\nimport { FORM_DEVTOOLS_OPTIONS, FormDevtoolsOptions } from './form-devtools.options';\n\nexport function provideFormDevtools(options: FormDevtoolsOptions = {}): EnvironmentProviders {\n const bridge = resolveBridge(options.bridge);\n\n return makeEnvironmentProviders([\n {\n provide: FORM_DEVTOOLS_OPTIONS,\n useValue: {\n bridge: 'off',\n ...options\n }\n },\n {\n provide: FORM_DEVTOOLS_BRIDGE,\n useValue: bridge\n }\n ]);\n}\n\nfunction resolveBridge(bridge: FormDevtoolsOptions['bridge']): FormDevtoolsBridge {\n if (bridge === undefined || bridge === 'off') {\n return noopFormDevtoolsBridge;\n }\n\n if (bridge === 'window-message') {\n return windowPostMessageFormDevtoolsBridge;\n }\n\n return bridge;\n}\n","import { DestroyRef, assertInInjectionContext, inject } from '@angular/core';\nimport { AbstractControl } from '@angular/forms';\nimport { FormDevtools } from './form-devtools.service';\n\nexport function track(form: AbstractControl, name?: string): VoidFunction {\n assertInInjectionContext(track);\n\n return inject(FormDevtools).track(form, {\n name,\n destroyRef: inject(DestroyRef)\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export * from './lib/control-snapshot';
2
+ export * from './lib/devtools-message';
3
+ export * from './lib/form-snapshot';
4
+ export * from './lib/tree-utils';
5
+ export * from './lib/form-devtools.bridge';
6
+ export * from './lib/form-devtools.options';
7
+ export * from './lib/form-devtools.service';
8
+ export * from './lib/provide-form-devtools';
9
+ export * from './lib/track';
@@ -0,0 +1,3 @@
1
+ import { AbstractControl } from '@angular/forms';
2
+ import { DebugControlNode } from './devtools-message';
3
+ export declare function applyReactiveFormSnapshot(control: AbstractControl, snapshot: DebugControlNode): void;
@@ -16,4 +16,3 @@ export interface ControlSnapshot {
16
16
  errors: Record<string, unknown> | null;
17
17
  children: readonly ControlSnapshot[];
18
18
  }
19
- //# sourceMappingURL=control-snapshot.d.ts.map
@@ -68,4 +68,3 @@ export declare function createApplySnapshotMessage(snapshot: DebugFormSnapshot):
68
68
  export declare function isRequestStateMessage(value: unknown): value is RequestStateMessage;
69
69
  export declare function isApplySnapshotMessage(value: unknown): value is ApplySnapshotMessage;
70
70
  export declare function isDebugFormSnapshot(value: unknown): value is DebugFormSnapshot;
71
- //# sourceMappingURL=devtools-message.d.ts.map
@@ -0,0 +1,10 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ import { ApplySnapshotMessage, DevtoolsMessage } from './devtools-message';
3
+ export interface FormDevtoolsBridge {
4
+ emit(message: DevtoolsMessage): void;
5
+ onRequestState?(handler: () => void): VoidFunction;
6
+ onApplySnapshot?(handler: (message: ApplySnapshotMessage) => void): VoidFunction;
7
+ }
8
+ export declare const noopFormDevtoolsBridge: FormDevtoolsBridge;
9
+ export declare const windowPostMessageFormDevtoolsBridge: FormDevtoolsBridge;
10
+ export declare const FORM_DEVTOOLS_BRIDGE: InjectionToken<FormDevtoolsBridge>;
@@ -0,0 +1,7 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ import { FormDevtoolsBridge } from './form-devtools.bridge';
3
+ export type FormDevtoolsBridgeMode = 'off' | 'window-message';
4
+ export interface FormDevtoolsOptions {
5
+ bridge?: FormDevtoolsBridgeMode | FormDevtoolsBridge;
6
+ }
7
+ export declare const FORM_DEVTOOLS_OPTIONS: InjectionToken<FormDevtoolsOptions>;
@@ -0,0 +1,30 @@
1
+ import { DestroyRef } from '@angular/core';
2
+ import { AbstractControl } from '@angular/forms';
3
+ import { Observable } from 'rxjs';
4
+ import { TrackedFormSnapshot } from './form-snapshot';
5
+ import * as i0 from "@angular/core";
6
+ export interface TrackFormOptions {
7
+ name?: string;
8
+ destroyRef?: DestroyRef;
9
+ }
10
+ export declare class FormDevtools {
11
+ private readonly applicationRef;
12
+ private readonly bridge;
13
+ private readonly destroyRef;
14
+ private readonly entriesByControl;
15
+ private readonly entriesById;
16
+ private nextFormId;
17
+ private domRefreshScheduled;
18
+ constructor();
19
+ track(form: AbstractControl, options?: TrackFormOptions): VoidFunction;
20
+ snapshot$(form: AbstractControl): Observable<TrackedFormSnapshot>;
21
+ private ensureEntry;
22
+ private pushSnapshot;
23
+ private createSnapshot;
24
+ private createFormId;
25
+ private emitAllSnapshots;
26
+ private applySnapshot;
27
+ private scheduleDomRefresh;
28
+ static ɵfac: i0.ɵɵFactoryDeclaration<FormDevtools, never>;
29
+ static ɵprov: i0.ɵɵInjectableDeclaration<FormDevtools>;
30
+ }
@@ -16,4 +16,3 @@ export interface CreateTrackedFormSnapshotInput {
16
16
  capturedAt?: string;
17
17
  }
18
18
  export declare function createTrackedFormSnapshot(input: CreateTrackedFormSnapshotInput): TrackedFormSnapshot;
19
- //# sourceMappingURL=form-snapshot.d.ts.map
@@ -0,0 +1,3 @@
1
+ import { EnvironmentProviders } from '@angular/core';
2
+ import { FormDevtoolsOptions } from './form-devtools.options';
3
+ export declare function provideFormDevtools(options?: FormDevtoolsOptions): EnvironmentProviders;
@@ -0,0 +1,3 @@
1
+ import { AbstractControl } from '@angular/forms';
2
+ import { TrackedFormSnapshot } from './form-snapshot';
3
+ export declare function createReactiveFormSnapshot(form: AbstractControl, formId: string, name: string): TrackedFormSnapshot;
package/lib/track.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { AbstractControl } from '@angular/forms';
2
+ export declare function track(form: AbstractControl, name?: string): VoidFunction;
@@ -1,4 +1,3 @@
1
1
  import { ControlPathSegment, ControlSnapshot } from './control-snapshot';
2
2
  export declare function serializeControlPath(path: readonly ControlPathSegment[]): string;
3
3
  export declare function walkControlTree(root: ControlSnapshot, visitor: (control: ControlSnapshot) => void): void;
4
- //# sourceMappingURL=tree-utils.d.ts.map
package/package.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "name": "ng-form-devtools",
3
- "version": "0.1.0",
4
- "description": "Framework-agnostic debug model for ng-form-devtools",
5
- "type": "module",
3
+ "version": "0.1.2",
4
+ "description": "Angular form devtools with runtime tracking, snapshot contracts, and Chrome DevTools integration",
6
5
  "license": "MIT",
7
6
  "repository": {
8
7
  "type": "git",
@@ -13,24 +12,27 @@
13
12
  "url": "https://github.com/timtilch/ng-form-devtools/issues"
14
13
  },
15
14
  "sideEffects": false,
16
- "main": "./dist/index.js",
17
- "types": "./dist/index.d.ts",
18
- "exports": {
19
- ".": {
20
- "types": "./dist/index.d.ts",
21
- "default": "./dist/index.js"
22
- }
15
+ "dependencies": {
16
+ "tslib": "^2.8.1"
17
+ },
18
+ "peerDependencies": {
19
+ "@angular/common": "^19.2.0",
20
+ "@angular/core": "^19.2.0",
21
+ "@angular/forms": "^19.2.0",
22
+ "rxjs": "^7.8.0"
23
23
  },
24
24
  "publishConfig": {
25
25
  "access": "public"
26
26
  },
27
- "files": [
28
- "dist"
29
- ],
30
- "scripts": {
31
- "build": "tsc -p tsconfig.build.json",
32
- "prepublishOnly": "npm run build",
33
- "typecheck": "tsc --noEmit -p tsconfig.json",
34
- "test": "vitest run"
27
+ "module": "fesm2022/ng-form-devtools.mjs",
28
+ "typings": "index.d.ts",
29
+ "exports": {
30
+ "./package.json": {
31
+ "default": "./package.json"
32
+ },
33
+ ".": {
34
+ "types": "./index.d.ts",
35
+ "default": "./fesm2022/ng-form-devtools.mjs"
36
+ }
35
37
  }
36
- }
38
+ }
package/dist/index.d.ts DELETED
@@ -1,5 +0,0 @@
1
- export * from './lib/control-snapshot';
2
- export * from './lib/devtools-message';
3
- export * from './lib/form-snapshot';
4
- export * from './lib/tree-utils';
5
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC"}
package/dist/index.js DELETED
@@ -1,5 +0,0 @@
1
- export * from './lib/control-snapshot';
2
- export * from './lib/devtools-message';
3
- export * from './lib/form-snapshot';
4
- export * from './lib/tree-utils';
5
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"control-snapshot.d.ts","sourceRoot":"","sources":["../../src/lib/control-snapshot.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAExD,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjD,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAEzE,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACpC,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACvC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;CACtC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=control-snapshot.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"control-snapshot.js","sourceRoot":"","sources":["../../src/lib/control-snapshot.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"devtools-message.d.ts","sourceRoot":"","sources":["../../src/lib/devtools-message.ts"],"names":[],"mappings":"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"}
@@ -1,118 +0,0 @@
1
- import { serializeControlPath } from './tree-utils';
2
- export const NG_FORM_DEVTOOLS_SOURCE = 'NG_FORM_DEVTOOLS';
3
- export const NG_FORM_DEVTOOLS_EXTENSION_SOURCE = 'NG_FORM_DEVTOOLS_EXTENSION';
4
- export function toDebugControlNode(control) {
5
- return {
6
- id: control.id,
7
- name: control.name,
8
- type: control.kind,
9
- path: serializeControlPath(control.path),
10
- value: control.value,
11
- valid: control.valid,
12
- invalid: control.invalid,
13
- status: control.status,
14
- touched: control.touched,
15
- dirty: control.dirty,
16
- disabled: control.disabled,
17
- errors: control.errors,
18
- children: control.children.map((child) => toDebugControlNode(child))
19
- };
20
- }
21
- export function toDebugFormSnapshot(snapshot) {
22
- return {
23
- formId: snapshot.id,
24
- formName: snapshot.name,
25
- source: snapshot.source,
26
- timestamp: snapshot.timestamp,
27
- capturedAt: snapshot.capturedAt,
28
- root: toDebugControlNode(snapshot.root)
29
- };
30
- }
31
- export function createFormRegisteredMessage(snapshot) {
32
- return {
33
- source: NG_FORM_DEVTOOLS_SOURCE,
34
- type: 'FORM_REGISTERED',
35
- payload: {
36
- formId: snapshot.id,
37
- formName: snapshot.name,
38
- source: snapshot.source
39
- }
40
- };
41
- }
42
- export function createFormSnapshotMessage(snapshot) {
43
- return {
44
- source: NG_FORM_DEVTOOLS_SOURCE,
45
- type: 'FORM_SNAPSHOT',
46
- payload: toDebugFormSnapshot(snapshot)
47
- };
48
- }
49
- export function createFormRemovedMessage(formId) {
50
- return {
51
- source: NG_FORM_DEVTOOLS_SOURCE,
52
- type: 'FORM_REMOVED',
53
- payload: {
54
- formId
55
- }
56
- };
57
- }
58
- export function isDevtoolsMessage(value) {
59
- if (!isRecord(value)) {
60
- return false;
61
- }
62
- return (value['source'] === NG_FORM_DEVTOOLS_SOURCE &&
63
- (value['type'] === 'FORM_REGISTERED' ||
64
- value['type'] === 'FORM_SNAPSHOT' ||
65
- value['type'] === 'FORM_REMOVED'));
66
- }
67
- export function createRequestStateMessage() {
68
- return {
69
- source: NG_FORM_DEVTOOLS_EXTENSION_SOURCE,
70
- type: 'REQUEST_STATE'
71
- };
72
- }
73
- export function createApplySnapshotMessage(snapshot) {
74
- return {
75
- source: NG_FORM_DEVTOOLS_EXTENSION_SOURCE,
76
- type: 'APPLY_SNAPSHOT',
77
- payload: snapshot
78
- };
79
- }
80
- export function isRequestStateMessage(value) {
81
- return (isRecord(value) &&
82
- value['source'] === NG_FORM_DEVTOOLS_EXTENSION_SOURCE &&
83
- value['type'] === 'REQUEST_STATE');
84
- }
85
- export function isApplySnapshotMessage(value) {
86
- return (isRecord(value) &&
87
- value['source'] === NG_FORM_DEVTOOLS_EXTENSION_SOURCE &&
88
- value['type'] === 'APPLY_SNAPSHOT' &&
89
- isDebugFormSnapshot(value['payload']));
90
- }
91
- export function isDebugFormSnapshot(value) {
92
- return (isRecord(value) &&
93
- typeof value['formId'] === 'string' &&
94
- typeof value['formName'] === 'string' &&
95
- (value['source'] === 'reactive' || value['source'] === 'signal') &&
96
- typeof value['timestamp'] === 'number' &&
97
- typeof value['capturedAt'] === 'string' &&
98
- isDebugControlNode(value['root']));
99
- }
100
- function isDebugControlNode(value) {
101
- return (isRecord(value) &&
102
- typeof value['id'] === 'string' &&
103
- typeof value['name'] === 'string' &&
104
- (value['type'] === 'group' || value['type'] === 'control' || value['type'] === 'array') &&
105
- typeof value['path'] === 'string' &&
106
- typeof value['valid'] === 'boolean' &&
107
- typeof value['invalid'] === 'boolean' &&
108
- typeof value['status'] === 'string' &&
109
- typeof value['touched'] === 'boolean' &&
110
- typeof value['dirty'] === 'boolean' &&
111
- typeof value['disabled'] === 'boolean' &&
112
- Array.isArray(value['children']) &&
113
- value['children'].every((child) => isDebugControlNode(child)));
114
- }
115
- function isRecord(value) {
116
- return typeof value === 'object' && value !== null;
117
- }
118
- //# sourceMappingURL=devtools-message.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"devtools-message.js","sourceRoot":"","sources":["../../src/lib/devtools-message.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"form-snapshot.d.ts","sourceRoot":"","sources":["../../src/lib/form-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,WAAW,8BAA8B;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,eAAe,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,8BAA8B,GACpC,mBAAmB,CAQrB"}
@@ -1,9 +0,0 @@
1
- export function createTrackedFormSnapshot(input) {
2
- const timestamp = input.timestamp ?? Date.now();
3
- return {
4
- ...input,
5
- timestamp,
6
- capturedAt: input.capturedAt ?? new Date(timestamp).toISOString()
7
- };
8
- }
9
- //# sourceMappingURL=form-snapshot.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"form-snapshot.js","sourceRoot":"","sources":["../../src/lib/form-snapshot.ts"],"names":[],"mappings":"AAoBA,MAAM,UAAU,yBAAyB,CACvC,KAAqC;IAErC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IAEhD,OAAO;QACL,GAAG,KAAK;QACR,SAAS;QACT,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;KAClE,CAAC;AACJ,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tree-utils.d.ts","sourceRoot":"","sources":["../../src/lib/tree-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAEzE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,kBAAkB,EAAE,GAAG,MAAM,CAMhF;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,GAC1C,IAAI,CAMN"}
@@ -1,13 +0,0 @@
1
- export function serializeControlPath(path) {
2
- if (path.length === 0) {
3
- return 'root';
4
- }
5
- return path.map((segment) => (typeof segment === 'number' ? `[${segment}]` : segment)).join('.');
6
- }
7
- export function walkControlTree(root, visitor) {
8
- visitor(root);
9
- for (const child of root.children) {
10
- walkControlTree(child, visitor);
11
- }
12
- }
13
- //# sourceMappingURL=tree-utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tree-utils.js","sourceRoot":"","sources":["../../src/lib/tree-utils.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,oBAAoB,CAAC,IAAmC;IACtE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACnG,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,IAAqB,EACrB,OAA2C;IAE3C,OAAO,CAAC,IAAI,CAAC,CAAC;IAEd,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClC,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;AACH,CAAC"}