UNPKG

callback-utility

Version:
338 lines 14.9 kB
import { CallTypes } from "./calls-struct.js"; import { FunctionResult, InternalResult } from "./result.js"; import { CBException, CBExceptions } from "./exception.js"; export class CB { static PREVIOUS_ERROR = Symbol("PREVIOUS_ERROR"); static PREVIOUS_RESULT1 = Symbol("PREVIOUS_RESULT1"); static PREVIOUS_RESULT2 = Symbol("PREVIOUS_RESULT2"); static PREVIOUS_RESULT3 = Symbol("PREVIOUS_RESULT3"); static PREVIOUS_RESULT4 = Symbol("PREVIOUS_RESULT4"); static PREVIOUS_RESULT5 = Symbol("PREVIOUS_RESULT5"); static PREVIOUS_RESULT6 = Symbol("PREVIOUS_RESULT6"); static PREVIOUS_RESULT7 = Symbol("PREVIOUS_RESULT7"); static PREVIOUS_RESULT8 = Symbol("PREVIOUS_RESULT8"); static PREVIOUS_RESULT9 = Symbol("PREVIOUS_RESULT9"); static #_Tokens = [ CB.PREVIOUS_ERROR, CB.PREVIOUS_RESULT1, CB.PREVIOUS_RESULT2, CB.PREVIOUS_RESULT3, CB.PREVIOUS_RESULT4, CB.PREVIOUS_RESULT5, CB.PREVIOUS_RESULT6, CB.PREVIOUS_RESULT7, CB.PREVIOUS_RESULT8, CB.PREVIOUS_RESULT9, ]; static f(p_Param1, p_Param2, ...p_Args) { let strAlias; let fnCall; let arrArgs; let blnToken = false; if ("string" === typeof p_Param1) { strAlias = p_Param1; fnCall = p_Param2; arrArgs = [...p_Args]; } else { strAlias = ""; fnCall = p_Param1; arrArgs = [p_Param2, ...p_Args]; } if (p_Args.length > 0 && p_Args.some(varArg => CB.#_Tokens.includes(varArg))) { blnToken = true; } return { Type: CallTypes.Function, Alias: strAlias, Fn: fnCall, Args: arrArgs, Finished: false, Invoked: false, Parent: null, Next: null, Previous: null, Root: null, RootIndex: -1, ParentIndex: -1, UseToken: blnToken, TsStart: 0, TsFinish: 0 }; } static p(p_Param1, ...p_ExecStructs) { let strAlias; let arrStructs; if ("string" === typeof p_Param1) { strAlias = p_Param1; arrStructs = [...p_ExecStructs]; } else { strAlias = ""; arrStructs = [p_Param1, ...p_ExecStructs]; } const structParallel = { Alias: strAlias, Type: CallTypes.Parallel, Calls: arrStructs, CallQty: 0, CallCount: 0, Finished: false, Invoked: false, Parent: null, Next: null, Previous: null, Root: null, ParentIndex: -1, RootIndex: -1, TsStart: 0, TsFinish: 0 }; for (let structCall of structParallel.Calls) { structCall.Parent = structParallel; if (structCall.UseToken) throw new CBException(CBExceptions.TokenInParallelCall); } return structParallel; } static e(p_CallStruct, p_Param2, p_Param3, p_Param4, p_Param5) { let fnCallback, blnBreakOnError = true, blnStats = false, intTimeout = 0; try { if ("function" === typeof p_Param2) fnCallback = p_Param2; else if ("number" === typeof p_Param2) { intTimeout = p_Param2; if ("function" === typeof p_Param3) fnCallback = p_Param3; else if ("boolean" === typeof p_Param3) { blnBreakOnError = p_Param3; if ("function" === typeof p_Param4) fnCallback = p_Param4; else if ("boolean" === typeof p_Param4) { blnStats = p_Param4; if ("function" === typeof p_Param5) fnCallback = p_Param5; } } } if (intTimeout <= 0) intTimeout = 5000; if (p_CallStruct.Type !== CallTypes.Parallel && p_CallStruct.Type !== CallTypes.Sequential) throw new CBException(CBExceptions.InvalidStructToExecute); const structRoot = p_CallStruct; let intCalls = -1; structRoot.PlainCalls = []; structRoot.GetStats = blnStats; const fnSetRoot = function (p_Root, p_CallStructSetRoot) { if (!p_CallStructSetRoot) p_CallStructSetRoot = p_Root; structRoot.PlainCalls.push(p_CallStructSetRoot); p_CallStructSetRoot.RootIndex = ++intCalls; p_CallStructSetRoot.Root = p_Root; if (p_CallStructSetRoot.Type === CallTypes.Parallel || p_CallStructSetRoot.Type === CallTypes.Sequential) { for (let structCallSetRoot of p_CallStructSetRoot.Calls) { fnSetRoot(p_Root, structCallSetRoot); } } }; fnSetRoot(p_CallStruct); const prmsReturn = new Promise((resolve, reject) => { const onFinish = (p_Exception) => { structRoot.Break = true; if (p_Exception) reject(p_Exception); else resolve(structRoot.MainResult.GetResult()); }; structRoot.MainResult = new InternalResult(structRoot, intTimeout, blnBreakOnError, blnStats, onFinish); CB.#Invoke(p_CallStruct); }); if (!fnCallback) return prmsReturn; else prmsReturn .then(value => fnCallback(value.error, value.timeout, value)) .catch(error => fnCallback(error)); } catch (p_Exception) { const excptUnknow = p_Exception instanceof CBException ? p_Exception : new CBException(CBExceptions.InternalError, p_Exception); if (!fnCallback) throw excptUnknow; else fnCallback(excptUnknow); } } static s(p_Param1, ...p_Fns) { let strAlias; let arrStructs; if ("string" === typeof p_Param1) { strAlias = p_Param1; arrStructs = [...p_Fns]; } else { strAlias = ""; arrStructs = [p_Param1, ...p_Fns]; } const structSequential = { Alias: strAlias, Type: CallTypes.Sequential, CallCount: 0, CallQty: 0, Calls: arrStructs, Finished: false, Invoked: false, Parent: null, Next: null, Previous: null, Root: null, ParentIndex: -1, RootIndex: -1, TsStart: 0, TsFinish: 0 }; for (let intA = 0; intA < structSequential.Calls.length; intA++) { const structCall = structSequential.Calls[intA]; if (intA === 0 && structCall.UseToken) throw new CBException(CBExceptions.TokenInFirstCall); structCall.Parent = structSequential; if (intA < structSequential.Calls.length - 1) structCall.Next = structSequential.Calls[intA + 1]; if (intA > 0) structCall.Previous = structSequential.Calls[intA - 1]; } return structSequential; } static #Invoke(p_Call) { const objRoot = p_Call.Root; const objResult = p_Call.Root.MainResult; if (objRoot.Break) return; if (objRoot.GetStats) p_Call.TsStart = Date.now(); if (p_Call.Parent) p_Call.ParentIndex = p_Call.Parent.CallQty++; const fnCallback = function () { if (objRoot.Break) return; if (objRoot.GetStats) p_Call.TsFinish = Date.now(); const structCallCallback = p_Call; if (!structCallCallback.Exception) objResult.SetResult(structCallCallback.RootIndex, structCallCallback.Alias, arguments[0], structCallCallback.TsStart, structCallCallback.TsFinish, Array.prototype.slice.call(arguments, 1)); else objResult.SetException(p_Call.RootIndex, p_Call.Alias, p_Call.Exception); const fnFinishCall = (p_FinishCall) => { p_FinishCall.Finished = true; if (p_FinishCall.Parent) { p_FinishCall.Parent.CallCount++; if (p_FinishCall.Parent.CallCount === p_FinishCall.Parent.Calls.length) fnFinishCall(p_FinishCall.Parent); } }; fnFinishCall(p_Call); if (p_Call.Next) CB.#Invoke(p_Call.Next); else if (p_Call.Parent.Next && p_Call.Parent.Finished) CB.#Invoke(p_Call.Parent.Next); }; switch (p_Call.Type) { case CallTypes.Function: setImmediate(() => { try { if (p_Call.Parent.Type === CallTypes.Sequential && p_Call.UseToken) { for (let intA = 0; intA < p_Call.Args.length; intA++) { const varArg = p_Call.Args[intA]; let intResult = -1, blnError = false; if ("symbol" === typeof varArg) { switch (varArg) { case CB.PREVIOUS_ERROR: blnError = true; break; case CB.PREVIOUS_RESULT1: intResult = 0; break; case CB.PREVIOUS_RESULT2: intResult = 1; break; case CB.PREVIOUS_RESULT3: intResult = 2; break; case CB.PREVIOUS_RESULT4: intResult = 3; break; case CB.PREVIOUS_RESULT5: intResult = 4; break; case CB.PREVIOUS_RESULT6: intResult = 5; break; case CB.PREVIOUS_RESULT7: intResult = 6; break; case CB.PREVIOUS_RESULT8: intResult = 7; break; case CB.PREVIOUS_RESULT9: intResult = 8; break; } if (blnError) p_Call.Args[intA] = objResult[p_Call.Previous.RootIndex].error; else if (intResult > -1) { if (p_Call.Previous.Type === CallTypes.Function) { if ("undefined" === typeof objResult[p_Call.Previous.RootIndex].results[intResult]) throw new CBException(CBExceptions.InvalidTokenResult); p_Call.Args[intA] = objResult[p_Call.Previous.RootIndex].results[intResult]; } else { const arrPreviousResults = objResult[p_Call.Previous.RootIndex].results; const arrFilteredResults = []; const fnGetResults = (p_Results, p_ResultsFiltered, p_Struct) => { for (let intA = 0; intA < p_Struct.length; intA++) { if (!Array.isArray(p_Results[intA]) || p_Results[intA].length < (intResult + 1)) return new CBException(CBExceptions.InvalidTokenResult); if (p_Struct[intA] instanceof FunctionResult) p_ResultsFiltered[intA] = p_Results[intA][intResult]; else { p_ResultsFiltered[intA] = []; return fnGetResults(p_Results[intA], p_ResultsFiltered[intA], p_Struct[intA]); } } }; const errGetResultsReturn = fnGetResults(arrPreviousResults, arrFilteredResults, objResult[p_Call.Previous.RootIndex]); if (errGetResultsReturn) throw errGetResultsReturn; p_Call.Args[intA] = arrFilteredResults; } } } } } p_Call.Fn(...p_Call.Args, fnCallback); } catch (p_Exception) { p_Call.Exception = p_Exception; fnCallback(); } }); break; case CallTypes.Parallel: for (let call of p_Call.Calls) { CB.#Invoke(call); } break; case CallTypes.Sequential: CB.#Invoke(p_Call.Calls[0]); break; } p_Call.Invoked = true; } } //# sourceMappingURL=callback-handler.js.map