@forzalabs/remora 2.0.0 → 2.0.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forzalabs/remora",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "A powerful CLI tool for seamless data translation.",
5
5
  "main": "index.js",
6
6
  "private": false,
@@ -11057,9 +11057,20 @@ var init_FileLogService = __esm({
11057
11057
  FileLogServiceClass = class {
11058
11058
  constructor() {
11059
11059
  this._enabled = false;
11060
+ /**
11061
+ * Points the sink at a file, once per target.
11062
+ *
11063
+ * Idempotent on purpose: the executor worker re-applies the parent's logger config at the START
11064
+ * OF EVERY TASK, and a thread under the run-long pool handles many tasks. Building a transport
11065
+ * per call left one open append stream per task on the same file.
11066
+ */
11060
11067
  this.enable = (folder = "./remora/.temp/logs", file = "remora.log") => {
11068
+ if (this._enabled && this._folder === folder && this._file === file)
11069
+ return;
11061
11070
  if (!(0, import_fs.existsSync)(folder))
11062
11071
  (0, import_fs.mkdirSync)(folder, { recursive: true });
11072
+ if (this._logger)
11073
+ this._logger.end();
11063
11074
  this._folder = folder;
11064
11075
  this._file = file;
11065
11076
  this._logger = import_winston.default.createLogger({
@@ -11073,6 +11084,9 @@ ${stack}` : base;
11073
11084
  })
11074
11085
  ),
11075
11086
  transports: [
11087
+ // Rotation is the transport's job. A run writes this file from the main process and
11088
+ // from every executor thread, so a rotation renames a file others hold open — the
11089
+ // 'error' handler below is what keeps that a logged line rather than a dead thread.
11076
11090
  new import_winston.default.transports.File({
11077
11091
  filename: import_path.default.join(folder, file),
11078
11092
  maxsize: 10 * 1024 * 1024,
@@ -11082,6 +11096,7 @@ ${stack}` : base;
11082
11096
  })
11083
11097
  ]
11084
11098
  });
11099
+ this._logger.on("error", (error) => console.error(`File logger error: ${error?.message ?? String(error)}`));
11085
11100
  this._enabled = true;
11086
11101
  };
11087
11102
  /**
@@ -11123,11 +11138,22 @@ ${stack}` : base;
11123
11138
  }
11124
11139
  });
11125
11140
  };
11141
+ /**
11142
+ * Ends the sink. The state goes with it, so the next write re-enables a fresh one.
11143
+ *
11144
+ * That reset is the point: a closed winston logger still accepts `log()` calls and writes them
11145
+ * into an ended stream, which throws ERR_STREAM_WRITE_AFTER_END from a stream nothing is
11146
+ * listening to. Leaving `_enabled` true after a close is what turned "someone logged after
11147
+ * close" into "the process died". Use `flush()` when the sink is still needed afterwards.
11148
+ */
11126
11149
  this.close = () => {
11127
11150
  if (!this._enabled || !this._logger) return Promise.resolve();
11151
+ const closing = this._logger;
11152
+ this._enabled = false;
11153
+ this._logger = null;
11128
11154
  return new Promise((resolve) => {
11129
- this._logger.on("finish", resolve);
11130
- this._logger.end();
11155
+ closing.on("finish", resolve);
11156
+ closing.end();
11131
11157
  });
11132
11158
  };
11133
11159
  }
@@ -11549,7 +11575,7 @@ var CONSTANTS, Constants_default;
11549
11575
  var init_Constants = __esm({
11550
11576
  "../../packages/constants/src/Constants.ts"() {
11551
11577
  CONSTANTS = {
11552
- cliVersion: "2.0.0",
11578
+ cliVersion: "2.0.1",
11553
11579
  backendVersion: 1,
11554
11580
  backendPort: 5088,
11555
11581
  workerVersion: 2,
@@ -11834,6 +11860,132 @@ var init_SecretManager = __esm({
11834
11860
  }
11835
11861
  });
11836
11862
 
11863
+ // ../../packages/common/src/schema/SchemaErrorReporter.ts
11864
+ var MAX_REPORTED_ERRORS, MAX_LISTED_VALUES, MAX_QUOTED_LENGTH, VALUE_KEYWORDS, ITEM_NAME_KEYS, SchemaErrorReporterClass, SchemaErrorReporter, SchemaErrorReporter_default;
11865
+ var init_SchemaErrorReporter = __esm({
11866
+ "../../packages/common/src/schema/SchemaErrorReporter.ts"() {
11867
+ MAX_REPORTED_ERRORS = 3;
11868
+ MAX_LISTED_VALUES = 30;
11869
+ MAX_QUOTED_LENGTH = 40;
11870
+ VALUE_KEYWORDS = ["type", "pattern", "format", "maxLength", "minLength", "minimum", "maximum", "exclusiveMinimum", "exclusiveMaximum", "multipleOf", "const"];
11871
+ ITEM_NAME_KEYS = ["name", "alias", "key", "title"];
11872
+ SchemaErrorReporterClass = class {
11873
+ constructor() {
11874
+ /**
11875
+ * One human-readable line for a failed validation. `data` is the value that was validated, and is
11876
+ * read to quote the offending value back and to name the resource's own parts.
11877
+ */
11878
+ this.describe = (errors, data) => {
11879
+ const relevant = this._prune(errors ?? []);
11880
+ const shown = relevant.slice(0, MAX_REPORTED_ERRORS).map((x2) => this._explain(x2, data));
11881
+ const hidden = relevant.length - shown.length;
11882
+ return [shown.join("; "), hidden > 0 ? `+${hidden} more` : null].filter(Boolean).join(", ");
11883
+ };
11884
+ /**
11885
+ * Drops the alternatives' complaints from every failed `oneOf`/`anyOf`, because they are one
11886
+ * rejection per alternative rather than one problem. What survives is whatever an alternative
11887
+ * said about a value BELOW the branch point — the alternative that got far enough in to find the
11888
+ * real mistake — and when no alternative got that far, the branch point itself, which then reads
11889
+ * as the list of what was allowed there.
11890
+ */
11891
+ this._prune = (errors) => {
11892
+ const branchPoints = errors.filter((x2) => x2.keyword === "oneOf" || x2.keyword === "anyOf");
11893
+ const kept = branchPoints.reduce((remaining, branch) => this._resolveBranch(remaining, branch), errors);
11894
+ return this._dedupe(kept);
11895
+ };
11896
+ /** Keeps, of everything reported at one branch point, only what says where the mistake actually is. */
11897
+ this._resolveBranch = (kept, branch) => {
11898
+ if (!kept.includes(branch)) return kept;
11899
+ const isAtBranch = (x2) => x2.instancePath === branch.instancePath;
11900
+ const hasDeeper = kept.some((x2) => x2.instancePath.startsWith(branch.instancePath + "/"));
11901
+ return hasDeeper ? kept.filter((x2) => !isAtBranch(x2)) : kept.filter((x2) => !isAtBranch(x2) || x2 === branch);
11902
+ };
11903
+ /** The same complaint from several alternatives is still one complaint. */
11904
+ this._dedupe = (errors) => {
11905
+ const seen = /* @__PURE__ */ new Set();
11906
+ return errors.filter((x2) => {
11907
+ const signature = `${x2.instancePath}|${x2.keyword}|${x2.message}|${JSON.stringify(x2.params ?? {})}`;
11908
+ if (seen.has(signature)) return false;
11909
+ seen.add(signature);
11910
+ return true;
11911
+ });
11912
+ };
11913
+ this._explain = (error, data) => `${this._locate(error.instancePath, data)} ${this._reason(error, data)}`;
11914
+ /**
11915
+ * The JSON pointer to the offending value, followed by the name of the array item it sits in.
11916
+ * "/fields/2" is a position; "(field "created_at")" is what the author called it.
11917
+ */
11918
+ this._locate = (instancePath, data) => {
11919
+ const named = this._nameItem(instancePath, data);
11920
+ return [instancePath || "/", named].filter(Boolean).join(" ");
11921
+ };
11922
+ /** `/fields/2/transform/cast` in a consumer -> `(field "created_at")`, when the item carries a name. */
11923
+ this._nameItem = (instancePath, data) => {
11924
+ const segments = this._segments(instancePath);
11925
+ for (let index = segments.length - 1; index > 0; index--) {
11926
+ if (!/^\d+$/.test(segments[index])) continue;
11927
+ const item = this._valueAt(data, segments.slice(0, index + 1));
11928
+ const nameKey = ITEM_NAME_KEYS.find((key) => typeof item?.[key] === "string");
11929
+ if (!nameKey) continue;
11930
+ return `(${this._singular(segments[index - 1])} "${item[nameKey]}")`;
11931
+ }
11932
+ return null;
11933
+ };
11934
+ /** Reads the way a config author speaks about the collection: `fields` -> `field`. */
11935
+ this._singular = (collection) => collection.endsWith("s") ? collection.slice(0, -1) : collection;
11936
+ /**
11937
+ * What was wrong, in the terms the author wrote. Ajv's own message says what the schema wanted;
11938
+ * these add what was actually there, which is the half that names the typo.
11939
+ */
11940
+ this._reason = (error, data) => {
11941
+ const value = "data" in error ? error.data : this._valueAt(data, this._segments(error.instancePath));
11942
+ if (error.keyword === "enum")
11943
+ return `must be one of: ${this._list(error.params.allowedValues)} (got ${this._quote(value)})`;
11944
+ if (error.keyword === "additionalProperties")
11945
+ return `has unknown property "${error.params.additionalProperty}"`;
11946
+ if (error.keyword === "oneOf" || error.keyword === "anyOf")
11947
+ return this._describeAlternatives(error, value);
11948
+ if (VALUE_KEYWORDS.includes(error.keyword))
11949
+ return `${error.message} (got ${this._quote(value)})`;
11950
+ return error.message;
11951
+ };
11952
+ /**
11953
+ * A branch point no alternative matched, named by what the alternatives ARE — read off the schema
11954
+ * rather than off their rejections, because an alternative says nothing about the property it
11955
+ * requires when that property is present and the rest of it is what failed.
11956
+ */
11957
+ this._describeAlternatives = (error, value) => {
11958
+ const shapes = (error.schema ?? []).map((x2) => this._shape(x2)).filter(Boolean);
11959
+ if (shapes.length === 0) return error.message;
11960
+ if (value && typeof value === "object" && !Array.isArray(value))
11961
+ return `must have exactly one of: ${this._list(shapes)} (has: ${this._list(Object.keys(value))})`;
11962
+ return `must be one of: ${this._list(shapes)} (got ${this._quote(value)})`;
11963
+ };
11964
+ /** How one alternative would be described to whoever has to write it: a property, or a type. */
11965
+ this._shape = (alternative) => {
11966
+ if (alternative?.required?.length > 0) return alternative.required.join(" + ");
11967
+ if (alternative?.pattern) return `${alternative.type ?? "string"} matching "${alternative.pattern}"`;
11968
+ return alternative?.type ?? null;
11969
+ };
11970
+ /** `/fields/2/transform` -> ['fields', '2', 'transform'], undoing the pointer's escapes. */
11971
+ this._segments = (instancePath) => (instancePath || "").split("/").slice(1).map((x2) => x2.replace(/~1/g, "/").replace(/~0/g, "~"));
11972
+ this._valueAt = (data, segments) => segments.reduce((current, segment) => current?.[segment], data);
11973
+ this._list = (values) => {
11974
+ const shown = (values ?? []).slice(0, MAX_LISTED_VALUES).join(", ");
11975
+ const hidden = (values ?? []).length - MAX_LISTED_VALUES;
11976
+ return hidden > 0 ? `${shown}, +${hidden} more` : shown;
11977
+ };
11978
+ this._quote = (value) => {
11979
+ const text = value === void 0 ? "nothing" : JSON.stringify(value);
11980
+ return text.length > MAX_QUOTED_LENGTH ? `${text.slice(0, MAX_QUOTED_LENGTH)}\u2026` : text;
11981
+ };
11982
+ }
11983
+ };
11984
+ SchemaErrorReporter = new SchemaErrorReporterClass();
11985
+ SchemaErrorReporter_default = SchemaErrorReporter;
11986
+ }
11987
+ });
11988
+
11837
11989
  // ../../packages/common/src/schema/SchemaValidator.ts
11838
11990
  var import_ajv, import_ajv_formats, import_fs3, import_path3, SchemaValidatorClass, SchemaValidator, SchemaValidator_default;
11839
11991
  var init_SchemaValidator = __esm({
@@ -11843,11 +11995,12 @@ var init_SchemaValidator = __esm({
11843
11995
  import_fs3 = __toESM(require("fs"), 1);
11844
11996
  import_path3 = __toESM(require("path"), 1);
11845
11997
  init_src();
11998
+ init_SchemaErrorReporter();
11846
11999
  SchemaValidatorClass = class {
11847
12000
  constructor() {
11848
12001
  this.addSchema = (schema, schemaKey) => {
11849
12002
  const isValid = this.ajv.validateSchema(schema);
11850
- Affirm_default(isValid, `Invalid JSON Schema: ${JSON.stringify(this.ajv.errors)}`);
12003
+ Affirm_default(isValid, `Invalid JSON Schema: ${SchemaErrorReporter_default.describe(this.ajv.errors, schema)}`);
11851
12004
  this.ajv.addSchema(schema, schemaKey);
11852
12005
  };
11853
12006
  this.getSchema = (schemaKey) => {
@@ -11901,7 +12054,10 @@ var init_SchemaValidator = __esm({
11901
12054
  strictSchema: false,
11902
12055
  // Code values may be string | number | boolean, so schemas legitimately use union types.
11903
12056
  allowUnionTypes: true,
11904
- validateFormats: true
12057
+ validateFormats: true,
12058
+ // Carries the failing schema and value on each error, which is what lets
12059
+ // SchemaErrorReporter say what was allowed there and what was found instead.
12060
+ verbose: true
11905
12061
  });
11906
12062
  (0, import_ajv_formats.default)(this.ajv);
11907
12063
  this.loadInternalSchema();
@@ -13231,7 +13387,7 @@ ${errors.map((x2) => ` - ${x2}`).join("\n")}`);
13231
13387
  });
13232
13388
 
13233
13389
  // ../../packages/common/src/Environment.ts
13234
- var import_fs4, import_crypto, import_adm_zip, import_path4, import_client_s3, RESOURCE_SCHEMA_KEYS, INVALID_RESOURCE_MESSAGES, MAX_REPORTED_SCHEMA_ERRORS, EnvironmentClass, Environment, Environment_default;
13390
+ var import_fs4, import_crypto, import_adm_zip, import_path4, import_client_s3, RESOURCE_SCHEMA_KEYS, INVALID_RESOURCE_MESSAGES, EnvironmentClass, Environment, Environment_default;
13235
13391
  var init_Environment = __esm({
13236
13392
  "../../packages/common/src/Environment.ts"() {
13237
13393
  import_fs4 = __toESM(require("fs"), 1);
@@ -13240,6 +13396,7 @@ var init_Environment = __esm({
13240
13396
  init_src();
13241
13397
  import_path4 = __toESM(require("path"), 1);
13242
13398
  init_SchemaValidator();
13399
+ init_SchemaErrorReporter();
13243
13400
  init_Validator();
13244
13401
  init_ProducerExpander();
13245
13402
  init_src3();
@@ -13259,7 +13416,6 @@ var init_Environment = __esm({
13259
13416
  codeSet: "Invalid code set configuration",
13260
13417
  schema: "Invalid schema configuration"
13261
13418
  };
13262
- MAX_REPORTED_SCHEMA_ERRORS = 3;
13263
13419
  EnvironmentClass = class {
13264
13420
  constructor() {
13265
13421
  this._env = null;
@@ -13432,21 +13588,21 @@ var init_Environment = __esm({
13432
13588
  schemas.forEach((schema) => this._registerSchema(schema, problems));
13433
13589
  const sourceFiles = read(projectConfig.sources);
13434
13590
  const sources = sourceFiles.map((x2) => x2.config);
13435
- sources.forEach((source) => this._recordSchemaProblem(source, "source", problems));
13591
+ sourceFiles.forEach((source) => this._recordSchemaProblem(source, "source", problems));
13436
13592
  this._checkApiQueueSource(projectConfig, sources, problems);
13437
13593
  const producerFiles = read(projectConfig.producers);
13438
13594
  const producers = producerFiles.map((x2) => x2.config);
13439
- producers.forEach((producer) => {
13440
- const schemaProblem = this._schemaProblem(producer, "producer");
13595
+ producerFiles.forEach(({ config: producer, file }) => {
13596
+ const schemaProblem = this._schemaProblem(producer, "producer", file);
13441
13597
  this._expandProducer(producer, problems);
13442
13598
  if (schemaProblem) problems.push(schemaProblem);
13443
13599
  });
13444
13600
  const consumerFiles = read(projectConfig.consumers);
13445
13601
  const consumers = consumerFiles.map((x2) => x2.config);
13446
- consumers.forEach((consumer) => this._recordSchemaProblem(consumer, "consumer", problems));
13602
+ consumerFiles.forEach((consumer) => this._recordSchemaProblem(consumer, "consumer", problems));
13447
13603
  const codeSetFiles = read(projectConfig.codeSets ?? []);
13448
13604
  const codeSets = codeSetFiles.map((x2) => x2.config);
13449
- codeSets.forEach((codeSet) => this._recordSchemaProblem(codeSet, "codeSet", problems));
13605
+ codeSetFiles.forEach((codeSet) => this._recordSchemaProblem(codeSet, "codeSet", problems));
13450
13606
  this._checkCodeSetNames(codeSets, problems);
13451
13607
  return {
13452
13608
  env: { settings: this._readSettings(projectConfig), sources, producers, consumers, schemas, codeSets },
@@ -13526,7 +13682,7 @@ var init_Environment = __esm({
13526
13682
  severity: "error",
13527
13683
  scope: "project",
13528
13684
  file: projectPath,
13529
- message: `Invalid project configuration (${this._describeSchemaErrors(validation.errors)})`
13685
+ message: `Invalid project configuration - ${SchemaErrorReporter_default.describe(validation.errors, projectConfig)}`
13530
13686
  });
13531
13687
  }
13532
13688
  return projectConfig;
@@ -13582,8 +13738,8 @@ var init_Environment = __esm({
13582
13738
  }
13583
13739
  return results;
13584
13740
  };
13585
- this._recordSchemaProblem = (resource, kind, problems) => {
13586
- const problem = this._schemaProblem(resource, kind);
13741
+ this._recordSchemaProblem = (read, kind, problems) => {
13742
+ const problem = this._schemaProblem(read.config, kind, read.file);
13587
13743
  if (problem) problems.push(problem);
13588
13744
  };
13589
13745
  /**
@@ -13594,15 +13750,17 @@ var init_Environment = __esm({
13594
13750
  * Returns the problem instead of recording it, because a producer's is reported after its
13595
13751
  * expansion has had its say (see `inspect`).
13596
13752
  */
13597
- this._schemaProblem = (resource, kind) => {
13753
+ this._schemaProblem = (resource, kind, file) => {
13598
13754
  const name = resource?.name;
13599
13755
  const validation = SchemaValidator_default.validate(RESOURCE_SCHEMA_KEYS[kind], resource);
13600
13756
  if (validation.isValid) return null;
13757
+ const where = [name, file ? `(${file})` : null].filter(Boolean).join(" ");
13601
13758
  return {
13602
13759
  severity: "error",
13603
13760
  scope: "resource",
13761
+ file,
13604
13762
  resource: { kind, name },
13605
- message: `${INVALID_RESOURCE_MESSAGES[kind]}: ${name} (${this._describeSchemaErrors(validation.errors)})`
13763
+ message: `${INVALID_RESOURCE_MESSAGES[kind]}: ${where} - ${SchemaErrorReporter_default.describe(validation.errors, resource)}`
13606
13764
  };
13607
13765
  };
13608
13766
  this._registerSchema = (schema, problems) => {
@@ -13679,12 +13837,6 @@ var init_Environment = __esm({
13679
13837
  /** Kept verbatim from the batch loader this replaced, so `load()` still throws the same string. */
13680
13838
  this._loadFailureMessage = (remoraPath, configPath, error) => `Error loading from ${import_path4.default.resolve(remoraPath)} configuration from ${configPath}: ${this._messageOf(error)}`;
13681
13839
  this._messageOf = (error) => error instanceof Error ? error.message : String(error);
13682
- /** The first few Ajv complaints, so "Invalid producer configuration: p_x" says what is wrong with it. */
13683
- this._describeSchemaErrors = (errors) => {
13684
- const shown = (errors ?? []).slice(0, MAX_REPORTED_SCHEMA_ERRORS).map((item) => `${item.instancePath || "/"} ${item.message}`);
13685
- const hidden = (errors ?? []).length - shown.length;
13686
- return [shown.join("; "), hidden > 0 ? `+${hidden} more` : null].filter(Boolean).join(", ");
13687
- };
13688
13840
  /**
13689
13841
  * The loaded environment, flattened for transport to a worker thread.
13690
13842
  *
@@ -52262,8 +52414,9 @@ var init_ExecutorOrchestrator = __esm({
52262
52414
  *
52263
52415
  * `maxWorkers` must come from getParallelWorkerCount(), never from the amount of work: that count
52264
52416
  * is memory-aware and is what stops a low-end machine oversubscribing itself. Surplus work queues
52265
- * instead of spawning threads. `census` counts threads as workerpool creates them, which is the
52266
- * only way to know the peak — they spawn lazily, on first exec.
52417
+ * instead of spawning threads. `census.created` counts every thread workerpool spawns — they
52418
+ * spawn lazily, on first exec, and a thread that dies mid-run is replaced by another, so this is
52419
+ * a count of spawns and NOT a concurrency figure (see IWorkerCensus).
52267
52420
  *
52268
52421
  * `workerData` carries the loaded environment, so it is cloned once per THREAD at spawn rather
52269
52422
  * than read and validated from disk once per chunk. Only run-constant data belongs there; per-task
@@ -52280,12 +52433,8 @@ var init_ExecutorOrchestrator = __esm({
52280
52433
  }
52281
52434
  },
52282
52435
  onCreateWorker: () => {
52283
- census.alive++;
52284
- census.peak = Math.max(census.peak, census.alive);
52436
+ census.created++;
52285
52437
  return void 0;
52286
- },
52287
- onTerminateWorker: () => {
52288
- census.alive--;
52289
52438
  }
52290
52439
  };
52291
52440
  const workerPath = OrchestratorHelper_default.getPhysicalWorkerPath();
@@ -52304,7 +52453,7 @@ var init_ExecutorOrchestrator = __esm({
52304
52453
  const { usageId } = UsageManager_default.startUsage(consumer, details);
52305
52454
  const scope = { id: usageId, folder: `${consumer.name}_${usageId}`, workersId: [], limitFileSize: consumer.maximumFileSize };
52306
52455
  const expandedFields = ConsumerManager_default.getExpandedFields(consumer);
52307
- const census = { alive: 0, peak: 0 };
52456
+ const census = { created: 0, peak: 0 };
52308
52457
  try {
52309
52458
  const start = performance.now();
52310
52459
  const executorResults = [];
@@ -52543,6 +52692,7 @@ var init_ExecutorOrchestrator = __esm({
52543
52692
  const context = {
52544
52693
  consumer: request.consumer,
52545
52694
  scope,
52695
+ census,
52546
52696
  options: request.options,
52547
52697
  lookups: request.lookups,
52548
52698
  progress: request.progress,
@@ -52557,8 +52707,12 @@ var init_ExecutorOrchestrator = __esm({
52557
52707
  phase = performance.now();
52558
52708
  const resultsByFile = await Promise.all(pendingByFile.map((file) => Promise.all(file)));
52559
52709
  tracker.measure("worker-wait", performance.now() - phase);
52710
+ census.peak = Math.max(census.peak, pool.stats().totalWorkers);
52560
52711
  Affirm_default(census.peak <= poolSize, `The worker pool ran ${census.peak} thread(s) at once but was sized ${poolSize}`);
52561
52712
  const results = resultsByFile.flat();
52713
+ const failures = results.filter((x2) => !Algo_default.hasVal(x2)).length;
52714
+ if (failures > 0 || census.created > poolSize)
52715
+ Logger_default.warn(`[${scope.id}] ${failures} of ${chunkCount} chunk(s) failed and ${census.created} thread(s) were spawned for a pool of ${poolSize} \u2014 a thread that dies is replaced, so the chunk error(s) logged above are the cause`);
52562
52716
  this.recordWorkerBoot(results, context.requestedAtByWorker, tracker);
52563
52717
  for (const [index, fileResults] of resultsByFile.entries())
52564
52718
  this._assignChunkRowMetadata(workFiles[index].chunks, fileResults);
@@ -52589,7 +52743,12 @@ var init_ExecutorOrchestrator = __esm({
52589
52743
  context.requestedAtByWorker.set(workerId, performance.timeOrigin + performance.now());
52590
52744
  Logger_default.log(`[${scope.id}] Queued worker ${workerId} for ${file.label} \u2014 chunk ${chunk.start}-${chunk.end} (${Math.round((chunk.end - chunk.start) / 1024)}KB)`);
52591
52745
  return pool.exec("executor", [workerData], {
52592
- on: (payload) => this.onWorkAdvanced(payload, workerId, context)
52746
+ // Progress packets are the run's only regular tick on the main thread, which makes them
52747
+ // the cheapest place to sample how many threads are actually alive at once.
52748
+ on: (payload) => {
52749
+ context.census.peak = Math.max(context.census.peak, pool.stats().totalWorkers);
52750
+ this.onWorkAdvanced(payload, workerId, context);
52751
+ }
52593
52752
  }).catch((error) => {
52594
52753
  Logger_default.error(error);
52595
52754
  return null;
@@ -53393,11 +53552,11 @@ var runExecutorTask = async (workerData) => {
53393
53552
  rssMB: Math.round(memory.rss / (1024 * 1024)),
53394
53553
  heapUsedMB: Math.round(memory.heapUsed / (1024 * 1024))
53395
53554
  };
53396
- await Logger_default.close();
53555
+ await Logger_default.flush();
53397
53556
  return res;
53398
53557
  } catch (error) {
53399
53558
  Logger_default.error(error);
53400
- await Logger_default.close();
53559
+ await Logger_default.flush();
53401
53560
  throw error;
53402
53561
  }
53403
53562
  };