@woosh/meep-engine 2.74.0 → 2.75.1

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 (38) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/meep.cjs +202 -204
  3. package/build/meep.min.js +1 -1
  4. package/build/meep.module.js +202 -204
  5. package/package.json +1 -1
  6. package/src/core/binary/UINT32_MAX.js +5 -0
  7. package/src/core/bvh2/bvh3/BVH.js +44 -2
  8. package/src/core/bvh2/bvh3/BVH.spec.js +45 -0
  9. package/src/core/bvh2/bvh3/build_triangle_morton_codes.js +73 -0
  10. package/src/core/bvh2/bvh3/ebvh_build_for_geometry_morton.js +5 -101
  11. package/src/core/bvh2/bvh3/ebvh_build_hierarchy.js +59 -0
  12. package/src/core/bvh2/bvh3/query/bvh_query_user_data_nearest_to_point.js +31 -32
  13. package/src/core/bvh2/bvh3/query/bvh_query_user_data_nearest_to_point.spec.js +139 -0
  14. package/src/core/collection/SCRATCH_UINT32_TRAVERSAL_STACK.js +1 -0
  15. package/src/core/events/signal/SignalBinding.js +18 -16
  16. package/src/core/geom/3d/aabb/aabb3_signed_distance_sqr_to_point.js +1 -0
  17. package/src/core/geom/3d/aabb/aabb3_unsigned_distance_sqr_to_point.js +36 -0
  18. package/src/core/model/ObservedBoolean.js +1 -1
  19. package/src/core/process/worker/OnDemandWorkerManager.js +5 -1
  20. package/src/engine/asset/loaders/ArrayBufferLoader.js +13 -15
  21. package/src/engine/asset/loaders/image/ImageDecoderWorker.js +1 -1
  22. package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +5 -7
  23. package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.js +1 -1
  24. package/src/engine/asset/loaders/image/png/PNG.js +339 -332
  25. package/src/engine/asset/loaders/image/png/PNGReader.js +59 -16
  26. package/src/engine/asset/loaders/image/png/prototypePNG.js +13 -4
  27. package/src/engine/graphics/texture/virtual/v2/{SparseTexture.js → PageTexture.js} +62 -18
  28. package/src/engine/graphics/texture/virtual/v2/ResidentTileTexture.js +46 -0
  29. package/src/engine/graphics/texture/virtual/v2/{TileLoader.js → VirtualTextureTileLoader.js} +11 -8
  30. package/src/engine/graphics/texture/virtual/v2/{UsageMetadata.js → VirtualTextureUsage.js} +2 -8
  31. package/src/engine/graphics/texture/virtual/v2/{VirtualTextureManager.js → VirtualTextureUsageUpdater.js} +7 -5
  32. package/src/engine/graphics/texture/virtual/v2/debug/ResidencyDebugView.js +17 -5
  33. package/src/engine/graphics/texture/virtual/v2/debug/UsageDebugView.js +1 -1
  34. package/src/engine/graphics/texture/virtual/v2/debug/UsagePyramidDebugView.js +1 -1
  35. package/src/engine/graphics/texture/virtual/v2/prototype.js +78 -59
  36. package/src/engine/graphics/texture/virtual/v2/tile/{TextureTile.js → VirtualTextureTile.js} +2 -2
  37. package/src/engine/graphics/texture/virtual/v2/tile/compose_tile_address.js +4 -0
  38. /package/src/engine/graphics/texture/virtual/v2/{ShaderUsage.js → VirtualTextureUsageShader.js} +0 -0
package/build/meep.cjs CHANGED
@@ -53660,6 +53660,12 @@ class TerrainPreview {
53660
53660
  }
53661
53661
  }
53662
53662
 
53663
+ /**
53664
+ * equal to `Math.pow(2,32) - 1`
53665
+ * @type {number}
53666
+ */
53667
+ const UINT32_MAX = 4294967295;
53668
+
53663
53669
  /**
53664
53670
  * Assumes arrays have the same type
53665
53671
  * @param {TypedArray|Float32Array|Uint8Array|Uint32Array} source
@@ -53739,6 +53745,13 @@ const ELEMENT_WORD_COUNT = 10;
53739
53745
  */
53740
53746
  const INITIAL_CAPACITY = 128;
53741
53747
 
53748
+
53749
+ /**
53750
+ * Tree can not contain more than this number of nodes
53751
+ * @type {number}
53752
+ */
53753
+ const NODE_CAPACITY_LIMIT = Math.floor(UINT32_MAX / (ELEMENT_WORD_COUNT * 4));
53754
+
53742
53755
  /**
53743
53756
  * Bounding Volume Hierarchy implementation. Stores unsigned integer values at leaves, these are typically IDs or Index values.
53744
53757
  * Highly optimized both in terms of memory usage and CPU. Most of the code inlined. No allocation are performed during usage (except for growing the tree capacity).
@@ -53833,17 +53846,26 @@ class BVH {
53833
53846
  }
53834
53847
 
53835
53848
  __grow_capacity() {
53836
- const new_capacity = Math.ceil(max2(
53849
+ if (this.__capacity >= NODE_CAPACITY_LIMIT) {
53850
+ throw new Error('Can not grow capacity, already at maximum platform limit');
53851
+ }
53852
+
53853
+ let new_capacity = Math.ceil(max2(
53837
53854
  this.__capacity * CAPACITY_GROW_MULTIPLIER,
53838
53855
  this.__capacity + CAPACITY_GROW_MIN_STEP
53839
53856
  ));
53840
53857
 
53858
+ if (new_capacity > NODE_CAPACITY_LIMIT) {
53859
+ // can not grow as much as we'd like, but we can still grow up to the limit
53860
+ new_capacity = NODE_CAPACITY_LIMIT;
53861
+ }
53862
+
53841
53863
  this.__set_capacity(new_capacity);
53842
53864
  }
53843
53865
 
53844
53866
  /**
53845
53867
  *
53846
- * @param {number} new_capacity
53868
+ * @param {number} new_capacity in number of nodes
53847
53869
  * @private
53848
53870
  */
53849
53871
  __set_capacity(new_capacity) {
@@ -54395,6 +54417,9 @@ class BVH {
54395
54417
  assert.notEqual(child1, NULL_NODE, 'child1 is null');
54396
54418
  assert.notEqual(child2, NULL_NODE, 'child2 is null');
54397
54419
 
54420
+ assert.notEqual(child1, index, 'child1 is equal to parent');
54421
+ assert.notEqual(child2, index, 'child2 is equal to parent');
54422
+
54398
54423
  this.node_set_combined_aabb(index, child1, child2);
54399
54424
 
54400
54425
  index = uint32[address + COLUMN_PARENT];
@@ -54422,6 +54447,9 @@ class BVH {
54422
54447
  assert.notEqual(child1, NULL_NODE, 'child1 is null');
54423
54448
  assert.notEqual(child2, NULL_NODE, 'child2 is null');
54424
54449
 
54450
+ assert.notEqual(child1, index, 'child1 is equal to parent');
54451
+ assert.notEqual(child2, index, 'child2 is equal to parent');
54452
+
54425
54453
  uint32[node_address + COLUMN_HEIGHT] = 1 + max2(
54426
54454
  uint32[child1 * ELEMENT_WORD_COUNT + COLUMN_HEIGHT],
54427
54455
  uint32[child2 * ELEMENT_WORD_COUNT + COLUMN_HEIGHT],
@@ -54503,6 +54531,9 @@ class BVH {
54503
54531
  const iB = uint32[iA * ELEMENT_WORD_COUNT + COLUMN_CHILD_1];
54504
54532
  const iC = uint32[iA * ELEMENT_WORD_COUNT + COLUMN_CHILD_2];
54505
54533
 
54534
+ assert.notEqual(iA, iB, 'child1 equal to parent');
54535
+ assert.notEqual(iA, iB, 'child2 equal to parent');
54536
+
54506
54537
  assert.greaterThanOrEqual(iB, 0);
54507
54538
  assert.lessThan(iB, this.node_capacity);
54508
54539
  assert.greaterThanOrEqual(iC, 0);
@@ -54518,6 +54549,9 @@ class BVH {
54518
54549
  const iF = uint32[iC * ELEMENT_WORD_COUNT + COLUMN_CHILD_1];
54519
54550
  const iG = uint32[iC * ELEMENT_WORD_COUNT + COLUMN_CHILD_2];
54520
54551
 
54552
+ assert.notEqual(iC, iF, 'child1 equal to parent');
54553
+ assert.notEqual(iC, iG, 'child2 equal to parent');
54554
+
54521
54555
  // b2TreeNode* F = m_nodes + iF;
54522
54556
  // b2TreeNode* G = m_nodes + iG;
54523
54557
 
@@ -54536,6 +54570,7 @@ class BVH {
54536
54570
 
54537
54571
  // A's old parent should point to C
54538
54572
  if (a_parent !== NULL_NODE) {
54573
+ assert.notEqual(a_parent, iC);
54539
54574
  if (uint32[a_parent * ELEMENT_WORD_COUNT + COLUMN_CHILD_1] === iA) {
54540
54575
  uint32[a_parent * ELEMENT_WORD_COUNT + COLUMN_CHILD_1] = iC;
54541
54576
  } else {
@@ -54588,6 +54623,9 @@ class BVH {
54588
54623
 
54589
54624
  }
54590
54625
 
54626
+ assert.notEqual(iC, uint32[iC * ELEMENT_WORD_COUNT + COLUMN_CHILD_1]);
54627
+ assert.notEqual(iC, uint32[iC * ELEMENT_WORD_COUNT + COLUMN_CHILD_2]);
54628
+
54591
54629
  return iC;
54592
54630
  }
54593
54631
 
@@ -54596,6 +54634,9 @@ class BVH {
54596
54634
  const iD = uint32[iB * ELEMENT_WORD_COUNT + COLUMN_CHILD_1];
54597
54635
  const iE = uint32[iB * ELEMENT_WORD_COUNT + COLUMN_CHILD_2];
54598
54636
 
54637
+ assert.notEqual(iB, iD, 'child1 equal to parent');
54638
+ assert.notEqual(iB, iE, 'child2 equal to parent');
54639
+
54599
54640
  assert.greaterThanOrEqual(iD, 0);
54600
54641
  assert.lessThan(iD, this.node_capacity);
54601
54642
  assert.greaterThanOrEqual(iE, 0);
@@ -54662,9 +54703,15 @@ class BVH {
54662
54703
 
54663
54704
  }
54664
54705
 
54706
+ assert.notEqual(iB, uint32[iB * ELEMENT_WORD_COUNT + COLUMN_CHILD_1]);
54707
+ assert.notEqual(iB, uint32[iB * ELEMENT_WORD_COUNT + COLUMN_CHILD_2]);
54708
+
54665
54709
  return iB;
54666
54710
  }
54667
54711
 
54712
+ assert.notEqual(iA, uint32[iA * ELEMENT_WORD_COUNT + COLUMN_CHILD_1]);
54713
+ assert.notEqual(iA, uint32[iA * ELEMENT_WORD_COUNT + COLUMN_CHILD_2]);
54714
+
54668
54715
  // no rotation
54669
54716
  return iA;
54670
54717
  }
@@ -54825,6 +54872,7 @@ const SCRATCH_UINT32_TRAVERSAL_STACK = new Uint32Array(781250);
54825
54872
 
54826
54873
  /**
54827
54874
  * Pointer used to track current top of the stack, make sure to unwind once your traversal is done
54875
+ * Must be a positive integer
54828
54876
  * @type {number}
54829
54877
  */
54830
54878
  SCRATCH_UINT32_TRAVERSAL_STACK.pointer = 0;
@@ -68902,50 +68950,49 @@ function bvh_query_user_data_overlaps_frustum(
68902
68950
  return result_cursor - result_offset;
68903
68951
  }
68904
68952
 
68953
+ const PATH_SEPARATOR = '/';
68954
+
68905
68955
  /**
68906
- * @template CTX
68907
- * @template Asset
68956
+ * Strips all directories from the path.
68957
+ * @example 'a/b/c' -> 'c'
68958
+ * @param {string} path
68959
+ * @returns {string}
68908
68960
  */
68909
- class AssetLoader {
68910
- /**
68911
- *
68912
- * @type {AssetManager}
68913
- */
68914
- assetManager = null;
68961
+ function computePathBase(path) {
68962
+ if (typeof path !== "string") {
68963
+ throw new Error('path is not a string');
68964
+ }
68915
68965
 
68916
- /**
68917
- *
68918
- * @type {CTX}
68919
- */
68920
- context = null;
68966
+ const lastSlashIndex = path.lastIndexOf(PATH_SEPARATOR);
68921
68967
 
68922
- /**
68923
- *
68924
- * @param {AssetManager} assetManager
68925
- * @param {CTX} context
68926
- */
68927
- async link(assetManager, context) {
68928
- this.assetManager = assetManager;
68929
- this.context = context;
68968
+ if (lastSlashIndex !== -1) {
68969
+ return path.substring(lastSlashIndex + 1);
68970
+ } else {
68971
+ return path;
68972
+ }
68973
+ }
68974
+
68975
+ /**
68976
+ *
68977
+ * @param {string} path
68978
+ * @returns {String|null}
68979
+ */
68980
+ function computeFileExtension(path) {
68981
+ const type_of_path = typeof path;
68982
+ if (type_of_path !== "string") {
68983
+ throw new Error(`path must be a string, instead was '${type_of_path}'`);
68930
68984
  }
68931
68985
 
68932
- /**
68933
- * Release any held resources, finalizing operation of the loader
68934
- */
68935
- async unlink() {
68986
+ //get base
68987
+ const pathBase = computePathBase(path);
68936
68988
 
68937
- }
68989
+ const lastDotIndex = pathBase.lastIndexOf('.');
68938
68990
 
68939
- /**
68940
- *
68941
- * @param {AssetRequestScope} scope
68942
- * @param {string} path
68943
- * @param {function(Asset)} success
68944
- * @param {function} failure
68945
- * @param {function(current:number, total:number)} progress
68946
- */
68947
- load(scope, path, success, failure, progress) {
68948
- failure('Not Implemented');
68991
+ if (lastDotIndex !== -1) {
68992
+ return pathBase.substring(lastDotIndex + 1);
68993
+ } else {
68994
+ //no extension
68995
+ return null;
68949
68996
  }
68950
68997
  }
68951
68998
 
@@ -69156,49 +69203,6 @@ class Asset {
69156
69203
 
69157
69204
  Asset.prototype.byteSize = 0;
69158
69205
 
69159
- class ImageRGBADataAsset extends Asset {
69160
- /**
69161
- *
69162
- * @param {number[]|Uint8Array} data
69163
- * @param {number} width
69164
- * @param {number} height
69165
- * @param {number} [itemSize]
69166
- */
69167
- constructor(data, width, height, itemSize = 4) {
69168
- super();
69169
-
69170
- /**
69171
- *
69172
- * @type {number[]}
69173
- */
69174
- this.data = data;
69175
-
69176
- /**
69177
- *
69178
- * @type {number}
69179
- */
69180
- this.width = width;
69181
-
69182
- /**
69183
- *
69184
- * @type {number}
69185
- */
69186
- this.height = height;
69187
-
69188
- /**
69189
- * Number of channels
69190
- * @type {number}
69191
- */
69192
- this.itemSize = itemSize;
69193
-
69194
- this.byteSize = data.length;
69195
- }
69196
-
69197
- create() {
69198
- return new Sampler2D(this.data, this.itemSize, this.width, this.height);
69199
- }
69200
- }
69201
-
69202
69206
  const CrossOriginKind = {
69203
69207
  UseCredentials: 'use-credentials',
69204
69208
  Anonymous: 'anonymous'
@@ -69214,6 +69218,53 @@ class CrossOriginConfig {
69214
69218
  const default_coc = new CrossOriginConfig();
69215
69219
  CrossOriginConfig.default = Object.freeze(default_coc);
69216
69220
 
69221
+ /**
69222
+ * @template CTX
69223
+ * @template Asset
69224
+ */
69225
+ class AssetLoader {
69226
+ /**
69227
+ *
69228
+ * @type {AssetManager}
69229
+ */
69230
+ assetManager = null;
69231
+
69232
+ /**
69233
+ *
69234
+ * @type {CTX}
69235
+ */
69236
+ context = null;
69237
+
69238
+ /**
69239
+ *
69240
+ * @param {AssetManager} assetManager
69241
+ * @param {CTX} context
69242
+ */
69243
+ async link(assetManager, context) {
69244
+ this.assetManager = assetManager;
69245
+ this.context = context;
69246
+ }
69247
+
69248
+ /**
69249
+ * Release any held resources, finalizing operation of the loader
69250
+ */
69251
+ async unlink() {
69252
+
69253
+ }
69254
+
69255
+ /**
69256
+ *
69257
+ * @param {AssetRequestScope} scope
69258
+ * @param {string} path
69259
+ * @param {function(Asset)} success
69260
+ * @param {function} failure
69261
+ * @param {function(current:number, total:number)} progress
69262
+ */
69263
+ load(scope, path, success, failure, progress) {
69264
+ failure('Not Implemented');
69265
+ }
69266
+ }
69267
+
69217
69268
  class ArrayBufferLoader extends AssetLoader {
69218
69269
  /**
69219
69270
  *
@@ -69298,33 +69349,33 @@ class ArrayBufferLoader extends AssetLoader {
69298
69349
  }
69299
69350
 
69300
69351
  const reader = response.body.getReader();
69301
- response.headers.get('Content-Length');
69352
+ const contentLength = response.headers.get('Content-Length');
69353
+ const total = contentLength ? parseInt(contentLength) : 0;
69302
69354
  let loaded = 0;
69303
69355
 
69304
69356
  // periodically read data into the new stream tracking while download progress
69305
69357
  const stream = new ReadableStream({
69358
+ type: "bytes",
69306
69359
  start(controller) {
69307
69360
 
69308
- readData();
69361
+ pump();
69309
69362
 
69310
- function readData() {
69363
+ function pump() {
69311
69364
 
69312
69365
  reader.read().then(({ done, value }) => {
69313
69366
 
69314
69367
  if (done) {
69315
-
69368
+ // no more data, we're done
69316
69369
  controller.close();
69370
+ return;
69371
+ }
69317
69372
 
69318
- } else {
69319
-
69320
- loaded += value.byteLength;
69321
-
69322
- progress(loaded, length);
69373
+ loaded += value.byteLength;
69323
69374
 
69324
- controller.enqueue(value);
69325
- readData();
69375
+ progress(loaded, total);
69326
69376
 
69327
- }
69377
+ controller.enqueue(value);
69378
+ pump();
69328
69379
 
69329
69380
  });
69330
69381
 
@@ -69468,6 +69519,10 @@ class OnDemandWorkerManager {
69468
69519
  this.worker = worker;
69469
69520
  }
69470
69521
 
69522
+ /**
69523
+ * In milliseconds
69524
+ * @param {number} v
69525
+ */
69471
69526
  setTimeout(v) {
69472
69527
  assert.isNonNegativeInteger(v, 'v');
69473
69528
 
@@ -69574,7 +69629,7 @@ class ThreadedImageDecoder extends Codec {
69574
69629
  */
69575
69630
  this.worker = new OnDemandWorkerManager(workerBuilder.build());
69576
69631
 
69577
- this.worker.setTimeout(200);
69632
+ this.worker.setTimeout(1200);
69578
69633
  }
69579
69634
 
69580
69635
  async test(data) {
@@ -69593,104 +69648,46 @@ class ThreadedImageDecoder extends Codec {
69593
69648
  }
69594
69649
  }
69595
69650
 
69596
- /**
69597
- *
69598
- * @param {Image|ImageBitmap|HTMLImageElement} img
69599
- * @returns {Uint8Array}
69600
- */
69601
- function decode(img) {
69602
- const imgWidth = img.width;
69603
- const imgHeight = img.height;
69604
-
69605
- //
69606
- const canvas = document.createElement('canvas');
69607
-
69608
- canvas.width = imgWidth;
69609
- canvas.height = imgHeight;
69610
-
69611
- const context = canvas.getContext('2d');
69612
-
69613
- context.drawImage(img, 0, 0, imgWidth, imgHeight);
69614
-
69615
- const imgd = context.getImageData(0, 0, imgWidth, imgHeight);
69616
-
69617
- return imgd.data;
69618
- }
69619
-
69620
- class NativeImageDecoder extends Codec {
69621
- async decode(data) {
69622
- const image = new Image();
69623
-
69624
- // convert binary data to image URL that we can load
69625
- const blob = new Blob([data]);
69626
- const url = URL.createObjectURL(blob);
69627
-
69628
- image.src = url;
69629
-
69630
- // give browser a chance to decode image in async
69631
- await image.decode();
69632
-
69633
- const rgba_data = decode(image);
69651
+ class ImageRGBADataAsset extends Asset {
69652
+ /**
69653
+ *
69654
+ * @param {number[]|Uint8Array} data
69655
+ * @param {number} width
69656
+ * @param {number} height
69657
+ * @param {number} [itemSize]
69658
+ */
69659
+ constructor(data, width, height, itemSize = 4) {
69660
+ super();
69634
69661
 
69635
- const width = image.width;
69636
- const height = image.height;
69662
+ /**
69663
+ *
69664
+ * @type {number[]}
69665
+ */
69666
+ this.data = data;
69637
69667
 
69638
- // release resources
69639
- URL.revokeObjectURL(url);
69668
+ /**
69669
+ *
69670
+ * @type {number}
69671
+ */
69672
+ this.width = width;
69640
69673
 
69641
- return {
69642
- data: rgba_data,
69643
- width: width,
69644
- height: height,
69645
- itemSize: 4,
69646
- bitDepth: 8
69647
- };
69648
- }
69649
- }
69650
-
69651
- const PATH_SEPARATOR = '/';
69652
-
69653
- /**
69654
- * Strips all directories from the path.
69655
- * @example 'a/b/c' -> 'c'
69656
- * @param {string} path
69657
- * @returns {string}
69658
- */
69659
- function computePathBase(path) {
69660
- if (typeof path !== "string") {
69661
- throw new Error('path is not a string');
69662
- }
69674
+ /**
69675
+ *
69676
+ * @type {number}
69677
+ */
69678
+ this.height = height;
69663
69679
 
69664
- const lastSlashIndex = path.lastIndexOf(PATH_SEPARATOR);
69680
+ /**
69681
+ * Number of channels
69682
+ * @type {number}
69683
+ */
69684
+ this.itemSize = itemSize;
69665
69685
 
69666
- if (lastSlashIndex !== -1) {
69667
- return path.substring(lastSlashIndex + 1);
69668
- } else {
69669
- return path;
69670
- }
69671
- }
69672
-
69673
- /**
69674
- *
69675
- * @param {string} path
69676
- * @returns {String|null}
69677
- */
69678
- function computeFileExtension(path) {
69679
- const type_of_path = typeof path;
69680
- if (type_of_path !== "string") {
69681
- throw new Error(`path must be a string, instead was '${type_of_path}'`);
69686
+ this.byteSize = data.length;
69682
69687
  }
69683
69688
 
69684
- //get base
69685
- const pathBase = computePathBase(path);
69686
-
69687
- const lastDotIndex = pathBase.lastIndexOf('.');
69688
-
69689
- if (lastDotIndex !== -1) {
69690
- return pathBase.substring(lastDotIndex + 1);
69691
- } else {
69692
- //no extension
69693
- return null;
69689
+ create() {
69690
+ return new Sampler2D(this.data, this.itemSize, this.width, this.height);
69694
69691
  }
69695
69692
  }
69696
69693
 
@@ -69702,7 +69699,7 @@ class ImageRGBADataLoader extends AssetLoader {
69702
69699
 
69703
69700
  this.decoder = new CodecWithFallback(
69704
69701
  new ThreadedImageDecoder(),
69705
- new NativeImageDecoder()
69702
+ // new NativeImageDecoder()
69706
69703
  );
69707
69704
  }
69708
69705
 
@@ -69744,7 +69741,6 @@ class ImageRGBADataLoader extends AssetLoader {
69744
69741
 
69745
69742
  const bitmap = await this.__decode_via_worker(path, scope);
69746
69743
 
69747
-
69748
69744
  let data;
69749
69745
 
69750
69746
  const bitDepth = bitmap.bitDepth;
@@ -69800,30 +69796,37 @@ class ImageRGBADataLoader extends AssetLoader {
69800
69796
  }
69801
69797
 
69802
69798
  /**
69803
- * @author Alex Goldring
69804
- * @copyright Alex Goldring 2018
69799
+ * Utility class for managing connection between listeners to signals
69805
69800
  */
69801
+ class SignalBinding {
69802
+ /**
69803
+ * State flag
69804
+ * @type {boolean}
69805
+ */
69806
+ #linked = false;
69806
69807
 
69808
+ get linked() {
69809
+ return this.#linked;
69810
+ }
69807
69811
 
69808
- class SignalBinding {
69809
69812
  /**
69810
69813
  *
69811
69814
  * @param {Signal} signal
69812
69815
  * @param {function} handler
69813
- * @param {*} [context]
69816
+ * @param {*} [context] will be passed as thisArg to the handler
69814
69817
  * @constructor
69815
69818
  */
69816
69819
  constructor(signal, handler, context) {
69817
69820
  if (typeof handler !== "function") {
69818
- throw new TypeError(`handler must be a function, instead was ${handler}`);
69821
+ throw new TypeError(`handler must be a function, instead was '${typeof handler}'`);
69819
69822
  }
69820
69823
 
69821
69824
  if (typeof signal !== "object") {
69822
- throw new TypeError(`signal must be of an object, instead was ${signal}`)
69825
+ throw new TypeError(`signal must be of an object, instead was '${typeof signal}'`)
69823
69826
  }
69824
69827
 
69825
69828
  if (typeof signal.add !== "function") {
69826
- throw new TypeError(`signal.add must be a function, instead was ${signal.add}`);
69829
+ throw new TypeError(`signal.add must be a function, instead was '${typeof signal.add}'`);
69827
69830
  }
69828
69831
 
69829
69832
  /**
@@ -69844,11 +69847,6 @@ class SignalBinding {
69844
69847
  */
69845
69848
  this.context = context;
69846
69849
 
69847
- /**
69848
- * State flag
69849
- * @type {boolean}
69850
- */
69851
- this.linked = false;
69852
69850
  }
69853
69851
 
69854
69852
  /**
@@ -69856,11 +69854,11 @@ class SignalBinding {
69856
69854
  * Idempotent
69857
69855
  */
69858
69856
  link() {
69859
- if (this.linked) {
69857
+ if (this.#linked) {
69860
69858
  return;
69861
69859
  }
69862
69860
 
69863
- this.linked = true;
69861
+ this.#linked = true;
69864
69862
  this.signal.add(this.handler, this.context);
69865
69863
  }
69866
69864
 
@@ -69869,11 +69867,11 @@ class SignalBinding {
69869
69867
  * Idempotent
69870
69868
  */
69871
69869
  unlink() {
69872
- if (!this.linked) {
69870
+ if (!this.#linked) {
69873
69871
  return;
69874
69872
  }
69875
69873
 
69876
- this.linked = false;
69874
+ this.#linked = false;
69877
69875
  this.signal.remove(this.handler, this.context);
69878
69876
  }
69879
69877
  }
@@ -70353,7 +70351,7 @@ class ObservedBoolean extends Boolean {
70353
70351
 
70354
70352
  /**
70355
70353
  *
70356
- * @param {function} f
70354
+ * @param {function(boolean)} f
70357
70355
  */
70358
70356
  process(f) {
70359
70357
  f(this.__value);