@accelint/map-toolkit 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/CHANGELOG.md +49 -24
  2. package/catalog-info.yaml +5 -7
  3. package/dist/cursor-coordinates/index.d.ts +14 -3
  4. package/dist/cursor-coordinates/index.js +16 -3
  5. package/dist/cursor-coordinates/use-cursor-coordinates.d.ts +20 -6
  6. package/dist/cursor-coordinates/use-cursor-coordinates.js +247 -128
  7. package/dist/cursor-coordinates/use-cursor-coordinates.js.map +1 -1
  8. package/dist/deckgl/base-map/constants.d.ts +14 -12
  9. package/dist/deckgl/base-map/constants.js +26 -12
  10. package/dist/deckgl/base-map/constants.js.map +1 -1
  11. package/dist/deckgl/base-map/events.d.ts +6 -4
  12. package/dist/deckgl/base-map/events.js +18 -4
  13. package/dist/deckgl/base-map/events.js.map +1 -1
  14. package/dist/deckgl/base-map/index.d.ts +45 -18
  15. package/dist/deckgl/base-map/index.js +216 -148
  16. package/dist/deckgl/base-map/index.js.map +1 -1
  17. package/dist/deckgl/base-map/provider.d.ts +48 -32
  18. package/dist/deckgl/base-map/provider.js +122 -11
  19. package/dist/deckgl/base-map/provider.js.map +1 -1
  20. package/dist/deckgl/base-map/types.d.ts +49 -39
  21. package/dist/deckgl/base-map/types.js +11 -2
  22. package/dist/deckgl/index.d.ts +18 -13
  23. package/dist/deckgl/index.js +19 -6
  24. package/dist/deckgl/symbol-layer/fiber.d.ts +21 -10
  25. package/dist/deckgl/symbol-layer/fiber.js +18 -3
  26. package/dist/deckgl/symbol-layer/fiber.js.map +1 -1
  27. package/dist/deckgl/symbol-layer/index.d.ts +68 -54
  28. package/dist/deckgl/symbol-layer/index.js +105 -85
  29. package/dist/deckgl/symbol-layer/index.js.map +1 -1
  30. package/dist/deckgl/text-layer/character-sets.d.ts +19 -17
  31. package/dist/deckgl/text-layer/character-sets.js +40 -19
  32. package/dist/deckgl/text-layer/character-sets.js.map +1 -1
  33. package/dist/deckgl/text-layer/default-settings.d.ts +16 -2
  34. package/dist/deckgl/text-layer/default-settings.js +42 -18
  35. package/dist/deckgl/text-layer/default-settings.js.map +1 -1
  36. package/dist/deckgl/text-layer/fiber.d.ts +38 -27
  37. package/dist/deckgl/text-layer/fiber.js +18 -3
  38. package/dist/deckgl/text-layer/fiber.js.map +1 -1
  39. package/dist/deckgl/text-layer/index.d.ts +39 -25
  40. package/dist/deckgl/text-layer/index.js +47 -29
  41. package/dist/deckgl/text-layer/index.js.map +1 -1
  42. package/dist/decorators/deckgl.d.ts +16 -2
  43. package/dist/decorators/deckgl.js +25 -7
  44. package/dist/decorators/deckgl.js.map +1 -1
  45. package/dist/map-cursor/events.d.ts +16 -0
  46. package/dist/map-cursor/events.js +27 -0
  47. package/dist/map-cursor/events.js.map +1 -0
  48. package/dist/map-cursor/index.d.ts +17 -0
  49. package/dist/map-cursor/index.js +18 -0
  50. package/dist/map-cursor/store.d.ts +93 -0
  51. package/dist/map-cursor/store.js +351 -0
  52. package/dist/map-cursor/store.js.map +1 -0
  53. package/dist/map-cursor/types.d.ts +81 -0
  54. package/dist/map-cursor/types.js +12 -0
  55. package/dist/map-cursor/use-map-cursor.d.ts +99 -0
  56. package/dist/map-cursor/use-map-cursor.js +116 -0
  57. package/dist/map-cursor/use-map-cursor.js.map +1 -0
  58. package/dist/map-mode/events.d.ts +11 -9
  59. package/dist/map-mode/events.js +43 -9
  60. package/dist/map-mode/events.js.map +1 -1
  61. package/dist/map-mode/index.d.ts +17 -6
  62. package/dist/map-mode/index.js +18 -5
  63. package/dist/map-mode/store.d.ts +26 -3
  64. package/dist/map-mode/store.js +329 -265
  65. package/dist/map-mode/store.js.map +1 -1
  66. package/dist/map-mode/types.d.ts +49 -35
  67. package/dist/map-mode/types.js +11 -2
  68. package/dist/map-mode/use-map-mode.d.ts +21 -7
  69. package/dist/map-mode/use-map-mode.js +66 -23
  70. package/dist/map-mode/use-map-mode.js.map +1 -1
  71. package/dist/maplibre/constants.d.ts +10 -8
  72. package/dist/maplibre/constants.js +22 -8
  73. package/dist/maplibre/constants.js.map +1 -1
  74. package/dist/maplibre/hooks/use-maplibre.d.ts +17 -2
  75. package/dist/maplibre/hooks/use-maplibre.js +77 -31
  76. package/dist/maplibre/hooks/use-maplibre.js.map +1 -1
  77. package/dist/maplibre/index.d.ts +15 -3
  78. package/dist/maplibre/index.js +17 -4
  79. package/dist/viewport/constants.d.ts +8 -6
  80. package/dist/viewport/constants.js +20 -6
  81. package/dist/viewport/constants.js.map +1 -1
  82. package/dist/viewport/index.d.ts +18 -13
  83. package/dist/viewport/index.js +19 -6
  84. package/dist/viewport/types.d.ts +27 -17
  85. package/dist/viewport/types.js +11 -2
  86. package/dist/viewport/use-viewport-state.d.ts +29 -14
  87. package/dist/viewport/use-viewport-state.js +200 -87
  88. package/dist/viewport/use-viewport-state.js.map +1 -1
  89. package/dist/viewport/utils.d.ts +25 -10
  90. package/dist/viewport/utils.js +67 -37
  91. package/dist/viewport/utils.js.map +1 -1
  92. package/dist/viewport/viewport-size.d.ts +27 -15
  93. package/dist/viewport/viewport-size.js +54 -11
  94. package/dist/viewport/viewport-size.js.map +1 -1
  95. package/package.json +107 -78
  96. package/dist/cursor-coordinates/index.js.map +0 -1
  97. package/dist/deckgl/base-map/types.js.map +0 -1
  98. package/dist/deckgl/index.js.map +0 -1
  99. package/dist/map-mode/index.js.map +0 -1
  100. package/dist/map-mode/types.js.map +0 -1
  101. package/dist/maplibre/index.js.map +0 -1
  102. package/dist/metafile-esm.json +0 -1
  103. package/dist/viewport/index.js.map +0 -1
  104. package/dist/viewport/types.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/viewport/use-viewport-state.ts"],"names":[],"mappings":"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","file":"use-viewport-state.js","sourcesContent":["/*\n * Copyright 2025 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 { Broadcast } from '@accelint/bus';\nimport { useSyncExternalStore } from 'react';\nimport { MapEvents } from '../deckgl/base-map/events';\nimport type { UniqueId } from '@accelint/core';\nimport type {\n MapEventType,\n MapViewportPayload,\n} from '../deckgl/base-map/types';\n\nconst bus = Broadcast.getInstance<MapEventType>();\n\nexport type UseViewportStateProps = {\n instanceId: UniqueId;\n subscribe?: Parameters<typeof useSyncExternalStore<MapViewportPayload>>[0];\n getSnapshot?: Parameters<typeof useSyncExternalStore<MapViewportPayload>>[1];\n getServerSnapshot?: Parameters<\n typeof useSyncExternalStore<MapViewportPayload>\n >[2];\n};\n\n/**\n * Store for viewport state keyed by instanceId\n */\nconst viewportStore = new Map<UniqueId, MapViewportPayload>();\n\n/**\n * Track React component subscribers per instanceId (for fan-out notifications).\n * Each Set contains onStoreChange callbacks from useSyncExternalStore.\n */\nconst componentSubscribers = new Map<UniqueId, Set<() => void>>();\n\n/**\n * Cache of bus unsubscribe functions (1 per instanceId).\n * This ensures we only have one bus listener per viewport, regardless of\n * how many React components subscribe to it.\n */\nconst busUnsubscribers = new Map<UniqueId, () => void>();\n\ntype Subscription = (onStoreChange: () => void) => () => void;\n/**\n * Cache of subscription functions per instanceId to avoid recreating on every render\n */\nconst subscriptionCache = new Map<UniqueId, Subscription>();\n\n/**\n * Cache of snapshot functions per instanceId to maintain referential stability\n */\nconst snapshotCache = new Map<UniqueId, () => MapViewportPayload>();\n\n/**\n * Cache of fallback snapshots per instanceId to maintain referential stability.\n * This prevents unnecessary re-renders when no viewport data exists yet.\n */\nconst fallbackCache = new Map<UniqueId, MapViewportPayload>();\n\n/**\n * Ensures a single bus listener exists for the given instanceId.\n * All React subscribers will be notified via fan-out when the bus event fires.\n * This prevents creating N bus listeners for N React components.\n *\n * @param instanceId - The unique identifier for the viewport\n */\nfunction ensureBusListener(instanceId: UniqueId): void {\n if (busUnsubscribers.has(instanceId)) {\n return; // Already listening\n }\n\n const unsub = bus.on(MapEvents.viewport, ({ payload }) => {\n if (instanceId === payload.id) {\n // Write to store once\n viewportStore.set(instanceId, payload);\n\n // Fan-out: notify all React subscribers\n const subscribers = componentSubscribers.get(instanceId);\n if (subscribers) {\n for (const onStoreChange of subscribers) {\n onStoreChange();\n }\n }\n }\n });\n\n busUnsubscribers.set(instanceId, unsub);\n}\n\n/**\n * Cleans up the bus listener if no React subscribers remain.\n *\n * @param instanceId - The unique identifier for the viewport\n */\nfunction cleanupBusListenerIfNeeded(instanceId: UniqueId): void {\n const subscribers = componentSubscribers.get(instanceId);\n\n if (!subscribers || subscribers.size === 0) {\n // No more React subscribers - clean up bus listener\n const unsub = busUnsubscribers.get(instanceId);\n if (unsub) {\n unsub();\n busUnsubscribers.delete(instanceId);\n }\n\n // Clean up all state\n viewportStore.delete(instanceId);\n componentSubscribers.delete(instanceId);\n subscriptionCache.delete(instanceId);\n snapshotCache.delete(instanceId);\n fallbackCache.delete(instanceId);\n }\n}\n\n/**\n * Creates or retrieves a cached subscription function for a given instanceId.\n * Uses a fan-out pattern: 1 bus listener -> N React subscribers.\n * Automatically cleans up viewport state when the last subscriber unsubscribes.\n *\n * @param instanceId - The unique identifier for the viewport\n * @returns A subscription function for useSyncExternalStore\n */\nfunction getOrCreateSubscription(\n instanceId: UniqueId,\n): (onStoreChange: () => void) => () => void {\n const subscription =\n subscriptionCache.get(instanceId) ??\n ((onStoreChange: () => void) => {\n // Ensure single bus listener exists for this instanceId\n ensureBusListener(instanceId);\n\n // Get or create the subscriber set for this map instance, then add this component's callback\n let subscriberSet = componentSubscribers.get(instanceId);\n if (!subscriberSet) {\n subscriberSet = new Set();\n componentSubscribers.set(instanceId, subscriberSet);\n }\n subscriberSet.add(onStoreChange);\n\n // Return cleanup function to remove this component's subscription\n return () => {\n const currentSubscriberSet = componentSubscribers.get(instanceId);\n if (currentSubscriberSet) {\n currentSubscriberSet.delete(onStoreChange);\n }\n\n // Clean up bus listener if this was the last React subscriber\n cleanupBusListenerIfNeeded(instanceId);\n };\n });\n\n subscriptionCache.set(instanceId, subscription);\n\n return subscription;\n}\n\n/**\n * Creates or retrieves a cached snapshot function for a given instanceId.\n * The object returned gets equality checked, so it needs to be stable or React re-renders unnecessarily.\n *\n * @param instanceId - The unique identifier for the viewport\n * @returns A snapshot function for useSyncExternalStore\n */\nfunction getOrCreateSnapshot(instanceId: UniqueId): () => MapViewportPayload {\n // Get or create stable fallback reference for this instanceId\n const fallback =\n fallbackCache.get(instanceId) ??\n (() => {\n const newFallback: MapViewportPayload = {\n id: instanceId,\n bounds: [Number.NaN, Number.NaN, Number.NaN, Number.NaN],\n latitude: Number.NaN,\n longitude: Number.NaN,\n zoom: Number.NaN,\n width: 0,\n height: 0,\n };\n fallbackCache.set(instanceId, newFallback);\n return newFallback;\n })();\n\n const snapshot =\n snapshotCache.get(instanceId) ??\n (() => viewportStore.get(instanceId) ?? fallback);\n\n snapshotCache.set(instanceId, snapshot);\n\n return snapshot;\n}\n\n/**\n * Hook to subscribe to viewport state changes for a specific view.\n *\n * By default, subscribes to MapEvents.viewport events from the event bus and\n * automatically cleans up when all subscribers unmount. For advanced use cases,\n * custom subscribe/getSnapshot functions can be provided.\n *\n * A thin wrapper around [useSyncExternalStore](https://react.dev/reference/react/useSyncExternalStore).\n *\n * @param instanceId - Unique identifier for the viewport to track\n * @param subscribe - Optional custom subscription function\n * @param getSnapshot - Optional custom snapshot getter\n * @param getServerSnapshot - Optional server-side snapshot getter\n * @returns Current viewport state including bounds, latitude, longitude, zoom\n *\n * @example\n * ```tsx\n * function MapInfo({ instanceId }) {\n * const { bounds, latitude, longitude, zoom } = useViewportState({\n * instanceId\n * });\n *\n * return (\n * <div>\n * Lat: {latitude?.toFixed(2)}, Lon: {longitude?.toFixed(2)}, Zoom: {zoom}\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With custom subscribe/getSnapshot for advanced use cases\n * function CustomMapInfo() {\n * const customSubscribe = (onStoreChange) => {\n * // Custom subscription logic\n * return () => { // cleanup }\n * }\n *\n * const customGetSnapshot = () => {\n * // Custom snapshot logic\n * return { latitude: 0, longitude: 0, zoom: 1 };\n * };\n *\n * const viewState = useViewportState({\n * instanceId: 'some-uuid',\n * subscribe: customSubscribe,\n * getSnapshot: customGetSnapshot,\n * });\n *\n * return <div>Custom viewport state</div>;\n * }\n * ```\n */\nexport function useViewportState({\n instanceId,\n subscribe,\n getSnapshot,\n getServerSnapshot,\n}: UseViewportStateProps) {\n return useSyncExternalStore<MapViewportPayload>(\n subscribe ?? getOrCreateSubscription(instanceId),\n getSnapshot ?? getOrCreateSnapshot(instanceId),\n getServerSnapshot,\n );\n}\n\n/**\n * Manually clear viewport state for a specific instanceId.\n * This is typically not needed as cleanup happens automatically when all subscribers unmount.\n * Use this only in advanced scenarios where manual cleanup is required.\n *\n * @param instanceId - The unique identifier for the viewport to clear\n *\n * @example\n * ```tsx\n * // Manual cleanup (rarely needed)\n * clearViewportState('my-map-instance');\n * ```\n */\nexport function clearViewportState(instanceId: UniqueId): void {\n // Unsubscribe from bus if listening\n const unsub = busUnsubscribers.get(instanceId);\n if (unsub) {\n unsub();\n busUnsubscribers.delete(instanceId);\n }\n\n // Clear all state\n viewportStore.delete(instanceId);\n componentSubscribers.delete(instanceId);\n subscriptionCache.delete(instanceId);\n snapshotCache.delete(instanceId);\n fallbackCache.delete(instanceId);\n}\n"]}
1
+ {"version":3,"file":"use-viewport-state.js","names":["newFallback: MapViewportPayload"],"sources":["../../src/viewport/use-viewport-state.ts"],"sourcesContent":["/*\n * Copyright 2025 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 { Broadcast } from '@accelint/bus';\nimport { useSyncExternalStore } from 'react';\nimport { MapEvents } from '../deckgl/base-map/events';\nimport type { UniqueId } from '@accelint/core';\nimport type {\n MapEventType,\n MapViewportPayload,\n} from '../deckgl/base-map/types';\n\nconst bus = Broadcast.getInstance<MapEventType>();\n\nexport type UseViewportStateProps = {\n instanceId: UniqueId;\n subscribe?: Parameters<typeof useSyncExternalStore<MapViewportPayload>>[0];\n getSnapshot?: Parameters<typeof useSyncExternalStore<MapViewportPayload>>[1];\n getServerSnapshot?: Parameters<\n typeof useSyncExternalStore<MapViewportPayload>\n >[2];\n};\n\n/**\n * Store for viewport state keyed by instanceId\n */\nconst viewportStore = new Map<UniqueId, MapViewportPayload>();\n\n/**\n * Track React component subscribers per instanceId (for fan-out notifications).\n * Each Set contains onStoreChange callbacks from useSyncExternalStore.\n */\nconst componentSubscribers = new Map<UniqueId, Set<() => void>>();\n\n/**\n * Cache of bus unsubscribe functions (1 per instanceId).\n * This ensures we only have one bus listener per viewport, regardless of\n * how many React components subscribe to it.\n */\nconst busUnsubscribers = new Map<UniqueId, () => void>();\n\ntype Subscription = (onStoreChange: () => void) => () => void;\n/**\n * Cache of subscription functions per instanceId to avoid recreating on every render\n */\nconst subscriptionCache = new Map<UniqueId, Subscription>();\n\n/**\n * Cache of snapshot functions per instanceId to maintain referential stability\n */\nconst snapshotCache = new Map<UniqueId, () => MapViewportPayload>();\n\n/**\n * Cache of fallback snapshots per instanceId to maintain referential stability.\n * This prevents unnecessary re-renders when no viewport data exists yet.\n */\nconst fallbackCache = new Map<UniqueId, MapViewportPayload>();\n\n/**\n * Ensures a single bus listener exists for the given instanceId.\n * All React subscribers will be notified via fan-out when the bus event fires.\n * This prevents creating N bus listeners for N React components.\n *\n * @param instanceId - The unique identifier for the viewport\n */\nfunction ensureBusListener(instanceId: UniqueId): void {\n if (busUnsubscribers.has(instanceId)) {\n return; // Already listening\n }\n\n const unsub = bus.on(MapEvents.viewport, ({ payload }) => {\n if (instanceId === payload.id) {\n // Write to store once\n viewportStore.set(instanceId, payload);\n\n // Fan-out: notify all React subscribers\n const subscribers = componentSubscribers.get(instanceId);\n if (subscribers) {\n for (const onStoreChange of subscribers) {\n onStoreChange();\n }\n }\n }\n });\n\n busUnsubscribers.set(instanceId, unsub);\n}\n\n/**\n * Cleans up the bus listener if no React subscribers remain.\n *\n * @param instanceId - The unique identifier for the viewport\n */\nfunction cleanupBusListenerIfNeeded(instanceId: UniqueId): void {\n const subscribers = componentSubscribers.get(instanceId);\n\n if (!subscribers || subscribers.size === 0) {\n // No more React subscribers - clean up bus listener\n const unsub = busUnsubscribers.get(instanceId);\n if (unsub) {\n unsub();\n busUnsubscribers.delete(instanceId);\n }\n\n // Clean up all state\n viewportStore.delete(instanceId);\n componentSubscribers.delete(instanceId);\n subscriptionCache.delete(instanceId);\n snapshotCache.delete(instanceId);\n fallbackCache.delete(instanceId);\n }\n}\n\n/**\n * Creates or retrieves a cached subscription function for a given instanceId.\n * Uses a fan-out pattern: 1 bus listener -> N React subscribers.\n * Automatically cleans up viewport state when the last subscriber unsubscribes.\n *\n * @param instanceId - The unique identifier for the viewport\n * @returns A subscription function for useSyncExternalStore\n */\nfunction getOrCreateSubscription(\n instanceId: UniqueId,\n): (onStoreChange: () => void) => () => void {\n const subscription =\n subscriptionCache.get(instanceId) ??\n ((onStoreChange: () => void) => {\n // Ensure single bus listener exists for this instanceId\n ensureBusListener(instanceId);\n\n // Get or create the subscriber set for this map instance, then add this component's callback\n let subscriberSet = componentSubscribers.get(instanceId);\n if (!subscriberSet) {\n subscriberSet = new Set();\n componentSubscribers.set(instanceId, subscriberSet);\n }\n subscriberSet.add(onStoreChange);\n\n // Return cleanup function to remove this component's subscription\n return () => {\n const currentSubscriberSet = componentSubscribers.get(instanceId);\n if (currentSubscriberSet) {\n currentSubscriberSet.delete(onStoreChange);\n }\n\n // Clean up bus listener if this was the last React subscriber\n cleanupBusListenerIfNeeded(instanceId);\n };\n });\n\n subscriptionCache.set(instanceId, subscription);\n\n return subscription;\n}\n\n/**\n * Creates or retrieves a cached snapshot function for a given instanceId.\n * The object returned gets equality checked, so it needs to be stable or React re-renders unnecessarily.\n *\n * @param instanceId - The unique identifier for the viewport\n * @returns A snapshot function for useSyncExternalStore\n */\nfunction getOrCreateSnapshot(instanceId: UniqueId): () => MapViewportPayload {\n // Get or create stable fallback reference for this instanceId\n const fallback =\n fallbackCache.get(instanceId) ??\n (() => {\n const newFallback: MapViewportPayload = {\n id: instanceId,\n bounds: undefined,\n latitude: Number.NaN,\n longitude: Number.NaN,\n zoom: Number.NaN,\n width: 0,\n height: 0,\n };\n fallbackCache.set(instanceId, newFallback);\n return newFallback;\n })();\n\n const snapshot =\n snapshotCache.get(instanceId) ??\n (() => viewportStore.get(instanceId) ?? fallback);\n\n snapshotCache.set(instanceId, snapshot);\n\n return snapshot;\n}\n\n/**\n * Hook to subscribe to viewport state changes for a specific view.\n *\n * By default, subscribes to MapEvents.viewport events from the event bus and\n * automatically cleans up when all subscribers unmount. For advanced use cases,\n * custom subscribe/getSnapshot functions can be provided.\n *\n * A thin wrapper around [useSyncExternalStore](https://react.dev/reference/react/useSyncExternalStore).\n *\n * @param instanceId - Unique identifier for the viewport to track\n * @param subscribe - Optional custom subscription function\n * @param getSnapshot - Optional custom snapshot getter\n * @param getServerSnapshot - Optional server-side snapshot getter\n * @returns Current viewport state including bounds, latitude, longitude, zoom\n *\n * @example\n * ```tsx\n * function MapInfo({ instanceId }) {\n * const { bounds, latitude, longitude, zoom } = useViewportState({\n * instanceId\n * });\n *\n * return (\n * <div>\n * Lat: {latitude?.toFixed(2)}, Lon: {longitude?.toFixed(2)}, Zoom: {zoom}\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With custom subscribe/getSnapshot for advanced use cases\n * function CustomMapInfo() {\n * const customSubscribe = (onStoreChange) => {\n * // Custom subscription logic\n * return () => { // cleanup }\n * }\n *\n * const customGetSnapshot = () => {\n * // Custom snapshot logic\n * return { latitude: 0, longitude: 0, zoom: 1 };\n * };\n *\n * const viewState = useViewportState({\n * instanceId: 'some-uuid',\n * subscribe: customSubscribe,\n * getSnapshot: customGetSnapshot,\n * });\n *\n * return <div>Custom viewport state</div>;\n * }\n * ```\n */\nexport function useViewportState({\n instanceId,\n subscribe,\n getSnapshot,\n getServerSnapshot,\n}: UseViewportStateProps) {\n return useSyncExternalStore<MapViewportPayload>(\n subscribe ?? getOrCreateSubscription(instanceId),\n getSnapshot ?? getOrCreateSnapshot(instanceId),\n getServerSnapshot,\n );\n}\n\n/**\n * Manually clear viewport state for a specific instanceId.\n * This is typically not needed as cleanup happens automatically when all subscribers unmount.\n * Use this only in advanced scenarios where manual cleanup is required.\n *\n * @param instanceId - The unique identifier for the viewport to clear\n *\n * @example\n * ```tsx\n * // Manual cleanup (rarely needed)\n * clearViewportState('my-map-instance');\n * ```\n */\nexport function clearViewportState(instanceId: UniqueId): void {\n // Unsubscribe from bus if listening\n const unsub = busUnsubscribers.get(instanceId);\n if (unsub) {\n unsub();\n busUnsubscribers.delete(instanceId);\n }\n\n // Clear all state\n viewportStore.delete(instanceId);\n componentSubscribers.delete(instanceId);\n subscriptionCache.delete(instanceId);\n snapshotCache.delete(instanceId);\n fallbackCache.delete(instanceId);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,MAAM,MAAM,UAAU,aAA2B;;;;AAcjD,MAAM,gCAAgB,IAAI,KAAmC;;;;;AAM7D,MAAM,uCAAuB,IAAI,KAAgC;;;;;;AAOjE,MAAM,mCAAmB,IAAI,KAA2B;;;;AAMxD,MAAM,oCAAoB,IAAI,KAA6B;;;;AAK3D,MAAM,gCAAgB,IAAI,KAAyC;;;;;AAMnE,MAAM,gCAAgB,IAAI,KAAmC;;;;;;;;AAS7D,SAAS,kBAAkB,YAA4B;AACrD,KAAI,iBAAiB,IAAI,WAAW,CAClC;CAGF,MAAM,QAAQ,IAAI,GAAG,UAAU,WAAW,EAAE,cAAc;AACxD,MAAI,eAAe,QAAQ,IAAI;AAE7B,iBAAc,IAAI,YAAY,QAAQ;GAGtC,MAAM,cAAc,qBAAqB,IAAI,WAAW;AACxD,OAAI,YACF,MAAK,MAAM,iBAAiB,YAC1B,gBAAe;;GAIrB;AAEF,kBAAiB,IAAI,YAAY,MAAM;;;;;;;AAQzC,SAAS,2BAA2B,YAA4B;CAC9D,MAAM,cAAc,qBAAqB,IAAI,WAAW;AAExD,KAAI,CAAC,eAAe,YAAY,SAAS,GAAG;EAE1C,MAAM,QAAQ,iBAAiB,IAAI,WAAW;AAC9C,MAAI,OAAO;AACT,UAAO;AACP,oBAAiB,OAAO,WAAW;;AAIrC,gBAAc,OAAO,WAAW;AAChC,uBAAqB,OAAO,WAAW;AACvC,oBAAkB,OAAO,WAAW;AACpC,gBAAc,OAAO,WAAW;AAChC,gBAAc,OAAO,WAAW;;;;;;;;;;;AAYpC,SAAS,wBACP,YAC2C;CAC3C,MAAM,eACJ,kBAAkB,IAAI,WAAW,MAC/B,kBAA8B;AAE9B,oBAAkB,WAAW;EAG7B,IAAI,gBAAgB,qBAAqB,IAAI,WAAW;AACxD,MAAI,CAAC,eAAe;AAClB,mCAAgB,IAAI,KAAK;AACzB,wBAAqB,IAAI,YAAY,cAAc;;AAErD,gBAAc,IAAI,cAAc;AAGhC,eAAa;GACX,MAAM,uBAAuB,qBAAqB,IAAI,WAAW;AACjE,OAAI,qBACF,sBAAqB,OAAO,cAAc;AAI5C,8BAA2B,WAAW;;;AAI5C,mBAAkB,IAAI,YAAY,aAAa;AAE/C,QAAO;;;;;;;;;AAUT,SAAS,oBAAoB,YAAgD;CAE3E,MAAM,WACJ,cAAc,IAAI,WAAW,WACtB;EACL,MAAMA,cAAkC;GACtC,IAAI;GACJ,QAAQ;GACR,UAAU;GACV,WAAW;GACX,MAAM;GACN,OAAO;GACP,QAAQ;GACT;AACD,gBAAc,IAAI,YAAY,YAAY;AAC1C,SAAO;KACL;CAEN,MAAM,WACJ,cAAc,IAAI,WAAW,WACtB,cAAc,IAAI,WAAW,IAAI;AAE1C,eAAc,IAAI,YAAY,SAAS;AAEvC,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDT,SAAgB,iBAAiB,EAC/B,YACA,WACA,aACA,qBACwB;AACxB,QAAO,qBACL,aAAa,wBAAwB,WAAW,EAChD,eAAe,oBAAoB,WAAW,EAC9C,kBACD;;;;;;;;;;;;;;;AAgBH,SAAgB,mBAAmB,YAA4B;CAE7D,MAAM,QAAQ,iBAAiB,IAAI,WAAW;AAC9C,KAAI,OAAO;AACT,SAAO;AACP,mBAAiB,OAAO,WAAW;;AAIrC,eAAc,OAAO,WAAW;AAChC,sBAAqB,OAAO,WAAW;AACvC,mBAAkB,OAAO,WAAW;AACpC,eAAc,OAAO,WAAW;AAChC,eAAc,OAAO,WAAW"}
@@ -1,11 +1,18 @@
1
- import { GetViewportSizeArgs } from './types.js';
2
- import '../deckgl/base-map/types.js';
3
- import '@accelint/bus';
4
- import '@accelint/core';
5
- import '@deck.gl/core';
6
- import 'mjolnir.js';
7
- import '../deckgl/base-map/events.js';
8
- import './constants.js';
1
+ /*
2
+ * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at https://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { GetViewportSizeArgs } from "./types.js";
14
+
15
+ //#region src/viewport/utils.d.ts
9
16
 
10
17
  /**
11
18
  * Returns a formatted viewport size string i.e. `660 x 1,801 NM`
@@ -32,6 +39,14 @@ import './constants.js';
32
39
  * // returns "2,050 x 1,538 KM"
33
40
  * ```
34
41
  */
35
- declare function getViewportSize({ bounds, zoom, width: pixelWidth, height: pixelHeight, unit, formatter, }: GetViewportSizeArgs): string;
36
-
42
+ declare function getViewportSize({
43
+ bounds,
44
+ zoom,
45
+ width: pixelWidth,
46
+ height: pixelHeight,
47
+ unit,
48
+ formatter
49
+ }: GetViewportSizeArgs): string;
50
+ //#endregion
37
51
  export { getViewportSize };
52
+ //# sourceMappingURL=utils.d.ts.map
@@ -1,46 +1,76 @@
1
- import { UNIT_MAP } from './constants.js';
1
+ /*
2
+ * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at https://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
2
12
 
13
+
14
+ import { UNIT_MAP } from "./constants.js";
15
+
16
+ //#region src/viewport/utils.ts
3
17
  const numberFormatter = Intl.NumberFormat("en-US");
18
+ /**
19
+ * Web Mercator constant: meters per pixel at zoom 0, equator.
20
+ * This is Earth's circumference (40075016.686m) divided by 256 (tile size).
21
+ */
4
22
  const METERS_PER_PIXEL_AT_ZOOM_0 = 156543.03392;
23
+ /**
24
+ * Unit conversion factors from meters.
25
+ */
5
26
  const METERS_TO_UNIT = {
6
- kilometers: 1e-3,
7
- meters: 1,
8
- nauticalmiles: 539957e-9,
9
- miles: 621371e-9,
10
- feet: 3.28084
27
+ kilometers: .001,
28
+ meters: 1,
29
+ nauticalmiles: 539957e-9,
30
+ miles: 621371e-9,
31
+ feet: 3.28084
11
32
  };
12
- function getViewportSize({
13
- bounds,
14
- zoom,
15
- width: pixelWidth,
16
- height: pixelHeight,
17
- unit = "nm",
18
- formatter = numberFormatter
19
- }) {
20
- const defaultValue = `-- x -- ${unit.toUpperCase()}`;
21
- if (bounds.every((b) => Number.isNaN(b))) {
22
- return defaultValue;
23
- }
24
- if (Number.isNaN(zoom) || pixelWidth === 0 || pixelHeight === 0) {
25
- return defaultValue;
26
- }
27
- const [, minLat, , maxLat] = bounds;
28
- if (minLat < -90 || minLat > 90 || maxLat < -90 || maxLat > 90) {
29
- return defaultValue;
30
- }
31
- const centerLat = (minLat + maxLat) / 2;
32
- const metersPerPixel = METERS_PER_PIXEL_AT_ZOOM_0 * Math.cos(centerLat * Math.PI / 180) / 2 ** zoom;
33
- const widthMeters = pixelWidth * metersPerPixel;
34
- const heightMeters = pixelHeight * metersPerPixel;
35
- const unitKey = UNIT_MAP[unit];
36
- const conversionFactor = METERS_TO_UNIT[unitKey];
37
- const widthDistance = Math.round(widthMeters * conversionFactor);
38
- const heightDistance = Math.round(heightMeters * conversionFactor);
39
- const width = formatter.format(widthDistance);
40
- const height = formatter.format(heightDistance);
41
- return `${width} x ${height} ${unit.toUpperCase()}`;
33
+ /**
34
+ * Returns a formatted viewport size string i.e. `660 x 1,801 NM`
35
+ *
36
+ * Calculates the geographic distance of the viewport using zoom level and
37
+ * pixel dimensions with the Web Mercator projection formula. This approach
38
+ * provides stable results without the edge cases of bounds-based calculations.
39
+ *
40
+ * @param args - Viewport size calculation arguments
41
+ * @param args.bounds - Geographic bounds [minLon, minLat, maxLon, maxLat]
42
+ * @param args.zoom - Zoom level for meters-per-pixel calculation
43
+ * @param args.width - Viewport width in pixels
44
+ * @param args.height - Viewport height in pixels
45
+ * @param args.unit - Unit of distance measurement: `km | m | nm | mi | ft`. Defaults to `nm`
46
+ * @param args.formatter - Number formatter for localization (defaults to en-US)
47
+ * @returns Formatted string like "660 x 1,801 NM" or "-- x -- NM" if invalid
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * getViewportSize({ bounds: [-82, 22, -71, 52], zoom: 5, width: 800, height: 600, unit: 'nm' })
52
+ * // returns "612 x 459 NM"
53
+ *
54
+ * getViewportSize({ bounds: [170, 50, -170, 60], zoom: 4, width: 1024, height: 768, unit: 'km' })
55
+ * // returns "2,050 x 1,538 KM"
56
+ * ```
57
+ */
58
+ function getViewportSize({ bounds, zoom, width: pixelWidth, height: pixelHeight, unit = "nm", formatter = numberFormatter }) {
59
+ const defaultValue = `-- x -- ${unit.toUpperCase()}`;
60
+ if (!bounds || bounds.every((b) => Number.isNaN(b))) return defaultValue;
61
+ if (Number.isNaN(zoom) || pixelWidth === 0 || pixelHeight === 0) return defaultValue;
62
+ const [, minLat, , maxLat] = bounds;
63
+ if (minLat < -90 || minLat > 90 || maxLat < -90 || maxLat > 90) return defaultValue;
64
+ const centerLat = (minLat + maxLat) / 2;
65
+ const metersPerPixel = METERS_PER_PIXEL_AT_ZOOM_0 * Math.cos(centerLat * Math.PI / 180) / 2 ** zoom;
66
+ const widthMeters = pixelWidth * metersPerPixel;
67
+ const heightMeters = pixelHeight * metersPerPixel;
68
+ const conversionFactor = METERS_TO_UNIT[UNIT_MAP[unit]];
69
+ const widthDistance = Math.round(widthMeters * conversionFactor);
70
+ const heightDistance = Math.round(heightMeters * conversionFactor);
71
+ return `${formatter.format(widthDistance)} x ${formatter.format(heightDistance)} ${unit.toUpperCase()}`;
42
72
  }
43
73
 
74
+ //#endregion
44
75
  export { getViewportSize };
45
- //# sourceMappingURL=utils.js.map
46
76
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/viewport/utils.ts"],"names":[],"mappings":";;AAeA,MAAM,eAAA,GAAkB,IAAA,CAAK,YAAA,CAAa,OAAO,CAAA;AAMjD,MAAM,0BAAA,GAA6B,YAAA;AAKnC,MAAM,cAAA,GAAiB;AAAA,EACrB,UAAA,EAAY,IAAA;AAAA,EACZ,MAAA,EAAQ,CAAA;AAAA,EACR,aAAA,EAAe,SAAA;AAAA,EACf,KAAA,EAAO,SAAA;AAAA,EACP,IAAA,EAAM;AACR,CAAA;AA2BO,SAAS,eAAA,CAAgB;AAAA,EAC9B,MAAA;AAAA,EACA,IAAA;AAAA,EACA,KAAA,EAAO,UAAA;AAAA,EACP,MAAA,EAAQ,WAAA;AAAA,EACR,IAAA,GAAO,IAAA;AAAA,EACP,SAAA,GAAY;AACd,CAAA,EAAwB;AACtB,EAAA,MAAM,YAAA,GAAe,CAAA,QAAA,EAAW,IAAA,CAAK,WAAA,EAAa,CAAA,CAAA;AAGlD,EAAA,IAAI,MAAA,CAAO,MAAM,CAAC,CAAA,KAAM,OAAO,KAAA,CAAM,CAAC,CAAC,CAAA,EAAG;AACxC,IAAA,OAAO,YAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,KAAA,CAAM,IAAI,KAAK,UAAA,KAAe,CAAA,IAAK,gBAAgB,CAAA,EAAG;AAC/D,IAAA,OAAO,YAAA;AAAA,EACT;AAEA,EAAA,MAAM,GAAG,MAAA,IAAU,MAAM,CAAA,GAAI,MAAA;AAG7B,EAAA,IAAI,SAAS,GAAA,IAAO,MAAA,GAAS,MAAM,MAAA,GAAS,GAAA,IAAO,SAAS,EAAA,EAAI;AAC9D,IAAA,OAAO,YAAA;AAAA,EACT;AAGA,EAAA,MAAM,SAAA,GAAA,CAAa,SAAS,MAAA,IAAU,CAAA;AAItC,EAAA,MAAM,cAAA,GACH,6BAA6B,IAAA,CAAK,GAAA,CAAK,YAAY,IAAA,CAAK,EAAA,GAAM,GAAG,CAAA,GAClE,CAAA,IAAK,IAAA;AAGP,EAAA,MAAM,cAAc,UAAA,GAAa,cAAA;AACjC,EAAA,MAAM,eAAe,WAAA,GAAc,cAAA;AAGnC,EAAA,MAAM,OAAA,GAAU,SAAS,IAAI,CAAA;AAC7B,EAAA,MAAM,gBAAA,GAAmB,eAAe,OAAO,CAAA;AAE/C,EAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,KAAA,CAAM,WAAA,GAAc,gBAAgB,CAAA;AAC/D,EAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,KAAA,CAAM,YAAA,GAAe,gBAAgB,CAAA;AAEjE,EAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,MAAA,CAAO,aAAa,CAAA;AAC5C,EAAA,MAAM,MAAA,GAAS,SAAA,CAAU,MAAA,CAAO,cAAc,CAAA;AAE9C,EAAA,OAAO,GAAG,KAAK,CAAA,GAAA,EAAM,MAAM,CAAA,CAAA,EAAI,IAAA,CAAK,aAAa,CAAA,CAAA;AACnD","file":"utils.js","sourcesContent":["/*\n * Copyright 2025 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 { UNIT_MAP } from './constants';\nimport type { GetViewportSizeArgs } from './types';\n\nconst numberFormatter = Intl.NumberFormat('en-US');\n\n/**\n * Web Mercator constant: meters per pixel at zoom 0, equator.\n * This is Earth's circumference (40075016.686m) divided by 256 (tile size).\n */\nconst METERS_PER_PIXEL_AT_ZOOM_0 = 156543.03392;\n\n/**\n * Unit conversion factors from meters.\n */\nconst METERS_TO_UNIT = {\n kilometers: 0.001,\n meters: 1,\n nauticalmiles: 0.000539957,\n miles: 0.000621371,\n feet: 3.28084,\n} as const;\n\n/**\n * Returns a formatted viewport size string i.e. `660 x 1,801 NM`\n *\n * Calculates the geographic distance of the viewport using zoom level and\n * pixel dimensions with the Web Mercator projection formula. This approach\n * provides stable results without the edge cases of bounds-based calculations.\n *\n * @param args - Viewport size calculation arguments\n * @param args.bounds - Geographic bounds [minLon, minLat, maxLon, maxLat]\n * @param args.zoom - Zoom level for meters-per-pixel calculation\n * @param args.width - Viewport width in pixels\n * @param args.height - Viewport height in pixels\n * @param args.unit - Unit of distance measurement: `km | m | nm | mi | ft`. Defaults to `nm`\n * @param args.formatter - Number formatter for localization (defaults to en-US)\n * @returns Formatted string like \"660 x 1,801 NM\" or \"-- x -- NM\" if invalid\n *\n * @example\n * ```typescript\n * getViewportSize({ bounds: [-82, 22, -71, 52], zoom: 5, width: 800, height: 600, unit: 'nm' })\n * // returns \"612 x 459 NM\"\n *\n * getViewportSize({ bounds: [170, 50, -170, 60], zoom: 4, width: 1024, height: 768, unit: 'km' })\n * // returns \"2,050 x 1,538 KM\"\n * ```\n */\nexport function getViewportSize({\n bounds,\n zoom,\n width: pixelWidth,\n height: pixelHeight,\n unit = 'nm',\n formatter = numberFormatter,\n}: GetViewportSizeArgs) {\n const defaultValue = `-- x -- ${unit.toUpperCase()}`;\n\n // Validate inputs\n if (bounds.every((b) => Number.isNaN(b))) {\n return defaultValue;\n }\n\n if (Number.isNaN(zoom) || pixelWidth === 0 || pixelHeight === 0) {\n return defaultValue;\n }\n\n const [, minLat, , maxLat] = bounds;\n\n // Validate latitude bounds are within valid geographic ranges\n if (minLat < -90 || minLat > 90 || maxLat < -90 || maxLat > 90) {\n return defaultValue;\n }\n\n // Calculate center latitude for the viewport\n const centerLat = (minLat + maxLat) / 2;\n\n // Web Mercator formula: meters per pixel at given zoom and latitude\n // Resolution = 156543.03392 * cos(latitude * π/180) / 2^zoom\n const metersPerPixel =\n (METERS_PER_PIXEL_AT_ZOOM_0 * Math.cos((centerLat * Math.PI) / 180)) /\n 2 ** zoom;\n\n // Calculate distances in meters\n const widthMeters = pixelWidth * metersPerPixel;\n const heightMeters = pixelHeight * metersPerPixel;\n\n // Convert to requested unit\n const unitKey = UNIT_MAP[unit] as keyof typeof METERS_TO_UNIT;\n const conversionFactor = METERS_TO_UNIT[unitKey];\n\n const widthDistance = Math.round(widthMeters * conversionFactor);\n const heightDistance = Math.round(heightMeters * conversionFactor);\n\n const width = formatter.format(widthDistance);\n const height = formatter.format(heightDistance);\n\n return `${width} x ${height} ${unit.toUpperCase()}`;\n}\n"]}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../src/viewport/utils.ts"],"sourcesContent":["/*\n * Copyright 2025 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 { UNIT_MAP } from './constants';\nimport type { GetViewportSizeArgs } from './types';\n\nconst numberFormatter = Intl.NumberFormat('en-US');\n\n/**\n * Web Mercator constant: meters per pixel at zoom 0, equator.\n * This is Earth's circumference (40075016.686m) divided by 256 (tile size).\n */\nconst METERS_PER_PIXEL_AT_ZOOM_0 = 156543.03392;\n\n/**\n * Unit conversion factors from meters.\n */\nconst METERS_TO_UNIT = {\n kilometers: 0.001,\n meters: 1,\n nauticalmiles: 0.000539957,\n miles: 0.000621371,\n feet: 3.28084,\n} as const;\n\n/**\n * Returns a formatted viewport size string i.e. `660 x 1,801 NM`\n *\n * Calculates the geographic distance of the viewport using zoom level and\n * pixel dimensions with the Web Mercator projection formula. This approach\n * provides stable results without the edge cases of bounds-based calculations.\n *\n * @param args - Viewport size calculation arguments\n * @param args.bounds - Geographic bounds [minLon, minLat, maxLon, maxLat]\n * @param args.zoom - Zoom level for meters-per-pixel calculation\n * @param args.width - Viewport width in pixels\n * @param args.height - Viewport height in pixels\n * @param args.unit - Unit of distance measurement: `km | m | nm | mi | ft`. Defaults to `nm`\n * @param args.formatter - Number formatter for localization (defaults to en-US)\n * @returns Formatted string like \"660 x 1,801 NM\" or \"-- x -- NM\" if invalid\n *\n * @example\n * ```typescript\n * getViewportSize({ bounds: [-82, 22, -71, 52], zoom: 5, width: 800, height: 600, unit: 'nm' })\n * // returns \"612 x 459 NM\"\n *\n * getViewportSize({ bounds: [170, 50, -170, 60], zoom: 4, width: 1024, height: 768, unit: 'km' })\n * // returns \"2,050 x 1,538 KM\"\n * ```\n */\nexport function getViewportSize({\n bounds,\n zoom,\n width: pixelWidth,\n height: pixelHeight,\n unit = 'nm',\n formatter = numberFormatter,\n}: GetViewportSizeArgs) {\n const defaultValue = `-- x -- ${unit.toUpperCase()}`;\n\n // Validate inputs\n if (!bounds || bounds.every((b) => Number.isNaN(b))) {\n return defaultValue;\n }\n\n if (Number.isNaN(zoom) || pixelWidth === 0 || pixelHeight === 0) {\n return defaultValue;\n }\n\n const [, minLat, , maxLat] = bounds;\n\n // Validate latitude bounds are within valid geographic ranges\n if (minLat < -90 || minLat > 90 || maxLat < -90 || maxLat > 90) {\n return defaultValue;\n }\n\n // Calculate center latitude for the viewport\n const centerLat = (minLat + maxLat) / 2;\n\n // Web Mercator formula: meters per pixel at given zoom and latitude\n // Resolution = 156543.03392 * cos(latitude * π/180) / 2^zoom\n const metersPerPixel =\n (METERS_PER_PIXEL_AT_ZOOM_0 * Math.cos((centerLat * Math.PI) / 180)) /\n 2 ** zoom;\n\n // Calculate distances in meters\n const widthMeters = pixelWidth * metersPerPixel;\n const heightMeters = pixelHeight * metersPerPixel;\n\n // Convert to requested unit\n const unitKey = UNIT_MAP[unit] as keyof typeof METERS_TO_UNIT;\n const conversionFactor = METERS_TO_UNIT[unitKey];\n\n const widthDistance = Math.round(widthMeters * conversionFactor);\n const heightDistance = Math.round(heightMeters * conversionFactor);\n\n const width = formatter.format(widthDistance);\n const height = formatter.format(heightDistance);\n\n return `${width} x ${height} ${unit.toUpperCase()}`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAM,kBAAkB,KAAK,aAAa,QAAQ;;;;;AAMlD,MAAM,6BAA6B;;;;AAKnC,MAAM,iBAAiB;CACrB,YAAY;CACZ,QAAQ;CACR,eAAe;CACf,OAAO;CACP,MAAM;CACP;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BD,SAAgB,gBAAgB,EAC9B,QACA,MACA,OAAO,YACP,QAAQ,aACR,OAAO,MACP,YAAY,mBACU;CACtB,MAAM,eAAe,WAAW,KAAK,aAAa;AAGlD,KAAI,CAAC,UAAU,OAAO,OAAO,MAAM,OAAO,MAAM,EAAE,CAAC,CACjD,QAAO;AAGT,KAAI,OAAO,MAAM,KAAK,IAAI,eAAe,KAAK,gBAAgB,EAC5D,QAAO;CAGT,MAAM,GAAG,UAAU,UAAU;AAG7B,KAAI,SAAS,OAAO,SAAS,MAAM,SAAS,OAAO,SAAS,GAC1D,QAAO;CAIT,MAAM,aAAa,SAAS,UAAU;CAItC,MAAM,iBACH,6BAA6B,KAAK,IAAK,YAAY,KAAK,KAAM,IAAI,GACnE,KAAK;CAGP,MAAM,cAAc,aAAa;CACjC,MAAM,eAAe,cAAc;CAInC,MAAM,mBAAmB,eADT,SAAS;CAGzB,MAAM,gBAAgB,KAAK,MAAM,cAAc,iBAAiB;CAChE,MAAM,iBAAiB,KAAK,MAAM,eAAe,iBAAiB;AAKlE,QAAO,GAHO,UAAU,OAAO,cAAc,CAG7B,KAFD,UAAU,OAAO,eAAe,CAEnB,GAAG,KAAK,aAAa"}
@@ -1,17 +1,24 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { UniqueId } from '@accelint/core';
3
- import { ComponentPropsWithRef } from 'react';
4
- import { SupportedDistanceUnit } from './types.js';
5
- import '../deckgl/base-map/types.js';
6
- import '@accelint/bus';
7
- import '@deck.gl/core';
8
- import 'mjolnir.js';
9
- import '../deckgl/base-map/events.js';
10
- import './constants.js';
1
+ /*
2
+ * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at https://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
11
12
 
13
+ import { SupportedDistanceUnit } from "./types.js";
14
+ import { ComponentPropsWithRef } from "react";
15
+ import { UniqueId } from "@accelint/core";
16
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
17
+
18
+ //#region src/viewport/viewport-size.d.ts
12
19
  type ViewportSizeProps = ComponentPropsWithRef<'span'> & {
13
- instanceId: UniqueId;
14
- unit?: SupportedDistanceUnit;
20
+ instanceId: UniqueId;
21
+ unit?: SupportedDistanceUnit;
15
22
  };
16
23
  /**
17
24
  * A span element displaying the current viewport bounds in the specified unit.
@@ -37,6 +44,11 @@ type ViewportSizeProps = ComponentPropsWithRef<'span'> & {
37
44
  * />
38
45
  * ```
39
46
  */
40
- declare function ViewportSize({ instanceId, unit, ...rest }: ViewportSizeProps): react_jsx_runtime.JSX.Element;
41
-
42
- export { ViewportSize, type ViewportSizeProps };
47
+ declare function ViewportSize({
48
+ instanceId,
49
+ unit,
50
+ ...rest
51
+ }: ViewportSizeProps): react_jsx_runtime0.JSX.Element;
52
+ //#endregion
53
+ export { ViewportSize, ViewportSizeProps };
54
+ //# sourceMappingURL=viewport-size.d.ts.map
@@ -1,16 +1,59 @@
1
- import { jsx } from 'react/jsx-runtime';
2
- import { useViewportState } from './use-viewport-state.js';
3
- import { getViewportSize } from './utils.js';
1
+ /*
2
+ * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at https://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
4
12
 
5
- function ViewportSize({
6
- instanceId,
7
- unit = "nm",
8
- ...rest
9
- }) {
10
- const { bounds, zoom, width, height } = useViewportState({ instanceId });
11
- return /* @__PURE__ */ jsx("span", { ...rest, children: getViewportSize({ bounds, unit, zoom, width, height }) });
13
+
14
+ import { useViewportState } from "./use-viewport-state.js";
15
+ import { getViewportSize } from "./utils.js";
16
+ import { jsx } from "react/jsx-runtime";
17
+
18
+ //#region src/viewport/viewport-size.tsx
19
+ /**
20
+ * A span element displaying the current viewport bounds in the specified unit.
21
+ *
22
+ * Displays the viewport dimensions in a format like `660 x 1,801 NM`.
23
+ * Updates automatically as the viewport changes by subscribing to viewport events.
24
+ *
25
+ * @param props - Extends `<span>` props
26
+ * @param props.instanceId - The id of the view to subscribe to
27
+ * @param props.unit - Measure of distance: `km | m | nm | mi | ft`. Defaults to `nm`
28
+ * @param props.className - CSS classes for styling
29
+ *
30
+ * @example
31
+ * ```tsx
32
+ * // Basic usage with default nautical miles
33
+ * <ViewportSize instanceId="some-uuid" />
34
+ *
35
+ * // With custom unit and styling
36
+ * <ViewportSize
37
+ * instanceId="some-uuid"
38
+ * unit="km"
39
+ * className="text-sm text-gray-600"
40
+ * />
41
+ * ```
42
+ */
43
+ function ViewportSize({ instanceId, unit = "nm", ...rest }) {
44
+ const { bounds, zoom, width, height } = useViewportState({ instanceId });
45
+ return /* @__PURE__ */ jsx("span", {
46
+ ...rest,
47
+ children: getViewportSize({
48
+ bounds,
49
+ unit,
50
+ zoom,
51
+ width,
52
+ height
53
+ })
54
+ });
12
55
  }
13
56
 
57
+ //#endregion
14
58
  export { ViewportSize };
15
- //# sourceMappingURL=viewport-size.js.map
16
59
  //# sourceMappingURL=viewport-size.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/viewport/viewport-size.tsx"],"names":[],"mappings":";;;;AA+CO,SAAS,YAAA,CAAa;AAAA,EAC3B,UAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP,GAAG;AACL,CAAA,EAAsB;AACpB,EAAA,MAAM,EAAE,QAAQ,IAAA,EAAM,KAAA,EAAO,QAAO,GAAI,gBAAA,CAAiB,EAAE,UAAA,EAAY,CAAA;AAEvE,EAAA,uBACE,GAAA,CAAC,MAAA,EAAA,EAAM,GAAG,IAAA,EACP,QAAA,EAAA,eAAA,CAAgB,EAAE,MAAA,EAAQ,IAAA,EAAM,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,CAAA,EACxD,CAAA;AAEJ","file":"viewport-size.js","sourcesContent":["/*\n * Copyright 2025 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 { useViewportState } from './use-viewport-state';\nimport { getViewportSize } from './utils';\nimport type { UniqueId } from '@accelint/core';\nimport type { ComponentPropsWithRef } from 'react';\nimport type { SupportedDistanceUnit } from './types';\n\nexport type ViewportSizeProps = ComponentPropsWithRef<'span'> & {\n instanceId: UniqueId;\n unit?: SupportedDistanceUnit;\n};\n\n/**\n * A span element displaying the current viewport bounds in the specified unit.\n *\n * Displays the viewport dimensions in a format like `660 x 1,801 NM`.\n * Updates automatically as the viewport changes by subscribing to viewport events.\n *\n * @param props - Extends `<span>` props\n * @param props.instanceId - The id of the view to subscribe to\n * @param props.unit - Measure of distance: `km | m | nm | mi | ft`. Defaults to `nm`\n * @param props.className - CSS classes for styling\n *\n * @example\n * ```tsx\n * // Basic usage with default nautical miles\n * <ViewportSize instanceId=\"some-uuid\" />\n *\n * // With custom unit and styling\n * <ViewportSize\n * instanceId=\"some-uuid\"\n * unit=\"km\"\n * className=\"text-sm text-gray-600\"\n * />\n * ```\n */\nexport function ViewportSize({\n instanceId,\n unit = 'nm',\n ...rest\n}: ViewportSizeProps) {\n const { bounds, zoom, width, height } = useViewportState({ instanceId });\n\n return (\n <span {...rest}>\n {getViewportSize({ bounds, unit, zoom, width, height })}\n </span>\n );\n}\n"]}
1
+ {"version":3,"file":"viewport-size.js","names":[],"sources":["../../src/viewport/viewport-size.tsx"],"sourcesContent":["/*\n * Copyright 2025 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 { useViewportState } from './use-viewport-state';\nimport { getViewportSize } from './utils';\nimport type { UniqueId } from '@accelint/core';\nimport type { ComponentPropsWithRef } from 'react';\nimport type { SupportedDistanceUnit } from './types';\n\nexport type ViewportSizeProps = ComponentPropsWithRef<'span'> & {\n instanceId: UniqueId;\n unit?: SupportedDistanceUnit;\n};\n\n/**\n * A span element displaying the current viewport bounds in the specified unit.\n *\n * Displays the viewport dimensions in a format like `660 x 1,801 NM`.\n * Updates automatically as the viewport changes by subscribing to viewport events.\n *\n * @param props - Extends `<span>` props\n * @param props.instanceId - The id of the view to subscribe to\n * @param props.unit - Measure of distance: `km | m | nm | mi | ft`. Defaults to `nm`\n * @param props.className - CSS classes for styling\n *\n * @example\n * ```tsx\n * // Basic usage with default nautical miles\n * <ViewportSize instanceId=\"some-uuid\" />\n *\n * // With custom unit and styling\n * <ViewportSize\n * instanceId=\"some-uuid\"\n * unit=\"km\"\n * className=\"text-sm text-gray-600\"\n * />\n * ```\n */\nexport function ViewportSize({\n instanceId,\n unit = 'nm',\n ...rest\n}: ViewportSizeProps) {\n const { bounds, zoom, width, height } = useViewportState({ instanceId });\n\n return (\n <span {...rest}>\n {getViewportSize({ bounds, unit, zoom, width, height })}\n </span>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,SAAgB,aAAa,EAC3B,YACA,OAAO,MACP,GAAG,QACiB;CACpB,MAAM,EAAE,QAAQ,MAAM,OAAO,WAAW,iBAAiB,EAAE,YAAY,CAAC;AAExE,QACE,oBAAC;EAAK,GAAI;YACP,gBAAgB;GAAE;GAAQ;GAAM;GAAM;GAAO;GAAQ,CAAC;GAClD"}
package/package.json CHANGED
@@ -1,57 +1,17 @@
1
1
  {
2
- "$schema": "https://json.schemastore.org/package",
3
2
  "name": "@accelint/map-toolkit",
4
- "title": "Accelint Map Toolkit",
5
3
  "description": "A collection of components and utilities to simplify visualizing and working with geospatial data.",
4
+ "version": "0.4.1",
6
5
  "author": "https://hypergiant.com",
7
- "owner": "default/pathfinder",
8
- "keywords": [
9
- "deckgl",
10
- "geospatial",
11
- "map-tk",
12
- "maplibre"
13
- ],
14
- "subPath": "packages/map-toolkit",
15
- "version": "0.3.1",
16
- "private": false,
17
- "license": "Apache-2.0",
18
- "repository": {
19
- "type": "git",
20
- "url": "https://github.com/gohypergiant/standard-toolkit"
21
- },
22
- "type": "module",
23
- "files": [
24
- "./dist/**",
25
- "./catalog-info.yaml",
26
- "./CHANGELOG.md",
27
- "./package.json",
28
- "./README.md"
29
- ],
30
- "types": "./dist/index.d.ts",
31
- "exports": {
32
- "./*": {
33
- "import": {
34
- "types": "./dist/*/index.d.ts",
35
- "default": "./dist/*/index.js"
36
- },
37
- "default": "./dist/*/index.js"
38
- },
39
- "./*/fiber": {
40
- "import": {
41
- "types": "./dist/*/fiber.d.ts",
42
- "default": "./dist/*/fiber.js"
43
- },
44
- "default": "./dist/*/fiber.js"
45
- }
46
- },
6
+ "$schema": "https://json.schemastore.org/package",
47
7
  "devDependencies": {
48
- "@deck.gl/core": "^9.1.14",
49
- "@deck.gl/extensions": "^9.1.14",
50
- "@deck.gl/geo-layers": "^9.1.14",
51
- "@deck.gl/layers": "^9.1.14",
52
- "@deck.gl/mapbox": "^9.1.14",
53
- "@deck.gl/mesh-layers": "^9.1.14",
54
- "@deck.gl/widgets": "^9.1.14",
8
+ "@deck.gl/core": "~9.1",
9
+ "@deck.gl/extensions": "~9.1",
10
+ "@deck.gl/geo-layers": "~9.1",
11
+ "@deck.gl/layers": "~9.1",
12
+ "@deck.gl/mapbox": "~9.1",
13
+ "@deck.gl/mesh-layers": "~9.1",
14
+ "@deck.gl/widgets": "~9.1",
55
15
  "@deckgl-fiber-renderer/dom": "^1.4.0",
56
16
  "@deckgl-fiber-renderer/shared": "^1.4.0",
57
17
  "@deckgl-fiber-renderer/types": "^1.4.0",
@@ -59,39 +19,92 @@
59
19
  "@storybook/addon-themes": "^9.1.16",
60
20
  "@storybook/builder-vite": "^9.1.16",
61
21
  "@storybook/react-vite": "^9.1.16",
62
- "@tailwindcss/vite": "^4.1.11",
22
+ "@tailwindcss/vite": "^4.1.18",
63
23
  "@testing-library/dom": "^10.4.1",
64
- "@testing-library/jest-dom": "^6.6.4",
24
+ "@testing-library/jest-dom": "^6.9.1",
65
25
  "@testing-library/react": "^16.3.0",
66
26
  "@testing-library/user-event": "^14.6.1",
67
- "@types/node": "^24.9.0",
68
- "@types/react": "19.1.13",
69
- "@types/react-dom": "19.1.11",
27
+ "@types/node": "^22",
28
+ "@types/react": "^19",
29
+ "@types/react-dom": "^19",
70
30
  "client-only": "^0.0.1",
71
- "esbuild-fix-imports-plugin": "^1.0.23",
72
31
  "maplibre-gl": "^5.7.1",
73
32
  "milsymbol": "^3.0.2",
74
33
  "mjolnir.js": "^3.0.0",
75
34
  "node-fetch": "^2.6.7",
76
- "react": "19.0.0",
77
- "react-dom": "19.0.0",
35
+ "react": "^19",
36
+ "react-dom": "^19",
78
37
  "storybook": "^9.1.16",
79
- "tailwindcss": "^4.1.11",
80
- "tsup": "8.5.0",
81
- "type-fest": "^4.41.0",
82
- "typescript": "5.8.3",
83
- "vite": "^7.2.2",
84
- "vitest": "^4.0.8",
85
- "@accelint/bus": "3.0.0",
86
- "@accelint/constellation-tracker": "1.0.1",
38
+ "tailwindcss": "^4.1.18",
39
+ "tsdown": "^0.18.0",
40
+ "type-fest": "^5.3.1",
41
+ "typescript": "^5.9.3",
42
+ "vite": "^7.2.7",
43
+ "vitest": "^4.0.15",
87
44
  "@accelint/biome-config": "1.0.2",
88
- "@accelint/core": "0.5.0",
89
- "@accelint/design-foundation": "1.0.0",
90
- "@accelint/design-toolkit": "8.1.0",
91
- "@accelint/geo": "0.4.0",
45
+ "@accelint/bus": "3.0.2",
46
+ "@accelint/core": "0.5.2",
47
+ "@accelint/design-foundation": "2.0.0",
48
+ "@accelint/design-toolkit": "9.0.0",
49
+ "@accelint/geo": "0.4.2",
92
50
  "@accelint/typescript-config": "0.1.4",
93
- "@accelint/vitest-config": "0.1.5"
51
+ "@accelint/vitest-config": "0.1.6"
52
+ },
53
+ "engines": {
54
+ "node": ">=22",
55
+ "pnpm": ">=10"
94
56
  },
57
+ "exports": {
58
+ "./cursor-coordinates": "./dist/cursor-coordinates/index.js",
59
+ "./cursor-coordinates/use-cursor-coordinates": "./dist/cursor-coordinates/use-cursor-coordinates.js",
60
+ "./deckgl": "./dist/deckgl/index.js",
61
+ "./deckgl/base-map": "./dist/deckgl/base-map/index.js",
62
+ "./deckgl/base-map/constants": "./dist/deckgl/base-map/constants.js",
63
+ "./deckgl/base-map/events": "./dist/deckgl/base-map/events.js",
64
+ "./deckgl/base-map/provider": "./dist/deckgl/base-map/provider.js",
65
+ "./deckgl/base-map/types": "./dist/deckgl/base-map/types.js",
66
+ "./deckgl/symbol-layer": "./dist/deckgl/symbol-layer/index.js",
67
+ "./deckgl/symbol-layer/fiber": "./dist/deckgl/symbol-layer/fiber.js",
68
+ "./deckgl/text-layer": "./dist/deckgl/text-layer/index.js",
69
+ "./deckgl/text-layer/character-sets": "./dist/deckgl/text-layer/character-sets.js",
70
+ "./deckgl/text-layer/default-settings": "./dist/deckgl/text-layer/default-settings.js",
71
+ "./deckgl/text-layer/fiber": "./dist/deckgl/text-layer/fiber.js",
72
+ "./decorators/deckgl": "./dist/decorators/deckgl.js",
73
+ "./map-cursor": "./dist/map-cursor/index.js",
74
+ "./map-cursor/events": "./dist/map-cursor/events.js",
75
+ "./map-cursor/store": "./dist/map-cursor/store.js",
76
+ "./map-cursor/types": "./dist/map-cursor/types.js",
77
+ "./map-cursor/use-map-cursor": "./dist/map-cursor/use-map-cursor.js",
78
+ "./map-mode": "./dist/map-mode/index.js",
79
+ "./map-mode/events": "./dist/map-mode/events.js",
80
+ "./map-mode/store": "./dist/map-mode/store.js",
81
+ "./map-mode/types": "./dist/map-mode/types.js",
82
+ "./map-mode/use-map-mode": "./dist/map-mode/use-map-mode.js",
83
+ "./maplibre": "./dist/maplibre/index.js",
84
+ "./maplibre/constants": "./dist/maplibre/constants.js",
85
+ "./maplibre/hooks/use-maplibre": "./dist/maplibre/hooks/use-maplibre.js",
86
+ "./viewport": "./dist/viewport/index.js",
87
+ "./viewport/constants": "./dist/viewport/constants.js",
88
+ "./viewport/types": "./dist/viewport/types.js",
89
+ "./viewport/use-viewport-state": "./dist/viewport/use-viewport-state.js",
90
+ "./viewport/utils": "./dist/viewport/utils.js",
91
+ "./viewport/viewport-size": "./dist/viewport/viewport-size.js",
92
+ "./package.json": "./package.json"
93
+ },
94
+ "files": [
95
+ "./dist/**",
96
+ "./catalog-info.yaml",
97
+ "./CHANGELOG.md",
98
+ "./package.json",
99
+ "./README.md"
100
+ ],
101
+ "keywords": [
102
+ "deckgl",
103
+ "geospatial",
104
+ "map-tk",
105
+ "maplibre"
106
+ ],
107
+ "license": "Apache-2.0",
95
108
  "optionalDependencies": {
96
109
  "@deck.gl/core": "9.1.14",
97
110
  "@deck.gl/extensions": "9.1.14",
@@ -105,23 +118,39 @@
105
118
  "@deckgl-fiber-renderer/types": "^1.4.0",
106
119
  "maplibre-gl": "^5.7.1",
107
120
  "milsymbol": "3.0.2",
108
- "mjolnir.js": "^3.0.0",
109
- "@accelint/core": "0.5.0",
110
- "@accelint/bus": "3.0.0",
111
- "@accelint/geo": "0.4.0"
121
+ "mjolnir.js": "^3.0.0"
112
122
  },
123
+ "owner": "default/pathfinder",
124
+ "peerDependencies": {
125
+ "react": "^19",
126
+ "@accelint/bus": "3.0.2",
127
+ "@accelint/core": "0.5.2",
128
+ "@accelint/geo": "0.4.2"
129
+ },
130
+ "private": false,
113
131
  "publishConfig": {
114
132
  "access": "public"
115
133
  },
134
+ "repository": {
135
+ "type": "git",
136
+ "url": "https://github.com/gohypergiant/standard-toolkit"
137
+ },
116
138
  "sideEffects": false,
139
+ "subPath": "packages/map-toolkit",
140
+ "title": "Accelint Map Toolkit",
141
+ "type": "module",
142
+ "types": "./dist/index.d.ts",
117
143
  "scripts": {
118
144
  "bench": "pnpm vitest bench --run --dir src",
119
- "build": "pnpm tsup",
145
+ "build": "pnpm tsdown",
120
146
  "build-storybook": "pnpm storybook build",
121
- "constellation-tracker": "constellation-tracker",
147
+ "constellation-tracker": "pnpm exec constellation-tracker",
122
148
  "dev": "pnpm tsc --watch",
123
- "lint": "pnpm biome lint",
124
- "preview": "pnpm storybook dev -p 6006",
149
+ "format": "pnpm biome format . --write --verbose",
150
+ "format:check": "pnpm biome format . --verbose",
151
+ "license": "pnpm zx ../../scripts/license.mjs",
152
+ "lint": "pnpm biome lint . --verbose",
153
+ "preview": "pnpm storybook dev -p 6007",
125
154
  "test": "pnpm vitest --dir=src",
126
155
  "test:watch": "pnpm vitest --dir=src --watch"
127
156
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"types.js"}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}