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 | 1x 1x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 18x 21x 21x 18x 20x 20x 18x 18x 34x 23x 22x 22x 22x 22x 22x 1x 23x 34x 3x 2x 2x 2x 2x 2x 1x 3x 34x 30x 8x 8x 22x 22x 21x 2x 2x 2x 2x 19x 21x 2x 2x 2x 2x 17x 21x 23x 17x 17x 22x 30x 2x 2x 2x 2x 16x 30x 34x | import { FlowfulError } from './error';
import { ActionMapExtended } from './action-map';
export type ChainedDispatchMiddlewareCallback<AM extends ActionMapExtended = ActionMapExtended> = (
actionMap: AM
) => any;
export interface IDispatchMiddlewareRunner<AM extends ActionMapExtended = ActionMapExtended> {
run(actionMap: AM, execute: ChainedDispatchMiddlewareCallback<AM>): any;
}
export interface IDispatchMiddleware<AM extends ActionMapExtended = ActionMapExtended>
extends IDispatchMiddlewareRunner<AM> {
add(callback: DispatchMiddlewareCallback<AM>): boolean;
remove(callback: DispatchMiddlewareCallback<AM>): boolean;
compose(): void;
}
export interface DispatchMiddlewareOptions {
cancellable?: boolean;
}
export type DispatchMiddlewareCallback<AM extends ActionMapExtended = ActionMapExtended> = (
next: ChainedDispatchMiddlewareCallback<AM>
) => ChainedDispatchMiddlewareCallback<AM>;
export class DispatchMiddleware<AM extends ActionMapExtended = ActionMapExtended> implements IDispatchMiddleware<AM> {
protected _middlewareCallbacks: Set<DispatchMiddlewareCallback<AM>>;
protected _middlewareCallbacksArray: DispatchMiddlewareCallback<AM>[];
protected _composed?: ChainedDispatchMiddlewareCallback<AM>;
protected _last?: ChainedDispatchMiddlewareCallback<AM>;
protected _className = 'DispatchMiddleware';
protected _errorPrefix = `[Flowful][${this._className}]`;
public options: Required<DispatchMiddlewareOptions>;
constructor(options?: DispatchMiddlewareOptions) {
this.options = {
cancellable: options?.cancellable ?? true,
};
this._middlewareCallbacks = new Set();
this._middlewareCallbacksArray = [];
}
compose() {
let next = (actionMap: AM) => {
return this._last!(actionMap);
};
for (const middleware of this._middlewareCallbacksArray) {
next = middleware(next);
}
this._composed = next;
}
add(callback: DispatchMiddlewareCallback<AM>) {
if (!this._middlewareCallbacks.has(callback)) {
this._middlewareCallbacks.add(callback);
this._middlewareCallbacksArray.unshift(callback);
this._composed = undefined;
return true;
}
return false;
}
remove(callback: DispatchMiddlewareCallback<AM>) {
if (this._middlewareCallbacks.has(callback)) {
this._middlewareCallbacks.delete(callback);
this._middlewareCallbacksArray = [...this._middlewareCallbacks];
this._composed = undefined;
return true;
}
return false;
}
run(actionMap: ActionMapExtended, execute: ChainedDispatchMiddlewareCallback<AM>) {
if (!this._middlewareCallbacks.size) {
// size is slightly faster than array.length
return execute(actionMap as unknown as AM);
}
let calledTimes = 0;
this._last = (actionMapFromMiddlewares: AM) => {
if (!this.options.cancellable && actionMapFromMiddlewares !== actionMap) {
throw new FlowfulError(
`${this._errorPrefix} The next function in the dispatch middleware was called with a different ActionMap, which is not possible when cancellable option is set to false.`
);
}
calledTimes++;
if (calledTimes > 1) {
// We have to check it here, otherwise it will throw an error that the solo event was emitted several times
throw new FlowfulError(
`${this._errorPrefix} The next function in the dispatch middleware was called more than once.`
);
}
return execute(actionMapFromMiddlewares);
};
if (!this._composed) {
this.compose();
}
const middlewareOutput = this._composed!(actionMap as unknown as AM);
if (!this.options.cancellable && calledTimes === 0) {
// the middleware should not be able to cancel the event
throw new FlowfulError(
`${this._errorPrefix} The next function in the dispatch middleware was not called, which is not possible when cancellable option is set to false.`
);
}
return middlewareOutput;
}
}
|