@walkthru-earth/objex-utils 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -39
- package/dist/index.cjs +48 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -8
- package/dist/index.d.ts +65 -8
- package/dist/index.js +44 -5
- package/dist/index.js.map +1 -1
- package/docs/README.md +102 -0
- package/docs/cog.md +303 -0
- package/docs/errors.md +34 -0
- package/docs/file-sort.md +67 -0
- package/docs/file-types.md +141 -0
- package/docs/formatting.md +192 -0
- package/docs/geometry.md +198 -0
- package/docs/local-storage.md +51 -0
- package/docs/markdown-sql.md +109 -0
- package/docs/parquet-metadata.md +133 -0
- package/docs/query-engine.md +140 -0
- package/docs/storage.md +251 -0
- package/docs/types-constants.md +173 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -3,51 +3,50 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@walkthru-earth/objex-utils)
|
|
4
4
|
[](https://creativecommons.org/licenses/by/4.0/)
|
|
5
5
|
|
|
6
|
-
Pure TypeScript utilities extracted from [objex](https://github.com/walkthru-earth/objex)
|
|
6
|
+
Pure TypeScript utilities extracted from [objex](https://github.com/walkthru-earth/objex). Zero Svelte dependency. Works with any JS framework or Node 18+.
|
|
7
|
+
|
|
8
|
+
Built for high-performance geospatial pipelines: WKB parsing, GeoArrow table construction, GeoParquet footer reading via range requests, cloud URL parsing, and a 200+ extension file-type registry.
|
|
7
9
|
|
|
8
10
|
## Install
|
|
9
11
|
|
|
10
12
|
```bash
|
|
11
13
|
pnpm add @walkthru-earth/objex-utils
|
|
14
|
+
# or
|
|
15
|
+
npm install @walkthru-earth/objex-utils
|
|
12
16
|
```
|
|
13
17
|
|
|
14
|
-
##
|
|
18
|
+
## At a glance
|
|
15
19
|
|
|
16
20
|
```ts
|
|
17
21
|
import {
|
|
18
|
-
// WKB /
|
|
22
|
+
// WKB / GeoArrow
|
|
19
23
|
parseWKB,
|
|
20
24
|
findGeoColumn,
|
|
21
25
|
buildGeoArrowTables,
|
|
22
26
|
|
|
23
|
-
//
|
|
24
|
-
parseStorageUrl,
|
|
25
|
-
looksLikeUrl,
|
|
26
|
-
|
|
27
|
-
// Parquet metadata
|
|
27
|
+
// Parquet metadata (hyparquet, range requests)
|
|
28
28
|
readParquetMetadata,
|
|
29
29
|
extractEpsgFromGeoMeta,
|
|
30
30
|
extractBounds,
|
|
31
31
|
|
|
32
|
-
//
|
|
32
|
+
// Storage URLs
|
|
33
|
+
parseStorageUrl,
|
|
34
|
+
resolveCloudUrl,
|
|
35
|
+
looksLikeUrl,
|
|
36
|
+
|
|
37
|
+
// File-type registry
|
|
33
38
|
getFileTypeInfo,
|
|
34
39
|
getViewerKind,
|
|
35
|
-
|
|
40
|
+
getDuckDbReadFn,
|
|
36
41
|
isQueryable,
|
|
37
42
|
|
|
38
|
-
// Formatting
|
|
43
|
+
// Formatting / classification / hex / CSV / JSON
|
|
39
44
|
formatFileSize,
|
|
40
|
-
formatDate,
|
|
41
45
|
formatValue,
|
|
42
|
-
jsonReplacerBigInt,
|
|
43
|
-
|
|
44
|
-
// Column types
|
|
45
46
|
classifyType,
|
|
46
|
-
typeColor,
|
|
47
|
-
typeLabel,
|
|
48
|
-
|
|
49
|
-
// Hex dump
|
|
50
47
|
generateHexDump,
|
|
48
|
+
serializeToCsv,
|
|
49
|
+
serializeToJson,
|
|
51
50
|
|
|
52
51
|
// Error handling
|
|
53
52
|
handleLoadError,
|
|
@@ -59,33 +58,41 @@ import {
|
|
|
59
58
|
} from '@walkthru-earth/objex-utils';
|
|
60
59
|
```
|
|
61
60
|
|
|
62
|
-
##
|
|
61
|
+
## Documentation
|
|
62
|
+
|
|
63
|
+
Full per-module developer reference lives in [`docs/`](./docs/README.md). Each page lists the exact TypeScript signature, parameter semantics, return shape, peer-dependency requirements, and non-obvious behavior.
|
|
64
|
+
|
|
65
|
+
| Page | Covers |
|
|
66
|
+
|------|--------|
|
|
67
|
+
| [`docs/geometry.md`](./docs/geometry.md) | WKB parser, GeoArrow builder, geometry-column detection |
|
|
68
|
+
| [`docs/cog.md`](./docs/cog.md) | Cloud-Optimized GeoTIFF pipeline helpers, band configs, color ramps |
|
|
69
|
+
| [`docs/parquet-metadata.md`](./docs/parquet-metadata.md) | `readParquetMetadata` + CRS / bounds / geometry-type extractors |
|
|
70
|
+
| [`docs/storage.md`](./docs/storage.md) | URL parsing, provider registry, `StorageAdapter`, `UrlAdapter` |
|
|
71
|
+
| [`docs/query-engine.md`](./docs/query-engine.md) | `QueryEngine` interface + handle / result types |
|
|
72
|
+
| [`docs/file-types.md`](./docs/file-types.md) | File-type registry: `getFileTypeInfo`, `getViewerKind`, `getDuckDbReadFn`, … |
|
|
73
|
+
| [`docs/formatting.md`](./docs/formatting.md) | Display formatters, column-type classification, hex dump, CSV/JSON export |
|
|
74
|
+
| [`docs/file-sort.md`](./docs/file-sort.md) | `sortFileEntries`, `toggleSortField` |
|
|
75
|
+
| [`docs/markdown-sql.md`](./docs/markdown-sql.md) | Markdown + SQL block parsing (Evidence-compatible) |
|
|
76
|
+
| [`docs/local-storage.md`](./docs/local-storage.md) | SSR-safe `loadFromStorage` / `persistToStorage` |
|
|
77
|
+
| [`docs/errors.md`](./docs/errors.md) | `handleLoadError` |
|
|
78
|
+
| [`docs/types-constants.md`](./docs/types-constants.md) | `Connection`, `Tab`, `FileEntry`, `WriteResult`, `Theme`, shared constants |
|
|
63
79
|
|
|
64
|
-
|
|
65
|
-
|--------|-------------|
|
|
66
|
-
| `parseWKB()` | Parse WKB binary into coordinates with geometry type classification |
|
|
67
|
-
| `findGeoColumn()` | 5-priority heuristic to detect geometry columns in tabular data |
|
|
68
|
-
| `buildGeoArrowTables()` | Convert WKB arrays to GeoArrow tables for deck.gl rendering |
|
|
69
|
-
| `parseStorageUrl()` | Parse S3/GCS/Azure/R2 URLs into provider, bucket, key |
|
|
70
|
-
| `readParquetMetadata()` | Read Parquet file metadata via HTTP range requests (hyparquet) |
|
|
71
|
-
| `getFileTypeInfo()` | Map file extensions to viewer kind, category, icon, and MIME type |
|
|
72
|
-
| `formatFileSize()` | Human-readable file sizes (1024-based: KB, MB, GB) |
|
|
73
|
-
| `formatValue()` | Format any value for display (handles BigInt, Date, objects, null) |
|
|
74
|
-
| `generateHexDump()` | Generate hex dump rows from binary data |
|
|
75
|
-
| `classifyType()` | Classify SQL/Arrow column types into categories |
|
|
76
|
-
| `handleLoadError()` | Normalize errors, silently skip AbortError |
|
|
77
|
-
| `WGS84_CODES` | Set of EPSG codes considered WGS84 (4326, 4979) |
|
|
80
|
+
## Optional peer dependencies
|
|
78
81
|
|
|
79
|
-
|
|
82
|
+
Heavy dependencies are **optional** peers. Install only what you use.
|
|
80
83
|
|
|
81
|
-
|
|
84
|
+
| Peer | Required by |
|
|
85
|
+
|------|-------------|
|
|
86
|
+
| `apache-arrow >=14` | `buildGeoArrowTables` |
|
|
87
|
+
| `hyparquet >=1.25` | `readParquetMetadata` and friends |
|
|
88
|
+
| `hyparquet-compressors >=1.1` | SNAPPY / ZSTD / GZIP / LZ4 / BROTLI support in `readParquetMetadata` |
|
|
89
|
+
| `yaml >=2` | `parseMarkdownDocument` (lazy-loaded — only when frontmatter is present) |
|
|
82
90
|
|
|
83
|
-
|
|
84
|
-
- `hyparquet` + `hyparquet-compressors` — required for `readParquetMetadata()`
|
|
91
|
+
As of v1.2 the `yaml` dependency is imported dynamically inside `parseMarkdownDocument`. Consumers who never call that function do not need `yaml` at all. Before v1.2 the bundle failed to load without `yaml` even for unrelated imports.
|
|
85
92
|
|
|
86
93
|
## Related
|
|
87
94
|
|
|
88
|
-
- [`@walkthru-earth/objex`](https://www.npmjs.com/package/@walkthru-earth/objex) — Full Svelte 5 component library with viewers, stores, and query engine
|
|
95
|
+
- [`@walkthru-earth/objex`](https://www.npmjs.com/package/@walkthru-earth/objex) — Full Svelte 5 component library with viewers, stores, and query engine.
|
|
89
96
|
|
|
90
97
|
## License
|
|
91
98
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
require('@developmentseed/epsg/all');
|
|
4
|
+
require('@developmentseed/epsg/all.csv.gz?url');
|
|
5
|
+
require('@developmentseed/geotiff');
|
|
6
|
+
require('@developmentseed/proj');
|
|
7
|
+
require('proj4');
|
|
3
8
|
var apacheArrow = require('apache-arrow');
|
|
4
|
-
var YAML = require('yaml');
|
|
5
|
-
|
|
6
|
-
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
-
|
|
8
|
-
var YAML__default = /*#__PURE__*/_interopDefault(YAML);
|
|
9
9
|
|
|
10
10
|
// ../../src/lib/constants.ts
|
|
11
11
|
var STORAGE_KEYS = {
|
|
@@ -14,7 +14,7 @@ var STORAGE_KEYS = {
|
|
|
14
14
|
QUERY_HISTORY: "obstore-explore-query-history"
|
|
15
15
|
};
|
|
16
16
|
var WGS84_CODES = /* @__PURE__ */ new Set([4326, 4979]);
|
|
17
|
-
var DEFAULT_TARGET_CRS = "
|
|
17
|
+
var DEFAULT_TARGET_CRS = "OGC:CRS84";
|
|
18
18
|
var DUCKDB_INIT_TIMEOUT_MS = 3e4;
|
|
19
19
|
var MAX_QUERY_HISTORY_ENTRIES = 200;
|
|
20
20
|
var SQL_PREVIEW_LENGTH = 120;
|
|
@@ -894,6 +894,16 @@ var EXTENSIONS = {
|
|
|
894
894
|
duckdbReadFn: null,
|
|
895
895
|
mimeType: "application/octet-stream"
|
|
896
896
|
},
|
|
897
|
+
".ducklake": {
|
|
898
|
+
icon: "Database",
|
|
899
|
+
color: "text-teal-600 dark:text-teal-400",
|
|
900
|
+
label: "DuckLake",
|
|
901
|
+
category: "database",
|
|
902
|
+
viewer: "database",
|
|
903
|
+
queryable: true,
|
|
904
|
+
duckdbReadFn: null,
|
|
905
|
+
mimeType: "application/octet-stream"
|
|
906
|
+
},
|
|
897
907
|
".sqlite": {
|
|
898
908
|
icon: "Database",
|
|
899
909
|
color: "text-sky-600 dark:text-sky-400",
|
|
@@ -1041,7 +1051,7 @@ function buildDuckDbSource(pathOrExt, url) {
|
|
|
1041
1051
|
const readFn = EXTENSIONS[ext]?.duckdbReadFn ?? "read_parquet";
|
|
1042
1052
|
return `${readFn}('${url}')`;
|
|
1043
1053
|
}
|
|
1044
|
-
var CLOUD_NATIVE_EXTS = /* @__PURE__ */ new Set([".parquet", ".geoparquet", ".gpq", ".gparquet"]);
|
|
1054
|
+
var CLOUD_NATIVE_EXTS = /* @__PURE__ */ new Set([".parquet", ".geoparquet", ".gpq", ".gparquet", ".ducklake"]);
|
|
1045
1055
|
function isCloudNativeFormat(pathOrExt) {
|
|
1046
1056
|
const ext = pathOrExt.includes(".") ? `.${pathOrExt.split(".").pop().toLowerCase()}` : "";
|
|
1047
1057
|
return CLOUD_NATIVE_EXTS.has(ext);
|
|
@@ -1438,6 +1448,28 @@ function resolveCloudUrl(url) {
|
|
|
1438
1448
|
}
|
|
1439
1449
|
return url;
|
|
1440
1450
|
}
|
|
1451
|
+
var SF_LABELS = {
|
|
1452
|
+
1: "uint",
|
|
1453
|
+
2: "int",
|
|
1454
|
+
3: "float",
|
|
1455
|
+
4: "void",
|
|
1456
|
+
5: "complex int",
|
|
1457
|
+
6: "complex float"
|
|
1458
|
+
};
|
|
1459
|
+
function safeClamp(v, lo, hi, fallback) {
|
|
1460
|
+
return Number.isFinite(v) ? Math.max(lo, Math.min(hi, v)) : fallback;
|
|
1461
|
+
}
|
|
1462
|
+
function clampBounds(b) {
|
|
1463
|
+
return {
|
|
1464
|
+
west: safeClamp(b.west, -180, 180, -180),
|
|
1465
|
+
south: safeClamp(b.south, -85.051129, 85.051129, -85.051129),
|
|
1466
|
+
east: safeClamp(b.east, -180, 180, 180),
|
|
1467
|
+
north: safeClamp(b.north, -85.051129, 85.051129, 85.051129)
|
|
1468
|
+
};
|
|
1469
|
+
}
|
|
1470
|
+
function buildDataTypeLabel(sampleFormat, bitsPerSample) {
|
|
1471
|
+
return `${SF_LABELS[sampleFormat] ?? `sf${sampleFormat}`}${bitsPerSample ?? ""}`;
|
|
1472
|
+
}
|
|
1441
1473
|
|
|
1442
1474
|
// ../../src/lib/utils/column-types.ts
|
|
1443
1475
|
var NUMBER_TYPES = [
|
|
@@ -2289,13 +2321,16 @@ function persistToStorage(key, value) {
|
|
|
2289
2321
|
} catch {
|
|
2290
2322
|
}
|
|
2291
2323
|
}
|
|
2292
|
-
|
|
2324
|
+
|
|
2325
|
+
// ../../src/lib/utils/markdown-sql.ts
|
|
2326
|
+
async function parseMarkdownDocument(markdown) {
|
|
2293
2327
|
let frontmatter = {};
|
|
2294
2328
|
let content = markdown;
|
|
2295
2329
|
const fmMatch = markdown.match(/^---\n([\s\S]*?)\n---\n/);
|
|
2296
2330
|
if (fmMatch) {
|
|
2297
2331
|
try {
|
|
2298
|
-
|
|
2332
|
+
const { default: YAML } = await import('yaml');
|
|
2333
|
+
frontmatter = YAML.parse(fmMatch[1]) || {};
|
|
2299
2334
|
} catch {
|
|
2300
2335
|
}
|
|
2301
2336
|
content = markdown.slice(fmMatch[0].length);
|
|
@@ -3067,15 +3102,18 @@ exports.MAX_QUERY_HISTORY_ENTRIES = MAX_QUERY_HISTORY_ENTRIES;
|
|
|
3067
3102
|
exports.PROVIDERS = PROVIDERS;
|
|
3068
3103
|
exports.PROVIDER_IDS = PROVIDER_IDS;
|
|
3069
3104
|
exports.QueryCancelledError = QueryCancelledError;
|
|
3105
|
+
exports.SF_LABELS = SF_LABELS;
|
|
3070
3106
|
exports.SQL_PREVIEW_LENGTH = SQL_PREVIEW_LENGTH;
|
|
3071
3107
|
exports.STORAGE_KEYS = STORAGE_KEYS;
|
|
3072
3108
|
exports.UrlAdapter = UrlAdapter;
|
|
3073
3109
|
exports.VIEWER_DIR_EXTENSIONS = VIEWER_DIR_EXTENSIONS;
|
|
3074
3110
|
exports.WGS84_CODES = WGS84_CODES;
|
|
3111
|
+
exports.buildDataTypeLabel = buildDataTypeLabel;
|
|
3075
3112
|
exports.buildDuckDbSource = buildDuckDbSource;
|
|
3076
3113
|
exports.buildEndpointFromTemplate = buildEndpointFromTemplate;
|
|
3077
3114
|
exports.buildGeoArrowTables = buildGeoArrowTables;
|
|
3078
3115
|
exports.buildProviderBaseUrl = buildProviderBaseUrl;
|
|
3116
|
+
exports.clampBounds = clampBounds;
|
|
3079
3117
|
exports.classifyType = classifyType;
|
|
3080
3118
|
exports.describeParseResult = describeParseResult;
|
|
3081
3119
|
exports.escapeCsvField = escapeCsvField;
|
|
@@ -3111,6 +3149,7 @@ exports.parseWKB = parseWKB;
|
|
|
3111
3149
|
exports.persistToStorage = persistToStorage;
|
|
3112
3150
|
exports.readParquetMetadata = readParquetMetadata;
|
|
3113
3151
|
exports.resolveCloudUrl = resolveCloudUrl;
|
|
3152
|
+
exports.safeClamp = safeClamp;
|
|
3114
3153
|
exports.safeDecodeURIComponent = safeDecodeURIComponent;
|
|
3115
3154
|
exports.serializeToCsv = serializeToCsv;
|
|
3116
3155
|
exports.serializeToJson = serializeToJson;
|