@pmate/cli 0.24.38 → 0.24.40

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.
Files changed (2) hide show
  1. package/dist/index.js +105 -23
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -15981,20 +15981,33 @@ async function writeStoredIndex(rootDir, index) {
15981
15981
  const filePath = import_node_path17.default.join(rootDir, "index.json");
15982
15982
  await import_node_fs12.promises.writeFile(filePath, JSON.stringify(index, null, 2) + "\n", "utf8");
15983
15983
  }
15984
- function mergeMessages(existing, incoming) {
15984
+ function diffMessages(existing, incoming) {
15985
15985
  const seenMessageIds = new Set(
15986
15986
  existing.map((message) => normalizeMessageId(message.messageId)).filter((value) => !!value)
15987
15987
  );
15988
- const merged = [...existing];
15989
- let added = 0;
15988
+ const mergedForMatching = [...existing];
15989
+ const diff = {
15990
+ added: [],
15991
+ upgraded: [],
15992
+ unchangedCount: 0
15993
+ };
15990
15994
  for (const message of incoming) {
15991
15995
  const incomingMessageId = normalizeMessageId(message.messageId);
15992
15996
  if (incomingMessageId && seenMessageIds.has(incomingMessageId)) {
15997
+ diff.unchangedCount += 1;
15993
15998
  continue;
15994
15999
  }
15995
- const upgradeIndex = merged.findIndex((current) => shouldUpgradeMessage(current, message));
16000
+ const upgradeIndex = mergedForMatching.findIndex(
16001
+ (current) => shouldUpgradeMessage(current, message)
16002
+ );
15996
16003
  if (upgradeIndex >= 0) {
15997
- merged[upgradeIndex] = message;
16004
+ const before = mergedForMatching[upgradeIndex];
16005
+ mergedForMatching[upgradeIndex] = message;
16006
+ diff.upgraded.push({
16007
+ index: upgradeIndex,
16008
+ before,
16009
+ after: message
16010
+ });
15998
16011
  if (incomingMessageId) {
15999
16012
  seenMessageIds.add(incomingMessageId);
16000
16013
  }
@@ -16003,10 +16016,18 @@ function mergeMessages(existing, incoming) {
16003
16016
  if (incomingMessageId) {
16004
16017
  seenMessageIds.add(incomingMessageId);
16005
16018
  }
16006
- merged.push(message);
16007
- added += 1;
16019
+ mergedForMatching.push(message);
16020
+ diff.added.push(message);
16021
+ }
16022
+ return diff;
16023
+ }
16024
+ function applyMessageDiff(existing, diff) {
16025
+ const merged = [...existing];
16026
+ for (const upgrade of diff.upgraded) {
16027
+ merged[upgrade.index] = upgrade.after;
16008
16028
  }
16009
- return { messages: merged, added };
16029
+ merged.push(...diff.added);
16030
+ return merged;
16010
16031
  }
16011
16032
  function shouldUpgradeMessage(existing, incoming) {
16012
16033
  const existingMessageId = normalizeMessageId(existing.messageId);
@@ -16113,7 +16134,21 @@ var CollectCommandHandler = class {
16113
16134
  throw new Error(firstFailure);
16114
16135
  }
16115
16136
  await this.writeIndex(target.rootDir, target, results, syncedAt);
16116
- this.printSyncSummary(target.sourceKey, target.rootDir, threads.length, results, failures);
16137
+ const reportPath = await this.writeSyncReport(
16138
+ target.rootDir,
16139
+ target,
16140
+ results,
16141
+ failures,
16142
+ syncedAt
16143
+ );
16144
+ this.printSyncSummary(
16145
+ target.sourceKey,
16146
+ target.rootDir,
16147
+ reportPath,
16148
+ threads.length,
16149
+ results,
16150
+ failures
16151
+ );
16117
16152
  } catch (error) {
16118
16153
  const message = error instanceof Error ? error.message : String(error);
16119
16154
  throw new Error(`collect failed: ${message}`);
@@ -16132,13 +16167,20 @@ var CollectCommandHandler = class {
16132
16167
  images: [...message.images],
16133
16168
  collectedAt: syncedAt
16134
16169
  }));
16135
- const merged = mergeMessages(existing?.messages ?? [], incoming);
16136
- const messagesWithArchivedImages = await archiveMessageImages(
16170
+ const existingMessages = await archiveMessageImages(
16137
16171
  rootDir,
16138
16172
  target.sourceKey,
16139
16173
  threadKey,
16140
- merged.messages
16174
+ existing?.messages ?? []
16141
16175
  );
16176
+ const incomingMessages = await archiveMessageImages(
16177
+ rootDir,
16178
+ target.sourceKey,
16179
+ threadKey,
16180
+ incoming
16181
+ );
16182
+ const diff = diffMessages(existingMessages, incomingMessages);
16183
+ const messagesWithArchivedImages = applyMessageDiff(existingMessages, diff);
16142
16184
  const stored = {
16143
16185
  source: target.sourceKey,
16144
16186
  endpoint: target.endpoint,
@@ -16154,8 +16196,9 @@ var CollectCommandHandler = class {
16154
16196
  await writeStoredThread(rootDir, stored);
16155
16197
  return {
16156
16198
  thread: stored,
16157
- addedMessages: merged.added,
16158
- updated: merged.added > 0 || !existing || existing.preview !== stored.preview || existing.unread !== stored.unread || existing.lastMessageAt !== stored.lastMessageAt
16199
+ diff,
16200
+ addedMessages: diff.added.length,
16201
+ updated: diff.added.length > 0 || diff.upgraded.length > 0 || !existing || existing.preview !== stored.preview || existing.unread !== stored.unread || existing.lastMessageAt !== stored.lastMessageAt
16159
16202
  };
16160
16203
  }
16161
16204
  async writeIndex(rootDir, target, results, syncedAt) {
@@ -16178,7 +16221,44 @@ var CollectCommandHandler = class {
16178
16221
  threads
16179
16222
  });
16180
16223
  }
16181
- printSyncSummary(sourceKey, rootDir, scannedThreads, results, failures) {
16224
+ async writeSyncReport(rootDir, target, results, failures, syncedAt) {
16225
+ const syncId = toSyncId(syncedAt);
16226
+ const reportPath = import_node_path18.default.join(rootDir, "syncs", `${syncId}.json`);
16227
+ const threadReports = results.map((result) => ({
16228
+ threadKey: result.thread.threadKey,
16229
+ threadName: result.thread.threadName,
16230
+ addedCount: result.diff.added.length,
16231
+ upgradedCount: result.diff.upgraded.length,
16232
+ addedMessages: result.diff.added,
16233
+ upgradedMessages: result.diff.upgraded
16234
+ })).filter((thread) => thread.addedCount > 0 || thread.upgradedCount > 0);
16235
+ await import_node_fs13.promises.mkdir(import_node_path18.default.dirname(reportPath), { recursive: true });
16236
+ await import_node_fs13.promises.writeFile(
16237
+ reportPath,
16238
+ JSON.stringify(
16239
+ {
16240
+ syncId,
16241
+ source: target.sourceKey,
16242
+ endpoint: target.endpoint,
16243
+ syncedAt,
16244
+ threadCount: results.length,
16245
+ changedThreadCount: threadReports.length,
16246
+ addedMessageCount: threadReports.reduce((sum, thread) => sum + thread.addedCount, 0),
16247
+ upgradedMessageCount: threadReports.reduce(
16248
+ (sum, thread) => sum + thread.upgradedCount,
16249
+ 0
16250
+ ),
16251
+ threads: threadReports,
16252
+ failures
16253
+ },
16254
+ null,
16255
+ 2
16256
+ ) + "\n",
16257
+ "utf8"
16258
+ );
16259
+ return reportPath;
16260
+ }
16261
+ printSyncSummary(sourceKey, rootDir, reportPath, scannedThreads, results, failures) {
16182
16262
  const updatedThreads = results.filter((result) => result.updated).length;
16183
16263
  const newMessages = results.reduce((sum, result) => sum + result.addedMessages, 0);
16184
16264
  ui.plain(`Synced source: ${sourceKey}`);
@@ -16186,7 +16266,8 @@ var CollectCommandHandler = class {
16186
16266
  ui.plain(`Threads updated: ${updatedThreads}`);
16187
16267
  ui.plain(`Threads failed: ${failures.length}`);
16188
16268
  ui.plain(`New messages: ${newMessages}`);
16189
- ui.plain(`Saved under: ${rootDir}`);
16269
+ ui.plain(`Diff saved: ${reportPath}`);
16270
+ ui.plain(`Archive saved: ${rootDir}`);
16190
16271
  for (const failure of failures.slice(0, 10)) {
16191
16272
  ui.warn(`Thread failed: ${failure.threadName}`, failure.message);
16192
16273
  }
@@ -16552,6 +16633,9 @@ function buildGetMessagesByConversationExpr(conversationId, limit) {
16552
16633
  function escapeForJs(value) {
16553
16634
  return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n").replace(/\r/g, "\\r");
16554
16635
  }
16636
+ function toSyncId(syncedAt) {
16637
+ return syncedAt.replace(/[:.]/g, "-");
16638
+ }
16555
16639
  function formatSentAt(sentAt) {
16556
16640
  const value = typeof sentAt === "number" ? sentAt : typeof sentAt === "string" && /^\d+$/.test(sentAt) ? Number.parseInt(sentAt, 10) : NaN;
16557
16641
  if (!Number.isFinite(value) || value <= 0) {
@@ -18723,7 +18807,7 @@ var ServiceRuntimeRunner = class {
18723
18807
  });
18724
18808
  ui.title(`Logs for ${namespace}/${appName}`);
18725
18809
  ui.info("Source", { mode: options.history ? "history" : "online" });
18726
- this.renderPage(page, { oldestFirst: Boolean(options.follow) });
18810
+ this.renderPage(page);
18727
18811
  if (options.follow) {
18728
18812
  await this.followLogs(namespace, appName, {
18729
18813
  page: options.page ?? 0,
@@ -18766,8 +18850,7 @@ var ServiceRuntimeRunner = class {
18766
18850
  if (newItems.length === 0) {
18767
18851
  continue;
18768
18852
  }
18769
- const ordered = [...newItems].reverse();
18770
- for (const item of ordered) {
18853
+ for (const item of newItems) {
18771
18854
  seen.add(item.hash);
18772
18855
  recent.unshift(item);
18773
18856
  if (recent.length > 200) {
@@ -19374,15 +19457,14 @@ var ServiceRuntimeRunner = class {
19374
19457
  }
19375
19458
  return "preview";
19376
19459
  }
19377
- renderPage(page, options = {}) {
19460
+ renderPage(page) {
19378
19461
  ui.info("Page", {
19379
19462
  page: page.page,
19380
19463
  totalPage: page.totalPage,
19381
19464
  pageSize: page.pageSize,
19382
19465
  items: page.data.length
19383
19466
  });
19384
- const items = options.oldestFirst ? [...page.data].reverse() : page.data;
19385
- for (const item of items) {
19467
+ for (const item of page.data) {
19386
19468
  ui.plain(this.renderLogLine(item));
19387
19469
  }
19388
19470
  }
@@ -19559,7 +19641,7 @@ var ServiceRuntimeRunner = class {
19559
19641
  shown: Math.min(matched.length, 20)
19560
19642
  });
19561
19643
  const toShow = matched.slice(0, 20);
19562
- for (const item of toShow.reverse()) {
19644
+ for (const item of toShow) {
19563
19645
  ui.plain(this.renderLogLine(item));
19564
19646
  }
19565
19647
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pmate/cli",
3
- "version": "0.24.38",
3
+ "version": "0.24.40",
4
4
  "description": "CLI utilities for the pMate project",
5
5
  "license": "MIT",
6
6
  "bin": {