@openforis/arena-core 2.16.5 → 2.16.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -148,7 +148,8 @@ export class JobBase {
148
148
  return;
149
149
  this.cancelRequested = true;
150
150
  const currentInnerJob = this.getCurrentInnerJob();
151
- if (currentInnerJob === null || currentInnerJob === void 0 ? void 0 : currentInnerJob.isRunning()) {
151
+ if (currentInnerJob && !currentInnerJob.isEnded()) {
152
+ // inner job running or about to start (pending):
152
153
  // the parent job status will be set to canceled when handling the canceled event of the inner job
153
154
  yield currentInnerJob.cancel({ canceledByAdmin });
154
155
  return;
@@ -181,6 +182,9 @@ export class JobBase {
181
182
  start() {
182
183
  return __awaiter(this, arguments, void 0, function* (client = null) {
183
184
  var _a;
185
+ // canceled before being started: nothing to execute
186
+ if (this.cancelRequested || this.isEnded())
187
+ return;
184
188
  this.logDebug('start');
185
189
  try {
186
190
  if (client) {
@@ -213,6 +217,9 @@ export class JobBase {
213
217
  executeInTransaction() {
214
218
  return __awaiter(this, void 0, void 0, function* () {
215
219
  try {
220
+ // canceled while the transaction was being opened: it must not be set as running again
221
+ if (this.cancelRequested)
222
+ return;
216
223
  yield this.onStart();
217
224
  const shouldExecute = yield this.shouldExecute();
218
225
  if (shouldExecute) {
@@ -268,6 +275,9 @@ export class JobBase {
268
275
  return __awaiter(this, void 0, void 0, function* () {
269
276
  this.logDebug(`- ${this.total} inner jobs found`);
270
277
  for (let i = 0; i < this.innerJobs.length; i++) {
278
+ // canceled between two inner jobs: the next ones must not be started
279
+ if (this.cancelRequested)
280
+ break;
271
281
  this.logDebug(`- executing inner job ${i + 1}`);
272
282
  this.currentInnerJobIndex = i;
273
283
  const currentInnerJob = this.innerJobs[i];
@@ -301,6 +311,12 @@ export class JobBase {
301
311
  break;
302
312
  }
303
313
  }
314
+ if (!this.stopOnInnerJobFailure &&
315
+ !this.cancelRequested &&
316
+ this.innerJobs.some((innerJob) => innerJob.isFailed())) {
317
+ // set only after all inner jobs have run: setting it at the first failure would end this job (onEnd) too early
318
+ yield this.setStatus(JobStatus.failed);
319
+ }
304
320
  this.logDebug(`- ${this.processed} inner jobs processed successfully`);
305
321
  });
306
322
  }
@@ -359,7 +375,8 @@ export class JobBase {
359
375
  if (status === JobStatus.failed) {
360
376
  // report the errors of the failed inner job in the failed event (and in the errors) of this job
361
377
  Object.assign(this.errors, (_d = (_b = this.getCurrentInnerJob()) === null || _b === void 0 ? void 0 : _b.errors) !== null && _d !== void 0 ? _d : {});
362
- return this.setStatus(status);
378
+ // when not stopping on inner job failures, this job is set as failed after all the inner jobs have run
379
+ return this.stopOnInnerJobFailure ? this.setStatus(status) : undefined;
363
380
  }
364
381
  if (status === JobStatus.running) {
365
382
  this.notifyEvent({
@@ -1 +1 @@
1
- {"version":3,"file":"JobBase.js","sourceRoot":"","sources":["../../../src/job/JobBase.ts"],"names":[],"mappings":"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","sourcesContent":["import { User } from '../auth'\nimport { Dictionary } from '../common'\nimport { SystemError, SystemErrorKeys } from '../error'\nimport { Logger } from '../logger'\nimport { Survey } from '../survey'\nimport { UUIDs } from '../utils'\n\nimport { Job } from './job'\nimport { JobContext } from './jobContext'\nimport { JobEvent, JobEventType } from './jobEvent'\nimport { JobSerialized } from './jobSerialized'\nimport { JobStatus } from './status'\n\nexport interface JobConstructor {\n new <C extends JobContext, R>(context: C, innerJobs?: JobBase<any>[]): JobBase<C, R>\n readonly prototype: JobBase<any, any>\n}\n\n/**\n * Client able to open a transaction (e.g. a pg-promise database): the job runs inside `client.tx(callback)`.\n */\nexport interface JobTxClient {\n tx(callback: (tx: any) => Promise<void>): Promise<unknown>\n}\n\nconst PROGRESS_NOTIFICATION_THROTTLE_MILLIS = 1000\n\n/**\n * Asynchronous task handler.\n *\n * Status workflow:\n * - pending\n * - running\n * - (end)\n * -- succeeded\n * -- failed\n * -- canceled\n *\n * Methods that can be overwritten by subclasses:\n * - shouldExecute (in tx)\n * - onStart (in tx)\n * - execute (in tx)\n * - beforeSuccess (in tx)\n * - generateResult (in tx)\n * - beforeEnd (in tx)\n * - onEnd (out of tx)\n * - getErrorInfo\n */\nexport abstract class JobBase<C extends JobContext, R = undefined> implements Job<R> {\n static readonly keysContext = {\n surveyId: 'surveyId',\n survey: 'survey',\n user: 'user',\n }\n\n readonly uuid: string\n readonly type: string\n status: JobStatus = JobStatus.pending\n startTime?: Date\n endTime?: Date\n total: number\n result: R | undefined = undefined\n errors: Record<string, any> = {}\n canceledByAdmin?: boolean\n\n protected logger: Logger\n protected context: C\n protected innerJobs: JobBase<C, any>[]\n protected currentInnerJobIndex = -1\n\n private _processed = 0\n private eventListener: ((event: JobEvent) => unknown) | undefined = undefined\n private progressThrottleTimeoutId: ReturnType<typeof setTimeout> | undefined = undefined\n private progressThrottleLastRunTime = 0\n private _stopOnInnerJobFailure = true\n // set as soon as cancel() is called (the canceled status is set only after beforeEnd has run)\n private cancelRequested = false\n private beforeEndCalled = false\n // inner job events are handled in sequence; executeJobs waits for them before going on\n private innerJobEventsQueue: Promise<void> = Promise.resolve()\n\n public constructor(context: C, innerJobs: JobBase<C, any>[] = []) {\n this.context = { ...context }\n this.innerJobs = innerJobs\n\n this.uuid = UUIDs.v4()\n this.type = this.context.type ?? this.constructor.name\n this.total = innerJobs.length > 0 ? innerJobs.length : 1\n\n // Created last, so that createLogger() overrides can safely build the logger name out of\n // the job identity (e.g. arena's `Job <ClassName> (<uuid>)` log correlation id).\n this.logger = this.createLogger()\n }\n\n get processed(): number {\n return this._processed\n }\n\n set processed(value: number) {\n this._processed = value\n this.notifyProgress()\n }\n\n get stopOnInnerJobFailure(): boolean {\n return this._stopOnInnerJobFailure\n }\n\n set stopOnInnerJobFailure(value: boolean) {\n this._stopOnInnerJobFailure = value\n }\n\n protected get surveyId(): number | null {\n return this.context.surveyId ?? null\n }\n\n protected get user(): User {\n return this.context.user\n }\n\n protected get userUuid(): string | undefined {\n return this.user?.uuid\n }\n\n protected get contextSurvey(): Survey | undefined {\n return this.context.survey\n }\n\n /**\n * Returns the value of the specified context prop, or the default value (null if not specified) when not set.\n */\n protected getContextProp<K extends keyof C & string>(prop: K, defaultValue?: C[K] | null): C[K] | null\n /** Context prop not declared in the context type: the value is typed by the caller. */\n protected getContextProp<T = any, P extends string = string>(\n prop: P extends keyof C ? never : P,\n defaultValue?: T | null\n ): T | null\n protected getContextProp(prop: string, defaultValue: unknown = null): unknown {\n const value = (this.context as Record<string, unknown>)[prop]\n return value ?? defaultValue\n }\n\n protected setContext(context: Partial<C>): void {\n Object.assign(this.context, context)\n }\n\n protected deleteContextProps(...propNames: string[]): void {\n propNames.forEach((propName) => {\n delete (this.context as any)[propName]\n })\n }\n\n /**\n * Registers the listener notified of job events (status changes and progress).\n * Only one listener can be registered at a time; registering a new one replaces the previous one.\n * Errors thrown (or rejections returned) by the listener are logged and do not affect the job execution.\n */\n onEvent(listener: (event: JobEvent) => unknown): this {\n this.eventListener = listener\n return this\n }\n\n isPending(): boolean {\n return this.status === JobStatus.pending\n }\n\n isRunning(): boolean {\n return this.status === JobStatus.running\n }\n\n isSucceeded(): boolean {\n return this.status === JobStatus.succeeded\n }\n\n isFailed(): boolean {\n return this.status === JobStatus.failed\n }\n\n isCanceled(): boolean {\n return this.status === JobStatus.canceled\n }\n\n isEnded(): boolean {\n return [JobStatus.succeeded, JobStatus.failed, JobStatus.canceled].includes(this.status)\n }\n\n hasErrors(): boolean {\n return Object.keys(this.errors).length > 0\n }\n\n protected getCurrentInnerJob(): JobBase<C, any> | undefined {\n return this.innerJobs[this.currentInnerJobIndex]\n }\n\n protected combineInnerJobsResults(): Record<string, any> {\n const results: Record<string, any> = {}\n this.innerJobs.forEach((innerJob) => Object.assign(results, innerJob.result ?? {}))\n return results\n }\n\n protected combineInnerJobsErrors(): Record<string, any> {\n const errors: Record<string, any> = {}\n this.innerJobs.forEach((innerJob) => Object.assign(errors, innerJob.errors ?? {}))\n return errors\n }\n\n async cancel(options: { canceledByAdmin?: boolean } = {}): Promise<void> {\n const { canceledByAdmin = false } = options\n if (this.isEnded()) return\n\n this.cancelRequested = true\n\n const currentInnerJob = this.getCurrentInnerJob()\n if (currentInnerJob?.isRunning()) {\n // the parent job status will be set to canceled when handling the canceled event of the inner job\n await currentInnerJob.cancel({ canceledByAdmin })\n return\n }\n // no inner job running (job without inner jobs, or between two inner jobs)\n this.canceledByAdmin = canceledByAdmin\n // release the resources (temp files/directories, streams) allocated before the cancellation\n await this.runBeforeEnd()\n await this.setStatus(JobStatus.canceled)\n }\n\n /**\n * Returns true when the job has been canceled (or is no longer running).\n * Long-running subclasses can check it to stop processing items (e.g. in a loop) as soon as the job is canceled.\n */\n protected isCancelRequestedOrNotRunning(): boolean {\n return this.cancelRequested || !this.isRunning()\n }\n\n /**\n * Runs beforeEnd only once (it can be called by cancel() and when the job execution ends).\n */\n private async runBeforeEnd(): Promise<void> {\n if (this.beforeEndCalled) return\n this.beforeEndCalled = true\n await this.beforeEnd()\n }\n\n async start(client: JobTxClient | null = null): Promise<void> {\n this.logDebug('start')\n\n try {\n if (client) {\n await client.tx(async (tx: any) => {\n this.context.tx = tx\n await this.executeInTransaction()\n })\n } else {\n await this.executeInTransaction()\n }\n if (!this.isCancelRequestedOrNotRunning()) {\n await this.setStatus(JobStatus.succeeded)\n }\n } catch (error: any) {\n // a job can fail while still pending (e.g. the transaction cannot be opened, or onStart fails)\n if (!this.cancelRequested && !this.isFailed() && !this.isCanceled()) {\n this.logError(error.stack ?? error)\n const { key, params } = this.getErrorInfo(error)\n this.addError({ error: { valid: false, errors: [{ key, params }] } })\n await this.setStatus(JobStatus.failed)\n }\n } finally {\n this.context.tx = undefined\n }\n }\n\n private async executeInTransaction(): Promise<void> {\n try {\n await this.onStart()\n\n const shouldExecute = await this.shouldExecute()\n if (shouldExecute) {\n if (this.innerJobs.length > 0) {\n await this.executeJobs()\n } else {\n await this.execute()\n }\n if (!this.isCancelRequestedOrNotRunning()) {\n await this.beforeSuccess()\n }\n }\n } finally {\n // runs only if not already run by cancel()\n await this.runBeforeEnd()\n this.context.tx = undefined\n }\n\n if (this.isCancelRequestedOrNotRunning()) {\n this.throwError(SystemErrorKeys.job.canceledOrErrorsFound)\n }\n }\n\n /**\n * Generates a plain JSON-serializable representation of the job, including its inner jobs.\n */\n toJSON(): JobSerialized<R> {\n const { errors, processed, result, status, total, type, userUuid, uuid } = this\n\n return {\n uuid,\n type,\n userUuid,\n surveyId: this.surveyId,\n innerJobs: this.innerJobs.map((job) => job.toJSON()),\n currentInnerJobIndex: this.currentInnerJobIndex,\n\n status,\n pending: this.isPending(),\n running: this.isRunning(),\n succeeded: this.isSucceeded(),\n canceled: this.isCanceled(),\n failed: this.isFailed(),\n ended: this.isEnded(),\n\n total,\n processed,\n progressPercent: this.calculateProgressPercent(),\n elapsedMillis: this.calculateElapsedMillis(),\n\n errors: this.isFailed() ? errors : undefined,\n result: this.isSucceeded() ? result : undefined,\n }\n }\n\n private async executeJobs(): Promise<void> {\n this.logDebug(`- ${this.total} inner jobs found`)\n\n for (let i = 0; i < this.innerJobs.length; i++) {\n this.logDebug(`- executing inner job ${i + 1}`)\n this.currentInnerJobIndex = i\n const currentInnerJob = this.innerJobs[i]\n if (currentInnerJob.context) {\n Object.assign(this.context, currentInnerJob.context)\n }\n currentInnerJob.context = this.context\n currentInnerJob.onEvent((event) => {\n // handle the inner job events in sequence; errors are logged (they would be unhandled rejections otherwise)\n this.innerJobEventsQueue = this.innerJobEventsQueue\n .then(() => this.onInnerJobEvent(event))\n .catch((error) => this.logError(error?.stack ?? error))\n })\n\n // The inner job shares this very context object, and its own start()/executeInTransaction()\n // clear `context.tx` when they terminate: without saving and restoring it here, the first\n // inner job would wipe the parent's transaction handle, leaving every following inner job\n // (and the parent's own beforeSuccess()/beforeEnd()) running outside of the transaction.\n // start() never throws (it swallows/records errors internally), so a plain restore is enough.\n const parentTx = this.context.tx\n await currentInnerJob.start(parentTx)\n this.context.tx = parentTx\n // the inner job events (e.g. canceled, failed) update the status of this job\n await this.innerJobEventsQueue\n\n if (this.cancelRequested || this.isCanceled() || currentInnerJob.isCanceled()) {\n break\n }\n if (currentInnerJob.isSucceeded()) {\n this.incrementProcessedItems()\n } else if (this.stopOnInnerJobFailure) {\n break\n }\n }\n\n this.logDebug(`- ${this.processed} inner jobs processed successfully`)\n }\n\n /**\n * Runs the job's own work when it has no inner jobs. Default implementation is a no-op, so\n * subclasses that only supply inner jobs (and never override this) don't need to. It also means\n * a subclass can safely call `super.execute()` defensively without knowing whether any ancestor\n * overrides it - if this were `abstract` instead, TypeScript would compile away any runtime\n * property for it entirely, so `super.execute()` would throw the moment no ancestor overrides it\n * (confirmed in production: a subclass whose immediate parent didn't override `execute()` crashed\n * with \"(intermediate value).execute is not a function\" the instant it called `super.execute()`).\n */\n protected async execute(): Promise<void> {\n // to be extended by subclasses\n }\n\n /**\n * Determines whether the job should actually run.\n * When it returns false, \"execute\" (or the inner jobs) will be skipped, but the job will still succeed.\n */\n protected shouldExecute(): Promise<boolean> {\n return Promise.resolve(true)\n }\n\n protected incrementProcessedItems(incrementBy = 1): void {\n this.processed += incrementBy\n }\n\n protected async setStatus(status: JobStatus): Promise<void> {\n this.logDebug(`set status: ${status}`)\n this.status = status\n\n const event: JobEvent = { type: JobEventType.statusChange, status, total: this.total, processed: this.processed }\n if (status === JobStatus.failed) {\n event.errors = this.errors\n }\n\n if (this.isEnded()) {\n this.logDebug('onEnd...')\n await this.onEnd()\n this.logDebug(`onEnd run. Job completed in ${this.elapsedTimePrettyFormat}`)\n }\n\n this.notifyEvent(event)\n }\n\n /**\n * Inner job event handler.\n */\n protected async onInnerJobEvent(event: JobEvent): Promise<void> {\n const { status } = event\n if (status === JobStatus.canceled) {\n this.canceledByAdmin = this.getCurrentInnerJob()?.canceledByAdmin ?? false\n return this.setStatus(status)\n }\n if (status === JobStatus.failed) {\n // report the errors of the failed inner job in the failed event (and in the errors) of this job\n Object.assign(this.errors, this.getCurrentInnerJob()?.errors ?? {})\n return this.setStatus(status)\n }\n if (status === JobStatus.running) {\n this.notifyEvent({\n type: JobEventType.progress,\n status: this.status,\n total: this.total,\n processed: this.processed,\n })\n return\n }\n this.logDebug(`Unknown inner job status: ${status}`)\n }\n\n /**\n * Called when the job just has been started.\n */\n protected async onStart(): Promise<void> {\n this.startTime = new Date()\n await this.setStatus(JobStatus.running)\n }\n\n /**\n * Called before beforeEnd only if the status will change to 'success'.\n * Default implementation stores the value returned by generateResult() via setResult().\n * It runs INSIDE the current db transaction.\n */\n protected async beforeSuccess(): Promise<void> {\n this.setResult(await this.generateResult())\n }\n\n /**\n * Computes the value beforeSuccess() will store as this job's result.\n * Default implementation returns whatever is already in `this.result`\n * (e.g. accumulated via earlier setResult() calls during execute()).\n */\n protected generateResult(): Promise<R | undefined> {\n return Promise.resolve(this.result)\n }\n\n /**\n * Updates this job's result. When both the current and incoming values are plain objects,\n * they are merged (Object.assign); otherwise the incoming value replaces the current one.\n * This keeps it safe for subclasses whose result is a primitive (e.g. a plain number) as\n * well as ones that build an object result incrementally across multiple setResult() calls.\n */\n protected setResult(result: R | undefined): void {\n if (result && typeof result === 'object' && this.result && typeof this.result === 'object') {\n Object.assign(this.result, result)\n } else {\n this.result = result\n }\n }\n\n /**\n * Called before onEnd. Useful for flushing resources used by the job before it terminates completely.\n * It runs INSIDE the current db transaction.\n */\n protected beforeEnd(): Promise<void> {\n this.logDebug('Cleanup')\n return Promise.resolve()\n }\n\n /**\n * Called when the job status changes to success, failed or canceled\n * (it runs OUTSIDE of the current db transaction)\n */\n protected onEnd(): Promise<void> {\n this.endTime = new Date()\n this.cancelNotifyProgress()\n return Promise.resolve()\n }\n\n protected addError(error: any, errorKey?: string): void {\n const key = errorKey ?? String(this.processed + 1)\n this.errors[key] = error\n }\n\n protected throwError(errorKey: string, params?: Dictionary<any>): void {\n // SystemError: getErrorInfo will report the translatable key instead of a generic error\n throw new SystemError(errorKey, params)\n }\n\n protected getErrorInfo(error: any): { key: string; params: Record<string, any> } {\n if (error instanceof SystemError) {\n return { key: `appErrors:${error.key}`, params: error.params }\n }\n return { key: 'appErrors:generic', params: { text: error.toString() } }\n }\n\n protected abstract createLogger(): Logger\n\n protected logDebug(...msgs: any[]): void {\n this.logger.debug(...msgs)\n }\n\n protected logInfo(...msgs: any[]): void {\n this.logger.info(...msgs)\n }\n\n protected logWarn(...msgs: any[]): void {\n this.logger.warn(...msgs)\n }\n\n protected logError(...msgs: any[]): void {\n this.logger.error(...msgs)\n }\n\n private get elapsedTimePrettyFormat(): string {\n const elapsedTime = this.calculateElapsedMillis()\n const elapsedMins = Math.floor(elapsedTime / 1000 / 60)\n const elapsedSeconds = String(Math.floor(elapsedTime / 1000) % 60).padStart(2, '0')\n const elapsedMillis = String(elapsedTime % 1000).padStart(3, '0')\n return `${elapsedMins}:${elapsedSeconds}.${elapsedMillis}`\n }\n\n private calculatePartialProgress(): number {\n if (this.isSucceeded()) return 100\n if (this.total > 0) return Math.floor((100 * this.processed) / this.total)\n return 0\n }\n\n private calculateProgressPercent(): number {\n const partialProgress = this.calculatePartialProgress()\n const currentInnerJob = this.getCurrentInnerJob()\n if (\n !currentInnerJob ||\n this.currentInnerJobIndex < 0 ||\n partialProgress === 100 ||\n this.processed > this.currentInnerJobIndex\n ) {\n return partialProgress\n }\n return partialProgress + Math.floor(currentInnerJob.calculateProgressPercent() / this.total)\n }\n\n private calculateElapsedMillis(): number {\n if (!this.startTime) return 0\n return (this.endTime ?? new Date()).getTime() - this.startTime.getTime()\n }\n\n /**\n * Notifies a progress event to the registered listener, throttled so that fast-changing\n * progress does not flood consumers (e.g. web socket clients).\n */\n private notifyProgress(): void {\n const run = (): void => {\n this.progressThrottleTimeoutId = undefined\n this.progressThrottleLastRunTime = Date.now()\n this.notifyEvent({\n type: JobEventType.progress,\n status: this.status,\n total: this.total,\n processed: this.processed,\n })\n }\n\n if (this.progressThrottleTimeoutId) return\n\n const elapsed = Date.now() - this.progressThrottleLastRunTime\n if (!this.progressThrottleLastRunTime || elapsed >= PROGRESS_NOTIFICATION_THROTTLE_MILLIS) {\n run()\n } else {\n this.progressThrottleTimeoutId = setTimeout(run, PROGRESS_NOTIFICATION_THROTTLE_MILLIS - elapsed)\n }\n }\n\n /**\n * Cancels any pending throttled progress notification and resets the throttle state.\n */\n private cancelNotifyProgress(): void {\n if (this.progressThrottleTimeoutId) {\n clearTimeout(this.progressThrottleTimeoutId)\n this.progressThrottleTimeoutId = undefined\n }\n this.progressThrottleLastRunTime = 0\n }\n\n /**\n * Notifies the event to the registered listener.\n * Listener errors are only logged: they would otherwise fail the job or, when thrown inside the progress\n * throttle timeout, crash the process.\n */\n private notifyEvent(event: JobEvent): void {\n const listener = this.eventListener\n if (!listener) return\n try {\n Promise.resolve(listener(event)).catch((error) => this.logListenerError(error))\n } catch (error) {\n this.logListenerError(error)\n }\n }\n\n private logListenerError(error: any): void {\n this.logError(`error in job event listener: ${error?.stack ?? error}`)\n }\n}\n"]}
1
+ {"version":3,"file":"JobBase.js","sourceRoot":"","sources":["../../../src/job/JobBase.ts"],"names":[],"mappings":"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","sourcesContent":["import { User } from '../auth'\nimport { Dictionary } from '../common'\nimport { SystemError, SystemErrorKeys } from '../error'\nimport { Logger } from '../logger'\nimport { Survey } from '../survey'\nimport { UUIDs } from '../utils'\n\nimport { Job } from './job'\nimport { JobContext } from './jobContext'\nimport { JobEvent, JobEventType } from './jobEvent'\nimport { JobSerialized } from './jobSerialized'\nimport { JobStatus } from './status'\n\nexport interface JobConstructor {\n new <C extends JobContext, R>(context: C, innerJobs?: JobBase<any>[]): JobBase<C, R>\n readonly prototype: JobBase<any, any>\n}\n\n/**\n * Client able to open a transaction (e.g. a pg-promise database): the job runs inside `client.tx(callback)`.\n */\nexport interface JobTxClient {\n tx(callback: (tx: any) => Promise<void>): Promise<unknown>\n}\n\nconst PROGRESS_NOTIFICATION_THROTTLE_MILLIS = 1000\n\n/**\n * Asynchronous task handler.\n *\n * Status workflow:\n * - pending\n * - running\n * - (end)\n * -- succeeded\n * -- failed\n * -- canceled\n *\n * Methods that can be overwritten by subclasses:\n * - shouldExecute (in tx)\n * - onStart (in tx)\n * - execute (in tx)\n * - beforeSuccess (in tx)\n * - generateResult (in tx)\n * - beforeEnd (in tx)\n * - onEnd (out of tx)\n * - getErrorInfo\n */\nexport abstract class JobBase<C extends JobContext, R = undefined> implements Job<R> {\n static readonly keysContext = {\n surveyId: 'surveyId',\n survey: 'survey',\n user: 'user',\n }\n\n readonly uuid: string\n readonly type: string\n status: JobStatus = JobStatus.pending\n startTime?: Date\n endTime?: Date\n total: number\n result: R | undefined = undefined\n errors: Record<string, any> = {}\n canceledByAdmin?: boolean\n\n protected logger: Logger\n protected context: C\n protected innerJobs: JobBase<C, any>[]\n protected currentInnerJobIndex = -1\n\n private _processed = 0\n private eventListener: ((event: JobEvent) => unknown) | undefined = undefined\n private progressThrottleTimeoutId: ReturnType<typeof setTimeout> | undefined = undefined\n private progressThrottleLastRunTime = 0\n private _stopOnInnerJobFailure = true\n // set as soon as cancel() is called (the canceled status is set only after beforeEnd has run)\n private cancelRequested = false\n private beforeEndCalled = false\n // inner job events are handled in sequence; executeJobs waits for them before going on\n private innerJobEventsQueue: Promise<void> = Promise.resolve()\n\n public constructor(context: C, innerJobs: JobBase<C, any>[] = []) {\n this.context = { ...context }\n this.innerJobs = innerJobs\n\n this.uuid = UUIDs.v4()\n this.type = this.context.type ?? this.constructor.name\n this.total = innerJobs.length > 0 ? innerJobs.length : 1\n\n // Created last, so that createLogger() overrides can safely build the logger name out of\n // the job identity (e.g. arena's `Job <ClassName> (<uuid>)` log correlation id).\n this.logger = this.createLogger()\n }\n\n get processed(): number {\n return this._processed\n }\n\n set processed(value: number) {\n this._processed = value\n this.notifyProgress()\n }\n\n get stopOnInnerJobFailure(): boolean {\n return this._stopOnInnerJobFailure\n }\n\n set stopOnInnerJobFailure(value: boolean) {\n this._stopOnInnerJobFailure = value\n }\n\n protected get surveyId(): number | null {\n return this.context.surveyId ?? null\n }\n\n protected get user(): User {\n return this.context.user\n }\n\n protected get userUuid(): string | undefined {\n return this.user?.uuid\n }\n\n protected get contextSurvey(): Survey | undefined {\n return this.context.survey\n }\n\n /**\n * Returns the value of the specified context prop, or the default value (null if not specified) when not set.\n */\n protected getContextProp<K extends keyof C & string>(prop: K, defaultValue?: C[K] | null): C[K] | null\n /** Context prop not declared in the context type: the value is typed by the caller. */\n protected getContextProp<T = any, P extends string = string>(\n prop: P extends keyof C ? never : P,\n defaultValue?: T | null\n ): T | null\n protected getContextProp(prop: string, defaultValue: unknown = null): unknown {\n const value = (this.context as Record<string, unknown>)[prop]\n return value ?? defaultValue\n }\n\n protected setContext(context: Partial<C>): void {\n Object.assign(this.context, context)\n }\n\n protected deleteContextProps(...propNames: string[]): void {\n propNames.forEach((propName) => {\n delete (this.context as any)[propName]\n })\n }\n\n /**\n * Registers the listener notified of job events (status changes and progress).\n * Only one listener can be registered at a time; registering a new one replaces the previous one.\n * Errors thrown (or rejections returned) by the listener are logged and do not affect the job execution.\n */\n onEvent(listener: (event: JobEvent) => unknown): this {\n this.eventListener = listener\n return this\n }\n\n isPending(): boolean {\n return this.status === JobStatus.pending\n }\n\n isRunning(): boolean {\n return this.status === JobStatus.running\n }\n\n isSucceeded(): boolean {\n return this.status === JobStatus.succeeded\n }\n\n isFailed(): boolean {\n return this.status === JobStatus.failed\n }\n\n isCanceled(): boolean {\n return this.status === JobStatus.canceled\n }\n\n isEnded(): boolean {\n return [JobStatus.succeeded, JobStatus.failed, JobStatus.canceled].includes(this.status)\n }\n\n hasErrors(): boolean {\n return Object.keys(this.errors).length > 0\n }\n\n protected getCurrentInnerJob(): JobBase<C, any> | undefined {\n return this.innerJobs[this.currentInnerJobIndex]\n }\n\n protected combineInnerJobsResults(): Record<string, any> {\n const results: Record<string, any> = {}\n this.innerJobs.forEach((innerJob) => Object.assign(results, innerJob.result ?? {}))\n return results\n }\n\n protected combineInnerJobsErrors(): Record<string, any> {\n const errors: Record<string, any> = {}\n this.innerJobs.forEach((innerJob) => Object.assign(errors, innerJob.errors ?? {}))\n return errors\n }\n\n async cancel(options: { canceledByAdmin?: boolean } = {}): Promise<void> {\n const { canceledByAdmin = false } = options\n if (this.isEnded()) return\n\n this.cancelRequested = true\n\n const currentInnerJob = this.getCurrentInnerJob()\n if (currentInnerJob && !currentInnerJob.isEnded()) {\n // inner job running or about to start (pending):\n // the parent job status will be set to canceled when handling the canceled event of the inner job\n await currentInnerJob.cancel({ canceledByAdmin })\n return\n }\n // no inner job running (job without inner jobs, or between two inner jobs)\n this.canceledByAdmin = canceledByAdmin\n // release the resources (temp files/directories, streams) allocated before the cancellation\n await this.runBeforeEnd()\n await this.setStatus(JobStatus.canceled)\n }\n\n /**\n * Returns true when the job has been canceled (or is no longer running).\n * Long-running subclasses can check it to stop processing items (e.g. in a loop) as soon as the job is canceled.\n */\n protected isCancelRequestedOrNotRunning(): boolean {\n return this.cancelRequested || !this.isRunning()\n }\n\n /**\n * Runs beforeEnd only once (it can be called by cancel() and when the job execution ends).\n */\n private async runBeforeEnd(): Promise<void> {\n if (this.beforeEndCalled) return\n this.beforeEndCalled = true\n await this.beforeEnd()\n }\n\n async start(client: JobTxClient | null = null): Promise<void> {\n // canceled before being started: nothing to execute\n if (this.cancelRequested || this.isEnded()) return\n\n this.logDebug('start')\n\n try {\n if (client) {\n await client.tx(async (tx: any) => {\n this.context.tx = tx\n await this.executeInTransaction()\n })\n } else {\n await this.executeInTransaction()\n }\n if (!this.isCancelRequestedOrNotRunning()) {\n await this.setStatus(JobStatus.succeeded)\n }\n } catch (error: any) {\n // a job can fail while still pending (e.g. the transaction cannot be opened, or onStart fails)\n if (!this.cancelRequested && !this.isFailed() && !this.isCanceled()) {\n this.logError(error.stack ?? error)\n const { key, params } = this.getErrorInfo(error)\n this.addError({ error: { valid: false, errors: [{ key, params }] } })\n await this.setStatus(JobStatus.failed)\n }\n } finally {\n this.context.tx = undefined\n }\n }\n\n private async executeInTransaction(): Promise<void> {\n try {\n // canceled while the transaction was being opened: it must not be set as running again\n if (this.cancelRequested) return\n\n await this.onStart()\n\n const shouldExecute = await this.shouldExecute()\n if (shouldExecute) {\n if (this.innerJobs.length > 0) {\n await this.executeJobs()\n } else {\n await this.execute()\n }\n if (!this.isCancelRequestedOrNotRunning()) {\n await this.beforeSuccess()\n }\n }\n } finally {\n // runs only if not already run by cancel()\n await this.runBeforeEnd()\n this.context.tx = undefined\n }\n\n if (this.isCancelRequestedOrNotRunning()) {\n this.throwError(SystemErrorKeys.job.canceledOrErrorsFound)\n }\n }\n\n /**\n * Generates a plain JSON-serializable representation of the job, including its inner jobs.\n */\n toJSON(): JobSerialized<R> {\n const { errors, processed, result, status, total, type, userUuid, uuid } = this\n\n return {\n uuid,\n type,\n userUuid,\n surveyId: this.surveyId,\n innerJobs: this.innerJobs.map((job) => job.toJSON()),\n currentInnerJobIndex: this.currentInnerJobIndex,\n\n status,\n pending: this.isPending(),\n running: this.isRunning(),\n succeeded: this.isSucceeded(),\n canceled: this.isCanceled(),\n failed: this.isFailed(),\n ended: this.isEnded(),\n\n total,\n processed,\n progressPercent: this.calculateProgressPercent(),\n elapsedMillis: this.calculateElapsedMillis(),\n\n errors: this.isFailed() ? errors : undefined,\n result: this.isSucceeded() ? result : undefined,\n }\n }\n\n private async executeJobs(): Promise<void> {\n this.logDebug(`- ${this.total} inner jobs found`)\n\n for (let i = 0; i < this.innerJobs.length; i++) {\n // canceled between two inner jobs: the next ones must not be started\n if (this.cancelRequested) break\n\n this.logDebug(`- executing inner job ${i + 1}`)\n this.currentInnerJobIndex = i\n const currentInnerJob = this.innerJobs[i]\n if (currentInnerJob.context) {\n Object.assign(this.context, currentInnerJob.context)\n }\n currentInnerJob.context = this.context\n currentInnerJob.onEvent((event) => {\n // handle the inner job events in sequence; errors are logged (they would be unhandled rejections otherwise)\n this.innerJobEventsQueue = this.innerJobEventsQueue\n .then(() => this.onInnerJobEvent(event))\n .catch((error) => this.logError(error?.stack ?? error))\n })\n\n // The inner job shares this very context object, and its own start()/executeInTransaction()\n // clear `context.tx` when they terminate: without saving and restoring it here, the first\n // inner job would wipe the parent's transaction handle, leaving every following inner job\n // (and the parent's own beforeSuccess()/beforeEnd()) running outside of the transaction.\n // start() never throws (it swallows/records errors internally), so a plain restore is enough.\n const parentTx = this.context.tx\n await currentInnerJob.start(parentTx)\n this.context.tx = parentTx\n // the inner job events (e.g. canceled, failed) update the status of this job\n await this.innerJobEventsQueue\n\n if (this.cancelRequested || this.isCanceled() || currentInnerJob.isCanceled()) {\n break\n }\n if (currentInnerJob.isSucceeded()) {\n this.incrementProcessedItems()\n } else if (this.stopOnInnerJobFailure) {\n break\n }\n }\n if (\n !this.stopOnInnerJobFailure &&\n !this.cancelRequested &&\n this.innerJobs.some((innerJob) => innerJob.isFailed())\n ) {\n // set only after all inner jobs have run: setting it at the first failure would end this job (onEnd) too early\n await this.setStatus(JobStatus.failed)\n }\n\n this.logDebug(`- ${this.processed} inner jobs processed successfully`)\n }\n\n /**\n * Runs the job's own work when it has no inner jobs. Default implementation is a no-op, so\n * subclasses that only supply inner jobs (and never override this) don't need to. It also means\n * a subclass can safely call `super.execute()` defensively without knowing whether any ancestor\n * overrides it - if this were `abstract` instead, TypeScript would compile away any runtime\n * property for it entirely, so `super.execute()` would throw the moment no ancestor overrides it\n * (confirmed in production: a subclass whose immediate parent didn't override `execute()` crashed\n * with \"(intermediate value).execute is not a function\" the instant it called `super.execute()`).\n */\n protected async execute(): Promise<void> {\n // to be extended by subclasses\n }\n\n /**\n * Determines whether the job should actually run.\n * When it returns false, \"execute\" (or the inner jobs) will be skipped, but the job will still succeed.\n */\n protected shouldExecute(): Promise<boolean> {\n return Promise.resolve(true)\n }\n\n protected incrementProcessedItems(incrementBy = 1): void {\n this.processed += incrementBy\n }\n\n protected async setStatus(status: JobStatus): Promise<void> {\n this.logDebug(`set status: ${status}`)\n this.status = status\n\n const event: JobEvent = { type: JobEventType.statusChange, status, total: this.total, processed: this.processed }\n if (status === JobStatus.failed) {\n event.errors = this.errors\n }\n\n if (this.isEnded()) {\n this.logDebug('onEnd...')\n await this.onEnd()\n this.logDebug(`onEnd run. Job completed in ${this.elapsedTimePrettyFormat}`)\n }\n\n this.notifyEvent(event)\n }\n\n /**\n * Inner job event handler.\n */\n protected async onInnerJobEvent(event: JobEvent): Promise<void> {\n const { status } = event\n if (status === JobStatus.canceled) {\n this.canceledByAdmin = this.getCurrentInnerJob()?.canceledByAdmin ?? false\n return this.setStatus(status)\n }\n if (status === JobStatus.failed) {\n // report the errors of the failed inner job in the failed event (and in the errors) of this job\n Object.assign(this.errors, this.getCurrentInnerJob()?.errors ?? {})\n // when not stopping on inner job failures, this job is set as failed after all the inner jobs have run\n return this.stopOnInnerJobFailure ? this.setStatus(status) : undefined\n }\n if (status === JobStatus.running) {\n this.notifyEvent({\n type: JobEventType.progress,\n status: this.status,\n total: this.total,\n processed: this.processed,\n })\n return\n }\n this.logDebug(`Unknown inner job status: ${status}`)\n }\n\n /**\n * Called when the job just has been started.\n */\n protected async onStart(): Promise<void> {\n this.startTime = new Date()\n await this.setStatus(JobStatus.running)\n }\n\n /**\n * Called before beforeEnd only if the status will change to 'success'.\n * Default implementation stores the value returned by generateResult() via setResult().\n * It runs INSIDE the current db transaction.\n */\n protected async beforeSuccess(): Promise<void> {\n this.setResult(await this.generateResult())\n }\n\n /**\n * Computes the value beforeSuccess() will store as this job's result.\n * Default implementation returns whatever is already in `this.result`\n * (e.g. accumulated via earlier setResult() calls during execute()).\n */\n protected generateResult(): Promise<R | undefined> {\n return Promise.resolve(this.result)\n }\n\n /**\n * Updates this job's result. When both the current and incoming values are plain objects,\n * they are merged (Object.assign); otherwise the incoming value replaces the current one.\n * This keeps it safe for subclasses whose result is a primitive (e.g. a plain number) as\n * well as ones that build an object result incrementally across multiple setResult() calls.\n */\n protected setResult(result: R | undefined): void {\n if (result && typeof result === 'object' && this.result && typeof this.result === 'object') {\n Object.assign(this.result, result)\n } else {\n this.result = result\n }\n }\n\n /**\n * Called before onEnd. Useful for flushing resources used by the job before it terminates completely.\n * It runs INSIDE the current db transaction.\n */\n protected beforeEnd(): Promise<void> {\n this.logDebug('Cleanup')\n return Promise.resolve()\n }\n\n /**\n * Called when the job status changes to success, failed or canceled\n * (it runs OUTSIDE of the current db transaction)\n */\n protected onEnd(): Promise<void> {\n this.endTime = new Date()\n this.cancelNotifyProgress()\n return Promise.resolve()\n }\n\n protected addError(error: any, errorKey?: string): void {\n const key = errorKey ?? String(this.processed + 1)\n this.errors[key] = error\n }\n\n protected throwError(errorKey: string, params?: Dictionary<any>): void {\n // SystemError: getErrorInfo will report the translatable key instead of a generic error\n throw new SystemError(errorKey, params)\n }\n\n protected getErrorInfo(error: any): { key: string; params: Record<string, any> } {\n if (error instanceof SystemError) {\n return { key: `appErrors:${error.key}`, params: error.params }\n }\n return { key: 'appErrors:generic', params: { text: error.toString() } }\n }\n\n protected abstract createLogger(): Logger\n\n protected logDebug(...msgs: any[]): void {\n this.logger.debug(...msgs)\n }\n\n protected logInfo(...msgs: any[]): void {\n this.logger.info(...msgs)\n }\n\n protected logWarn(...msgs: any[]): void {\n this.logger.warn(...msgs)\n }\n\n protected logError(...msgs: any[]): void {\n this.logger.error(...msgs)\n }\n\n private get elapsedTimePrettyFormat(): string {\n const elapsedTime = this.calculateElapsedMillis()\n const elapsedMins = Math.floor(elapsedTime / 1000 / 60)\n const elapsedSeconds = String(Math.floor(elapsedTime / 1000) % 60).padStart(2, '0')\n const elapsedMillis = String(elapsedTime % 1000).padStart(3, '0')\n return `${elapsedMins}:${elapsedSeconds}.${elapsedMillis}`\n }\n\n private calculatePartialProgress(): number {\n if (this.isSucceeded()) return 100\n if (this.total > 0) return Math.floor((100 * this.processed) / this.total)\n return 0\n }\n\n private calculateProgressPercent(): number {\n const partialProgress = this.calculatePartialProgress()\n const currentInnerJob = this.getCurrentInnerJob()\n if (\n !currentInnerJob ||\n this.currentInnerJobIndex < 0 ||\n partialProgress === 100 ||\n this.processed > this.currentInnerJobIndex\n ) {\n return partialProgress\n }\n return partialProgress + Math.floor(currentInnerJob.calculateProgressPercent() / this.total)\n }\n\n private calculateElapsedMillis(): number {\n if (!this.startTime) return 0\n return (this.endTime ?? new Date()).getTime() - this.startTime.getTime()\n }\n\n /**\n * Notifies a progress event to the registered listener, throttled so that fast-changing\n * progress does not flood consumers (e.g. web socket clients).\n */\n private notifyProgress(): void {\n const run = (): void => {\n this.progressThrottleTimeoutId = undefined\n this.progressThrottleLastRunTime = Date.now()\n this.notifyEvent({\n type: JobEventType.progress,\n status: this.status,\n total: this.total,\n processed: this.processed,\n })\n }\n\n if (this.progressThrottleTimeoutId) return\n\n const elapsed = Date.now() - this.progressThrottleLastRunTime\n if (!this.progressThrottleLastRunTime || elapsed >= PROGRESS_NOTIFICATION_THROTTLE_MILLIS) {\n run()\n } else {\n this.progressThrottleTimeoutId = setTimeout(run, PROGRESS_NOTIFICATION_THROTTLE_MILLIS - elapsed)\n }\n }\n\n /**\n * Cancels any pending throttled progress notification and resets the throttle state.\n */\n private cancelNotifyProgress(): void {\n if (this.progressThrottleTimeoutId) {\n clearTimeout(this.progressThrottleTimeoutId)\n this.progressThrottleTimeoutId = undefined\n }\n this.progressThrottleLastRunTime = 0\n }\n\n /**\n * Notifies the event to the registered listener.\n * Listener errors are only logged: they would otherwise fail the job or, when thrown inside the progress\n * throttle timeout, crash the process.\n */\n private notifyEvent(event: JobEvent): void {\n const listener = this.eventListener\n if (!listener) return\n try {\n Promise.resolve(listener(event)).catch((error) => this.logListenerError(error))\n } catch (error) {\n this.logListenerError(error)\n }\n }\n\n private logListenerError(error: any): void {\n this.logError(`error in job event listener: ${error?.stack ?? error}`)\n }\n}\n"]}
@@ -87,7 +87,7 @@ const fixNodeDefs = (params) => {
87
87
  if (fixedNodeDef) {
88
88
  updatedNodeDefs[nodeDef.uuid] = fixedNodeDef;
89
89
  }
90
- nodeDefsResult[nodeDef.uuid] = fixedNodeDef !== null && fixedNodeDef !== void 0 ? fixedNodeDef : nodeDef;
90
+ nodeDefsResult[nodeDef.uuid] = fixedNodeDef !== null && fixedNodeDef !== void 0 ? fixedNodeDef : nodeDefToFix;
91
91
  }
92
92
  }
93
93
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"nodeDefsFixer.js","sourceRoot":"","sources":["../../../src/survey/nodeDefsFixer.ts"],"names":[],"mappings":"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","sourcesContent":["import { SystemError, SystemErrorKeys } from '../error'\nimport { NodeDef, NodeDefEntity, NodeDefMap, NodeDefs } from '../nodeDef'\nimport { NodeDefEntityLayoutChildItem } from '../nodeDef/types/entity'\nimport { Objects } from '../utils'\nimport { MutationOptions } from '../utils/mutationOptions'\n\ntype NodeDefsFixParams = MutationOptions & {\n nodeDefs: NodeDefMap\n cycles: string[]\n}\n\ntype NodeDefsInCycleFixParams = NodeDefsFixParams & {\n cycle: string\n}\n\ntype NodeDefFixParams = NodeDefsInCycleFixParams & {\n nodeDef: NodeDef<any>\n}\n\ntype LayoutPropFixParams = NodeDefFixParams & {\n propName: string\n}\n\ntype LayoutPropFixerFnParams = LayoutPropFixParams & { propOld: any }\n\nconst calculateNodeDefHierarchy = (params: { nodeDef: NodeDef<any>; nodeDefs: NodeDefMap }): string[] => {\n const { nodeDef, nodeDefs } = params\n const hierarchy = []\n const visitedNodeDefUuids = new Set<string>()\n let currentParentUuid = nodeDef.parentUuid\n while (currentParentUuid) {\n if (visitedNodeDefUuids.has(currentParentUuid)) {\n throw new SystemError(SystemErrorKeys.nodeDef.hierarchyCircularDependency, {\n nodeDefName: nodeDef.props?.name,\n nodeDefUuid: nodeDef.uuid,\n parentUuid: currentParentUuid,\n })\n }\n visitedNodeDefUuids.add(currentParentUuid)\n hierarchy.unshift(currentParentUuid)\n const currentParentNode = nodeDefs[currentParentUuid]\n if (!currentParentNode) {\n throw new SystemError(SystemErrorKeys.nodeDef.parentNotFound, {\n nodeDefName: nodeDef.props?.name,\n nodeDefUuid: nodeDef.uuid,\n parentUuid: currentParentUuid,\n })\n }\n currentParentUuid = currentParentNode.parentUuid\n }\n return hierarchy\n}\n\nconst fixHierarchy = (params: NodeDefFixParams): NodeDef<any> | null => {\n const { nodeDefs, nodeDef, sideEffect } = params\n const calculatedHierarchy = calculateNodeDefHierarchy({ nodeDefs, nodeDef })\n // compare the whole hierarchy: a node def moved to another parent at the same depth has a hierarchy with the same length\n return Objects.isEqual(calculatedHierarchy, NodeDefs.getMetaHierarchy(nodeDef))\n ? null\n : Objects.assocPath({ obj: nodeDef, path: ['meta', 'h'], value: calculatedHierarchy, sideEffect })\n}\n\nconst fixLayoutProp = (\n params: LayoutPropFixParams & { fixerFn: (params: LayoutPropFixerFnParams) => any }\n): NodeDef<any> | null => {\n const { cycle, nodeDef, propName, sideEffect, fixerFn } = params\n\n const propPath = ['props', 'layout', cycle, propName]\n\n const propOld = Objects.path(propPath)(nodeDef)\n\n if (Objects.isEmpty(propOld)) return null\n\n const propFixed = fixerFn({ ...params, propOld })\n\n if (Objects.isEqual(propOld, propFixed)) return null\n\n return Objects.assocPath({\n obj: nodeDef,\n path: propPath,\n value: propFixed,\n sideEffect,\n })\n}\n\nconst fixIndexChildren = (params: NodeDefFixParams): NodeDef<any> | null =>\n fixLayoutProp({\n ...params,\n propName: 'indexChildren',\n fixerFn: ({ nodeDefs, cycle, propOld: indexChildren }) =>\n (indexChildren as string[]).filter((childDefUuid) => {\n const childDef = nodeDefs[childDefUuid]\n return (\n childDef?.parentUuid === params.nodeDef.uuid &&\n NodeDefs.isEntity(childDef) &&\n NodeDefs.isDisplayInOwnPage(cycle)(childDef as NodeDefEntity)\n )\n }),\n })\n\nconst fixLayoutChildren = (params: NodeDefFixParams): NodeDef<any> | null =>\n fixLayoutProp({\n ...params,\n propName: 'layoutChildren',\n fixerFn: ({ nodeDefs, cycle, propOld: layoutChildren }) =>\n (layoutChildren as NodeDefEntityLayoutChildItem[]).filter((item) => {\n const childDefUuid = typeof item === 'string' ? item : item.i\n const childDef = nodeDefs[childDefUuid]\n return (\n childDef?.parentUuid === params.nodeDef.uuid &&\n (!NodeDefs.isEntity(childDef) || !NodeDefs.isDisplayInOwnPage(cycle)(childDef as NodeDefEntity))\n )\n }),\n })\n\nconst fix = (params: NodeDefFixParams): NodeDef<any> | null => {\n const { nodeDef } = params\n let nodeDefFixed: NodeDef<any> | null = fixHierarchy(params)\n if (NodeDefs.isEntity(nodeDef)) {\n nodeDefFixed = fixIndexChildren({ ...params, nodeDef: nodeDefFixed ?? nodeDef }) ?? nodeDefFixed\n nodeDefFixed = fixLayoutChildren({ ...params, nodeDef: nodeDefFixed ?? nodeDef }) ?? nodeDefFixed\n }\n return nodeDefFixed\n}\n\nconst fixNodeDefs = (params: NodeDefsFixParams): { nodeDefs: NodeDefMap; updatedNodeDefs: NodeDefMap } => {\n const { nodeDefs, cycles } = params\n const nodeDefsResult: NodeDefMap = {}\n const updatedNodeDefs: NodeDefMap = {}\n\n for (const cycle of cycles) {\n for (const nodeDef of Object.values(nodeDefs)) {\n const nodeDefToFix = nodeDefsResult[nodeDef.uuid] ?? nodeDef\n const fixedNodeDef = fix({ ...params, cycle, nodeDef: nodeDefToFix })\n if (fixedNodeDef) {\n updatedNodeDefs[nodeDef.uuid] = fixedNodeDef\n }\n nodeDefsResult[nodeDef.uuid] = fixedNodeDef ?? nodeDef\n }\n }\n return {\n nodeDefs: nodeDefsResult,\n updatedNodeDefs,\n }\n}\n\nexport const NodeDefsFixer = {\n fixNodeDefs,\n}\n"]}
1
+ {"version":3,"file":"nodeDefsFixer.js","sourceRoot":"","sources":["../../../src/survey/nodeDefsFixer.ts"],"names":[],"mappings":"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","sourcesContent":["import { SystemError, SystemErrorKeys } from '../error'\nimport { NodeDef, NodeDefEntity, NodeDefMap, NodeDefs } from '../nodeDef'\nimport { NodeDefEntityLayoutChildItem } from '../nodeDef/types/entity'\nimport { Objects } from '../utils'\nimport { MutationOptions } from '../utils/mutationOptions'\n\ntype NodeDefsFixParams = MutationOptions & {\n nodeDefs: NodeDefMap\n cycles: string[]\n}\n\ntype NodeDefsInCycleFixParams = NodeDefsFixParams & {\n cycle: string\n}\n\ntype NodeDefFixParams = NodeDefsInCycleFixParams & {\n nodeDef: NodeDef<any>\n}\n\ntype LayoutPropFixParams = NodeDefFixParams & {\n propName: string\n}\n\ntype LayoutPropFixerFnParams = LayoutPropFixParams & { propOld: any }\n\nconst calculateNodeDefHierarchy = (params: { nodeDef: NodeDef<any>; nodeDefs: NodeDefMap }): string[] => {\n const { nodeDef, nodeDefs } = params\n const hierarchy = []\n const visitedNodeDefUuids = new Set<string>()\n let currentParentUuid = nodeDef.parentUuid\n while (currentParentUuid) {\n if (visitedNodeDefUuids.has(currentParentUuid)) {\n throw new SystemError(SystemErrorKeys.nodeDef.hierarchyCircularDependency, {\n nodeDefName: nodeDef.props?.name,\n nodeDefUuid: nodeDef.uuid,\n parentUuid: currentParentUuid,\n })\n }\n visitedNodeDefUuids.add(currentParentUuid)\n hierarchy.unshift(currentParentUuid)\n const currentParentNode = nodeDefs[currentParentUuid]\n if (!currentParentNode) {\n throw new SystemError(SystemErrorKeys.nodeDef.parentNotFound, {\n nodeDefName: nodeDef.props?.name,\n nodeDefUuid: nodeDef.uuid,\n parentUuid: currentParentUuid,\n })\n }\n currentParentUuid = currentParentNode.parentUuid\n }\n return hierarchy\n}\n\nconst fixHierarchy = (params: NodeDefFixParams): NodeDef<any> | null => {\n const { nodeDefs, nodeDef, sideEffect } = params\n const calculatedHierarchy = calculateNodeDefHierarchy({ nodeDefs, nodeDef })\n // compare the whole hierarchy: a node def moved to another parent at the same depth has a hierarchy with the same length\n return Objects.isEqual(calculatedHierarchy, NodeDefs.getMetaHierarchy(nodeDef))\n ? null\n : Objects.assocPath({ obj: nodeDef, path: ['meta', 'h'], value: calculatedHierarchy, sideEffect })\n}\n\nconst fixLayoutProp = (\n params: LayoutPropFixParams & { fixerFn: (params: LayoutPropFixerFnParams) => any }\n): NodeDef<any> | null => {\n const { cycle, nodeDef, propName, sideEffect, fixerFn } = params\n\n const propPath = ['props', 'layout', cycle, propName]\n\n const propOld = Objects.path(propPath)(nodeDef)\n\n if (Objects.isEmpty(propOld)) return null\n\n const propFixed = fixerFn({ ...params, propOld })\n\n if (Objects.isEqual(propOld, propFixed)) return null\n\n return Objects.assocPath({\n obj: nodeDef,\n path: propPath,\n value: propFixed,\n sideEffect,\n })\n}\n\nconst fixIndexChildren = (params: NodeDefFixParams): NodeDef<any> | null =>\n fixLayoutProp({\n ...params,\n propName: 'indexChildren',\n fixerFn: ({ nodeDefs, cycle, propOld: indexChildren }) =>\n (indexChildren as string[]).filter((childDefUuid) => {\n const childDef = nodeDefs[childDefUuid]\n return (\n childDef?.parentUuid === params.nodeDef.uuid &&\n NodeDefs.isEntity(childDef) &&\n NodeDefs.isDisplayInOwnPage(cycle)(childDef as NodeDefEntity)\n )\n }),\n })\n\nconst fixLayoutChildren = (params: NodeDefFixParams): NodeDef<any> | null =>\n fixLayoutProp({\n ...params,\n propName: 'layoutChildren',\n fixerFn: ({ nodeDefs, cycle, propOld: layoutChildren }) =>\n (layoutChildren as NodeDefEntityLayoutChildItem[]).filter((item) => {\n const childDefUuid = typeof item === 'string' ? item : item.i\n const childDef = nodeDefs[childDefUuid]\n return (\n childDef?.parentUuid === params.nodeDef.uuid &&\n (!NodeDefs.isEntity(childDef) || !NodeDefs.isDisplayInOwnPage(cycle)(childDef as NodeDefEntity))\n )\n }),\n })\n\nconst fix = (params: NodeDefFixParams): NodeDef<any> | null => {\n const { nodeDef } = params\n let nodeDefFixed: NodeDef<any> | null = fixHierarchy(params)\n if (NodeDefs.isEntity(nodeDef)) {\n nodeDefFixed = fixIndexChildren({ ...params, nodeDef: nodeDefFixed ?? nodeDef }) ?? nodeDefFixed\n nodeDefFixed = fixLayoutChildren({ ...params, nodeDef: nodeDefFixed ?? nodeDef }) ?? nodeDefFixed\n }\n return nodeDefFixed\n}\n\nconst fixNodeDefs = (params: NodeDefsFixParams): { nodeDefs: NodeDefMap; updatedNodeDefs: NodeDefMap } => {\n const { nodeDefs, cycles } = params\n const nodeDefsResult: NodeDefMap = {}\n const updatedNodeDefs: NodeDefMap = {}\n\n for (const cycle of cycles) {\n for (const nodeDef of Object.values(nodeDefs)) {\n const nodeDefToFix = nodeDefsResult[nodeDef.uuid] ?? nodeDef\n const fixedNodeDef = fix({ ...params, cycle, nodeDef: nodeDefToFix })\n if (fixedNodeDef) {\n updatedNodeDefs[nodeDef.uuid] = fixedNodeDef\n }\n nodeDefsResult[nodeDef.uuid] = fixedNodeDef ?? nodeDefToFix\n }\n }\n return {\n nodeDefs: nodeDefsResult,\n updatedNodeDefs,\n }\n}\n\nexport const NodeDefsFixer = {\n fixNodeDefs,\n}\n"]}
@@ -92,6 +92,9 @@ export const getOnUpdateDependents = (params) => {
92
92
  const addDependency = (params) => {
93
93
  const { graphs, type, nodeDefUuid, nodeDefDepUuid, sideEffect = false } = params;
94
94
  const deps = getDependencies({ graphs, type, nodeDefUuid });
95
+ // dependencies of a node def can be added again (e.g. when it is updated): keep each dependent only once
96
+ if (deps.includes(nodeDefDepUuid))
97
+ return graphs;
95
98
  const depsUpdated = Arrays.addItem(nodeDefDepUuid, { sideEffect })(deps);
96
99
  return Objects.assocPath({ obj: graphs, path: [type, nodeDefUuid], value: depsUpdated, sideEffect });
97
100
  };
@@ -1 +1 @@
1
- {"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../../../src/survey/surveys/dependencies.ts"],"names":[],"mappings":"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","sourcesContent":["import * as SurveyNodeDefs from './nodeDefs'\nimport {\n NodeDef,\n NodeDefCode,\n NodeDefEntity,\n NodeDefExpression,\n NodeDefFile,\n NodeDefProps,\n NodeDefs,\n NodeDefType,\n} from '../../nodeDef'\nimport { NodeDefExpressionEvaluator } from '../../nodeDefExpressionEvaluator'\n\nimport { Survey, SurveyDependencyGraph, SurveyDependencyType } from '../survey'\nimport { Arrays, Objects } from '../../utils'\nimport { NodeDefExpressionFactory } from '../../nodeDef/nodeDef'\nimport { Dictionary } from '../../common'\n\nconst functionsRequiringOnUpdateDependency = ['recordDateLastModified']\n\nconst isContextParentByDependencyType = {\n [SurveyDependencyType.applicable]: true,\n [SurveyDependencyType.defaultValues]: true,\n [SurveyDependencyType.editable]: true,\n [SurveyDependencyType.enumeratingItems]: true,\n [SurveyDependencyType.fileName]: true,\n [SurveyDependencyType.formula]: false,\n [SurveyDependencyType.maxCount]: true,\n [SurveyDependencyType.minCount]: true,\n [SurveyDependencyType.onUpdate]: true,\n [SurveyDependencyType.parentCode]: false,\n [SurveyDependencyType.required]: true,\n [SurveyDependencyType.validations]: true,\n [SurveyDependencyType.visible]: true,\n}\n\nconst selfReferenceAllowedByDependencyType = {\n [SurveyDependencyType.applicable]: false,\n [SurveyDependencyType.defaultValues]: false,\n [SurveyDependencyType.editable]: false,\n [SurveyDependencyType.enumeratingItems]: false,\n [SurveyDependencyType.fileName]: false,\n [SurveyDependencyType.formula]: false,\n [SurveyDependencyType.maxCount]: false,\n [SurveyDependencyType.minCount]: false,\n [SurveyDependencyType.onUpdate]: false,\n [SurveyDependencyType.parentCode]: false,\n [SurveyDependencyType.required]: false,\n [SurveyDependencyType.validations]: true,\n [SurveyDependencyType.visible]: false,\n}\n\nconst newDependencyGraph = () => ({\n [SurveyDependencyType.applicable]: {},\n [SurveyDependencyType.defaultValues]: {},\n [SurveyDependencyType.editable]: {},\n [SurveyDependencyType.enumeratingItems]: {},\n [SurveyDependencyType.fileName]: {},\n [SurveyDependencyType.formula]: {},\n [SurveyDependencyType.maxCount]: {},\n [SurveyDependencyType.minCount]: {},\n [SurveyDependencyType.onUpdate]: {},\n [SurveyDependencyType.parentCode]: {},\n [SurveyDependencyType.required]: {},\n [SurveyDependencyType.validations]: {},\n [SurveyDependencyType.visible]: {},\n})\n\nconst getDependencyGraph = (survey: Survey): SurveyDependencyGraph => survey.dependencyGraph ?? newDependencyGraph()\n\nconst getDependencies = (params: {\n graphs: SurveyDependencyGraph\n type: SurveyDependencyType\n nodeDefUuid: string\n}): Array<string> => {\n const { graphs, type, nodeDefUuid } = params\n return type === SurveyDependencyType.onUpdate ? [] : ((graphs?.[type]?.[nodeDefUuid] ?? []) as string[])\n}\n\nexport const getNodeDefDependents = (params: {\n survey: Survey\n nodeDefUuid: string\n dependencyType?: SurveyDependencyType\n}): NodeDef<NodeDefType, NodeDefProps>[] => {\n const { survey, nodeDefUuid, dependencyType } = params\n const dependencyGraph = getDependencyGraph(survey)\n\n const dependentUuids = new Set<string>()\n\n const dependencyTypes: SurveyDependencyType[] = dependencyType\n ? [dependencyType]\n : Object.values(SurveyDependencyType)\n\n for (const depType of dependencyTypes) {\n const dependentUuidsTemp = getDependencies({ graphs: dependencyGraph, type: depType, nodeDefUuid })\n for (const dependentUuid of dependentUuidsTemp) {\n dependentUuids.add(dependentUuid)\n }\n }\n return dependentUuids.size > 0 ? SurveyNodeDefs.findNodeDefsByUuids({ survey, uuids: [...dependentUuids] }) : []\n}\n\nexport const getOnUpdateDependents = (params: { survey: Survey }) => {\n const { survey } = params\n const dependencyGraph = getDependencyGraph(survey)\n const sourceDefUuids = Object.keys(dependencyGraph[SurveyDependencyType.onUpdate] ?? {})\n return sourceDefUuids.length > 0 ? SurveyNodeDefs.findNodeDefsByUuids({ survey, uuids: sourceDefUuids }) : []\n}\n\n// UPDATE\n\nconst addDependency = (params: {\n graphs: SurveyDependencyGraph\n type: SurveyDependencyType\n nodeDefUuid: string\n nodeDefDepUuid: string\n sideEffect: boolean\n}): SurveyDependencyGraph => {\n const { graphs, type, nodeDefUuid, nodeDefDepUuid, sideEffect = false } = params\n const deps = getDependencies({ graphs, type, nodeDefUuid })\n const depsUpdated = Arrays.addItem(nodeDefDepUuid, { sideEffect })(deps)\n return Objects.assocPath({ obj: graphs, path: [type, nodeDefUuid], value: depsUpdated, sideEffect })\n}\n\nconst addDependencies = async (params: {\n survey: Survey\n nodeDef: NodeDef<NodeDefType>\n type: SurveyDependencyType\n graphs: SurveyDependencyGraph\n expressions: NodeDefExpression[]\n sideEffect?: boolean\n}): Promise<SurveyDependencyGraph> => {\n const { survey, nodeDef, type, expressions, graphs: graphsParam, sideEffect = false } = params\n\n if (!expressions || expressions.length === 0) return graphsParam\n\n let graphsUpdated = sideEffect ? graphsParam : { ...graphsParam }\n\n const isContextParent = isContextParentByDependencyType[type]\n const selfReferenceAllowed = selfReferenceAllowedByDependencyType[type]\n\n const findReferencedNodeDefs = async (\n expression: string | undefined\n ): Promise<{ [key: string]: NodeDef<NodeDefType> }> => {\n if (!expression) return {}\n\n const referencedNodeDefUuids = await new NodeDefExpressionEvaluator().findReferencedNodeDefUuids({\n expression,\n survey,\n nodeDef,\n isContextParent,\n selfReferenceAllowed,\n })\n const referencedNodeDefsByUuid: Dictionary<NodeDef<any>> = {}\n for (const uuid of referencedNodeDefUuids) {\n referencedNodeDefsByUuid[uuid] = SurveyNodeDefs.getNodeDefByUuid({ survey, uuid })\n }\n return referencedNodeDefsByUuid\n }\n\n const referencedNodeDefsArray = await Promise.all(\n expressions.flatMap((nodeDefExpr) => [\n findReferencedNodeDefs(nodeDefExpr.expression),\n findReferencedNodeDefs(nodeDefExpr.applyIf),\n ])\n )\n const referencedNodeDefs: Dictionary<NodeDef<any>> = Object.assign({}, ...referencedNodeDefsArray)\n\n for (const nodeDefRef of Object.values(referencedNodeDefs)) {\n graphsUpdated = addDependency({\n graphs: graphsUpdated,\n type,\n nodeDefUuid: nodeDefRef.uuid,\n nodeDefDepUuid: nodeDef.uuid,\n sideEffect,\n })\n }\n\n return graphsUpdated\n}\n\nexport const addNodeDefDependencies = async (params: {\n nodeDef: NodeDef<NodeDefType>\n survey: Survey\n sideEffect?: boolean\n}): Promise<Survey> => {\n const { nodeDef, survey, sideEffect = false } = params\n const graphs = getDependencyGraph(survey)\n let graphsUpdated = sideEffect ? graphs : { ...graphs }\n\n const _addDependencies = async (type: SurveyDependencyType, expressions: NodeDefExpression[]) => {\n let _graphUpdated = await addDependencies({\n survey,\n nodeDef,\n type,\n expressions,\n graphs: graphsUpdated,\n sideEffect,\n })\n // add onUpdate dependencies\n if (\n expressions.some((expression) =>\n functionsRequiringOnUpdateDependency.some(\n (functionName) => expression.applyIf?.includes(functionName) || expression.expression?.includes(functionName)\n )\n )\n ) {\n _graphUpdated = Objects.assocPath({\n obj: _graphUpdated,\n path: [SurveyDependencyType.onUpdate, nodeDef.uuid],\n value: true,\n sideEffect,\n })\n }\n return _graphUpdated\n }\n graphsUpdated = await _addDependencies(SurveyDependencyType.applicable, NodeDefs.getApplicable(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.defaultValues, NodeDefs.getDefaultValues(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.editable, NodeDefs.getEditableIf(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.required, NodeDefs.getRequiredIf(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.validations, NodeDefs.getValidationsExpressions(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.visible, NodeDefs.getVisibleIf(nodeDef))\n const maxCount = NodeDefs.getMaxCount(nodeDef)\n if (Array.isArray(maxCount)) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.maxCount, maxCount)\n }\n const minCount = NodeDefs.getMinCount(nodeDef)\n if (Array.isArray(minCount)) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.minCount, minCount)\n }\n // file name expression\n if (NodeDefs.getType(nodeDef) === NodeDefType.file) {\n const fileNameExpression = NodeDefs.getFileNameExpression(nodeDef as NodeDefFile)\n if (fileNameExpression) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.fileName, [\n NodeDefExpressionFactory.createInstance({ expression: fileNameExpression }),\n ])\n }\n }\n if (NodeDefs.isEntity(nodeDef)) {\n const enumeratingItemsExpression = NodeDefs.getEnumeratingItemsExpression(nodeDef as NodeDefEntity)\n if (enumeratingItemsExpression) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.enumeratingItems, [\n NodeDefExpressionFactory.createInstance({ expression: enumeratingItemsExpression }),\n ])\n }\n }\n // parent code\n if (NodeDefs.getType(nodeDef) === NodeDefType.code) {\n const parentCodeDefUuid = NodeDefs.getParentCodeDefUuid(nodeDef as NodeDefCode)\n if (parentCodeDefUuid) {\n graphsUpdated = addDependency({\n graphs: graphsUpdated,\n type: SurveyDependencyType.parentCode,\n nodeDefUuid: parentCodeDefUuid,\n nodeDefDepUuid: nodeDef.uuid,\n sideEffect,\n })\n }\n }\n if (sideEffect) {\n survey.dependencyGraph = graphsUpdated\n return survey\n }\n return { ...survey, dependencyGraph: graphsUpdated }\n}\n\n// DELETE\n\nconst _removeNodeDefDependenciesOfType = (params: {\n graphs: SurveyDependencyGraph\n dependencyType: SurveyDependencyType\n nodeDefUuid: string\n}): SurveyDependencyGraph => {\n const { graphs, nodeDefUuid, dependencyType } = params\n\n const graphsUpdated = { ...graphs }\n let graphUpdated = { ...graphsUpdated[dependencyType] }\n // dissoc nodeDefUuid dependency as dependent\n graphUpdated = Objects.dissoc({ obj: graphUpdated, prop: nodeDefUuid })\n\n if (dependencyType !== SurveyDependencyType.onUpdate) {\n // dissoc nodeDefUuid dependency from sources (if any)\n for (const [key, dependentUuids] of Object.entries(graphUpdated)) {\n graphUpdated[key] = Arrays.removeItem(nodeDefUuid)(dependentUuids as string[])\n }\n }\n\n graphsUpdated[dependencyType] = graphUpdated\n return graphsUpdated\n}\n\nexport const removeNodeDefDependencies = (params: {\n survey: Survey\n nodeDefUuid: string\n dependencyType?: SurveyDependencyType\n}): Survey => {\n const { survey, nodeDefUuid, dependencyType = null } = params\n const graphs = getDependencyGraph(survey)\n const dependencyTypes = dependencyType ? [dependencyType] : (Object.keys(graphs) as SurveyDependencyType[])\n const graphsUpdated = dependencyTypes.reduce(\n (dependencyGraphAcc, type) =>\n _removeNodeDefDependenciesOfType({ graphs: dependencyGraphAcc, dependencyType: type, nodeDefUuid }),\n graphs\n )\n return { ...survey, dependencyGraph: graphsUpdated }\n}\n\n/**\n * Builds the dependency graph of the survey.\n *\n * @param survey - The survey.\n * @returns A copy of the survey with the dependency graph (the survey passed in is not modified).\n */\nexport const buildAndAssocDependencyGraph = async (survey: Survey): Promise<Survey> => {\n // the new graph is built from scratch with side effect (to avoid re-creating objects): it belongs only to the copy of the survey\n const sideEffect = true\n\n // add dependencies for every node def\n let surveyUpdated: Survey = { ...survey, dependencyGraph: newDependencyGraph() }\n for (const nodeDef of SurveyNodeDefs.getNodeDefsArray(survey)) {\n // sequential: each iteration updates the survey\n surveyUpdated = await addNodeDefDependencies({ nodeDef, survey: surveyUpdated, sideEffect }) // NOSONAR\n }\n return surveyUpdated\n}\n"]}
1
+ {"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../../../src/survey/surveys/dependencies.ts"],"names":[],"mappings":"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","sourcesContent":["import * as SurveyNodeDefs from './nodeDefs'\nimport {\n NodeDef,\n NodeDefCode,\n NodeDefEntity,\n NodeDefExpression,\n NodeDefFile,\n NodeDefProps,\n NodeDefs,\n NodeDefType,\n} from '../../nodeDef'\nimport { NodeDefExpressionEvaluator } from '../../nodeDefExpressionEvaluator'\n\nimport { Survey, SurveyDependencyGraph, SurveyDependencyType } from '../survey'\nimport { Arrays, Objects } from '../../utils'\nimport { NodeDefExpressionFactory } from '../../nodeDef/nodeDef'\nimport { Dictionary } from '../../common'\n\nconst functionsRequiringOnUpdateDependency = ['recordDateLastModified']\n\nconst isContextParentByDependencyType = {\n [SurveyDependencyType.applicable]: true,\n [SurveyDependencyType.defaultValues]: true,\n [SurveyDependencyType.editable]: true,\n [SurveyDependencyType.enumeratingItems]: true,\n [SurveyDependencyType.fileName]: true,\n [SurveyDependencyType.formula]: false,\n [SurveyDependencyType.maxCount]: true,\n [SurveyDependencyType.minCount]: true,\n [SurveyDependencyType.onUpdate]: true,\n [SurveyDependencyType.parentCode]: false,\n [SurveyDependencyType.required]: true,\n [SurveyDependencyType.validations]: true,\n [SurveyDependencyType.visible]: true,\n}\n\nconst selfReferenceAllowedByDependencyType = {\n [SurveyDependencyType.applicable]: false,\n [SurveyDependencyType.defaultValues]: false,\n [SurveyDependencyType.editable]: false,\n [SurveyDependencyType.enumeratingItems]: false,\n [SurveyDependencyType.fileName]: false,\n [SurveyDependencyType.formula]: false,\n [SurveyDependencyType.maxCount]: false,\n [SurveyDependencyType.minCount]: false,\n [SurveyDependencyType.onUpdate]: false,\n [SurveyDependencyType.parentCode]: false,\n [SurveyDependencyType.required]: false,\n [SurveyDependencyType.validations]: true,\n [SurveyDependencyType.visible]: false,\n}\n\nconst newDependencyGraph = () => ({\n [SurveyDependencyType.applicable]: {},\n [SurveyDependencyType.defaultValues]: {},\n [SurveyDependencyType.editable]: {},\n [SurveyDependencyType.enumeratingItems]: {},\n [SurveyDependencyType.fileName]: {},\n [SurveyDependencyType.formula]: {},\n [SurveyDependencyType.maxCount]: {},\n [SurveyDependencyType.minCount]: {},\n [SurveyDependencyType.onUpdate]: {},\n [SurveyDependencyType.parentCode]: {},\n [SurveyDependencyType.required]: {},\n [SurveyDependencyType.validations]: {},\n [SurveyDependencyType.visible]: {},\n})\n\nconst getDependencyGraph = (survey: Survey): SurveyDependencyGraph => survey.dependencyGraph ?? newDependencyGraph()\n\nconst getDependencies = (params: {\n graphs: SurveyDependencyGraph\n type: SurveyDependencyType\n nodeDefUuid: string\n}): Array<string> => {\n const { graphs, type, nodeDefUuid } = params\n return type === SurveyDependencyType.onUpdate ? [] : ((graphs?.[type]?.[nodeDefUuid] ?? []) as string[])\n}\n\nexport const getNodeDefDependents = (params: {\n survey: Survey\n nodeDefUuid: string\n dependencyType?: SurveyDependencyType\n}): NodeDef<NodeDefType, NodeDefProps>[] => {\n const { survey, nodeDefUuid, dependencyType } = params\n const dependencyGraph = getDependencyGraph(survey)\n\n const dependentUuids = new Set<string>()\n\n const dependencyTypes: SurveyDependencyType[] = dependencyType\n ? [dependencyType]\n : Object.values(SurveyDependencyType)\n\n for (const depType of dependencyTypes) {\n const dependentUuidsTemp = getDependencies({ graphs: dependencyGraph, type: depType, nodeDefUuid })\n for (const dependentUuid of dependentUuidsTemp) {\n dependentUuids.add(dependentUuid)\n }\n }\n return dependentUuids.size > 0 ? SurveyNodeDefs.findNodeDefsByUuids({ survey, uuids: [...dependentUuids] }) : []\n}\n\nexport const getOnUpdateDependents = (params: { survey: Survey }) => {\n const { survey } = params\n const dependencyGraph = getDependencyGraph(survey)\n const sourceDefUuids = Object.keys(dependencyGraph[SurveyDependencyType.onUpdate] ?? {})\n return sourceDefUuids.length > 0 ? SurveyNodeDefs.findNodeDefsByUuids({ survey, uuids: sourceDefUuids }) : []\n}\n\n// UPDATE\n\nconst addDependency = (params: {\n graphs: SurveyDependencyGraph\n type: SurveyDependencyType\n nodeDefUuid: string\n nodeDefDepUuid: string\n sideEffect: boolean\n}): SurveyDependencyGraph => {\n const { graphs, type, nodeDefUuid, nodeDefDepUuid, sideEffect = false } = params\n const deps = getDependencies({ graphs, type, nodeDefUuid })\n // dependencies of a node def can be added again (e.g. when it is updated): keep each dependent only once\n if (deps.includes(nodeDefDepUuid)) return graphs\n const depsUpdated = Arrays.addItem(nodeDefDepUuid, { sideEffect })(deps)\n return Objects.assocPath({ obj: graphs, path: [type, nodeDefUuid], value: depsUpdated, sideEffect })\n}\n\nconst addDependencies = async (params: {\n survey: Survey\n nodeDef: NodeDef<NodeDefType>\n type: SurveyDependencyType\n graphs: SurveyDependencyGraph\n expressions: NodeDefExpression[]\n sideEffect?: boolean\n}): Promise<SurveyDependencyGraph> => {\n const { survey, nodeDef, type, expressions, graphs: graphsParam, sideEffect = false } = params\n\n if (!expressions || expressions.length === 0) return graphsParam\n\n let graphsUpdated = sideEffect ? graphsParam : { ...graphsParam }\n\n const isContextParent = isContextParentByDependencyType[type]\n const selfReferenceAllowed = selfReferenceAllowedByDependencyType[type]\n\n const findReferencedNodeDefs = async (\n expression: string | undefined\n ): Promise<{ [key: string]: NodeDef<NodeDefType> }> => {\n if (!expression) return {}\n\n const referencedNodeDefUuids = await new NodeDefExpressionEvaluator().findReferencedNodeDefUuids({\n expression,\n survey,\n nodeDef,\n isContextParent,\n selfReferenceAllowed,\n })\n const referencedNodeDefsByUuid: Dictionary<NodeDef<any>> = {}\n for (const uuid of referencedNodeDefUuids) {\n referencedNodeDefsByUuid[uuid] = SurveyNodeDefs.getNodeDefByUuid({ survey, uuid })\n }\n return referencedNodeDefsByUuid\n }\n\n const referencedNodeDefsArray = await Promise.all(\n expressions.flatMap((nodeDefExpr) => [\n findReferencedNodeDefs(nodeDefExpr.expression),\n findReferencedNodeDefs(nodeDefExpr.applyIf),\n ])\n )\n const referencedNodeDefs: Dictionary<NodeDef<any>> = Object.assign({}, ...referencedNodeDefsArray)\n\n for (const nodeDefRef of Object.values(referencedNodeDefs)) {\n graphsUpdated = addDependency({\n graphs: graphsUpdated,\n type,\n nodeDefUuid: nodeDefRef.uuid,\n nodeDefDepUuid: nodeDef.uuid,\n sideEffect,\n })\n }\n\n return graphsUpdated\n}\n\nexport const addNodeDefDependencies = async (params: {\n nodeDef: NodeDef<NodeDefType>\n survey: Survey\n sideEffect?: boolean\n}): Promise<Survey> => {\n const { nodeDef, survey, sideEffect = false } = params\n const graphs = getDependencyGraph(survey)\n let graphsUpdated = sideEffect ? graphs : { ...graphs }\n\n const _addDependencies = async (type: SurveyDependencyType, expressions: NodeDefExpression[]) => {\n let _graphUpdated = await addDependencies({\n survey,\n nodeDef,\n type,\n expressions,\n graphs: graphsUpdated,\n sideEffect,\n })\n // add onUpdate dependencies\n if (\n expressions.some((expression) =>\n functionsRequiringOnUpdateDependency.some(\n (functionName) => expression.applyIf?.includes(functionName) || expression.expression?.includes(functionName)\n )\n )\n ) {\n _graphUpdated = Objects.assocPath({\n obj: _graphUpdated,\n path: [SurveyDependencyType.onUpdate, nodeDef.uuid],\n value: true,\n sideEffect,\n })\n }\n return _graphUpdated\n }\n graphsUpdated = await _addDependencies(SurveyDependencyType.applicable, NodeDefs.getApplicable(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.defaultValues, NodeDefs.getDefaultValues(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.editable, NodeDefs.getEditableIf(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.required, NodeDefs.getRequiredIf(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.validations, NodeDefs.getValidationsExpressions(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.visible, NodeDefs.getVisibleIf(nodeDef))\n const maxCount = NodeDefs.getMaxCount(nodeDef)\n if (Array.isArray(maxCount)) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.maxCount, maxCount)\n }\n const minCount = NodeDefs.getMinCount(nodeDef)\n if (Array.isArray(minCount)) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.minCount, minCount)\n }\n // file name expression\n if (NodeDefs.getType(nodeDef) === NodeDefType.file) {\n const fileNameExpression = NodeDefs.getFileNameExpression(nodeDef as NodeDefFile)\n if (fileNameExpression) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.fileName, [\n NodeDefExpressionFactory.createInstance({ expression: fileNameExpression }),\n ])\n }\n }\n if (NodeDefs.isEntity(nodeDef)) {\n const enumeratingItemsExpression = NodeDefs.getEnumeratingItemsExpression(nodeDef as NodeDefEntity)\n if (enumeratingItemsExpression) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.enumeratingItems, [\n NodeDefExpressionFactory.createInstance({ expression: enumeratingItemsExpression }),\n ])\n }\n }\n // parent code\n if (NodeDefs.getType(nodeDef) === NodeDefType.code) {\n const parentCodeDefUuid = NodeDefs.getParentCodeDefUuid(nodeDef as NodeDefCode)\n if (parentCodeDefUuid) {\n graphsUpdated = addDependency({\n graphs: graphsUpdated,\n type: SurveyDependencyType.parentCode,\n nodeDefUuid: parentCodeDefUuid,\n nodeDefDepUuid: nodeDef.uuid,\n sideEffect,\n })\n }\n }\n if (sideEffect) {\n survey.dependencyGraph = graphsUpdated\n return survey\n }\n return { ...survey, dependencyGraph: graphsUpdated }\n}\n\n// DELETE\n\nconst _removeNodeDefDependenciesOfType = (params: {\n graphs: SurveyDependencyGraph\n dependencyType: SurveyDependencyType\n nodeDefUuid: string\n}): SurveyDependencyGraph => {\n const { graphs, nodeDefUuid, dependencyType } = params\n\n const graphsUpdated = { ...graphs }\n let graphUpdated = { ...graphsUpdated[dependencyType] }\n // dissoc nodeDefUuid dependency as dependent\n graphUpdated = Objects.dissoc({ obj: graphUpdated, prop: nodeDefUuid })\n\n if (dependencyType !== SurveyDependencyType.onUpdate) {\n // dissoc nodeDefUuid dependency from sources (if any)\n for (const [key, dependentUuids] of Object.entries(graphUpdated)) {\n graphUpdated[key] = Arrays.removeItem(nodeDefUuid)(dependentUuids as string[])\n }\n }\n\n graphsUpdated[dependencyType] = graphUpdated\n return graphsUpdated\n}\n\nexport const removeNodeDefDependencies = (params: {\n survey: Survey\n nodeDefUuid: string\n dependencyType?: SurveyDependencyType\n}): Survey => {\n const { survey, nodeDefUuid, dependencyType = null } = params\n const graphs = getDependencyGraph(survey)\n const dependencyTypes = dependencyType ? [dependencyType] : (Object.keys(graphs) as SurveyDependencyType[])\n const graphsUpdated = dependencyTypes.reduce(\n (dependencyGraphAcc, type) =>\n _removeNodeDefDependenciesOfType({ graphs: dependencyGraphAcc, dependencyType: type, nodeDefUuid }),\n graphs\n )\n return { ...survey, dependencyGraph: graphsUpdated }\n}\n\n/**\n * Builds the dependency graph of the survey.\n *\n * @param survey - The survey.\n * @returns A copy of the survey with the dependency graph (the survey passed in is not modified).\n */\nexport const buildAndAssocDependencyGraph = async (survey: Survey): Promise<Survey> => {\n // the new graph is built from scratch with side effect (to avoid re-creating objects): it belongs only to the copy of the survey\n const sideEffect = true\n\n // add dependencies for every node def\n let surveyUpdated: Survey = { ...survey, dependencyGraph: newDependencyGraph() }\n for (const nodeDef of SurveyNodeDefs.getNodeDefsArray(survey)) {\n // sequential: each iteration updates the survey\n surveyUpdated = await addNodeDefDependencies({ nodeDef, survey: surveyUpdated, sideEffect }) // NOSONAR\n }\n return surveyUpdated\n}\n"]}
@@ -151,7 +151,8 @@ class JobBase {
151
151
  return;
152
152
  this.cancelRequested = true;
153
153
  const currentInnerJob = this.getCurrentInnerJob();
154
- if (currentInnerJob === null || currentInnerJob === void 0 ? void 0 : currentInnerJob.isRunning()) {
154
+ if (currentInnerJob && !currentInnerJob.isEnded()) {
155
+ // inner job running or about to start (pending):
155
156
  // the parent job status will be set to canceled when handling the canceled event of the inner job
156
157
  yield currentInnerJob.cancel({ canceledByAdmin });
157
158
  return;
@@ -184,6 +185,9 @@ class JobBase {
184
185
  start() {
185
186
  return __awaiter(this, arguments, void 0, function* (client = null) {
186
187
  var _a;
188
+ // canceled before being started: nothing to execute
189
+ if (this.cancelRequested || this.isEnded())
190
+ return;
187
191
  this.logDebug('start');
188
192
  try {
189
193
  if (client) {
@@ -216,6 +220,9 @@ class JobBase {
216
220
  executeInTransaction() {
217
221
  return __awaiter(this, void 0, void 0, function* () {
218
222
  try {
223
+ // canceled while the transaction was being opened: it must not be set as running again
224
+ if (this.cancelRequested)
225
+ return;
219
226
  yield this.onStart();
220
227
  const shouldExecute = yield this.shouldExecute();
221
228
  if (shouldExecute) {
@@ -271,6 +278,9 @@ class JobBase {
271
278
  return __awaiter(this, void 0, void 0, function* () {
272
279
  this.logDebug(`- ${this.total} inner jobs found`);
273
280
  for (let i = 0; i < this.innerJobs.length; i++) {
281
+ // canceled between two inner jobs: the next ones must not be started
282
+ if (this.cancelRequested)
283
+ break;
274
284
  this.logDebug(`- executing inner job ${i + 1}`);
275
285
  this.currentInnerJobIndex = i;
276
286
  const currentInnerJob = this.innerJobs[i];
@@ -304,6 +314,12 @@ class JobBase {
304
314
  break;
305
315
  }
306
316
  }
317
+ if (!this.stopOnInnerJobFailure &&
318
+ !this.cancelRequested &&
319
+ this.innerJobs.some((innerJob) => innerJob.isFailed())) {
320
+ // set only after all inner jobs have run: setting it at the first failure would end this job (onEnd) too early
321
+ yield this.setStatus(status_1.JobStatus.failed);
322
+ }
307
323
  this.logDebug(`- ${this.processed} inner jobs processed successfully`);
308
324
  });
309
325
  }
@@ -362,7 +378,8 @@ class JobBase {
362
378
  if (status === status_1.JobStatus.failed) {
363
379
  // report the errors of the failed inner job in the failed event (and in the errors) of this job
364
380
  Object.assign(this.errors, (_d = (_b = this.getCurrentInnerJob()) === null || _b === void 0 ? void 0 : _b.errors) !== null && _d !== void 0 ? _d : {});
365
- return this.setStatus(status);
381
+ // when not stopping on inner job failures, this job is set as failed after all the inner jobs have run
382
+ return this.stopOnInnerJobFailure ? this.setStatus(status) : undefined;
366
383
  }
367
384
  if (status === status_1.JobStatus.running) {
368
385
  this.notifyEvent({
@@ -1 +1 @@
1
- {"version":3,"file":"JobBase.js","sourceRoot":"","sources":["../../src/job/JobBase.ts"],"names":[],"mappings":"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","sourcesContent":["import { User } from '../auth'\nimport { Dictionary } from '../common'\nimport { SystemError, SystemErrorKeys } from '../error'\nimport { Logger } from '../logger'\nimport { Survey } from '../survey'\nimport { UUIDs } from '../utils'\n\nimport { Job } from './job'\nimport { JobContext } from './jobContext'\nimport { JobEvent, JobEventType } from './jobEvent'\nimport { JobSerialized } from './jobSerialized'\nimport { JobStatus } from './status'\n\nexport interface JobConstructor {\n new <C extends JobContext, R>(context: C, innerJobs?: JobBase<any>[]): JobBase<C, R>\n readonly prototype: JobBase<any, any>\n}\n\n/**\n * Client able to open a transaction (e.g. a pg-promise database): the job runs inside `client.tx(callback)`.\n */\nexport interface JobTxClient {\n tx(callback: (tx: any) => Promise<void>): Promise<unknown>\n}\n\nconst PROGRESS_NOTIFICATION_THROTTLE_MILLIS = 1000\n\n/**\n * Asynchronous task handler.\n *\n * Status workflow:\n * - pending\n * - running\n * - (end)\n * -- succeeded\n * -- failed\n * -- canceled\n *\n * Methods that can be overwritten by subclasses:\n * - shouldExecute (in tx)\n * - onStart (in tx)\n * - execute (in tx)\n * - beforeSuccess (in tx)\n * - generateResult (in tx)\n * - beforeEnd (in tx)\n * - onEnd (out of tx)\n * - getErrorInfo\n */\nexport abstract class JobBase<C extends JobContext, R = undefined> implements Job<R> {\n static readonly keysContext = {\n surveyId: 'surveyId',\n survey: 'survey',\n user: 'user',\n }\n\n readonly uuid: string\n readonly type: string\n status: JobStatus = JobStatus.pending\n startTime?: Date\n endTime?: Date\n total: number\n result: R | undefined = undefined\n errors: Record<string, any> = {}\n canceledByAdmin?: boolean\n\n protected logger: Logger\n protected context: C\n protected innerJobs: JobBase<C, any>[]\n protected currentInnerJobIndex = -1\n\n private _processed = 0\n private eventListener: ((event: JobEvent) => unknown) | undefined = undefined\n private progressThrottleTimeoutId: ReturnType<typeof setTimeout> | undefined = undefined\n private progressThrottleLastRunTime = 0\n private _stopOnInnerJobFailure = true\n // set as soon as cancel() is called (the canceled status is set only after beforeEnd has run)\n private cancelRequested = false\n private beforeEndCalled = false\n // inner job events are handled in sequence; executeJobs waits for them before going on\n private innerJobEventsQueue: Promise<void> = Promise.resolve()\n\n public constructor(context: C, innerJobs: JobBase<C, any>[] = []) {\n this.context = { ...context }\n this.innerJobs = innerJobs\n\n this.uuid = UUIDs.v4()\n this.type = this.context.type ?? this.constructor.name\n this.total = innerJobs.length > 0 ? innerJobs.length : 1\n\n // Created last, so that createLogger() overrides can safely build the logger name out of\n // the job identity (e.g. arena's `Job <ClassName> (<uuid>)` log correlation id).\n this.logger = this.createLogger()\n }\n\n get processed(): number {\n return this._processed\n }\n\n set processed(value: number) {\n this._processed = value\n this.notifyProgress()\n }\n\n get stopOnInnerJobFailure(): boolean {\n return this._stopOnInnerJobFailure\n }\n\n set stopOnInnerJobFailure(value: boolean) {\n this._stopOnInnerJobFailure = value\n }\n\n protected get surveyId(): number | null {\n return this.context.surveyId ?? null\n }\n\n protected get user(): User {\n return this.context.user\n }\n\n protected get userUuid(): string | undefined {\n return this.user?.uuid\n }\n\n protected get contextSurvey(): Survey | undefined {\n return this.context.survey\n }\n\n /**\n * Returns the value of the specified context prop, or the default value (null if not specified) when not set.\n */\n protected getContextProp<K extends keyof C & string>(prop: K, defaultValue?: C[K] | null): C[K] | null\n /** Context prop not declared in the context type: the value is typed by the caller. */\n protected getContextProp<T = any, P extends string = string>(\n prop: P extends keyof C ? never : P,\n defaultValue?: T | null\n ): T | null\n protected getContextProp(prop: string, defaultValue: unknown = null): unknown {\n const value = (this.context as Record<string, unknown>)[prop]\n return value ?? defaultValue\n }\n\n protected setContext(context: Partial<C>): void {\n Object.assign(this.context, context)\n }\n\n protected deleteContextProps(...propNames: string[]): void {\n propNames.forEach((propName) => {\n delete (this.context as any)[propName]\n })\n }\n\n /**\n * Registers the listener notified of job events (status changes and progress).\n * Only one listener can be registered at a time; registering a new one replaces the previous one.\n * Errors thrown (or rejections returned) by the listener are logged and do not affect the job execution.\n */\n onEvent(listener: (event: JobEvent) => unknown): this {\n this.eventListener = listener\n return this\n }\n\n isPending(): boolean {\n return this.status === JobStatus.pending\n }\n\n isRunning(): boolean {\n return this.status === JobStatus.running\n }\n\n isSucceeded(): boolean {\n return this.status === JobStatus.succeeded\n }\n\n isFailed(): boolean {\n return this.status === JobStatus.failed\n }\n\n isCanceled(): boolean {\n return this.status === JobStatus.canceled\n }\n\n isEnded(): boolean {\n return [JobStatus.succeeded, JobStatus.failed, JobStatus.canceled].includes(this.status)\n }\n\n hasErrors(): boolean {\n return Object.keys(this.errors).length > 0\n }\n\n protected getCurrentInnerJob(): JobBase<C, any> | undefined {\n return this.innerJobs[this.currentInnerJobIndex]\n }\n\n protected combineInnerJobsResults(): Record<string, any> {\n const results: Record<string, any> = {}\n this.innerJobs.forEach((innerJob) => Object.assign(results, innerJob.result ?? {}))\n return results\n }\n\n protected combineInnerJobsErrors(): Record<string, any> {\n const errors: Record<string, any> = {}\n this.innerJobs.forEach((innerJob) => Object.assign(errors, innerJob.errors ?? {}))\n return errors\n }\n\n async cancel(options: { canceledByAdmin?: boolean } = {}): Promise<void> {\n const { canceledByAdmin = false } = options\n if (this.isEnded()) return\n\n this.cancelRequested = true\n\n const currentInnerJob = this.getCurrentInnerJob()\n if (currentInnerJob?.isRunning()) {\n // the parent job status will be set to canceled when handling the canceled event of the inner job\n await currentInnerJob.cancel({ canceledByAdmin })\n return\n }\n // no inner job running (job without inner jobs, or between two inner jobs)\n this.canceledByAdmin = canceledByAdmin\n // release the resources (temp files/directories, streams) allocated before the cancellation\n await this.runBeforeEnd()\n await this.setStatus(JobStatus.canceled)\n }\n\n /**\n * Returns true when the job has been canceled (or is no longer running).\n * Long-running subclasses can check it to stop processing items (e.g. in a loop) as soon as the job is canceled.\n */\n protected isCancelRequestedOrNotRunning(): boolean {\n return this.cancelRequested || !this.isRunning()\n }\n\n /**\n * Runs beforeEnd only once (it can be called by cancel() and when the job execution ends).\n */\n private async runBeforeEnd(): Promise<void> {\n if (this.beforeEndCalled) return\n this.beforeEndCalled = true\n await this.beforeEnd()\n }\n\n async start(client: JobTxClient | null = null): Promise<void> {\n this.logDebug('start')\n\n try {\n if (client) {\n await client.tx(async (tx: any) => {\n this.context.tx = tx\n await this.executeInTransaction()\n })\n } else {\n await this.executeInTransaction()\n }\n if (!this.isCancelRequestedOrNotRunning()) {\n await this.setStatus(JobStatus.succeeded)\n }\n } catch (error: any) {\n // a job can fail while still pending (e.g. the transaction cannot be opened, or onStart fails)\n if (!this.cancelRequested && !this.isFailed() && !this.isCanceled()) {\n this.logError(error.stack ?? error)\n const { key, params } = this.getErrorInfo(error)\n this.addError({ error: { valid: false, errors: [{ key, params }] } })\n await this.setStatus(JobStatus.failed)\n }\n } finally {\n this.context.tx = undefined\n }\n }\n\n private async executeInTransaction(): Promise<void> {\n try {\n await this.onStart()\n\n const shouldExecute = await this.shouldExecute()\n if (shouldExecute) {\n if (this.innerJobs.length > 0) {\n await this.executeJobs()\n } else {\n await this.execute()\n }\n if (!this.isCancelRequestedOrNotRunning()) {\n await this.beforeSuccess()\n }\n }\n } finally {\n // runs only if not already run by cancel()\n await this.runBeforeEnd()\n this.context.tx = undefined\n }\n\n if (this.isCancelRequestedOrNotRunning()) {\n this.throwError(SystemErrorKeys.job.canceledOrErrorsFound)\n }\n }\n\n /**\n * Generates a plain JSON-serializable representation of the job, including its inner jobs.\n */\n toJSON(): JobSerialized<R> {\n const { errors, processed, result, status, total, type, userUuid, uuid } = this\n\n return {\n uuid,\n type,\n userUuid,\n surveyId: this.surveyId,\n innerJobs: this.innerJobs.map((job) => job.toJSON()),\n currentInnerJobIndex: this.currentInnerJobIndex,\n\n status,\n pending: this.isPending(),\n running: this.isRunning(),\n succeeded: this.isSucceeded(),\n canceled: this.isCanceled(),\n failed: this.isFailed(),\n ended: this.isEnded(),\n\n total,\n processed,\n progressPercent: this.calculateProgressPercent(),\n elapsedMillis: this.calculateElapsedMillis(),\n\n errors: this.isFailed() ? errors : undefined,\n result: this.isSucceeded() ? result : undefined,\n }\n }\n\n private async executeJobs(): Promise<void> {\n this.logDebug(`- ${this.total} inner jobs found`)\n\n for (let i = 0; i < this.innerJobs.length; i++) {\n this.logDebug(`- executing inner job ${i + 1}`)\n this.currentInnerJobIndex = i\n const currentInnerJob = this.innerJobs[i]\n if (currentInnerJob.context) {\n Object.assign(this.context, currentInnerJob.context)\n }\n currentInnerJob.context = this.context\n currentInnerJob.onEvent((event) => {\n // handle the inner job events in sequence; errors are logged (they would be unhandled rejections otherwise)\n this.innerJobEventsQueue = this.innerJobEventsQueue\n .then(() => this.onInnerJobEvent(event))\n .catch((error) => this.logError(error?.stack ?? error))\n })\n\n // The inner job shares this very context object, and its own start()/executeInTransaction()\n // clear `context.tx` when they terminate: without saving and restoring it here, the first\n // inner job would wipe the parent's transaction handle, leaving every following inner job\n // (and the parent's own beforeSuccess()/beforeEnd()) running outside of the transaction.\n // start() never throws (it swallows/records errors internally), so a plain restore is enough.\n const parentTx = this.context.tx\n await currentInnerJob.start(parentTx)\n this.context.tx = parentTx\n // the inner job events (e.g. canceled, failed) update the status of this job\n await this.innerJobEventsQueue\n\n if (this.cancelRequested || this.isCanceled() || currentInnerJob.isCanceled()) {\n break\n }\n if (currentInnerJob.isSucceeded()) {\n this.incrementProcessedItems()\n } else if (this.stopOnInnerJobFailure) {\n break\n }\n }\n\n this.logDebug(`- ${this.processed} inner jobs processed successfully`)\n }\n\n /**\n * Runs the job's own work when it has no inner jobs. Default implementation is a no-op, so\n * subclasses that only supply inner jobs (and never override this) don't need to. It also means\n * a subclass can safely call `super.execute()` defensively without knowing whether any ancestor\n * overrides it - if this were `abstract` instead, TypeScript would compile away any runtime\n * property for it entirely, so `super.execute()` would throw the moment no ancestor overrides it\n * (confirmed in production: a subclass whose immediate parent didn't override `execute()` crashed\n * with \"(intermediate value).execute is not a function\" the instant it called `super.execute()`).\n */\n protected async execute(): Promise<void> {\n // to be extended by subclasses\n }\n\n /**\n * Determines whether the job should actually run.\n * When it returns false, \"execute\" (or the inner jobs) will be skipped, but the job will still succeed.\n */\n protected shouldExecute(): Promise<boolean> {\n return Promise.resolve(true)\n }\n\n protected incrementProcessedItems(incrementBy = 1): void {\n this.processed += incrementBy\n }\n\n protected async setStatus(status: JobStatus): Promise<void> {\n this.logDebug(`set status: ${status}`)\n this.status = status\n\n const event: JobEvent = { type: JobEventType.statusChange, status, total: this.total, processed: this.processed }\n if (status === JobStatus.failed) {\n event.errors = this.errors\n }\n\n if (this.isEnded()) {\n this.logDebug('onEnd...')\n await this.onEnd()\n this.logDebug(`onEnd run. Job completed in ${this.elapsedTimePrettyFormat}`)\n }\n\n this.notifyEvent(event)\n }\n\n /**\n * Inner job event handler.\n */\n protected async onInnerJobEvent(event: JobEvent): Promise<void> {\n const { status } = event\n if (status === JobStatus.canceled) {\n this.canceledByAdmin = this.getCurrentInnerJob()?.canceledByAdmin ?? false\n return this.setStatus(status)\n }\n if (status === JobStatus.failed) {\n // report the errors of the failed inner job in the failed event (and in the errors) of this job\n Object.assign(this.errors, this.getCurrentInnerJob()?.errors ?? {})\n return this.setStatus(status)\n }\n if (status === JobStatus.running) {\n this.notifyEvent({\n type: JobEventType.progress,\n status: this.status,\n total: this.total,\n processed: this.processed,\n })\n return\n }\n this.logDebug(`Unknown inner job status: ${status}`)\n }\n\n /**\n * Called when the job just has been started.\n */\n protected async onStart(): Promise<void> {\n this.startTime = new Date()\n await this.setStatus(JobStatus.running)\n }\n\n /**\n * Called before beforeEnd only if the status will change to 'success'.\n * Default implementation stores the value returned by generateResult() via setResult().\n * It runs INSIDE the current db transaction.\n */\n protected async beforeSuccess(): Promise<void> {\n this.setResult(await this.generateResult())\n }\n\n /**\n * Computes the value beforeSuccess() will store as this job's result.\n * Default implementation returns whatever is already in `this.result`\n * (e.g. accumulated via earlier setResult() calls during execute()).\n */\n protected generateResult(): Promise<R | undefined> {\n return Promise.resolve(this.result)\n }\n\n /**\n * Updates this job's result. When both the current and incoming values are plain objects,\n * they are merged (Object.assign); otherwise the incoming value replaces the current one.\n * This keeps it safe for subclasses whose result is a primitive (e.g. a plain number) as\n * well as ones that build an object result incrementally across multiple setResult() calls.\n */\n protected setResult(result: R | undefined): void {\n if (result && typeof result === 'object' && this.result && typeof this.result === 'object') {\n Object.assign(this.result, result)\n } else {\n this.result = result\n }\n }\n\n /**\n * Called before onEnd. Useful for flushing resources used by the job before it terminates completely.\n * It runs INSIDE the current db transaction.\n */\n protected beforeEnd(): Promise<void> {\n this.logDebug('Cleanup')\n return Promise.resolve()\n }\n\n /**\n * Called when the job status changes to success, failed or canceled\n * (it runs OUTSIDE of the current db transaction)\n */\n protected onEnd(): Promise<void> {\n this.endTime = new Date()\n this.cancelNotifyProgress()\n return Promise.resolve()\n }\n\n protected addError(error: any, errorKey?: string): void {\n const key = errorKey ?? String(this.processed + 1)\n this.errors[key] = error\n }\n\n protected throwError(errorKey: string, params?: Dictionary<any>): void {\n // SystemError: getErrorInfo will report the translatable key instead of a generic error\n throw new SystemError(errorKey, params)\n }\n\n protected getErrorInfo(error: any): { key: string; params: Record<string, any> } {\n if (error instanceof SystemError) {\n return { key: `appErrors:${error.key}`, params: error.params }\n }\n return { key: 'appErrors:generic', params: { text: error.toString() } }\n }\n\n protected abstract createLogger(): Logger\n\n protected logDebug(...msgs: any[]): void {\n this.logger.debug(...msgs)\n }\n\n protected logInfo(...msgs: any[]): void {\n this.logger.info(...msgs)\n }\n\n protected logWarn(...msgs: any[]): void {\n this.logger.warn(...msgs)\n }\n\n protected logError(...msgs: any[]): void {\n this.logger.error(...msgs)\n }\n\n private get elapsedTimePrettyFormat(): string {\n const elapsedTime = this.calculateElapsedMillis()\n const elapsedMins = Math.floor(elapsedTime / 1000 / 60)\n const elapsedSeconds = String(Math.floor(elapsedTime / 1000) % 60).padStart(2, '0')\n const elapsedMillis = String(elapsedTime % 1000).padStart(3, '0')\n return `${elapsedMins}:${elapsedSeconds}.${elapsedMillis}`\n }\n\n private calculatePartialProgress(): number {\n if (this.isSucceeded()) return 100\n if (this.total > 0) return Math.floor((100 * this.processed) / this.total)\n return 0\n }\n\n private calculateProgressPercent(): number {\n const partialProgress = this.calculatePartialProgress()\n const currentInnerJob = this.getCurrentInnerJob()\n if (\n !currentInnerJob ||\n this.currentInnerJobIndex < 0 ||\n partialProgress === 100 ||\n this.processed > this.currentInnerJobIndex\n ) {\n return partialProgress\n }\n return partialProgress + Math.floor(currentInnerJob.calculateProgressPercent() / this.total)\n }\n\n private calculateElapsedMillis(): number {\n if (!this.startTime) return 0\n return (this.endTime ?? new Date()).getTime() - this.startTime.getTime()\n }\n\n /**\n * Notifies a progress event to the registered listener, throttled so that fast-changing\n * progress does not flood consumers (e.g. web socket clients).\n */\n private notifyProgress(): void {\n const run = (): void => {\n this.progressThrottleTimeoutId = undefined\n this.progressThrottleLastRunTime = Date.now()\n this.notifyEvent({\n type: JobEventType.progress,\n status: this.status,\n total: this.total,\n processed: this.processed,\n })\n }\n\n if (this.progressThrottleTimeoutId) return\n\n const elapsed = Date.now() - this.progressThrottleLastRunTime\n if (!this.progressThrottleLastRunTime || elapsed >= PROGRESS_NOTIFICATION_THROTTLE_MILLIS) {\n run()\n } else {\n this.progressThrottleTimeoutId = setTimeout(run, PROGRESS_NOTIFICATION_THROTTLE_MILLIS - elapsed)\n }\n }\n\n /**\n * Cancels any pending throttled progress notification and resets the throttle state.\n */\n private cancelNotifyProgress(): void {\n if (this.progressThrottleTimeoutId) {\n clearTimeout(this.progressThrottleTimeoutId)\n this.progressThrottleTimeoutId = undefined\n }\n this.progressThrottleLastRunTime = 0\n }\n\n /**\n * Notifies the event to the registered listener.\n * Listener errors are only logged: they would otherwise fail the job or, when thrown inside the progress\n * throttle timeout, crash the process.\n */\n private notifyEvent(event: JobEvent): void {\n const listener = this.eventListener\n if (!listener) return\n try {\n Promise.resolve(listener(event)).catch((error) => this.logListenerError(error))\n } catch (error) {\n this.logListenerError(error)\n }\n }\n\n private logListenerError(error: any): void {\n this.logError(`error in job event listener: ${error?.stack ?? error}`)\n }\n}\n"]}
1
+ {"version":3,"file":"JobBase.js","sourceRoot":"","sources":["../../src/job/JobBase.ts"],"names":[],"mappings":"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","sourcesContent":["import { User } from '../auth'\nimport { Dictionary } from '../common'\nimport { SystemError, SystemErrorKeys } from '../error'\nimport { Logger } from '../logger'\nimport { Survey } from '../survey'\nimport { UUIDs } from '../utils'\n\nimport { Job } from './job'\nimport { JobContext } from './jobContext'\nimport { JobEvent, JobEventType } from './jobEvent'\nimport { JobSerialized } from './jobSerialized'\nimport { JobStatus } from './status'\n\nexport interface JobConstructor {\n new <C extends JobContext, R>(context: C, innerJobs?: JobBase<any>[]): JobBase<C, R>\n readonly prototype: JobBase<any, any>\n}\n\n/**\n * Client able to open a transaction (e.g. a pg-promise database): the job runs inside `client.tx(callback)`.\n */\nexport interface JobTxClient {\n tx(callback: (tx: any) => Promise<void>): Promise<unknown>\n}\n\nconst PROGRESS_NOTIFICATION_THROTTLE_MILLIS = 1000\n\n/**\n * Asynchronous task handler.\n *\n * Status workflow:\n * - pending\n * - running\n * - (end)\n * -- succeeded\n * -- failed\n * -- canceled\n *\n * Methods that can be overwritten by subclasses:\n * - shouldExecute (in tx)\n * - onStart (in tx)\n * - execute (in tx)\n * - beforeSuccess (in tx)\n * - generateResult (in tx)\n * - beforeEnd (in tx)\n * - onEnd (out of tx)\n * - getErrorInfo\n */\nexport abstract class JobBase<C extends JobContext, R = undefined> implements Job<R> {\n static readonly keysContext = {\n surveyId: 'surveyId',\n survey: 'survey',\n user: 'user',\n }\n\n readonly uuid: string\n readonly type: string\n status: JobStatus = JobStatus.pending\n startTime?: Date\n endTime?: Date\n total: number\n result: R | undefined = undefined\n errors: Record<string, any> = {}\n canceledByAdmin?: boolean\n\n protected logger: Logger\n protected context: C\n protected innerJobs: JobBase<C, any>[]\n protected currentInnerJobIndex = -1\n\n private _processed = 0\n private eventListener: ((event: JobEvent) => unknown) | undefined = undefined\n private progressThrottleTimeoutId: ReturnType<typeof setTimeout> | undefined = undefined\n private progressThrottleLastRunTime = 0\n private _stopOnInnerJobFailure = true\n // set as soon as cancel() is called (the canceled status is set only after beforeEnd has run)\n private cancelRequested = false\n private beforeEndCalled = false\n // inner job events are handled in sequence; executeJobs waits for them before going on\n private innerJobEventsQueue: Promise<void> = Promise.resolve()\n\n public constructor(context: C, innerJobs: JobBase<C, any>[] = []) {\n this.context = { ...context }\n this.innerJobs = innerJobs\n\n this.uuid = UUIDs.v4()\n this.type = this.context.type ?? this.constructor.name\n this.total = innerJobs.length > 0 ? innerJobs.length : 1\n\n // Created last, so that createLogger() overrides can safely build the logger name out of\n // the job identity (e.g. arena's `Job <ClassName> (<uuid>)` log correlation id).\n this.logger = this.createLogger()\n }\n\n get processed(): number {\n return this._processed\n }\n\n set processed(value: number) {\n this._processed = value\n this.notifyProgress()\n }\n\n get stopOnInnerJobFailure(): boolean {\n return this._stopOnInnerJobFailure\n }\n\n set stopOnInnerJobFailure(value: boolean) {\n this._stopOnInnerJobFailure = value\n }\n\n protected get surveyId(): number | null {\n return this.context.surveyId ?? null\n }\n\n protected get user(): User {\n return this.context.user\n }\n\n protected get userUuid(): string | undefined {\n return this.user?.uuid\n }\n\n protected get contextSurvey(): Survey | undefined {\n return this.context.survey\n }\n\n /**\n * Returns the value of the specified context prop, or the default value (null if not specified) when not set.\n */\n protected getContextProp<K extends keyof C & string>(prop: K, defaultValue?: C[K] | null): C[K] | null\n /** Context prop not declared in the context type: the value is typed by the caller. */\n protected getContextProp<T = any, P extends string = string>(\n prop: P extends keyof C ? never : P,\n defaultValue?: T | null\n ): T | null\n protected getContextProp(prop: string, defaultValue: unknown = null): unknown {\n const value = (this.context as Record<string, unknown>)[prop]\n return value ?? defaultValue\n }\n\n protected setContext(context: Partial<C>): void {\n Object.assign(this.context, context)\n }\n\n protected deleteContextProps(...propNames: string[]): void {\n propNames.forEach((propName) => {\n delete (this.context as any)[propName]\n })\n }\n\n /**\n * Registers the listener notified of job events (status changes and progress).\n * Only one listener can be registered at a time; registering a new one replaces the previous one.\n * Errors thrown (or rejections returned) by the listener are logged and do not affect the job execution.\n */\n onEvent(listener: (event: JobEvent) => unknown): this {\n this.eventListener = listener\n return this\n }\n\n isPending(): boolean {\n return this.status === JobStatus.pending\n }\n\n isRunning(): boolean {\n return this.status === JobStatus.running\n }\n\n isSucceeded(): boolean {\n return this.status === JobStatus.succeeded\n }\n\n isFailed(): boolean {\n return this.status === JobStatus.failed\n }\n\n isCanceled(): boolean {\n return this.status === JobStatus.canceled\n }\n\n isEnded(): boolean {\n return [JobStatus.succeeded, JobStatus.failed, JobStatus.canceled].includes(this.status)\n }\n\n hasErrors(): boolean {\n return Object.keys(this.errors).length > 0\n }\n\n protected getCurrentInnerJob(): JobBase<C, any> | undefined {\n return this.innerJobs[this.currentInnerJobIndex]\n }\n\n protected combineInnerJobsResults(): Record<string, any> {\n const results: Record<string, any> = {}\n this.innerJobs.forEach((innerJob) => Object.assign(results, innerJob.result ?? {}))\n return results\n }\n\n protected combineInnerJobsErrors(): Record<string, any> {\n const errors: Record<string, any> = {}\n this.innerJobs.forEach((innerJob) => Object.assign(errors, innerJob.errors ?? {}))\n return errors\n }\n\n async cancel(options: { canceledByAdmin?: boolean } = {}): Promise<void> {\n const { canceledByAdmin = false } = options\n if (this.isEnded()) return\n\n this.cancelRequested = true\n\n const currentInnerJob = this.getCurrentInnerJob()\n if (currentInnerJob && !currentInnerJob.isEnded()) {\n // inner job running or about to start (pending):\n // the parent job status will be set to canceled when handling the canceled event of the inner job\n await currentInnerJob.cancel({ canceledByAdmin })\n return\n }\n // no inner job running (job without inner jobs, or between two inner jobs)\n this.canceledByAdmin = canceledByAdmin\n // release the resources (temp files/directories, streams) allocated before the cancellation\n await this.runBeforeEnd()\n await this.setStatus(JobStatus.canceled)\n }\n\n /**\n * Returns true when the job has been canceled (or is no longer running).\n * Long-running subclasses can check it to stop processing items (e.g. in a loop) as soon as the job is canceled.\n */\n protected isCancelRequestedOrNotRunning(): boolean {\n return this.cancelRequested || !this.isRunning()\n }\n\n /**\n * Runs beforeEnd only once (it can be called by cancel() and when the job execution ends).\n */\n private async runBeforeEnd(): Promise<void> {\n if (this.beforeEndCalled) return\n this.beforeEndCalled = true\n await this.beforeEnd()\n }\n\n async start(client: JobTxClient | null = null): Promise<void> {\n // canceled before being started: nothing to execute\n if (this.cancelRequested || this.isEnded()) return\n\n this.logDebug('start')\n\n try {\n if (client) {\n await client.tx(async (tx: any) => {\n this.context.tx = tx\n await this.executeInTransaction()\n })\n } else {\n await this.executeInTransaction()\n }\n if (!this.isCancelRequestedOrNotRunning()) {\n await this.setStatus(JobStatus.succeeded)\n }\n } catch (error: any) {\n // a job can fail while still pending (e.g. the transaction cannot be opened, or onStart fails)\n if (!this.cancelRequested && !this.isFailed() && !this.isCanceled()) {\n this.logError(error.stack ?? error)\n const { key, params } = this.getErrorInfo(error)\n this.addError({ error: { valid: false, errors: [{ key, params }] } })\n await this.setStatus(JobStatus.failed)\n }\n } finally {\n this.context.tx = undefined\n }\n }\n\n private async executeInTransaction(): Promise<void> {\n try {\n // canceled while the transaction was being opened: it must not be set as running again\n if (this.cancelRequested) return\n\n await this.onStart()\n\n const shouldExecute = await this.shouldExecute()\n if (shouldExecute) {\n if (this.innerJobs.length > 0) {\n await this.executeJobs()\n } else {\n await this.execute()\n }\n if (!this.isCancelRequestedOrNotRunning()) {\n await this.beforeSuccess()\n }\n }\n } finally {\n // runs only if not already run by cancel()\n await this.runBeforeEnd()\n this.context.tx = undefined\n }\n\n if (this.isCancelRequestedOrNotRunning()) {\n this.throwError(SystemErrorKeys.job.canceledOrErrorsFound)\n }\n }\n\n /**\n * Generates a plain JSON-serializable representation of the job, including its inner jobs.\n */\n toJSON(): JobSerialized<R> {\n const { errors, processed, result, status, total, type, userUuid, uuid } = this\n\n return {\n uuid,\n type,\n userUuid,\n surveyId: this.surveyId,\n innerJobs: this.innerJobs.map((job) => job.toJSON()),\n currentInnerJobIndex: this.currentInnerJobIndex,\n\n status,\n pending: this.isPending(),\n running: this.isRunning(),\n succeeded: this.isSucceeded(),\n canceled: this.isCanceled(),\n failed: this.isFailed(),\n ended: this.isEnded(),\n\n total,\n processed,\n progressPercent: this.calculateProgressPercent(),\n elapsedMillis: this.calculateElapsedMillis(),\n\n errors: this.isFailed() ? errors : undefined,\n result: this.isSucceeded() ? result : undefined,\n }\n }\n\n private async executeJobs(): Promise<void> {\n this.logDebug(`- ${this.total} inner jobs found`)\n\n for (let i = 0; i < this.innerJobs.length; i++) {\n // canceled between two inner jobs: the next ones must not be started\n if (this.cancelRequested) break\n\n this.logDebug(`- executing inner job ${i + 1}`)\n this.currentInnerJobIndex = i\n const currentInnerJob = this.innerJobs[i]\n if (currentInnerJob.context) {\n Object.assign(this.context, currentInnerJob.context)\n }\n currentInnerJob.context = this.context\n currentInnerJob.onEvent((event) => {\n // handle the inner job events in sequence; errors are logged (they would be unhandled rejections otherwise)\n this.innerJobEventsQueue = this.innerJobEventsQueue\n .then(() => this.onInnerJobEvent(event))\n .catch((error) => this.logError(error?.stack ?? error))\n })\n\n // The inner job shares this very context object, and its own start()/executeInTransaction()\n // clear `context.tx` when they terminate: without saving and restoring it here, the first\n // inner job would wipe the parent's transaction handle, leaving every following inner job\n // (and the parent's own beforeSuccess()/beforeEnd()) running outside of the transaction.\n // start() never throws (it swallows/records errors internally), so a plain restore is enough.\n const parentTx = this.context.tx\n await currentInnerJob.start(parentTx)\n this.context.tx = parentTx\n // the inner job events (e.g. canceled, failed) update the status of this job\n await this.innerJobEventsQueue\n\n if (this.cancelRequested || this.isCanceled() || currentInnerJob.isCanceled()) {\n break\n }\n if (currentInnerJob.isSucceeded()) {\n this.incrementProcessedItems()\n } else if (this.stopOnInnerJobFailure) {\n break\n }\n }\n if (\n !this.stopOnInnerJobFailure &&\n !this.cancelRequested &&\n this.innerJobs.some((innerJob) => innerJob.isFailed())\n ) {\n // set only after all inner jobs have run: setting it at the first failure would end this job (onEnd) too early\n await this.setStatus(JobStatus.failed)\n }\n\n this.logDebug(`- ${this.processed} inner jobs processed successfully`)\n }\n\n /**\n * Runs the job's own work when it has no inner jobs. Default implementation is a no-op, so\n * subclasses that only supply inner jobs (and never override this) don't need to. It also means\n * a subclass can safely call `super.execute()` defensively without knowing whether any ancestor\n * overrides it - if this were `abstract` instead, TypeScript would compile away any runtime\n * property for it entirely, so `super.execute()` would throw the moment no ancestor overrides it\n * (confirmed in production: a subclass whose immediate parent didn't override `execute()` crashed\n * with \"(intermediate value).execute is not a function\" the instant it called `super.execute()`).\n */\n protected async execute(): Promise<void> {\n // to be extended by subclasses\n }\n\n /**\n * Determines whether the job should actually run.\n * When it returns false, \"execute\" (or the inner jobs) will be skipped, but the job will still succeed.\n */\n protected shouldExecute(): Promise<boolean> {\n return Promise.resolve(true)\n }\n\n protected incrementProcessedItems(incrementBy = 1): void {\n this.processed += incrementBy\n }\n\n protected async setStatus(status: JobStatus): Promise<void> {\n this.logDebug(`set status: ${status}`)\n this.status = status\n\n const event: JobEvent = { type: JobEventType.statusChange, status, total: this.total, processed: this.processed }\n if (status === JobStatus.failed) {\n event.errors = this.errors\n }\n\n if (this.isEnded()) {\n this.logDebug('onEnd...')\n await this.onEnd()\n this.logDebug(`onEnd run. Job completed in ${this.elapsedTimePrettyFormat}`)\n }\n\n this.notifyEvent(event)\n }\n\n /**\n * Inner job event handler.\n */\n protected async onInnerJobEvent(event: JobEvent): Promise<void> {\n const { status } = event\n if (status === JobStatus.canceled) {\n this.canceledByAdmin = this.getCurrentInnerJob()?.canceledByAdmin ?? false\n return this.setStatus(status)\n }\n if (status === JobStatus.failed) {\n // report the errors of the failed inner job in the failed event (and in the errors) of this job\n Object.assign(this.errors, this.getCurrentInnerJob()?.errors ?? {})\n // when not stopping on inner job failures, this job is set as failed after all the inner jobs have run\n return this.stopOnInnerJobFailure ? this.setStatus(status) : undefined\n }\n if (status === JobStatus.running) {\n this.notifyEvent({\n type: JobEventType.progress,\n status: this.status,\n total: this.total,\n processed: this.processed,\n })\n return\n }\n this.logDebug(`Unknown inner job status: ${status}`)\n }\n\n /**\n * Called when the job just has been started.\n */\n protected async onStart(): Promise<void> {\n this.startTime = new Date()\n await this.setStatus(JobStatus.running)\n }\n\n /**\n * Called before beforeEnd only if the status will change to 'success'.\n * Default implementation stores the value returned by generateResult() via setResult().\n * It runs INSIDE the current db transaction.\n */\n protected async beforeSuccess(): Promise<void> {\n this.setResult(await this.generateResult())\n }\n\n /**\n * Computes the value beforeSuccess() will store as this job's result.\n * Default implementation returns whatever is already in `this.result`\n * (e.g. accumulated via earlier setResult() calls during execute()).\n */\n protected generateResult(): Promise<R | undefined> {\n return Promise.resolve(this.result)\n }\n\n /**\n * Updates this job's result. When both the current and incoming values are plain objects,\n * they are merged (Object.assign); otherwise the incoming value replaces the current one.\n * This keeps it safe for subclasses whose result is a primitive (e.g. a plain number) as\n * well as ones that build an object result incrementally across multiple setResult() calls.\n */\n protected setResult(result: R | undefined): void {\n if (result && typeof result === 'object' && this.result && typeof this.result === 'object') {\n Object.assign(this.result, result)\n } else {\n this.result = result\n }\n }\n\n /**\n * Called before onEnd. Useful for flushing resources used by the job before it terminates completely.\n * It runs INSIDE the current db transaction.\n */\n protected beforeEnd(): Promise<void> {\n this.logDebug('Cleanup')\n return Promise.resolve()\n }\n\n /**\n * Called when the job status changes to success, failed or canceled\n * (it runs OUTSIDE of the current db transaction)\n */\n protected onEnd(): Promise<void> {\n this.endTime = new Date()\n this.cancelNotifyProgress()\n return Promise.resolve()\n }\n\n protected addError(error: any, errorKey?: string): void {\n const key = errorKey ?? String(this.processed + 1)\n this.errors[key] = error\n }\n\n protected throwError(errorKey: string, params?: Dictionary<any>): void {\n // SystemError: getErrorInfo will report the translatable key instead of a generic error\n throw new SystemError(errorKey, params)\n }\n\n protected getErrorInfo(error: any): { key: string; params: Record<string, any> } {\n if (error instanceof SystemError) {\n return { key: `appErrors:${error.key}`, params: error.params }\n }\n return { key: 'appErrors:generic', params: { text: error.toString() } }\n }\n\n protected abstract createLogger(): Logger\n\n protected logDebug(...msgs: any[]): void {\n this.logger.debug(...msgs)\n }\n\n protected logInfo(...msgs: any[]): void {\n this.logger.info(...msgs)\n }\n\n protected logWarn(...msgs: any[]): void {\n this.logger.warn(...msgs)\n }\n\n protected logError(...msgs: any[]): void {\n this.logger.error(...msgs)\n }\n\n private get elapsedTimePrettyFormat(): string {\n const elapsedTime = this.calculateElapsedMillis()\n const elapsedMins = Math.floor(elapsedTime / 1000 / 60)\n const elapsedSeconds = String(Math.floor(elapsedTime / 1000) % 60).padStart(2, '0')\n const elapsedMillis = String(elapsedTime % 1000).padStart(3, '0')\n return `${elapsedMins}:${elapsedSeconds}.${elapsedMillis}`\n }\n\n private calculatePartialProgress(): number {\n if (this.isSucceeded()) return 100\n if (this.total > 0) return Math.floor((100 * this.processed) / this.total)\n return 0\n }\n\n private calculateProgressPercent(): number {\n const partialProgress = this.calculatePartialProgress()\n const currentInnerJob = this.getCurrentInnerJob()\n if (\n !currentInnerJob ||\n this.currentInnerJobIndex < 0 ||\n partialProgress === 100 ||\n this.processed > this.currentInnerJobIndex\n ) {\n return partialProgress\n }\n return partialProgress + Math.floor(currentInnerJob.calculateProgressPercent() / this.total)\n }\n\n private calculateElapsedMillis(): number {\n if (!this.startTime) return 0\n return (this.endTime ?? new Date()).getTime() - this.startTime.getTime()\n }\n\n /**\n * Notifies a progress event to the registered listener, throttled so that fast-changing\n * progress does not flood consumers (e.g. web socket clients).\n */\n private notifyProgress(): void {\n const run = (): void => {\n this.progressThrottleTimeoutId = undefined\n this.progressThrottleLastRunTime = Date.now()\n this.notifyEvent({\n type: JobEventType.progress,\n status: this.status,\n total: this.total,\n processed: this.processed,\n })\n }\n\n if (this.progressThrottleTimeoutId) return\n\n const elapsed = Date.now() - this.progressThrottleLastRunTime\n if (!this.progressThrottleLastRunTime || elapsed >= PROGRESS_NOTIFICATION_THROTTLE_MILLIS) {\n run()\n } else {\n this.progressThrottleTimeoutId = setTimeout(run, PROGRESS_NOTIFICATION_THROTTLE_MILLIS - elapsed)\n }\n }\n\n /**\n * Cancels any pending throttled progress notification and resets the throttle state.\n */\n private cancelNotifyProgress(): void {\n if (this.progressThrottleTimeoutId) {\n clearTimeout(this.progressThrottleTimeoutId)\n this.progressThrottleTimeoutId = undefined\n }\n this.progressThrottleLastRunTime = 0\n }\n\n /**\n * Notifies the event to the registered listener.\n * Listener errors are only logged: they would otherwise fail the job or, when thrown inside the progress\n * throttle timeout, crash the process.\n */\n private notifyEvent(event: JobEvent): void {\n const listener = this.eventListener\n if (!listener) return\n try {\n Promise.resolve(listener(event)).catch((error) => this.logListenerError(error))\n } catch (error) {\n this.logListenerError(error)\n }\n }\n\n private logListenerError(error: any): void {\n this.logError(`error in job event listener: ${error?.stack ?? error}`)\n }\n}\n"]}
@@ -90,7 +90,7 @@ const fixNodeDefs = (params) => {
90
90
  if (fixedNodeDef) {
91
91
  updatedNodeDefs[nodeDef.uuid] = fixedNodeDef;
92
92
  }
93
- nodeDefsResult[nodeDef.uuid] = fixedNodeDef !== null && fixedNodeDef !== void 0 ? fixedNodeDef : nodeDef;
93
+ nodeDefsResult[nodeDef.uuid] = fixedNodeDef !== null && fixedNodeDef !== void 0 ? fixedNodeDef : nodeDefToFix;
94
94
  }
95
95
  }
96
96
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"nodeDefsFixer.js","sourceRoot":"","sources":["../../src/survey/nodeDefsFixer.ts"],"names":[],"mappings":"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","sourcesContent":["import { SystemError, SystemErrorKeys } from '../error'\nimport { NodeDef, NodeDefEntity, NodeDefMap, NodeDefs } from '../nodeDef'\nimport { NodeDefEntityLayoutChildItem } from '../nodeDef/types/entity'\nimport { Objects } from '../utils'\nimport { MutationOptions } from '../utils/mutationOptions'\n\ntype NodeDefsFixParams = MutationOptions & {\n nodeDefs: NodeDefMap\n cycles: string[]\n}\n\ntype NodeDefsInCycleFixParams = NodeDefsFixParams & {\n cycle: string\n}\n\ntype NodeDefFixParams = NodeDefsInCycleFixParams & {\n nodeDef: NodeDef<any>\n}\n\ntype LayoutPropFixParams = NodeDefFixParams & {\n propName: string\n}\n\ntype LayoutPropFixerFnParams = LayoutPropFixParams & { propOld: any }\n\nconst calculateNodeDefHierarchy = (params: { nodeDef: NodeDef<any>; nodeDefs: NodeDefMap }): string[] => {\n const { nodeDef, nodeDefs } = params\n const hierarchy = []\n const visitedNodeDefUuids = new Set<string>()\n let currentParentUuid = nodeDef.parentUuid\n while (currentParentUuid) {\n if (visitedNodeDefUuids.has(currentParentUuid)) {\n throw new SystemError(SystemErrorKeys.nodeDef.hierarchyCircularDependency, {\n nodeDefName: nodeDef.props?.name,\n nodeDefUuid: nodeDef.uuid,\n parentUuid: currentParentUuid,\n })\n }\n visitedNodeDefUuids.add(currentParentUuid)\n hierarchy.unshift(currentParentUuid)\n const currentParentNode = nodeDefs[currentParentUuid]\n if (!currentParentNode) {\n throw new SystemError(SystemErrorKeys.nodeDef.parentNotFound, {\n nodeDefName: nodeDef.props?.name,\n nodeDefUuid: nodeDef.uuid,\n parentUuid: currentParentUuid,\n })\n }\n currentParentUuid = currentParentNode.parentUuid\n }\n return hierarchy\n}\n\nconst fixHierarchy = (params: NodeDefFixParams): NodeDef<any> | null => {\n const { nodeDefs, nodeDef, sideEffect } = params\n const calculatedHierarchy = calculateNodeDefHierarchy({ nodeDefs, nodeDef })\n // compare the whole hierarchy: a node def moved to another parent at the same depth has a hierarchy with the same length\n return Objects.isEqual(calculatedHierarchy, NodeDefs.getMetaHierarchy(nodeDef))\n ? null\n : Objects.assocPath({ obj: nodeDef, path: ['meta', 'h'], value: calculatedHierarchy, sideEffect })\n}\n\nconst fixLayoutProp = (\n params: LayoutPropFixParams & { fixerFn: (params: LayoutPropFixerFnParams) => any }\n): NodeDef<any> | null => {\n const { cycle, nodeDef, propName, sideEffect, fixerFn } = params\n\n const propPath = ['props', 'layout', cycle, propName]\n\n const propOld = Objects.path(propPath)(nodeDef)\n\n if (Objects.isEmpty(propOld)) return null\n\n const propFixed = fixerFn({ ...params, propOld })\n\n if (Objects.isEqual(propOld, propFixed)) return null\n\n return Objects.assocPath({\n obj: nodeDef,\n path: propPath,\n value: propFixed,\n sideEffect,\n })\n}\n\nconst fixIndexChildren = (params: NodeDefFixParams): NodeDef<any> | null =>\n fixLayoutProp({\n ...params,\n propName: 'indexChildren',\n fixerFn: ({ nodeDefs, cycle, propOld: indexChildren }) =>\n (indexChildren as string[]).filter((childDefUuid) => {\n const childDef = nodeDefs[childDefUuid]\n return (\n childDef?.parentUuid === params.nodeDef.uuid &&\n NodeDefs.isEntity(childDef) &&\n NodeDefs.isDisplayInOwnPage(cycle)(childDef as NodeDefEntity)\n )\n }),\n })\n\nconst fixLayoutChildren = (params: NodeDefFixParams): NodeDef<any> | null =>\n fixLayoutProp({\n ...params,\n propName: 'layoutChildren',\n fixerFn: ({ nodeDefs, cycle, propOld: layoutChildren }) =>\n (layoutChildren as NodeDefEntityLayoutChildItem[]).filter((item) => {\n const childDefUuid = typeof item === 'string' ? item : item.i\n const childDef = nodeDefs[childDefUuid]\n return (\n childDef?.parentUuid === params.nodeDef.uuid &&\n (!NodeDefs.isEntity(childDef) || !NodeDefs.isDisplayInOwnPage(cycle)(childDef as NodeDefEntity))\n )\n }),\n })\n\nconst fix = (params: NodeDefFixParams): NodeDef<any> | null => {\n const { nodeDef } = params\n let nodeDefFixed: NodeDef<any> | null = fixHierarchy(params)\n if (NodeDefs.isEntity(nodeDef)) {\n nodeDefFixed = fixIndexChildren({ ...params, nodeDef: nodeDefFixed ?? nodeDef }) ?? nodeDefFixed\n nodeDefFixed = fixLayoutChildren({ ...params, nodeDef: nodeDefFixed ?? nodeDef }) ?? nodeDefFixed\n }\n return nodeDefFixed\n}\n\nconst fixNodeDefs = (params: NodeDefsFixParams): { nodeDefs: NodeDefMap; updatedNodeDefs: NodeDefMap } => {\n const { nodeDefs, cycles } = params\n const nodeDefsResult: NodeDefMap = {}\n const updatedNodeDefs: NodeDefMap = {}\n\n for (const cycle of cycles) {\n for (const nodeDef of Object.values(nodeDefs)) {\n const nodeDefToFix = nodeDefsResult[nodeDef.uuid] ?? nodeDef\n const fixedNodeDef = fix({ ...params, cycle, nodeDef: nodeDefToFix })\n if (fixedNodeDef) {\n updatedNodeDefs[nodeDef.uuid] = fixedNodeDef\n }\n nodeDefsResult[nodeDef.uuid] = fixedNodeDef ?? nodeDef\n }\n }\n return {\n nodeDefs: nodeDefsResult,\n updatedNodeDefs,\n }\n}\n\nexport const NodeDefsFixer = {\n fixNodeDefs,\n}\n"]}
1
+ {"version":3,"file":"nodeDefsFixer.js","sourceRoot":"","sources":["../../src/survey/nodeDefsFixer.ts"],"names":[],"mappings":"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","sourcesContent":["import { SystemError, SystemErrorKeys } from '../error'\nimport { NodeDef, NodeDefEntity, NodeDefMap, NodeDefs } from '../nodeDef'\nimport { NodeDefEntityLayoutChildItem } from '../nodeDef/types/entity'\nimport { Objects } from '../utils'\nimport { MutationOptions } from '../utils/mutationOptions'\n\ntype NodeDefsFixParams = MutationOptions & {\n nodeDefs: NodeDefMap\n cycles: string[]\n}\n\ntype NodeDefsInCycleFixParams = NodeDefsFixParams & {\n cycle: string\n}\n\ntype NodeDefFixParams = NodeDefsInCycleFixParams & {\n nodeDef: NodeDef<any>\n}\n\ntype LayoutPropFixParams = NodeDefFixParams & {\n propName: string\n}\n\ntype LayoutPropFixerFnParams = LayoutPropFixParams & { propOld: any }\n\nconst calculateNodeDefHierarchy = (params: { nodeDef: NodeDef<any>; nodeDefs: NodeDefMap }): string[] => {\n const { nodeDef, nodeDefs } = params\n const hierarchy = []\n const visitedNodeDefUuids = new Set<string>()\n let currentParentUuid = nodeDef.parentUuid\n while (currentParentUuid) {\n if (visitedNodeDefUuids.has(currentParentUuid)) {\n throw new SystemError(SystemErrorKeys.nodeDef.hierarchyCircularDependency, {\n nodeDefName: nodeDef.props?.name,\n nodeDefUuid: nodeDef.uuid,\n parentUuid: currentParentUuid,\n })\n }\n visitedNodeDefUuids.add(currentParentUuid)\n hierarchy.unshift(currentParentUuid)\n const currentParentNode = nodeDefs[currentParentUuid]\n if (!currentParentNode) {\n throw new SystemError(SystemErrorKeys.nodeDef.parentNotFound, {\n nodeDefName: nodeDef.props?.name,\n nodeDefUuid: nodeDef.uuid,\n parentUuid: currentParentUuid,\n })\n }\n currentParentUuid = currentParentNode.parentUuid\n }\n return hierarchy\n}\n\nconst fixHierarchy = (params: NodeDefFixParams): NodeDef<any> | null => {\n const { nodeDefs, nodeDef, sideEffect } = params\n const calculatedHierarchy = calculateNodeDefHierarchy({ nodeDefs, nodeDef })\n // compare the whole hierarchy: a node def moved to another parent at the same depth has a hierarchy with the same length\n return Objects.isEqual(calculatedHierarchy, NodeDefs.getMetaHierarchy(nodeDef))\n ? null\n : Objects.assocPath({ obj: nodeDef, path: ['meta', 'h'], value: calculatedHierarchy, sideEffect })\n}\n\nconst fixLayoutProp = (\n params: LayoutPropFixParams & { fixerFn: (params: LayoutPropFixerFnParams) => any }\n): NodeDef<any> | null => {\n const { cycle, nodeDef, propName, sideEffect, fixerFn } = params\n\n const propPath = ['props', 'layout', cycle, propName]\n\n const propOld = Objects.path(propPath)(nodeDef)\n\n if (Objects.isEmpty(propOld)) return null\n\n const propFixed = fixerFn({ ...params, propOld })\n\n if (Objects.isEqual(propOld, propFixed)) return null\n\n return Objects.assocPath({\n obj: nodeDef,\n path: propPath,\n value: propFixed,\n sideEffect,\n })\n}\n\nconst fixIndexChildren = (params: NodeDefFixParams): NodeDef<any> | null =>\n fixLayoutProp({\n ...params,\n propName: 'indexChildren',\n fixerFn: ({ nodeDefs, cycle, propOld: indexChildren }) =>\n (indexChildren as string[]).filter((childDefUuid) => {\n const childDef = nodeDefs[childDefUuid]\n return (\n childDef?.parentUuid === params.nodeDef.uuid &&\n NodeDefs.isEntity(childDef) &&\n NodeDefs.isDisplayInOwnPage(cycle)(childDef as NodeDefEntity)\n )\n }),\n })\n\nconst fixLayoutChildren = (params: NodeDefFixParams): NodeDef<any> | null =>\n fixLayoutProp({\n ...params,\n propName: 'layoutChildren',\n fixerFn: ({ nodeDefs, cycle, propOld: layoutChildren }) =>\n (layoutChildren as NodeDefEntityLayoutChildItem[]).filter((item) => {\n const childDefUuid = typeof item === 'string' ? item : item.i\n const childDef = nodeDefs[childDefUuid]\n return (\n childDef?.parentUuid === params.nodeDef.uuid &&\n (!NodeDefs.isEntity(childDef) || !NodeDefs.isDisplayInOwnPage(cycle)(childDef as NodeDefEntity))\n )\n }),\n })\n\nconst fix = (params: NodeDefFixParams): NodeDef<any> | null => {\n const { nodeDef } = params\n let nodeDefFixed: NodeDef<any> | null = fixHierarchy(params)\n if (NodeDefs.isEntity(nodeDef)) {\n nodeDefFixed = fixIndexChildren({ ...params, nodeDef: nodeDefFixed ?? nodeDef }) ?? nodeDefFixed\n nodeDefFixed = fixLayoutChildren({ ...params, nodeDef: nodeDefFixed ?? nodeDef }) ?? nodeDefFixed\n }\n return nodeDefFixed\n}\n\nconst fixNodeDefs = (params: NodeDefsFixParams): { nodeDefs: NodeDefMap; updatedNodeDefs: NodeDefMap } => {\n const { nodeDefs, cycles } = params\n const nodeDefsResult: NodeDefMap = {}\n const updatedNodeDefs: NodeDefMap = {}\n\n for (const cycle of cycles) {\n for (const nodeDef of Object.values(nodeDefs)) {\n const nodeDefToFix = nodeDefsResult[nodeDef.uuid] ?? nodeDef\n const fixedNodeDef = fix({ ...params, cycle, nodeDef: nodeDefToFix })\n if (fixedNodeDef) {\n updatedNodeDefs[nodeDef.uuid] = fixedNodeDef\n }\n nodeDefsResult[nodeDef.uuid] = fixedNodeDef ?? nodeDefToFix\n }\n }\n return {\n nodeDefs: nodeDefsResult,\n updatedNodeDefs,\n }\n}\n\nexport const NodeDefsFixer = {\n fixNodeDefs,\n}\n"]}
@@ -130,6 +130,9 @@ exports.getOnUpdateDependents = getOnUpdateDependents;
130
130
  const addDependency = (params) => {
131
131
  const { graphs, type, nodeDefUuid, nodeDefDepUuid, sideEffect = false } = params;
132
132
  const deps = getDependencies({ graphs, type, nodeDefUuid });
133
+ // dependencies of a node def can be added again (e.g. when it is updated): keep each dependent only once
134
+ if (deps.includes(nodeDefDepUuid))
135
+ return graphs;
133
136
  const depsUpdated = utils_1.Arrays.addItem(nodeDefDepUuid, { sideEffect })(deps);
134
137
  return utils_1.Objects.assocPath({ obj: graphs, path: [type, nodeDefUuid], value: depsUpdated, sideEffect });
135
138
  };
@@ -1 +1 @@
1
- {"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../../src/survey/surveys/dependencies.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,MAAY,cAAc,uCAAkB;AAC5C,2CASsB;AACtB,iFAA6E;AAE7E,sCAA+E;AAC/E,uCAA6C;AAC7C,mDAAgE;AAGhE,MAAM,oCAAoC,GAAG,CAAC,wBAAwB,CAAC,CAAA;AAEvE,MAAM,+BAA+B,GAAG;IACtC,CAAC,6BAAoB,CAAC,UAAU,CAAC,EAAE,IAAI;IACvC,CAAC,6BAAoB,CAAC,aAAa,CAAC,EAAE,IAAI;IAC1C,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,IAAI;IACrC,CAAC,6BAAoB,CAAC,gBAAgB,CAAC,EAAE,IAAI;IAC7C,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,IAAI;IACrC,CAAC,6BAAoB,CAAC,OAAO,CAAC,EAAE,KAAK;IACrC,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,IAAI;IACrC,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,IAAI;IACrC,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,IAAI;IACrC,CAAC,6BAAoB,CAAC,UAAU,CAAC,EAAE,KAAK;IACxC,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,IAAI;IACrC,CAAC,6BAAoB,CAAC,WAAW,CAAC,EAAE,IAAI;IACxC,CAAC,6BAAoB,CAAC,OAAO,CAAC,EAAE,IAAI;CACrC,CAAA;AAED,MAAM,oCAAoC,GAAG;IAC3C,CAAC,6BAAoB,CAAC,UAAU,CAAC,EAAE,KAAK;IACxC,CAAC,6BAAoB,CAAC,aAAa,CAAC,EAAE,KAAK;IAC3C,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,KAAK;IACtC,CAAC,6BAAoB,CAAC,gBAAgB,CAAC,EAAE,KAAK;IAC9C,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,KAAK;IACtC,CAAC,6BAAoB,CAAC,OAAO,CAAC,EAAE,KAAK;IACrC,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,KAAK;IACtC,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,KAAK;IACtC,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,KAAK;IACtC,CAAC,6BAAoB,CAAC,UAAU,CAAC,EAAE,KAAK;IACxC,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,KAAK;IACtC,CAAC,6BAAoB,CAAC,WAAW,CAAC,EAAE,IAAI;IACxC,CAAC,6BAAoB,CAAC,OAAO,CAAC,EAAE,KAAK;CACtC,CAAA;AAED,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,CAAC;IAChC,CAAC,6BAAoB,CAAC,UAAU,CAAC,EAAE,EAAE;IACrC,CAAC,6BAAoB,CAAC,aAAa,CAAC,EAAE,EAAE;IACxC,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,EAAE;IACnC,CAAC,6BAAoB,CAAC,gBAAgB,CAAC,EAAE,EAAE;IAC3C,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,EAAE;IACnC,CAAC,6BAAoB,CAAC,OAAO,CAAC,EAAE,EAAE;IAClC,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,EAAE;IACnC,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,EAAE;IACnC,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,EAAE;IACnC,CAAC,6BAAoB,CAAC,UAAU,CAAC,EAAE,EAAE;IACrC,CAAC,6BAAoB,CAAC,QAAQ,CAAC,EAAE,EAAE;IACnC,CAAC,6BAAoB,CAAC,WAAW,CAAC,EAAE,EAAE;IACtC,CAAC,6BAAoB,CAAC,OAAO,CAAC,EAAE,EAAE;CACnC,CAAC,CAAA;AAEF,MAAM,kBAAkB,GAAG,CAAC,MAAc,EAAyB,EAAE,wBAAC,MAAM,CAAC,eAAe,mCAAI,kBAAkB,EAAE,GAAA,CAAA;AAEpH,MAAM,eAAe,GAAG,CAAC,MAIxB,EAAiB,EAAE;;;IAClB,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,CAAA;IAC5C,OAAO,IAAI,KAAK,6BAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,OAAC,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAG,IAAI,CAAC,0CAAG,WAAW,CAAC,mCAAI,EAAE,CAAc,CAAA;AAC1G,CAAC,CAAA;AAEM,MAAM,oBAAoB,GAAG,CAAC,MAIpC,EAAwC,EAAE;IACzC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,MAAM,CAAA;IACtD,MAAM,eAAe,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAElD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAA;IAExC,MAAM,eAAe,GAA2B,cAAc;QAC5D,CAAC,CAAC,CAAC,cAAc,CAAC;QAClB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,6BAAoB,CAAC,CAAA;IAEvC,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,MAAM,kBAAkB,GAAG,eAAe,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAA;QACnG,KAAK,MAAM,aAAa,IAAI,kBAAkB,EAAE,CAAC;YAC/C,cAAc,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;QACnC,CAAC;IACH,CAAC;IACD,OAAO,cAAc,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AAClH,CAAC,CAAA;AArBY,QAAA,oBAAoB,GAApB,oBAAoB,CAqBhC;AAEM,MAAM,qBAAqB,GAAG,CAAC,MAA0B,EAAE,EAAE;;IAClE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IACzB,MAAM,eAAe,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAClD,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,OAAC,eAAe,CAAC,6BAAoB,CAAC,QAAQ,CAAC,mCAAI,EAAE,CAAC,CAAA;IACxF,OAAO,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AAC/G,CAAC,CAAA;AALY,QAAA,qBAAqB,GAArB,qBAAqB,CAKjC;AAED,SAAS;AAET,MAAM,aAAa,GAAG,CAAC,MAMtB,EAAyB,EAAE;IAC1B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,GAAG,KAAK,EAAE,GAAG,MAAM,CAAA;IAChF,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;IAC3D,MAAM,WAAW,GAAG,cAAM,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA;IACxE,OAAO,eAAO,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAA;AACtG,CAAC,CAAA;AAED,MAAM,eAAe,GAAG,CAAO,MAO9B,EAAkC,EAAE;IACnC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,GAAG,KAAK,EAAE,GAAG,MAAM,CAAA;IAE9F,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,WAAW,CAAA;IAEhE,IAAI,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,mBAAM,WAAW,CAAE,CAAA;IAEjE,MAAM,eAAe,GAAG,+BAA+B,CAAC,IAAI,CAAC,CAAA;IAC7D,MAAM,oBAAoB,GAAG,oCAAoC,CAAC,IAAI,CAAC,CAAA;IAEvE,MAAM,sBAAsB,GAAG,CAC7B,UAA8B,EACoB,EAAE;QACpD,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,CAAA;QAE1B,MAAM,sBAAsB,GAAG,MAAM,IAAI,uDAA0B,EAAE,CAAC,0BAA0B,CAAC;YAC/F,UAAU;YACV,MAAM;YACN,OAAO;YACP,eAAe;YACf,oBAAoB;SACrB,CAAC,CAAA;QACF,MAAM,wBAAwB,GAA6B,EAAE,CAAA;QAC7D,KAAK,MAAM,IAAI,IAAI,sBAAsB,EAAE,CAAC;YAC1C,wBAAwB,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;QACpF,CAAC;QACD,OAAO,wBAAwB,CAAA;IACjC,CAAC,CAAA,CAAA;IAED,MAAM,uBAAuB,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/C,WAAW,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACnC,sBAAsB,CAAC,WAAW,CAAC,UAAU,CAAC;QAC9C,sBAAsB,CAAC,WAAW,CAAC,OAAO,CAAC;KAC5C,CAAC,CACH,CAAA;IACD,MAAM,kBAAkB,GAA6B,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,uBAAuB,CAAC,CAAA;IAElG,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC3D,aAAa,GAAG,aAAa,CAAC;YAC5B,MAAM,EAAE,aAAa;YACrB,IAAI;YACJ,WAAW,EAAE,UAAU,CAAC,IAAI;YAC5B,cAAc,EAAE,OAAO,CAAC,IAAI;YAC5B,UAAU;SACX,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,aAAa,CAAA;AACtB,CAAC,CAAA,CAAA;AAEM,MAAM,sBAAsB,GAAG,CAAO,MAI5C,EAAmB,EAAE;IACpB,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,KAAK,EAAE,GAAG,MAAM,CAAA;IACtD,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;IACzC,IAAI,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,mBAAM,MAAM,CAAE,CAAA;IAEvD,MAAM,gBAAgB,GAAG,CAAO,IAA0B,EAAE,WAAgC,EAAE,EAAE;QAC9F,IAAI,aAAa,GAAG,MAAM,eAAe,CAAC;YACxC,MAAM;YACN,OAAO;YACP,IAAI;YACJ,WAAW;YACX,MAAM,EAAE,aAAa;YACrB,UAAU;SACX,CAAC,CAAA;QACF,4BAA4B;QAC5B,IACE,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAC9B,oCAAoC,CAAC,IAAI,CACvC,CAAC,YAAY,EAAE,EAAE,sBAAC,CAAA,MAAA,UAAU,CAAC,OAAO,0CAAE,QAAQ,CAAC,YAAY,CAAC,MAAI,MAAA,UAAU,CAAC,UAAU,0CAAE,QAAQ,CAAC,YAAY,CAAC,CAAA,GAAA,CAC9G,CACF,EACD,CAAC;YACD,aAAa,GAAG,eAAO,CAAC,SAAS,CAAC;gBAChC,GAAG,EAAE,aAAa;gBAClB,IAAI,EAAE,CAAC,6BAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC;gBACnD,KAAK,EAAE,IAAI;gBACX,UAAU;aACX,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,aAAa,CAAA;IACtB,CAAC,CAAA,CAAA;IACD,aAAa,GAAG,MAAM,gBAAgB,CAAC,6BAAoB,CAAC,UAAU,EAAE,kBAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAA;IACxG,aAAa,GAAG,MAAM,gBAAgB,CAAC,6BAAoB,CAAC,aAAa,EAAE,kBAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAA;IAC9G,aAAa,GAAG,MAAM,gBAAgB,CAAC,6BAAoB,CAAC,QAAQ,EAAE,kBAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAA;IACtG,aAAa,GAAG,MAAM,gBAAgB,CAAC,6BAAoB,CAAC,QAAQ,EAAE,kBAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAA;IACtG,aAAa,GAAG,MAAM,gBAAgB,CAAC,6BAAoB,CAAC,WAAW,EAAE,kBAAQ,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC,CAAA;IACrH,aAAa,GAAG,MAAM,gBAAgB,CAAC,6BAAoB,CAAC,OAAO,EAAE,kBAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAA;IACpG,MAAM,QAAQ,GAAG,kBAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;IAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,aAAa,GAAG,MAAM,gBAAgB,CAAC,6BAAoB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IACjF,CAAC;IACD,MAAM,QAAQ,GAAG,kBAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;IAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,aAAa,GAAG,MAAM,gBAAgB,CAAC,6BAAoB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IACjF,CAAC;IACD,uBAAuB;IACvB,IAAI,kBAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,qBAAW,CAAC,IAAI,EAAE,CAAC;QACnD,MAAM,kBAAkB,GAAG,kBAAQ,CAAC,qBAAqB,CAAC,OAAsB,CAAC,CAAA;QACjF,IAAI,kBAAkB,EAAE,CAAC;YACvB,aAAa,GAAG,MAAM,gBAAgB,CAAC,6BAAoB,CAAC,QAAQ,EAAE;gBACpE,kCAAwB,CAAC,cAAc,CAAC,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC;aAC5E,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IACD,IAAI,kBAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,MAAM,0BAA0B,GAAG,kBAAQ,CAAC,6BAA6B,CAAC,OAAwB,CAAC,CAAA;QACnG,IAAI,0BAA0B,EAAE,CAAC;YAC/B,aAAa,GAAG,MAAM,gBAAgB,CAAC,6BAAoB,CAAC,gBAAgB,EAAE;gBAC5E,kCAAwB,CAAC,cAAc,CAAC,EAAE,UAAU,EAAE,0BAA0B,EAAE,CAAC;aACpF,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IACD,cAAc;IACd,IAAI,kBAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,qBAAW,CAAC,IAAI,EAAE,CAAC;QACnD,MAAM,iBAAiB,GAAG,kBAAQ,CAAC,oBAAoB,CAAC,OAAsB,CAAC,CAAA;QAC/E,IAAI,iBAAiB,EAAE,CAAC;YACtB,aAAa,GAAG,aAAa,CAAC;gBAC5B,MAAM,EAAE,aAAa;gBACrB,IAAI,EAAE,6BAAoB,CAAC,UAAU;gBACrC,WAAW,EAAE,iBAAiB;gBAC9B,cAAc,EAAE,OAAO,CAAC,IAAI;gBAC5B,UAAU;aACX,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IACD,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,CAAC,eAAe,GAAG,aAAa,CAAA;QACtC,OAAO,MAAM,CAAA;IACf,CAAC;IACD,uCAAY,MAAM,KAAE,eAAe,EAAE,aAAa,IAAE;AACtD,CAAC,CAAA,CAAA;AApFY,QAAA,sBAAsB,GAAtB,sBAAsB,CAoFlC;AAED,SAAS;AAET,MAAM,gCAAgC,GAAG,CAAC,MAIzC,EAAyB,EAAE;IAC1B,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,MAAM,CAAA;IAEtD,MAAM,aAAa,qBAAQ,MAAM,CAAE,CAAA;IACnC,IAAI,YAAY,qBAAQ,aAAa,CAAC,cAAc,CAAC,CAAE,CAAA;IACvD,6CAA6C;IAC7C,YAAY,GAAG,eAAO,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;IAEvE,IAAI,cAAc,KAAK,6BAAoB,CAAC,QAAQ,EAAE,CAAC;QACrD,sDAAsD;QACtD,KAAK,MAAM,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YACjE,YAAY,CAAC,GAAG,CAAC,GAAG,cAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,cAA0B,CAAC,CAAA;QAChF,CAAC;IACH,CAAC;IAED,aAAa,CAAC,cAAc,CAAC,GAAG,YAAY,CAAA;IAC5C,OAAO,aAAa,CAAA;AACtB,CAAC,CAAA;AAEM,MAAM,yBAAyB,GAAG,CAAC,MAIzC,EAAU,EAAE;IACX,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,GAAG,IAAI,EAAE,GAAG,MAAM,CAAA;IAC7D,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;IACzC,MAAM,eAAe,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAA4B,CAAA;IAC3G,MAAM,aAAa,GAAG,eAAe,CAAC,MAAM,CAC1C,CAAC,kBAAkB,EAAE,IAAI,EAAE,EAAE,CAC3B,gCAAgC,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EACrG,MAAM,CACP,CAAA;IACD,uCAAY,MAAM,KAAE,eAAe,EAAE,aAAa,IAAE;AACtD,CAAC,CAAA;AAdY,QAAA,yBAAyB,GAAzB,yBAAyB,CAcrC;AAED;;;;;GAKG;AACI,MAAM,4BAA4B,GAAG,CAAO,MAAc,EAAmB,EAAE;IACpF,iIAAiI;IACjI,MAAM,UAAU,GAAG,IAAI,CAAA;IAEvB,sCAAsC;IACtC,IAAI,aAAa,mCAAgB,MAAM,KAAE,eAAe,EAAE,kBAAkB,EAAE,GAAE,CAAA;IAChF,KAAK,MAAM,OAAO,IAAI,cAAc,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9D,gDAAgD;QAChD,aAAa,GAAG,MAAM,IAAA,QAAA,sBAAsB,EAAC,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC,CAAA,CAAC,UAAU;IACzG,CAAC;IACD,OAAO,aAAa,CAAA;AACtB,CAAC,CAAA,CAAA;AAXY,QAAA,4BAA4B,GAA5B,4BAA4B,CAWxC","sourcesContent":["import * as SurveyNodeDefs from './nodeDefs'\nimport {\n NodeDef,\n NodeDefCode,\n NodeDefEntity,\n NodeDefExpression,\n NodeDefFile,\n NodeDefProps,\n NodeDefs,\n NodeDefType,\n} from '../../nodeDef'\nimport { NodeDefExpressionEvaluator } from '../../nodeDefExpressionEvaluator'\n\nimport { Survey, SurveyDependencyGraph, SurveyDependencyType } from '../survey'\nimport { Arrays, Objects } from '../../utils'\nimport { NodeDefExpressionFactory } from '../../nodeDef/nodeDef'\nimport { Dictionary } from '../../common'\n\nconst functionsRequiringOnUpdateDependency = ['recordDateLastModified']\n\nconst isContextParentByDependencyType = {\n [SurveyDependencyType.applicable]: true,\n [SurveyDependencyType.defaultValues]: true,\n [SurveyDependencyType.editable]: true,\n [SurveyDependencyType.enumeratingItems]: true,\n [SurveyDependencyType.fileName]: true,\n [SurveyDependencyType.formula]: false,\n [SurveyDependencyType.maxCount]: true,\n [SurveyDependencyType.minCount]: true,\n [SurveyDependencyType.onUpdate]: true,\n [SurveyDependencyType.parentCode]: false,\n [SurveyDependencyType.required]: true,\n [SurveyDependencyType.validations]: true,\n [SurveyDependencyType.visible]: true,\n}\n\nconst selfReferenceAllowedByDependencyType = {\n [SurveyDependencyType.applicable]: false,\n [SurveyDependencyType.defaultValues]: false,\n [SurveyDependencyType.editable]: false,\n [SurveyDependencyType.enumeratingItems]: false,\n [SurveyDependencyType.fileName]: false,\n [SurveyDependencyType.formula]: false,\n [SurveyDependencyType.maxCount]: false,\n [SurveyDependencyType.minCount]: false,\n [SurveyDependencyType.onUpdate]: false,\n [SurveyDependencyType.parentCode]: false,\n [SurveyDependencyType.required]: false,\n [SurveyDependencyType.validations]: true,\n [SurveyDependencyType.visible]: false,\n}\n\nconst newDependencyGraph = () => ({\n [SurveyDependencyType.applicable]: {},\n [SurveyDependencyType.defaultValues]: {},\n [SurveyDependencyType.editable]: {},\n [SurveyDependencyType.enumeratingItems]: {},\n [SurveyDependencyType.fileName]: {},\n [SurveyDependencyType.formula]: {},\n [SurveyDependencyType.maxCount]: {},\n [SurveyDependencyType.minCount]: {},\n [SurveyDependencyType.onUpdate]: {},\n [SurveyDependencyType.parentCode]: {},\n [SurveyDependencyType.required]: {},\n [SurveyDependencyType.validations]: {},\n [SurveyDependencyType.visible]: {},\n})\n\nconst getDependencyGraph = (survey: Survey): SurveyDependencyGraph => survey.dependencyGraph ?? newDependencyGraph()\n\nconst getDependencies = (params: {\n graphs: SurveyDependencyGraph\n type: SurveyDependencyType\n nodeDefUuid: string\n}): Array<string> => {\n const { graphs, type, nodeDefUuid } = params\n return type === SurveyDependencyType.onUpdate ? [] : ((graphs?.[type]?.[nodeDefUuid] ?? []) as string[])\n}\n\nexport const getNodeDefDependents = (params: {\n survey: Survey\n nodeDefUuid: string\n dependencyType?: SurveyDependencyType\n}): NodeDef<NodeDefType, NodeDefProps>[] => {\n const { survey, nodeDefUuid, dependencyType } = params\n const dependencyGraph = getDependencyGraph(survey)\n\n const dependentUuids = new Set<string>()\n\n const dependencyTypes: SurveyDependencyType[] = dependencyType\n ? [dependencyType]\n : Object.values(SurveyDependencyType)\n\n for (const depType of dependencyTypes) {\n const dependentUuidsTemp = getDependencies({ graphs: dependencyGraph, type: depType, nodeDefUuid })\n for (const dependentUuid of dependentUuidsTemp) {\n dependentUuids.add(dependentUuid)\n }\n }\n return dependentUuids.size > 0 ? SurveyNodeDefs.findNodeDefsByUuids({ survey, uuids: [...dependentUuids] }) : []\n}\n\nexport const getOnUpdateDependents = (params: { survey: Survey }) => {\n const { survey } = params\n const dependencyGraph = getDependencyGraph(survey)\n const sourceDefUuids = Object.keys(dependencyGraph[SurveyDependencyType.onUpdate] ?? {})\n return sourceDefUuids.length > 0 ? SurveyNodeDefs.findNodeDefsByUuids({ survey, uuids: sourceDefUuids }) : []\n}\n\n// UPDATE\n\nconst addDependency = (params: {\n graphs: SurveyDependencyGraph\n type: SurveyDependencyType\n nodeDefUuid: string\n nodeDefDepUuid: string\n sideEffect: boolean\n}): SurveyDependencyGraph => {\n const { graphs, type, nodeDefUuid, nodeDefDepUuid, sideEffect = false } = params\n const deps = getDependencies({ graphs, type, nodeDefUuid })\n const depsUpdated = Arrays.addItem(nodeDefDepUuid, { sideEffect })(deps)\n return Objects.assocPath({ obj: graphs, path: [type, nodeDefUuid], value: depsUpdated, sideEffect })\n}\n\nconst addDependencies = async (params: {\n survey: Survey\n nodeDef: NodeDef<NodeDefType>\n type: SurveyDependencyType\n graphs: SurveyDependencyGraph\n expressions: NodeDefExpression[]\n sideEffect?: boolean\n}): Promise<SurveyDependencyGraph> => {\n const { survey, nodeDef, type, expressions, graphs: graphsParam, sideEffect = false } = params\n\n if (!expressions || expressions.length === 0) return graphsParam\n\n let graphsUpdated = sideEffect ? graphsParam : { ...graphsParam }\n\n const isContextParent = isContextParentByDependencyType[type]\n const selfReferenceAllowed = selfReferenceAllowedByDependencyType[type]\n\n const findReferencedNodeDefs = async (\n expression: string | undefined\n ): Promise<{ [key: string]: NodeDef<NodeDefType> }> => {\n if (!expression) return {}\n\n const referencedNodeDefUuids = await new NodeDefExpressionEvaluator().findReferencedNodeDefUuids({\n expression,\n survey,\n nodeDef,\n isContextParent,\n selfReferenceAllowed,\n })\n const referencedNodeDefsByUuid: Dictionary<NodeDef<any>> = {}\n for (const uuid of referencedNodeDefUuids) {\n referencedNodeDefsByUuid[uuid] = SurveyNodeDefs.getNodeDefByUuid({ survey, uuid })\n }\n return referencedNodeDefsByUuid\n }\n\n const referencedNodeDefsArray = await Promise.all(\n expressions.flatMap((nodeDefExpr) => [\n findReferencedNodeDefs(nodeDefExpr.expression),\n findReferencedNodeDefs(nodeDefExpr.applyIf),\n ])\n )\n const referencedNodeDefs: Dictionary<NodeDef<any>> = Object.assign({}, ...referencedNodeDefsArray)\n\n for (const nodeDefRef of Object.values(referencedNodeDefs)) {\n graphsUpdated = addDependency({\n graphs: graphsUpdated,\n type,\n nodeDefUuid: nodeDefRef.uuid,\n nodeDefDepUuid: nodeDef.uuid,\n sideEffect,\n })\n }\n\n return graphsUpdated\n}\n\nexport const addNodeDefDependencies = async (params: {\n nodeDef: NodeDef<NodeDefType>\n survey: Survey\n sideEffect?: boolean\n}): Promise<Survey> => {\n const { nodeDef, survey, sideEffect = false } = params\n const graphs = getDependencyGraph(survey)\n let graphsUpdated = sideEffect ? graphs : { ...graphs }\n\n const _addDependencies = async (type: SurveyDependencyType, expressions: NodeDefExpression[]) => {\n let _graphUpdated = await addDependencies({\n survey,\n nodeDef,\n type,\n expressions,\n graphs: graphsUpdated,\n sideEffect,\n })\n // add onUpdate dependencies\n if (\n expressions.some((expression) =>\n functionsRequiringOnUpdateDependency.some(\n (functionName) => expression.applyIf?.includes(functionName) || expression.expression?.includes(functionName)\n )\n )\n ) {\n _graphUpdated = Objects.assocPath({\n obj: _graphUpdated,\n path: [SurveyDependencyType.onUpdate, nodeDef.uuid],\n value: true,\n sideEffect,\n })\n }\n return _graphUpdated\n }\n graphsUpdated = await _addDependencies(SurveyDependencyType.applicable, NodeDefs.getApplicable(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.defaultValues, NodeDefs.getDefaultValues(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.editable, NodeDefs.getEditableIf(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.required, NodeDefs.getRequiredIf(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.validations, NodeDefs.getValidationsExpressions(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.visible, NodeDefs.getVisibleIf(nodeDef))\n const maxCount = NodeDefs.getMaxCount(nodeDef)\n if (Array.isArray(maxCount)) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.maxCount, maxCount)\n }\n const minCount = NodeDefs.getMinCount(nodeDef)\n if (Array.isArray(minCount)) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.minCount, minCount)\n }\n // file name expression\n if (NodeDefs.getType(nodeDef) === NodeDefType.file) {\n const fileNameExpression = NodeDefs.getFileNameExpression(nodeDef as NodeDefFile)\n if (fileNameExpression) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.fileName, [\n NodeDefExpressionFactory.createInstance({ expression: fileNameExpression }),\n ])\n }\n }\n if (NodeDefs.isEntity(nodeDef)) {\n const enumeratingItemsExpression = NodeDefs.getEnumeratingItemsExpression(nodeDef as NodeDefEntity)\n if (enumeratingItemsExpression) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.enumeratingItems, [\n NodeDefExpressionFactory.createInstance({ expression: enumeratingItemsExpression }),\n ])\n }\n }\n // parent code\n if (NodeDefs.getType(nodeDef) === NodeDefType.code) {\n const parentCodeDefUuid = NodeDefs.getParentCodeDefUuid(nodeDef as NodeDefCode)\n if (parentCodeDefUuid) {\n graphsUpdated = addDependency({\n graphs: graphsUpdated,\n type: SurveyDependencyType.parentCode,\n nodeDefUuid: parentCodeDefUuid,\n nodeDefDepUuid: nodeDef.uuid,\n sideEffect,\n })\n }\n }\n if (sideEffect) {\n survey.dependencyGraph = graphsUpdated\n return survey\n }\n return { ...survey, dependencyGraph: graphsUpdated }\n}\n\n// DELETE\n\nconst _removeNodeDefDependenciesOfType = (params: {\n graphs: SurveyDependencyGraph\n dependencyType: SurveyDependencyType\n nodeDefUuid: string\n}): SurveyDependencyGraph => {\n const { graphs, nodeDefUuid, dependencyType } = params\n\n const graphsUpdated = { ...graphs }\n let graphUpdated = { ...graphsUpdated[dependencyType] }\n // dissoc nodeDefUuid dependency as dependent\n graphUpdated = Objects.dissoc({ obj: graphUpdated, prop: nodeDefUuid })\n\n if (dependencyType !== SurveyDependencyType.onUpdate) {\n // dissoc nodeDefUuid dependency from sources (if any)\n for (const [key, dependentUuids] of Object.entries(graphUpdated)) {\n graphUpdated[key] = Arrays.removeItem(nodeDefUuid)(dependentUuids as string[])\n }\n }\n\n graphsUpdated[dependencyType] = graphUpdated\n return graphsUpdated\n}\n\nexport const removeNodeDefDependencies = (params: {\n survey: Survey\n nodeDefUuid: string\n dependencyType?: SurveyDependencyType\n}): Survey => {\n const { survey, nodeDefUuid, dependencyType = null } = params\n const graphs = getDependencyGraph(survey)\n const dependencyTypes = dependencyType ? [dependencyType] : (Object.keys(graphs) as SurveyDependencyType[])\n const graphsUpdated = dependencyTypes.reduce(\n (dependencyGraphAcc, type) =>\n _removeNodeDefDependenciesOfType({ graphs: dependencyGraphAcc, dependencyType: type, nodeDefUuid }),\n graphs\n )\n return { ...survey, dependencyGraph: graphsUpdated }\n}\n\n/**\n * Builds the dependency graph of the survey.\n *\n * @param survey - The survey.\n * @returns A copy of the survey with the dependency graph (the survey passed in is not modified).\n */\nexport const buildAndAssocDependencyGraph = async (survey: Survey): Promise<Survey> => {\n // the new graph is built from scratch with side effect (to avoid re-creating objects): it belongs only to the copy of the survey\n const sideEffect = true\n\n // add dependencies for every node def\n let surveyUpdated: Survey = { ...survey, dependencyGraph: newDependencyGraph() }\n for (const nodeDef of SurveyNodeDefs.getNodeDefsArray(survey)) {\n // sequential: each iteration updates the survey\n surveyUpdated = await addNodeDefDependencies({ nodeDef, survey: surveyUpdated, sideEffect }) // NOSONAR\n }\n return surveyUpdated\n}\n"]}
1
+ {"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../../src/survey/surveys/dependencies.ts"],"names":[],"mappings":"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","sourcesContent":["import * as SurveyNodeDefs from './nodeDefs'\nimport {\n NodeDef,\n NodeDefCode,\n NodeDefEntity,\n NodeDefExpression,\n NodeDefFile,\n NodeDefProps,\n NodeDefs,\n NodeDefType,\n} from '../../nodeDef'\nimport { NodeDefExpressionEvaluator } from '../../nodeDefExpressionEvaluator'\n\nimport { Survey, SurveyDependencyGraph, SurveyDependencyType } from '../survey'\nimport { Arrays, Objects } from '../../utils'\nimport { NodeDefExpressionFactory } from '../../nodeDef/nodeDef'\nimport { Dictionary } from '../../common'\n\nconst functionsRequiringOnUpdateDependency = ['recordDateLastModified']\n\nconst isContextParentByDependencyType = {\n [SurveyDependencyType.applicable]: true,\n [SurveyDependencyType.defaultValues]: true,\n [SurveyDependencyType.editable]: true,\n [SurveyDependencyType.enumeratingItems]: true,\n [SurveyDependencyType.fileName]: true,\n [SurveyDependencyType.formula]: false,\n [SurveyDependencyType.maxCount]: true,\n [SurveyDependencyType.minCount]: true,\n [SurveyDependencyType.onUpdate]: true,\n [SurveyDependencyType.parentCode]: false,\n [SurveyDependencyType.required]: true,\n [SurveyDependencyType.validations]: true,\n [SurveyDependencyType.visible]: true,\n}\n\nconst selfReferenceAllowedByDependencyType = {\n [SurveyDependencyType.applicable]: false,\n [SurveyDependencyType.defaultValues]: false,\n [SurveyDependencyType.editable]: false,\n [SurveyDependencyType.enumeratingItems]: false,\n [SurveyDependencyType.fileName]: false,\n [SurveyDependencyType.formula]: false,\n [SurveyDependencyType.maxCount]: false,\n [SurveyDependencyType.minCount]: false,\n [SurveyDependencyType.onUpdate]: false,\n [SurveyDependencyType.parentCode]: false,\n [SurveyDependencyType.required]: false,\n [SurveyDependencyType.validations]: true,\n [SurveyDependencyType.visible]: false,\n}\n\nconst newDependencyGraph = () => ({\n [SurveyDependencyType.applicable]: {},\n [SurveyDependencyType.defaultValues]: {},\n [SurveyDependencyType.editable]: {},\n [SurveyDependencyType.enumeratingItems]: {},\n [SurveyDependencyType.fileName]: {},\n [SurveyDependencyType.formula]: {},\n [SurveyDependencyType.maxCount]: {},\n [SurveyDependencyType.minCount]: {},\n [SurveyDependencyType.onUpdate]: {},\n [SurveyDependencyType.parentCode]: {},\n [SurveyDependencyType.required]: {},\n [SurveyDependencyType.validations]: {},\n [SurveyDependencyType.visible]: {},\n})\n\nconst getDependencyGraph = (survey: Survey): SurveyDependencyGraph => survey.dependencyGraph ?? newDependencyGraph()\n\nconst getDependencies = (params: {\n graphs: SurveyDependencyGraph\n type: SurveyDependencyType\n nodeDefUuid: string\n}): Array<string> => {\n const { graphs, type, nodeDefUuid } = params\n return type === SurveyDependencyType.onUpdate ? [] : ((graphs?.[type]?.[nodeDefUuid] ?? []) as string[])\n}\n\nexport const getNodeDefDependents = (params: {\n survey: Survey\n nodeDefUuid: string\n dependencyType?: SurveyDependencyType\n}): NodeDef<NodeDefType, NodeDefProps>[] => {\n const { survey, nodeDefUuid, dependencyType } = params\n const dependencyGraph = getDependencyGraph(survey)\n\n const dependentUuids = new Set<string>()\n\n const dependencyTypes: SurveyDependencyType[] = dependencyType\n ? [dependencyType]\n : Object.values(SurveyDependencyType)\n\n for (const depType of dependencyTypes) {\n const dependentUuidsTemp = getDependencies({ graphs: dependencyGraph, type: depType, nodeDefUuid })\n for (const dependentUuid of dependentUuidsTemp) {\n dependentUuids.add(dependentUuid)\n }\n }\n return dependentUuids.size > 0 ? SurveyNodeDefs.findNodeDefsByUuids({ survey, uuids: [...dependentUuids] }) : []\n}\n\nexport const getOnUpdateDependents = (params: { survey: Survey }) => {\n const { survey } = params\n const dependencyGraph = getDependencyGraph(survey)\n const sourceDefUuids = Object.keys(dependencyGraph[SurveyDependencyType.onUpdate] ?? {})\n return sourceDefUuids.length > 0 ? SurveyNodeDefs.findNodeDefsByUuids({ survey, uuids: sourceDefUuids }) : []\n}\n\n// UPDATE\n\nconst addDependency = (params: {\n graphs: SurveyDependencyGraph\n type: SurveyDependencyType\n nodeDefUuid: string\n nodeDefDepUuid: string\n sideEffect: boolean\n}): SurveyDependencyGraph => {\n const { graphs, type, nodeDefUuid, nodeDefDepUuid, sideEffect = false } = params\n const deps = getDependencies({ graphs, type, nodeDefUuid })\n // dependencies of a node def can be added again (e.g. when it is updated): keep each dependent only once\n if (deps.includes(nodeDefDepUuid)) return graphs\n const depsUpdated = Arrays.addItem(nodeDefDepUuid, { sideEffect })(deps)\n return Objects.assocPath({ obj: graphs, path: [type, nodeDefUuid], value: depsUpdated, sideEffect })\n}\n\nconst addDependencies = async (params: {\n survey: Survey\n nodeDef: NodeDef<NodeDefType>\n type: SurveyDependencyType\n graphs: SurveyDependencyGraph\n expressions: NodeDefExpression[]\n sideEffect?: boolean\n}): Promise<SurveyDependencyGraph> => {\n const { survey, nodeDef, type, expressions, graphs: graphsParam, sideEffect = false } = params\n\n if (!expressions || expressions.length === 0) return graphsParam\n\n let graphsUpdated = sideEffect ? graphsParam : { ...graphsParam }\n\n const isContextParent = isContextParentByDependencyType[type]\n const selfReferenceAllowed = selfReferenceAllowedByDependencyType[type]\n\n const findReferencedNodeDefs = async (\n expression: string | undefined\n ): Promise<{ [key: string]: NodeDef<NodeDefType> }> => {\n if (!expression) return {}\n\n const referencedNodeDefUuids = await new NodeDefExpressionEvaluator().findReferencedNodeDefUuids({\n expression,\n survey,\n nodeDef,\n isContextParent,\n selfReferenceAllowed,\n })\n const referencedNodeDefsByUuid: Dictionary<NodeDef<any>> = {}\n for (const uuid of referencedNodeDefUuids) {\n referencedNodeDefsByUuid[uuid] = SurveyNodeDefs.getNodeDefByUuid({ survey, uuid })\n }\n return referencedNodeDefsByUuid\n }\n\n const referencedNodeDefsArray = await Promise.all(\n expressions.flatMap((nodeDefExpr) => [\n findReferencedNodeDefs(nodeDefExpr.expression),\n findReferencedNodeDefs(nodeDefExpr.applyIf),\n ])\n )\n const referencedNodeDefs: Dictionary<NodeDef<any>> = Object.assign({}, ...referencedNodeDefsArray)\n\n for (const nodeDefRef of Object.values(referencedNodeDefs)) {\n graphsUpdated = addDependency({\n graphs: graphsUpdated,\n type,\n nodeDefUuid: nodeDefRef.uuid,\n nodeDefDepUuid: nodeDef.uuid,\n sideEffect,\n })\n }\n\n return graphsUpdated\n}\n\nexport const addNodeDefDependencies = async (params: {\n nodeDef: NodeDef<NodeDefType>\n survey: Survey\n sideEffect?: boolean\n}): Promise<Survey> => {\n const { nodeDef, survey, sideEffect = false } = params\n const graphs = getDependencyGraph(survey)\n let graphsUpdated = sideEffect ? graphs : { ...graphs }\n\n const _addDependencies = async (type: SurveyDependencyType, expressions: NodeDefExpression[]) => {\n let _graphUpdated = await addDependencies({\n survey,\n nodeDef,\n type,\n expressions,\n graphs: graphsUpdated,\n sideEffect,\n })\n // add onUpdate dependencies\n if (\n expressions.some((expression) =>\n functionsRequiringOnUpdateDependency.some(\n (functionName) => expression.applyIf?.includes(functionName) || expression.expression?.includes(functionName)\n )\n )\n ) {\n _graphUpdated = Objects.assocPath({\n obj: _graphUpdated,\n path: [SurveyDependencyType.onUpdate, nodeDef.uuid],\n value: true,\n sideEffect,\n })\n }\n return _graphUpdated\n }\n graphsUpdated = await _addDependencies(SurveyDependencyType.applicable, NodeDefs.getApplicable(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.defaultValues, NodeDefs.getDefaultValues(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.editable, NodeDefs.getEditableIf(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.required, NodeDefs.getRequiredIf(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.validations, NodeDefs.getValidationsExpressions(nodeDef))\n graphsUpdated = await _addDependencies(SurveyDependencyType.visible, NodeDefs.getVisibleIf(nodeDef))\n const maxCount = NodeDefs.getMaxCount(nodeDef)\n if (Array.isArray(maxCount)) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.maxCount, maxCount)\n }\n const minCount = NodeDefs.getMinCount(nodeDef)\n if (Array.isArray(minCount)) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.minCount, minCount)\n }\n // file name expression\n if (NodeDefs.getType(nodeDef) === NodeDefType.file) {\n const fileNameExpression = NodeDefs.getFileNameExpression(nodeDef as NodeDefFile)\n if (fileNameExpression) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.fileName, [\n NodeDefExpressionFactory.createInstance({ expression: fileNameExpression }),\n ])\n }\n }\n if (NodeDefs.isEntity(nodeDef)) {\n const enumeratingItemsExpression = NodeDefs.getEnumeratingItemsExpression(nodeDef as NodeDefEntity)\n if (enumeratingItemsExpression) {\n graphsUpdated = await _addDependencies(SurveyDependencyType.enumeratingItems, [\n NodeDefExpressionFactory.createInstance({ expression: enumeratingItemsExpression }),\n ])\n }\n }\n // parent code\n if (NodeDefs.getType(nodeDef) === NodeDefType.code) {\n const parentCodeDefUuid = NodeDefs.getParentCodeDefUuid(nodeDef as NodeDefCode)\n if (parentCodeDefUuid) {\n graphsUpdated = addDependency({\n graphs: graphsUpdated,\n type: SurveyDependencyType.parentCode,\n nodeDefUuid: parentCodeDefUuid,\n nodeDefDepUuid: nodeDef.uuid,\n sideEffect,\n })\n }\n }\n if (sideEffect) {\n survey.dependencyGraph = graphsUpdated\n return survey\n }\n return { ...survey, dependencyGraph: graphsUpdated }\n}\n\n// DELETE\n\nconst _removeNodeDefDependenciesOfType = (params: {\n graphs: SurveyDependencyGraph\n dependencyType: SurveyDependencyType\n nodeDefUuid: string\n}): SurveyDependencyGraph => {\n const { graphs, nodeDefUuid, dependencyType } = params\n\n const graphsUpdated = { ...graphs }\n let graphUpdated = { ...graphsUpdated[dependencyType] }\n // dissoc nodeDefUuid dependency as dependent\n graphUpdated = Objects.dissoc({ obj: graphUpdated, prop: nodeDefUuid })\n\n if (dependencyType !== SurveyDependencyType.onUpdate) {\n // dissoc nodeDefUuid dependency from sources (if any)\n for (const [key, dependentUuids] of Object.entries(graphUpdated)) {\n graphUpdated[key] = Arrays.removeItem(nodeDefUuid)(dependentUuids as string[])\n }\n }\n\n graphsUpdated[dependencyType] = graphUpdated\n return graphsUpdated\n}\n\nexport const removeNodeDefDependencies = (params: {\n survey: Survey\n nodeDefUuid: string\n dependencyType?: SurveyDependencyType\n}): Survey => {\n const { survey, nodeDefUuid, dependencyType = null } = params\n const graphs = getDependencyGraph(survey)\n const dependencyTypes = dependencyType ? [dependencyType] : (Object.keys(graphs) as SurveyDependencyType[])\n const graphsUpdated = dependencyTypes.reduce(\n (dependencyGraphAcc, type) =>\n _removeNodeDefDependenciesOfType({ graphs: dependencyGraphAcc, dependencyType: type, nodeDefUuid }),\n graphs\n )\n return { ...survey, dependencyGraph: graphsUpdated }\n}\n\n/**\n * Builds the dependency graph of the survey.\n *\n * @param survey - The survey.\n * @returns A copy of the survey with the dependency graph (the survey passed in is not modified).\n */\nexport const buildAndAssocDependencyGraph = async (survey: Survey): Promise<Survey> => {\n // the new graph is built from scratch with side effect (to avoid re-creating objects): it belongs only to the copy of the survey\n const sideEffect = true\n\n // add dependencies for every node def\n let surveyUpdated: Survey = { ...survey, dependencyGraph: newDependencyGraph() }\n for (const nodeDef of SurveyNodeDefs.getNodeDefsArray(survey)) {\n // sequential: each iteration updates the survey\n surveyUpdated = await addNodeDefDependencies({ nodeDef, survey: surveyUpdated, sideEffect }) // NOSONAR\n }\n return surveyUpdated\n}\n"]}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "name": "OpenForis",
5
5
  "email": "openforis.arena@gmail.com"
6
6
  },
7
- "version": "2.16.5",
7
+ "version": "2.16.7",
8
8
  "description": "Arena core module",
9
9
  "repository": {
10
10
  "type": "git",