http-request-manager 18.16.26 → 18.16.29
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.
|
@@ -4259,10 +4259,8 @@ class HTTPManagerService extends RequestService {
|
|
|
4259
4259
|
handleSuccessWithSnackBar(message) {
|
|
4260
4260
|
const displaySuccess = ToastDisplay.adapt({
|
|
4261
4261
|
message: message || 'Success',
|
|
4262
|
-
action: 'OK',
|
|
4263
4262
|
color: ToastColors.SUCCESS,
|
|
4264
4263
|
icon: 'check_circle',
|
|
4265
|
-
duration: 3 * 1000, //3 seconds
|
|
4266
4264
|
});
|
|
4267
4265
|
this.toastMessage.toastMessage(displaySuccess);
|
|
4268
4266
|
}
|
|
@@ -5059,10 +5057,8 @@ class HTTPManagerSignalsService extends RequestSignalsService {
|
|
|
5059
5057
|
handleSuccessWithSnackBar(message) {
|
|
5060
5058
|
const displaySuccess = ToastDisplay.adapt({
|
|
5061
5059
|
message: message || 'Success',
|
|
5062
|
-
action: 'OK',
|
|
5063
5060
|
color: ToastColors.SUCCESS,
|
|
5064
5061
|
icon: 'check_circle',
|
|
5065
|
-
duration: 3 * 1000,
|
|
5066
5062
|
});
|
|
5067
5063
|
this.toastMessage.toastMessage(displaySuccess);
|
|
5068
5064
|
}
|
|
@@ -7231,19 +7227,16 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7231
7227
|
}
|
|
7232
7228
|
return this.httpManagerService.getRequest(requestOptions, effectiveParams).pipe(tap((data) => {
|
|
7233
7229
|
// Extract array from paginated response if needed
|
|
7230
|
+
// Data is already adapted by RequestService.request() pipe - no need to adapt again
|
|
7234
7231
|
const arrayData = (data?.results && Array.isArray(data.results)) ? data.results : data;
|
|
7235
|
-
|
|
7236
|
-
let adaptedData = this.applyAdapter(arrayData);
|
|
7237
|
-
adaptedData = (!adaptedData) ? (this.dataType === DataType.ARRAY) ? [] : {} : adaptedData;
|
|
7238
|
-
this.setData$(adaptedData);
|
|
7232
|
+
this.setData$(arrayData);
|
|
7239
7233
|
}), concatMap((data) => {
|
|
7240
7234
|
// Extract array from paginated response for database storage
|
|
7235
|
+
// Data is already adapted by RequestService.request() pipe - no need to adapt again
|
|
7241
7236
|
const dbData = (data?.results && Array.isArray(data.results)) ? data.results : data;
|
|
7242
|
-
|
|
7243
|
-
const adaptedDbData = this.applyAdapter(dbData);
|
|
7244
|
-
if (this.hasDatabase && this.databaseOptions?.table && Array.isArray(adaptedDbData) && adaptedDbData.length > 0) {
|
|
7237
|
+
if (this.hasDatabase && this.databaseOptions?.table && Array.isArray(dbData) && dbData.length > 0) {
|
|
7245
7238
|
const tableName = this.databaseOptions.table;
|
|
7246
|
-
const schema = this.buildSchemaFromSample(
|
|
7239
|
+
const schema = this.buildSchemaFromSample(dbData[0]);
|
|
7247
7240
|
const tableDef = TableSchemaDef.adapt({ table: tableName, schema });
|
|
7248
7241
|
const schemaSignature = this.buildSchemaSignature(schema);
|
|
7249
7242
|
// Always ensure table exists immediately before writing to avoid stale schema/store races.
|
|
@@ -7258,7 +7251,7 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7258
7251
|
console.warn('[DB STORAGE] Table create/open not ready, skipping DB write for this payload:', { table: tableName });
|
|
7259
7252
|
return of(data);
|
|
7260
7253
|
}
|
|
7261
|
-
return this.dbManagerService.createTableRecords(tableName,
|
|
7254
|
+
return this.dbManagerService.createTableRecords(tableName, dbData).pipe(tap(() => this.saveRequestCacheMetadata(tableName, 'GET', requestSignature, schemaSignature, options)));
|
|
7262
7255
|
}));
|
|
7263
7256
|
}), catchError((error) => {
|
|
7264
7257
|
console.error('[DB STORAGE] Failed to ensure table and write records:', { table: tableName, schema, error });
|
|
@@ -7371,14 +7364,14 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7371
7364
|
return this.httpManagerService.getRequest(requestOptions, effectiveParams)
|
|
7372
7365
|
.pipe(tap((data) => {
|
|
7373
7366
|
console.log('📦 fetchRecord received data:', data);
|
|
7374
|
-
//
|
|
7375
|
-
|
|
7376
|
-
|
|
7367
|
+
// Data is already adapted by RequestService.request() pipe - no need to adapt again
|
|
7368
|
+
const arrayData = (data?.results && Array.isArray(data.results)) ? data.results : data;
|
|
7369
|
+
const finalData = (!arrayData) ? (this.dataType === DataType.ARRAY) ? [] : {} : arrayData;
|
|
7377
7370
|
const id = options.path?.length ? options.path[options.path.length - 1] : null;
|
|
7378
7371
|
// For single-record operations (CREATE, UPDATE, DELETE), extract from array if needed
|
|
7379
|
-
let singleRecord =
|
|
7380
|
-
if (Array.isArray(
|
|
7381
|
-
singleRecord =
|
|
7372
|
+
let singleRecord = finalData;
|
|
7373
|
+
if (Array.isArray(finalData) && finalData.length > 0) {
|
|
7374
|
+
singleRecord = finalData[0];
|
|
7382
7375
|
}
|
|
7383
7376
|
if (method === 'DELETE') {
|
|
7384
7377
|
console.log('🗑️ Deleting record with id:', id);
|
|
@@ -7389,17 +7382,18 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7389
7382
|
this.updateData$(singleRecord);
|
|
7390
7383
|
}
|
|
7391
7384
|
if (method === 'CREATE') {
|
|
7392
|
-
console.log('➕ Adding record:',
|
|
7393
|
-
this.addData$(
|
|
7385
|
+
console.log('➕ Adding record:', finalData);
|
|
7386
|
+
this.addData$(finalData);
|
|
7394
7387
|
}
|
|
7395
7388
|
}), concatMap((data) => {
|
|
7396
|
-
|
|
7389
|
+
// Data is already adapted by RequestService.request() pipe - no need to adapt again
|
|
7390
|
+
const dbData = (data?.results && Array.isArray(data.results)) ? data.results : data;
|
|
7397
7391
|
const tableName = this.databaseOptions?.table;
|
|
7398
7392
|
const idFromPath = options.path?.length ? options.path[options.path.length - 1] : null;
|
|
7399
7393
|
// For single-record operations, extract from array if needed
|
|
7400
|
-
let singleRecord =
|
|
7401
|
-
if (Array.isArray(
|
|
7402
|
-
singleRecord =
|
|
7394
|
+
let singleRecord = dbData;
|
|
7395
|
+
if (Array.isArray(dbData) && dbData.length > 0) {
|
|
7396
|
+
singleRecord = dbData[0];
|
|
7403
7397
|
}
|
|
7404
7398
|
if (this.hasDatabase && tableName) {
|
|
7405
7399
|
switch (method) {
|
|
@@ -7418,11 +7412,11 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7418
7412
|
this.logger.warn('fetchRecord', 'UPDATE method called but singleRecord or id is missing', { singleRecord, hasData: !!singleRecord, hasId: !!singleRecord?.id });
|
|
7419
7413
|
break;
|
|
7420
7414
|
case 'CREATE':
|
|
7421
|
-
if (
|
|
7422
|
-
this.logger.debug('fetchRecord', 'Creating database record', { table: tableName, id:
|
|
7423
|
-
return this.dbManagerService.createTableRecord(tableName,
|
|
7415
|
+
if (dbData && dbData.id != null && dbData.id !== '') {
|
|
7416
|
+
this.logger.debug('fetchRecord', 'Creating database record', { table: tableName, id: dbData.id, data: dbData });
|
|
7417
|
+
return this.dbManagerService.createTableRecord(tableName, dbData);
|
|
7424
7418
|
}
|
|
7425
|
-
this.logger.warn('fetchRecord', 'CREATE method called but data.id is invalid', {
|
|
7419
|
+
this.logger.warn('fetchRecord', 'CREATE method called but data.id is invalid', { dbData });
|
|
7426
7420
|
break;
|
|
7427
7421
|
default:
|
|
7428
7422
|
this.logger.debug('fetchRecord', 'Method does not require database operation', { method });
|
|
@@ -7434,7 +7428,7 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7434
7428
|
hasTable: !!tableName
|
|
7435
7429
|
});
|
|
7436
7430
|
}
|
|
7437
|
-
return of(
|
|
7431
|
+
return of(dbData);
|
|
7438
7432
|
}));
|
|
7439
7433
|
})));
|
|
7440
7434
|
// CREATE RECORD
|
|
@@ -7443,17 +7437,13 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7443
7437
|
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
7444
7438
|
const effectiveParams = this.getEffectiveParams(options?.path);
|
|
7445
7439
|
return this.httpManagerService.postRequest(data, requestOptions, effectiveParams)
|
|
7446
|
-
.pipe(tap((
|
|
7447
|
-
//
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
this.addData$(adaptedData);
|
|
7440
|
+
.pipe(tap((adaptedData) => {
|
|
7441
|
+
// Data is already adapted by RequestService
|
|
7442
|
+
const safeData = (!adaptedData) ? (this.dataType === DataType.ARRAY ? [] : {}) : adaptedData;
|
|
7443
|
+
this.addData$(safeData);
|
|
7451
7444
|
this.operationSuccess.next(OperationResultModel.adapt({ success: true, operation: 'CREATE' }));
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
}), concatMap((data) => {
|
|
7455
|
-
// Apply adapter before database operations
|
|
7456
|
-
const adaptedData = this.applyAdapter(data);
|
|
7445
|
+
this.wsCommunication('CREATE', [...options?.path || [], safeData.id]);
|
|
7446
|
+
}), concatMap((adaptedData) => {
|
|
7457
7447
|
if (this.hasDatabase && this.databaseOptions?.table && adaptedData?.id) {
|
|
7458
7448
|
return this.dbManagerService.createTableRecord(this.databaseOptions.table, adaptedData);
|
|
7459
7449
|
}
|
|
@@ -7466,17 +7456,13 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7466
7456
|
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
7467
7457
|
const effectiveParams = this.getEffectiveParams(options?.path);
|
|
7468
7458
|
return this.httpManagerService.putRequest(data, requestOptions, effectiveParams)
|
|
7469
|
-
.pipe(tap((
|
|
7470
|
-
//
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
this.updateData$(adaptedData);
|
|
7459
|
+
.pipe(tap((adaptedData) => {
|
|
7460
|
+
// Data is already adapted by RequestService
|
|
7461
|
+
const safeData = (!adaptedData) ? (this.dataType === DataType.ARRAY ? [] : {}) : adaptedData;
|
|
7462
|
+
this.updateData$(safeData);
|
|
7474
7463
|
this.operationSuccess.next(OperationResultModel.adapt({ success: true, operation: 'UPDATE' }));
|
|
7475
|
-
// Always call wsCommunication - it will queue if not connected
|
|
7476
7464
|
this.wsCommunication('UPDATE', [...options?.path || []]);
|
|
7477
|
-
}), concatMap((
|
|
7478
|
-
// Apply adapter before database operations
|
|
7479
|
-
const adaptedData = this.applyAdapter(data);
|
|
7465
|
+
}), concatMap((adaptedData) => {
|
|
7480
7466
|
if (this.hasDatabase && this.databaseOptions?.table && adaptedData?.id) {
|
|
7481
7467
|
return this.dbManagerService.updateTableRecord(this.databaseOptions.table, adaptedData);
|
|
7482
7468
|
}
|
|
@@ -7489,17 +7475,13 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7489
7475
|
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
7490
7476
|
const effectiveParams = this.getEffectiveParams(options?.path);
|
|
7491
7477
|
return this.httpManagerService.deleteRequest(requestOptions, effectiveParams)
|
|
7492
|
-
.pipe(tap((
|
|
7493
|
-
//
|
|
7494
|
-
|
|
7495
|
-
|
|
7496
|
-
this.deleteData$(adaptedData);
|
|
7478
|
+
.pipe(tap((adaptedData) => {
|
|
7479
|
+
// Data is already adapted by RequestService
|
|
7480
|
+
const safeData = (!adaptedData) ? (this.dataType === DataType.ARRAY ? [] : {}) : adaptedData;
|
|
7481
|
+
this.deleteData$(safeData);
|
|
7497
7482
|
this.operationSuccess.next(OperationResultModel.adapt({ success: true, operation: 'DELETE' }));
|
|
7498
|
-
// Always call wsCommunication - it will queue if not connected
|
|
7499
7483
|
this.wsCommunication('DELETE', [...options?.path || []]);
|
|
7500
|
-
}), concatMap((
|
|
7501
|
-
// Apply adapter before database operations
|
|
7502
|
-
const adaptedData = this.applyAdapter(data);
|
|
7484
|
+
}), concatMap((adaptedData) => {
|
|
7503
7485
|
if (this.hasDatabase && this.databaseOptions?.table && adaptedData?.id) {
|
|
7504
7486
|
return this.dbManagerService.deleteTableRecord(this.databaseOptions.table, adaptedData.id);
|
|
7505
7487
|
}
|
|
@@ -7512,13 +7494,12 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7512
7494
|
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
7513
7495
|
const effectiveParams = this.getEffectiveParams(options?.path);
|
|
7514
7496
|
return this.httpManagerService.postRequest(data, requestOptions, effectiveParams)
|
|
7515
|
-
.pipe(tap((
|
|
7516
|
-
//
|
|
7517
|
-
const adaptedRes = this.applyAdapter(res);
|
|
7497
|
+
.pipe(tap((adaptedRes) => {
|
|
7498
|
+
// Data is already adapted by RequestService
|
|
7518
7499
|
if (adaptedRes.length > 0)
|
|
7519
7500
|
this.setData$(adaptedRes);
|
|
7520
7501
|
this.streamedResponse = adaptedRes;
|
|
7521
|
-
}), concatMap((
|
|
7502
|
+
}), concatMap((adaptedRes) => this.persistStreamDataToDb(adaptedRes, options)), scan((acc, res) => {
|
|
7522
7503
|
const previous = acc.current;
|
|
7523
7504
|
const current = res;
|
|
7524
7505
|
return { previous, current };
|
|
@@ -7533,14 +7514,12 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7533
7514
|
}));
|
|
7534
7515
|
})));
|
|
7535
7516
|
this.fetchStream = (options) => this.effect(() => of(options).pipe(tap(() => {
|
|
7536
|
-
// console.log('[DEBUG] fetchStream called')
|
|
7537
7517
|
this.streamedResponse = [];
|
|
7538
7518
|
this.httpManagerService.isPending.next(true);
|
|
7539
7519
|
}), switchMap((options) => {
|
|
7540
7520
|
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
7541
7521
|
requestOptions.stream = true;
|
|
7542
7522
|
const effectiveParams = this.getEffectiveParams(options?.path);
|
|
7543
|
-
// console.log('[DEBUG] Making streaming request:', requestOptions)
|
|
7544
7523
|
if (this.hasDatabase && this.databaseOptions?.table) {
|
|
7545
7524
|
const requestSignature = this.buildRequestSignature('STREAM', requestOptions, effectiveParams);
|
|
7546
7525
|
const fetchStreamFromAPI = () => {
|
|
@@ -7549,9 +7528,7 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7549
7528
|
if (Array.isArray(currentStateData) && currentStateData.length > 0) {
|
|
7550
7529
|
return of({ data: currentStateData, fromCache: true });
|
|
7551
7530
|
}
|
|
7552
|
-
if (currentStateData &&
|
|
7553
|
-
!Array.isArray(currentStateData) &&
|
|
7554
|
-
Object.keys(currentStateData).length > 0) {
|
|
7531
|
+
if (currentStateData && !Array.isArray(currentStateData) && Object.keys(currentStateData).length > 0) {
|
|
7555
7532
|
return of({ data: currentStateData, fromCache: true });
|
|
7556
7533
|
}
|
|
7557
7534
|
return of({ data: this.dataType === DataType.ARRAY ? [] : {}, fromCache: true });
|
|
@@ -7586,9 +7563,7 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7586
7563
|
if (Array.isArray(currentStateData) && currentStateData.length > 0) {
|
|
7587
7564
|
return of({ data: currentStateData, fromCache: true });
|
|
7588
7565
|
}
|
|
7589
|
-
if (currentStateData &&
|
|
7590
|
-
!Array.isArray(currentStateData) &&
|
|
7591
|
-
Object.keys(currentStateData).length > 0) {
|
|
7566
|
+
if (currentStateData && !Array.isArray(currentStateData) && Object.keys(currentStateData).length > 0) {
|
|
7592
7567
|
return of({ data: currentStateData, fromCache: true });
|
|
7593
7568
|
}
|
|
7594
7569
|
return fetchStreamFromAPI();
|
|
@@ -7598,23 +7573,17 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7598
7573
|
}));
|
|
7599
7574
|
})).pipe(tap((packet) => {
|
|
7600
7575
|
const res = packet?.data;
|
|
7601
|
-
//
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
// console.log('[DEBUG] Updating state with streaming data:', adaptedRes)
|
|
7606
|
-
this.setData$(adaptedRes);
|
|
7607
|
-
this.streamedResponse = [...this.streamedResponse, ...adaptedRes];
|
|
7576
|
+
// Data is already adapted by RequestService
|
|
7577
|
+
if (res && res.length > 0) {
|
|
7578
|
+
this.setData$(res);
|
|
7579
|
+
this.streamedResponse = [...this.streamedResponse, ...res];
|
|
7608
7580
|
}
|
|
7609
7581
|
}), concatMap((packet) => {
|
|
7610
7582
|
if (packet?.fromCache) {
|
|
7611
7583
|
return of(packet?.data);
|
|
7612
7584
|
}
|
|
7613
7585
|
return this.persistStreamDataToDb(packet?.data, options);
|
|
7614
|
-
}), map((res) => {
|
|
7615
|
-
// console.log('[DEBUG] Returning data to subscribers:', res)
|
|
7616
|
-
return res;
|
|
7617
|
-
}), catchError((error) => {
|
|
7586
|
+
}), map((res) => res), catchError((error) => {
|
|
7618
7587
|
console.error('[DEBUG] Streaming error:', error);
|
|
7619
7588
|
return of([]);
|
|
7620
7589
|
}), finalize(() => this.httpManagerService.isPending.next(false)));
|
|
@@ -7622,23 +7591,12 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7622
7591
|
// If no database is configured, always call the API (do not check tracker)
|
|
7623
7592
|
return this.httpManagerService.getRequest(requestOptions, effectiveParams)
|
|
7624
7593
|
.pipe(tap((res) => {
|
|
7625
|
-
//
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
if (adaptedRes && adaptedRes.length > 0) {
|
|
7630
|
-
// console.log('[DEBUG] Updating state with streaming data:', adaptedRes)
|
|
7631
|
-
this.setData$(adaptedRes);
|
|
7632
|
-
this.streamedResponse = [...this.streamedResponse, ...adaptedRes];
|
|
7633
|
-
}
|
|
7634
|
-
else {
|
|
7635
|
-
// console.log('[DEBUG] No streaming data or empty array:', adaptedRes)
|
|
7594
|
+
// Data is already adapted by RequestService
|
|
7595
|
+
if (res && res.length > 0) {
|
|
7596
|
+
this.setData$(res);
|
|
7597
|
+
this.streamedResponse = [...this.streamedResponse, ...res];
|
|
7636
7598
|
}
|
|
7637
|
-
}), concatMap((res) => this.persistStreamDataToDb(res, options)), map((res) => {
|
|
7638
|
-
// console.log('[DEBUG] Returning data to subscribers:', res)
|
|
7639
|
-
return res; // Return the data so subscribers can receive it
|
|
7640
|
-
}), catchError((error) => {
|
|
7641
|
-
// console.error('[DEBUG] Streaming error:', error)
|
|
7599
|
+
}), concatMap((res) => this.persistStreamDataToDb(res, options)), map((res) => res), catchError((error) => {
|
|
7642
7600
|
return of([]);
|
|
7643
7601
|
}), finalize(() => this.httpManagerService.isPending.next(false)));
|
|
7644
7602
|
})));
|
|
@@ -7926,17 +7884,16 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7926
7884
|
if (!this.hasDatabase || !this.databaseOptions?.table) {
|
|
7927
7885
|
return of(payload);
|
|
7928
7886
|
}
|
|
7929
|
-
//
|
|
7930
|
-
const
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
? [adaptedPayload]
|
|
7887
|
+
// Payload is already adapted by RequestService.requestStreaming() pipe - no need to adapt again
|
|
7888
|
+
const dbData = (payload?.results && Array.isArray(payload.results))
|
|
7889
|
+
? payload.results
|
|
7890
|
+
: Array.isArray(payload)
|
|
7891
|
+
? payload
|
|
7892
|
+
: payload
|
|
7893
|
+
? [payload]
|
|
7937
7894
|
: [];
|
|
7938
7895
|
if (dbData.length === 0) {
|
|
7939
|
-
return of(
|
|
7896
|
+
return of(payload);
|
|
7940
7897
|
}
|
|
7941
7898
|
const tableName = this.databaseOptions.table;
|
|
7942
7899
|
const requestOptions = this.updateRequestOptions(streamOptions?.headers);
|
|
@@ -7955,13 +7912,13 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7955
7912
|
return ensureTable$.pipe(switchMap((created) => {
|
|
7956
7913
|
if (!created) {
|
|
7957
7914
|
console.warn('[DB STORAGE] Stream table create/open not ready, skipping DB write for this chunk:', { table: tableName });
|
|
7958
|
-
return of(
|
|
7915
|
+
return of(payload);
|
|
7959
7916
|
}
|
|
7960
|
-
return this.dbManagerService.createTableRecords(tableName, dbData).pipe(tap(() => this.saveRequestCacheMetadata(tableName, 'STREAM', requestSignature, schemaSignature, streamOptions)), map(() =>
|
|
7917
|
+
return this.dbManagerService.createTableRecords(tableName, dbData).pipe(tap(() => this.saveRequestCacheMetadata(tableName, 'STREAM', requestSignature, schemaSignature, streamOptions)), map(() => payload));
|
|
7961
7918
|
}));
|
|
7962
|
-
}), map(() =>
|
|
7919
|
+
}), map(() => payload), catchError((error) => {
|
|
7963
7920
|
console.error('[DB STORAGE] Failed to persist streaming payload:', { table: tableName, schema, error });
|
|
7964
|
-
return of(
|
|
7921
|
+
return of(payload);
|
|
7965
7922
|
}));
|
|
7966
7923
|
}
|
|
7967
7924
|
// WEBSOCKET COMMUNICATION (STATE MANAGER)
|
|
@@ -8283,19 +8240,8 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
8283
8240
|
return Object.keys(obj).length === 0;
|
|
8284
8241
|
}
|
|
8285
8242
|
/**
|
|
8286
|
-
*
|
|
8287
|
-
* Handles both array and single object responses
|
|
8288
|
-
* Only applies adapter when it exists - returns data as-is otherwise
|
|
8243
|
+
* Update request options with provided headers
|
|
8289
8244
|
*/
|
|
8290
|
-
applyAdapter(data) {
|
|
8291
|
-
if (!data || !this.apiOptions?.adapter) {
|
|
8292
|
-
return data;
|
|
8293
|
-
}
|
|
8294
|
-
if (Array.isArray(data)) {
|
|
8295
|
-
return data.map((item) => this.apiOptions.adapter(item));
|
|
8296
|
-
}
|
|
8297
|
-
return this.apiOptions.adapter(data);
|
|
8298
|
-
}
|
|
8299
8245
|
updateRequestOptions(headers) {
|
|
8300
8246
|
const options = ApiRequest.adapt({ ...this.apiOptions });
|
|
8301
8247
|
options.headers = (headers)
|
|
@@ -8419,6 +8365,58 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
8419
8365
|
const currentQueryParams = { ...(currentEntry.queryParams || {}) };
|
|
8420
8366
|
const currentQueryCombinations = [...(currentEntry.queryCombinations || [])];
|
|
8421
8367
|
const currentQueryParamsExpires = currentEntry.queryParamsExpires ?? null;
|
|
8368
|
+
// Extract query params from options?.path and build combination string
|
|
8369
|
+
const resolvedPath = this.resolvePath(options?.path);
|
|
8370
|
+
const extractedParams = {};
|
|
8371
|
+
const ignoreQueryParams = Array.isArray(options?.ignoreQueryParams) ? options.ignoreQueryParams : [];
|
|
8372
|
+
if (Array.isArray(resolvedPath)) {
|
|
8373
|
+
const normalizedIgnore = ignoreQueryParams.map(p => this.trackerNormalizeParamKey(p));
|
|
8374
|
+
resolvedPath.forEach((pathPart) => {
|
|
8375
|
+
// Extract query params from objects in the path array
|
|
8376
|
+
if (pathPart && typeof pathPart === 'object' && !Array.isArray(pathPart)) {
|
|
8377
|
+
Object.keys(pathPart).forEach((key) => {
|
|
8378
|
+
const normalizedKey = this.trackerNormalizeParamKey(key);
|
|
8379
|
+
const value = String(pathPart[key]);
|
|
8380
|
+
// Only add to queryParams if NOT in ignoreQueryParams
|
|
8381
|
+
if (!normalizedIgnore.includes(normalizedKey)) {
|
|
8382
|
+
if (!currentQueryParams[key]) {
|
|
8383
|
+
currentQueryParams[key] = [];
|
|
8384
|
+
}
|
|
8385
|
+
if (!currentQueryParams[key].includes(value)) {
|
|
8386
|
+
currentQueryParams[key].push(value);
|
|
8387
|
+
}
|
|
8388
|
+
// Track extracted param for combination string
|
|
8389
|
+
extractedParams[normalizedKey] = value;
|
|
8390
|
+
}
|
|
8391
|
+
});
|
|
8392
|
+
}
|
|
8393
|
+
else if (typeof pathPart === 'string') {
|
|
8394
|
+
// Parse URL query strings like 'items?active=true&location=6'
|
|
8395
|
+
const normalized = this.trackerNormalizePath([pathPart]);
|
|
8396
|
+
if (normalized.hasQuery) {
|
|
8397
|
+
const filtered = this.trackerFilterQuery(normalized.query, ignoreQueryParams);
|
|
8398
|
+
Object.assign(extractedParams, filtered);
|
|
8399
|
+
// Add filtered params to queryParams
|
|
8400
|
+
Object.keys(filtered).forEach((key) => {
|
|
8401
|
+
if (!currentQueryParams[key]) {
|
|
8402
|
+
currentQueryParams[key] = [];
|
|
8403
|
+
}
|
|
8404
|
+
if (!currentQueryParams[key].includes(filtered[key])) {
|
|
8405
|
+
currentQueryParams[key].push(filtered[key]);
|
|
8406
|
+
}
|
|
8407
|
+
});
|
|
8408
|
+
}
|
|
8409
|
+
}
|
|
8410
|
+
});
|
|
8411
|
+
}
|
|
8412
|
+
// Build combination string if we have extracted params
|
|
8413
|
+
if (Object.keys(extractedParams).length > 0) {
|
|
8414
|
+
const keys = Object.keys(extractedParams).sort();
|
|
8415
|
+
const combinationString = keys.map((k) => `${k}=${extractedParams[k]}`).join('&');
|
|
8416
|
+
if (!currentQueryCombinations.includes(combinationString)) {
|
|
8417
|
+
currentQueryCombinations.push(combinationString);
|
|
8418
|
+
}
|
|
8419
|
+
}
|
|
8422
8420
|
this.localStorageManagerService.updateStore({
|
|
8423
8421
|
name: tableName,
|
|
8424
8422
|
data: {
|
|
@@ -8429,7 +8427,7 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
8429
8427
|
...currentEntry,
|
|
8430
8428
|
signature,
|
|
8431
8429
|
savedAt: Date.now(),
|
|
8432
|
-
path:
|
|
8430
|
+
path: resolvedPath,
|
|
8433
8431
|
headers: this.filterHeaders(options?.headers),
|
|
8434
8432
|
queryCombinations: currentQueryCombinations,
|
|
8435
8433
|
queryParams: currentQueryParams,
|
|
@@ -8556,22 +8554,6 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
8556
8554
|
});
|
|
8557
8555
|
return result;
|
|
8558
8556
|
}
|
|
8559
|
-
trackerBuildExpiryEpoch(expireIn) {
|
|
8560
|
-
if (typeof expireIn === 'undefined' || expireIn === null || expireIn === '')
|
|
8561
|
-
return null;
|
|
8562
|
-
if (typeof expireIn === 'number' && Number.isFinite(expireIn) && expireIn > 0) {
|
|
8563
|
-
return Math.floor(Date.now() / 1000) + Math.floor(expireIn);
|
|
8564
|
-
}
|
|
8565
|
-
const raw = String(expireIn).trim().toLowerCase().replace(/\s+/g, '');
|
|
8566
|
-
const parsed = raw.match(/^(\d+)(y|w|d|hr|h|mn|min|m|s)$/);
|
|
8567
|
-
if (!parsed)
|
|
8568
|
-
return null;
|
|
8569
|
-
const toSeconds = { y: 31556926, w: 604800, d: 86400, hr: 3600, h: 3600, mn: 60, min: 60, m: 60, s: 1 };
|
|
8570
|
-
const seconds = toSeconds[parsed[2]];
|
|
8571
|
-
if (!seconds)
|
|
8572
|
-
return null;
|
|
8573
|
-
return Math.floor(Date.now() / 1000) + Number(parsed[1]) * seconds;
|
|
8574
|
-
}
|
|
8575
8557
|
checkTrackerAllowsRequest(tableName, type, path, options, storeData) {
|
|
8576
8558
|
const normalized = this.trackerNormalizePath(path);
|
|
8577
8559
|
const ignoreQueryParams = Array.isArray(options?.ignoreQueryParams) ? options.ignoreQueryParams : [];
|
|
@@ -8590,58 +8572,47 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
8590
8572
|
const combinationString = keys.sort().map((k) => `${k}=${filtered[k]}`).join('&');
|
|
8591
8573
|
// Legacy per-key queryParams for backward compatibility (read-only)
|
|
8592
8574
|
const queryParams = { ...(meta.queryParams || {}) };
|
|
8593
|
-
|
|
8575
|
+
const queryParamsExpires = meta.queryParamsExpires ?? null;
|
|
8594
8576
|
// New combination-based tracking
|
|
8595
|
-
|
|
8577
|
+
const queryCombinations = [...(meta.queryCombinations || [])];
|
|
8596
8578
|
// Reset combinations if the request path has changed (different endpoint)
|
|
8597
8579
|
// Use trackerNormalizePath so inline query strings (e.g. 'items?a=1') are stripped
|
|
8598
8580
|
// before comparing, matching the same normalization applied to the current request.
|
|
8599
8581
|
const storedPathKey = meta.path
|
|
8600
8582
|
? this.trackerNormalizePath(meta.path.filter((p) => typeof p === 'string' || typeof p === 'number').map(String)).pathKey
|
|
8601
8583
|
: null;
|
|
8602
|
-
|
|
8603
|
-
|
|
8604
|
-
|
|
8605
|
-
Object.keys(queryParams).forEach((k) => delete queryParams[k]);
|
|
8606
|
-
queryParamsExpires = null;
|
|
8607
|
-
}
|
|
8608
|
-
if (queryParamsExpires !== null && queryParamsExpires <= now) {
|
|
8609
|
-
queryCombinations = [];
|
|
8610
|
-
queryParamsExpires = null;
|
|
8611
|
-
Object.keys(queryParams).forEach((k) => delete queryParams[k]);
|
|
8612
|
-
}
|
|
8584
|
+
const pathChanged = storedPathKey && storedPathKey !== normalized.pathKey;
|
|
8585
|
+
const isExpired = queryParamsExpires !== null && queryParamsExpires <= now;
|
|
8586
|
+
const shouldReset = pathChanged || isExpired;
|
|
8613
8587
|
// Determine if request is accepted (not yet tracked)
|
|
8614
8588
|
// Use combination-based tracking when available; fall back to legacy per-key tracking
|
|
8615
|
-
|
|
8616
|
-
|
|
8617
|
-
|
|
8618
|
-
|
|
8619
|
-
|
|
8620
|
-
|
|
8621
|
-
|
|
8622
|
-
|
|
8623
|
-
|
|
8624
|
-
|
|
8625
|
-
|
|
8626
|
-
|
|
8627
|
-
|
|
8628
|
-
}
|
|
8629
|
-
if (accepted) {
|
|
8630
|
-
queryCombinations = [...queryCombinations, combinationString];
|
|
8631
|
-
// Also update legacy queryParams so existing consumers still work
|
|
8632
|
-
keys.forEach(key => {
|
|
8589
|
+
const accepted = shouldReset
|
|
8590
|
+
? true
|
|
8591
|
+
: queryCombinations.length > 0
|
|
8592
|
+
? !queryCombinations.includes(combinationString)
|
|
8593
|
+
: Object.keys(queryParams).length > 0
|
|
8594
|
+
? !keys.every((key) => (queryParams[key] || []).includes(filtered[key]))
|
|
8595
|
+
: true;
|
|
8596
|
+
// Compute updated values immutably
|
|
8597
|
+
const updatedQueryCombinations = accepted
|
|
8598
|
+
? [...queryCombinations, combinationString]
|
|
8599
|
+
: queryCombinations;
|
|
8600
|
+
const updatedQueryParams = accepted
|
|
8601
|
+
? keys.reduce((acc, key) => {
|
|
8633
8602
|
const value = filtered[key];
|
|
8634
|
-
const consumed =
|
|
8603
|
+
const consumed = acc[key] || [];
|
|
8635
8604
|
if (!consumed.includes(value)) {
|
|
8636
|
-
|
|
8605
|
+
acc[key] = [...consumed, value];
|
|
8637
8606
|
}
|
|
8638
|
-
|
|
8639
|
-
|
|
8640
|
-
|
|
8641
|
-
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8607
|
+
return acc;
|
|
8608
|
+
}, { ...queryParams })
|
|
8609
|
+
: { ...queryParams };
|
|
8610
|
+
const updatedQueryParamsExpires = this.utils.expires(options?.queryParamsExpiresIn) ?? queryParamsExpires;
|
|
8611
|
+
// Apply reset if path changed or expired
|
|
8612
|
+
const finalQueryCombinations = shouldReset ? updatedQueryCombinations : queryCombinations;
|
|
8613
|
+
const finalQueryParams = shouldReset ? updatedQueryParams : queryParams;
|
|
8614
|
+
const finalQueryParamsExpires = shouldReset ? updatedQueryParamsExpires : updatedQueryParamsExpires;
|
|
8615
|
+
if (accepted || updatedQueryParamsExpires !== queryParamsExpires) {
|
|
8645
8616
|
this.localStorageManagerService.store$(tableName).pipe(take(1), tap((latestStoreData) => {
|
|
8646
8617
|
const currentCache = latestStoreData?.requestCache || {};
|
|
8647
8618
|
const currentEntry = currentCache[type] || {};
|
|
@@ -8653,9 +8624,9 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
8653
8624
|
...currentCache,
|
|
8654
8625
|
[type]: {
|
|
8655
8626
|
...currentEntry,
|
|
8656
|
-
queryCombinations,
|
|
8657
|
-
queryParams,
|
|
8658
|
-
queryParamsExpires,
|
|
8627
|
+
queryCombinations: finalQueryCombinations,
|
|
8628
|
+
queryParams: finalQueryParams,
|
|
8629
|
+
queryParamsExpires: finalQueryParamsExpires,
|
|
8659
8630
|
}
|
|
8660
8631
|
}
|
|
8661
8632
|
}
|