npm package: @seamos/map-preset
Description: Simple Preset for map(Maplibre) when you development SeamOS application.
Author: Sungmin Cho
Latest version: 0.1.1

# @seamos/map-preset

A lightweight MapLibre wrapper library for SeamOS, providing  
**PMTiles-based vector & terrain maps** with environment-aware presets.

This library allows you to:
- Use **PMTiles (vector + raster-dem)** seamlessly with MapLibre
- Switch automatically between **development (S3)** and **production (device local server)** environments
- Reuse **predefined map style presets** (`basic`, `terrain`, etc.)
- Initialize a MapLibre map with a single function call

---

## Features

- ✅ MapLibre wrapper (browser-only)
- ✅ PMTiles protocol auto-registration
- ✅ Environment-based PMTiles base URL handling
- ✅ Built-in style presets (`STYLE_PRESETS`)
- ✅ Works with Vanilla JS, Vue, React, Next.js (client-side)

---

## Installation

```bash
npm install @seamos/map-preset maplibre-gl pmtiles
```

## Environment Concept (Important)
This library supports two environments:
| Environment | Description | When to Use |
|------------|------------------|-------------|
| `dev` | Local / Web development environment with internet access  | During local development and testing |
| `prod` | Device / Tablet deployment environment (offline or local static server) | Before app build and device deployment |

### Recommended Usage
- Use `env: "dev"` while developing locally to load PMTiles from S3.
- Switch to `env: "prod"` before building or deploying the app so the device loads PMTiles from its local static server.

## Basic Usage

### 1. Import MapLibre CSS (required)
```ts
import "maplibre-gl/dist/maplibre-gl.css";
```

### 2. Create a map
```Typescript
import { createSeamOSMap } from "@seamos/map-preset";

const map = createSeamOSMap({
    container: document.getElementById("map")!,
    preset: "basic",
    env: "dev",
    maplibre: {
        center: [127.0, 37.5],
        zoom: 12,
        maxZoom: 16,
        pitch: 45
    }
});

map.on("load", () => {
    console.log("✅ Map loaded");
});

map.on("error", (e) => {
    console.error("🧨 Map error", e?.error ?? e);
});
```

## Framework Examples
### Vanilla JavaScript
```html
<div id="map" style="width:100vw; height:100vh"></div>

<script type="module">
    import "maplibre-gl/dist/maplibre-gl.css";
    import { createSeamOSMap } from "@seamos/map-preset";

    const map = createSeamOSMap({
        container: document.getElementById("map"),
        preset: "basic",
        env: "dev"
    });
</script>
```

### Vue3
```typescript
<template>
    <div ref="mapEl" class="map" id="map"></div>
</template>

<script setup lang="ts">
import { createSeamOSMap } from "@seamos/map-preset";
import 'maplibre-gl/dist/maplibre-gl.css';
import { onMounted, ref } from "vue";

const mapEl = ref<HTMLDivElement | null>(null);
let map: maplibregl.Map | null = null;

onMounted(async() => {
    if (!mapEl.value) return;

    try {
        map = createSeamOSMap({
            container: mapEl.value,
            preset: "basic",
            env: "dev",
            
            maplibre: { center: [127, 37.5], zoom: 12, maxZoom: 16, pitch: 45 }
        });

        map.on("load", () => console.log("✅ map loaded"));
        map.on("error", (e) => console.error("🧨 map error", e?.error || e));
    } catch (err) {
        console.error("🧨 createAgmoMap failed", err);
    }
})
</script>

<style scoped>
.map {
    width: 100vw;
    height: 100vh;
    background: #111;
}
</style>
```

### React / Next.js (Client Component)
```typescript
"use client";

import { useEffect, useRef } from "react";
import { createSeamOSMap } from "@seamos/map-preset";
import "maplibre-gl/dist/maplibre-gl.css";

export default function MapView() {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!ref.current) return;

    const map = createSeamOSMap({
      container: ref.current,
      preset: "basic",
      env: "dev"
    });

    return () => map.remove();
  }, []);

  return <div ref={ref} style={{ width: "100vw", height: "100vh" }} />;
}
```

## Notes & Best Practices
- ❗ Browser-only library
  - Do not call createSeamOSMap in SSR or Node.js environments.
- ❗ Always include MapLibre CSS
- ❗ PMTiles requires HTTP Range Requests (206)
  - Ensure S3 / CDN / local device server supports range requests.
- ❗ Switch env to "prod" before app/device deployment

## License

MIT © SeamOS