Bug fixes

This commit is contained in:
Sebastian Seedorf
2020-11-16 17:50:08 +01:00
parent 0597b36ef3
commit 37c34f99ac
12 changed files with 112 additions and 186 deletions

View File

@@ -0,0 +1,78 @@
enum ResolvableState {
WAITING,
PENDING,
ERROR,
DONE
}
class FetchOnce<T> {
protected data: T|undefined;
protected error: unknown|undefined;
protected state: ResolvableState = ResolvableState.WAITING;
protected pendings: [(res: Promise<T>|T) => void, (reason: unknown) => void][] = [];
constructor(protected fetchMethod?: () => Promise<T>) { }
public resolve(): Promise<T> {
return new Promise((resolve, reject) => {
switch (this.state) {
case ResolvableState.WAITING:
this.state = ResolvableState.PENDING;
this.pendings.push([resolve, reject]);
if (this.fetchMethod) this.parsePromise(this.fetchMethod());
break;
case ResolvableState.PENDING:
this.pendings.push([resolve, reject]);
break;
case ResolvableState.DONE:
resolve(this.data);
break;
case ResolvableState.ERROR:
reject(this.error);
break;
}
});
}
protected isFinished(): boolean {
return this.state === ResolvableState.DONE || this.state === ResolvableState.ERROR;
}
protected parsePromise(promise: Promise<T>): void {
promise.then((data) => {
this.data = data;
this.state = ResolvableState.DONE;
this.pendings.forEach(pending => pending[0](data));
}).catch(err => {
this.error = err;
this.state = ResolvableState.ERROR;
this.pendings.forEach(pending => pending[1](err));
});
}
}
export class Resolvable<T> extends FetchOnce<T> {
constructor(fetchMethod: () => Promise<T>) {
super(fetchMethod);
}
}
export class WaitForSync<T> extends FetchOnce<T> {
protected state: ResolvableState = ResolvableState.PENDING;
constructor() {
super(undefined);
}
public setData(data: T): void {
if (!this.isFinished()) {
this.parsePromise((async () => data)());
}
}
public setError(error: unknown): void {
if (!this.isFinished()) {
this.parsePromise((async () => { throw error; })());
}
}
}

View File

@@ -0,0 +1,10 @@
type UserInfo = {
email: string,
email_verified: boolean,
family_name: string,
given_name: string,
groups: string[],
name: string,
preferred_username: string,
sub: string,
};

View File

@@ -0,0 +1,23 @@
import {WaitForSync} from './resolvable';
export interface ClientConfig {
EXTERNAL_BASE_URL: string
}
let config: ClientConfig|undefined;
const configWaiter = new WaitForSync<ClientConfig>();
export function setConfig(clientConfig: ClientConfig): void {
config = clientConfig;
configWaiter.setData(config);
}
export function getConfig(): Promise<ClientConfig> {
return configWaiter.resolve();
}
export async function getUserInfo(): Promise<UserInfo|undefined> {
const config = await getConfig();
const res = await fetch(config.EXTERNAL_BASE_URL + "/api/user");
return res.json();
}