import type { MapView, Directions, TNavigationOptions, TAddMarkerOptions, TStateChangedInternalPayload, Image3D, Shapes, Models, Markers, Labels, Camera, Text3D, Style, Outdoor, Paths } from '@mappedin/mappedin-js'; import type { UseBridgeHook } from '../hooks/use-bridge.js'; import type { Mappedin } from '../types.js'; import type { EventControl } from './event-control.js'; /** * Configuration for a navigation marker's template and display options. * * @example * ```typescript * // Basic distance marker * { * template: 'Distance: {{instruction.distance}}m', * options: { interactive: true, rank: 'high' } * } * * // Turn instruction marker * { * template: 'Turn {{instruction.action.bearing}} in {{instruction.distance}}m', * options: { rank: 'medium' } * } * ``` */ export type NavigationMarkerConfig = { /** * Handlebars templates receive objects with an 'instruction' property containing TDirectionInstruction data. @see {@link TDirectionInstruction} in @mappedin/mappedin-js for full type details * * @example * ```typescript * { * template: '
Turn {{instruction.action.bearing}} in {{instruction.distance}}m
', * } */ template?: string; /** Optional configuration for marker behavior */ options?: TAddMarkerOptions; }; /** * Extended navigation options that support configurable markers. * * Example: * ```typescript * createMarkers: { * departure: { * template: 'Departure: {{instruction.action.type}}', * options: { interactive: true } * }, * destination: { * template: 'Destination: {{instruction.action.type}}', * options: { rank: 'medium' } * }, * connection: false // Disable connection markers. * } * ``` */ export type ExtendedNavigationOptions = Omit & { createMarkers?: { /** Departure marker configuration or boolean to enable/disable */ departure?: NavigationMarkerConfig | boolean; /** Destination marker configuration or boolean to enable/disable */ destination?: NavigationMarkerConfig | boolean; /** Connection marker configuration or boolean to enable/disable */ connection?: NavigationMarkerConfig | boolean; }; }; /** * Utility type that converts all methods in a given type to return Promises. * Used in MapViewControl to wrap synchronous MapView methods for async bridge communication. * * @template T - The type to promisify * * @example * ```typescript * // Original synchronous API * interface TextAPI { * label(space: Space): Text3D; * remove(text: Text3D): void; * } * * // Promisified version * type AsyncTextAPI = Promisify; * // Results in: * // { * // label(space: Space): Promise; * // remove(text: Text3D): Promise; * // } * ``` * * @remarks * TypeScript's type system has limitations with complex generic transformations. * The basic Promisify works well for simple cases but struggles with: * - Function overloads - only the last overload signature is preserved * - Generic functions with conditional return types - type information is lost * - Complex generic constraints - requires manual type definitions */ export type Promisify = { [K in keyof T]: T[K] extends (...args: infer Args) => infer Return ? Return extends Promise ? T[K] : (...args: Args) => Promise : T[K] extends object ? Promisify : T[K]; }; /** * Extended navigation with custom marker templates * * @see {@link ExtendedNavigationOptions} for more information on the options * * @interface */ export type Navigation = { draw(directions: Directions | Directions[], options?: ExtendedNavigationOptions): Promise; } & Omit; type MapViewMethods = Omit & { /** * Internal method used by useEvent hook to call the bridge. * * @remarks * This method is used by useEvent hook to call the bridge. * It is not part of the public API and should not be used directly. * * @internal */ _bridgeCall: UseBridgeHook['instruct']; }; /** * A proxy that intercepts {@link MapView} method calls and forwards them through the bridge to the WebView. * All method calls are converted to asynchronous bridge instructions. * * This interface provides access to all MapView methods and properties in an async manner, * with specialized handling for Navigation and updateState methods. * * **Key Properties:** * - `updateState` - Async wrapper for updating entity states with type safety * - `Navigation` - Extended navigation with custom marker templates * - `on` - Subscribe to map events * - `off` - Unsubscribe from map events * - `destroy` - Clean up resources and event subscriptions * - All other MapView methods are available as async calls * * @example Basic Usage * ```typescript * // All MapView methods are available as async calls * await mapView.setFloor('floor-id'); * await mapView.Camera.focusOn(target, options); * await mapView.Labels.add(coordinate, content); * * // Navigation with custom markers * await mapView.Navigation.draw(directions, { * createMarkers: { * connection: { template: '
{{instruction.action.type}}
', options: { rank: 'always-visible' } } * } * }); * * // Event handling * mapView.on('click', handler); * mapView.off('click', handler); * * // Cleanup when unmounting * mapView.destroy(); * ``` * * @interface */ export type MapViewControl = Omit, 'Navigation' | 'Text3D' | 'BlueDot' | 'Camera' | 'Labels' | 'Markers' | 'Models' | 'Image3D' | 'Paths' | 'Shapes' | 'Style' | 'Outdoor'> & { /** Extended navigation with custom marker templates */ Navigation: Navigation; /** 3D text controls with async methods */ Text3D: Promisify; /** Camera controls with async methods */ Camera: Promisify; /** Label controls with async methods */ Labels: Promisify; /** Marker controls with async methods */ Markers: Promisify; /** Model controls with async methods */ Models: Promisify; /** Image controls with async methods */ Image3D: Promisify; /** Path controls with async methods */ Paths: Promisify; /** Shape controls with async methods */ Shapes: Promisify; /** Style controls with async methods */ Style: Promisify