{"version":3,"file":"ActionState.mjs","names":[],"sources":["../../../../../../../components-base/src/action/ActionState.ts"],"sourcesContent":["import { action, computed, makeObservable, observable } from \"mobx\";\n\nexport type ActionStateValue =\n  \"isIdle\" | \"isSucceeded\" | \"isPending\" | \"isExecuting\" | \"isFailed\";\n\n/** How long each state lasts, in ms. */\nexport const actionStateDurations = {\n  /** An async action counts as pending only after this long. */\n  pending: 1000,\n  succeeded: 800,\n  failed: 2000,\n};\n\nconst sleep = (ms: number): Promise<void> =>\n  new Promise((resolve) => setTimeout(resolve, ms));\n\n/**\n * What an `Action` shows on its button: executing, pending, then succeeded or\n * failed for a moment, then idle again.\n *\n * A synchronous action shows success only with `showFeedback`, an async one\n * unless `showFeedback` is `false`. A failure is shown either way.\n */\nexport class ActionState {\n  private showFeedback?: boolean;\n  public state: ActionStateValue = \"isIdle\";\n  private setPendingTimeout: ReturnType<typeof setTimeout> | undefined;\n  public error: unknown;\n  private isAsync = false;\n\n  public constructor() {\n    makeObservable(this, {\n      state: observable,\n      updateState: action,\n      isBusy: computed,\n    });\n  }\n\n  public updateState(newState: ActionStateValue): void {\n    this.state = newState;\n  }\n\n  public get isBusy(): boolean {\n    return this.state !== \"isIdle\";\n  }\n\n  public onAsyncStart(): void {\n    this.clearPendingTimeout();\n    this.isAsync = true;\n    this.updateState(\"isExecuting\");\n    this.setPendingTimeout = setTimeout(\n      () => this.startPending(),\n      actionStateDurations.pending,\n    );\n  }\n\n  public async onSucceeded(): Promise<void> {\n    await this.onDone();\n  }\n\n  public async onFailed(error?: unknown): Promise<void> {\n    this.error = error ?? new Error(\"Unknown error\");\n    await this.onDone();\n  }\n\n  public withFeedback(feedback?: boolean): this {\n    this.showFeedback = feedback;\n    return this;\n  }\n\n  private async startFailedFeedback(): Promise<void> {\n    this.updateState(\"isFailed\");\n    await sleep(actionStateDurations.failed);\n    this.resetAfterDone();\n  }\n\n  private async startSucceededFeedback(): Promise<void> {\n    this.updateState(\"isSucceeded\");\n    await sleep(actionStateDurations.succeeded);\n    this.resetAfterDone();\n  }\n\n  private resetAfterDone(): void {\n    this.updateState(\"isIdle\");\n    this.isAsync = false;\n    this.error = undefined;\n  }\n\n  private clearPendingTimeout(): void {\n    if (this.setPendingTimeout) {\n      clearTimeout(this.setPendingTimeout);\n    }\n  }\n\n  private onDone(): Promise<void> | void {\n    this.clearPendingTimeout();\n    if (this.error) {\n      return this.startFailedFeedback();\n    } else if (\n      this.showFeedback !== false &&\n      (this.showFeedback || this.isAsync)\n    ) {\n      return this.startSucceededFeedback();\n    } else {\n      this.resetAfterDone();\n    }\n  }\n\n  private startPending(): void {\n    this.updateState(\"isPending\");\n  }\n}\n\nexport default ActionState;\n"],"mappings":";;;;;AAMA,IAAa,uBAAuB;;CAElC,SAAS;CACT,WAAW;CACX,QAAQ;AACV;AAEA,IAAM,SAAS,OACb,IAAI,SAAS,YAAY,WAAW,SAAS,EAAE,CAAC;;;;;;;;AASlD,IAAa,cAAb,MAAyB;CACvB;CACA,QAAiC;CACjC;CACA;CACA,UAAkB;CAElB,cAAqB;EACnB,eAAe,MAAM;GACnB,OAAO;GACP,aAAa;GACb,QAAQ;EACV,CAAC;CACH;CAEA,YAAmB,UAAkC;EACnD,KAAK,QAAQ;CACf;CAEA,IAAW,SAAkB;EAC3B,OAAO,KAAK,UAAU;CACxB;CAEA,eAA4B;EAC1B,KAAK,oBAAoB;EACzB,KAAK,UAAU;EACf,KAAK,YAAY,aAAa;EAC9B,KAAK,oBAAoB,iBACjB,KAAK,aAAa,GACxB,qBAAqB,OACvB;CACF;CAEA,MAAa,cAA6B;EACxC,MAAM,KAAK,OAAO;CACpB;CAEA,MAAa,SAAS,OAAgC;EACpD,KAAK,QAAQ,yBAAS,IAAI,MAAM,eAAe;EAC/C,MAAM,KAAK,OAAO;CACpB;CAEA,aAAoB,UAA0B;EAC5C,KAAK,eAAe;EACpB,OAAO;CACT;CAEA,MAAc,sBAAqC;EACjD,KAAK,YAAY,UAAU;EAC3B,MAAM,MAAM,qBAAqB,MAAM;EACvC,KAAK,eAAe;CACtB;CAEA,MAAc,yBAAwC;EACpD,KAAK,YAAY,aAAa;EAC9B,MAAM,MAAM,qBAAqB,SAAS;EAC1C,KAAK,eAAe;CACtB;CAEA,iBAA+B;EAC7B,KAAK,YAAY,QAAQ;EACzB,KAAK,UAAU;EACf,KAAK,QAAQ,KAAA;CACf;CAEA,sBAAoC;EAClC,IAAI,KAAK,mBACP,aAAa,KAAK,iBAAiB;CAEvC;CAEA,SAAuC;EACrC,KAAK,oBAAoB;EACzB,IAAI,KAAK,OACP,OAAO,KAAK,oBAAoB;OAC3B,IACL,KAAK,iBAAiB,UACrB,KAAK,gBAAgB,KAAK,UAE3B,OAAO,KAAK,uBAAuB;OAEnC,KAAK,eAAe;CAExB;CAEA,eAA6B;EAC3B,KAAK,YAAY,WAAW;CAC9B;AACF"}