@massif-maps/web 6.1.2 → 6.1.3

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/index.d.ts CHANGED
@@ -17,3 +17,9 @@ export interface CreateMapOptions {
17
17
 
18
18
  /** Loads the SDK module and starts a map on `canvas`. One per page. */
19
19
  export declare function createMap(canvas: HTMLCanvasElement, options?: CreateMapOptions): Promise<MassifMap & { module: any }>;
20
+
21
+ /**
22
+ * Keeps a directory of `module`'s filesystem (`map.module`) in the origin private file system: restored
23
+ * now, written back every `interval` ms (default 10000) and on `pagehide`. Resolves to a flush function.
24
+ */
25
+ export declare function persistDirectory(module: any, path: string, options?: { interval?: number }): Promise<() => Promise<void>>;
package/index.mjs CHANGED
@@ -9,6 +9,8 @@ import { attach, setBridge } from '@massif-maps/api';
9
9
  import { createBridge } from './bridge.mjs';
10
10
  import { canvasSelector, loadModule } from './massif.mjs';
11
11
 
12
+ export { persistDirectory } from './massif.mjs';
13
+
12
14
  export * from '@massif-maps/api';
13
15
 
14
16
  let created = false;
@@ -35,7 +37,7 @@ export async function createMap(canvas, { id = 'map', projection = 'EPSG:4326',
35
37
  getMeasuredHeight: () => canvas.height,
36
38
  };
37
39
  const map = attach(view, { id, projection });
38
- // The emscripten module, for what the facade does not cover (its FS, to mount an IndexedDB cache).
40
+ // The emscripten module, for what the facade does not cover (its FS, persistDirectory).
39
41
  map.module = module;
40
42
  return map;
41
43
  }
@@ -116,7 +116,7 @@ var PROPS = {
116
116
  "massif::Label": "style,o,massif::LabelStyle",
117
117
  "massif::LabelStyle": "anchorPointX,f;anchorPointY,f;flippable,b;orientationMode,e,BillboardOrientation;renderScale,f;scalingMode,e,BillboardScaling",
118
118
  "massif::LabelStyleBuilder": "anchorPointX,f;anchorPointY,f;flippable,b;orientationMode,e,BillboardOrientation;renderScale,f;scalingMode,e,BillboardScaling",
119
- "massif::Layer": "cullDelay,i;metaData,g,v;opacity,f;postProcessed,b;updatePriority,i;visible,b;visibleZoomRange,t",
119
+ "massif::Layer": "billboardsUnderLabels,b;cullDelay,i;metaData,g,v;opacity,f;postProcessed,b;updatePriority,i;visible,b;visibleZoomRange,t",
120
120
  "massif::Layers": "count,i",
121
121
  "massif::LightOptions": "ambientColor,c;ambientIntensity,f;dayCycleLightStops,t;dayCycleLightsEnabled,b;dayCycleRisingLightStops,t;shadowBias,f;shadowCascades,i;shadowCasterMargin,i;shadowDistance,f;shadowMapSize,i;shadowNormalOffset,f;shadowSoftness,f;shadowStrength,f;sunAltitude,f;sunAzimuth,f;sunColor,c;sunIntensity,f;sunOverridingStyle,b;terrainLightingEnabled,b",
122
122
  "massif::LightStop": "ambientColor,c;ambientIntensity,f;sunAltitude,f;sunColor,c;sunIntensity,f",
@@ -148,7 +148,7 @@ var PROPS = {
148
148
  "massif::NMLModel": "rotationAngle,f;rotationAxis,t;scale,f;style,o,massif::NMLModelStyle",
149
149
  "massif::NMLModelStyle": "modelAsset,o,massif::BinaryData;orientationMode,e,BillboardOrientation;scalingMode,e,BillboardScaling",
150
150
  "massif::NMLModelStyleBuilder": "modelAsset,o,massif::BinaryData;orientationMode,e,BillboardOrientation;scalingMode,e,BillboardScaling",
151
- "massif::Options": "DPI,f;ambientLightColor,c;backgroundBitmap,o,massif::Bitmap;baseProjection,o,massif::Projection;clearColor,c;clickMovingTolerance,f;clickTypeDetection,b;debugTileBorders,b;doubleClickDetection,b;doubleClickMaxDuration,f;drawDistance,f;envelopeThreadPoolSize,i;fieldOfViewY,f;focusPointOffset,t;fogOptions,o,massif::FogOptions;freeRoamLookSensitivity,f;freeRoamMode,e,FreeRoamMode;freeRoamMoveSpeed,f;kineticPan,b;kineticRotation,b;kineticZoom,b;labelPadding,f;labelViewDistance,f;layersLabelsProcessedInReverseOrder,b;lightOptions,o,massif::LightOptions;longClickDuration,f;mainLightColor,c;mainLightDirection,t;panBounds,p;panningMode,e,PanningMode;panningSpeedMode,e,PanningSpeedMode;pivotMode,e,PivotMode;renderProjectionMode,e,RenderProjectionMode;restrictedPanning,b;rotatable,b;rotationGestures,b;seamlessPanning,b;skyColor,c;skyOptions,o,massif::SkyOptions;terrainOptions,o,massif::TerrainOptions;tileDrawSize,i;tileLODFactor,f;tileLODMaxZoomLevelsOnScreen,f;tileLODTileCountRatio,f;tileStyleZoomLift,i;tileThreadPoolSize,i;tiltGestureReversed,b;tiltRange,t;userInput,b;zoomGestures,b;zoomOffset,f;zoomRange,t",
151
+ "massif::Options": "DPI,f;ambientLightColor,c;backgroundBitmap,o,massif::Bitmap;baseProjection,o,massif::Projection;clearColor,c;clickMovingTolerance,f;clickTypeDetection,b;debugTileBorders,b;doubleClickDetection,b;doubleClickMaxDuration,f;drawDistance,f;envelopeThreadPoolSize,i;fieldOfViewY,f;focusPointOffset,t;fogOptions,o,massif::FogOptions;freeRoamLookSensitivity,f;freeRoamMode,e,FreeRoamMode;freeRoamMoveSpeed,f;kineticPan,b;kineticRotation,b;kineticZoom,b;labelPadding,f;labelViewDistance,f;layersLabelsProcessedInReverseOrder,b;lightOptions,o,massif::LightOptions;longClickDuration,f;mainLightColor,c;mainLightDirection,t;orbitAroundPivot,b;panBounds,p;panningMode,e,PanningMode;panningSpeedMode,e,PanningSpeedMode;pivotMode,e,PivotMode;renderProjectionMode,e,RenderProjectionMode;restrictedPanning,b;rotatable,b;rotationGestures,b;seamlessPanning,b;skyColor,c;skyOptions,o,massif::SkyOptions;terrainOptions,o,massif::TerrainOptions;tileDrawSize,i;tileLODFactor,f;tileLODMaxZoomLevelsOnScreen,f;tileLODTileCountRatio,f;tileStyleZoomLift,i;tileThreadPoolSize,i;tiltGestureReversed,b;tiltRange,t;userInput,b;zoomGestures,b;zoomOffset,f;zoomRange,t",
152
152
  "massif::PackageInfo": "metaInfo,o,massif::PackageMetaInfo;name,s;packageId,s;packageType,e,PackageType;size,i;tileMask,o,massif::PackageTileMask;version,i",
153
153
  "massif::PackageManager": "localPackages,t;packageManagerListener,o,massif::PackageManagerListener;serverPackageListAge,i;serverPackageListMetaInfo,o,massif::PackageMetaInfo;serverPackages,t",
154
154
  "massif::PackageManagerTileDataSource": "packageManager,o,massif::PackageManager",
@@ -400,7 +400,7 @@ var SPEC_CLASS = {
400
400
  "elementstyle": { "balloon": "massif::BalloonPopupStyle", "line": "massif::LineStyle", "marker": "massif::MarkerStyle", "point": "massif::PointStyle", "polygon": "massif::PolygonStyle", "text": "massif::TextStyle" },
401
401
  "feature": { "feature": "massif::Feature" },
402
402
  "geocoding": { "multi-osm-offline": "massif::MultiOSMOfflineGeocodingService", "multi-osm-offline-reverse": "massif::MultiOSMOfflineReverseGeocodingService" },
403
- "geometry": { "line": "massif::LineGeometry", "point": "massif::PointGeometry", "polygon": "massif::PolygonGeometry" },
403
+ "geometry": { "line": "massif::LineGeometry", "maneuver-arrow": "massif::ManeuverArrowBuilder", "point": "massif::PointGeometry", "polygon": "massif::PolygonGeometry" },
404
404
  "layer": { "celestial": "massif::CelestialLayer", "composite-vector": "massif::CompositeVectorTileLayer", "elements": "massif::VectorLayer", "hillshade": "massif::HillshadeRasterTileLayer", "raster": "massif::RasterTileLayer", "solid": "massif::SolidLayer", "vector": "massif::VectorTileLayer" },
405
405
  "options": { "fog": "massif::FogOptions", "light": "massif::LightOptions", "sky": "massif::SkyOptions", "terrain": "massif::TerrainOptions" },
406
406
  "routing": { "multi-valhalla-offline": "massif::MultiValhallaOfflineRoutingService", "valhalla-offline": "massif::ValhallaOfflineRoutingService", "valhalla-online": "massif::ValhallaOnlineRoutingService" },
@@ -455,6 +455,7 @@ var KIND_OF_CLASS = {
455
455
  "massif::LocalVectorDataSource": "source",
456
456
  "massif::MBTilesTileDataSource": "source",
457
457
  "massif::MBVectorTileDecoder": "style",
458
+ "massif::ManeuverArrowBuilder": "geometry",
458
459
  "massif::MapTilerOnlineTileDataSource": "source",
459
460
  "massif::Marker": "element",
460
461
  "massif::MarkerStyle": "elementstyle",
@@ -515,7 +516,7 @@ var METHODS = {
515
516
  "massif::CelestialImage": "setAnchors,v",
516
517
  "massif::CelestialLabel": "setAnchorPoint,v;setOffset,v",
517
518
  "massif::CelestialLayer": "add,v;clear,v;remove,b",
518
- "massif::CelestialObject": "setDirection,v",
519
+ "massif::CelestialObject": "setDirection,v;setPosition,v",
519
520
  "massif::CompositeVectorTileLayer": "addExternalDataSource,v;addVectorDataSource,v;getExternalChildLayer,o,massif::Layer;getExternalDataSourceNames,j;removeExternalDataSource,b;setExternalDataSourceMaxOverzoomLevel,v;setExternalDataSourceZoomLevelBias,v",
520
521
  "massif::FeatureCollection": "getFeature,o,massif::Feature",
521
522
  "massif::FeatureCollectionSearchService": "findFeatures,o,massif::FeatureCollection",
@@ -527,6 +528,7 @@ var METHODS = {
527
528
  "massif::LightOptions": "setSunPositionFromTime,v",
528
529
  "massif::LocalVectorDataSource": "add,v;clear,v;remove,b",
529
530
  "massif::MBVectorTileDecoder": "addFallbackFont,v;getLegend,j;getStyleParameter,s;setStyleParameter,b;setStyleParameters,v",
531
+ "massif::ManeuverArrowBuilder": "buildArrow,j;buildArrowAtIndex,j",
530
532
  "massif::MultiOSMOfflineGeocodingService": "add,v;remove,b",
531
533
  "massif::MultiOSMOfflineReverseGeocodingService": "add,v;remove,b",
532
534
  "massif::MultiTileDataSource": "add,v;remove,b",
@@ -2404,6 +2406,74 @@ async function loadModule({ variant, moduleUrl = new URL(`${MODULE_NAME}${varian
2404
2406
  const base = new URL(".", new URL(moduleUrl, location.href)).href;
2405
2407
  return factory({ locateFile: (path) => base + path, ...options });
2406
2408
  }
2409
+ var S_IFMT = 61440;
2410
+ var S_IFDIR = 16384;
2411
+ var statSeconds = (time) => typeof time === "number" ? time : Math.floor(time.getTime() / 1e3);
2412
+ async function persistDirectory(module, path, { interval = 1e4 } = {}) {
2413
+ const { FS } = module;
2414
+ FS.mkdirTree(path);
2415
+ let root = await navigator.storage.getDirectory();
2416
+ for (const name of path.split("/").filter(Boolean)) {
2417
+ root = await root.getDirectoryHandle(name, { create: true });
2418
+ }
2419
+ const written = /* @__PURE__ */ new Map();
2420
+ const unchanged = (child, mtime) => {
2421
+ const entry = written.get(child);
2422
+ return entry !== void 0 && entry.mtime === mtime && mtime < entry.at;
2423
+ };
2424
+ async function restore(handle, dir) {
2425
+ for await (const [name, entry] of handle.entries()) {
2426
+ const child = `${dir}/${name}`;
2427
+ if (entry.kind === "directory") {
2428
+ FS.mkdirTree(child);
2429
+ await restore(entry, child);
2430
+ } else {
2431
+ FS.writeFile(child, new Uint8Array(await (await entry.getFile()).arrayBuffer()));
2432
+ written.set(child, { mtime: statSeconds(FS.stat(child).mtime), at: Infinity });
2433
+ }
2434
+ }
2435
+ }
2436
+ async function save(handle, dir) {
2437
+ const names2 = new Set(FS.readdir(dir).filter((name) => name !== "." && name !== ".."));
2438
+ for (const child of [...written.keys()]) {
2439
+ const name = child.slice(dir.length + 1);
2440
+ if (child.startsWith(`${dir}/`) && !name.includes("/") && !names2.has(name)) {
2441
+ await handle.removeEntry(name).catch(() => {
2442
+ });
2443
+ written.delete(child);
2444
+ }
2445
+ }
2446
+ for (const name of names2) {
2447
+ const child = `${dir}/${name}`;
2448
+ const stat = FS.stat(child);
2449
+ if ((stat.mode & S_IFMT) === S_IFDIR) {
2450
+ await save(await handle.getDirectoryHandle(name, { create: true }), child);
2451
+ continue;
2452
+ }
2453
+ const mtime = statSeconds(stat.mtime);
2454
+ if (unchanged(child, mtime)) {
2455
+ continue;
2456
+ }
2457
+ const at = Math.floor(Date.now() / 1e3);
2458
+ const data = FS.readFile(child);
2459
+ const writable = await (await handle.getFileHandle(name, { create: true })).createWritable();
2460
+ await writable.write(data);
2461
+ await writable.close();
2462
+ written.set(child, { mtime, at });
2463
+ }
2464
+ }
2465
+ await restore(root, path.replace(/\/+$/, ""));
2466
+ let saving = null;
2467
+ const flush = () => {
2468
+ saving ?? (saving = save(root, path.replace(/\/+$/, "")).finally(() => {
2469
+ saving = null;
2470
+ }));
2471
+ return saving;
2472
+ };
2473
+ setInterval(flush, interval);
2474
+ addEventListener("pagehide", flush);
2475
+ return flush;
2476
+ }
2407
2477
 
2408
2478
  // ../../dist/web/index.mjs
2409
2479
  var created = false;
@@ -2453,6 +2523,7 @@ export {
2453
2523
  find,
2454
2524
  isAvailable,
2455
2525
  log,
2526
+ persistDirectory,
2456
2527
  setBridge,
2457
2528
  wrap,
2458
2529
  wrapLayer