{"version":3,"sources":["../src/mesh-bin-contract.ts"],"names":[],"mappings":"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","file":"mesh-bin-contract.mjs","sourcesContent":["/** Canonical mesh binary wire facts shared by build-time and runtime owners. */\n\nexport const MESH_BIN_VERSION = 5 as const;\nexport const MESH_BIN_PROJECTION_VERSION = 1 as const;\nexport const MESH_BIN_HEADER_BYTES = 80;\nexport const MESH_BIN_DIGEST_BYTES = 32;\n\nexport interface MeshBinHeader {\n  readonly version: 4 | 5;\n  readonly projectionVersion: 1;\n  readonly mask: number;\n  readonly digest: string;\n  readonly stride: number;\n  readonly vertexCount: number;\n  readonly vertexBytes: number;\n  readonly indexCount: number;\n  readonly indexWidth: 0 | 2 | 4;\n  readonly indexBytes: number;\n  readonly jsonBytes: number;\n  readonly morphBytes: number;\n}\n\nexport interface MeshBinContractError {\n  readonly code:\n    | 'mesh-bin-header-truncated'\n    | 'mesh-bin-version-unsupported'\n    | 'mesh-bin-header-invalid';\n  readonly subject: 'mesh-bin';\n  readonly sourceKey: string;\n  readonly expected: string;\n  readonly actual: string;\n  readonly recovery: string;\n}\n\nexport type MeshBinHeaderResult =\n  | { readonly ok: true; readonly value: MeshBinHeader }\n  | { readonly ok: false; readonly error: MeshBinContractError };\n\nfunction failure(\n  code: MeshBinContractError['code'],\n  sourceKey: string,\n  expected: string,\n  actual: string,\n): MeshBinHeaderResult {\n  return {\n    ok: false,\n    error: {\n      code,\n      subject: 'mesh-bin',\n      sourceKey,\n      expected,\n      actual,\n      recovery: 're-cook the source with its Meta sidecar through the build-time importer',\n    },\n  };\n}\n\nfunction digestBytes(digest: string): Uint8Array {\n  const bytes = new Uint8Array(MESH_BIN_DIGEST_BYTES);\n  bytes.set(new TextEncoder().encode(digest).subarray(0, MESH_BIN_DIGEST_BYTES));\n  return bytes;\n}\n\nfunction readDigest(bytes: Uint8Array): string {\n  return new TextDecoder().decode(bytes).replace(/\\0+$/u, '');\n}\n\nexport function writeMeshBinHeader(header: MeshBinHeader, out: Uint8Array): void {\n  if (out.byteLength < MESH_BIN_HEADER_BYTES) {\n    throw new RangeError('mesh-bin header output is truncated');\n  }\n  const view = new DataView(out.buffer, out.byteOffset, out.byteLength);\n  view.setUint32(0, header.version, true);\n  view.setUint32(4, header.projectionVersion, true);\n  view.setUint32(8, header.mask, true);\n  view.setUint32(12, header.stride, true);\n  view.setUint32(16, header.vertexCount, true);\n  view.setUint32(20, header.vertexBytes, true);\n  view.setUint32(24, header.indexCount, true);\n  view.setUint32(28, header.indexWidth, true);\n  view.setUint32(32, header.indexBytes, true);\n  view.setUint32(36, header.jsonBytes, true);\n  view.setUint32(40, header.version === 5 ? header.morphBytes : 0, true);\n  view.setUint32(44, 0, true);\n  out.set(digestBytes(header.digest), 48);\n}\n\nexport function decodeMeshBinHeader(\n  bytes: Uint8Array,\n  sourceKey = '<unknown mesh source>',\n): MeshBinHeaderResult {\n  if (bytes.byteLength < MESH_BIN_HEADER_BYTES) {\n    return failure(\n      'mesh-bin-header-truncated',\n      sourceKey,\n      `mesh-bin v4/v5 header (${MESH_BIN_HEADER_BYTES} bytes)`,\n      `${bytes.byteLength} bytes`,\n    );\n  }\n  const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n  const version = view.getUint32(0, true);\n  if (version !== 4 && version !== MESH_BIN_VERSION) {\n    return failure(\n      'mesh-bin-version-unsupported',\n      sourceKey,\n      'mesh-bin v4 or v5',\n      `version ${version}`,\n    );\n  }\n  const projectionVersion = view.getUint32(4, true);\n  const mask = view.getUint32(8, true);\n  const stride = view.getUint32(12, true);\n  const vertexCount = view.getUint32(16, true);\n  const vertexBytes = view.getUint32(20, true);\n  const indexCount = view.getUint32(24, true);\n  const indexWidth = view.getUint32(28, true);\n  const indexBytes = view.getUint32(32, true);\n  const jsonBytes = view.getUint32(36, true);\n  const morphBytes = version === 5 ? view.getUint32(40, true) : 0;\n  const digest = readDigest(bytes.subarray(48, 48 + MESH_BIN_DIGEST_BYTES));\n  if (\n    projectionVersion !== MESH_BIN_PROJECTION_VERSION ||\n    mask === 0 ||\n    morphBytes % 4 !== 0 ||\n    (version === 5 && view.getUint32(44, true) !== 0) ||\n    stride === 0 ||\n    !Number.isSafeInteger(vertexCount) ||\n    !Number.isSafeInteger(vertexBytes) ||\n    !Number.isSafeInteger(indexCount) ||\n    !Number.isSafeInteger(indexBytes) ||\n    !Number.isSafeInteger(jsonBytes) ||\n    (indexCount === 0 && indexWidth !== 0) ||\n    (indexCount > 0 && indexWidth !== 2 && indexWidth !== 4) ||\n    indexBytes !== indexCount * indexWidth ||\n    vertexBytes !== vertexCount * stride ||\n    digest.length === 0\n  ) {\n    return failure(\n      'mesh-bin-header-invalid',\n      sourceKey,\n      'safe mesh projection, stride, cardinality, and payload byte lengths',\n      `projection=${projectionVersion}; mask=${mask}; stride=${stride}; vertexBytes=${vertexBytes}; indexBytes=${indexBytes}; digest=${digest}`,\n    );\n  }\n  return {\n    ok: true,\n    value: {\n      version,\n      projectionVersion: 1,\n      mask,\n      digest,\n      stride,\n      vertexCount,\n      vertexBytes,\n      indexCount,\n      indexWidth: indexWidth as 0 | 2 | 4,\n      indexBytes,\n      jsonBytes,\n      morphBytes,\n    },\n  };\n}\n\n/** Low bits declare channels; corresponding bits shifted by three elide all-positive-zero lanes. */\nexport const MESH_BIN_MORPH_CHANNELS = [\n  { key: 'position', mask: 1, components: 3 },\n  { key: 'normal', mask: 2, components: 3 },\n  { key: 'tangent', mask: 4, components: 4 },\n] as const;\n\n/** Decode v5 morph lanes into private arrays; both mesh readers use this wire contract. */\nexport function decodeMeshBinMorphs(\n  bytes: Uint8Array,\n  vertexCount: number,\n  masks: unknown,\n): ReadonlyArray<Record<string, Float32Array>> | undefined {\n  if (masks === undefined) {\n    if (bytes.byteLength !== 0) throw new TypeError('morph bytes require target masks');\n    return undefined;\n  }\n  if (!Array.isArray(masks) || masks.length < 1 || masks.length > 8)\n    throw new TypeError('expected one to eight morph target masks');\n  let expected = 0;\n  for (const mask of masks) {\n    if (\n      !Number.isInteger(mask) ||\n      mask < 1 ||\n      mask > 63 ||\n      !(mask & 7) ||\n      ((mask >> 3) & ~(mask & 7)) !== 0\n    )\n      throw new TypeError('unknown or empty morph channel mask');\n    for (const channel of MESH_BIN_MORPH_CHANNELS)\n      if (mask & channel.mask && !(mask & (channel.mask << 3)))\n        expected += vertexCount * channel.components * 4;\n  }\n  if (!Number.isSafeInteger(expected) || expected !== bytes.byteLength)\n    throw new TypeError('morph lane byte length differs from target cardinality');\n  const littleEndian = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;\n  const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n  let offset = 0;\n  return masks.map((mask: number) => {\n    const target: Record<string, Float32Array> = {};\n    for (const channel of MESH_BIN_MORPH_CHANNELS) {\n      if (!(mask & channel.mask)) continue;\n      const values = new Float32Array(vertexCount * channel.components);\n      if (mask & (channel.mask << 3)) {\n        target[channel.key] = values;\n        continue;\n      }\n      if (littleEndian)\n        new Uint8Array(values.buffer).set(bytes.subarray(offset, offset + values.byteLength));\n      for (let i = 0; i < values.length; i++) {\n        if (!littleEndian) values[i] = view.getFloat32(offset + i * 4, true);\n        if (!Number.isFinite(values[i])) throw new TypeError('non-finite morph lane');\n      }\n      offset += values.byteLength;\n      target[channel.key] = values;\n    }\n    return target;\n  });\n}\n"]}