@nmakarov/cli-toolkit 0.40.0 → 0.44.0

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/dist/tasks.js CHANGED
@@ -372,22 +372,46 @@ async function ensureTaskTables(context, options = {}) {
372
372
  }
373
373
  }
374
374
  const { actions } = await ensureSchema(db, spec, { dryRun, logger: context.logger });
375
+ const legacyDrops = await dropLegacyTaskNameColumn(db, [tasksTable, historyTable], {
376
+ dryRun,
377
+ log,
378
+ label
379
+ });
380
+ const allActions = [...actions, ...legacyDrops];
375
381
  if (dryRun) {
376
- if (actions.length === 0) {
382
+ if (allActions.length === 0) {
377
383
  log.info?.(`[tasks-schema] dryRun \u2014 ${label}: queue "${queueName}" already up to date; no DDL`);
378
384
  } else {
379
385
  log.info?.(
380
- `[tasks-schema] dryRun \u2014 ${label}: would run ${actions.length} statement(s) for queue "${queueName}":`
386
+ `[tasks-schema] dryRun \u2014 ${label}: would run ${allActions.length} statement(s) for queue "${queueName}":`
381
387
  );
382
- for (const s of actions) log.info?.(` - ${s}`);
388
+ for (const s of allActions) log.info?.(` - ${s}`);
383
389
  }
384
- } else if (actions.length > 0) {
390
+ } else if (allActions.length > 0) {
385
391
  log.info?.(
386
- `[tasks-schema] ${label}: applied ${actions.length} DDL statement(s) for queue "${queueName}"`
392
+ `[tasks-schema] ${label}: applied ${allActions.length} DDL statement(s) for queue "${queueName}"`
387
393
  );
388
394
  }
389
395
  }
390
396
  }
397
+ async function dropLegacyTaskNameColumn(db, tableNames, { dryRun, log, label }) {
398
+ const actions = [];
399
+ for (const table of tableNames) {
400
+ if (!await db.tableExists(table).catch(() => false)) continue;
401
+ const hasTask = await db.schema.hasColumn(table, "task");
402
+ const hasName = await db.schema.hasColumn(table, "name");
403
+ if (!hasTask || !hasName) continue;
404
+ const sql = `ALTER TABLE "${table}" DROP COLUMN IF EXISTS "task"`;
405
+ actions.push(sql);
406
+ if (dryRun) {
407
+ log?.info?.(`[tasks-schema] dryRun \u2014 ${label}: ${sql}`);
408
+ } else {
409
+ await db.raw(sql);
410
+ log?.info?.(`[tasks-schema] ${label}: dropped legacy column ${table}.task`);
411
+ }
412
+ }
413
+ return actions;
414
+ }
391
415
  async function enqueueTask(context, options) {
392
416
  const db = getDb(context);
393
417
  const queueName = options.queueName ?? "tasks";
@@ -404,7 +428,7 @@ async function enqueueTask(context, options) {
404
428
  } else if (schedule) {
405
429
  nextRunAt = nextTimeMatch(schedule, /* @__PURE__ */ new Date());
406
430
  }
407
- await db(tasksTable).insert({
431
+ const row = {
408
432
  id,
409
433
  name,
410
434
  params: toJsonColumn(options.params ?? null),
@@ -418,9 +442,21 @@ async function enqueueTask(context, options) {
418
442
  server_name: options.serverName ?? null,
419
443
  status: "idle",
420
444
  status_changed_at: db.fn.now()
421
- });
445
+ };
446
+ if (await tableHasLegacyTaskColumn(db, tasksTable)) {
447
+ row.task = name;
448
+ }
449
+ await db(tasksTable).insert(row);
422
450
  return id;
423
451
  }
452
+ var legacyTaskColumnCache = /* @__PURE__ */ new Map();
453
+ async function tableHasLegacyTaskColumn(db, tableName) {
454
+ const key = `${db?.config?.name ?? "db"}:${tableName}`;
455
+ if (!legacyTaskColumnCache.has(key)) {
456
+ legacyTaskColumnCache.set(key, await db.schema.hasColumn(tableName, "task"));
457
+ }
458
+ return legacyTaskColumnCache.get(key);
459
+ }
424
460
  async function updateTaskProgress(context, tasksTable, taskId, progress) {
425
461
  const db = getDb(context);
426
462
  await db(tasksTable).where({ id: taskId }).update({
@@ -752,6 +788,9 @@ var FileDatabase = class _FileDatabase {
752
788
  currentRecord = 0;
753
789
  hasReadFirstPage = false;
754
790
  lastFileData = null;
791
+ /** Cache of the last JSON file parsed during paginated reads (avoid re-parse per page). */
792
+ readFileCache = null;
793
+ // { filePath: string, data: any[] } | null
755
794
  metadata;
756
795
  // Synopsis calculation functions
757
796
  fileSynopsisFunction = null;
@@ -1518,7 +1557,6 @@ var FileDatabase = class _FileDatabase {
1518
1557
  let effectivePageSize;
1519
1558
  if (nextPage && this.hasReadFirstPage) {
1520
1559
  effectivePageSize = pageSize || this.pageSize;
1521
- this.currentRecord += effectivePageSize;
1522
1560
  } else if (!nextPage) {
1523
1561
  effectivePageSize = pageSize !== void 0 ? pageSize : this.metadata.totalRecords;
1524
1562
  this.currentRecord = 0;
@@ -1547,8 +1585,14 @@ var FileDatabase = class _FileDatabase {
1547
1585
  const file = this.metadata.files[i];
1548
1586
  const filePath = path3.join(this.getDestinationPath(this.currentVersion || void 0), file.fileName);
1549
1587
  try {
1550
- const rawData = await fs3.promises.readFile(filePath, "utf8");
1551
- const fileData = deserializeData(rawData, this.metadata.dataType);
1588
+ let fileData;
1589
+ if (this.readFileCache?.filePath === filePath && Array.isArray(this.readFileCache.data)) {
1590
+ fileData = this.readFileCache.data;
1591
+ } else {
1592
+ const rawData = await fs3.promises.readFile(filePath, "utf8");
1593
+ fileData = deserializeData(rawData, this.metadata.dataType);
1594
+ this.readFileCache = { filePath, data: fileData };
1595
+ }
1552
1596
  let startIndex = 0;
1553
1597
  if (i === currentFileIndex) {
1554
1598
  startIndex = this.currentRecord - cumulativeRecords;
@@ -1562,6 +1606,7 @@ var FileDatabase = class _FileDatabase {
1562
1606
  throw new FileDatabaseError(`Failed to read file ${file.fileName}: ${error.message}`);
1563
1607
  }
1564
1608
  }
1609
+ this.currentRecord += recordsRead;
1565
1610
  if (result.length > 0) {
1566
1611
  if (nextPage || pageSize !== void 0 && pageSize < this.metadata.totalRecords) {
1567
1612
  this.hasReadFirstPage = true;
@@ -1575,6 +1620,7 @@ var FileDatabase = class _FileDatabase {
1575
1620
  setStartRecord(startRecord) {
1576
1621
  this.currentRecord = startRecord - 1;
1577
1622
  this.hasReadFirstPage = false;
1623
+ this.readFileCache = null;
1578
1624
  }
1579
1625
  /**
1580
1626
  * Reset read pagination state
@@ -1582,6 +1628,7 @@ var FileDatabase = class _FileDatabase {
1582
1628
  resetPagination() {
1583
1629
  this.currentRecord = 0;
1584
1630
  this.hasReadFirstPage = false;
1631
+ this.readFileCache = null;
1585
1632
  }
1586
1633
  /**
1587
1634
  * List filenames in the table directory.