@accelint/map-toolkit 1.4.0 → 2.0.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 (204) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/catalog-info.yaml +4 -4
  3. package/dist/camera/events.js +1 -1
  4. package/dist/camera/index.d.ts +1 -1
  5. package/dist/camera/index.js +1 -1
  6. package/dist/camera/store.d.ts +1 -1
  7. package/dist/camera/store.js +4 -6
  8. package/dist/camera/store.js.map +1 -1
  9. package/dist/camera/types.d.ts +1 -1
  10. package/dist/camera/types.js +1 -1
  11. package/dist/cursor-coordinates/constants.js +1 -1
  12. package/dist/cursor-coordinates/index.d.ts +1 -1
  13. package/dist/cursor-coordinates/index.js +1 -1
  14. package/dist/cursor-coordinates/store.d.ts +1 -1
  15. package/dist/cursor-coordinates/store.js +1 -1
  16. package/dist/cursor-coordinates/types.d.ts +1 -1
  17. package/dist/cursor-coordinates/types.js +1 -1
  18. package/dist/cursor-coordinates/use-cursor-coordinates.d.ts +1 -1
  19. package/dist/cursor-coordinates/use-cursor-coordinates.js +4 -9
  20. package/dist/cursor-coordinates/use-cursor-coordinates.js.map +1 -1
  21. package/dist/deckgl/base-map/constants.js +1 -1
  22. package/dist/deckgl/base-map/controls.d.ts +1 -1
  23. package/dist/deckgl/base-map/controls.js +1 -1
  24. package/dist/deckgl/base-map/events.js +1 -1
  25. package/dist/deckgl/base-map/index.d.ts +3 -3
  26. package/dist/deckgl/base-map/index.js +15 -7
  27. package/dist/deckgl/base-map/index.js.map +1 -1
  28. package/dist/deckgl/base-map/provider.d.ts +3 -3
  29. package/dist/deckgl/base-map/provider.js +3 -5
  30. package/dist/deckgl/base-map/provider.js.map +1 -1
  31. package/dist/deckgl/base-map/types.d.ts +1 -1
  32. package/dist/deckgl/base-map/types.js +1 -1
  33. package/dist/deckgl/index.d.ts +4 -4
  34. package/dist/deckgl/index.js +4 -4
  35. package/dist/deckgl/saved-viewports/index.d.ts +1 -1
  36. package/dist/deckgl/saved-viewports/index.js +1 -1
  37. package/dist/deckgl/saved-viewports/storage.d.ts +1 -1
  38. package/dist/deckgl/saved-viewports/storage.js +5 -10
  39. package/dist/deckgl/saved-viewports/storage.js.map +1 -1
  40. package/dist/deckgl/shapes/display-shape-layer/constants.js +66 -13
  41. package/dist/deckgl/shapes/display-shape-layer/constants.js.map +1 -1
  42. package/dist/deckgl/shapes/display-shape-layer/fiber.d.ts +1 -1
  43. package/dist/deckgl/shapes/display-shape-layer/fiber.js +1 -1
  44. package/dist/deckgl/shapes/display-shape-layer/index.d.ts +74 -35
  45. package/dist/deckgl/shapes/display-shape-layer/index.js +381 -154
  46. package/dist/deckgl/shapes/display-shape-layer/index.js.map +1 -1
  47. package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js +1 -1
  48. package/dist/deckgl/shapes/display-shape-layer/store.js +8 -2
  49. package/dist/deckgl/shapes/display-shape-layer/store.js.map +1 -1
  50. package/dist/deckgl/shapes/display-shape-layer/types.d.ts +108 -19
  51. package/dist/deckgl/shapes/display-shape-layer/types.js +1 -1
  52. package/dist/deckgl/shapes/display-shape-layer/use-select-shape.d.ts +1 -1
  53. package/dist/deckgl/shapes/display-shape-layer/use-select-shape.js +1 -1
  54. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js +66 -36
  55. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js.map +1 -1
  56. package/dist/deckgl/shapes/display-shape-layer/utils/elevation.js +407 -0
  57. package/dist/deckgl/shapes/display-shape-layer/utils/elevation.js.map +1 -0
  58. package/dist/deckgl/shapes/display-shape-layer/utils/icon-config.js +151 -0
  59. package/dist/deckgl/shapes/display-shape-layer/utils/icon-config.js.map +1 -0
  60. package/dist/deckgl/shapes/display-shape-layer/utils/interaction.js +50 -0
  61. package/dist/deckgl/shapes/display-shape-layer/utils/interaction.js.map +1 -0
  62. package/dist/deckgl/shapes/display-shape-layer/utils/labels.d.ts +1 -1
  63. package/dist/deckgl/shapes/display-shape-layer/utils/labels.js +28 -39
  64. package/dist/deckgl/shapes/display-shape-layer/utils/labels.js.map +1 -1
  65. package/dist/deckgl/shapes/draw-shape-layer/constants.js +1 -1
  66. package/dist/deckgl/shapes/draw-shape-layer/events.d.ts +1 -1
  67. package/dist/deckgl/shapes/draw-shape-layer/events.js +1 -1
  68. package/dist/deckgl/shapes/draw-shape-layer/fiber.js +1 -1
  69. package/dist/deckgl/shapes/draw-shape-layer/index.d.ts +3 -3
  70. package/dist/deckgl/shapes/draw-shape-layer/index.js +7 -17
  71. package/dist/deckgl/shapes/draw-shape-layer/index.js.map +1 -1
  72. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js +8 -9
  73. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js.map +1 -1
  74. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js +3 -3
  75. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js +4 -21
  76. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js.map +1 -1
  77. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js +4 -34
  78. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js.map +1 -1
  79. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js +11 -12
  80. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js.map +1 -1
  81. package/dist/deckgl/shapes/draw-shape-layer/modes/index.js +2 -32
  82. package/dist/deckgl/shapes/draw-shape-layer/modes/index.js.map +1 -1
  83. package/dist/deckgl/shapes/draw-shape-layer/store.js +38 -4
  84. package/dist/deckgl/shapes/draw-shape-layer/store.js.map +1 -1
  85. package/dist/deckgl/shapes/draw-shape-layer/types.d.ts +1 -1
  86. package/dist/deckgl/shapes/draw-shape-layer/types.js +1 -1
  87. package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.d.ts +1 -1
  88. package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.js +2 -2
  89. package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js +4 -9
  90. package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js.map +1 -1
  91. package/dist/deckgl/shapes/edit-shape-layer/constants.js +17 -2
  92. package/dist/deckgl/shapes/edit-shape-layer/constants.js.map +1 -1
  93. package/dist/deckgl/shapes/edit-shape-layer/events.d.ts +1 -1
  94. package/dist/deckgl/shapes/edit-shape-layer/events.js +1 -1
  95. package/dist/deckgl/shapes/edit-shape-layer/fiber.d.ts +1 -1
  96. package/dist/deckgl/shapes/edit-shape-layer/fiber.js +1 -1
  97. package/dist/deckgl/shapes/edit-shape-layer/index.d.ts +7 -4
  98. package/dist/deckgl/shapes/edit-shape-layer/index.js +52 -21
  99. package/dist/deckgl/shapes/edit-shape-layer/index.js.map +1 -1
  100. package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js +4 -1
  101. package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js.map +1 -1
  102. package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js +2 -2
  103. package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js.map +1 -1
  104. package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js +7 -7
  105. package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js.map +1 -1
  106. package/dist/deckgl/shapes/edit-shape-layer/modes/index.js +2 -2
  107. package/dist/deckgl/shapes/edit-shape-layer/modes/index.js.map +1 -1
  108. package/dist/deckgl/shapes/edit-shape-layer/modes/point-translate-mode.js +1 -1
  109. package/dist/deckgl/shapes/edit-shape-layer/modes/point-translate-mode.js.map +1 -1
  110. package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js +2 -2
  111. package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js.map +1 -1
  112. package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js +1 -1
  113. package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js.map +1 -1
  114. package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js +1 -1
  115. package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js.map +1 -1
  116. package/dist/deckgl/shapes/edit-shape-layer/store.js +78 -14
  117. package/dist/deckgl/shapes/edit-shape-layer/store.js.map +1 -1
  118. package/dist/deckgl/shapes/edit-shape-layer/types.d.ts +14 -2
  119. package/dist/deckgl/shapes/edit-shape-layer/types.js +1 -1
  120. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.d.ts +1 -1
  121. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js +2 -2
  122. package/dist/deckgl/shapes/index.d.ts +4 -4
  123. package/dist/deckgl/shapes/index.js +5 -5
  124. package/dist/deckgl/shapes/shared/constants.d.ts +4 -3
  125. package/dist/deckgl/shapes/shared/constants.js +55 -15
  126. package/dist/deckgl/shapes/shared/constants.js.map +1 -1
  127. package/dist/deckgl/shapes/shared/events.d.ts +5 -1
  128. package/dist/deckgl/shapes/shared/events.js +1 -1
  129. package/dist/deckgl/shapes/shared/events.js.map +1 -1
  130. package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js +19 -16
  131. package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js.map +1 -1
  132. package/dist/deckgl/shapes/shared/types.d.ts +174 -53
  133. package/dist/deckgl/shapes/shared/types.js +155 -2
  134. package/dist/deckgl/shapes/shared/types.js.map +1 -1
  135. package/dist/deckgl/shapes/shared/utils/geometry-measurements.js +29 -24
  136. package/dist/deckgl/shapes/shared/utils/geometry-measurements.js.map +1 -1
  137. package/dist/deckgl/shapes/shared/utils/layer-config.js +9 -6
  138. package/dist/deckgl/shapes/shared/utils/layer-config.js.map +1 -1
  139. package/dist/deckgl/shapes/shared/utils/mode-utils.js +50 -20
  140. package/dist/deckgl/shapes/shared/utils/mode-utils.js.map +1 -1
  141. package/dist/deckgl/shapes/shared/utils/pick-filtering.js +22 -15
  142. package/dist/deckgl/shapes/shared/utils/pick-filtering.js.map +1 -1
  143. package/dist/deckgl/shapes/shared/utils/style-utils.d.ts +38 -14
  144. package/dist/deckgl/shapes/shared/utils/style-utils.js +43 -32
  145. package/dist/deckgl/shapes/shared/utils/style-utils.js.map +1 -1
  146. package/dist/deckgl/symbol-layer/fiber.d.ts +1 -1
  147. package/dist/deckgl/symbol-layer/fiber.js +1 -1
  148. package/dist/deckgl/symbol-layer/index.d.ts +1 -1
  149. package/dist/deckgl/symbol-layer/index.js +1 -1
  150. package/dist/deckgl/text-layer/character-sets.js +1 -1
  151. package/dist/deckgl/text-layer/default-settings.d.ts +1 -1
  152. package/dist/deckgl/text-layer/default-settings.js +1 -1
  153. package/dist/deckgl/text-layer/fiber.d.ts +1 -1
  154. package/dist/deckgl/text-layer/fiber.js +1 -1
  155. package/dist/deckgl/text-layer/index.d.ts +1 -1
  156. package/dist/deckgl/text-layer/index.js +1 -1
  157. package/dist/deckgl/text-settings.d.ts +3 -3
  158. package/dist/deckgl/text-settings.js +1 -1
  159. package/dist/map-cursor/events.js +1 -1
  160. package/dist/map-cursor/index.d.ts +1 -1
  161. package/dist/map-cursor/index.js +1 -1
  162. package/dist/map-cursor/store.d.ts +1 -1
  163. package/dist/map-cursor/store.js +1 -1
  164. package/dist/map-cursor/types.d.ts +1 -1
  165. package/dist/map-cursor/types.js +1 -1
  166. package/dist/map-cursor/use-map-cursor.d.ts +1 -1
  167. package/dist/map-cursor/use-map-cursor.js +1 -1
  168. package/dist/map-mode/events.js +1 -1
  169. package/dist/map-mode/index.d.ts +1 -1
  170. package/dist/map-mode/index.js +1 -1
  171. package/dist/map-mode/store.d.ts +1 -1
  172. package/dist/map-mode/store.js +3 -8
  173. package/dist/map-mode/store.js.map +1 -1
  174. package/dist/map-mode/types.d.ts +1 -1
  175. package/dist/map-mode/types.js +1 -1
  176. package/dist/map-mode/use-map-mode.d.ts +1 -1
  177. package/dist/map-mode/use-map-mode.js +1 -1
  178. package/dist/maplibre/hooks/use-maplibre.d.ts +1 -1
  179. package/dist/maplibre/hooks/use-maplibre.js +1 -1
  180. package/dist/maplibre/index.d.ts +1 -1
  181. package/dist/maplibre/index.js +1 -1
  182. package/dist/shared/cleanup.d.ts +58 -0
  183. package/dist/shared/cleanup.js +93 -0
  184. package/dist/shared/cleanup.js.map +1 -0
  185. package/dist/shared/constants.js +1 -1
  186. package/dist/shared/create-map-store.d.ts +13 -1
  187. package/dist/shared/create-map-store.js +9 -4
  188. package/dist/shared/create-map-store.js.map +1 -1
  189. package/dist/shared/logger.js +31 -0
  190. package/dist/shared/logger.js.map +1 -0
  191. package/dist/shared/units.js +1 -1
  192. package/dist/viewport/index.d.ts +1 -1
  193. package/dist/viewport/index.js +1 -1
  194. package/dist/viewport/store.d.ts +1 -1
  195. package/dist/viewport/store.js +1 -1
  196. package/dist/viewport/types.d.ts +1 -1
  197. package/dist/viewport/types.js +1 -1
  198. package/dist/viewport/utils.d.ts +1 -1
  199. package/dist/viewport/utils.js +1 -1
  200. package/dist/viewport/viewport-size.d.ts +3 -3
  201. package/dist/viewport/viewport-size.js +1 -1
  202. package/package.json +22 -19
  203. package/dist/hotkey-manager/dist/react/use-hotkey.js +0 -39
  204. package/dist/hotkey-manager/dist/react/use-hotkey.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["CANVAS_CONTEXT_ATTRIBUTES: WebGLContextAttributesWithType","MapLibre"],"sources":["../../../src/deckgl/base-map/index.tsx"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\nimport { useEffectEvent, useEmit } from '@accelint/bus/react';\nimport { Deckgl, useDeckgl } from '@deckgl-fiber-renderer/dom';\nimport type { PickingInfo, ViewStateChangeParameters } from '@deck.gl/core';\nimport 'client-only';\nimport { useCallback, useId, useMemo, useRef } from 'react';\nimport {\n Map as MapLibre,\n type MapRef,\n useControl,\n type ViewState,\n} from 'react-map-gl/maplibre';\nimport { useMapCamera } from '../../camera';\nimport { getCursor } from '../../map-cursor/store';\nimport { DEFAULT_VIEW_STATE } from '../../shared/constants';\nimport { DARK_BASE_MAP_STYLE, PARAMETERS, PICKING_RADIUS } from './constants';\nimport { MapControls } from './controls';\nimport { MapEvents } from './events';\nimport { MapProvider } from './provider';\nimport type { IControl, WebGLContextAttributesWithType } from 'maplibre-gl';\nimport type { MjolnirGestureEvent, MjolnirPointerEvent } from 'mjolnir.js';\nimport type {\n BaseMapProps,\n MapClickEvent,\n MapHoverEvent,\n MapViewportEvent,\n SerializablePickingInfo,\n} from './types';\n\nconst CANVAS_CONTEXT_ATTRIBUTES: WebGLContextAttributesWithType = {\n antialias: true,\n powerPreference: 'high-performance',\n preserveDrawingBuffer: false,\n failIfMajorPerformanceCaveat: false,\n desynchronized: false,\n contextType: 'webgl2',\n} as const;\n\n/**\n * Serializes PickingInfo for event bus transmission.\n * Omits viewport, layer, and sourceLayer (contain functions) but preserves layer IDs.\n *\n * @param info - The PickingInfo object from Deck.gl\n * @returns Serializable picking info with layer IDs extracted\n */\nfunction serializePickingInfo(info: PickingInfo): SerializablePickingInfo {\n const { viewport, layer, sourceLayer, ...infoRest } = info;\n return {\n layerId: layer?.id,\n sourceLayerId: sourceLayer?.id,\n ...infoRest,\n };\n}\n\n/**\n * Strips non-serializable properties from MjolnirGestureEvent for event bus transmission.\n * Removes functions, DOM elements, and PointerEvent objects that cannot be cloned.\n *\n * @param event - The MjolnirGestureEvent from Deck.gl\n * @returns Serializable gesture event with non-cloneable properties removed\n */\nfunction serializeMjolnirEvent(\n event: MjolnirGestureEvent,\n): Omit<\n MjolnirGestureEvent,\n | 'stopPropagation'\n | 'preventDefault'\n | 'stopImmediatePropagation'\n | 'srcEvent'\n | 'rootElement'\n | 'target'\n | 'changedPointers'\n | 'pointers'\n>;\n/**\n * Strips non-serializable properties from MjolnirPointerEvent for event bus transmission.\n * Removes functions and DOM elements that cannot be cloned.\n *\n * @param event - The MjolnirPointerEvent from Deck.gl\n * @returns Serializable pointer event with non-cloneable properties removed\n */\nfunction serializeMjolnirEvent(\n event: MjolnirPointerEvent,\n): Omit<\n MjolnirPointerEvent,\n | 'stopPropagation'\n | 'preventDefault'\n | 'stopImmediatePropagation'\n | 'srcEvent'\n | 'rootElement'\n | 'target'\n>;\nfunction serializeMjolnirEvent(\n event: MjolnirGestureEvent | MjolnirPointerEvent,\n) {\n const {\n stopImmediatePropagation,\n stopPropagation,\n preventDefault,\n srcEvent,\n rootElement,\n target,\n ...rest\n } = event;\n\n // Remove pointer arrays if present (only on MjolnirGestureEvent)\n if ('changedPointers' in rest) {\n const { changedPointers, pointers, ...gestureRest } = rest;\n return gestureRest;\n }\n\n return rest;\n}\n\n/**\n * Internal component that registers the Deck.gl instance as a MapLibre control.\n * Enables the Deck.gl canvas to render within the MapLibre GL map container.\n *\n * @returns null (headless component)\n */\nfunction AddDeckglControl() {\n const deckglInstance = useDeckgl();\n useControl(() => deckglInstance as IControl);\n\n return null;\n}\n\n/**\n * A React component that provides a Deck.gl-powered base map with MapLibre GL integration.\n *\n * This component serves as the foundation for building interactive map applications with\n * support for click and hover events through a centralized event bus. It integrates\n * Deck.gl for 3D visualizations with MapLibre GL for the base map tiles.\n *\n * **Map Mode Integration**: BaseMap automatically creates a `MapProvider` internally,\n * which sets up the map mode state management for this instance.\n * - **Children**: Only Deck.gl layer components can be rendered as children. Custom Deck.gl\n * layers can use `useMapMode()` without parameters to access context.\n * - **Siblings**: UI components (buttons, toolbars, etc.) must be rendered as siblings\n * and pass `id` to `useMapMode(id)`.\n *\n * **Event Bus**: Click and hover events are emitted through the event bus with the `id`\n * included in the payload, allowing multiple map instances to coexist without interference.\n *\n * @param props - Component props including id (required), className, onClick, onHover, and all Deck.gl props\n * @returns A map component with Deck.gl and MapLibre GL integration\n *\n * @example\n * Basic usage with id (recommended: module-level constant):\n * ```tsx\n * import { BaseMap } from '@accelint/map-toolkit/deckgl';\n * import { View } from '@deckgl-fiber-renderer/dom';\n * import { uuid } from '@accelint/core';\n *\n * // Create id at module level for stability and easy sharing\n * const MAIN_MAP_ID = uuid();\n *\n * export function MapView() {\n * return (\n * <BaseMap className=\"w-full h-full\" id={MAIN_MAP_ID}>\n * <View id=\"main\" controller />\n * </BaseMap>\n * );\n * }\n * ```\n *\n * @example\n * With map mode and event handlers (module-level constant for sharing):\n * ```tsx\n * import { BaseMap } from '@accelint/map-toolkit/deckgl';\n * import { useMapMode } from '@accelint/map-toolkit/map-mode';\n * import { uuid } from '@accelint/core';\n * import type { PickingInfo } from '@deck.gl/core';\n * import type { MjolnirGestureEvent } from 'mjolnir.js';\n *\n * // Module-level constant - stable and shareable across all components\n * const MAIN_MAP_ID = uuid();\n *\n * function Toolbar() {\n * // Access map mode using the shared id\n * const { mode, requestModeChange } = useMapMode(MAIN_MAP_ID);\n * return <div>Current mode: {mode}</div>;\n * }\n *\n * export function InteractiveMap() {\n * const handleClick = (info: PickingInfo, event: MjolnirGestureEvent) => {\n * console.log('Clicked:', info.object);\n * };\n *\n * return (\n * <div className=\"relative w-full h-full\">\n * <BaseMap className=\"absolute inset-0\" id={MAIN_MAP_ID} onClick={handleClick}>\n * <View id=\"main\" controller />\n * </BaseMap>\n * <Toolbar />\n * </div>\n * );\n * }\n * ```\n */\nexport function BaseMap({\n id,\n className,\n children,\n controller = true,\n enableControlEvents = true,\n interleaved = true,\n parameters = {},\n styleUrl = DARK_BASE_MAP_STYLE,\n useDevicePixels = false,\n widgets: widgetsProp = [],\n defaultView = '2D',\n initialViewState,\n onClick,\n onHover,\n onViewStateChange,\n pickingRadius,\n ...rest\n}: BaseMapProps) {\n const deckglInstance = useDeckgl();\n const container = useId();\n const mapRef = useRef<MapRef>(null);\n\n const { cameraState, setCameraState } = useMapCamera(id, {\n view: defaultView,\n zoom: initialViewState?.zoom ?? DEFAULT_VIEW_STATE.zoom,\n latitude: initialViewState?.latitude ?? DEFAULT_VIEW_STATE.latitude,\n longitude: initialViewState?.longitude ?? DEFAULT_VIEW_STATE.longitude,\n });\n\n const viewState = useMemo<ViewState>(\n () => ({\n // @ts-expect-error squirrelly deckglInstance typing\n ...(deckglInstance?._deck?._getViewState() as ViewState),\n ...cameraState,\n bearing: cameraState.rotation,\n }),\n // @ts-expect-error squirrelly deckglInstance typing\n [cameraState, deckglInstance?._deck?._getViewState],\n );\n\n // Memoize MapLibre options to avoid creating new object on every render\n const mapOptions = useMemo(\n () => ({\n container,\n zoom: viewState.zoom,\n pitch: viewState.pitch,\n bearing: viewState.bearing,\n latitude: viewState.latitude,\n longitude: viewState.longitude,\n doubleClickZoom: false,\n dragRotate: false,\n pitchWithRotate: false,\n rollEnabled: false,\n attributionControl: { compact: true },\n projection: cameraState.projection,\n maxPitch: cameraState.view === '2D' ? 0 : 85,\n canvasContextAttributes: CANVAS_CONTEXT_ATTRIBUTES,\n }),\n [viewState, container, cameraState.projection, cameraState.view],\n );\n\n const emitClick = useEmit<MapClickEvent>(MapEvents.click);\n const emitHover = useEmit<MapHoverEvent>(MapEvents.hover);\n const emitViewport = useEmit<MapViewportEvent>(MapEvents.viewport);\n\n const resizeTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n const handleClick = useCallback(\n (info: PickingInfo, event: MjolnirGestureEvent) => {\n // send full pickingInfo and event to user-defined onClick\n onClick?.(info, event);\n\n emitClick({\n info: serializePickingInfo(info),\n event: serializeMjolnirEvent(event),\n id,\n });\n },\n [emitClick, id, onClick],\n );\n\n const handleHover = useCallback(\n (info: PickingInfo, event: MjolnirPointerEvent) => {\n // send full pickingInfo and event to user-defined onHover\n onHover?.(info, event);\n\n emitHover({\n info: serializePickingInfo(info),\n event: serializeMjolnirEvent(event),\n id,\n });\n },\n [emitHover, id, onHover],\n );\n\n const handleGetCursor = useCallback(() => {\n return getCursor(id);\n }, [id]);\n\n const handleViewStateChange = useEffectEvent(\n (params: ViewStateChangeParameters) => {\n onViewStateChange?.(params);\n\n const {\n viewId,\n viewState: { latitude, longitude, zoom },\n } = params;\n\n // @ts-expect-error squirrelly deckglInstance typing\n const viewport = deckglInstance._deck\n .getViewports()\n // @ts-expect-error squirrelly deckglInstance typing\n ?.find((vp) => vp.id === viewId);\n\n if (!viewport) {\n return;\n }\n\n emitViewport({\n id,\n bounds: viewport?.getBounds(),\n latitude,\n longitude,\n zoom,\n width: viewport?.width ?? 0,\n height: viewport?.height ?? 0,\n });\n },\n );\n\n const handleResize = useEffectEvent((params) => {\n // Clear existing timeout\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n\n // Debounce\n resizeTimeoutRef.current = setTimeout(() => {\n // @ts-expect-error squirrelly deckglInstance typing\n const viewports = deckglInstance._deck.getViewports() ?? [];\n for (const vp of viewports) {\n handleViewStateChange({\n viewId: vp.id,\n viewState: {\n latitude: vp.latitude,\n longitude: vp.longitude,\n zoom: vp.zoom,\n id: vp.id,\n bounds: vp.getBounds(),\n width: params.width,\n height: params.height,\n },\n } as ViewStateChangeParameters);\n }\n }, 200);\n });\n\n const handleLoad = useEffectEvent(() => {\n //--- force update viewport state once all viewports initialized ---\n // @ts-expect-error squirrelly deckglInstance typing\n const viewports = deckglInstance._deck.getViewports() ?? [];\n for (const vp of viewports) {\n handleViewStateChange({\n viewId: vp.id,\n viewState: {\n latitude: vp.latitude,\n longitude: vp.longitude,\n zoom: vp.zoom,\n id: vp.id,\n bounds: vp.getBounds(),\n width: vp.width,\n height: vp.height,\n },\n } as ViewStateChangeParameters);\n }\n });\n\n return (\n <div id={container} className={className}>\n {enableControlEvents && <MapControls id={id} mapRef={mapRef} />}\n <MapProvider id={id}>\n <MapLibre\n onMove={(evt) => setCameraState(evt.viewState)}\n mapStyle={styleUrl}\n ref={mapRef}\n {...mapOptions}\n >\n <Deckgl\n {...rest}\n controller={controller}\n interleaved={interleaved}\n getCursor={handleGetCursor}\n useDevicePixels={useDevicePixels}\n onClick={handleClick}\n pickingRadius={pickingRadius ?? PICKING_RADIUS}\n onHover={handleHover}\n onLoad={handleLoad}\n onResize={handleResize}\n onViewStateChange={handleViewStateChange}\n // @ts-expect-error - DeckglProps parameters type is overly strict for WebGL parameter spreading.\n // The merged object is valid at runtime but TypeScript cannot verify all possible parameter combinations.\n parameters={{ ...PARAMETERS, ...parameters }}\n >\n <AddDeckglControl />\n {children}\n </Deckgl>\n </MapLibre>\n </MapProvider>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["CANVAS_CONTEXT_ATTRIBUTES: WebGLContextAttributesWithType","MapLibre"],"sources":["../../../src/deckgl/base-map/index.tsx"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\nimport { useEffectEvent, useEmit } from '@accelint/bus/react';\nimport { Deckgl, useDeckgl } from '@deckgl-fiber-renderer/dom';\nimport type { PickingInfo, ViewStateChangeParameters } from '@deck.gl/core';\nimport 'client-only';\nimport { useCallback, useId, useMemo, useRef } from 'react';\nimport {\n Map as MapLibre,\n type MapRef,\n useControl,\n type ViewState,\n} from 'react-map-gl/maplibre';\nimport { useMapCamera } from '../../camera';\nimport { getCursor } from '../../map-cursor/store';\nimport { getMapGeneration } from '../../shared/cleanup';\nimport { DEFAULT_VIEW_STATE } from '../../shared/constants';\nimport { DARK_BASE_MAP_STYLE, PARAMETERS, PICKING_RADIUS } from './constants';\nimport { MapControls } from './controls';\nimport { MapEvents } from './events';\nimport { MapProvider } from './provider';\nimport type { IControl, WebGLContextAttributesWithType } from 'maplibre-gl';\nimport type { MjolnirGestureEvent, MjolnirPointerEvent } from 'mjolnir.js';\nimport type {\n BaseMapProps,\n MapClickEvent,\n MapHoverEvent,\n MapViewportEvent,\n SerializablePickingInfo,\n} from './types';\n\nconst CANVAS_CONTEXT_ATTRIBUTES: WebGLContextAttributesWithType = {\n antialias: true,\n powerPreference: 'high-performance',\n preserveDrawingBuffer: false,\n failIfMajorPerformanceCaveat: false,\n desynchronized: false,\n contextType: 'webgl2',\n} as const;\n\n/**\n * Serializes PickingInfo for event bus transmission.\n * Omits viewport, layer, and sourceLayer (contain functions) but preserves layer IDs.\n *\n * @param info - The PickingInfo object from Deck.gl\n * @returns Serializable picking info with layer IDs extracted\n */\nfunction serializePickingInfo(info: PickingInfo): SerializablePickingInfo {\n const { viewport, layer, sourceLayer, ...infoRest } = info;\n return {\n layerId: layer?.id,\n sourceLayerId: sourceLayer?.id,\n ...infoRest,\n };\n}\n\n/**\n * Strips non-serializable properties from MjolnirGestureEvent for event bus transmission.\n * Removes functions, DOM elements, and PointerEvent objects that cannot be cloned.\n *\n * @param event - The MjolnirGestureEvent from Deck.gl\n * @returns Serializable gesture event with non-cloneable properties removed\n */\nfunction serializeMjolnirEvent(\n event: MjolnirGestureEvent,\n): Omit<\n MjolnirGestureEvent,\n | 'stopPropagation'\n | 'preventDefault'\n | 'stopImmediatePropagation'\n | 'srcEvent'\n | 'rootElement'\n | 'target'\n | 'changedPointers'\n | 'pointers'\n>;\n/**\n * Strips non-serializable properties from MjolnirPointerEvent for event bus transmission.\n * Removes functions and DOM elements that cannot be cloned.\n *\n * @param event - The MjolnirPointerEvent from Deck.gl\n * @returns Serializable pointer event with non-cloneable properties removed\n */\nfunction serializeMjolnirEvent(\n event: MjolnirPointerEvent,\n): Omit<\n MjolnirPointerEvent,\n | 'stopPropagation'\n | 'preventDefault'\n | 'stopImmediatePropagation'\n | 'srcEvent'\n | 'rootElement'\n | 'target'\n>;\nfunction serializeMjolnirEvent(\n event: MjolnirGestureEvent | MjolnirPointerEvent,\n) {\n const {\n stopImmediatePropagation,\n stopPropagation,\n preventDefault,\n srcEvent,\n rootElement,\n target,\n ...rest\n } = event;\n\n // Remove pointer arrays if present (only on MjolnirGestureEvent)\n if ('changedPointers' in rest) {\n const { changedPointers, pointers, ...gestureRest } = rest;\n return gestureRest;\n }\n\n return rest;\n}\n\n/**\n * Internal component that registers the Deck.gl instance as a MapLibre control.\n * Enables the Deck.gl canvas to render within the MapLibre GL map container.\n *\n * @returns null (headless component)\n */\nfunction AddDeckglControl() {\n const deckglInstance = useDeckgl();\n useControl(() => deckglInstance as IControl);\n\n return null;\n}\n\n/**\n * A React component that provides a Deck.gl-powered base map with MapLibre GL integration.\n *\n * This component serves as the foundation for building interactive map applications with\n * support for click and hover events through a centralized event bus. It integrates\n * Deck.gl for 3D visualizations with MapLibre GL for the base map tiles.\n *\n * **Map Mode Integration**: BaseMap automatically creates a `MapProvider` internally,\n * which sets up the map mode state management for this instance.\n * - **Children**: Only Deck.gl layer components can be rendered as children. Custom Deck.gl\n * layers can use `useMapMode()` without parameters to access context.\n * - **Siblings**: UI components (buttons, toolbars, etc.) must be rendered as siblings\n * and pass `id` to `useMapMode(id)`.\n *\n * **Event Bus**: Click and hover events are emitted through the event bus with the `id`\n * included in the payload, allowing multiple map instances to coexist without interference.\n *\n * @param props - Component props including id (required), className, onClick, onHover, and all Deck.gl props\n * @returns A map component with Deck.gl and MapLibre GL integration\n *\n * @example\n * Basic usage with id (recommended: module-level constant):\n * ```tsx\n * import { BaseMap } from '@accelint/map-toolkit/deckgl';\n * import { View } from '@deckgl-fiber-renderer/dom';\n * import { uuid } from '@accelint/core';\n *\n * // Create id at module level for stability and easy sharing\n * const MAIN_MAP_ID = uuid();\n *\n * export function MapView() {\n * return (\n * <BaseMap className=\"w-full h-full\" id={MAIN_MAP_ID}>\n * <View id=\"main\" controller />\n * </BaseMap>\n * );\n * }\n * ```\n *\n * @example\n * With map mode and event handlers (module-level constant for sharing):\n * ```tsx\n * import { BaseMap } from '@accelint/map-toolkit/deckgl';\n * import { useMapMode } from '@accelint/map-toolkit/map-mode';\n * import { uuid } from '@accelint/core';\n * import type { PickingInfo } from '@deck.gl/core';\n * import type { MjolnirGestureEvent } from 'mjolnir.js';\n *\n * // Module-level constant - stable and shareable across all components\n * const MAIN_MAP_ID = uuid();\n *\n * function Toolbar() {\n * // Access map mode using the shared id\n * const { mode, requestModeChange } = useMapMode(MAIN_MAP_ID);\n * return <div>Current mode: {mode}</div>;\n * }\n *\n * export function InteractiveMap() {\n * const handleClick = (info: PickingInfo, event: MjolnirGestureEvent) => {\n * console.log('Clicked:', info.object);\n * };\n *\n * return (\n * <div className=\"relative w-full h-full\">\n * <BaseMap className=\"absolute inset-0\" id={MAIN_MAP_ID} onClick={handleClick}>\n * <View id=\"main\" controller />\n * </BaseMap>\n * <Toolbar />\n * </div>\n * );\n * }\n * ```\n */\nexport function BaseMap({\n id,\n className,\n children,\n controller = true,\n enableControlEvents = true,\n interleaved = true,\n parameters = {},\n styleUrl = DARK_BASE_MAP_STYLE,\n useDevicePixels = false,\n widgets: widgetsProp = [],\n defaultView = '2D',\n initialViewState,\n onClick,\n onHover,\n onViewStateChange,\n pickingRadius,\n ...rest\n}: BaseMapProps) {\n const mapGeneration = getMapGeneration(id);\n const deckglInstance = useDeckgl();\n const container = useId();\n const mapRef = useRef<MapRef>(null);\n\n const { cameraState, setCameraState } = useMapCamera(id, {\n view: defaultView,\n zoom: initialViewState?.zoom ?? DEFAULT_VIEW_STATE.zoom,\n latitude: initialViewState?.latitude ?? DEFAULT_VIEW_STATE.latitude,\n longitude: initialViewState?.longitude ?? DEFAULT_VIEW_STATE.longitude,\n });\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: we only need to recompute when cameraState changes.\n const viewState = useMemo<ViewState>(\n () => ({\n // @ts-expect-error squirrelly deckglInstance typing\n ...(deckglInstance?._deck?._getViewState() as ViewState),\n ...cameraState,\n bearing: cameraState.rotation,\n }),\n [cameraState],\n );\n\n // Memoize MapLibre options to avoid creating new object on every render\n const mapOptions = useMemo(\n () => ({\n container,\n zoom: viewState.zoom,\n pitch: viewState.pitch,\n bearing: viewState.bearing,\n latitude: viewState.latitude,\n longitude: viewState.longitude,\n doubleClickZoom: false,\n dragRotate: false,\n pitchWithRotate: false,\n rollEnabled: false,\n attributionControl: { compact: true },\n projection: cameraState.projection,\n maxPitch: cameraState.view === '2D' ? 0 : 85,\n canvasContextAttributes: CANVAS_CONTEXT_ATTRIBUTES,\n }),\n [viewState, container, cameraState.projection, cameraState.view],\n );\n\n const emitClick = useEmit<MapClickEvent>(MapEvents.click);\n const emitHover = useEmit<MapHoverEvent>(MapEvents.hover);\n const emitViewport = useEmit<MapViewportEvent>(MapEvents.viewport);\n\n const resizeTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n const handleClick = useCallback(\n (info: PickingInfo, event: MjolnirGestureEvent) => {\n // send full pickingInfo and event to user-defined onClick\n onClick?.(info, event);\n\n emitClick({\n info: serializePickingInfo(info),\n event: serializeMjolnirEvent(event),\n id,\n });\n },\n [emitClick, id, onClick],\n );\n\n const handleHover = useCallback(\n (info: PickingInfo, event: MjolnirPointerEvent) => {\n // send full pickingInfo and event to user-defined onHover\n onHover?.(info, event);\n\n emitHover({\n info: serializePickingInfo(info),\n event: serializeMjolnirEvent(event),\n id,\n });\n },\n [emitHover, id, onHover],\n );\n\n const handleGetCursor = useCallback(() => {\n return getCursor(id);\n }, [id]);\n\n const handleViewStateChange = useEffectEvent(\n (params: ViewStateChangeParameters) => {\n onViewStateChange?.(params);\n\n const {\n viewId,\n viewState: { latitude, longitude, zoom },\n } = params;\n\n // @ts-expect-error squirrelly deckglInstance typing\n const viewports = deckglInstance._deck?.getViewports();\n if (!viewports) {\n return;\n }\n\n // @ts-expect-error squirrelly deckglInstance typing\n const viewport = viewports.find((vp) => vp.id === viewId);\n\n if (!viewport) {\n return;\n }\n\n emitViewport({\n id,\n bounds: viewport?.getBounds(),\n latitude,\n longitude,\n zoom,\n width: viewport?.width ?? 0,\n height: viewport?.height ?? 0,\n });\n },\n );\n\n const handleResize = useEffectEvent((params) => {\n // Clear existing timeout\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n\n // Debounce\n resizeTimeoutRef.current = setTimeout(() => {\n // @ts-expect-error squirrelly deckglInstance typing\n const viewports = deckglInstance._deck?.getViewports();\n if (!viewports) {\n return;\n }\n for (const vp of viewports) {\n handleViewStateChange({\n viewId: vp.id,\n viewState: {\n latitude: vp.latitude,\n longitude: vp.longitude,\n zoom: vp.zoom,\n id: vp.id,\n bounds: vp.getBounds(),\n width: params.width,\n height: params.height,\n },\n } as ViewStateChangeParameters);\n }\n }, 200);\n });\n\n const handleLoad = useEffectEvent(() => {\n //--- force update viewport state once all viewports initialized ---\n // @ts-expect-error squirrelly deckglInstance typing\n const viewports = deckglInstance._deck?.getViewports();\n if (!viewports) {\n return;\n }\n for (const vp of viewports) {\n handleViewStateChange({\n viewId: vp.id,\n viewState: {\n latitude: vp.latitude,\n longitude: vp.longitude,\n zoom: vp.zoom,\n id: vp.id,\n bounds: vp.getBounds(),\n width: vp.width,\n height: vp.height,\n },\n } as ViewStateChangeParameters);\n }\n });\n\n return (\n <div id={container} className={className}>\n {enableControlEvents && <MapControls id={id} mapRef={mapRef} />}\n <MapProvider id={id}>\n <MapLibre\n key={mapGeneration}\n onMove={(evt) => {\n setCameraState(evt.viewState);\n }}\n mapStyle={styleUrl}\n ref={mapRef}\n {...mapOptions}\n >\n <Deckgl\n {...rest}\n controller={controller}\n interleaved={interleaved}\n getCursor={handleGetCursor}\n useDevicePixels={useDevicePixels}\n onClick={handleClick}\n pickingRadius={pickingRadius ?? PICKING_RADIUS}\n onHover={handleHover}\n onLoad={handleLoad}\n onResize={handleResize}\n onViewStateChange={handleViewStateChange}\n // @ts-expect-error - DeckglProps parameters type is overly strict for WebGL parameter spreading.\n // The merged object is valid at runtime but TypeScript cannot verify all possible parameter combinations.\n parameters={{ ...PARAMETERS, ...parameters }}\n >\n <AddDeckglControl />\n {children}\n </Deckgl>\n </MapLibre>\n </MapProvider>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -12,7 +12,7 @@
12
12
 
13
13
  import { ReactNode } from "react";
14
14
  import { UniqueId } from "@accelint/core";
15
- import * as react_jsx_runtime3 from "react/jsx-runtime";
15
+ import * as react_jsx_runtime1 from "react/jsx-runtime";
16
16
 
17
17
  //#region src/deckgl/base-map/provider.d.ts
18
18
  /**
@@ -139,7 +139,7 @@ type MapProviderProps = {
139
139
  declare function MapProvider({
140
140
  children,
141
141
  id
142
- }: MapProviderProps): react_jsx_runtime3.JSX.Element;
142
+ }: MapProviderProps): react_jsx_runtime1.JSX.Element;
143
143
  //#endregion
144
144
  export { MapContext, MapProvider, MapProviderProps };
145
145
  //# sourceMappingURL=provider.d.ts.map
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -13,8 +13,7 @@
13
13
 
14
14
  'use client';
15
15
 
16
- import { clearCursorState } from "../../map-cursor/store.js";
17
- import { clearMapModeState } from "../../map-mode/store.js";
16
+ import { clearAllMapStores } from "../../shared/cleanup.js";
18
17
  import { createContext, useEffect } from "react";
19
18
  import { jsx } from "react/jsx-runtime";
20
19
 
@@ -114,8 +113,7 @@ const MapContext = createContext(null);
114
113
  function MapProvider({ children, id }) {
115
114
  useEffect(() => {
116
115
  return () => {
117
- clearMapModeState(id);
118
- clearCursorState(id);
116
+ clearAllMapStores(id);
119
117
  };
120
118
  }, [id]);
121
119
  return /* @__PURE__ */ jsx(MapContext.Provider, {
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","names":[],"sources":["../../../src/deckgl/base-map/provider.tsx"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\nimport 'client-only';\nimport { createContext, type ReactNode, useEffect } from 'react';\nimport { clearCursorState } from '../../map-cursor/store';\nimport { clearMapModeState } from '../../map-mode/store';\nimport type { UniqueId } from '@accelint/core';\n\n/**\n * React context for map ID.\n * Use the `useMapMode` hook to access the map mode state.\n */\nexport const MapContext = createContext<UniqueId | null>(null);\n\n/**\n * Props for the MapProvider component.\n */\nexport type MapProviderProps = {\n /** Child components that will have access to map mode context */\n children: ReactNode;\n /**\n * Unique identifier for this map instance.\n *\n * Used to isolate mode changes between different map instances (e.g., main map vs minimap).\n * This is required and should be provided by the parent component (typically BaseMap).\n *\n * @example\n * ```tsx\n * // Multiple independent map instances\n * const mainMapId = uuid();\n * const minimapId = uuid();\n *\n * <MapProvider id={mainMapId}>\n * // Map layers and components\n * </MapProvider>\n *\n * <MapProvider id={minimapId}>\n * // Minimap layers and components\n * </MapProvider>\n * ```\n */\n id: UniqueId;\n};\n\n/**\n * Provider component for managing map modes with ownership and authorization.\n *\n * **Note**: This provider is used internally by `BaseMap` and should not be used directly.\n * Consumers should pass the `id` prop to `BaseMap`, which will create this provider automatically.\n *\n * This component uses a hybrid architecture combining React Context (for map instance identity)\n * with module-level state management (for map mode state). The provider:\n * - Provides a unique `id` via Context\n * - Cleans up map mode state when unmounted\n * - Allows components to subscribe to mode changes via `useMapMode` hook (which uses `useSyncExternalStore`)\n *\n * The module-level state management system implements a state machine for map modes where\n * components can request mode changes with ownership. When a mode is owned by a component,\n * other components must request authorization to change to a different mode. The system handles:\n *\n * - Automatic mode changes when no ownership conflicts exist\n * - Authorization flow when switching between owned modes\n * - Per-mode ownership tracking that persists throughout the session\n * - Pending request management (one pending request per requester)\n * - Auto-acceptance of first pending request when mode owner returns to default\n * - Auto-rejection of other pending requests when one is approved\n * - Event emission through a centralized event bus\n * - Instance isolation for multiple map scenarios (main map + minimap)\n * - Always initializes in 'default' mode\n *\n * ## Instance Isolation\n *\n * Each MapProvider instance operates independently. Mode changes in one instance\n * do not affect other instances, even when multiple maps are rendered on the same page.\n * This enables scenarios like:\n * - Main map in \"drawing\" mode while minimap stays in \"view\" mode\n * - Multiple independent map views with different interaction modes\n *\n * Events are scoped to specific instances using the `id` prop. The event bus\n * filters events to ensure each provider only responds to events for its own instance.\n *\n * ## Pending Request Behavior\n *\n * - Pending requests are stored by requester ID (not mode owner)\n * - Each requester can have only one pending request at a time\n * - New requests from the same requester auto-replace previous requests\n * - Pending requests persist when mode owner switches between their own modes\n * - When any request is approved, all other pending requests are auto-rejected\n * - When mode owner returns to default mode:\n * - If first pending request is for default mode, all pending requests are rejected (already in requested mode)\n * - If first pending request is for a different mode, that request is auto-approved and others are rejected\n *\n * ## Instance ID Stability and Lifecycle\n *\n * The provider's cleanup mechanism (via `useEffect`) ensures proper state management:\n * - Map mode state is cleaned up when the provider unmounts\n * - Changing the `id` prop will trigger cleanup of the old state via the effect dependency\n * - State is lazily initialized on first subscription (no manual creation needed)\n *\n * While the `id` prop should typically remain stable (created as a module-level constant\n * or with `useState`), changing it will work correctly due to the cleanup mechanism.\n *\n * @param props - Provider props including children and required id\n * @returns Provider component that wraps children with map instance identity context\n *\n * @example\n * Internal usage within BaseMap:\n * ```tsx\n * // BaseMap automatically creates the provider\n * function BaseMap({ id, children, ...props }: BaseMapProps) {\n * return (\n * <div>\n * <MapProvider id={id}>\n * <Deckgl {...props}>\n * {children}\n * </Deckgl>\n * </MapProvider>\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * With authorization handling - use id in event payloads:\n * ```tsx\n * useOn(MapModeEvents.changeAuthorization, (event) => {\n * const { authId, id } = event.payload;\n * emitDecision({ authId, approved: true, owner: 'tool', id });\n * });\n * ```\n */\nexport function MapProvider({ children, id }: MapProviderProps) {\n // Cleanup when component unmounts\n // State is created automatically on first subscription in useMapMode/useMapCursor\n useEffect(() => {\n return () => {\n clearMapModeState(id);\n clearCursorState(id);\n };\n }, [id]);\n\n return <MapContext.Provider value={id}>{children}</MapContext.Provider>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAa,aAAa,cAA+B,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuH9D,SAAgB,YAAY,EAAE,UAAU,MAAwB;AAG9D,iBAAgB;AACd,eAAa;AACX,qBAAkB,GAAG;AACrB,oBAAiB,GAAG;;IAErB,CAAC,GAAG,CAAC;AAER,QAAO,oBAAC,WAAW;EAAS,OAAO;EAAK;GAA+B"}
1
+ {"version":3,"file":"provider.js","names":[],"sources":["../../../src/deckgl/base-map/provider.tsx"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\nimport 'client-only';\nimport { createContext, type ReactNode, useEffect } from 'react';\nimport { clearAllMapStores } from '../../shared/cleanup';\nimport type { UniqueId } from '@accelint/core';\n\n/**\n * React context for map ID.\n * Use the `useMapMode` hook to access the map mode state.\n */\nexport const MapContext = createContext<UniqueId | null>(null);\n\n/**\n * Props for the MapProvider component.\n */\nexport type MapProviderProps = {\n /** Child components that will have access to map mode context */\n children: ReactNode;\n /**\n * Unique identifier for this map instance.\n *\n * Used to isolate mode changes between different map instances (e.g., main map vs minimap).\n * This is required and should be provided by the parent component (typically BaseMap).\n *\n * @example\n * ```tsx\n * // Multiple independent map instances\n * const mainMapId = uuid();\n * const minimapId = uuid();\n *\n * <MapProvider id={mainMapId}>\n * // Map layers and components\n * </MapProvider>\n *\n * <MapProvider id={minimapId}>\n * // Minimap layers and components\n * </MapProvider>\n * ```\n */\n id: UniqueId;\n};\n\n/**\n * Provider component for managing map modes with ownership and authorization.\n *\n * **Note**: This provider is used internally by `BaseMap` and should not be used directly.\n * Consumers should pass the `id` prop to `BaseMap`, which will create this provider automatically.\n *\n * This component uses a hybrid architecture combining React Context (for map instance identity)\n * with module-level state management (for map mode state). The provider:\n * - Provides a unique `id` via Context\n * - Cleans up map mode state when unmounted\n * - Allows components to subscribe to mode changes via `useMapMode` hook (which uses `useSyncExternalStore`)\n *\n * The module-level state management system implements a state machine for map modes where\n * components can request mode changes with ownership. When a mode is owned by a component,\n * other components must request authorization to change to a different mode. The system handles:\n *\n * - Automatic mode changes when no ownership conflicts exist\n * - Authorization flow when switching between owned modes\n * - Per-mode ownership tracking that persists throughout the session\n * - Pending request management (one pending request per requester)\n * - Auto-acceptance of first pending request when mode owner returns to default\n * - Auto-rejection of other pending requests when one is approved\n * - Event emission through a centralized event bus\n * - Instance isolation for multiple map scenarios (main map + minimap)\n * - Always initializes in 'default' mode\n *\n * ## Instance Isolation\n *\n * Each MapProvider instance operates independently. Mode changes in one instance\n * do not affect other instances, even when multiple maps are rendered on the same page.\n * This enables scenarios like:\n * - Main map in \"drawing\" mode while minimap stays in \"view\" mode\n * - Multiple independent map views with different interaction modes\n *\n * Events are scoped to specific instances using the `id` prop. The event bus\n * filters events to ensure each provider only responds to events for its own instance.\n *\n * ## Pending Request Behavior\n *\n * - Pending requests are stored by requester ID (not mode owner)\n * - Each requester can have only one pending request at a time\n * - New requests from the same requester auto-replace previous requests\n * - Pending requests persist when mode owner switches between their own modes\n * - When any request is approved, all other pending requests are auto-rejected\n * - When mode owner returns to default mode:\n * - If first pending request is for default mode, all pending requests are rejected (already in requested mode)\n * - If first pending request is for a different mode, that request is auto-approved and others are rejected\n *\n * ## Instance ID Stability and Lifecycle\n *\n * The provider's cleanup mechanism (via `useEffect`) ensures proper state management:\n * - Map mode state is cleaned up when the provider unmounts\n * - Changing the `id` prop will trigger cleanup of the old state via the effect dependency\n * - State is lazily initialized on first subscription (no manual creation needed)\n *\n * While the `id` prop should typically remain stable (created as a module-level constant\n * or with `useState`), changing it will work correctly due to the cleanup mechanism.\n *\n * @param props - Provider props including children and required id\n * @returns Provider component that wraps children with map instance identity context\n *\n * @example\n * Internal usage within BaseMap:\n * ```tsx\n * // BaseMap automatically creates the provider\n * function BaseMap({ id, children, ...props }: BaseMapProps) {\n * return (\n * <div>\n * <MapProvider id={id}>\n * <Deckgl {...props}>\n * {children}\n * </Deckgl>\n * </MapProvider>\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * With authorization handling - use id in event payloads:\n * ```tsx\n * useOn(MapModeEvents.changeAuthorization, (event) => {\n * const { authId, id } = event.payload;\n * emitDecision({ authId, approved: true, owner: 'tool', id });\n * });\n * ```\n */\nexport function MapProvider({ children, id }: MapProviderProps) {\n // Cleanup when component unmounts\n // State is created automatically on first subscription in useMapMode/useMapCursor/useMapCamera\n useEffect(() => {\n return () => {\n clearAllMapStores(id);\n };\n }, [id]);\n\n return <MapContext.Provider value={id}>{children}</MapContext.Provider>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,aAAa,cAA+B,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuH9D,SAAgB,YAAY,EAAE,UAAU,MAAwB;AAG9D,iBAAgB;AACd,eAAa;AACX,qBAAkB,GAAG;;IAEtB,CAAC,GAAG,CAAC;AAER,QAAO,oBAAC,WAAW;EAAS,OAAO;EAAK;GAA+B"}
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -15,11 +15,11 @@ import { BaseMapProps, MapClickEvent, MapClickPayload, MapControlPayload, MapDis
15
15
  import { DARK_BASE_MAP_STYLE, LIGHT_BASE_MAP_STYLE, PARAMETERS } from "./base-map/constants.js";
16
16
  import { BaseMap } from "./base-map/index.js";
17
17
  import { SavedViewportOptions, createSavedViewport } from "./saved-viewports/index.js";
18
- import { CircleProperties, CircleRadius, EllipseProperties, Shape, ShapeFeature, ShapeFeatureProperties, ShapeFeatureType, ShapeFeatureTypeValues, ShapeId, StyleProperties } from "./shapes/shared/types.js";
19
- import { DisplayShapeLayerProps, StyledFeature, StyledFeatureProperties } from "./shapes/display-shape-layer/types.js";
18
+ import { CircleProperties, CircleRadius, EllipseProperties, Shape, ShapeFeature, ShapeFeatureProperties, ShapeFeatureType, ShapeId, StyleProperties, StyledFeature, StyledFeatureProperties } from "./shapes/shared/types.js";
19
+ import { DisplayShapeLayerProps } from "./shapes/display-shape-layer/types.js";
20
20
  import { DisplayShapeLayer } from "./shapes/display-shape-layer/index.js";
21
21
  import { DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_STYLE_PROPERTIES, LINE_PATTERNS, LINE_WIDTHS, SHAPE_LAYER_IDS } from "./shapes/shared/constants.js";
22
22
  import { ShapeEventType, ShapeEvents } from "./shapes/shared/events.js";
23
23
  import "./shapes/index.js";
24
24
  import { SymbolLayer, SymbolLayerProps } from "./symbol-layer/index.js";
25
- export { BaseMap, type BaseMapProps, type CircleProperties, type CircleRadius, DARK_BASE_MAP_STYLE, DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_STYLE_PROPERTIES, DisplayShapeLayer, type DisplayShapeLayerProps, type EllipseProperties, LIGHT_BASE_MAP_STYLE, LINE_PATTERNS, LINE_WIDTHS, type MapClickEvent, type MapClickPayload, type MapControlPayload, type MapDisablePanEvent, type MapDisableZoomEvent, type MapEnablePanEvent, type MapEnableZoomEvent, type MapEventType, MapEvents, MapEventsNamespace, type MapHoverEvent, type MapHoverPayload, PARAMETERS, SHAPE_LAYER_IDS, type SavedViewportOptions, type Shape, type ShapeEventType, ShapeEvents, type ShapeFeature, type ShapeFeatureProperties, ShapeFeatureType, type ShapeFeatureTypeValues, type ShapeId, type StyleProperties, type StyledFeature, type StyledFeatureProperties, SymbolLayer, type SymbolLayerProps, createSavedViewport };
25
+ export { BaseMap, type BaseMapProps, type CircleProperties, type CircleRadius, DARK_BASE_MAP_STYLE, DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_STYLE_PROPERTIES, DisplayShapeLayer, type DisplayShapeLayerProps, type EllipseProperties, LIGHT_BASE_MAP_STYLE, LINE_PATTERNS, LINE_WIDTHS, type MapClickEvent, type MapClickPayload, type MapControlPayload, type MapDisablePanEvent, type MapDisableZoomEvent, type MapEnablePanEvent, type MapEnableZoomEvent, type MapEventType, MapEvents, MapEventsNamespace, type MapHoverEvent, type MapHoverPayload, PARAMETERS, SHAPE_LAYER_IDS, type SavedViewportOptions, type Shape, type ShapeEventType, ShapeEvents, type ShapeFeature, type ShapeFeatureProperties, ShapeFeatureType, type ShapeId, type StyleProperties, type StyledFeature, type StyledFeatureProperties, SymbolLayer, type SymbolLayerProps, createSavedViewport };
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -12,12 +12,12 @@
12
12
 
13
13
 
14
14
  import { MapEvents, MapEventsNamespace } from "./base-map/events.js";
15
+ import { ShapeEvents } from "./shapes/shared/events.js";
16
+ import { ShapeFeatureType } from "./shapes/shared/types.js";
17
+ import { DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_STYLE_PROPERTIES, LINE_PATTERNS, LINE_WIDTHS, SHAPE_LAYER_IDS } from "./shapes/shared/constants.js";
15
18
  import { DARK_BASE_MAP_STYLE, LIGHT_BASE_MAP_STYLE, PARAMETERS } from "./base-map/constants.js";
16
19
  import { BaseMap } from "./base-map/index.js";
17
20
  import { createSavedViewport } from "./saved-viewports/index.js";
18
- import { DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_STYLE_PROPERTIES, LINE_PATTERNS, LINE_WIDTHS, SHAPE_LAYER_IDS } from "./shapes/shared/constants.js";
19
- import { ShapeEvents } from "./shapes/shared/events.js";
20
- import { ShapeFeatureType } from "./shapes/shared/types.js";
21
21
  import { DisplayShapeLayer } from "./shapes/display-shape-layer/index.js";
22
22
  import { SymbolLayer } from "./symbol-layer/index.js";
23
23
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -11,15 +11,10 @@
11
11
  */
12
12
 
13
13
 
14
- import { getLogger } from "@accelint/logger";
14
+ import { createLoggerDomain } from "../../shared/logger.js";
15
15
 
16
16
  //#region src/deckgl/saved-viewports/storage.ts
17
- const logger = getLogger({
18
- enabled: process.env.NODE_ENV !== "production" && process.env.NODE_ENV !== "test",
19
- level: "warn",
20
- prefix: "[SavedViewports]",
21
- pretty: true
22
- });
17
+ const logger = createLoggerDomain("[SavedViewports]");
23
18
  /**
24
19
  * Base storage key for saved viewports in localStorage.
25
20
  */
@@ -41,8 +36,8 @@ const getContainerKey = (uniqueIdentifier) => uniqueIdentifier ? `${STORAGE_ID}-
41
36
  const getContainer = (containerKey) => {
42
37
  try {
43
38
  return JSON.parse(localStorage.getItem(containerKey) ?? "{}");
44
- } catch {
45
- logger.warn(`Failed to parse storage container for key: ${containerKey}, returning empty container.`);
39
+ } catch (err) {
40
+ logger.withError(err).error(`Failed to parse storage container for key: ${containerKey}, returning empty container.`);
46
41
  return {};
47
42
  }
48
43
  };
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","names":[],"sources":["../../../src/deckgl/saved-viewports/storage.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { getLogger } from '@accelint/logger';\nimport type { MapViewState } from '@deck.gl/core';\n\nconst logger = getLogger({\n enabled:\n process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test',\n level: 'warn',\n prefix: '[SavedViewports]',\n pretty: true,\n});\n\n/**\n * Base storage key for saved viewports in localStorage.\n */\nexport const STORAGE_ID = 'deckgl-saved-viewports';\n\n/**\n * Generates a storage key, optionally namespaced by unique identifier.\n *\n * @param uniqueIdentifier - Optional namespace for multiple map instances\n * @returns Storage key string\n */\nconst getContainerKey = (uniqueIdentifier?: string) =>\n uniqueIdentifier ? `${STORAGE_ID}-${uniqueIdentifier}` : STORAGE_ID;\n\n/**\n * Retrieves the storage container from localStorage.\n * Returns empty object if parsing fails or key doesn't exist.\n *\n * @param containerKey - The storage key to retrieve\n * @returns Parsed storage container object\n */\nconst getContainer = (containerKey: string) => {\n try {\n return JSON.parse(localStorage.getItem(containerKey) ?? '{}');\n } catch {\n logger.warn(\n `Failed to parse storage container for key: ${containerKey}, returning empty container.`,\n );\n return {};\n }\n};\n\n/**\n * Persists a viewport state to localStorage.\n *\n * Saves the viewport under the given ID within a namespaced container.\n * If the container doesn't exist, creates it. If the ID already exists, overwrites it.\n *\n * @param id - Unique identifier for this viewport (typically a key combination ID)\n * @param obj - The MapViewState to persist\n * @param uniqueIdentifier - Optional namespace for multiple map instances\n *\n * @example\n * ```typescript\n * import { persist } from '@accelint/map-toolkit/deckgl/saved-viewports/storage';\n *\n * const viewport = {\n * latitude: 38.9072,\n * longitude: -77.0369,\n * zoom: 10,\n * pitch: 0,\n * bearing: 0,\n * };\n *\n * persist('Digit1', viewport);\n * persist('Digit2', viewport, 'main-map');\n * ```\n */\nexport const persist = (\n id: string,\n obj: MapViewState,\n uniqueIdentifier?: string,\n) => {\n const containerKey = getContainerKey(uniqueIdentifier);\n const container = getContainer(containerKey);\n container[id] = obj;\n localStorage.setItem(containerKey, JSON.stringify(container));\n};\n\n/**\n * Retrieves a saved viewport state from localStorage.\n *\n * Returns the viewport associated with the given ID, or undefined if not found.\n * Logs a warning if the viewport doesn't exist.\n *\n * @param id - Unique identifier for the viewport to retrieve\n * @param uniqueIdentifier - Optional namespace for multiple map instances\n * @returns The saved MapViewState or undefined if not found\n *\n * @example\n * ```typescript\n * import { retrieve } from '@accelint/map-toolkit/deckgl/saved-viewports/storage';\n *\n * const viewport = retrieve('Digit1');\n * if (viewport) {\n * console.log('Restored viewport:', viewport);\n * }\n *\n * const mainMapViewport = retrieve('Digit1', 'main-map');\n * ```\n */\nexport const retrieve = (id: string, uniqueIdentifier?: string) => {\n const containerKey = getContainerKey(uniqueIdentifier);\n const container = getContainer(containerKey);\n const obj = container[id];\n if (!obj) {\n logger.warn(`Object with id: ${id} does not exist`);\n }\n return obj;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAM,SAAS,UAAU;CACvB,SACE,QAAQ,IAAI,aAAa,gBAAgB,QAAQ,IAAI,aAAa;CACpE,OAAO;CACP,QAAQ;CACR,QAAQ;CACT,CAAC;;;;AAKF,MAAa,aAAa;;;;;;;AAQ1B,MAAM,mBAAmB,qBACvB,mBAAmB,GAAG,WAAW,GAAG,qBAAqB;;;;;;;;AAS3D,MAAM,gBAAgB,iBAAyB;AAC7C,KAAI;AACF,SAAO,KAAK,MAAM,aAAa,QAAQ,aAAa,IAAI,KAAK;SACvD;AACN,SAAO,KACL,8CAA8C,aAAa,8BAC5D;AACD,SAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8Bb,MAAa,WACX,IACA,KACA,qBACG;CACH,MAAM,eAAe,gBAAgB,iBAAiB;CACtD,MAAM,YAAY,aAAa,aAAa;AAC5C,WAAU,MAAM;AAChB,cAAa,QAAQ,cAAc,KAAK,UAAU,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;AAyB/D,MAAa,YAAY,IAAY,qBAA8B;CAGjE,MAAM,MADY,aADG,gBAAgB,iBAAiB,CACV,CACtB;AACtB,KAAI,CAAC,IACH,QAAO,KAAK,mBAAmB,GAAG,iBAAiB;AAErD,QAAO"}
1
+ {"version":3,"file":"storage.js","names":[],"sources":["../../../src/deckgl/saved-viewports/storage.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { createLoggerDomain } from '@/shared/logger';\nimport type { MapViewState } from '@deck.gl/core';\n\nconst logger = createLoggerDomain('[SavedViewports]');\n\n/**\n * Base storage key for saved viewports in localStorage.\n */\nexport const STORAGE_ID = 'deckgl-saved-viewports';\n\n/**\n * Generates a storage key, optionally namespaced by unique identifier.\n *\n * @param uniqueIdentifier - Optional namespace for multiple map instances\n * @returns Storage key string\n */\nconst getContainerKey = (uniqueIdentifier?: string) =>\n uniqueIdentifier ? `${STORAGE_ID}-${uniqueIdentifier}` : STORAGE_ID;\n\n/**\n * Retrieves the storage container from localStorage.\n * Returns empty object if parsing fails or key doesn't exist.\n *\n * @param containerKey - The storage key to retrieve\n * @returns Parsed storage container object\n */\nconst getContainer = (containerKey: string) => {\n try {\n return JSON.parse(localStorage.getItem(containerKey) ?? '{}');\n } catch (err) {\n logger\n .withError(err)\n .error(\n `Failed to parse storage container for key: ${containerKey}, returning empty container.`,\n );\n\n return {};\n }\n};\n\n/**\n * Persists a viewport state to localStorage.\n *\n * Saves the viewport under the given ID within a namespaced container.\n * If the container doesn't exist, creates it. If the ID already exists, overwrites it.\n *\n * @param id - Unique identifier for this viewport (typically a key combination ID)\n * @param obj - The MapViewState to persist\n * @param uniqueIdentifier - Optional namespace for multiple map instances\n *\n * @example\n * ```typescript\n * import { persist } from '@accelint/map-toolkit/deckgl/saved-viewports/storage';\n *\n * const viewport = {\n * latitude: 38.9072,\n * longitude: -77.0369,\n * zoom: 10,\n * pitch: 0,\n * bearing: 0,\n * };\n *\n * persist('Digit1', viewport);\n * persist('Digit2', viewport, 'main-map');\n * ```\n */\nexport const persist = (\n id: string,\n obj: MapViewState,\n uniqueIdentifier?: string,\n) => {\n const containerKey = getContainerKey(uniqueIdentifier);\n const container = getContainer(containerKey);\n container[id] = obj;\n localStorage.setItem(containerKey, JSON.stringify(container));\n};\n\n/**\n * Retrieves a saved viewport state from localStorage.\n *\n * Returns the viewport associated with the given ID, or undefined if not found.\n * Logs a warning if the viewport doesn't exist.\n *\n * @param id - Unique identifier for the viewport to retrieve\n * @param uniqueIdentifier - Optional namespace for multiple map instances\n * @returns The saved MapViewState or undefined if not found\n *\n * @example\n * ```typescript\n * import { retrieve } from '@accelint/map-toolkit/deckgl/saved-viewports/storage';\n *\n * const viewport = retrieve('Digit1');\n * if (viewport) {\n * console.log('Restored viewport:', viewport);\n * }\n *\n * const mainMapViewport = retrieve('Digit1', 'main-map');\n * ```\n */\nexport const retrieve = (id: string, uniqueIdentifier?: string) => {\n const containerKey = getContainerKey(uniqueIdentifier);\n const container = getContainer(containerKey);\n const obj = container[id];\n if (!obj) {\n logger.warn(`Object with id: ${id} does not exist`);\n }\n return obj;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAM,SAAS,mBAAmB,mBAAmB;;;;AAKrD,MAAa,aAAa;;;;;;;AAQ1B,MAAM,mBAAmB,qBACvB,mBAAmB,GAAG,WAAW,GAAG,qBAAqB;;;;;;;;AAS3D,MAAM,gBAAgB,iBAAyB;AAC7C,KAAI;AACF,SAAO,KAAK,MAAM,aAAa,QAAQ,aAAa,IAAI,KAAK;UACtD,KAAK;AACZ,SACG,UAAU,IAAI,CACd,MACC,8CAA8C,aAAa,8BAC5D;AAEH,SAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8Bb,MAAa,WACX,IACA,KACA,qBACG;CACH,MAAM,eAAe,gBAAgB,iBAAiB;CACtD,MAAM,YAAY,aAAa,aAAa;AAC5C,WAAU,MAAM;AAChB,cAAa,QAAQ,cAAc,KAAK,UAAU,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;AAyB/D,MAAa,YAAY,IAAY,qBAA8B;CAGjE,MAAM,MADY,aADG,gBAAgB,iBAAiB,CACV,CACtB;AACtB,KAAI,CAAC,IACH,QAAO,KAAK,mBAAmB,GAAG,iBAAiB;AAErD,QAAO"}
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -14,6 +14,7 @@
14
14
  'use client';
15
15
 
16
16
  import { DEFAULT_COLORS } from "../shared/constants.js";
17
+ import { PathStyleExtension } from "@deck.gl/extensions";
17
18
 
18
19
  //#region src/deckgl/shapes/display-shape-layer/constants.ts
19
20
  /**
@@ -28,16 +29,6 @@ const MAP_INTERACTION = {
28
29
  ICON_HOVER_SIZE_INCREASE: 5
29
30
  };
30
31
  /**
31
- * Selection highlight configuration.
32
- *
33
- * Controls the appearance of selected shapes, including highlight color
34
- * and icon size adjustments for Point shapes.
35
- */
36
- const SELECTION_HIGHLIGHT = {
37
- COLOR: DEFAULT_COLORS.highlight,
38
- ICON_SIZE_INCREASE: 8
39
- };
40
- /**
41
32
  * Coffin corners configuration for Point selection/hover feedback.
42
33
  *
43
34
  * Coffin corners are bracket-like corners that appear around Point shapes
@@ -62,9 +53,71 @@ const DEFAULT_DISPLAY_PROPS = {
62
53
  showLabels: "always",
63
54
  showHighlight: false,
64
55
  applyBaseOpacity: true,
65
- highlightColor: SELECTION_HIGHLIGHT.COLOR
56
+ highlightColor: DEFAULT_COLORS.highlight
57
+ };
58
+ /**
59
+ * Material settings for lighting effects on polygon shapes.
60
+ * Controls fill brightness for hover and selection overlay layers.
61
+ * Keys mirror BRIGHTNESS_FACTOR for consistency.
62
+ */
63
+ const MATERIAL_SETTINGS = {
64
+ NORMAL: {
65
+ ambient: .35,
66
+ diffuse: .6,
67
+ shininess: 32,
68
+ specularColor: [
69
+ 255,
70
+ 255,
71
+ 255
72
+ ]
73
+ },
74
+ HOVER_OR_SELECT: {
75
+ ambient: .6,
76
+ diffuse: .8,
77
+ shininess: 64,
78
+ specularColor: [
79
+ 255,
80
+ 255,
81
+ 255
82
+ ]
83
+ },
84
+ HOVER_AND_SELECT: {
85
+ ambient: .75,
86
+ diffuse: .95,
87
+ shininess: 80,
88
+ specularColor: [
89
+ 255,
90
+ 255,
91
+ 255
92
+ ]
93
+ }
94
+ };
95
+ /**
96
+ * Brightness multipliers for interaction state feedback.
97
+ * Applied via brightenColor() to line colors, curtains, and elevation indicators.
98
+ * - HOVER_OR_SELECT: shape is hovered or selected (single active state)
99
+ * - HOVER_AND_SELECT: shape is both hovered and selected simultaneously
100
+ */
101
+ const BRIGHTNESS_FACTOR = {
102
+ HOVER_OR_SELECT: 1.4,
103
+ HOVER_AND_SELECT: 1.7
66
104
  };
105
+ /**
106
+ * Opacity multiplier for interaction overlay layers (hover, select).
107
+ * Applied to the shape's fill alpha — sits between the base opacity (0.2)
108
+ * and full opacity (1.0) so the overlay reads clearly without being too solid.
109
+ */
110
+ const OVERLAY_FILL_OPACITY = .25;
111
+ /** Reusable deck.gl PathStyleExtension enabling dash patterns on GeoJsonLayer lines. */
112
+ const DASH_EXTENSION = [new PathStyleExtension({ dash: true })];
113
+ /** Readonly [r, g, b, a] tuple of DEFAULT_COLORS.highlight, pre-spread at module load for hot-path usage. */
114
+ const HIGHLIGHT_COLOR_TUPLE = [
115
+ DEFAULT_COLORS.highlight[0],
116
+ DEFAULT_COLORS.highlight[1],
117
+ DEFAULT_COLORS.highlight[2],
118
+ DEFAULT_COLORS.highlight[3] ?? 255
119
+ ];
67
120
 
68
121
  //#endregion
69
- export { COFFIN_CORNERS, DEFAULT_DISPLAY_PROPS, MAP_INTERACTION };
122
+ export { BRIGHTNESS_FACTOR, COFFIN_CORNERS, DASH_EXTENSION, DEFAULT_DISPLAY_PROPS, HIGHLIGHT_COLOR_TUPLE, MAP_INTERACTION, MATERIAL_SETTINGS, OVERLAY_FILL_OPACITY };
70
123
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","names":[],"sources":["../../../../src/deckgl/shapes/display-shape-layer/constants.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\nimport { DEFAULT_COLORS } from '../shared/constants';\n\n/**\n * Map interaction constants.\n *\n * Values derived from ngc2 for consistency with existing UI patterns.\n * Controls sizing and interaction feedback for shape rendering.\n */\nexport const MAP_INTERACTION = {\n LINE_WIDTH_MIN_PIXELS: 1, // Minimum line width in pixels\n ICON_SIZE: 38, // Size of shape icons\n ICON_HOVER_SIZE_INCREASE: 5, // Additional pixels added on hover\n} as const;\n\n/**\n * Selection highlight configuration.\n *\n * Controls the appearance of selected shapes, including highlight color\n * and icon size adjustments for Point shapes.\n */\nexport const SELECTION_HIGHLIGHT = {\n /** Uses DEFAULT_COLORS.highlight from shared constants */\n COLOR: DEFAULT_COLORS.highlight,\n ICON_SIZE_INCREASE: 8, // Additional pixels for highlight icon\n} as const;\n\n/**\n * Coffin corners configuration for Point selection/hover feedback.\n *\n * Coffin corners are bracket-like corners that appear around Point shapes\n * with icons to indicate hover and selection states. They provide visual\n * feedback without obscuring the icon itself.\n */\nexport const COFFIN_CORNERS = {\n /** Icon name for hover state (white corners with background fill) */\n HOVER_ICON: 'coffin-corners-hover',\n /** Icon name for selected state (blue corners, no fill) */\n SELECTED_ICON: 'coffin-corners-selected',\n /** Icon name for selected+hover state (blue corners with background fill) */\n SELECTED_HOVER_ICON: 'coffin-corners-selected-hover',\n /** Size of the coffin corners icon */\n SIZE: 38,\n} as const;\n\n/**\n * Default props for DisplayShapeLayer.\n *\n * Provides sensible defaults for interactive shape display with labels,\n * standard opacity handling, and minimal visual feedback. These can be\n * overridden via layer props.\n */\nexport const DEFAULT_DISPLAY_PROPS = {\n pickable: true,\n showLabels: 'always' as const,\n showHighlight: false,\n applyBaseOpacity: true,\n highlightColor: SELECTION_HIGHLIGHT.COLOR,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,kBAAkB;CAC7B,uBAAuB;CACvB,WAAW;CACX,0BAA0B;CAC3B;;;;;;;AAQD,MAAa,sBAAsB;CAEjC,OAAO,eAAe;CACtB,oBAAoB;CACrB;;;;;;;;AASD,MAAa,iBAAiB;CAE5B,YAAY;CAEZ,eAAe;CAEf,qBAAqB;CAErB,MAAM;CACP;;;;;;;;AASD,MAAa,wBAAwB;CACnC,UAAU;CACV,YAAY;CACZ,eAAe;CACf,kBAAkB;CAClB,gBAAgB,oBAAoB;CACrC"}
1
+ {"version":3,"file":"constants.js","names":["HIGHLIGHT_COLOR_TUPLE: Rgba255Tuple"],"sources":["../../../../src/deckgl/shapes/display-shape-layer/constants.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\nimport { PathStyleExtension } from '@deck.gl/extensions';\nimport { DEFAULT_COLORS } from '../shared/constants';\nimport type { Rgba255Tuple } from '@accelint/predicates';\n\n/**\n * Map interaction constants.\n *\n * Values derived from ngc2 for consistency with existing UI patterns.\n * Controls sizing and interaction feedback for shape rendering.\n */\nexport const MAP_INTERACTION = {\n LINE_WIDTH_MIN_PIXELS: 1, // Minimum line width in pixels\n ICON_SIZE: 38, // Size of shape icons\n ICON_HOVER_SIZE_INCREASE: 5, // Additional pixels added on hover\n} as const;\n\n/**\n * Coffin corners configuration for Point selection/hover feedback.\n *\n * Coffin corners are bracket-like corners that appear around Point shapes\n * with icons to indicate hover and selection states. They provide visual\n * feedback without obscuring the icon itself.\n */\nexport const COFFIN_CORNERS = {\n /** Icon name for hover state (white corners with background fill) */\n HOVER_ICON: 'coffin-corners-hover',\n /** Icon name for selected state (blue corners, no fill) */\n SELECTED_ICON: 'coffin-corners-selected',\n /** Icon name for selected+hover state (blue corners with background fill) */\n SELECTED_HOVER_ICON: 'coffin-corners-selected-hover',\n /** Size of the coffin corners icon */\n SIZE: 38,\n} as const;\n\n/**\n * Default props for DisplayShapeLayer.\n *\n * Provides sensible defaults for interactive shape display with labels,\n * standard opacity handling, and minimal visual feedback. These can be\n * overridden via layer props.\n */\nexport const DEFAULT_DISPLAY_PROPS = {\n pickable: true,\n showLabels: 'always' as const,\n showHighlight: false,\n applyBaseOpacity: true,\n highlightColor: DEFAULT_COLORS.highlight,\n};\n\n/**\n * Material settings for lighting effects on polygon shapes.\n * Controls fill brightness for hover and selection overlay layers.\n * Keys mirror BRIGHTNESS_FACTOR for consistency.\n */\nexport const MATERIAL_SETTINGS = {\n // Normal state - standard lighting\n NORMAL: {\n ambient: 0.35,\n diffuse: 0.6,\n shininess: 32,\n specularColor: [255, 255, 255] as [number, number, number],\n },\n // Hovered or selected (single active state)\n HOVER_OR_SELECT: {\n ambient: 0.6,\n diffuse: 0.8,\n shininess: 64,\n specularColor: [255, 255, 255] as [number, number, number],\n },\n // Hovered and selected simultaneously - brighter\n HOVER_AND_SELECT: {\n ambient: 0.75,\n diffuse: 0.95,\n shininess: 80,\n specularColor: [255, 255, 255] as [number, number, number],\n },\n} as const;\n\n/**\n * Brightness multipliers for interaction state feedback.\n * Applied via brightenColor() to line colors, curtains, and elevation indicators.\n * - HOVER_OR_SELECT: shape is hovered or selected (single active state)\n * - HOVER_AND_SELECT: shape is both hovered and selected simultaneously\n */\nexport const BRIGHTNESS_FACTOR = {\n HOVER_OR_SELECT: 1.4,\n HOVER_AND_SELECT: 1.7,\n} as const;\n\n/**\n * Opacity multiplier for interaction overlay layers (hover, select).\n * Applied to the shape's fill alpha — sits between the base opacity (0.2)\n * and full opacity (1.0) so the overlay reads clearly without being too solid.\n */\nexport const OVERLAY_FILL_OPACITY = 0.25;\n\n/** Reusable deck.gl PathStyleExtension enabling dash patterns on GeoJsonLayer lines. */\nexport const DASH_EXTENSION = [new PathStyleExtension({ dash: true })];\n\n/** Readonly [r, g, b, a] tuple of DEFAULT_COLORS.highlight, pre-spread at module load for hot-path usage. */\nexport const HIGHLIGHT_COLOR_TUPLE: Rgba255Tuple = [\n DEFAULT_COLORS.highlight[0],\n DEFAULT_COLORS.highlight[1],\n DEFAULT_COLORS.highlight[2],\n DEFAULT_COLORS.highlight[3] ?? 255,\n];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,kBAAkB;CAC7B,uBAAuB;CACvB,WAAW;CACX,0BAA0B;CAC3B;;;;;;;;AASD,MAAa,iBAAiB;CAE5B,YAAY;CAEZ,eAAe;CAEf,qBAAqB;CAErB,MAAM;CACP;;;;;;;;AASD,MAAa,wBAAwB;CACnC,UAAU;CACV,YAAY;CACZ,eAAe;CACf,kBAAkB;CAClB,gBAAgB,eAAe;CAChC;;;;;;AAOD,MAAa,oBAAoB;CAE/B,QAAQ;EACN,SAAS;EACT,SAAS;EACT,WAAW;EACX,eAAe;GAAC;GAAK;GAAK;GAAI;EAC/B;CAED,iBAAiB;EACf,SAAS;EACT,SAAS;EACT,WAAW;EACX,eAAe;GAAC;GAAK;GAAK;GAAI;EAC/B;CAED,kBAAkB;EAChB,SAAS;EACT,SAAS;EACT,WAAW;EACX,eAAe;GAAC;GAAK;GAAK;GAAI;EAC/B;CACF;;;;;;;AAQD,MAAa,oBAAoB;CAC/B,iBAAiB;CACjB,kBAAkB;CACnB;;;;;;AAOD,MAAa,uBAAuB;;AAGpC,MAAa,iBAAiB,CAAC,IAAI,mBAAmB,EAAE,MAAM,MAAM,CAAC,CAAC;;AAGtE,MAAaA,wBAAsC;CACjD,eAAe,UAAU;CACzB,eAAe,UAAU;CACzB,eAAe,UAAU;CACzB,eAAe,UAAU,MAAM;CAChC"}
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0