@constantant/openapi-resource-mocks 0.2.0 → 0.4.0
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 +36 -0
- package/README.md +23 -3
- package/package.json +1 -1
- package/src/index.d.ts +1 -0
- package/src/index.js.map +1 -1
- package/src/lib/mock-events.d.ts +5 -0
- package/src/lib/mock-resource-bus.d.ts +13 -1
- package/src/lib/mock-resource-bus.js +74 -4
- package/src/lib/mock-resource-bus.js.map +1 -1
- package/src/lib/mock-resource-meta.d.ts +8 -0
- package/src/lib/mock-resource-meta.js +3 -0
- package/src/lib/mock-resource-meta.js.map +1 -0
- package/src/lib/provide-mock-resource.d.ts +2 -1
- package/src/lib/provide-mock-resource.js +53 -24
- package/src/lib/provide-mock-resource.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,39 @@
|
|
|
1
|
+
## 0.4.0 (2026-06-13)
|
|
2
|
+
|
|
3
|
+
### 🩹 Fixes
|
|
4
|
+
|
|
5
|
+
- **openapi-resource-mocks:** sanitize FormData/File/Blob args before DOM dispatch ([7609660](https://github.com/constantant/angular-openapi-gen/commit/7609660))
|
|
6
|
+
|
|
7
|
+
### 📖 Documentation
|
|
8
|
+
|
|
9
|
+
- fix badge coverage and stale version numbers ([290ea7f](https://github.com/constantant/angular-openapi-gen/commit/290ea7f))
|
|
10
|
+
|
|
11
|
+
### ❤️ Thank You
|
|
12
|
+
|
|
13
|
+
- Claude Sonnet 4.6
|
|
14
|
+
- kk
|
|
15
|
+
|
|
16
|
+
## 0.3.0 (2026-06-10)
|
|
17
|
+
|
|
18
|
+
### 🚀 Features
|
|
19
|
+
|
|
20
|
+
- **mocks:** phase 1 spec-aware mocks — MockResourceMeta through the stack ([e3a9520](https://github.com/constantant/angular-openapi-gen/commit/e3a9520))
|
|
21
|
+
- **openapi-resource-mocks:** persistent catch-mode watch list and timing fixes ([1d63b36](https://github.com/constantant/angular-openapi-gen/commit/1d63b36))
|
|
22
|
+
- **devtools-panel:** add history tab, catch mode, and CSS token migration ([d4151bc](https://github.com/constantant/angular-openapi-gen/commit/d4151bc))
|
|
23
|
+
|
|
24
|
+
### 🩹 Fixes
|
|
25
|
+
|
|
26
|
+
- **openapi-resource-mocks:** re-fire _notifyRequest when reactive thunk args change ([708a71e](https://github.com/constantant/angular-openapi-gen/commit/708a71e))
|
|
27
|
+
|
|
28
|
+
### 📖 Documentation
|
|
29
|
+
|
|
30
|
+
- align all docs with spec-aware mocks (phases 2-4) ([e7c4374](https://github.com/constantant/angular-openapi-gen/commit/e7c4374))
|
|
31
|
+
|
|
32
|
+
### ❤️ Thank You
|
|
33
|
+
|
|
34
|
+
- Claude Sonnet 4.6
|
|
35
|
+
- kk
|
|
36
|
+
|
|
1
37
|
## 0.2.0 (2026-06-09)
|
|
2
38
|
|
|
3
39
|
### 🚀 Features
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @constantant/openapi-resource-mocks
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@constantant/openapi-resource-mocks)
|
|
4
|
+
|
|
3
5
|
Mock bus for [`@constantant/openapi-resource-gen`](https://www.npmjs.com/package/@constantant/openapi-resource-gen) tokens.
|
|
4
6
|
|
|
5
7
|
Provides zero-HTTP, pure-DI mocks for Angular `InjectionToken`-based data-access libs — with a cross-boundary API so **Playwright E2E tests** and a future **Chrome Extension devtools panel** can observe and control every token's state from outside the Angular context.
|
|
@@ -21,8 +23,8 @@ Peer dependencies: `@angular/core >=22`, `@angular/common >=22`.
|
|
|
21
23
|
Each mock token is registered in a `MockResourceBus`. The bus:
|
|
22
24
|
|
|
23
25
|
- Exposes `window.__openApiMocks__` — a plain object keyed by token name, accessible from Playwright's `page.evaluate()` or a Chrome Extension content script.
|
|
24
|
-
- Emits DOM events (`openapi-mock-event`) on every state change so the
|
|
25
|
-
- Listens for DOM events (`openapi-mock-control`) so the
|
|
26
|
+
- Emits DOM events (`openapi-mock-event`) on every state change so the Chrome Extension DevTools panel can observe in real time.
|
|
27
|
+
- Listens for DOM events (`openapi-mock-control`) so the DevTools panel can push data into the app.
|
|
26
28
|
|
|
27
29
|
---
|
|
28
30
|
|
|
@@ -347,10 +349,12 @@ document.addEventListener('openapi-mock-event', (e) => {
|
|
|
347
349
|
|
|
348
350
|
Returns `EnvironmentProviders`. Call once in your root providers or TestBed setup.
|
|
349
351
|
|
|
350
|
-
### `provideMockResource(token, key, initialBehavior?)`
|
|
352
|
+
### `provideMockResource(token, key, initialBehavior?, meta?)`
|
|
351
353
|
|
|
352
354
|
Returns `FactoryProvider`. Each time a component invokes the factory function, a fresh ref is created, registered in the bus under `key`, and `initialBehavior` is applied — simulating the full request lifecycle on every mount.
|
|
353
355
|
|
|
356
|
+
The optional `meta` argument is a `MockResourceMeta` object. When provided, the DevTools panel uses it to look up response schemas and pre-populate the Respond tab's schema display. Generated `.mock.ts` files embed this automatically — you only need to pass it manually when using `provideMockResource()` directly.
|
|
357
|
+
|
|
354
358
|
`initialBehavior` controls how the mock behaves on each invocation:
|
|
355
359
|
|
|
356
360
|
| Shape | Effect |
|
|
@@ -377,6 +381,22 @@ Union type accepted by `provideMockResource()` and generated `provide{Operation}
|
|
|
377
381
|
| `{ error: unknown }` | Fails immediately |
|
|
378
382
|
| `{ error: unknown, delay: ms }` | Loading for `ms` ms, then fails |
|
|
379
383
|
|
|
384
|
+
### `MockResourceMeta`
|
|
385
|
+
|
|
386
|
+
Metadata embedded in generated `.mock.ts` files and read by the DevTools panel to show response schemas, generate example payloads, and validate responses:
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
interface MockResourceMeta {
|
|
390
|
+
specId: string; // matches the --specId generator option (default: derived from baseUrlToken)
|
|
391
|
+
operationId: string; // OpenAPI operationId
|
|
392
|
+
path: string; // API path, e.g. '/pet/findByStatus'
|
|
393
|
+
method: string; // HTTP method, lowercase
|
|
394
|
+
tag?: string; // OpenAPI tag (omitted for untagged operations)
|
|
395
|
+
}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
The DevTools panel resolves the response schema by looking up `specId` in its Specs store and then matching `operationId`. Import the spec (or its `mocks.manifest.json`) in the panel's **Specs** tab to enable schema-aware features.
|
|
399
|
+
|
|
380
400
|
### `DeepPartial<T>`
|
|
381
401
|
|
|
382
402
|
Recursively marks all properties of `T` as optional. Used as the value type in `ProviderInitialBehavior<T>` so you can provide partial seed data without satisfying every nested field.
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export { MockResourceBus, provideMockResourceBus } from './lib/mock-resource-bus
|
|
|
4
4
|
export type { WindowMockEntry } from './lib/mock-resource-bus';
|
|
5
5
|
export { provideMockResource } from './lib/provide-mock-resource';
|
|
6
6
|
export type { ProviderInitialBehavior, DeepPartial } from './lib/provide-mock-resource';
|
|
7
|
+
export type { MockResourceMeta } from './lib/mock-resource-meta';
|
|
7
8
|
export { injectMockResource } from './lib/inject-mock-resource';
|
|
8
9
|
export type { MockEvent, MockProgress } from './lib/mock-events';
|
|
9
10
|
export type { TokenValue } from './lib/token-value';
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../tools/openapi-resource-mocks/src/index.ts"],"names":[],"mappings":";;;AAAA,6DAAgE;AAAvD,0HAAA,qBAAqB,OAAA;AAE9B,6DAAkF;AAAzE,oHAAA,eAAe,OAAA;AAAE,2HAAA,sBAAsB,OAAA;AAEhD,qEAAkE;AAAzD,4HAAA,mBAAmB,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../tools/openapi-resource-mocks/src/index.ts"],"names":[],"mappings":";;;AAAA,6DAAgE;AAAvD,0HAAA,qBAAqB,OAAA;AAE9B,6DAAkF;AAAzE,oHAAA,eAAe,OAAA;AAAE,2HAAA,sBAAsB,OAAA;AAEhD,qEAAkE;AAAzD,4HAAA,mBAAmB,OAAA;AAG5B,mEAAgE;AAAvD,0HAAA,kBAAkB,OAAA"}
|
package/src/lib/mock-events.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EnvironmentProviders } from '@angular/core';
|
|
2
2
|
import type { MockResourceRef } from './mock-resource-ref';
|
|
3
3
|
import type { MockEvent } from './mock-events';
|
|
4
|
+
import type { MockResourceMeta } from './mock-resource-meta';
|
|
4
5
|
export interface WindowMockEntry {
|
|
5
6
|
resolve(value: unknown): void;
|
|
6
7
|
resolveAfter(delayMs: number, value: unknown): void;
|
|
@@ -9,12 +10,14 @@ export interface WindowMockEntry {
|
|
|
9
10
|
reset(): void;
|
|
10
11
|
setProgress(type: 'upload' | 'download', loaded: number, total?: number): void;
|
|
11
12
|
simulateProgress(type: 'upload' | 'download', totalBytes: number, durationMs: number, finalValue: unknown, steps?: number): void;
|
|
13
|
+
setCatchMode(enabled: boolean): void;
|
|
12
14
|
getState(): {
|
|
13
15
|
status: string;
|
|
14
16
|
value: unknown;
|
|
15
17
|
error: unknown;
|
|
16
18
|
progress: unknown;
|
|
17
19
|
};
|
|
20
|
+
getMeta(): MockResourceMeta | undefined;
|
|
18
21
|
getHistory(): MockEvent[];
|
|
19
22
|
onEvent(cb: (event: MockEvent) => void): () => void;
|
|
20
23
|
}
|
|
@@ -26,9 +29,18 @@ declare global {
|
|
|
26
29
|
}
|
|
27
30
|
export declare class MockResourceBus {
|
|
28
31
|
private readonly refs;
|
|
29
|
-
|
|
32
|
+
private readonly metas;
|
|
33
|
+
private readonly catchModeKeys;
|
|
34
|
+
private _reqCount;
|
|
35
|
+
register<T>(key: string, ref: MockResourceRef<T>, meta?: MockResourceMeta): void;
|
|
30
36
|
get<T>(key: string): MockResourceRef<T> | undefined;
|
|
37
|
+
getMeta(key: string): MockResourceMeta | undefined;
|
|
38
|
+
isCatchMode(key: string): boolean;
|
|
39
|
+
setCatchMode(key: string, enabled: boolean): void;
|
|
40
|
+
private nextReqId;
|
|
31
41
|
private exposeToWindow;
|
|
42
|
+
private sanitizeArg;
|
|
43
|
+
private sanitizeEventForDom;
|
|
32
44
|
private dispatchDomEvent;
|
|
33
45
|
constructor();
|
|
34
46
|
}
|
|
@@ -5,14 +5,43 @@ exports.provideMockResourceBus = provideMockResourceBus;
|
|
|
5
5
|
const core_1 = require("@angular/core");
|
|
6
6
|
class MockResourceBus {
|
|
7
7
|
refs = new Map();
|
|
8
|
-
|
|
8
|
+
metas = new Map();
|
|
9
|
+
catchModeKeys = new Set();
|
|
10
|
+
_reqCount = 0;
|
|
11
|
+
register(key, ref, meta) {
|
|
9
12
|
const internal = ref;
|
|
10
13
|
this.refs.set(key, internal);
|
|
14
|
+
if (meta)
|
|
15
|
+
this.metas.set(key, meta);
|
|
11
16
|
this.exposeToWindow(key, internal);
|
|
12
17
|
}
|
|
13
18
|
get(key) {
|
|
14
19
|
return this.refs.get(key);
|
|
15
20
|
}
|
|
21
|
+
getMeta(key) {
|
|
22
|
+
return this.metas.get(key);
|
|
23
|
+
}
|
|
24
|
+
isCatchMode(key) {
|
|
25
|
+
return this.catchModeKeys.has(key);
|
|
26
|
+
}
|
|
27
|
+
setCatchMode(key, enabled) {
|
|
28
|
+
if (enabled) {
|
|
29
|
+
if (this.catchModeKeys.has(key))
|
|
30
|
+
return; // idempotent — avoids duplicate caught events
|
|
31
|
+
this.catchModeKeys.add(key);
|
|
32
|
+
const ref = this.refs.get(key);
|
|
33
|
+
if (ref) {
|
|
34
|
+
ref.setLoading();
|
|
35
|
+
this.dispatchDomEvent(key, { type: 'caught', args: [], requestId: this.nextReqId(), ts: Date.now() });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.catchModeKeys.delete(key);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
nextReqId() {
|
|
43
|
+
return `req-${++this._reqCount}`;
|
|
44
|
+
}
|
|
16
45
|
exposeToWindow(key, ref) {
|
|
17
46
|
window.__openApiMocks__ ??= {};
|
|
18
47
|
window.openApiMock ??= (k) => window.__openApiMocks__[k];
|
|
@@ -23,7 +52,13 @@ class MockResourceBus {
|
|
|
23
52
|
listeners.forEach((cb) => cb(e));
|
|
24
53
|
this.dispatchDomEvent(key, e);
|
|
25
54
|
};
|
|
26
|
-
ref.onRequest((args) =>
|
|
55
|
+
ref.onRequest((args) => {
|
|
56
|
+
emit({ type: 'request', args, ts: Date.now() });
|
|
57
|
+
if (this.catchModeKeys.has(key)) {
|
|
58
|
+
ref.setLoading();
|
|
59
|
+
emit({ type: 'caught', args, requestId: this.nextReqId(), ts: Date.now() });
|
|
60
|
+
}
|
|
61
|
+
});
|
|
27
62
|
window.__openApiMocks__[key] = {
|
|
28
63
|
resolve: (v) => { ref.resolve(v); emit({ type: 'resolve', value: v, ts: Date.now() }); },
|
|
29
64
|
resolveAfter: (ms, v) => { ref.resolveAfter(ms, v); },
|
|
@@ -37,6 +72,8 @@ class MockResourceBus {
|
|
|
37
72
|
simulateProgress: (pt, total, dur, v, steps) => {
|
|
38
73
|
ref.simulateProgress(pt, total, dur, v, steps);
|
|
39
74
|
},
|
|
75
|
+
setCatchMode: (enabled) => this.setCatchMode(key, enabled),
|
|
76
|
+
getMeta: () => this.getMeta(key),
|
|
40
77
|
getState: () => ({
|
|
41
78
|
status: String(ref.status()),
|
|
42
79
|
value: ref.value(),
|
|
@@ -47,10 +84,27 @@ class MockResourceBus {
|
|
|
47
84
|
onEvent: (cb) => { listeners.add(cb); return () => listeners.delete(cb); },
|
|
48
85
|
};
|
|
49
86
|
}
|
|
87
|
+
sanitizeArg(arg) {
|
|
88
|
+
if (typeof FormData !== 'undefined' && arg instanceof FormData)
|
|
89
|
+
return '[FormData]';
|
|
90
|
+
if (typeof File !== 'undefined' && arg instanceof File)
|
|
91
|
+
return `[File: ${arg.name}]`;
|
|
92
|
+
if (typeof Blob !== 'undefined' && arg instanceof Blob)
|
|
93
|
+
return '[Blob]';
|
|
94
|
+
if (typeof ArrayBuffer !== 'undefined' && arg instanceof ArrayBuffer)
|
|
95
|
+
return '[ArrayBuffer]';
|
|
96
|
+
return arg;
|
|
97
|
+
}
|
|
98
|
+
sanitizeEventForDom(event) {
|
|
99
|
+
if (event.type === 'request' || event.type === 'caught') {
|
|
100
|
+
return { ...event, args: event.args.map(a => this.sanitizeArg(a)) };
|
|
101
|
+
}
|
|
102
|
+
return event;
|
|
103
|
+
}
|
|
50
104
|
dispatchDomEvent(key, event) {
|
|
51
105
|
if (typeof document === 'undefined')
|
|
52
106
|
return;
|
|
53
|
-
document.dispatchEvent(new CustomEvent('openapi-mock-event', { detail: { key, event } }));
|
|
107
|
+
document.dispatchEvent(new CustomEvent('openapi-mock-event', { detail: { key, event: this.sanitizeEventForDom(event) } }));
|
|
54
108
|
}
|
|
55
109
|
constructor() {
|
|
56
110
|
if (typeof document === 'undefined')
|
|
@@ -58,6 +112,14 @@ class MockResourceBus {
|
|
|
58
112
|
document.addEventListener('openapi-mock-control', (e) => {
|
|
59
113
|
const detail = e.detail;
|
|
60
114
|
const ref = this.refs.get(detail.key);
|
|
115
|
+
switch (detail.action) {
|
|
116
|
+
case 'setCatchMode':
|
|
117
|
+
this.setCatchMode(detail.key, true);
|
|
118
|
+
return;
|
|
119
|
+
case 'clearCatchMode':
|
|
120
|
+
this.setCatchMode(detail.key, false);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
61
123
|
if (!ref)
|
|
62
124
|
return;
|
|
63
125
|
switch (detail.action) {
|
|
@@ -73,9 +135,17 @@ class MockResourceBus {
|
|
|
73
135
|
case 'fail':
|
|
74
136
|
ref.fail(detail.value);
|
|
75
137
|
break;
|
|
76
|
-
case 'reset':
|
|
138
|
+
case 'reset': {
|
|
77
139
|
ref.reset();
|
|
140
|
+
// If catch mode is still on, immediately re-intercept the resource.
|
|
141
|
+
if (this.catchModeKeys.has(detail.key)) {
|
|
142
|
+
ref.setLoading();
|
|
143
|
+
this.dispatchDomEvent(detail.key, {
|
|
144
|
+
type: 'caught', args: [], requestId: this.nextReqId(), ts: Date.now(),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
78
147
|
break;
|
|
148
|
+
}
|
|
79
149
|
case 'setProgress':
|
|
80
150
|
ref.setProgress(detail.progressType, detail.loaded, detail.total);
|
|
81
151
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock-resource-bus.js","sourceRoot":"","sources":["../../../../../tools/openapi-resource-mocks/src/lib/mock-resource-bus.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"mock-resource-bus.js","sourceRoot":"","sources":["../../../../../tools/openapi-resource-mocks/src/lib/mock-resource-bus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-resource-meta.js","sourceRoot":"","sources":["../../../../../tools/openapi-resource-mocks/src/lib/mock-resource-meta.ts"],"names":[],"mappings":""}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { InjectionToken, FactoryProvider } from '@angular/core';
|
|
2
2
|
import { httpResource } from '@angular/common/http';
|
|
3
|
+
import type { MockResourceMeta } from './mock-resource-meta';
|
|
3
4
|
export type DeepPartial<T> = T extends Array<infer E> ? DeepPartial<E>[] : T extends object ? {
|
|
4
5
|
[K in keyof T]?: DeepPartial<T[K]>;
|
|
5
6
|
} : T;
|
|
@@ -12,4 +13,4 @@ export type ProviderInitialBehavior<T> = {
|
|
|
12
13
|
error: unknown;
|
|
13
14
|
delay?: number;
|
|
14
15
|
};
|
|
15
|
-
export declare function provideMockResource<T>(token: InjectionToken<(...args: unknown[]) => ReturnType<typeof httpResource<T>>>, key: string, initialBehavior?: ProviderInitialBehavior<T
|
|
16
|
+
export declare function provideMockResource<T>(token: InjectionToken<(...args: unknown[]) => ReturnType<typeof httpResource<T>>>, key: string, initialBehavior?: ProviderInitialBehavior<T>, meta?: MockResourceMeta): FactoryProvider;
|
|
@@ -4,36 +4,65 @@ exports.provideMockResource = provideMockResource;
|
|
|
4
4
|
const core_1 = require("@angular/core");
|
|
5
5
|
const mock_resource_bus_1 = require("./mock-resource-bus");
|
|
6
6
|
const mock_resource_ref_1 = require("./mock-resource-ref");
|
|
7
|
-
function
|
|
7
|
+
function applyBehavior(ref, behavior) {
|
|
8
|
+
if ('value' in behavior) {
|
|
9
|
+
if (behavior.delay) {
|
|
10
|
+
ref.resolveAfter(behavior.delay, behavior.value);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
ref.resolve(behavior.value);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
else if ('error' in behavior) {
|
|
17
|
+
if (behavior.delay) {
|
|
18
|
+
ref.setLoading();
|
|
19
|
+
setTimeout(() => ref.fail(behavior.error), behavior.delay);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
ref.fail(behavior.error);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
ref.setLoading();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function provideMockResource(token, key, initialBehavior, meta) {
|
|
8
30
|
return {
|
|
9
31
|
provide: token,
|
|
10
32
|
useFactory: () => {
|
|
11
33
|
const bus = (0, core_1.inject)(mock_resource_bus_1.MockResourceBus);
|
|
12
34
|
return (...args) => {
|
|
13
35
|
const ref = (0, mock_resource_ref_1.createMockResourceRef)();
|
|
14
|
-
bus.register(key, ref);
|
|
15
|
-
ref
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
bus.register(key, ref, meta);
|
|
37
|
+
const internal = ref;
|
|
38
|
+
// untracked() prevents thunk signal-reads from leaking into the outer reactive
|
|
39
|
+
// context — component field initializers run during Angular change detection.
|
|
40
|
+
(0, core_1.untracked)(() => {
|
|
41
|
+
internal._notifyRequest(args);
|
|
42
|
+
// Skip initialBehavior when the bus caught the request: catch mode takes
|
|
43
|
+
// precedence and the response must come from the DevTools panel.
|
|
44
|
+
if (initialBehavior && !bus.isCatchMode(key))
|
|
45
|
+
applyBehavior(ref, initialBehavior);
|
|
46
|
+
});
|
|
47
|
+
// When any arg is a reactive thunk, track signal changes so each new set of
|
|
48
|
+
// params fires a new request event (mirroring how httpResource re-fires on
|
|
49
|
+
// reactive lambda changes). effect() is valid here because this function is
|
|
50
|
+
// always called from a component constructor / field-initializer context.
|
|
51
|
+
if (args.some((a) => typeof a === 'function')) {
|
|
52
|
+
let first = true;
|
|
53
|
+
(0, core_1.effect)(() => {
|
|
54
|
+
// Resolve thunks inside the effect body so their signals are tracked.
|
|
55
|
+
const resolved = args.map((a) => (typeof a === 'function' ? a() : a));
|
|
56
|
+
(0, core_1.untracked)(() => {
|
|
57
|
+
if (first) {
|
|
58
|
+
first = false;
|
|
59
|
+
return;
|
|
60
|
+
} // first run already handled above
|
|
61
|
+
internal._notifyRequest(resolved);
|
|
62
|
+
if (initialBehavior && !bus.isCatchMode(key))
|
|
63
|
+
applyBehavior(ref, initialBehavior);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
37
66
|
}
|
|
38
67
|
return ref;
|
|
39
68
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provide-mock-resource.js","sourceRoot":"","sources":["../../../../../tools/openapi-resource-mocks/src/lib/provide-mock-resource.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"provide-mock-resource.js","sourceRoot":"","sources":["../../../../../tools/openapi-resource-mocks/src/lib/provide-mock-resource.ts"],"names":[],"mappings":"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"}
|