minerender 2.1.0-alpha.116 → 2.1.0-alpha.117

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.
@@ -1346,6 +1346,7 @@ interface MineRenderDataManifest {
1346
1346
  interface ResolvedMineRenderData {
1347
1347
  requestedVersion: string;
1348
1348
  version: string;
1349
+ /** Registry lookup root. Rootless requests still allow registered sources to override this URL. */
1349
1350
  root: string;
1350
1351
  manifest: MineRenderDataManifest;
1351
1352
  }
@@ -1355,7 +1356,8 @@ declare class MineRenderData {
1355
1356
  static get<K extends keyof MineRenderDatasets>(dataset: K, root?: string): Promise<MineRenderDatasets[K]>;
1356
1357
  /**
1357
1358
  * Uses the exact version when published. Otherwise, selects the nearest patch in the same
1358
- * release line (older on ties), then the latest earlier release. Unpublished snapshots reject.
1359
+ * release line (older on ties), then the latest earlier release or the oldest published release.
1360
+ * Unpublished snapshots reject.
1359
1361
  */
1360
1362
  static resolve(root?: string): Promise<ResolvedMineRenderData>;
1361
1363
  private static manifest;
@@ -1392,7 +1394,6 @@ declare class Models {
1392
1394
  static componentValue(components: Record<string, unknown>, id: string): unknown;
1393
1395
  private static snapshotContext;
1394
1396
  private static applyDefaults;
1395
- private static sourceCheck;
1396
1397
  private static contextKey;
1397
1398
  private static snapshotJson;
1398
1399
  private static propertyValue;
@@ -3622,7 +3623,6 @@ declare class AnvilParser {
3622
3623
  * @returns The chunk with absolute coordinates, or `undefined` if the region has no chunk there.
3623
3624
  */
3624
3625
  static parseChunk(data: RegionInput, localX: number, localZ: number, options?: AnvilParseOptions): Promise<AnvilChunk | undefined>;
3625
- private static assetGuard;
3626
3626
  /**
3627
3627
  * Decodes one chunk from an `entities/r.x.z.mca` file without migrating its NBT.
3628
3628
  * @param localX - Chunk x within the region, from 0 to 31.
@@ -1346,6 +1346,7 @@ interface MineRenderDataManifest {
1346
1346
  interface ResolvedMineRenderData {
1347
1347
  requestedVersion: string;
1348
1348
  version: string;
1349
+ /** Registry lookup root. Rootless requests still allow registered sources to override this URL. */
1349
1350
  root: string;
1350
1351
  manifest: MineRenderDataManifest;
1351
1352
  }
@@ -1355,7 +1356,8 @@ declare class MineRenderData {
1355
1356
  static get<K extends keyof MineRenderDatasets>(dataset: K, root?: string): Promise<MineRenderDatasets[K]>;
1356
1357
  /**
1357
1358
  * Uses the exact version when published. Otherwise, selects the nearest patch in the same
1358
- * release line (older on ties), then the latest earlier release. Unpublished snapshots reject.
1359
+ * release line (older on ties), then the latest earlier release or the oldest published release.
1360
+ * Unpublished snapshots reject.
1359
1361
  */
1360
1362
  static resolve(root?: string): Promise<ResolvedMineRenderData>;
1361
1363
  private static manifest;
@@ -1392,7 +1394,6 @@ declare class Models {
1392
1394
  static componentValue(components: Record<string, unknown>, id: string): unknown;
1393
1395
  private static snapshotContext;
1394
1396
  private static applyDefaults;
1395
- private static sourceCheck;
1396
1397
  private static contextKey;
1397
1398
  private static snapshotJson;
1398
1399
  private static propertyValue;
@@ -3622,7 +3623,6 @@ declare class AnvilParser {
3622
3623
  * @returns The chunk with absolute coordinates, or `undefined` if the region has no chunk there.
3623
3624
  */
3624
3625
  static parseChunk(data: RegionInput, localX: number, localZ: number, options?: AnvilParseOptions): Promise<AnvilChunk | undefined>;
3625
- private static assetGuard;
3626
3626
  /**
3627
3627
  * Decodes one chunk from an `entities/r.x.z.mca` file without migrating its NBT.
3628
3628
  * @param localX - Chunk x within the region, from 0 to 31.
@@ -1607,7 +1607,8 @@ var init_MineRenderData = __esm({
1607
1607
  }
1608
1608
  /**
1609
1609
  * Uses the exact version when published. Otherwise, selects the nearest patch in the same
1610
- * release line (older on ties), then the latest earlier release. Unpublished snapshots reject.
1610
+ * release line (older on ties), then the latest earlier release or the oldest published release.
1611
+ * Unpublished snapshots reject.
1611
1612
  */
1612
1613
  static async resolve(root) {
1613
1614
  const requestRoot = root?.replace(/\/+$/, "");
@@ -1616,11 +1617,11 @@ var init_MineRenderData = __esm({
1616
1617
  const scope = AssetLoader.persistentScope;
1617
1618
  return this.cached(`resolve:${requestRoot === void 0 ? "sources" : "explicit"}:${root}`, scope, defaultRoot, async () => {
1618
1619
  const requestedVersion = root.slice(root.lastIndexOf("/") + 1);
1619
- let manifest = await this.manifest(root, release(requestedVersion) ? requestedVersion : void 0, requestRoot);
1620
+ let manifest = await this.manifest(root, requestRoot !== void 0 && release(requestedVersion) ? requestedVersion : void 0, requestRoot);
1620
1621
  if (manifest) return { requestedVersion, version: manifest.minecraftVersion, root, manifest };
1621
1622
  const requested = release(requestedVersion);
1622
- if (!requested || compare(requested, [1, 16, 5]) < 0) {
1623
- throw new Error(`No MineRender data is published for ${requestedVersion}; automatic fallback requires a release from 1.16.5 onward`);
1623
+ if (!requested) {
1624
+ throw new Error(`No MineRender data is published for ${requestedVersion}; automatic fallback requires a release`);
1624
1625
  }
1625
1626
  const base = root.slice(0, root.lastIndexOf("/"));
1626
1627
  const index = await this.cached(`versions:${base}`, scope, defaultRoot, async () => {
@@ -1630,9 +1631,9 @@ var init_MineRenderData = __esm({
1630
1631
  }
1631
1632
  return value.versions;
1632
1633
  });
1633
- const versions = index.map((entry) => ({ name: entry.name, number: release(entry.name) })).filter((entry) => !!entry.number && compare(entry.number, [1, 16, 5]) >= 0).sort((left, right) => compare(left.number, right.number));
1634
+ const versions = index.map((entry) => ({ name: entry.name, number: release(entry.name) })).filter((entry) => !!entry.number).sort((left, right) => compare(left.number, right.number));
1634
1635
  const sameLine = versions.filter((entry) => entry.number[0] === requested[0] && entry.number[1] === requested[1]);
1635
- const selected = sameLine.sort((left, right) => Math.abs((left.number[2] ?? 0) - (requested[2] ?? 0)) - Math.abs((right.number[2] ?? 0) - (requested[2] ?? 0)) || compare(left.number, right.number))[0] ?? versions.filter((entry) => compare(entry.number, requested) <= 0).pop();
1636
+ const selected = sameLine.sort((left, right) => Math.abs((left.number[2] ?? 0) - (requested[2] ?? 0)) - Math.abs((right.number[2] ?? 0) - (requested[2] ?? 0)) || compare(left.number, right.number))[0] ?? versions.filter((entry) => compare(entry.number, requested) <= 0).pop() ?? versions[0];
1636
1637
  if (!selected) throw new Error(`No compatible MineRender data is published for ${requestedVersion}`);
1637
1638
  const resolvedRoot = `${base}/${selected.name}`;
1638
1639
  manifest = await this.manifest(resolvedRoot, selected.name, resolvedRoot);
@@ -1748,12 +1749,7 @@ var init_BannerPatterns = __esm({
1748
1749
  static async getLayers(value, target, root) {
1749
1750
  if (value === void 0) return [];
1750
1751
  if (!Array.isArray(value)) throw new Error("banner_patterns must be an array");
1751
- const activeRoot = AssetLoader.ROOT, scope = AssetLoader.persistentScope;
1752
- const checkSources = () => {
1753
- if (activeRoot !== AssetLoader.ROOT || scope !== AssetLoader.persistentScope) throw new Error("Asset sources changed while loading banner patterns; retry the request");
1754
- };
1755
1752
  const colors = value.length ? await this.getColors(root) : void 0;
1756
- checkSources();
1757
1753
  return Promise.all(value.slice(0, 16).map(async (layer) => {
1758
1754
  if (!layer || typeof layer !== "object" || Array.isArray(layer)) throw new Error("Each banner pattern requires a pattern and dye color");
1759
1755
  if (typeof layer.color !== "string" || !Object.prototype.hasOwnProperty.call(colors, layer.color)) throw new Error(`Unsupported dye color ${layer.color}`);
@@ -1763,7 +1759,6 @@ var init_BannerPatterns = __esm({
1763
1759
  const id = this.identifier(pattern2);
1764
1760
  const key = new AssetKey(id.namespace, id.getFullPath(), "banner_pattern", void 0, "data", ".json", root);
1765
1761
  pattern2 = await Caching.bannerPatternCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
1766
- checkSources();
1767
1762
  if (!pattern2) throw new Error(`Missing banner pattern ${layer.pattern}`);
1768
1763
  }
1769
1764
  if (!pattern2 || typeof pattern2 !== "object" || Array.isArray(pattern2) || typeof pattern2.translation_key !== "string") throw new Error("Banner patterns require asset_id and translation_key");
@@ -2048,30 +2043,24 @@ var init_Models = __esm({
2048
2043
  }).then((r) => r?.files ?? []);
2049
2044
  }
2050
2045
  static async loadAndMerge(key, context = {}) {
2051
- const checkSources = this.sourceCheck();
2052
2046
  const model = key.type === "item" ? await this.getItemModel(key, context) : await this.getRaw(key);
2053
2047
  if (!model) {
2054
2048
  return void 0;
2055
2049
  }
2056
2050
  const merged = await ModelMerger.mergeWithParents(model);
2057
- checkSources();
2058
2051
  return merged;
2059
2052
  }
2060
2053
  static async getItemModel(key, context = {}) {
2061
- const checkSources = this.sourceCheck();
2062
2054
  const preview = this.snapshotContext(key, context);
2063
2055
  const dataKey = await this.applyDefaults(key, preview);
2064
- checkSources();
2065
2056
  return this.getPreparedItemModel(key, preview, dataKey);
2066
2057
  }
2067
2058
  static async getPreparedItemModel(key, preview, dataKey) {
2068
- const checkSources = this.sourceCheck();
2069
2059
  const itemId = `${key.namespace}:${key.path}`;
2070
2060
  const itemKey2 = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
2071
2061
  const cacheKey = itemKey2.serialize() + this.contextKey(preview) + dataKey;
2072
2062
  const model = await this.PERSISTENT_CACHE.getOrLoad(`${this.ITEM_CACHE_VERSION}:${AssetLoader.persistentKey(cacheKey)}`, async () => {
2073
2063
  const result = await AssetLoader.getFirst([itemKey2, key], "json" /* JSON */);
2074
- checkSources();
2075
2064
  if (!result) return void 0;
2076
2065
  if (result.key.assetType !== "items") return { ...result.asset, key, itemId, components: preview.components };
2077
2066
  const load = async (selected) => {
@@ -2090,10 +2079,8 @@ var init_Models = __esm({
2090
2079
  return { ...model3, itemId, components: preview.components, ...selected.special && { special: selected.special }, ...selected.tints && { tints: selected.tints } };
2091
2080
  };
2092
2081
  const model2 = await load(this.selectItemModel(result.asset.model, key, preview));
2093
- checkSources();
2094
2082
  return model2;
2095
2083
  });
2096
- checkSources();
2097
2084
  const restore = (model2) => ({
2098
2085
  ...model2,
2099
2086
  key: Object.assign(new AssetKey("", ""), model2.key),
@@ -2157,22 +2144,14 @@ var init_Models = __esm({
2157
2144
  }
2158
2145
  static async applyDefaults(key, preview) {
2159
2146
  if (key.type !== "item") return "";
2160
- const root = AssetLoader.ROOT, scope = AssetLoader.persistentScope;
2161
2147
  const resolved = await MineRenderData.resolve(key.root);
2162
2148
  const defaults = await ItemDefaults.get(`${key.namespace}:${key.path}`, key.root);
2163
2149
  preview.components = { ...defaults, ...preview.components };
2164
2150
  if (resolved.manifest.dataVersion < 3337 && key.namespace === DEFAULT_NAMESPACE && ["potion", "splash_potion", "lingering_potion"].includes(key.path) && !Object.prototype.hasOwnProperty.call(preview.components, "minecraft:enchantment_glint_override") && await ItemTints.hasPotionEffects(preview.components["minecraft:potion_contents"], key.root)) {
2165
2151
  preview.components["minecraft:enchantment_glint_override"] = true;
2166
2152
  }
2167
- if (AssetLoader.ROOT !== root || AssetLoader.persistentScope !== scope) throw new Error("Asset sources changed while loading item defaults; retry the request");
2168
2153
  return `|data:${resolved.root}:${resolved.manifest.datasets.itemDefaults?.sha256}:${resolved.manifest.datasets.potionColors?.sha256}`;
2169
2154
  }
2170
- static sourceCheck() {
2171
- const root = AssetLoader.ROOT, scope = AssetLoader.persistentScope;
2172
- return () => {
2173
- if (AssetLoader.ROOT !== root || AssetLoader.persistentScope !== scope) throw new Error("Asset sources changed while loading item models; retry the request");
2174
- };
2175
- }
2176
2155
  static contextKey(context) {
2177
2156
  const itemReferences = Object.fromEntries(Object.entries(context.itemReferences).map(([id, key]) => [id, key.serialize()]));
2178
2157
  return `|${this.ITEM_CACHE_VERSION}:${JSON.stringify(this.snapshotJson({ ...context, itemReferences }))}`;
@@ -2359,7 +2338,6 @@ var init_Models = __esm({
2359
2338
  * @param key - Model key, for example `AssetKey.parse("models", "minecraft:item/diamond_sword")`.
2360
2339
  */
2361
2340
  static async getMerged(key, context = {}) {
2362
- const checkSources = this.sourceCheck();
2363
2341
  if (!key.assetType) {
2364
2342
  key.assetType = "models";
2365
2343
  }
@@ -2368,15 +2346,12 @@ var init_Models = __esm({
2368
2346
  }
2369
2347
  const preview = this.snapshotContext(key, context);
2370
2348
  const dataKey = await this.applyDefaults(key, preview);
2371
- checkSources();
2372
2349
  const keyStr = AssetLoader.persistentKey(key.serialize() + (key.type === "item" ? this.contextKey(preview) + dataKey : ""));
2373
2350
  const model = await Caching.mergedModelCache.get(keyStr, async () => {
2374
2351
  const raw = key.type === "item" ? await this.getPreparedItemModel(key, preview, dataKey) : await this.getRaw(key);
2375
2352
  const merged = raw ? await ModelMerger.mergeWithParents(raw) : void 0;
2376
- checkSources();
2377
2353
  return merged;
2378
2354
  });
2379
- checkSources();
2380
2355
  return model;
2381
2356
  }
2382
2357
  /** Alias for {@link getMerged}. */
@@ -12531,7 +12506,6 @@ init_AssetKey();
12531
12506
  init_ModelCulling();
12532
12507
  init_FluidGeometry();
12533
12508
  init_MineRenderData();
12534
- init_AssetLoader();
12535
12509
  init_Entities();
12536
12510
  var _BlockObject = class _BlockObject extends SceneObject {
12537
12511
  constructor(blockState3, options) {
@@ -12556,19 +12530,12 @@ var _BlockObject = class _BlockObject extends SceneObject {
12556
12530
  this.biomePosition = options?.biomePosition ? [...options.biomePosition] : void 0;
12557
12531
  }
12558
12532
  async init() {
12559
- const root = AssetLoader.ROOT, scope = AssetLoader.persistentScope;
12560
- const checkSources = () => {
12561
- if (root !== AssetLoader.ROOT || scope !== AssetLoader.persistentScope) throw new Error("Asset sources changed while loading a block; retry the request");
12562
- };
12563
12533
  this._fluidRules = await MineRenderData.get("fluids", this.blockState.key?.root);
12564
- checkSources();
12565
12534
  if (this.options.applyDefaultState) {
12566
12535
  this._setState(await BlockStateResolver.defaults(this.blockState));
12567
- checkSources();
12568
12536
  }
12569
12537
  if (this.options.initialState !== void 0) this._setState(this.options.initialState);
12570
12538
  await this.recreateModels();
12571
- checkSources();
12572
12539
  }
12573
12540
  dispose() {
12574
12541
  this.clearModels();
@@ -16483,7 +16450,6 @@ init_util2();
16483
16450
  // src/world/AnvilParser.ts
16484
16451
  init_MineRenderError();
16485
16452
  init_MineRenderData();
16486
- init_AssetLoader();
16487
16453
  init_NBTHelper();
16488
16454
 
16489
16455
  // src/world/ChunkData.ts
@@ -16754,14 +16720,12 @@ var AnvilParser = class {
16754
16720
  /** Decodes all stored chunks. Gzip, zlib, LZ4, and uncompressed payloads are supported. */
16755
16721
  static async parse(data, options = {}) {
16756
16722
  options = { ...options };
16757
- const checkSources = this.assetGuard();
16758
16723
  options.signal?.throwIfAborted();
16759
16724
  const bytes = this.bytes(data);
16760
16725
  const chunks = [];
16761
16726
  for (const location of this.locations(bytes)) {
16762
16727
  chunks.push(await this.abortable(this.readChunk(bytes, location, options), options.signal));
16763
16728
  }
16764
- checkSources();
16765
16729
  return { chunks };
16766
16730
  }
16767
16731
  /**
@@ -16772,22 +16736,12 @@ var AnvilParser = class {
16772
16736
  */
16773
16737
  static async parseChunk(data, localX, localZ, options = {}) {
16774
16738
  options = { ...options };
16775
- const checkSources = this.assetGuard();
16776
16739
  options.signal?.throwIfAborted();
16777
16740
  const bytes = this.bytes(data);
16778
16741
  const location = this.location(bytes, localX, localZ);
16779
16742
  const chunk = location ? await this.abortable(this.readChunk(bytes, location, options), options.signal) : void 0;
16780
- checkSources();
16781
16743
  return chunk;
16782
16744
  }
16783
- static assetGuard() {
16784
- const root = AssetLoader.ROOT, scope = AssetLoader.persistentScope;
16785
- return () => {
16786
- if (AssetLoader.ROOT !== root || AssetLoader.persistentScope !== scope) {
16787
- throw new MineRenderError("Asset sources changed while parsing Anvil data; retry the request");
16788
- }
16789
- };
16790
- }
16791
16745
  /**
16792
16746
  * Decodes one chunk from an `entities/r.x.z.mca` file without migrating its NBT.
16793
16747
  * @param localX - Chunk x within the region, from 0 to 31.
@@ -17508,7 +17462,6 @@ function resolveSavedEntity(entity) {
17508
17462
 
17509
17463
  // src/world/_entities/WorldEntities.ts
17510
17464
  init_BannerPatterns();
17511
- init_AssetLoader();
17512
17465
  var WorldEntities = class {
17513
17466
  constructor(scene) {
17514
17467
  this.scene = scene;
@@ -17516,10 +17469,6 @@ var WorldEntities = class {
17516
17469
  }
17517
17470
  /** Captures column ownership before asynchronous block or asset loading starts. */
17518
17471
  prepare(entities = [], column) {
17519
- const root = AssetLoader.ROOT, scope = AssetLoader.persistentScope;
17520
- const checkSources = () => {
17521
- if (root !== AssetLoader.ROOT || scope !== AssetLoader.persistentScope) throw new Error("Asset sources changed while loading saved entities; retry the request");
17522
- };
17523
17472
  const placements = entities.flatMap((entity) => {
17524
17473
  const resolved = resolveSavedEntity(entity);
17525
17474
  if (!resolved) return [];
@@ -17535,17 +17484,13 @@ var WorldEntities = class {
17535
17484
  let object4;
17536
17485
  try {
17537
17486
  if (!current()) return;
17538
- checkSources();
17539
17487
  const models = await Entities.getEntityList();
17540
- checkSources();
17541
17488
  if (!models.includes(placement.key.path) || !current()) return;
17542
17489
  const model = await Entities.getEntity(placement.key, placement.texture, { when: placement.when });
17543
- checkSources();
17544
17490
  if (!model || !current()) return;
17545
17491
  let tints = placement.tints;
17546
17492
  if (placement.woolDye) {
17547
17493
  const dye = (await BannerPatterns.getColors(placement.key.root))[placement.woolDye];
17548
- checkSources();
17549
17494
  const tint = placement.woolDye === "white" ? 15132390 : Math.floor((dye >> 16 & 255) * 0.75) << 16 | Math.floor((dye >> 8 & 255) * 0.75) << 8 | Math.floor((dye & 255) * 0.75);
17550
17495
  tints = { ...tints, wool_color: tint };
17551
17496
  }
@@ -17555,7 +17500,6 @@ var WorldEntities = class {
17555
17500
  object4.position.fromArray(placement.position).multiplyScalar(16).addScalar(-8);
17556
17501
  object4.rotation.y = placement.yaw;
17557
17502
  await object4.init();
17558
- checkSources();
17559
17503
  if (!current()) return;
17560
17504
  placement.owner.add(object4);
17561
17505
  this.scene.add(object4);