@deepmaid/maid-state 0.0.0-stage → 0.1.0-alpha.2
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/LICENSE +21 -0
- package/lib/index.d.ts +411 -0
- package/lib/index.js +1113 -0
- package/package.json +24 -3
- package/README.md +0 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 kenyonxu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
//#region src/protocol.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* maid-state 协议信封(阶段规格 §6,2026-11-06):传输无关的命令/快照/回执三件套。
|
|
4
|
+
* 稳定性纪律:
|
|
5
|
+
* - turn eventId 派生命名空间 'emotion.turn.v1' 与 commandHash 的语义字段集都**不随
|
|
6
|
+
* 线 protocolVersion 变化**(升级后重放旧命令不得被当成新事件/新冲突);
|
|
7
|
+
* - canonicalJson 键排序用代码点比较,不用 localeCompare(ICU 随构建漂移会破哈希稳定性)。
|
|
8
|
+
*/
|
|
9
|
+
declare const PROTOCOL_VERSION = 1;
|
|
10
|
+
type EventKind = 'emotion.settle_turn' | 'emotion.apply_deltas';
|
|
11
|
+
interface StateCommand<P = unknown> {
|
|
12
|
+
protocolVersion: number;
|
|
13
|
+
eventId: string;
|
|
14
|
+
hostId: string;
|
|
15
|
+
maidId: string;
|
|
16
|
+
kind: EventKind;
|
|
17
|
+
occurredAt: number;
|
|
18
|
+
sourceConfigRevision: string;
|
|
19
|
+
payload: P;
|
|
20
|
+
}
|
|
21
|
+
interface StateSnapshot<S, C> {
|
|
22
|
+
maidId: string;
|
|
23
|
+
stateRevision: number;
|
|
24
|
+
configRevision: string;
|
|
25
|
+
serverTime: number;
|
|
26
|
+
state: S;
|
|
27
|
+
config: C;
|
|
28
|
+
}
|
|
29
|
+
interface CommandReceipt<S, C> {
|
|
30
|
+
eventId: string;
|
|
31
|
+
status: 'applied' | 'duplicate' | 'rejected';
|
|
32
|
+
appliedRevision: number | null;
|
|
33
|
+
snapshot: StateSnapshot<S, C> | null;
|
|
34
|
+
errorCode: string | null;
|
|
35
|
+
}
|
|
36
|
+
/** 传输接缝(in-memory 假件与 HTTPS+mTLS 实现同面;maid-state 不认识具体 domain) */
|
|
37
|
+
interface StateTransport<S, C> {
|
|
38
|
+
getSnapshot(maidId: string): Promise<StateSnapshot<S, C>>;
|
|
39
|
+
submit(command: StateCommand): Promise<CommandReceipt<S, C>>;
|
|
40
|
+
}
|
|
41
|
+
/** 稳定机器码错误(规格 §11:永久协议错误与临时网络错误必须分开) */
|
|
42
|
+
declare class StateCommandError extends Error {
|
|
43
|
+
readonly code: string;
|
|
44
|
+
constructor(code: string, message: string);
|
|
45
|
+
}
|
|
46
|
+
/** 确定性 JSON 序列化:键代码点排序、剔除 undefined;数字/字符串走 JSON 标准形态 */
|
|
47
|
+
declare function canonicalJson(value: unknown): string;
|
|
48
|
+
declare function revisionOf(value: unknown): string;
|
|
49
|
+
/** UUIDv7(时间有序,重试语义友好);eventId 手势/重逢/补偿通道使用 */
|
|
50
|
+
declare function newEventId(now?: number): string;
|
|
51
|
+
/** turn 命令稳定身份:turnKey 派生(规格 §6.1),宿主会话/轮次重放复用同一 eventId */
|
|
52
|
+
declare function turnEventId(input: {
|
|
53
|
+
hostId: string;
|
|
54
|
+
sessionId: string;
|
|
55
|
+
turn: number;
|
|
56
|
+
}): string;
|
|
57
|
+
/** 语义命令哈希:只覆盖领域语义字段,不含 protocolVersion/传输元数据(规格 §6.1) */
|
|
58
|
+
declare function commandHash(command: StateCommand): string;
|
|
59
|
+
/** 入站命令形状守卫(规格 §6.1):协议版本/必填串/有限时间/payload 对象 */
|
|
60
|
+
declare function assertStateCommand(value: unknown): asserts value is StateCommand;
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region src/lock.d.ts
|
|
63
|
+
/**
|
|
64
|
+
* server 数据目录排他锁(maid-state 阶段规格 §10.1):防第二活跃实例双写同库。
|
|
65
|
+
* - 锁体 {pid, startedAt, heartbeatAt},heartbeat 5s 刷新(unref,不阻进程退出);
|
|
66
|
+
* - 回收判定按持锁进程存活性:PID 已死(ESRCH)→ 回收;活进程(含 EPERM)→ 一律拒绝,
|
|
67
|
+
* 即便 heartbeat 过期也不抢(挂死服务器留给人工处置,不引入双开风险);
|
|
68
|
+
* - Windows 不改 ACL,目录边界由宿主用户目录承担(部署文档声明)。
|
|
69
|
+
*/
|
|
70
|
+
interface DataDirLock {
|
|
71
|
+
readonly pid: number;
|
|
72
|
+
/** 停止 heartbeat 并删除自持锁文件(幂等) */
|
|
73
|
+
release(): void;
|
|
74
|
+
}
|
|
75
|
+
declare function acquireDataDirLock(dataDir: string): DataDirLock;
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/authority-store.d.ts
|
|
78
|
+
/**
|
|
79
|
+
* 权威事务存储(maid-state 阶段规格 §6.3/§10.1):SQLite 单库承载 maid 状态、revision、
|
|
80
|
+
* 事件回执与 meta(authorityId/协议版本)。纪律:
|
|
81
|
+
* - 状态更新、revision、事件去重记录**同事务**(write 方法仅可在 transaction() 内调用);
|
|
82
|
+
* - 第二活跃实例经数据目录排他锁拒绝;死 PID 残留锁回收;
|
|
83
|
+
* - readOnly 形态供运行中 server 的只读 CLI(status/events/export):不开写锁、禁止事务;
|
|
84
|
+
* - S 为不透明状态(domain 负责形状);存储层只做 JSON 序列化。
|
|
85
|
+
*/
|
|
86
|
+
interface StoredAuthorityState<S> {
|
|
87
|
+
state: S;
|
|
88
|
+
revision: number;
|
|
89
|
+
}
|
|
90
|
+
interface StoredReceipt {
|
|
91
|
+
maidId: string;
|
|
92
|
+
eventId: string;
|
|
93
|
+
commandHash: string;
|
|
94
|
+
hostId: string;
|
|
95
|
+
kind: string;
|
|
96
|
+
occurredAt: number;
|
|
97
|
+
receivedAt: number;
|
|
98
|
+
effectiveAt: number | null;
|
|
99
|
+
sourceConfigRevision: string;
|
|
100
|
+
appliedConfigRevision: string;
|
|
101
|
+
status: string;
|
|
102
|
+
appliedRevision: number | null;
|
|
103
|
+
errorCode: string | null;
|
|
104
|
+
audit: Record<string, unknown>;
|
|
105
|
+
}
|
|
106
|
+
interface AuthorityTransaction<S> {
|
|
107
|
+
readState(maidId: string): StoredAuthorityState<S> | undefined;
|
|
108
|
+
writeState(maidId: string, value: StoredAuthorityState<S>): void;
|
|
109
|
+
readReceipt(maidId: string, eventId: string): StoredReceipt | undefined;
|
|
110
|
+
writeReceipt(receipt: StoredReceipt): void;
|
|
111
|
+
}
|
|
112
|
+
interface ListEventsFilter {
|
|
113
|
+
maidId?: string;
|
|
114
|
+
afterRevision?: number;
|
|
115
|
+
limit: number;
|
|
116
|
+
}
|
|
117
|
+
interface AuthorityStore<S> extends AuthorityTransaction<S> {
|
|
118
|
+
readonly authorityId: string;
|
|
119
|
+
transaction<T>(fn: (tx: AuthorityTransaction<S>) => T): T;
|
|
120
|
+
listEvents(filter: ListEventsFilter): StoredReceipt[];
|
|
121
|
+
exportStates(): Record<string, StoredAuthorityState<S>>;
|
|
122
|
+
close(): void;
|
|
123
|
+
}
|
|
124
|
+
interface OpenAuthorityStoreOptions {
|
|
125
|
+
dataDir: string;
|
|
126
|
+
/** 只读形态(CLI status/events/export):不取排他锁、禁止事务/写方法 */
|
|
127
|
+
readOnly?: boolean;
|
|
128
|
+
}
|
|
129
|
+
declare function openAuthorityStore<S>(options: OpenAuthorityStoreOptions): AuthorityStore<S>;
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/authority.d.ts
|
|
132
|
+
/**
|
|
133
|
+
* per-maid 权威服务(maid-state 阶段规格 §4.2/§8.2):领域无关的串行结算与幂等层。
|
|
134
|
+
* - StateDomain 是 domain 接缝(emotion/未来 world 各自实现 apply/config/fresh);
|
|
135
|
+
* - 同 maid 全部写命令经 Promise 链串行,不同 maid 并行;
|
|
136
|
+
* - 幂等键 (maidId,eventId):applied+同 hash → duplicate(返回当前快照,不用陈旧历史快照
|
|
137
|
+
* 覆盖);rejected+同 hash → 原样复述;任意 status+异 hash → EVENT_ID_CONFLICT;
|
|
138
|
+
* - StateCommandError = 永久拒绝(落 rejected 回执、不动状态、不推进 revision);
|
|
139
|
+
* 未知异常向上抛(传输层转临时 500),链尾兜底 catch 防一次失败毒死后续。
|
|
140
|
+
*/
|
|
141
|
+
interface StateDomain<S, C> {
|
|
142
|
+
/** maid 配置(权威配置源);undefined = 未注册 maid(UNKNOWN_MAID) */
|
|
143
|
+
config(maidId: string): {
|
|
144
|
+
config: C;
|
|
145
|
+
configRevision: string;
|
|
146
|
+
} | undefined;
|
|
147
|
+
fresh(maidId: string, config: C): S;
|
|
148
|
+
apply(input: {
|
|
149
|
+
state: S;
|
|
150
|
+
command: StateCommand;
|
|
151
|
+
config: C;
|
|
152
|
+
receivedAt: number;
|
|
153
|
+
}): {
|
|
154
|
+
state: S;
|
|
155
|
+
effectiveAt: number;
|
|
156
|
+
audit: Record<string, unknown>;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
declare class StateAuthority<S, C> {
|
|
160
|
+
#private;
|
|
161
|
+
private readonly store;
|
|
162
|
+
private readonly domain;
|
|
163
|
+
private readonly now;
|
|
164
|
+
readonly authorityId: string;
|
|
165
|
+
constructor(store: AuthorityStore<S>, domain: StateDomain<S, C>, now: () => number);
|
|
166
|
+
/** 当前权威快照;fresh 状态不落库、不推进 revision */
|
|
167
|
+
snapshot(maidId: string): StateSnapshot<S, C>;
|
|
168
|
+
submit(command: StateCommand): Promise<CommandReceipt<S, C>>;
|
|
169
|
+
private submitNow;
|
|
170
|
+
/** 拒绝回执:maidId 可用时持久化(幂等复述),不可用时(坏形状)仅返回 */
|
|
171
|
+
private reject;
|
|
172
|
+
/** 事务内快照(与公开 snapshot 同语义,读未提交的本事务写入) */
|
|
173
|
+
private snapshotInTx;
|
|
174
|
+
}
|
|
175
|
+
//#endregion
|
|
176
|
+
//#region src/tls.d.ts
|
|
177
|
+
/**
|
|
178
|
+
* TLS 材料装载与身份映射(maid-state 阶段规格 §10.3):
|
|
179
|
+
* - 证书/私钥/CA 从文件读入(server 与 client 各自持有);
|
|
180
|
+
* - fingerprint 归一化(去冒号、大写)后比对,client 身份只信证书,不信 body 自报;
|
|
181
|
+
* - allowMaids 是 host→maid 授权面(缺省 = 全部已注册 maid)。
|
|
182
|
+
*/
|
|
183
|
+
interface ClientIdentity {
|
|
184
|
+
hostId: string;
|
|
185
|
+
fingerprint256: string;
|
|
186
|
+
allowMaids?: readonly string[];
|
|
187
|
+
}
|
|
188
|
+
interface TlsServerConfig {
|
|
189
|
+
keyFile: string;
|
|
190
|
+
certFile: string;
|
|
191
|
+
caFile: string;
|
|
192
|
+
clients: readonly ClientIdentity[];
|
|
193
|
+
}
|
|
194
|
+
interface TlsClientConfig {
|
|
195
|
+
url: string;
|
|
196
|
+
hostId: string;
|
|
197
|
+
keyFile: string;
|
|
198
|
+
certFile: string;
|
|
199
|
+
caFile: string;
|
|
200
|
+
serverFingerprint256: string;
|
|
201
|
+
authorityId: string;
|
|
202
|
+
requestTimeoutMs?: number;
|
|
203
|
+
}
|
|
204
|
+
declare function normalizeFingerprint(fp: string): string;
|
|
205
|
+
declare function loadKeyCertCa(input: {
|
|
206
|
+
keyFile: string;
|
|
207
|
+
certFile: string;
|
|
208
|
+
caFile: string;
|
|
209
|
+
}): {
|
|
210
|
+
key: string;
|
|
211
|
+
cert: string;
|
|
212
|
+
ca: string;
|
|
213
|
+
};
|
|
214
|
+
/** 证书指纹 → host 身份映射(未登记指纹返回 undefined) */
|
|
215
|
+
declare function identityOfPeer(clients: readonly ClientIdentity[], peerFingerprint256: string | undefined): ClientIdentity | undefined;
|
|
216
|
+
declare function maidAllowed(identity: ClientIdentity, maidId: string): boolean;
|
|
217
|
+
//#endregion
|
|
218
|
+
//#region src/http-server.d.ts
|
|
219
|
+
interface StateHttpServer {
|
|
220
|
+
url: string;
|
|
221
|
+
authorityId: string;
|
|
222
|
+
close(): Promise<void>;
|
|
223
|
+
}
|
|
224
|
+
declare function startStateHttpServer<S, C>(input: {
|
|
225
|
+
authority: StateAuthority<S, C>;
|
|
226
|
+
store: AuthorityStore<S>;
|
|
227
|
+
listen: {
|
|
228
|
+
host: string;
|
|
229
|
+
port: number;
|
|
230
|
+
};
|
|
231
|
+
tls: TlsServerConfig;
|
|
232
|
+
}): Promise<StateHttpServer>;
|
|
233
|
+
//#endregion
|
|
234
|
+
//#region src/http-client.d.ts
|
|
235
|
+
interface ServerStatusView {
|
|
236
|
+
authorityId: string;
|
|
237
|
+
protocolVersion: number;
|
|
238
|
+
maids: Array<{
|
|
239
|
+
maidId: string;
|
|
240
|
+
stateRevision: number;
|
|
241
|
+
}>;
|
|
242
|
+
}
|
|
243
|
+
declare class StateHttpClient<S, C> implements StateTransport<S, C> {
|
|
244
|
+
#private;
|
|
245
|
+
constructor(config: TlsClientConfig);
|
|
246
|
+
getSnapshot(maidId: string): Promise<StateSnapshot<S, C>>;
|
|
247
|
+
submit(command: StateCommand): Promise<CommandReceipt<S, C>>;
|
|
248
|
+
health(): Promise<{
|
|
249
|
+
authorityId: string;
|
|
250
|
+
protocolVersion: number;
|
|
251
|
+
}>;
|
|
252
|
+
status(): Promise<ServerStatusView>;
|
|
253
|
+
listEvents(filter: {
|
|
254
|
+
maidId?: string;
|
|
255
|
+
afterRevision?: number;
|
|
256
|
+
limit: number;
|
|
257
|
+
}): Promise<StoredReceipt[]>;
|
|
258
|
+
close(): void;
|
|
259
|
+
}
|
|
260
|
+
//#endregion
|
|
261
|
+
//#region src/client-journal.d.ts
|
|
262
|
+
/**
|
|
263
|
+
* client durable journal(maid-state 阶段规格 §6.5/§8.1/§10.4):
|
|
264
|
+
* - turn 在 LLM judge 前以 turnKey 预留(reserved),判分后 finalize 成 pending——崩溃重启
|
|
265
|
+
* 复用原 eventId/occurredAt,draft 原文仅保留到确认,acked 后清除 payload 只留去重元数据;
|
|
266
|
+
* - awaiting_config = 无配置快照时的本地保留,取得配置后 finalize(不得空判分冒充);
|
|
267
|
+
* - pending 上限只数 reserved/awaiting/pending,满员拒绝新写入,绝不静默丢最旧;
|
|
268
|
+
* - 快照缓存带 revision 守卫:旧 revision 不回退,同 revision 允许新 serverTime/config 更新。
|
|
269
|
+
*/
|
|
270
|
+
type JournalStatus = 'reserved' | 'awaiting_config' | 'pending' | 'acked' | 'failed';
|
|
271
|
+
interface ReserveTurnInput<D> {
|
|
272
|
+
maidId: string;
|
|
273
|
+
sessionId: string;
|
|
274
|
+
turn: number;
|
|
275
|
+
occurredAt: number;
|
|
276
|
+
draft: D;
|
|
277
|
+
}
|
|
278
|
+
type ReserveTurnResult<D> = {
|
|
279
|
+
kind: 'new' | 'resume';
|
|
280
|
+
eventId: string;
|
|
281
|
+
draft: D;
|
|
282
|
+
} | {
|
|
283
|
+
kind: 'duplicate';
|
|
284
|
+
eventId: string;
|
|
285
|
+
} | {
|
|
286
|
+
kind: 'full';
|
|
287
|
+
eventId: null;
|
|
288
|
+
};
|
|
289
|
+
interface FailedJournalEntry {
|
|
290
|
+
maidId: string;
|
|
291
|
+
eventId: string;
|
|
292
|
+
command: StateCommand | undefined;
|
|
293
|
+
errorCode: string | null;
|
|
294
|
+
}
|
|
295
|
+
interface ClientJournalOptions {
|
|
296
|
+
file: string;
|
|
297
|
+
hostId: string;
|
|
298
|
+
maxPendingEvents?: number;
|
|
299
|
+
}
|
|
300
|
+
declare class ClientJournal<S = unknown, C = unknown> {
|
|
301
|
+
#private;
|
|
302
|
+
constructor(options: ClientJournalOptions);
|
|
303
|
+
/** turn 预留(判分前):turnKey 查重(hostId 用本 journal 构造身份,调用方无须知晓),新轮插入 reserved */
|
|
304
|
+
reserveTurn<D>(input: ReserveTurnInput<D>): ReserveTurnResult<D>;
|
|
305
|
+
/** 预留记录查询(reserved/awaiting/pending/acked/failed 任意状态;draft 仅预留态有语义) */
|
|
306
|
+
reservationOf(eventId: string): {
|
|
307
|
+
maidId: string;
|
|
308
|
+
status: JournalStatus;
|
|
309
|
+
} | undefined;
|
|
310
|
+
/** reserved/awaiting_config → pending(定稿):draft 从预留行内部取(builder 组装完整 payload) */
|
|
311
|
+
finalizeTurn(input: {
|
|
312
|
+
eventId: string;
|
|
313
|
+
sourceConfigRevision: string;
|
|
314
|
+
build(draft: unknown): unknown;
|
|
315
|
+
}): StateCommand | null;
|
|
316
|
+
/** gesture/reunion/manual:一次性持久化完整命令(幂等:重复 eventId 直接接受) */
|
|
317
|
+
enqueueCommand(command: StateCommand): boolean;
|
|
318
|
+
/** reserved → awaiting_config(无配置快照的本地保留);仅 reserved 可转 */
|
|
319
|
+
markAwaitingConfig(eventId: string): boolean;
|
|
320
|
+
listAwaitingConfig(maidId: string): Array<{
|
|
321
|
+
eventId: string;
|
|
322
|
+
kind: string;
|
|
323
|
+
occurredAt: number;
|
|
324
|
+
draft: unknown;
|
|
325
|
+
}>;
|
|
326
|
+
listPending(maidId: string): StateCommand[];
|
|
327
|
+
/** 确认:pending → acked,清 payload(原文清理),可选保存权威快照(revision 守卫) */
|
|
328
|
+
markAcked(eventId: string, ack: {
|
|
329
|
+
appliedRevision: number | null;
|
|
330
|
+
snapshot?: StateSnapshot<S, C>;
|
|
331
|
+
}): void;
|
|
332
|
+
/** 永久失败:pending → failed,payload 保留供显式导出(不自动删除) */
|
|
333
|
+
markFailed(eventId: string, errorCode: string | null): void;
|
|
334
|
+
exportFailed(): FailedJournalEntry[];
|
|
335
|
+
/** 快照缓存:旧 revision 不回退;同 revision 允许新 serverTime(不回退)/config 更新 */
|
|
336
|
+
saveSnapshot(snapshot: StateSnapshot<S, C>): void;
|
|
337
|
+
/** 已知 maid 全集(快照 ∪ 命令表;M3h 预备状态面用)。 */
|
|
338
|
+
listMaids(): string[];
|
|
339
|
+
readSnapshot(maidId: string): StateSnapshot<S, C> | undefined;
|
|
340
|
+
close(): void;
|
|
341
|
+
}
|
|
342
|
+
//#endregion
|
|
343
|
+
//#region src/remote-client.d.ts
|
|
344
|
+
/**
|
|
345
|
+
* remote client(maid-state 阶段规格 §7/§8):读 = 快照缓存 + pending 乐观投影(逐次重算,
|
|
346
|
+
* 绝不写回 base);写 = journal FIFO flush,applied/duplicate → acked(清原文),
|
|
347
|
+
* rejected → failed(保留原文供导出),网络/临时错误 → 保留 pending 指数退避重试。
|
|
348
|
+
* - per-maid Promise 链串行(refresh/flush 共用),同 maid 至多一个在途请求,不同 maid 并行;
|
|
349
|
+
* - 乐观投影永远可丢弃:refresh 拿到新 base 后由 read() 重算;
|
|
350
|
+
* - 自动重试 timer unref,不阻进程退出;close 停 timer 拒后续。
|
|
351
|
+
*/
|
|
352
|
+
interface ClientRead<S, C> {
|
|
353
|
+
state: S;
|
|
354
|
+
config: C;
|
|
355
|
+
stateRevision: number;
|
|
356
|
+
configRevision: string;
|
|
357
|
+
/** 缓存陈旧度代理:now - base snapshot.serverTime;无快照不可读 */
|
|
358
|
+
staleSince: number | null;
|
|
359
|
+
outboxDepth: number;
|
|
360
|
+
}
|
|
361
|
+
/** 运行时可观测状态(M3h 预备:设置页「状态服务」行数据源;§12.2 client 侧可查项)。 */
|
|
362
|
+
interface ClientRuntimeStatus {
|
|
363
|
+
/** 最近一次与权威的成功往返(refresh/ack);null=从未成功 */
|
|
364
|
+
lastOkAt: number | null;
|
|
365
|
+
closed: boolean;
|
|
366
|
+
maids: Array<{
|
|
367
|
+
maidId: string;
|
|
368
|
+
hasSnapshot: boolean;
|
|
369
|
+
stateRevision: number;
|
|
370
|
+
staleSince: number | null;
|
|
371
|
+
outboxDepth: number;
|
|
372
|
+
}>;
|
|
373
|
+
}
|
|
374
|
+
interface RemoteStateClientOptions<S, C> {
|
|
375
|
+
journal: ClientJournal<S, C>;
|
|
376
|
+
transport: StateTransport<S, C>;
|
|
377
|
+
project(base: StateSnapshot<S, C>, pending: readonly StateCommand[], now: number): S;
|
|
378
|
+
now?: () => number;
|
|
379
|
+
random?: () => number;
|
|
380
|
+
retryInitialMs?: number;
|
|
381
|
+
retryMaxMs?: number;
|
|
382
|
+
}
|
|
383
|
+
declare class RemoteStateClient<S, C> {
|
|
384
|
+
#private;
|
|
385
|
+
readonly journal: ClientJournal<S, C>;
|
|
386
|
+
constructor(options: RemoteStateClientOptions<S, C>);
|
|
387
|
+
/** 同步读:base 快照 + pending 重算;无快照 → undefined(不注情绪、不发网络) */
|
|
388
|
+
read(maidId: string): ClientRead<S, C> | undefined;
|
|
389
|
+
/** 权威快照刷新:成功后 read() 以新 base 重算;失败沿用缓存(向调用方上抛由其决定) */
|
|
390
|
+
refresh(maidId: string): Promise<void>;
|
|
391
|
+
/** FIFO flush(显式调用):成功重置退避;网络/临时错误中断并上抛(已 ack 的不回退) */
|
|
392
|
+
flush(maidId: string): Promise<void>;
|
|
393
|
+
close(): void;
|
|
394
|
+
/** 可观测快照(M3h 预备):lastOkAt + 逐 maid 缓存陈旧度/outbox 深度;同步读不发网络。 */
|
|
395
|
+
status(): ClientRuntimeStatus;
|
|
396
|
+
}
|
|
397
|
+
//#endregion
|
|
398
|
+
//#region src/embedded-transport.d.ts
|
|
399
|
+
/**
|
|
400
|
+
* M3j 内嵌传输(规格 §9.2):直接调用同进程 StateAuthority——无网络监听、无 TLS、
|
|
401
|
+
* 无序列化边界。embedded 后端与 HTTP client 共用同一权威/命令/回执/revision 语义,
|
|
402
|
+
* 由结构保证「同一输入同一结果」;唯一权威仍是 authority.db,本 transport 不持状态。
|
|
403
|
+
*/
|
|
404
|
+
declare class EmbeddedStateTransport<S, C> implements StateTransport<S, C> {
|
|
405
|
+
private readonly authority;
|
|
406
|
+
constructor(authority: StateAuthority<S, C>);
|
|
407
|
+
getSnapshot(maidId: string): Promise<StateSnapshot<S, C>>;
|
|
408
|
+
submit(command: StateCommand): Promise<CommandReceipt<S, C>>;
|
|
409
|
+
}
|
|
410
|
+
//#endregion
|
|
411
|
+
export { type AuthorityStore, type AuthorityTransaction, type ClientIdentity, ClientJournal, type ClientJournalOptions, type ClientRead, type ClientRuntimeStatus, type CommandReceipt, type DataDirLock, EmbeddedStateTransport, type EventKind, type FailedJournalEntry, type JournalStatus, type ListEventsFilter, type OpenAuthorityStoreOptions, PROTOCOL_VERSION, RemoteStateClient, type RemoteStateClientOptions, type ReserveTurnInput, type ReserveTurnResult, type ServerStatusView, StateAuthority, type StateCommand, StateCommandError, type StateDomain, StateHttpClient, type StateHttpServer, type StateSnapshot, type StateTransport, type StoredAuthorityState, type StoredReceipt, type TlsClientConfig, type TlsServerConfig, acquireDataDirLock, assertStateCommand, canonicalJson, commandHash, identityOfPeer, loadKeyCertCa, maidAllowed, newEventId, normalizeFingerprint, openAuthorityStore, revisionOf, startStateHttpServer, turnEventId };
|