http-request-manager 18.15.11 → 18.15.13
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.
|
@@ -1065,8 +1065,7 @@ function safeJsonParse(jsonStr, fallback) {
|
|
|
1065
1065
|
try {
|
|
1066
1066
|
return JSON.parse(jsonStr);
|
|
1067
1067
|
}
|
|
1068
|
-
catch
|
|
1069
|
-
console.warn('Failed to parse JSON:', jsonStr.substring(0, 100));
|
|
1068
|
+
catch {
|
|
1070
1069
|
return fallback || null;
|
|
1071
1070
|
}
|
|
1072
1071
|
}
|
|
@@ -1078,8 +1077,7 @@ function safeJsonArrayParse(jsonStr, fallback = []) {
|
|
|
1078
1077
|
const parsed = JSON.parse(jsonStr);
|
|
1079
1078
|
return Array.isArray(parsed) ? parsed : fallback;
|
|
1080
1079
|
}
|
|
1081
|
-
catch
|
|
1082
|
-
console.warn('Failed to parse JSON array:', jsonStr.substring(0, 100));
|
|
1080
|
+
catch {
|
|
1083
1081
|
return fallback;
|
|
1084
1082
|
}
|
|
1085
1083
|
}
|
|
@@ -6437,7 +6435,10 @@ class QueryParamsTrackerService {
|
|
|
6437
6435
|
checkRequestOptions(requestOptions = [], options = {}) {
|
|
6438
6436
|
this.ensureStateRestored();
|
|
6439
6437
|
if (!this.ready$.value) {
|
|
6440
|
-
|
|
6438
|
+
// When tracker hasn't restored from localStorage yet, block the request
|
|
6439
|
+
// so cached/state data is used instead of making a redundant API call.
|
|
6440
|
+
// This prevents the first-call-after-refresh race condition.
|
|
6441
|
+
return false;
|
|
6441
6442
|
}
|
|
6442
6443
|
const normalized = this.normalizeRequestOptions(requestOptions);
|
|
6443
6444
|
if (!normalized.pathKey)
|
|
@@ -7273,99 +7274,7 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7273
7274
|
table: this.databaseOptions?.table,
|
|
7274
7275
|
databaseOptions: this.databaseOptions
|
|
7275
7276
|
});
|
|
7276
|
-
|
|
7277
|
-
return this.dbManagerService.databaseExists().pipe(switchMap((dbExists) => {
|
|
7278
|
-
if (!dbExists) {
|
|
7279
|
-
const initObs = this.initDBStorageAsync();
|
|
7280
|
-
return initObs.pipe(switchMap(() => fetchFromAPI()), catchError((error) => {
|
|
7281
|
-
console.warn('[DB STORAGE] initDBStorageAsync failed when DB did not exist, continuing with API:', error);
|
|
7282
|
-
return fetchFromAPI();
|
|
7283
|
-
}));
|
|
7284
|
-
}
|
|
7285
|
-
return this.dbManagerService.hasDatabaseTable(this.databaseOptions.table).pipe(switchMap((tableExists) => {
|
|
7286
|
-
if (!tableExists) {
|
|
7287
|
-
const initObs = this.initDBStorageAsync();
|
|
7288
|
-
return initObs.pipe(switchMap(() => fetchFromAPI()), catchError((error) => {
|
|
7289
|
-
console.warn('[DB STORAGE] initDBStorageAsync failed when table missing, continuing with API:', error);
|
|
7290
|
-
return fetchFromAPI();
|
|
7291
|
-
}));
|
|
7292
|
-
}
|
|
7293
|
-
return this.localStorageManagerService.store$(this.databaseOptions.table).pipe(take(1), switchMap((storeData) => {
|
|
7294
|
-
console.log('[CacheDebug] storeData for table:', this.databaseOptions.table, { storeData, requestCache: storeData?.requestCache, expires: storeData?.expires });
|
|
7295
|
-
const forceRefresh = !!options?.forceRefresh;
|
|
7296
|
-
const storedSchemaSignature = this.getStoredSchemaSignature(storeData);
|
|
7297
|
-
const expires = storeData?.expires || 0;
|
|
7298
|
-
const hasExpired = expires > 0 && this.utils.hasExpired(expires);
|
|
7299
|
-
if (forceRefresh) {
|
|
7300
|
-
return fetchFromAPI();
|
|
7301
|
-
}
|
|
7302
|
-
if (hasExpired) {
|
|
7303
|
-
return this.dbManagerService.clearTable(this.databaseOptions.table).pipe(switchMap(() => fetchFromAPI()));
|
|
7304
|
-
}
|
|
7305
|
-
const expectedSchema = this.buildSchemaFromAdapter();
|
|
7306
|
-
const expectedSchemaSignature = this.buildSchemaSignature(expectedSchema);
|
|
7307
|
-
console.log('[CacheDebug] schema check:', { tableName: this.databaseOptions.table, storedSchemaSignature, expectedSchemaSignature, mismatch: storedSchemaSignature && storedSchemaSignature !== expectedSchemaSignature });
|
|
7308
|
-
if (storedSchemaSignature && storedSchemaSignature !== expectedSchemaSignature) {
|
|
7309
|
-
const tableDef = TableSchemaDef.adapt({ table: this.databaseOptions.table, schema: expectedSchema });
|
|
7310
|
-
return this.dbManagerService.clearTable(this.databaseOptions.table).pipe(switchMap(() => this.dbManagerService.createDatabaseTable(tableDef)), switchMap(() => fetchFromAPI()));
|
|
7311
|
-
}
|
|
7312
|
-
const trackerAllowsRequest = this.checkTrackerAllowsRequest(this.databaseOptions.table, this.resolvePath(effectiveParams), options, storeData);
|
|
7313
|
-
if (trackerAllowsRequest) {
|
|
7314
|
-
const normalizedPath = this.trackerNormalizePath(this.resolvePath(effectiveParams));
|
|
7315
|
-
if (!normalizedPath.hasQuery) {
|
|
7316
|
-
return this.dbManagerService.getTableRecords(this.databaseOptions.table).pipe(switchMap((dbData) => {
|
|
7317
|
-
if (Array.isArray(dbData) && dbData.length > 0) {
|
|
7318
|
-
this.setData$(dbData);
|
|
7319
|
-
// Save cache metadata for both GET and STREAM request types so
|
|
7320
|
-
// tracker/check logic can detect cached responses regardless
|
|
7321
|
-
// of whether a subsequent call is a normal GET or a streaming GET.
|
|
7322
|
-
const getSignature = requestSignature;
|
|
7323
|
-
const streamRequestOptions = { ...(requestOptions || {}), stream: true };
|
|
7324
|
-
const streamSignature = this.buildRequestSignature('STREAM', streamRequestOptions, effectiveParams);
|
|
7325
|
-
this.saveRequestCacheMetadata(this.databaseOptions.table, 'GET', getSignature, storedSchemaSignature ?? expectedSchemaSignature ?? undefined, options);
|
|
7326
|
-
this.saveRequestCacheMetadata(this.databaseOptions.table, 'STREAM', streamSignature, storedSchemaSignature ?? expectedSchemaSignature ?? undefined, options);
|
|
7327
|
-
return of({ data: dbData, fromCache: true });
|
|
7328
|
-
}
|
|
7329
|
-
return fetchFromAPI();
|
|
7330
|
-
}), catchError((error) => {
|
|
7331
|
-
const tableName = this.databaseOptions.table;
|
|
7332
|
-
console.warn('[DB STORAGE] fallback cache read failed, falling back to API:', { table: tableName, error });
|
|
7333
|
-
return fetchFromAPI();
|
|
7334
|
-
}));
|
|
7335
|
-
}
|
|
7336
|
-
return fetchFromAPI();
|
|
7337
|
-
}
|
|
7338
|
-
return this.dbManagerService.getTableRecords(this.databaseOptions.table).pipe(switchMap((dbData) => {
|
|
7339
|
-
if (Array.isArray(dbData) && dbData.length > 0) {
|
|
7340
|
-
this.setData$(dbData);
|
|
7341
|
-
this.saveRequestCacheMetadata(this.databaseOptions.table, 'GET', requestSignature, storedSchemaSignature ?? expectedSchemaSignature ?? undefined, options);
|
|
7342
|
-
return of(dbData);
|
|
7343
|
-
}
|
|
7344
|
-
const currentStateData = this.get()?.data;
|
|
7345
|
-
if (Array.isArray(currentStateData) && currentStateData.length > 0) {
|
|
7346
|
-
return of(currentStateData);
|
|
7347
|
-
}
|
|
7348
|
-
if (currentStateData &&
|
|
7349
|
-
!Array.isArray(currentStateData) &&
|
|
7350
|
-
Object.keys(currentStateData).length > 0) {
|
|
7351
|
-
return of(currentStateData);
|
|
7352
|
-
}
|
|
7353
|
-
return of(this.dataType === DataType.ARRAY ? [] : {});
|
|
7354
|
-
}), catchError((error) => {
|
|
7355
|
-
const tableName = this.databaseOptions.table;
|
|
7356
|
-
console.warn('[DB STORAGE] getTableRecords failed, recreating table and falling back to API:', { table: tableName, error });
|
|
7357
|
-
const schema = this.buildSchemaFromAdapter();
|
|
7358
|
-
const tableDef = TableSchemaDef.adapt({ table: tableName, schema });
|
|
7359
|
-
return this.dbManagerService.createDatabaseTable(tableDef).pipe(switchMap(() => fetchFromAPI()), catchError((recreateError) => {
|
|
7360
|
-
console.error('[DB STORAGE] Failed to recreate table after read error, continuing with API only:', recreateError);
|
|
7361
|
-
return fetchFromAPI();
|
|
7362
|
-
}));
|
|
7363
|
-
}));
|
|
7364
|
-
}));
|
|
7365
|
-
}));
|
|
7366
|
-
}));
|
|
7367
|
-
}
|
|
7368
|
-
return fetchFromAPI();
|
|
7277
|
+
return this.resolveCacheDecision('GET', requestOptions, effectiveParams, options, fetchFromAPI);
|
|
7369
7278
|
})));
|
|
7370
7279
|
// FETCH RECORD
|
|
7371
7280
|
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) => {
|
|
@@ -7505,62 +7414,29 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7505
7414
|
const requestOptions = this.updateRequestOptions(options?.headers);
|
|
7506
7415
|
requestOptions.stream = true;
|
|
7507
7416
|
const effectiveParams = this.getEffectiveParams(options?.path);
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7512
|
-
if (
|
|
7513
|
-
|
|
7514
|
-
if (Array.isArray(currentStateData) && currentStateData.length > 0) {
|
|
7515
|
-
return of({ data: currentStateData, fromCache: true });
|
|
7516
|
-
}
|
|
7517
|
-
if (currentStateData &&
|
|
7518
|
-
!Array.isArray(currentStateData) &&
|
|
7519
|
-
Object.keys(currentStateData).length > 0) {
|
|
7520
|
-
return of({ data: currentStateData, fromCache: true });
|
|
7521
|
-
}
|
|
7522
|
-
return of({ data: this.dataType === DataType.ARRAY ? [] : {}, fromCache: true });
|
|
7523
|
-
}
|
|
7524
|
-
this.setCachedRequestSignature(this.databaseOptions.table, 'STREAM', requestSignature);
|
|
7525
|
-
return this.httpManagerService.getRequest(requestOptions, effectiveParams).pipe(map((apiData) => ({ data: apiData, fromCache: false })), finalize(() => this.endInFlightRequest(requestSignature)));
|
|
7526
|
-
};
|
|
7527
|
-
return this.localStorageManagerService.store$(this.databaseOptions.table).pipe(take(1), switchMap((storeData) => {
|
|
7528
|
-
const forceRefresh = !!options?.forceRefresh;
|
|
7529
|
-
const expires = storeData?.expires || 0;
|
|
7530
|
-
const hasExpired = expires > 0 && this.utils.hasExpired(expires);
|
|
7531
|
-
if (forceRefresh) {
|
|
7532
|
-
return fetchStreamFromAPI();
|
|
7533
|
-
}
|
|
7534
|
-
if (hasExpired) {
|
|
7535
|
-
return this.dbManagerService.clearTable(this.databaseOptions.table).pipe(switchMap(() => fetchStreamFromAPI()));
|
|
7417
|
+
const requestSignature = this.buildRequestSignature('STREAM', requestOptions, effectiveParams);
|
|
7418
|
+
const fetchStreamFromAPI = () => {
|
|
7419
|
+
if (!this.tryBeginInFlightRequest(requestSignature)) {
|
|
7420
|
+
const currentStateData = this.get()?.data;
|
|
7421
|
+
if (Array.isArray(currentStateData) && currentStateData.length > 0) {
|
|
7422
|
+
return of({ data: currentStateData, fromCache: true });
|
|
7536
7423
|
}
|
|
7537
|
-
|
|
7538
|
-
|
|
7539
|
-
|
|
7540
|
-
|
|
7541
|
-
const tableDef = TableSchemaDef.adapt({ table: this.databaseOptions.table, schema: expectedSchema });
|
|
7542
|
-
return this.dbManagerService.clearTable(this.databaseOptions.table).pipe(switchMap(() => this.dbManagerService.createDatabaseTable(tableDef)), switchMap(() => fetchStreamFromAPI()));
|
|
7424
|
+
if (currentStateData &&
|
|
7425
|
+
!Array.isArray(currentStateData) &&
|
|
7426
|
+
Object.keys(currentStateData).length > 0) {
|
|
7427
|
+
return of({ data: currentStateData, fromCache: true });
|
|
7543
7428
|
}
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
|
|
7555
|
-
!Array.isArray(currentStateData) &&
|
|
7556
|
-
Object.keys(currentStateData).length > 0) {
|
|
7557
|
-
return of({ data: currentStateData, fromCache: true });
|
|
7558
|
-
}
|
|
7559
|
-
return of({ data: this.dataType === DataType.ARRAY ? [] : {}, fromCache: true });
|
|
7560
|
-
}));
|
|
7561
|
-
}
|
|
7562
|
-
return fetchStreamFromAPI();
|
|
7563
|
-
})).pipe(tap((packet) => {
|
|
7429
|
+
return of({ data: this.dataType === DataType.ARRAY ? [] : {}, fromCache: true });
|
|
7430
|
+
}
|
|
7431
|
+
if (this.hasDatabase && this.databaseOptions?.table) {
|
|
7432
|
+
this.setCachedRequestSignature(this.databaseOptions.table, 'STREAM', requestSignature);
|
|
7433
|
+
}
|
|
7434
|
+
return this.httpManagerService.getRequest(requestOptions, effectiveParams).pipe(map((apiData) => ({ data: apiData, fromCache: false })), finalize(() => this.endInFlightRequest(requestSignature)));
|
|
7435
|
+
};
|
|
7436
|
+
// Use shared gating decision for parity with GET
|
|
7437
|
+
const cacheDecision$ = this.resolveCacheDecision('STREAM', requestOptions, effectiveParams, options, fetchStreamFromAPI);
|
|
7438
|
+
if (this.hasDatabase && this.databaseOptions?.table) {
|
|
7439
|
+
return cacheDecision$.pipe(tap((packet) => {
|
|
7564
7440
|
const res = packet?.data;
|
|
7565
7441
|
// console.log('[DEBUG] Streaming response received:', res)
|
|
7566
7442
|
if (res && res.length > 0) {
|
|
@@ -7827,6 +7703,129 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
7827
7703
|
});
|
|
7828
7704
|
return [...updatedData, ...addedData];
|
|
7829
7705
|
}
|
|
7706
|
+
// --------------------------------------------------------------------------------------------------
|
|
7707
|
+
// SHARED CACHE GATING DECISION
|
|
7708
|
+
// --------------------------------------------------------------------------------------------------
|
|
7709
|
+
/**
|
|
7710
|
+
* Resolves whether a request should use cached/DB data or call the API.
|
|
7711
|
+
* Shared by both fetchRecords (GET) and fetchStream (STREAM) to ensure parity.
|
|
7712
|
+
*
|
|
7713
|
+
* Decision order:
|
|
7714
|
+
* 1. forceRefresh → API
|
|
7715
|
+
* 2. cache expired → clear + API
|
|
7716
|
+
* 3. schema mismatch → clear + rebuild + API
|
|
7717
|
+
* 4. tracker blocks request → DB/state fallback
|
|
7718
|
+
* 5. tracker allows request → API (with optional no-query DB shortcut)
|
|
7719
|
+
*
|
|
7720
|
+
* Returns an observable of the result data.
|
|
7721
|
+
*/
|
|
7722
|
+
resolveCacheDecision(requestType, requestOptions, effectiveParams, options, fetchFromAPI) {
|
|
7723
|
+
if (!this.hasDatabase || !this.databaseOptions?.table) {
|
|
7724
|
+
return fetchFromAPI();
|
|
7725
|
+
}
|
|
7726
|
+
const requestSignature = this.buildRequestSignature(requestType, requestOptions, effectiveParams);
|
|
7727
|
+
return this.dbManagerService.databaseExists().pipe(switchMap((dbExists) => {
|
|
7728
|
+
if (!dbExists) {
|
|
7729
|
+
return this.initDBStorageAsync().pipe(switchMap(() => fetchFromAPI()), catchError((error) => {
|
|
7730
|
+
console.warn('[DB STORAGE] initDBStorageAsync failed when DB did not exist, continuing with API:', error);
|
|
7731
|
+
return fetchFromAPI();
|
|
7732
|
+
}));
|
|
7733
|
+
}
|
|
7734
|
+
return this.dbManagerService.hasDatabaseTable(this.databaseOptions.table).pipe(switchMap((tableExists) => {
|
|
7735
|
+
if (!tableExists) {
|
|
7736
|
+
return this.initDBStorageAsync().pipe(switchMap(() => fetchFromAPI()), catchError((error) => {
|
|
7737
|
+
console.warn('[DB STORAGE] initDBStorageAsync failed when table missing, continuing with API:', error);
|
|
7738
|
+
return fetchFromAPI();
|
|
7739
|
+
}));
|
|
7740
|
+
}
|
|
7741
|
+
return this.localStorageManagerService.store$(this.databaseOptions.table).pipe(take(1), switchMap((storeData) => {
|
|
7742
|
+
console.log('[CacheDebug] storeData for table:', this.databaseOptions.table, { storeData, requestCache: storeData?.requestCache, expires: storeData?.expires });
|
|
7743
|
+
// 1. forceRefresh → API
|
|
7744
|
+
const forceRefresh = !!options?.forceRefresh;
|
|
7745
|
+
if (forceRefresh) {
|
|
7746
|
+
return fetchFromAPI();
|
|
7747
|
+
}
|
|
7748
|
+
// 2. cache expired → clear + API
|
|
7749
|
+
const expires = storeData?.expires || 0;
|
|
7750
|
+
const hasExpired = expires > 0 && this.utils.hasExpired(expires);
|
|
7751
|
+
if (hasExpired) {
|
|
7752
|
+
return this.dbManagerService.clearTable(this.databaseOptions.table).pipe(switchMap(() => fetchFromAPI()));
|
|
7753
|
+
}
|
|
7754
|
+
// 3. schema mismatch → clear + rebuild + API
|
|
7755
|
+
const storedSchemaSignature = this.getStoredSchemaSignature(storeData);
|
|
7756
|
+
const expectedSchema = this.buildSchemaFromAdapter();
|
|
7757
|
+
const expectedSchemaSignature = this.buildSchemaSignature(expectedSchema);
|
|
7758
|
+
console.log('[CacheDebug] schema check:', { tableName: this.databaseOptions.table, storedSchemaSignature, expectedSchemaSignature, mismatch: storedSchemaSignature && storedSchemaSignature !== expectedSchemaSignature });
|
|
7759
|
+
if (storedSchemaSignature && storedSchemaSignature !== expectedSchemaSignature) {
|
|
7760
|
+
const tableDef = TableSchemaDef.adapt({ table: this.databaseOptions.table, schema: expectedSchema });
|
|
7761
|
+
return this.dbManagerService.clearTable(this.databaseOptions.table).pipe(switchMap(() => this.dbManagerService.createDatabaseTable(tableDef)), switchMap(() => fetchFromAPI()));
|
|
7762
|
+
}
|
|
7763
|
+
// 4 & 5. tracker decision
|
|
7764
|
+
const trackerAllowsRequest = this.checkTrackerAllowsRequest(this.databaseOptions.table, this.resolvePath(effectiveParams), options, storeData);
|
|
7765
|
+
if (trackerAllowsRequest) {
|
|
7766
|
+
// For no-query paths, try DB first before API
|
|
7767
|
+
const normalizedPath = this.trackerNormalizePath(this.resolvePath(effectiveParams));
|
|
7768
|
+
if (!normalizedPath.hasQuery) {
|
|
7769
|
+
return this.dbManagerService.getTableRecords(this.databaseOptions.table).pipe(switchMap((dbData) => {
|
|
7770
|
+
if (Array.isArray(dbData) && dbData.length > 0) {
|
|
7771
|
+
this.setData$(dbData);
|
|
7772
|
+
// Save cache metadata for both GET and STREAM request types so
|
|
7773
|
+
// tracker/check logic can detect cached responses regardless
|
|
7774
|
+
// of whether a subsequent call is a normal GET or a streaming GET.
|
|
7775
|
+
const getSignature = this.buildRequestSignature('GET', requestOptions, effectiveParams);
|
|
7776
|
+
const streamRequestOptions = { ...(requestOptions || {}), stream: true };
|
|
7777
|
+
const streamSignature = this.buildRequestSignature('STREAM', streamRequestOptions, effectiveParams);
|
|
7778
|
+
this.saveRequestCacheMetadata(this.databaseOptions.table, 'GET', getSignature, storedSchemaSignature ?? expectedSchemaSignature ?? undefined, options);
|
|
7779
|
+
this.saveRequestCacheMetadata(this.databaseOptions.table, 'STREAM', streamSignature, storedSchemaSignature ?? expectedSchemaSignature ?? undefined, options);
|
|
7780
|
+
return of({ data: dbData, fromCache: true });
|
|
7781
|
+
}
|
|
7782
|
+
return fetchFromAPI();
|
|
7783
|
+
}), catchError((error) => {
|
|
7784
|
+
const tableName = this.databaseOptions.table;
|
|
7785
|
+
console.warn('[DB STORAGE] fallback cache read failed, falling back to API:', { table: tableName, error });
|
|
7786
|
+
return fetchFromAPI();
|
|
7787
|
+
}));
|
|
7788
|
+
}
|
|
7789
|
+
return fetchFromAPI();
|
|
7790
|
+
}
|
|
7791
|
+
// tracker blocks request → DB/state fallback
|
|
7792
|
+
return this.dbManagerService.getTableRecords(this.databaseOptions.table).pipe(switchMap((dbData) => {
|
|
7793
|
+
if (Array.isArray(dbData) && dbData.length > 0) {
|
|
7794
|
+
this.setData$(dbData);
|
|
7795
|
+
// Save cache metadata for both GET and STREAM request types so
|
|
7796
|
+
// tracker/check logic can detect cached responses regardless
|
|
7797
|
+
// of whether a subsequent call is a normal GET or a streaming GET.
|
|
7798
|
+
const getSignature = this.buildRequestSignature('GET', requestOptions, effectiveParams);
|
|
7799
|
+
const streamRequestOptions = { ...(requestOptions || {}), stream: true };
|
|
7800
|
+
const streamSignature = this.buildRequestSignature('STREAM', streamRequestOptions, effectiveParams);
|
|
7801
|
+
this.saveRequestCacheMetadata(this.databaseOptions.table, 'GET', getSignature, storedSchemaSignature ?? expectedSchemaSignature ?? undefined, options);
|
|
7802
|
+
this.saveRequestCacheMetadata(this.databaseOptions.table, 'STREAM', streamSignature, storedSchemaSignature ?? expectedSchemaSignature ?? undefined, options);
|
|
7803
|
+
return of(dbData);
|
|
7804
|
+
}
|
|
7805
|
+
const currentStateData = this.get()?.data;
|
|
7806
|
+
if (Array.isArray(currentStateData) && currentStateData.length > 0) {
|
|
7807
|
+
return of(currentStateData);
|
|
7808
|
+
}
|
|
7809
|
+
if (currentStateData &&
|
|
7810
|
+
!Array.isArray(currentStateData) &&
|
|
7811
|
+
Object.keys(currentStateData).length > 0) {
|
|
7812
|
+
return of(currentStateData);
|
|
7813
|
+
}
|
|
7814
|
+
return of(this.dataType === DataType.ARRAY ? [] : {});
|
|
7815
|
+
}), catchError((error) => {
|
|
7816
|
+
const tableName = this.databaseOptions.table;
|
|
7817
|
+
console.warn('[DB STORAGE] getTableRecords failed, recreating table and falling back to API:', { table: tableName, error });
|
|
7818
|
+
const schema = this.buildSchemaFromAdapter();
|
|
7819
|
+
const tableDef = TableSchemaDef.adapt({ table: tableName, schema });
|
|
7820
|
+
return this.dbManagerService.createDatabaseTable(tableDef).pipe(switchMap(() => fetchFromAPI()), catchError((recreateError) => {
|
|
7821
|
+
console.error('[DB STORAGE] Failed to recreate table after read error, continuing with API only:', recreateError);
|
|
7822
|
+
return fetchFromAPI();
|
|
7823
|
+
}));
|
|
7824
|
+
}));
|
|
7825
|
+
}));
|
|
7826
|
+
}));
|
|
7827
|
+
}));
|
|
7828
|
+
}
|
|
7830
7829
|
initDBStorageAsync() {
|
|
7831
7830
|
console.log('[initDBStorageAsync] Starting initialization:', {
|
|
7832
7831
|
dataType: this.dataType,
|
|
@@ -8498,7 +8497,7 @@ class HTTPManagerStateService extends ComponentStore {
|
|
|
8498
8497
|
return Math.floor(Date.now() / 1000) + Number(parsed[1]) * seconds;
|
|
8499
8498
|
}
|
|
8500
8499
|
checkTrackerAllowsRequest(tableName, path, options, storeData) {
|
|
8501
|
-
if (options &&
|
|
8500
|
+
if (options && Array.isArray(options.watchParams)) {
|
|
8502
8501
|
return this.queryParamsTrackerService.checkRequestOptions(path, {
|
|
8503
8502
|
watchParams: options.watchParams,
|
|
8504
8503
|
watchExpiresAt: options?.watchExpiresAt,
|