http-request-manager 18.15.12 → 18.15.14
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.
|
@@ -6434,28 +6434,25 @@ class QueryParamsTrackerService {
|
|
|
6434
6434
|
}
|
|
6435
6435
|
checkRequestOptions(requestOptions = [], options = {}) {
|
|
6436
6436
|
this.ensureStateRestored();
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
pathState.consumedValuesByKey['__path_seen__'] = ['true'];
|
|
6451
|
-
this.persistState();
|
|
6437
|
+
return this.ready$.pipe(take(1), map(() => {
|
|
6438
|
+
const normalized = this.normalizeRequestOptions(requestOptions);
|
|
6439
|
+
if (!normalized.pathKey)
|
|
6440
|
+
return false;
|
|
6441
|
+
this.cleanupExpiredEntries();
|
|
6442
|
+
if (!normalized.hasQuery) {
|
|
6443
|
+
const pathState = this.ensurePathState(normalized.pathKey);
|
|
6444
|
+
const pathSeenBefore = pathState.consumedValuesByKey.hasOwnProperty('__path_seen__');
|
|
6445
|
+
if (!pathSeenBefore) {
|
|
6446
|
+
pathState.consumedValuesByKey['__path_seen__'] = ['true'];
|
|
6447
|
+
this.persistState();
|
|
6448
|
+
}
|
|
6449
|
+
return !pathSeenBefore;
|
|
6452
6450
|
}
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
return this.
|
|
6457
|
-
}
|
|
6458
|
-
return this.checkVariation(normalized, options);
|
|
6451
|
+
if (options.mode === 'exact') {
|
|
6452
|
+
return this.checkExact(normalized, options);
|
|
6453
|
+
}
|
|
6454
|
+
return this.checkVariation(normalized, options);
|
|
6455
|
+
}));
|
|
6459
6456
|
}
|
|
6460
6457
|
matchesPath(requestOptions = [], expectedPathOptions = []) {
|
|
6461
6458
|
this.ensureStateRestored();
|
|
@@ -7271,99 +7268,7 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7271
7268
|
table: this.databaseOptions?.table,
|
|
7272
7269
|
databaseOptions: this.databaseOptions
|
|
7273
7270
|
});
|
|
7274
|
-
|
|
7275
|
-
return this.dbManagerService.databaseExists().pipe(switchMap((dbExists) => {
|
|
7276
|
-
if (!dbExists) {
|
|
7277
|
-
const initObs = this.initDBStorageAsync();
|
|
7278
|
-
return initObs.pipe(switchMap(() => fetchFromAPI()), catchError((error) => {
|
|
7279
|
-
console.warn('[DB STORAGE] initDBStorageAsync failed when DB did not exist, continuing with API:', error);
|
|
7280
|
-
return fetchFromAPI();
|
|
7281
|
-
}));
|
|
7282
|
-
}
|
|
7283
|
-
return this.dbManagerService.hasDatabaseTable(this.databaseOptions.table).pipe(switchMap((tableExists) => {
|
|
7284
|
-
if (!tableExists) {
|
|
7285
|
-
const initObs = this.initDBStorageAsync();
|
|
7286
|
-
return initObs.pipe(switchMap(() => fetchFromAPI()), catchError((error) => {
|
|
7287
|
-
console.warn('[DB STORAGE] initDBStorageAsync failed when table missing, continuing with API:', error);
|
|
7288
|
-
return fetchFromAPI();
|
|
7289
|
-
}));
|
|
7290
|
-
}
|
|
7291
|
-
return this.localStorageManagerService.store$(this.databaseOptions.table).pipe(take(1), switchMap((storeData) => {
|
|
7292
|
-
console.log('[CacheDebug] storeData for table:', this.databaseOptions.table, { storeData, requestCache: storeData?.requestCache, expires: storeData?.expires });
|
|
7293
|
-
const forceRefresh = !!options?.forceRefresh;
|
|
7294
|
-
const storedSchemaSignature = this.getStoredSchemaSignature(storeData);
|
|
7295
|
-
const expires = storeData?.expires || 0;
|
|
7296
|
-
const hasExpired = expires > 0 && this.utils.hasExpired(expires);
|
|
7297
|
-
if (forceRefresh) {
|
|
7298
|
-
return fetchFromAPI();
|
|
7299
|
-
}
|
|
7300
|
-
if (hasExpired) {
|
|
7301
|
-
return this.dbManagerService.clearTable(this.databaseOptions.table).pipe(switchMap(() => fetchFromAPI()));
|
|
7302
|
-
}
|
|
7303
|
-
const expectedSchema = this.buildSchemaFromAdapter();
|
|
7304
|
-
const expectedSchemaSignature = this.buildSchemaSignature(expectedSchema);
|
|
7305
|
-
console.log('[CacheDebug] schema check:', { tableName: this.databaseOptions.table, storedSchemaSignature, expectedSchemaSignature, mismatch: storedSchemaSignature && storedSchemaSignature !== expectedSchemaSignature });
|
|
7306
|
-
if (storedSchemaSignature && storedSchemaSignature !== expectedSchemaSignature) {
|
|
7307
|
-
const tableDef = TableSchemaDef.adapt({ table: this.databaseOptions.table, schema: expectedSchema });
|
|
7308
|
-
return this.dbManagerService.clearTable(this.databaseOptions.table).pipe(switchMap(() => this.dbManagerService.createDatabaseTable(tableDef)), switchMap(() => fetchFromAPI()));
|
|
7309
|
-
}
|
|
7310
|
-
const trackerAllowsRequest = this.checkTrackerAllowsRequest(this.databaseOptions.table, this.resolvePath(effectiveParams), options, storeData);
|
|
7311
|
-
if (trackerAllowsRequest) {
|
|
7312
|
-
const normalizedPath = this.trackerNormalizePath(this.resolvePath(effectiveParams));
|
|
7313
|
-
if (!normalizedPath.hasQuery) {
|
|
7314
|
-
return this.dbManagerService.getTableRecords(this.databaseOptions.table).pipe(switchMap((dbData) => {
|
|
7315
|
-
if (Array.isArray(dbData) && dbData.length > 0) {
|
|
7316
|
-
this.setData$(dbData);
|
|
7317
|
-
// Save cache metadata for both GET and STREAM request types so
|
|
7318
|
-
// tracker/check logic can detect cached responses regardless
|
|
7319
|
-
// of whether a subsequent call is a normal GET or a streaming GET.
|
|
7320
|
-
const getSignature = requestSignature;
|
|
7321
|
-
const streamRequestOptions = { ...(requestOptions || {}), stream: true };
|
|
7322
|
-
const streamSignature = this.buildRequestSignature('STREAM', streamRequestOptions, effectiveParams);
|
|
7323
|
-
this.saveRequestCacheMetadata(this.databaseOptions.table, 'GET', getSignature, storedSchemaSignature ?? expectedSchemaSignature ?? undefined, options);
|
|
7324
|
-
this.saveRequestCacheMetadata(this.databaseOptions.table, 'STREAM', streamSignature, storedSchemaSignature ?? expectedSchemaSignature ?? undefined, options);
|
|
7325
|
-
return of({ data: dbData, fromCache: true });
|
|
7326
|
-
}
|
|
7327
|
-
return fetchFromAPI();
|
|
7328
|
-
}), catchError((error) => {
|
|
7329
|
-
const tableName = this.databaseOptions.table;
|
|
7330
|
-
console.warn('[DB STORAGE] fallback cache read failed, falling back to API:', { table: tableName, error });
|
|
7331
|
-
return fetchFromAPI();
|
|
7332
|
-
}));
|
|
7333
|
-
}
|
|
7334
|
-
return fetchFromAPI();
|
|
7335
|
-
}
|
|
7336
|
-
return this.dbManagerService.getTableRecords(this.databaseOptions.table).pipe(switchMap((dbData) => {
|
|
7337
|
-
if (Array.isArray(dbData) && dbData.length > 0) {
|
|
7338
|
-
this.setData$(dbData);
|
|
7339
|
-
this.saveRequestCacheMetadata(this.databaseOptions.table, 'GET', requestSignature, storedSchemaSignature ?? expectedSchemaSignature ?? undefined, options);
|
|
7340
|
-
return of(dbData);
|
|
7341
|
-
}
|
|
7342
|
-
const currentStateData = this.get()?.data;
|
|
7343
|
-
if (Array.isArray(currentStateData) && currentStateData.length > 0) {
|
|
7344
|
-
return of(currentStateData);
|
|
7345
|
-
}
|
|
7346
|
-
if (currentStateData &&
|
|
7347
|
-
!Array.isArray(currentStateData) &&
|
|
7348
|
-
Object.keys(currentStateData).length > 0) {
|
|
7349
|
-
return of(currentStateData);
|
|
7350
|
-
}
|
|
7351
|
-
return of(this.dataType === DataType.ARRAY ? [] : {});
|
|
7352
|
-
}), catchError((error) => {
|
|
7353
|
-
const tableName = this.databaseOptions.table;
|
|
7354
|
-
console.warn('[DB STORAGE] getTableRecords failed, recreating table and falling back to API:', { table: tableName, error });
|
|
7355
|
-
const schema = this.buildSchemaFromAdapter();
|
|
7356
|
-
const tableDef = TableSchemaDef.adapt({ table: tableName, schema });
|
|
7357
|
-
return this.dbManagerService.createDatabaseTable(tableDef).pipe(switchMap(() => fetchFromAPI()), catchError((recreateError) => {
|
|
7358
|
-
console.error('[DB STORAGE] Failed to recreate table after read error, continuing with API only:', recreateError);
|
|
7359
|
-
return fetchFromAPI();
|
|
7360
|
-
}));
|
|
7361
|
-
}));
|
|
7362
|
-
}));
|
|
7363
|
-
}));
|
|
7364
|
-
}));
|
|
7365
|
-
}
|
|
7366
|
-
return fetchFromAPI();
|
|
7271
|
+
return this.resolveCacheDecision('GET', requestOptions, effectiveParams, options, fetchFromAPI);
|
|
7367
7272
|
})));
|
|
7368
7273
|
// FETCH RECORD
|
|
7369
7274
|
this.fetchRecord = (options, method) => this.effect(() => of(RequestOptions.adapt(options)).pipe(tap(() => console.log('🔄 fetchRecord effect triggered with path:', options?.path, 'method:', method)), switchMap((options) => {
|
|
@@ -7503,62 +7408,29 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7503
7408
|
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
7504
7409
|
requestOptions.stream = true;
|
|
7505
7410
|
const effectiveParams = this.getEffectiveParams(options?.path);
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
if (
|
|
7511
|
-
|
|
7512
|
-
if (Array.isArray(currentStateData) && currentStateData.length > 0) {
|
|
7513
|
-
return of({ data: currentStateData, fromCache: true });
|
|
7514
|
-
}
|
|
7515
|
-
if (currentStateData &&
|
|
7516
|
-
!Array.isArray(currentStateData) &&
|
|
7517
|
-
Object.keys(currentStateData).length > 0) {
|
|
7518
|
-
return of({ data: currentStateData, fromCache: true });
|
|
7519
|
-
}
|
|
7520
|
-
return of({ data: this.dataType === DataType.ARRAY ? [] : {}, fromCache: true });
|
|
7411
|
+
const requestSignature = this.buildRequestSignature('STREAM', requestOptions, effectiveParams);
|
|
7412
|
+
const fetchStreamFromAPI = () => {
|
|
7413
|
+
if (!this.tryBeginInFlightRequest(requestSignature)) {
|
|
7414
|
+
const currentStateData = this.get()?.data;
|
|
7415
|
+
if (Array.isArray(currentStateData) && currentStateData.length > 0) {
|
|
7416
|
+
return of({ data: currentStateData, fromCache: true });
|
|
7521
7417
|
}
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
const forceRefresh = !!options?.forceRefresh;
|
|
7527
|
-
const expires = storeData?.expires || 0;
|
|
7528
|
-
const hasExpired = expires > 0 && this.utils.hasExpired(expires);
|
|
7529
|
-
if (forceRefresh) {
|
|
7530
|
-
return fetchStreamFromAPI();
|
|
7531
|
-
}
|
|
7532
|
-
if (hasExpired) {
|
|
7533
|
-
return this.dbManagerService.clearTable(this.databaseOptions.table).pipe(switchMap(() => fetchStreamFromAPI()));
|
|
7534
|
-
}
|
|
7535
|
-
const storedSchemaSignature = this.getStoredSchemaSignature(storeData);
|
|
7536
|
-
const expectedSchema = this.buildSchemaFromAdapter();
|
|
7537
|
-
const expectedSchemaSignature = this.buildSchemaSignature(expectedSchema);
|
|
7538
|
-
if (storedSchemaSignature && storedSchemaSignature !== expectedSchemaSignature) {
|
|
7539
|
-
const tableDef = TableSchemaDef.adapt({ table: this.databaseOptions.table, schema: expectedSchema });
|
|
7540
|
-
return this.dbManagerService.clearTable(this.databaseOptions.table).pipe(switchMap(() => this.dbManagerService.createDatabaseTable(tableDef)), switchMap(() => fetchStreamFromAPI()));
|
|
7418
|
+
if (currentStateData &&
|
|
7419
|
+
!Array.isArray(currentStateData) &&
|
|
7420
|
+
Object.keys(currentStateData).length > 0) {
|
|
7421
|
+
return of({ data: currentStateData, fromCache: true });
|
|
7541
7422
|
}
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
!Array.isArray(currentStateData) &&
|
|
7554
|
-
Object.keys(currentStateData).length > 0) {
|
|
7555
|
-
return of({ data: currentStateData, fromCache: true });
|
|
7556
|
-
}
|
|
7557
|
-
return of({ data: this.dataType === DataType.ARRAY ? [] : {}, fromCache: true });
|
|
7558
|
-
}));
|
|
7559
|
-
}
|
|
7560
|
-
return fetchStreamFromAPI();
|
|
7561
|
-
})).pipe(tap((packet) => {
|
|
7423
|
+
return of({ data: this.dataType === DataType.ARRAY ? [] : {}, fromCache: true });
|
|
7424
|
+
}
|
|
7425
|
+
if (this.hasDatabase && this.databaseOptions?.table) {
|
|
7426
|
+
this.setCachedRequestSignature(this.databaseOptions.table, 'STREAM', requestSignature);
|
|
7427
|
+
}
|
|
7428
|
+
return this.httpManagerService.getRequest(requestOptions, effectiveParams).pipe(map((apiData) => ({ data: apiData, fromCache: false })), finalize(() => this.endInFlightRequest(requestSignature)));
|
|
7429
|
+
};
|
|
7430
|
+
// Use shared gating decision for parity with GET
|
|
7431
|
+
const cacheDecision$ = this.resolveCacheDecision('STREAM', requestOptions, effectiveParams, options, fetchStreamFromAPI);
|
|
7432
|
+
if (this.hasDatabase && this.databaseOptions?.table) {
|
|
7433
|
+
return cacheDecision$.pipe(tap((packet) => {
|
|
7562
7434
|
const res = packet?.data;
|
|
7563
7435
|
// console.log('[DEBUG] Streaming response received:', res)
|
|
7564
7436
|
if (res && res.length > 0) {
|
|
@@ -7825,6 +7697,130 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7825
7697
|
});
|
|
7826
7698
|
return [...updatedData, ...addedData];
|
|
7827
7699
|
}
|
|
7700
|
+
// --------------------------------------------------------------------------------------------------
|
|
7701
|
+
// SHARED CACHE GATING DECISION
|
|
7702
|
+
// --------------------------------------------------------------------------------------------------
|
|
7703
|
+
/**
|
|
7704
|
+
* Resolves whether a request should use cached/DB data or call the API.
|
|
7705
|
+
* Shared by both fetchRecords (GET) and fetchStream (STREAM) to ensure parity.
|
|
7706
|
+
*
|
|
7707
|
+
* Decision order:
|
|
7708
|
+
* 1. forceRefresh → API
|
|
7709
|
+
* 2. cache expired → clear + API
|
|
7710
|
+
* 3. schema mismatch → clear + rebuild + API
|
|
7711
|
+
* 4. tracker blocks request → DB/state fallback
|
|
7712
|
+
* 5. tracker allows request → API (with optional no-query DB shortcut)
|
|
7713
|
+
*
|
|
7714
|
+
* Returns an observable of the result data.
|
|
7715
|
+
*/
|
|
7716
|
+
resolveCacheDecision(requestType, requestOptions, effectiveParams, options, fetchFromAPI) {
|
|
7717
|
+
if (!this.hasDatabase || !this.databaseOptions?.table) {
|
|
7718
|
+
return fetchFromAPI();
|
|
7719
|
+
}
|
|
7720
|
+
const requestSignature = this.buildRequestSignature(requestType, requestOptions, effectiveParams);
|
|
7721
|
+
return this.dbManagerService.databaseExists().pipe(switchMap((dbExists) => {
|
|
7722
|
+
if (!dbExists) {
|
|
7723
|
+
return this.initDBStorageAsync().pipe(switchMap(() => fetchFromAPI()), catchError((error) => {
|
|
7724
|
+
console.warn('[DB STORAGE] initDBStorageAsync failed when DB did not exist, continuing with API:', error);
|
|
7725
|
+
return fetchFromAPI();
|
|
7726
|
+
}));
|
|
7727
|
+
}
|
|
7728
|
+
return this.dbManagerService.hasDatabaseTable(this.databaseOptions.table).pipe(switchMap((tableExists) => {
|
|
7729
|
+
if (!tableExists) {
|
|
7730
|
+
return this.initDBStorageAsync().pipe(switchMap(() => fetchFromAPI()), catchError((error) => {
|
|
7731
|
+
console.warn('[DB STORAGE] initDBStorageAsync failed when table missing, continuing with API:', error);
|
|
7732
|
+
return fetchFromAPI();
|
|
7733
|
+
}));
|
|
7734
|
+
}
|
|
7735
|
+
return this.localStorageManagerService.store$(this.databaseOptions.table).pipe(take(1), switchMap((storeData) => {
|
|
7736
|
+
console.log('[CacheDebug] storeData for table:', this.databaseOptions.table, { storeData, requestCache: storeData?.requestCache, expires: storeData?.expires });
|
|
7737
|
+
// 1. forceRefresh → API
|
|
7738
|
+
const forceRefresh = !!options?.forceRefresh;
|
|
7739
|
+
if (forceRefresh) {
|
|
7740
|
+
return fetchFromAPI();
|
|
7741
|
+
}
|
|
7742
|
+
// 2. cache expired → clear + API
|
|
7743
|
+
const expires = storeData?.expires || 0;
|
|
7744
|
+
const hasExpired = expires > 0 && this.utils.hasExpired(expires);
|
|
7745
|
+
if (hasExpired) {
|
|
7746
|
+
return this.dbManagerService.clearTable(this.databaseOptions.table).pipe(switchMap(() => fetchFromAPI()));
|
|
7747
|
+
}
|
|
7748
|
+
// 3. schema mismatch → clear + rebuild + API
|
|
7749
|
+
const storedSchemaSignature = this.getStoredSchemaSignature(storeData);
|
|
7750
|
+
const expectedSchema = this.buildSchemaFromAdapter();
|
|
7751
|
+
const expectedSchemaSignature = this.buildSchemaSignature(expectedSchema);
|
|
7752
|
+
console.log('[CacheDebug] schema check:', { tableName: this.databaseOptions.table, storedSchemaSignature, expectedSchemaSignature, mismatch: storedSchemaSignature && storedSchemaSignature !== expectedSchemaSignature });
|
|
7753
|
+
if (storedSchemaSignature && storedSchemaSignature !== expectedSchemaSignature) {
|
|
7754
|
+
const tableDef = TableSchemaDef.adapt({ table: this.databaseOptions.table, schema: expectedSchema });
|
|
7755
|
+
return this.dbManagerService.clearTable(this.databaseOptions.table).pipe(switchMap(() => this.dbManagerService.createDatabaseTable(tableDef)), switchMap(() => fetchFromAPI()));
|
|
7756
|
+
}
|
|
7757
|
+
// 4 & 5. tracker decision (async — awaits tracker readiness)
|
|
7758
|
+
return this.checkTrackerAllowsRequest(this.databaseOptions.table, this.resolvePath(effectiveParams), options, storeData).pipe(switchMap((trackerAllowsRequest) => {
|
|
7759
|
+
if (trackerAllowsRequest) {
|
|
7760
|
+
// For no-query paths, try DB first before API
|
|
7761
|
+
const normalizedPath = this.trackerNormalizePath(this.resolvePath(effectiveParams));
|
|
7762
|
+
if (!normalizedPath.hasQuery) {
|
|
7763
|
+
return this.dbManagerService.getTableRecords(this.databaseOptions.table).pipe(switchMap((dbData) => {
|
|
7764
|
+
if (Array.isArray(dbData) && dbData.length > 0) {
|
|
7765
|
+
this.setData$(dbData);
|
|
7766
|
+
// Save cache metadata for both GET and STREAM request types so
|
|
7767
|
+
// tracker/check logic can detect cached responses regardless
|
|
7768
|
+
// of whether a subsequent call is a normal GET or a streaming GET.
|
|
7769
|
+
const getSignature = this.buildRequestSignature('GET', requestOptions, effectiveParams);
|
|
7770
|
+
const streamRequestOptions = { ...(requestOptions || {}), stream: true };
|
|
7771
|
+
const streamSignature = this.buildRequestSignature('STREAM', streamRequestOptions, effectiveParams);
|
|
7772
|
+
this.saveRequestCacheMetadata(this.databaseOptions.table, 'GET', getSignature, storedSchemaSignature ?? expectedSchemaSignature ?? undefined, options);
|
|
7773
|
+
this.saveRequestCacheMetadata(this.databaseOptions.table, 'STREAM', streamSignature, storedSchemaSignature ?? expectedSchemaSignature ?? undefined, options);
|
|
7774
|
+
return of({ data: dbData, fromCache: true });
|
|
7775
|
+
}
|
|
7776
|
+
return fetchFromAPI();
|
|
7777
|
+
}), catchError((error) => {
|
|
7778
|
+
const tableName = this.databaseOptions.table;
|
|
7779
|
+
console.warn('[DB STORAGE] fallback cache read failed, falling back to API:', { table: tableName, error });
|
|
7780
|
+
return fetchFromAPI();
|
|
7781
|
+
}));
|
|
7782
|
+
}
|
|
7783
|
+
return fetchFromAPI();
|
|
7784
|
+
}
|
|
7785
|
+
// tracker blocks request → DB/state fallback
|
|
7786
|
+
return this.dbManagerService.getTableRecords(this.databaseOptions.table).pipe(switchMap((dbData) => {
|
|
7787
|
+
if (Array.isArray(dbData) && dbData.length > 0) {
|
|
7788
|
+
this.setData$(dbData);
|
|
7789
|
+
// Save cache metadata for both GET and STREAM request types so
|
|
7790
|
+
// tracker/check logic can detect cached responses regardless
|
|
7791
|
+
// of whether a subsequent call is a normal GET or a streaming GET.
|
|
7792
|
+
const getSignature = this.buildRequestSignature('GET', requestOptions, effectiveParams);
|
|
7793
|
+
const streamRequestOptions = { ...(requestOptions || {}), stream: true };
|
|
7794
|
+
const streamSignature = this.buildRequestSignature('STREAM', streamRequestOptions, effectiveParams);
|
|
7795
|
+
this.saveRequestCacheMetadata(this.databaseOptions.table, 'GET', getSignature, storedSchemaSignature ?? expectedSchemaSignature ?? undefined, options);
|
|
7796
|
+
this.saveRequestCacheMetadata(this.databaseOptions.table, 'STREAM', streamSignature, storedSchemaSignature ?? expectedSchemaSignature ?? undefined, options);
|
|
7797
|
+
return of(dbData);
|
|
7798
|
+
}
|
|
7799
|
+
const currentStateData = this.get()?.data;
|
|
7800
|
+
if (Array.isArray(currentStateData) && currentStateData.length > 0) {
|
|
7801
|
+
return of(currentStateData);
|
|
7802
|
+
}
|
|
7803
|
+
if (currentStateData &&
|
|
7804
|
+
!Array.isArray(currentStateData) &&
|
|
7805
|
+
Object.keys(currentStateData).length > 0) {
|
|
7806
|
+
return of(currentStateData);
|
|
7807
|
+
}
|
|
7808
|
+
return of(this.dataType === DataType.ARRAY ? [] : {});
|
|
7809
|
+
}), catchError((error) => {
|
|
7810
|
+
const tableName = this.databaseOptions.table;
|
|
7811
|
+
console.warn('[DB STORAGE] getTableRecords failed, recreating table and falling back to API:', { table: tableName, error });
|
|
7812
|
+
const schema = this.buildSchemaFromAdapter();
|
|
7813
|
+
const tableDef = TableSchemaDef.adapt({ table: tableName, schema });
|
|
7814
|
+
return this.dbManagerService.createDatabaseTable(tableDef).pipe(switchMap(() => fetchFromAPI()), catchError((recreateError) => {
|
|
7815
|
+
console.error('[DB STORAGE] Failed to recreate table after read error, continuing with API only:', recreateError);
|
|
7816
|
+
return fetchFromAPI();
|
|
7817
|
+
}));
|
|
7818
|
+
}));
|
|
7819
|
+
}));
|
|
7820
|
+
}));
|
|
7821
|
+
}));
|
|
7822
|
+
}));
|
|
7823
|
+
}
|
|
7828
7824
|
initDBStorageAsync() {
|
|
7829
7825
|
console.log('[initDBStorageAsync] Starting initialization:', {
|
|
7830
7826
|
dataType: this.dataType,
|
|
@@ -8496,7 +8492,7 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
8496
8492
|
return Math.floor(Date.now() / 1000) + Number(parsed[1]) * seconds;
|
|
8497
8493
|
}
|
|
8498
8494
|
checkTrackerAllowsRequest(tableName, path, options, storeData) {
|
|
8499
|
-
if (options &&
|
|
8495
|
+
if (options && Array.isArray(options.watchParams)) {
|
|
8500
8496
|
return this.queryParamsTrackerService.checkRequestOptions(path, {
|
|
8501
8497
|
watchParams: options.watchParams,
|
|
8502
8498
|
watchExpiresAt: options?.watchExpiresAt,
|
|
@@ -8507,12 +8503,12 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
8507
8503
|
if (!normalized.hasQuery || ignoreQueryParams.length === 0) {
|
|
8508
8504
|
const meta = this.getRequestCacheMetadata(storeData, 'GET');
|
|
8509
8505
|
console.log('[CacheDebug] checkTrackerAllowsRequest: no query params path', { tableName, requestCacheMeta: meta, allowsRequest: !meta });
|
|
8510
|
-
return !meta;
|
|
8506
|
+
return of(!meta);
|
|
8511
8507
|
}
|
|
8512
8508
|
const filtered = this.trackerFilterQuery(normalized.query, ignoreQueryParams);
|
|
8513
8509
|
const keys = Object.keys(filtered);
|
|
8514
8510
|
if (keys.length === 0) {
|
|
8515
|
-
return !this.getRequestCacheMetadata(storeData, 'GET');
|
|
8511
|
+
return of(!this.getRequestCacheMetadata(storeData, 'GET'));
|
|
8516
8512
|
}
|
|
8517
8513
|
const tracker = this.getTrackerState(storeData);
|
|
8518
8514
|
const now = Math.floor(Date.now() / 1000);
|
|
@@ -8536,7 +8532,7 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
8536
8532
|
}
|
|
8537
8533
|
this.saveTrackerState(tableName, tracker.consumedValuesByKey, tracker.trackingExpires);
|
|
8538
8534
|
}
|
|
8539
|
-
return accepted;
|
|
8535
|
+
return of(accepted);
|
|
8540
8536
|
}
|
|
8541
8537
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HTTPManagerStateService, deps: [{ token: API_OPTS }, { token: "dataType" }, { token: DatabaseStorage }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
8542
8538
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HTTPManagerStateService }); }
|