@llblab/pi-telegram 0.24.0 → 0.24.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/lib/threads.ts CHANGED
@@ -443,8 +443,7 @@ export function getTelegramTopicTargetsPath(
443
443
  return getTelegramStatePath(agentDir, profileName);
444
444
  }
445
445
 
446
- const TELEGRAM_LEADER_SESSION_HANDOFF_KEY =
447
- "__piTelegramLeaderSessionHandoff";
446
+ const TELEGRAM_LEADER_SESSION_HANDOFF_KEY = "__piTelegramLeaderSessionHandoff";
448
447
  export const TELEGRAM_LEADER_SESSION_HANDOFF_TTL_MS = 30_000;
449
448
 
450
449
  export interface TelegramLeaderSessionHandoff {
@@ -458,8 +457,7 @@ export interface TelegramLeaderSessionHandoff {
458
457
  }
459
458
 
460
459
  export function getTelegramLeaderSessionHandoff():
461
- | TelegramLeaderSessionHandoff
462
- | undefined {
460
+ TelegramLeaderSessionHandoff | undefined {
463
461
  const value = (globalThis as Record<string, unknown>)[
464
462
  TELEGRAM_LEADER_SESSION_HANDOFF_KEY
465
463
  ];
@@ -981,6 +979,18 @@ function parseTopicTargetFile(value: unknown): TelegramTopicTargetFile {
981
979
  };
982
980
  }
983
981
 
982
+ function serializeTelegramStateSemanticSnapshot(
983
+ value: unknown,
984
+ ): string | undefined {
985
+ if (!value || typeof value !== "object" || Array.isArray(value))
986
+ return undefined;
987
+ const { writtenAtMs: _writtenAtMs, ...semantic } = value as Record<
988
+ string,
989
+ unknown
990
+ >;
991
+ return JSON.stringify(semantic);
992
+ }
993
+
984
994
  function targetMatches(left: TelegramTarget, right: TelegramTarget): boolean {
985
995
  return left.chatId === right.chatId && left.threadId === right.threadId;
986
996
  }
@@ -1083,6 +1093,7 @@ export function createTelegramTopicTargetStore(
1083
1093
  let loadedPath: string | undefined;
1084
1094
  let dirty = false;
1085
1095
  let mutationRevision = 0;
1096
+ let statusRevision = 0;
1086
1097
  let persistQueue: Promise<void> = Promise.resolve();
1087
1098
  let statusSnapshot: {
1088
1099
  runtime?: Record<string, unknown>;
@@ -1245,6 +1256,7 @@ export function createTelegramTopicTargetStore(
1245
1256
  ]),
1246
1257
  );
1247
1258
  const persistedRevision = mutationRevision;
1259
+ const persistedStatusRevision = statusRevision;
1248
1260
  const file = {
1249
1261
  version: 1,
1250
1262
  source: "snapshot",
@@ -1266,6 +1278,24 @@ export function createTelegramTopicTargetStore(
1266
1278
  return serialized;
1267
1279
  }),
1268
1280
  };
1281
+ let persistedSemanticSnapshot: string | undefined;
1282
+ try {
1283
+ persistedSemanticSnapshot = serializeTelegramStateSemanticSnapshot(
1284
+ JSON.parse(await readFile(path, "utf8")),
1285
+ );
1286
+ } catch {
1287
+ /* missing or invalid snapshots must be replaced */
1288
+ }
1289
+ if (
1290
+ persistedSemanticSnapshot ===
1291
+ serializeTelegramStateSemanticSnapshot(file) &&
1292
+ mutationRevision === persistedRevision &&
1293
+ statusRevision === persistedStatusRevision
1294
+ ) {
1295
+ loaded = true;
1296
+ dirty = false;
1297
+ return;
1298
+ }
1269
1299
  await writeFile(tempPath, `${JSON.stringify(file, null, 2)}\n`, {
1270
1300
  encoding: "utf8",
1271
1301
  mode: 0o600,
@@ -1407,6 +1437,7 @@ export function createTelegramTopicTargetStore(
1407
1437
  setStatusSnapshot(snapshot) {
1408
1438
  if (!loadedPath) loadedPath = getPath();
1409
1439
  statusSnapshot = { ...snapshot };
1440
+ statusRevision += 1;
1410
1441
  },
1411
1442
  getByProfileKey(profileKey) {
1412
1443
  const ownerKey = getTelegramThreadOwnerKey(
@@ -2025,13 +2056,16 @@ export async function provisionOwnBusTopic(
2025
2056
  ) {
2026
2057
  const existingHandoffRecord = deps.store
2027
2058
  .list()
2028
- .find((record) => targetMatches(record.target, leaderSessionHandoff.target));
2059
+ .find((record) =>
2060
+ targetMatches(record.target, leaderSessionHandoff.target),
2061
+ );
2029
2062
  deps.store.upsert({
2030
2063
  profileKey,
2031
2064
  owner: currentLeaderOwner,
2032
2065
  target: { ...leaderSessionHandoff.target },
2033
2066
  status: "active",
2034
- createdAtMs: existingHandoffRecord?.createdAtMs ?? leaderSessionHandoff.createdAtMs,
2067
+ createdAtMs:
2068
+ existingHandoffRecord?.createdAtMs ?? leaderSessionHandoff.createdAtMs,
2035
2069
  updatedAtMs: nowMs,
2036
2070
  threadName:
2037
2071
  existingHandoffRecord?.threadName ?? leaderSessionHandoff.threadName,
@@ -2042,8 +2076,7 @@ export async function provisionOwnBusTopic(
2042
2076
  : {}),
2043
2077
  ...(existingHandoffRecord?.lastSyncObservedAtMs !== undefined
2044
2078
  ? {
2045
- lastSyncObservedAtMs:
2046
- existingHandoffRecord.lastSyncObservedAtMs,
2079
+ lastSyncObservedAtMs: existingHandoffRecord.lastSyncObservedAtMs,
2047
2080
  }
2048
2081
  : {}),
2049
2082
  lastReconcileAction: "leader-session-handoff-restored",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-telegram",
3
- "version": "0.24.0",
3
+ "version": "0.24.1",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"