@world-engines/scenario-review-snapshot 1.1.3 → 1.1.4
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/artifact-digest.js +6 -0
- package/dist/artifact-stream.d.ts +233 -0
- package/dist/artifact-stream.js +477 -0
- package/dist/canonical.d.ts +13 -0
- package/dist/canonical.js +68 -26
- package/dist/device-view-receipt.d.ts +16 -0
- package/dist/device-view-receipt.js +30 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +5 -3
- package/dist/neutral-artifact-assembler.d.ts +29 -0
- package/dist/neutral-artifact-assembler.js +367 -67
- package/dist/snapshot.d.ts +13 -0
- package/dist/snapshot.js +19 -4
- package/dist/view-publish-artifact.d.ts +35 -0
- package/dist/view-publish-artifact.js +68 -0
- package/package.json +10 -10
package/dist/artifact-digest.js
CHANGED
|
@@ -252,6 +252,12 @@ export function parseArtifactV5(value) {
|
|
|
252
252
|
throw new Error("artifact_v5_required");
|
|
253
253
|
}
|
|
254
254
|
const packageFormat = root.package_format_version;
|
|
255
|
+
if (packageFormat === EARLIER_LEGACY_ARTIFACT_PACKAGE_FORMAT_VERSION_V5) {
|
|
256
|
+
// Package V2 缺 immutable database delivery 身份,补默认字段或重算 digest 都会把 legacy
|
|
257
|
+
// manifest 伪装成 verified V5;只能由 parseLegacyArtifactV5Package2 显式 legacy reader 读取。
|
|
258
|
+
// 这里给出可路由的 legacy_reader_required 信号,而不是与未知版本共用的 invalid code。
|
|
259
|
+
throw new Error("artifact_v5_legacy_package_reader_required");
|
|
260
|
+
}
|
|
255
261
|
if (packageFormat !== LEGACY_ARTIFACT_PACKAGE_FORMAT_VERSION_V5
|
|
256
262
|
&& packageFormat !== ARTIFACT_PACKAGE_FORMAT_VERSION_V5 && packageFormat !== 5) {
|
|
257
263
|
throw new Error("artifact_v5_package_format_version_invalid");
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { type ArtifactV5, type FrozenArtifactBundle, type PublishedArtifactHead, type PublishedArtifactHeadCore, type Sha256Hex } from "./artifact.js";
|
|
2
|
+
export declare const FROZEN_ARTIFACT_STREAM_WIRE_VERSION: 1;
|
|
3
|
+
/**
|
|
4
|
+
* 有界流的字节预算。数值与 `frozen-artifact-resolver.ts` 的 `FROZEN_STREAM_BUDGET`
|
|
5
|
+
* 逐字一致;本模块是这一组数字的唯一定义点,两侧都从这里引用。
|
|
6
|
+
*/
|
|
7
|
+
export declare const FROZEN_ARTIFACT_STREAM_BUDGET: Readonly<{
|
|
8
|
+
/**
|
|
9
|
+
* 单帧载荷上限:与 edge `ARTIFACT_RESPONSE_STREAM_CHUNK_BYTES` 同值。
|
|
10
|
+
* base64(16 KiB)=21,848 必须放得进 preRead(32 KiB 行缓冲) 与 preDecode(24 KiB base64 上限)。
|
|
11
|
+
*/
|
|
12
|
+
readonly chunkSizeBytes: 16384;
|
|
13
|
+
/**
|
|
14
|
+
* 常驻内存上限(wire 头 peak_memory_budget_bytes):与 edge 的
|
|
15
|
+
* ARTIFACT_STREAM_PEAK_MEMORY_BUDGET_BYTES 同值。它是平台容量上限,不是用户体积配额:
|
|
16
|
+
* 下发线由 edge isolate 与浏览器把整批 entry 常驻内存(resolver 会为每个 entry 一次性
|
|
17
|
+
* new Uint8Array(sizeBytes)),65 MiB 已接近 isolate 128 MB 扣掉读取与解帧开销后的容量。
|
|
18
|
+
* 用户体积限制已在 2026-09-18 全部移除,这里保留的只是平台容量。
|
|
19
|
+
*/
|
|
20
|
+
readonly peakMemoryBudgetBytes: 68157440;
|
|
21
|
+
/**
|
|
22
|
+
* 任一 entry 的统一上限(wire 头 max_entry_bytes):与 edge 的
|
|
23
|
+
* ARTIFACT_STREAM_MAX_ENTRY_BYTES 及 frozen-artifact-resolver.ts 的 buffers 判定同值。
|
|
24
|
+
*/
|
|
25
|
+
readonly maxEntryBytes: 67108864;
|
|
26
|
+
/**
|
|
27
|
+
* 历史上非 database / 非 view publication 的 entry 会被额外收紧到 16 KiB;该按 kind 的
|
|
28
|
+
* 体积拒收已移除:它与 wire 头宣告的 max_entry_bytes(64 MiB)以及 resolver 的统一判定
|
|
29
|
+
* 自相矛盾,并会拒掉真实规模的对象(诡异复苏 61 节点蓝图的 trigger_semantics 本身
|
|
30
|
+
* 44,922 B)。保留该键只为兼容既有读取方,取值与 maxEntryBytes 相同:不再有任何按
|
|
31
|
+
* kind 的体积拒收。
|
|
32
|
+
*/
|
|
33
|
+
readonly maxRuntimeEntryBytes: 67108864;
|
|
34
|
+
readonly preReadAllocationCeilingBytes: 32768;
|
|
35
|
+
readonly preDecodeAllocationCeilingBytes: 24576;
|
|
36
|
+
}>;
|
|
37
|
+
/** index 0 恒为 artifact manifest(ArtifactV5 canonical JSON)。 */
|
|
38
|
+
export declare const FROZEN_ARTIFACT_MANIFEST_ENTRY_KIND: "artifact_manifest";
|
|
39
|
+
export declare const FROZEN_ARTIFACT_MANIFEST_ENTRY_RELATIVE_PATH: "artifact-v5.json";
|
|
40
|
+
/**
|
|
41
|
+
* manifest + 9 个冻结对象(= resolver 的 FROZEN_OBJECT_ENTRY_COUNT,区别于
|
|
42
|
+
* artifact.ts 里只数对象的 FROZEN_ARTIFACT_OBJECT_COUNT=9);10..11 只允许是 view publication。
|
|
43
|
+
*/
|
|
44
|
+
export declare const FROZEN_ARTIFACT_STREAM_BASE_ENTRY_COUNT: 10;
|
|
45
|
+
export declare const FROZEN_ARTIFACT_STREAM_MAX_ENTRY_COUNT: 12;
|
|
46
|
+
/** database delivery entry kind;历史上是唯一走 maxEntryBytes 的非 view publication kind。 */
|
|
47
|
+
export declare const FROZEN_DATABASE_DELIVERY_ENTRY_KIND: "database";
|
|
48
|
+
/** view publication 的 wire kind ↔ device;相对路径直接取自 capture 自身的字面量类型。 */
|
|
49
|
+
export declare const FROZEN_VIEW_PUBLICATION_WIRE_KINDS: Readonly<{
|
|
50
|
+
readonly mobile: "view_publish_mobile";
|
|
51
|
+
readonly pc: "view_publish_pc";
|
|
52
|
+
}>;
|
|
53
|
+
export declare function isFrozenViewPublicationEntryKind(kind: string): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* entry 的字节上限。历史上 database / view publication 走 maxEntryBytes,其余冻结对象被
|
|
56
|
+
* 额外收紧到 16 KiB;按 kind 的收紧已移除,现在所有 kind 共用 wire 头宣告的统一上限
|
|
57
|
+
* (与 frozen-artifact-resolver.ts 的 buffers 判定同义)。
|
|
58
|
+
*/
|
|
59
|
+
export declare function frozenArtifactStreamEntryMaxBytes(kind: string): number;
|
|
60
|
+
/** 客户端逐行校验要求 `chunk_count === ceil(size_bytes / chunk_size_bytes)`。 */
|
|
61
|
+
export declare function frozenArtifactStreamEntryChunkCount(sizeBytes: number): number;
|
|
62
|
+
/** 校验所需的最小 entry 形状;不含字节,便于单独测试拒绝矩阵。 */
|
|
63
|
+
export interface FrozenArtifactStreamEntryShape {
|
|
64
|
+
readonly kind: string;
|
|
65
|
+
readonly relativePath: string;
|
|
66
|
+
readonly sizeBytes: number;
|
|
67
|
+
}
|
|
68
|
+
export interface FrozenArtifactStreamEntryDescriptor extends FrozenArtifactStreamEntryShape {
|
|
69
|
+
readonly sha256: string;
|
|
70
|
+
readonly chunkCount: number;
|
|
71
|
+
}
|
|
72
|
+
/** 一个待编码对象的字节;顺序即 wire 上的 entry 顺序。 */
|
|
73
|
+
export interface FrozenArtifactStreamEntrySource extends FrozenArtifactStreamEntryShape {
|
|
74
|
+
readonly bytes: Uint8Array;
|
|
75
|
+
}
|
|
76
|
+
export interface FrozenArtifactStreamHeadLineage {
|
|
77
|
+
readonly head_revision: number;
|
|
78
|
+
readonly review_ticket_id: string;
|
|
79
|
+
readonly review_snapshot_hash: Sha256Hex;
|
|
80
|
+
readonly review_coverage_hash: Sha256Hex;
|
|
81
|
+
readonly published_at: number;
|
|
82
|
+
readonly previous_head_digest: Sha256Hex | null;
|
|
83
|
+
}
|
|
84
|
+
export interface FrozenArtifactStreamPlanOptions {
|
|
85
|
+
/**
|
|
86
|
+
* 发布 head。给完整 head(含 `head_digest`)则原样校验;给 head core 则由本模块计算摘要。
|
|
87
|
+
* 两种形态都必须绑定到 bundle 里的 artifact。
|
|
88
|
+
*/
|
|
89
|
+
readonly head: PublishedArtifactHeadCore | PublishedArtifactHead;
|
|
90
|
+
/**
|
|
91
|
+
* 服务端签发的 `object_set_sha256`。生产路径由发布侧权威签发(客户端只比对
|
|
92
|
+
* header 与 terminal 一致),因此这里允许显式传入;省略时按有序 entry 身份确定性派生。
|
|
93
|
+
*/
|
|
94
|
+
readonly objectSetSha256?: string;
|
|
95
|
+
}
|
|
96
|
+
export interface FrozenArtifactStreamPlan {
|
|
97
|
+
readonly head: PublishedArtifactHead;
|
|
98
|
+
readonly objectSetSha256: Sha256Hex;
|
|
99
|
+
readonly entries: readonly FrozenArtifactStreamEntrySource[];
|
|
100
|
+
readonly descriptors: readonly FrozenArtifactStreamEntryDescriptor[];
|
|
101
|
+
readonly totalPayloadBytes: number;
|
|
102
|
+
readonly totalChunks: number;
|
|
103
|
+
}
|
|
104
|
+
export interface FrozenArtifactBoundedStreamAllocationReceipt {
|
|
105
|
+
readonly phase: "bounded";
|
|
106
|
+
readonly wireVersion: typeof FROZEN_ARTIFACT_STREAM_WIRE_VERSION;
|
|
107
|
+
readonly maxEntryBytes: typeof FROZEN_ARTIFACT_STREAM_BUDGET.maxEntryBytes;
|
|
108
|
+
readonly preReadAllocationCeilingBytes: typeof FROZEN_ARTIFACT_STREAM_BUDGET.preReadAllocationCeilingBytes;
|
|
109
|
+
readonly preDecodeAllocationCeilingBytes: typeof FROZEN_ARTIFACT_STREAM_BUDGET.preDecodeAllocationCeilingBytes;
|
|
110
|
+
}
|
|
111
|
+
/** 与 ui-shell `ArtifactV5StreamHeader` 同形(字段名与字面量预算一致)。 */
|
|
112
|
+
export interface FrozenArtifactBoundedStreamHeader {
|
|
113
|
+
readonly wireVersion: typeof FROZEN_ARTIFACT_STREAM_WIRE_VERSION;
|
|
114
|
+
readonly scenarioId: string;
|
|
115
|
+
readonly headDigest: Sha256Hex;
|
|
116
|
+
readonly artifactCanonicalDigest: Sha256Hex;
|
|
117
|
+
readonly artifactManifestSha256: Sha256Hex;
|
|
118
|
+
readonly objectSetSha256: Sha256Hex;
|
|
119
|
+
readonly head: PublishedArtifactHead;
|
|
120
|
+
readonly chunkSizeBytes: typeof FROZEN_ARTIFACT_STREAM_BUDGET.chunkSizeBytes;
|
|
121
|
+
readonly peakMemoryBudgetBytes: typeof FROZEN_ARTIFACT_STREAM_BUDGET.peakMemoryBudgetBytes;
|
|
122
|
+
readonly allocationReceipt: FrozenArtifactBoundedStreamAllocationReceipt;
|
|
123
|
+
readonly totalPayloadBytes: number;
|
|
124
|
+
readonly totalChunks: number;
|
|
125
|
+
readonly entries: readonly FrozenArtifactStreamEntryDescriptor[];
|
|
126
|
+
}
|
|
127
|
+
export interface FrozenArtifactBoundedStreamChunk {
|
|
128
|
+
readonly sequence: number;
|
|
129
|
+
readonly entryIndex: number;
|
|
130
|
+
readonly entryOffset: number;
|
|
131
|
+
readonly sha256: string;
|
|
132
|
+
readonly bytes: Uint8Array;
|
|
133
|
+
}
|
|
134
|
+
export interface FrozenArtifactBoundedStreamTerminal {
|
|
135
|
+
readonly wireVersion: typeof FROZEN_ARTIFACT_STREAM_WIRE_VERSION;
|
|
136
|
+
readonly headDigest: Sha256Hex;
|
|
137
|
+
readonly artifactCanonicalDigest: Sha256Hex;
|
|
138
|
+
readonly objectSetSha256: Sha256Hex;
|
|
139
|
+
readonly totalPayloadBytes: number;
|
|
140
|
+
readonly totalChunks: number;
|
|
141
|
+
readonly payloadSha256: string;
|
|
142
|
+
}
|
|
143
|
+
/** 与 ui-shell `ArtifactV5BoundedStream` 同形。 */
|
|
144
|
+
export interface FrozenArtifactBoundedStream {
|
|
145
|
+
readonly header: FrozenArtifactBoundedStreamHeader;
|
|
146
|
+
readonly chunks: AsyncIterable<FrozenArtifactBoundedStreamChunk>;
|
|
147
|
+
readonly completion: Promise<FrozenArtifactBoundedStreamTerminal>;
|
|
148
|
+
}
|
|
149
|
+
export interface FrozenArtifactStreamHeaderEntryWire {
|
|
150
|
+
readonly kind: string;
|
|
151
|
+
readonly relative_path: string;
|
|
152
|
+
readonly size_bytes: number;
|
|
153
|
+
readonly sha256: string;
|
|
154
|
+
readonly chunk_count: number;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* NDJSON header 帧。字段顺序与 edge 生产者的 `head_json` + header 一致,使同一 plan
|
|
158
|
+
* 在本模块与 Rust 编码器下产出同一批字节(golden 逐字节可比)。
|
|
159
|
+
*/
|
|
160
|
+
export interface FrozenArtifactStreamHeaderWire {
|
|
161
|
+
readonly type: "header";
|
|
162
|
+
readonly wire_version: typeof FROZEN_ARTIFACT_STREAM_WIRE_VERSION;
|
|
163
|
+
readonly scenario_id: string;
|
|
164
|
+
readonly head: PublishedArtifactHead;
|
|
165
|
+
readonly head_digest: Sha256Hex;
|
|
166
|
+
readonly artifact_canonical_digest: Sha256Hex;
|
|
167
|
+
readonly artifact_manifest_sha256: Sha256Hex;
|
|
168
|
+
readonly object_set_sha256: Sha256Hex;
|
|
169
|
+
readonly chunk_size_bytes: number;
|
|
170
|
+
readonly peak_memory_budget_bytes: number;
|
|
171
|
+
readonly max_entry_bytes: number;
|
|
172
|
+
readonly pre_read_allocation_ceiling_bytes: number;
|
|
173
|
+
readonly pre_decode_allocation_ceiling_bytes: number;
|
|
174
|
+
readonly total_payload_bytes: number;
|
|
175
|
+
readonly total_chunks: number;
|
|
176
|
+
readonly entries: readonly FrozenArtifactStreamHeaderEntryWire[];
|
|
177
|
+
}
|
|
178
|
+
export interface FrozenArtifactStreamChunkWire {
|
|
179
|
+
readonly type: "chunk";
|
|
180
|
+
readonly wire_version: typeof FROZEN_ARTIFACT_STREAM_WIRE_VERSION;
|
|
181
|
+
readonly sequence: number;
|
|
182
|
+
readonly entry_index: number;
|
|
183
|
+
readonly entry_offset: number;
|
|
184
|
+
readonly byte_length: number;
|
|
185
|
+
readonly sha256: string;
|
|
186
|
+
readonly bytes_base64: string;
|
|
187
|
+
}
|
|
188
|
+
export interface FrozenArtifactStreamTerminalWire {
|
|
189
|
+
readonly type: "terminal";
|
|
190
|
+
readonly wire_version: typeof FROZEN_ARTIFACT_STREAM_WIRE_VERSION;
|
|
191
|
+
readonly head_digest: Sha256Hex;
|
|
192
|
+
readonly artifact_canonical_digest: Sha256Hex;
|
|
193
|
+
readonly object_set_sha256: Sha256Hex;
|
|
194
|
+
readonly total_payload_bytes: number;
|
|
195
|
+
readonly total_chunks: number;
|
|
196
|
+
readonly payload_sha256: string;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* entry 顺序与预算校验。逐条对应 `frozen-artifact-resolver.ts:459-481`(单 entry 上限、
|
|
200
|
+
* 逐步累计的 peak 预算)与 `:517-543`、`:560`(index 0 为 manifest、1..9 不得是 view
|
|
201
|
+
* publication、10+ 必须全是 view publication、总数 10..12)。
|
|
202
|
+
*
|
|
203
|
+
* kind 是否属于冻结对象集不在这里判断:它已由 `parseFrozenArtifactBundle` 的
|
|
204
|
+
* `assertBundleMatchesArtifact` 固定,本函数只保证「顺序 / 位置 / 预算」三条不变式。
|
|
205
|
+
*/
|
|
206
|
+
export declare function assertFrozenArtifactStreamEntries(entries: readonly FrozenArtifactStreamEntryShape[]): void;
|
|
207
|
+
/**
|
|
208
|
+
* 由 artifact 推导一个绑定正确的发布 head。head 的 artifact 侧字段(scenario/epoch/
|
|
209
|
+
* runtime contract/source revision/canonical digest/manifest sha256)只在这一处取值,
|
|
210
|
+
* 调用方只提供发布谱系,避免每个生产者各自复算一遍摘要。
|
|
211
|
+
*/
|
|
212
|
+
export declare function buildFrozenArtifactStreamHead(artifact: ArtifactV5, lineage: FrozenArtifactStreamHeadLineage): PublishedArtifactHead;
|
|
213
|
+
/**
|
|
214
|
+
* bundle → 有序 entry 计划。entry 顺序 = manifest、按相对路径升序的 9 个冻结对象、
|
|
215
|
+
* mobile 后 pc 的 view publication,与 edge 生产者的写出顺序一致。
|
|
216
|
+
*/
|
|
217
|
+
export declare function buildFrozenArtifactStreamPlan(bundle: FrozenArtifactBundle, options: FrozenArtifactStreamPlanOptions): FrozenArtifactStreamPlan;
|
|
218
|
+
export declare function buildFrozenArtifactBoundedStreamHeader(plan: FrozenArtifactStreamPlan): FrozenArtifactBoundedStreamHeader;
|
|
219
|
+
export declare function buildFrozenArtifactBoundedStreamTerminal(plan: FrozenArtifactStreamPlan): FrozenArtifactBoundedStreamTerminal;
|
|
220
|
+
/** 由已校验计划产出有界流;载荷逐窗口产出,不整包物化。 */
|
|
221
|
+
export declare function encodeFrozenArtifactBoundedStreamFromPlan(plan: FrozenArtifactStreamPlan): FrozenArtifactBoundedStream;
|
|
222
|
+
/** bundle → 有界流(= `buildFrozenArtifactStreamPlan` + `encodeFrozenArtifactBoundedStreamFromPlan`)。 */
|
|
223
|
+
export declare function encodeFrozenArtifactBoundedStream(bundle: FrozenArtifactBundle, options: FrozenArtifactStreamPlanOptions): FrozenArtifactBoundedStream;
|
|
224
|
+
export declare function buildFrozenArtifactStreamHeaderWire(plan: FrozenArtifactStreamPlan): FrozenArtifactStreamHeaderWire;
|
|
225
|
+
/**
|
|
226
|
+
* 由已校验计划产出 NDJSON 帧(每条含换行,可直接拼接为响应体)。
|
|
227
|
+
* payload_sha256 在产出过程中增量累计,不等同于先拼接再哈希。
|
|
228
|
+
*/
|
|
229
|
+
export declare function encodeFrozenArtifactNdjsonFramesFromPlan(plan: FrozenArtifactStreamPlan): AsyncGenerator<string, void, void>;
|
|
230
|
+
export declare function encodeFrozenArtifactNdjsonFrames(bundle: FrozenArtifactBundle, options: FrozenArtifactStreamPlanOptions): AsyncIterable<string>;
|
|
231
|
+
/** 已校验计划 → 完整 NDJSON 响应体字节(single-file HTML 内嵌用)。 */
|
|
232
|
+
export declare function encodeFrozenArtifactNdjsonBytesFromPlan(plan: FrozenArtifactStreamPlan): Promise<Uint8Array>;
|
|
233
|
+
export declare function encodeFrozenArtifactNdjsonBytes(bundle: FrozenArtifactBundle, options: FrozenArtifactStreamPlanOptions): Promise<Uint8Array>;
|