@arcgis/core 5.2.0-next.14 → 5.2.0-next.15

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 (175) hide show
  1. package/assets/esri/core/workers/RemoteClient.js +1 -1
  2. package/assets/esri/core/workers/chunks/{31762eb20a9a0ed3f8b0.js → 011a4d4201696fa10408.js} +1 -1
  3. package/assets/esri/core/workers/chunks/01ba5319cac3e0f14205.js +1 -0
  4. package/assets/esri/core/workers/chunks/0436fe89adc78696251c.js +1 -0
  5. package/assets/esri/core/workers/chunks/079b412d07d02504f1db.js +1 -0
  6. package/assets/esri/core/workers/chunks/{38cfedce779dd75bd217.js → 07ca020796c57cefda62.js} +1 -1
  7. package/assets/esri/core/workers/chunks/0b45d34938fa7862f746.js +1 -0
  8. package/assets/esri/core/workers/chunks/{a4b970a841b3085500fc.js → 0b55fc5050e718371e05.js} +1 -1
  9. package/assets/esri/core/workers/chunks/{97a654e8054302582a3b.js → 0bf72e9d0a6deceeb406.js} +1 -1
  10. package/assets/esri/core/workers/chunks/11c3b1e8ca21ad62fdd1.js +1 -0
  11. package/assets/esri/core/workers/chunks/1bd49e8d2657c72bf3f9.js +1 -0
  12. package/assets/esri/core/workers/chunks/1d81e667a580c5cdeda1.js +262 -0
  13. package/assets/esri/core/workers/chunks/25c1f5e2561986330b80.js +1 -0
  14. package/assets/esri/core/workers/chunks/2bc4aff77c830061e16e.js +1 -0
  15. package/assets/esri/core/workers/chunks/{8c443c52c846a096a250.js → 36dd3ad3ef2fbfc15cbd.js} +1 -1
  16. package/assets/esri/core/workers/chunks/39a10b2092a98083f4cf.js +1 -0
  17. package/assets/esri/core/workers/chunks/3bd32387af52fa48d747.js +1 -0
  18. package/assets/esri/core/workers/chunks/3dc6e9494af16f7b8009.js +1 -0
  19. package/assets/esri/core/workers/chunks/42e5e00610f281ca8ffa.js +1 -0
  20. package/assets/esri/core/workers/chunks/{73c355b895fd6a34fcb8.js → 45b560ca01fb566ba560.js} +1 -1
  21. package/assets/esri/core/workers/chunks/47d630561f3fce5c63c4.js +1 -0
  22. package/assets/esri/core/workers/chunks/4cc78493805671708a9b.js +1 -0
  23. package/assets/esri/core/workers/chunks/4e59e5a5d0ff887ff899.js +1 -0
  24. package/assets/esri/core/workers/chunks/4efef5fa8bf23aaf34cd.js +1 -0
  25. package/assets/esri/core/workers/chunks/511b9c12a7479d39dac0.js +1 -0
  26. package/assets/esri/core/workers/chunks/{20c729fca2e4b4c6b28d.js → 57b7e5fde972d3ad7884.js} +1 -1
  27. package/assets/esri/core/workers/chunks/57e04b7ec238f7b24274.js +1 -0
  28. package/assets/esri/core/workers/chunks/5d8924fdcdb473d261cd.js +1 -0
  29. package/assets/esri/core/workers/chunks/62de9e83331fb10aac6a.js +2 -0
  30. package/assets/esri/core/workers/chunks/{854c320af09b6afc4b80.js → 641cddee377599916de2.js} +2 -2
  31. package/assets/esri/core/workers/chunks/65cc9a48ac95523f7aa8.js +1 -0
  32. package/assets/esri/core/workers/chunks/66392ff750c28064040a.js +1 -0
  33. package/assets/esri/core/workers/chunks/668d84dc512b3085a960.js +1 -0
  34. package/assets/esri/core/workers/chunks/{318a2702632aaa4d3a63.js → 6a1b6f8c868f8edce1d7.js} +1 -1
  35. package/assets/esri/core/workers/chunks/6f5a82388a5eb5fcf1b7.js +1 -0
  36. package/assets/esri/core/workers/chunks/73b0edabddbb72fe1104.js +1 -0
  37. package/assets/esri/core/workers/chunks/7ee76504e7fea389a1c9.js +1 -0
  38. package/assets/esri/core/workers/chunks/7f849c8255140be6097f.js +1 -0
  39. package/assets/esri/core/workers/chunks/8927fb4aa68f7e541a39.js +30 -0
  40. package/assets/esri/core/workers/chunks/8eda85fc01a71aedd9e4.js +1 -0
  41. package/assets/esri/core/workers/chunks/8f25d91ea7b99597124e.js +1 -0
  42. package/assets/esri/core/workers/chunks/92341f36a8b15f34bcca.js +1 -0
  43. package/assets/esri/core/workers/chunks/9f93c29af2a18f7cb160.js +1 -0
  44. package/assets/esri/core/workers/chunks/a18cb809dd56c5537b3b.js +1 -0
  45. package/assets/esri/core/workers/chunks/a4f3bcfabd4ad127abf2.js +1 -0
  46. package/assets/esri/core/workers/chunks/a63bba226de6c5e464b0.js +1 -0
  47. package/assets/esri/core/workers/chunks/{7dcf804e1918b94fa4e1.js → a98905bf6050ad3b8721.js} +1 -1
  48. package/assets/esri/core/workers/chunks/a9f29ff36a7ae5bae686.js +1 -0
  49. package/assets/esri/core/workers/chunks/{1d5db8746a4f1ed1d18f.js → b102beeeb7a919f68b51.js} +1 -1
  50. package/assets/esri/core/workers/chunks/b75a4753cea6544da8bb.js +1 -0
  51. package/assets/esri/core/workers/chunks/bd36c57dd0cd28dee55f.js +30 -0
  52. package/assets/esri/core/workers/chunks/c8460bdf60aca749ed05.js +30 -0
  53. package/assets/esri/core/workers/chunks/c9057b0ad2c2bae4a8ce.js +1 -0
  54. package/assets/esri/core/workers/chunks/e73bb7c8de7412d9975c.js +1 -0
  55. package/assets/esri/core/workers/chunks/e8546ab510fc9515bd23.js +1 -0
  56. package/assets/esri/core/workers/chunks/e9acc05b0cf9e05f31a8.js +1 -0
  57. package/assets/esri/core/workers/chunks/{e77df11aee136d64ff0f.js → eb91dc957c328674e119.js} +1 -1
  58. package/assets/esri/core/workers/chunks/{0a8ba5cb857f61de40fb.js → ed2a1c371dfc5d4a744e.js} +28 -28
  59. package/assets/esri/core/workers/chunks/f0832b413612c77a62ca.js +1 -0
  60. package/assets/esri/core/workers/chunks/f955b35337a08f9f747d.js +1 -0
  61. package/assets/esri/core/workers/chunks/fea3b6bef761ef78630e.js +1 -0
  62. package/assets/esri/libs/lyr3d/lyr3DMain.wasm +0 -0
  63. package/assets/esri/views/3d/analysis/ShadowCast/t9n/ShadowCastAnalysis_fr.json +1 -1
  64. package/chunks/Component.glsl.js +3 -3
  65. package/chunks/GaussianSplatComposition.glsl.js +1 -1
  66. package/chunks/GlobalIlluminationBlur.glsl.js +11 -11
  67. package/chunks/OITBlend.glsl.js +1 -24
  68. package/chunks/OITBlendEmission.glsl.js +9 -9
  69. package/chunks/OITDimOpaque.glsl.js +3 -9
  70. package/chunks/lyr3DMain.js +1 -1
  71. package/config.js +1 -1
  72. package/core/reactiveUtils.d.ts +410 -109
  73. package/kernel.js +1 -1
  74. package/layers/Lyr3DWasmPerSceneView.js +1 -1
  75. package/layers/graphics/sources/MemorySource.js +1 -1
  76. package/layers/mixins/OperationalLayer.js +1 -1
  77. package/layers/support/ExportImageServiceParameters.js +1 -1
  78. package/layers/support/layersMapping.js +1 -1
  79. package/package.json +3 -3
  80. package/rest/print.js +1 -1
  81. package/support/revision.js +1 -1
  82. package/views/2d/engine/webgl/TextureManager.js +1 -1
  83. package/views/2d/engine/webgl/shaderGraph/techniques/vectorTiles/VTLTechniqueBackground.js +1 -1
  84. package/views/2d/engine/webgl/shaders/sources/shaderRepository.js +1 -1
  85. package/views/3d/interactive/visualElements/DrapedVisualElementResources.js +1 -1
  86. package/views/3d/layers/graphics/Graphics3DIconSymbolLayer.js +1 -1
  87. package/views/3d/webgl-engine/core/shaderLibrary/shading/Gamma.glsl.js +2 -2
  88. package/views/3d/webgl-engine/core/shaderLibrary/util/EmissionDimming.glsl.js +1 -1
  89. package/views/3d/webgl-engine/core/shaderTechnique/ShaderTechniqueRepository.js +1 -1
  90. package/views/3d/webgl-engine/effects/fog/FogTechniqueConfiguration.js +1 -1
  91. package/views/3d/webgl-engine/effects/globalIllumination/GlobalIlluminationBlur.glsl.js +1 -1
  92. package/views/3d/webgl-engine/effects/glow/Glow.js +1 -1
  93. package/views/3d/webgl-engine/effects/glow/GlowBlurTechniqueConfiguration.js +1 -1
  94. package/views/3d/webgl-engine/effects/glow/GlowCompositionTechniqueConfiguration.js +1 -1
  95. package/views/3d/webgl-engine/effects/smaa/SMAA.js +1 -1
  96. package/views/3d/webgl-engine/effects/transparency/OITBlend.glsl.js +1 -1
  97. package/views/3d/webgl-engine/effects/transparency/OITBlend.js +1 -1
  98. package/views/3d/webgl-engine/effects/transparency/OITBlendEmission.glsl.js +1 -1
  99. package/views/3d/webgl-engine/effects/transparency/OITBlendEmissionTechnique.js +1 -1
  100. package/views/3d/webgl-engine/effects/transparency/OITBlendFragmentTechniqueConfiguration.js +2 -0
  101. package/views/3d/webgl-engine/effects/transparency/OITBlendTechnique.js +1 -1
  102. package/views/3d/webgl-engine/effects/transparency/OITBlendTechniqueConfiguration.js +1 -1
  103. package/views/3d/webgl-engine/effects/transparency/OITDimOpaque.glsl.js +1 -1
  104. package/views/3d/webgl-engine/effects/transparency/OITDimOpaqueTechnique.js +1 -1
  105. package/views/3d/webgl-engine/effects/transparency/oitBlendFragment.glsl.js +2 -0
  106. package/views/3d/webgl-engine/lib/GaussianSplatRenderNode.js +1 -1
  107. package/views/3d/webgl-engine/lib/Material.js +1 -1
  108. package/views/3d/webgl-engine/lib/Renderer.js +1 -1
  109. package/views/3d/webgl-engine/lib/lodRendering/LodComponentData.js +1 -1
  110. package/views/3d/webgl-engine/lib/lodRendering/LodLevel.js +1 -1
  111. package/views/3d/webgl-engine/lib/lodRendering/LodRenderer.js +1 -1
  112. package/views/3d/webgl-engine/materials/ColorMaterial.js +1 -1
  113. package/views/3d/webgl-engine/materials/DefaultMaterial.js +1 -1
  114. package/views/3d/webgl-engine/materials/PathMaterial.js +1 -1
  115. package/views/3d/webgl-engine/materials/PatternMaterial.js +1 -1
  116. package/views/3d/webgl-engine/materials/RibbonLineMaterial.js +1 -1
  117. package/views/3d/webgl-engine/materials/renderers/MergedRenderer.js +1 -1
  118. package/views/3d/webgl-engine/shaders/GaussianSplatCompositionTechniqueConfiguration.js +1 -1
  119. package/views/3d/webgl-engine/shaders/OutputColorHighlightOLID.glsl.js +1 -1
  120. package/views/3d/webgl-engine/shaders/oitResolution.glsl.js +1 -1
  121. package/views/View2D.d.ts +2 -3
  122. package/webdoc/support/writeUtils.js +1 -1
  123. package/widgets/Editor.js +1 -1
  124. package/widgets/Print/PrintViewModel.d.ts +11 -1
  125. package/widgets/Print/PrintViewModel.js +1 -1
  126. package/assets/esri/core/workers/chunks/0cbd7f5fe24271942abd.js +0 -1
  127. package/assets/esri/core/workers/chunks/1a95370ddc22729ab3c6.js +0 -1
  128. package/assets/esri/core/workers/chunks/2185e8a52c5e29d46680.js +0 -1
  129. package/assets/esri/core/workers/chunks/23d50c4478f40a7d62bf.js +0 -1
  130. package/assets/esri/core/workers/chunks/2623cd08487fdc9a94f1.js +0 -1
  131. package/assets/esri/core/workers/chunks/26583db2af1a1cc456e5.js +0 -1
  132. package/assets/esri/core/workers/chunks/2b00229c238aae70b948.js +0 -1
  133. package/assets/esri/core/workers/chunks/2b814bb51704a5b4fdc2.js +0 -30
  134. package/assets/esri/core/workers/chunks/30f1909c5ef1835b8507.js +0 -1
  135. package/assets/esri/core/workers/chunks/3172d7fc23787a287191.js +0 -1
  136. package/assets/esri/core/workers/chunks/39596715e84d0da2f803.js +0 -30
  137. package/assets/esri/core/workers/chunks/398eb3100a282e4736bb.js +0 -1
  138. package/assets/esri/core/workers/chunks/426b8e1e2eef2460851d.js +0 -1
  139. package/assets/esri/core/workers/chunks/4376bc2934a996d8bc27.js +0 -1
  140. package/assets/esri/core/workers/chunks/44e52fe98ffafe6a2807.js +0 -1
  141. package/assets/esri/core/workers/chunks/4d09ef7c57ab7f9782fe.js +0 -1
  142. package/assets/esri/core/workers/chunks/5022413f5a41b5d435ea.js +0 -1
  143. package/assets/esri/core/workers/chunks/5201105ca11a2d450460.js +0 -1
  144. package/assets/esri/core/workers/chunks/528ed0bd8dc149ead023.js +0 -1
  145. package/assets/esri/core/workers/chunks/59dafa1e1340ea4043e6.js +0 -1
  146. package/assets/esri/core/workers/chunks/684d3cb4fb233180b2d0.js +0 -1
  147. package/assets/esri/core/workers/chunks/6d616b66fb32904b55a1.js +0 -1
  148. package/assets/esri/core/workers/chunks/6d696beddcc5fbed5875.js +0 -1
  149. package/assets/esri/core/workers/chunks/6f125b4ed06c0022dee6.js +0 -1
  150. package/assets/esri/core/workers/chunks/6f4825c3ef1fe202ab82.js +0 -1
  151. package/assets/esri/core/workers/chunks/6f7193b9ff5942c0d354.js +0 -1
  152. package/assets/esri/core/workers/chunks/70737052bab29fcaa120.js +0 -1
  153. package/assets/esri/core/workers/chunks/72d67cc3a382e83bf1a2.js +0 -1
  154. package/assets/esri/core/workers/chunks/851705cf276eae8d4d37.js +0 -1
  155. package/assets/esri/core/workers/chunks/882ee7ed8a3a0215f9b9.js +0 -1
  156. package/assets/esri/core/workers/chunks/9d5f7573bfe3b051daf1.js +0 -1
  157. package/assets/esri/core/workers/chunks/a0c00c6fe60db49b3ab9.js +0 -1
  158. package/assets/esri/core/workers/chunks/af31e62499d45bdab3c3.js +0 -1
  159. package/assets/esri/core/workers/chunks/b9935cc8e2bd4045058a.js +0 -1
  160. package/assets/esri/core/workers/chunks/bdc66ef2b6ed783047d5.js +0 -1
  161. package/assets/esri/core/workers/chunks/c2a65de34f6a6c89c652.js +0 -1
  162. package/assets/esri/core/workers/chunks/c424a66f1546275e2bcb.js +0 -30
  163. package/assets/esri/core/workers/chunks/d2f47f21ce0b0ab4da17.js +0 -262
  164. package/assets/esri/core/workers/chunks/d5c35a75fd4c41def420.js +0 -1
  165. package/assets/esri/core/workers/chunks/dbd2bfcbf3e0f86f07b8.js +0 -1
  166. package/assets/esri/core/workers/chunks/df54e741db40b308c2dd.js +0 -2
  167. package/assets/esri/core/workers/chunks/e33d2ede6c9f1527d51b.js +0 -1
  168. package/assets/esri/core/workers/chunks/e912b515704e20313e53.js +0 -1
  169. package/assets/esri/core/workers/chunks/eac683a37339aa558455.js +0 -1
  170. package/assets/esri/core/workers/chunks/f590db684d88e72bd79b.js +0 -1
  171. package/assets/esri/core/workers/chunks/fa3faec65882c5b6f1a0.js +0 -1
  172. package/views/3d/webgl-engine/effects/transparency/OITBlendEmissionTechniqueConfiguration.js +0 -2
  173. package/views/3d/webgl-engine/effects/transparency/OITDimOpaqueTechniqueConfiguration.js +0 -2
  174. /package/assets/esri/core/workers/chunks/{df54e741db40b308c2dd.js.LICENSE.txt → 62de9e83331fb10aac6a.js.LICENSE.txt} +0 -0
  175. /package/assets/esri/core/workers/chunks/{854c320af09b6afc4b80.js.LICENSE.txt → 641cddee377599916de2.js.LICENSE.txt} +0 -0
@@ -1,139 +1,429 @@
1
1
  /**
2
2
  * * [Overview](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#overview)
3
3
  * * [Using reactiveUtils](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#using-reactiveutils)
4
+ * * [Truthy checks versus explicit value checks](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#truthy-values)
5
+ * * [Async versus sync callbacks](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#async-vs-sync)
4
6
  * * [Working with collections](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#working-with-collections)
5
7
  * * [Working with objects](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#working-with-objects)
6
- * * [WatchHandles and Promises](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#watchhandles-and-promises)
7
- * * [Working with truthy values](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#truthy-values)
8
+ * * [ResourceHandles and Promises](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#resourcehandles-and-promises)
9
+ * * [Working with TypeScript](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#typescript)
8
10
  *
9
11
  * <span id="overview"></span>
10
12
  * ## Overview
11
- * `reactiveUtils` provide capabilities for observing changes to the state of the SDK's properties,
12
- * and is an important part of managing your application's life-cycle.
13
- * State can be observed on a variety of different data types and structures
14
- * including strings, numbers, arrays, booleans, collections, and objects.
13
+ * `reactiveUtils` provides a declarative way to watch SDK state and respond to changes.
14
+ *
15
+ * To use it, provide:
16
+ * - A reactive expression that returns the state you want to track.
17
+ * - A callback that runs whenever that state changes.
18
+ *
19
+ * The reactive expression is a function that automatically re-evaluates whenever any state it accesses changes.
20
+ * For example, if the expression reads the map component's `stationary` property,
21
+ * the callback runs whenever `stationary` changes between `true` and `false`.
22
+ *
23
+ * Reactive expressions can track primitive values, arrays, collections, and objects.
24
+ * Depending on the function you use, `reactiveUtils` supports both continuous observation and one-time conditions.
15
25
  *
16
26
  * <span id="using-reactiveutils"></span>
17
27
  * ## Using reactiveUtils
18
28
  *
19
- * `reactiveUtils` provides five methods that offer different patterns and capabilities for observing state:
29
+ * `reactiveUtils` provides five functions for observing state:
20
30
  * [on()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#on), [once()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#once), [watch()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#watch), [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when) and [whenOnce()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#whenOnce).
31
+ * Each of these has different characteristics and use cases, as summarized in the table below:
32
+ *
33
+ * | Function | Runs multiple times | Resolves once | Returns | Common use |
34
+ * | ----------------------------------- | ------------------- | ------------- | ---------------- | ------------------------------------ |
35
+ * | [watch()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#watch) | Yes | No | `ResourceHandle` | Continuously observe for changes |
36
+ * | [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when) | Yes | No | `ResourceHandle` | Run when expression becomes truthy |
37
+ * | [on()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#on) | Yes | No | `ResourceHandle` | Observe events |
38
+ * | [once()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#once) | No | Yes | `Promise` | Wait for first emitted value |
39
+ * | [whenOnce()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#whenOnce) | No | Yes | `Promise` | Wait until expression becomes truthy |
21
40
  *
22
- * The following is a basic example using [watch()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#watch). It demonstrates how to track the
23
- * Map component [updating](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-map/#updating) property and then send a message to the console
24
- * when the property changes. This snippet uses a `getValue` function as an expression that evaluates the
25
- * `updating` property, and when a change is observed the new value is passed to the callback:
41
+ * <details>
42
+ * <summary>Read More</summary>
43
+ *
44
+ * The snippet below uses [watch()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#watch) to react when the
45
+ * Map component's [stationary](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-map/#stationary) property changes.
46
+ * This pattern is useful when work should run after navigation settles, such as querying
47
+ * features for the current extent, refreshing summary statistics, or enabling UI actions.
48
+ *
49
+ * The first argument in the `watch()` function is the reactive expression, in the form of a `getValue` function, that evaluates the
50
+ * `stationary` property. When a change is observed in the expression the new value is automatically passed to the callback:
26
51
  *
27
52
  * ```js
28
- * // Basic example of watching for changes on a boolean property
53
+ * // Watching for changes on the map component's stationary property
29
54
  * const viewElement = document.querySelector("arcgis-map");
30
- * reactiveUtils.watch(
31
- * // getValue function
32
- * () => viewElement.updating,
55
+ * const handle = reactiveUtils.watch(
56
+ * // getValue expression
57
+ * () => viewElement.stationary,
33
58
  * // callback
34
- * (updating) => {
35
- * console.log(updating)
59
+ * (stationary) => {
60
+ * console.log(stationary)
36
61
  * });
62
+ *
63
+ * // Remove the handle when it's no longer needed to stop watching for changes
64
+ * handle.remove();
65
+ * ```
66
+ *
67
+ * Other examples of `getValue` expressions include:
68
+ *
69
+ * ```js
70
+ * () => viewElement.ready // Wait until the view finishes updating
71
+ * () => [viewElement.stationary, viewElement.zoom] // Track changes to multiple properties at once
72
+ * () => viewElement.popupElement?.open // Detect when a popup is opened
73
+ * () => layer.visible // Track changes in layer visibility
74
+ * ```
75
+ *
76
+ * **Basic usage rules:**
77
+ * - Shape expressions so callbacks receive defined values.
78
+ * - Avoid truthy checks when falsy values like `0`, `""`, or `false` are valid.
79
+ * - Use explicit comparisons for specific values (e.g., `=== 0` or `=== false`).
80
+ * - Use optional chaining (`?.`) to safely access nested properties.
81
+ * - Return derived values for collections to react to structural changes.
82
+ *
83
+ * </details>
84
+ *
85
+ * <span id="truthy-values"></span>
86
+ * ### Truthy checks versus explicit value checks
87
+ *
88
+ * The [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when) and [whenOnce()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#whenOnce) functions execute when the `getValue` expression
89
+ * evaluates as truthy, instead of reacting to every value change.
90
+ *
91
+ * Use [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) checks when you only care whether a value is present or available.
92
+ * Use [explicit value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Equality_comparisons_and_sameness) checks
93
+ * when you need to verify a specific state or distinguish between different values.
94
+ *
95
+ * | Goal | Recommended approach |
96
+ * | ------------------------------------- | -------------------- |
97
+ * | Wait for property existence | Truthy |
98
+ * | Wait for async resource | Truthy |
99
+ * | Check boolean state (true or false) | Explicit |
100
+ * | Allow values such `0` or `""` | Explicit |
101
+ * | Distinguish `null` or `undefined` | Explicit |
102
+ * | Implement exact application logic | Explicit |
103
+ *
104
+ * <details>
105
+ * <summary>Read More</summary>
106
+ *
107
+ * > [!WARNING]
108
+ * >
109
+ * > `when()` and `whenOnce()` functions only trigger the callback when the expression changes and then the value satisfies the expression,
110
+ * > such as *false -> true -> false*, but not *true -> true*.
111
+ * >
112
+ * > Be careful with initial and default property values. For example, if you are watching for a property that is `true` by default,
113
+ * > such as [FeatureLayer.visible](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/), using a truthy check will not trigger the callback
114
+ * > until the property becomes `false` and then `true` again, which may not be the intended behavior.
115
+ *
116
+ * The snippets below use the Popup component's [open](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-popup/#open) property in the `getValue` expression.
117
+ * The first snippet uses a truthy check to determine when the popup is open,
118
+ * which is useful when you want to run the callback whenever the popup becomes visible.
119
+ * The property is `false` by default, so the callback will run when the popup opens,
120
+ * but not on subsequent changes that keep it open. Once the popup is closed, the callback will run again when it opens.
121
+ *
122
+ * ```js
123
+ * const viewElement = document.querySelector("arcgis-map");
124
+ *
125
+ * const handle = reactiveUtils.when(() => viewElement.popupElement.open, () => {
126
+ * console.log("Truthy check for popup open");
127
+ * });
128
+ *
129
+ * // Remove the handle when it's no longer needed to stop watching for changes
130
+ * handle.remove();
131
+ * ```
132
+ *
133
+ * Other truthy examples include:
134
+ * ```js
135
+ * () => viewElement.ready
136
+ * () => layer.loaded
137
+ * () => layer.visible
138
+ * ```
139
+ *
140
+ * Use explicit value checks when your logic depends on a specific value,
141
+ * rather than simply whether a value is truthy.
142
+ *
143
+ * This is useful when valid values may be falsy, such as `0`, `""`, or
144
+ * `false`, and a truthy check would produce unintended results.
145
+ *
146
+ * For example, to react only when the map is at a specific scale:
147
+ *
148
+ * ```js
149
+ * const handle = reactiveUtils.when(() => viewElement.scale === 5000, () => {
150
+ * console.log("The map is at scale 1:5000");
151
+ * });
152
+ *
153
+ * // Remove the handle when it's no longer needed to stop watching for changes
154
+ * handle.remove();
155
+ * ```
156
+ *
157
+ * Other examples include:
158
+ *
159
+ * ```js
160
+ * () => viewElement.updating === false
161
+ * () => layer.visible === false
37
162
  * ```
38
163
  *
164
+ * See the MDN documentation to learn more about
165
+ * [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) and
166
+ * [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) values.
167
+ *
168
+ * </details>
169
+ *
170
+ * <span id="async-vs-sync"></span>
171
+ * ### Async versus sync callbacks
172
+ *
173
+ * Understanding the difference between asynchronous and synchronous callbacks is essential when working with `reactiveUtils`.
174
+ * The timing of when your callback executes, either immediately or on the next microtask,
175
+ * can impact both application behavior and performance.
176
+ *
177
+ * <details>
178
+ * <summary>Read More</summary>
179
+ *
180
+ * By default, [watch()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#watch), [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when) and [on()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#on)
181
+ * functions are asynchronous, meaning that the callback will run on the next [microtask](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide) after the
182
+ * expression value changes. This allows for batching of multiple changes and can help with
183
+ * performance. However, if you need the callback to run synchronously with the change, you
184
+ * can set the `sync` option to `true` in the options parameter.
185
+ *
186
+ * [once()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#once) and [whenOnce()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#whenOnce) resolve via a Promise,
187
+ * so they are always asynchronous and cannot be made synchronous. If the condition is
188
+ * already satisfied when `once()` or `whenOnce()` is called, the promise will resolve
189
+ * on the next microtask with the current value.
190
+ *
191
+ * One nuance, if you provide `initial: true` in the [ReactiveWatchOptions](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#ReactiveWatchOptions)
192
+ * for `watch()` and `when()`, the callback will run immediately after initialization if the
193
+ * condition is met, and then continue to watch for changes. In this case, the callback runs
194
+ * synchronously with the initial check, but subsequent calls are asynchronous.
195
+ * This is useful when you don’t want to duplicate initialization logic or manually “seed” state.
196
+ *
197
+ * ```js
198
+ * const handle = reactiveUtils.when(
199
+ * () => layer.visible === true,
200
+ * () => showLayerUI(),
201
+ * { initial: true }
202
+ * );
203
+ *
204
+ * // Remove the handle when it's no longer needed to stop watching for changes
205
+ * handle.remove();
206
+ * ```
207
+ *
208
+ * Without `initial: true`, you might miss the fact that `layer.visible` was already true at startup and only respond to future changes.
209
+ *
210
+ * </details>
211
+ *
39
212
  * <span id="working-with-collections"></span>
40
213
  * ### Working with collections
41
214
  *
42
- * `reactiveUtils` can be used to observe changes within a collection, such as [Map.allLayers](https://developers.arcgis.com/javascript/latest/references/core/Map/#allLayers). Out-of-the-box JavaScript methods
43
- * such as [`.map()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map) and [`.filter()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) can be used as
44
- * expressions to be evaluated in the `getValue` function.
215
+ * `reactiveUtils` can observe changes with a [Collection](https://developers.arcgis.com/javascript/latest/references/core/core/Collection/), such as the Map component’s
216
+ * [allLayerViews](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-map/#allLayerViews).
217
+ * Methods like [Collection.map()](https://developers.arcgis.com/javascript/latest/references/core/core/Collection/#map) and [Collection.filter()](https://developers.arcgis.com/javascript/latest/references/core/core/Collection/#filter),
218
+ * can be used in the `getValue` expression to derive values.
219
+ * This ensures the callback reacts to additions, removals, or updates in the collection.
45
220
  *
46
221
  * ```js
47
- * // Watching for changes within a collection
48
- * // whenever a new layer is added to the map
49
- * const viewElement = document.querySelector("arcgis-map");
50
- * reactiveUtils.watch(
51
- * () => viewElement.map.allLayers.map( layer => layer.id),
52
- * (ids) => {
53
- * console.log(`FeatureLayer IDs ${ids}`);
222
+ * const handle = reactiveUtils.watch(
223
+ * () => viewElement.allLayerViews.map((layerView) => layerView.visible),
224
+ * (layerViews) => {
225
+ * console.log(`Visible layerViews: ${layerViews}`);
54
226
  * });
227
+ *
228
+ * // Remove the handle when it's no longer needed to stop watching for changes
229
+ * handle.remove();
55
230
  * ```
56
231
  *
57
232
  * <span id="working-with-objects"></span>
58
233
  * ### Working with objects
59
234
  *
60
- * With `reactiveUtils` you can track named object properties through dot notation (e.g. `viewElement.updating`) or
61
- * through bracket notation (e.g. `viewElement["updating"]`). You can also use the
62
- * [optional chaining](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Optional_chaining) operator (`?.`). This operator
63
- * simplifies the process of verifying that properties used in the `getValue` function
64
- * are not `undefined` or `null`.
235
+ * `reactiveUtils` allows you to track object properties using dot notation
236
+ * (e.g. `viewElement.updating`) or bracket notation (e.g. `viewElement["updating"]`).
237
+ *
238
+ * Optional chaining (`?.`) can be used to safely access nested properties
239
+ * without manually checking each level.
65
240
  *
66
241
  * ```js
67
- * // Watch for changes in an object using optional chaining
68
- * // whenever the map's extent changes
69
- * const viewElement = document.querySelector("arcgis-map");
70
- * reactiveUtils.watch(
242
+ * const handle = reactiveUtils.watch(
71
243
  * () => viewElement?.extent?.xmin,
72
244
  * (xmin) => {
73
- * console.log(`Extent change xmin = ${xmin}`)
74
- * });
245
+ * console.log(`Extent change xmin = ${xmin}`);
246
+ * }
247
+ * );
248
+ *
249
+ * // Remove the handle when it's no longer needed to stop watching for changes
250
+ * handle.remove();
75
251
  * ```
76
252
  *
77
- * <span id="watchhandles-and-promises"></span>
78
- * ### WatchHandles and Promises
253
+ * <span id="resourcehandles-and-promises"></span>
254
+ * ### ResourceHandles and Promises
79
255
  *
80
256
  * The [watch()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#watch), [on()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#on) and
81
- * [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when) methods return a [ResourceHandle](https://developers.arcgis.com/javascript/latest/references/core/core/Handles/#ResourceHandle). Be sure to remove watch handles when they are no longer needed to avoid memory leaks.
257
+ * [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when) functions return a [ResourceHandle](https://developers.arcgis.com/javascript/latest/references/core/core/Handles/#ResourceHandle).
258
+ * Handles retain references to observed objects and callbacks until they are removed.
259
+ * The [once()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#once) and [whenOnce()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#whenOnce) functions return a
260
+ * Promise instead of a `ResourceHandle` and have the option to be cancelled via an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal). When cancelled, the Promise settles and is eligible for disposal.
261
+ *
262
+ * [watch()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#watch) and [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when) have an optional `once` property in
263
+ * their `options` parameter. When `once: true` is set, the returned `ResourceHandle` will automatically remove
264
+ * itself after the first time the callback is executed, which can be useful for one-time conditions
265
+ * while still allowing for manual removal if needed.
266
+ *
267
+ * <details>
268
+ * <summary>Read More</summary>
269
+ *
270
+ * To avoid memory leaks:
271
+ * * Remove handles when the reference is no longer needed, such as during component teardown or before creating a replacement handle.
272
+ * * Use [Handles](https://developers.arcgis.com/javascript/latest/references/core/core/Handles/) to manage groups of handles.
273
+ * * Abort unresolved async operations, this allows them to be disposed.
274
+ *
275
+ * Removing a handle stops the observation and releases references to observed objects and callbacks,
276
+ * allowing them to be garbage collected.
277
+ * Handle removal is idempotent and can be safely called multiple times.
82
278
  *
83
279
  * ```js
84
- * // Use a WatchHandle to stop watching
85
- * const viewElement = document.querySelector("arcgis-map");
280
+ * // Remove a ResourceHandle to stop watching for changes
86
281
  * const handle = reactiveUtils.watch(
87
282
  * () => viewElement?.extent?.xmin,
88
283
  * (xmin) => {
89
284
  * console.log(`Extent change xmin = ${xmin}`)
90
285
  * });
91
286
  *
92
- * // In another function
287
+ * // Remove the handle when it's no longer needed to stop watching for changes
93
288
  * handle.remove()
94
289
  * ```
95
290
  *
96
- * The [once()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#once) and [whenOnce()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#whenOnce) methods return a Promise instead of a `WatchHandle`.
97
- * In some advanced use cases where an API action may take additional time, these
98
- * methods also offer the option to cancel the async callback via an
99
- * [`AbortSignal`](https://developer.mozilla.org/docs/Web/API/AbortController/signal).
100
- * Be aware that if the returned Promise is not resolved, it can also result in a memory leak.
291
+ * Use [Handles](https://developers.arcgis.com/javascript/latest/references/core/core/Handles/) to group multiple ResourceHandles and remove them together, such as when a component is torn down.
292
+ * This also makes it easier to manage handles by name.
101
293
  *
102
294
  * ```js
103
- * // Use an AbortSignal to cancel an async callback
104
- * // during view animation
105
- * const abortController = new AbortController();
295
+ * const handles = new Handles();
296
+ * handles.add(
297
+ * reactiveUtils.watch(...),
298
+ * "view-watcher" // groupKey is optional but can be helpful for managing handles
299
+ * );
106
300
  *
107
- * // Observe the View's animation state
108
- * reactiveUtils.whenOnce(
109
- * () => view?.animation, {signal: abortController.signal})
110
- * .then((animation) => {
111
- * console.log(`View animation state is ${animation.state}`)
112
- * });
301
+ * // In another function or during component teardown
302
+ * handles.remove("view-watcher");
303
+ * ```
113
304
  *
114
- * // Cancel the async callback
115
- * const someFunction = () => {
116
- * abortController.abort();
305
+ * The [once()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#once) and [whenOnce()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#whenOnce) functions return a Promise.
306
+ * In some advanced use cases where an action may take additional time, these
307
+ * functions also offer the option to cancel the async callback via an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
308
+ *
309
+ * > [!WARNING]
310
+ * >
311
+ * > If the component being watched is removed before the promise resolves,
312
+ * > it can lead to memory leaks or unhandled promise rejections.
313
+ *
314
+ * ```js
315
+ * let abortController = new AbortController();
316
+ * const { signal } = abortController;
317
+ *
318
+ * // Cancel the async callback by sending an AbortSignal
319
+ * const abort = () => {
320
+ * abortController?.abort();
117
321
  * }
322
+ *
323
+ * // Set the signal property to watch for abort signals
324
+ * // and reject the promise if the signal is aborted before the promise resolves
325
+ * reactiveUtils.whenOnce(
326
+ * () => !viewElement.updating,
327
+ * { signal }
328
+ * )
329
+ * .then((updating) => {
330
+ * console.log("Map is not updating", updating);
331
+ * })
332
+ * .catch((error) => {
333
+ * if (error.name === "AbortError") {
334
+ * console.log("The async callback was aborted");
335
+ * } else {
336
+ * console.error("An unexpected error occurred:", error);
337
+ * }
338
+ * })
339
+ * .finally(() => {
340
+ * console.log("Async callback has completed or was aborted");
341
+ * abortController = null;
342
+ * });
118
343
  * ```
119
344
  *
120
- * <span id="truthy-values"></span>
121
- * ### Working with truthy values
345
+ * See the SDK guide topic on [Async cancellation with AbortController](https://developers.arcgis.com/javascript/latest/async-cancellation-with-abortcontroller/) for more details and examples.
122
346
  *
123
- * The [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when) and [whenOnce()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#whenOnce) methods watch for *truthy* values, these are values that evaluate to `true`
124
- * in boolean contexts. To learn more about using truthy, visit this
125
- * [MDN Web doc](https://developer.mozilla.org/docs/Glossary/Truthy) article. The snippets below use the [Popup.visible](https://developers.arcgis.com/javascript/latest/references/core/widgets/Popup/) property, which is a boolean.
347
+ * </details>
126
348
  *
127
- * ```js
128
- * // Observe changes on a boolean property
129
- * const viewElement = document.querySelector("arcgis-map");
130
- * reactiveUtils.when(() => viewElement.popup?.visible, () => console.log("Truthy"));
131
- * reactiveUtils.when(() => !viewElement.popup?.visible, () => console.log("Not truthy"));
132
- * reactiveUtils.when(() => viewElement.popup?.visible === true, () => console.log("True"));
133
- * reactiveUtils.when(() => viewElement.popup?.visible !== undefined, () => console.log("Defined"));
134
- * reactiveUtils.when(() => viewElement.popup?.visible === undefined, () => console.log("Undefined"));
349
+ * <span id="typescript"></span>
350
+ * ### Working with TypeScript
351
+ *
352
+ * `reactiveUtils` also works with TypeScript. TypeScript infers the expression result type from the `getValue`
353
+ * expression and passes it to the callback.
354
+ * For array expressions, use explicit tuple typing when positional meaning matters.
355
+ * Using `as const` preserves tuple types so callback parameters are strongly typed by position.
356
+ * You can also use objects to group values and maintain strong typing without relying on position.
357
+ *
358
+ * <details>
359
+ * <summary>Read More</summary>
360
+ *
361
+ * The first snippet shows how to use `as const` for tuple typing when tracking multiple properties in an array.
362
+ *
363
+ * ```ts
364
+ * import { watch } from "@arcgis/core/core/reactiveUtils.js";
365
+ * import type { ArcgisMap } from "@arcgis/map-components/components/arcgis-map";
366
+ *
367
+ * // Get a reference to the map component
368
+ * const arcgisMap = document.querySelector<ArcgisMap>("arcgis-map");
369
+ *
370
+ * const handle = reactiveUtils.watch(
371
+ * () => [view.stationary, view.zoom] as const,
372
+ * ([stationary, zoom], oldValue) => {
373
+ * if (stationary) {
374
+ * const previousZoom = oldValue?.[1];
375
+ * console.log("Zoom:", zoom, "Previous:", previousZoom);
376
+ * }
377
+ * }
378
+ * );
379
+ *
380
+ * // Remove the handle when it's no longer needed to stop watching for changes
381
+ * handle.remove();
135
382
  * ```
136
383
  *
384
+ * The second snippet shows how to use an object to group values and maintain strong typing without
385
+ * relying on position. One advantage of this approach is the callback properties are named.
386
+ * The order of properties in the `getValue` expression doesn't matter. This improves maintainability
387
+ * and readability, especially when tracking multiple properties or when the expression is complex
388
+ * because the properties are matched by the name and not position.
389
+ *
390
+ * ```ts
391
+ * const handle = reactiveUtils.watch(
392
+ * () => ({
393
+ * scale: viewElement.scale,
394
+ * stationary: viewElement.stationary,
395
+ * extent: viewElement.extent
396
+ * }),
397
+ * ({ stationary, extent, scale }) => {
398
+ * if (stationary) {
399
+ * console.log("View stopped moving");
400
+ * console.log("Scale:", scale);
401
+ * console.log("Extent:", extent);
402
+ * }
403
+ * }
404
+ * );
405
+ * ```
406
+ *
407
+ * If the `getValue` expression may return `null` or `undefined`,
408
+ * shape the expression so the callback only runs when a defined value is available.
409
+ *
410
+ * This avoids unnecessary callback executions and ensures TypeScript receives a
411
+ * narrowed type.
412
+ *
413
+ * ```ts
414
+ * const handle = reactiveUtils.when(
415
+ * () => viewElement.popupElement?.selectedFeature?.geometry,
416
+ * (geometry) => {
417
+ * console.log(geometry.type);
418
+ * }
419
+ * );
420
+ *
421
+ * // Remove the handle when it's no longer needed to stop watching for changes
422
+ * handle.remove();
423
+ * ```
424
+ *
425
+ * </details>
426
+ *
137
427
  * @since 4.23
138
428
  * @see [Watch for changes guide topic](https://developers.arcgis.com/javascript/latest/watch-for-changes/)
139
429
  * @see [Sample - Watch for changes in components using reactiveUtils](https://developers.arcgis.com/javascript/latest/sample-code/watch-for-changes-reactiveutils-components/)
@@ -156,7 +446,7 @@ export interface ReactiveWatchOptions<T = unknown> {
156
446
  */
157
447
  readonly initial?: boolean;
158
448
  /**
159
- * Whether to fire the callback synchronously or on the next tick.
449
+ * Whether to fire the callback synchronously or on the next microtask.
160
450
  *
161
451
  * @default false
162
452
  */
@@ -182,14 +472,14 @@ export interface ReactiveWatchOptions<T = unknown> {
182
472
  export type ReactiveEqualityFunction<T> = (newValue: T, oldValue: T) => boolean;
183
473
 
184
474
  /**
185
- * Function which is auto-tracked and should return a value to pass to the [ReactiveWatchCallback](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#ReactiveWatchCallback)
475
+ * Expression which is auto-tracked and should return a value to pass to the [ReactiveWatchCallback](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#ReactiveWatchCallback).
186
476
  *
187
477
  * @returns The new value.
188
478
  */
189
479
  export type ReactiveWatchExpression<T> = () => T;
190
480
 
191
481
  /**
192
- * Function which is auto-tracked and should return an event target to which
482
+ * Expression which is auto-tracked and should return an event target to which
193
483
  * an event listener is to be added.
194
484
  *
195
485
  * @returns The event target.
@@ -205,14 +495,14 @@ export type ReactiveOnExpression<T> = () => T;
205
495
  export type ReactiveWatchCallback<T> = (newValue: T, oldValue?: T) => void;
206
496
 
207
497
  /**
208
- * Function called to be called when an event is emitted or dispatched.
498
+ * Function to be called when an event is emitted or dispatched.
209
499
  *
210
500
  * @param event - The event emitted by the target.
211
501
  */
212
502
  export type ReactiveOnCallback<T> = (event: T) => void;
213
503
 
214
504
  /**
215
- * Tracks any properties accessed in the `getValue` function and calls the callback
505
+ * Tracks any properties accessed in the `getValue` expression and calls the `callback`
216
506
  * when any of them change.
217
507
  *
218
508
  * @param getValue - Function used to get the current value. All accessed properties will be tracked.
@@ -221,28 +511,30 @@ export type ReactiveOnCallback<T> = (event: T) => void;
221
511
  * @returns A watch handle.
222
512
  * @example
223
513
  * // Watching for changes in a boolean value
224
- * // Equivalent to watchUtils.watch()
225
514
  * const viewElement = document.querySelector("arcgis-map");
226
- * reactiveUtils.watch(
227
- * () => viewElement.popup?.visible,
515
+ * const handle = reactiveUtils.watch(
516
+ * () => viewElement.popupElement.open,
228
517
  * () => {
229
- * console.log(`Popup visible: ${viewElement.popup.visible}`);
518
+ * console.log(`Popup open: ${viewElement.popupElement.open}`);
230
519
  * });
520
+ * // Remove the handle when it's no longer needed to stop watching for changes
521
+ * handle.remove();
231
522
  * @example
232
523
  * // Watching for changes within a Collection
233
524
  * const viewElement = document.querySelector("arcgis-map");
234
- * reactiveUtils.watch(
525
+ * const handle = reactiveUtils.watch(
235
526
  * () => viewElement.map.allLayers.length,
236
527
  * () => {
237
528
  * console.log(`Layer collection length changed: ${viewElement.map.allLayers.length}`);
238
529
  * });
530
+ * // Remove the handle when it's no longer needed to stop watching for changes
531
+ * handle.remove();
239
532
  * @example
240
533
  * // Watch for changes in a numerical value.
241
534
  * // Providing `initial: true` in ReactiveWatchOptions
242
535
  * // checks immediately after initialization
243
- * // Equivalent to watchUtils.init()
244
536
  * const viewElement = document.querySelector("arcgis-map");
245
- * reactiveUtils.watch(
537
+ * const handle = reactiveUtils.watch(
246
538
  * () => viewElement.zoom,
247
539
  * () => {
248
540
  * console.log(`zoom changed to ${viewElement.zoom}`);
@@ -250,6 +542,8 @@ export type ReactiveOnCallback<T> = (event: T) => void;
250
542
  * {
251
543
  * initial: true
252
544
  * });
545
+ * // Remove the handle when it's no longer needed to stop watching for changes
546
+ * handle.remove();
253
547
  * @example
254
548
  * // Watch properties from multiple sources
255
549
  * const viewElement = document.querySelector("arcgis-map");
@@ -262,48 +556,53 @@ export type ReactiveOnCallback<T> = (event: T) => void;
262
556
  * }
263
557
  * }
264
558
  * );
559
+ * // Remove the handle when it's no longer needed to stop watching for changes
560
+ * handle.remove();
265
561
  */
266
562
  export function watch<T, U extends T>(getValue: ReactiveWatchExpression<T>, callback: ReactiveWatchCallback<T>, options?: ReactiveWatchOptions<U>): ResourceHandle;
267
563
 
268
564
  /**
269
- * Watches the value returned by the `getValue` function and calls the callback when it becomes truthy.
565
+ * Watches the value returned by the `getValue` expression and calls the `callback` when it becomes truthy.
270
566
  *
271
- * @param getValue - Function used to get the current value. All accessed properties will be tracked.
567
+ * @param getValue - Expression used to get the current value. All accessed properties will be tracked.
272
568
  * @param callback - The function to call when the value becomes truthy.
273
569
  * @param options - Options used to configure how the tracking happens and how the callback is to be called.
274
570
  * @returns A watch handle.
275
571
  * @example
276
572
  * // Observe when a boolean property becomes not truthy
277
- * // Equivalent to watchUtils.whenFalse()
278
- * reactiveUtils.when(
573
+ * const handle = reactiveUtils.when(
279
574
  * () => !layerView.updating,
280
575
  * () => {
281
576
  * console.log("LayerView finished updating.");
282
577
  * });
578
+ * // Remove the handle when it's no longer needed to stop watching for changes
579
+ * handle.remove();
283
580
  * @example
284
581
  * // Observe when a boolean property becomes true
285
- * // Equivalent to watchUtils.whenTrue()
286
582
  * const viewElement = document.querySelector("arcgis-map");
287
- * reactiveUtils.when(
583
+ * const handle = reactiveUtils.when(
288
584
  * () => viewElement?.stationary === true,
289
585
  * async () => {
290
586
  * console.log("User is no longer interacting with the map");
291
587
  * await drawBuffer();
292
588
  * });
589
+ * // Remove the handle when it's no longer needed to stop watching for changes
590
+ * handle.remove();
293
591
  * @example
294
592
  * // Observe a boolean property for truthiness.
295
593
  * // Providing `once: true` in ReactiveWatchOptions
296
594
  * // only fires the callback once
297
- * // Equivalent to watchUtils.whenFalseOnce()
298
595
  * const featuresComponent = document.querySelector("arcgis-features");
299
- * reactiveUtils.when(
300
- * () => !featuresComponent.closed,
596
+ * const handle = reactiveUtils.when(
597
+ * () => featuresComponent.open,
301
598
  * () => {
302
- * console.log(`The features component is closed: ${featuresComponent.closed}`);
599
+ * console.log("The features component is open");
303
600
  * },
304
601
  * {
305
602
  * once: true
306
603
  * });
604
+ * // Remove the handle when it's no longer needed to stop watching for changes
605
+ * handle.remove();
307
606
  */
308
607
  export function when<T, U extends T>(getValue: ReactiveWatchExpression<T | null | undefined>, callback: (newValue: T, oldValue?: T) => void, options?: ReactiveWatchOptions<U>): ResourceHandle;
309
608
 
@@ -317,7 +616,7 @@ export type ReactiveListenerChangeCallback<T> = (target: T) => void;
317
616
  /** Options used to configure the behavior of [on()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#on). */
318
617
  export interface ReactiveOnOptions<Target> {
319
618
  /**
320
- * Whether to fire the callback synchronously or on the next tick.
619
+ * Whether to fire the callback synchronously or on the next microtask.
321
620
  *
322
621
  * @default false
323
622
  */
@@ -347,19 +646,21 @@ export interface ReactiveOnOptions<Target> {
347
646
  * @example
348
647
  * // Adds a click event on a map component when it changes
349
648
  * const viewElement = document.querySelector("arcgis-map");
350
- * reactiveUtils.on(
649
+ * const handle = reactiveUtils.on(
351
650
  * () => viewElement,
352
651
  * "arcgisViewClick",
353
652
  * (event) => {
354
653
  * console.log("arcgisViewClick event emitted: ", event);
355
654
  * });
655
+ * // Remove the handle when it's no longer needed to stop watching for changes
656
+ * handle.remove();
356
657
  * @example
357
658
  * // Adds a drag event on a map component and adds a callback
358
659
  * // to check when the listener is added and removed.
359
660
  * // Providing `once: true` in the ReactiveListenerOptions
360
661
  * // removes the event after first callback.
361
662
  * const viewElement = document.querySelector("arcgis-map");
362
- * reactiveUtils.on(
663
+ * const handle = reactiveUtils.on(
363
664
  * () => viewElement,
364
665
  * "arcgisViewDrag",
365
666
  * (event) => {
@@ -370,11 +671,13 @@ export interface ReactiveOnOptions<Target> {
370
671
  * onListenerAdd: () => console.log("Drag listener added!"),
371
672
  * onListenerRemove: () => console.log("Drag listener removed!")
372
673
  * });
674
+ * // Remove the handle when it's no longer needed to stop watching for changes
675
+ * handle.remove();
373
676
  */
374
677
  export function on<Target extends EventTarget | EventedMixin>(getTarget: ReactiveOnExpression<Target | null | undefined>, eventName: string, callback: ReactiveOnCallback<any>, options?: ReactiveOnOptions<Target>): ResourceHandle;
375
678
 
376
679
  /**
377
- * Tracks any properties being evaluated by the `getValue` function. When `getValue` changes, it
680
+ * Tracks any properties being evaluated by the `getValue` expression. When `getValue` changes, it
378
681
  * returns a promise containing the value. This method only tracks a single change.
379
682
  *
380
683
  * @param getValue - Expression to be tracked.
@@ -382,15 +685,14 @@ export function on<Target extends EventTarget | EventedMixin>(getTarget: Reactiv
382
685
  * @returns A promise which resolves when the tracked expression changes.
383
686
  * @example
384
687
  * // Observe the first time a property equals a specific string value
385
- * // Equivalent to watchUtils.once()
386
688
  * reactiveUtils.once(
387
689
  * () => featureLayer.loadStatus === "loaded")
388
690
  * .then(() => {
389
691
  * console.log("featureLayer loadStatus is loaded.");
390
692
  * });
391
693
  * @example
392
- * // Use a comparison operator to observe a first time
393
- * // difference in numerical values
694
+ * // Use a comparison operator to resolve on the first tracked change that
695
+ * // matches this expression.
394
696
  * const viewElement = document.querySelector("arcgis-map");
395
697
  * const someFunction = async () => {
396
698
  * await reactiveUtils.once(() => viewElement.zoom > 20);
@@ -408,7 +710,7 @@ export function on<Target extends EventTarget | EventedMixin>(getTarget: Reactiv
408
710
  export function once<T>(getValue: ReactiveWatchExpression<T>, signal?: AbortSignal | AbortOptions | null | undefined): Promise<T>;
409
711
 
410
712
  /**
411
- * Tracks any properties being evaluated by the `getValue` function. When `getValue` becomes truthy,
713
+ * Tracks any properties being evaluated by the `getValue` expression. When `getValue` becomes truthy,
412
714
  * it returns a promise containing the value. This method only tracks a single change.
413
715
  *
414
716
  * @param getValue - Expression to be tracked.
@@ -416,31 +718,30 @@ export function once<T>(getValue: ReactiveWatchExpression<T>, signal?: AbortSign
416
718
  * @returns A promise which resolves once the tracked expression becomes truthy.
417
719
  * @example
418
720
  * // Check for the first time a property becomes truthy
419
- * // Equivalent to watchUtils.whenOnce()
420
721
  * const viewElement = document.querySelector("arcgis-map");
421
722
  * reactiveUtils.whenOnce(
422
- * () => viewElement.popup?.visible)
723
+ * () => viewElement.popupElement.open)
423
724
  * .then(() => {
424
725
  * console.log("Popup used for the first time");
425
726
  * });
426
727
  * @example
427
728
  * // Check for the first time a property becomes not truthy
428
- * // Equivalent to watchUtils.whenFalseOnce()
429
729
  * const someFunction = async () => {
430
730
  * await reactiveUtils.whenOnce(() => !layerView.updating);
431
731
  * console.log("LayerView is no longer updating");
432
732
  * }
433
733
  * @example
434
734
  * // Check for the first time a property becomes truthy
435
- * // And, use AbortController to potentially cancel the async callback
735
+ * // And, use AbortController to cancel the async callback
436
736
  * const abortController = new AbortController();
437
737
  * const viewElement = document.querySelector("arcgis-map");
438
738
  *
439
739
  * // Observe the map component's updating state
740
+ * // The updating property is false by default
440
741
  * reactiveUtils.whenOnce(
441
742
  * () => viewElement?.updating, {signal: abortController.signal})
442
743
  * .then((updating) => {
443
- * console.log(`Map component's updating state is ${updating.state}`)
744
+ * console.log(`Map component updated.`)
444
745
  * });
445
746
  *
446
747
  * // Cancel the async callback