@ixfx/components 0.3.2 → 0.4.0

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 (256) hide show
  1. package/bundle/index.d.ts +1086 -603
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +16153 -15296
  4. package/bundle/index.js.map +1 -1
  5. package/bundle/style.css +14 -4
  6. package/dist/ac-text.d.ts.map +1 -1
  7. package/dist/ac-text.js +11 -6
  8. package/dist/ac-text.js.map +1 -1
  9. package/dist/{button-DMt5XWUK.js → button-C3fLMKUv.js} +4 -4
  10. package/dist/{button-DMt5XWUK.js.map → button-C3fLMKUv.js.map} +1 -1
  11. package/dist/button.d.ts +1 -1
  12. package/dist/button.d.ts.map +1 -1
  13. package/dist/button.js +1 -1
  14. package/dist/checkbox.d.ts +2 -2
  15. package/dist/checkbox.d.ts.map +1 -1
  16. package/dist/checkbox.js +14 -8
  17. package/dist/checkbox.js.map +1 -1
  18. package/dist/{colour-C3MQIjFJ-BLXg8W3U.js → colour-C3MQIjFJ-vRCdr8W-.js} +146 -552
  19. package/dist/colour-C3MQIjFJ-vRCdr8W-.js.map +1 -0
  20. package/dist/{colour-picker-K6zu82lm.js → colour-picker-0sgAha1T.js} +14 -9
  21. package/dist/colour-picker-0sgAha1T.js.map +1 -0
  22. package/dist/colour-picker.d.ts +1 -1
  23. package/dist/colour-picker.js +1 -1
  24. package/dist/crumbs.d.ts +1 -1
  25. package/dist/crumbs.d.ts.map +1 -1
  26. package/dist/crumbs.js +11 -6
  27. package/dist/crumbs.js.map +1 -1
  28. package/dist/data-display.d.ts +9 -4
  29. package/dist/data-display.d.ts.map +1 -1
  30. package/dist/data-display.js +270 -43
  31. package/dist/data-display.js.map +1 -1
  32. package/dist/data-provider-DgI909FP.js +23 -0
  33. package/dist/data-provider-DgI909FP.js.map +1 -0
  34. package/dist/{decorate-D7rC1gLP.js → decorate-DdjvVHS-.js} +2 -2
  35. package/dist/{decorate-D7rC1gLP.js.map → decorate-DdjvVHS-.js.map} +1 -1
  36. package/dist/{defaults-C7elhuyJ.js → defaults-C3b9OWJD.js} +2 -2
  37. package/dist/{defaults-C7elhuyJ.js.map → defaults-C3b9OWJD.js.map} +1 -1
  38. package/dist/{dist-TAGYwaju.js → dist-CA13FvMn.js} +7 -66
  39. package/dist/dist-CA13FvMn.js.map +1 -0
  40. package/dist/editable-label.d.ts.map +1 -1
  41. package/dist/editable-label.js +3 -2
  42. package/dist/editable-label.js.map +1 -1
  43. package/dist/fallbacks-pNMOMx38.js +168 -0
  44. package/dist/fallbacks-pNMOMx38.js.map +1 -0
  45. package/dist/{hex-editor-DlfoA65y.d.ts → hex-editor-CMIxtNgT.d.ts} +1 -1
  46. package/dist/hex-editor-CMIxtNgT.d.ts.map +1 -0
  47. package/dist/{hex-editor-CsN_ySkH.js → hex-editor-WZrjRtvL.js} +3 -3
  48. package/dist/{hex-editor-CsN_ySkH.js.map → hex-editor-WZrjRtvL.js.map} +1 -1
  49. package/dist/hex.d.ts +1 -1
  50. package/dist/hex.js +1 -1
  51. package/dist/{highlight-TPbSHruI.js → highlight-B-eQrhhb.js} +1 -1
  52. package/dist/{highlight-TPbSHruI.js.map → highlight-B-eQrhhb.js.map} +1 -1
  53. package/dist/{icon-Dm_DHDz6.d.ts → icon-Bd5BiU4b.d.ts} +3 -3
  54. package/dist/icon-Bd5BiU4b.d.ts.map +1 -0
  55. package/dist/{icon-9NWTXtE1.js → icon-Ndo40kNO.js} +6 -5
  56. package/dist/icon-Ndo40kNO.js.map +1 -0
  57. package/dist/icons.d.ts +2 -2
  58. package/dist/icons.js +3 -3
  59. package/dist/{incr-search-DSKKsk6w.js → incr-search-CeERfijK.js} +2 -2
  60. package/dist/{incr-search-DSKKsk6w.js.map → incr-search-CeERfijK.js.map} +1 -1
  61. package/dist/incr-search.d.ts +1 -1
  62. package/dist/incr-search.js +2 -2
  63. package/dist/{index-hXFn14tM.d.ts → index-BMjri2-S.d.ts} +2 -2
  64. package/dist/{index-hXFn14tM.d.ts.map → index-BMjri2-S.d.ts.map} +1 -1
  65. package/dist/{index-DSlPeWLK.d.ts → index-CWpNcQKE.d.ts} +5 -5
  66. package/dist/index-CWpNcQKE.d.ts.map +1 -0
  67. package/dist/{index-DLkSKL4T.d.ts → index-CowKi2mo.d.ts} +1 -1
  68. package/dist/index-CowKi2mo.d.ts.map +1 -0
  69. package/dist/{index-B1hNR7Z9.d.ts → index-D87kRcEs.d.ts} +1 -1
  70. package/dist/{index-B1hNR7Z9.d.ts.map → index-D87kRcEs.d.ts.map} +1 -1
  71. package/dist/{index-CnL9krsH.d.ts → index-DgXpCg_G.d.ts} +32 -26
  72. package/dist/index-DgXpCg_G.d.ts.map +1 -0
  73. package/dist/{index-iZLld8Ca.d.ts → index-s_IhSnwc.d.ts} +2 -2
  74. package/dist/index-s_IhSnwc.d.ts.map +1 -0
  75. package/dist/index.d.ts +432 -121
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +2369 -1706
  78. package/dist/index.js.map +1 -1
  79. package/dist/interaction-D6efrBLo.js +1 -0
  80. package/dist/{keyboard-De_vOHLg.js → keyboard-CimiEskD.js} +1 -1
  81. package/dist/{keyboard-De_vOHLg.js.map → keyboard-CimiEskD.js.map} +1 -1
  82. package/dist/{labelled-input-base-CqPL5rKm.js → labelled-input-base-9K_w3oLj.js} +2 -2
  83. package/dist/{labelled-input-base-CqPL5rKm.js.map → labelled-input-base-9K_w3oLj.js.map} +1 -1
  84. package/dist/{labelled-input-base-BVvNeb5R.d.ts → labelled-input-base-ORb1rGq6.d.ts} +2 -2
  85. package/dist/labelled-input-base-ORb1rGq6.d.ts.map +1 -0
  86. package/dist/labelled-radial-input.d.ts +3 -3
  87. package/dist/labelled-radial-input.d.ts.map +1 -1
  88. package/dist/labelled-radial-input.js +7 -6
  89. package/dist/labelled-radial-input.js.map +1 -1
  90. package/dist/labelled-range-input.d.ts +1 -1
  91. package/dist/labelled-range-input.js +2 -2
  92. package/dist/led.d.ts +1 -1
  93. package/dist/led.d.ts.map +1 -1
  94. package/dist/led.js +2 -2
  95. package/dist/led.js.map +1 -1
  96. package/dist/{menu-item-CKRfP0pN.js → menu-item-BrIuORYD.js} +20 -10
  97. package/dist/menu-item-BrIuORYD.js.map +1 -0
  98. package/dist/{menu-item-ClQF2DKN.d.ts → menu-item-COx-Azgj.d.ts} +1 -1
  99. package/dist/menu-item-COx-Azgj.d.ts.map +1 -0
  100. package/dist/{menu-DJJuCm-5.js → menu-vjoiHZ13.js} +30 -17
  101. package/dist/menu-vjoiHZ13.js.map +1 -0
  102. package/dist/menu.d.ts +2 -2
  103. package/dist/menu.js +2 -2
  104. package/dist/miller.d.ts +2 -2
  105. package/dist/miller.d.ts.map +1 -1
  106. package/dist/miller.js +18 -11
  107. package/dist/miller.js.map +1 -1
  108. package/dist/narrowed-text.d.ts.map +1 -1
  109. package/dist/narrowed-text.js +7 -5
  110. package/dist/narrowed-text.js.map +1 -1
  111. package/dist/panel.d.ts +1 -1
  112. package/dist/panel.d.ts.map +1 -1
  113. package/dist/panel.js +5 -4
  114. package/dist/panel.js.map +1 -1
  115. package/dist/plots.d.ts +2 -2
  116. package/dist/plots.js +2 -2
  117. package/dist/polar-pad.d.ts +1 -1
  118. package/dist/polar-pad.d.ts.map +1 -1
  119. package/dist/polar-pad.js +10 -4
  120. package/dist/polar-pad.js.map +1 -1
  121. package/dist/{popup-ImtS9KnS.js → popup-DiWMxsWj.js} +1 -1
  122. package/dist/{popup-ImtS9KnS.js.map → popup-DiWMxsWj.js.map} +1 -1
  123. package/dist/prominence-DlFShic3.js +104 -0
  124. package/dist/prominence-DlFShic3.js.map +1 -0
  125. package/dist/{radial-input-LUSBEycd.d.ts → radial-input-CpQPs1Mp.d.ts} +1 -1
  126. package/dist/radial-input-CpQPs1Mp.d.ts.map +1 -0
  127. package/dist/{radial-input-DZA6WaFu.js → radial-input-DZ7eQCcM.js} +11 -6
  128. package/dist/radial-input-DZ7eQCcM.js.map +1 -0
  129. package/dist/radial-input.d.ts +1 -1
  130. package/dist/radial-input.js +1 -1
  131. package/dist/range-input.d.ts +1 -1
  132. package/dist/range-input.d.ts.map +1 -1
  133. package/dist/range-input.js +9 -4
  134. package/dist/range-input.js.map +1 -1
  135. package/dist/range.d.ts +1 -1
  136. package/dist/range.d.ts.map +1 -1
  137. package/dist/range.js +5 -3
  138. package/dist/range.js.map +1 -1
  139. package/dist/{registry-Q2gYQCHM.js → registry-CkW7q09Q.js} +1 -1
  140. package/dist/{registry-Q2gYQCHM.js.map → registry-CkW7q09Q.js.map} +1 -1
  141. package/dist/selecthorizontal.d.ts +1 -1
  142. package/dist/selecthorizontal.d.ts.map +1 -1
  143. package/dist/selecthorizontal.js +4 -3
  144. package/dist/selecthorizontal.js.map +1 -1
  145. package/dist/snap-container.d.ts.map +1 -1
  146. package/dist/snap-container.js +1 -1
  147. package/dist/split-layout.d.ts +1 -1
  148. package/dist/split-layout.d.ts.map +1 -1
  149. package/dist/split-layout.js +6 -5
  150. package/dist/split-layout.js.map +1 -1
  151. package/dist/style.css +14 -4
  152. package/dist/swipe.d.ts.map +1 -1
  153. package/dist/swipe.js +9 -4
  154. package/dist/swipe.js.map +1 -1
  155. package/dist/{tab-list-BnqISNvO.d.ts → tab-list-DLzb-m-I.d.ts} +2 -2
  156. package/dist/tab-list-DLzb-m-I.d.ts.map +1 -0
  157. package/dist/tabs.d.ts +1 -1
  158. package/dist/tabs.js +10 -4
  159. package/dist/tabs.js.map +1 -1
  160. package/dist/{tickled-controller-Cq1Va0rR.d.ts → tickled-controller-BjYCzGrU.d.ts} +2 -2
  161. package/dist/tickled-controller-BjYCzGrU.d.ts.map +1 -0
  162. package/dist/{tickled-styles-Bg3QbcrD.js → tickled-styles-fNDdqf6l.js} +1 -17
  163. package/dist/{tickled-styles-Bg3QbcrD.js.map → tickled-styles-fNDdqf6l.js.map} +1 -1
  164. package/dist/{timeline-Bh0PhlKW.js → timeline-2OFtN4Ta.js} +2 -2
  165. package/dist/{timeline-Bh0PhlKW.js.map → timeline-2OFtN4Ta.js.map} +1 -1
  166. package/dist/timeline.d.ts +1 -1
  167. package/dist/timeline.js +1 -1
  168. package/dist/{tooltip-DMxmBNky.js → tooltip-CJt3WLmN.js} +1 -1
  169. package/dist/{tooltip-DMxmBNky.js.map → tooltip-CJt3WLmN.js.map} +1 -1
  170. package/dist/{tooltip-CwGfb4lp.d.ts → tooltip-RGVIwHrZ.d.ts} +1 -1
  171. package/dist/{tooltip-CwGfb4lp.d.ts.map → tooltip-RGVIwHrZ.d.ts.map} +1 -1
  172. package/dist/{tree-CvvKbO-f.js → tree-CJWpMUvD.js} +113 -103
  173. package/dist/tree-CJWpMUvD.js.map +1 -0
  174. package/dist/{tree-component-D8Bg48tt.d.ts → tree-component-BcO26Xvt.d.ts} +65 -3
  175. package/dist/tree-component-BcO26Xvt.d.ts.map +1 -0
  176. package/dist/tree.d.ts +15 -15
  177. package/dist/tree.d.ts.map +1 -1
  178. package/dist/tree.js +1 -1
  179. package/dist/{types-BKaqnpwx.d.ts → types-DSfbtHs3.d.ts} +1 -1
  180. package/dist/types-DSfbtHs3.d.ts.map +1 -0
  181. package/dist/{xy-axis-DL0tfJDr.js → xy-axis-CK64haaK.js} +1831 -359
  182. package/dist/xy-axis-CK64haaK.js.map +1 -0
  183. package/dist/{xy-axis-D9uwpGTT.d.ts → xy-axis-McdUpcYr.d.ts} +102 -3
  184. package/dist/xy-axis-McdUpcYr.d.ts.map +1 -0
  185. package/dist/xy-pad.d.ts +1 -1
  186. package/dist/xy-pad.d.ts.map +1 -1
  187. package/dist/xy-pad.js +11 -6
  188. package/dist/xy-pad.js.map +1 -1
  189. package/docs-user/README.md +45 -0
  190. package/docs-user/ac-text.md +67 -0
  191. package/docs-user/ac-token.md +187 -0
  192. package/docs-user/button.md +355 -0
  193. package/docs-user/checkbox.md +62 -0
  194. package/docs-user/colour-picker.md +237 -0
  195. package/docs-user/crumbs.md +66 -0
  196. package/docs-user/data-display.md +98 -0
  197. package/docs-user/editable-label.md +244 -0
  198. package/docs-user/grouped-item-lister.md +424 -0
  199. package/docs-user/icons.md +191 -0
  200. package/docs-user/incr-search.md +94 -0
  201. package/docs-user/labelled-radial-input.md +204 -0
  202. package/docs-user/labelled-range-input.md +194 -0
  203. package/docs-user/led.md +40 -0
  204. package/docs-user/menu.md +319 -0
  205. package/docs-user/miller.md +453 -0
  206. package/docs-user/narrowed-text.md +72 -0
  207. package/docs-user/panel.md +250 -0
  208. package/docs-user/plots.md +361 -0
  209. package/docs-user/polar-pad.md +228 -0
  210. package/docs-user/radial-input.md +559 -0
  211. package/docs-user/range-input.md +264 -0
  212. package/docs-user/range.md +12 -0
  213. package/docs-user/selecthorizontal.md +32 -0
  214. package/docs-user/snap-container.md +132 -0
  215. package/docs-user/split-layout.md +232 -0
  216. package/docs-user/swipe.md +44 -0
  217. package/docs-user/tabs.md +217 -0
  218. package/docs-user/timeline.md +116 -0
  219. package/docs-user/transitory-label.md +120 -0
  220. package/docs-user/tree.md +592 -0
  221. package/docs-user/user-catalog.md +165 -0
  222. package/docs-user/user-theming.md +379 -0
  223. package/docs-user/util.md +122 -0
  224. package/docs-user/vertical-list.md +351 -0
  225. package/docs-user/xy-pad.md +94 -0
  226. package/package.json +18 -17
  227. package/dist/colour-C3MQIjFJ-BLXg8W3U.js.map +0 -1
  228. package/dist/colour-picker-K6zu82lm.js.map +0 -1
  229. package/dist/dist-BX0OVIm7.js +0 -1290
  230. package/dist/dist-BX0OVIm7.js.map +0 -1
  231. package/dist/dist-TAGYwaju.js.map +0 -1
  232. package/dist/hex-editor-DlfoA65y.d.ts.map +0 -1
  233. package/dist/icon-9NWTXtE1.js.map +0 -1
  234. package/dist/icon-Dm_DHDz6.d.ts.map +0 -1
  235. package/dist/index-CnL9krsH.d.ts.map +0 -1
  236. package/dist/index-DLkSKL4T.d.ts.map +0 -1
  237. package/dist/index-DSlPeWLK.d.ts.map +0 -1
  238. package/dist/index-iZLld8Ca.d.ts.map +0 -1
  239. package/dist/interaction-DG7X1rhI.js +0 -1
  240. package/dist/labelled-input-base-BVvNeb5R.d.ts.map +0 -1
  241. package/dist/menu-DJJuCm-5.js.map +0 -1
  242. package/dist/menu-item-CKRfP0pN.js.map +0 -1
  243. package/dist/menu-item-ClQF2DKN.d.ts.map +0 -1
  244. package/dist/prominence--ic9uWBl.js +0 -98
  245. package/dist/prominence--ic9uWBl.js.map +0 -1
  246. package/dist/radial-input-DZA6WaFu.js.map +0 -1
  247. package/dist/radial-input-LUSBEycd.d.ts.map +0 -1
  248. package/dist/tab-list-BnqISNvO.d.ts.map +0 -1
  249. package/dist/tickled-controller-Cq1Va0rR.d.ts.map +0 -1
  250. package/dist/tree-CvvKbO-f.js.map +0 -1
  251. package/dist/tree-component-D8Bg48tt.d.ts.map +0 -1
  252. package/dist/types-BKaqnpwx.d.ts.map +0 -1
  253. package/dist/xy-axis-D9uwpGTT.d.ts.map +0 -1
  254. package/dist/xy-axis-DL0tfJDr.js.map +0 -1
  255. /package/bundle/{chunk-pbuEa-1d.js → chunk-D7D4PA-g.js} +0 -0
  256. /package/dist/{chunk-pbuEa-1d.js → chunk-D7D4PA-g.js} +0 -0
@@ -1,17 +1,15 @@
1
- import { n as safeCustomElement, t as __decorate } from "./decorate-D7rC1gLP.js";
2
- import { c as round } from "./dist-TAGYwaju.js";
3
- import { i as records_exports } from "./dist-BX0OVIm7.js";
1
+ import { t as themeFallbacks } from "./fallbacks-pNMOMx38.js";
2
+ import { n as safeCustomElement, t as __decorate } from "./decorate-DdjvVHS-.js";
3
+ import { c as round, s as rangeStream } from "./dist-CA13FvMn.js";
4
4
  import { LitElement, css } from "lit";
5
- //#region src/data-display.ts
6
- var _DataDisplayComponent;
5
+ import { property } from "lit/decorators.js";
6
+ //#region src/data-display/data-display.ts
7
7
  let DataDisplayComponent = class DataDisplayComponent extends LitElement {
8
8
  static {
9
- _DataDisplayComponent = this;
10
- }
11
- static {
12
- this.styles = css`
9
+ this.styles = [themeFallbacks, css`
13
10
  :host {
14
11
  display: block;
12
+ width: fit-content;
15
13
  }
16
14
  section {
17
15
  background: var(--surface-3);
@@ -20,21 +18,57 @@ let DataDisplayComponent = class DataDisplayComponent extends LitElement {
20
18
  padding: var(--space-m);
21
19
  font-family: var(--font-mono);
22
20
  display: grid;
23
- grid-template-columns: repeat(2, 1fr);
21
+ grid-template-columns: auto auto;
22
+ column-gap: var(--space-s);
23
+ }
24
+ .row {
25
+ display: contents;
26
+ }
27
+ .row > label {
28
+ font-weight: bold;
29
+ text-align: end;
30
+ justify-self: end;
31
+ padding: 2px 0;
32
+ }
33
+ .row > :not(label) {
34
+ padding: 2px 0;
35
+ }
36
+ .row > ixfx-led {
37
+ align-self: center;
24
38
  }
25
- div {
26
- border: var(--border-subtle);
39
+ .value {
40
+ font-variant-numeric: tabular-nums;
41
+ white-space: pre;
27
42
  }
28
- `;
43
+ `];
29
44
  }
45
+ #config;
46
+ #previousValues;
47
+ #rangeStreams;
48
+ #currentData;
30
49
  constructor() {
31
50
  super();
51
+ this.automap = false;
52
+ this.#config = /* @__PURE__ */ new Map();
53
+ this.#previousValues = /* @__PURE__ */ new Map();
54
+ this.#rangeStreams = /* @__PURE__ */ new Map();
32
55
  this._container = document.createElement(`section`);
33
56
  }
34
57
  connectedCallback() {
35
58
  super.connectedCallback();
36
59
  this.renderRoot.append(this._container);
37
60
  }
61
+ configure(config) {
62
+ this.#config.clear();
63
+ for (const [path, style, options] of config) this.#config.set(path, {
64
+ style,
65
+ options
66
+ });
67
+ this._container.innerHTML = ``;
68
+ this.#previousValues.clear();
69
+ this.#rangeStreams.clear();
70
+ if (this.#currentData !== void 0) this.#renderAll(this.#currentData);
71
+ }
38
72
  formatValue(v, options = {}) {
39
73
  if (v === null) return `(null)`;
40
74
  if (v === void 0) return `(undefined)`;
@@ -44,7 +78,8 @@ let DataDisplayComponent = class DataDisplayComponent extends LitElement {
44
78
  let vAsNumber = v;
45
79
  if (options.roundNumbers !== void 0) vAsNumber = round(options.roundNumbers, v);
46
80
  if (options.precision !== void 0) return vAsNumber.toFixed(options.precision);
47
- return vAsNumber.toString();
81
+ const formatted = vAsNumber.toFixed(2);
82
+ return vAsNumber >= 0 ? ` ${formatted}` : formatted;
48
83
  }
49
84
  return JSON.stringify(v);
50
85
  }
@@ -53,30 +88,12 @@ let DataDisplayComponent = class DataDisplayComponent extends LitElement {
53
88
  this.innerHTML = ``;
54
89
  return;
55
90
  }
56
- for (const [key, value] of Object.entries(o)) {
57
- const domKey = `path-${key}`;
58
- if (typeof value === `object`) {
59
- const valueElement = this.getOrCreate(domKey, (parent) => {
60
- parent.classList.add(`row`, `nested`);
61
- const label = document.createElement(`label`);
62
- label.textContent = key;
63
- const valueElement = new _DataDisplayComponent();
64
- parent.append(label, valueElement);
65
- }).querySelector(`ixfx-data-display`);
66
- if (valueElement !== null) valueElement.updateData(value);
67
- } else {
68
- const valueElement = this.getOrCreate(domKey, (parent) => {
69
- parent.classList.add(`row`);
70
- const label = document.createElement(`label`);
71
- label.textContent = key;
72
- const valueElement = document.createElement(`div`);
73
- valueElement.textContent = this.formatValue(value);
74
- parent.append(label, valueElement);
75
- }).querySelector(`div`);
76
- if (valueElement === null) console.warn(`data-display.displayData Unexpected case?`);
77
- else valueElement.innerHTML = this.formatValue(value);
78
- }
79
- }
91
+ this.#renderAll(o);
92
+ }
93
+ updateData(value) {
94
+ this.#currentData = value;
95
+ this.#renderAll(value);
96
+ this.previousValue = value;
80
97
  }
81
98
  getOrCreate(path, init) {
82
99
  const element = this.renderRoot.querySelector(`#${path}`);
@@ -87,13 +104,223 @@ let DataDisplayComponent = class DataDisplayComponent extends LitElement {
87
104
  this._container.append(elementCreated);
88
105
  return elementCreated;
89
106
  }
90
- updateData(value) {
91
- if (this.previousValue === void 0) this.displayData(value);
92
- else this.displayData(records_exports.changedProperties(this.previousValue, value));
93
- this.previousValue = value;
107
+ #renderAll(data) {
108
+ const activePaths = /* @__PURE__ */ new Set();
109
+ this.#walk(data, ``, activePaths);
110
+ this.#cleanupPaths(activePaths);
111
+ }
112
+ #walk(data, basePath, activePaths) {
113
+ for (const [key, value] of Object.entries(data)) {
114
+ const fullPath = basePath ? `${basePath}.${key}` : key;
115
+ activePaths.add(fullPath);
116
+ const config = this.#config.get(fullPath);
117
+ if (config !== void 0) {
118
+ if (config.style !== `hide`) {
119
+ const row = this.#ensureRow(fullPath, key);
120
+ this.#updateRenderer(row, fullPath, config.style, value, config.options);
121
+ }
122
+ continue;
123
+ }
124
+ if (typeof value === `object` && value !== null && !Array.isArray(value)) if (this.#hasDescendantConfig(fullPath)) this.#walk(value, fullPath, activePaths);
125
+ else if (this.automap) {
126
+ const row = this.#ensureRow(fullPath, key);
127
+ this.#renderNestedDisplay(row, value, true);
128
+ } else {
129
+ const row = this.#ensureRow(fullPath, key);
130
+ this.#renderNestedDisplay(row, value);
131
+ }
132
+ else {
133
+ const autoStyle = this.#determineAutoStyle(value);
134
+ if (autoStyle !== void 0) {
135
+ const row = this.#ensureRow(fullPath, key);
136
+ this.#updateRenderer(row, fullPath, autoStyle, value, void 0);
137
+ } else {
138
+ const row = this.#ensureRow(fullPath, key);
139
+ this.#renderText(row, this.formatValue(value));
140
+ }
141
+ }
142
+ }
143
+ }
144
+ #hasDescendantConfig(path) {
145
+ const prefix = path ? `${path}.` : ``;
146
+ for (const configPath of this.#config.keys()) if (configPath.startsWith(prefix)) return true;
147
+ return false;
148
+ }
149
+ #determineAutoStyle(value) {
150
+ if (!this.automap) return void 0;
151
+ if (typeof value === `boolean`) return `led`;
152
+ if (typeof value === `number`) return `plot`;
153
+ }
154
+ #ensureRow(path, label) {
155
+ const id = `path-${path}`;
156
+ let row = this.renderRoot.querySelector(`#${CSS.escape(id)}`);
157
+ if (row !== null) return row;
158
+ row = document.createElement(`div`);
159
+ row.id = id;
160
+ row.classList.add(`row`);
161
+ const labelEl = document.createElement(`label`);
162
+ labelEl.textContent = label;
163
+ row.append(labelEl);
164
+ this._container.append(row);
165
+ return row;
166
+ }
167
+ #updateRenderer(row, path, style, value, options) {
168
+ const tag = this.#rendererTag(style, value);
169
+ if (tag === null) return;
170
+ const el = this.#getOrCreateRendererElement(row, tag);
171
+ if (el === null) return;
172
+ this.#applyValue(el, tag, style, path, value, options);
173
+ }
174
+ #rendererTag(style, value) {
175
+ switch (style) {
176
+ case `hide`: return null;
177
+ case `led`: return `ixfx-led`;
178
+ case `plot`:
179
+ if (typeof value === `number`) return `ixfx-plot-single-axis`;
180
+ if (typeof value === `object` && value !== null) return `ixfx-plot-multi-axis`;
181
+ return `span`;
182
+ case `plot-xy`: return `ixfx-plot-xy-axis`;
183
+ case `plot-heat`:
184
+ case `plot-histogram`: return `ixfx-plot-histogram`;
185
+ case `time-elapsed`: return `span`;
186
+ }
187
+ }
188
+ #getOrCreateRendererElement(row, tag) {
189
+ const existing = row.querySelector(`:scope > [data-renderer]`);
190
+ if (existing !== null) {
191
+ if (existing.tagName.toLowerCase() === tag) return existing;
192
+ existing.remove();
193
+ }
194
+ const el = document.createElement(tag);
195
+ el.dataset.renderer = ``;
196
+ if (tag.startsWith(`ixfx-plot`)) {
197
+ el.style.height = `1.4em`;
198
+ if (tag === `ixfx-plot-xy-axis`) el.style.width = `1.4em`;
199
+ else el.style.width = `5em`;
200
+ }
201
+ row.append(el);
202
+ return el;
203
+ }
204
+ #applyValue(el, _tag, style, path, value, options) {
205
+ const changed = this.#previousValues.get(path) !== value;
206
+ switch (style) {
207
+ case `led`:
208
+ this.#applyLed(el, path, value, options);
209
+ break;
210
+ case `plot`:
211
+ if (typeof value === `number`) {
212
+ if (changed) el.add(value);
213
+ } else if (typeof value === `object` && value !== null && changed) if (Array.isArray(value)) {
214
+ const record = {};
215
+ value.forEach((v, i) => {
216
+ if (typeof v === `number`) record[String(i)] = v;
217
+ });
218
+ if (Object.keys(record).length > 0) el.addData(record);
219
+ } else el.addData(value);
220
+ this.#applyPlotOptions(el, style, options);
221
+ break;
222
+ case `plot-xy`:
223
+ if (changed) this.#applyPlotXy(el, value);
224
+ this.#applyPlotOptions(el, style, options);
225
+ break;
226
+ case `plot-heat`: el.style.setProperty(`--plot-histogram-bar-length`, `1`);
227
+ case `plot-histogram`:
228
+ if (typeof value === `number` && changed) el.add(value);
229
+ this.#applyPlotOptions(el, style, options);
230
+ break;
231
+ case `time-elapsed`:
232
+ el.textContent = this.#formatTimeElapsed(value);
233
+ break;
234
+ }
235
+ this.#previousValues.set(path, value);
236
+ }
237
+ #applyLed(el, path, value, options) {
238
+ const led = el;
239
+ if (typeof value === `boolean`) {
240
+ led.lit = value;
241
+ led.value = value ? 1 : 0;
242
+ } else if (typeof value === `number`) {
243
+ let rs = this.#rangeStreams.get(path);
244
+ if (rs === void 0) {
245
+ rs = rangeStream();
246
+ this.#rangeStreams.set(path, rs);
247
+ }
248
+ const range = rs.seen(value);
249
+ const normalized = range.max !== range.min ? (value - range.min) / (range.max - range.min) : .5;
250
+ led.value = normalized;
251
+ led.lit = normalized > .3;
252
+ }
253
+ if (options?.color !== void 0) led.color = options.color;
254
+ }
255
+ #applyPlotXy(el, value) {
256
+ const xy = el;
257
+ if (Array.isArray(value) && value.length >= 2) xy.add(value[0], value[1]);
258
+ else if (typeof value === `object` && value !== null) {
259
+ const obj = value;
260
+ if (`x` in obj && `y` in obj) xy.add(obj.x, obj.y);
261
+ else {
262
+ const entries = Object.entries(obj).filter(([_, v]) => typeof v === `number`);
263
+ if (entries.length >= 2) xy.add(entries[0][1], entries[1][1]);
264
+ }
265
+ }
266
+ }
267
+ #applyPlotOptions(el, _style, options) {
268
+ if (options === void 0) return;
269
+ const target = el;
270
+ if (typeof options.capacity === `number`) target.capacity = options.capacity;
271
+ if (typeof options.resolution === `number`) target.resolution = options.resolution;
272
+ if (typeof options.drawStyle === `string`) target.drawStyle = options.drawStyle;
273
+ if (typeof options.orientation === `string`) target.orientation = options.orientation;
274
+ if (typeof options.layout === `string`) target.layout = options.layout;
275
+ }
276
+ #formatTimeElapsed(value) {
277
+ let timestamp;
278
+ if (value instanceof Date) timestamp = value.getTime();
279
+ else if (typeof value === `number`) if (value > 0xe8d4a51000) timestamp = value;
280
+ else timestamp = Date.now();
281
+ else if (typeof value === `string`) timestamp = new Date(value).getTime();
282
+ else return String(value);
283
+ if (Number.isNaN(timestamp)) return String(value);
284
+ const elapsed = Date.now() - timestamp;
285
+ const abs = Math.abs(elapsed);
286
+ if (abs < 1e3) return `${abs}ms`;
287
+ if (abs < 6e4) return `${(abs / 1e3).toFixed(1)}s`;
288
+ if (abs < 36e5) return `${(abs / 6e4).toFixed(1)}mins`;
289
+ if (abs < 864e5) return `${(abs / 36e5).toFixed(1)}h`;
290
+ return `${(abs / 864e5).toFixed(1)}d`;
291
+ }
292
+ #renderText(row, text) {
293
+ let valueEl = row.querySelector(`:scope > .value`);
294
+ if (valueEl === null) {
295
+ valueEl = document.createElement(`span`);
296
+ valueEl.classList.add(`value`);
297
+ row.append(valueEl);
298
+ }
299
+ valueEl.textContent = text;
300
+ }
301
+ #renderNestedDisplay(row, data, automapChild = false) {
302
+ let child = row.querySelector(`:scope > ixfx-data-display`);
303
+ if (child === null) {
304
+ child = document.createElement(`ixfx-data-display`);
305
+ row.append(child);
306
+ }
307
+ child.automap = automapChild;
308
+ child.updateData(data);
309
+ }
310
+ #cleanupPaths(activePaths) {
311
+ const rows = this._container.querySelectorAll(`[id^="path-"]`);
312
+ for (const row of rows) {
313
+ const path = row.id.slice(5);
314
+ if (!activePaths.has(path)) {
315
+ row.remove();
316
+ this.#rangeStreams.delete(path);
317
+ this.#previousValues.delete(path);
318
+ }
319
+ }
94
320
  }
95
321
  };
96
- DataDisplayComponent = _DataDisplayComponent = __decorate([safeCustomElement(`ixfx-data-display`)], DataDisplayComponent);
322
+ __decorate([property({ type: Boolean })], DataDisplayComponent.prototype, "automap", void 0);
323
+ DataDisplayComponent = __decorate([safeCustomElement(`ixfx-data-display`)], DataDisplayComponent);
97
324
  //#endregion
98
325
  export { DataDisplayComponent };
99
326
 
@@ -1 +1 @@
1
- {"version":3,"file":"data-display.js","names":["Records","customElement"],"sources":["../src/data-display.ts"],"sourcesContent":["import { Records } from \"@ixfx/core\";\nimport { round } from \"@ixfx/numbers\";\n\nimport { css, LitElement } from 'lit';\nimport { safeCustomElement as customElement } from './util/custom-elements.js';\n\nexport type FormattingOptions = {\n readonly precision?: number;\n readonly roundNumbers?: number;\n};\n\n@customElement(`ixfx-data-display`)\nexport class DataDisplayComponent extends LitElement {\n static override styles = css`\n :host {\n display: block;\n }\n section {\n background: var(--surface-3);\n color: var(--surface-2-text);\n border: var(--border);\n padding: var(--space-m);\n font-family: var(--font-mono);\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n }\n div {\n border: var(--border-subtle);\n }\n `;\n\n previousValue: Record<string, unknown> | undefined;\n _container: HTMLElement;\n\n constructor() {\n super();\n this._container = document.createElement(`section`);\n }\n\n override connectedCallback() {\n super.connectedCallback();\n this.renderRoot.append(this._container);\n }\n\n formatValue(v: unknown, options: FormattingOptions = {}): string {\n if (v === null)\n return `(null)`;\n if (v === undefined)\n return `(undefined)`;\n if (typeof v === `boolean`)\n return v ? `true` : `false`;\n if (typeof v === `string`)\n return `\"${v}\"`;\n if (typeof v === `number`) {\n let vAsNumber = v;\n if (options.roundNumbers !== undefined)\n vAsNumber = round(options.roundNumbers, v);\n if (options.precision !== undefined)\n return vAsNumber.toFixed(options.precision);\n return vAsNumber.toString();\n }\n return JSON.stringify(v);\n }\n\n displayData(o: Record<string, unknown> | unknown[]) {\n if (o === null) {\n this.innerHTML = ``;\n return;\n }\n for (const [key, value] of Object.entries(o)) {\n const domKey = `path-${key}`;\n if (typeof value === `object`) {\n const element = this.getOrCreate(domKey, (parent) => {\n parent.classList.add(`row`, `nested`);\n const label = document.createElement(`label`);\n label.textContent = key;\n const valueElement = new DataDisplayComponent();\n parent.append(label, valueElement);\n });\n const valueElement = element.querySelector<DataDisplayComponent>(`ixfx-data-display`);\n if (valueElement !== null) {\n valueElement.updateData(value as Record<string, unknown>);\n }\n } else {\n const element = this.getOrCreate(domKey, (parent) => {\n parent.classList.add(`row`);\n const label = document.createElement(`label`);\n label.textContent = key;\n const valueElement = document.createElement(`div`);\n valueElement.textContent = this.formatValue(value);\n parent.append(label, valueElement);\n });\n const valueElement = element.querySelector(`div`);\n if (valueElement === null) {\n console.warn(`data-display.displayData Unexpected case?`);\n // debugger;\n } else {\n valueElement.innerHTML = this.formatValue(value);\n }\n }\n }\n\n // const paths = getFieldPaths(o);\n // console.log(`paths: ${ JSON.stringify(paths) }`);\n\n // for (const path of paths) {\n\n // }\n }\n\n getOrCreate(path: string, init?: (parent: HTMLElement) => void): HTMLElement {\n const element = this.renderRoot.querySelector(`#${path}`) as HTMLElement | null;\n if (element !== null)\n return element;\n\n const elementCreated = document.createElement(`div`);\n elementCreated.id = path;\n if (init)\n init(elementCreated);\n this._container.append(elementCreated);\n return elementCreated;\n }\n\n updateData(value: Record<string, unknown>) {\n if (this.previousValue === undefined) {\n this.displayData(value);\n } else {\n this.displayData(Records.changedProperties(this.previousValue, value));\n }\n this.previousValue = value;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-data-display': DataDisplayComponent;\n }\n}\n"],"mappings":";;;;;;AAYO,IAAA,uBAAA,MAAM,6BAA6B,WAAW;;;;;gBAC1B,GAAG;;;;;;;;;;;;;;;;;;CAqB5B,cAAc;EACZ,MAAM;EACN,KAAK,aAAa,SAAS,cAAc,SAAS;CACpD;CAEA,oBAA6B;EAC3B,MAAM,kBAAkB;EACxB,KAAK,WAAW,OAAO,KAAK,UAAU;CACxC;CAEA,YAAY,GAAY,UAA6B,CAAC,GAAW;EAC/D,IAAI,MAAM,MACR,OAAO;EACT,IAAI,MAAM,KAAA,GACR,OAAO;EACT,IAAI,OAAO,MAAM,WACf,OAAO,IAAI,SAAS;EACtB,IAAI,OAAO,MAAM,UACf,OAAO,IAAI,EAAE;EACf,IAAI,OAAO,MAAM,UAAU;GACzB,IAAI,YAAY;GAChB,IAAI,QAAQ,iBAAiB,KAAA,GAC3B,YAAY,MAAM,QAAQ,cAAc,CAAC;GAC3C,IAAI,QAAQ,cAAc,KAAA,GACxB,OAAO,UAAU,QAAQ,QAAQ,SAAS;GAC5C,OAAO,UAAU,SAAS;EAC5B;EACA,OAAO,KAAK,UAAU,CAAC;CACzB;CAEA,YAAY,GAAwC;EAClD,IAAI,MAAM,MAAM;GACd,KAAK,YAAY;GACjB;EACF;EACA,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,CAAC,GAAG;GAC5C,MAAM,SAAS,QAAQ;GACvB,IAAI,OAAO,UAAU,UAAU;IAQ7B,MAAM,eAPU,KAAK,YAAY,SAAS,WAAW;KACnD,OAAO,UAAU,IAAI,OAAO,QAAQ;KACpC,MAAM,QAAQ,SAAS,cAAc,OAAO;KAC5C,MAAM,cAAc;KACpB,MAAM,eAAe,IAAA,sBAAyB;KAC9C,OAAO,OAAO,OAAO,YAAY;IACnC,CAC2B,EAAE,cAAoC,mBAAmB;IACpF,IAAI,iBAAiB,MACnB,aAAa,WAAW,KAAgC;GAE5D,OAAO;IASL,MAAM,eARU,KAAK,YAAY,SAAS,WAAW;KACnD,OAAO,UAAU,IAAI,KAAK;KAC1B,MAAM,QAAQ,SAAS,cAAc,OAAO;KAC5C,MAAM,cAAc;KACpB,MAAM,eAAe,SAAS,cAAc,KAAK;KACjD,aAAa,cAAc,KAAK,YAAY,KAAK;KACjD,OAAO,OAAO,OAAO,YAAY;IACnC,CAC2B,EAAE,cAAc,KAAK;IAChD,IAAI,iBAAiB,MACnB,QAAQ,KAAK,2CAA2C;SAGxD,aAAa,YAAY,KAAK,YAAY,KAAK;GAEnD;EACF;CAQF;CAEA,YAAY,MAAc,MAAmD;EAC3E,MAAM,UAAU,KAAK,WAAW,cAAc,IAAI,MAAM;EACxD,IAAI,YAAY,MACd,OAAO;EAET,MAAM,iBAAiB,SAAS,cAAc,KAAK;EACnD,eAAe,KAAK;EACpB,IAAI,MACF,KAAK,cAAc;EACrB,KAAK,WAAW,OAAO,cAAc;EACrC,OAAO;CACT;CAEA,WAAW,OAAgC;EACzC,IAAI,KAAK,kBAAkB,KAAA,GACzB,KAAK,YAAY,KAAK;OAEtB,KAAK,YAAYA,gBAAQ,kBAAkB,KAAK,eAAe,KAAK,CAAC;EAEvE,KAAK,gBAAgB;CACvB;AACF;2DAxHCC,kBAAc,mBAAmB,CAAA,GAAA,oBAAA"}
1
+ {"version":3,"file":"data-display.js","names":["#config","#previousValues","#rangeStreams","#currentData","#renderAll","#walk","#cleanupPaths","#ensureRow","#updateRenderer","#hasDescendantConfig","#renderNestedDisplay","#determineAutoStyle","#renderText","#rendererTag","#getOrCreateRendererElement","#applyValue","#applyLed","#applyPlotOptions","#applyPlotXy","#formatTimeElapsed","customElement"],"sources":["../src/data-display/data-display.ts"],"sourcesContent":["import { rangeStream, round } from \"@ixfx/numbers\";\n\nimport { css, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\nexport type RendererStyle\n = | `led`\n | `plot`\n | `plot-xy`\n | `plot-heat`\n | `plot-histogram`\n | `time-elapsed`\n | `hide`;\n\nexport type ConfigEntry = readonly [\n path: string,\n style: RendererStyle,\n options?: Record<string, unknown>,\n];\n\nexport type FormattingOptions = {\n readonly precision?: number;\n readonly roundNumbers?: number;\n};\n\ntype ConfigRecord = {\n readonly style: RendererStyle;\n readonly options?: Record<string, unknown>;\n};\n\ntype RangeStream = ReturnType<typeof rangeStream>;\n\n@customElement(`ixfx-data-display`)\nexport class DataDisplayComponent extends LitElement {\n static override styles = [themeFallbacks, css`\n :host {\n display: block;\n width: fit-content;\n }\n section {\n background: var(--surface-3);\n color: var(--surface-2-text);\n border: var(--border);\n padding: var(--space-m);\n font-family: var(--font-mono);\n display: grid;\n grid-template-columns: auto auto;\n column-gap: var(--space-s);\n }\n .row {\n display: contents;\n }\n .row > label {\n font-weight: bold;\n text-align: end;\n justify-self: end;\n padding: 2px 0;\n }\n .row > :not(label) {\n padding: 2px 0;\n }\n .row > ixfx-led {\n align-self: center;\n }\n .value {\n font-variant-numeric: tabular-nums;\n white-space: pre;\n }\n `];\n\n @property({ type: Boolean })\n automap = false;\n\n previousValue: Record<string, unknown> | undefined;\n _container: HTMLElement;\n\n #config = new Map<string, ConfigRecord>();\n #previousValues = new Map<string, unknown>();\n #rangeStreams = new Map<string, RangeStream>();\n #currentData: Record<string, unknown> | undefined;\n\n constructor() {\n super();\n this._container = document.createElement(`section`);\n }\n\n override connectedCallback() {\n super.connectedCallback();\n this.renderRoot.append(this._container);\n }\n\n configure(config: ConfigEntry[]) {\n this.#config.clear();\n for (const [path, style, options] of config) {\n this.#config.set(path, { style, options });\n }\n this._container.innerHTML = ``;\n this.#previousValues.clear();\n this.#rangeStreams.clear();\n if (this.#currentData !== undefined) {\n this.#renderAll(this.#currentData);\n }\n }\n\n formatValue(v: unknown, options: FormattingOptions = {}): string {\n if (v === null)\n return `(null)`;\n if (v === undefined)\n return `(undefined)`;\n if (typeof v === `boolean`)\n return v ? `true` : `false`;\n if (typeof v === `string`)\n return `\"${v}\"`;\n if (typeof v === `number`) {\n let vAsNumber = v;\n if (options.roundNumbers !== undefined)\n vAsNumber = round(options.roundNumbers, v);\n if (options.precision !== undefined)\n return vAsNumber.toFixed(options.precision);\n const formatted = vAsNumber.toFixed(2);\n return vAsNumber >= 0 ? ` ${formatted}` : formatted;\n }\n return JSON.stringify(v);\n }\n\n displayData(o: Record<string, unknown> | unknown[]) {\n if (o === null) {\n this.innerHTML = ``;\n return;\n }\n this.#renderAll(o as Record<string, unknown>);\n }\n\n updateData(value: Record<string, unknown>) {\n this.#currentData = value;\n this.#renderAll(value);\n this.previousValue = value;\n }\n\n getOrCreate(path: string, init?: (parent: HTMLElement) => void): HTMLElement {\n const element = this.renderRoot.querySelector(`#${path}`) as HTMLElement | null;\n if (element !== null)\n return element;\n\n const elementCreated = document.createElement(`div`);\n elementCreated.id = path;\n if (init)\n init(elementCreated);\n this._container.append(elementCreated);\n return elementCreated;\n }\n\n #renderAll(data: Record<string, unknown>) {\n const activePaths = new Set<string>();\n this.#walk(data, ``, activePaths);\n this.#cleanupPaths(activePaths);\n }\n\n #walk(\n data: Record<string, unknown>,\n basePath: string,\n activePaths: Set<string>,\n ) {\n for (const [key, value] of Object.entries(data)) {\n const fullPath = basePath ? `${basePath}.${key}` : key;\n activePaths.add(fullPath);\n\n const config = this.#config.get(fullPath);\n\n if (config !== undefined) {\n if (config.style !== `hide`) {\n const row = this.#ensureRow(fullPath, key);\n this.#updateRenderer(row, fullPath, config.style, value, config.options);\n }\n continue;\n }\n\n if (typeof value === `object` && value !== null && !Array.isArray(value)) {\n if (this.#hasDescendantConfig(fullPath)) {\n this.#walk(value as Record<string, unknown>, fullPath, activePaths);\n } else if (this.automap) {\n const row = this.#ensureRow(fullPath, key);\n this.#renderNestedDisplay(row, value as Record<string, unknown>, true);\n } else {\n const row = this.#ensureRow(fullPath, key);\n this.#renderNestedDisplay(row, value as Record<string, unknown>);\n }\n } else {\n const autoStyle = this.#determineAutoStyle(value);\n if (autoStyle !== undefined) {\n const row = this.#ensureRow(fullPath, key);\n this.#updateRenderer(row, fullPath, autoStyle, value, undefined);\n } else {\n const row = this.#ensureRow(fullPath, key);\n this.#renderText(row, this.formatValue(value));\n }\n }\n }\n }\n\n #hasDescendantConfig(path: string): boolean {\n const prefix = path ? `${path}.` : ``;\n for (const configPath of this.#config.keys()) {\n if (configPath.startsWith(prefix))\n return true;\n }\n return false;\n }\n\n #determineAutoStyle(value: unknown): RendererStyle | undefined {\n if (!this.automap)\n return undefined;\n if (typeof value === `boolean`)\n return `led`;\n if (typeof value === `number`)\n return `plot`;\n return undefined;\n }\n\n #ensureRow(path: string, label: string): HTMLElement {\n const id = `path-${path}`;\n let row = this.renderRoot.querySelector(`#${CSS.escape(id)}`) as HTMLElement | null;\n if (row !== null)\n return row;\n\n row = document.createElement(`div`);\n row.id = id;\n row.classList.add(`row`);\n\n const labelEl = document.createElement(`label`);\n labelEl.textContent = label;\n row.append(labelEl);\n\n this._container.append(row);\n return row;\n }\n\n #updateRenderer(\n row: HTMLElement,\n path: string,\n style: RendererStyle,\n value: unknown,\n options?: Record<string, unknown>,\n ) {\n const tag = this.#rendererTag(style, value);\n if (tag === null)\n return;\n\n const el = this.#getOrCreateRendererElement(row, tag);\n if (el === null)\n return;\n\n this.#applyValue(el, tag, style, path, value, options);\n }\n\n #rendererTag(style: RendererStyle, value: unknown): string | null {\n switch (style) {\n case `hide`:\n return null;\n case `led`:\n return `ixfx-led`;\n case `plot`:\n if (typeof value === `number`)\n return `ixfx-plot-single-axis`;\n if (typeof value === `object` && value !== null)\n return `ixfx-plot-multi-axis`;\n return `span`;\n case `plot-xy`:\n return `ixfx-plot-xy-axis`;\n case `plot-heat`:\n case `plot-histogram`:\n return `ixfx-plot-histogram`;\n case `time-elapsed`:\n return `span`;\n }\n }\n\n #getOrCreateRendererElement(row: HTMLElement, tag: string): HTMLElement | null {\n const existing = row.querySelector(`:scope > [data-renderer]`) as HTMLElement | null;\n if (existing !== null) {\n if (existing.tagName.toLowerCase() === tag)\n return existing;\n existing.remove();\n }\n const el = document.createElement(tag);\n el.dataset.renderer = ``;\n if (tag.startsWith(`ixfx-plot`)) {\n (el as HTMLElement).style.height = `1.4em`;\n if (tag === `ixfx-plot-xy-axis`) {\n (el as HTMLElement).style.width = `1.4em`;\n } else {\n (el as HTMLElement).style.width = `5em`;\n }\n }\n row.append(el);\n return el;\n }\n\n #applyValue(\n el: HTMLElement,\n _tag: string,\n style: RendererStyle,\n path: string,\n value: unknown,\n options?: Record<string, unknown>,\n ) {\n const prev = this.#previousValues.get(path);\n const changed = prev !== value;\n\n switch (style) {\n case `led`:\n this.#applyLed(el, path, value, options);\n break;\n\n case `plot`:\n if (typeof value === `number`) {\n if (changed) {\n (el as any).add(value);\n }\n } else if (typeof value === `object` && value !== null && changed) {\n if (Array.isArray(value)) {\n const record: Record<string, number> = {};\n value.forEach((v: unknown, i: number) => {\n if (typeof v === `number`)\n record[String(i)] = v;\n });\n if (Object.keys(record).length > 0) {\n (el as any).addData(record);\n }\n } else {\n (el as any).addData(value as Record<string, number>);\n }\n }\n this.#applyPlotOptions(el, style, options);\n break;\n\n case `plot-xy`:\n if (changed) {\n this.#applyPlotXy(el, value);\n }\n this.#applyPlotOptions(el, style, options);\n break;\n\n case `plot-heat`:\n el.style.setProperty(`--plot-histogram-bar-length`, `1`);\n // falls through\n case `plot-histogram`:\n if (typeof value === `number` && changed) {\n (el as any).add(value);\n }\n this.#applyPlotOptions(el, style, options);\n break;\n\n case `time-elapsed`:\n el.textContent = this.#formatTimeElapsed(value);\n break;\n }\n\n this.#previousValues.set(path, value);\n }\n\n #applyLed(el: HTMLElement, path: string, value: unknown, options?: Record<string, unknown>) {\n const led = el as any;\n\n if (typeof value === `boolean`) {\n led.lit = value;\n led.value = value ? 1 : 0;\n } else if (typeof value === `number`) {\n let rs = this.#rangeStreams.get(path);\n if (rs === undefined) {\n rs = rangeStream();\n this.#rangeStreams.set(path, rs);\n }\n const range = rs.seen(value);\n const normalized = range.max !== range.min\n ? (value - range.min) / (range.max - range.min)\n : 0.5;\n led.value = normalized;\n led.lit = normalized > 0.3;\n }\n\n if (options?.color !== undefined)\n led.color = options.color;\n }\n\n #applyPlotXy(el: HTMLElement, value: unknown) {\n const xy = el as any;\n\n if (Array.isArray(value) && value.length >= 2) {\n xy.add(value[0], value[1]);\n } else if (typeof value === `object` && value !== null) {\n const obj = value as Record<string, number>;\n if (`x` in obj && `y` in obj) {\n xy.add(obj.x, obj.y);\n } else {\n const entries = Object.entries(obj).filter(([_, v]) => typeof v === `number`);\n if (entries.length >= 2) {\n xy.add(entries[0][1], entries[1][1]);\n }\n }\n }\n }\n\n #applyPlotOptions(el: HTMLElement, _style: RendererStyle, options?: Record<string, unknown>) {\n if (options === undefined)\n return;\n\n const target = el as any;\n\n if (typeof options.capacity === `number`)\n target.capacity = options.capacity;\n if (typeof options.resolution === `number`)\n target.resolution = options.resolution;\n if (typeof options.drawStyle === `string`)\n target.drawStyle = options.drawStyle;\n if (typeof options.orientation === `string`)\n target.orientation = options.orientation;\n if (typeof options.layout === `string`)\n target.layout = options.layout;\n }\n\n #formatTimeElapsed(value: unknown): string {\n let timestamp: number;\n\n if (value instanceof Date) {\n timestamp = value.getTime();\n } else if (typeof value === `number`) {\n if (value > 1e12) {\n timestamp = value;\n } else {\n timestamp = Date.now();\n }\n } else if (typeof value === `string`) {\n timestamp = new Date(value).getTime();\n } else {\n return String(value);\n }\n\n if (Number.isNaN(timestamp))\n return String(value);\n\n const elapsed = Date.now() - timestamp;\n const abs = Math.abs(elapsed);\n\n if (abs < 1000)\n return `${abs}ms`;\n if (abs < 60000)\n return `${(abs / 1000).toFixed(1)}s`;\n if (abs < 3600000)\n return `${(abs / 60000).toFixed(1)}mins`;\n if (abs < 86400000)\n return `${(abs / 3600000).toFixed(1)}h`;\n return `${(abs / 86400000).toFixed(1)}d`;\n }\n\n #renderText(row: HTMLElement, text: string) {\n let valueEl = row.querySelector(`:scope > .value`) as HTMLElement | null;\n if (valueEl === null) {\n valueEl = document.createElement(`span`);\n valueEl.classList.add(`value`);\n row.append(valueEl);\n }\n valueEl.textContent = text;\n }\n\n #renderNestedDisplay(row: HTMLElement, data: Record<string, unknown>, automapChild = false) {\n let child = row.querySelector(`:scope > ixfx-data-display`) as DataDisplayComponent | null;\n if (child === null) {\n child = document.createElement(`ixfx-data-display`) as DataDisplayComponent;\n row.append(child);\n }\n child.automap = automapChild;\n child.updateData(data);\n }\n\n #cleanupPaths(activePaths: Set<string>) {\n const rows = this._container.querySelectorAll<HTMLElement>(`[id^=\"path-\"]`);\n for (const row of rows) {\n const path = row.id.slice(5);\n if (!activePaths.has(path)) {\n row.remove();\n this.#rangeStreams.delete(path);\n this.#previousValues.delete(path);\n }\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-data-display': DataDisplayComponent;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ //#region src/common/data-provider.ts
2
+ /**
3
+ * Collects all items from any DataProviderResult into a flat array.
4
+ * Useful for components that need a complete list before rendering (e.g. tree branches).
5
+ * Respects the AbortSignal — stops accumulating if cancelled mid-stream.
6
+ */
7
+ async function collectDataResult(result, signal) {
8
+ if (Array.isArray(result)) return result;
9
+ if (Symbol.asyncIterator in Object(result)) {
10
+ const items = [];
11
+ for await (const batch of result) {
12
+ if (signal.aborted) return items;
13
+ if (batch.replace) items.length = 0;
14
+ items.push(...batch.items);
15
+ }
16
+ return items;
17
+ }
18
+ return result;
19
+ }
20
+ //#endregion
21
+ export { collectDataResult as t };
22
+
23
+ //# sourceMappingURL=data-provider-DgI909FP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-provider-DgI909FP.js","names":[],"sources":["../src/common/data-provider.ts"],"sourcesContent":["/**\n * Shared data-provider contract used by components that render a list of items.\n *\n * A provider is a simple callable — the consuming component (via DataController)\n * manages the request lifecycle, cancellation, and reactive state.\n */\n\n/**\n * One batch of items within a streaming provider response.\n *\n * For sync and async one-shot providers, the DataController synthesises a single\n * DataBatch internally — you only need this type when writing a streaming provider.\n */\nexport type DataBatch<T> = {\n /** Items delivered in this batch. */\n readonly items: readonly T[];\n /**\n * When true, replace all previously accumulated items with this batch instead\n * of appending. Useful for re-ranked or filtered results mid-stream.\n * Default: false (append).\n */\n replace?: boolean;\n /**\n * Provider's current estimate of the total number of items that will be\n * delivered across all batches. Enables progress percentage in the consumer.\n * May be refined in subsequent batches as the estimate improves.\n * Omit when the total is unknown.\n */\n total?: number;\n};\n\n/**\n * The three return modes a provider may use.\n * DataController normalises all three — callers can mix modes freely.\n *\n * - `readonly T[]` — sync, items available immediately\n * - `Promise<readonly T[]>` — async one-shot, resolves to the full result\n * - `AsyncIterable<DataBatch<T>>` — streaming, batches arrive over time\n */\nexport type DataProviderResult<T> =\n | readonly T[]\n | Promise<readonly T[]>\n | AsyncIterable<DataBatch<T>>;\n\n/**\n * A data provider callable.\n *\n * @typeParam TQuery - The input that scopes the request (e.g. `string` for\n * autocomplete, `{ node, depth }` for a tree branch, `void` for a plain list).\n * @typeParam TItem - The item type produced.\n *\n * The AbortSignal is cancelled when the consumer supersedes the request (e.g.\n * a new query arrives before the previous one completes). Streaming providers\n * should check `signal.aborted` between yields or pass the signal to their\n * underlying fetch calls.\n */\nexport type IDataProvider<TQuery, TItem> = (\n query: TQuery,\n signal: AbortSignal,\n) => DataProviderResult<TItem>;\n\n/**\n * Collects all items from any DataProviderResult into a flat array.\n * Useful for components that need a complete list before rendering (e.g. tree branches).\n * Respects the AbortSignal — stops accumulating if cancelled mid-stream.\n */\nexport async function collectDataResult<T>(\n result: DataProviderResult<T>,\n signal: AbortSignal,\n): Promise<readonly T[]> {\n if (Array.isArray(result))\n return result as T[];\n if (Symbol.asyncIterator in Object(result)) {\n const items: T[] = [];\n for await (const batch of result as AsyncIterable<DataBatch<T>>) {\n if (signal.aborted)\n return items;\n if (batch.replace)\n items.length = 0;\n items.push(...(batch.items as T[]));\n }\n return items;\n }\n return result as Promise<readonly T[]>;\n}\n"],"mappings":";;;;;;AAkEA,eAAsB,kBACpB,QACA,QACuB;CACvB,IAAI,MAAM,QAAQ,MAAM,GACtB,OAAO;CACT,IAAI,OAAO,iBAAiB,OAAO,MAAM,GAAG;EAC1C,MAAM,QAAa,CAAC;EACpB,WAAW,MAAM,SAAS,QAAuC;GAC/D,IAAI,OAAO,SACT,OAAO;GACT,IAAI,MAAM,SACR,MAAM,SAAS;GACjB,MAAM,KAAK,GAAI,MAAM,KAAa;EACpC;EACA,OAAO;CACT;CACA,OAAO;AACT"}
@@ -14,7 +14,7 @@ function safeCustomElement(name) {
14
14
  };
15
15
  }
16
16
  //#endregion
17
- //#region \0@oxc-project+runtime@0.130.0/helpers/decorate.js
17
+ //#region \0@oxc-project+runtime@0.133.0/helpers/esm/decorate.js
18
18
  function __decorate(decorators, target, key, desc) {
19
19
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
20
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -24,4 +24,4 @@ function __decorate(decorators, target, key, desc) {
24
24
  //#endregion
25
25
  export { safeCustomElement as n, __decorate as t };
26
26
 
27
- //# sourceMappingURL=decorate-D7rC1gLP.js.map
27
+ //# sourceMappingURL=decorate-DdjvVHS-.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"decorate-D7rC1gLP.js","names":[],"sources":["../src/util/custom-elements.ts"],"sourcesContent":["type CustomElementCtor = CustomElementConstructor;\n\nfunction getRegistry(): CustomElementRegistry | undefined {\n if (typeof customElements === `undefined`)\n return undefined;\n return customElements;\n}\n\nexport function safeDefine(name: string, ctor: CustomElementCtor): void {\n const registry = getRegistry();\n if (!registry)\n return;\n const existing = registry.get(name);\n if (existing === undefined) {\n registry.define(name, ctor);\n }\n}\n\nexport function safeCustomElement(name: string) {\n return (ctor: CustomElementCtor): void => {\n safeDefine(name, ctor);\n };\n}\n"],"mappings":";AAEA,SAAS,cAAiD;CACxD,IAAI,OAAO,mBAAmB,aAC5B,OAAO,KAAA;CACT,OAAO;AACT;AAEA,SAAgB,WAAW,MAAc,MAA+B;CACtE,MAAM,WAAW,YAAY;CAC7B,IAAI,CAAC,UACH;CAEF,IADiB,SAAS,IAAI,IACnB,MAAM,KAAA,GACf,SAAS,OAAO,MAAM,IAAI;AAE9B;AAEA,SAAgB,kBAAkB,MAAc;CAC9C,QAAQ,SAAkC;EACxC,WAAW,MAAM,IAAI;CACvB;AACF"}
1
+ {"version":3,"file":"decorate-DdjvVHS-.js","names":[],"sources":["../src/util/custom-elements.ts"],"sourcesContent":["type CustomElementCtor = CustomElementConstructor;\n\nfunction getRegistry(): CustomElementRegistry | undefined {\n if (typeof customElements === `undefined`)\n return undefined;\n return customElements;\n}\n\nexport function safeDefine(name: string, ctor: CustomElementCtor): void {\n const registry = getRegistry();\n if (!registry)\n return;\n const existing = registry.get(name);\n if (existing === undefined) {\n registry.define(name, ctor);\n }\n}\n\nexport function safeCustomElement(name: string) {\n return (ctor: CustomElementCtor): void => {\n safeDefine(name, ctor);\n };\n}\n"],"mappings":";AAEA,SAAS,cAAiD;CACxD,IAAI,OAAO,mBAAmB,aAC5B,OAAO,KAAA;CACT,OAAO;AACT;AAEA,SAAgB,WAAW,MAAc,MAA+B;CACtE,MAAM,WAAW,YAAY;CAC7B,IAAI,CAAC,UACH;CAEF,IADiB,SAAS,IAAI,IACnB,MAAM,KAAA,GACf,SAAS,OAAO,MAAM,IAAI;AAE9B;AAEA,SAAgB,kBAAkB,MAAc;CAC9C,QAAQ,SAAkC;EACxC,WAAW,MAAM,IAAI;CACvB;AACF"}
@@ -1,4 +1,4 @@
1
- import { i as registerIcon } from "./registry-Q2gYQCHM.js";
1
+ import { i as registerIcon } from "./registry-CkW7q09Q.js";
2
2
  //#region src/icons/defaults.ts
3
3
  /**
4
4
  * Chevron pointing down. Used for split-button dropdown toggle.
@@ -35,4 +35,4 @@ function registerDefaults() {
35
35
  //#endregion
36
36
  export { registerDefaults as a, ICON_CLOSE as i, ICON_CHECK as n, ICON_CHEVRON_DOWN as r, ICON_CARET_RIGHT as t };
37
37
 
38
- //# sourceMappingURL=defaults-C7elhuyJ.js.map
38
+ //# sourceMappingURL=defaults-C3b9OWJD.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"defaults-C7elhuyJ.js","names":[],"sources":["../src/icons/defaults.ts"],"sourcesContent":["import { registerIcon } from './registry.js';\n\n/**\n * Chevron pointing down. Used for split-button dropdown toggle.\n * fill=\"currentColor\" so it inherits CSS color.\n */\nexport const ICON_CHEVRON_DOWN = `<svg viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\"/></svg>`;\n\n/**\n * Caret pointing right. Used for tree-basic expand indicator as a CSS mask.\n * fill=\"black\" is correct for CSS mask-image use (shape only, color comes from background-color).\n */\nexport const ICON_CARET_RIGHT = `<svg viewBox=\"0 0 24 24\" fill=\"black\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 7l6 5-6 5V7z\"/></svg>`;\n\n/**\n * Checkmark. Useful for menu-check-item or confirmation states.\n * fill=\"currentColor\" so it inherits CSS color.\n */\nexport const ICON_CHECK = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z\"/></svg>`;\n\n/**\n * Close / X icon. Useful for dialogs, notifications, dismissible elements.\n * fill=\"currentColor\" so it inherits CSS color.\n */\nexport const ICON_CLOSE = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z\"/></svg>`;\n\n/**\n * Chevron pointing right. Used for split-button switcher toggle.\n * fill=\"currentColor\" so it inherits CSS color.\n */\nexport const ICON_CHEVRON_RIGHT = `<svg viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\"/></svg>`;\n\nexport function registerDefaults(): void {\n registerIcon(`chevron-down`, ICON_CHEVRON_DOWN);\n registerIcon(`chevron-right`, ICON_CHEVRON_RIGHT);\n registerIcon(`caret-right`, ICON_CARET_RIGHT);\n registerIcon(`check`, ICON_CHECK);\n registerIcon(`close`, ICON_CLOSE);\n}\n"],"mappings":";;;;;;AAMA,MAAa,oBAAoB;;;;;AAMjC,MAAa,mBAAmB;;;;;AAMhC,MAAa,aAAa;;;;;AAM1B,MAAa,aAAa;;;;;AAM1B,MAAa,qBAAqB;AAElC,SAAgB,mBAAyB;CACvC,aAAa,gBAAgB,iBAAiB;CAC9C,aAAa,iBAAiB,kBAAkB;CAChD,aAAa,eAAe,gBAAgB;CAC5C,aAAa,SAAS,UAAU;CAChC,aAAa,SAAS,UAAU;AAClC"}
1
+ {"version":3,"file":"defaults-C3b9OWJD.js","names":[],"sources":["../src/icons/defaults.ts"],"sourcesContent":["import { registerIcon } from './registry.js';\n\n/**\n * Chevron pointing down. Used for split-button dropdown toggle.\n * fill=\"currentColor\" so it inherits CSS color.\n */\nexport const ICON_CHEVRON_DOWN = `<svg viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\"/></svg>`;\n\n/**\n * Caret pointing right. Used for tree-basic expand indicator as a CSS mask.\n * fill=\"black\" is correct for CSS mask-image use (shape only, color comes from background-color).\n */\nexport const ICON_CARET_RIGHT = `<svg viewBox=\"0 0 24 24\" fill=\"black\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 7l6 5-6 5V7z\"/></svg>`;\n\n/**\n * Checkmark. Useful for menu-check-item or confirmation states.\n * fill=\"currentColor\" so it inherits CSS color.\n */\nexport const ICON_CHECK = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z\"/></svg>`;\n\n/**\n * Close / X icon. Useful for dialogs, notifications, dismissible elements.\n * fill=\"currentColor\" so it inherits CSS color.\n */\nexport const ICON_CLOSE = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z\"/></svg>`;\n\n/**\n * Chevron pointing right. Used for split-button switcher toggle.\n * fill=\"currentColor\" so it inherits CSS color.\n */\nexport const ICON_CHEVRON_RIGHT = `<svg viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\"/></svg>`;\n\nexport function registerDefaults(): void {\n registerIcon(`chevron-down`, ICON_CHEVRON_DOWN);\n registerIcon(`chevron-right`, ICON_CHEVRON_RIGHT);\n registerIcon(`caret-right`, ICON_CARET_RIGHT);\n registerIcon(`check`, ICON_CHECK);\n registerIcon(`close`, ICON_CLOSE);\n}\n"],"mappings":";;;;;;AAMA,MAAa,oBAAoB;;;;;AAMjC,MAAa,mBAAmB;;;;;AAMhC,MAAa,aAAa;;;;;AAM1B,MAAa,aAAa;;;;;AAM1B,MAAa,qBAAqB;AAElC,SAAgB,mBAAyB;CACvC,aAAa,gBAAgB,iBAAiB;CAC9C,aAAa,iBAAiB,kBAAkB;CAChD,aAAa,eAAe,gBAAgB;CAC5C,aAAa,SAAS,UAAU;CAChC,aAAa,SAAS,UAAU;AAClC"}
@@ -1,4 +1,4 @@
1
- //#region node_modules/.pnpm/@ixfx+guards@0.56.12/node_modules/@ixfx/guards/dist/index.js
1
+ //#region node_modules/.pnpm/@ixfx+guards@0.56.13/node_modules/@ixfx/guards/dist/index.js
2
2
  function getErrorMessage(ex) {
3
3
  if (typeof ex === `string`) return ex;
4
4
  if (ex instanceof Error) return ex.message;
@@ -315,70 +315,11 @@ const functionTest$1 = (value, parameterName = `?`) => {
315
315
  };
316
316
  };
317
317
  /**
318
- * Tests_if `value` is a plain object
319
- *
320
- * ```js
321
- * isPlainObject(`text`); // false
322
- * isPlainObject(document); // false
323
- * isPlainObject({ hello: `there` }); // true
324
- * ```
325
- * @param value
326
- * @returns
327
- */
328
- const testPlainObject = (value) => {
329
- if (typeof value !== `object` || value === null) return {
330
- success: false,
331
- error: `Value is null or not object type`
332
- };
333
- const prototype = Object.getPrototypeOf(value);
334
- if ((prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value)) return {
335
- success: true,
336
- value
337
- };
338
- return {
339
- success: false,
340
- error: `Fancy object`
341
- };
342
- };
343
- /**
344
- * Tests if `value` is primitive value (bigint,number,string or boolean) or plain object
345
- * @param value
346
- * @returns
347
- */
348
- const testPlainObjectOrPrimitive = (value) => {
349
- const t = typeof value;
350
- if (t === `symbol`) return {
351
- success: false,
352
- error: `Symbol type`
353
- };
354
- if (t === `function`) return {
355
- success: false,
356
- error: `Function type`
357
- };
358
- if (t === `bigint`) return {
359
- success: true,
360
- value
361
- };
362
- if (t === `number`) return {
363
- success: true,
364
- value
365
- };
366
- if (t === `string`) return {
367
- success: true,
368
- value
369
- };
370
- if (t === `boolean`) return {
371
- success: true,
372
- value
373
- };
374
- return testPlainObject(value);
375
- };
376
- /**
377
318
  * Throws an error if parameter is not an string
378
319
  * @param value
379
320
  * @param parameterName
380
321
  */
381
- const stringTest = (value, range = ``, parameterName = `?`) => {
322
+ function stringTest(value, range = ``, parameterName = `?`) {
382
323
  if (typeof value !== `string`) return {
383
324
  success: false,
384
325
  error: `Param '${parameterName} is not type string. Got: ${typeof value}`
@@ -395,9 +336,9 @@ const stringTest = (value, range = ``, parameterName = `?`) => {
395
336
  success: true,
396
337
  value
397
338
  };
398
- };
339
+ }
399
340
  //#endregion
400
- //#region node_modules/.pnpm/@ixfx+arrays@0.56.12/node_modules/@ixfx/arrays/dist/index.js
341
+ //#region node_modules/.pnpm/@ixfx+arrays@0.56.13/node_modules/@ixfx/arrays/dist/index.js
401
342
  /**
402
343
  * If any of `results` is an error, throws it, otherwise ignored.
403
344
  * @param results
@@ -588,7 +529,7 @@ const without = (sourceArray, toRemove, comparer = isEqualDefault) => {
588
529
  } else return sourceArray.filter((v) => !comparer(v, toRemove));
589
530
  };
590
531
  //#endregion
591
- //#region node_modules/.pnpm/@ixfx+numbers@0.56.12/node_modules/@ixfx/numbers/dist/index.js
532
+ //#region node_modules/.pnpm/@ixfx+numbers@0.56.13/node_modules/@ixfx/numbers/dist/index.js
592
533
  /**
593
534
  * Returns the dot product of arbitrary-sized arrays. Assumed they are of the same length.
594
535
  * @param values
@@ -1034,6 +975,6 @@ const rangeStream = (initWith = rangeInit()) => {
1034
975
  };
1035
976
  };
1036
977
  //#endregion
1037
- export { resultThrow$1 as C, throwIfFailed as E, percentTest as S, testPlainObjectOrPrimitive as T, functionTest$1 as _, movingAverageLight as a, numberInclusiveRangeTest as b, round as c, scaler as d, wrap as f, errorResult as g, without as h, interpolate as i, scale as l, pairwise as m, clamper as n, quantiseEvery as o, containsDuplicateInstances as p, dotProduct as r, rangeStream as s, clamp as t, scaleClamped as u, integerTest as v, stringTest as w, numberTest as x, nullUndefTest as y };
978
+ export { resultThrow$1 as C, percentTest as S, throwIfFailed as T, functionTest$1 as _, movingAverageLight as a, numberInclusiveRangeTest as b, round as c, scaler as d, wrap as f, errorResult as g, without as h, interpolate as i, scale as l, pairwise as m, clamper as n, quantiseEvery as o, containsDuplicateInstances as p, dotProduct as r, rangeStream as s, clamp as t, scaleClamped as u, integerTest as v, stringTest as w, numberTest as x, nullUndefTest as y };
1038
979
 
1039
- //# sourceMappingURL=dist-TAGYwaju.js.map
980
+ //# sourceMappingURL=dist-CA13FvMn.js.map