Skip to content

Commit

Permalink
refactor(patch-db): use PatchDB class declaratively (#1562)
Browse files Browse the repository at this point in the history
* refactor(patch-db): use PatchDB class declaratively

* chore: remove initial source before init

* chore: show spinner

* fix: show Connecting to Embassy spinner until first connection

* fix: switching marketplaces

* allow for subscription to end with take when installing a package

* update patchdb

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
  • Loading branch information
waterplea and elvece committed Jun 22, 2022
1 parent a8749f5 commit 53ca9b0
Show file tree
Hide file tree
Showing 19 changed files with 142 additions and 105 deletions.
14 changes: 12 additions & 2 deletions frontend/projects/ui/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
import { Component } from '@angular/core'
import { Component, Inject, OnDestroy } from '@angular/core'
import { AuthService } from './services/auth.service'
import { SplitPaneTracker } from './services/split-pane.service'
import { merge, Observable } from 'rxjs'
import { GLOBAL_SERVICE } from './app/global/global.module'

@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss'],
})
export class AppComponent {
export class AppComponent implements OnDestroy {
readonly subscription = merge(...this.services).subscribe()

constructor(
@Inject(GLOBAL_SERVICE)
private readonly services: readonly Observable<unknown>[],
readonly authService: AuthService,
private readonly splitPane: SplitPaneTracker,
) {}

splitPaneVisible({ detail }: any) {
this.splitPane.sidebarOpen$.next(detail.visible)
}

ngOnDestroy() {
this.subscription.unsubscribe()
}
}
2 changes: 2 additions & 0 deletions frontend/projects/ui/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { MenuModule } from './app/menu/menu.module'
import { EnterModule } from './app/enter/enter.module'
import { APP_PROVIDERS } from './app.providers'
import { GlobalModule } from './app/global/global.module'
import { PatchDbModule } from './services/patch-db/patch-db.module'

@NgModule({
declarations: [AppComponent],
Expand Down Expand Up @@ -46,6 +47,7 @@ import { GlobalModule } from './app/global/global.module'
SharedPipesModule,
MarketplaceModule,
GlobalModule,
PatchDbModule,
],
providers: APP_PROVIDERS,
bootstrap: [AppComponent],
Expand Down
31 changes: 18 additions & 13 deletions frontend/projects/ui/src/app/app.providers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DOCUMENT } from '@angular/common'
import { Bootstrapper, DBCache } from 'patch-db-client'
import { APP_INITIALIZER, ErrorHandler, Provider } from '@angular/core'
import { FormBuilder } from '@angular/forms'
import { Router, RouteReuseStrategy } from '@angular/router'
Expand All @@ -9,15 +9,11 @@ import { WorkspaceConfig } from '@start9labs/shared'
import { ApiService } from './services/api/embassy-api.service'
import { MockApiService } from './services/api/embassy-mock-api.service'
import { LiveApiService } from './services/api/embassy-live-api.service'
import {
PATCH_SOURCE,
mockSourceFactory,
realSourceFactory,
} from './services/patch-db/patch-db.factory'
import { ConfigService } from './services/config.service'
import { BOOTSTRAPPER, PATCH_CACHE } from './services/patch-db/patch-db.factory'
import { GlobalErrorHandler } from './services/global-error-handler.service'
import { AuthService } from './services/auth.service'
import { LocalStorageService } from './services/local-storage.service'
import { DataModel } from './services/patch-db/data-model'

const { useMocks } = require('../../../../config.json') as WorkspaceConfig

Expand All @@ -32,18 +28,20 @@ export const APP_PROVIDERS: Provider[] = [
provide: ApiService,
useClass: useMocks ? MockApiService : LiveApiService,
},
{
provide: PATCH_SOURCE,
deps: [ApiService, ConfigService, DOCUMENT],
useFactory: useMocks ? mockSourceFactory : realSourceFactory,
},
{
provide: ErrorHandler,
useClass: GlobalErrorHandler,
},
{
provide: APP_INITIALIZER,
deps: [Storage, AuthService, LocalStorageService, Router],
deps: [
Storage,
AuthService,
LocalStorageService,
Router,
BOOTSTRAPPER,
PATCH_CACHE,
],
useFactory: appInitializer,
multi: true,
},
Expand All @@ -54,12 +52,19 @@ export function appInitializer(
auth: AuthService,
localStorage: LocalStorageService,
router: Router,
bootstrapper: Bootstrapper<DataModel>,
cache: DBCache<DataModel>,
): () => Promise<void> {
return async () => {
await storage.create()
await auth.init()
await localStorage.init()

const localCache = await bootstrapper.init()

cache.sequence = localCache.sequence
cache.data = localCache.data

router.initialNavigation()
}
}
20 changes: 5 additions & 15 deletions frontend/projects/ui/src/app/app/global/global.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ import { UnreadToastService } from './services/unread-toast.service'
import { RefreshToastService } from './services/refresh-toast.service'
import { UpdateToastService } from './services/update-toast.service'

const GLOBAL_SERVICE = new InjectionToken<readonly Observable<unknown>[]>(
'A multi token of global Observable services',
)
export const GLOBAL_SERVICE = new InjectionToken<
readonly Observable<unknown>[]
>('A multi token of global Observable services')

// This module is purely for providers organization purposes
@NgModule({
providers: [
[
Expand All @@ -34,18 +35,7 @@ const GLOBAL_SERVICE = new InjectionToken<readonly Observable<unknown>[]>(
[PatchDataService, PatchMonitorService].map(useExisting),
],
})
export class GlobalModule implements OnDestroy {
readonly subscription = merge(...this.services).subscribe()

constructor(
@Inject(GLOBAL_SERVICE)
private readonly services: readonly Observable<unknown>[],
) {}

ngOnDestroy() {
this.subscription.unsubscribe()
}
}
export class GlobalModule {}

function useClass(useClass: Type<unknown>): ClassProvider {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { ApiService } from '../../services/api/embassy-api.service'
import { AppWizardComponent, SlideDefinition } from './app-wizard.component'
import { ConfigService } from 'src/app/services/config.service'
import { MarketplaceService } from 'src/app/services/marketplace.service'
import { first } from 'rxjs/operators'

@Injectable({ providedIn: 'root' })
export class WizardDefs {
Expand Down Expand Up @@ -45,7 +44,6 @@ export class WizardDefs {
id,
'version-spec': version ? `=${version}` : undefined,
})
.pipe(first())
.toPromise(),
},
},
Expand Down Expand Up @@ -87,7 +85,6 @@ export class WizardDefs {
id,
'version-spec': version ? `=${version}` : undefined,
})
.pipe(first())
.toPromise(),
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@

<ion-content class="ion-padding">
<!-- loading -->
<text-spinner
*ngIf="!patch.loaded else data"
text="Connecting to Embassy"
></text-spinner>
<ng-template #loading>
<text-spinner text="Connecting to Embassy"></text-spinner>
</ng-template>

<!-- not loading -->
<ng-template #data>
<ng-container *ngIf="connected$ | async else loading">
<app-list-empty
*ngIf="empty; else list"
class="ion-text-center ion-padding"
Expand All @@ -40,5 +39,5 @@
</ion-item-group>
</ng-container>
</ng-template>
</ng-template>
</ng-container>
</ion-content>
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,17 @@ export class AppListPage {
recoveredPkgs: readonly RecoveredInfo[] = []
order: readonly string[] = []
reordering = false
loading = true

readonly connected$ = this.patch.connected$

constructor(
private readonly api: ApiService,
private readonly destroy$: DestroyService,
public readonly patch: PatchDbService,
private readonly patch: PatchDbService,
) {}

get empty(): boolean {
return (
!this.loading && !this.pkgs.length && isEmptyObject(this.recoveredPkgs)
)
return !this.pkgs.length && isEmptyObject(this.recoveredPkgs)
}

ngOnInit() {
Expand All @@ -43,7 +42,6 @@ export class AppListPage {
this.pkgs = pkgs
this.recoveredPkgs = recoveredPkgs
this.order = order
this.loading = false

// set order in UI DB if there were unknown packages
if (order.length < pkgs.length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class DeveloperMenuPage {
) {}

get name(): string {
return this.patchDb.data.ui?.dev?.[this.projectId]?.name || ''
return this.patchDb.getData().ui?.dev?.[this.projectId]?.name || ''
}

ngOnInit() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<ion-content class="ion-padding">
<marketplace-list-content
*ngIf="loaded else loading"
*ngIf="connected$ | async else loading"
[localPkgs]="(localPkgs$ | async) || {}"
[pkgs]="pkgs$ | async"
[categories]="categories$ | async"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
templateUrl: './marketplace-list.page.html',
})
export class MarketplaceListPage {
readonly connected$ = this.patch.connected$

readonly localPkgs$: Observable<Record<string, PackageDataEntry>> = this.patch
.watch$('package-data')
.pipe(
Expand Down Expand Up @@ -44,8 +46,4 @@ export class MarketplaceListPage {
private readonly patch: PatchDbService,
private readonly marketplaceService: AbstractMarketplaceService,
) {}

get loaded(): boolean {
return this.patch.loaded
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { LocalStorageService } from 'src/app/services/local-storage.service'
import { MarketplaceService } from 'src/app/services/marketplace.service'
import { hasCurrentDeps } from 'src/app/util/has-deps'
import { Emver } from '../../../../../../../shared/src/services/emver.service'
import { first } from 'rxjs/operators'
import { ErrorToastService } from '../../../../../../../shared/src/services/error-toast.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { isEmptyObject } from '../../../../../../../shared/src/util/misc.util'
Expand Down Expand Up @@ -145,7 +144,6 @@ export class MarketplaceShowControlsComponent {
id,
'version-spec': `=${version}`,
})
.pipe(first())
.toPromise()
} catch (e: any) {
this.errToast.present(e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,12 @@ <h4 style="color: #595959; margin-top: 0px">Inbox Empty</h4>
<ion-label>
<h2>
<b>
<span *ngIf="not['package-id'] && patch.data['package-data']">
{{ patch.data['package-data'][not['package-id']] ?
patch.data['package-data'][not['package-id']].manifest.title :
not['package-id'] }} -
<span
*ngIf="not['package-id'] && patch.getData()['package-data']"
>
{{ patch.getData()['package-data'][not['package-id']] ?
patch.getData()['package-data'][not['package-id']].manifest.title
: not['package-id'] }} -
</span>
<ion-text [color]="getColor(not)"> {{ not.title }} </ion-text>
</b>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<ion-header>
<ion-toolbar>
<ion-title *ngIf="patch.loaded else loading">
<ion-title *ngIf="connected$ | async else loading">
{{ (ui$ | async)?.name || "Embassy-" + (server$ | async)?.id }}
</ion-title>
<ng-template #loading>
Expand All @@ -14,13 +14,12 @@

<ion-content class="ion-padding">
<!-- loading -->
<text-spinner
*ngIf="!patch.loaded else data"
text="Connecting to Embassy"
></text-spinner>
<ng-template #spinner>
<text-spinner text="Connecting to Embassy"></text-spinner>
</ng-template>

<!-- not loading -->
<ng-template #data>
<ng-container *ngIf="connected$ | async else spinner">
<ion-item-group *ngIf="server$ | async as server">
<div *ngFor="let cat of settings | keyvalue : asIsOrder">
<ion-item-divider>
Expand Down Expand Up @@ -98,5 +97,5 @@ <h2>{{ button.title }}</h2>
</ng-container>
</div>
</ion-item-group>
</ng-template>
</ng-container>
</ion-content>
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ActivatedRoute } from '@angular/router'
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
import { Observable, of } from 'rxjs'
import { filter, map, take } from 'rxjs/operators'
import { filter, take } from 'rxjs/operators'
import { exists, isEmptyObject, ErrorToastService } from '@start9labs/shared'
import { EOSService } from 'src/app/services/eos.service'
import { LocalStorageService } from 'src/app/services/local-storage.service'
Expand All @@ -28,6 +28,7 @@ export class ServerShowPage {

readonly server$ = this.patch.watch$('server-info')
readonly ui$ = this.patch.watch$('ui')
readonly connected$ = this.patch.connected$

constructor(
private readonly alertCtrl: AlertController,
Expand All @@ -37,8 +38,8 @@ export class ServerShowPage {
private readonly embassyApi: ApiService,
private readonly navCtrl: NavController,
private readonly route: ActivatedRoute,
private readonly patch: PatchDbService,
public readonly eosService: EOSService,
public readonly patch: PatchDbService,
public readonly localStorageService: LocalStorageService,
) {}

Expand Down
8 changes: 4 additions & 4 deletions frontend/projects/ui/src/app/services/marketplace.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
AbstractMarketplaceService,
Marketplace,
} from '@start9labs/marketplace'
import { defer, from, Observable, of } from 'rxjs'
import { from, Observable, of } from 'rxjs'
import { RR } from 'src/app/services/api/api.types'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ConfigService } from 'src/app/services/config.service'
Expand All @@ -32,7 +32,7 @@ export class MarketplaceService extends AbstractMarketplaceService {

private readonly altMarketplaceData$: Observable<
UIMarketplaceData | undefined
> = this.patch.watch$('ui', 'marketplace').pipe(shareReplay())
> = this.patch.watch$('ui', 'marketplace').pipe(shareReplay(1))

private readonly marketplace$ = this.altMarketplaceData$.pipe(
map(data => this.toMarketplace(data)),
Expand All @@ -51,7 +51,7 @@ export class MarketplaceService extends AbstractMarketplaceService {
),
),
map(({ categories }) => categories),
shareReplay(),
shareReplay(1),
)

private readonly pkg$: Observable<MarketplacePkg[]> =
Expand All @@ -74,7 +74,7 @@ export class MarketplaceService extends AbstractMarketplaceService {

return of([])
}),
shareReplay(),
shareReplay(1),
)

constructor(
Expand Down
Loading

0 comments on commit 53ca9b0

Please sign in to comment.