@forgeax/engine-pack 0.1.6 → 0.1.19
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/README.md +12 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/build.d.ts +1 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.mjs +100 -51
- package/dist/build.mjs.map +1 -1
- package/dist/catalog-builder.d.ts +12 -0
- package/dist/catalog-builder.d.ts.map +1 -1
- package/dist/cli-asset.mjs +1 -1
- package/dist/cli-asset.mjs.map +1 -1
- package/dist/evidence/material-cook.d.ts +28 -6
- package/dist/evidence/material-cook.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +97 -42
- package/dist/index.mjs.map +1 -1
- package/dist/material-cook.d.ts +1 -1
- package/dist/material-cook.d.ts.map +1 -1
- package/dist/material-cook.mjs +96 -41
- package/dist/material-cook.mjs.map +1 -1
- package/dist/scanner.mjs +1 -1
- package/dist/scanner.mjs.map +1 -1
- package/dist/scriptable-pack-node.d.ts.map +1 -1
- package/dist/scriptable-pack-node.mjs +1 -1
- package/dist/scriptable-pack-node.mjs.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/material-cook-dependencies.unit.test.ts +111 -0
- package/src/__tests__/material-cook-receipt.unit.test.ts +77 -20
- package/src/__tests__/material-cook-schema.unit.test.ts +64 -10
- package/src/__tests__/pack-v2-fixture-migration.test.ts +24 -1
- package/src/build.ts +1 -0
- package/src/catalog-builder.ts +42 -5
- package/src/evidence/material-cook.ts +133 -54
- package/src/index.ts +4 -0
- package/src/material-cook.ts +2 -0
- package/src/schema/material-cook.schema.json +48 -8
- package/src/scriptable-pack-node.ts +4 -1
|
@@ -25,16 +25,38 @@ export interface MaterialCookArtifact {
|
|
|
25
25
|
readonly bytes: Uint8Array;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
export interface MaterialCookWasmProvenance {
|
|
29
|
+
readonly sourceContentKey: string;
|
|
30
|
+
readonly artifactSha256: string;
|
|
31
|
+
readonly glueSha256: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface MaterialCookIdentity {
|
|
35
|
+
readonly materialContractDigest: string;
|
|
36
|
+
readonly sourceRevision: string;
|
|
37
|
+
readonly sourceClosureDigest: string;
|
|
38
|
+
readonly layoutIdentity: string;
|
|
39
|
+
readonly programIdentity: string;
|
|
40
|
+
readonly pipelineIdentity: string;
|
|
41
|
+
readonly materialPublicationIdentity: string;
|
|
42
|
+
readonly cookIdentity: string;
|
|
43
|
+
readonly compilerFingerprint: string;
|
|
44
|
+
readonly wasm: MaterialCookWasmProvenance;
|
|
45
|
+
readonly artifactDigest: string;
|
|
46
|
+
readonly valueGeneration: number;
|
|
47
|
+
readonly dependencyGeneration: number;
|
|
48
|
+
readonly cookGeneration: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type MaterialCookIdentityInput = Omit<MaterialCookIdentity, 'cookIdentity'>;
|
|
52
|
+
|
|
28
53
|
export interface MaterialCookReceipt {
|
|
29
|
-
readonly schemaVersion: 'material-cook/
|
|
54
|
+
readonly schemaVersion: 'material-cook/3';
|
|
30
55
|
readonly sourceClosure: readonly string[];
|
|
31
56
|
readonly profile: string;
|
|
32
57
|
readonly compilerVersion: string;
|
|
33
|
-
readonly
|
|
34
|
-
readonly outputDigest: string;
|
|
35
|
-
readonly layoutIdentity: string;
|
|
58
|
+
readonly identity: MaterialCookIdentity;
|
|
36
59
|
readonly derivedInterface: { readonly layoutIdentity: string };
|
|
37
|
-
readonly publicationGeneration?: number;
|
|
38
60
|
}
|
|
39
61
|
|
|
40
62
|
export interface MaterialParameterContract {
|
|
@@ -43,7 +65,7 @@ export interface MaterialParameterContract {
|
|
|
43
65
|
}
|
|
44
66
|
|
|
45
67
|
export interface CookedMaterialRecord {
|
|
46
|
-
readonly schemaVersion: 'material-cook/
|
|
68
|
+
readonly schemaVersion: 'material-cook/3';
|
|
47
69
|
readonly guid: string;
|
|
48
70
|
readonly authored?: MaterialAsset;
|
|
49
71
|
readonly materialGuid?: string;
|
|
@@ -66,7 +88,11 @@ export interface MaterialCookRecordError {
|
|
|
66
88
|
readonly code: 'material-cook-record-invalid';
|
|
67
89
|
readonly expected: string;
|
|
68
90
|
readonly hint: string;
|
|
69
|
-
readonly detail: {
|
|
91
|
+
readonly detail: {
|
|
92
|
+
readonly field: string;
|
|
93
|
+
readonly actual?: unknown;
|
|
94
|
+
readonly action: string;
|
|
95
|
+
};
|
|
70
96
|
}
|
|
71
97
|
|
|
72
98
|
export interface MaterialCookIdentityExpectation {
|
|
@@ -154,6 +180,27 @@ function jsonValue(value: unknown): unknown {
|
|
|
154
180
|
return value;
|
|
155
181
|
}
|
|
156
182
|
|
|
183
|
+
export function createMaterialCookIdentity(input: MaterialCookIdentityInput): MaterialCookIdentity {
|
|
184
|
+
const cookIdentity = createMaterialArtifactDigest(
|
|
185
|
+
new TextEncoder().encode(
|
|
186
|
+
JSON.stringify(
|
|
187
|
+
jsonValue({
|
|
188
|
+
materialContractDigest: input.materialContractDigest,
|
|
189
|
+
sourceRevision: input.sourceRevision,
|
|
190
|
+
sourceClosureDigest: input.sourceClosureDigest,
|
|
191
|
+
layoutIdentity: input.layoutIdentity,
|
|
192
|
+
programIdentity: input.programIdentity,
|
|
193
|
+
pipelineIdentity: input.pipelineIdentity,
|
|
194
|
+
compilerFingerprint: input.compilerFingerprint,
|
|
195
|
+
wasm: input.wasm,
|
|
196
|
+
artifactDigest: input.artifactDigest,
|
|
197
|
+
}),
|
|
198
|
+
),
|
|
199
|
+
),
|
|
200
|
+
);
|
|
201
|
+
return { ...input, cookIdentity };
|
|
202
|
+
}
|
|
203
|
+
|
|
157
204
|
export function serializeCookedMaterialRecord(record: CookedMaterialRecord): string {
|
|
158
205
|
return JSON.stringify(jsonValue(record));
|
|
159
206
|
}
|
|
@@ -162,83 +209,116 @@ export function serializeMaterialCookReceipt(receipt: MaterialCookReceipt): stri
|
|
|
162
209
|
return JSON.stringify(jsonValue({ ...receipt, sourceClosure: unique(receipt.sourceClosure) }));
|
|
163
210
|
}
|
|
164
211
|
|
|
165
|
-
function invalid(field: string): Result<never, MaterialCookRecordError> {
|
|
212
|
+
function invalid(field: string, actual?: unknown): Result<never, MaterialCookRecordError> {
|
|
166
213
|
return err({
|
|
167
214
|
code: 'material-cook-record-invalid',
|
|
168
|
-
expected: 'a complete material-cook/
|
|
215
|
+
expected: 'a complete material-cook/3 record with layered identity and provenance',
|
|
169
216
|
hint: 're-cook the material and publish its record, artifact, references, and receipt together',
|
|
170
|
-
detail: {
|
|
217
|
+
detail: {
|
|
218
|
+
field,
|
|
219
|
+
...(actual === undefined ? {} : { actual }),
|
|
220
|
+
action: 'inspect the named field and recook the material generation',
|
|
221
|
+
},
|
|
171
222
|
});
|
|
172
223
|
}
|
|
173
224
|
|
|
225
|
+
const IDENTITY_FIELDS = [
|
|
226
|
+
'materialContractDigest',
|
|
227
|
+
'sourceRevision',
|
|
228
|
+
'sourceClosureDigest',
|
|
229
|
+
'layoutIdentity',
|
|
230
|
+
'programIdentity',
|
|
231
|
+
'pipelineIdentity',
|
|
232
|
+
'materialPublicationIdentity',
|
|
233
|
+
'cookIdentity',
|
|
234
|
+
'compilerFingerprint',
|
|
235
|
+
'artifactDigest',
|
|
236
|
+
] as const;
|
|
237
|
+
|
|
238
|
+
function isGeneration(value: unknown): value is number {
|
|
239
|
+
return typeof value === 'number' && Number.isSafeInteger(value) && value >= 1;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function validateIdentity(value: unknown): Result<MaterialCookIdentity, MaterialCookRecordError> {
|
|
243
|
+
if (value === null || typeof value !== 'object') return invalid('receipt.identity', value);
|
|
244
|
+
const candidate = value as Record<string, unknown>;
|
|
245
|
+
for (const field of IDENTITY_FIELDS) {
|
|
246
|
+
if (typeof candidate[field] !== 'string' || candidate[field].length === 0) {
|
|
247
|
+
return invalid(`receipt.identity.${field}`, candidate[field]);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (candidate.wasm === null || typeof candidate.wasm !== 'object') {
|
|
251
|
+
return invalid('receipt.identity.wasm', candidate.wasm);
|
|
252
|
+
}
|
|
253
|
+
const wasm = candidate.wasm as Record<string, unknown>;
|
|
254
|
+
for (const field of ['sourceContentKey', 'artifactSha256', 'glueSha256']) {
|
|
255
|
+
if (typeof wasm[field] !== 'string' || wasm[field].length === 0) {
|
|
256
|
+
return invalid(`receipt.identity.wasm.${field}`, wasm[field]);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
for (const field of ['valueGeneration', 'dependencyGeneration', 'cookGeneration']) {
|
|
260
|
+
if (!isGeneration(candidate[field]))
|
|
261
|
+
return invalid(`receipt.identity.${field}`, candidate[field]);
|
|
262
|
+
}
|
|
263
|
+
return ok({
|
|
264
|
+
...candidate,
|
|
265
|
+
wasm: wasm as unknown as MaterialCookWasmProvenance,
|
|
266
|
+
} as MaterialCookIdentity);
|
|
267
|
+
}
|
|
268
|
+
|
|
174
269
|
export function validateMaterialCookReceipt(
|
|
175
270
|
value: unknown,
|
|
176
271
|
expected: MaterialCookIdentityExpectation = {},
|
|
177
272
|
): Result<MaterialCookReceipt, MaterialCookRecordError> {
|
|
178
273
|
if (value === null || typeof value !== 'object') return invalid('receipt');
|
|
179
274
|
const candidate = value as Record<string, unknown>;
|
|
180
|
-
if (candidate.schemaVersion !== 'material-cook/
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
275
|
+
if (candidate.schemaVersion !== 'material-cook/3')
|
|
276
|
+
return invalid('receipt.schemaVersion', candidate.schemaVersion);
|
|
277
|
+
const identityResult = validateIdentity(candidate.identity);
|
|
278
|
+
if (!identityResult.ok) return identityResult;
|
|
279
|
+
const identity = identityResult.value;
|
|
184
280
|
if (candidate.derivedInterface === null || typeof candidate.derivedInterface !== 'object') {
|
|
185
|
-
return invalid('receipt.derivedInterface');
|
|
281
|
+
return invalid('receipt.derivedInterface', candidate.derivedInterface);
|
|
186
282
|
}
|
|
187
283
|
const derivedInterface = candidate.derivedInterface as Record<string, unknown>;
|
|
188
|
-
if (derivedInterface.layoutIdentity !==
|
|
189
|
-
return invalid('receipt.derivedInterface.layoutIdentity');
|
|
284
|
+
if (derivedInterface.layoutIdentity !== identity.layoutIdentity) {
|
|
285
|
+
return invalid('receipt.derivedInterface.layoutIdentity', derivedInterface.layoutIdentity);
|
|
190
286
|
}
|
|
191
|
-
for (const field of [
|
|
192
|
-
'sourceClosure',
|
|
193
|
-
'profile',
|
|
194
|
-
'compilerVersion',
|
|
195
|
-
'inputDigest',
|
|
196
|
-
'outputDigest',
|
|
197
|
-
]) {
|
|
287
|
+
for (const field of ['sourceClosure', 'profile', 'compilerVersion']) {
|
|
198
288
|
const fieldValue = candidate[field];
|
|
199
289
|
if (
|
|
200
290
|
(field === 'sourceClosure' && !Array.isArray(fieldValue)) ||
|
|
201
291
|
(field !== 'sourceClosure' && typeof fieldValue !== 'string')
|
|
202
292
|
) {
|
|
203
|
-
return invalid(`receipt.${field}
|
|
293
|
+
return invalid(`receipt.${field}`, fieldValue);
|
|
204
294
|
}
|
|
205
295
|
}
|
|
206
296
|
const sourceClosure = candidate.sourceClosure;
|
|
207
297
|
if (Array.isArray(sourceClosure) && sourceClosure.some((path) => typeof path !== 'string')) {
|
|
208
|
-
return invalid('receipt.sourceClosure');
|
|
298
|
+
return invalid('receipt.sourceClosure', sourceClosure);
|
|
209
299
|
}
|
|
210
300
|
if (
|
|
211
301
|
expected.layoutIdentity !== undefined &&
|
|
212
|
-
|
|
302
|
+
identity.layoutIdentity !== expected.layoutIdentity
|
|
213
303
|
) {
|
|
214
|
-
return invalid('receipt.layoutIdentity');
|
|
215
|
-
}
|
|
216
|
-
if (expected.artifactDigest !== undefined && candidate.outputDigest !== expected.artifactDigest) {
|
|
217
|
-
return invalid('receipt.outputDigest');
|
|
218
|
-
}
|
|
219
|
-
if (expected.inputDigest !== undefined && candidate.inputDigest !== expected.inputDigest) {
|
|
220
|
-
return invalid('receipt.inputDigest');
|
|
304
|
+
return invalid('receipt.identity.layoutIdentity', identity.layoutIdentity);
|
|
221
305
|
}
|
|
222
306
|
if (
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
!Number.isSafeInteger(candidate.publicationGeneration) ||
|
|
226
|
-
candidate.publicationGeneration < 1)
|
|
307
|
+
expected.artifactDigest !== undefined &&
|
|
308
|
+
identity.artifactDigest !== expected.artifactDigest
|
|
227
309
|
) {
|
|
228
|
-
return invalid('receipt.
|
|
310
|
+
return invalid('receipt.identity.artifactDigest', identity.artifactDigest);
|
|
311
|
+
}
|
|
312
|
+
if (expected.inputDigest !== undefined && identity.cookIdentity !== expected.inputDigest) {
|
|
313
|
+
return invalid('receipt.identity.cookIdentity', identity.cookIdentity);
|
|
229
314
|
}
|
|
230
315
|
return ok({
|
|
231
|
-
schemaVersion: 'material-cook/
|
|
316
|
+
schemaVersion: 'material-cook/3',
|
|
232
317
|
sourceClosure: candidate.sourceClosure as string[],
|
|
233
318
|
profile: candidate.profile as string,
|
|
234
319
|
compilerVersion: candidate.compilerVersion as string,
|
|
235
|
-
|
|
236
|
-
outputDigest: candidate.outputDigest as string,
|
|
237
|
-
layoutIdentity: candidate.layoutIdentity,
|
|
320
|
+
identity,
|
|
238
321
|
derivedInterface: { layoutIdentity: derivedInterface.layoutIdentity as string },
|
|
239
|
-
...(candidate.publicationGeneration === undefined
|
|
240
|
-
? {}
|
|
241
|
-
: { publicationGeneration: candidate.publicationGeneration as number }),
|
|
242
322
|
});
|
|
243
323
|
}
|
|
244
324
|
|
|
@@ -247,17 +327,16 @@ export function validateCookedMaterialRecord(
|
|
|
247
327
|
): Result<CookedMaterialRecord, MaterialCookRecordError> {
|
|
248
328
|
if (value === null || typeof value !== 'object') return invalid('record');
|
|
249
329
|
const candidate = value as Record<string, unknown>;
|
|
250
|
-
if (candidate.schemaVersion !== 'material-cook/
|
|
330
|
+
if (candidate.schemaVersion !== 'material-cook/3')
|
|
331
|
+
return invalid('schemaVersion', candidate.schemaVersion);
|
|
251
332
|
if (typeof candidate.guid !== 'string' || !candidate.guid) return invalid('guid');
|
|
252
333
|
if (candidate.materialGuid !== undefined && typeof candidate.materialGuid !== 'string')
|
|
253
334
|
return invalid('materialGuid');
|
|
254
335
|
if (
|
|
255
336
|
candidate.publicationGeneration !== undefined &&
|
|
256
|
-
(
|
|
257
|
-
!Number.isSafeInteger(candidate.publicationGeneration) ||
|
|
258
|
-
candidate.publicationGeneration < 1)
|
|
337
|
+
!isGeneration(candidate.publicationGeneration)
|
|
259
338
|
)
|
|
260
|
-
return invalid('publicationGeneration');
|
|
339
|
+
return invalid('publicationGeneration', candidate.publicationGeneration);
|
|
261
340
|
if (candidate.specializationKey !== undefined && typeof candidate.specializationKey !== 'string')
|
|
262
341
|
return invalid('specializationKey');
|
|
263
342
|
if (candidate.artifactDigest !== undefined && typeof candidate.artifactDigest !== 'string')
|
|
@@ -300,12 +379,12 @@ export function validateCookedMaterialRecord(
|
|
|
300
379
|
});
|
|
301
380
|
if (!receiptResult.ok) return receiptResult;
|
|
302
381
|
if (candidate.artifactDigest !== undefined && candidate.artifactDigest !== artifact.digest)
|
|
303
|
-
return invalid('artifactDigest');
|
|
382
|
+
return invalid('artifactDigest', candidate.artifactDigest);
|
|
304
383
|
if (
|
|
305
384
|
candidate.publicationGeneration !== undefined &&
|
|
306
|
-
receiptResult.value.
|
|
385
|
+
receiptResult.value.identity.cookGeneration !== candidate.publicationGeneration
|
|
307
386
|
)
|
|
308
|
-
return invalid('receipt.
|
|
387
|
+
return invalid('receipt.identity.cookGeneration', receiptResult.value.identity.cookGeneration);
|
|
309
388
|
const normalized = {
|
|
310
389
|
...candidate,
|
|
311
390
|
artifact: {
|
package/src/index.ts
CHANGED
|
@@ -6,11 +6,15 @@ export {
|
|
|
6
6
|
type CookedMaterialRecord,
|
|
7
7
|
collectMaterialCookRefs,
|
|
8
8
|
createMaterialArtifactDigest,
|
|
9
|
+
createMaterialCookIdentity,
|
|
9
10
|
type MaterialCookArtifact,
|
|
11
|
+
type MaterialCookIdentity,
|
|
10
12
|
type MaterialCookIdentityExpectation,
|
|
13
|
+
type MaterialCookIdentityInput,
|
|
11
14
|
type MaterialCookReceipt,
|
|
12
15
|
type MaterialCookRecordError,
|
|
13
16
|
type MaterialCookRefs,
|
|
17
|
+
type MaterialCookWasmProvenance,
|
|
14
18
|
projectCookedMaterialRecord,
|
|
15
19
|
serializeCookedMaterialRecord,
|
|
16
20
|
serializeMaterialCookReceipt,
|
package/src/material-cook.ts
CHANGED
|
@@ -2,10 +2,12 @@ export {
|
|
|
2
2
|
type CookedMaterialRecord,
|
|
3
3
|
collectMaterialCookRefs,
|
|
4
4
|
createMaterialArtifactDigest,
|
|
5
|
+
createMaterialCookIdentity,
|
|
5
6
|
type MaterialCookArtifact,
|
|
6
7
|
type MaterialCookReceipt,
|
|
7
8
|
type MaterialCookRecordError,
|
|
8
9
|
type MaterialCookRefs,
|
|
10
|
+
type MaterialCookWasmProvenance,
|
|
9
11
|
projectCookedMaterialRecord,
|
|
10
12
|
serializeCookedMaterialRecord,
|
|
11
13
|
serializeMaterialCookReceipt,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"type": "object",
|
|
5
5
|
"required": ["schemaVersion", "guid", "resolved", "refs", "artifact", "receipt"],
|
|
6
6
|
"properties": {
|
|
7
|
-
"schemaVersion": { "const": "material-cook/
|
|
7
|
+
"schemaVersion": { "const": "material-cook/3" },
|
|
8
8
|
"guid": { "type": "string", "minLength": 1 },
|
|
9
9
|
"materialGuid": { "type": "string", "minLength": 1 },
|
|
10
10
|
"publicationGeneration": { "type": "integer", "minimum": 1 },
|
|
@@ -51,19 +51,59 @@
|
|
|
51
51
|
"sourceClosure",
|
|
52
52
|
"profile",
|
|
53
53
|
"compilerVersion",
|
|
54
|
-
"
|
|
55
|
-
"outputDigest",
|
|
56
|
-
"layoutIdentity",
|
|
54
|
+
"identity",
|
|
57
55
|
"derivedInterface"
|
|
58
56
|
],
|
|
59
57
|
"properties": {
|
|
60
|
-
"schemaVersion": { "const": "material-cook/
|
|
58
|
+
"schemaVersion": { "const": "material-cook/3" },
|
|
61
59
|
"sourceClosure": { "type": "array", "items": { "type": "string" } },
|
|
62
60
|
"profile": { "type": "string" },
|
|
63
61
|
"compilerVersion": { "type": "string" },
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
"identity": {
|
|
63
|
+
"type": "object",
|
|
64
|
+
"required": [
|
|
65
|
+
"materialContractDigest",
|
|
66
|
+
"sourceRevision",
|
|
67
|
+
"sourceClosureDigest",
|
|
68
|
+
"layoutIdentity",
|
|
69
|
+
"programIdentity",
|
|
70
|
+
"pipelineIdentity",
|
|
71
|
+
"materialPublicationIdentity",
|
|
72
|
+
"cookIdentity",
|
|
73
|
+
"compilerFingerprint",
|
|
74
|
+
"wasm",
|
|
75
|
+
"artifactDigest",
|
|
76
|
+
"valueGeneration",
|
|
77
|
+
"dependencyGeneration",
|
|
78
|
+
"cookGeneration"
|
|
79
|
+
],
|
|
80
|
+
"properties": {
|
|
81
|
+
"materialContractDigest": { "type": "string", "minLength": 1 },
|
|
82
|
+
"sourceRevision": { "type": "string", "minLength": 1 },
|
|
83
|
+
"sourceClosureDigest": { "type": "string", "minLength": 1 },
|
|
84
|
+
"layoutIdentity": { "type": "string", "minLength": 1 },
|
|
85
|
+
"programIdentity": { "type": "string", "minLength": 1 },
|
|
86
|
+
"pipelineIdentity": { "type": "string", "minLength": 1 },
|
|
87
|
+
"materialPublicationIdentity": { "type": "string", "minLength": 1 },
|
|
88
|
+
"cookIdentity": { "type": "string", "minLength": 1 },
|
|
89
|
+
"compilerFingerprint": { "type": "string", "minLength": 1 },
|
|
90
|
+
"wasm": {
|
|
91
|
+
"type": "object",
|
|
92
|
+
"required": ["sourceContentKey", "artifactSha256", "glueSha256"],
|
|
93
|
+
"properties": {
|
|
94
|
+
"sourceContentKey": { "type": "string", "minLength": 1 },
|
|
95
|
+
"artifactSha256": { "type": "string", "minLength": 1 },
|
|
96
|
+
"glueSha256": { "type": "string", "minLength": 1 }
|
|
97
|
+
},
|
|
98
|
+
"additionalProperties": false
|
|
99
|
+
},
|
|
100
|
+
"artifactDigest": { "type": "string", "minLength": 1 },
|
|
101
|
+
"valueGeneration": { "type": "integer", "minimum": 1 },
|
|
102
|
+
"dependencyGeneration": { "type": "integer", "minimum": 1 },
|
|
103
|
+
"cookGeneration": { "type": "integer", "minimum": 1 }
|
|
104
|
+
},
|
|
105
|
+
"additionalProperties": false
|
|
106
|
+
},
|
|
67
107
|
"derivedInterface": {
|
|
68
108
|
"type": "object",
|
|
69
109
|
"required": ["layoutIdentity"],
|
|
@@ -670,7 +670,10 @@ export async function loadScriptablePack(
|
|
|
670
670
|
sourcePath: string,
|
|
671
671
|
options: LoadScriptablePackOptions = {},
|
|
672
672
|
): Promise<Result<Readonly<ScriptablePackDefinition>, ScriptablePackError>> {
|
|
673
|
-
|
|
673
|
+
// Module initialization includes transpiling the trusted TypeScript source
|
|
674
|
+
// closure in a fresh Worker. A cold SDK workspace can legitimately exceed
|
|
675
|
+
// the build execution budget before any authored build() code has run.
|
|
676
|
+
const timeoutMs = options.timeoutMs ?? 15_000;
|
|
674
677
|
const buildTimeoutMs = options.buildTimeoutMs ?? 5_000;
|
|
675
678
|
const executor = options.executor ?? new WorkerScriptablePackExecutor();
|
|
676
679
|
let disposeReason: 'complete' | 'timeout' | 'failure' | undefined;
|