callback-utility
Version:
An utility handler to deal with callback functions
248 lines • 8.32 kB
JavaScript
import { CallTypes } from "./calls-struct.js";
import { CBException, CBExceptions } from "./exception.js";
export class InternalResult {
constructor(p_RootStruct, p_Timeout, p_StopOnError, p_GetStats, p_onFinish) {
this.#_CallsCount = p_RootStruct.PlainCalls.filter(structCall => structCall.Type === CallTypes.Function).length;
this.#_Count = p_RootStruct.PlainCalls.length;
this.#_GetStats = p_GetStats;
this.#_onFinish = p_onFinish;
this.#_RootStruct = p_RootStruct;
this.#_StopOnError = p_StopOnError;
this.#_CallResults = new Array(this.#_Count).fill(false);
this.#_Stats = new Array(this.#_Count).fill([-1, -1]);
this.#_TimeoutPtr = setTimeout(() => {
this.#_Finish(undefined, true);
}, p_Timeout);
}
#_Error = false;
#_Timeout = false;
#_AliasResult = {};
#_Count = 0;
#_CallsCount;
#_CallResults;
#_Errors = [];
#_Finished = false;
#_GetStats;
#_onFinish;
#_ResultsCount = 0;
#_RootStruct;
#_StopOnError = false;
#_TimeoutPtr;
#_Stats;
get AliasResult() {
return this.#_AliasResult;
}
get Count() {
return this.#_Count;
}
get Error() {
return this.#_Error;
}
get Errors() {
return this.#_Errors;
}
get GetStats() {
return this.#_GetStats;
}
get Timeout() {
return this.#_Timeout;
}
#_Finish(p_Exception, p_Timeout) {
if (!this.#_Finished) {
if (p_Timeout)
this.#_Timeout = true;
clearTimeout(this.#_TimeoutPtr);
this.#_TimeoutPtr?.unref();
this.#_onFinish(p_Exception);
this.#_Finished = true;
}
}
#_SetError(p_Error, p_Index, p_Alias) {
const structDetails = { callIndex: p_Index };
if (p_Alias)
structDetails.callAlias = p_Alias;
if (p_Error instanceof CBException)
p_Error.details = structDetails;
else
p_Error = new CBException(CBExceptions.ExecutionException, structDetails, undefined, p_Error);
this.#_Errors.push(p_Error);
return p_Error;
}
#_SetParentResult(p_CallStruct, p_TsStart, p_TsFinish) {
if (p_CallStruct.Parent) {
const arrStats = this.#_Stats[p_CallStruct.Parent.RootIndex];
if (this.#_RootStruct.GetStats) {
if (arrStats[0] === -1 || p_TsStart < arrStats[0])
arrStats[0] = p_TsStart;
if (p_TsFinish > arrStats[1])
arrStats[1] = p_TsFinish;
}
if (!this[p_CallStruct.Parent.RootIndex]) {
if (p_CallStruct.Parent.Type === CallTypes.Parallel)
this[p_CallStruct.Parent.RootIndex] = new ParallelResult(p_CallStruct.Parent.Calls.length, this.#_RootStruct.GetStats, arrStats);
else
this[p_CallStruct.Parent.RootIndex] = new SequentialResult(p_CallStruct.Parent.Calls.length, this.#_RootStruct.GetStats, arrStats);
}
if (p_CallStruct.Parent.Alias !== "")
this.#_AliasResult[p_CallStruct.Parent.Alias] = this[p_CallStruct.Parent.RootIndex];
this[p_CallStruct.Parent.RootIndex][p_CallStruct.ParentIndex] = this[p_CallStruct.RootIndex];
this.#_SetParentResult(p_CallStruct.Parent, p_TsStart, p_TsFinish);
}
}
GetResult() {
return new Result(this);
}
SetException(p_Index, p_Alias, p_Exception) {
this.#_Finish(this.#_SetError(p_Exception, p_Index, p_Alias));
}
SetResult(p_Index, p_Alias, p_Error, p_TsStart, p_TsFinish, p_Results) {
if (this.#_CallResults[p_Index]) {
this.SetException(p_Index, p_Alias, new CBException(CBExceptions.ResultAlreadySet));
return;
}
else
this.#_CallResults[p_Index] = true;
const objResult = new FunctionResult(p_Error, p_Results, (p_TsFinish - p_TsStart));
if (p_Error)
this.#_SetError(p_Error, p_Index, p_Alias);
if (p_Alias !== "") {
if (p_Alias in this.#_AliasResult) {
this.SetException(p_Index, p_Alias, new CBException(CBExceptions.ResultAlreadySetForAlias));
return;
}
this.#_AliasResult[p_Alias] = objResult;
}
this[p_Index] = objResult;
const callStruct = this.#_RootStruct.PlainCalls[p_Index];
this.#_SetParentResult(callStruct, p_TsStart, p_TsFinish);
if (p_Error) {
this.#_Error = true;
if (this.#_StopOnError)
this.#_Finish();
}
this.#_ResultsCount++;
if (this.#_ResultsCount >= this.#_CallsCount)
this.#_Finish();
}
}
class BaseResult {
constructor(p_Count, p_Error, p_Results, p_Stats, p_StatsArray) {
this.#_Length = p_Count;
this.#_Errors = p_Error ? p_Error : null;
this.#_Results = p_Results ? p_Results : null;
this.#_Stats = p_Stats ? p_Stats : -1;
this.#_StatsArray = p_StatsArray;
}
#_Length;
#_Errors;
#_Results;
#_Stats;
#_StatsArray;
get length() {
return this.#_Length;
}
get error() {
if (!this.#_Errors && this.#_Length > 0) {
this.#_Errors = [];
for (let intA = 0; intA < this.length; intA++) {
this.#_Errors[intA] = this[intA].error;
}
}
return this.#_Errors;
}
get results() {
if (!this.#_Results && this.#_Length > 0) {
this.#_Results = [];
for (let intA = 0; intA < this.length; intA++) {
this.#_Results[intA] = this[intA].results;
}
}
return this.#_Results;
}
get stats() {
if (-2 === this.#_Stats)
this.#_Stats = this.#_StatsArray[1] - this.#_StatsArray[0];
if (-1 === this.#_Stats)
throw new CBException(CBExceptions.NoStatsGathered);
return this.#_Stats;
}
[Symbol.iterator]() {
let index = 0;
const data = this;
return {
next() {
if (index < data.length)
return { value: data[index++], done: false };
else
return { done: true };
}
};
}
}
class BaseStructResult extends BaseResult {
constructor(p_Count, p_GetStats, p_StatsArray) {
super(p_Count, null, null, p_GetStats ? -2 : -1, p_StatsArray);
}
}
export class FunctionResult extends BaseResult {
constructor(p_Error, p_Results, p_Stats) {
super(0, p_Error, p_Results, p_Stats);
}
}
export class ParallelResult extends BaseStructResult {
}
export class SequentialResult extends BaseStructResult {
}
export class Result {
constructor(p_InternalResult) {
this.#_AliasResult = p_InternalResult.AliasResult;
this.#_Count = p_InternalResult.Count;
this.#_Error = p_InternalResult.Error;
this.#_Errors = p_InternalResult.Errors;
this.#_Timeout = p_InternalResult.Timeout;
for (let intA = 0; intA < p_InternalResult.Count; intA++) {
this[intA] = p_InternalResult[intA];
}
this.#_Stats = (p_InternalResult.GetStats ? this[0].stats : -1);
Object.seal(this);
}
#_AliasResult = {};
#_Count = 0;
#_Error = false;
#_Errors;
#_Stats = 0;
#_Timeout = false;
get error() {
return this.#_Error;
}
get length() {
return this.#_Count;
}
get stats() {
if (-1 === this.#_Stats)
throw new CBException(CBExceptions.NoStatsGathered);
return this[0].stats;
}
get timeout() {
return this.#_Timeout;
}
[Symbol.iterator]() {
let index = 0;
const data = this;
return {
next() {
if (index < data.length)
return { value: data[index++], done: false };
else
return { done: true };
}
};
}
getByAlias(p_Alias) {
return this.#_AliasResult[p_Alias];
}
getErrors() {
return this.#_Errors;
}
}
//# sourceMappingURL=result.js.map