npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

hamuga-imap-sdk

v0.1.0

Published

[English](#english) · [Монгол хэлээр](#монгол-хэлээр)

Readme

Hamuga iMap JavaScript SDK

English · Монгол хэлээр

English

Hamuga iMap is a browser JavaScript SDK built on MapLibre GL JS. It provides a Hamuga map, address autocomplete, points of interest (POI) lookup, and route planning through one API.

  • Package: hamuga-imap-sdk
  • Current package version: 0.1.0
  • Peer dependency: maplibre-gl ^5.14.0
  • Default gateway: https://gateway.hamuga.mn
  • Default style: https://cdn.hamuga.mn/style.json

Install with npm

npm install hamuga-imap-sdk maplibre-gl

The package ships ESM, CommonJS, and IIFE builds with TypeScript types included.

Import the stylesheet before rendering the map. MapLibre styles are bundled inside it, so no separate MapLibre CSS import is needed:

import HamugaImap from 'hamuga-imap-sdk';
import 'hamuga-imap-sdk/dist/hamuga-imap.min.css';

HamugaImap.initialize({
  apiKey: 'your_hamuga_imap_api_key',
  theme: 'light',
  debug: false,
});

const map = HamugaImap.ui.map({
  container: 'map',
  center: [106.9163376, 47.919118], // [longitude, latitude]
  zoom: 12,
  attributionControl: false,
});

const maplibregl = HamugaImap.ui.maplibregl;
map.addControl(new maplibregl.NavigationControl(), 'bottom-right');
map.addControl(new maplibregl.ScaleControl({ unit: 'metric' }), 'bottom-right');

The map container must have a height. The SDK uses the default Hamuga style unless your mapOptions.style overrides it.

html,
body,
#map {
  width: 100%;
  height: 100%;
  margin: 0;
}

Use from a script tag

Load MapLibre before the SDK. The Immediately Invoked Function Expression (IIFE) build exposes the default class as HamugaImap.

<link
  rel="stylesheet"
  href="https://unpkg.com/[email protected]/dist/hamuga-imap.min.css"
/>
<script src="https://unpkg.com/[email protected]/dist/maplibre-gl.js"></script>
<script src="https://unpkg.com/[email protected]/dist/iife.global.js"></script>
<div id="map"></div>
<script>
  HamugaImap.initialize({
    apiKey: 'your_hamuga_imap_api_key',
    theme: 'light',
  });

  const map = HamugaImap.ui.map({
    container: 'map',
    center: [106.9163376, 47.919118],
    zoom: 12,
  });

  map.addControl(
    new HamugaImap.ui.maplibregl.NavigationControl(),
    'bottom-right',
  );
</script>

Use a client-safe key intended for this SDK. Do not put server credentials in browser code.

Autocomplete

The UI helper mounts an accessible search input into a container element. Runtime defaults are minCharacters: 3 and limit: 8.

const autocomplete = HamugaImap.ui.autocomplete({
  container: 'autocomplete',
  placeholder: 'Search for a place',
  width: 600,
  limit: 8,
  onSelection: (selection) => {
    const location = selection?.location;
    if (!location) return;

    const { latitude, longitude } = location;
    map.flyTo({ center: [longitude, latitude], zoom: 15 });
    HamugaImap.ui.marker()
      .setLngLat([longitude, latitude])
      .addTo(map);
  },
});

// Keep the instance if you need to inspect or manage the mounted UI.
void autocomplete;

For a headless request, call the API directly:

const result = await HamugaImap.autocomplete({
  value: 'Sukhbaatar Square',
  page: 1,
  perPage: 10,
});

POI lookup

const pois = await HamugaImap.poi({
  area: true,
  categoryIds: [543],
  llx: 106.90699148188776,
  lly: 47.90622961174208,
  urx: 106.93673742840637,
  ury: 47.91933711330858,
  name: 'restaurant',
  page: 1,
  size: 10,
});

const nearby = await HamugaImap.poiCoordinate({
  lat: 47.91194077591632,
  lon: 106.92879515654936,
  zoom: 10,
});

For an area query, llx/lly are the south-west corner and urx/ury are the north-east corner, in longitude/latitude order.

Routing

const drivingOrWalking = await HamugaImap.routing({
  locations: [
    { lat: 47.918, lon: 106.9176 },
    { lat: 47.92, lon: 106.92 },
  ],
});

const publicTransport = await HamugaImap.routingBus({
  start: '47.927572261628114,106.93353687526832',
  end: '47.907956772246735,106.91491161586976',
  mode: ['WALK', 'BUS'],
});

routingBus accepts WALK, BUS, and TRAIN modes. The response shape is returned by the gateway and is not normalized by this SDK.

Public API

| API | Purpose | | --- | --- | | HamugaImap.initialize(options) | Set the API key, gateway host, logging, and theme. Call before other SDK APIs. | | HamugaImap.ui.map(options) | Create a MapLibre map with Hamuga's default style and tile request handling. | | HamugaImap.ui.maplibregl | Access the MapLibre GL JS constructor and control classes used by the SDK. | | HamugaImap.ui.marker(options) | Create a Hamuga marker compatible with the MapLibre map. | | HamugaImap.ui.autocomplete(options) | Mount the autocomplete UI. | | HamugaImap.autocomplete(params) | Request address autocomplete results. | | HamugaImap.poi(params) | Search POIs by area, category, name, and pagination. | | HamugaImap.poiCoordinate(params) | Request POIs around a coordinate and zoom level. | | HamugaImap.routing(params) | Request a route for latitude/longitude locations. | | HamugaImap.routingBus(params) | Request a multimodal public transport plan. |

Error handling

Gateway failures throw typed errors instead of raw axios errors. All extend HamugaImapError:

| Error | When | Extra fields | | --- | --- | --- | | HamugaImapApiKeyError | initialize called without an API key, or a request ran before initialize. | — | | HamugaImapRequestError | Gateway returned an HTTP error status, or the request failed before a response arrived (network error, or an error response blocked from reading by missing CORS headers). | statusCode, gatewayMessage, requestId (each set when the gateway response was readable) | | HamugaImapResponseError | Gateway answered 200 but the body did not match the documented shape. | — | | HamugaImapAutocompleteContainerNotFound | The autocomplete container element does not exist. | — |

import HamugaImap, { HamugaImapRequestError } from 'hamuga-imap-sdk';

try {
  const result = await HamugaImap.autocomplete({ value: 'Ulaanbaatar' });
} catch (error) {
  if (error instanceof HamugaImapRequestError && error.statusCode === 403) {
    // The API key is not subscribed to this service.
    // error.requestId helps gateway support locate the request.
  }
}

Configuration

initialize accepts the following documented options:

| Option | Type | Notes | | --- | --- | --- | | apiKey | string | Required. Sent as x-api-key to Hamuga endpoints. | | tileUrlTemplate | string | Optional tile-only override. Defaults to ${host}/tile/tiles/{z}/{x}/{y}.pbf. | | theme | 'light' \| 'dark' | Controls the SDK UI theme. | | debug | boolean | Enables debug logging when supported by the SDK. | | logLevel | 'none' \| 'debug' \| 'info' \| 'warn' \| 'error' | Controls logger verbosity. |

Custom styles and tile requests

The default map style uses Hamuga's CDN style. The SDK rewrites legacy tile URLs to tileUrlTemplate and adds x-api-key only to matching tile requests. host remains the base URL for search, POI, and routing. If you provide a custom transformRequest, you own authentication and tile URL handling for that map.

Custom tile endpoints must be reachable from the browser and allow the required Cross-Origin Resource Sharing (CORS) headers. If a tile endpoint is private, proxy it through a server you control instead of exposing a server credential in the browser.

Troubleshooting

  • Map is blank: set an explicit height on the map container and import hamuga-imap-sdk/dist/hamuga-imap.min.css (MapLibre styles included).
  • Tiles fail: verify the API key, gateway reachability, CORS, and the browser network panel. The default tile endpoint is https://gateway.hamuga.mn/tile/tiles/{z}/{x}/{y}.pbf.
  • Autocomplete throws a container error: create the container element before calling HamugaImap.ui.autocomplete(options).
  • React integration: create the map in an effect, keep the map instance in a ref, and call map.remove() when the component unmounts. Do not create a new MapLibre map on every render.
  • API errors: wrap asynchronous calls in try/catch and inspect the typed error classes (see Error handling); the SDK propagates gateway failures rather than returning fake data.

Local development

npm install
npm run build
# Watch mode
npm run dev

License

Apache-2.0.

Монгол хэлээр

Hamuga iMap нь MapLibre GL JS дээр суурилсан browser JavaScript SDK юм. Нэг API-аар Hamuga газрын зураг, хаягийн autocomplete, сонирхлын цэгийн (POI) хайлт, маршрут тооцооллыг ашиглана.

  • Package: hamuga-imap-sdk
  • Одоогийн хувилбар: 0.1.0
  • Peer dependency: maplibre-gl ^5.14.0
  • Үндсэн gateway: https://gateway.hamuga.mn
  • Үндсэн style: https://cdn.hamuga.mn/style.json

npm-ээр суулгах

npm install hamuga-imap-sdk maplibre-gl

Package нь ESM, CommonJS, IIFE build болон TypeScript type-ийг дагуулж өгнө.

Газрын зураг зурахаас өмнө stylesheet-ийг import хийнэ. MapLibre style нь дотор багтсан тул тусдаа MapLibre CSS import хийх шаардлагагүй:

import HamugaImap from 'hamuga-imap-sdk';
import 'hamuga-imap-sdk/dist/hamuga-imap.min.css';

HamugaImap.initialize({
  apiKey: 'your_hamuga_imap_api_key',
  theme: 'light',
  debug: false,
});

const map = HamugaImap.ui.map({
  container: 'map',
  center: [106.9163376, 47.919118], // [longitude, latitude]
  zoom: 12,
  attributionControl: false,
});

const maplibregl = HamugaImap.ui.maplibregl;
map.addControl(new maplibregl.NavigationControl(), 'bottom-right');
map.addControl(new maplibregl.ScaleControl({ unit: 'metric' }), 'bottom-right');

Map container заавал өндөртэй байна. mapOptions.style өгөөгүй бол SDK-ийн default Hamuga style ашиглана.

html,
body,
#map {
  width: 100%;
  height: 100%;
  margin: 0;
}

Script tag-аар ашиглах

MapLibre-г SDK-аас өмнө ачаална. Immediately Invoked Function Expression (IIFE) build нь default class-ийг HamugaImap нэрээр global-д гаргана.

<link
  rel="stylesheet"
  href="https://unpkg.com/[email protected]/dist/hamuga-imap.min.css"
/>
<script src="https://unpkg.com/[email protected]/dist/maplibre-gl.js"></script>
<script src="https://unpkg.com/[email protected]/dist/iife.global.js"></script>
<div id="map"></div>
<script>
  HamugaImap.initialize({
    apiKey: 'your_hamuga_imap_api_key',
    theme: 'light',
  });

  const map = HamugaImap.ui.map({
    container: 'map',
    center: [106.9163376, 47.919118],
    zoom: 12,
  });

  map.addControl(
    new HamugaImap.ui.maplibregl.NavigationControl(),
    'bottom-right',
  );
</script>

Browser кодонд зөвхөн энэ SDK-д зориулсан client-safe key ашигла. Server credential бүү оруул.

Autocomplete

UI helper нь accessible search input-ийг container элементэд байрлуулна. Runtime default нь minCharacters: 3, limit: 8 байна.

const autocomplete = HamugaImap.ui.autocomplete({
  container: 'autocomplete',
  placeholder: 'Байршил хайх',
  width: 600,
  limit: 8,
  onSelection: (selection) => {
    const location = selection?.location;
    if (!location) return;

    const { latitude, longitude } = location;
    map.flyTo({ center: [longitude, latitude], zoom: 15 });
    HamugaImap.ui.marker()
      .setLngLat([longitude, latitude])
      .addTo(map);
  },
});

// Хэрэв mounted UI-г шалгах эсвэл удирдах бол instance-ийг хадгал.
void autocomplete;

Headless request хийхдээ API-г шууд дууд:

const result = await HamugaImap.autocomplete({
  value: 'Сүхбаатарын талбай',
  page: 1,
  perPage: 10,
});

POI хайлт

const pois = await HamugaImap.poi({
  area: true,
  categoryIds: [543],
  llx: 106.90699148188776,
  lly: 47.90622961174208,
  urx: 106.93673742840637,
  ury: 47.91933711330858,
  name: 'restaurant',
  page: 1,
  size: 10,
});

const nearby = await HamugaImap.poiCoordinate({
  lat: 47.91194077591632,
  lon: 106.92879515654936,
  zoom: 10,
});

Area query-д llx/lly нь зүүн-доод, urx/ury нь баруун-дээд булан байна. Координатын дараалал нь longitude/latitude байна.

Маршрут тооцоолох

const drivingOrWalking = await HamugaImap.routing({
  locations: [
    { lat: 47.918, lon: 106.9176 },
    { lat: 47.92, lon: 106.92 },
  ],
});

const publicTransport = await HamugaImap.routingBus({
  start: '47.927572261628114,106.93353687526832',
  end: '47.907956772246735,106.91491161586976',
  mode: ['WALK', 'BUS'],
});

routingBus нь WALK, BUS, TRAIN mode хүлээн авна. Response shape-г gateway буцаадаг бөгөөд энэ SDK normalization хийхгүй.

Нийтийн API

| API | Үүрэг | | --- | --- | | HamugaImap.initialize(options) | API key, gateway host, log болон theme тохируулна. Бусад API-аас өмнө дуудна. | | HamugaImap.ui.map(options) | Hamuga-ийн default style болон tile request handling-тэй MapLibre map үүсгэнэ. | | HamugaImap.ui.maplibregl | SDK ашиглаж буй MapLibre GL JS constructor болон control-уудыг өгнө. | | HamugaImap.ui.marker(options) | MapLibre map-тэй ажиллах Hamuga marker үүсгэнэ. | | HamugaImap.ui.autocomplete(options) | Autocomplete UI байрлуулна. | | HamugaImap.autocomplete(params) | Хаягийн autocomplete үр дүн хүснэ. | | HamugaImap.poi(params) | Area, category, name болон pagination-ээр POI хайна. | | HamugaImap.poiCoordinate(params) | Координат болон zoom-ийн орчимд POI хүснэ. | | HamugaImap.routing(params) | Latitude/longitude байршлуудаар маршрут хүснэ. | | HamugaImap.routingBus(params) | Олон төрлийн нийтийн тээврийн төлөвлөгөө хүснэ. |

Алдаа гаралт

Gateway-ийн алдаа нь түүхий axios алдаа биш, тодорхой төрлийн алдаа болон шидэгдэнэ. Бүгд HamugaImapError-г өвлөнө:

| Алдаа | Үүсэх үе | Нэмэлт талбар | | --- | --- | --- | | HamugaImapApiKeyError | initialize-д API key өгөгдөөгүй, эсвэл initialize-ээс өмнө request хийгдсэн. | — | | HamugaImapRequestError | Gateway HTTP алдааны status буцаасан, эсвэл response ирэхээс өмнө request бүтэлгүйтсэн (сүлжээний алдаа, эсвэл CORS header байхгүй тул browser алдааг уншиж чадахгүй). | statusCode, gatewayMessage, requestId (gateway response уншигдах үед оноогдоно) | | HamugaImapResponseError | Gateway 200 буцаасан ч бүтэц нь баримт бичгийн shape-т тохироогүй. | — | | HamugaImapAutocompleteContainerNotFound | Autocomplete container элемент олдоогүй. | — |

import HamugaImap, { HamugaImapRequestError } from 'hamuga-imap-sdk';

try {
  const result = await HamugaImap.autocomplete({ value: 'Улаанбаатар' });
} catch (error) {
  if (error instanceof HamugaImapRequestError && error.statusCode === 403) {
    // API key энэ service-д бүртгэлгүй байна.
    // error.requestId-г gateway support-д өгвөл request-ийг олоход тустай.
  }
}

Тохиргоо

initialize дараах сонголтуудыг авна:

| Option | Type | Тайлбар | | --- | --- | --- | | apiKey | string | Заавал өгнө. Hamuga endpoint-үүд рүү x-api-key хэлбэрээр илгээнэ. | | tileUrlTemplate | string | Зөвхөн tile-д зориулсан override. Default нь ${host}/tile/tiles/{z}/{x}/{y}.pbf. | | theme | 'light' \| 'dark' | SDK UI-ийн theme-г тохируулна. | | debug | boolean | SDK дэмжсэн үед debug log идэвхжүүлнэ. | | logLevel | 'none' \| 'debug' \| 'info' \| 'warn' \| 'error' | Logger-ийн дэлгэрэнгүй түвшинг тохируулна. |

Custom style болон tile request

Default map style нь Hamuga-ийн CDN style байна. SDK хуучин tile URL-үүдийг tileUrlTemplate рүү шилжүүлж, зөвхөн тохирсон tile request-д x-api-key нэмнэ. host нь search, POI болон routing-ийн base URL хэвээр байна. Custom transformRequest өгвөл тухайн map-ийн authentication болон tile URL handling-ийг өөрөө хариуцна.

Custom tile endpoint нь browser-оос хүрэх боломжтой бөгөөд шаардлагатай Cross-Origin Resource Sharing (CORS) header-үүдийг зөвшөөрөх ёстой. Tile endpoint private бол server credential-ийг browser-д ил гаргалгүй өөрийн server-ээр proxy хий.

Алдааг оношлох

  • Map хоосон: Map container-т explicit height өгч, hamuga-imap-sdk/dist/hamuga-imap.min.css-ийг import хий (MapLibre style дотор багтсан).
  • Tile ачаалахгүй: API key, gateway, CORS болон browser network panel-ийг шалга. Default tile endpoint нь https://gateway.hamuga.mn/tile/tiles/{z}/{x}/{y}.pbf.
  • Autocomplete container error: HamugaImap.ui.autocomplete(options) дуудахаас өмнө container element үүсгэ.
  • React integration: Map-ийг effect дотор үүсгэж, instance-ийг ref-д хадгал. Component unmount хийхэд map.remove() дууд. Render бүрт шинэ MapLibre map бүү үүсгэ.
  • API error: Async дуудлагыг try/catch-ээр барь, тодорхой төрлийн алдааны классуудыг шалга (үзнэ үү: Алдаа гаралт). SDK gateway-ийн алдааг fake data болгон нуухгүй.

Локал хөгжүүлэлт

npm install
npm run build
# Watch mode
npm run dev

License

Apache-2.0.