@forgeax/engine-pack 0.1.21 → 0.1.24

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.
Files changed (139) hide show
  1. package/README.md +167 -48
  2. package/dist/__tests__/inventory-schema.test.d.ts +2 -0
  3. package/dist/__tests__/inventory-schema.test.d.ts.map +1 -0
  4. package/dist/__tests__/material-cook-receipt-layer-plan.unit.test.d.ts +2 -0
  5. package/dist/__tests__/material-cook-receipt-layer-plan.unit.test.d.ts.map +1 -0
  6. package/dist/__tests__/pack-authoring-gateway.unit.test.d.ts +2 -0
  7. package/dist/__tests__/pack-authoring-gateway.unit.test.d.ts.map +1 -0
  8. package/dist/__tests__/pack-authoring.unit.test.d.ts +2 -0
  9. package/dist/__tests__/pack-authoring.unit.test.d.ts.map +1 -0
  10. package/dist/__tests__/pack-scanner.unit.test.d.ts +2 -0
  11. package/dist/__tests__/pack-scanner.unit.test.d.ts.map +1 -0
  12. package/dist/__tests__/scanner-blacklist.test.d.ts +2 -0
  13. package/dist/__tests__/scanner-blacklist.test.d.ts.map +1 -0
  14. package/dist/build.d.ts +9 -4
  15. package/dist/build.d.ts.map +1 -1
  16. package/dist/build.mjs +3449 -897
  17. package/dist/build.mjs.map +1 -1
  18. package/dist/builtin.mjs +37 -4
  19. package/dist/builtin.mjs.map +1 -1
  20. package/dist/catalog-builder.d.ts.map +1 -1
  21. package/dist/cli-asset.d.ts.map +1 -1
  22. package/dist/cli-asset.mjs +1361 -845
  23. package/dist/cli-asset.mjs.map +1 -1
  24. package/dist/deriveAssetName.d.ts +11 -7
  25. package/dist/deriveAssetName.d.ts.map +1 -1
  26. package/dist/evidence/material-cook.d.ts +11 -0
  27. package/dist/evidence/material-cook.d.ts.map +1 -1
  28. package/dist/evidence/source-inventory.d.ts.map +1 -1
  29. package/dist/guid.d.ts +15 -0
  30. package/dist/guid.d.ts.map +1 -1
  31. package/dist/guid.mjs +53 -5
  32. package/dist/guid.mjs.map +1 -1
  33. package/dist/index.d.ts +4 -2
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.mjs +1297 -562
  36. package/dist/index.mjs.map +1 -1
  37. package/dist/inventory/binding.d.ts +6 -0
  38. package/dist/inventory/binding.d.ts.map +1 -0
  39. package/dist/inventory/declaration.d.ts +24 -0
  40. package/dist/inventory/declaration.d.ts.map +1 -0
  41. package/dist/inventory/index.d.ts +3 -0
  42. package/dist/inventory/index.d.ts.map +1 -0
  43. package/dist/inventory/sync.d.ts +5 -0
  44. package/dist/inventory/sync.d.ts.map +1 -0
  45. package/dist/material-cook.d.ts +1 -1
  46. package/dist/material-cook.d.ts.map +1 -1
  47. package/dist/material-cook.mjs +50 -3
  48. package/dist/material-cook.mjs.map +1 -1
  49. package/dist/name.mjs +4 -7
  50. package/dist/name.mjs.map +1 -1
  51. package/dist/pack-authoring-node.d.ts +26 -0
  52. package/dist/pack-authoring-node.d.ts.map +1 -0
  53. package/dist/pack-authoring-node.mjs +11089 -0
  54. package/dist/pack-authoring-node.mjs.map +1 -0
  55. package/dist/pack-authoring.d.ts +230 -0
  56. package/dist/pack-authoring.d.ts.map +1 -0
  57. package/dist/pack-authoring.mjs +1137 -0
  58. package/dist/pack-authoring.mjs.map +1 -0
  59. package/dist/package-finalizer.d.ts +2 -20
  60. package/dist/package-finalizer.d.ts.map +1 -1
  61. package/dist/resolve-asset-source.d.ts +1 -3
  62. package/dist/resolve-asset-source.d.ts.map +1 -1
  63. package/dist/resolve-asset-source.mjs +6 -81
  64. package/dist/resolve-asset-source.mjs.map +1 -1
  65. package/dist/runtime.mjs +77 -7
  66. package/dist/runtime.mjs.map +1 -1
  67. package/dist/scanner.d.ts +18 -7
  68. package/dist/scanner.d.ts.map +1 -1
  69. package/dist/scanner.mjs +1164 -687
  70. package/dist/scanner.mjs.map +1 -1
  71. package/dist/schema-compiled.d.ts.map +1 -1
  72. package/dist/schema.mjs +79 -7
  73. package/dist/schema.mjs.map +1 -1
  74. package/dist/scriptable-pack-node.d.ts +7 -31
  75. package/dist/scriptable-pack-node.d.ts.map +1 -1
  76. package/dist/scriptable-pack-node.mjs +572 -1019
  77. package/dist/scriptable-pack-node.mjs.map +1 -1
  78. package/dist/scriptable-pack-worker.mjs +29 -11
  79. package/dist/scriptable-pack-worker.mjs.map +1 -1
  80. package/dist/scriptable-pack.d.ts +20 -532
  81. package/dist/scriptable-pack.d.ts.map +1 -1
  82. package/dist/scriptable-pack.mjs +1038 -527
  83. package/dist/scriptable-pack.mjs.map +1 -1
  84. package/package.json +2 -7
  85. package/schema/meta.schema.json +1 -1
  86. package/schema/pack.schema.json +76 -6
  87. package/src/__tests__/guid-collision.unit.test.ts +18 -9
  88. package/src/__tests__/inventory-schema.test.ts +109 -0
  89. package/src/__tests__/material-cook-receipt-layer-plan.unit.test.ts +16 -0
  90. package/src/__tests__/material-cook-schema.unit.test.ts +62 -0
  91. package/src/__tests__/pack-authoring-gateway.unit.test.ts +249 -0
  92. package/src/__tests__/pack-authoring.unit.test.ts +266 -0
  93. package/src/__tests__/pack-scanner.unit.test.ts +123 -0
  94. package/src/__tests__/pack.unit.test.ts +1 -238
  95. package/src/__tests__/package-finalizer.contract.test.ts +55 -0
  96. package/src/__tests__/resolve-asset-source.test.ts +15 -98
  97. package/src/__tests__/scanner-blacklist.test.ts +55 -0
  98. package/src/__tests__/scanner-inventory.contract.test.ts +11 -14
  99. package/src/__tests__/scanner-inventory.test.ts +23 -10
  100. package/src/__tests__/scriptable-pack-cli.integration.test.ts +4 -9
  101. package/src/__tests__/topology.unit.test.ts +23 -0
  102. package/src/build.ts +28 -18
  103. package/src/catalog-builder.ts +60 -33
  104. package/src/cli-asset.ts +68 -83
  105. package/src/deriveAssetName.ts +14 -13
  106. package/src/evidence/material-cook.ts +79 -3
  107. package/src/evidence/source-inventory.ts +34 -21
  108. package/src/guid.ts +65 -4
  109. package/src/index.ts +15 -11
  110. package/src/inventory/binding.ts +25 -0
  111. package/src/inventory/declaration.ts +168 -0
  112. package/src/inventory/index.ts +18 -0
  113. package/src/inventory/sync.ts +22 -0
  114. package/src/material-cook.ts +1 -0
  115. package/src/pack-authoring-node.ts +1966 -0
  116. package/src/pack-authoring.ts +1478 -0
  117. package/src/package-finalizer.ts +2 -42
  118. package/src/resolve-asset-source.ts +4 -76
  119. package/src/scanner.ts +236 -56
  120. package/src/schema/material-cook.schema.json +4 -1
  121. package/src/schema-compiled.ts +2 -0
  122. package/src/scriptable-pack-node.ts +108 -719
  123. package/src/scriptable-pack-worker.ts +48 -16
  124. package/src/scriptable-pack.ts +28 -939
  125. package/dist/.tsbuildinfo +0 -1
  126. package/dist/__tests__/load-asset-config.test.d.ts +0 -2
  127. package/dist/__tests__/load-asset-config.test.d.ts.map +0 -1
  128. package/dist/__tests__/scriptable-pack.test-d.d.ts +0 -2
  129. package/dist/__tests__/scriptable-pack.test-d.d.ts.map +0 -1
  130. package/dist/__tests__/scriptable-pack.unit.test.d.ts +0 -2
  131. package/dist/__tests__/scriptable-pack.unit.test.d.ts.map +0 -1
  132. package/dist/config.d.ts +0 -6
  133. package/dist/config.d.ts.map +0 -1
  134. package/dist/config.mjs +0 -29
  135. package/dist/config.mjs.map +0 -1
  136. package/src/__tests__/load-asset-config.test.ts +0 -121
  137. package/src/__tests__/scriptable-pack.test-d.ts +0 -131
  138. package/src/__tests__/scriptable-pack.unit.test.ts +0 -789
  139. package/src/config.ts +0 -36
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
- import { MATERIAL_TEXTURE_SLOTS, ok, projectCookProductEvidence, projectAssetEvidence, err, validateSourceOverrideMap } from '@forgeax/engine-types';
1
+ import { deriveStandardLayerPlan, MATERIAL_TEXTURE_SLOTS, ok, projectCookProductEvidence, projectAssetEvidence, err, validateSourceOverrideMap } from '@forgeax/engine-types';
2
2
  import { sha256 } from '@noble/hashes/sha2.js';
3
3
  import { bytesToHex } from '@noble/hashes/utils.js';
4
+ import { sha1 } from '@noble/hashes/legacy.js';
4
5
  import { uuidv7obj } from 'uuidv7';
5
6
 
6
7
  var __create = Object.create;
@@ -4708,8 +4709,8 @@ var require_multipleOf = __commonJS({
4708
4709
  const { gen, data, schemaCode, it } = cxt;
4709
4710
  const prec = it.opts.multipleOfPrecision;
4710
4711
  const res = gen.let("res");
4711
- const invalid4 = prec ? (0, codegen_1._)`Math.abs(Math.round(${res}) - ${res}) > 1e-${prec}` : (0, codegen_1._)`${res} !== parseInt(${res})`;
4712
- cxt.fail$data((0, codegen_1._)`(${schemaCode} === 0 || (${res} = ${data}/${schemaCode}, ${invalid4}))`);
4712
+ const invalid3 = prec ? (0, codegen_1._)`Math.abs(Math.round(${res}) - ${res}) > 1e-${prec}` : (0, codegen_1._)`${res} !== parseInt(${res})`;
4713
+ cxt.fail$data((0, codegen_1._)`(${schemaCode} === 0 || (${res} = ${data}/${schemaCode}, ${invalid3}))`);
4713
4714
  }
4714
4715
  };
4715
4716
  exports.default = def;
@@ -6814,6 +6815,24 @@ var require_dist = __commonJS({
6814
6815
  exports.default = formatsPlugin;
6815
6816
  }
6816
6817
  });
6818
+ var STANDARD_ROOT_MODULES = /* @__PURE__ */ new Set([
6819
+ "forgeax::default-standard-pbr",
6820
+ "forgeax::pbr-skin",
6821
+ "forgeax_material::standard",
6822
+ "forgeax_material::pbr-skin"
6823
+ ]);
6824
+ function isStandardRootModule(module) {
6825
+ return STANDARD_ROOT_MODULES.has(module);
6826
+ }
6827
+ function isStandardMaterialRecord(record) {
6828
+ return record.resolved.passes.some((pass) => isStandardRootModule(pass.program.module));
6829
+ }
6830
+ function materialLayerPlanIdentity(record) {
6831
+ if (!isStandardMaterialRecord(record)) {
6832
+ return void 0;
6833
+ }
6834
+ return deriveStandardLayerPlan(record.resolved.parameters, record.resolved.passes).identity;
6835
+ }
6817
6836
  function unique(values) {
6818
6837
  return [...new Set(values)].sort();
6819
6838
  }
@@ -6896,14 +6915,14 @@ function serializeCookedMaterialRecord(record) {
6896
6915
  function serializeMaterialCookReceipt(receipt) {
6897
6916
  return JSON.stringify(jsonValue({ ...receipt, sourceClosure: unique(receipt.sourceClosure) }));
6898
6917
  }
6899
- function invalid(field, actual2) {
6918
+ function invalid(field, actual) {
6900
6919
  return err({
6901
6920
  code: "material-cook-record-invalid",
6902
6921
  expected: "a complete material-cook/3 record with layered identity and provenance",
6903
6922
  hint: "re-cook the material and publish its record, artifact, references, and receipt together",
6904
6923
  detail: {
6905
6924
  field,
6906
- ...actual2 === void 0 ? {} : { actual: actual2 },
6925
+ ...actual === void 0 ? {} : { actual },
6907
6926
  action: "inspect the named field and recook the material generation"
6908
6927
  }
6909
6928
  });
@@ -6964,6 +6983,12 @@ function validateMaterialCookReceipt(value, expected = {}) {
6964
6983
  if (derivedInterface.layoutIdentity !== identity.layoutIdentity) {
6965
6984
  return invalid("receipt.derivedInterface.layoutIdentity", derivedInterface.layoutIdentity);
6966
6985
  }
6986
+ if (derivedInterface.layerPlanIdentity !== void 0 && (typeof derivedInterface.layerPlanIdentity !== "string" || derivedInterface.layerPlanIdentity.length === 0)) {
6987
+ return invalid(
6988
+ "receipt.derivedInterface.layerPlanIdentity",
6989
+ derivedInterface.layerPlanIdentity
6990
+ );
6991
+ }
6967
6992
  for (const field of ["sourceClosure", "profile", "compilerVersion"]) {
6968
6993
  const fieldValue = candidate[field];
6969
6994
  if (field === "sourceClosure" && !Array.isArray(fieldValue) || field !== "sourceClosure" && typeof fieldValue !== "string") {
@@ -6989,7 +7014,10 @@ function validateMaterialCookReceipt(value, expected = {}) {
6989
7014
  profile: candidate.profile,
6990
7015
  compilerVersion: candidate.compilerVersion,
6991
7016
  identity,
6992
- derivedInterface: { layoutIdentity: derivedInterface.layoutIdentity }
7017
+ derivedInterface: {
7018
+ layoutIdentity: derivedInterface.layoutIdentity,
7019
+ ...derivedInterface.layerPlanIdentity === void 0 ? {} : { layerPlanIdentity: derivedInterface.layerPlanIdentity }
7020
+ }
6993
7021
  });
6994
7022
  }
6995
7023
  function validateCookedMaterialRecord(value) {
@@ -7032,6 +7060,26 @@ function validateCookedMaterialRecord(value) {
7032
7060
  artifactDigest: artifact.digest
7033
7061
  });
7034
7062
  if (!receiptResult.ok) return receiptResult;
7063
+ const resolved = candidate.resolved;
7064
+ if (!Array.isArray(resolved.passes)) return invalid("resolved.passes", resolved.passes);
7065
+ if (!Array.isArray(resolved.parameters))
7066
+ return invalid("resolved.parameters", resolved.parameters);
7067
+ if (resolved.values === null || typeof resolved.values !== "object" || Array.isArray(resolved.values))
7068
+ return invalid("resolved.values", resolved.values);
7069
+ let expectedLayerPlanIdentity;
7070
+ try {
7071
+ expectedLayerPlanIdentity = materialLayerPlanIdentity({
7072
+ resolved
7073
+ });
7074
+ } catch (error) {
7075
+ return invalid("resolved.layerPlanIdentity", error instanceof Error ? error.message : error);
7076
+ }
7077
+ if (expectedLayerPlanIdentity !== void 0 && receiptResult.value.derivedInterface.layerPlanIdentity !== expectedLayerPlanIdentity) {
7078
+ return invalid(
7079
+ "receipt.derivedInterface.layerPlanIdentity",
7080
+ receiptResult.value.derivedInterface.layerPlanIdentity
7081
+ );
7082
+ }
7035
7083
  if (candidate.artifactDigest !== void 0 && candidate.artifactDigest !== artifact.digest)
7036
7084
  return invalid("artifactDigest", candidate.artifactDigest);
7037
7085
  if (candidate.publicationGeneration !== void 0 && receiptResult.value.identity.cookGeneration !== candidate.publicationGeneration)
@@ -7095,12 +7143,146 @@ function packageVerification(input) {
7095
7143
  };
7096
7144
  }
7097
7145
 
7146
+ // src/errors.ts
7147
+ var PackError = class extends Error {
7148
+ code;
7149
+ expected;
7150
+ hint;
7151
+ detail;
7152
+ constructor(args) {
7153
+ super(`[PackError ${args.code}] expected: ${args.expected}; hint: ${args.hint}`);
7154
+ this.name = "PackError";
7155
+ this.code = args.code;
7156
+ this.expected = args.expected;
7157
+ this.hint = args.hint;
7158
+ this.detail = args.detail;
7159
+ }
7160
+ };
7161
+
7162
+ // src/guid.ts
7163
+ function brand(bytes) {
7164
+ return bytes;
7165
+ }
7166
+ var HEX_BYTE = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
7167
+ function bytesToDashForm(bytes) {
7168
+ const h = HEX_BYTE;
7169
+ return `${h[bytes[0]]}${h[bytes[1]]}${h[bytes[2]]}${h[bytes[3]]}-${h[bytes[4]]}${h[bytes[5]]}-${h[bytes[6]]}${h[bytes[7]]}-${h[bytes[8]]}${h[bytes[9]]}-${h[bytes[10]]}${h[bytes[11]]}${h[bytes[12]]}${h[bytes[13]]}${h[bytes[14]]}${h[bytes[15]]}`;
7170
+ }
7171
+ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
7172
+ var PACK_SOURCE_KEY_RE = /^[a-z0-9][a-z0-9._-]*(\/[a-z0-9][a-z0-9._-]*)*$/;
7173
+ function isValidPackSourceKey(value) {
7174
+ return typeof value === "string" && PACK_SOURCE_KEY_RE.test(value);
7175
+ }
7176
+ function isValidAssetGuidString(value) {
7177
+ return typeof value === "string" && UUID_RE.test(value);
7178
+ }
7179
+ function dashFormToBytes(dashForm) {
7180
+ const hex = dashForm.replace(/-/g, "");
7181
+ const bytes = new Uint8Array(16);
7182
+ for (let i = 0; i < 16; i++) {
7183
+ bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
7184
+ }
7185
+ return bytes;
7186
+ }
7187
+ function randomUuidBytes() {
7188
+ const uuid = uuidv7obj();
7189
+ const bytes = new Uint8Array(16);
7190
+ bytes.set(uuid.bytes);
7191
+ return bytes;
7192
+ }
7193
+ function packageId(value) {
7194
+ return value;
7195
+ }
7196
+ var PackageId = {
7197
+ parse(dashForm) {
7198
+ const parsed = AssetGuid.parse(dashForm);
7199
+ return parsed.ok ? { ok: true, value: packageId(parsed.value) } : parsed;
7200
+ },
7201
+ format(value) {
7202
+ return bytesToDashForm(value);
7203
+ },
7204
+ random() {
7205
+ return packageId(randomUuidBytes());
7206
+ }
7207
+ };
7208
+ function derivedGuid(namespace, sourceKey2) {
7209
+ if (!(namespace instanceof Uint8Array) || namespace.byteLength !== 16) {
7210
+ throw new TypeError("AssetGuid.derive requires a 16-byte PackageId");
7211
+ }
7212
+ if (!isValidPackSourceKey(sourceKey2)) {
7213
+ const error = new TypeError(
7214
+ `AssetGuid.derive received invalid sourceKey ${JSON.stringify(sourceKey2)}`
7215
+ );
7216
+ Object.defineProperty(error, "code", { value: "pack-source-key-invalid" });
7217
+ throw error;
7218
+ }
7219
+ const name = new TextEncoder().encode(sourceKey2);
7220
+ const input = new Uint8Array(namespace.byteLength + name.byteLength);
7221
+ input.set(namespace, 0);
7222
+ input.set(name, namespace.byteLength);
7223
+ const digest = sha1(input);
7224
+ const result = digest.slice(0, 16);
7225
+ result[6] = (result[6] ?? 0) & 15 | 80;
7226
+ result[8] = (result[8] ?? 0) & 63 | 128;
7227
+ return brand(result);
7228
+ }
7229
+ var AssetGuid = {
7230
+ /**
7231
+ * Parse a 36-char RFC 4122 dash-form UUID string into an AssetGuid.
7232
+ * Returns Ok(AssetGuid) on success or Err(PackError) with code 'pack-guid-malformed' on failure.
7233
+ * Never throws for expected failures (requirements §4.2 / §14 / charter proposition 4).
7234
+ */
7235
+ parse(dashForm) {
7236
+ if (!isValidAssetGuidString(dashForm)) {
7237
+ return {
7238
+ ok: false,
7239
+ error: new PackError({
7240
+ code: "pack-guid-malformed",
7241
+ expected: "36-char RFC 4122 dash-form UUID",
7242
+ hint: "use AssetGuid.random() or a UUIDv7 generator; all GUID fields must be 36-char RFC 4122 dash-form",
7243
+ detail: {
7244
+ raw: dashForm,
7245
+ reason: "expected 36-char RFC 4122 dash-form UUID"
7246
+ }
7247
+ })
7248
+ };
7249
+ }
7250
+ return { ok: true, value: brand(dashFormToBytes(dashForm)) };
7251
+ },
7252
+ /**
7253
+ * Format an AssetGuid as a 36-char RFC 4122 lowercase dash-form string.
7254
+ */
7255
+ format(guid) {
7256
+ return bytesToDashForm(guid);
7257
+ },
7258
+ /**
7259
+ * Test byte-by-byte equality between two AssetGuids.
7260
+ */
7261
+ equals(a, b) {
7262
+ for (let i = 0; i < 16; i++) {
7263
+ if (a[i] !== b[i]) return false;
7264
+ }
7265
+ return true;
7266
+ },
7267
+ /**
7268
+ * Mint a new time-ordered UUIDv7 as an AssetGuid.
7269
+ * Works in both Node.js and browser environments.
7270
+ */
7271
+ random() {
7272
+ return brand(randomUuidBytes());
7273
+ },
7274
+ /** Derive the stable UUIDv5 projection for one Pack subject and sourceKey. */
7275
+ derive(namespace, sourceKey2) {
7276
+ return derivedGuid(namespace, sourceKey2);
7277
+ }
7278
+ };
7279
+
7098
7280
  // src/mesh-bin-contract.ts
7099
7281
  var MESH_BIN_VERSION = 4;
7100
7282
  var MESH_BIN_PROJECTION_VERSION = 1;
7101
7283
  var MESH_BIN_HEADER_V4_BYTES = 80;
7102
7284
  var MESH_BIN_DIGEST_BYTES = 32;
7103
- function failure(code, sourceKey2, expected, actual2) {
7285
+ function failure(code, sourceKey2, expected, actual) {
7104
7286
  return {
7105
7287
  ok: false,
7106
7288
  error: {
@@ -7108,7 +7290,7 @@ function failure(code, sourceKey2, expected, actual2) {
7108
7290
  subject: "mesh-bin",
7109
7291
  sourceKey: sourceKey2,
7110
7292
  expected,
7111
- actual: actual2,
7293
+ actual,
7112
7294
  recovery: "re-cook the source with its Meta sidecar through the build-time importer"
7113
7295
  }
7114
7296
  };
@@ -7187,41 +7369,1033 @@ function decodeMeshBinHeader(bytes, sourceKey2 = "<unknown mesh source>") {
7187
7369
  }
7188
7370
  };
7189
7371
  }
7190
- function isRecord(value) {
7372
+ var PACK_PARAMETER_TYPES = [
7373
+ "bool",
7374
+ "u32",
7375
+ "i32",
7376
+ "f32",
7377
+ "f64",
7378
+ "string",
7379
+ "enum",
7380
+ "vec2",
7381
+ "vec3",
7382
+ "vec4",
7383
+ "color",
7384
+ "asset-guid"
7385
+ ];
7386
+ function authoringError(code, expected, hint, detail = {}, actual) {
7387
+ return {
7388
+ code,
7389
+ expected,
7390
+ hint,
7391
+ ...actual === void 0 ? {} : { actual },
7392
+ detail
7393
+ };
7394
+ }
7395
+ function failure2(error) {
7396
+ return err(error);
7397
+ }
7398
+ function isRecord(value) {
7399
+ return value !== null && typeof value === "object" && !Array.isArray(value);
7400
+ }
7401
+ function validateSceneComponents(value) {
7402
+ if (value === void 0) return ok(void 0);
7403
+ if (!Array.isArray(value)) {
7404
+ return failure2(
7405
+ parameterFailure(
7406
+ "$.sceneComponents",
7407
+ "an array of component schema records",
7408
+ value,
7409
+ "sceneComponents is not an array"
7410
+ )
7411
+ );
7412
+ }
7413
+ const components = [];
7414
+ const names = /* @__PURE__ */ new Set();
7415
+ for (const [componentIndex, candidate] of value.entries()) {
7416
+ if (!isRecord(candidate) || typeof candidate.name !== "string" || !isRecord(candidate.fields)) {
7417
+ return failure2(
7418
+ parameterFailure(
7419
+ `$.sceneComponents[${componentIndex}]`,
7420
+ "a component record with name and fields",
7421
+ candidate,
7422
+ "scene component schema is malformed"
7423
+ )
7424
+ );
7425
+ }
7426
+ if (candidate.name.length === 0 || names.has(candidate.name)) {
7427
+ return failure2(
7428
+ parameterFailure(
7429
+ `$.sceneComponents[${componentIndex}].name`,
7430
+ "a non-empty unique component name",
7431
+ candidate.name,
7432
+ "scene component names must be unique"
7433
+ )
7434
+ );
7435
+ }
7436
+ names.add(candidate.name);
7437
+ const fields = {};
7438
+ for (const [fieldName, field] of Object.entries(candidate.fields)) {
7439
+ if (typeof field === "string" && field.length === 0 || typeof field !== "string" && (!isRecord(field) || typeof field.type !== "string" || field.type.length === 0)) {
7440
+ return failure2(
7441
+ parameterFailure(
7442
+ `$.sceneComponents[${componentIndex}].fields.${fieldName}`,
7443
+ "a field type string or { type: string }",
7444
+ field,
7445
+ "scene component field schema is malformed"
7446
+ )
7447
+ );
7448
+ }
7449
+ fields[fieldName] = field;
7450
+ }
7451
+ components.push({ name: candidate.name, fields });
7452
+ }
7453
+ return ok(components);
7454
+ }
7455
+ function isPackageId(value) {
7456
+ return value instanceof Uint8Array && value.byteLength === 16;
7457
+ }
7458
+ function cloneValue(value) {
7459
+ if (value instanceof Uint8Array) return value.slice();
7460
+ if (Array.isArray(value)) return value.map((item) => cloneValue(item));
7461
+ return value;
7462
+ }
7463
+ function sourceKeyFailure(sourceKey2, propertyPath = "$.sourceKey") {
7464
+ return authoringError(
7465
+ "pack-source-key-invalid",
7466
+ "a sourceKey matching ^[a-z0-9][a-z0-9._-]*(/[a-z0-9][a-z0-9._-]*)*$",
7467
+ "use a stable lower-case semantic key; do not derive it from file paths or output order",
7468
+ { propertyPath, sourceKey: sourceKey2 },
7469
+ typeof sourceKey2 === "string" ? sourceKey2 : void 0
7470
+ );
7471
+ }
7472
+ function parameterFailure(propertyPath, expected, actual, reason) {
7473
+ return authoringError(
7474
+ "pack-parameter-invalid",
7475
+ expected,
7476
+ "repair the parameter declaration or the instance values, then inspect and rebuild",
7477
+ { propertyPath, reason, actual: typeof actual === "string" ? actual : JSON.stringify(actual) }
7478
+ );
7479
+ }
7480
+ function numericType(type) {
7481
+ return type === "u32" || type === "i32" || type === "f32" || type === "f64";
7482
+ }
7483
+ function vectorLength(type) {
7484
+ switch (type) {
7485
+ case "vec2":
7486
+ return 2;
7487
+ case "vec3":
7488
+ return 3;
7489
+ case "vec4":
7490
+ case "color":
7491
+ return 4;
7492
+ default:
7493
+ return void 0;
7494
+ }
7495
+ }
7496
+ function parameterValueError(parameter, value, propertyPath) {
7497
+ const { type } = parameter;
7498
+ if (type === "bool" && typeof value !== "boolean") {
7499
+ return parameterFailure(propertyPath, "a boolean", value, "bool value has the wrong type");
7500
+ }
7501
+ if (numericType(type)) {
7502
+ if (typeof value !== "number" || !Number.isFinite(value)) {
7503
+ return parameterFailure(
7504
+ propertyPath,
7505
+ "a finite number",
7506
+ value,
7507
+ "numeric value is not finite"
7508
+ );
7509
+ }
7510
+ if ((type === "u32" || type === "i32") && !Number.isInteger(value)) {
7511
+ return parameterFailure(
7512
+ propertyPath,
7513
+ "an integer",
7514
+ value,
7515
+ "integer parameter received a fraction"
7516
+ );
7517
+ }
7518
+ if (type === "u32" && (value < 0 || value > 4294967295)) {
7519
+ return parameterFailure(
7520
+ propertyPath,
7521
+ "an unsigned 32-bit integer",
7522
+ value,
7523
+ "u32 value is outside [0, 2^32 - 1]"
7524
+ );
7525
+ }
7526
+ if (type === "i32" && (value < -2147483648 || value > 2147483647)) {
7527
+ return parameterFailure(
7528
+ propertyPath,
7529
+ "a signed 32-bit integer",
7530
+ value,
7531
+ "i32 value is outside [-2^31, 2^31 - 1]"
7532
+ );
7533
+ }
7534
+ if (type === "f32" && !Number.isFinite(Math.fround(value))) {
7535
+ return parameterFailure(
7536
+ propertyPath,
7537
+ "a finite IEEE-754 32-bit float",
7538
+ value,
7539
+ "f32 value overflows binary32"
7540
+ );
7541
+ }
7542
+ if (parameter.minimum !== void 0 && value < parameter.minimum) {
7543
+ return parameterFailure(
7544
+ propertyPath,
7545
+ `a number >= ${parameter.minimum}`,
7546
+ value,
7547
+ "value is below minimum"
7548
+ );
7549
+ }
7550
+ if (parameter.maximum !== void 0 && value > parameter.maximum) {
7551
+ return parameterFailure(
7552
+ propertyPath,
7553
+ `a number <= ${parameter.maximum}`,
7554
+ value,
7555
+ "value is above maximum"
7556
+ );
7557
+ }
7558
+ return void 0;
7559
+ }
7560
+ if (type === "string" && typeof value !== "string") {
7561
+ return parameterFailure(propertyPath, "a string", value, "string parameter has the wrong type");
7562
+ }
7563
+ if (type === "enum") {
7564
+ if (typeof value !== "string") {
7565
+ return parameterFailure(
7566
+ propertyPath,
7567
+ "one of the declared enum strings",
7568
+ value,
7569
+ "enum value has the wrong type"
7570
+ );
7571
+ }
7572
+ if (parameter.values === void 0 || !parameter.values.includes(value)) {
7573
+ return parameterFailure(
7574
+ propertyPath,
7575
+ "one of the declared enum values",
7576
+ value,
7577
+ "enum value is not declared"
7578
+ );
7579
+ }
7580
+ return void 0;
7581
+ }
7582
+ const length = vectorLength(type);
7583
+ if (length !== void 0) {
7584
+ if (!Array.isArray(value) || value.length !== length || value.some((component) => typeof component !== "number" || !Number.isFinite(component))) {
7585
+ return parameterFailure(
7586
+ propertyPath,
7587
+ `a finite numeric vector with ${length} components`,
7588
+ value,
7589
+ "vector value has the wrong shape"
7590
+ );
7591
+ }
7592
+ if (type === "color" && value.some((component) => component < 0 || component > 1)) {
7593
+ return parameterFailure(
7594
+ propertyPath,
7595
+ "an RGBA color with components in [0, 1]",
7596
+ value,
7597
+ "color component is outside [0, 1]"
7598
+ );
7599
+ }
7600
+ return void 0;
7601
+ }
7602
+ if (type === "asset-guid") {
7603
+ const validString = typeof value === "string" && isValidAssetGuidString(value);
7604
+ if (!(value instanceof Uint8Array && value.byteLength === 16) && !validString) {
7605
+ return parameterFailure(
7606
+ propertyPath,
7607
+ "a 16-byte AssetGuid or UUID string",
7608
+ value,
7609
+ "asset GUID value is malformed"
7610
+ );
7611
+ }
7612
+ return void 0;
7613
+ }
7614
+ return parameterFailure(
7615
+ propertyPath,
7616
+ "a supported Pack parameter type",
7617
+ value,
7618
+ "unknown parameter type"
7619
+ );
7620
+ }
7621
+ function normalizeParameterValue(parameter, value, propertyPath) {
7622
+ const error = parameterValueError(parameter, value, propertyPath);
7623
+ if (error !== void 0) return failure2(error);
7624
+ if (parameter.type === "asset-guid" && typeof value === "string") {
7625
+ const parsed = AssetGuid.parse(value);
7626
+ if (!parsed.ok) {
7627
+ return failure2(
7628
+ parameterFailure(
7629
+ propertyPath,
7630
+ "a valid AssetGuid UUID string",
7631
+ value,
7632
+ "asset GUID parser rejected the value"
7633
+ )
7634
+ );
7635
+ }
7636
+ return ok(parsed.value);
7637
+ }
7638
+ return ok(cloneValue(value));
7639
+ }
7640
+ function validateParameterDefinitions(parameters, propertyPath = "$.parameters") {
7641
+ if (!Array.isArray(parameters) || parameters.length === 0) {
7642
+ return failure2(
7643
+ parameterFailure(
7644
+ propertyPath,
7645
+ "a non-empty parameter descriptor array",
7646
+ parameters,
7647
+ "parameters must be explicit and non-empty"
7648
+ )
7649
+ );
7650
+ }
7651
+ const names = /* @__PURE__ */ new Set();
7652
+ const normalized = [];
7653
+ for (const [index, candidate] of parameters.entries()) {
7654
+ const path = `${propertyPath}[${index}]`;
7655
+ if (!isRecord(candidate))
7656
+ return failure2(
7657
+ parameterFailure(
7658
+ path,
7659
+ "a parameter descriptor object",
7660
+ candidate,
7661
+ "descriptor is not an object"
7662
+ )
7663
+ );
7664
+ const name = candidate.name;
7665
+ if (typeof name !== "string" || !/^[A-Za-z][A-Za-z0-9_.-]*$/.test(name)) {
7666
+ return failure2(
7667
+ parameterFailure(
7668
+ `${path}.name`,
7669
+ "a unique identifier-like parameter name",
7670
+ name,
7671
+ "parameter name is invalid"
7672
+ )
7673
+ );
7674
+ }
7675
+ if (names.has(name))
7676
+ return failure2(
7677
+ parameterFailure(
7678
+ `${path}.name`,
7679
+ "a unique parameter name",
7680
+ name,
7681
+ "parameter name is duplicated"
7682
+ )
7683
+ );
7684
+ names.add(name);
7685
+ const unknown = Object.keys(candidate).find(
7686
+ (key) => !["name", "type", "default", "minimum", "maximum", "values", "kind"].includes(key)
7687
+ );
7688
+ if (unknown !== void 0) {
7689
+ return failure2(
7690
+ parameterFailure(
7691
+ `${path}.${unknown}`,
7692
+ "only name, type, default, minimum, maximum, values, and kind fields",
7693
+ candidate[unknown],
7694
+ "parameter descriptors are a closed authoring schema"
7695
+ )
7696
+ );
7697
+ }
7698
+ const type = candidate.type;
7699
+ if (typeof type !== "string" || !PACK_PARAMETER_TYPES.includes(type)) {
7700
+ return failure2(
7701
+ parameterFailure(
7702
+ `${path}.type`,
7703
+ PACK_PARAMETER_TYPES.join(" | "),
7704
+ type,
7705
+ "parameter type is not supported"
7706
+ )
7707
+ );
7708
+ }
7709
+ const typed = {
7710
+ ...candidate,
7711
+ name,
7712
+ type
7713
+ };
7714
+ if (typed.values !== void 0) {
7715
+ if (typed.type !== "enum" || !Array.isArray(typed.values) || typed.values.length === 0 || typed.values.some((item) => typeof item !== "string") || new Set(typed.values).size !== typed.values.length) {
7716
+ return failure2(
7717
+ parameterFailure(
7718
+ `${path}.values`,
7719
+ "unique non-empty strings for enum",
7720
+ typed.values,
7721
+ "enum values are malformed"
7722
+ )
7723
+ );
7724
+ }
7725
+ } else if (typed.type === "enum") {
7726
+ return failure2(
7727
+ parameterFailure(
7728
+ `${path}.values`,
7729
+ "a non-empty enum choices array",
7730
+ typed.values,
7731
+ "enum has no choices"
7732
+ )
7733
+ );
7734
+ }
7735
+ if (typed.kind !== void 0 && (typed.type !== "asset-guid" || typeof typed.kind !== "string")) {
7736
+ return failure2(
7737
+ parameterFailure(
7738
+ `${path}.kind`,
7739
+ "a kind constraint only on asset-guid parameters",
7740
+ typed.kind,
7741
+ "kind is misplaced"
7742
+ )
7743
+ );
7744
+ }
7745
+ for (const field of ["minimum", "maximum"]) {
7746
+ const bound = typed[field];
7747
+ if (bound !== void 0 && (typeof bound !== "number" || !Number.isFinite(bound))) {
7748
+ return failure2(
7749
+ parameterFailure(
7750
+ `${path}.${field}`,
7751
+ "a finite numeric bound",
7752
+ bound,
7753
+ "numeric bound is invalid"
7754
+ )
7755
+ );
7756
+ }
7757
+ }
7758
+ if (!numericType(typed.type) && (typed.minimum !== void 0 || typed.maximum !== void 0)) {
7759
+ return failure2(
7760
+ parameterFailure(
7761
+ path,
7762
+ "minimum/maximum only on numeric parameters",
7763
+ typed,
7764
+ "numeric bounds are not meaningful for this parameter type"
7765
+ )
7766
+ );
7767
+ }
7768
+ if (typed.minimum !== void 0 && typed.maximum !== void 0 && typed.minimum > typed.maximum) {
7769
+ return failure2(
7770
+ parameterFailure(path, "minimum <= maximum", typed, "numeric bounds are reversed")
7771
+ );
7772
+ }
7773
+ const defaultResult = normalizeParameterValue(typed, typed.default, `${path}.default`);
7774
+ if (!defaultResult.ok) return defaultResult;
7775
+ normalized.push({
7776
+ ...typed,
7777
+ default: defaultResult.value,
7778
+ ...typed.values === void 0 ? {} : { values: Object.freeze([...typed.values]) }
7779
+ });
7780
+ }
7781
+ return ok(Object.freeze(normalized));
7782
+ }
7783
+ function definePackageId(value) {
7784
+ if (isPackageId(value)) return value.slice();
7785
+ const parsed = PackageId.parse(value);
7786
+ if (!parsed.ok) {
7787
+ const error = authoringError(
7788
+ "pack-package-id-invalid",
7789
+ "a 36-character RFC 4122 UUID packageId",
7790
+ "use PackageId.random() or repair the packageId literal before loading the Pack",
7791
+ { value },
7792
+ value
7793
+ );
7794
+ throw Object.assign(new TypeError(error.hint), error);
7795
+ }
7796
+ return parsed.value;
7797
+ }
7798
+ function cloneDefinition(definition) {
7799
+ const parameters = "parameters" in definition ? Object.freeze(
7800
+ definition.parameters.map(
7801
+ (parameter) => Object.freeze({
7802
+ ...parameter,
7803
+ default: cloneValue(parameter.default),
7804
+ ...parameter.values === void 0 ? {} : { values: Object.freeze(parameter.values.map((value) => cloneValue(value))) }
7805
+ })
7806
+ )
7807
+ ) : void 0;
7808
+ const sceneComponents = definition.sceneComponents === void 0 ? void 0 : Object.freeze(
7809
+ definition.sceneComponents.map(
7810
+ (component) => Object.freeze({
7811
+ name: component.name,
7812
+ fields: Object.freeze({ ...component.fields })
7813
+ })
7814
+ )
7815
+ );
7816
+ return Object.freeze({
7817
+ ...definition,
7818
+ packageId: definition.packageId.slice(),
7819
+ ...parameters === void 0 ? {} : { parameters },
7820
+ ...sceneComponents === void 0 ? {} : { sceneComponents }
7821
+ });
7822
+ }
7823
+ function definePack(definition) {
7824
+ const validated = validatePackDefinition(definition);
7825
+ if (!validated.ok) throw Object.assign(new TypeError(validated.error.hint), validated.error);
7826
+ return cloneDefinition(
7827
+ validated.value
7828
+ );
7829
+ }
7830
+ function projectScriptablePackMeta(definition, sourcePath) {
7831
+ return {
7832
+ schemaVersion: "2.0.0",
7833
+ kind: "scriptable-pack-source",
7834
+ packageId: PackageId.format(definition.packageId),
7835
+ source: sourcePath,
7836
+ ..."parameters" in definition ? {
7837
+ parameters: definition.parameters.map((parameter) => ({
7838
+ name: parameter.name,
7839
+ type: parameter.type,
7840
+ default: jsonParameterValue(parameter.default),
7841
+ ...parameter.minimum === void 0 ? {} : { minimum: parameter.minimum },
7842
+ ...parameter.maximum === void 0 ? {} : { maximum: parameter.maximum },
7843
+ ...parameter.values === void 0 ? {} : { values: parameter.values },
7844
+ ...parameter.kind === void 0 ? {} : { kind: parameter.kind }
7845
+ }))
7846
+ } : {}
7847
+ };
7848
+ }
7849
+ function jsonParameterValue(value) {
7850
+ return value instanceof Uint8Array ? AssetGuid.format(value) : value;
7851
+ }
7852
+ function validatePackDefinition(value, sourcePath) {
7853
+ if (!isRecord(value))
7854
+ return failure2(
7855
+ parameterFailure("$", "a Pack definition object", value, "definition is not an object")
7856
+ );
7857
+ const unknown = Object.keys(value).find(
7858
+ (key) => !["schemaVersion", "packageId", "name", "parameters", "sceneComponents", "build"].includes(
7859
+ key
7860
+ )
7861
+ );
7862
+ if (unknown !== void 0) {
7863
+ return failure2(
7864
+ parameterFailure(
7865
+ `$.${unknown}`,
7866
+ "only schemaVersion, packageId, name, parameters, sceneComponents, and build fields",
7867
+ value[unknown],
7868
+ "legacy static output declarations and external asset tables are not part of v2 authoring"
7869
+ )
7870
+ );
7871
+ }
7872
+ if (value.schemaVersion !== "2.0.0") {
7873
+ return failure2(
7874
+ parameterFailure(
7875
+ "$.schemaVersion",
7876
+ "the literal '2.0.0'",
7877
+ value.schemaVersion,
7878
+ "authoring source schema is unsupported"
7879
+ )
7880
+ );
7881
+ }
7882
+ if (!isPackageId(value.packageId)) {
7883
+ return failure2(
7884
+ authoringError(
7885
+ "pack-package-id-invalid",
7886
+ "a 16-byte PackageId",
7887
+ "use definePackageId() for the stable source identity",
7888
+ { sourcePath, propertyPath: "$.packageId" },
7889
+ typeof value.packageId === "string" ? value.packageId : void 0
7890
+ )
7891
+ );
7892
+ }
7893
+ if (value.name !== void 0 && typeof value.name !== "string") {
7894
+ return failure2(
7895
+ parameterFailure("$.name", "a string when present", value.name, "display name is malformed")
7896
+ );
7897
+ }
7898
+ if (typeof value.build !== "function") {
7899
+ return failure2(
7900
+ parameterFailure("$.build", "a build function", value.build, "build is not callable")
7901
+ );
7902
+ }
7903
+ const sceneComponents = validateSceneComponents(value.sceneComponents);
7904
+ if (!sceneComponents.ok) return sceneComponents;
7905
+ const hasParameters = Object.hasOwn(value, "parameters");
7906
+ if (!hasParameters) {
7907
+ return ok(
7908
+ Object.freeze({
7909
+ schemaVersion: "2.0.0",
7910
+ packageId: value.packageId,
7911
+ ...value.name === void 0 ? {} : { name: value.name },
7912
+ ...sceneComponents.value === void 0 ? {} : { sceneComponents: sceneComponents.value },
7913
+ build: value.build
7914
+ })
7915
+ );
7916
+ }
7917
+ const parameters = validateParameterDefinitions(value.parameters);
7918
+ if (!parameters.ok) return parameters;
7919
+ return ok(
7920
+ Object.freeze({
7921
+ schemaVersion: "2.0.0",
7922
+ packageId: value.packageId,
7923
+ ...value.name === void 0 ? {} : { name: value.name },
7924
+ ...sceneComponents.value === void 0 ? {} : { sceneComponents: sceneComponents.value },
7925
+ parameters: parameters.value,
7926
+ build: value.build
7927
+ })
7928
+ );
7929
+ }
7930
+ function hasPackParameters(value) {
7931
+ return isRecord(value) && Array.isArray(value.parameters) && value.parameters.length > 0;
7932
+ }
7933
+ function resolvePackParameterValues(definition, overrides = {}, inheritedValues) {
7934
+ if (!isRecord(overrides)) {
7935
+ return failure2(
7936
+ parameterFailure(
7937
+ "$.values",
7938
+ "an object of sparse parameter overrides",
7939
+ overrides,
7940
+ "values is not an object"
7941
+ )
7942
+ );
7943
+ }
7944
+ const descriptors = new Map(
7945
+ definition.parameters.map((parameter) => [parameter.name, parameter])
7946
+ );
7947
+ for (const name of Object.keys(overrides)) {
7948
+ if (!descriptors.has(name)) {
7949
+ return failure2(
7950
+ parameterFailure(
7951
+ `$.values.${name}`,
7952
+ "a declared parameter name",
7953
+ name,
7954
+ "instance contains an unknown parameter"
7955
+ )
7956
+ );
7957
+ }
7958
+ }
7959
+ const values = {};
7960
+ for (const parameter of definition.parameters) {
7961
+ const raw = Object.hasOwn(overrides, parameter.name) ? overrides[parameter.name] : inheritedValues?.[parameter.name] ?? parameter.default;
7962
+ const normalized = normalizeParameterValue(parameter, raw, `$.values.${parameter.name}`);
7963
+ if (!normalized.ok) return normalized;
7964
+ values[parameter.name] = normalized.value;
7965
+ }
7966
+ return ok(Object.freeze(values));
7967
+ }
7968
+ function jsonError(propertyPath, expected, actual, reason) {
7969
+ return failure2(
7970
+ authoringError(
7971
+ "pack-parameter-invalid",
7972
+ expected,
7973
+ "repair the v3 pack.json authoring data, then rerun scan or rebuild",
7974
+ {
7975
+ propertyPath,
7976
+ reason,
7977
+ actual: typeof actual === "string" ? actual : JSON.stringify(actual)
7978
+ }
7979
+ )
7980
+ );
7981
+ }
7982
+ function parsePackageId(value, propertyPath) {
7983
+ if (typeof value !== "string") {
7984
+ return failure2(
7985
+ authoringError(
7986
+ "pack-package-id-invalid",
7987
+ "a UUID string",
7988
+ "repair packageId in the authoring file",
7989
+ { propertyPath, value }
7990
+ )
7991
+ );
7992
+ }
7993
+ const parsed = PackageId.parse(value);
7994
+ if (!parsed.ok) {
7995
+ return failure2(
7996
+ authoringError(
7997
+ "pack-package-id-invalid",
7998
+ "a 36-character RFC 4122 UUID",
7999
+ "repair packageId or use the authoring gateway to mint one",
8000
+ { propertyPath, value },
8001
+ value
8002
+ )
8003
+ );
8004
+ }
8005
+ return ok(parsed.value);
8006
+ }
8007
+ function parsePackJsonAsset(value, sourceKey2) {
8008
+ if (!isRecord(value))
8009
+ return jsonError(
8010
+ `$.assets.${sourceKey2}`,
8011
+ "an asset entry object",
8012
+ value,
8013
+ "asset entry is not an object"
8014
+ );
8015
+ const allowed = /* @__PURE__ */ new Set(["kind", "payload", "refs", "name", "artifacts"]);
8016
+ const unknown = Object.keys(value).find((key) => !allowed.has(key));
8017
+ if (unknown !== void 0)
8018
+ return jsonError(
8019
+ `$.assets.${sourceKey2}.${unknown}`,
8020
+ "no GUID or extra authoring field",
8021
+ value[unknown],
8022
+ "direct v3 entries derive identity from their object key"
8023
+ );
8024
+ if (typeof value.kind !== "string" || value.kind.length === 0)
8025
+ return jsonError(
8026
+ `$.assets.${sourceKey2}.kind`,
8027
+ "a non-empty asset kind",
8028
+ value.kind,
8029
+ "asset kind is missing"
8030
+ );
8031
+ if (!isRecord(value.payload))
8032
+ return jsonError(
8033
+ `$.assets.${sourceKey2}.payload`,
8034
+ "a JSON object payload",
8035
+ value.payload,
8036
+ "payload must be a plain object"
8037
+ );
8038
+ if (!Array.isArray(value.refs) || value.refs.some((ref) => typeof ref !== "string" || !isValidAssetGuidString(ref))) {
8039
+ return jsonError(
8040
+ `$.assets.${sourceKey2}.refs`,
8041
+ "an array of UUID references",
8042
+ value.refs,
8043
+ "references must already be real AssetGuids"
8044
+ );
8045
+ }
8046
+ if (value.name !== void 0 && (typeof value.name !== "string" || value.name.length === 0))
8047
+ return jsonError(
8048
+ `$.assets.${sourceKey2}.name`,
8049
+ "a non-empty display name when present",
8050
+ value.name,
8051
+ "asset name is malformed"
8052
+ );
8053
+ if (value.artifacts !== void 0 && !isRecord(value.artifacts))
8054
+ return jsonError(
8055
+ `$.assets.${sourceKey2}.artifacts`,
8056
+ "an artifact descriptor object when present",
8057
+ value.artifacts,
8058
+ "artifacts are not an object"
8059
+ );
8060
+ const base = {
8061
+ kind: value.kind,
8062
+ payload: value.payload,
8063
+ refs: Object.freeze([...value.refs]),
8064
+ ...value.name === void 0 ? {} : { name: value.name }
8065
+ };
8066
+ if (value.artifacts === void 0) return ok(base);
8067
+ const withArtifacts = {
8068
+ ...base,
8069
+ artifacts: value.artifacts
8070
+ };
8071
+ return ok(withArtifacts);
8072
+ }
8073
+ function parsePackSourceJson(value) {
8074
+ if (!isRecord(value))
8075
+ return jsonError("$", "a v3 pack.json object", value, "document is not an object");
8076
+ if (value.schemaVersion !== "3.0.0")
8077
+ return jsonError(
8078
+ "$.schemaVersion",
8079
+ "the literal '3.0.0'",
8080
+ value.schemaVersion,
8081
+ "document schema is not v3"
8082
+ );
8083
+ const unknown = Object.keys(value).find(
8084
+ (key) => !["schemaVersion", "packageId", "assets", "parent", "values"].includes(key)
8085
+ );
8086
+ if (unknown !== void 0)
8087
+ return jsonError(
8088
+ `$.${unknown}`,
8089
+ "no extra top-level authoring fields",
8090
+ value[unknown],
8091
+ "keep the v3 document to packageId+assets or packageId+parent+values"
8092
+ );
8093
+ const packageResult = parsePackageId(value.packageId, "$.packageId");
8094
+ if (!packageResult.ok) return packageResult;
8095
+ const hasAssets = Object.hasOwn(value, "assets");
8096
+ const hasParent = Object.hasOwn(value, "parent");
8097
+ const hasValues = Object.hasOwn(value, "values");
8098
+ if (hasAssets && (hasParent || hasValues))
8099
+ return jsonError(
8100
+ "$",
8101
+ "assets or parent+values, never both",
8102
+ value,
8103
+ "direct and instance branches are mutually exclusive"
8104
+ );
8105
+ if (hasAssets) {
8106
+ if (!isRecord(value.assets))
8107
+ return jsonError(
8108
+ "$.assets",
8109
+ "a sourceKey to asset object",
8110
+ value.assets,
8111
+ "direct assets are not an object"
8112
+ );
8113
+ const assets = {};
8114
+ for (const [sourceKey2, entry] of Object.entries(value.assets)) {
8115
+ if (!isValidPackSourceKey(sourceKey2))
8116
+ return failure2(sourceKeyFailure(sourceKey2, `$.assets.${sourceKey2}`));
8117
+ const parsed = parsePackJsonAsset(entry, sourceKey2);
8118
+ if (!parsed.ok) return parsed;
8119
+ assets[sourceKey2] = parsed.value;
8120
+ }
8121
+ return ok({
8122
+ format: "direct",
8123
+ schemaVersion: "3.0.0",
8124
+ packageId: packageResult.value,
8125
+ assets: Object.freeze(assets)
8126
+ });
8127
+ }
8128
+ if (!hasParent || !hasValues || hasAssets)
8129
+ return jsonError(
8130
+ "$",
8131
+ "parent and values for an instance document",
8132
+ value,
8133
+ "instance branch is incomplete"
8134
+ );
8135
+ const parentResult = parsePackageId(value.parent, "$.parent");
8136
+ if (!parentResult.ok) return parentResult;
8137
+ if (!isRecord(value.values))
8138
+ return jsonError(
8139
+ "$.values",
8140
+ "a sparse parameter object",
8141
+ value.values,
8142
+ "instance values are not an object"
8143
+ );
8144
+ return ok({
8145
+ format: "instance",
8146
+ schemaVersion: "3.0.0",
8147
+ packageId: packageResult.value,
8148
+ parent: parentResult.value,
8149
+ values: Object.freeze({ ...value.values })
8150
+ });
8151
+ }
8152
+ function projectDirectPackJson(value) {
8153
+ const parsed = "format" in value ? ok(value) : parsePackSourceJson(value);
8154
+ if (!parsed.ok) return parsed;
8155
+ if (parsed.value.format !== "direct") {
8156
+ return failure2(
8157
+ authoringError(
8158
+ "pack-parameter-invalid",
8159
+ "a direct v3 pack.json",
8160
+ "projectDirectPackJson accepts the direct branch only",
8161
+ { observed: parsed.value.format }
8162
+ )
8163
+ );
8164
+ }
8165
+ const assets = [];
8166
+ for (const [sourceKey2, entry] of Object.entries(parsed.value.assets).sort(
8167
+ ([left], [right]) => left.localeCompare(right)
8168
+ )) {
8169
+ assets.push({
8170
+ ...entry,
8171
+ guid: AssetGuid.format(AssetGuid.derive(parsed.value.packageId, sourceKey2)),
8172
+ sourceKey: sourceKey2
8173
+ });
8174
+ }
8175
+ return ok({ packageId: PackageId.format(parsed.value.packageId), assets: Object.freeze(assets) });
8176
+ }
8177
+ function subjectId(subject) {
8178
+ return PackageId.format(subject.packageId).toLowerCase();
8179
+ }
8180
+ async function resolvePackParameterInheritance(subject, readParent) {
8181
+ const visited = /* @__PURE__ */ new Set();
8182
+ async function visit(current, path) {
8183
+ const currentId = subjectId(current);
8184
+ if (visited.has(currentId) || path.includes(currentId)) {
8185
+ return failure2(
8186
+ authoringError(
8187
+ "pack-parent-cycle",
8188
+ "a finite acyclic Pack parent chain",
8189
+ "inspect parentChain and repair the first repeated packageId",
8190
+ { packageId: currentId, parentChain: [...path, currentId] }
8191
+ )
8192
+ );
8193
+ }
8194
+ visited.add(currentId);
8195
+ const nextPath = [...path, currentId];
8196
+ if (current.format === "direct") {
8197
+ return failure2(
8198
+ authoringError(
8199
+ "pack-parent-has-no-parameters",
8200
+ "a ScriptablePack source with parameters as the parent",
8201
+ "direct packs cannot be instance parents; point the instance at a ScriptablePack source with parameters",
8202
+ { packageId: currentId }
8203
+ )
8204
+ );
8205
+ }
8206
+ if (current.format === "source") {
8207
+ const descriptors2 = validateParameterDefinitions(current.parameters, "$.parameters");
8208
+ if (!descriptors2.ok) return descriptors2;
8209
+ if (descriptors2.value.length === 0) {
8210
+ return failure2(
8211
+ authoringError(
8212
+ "pack-parent-has-no-parameters",
8213
+ "the parent source to declare a non-empty parameter list",
8214
+ "use clone for an independent zero-parameter Pack instead of creating an empty instance",
8215
+ { packageId: currentId }
8216
+ )
8217
+ );
8218
+ }
8219
+ const definition2 = {
8220
+ packageId: current.packageId,
8221
+ parameters: descriptors2.value};
8222
+ const values2 = resolvePackParameterValues(definition2);
8223
+ if (!values2.ok) return values2;
8224
+ return ok({
8225
+ packageId: current.packageId,
8226
+ rootPackageId: current.packageId,
8227
+ values: values2.value,
8228
+ parentChain: [],
8229
+ parameters: descriptors2.value
8230
+ });
8231
+ }
8232
+ const parent = await readParent(current.parent);
8233
+ if (parent === void 0) {
8234
+ return failure2(
8235
+ authoringError(
8236
+ "pack-parent-not-found",
8237
+ "the parent packageId to resolve in the source index",
8238
+ "inspect the parent locator or recreate the instance from a live ScriptablePack with parameters",
8239
+ { packageId: currentId, parent: PackageId.format(current.parent) }
8240
+ )
8241
+ );
8242
+ }
8243
+ if (PackageId.format(parent.packageId).toLowerCase() !== PackageId.format(current.parent).toLowerCase()) {
8244
+ return failure2(
8245
+ authoringError(
8246
+ "pack-parent-not-found",
8247
+ "the parent reader to return the requested packageId",
8248
+ "repair the Source Index locator and retry inheritance resolution",
8249
+ {
8250
+ packageId: currentId,
8251
+ requestedParent: PackageId.format(current.parent),
8252
+ observedParent: PackageId.format(parent.packageId)
8253
+ }
8254
+ )
8255
+ );
8256
+ }
8257
+ const resolvedParent = await visit(parent, nextPath);
8258
+ if (!resolvedParent.ok) return resolvedParent;
8259
+ const descriptors = resolvedParent.value.parameters;
8260
+ const definition = {
8261
+ packageId: resolvedParent.value.rootPackageId,
8262
+ parameters: descriptors};
8263
+ const values = resolvePackParameterValues(
8264
+ definition,
8265
+ current.values,
8266
+ resolvedParent.value.values
8267
+ );
8268
+ if (!values.ok) return values;
8269
+ return ok({
8270
+ packageId: current.packageId,
8271
+ rootPackageId: resolvedParent.value.rootPackageId,
8272
+ values: values.value,
8273
+ parentChain: [PackageId.format(current.parent), ...resolvedParent.value.parentChain],
8274
+ parameters: descriptors
8275
+ });
8276
+ }
8277
+ return visit(subject, []);
8278
+ }
8279
+ var resolvePackInheritance = resolvePackParameterInheritance;
8280
+ var PACK_AUTHORING_OPERATION_IDS = [
8281
+ "asset.list",
8282
+ "asset.inspect",
8283
+ "asset.resolve",
8284
+ "asset.verify",
8285
+ "asset-source.create",
8286
+ "asset-source.clone",
8287
+ "asset-source.create-instance",
8288
+ "asset-source.apply-values",
8289
+ "asset-source.rebuild",
8290
+ "asset-source.cold-cook"
8291
+ ];
8292
+ function createPackAuthoringGateway(port) {
8293
+ const requests = /* @__PURE__ */ new Map();
8294
+ return {
8295
+ execute(operation) {
8296
+ if (typeof operation.requestId !== "string" || operation.requestId.trim().length === 0) {
8297
+ return Promise.resolve(
8298
+ failure2(
8299
+ authoringError(
8300
+ "pack-source-revision-conflict",
8301
+ "a non-empty caller-minted requestId",
8302
+ "mint a new requestId and retry",
8303
+ { requestId: operation.requestId }
8304
+ )
8305
+ )
8306
+ );
8307
+ }
8308
+ let fingerprint;
8309
+ try {
8310
+ fingerprint = JSON.stringify(operation);
8311
+ } catch (cause) {
8312
+ return Promise.resolve(
8313
+ failure2(
8314
+ authoringError(
8315
+ "pack-parameter-invalid",
8316
+ "a JSON-serialisable authoring operation",
8317
+ "remove non-serialisable operation fields and retry with a new requestId",
8318
+ {
8319
+ requestId: operation.requestId,
8320
+ cause: cause instanceof Error ? cause.message : String(cause)
8321
+ }
8322
+ )
8323
+ )
8324
+ );
8325
+ }
8326
+ const previous = requests.get(operation.requestId);
8327
+ if (previous !== void 0) {
8328
+ if (previous.fingerprint === fingerprint) return previous.result;
8329
+ return Promise.resolve(
8330
+ failure2(
8331
+ authoringError(
8332
+ "pack-source-revision-conflict",
8333
+ "one immutable operation per requestId",
8334
+ "read the original result or mint a new requestId",
8335
+ { requestId: operation.requestId }
8336
+ )
8337
+ )
8338
+ );
8339
+ }
8340
+ const result = Promise.resolve().then(() => port.execute(operation)).catch(
8341
+ (cause) => failure2(
8342
+ authoringError(
8343
+ "pack-parameter-invalid",
8344
+ "the Pack authoring port to return a structured Result",
8345
+ "repair the gateway port failure, then retry with a new requestId",
8346
+ {
8347
+ requestId: operation.requestId,
8348
+ cause: cause instanceof Error ? cause.message : String(cause)
8349
+ }
8350
+ )
8351
+ )
8352
+ );
8353
+ requests.set(operation.requestId, { fingerprint, result });
8354
+ return result;
8355
+ }
8356
+ };
8357
+ }
8358
+ var PACK_AUTHORING_OPERATION_DESCRIPTORS = PACK_AUTHORING_OPERATION_IDS.map((id) => ({
8359
+ id,
8360
+ domain: id.startsWith("asset-source.") ? "session" : "asset",
8361
+ readOnly: id.startsWith("asset."),
8362
+ requiresRevision: !id.startsWith("asset.") && id !== "asset-source.create"
8363
+ }));
8364
+ function isRecord2(value) {
7191
8365
  return typeof value === "object" && value !== null && !Array.isArray(value);
7192
8366
  }
7193
8367
  function hasText(value) {
7194
8368
  return typeof value === "string" && value.length > 0;
7195
8369
  }
7196
- function issue(code, subjectId, expected, hint, actual2, authority = "producer") {
7197
- const subject = { type: "asset", id: subjectId };
8370
+ function issue(code, subjectId2, expected, hint, actual, authority = "producer") {
8371
+ const subject = { type: "asset", id: subjectId2 };
7198
8372
  return {
7199
8373
  ok: false,
7200
8374
  error: {
7201
8375
  code,
7202
8376
  subject,
7203
8377
  expected,
7204
- ...actual2 === void 0 ? {} : { actual: actual2 },
8378
+ ...actual === void 0 ? {} : { actual },
7205
8379
  hint,
7206
8380
  authority
7207
8381
  }
7208
8382
  };
7209
8383
  }
7210
- function validateFacts(value, subjectId) {
8384
+ function validateFacts(value, subjectId2) {
7211
8385
  if ("packageId" in value && !hasText(value.packageId)) {
7212
8386
  return issue(
7213
8387
  "invalid-producer-fact",
7214
- subjectId,
8388
+ subjectId2,
7215
8389
  "packageId must be a non-empty string",
7216
8390
  "publish a stable package identity"
7217
8391
  );
7218
8392
  }
7219
8393
  if ("provenance" in value) {
7220
8394
  const provenance = value.provenance;
7221
- if (!isRecord(provenance) || !hasText(provenance.provider) || !hasText(provenance.version)) {
8395
+ if (!isRecord2(provenance) || !hasText(provenance.provider) || !hasText(provenance.version)) {
7222
8396
  return issue(
7223
8397
  "invalid-producer-fact",
7224
- subjectId,
8398
+ subjectId2,
7225
8399
  "provenance.provider and provenance.version must be non-empty",
7226
8400
  "publish provider identity and version"
7227
8401
  );
@@ -7229,10 +8403,10 @@ function validateFacts(value, subjectId) {
7229
8403
  }
7230
8404
  if ("revision" in value) {
7231
8405
  const revision = value.revision;
7232
- if (!isRecord(revision) || !hasText(revision.digest) || !hasText(revision.rootId) || typeof revision.observedAt !== "number" || !Number.isFinite(revision.observedAt)) {
8406
+ if (!isRecord2(revision) || !hasText(revision.digest) || !hasText(revision.rootId) || typeof revision.observedAt !== "number" || !Number.isFinite(revision.observedAt)) {
7233
8407
  return issue(
7234
8408
  "invalid-producer-fact",
7235
- subjectId,
8409
+ subjectId2,
7236
8410
  "revision.digest, revision.rootId and finite revision.observedAt",
7237
8411
  "publish a complete resource revision"
7238
8412
  );
@@ -7242,25 +8416,25 @@ function validateFacts(value, subjectId) {
7242
8416
  if (!Array.isArray(value.diagnostics)) {
7243
8417
  return issue(
7244
8418
  "invalid-producer-fact",
7245
- subjectId,
8419
+ subjectId2,
7246
8420
  "diagnostics must be an array",
7247
8421
  "publish structured diagnostics as an array"
7248
8422
  );
7249
8423
  }
7250
8424
  for (const diagnostic of value.diagnostics) {
7251
- if (!isRecord(diagnostic) || !hasText(diagnostic.code)) {
8425
+ if (!isRecord2(diagnostic) || !hasText(diagnostic.code)) {
7252
8426
  return issue(
7253
8427
  "invalid-producer-fact",
7254
- subjectId,
8428
+ subjectId2,
7255
8429
  "each diagnostic needs a stable code",
7256
8430
  "publish a machine-readable diagnostic code"
7257
8431
  );
7258
8432
  }
7259
8433
  if (diagnostic.severity === "blocking") {
7260
- if (!isRecord(diagnostic.subject) || !hasText(diagnostic.subject.id)) {
8434
+ if (!isRecord2(diagnostic.subject) || !hasText(diagnostic.subject.id)) {
7261
8435
  return issue(
7262
8436
  "invalid-producer-fact",
7263
- subjectId,
8437
+ subjectId2,
7264
8438
  "blocking diagnostic.subject must identify an object",
7265
8439
  "set subject.type and subject.id"
7266
8440
  );
@@ -7268,7 +8442,7 @@ function validateFacts(value, subjectId) {
7268
8442
  if (!hasText(diagnostic.expected) || !hasText(diagnostic.hint)) {
7269
8443
  return issue(
7270
8444
  "invalid-producer-fact",
7271
- subjectId,
8445
+ subjectId2,
7272
8446
  "blocking diagnostics need expected and hint",
7273
8447
  "provide an executable recovery hint"
7274
8448
  );
@@ -7278,16 +8452,16 @@ function validateFacts(value, subjectId) {
7278
8452
  }
7279
8453
  return { ok: true, value };
7280
8454
  }
7281
- function validateMetaSourceOverrides(value, subjectId) {
8455
+ function validateMetaSourceOverrides(value, subjectId2) {
7282
8456
  if (!("sourceOverrides" in value)) return { ok: true, value };
7283
8457
  const declaredSourceKeys = Array.isArray(value.subAssets) ? value.subAssets.flatMap(
7284
- (subAsset) => isRecord(subAsset) && hasText(subAsset.sourceKey) ? [subAsset.sourceKey] : []
8458
+ (subAsset) => isRecord2(subAsset) && hasText(subAsset.sourceKey) ? [subAsset.sourceKey] : []
7285
8459
  ) : [];
7286
8460
  const result = validateSourceOverrideMap(value.sourceOverrides, declaredSourceKeys);
7287
8461
  if (!result.ok) {
7288
8462
  return issue(
7289
8463
  result.error.code,
7290
- subjectId,
8464
+ subjectId2,
7291
8465
  result.error.expected,
7292
8466
  result.error.hint,
7293
8467
  result.error.actual,
@@ -7300,7 +8474,7 @@ function validateMetaSourceOverrides(value, subjectId) {
7300
8474
  };
7301
8475
  }
7302
8476
  function validateProducerContract(value) {
7303
- if (!isRecord(value)) {
8477
+ if (!isRecord2(value)) {
7304
8478
  return issue(
7305
8479
  "invalid-producer-fact",
7306
8480
  "unknown",
@@ -7308,15 +8482,15 @@ function validateProducerContract(value) {
7308
8482
  "publish a JSON object"
7309
8483
  );
7310
8484
  }
7311
- const subjectId = hasText(value.guid) ? value.guid : hasText(value.packageId) ? value.packageId : "unknown";
7312
- const facts = validateFacts(value, subjectId);
8485
+ const subjectId2 = hasText(value.guid) ? value.guid : hasText(value.packageId) ? value.packageId : "unknown";
8486
+ const facts = validateFacts(value, subjectId2);
7313
8487
  if (!facts.ok) return facts;
7314
- const metaOverrides = validateMetaSourceOverrides(value, subjectId);
8488
+ const metaOverrides = validateMetaSourceOverrides(value, subjectId2);
7315
8489
  if (!metaOverrides.ok) return metaOverrides;
7316
8490
  if ("kind" in value && !hasText(value.kind)) {
7317
8491
  return issue(
7318
8492
  "invalid-producer-fact",
7319
- subjectId,
8493
+ subjectId2,
7320
8494
  "kind must be a non-empty open string",
7321
8495
  "publish the provider-owned asset kind"
7322
8496
  );
@@ -7324,7 +8498,7 @@ function validateProducerContract(value) {
7324
8498
  if ("execution" in value && value.execution !== "direct" && value.execution !== "cooked") {
7325
8499
  return issue(
7326
8500
  "invalid-producer-fact",
7327
- subjectId,
8501
+ subjectId2,
7328
8502
  "execution must be either direct or cooked",
7329
8503
  "publish the explicit authoring execution mode"
7330
8504
  );
@@ -7334,7 +8508,7 @@ function validateProducerContract(value) {
7334
8508
  if (value.sourceKey !== void 0 && !hasText(value.sourceKey)) {
7335
8509
  return issue(
7336
8510
  "invalid-source-key",
7337
- subjectId,
8511
+ subjectId2,
7338
8512
  "sourceKey must be a non-empty producer-owned string",
7339
8513
  "publish a stable semantic sourceKey"
7340
8514
  );
@@ -7342,7 +8516,7 @@ function validateProducerContract(value) {
7342
8516
  if (value.sourceIndex !== void 0 && (typeof value.sourceIndex !== "number" || !Number.isInteger(value.sourceIndex) || value.sourceIndex < 0)) {
7343
8517
  return issue(
7344
8518
  "invalid-source-index",
7345
- subjectId,
8519
+ subjectId2,
7346
8520
  "sourceIndex must be a non-negative integer locator",
7347
8521
  "publish a non-negative sourceIndex without using it as identity"
7348
8522
  );
@@ -7350,7 +8524,7 @@ function validateProducerContract(value) {
7350
8524
  if (value.sourceKey === void 0 && value.sourceIndex !== void 0) {
7351
8525
  return issue(
7352
8526
  "missing-source-key",
7353
- subjectId,
8527
+ subjectId2,
7354
8528
  "sourceKey is required when an output declares sourceIndex",
7355
8529
  "publish a stable semantic key; do not derive identity from sourceIndex"
7356
8530
  );
@@ -7358,7 +8532,7 @@ function validateProducerContract(value) {
7358
8532
  if ("compatiblePreviousKinds" in value && (!Array.isArray(value.compatiblePreviousKinds) || value.compatiblePreviousKinds.some((kind) => !hasText(kind)))) {
7359
8533
  return issue(
7360
8534
  "invalid-producer-fact",
7361
- subjectId,
8535
+ subjectId2,
7362
8536
  "compatiblePreviousKinds must be an array of non-empty kind strings",
7363
8537
  "declare only producer-verified prior kinds that may preserve the GUID"
7364
8538
  );
@@ -7396,93 +8570,6 @@ function validateProducerOutputs(outputs) {
7396
8570
  return { ok: true, value: outputs };
7397
8571
  }
7398
8572
 
7399
- // src/errors.ts
7400
- var PackError = class extends Error {
7401
- code;
7402
- expected;
7403
- hint;
7404
- detail;
7405
- constructor(args) {
7406
- super(`[PackError ${args.code}] expected: ${args.expected}; hint: ${args.hint}`);
7407
- this.name = "PackError";
7408
- this.code = args.code;
7409
- this.expected = args.expected;
7410
- this.hint = args.hint;
7411
- this.detail = args.detail;
7412
- }
7413
- };
7414
-
7415
- // src/guid.ts
7416
- function brand(bytes) {
7417
- return bytes;
7418
- }
7419
- var HEX_BYTE = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
7420
- function bytesToDashForm(bytes) {
7421
- const h = HEX_BYTE;
7422
- return `${h[bytes[0]]}${h[bytes[1]]}${h[bytes[2]]}${h[bytes[3]]}-${h[bytes[4]]}${h[bytes[5]]}-${h[bytes[6]]}${h[bytes[7]]}-${h[bytes[8]]}${h[bytes[9]]}-${h[bytes[10]]}${h[bytes[11]]}${h[bytes[12]]}${h[bytes[13]]}${h[bytes[14]]}${h[bytes[15]]}`;
7423
- }
7424
- var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
7425
- function isValidAssetGuidString(value) {
7426
- return typeof value === "string" && UUID_RE.test(value);
7427
- }
7428
- function dashFormToBytes(dashForm) {
7429
- const hex = dashForm.replace(/-/g, "");
7430
- const bytes = new Uint8Array(16);
7431
- for (let i = 0; i < 16; i++) {
7432
- bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
7433
- }
7434
- return bytes;
7435
- }
7436
- var AssetGuid = {
7437
- /**
7438
- * Parse a 36-char RFC 4122 dash-form UUID string into an AssetGuid.
7439
- * Returns Ok(AssetGuid) on success or Err(PackError) with code 'pack-guid-malformed' on failure.
7440
- * Never throws for expected failures (requirements §4.2 / §14 / charter proposition 4).
7441
- */
7442
- parse(dashForm) {
7443
- if (!isValidAssetGuidString(dashForm)) {
7444
- return {
7445
- ok: false,
7446
- error: new PackError({
7447
- code: "pack-guid-malformed",
7448
- expected: "36-char RFC 4122 dash-form UUID",
7449
- hint: "use AssetGuid.random() or a UUIDv7 generator; all GUID fields must be 36-char RFC 4122 dash-form",
7450
- detail: {
7451
- raw: dashForm,
7452
- reason: "expected 36-char RFC 4122 dash-form UUID"
7453
- }
7454
- })
7455
- };
7456
- }
7457
- return { ok: true, value: brand(dashFormToBytes(dashForm)) };
7458
- },
7459
- /**
7460
- * Format an AssetGuid as a 36-char RFC 4122 lowercase dash-form string.
7461
- */
7462
- format(guid) {
7463
- return bytesToDashForm(guid);
7464
- },
7465
- /**
7466
- * Test byte-by-byte equality between two AssetGuids.
7467
- */
7468
- equals(a, b) {
7469
- for (let i = 0; i < 16; i++) {
7470
- if (a[i] !== b[i]) return false;
7471
- }
7472
- return true;
7473
- },
7474
- /**
7475
- * Mint a new time-ordered UUIDv7 as an AssetGuid.
7476
- * Works in both Node.js and browser environments.
7477
- */
7478
- random() {
7479
- const uuid = uuidv7obj();
7480
- const bytes = new Uint8Array(16);
7481
- bytes.set(uuid.bytes);
7482
- return brand(bytes);
7483
- }
7484
- };
7485
-
7486
8573
  // src/scriptable-pack.ts
7487
8574
  var SCRIPTABLE_PACK_ASSET_KINDS = [
7488
8575
  "mesh",
@@ -7500,15 +8587,17 @@ var SCRIPTABLE_PACK_ASSET_KINDS = [
7500
8587
  "animation-clip",
7501
8588
  "animation-graph",
7502
8589
  "audio",
7503
- "particle-effect"
8590
+ "particle-effect",
8591
+ "ies-profile"
7504
8592
  ];
7505
8593
  function isScriptablePackAssetKind(value) {
7506
8594
  return SCRIPTABLE_PACK_ASSET_KINDS.includes(value);
7507
8595
  }
7508
8596
  function sceneComponentFieldType(value) {
7509
8597
  if (typeof value === "string") return value;
7510
- if (isRecord2(value) && typeof value.type === "string") return value.type;
7511
- return void 0;
8598
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
8599
+ const type = value.type;
8600
+ return typeof type === "string" ? type : void 0;
7512
8601
  }
7513
8602
  function projectScriptablePackSceneComponents(components) {
7514
8603
  return (components ?? []).map((component) => ({
@@ -7521,430 +8610,6 @@ function projectScriptablePackSceneComponents(components) {
7521
8610
  )
7522
8611
  }));
7523
8612
  }
7524
- var SCRIPTABLE_PACK_REQUEST_ID_SCHEMA = {
7525
- type: "string",
7526
- minLength: 1,
7527
- maxLength: 128,
7528
- pattern: "^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$",
7529
- description: "Caller-minted identity for one idempotent ScriptablePack operation."
7530
- };
7531
- var SCRIPTABLE_PACK_SOURCE_PATH_SCHEMA = {
7532
- type: "string",
7533
- minLength: 8,
7534
- pattern: "^[^/].*\\.pack\\.ts$",
7535
- description: "Game-root-relative ScriptablePack source path."
7536
- };
7537
- var SCRIPTABLE_PACK_OWNER_GUID_SCHEMA = {
7538
- type: "string",
7539
- format: "uuid",
7540
- description: "Catalog GUID used to resolve the producer-owned source subject."
7541
- };
7542
- var SCRIPTABLE_PACK_REVISION_SCHEMA = {
7543
- type: "string",
7544
- minLength: 64,
7545
- maxLength: 64,
7546
- pattern: "^[a-f0-9]{64}$",
7547
- description: "SHA-256 source revision returned by preflight."
7548
- };
7549
- var SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA = { type: "string", minLength: 1 };
7550
- var SCRIPTABLE_PACK_ASSET_KIND_SCHEMA = {
7551
- enum: SCRIPTABLE_PACK_ASSET_KINDS,
7552
- description: "Ordinary Asset kind supported by the ScriptablePack producer/loader matrix."
7553
- };
7554
- var SCRIPTABLE_PACK_NAME_SCHEMA = { type: "string", minLength: 1 };
7555
- function scriptablePackArgsSchema(properties, required, options = {}) {
7556
- const subjectRequired = ["requestId", ...required];
7557
- return {
7558
- type: "object",
7559
- properties: {
7560
- sourcePath: SCRIPTABLE_PACK_SOURCE_PATH_SCHEMA,
7561
- ownerGuid: SCRIPTABLE_PACK_OWNER_GUID_SCHEMA,
7562
- requestId: SCRIPTABLE_PACK_REQUEST_ID_SCHEMA,
7563
- ...properties
7564
- },
7565
- required: subjectRequired,
7566
- ...options.subject === false ? {} : {
7567
- anyOf: [
7568
- { required: [...subjectRequired, "sourcePath"] },
7569
- { required: [...subjectRequired, "ownerGuid"] },
7570
- ...options.guidSubject === false ? [] : [{ required: [...subjectRequired, "guid"] }]
7571
- ]
7572
- },
7573
- additionalProperties: false
7574
- };
7575
- }
7576
- [
7577
- {
7578
- id: "asset-source.create",
7579
- kind: "create",
7580
- domain: "session",
7581
- title: "Create Asset Source",
7582
- argsSchema: scriptablePackArgsSchema(
7583
- {
7584
- name: SCRIPTABLE_PACK_NAME_SCHEMA,
7585
- initialOutput: {
7586
- type: "object",
7587
- properties: {
7588
- sourceKey: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA,
7589
- kind: SCRIPTABLE_PACK_ASSET_KIND_SCHEMA,
7590
- name: SCRIPTABLE_PACK_NAME_SCHEMA
7591
- },
7592
- required: ["sourceKey", "kind"],
7593
- additionalProperties: false
7594
- }
7595
- },
7596
- ["sourcePath", "initialOutput"],
7597
- { subject: false }
7598
- )
7599
- },
7600
- {
7601
- id: "asset-source.add-output",
7602
- kind: "add-output",
7603
- domain: "session",
7604
- title: "Add Asset Source Output",
7605
- argsSchema: scriptablePackArgsSchema(
7606
- {
7607
- sourceKey: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA,
7608
- assetKind: SCRIPTABLE_PACK_ASSET_KIND_SCHEMA,
7609
- name: SCRIPTABLE_PACK_NAME_SCHEMA,
7610
- expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
7611
- },
7612
- ["sourceKey", "assetKind", "expectedRevision"]
7613
- )
7614
- },
7615
- {
7616
- id: "asset-source.add-external-asset",
7617
- kind: "add-external-asset",
7618
- domain: "session",
7619
- title: "Add Asset Source External Asset",
7620
- argsSchema: scriptablePackArgsSchema(
7621
- {
7622
- alias: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA,
7623
- guid: { type: "string", format: "uuid" },
7624
- expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
7625
- },
7626
- ["alias", "guid", "expectedRevision"],
7627
- { guidSubject: false }
7628
- )
7629
- },
7630
- {
7631
- id: "asset-source.rename",
7632
- kind: "rename",
7633
- domain: "session",
7634
- title: "Rename Asset Source Display Name",
7635
- argsSchema: scriptablePackArgsSchema(
7636
- {
7637
- target: {
7638
- oneOf: [
7639
- {
7640
- type: "object",
7641
- properties: { kind: { const: "package" } },
7642
- required: ["kind"],
7643
- additionalProperties: false
7644
- },
7645
- {
7646
- type: "object",
7647
- properties: {
7648
- kind: { const: "output" },
7649
- sourceKey: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA
7650
- },
7651
- required: ["kind", "sourceKey"],
7652
- additionalProperties: false
7653
- }
7654
- ]
7655
- },
7656
- name: SCRIPTABLE_PACK_NAME_SCHEMA,
7657
- expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
7658
- },
7659
- ["target", "name", "expectedRevision"]
7660
- )
7661
- },
7662
- {
7663
- id: "asset-source.remove-output",
7664
- kind: "remove-output",
7665
- domain: "session",
7666
- title: "Remove Asset Source Output",
7667
- destructive: true,
7668
- argsSchema: scriptablePackArgsSchema(
7669
- {
7670
- sourceKey: SCRIPTABLE_PACK_SOURCE_KEY_SCHEMA,
7671
- confirmIncomingRefs: { type: "array", items: { type: "string" } },
7672
- expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
7673
- },
7674
- ["sourceKey", "expectedRevision"]
7675
- )
7676
- },
7677
- {
7678
- id: "asset-source.clone",
7679
- kind: "clone",
7680
- domain: "session",
7681
- title: "Clone Asset Source",
7682
- argsSchema: scriptablePackArgsSchema(
7683
- {
7684
- targetPath: SCRIPTABLE_PACK_SOURCE_PATH_SCHEMA,
7685
- expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA
7686
- },
7687
- ["targetPath", "expectedRevision"]
7688
- )
7689
- },
7690
- {
7691
- id: "asset-source.rebuild",
7692
- kind: "rebuild",
7693
- domain: "session",
7694
- title: "Rebuild Asset Source",
7695
- argsSchema: scriptablePackArgsSchema({ expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA }, [
7696
- "expectedRevision"
7697
- ])
7698
- },
7699
- {
7700
- id: "asset-source.cold-cook",
7701
- kind: "cold-cook",
7702
- domain: "session",
7703
- title: "Cold Cook Asset Source",
7704
- argsSchema: scriptablePackArgsSchema({ expectedRevision: SCRIPTABLE_PACK_REVISION_SCHEMA }, [
7705
- "expectedRevision"
7706
- ])
7707
- }
7708
- ];
7709
- function actual(value) {
7710
- if (value === null) return "null";
7711
- if (Array.isArray(value)) return "array";
7712
- if (ArrayBuffer.isView(value)) return value.constructor.name;
7713
- return typeof value;
7714
- }
7715
- function invalid2(propertyPath, expected, value, sourcePath) {
7716
- return err({
7717
- code: "pack-source-definition-invalid",
7718
- expected,
7719
- hint: "repair the default exported ScriptablePack definition, then inspect Meta again",
7720
- detail: {
7721
- ...sourcePath === void 0 ? {} : { sourcePath },
7722
- propertyPath,
7723
- actual: actual(value)
7724
- }
7725
- });
7726
- }
7727
- function isRecord2(value) {
7728
- return value !== null && typeof value === "object" && !Array.isArray(value);
7729
- }
7730
- function isAssetGuid(value) {
7731
- return value instanceof Uint8Array && value.byteLength === 16;
7732
- }
7733
- function guidKey(guid) {
7734
- return AssetGuid.format(guid);
7735
- }
7736
- function freezeDefinition(definition) {
7737
- const assets = Object.fromEntries(
7738
- Object.entries(definition.assets).map(([sourceKey2, descriptor]) => [
7739
- sourceKey2,
7740
- Object.freeze({ ...descriptor, guid: descriptor.guid.slice() })
7741
- ])
7742
- );
7743
- const externalAssets = Object.fromEntries(
7744
- Object.entries(definition.externalAssets).map(([alias, guid]) => [
7745
- alias,
7746
- guid.slice()
7747
- ])
7748
- );
7749
- const sceneComponents = definition.sceneComponents === void 0 ? void 0 : Object.freeze(
7750
- projectScriptablePackSceneComponents(definition.sceneComponents).map(
7751
- (component) => Object.freeze({
7752
- ...component,
7753
- fields: Object.freeze({ ...component.fields })
7754
- })
7755
- )
7756
- );
7757
- return Object.freeze({
7758
- ...definition,
7759
- packageId: definition.packageId.slice(),
7760
- assets: Object.freeze(assets),
7761
- externalAssets: Object.freeze(externalAssets),
7762
- ...sceneComponents === void 0 ? {} : { sceneComponents }
7763
- });
7764
- }
7765
- function validateScriptablePackDefinition(value, sourcePath) {
7766
- if (!isRecord2(value))
7767
- return invalid2("$", "a ScriptablePack definition object", value, sourcePath);
7768
- if (value.schemaVersion !== "1.0.0") {
7769
- return invalid2("$.schemaVersion", "the literal '1.0.0'", value.schemaVersion, sourcePath);
7770
- }
7771
- if (!isAssetGuid(value.packageId)) {
7772
- return invalid2("$.packageId", "a 16-byte AssetGuid", value.packageId, sourcePath);
7773
- }
7774
- if (value.name !== void 0 && typeof value.name !== "string") {
7775
- return invalid2("$.name", "a string when present", value.name, sourcePath);
7776
- }
7777
- if (!isRecord2(value.assets) || Object.keys(value.assets).length === 0) {
7778
- return invalid2(
7779
- "$.assets",
7780
- "a non-empty sourceKey to descriptor object",
7781
- value.assets,
7782
- sourcePath
7783
- );
7784
- }
7785
- if (!isRecord2(value.externalAssets)) {
7786
- return invalid2(
7787
- "$.externalAssets",
7788
- "an alias to AssetGuid object",
7789
- value.externalAssets,
7790
- sourcePath
7791
- );
7792
- }
7793
- if (value.sceneComponents !== void 0) {
7794
- if (!Array.isArray(value.sceneComponents)) {
7795
- return invalid2(
7796
- "$.sceneComponents",
7797
- "an array of component tokens or neutral schema rows when present",
7798
- value.sceneComponents,
7799
- sourcePath
7800
- );
7801
- }
7802
- const componentNames = /* @__PURE__ */ new Set();
7803
- for (const [componentIndex, component] of value.sceneComponents.entries()) {
7804
- if (!isRecord2(component)) {
7805
- return invalid2(
7806
- `$.sceneComponents[${componentIndex}]`,
7807
- "a component token or neutral schema row",
7808
- component,
7809
- sourcePath
7810
- );
7811
- }
7812
- if (typeof component.name !== "string" || component.name.trim().length === 0) {
7813
- return invalid2(
7814
- `$.sceneComponents[${componentIndex}].name`,
7815
- "a non-empty component name",
7816
- component.name,
7817
- sourcePath
7818
- );
7819
- }
7820
- if (componentNames.has(component.name)) {
7821
- return invalid2(
7822
- `$.sceneComponents[${componentIndex}].name`,
7823
- "component names to be unique within one ScriptablePack",
7824
- component.name,
7825
- sourcePath
7826
- );
7827
- }
7828
- componentNames.add(component.name);
7829
- if (!isRecord2(component.fields)) {
7830
- return invalid2(
7831
- `$.sceneComponents[${componentIndex}].fields`,
7832
- "a field-name to schema-type object",
7833
- component.fields,
7834
- sourcePath
7835
- );
7836
- }
7837
- for (const [fieldName, field] of Object.entries(component.fields)) {
7838
- const type = sceneComponentFieldType(field);
7839
- if (fieldName.trim().length === 0 || type === void 0 || type.trim().length === 0) {
7840
- return invalid2(
7841
- `$.sceneComponents[${componentIndex}].fields`,
7842
- "field names with non-empty string schema types",
7843
- field,
7844
- sourcePath
7845
- );
7846
- }
7847
- }
7848
- }
7849
- }
7850
- if (typeof value.build !== "function") {
7851
- return invalid2("$.build", "a build(assetReader) function", value.build, sourcePath);
7852
- }
7853
- const packageGuid = guidKey(value.packageId);
7854
- const localGuids = /* @__PURE__ */ new Set();
7855
- for (const [sourceKey2, descriptor] of Object.entries(value.assets)) {
7856
- if (sourceKey2.trim().length === 0) {
7857
- return invalid2("$.assets", "non-empty sourceKey object keys", sourceKey2, sourcePath);
7858
- }
7859
- if (!isRecord2(descriptor)) {
7860
- return invalid2(
7861
- `$.assets[${JSON.stringify(sourceKey2)}]`,
7862
- "an asset descriptor",
7863
- descriptor,
7864
- sourcePath
7865
- );
7866
- }
7867
- if (!isAssetGuid(descriptor.guid)) {
7868
- return invalid2(
7869
- `$.assets[${JSON.stringify(sourceKey2)}].guid`,
7870
- "a 16-byte AssetGuid",
7871
- descriptor.guid,
7872
- sourcePath
7873
- );
7874
- }
7875
- if (typeof descriptor.kind !== "string" || !isScriptablePackAssetKind(descriptor.kind)) {
7876
- return invalid2(
7877
- `$.assets[${JSON.stringify(sourceKey2)}].kind`,
7878
- "one of SCRIPTABLE_PACK_ASSET_KINDS",
7879
- descriptor.kind,
7880
- sourcePath
7881
- );
7882
- }
7883
- if (descriptor.name !== void 0 && typeof descriptor.name !== "string") {
7884
- return invalid2(
7885
- `$.assets[${JSON.stringify(sourceKey2)}].name`,
7886
- "a string when present",
7887
- descriptor.name,
7888
- sourcePath
7889
- );
7890
- }
7891
- const guid = guidKey(descriptor.guid);
7892
- if (guid === packageGuid || localGuids.has(guid)) {
7893
- return invalid2(
7894
- `$.assets[${JSON.stringify(sourceKey2)}].guid`,
7895
- "a GUID unique within the package and distinct from packageId",
7896
- descriptor.guid,
7897
- sourcePath
7898
- );
7899
- }
7900
- localGuids.add(guid);
7901
- }
7902
- const externalGuids = /* @__PURE__ */ new Set();
7903
- for (const [alias, guidValue] of Object.entries(value.externalAssets)) {
7904
- if (alias.trim().length === 0) {
7905
- return invalid2("$.externalAssets", "non-empty alias object keys", alias, sourcePath);
7906
- }
7907
- if (!isAssetGuid(guidValue)) {
7908
- return invalid2(
7909
- `$.externalAssets[${JSON.stringify(alias)}]`,
7910
- "a 16-byte AssetGuid",
7911
- guidValue,
7912
- sourcePath
7913
- );
7914
- }
7915
- const guid = guidKey(guidValue);
7916
- if (guid === packageGuid || localGuids.has(guid) || externalGuids.has(guid)) {
7917
- return invalid2(
7918
- `$.externalAssets[${JSON.stringify(alias)}]`,
7919
- "a unique foreign GUID not owned by this package",
7920
- guidValue,
7921
- sourcePath
7922
- );
7923
- }
7924
- externalGuids.add(guid);
7925
- }
7926
- return ok(freezeDefinition(value));
7927
- }
7928
- function projectScriptablePackMeta(definition, source) {
7929
- const subAssets = Object.entries(definition.assets).sort(([left], [right]) => left.localeCompare(right)).map(([sourceKey2, descriptor], sourceIndex) => ({
7930
- guid: guidKey(descriptor.guid),
7931
- sourceIndex,
7932
- sourceKey: sourceKey2,
7933
- kind: descriptor.kind,
7934
- ...descriptor.name === void 0 ? {} : { name: descriptor.name }
7935
- }));
7936
- const externalAssets = Object.entries(definition.externalAssets).sort(([left], [right]) => left.localeCompare(right)).map(([alias, guid]) => ({ alias, guid: guidKey(guid) }));
7937
- return {
7938
- schemaVersion: "1.0.0",
7939
- kind: "external-asset-package",
7940
- packageId: guidKey(definition.packageId),
7941
- ...definition.name === void 0 ? {} : { name: definition.name },
7942
- importer: "pack-ts",
7943
- source,
7944
- importSettings: { contractVersion: "1.0.0", externalAssets },
7945
- subAssets
7946
- };
7947
- }
7948
8613
 
7949
8614
  // src/topology.ts
7950
8615
  function sourceKey(output) {
@@ -8155,7 +8820,7 @@ var meta_schema_default = {
8155
8820
  source: {
8156
8821
  type: "string",
8157
8822
  minLength: 1,
8158
- description: "Optional. Omit to derive the companion file in the same directory (strip .meta.json suffix from the meta filename). Or write @<name>/<rest> to reference a declared path table entry (see package.json#forgeax.assets.paths). Existing relative paths remain unchanged."
8823
+ description: "Optional. Omit to derive the companion file in the same directory (strip .meta.json suffix from the meta filename). An explicit source is resolved relative to this sidecar."
8159
8824
  },
8160
8825
  importSettings: {
8161
8826
  type: "object",
@@ -8296,11 +8961,11 @@ var pack_schema_default = {
8296
8961
  $comment: "The ordinary durable consumer matrix is SCRIPTABLE_PACK_ASSET_KINDS in @forgeax/engine-pack/source. Pack kind fields remain open for registered producer extensions.",
8297
8962
  type: "object",
8298
8963
  additionalProperties: false,
8299
- required: ["schemaVersion", "kind", "assets"],
8964
+ required: ["schemaVersion"],
8300
8965
  properties: {
8301
8966
  schemaVersion: {
8302
8967
  type: "string",
8303
- enum: ["1.0.0", "2.0.0"]
8968
+ enum: ["1.0.0", "2.0.0", "3.0.0"]
8304
8969
  },
8305
8970
  kind: {
8306
8971
  type: "string",
@@ -8322,12 +8987,58 @@ var pack_schema_default = {
8322
8987
  items: { $ref: "#/$defs/diagnostic" }
8323
8988
  },
8324
8989
  assets: {
8325
- type: "array",
8326
- items: {
8327
- $ref: "#/$defs/asset"
8328
- }
8990
+ oneOf: [
8991
+ {
8992
+ type: "array",
8993
+ items: { $ref: "#/$defs/asset" }
8994
+ },
8995
+ { $ref: "#/$defs/authoringAssets" }
8996
+ ]
8997
+ },
8998
+ parent: {
8999
+ $ref: "#/$defs/guid36",
9000
+ description: "Parent ScriptablePack packageId for one v3 instance; the source may declare Pack parameters."
9001
+ },
9002
+ values: {
9003
+ type: "object",
9004
+ additionalProperties: true,
9005
+ description: "Sparse shallow parameter overrides for one v3 instance."
8329
9006
  }
8330
9007
  },
9008
+ oneOf: [
9009
+ {
9010
+ required: ["kind", "assets"],
9011
+ properties: {
9012
+ schemaVersion: { enum: ["1.0.0", "2.0.0"] },
9013
+ kind: { const: "internal-text-package" },
9014
+ assets: { type: "array" },
9015
+ parent: false,
9016
+ values: false
9017
+ }
9018
+ },
9019
+ {
9020
+ required: ["packageId", "assets"],
9021
+ properties: {
9022
+ schemaVersion: { const: "3.0.0" },
9023
+ kind: false,
9024
+ packageId: { $ref: "#/$defs/guid36" },
9025
+ assets: { $ref: "#/$defs/authoringAssets" },
9026
+ parent: false,
9027
+ values: false
9028
+ }
9029
+ },
9030
+ {
9031
+ required: ["packageId", "parent", "values"],
9032
+ properties: {
9033
+ schemaVersion: { const: "3.0.0" },
9034
+ kind: false,
9035
+ packageId: { $ref: "#/$defs/guid36" },
9036
+ parent: { $ref: "#/$defs/guid36" },
9037
+ values: { type: "object" },
9038
+ assets: false
9039
+ }
9040
+ }
9041
+ ],
8331
9042
  allOf: [
8332
9043
  {
8333
9044
  if: {
@@ -8419,6 +9130,30 @@ var pack_schema_default = {
8419
9130
  }
8420
9131
  ]
8421
9132
  },
9133
+ authoringAssets: {
9134
+ type: "object",
9135
+ additionalProperties: false,
9136
+ patternProperties: {
9137
+ "^[a-z0-9][a-z0-9._-]*(/[a-z0-9][a-z0-9._-]*)*$": {
9138
+ $ref: "#/$defs/authoringAsset"
9139
+ }
9140
+ }
9141
+ },
9142
+ authoringAsset: {
9143
+ type: "object",
9144
+ additionalProperties: false,
9145
+ required: ["kind", "payload", "refs"],
9146
+ properties: {
9147
+ kind: { type: "string", minLength: 1 },
9148
+ name: { type: "string", minLength: 1 },
9149
+ payload: { type: "object" },
9150
+ refs: {
9151
+ type: "array",
9152
+ items: { $ref: "#/$defs/guid36" }
9153
+ },
9154
+ artifacts: { $ref: "#/$defs/artifacts" }
9155
+ }
9156
+ },
8422
9157
  artifacts: {
8423
9158
  type: "object",
8424
9159
  additionalProperties: false,
@@ -8548,7 +9283,7 @@ function writeMaterialArtifact(input) {
8548
9283
  digest: createMaterialArtifactDigest(input.bytes)
8549
9284
  };
8550
9285
  }
8551
- function invalid3(observed, expected) {
9286
+ function invalid2(observed, expected) {
8552
9287
  return err({
8553
9288
  code: "pack-v2-envelope-invalid",
8554
9289
  expected,
@@ -8567,10 +9302,10 @@ function isAsset(value) {
8567
9302
  }
8568
9303
  function projectRuntimePack(value) {
8569
9304
  if (!isRecord3(value) || ("schemaVersion" in value || "kind" in value) && (value.schemaVersion !== "2.0.0" || value.kind !== "internal-text-package")) {
8570
- return invalid3("legacy or malformed pack input", "runtime Pack v2");
9305
+ return invalid2("legacy or malformed pack input", "runtime Pack v2");
8571
9306
  }
8572
9307
  if (!isTuple(value) || !Array.isArray(value.assets) || !value.assets.every(isAsset)) {
8573
- return invalid3("incomplete publication tuple or asset envelope", "verified runtime Pack v2");
9308
+ return invalid2("incomplete publication tuple or asset envelope", "verified runtime Pack v2");
8574
9309
  }
8575
9310
  const seen = /* @__PURE__ */ new Set();
8576
9311
  for (const asset of value.assets) {
@@ -8609,6 +9344,6 @@ function parsePackV2(value) {
8609
9344
  return ok(value);
8610
9345
  }
8611
9346
 
8612
- export { MESH_BIN_DIGEST_BYTES, MESH_BIN_HEADER_V4_BYTES, MESH_BIN_PROJECTION_VERSION, MESH_BIN_VERSION, SCRIPTABLE_PACK_ASSET_KINDS, buildOfflineAssetEvidence, calculateTopologyDiff, collectMaterialCookRefs, createMaterialArtifactDigest, createMaterialCookIdentity, decodeMeshBinHeader, diffTopology, isScriptablePackAssetKind, packageVerification, parsePackV2, projectCookedMaterialRecord, projectRuntimePack, projectScriptablePackMeta, serializeCookedMaterialRecord, serializeMaterialCookReceipt, validateArtifactPath, validateCookedMaterialRecord, validateMaterialCookReceipt, validateMeta, validatePack, validatePackV2, validateProducerContract, validateProducerOutputs, validateScriptablePackDefinition, writeMaterialArtifact, writeMeshBinHeader };
9347
+ export { AssetGuid, MESH_BIN_DIGEST_BYTES, MESH_BIN_HEADER_V4_BYTES, MESH_BIN_PROJECTION_VERSION, MESH_BIN_VERSION, PACK_AUTHORING_OPERATION_DESCRIPTORS, PACK_AUTHORING_OPERATION_IDS, PACK_PARAMETER_TYPES, PACK_SOURCE_KEY_RE, PackageId, SCRIPTABLE_PACK_ASSET_KINDS, buildOfflineAssetEvidence, calculateTopologyDiff, collectMaterialCookRefs, createMaterialArtifactDigest, createMaterialCookIdentity, createPackAuthoringGateway, decodeMeshBinHeader, definePack, definePackageId, diffTopology, hasPackParameters, isScriptablePackAssetKind, isStandardMaterialRecord, isStandardRootModule, isValidAssetGuidString, isValidPackSourceKey, materialLayerPlanIdentity, packageVerification, parsePackSourceJson, parsePackV2, projectCookedMaterialRecord, projectDirectPackJson, projectRuntimePack, projectScriptablePackMeta, projectScriptablePackSceneComponents, resolvePackInheritance, resolvePackParameterInheritance, resolvePackParameterValues, serializeCookedMaterialRecord, serializeMaterialCookReceipt, validateArtifactPath, validateCookedMaterialRecord, validateMaterialCookReceipt, validateMeta, validatePack, validatePackDefinition, validatePackV2, validateProducerContract, validateProducerOutputs, writeMaterialArtifact, writeMeshBinHeader };
8613
9348
  //# sourceMappingURL=index.mjs.map
8614
9349
  //# sourceMappingURL=index.mjs.map