move logic to zones.ts
This commit is contained in:
parent
62c23ce180
commit
df2ceb726a
|
|
@ -30,7 +30,7 @@ export class Waiter {
|
||||||
private _channelOwner: ChannelOwner<channels.EventTargetChannel>;
|
private _channelOwner: ChannelOwner<channels.EventTargetChannel>;
|
||||||
private _waitId: string;
|
private _waitId: string;
|
||||||
private _error: string | undefined;
|
private _error: string | undefined;
|
||||||
private _savedZone: Zone | undefined;
|
private _savedZone: Zone;
|
||||||
|
|
||||||
constructor(channelOwner: ChannelOwner<channels.EventTargetChannel>, event: string) {
|
constructor(channelOwner: ChannelOwner<channels.EventTargetChannel>, event: string) {
|
||||||
this._waitId = createGuid();
|
this._waitId = createGuid();
|
||||||
|
|
@ -107,12 +107,11 @@ export class Waiter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function waitForEvent<T = void>(emitter: EventEmitter, event: string, savedZone: Zone | undefined, predicate?: (arg: T) => boolean | Promise<boolean>): { promise: Promise<T>, dispose: () => void } {
|
function waitForEvent<T = void>(emitter: EventEmitter, event: string, savedZone: Zone, predicate?: (arg: T) => boolean | Promise<boolean>): { promise: Promise<T>, dispose: () => void } {
|
||||||
let listener: (eventArg: any) => void;
|
let listener: (eventArg: any) => void;
|
||||||
const promise = new Promise<T>((resolve, reject) => {
|
const promise = new Promise<T>((resolve, reject) => {
|
||||||
listener = async (eventArg: any) => {
|
listener = async (eventArg: any) => {
|
||||||
// Reset apiZone and expectZone, but restore step data.
|
await savedZone.run(async () => {
|
||||||
await zones.runInZone(savedZone?.copyWithoutTypes(['apiZone', 'expectZone']), async () => {
|
|
||||||
try {
|
try {
|
||||||
if (predicate && !(await predicate(eventArg)))
|
if (predicate && !(await predicate(eventArg)))
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,7 @@ class ZoneManager {
|
||||||
private readonly _asyncLocalStorage = new AsyncLocalStorage<Zone|undefined>();
|
private readonly _asyncLocalStorage = new AsyncLocalStorage<Zone|undefined>();
|
||||||
|
|
||||||
run<T, R>(type: ZoneType, data: T, func: () => R): R {
|
run<T, R>(type: ZoneType, data: T, func: () => R): R {
|
||||||
const current = this._asyncLocalStorage.getStore();
|
const zone = Zone.createWithData(this._asyncLocalStorage, type, data);
|
||||||
const zone = Zone.createWithData(current, type, data);
|
|
||||||
return this.runInZone(zone, func);
|
|
||||||
}
|
|
||||||
|
|
||||||
runInZone<R>(zone: Zone | undefined, func: () => R): R {
|
|
||||||
return this._asyncLocalStorage.run(zone, func);
|
return this._asyncLocalStorage.run(zone, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,8 +31,8 @@ class ZoneManager {
|
||||||
return zone?.get(type);
|
return zone?.get(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentZone(): Zone | undefined {
|
currentZone(): Zone {
|
||||||
return this._asyncLocalStorage.getStore();
|
return this._asyncLocalStorage.getStore() ?? Zone.createEmpty(this._asyncLocalStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
exitZones<R>(func: () => R): R {
|
exitZones<R>(func: () => R): R {
|
||||||
|
|
@ -46,25 +41,33 @@ class ZoneManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Zone {
|
export class Zone {
|
||||||
private readonly store: Map<ZoneType, unknown>;
|
private readonly _asyncLocalStorage: AsyncLocalStorage<Zone | undefined>;
|
||||||
|
private readonly _data: Map<ZoneType, unknown>;
|
||||||
|
|
||||||
static createWithData(currentZone: Zone | undefined, type: ZoneType, data: unknown) {
|
static createWithData(asyncLocalStorage: AsyncLocalStorage<Zone|undefined>, type: ZoneType, data: unknown) {
|
||||||
const store = new Map(currentZone?.store.entries() ?? []);
|
const store = new Map(asyncLocalStorage.getStore()?._data);
|
||||||
store.set(type, data);
|
store.set(type, data);
|
||||||
return new Zone(store);
|
return new Zone(asyncLocalStorage, store);
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructor(store: Map<ZoneType, unknown>) {
|
static createEmpty(asyncLocalStorage: AsyncLocalStorage<Zone|undefined>) {
|
||||||
this.store = store;
|
return new Zone(asyncLocalStorage, new Map());
|
||||||
}
|
}
|
||||||
|
|
||||||
copyWithoutTypes(types: ZoneType[]): Zone {
|
private constructor(asyncLocalStorage: AsyncLocalStorage<Zone|undefined>, store: Map<ZoneType, unknown>) {
|
||||||
const store = new Map(this.store.entries().filter(([type]) => !types.includes(type)));
|
this._asyncLocalStorage = asyncLocalStorage;
|
||||||
return new Zone(store);
|
this._data = store;
|
||||||
|
}
|
||||||
|
|
||||||
|
run<R>(func: () => R): R {
|
||||||
|
// Reset apiZone and expectZone, but restore stepZone.
|
||||||
|
const entries = [...this._data.entries()].filter(([type]) => (type !== 'apiZone' && type !== 'expectZone'));
|
||||||
|
const resetZone = new Zone(this._asyncLocalStorage, new Map(entries));
|
||||||
|
return this._asyncLocalStorage.run(resetZone, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
get<T>(type: ZoneType): T | undefined {
|
get<T>(type: ZoneType): T | undefined {
|
||||||
return this.store.get(type) as T | undefined;
|
return this._data.get(type) as T | undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue