@llblab/pi-telegram 0.50.1 → 0.51.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/AGENTS.md +10 -8
- package/BACKLOG.md +13 -32
- package/CHANGELOG.md +16 -0
- package/README.md +4 -3
- package/dist/lib/bindings.d.ts +4 -2
- package/dist/lib/bindings.js +5 -5
- package/dist/lib/bus-follower.d.ts +4 -2
- package/dist/lib/bus-follower.js +99 -10
- package/dist/lib/bus-leader.d.ts +9 -3
- package/dist/lib/bus-leader.js +231 -71
- package/dist/lib/bus.d.ts +4 -0
- package/dist/lib/bus.js +34 -7
- package/dist/lib/commands.d.ts +5 -0
- package/dist/lib/commands.js +9 -0
- package/dist/lib/extension.js +68 -3
- package/dist/lib/journal.d.ts +3 -0
- package/dist/lib/journal.js +13 -0
- package/dist/lib/lifecycle.d.ts +2 -0
- package/dist/lib/lifecycle.js +25 -4
- package/dist/lib/locks.d.ts +1 -0
- package/dist/lib/locks.js +32 -12
- package/dist/lib/paths.d.ts +10 -0
- package/dist/lib/paths.js +22 -1
- package/dist/lib/polling.js +2 -2
- package/dist/lib/queue.d.ts +9 -1
- package/dist/lib/queue.js +64 -13
- package/dist/lib/replies.d.ts +4 -0
- package/dist/lib/replies.js +14 -0
- package/dist/lib/routing.d.ts +1 -0
- package/dist/lib/routing.js +5 -0
- package/dist/lib/sync.d.ts +9 -0
- package/dist/lib/sync.js +41 -1
- package/dist/lib/telegram-api.d.ts +9 -1
- package/dist/lib/telegram-api.js +23 -3
- package/dist/lib/thread-cleanup-manager.js +7 -2
- package/dist/lib/threads.d.ts +2 -0
- package/dist/lib/threads.js +68 -37
- package/dist/lib/updates.d.ts +6 -4
- package/dist/lib/updates.js +134 -61
- package/dist/lib/workspace-admission.d.ts +9 -0
- package/dist/lib/workspace-admission.js +49 -3
- package/dist/lib/workspace-retirement.d.ts +77 -6
- package/dist/lib/workspace-retirement.js +384 -8
- package/dist/lib/workspace-slots.d.ts +3 -0
- package/dist/lib/workspace-slots.js +6 -0
- package/dist/package.json +1 -1
- package/docs/architecture.md +22 -15
- package/docs/multi-instance-bus.md +32 -11
- package/docs/public-api.md +1 -1
- package/docs/updates.md +2 -0
- package/lib/bindings.ts +12 -7
- package/lib/bus-follower.ts +82 -14
- package/lib/bus-leader.ts +236 -94
- package/lib/bus.ts +39 -9
- package/lib/commands.ts +19 -0
- package/lib/extension.ts +78 -2
- package/lib/journal.ts +14 -0
- package/lib/lifecycle.ts +23 -4
- package/lib/locks.ts +32 -13
- package/lib/paths.ts +29 -1
- package/lib/polling.ts +2 -2
- package/lib/queue.ts +77 -19
- package/lib/replies.ts +18 -0
- package/lib/routing.ts +7 -0
- package/lib/sync.ts +45 -1
- package/lib/telegram-api.ts +30 -2
- package/lib/thread-cleanup-manager.ts +11 -3
- package/lib/threads.ts +73 -36
- package/lib/updates.ts +145 -78
- package/lib/workspace-admission.ts +67 -4
- package/lib/workspace-retirement.ts +465 -7
- package/lib/workspace-slots.ts +7 -0
- package/package.json +1 -1
package/dist/lib/bus-follower.js
CHANGED
|
@@ -9,6 +9,7 @@ import { basename } from "node:path";
|
|
|
9
9
|
import * as Sync from "./sync.js";
|
|
10
10
|
import * as Threads from "./threads.js";
|
|
11
11
|
import { parseTelegramUpdateJournalQueueOwner } from "./journal.js";
|
|
12
|
+
import { TELEGRAM_BUS_LEADER_STALE_HEARTBEAT_MS, } from "./locks.js";
|
|
12
13
|
import { isTelegramApiMethodRetrySafe, TelegramApiCommitUnknownError, TelegramApiStaleTargetError, } from "./telegram-api.js";
|
|
13
14
|
import { createTelegramBusFollowerDeliveryIdentity, createTelegramBusFollowerTargetController, createTelegramBusForeignOwnedUpdateForwarder, createTelegramBusLocalServer, createTelegramBusRequestIdFactory, createUnauthorizedBusAck, getTelegramBusProtocolCompatibility, getTelegramBusSocketPath, hasTelegramBusCapability, isTelegramBusEnvelopeAuthorized, resolveTelegramBusSocketPath, sendTelegramBusLocalEnvelope, TELEGRAM_BUS_CAPABILITY_WORKSPACE_THREAD_RENAME, TELEGRAM_BUS_CAPABILITY_THREAD_DISPLAY_MODE, TELEGRAM_BUS_CAPABILITY_DIRECTORY_DISPLAY_FORMAT, } from "./bus.js";
|
|
14
15
|
import { getTelegramBusTransportRetryPolicy, TELEGRAM_BUS_REGISTRATION_RETRY, } from "./bus-transport.js";
|
|
@@ -17,6 +18,7 @@ export const TELEGRAM_BUS_FOLLOWER_PROMOTION_GRACE_MS = 2_500;
|
|
|
17
18
|
export const TELEGRAM_FOLLOWER_SESSION_HANDOFF_TTL_MS = 30_000;
|
|
18
19
|
export const TELEGRAM_BUS_FOLLOWER_CLIENT_TIMEOUT_MS = 30_000;
|
|
19
20
|
export const TELEGRAM_BUS_FOLLOWER_REGISTRATION_WAIT_MS = 30_000;
|
|
21
|
+
export const TELEGRAM_BUS_FOLLOWER_HEARTBEAT_TIMEOUT_MS = TELEGRAM_BUS_LEADER_STALE_HEARTBEAT_MS;
|
|
20
22
|
export const TELEGRAM_BUS_FOLLOWER_REGISTRATION_RETRY_ATTEMPTS = TELEGRAM_BUS_REGISTRATION_RETRY.attempts;
|
|
21
23
|
export const TELEGRAM_BUS_FOLLOWER_REGISTRATION_RETRY_DELAY_MS = TELEGRAM_BUS_REGISTRATION_RETRY.delayMs;
|
|
22
24
|
const TELEGRAM_FOLLOWER_SESSION_HANDOFF_KEY = "__piTelegramFollowerSessionHandoff";
|
|
@@ -139,6 +141,23 @@ export function createTelegramBusFollowerPromotionHandler(input) {
|
|
|
139
141
|
});
|
|
140
142
|
}
|
|
141
143
|
export function createTelegramBusFollowerRuntimeAssembly(ports) {
|
|
144
|
+
// Binding startup needs registration identity before it can grant inbound authority.
|
|
145
|
+
let readyContext;
|
|
146
|
+
const isReadyContext = (ctx) => Boolean(readyContext &&
|
|
147
|
+
(ctx === undefined || readyContext.ctx === ctx) &&
|
|
148
|
+
ports.registrationState.getGeneration() === readyContext.generation &&
|
|
149
|
+
ports.registration.getSessionGeneration?.() === readyContext.sessionGeneration &&
|
|
150
|
+
ports.registration.isContextActive?.(readyContext.ctx) !== false);
|
|
151
|
+
const prepareContext = async (ctx) => {
|
|
152
|
+
const generation = ports.registrationState.getGeneration();
|
|
153
|
+
const sessionGeneration = ports.registration.getSessionGeneration?.();
|
|
154
|
+
readyContext = undefined;
|
|
155
|
+
await ports.registration.onRegistered?.(ctx);
|
|
156
|
+
if (generation && ports.registrationState.getGeneration() === generation &&
|
|
157
|
+
ports.registration.getSessionGeneration?.() === sessionGeneration &&
|
|
158
|
+
ports.registration.isContextActive?.(ctx) !== false)
|
|
159
|
+
readyContext = { generation, ctx, sessionGeneration };
|
|
160
|
+
};
|
|
142
161
|
const sharedRuntimeDeps = {
|
|
143
162
|
instanceId: ports.instanceId,
|
|
144
163
|
registrationState: ports.registrationState,
|
|
@@ -148,7 +167,9 @@ export function createTelegramBusFollowerRuntimeAssembly(ports) {
|
|
|
148
167
|
...ports.receiver,
|
|
149
168
|
instanceId: ports.instanceId,
|
|
150
169
|
recordRuntimeEvent: ports.recordRuntimeEvent,
|
|
151
|
-
getRegistrationGeneration
|
|
170
|
+
getRegistrationGeneration() {
|
|
171
|
+
return isReadyContext() ? readyContext?.generation : undefined;
|
|
172
|
+
},
|
|
152
173
|
handleReplaceTarget: createTelegramBusFollowerTargetReplacementHandler({
|
|
153
174
|
...ports.targetReplacement,
|
|
154
175
|
...sharedRuntimeDeps,
|
|
@@ -166,8 +187,24 @@ export function createTelegramBusFollowerRuntimeAssembly(ports) {
|
|
|
166
187
|
...sharedRuntimeDeps,
|
|
167
188
|
startReceiving: receiver.start,
|
|
168
189
|
stopReceiving: receiver.stop,
|
|
190
|
+
onRegistered: prepareContext,
|
|
169
191
|
onHeartbeatFailure: recovery,
|
|
170
192
|
});
|
|
193
|
+
const baseRegistration = registration;
|
|
194
|
+
registration = {
|
|
195
|
+
...baseRegistration,
|
|
196
|
+
async setContext(ctx) {
|
|
197
|
+
const sessionGeneration = ports.registration.getSessionGeneration?.();
|
|
198
|
+
if (ports.registration.isContextActive?.(ctx) === false)
|
|
199
|
+
return;
|
|
200
|
+
await baseRegistration.setContext(ctx);
|
|
201
|
+
if (ports.registration.getSessionGeneration?.() !== sessionGeneration ||
|
|
202
|
+
ports.registration.isContextActive?.(ctx) === false)
|
|
203
|
+
return;
|
|
204
|
+
if (!isReadyContext(ctx))
|
|
205
|
+
await prepareContext(ctx);
|
|
206
|
+
},
|
|
207
|
+
};
|
|
171
208
|
return { receiver, registration };
|
|
172
209
|
}
|
|
173
210
|
export function createTelegramBusFollowerTargetReplacementHandler(deps) {
|
|
@@ -575,7 +612,15 @@ export function createTelegramBusFollowerSessionRefreshHook(deps) {
|
|
|
575
612
|
return;
|
|
576
613
|
if (deps.isSessionActive && !deps.isSessionActive(ctx))
|
|
577
614
|
return;
|
|
578
|
-
|
|
615
|
+
try {
|
|
616
|
+
await deps.registrationRuntime.setContext(ctx);
|
|
617
|
+
}
|
|
618
|
+
catch (error) {
|
|
619
|
+
deps.recordRuntimeEvent("bus", error, { phase: "follower-session-refresh" });
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
if (deps.isSessionActive && !deps.isSessionActive(ctx))
|
|
623
|
+
return;
|
|
579
624
|
deps.updateStatus(ctx);
|
|
580
625
|
deps.recordRuntimeEvent("bus", "Telegram follower session context refreshed", { phase: "follower-session-refresh" });
|
|
581
626
|
};
|
|
@@ -877,6 +922,9 @@ export function createTelegramBusFollowerRegistrationRuntime(deps) {
|
|
|
877
922
|
const getNowMs = deps.getNowMs ?? Date.now;
|
|
878
923
|
const getPid = deps.getPid ?? (() => process.pid);
|
|
879
924
|
const heartbeatMs = deps.heartbeatMs ?? 1000;
|
|
925
|
+
const heartbeatTimeoutMs = deps.heartbeatTimeoutMs ??
|
|
926
|
+
deps.timeoutMs ??
|
|
927
|
+
TELEGRAM_BUS_FOLLOWER_HEARTBEAT_TIMEOUT_MS;
|
|
880
928
|
const registrationTimeoutMs = deps.registrationTimeoutMs ?? deps.timeoutMs ?? 30000;
|
|
881
929
|
const registrationRetryAttempts = deps.registrationRetryAttempts ??
|
|
882
930
|
TELEGRAM_BUS_FOLLOWER_REGISTRATION_RETRY_ATTEMPTS;
|
|
@@ -888,6 +936,7 @@ export function createTelegramBusFollowerRegistrationRuntime(deps) {
|
|
|
888
936
|
let activeLeaderSocketPath;
|
|
889
937
|
let activeAuthSecret;
|
|
890
938
|
let activeRegistrationGeneration;
|
|
939
|
+
let registrationAttempt;
|
|
891
940
|
let activeContext;
|
|
892
941
|
let lastKnownTarget;
|
|
893
942
|
let lastKnownSlot;
|
|
@@ -899,6 +948,7 @@ export function createTelegramBusFollowerRegistrationRuntime(deps) {
|
|
|
899
948
|
heartbeatInterval = undefined;
|
|
900
949
|
};
|
|
901
950
|
const stop = () => {
|
|
951
|
+
registrationAttempt = undefined;
|
|
902
952
|
stopHeartbeat();
|
|
903
953
|
activeAuthSecret = undefined;
|
|
904
954
|
activeRegistrationGeneration = undefined;
|
|
@@ -934,7 +984,7 @@ export function createTelegramBusFollowerRegistrationRuntime(deps) {
|
|
|
934
984
|
try {
|
|
935
985
|
const response = await sendTelegramBusLocalEnvelope({
|
|
936
986
|
socketPath: leaderSocketPath,
|
|
937
|
-
timeoutMs:
|
|
987
|
+
timeoutMs: heartbeatTimeoutMs,
|
|
938
988
|
retry: getTelegramBusTransportRetryPolicy({
|
|
939
989
|
endpoint: leaderSocketPath,
|
|
940
990
|
operation: "operation",
|
|
@@ -1027,6 +1077,26 @@ export function createTelegramBusFollowerRegistrationRuntime(deps) {
|
|
|
1027
1077
|
};
|
|
1028
1078
|
return {
|
|
1029
1079
|
registerWithLeader: async (ctx, leader, options) => {
|
|
1080
|
+
if (deps.isContextActive?.(ctx) === false)
|
|
1081
|
+
return false;
|
|
1082
|
+
const sessionGeneration = deps.getSessionGeneration?.();
|
|
1083
|
+
const attempt = { ctx, sessionGeneration };
|
|
1084
|
+
registrationAttempt = attempt;
|
|
1085
|
+
const isCurrentRequest = () => registrationAttempt === attempt &&
|
|
1086
|
+
deps.getSessionGeneration?.() === sessionGeneration && deps.isContextActive?.(ctx) !== false;
|
|
1087
|
+
const abandonOwnedRequest = async () => {
|
|
1088
|
+
if (registrationAttempt !== attempt)
|
|
1089
|
+
return;
|
|
1090
|
+
registrationAttempt = undefined;
|
|
1091
|
+
stopHeartbeat();
|
|
1092
|
+
activeLeaderSocketPath = undefined;
|
|
1093
|
+
activeAuthSecret = undefined;
|
|
1094
|
+
activeRegistrationGeneration = undefined;
|
|
1095
|
+
activeContext = undefined;
|
|
1096
|
+
deps.registrationState?.setRegistered(false);
|
|
1097
|
+
deps.setActiveAuthSecret?.(undefined);
|
|
1098
|
+
await deps.stopReceiving?.();
|
|
1099
|
+
};
|
|
1030
1100
|
const pendingHandoff = options
|
|
1031
1101
|
? undefined
|
|
1032
1102
|
: getTelegramFollowerSessionHandoff();
|
|
@@ -1041,6 +1111,10 @@ export function createTelegramBusFollowerRegistrationRuntime(deps) {
|
|
|
1041
1111
|
deps.getLeaderSocketPath?.() ??
|
|
1042
1112
|
getTelegramBusSocketPath();
|
|
1043
1113
|
await deps.startReceiving?.();
|
|
1114
|
+
if (!isCurrentRequest()) {
|
|
1115
|
+
await abandonOwnedRequest();
|
|
1116
|
+
return false;
|
|
1117
|
+
}
|
|
1044
1118
|
activeAuthSecret = deps.getLeaderAuthSecret
|
|
1045
1119
|
? deps.getLeaderAuthSecret(leader)
|
|
1046
1120
|
: leader?.busSecret;
|
|
@@ -1070,7 +1144,7 @@ export function createTelegramBusFollowerRegistrationRuntime(deps) {
|
|
|
1070
1144
|
sessionId: deps.getSessionId?.(ctx),
|
|
1071
1145
|
pid: getPid(),
|
|
1072
1146
|
processBirthId: deps.getProcessBirthId?.(),
|
|
1073
|
-
sessionGeneration
|
|
1147
|
+
sessionGeneration,
|
|
1074
1148
|
target: registrationOptions?.target ??
|
|
1075
1149
|
deps.registrationState?.getTarget() ??
|
|
1076
1150
|
lastKnownTarget,
|
|
@@ -1103,6 +1177,10 @@ export function createTelegramBusFollowerRegistrationRuntime(deps) {
|
|
|
1103
1177
|
});
|
|
1104
1178
|
}
|
|
1105
1179
|
catch (error) {
|
|
1180
|
+
if (!isCurrentRequest()) {
|
|
1181
|
+
await abandonOwnedRequest();
|
|
1182
|
+
return false;
|
|
1183
|
+
}
|
|
1106
1184
|
stopHeartbeat();
|
|
1107
1185
|
activeLeaderSocketPath = undefined;
|
|
1108
1186
|
activeAuthSecret = undefined;
|
|
@@ -1111,12 +1189,8 @@ export function createTelegramBusFollowerRegistrationRuntime(deps) {
|
|
|
1111
1189
|
await deps.stopReceiving?.();
|
|
1112
1190
|
throw error;
|
|
1113
1191
|
}
|
|
1114
|
-
if (
|
|
1115
|
-
|
|
1116
|
-
activeLeaderSocketPath = undefined;
|
|
1117
|
-
activeAuthSecret = undefined;
|
|
1118
|
-
deps.setActiveAuthSecret?.(undefined);
|
|
1119
|
-
await deps.stopReceiving?.();
|
|
1192
|
+
if (!isCurrentRequest()) {
|
|
1193
|
+
await abandonOwnedRequest();
|
|
1120
1194
|
return false;
|
|
1121
1195
|
}
|
|
1122
1196
|
const compatibility = getTelegramBusProtocolCompatibility({
|
|
@@ -1164,6 +1238,10 @@ export function createTelegramBusFollowerRegistrationRuntime(deps) {
|
|
|
1164
1238
|
await deps.onRegistered?.(ctx);
|
|
1165
1239
|
}
|
|
1166
1240
|
catch (error) {
|
|
1241
|
+
if (!isCurrentRequest()) {
|
|
1242
|
+
await abandonOwnedRequest();
|
|
1243
|
+
return false;
|
|
1244
|
+
}
|
|
1167
1245
|
stopHeartbeat();
|
|
1168
1246
|
activeLeaderSocketPath = undefined;
|
|
1169
1247
|
activeAuthSecret = undefined;
|
|
@@ -1173,7 +1251,15 @@ export function createTelegramBusFollowerRegistrationRuntime(deps) {
|
|
|
1173
1251
|
await deps.stopReceiving?.();
|
|
1174
1252
|
throw error;
|
|
1175
1253
|
}
|
|
1254
|
+
if (!isCurrentRequest()) {
|
|
1255
|
+
await abandonOwnedRequest();
|
|
1256
|
+
return false;
|
|
1257
|
+
}
|
|
1176
1258
|
await requestHeartbeat();
|
|
1259
|
+
if (!isCurrentRequest()) {
|
|
1260
|
+
await abandonOwnedRequest();
|
|
1261
|
+
return false;
|
|
1262
|
+
}
|
|
1177
1263
|
startHeartbeat(leaderSocketPath);
|
|
1178
1264
|
if (pendingHandoffOptions &&
|
|
1179
1265
|
getTelegramFollowerSessionHandoff()?.instanceId ===
|
|
@@ -1191,6 +1277,9 @@ export function createTelegramBusFollowerRegistrationRuntime(deps) {
|
|
|
1191
1277
|
return false;
|
|
1192
1278
|
},
|
|
1193
1279
|
setContext(ctx) {
|
|
1280
|
+
if (registrationAttempt && (registrationAttempt.ctx !== ctx ||
|
|
1281
|
+
registrationAttempt.sessionGeneration !== deps.getSessionGeneration?.()))
|
|
1282
|
+
registrationAttempt = undefined;
|
|
1194
1283
|
activeContext = ctx;
|
|
1195
1284
|
},
|
|
1196
1285
|
async setThreadDisplayMode(mode) {
|
package/dist/lib/bus-leader.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type { TelegramTarget } from "./target.ts";
|
|
|
12
12
|
import * as Threads from "./threads.ts";
|
|
13
13
|
import { type TelegramBusEnvelope, type TelegramBusFollowerRegistry, type TelegramBusFollowerView, type TelegramBusInstanceRegistration, type TelegramBusProtocolIdentity, type TelegramBusSocketPathSource } from "./bus.ts";
|
|
14
14
|
import type { TelegramQueueHandoffPayload } from "./queue.ts";
|
|
15
|
-
import { type TelegramWorkspaceOperationRunner } from "./workspace-retirement.ts";
|
|
15
|
+
import { type TelegramWorkspaceCapacityRunner, type TelegramWorkspaceSlotRotationPorts, type TelegramWorkspaceOperationRunner } from "./workspace-retirement.ts";
|
|
16
16
|
import { type TelegramWorkspaceAdmissionLedger } from "./workspace-admission.ts";
|
|
17
17
|
export declare const TELEGRAM_BUS_FOLLOWER_STALE_AFTER_MS = 15000;
|
|
18
18
|
export type TelegramBusWorkspaceAdmissionRunner = TelegramWorkspaceOperationRunner;
|
|
@@ -90,7 +90,7 @@ export interface TelegramBusFollowerTargetProvisionerDeps {
|
|
|
90
90
|
recordRuntimeEvent: (category: string, error: unknown, details?: Record<string, unknown>) => void;
|
|
91
91
|
}
|
|
92
92
|
export interface TelegramBusFollowerDisconnectHandlerDeps {
|
|
93
|
-
topicTargetStore: Pick<Threads.TelegramTopicTargetStore, "list" | "markStaleByTarget" | "
|
|
93
|
+
topicTargetStore: Pick<Threads.TelegramTopicTargetStore, "list" | "markStaleByTarget" | "persist" | "upsertPendingCleanup" | "removePendingCleanup">;
|
|
94
94
|
callApi: <TResponse>(method: string, body: Record<string, unknown>) => Promise<TResponse>;
|
|
95
95
|
getCurrentLeaderEpoch?: () => number | string | undefined;
|
|
96
96
|
getSyncState: () => Sync.TelegramSyncState;
|
|
@@ -108,7 +108,7 @@ export interface TelegramBusLeaderRuntimeAssemblyDeps<TContext> {
|
|
|
108
108
|
getThreadDisplayMode?: () => TelegramThreadDisplayMode;
|
|
109
109
|
persistThreadDisplayMode?: (mode: TelegramThreadDisplayMode, isCurrent: () => boolean) => Promise<void>;
|
|
110
110
|
onThreadDisplayChanged?: () => void;
|
|
111
|
-
runtime: Omit<TelegramBusLeaderRuntimeDeps<TContext>, "callApi" | "onFollowerDisconnected" | "onFollowerConfirmedDead" | "provisionFollowerTarget" | "provisionLeaderTarget" | "recordRuntimeEvent">;
|
|
111
|
+
runtime: Omit<TelegramBusLeaderRuntimeDeps<TContext>, "callApi" | "onFollowerDisconnected" | "onFollowerConfirmedDead" | "onFollowerConfirmedDeadPreserved" | "getTelegramProfile" | "provisionFollowerTarget" | "provisionLeaderTarget" | "recordRuntimeEvent">;
|
|
112
112
|
getAllowedUserId: () => number | undefined;
|
|
113
113
|
instanceId: string;
|
|
114
114
|
getCwd?: (ctx: TContext) => string | undefined;
|
|
@@ -133,6 +133,7 @@ export interface TelegramBusLeaderRuntimeAssemblyDeps<TContext> {
|
|
|
133
133
|
captureWorkspaceExternalProtection?: (binding: Threads.TelegramWorkspaceThreadBinding) => Threads.TelegramWorkspaceExternalProtectionEvidence;
|
|
134
134
|
getWorkspaceAdmission?: () => Pick<TelegramWorkspaceAdmissionLedger, "acquireAdmission" | "releaseAdmission"> | undefined;
|
|
135
135
|
runWorkspaceOperation?: TelegramBusWorkspaceAdmissionRunner;
|
|
136
|
+
workspaceRotation?: TelegramWorkspaceSlotRotationPorts;
|
|
136
137
|
}
|
|
137
138
|
export declare function createTelegramBusLeaderRuntimeAssembly<TContext>(deps: TelegramBusLeaderRuntimeAssemblyDeps<TContext>): TelegramBusLeaderRuntime<TContext> & {
|
|
138
139
|
renameLeaderThreadAdmitted: (threadName: string, expectedTarget?: Threads.TelegramTopicTargetRecord["target"]) => Promise<Threads.TelegramTopicTargetRecord>;
|
|
@@ -192,8 +193,10 @@ export interface TelegramBusLeaderRuntimeDeps<TContext> {
|
|
|
192
193
|
applyThreadDisplayMode?: (mode: TelegramThreadDisplayMode, isCurrent: () => boolean) => Promise<void>;
|
|
193
194
|
getThreadDisplayMode?: () => TelegramThreadDisplayMode;
|
|
194
195
|
getCurrentLeaderEpoch?: () => number | string | undefined;
|
|
196
|
+
getTelegramProfile?: () => string | undefined;
|
|
195
197
|
provisionLeaderTarget?: (ctx: TContext) => Promise<void> | void;
|
|
196
198
|
runWorkspaceAdmission?: TelegramBusWorkspaceAdmissionRunner;
|
|
199
|
+
runWithWorkspaceCapacity?: TelegramWorkspaceCapacityRunner;
|
|
197
200
|
getNowMs?: () => number;
|
|
198
201
|
timeoutMs?: number;
|
|
199
202
|
followerPruneIntervalMs?: number;
|
|
@@ -202,6 +205,8 @@ export interface TelegramBusLeaderRuntimeDeps<TContext> {
|
|
|
202
205
|
shouldCleanupConfirmedDeadFollower?: () => Promise<boolean> | boolean;
|
|
203
206
|
onFollowerDisconnected?: (follower: TelegramBusFollowerView) => Promise<void> | void;
|
|
204
207
|
onFollowerConfirmedDead?: (follower: TelegramBusFollowerView) => Promise<void> | void;
|
|
208
|
+
/** True settles this observation; false needs fresh proof before another attempt. */
|
|
209
|
+
onFollowerConfirmedDeadPreserved?: (follower: TelegramBusFollowerView, isDetached: () => boolean, operationId: string) => Promise<boolean> | boolean;
|
|
205
210
|
recordRuntimeEvent?: (category: string, error: unknown, details?: Record<string, unknown>) => void;
|
|
206
211
|
}
|
|
207
212
|
export declare function createTelegramBusInstanceLifecycleAnnouncement(input: {
|
|
@@ -275,6 +280,7 @@ export declare function createTelegramBusLeaderEnvelopeHandler(deps: {
|
|
|
275
280
|
getCurrentLeaderEpoch?: () => number | string | undefined;
|
|
276
281
|
runFollowerMutation?: TelegramBusFollowerMutationRunner;
|
|
277
282
|
runWorkspaceAdmission?: TelegramBusWorkspaceAdmissionRunner;
|
|
283
|
+
runWithWorkspaceCapacity?: TelegramWorkspaceCapacityRunner;
|
|
278
284
|
}): (envelope: TelegramBusEnvelope) => Promise<TelegramBusEnvelope> | TelegramBusEnvelope;
|
|
279
285
|
export interface TelegramBusLeaderActivationSchedulerDeps<TContext> {
|
|
280
286
|
isBusEnabled: () => boolean;
|