@mapmap/maps 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -929,6 +929,12 @@ interface RouteLayerOptions {
929
929
  * without a design the layer keeps its built-in signal-blue look.
930
930
  */
931
931
  design?: NavRouteDesign;
932
+ /**
933
+ * Colour of the already-travelled part of the line once
934
+ * {@link RouteLayer.setProgress} is used (the Google-style "vanishing
935
+ * route line"). Defaults to a dimmed grey.
936
+ */
937
+ progressColor?: string;
932
938
  }
933
939
  /** Draws MapMap routes on a MapLibre map. */
934
940
  declare class RouteLayer {
@@ -941,8 +947,14 @@ declare class RouteLayer {
941
947
  private readonly sourceId;
942
948
  private readonly casingLayerId;
943
949
  private readonly lineLayerId;
950
+ private readonly maneuverSourceId;
951
+ private readonly maneuverLayerId;
952
+ private readonly arrowImageId;
944
953
  private readonly design;
954
+ private readonly progressColor;
945
955
  private lastRoute;
956
+ private progress;
957
+ private maneuver;
946
958
  constructor(map: MapMapMap | Map, options?: RouteLayerOptions);
947
959
  private readonly handleStyleLoad;
948
960
  /**
@@ -963,6 +975,26 @@ declare class RouteLayer {
963
975
  draw(route: ParsedRoute): void;
964
976
  /** Add-or-update the source and layers for a route on the current style. */
965
977
  private install;
978
+ /**
979
+ * Sets how much of the route has been travelled, as a fraction in `[0, 1]`
980
+ * of the line's length. The travelled part dims to `progressColor` (the
981
+ * "vanishing route line"); `0` restores the untinted line. The value is
982
+ * remembered across {@link draw} calls and style swaps. Pair with the
983
+ * guidance module's distance-remaining to derive the fraction.
984
+ */
985
+ setProgress(fraction: number): void;
986
+ /** Applies the current progress fraction to the line layer's gradient. */
987
+ private applyProgress;
988
+ /**
989
+ * Shows (or moves) the upcoming-manoeuvre arrow: a small map-aligned
990
+ * arrow at `lngLat` rotated to `bearingDeg` (clockwise from north).
991
+ * Survives style swaps until {@link clearManeuver}.
992
+ */
993
+ setManeuver(lngLat: [number, number], bearingDeg: number): void;
994
+ /** Hides the manoeuvre arrow. */
995
+ clearManeuver(): void;
996
+ /** Add-or-update the manoeuvre arrow source/layer for the current style. */
997
+ private installManeuver;
966
998
  /** Remove the route's layers and source from the map. */
967
999
  clear(): void;
968
1000
  /**
@@ -974,6 +1006,29 @@ declare class RouteLayer {
974
1006
 
975
1007
  /** Maximum accepted `data:` puck-image payload (matches Studio's upload cap). */
976
1008
  declare const MAX_PUCK_IMAGE_BYTES: number;
1009
+ /**
1010
+ * The signed shortest-arc rotation from `fromDeg` to `toDeg`, in degrees.
1011
+ * Always in `(-180, 180]`, so a heading tween never spins the long way
1012
+ * round the compass (350° -> 10° is +20°, not -340°).
1013
+ */
1014
+ declare function shortestArcDeg(fromDeg: number, toDeg: number): number;
1015
+ /** Options for {@link PositionPuck}. */
1016
+ interface PositionPuckOptions {
1017
+ /**
1018
+ * Animate between fixes instead of snapping (default `true`). Position
1019
+ * lerps linearly and heading tweens along the shortest arc, over a
1020
+ * duration adapted to the observed fix interval (like the
1021
+ * `NavigationCamera` glide, so puck and camera arrive together). Falls
1022
+ * back to instant placement where `requestAnimationFrame` is missing.
1023
+ */
1024
+ interpolate?: boolean;
1025
+ /** Test seam: clock override, defaults to `Date.now`. */
1026
+ now?: () => number;
1027
+ /** Test seam: frame scheduler override, defaults to rAF. */
1028
+ requestFrame?: (callback: () => void) => number;
1029
+ /** Test seam: frame canceller override, defaults to cancelAnimationFrame. */
1030
+ cancelFrame?: (handle: number) => void;
1031
+ }
977
1032
  /** A current-position puck marker for MapMap maps. */
978
1033
  declare class PositionPuck {
979
1034
  /** The puck's root DOM element (the Marker element). */
@@ -982,26 +1037,201 @@ declare class PositionPuck {
982
1037
  private readonly marker;
983
1038
  private readonly design;
984
1039
  private added;
1040
+ private readonly interpolate;
1041
+ private readonly now;
1042
+ private readonly requestFrame?;
1043
+ private readonly cancelFrame?;
1044
+ private frameHandle;
1045
+ /** The position/heading currently rendered on the marker. */
1046
+ private rendered;
1047
+ private lastFixAt;
985
1048
  /**
986
1049
  * Creates the puck (not yet on the map - it appears on the first
987
1050
  * {@link setLocation}). The design defaults to the map's
988
1051
  * `navDesign.puck` when given a `MapMapMap` whose theme carried an
989
1052
  * `extra.nav` block, then to the built-in blue puck.
990
1053
  */
991
- constructor(map: MapMapMap | Map, design?: NavPuckDesign);
1054
+ constructor(map: MapMapMap | Map, design?: NavPuckDesign, options?: PositionPuckOptions);
992
1055
  /**
993
1056
  * Moves the puck (adding it to the map on the first call). `headingDeg`
994
1057
  * rotates the whole element - arrow or custom image - clockwise from
995
1058
  * north; omit it to keep the previous heading.
1059
+ *
1060
+ * With interpolation on (the default) every call after the first glides
1061
+ * from the currently rendered position - a fix arriving mid-tween
1062
+ * retargets smoothly rather than jumping.
996
1063
  */
997
1064
  setLocation(location: {
998
1065
  lat: number;
999
1066
  lon: number;
1000
1067
  }, headingDeg?: number): void;
1001
- /** Removes the puck from the map. `setLocation` re-adds it. */
1068
+ /** Removes the puck from the map (cancelling any tween). `setLocation` re-adds it. */
1002
1069
  remove(): void;
1070
+ /** Applies a position/heading to the marker immediately. */
1071
+ private render;
1072
+ /** Runs a linear position lerp + shortest-arc heading tween via rAF. */
1073
+ private tween;
1074
+ /** Cancels an in-flight tween, leaving the marker where it rendered last. */
1075
+ private cancelTween;
1003
1076
  }
1004
1077
 
1078
+ /**
1079
+ * Auto day/night theme switching from sun position.
1080
+ *
1081
+ * A dependency-free solar calculator (the standard sunrise equation, as
1082
+ * published at https://en.wikipedia.org/wiki/Sunrise_equation, itself a
1083
+ * restatement of the NOAA solar calculation details,
1084
+ * https://gml.noaa.gov/grad/solcalc/calcdetails.html) plus a small
1085
+ * scheduler that flips between light and dark at sunrise/sunset. Nothing
1086
+ * here touches a map: pair {@link ThemeScheduler} with
1087
+ * `MapMapMap.setStyle("light" | "dark")` (or any other callback) in the
1088
+ * app. Territory packages already ship paired light/dark styles, so the
1089
+ * switch works offline too.
1090
+ */
1091
+ /** Sun-times result: either both events, or a polar day/night marker. */
1092
+ type SunTimes = {
1093
+ sunrise: Date;
1094
+ sunset: Date;
1095
+ } | "polarDay" | "polarNight";
1096
+ /**
1097
+ * Sunrise and sunset (standard -0.833° horizon: refraction + solar disc)
1098
+ * for the civil day containing `date` (UTC) at `lat`/`lng`, or a polar
1099
+ * marker when the sun never crosses the horizon that day.
1100
+ */
1101
+ declare function sunTimes(date: Date, lat: number, lng: number): SunTimes;
1102
+ /** The theme the sun dictates at `date` for `lat`/`lng`. */
1103
+ declare function resolveTheme(date: Date, lat: number, lng: number): "light" | "dark";
1104
+ /** Options for {@link ThemeScheduler}. */
1105
+ interface ThemeSchedulerOptions {
1106
+ /** Latitude used for the solar calculation. */
1107
+ lat: number;
1108
+ /** Longitude used for the solar calculation. */
1109
+ lng: number;
1110
+ /** Called (immediately on construction, then at each sunrise) for light. */
1111
+ onLight: () => void;
1112
+ /** Called (immediately on construction, then at each sunset) for dark. */
1113
+ onDark: () => void;
1114
+ /** Test seam: clock override, defaults to `Date.now`. */
1115
+ now?: () => number;
1116
+ /** Test seam: timer override, defaults to `setTimeout`. */
1117
+ setTimeoutFn?: (callback: () => void, ms: number) => ReturnType<typeof setTimeout>;
1118
+ /** Test seam: timer canceller, defaults to `clearTimeout`. */
1119
+ clearTimeoutFn?: (handle: ReturnType<typeof setTimeout>) => void;
1120
+ }
1121
+ /**
1122
+ * Applies the sun-appropriate theme now and at every subsequent
1123
+ * sunrise/sunset until {@link dispose}. No OSS map SDK ships this
1124
+ * out of the box; pair with the OS dark-mode signal in the app if the
1125
+ * user's system preference should win instead.
1126
+ */
1127
+ declare class ThemeScheduler {
1128
+ private lat;
1129
+ private lng;
1130
+ private readonly onLight;
1131
+ private readonly onDark;
1132
+ private readonly now;
1133
+ private readonly setTimeoutFn;
1134
+ private readonly clearTimeoutFn;
1135
+ private handle;
1136
+ private applied;
1137
+ private disposed;
1138
+ constructor(options: ThemeSchedulerOptions);
1139
+ /** The theme most recently applied, if any. */
1140
+ get current(): "light" | "dark" | undefined;
1141
+ /** Moves the observer (e.g. a new GPS fix region) and re-evaluates. */
1142
+ setPosition(lat: number, lng: number): void;
1143
+ /** Stops all future flips. */
1144
+ dispose(): void;
1145
+ /** Applies the theme for now and arms the timer for the next boundary. */
1146
+ private evaluate;
1147
+ /** Milliseconds until the next sunrise/sunset (or the polar re-check). */
1148
+ private nextBoundaryDelay;
1149
+ }
1150
+
1151
+ /**
1152
+ * Runtime label-language switching.
1153
+ *
1154
+ * MapMap tiles carry OpenMapTiles multilingual `name:*` fields
1155
+ * (https://openmaptiles.org/schema/), so a map can switch label language
1156
+ * without new tiles: rewrite each symbol layer's `text-field` to prefer
1157
+ * `name:{language}`. `setMapLanguage(map, "de")` does exactly that for
1158
+ * every layer whose text-field reads name fields (other text — road refs,
1159
+ * house numbers — is left untouched). Pass `null` to restore the compiled
1160
+ * style's default (`name:en` first).
1161
+ *
1162
+ * Server-side, themes can bake a language in with `theme.language`; this
1163
+ * helper is the client-side equivalent for user-facing toggles. For
1164
+ * right-to-left scripts (Arabic, Hebrew) also install MapLibre's RTL text
1165
+ * plugin in the app (`maplibregl.setRTLTextPlugin(...)`) — the SDK does
1166
+ * not fetch remote scripts on your behalf.
1167
+ */
1168
+
1169
+ /**
1170
+ * The `text-field` expression for labels in `language` — the requested
1171
+ * language first, the Latin transliteration second, the local name last.
1172
+ * `null` yields the compiled default (`name:en`, then `name`).
1173
+ */
1174
+ declare function languageTextField(language: string | null): unknown;
1175
+ /**
1176
+ * True when a layer's `text-field` reads `name`/`name:*` properties —
1177
+ * i.e. it is a place/POI/road-name label whose language can switch.
1178
+ * Fields reading other properties (`ref` shields, house numbers) are not.
1179
+ */
1180
+ declare function isNameTextField(textField: unknown): boolean;
1181
+ /**
1182
+ * Switches every name-label layer of the map's current style to
1183
+ * `language` (`null` restores the style's default). Returns the ids of
1184
+ * the layers it rewrote. Throws on a malformed language tag. Reapply
1185
+ * after `setStyle` — a style swap resets label languages.
1186
+ */
1187
+ declare function setMapLanguage(map: MapMapMap | Map, language: string | null): string[];
1188
+
1189
+ /**
1190
+ * Probe batch upload - the browser side of opt-in aggregate collection.
1191
+ *
1192
+ * The wasm nav core (`@mapmap/core` `GuidanceSession`) accumulates aggregates
1193
+ * on-device and hands back the exact body to POST via `finishProbeJson()`;
1194
+ * this helper delivers it to the gateway's `POST /v1/probe`, with the same
1195
+ * status handling and retry policy as the mobile SDKs. Aggregates only - the
1196
+ * core is architecturally incapable of emitting a trajectory.
1197
+ *
1198
+ * Consent is the caller's responsibility: only upload for a key whose operator
1199
+ * has set `probe_opt_in`, and - in a browser - only with the user's opt-in
1200
+ * (ePrivacy/PECR) consent. See `docs/PROBE-SDK-INTEGRATION.md`.
1201
+ *
1202
+ * @example
1203
+ * ```ts
1204
+ * const body = session.finishProbeJson(arrived, Date.now());
1205
+ * if (body) void uploadProbeBatch("https://api.mapmap.ai", apiKey, body);
1206
+ * ```
1207
+ */
1208
+ /** The outcome of an upload attempt. */
1209
+ type ProbeUploadOutcome = "accepted" | "refused" | "notEnabled" | "rejected" | "gaveUp";
1210
+ /** Options for {@link uploadProbeBatch}. All optional. */
1211
+ interface UploadProbeOptions {
1212
+ /** Injectable fetch (defaults to the global). */
1213
+ fetch?: typeof fetch;
1214
+ /** Total attempts including the first (default 4). */
1215
+ maxAttempts?: number;
1216
+ /** Attempt number → delay before the next try, ms (default `attempt*1000`). */
1217
+ backoffMs?: (attempt: number) => number;
1218
+ /** Injectable delay, for deterministic tests (default `setTimeout`). */
1219
+ sleep?: (ms: number) => Promise<void>;
1220
+ /** Abort signal forwarded to fetch. */
1221
+ signal?: AbortSignal;
1222
+ }
1223
+ /** The `/v1/probe` endpoint for a gateway origin (trailing slashes trimmed). */
1224
+ declare function buildProbeUrl(baseUrl: string): string;
1225
+ /**
1226
+ * POST one probe body to `{baseUrl}/v1/probe` with a bearer key. Transient
1227
+ * failures (network or `5xx`) are retried with bounded backoff; permanent ones
1228
+ * (`400`/`403`/`501`) are not. Resolves with the terminal outcome and never
1229
+ * rejects, so a fire-and-forget `void uploadProbeBatch(...)` is safe.
1230
+ *
1231
+ * @param body the string returned by `GuidanceSession.finishProbeJson()`.
1232
+ */
1233
+ declare function uploadProbeBatch(baseUrl: string, apiKey: string, body: string, options?: UploadProbeOptions): Promise<ProbeUploadOutcome>;
1234
+
1005
1235
  /** One place to show on the map - a store, depot, branch, POI. */
1006
1236
  interface Place {
1007
1237
  /** Stable unique id, e.g. your store number. */
@@ -1981,4 +2211,4 @@ declare class VoiceGuidance {
1981
2211
  private playEarcon;
1982
2212
  }
1983
2213
 
1984
- export { AdrCheck, type AdrCheckOptions, type AdrCheckRequest, type AdrCheckResult, type AdrDimensions, type AdrTunnelCategory, type BannerComponent, type BannerContent, type BannerInstruction, type BuildStyleOptions, type CameraFix, DEFAULT_GLYPHS_URL, DEFAULT_TERRITORY_TILES_URL, type DiagnosticIssue, EFFECTS_METADATA_KEY, FLOW_DEFAULTS, FULL_ATTRIBUTION, FlowRouteEffectLayer, type FlythroughController, type FlythroughOptions, type FlythroughPose, GuidanceBanner, type GuidanceSeverity, type GuidanceSpokenPrompt, type IsochroneFeatureCollection, IsochroneLayer, type IsochroneLayerOptions, LOGO_SVG, type LaneIndication, type LayerOverride, type LngLatLike, LogoControl, type LogoOptions, type LogoPosition, MAX_PUCK_IMAGE_BYTES, type MapDiagnosticsInput, MapMapMap, type MapMapOptions, type MapMapTheme, NAV_CAMERA_DEFAULTS, type NavBannerDesign, type NavCameraDesign, type NavDesign, type NavPuckDesign, type NavRouteDesign, NavigationCamera, type NavigationCameraMode, type NavigationCameraOptions, type NearestByDriveTimeOptions, OPENMAPTILES_ATTRIBUTION, OSM_ATTRIBUTION, PALETTE_SLOTS, POI_CATEGORY_COLORS, POI_CATEGORY_IDS, POI_CLASS_CATEGORIES, type ParsedRoute, type Place, type PlacePointFeature, type PlaceWithDistance, type PlaceWithDriveTime, type PlacesFeatureCollection, type PlacesIcon, type PlacesInput, PlacesLayer, type PlacesLayerIds, type PlacesLayerOptions, type PlacesSelectOptions, type PoiCategoryDesign, type PoiDesign, PositionPuck, RIBBON_FLOATS_PER_VERTEX, ROUTE_EFFECTS, type ReachabilityMode, type RibbonMesh, type RouteEffectLayer, type RouteEffectName, type RouteFlowOptions, type RouteGeometry, RouteLayer, type RouteLayerOptions, type RouteOptions, type RouteProfile, SIGNAL_BLUE, SOURCE_LAYERS, type SetRouteEffectOptions, type SeverityProsody, type ShowReachabilityOptions, type SpeakOptions, type StepGuidance, type Theme, type ThemeEffects, type TruckParams, VoiceGuidance, type VoiceGuidanceOptions, type VoiceGuidanceUpdate, type VoiceInstruction, applyPoiDesign, bannerLanes, bearingBetween, bindFlythroughToScroll, buildAdrCheckBody, buildRouteQuery, buildRouteUrl, buildStyle, builtInPoiColor, createMap, createRouteEffect, defaultNavDesign, defaultPoiDesign, directionArrow, effectsFromStyleMetadata, extractGuidance, flythrough, flythroughPose, formatCoord, formatCoords, haversineDistanceM, lngLatToMercator, navDesignFromTheme, navDesignFromThemeUrl, parseCssColour, parseNavDesign, parseOsrmRoute, parsePoiDesign, placesFromGeoJSON, poiDesignFromTheme, poiDesignFromThemeUrl, poiDesignIsDefault, poiTextColorExpression, prefersReducedMotion, registerPmtilesProtocol, resetDiagnostics, runMapDiagnostics, severityProsody, shortestArcDelta, speak, ssmlToText, tessellateRouteRibbon, toLngLat, toPmtilesUrl };
2214
+ export { AdrCheck, type AdrCheckOptions, type AdrCheckRequest, type AdrCheckResult, type AdrDimensions, type AdrTunnelCategory, type BannerComponent, type BannerContent, type BannerInstruction, type BuildStyleOptions, type CameraFix, DEFAULT_GLYPHS_URL, DEFAULT_TERRITORY_TILES_URL, type DiagnosticIssue, EFFECTS_METADATA_KEY, FLOW_DEFAULTS, FULL_ATTRIBUTION, FlowRouteEffectLayer, type FlythroughController, type FlythroughOptions, type FlythroughPose, GuidanceBanner, type GuidanceSeverity, type GuidanceSpokenPrompt, type IsochroneFeatureCollection, IsochroneLayer, type IsochroneLayerOptions, LOGO_SVG, type LaneIndication, type LayerOverride, type LngLatLike, LogoControl, type LogoOptions, type LogoPosition, MAX_PUCK_IMAGE_BYTES, type MapDiagnosticsInput, MapMapMap, type MapMapOptions, type MapMapTheme, NAV_CAMERA_DEFAULTS, type NavBannerDesign, type NavCameraDesign, type NavDesign, type NavPuckDesign, type NavRouteDesign, NavigationCamera, type NavigationCameraMode, type NavigationCameraOptions, type NearestByDriveTimeOptions, OPENMAPTILES_ATTRIBUTION, OSM_ATTRIBUTION, PALETTE_SLOTS, POI_CATEGORY_COLORS, POI_CATEGORY_IDS, POI_CLASS_CATEGORIES, type ParsedRoute, type Place, type PlacePointFeature, type PlaceWithDistance, type PlaceWithDriveTime, type PlacesFeatureCollection, type PlacesIcon, type PlacesInput, PlacesLayer, type PlacesLayerIds, type PlacesLayerOptions, type PlacesSelectOptions, type PoiCategoryDesign, type PoiDesign, PositionPuck, type PositionPuckOptions, type ProbeUploadOutcome, RIBBON_FLOATS_PER_VERTEX, ROUTE_EFFECTS, type ReachabilityMode, type RibbonMesh, type RouteEffectLayer, type RouteEffectName, type RouteFlowOptions, type RouteGeometry, RouteLayer, type RouteLayerOptions, type RouteOptions, type RouteProfile, SIGNAL_BLUE, SOURCE_LAYERS, type SetRouteEffectOptions, type SeverityProsody, type ShowReachabilityOptions, type SpeakOptions, type StepGuidance, type SunTimes, type Theme, type ThemeEffects, ThemeScheduler, type ThemeSchedulerOptions, type TruckParams, type UploadProbeOptions, VoiceGuidance, type VoiceGuidanceOptions, type VoiceGuidanceUpdate, type VoiceInstruction, applyPoiDesign, bannerLanes, bearingBetween, bindFlythroughToScroll, buildAdrCheckBody, buildProbeUrl, buildRouteQuery, buildRouteUrl, buildStyle, builtInPoiColor, createMap, createRouteEffect, defaultNavDesign, defaultPoiDesign, directionArrow, effectsFromStyleMetadata, extractGuidance, flythrough, flythroughPose, formatCoord, formatCoords, haversineDistanceM, isNameTextField, languageTextField, lngLatToMercator, navDesignFromTheme, navDesignFromThemeUrl, parseCssColour, parseNavDesign, parseOsrmRoute, parsePoiDesign, placesFromGeoJSON, poiDesignFromTheme, poiDesignFromThemeUrl, poiDesignIsDefault, poiTextColorExpression, prefersReducedMotion, registerPmtilesProtocol, resetDiagnostics, resolveTheme, runMapDiagnostics, setMapLanguage, severityProsody, shortestArcDeg, shortestArcDelta, speak, ssmlToText, sunTimes, tessellateRouteRibbon, toLngLat, toPmtilesUrl, uploadProbeBatch };