From b4750a62c074574a7218e421d5f066191413f54c Mon Sep 17 00:00:00 2001 From: Julia Samol Date: Mon, 11 Sep 2023 13:27:49 +0200 Subject: [PATCH 1/2] Feat/iso improved ui --- .../plugin/isolatedmodules/FileExplorer.kt | 6 +++++ .../plugin/isolatedmodules/IsolatedModules.kt | 24 +++++++++++++++++ ios/App/App.xcodeproj/project.pbxproj | 4 +++ .../Extensions/Dictionary+Additions.swift | 26 ++++++++++++++++++ .../App/IsolatedModules/FileExplorer.swift | 14 +++++++--- ios/App/App/IsolatedModules/IsolatedModules.m | 1 + .../App/IsolatedModules/IsolatedModules.swift | 25 +++++++++++++++++ .../JS/Environment/WebViewEnvironment.swift | 27 ++++++++++++------- ios/App/Podfile.lock | 4 +-- package.json | 4 +-- .../isolated-modules.details.types.ts | 3 ++- .../isolated-modules-list.page.ts | 3 ++- .../pages/tab-settings/tab-settings.page.html | 4 +-- src/global.scss | 7 +++++ yarn.lock | 16 +++++------ 15 files changed, 139 insertions(+), 29 deletions(-) create mode 100644 ios/App/App/Helpers/Extensions/Dictionary+Additions.swift diff --git a/android/app/src/main/java/it/airgap/vault/plugin/isolatedmodules/FileExplorer.kt b/android/app/src/main/java/it/airgap/vault/plugin/isolatedmodules/FileExplorer.kt index 38ef7cf6..db0401e5 100644 --- a/android/app/src/main/java/it/airgap/vault/plugin/isolatedmodules/FileExplorer.kt +++ b/android/app/src/main/java/it/airgap/vault/plugin/isolatedmodules/FileExplorer.kt @@ -54,6 +54,12 @@ class FileExplorer private constructor( fun loadInstalledModules(): List = loadModules(filesExplorer, JSModule.Installed.constructor) + fun loadAssetModule(identifier: String): JSModule.Asset { + val manifest = JSObject(assetsExplorer.readModuleManifest(identifier).decodeToString()) + + return loadModule(identifier, manifest, JSModule.Asset.constructor) + } + fun loadInstalledModule(identifier: String): JSModule.Installed { val manifest = JSObject(filesExplorer.readModuleManifest(identifier).decodeToString()) diff --git a/android/app/src/main/java/it/airgap/vault/plugin/isolatedmodules/IsolatedModules.kt b/android/app/src/main/java/it/airgap/vault/plugin/isolatedmodules/IsolatedModules.kt index 6a2756c1..567ade84 100644 --- a/android/app/src/main/java/it/airgap/vault/plugin/isolatedmodules/IsolatedModules.kt +++ b/android/app/src/main/java/it/airgap/vault/plugin/isolatedmodules/IsolatedModules.kt @@ -141,6 +141,30 @@ class IsolatedModules : Plugin() { } } + @PluginMethod + fun readAssetModule(call: PluginCall) { + call.executeCatching { + assertReceived(Param.IDENTIFIER) + + activity.lifecycleScope.launch { + executeCatching { + val module = fileExplorer.loadAssetModule(identifier) + val manifest = fileExplorer.readModuleManifest(module) + + resolve( + JSObject( + """ + { + "manifest": ${JSObject(manifest.decodeToString())} + } + """.trimIndent() + ) + ) + } + } + } + } + @PluginMethod fun loadAllModules(call: PluginCall) { activity.lifecycleScope.launch { diff --git a/ios/App/App.xcodeproj/project.pbxproj b/ios/App/App.xcodeproj/project.pbxproj index dc02fb4d..9d650bd5 100644 --- a/ios/App/App.xcodeproj/project.pbxproj +++ b/ios/App/App.xcodeproj/project.pbxproj @@ -42,6 +42,7 @@ A351B44E297965EF00BE0DC9 /* Zip.m in Sources */ = {isa = PBXBuildFile; fileRef = A351B44D297965EF00BE0DC9 /* Zip.m */; }; A35472FD29ED9C7C00AFD5A7 /* Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A35472FC29ED9C7C00AFD5A7 /* Hex.swift */; }; A357ED09299BD8EA00EDCA39 /* Filesystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A357ED08299BD8EA00EDCA39 /* Filesystem.swift */; }; + A3BD9A0D2AA5E7EE00666155 /* Dictionary+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3BD9A0C2AA5E7EE00666155 /* Dictionary+Additions.swift */; }; A3C53AA1299247640059E997 /* JSEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3C53AA0299247640059E997 /* JSEnvironment.swift */; }; A3C53AA3299259FC0059E997 /* WebViewEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3C53AA2299259FC0059E997 /* WebViewEnvironment.swift */; }; A3C53AA52992711E0059E997 /* Sequence+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3C53AA42992711E0059E997 /* Sequence+Additions.swift */; }; @@ -89,6 +90,7 @@ A351B44D297965EF00BE0DC9 /* Zip.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Zip.m; sourceTree = ""; }; A35472FC29ED9C7C00AFD5A7 /* Hex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Hex.swift; sourceTree = ""; }; A357ED08299BD8EA00EDCA39 /* Filesystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Filesystem.swift; sourceTree = ""; }; + A3BD9A0C2AA5E7EE00666155 /* Dictionary+Additions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+Additions.swift"; sourceTree = ""; }; A3C53AA0299247640059E997 /* JSEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSEnvironment.swift; sourceTree = ""; }; A3C53AA2299259FC0059E997 /* WebViewEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewEnvironment.swift; sourceTree = ""; }; A3C53AA42992711E0059E997 /* Sequence+Additions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sequence+Additions.swift"; sourceTree = ""; }; @@ -218,6 +220,7 @@ A33BA9E628D9C52D00BD8015 /* JSValue+Additions.swift */, A33BA9E828D9E23E00BD8015 /* WK+Additions.swift */, A3C53AA42992711E0059E997 /* Sequence+Additions.swift */, + A3BD9A0C2AA5E7EE00666155 /* Dictionary+Additions.swift */, ); path = Extensions; sourceTree = ""; @@ -419,6 +422,7 @@ A33BA9E728D9C52D00BD8015 /* JSValue+Additions.swift in Sources */, A3226AAC29F12FA10006ACCA /* Environment.m in Sources */, A3CF6E4D28CA2FA100A9A883 /* IsolatedModules.swift in Sources */, + A3BD9A0D2AA5E7EE00666155 /* Dictionary+Additions.swift in Sources */, A3E4DE8F299157C2009F3C8D /* JSModule.swift in Sources */, 885F55E825EE224200D85A88 /* SaplingNative.m in Sources */, 49690A7E25C2BF80004A3586 /* VaultError.swift in Sources */, diff --git a/ios/App/App/Helpers/Extensions/Dictionary+Additions.swift b/ios/App/App/Helpers/Extensions/Dictionary+Additions.swift new file mode 100644 index 00000000..1fa484f2 --- /dev/null +++ b/ios/App/App/Helpers/Extensions/Dictionary+Additions.swift @@ -0,0 +1,26 @@ +// +// Dictionary+Additions.swift +// App +// +// Created by Julia Samol on 04.09.23. +// + +import Foundation + +extension Dictionary { + @inlinable subscript(key: Key, setDefault defaultValue: @autoclosure () -> Value) -> Value { + mutating get { + guard let value = self[key] else { + let value = defaultValue() + self[key] = value + + return value + } + + return value + } + set { + self[key] = newValue + } + } +} diff --git a/ios/App/App/IsolatedModules/FileExplorer.swift b/ios/App/App/IsolatedModules/FileExplorer.swift index 9cddb43c..11fc969b 100644 --- a/ios/App/App/IsolatedModules/FileExplorer.swift +++ b/ios/App/App/IsolatedModules/FileExplorer.swift @@ -31,16 +31,22 @@ struct FileExplorer { try loadModules(using: assetsExplorer, creatingModuleWith: JSModule.Asset.getInit()) } + func loadInstalledModules() throws -> [JSModule.Installed] { + try loadModules(using: documentExplorer, creatingModuleWith: JSModule.Installed.getInit(using: documentExplorer)) + } + + func loadAssetModule(_ identifier: String) throws -> JSModule.Asset { + let manifest = try assetsExplorer.readModuleManifest(identifier) + + return try loadModule(identifier, fromManifest: manifest, creatingModuleWith: JSModule.Asset.getInit()) + } + func loadInstalledModule(_ identifier: String) throws -> JSModule.Installed { let manifest = try documentExplorer.readModuleManifest(identifier) return try loadModule(identifier, fromManifest: manifest, creatingModuleWith: JSModule.Installed.getInit(using: documentExplorer)) } - func loadInstalledModules() throws -> [JSModule.Installed] { - try loadModules(using: documentExplorer, creatingModuleWith: JSModule.Installed.getInit(using: documentExplorer)) - } - func loadPreviewModule(atPath path: String, locatedIn directory: Directory) throws -> JSModule.Preview { guard let directory = fileManager.getDirectory(from: directory), let url = fileManager.urls(for: directory, in: .userDomainMask).first?.appendingPathComponent(path) else { diff --git a/ios/App/App/IsolatedModules/IsolatedModules.m b/ios/App/App/IsolatedModules/IsolatedModules.m index 5829e949..c287a77b 100644 --- a/ios/App/App/IsolatedModules/IsolatedModules.m +++ b/ios/App/App/IsolatedModules/IsolatedModules.m @@ -14,6 +14,7 @@ CAP_PLUGIN_METHOD(registerDynamicModule, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(readDynamicModule, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(removeDynamicModules, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(readAssetModule, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(loadAllModules, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(callMethod, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(batchCallMethod, CAPPluginReturnPromise); diff --git a/ios/App/App/IsolatedModules/IsolatedModules.swift b/ios/App/App/IsolatedModules/IsolatedModules.swift index 8d7825ec..7a631089 100644 --- a/ios/App/App/IsolatedModules/IsolatedModules.swift +++ b/ios/App/App/IsolatedModules/IsolatedModules.swift @@ -143,6 +143,31 @@ public class IsolatedModules: CAPPlugin { } } + @objc func readAssetModule(_ call: CAPPluginCall) { + call.assertReceived(forMethod: "readAssetModule", requiredParams: Param.IDENTIFIER) + + do { + guard let identifier = call.identifier else { + throw Error.invalidData + } + + Task { + do { + let module = try fileExplorer.loadAssetModule(identifier) + let manifest = try fileExplorer.readModuleManifest(.asset(module)) + + call.resolve([ + "manifest": try JSONSerialization.jsonObject(with: manifest) + ]) + } catch { + call.reject("Error: \(error)") + } + } + } catch { + call.reject("Error: \(error)") + } + } + @objc func loadAllModules(_ call: CAPPluginCall) { Task { do { diff --git a/ios/App/App/IsolatedModules/JS/Environment/WebViewEnvironment.swift b/ios/App/App/IsolatedModules/JS/Environment/WebViewEnvironment.swift index 6fa36269..5ce0ae21 100644 --- a/ios/App/App/IsolatedModules/JS/Environment/WebViewEnvironment.swift +++ b/ios/App/App/IsolatedModules/JS/Environment/WebViewEnvironment.swift @@ -42,7 +42,7 @@ class WebViewEnvironment: NSObject, JSEnvironment, WKNavigationDelegate { ); """ - webView.evaluateJavaScript(script, completionHandler: nil) + try await webView.evaluateJavaScriptAsync(script) guard let result = try await jsAsyncResult.awaitResultWithID(resultID) as? [String: Any] else { throw Error.invalidResult } @@ -72,7 +72,7 @@ class WebViewEnvironment: NSObject, JSEnvironment, WKNavigationDelegate { private actor WebViewManager { private(set) var webViews: [String: [String: WKWebViewExtended]] = [:] - @MainActor private var activeTasks: [String: Task] = [:] + @MainActor private var activeTasks: [String: [String: Task]] = [:] func add( runRef: String, @@ -81,11 +81,7 @@ class WebViewEnvironment: NSObject, JSEnvironment, WKNavigationDelegate { userContentController: WKUserContentController, jsAsyncResult: JSAsyncResult ) { - if webViews[runRef] == nil { - webViews[runRef] = .init() - } - - webViews[runRef]![module.identifier] = (webView, userContentController, jsAsyncResult) + webViews[runRef, setDefault: .init()][module.identifier] = (webView, userContentController, jsAsyncResult) } @MainActor @@ -94,7 +90,7 @@ class WebViewEnvironment: NSObject, JSEnvironment, WKNavigationDelegate { and module: JSModule, using env: WebViewEnvironment ) async throws -> WKWebViewExtended { - if let runRef = runRef, let activeTask = activeTasks[runRef] { + if let runRef = runRef, let activeTask = activeTasks[runRef]?[module.identifier] { return try await activeTask.value } @@ -153,7 +149,7 @@ class WebViewEnvironment: NSObject, JSEnvironment, WKNavigationDelegate { } if let runRef = runRef { - activeTasks[runRef] = task + activeTasks[runRef, setDefault: .init()][module.identifier] = task } return try await task.value @@ -173,10 +169,16 @@ class WebViewEnvironment: NSObject, JSEnvironment, WKNavigationDelegate { func remove(at runRef: String) { webViews.removeValue(forKey: runRef) + Task { @MainActor in + activeTasks.removeValue(forKey: runRef) + } } func removeAll() { webViews.removeAll() + Task { @MainActor in + activeTasks.removeAll() + } } @MainActor @@ -198,3 +200,10 @@ class WebViewEnvironment: NSObject, JSEnvironment, WKNavigationDelegate { private typealias WKWebViewExtended = (WKWebView, WKUserContentController, JSAsyncResult) } + + +// MARK: Extensions + +private extension Dictionary where Value == String { + +} diff --git a/ios/App/Podfile.lock b/ios/App/Podfile.lock index db963ab1..4f8ad2de 100644 --- a/ios/App/Podfile.lock +++ b/ios/App/Podfile.lock @@ -8,7 +8,7 @@ PODS: - CapacitorClipboard (5.0.6): - Capacitor - CapacitorCordova (5.2.2) - - CapacitorFilesystem (5.1.1): + - CapacitorFilesystem (5.1.2): - Capacitor - CapacitorSplashScreen (5.0.6): - Capacitor @@ -65,7 +65,7 @@ SPEC CHECKSUMS: CapacitorAppLauncher: 5a9f06c13c6b4f5d65b550a07128ef04f3a216b3 CapacitorClipboard: 77edf49827ea21da2a9c05c690a4a6a4d07199c4 CapacitorCordova: 3773395d5331add072300ff6041ca2cf7b93cb0b - CapacitorFilesystem: 38e85e56818420bed3f0aa1b77128f503a960821 + CapacitorFilesystem: 5efb77d5dc1c8c05bce5e19f0e7bfdf72363fb43 CapacitorSplashScreen: 5fa2ab5e46cf5cc530cf16a51c80c7a986579ccd CapacitorStatusBar: 565c0a1ebd79bb40d797606a8992b4a105885309 CapawesomeCapacitorFilePicker: 3c6c193300649c9c7ce49426e17582edbf7ed601 diff --git a/package.json b/package.json index b9dbf4fa..0cc085fc 100644 --- a/package.json +++ b/package.json @@ -57,8 +57,8 @@ }, "dependencies": { "@airgap/aeternity": "0.13.20", - "@airgap/angular-core": "0.0.41", - "@airgap/angular-ngrx": "0.0.41", + "@airgap/angular-core": "0.0.42-beta.2", + "@airgap/angular-ngrx": "0.0.42-beta.2", "@airgap/astar": "0.13.20", "@airgap/bitcoin": "0.13.20", "@airgap/coinlib-core": "0.13.20", diff --git a/src/app/pages/isolated-modules-details/isolated-modules.details.types.ts b/src/app/pages/isolated-modules-details/isolated-modules.details.types.ts index 9b76ea31..01ab6ecd 100644 --- a/src/app/pages/isolated-modules-details/isolated-modules.details.types.ts +++ b/src/app/pages/isolated-modules-details/isolated-modules.details.types.ts @@ -1,5 +1,6 @@ export enum IsolatedModulesDetailsMode { INSTALL, UPDATE, - VIEW_INSTALLED + VIEW_INSTALLED, + VIEW_ASSET } \ No newline at end of file diff --git a/src/app/pages/isolated-modules-list/isolated-modules-list.page.ts b/src/app/pages/isolated-modules-list/isolated-modules-list.page.ts index 484d34ca..beba7ab6 100644 --- a/src/app/pages/isolated-modules-list/isolated-modules-list.page.ts +++ b/src/app/pages/isolated-modules-list/isolated-modules-list.page.ts @@ -72,7 +72,8 @@ export class IsolatedModulesListPage implements OnInit, ViewWillEnter, ViewWillL } public async onModuleSelected(metadata: IsolatedModuleMetadata): Promise { - this.navigationService.routeWithState(`/isolated-modules-details/${IsolatedModulesDetailsMode.VIEW_INSTALLED}`, { metadata, mode: IsolatedModulesDetailsMode.VIEW_INSTALLED }).catch(handleErrorLocal(ErrorCategory.IONIC_NAVIGATION)) + const mode = metadata.type === 'asset' ? IsolatedModulesDetailsMode.VIEW_ASSET : IsolatedModulesDetailsMode.VIEW_INSTALLED + this.navigationService.routeWithState(`/isolated-modules-details/${mode}`, { metadata, mode }).catch(handleErrorLocal(ErrorCategory.IONIC_NAVIGATION)) } private async goToOnboardingPage(): Promise { diff --git a/src/app/pages/tab-settings/tab-settings.page.html b/src/app/pages/tab-settings/tab-settings.page.html index 724b07ee..d7abe28f 100644 --- a/src/app/pages/tab-settings/tab-settings.page.html +++ b/src/app/pages/tab-settings/tab-settings.page.html @@ -33,10 +33,10 @@ {{ 'tab-settings.advanced-mode-type_label' | translate }} - + {{ 'tab-settings.actions_label' | translate }} diff --git a/src/global.scss b/src/global.scss index 541ff6de..4e11960b 100644 --- a/src/global.scss +++ b/src/global.scss @@ -46,6 +46,13 @@ ion-label { image-rendering: pixelated; } +airgap-currency-symbol { + img { + aspect-ratio: 1/1; + border-radius: 50%; + } +} + swiper-container { --swiper-pagination-bullet-inactive-color: var(--ion-color-step-200, #cccccc); --swiper-pagination-color: var(--ion-color-primary, #3880ff); diff --git a/yarn.lock b/yarn.lock index 7c2c3e0d..85883c29 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17,17 +17,17 @@ "@airgap/serializer" "^0.13.20" "@stablelib/ed25519" "^1.0.3" -"@airgap/angular-core@0.0.41": - version "0.0.41" - resolved "https://registry.yarnpkg.com/@airgap/angular-core/-/angular-core-0.0.41.tgz#6d626b6dd2eb60c2625e1b59ac5076a213be14a1" - integrity sha512-Tp9f+Hegws40wW2eoMHau7i/YSFkXTZMn3+w0P1EuNIO839fRYoLEFR30W1ctRWMpJJZkwjHZPjWRGCGPJxCEg== +"@airgap/angular-core@0.0.42-beta.2": + version "0.0.42-beta.2" + resolved "https://registry.yarnpkg.com/@airgap/angular-core/-/angular-core-0.0.42-beta.2.tgz#a7f994257da2fbe4537724144f9acf46ccfebe00" + integrity sha512-di0yalK1sXJ/gjxrfjcynnrOqNrQht4Y+TABUngUHYt6DRLECsPIv8BuAOZcT/QB1KhYsfWOe4ZSAyXQObMWug== dependencies: tslib "^2.3.0" -"@airgap/angular-ngrx@0.0.41": - version "0.0.41" - resolved "https://registry.yarnpkg.com/@airgap/angular-ngrx/-/angular-ngrx-0.0.41.tgz#76a65f19a2858ebecda071376ce8b01aeb69657b" - integrity sha512-QmVe0+uWf/HH1V/rBxUXov9tk1FhpIuC5aH736HngKTyLeH4mdpJqkYAVugBDe6trcVz7hWF04kpnzSE1xtZ0w== +"@airgap/angular-ngrx@0.0.42-beta.2": + version "0.0.42-beta.2" + resolved "https://registry.yarnpkg.com/@airgap/angular-ngrx/-/angular-ngrx-0.0.42-beta.2.tgz#256a74c9920b99ab634220179b2ce9b45f440eb1" + integrity sha512-Asm42hB3B4ER/TTir/Qb+GRtVUsDgKVw0VL0NkH/cse0ZaEpZmwcnahgSCOq3ycvGRa6bO8bNnyULnoqh/WF1g== dependencies: tslib "^2.3.0" From fcc1833166ee64a164bcfc170f1a466476135a34 Mon Sep 17 00:00:00 2001 From: Mike Godenzi Date: Mon, 25 Sep 2023 15:46:49 +0200 Subject: [PATCH 2/2] chore: updated dependencies --- package.json | 4 ++-- yarn.lock | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 0cc085fc..04c6624c 100644 --- a/package.json +++ b/package.json @@ -57,8 +57,8 @@ }, "dependencies": { "@airgap/aeternity": "0.13.20", - "@airgap/angular-core": "0.0.42-beta.2", - "@airgap/angular-ngrx": "0.0.42-beta.2", + "@airgap/angular-core": "0.0.42", + "@airgap/angular-ngrx": "0.0.42", "@airgap/astar": "0.13.20", "@airgap/bitcoin": "0.13.20", "@airgap/coinlib-core": "0.13.20", diff --git a/yarn.lock b/yarn.lock index 85883c29..f187eae3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17,17 +17,17 @@ "@airgap/serializer" "^0.13.20" "@stablelib/ed25519" "^1.0.3" -"@airgap/angular-core@0.0.42-beta.2": - version "0.0.42-beta.2" - resolved "https://registry.yarnpkg.com/@airgap/angular-core/-/angular-core-0.0.42-beta.2.tgz#a7f994257da2fbe4537724144f9acf46ccfebe00" - integrity sha512-di0yalK1sXJ/gjxrfjcynnrOqNrQht4Y+TABUngUHYt6DRLECsPIv8BuAOZcT/QB1KhYsfWOe4ZSAyXQObMWug== +"@airgap/angular-core@0.0.42": + version "0.0.42" + resolved "https://registry.yarnpkg.com/@airgap/angular-core/-/angular-core-0.0.42.tgz#7c5a99eeb6198da44e0ea315f181806d3f94e6a3" + integrity sha512-JKaVotRywvtEGENR/oVcEfWTQnGrrn163Kgz6CAeibOJw6/RNdkBD6suxlxCvz7ne+dMPd9su2kI5OhFKVq3Wg== dependencies: tslib "^2.3.0" -"@airgap/angular-ngrx@0.0.42-beta.2": - version "0.0.42-beta.2" - resolved "https://registry.yarnpkg.com/@airgap/angular-ngrx/-/angular-ngrx-0.0.42-beta.2.tgz#256a74c9920b99ab634220179b2ce9b45f440eb1" - integrity sha512-Asm42hB3B4ER/TTir/Qb+GRtVUsDgKVw0VL0NkH/cse0ZaEpZmwcnahgSCOq3ycvGRa6bO8bNnyULnoqh/WF1g== +"@airgap/angular-ngrx@0.0.42": + version "0.0.42" + resolved "https://registry.yarnpkg.com/@airgap/angular-ngrx/-/angular-ngrx-0.0.42.tgz#b85aff5f9f6a6c61000339b38030d012b122f2da" + integrity sha512-89KsCtmWdzgwARouRN9mPiJShbPXLg5f6HPOzoeMXCzP+e5k3B0RurspPYpjgz4S52O/k7I1YaAyMMqRNq0NIQ== dependencies: tslib "^2.3.0"