@sjvair/monitor-map 4.2.0 → 5.0.0-beta.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 (265) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -126
  3. package/dist/lib/MonitorDetailPanel.svelte +23 -20
  4. package/dist/lib/MonitorMapLayout.svelte +147 -77
  5. package/dist/lib/abort.d.ts +16 -0
  6. package/dist/lib/abort.js +51 -0
  7. package/dist/lib/components/DataBox.svelte +4 -1
  8. package/dist/lib/components/ui/range-calendar/range-calendar.svelte.d.ts +1 -1
  9. package/dist/lib/config.svelte.d.ts +7 -0
  10. package/dist/lib/config.svelte.js +10 -0
  11. package/dist/lib/core.d.ts +2 -2
  12. package/dist/lib/core.js +2 -1
  13. package/dist/lib/data-chart/DataChart.svelte +54 -24
  14. package/dist/lib/data-chart/DateRange.d.ts +13 -4
  15. package/dist/lib/data-chart/DateRange.js +50 -14
  16. package/dist/lib/data-chart/chart-utils.js +5 -7
  17. package/dist/lib/data-chart/level-colors.d.ts +3 -4
  18. package/dist/lib/data-chart/level-colors.js +7 -4
  19. package/dist/lib/data-chart/pacific-time.d.ts +9 -0
  20. package/dist/lib/data-chart/pacific-time.js +25 -0
  21. package/dist/lib/data-chart/requests.d.ts +2 -1
  22. package/dist/lib/data-chart/requests.js +5 -2
  23. package/dist/lib/data-chart/tooltip.js +2 -2
  24. package/{src/lib/ev-stations/components/EvStationTooltip.svelte → dist/lib/ev-stations/EvPopup.svelte} +6 -5
  25. package/dist/lib/ev-stations/EvPopup.svelte.d.ts +7 -0
  26. package/dist/lib/ev-stations/ev-plugin.svelte.d.ts +14 -0
  27. package/dist/lib/ev-stations/ev-plugin.svelte.js +71 -0
  28. package/dist/lib/ev-stations/ev-station-icons.d.ts +1 -4
  29. package/dist/lib/ev-stations/ev-station-icons.js +1 -13
  30. package/dist/lib/ev-stations/ev-stations.d.ts +7 -0
  31. package/dist/lib/ev-stations/ev-stations.js +53 -0
  32. package/dist/lib/ev-stations/ev-store.svelte.d.ts +21 -0
  33. package/dist/lib/ev-stations/ev-store.svelte.js +83 -0
  34. package/dist/lib/ev-stations/station-popup.svelte.d.ts +14 -0
  35. package/dist/lib/ev-stations/station-popup.svelte.js +54 -0
  36. package/dist/lib/ev-stations/types.d.ts +0 -29
  37. package/dist/lib/ev-stations/zip-codes.d.ts +11 -0
  38. package/dist/lib/ev-stations/zip-codes.js +28 -16
  39. package/dist/lib/index.d.ts +8 -56
  40. package/dist/lib/index.js +7 -46
  41. package/dist/lib/legend/Legend.svelte +18 -19
  42. package/dist/lib/legend/Legend.svelte.d.ts +2 -2
  43. package/dist/lib/levels.d.ts +7 -0
  44. package/dist/lib/levels.js +19 -0
  45. package/dist/lib/map/MapShell.svelte +17 -24
  46. package/dist/lib/map/MapShell.svelte.d.ts +4 -4
  47. package/dist/lib/map/basemaps.d.ts +25 -0
  48. package/dist/lib/map/basemaps.js +66 -0
  49. package/dist/lib/map/live-map.svelte.d.ts +3 -0
  50. package/dist/lib/map/live-map.svelte.js +22 -0
  51. package/dist/lib/map/sync-plugins.svelte.d.ts +19 -0
  52. package/dist/lib/map/sync-plugins.svelte.js +52 -0
  53. package/dist/lib/monitors/components/MonitorSubscriptionManager.svelte +82 -82
  54. package/dist/lib/monitors/filtered-source.svelte.d.ts +9 -0
  55. package/dist/lib/monitors/filtered-source.svelte.js +28 -0
  56. package/dist/lib/monitors/monitor-details.svelte.js +11 -3
  57. package/dist/lib/monitors/monitors.svelte.d.ts +29 -26
  58. package/dist/lib/monitors/monitors.svelte.js +35 -126
  59. package/dist/lib/monitors/retry-load.d.ts +8 -0
  60. package/dist/lib/monitors/retry-load.js +11 -0
  61. package/dist/lib/monitors/subscriptions.d.ts +3 -0
  62. package/dist/lib/monitors/subscriptions.js +9 -0
  63. package/dist/lib/monitors/types.d.ts +1 -41
  64. package/dist/lib/options/map-option-defaults.d.ts +25 -36
  65. package/dist/lib/options/map-option-defaults.js +12 -30
  66. package/dist/lib/options/map-options.svelte.d.ts +13 -0
  67. package/dist/lib/options/map-options.svelte.js +26 -0
  68. package/dist/lib/options/menus/LayersMenu.svelte +8 -20
  69. package/dist/lib/options/menus/LayersMenu.svelte.d.ts +17 -2
  70. package/dist/lib/options/menus/MonitorsMenu.svelte +34 -18
  71. package/dist/lib/options/menus/OverlaysMenu.svelte +2 -2
  72. package/dist/lib/options/menus/PollutantMenu.svelte +4 -9
  73. package/dist/lib/options/menus/SettingsMenu.svelte +32 -25
  74. package/dist/lib/options/menus/SettingsMenu.svelte.d.ts +5 -16
  75. package/dist/lib/options/plugin-order.d.ts +8 -0
  76. package/dist/lib/options/plugin-order.js +36 -0
  77. package/dist/lib/options/pollutant-param.d.ts +7 -5
  78. package/dist/lib/options/pollutant-param.js +9 -5
  79. package/dist/lib/options/row-icons.d.ts +8 -0
  80. package/dist/lib/options/row-icons.js +15 -0
  81. package/dist/lib/options/rows/MarkerIcon.svelte +5 -5
  82. package/dist/lib/options/rows/MarkerIcon.svelte.d.ts +1 -2
  83. package/dist/lib/search/Search.svelte +20 -33
  84. package/dist/lib/search/Search.svelte.d.ts +5 -1
  85. package/dist/lib/search/search-pin.svelte.d.ts +11 -0
  86. package/dist/lib/search/search-pin.svelte.js +28 -0
  87. package/dist/lib/search/service.d.ts +7 -2
  88. package/dist/lib/search/service.js +17 -10
  89. package/dist/lib/stores.svelte.d.ts +8 -0
  90. package/dist/lib/stores.svelte.js +9 -0
  91. package/dist/lib/wind/wind-plugin.d.ts +11 -0
  92. package/dist/lib/wind/wind-plugin.js +25 -0
  93. package/package.json +12 -10
  94. package/src/lib/MonitorDetailPanel.svelte +23 -20
  95. package/src/lib/MonitorMapLayout.svelte +147 -77
  96. package/src/lib/abort.ts +59 -0
  97. package/src/lib/components/DataBox.svelte +4 -1
  98. package/src/lib/config.svelte.ts +16 -0
  99. package/src/lib/core.ts +2 -2
  100. package/src/lib/data-chart/DataChart.svelte +54 -24
  101. package/src/lib/data-chart/DateRange.ts +58 -15
  102. package/src/lib/data-chart/chart-utils.ts +6 -7
  103. package/src/lib/data-chart/level-colors.ts +8 -9
  104. package/src/lib/data-chart/pacific-time.ts +31 -0
  105. package/src/lib/data-chart/requests.ts +14 -7
  106. package/src/lib/data-chart/tooltip.ts +2 -2
  107. package/{dist/lib/ev-stations/components/EvStationTooltip.svelte → src/lib/ev-stations/EvPopup.svelte} +6 -5
  108. package/src/lib/ev-stations/ev-plugin.svelte.ts +86 -0
  109. package/src/lib/ev-stations/ev-station-icons.ts +1 -17
  110. package/src/lib/ev-stations/ev-stations.ts +72 -0
  111. package/src/lib/ev-stations/ev-store.svelte.ts +117 -0
  112. package/src/lib/ev-stations/station-popup.svelte.ts +64 -0
  113. package/src/lib/ev-stations/types.ts +0 -34
  114. package/src/lib/ev-stations/zip-codes.ts +29 -16
  115. package/src/lib/index.ts +8 -99
  116. package/src/lib/legend/Legend.svelte +18 -19
  117. package/src/lib/levels.ts +24 -0
  118. package/src/lib/map/MapShell.svelte +17 -24
  119. package/src/lib/map/basemaps.ts +76 -0
  120. package/src/lib/map/live-map.svelte.ts +24 -0
  121. package/src/lib/map/sync-plugins.svelte.ts +69 -0
  122. package/src/lib/monitors/components/MonitorSubscriptionManager.svelte +82 -82
  123. package/src/lib/monitors/filtered-source.svelte.ts +38 -0
  124. package/src/lib/monitors/monitor-details.svelte.ts +12 -3
  125. package/src/lib/monitors/monitors.svelte.ts +62 -153
  126. package/src/lib/monitors/retry-load.ts +14 -0
  127. package/src/lib/monitors/subscriptions.ts +17 -0
  128. package/src/lib/monitors/types.ts +1 -47
  129. package/src/lib/options/map-option-defaults.ts +30 -53
  130. package/src/lib/options/map-options.svelte.ts +30 -0
  131. package/src/lib/options/menus/LayersMenu.svelte +8 -20
  132. package/src/lib/options/menus/MonitorsMenu.svelte +34 -18
  133. package/src/lib/options/menus/OverlaysMenu.svelte +2 -2
  134. package/src/lib/options/menus/PollutantMenu.svelte +4 -9
  135. package/src/lib/options/menus/SettingsMenu.svelte +32 -25
  136. package/src/lib/options/plugin-order.ts +38 -0
  137. package/src/lib/options/pollutant-param.ts +14 -9
  138. package/src/lib/options/row-icons.ts +17 -0
  139. package/src/lib/options/rows/MarkerIcon.svelte +5 -5
  140. package/src/lib/search/Search.svelte +20 -33
  141. package/src/lib/search/search-pin.svelte.ts +35 -0
  142. package/src/lib/search/service.ts +34 -15
  143. package/src/lib/stores.svelte.ts +15 -0
  144. package/src/lib/wind/wind-plugin.ts +33 -0
  145. package/dist/lib/collocation-sites/CollocationTooltip.svelte +0 -98
  146. package/dist/lib/collocation-sites/CollocationTooltip.svelte.d.ts +0 -7
  147. package/dist/lib/collocation-sites/collocations-icon-manager.svelte.d.ts +0 -7
  148. package/dist/lib/collocation-sites/collocations-icon-manager.svelte.js +0 -18
  149. package/dist/lib/collocation-sites/collocations-map-integration.svelte.d.ts +0 -21
  150. package/dist/lib/collocation-sites/collocations-map-integration.svelte.js +0 -113
  151. package/dist/lib/collocation-sites/collocations.svelte.d.ts +0 -9
  152. package/dist/lib/collocation-sites/collocations.svelte.js +0 -17
  153. package/dist/lib/collocation-sites/types.d.ts +0 -8
  154. package/dist/lib/collocation-sites/types.js +0 -1
  155. package/dist/lib/ev-stations/components/EvStationClusterTooltip.svelte +0 -16
  156. package/dist/lib/ev-stations/components/EvStationClusterTooltip.svelte.d.ts +0 -7
  157. package/dist/lib/ev-stations/components/EvStationTooltip.svelte.d.ts +0 -7
  158. package/dist/lib/ev-stations/ev-stations-cluster-renderer.d.ts +0 -19
  159. package/dist/lib/ev-stations/ev-stations-cluster-renderer.js +0 -131
  160. package/dist/lib/ev-stations/ev-stations-map-integration.svelte.d.ts +0 -31
  161. package/dist/lib/ev-stations/ev-stations-map-integration.svelte.js +0 -226
  162. package/dist/lib/ev-stations/ev-stations.svelte.d.ts +0 -9
  163. package/dist/lib/ev-stations/ev-stations.svelte.js +0 -55
  164. package/dist/lib/hms/hms-fire-icon-manager.d.ts +0 -13
  165. package/dist/lib/hms/hms-fire-icon-manager.js +0 -39
  166. package/dist/lib/hms/hms-fire-map-integration.svelte.d.ts +0 -23
  167. package/dist/lib/hms/hms-fire-map-integration.svelte.js +0 -94
  168. package/dist/lib/hms/hms-smoke-map-integration.svelte.d.ts +0 -39
  169. package/dist/lib/hms/hms-smoke-map-integration.svelte.js +0 -87
  170. package/dist/lib/hms/hms.svelte.d.ts +0 -19
  171. package/dist/lib/hms/hms.svelte.js +0 -227
  172. package/dist/lib/legend/LegendBar.svelte +0 -45
  173. package/dist/lib/legend/LegendBar.svelte.d.ts +0 -7
  174. package/dist/lib/legend/legend-data.d.ts +0 -40
  175. package/dist/lib/legend/legend-data.js +0 -65
  176. package/dist/lib/map/Map.svelte +0 -13
  177. package/dist/lib/map/Map.svelte.d.ts +0 -8
  178. package/dist/lib/map/basemap.d.ts +0 -14
  179. package/dist/lib/map/basemap.js +0 -10
  180. package/dist/lib/map/icons.d.ts +0 -7
  181. package/dist/lib/map/icons.js +0 -33
  182. package/dist/lib/map/integrations/base-layer-seperator.d.ts +0 -9
  183. package/dist/lib/map/integrations/base-layer-seperator.js +0 -11
  184. package/dist/lib/map/integrations/click-manager.d.ts +0 -14
  185. package/dist/lib/map/integrations/click-manager.js +0 -52
  186. package/dist/lib/map/integrations/integrations-manager.d.ts +0 -8
  187. package/dist/lib/map/integrations/integrations-manager.js +0 -20
  188. package/dist/lib/map/integrations/map-display-option.svelte.d.ts +0 -7
  189. package/dist/lib/map/integrations/map-display-option.svelte.js +0 -10
  190. package/dist/lib/map/integrations/map-geojson-integration.svelte.d.ts +0 -32
  191. package/dist/lib/map/integrations/map-geojson-integration.svelte.js +0 -60
  192. package/dist/lib/map/integrations/map-icon-manager.d.ts +0 -15
  193. package/dist/lib/map/integrations/map-icon-manager.js +0 -52
  194. package/dist/lib/map/integrations/map-integration.svelte.d.ts +0 -6
  195. package/dist/lib/map/integrations/map-integration.svelte.js +0 -2
  196. package/dist/lib/map/integrations/map-layer-integration.svelte.d.ts +0 -11
  197. package/dist/lib/map/integrations/map-layer-integration.svelte.js +0 -40
  198. package/dist/lib/map/integrations/tooltip.svelte.d.ts +0 -36
  199. package/dist/lib/map/integrations/tooltip.svelte.js +0 -131
  200. package/dist/lib/map/integrations/types.d.ts +0 -14
  201. package/dist/lib/map/integrations/types.js +0 -1
  202. package/dist/lib/map/map-manager.svelte.d.ts +0 -20
  203. package/dist/lib/map/map-manager.svelte.js +0 -63
  204. package/dist/lib/map/map-style-state.svelte.d.ts +0 -23
  205. package/dist/lib/map/map-style-state.svelte.js +0 -86
  206. package/dist/lib/map/utils.d.ts +0 -7
  207. package/dist/lib/map/utils.js +0 -36
  208. package/dist/lib/monitors/components/MonitorClusterTooltip.svelte +0 -112
  209. package/dist/lib/monitors/components/MonitorClusterTooltip.svelte.d.ts +0 -7
  210. package/dist/lib/monitors/components/MonitorTooltip.svelte +0 -61
  211. package/dist/lib/monitors/components/MonitorTooltip.svelte.d.ts +0 -7
  212. package/dist/lib/monitors/monitor-utils.d.ts +0 -4
  213. package/dist/lib/monitors/monitor-utils.js +0 -41
  214. package/dist/lib/monitors/monitors-cluster-renderer.d.ts +0 -33
  215. package/dist/lib/monitors/monitors-cluster-renderer.js +0 -221
  216. package/dist/lib/monitors/monitors-icon-manager.svelte.d.ts +0 -15
  217. package/dist/lib/monitors/monitors-icon-manager.svelte.js +0 -78
  218. package/dist/lib/monitors/monitors-map-integration.svelte.d.ts +0 -43
  219. package/dist/lib/monitors/monitors-map-integration.svelte.js +0 -301
  220. package/dist/lib/options/reset-map-options.d.ts +0 -2
  221. package/dist/lib/options/reset-map-options.js +0 -24
  222. package/dist/lib/reactivity.svelte.d.ts +0 -0
  223. package/dist/lib/reactivity.svelte.js +0 -83
  224. package/dist/lib/wind/wind.svelte.d.ts +0 -10
  225. package/dist/lib/wind/wind.svelte.js +0 -13
  226. package/src/lib/collocation-sites/CollocationTooltip.svelte +0 -98
  227. package/src/lib/collocation-sites/collocations-icon-manager.svelte.ts +0 -21
  228. package/src/lib/collocation-sites/collocations-map-integration.svelte.ts +0 -136
  229. package/src/lib/collocation-sites/collocations.svelte.ts +0 -24
  230. package/src/lib/collocation-sites/types.ts +0 -10
  231. package/src/lib/ev-stations/components/EvStationClusterTooltip.svelte +0 -16
  232. package/src/lib/ev-stations/ev-stations-cluster-renderer.ts +0 -162
  233. package/src/lib/ev-stations/ev-stations-map-integration.svelte.ts +0 -248
  234. package/src/lib/ev-stations/ev-stations.svelte.ts +0 -79
  235. package/src/lib/hms/hms-fire-icon-manager.ts +0 -48
  236. package/src/lib/hms/hms-fire-map-integration.svelte.ts +0 -109
  237. package/src/lib/hms/hms-smoke-map-integration.svelte.ts +0 -105
  238. package/src/lib/hms/hms.svelte.ts +0 -264
  239. package/src/lib/legend/LegendBar.svelte +0 -45
  240. package/src/lib/legend/legend-data.ts +0 -101
  241. package/src/lib/map/Map.svelte +0 -13
  242. package/src/lib/map/basemap.ts +0 -24
  243. package/src/lib/map/icons.ts +0 -42
  244. package/src/lib/map/integrations/base-layer-seperator.ts +0 -17
  245. package/src/lib/map/integrations/click-manager.ts +0 -64
  246. package/src/lib/map/integrations/integrations-manager.ts +0 -25
  247. package/src/lib/map/integrations/map-display-option.svelte.ts +0 -13
  248. package/src/lib/map/integrations/map-geojson-integration.svelte.ts +0 -77
  249. package/src/lib/map/integrations/map-icon-manager.ts +0 -67
  250. package/src/lib/map/integrations/map-integration.svelte.ts +0 -8
  251. package/src/lib/map/integrations/map-layer-integration.svelte.ts +0 -49
  252. package/src/lib/map/integrations/tooltip.svelte.ts +0 -153
  253. package/src/lib/map/integrations/types.ts +0 -24
  254. package/src/lib/map/map-manager.svelte.ts +0 -83
  255. package/src/lib/map/map-style-state.svelte.ts +0 -94
  256. package/src/lib/map/utils.ts +0 -53
  257. package/src/lib/monitors/components/MonitorClusterTooltip.svelte +0 -112
  258. package/src/lib/monitors/components/MonitorTooltip.svelte +0 -61
  259. package/src/lib/monitors/monitor-utils.ts +0 -57
  260. package/src/lib/monitors/monitors-cluster-renderer.ts +0 -285
  261. package/src/lib/monitors/monitors-icon-manager.svelte.ts +0 -98
  262. package/src/lib/monitors/monitors-map-integration.svelte.ts +0 -318
  263. package/src/lib/options/reset-map-options.ts +0 -28
  264. package/src/lib/reactivity.svelte.ts +0 -82
  265. package/src/lib/wind/wind.svelte.ts +0 -20
@@ -0,0 +1,9 @@
1
+ import type { DataSource, MonitorFeatureProperties } from "@sjvair/map-sdk/data";
2
+ import type { MapOptions } from "../options/map-option-defaults";
3
+ type Options = Pick<MapOptions, "monitorTypes" | "inactive" | "inside">;
4
+ /**
5
+ * `source` with only the monitors the Monitors menu shows: types that are on, inactive and
6
+ * inside ones only when those are on. Clusters are built from these, so their averages follow.
7
+ */
8
+ export declare function filteredMonitors(source: DataSource<MonitorFeatureProperties>, options: Options): DataSource<MonitorFeatureProperties>;
9
+ export {};
@@ -0,0 +1,28 @@
1
+ function shown(props, options) {
2
+ return (options.monitorTypes[props.type] === true &&
3
+ (props.isActive || options.inactive) &&
4
+ (props.location !== "inside" || options.inside));
5
+ }
6
+ /**
7
+ * `source` with only the monitors the Monitors menu shows: types that are on, inactive and
8
+ * inside ones only when those are on. Clusters are built from these, so their averages follow.
9
+ */
10
+ export function filteredMonitors(source, options) {
11
+ const features = $derived.by(() => {
12
+ const all = source.features;
13
+ if (!all)
14
+ return null;
15
+ return { ...all, features: all.features.filter((f) => shown(f.properties, options)) };
16
+ });
17
+ return {
18
+ get status() {
19
+ return source.status;
20
+ },
21
+ get features() {
22
+ return features;
23
+ },
24
+ get scale() {
25
+ return source.scale;
26
+ }
27
+ };
28
+ }
@@ -9,13 +9,15 @@ export class MonitorDetailsState {
9
9
  #id = null;
10
10
  // Bumped per request; a response for anything but the latest request is dropped.
11
11
  #request = 0;
12
+ #controller = null;
12
13
  async load(id) {
13
14
  this.#id = id;
14
15
  const request = ++this.#request;
16
+ const { signal } = this.#restart();
15
17
  this.monitor = null;
16
18
  this.status = "loading";
17
19
  try {
18
- const monitor = await getMonitorDetails(id);
20
+ const monitor = await getMonitorDetails(id, { signal });
19
21
  if (request !== this.#request)
20
22
  return;
21
23
  this.monitor = monitor;
@@ -37,17 +39,23 @@ export class MonitorDetailsState {
37
39
  if (this.status !== "ready" || this.#id === null)
38
40
  return;
39
41
  const request = ++this.#request;
42
+ const { signal } = this.#restart();
40
43
  try {
41
- const monitor = await getMonitorDetails(this.#id);
44
+ const monitor = await getMonitorDetails(this.#id, { signal });
42
45
  if (request !== this.#request)
43
46
  return;
44
47
  this.monitor = monitor;
45
48
  }
46
49
  catch (error) {
47
- if (request === this.#request)
50
+ if (!signal.aborted && request === this.#request)
48
51
  console.error(error);
49
52
  }
50
53
  }
54
+ /** Aborts whatever request is in flight and starts a new controller for the next one. */
55
+ #restart() {
56
+ this.#controller?.abort();
57
+ return (this.#controller = new AbortController());
58
+ }
51
59
  retry() {
52
60
  return this.#id === null ? Promise.resolve() : this.load(this.#id);
53
61
  }
@@ -1,39 +1,42 @@
1
- import { type MonitorData, type MonitorLatestType, type MonitorsMeta, type SJVAirEntryLevel } from "@sjvair/sdk";
2
- import { XMap } from "@tstk/builtin-extensions";
3
- import { Interval } from "@tstk/utils";
4
- import type { MonitorsDataSource } from "./types";
1
+ import type { MonitorData, MonitorsMeta } from "@sjvair/sdk";
2
+ import type { MonitorsStore } from "@sjvair/map-sdk/stores";
5
3
  export interface MonitorsInitOptions {
6
4
  /**
7
5
  * Start the 2-minute polling once the initial load finishes. Defaults to true; pass false to
8
6
  * load the data without showing a map (`resumeAutoUpdate()` starts polling later).
9
7
  */
10
8
  autoUpdate?: boolean;
11
- }
12
- declare class MonitorsManager implements MonitorsDataSource {
13
- #private;
14
- autoUpdate: Interval;
15
- initialized: boolean;
16
- latest: XMap<string, MonitorLatestType<"pm25" | "o3">> | null;
17
- list: Array<MonitorData> | null;
18
- meta: MonitorsMeta | null;
19
- pollutant: "pm25" | "o3" | null;
20
- levels: Array<SJVAirEntryLevel> | null;
21
- constructor();
22
9
  /**
23
- * Safe to call from several places: overlapping calls share one run, and a failed run can
24
- * be retried. An explicit "pm25"/"o3" wins over a call without one, whichever came first;
25
- * between two explicit values the most recent wins. Polling starts when the run finishes
26
- * unless every call sharing it passed `autoUpdate: false`. A no-op once initialized, so it
27
- * never restarts polling either: that is `resumeAutoUpdate()`.
10
+ * Stops waiting: the returned promise rejects with the signal's reason. The shared run keeps
11
+ * going for the other calls waiting on it, and is cancelled only when every call waiting on it
12
+ * passed a signal and all of those aborted. Ignored once initialized.
28
13
  */
29
- init(urlPollutant?: string | number | boolean, options?: MonitorsInitOptions): Promise<void>;
14
+ signal?: AbortSignal;
15
+ }
16
+ /**
17
+ * The live monitors data, as hosts have used it since 4.x: a thin view over map-sdk's monitors
18
+ * store, which owns the data, the shared init and the polling.
19
+ */
20
+ export interface MonitorsManager {
21
+ /** Loads the monitors. Only "pm25" and "o3" pass through; anything else means the default. */
22
+ init(pollutant?: unknown, options?: MonitorsInitOptions): Promise<void>;
23
+ readonly initialized: boolean;
24
+ readonly meta: MonitorsMeta | null;
30
25
  /**
31
- * Starts polling when it is not running: after something stopped it (MonitorMapLayout stops
32
- * it on destroy) or after an init that opted out of it. Refreshes first since the data may
33
- * be stale. A no-op before init or while polling.
26
+ * Every monitor, or null until initialized. The same array between reads until the store's
27
+ * monitors are replaced.
34
28
  */
29
+ readonly list: MonitorData[] | null;
30
+ /** The pollutant the readings are for, or null before init. */
31
+ readonly pollutant: string | null;
32
+ setPollutant(pollutant: "pm25" | "o3"): void;
33
+ update(options?: {
34
+ signal?: AbortSignal;
35
+ }): Promise<void>;
35
36
  resumeAutoUpdate(): void;
36
- update(): Promise<void>;
37
+ pauseAutoUpdate(): void;
38
+ /** The store underneath, for map-sdk plugins and stores. */
39
+ readonly store: MonitorsStore;
37
40
  }
41
+ export declare function createMonitorsManager(store: MonitorsStore): MonitorsManager;
38
42
  export declare const monitorsManager: MonitorsManager;
39
- export type { MonitorsManager };
@@ -1,128 +1,37 @@
1
- import { getMonitors, getMonitorsList, getMonitorsMeta } from "@sjvair/sdk";
2
- import { XMap } from "@tstk/builtin-extensions";
3
- import { Interval } from "@tstk/utils";
4
- import { untrack } from "svelte";
5
- class MonitorsManager {
6
- autoUpdate = new Interval(async () => await this.update(), 2 * 60 * 1000);
7
- initialized = $state(false);
8
- latest = $state(null);
9
- list = $state(null);
10
- meta = $state(null);
11
- pollutant = $state(null);
12
- levels = $derived(this.meta?.entryType(this.pollutant ?? this.meta.default_pollutant).asIter.levels || null);
13
- #initPromise = null;
14
- #requestedPollutant = null;
15
- #requestedAutoUpdate = false;
16
- constructor() {
17
- // Refetch monitors when the pollutant changes after the initial load, wherever the change
18
- // comes from (Pollutant menu, URL sync, a host's own UI). Clearing first blanks the markers
19
- // instead of briefly coloring them with the previous pollutant's readings.
20
- let fetchedPollutant = null;
21
- $effect.root(() => {
22
- $effect(() => {
23
- const pollutant = this.pollutant;
24
- if (!this.initialized)
25
- return;
26
- if (fetchedPollutant !== null && fetchedPollutant !== pollutant) {
27
- untrack(() => {
28
- this.list = [];
29
- this.latest = null;
30
- this.update();
31
- });
32
- }
33
- fetchedPollutant = pollutant;
34
- });
35
- });
36
- }
37
- /**
38
- * Safe to call from several places: overlapping calls share one run, and a failed run can
39
- * be retried. An explicit "pm25"/"o3" wins over a call without one, whichever came first;
40
- * between two explicit values the most recent wins. Polling starts when the run finishes
41
- * unless every call sharing it passed `autoUpdate: false`. A no-op once initialized, so it
42
- * never restarts polling either: that is `resumeAutoUpdate()`.
43
- */
44
- init(urlPollutant, options = {}) {
45
- if (this.initialized)
46
- return Promise.resolve();
47
- if (options.autoUpdate !== false)
48
- this.#requestedAutoUpdate = true;
49
- if (urlPollutant === "pm25" || urlPollutant === "o3") {
50
- this.#requestedPollutant = urlPollutant;
51
- }
52
- this.#initPromise ??= this.#runInit().finally(() => {
53
- this.#initPromise = null;
54
- this.#requestedPollutant = null;
55
- this.#requestedAutoUpdate = false;
56
- });
57
- return this.#initPromise;
58
- }
59
- async #runInit() {
60
- // The pollutant the latest readings were requested for.
61
- let fetchedPollutant = this.#requestedPollutant;
62
- const metaRequest = getMonitorsMeta();
63
- const listAndMeta = Promise.all([getMonitorsList(), metaRequest]).then(([list, meta]) => {
64
- this.list = list;
65
- this.meta = meta;
66
- return meta;
67
- });
68
- // The latest readings only need the pollutant, so they never wait for the list. An explicit
69
- // pollutant may still arrive before meta does, in which case the default is never fetched.
70
- const latestRequest = fetchedPollutant
71
- ? getMonitorsLatestMap(fetchedPollutant)
72
- : metaRequest.then((meta) => {
73
- const pollutant = this.#requestedPollutant ?? meta.default_pollutant;
74
- fetchedPollutant = pollutant;
75
- return getMonitorsLatestMap(pollutant);
76
- });
77
- // One Promise.all so a failure in either never leaves the other unhandled.
78
- const [meta, firstLatest] = await Promise.all([listAndMeta, latestRequest]);
79
- let latest = firstLatest;
80
- // An explicit pollutant may have arrived while the requests above were in flight.
81
- let wanted = this.#requestedPollutant ?? meta.default_pollutant;
82
- while (wanted !== fetchedPollutant) {
83
- latest = await getMonitorsLatestMap(wanted);
84
- fetchedPollutant = wanted;
85
- wanted = this.#requestedPollutant ?? meta.default_pollutant;
86
- }
87
- this.pollutant = fetchedPollutant;
88
- this.latest = latest;
89
- if (this.#requestedAutoUpdate)
90
- this.autoUpdate.start();
91
- this.initialized = true;
92
- }
93
- /**
94
- * Starts polling when it is not running: after something stopped it (MonitorMapLayout stops
95
- * it on destroy) or after an init that opted out of it. Refreshes first since the data may
96
- * be stale. A no-op before init or while polling.
97
- */
98
- resumeAutoUpdate() {
99
- if (!this.initialized || this.autoUpdate.isActive)
100
- return;
101
- this.update().catch(console.error);
102
- this.autoUpdate.start();
103
- }
104
- async update() {
105
- if (!this.initialized)
106
- return;
107
- const pollutant = this.pollutant;
108
- const [list, latest] = await Promise.all([
109
- getMonitorsList(),
110
- getMonitorsLatestMap(pollutant || this.meta?.default_pollutant || "pm25")
111
- ]);
112
- // The pollutant changed while this was in flight: these readings belong to the previous
113
- // one, and the change has already started its own update.
114
- if (this.pollutant !== pollutant)
115
- return;
116
- this.list = list;
117
- this.latest = latest;
118
- }
1
+ import { monitorsStore } from "../stores.svelte.js";
2
+ function initPollutant(pollutant) {
3
+ return pollutant === "pm25" || pollutant === "o3" ? pollutant : undefined;
119
4
  }
120
- async function getMonitorsLatestMap(pollutant) {
121
- const monitors = await getMonitors(pollutant);
122
- const latest = new XMap();
123
- for (const monitor of monitors) {
124
- latest.set(monitor.id, monitor);
125
- }
126
- return latest;
5
+ export function createMonitorsManager(store) {
6
+ // The list built from `store.monitors`, which the store replaces rather than mutates.
7
+ let listFrom = null;
8
+ let list = [];
9
+ return {
10
+ init: (pollutant, options) => store.init(initPollutant(pollutant), options),
11
+ get initialized() {
12
+ return store.initialized;
13
+ },
14
+ get meta() {
15
+ return store.meta;
16
+ },
17
+ get list() {
18
+ if (!store.initialized)
19
+ return null;
20
+ const monitors = store.monitors;
21
+ if (monitors !== listFrom) {
22
+ listFrom = monitors;
23
+ list = [...monitors.values()];
24
+ }
25
+ return list;
26
+ },
27
+ get pollutant() {
28
+ return store.entryType;
29
+ },
30
+ setPollutant: (pollutant) => store.entryTypeFor(pollutant),
31
+ update: (options) => store.update(options),
32
+ resumeAutoUpdate: () => store.resumeAutoUpdate(),
33
+ pauseAutoUpdate: () => store.pauseAutoUpdate(),
34
+ store
35
+ };
127
36
  }
128
- export const monitorsManager = new MonitorsManager();
37
+ export const monitorsManager = createMonitorsManager(monitorsStore);
@@ -0,0 +1,8 @@
1
+ import type { monitorsStore } from "../stores.svelte.js";
2
+ /**
3
+ * Retries a failed initial monitors load through the store's own `status.retry()`, which repeats
4
+ * the failed `init()` call. When the status is not an error (nothing to retry), runs `fallback`.
5
+ */
6
+ export declare function retryMonitorsLoad(store: {
7
+ dataSource: Pick<typeof monitorsStore.dataSource, "status">;
8
+ }, fallback: () => void): void;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Retries a failed initial monitors load through the store's own `status.retry()`, which repeats
3
+ * the failed `init()` call. When the status is not an error (nothing to retry), runs `fallback`.
4
+ */
5
+ export function retryMonitorsLoad(store, fallback) {
6
+ const { status } = store.dataSource;
7
+ if (status.state === "error")
8
+ status.retry();
9
+ else
10
+ fallback();
11
+ }
@@ -0,0 +1,3 @@
1
+ import type { SignalOptions } from "../abort";
2
+ export declare function getApiToken(): string | undefined;
3
+ export declare function loadSubscriptionLevel(monitorId: string, options?: SignalOptions): Promise<string | null>;
@@ -0,0 +1,9 @@
1
+ import { getSubscriptions } from "@sjvair/sdk/account";
2
+ export function getApiToken() {
3
+ const token = globalThis["USER"]?.api_token;
4
+ return typeof token === "string" && token !== "" ? token : undefined;
5
+ }
6
+ export async function loadSubscriptionLevel(monitorId, options) {
7
+ const subscriptions = await getSubscriptions(getApiToken(), { signal: options?.signal });
8
+ return subscriptions.find((s) => s.monitor === monitorId)?.level ?? null;
9
+ }
@@ -1,42 +1,2 @@
1
- import type { Feature, Geometry } from "geojson";
2
- import type { MonitorLatestType, MonitorsMeta, MonitorType, SJVAirEntryLevel } from "@sjvair/sdk";
3
- import type { MapGeoJSONFeature } from "@maptiler/sdk";
4
- import type { XMap } from "@tstk/builtin-extensions";
5
- export type MonitorMapFeature = Feature<Geometry, MonitorMarkerProperties>;
6
- export interface MonitorClusterMapFeature extends MapGeoJSONFeature {
7
- properties: MonitorClusterMarkerProperties;
8
- }
9
- export interface MonitorMarkerProperties {
10
- icon: string;
11
- id: string;
12
- is_active: boolean;
13
- is_sjvair?: boolean;
14
- location: string;
15
- name: string;
16
- order: number;
17
- type: MonitorType;
18
- value: string;
19
- }
20
- export interface MonitorClusterMarkerProperties {
21
- cluster: true;
22
- cluster_id: number;
23
- point_count: number;
24
- point_count_abbreviated: string | number;
25
- sumValues: number;
26
- countValues: number;
27
- }
28
- /** The pollutants monitorsMapIntegration/monitorsIconManager can render. */
1
+ /** The pollutants the map can show. */
29
2
  export type MonitorsPollutant = "pm25" | "o3";
30
- /**
31
- * The reactive data a monitors map display needs: which monitors exist, their
32
- * per-monitor "latest" value for the active pollutant, and the entry-level metadata
33
- * used to color icons. `monitorsManager` (live, auto-polling) is the default
34
- * implementation; a host app can supply its own (e.g. one backed by historical
35
- * summaries instead of live readings) to reuse the map rendering with different data.
36
- */
37
- export interface MonitorsDataSource {
38
- readonly meta: MonitorsMeta | null;
39
- readonly pollutant: MonitorsPollutant | null;
40
- readonly latest: XMap<string, MonitorLatestType<MonitorsPollutant>> | null;
41
- readonly levels: Array<SJVAirEntryLevel> | null;
42
- }
@@ -1,9 +1,24 @@
1
- import type { MonitorsPollutant } from "../monitors/types";
2
- import { type PollutantTargets } from "./pollutant-param";
3
- /**
4
- * Defaults restored by "Reset Map Options". Keep in sync with the constructor defaults in each
5
- * integration (monitors/EV display options, `enabled`, `clustered`) so a reset matches a fresh load.
6
- */
1
+ /** The map options the toolbar edits; `mapOptions` holds the live copy. */
2
+ export interface MapOptions {
3
+ /** False for the Pollutant menu's "None": no monitors (or collocation sites) on the map. */
4
+ monitorsOn: boolean;
5
+ /** Which monitor types draw, keyed by server type; a type with no key never draws. */
6
+ monitorTypes: Record<string, boolean>;
7
+ inactive: boolean;
8
+ inside: boolean;
9
+ /** Monitors' and EV chargers' clustering. */
10
+ clustered: boolean;
11
+ collocationSites: boolean;
12
+ /** HMS smoke and fire together. */
13
+ fireAndSmoke: boolean;
14
+ evStations: boolean;
15
+ evLevels: {
16
+ lvl2: boolean;
17
+ lvl3: boolean;
18
+ };
19
+ wind: boolean;
20
+ }
21
+ /** Defaults restored by "Reset Map Options"; a fresh load starts at them too. */
7
22
  export declare const MAP_OPTION_DEFAULTS: {
8
23
  readonly monitorTypes: {
9
24
  readonly airnow: true;
@@ -13,9 +28,9 @@ export declare const MAP_OPTION_DEFAULTS: {
13
28
  readonly airgradient: true;
14
29
  readonly purpleair: true;
15
30
  readonly vozbox: true;
16
- readonly inactive: false;
17
- readonly inside: false;
18
31
  };
32
+ readonly inactive: false;
33
+ readonly inside: false;
19
34
  readonly clustered: true;
20
35
  readonly collocationSites: false;
21
36
  readonly fireAndSmoke: true;
@@ -26,31 +41,5 @@ export declare const MAP_OPTION_DEFAULTS: {
26
41
  };
27
42
  readonly wind: false;
28
43
  };
29
- type Toggle = {
30
- enabled: boolean;
31
- };
32
- type Option = {
33
- value: boolean;
34
- };
35
- export interface MapOptionTargets extends PollutantTargets {
36
- integration: PollutantTargets["integration"] & {
37
- clustered: boolean;
38
- displayOptions: Record<string, Option>;
39
- };
40
- collocationSites: Toggle;
41
- hmsFire: Toggle;
42
- hmsSmoke: Toggle;
43
- evStations: Toggle & {
44
- clustered: boolean;
45
- displayOptions: {
46
- lvl2: Option;
47
- lvl3: Option;
48
- };
49
- };
50
- wind: Toggle;
51
- mapStyle: {
52
- reset(): void;
53
- };
54
- }
55
- export declare function applyMapOptionDefaults(targets: MapOptionTargets, defaultPollutant: MonitorsPollutant | null): void;
56
- export {};
44
+ /** A fresh copy of the defaults, with monitors on. */
45
+ export declare function defaultMapOptions(): MapOptions;
@@ -1,8 +1,4 @@
1
- import { applyPollutantSelection } from "./pollutant-param";
2
- /**
3
- * Defaults restored by "Reset Map Options". Keep in sync with the constructor defaults in each
4
- * integration (monitors/EV display options, `enabled`, `clustered`) so a reset matches a fresh load.
5
- */
1
+ /** Defaults restored by "Reset Map Options"; a fresh load starts at them too. */
6
2
  export const MAP_OPTION_DEFAULTS = {
7
3
  monitorTypes: {
8
4
  airnow: true,
@@ -11,10 +7,10 @@ export const MAP_OPTION_DEFAULTS = {
11
7
  bam1022: true,
12
8
  airgradient: true,
13
9
  purpleair: true,
14
- vozbox: true,
15
- inactive: false,
16
- inside: false
10
+ vozbox: true
17
11
  },
12
+ inactive: false,
13
+ inside: false,
18
14
  clustered: true,
19
15
  collocationSites: false,
20
16
  fireAndSmoke: true,
@@ -22,26 +18,12 @@ export const MAP_OPTION_DEFAULTS = {
22
18
  evLevels: { lvl2: true, lvl3: true },
23
19
  wind: false
24
20
  };
25
- export function applyMapOptionDefaults(targets, defaultPollutant) {
26
- if (defaultPollutant) {
27
- applyPollutantSelection(defaultPollutant, targets);
28
- }
29
- else {
30
- targets.integration.enabled = true;
31
- }
32
- for (const [key, value] of Object.entries(MAP_OPTION_DEFAULTS.monitorTypes)) {
33
- const option = targets.integration.displayOptions[key];
34
- if (option)
35
- option.value = value;
36
- }
37
- targets.integration.clustered = MAP_OPTION_DEFAULTS.clustered;
38
- targets.collocationSites.enabled = MAP_OPTION_DEFAULTS.collocationSites;
39
- targets.hmsFire.enabled = MAP_OPTION_DEFAULTS.fireAndSmoke;
40
- targets.hmsSmoke.enabled = MAP_OPTION_DEFAULTS.fireAndSmoke;
41
- targets.evStations.enabled = MAP_OPTION_DEFAULTS.evStations;
42
- targets.evStations.clustered = MAP_OPTION_DEFAULTS.clustered;
43
- targets.evStations.displayOptions.lvl2.value = MAP_OPTION_DEFAULTS.evLevels.lvl2;
44
- targets.evStations.displayOptions.lvl3.value = MAP_OPTION_DEFAULTS.evLevels.lvl3;
45
- targets.wind.enabled = MAP_OPTION_DEFAULTS.wind;
46
- targets.mapStyle.reset();
21
+ /** A fresh copy of the defaults, with monitors on. */
22
+ export function defaultMapOptions() {
23
+ return {
24
+ ...MAP_OPTION_DEFAULTS,
25
+ monitorsOn: true,
26
+ monitorTypes: { ...MAP_OPTION_DEFAULTS.monitorTypes },
27
+ evLevels: { ...MAP_OPTION_DEFAULTS.evLevels }
28
+ };
47
29
  }
@@ -0,0 +1,13 @@
1
+ import type { MonitorsPollutant } from "../monitors/types";
2
+ import { type MapOptions } from "./map-option-defaults";
3
+ export type { MapOptions } from "./map-option-defaults";
4
+ /**
5
+ * The toolbar's map options. Module-level, so they survive the layout remounting (as the 4.x
6
+ * integrations' state did); the layout turns them into map-sdk plugins.
7
+ */
8
+ export declare const mapOptions: MapOptions;
9
+ /**
10
+ * "Reset Map Options": every option back to its default, monitors on, and the pollutant back to
11
+ * `defaultPollutant` (the server's default; null before the meta loads leaves it as it is).
12
+ */
13
+ export declare function resetMapOptions(defaultPollutant: MonitorsPollutant | null): void;
@@ -0,0 +1,26 @@
1
+ import { monitorsManager } from "../monitors/monitors.svelte.js";
2
+ import { defaultMapOptions, MAP_OPTION_DEFAULTS } from "./map-option-defaults";
3
+ /**
4
+ * The toolbar's map options. Module-level, so they survive the layout remounting (as the 4.x
5
+ * integrations' state did); the layout turns them into map-sdk plugins.
6
+ */
7
+ export const mapOptions = $state(defaultMapOptions());
8
+ /**
9
+ * "Reset Map Options": every option back to its default, monitors on, and the pollutant back to
10
+ * `defaultPollutant` (the server's default; null before the meta loads leaves it as it is).
11
+ */
12
+ export function resetMapOptions(defaultPollutant) {
13
+ if (defaultPollutant)
14
+ monitorsManager.setPollutant(defaultPollutant);
15
+ mapOptions.monitorsOn = true;
16
+ Object.assign(mapOptions.monitorTypes, MAP_OPTION_DEFAULTS.monitorTypes);
17
+ mapOptions.inactive = MAP_OPTION_DEFAULTS.inactive;
18
+ mapOptions.inside = MAP_OPTION_DEFAULTS.inside;
19
+ mapOptions.clustered = MAP_OPTION_DEFAULTS.clustered;
20
+ mapOptions.collocationSites = MAP_OPTION_DEFAULTS.collocationSites;
21
+ mapOptions.fireAndSmoke = MAP_OPTION_DEFAULTS.fireAndSmoke;
22
+ mapOptions.evStations = MAP_OPTION_DEFAULTS.evStations;
23
+ mapOptions.evLevels.lvl2 = MAP_OPTION_DEFAULTS.evLevels.lvl2;
24
+ mapOptions.evLevels.lvl3 = MAP_OPTION_DEFAULTS.evLevels.lvl3;
25
+ mapOptions.wind = MAP_OPTION_DEFAULTS.wind;
26
+ }
@@ -4,43 +4,31 @@
4
4
  import CheckboxRow from "../rows/CheckboxRow.svelte";
5
5
  import SubmenuRow from "../rows/SubmenuRow.svelte";
6
6
  import MarkerIcon from "../rows/MarkerIcon.svelte";
7
- import { hmsFireMapIntegration } from "../../hms/hms-fire-map-integration.svelte";
8
- import { hmsSmokeMapIntegration } from "../../hms/hms-smoke-map-integration.svelte";
9
- import { evStationsMapIntegration } from "../../ev-stations/ev-stations-map-integration.svelte";
10
-
11
- const levels = $derived(evStationsMapIntegration.displayOptions);
7
+ import { mapOptions } from "../map-options.svelte.js";
8
+ import { ROW_ICONS } from "../row-icons";
12
9
  </script>
13
10
 
14
11
  <OptionsMenu id="layers" label="Layers">
15
12
  {#snippet icon()}
16
13
  <LayersIcon size={20} color="#708090" />
17
14
  {/snippet}
18
- <CheckboxRow
19
- label="Fire & Smoke"
20
- bind:checked={
21
- () => hmsFireMapIntegration.enabled && hmsSmokeMapIntegration.enabled,
22
- (value) => {
23
- hmsFireMapIntegration.enabled = value;
24
- hmsSmokeMapIntegration.enabled = value;
25
- }
26
- }
27
- >
15
+ <CheckboxRow label="Fire & Smoke" bind:checked={mapOptions.fireAndSmoke}>
28
16
  {#snippet icon()}
29
17
  <FlameIcon size={18} color="#ff4500" />
30
18
  {/snippet}
31
19
  </CheckboxRow>
32
- <SubmenuRow label="EV Chargers" bind:checked={evStationsMapIntegration.enabled}>
20
+ <SubmenuRow label="EV Chargers" bind:checked={mapOptions.evStations}>
33
21
  {#snippet icon()}
34
22
  <EvChargerIcon size={18} color="#708090" />
35
23
  {/snippet}
36
- <CheckboxRow label="Level 2" bind:checked={evStationsMapIntegration.displayOptions.lvl2.value}>
24
+ <CheckboxRow label="Level 2" bind:checked={mapOptions.evLevels.lvl2}>
37
25
  {#snippet icon()}
38
- <MarkerIcon icon={levels.lvl2.icon} class="w-5" />
26
+ <MarkerIcon svg={ROW_ICONS.evLevel2} class="w-5" />
39
27
  {/snippet}
40
28
  </CheckboxRow>
41
- <CheckboxRow label="Level 3" bind:checked={evStationsMapIntegration.displayOptions.lvl3.value}>
29
+ <CheckboxRow label="Level 3" bind:checked={mapOptions.evLevels.lvl3}>
42
30
  {#snippet icon()}
43
- <MarkerIcon icon={levels.lvl3.icon} class="w-5" />
31
+ <MarkerIcon svg={ROW_ICONS.evLevel3} class="w-5" />
44
32
  {/snippet}
45
33
  </CheckboxRow>
46
34
  </SubmenuRow>
@@ -1,3 +1,18 @@
1
- declare const LayersMenu: import("svelte").Component<Record<string, never>, {}, "">;
2
- type LayersMenu = ReturnType<typeof LayersMenu>;
1
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
11
+ };
12
+ z_$$bindings?: Bindings;
13
+ }
14
+ declare const LayersMenu: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type LayersMenu = InstanceType<typeof LayersMenu>;
3
18
  export default LayersMenu;