{"_id":"@ecoscope/ecoscope-deckgl-extensions","_rev":"4-68143837ad5ff719fa4896e61953ed44","name":"@ecoscope/ecoscope-deckgl-extensions","dist-tags":{"latest":"0.1.1"},"versions":{"0.0.7":{"name":"@ecoscope/ecoscope-deckgl-extensions","version":"0.0.7","author":"","license":"BSD-3-Clause","_id":"@ecoscope/ecoscope-deckgl-extensions@0.0.7","maintainers":[{"name":"atmorling","email":"atmorling@gmail.com"}],"homepage":"https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions#readme","bugs":{"url":"https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions/issues"},"dist":{"shasum":"c946372bbf7f6fca15f93a2e8317b65543ef3968","tarball":"https://registry.npmjs.org/@ecoscope/ecoscope-deckgl-extensions/-/ecoscope-deckgl-extensions-0.0.7.tgz","fileCount":12,"integrity":"sha512-Al5T+eezKZeZFdWHVf7STB2D+2oD7H15hIJmQDoLn4A7891ZNQjbx3zQ+3kYFFohYmXCufQhyJpyV3m/d1N3nA==","signatures":[{"sig":"MEYCIQDyNQLkbvKn9xut+uFZ5BPvchP1hgPn6nhOBKHAA/y/GQIhAPBAXP79hzl2aUoAGLcUB0aJhneq10yIFdNoQ9VcvVNM","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":131885},"main":"index.ts","type":"module","exports":{".":"./dist/bundle.js"},"gitHead":"11e1ba4568676e5eca76049164f8ffae10fdaa07","scripts":{"lint":"eslint src/","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","build-webpack":"rm -rf ./dist && mkdir dist && webpack"},"_npmUser":{"name":"atmorling","email":"atmorling@gmail.com"},"repository":{"url":"git+https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions.git","type":"git"},"_npmVersion":"10.8.2","description":"Custom deck.gl components used by ecoscope","directories":{},"_nodeVersion":"20.20.2","dependencies":{"preact":"^10.26.9","ts-loader":"^9.5.2","html-to-image":"^1.11.13","preact-jsx-runtime":"^1.2.0"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.2.0","css-loader":"^7.1.2","webpack-cli":"^6.0.1","style-loader":"^4.0.0","@deck.gl/core":"^9.2.1","@deck.gl/layers":"^9.2.1","@deck.gl/widgets":"^9.2.1","typescript-eslint":"^8.58.2","@deck.gl/geo-layers":"^9.2.1"},"_npmOperationalInternal":{"tmp":"tmp/ecoscope-deckgl-extensions_0.0.7_1776187303941_0.4843061792472594","host":"s3://npm-registry-packages-npm-production"}},"0.0.8":{"name":"@ecoscope/ecoscope-deckgl-extensions","version":"0.0.8","author":"","license":"BSD-3-Clause","_id":"@ecoscope/ecoscope-deckgl-extensions@0.0.8","maintainers":[{"name":"atmorling","email":"atmorling@gmail.com"}],"homepage":"https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions#readme","bugs":{"url":"https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions/issues"},"dist":{"shasum":"c7255ffa542ecae9e326f7511a93aadde2ac0ede","tarball":"https://registry.npmjs.org/@ecoscope/ecoscope-deckgl-extensions/-/ecoscope-deckgl-extensions-0.0.8.tgz","fileCount":13,"integrity":"sha512-FRF/RPmXdpFPwZzCy+REi110JCUpPxgb9/wLwGLZTaZP2yo+NUkJBSPLxHlt1eJxYWtYltUc0Ka9zUEAbkUV/A==","signatures":[{"sig":"MEUCICGQ1HM6LnladVbd1f1oOCYKkRK65rt8Hp24Gwdbw4AXAiEA6iQnT8011Zbi9mn2NoMCKeXtRp++wTtSE9JpsVC/YKw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ecoscope%2fecoscope-deckgl-extensions@0.0.8","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":143039},"main":"index.ts","type":"module","exports":{".":"./dist/bundle.js"},"gitHead":"a384c3054ef523a7d75d90ad5ff9a49b5c2943d2","scripts":{"lint":"eslint src/","lint:fix":"eslint src/ --fix","typecheck":"tsc --noEmit","build-webpack":"rm -rf ./dist && mkdir dist && webpack"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f999cbb9-dcff-4f16-bb7d-d9203aa3e522"}},"repository":{"url":"git+https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions.git","type":"git"},"_npmVersion":"11.11.0","description":"Custom deck.gl components used by ecoscope","directories":{},"_nodeVersion":"24.14.1","dependencies":{"preact":"^10.26.9","ts-loader":"^9.5.2","html-to-image":"^1.11.13","preact-jsx-runtime":"^1.2.0"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.2.0","css-loader":"^7.1.2","webpack-cli":"^6.0.1","style-loader":"^4.0.0","@deck.gl/core":"^9.2.1","@deck.gl/layers":"^9.2.1","@deck.gl/widgets":"^9.2.1","typescript-eslint":"^8.58.2","@deck.gl/geo-layers":"^9.2.1"},"_npmOperationalInternal":{"tmp":"tmp/ecoscope-deckgl-extensions_0.0.8_1778150251564_0.8085381651895338","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@ecoscope/ecoscope-deckgl-extensions","version":"0.1.0","author":"","license":"BSD-3-Clause","_id":"@ecoscope/ecoscope-deckgl-extensions@0.1.0","maintainers":[{"name":"atmorling","email":"atmorling@gmail.com"}],"homepage":"https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions#readme","bugs":{"url":"https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions/issues"},"dist":{"shasum":"3baa313fbef7cbdeb343b743d68588589ddc94f1","tarball":"https://registry.npmjs.org/@ecoscope/ecoscope-deckgl-extensions/-/ecoscope-deckgl-extensions-0.1.0.tgz","fileCount":10,"integrity":"sha512-TsuoZBs+UDurR2hHb/fdkwx+rm1gBJ8GFYGqIHKeYw2lWcTNKLpa73w9pk9x51ymgfYJJ2OU4fcqNktDAePeGA==","signatures":[{"sig":"MEQCICERrlLqrQpz5wP4yEmoNO0qC79xVyZmHgZjZU2IUFpzAiBu5pkUi4gDpYT7Tngs8oVD2dpweyd0B0C2yQFZYxpwuQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ecoscope%2fecoscope-deckgl-extensions@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":7840662},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./umd":"./dist/bundle.js","./package.json":"./package.json"},"gitHead":"8ae00a2807a65b74526ed16567576254e9ef6661","scripts":{"lint":"eslint src/","build":"rm -rf dist && npm run build:lib && npm run build:bundle","lint:fix":"eslint src/ --fix","build:lib":"tsup src/index.ts --format esm --dts --clean --target esnext --external preact --external @deck.gl/core --external @deck.gl/layers --external @deck.gl/geo-layers --external @deck.gl/widgets --external @deck.gl/aggregation-layers --external @geoarrow/deck.gl-geoarrow --external @geoarrow/geoparquet-wasm --external @loaders.gl/loader-utils --external apache-arrow","typecheck":"tsc --noEmit","build:bundle":"webpack","build-webpack":"npm run build:bundle"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f999cbb9-dcff-4f16-bb7d-d9203aa3e522"}},"repository":{"url":"git+https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions.git","type":"git"},"_npmVersion":"11.13.0","description":"Custom deck.gl components used by ecoscope","directories":{},"_nodeVersion":"24.16.0","dependencies":{"preact":"^10.26.9","html-to-image":"^1.11.13","preact-jsx-runtime":"^1.2.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","eslint":"^10.2.0","ts-loader":"^9.5.2","css-loader":"^7.1.2","webpack-cli":"^6.0.1","apache-arrow":"^21.1.0","style-loader":"^4.0.0","@deck.gl/core":"~9.2.1","@deck.gl/layers":"~9.2.1","@deck.gl/widgets":"~9.2.1","typescript-eslint":"^8.58.2","@deck.gl/geo-layers":"~9.2.1","@loaders.gl/loader-utils":"~4.3.4","@geoarrow/geoparquet-wasm":"^0.2.0-beta.5","@geoarrow/deck.gl-geoarrow":"^0.4.1","@deck.gl/aggregation-layers":"~9.2.1"},"peerDependencies":{"apache-arrow":">=21","@deck.gl/core":"^9.2.0","@deck.gl/layers":"^9.2.0","@deck.gl/widgets":"^9.2.0","@deck.gl/geo-layers":"^9.2.0","@geoarrow/geoparquet-wasm":"^0.2.0-beta.5","@geoarrow/deck.gl-geoarrow":"^0.4.0"},"peerDependenciesMeta":{"@geoarrow/geoparquet-wasm":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/ecoscope-deckgl-extensions_0.1.0_1780400134444_0.25549719243689006","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@ecoscope/ecoscope-deckgl-extensions","version":"0.1.1","type":"module","description":"Custom deck.gl components used by ecoscope","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./umd":"./dist/bundle.js","./package.json":"./package.json"},"scripts":{"build":"rm -rf dist && npm run build:lib && npm run build:bundle","build:lib":"tsup src/index.ts --format esm --dts --clean --target esnext --external preact --external @deck.gl/core --external @deck.gl/layers --external @deck.gl/geo-layers --external @deck.gl/widgets --external @deck.gl/aggregation-layers --external @geoarrow/deck.gl-geoarrow --external @geoarrow/geoparquet-wasm --external @loaders.gl/loader-utils --external apache-arrow","build:bundle":"webpack","build-webpack":"npm run build:bundle","typecheck":"tsc --noEmit","lint":"eslint src/","lint:fix":"eslint src/ --fix"},"author":"","license":"BSD-3-Clause","dependencies":{"html-to-image":"^1.11.13","preact":"^10.26.9","preact-jsx-runtime":"^1.2.0"},"peerDependencies":{"@deck.gl/core":"^9.2.0","@deck.gl/geo-layers":"^9.2.0","@deck.gl/layers":"^9.2.0","@deck.gl/widgets":"^9.2.0","@geoarrow/deck.gl-geoarrow":"^0.4.0","@geoarrow/geoparquet-wasm":"^0.2.0-beta.5","apache-arrow":">=21"},"peerDependenciesMeta":{"@geoarrow/geoparquet-wasm":{"optional":true}},"devDependencies":{"@deck.gl/aggregation-layers":"~9.2.1","@deck.gl/core":"~9.2.1","@deck.gl/geo-layers":"~9.2.1","@deck.gl/layers":"~9.2.1","@deck.gl/widgets":"~9.2.1","@geoarrow/deck.gl-geoarrow":"^0.4.1","@geoarrow/geoparquet-wasm":"^0.2.0-beta.5","@loaders.gl/loader-utils":"~4.3.4","apache-arrow":"^21.1.0","css-loader":"^7.1.2","eslint":"^10.2.0","style-loader":"^4.0.0","ts-loader":"^9.5.2","tsup":"^8.5.1","typescript-eslint":"^8.58.2","webpack-cli":"^6.0.1"},"repository":{"type":"git","url":"git+https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions.git"},"bugs":{"url":"https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions/issues"},"homepage":"https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions#readme","gitHead":"d48b9a7e84a13bb23c5b25669029e51194a05b8d","_id":"@ecoscope/ecoscope-deckgl-extensions@0.1.1","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-BM+TU1/FRyaaHf6N2hiuTptHqfA9ohgl5F0qIPS5T3R0BDs14ZWKiD9aDLNz/yMLuthxtte+kV4/iwUXYoFBEg==","shasum":"4e3a0c2c1f4352d7a798208d4a74f8c77eea0173","tarball":"https://registry.npmjs.org/@ecoscope/ecoscope-deckgl-extensions/-/ecoscope-deckgl-extensions-0.1.1.tgz","fileCount":10,"unpackedSize":7840752,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ecoscope%2fecoscope-deckgl-extensions@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC5t71j7KGNX7ZzIcLrkw7cbtlpkttzXYvPSYUwqCJ0ugIhANu2OvEbxKSGFZDCVjfkpfZDX0Vwzu2MxjcC4sckwlOu"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f999cbb9-dcff-4f16-bb7d-d9203aa3e522"}},"directories":{},"maintainers":[{"name":"atmorling","email":"atmorling@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ecoscope-deckgl-extensions_0.1.1_1786985374283_0.2539948086514714"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-14T17:21:43.804Z","modified":"2026-08-17T16:49:34.828Z","0.0.7":"2026-04-14T17:21:44.119Z","0.0.8":"2026-05-07T10:37:31.733Z","0.1.0":"2026-06-02T11:35:34.654Z","0.1.1":"2026-08-17T16:49:34.495Z"},"bugs":{"url":"https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions/issues"},"license":"BSD-3-Clause","homepage":"https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions#readme","repository":{"type":"git","url":"git+https://github.com/wildlife-dynamics/ecoscope-deckgl-extensions.git"},"description":"Custom deck.gl components used by ecoscope","maintainers":[{"name":"atmorling","email":"atmorling@gmail.com"}],"readme":"# ecoscope-deckgl-extensions\n\nCustom [deck.gl](https://deck.gl/) widgets and layers used by [Ecoscope](https://github.com/wildlife-dynamics/ecoscope). Built on `@deck.gl/core` 9.x and rendered with Preact.\n\nShips two artifacts from one source tree:\n\n- **ESM library** (`dist/index.js` + type declarations) — entry for bundler-based apps (ie Next.js).\n- **UMD bundle** (`dist/bundle.js`) — single-file build intended for pydeck's `customLibraries` script-tag loading. Attaches all exports to `window.EcoscopeDeckglExtensions`.\n\n## Install\n\n```bash\nnpm install @ecoscope/ecoscope-deckgl-extensions\n```\n\n`@deck.gl/*`, `@geoarrow/deck.gl-geoarrow`, and `apache-arrow` are peer dependencies — the consuming app provides them. `@geoarrow/geoparquet-wasm` is an optional peer (only needed if you load `.parquet` data through the GeoArrow layers).\n\n```ts\nimport {\n  NorthArrowWidget,\n  TitleWidget,\n  ScaleWidget,\n  LegendWidget,\n  SaveImageWidget,\n  TooltipWidget,\n  TiledBitmapLayer,\n  GeoArrowPathLayer,\n  GeoArrowScatterplotLayer,\n  GeoArrowPolygonLayer,\n} from '@ecoscope/ecoscope-deckgl-extensions';\n```\n\ndeck.gl is browser-only, so any component that constructs layers/widgets from this package must live behind a `'use client'` boundary (App Router) or be imported dynamically with `ssr: false`.\n\n## Widgets\n\n### `NorthArrowWidget`\nCompass SVG that rotates to match the current viewport. Reads `bearing`/`pitch` on a `WebMercatorViewport`.\n\n```ts\nnew NorthArrowWidget({ placement: 'top-left' });\n```\n\n### `TitleWidget`\nStatic title rendered as an absolutely-positioned overlay on the deck (this is to enable centering and positional overrides above the standard widget-placement quadrants).\n\n```ts\nnew TitleWidget({ id: 'title', title: 'My Map' });\n```\n\n### `ScaleWidget`\nTwo-block map scale bar. Computes distance from the viewport's `metersPerPixel`, and renders either as metric (`m`/`km`) or imperial (`ft`/`mi`) units.\n\n```ts\nnew ScaleWidget({ maxWidth: 300, useImperial: false });\n```\n\n### `LegendWidget`\nRenders one or more legend segments, each with a title and a list of `{ label, color }` swatches.\n\n```ts\nnew LegendWidget({\n  id: 'legend',\n  placement: 'bottom-right',\n  legendValues: [\n    { title: 'Species', values: [{ label: 'Elephant', color: '#aa3' }] },\n  ],\n});\n```\n\n### `SaveImageWidget`\nToolbar button that snapshots the deck canvas and surrounding overlays (inclusive of other widgets) to PNG via `html-to-image` and triggers a `map.png` download. The button itself is filtered out of the capture.\n\n```ts\nnew SaveImageWidget({ label: 'Save as Image' });\n```\n\n### `TooltipWidget`\nInstalls a `getTooltip` handler on the deck that renders a feature's `properties` as an HTML table on hover. Pass `layerColumns` to whitelist which property keys to show per layer. This will override any existing tooltip on the deck it's added to. Exists to allow per layer definition of tooltip data via deck.gl json / Pydeck.\n\n```ts\nnew TooltipWidget({\n  layerColumns: { 'subjects-layer': ['name', 'species'] },\n});\n```\n\n## Layers\n\n### `TiledBitmapLayer`\nA `TileLayer` that renders each tile as a `BitmapLayer`. When a tile finishes loading and a `widgetId` prop is set, it posts a `{ type: 'TileLoaded', widgetId }` message to `window.parent` — used to signal load completion to a host (e.g. a Jupyter widget iframe).\nAllows configuration of a simple tiled raster layer via deck.gl json / Pydeck.\n\n```ts\nnew TiledBitmapLayer({\n  id: 'basemap',\n  data: 'https://tiles.example.com/{z}/{x}/{y}.png',\n  widgetId: 'map-1',\n});\n```\n\n### `GeoArrowPathLayer`, `GeoArrowScatterplotLayer`, `GeoArrowPolygonLayer`\nThin subclasses of the corresponding [`@geoarrow/deck.gl-geoarrow`](https://github.com/geoarrow/deck.gl-geoarrow) layers that add:\n\n- A bundled GeoParquet loader (`.parquet` URLs in `data` are parsed in-browser via `@geoarrow/geoparquet-wasm`, wired in via `defaultProps.loaders` — no global `registerLoaders` call needed).\n- Bare-string column references on `get*` accessors.** Set `getFillColor: \"color_column\"` and the named column is bound directly as a vectorized arrow attribute on the upstream layer. Allows defining accessors in terms of columns via Pydeck.\n\n```ts\nnew GeoArrowScatterplotLayer({\n  id: 'events',\n  data: 'https://example.com/events.parquet',\n  getFillColor: 'fill_color',   // column of FixedSizeList<Uint8>\n  getRadius: 'radius',          // column of Float\n});\n```\n\n## Development\n\n```bash\nnpm run build           # ESM library + UMD bundle to dist/\nnpm run build:lib       # ESM library only (dist/index.js + .d.ts tree)\nnpm run build:bundle    # UMD bundle only (dist/bundle.js) — for pydeck\nnpm run build-webpack   # legacy alias for build:bundle\nnpm run typecheck\nnpm run lint\n```\n","readmeFilename":"README.md"}