minerender 2.1.0-alpha.118 → 2.1.0-alpha.119

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.
@@ -86,6 +86,19 @@ var init_PersistentCache = __esm({
86
86
  }
87
87
  });
88
88
 
89
+ // src/util/log.ts
90
+ function prefix(prefix2) {
91
+ return `${FgGreen}MR${BgBlack}${prefix2 ?? ""}${Reset}`;
92
+ }
93
+ var Reset, FgGreen, BgBlack;
94
+ var init_log = __esm({
95
+ "src/util/log.ts"() {
96
+ Reset = "\x1B[0m";
97
+ FgGreen = "\x1B[32m";
98
+ BgBlack = "\x1B[40m";
99
+ }
100
+ });
101
+
89
102
  // src/Axis.ts
90
103
  import { Vector3 } from "three";
91
104
  function axisToVec3(axis) {
@@ -376,19 +389,6 @@ var init_CanvasCompat = __esm({
376
389
  }
377
390
  });
378
391
 
379
- // src/util/log.ts
380
- function prefix(prefix2) {
381
- return `${FgGreen}MR${BgBlack}${prefix2 ?? ""}${Reset}`;
382
- }
383
- var Reset, FgGreen, BgBlack;
384
- var init_log = __esm({
385
- "src/util/log.ts"() {
386
- Reset = "\x1B[0m";
387
- FgGreen = "\x1B[32m";
388
- BgBlack = "\x1B[40m";
389
- }
390
- });
391
-
392
392
  // src/request/Requests.ts
393
393
  import { JobCancelledError, JobQueue } from "jobqu";
394
394
  async function fetchRequest(config, defaultBaseURL) {
@@ -443,11 +443,11 @@ async function abortable(promise, signal) {
443
443
  signal.removeEventListener("abort", abort);
444
444
  }
445
445
  }
446
- var p, RequestError, RequestQueue, Requests;
446
+ var p2, RequestError, RequestQueue, Requests;
447
447
  var init_Requests = __esm({
448
448
  "src/request/Requests.ts"() {
449
449
  init_log();
450
- p = prefix("Requests");
450
+ p2 = prefix("Requests");
451
451
  RequestError = class extends Error {
452
452
  constructor(message, response, cause) {
453
453
  super(message);
@@ -474,7 +474,7 @@ var init_Requests = __esm({
474
474
  try {
475
475
  return await abortable(this.queue.add(request), signal);
476
476
  } catch (error) {
477
- console.debug(p, "Request failed", error);
477
+ console.debug(p2, "Request failed", error);
478
478
  const delay = this.retryDelay(error, request, retries);
479
479
  if (delay === void 0) {
480
480
  throw error;
@@ -639,7 +639,7 @@ var init_WrappedImage = __esm({
639
639
 
640
640
  // src/image/ImageLoader.ts
641
641
  import { Buffer as Buffer2 } from "buffer";
642
- var p2, ImageLoader;
642
+ var p3, ImageLoader;
643
643
  var init_ImageLoader = __esm({
644
644
  "src/image/ImageLoader.ts"() {
645
645
  init_CanvasCompat();
@@ -649,7 +649,7 @@ var init_ImageLoader = __esm({
649
649
  init_Requests();
650
650
  init_WrappedImage();
651
651
  init_log();
652
- p2 = prefix("ImageLoader");
652
+ p3 = prefix("ImageLoader");
653
653
  ImageLoader = class _ImageLoader {
654
654
  static _createImage() {
655
655
  return createImage();
@@ -674,7 +674,7 @@ var init_ImageLoader = __esm({
674
674
  return image;
675
675
  }
676
676
  static async loadData(src) {
677
- console.debug(p2, "loadData", src);
677
+ console.debug(p3, "loadData", src);
678
678
  const image = await this.loadCanvasData(src);
679
679
  return image.data.getImageData(0, 0, image.width, image.height);
680
680
  }
@@ -1236,8 +1236,8 @@ var require_dist = __commonJS({
1236
1236
  __assign = Object.assign || function(t) {
1237
1237
  for (var s, i = 1, n = arguments.length; i < n; i++) {
1238
1238
  s = arguments[i];
1239
- for (var p10 in s) if (Object.prototype.hasOwnProperty.call(s, p10))
1240
- t[p10] = s[p10];
1239
+ for (var p11 in s) if (Object.prototype.hasOwnProperty.call(s, p11))
1240
+ t[p11] = s[p11];
1241
1241
  }
1242
1242
  return t;
1243
1243
  };
@@ -1418,12 +1418,12 @@ var init_AssetKey = __esm({
1418
1418
  }
1419
1419
  /** Joins the type subdirectory and path without adding a namespace or file extension. */
1420
1420
  getFullPath() {
1421
- let p10 = [];
1421
+ let p11 = [];
1422
1422
  if (this.type) {
1423
- p10.push(this.type);
1423
+ p11.push(this.type);
1424
1424
  }
1425
- p10.push(this.path);
1426
- return p10.join("/");
1425
+ p11.push(this.path);
1426
+ return p11.join("/");
1427
1427
  }
1428
1428
  toNamespacedString() {
1429
1429
  return this.namespace + ":" + this.getFullPath();
@@ -1529,7 +1529,7 @@ var init_ModelMerger = __esm({
1529
1529
  merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
1530
1530
  }
1531
1531
  }
1532
- merged.hierarchy = models.map((m) => m.parent).filter((p10) => `${p10}`);
1532
+ merged.hierarchy = models.map((m) => m.parent).filter((p11) => `${p11}`);
1533
1533
  merged.hierarchy.push(`${merged.parent}`);
1534
1534
  if (model.components) merged.components = model.components;
1535
1535
  return merged;
@@ -2721,7 +2721,7 @@ var init_parser = __esm({
2721
2721
  });
2722
2722
 
2723
2723
  // src/assets/source/HostedAssetSource.ts
2724
- var import_ts_deepmerge2, p3, DEFAULT_OPTIONS, _HostedAssetSource, HostedAssetSource;
2724
+ var import_ts_deepmerge2, p4, DEFAULT_OPTIONS, _HostedAssetSource, HostedAssetSource;
2725
2725
  var init_HostedAssetSource = __esm({
2726
2726
  "src/assets/source/HostedAssetSource.ts"() {
2727
2727
  init_AssetSource();
@@ -2734,7 +2734,7 @@ var init_HostedAssetSource = __esm({
2734
2734
  init_AssetLoader();
2735
2735
  init_parser();
2736
2736
  import_ts_deepmerge2 = __toESM(require_dist());
2737
- p3 = prefix("HostedAssetSource");
2737
+ p4 = prefix("HostedAssetSource");
2738
2738
  DEFAULT_OPTIONS = {
2739
2739
  retryDefaults: true
2740
2740
  };
@@ -2746,14 +2746,14 @@ var init_HostedAssetSource = __esm({
2746
2746
  return direct;
2747
2747
  }
2748
2748
  if (key.namespace !== DEFAULT_NAMESPACE) {
2749
- console.info(p3, "Retrying", key, "with default namespace");
2749
+ console.info(p4, "Retrying", key, "with default namespace");
2750
2750
  const namespaceKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, key.root);
2751
2751
  const namespaced = await this.load(namespaceKey, parser);
2752
2752
  if (typeof namespaced !== "undefined") {
2753
2753
  return namespaced;
2754
2754
  }
2755
2755
  if (typeof key.root !== "undefined" && key.root !== AssetLoader.ROOT || typeof this.root !== "undefined" && this.root !== AssetLoader.ROOT) {
2756
- console.info(p3, "Retrying", key, "with default root+namespace");
2756
+ console.info(p4, "Retrying", key, "with default root+namespace");
2757
2757
  const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);
2758
2758
  const namespacedRooted = await this.load(namespacedRootedKey, parser);
2759
2759
  if (typeof namespacedRooted !== "undefined") {
@@ -2761,7 +2761,7 @@ var init_HostedAssetSource = __esm({
2761
2761
  }
2762
2762
  }
2763
2763
  } else if (typeof key.root !== "undefined" && key.root !== AssetLoader.ROOT || typeof this.root !== "undefined" && this.root !== AssetLoader.ROOT) {
2764
- console.info(p3, "Retrying", key, "with default root");
2764
+ console.info(p4, "Retrying", key, "with default root");
2765
2765
  const rootKey = new AssetKey(key.namespace, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);
2766
2766
  const rooted = await this.load(rootKey, parser);
2767
2767
  if (typeof rooted !== "undefined") {
@@ -2771,9 +2771,9 @@ var init_HostedAssetSource = __esm({
2771
2771
  return void 0;
2772
2772
  }
2773
2773
  async load(key, parser) {
2774
- console.info(p3, "Loading", key);
2774
+ console.info(p4, "Loading", key);
2775
2775
  const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
2776
- console.debug(p3, url);
2776
+ console.debug(p4, url);
2777
2777
  const request = { url };
2778
2778
  try {
2779
2779
  parser.config(request);
@@ -3216,7 +3216,7 @@ var init_source = __esm({
3216
3216
  });
3217
3217
 
3218
3218
  // src/assets/AssetLoader.ts
3219
- var p4, _AssetLoader, AssetLoader;
3219
+ var p5, _AssetLoader, AssetLoader;
3220
3220
  var init_AssetLoader = __esm({
3221
3221
  "src/assets/AssetLoader.ts"() {
3222
3222
  init_Assets();
@@ -3224,7 +3224,7 @@ var init_AssetLoader = __esm({
3224
3224
  init_log();
3225
3225
  init_source();
3226
3226
  init_Caching();
3227
- p4 = prefix("AssetLoader");
3227
+ p5 = prefix("AssetLoader");
3228
3228
  _AssetLoader = class _AssetLoader {
3229
3229
  static get version() {
3230
3230
  return this.ROOT.substring(this.ROOT.lastIndexOf("/") + 1);
@@ -3273,11 +3273,11 @@ ${key}` : key;
3273
3273
  if (override) {
3274
3274
  const existing = this.removeSource(key);
3275
3275
  if (existing) {
3276
- console.log(p4, "Removed existing AssetSource", key);
3276
+ console.log(p5, "Removed existing AssetSource", key);
3277
3277
  }
3278
3278
  }
3279
3279
  this._SOURCES.unshift({ key, source });
3280
- console.log(p4, "Added AssetSource", key);
3280
+ console.log(p5, "Added AssetSource", key);
3281
3281
  }
3282
3282
  /** Removes and returns the first source with this name. Call {@link Caching.clear} to reload assets. */
3283
3283
  static removeSource(key) {
@@ -3669,7 +3669,7 @@ var init_ModelGenerator = __esm({
3669
3669
 
3670
3670
  // src/UVMapper.ts
3671
3671
  import { Float32BufferAttribute as Float32BufferAttribute2, Vector2, Vector3 as Vector34 } from "three";
3672
- var p5, DEFAULT_UV, X, Y, Z, FACE_UV_AXES, UVMapper, MinecraftFaceUV;
3672
+ var p6, DEFAULT_UV, X, Y, Z, FACE_UV_AXES, UVMapper, MinecraftFaceUV;
3673
3673
  var init_UVMapper = __esm({
3674
3674
  "src/UVMapper.ts"() {
3675
3675
  init_CubeFace();
@@ -3682,7 +3682,7 @@ var init_UVMapper = __esm({
3682
3682
  init_AssetKey();
3683
3683
  init_ModelGenerator();
3684
3684
  init_log();
3685
- p5 = prefix("UVMapper");
3685
+ p6 = prefix("UVMapper");
3686
3686
  DEFAULT_UV = [0, 0, 16, 16];
3687
3687
  X = 0;
3688
3688
  Y = 1;
@@ -3943,7 +3943,7 @@ var init_UVMapper = __esm({
3943
3943
  model.elements = originalModel.elements.map((element) => ({ ...element }));
3944
3944
  }
3945
3945
  const isItemModel = !("elements" in model);
3946
- console.debug(p5, "Creating Atlas for", model.key);
3946
+ console.debug(p6, "Creating Atlas for", model.key);
3947
3947
  if (model.textures) {
3948
3948
  const promises = [];
3949
3949
  const uniqueTextureNames = [];
@@ -3957,7 +3957,7 @@ var init_UVMapper = __esm({
3957
3957
  const assetKey = AssetKey.parse("textures", textureValue, model.key);
3958
3958
  promises.push(ModelTextures.get(assetKey).then((asset2) => {
3959
3959
  if (!asset2) {
3960
- console.warn(p5, "Missing texture", assetKey);
3960
+ console.warn(p6, "Missing texture", assetKey);
3961
3961
  return;
3962
3962
  }
3963
3963
  textureMap[textureKey] = new WrappedImage(asset2);
@@ -3969,7 +3969,7 @@ var init_UVMapper = __esm({
3969
3969
  }
3970
3970
  await Promise.all(promises);
3971
3971
  const textureCount = uniqueTextureNames.length;
3972
- console.debug(p5, "Creating Atlas for", textureCount, "textures");
3972
+ console.debug(p6, "Creating Atlas for", textureCount, "textures");
3973
3973
  this.fillMissingTextureKeys(model.textures, textureMap);
3974
3974
  this.fillMissingTextureKeys(model.textures, metaMap);
3975
3975
  const sizes = {};
@@ -4000,7 +4000,7 @@ var init_UVMapper = __esm({
4000
4000
  this.fillMissingTextureKeys(model.textures, sizes);
4001
4001
  const s = Math.ceil(Math.sqrt(textureCount + 1));
4002
4002
  const size = Math.ceil(s * maxWidth);
4003
- console.debug(p5, "Atlas size:", size);
4003
+ console.debug(p6, "Atlas size:", size);
4004
4004
  const squaredSize = size * size;
4005
4005
  const image = new CanvasImage(size, size);
4006
4006
  const missing = Textures.getMissing().image;
@@ -4079,7 +4079,7 @@ var init_UVMapper = __esm({
4079
4079
  }
4080
4080
  this.fillMissingTextureKeys(model.textures, positions);
4081
4081
  if (isItemModel) {
4082
- console.debug(p5, "Generating item model for", model);
4082
+ console.debug(p6, "Generating item model for", model);
4083
4083
  model.elements = [];
4084
4084
  for (let layerName of ModelGenerator.ITEM_LAYERS) {
4085
4085
  const textureImage = textureMap[layerName];
@@ -4095,7 +4095,7 @@ var init_UVMapper = __esm({
4095
4095
  ), layerName));
4096
4096
  }
4097
4097
  }
4098
- console.debug(p5, "Item model elements", model.elements);
4098
+ console.debug(p6, "Item model elements", model.elements);
4099
4099
  }
4100
4100
  if (!model.elements) {
4101
4101
  }
@@ -4152,7 +4152,7 @@ var init_UVMapper = __esm({
4152
4152
  hasTranslucency
4153
4153
  );
4154
4154
  } else {
4155
- console.warn(p5, "Model does not have any textures", model);
4155
+ console.warn(p6, "Model does not have any textures", model);
4156
4156
  }
4157
4157
  return void 0;
4158
4158
  }
@@ -4672,7 +4672,7 @@ import { Color as Color2, Euler as Euler4, InstancedBufferAttribute, InstancedMe
4672
4672
  function isSceneObject(obj) {
4673
4673
  return obj.isSceneObject;
4674
4674
  }
4675
- var import_ts_deepmerge3, p6, _SceneObject, SceneObject;
4675
+ var import_ts_deepmerge3, p7, _SceneObject, SceneObject;
4676
4676
  var init_SceneObject = __esm({
4677
4677
  "src/renderer/SceneObject.ts"() {
4678
4678
  init_Geometries();
@@ -4685,7 +4685,7 @@ var init_SceneObject = __esm({
4685
4685
  init_Disposable();
4686
4686
  import_ts_deepmerge3 = __toESM(require_dist());
4687
4687
  init_log();
4688
- p6 = prefix("SceneObject");
4688
+ p7 = prefix("SceneObject");
4689
4689
  _SceneObject = class _SceneObject extends Object3D2 {
4690
4690
  constructor(options) {
4691
4691
  super();
@@ -6942,7 +6942,7 @@ import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color
6942
6942
  function isModelObject(obj) {
6943
6943
  return obj.isModelObject;
6944
6944
  }
6945
- var import_ts_deepmerge5, p7, _ModelObject, ModelObject;
6945
+ var import_ts_deepmerge5, p8, _ModelObject, ModelObject;
6946
6946
  var init_ModelObject = __esm({
6947
6947
  "src/model/scene/ModelObject.ts"() {
6948
6948
  init_SceneObject();
@@ -6961,7 +6961,7 @@ var init_ModelObject = __esm({
6961
6961
  init_GuiLight();
6962
6962
  init_ItemTints();
6963
6963
  init_ItemGlint();
6964
- p7 = prefix("ModelObject");
6964
+ p8 = prefix("ModelObject");
6965
6965
  _ModelObject = class _ModelObject extends SceneObject {
6966
6966
  constructor(originalModel, options) {
6967
6967
  super(options);
@@ -7134,10 +7134,10 @@ var init_ModelObject = __esm({
7134
7134
  }
7135
7135
  });
7136
7136
  } else {
7137
- console.debug(p7, this.atlas.model, "has no elements");
7137
+ console.debug(p8, this.atlas.model, "has no elements");
7138
7138
  }
7139
7139
  } else {
7140
- console.debug(p7, "Missing atlas for", this);
7140
+ console.debug(p8, "Missing atlas for", this);
7141
7141
  }
7142
7142
  if (this.options.mergeMeshes) {
7143
7143
  let combinedGeo;
@@ -7490,32 +7490,53 @@ import localforage from "localforage";
7490
7490
 
7491
7491
  // src/env/browser/BrowserCache.ts
7492
7492
  init_PersistentCache();
7493
+ init_log();
7494
+ var p = prefix("BrowserCache");
7493
7495
  var BrowserCache = class extends PersistentCache {
7494
7496
  constructor(backing) {
7495
7497
  super(backing);
7496
7498
  }
7499
+ async initialize() {
7500
+ try {
7501
+ await this.backing.ready();
7502
+ return true;
7503
+ } catch (error) {
7504
+ this.memory = /* @__PURE__ */ new Map();
7505
+ console.warn(p, "Could not open browser storage; using an in-memory store", error);
7506
+ return false;
7507
+ }
7508
+ }
7509
+ async run(operation, fallback) {
7510
+ if (await (this.initialized ?? (this.initialized = this.initialize()))) return operation();
7511
+ return fallback(this.memory);
7512
+ }
7497
7513
  get(key) {
7498
- return this.backing.getItem(key);
7514
+ return this.run(() => this.backing.getItem(key), (memory) => memory.get(key));
7499
7515
  }
7500
7516
  put(key, value) {
7501
- return this.backing.setItem(key, value);
7517
+ return this.run(() => this.backing.setItem(key, value), (memory) => {
7518
+ memory.set(key, value);
7519
+ return value;
7520
+ });
7502
7521
  }
7503
7522
  delete(key) {
7504
- return this.backing.removeItem(key);
7523
+ return this.run(() => this.backing.removeItem(key), (memory) => {
7524
+ memory.delete(key);
7525
+ });
7505
7526
  }
7506
7527
  clear() {
7507
- return this.backing.clear();
7528
+ return this.run(() => this.backing.clear(), (memory) => memory.clear());
7508
7529
  }
7509
7530
  length() {
7510
- return this.backing.length();
7531
+ return this.run(() => this.backing.length(), (memory) => memory.size);
7511
7532
  }
7512
7533
  keys() {
7513
- return this.backing.keys();
7534
+ return this.run(() => this.backing.keys(), (memory) => [...memory.keys()]);
7514
7535
  }
7515
7536
  forEach(callback) {
7516
- return this.backing.iterate((v, k) => {
7517
- callback(v, k);
7518
- });
7537
+ return this.run(() => this.backing.iterate((value, key) => {
7538
+ callback(value, key);
7539
+ }), (memory) => memory.forEach((value, key) => callback(value, key)));
7519
7540
  }
7520
7541
  };
7521
7542
 
@@ -7722,7 +7743,7 @@ function createPermutation() {
7722
7743
  return values;
7723
7744
  }
7724
7745
  function swampGrassColor(x, z) {
7725
- const p10 = permutation ?? (permutation = createPermutation());
7746
+ const p11 = permutation ?? (permutation = createPermutation());
7726
7747
  x *= 0.0225;
7727
7748
  z *= 0.0225;
7728
7749
  const s = (x + z) * skew;
@@ -7733,7 +7754,7 @@ function swampGrassColor(x, z) {
7733
7754
  const corner = (gx, gz, a, b) => {
7734
7755
  let falloff = 0.5 - a * a - b * b;
7735
7756
  if (falloff < 0) return 0;
7736
- const gradient = gradients[p10[gx + p10[gz & 255] & 255] % 12];
7757
+ const gradient = gradients[p11[gx + p11[gz & 255] & 255] % 12];
7737
7758
  falloff *= falloff;
7738
7759
  return falloff * falloff * (gradient[0] * a + gradient[1] * b);
7739
7760
  };
@@ -11737,7 +11758,7 @@ init_util();
11737
11758
  import { Raycaster, Vector2 as Vector25 } from "three";
11738
11759
  init_log();
11739
11760
  init_three();
11740
- var p8 = prefix("SceneInspector");
11761
+ var p9 = prefix("SceneInspector");
11741
11762
  var help = "<span>Ctrl/Cmd+Click to Select<br/></span><br/>";
11742
11763
  var SceneInspector = class {
11743
11764
  constructor(renderer) {
@@ -11831,7 +11852,7 @@ var SceneInspector = class {
11831
11852
  }
11832
11853
  selectObject(targetObject, targetIntersection, instance = this.getIntersectionInstance(targetIntersection)) {
11833
11854
  this.selectedObject = targetObject;
11834
- console.log(p8, "selected", targetObject);
11855
+ console.log(p9, "selected", targetObject);
11835
11856
  this.redraw(targetObject, targetIntersection, instance);
11836
11857
  }
11837
11858
  redraw(targetObject, targetIntersection, instance) {
@@ -12091,7 +12112,7 @@ var SceneStatsDisplay = class {
12091
12112
 
12092
12113
  // src/instance/InstanceManager.ts
12093
12114
  init_log();
12094
- var p9 = prefix("InstanceManager");
12115
+ var p10 = prefix("InstanceManager");
12095
12116
  var InstanceManager = class {
12096
12117
  constructor() {
12097
12118
  this.isInstanceManager = true;
@@ -12100,7 +12121,7 @@ var InstanceManager = class {
12100
12121
  /** Allocates a new placement of a cached model, or returns `undefined` if the key is unknown. */
12101
12122
  async get(key) {
12102
12123
  if (key in this.instanceCache) {
12103
- console.debug(p9, "key in cache", key);
12124
+ console.debug(p10, "key in cache", key);
12104
12125
  return (await this.instanceCache[key]).nextInstance();
12105
12126
  }
12106
12127
  return void 0;
@@ -12110,7 +12131,7 @@ var InstanceManager = class {
12110
12131
  if (key in this.instanceCache) {
12111
12132
  return await this.get(key);
12112
12133
  }
12113
- console.debug(p9, "key not in cache", key);
12134
+ console.debug(p10, "key not in cache", key);
12114
12135
  const pending = Promise.resolve().then(supplier).then((obj) => obj.nextInstance());
12115
12136
  this.instanceCache[key] = pending;
12116
12137
  try {
@@ -16105,6 +16126,79 @@ function parseSceneDocument(value) {
16105
16126
  return JSON.parse(JSON.stringify(input));
16106
16127
  }
16107
16128
 
16129
+ // src/scene/SceneDocumentCodec.ts
16130
+ var SCENE_DOCUMENT_MAX_BYTES = 1024 * 1024;
16131
+ async function readBounded(stream, label) {
16132
+ const reader = stream.getReader();
16133
+ const chunks = [];
16134
+ let size = 0;
16135
+ try {
16136
+ while (true) {
16137
+ const { value, done } = await reader.read();
16138
+ if (done) break;
16139
+ size += value.byteLength;
16140
+ if (size > SCENE_DOCUMENT_MAX_BYTES) throw new RangeError(`${label} exceeds ${SCENE_DOCUMENT_MAX_BYTES} bytes`);
16141
+ chunks.push(value);
16142
+ }
16143
+ } catch (error) {
16144
+ await reader.cancel().catch(() => {
16145
+ });
16146
+ throw error;
16147
+ } finally {
16148
+ reader.releaseLock();
16149
+ }
16150
+ const bytes = new Uint8Array(size);
16151
+ let offset = 0;
16152
+ for (const chunk of chunks) {
16153
+ bytes.set(chunk, offset);
16154
+ offset += chunk.byteLength;
16155
+ }
16156
+ return bytes;
16157
+ }
16158
+ function encodeBase64(bytes) {
16159
+ let binary = "";
16160
+ for (let offset = 0; offset < bytes.length; offset += 32768) {
16161
+ binary += String.fromCharCode(...bytes.subarray(offset, offset + 32768));
16162
+ }
16163
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
16164
+ }
16165
+ async function encodeSceneDocument(value) {
16166
+ const scene = parseSceneDocument(value);
16167
+ const bytes = new TextEncoder().encode(JSON.stringify(scene));
16168
+ if (bytes.byteLength > SCENE_DOCUMENT_MAX_BYTES) {
16169
+ throw new RangeError(`Scene document exceeds ${SCENE_DOCUMENT_MAX_BYTES} bytes`);
16170
+ }
16171
+ const compressed = await readBounded(new Blob([bytes]).stream().pipeThrough(new CompressionStream("deflate")), "Encoded scene");
16172
+ return `v1.${encodeBase64(compressed)}`;
16173
+ }
16174
+ async function decodeSceneDocument(value) {
16175
+ if (!value.startsWith("v1.")) throw new Error("Unsupported scene encoding version; expected v1");
16176
+ const encoded = value.slice(3);
16177
+ if (encoded.length > Math.ceil(SCENE_DOCUMENT_MAX_BYTES * 4 / 3)) {
16178
+ throw new RangeError(`Encoded scene exceeds ${SCENE_DOCUMENT_MAX_BYTES} bytes`);
16179
+ }
16180
+ if (!/^[A-Za-z0-9_-]+$/.test(encoded) || encoded.length % 4 === 1) {
16181
+ throw new Error("Invalid scene base64url encoding");
16182
+ }
16183
+ const binary = atob(encoded.replace(/-/g, "+").replace(/_/g, "/"));
16184
+ const compressed = Uint8Array.from(binary, (character) => character.charCodeAt(0));
16185
+ if (encodeBase64(compressed) !== encoded) throw new Error("Invalid scene base64url encoding");
16186
+ let bytes;
16187
+ try {
16188
+ bytes = await readBounded(new Blob([compressed]).stream().pipeThrough(new DecompressionStream("deflate")), "Scene document");
16189
+ } catch (error) {
16190
+ if (error instanceof RangeError) throw error;
16191
+ throw new Error("Invalid compressed scene document");
16192
+ }
16193
+ let json;
16194
+ try {
16195
+ json = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
16196
+ } catch {
16197
+ throw new Error("Invalid UTF-8 scene document");
16198
+ }
16199
+ return parseSceneDocument(json);
16200
+ }
16201
+
16108
16202
  // src/scene/SceneDocumentLoader.ts
16109
16203
  init_AssetKey();
16110
16204
  init_AssetLoader();
@@ -19026,6 +19120,7 @@ export {
19026
19120
  Renderer,
19027
19121
  RequestError,
19028
19122
  Requests,
19123
+ SCENE_DOCUMENT_MAX_BYTES,
19029
19124
  SKIN_PARTS,
19030
19125
  SceneDocumentLoader,
19031
19126
  SceneExporter,
@@ -19077,6 +19172,8 @@ export {
19077
19172
  createGuiTextGeometry,
19078
19173
  createGuiTextureGeometry,
19079
19174
  createImage,
19175
+ decodeSceneDocument,
19176
+ encodeSceneDocument,
19080
19177
  entityAnimationTime,
19081
19178
  estimateBytesUsed,
19082
19179
  fluidKindOf,