@acorex-platform/client-connectivity-api 0.0.28

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,28 @@
1
+ # @acorex-platform/client-connectivity-api
2
+
3
+ Published Nest / demo-api CQRS transport for standalone Angular hosts.
4
+
5
+ - `AXCRuntimeRemoteApiModule` / `provideRuntimeRemoteTransport()`
6
+ - Hooks: `runtime.query.execute`, `runtime.command.execute`, `runtime.command.execute-bulk`
7
+ - HTTP helpers (`isAuthHttpRequest`, retry interceptor)
8
+
9
+ ```typescript
10
+ import { AXCRuntimeRemoteApiModule } from '@acorex-platform/client-connectivity-api';
11
+
12
+ @NgModule({
13
+ imports: [AXCRuntimeRemoteApiModule],
14
+ })
15
+ export class AppModule {}
16
+ ```
17
+
18
+ `AXP_ROOT_CONFIG_TOKEN.baseUrl` must point at the API (demo: `/api`). Calls go to:
19
+
20
+ - `POST {baseUrl}/v1/runtime/queries` and `/queries/invoke`
21
+ - `POST {baseUrl}/v1/runtime/commands` and `/commands/invoke`
22
+ - `POST {baseUrl}/v1/runtime/commands/bulk`
23
+
24
+ `AXMSettingsManagementModule` already imports this module so official client apps get the transport without an extra import.
25
+
26
+ Hosts that are not Nest should use `provideExternalRuntimeQueryTransport` /
27
+ `provideExternalRuntimeCommandTransport` / `provideExternalRuntimeBulkTransport`
28
+ from `@acorex-platform/framework-client/runtime` instead.
@@ -0,0 +1,728 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Injectable, NgModule, inject } from '@angular/core';
3
+ import { throwError, timer, firstValueFrom, catchError as catchError$1 } from 'rxjs';
4
+ import { catchError, switchMap } from 'rxjs/operators';
5
+ import { AUTH_SIGN_IN_DEFAULT, AUTH_REGISTER_DEFAULT, AUTH_REFRESH_DEFAULT, AUTH_LOGOUT_DEFAULT, AUTH_UPDATE_SESSION_DEFAULT, AUTH_LIST_PROVIDERS_DEFAULT, buildRuntimeInvokeQueryString } from '@acorex-platform/framework-shared/runtime';
6
+ import { HTTP_INTERCEPTORS, HttpClient, HttpHeaders } from '@angular/common/http';
7
+ import { toAXPRequestError, AXPSettingsService, AXPCommonSettings, AXP_RUNTIME_QUERY_CACHE_DEFAULTS, coerceAXPSettingRawValueByKind, AXP_ROOT_CONFIG_TOKEN } from '@acorex-platform/framework-client/common';
8
+ import { AXPDebugService, AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER } from '@acorex-platform/framework-client/core';
9
+ import { AXPRuntimeRemoteHookKeys } from '@acorex-platform/framework-client/runtime';
10
+ import { AXPRequestError } from '@acorex-platform/framework-shared/core';
11
+
12
+ //#region ----- Constants -----
13
+ /** Client-only marker: do not refresh/retry auth HTTP when this request fails. */
14
+ const API_SKIP_AUTH_RETRY_HEADER = 'X-Skip-Auth-Retry';
15
+ const AUTH_RUNTIME_COMMAND_KEYS = new Set([
16
+ AUTH_SIGN_IN_DEFAULT,
17
+ AUTH_REGISTER_DEFAULT,
18
+ AUTH_REFRESH_DEFAULT,
19
+ AUTH_LOGOUT_DEFAULT,
20
+ AUTH_UPDATE_SESSION_DEFAULT,
21
+ ]);
22
+ const AUTH_RUNTIME_QUERY_KEYS = new Set([AUTH_LIST_PROVIDERS_DEFAULT]);
23
+ //#endregion
24
+ //#region ----- Auth HTTP helpers -----
25
+ function isAuthRuntimeCommandKey(name) {
26
+ return AUTH_RUNTIME_COMMAND_KEYS.has(name);
27
+ }
28
+ function isAuthRuntimeQueryKey(name) {
29
+ return AUTH_RUNTIME_QUERY_KEYS.has(name);
30
+ }
31
+ /** Headers for auth runtime transport calls (prevents 401 refresh loops). */
32
+ function skipAuthRetryHeadersForRuntime(name, kind) {
33
+ const isAuth = kind === 'command' ? isAuthRuntimeCommandKey(name) : isAuthRuntimeQueryKey(name);
34
+ return isAuth ? { [API_SKIP_AUTH_RETRY_HEADER]: '1' } : undefined;
35
+ }
36
+ /**
37
+ * True when the request is part of the auth flow and must not trigger token refresh
38
+ * or transient HTTP retry (legacy `/v1/auth/*`, runtime auth keys, or explicit header).
39
+ */
40
+ function isAuthHttpRequest(request) {
41
+ if (request.headers.has(API_SKIP_AUTH_RETRY_HEADER)) {
42
+ return true;
43
+ }
44
+ if (request.url.includes('/v1/auth/')) {
45
+ return true;
46
+ }
47
+ return isAuthRuntimeHttpRequest(request);
48
+ }
49
+ function isAuthRuntimeHttpRequest(request) {
50
+ if (request.method !== 'POST') {
51
+ return false;
52
+ }
53
+ const runtimeKey = resolveRuntimeRequestName(request);
54
+ if (!runtimeKey) {
55
+ return false;
56
+ }
57
+ if (request.url.includes('/v1/runtime/commands')) {
58
+ return isAuthRuntimeCommandKey(runtimeKey);
59
+ }
60
+ if (request.url.includes('/v1/runtime/queries')) {
61
+ return isAuthRuntimeQueryKey(runtimeKey);
62
+ }
63
+ return false;
64
+ }
65
+ /**
66
+ * Prefer `?name=` (invoke) over envelope `body.name` so input-only bodies that
67
+ * happen to include a `name` field cannot be mistaken for the runtime key.
68
+ */
69
+ function resolveRuntimeRequestName(request) {
70
+ const fromUrl = readRuntimeNameFromUrl(request.url);
71
+ if (fromUrl) {
72
+ return fromUrl;
73
+ }
74
+ return readRuntimeRequestNameFromBody(request.body);
75
+ }
76
+ function readRuntimeNameFromUrl(url) {
77
+ try {
78
+ const parsed = new URL(url, 'http://localhost');
79
+ const name = parsed.searchParams.get('name');
80
+ return typeof name === 'string' && name.trim() ? name.trim() : undefined;
81
+ }
82
+ catch {
83
+ return undefined;
84
+ }
85
+ }
86
+ function readRuntimeRequestNameFromBody(body) {
87
+ if (body == null || typeof body !== 'object') {
88
+ return undefined;
89
+ }
90
+ const name = body.name;
91
+ return typeof name === 'string' && name.trim() ? name.trim() : undefined;
92
+ }
93
+ //#endregion
94
+
95
+ const API_HTTP_RETRY_MAX_ATTEMPTS = 5;
96
+ const API_HTTP_RETRY_BASE_MS = 400;
97
+ /** POST endpoints that only perform reads and are safe to retry after transient failures. */
98
+ const READ_ONLY_POST_URL_PARTS = ['/v1/runtime/queries'];
99
+ //#endregion
100
+ //#region ----- Retry helpers -----
101
+ function apiHttpRetryDelayMs(attempt) {
102
+ return API_HTTP_RETRY_BASE_MS * attempt;
103
+ }
104
+ /** GET/HEAD and read-only POST queries — safe to retry when the server may not have responded. */
105
+ function isSafeToRetryHttpRequest(request) {
106
+ if (request.method === 'GET' || request.method === 'HEAD') {
107
+ return true;
108
+ }
109
+ return (request.method === 'POST' &&
110
+ READ_ONLY_POST_URL_PARTS.some((part) => request.url.includes(part)));
111
+ }
112
+ function isRetriableHttpError(error, request, attempt) {
113
+ if (attempt >= API_HTTP_RETRY_MAX_ATTEMPTS) {
114
+ return false;
115
+ }
116
+ if (isAuthHttpRequest(request)) {
117
+ return false;
118
+ }
119
+ if (request.headers.has('X-Skip-Http-Retry')) {
120
+ return false;
121
+ }
122
+ const status = error.status;
123
+ const isTransientStatus = status === 0 || status === 502 || status === 503 || status === 504;
124
+ if (!isTransientStatus) {
125
+ return false;
126
+ }
127
+ return isSafeToRetryHttpRequest(request);
128
+ }
129
+ //#endregion
130
+
131
+ //#endregion
132
+ //#region ----- Interceptor -----
133
+ /**
134
+ * Retries transient connectivity failures (status 0, 502, 503, 504) for idempotent
135
+ * platform API calls: GET/HEAD and read-only POST runtime queries.
136
+ */
137
+ class AXCApiHttpRetryInterceptor {
138
+ intercept(request, next) {
139
+ return this.sendWithRetry(request, next, 0);
140
+ }
141
+ sendWithRetry(request, next, attempt) {
142
+ return next.handle(request).pipe(catchError((error) => {
143
+ if (!isRetriableHttpError(error, request, attempt)) {
144
+ return throwError(() => error);
145
+ }
146
+ const nextAttempt = attempt + 1;
147
+ return timer(apiHttpRetryDelayMs(nextAttempt)).pipe(switchMap(() => this.sendWithRetry(request, next, nextAttempt)));
148
+ }));
149
+ }
150
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCApiHttpRetryInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
151
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCApiHttpRetryInterceptor }); }
152
+ }
153
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCApiHttpRetryInterceptor, decorators: [{
154
+ type: Injectable
155
+ }] });
156
+
157
+ //#region ----- Imports -----
158
+ //#endregion
159
+ //#region ----- Module -----
160
+ class AXCApiHttpModule {
161
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCApiHttpModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
162
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXCApiHttpModule }); }
163
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCApiHttpModule, providers: [
164
+ {
165
+ provide: HTTP_INTERCEPTORS,
166
+ useClass: AXCApiHttpRetryInterceptor,
167
+ multi: true,
168
+ },
169
+ ] }); }
170
+ }
171
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCApiHttpModule, decorators: [{
172
+ type: NgModule,
173
+ args: [{
174
+ providers: [
175
+ {
176
+ provide: HTTP_INTERCEPTORS,
177
+ useClass: AXCApiHttpRetryInterceptor,
178
+ multi: true,
179
+ },
180
+ ],
181
+ }]
182
+ }] });
183
+
184
+ //#region ---- HTTP → AXPRequestError ----
185
+ /**
186
+ * Normalize Angular HTTP failures into transport-agnostic {@link AXPRequestError}.
187
+ * Call only from connectivity adapters (REST today; gRPC/GraphQL later).
188
+ */
189
+ function mapHttpErrorResponseToAXPRequestError(error) {
190
+ return toAXPRequestError(error);
191
+ }
192
+ //#endregion
193
+
194
+ //#region ----- Stable Request Serialization -----
195
+ /**
196
+ * Serializes JSON-like query input with object keys sorted recursively.
197
+ * Equivalent inputs produce the same cache key regardless of property insertion order.
198
+ */
199
+ function stableSerializeRuntimeQueryInput(value) {
200
+ return JSON.stringify(normalizeValue(value, new WeakSet())) ?? 'undefined';
201
+ }
202
+ function normalizeValue(value, ancestors) {
203
+ if (value === null || typeof value !== 'object') {
204
+ return value;
205
+ }
206
+ if (value instanceof Date) {
207
+ return value.toJSON();
208
+ }
209
+ if (ancestors.has(value)) {
210
+ throw new TypeError('Runtime query input must not contain circular references');
211
+ }
212
+ ancestors.add(value);
213
+ try {
214
+ if (Array.isArray(value)) {
215
+ return value.map((item) => normalizeValue(item, ancestors));
216
+ }
217
+ const record = value;
218
+ return Object.keys(record)
219
+ .sort()
220
+ .reduce((normalized, key) => {
221
+ const item = record[key];
222
+ if (item !== undefined) {
223
+ normalized[key] = normalizeValue(item, ancestors);
224
+ }
225
+ return normalized;
226
+ }, {});
227
+ }
228
+ finally {
229
+ ancestors.delete(value);
230
+ }
231
+ }
232
+ //#endregion
233
+
234
+ //#region ----- Imports -----
235
+ const MAX_CACHE_ENTRIES = 250;
236
+ const DEBUG_NAMESPACE = 'runtime-query-cache';
237
+ /** Duplicates are collected for this window, then reported as one line per request. */
238
+ const DUPLICATE_REPORT_WINDOW_MS = 1_000;
239
+ const MAX_TRACKED_DUPLICATE_REQUESTS = 50;
240
+ const MAX_STACK_FRAMES = 8;
241
+ const MAX_DUPLICATE_STACK_SAMPLES = 3;
242
+ const MAX_TARGET_LENGTH = 120;
243
+ const MAX_FILTER_FIELDS = 3;
244
+ const MAX_FILTER_DEPTH = 3;
245
+ /** Gateway frames that hide the real caller in captured stacks. */
246
+ const GATEWAY_STACK_FRAME_PATTERN = /AXCRuntimeQueryCacheService|AXCRuntimeApiService\.(executeQuery|sendQuery)|runtime-query-cache/;
247
+ /** Async/zone plumbing frames that carry no call-site information. */
248
+ const PLUMBING_STACK_FRAME_PATTERN = /zone\.js|Zone[A-Za-z]*\.|ZoneAwarePromise|asyncGeneratorStep|_?asyncToGenerator|__awaiter|Generator\.|Object\.next|drainMicroTaskQueue|processTicksAndRejections/;
249
+ //#endregion
250
+ //#region ----- Runtime Query Cache -----
251
+ /**
252
+ * Coalesces identical in-flight runtime queries and optionally reuses successful
253
+ * responses for a short platform-configured TTL.
254
+ */
255
+ class AXCRuntimeQueryCacheService {
256
+ //#endregion
257
+ constructor() {
258
+ //#region ----- Services & Dependencies -----
259
+ this.settings = inject(AXPSettingsService);
260
+ this.debug = inject(AXPDebugService);
261
+ //#endregion
262
+ //#region ----- State -----
263
+ this.inFlight = new Map();
264
+ this.responses = new Map();
265
+ this.duplicates = new Map();
266
+ this.generation = 0;
267
+ this.settings.onLoaded.subscribe(() => this.clear());
268
+ this.settings.onChanged.subscribe((event) => {
269
+ if (event.keys.includes(AXPCommonSettings.RuntimeQueryCacheEnabled) ||
270
+ event.keys.includes(AXPCommonSettings.RuntimeQueryCacheTtlMs)) {
271
+ this.clear();
272
+ }
273
+ });
274
+ }
275
+ //#region ----- Public API -----
276
+ execute(name, input, request, options) {
277
+ if (!this.isEnabled()) {
278
+ return request();
279
+ }
280
+ const optionsKey = options != null && Object.keys(options).length > 0
281
+ ? stableSerializeRuntimeQueryInput(options)
282
+ : '';
283
+ const key = `${name}|${stableSerializeRuntimeQueryInput(input ?? {})}|${optionsKey}`;
284
+ const now = Date.now();
285
+ const cached = this.responses.get(key);
286
+ if (cached) {
287
+ if (cached.expiresAt > now) {
288
+ this.recordDuplicate({
289
+ duplicateStack: this.captureCallerStack(),
290
+ input,
291
+ key,
292
+ name,
293
+ originAgeMs: now - cached.storedAt,
294
+ originStack: cached.originStack,
295
+ type: 'ttl-cache-hit',
296
+ });
297
+ return Promise.resolve(cached.result);
298
+ }
299
+ this.responses.delete(key);
300
+ }
301
+ const existing = this.inFlight.get(key);
302
+ if (existing) {
303
+ this.recordDuplicate({
304
+ duplicateStack: this.captureCallerStack(),
305
+ input,
306
+ key,
307
+ name,
308
+ originAgeMs: now - existing.startedAt,
309
+ originStack: existing.originStack,
310
+ type: 'in-flight-coalesced',
311
+ });
312
+ return existing.promise;
313
+ }
314
+ const generation = this.generation;
315
+ const ttlMs = this.getTtlMs();
316
+ const originStack = this.captureCallerStack();
317
+ const task = request()
318
+ .then((result) => {
319
+ if (result.success &&
320
+ ttlMs > 0 &&
321
+ generation === this.generation &&
322
+ this.isEnabled()) {
323
+ this.storeResponse(key, result, ttlMs, originStack);
324
+ }
325
+ return result;
326
+ })
327
+ .finally(() => {
328
+ if (this.inFlight.get(key)?.promise === task) {
329
+ this.inFlight.delete(key);
330
+ }
331
+ });
332
+ this.inFlight.set(key, {
333
+ originStack,
334
+ promise: task,
335
+ startedAt: now,
336
+ });
337
+ return task;
338
+ }
339
+ /**
340
+ * Invalidates completed responses and prevents older in-flight queries from
341
+ * repopulating the cache after a command or configuration change.
342
+ */
343
+ clear() {
344
+ this.generation += 1;
345
+ this.responses.clear();
346
+ this.inFlight.clear();
347
+ this.reportDuplicates();
348
+ }
349
+ //#endregion
350
+ //#region ----- Settings -----
351
+ isEnabled() {
352
+ const raw = this.settings.peekCached(AXPCommonSettings.RuntimeQueryCacheEnabled);
353
+ return raw === undefined
354
+ ? AXP_RUNTIME_QUERY_CACHE_DEFAULTS.enabled
355
+ : coerceAXPSettingRawValueByKind(raw, 'boolean');
356
+ }
357
+ getTtlMs() {
358
+ const raw = this.settings.peekCached(AXPCommonSettings.RuntimeQueryCacheTtlMs);
359
+ const value = raw === undefined
360
+ ? AXP_RUNTIME_QUERY_CACHE_DEFAULTS.ttlMs
361
+ : coerceAXPSettingRawValueByKind(raw, 'number');
362
+ return Number.isFinite(value) ? Math.max(0, value) : AXP_RUNTIME_QUERY_CACHE_DEFAULTS.ttlMs;
363
+ }
364
+ //#endregion
365
+ //#region ----- Cache Maintenance -----
366
+ storeResponse(key, result, ttlMs, originStack) {
367
+ this.pruneExpired();
368
+ if (this.responses.size >= MAX_CACHE_ENTRIES) {
369
+ const oldestKey = this.responses.keys().next().value;
370
+ if (oldestKey) {
371
+ this.responses.delete(oldestKey);
372
+ }
373
+ }
374
+ const storedAt = Date.now();
375
+ this.responses.set(key, {
376
+ result,
377
+ expiresAt: storedAt + ttlMs,
378
+ originStack,
379
+ storedAt,
380
+ });
381
+ }
382
+ pruneExpired() {
383
+ const now = Date.now();
384
+ for (const [key, entry] of this.responses) {
385
+ if (entry.expiresAt <= now) {
386
+ this.responses.delete(key);
387
+ }
388
+ }
389
+ }
390
+ //#endregion
391
+ //#region ----- Debug Diagnostics -----
392
+ captureCallerStack() {
393
+ if (!this.debug.isDebugMode()) {
394
+ return undefined;
395
+ }
396
+ const frames = (new Error().stack?.split('\n') ?? [])
397
+ .map((frame) => frame.trim())
398
+ .filter((frame) => frame.length > 0 && frame !== 'Error' && !GATEWAY_STACK_FRAME_PATTERN.test(frame));
399
+ const callSites = frames.filter((frame) => !PLUMBING_STACK_FRAME_PATTERN.test(frame));
400
+ const selected = (callSites.length > 0 ? callSites : frames).slice(0, MAX_STACK_FRAMES);
401
+ return selected.length > 0 ? selected.join('\n') : undefined;
402
+ }
403
+ recordDuplicate(details) {
404
+ if (!this.debug.isDebugMode()) {
405
+ return;
406
+ }
407
+ const now = Date.now();
408
+ let stat = this.duplicates.get(details.key);
409
+ if (!stat) {
410
+ stat = {
411
+ callerLabel: this.describeCaller(details.duplicateStack ?? details.originStack),
412
+ coalescedCount: 0,
413
+ duplicateStacks: [],
414
+ firstAt: now,
415
+ input: details.input,
416
+ lastAt: now,
417
+ maxOriginAgeMs: 0,
418
+ name: details.name,
419
+ originStack: details.originStack,
420
+ reusedCount: 0,
421
+ target: this.describeTarget(details.input),
422
+ };
423
+ this.duplicates.set(details.key, stat);
424
+ }
425
+ stat.lastAt = now;
426
+ stat.maxOriginAgeMs = Math.max(stat.maxOriginAgeMs, Math.round(details.originAgeMs));
427
+ if (details.type === 'in-flight-coalesced') {
428
+ stat.coalescedCount += 1;
429
+ }
430
+ else {
431
+ stat.reusedCount += 1;
432
+ }
433
+ if (details.duplicateStack &&
434
+ stat.duplicateStacks.length < MAX_DUPLICATE_STACK_SAMPLES &&
435
+ !stat.duplicateStacks.includes(details.duplicateStack)) {
436
+ stat.duplicateStacks.push(details.duplicateStack);
437
+ }
438
+ if (this.duplicates.size >= MAX_TRACKED_DUPLICATE_REQUESTS) {
439
+ this.reportDuplicates();
440
+ return;
441
+ }
442
+ this.duplicateReportHandle ??= setTimeout(() => this.reportDuplicates(), DUPLICATE_REPORT_WINDOW_MS);
443
+ }
444
+ /** Emits one warning per duplicated request, with every key value inline in the message. */
445
+ reportDuplicates() {
446
+ if (this.duplicateReportHandle !== undefined) {
447
+ clearTimeout(this.duplicateReportHandle);
448
+ this.duplicateReportHandle = undefined;
449
+ }
450
+ const stats = [...this.duplicates.values()].sort((left, right) => right.coalescedCount + right.reusedCount - (left.coalescedCount + left.reusedCount));
451
+ this.duplicates.clear();
452
+ if (stats.length === 0) {
453
+ return;
454
+ }
455
+ const totalCalls = stats.reduce((total, stat) => total + stat.coalescedCount + stat.reusedCount, 0);
456
+ if (stats.length > 1) {
457
+ this.debug.warn(DEBUG_NAMESPACE, 'duplicates', `${totalCalls} duplicate calls suppressed · ${stats.length} distinct requests · last ${DUPLICATE_REPORT_WINDOW_MS}ms`);
458
+ }
459
+ for (const stat of stats) {
460
+ const count = stat.coalescedCount + stat.reusedCount;
461
+ const segments = [
462
+ `×${count} duplicate ${count === 1 ? 'call' : 'calls'}`,
463
+ stat.target,
464
+ `coalesced ${stat.coalescedCount} / from memory ${stat.reusedCount}`,
465
+ `burst ${Math.max(0, stat.lastAt - stat.firstAt)}ms`,
466
+ `origin age ≤${stat.maxOriginAgeMs}ms`,
467
+ ];
468
+ if (stat.callerLabel) {
469
+ segments.push(`caller ${stat.callerLabel}`);
470
+ }
471
+ this.debug.warn(DEBUG_NAMESPACE, stat.name, segments.join(' · '), () => ({
472
+ duplicateStacks: stat.duplicateStacks,
473
+ input: stat.input,
474
+ originalCallStack: stat.originStack,
475
+ }));
476
+ }
477
+ }
478
+ /** First meaningful frame, e.g. `AXPLookupEditorWidgetColumn.loadTitle`. */
479
+ describeCaller(stack) {
480
+ const frame = stack?.split('\n')[0];
481
+ if (!frame) {
482
+ return undefined;
483
+ }
484
+ return frame.match(/^at\s+([\w$.<>]+)/)?.[1] ?? frame.match(/^([\w$.<>]+)@/)?.[1];
485
+ }
486
+ describeTarget(input) {
487
+ if (input === undefined || input === null) {
488
+ return 'no input';
489
+ }
490
+ if (typeof input !== 'object') {
491
+ return String(input);
492
+ }
493
+ const record = input;
494
+ const pick = (...keys) => keys.map((key) => record[key]).find((value) => typeof value === 'string');
495
+ const entity = pick('entity', 'entityName', 'entityType');
496
+ const id = pick('id', 'entityId', 'key');
497
+ const view = pick('view', 'viewName', 'queryName');
498
+ const filterFields = this.collectFilterFields(record['filter']);
499
+ const segments = [
500
+ entity,
501
+ id ? `#${id.slice(0, 8)}` : undefined,
502
+ view ? `view=${view}` : undefined,
503
+ filterFields.length > 0 ? `filter=${filterFields.join(',')}` : undefined,
504
+ typeof record['take'] === 'number' ? `take=${record['take']}` : undefined,
505
+ ].filter((segment) => !!segment);
506
+ if (segments.length > 0) {
507
+ return segments.join(' ');
508
+ }
509
+ const serialized = stableSerializeRuntimeQueryInput(input);
510
+ return serialized.length > MAX_TARGET_LENGTH
511
+ ? `${serialized.slice(0, MAX_TARGET_LENGTH - 1)}…`
512
+ : serialized;
513
+ }
514
+ collectFilterFields(filter, depth = 0) {
515
+ if (depth > MAX_FILTER_DEPTH || filter == null || typeof filter !== 'object') {
516
+ return [];
517
+ }
518
+ const record = filter;
519
+ if (typeof record['field'] === 'string') {
520
+ return [record['field']];
521
+ }
522
+ const nested = Array.isArray(record['filters']) ? record['filters'] : [];
523
+ const fields = nested.flatMap((child) => this.collectFilterFields(child, depth + 1));
524
+ return [...new Set(fields)].slice(0, MAX_FILTER_FIELDS);
525
+ }
526
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCRuntimeQueryCacheService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
527
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCRuntimeQueryCacheService }); }
528
+ }
529
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCRuntimeQueryCacheService, decorators: [{
530
+ type: Injectable
531
+ }], ctorParameters: () => [] });
532
+
533
+ //#region ---- Runtime API service ----
534
+ /**
535
+ * HTTP client for platform runtime command/query endpoints.
536
+ * Transport failures are normalized to {@link AXPRequestError}.
537
+ */
538
+ class AXCRuntimeApiService {
539
+ constructor() {
540
+ this.http = inject(HttpClient);
541
+ this.configs = inject(AXP_ROOT_CONFIG_TOKEN);
542
+ this.queryCache = inject(AXCRuntimeQueryCacheService);
543
+ }
544
+ runtimeUrl(kind) {
545
+ return `${this.configs.baseUrl}/v1/runtime/${kind}`;
546
+ }
547
+ /**
548
+ * Single command/query invoke — key (and entity for `Entity:*:Default`) in the
549
+ * query string so DevTools shows the operation without `%3A` noise.
550
+ */
551
+ runtimeInvokeUrl(kind, name, input) {
552
+ const query = buildRuntimeInvokeQueryString(name, input);
553
+ return `${this.configs.baseUrl}/v1/runtime/${kind}/invoke?${query}`;
554
+ }
555
+ executeCommand(name, input, options) {
556
+ const skipAuthRetry = skipAuthRetryHeadersForRuntime(name, 'command');
557
+ const headers = skipAuthRetry ? new HttpHeaders(skipAuthRetry) : undefined;
558
+ const hasOptions = options != null && Object.keys(options).length > 0;
559
+ const request$ = hasOptions
560
+ ? this.http.post(this.runtimeUrl('commands'), { name, input: input ?? {}, options }, { withCredentials: true, ...(headers ? { headers } : undefined) })
561
+ : this.http.post(this.runtimeInvokeUrl('commands', name, input), input ?? {}, { withCredentials: true, ...(headers ? { headers } : undefined) });
562
+ return firstValueFrom(request$.pipe(catchError$1((error) => throwError(() => mapHttpErrorResponseToAXPRequestError(error))))).then((result) => {
563
+ if (result.success) {
564
+ this.queryCache.clear();
565
+ }
566
+ return result;
567
+ });
568
+ }
569
+ executeBulkCommand(request) {
570
+ return firstValueFrom(this.http
571
+ .post(this.runtimeUrl('commands/bulk'), request, {
572
+ withCredentials: true,
573
+ })
574
+ .pipe(catchError$1((error) => throwError(() => mapHttpErrorResponseToAXPRequestError(error))))).then((result) => {
575
+ if (result.success) {
576
+ this.queryCache.clear();
577
+ }
578
+ return result;
579
+ });
580
+ }
581
+ executeQuery(name, input, options) {
582
+ return this.queryCache.execute(name, input, () => this.sendQuery(name, input, options), options);
583
+ }
584
+ sendQuery(name, input, options) {
585
+ const skipAuthRetry = skipAuthRetryHeadersForRuntime(name, 'query');
586
+ const headers = skipAuthRetry ? new HttpHeaders(skipAuthRetry) : undefined;
587
+ const hasOptions = options != null && Object.keys(options).length > 0;
588
+ // Named body carries `options`; invoke keeps body = input only for DevTools-friendly URLs.
589
+ const request$ = hasOptions
590
+ ? this.http.post(this.runtimeUrl('queries'), { name, input: input ?? {}, options }, { withCredentials: true, ...(headers ? { headers } : undefined) })
591
+ : this.http.post(this.runtimeInvokeUrl('queries', name, input), input ?? {}, { withCredentials: true, ...(headers ? { headers } : undefined) });
592
+ return firstValueFrom(request$.pipe(catchError$1((error) => throwError(() => mapHttpErrorResponseToAXPRequestError(error)))));
593
+ }
594
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCRuntimeApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
595
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCRuntimeApiService }); }
596
+ }
597
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCRuntimeApiService, decorators: [{
598
+ type: Injectable
599
+ }] });
600
+
601
+ //#region ---- Unwrap helpers ----
602
+ /**
603
+ * Map server runtime query envelope to the value local {@code query.fetch} would return.
604
+ *
605
+ * - success: false → throw using `message`
606
+ * - kind: 'value' | 'object' | 'collection' → `data`
607
+ */
608
+ function unwrapRuntimeQueryResult(result) {
609
+ if (!result.success) {
610
+ const message = result.message;
611
+ const text = typeof message?.text === 'string'
612
+ ? message.text
613
+ : message?.code || 'Query execution failed';
614
+ throw new AXPRequestError(text, {
615
+ code: message?.code,
616
+ details: message?.details,
617
+ });
618
+ }
619
+ if (result.kind === 'collection' || result.kind === 'object' || result.kind === 'value') {
620
+ return result.data;
621
+ }
622
+ return result;
623
+ }
624
+ //#endregion
625
+ //#region ---- Hook providers ----
626
+ const AXCRuntimeCommandExecuteHookProvider = {
627
+ key: AXPRuntimeRemoteHookKeys.CommandExecute,
628
+ async execute(payload) {
629
+ if (payload.handled) {
630
+ return payload;
631
+ }
632
+ const api = inject(AXCRuntimeApiService);
633
+ const result = await api.executeCommand(payload.name, payload.input, payload.options);
634
+ return { ...payload, handled: true, result };
635
+ },
636
+ };
637
+ const AXCRuntimeCommandExecuteBulkHookProvider = {
638
+ key: AXPRuntimeRemoteHookKeys.CommandExecuteBulk,
639
+ async execute(payload) {
640
+ if (payload.handled) {
641
+ return payload;
642
+ }
643
+ const api = inject(AXCRuntimeApiService);
644
+ const result = await api.executeBulkCommand(payload.request);
645
+ return { ...payload, handled: true, result };
646
+ },
647
+ };
648
+ const AXCRuntimeQueryExecuteHookProvider = {
649
+ key: AXPRuntimeRemoteHookKeys.QueryExecute,
650
+ async execute(payload) {
651
+ if (payload.handled) {
652
+ return payload;
653
+ }
654
+ const api = inject(AXCRuntimeApiService);
655
+ const response = await api.executeQuery(payload.name, payload.input, payload.options);
656
+ // Keep the wire envelope — same contract as local AXPQuery.fetch / command execute.
657
+ return {
658
+ ...payload,
659
+ handled: true,
660
+ result: response,
661
+ };
662
+ },
663
+ };
664
+ const AXC_RUNTIME_REMOTE_HOOK_PROVIDERS = [
665
+ AXCRuntimeQueryCacheService,
666
+ AXCRuntimeApiService,
667
+ {
668
+ provide: AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER,
669
+ useValue: AXCRuntimeCommandExecuteHookProvider,
670
+ multi: true,
671
+ },
672
+ {
673
+ provide: AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER,
674
+ useValue: AXCRuntimeCommandExecuteBulkHookProvider,
675
+ multi: true,
676
+ },
677
+ {
678
+ provide: AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER,
679
+ useValue: AXCRuntimeQueryExecuteHookProvider,
680
+ multi: true,
681
+ },
682
+ ];
683
+ //#endregion
684
+
685
+ //#region ----- Imports -----
686
+ //#endregion
687
+ //#region ----- Provider factory -----
688
+ /**
689
+ * Nest / demo-api CQRS transport: `runtime.query.execute`, `runtime.command.execute`,
690
+ * and `runtime.command.execute-bulk` against `{AXP_ROOT_CONFIG_TOKEN.baseUrl}/v1/runtime/*`.
691
+ *
692
+ * Official hosts that import `AXMSettingsManagementModule` get this automatically.
693
+ * Custom API stacks should use `provideExternalRuntimeQueryTransport` /
694
+ * `provideExternalRuntimeCommandTransport` / `provideExternalRuntimeBulkTransport` instead.
695
+ */
696
+ function provideRuntimeRemoteTransport() {
697
+ return [...AXC_RUNTIME_REMOTE_HOOK_PROVIDERS];
698
+ }
699
+ //#endregion
700
+
701
+ //#region ----- Imports -----
702
+ //#endregion
703
+ //#region ----- Module -----
704
+ /**
705
+ * Registers the Nest runtime CQRS hooks used when a query/command is not in
706
+ * {@code provideQuerySetups} / {@code provideCommandSetups}.
707
+ *
708
+ * Requires {@link AXP_ROOT_CONFIG_TOKEN} (`baseUrl`, typically `/api`) and Angular
709
+ * {@code HttpClient}.
710
+ */
711
+ class AXCRuntimeRemoteApiModule {
712
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCRuntimeRemoteApiModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
713
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXCRuntimeRemoteApiModule }); }
714
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCRuntimeRemoteApiModule, providers: provideRuntimeRemoteTransport() }); }
715
+ }
716
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCRuntimeRemoteApiModule, decorators: [{
717
+ type: NgModule,
718
+ args: [{
719
+ providers: provideRuntimeRemoteTransport(),
720
+ }]
721
+ }] });
722
+
723
+ /**
724
+ * Generated bundle index. Do not edit.
725
+ */
726
+
727
+ export { API_HTTP_RETRY_BASE_MS, API_HTTP_RETRY_MAX_ATTEMPTS, API_SKIP_AUTH_RETRY_HEADER, AXCApiHttpModule, AXCApiHttpRetryInterceptor, AXCRuntimeApiService, AXCRuntimeCommandExecuteBulkHookProvider, AXCRuntimeCommandExecuteHookProvider, AXCRuntimeQueryCacheService, AXCRuntimeQueryExecuteHookProvider, AXCRuntimeRemoteApiModule, AXC_RUNTIME_REMOTE_HOOK_PROVIDERS, apiHttpRetryDelayMs, isAuthHttpRequest, isAuthRuntimeCommandKey, isAuthRuntimeQueryKey, isRetriableHttpError, isSafeToRetryHttpRequest, mapHttpErrorResponseToAXPRequestError, provideRuntimeRemoteTransport, skipAuthRetryHeadersForRuntime, unwrapRuntimeQueryResult };
728
+ //# sourceMappingURL=acorex-platform-client-connectivity-api.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-client-connectivity-api.mjs","sources":["../../../../libs/connectivity/runtime/src/lib/http/api-http-auth.util.ts","../../../../libs/connectivity/runtime/src/lib/http/api-http-retry.util.ts","../../../../libs/connectivity/runtime/src/lib/http/api-http-retry.interceptor.ts","../../../../libs/connectivity/runtime/src/lib/http/api-http.module.ts","../../../../libs/connectivity/runtime/src/lib/http/map-http-error-to-request-error.util.ts","../../../../libs/connectivity/runtime/src/lib/runtime/runtime-query-cache-key.util.ts","../../../../libs/connectivity/runtime/src/lib/runtime/runtime-query-cache.service.ts","../../../../libs/connectivity/runtime/src/lib/runtime/runtime-api.service.ts","../../../../libs/connectivity/runtime/src/lib/runtime/runtime-remote.hooks.ts","../../../../libs/connectivity/runtime/src/lib/runtime/provide-runtime-remote-transport.ts","../../../../libs/connectivity/runtime/src/lib/runtime/runtime-remote-api.module.ts","../../../../libs/connectivity/runtime/src/acorex-platform-client-connectivity-api.ts"],"sourcesContent":["import {\n AUTH_LIST_PROVIDERS_DEFAULT,\n AUTH_LOGOUT_DEFAULT,\n AUTH_REFRESH_DEFAULT,\n AUTH_REGISTER_DEFAULT,\n AUTH_SIGN_IN_DEFAULT,\n AUTH_UPDATE_SESSION_DEFAULT,\n} from '@acorex-platform/framework-shared/runtime';\nimport type { HttpRequest } from '@angular/common/http';\n\n//#region ----- Constants -----\n\n/** Client-only marker: do not refresh/retry auth HTTP when this request fails. */\nexport const API_SKIP_AUTH_RETRY_HEADER = 'X-Skip-Auth-Retry';\n\nconst AUTH_RUNTIME_COMMAND_KEYS = new Set<string>([\n AUTH_SIGN_IN_DEFAULT,\n AUTH_REGISTER_DEFAULT,\n AUTH_REFRESH_DEFAULT,\n AUTH_LOGOUT_DEFAULT,\n AUTH_UPDATE_SESSION_DEFAULT,\n]);\n\nconst AUTH_RUNTIME_QUERY_KEYS = new Set<string>([AUTH_LIST_PROVIDERS_DEFAULT]);\n\n//#endregion\n\n//#region ----- Auth HTTP helpers -----\n\nexport function isAuthRuntimeCommandKey(name: string): boolean {\n return AUTH_RUNTIME_COMMAND_KEYS.has(name);\n}\n\nexport function isAuthRuntimeQueryKey(name: string): boolean {\n return AUTH_RUNTIME_QUERY_KEYS.has(name);\n}\n\n/** Headers for auth runtime transport calls (prevents 401 refresh loops). */\nexport function skipAuthRetryHeadersForRuntime(\n name: string,\n kind: 'command' | 'query',\n): Record<string, string> | undefined {\n const isAuth =\n kind === 'command' ? isAuthRuntimeCommandKey(name) : isAuthRuntimeQueryKey(name);\n\n return isAuth ? { [API_SKIP_AUTH_RETRY_HEADER]: '1' } : undefined;\n}\n\n/**\n * True when the request is part of the auth flow and must not trigger token refresh\n * or transient HTTP retry (legacy `/v1/auth/*`, runtime auth keys, or explicit header).\n */\nexport function isAuthHttpRequest(request: HttpRequest<unknown>): boolean {\n if (request.headers.has(API_SKIP_AUTH_RETRY_HEADER)) {\n return true;\n }\n\n if (request.url.includes('/v1/auth/')) {\n return true;\n }\n\n return isAuthRuntimeHttpRequest(request);\n}\n\nfunction isAuthRuntimeHttpRequest(request: HttpRequest<unknown>): boolean {\n if (request.method !== 'POST') {\n return false;\n }\n\n const runtimeKey = resolveRuntimeRequestName(request);\n if (!runtimeKey) {\n return false;\n }\n\n if (request.url.includes('/v1/runtime/commands')) {\n return isAuthRuntimeCommandKey(runtimeKey);\n }\n\n if (request.url.includes('/v1/runtime/queries')) {\n return isAuthRuntimeQueryKey(runtimeKey);\n }\n\n return false;\n}\n\n/**\n * Prefer `?name=` (invoke) over envelope `body.name` so input-only bodies that\n * happen to include a `name` field cannot be mistaken for the runtime key.\n */\nfunction resolveRuntimeRequestName(request: HttpRequest<unknown>): string | undefined {\n const fromUrl = readRuntimeNameFromUrl(request.url);\n if (fromUrl) {\n return fromUrl;\n }\n\n return readRuntimeRequestNameFromBody(request.body);\n}\n\nfunction readRuntimeNameFromUrl(url: string): string | undefined {\n try {\n const parsed = new URL(url, 'http://localhost');\n const name = parsed.searchParams.get('name');\n return typeof name === 'string' && name.trim() ? name.trim() : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction readRuntimeRequestNameFromBody(body: unknown): string | undefined {\n if (body == null || typeof body !== 'object') {\n return undefined;\n }\n\n const name = (body as { name?: unknown }).name;\n return typeof name === 'string' && name.trim() ? name.trim() : undefined;\n}\n\n//#endregion\n","import { HttpErrorResponse, HttpRequest } from '@angular/common/http';\nimport { isAuthHttpRequest } from './api-http-auth.util';\n\n//#region ----- Constants -----\n\nexport { API_SKIP_AUTH_RETRY_HEADER, isAuthHttpRequest } from './api-http-auth.util';\n\nexport const API_HTTP_RETRY_MAX_ATTEMPTS = 5;\nexport const API_HTTP_RETRY_BASE_MS = 400;\n\n/** POST endpoints that only perform reads and are safe to retry after transient failures. */\nconst READ_ONLY_POST_URL_PARTS = ['/v1/runtime/queries'];\n\n//#endregion\n\n//#region ----- Retry helpers -----\n\nexport function apiHttpRetryDelayMs(attempt: number): number {\n return API_HTTP_RETRY_BASE_MS * attempt;\n}\n\n/** GET/HEAD and read-only POST queries — safe to retry when the server may not have responded. */\nexport function isSafeToRetryHttpRequest(request: HttpRequest<unknown>): boolean {\n if (request.method === 'GET' || request.method === 'HEAD') {\n return true;\n }\n\n return (\n request.method === 'POST' &&\n READ_ONLY_POST_URL_PARTS.some((part) => request.url.includes(part))\n );\n}\n\nexport function isRetriableHttpError(\n error: HttpErrorResponse,\n request: HttpRequest<unknown>,\n attempt: number,\n): boolean {\n if (attempt >= API_HTTP_RETRY_MAX_ATTEMPTS) {\n return false;\n }\n\n if (isAuthHttpRequest(request)) {\n return false;\n }\n\n if (request.headers.has('X-Skip-Http-Retry')) {\n return false;\n }\n\n const status = error.status;\n const isTransientStatus = status === 0 || status === 502 || status === 503 || status === 504;\n\n if (!isTransientStatus) {\n return false;\n }\n\n return isSafeToRetryHttpRequest(request);\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport {\n HttpErrorResponse,\n HttpEvent,\n HttpHandler,\n HttpInterceptor,\n HttpRequest,\n} from '@angular/common/http';\nimport { Injectable } from '@angular/core';\nimport { Observable, throwError, timer } from 'rxjs';\nimport { catchError, switchMap } from 'rxjs/operators';\nimport { apiHttpRetryDelayMs, isRetriableHttpError } from './api-http-retry.util';\n\n//#endregion\n\n//#region ----- Interceptor -----\n\n/**\n * Retries transient connectivity failures (status 0, 502, 503, 504) for idempotent\n * platform API calls: GET/HEAD and read-only POST runtime queries.\n */\n@Injectable()\nexport class AXCApiHttpRetryInterceptor implements HttpInterceptor {\n intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {\n return this.sendWithRetry(request, next, 0);\n }\n\n private sendWithRetry(\n request: HttpRequest<unknown>,\n next: HttpHandler,\n attempt: number,\n ): Observable<HttpEvent<unknown>> {\n return next.handle(request).pipe(\n catchError((error: HttpErrorResponse) => {\n if (!isRetriableHttpError(error, request, attempt)) {\n return throwError(() => error);\n }\n\n const nextAttempt = attempt + 1;\n return timer(apiHttpRetryDelayMs(nextAttempt)).pipe(\n switchMap(() => this.sendWithRetry(request, next, nextAttempt)),\n );\n }),\n );\n }\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { HTTP_INTERCEPTORS } from '@angular/common/http';\nimport { NgModule } from '@angular/core';\nimport { AXCApiHttpRetryInterceptor } from './api-http-retry.interceptor';\n\n//#endregion\n\n//#region ----- Module -----\n\n@NgModule({\n providers: [\n {\n provide: HTTP_INTERCEPTORS,\n useClass: AXCApiHttpRetryInterceptor,\n multi: true,\n },\n ],\n})\nexport class AXCApiHttpModule {}\n\n//#endregion\n","import { AXPRequestError } from '@acorex-platform/framework-shared/core';\nimport { toAXPRequestError } from '@acorex-platform/framework-client/common';\n\n//#region ---- HTTP → AXPRequestError ----\n\n/**\n * Normalize Angular HTTP failures into transport-agnostic {@link AXPRequestError}.\n * Call only from connectivity adapters (REST today; gRPC/GraphQL later).\n */\nexport function mapHttpErrorResponseToAXPRequestError(error: unknown): AXPRequestError {\n return toAXPRequestError(error);\n}\n\n//#endregion\n","//#region ----- Stable Request Serialization -----\n\n/**\n * Serializes JSON-like query input with object keys sorted recursively.\n * Equivalent inputs produce the same cache key regardless of property insertion order.\n */\nexport function stableSerializeRuntimeQueryInput(value: unknown): string {\n return JSON.stringify(normalizeValue(value, new WeakSet<object>())) ?? 'undefined';\n}\n\nfunction normalizeValue(value: unknown, ancestors: WeakSet<object>): unknown {\n if (value === null || typeof value !== 'object') {\n return value;\n }\n\n if (value instanceof Date) {\n return value.toJSON();\n }\n\n if (ancestors.has(value)) {\n throw new TypeError('Runtime query input must not contain circular references');\n }\n\n ancestors.add(value);\n try {\n if (Array.isArray(value)) {\n return value.map((item) => normalizeValue(item, ancestors));\n }\n\n const record = value as Record<string, unknown>;\n return Object.keys(record)\n .sort()\n .reduce<Record<string, unknown>>((normalized, key) => {\n const item = record[key];\n if (item !== undefined) {\n normalized[key] = normalizeValue(item, ancestors);\n }\n return normalized;\n }, {});\n } finally {\n ancestors.delete(value);\n }\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport {\n AXPCommonSettings,\n AXPSettingsService,\n AXP_RUNTIME_QUERY_CACHE_DEFAULTS,\n coerceAXPSettingRawValueByKind,\n} from '@acorex-platform/framework-client/common';\nimport { AXPDebugService } from '@acorex-platform/framework-client/core';\nimport type { AXPQueryExecuteOptions } from '@acorex-platform/framework-shared/runtime';\nimport { inject, Injectable } from '@angular/core';\n\nimport type { AXCRuntimeQueryResult } from './runtime-api.types';\nimport { stableSerializeRuntimeQueryInput } from './runtime-query-cache-key.util';\n\n//#endregion\n\n//#region ----- Types & Constants -----\n\ninterface AXCRuntimeQueryCacheEntry {\n expiresAt: number;\n originStack?: string;\n result: AXCRuntimeQueryResult;\n storedAt: number;\n}\n\ninterface AXCRuntimeQueryInFlightEntry {\n originStack?: string;\n promise: Promise<AXCRuntimeQueryResult>;\n startedAt: number;\n}\n\ntype AXCRuntimeQueryDuplicateType = 'in-flight-coalesced' | 'ttl-cache-hit';\n\ninterface AXCRuntimeQueryDuplicateStat {\n callerLabel?: string;\n coalescedCount: number;\n duplicateStacks: string[];\n firstAt: number;\n input: unknown;\n lastAt: number;\n maxOriginAgeMs: number;\n name: string;\n originStack?: string;\n reusedCount: number;\n target: string;\n}\n\nconst MAX_CACHE_ENTRIES = 250;\nconst DEBUG_NAMESPACE = 'runtime-query-cache';\n\n/** Duplicates are collected for this window, then reported as one line per request. */\nconst DUPLICATE_REPORT_WINDOW_MS = 1_000;\nconst MAX_TRACKED_DUPLICATE_REQUESTS = 50;\nconst MAX_STACK_FRAMES = 8;\nconst MAX_DUPLICATE_STACK_SAMPLES = 3;\nconst MAX_TARGET_LENGTH = 120;\nconst MAX_FILTER_FIELDS = 3;\nconst MAX_FILTER_DEPTH = 3;\n\n/** Gateway frames that hide the real caller in captured stacks. */\nconst GATEWAY_STACK_FRAME_PATTERN =\n /AXCRuntimeQueryCacheService|AXCRuntimeApiService\\.(executeQuery|sendQuery)|runtime-query-cache/;\n\n/** Async/zone plumbing frames that carry no call-site information. */\nconst PLUMBING_STACK_FRAME_PATTERN =\n /zone\\.js|Zone[A-Za-z]*\\.|ZoneAwarePromise|asyncGeneratorStep|_?asyncToGenerator|__awaiter|Generator\\.|Object\\.next|drainMicroTaskQueue|processTicksAndRejections/;\n\n//#endregion\n\n//#region ----- Runtime Query Cache -----\n\n/**\n * Coalesces identical in-flight runtime queries and optionally reuses successful\n * responses for a short platform-configured TTL.\n */\n@Injectable()\nexport class AXCRuntimeQueryCacheService {\n //#region ----- Services & Dependencies -----\n\n private readonly settings = inject(AXPSettingsService);\n private readonly debug = inject(AXPDebugService);\n\n //#endregion\n\n //#region ----- State -----\n\n private readonly inFlight = new Map<string, AXCRuntimeQueryInFlightEntry>();\n private readonly responses = new Map<string, AXCRuntimeQueryCacheEntry>();\n private readonly duplicates = new Map<string, AXCRuntimeQueryDuplicateStat>();\n private duplicateReportHandle: ReturnType<typeof setTimeout> | undefined;\n private generation = 0;\n\n //#endregion\n\n constructor() {\n this.settings.onLoaded.subscribe(() => this.clear());\n this.settings.onChanged.subscribe((event) => {\n if (\n event.keys.includes(AXPCommonSettings.RuntimeQueryCacheEnabled) ||\n event.keys.includes(AXPCommonSettings.RuntimeQueryCacheTtlMs)\n ) {\n this.clear();\n }\n });\n }\n\n //#region ----- Public API -----\n\n execute(\n name: string,\n input: unknown,\n request: () => Promise<AXCRuntimeQueryResult>,\n options?: AXPQueryExecuteOptions,\n ): Promise<AXCRuntimeQueryResult> {\n if (!this.isEnabled()) {\n return request();\n }\n\n const optionsKey =\n options != null && Object.keys(options).length > 0\n ? stableSerializeRuntimeQueryInput(options)\n : '';\n const key = `${name}|${stableSerializeRuntimeQueryInput(input ?? {})}|${optionsKey}`;\n const now = Date.now();\n const cached = this.responses.get(key);\n if (cached) {\n if (cached.expiresAt > now) {\n this.recordDuplicate({\n duplicateStack: this.captureCallerStack(),\n input,\n key,\n name,\n originAgeMs: now - cached.storedAt,\n originStack: cached.originStack,\n type: 'ttl-cache-hit',\n });\n return Promise.resolve(cached.result);\n }\n this.responses.delete(key);\n }\n\n const existing = this.inFlight.get(key);\n if (existing) {\n this.recordDuplicate({\n duplicateStack: this.captureCallerStack(),\n input,\n key,\n name,\n originAgeMs: now - existing.startedAt,\n originStack: existing.originStack,\n type: 'in-flight-coalesced',\n });\n return existing.promise;\n }\n\n const generation = this.generation;\n const ttlMs = this.getTtlMs();\n const originStack = this.captureCallerStack();\n const task = request()\n .then((result) => {\n if (\n result.success &&\n ttlMs > 0 &&\n generation === this.generation &&\n this.isEnabled()\n ) {\n this.storeResponse(key, result, ttlMs, originStack);\n }\n return result;\n })\n .finally(() => {\n if (this.inFlight.get(key)?.promise === task) {\n this.inFlight.delete(key);\n }\n });\n\n this.inFlight.set(key, {\n originStack,\n promise: task,\n startedAt: now,\n });\n return task;\n }\n\n /**\n * Invalidates completed responses and prevents older in-flight queries from\n * repopulating the cache after a command or configuration change.\n */\n clear(): void {\n this.generation += 1;\n this.responses.clear();\n this.inFlight.clear();\n this.reportDuplicates();\n }\n\n //#endregion\n\n //#region ----- Settings -----\n\n private isEnabled(): boolean {\n const raw = this.settings.peekCached(AXPCommonSettings.RuntimeQueryCacheEnabled);\n return raw === undefined\n ? AXP_RUNTIME_QUERY_CACHE_DEFAULTS.enabled\n : (coerceAXPSettingRawValueByKind(raw, 'boolean') as boolean);\n }\n\n private getTtlMs(): number {\n const raw = this.settings.peekCached(AXPCommonSettings.RuntimeQueryCacheTtlMs);\n const value =\n raw === undefined\n ? AXP_RUNTIME_QUERY_CACHE_DEFAULTS.ttlMs\n : (coerceAXPSettingRawValueByKind(raw, 'number') as number);\n return Number.isFinite(value) ? Math.max(0, value) : AXP_RUNTIME_QUERY_CACHE_DEFAULTS.ttlMs;\n }\n\n //#endregion\n\n //#region ----- Cache Maintenance -----\n\n private storeResponse(\n key: string,\n result: AXCRuntimeQueryResult,\n ttlMs: number,\n originStack?: string,\n ): void {\n this.pruneExpired();\n if (this.responses.size >= MAX_CACHE_ENTRIES) {\n const oldestKey = this.responses.keys().next().value as string | undefined;\n if (oldestKey) {\n this.responses.delete(oldestKey);\n }\n }\n const storedAt = Date.now();\n this.responses.set(key, {\n result,\n expiresAt: storedAt + ttlMs,\n originStack,\n storedAt,\n });\n }\n\n private pruneExpired(): void {\n const now = Date.now();\n for (const [key, entry] of this.responses) {\n if (entry.expiresAt <= now) {\n this.responses.delete(key);\n }\n }\n }\n\n //#endregion\n\n //#region ----- Debug Diagnostics -----\n\n private captureCallerStack(): string | undefined {\n if (!this.debug.isDebugMode()) {\n return undefined;\n }\n\n const frames = (new Error().stack?.split('\\n') ?? [])\n .map((frame) => frame.trim())\n .filter(\n (frame) =>\n frame.length > 0 && frame !== 'Error' && !GATEWAY_STACK_FRAME_PATTERN.test(frame),\n );\n const callSites = frames.filter((frame) => !PLUMBING_STACK_FRAME_PATTERN.test(frame));\n const selected = (callSites.length > 0 ? callSites : frames).slice(0, MAX_STACK_FRAMES);\n\n return selected.length > 0 ? selected.join('\\n') : undefined;\n }\n\n private recordDuplicate(details: {\n duplicateStack?: string;\n input: unknown;\n key: string;\n name: string;\n originAgeMs: number;\n originStack?: string;\n type: AXCRuntimeQueryDuplicateType;\n }): void {\n if (!this.debug.isDebugMode()) {\n return;\n }\n\n const now = Date.now();\n let stat = this.duplicates.get(details.key);\n if (!stat) {\n stat = {\n callerLabel: this.describeCaller(details.duplicateStack ?? details.originStack),\n coalescedCount: 0,\n duplicateStacks: [],\n firstAt: now,\n input: details.input,\n lastAt: now,\n maxOriginAgeMs: 0,\n name: details.name,\n originStack: details.originStack,\n reusedCount: 0,\n target: this.describeTarget(details.input),\n };\n this.duplicates.set(details.key, stat);\n }\n\n stat.lastAt = now;\n stat.maxOriginAgeMs = Math.max(stat.maxOriginAgeMs, Math.round(details.originAgeMs));\n if (details.type === 'in-flight-coalesced') {\n stat.coalescedCount += 1;\n } else {\n stat.reusedCount += 1;\n }\n\n if (\n details.duplicateStack &&\n stat.duplicateStacks.length < MAX_DUPLICATE_STACK_SAMPLES &&\n !stat.duplicateStacks.includes(details.duplicateStack)\n ) {\n stat.duplicateStacks.push(details.duplicateStack);\n }\n\n if (this.duplicates.size >= MAX_TRACKED_DUPLICATE_REQUESTS) {\n this.reportDuplicates();\n return;\n }\n\n this.duplicateReportHandle ??= setTimeout(\n () => this.reportDuplicates(),\n DUPLICATE_REPORT_WINDOW_MS,\n );\n }\n\n /** Emits one warning per duplicated request, with every key value inline in the message. */\n private reportDuplicates(): void {\n if (this.duplicateReportHandle !== undefined) {\n clearTimeout(this.duplicateReportHandle);\n this.duplicateReportHandle = undefined;\n }\n\n const stats = [...this.duplicates.values()].sort(\n (left, right) =>\n right.coalescedCount + right.reusedCount - (left.coalescedCount + left.reusedCount),\n );\n this.duplicates.clear();\n if (stats.length === 0) {\n return;\n }\n\n const totalCalls = stats.reduce(\n (total, stat) => total + stat.coalescedCount + stat.reusedCount,\n 0,\n );\n\n if (stats.length > 1) {\n this.debug.warn(\n DEBUG_NAMESPACE,\n 'duplicates',\n `${totalCalls} duplicate calls suppressed · ${stats.length} distinct requests · last ${DUPLICATE_REPORT_WINDOW_MS}ms`,\n );\n }\n\n for (const stat of stats) {\n const count = stat.coalescedCount + stat.reusedCount;\n const segments = [\n `×${count} duplicate ${count === 1 ? 'call' : 'calls'}`,\n stat.target,\n `coalesced ${stat.coalescedCount} / from memory ${stat.reusedCount}`,\n `burst ${Math.max(0, stat.lastAt - stat.firstAt)}ms`,\n `origin age ≤${stat.maxOriginAgeMs}ms`,\n ];\n if (stat.callerLabel) {\n segments.push(`caller ${stat.callerLabel}`);\n }\n\n this.debug.warn(DEBUG_NAMESPACE, stat.name, segments.join(' · '), () => ({\n duplicateStacks: stat.duplicateStacks,\n input: stat.input,\n originalCallStack: stat.originStack,\n }));\n }\n }\n\n /** First meaningful frame, e.g. `AXPLookupEditorWidgetColumn.loadTitle`. */\n private describeCaller(stack?: string): string | undefined {\n const frame = stack?.split('\\n')[0];\n if (!frame) {\n return undefined;\n }\n\n return frame.match(/^at\\s+([\\w$.<>]+)/)?.[1] ?? frame.match(/^([\\w$.<>]+)@/)?.[1];\n }\n\n private describeTarget(input: unknown): string {\n if (input === undefined || input === null) {\n return 'no input';\n }\n\n if (typeof input !== 'object') {\n return String(input);\n }\n\n const record = input as Record<string, unknown>;\n const pick = (...keys: string[]): string | undefined =>\n keys.map((key) => record[key]).find((value): value is string => typeof value === 'string');\n\n const entity = pick('entity', 'entityName', 'entityType');\n const id = pick('id', 'entityId', 'key');\n const view = pick('view', 'viewName', 'queryName');\n const filterFields = this.collectFilterFields(record['filter']);\n const segments = [\n entity,\n id ? `#${id.slice(0, 8)}` : undefined,\n view ? `view=${view}` : undefined,\n filterFields.length > 0 ? `filter=${filterFields.join(',')}` : undefined,\n typeof record['take'] === 'number' ? `take=${record['take']}` : undefined,\n ].filter((segment): segment is string => !!segment);\n if (segments.length > 0) {\n return segments.join(' ');\n }\n\n const serialized = stableSerializeRuntimeQueryInput(input);\n return serialized.length > MAX_TARGET_LENGTH\n ? `${serialized.slice(0, MAX_TARGET_LENGTH - 1)}…`\n : serialized;\n }\n\n private collectFilterFields(filter: unknown, depth = 0): string[] {\n if (depth > MAX_FILTER_DEPTH || filter == null || typeof filter !== 'object') {\n return [];\n }\n\n const record = filter as Record<string, unknown>;\n if (typeof record['field'] === 'string') {\n return [record['field']];\n }\n\n const nested = Array.isArray(record['filters']) ? (record['filters'] as unknown[]) : [];\n const fields = nested.flatMap((child) => this.collectFilterFields(child, depth + 1));\n return [...new Set(fields)].slice(0, MAX_FILTER_FIELDS);\n }\n\n //#endregion\n}\n\n//#endregion\n","import { AXP_ROOT_CONFIG_TOKEN } from '@acorex-platform/framework-client/common';\nimport {\n buildRuntimeInvokeQueryString,\n type AXPCommandExecuteOptions,\n type AXPQueryExecuteOptions,\n} from '@acorex-platform/framework-shared/runtime';\nimport { HttpClient, HttpHeaders } from '@angular/common/http';\nimport { inject, Injectable } from '@angular/core';\nimport { catchError, firstValueFrom, throwError } from 'rxjs';\nimport { skipAuthRetryHeadersForRuntime } from '../http/api-http-auth.util';\nimport { mapHttpErrorResponseToAXPRequestError } from '../http/map-http-error-to-request-error.util';\nimport { AXCRuntimeQueryCacheService } from './runtime-query-cache.service';\nimport type {\n AXCRuntimeBulkCommandRequest,\n AXCRuntimeBulkCommandResult,\n AXCRuntimeCommandResult,\n AXCRuntimeQueryResult,\n} from './runtime-api.types';\n\n//#region ---- Runtime API service ----\n\n/**\n * HTTP client for platform runtime command/query endpoints.\n * Transport failures are normalized to {@link AXPRequestError}.\n */\n@Injectable()\nexport class AXCRuntimeApiService {\n private readonly http = inject(HttpClient);\n private readonly configs = inject(AXP_ROOT_CONFIG_TOKEN);\n private readonly queryCache = inject(AXCRuntimeQueryCacheService);\n\n private runtimeUrl(kind: 'commands' | 'commands/bulk' | 'queries'): string {\n return `${this.configs.baseUrl}/v1/runtime/${kind}`;\n }\n\n /**\n * Single command/query invoke — key (and entity for `Entity:*:Default`) in the\n * query string so DevTools shows the operation without `%3A` noise.\n */\n private runtimeInvokeUrl(kind: 'commands' | 'queries', name: string, input?: unknown): string {\n const query = buildRuntimeInvokeQueryString(name, input);\n return `${this.configs.baseUrl}/v1/runtime/${kind}/invoke?${query}`;\n }\n\n executeCommand(\n name: string,\n input?: unknown,\n options?: AXPCommandExecuteOptions,\n ): Promise<AXCRuntimeCommandResult> {\n const skipAuthRetry = skipAuthRetryHeadersForRuntime(name, 'command');\n const headers = skipAuthRetry ? new HttpHeaders(skipAuthRetry) : undefined;\n const hasOptions = options != null && Object.keys(options).length > 0;\n\n const request$ = hasOptions\n ? this.http.post<AXCRuntimeCommandResult>(\n this.runtimeUrl('commands'),\n { name, input: input ?? {}, options },\n { withCredentials: true, ...(headers ? { headers } : undefined) },\n )\n : this.http.post<AXCRuntimeCommandResult>(\n this.runtimeInvokeUrl('commands', name, input),\n input ?? {},\n { withCredentials: true, ...(headers ? { headers } : undefined) },\n );\n\n return firstValueFrom(\n request$.pipe(catchError((error) => throwError(() => mapHttpErrorResponseToAXPRequestError(error)))),\n ).then((result) => {\n if (result.success) {\n this.queryCache.clear();\n }\n return result;\n });\n }\n\n executeBulkCommand(request: AXCRuntimeBulkCommandRequest): Promise<AXCRuntimeBulkCommandResult> {\n return firstValueFrom(\n this.http\n .post<AXCRuntimeBulkCommandResult>(this.runtimeUrl('commands/bulk'), request, {\n withCredentials: true,\n })\n .pipe(catchError((error) => throwError(() => mapHttpErrorResponseToAXPRequestError(error)))),\n ).then((result) => {\n if (result.success) {\n this.queryCache.clear();\n }\n return result;\n });\n }\n\n executeQuery(\n name: string,\n input?: unknown,\n options?: AXPQueryExecuteOptions,\n ): Promise<AXCRuntimeQueryResult> {\n return this.queryCache.execute(name, input, () => this.sendQuery(name, input, options), options);\n }\n\n private sendQuery(\n name: string,\n input?: unknown,\n options?: AXPQueryExecuteOptions,\n ): Promise<AXCRuntimeQueryResult> {\n const skipAuthRetry = skipAuthRetryHeadersForRuntime(name, 'query');\n const headers = skipAuthRetry ? new HttpHeaders(skipAuthRetry) : undefined;\n const hasOptions = options != null && Object.keys(options).length > 0;\n\n // Named body carries `options`; invoke keeps body = input only for DevTools-friendly URLs.\n const request$ = hasOptions\n ? this.http.post<AXCRuntimeQueryResult>(\n this.runtimeUrl('queries'),\n { name, input: input ?? {}, options },\n { withCredentials: true, ...(headers ? { headers } : undefined) },\n )\n : this.http.post<AXCRuntimeQueryResult>(\n this.runtimeInvokeUrl('queries', name, input),\n input ?? {},\n { withCredentials: true, ...(headers ? { headers } : undefined) },\n );\n\n return firstValueFrom(\n request$.pipe(catchError((error) => throwError(() => mapHttpErrorResponseToAXPRequestError(error)))),\n );\n }\n}\n\n//#endregion\n","import {\n AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER,\n type AXPDistributedEventListenerProvider,\n} from '@acorex-platform/framework-client/core';\nimport {\n AXPRuntimeRemoteHookKeys,\n type AXPRuntimeCommandExecuteBulkHookPayload,\n type AXPRuntimeCommandExecuteHookPayload,\n type AXPRuntimeQueryExecuteHookPayload,\n} from '@acorex-platform/framework-client/runtime';\nimport { AXPRequestError } from '@acorex-platform/framework-shared/core';\nimport { inject, type Provider } from '@angular/core';\nimport { AXCRuntimeApiService } from './runtime-api.service';\nimport { AXCRuntimeQueryCacheService } from './runtime-query-cache.service';\nimport type { AXCRuntimeQueryResult } from './runtime-api.types';\n\n//#region ---- Unwrap helpers ----\n\n/**\n * Map server runtime query envelope to the value local {@code query.fetch} would return.\n *\n * - success: false → throw using `message`\n * - kind: 'value' | 'object' | 'collection' → `data`\n */\nexport function unwrapRuntimeQueryResult(result: AXCRuntimeQueryResult): unknown {\n if (!result.success) {\n const message = result.message;\n const text =\n typeof message?.text === 'string'\n ? message.text\n : message?.code || 'Query execution failed';\n throw new AXPRequestError(text, {\n code: message?.code,\n details: message?.details,\n });\n }\n\n if (result.kind === 'collection' || result.kind === 'object' || result.kind === 'value') {\n return result.data;\n }\n\n return result;\n}\n\n//#endregion\n\n//#region ---- Hook providers ----\n\nexport const AXCRuntimeCommandExecuteHookProvider: AXPDistributedEventListenerProvider<\n AXPRuntimeCommandExecuteHookPayload,\n AXPRuntimeCommandExecuteHookPayload\n> = {\n key: AXPRuntimeRemoteHookKeys.CommandExecute,\n async execute(payload) {\n if (payload.handled) {\n return payload;\n }\n const api = inject(AXCRuntimeApiService);\n const result = await api.executeCommand(payload.name, payload.input, payload.options);\n return { ...payload, handled: true, result };\n },\n};\n\nexport const AXCRuntimeCommandExecuteBulkHookProvider: AXPDistributedEventListenerProvider<\n AXPRuntimeCommandExecuteBulkHookPayload,\n AXPRuntimeCommandExecuteBulkHookPayload\n> = {\n key: AXPRuntimeRemoteHookKeys.CommandExecuteBulk,\n async execute(payload) {\n if (payload.handled) {\n return payload;\n }\n const api = inject(AXCRuntimeApiService);\n const result = await api.executeBulkCommand(payload.request);\n return { ...payload, handled: true, result };\n },\n};\n\nexport const AXCRuntimeQueryExecuteHookProvider: AXPDistributedEventListenerProvider<\n AXPRuntimeQueryExecuteHookPayload,\n AXPRuntimeQueryExecuteHookPayload\n> = {\n key: AXPRuntimeRemoteHookKeys.QueryExecute,\n async execute(payload) {\n if (payload.handled) {\n return payload;\n }\n const api = inject(AXCRuntimeApiService);\n const response = await api.executeQuery(payload.name, payload.input, payload.options);\n // Keep the wire envelope — same contract as local AXPQuery.fetch / command execute.\n return {\n ...payload,\n handled: true,\n result: response,\n };\n },\n};\n\nexport const AXC_RUNTIME_REMOTE_HOOK_PROVIDERS: Provider[] = [\n AXCRuntimeQueryCacheService,\n AXCRuntimeApiService,\n {\n provide: AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER,\n useValue: AXCRuntimeCommandExecuteHookProvider,\n multi: true,\n },\n {\n provide: AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER,\n useValue: AXCRuntimeCommandExecuteBulkHookProvider,\n multi: true,\n },\n {\n provide: AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER,\n useValue: AXCRuntimeQueryExecuteHookProvider,\n multi: true,\n },\n];\n\n//#endregion\n","//#region ----- Imports -----\n\nimport type { Provider } from '@angular/core';\nimport { AXC_RUNTIME_REMOTE_HOOK_PROVIDERS } from './runtime-remote.hooks';\n\n//#endregion\n\n//#region ----- Provider factory -----\n\n/**\n * Nest / demo-api CQRS transport: `runtime.query.execute`, `runtime.command.execute`,\n * and `runtime.command.execute-bulk` against `{AXP_ROOT_CONFIG_TOKEN.baseUrl}/v1/runtime/*`.\n *\n * Official hosts that import `AXMSettingsManagementModule` get this automatically.\n * Custom API stacks should use `provideExternalRuntimeQueryTransport` /\n * `provideExternalRuntimeCommandTransport` / `provideExternalRuntimeBulkTransport` instead.\n */\nexport function provideRuntimeRemoteTransport(): Provider[] {\n return [...AXC_RUNTIME_REMOTE_HOOK_PROVIDERS];\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { NgModule } from '@angular/core';\nimport { provideRuntimeRemoteTransport } from './provide-runtime-remote-transport';\n\n//#endregion\n\n//#region ----- Module -----\n\n/**\n * Registers the Nest runtime CQRS hooks used when a query/command is not in\n * {@code provideQuerySetups} / {@code provideCommandSetups}.\n *\n * Requires {@link AXP_ROOT_CONFIG_TOKEN} (`baseUrl`, typically `/api`) and Angular\n * {@code HttpClient}.\n */\n@NgModule({\n providers: provideRuntimeRemoteTransport(),\n})\nexport class AXCRuntimeRemoteApiModule {}\n\n//#endregion\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["catchError"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@acorex-platform/client-connectivity-api",
3
+ "version": "0.0.28",
4
+ "sideEffects": false,
5
+ "peerDependencies": {
6
+ "@acorex-platform/framework-client": "0.0.28",
7
+ "@acorex-platform/framework-shared": "0.0.28",
8
+ "@angular/common": "^21.0.0 || ^22.0.0",
9
+ "@angular/core": "^21.0.0 || ^22.0.0",
10
+ "rxjs": "^7.8.0"
11
+ },
12
+ "dependencies": {
13
+ "tslib": "^2.3.0"
14
+ },
15
+ "module": "fesm2022/acorex-platform-client-connectivity-api.mjs",
16
+ "typings": "types/acorex-platform-client-connectivity-api.d.ts",
17
+ "exports": {
18
+ "./package.json": {
19
+ "default": "./package.json"
20
+ },
21
+ ".": {
22
+ "types": "./types/acorex-platform-client-connectivity-api.d.ts",
23
+ "default": "./fesm2022/acorex-platform-client-connectivity-api.mjs"
24
+ }
25
+ },
26
+ "type": "module"
27
+ }
@@ -0,0 +1,151 @@
1
+ import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http';
2
+ import { Observable } from 'rxjs';
3
+ import * as i0 from '@angular/core';
4
+ import { Provider } from '@angular/core';
5
+ import { AXPRequestError, AXPRuntimeCommandResult, AXPRuntimeQueryResult } from '@acorex-platform/framework-shared/core';
6
+ import { AXPBulkCommandRequest, AXPBulkCommandResultData, AXPCommandExecuteOptions, AXPQueryExecuteOptions } from '@acorex-platform/framework-shared/runtime';
7
+ import { AXPDistributedEventListenerProvider } from '@acorex-platform/framework-client/core';
8
+ import { AXPRuntimeCommandExecuteBulkHookPayload, AXPRuntimeCommandExecuteHookPayload, AXPRuntimeQueryExecuteHookPayload } from '@acorex-platform/framework-client/runtime';
9
+
10
+ /**
11
+ * Retries transient connectivity failures (status 0, 502, 503, 504) for idempotent
12
+ * platform API calls: GET/HEAD and read-only POST runtime queries.
13
+ */
14
+ declare class AXCApiHttpRetryInterceptor implements HttpInterceptor {
15
+ intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>>;
16
+ private sendWithRetry;
17
+ static ɵfac: i0.ɵɵFactoryDeclaration<AXCApiHttpRetryInterceptor, never>;
18
+ static ɵprov: i0.ɵɵInjectableDeclaration<AXCApiHttpRetryInterceptor>;
19
+ }
20
+
21
+ declare class AXCApiHttpModule {
22
+ static ɵfac: i0.ɵɵFactoryDeclaration<AXCApiHttpModule, never>;
23
+ static ɵmod: i0.ɵɵNgModuleDeclaration<AXCApiHttpModule, never, never, never>;
24
+ static ɵinj: i0.ɵɵInjectorDeclaration<AXCApiHttpModule>;
25
+ }
26
+
27
+ /** Client-only marker: do not refresh/retry auth HTTP when this request fails. */
28
+ declare const API_SKIP_AUTH_RETRY_HEADER = "X-Skip-Auth-Retry";
29
+ declare function isAuthRuntimeCommandKey(name: string): boolean;
30
+ declare function isAuthRuntimeQueryKey(name: string): boolean;
31
+ /** Headers for auth runtime transport calls (prevents 401 refresh loops). */
32
+ declare function skipAuthRetryHeadersForRuntime(name: string, kind: 'command' | 'query'): Record<string, string> | undefined;
33
+ /**
34
+ * True when the request is part of the auth flow and must not trigger token refresh
35
+ * or transient HTTP retry (legacy `/v1/auth/*`, runtime auth keys, or explicit header).
36
+ */
37
+ declare function isAuthHttpRequest(request: HttpRequest<unknown>): boolean;
38
+
39
+ declare const API_HTTP_RETRY_MAX_ATTEMPTS = 5;
40
+ declare const API_HTTP_RETRY_BASE_MS = 400;
41
+ declare function apiHttpRetryDelayMs(attempt: number): number;
42
+ /** GET/HEAD and read-only POST queries — safe to retry when the server may not have responded. */
43
+ declare function isSafeToRetryHttpRequest(request: HttpRequest<unknown>): boolean;
44
+ declare function isRetriableHttpError(error: HttpErrorResponse, request: HttpRequest<unknown>, attempt: number): boolean;
45
+
46
+ /**
47
+ * Normalize Angular HTTP failures into transport-agnostic {@link AXPRequestError}.
48
+ * Call only from connectivity adapters (REST today; gRPC/GraphQL later).
49
+ */
50
+ declare function mapHttpErrorResponseToAXPRequestError(error: unknown): AXPRequestError;
51
+
52
+ /**
53
+ * Nest / demo-api CQRS transport: `runtime.query.execute`, `runtime.command.execute`,
54
+ * and `runtime.command.execute-bulk` against `{AXP_ROOT_CONFIG_TOKEN.baseUrl}/v1/runtime/*`.
55
+ *
56
+ * Official hosts that import `AXMSettingsManagementModule` get this automatically.
57
+ * Custom API stacks should use `provideExternalRuntimeQueryTransport` /
58
+ * `provideExternalRuntimeCommandTransport` / `provideExternalRuntimeBulkTransport` instead.
59
+ */
60
+ declare function provideRuntimeRemoteTransport(): Provider[];
61
+
62
+ /** Mirrors server `RuntimeQueryResult` / {@link AXPRuntimeQueryResult}. */
63
+ type AXCRuntimeQueryResult = AXPRuntimeQueryResult;
64
+ type AXCRuntimeCommandResult = AXPRuntimeCommandResult;
65
+ type AXCRuntimeBulkCommandRequest = AXPBulkCommandRequest;
66
+ type AXCRuntimeBulkCommandResult = AXPRuntimeCommandResult<AXPBulkCommandResultData>;
67
+
68
+ /**
69
+ * HTTP client for platform runtime command/query endpoints.
70
+ * Transport failures are normalized to {@link AXPRequestError}.
71
+ */
72
+ declare class AXCRuntimeApiService {
73
+ private readonly http;
74
+ private readonly configs;
75
+ private readonly queryCache;
76
+ private runtimeUrl;
77
+ /**
78
+ * Single command/query invoke — key (and entity for `Entity:*:Default`) in the
79
+ * query string so DevTools shows the operation without `%3A` noise.
80
+ */
81
+ private runtimeInvokeUrl;
82
+ executeCommand(name: string, input?: unknown, options?: AXPCommandExecuteOptions): Promise<AXCRuntimeCommandResult>;
83
+ executeBulkCommand(request: AXCRuntimeBulkCommandRequest): Promise<AXCRuntimeBulkCommandResult>;
84
+ executeQuery(name: string, input?: unknown, options?: AXPQueryExecuteOptions): Promise<AXCRuntimeQueryResult>;
85
+ private sendQuery;
86
+ static ɵfac: i0.ɵɵFactoryDeclaration<AXCRuntimeApiService, never>;
87
+ static ɵprov: i0.ɵɵInjectableDeclaration<AXCRuntimeApiService>;
88
+ }
89
+
90
+ /**
91
+ * Coalesces identical in-flight runtime queries and optionally reuses successful
92
+ * responses for a short platform-configured TTL.
93
+ */
94
+ declare class AXCRuntimeQueryCacheService {
95
+ private readonly settings;
96
+ private readonly debug;
97
+ private readonly inFlight;
98
+ private readonly responses;
99
+ private readonly duplicates;
100
+ private duplicateReportHandle;
101
+ private generation;
102
+ constructor();
103
+ execute(name: string, input: unknown, request: () => Promise<AXCRuntimeQueryResult>, options?: AXPQueryExecuteOptions): Promise<AXCRuntimeQueryResult>;
104
+ /**
105
+ * Invalidates completed responses and prevents older in-flight queries from
106
+ * repopulating the cache after a command or configuration change.
107
+ */
108
+ clear(): void;
109
+ private isEnabled;
110
+ private getTtlMs;
111
+ private storeResponse;
112
+ private pruneExpired;
113
+ private captureCallerStack;
114
+ private recordDuplicate;
115
+ /** Emits one warning per duplicated request, with every key value inline in the message. */
116
+ private reportDuplicates;
117
+ /** First meaningful frame, e.g. `AXPLookupEditorWidgetColumn.loadTitle`. */
118
+ private describeCaller;
119
+ private describeTarget;
120
+ private collectFilterFields;
121
+ static ɵfac: i0.ɵɵFactoryDeclaration<AXCRuntimeQueryCacheService, never>;
122
+ static ɵprov: i0.ɵɵInjectableDeclaration<AXCRuntimeQueryCacheService>;
123
+ }
124
+
125
+ /**
126
+ * Registers the Nest runtime CQRS hooks used when a query/command is not in
127
+ * {@code provideQuerySetups} / {@code provideCommandSetups}.
128
+ *
129
+ * Requires {@link AXP_ROOT_CONFIG_TOKEN} (`baseUrl`, typically `/api`) and Angular
130
+ * {@code HttpClient}.
131
+ */
132
+ declare class AXCRuntimeRemoteApiModule {
133
+ static ɵfac: i0.ɵɵFactoryDeclaration<AXCRuntimeRemoteApiModule, never>;
134
+ static ɵmod: i0.ɵɵNgModuleDeclaration<AXCRuntimeRemoteApiModule, never, never, never>;
135
+ static ɵinj: i0.ɵɵInjectorDeclaration<AXCRuntimeRemoteApiModule>;
136
+ }
137
+
138
+ /**
139
+ * Map server runtime query envelope to the value local {@code query.fetch} would return.
140
+ *
141
+ * - success: false → throw using `message`
142
+ * - kind: 'value' | 'object' | 'collection' → `data`
143
+ */
144
+ declare function unwrapRuntimeQueryResult(result: AXCRuntimeQueryResult): unknown;
145
+ declare const AXCRuntimeCommandExecuteHookProvider: AXPDistributedEventListenerProvider<AXPRuntimeCommandExecuteHookPayload, AXPRuntimeCommandExecuteHookPayload>;
146
+ declare const AXCRuntimeCommandExecuteBulkHookProvider: AXPDistributedEventListenerProvider<AXPRuntimeCommandExecuteBulkHookPayload, AXPRuntimeCommandExecuteBulkHookPayload>;
147
+ declare const AXCRuntimeQueryExecuteHookProvider: AXPDistributedEventListenerProvider<AXPRuntimeQueryExecuteHookPayload, AXPRuntimeQueryExecuteHookPayload>;
148
+ declare const AXC_RUNTIME_REMOTE_HOOK_PROVIDERS: Provider[];
149
+
150
+ export { API_HTTP_RETRY_BASE_MS, API_HTTP_RETRY_MAX_ATTEMPTS, API_SKIP_AUTH_RETRY_HEADER, AXCApiHttpModule, AXCApiHttpRetryInterceptor, AXCRuntimeApiService, AXCRuntimeCommandExecuteBulkHookProvider, AXCRuntimeCommandExecuteHookProvider, AXCRuntimeQueryCacheService, AXCRuntimeQueryExecuteHookProvider, AXCRuntimeRemoteApiModule, AXC_RUNTIME_REMOTE_HOOK_PROVIDERS, apiHttpRetryDelayMs, isAuthHttpRequest, isAuthRuntimeCommandKey, isAuthRuntimeQueryKey, isRetriableHttpError, isSafeToRetryHttpRequest, mapHttpErrorResponseToAXPRequestError, provideRuntimeRemoteTransport, skipAuthRetryHeadersForRuntime, unwrapRuntimeQueryResult };
151
+ export type { AXCRuntimeBulkCommandRequest, AXCRuntimeBulkCommandResult, AXCRuntimeCommandResult, AXCRuntimeQueryResult };