Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | 1x 1x 1x 6x 6x 6x 6x 6x 6x 4x 4x 4x 4x 4x 4x 4x 4x 4x 2x 2x 32x 216x 72x 24x 48x 8x 16x 8x 4x 8x | import { Injectable } from '@angular/core';
import { uniq } from 'lodash-es';
import { runInAction } from 'mobx';
import { catchError, Observable, of, switchMap } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Ref } from '../model/ref';
import { isPushing, isReplicating } from '../mods/sync/origin';
import { Store } from '../store/store';
import { defaultOrigin, subOrigin } from '../util/tag';
import { AdminService } from './admin.service';
import { RefService } from './api/ref.service';
import { ConfigService } from './config.service';
@Injectable({
providedIn: 'root'
})
export class OriginMapService {
private origins: Ref[] = [];
constructor(
private config: ConfigService,
private admin: AdminService,
private refs: RefService,
private store: Store,
) { }
get init$() {
this.origins = [];
if (!this.admin.getPlugin('+plugin/origin')) return of(null);
return this.loadOrigins$().pipe(
tap(() => runInAction(() => {
this.store.origins.origins = this.origins;
this.store.origins.list = this.list;
this.store.origins.lookup = this.lookup;
this.store.origins.tunnelLookup = this.tunnelLookup;
this.store.origins.reverseLookup = this.reverseLookup;
this.store.origins.originMap = this.originMap;
})),
catchError(err => {
console.error("Error looking up origin cross references.");
console.error(err);
return of(null)
}),
);
}
private loadOrigins$(page = 0): Observable<null> {
const alreadyLoaded = page * this.config.fetchBatch;
if (alreadyLoaded >= this.config.maxOrigins) {
console.error(`Too many origins to load, only loaded ${alreadyLoaded}. Increase maxOrigins to load more.`)
return of(null);
}
return this.refs.page({ query: '+plugin/origin', page, size: this.config.fetchBatch, obsolete: null as any }).pipe(
tap(batch => this.origins.push(...batch.content)),
switchMap(batch => !batch.content.length ? of(null) : this.loadOrigins$(page + 1)),
);
}
private get api() {
Iif (this.config.api.startsWith('//')) {
return location.protocol + this.config.api;
}
return this.config.api;
}
/**
* Searches push configs to list api aliases.
*/
private get selfApis(): Map<string, string> {
const config = (remote?: Ref): any => remote?.plugins?.['+plugin/origin'];
const trimUrl = (url: string) => url.endsWith('/') ? url.substring(0, url.length - 1) : url;
const remotesForOrigin = (origin: string) => this.origins.filter(remote => remote.origin === origin);
return new Map([
[this.api, this.store.account.origin],
...remotesForOrigin(this.store.account.origin)
.filter(remote => isPushing(remote, ''))
.map(remote => [trimUrl(remote.url), config(remote).remote]),
] as [string, string][]);
}
/**
* Lists all visible origins.
*/
private get list(): string[] {
const config = (remote?: Ref): any => remote?.plugins?.['+plugin/origin'];
const remotesForOrigin = (origin: string) => this.origins.filter(remote => remote.origin === origin);
return uniq([
this.store.account.origin,
...remotesForOrigin(this.store.account.origin)
.map(remote => subOrigin(remote.origin, config(remote)?.local)),
]);
}
/**
* Maps local-alias -> api.
*/
private get lookup(): Map<string, string> {
const config = (remote?: Ref): any => remote?.plugins?.['+plugin/origin'];
const trimUrl = (url: string) => url.endsWith('/') ? url.substring(0, url.length - 1) : url;
const remotesForOrigin = (origin: string) => this.origins.filter(remote => remote.origin === origin);
return new Map([
[this.store.account.origin, this.api],
...remotesForOrigin(this.store.account.origin)
.map(remote => [subOrigin(remote.origin, config(remote)?.local), trimUrl(remote.url)]),
] as [string, string][]);
}
/**
* Maps local-alias -> ssh user.
*/
private get tunnelLookup(): Map<string, string> {
const config = (remote?: Ref): any => remote?.plugins?.['+plugin/origin'];
const tunnel = (remote: Ref): any => remote.plugins?.['+plugin/origin/tunnel'];
const remotesForOrigin = (origin: string) => this.origins.filter(remote => remote.origin === origin);
return new Map([
[this.store.account.origin, this.api],
...remotesForOrigin(this.store.account.origin)
.map(remote => [subOrigin(remote.origin, config(remote)?.local), {
...tunnel(remote),
remoteUser: defaultOrigin(tunnel(remote)?.remoteUser || '', remote.origin),
}]),
] as [string, string][]);
}
/**
* Maps local-alias -> remote-alias-to-self.
*/
private get reverseLookup(): Map<string, string> {
const config = (remote?: Ref): any => remote?.plugins?.['+plugin/origin'];
return new Map(this.origins
.filter(remote => isReplicating(this.store.account.origin || '', remote, this.selfApis))
.filter(remote => config(remote)?.local)
.map(remote => [remote.origin || '', config(remote)?.local]));
}
/**
* Maps local-alias -> remote-alias -> local-alias.
*/
private get originMap(): Map<string, Map<string, string>> {
const config = (remote: Ref): any => remote.plugins?.['+plugin/origin'];
const remotesForOrigin = (origin: string) => this.origins.filter(remote => remote.origin === origin);
const trimUrl = (url: string) => url.endsWith('/') ? url.substring(0, url.length - 1) : url;
const findLocalAlias = (url: string) => remotesForOrigin(this.store.account.origin)
.filter(remote => trimUrl(remote.url) === url)
[0] || undefined;
const originMapFor = (remote: Ref): Map<string, string> => new Map(
remotesForOrigin(subOrigin(this.store.account.origin, config(remote)?.local))
.filter(nested => findLocalAlias(trimUrl(nested.url)) !== undefined)
.map(nested => [
config(nested)?.local || '',
config(findLocalAlias(trimUrl(nested.url))!)?.local || ''
]));
return new Map(
remotesForOrigin(this.store.account.origin || '')
.map(remote => [
subOrigin(this.store.account.origin, config(remote)?.local),
originMapFor(remote)
]));
}
}
|