diff --git a/.vscode/settings.json b/.vscode/settings.json index 57227852..32364eae 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,10 +2,10 @@ "dart.lineLength": 100, "editor.formatOnSave": true, "editor.codeActionsOnSave": { - "source.fixAll": true, - "source.organizeImports": true, + "source.fixAll": "explicit", + "source.organizeImports": "explicit" }, "explorer.fileNesting.enabled": true, "explorer.fileNesting.expand": false, - "files.insertFinalNewline": true, + "files.insertFinalNewline": true } diff --git a/packages/brick_offline_first/CHANGELOG.md b/packages/brick_offline_first/CHANGELOG.md index 1249c501..2c0acbbe 100644 --- a/packages/brick_offline_first/CHANGELOG.md +++ b/packages/brick_offline_first/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +* Apply desired policy to all association fetches during `OfflineFirstRepository#get` requests. Fixes #371. + ## 3.1.0 * Apply standardized lints diff --git a/packages/brick_offline_first/lib/src/offline_first_repository.dart b/packages/brick_offline_first/lib/src/offline_first_repository.dart index 795e1a15..065ea425 100644 --- a/packages/brick_offline_first/lib/src/offline_first_repository.dart +++ b/packages/brick_offline_first/lib/src/offline_first_repository.dart @@ -47,6 +47,13 @@ abstract class OfflineFirstRepository /// Defaults to [false]. final bool autoHydrate; + /// Required to maintain the same policy for [getAssociation] requests. + /// This is a stateful variable that should be cleared immediately after + /// it is no longer necessary. + /// + /// See discussion: https://github.com/GetDutchie/brick/issues/371 + OfflineFirstGetPolicy? _latestGetPolicy; + /// The first data source to speed up otherwise taxing queries. Only caches specified models. final MemoryCacheProvider memoryCacheProvider; @@ -179,38 +186,47 @@ abstract class OfflineFirstRepository final hydrateUnexisting = policy == OfflineFirstGetPolicy.awaitRemoteWhenNoneExist; final alwaysHydrate = policy == OfflineFirstGetPolicy.alwaysHydrate; - if (memoryCacheProvider.canFind(query) && !requireRemote) { - final memoryCacheResults = memoryCacheProvider.get(query: query, repository: this); + try { + _latestGetPolicy = policy; + + if (memoryCacheProvider.canFind(query) && !requireRemote) { + final memoryCacheResults = memoryCacheProvider.get(query: query, repository: this); + + if (alwaysHydrate) { + // start round trip for fresh data + // ignore: unawaited_futures + hydrate(query: query, deserializeSqlite: !seedOnly); + } + + if (memoryCacheResults?.isNotEmpty ?? false) return memoryCacheResults!; + } + + final modelExists = await exists(query: query); - if (alwaysHydrate) { + if (requireRemote || (hydrateUnexisting && !modelExists)) { + return await hydrate(query: query, deserializeSqlite: !seedOnly); + } else if (alwaysHydrate) { // start round trip for fresh data // ignore: unawaited_futures hydrate(query: query, deserializeSqlite: !seedOnly); } - if (memoryCacheResults?.isNotEmpty ?? false) return memoryCacheResults!; - } - - final modelExists = await exists(query: query); - - if (requireRemote || (hydrateUnexisting && !modelExists)) { - return await hydrate(query: query, deserializeSqlite: !seedOnly); - } else if (alwaysHydrate) { - // start round trip for fresh data - // ignore: unawaited_futures - hydrate(query: query, deserializeSqlite: !seedOnly); + return await sqliteProvider + .get(query: query, repository: this) + // cache this query + .then((m) => memoryCacheProvider.hydrate(m)); + } finally { + _latestGetPolicy = null; } - - return await sqliteProvider - .get(query: query, repository: this) - // cache this query - .then((m) => memoryCacheProvider.hydrate(m)); } /// Used exclusively by the [OfflineFirstAdapter]. If there are no results, returns `null`. Future?> getAssociation(Query query) async { logger.finest('#getAssociation: $TModel $query'); - final results = await get(query: query); + final results = await get( + query: query, + policy: _latestGetPolicy ?? OfflineFirstGetPolicy.awaitRemoteWhenNoneExist, + ); if (results.isEmpty) return null; return results; }