@zhushanwen/session-delivery 2.1.0 → 2.2.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/index.d.mts +55 -12
- package/dist/index.mjs +82 -19
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -202,7 +202,7 @@ interface DeliveryStoreRecord {
|
|
|
202
202
|
meta?: DeliveryMeta;
|
|
203
203
|
}
|
|
204
204
|
/**
|
|
205
|
-
* 持久化存储端口(v3
|
|
205
|
+
* 持久化存储端口(v3,统一语言词条「持久化存储端口」):内核与耐久层的唯一接口。
|
|
206
206
|
* 两个实现在两半区适配层(本包零 fs 零 pi 知识):runtime 半区 = 磁盘 outbox 文件
|
|
207
207
|
* (文本投递路径,波 4 接线);port 半区 = session entry 读写(通知投递路径,波 2 接线)。
|
|
208
208
|
*
|
|
@@ -210,8 +210,12 @@ interface DeliveryStoreRecord {
|
|
|
210
210
|
* - persist:send 受理前调用(耐久承诺先于投递尝试,与账本 record 先于 deliver 同
|
|
211
211
|
* 律)。persist 抛错 = 承诺未落 → 内核拒收该条目(send 返回 persist-failed /
|
|
212
212
|
* sendChecked 同步 throw),不进入投递流程。
|
|
213
|
-
* - ack:终局 delivered / cancelled
|
|
214
|
-
*
|
|
213
|
+
* - ack:终局 delivered / cancelled 时调用(写持久终局——已撤销消息的防复活凭据
|
|
214
|
+
* 同样在持久终局记录里)。磁盘权威(2026-10-30 用户裁决「内存终态必须以磁盘确认为
|
|
215
|
+
* 准」):ack 先于内存终态登记,抛错 = 持久终局未写入 → 内核不登记内存终态(条目
|
|
216
|
+
* 留守活跃集非终态)并显式上报分型错误 DeliveryAckPersistError;外部送达事实不
|
|
217
|
+
* 回滚,恢复后可能重投(at-least-once 显式接受)。实现方须遵守同序:自身内存派生
|
|
218
|
+
* 数据只在落盘成功后登记。
|
|
215
219
|
* - discard:forget 失败条目的记录无痕移除(无终局无判重语义——区别于 ack,不进
|
|
216
220
|
* 终局记录,防重启后 loadUndelivered 把已弃条目当未投递复活)。
|
|
217
221
|
* - loadUndelivered:供重启 / 重放时重入队(装配方启动时取回未终局记录重新提交)。
|
|
@@ -228,7 +232,7 @@ interface DeliveryStoreRecord {
|
|
|
228
232
|
interface DeliveryStore {
|
|
229
233
|
/** 受理前写入记录(耐久承诺先于投递尝试)。抛错 = 承诺未写入,内核拒收。 */
|
|
230
234
|
persist(record: DeliveryStoreRecord): void;
|
|
231
|
-
/** 终局(delivered / cancelled
|
|
235
|
+
/** 终局(delivered / cancelled)写持久终局(从待投差集移除、进终局记录)。抛错 = 持久终局未写入 → 内核不登记内存终态(磁盘权威,见上方契约)。 */
|
|
232
236
|
ack(id: string): void;
|
|
233
237
|
/** forget 失败条目的记录无痕移除(无终局形态,区别于 ack)。 */
|
|
234
238
|
discard(id: string): void;
|
|
@@ -272,7 +276,7 @@ interface DeliveryConfig {
|
|
|
272
276
|
*/
|
|
273
277
|
onSettled?: (msg: DeliveryMessage, outcome: 'delivered' | 'rejected') => void;
|
|
274
278
|
/**
|
|
275
|
-
* 持久化存储端口(v3)。缺省 undefined =
|
|
279
|
+
* 持久化存储端口(v3)。缺省 undefined = 无耐久层(v2 行为:纯内存条目集)——
|
|
276
280
|
* 既有 runtime 装配不传 = 逐字节不变(波 1 零行为变化锚)。提供时内核行为契约见
|
|
277
281
|
* DeliveryStore(受理前 persist / 终局 ack / forget 失败 discard / 构造期
|
|
278
282
|
* loadTerminalIds 播种判重索引)。
|
|
@@ -459,10 +463,12 @@ interface DeliveryEntriesProjection {
|
|
|
459
463
|
* v3 增量(统一消息投递内核,设计 unified-delivery §3.5):
|
|
460
464
|
* - DeliveryStore 端口(config.store):send/sendChecked 受理前先 persist(耐久承诺
|
|
461
465
|
* 先于投递尝试;persist 抛错 = 承诺未落 → 拒收 rejected('persist-failed'),条目
|
|
462
|
-
* 回滚不入队不投递);终局 delivered / cancelled
|
|
463
|
-
* forget 失败条目 discard(无终局语义的记录无痕移除,防重启复活)。ack
|
|
464
|
-
*
|
|
465
|
-
*
|
|
466
|
+
* 回滚不入队不投递);终局 delivered / cancelled 时 ack(finalizeEntry / drain);
|
|
467
|
+
* forget 失败条目 discard(无终局语义的记录无痕移除,防重启复活)。ack 先于内存
|
|
468
|
+
* 终态登记(磁盘权威,2026-10-30 用户裁决「内存终态必须以磁盘确认为准」):写盘
|
|
469
|
+
* 失败 → 内存不登记终态(条目留守活跃集非终态)+ 分型错误 DeliveryAckPersistError
|
|
470
|
+
* 显式上报——外部送达事实不回滚,恢复后可能重投(at-least-once 显式接受);判重
|
|
471
|
+
* 查询(hasTerminal)异常保守放行 + warn;persist 异常 fail-fast 拒收(承诺语义)。
|
|
466
472
|
* - 送达凭据三档(receiptAnchor):'details-id' 与 'marker' / 'acceptance' 并列
|
|
467
473
|
* (ADR-0074 词条扩展)。details-id 条目受理后维持 in-flight 等回执(同 marker);
|
|
468
474
|
* 判定逻辑以可注入凭据检查函数(config.proofCheck)承载,调用点 =
|
|
@@ -652,7 +658,10 @@ interface DeliveryHandleV2 extends DeliveryHandle {
|
|
|
652
658
|
* msg.payload 同步替换引用(onSettled per-message 契约的消费方拿到替换后内容)。
|
|
653
659
|
*/
|
|
654
660
|
edit(id: string, payload: DeliveryPayload): boolean;
|
|
655
|
-
/**
|
|
661
|
+
/**
|
|
662
|
+
* 全量取回文本(forceQuit,D9③):条目清空 + 全部记 cancelled tombstone(ack 写盘
|
|
663
|
+
* 失败的条目除外——文本照常返回,条目转 failed 留守,见 drain 实现的磁盘权威序注释)。
|
|
664
|
+
*/
|
|
656
665
|
drain(): DrainResult;
|
|
657
666
|
}
|
|
658
667
|
/** cancel(id) 结果(D-3 偏差:cancelled 形态携带条目快照含 payload 全文供草稿恢复)。 */
|
|
@@ -686,7 +695,7 @@ declare function createDelivery(port: DeliveryPort, config?: DeliveryConfigWithW
|
|
|
686
695
|
*
|
|
687
696
|
* 判别形态依据(设计 §3.3 D4 尾注):本包与消费方(runtime registry)是进程内同包
|
|
688
697
|
* 调用边界——编译期类型可得,instanceof 是最简判别且免词表;与跨进程 WS 边界的
|
|
689
|
-
*
|
|
698
|
+
* error envelope 分类码形态不构成双轨。
|
|
690
699
|
*/
|
|
691
700
|
/**
|
|
692
701
|
* 「用户主动回收」对挂起 sendChecked waiter 的 reject 错误类。
|
|
@@ -708,6 +717,28 @@ declare class DeliveryReclaimError extends Error {
|
|
|
708
717
|
readonly entryId: string | undefined;
|
|
709
718
|
constructor(kind: 'cancelled' | 'drained', entryId?: string);
|
|
710
719
|
}
|
|
720
|
+
/**
|
|
721
|
+
* 「终局事实已发生,但持久终局(store.ack)写入失败」的分型错误(2026-10-30 用户裁决
|
|
722
|
+
* 「磁盘为准」:内存终态必须以磁盘确认为准)。
|
|
723
|
+
*
|
|
724
|
+
* 产生点(delivery.ts ackStore):confirmDelivered / cancel / drain 终局化时先写持久
|
|
725
|
+
* 终局,store.ack 抛错即包装为本类——内核不登记内存终态(条目留守活跃集非终态,判重
|
|
726
|
+
* 与恢复以磁盘为唯一权威),由各终局入口捕获留痕并显式上报。
|
|
727
|
+
*
|
|
728
|
+
* 语义边界:外部送达事实不可回滚(消息已实际发出)——写盘失败期间该条不视为已终态,
|
|
729
|
+
* 恢复(重启重放 / 下一回执边沿重驱动)后可能重投,at-least-once 语义被显式接受
|
|
730
|
+
* (宁可可能重投,不做内存单方终态)。
|
|
731
|
+
*
|
|
732
|
+
* 结构化字段:
|
|
733
|
+
* - entryId:终局写入失败的条目 id。
|
|
734
|
+
* - state:本应落定的终态('delivered' | 'cancelled')——文案按它分叉:delivered 强调
|
|
735
|
+
* 送达事实已成立;cancelled 强调本地撤销意图已发生但持久撤销凭据未落。
|
|
736
|
+
*/
|
|
737
|
+
declare class DeliveryAckPersistError extends Error {
|
|
738
|
+
readonly entryId: string;
|
|
739
|
+
readonly state: 'delivered' | 'cancelled';
|
|
740
|
+
constructor(entryId: string, state: 'delivered' | 'cancelled', cause?: unknown);
|
|
741
|
+
}
|
|
711
742
|
|
|
712
743
|
/**
|
|
713
744
|
* 磁盘 outbox —— DeliveryStore 的 runtime 半区实现(统一消息投递设计 §3.5.1 / §3.8
|
|
@@ -731,6 +762,8 @@ declare class DeliveryReclaimError extends Error {
|
|
|
731
762
|
* 设计 §3.5.1「两个实现在两半区适配层」);目录与文件路径由装配方(runtime 侧)动态
|
|
732
763
|
* 推导后以字符串传入。崩溃写入的中途半行由读取容错覆盖(JSON.parse 失败 warn 跳过)
|
|
733
764
|
* ——最坏丢一行 = 最坏多投一次,与「必达优先于去重」语义一致,不需要原子替换协议。
|
|
765
|
+
* 读失败(文件存在但不可读)显式分型上抛 DiskStoreReadError,不折叠成空结果(见
|
|
766
|
+
* ensureLoaded 注释);文件不存在 = 合法空态。
|
|
734
767
|
*/
|
|
735
768
|
|
|
736
769
|
/** fs 窄接口(注入点;生产 = node:fs 适配,测试 = 内存替身)。 */
|
|
@@ -762,6 +795,16 @@ interface DiskDeliveryStore extends DeliveryStore {
|
|
|
762
795
|
*/
|
|
763
796
|
attachSegments(id: string, segments: readonly unknown[]): void;
|
|
764
797
|
}
|
|
798
|
+
/**
|
|
799
|
+
* outbox 读失败错误(显式分型:读失败 ≠ 空文件)。文件存在但不可读(权限 / 瞬时 fs
|
|
800
|
+
* 故障)时由 ensureLoaded 抛出——判别形态与 DeliveryReclaimError 同理(进程内同包
|
|
801
|
+
* 调用边界,instanceof 最简判别)。
|
|
802
|
+
*/
|
|
803
|
+
declare class DiskStoreReadError extends Error {
|
|
804
|
+
/** outbox 文件路径(诊断定位)。 */
|
|
805
|
+
readonly file: string;
|
|
806
|
+
constructor(file: string, cause?: unknown);
|
|
807
|
+
}
|
|
765
808
|
declare function createDiskDeliveryStore(deps: DiskDeliveryStoreDeps): DiskDeliveryStore;
|
|
766
809
|
|
|
767
|
-
export { type CustomPayload, type DeliveryCancelResult, type DeliveryConfig, type DeliveryConfigWithWarn, type DeliveryDeferReason, type DeliveryEntriesFull, type DeliveryEntriesProjection, type DeliveryEntry, type DeliveryEntryState, type DeliveryFailurePolicy, type DeliveryHandle, type DeliveryHandleV2, type DeliveryIntent, type DeliveryLane, type DeliveryMessage, type DeliveryMeta, type DeliveryPayload, type DeliveryPort, type DeliveryProofCheck, type DeliveryReceiptAnchor, DeliveryReclaimError, type DeliverySendResult, type DeliveryStore, type DeliveryStoreRecord, type DeliverySubmitOptions, type DeliveryTerminalRecord, type DeliveryWarnSink, type DiskDeliveryStore, type DiskDeliveryStoreDeps, type DiskStoreFs, type DrainResult, type SendReceipt, type TextPayload, createDelivery, createDiskDeliveryStore };
|
|
810
|
+
export { type CustomPayload, DeliveryAckPersistError, type DeliveryCancelResult, type DeliveryConfig, type DeliveryConfigWithWarn, type DeliveryDeferReason, type DeliveryEntriesFull, type DeliveryEntriesProjection, type DeliveryEntry, type DeliveryEntryState, type DeliveryFailurePolicy, type DeliveryHandle, type DeliveryHandleV2, type DeliveryIntent, type DeliveryLane, type DeliveryMessage, type DeliveryMeta, type DeliveryPayload, type DeliveryPort, type DeliveryProofCheck, type DeliveryReceiptAnchor, DeliveryReclaimError, type DeliverySendResult, type DeliveryStore, type DeliveryStoreRecord, type DeliverySubmitOptions, type DeliveryTerminalRecord, type DeliveryWarnSink, type DiskDeliveryStore, type DiskDeliveryStoreDeps, type DiskStoreFs, DiskStoreReadError, type DrainResult, type SendReceipt, type TextPayload, createDelivery, createDiskDeliveryStore };
|
package/dist/index.mjs
CHANGED
|
@@ -9,6 +9,19 @@ var DeliveryReclaimError = class extends Error {
|
|
|
9
9
|
this.entryId = entryId;
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
|
+
var DeliveryAckPersistError = class extends Error {
|
|
13
|
+
entryId;
|
|
14
|
+
state;
|
|
15
|
+
constructor(entryId, state, cause) {
|
|
16
|
+
super(
|
|
17
|
+
state === "delivered" ? `delivery delivered but terminal record not persisted; recovery may redeliver (id=${entryId})` : `entry cancelled locally but terminal record not persisted; recovery may redeliver (id=${entryId})`,
|
|
18
|
+
{ cause }
|
|
19
|
+
);
|
|
20
|
+
this.name = "DeliveryAckPersistError";
|
|
21
|
+
this.entryId = entryId;
|
|
22
|
+
this.state = state;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
12
25
|
|
|
13
26
|
// src/lru.ts
|
|
14
27
|
var LruSet = class {
|
|
@@ -144,12 +157,12 @@ function createDelivery(port, config) {
|
|
|
144
157
|
meta: e.msg.meta
|
|
145
158
|
});
|
|
146
159
|
}
|
|
147
|
-
function ackStore(id) {
|
|
160
|
+
function ackStore(id, state) {
|
|
148
161
|
if (!store) return;
|
|
149
162
|
try {
|
|
150
163
|
store.ack(id);
|
|
151
164
|
} catch (err) {
|
|
152
|
-
|
|
165
|
+
throw new DeliveryAckPersistError(id, state, err);
|
|
153
166
|
}
|
|
154
167
|
}
|
|
155
168
|
function safeHasTerminal(id) {
|
|
@@ -203,6 +216,7 @@ function createDelivery(port, config) {
|
|
|
203
216
|
return false;
|
|
204
217
|
}
|
|
205
218
|
function finalizeEntry(e, state) {
|
|
219
|
+
ackStore(e.id, state);
|
|
206
220
|
const batchIdx = inflightBatch.indexOf(e);
|
|
207
221
|
if (batchIdx !== -1) inflightBatch.splice(batchIdx, 1);
|
|
208
222
|
const idx = active.indexOf(e);
|
|
@@ -214,7 +228,6 @@ function createDelivery(port, config) {
|
|
|
214
228
|
e.settledAt = ts;
|
|
215
229
|
terminalIndex.add(e.id);
|
|
216
230
|
terminalRecords.set(e.id, { id: e.id, state, lane: e.lane, settledAt: ts });
|
|
217
|
-
ackStore(e.id);
|
|
218
231
|
if (state === "delivered") {
|
|
219
232
|
resolveWaitersOf(e);
|
|
220
233
|
deliveredLog.push(e);
|
|
@@ -222,6 +235,25 @@ function createDelivery(port, config) {
|
|
|
222
235
|
}
|
|
223
236
|
notifyChange();
|
|
224
237
|
}
|
|
238
|
+
function parkAsFailed(e) {
|
|
239
|
+
const batchIdx = inflightBatch.indexOf(e);
|
|
240
|
+
if (batchIdx !== -1) inflightBatch.splice(batchIdx, 1);
|
|
241
|
+
const ts = now();
|
|
242
|
+
e.state = "failed";
|
|
243
|
+
e.updatedAt = ts;
|
|
244
|
+
e.settledAt = ts;
|
|
245
|
+
notifyChange();
|
|
246
|
+
}
|
|
247
|
+
function cancelFinalize(e) {
|
|
248
|
+
try {
|
|
249
|
+
finalizeEntry(e, "cancelled");
|
|
250
|
+
} catch (err) {
|
|
251
|
+
if (!(err instanceof DeliveryAckPersistError)) throw err;
|
|
252
|
+
warn(`store.ack failed; cancel not terminalized, entry parked failed (id=${e.id})`, err);
|
|
253
|
+
parkAsFailed(e);
|
|
254
|
+
throw err;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
225
257
|
function removeActive(e) {
|
|
226
258
|
const idx = active.indexOf(e);
|
|
227
259
|
if (idx !== -1) active.splice(idx, 1);
|
|
@@ -538,7 +570,13 @@ function createDelivery(port, config) {
|
|
|
538
570
|
const e = activeIndex.get(id);
|
|
539
571
|
if (!e) return false;
|
|
540
572
|
if (e.state !== "queued" && e.state !== "in-flight" && e.state !== "failed") return false;
|
|
541
|
-
|
|
573
|
+
try {
|
|
574
|
+
finalizeEntry(e, "delivered");
|
|
575
|
+
} catch (err) {
|
|
576
|
+
if (!(err instanceof DeliveryAckPersistError)) throw err;
|
|
577
|
+
warn(`store.ack failed; terminal not registered, entry stays non-terminal (id=${id})`, err);
|
|
578
|
+
return false;
|
|
579
|
+
}
|
|
542
580
|
if (!disposed) callOnSettled(e.msg, "delivered");
|
|
543
581
|
return true;
|
|
544
582
|
}
|
|
@@ -625,11 +663,11 @@ function createDelivery(port, config) {
|
|
|
625
663
|
return { kind: "reclaim-requested", entry: snapshot(e) };
|
|
626
664
|
}
|
|
627
665
|
rejectWaitersOf(e, new DeliveryReclaimError("cancelled", id));
|
|
628
|
-
|
|
666
|
+
cancelFinalize(e);
|
|
629
667
|
return { kind: "cancelled", entry: snapshot(e) };
|
|
630
668
|
}
|
|
631
669
|
rejectWaitersOf(e, new DeliveryReclaimError("cancelled", id));
|
|
632
|
-
|
|
670
|
+
cancelFinalize(e);
|
|
633
671
|
return { kind: "cancelled", entry: snapshot(e) };
|
|
634
672
|
}
|
|
635
673
|
function edit(id, payload) {
|
|
@@ -667,17 +705,28 @@ function createDelivery(port, config) {
|
|
|
667
705
|
function drain() {
|
|
668
706
|
if (disposed) return [];
|
|
669
707
|
const drained = active.slice();
|
|
670
|
-
|
|
671
|
-
|
|
708
|
+
const ts = now();
|
|
709
|
+
const result = [];
|
|
710
|
+
for (const e of drained) {
|
|
711
|
+
try {
|
|
712
|
+
ackStore(e.id, "cancelled");
|
|
713
|
+
const idx = active.indexOf(e);
|
|
714
|
+
if (idx !== -1) active.splice(idx, 1);
|
|
715
|
+
activeIndex.delete(e.id);
|
|
716
|
+
e.state = "cancelled";
|
|
717
|
+
e.updatedAt = ts;
|
|
718
|
+
e.settledAt = ts;
|
|
719
|
+
terminalIndex.add(e.id);
|
|
720
|
+
terminalRecords.set(e.id, { id: e.id, state: "cancelled", lane: e.lane, settledAt: ts });
|
|
721
|
+
} catch (err) {
|
|
722
|
+
if (!(err instanceof DeliveryAckPersistError)) throw err;
|
|
723
|
+
warn(`store.ack failed in drain; entry not terminalized, parked failed (id=${e.id})`, err);
|
|
724
|
+
parkAsFailed(e);
|
|
725
|
+
}
|
|
726
|
+
result.push({ id: e.id, payload: e.payload });
|
|
727
|
+
}
|
|
672
728
|
inflightBatch = [];
|
|
673
729
|
inFlight = false;
|
|
674
|
-
const ts = now();
|
|
675
|
-
const result = drained.map((e) => {
|
|
676
|
-
terminalIndex.add(e.id);
|
|
677
|
-
terminalRecords.set(e.id, { id: e.id, state: "cancelled", lane: e.lane, settledAt: ts });
|
|
678
|
-
ackStore(e.id);
|
|
679
|
-
return { id: e.id, payload: e.payload };
|
|
680
|
-
});
|
|
681
730
|
for (const w of checkedPending) {
|
|
682
731
|
w.reject(new DeliveryReclaimError("drained"));
|
|
683
732
|
}
|
|
@@ -710,6 +759,15 @@ function serializeLine(line) {
|
|
|
710
759
|
return `${JSON.stringify(line)}
|
|
711
760
|
`;
|
|
712
761
|
}
|
|
762
|
+
var DiskStoreReadError = class extends Error {
|
|
763
|
+
/** outbox 文件路径(诊断定位)。 */
|
|
764
|
+
file;
|
|
765
|
+
constructor(file, cause) {
|
|
766
|
+
super(`disk delivery store read failed: ${file}`, { cause });
|
|
767
|
+
this.name = "DiskStoreReadError";
|
|
768
|
+
this.file = file;
|
|
769
|
+
}
|
|
770
|
+
};
|
|
713
771
|
function createDiskDeliveryStore(deps) {
|
|
714
772
|
const { fs, dir, file } = deps;
|
|
715
773
|
const log = deps.log ?? ((message, err) => {
|
|
@@ -742,15 +800,18 @@ function createDiskDeliveryStore(deps) {
|
|
|
742
800
|
}
|
|
743
801
|
function ensureLoaded() {
|
|
744
802
|
if (loaded) return;
|
|
745
|
-
|
|
746
|
-
|
|
803
|
+
if (!fs.existsSync(file)) {
|
|
804
|
+
loaded = true;
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
747
807
|
let raw;
|
|
748
808
|
try {
|
|
749
809
|
raw = fs.readFileSync(file, "utf8");
|
|
750
810
|
} catch (err) {
|
|
751
|
-
log(`[disk-delivery-store] read failed (treated as empty), file=${file}`, err);
|
|
752
|
-
|
|
811
|
+
log(`[disk-delivery-store] read failed (propagating; not treated as empty), file=${file}`, err);
|
|
812
|
+
throw new DiskStoreReadError(file, err);
|
|
753
813
|
}
|
|
814
|
+
loaded = true;
|
|
754
815
|
let lineNumber = 0;
|
|
755
816
|
for (const lineText of raw.split("\n")) {
|
|
756
817
|
lineNumber += 1;
|
|
@@ -818,7 +879,9 @@ function createDiskDeliveryStore(deps) {
|
|
|
818
879
|
};
|
|
819
880
|
}
|
|
820
881
|
export {
|
|
882
|
+
DeliveryAckPersistError,
|
|
821
883
|
DeliveryReclaimError,
|
|
884
|
+
DiskStoreReadError,
|
|
822
885
|
createDelivery,
|
|
823
886
|
createDiskDeliveryStore
|
|
824
887
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhushanwen/session-delivery",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Session message delivery kernel: zero-pi-dependency strategy layer for idempotent, accept-time dispatch of messages into pi sessions",
|
|
5
5
|
"main": "dist/index.mjs",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -25,6 +25,6 @@
|
|
|
25
25
|
"scripts": {
|
|
26
26
|
"build": "tsup",
|
|
27
27
|
"typecheck": "tsc --noEmit",
|
|
28
|
-
"test": "vitest run"
|
|
28
|
+
"test": "vitest run --pool=threads"
|
|
29
29
|
}
|
|
30
30
|
}
|