@aelionsdk/material-sdk 0.1.0-beta.1
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/README.md +7 -0
- package/dist/bundled-schemas.d.ts +5 -0
- package/dist/bundled-schemas.d.ts.map +1 -0
- package/dist/bundled-schemas.js +3 -0
- package/dist/canonical.d.ts +6 -0
- package/dist/canonical.d.ts.map +1 -0
- package/dist/canonical.js +33 -0
- package/dist/catalog.d.ts +24 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +47 -0
- package/dist/composition.d.ts +42 -0
- package/dist/composition.d.ts.map +1 -0
- package/dist/composition.js +169 -0
- package/dist/definition-builder.d.ts +48 -0
- package/dist/definition-builder.d.ts.map +1 -0
- package/dist/definition-builder.js +159 -0
- package/dist/graph-builder.d.ts +45 -0
- package/dist/graph-builder.d.ts.map +1 -0
- package/dist/graph-builder.js +125 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/lab.d.ts +48 -0
- package/dist/lab.d.ts.map +1 -0
- package/dist/lab.js +169 -0
- package/dist/migration.d.ts +22 -0
- package/dist/migration.d.ts.map +1 -0
- package/dist/migration.js +59 -0
- package/dist/package-limits.d.ts +30 -0
- package/dist/package-limits.d.ts.map +1 -0
- package/dist/package-limits.js +202 -0
- package/dist/package-shape.d.ts +6 -0
- package/dist/package-shape.d.ts.map +1 -0
- package/dist/package-shape.js +547 -0
- package/dist/package-snapshot.d.ts +5 -0
- package/dist/package-snapshot.d.ts.map +1 -0
- package/dist/package-snapshot.js +31 -0
- package/dist/package.d.ts +12 -0
- package/dist/package.d.ts.map +1 -0
- package/dist/package.js +244 -0
- package/dist/registry.d.ts +32 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +150 -0
- package/dist/schema-validation.d.ts +4 -0
- package/dist/schema-validation.d.ts.map +1 -0
- package/dist/schema-validation.js +36 -0
- package/dist/security.d.ts +70 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +161 -0
- package/dist/types.d.ts +245 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/validation.d.ts +6 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +124 -0
- package/dist/zip.d.ts +4 -0
- package/dist/zip.d.ts.map +1 -0
- package/dist/zip.js +172 -0
- package/package.json +46 -0
package/dist/security.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { throwIfAborted } from '@aelionsdk/core';
|
|
2
|
+
import { verifyMaterialPackage } from './package.js';
|
|
3
|
+
function signatureAlgorithm(algorithm) {
|
|
4
|
+
return algorithm === 'Ed25519'
|
|
5
|
+
? { name: 'Ed25519' }
|
|
6
|
+
: { name: 'ECDSA', hash: { name: 'SHA-256' } };
|
|
7
|
+
}
|
|
8
|
+
function base64Url(bytes) {
|
|
9
|
+
let binary = '';
|
|
10
|
+
for (const value of bytes)
|
|
11
|
+
binary += String.fromCharCode(value);
|
|
12
|
+
return btoa(binary).replaceAll('+', '-').replaceAll('/', '_').replaceAll('=', '');
|
|
13
|
+
}
|
|
14
|
+
function fromBase64Url(value) {
|
|
15
|
+
if (!/^[A-Za-z0-9_-]+$/u.test(value))
|
|
16
|
+
throw new TypeError('Invalid base64url signature');
|
|
17
|
+
const padded = value
|
|
18
|
+
.replaceAll('-', '+')
|
|
19
|
+
.replaceAll('_', '/')
|
|
20
|
+
.padEnd(Math.ceil(value.length / 4) * 4, '=');
|
|
21
|
+
const binary = atob(padded);
|
|
22
|
+
return Uint8Array.from(binary, character => character.charCodeAt(0));
|
|
23
|
+
}
|
|
24
|
+
function signingPayload(packed) {
|
|
25
|
+
const domain = new TextEncoder().encode(`AELION-MATERIAL-SIGNATURE-V1\n${packed.integrity}\n`);
|
|
26
|
+
const payload = new Uint8Array(domain.byteLength + packed.manifestBytes.byteLength);
|
|
27
|
+
payload.set(domain);
|
|
28
|
+
payload.set(packed.manifestBytes, domain.byteLength);
|
|
29
|
+
return payload;
|
|
30
|
+
}
|
|
31
|
+
export async function signMaterialPackage(packed, options) {
|
|
32
|
+
throwIfAborted(options.signal, 'Material package signing');
|
|
33
|
+
await verifyMaterialPackage(packed);
|
|
34
|
+
const signature = new Uint8Array(await crypto.subtle.sign(signatureAlgorithm(options.algorithm), options.privateKey, signingPayload(packed)));
|
|
35
|
+
throwIfAborted(options.signal, 'Material package signing');
|
|
36
|
+
return {
|
|
37
|
+
package: packed,
|
|
38
|
+
signature: {
|
|
39
|
+
version: 1,
|
|
40
|
+
publisherId: options.publisherId,
|
|
41
|
+
keyId: options.keyId,
|
|
42
|
+
algorithm: options.algorithm,
|
|
43
|
+
signedAtMs: options.signedAtMs ?? Date.now(),
|
|
44
|
+
manifestIntegrity: packed.integrity,
|
|
45
|
+
signatureBase64Url: base64Url(signature),
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export class MaterialTrustStore {
|
|
50
|
+
#keys = new Map();
|
|
51
|
+
#revokedKeys = new Map();
|
|
52
|
+
#revokedPackages = new Map();
|
|
53
|
+
#audit = [];
|
|
54
|
+
#maxAuditEntries;
|
|
55
|
+
#sequence = 0;
|
|
56
|
+
constructor(maxAuditEntries = 1_024) {
|
|
57
|
+
if (!Number.isSafeInteger(maxAuditEntries) || maxAuditEntries <= 0) {
|
|
58
|
+
throw new RangeError('maxAuditEntries must be a positive safe integer');
|
|
59
|
+
}
|
|
60
|
+
this.#maxAuditEntries = maxAuditEntries;
|
|
61
|
+
}
|
|
62
|
+
addKey(key, nowMs = Date.now()) {
|
|
63
|
+
const id = this.#keyId(key.publisherId, key.keyId);
|
|
64
|
+
if (this.#keys.has(id))
|
|
65
|
+
throw new TypeError('MATERIAL_TRUST_KEY_EXISTS');
|
|
66
|
+
this.#keys.set(id, key);
|
|
67
|
+
this.#record({
|
|
68
|
+
timeMs: nowMs,
|
|
69
|
+
action: 'key-added',
|
|
70
|
+
publisherId: key.publisherId,
|
|
71
|
+
keyId: key.keyId,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
revokeKey(publisherId, keyId, reason, nowMs = Date.now()) {
|
|
75
|
+
this.#revokedKeys.set(this.#keyId(publisherId, keyId), reason);
|
|
76
|
+
this.#record({ timeMs: nowMs, action: 'key-revoked', publisherId, keyId, reason });
|
|
77
|
+
}
|
|
78
|
+
revokePackage(integrity, reason, nowMs = Date.now()) {
|
|
79
|
+
this.#revokedPackages.set(integrity, reason);
|
|
80
|
+
this.#record({ timeMs: nowMs, action: 'package-revoked', integrity, reason });
|
|
81
|
+
}
|
|
82
|
+
async verify(signed, options = {}) {
|
|
83
|
+
const nowMs = options.nowMs ?? Date.now();
|
|
84
|
+
const { signature, package: packed } = signed;
|
|
85
|
+
const signatureVersion = Reflect.get(signature, 'version');
|
|
86
|
+
try {
|
|
87
|
+
throwIfAborted(options.signal, 'Material signature verification');
|
|
88
|
+
await verifyMaterialPackage(packed, signature.manifestIntegrity);
|
|
89
|
+
if (signatureVersion !== 1 ||
|
|
90
|
+
signature.manifestIntegrity !== packed.integrity ||
|
|
91
|
+
signature.publisherId !== packed.manifest.package.publisher.id) {
|
|
92
|
+
throw new TypeError('MATERIAL_SIGNATURE_IDENTITY_MISMATCH');
|
|
93
|
+
}
|
|
94
|
+
const keyIdentity = this.#keyId(signature.publisherId, signature.keyId);
|
|
95
|
+
const revokedKey = this.#revokedKeys.get(keyIdentity);
|
|
96
|
+
if (revokedKey !== undefined)
|
|
97
|
+
throw new TypeError(`MATERIAL_KEY_REVOKED: ${revokedKey}`);
|
|
98
|
+
const revokedPackage = this.#revokedPackages.get(packed.integrity);
|
|
99
|
+
if (revokedPackage !== undefined) {
|
|
100
|
+
throw new TypeError(`MATERIAL_PACKAGE_REVOKED: ${revokedPackage}`);
|
|
101
|
+
}
|
|
102
|
+
const key = this.#keys.get(keyIdentity);
|
|
103
|
+
if (key === undefined || key.algorithm !== signature.algorithm) {
|
|
104
|
+
throw new TypeError('MATERIAL_PUBLISHER_UNTRUSTED');
|
|
105
|
+
}
|
|
106
|
+
if ((key.validFromMs !== undefined && signature.signedAtMs < key.validFromMs) ||
|
|
107
|
+
(key.validUntilMs !== undefined && signature.signedAtMs > key.validUntilMs) ||
|
|
108
|
+
signature.signedAtMs > nowMs) {
|
|
109
|
+
throw new TypeError('MATERIAL_SIGNATURE_TIME_INVALID');
|
|
110
|
+
}
|
|
111
|
+
const valid = await crypto.subtle.verify(signatureAlgorithm(signature.algorithm), key.publicKey, fromBase64Url(signature.signatureBase64Url), signingPayload(packed));
|
|
112
|
+
if (!valid)
|
|
113
|
+
throw new TypeError('MATERIAL_SIGNATURE_INVALID');
|
|
114
|
+
this.#record({
|
|
115
|
+
timeMs: nowMs,
|
|
116
|
+
action: 'verified',
|
|
117
|
+
publisherId: signature.publisherId,
|
|
118
|
+
keyId: signature.keyId,
|
|
119
|
+
integrity: packed.integrity,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
this.#record({
|
|
124
|
+
timeMs: nowMs,
|
|
125
|
+
action: 'rejected',
|
|
126
|
+
publisherId: signature.publisherId,
|
|
127
|
+
keyId: signature.keyId,
|
|
128
|
+
integrity: packed.integrity,
|
|
129
|
+
reason: error instanceof Error ? error.message : 'unknown',
|
|
130
|
+
});
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
auditLog() {
|
|
135
|
+
return this.#audit.map(entry => ({ ...entry }));
|
|
136
|
+
}
|
|
137
|
+
#keyId(publisherId, keyId) {
|
|
138
|
+
return `${publisherId}\0${keyId}`;
|
|
139
|
+
}
|
|
140
|
+
#record(entry) {
|
|
141
|
+
this.#audit.push({ sequence: ++this.#sequence, ...entry });
|
|
142
|
+
if (this.#audit.length > this.#maxAuditEntries)
|
|
143
|
+
this.#audit.shift();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
export function enforceMaterialExecutionPolicy(publisherId, requested, host) {
|
|
147
|
+
if (!host.trustedPublisherIds.has(publisherId))
|
|
148
|
+
throw new TypeError('MATERIAL_PUBLISHER_UNTRUSTED');
|
|
149
|
+
if (requested.allowShader && !host.allowShader)
|
|
150
|
+
throw new TypeError('MATERIAL_SHADER_PERMISSION_DENIED');
|
|
151
|
+
if (requested.allowWasm && !host.allowWasm)
|
|
152
|
+
throw new TypeError('MATERIAL_WASM_PERMISSION_DENIED');
|
|
153
|
+
if (requested.maxMemoryBytes > host.maxMemoryBytes ||
|
|
154
|
+
requested.maxExecutionMs > host.maxExecutionMs) {
|
|
155
|
+
throw new RangeError('MATERIAL_EXECUTION_BUDGET_DENIED');
|
|
156
|
+
}
|
|
157
|
+
for (const origin of requested.allowedNetworkOrigins) {
|
|
158
|
+
if (!host.allowedNetworkOrigins.has(origin))
|
|
159
|
+
throw new TypeError('MATERIAL_NETWORK_PERMISSION_DENIED');
|
|
160
|
+
}
|
|
161
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import type { Diagnostic, JsonValue } from '@aelionsdk/core';
|
|
2
|
+
import type { MaterialGraph } from '@aelionsdk/material-compiler';
|
|
3
|
+
export declare const MATERIAL_PROTOCOL_VERSION: "1.0.0";
|
|
4
|
+
export declare const MATERIAL_PACKAGE_SCHEMA: "https://schemas.aelion.dev/material/package/v1.json";
|
|
5
|
+
export declare const MATERIAL_DEFINITION_SCHEMA: "https://schemas.aelion.dev/material/definition/v1.json";
|
|
6
|
+
export declare const MATERIAL_GRAPH_SCHEMA: "https://schemas.aelion.dev/material/graph/v1.json";
|
|
7
|
+
export declare const MATERIAL_NODE_SET: "aelion.visual.nodes/1.0.0";
|
|
8
|
+
export type MaterialKind = 'visual-filter' | 'visual-effect' | 'visual-transition' | 'visual-generator';
|
|
9
|
+
export type MaterialScope = 'source' | 'item' | 'track' | 'sequence' | 'transition';
|
|
10
|
+
export type MaterialPortType = 'visual-frame' | 'mask' | 'depth' | 'motion-vectors';
|
|
11
|
+
export type MaterialParameterType = 'boolean' | 'integer' | 'float' | 'enum' | 'vec2' | 'vec3' | 'vec4' | 'color' | 'angle' | 'duration' | 'gradient' | 'curve' | 'string';
|
|
12
|
+
export type MaterialResourceKind = 'texture2d' | 'texture3d' | 'lut1d' | 'lut3d' | 'cube-texture' | 'mask' | 'binary-table';
|
|
13
|
+
export interface MaterialDisplay {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly description?: string;
|
|
16
|
+
readonly category?: string;
|
|
17
|
+
readonly tags?: readonly string[];
|
|
18
|
+
readonly icon?: string;
|
|
19
|
+
readonly thumbnail?: string;
|
|
20
|
+
readonly preview?: string;
|
|
21
|
+
readonly localizationPrefix?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface MaterialPort {
|
|
24
|
+
readonly id: string;
|
|
25
|
+
readonly direction: 'input' | 'output';
|
|
26
|
+
readonly type: MaterialPortType;
|
|
27
|
+
readonly role: 'source' | 'from' | 'to' | 'auxiliary' | 'result';
|
|
28
|
+
readonly binding: 'host' | 'instance';
|
|
29
|
+
readonly required: boolean;
|
|
30
|
+
readonly description?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface MaterialParameter {
|
|
33
|
+
readonly id: string;
|
|
34
|
+
readonly type: MaterialParameterType;
|
|
35
|
+
readonly default: JsonValue;
|
|
36
|
+
readonly range?: {
|
|
37
|
+
readonly min?: number;
|
|
38
|
+
readonly max?: number;
|
|
39
|
+
readonly softMin?: number;
|
|
40
|
+
readonly softMax?: number;
|
|
41
|
+
readonly step?: number;
|
|
42
|
+
};
|
|
43
|
+
readonly values?: readonly string[];
|
|
44
|
+
readonly unit?: 'none' | 'ratio' | 'percent' | 'px' | 'degree' | 'us' | 'db' | 'hz';
|
|
45
|
+
readonly animatable: boolean;
|
|
46
|
+
readonly interpolation?: 'hold' | 'linear' | 'cubic-bezier' | 'shortest-angle' | 'linear-color';
|
|
47
|
+
readonly affects: 'uniform' | 'specialization' | 'graph';
|
|
48
|
+
readonly ui: {
|
|
49
|
+
readonly control: 'toggle' | 'slider' | 'number' | 'select' | 'segmented' | 'color' | 'point' | 'curve' | 'gradient' | 'text';
|
|
50
|
+
readonly group: string;
|
|
51
|
+
readonly order: number;
|
|
52
|
+
readonly label: string;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export interface BundledMaterialResource {
|
|
56
|
+
readonly id: string;
|
|
57
|
+
readonly kind: MaterialResourceKind;
|
|
58
|
+
readonly path: string;
|
|
59
|
+
readonly [key: string]: JsonValue;
|
|
60
|
+
}
|
|
61
|
+
export interface MaterialResourceSlot {
|
|
62
|
+
readonly id: string;
|
|
63
|
+
readonly kind: MaterialResourceKind;
|
|
64
|
+
readonly required: boolean;
|
|
65
|
+
readonly fallbackResourceId?: string;
|
|
66
|
+
readonly [key: string]: JsonValue | undefined;
|
|
67
|
+
}
|
|
68
|
+
export interface MaterialExecutionContract {
|
|
69
|
+
readonly color: {
|
|
70
|
+
readonly input: 'working-linear';
|
|
71
|
+
readonly output: 'working-linear';
|
|
72
|
+
};
|
|
73
|
+
readonly alpha: {
|
|
74
|
+
readonly input: 'premultiplied';
|
|
75
|
+
readonly output: 'premultiplied';
|
|
76
|
+
readonly preservesTransparency: boolean;
|
|
77
|
+
};
|
|
78
|
+
readonly resolution: {
|
|
79
|
+
readonly policy: 'same-as-host' | 'scale';
|
|
80
|
+
readonly scale?: number;
|
|
81
|
+
readonly minimum?: {
|
|
82
|
+
readonly width: number;
|
|
83
|
+
readonly height: number;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
readonly spatialPadding: {
|
|
87
|
+
readonly mode: 'none';
|
|
88
|
+
} | {
|
|
89
|
+
readonly mode: 'fixed';
|
|
90
|
+
readonly pixels: number;
|
|
91
|
+
} | {
|
|
92
|
+
readonly mode: 'parameter-bound';
|
|
93
|
+
readonly parameter: string;
|
|
94
|
+
readonly maximumPixels: number;
|
|
95
|
+
};
|
|
96
|
+
readonly temporal: {
|
|
97
|
+
readonly pastUs: number;
|
|
98
|
+
readonly futureUs: number;
|
|
99
|
+
readonly stateful: boolean;
|
|
100
|
+
readonly seekPolicy: 'stateless' | 'reconstruct' | 'reset-with-warning';
|
|
101
|
+
};
|
|
102
|
+
readonly determinism: 'strict' | 'backend-tolerant' | 'non-deterministic';
|
|
103
|
+
readonly supports: {
|
|
104
|
+
readonly realtime: boolean;
|
|
105
|
+
readonly offline: boolean;
|
|
106
|
+
readonly alpha: boolean;
|
|
107
|
+
readonly hdr: boolean;
|
|
108
|
+
readonly tiled: boolean;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export type MaterialImplementation = {
|
|
112
|
+
readonly type: 'graph';
|
|
113
|
+
readonly graph: string;
|
|
114
|
+
readonly nodeSet: string;
|
|
115
|
+
} | ({
|
|
116
|
+
readonly type: 'shader';
|
|
117
|
+
readonly backend: 'webgpu';
|
|
118
|
+
readonly abi: 'aelion-material-shader/1';
|
|
119
|
+
readonly module: string;
|
|
120
|
+
readonly entryPoint: string;
|
|
121
|
+
readonly [key: string]: JsonValue;
|
|
122
|
+
} | {
|
|
123
|
+
readonly type: 'shader';
|
|
124
|
+
readonly backend: 'webgl2';
|
|
125
|
+
readonly abi: 'aelion-material-webgl/1';
|
|
126
|
+
readonly vertexModule?: string;
|
|
127
|
+
readonly fragmentModule: string;
|
|
128
|
+
readonly entryPoint: string;
|
|
129
|
+
readonly [key: string]: JsonValue | undefined;
|
|
130
|
+
}) | {
|
|
131
|
+
readonly type: 'wasm';
|
|
132
|
+
readonly module: string;
|
|
133
|
+
readonly abi: 'aelion-material-wasm/1';
|
|
134
|
+
readonly [key: string]: JsonValue;
|
|
135
|
+
};
|
|
136
|
+
export interface MaterialDefinition {
|
|
137
|
+
readonly $schema: typeof MATERIAL_DEFINITION_SCHEMA;
|
|
138
|
+
readonly protocolVersion: typeof MATERIAL_PROTOCOL_VERSION;
|
|
139
|
+
readonly id: string;
|
|
140
|
+
readonly kind: MaterialKind;
|
|
141
|
+
readonly display: MaterialDisplay;
|
|
142
|
+
readonly scopes: readonly MaterialScope[];
|
|
143
|
+
readonly ports: readonly MaterialPort[];
|
|
144
|
+
readonly parameters: readonly MaterialParameter[];
|
|
145
|
+
readonly bundledResources: readonly BundledMaterialResource[];
|
|
146
|
+
readonly resourceSlots: readonly MaterialResourceSlot[];
|
|
147
|
+
readonly execution: MaterialExecutionContract;
|
|
148
|
+
readonly implementations: readonly MaterialImplementation[];
|
|
149
|
+
readonly splitPolicy: 'copy' | 'reset' | 'reject';
|
|
150
|
+
}
|
|
151
|
+
export interface MaterialPackageMetadata {
|
|
152
|
+
readonly id: string;
|
|
153
|
+
readonly version: string;
|
|
154
|
+
readonly displayName: string;
|
|
155
|
+
readonly publisher: {
|
|
156
|
+
readonly id: string;
|
|
157
|
+
readonly name: string;
|
|
158
|
+
};
|
|
159
|
+
readonly license: string;
|
|
160
|
+
readonly engines: {
|
|
161
|
+
readonly aelion: string;
|
|
162
|
+
readonly nodeSet: string;
|
|
163
|
+
};
|
|
164
|
+
readonly trust: 'declarative' | 'trusted-code';
|
|
165
|
+
}
|
|
166
|
+
export interface MaterialPackageManifest {
|
|
167
|
+
readonly $schema: typeof MATERIAL_PACKAGE_SCHEMA;
|
|
168
|
+
readonly protocolVersion: typeof MATERIAL_PROTOCOL_VERSION;
|
|
169
|
+
readonly package: MaterialPackageMetadata;
|
|
170
|
+
readonly materials: readonly {
|
|
171
|
+
readonly id: string;
|
|
172
|
+
readonly kind: MaterialKind;
|
|
173
|
+
readonly definition: string;
|
|
174
|
+
}[];
|
|
175
|
+
readonly files: readonly {
|
|
176
|
+
readonly path: string;
|
|
177
|
+
readonly mediaType: string;
|
|
178
|
+
readonly bytes: number;
|
|
179
|
+
readonly sha256: string;
|
|
180
|
+
}[];
|
|
181
|
+
}
|
|
182
|
+
export interface AuthoredMaterial {
|
|
183
|
+
readonly definition: MaterialDefinition;
|
|
184
|
+
readonly graph?: MaterialGraph;
|
|
185
|
+
readonly definitionPath?: string;
|
|
186
|
+
readonly graphPath?: string;
|
|
187
|
+
}
|
|
188
|
+
export interface MaterialPackageFile {
|
|
189
|
+
readonly path: string;
|
|
190
|
+
readonly mediaType: string;
|
|
191
|
+
readonly data: Uint8Array | string;
|
|
192
|
+
}
|
|
193
|
+
/** Hard transport bounds applied before package bytes are copied or ZIP bytes are rebuilt. */
|
|
194
|
+
export interface MaterialPackageByteLimits {
|
|
195
|
+
/** Includes `manifest.json`. ZIP transport cannot represent more than 65,535 entries. */
|
|
196
|
+
readonly maxFiles: number;
|
|
197
|
+
/** Maximum bytes for any one non-manifest payload. */
|
|
198
|
+
readonly maxFileBytes: number;
|
|
199
|
+
/** Maximum canonical `manifest.json` bytes. */
|
|
200
|
+
readonly maxManifestBytes: number;
|
|
201
|
+
/** Maximum sum of `manifest.json` and all payload bytes. */
|
|
202
|
+
readonly maxPackageBytes: number;
|
|
203
|
+
/** Maximum deterministic `.aelionmat` ZIP bytes. */
|
|
204
|
+
readonly maxArchiveBytes: number;
|
|
205
|
+
}
|
|
206
|
+
export type MaterialPackageByteLimitOptions = Partial<MaterialPackageByteLimits>;
|
|
207
|
+
export interface PackMaterialPackageOptions {
|
|
208
|
+
readonly metadata: MaterialPackageMetadata;
|
|
209
|
+
readonly materials: readonly AuthoredMaterial[];
|
|
210
|
+
readonly files?: readonly MaterialPackageFile[];
|
|
211
|
+
/** Defaults to the fail-closed browser transport limits exported by this package. */
|
|
212
|
+
readonly limits?: MaterialPackageByteLimitOptions;
|
|
213
|
+
}
|
|
214
|
+
export interface PackedMaterialPackage {
|
|
215
|
+
/** Derived convenience view; verification authority is the signed `manifestBytes`. */
|
|
216
|
+
readonly manifest: MaterialPackageManifest;
|
|
217
|
+
readonly manifestBytes: Uint8Array;
|
|
218
|
+
/** Includes manifest.json and every manifest-declared payload file. */
|
|
219
|
+
readonly files: ReadonlyMap<string, Uint8Array>;
|
|
220
|
+
/** Deterministic, store-only ZIP bytes suitable for a `.aelionmat` file. */
|
|
221
|
+
readonly archiveBytes: Uint8Array;
|
|
222
|
+
readonly integrity: `sha256:${string}`;
|
|
223
|
+
}
|
|
224
|
+
export interface MaterialValidationResult {
|
|
225
|
+
readonly valid: boolean;
|
|
226
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
227
|
+
}
|
|
228
|
+
export interface MaterialPackageReference {
|
|
229
|
+
readonly packageId: string;
|
|
230
|
+
readonly packageVersion: string;
|
|
231
|
+
readonly packageIntegrity: string;
|
|
232
|
+
readonly materialId: string;
|
|
233
|
+
}
|
|
234
|
+
export interface ResolvedMaterial {
|
|
235
|
+
readonly reference: MaterialPackageReference;
|
|
236
|
+
readonly manifest: MaterialPackageManifest;
|
|
237
|
+
readonly definition: MaterialDefinition;
|
|
238
|
+
readonly graph?: MaterialGraph;
|
|
239
|
+
}
|
|
240
|
+
export interface MaterialPackageResolver {
|
|
241
|
+
resolve(reference: Pick<MaterialPackageReference, 'packageId' | 'packageVersion' | 'packageIntegrity'>, options?: {
|
|
242
|
+
readonly signal?: AbortSignal;
|
|
243
|
+
}): Promise<PackedMaterialPackage>;
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export const MATERIAL_PROTOCOL_VERSION = '1.0.0';
|
|
2
|
+
export const MATERIAL_PACKAGE_SCHEMA = 'https://schemas.aelion.dev/material/package/v1.json';
|
|
3
|
+
export const MATERIAL_DEFINITION_SCHEMA = 'https://schemas.aelion.dev/material/definition/v1.json';
|
|
4
|
+
export const MATERIAL_GRAPH_SCHEMA = 'https://schemas.aelion.dev/material/graph/v1.json';
|
|
5
|
+
export const MATERIAL_NODE_SET = 'aelion.visual.nodes/1.0.0';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type CompileMaterialOptions } from '@aelionsdk/material-compiler';
|
|
2
|
+
import type { AuthoredMaterial, MaterialValidationResult } from './types.js';
|
|
3
|
+
export declare function validateAuthoredMaterial(authored: AuthoredMaterial, options?: {
|
|
4
|
+
readonly budget?: CompileMaterialOptions['budget'];
|
|
5
|
+
}): MaterialValidationResult;
|
|
6
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAEjG,OAAO,KAAK,EACV,gBAAgB,EAGhB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAsEpB,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,sBAAsB,CAAC,QAAQ,CAAC,CAAA;CAAO,GACnE,wBAAwB,CAgH1B"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { compileMaterialGraph } from '@aelionsdk/material-compiler';
|
|
2
|
+
function issue(diagnostics, code, message, path) {
|
|
3
|
+
diagnostics.push({ code, severity: 'error', message, path, recoverable: false });
|
|
4
|
+
}
|
|
5
|
+
function duplicates(values) {
|
|
6
|
+
const seen = new Set();
|
|
7
|
+
const result = new Set();
|
|
8
|
+
for (const value of values) {
|
|
9
|
+
if (seen.has(value.id))
|
|
10
|
+
result.add(value.id);
|
|
11
|
+
seen.add(value.id);
|
|
12
|
+
}
|
|
13
|
+
return [...result];
|
|
14
|
+
}
|
|
15
|
+
function validDefault(parameter) {
|
|
16
|
+
const value = parameter.default;
|
|
17
|
+
switch (parameter.type) {
|
|
18
|
+
case 'boolean':
|
|
19
|
+
return typeof value === 'boolean';
|
|
20
|
+
case 'integer':
|
|
21
|
+
case 'duration':
|
|
22
|
+
return typeof value === 'number' && Number.isSafeInteger(value);
|
|
23
|
+
case 'float':
|
|
24
|
+
case 'angle':
|
|
25
|
+
return typeof value === 'number' && Number.isFinite(value);
|
|
26
|
+
case 'enum':
|
|
27
|
+
return typeof value === 'string' && (parameter.values?.includes(value) ?? false);
|
|
28
|
+
case 'string':
|
|
29
|
+
return typeof value === 'string';
|
|
30
|
+
default:
|
|
31
|
+
return value !== null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function requireHostPort(definition, diagnostics, id, direction, role) {
|
|
35
|
+
const port = definition.ports.find(value => value.id === id);
|
|
36
|
+
if (port?.direction !== direction ||
|
|
37
|
+
port.type !== 'visual-frame' ||
|
|
38
|
+
port.role !== role ||
|
|
39
|
+
port.binding !== 'host' ||
|
|
40
|
+
!port.required) {
|
|
41
|
+
issue(diagnostics, 'MATERIAL_DEFINITION_INVALID', `${definition.kind} requires host port ${id}:${direction}/${role}`, ['definition', 'ports']);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function compilerParameterType(parameter) {
|
|
45
|
+
if (['float', 'integer', 'angle', 'duration'].includes(parameter.type))
|
|
46
|
+
return 'float';
|
|
47
|
+
return parameter.type === 'enum' ? 'enum' : undefined;
|
|
48
|
+
}
|
|
49
|
+
export function validateAuthoredMaterial(authored, options = {}) {
|
|
50
|
+
const diagnostics = [];
|
|
51
|
+
const { definition, graph } = authored;
|
|
52
|
+
for (const [collection, values] of [
|
|
53
|
+
['ports', definition.ports],
|
|
54
|
+
['parameters', definition.parameters],
|
|
55
|
+
['bundledResources', definition.bundledResources],
|
|
56
|
+
['resourceSlots', definition.resourceSlots],
|
|
57
|
+
]) {
|
|
58
|
+
for (const id of duplicates(values)) {
|
|
59
|
+
issue(diagnostics, 'MATERIAL_DEFINITION_INVALID', `Duplicate ${collection} id ${id}`, [
|
|
60
|
+
'definition',
|
|
61
|
+
collection,
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (definition.kind === 'visual-filter' || definition.kind === 'visual-effect') {
|
|
66
|
+
requireHostPort(definition, diagnostics, 'source', 'input', 'source');
|
|
67
|
+
requireHostPort(definition, diagnostics, 'result', 'output', 'result');
|
|
68
|
+
}
|
|
69
|
+
else if (definition.kind === 'visual-transition') {
|
|
70
|
+
requireHostPort(definition, diagnostics, 'from', 'input', 'from');
|
|
71
|
+
requireHostPort(definition, diagnostics, 'to', 'input', 'to');
|
|
72
|
+
requireHostPort(definition, diagnostics, 'result', 'output', 'result');
|
|
73
|
+
if (!definition.scopes.includes('transition')) {
|
|
74
|
+
issue(diagnostics, 'MATERIAL_DEFINITION_INVALID', 'visual-transition requires transition scope', ['definition', 'scopes']);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
requireHostPort(definition, diagnostics, 'result', 'output', 'result');
|
|
79
|
+
}
|
|
80
|
+
for (const [index, parameter] of definition.parameters.entries()) {
|
|
81
|
+
if (!validDefault(parameter)) {
|
|
82
|
+
issue(diagnostics, 'MATERIAL_DEFINITION_INVALID', `Parameter ${parameter.id} has an invalid default`, ['definition', 'parameters', index, 'default']);
|
|
83
|
+
}
|
|
84
|
+
if (parameter.animatable && parameter.affects !== 'uniform') {
|
|
85
|
+
issue(diagnostics, 'MATERIAL_DEFINITION_INVALID', `Animatable parameter ${parameter.id} must affect uniform`, ['definition', 'parameters', index, 'affects']);
|
|
86
|
+
}
|
|
87
|
+
if (typeof parameter.default === 'number' &&
|
|
88
|
+
((parameter.range?.min !== undefined && parameter.default < parameter.range.min) ||
|
|
89
|
+
(parameter.range?.max !== undefined && parameter.default > parameter.range.max))) {
|
|
90
|
+
issue(diagnostics, 'MATERIAL_DEFINITION_INVALID', `Parameter ${parameter.id} default is outside its range`, ['definition', 'parameters', index, 'default']);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const graphImplementations = definition.implementations.filter(value => value.type === 'graph');
|
|
94
|
+
if (graphImplementations.length > 0 && graph === undefined) {
|
|
95
|
+
issue(diagnostics, 'MATERIAL_GRAPH_INVALID', 'A graph implementation requires a Graph payload', ['graph']);
|
|
96
|
+
}
|
|
97
|
+
if (graph !== undefined) {
|
|
98
|
+
const parameters = Object.fromEntries(definition.parameters.flatMap(parameter => {
|
|
99
|
+
const type = compilerParameterType(parameter);
|
|
100
|
+
return type === undefined ? [] : [[parameter.id, type]];
|
|
101
|
+
}));
|
|
102
|
+
const inputPorts = Object.fromEntries(definition.ports
|
|
103
|
+
.filter(port => port.direction === 'input' && port.type === 'visual-frame')
|
|
104
|
+
.map(port => [port.id, 'visual-frame']));
|
|
105
|
+
const specializationValues = Object.fromEntries(definition.parameters
|
|
106
|
+
.filter(parameter => parameter.affects === 'specialization')
|
|
107
|
+
.map(parameter => [parameter.id, parameter.default]));
|
|
108
|
+
const compiled = compileMaterialGraph(graph, {
|
|
109
|
+
parameters,
|
|
110
|
+
inputPorts,
|
|
111
|
+
systems: { transitionProgress: 'float' },
|
|
112
|
+
specializationValues,
|
|
113
|
+
...(options.budget === undefined ? {} : { budget: options.budget }),
|
|
114
|
+
});
|
|
115
|
+
diagnostics.push(...compiled.diagnostics);
|
|
116
|
+
if (graph.nodeSet !== definition.implementations.find(value => value.type === 'graph')?.nodeSet) {
|
|
117
|
+
issue(diagnostics, 'MATERIAL_PROTOCOL_UNSUPPORTED', 'Definition and Graph node sets differ', [
|
|
118
|
+
'graph',
|
|
119
|
+
'nodeSet',
|
|
120
|
+
]);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return { valid: diagnostics.length === 0, diagnostics };
|
|
124
|
+
}
|
package/dist/zip.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { MaterialPackageByteLimitOptions } from './types.js';
|
|
2
|
+
/** Writes deterministic uncompressed ZIP bytes without platform metadata or variable timestamps. */
|
|
3
|
+
export declare function createDeterministicMaterialArchive(files: ReadonlyMap<string, Uint8Array>, options?: MaterialPackageByteLimitOptions): Uint8Array;
|
|
4
|
+
//# sourceMappingURL=zip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zip.d.ts","sourceRoot":"","sources":["../src/zip.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,YAAY,CAAC;AAgJlE,oGAAoG;AACpG,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EACtC,OAAO,GAAE,+BAAoC,GAC5C,UAAU,CAsDZ"}
|