@forgeax/engine-pack 0.1.20 → 0.1.21
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/.tsbuildinfo +1 -1
- package/dist/build.mjs +3 -1
- package/dist/build.mjs.map +1 -1
- package/dist/evidence/material-cook.d.ts.map +1 -1
- package/dist/index.mjs +3 -1
- package/dist/index.mjs.map +1 -1
- package/dist/material-cook.mjs +3 -1
- package/dist/material-cook.mjs.map +1 -1
- package/package.json +2 -2
- package/src/evidence/material-cook.ts +3 -1
package/dist/material-cook.mjs
CHANGED
|
@@ -23,7 +23,9 @@ function textureValues(values, textureFields) {
|
|
|
23
23
|
}
|
|
24
24
|
function collectMaterialCookRefs(material) {
|
|
25
25
|
const textureFields = material.parameters === void 0 ? new Set(MATERIAL_TEXTURE_SLOTS) : new Set(
|
|
26
|
-
material.parameters.filter(
|
|
26
|
+
material.parameters.filter(
|
|
27
|
+
(parameter) => parameter.type === "texture" || parameter.type === "texture_cube"
|
|
28
|
+
).map((parameter) => parameter.name)
|
|
27
29
|
);
|
|
28
30
|
const textures = textureValues(material.values, textureFields);
|
|
29
31
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/evidence/material-cook.ts"],"names":[],"mappings":"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","file":"material-cook.mjs","sourcesContent":["import type {\n MaterialAsset,\n MaterialParameter,\n MaterialPass,\n MaterialTextureReference,\n MaterialTextureValue,\n MaterialValue,\n Result,\n} from '@forgeax/engine-types';\nimport { err, MATERIAL_TEXTURE_SLOTS, ok } from '@forgeax/engine-types';\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { bytesToHex } from '@noble/hashes/utils.js';\n\nexport interface MaterialCookRefs {\n readonly parent: readonly string[];\n readonly textures: readonly string[];\n readonly samplers: readonly string[];\n readonly modules: readonly string[];\n}\n\nexport interface MaterialCookArtifact {\n readonly mediaType: string;\n readonly path: string;\n readonly digest: string;\n readonly bytes: Uint8Array;\n}\n\nexport interface MaterialCookWasmProvenance {\n readonly sourceContentKey: string;\n readonly artifactSha256: string;\n readonly glueSha256: string;\n}\n\nexport interface MaterialCookIdentity {\n readonly materialContractDigest: string;\n readonly sourceRevision: string;\n readonly sourceClosureDigest: string;\n readonly layoutIdentity: string;\n readonly programIdentity: string;\n readonly pipelineIdentity: string;\n readonly materialPublicationIdentity: string;\n readonly cookIdentity: string;\n readonly compilerFingerprint: string;\n readonly wasm: MaterialCookWasmProvenance;\n readonly artifactDigest: string;\n readonly valueGeneration: number;\n readonly dependencyGeneration: number;\n readonly cookGeneration: number;\n}\n\nexport type MaterialCookIdentityInput = Omit<MaterialCookIdentity, 'cookIdentity'>;\n\nexport interface MaterialCookReceipt {\n readonly schemaVersion: 'material-cook/3';\n readonly sourceClosure: readonly string[];\n readonly profile: string;\n readonly compilerVersion: string;\n readonly identity: MaterialCookIdentity;\n readonly derivedInterface: { readonly layoutIdentity: string };\n}\n\nexport interface MaterialParameterContract {\n readonly parameters: readonly MaterialParameter[];\n readonly values: Readonly<Record<string, MaterialValue | null>>;\n}\n\nexport interface CookedMaterialRecord {\n readonly schemaVersion: 'material-cook/3';\n readonly guid: string;\n readonly authored?: MaterialAsset;\n readonly materialGuid?: string;\n readonly publicationGeneration?: number;\n readonly specializationKey?: string;\n readonly artifactDigest?: string;\n readonly sourceClosure?: readonly string[];\n readonly parameterContract?: MaterialParameterContract;\n readonly resolved: {\n readonly passes: readonly MaterialPass[];\n readonly parameters: readonly MaterialParameter[];\n readonly values: Readonly<Record<string, MaterialValue | null>>;\n };\n readonly refs: MaterialCookRefs;\n readonly artifact: MaterialCookArtifact;\n readonly receipt: MaterialCookReceipt;\n}\n\nexport interface MaterialCookRecordError {\n readonly code: 'material-cook-record-invalid';\n readonly expected: string;\n readonly hint: string;\n readonly detail: {\n readonly field: string;\n readonly actual?: unknown;\n readonly action: string;\n };\n}\n\nexport interface MaterialCookIdentityExpectation {\n readonly layoutIdentity?: string;\n readonly artifactDigest?: string;\n readonly inputDigest?: string;\n}\n\nfunction unique(values: readonly string[]): readonly string[] {\n return [...new Set(values)].sort();\n}\n\nfunction guidText(value: string | Uint8Array): string {\n return typeof value === 'string'\n ? value\n : Array.from(value, (byte) => byte.toString(16).padStart(2, '0')).join('');\n}\n\nfunction cookGuidText(value: MaterialTextureReference): string | undefined {\n return typeof value === 'number' ? undefined : guidText(value);\n}\n\nfunction textureValues(\n values: Readonly<Record<string, MaterialValue | null>> | undefined,\n textureFields: ReadonlySet<string>,\n): readonly MaterialTextureValue[] {\n return Object.entries(values ?? {}).flatMap(([name, value]) => {\n if (value === null) return [];\n if (typeof value === 'string') {\n return textureFields.has(name) ? [{ texture: value }] : [];\n }\n return value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n 'texture' in value\n ? [value as MaterialTextureValue]\n : [];\n });\n}\n\nexport function collectMaterialCookRefs(material: Partial<MaterialAsset>): MaterialCookRefs {\n const textureFields =\n material.parameters === undefined\n ? new Set<string>(MATERIAL_TEXTURE_SLOTS)\n : new Set(\n material.parameters\n .filter((parameter) => parameter.type === 'texture')\n .map((parameter) => parameter.name),\n );\n const textures = textureValues(material.values, textureFields);\n return {\n parent: material.parent ? [guidText(material.parent)] : [],\n textures: unique(\n textures.flatMap((value) => {\n const guid = cookGuidText(value.texture);\n return guid === undefined ? [] : [guid];\n }),\n ),\n samplers: unique(\n textures.flatMap((value) => {\n if (value.sampler === undefined) return [];\n const guid = cookGuidText(value.sampler);\n return guid === undefined ? [] : [guid];\n }),\n ),\n modules: unique((material.passes ?? []).map((pass) => pass.program.module)),\n };\n}\n\nexport function createMaterialArtifactDigest(bytes: Uint8Array): string {\n return `sha256:${bytesToHex(sha256(bytes))}`;\n}\n\nfunction jsonValue(value: unknown): unknown {\n if (value instanceof Uint8Array) return [...value];\n if (Array.isArray(value)) return value.map(jsonValue);\n if (value !== null && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value)\n .filter(([, entry]) => entry !== undefined)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, entry]) => [key, jsonValue(entry)]),\n );\n }\n return value;\n}\n\nexport function createMaterialCookIdentity(input: MaterialCookIdentityInput): MaterialCookIdentity {\n const cookIdentity = createMaterialArtifactDigest(\n new TextEncoder().encode(\n JSON.stringify(\n jsonValue({\n materialContractDigest: input.materialContractDigest,\n sourceRevision: input.sourceRevision,\n sourceClosureDigest: input.sourceClosureDigest,\n layoutIdentity: input.layoutIdentity,\n programIdentity: input.programIdentity,\n pipelineIdentity: input.pipelineIdentity,\n compilerFingerprint: input.compilerFingerprint,\n wasm: input.wasm,\n artifactDigest: input.artifactDigest,\n }),\n ),\n ),\n );\n return { ...input, cookIdentity };\n}\n\nexport function serializeCookedMaterialRecord(record: CookedMaterialRecord): string {\n return JSON.stringify(jsonValue(record));\n}\n\nexport function serializeMaterialCookReceipt(receipt: MaterialCookReceipt): string {\n return JSON.stringify(jsonValue({ ...receipt, sourceClosure: unique(receipt.sourceClosure) }));\n}\n\nfunction invalid(field: string, actual?: unknown): Result<never, MaterialCookRecordError> {\n return err({\n code: 'material-cook-record-invalid',\n expected: 'a complete material-cook/3 record with layered identity and provenance',\n hint: 're-cook the material and publish its record, artifact, references, and receipt together',\n detail: {\n field,\n ...(actual === undefined ? {} : { actual }),\n action: 'inspect the named field and recook the material generation',\n },\n });\n}\n\nconst IDENTITY_FIELDS = [\n 'materialContractDigest',\n 'sourceRevision',\n 'sourceClosureDigest',\n 'layoutIdentity',\n 'programIdentity',\n 'pipelineIdentity',\n 'materialPublicationIdentity',\n 'cookIdentity',\n 'compilerFingerprint',\n 'artifactDigest',\n] as const;\n\nfunction isGeneration(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 1;\n}\n\nfunction validateIdentity(value: unknown): Result<MaterialCookIdentity, MaterialCookRecordError> {\n if (value === null || typeof value !== 'object') return invalid('receipt.identity', value);\n const candidate = value as Record<string, unknown>;\n for (const field of IDENTITY_FIELDS) {\n if (typeof candidate[field] !== 'string' || candidate[field].length === 0) {\n return invalid(`receipt.identity.${field}`, candidate[field]);\n }\n }\n if (candidate.wasm === null || typeof candidate.wasm !== 'object') {\n return invalid('receipt.identity.wasm', candidate.wasm);\n }\n const wasm = candidate.wasm as Record<string, unknown>;\n for (const field of ['sourceContentKey', 'artifactSha256', 'glueSha256']) {\n if (typeof wasm[field] !== 'string' || wasm[field].length === 0) {\n return invalid(`receipt.identity.wasm.${field}`, wasm[field]);\n }\n }\n for (const field of ['valueGeneration', 'dependencyGeneration', 'cookGeneration']) {\n if (!isGeneration(candidate[field]))\n return invalid(`receipt.identity.${field}`, candidate[field]);\n }\n return ok({\n ...candidate,\n wasm: wasm as unknown as MaterialCookWasmProvenance,\n } as MaterialCookIdentity);\n}\n\nexport function validateMaterialCookReceipt(\n value: unknown,\n expected: MaterialCookIdentityExpectation = {},\n): Result<MaterialCookReceipt, MaterialCookRecordError> {\n if (value === null || typeof value !== 'object') return invalid('receipt');\n const candidate = value as Record<string, unknown>;\n if (candidate.schemaVersion !== 'material-cook/3')\n return invalid('receipt.schemaVersion', candidate.schemaVersion);\n const identityResult = validateIdentity(candidate.identity);\n if (!identityResult.ok) return identityResult;\n const identity = identityResult.value;\n if (candidate.derivedInterface === null || typeof candidate.derivedInterface !== 'object') {\n return invalid('receipt.derivedInterface', candidate.derivedInterface);\n }\n const derivedInterface = candidate.derivedInterface as Record<string, unknown>;\n if (derivedInterface.layoutIdentity !== identity.layoutIdentity) {\n return invalid('receipt.derivedInterface.layoutIdentity', derivedInterface.layoutIdentity);\n }\n for (const field of ['sourceClosure', 'profile', 'compilerVersion']) {\n const fieldValue = candidate[field];\n if (\n (field === 'sourceClosure' && !Array.isArray(fieldValue)) ||\n (field !== 'sourceClosure' && typeof fieldValue !== 'string')\n ) {\n return invalid(`receipt.${field}`, fieldValue);\n }\n }\n const sourceClosure = candidate.sourceClosure;\n if (Array.isArray(sourceClosure) && sourceClosure.some((path) => typeof path !== 'string')) {\n return invalid('receipt.sourceClosure', sourceClosure);\n }\n if (\n expected.layoutIdentity !== undefined &&\n identity.layoutIdentity !== expected.layoutIdentity\n ) {\n return invalid('receipt.identity.layoutIdentity', identity.layoutIdentity);\n }\n if (\n expected.artifactDigest !== undefined &&\n identity.artifactDigest !== expected.artifactDigest\n ) {\n return invalid('receipt.identity.artifactDigest', identity.artifactDigest);\n }\n if (expected.inputDigest !== undefined && identity.cookIdentity !== expected.inputDigest) {\n return invalid('receipt.identity.cookIdentity', identity.cookIdentity);\n }\n return ok({\n schemaVersion: 'material-cook/3',\n sourceClosure: candidate.sourceClosure as string[],\n profile: candidate.profile as string,\n compilerVersion: candidate.compilerVersion as string,\n identity,\n derivedInterface: { layoutIdentity: derivedInterface.layoutIdentity as string },\n });\n}\n\nexport function validateCookedMaterialRecord(\n value: unknown,\n): Result<CookedMaterialRecord, MaterialCookRecordError> {\n if (value === null || typeof value !== 'object') return invalid('record');\n const candidate = value as Record<string, unknown>;\n if (candidate.schemaVersion !== 'material-cook/3')\n return invalid('schemaVersion', candidate.schemaVersion);\n if (typeof candidate.guid !== 'string' || !candidate.guid) return invalid('guid');\n if (candidate.materialGuid !== undefined && typeof candidate.materialGuid !== 'string')\n return invalid('materialGuid');\n if (\n candidate.publicationGeneration !== undefined &&\n !isGeneration(candidate.publicationGeneration)\n )\n return invalid('publicationGeneration', candidate.publicationGeneration);\n if (candidate.specializationKey !== undefined && typeof candidate.specializationKey !== 'string')\n return invalid('specializationKey');\n if (candidate.artifactDigest !== undefined && typeof candidate.artifactDigest !== 'string')\n return invalid('artifactDigest');\n if (\n candidate.sourceClosure !== undefined &&\n (!Array.isArray(candidate.sourceClosure) ||\n candidate.sourceClosure.some((path) => typeof path !== 'string'))\n )\n return invalid('sourceClosure');\n if (candidate.parameterContract !== undefined) {\n if (candidate.parameterContract === null || typeof candidate.parameterContract !== 'object')\n return invalid('parameterContract');\n const parameterContract = candidate.parameterContract as Record<string, unknown>;\n if (!Array.isArray(parameterContract.parameters))\n return invalid('parameterContract.parameters');\n if (\n parameterContract.values === null ||\n typeof parameterContract.values !== 'object' ||\n Array.isArray(parameterContract.values)\n )\n return invalid('parameterContract.values');\n }\n if (candidate.resolved === null || typeof candidate.resolved !== 'object')\n return invalid('resolved');\n if (candidate.refs === null || typeof candidate.refs !== 'object') return invalid('refs');\n if (candidate.artifact === null || typeof candidate.artifact !== 'object')\n return invalid('artifact');\n if (candidate.receipt === null || typeof candidate.receipt !== 'object')\n return invalid('receipt');\n const artifact = candidate.artifact as Record<string, unknown>;\n if (\n typeof artifact.digest !== 'string' ||\n (!Array.isArray(artifact.bytes) && !ArrayBuffer.isView(artifact.bytes))\n ) {\n return invalid('artifact');\n }\n const receiptResult = validateMaterialCookReceipt(candidate.receipt, {\n artifactDigest: artifact.digest as string,\n });\n if (!receiptResult.ok) return receiptResult;\n if (candidate.artifactDigest !== undefined && candidate.artifactDigest !== artifact.digest)\n return invalid('artifactDigest', candidate.artifactDigest);\n if (\n candidate.publicationGeneration !== undefined &&\n receiptResult.value.identity.cookGeneration !== candidate.publicationGeneration\n )\n return invalid('receipt.identity.cookGeneration', receiptResult.value.identity.cookGeneration);\n const normalized = {\n ...candidate,\n artifact: {\n ...artifact,\n bytes: ArrayBuffer.isView(artifact.bytes)\n ? Uint8Array.from(artifact.bytes as Uint8Array)\n : Uint8Array.from(artifact.bytes as number[]),\n },\n receipt: receiptResult.value,\n } as CookedMaterialRecord;\n return ok(normalized);\n}\n\nexport function projectCookedMaterialRecord(\n record: CookedMaterialRecord,\n): Omit<CookedMaterialRecord, 'guid' | 'authored'> {\n return {\n resolved: record.resolved,\n refs: record.refs,\n artifact: record.artifact,\n receipt: record.receipt,\n schemaVersion: record.schemaVersion,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/evidence/material-cook.ts"],"names":[],"mappings":"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","file":"material-cook.mjs","sourcesContent":["import type {\n MaterialAsset,\n MaterialParameter,\n MaterialPass,\n MaterialTextureReference,\n MaterialTextureValue,\n MaterialValue,\n Result,\n} from '@forgeax/engine-types';\nimport { err, MATERIAL_TEXTURE_SLOTS, ok } from '@forgeax/engine-types';\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { bytesToHex } from '@noble/hashes/utils.js';\n\nexport interface MaterialCookRefs {\n readonly parent: readonly string[];\n readonly textures: readonly string[];\n readonly samplers: readonly string[];\n readonly modules: readonly string[];\n}\n\nexport interface MaterialCookArtifact {\n readonly mediaType: string;\n readonly path: string;\n readonly digest: string;\n readonly bytes: Uint8Array;\n}\n\nexport interface MaterialCookWasmProvenance {\n readonly sourceContentKey: string;\n readonly artifactSha256: string;\n readonly glueSha256: string;\n}\n\nexport interface MaterialCookIdentity {\n readonly materialContractDigest: string;\n readonly sourceRevision: string;\n readonly sourceClosureDigest: string;\n readonly layoutIdentity: string;\n readonly programIdentity: string;\n readonly pipelineIdentity: string;\n readonly materialPublicationIdentity: string;\n readonly cookIdentity: string;\n readonly compilerFingerprint: string;\n readonly wasm: MaterialCookWasmProvenance;\n readonly artifactDigest: string;\n readonly valueGeneration: number;\n readonly dependencyGeneration: number;\n readonly cookGeneration: number;\n}\n\nexport type MaterialCookIdentityInput = Omit<MaterialCookIdentity, 'cookIdentity'>;\n\nexport interface MaterialCookReceipt {\n readonly schemaVersion: 'material-cook/3';\n readonly sourceClosure: readonly string[];\n readonly profile: string;\n readonly compilerVersion: string;\n readonly identity: MaterialCookIdentity;\n readonly derivedInterface: { readonly layoutIdentity: string };\n}\n\nexport interface MaterialParameterContract {\n readonly parameters: readonly MaterialParameter[];\n readonly values: Readonly<Record<string, MaterialValue | null>>;\n}\n\nexport interface CookedMaterialRecord {\n readonly schemaVersion: 'material-cook/3';\n readonly guid: string;\n readonly authored?: MaterialAsset;\n readonly materialGuid?: string;\n readonly publicationGeneration?: number;\n readonly specializationKey?: string;\n readonly artifactDigest?: string;\n readonly sourceClosure?: readonly string[];\n readonly parameterContract?: MaterialParameterContract;\n readonly resolved: {\n readonly passes: readonly MaterialPass[];\n readonly parameters: readonly MaterialParameter[];\n readonly values: Readonly<Record<string, MaterialValue | null>>;\n };\n readonly refs: MaterialCookRefs;\n readonly artifact: MaterialCookArtifact;\n readonly receipt: MaterialCookReceipt;\n}\n\nexport interface MaterialCookRecordError {\n readonly code: 'material-cook-record-invalid';\n readonly expected: string;\n readonly hint: string;\n readonly detail: {\n readonly field: string;\n readonly actual?: unknown;\n readonly action: string;\n };\n}\n\nexport interface MaterialCookIdentityExpectation {\n readonly layoutIdentity?: string;\n readonly artifactDigest?: string;\n readonly inputDigest?: string;\n}\n\nfunction unique(values: readonly string[]): readonly string[] {\n return [...new Set(values)].sort();\n}\n\nfunction guidText(value: string | Uint8Array): string {\n return typeof value === 'string'\n ? value\n : Array.from(value, (byte) => byte.toString(16).padStart(2, '0')).join('');\n}\n\nfunction cookGuidText(value: MaterialTextureReference): string | undefined {\n return typeof value === 'number' ? undefined : guidText(value);\n}\n\nfunction textureValues(\n values: Readonly<Record<string, MaterialValue | null>> | undefined,\n textureFields: ReadonlySet<string>,\n): readonly MaterialTextureValue[] {\n return Object.entries(values ?? {}).flatMap(([name, value]) => {\n if (value === null) return [];\n if (typeof value === 'string') {\n return textureFields.has(name) ? [{ texture: value }] : [];\n }\n return value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n 'texture' in value\n ? [value as MaterialTextureValue]\n : [];\n });\n}\n\nexport function collectMaterialCookRefs(material: Partial<MaterialAsset>): MaterialCookRefs {\n const textureFields =\n material.parameters === undefined\n ? new Set<string>(MATERIAL_TEXTURE_SLOTS)\n : new Set(\n material.parameters\n .filter(\n (parameter) => parameter.type === 'texture' || parameter.type === 'texture_cube',\n )\n .map((parameter) => parameter.name),\n );\n const textures = textureValues(material.values, textureFields);\n return {\n parent: material.parent ? [guidText(material.parent)] : [],\n textures: unique(\n textures.flatMap((value) => {\n const guid = cookGuidText(value.texture);\n return guid === undefined ? [] : [guid];\n }),\n ),\n samplers: unique(\n textures.flatMap((value) => {\n if (value.sampler === undefined) return [];\n const guid = cookGuidText(value.sampler);\n return guid === undefined ? [] : [guid];\n }),\n ),\n modules: unique((material.passes ?? []).map((pass) => pass.program.module)),\n };\n}\n\nexport function createMaterialArtifactDigest(bytes: Uint8Array): string {\n return `sha256:${bytesToHex(sha256(bytes))}`;\n}\n\nfunction jsonValue(value: unknown): unknown {\n if (value instanceof Uint8Array) return [...value];\n if (Array.isArray(value)) return value.map(jsonValue);\n if (value !== null && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value)\n .filter(([, entry]) => entry !== undefined)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, entry]) => [key, jsonValue(entry)]),\n );\n }\n return value;\n}\n\nexport function createMaterialCookIdentity(input: MaterialCookIdentityInput): MaterialCookIdentity {\n const cookIdentity = createMaterialArtifactDigest(\n new TextEncoder().encode(\n JSON.stringify(\n jsonValue({\n materialContractDigest: input.materialContractDigest,\n sourceRevision: input.sourceRevision,\n sourceClosureDigest: input.sourceClosureDigest,\n layoutIdentity: input.layoutIdentity,\n programIdentity: input.programIdentity,\n pipelineIdentity: input.pipelineIdentity,\n compilerFingerprint: input.compilerFingerprint,\n wasm: input.wasm,\n artifactDigest: input.artifactDigest,\n }),\n ),\n ),\n );\n return { ...input, cookIdentity };\n}\n\nexport function serializeCookedMaterialRecord(record: CookedMaterialRecord): string {\n return JSON.stringify(jsonValue(record));\n}\n\nexport function serializeMaterialCookReceipt(receipt: MaterialCookReceipt): string {\n return JSON.stringify(jsonValue({ ...receipt, sourceClosure: unique(receipt.sourceClosure) }));\n}\n\nfunction invalid(field: string, actual?: unknown): Result<never, MaterialCookRecordError> {\n return err({\n code: 'material-cook-record-invalid',\n expected: 'a complete material-cook/3 record with layered identity and provenance',\n hint: 're-cook the material and publish its record, artifact, references, and receipt together',\n detail: {\n field,\n ...(actual === undefined ? {} : { actual }),\n action: 'inspect the named field and recook the material generation',\n },\n });\n}\n\nconst IDENTITY_FIELDS = [\n 'materialContractDigest',\n 'sourceRevision',\n 'sourceClosureDigest',\n 'layoutIdentity',\n 'programIdentity',\n 'pipelineIdentity',\n 'materialPublicationIdentity',\n 'cookIdentity',\n 'compilerFingerprint',\n 'artifactDigest',\n] as const;\n\nfunction isGeneration(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 1;\n}\n\nfunction validateIdentity(value: unknown): Result<MaterialCookIdentity, MaterialCookRecordError> {\n if (value === null || typeof value !== 'object') return invalid('receipt.identity', value);\n const candidate = value as Record<string, unknown>;\n for (const field of IDENTITY_FIELDS) {\n if (typeof candidate[field] !== 'string' || candidate[field].length === 0) {\n return invalid(`receipt.identity.${field}`, candidate[field]);\n }\n }\n if (candidate.wasm === null || typeof candidate.wasm !== 'object') {\n return invalid('receipt.identity.wasm', candidate.wasm);\n }\n const wasm = candidate.wasm as Record<string, unknown>;\n for (const field of ['sourceContentKey', 'artifactSha256', 'glueSha256']) {\n if (typeof wasm[field] !== 'string' || wasm[field].length === 0) {\n return invalid(`receipt.identity.wasm.${field}`, wasm[field]);\n }\n }\n for (const field of ['valueGeneration', 'dependencyGeneration', 'cookGeneration']) {\n if (!isGeneration(candidate[field]))\n return invalid(`receipt.identity.${field}`, candidate[field]);\n }\n return ok({\n ...candidate,\n wasm: wasm as unknown as MaterialCookWasmProvenance,\n } as MaterialCookIdentity);\n}\n\nexport function validateMaterialCookReceipt(\n value: unknown,\n expected: MaterialCookIdentityExpectation = {},\n): Result<MaterialCookReceipt, MaterialCookRecordError> {\n if (value === null || typeof value !== 'object') return invalid('receipt');\n const candidate = value as Record<string, unknown>;\n if (candidate.schemaVersion !== 'material-cook/3')\n return invalid('receipt.schemaVersion', candidate.schemaVersion);\n const identityResult = validateIdentity(candidate.identity);\n if (!identityResult.ok) return identityResult;\n const identity = identityResult.value;\n if (candidate.derivedInterface === null || typeof candidate.derivedInterface !== 'object') {\n return invalid('receipt.derivedInterface', candidate.derivedInterface);\n }\n const derivedInterface = candidate.derivedInterface as Record<string, unknown>;\n if (derivedInterface.layoutIdentity !== identity.layoutIdentity) {\n return invalid('receipt.derivedInterface.layoutIdentity', derivedInterface.layoutIdentity);\n }\n for (const field of ['sourceClosure', 'profile', 'compilerVersion']) {\n const fieldValue = candidate[field];\n if (\n (field === 'sourceClosure' && !Array.isArray(fieldValue)) ||\n (field !== 'sourceClosure' && typeof fieldValue !== 'string')\n ) {\n return invalid(`receipt.${field}`, fieldValue);\n }\n }\n const sourceClosure = candidate.sourceClosure;\n if (Array.isArray(sourceClosure) && sourceClosure.some((path) => typeof path !== 'string')) {\n return invalid('receipt.sourceClosure', sourceClosure);\n }\n if (\n expected.layoutIdentity !== undefined &&\n identity.layoutIdentity !== expected.layoutIdentity\n ) {\n return invalid('receipt.identity.layoutIdentity', identity.layoutIdentity);\n }\n if (\n expected.artifactDigest !== undefined &&\n identity.artifactDigest !== expected.artifactDigest\n ) {\n return invalid('receipt.identity.artifactDigest', identity.artifactDigest);\n }\n if (expected.inputDigest !== undefined && identity.cookIdentity !== expected.inputDigest) {\n return invalid('receipt.identity.cookIdentity', identity.cookIdentity);\n }\n return ok({\n schemaVersion: 'material-cook/3',\n sourceClosure: candidate.sourceClosure as string[],\n profile: candidate.profile as string,\n compilerVersion: candidate.compilerVersion as string,\n identity,\n derivedInterface: { layoutIdentity: derivedInterface.layoutIdentity as string },\n });\n}\n\nexport function validateCookedMaterialRecord(\n value: unknown,\n): Result<CookedMaterialRecord, MaterialCookRecordError> {\n if (value === null || typeof value !== 'object') return invalid('record');\n const candidate = value as Record<string, unknown>;\n if (candidate.schemaVersion !== 'material-cook/3')\n return invalid('schemaVersion', candidate.schemaVersion);\n if (typeof candidate.guid !== 'string' || !candidate.guid) return invalid('guid');\n if (candidate.materialGuid !== undefined && typeof candidate.materialGuid !== 'string')\n return invalid('materialGuid');\n if (\n candidate.publicationGeneration !== undefined &&\n !isGeneration(candidate.publicationGeneration)\n )\n return invalid('publicationGeneration', candidate.publicationGeneration);\n if (candidate.specializationKey !== undefined && typeof candidate.specializationKey !== 'string')\n return invalid('specializationKey');\n if (candidate.artifactDigest !== undefined && typeof candidate.artifactDigest !== 'string')\n return invalid('artifactDigest');\n if (\n candidate.sourceClosure !== undefined &&\n (!Array.isArray(candidate.sourceClosure) ||\n candidate.sourceClosure.some((path) => typeof path !== 'string'))\n )\n return invalid('sourceClosure');\n if (candidate.parameterContract !== undefined) {\n if (candidate.parameterContract === null || typeof candidate.parameterContract !== 'object')\n return invalid('parameterContract');\n const parameterContract = candidate.parameterContract as Record<string, unknown>;\n if (!Array.isArray(parameterContract.parameters))\n return invalid('parameterContract.parameters');\n if (\n parameterContract.values === null ||\n typeof parameterContract.values !== 'object' ||\n Array.isArray(parameterContract.values)\n )\n return invalid('parameterContract.values');\n }\n if (candidate.resolved === null || typeof candidate.resolved !== 'object')\n return invalid('resolved');\n if (candidate.refs === null || typeof candidate.refs !== 'object') return invalid('refs');\n if (candidate.artifact === null || typeof candidate.artifact !== 'object')\n return invalid('artifact');\n if (candidate.receipt === null || typeof candidate.receipt !== 'object')\n return invalid('receipt');\n const artifact = candidate.artifact as Record<string, unknown>;\n if (\n typeof artifact.digest !== 'string' ||\n (!Array.isArray(artifact.bytes) && !ArrayBuffer.isView(artifact.bytes))\n ) {\n return invalid('artifact');\n }\n const receiptResult = validateMaterialCookReceipt(candidate.receipt, {\n artifactDigest: artifact.digest as string,\n });\n if (!receiptResult.ok) return receiptResult;\n if (candidate.artifactDigest !== undefined && candidate.artifactDigest !== artifact.digest)\n return invalid('artifactDigest', candidate.artifactDigest);\n if (\n candidate.publicationGeneration !== undefined &&\n receiptResult.value.identity.cookGeneration !== candidate.publicationGeneration\n )\n return invalid('receipt.identity.cookGeneration', receiptResult.value.identity.cookGeneration);\n const normalized = {\n ...candidate,\n artifact: {\n ...artifact,\n bytes: ArrayBuffer.isView(artifact.bytes)\n ? Uint8Array.from(artifact.bytes as Uint8Array)\n : Uint8Array.from(artifact.bytes as number[]),\n },\n receipt: receiptResult.value,\n } as CookedMaterialRecord;\n return ok(normalized);\n}\n\nexport function projectCookedMaterialRecord(\n record: CookedMaterialRecord,\n): Omit<CookedMaterialRecord, 'guid' | 'authored'> {\n return {\n resolved: record.resolved,\n refs: record.refs,\n artifact: record.artifact,\n receipt: record.receipt,\n schemaVersion: record.schemaVersion,\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgeax/engine-pack",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
}
|
|
137
137
|
},
|
|
138
138
|
"dependencies": {
|
|
139
|
-
"@forgeax/engine-types": "0.1.
|
|
139
|
+
"@forgeax/engine-types": "0.1.21",
|
|
140
140
|
"@noble/hashes": "^2.2.0",
|
|
141
141
|
"fast-glob": "^3.3.3",
|
|
142
142
|
"typescript": "^5.8.3",
|
|
@@ -139,7 +139,9 @@ export function collectMaterialCookRefs(material: Partial<MaterialAsset>): Mater
|
|
|
139
139
|
? new Set<string>(MATERIAL_TEXTURE_SLOTS)
|
|
140
140
|
: new Set(
|
|
141
141
|
material.parameters
|
|
142
|
-
.filter(
|
|
142
|
+
.filter(
|
|
143
|
+
(parameter) => parameter.type === 'texture' || parameter.type === 'texture_cube',
|
|
144
|
+
)
|
|
143
145
|
.map((parameter) => parameter.name),
|
|
144
146
|
);
|
|
145
147
|
const textures = textureValues(material.values, textureFields);
|