@forgeax/engine-naga 0.1.25 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -65,6 +65,8 @@ export declare function parse(source: string): Promise<Result<ParsedModule, Shad
65
65
  * `lineNum` / `linePos` remain undefined.
66
66
  */
67
67
  export declare function validate(parsed: ParsedModule): Promise<Result<ValidatedModule, ShaderError>>;
68
+ /** Validate a selected vertex/fragment pair against the validated Naga module. */
69
+ export declare function validateRenderEntries(module: ValidatedModule, vertex: string, fragment?: string): Promise<Result<void, ShaderError>>;
68
70
  /**
69
71
  * naga_oil Composer passthrough — `#import` + `#ifdef` composition over WGSL.
70
72
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAKL,KAAK,MAAM,EACX,WAAW,EACX,KAAK,WAAW,IAAI,eAAe,EAEpC,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,aAAa,EACb,GAAG,EACH,UAAU,EACV,iBAAiB,EACjB,EAAE,EACF,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,WAAW,EACX,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,cAAc,GACf,MAAM,aAAa,CAAC;AAIrB;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC;AAEnC;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC;AAEtC,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACrD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;IAC9C,QAAQ,CAAC,YAAY,EAAE,SAAS,2BAA2B,EAAE,CAAC;IAC9D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AA0FD,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CA8BlE;AAED,yFAAyF;AACzF,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,MAAM,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAe3C;AAID;;;;;;;;;GASG;AACH,wBAAsB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,CAkBtF;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC,CAkB/C;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,MAAM,CAAC,CAKjB;AAID;;;;;;;;;;;;GAYG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,eAAe,EAC1B,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAqBtC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAKL,KAAK,MAAM,EACX,WAAW,EACX,KAAK,WAAW,IAAI,eAAe,EAEpC,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,aAAa,EACb,GAAG,EACH,UAAU,EACV,iBAAiB,EACjB,EAAE,EACF,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,WAAW,EACX,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,cAAc,GACf,MAAM,aAAa,CAAC;AAIrB;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC;AAEnC;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC;AAEtC,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACrD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAC;IAC9C,QAAQ,CAAC,YAAY,EAAE,SAAS,2BAA2B,EAAE,CAAC;IAC9D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AA0FD,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CA8BlE;AAED,yFAAyF;AACzF,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,MAAM,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAe3C;AAID;;;;;;;;;GASG;AACH,wBAAsB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,CAkBtF;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC,CAkB/C;AAED,kFAAkF;AAClF,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAYpC;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,MAAM,CAAC,CAKjB;AAID;;;;;;;;;;;;GAYG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,eAAe,EAC1B,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAqBtC"}
package/dist/index.mjs CHANGED
@@ -249,6 +249,19 @@ async function validate(parsed) {
249
249
  return err(wrapShaderError(e));
250
250
  }
251
251
  }
252
+ async function validateRenderEntries(module, vertex, fragment) {
253
+ try {
254
+ const wasm = await ensureReady();
255
+ wasm.validate_render_entries(
256
+ module,
257
+ vertex,
258
+ fragment
259
+ );
260
+ return ok(void 0);
261
+ } catch (error) {
262
+ return err(wrapShaderError(error));
263
+ }
264
+ }
252
265
  async function composeShader(entry, imports, defines) {
253
266
  const wasm = await ensureReady();
254
267
  const compose = wasm.compose_shader;
@@ -277,6 +290,6 @@ async function emit_reflection(validated, options_json) {
277
290
  }
278
291
  }
279
292
 
280
- export { ShaderError, compileFailed, composeShader, emit_reflection, initFailed, manifestMalformed, parse, parseReflectionWire, readReflectionWire, shaderNotFound, validate };
293
+ export { ShaderError, compileFailed, composeShader, emit_reflection, initFailed, manifestMalformed, parse, parseReflectionWire, readReflectionWire, shaderNotFound, validate, validateRenderEntries };
281
294
  //# sourceMappingURL=index.mjs.map
282
295
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["// @forgeax/engine-naga/errors — ShaderError + Result<T, E> + wrapShaderError helper.\n//\n// Form invariants (plan-strategy §D-P4 / requirements MVP-2.3 + AC-09):\n// - ShaderErrorCode (closed 4-member union) is imported from @forgeax/engine-types as\n// the SSOT. This package does **not** redefine the union — +0 breaking points\n// to the error model (AC-09; charter proposition 5 consistent abstraction).\n// - The ShaderError class shape + 4 factory helpers + Result<T, E> shape are\n// byte-for-byte equivalent to @forgeax/engine-shader-compiler/src/errors.ts; that\n// package will re-export from here in w7 after the import switch lands\n// (charter proposition 5 + plan-strategy D-P4 byte-for-byte form recovery).\n// - wrapShaderError is the JsError -> ShaderError adapter for the parse /\n// validate / emit_reflection wrappers in index.ts: it tries to JSON.parse the\n// wasm-side ParseErrorPayload (message / summary / line_num / line_pos)\n// first, falls back to the prose message for validator / reflection failures.\n\n/// <reference types=\"@webgpu/types\" />\n\nimport type { ShaderErrorCode, ShaderErrorDetail } from '@forgeax/engine-types';\n\nexport type { ShaderErrorCode, ShaderErrorDetail };\n\ninterface ShaderErrorInit {\n readonly code: ShaderErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly message: string;\n readonly lineNum?: number | undefined;\n readonly linePos?: number | undefined;\n readonly detail?: ShaderErrorDetail | undefined;\n}\n\n/**\n * Structured shader error.\n *\n * **5 surface fields** (MVP-2.3 top-level surface, AI consumer path):\n * - `.code` — member of the closed `ShaderErrorCode` union (4 variants)\n * - `.message` — display text (the base `Error` field, populated by the constructor)\n * - `.hint` — actionable recovery guidance (charter proposition 3: machine-readable hint over prose)\n * - `.lineNum` / `.linePos` — error source location (mandatory for compile-failed; undefined on other paths)\n *\n * **3 internal fields**:\n * - `.name` = `'ShaderError'` (debug tag)\n * - `.expected` — description of the expected state (symmetric with RhiError)\n * - `.detail` — path-specific extra info (e.g. all 6 fields of GPUCompilationMessage[])\n *\n * **Do not new directly** — construct via the 4 factories (compileFailed /\n * initFailed / manifestMalformed / shaderNotFound) to avoid ad-hoc arguments\n * bypassing union narrowing.\n */\nexport class ShaderError extends Error {\n override readonly name: 'ShaderError' = 'ShaderError';\n readonly code: ShaderErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly lineNum: number | undefined;\n readonly linePos: number | undefined;\n readonly detail: ShaderErrorDetail | undefined;\n\n constructor(init: ShaderErrorInit) {\n super(init.message);\n this.code = init.code;\n this.expected = init.expected;\n this.hint = init.hint;\n this.lineNum = init.lineNum;\n this.linePos = init.linePos;\n this.detail = init.detail;\n }\n}\n\n// === 4 factory helpers (plan-strategy §D-P4 closed union with 4 members) ===========\n\n/** `shader-compile-failed`: naga parse_str or Validator::validate failure. */\nexport function compileFailed(args: {\n readonly message: string;\n readonly hint: string;\n readonly lineNum?: number | undefined;\n readonly linePos?: number | undefined;\n readonly compilerMessages?: readonly GPUCompilationMessage[] | undefined;\n readonly reason?: string | undefined;\n}): ShaderError {\n return new ShaderError({\n code: 'shader-compile-failed',\n expected: 'WGSL source parses + validates against naga IR',\n message: args.message,\n hint: args.hint,\n ...(args.lineNum !== undefined ? { lineNum: args.lineNum } : {}),\n ...(args.linePos !== undefined ? { linePos: args.linePos } : {}),\n ...(args.compilerMessages !== undefined\n ? {\n detail: {\n code: 'shader-compile-failed',\n compilerMessages: args.compilerMessages,\n ...(args.reason !== undefined ? { reason: args.reason } : {}),\n },\n }\n : {}),\n });\n}\n\n/** `compiler-init-failed`: wasm loading or init() failure (cold start / missing wasm artifact). */\nexport function initFailed(args: {\n readonly message: string;\n readonly hint: string;\n readonly reason?: string | undefined;\n}): ShaderError {\n return new ShaderError({\n code: 'compiler-init-failed',\n expected: '@forgeax/engine-wgpu-wasm ensureReady() resolves with naga raw bindings available',\n message: args.message,\n hint: args.hint,\n detail: {\n code: 'compiler-init-failed',\n ...(args.reason !== undefined ? { reason: args.reason } : {}),\n },\n });\n}\n\n/** `manifest-malformed`: manifest.json schema validation failure (a required field is missing or JSON is not parseable). */\nexport function manifestMalformed(args: {\n readonly message: string;\n readonly hint: string;\n readonly reason?: string | undefined;\n}): ShaderError {\n return new ShaderError({\n code: 'manifest-malformed',\n expected: 'manifest.json parses + every entry has {hash, wgsl, glsl, bindings}',\n message: args.message,\n hint: args.hint,\n detail: {\n code: 'manifest-malformed',\n ...(args.reason !== undefined ? { reason: args.reason } : {}),\n },\n });\n}\n\n/** `shader-not-found`: ShaderRegistry.get(hash) hash miss. */\nexport function shaderNotFound(args: {\n readonly hash: string;\n readonly hint: string;\n}): ShaderError {\n return new ShaderError({\n code: 'shader-not-found',\n expected: `manifest.entries contains entry with hash '${args.hash}'`,\n message: `ShaderRegistry: hash '${args.hash}' not present in manifest`,\n hint: args.hint,\n });\n}\n\n// === wrapShaderError: JsError -> ShaderError adapter ================================\n\n/**\n * Translate a thrown wasm-bindgen JsError to a structured ShaderError.\n *\n * The Rust side serializes `ParseErrorPayload { message, summary, line_num,\n * line_pos }` to a JSON string and uses it as the JsError message. We attempt\n * JSON.parse first; on success the lineNum/linePos are extracted as top-level\n * surface fields (MVP-2.3). On failure (validator errors, reflection errors,\n * non-JSON messages) we fall back to the prose message — hint is always\n * populated so AI consumers always have an actionable recovery signal\n * (charter proposition 4 explicit failure + proposition 3 machine-readable hint).\n */\nexport function wrapShaderError(e: unknown, hint?: string): ShaderError {\n if (e instanceof Error) {\n try {\n const payload = JSON.parse(e.message) as {\n message?: string;\n summary?: string;\n line_num?: number | null;\n line_pos?: number | null;\n };\n return compileFailed({\n message: payload.summary ?? payload.message ?? e.message,\n hint:\n hint ??\n 'fix the WGSL source at the indicated line/column; see ShaderError.detail.compilerMessages for full diagnostic frame',\n ...(typeof payload.line_num === 'number' ? { lineNum: payload.line_num } : {}),\n ...(typeof payload.line_pos === 'number' ? { linePos: payload.line_pos } : {}),\n });\n } catch {\n return compileFailed({\n message: e.message,\n hint: hint ?? 'check WGSL syntax + validation rules; consult naga error output for details',\n });\n }\n }\n return compileFailed({\n message: String(e),\n hint:\n hint ??\n 'unknown error type from @forgeax/engine-wgpu-wasm; report as @forgeax/engine-naga bug',\n });\n}\n\n// === Result<T, E> ====================================================================\n//\n// Result<T, E> + ok / err + ResultOk / ResultErr live in `@forgeax/engine-types`\n// (tweak-20260612-result-into-types). They were duplicated here as a lite\n// (plain-object, no `unwrap`) variant; consolidated upstream into the same\n// shape used by rhi / ecs. The barrel here re-exports them so existing\n// `import { err, ok, Result, ResultOk, ResultErr } from '@forgeax/engine-naga'`\n// consumers stay unchanged.\nexport {\n err,\n ok,\n type Result,\n type ResultErr,\n type ResultOk,\n} from '@forgeax/engine-types';\n","// @forgeax/engine-naga — TS-only thin shell over @forgeax/engine-wgpu-wasm raw naga bindings.\n//\n// Form invariants (locked by plan-strategy D-P3 / D-P4 + research F-4):\n//\n// - snake_case three-phase functions byte-for-byte aligned with naga upstream\n// naming (this package replaces the legacy wasm-pack shim archived in\n// feat-20260511-naga-rhi-wgpu-merge M5 — charter proposition 2 industry\n// analogy + proposition 5 consistent abstraction).\n// - Each public function awaits ensureReady() from @forgeax/engine-wgpu-wasm before\n// calling the raw wasm-bindgen export — one wasm boundary crossing per page\n// lifecycle, shared with @forgeax/engine-rhi-wgpu (research F-4 ensureReady SSOT).\n// - Throws are caught at the wrapper boundary and translated to\n// Result.err(ShaderError) — never throw for expected failures\n// (AGENTS.md \"Errors are structured\" + charter proposition 4 explicit failure).\n// - The opaque handle types ParsedModule / ValidatedModule are re-exported\n// so downstream consumers (@forgeax/engine-shader-compiler) can hold the handle\n// between phases without inspecting the underlying naga IR\n// (plan-strategy §S-1 opaque handle invariant).\n\nimport { ensureReady } from '@forgeax/engine-wgpu-wasm';\nimport {\n err,\n initFailed,\n manifestMalformed,\n ok,\n type Result,\n ShaderError,\n type ShaderError as ShaderErrorType,\n wrapShaderError,\n} from './errors.js';\n\nexport {\n compileFailed,\n err,\n initFailed,\n manifestMalformed,\n ok,\n type Result,\n type ResultErr,\n type ResultOk,\n ShaderError,\n type ShaderErrorCode,\n type ShaderErrorDetail,\n shaderNotFound,\n} from './errors.js';\n\n// === Opaque handle types ============================================================\n\n/**\n * Handle for the `parse` output. The underlying type is a wasm-bindgen exported\n * struct: JS can only hold the handle — it cannot inspect naga IR fields\n * directly (charter proposition 4 + opaque handle invariant). Pass through to\n * `validate` to advance to phase 2.\n *\n * Surface type uses `unknown` to keep this layer math-free and opaque-handle\n * pure (no direct dependency on @forgeax/engine-wgpu-wasm/pkg ABI types). Downstream\n * consumers should not inspect the handle.\n */\nexport type ParsedModule = unknown;\n\n/**\n * Handle for the `validate` output (Module + ModuleInfo); pass through to\n * `emit_reflection` for the reflection JSON emit.\n */\nexport type ValidatedModule = unknown;\n\nexport interface ShaderReflectionMember {\n readonly name: string;\n readonly type: string;\n readonly offset: number;\n readonly size: number;\n readonly alignment: number;\n}\n\nexport interface ShaderReflectionBoundGlobal {\n readonly group: number;\n readonly binding: number;\n readonly addressSpace: string;\n readonly resourceKind: string;\n readonly visibility: number;\n readonly name?: string;\n readonly members?: readonly ShaderReflectionMember[];\n readonly span?: number;\n}\n\nexport interface ShaderReflection {\n readonly schemaVersion: 'shader-reflection/2';\n readonly boundGlobals: readonly ShaderReflectionBoundGlobal[];\n readonly uvSetCount: number;\n}\n\ntype ReflectionRecord = Record<string, unknown>;\n\nfunction reflectionMalformed(reason: string): ShaderError {\n return manifestMalformed({\n message: `shader-reflection/2 is malformed: ${reason}`,\n hint: 'rebuild the shader with the current Naga/WASM producer and preserve every bound-global fact',\n reason,\n });\n}\n\nfunction isRecord(value: unknown): value is ReflectionRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction requiredNonNegativeInteger(record: ReflectionRecord, key: string): number {\n const value = record[key];\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) {\n throw reflectionMalformed(`boundGlobals entry requires non-negative integer '${key}'`);\n }\n return value;\n}\n\nfunction readMember(value: unknown, index: number): ShaderReflectionMember {\n if (!isRecord(value)) throw reflectionMalformed(`member ${index} is not an object`);\n const name = value.name;\n const type = value.type;\n if (\n typeof name !== 'string' ||\n name.length === 0 ||\n typeof type !== 'string' ||\n type.length === 0\n ) {\n throw reflectionMalformed(`member ${index} requires name and type`);\n }\n return {\n name,\n type,\n offset: requiredNonNegativeInteger(value, 'offset'),\n size: requiredNonNegativeInteger(value, 'size'),\n alignment: requiredNonNegativeInteger(value, 'alignment'),\n };\n}\n\nfunction readBoundGlobal(value: unknown, index: number): ShaderReflectionBoundGlobal {\n if (!isRecord(value)) throw reflectionMalformed(`boundGlobals entry ${index} is not an object`);\n const addressSpace = value.addressSpace;\n const resourceKind = value.resourceKind;\n if (typeof addressSpace !== 'string' || addressSpace.length === 0) {\n throw reflectionMalformed(`boundGlobals entry ${index} requires addressSpace`);\n }\n if (typeof resourceKind !== 'string' || resourceKind.length === 0) {\n throw reflectionMalformed(`boundGlobals entry ${index} requires resourceKind`);\n }\n const visibility = requiredNonNegativeInteger(value, 'visibility');\n const membersValue = value.members;\n const hasMembers = membersValue !== undefined;\n if (hasMembers && !Array.isArray(membersValue)) {\n throw reflectionMalformed(`boundGlobals entry ${index} members must be an array`);\n }\n const hasSpan = value.span !== undefined;\n if (resourceKind === 'buffer' || resourceKind === 'storage-buffer') {\n if (!hasMembers || !hasSpan) {\n throw reflectionMalformed(`buffer boundGlobals entry ${index} requires members and span`);\n }\n } else if (hasMembers !== hasSpan) {\n throw reflectionMalformed(`boundGlobals entry ${index} members and span must be paired`);\n }\n if (value.name !== undefined && typeof value.name !== 'string') {\n throw reflectionMalformed(`boundGlobals entry ${index} diagnostic name must be a string`);\n }\n return {\n group: requiredNonNegativeInteger(value, 'group'),\n binding: requiredNonNegativeInteger(value, 'binding'),\n addressSpace,\n resourceKind,\n visibility,\n ...(value.name !== undefined ? { name: value.name as string } : {}),\n ...(hasMembers\n ? {\n members: (membersValue as unknown[]).map((member, memberIndex) =>\n readMember(member, memberIndex),\n ),\n span: requiredNonNegativeInteger(value, 'span'),\n }\n : {}),\n };\n}\n\n/** Parse and validate the business-neutral shader-reflection/2 wire. */\nexport function parseReflectionWire(json: string): ShaderReflection {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch (cause) {\n throw reflectionMalformed(cause instanceof Error ? cause.message : 'JSON.parse failed');\n }\n if (!isRecord(parsed) || parsed.schemaVersion !== 'shader-reflection/2') {\n throw reflectionMalformed(\"schemaVersion must equal 'shader-reflection/2'\");\n }\n if ('material' in parsed) throw reflectionMalformed('legacy material projection is not accepted');\n if (!Array.isArray(parsed.boundGlobals)) {\n throw reflectionMalformed('boundGlobals must be an array');\n }\n if (\n typeof parsed.uvSetCount !== 'number' ||\n !Number.isSafeInteger(parsed.uvSetCount) ||\n parsed.uvSetCount < 0\n ) {\n throw reflectionMalformed('uvSetCount must be a non-negative integer');\n }\n const boundGlobals = parsed.boundGlobals.map((global, index) => readBoundGlobal(global, index));\n const coordinates = new Set<string>();\n for (const global of boundGlobals) {\n const coordinate = `${global.group}:${global.binding}`;\n if (coordinates.has(coordinate))\n throw reflectionMalformed(`duplicate bound-global coordinate ${coordinate}`);\n coordinates.add(coordinate);\n }\n return { schemaVersion: 'shader-reflection/2', boundGlobals, uvSetCount: parsed.uvSetCount };\n}\n\n/** Result-form reader for callers that need an explicit unavailable/malformed branch. */\nexport function readReflectionWire(\n json: string | undefined,\n): Result<ShaderReflection, ShaderErrorType> {\n if (json === undefined) {\n return err(\n initFailed({\n message: 'shader-reflection/2 is unavailable before the Naga producer emits a wire',\n hint: 'run the validated compose -> reflect path and retain its raw reflection bytes',\n reason: 'reflection wire unavailable',\n }),\n );\n }\n try {\n return ok(parseReflectionWire(json));\n } catch (error) {\n return err(error instanceof ShaderError ? error : reflectionMalformed(String(error)));\n }\n}\n\n// === Phase 1: parse =================================================================\n\n/**\n * WGSL source -> `ParsedModule`.\n *\n * On failure returns `Result.err(ShaderError code='shader-compile-failed')`\n * whose `lineNum` / `linePos` carry the source position (from the wasm-side\n * `ParseErrorPayload`). The hint defaults to actionable WGSL fix guidance.\n *\n * Wasm boundary: awaits ensureReady() on first call (shared singleton with\n * @forgeax/engine-rhi-wgpu); subsequent calls take the cached path.\n */\nexport async function parse(source: string): Promise<Result<ParsedModule, ShaderError>> {\n let wasm: Awaited<ReturnType<typeof ensureReady>>;\n try {\n wasm = await ensureReady();\n } catch (e) {\n return err(\n wrapShaderError(\n e,\n 'rerun bash packages/wgpu-wasm/build.sh and verify packages/wgpu-wasm/pkg contains a fresh .wasm',\n ),\n );\n }\n try {\n const parsed = wasm.parse(source);\n return ok(parsed as ParsedModule);\n } catch (e) {\n return err(wrapShaderError(e));\n }\n}\n\n// === Phase 2: validate ==============================================================\n\n/**\n * `ParsedModule` -> `ValidatedModule` (Module + ModuleInfo).\n *\n * **Ownership transfer** — wasm-bindgen consumes the `parsed` handle. Do not\n * reuse the handle after this call; passing a consumed handle is undefined\n * behaviour on the wasm side (research Finding 6 ownership semantics).\n *\n * On failure returns `Result.err(ShaderError code='shader-compile-failed')`.\n * Validator errors have no source position attached on the wasm side, so\n * `lineNum` / `linePos` remain undefined.\n */\nexport async function validate(\n parsed: ParsedModule,\n): Promise<Result<ValidatedModule, ShaderError>> {\n let wasm: Awaited<ReturnType<typeof ensureReady>>;\n try {\n wasm = await ensureReady();\n } catch (e) {\n return err(\n wrapShaderError(\n e,\n 'rerun bash packages/wgpu-wasm/build.sh and verify packages/wgpu-wasm/pkg contains a fresh .wasm',\n ),\n );\n }\n try {\n const validated = (wasm.validate as (p: unknown) => unknown)(parsed);\n return ok(validated as ValidatedModule);\n } catch (e) {\n return err(wrapShaderError(e));\n }\n}\n\n// === Composer passthrough ===========================================================\n\n/**\n * naga_oil Composer passthrough — `#import` + `#ifdef` composition over WGSL.\n *\n * Thin TS wrap over `@forgeax/engine-wgpu-wasm`'s raw `compose_shader` export\n * (feat-20260512 M1 compose.rs). Three-argument surface:\n *\n * - `entry` — the entry-point WGSL source (may contain `#import` directives\n * and `#ifdef` guards).\n * - `imports` — `moduleId -> wgslSource` map; each value is a companion\n * module whose header declares `#define_import_path <moduleId>` so the\n * upstream composer can register it. The map is JSON.stringified at the\n * wasm boundary.\n * - `defines` — `name -> boolean` map driving `#ifdef` branch elimination\n * (plan-strategy D-06: non-boolean values are rejected at the TS layer by\n * the shader-compiler wrapper; this wrap takes booleans verbatim). Also\n * JSON.stringified at the boundary.\n *\n * Return: the composed WGSL string (entry + inlined imports, `#ifdef` branches\n * resolved).\n *\n * Errors: the raw wasm export throws `JsError` whose message carries a\n * `shader-import-not-found: ...` or `shader-compile-failed: ...` prefix\n * (feat-20260512 M1 compose.rs convention). This wrap does **not** translate\n * the prefix into a structured `ShaderError`; that splitting happens one layer\n * up at `@forgeax/engine-shader-compiler` (feat-20260512 M3), which is where\n * the three-argument `compileShader(src, { imports, defines, id })` entry lives.\n * Callers of this raw passthrough should `try / catch` the thrown error.\n *\n * Wasm boundary: awaits `ensureReady()` on first call (shared singleton with\n * `@forgeax/engine-rhi-wgpu` + other naga phases); subsequent calls take the\n * cached path.\n */\nexport async function composeShader(\n entry: string,\n imports: Record<string, string>,\n defines: Record<string, boolean>,\n): Promise<string> {\n const wasm = await ensureReady();\n const compose = (wasm as { compose_shader: (e: string, i: string, d: string) => string })\n .compose_shader;\n return compose(entry, JSON.stringify(imports), JSON.stringify(defines));\n}\n\n// === Phase 3: emit_reflection =======================================================\n\n/**\n * `ValidatedModule` + options JSON -> `BindGroupLayoutDescriptor[]` JSON string.\n *\n * `options_json` shape: `{ \"dynamicOffsets\": [{ \"group\": u32, \"binding\": u32 }, ...] }`.\n * The naga IR does not express the dynamic-offset dimension (research Finding 2\n * footnote), so it is injected via this JS-side options string. Pass an empty\n * `{}` (or a JSON-encoded object without `dynamicOffsets`) for the no-dynamic-\n * offset path.\n *\n * The validator's borrowed reference is **not** consumed — the same\n * `ValidatedModule` handle can be reused for repeated emits with different\n * options (e.g. for variant generation).\n */\nexport async function emit_reflection(\n validated: ValidatedModule,\n options_json: string,\n): Promise<Result<string, ShaderError>> {\n let wasm: Awaited<ReturnType<typeof ensureReady>>;\n try {\n wasm = await ensureReady();\n } catch (e) {\n return err(\n wrapShaderError(\n e,\n 'rerun bash packages/wgpu-wasm/build.sh and verify packages/wgpu-wasm/pkg contains a fresh .wasm',\n ),\n );\n }\n try {\n const reflectionJson = (wasm.emit_reflection as (v: unknown, o: string) => string)(\n validated,\n options_json,\n );\n return ok(reflectionJson);\n } catch (e) {\n return err(wrapShaderError(e));\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["// @forgeax/engine-naga/errors — ShaderError + Result<T, E> + wrapShaderError helper.\n//\n// Form invariants (plan-strategy §D-P4 / requirements MVP-2.3 + AC-09):\n// - ShaderErrorCode (closed 4-member union) is imported from @forgeax/engine-types as\n// the SSOT. This package does **not** redefine the union — +0 breaking points\n// to the error model (AC-09; charter proposition 5 consistent abstraction).\n// - The ShaderError class shape + 4 factory helpers + Result<T, E> shape are\n// byte-for-byte equivalent to @forgeax/engine-shader-compiler/src/errors.ts; that\n// package will re-export from here in w7 after the import switch lands\n// (charter proposition 5 + plan-strategy D-P4 byte-for-byte form recovery).\n// - wrapShaderError is the JsError -> ShaderError adapter for the parse /\n// validate / emit_reflection wrappers in index.ts: it tries to JSON.parse the\n// wasm-side ParseErrorPayload (message / summary / line_num / line_pos)\n// first, falls back to the prose message for validator / reflection failures.\n\n/// <reference types=\"@webgpu/types\" />\n\nimport type { ShaderErrorCode, ShaderErrorDetail } from '@forgeax/engine-types';\n\nexport type { ShaderErrorCode, ShaderErrorDetail };\n\ninterface ShaderErrorInit {\n readonly code: ShaderErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly message: string;\n readonly lineNum?: number | undefined;\n readonly linePos?: number | undefined;\n readonly detail?: ShaderErrorDetail | undefined;\n}\n\n/**\n * Structured shader error.\n *\n * **5 surface fields** (MVP-2.3 top-level surface, AI consumer path):\n * - `.code` — member of the closed `ShaderErrorCode` union (4 variants)\n * - `.message` — display text (the base `Error` field, populated by the constructor)\n * - `.hint` — actionable recovery guidance (charter proposition 3: machine-readable hint over prose)\n * - `.lineNum` / `.linePos` — error source location (mandatory for compile-failed; undefined on other paths)\n *\n * **3 internal fields**:\n * - `.name` = `'ShaderError'` (debug tag)\n * - `.expected` — description of the expected state (symmetric with RhiError)\n * - `.detail` — path-specific extra info (e.g. all 6 fields of GPUCompilationMessage[])\n *\n * **Do not new directly** — construct via the 4 factories (compileFailed /\n * initFailed / manifestMalformed / shaderNotFound) to avoid ad-hoc arguments\n * bypassing union narrowing.\n */\nexport class ShaderError extends Error {\n override readonly name: 'ShaderError' = 'ShaderError';\n readonly code: ShaderErrorCode;\n readonly expected: string;\n readonly hint: string;\n readonly lineNum: number | undefined;\n readonly linePos: number | undefined;\n readonly detail: ShaderErrorDetail | undefined;\n\n constructor(init: ShaderErrorInit) {\n super(init.message);\n this.code = init.code;\n this.expected = init.expected;\n this.hint = init.hint;\n this.lineNum = init.lineNum;\n this.linePos = init.linePos;\n this.detail = init.detail;\n }\n}\n\n// === 4 factory helpers (plan-strategy §D-P4 closed union with 4 members) ===========\n\n/** `shader-compile-failed`: naga parse_str or Validator::validate failure. */\nexport function compileFailed(args: {\n readonly message: string;\n readonly hint: string;\n readonly lineNum?: number | undefined;\n readonly linePos?: number | undefined;\n readonly compilerMessages?: readonly GPUCompilationMessage[] | undefined;\n readonly reason?: string | undefined;\n}): ShaderError {\n return new ShaderError({\n code: 'shader-compile-failed',\n expected: 'WGSL source parses + validates against naga IR',\n message: args.message,\n hint: args.hint,\n ...(args.lineNum !== undefined ? { lineNum: args.lineNum } : {}),\n ...(args.linePos !== undefined ? { linePos: args.linePos } : {}),\n ...(args.compilerMessages !== undefined\n ? {\n detail: {\n code: 'shader-compile-failed',\n compilerMessages: args.compilerMessages,\n ...(args.reason !== undefined ? { reason: args.reason } : {}),\n },\n }\n : {}),\n });\n}\n\n/** `compiler-init-failed`: wasm loading or init() failure (cold start / missing wasm artifact). */\nexport function initFailed(args: {\n readonly message: string;\n readonly hint: string;\n readonly reason?: string | undefined;\n}): ShaderError {\n return new ShaderError({\n code: 'compiler-init-failed',\n expected: '@forgeax/engine-wgpu-wasm ensureReady() resolves with naga raw bindings available',\n message: args.message,\n hint: args.hint,\n detail: {\n code: 'compiler-init-failed',\n ...(args.reason !== undefined ? { reason: args.reason } : {}),\n },\n });\n}\n\n/** `manifest-malformed`: manifest.json schema validation failure (a required field is missing or JSON is not parseable). */\nexport function manifestMalformed(args: {\n readonly message: string;\n readonly hint: string;\n readonly reason?: string | undefined;\n}): ShaderError {\n return new ShaderError({\n code: 'manifest-malformed',\n expected: 'manifest.json parses + every entry has {hash, wgsl, glsl, bindings}',\n message: args.message,\n hint: args.hint,\n detail: {\n code: 'manifest-malformed',\n ...(args.reason !== undefined ? { reason: args.reason } : {}),\n },\n });\n}\n\n/** `shader-not-found`: ShaderRegistry.get(hash) hash miss. */\nexport function shaderNotFound(args: {\n readonly hash: string;\n readonly hint: string;\n}): ShaderError {\n return new ShaderError({\n code: 'shader-not-found',\n expected: `manifest.entries contains entry with hash '${args.hash}'`,\n message: `ShaderRegistry: hash '${args.hash}' not present in manifest`,\n hint: args.hint,\n });\n}\n\n// === wrapShaderError: JsError -> ShaderError adapter ================================\n\n/**\n * Translate a thrown wasm-bindgen JsError to a structured ShaderError.\n *\n * The Rust side serializes `ParseErrorPayload { message, summary, line_num,\n * line_pos }` to a JSON string and uses it as the JsError message. We attempt\n * JSON.parse first; on success the lineNum/linePos are extracted as top-level\n * surface fields (MVP-2.3). On failure (validator errors, reflection errors,\n * non-JSON messages) we fall back to the prose message — hint is always\n * populated so AI consumers always have an actionable recovery signal\n * (charter proposition 4 explicit failure + proposition 3 machine-readable hint).\n */\nexport function wrapShaderError(e: unknown, hint?: string): ShaderError {\n if (e instanceof Error) {\n try {\n const payload = JSON.parse(e.message) as {\n message?: string;\n summary?: string;\n line_num?: number | null;\n line_pos?: number | null;\n };\n return compileFailed({\n message: payload.summary ?? payload.message ?? e.message,\n hint:\n hint ??\n 'fix the WGSL source at the indicated line/column; see ShaderError.detail.compilerMessages for full diagnostic frame',\n ...(typeof payload.line_num === 'number' ? { lineNum: payload.line_num } : {}),\n ...(typeof payload.line_pos === 'number' ? { linePos: payload.line_pos } : {}),\n });\n } catch {\n return compileFailed({\n message: e.message,\n hint: hint ?? 'check WGSL syntax + validation rules; consult naga error output for details',\n });\n }\n }\n return compileFailed({\n message: String(e),\n hint:\n hint ??\n 'unknown error type from @forgeax/engine-wgpu-wasm; report as @forgeax/engine-naga bug',\n });\n}\n\n// === Result<T, E> ====================================================================\n//\n// Result<T, E> + ok / err + ResultOk / ResultErr live in `@forgeax/engine-types`\n// (tweak-20260612-result-into-types). They were duplicated here as a lite\n// (plain-object, no `unwrap`) variant; consolidated upstream into the same\n// shape used by rhi / ecs. The barrel here re-exports them so existing\n// `import { err, ok, Result, ResultOk, ResultErr } from '@forgeax/engine-naga'`\n// consumers stay unchanged.\nexport {\n err,\n ok,\n type Result,\n type ResultErr,\n type ResultOk,\n} from '@forgeax/engine-types';\n","// @forgeax/engine-naga — TS-only thin shell over @forgeax/engine-wgpu-wasm raw naga bindings.\n//\n// Form invariants (locked by plan-strategy D-P3 / D-P4 + research F-4):\n//\n// - snake_case three-phase functions byte-for-byte aligned with naga upstream\n// naming (this package replaces the legacy wasm-pack shim archived in\n// feat-20260511-naga-rhi-wgpu-merge M5 — charter proposition 2 industry\n// analogy + proposition 5 consistent abstraction).\n// - Each public function awaits ensureReady() from @forgeax/engine-wgpu-wasm before\n// calling the raw wasm-bindgen export — one wasm boundary crossing per page\n// lifecycle, shared with @forgeax/engine-rhi-wgpu (research F-4 ensureReady SSOT).\n// - Throws are caught at the wrapper boundary and translated to\n// Result.err(ShaderError) — never throw for expected failures\n// (AGENTS.md \"Errors are structured\" + charter proposition 4 explicit failure).\n// - The opaque handle types ParsedModule / ValidatedModule are re-exported\n// so downstream consumers (@forgeax/engine-shader-compiler) can hold the handle\n// between phases without inspecting the underlying naga IR\n// (plan-strategy §S-1 opaque handle invariant).\n\nimport { ensureReady } from '@forgeax/engine-wgpu-wasm';\nimport {\n err,\n initFailed,\n manifestMalformed,\n ok,\n type Result,\n ShaderError,\n type ShaderError as ShaderErrorType,\n wrapShaderError,\n} from './errors.js';\n\nexport {\n compileFailed,\n err,\n initFailed,\n manifestMalformed,\n ok,\n type Result,\n type ResultErr,\n type ResultOk,\n ShaderError,\n type ShaderErrorCode,\n type ShaderErrorDetail,\n shaderNotFound,\n} from './errors.js';\n\n// === Opaque handle types ============================================================\n\n/**\n * Handle for the `parse` output. The underlying type is a wasm-bindgen exported\n * struct: JS can only hold the handle — it cannot inspect naga IR fields\n * directly (charter proposition 4 + opaque handle invariant). Pass through to\n * `validate` to advance to phase 2.\n *\n * Surface type uses `unknown` to keep this layer math-free and opaque-handle\n * pure (no direct dependency on @forgeax/engine-wgpu-wasm/pkg ABI types). Downstream\n * consumers should not inspect the handle.\n */\nexport type ParsedModule = unknown;\n\n/**\n * Handle for the `validate` output (Module + ModuleInfo); pass through to\n * `emit_reflection` for the reflection JSON emit.\n */\nexport type ValidatedModule = unknown;\n\nexport interface ShaderReflectionMember {\n readonly name: string;\n readonly type: string;\n readonly offset: number;\n readonly size: number;\n readonly alignment: number;\n}\n\nexport interface ShaderReflectionBoundGlobal {\n readonly group: number;\n readonly binding: number;\n readonly addressSpace: string;\n readonly resourceKind: string;\n readonly visibility: number;\n readonly name?: string;\n readonly members?: readonly ShaderReflectionMember[];\n readonly span?: number;\n}\n\nexport interface ShaderReflection {\n readonly schemaVersion: 'shader-reflection/2';\n readonly boundGlobals: readonly ShaderReflectionBoundGlobal[];\n readonly uvSetCount: number;\n}\n\ntype ReflectionRecord = Record<string, unknown>;\n\nfunction reflectionMalformed(reason: string): ShaderError {\n return manifestMalformed({\n message: `shader-reflection/2 is malformed: ${reason}`,\n hint: 'rebuild the shader with the current Naga/WASM producer and preserve every bound-global fact',\n reason,\n });\n}\n\nfunction isRecord(value: unknown): value is ReflectionRecord {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction requiredNonNegativeInteger(record: ReflectionRecord, key: string): number {\n const value = record[key];\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) {\n throw reflectionMalformed(`boundGlobals entry requires non-negative integer '${key}'`);\n }\n return value;\n}\n\nfunction readMember(value: unknown, index: number): ShaderReflectionMember {\n if (!isRecord(value)) throw reflectionMalformed(`member ${index} is not an object`);\n const name = value.name;\n const type = value.type;\n if (\n typeof name !== 'string' ||\n name.length === 0 ||\n typeof type !== 'string' ||\n type.length === 0\n ) {\n throw reflectionMalformed(`member ${index} requires name and type`);\n }\n return {\n name,\n type,\n offset: requiredNonNegativeInteger(value, 'offset'),\n size: requiredNonNegativeInteger(value, 'size'),\n alignment: requiredNonNegativeInteger(value, 'alignment'),\n };\n}\n\nfunction readBoundGlobal(value: unknown, index: number): ShaderReflectionBoundGlobal {\n if (!isRecord(value)) throw reflectionMalformed(`boundGlobals entry ${index} is not an object`);\n const addressSpace = value.addressSpace;\n const resourceKind = value.resourceKind;\n if (typeof addressSpace !== 'string' || addressSpace.length === 0) {\n throw reflectionMalformed(`boundGlobals entry ${index} requires addressSpace`);\n }\n if (typeof resourceKind !== 'string' || resourceKind.length === 0) {\n throw reflectionMalformed(`boundGlobals entry ${index} requires resourceKind`);\n }\n const visibility = requiredNonNegativeInteger(value, 'visibility');\n const membersValue = value.members;\n const hasMembers = membersValue !== undefined;\n if (hasMembers && !Array.isArray(membersValue)) {\n throw reflectionMalformed(`boundGlobals entry ${index} members must be an array`);\n }\n const hasSpan = value.span !== undefined;\n if (resourceKind === 'buffer' || resourceKind === 'storage-buffer') {\n if (!hasMembers || !hasSpan) {\n throw reflectionMalformed(`buffer boundGlobals entry ${index} requires members and span`);\n }\n } else if (hasMembers !== hasSpan) {\n throw reflectionMalformed(`boundGlobals entry ${index} members and span must be paired`);\n }\n if (value.name !== undefined && typeof value.name !== 'string') {\n throw reflectionMalformed(`boundGlobals entry ${index} diagnostic name must be a string`);\n }\n return {\n group: requiredNonNegativeInteger(value, 'group'),\n binding: requiredNonNegativeInteger(value, 'binding'),\n addressSpace,\n resourceKind,\n visibility,\n ...(value.name !== undefined ? { name: value.name as string } : {}),\n ...(hasMembers\n ? {\n members: (membersValue as unknown[]).map((member, memberIndex) =>\n readMember(member, memberIndex),\n ),\n span: requiredNonNegativeInteger(value, 'span'),\n }\n : {}),\n };\n}\n\n/** Parse and validate the business-neutral shader-reflection/2 wire. */\nexport function parseReflectionWire(json: string): ShaderReflection {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch (cause) {\n throw reflectionMalformed(cause instanceof Error ? cause.message : 'JSON.parse failed');\n }\n if (!isRecord(parsed) || parsed.schemaVersion !== 'shader-reflection/2') {\n throw reflectionMalformed(\"schemaVersion must equal 'shader-reflection/2'\");\n }\n if ('material' in parsed) throw reflectionMalformed('legacy material projection is not accepted');\n if (!Array.isArray(parsed.boundGlobals)) {\n throw reflectionMalformed('boundGlobals must be an array');\n }\n if (\n typeof parsed.uvSetCount !== 'number' ||\n !Number.isSafeInteger(parsed.uvSetCount) ||\n parsed.uvSetCount < 0\n ) {\n throw reflectionMalformed('uvSetCount must be a non-negative integer');\n }\n const boundGlobals = parsed.boundGlobals.map((global, index) => readBoundGlobal(global, index));\n const coordinates = new Set<string>();\n for (const global of boundGlobals) {\n const coordinate = `${global.group}:${global.binding}`;\n if (coordinates.has(coordinate))\n throw reflectionMalformed(`duplicate bound-global coordinate ${coordinate}`);\n coordinates.add(coordinate);\n }\n return { schemaVersion: 'shader-reflection/2', boundGlobals, uvSetCount: parsed.uvSetCount };\n}\n\n/** Result-form reader for callers that need an explicit unavailable/malformed branch. */\nexport function readReflectionWire(\n json: string | undefined,\n): Result<ShaderReflection, ShaderErrorType> {\n if (json === undefined) {\n return err(\n initFailed({\n message: 'shader-reflection/2 is unavailable before the Naga producer emits a wire',\n hint: 'run the validated compose -> reflect path and retain its raw reflection bytes',\n reason: 'reflection wire unavailable',\n }),\n );\n }\n try {\n return ok(parseReflectionWire(json));\n } catch (error) {\n return err(error instanceof ShaderError ? error : reflectionMalformed(String(error)));\n }\n}\n\n// === Phase 1: parse =================================================================\n\n/**\n * WGSL source -> `ParsedModule`.\n *\n * On failure returns `Result.err(ShaderError code='shader-compile-failed')`\n * whose `lineNum` / `linePos` carry the source position (from the wasm-side\n * `ParseErrorPayload`). The hint defaults to actionable WGSL fix guidance.\n *\n * Wasm boundary: awaits ensureReady() on first call (shared singleton with\n * @forgeax/engine-rhi-wgpu); subsequent calls take the cached path.\n */\nexport async function parse(source: string): Promise<Result<ParsedModule, ShaderError>> {\n let wasm: Awaited<ReturnType<typeof ensureReady>>;\n try {\n wasm = await ensureReady();\n } catch (e) {\n return err(\n wrapShaderError(\n e,\n 'rerun bash packages/wgpu-wasm/build.sh and verify packages/wgpu-wasm/pkg contains a fresh .wasm',\n ),\n );\n }\n try {\n const parsed = wasm.parse(source);\n return ok(parsed as ParsedModule);\n } catch (e) {\n return err(wrapShaderError(e));\n }\n}\n\n// === Phase 2: validate ==============================================================\n\n/**\n * `ParsedModule` -> `ValidatedModule` (Module + ModuleInfo).\n *\n * **Ownership transfer** — wasm-bindgen consumes the `parsed` handle. Do not\n * reuse the handle after this call; passing a consumed handle is undefined\n * behaviour on the wasm side (research Finding 6 ownership semantics).\n *\n * On failure returns `Result.err(ShaderError code='shader-compile-failed')`.\n * Validator errors have no source position attached on the wasm side, so\n * `lineNum` / `linePos` remain undefined.\n */\nexport async function validate(\n parsed: ParsedModule,\n): Promise<Result<ValidatedModule, ShaderError>> {\n let wasm: Awaited<ReturnType<typeof ensureReady>>;\n try {\n wasm = await ensureReady();\n } catch (e) {\n return err(\n wrapShaderError(\n e,\n 'rerun bash packages/wgpu-wasm/build.sh and verify packages/wgpu-wasm/pkg contains a fresh .wasm',\n ),\n );\n }\n try {\n const validated = (wasm.validate as (p: unknown) => unknown)(parsed);\n return ok(validated as ValidatedModule);\n } catch (e) {\n return err(wrapShaderError(e));\n }\n}\n\n/** Validate a selected vertex/fragment pair against the validated Naga module. */\nexport async function validateRenderEntries(\n module: ValidatedModule,\n vertex: string,\n fragment?: string,\n): Promise<Result<void, ShaderError>> {\n try {\n const wasm = await ensureReady();\n (wasm.validate_render_entries as (module: unknown, vertex: string, fragment?: string) => void)(\n module,\n vertex,\n fragment,\n );\n return ok(undefined);\n } catch (error) {\n return err(wrapShaderError(error));\n }\n}\n\n// === Composer passthrough ===========================================================\n\n/**\n * naga_oil Composer passthrough — `#import` + `#ifdef` composition over WGSL.\n *\n * Thin TS wrap over `@forgeax/engine-wgpu-wasm`'s raw `compose_shader` export\n * (feat-20260512 M1 compose.rs). Three-argument surface:\n *\n * - `entry` — the entry-point WGSL source (may contain `#import` directives\n * and `#ifdef` guards).\n * - `imports` — `moduleId -> wgslSource` map; each value is a companion\n * module whose header declares `#define_import_path <moduleId>` so the\n * upstream composer can register it. The map is JSON.stringified at the\n * wasm boundary.\n * - `defines` — `name -> boolean` map driving `#ifdef` branch elimination\n * (plan-strategy D-06: non-boolean values are rejected at the TS layer by\n * the shader-compiler wrapper; this wrap takes booleans verbatim). Also\n * JSON.stringified at the boundary.\n *\n * Return: the composed WGSL string (entry + inlined imports, `#ifdef` branches\n * resolved).\n *\n * Errors: the raw wasm export throws `JsError` whose message carries a\n * `shader-import-not-found: ...` or `shader-compile-failed: ...` prefix\n * (feat-20260512 M1 compose.rs convention). This wrap does **not** translate\n * the prefix into a structured `ShaderError`; that splitting happens one layer\n * up at `@forgeax/engine-shader-compiler` (feat-20260512 M3), which is where\n * the three-argument `compileShader(src, { imports, defines, id })` entry lives.\n * Callers of this raw passthrough should `try / catch` the thrown error.\n *\n * Wasm boundary: awaits `ensureReady()` on first call (shared singleton with\n * `@forgeax/engine-rhi-wgpu` + other naga phases); subsequent calls take the\n * cached path.\n */\nexport async function composeShader(\n entry: string,\n imports: Record<string, string>,\n defines: Record<string, boolean>,\n): Promise<string> {\n const wasm = await ensureReady();\n const compose = (wasm as { compose_shader: (e: string, i: string, d: string) => string })\n .compose_shader;\n return compose(entry, JSON.stringify(imports), JSON.stringify(defines));\n}\n\n// === Phase 3: emit_reflection =======================================================\n\n/**\n * `ValidatedModule` + options JSON -> `BindGroupLayoutDescriptor[]` JSON string.\n *\n * `options_json` shape: `{ \"dynamicOffsets\": [{ \"group\": u32, \"binding\": u32 }, ...] }`.\n * The naga IR does not express the dynamic-offset dimension (research Finding 2\n * footnote), so it is injected via this JS-side options string. Pass an empty\n * `{}` (or a JSON-encoded object without `dynamicOffsets`) for the no-dynamic-\n * offset path.\n *\n * The validator's borrowed reference is **not** consumed — the same\n * `ValidatedModule` handle can be reused for repeated emits with different\n * options (e.g. for variant generation).\n */\nexport async function emit_reflection(\n validated: ValidatedModule,\n options_json: string,\n): Promise<Result<string, ShaderError>> {\n let wasm: Awaited<ReturnType<typeof ensureReady>>;\n try {\n wasm = await ensureReady();\n } catch (e) {\n return err(\n wrapShaderError(\n e,\n 'rerun bash packages/wgpu-wasm/build.sh and verify packages/wgpu-wasm/pkg contains a fresh .wasm',\n ),\n );\n }\n try {\n const reflectionJson = (wasm.emit_reflection as (v: unknown, o: string) => string)(\n validated,\n options_json,\n );\n return ok(reflectionJson);\n } catch (e) {\n return err(wrapShaderError(e));\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgeax/engine-naga",
3
- "version": "0.1.25",
3
+ "version": "0.1.26",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -22,8 +22,8 @@
22
22
  "LICENSE"
23
23
  ],
24
24
  "dependencies": {
25
- "@forgeax/engine-types": "0.1.25",
26
- "@forgeax/engine-wgpu-wasm": "0.1.25",
25
+ "@forgeax/engine-types": "0.1.26",
26
+ "@forgeax/engine-wgpu-wasm": "0.1.26",
27
27
  "@webgpu/types": "^0.1.71"
28
28
  },
29
29
  "forgeax": {
package/src/index.ts CHANGED
@@ -297,6 +297,25 @@ export async function validate(
297
297
  }
298
298
  }
299
299
 
300
+ /** Validate a selected vertex/fragment pair against the validated Naga module. */
301
+ export async function validateRenderEntries(
302
+ module: ValidatedModule,
303
+ vertex: string,
304
+ fragment?: string,
305
+ ): Promise<Result<void, ShaderError>> {
306
+ try {
307
+ const wasm = await ensureReady();
308
+ (wasm.validate_render_entries as (module: unknown, vertex: string, fragment?: string) => void)(
309
+ module,
310
+ vertex,
311
+ fragment,
312
+ );
313
+ return ok(undefined);
314
+ } catch (error) {
315
+ return err(wrapShaderError(error));
316
+ }
317
+ }
318
+
300
319
  // === Composer passthrough ===========================================================
301
320
 
302
321
  /**