Skip to content

chore: version packages#10

Merged
yharby merged 1 commit into
mainfrom
changeset-release/main
Apr 24, 2026
Merged

chore: version packages#10
yharby merged 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@walkthru-earth/objex@1.3.0

Minor Changes

  • 07e1570 Thanks @yharby! - Canonical connection identity and deduplication across every write path.

    • New utils/connection-identity.ts (exported from src/lib/index.ts): connectionIdentityKey, isSameConnectionIdentity, normalizeEndpoint, normalizeProvider, ConnectionIdentityInput. Identity is provider-aware: azureprovider|endpoint|bucket, gcsprovider|bucket (global namespace), s3 with empty endpoint → s3|bucket|region (region is load-bearing for signing), all other S3-compatible providers → provider|normalizedEndpoint|bucket. normalizeEndpoint lowercases host, strips default ports (:443/:80) and trailing slashes, and preserves explicit non-default ports and pathnames so http vs https, :443 vs empty, and trailing-slash drift collapse to one key.
    • connections store: removed findByBucketEndpoint (bucket+endpoint string match, which produced silent duplicates for AWS same-bucket-different-region and custom S3-compat scheme/port drift, and was bypassed entirely by the manual Add Connection dialog). Every write path now dedups through connectionIdentityKey:
      • save(config) returns { id, existed }. On existed: true, the row is reused and credentials from the new config overwrite the old ones.
      • update(id, config) throws the new DuplicateConnectionError when the new identity would collide with a different saved row, so edits can't silently produce phantom duplicates.
      • saveHostConnection(detected) continues to be the auto-detect entry and returns the final id, either reused or newly inserted.
      • New public findByIdentity(input) exposes the same key for callers that need to check without writing.
    • ConnectionDialog surfaces both outcomes: amber "merged into existing" notice on dedup and destructive "already used by X" block on edit collision, with the offending connection's name.
    • Build: svelte-check 0 errors, publint clean, no $lib/ leaks in dist/.
  • 676c792 Thanks @yharby! - Bump the @developmentseed/deck.gl-geotiff family to 0.6.0-alpha.1 and add two new viewers plus a dual-path Zarr renderer. No breaking changes to existing tabs, and CogViewer behavior is unchanged.

    What's new

    • StacMosaicViewer (renamed from SentinelMosaicViewer, wrapped in a new StacTabViewer). ViewerRouter now detects STAC Items / FeatureCollections / Collections / Catalogs via a 256 KB adapter peek (utils/stac.ts::classifyStac) and mounts a tab wrapper with Map / STAC Browser / JSON buttons (URL hash #map / #stac-browser / #code, shareable). The user can always toggle back to the third-party stac-browser iframe. For Collection / Catalog inputs, utils/stac-hydrate.ts::hydrateStacItems walks links[rel=item|child|next] with a 12-way concurrency pool and a 2000-item cap, emitting progressive batches so the MosaicLayer starts rendering after ~1–2s. Each inner COG still runs through selectCogPipeline, so palette-indexed short-circuits, non-uint custom pipelines, LinearRescale, and normalizeCogGeotiff (overview strip + polar bbox clamp) all apply per scene. Shared DecoderPool and createEpsgResolver across every inner source.
    • MultiCogViewer. STAC Item JSON routes here when eo:bands.common_name or MPC/Element 84/AWS asset-key heuristics identify at least the red/green/blue Sentinel-2 bands. Preset dropdown (True Color / False-Color IR / SWIR / Vegetation / Agriculture) drives the v0.6 MultiCOGLayer.composite prop, and a FilterNoDataVal + LinearRescale pipeline (0..0.3 default for L2A reflectance) mask scene edges and stretch contrast.
    • Zarr dual path. utils/zarr.ts::detectGeoZarr inspects hierarchy attributes for the GeoZarr convention (multiscales + spatial + CRS). Matching stores render via @developmentseed/deck.gl-zarr ZarrLayer on MapboxOverlay; anything else falls through to the existing @carbonplan/zarr-layer path with its 10 k-tile guard and numcodecs codec aliases.
    • New utilities. utils/stac.ts (STAC item/FeatureCollection shape checks, Sentinel band extraction, bbox helper). utils/cog.ts gains buildMosaicSourceMeta, buildBandRenderPipeline (composes FilterNoDataVal + LinearRescale in GPU-correct order). utils/zarr.ts gains detectGeoZarr and zarrTileToImageData.
    • CogControls mode prop. Accepts 'single' (default, full band + color-ramp UI) or 'multi' (rescale slider only). MultiCogViewer uses the new mode; existing CogViewer is unchanged.

    Package bumps

    @developmentseed/deck.gl-geotiff, deck.gl-raster, geotiff, proj, epsg: ^0.5.0 → ^0.6.0-alpha.1. New deps: @developmentseed/deck.gl-zarr@^0.6.0-alpha.1 (pulls in @developmentseed/geozarr transitively). zarrita bumped ^0.6.2 → ^0.7.1, forced across the tree via pnpm.overrides so @carbonplan/zarr-layer@^0.4.3 runs on the same major.

    Patches

    patches/@developmentseed__deck.gl-geotiff@0.5.0.patch renamed and re-attached as @0.6.0-alpha.1.patch. Both hunks (proj4 +over antimeridian fix, inferRenderPipeline re-export) still apply unchanged, upstream tickets #366 and PR #374 remain open.

    New patch patches/@carbonplan__zarr-layer@0.4.3.patch replaces two calls to zarr.tryWithConsolidated() with Promise.resolve(baseStore). The helper was removed in zarrita 0.7, and the override above forces 0.7 across the tree, which otherwise surfaced as a runtime (void 0) is not a function inside _onAddAsync when mounting the legacy ZarrLayer. Consolidated metadata (.zmetadata) is still fetched manually by the library's own _loadV2, so skipping the helper is behavior-preserving.

    Vite config

    optimizeDeps.include extended with @developmentseed/deck.gl-zarr and its geozarr + raster-reproject leaves, plus zarrita itself.

  • 4cf01c5 Thanks @yharby! - GPU colormap sprite, histogram slider, and 4-band COG fix.

    GPU Colormap sprite with 107 ramps

    Single-band COGs and mosaics now render through the v0.6 Colormap shader module sampling @developmentseed/deck.gl-raster/gpu-modules/colormaps.png (256x107 RGBA, matplotlib + rio-tiler + cmocean). Switching ramps is a uniform update on colormapIndex, no tile re-decode. The CPU baker normalizes band N into color.r with r = 1 + round(t * 254) and reserves r = 0 as a nodata sentinel so FilterNoDataVal({ value: 0 }) discards those fragments before the ramp sample.

    New helper module utils/colormap-sprite.ts decodes the sprite once per session and caches the uploaded sampler2DArray texture per luma.gl Device via a WeakMap. Exports COLORMAP_INDEX (all 107 names), COLORMAP_NAMES (sorted), loadColormapSprite(), getColormapTexture(device), and spriteBackgroundStyle(name, heightPx) for CSS previews.

    CogControls.svelte previews every ramp by slicing the sprite as a CSS background-image. Curated 10-ramp "pinned" grid (gray, terrain, viridis, magma, turbo, spectral, inferno, plasma, cividis, rdylgn), plus a search field and a scrollable full list of all 107.

    Histogram behind the rescale slider

    selectCogPipeline now accepts an onHistogram?: (bins: Uint32Array) => void callback. The CPU baker emits a 64-bin histogram (HISTOGRAM_BIN_COUNT) built over the tile's valid samples, stored in CogViewer / StacMosaicViewer as $state.raw<Uint32Array> and rendered by CogControls as an SVG bar chart behind the rescale sliders. The active [min, max] window draws as a translucent band so the slider visualizes what it is actually clipping.

    rescaleApplicable now returns true when bandConfig.mode === 'single' in addition to the legacy uint-RGB case. The single-band path builds its pipeline as [Sampler2DArrayPrecision, FilterNoDataVal, LinearRescale?, Colormap], so the slider stretches color.r before the ramp lookup.

    NAIP 4-band opacity fix + dynamic band detection

    needsCustomPipelineForConfig now forces the CPU path for geotiff.count === 4 in RGB mode, so the 4th NAIP band is no longer silently interpreted as alpha by the library-default RGBA pipeline.

    StacMosaicViewer detects band count + SampleFormat dynamically on the first COG that MosaicLayer.getSource resolves (via geotiff.count and cachedTags.sampleFormat), reseeds bandConfig via defaultBandConfig(count, sf), and updates <CogControls bandCount=...> so 4-band imagery exposes all four bands in the picker. Previously the mosaic hard-coded 3 bands.

    Sampler2DArrayPrecision shim

    @developmentseed/deck.gl-raster@0.6.0-alpha.1's Colormap module injects uniform sampler2DArray colormapTexture; without a precision qualifier, which the Apple-GPU path of luma.gl's WebGL2 backend rejects with ERROR: 'sampler2DArray' : No precision specified. Local shim Sampler2DArrayPrecision (in utils/cog.ts) injects precision highp sampler2DArray; at fs:#decl and is chained immediately before Colormap in buildCustomRenderTile. Remove once upstream fixes.

    Dead code removed

    Retired COLOR_RAMP_STOPS, ColorRampId, interpolateRamp, rampToGradientCss, and customRenderTile from utils/cog.ts. All superseded by the sprite path. ColorRampId is now a type alias for ColormapName (all 107 entries).

    objex-utils

    Bump coordinated with the main package via the fixed changeset config. No new re-exports, colormap-sprite.ts is not published because it depends on luma.gl Device / WebGL2. Consumers who want GPU colormap rendering should depend on the full @walkthru-earth/objex package.

  • 439dfd7 Thanks @yharby! - Add stac-geoparquet support.

    • objex-utils: new stac-geoparquet module with pure transforms that any consumer can use: isStacGeoparquetSchema, stacRowToItem, flattenStacBbox, resolveStacAssetHref, pickStacPrimaryAsset, plus StacGeoparquetRow / StacBboxStruct / StacGeoparquetSchemaColumn / StacRowToItemOptions types.
    • objex Svelte lib: ViewerRouter detects stac-geoparquet via hyparquet schema sniff and routes matching .parquet / .geoparquet files to StacTabViewer. A new query/stac-geoparquet.ts helper uses the existing DuckDB engine (presigned URL, single worker, cancellable) to materialize a STAC FeatureCollection in one shot; StacMosaicViewer consumes it through the same buildMosaicSourceMeta + MosaicLayer path as JSON catalogs. StacTabViewer now shows a "Parquet" badge, relabels the last tab as "Table" (mounting TableViewer), and disables the STAC Browser iframe button with a tooltip since Radiant Earth stac-browser is JSON-only. The stac-map DevSeed iframe handles parquet on its own, so its button is unchanged.
  • 4cf01c5 Thanks @yharby! - STAC mosaic pixel inspection and stricter STAC JSON routing.

    Mosaic pixel inspection + info panel

    StacMosaicViewer now exposes the same Info button and pixel-inspection overlay that CogViewer has. Clicking a pixel inside a STAC Catalog / Collection / ItemCollection / stac-geoparquet tab surfaces the sampled band values plus the matching source id, and the info panel lists source count, detected band count, data type (captured as buildDataTypeLabel(sampleFormat, bitsPerSample) on the first resolved COG), and union bounds.

    A geotiffCache: Map<string, Promise<GeoTIFF>> is populated inside getSource and reused both for MosaicLayer rebuilds and for the map-click handler, so clicks do not trigger a second HTTP fetch. The click handler reverse-iterates itemsRef to match mosaic z-order, finds the topmost source whose bbox contains the click, and calls readPixelAtLngLat(...) against that source's cached GeoTIFF.

    New translations stac.mosaicInfo and stac.mosaicSourcesLabel for English and Arabic.

    Stop routing plain JSON through StacTabViewer

    ViewerRouter::detectStac now propagates classifyStac(parsed)'s { kind: 'none' } result in both the 256 KB peek branch and the full-read fallback. Previously any JSON that parsed returned { kind: 'stac', classified: { kind: 'none' } }, which still mounted StacTabViewer and exposed the stac-map and STAC Browser buttons on files that were not STAC at all (including GeoJSON FeatureCollections that fail the STAC shape checks). Plain JSON now falls through to CodeViewer as intended.

@walkthru-earth/objex-utils@1.3.0

Minor Changes

  • 676c792 Thanks @yharby! - Bump the @developmentseed/deck.gl-geotiff family to 0.6.0-alpha.1 and add two new viewers plus a dual-path Zarr renderer. No breaking changes to existing tabs, and CogViewer behavior is unchanged.

    What's new

    • StacMosaicViewer (renamed from SentinelMosaicViewer, wrapped in a new StacTabViewer). ViewerRouter now detects STAC Items / FeatureCollections / Collections / Catalogs via a 256 KB adapter peek (utils/stac.ts::classifyStac) and mounts a tab wrapper with Map / STAC Browser / JSON buttons (URL hash #map / #stac-browser / #code, shareable). The user can always toggle back to the third-party stac-browser iframe. For Collection / Catalog inputs, utils/stac-hydrate.ts::hydrateStacItems walks links[rel=item|child|next] with a 12-way concurrency pool and a 2000-item cap, emitting progressive batches so the MosaicLayer starts rendering after ~1–2s. Each inner COG still runs through selectCogPipeline, so palette-indexed short-circuits, non-uint custom pipelines, LinearRescale, and normalizeCogGeotiff (overview strip + polar bbox clamp) all apply per scene. Shared DecoderPool and createEpsgResolver across every inner source.
    • MultiCogViewer. STAC Item JSON routes here when eo:bands.common_name or MPC/Element 84/AWS asset-key heuristics identify at least the red/green/blue Sentinel-2 bands. Preset dropdown (True Color / False-Color IR / SWIR / Vegetation / Agriculture) drives the v0.6 MultiCOGLayer.composite prop, and a FilterNoDataVal + LinearRescale pipeline (0..0.3 default for L2A reflectance) mask scene edges and stretch contrast.
    • Zarr dual path. utils/zarr.ts::detectGeoZarr inspects hierarchy attributes for the GeoZarr convention (multiscales + spatial + CRS). Matching stores render via @developmentseed/deck.gl-zarr ZarrLayer on MapboxOverlay; anything else falls through to the existing @carbonplan/zarr-layer path with its 10 k-tile guard and numcodecs codec aliases.
    • New utilities. utils/stac.ts (STAC item/FeatureCollection shape checks, Sentinel band extraction, bbox helper). utils/cog.ts gains buildMosaicSourceMeta, buildBandRenderPipeline (composes FilterNoDataVal + LinearRescale in GPU-correct order). utils/zarr.ts gains detectGeoZarr and zarrTileToImageData.
    • CogControls mode prop. Accepts 'single' (default, full band + color-ramp UI) or 'multi' (rescale slider only). MultiCogViewer uses the new mode; existing CogViewer is unchanged.

    Package bumps

    @developmentseed/deck.gl-geotiff, deck.gl-raster, geotiff, proj, epsg: ^0.5.0 → ^0.6.0-alpha.1. New deps: @developmentseed/deck.gl-zarr@^0.6.0-alpha.1 (pulls in @developmentseed/geozarr transitively). zarrita bumped ^0.6.2 → ^0.7.1, forced across the tree via pnpm.overrides so @carbonplan/zarr-layer@^0.4.3 runs on the same major.

    Patches

    patches/@developmentseed__deck.gl-geotiff@0.5.0.patch renamed and re-attached as @0.6.0-alpha.1.patch. Both hunks (proj4 +over antimeridian fix, inferRenderPipeline re-export) still apply unchanged, upstream tickets #366 and PR #374 remain open.

    New patch patches/@carbonplan__zarr-layer@0.4.3.patch replaces two calls to zarr.tryWithConsolidated() with Promise.resolve(baseStore). The helper was removed in zarrita 0.7, and the override above forces 0.7 across the tree, which otherwise surfaced as a runtime (void 0) is not a function inside _onAddAsync when mounting the legacy ZarrLayer. Consolidated metadata (.zmetadata) is still fetched manually by the library's own _loadV2, so skipping the helper is behavior-preserving.

    Vite config

    optimizeDeps.include extended with @developmentseed/deck.gl-zarr and its geozarr + raster-reproject leaves, plus zarrita itself.

  • 4cf01c5 Thanks @yharby! - GPU colormap sprite, histogram slider, and 4-band COG fix.

    GPU Colormap sprite with 107 ramps

    Single-band COGs and mosaics now render through the v0.6 Colormap shader module sampling @developmentseed/deck.gl-raster/gpu-modules/colormaps.png (256x107 RGBA, matplotlib + rio-tiler + cmocean). Switching ramps is a uniform update on colormapIndex, no tile re-decode. The CPU baker normalizes band N into color.r with r = 1 + round(t * 254) and reserves r = 0 as a nodata sentinel so FilterNoDataVal({ value: 0 }) discards those fragments before the ramp sample.

    New helper module utils/colormap-sprite.ts decodes the sprite once per session and caches the uploaded sampler2DArray texture per luma.gl Device via a WeakMap. Exports COLORMAP_INDEX (all 107 names), COLORMAP_NAMES (sorted), loadColormapSprite(), getColormapTexture(device), and spriteBackgroundStyle(name, heightPx) for CSS previews.

    CogControls.svelte previews every ramp by slicing the sprite as a CSS background-image. Curated 10-ramp "pinned" grid (gray, terrain, viridis, magma, turbo, spectral, inferno, plasma, cividis, rdylgn), plus a search field and a scrollable full list of all 107.

    Histogram behind the rescale slider

    selectCogPipeline now accepts an onHistogram?: (bins: Uint32Array) => void callback. The CPU baker emits a 64-bin histogram (HISTOGRAM_BIN_COUNT) built over the tile's valid samples, stored in CogViewer / StacMosaicViewer as $state.raw<Uint32Array> and rendered by CogControls as an SVG bar chart behind the rescale sliders. The active [min, max] window draws as a translucent band so the slider visualizes what it is actually clipping.

    rescaleApplicable now returns true when bandConfig.mode === 'single' in addition to the legacy uint-RGB case. The single-band path builds its pipeline as [Sampler2DArrayPrecision, FilterNoDataVal, LinearRescale?, Colormap], so the slider stretches color.r before the ramp lookup.

    NAIP 4-band opacity fix + dynamic band detection

    needsCustomPipelineForConfig now forces the CPU path for geotiff.count === 4 in RGB mode, so the 4th NAIP band is no longer silently interpreted as alpha by the library-default RGBA pipeline.

    StacMosaicViewer detects band count + SampleFormat dynamically on the first COG that MosaicLayer.getSource resolves (via geotiff.count and cachedTags.sampleFormat), reseeds bandConfig via defaultBandConfig(count, sf), and updates <CogControls bandCount=...> so 4-band imagery exposes all four bands in the picker. Previously the mosaic hard-coded 3 bands.

    Sampler2DArrayPrecision shim

    @developmentseed/deck.gl-raster@0.6.0-alpha.1's Colormap module injects uniform sampler2DArray colormapTexture; without a precision qualifier, which the Apple-GPU path of luma.gl's WebGL2 backend rejects with ERROR: 'sampler2DArray' : No precision specified. Local shim Sampler2DArrayPrecision (in utils/cog.ts) injects precision highp sampler2DArray; at fs:#decl and is chained immediately before Colormap in buildCustomRenderTile. Remove once upstream fixes.

    Dead code removed

    Retired COLOR_RAMP_STOPS, ColorRampId, interpolateRamp, rampToGradientCss, and customRenderTile from utils/cog.ts. All superseded by the sprite path. ColorRampId is now a type alias for ColormapName (all 107 entries).

    objex-utils

    Bump coordinated with the main package via the fixed changeset config. No new re-exports, colormap-sprite.ts is not published because it depends on luma.gl Device / WebGL2. Consumers who want GPU colormap rendering should depend on the full @walkthru-earth/objex package.

  • 439dfd7 Thanks @yharby! - Add stac-geoparquet support.

    • objex-utils: new stac-geoparquet module with pure transforms that any consumer can use: isStacGeoparquetSchema, stacRowToItem, flattenStacBbox, resolveStacAssetHref, pickStacPrimaryAsset, plus StacGeoparquetRow / StacBboxStruct / StacGeoparquetSchemaColumn / StacRowToItemOptions types.
    • objex Svelte lib: ViewerRouter detects stac-geoparquet via hyparquet schema sniff and routes matching .parquet / .geoparquet files to StacTabViewer. A new query/stac-geoparquet.ts helper uses the existing DuckDB engine (presigned URL, single worker, cancellable) to materialize a STAC FeatureCollection in one shot; StacMosaicViewer consumes it through the same buildMosaicSourceMeta + MosaicLayer path as JSON catalogs. StacTabViewer now shows a "Parquet" badge, relabels the last tab as "Table" (mounting TableViewer), and disables the STAC Browser iframe button with a tooltip since Radiant Earth stac-browser is JSON-only. The stac-map DevSeed iframe handles parquet on its own, so its button is unchanged.

@yharby yharby merged commit 36ce57b into main Apr 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant