Skip to content

A utility for serializing and deserializing OpenLayers maps, layers, views, and features.

License

Notifications You must be signed in to change notification settings

rgbcmy/openlayers-serializer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

36 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

openlayers-serializer

A secure, type-safe utility library for OpenLayers that allows you to serialize and deserialize map objects. Easily transfer map state, layers, views, and features between frontend and backend, or save and restore map configurations.


πŸ†• Latest Improvements (v2.0)

  • πŸ”’ Security First: Eliminated eval() usage with safe function serialization
  • πŸ›‘οΈ Input Validation: Comprehensive data validation using Zod schemas
  • πŸ”§ Error Recovery: Robust error handling with graceful fallbacks
  • βœ… Fully Tested: 59 unit tests with 90%+ coverage on core modules
  • πŸ“ TypeScript: Complete type safety and IntelliSense support

✨ Features

  • πŸ”„ Serialization: Convert ol.Map, ol.View, ol.layer.*, ol.source.*, and ol.Feature into JSON
  • πŸ“¦ Deserialization: Rebuild OpenLayers objects from JSON with validation
  • 🎯 Supports Map, View, Layers, Sources, and Features
  • πŸ”’ Secure: Safe function serialization without eval() risks
  • πŸ›‘οΈ Validated: Input validation and error recovery mechanisms
  • πŸ’Ύ Perfect for saving map configurations or data exchange

πŸ“¦ Installation

npm install openlayers-serializer
# or
yarn add openlayers-serializer
# or  
pnpm add openlayers-serializer

πŸš€ Quick Start

Basic Usage

import { serializeMap, deserializeMap } from "openlayers-serializer";
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import OSM from "ol/source/OSM";

// Create a map
const map = new Map({
  view: new View({
    center: [0, 0],
    zoom: 2,
  }),
  layers: [
    new TileLayer({
      source: new OSM(),
    }),
  ],
});

// Serialize map to JSON (secure, validated)
const mapData = serializeMap(map);
console.log("Serialized:", mapData);

// Save to localStorage (example)
localStorage.setItem('myMap', JSON.stringify(mapData));

// Restore map from JSON (with validation)
const savedData = JSON.parse(localStorage.getItem('myMap'));
const restoredMap = deserializeMap(savedData);
console.log("Restored:", restoredMap);

Error Handling

import { deserializeMap, ValidationError, DeserializationError } from "openlayers-serializer";

try {
  const map = deserializeMap(mapData);
} catch (error) {
  if (error instanceof ValidationError) {
    console.error("Invalid map data:", error.message);
  } else if (error instanceof DeserializationError) {
    console.error("Failed to create map:", error.message);
    // Error includes context and suggestions
    console.log("Context:", error.context);
    console.log("Suggestions:", error.suggestions);
  }
}

Browser Demo

<!DOCTYPE html>
<html>
<head>
  <title>OpenLayers Serializer Demo</title>
  <script type="module">
    import { createDemoMap, exportMapData, importMapData } from './dist/openlayers-serializer.es.js';
    
    // Create demo map
    const map = createDemoMap();
    
    // Export map data
    window.exportMap = () => exportMapData();
    
    // Import map data
    window.importMap = () => importMapData();
  </script>
</head>
<body>
  <div id="map" style="width: 100%; height: 500px;"></div>
  <button onclick="exportMap()">Export Map</button>
  <button onclick="importMap()">Import Map</button>
</body>
</html>

οΏ½ Development & Testing

# Install dependencies
pnpm install

# Run development server
pnpm dev

# Build for production
pnpm build

# Run tests
pnpm test

# Run tests with coverage
pnpm test:coverage

# Run tests with UI
pnpm test:ui

Test Coverage

  • Total Tests: 59 tests, all passing βœ…
  • Core Modules: 90%+ test coverage
  • Security: No eval() usage, safe function serialization
  • Validation: Comprehensive input validation with Zod

πŸ“š API Reference

Core Functions

serializeMap(map: Map): IMap

Convert an OpenLayers Map instance into a serializable object.

Parameters:

  • map: Map - OpenLayers Map instance

Returns: Serialized map data object

deserializeMap(data: IMap): Map

Rebuild an OpenLayers Map instance from serialized data.

Parameters:

  • data: IMap - Serialized map data (validated automatically)

Returns: OpenLayers Map instance

Throws:

  • ValidationError - If input data is invalid
  • DeserializationError - If map creation fails

Utility Functions

serializeFunctionSafe(func: Function): SerializedFunction | undefined

Safely serialize functions without eval() risks.

deserializeFunctionSafe(data: SerializedFunction): Function | undefined

Safely deserialize functions with validation.


Supported Objects

Category Supported Types Count
Map ol/Map 1
View ol/View 1
Layers Tile, Vector, Image, Heatmap, Group (recursive) 5
Sources Core (9) + Advanced (5) + Extended (7) 21
Features ol/Feature (with geometry) 1
Styles Style, Fill, Stroke, Circle, Icon, Text 6+

Layer Details (5 Types)

  • βœ… TileLayer - Raster tile layers
  • βœ… VectorLayer - Vector feature layers with style support
  • βœ… ImageLayer - Static and dynamic image layers
  • βœ… HeatmapLayer - Heatmap visualization with gradients
  • βœ… GroupLayer - Hierarchical layer groups with recursive serialization

Source Details (21 Types)

Core Sources (9):

  • βœ… OSM - OpenStreetMap tiles
  • βœ… XYZ - Generic XYZ tile sources
  • βœ… BingMaps - Bing Maps aerial/road tiles
  • βœ… StadiaMaps - Stadia Maps (formerly Stamen)
  • βœ… TileDebug - Debug tile boundaries
  • βœ… TileWMS - OGC WMS tile service
  • βœ… Vector - GeoJSON and other vector formats
  • βœ… ImageStatic - Static georeferenced images
  • βœ… IIIF - International Image Interoperability Framework

Advanced Sources (5):

  • βœ… Cluster - Point clustering with configurable distance
  • βœ… GeoTIFF - Cloud Optimized GeoTIFF
  • βœ… VectorTile - Mapbox Vector Tiles (MVT)
  • βœ… WMTS - OGC Web Map Tile Service
  • βœ… UTFGrid - Interactive UTF grid layers

Extended Sources (7):

  • βœ… TileJSON - TileJSON specification tiles
  • βœ… Zoomify - Zoomify image pyramids
  • βœ… OGCMapTile - OGC Map Tile API
  • βœ… ImageArcGISRest - ArcGIS REST image services
  • βœ… ImageWMS - WMS image services
  • βœ… OGCVectorTile - OGC Vector Tile API
  • βœ… TileArcGISRest - ArcGIS REST tile services

πŸ”’ Security Features

Safe Function Serialization

  • ❌ No eval(): Eliminates code injection risks
  • βœ… Function Registry: Pre-approved function whitelist
  • βœ… Parser-based: Safe function parsing and reconstruction

Input Validation

  • πŸ›‘οΈ Zod Schemas: Runtime type validation
  • πŸ” Data Sanitization: Automatic data cleaning and fixing
  • ⚠️ Error Recovery: Graceful handling of invalid data

Error Handling

  • πŸ“Š Structured Errors: Detailed error context and suggestions
  • πŸ”„ Fallback Mechanisms: Automatic recovery strategies
  • πŸ“ Comprehensive Logging: Debug-friendly error messages

πŸ—οΈ Architecture

src/
β”œβ”€β”€ common/              # Core utilities
β”‚   β”œβ”€β”€ safe-functions.ts   # Secure function serialization
β”‚   β”œβ”€β”€ error-handling.ts   # Error recovery system
β”‚   β”œβ”€β”€ validation.ts       # Zod validation schemas
β”‚   └── registry.ts         # Function registry
β”œβ”€β”€ serializer/          # Serialization logic
β”‚   β”œβ”€β”€ map.ts             # Map serialization
β”‚   β”œβ”€β”€ view.ts            # View serialization
β”‚   β”œβ”€β”€ layer.ts           # Layer serialization
β”‚   └── source.ts          # Source serialization
β”œβ”€β”€ dto/                 # Type definitions
β”‚   └── *.ts               # Interface definitions
└── examples/            # Demo code
    └── demo.ts            # Usage examples

πŸ§ͺ Testing

# Run all tests
pnpm test

# Run with coverage report
pnpm test:coverage

# Run tests in watch mode
pnpm test:ui

Test Results

  • Total: 59 tests, all passing βœ…
  • Coverage: 90%+ on core modules
  • Security: No eval() usage detected
  • Validation: All edge cases covered

πŸš€ Migration from v1.x

Breaking Changes

  • eval() removed - functions now use safe serialization
  • Validation required - invalid data will throw errors
  • Error handling changed - new error types with context

Migration Steps

  1. Update imports: Error classes now available from main package
  2. Add error handling: Wrap deserialization in try-catch blocks
  3. Review custom functions: Ensure compatibility with safe serialization
  4. Test thoroughly: Validate existing serialized data
// v1.x (deprecated)
const map = deserializeMap(data); // Risky, no validation

// v2.x (recommended)  
try {
  const map = deserializeMap(data); // Safe, validated
} catch (error) {
  if (error instanceof ValidationError) {
    console.error("Data validation failed:", error.message);
  }
}

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Run tests (pnpm test)
  4. Commit changes (git commit -m 'Add amazing feature')
  5. Push to branch (git push origin feature/amazing-feature)
  6. Open a Pull Request

Development Guidelines

  • πŸ§ͺ Tests Required: All new features must include tests
  • πŸ”’ Security First: No eval() or unsafe practices
  • πŸ“ Documentation: Update README for API changes
  • 🎯 TypeScript: Maintain strict type safety

οΏ½ License

MIT License Β© 2025 rgbcmy

This project uses OpenLayers which is licensed under the BSD 2-Clause License.


πŸ™ Acknowledgments

  • OpenLayers - The amazing mapping library
  • Vite - Lightning fast build tool
  • Vitest - Delightful testing framework
  • Zod - TypeScript-first schema validation

About

A utility for serializing and deserializing OpenLayers maps, layers, views, and features.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published