@walkthru-earth/objex 1.2.0 → 1.2.1
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/dist/components/browser/FileTreeSidebar.svelte +1 -1
- package/dist/components/layout/Sidebar.svelte +27 -0
- package/dist/components/viewers/ArchiveViewer.svelte +4 -4
- package/dist/components/viewers/CodeViewer.svelte +21 -5
- package/dist/components/viewers/CogViewer.svelte +21 -3
- package/dist/components/viewers/CopcViewer.svelte +20 -2
- package/dist/components/viewers/FlatGeobufViewer.svelte +15 -9
- package/dist/components/viewers/PmtilesViewer.svelte +2 -2
- package/dist/components/viewers/StacMapViewer.svelte +25 -9
- package/dist/components/viewers/TableViewer.svelte +50 -21
- package/dist/components/viewers/ZarrMapViewer.svelte +4 -4
- package/dist/components/viewers/ZarrViewer.svelte +2 -2
- package/dist/components/viewers/pmtiles/PmtilesMapView.svelte +0 -1
- package/dist/i18n/ar.js +1 -0
- package/dist/i18n/en.js +1 -0
- package/dist/query/index.d.ts +1 -1
- package/dist/query/index.js +1 -1
- package/dist/query/source.d.ts +12 -0
- package/dist/query/source.js +25 -8
- package/dist/query/wasm.js +130 -23
- package/dist/storage/adapter.d.ts +9 -0
- package/dist/storage/adapter.js +13 -1
- package/dist/storage/browser-azure.d.ts +1 -1
- package/dist/storage/browser-azure.js +4 -0
- package/dist/storage/browser-cloud.d.ts +1 -1
- package/dist/storage/browser-cloud.js +7 -0
- package/dist/storage/presign.d.ts +13 -0
- package/dist/storage/presign.js +55 -0
- package/dist/storage/providers.d.ts +6 -0
- package/dist/storage/providers.js +13 -2
- package/dist/stores/browser.svelte.d.ts +2 -0
- package/dist/stores/browser.svelte.js +17 -1
- package/dist/utils/url.d.ts +13 -0
- package/dist/utils/url.js +36 -0
- package/dist/utils/wkb.js +22 -8
- package/package.json +1 -1
package/dist/utils/url.d.ts
CHANGED
|
@@ -4,6 +4,12 @@ import type { Tab } from '../types.js';
|
|
|
4
4
|
* Works for any viewer that needs an HTTP-accessible URL (COG, PMTiles, Zarr, etc.)
|
|
5
5
|
*/
|
|
6
6
|
export declare function buildHttpsUrl(tab: Tab): string;
|
|
7
|
+
/**
|
|
8
|
+
* Async counterpart of `buildHttpsUrl`. For `signed-s3` connections, returns a
|
|
9
|
+
* presigned HTTPS URL (SigV4 query-string auth). For public or SAS connections
|
|
10
|
+
* it returns the same URL as the sync version.
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildHttpsUrlAsync(tab: Tab, expiresIn?: number): Promise<string>;
|
|
7
13
|
/**
|
|
8
14
|
* Build a provider-native protocol URL (s3://bucket/path, sj://bucket/path, etc.).
|
|
9
15
|
*/
|
|
@@ -21,6 +27,13 @@ export declare function buildStorageUrl(tab: Tab): string;
|
|
|
21
27
|
* (e.g. Arabic filenames `%D9%85` → `%25D9%2585`).
|
|
22
28
|
*/
|
|
23
29
|
export declare function buildDuckDbUrl(tab: Tab): string;
|
|
30
|
+
/**
|
|
31
|
+
* Async counterpart of `buildDuckDbUrl`. Returns a presigned HTTPS URL for
|
|
32
|
+
* `signed-s3` connections so DuckDB httpfs can fetch with `Range` only, no
|
|
33
|
+
* `Authorization` preflight (which breaks on GCS's S3-compat endpoint when
|
|
34
|
+
* the bucket CORS `responseHeader` list desyncs from the browser's request).
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildDuckDbUrlAsync(tab: Tab, expiresIn?: number): Promise<string>;
|
|
24
37
|
/**
|
|
25
38
|
* True when any HTTP client (fetch/img/video/deck.gl/COG/Zarr/PMTiles) can
|
|
26
39
|
* load the tab's file directly via its HTTPS URL. False when SigV4 signing
|
package/dist/utils/url.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { presignHttpsUrl } from '../storage/presign.js';
|
|
1
2
|
import { buildProviderBaseUrl, isPubliclyStreamable } from '../storage/providers.js';
|
|
2
3
|
import { connections } from '../stores/connections.svelte.js';
|
|
3
4
|
import { credentialStore } from '../stores/credentials.svelte.js';
|
|
@@ -20,6 +21,15 @@ export function buildHttpsUrl(tab) {
|
|
|
20
21
|
}
|
|
21
22
|
return `${buildProviderBaseUrl(conn.provider, conn.endpoint, conn.bucket, conn.region)}/${cleanPath}`;
|
|
22
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Async counterpart of `buildHttpsUrl`. For `signed-s3` connections, returns a
|
|
26
|
+
* presigned HTTPS URL (SigV4 query-string auth). For public or SAS connections
|
|
27
|
+
* it returns the same URL as the sync version.
|
|
28
|
+
*/
|
|
29
|
+
export async function buildHttpsUrlAsync(tab, expiresIn) {
|
|
30
|
+
const presigned = await tryPresignTab(tab, expiresIn);
|
|
31
|
+
return presigned ?? buildHttpsUrl(tab);
|
|
32
|
+
}
|
|
23
33
|
/**
|
|
24
34
|
* Build a provider-native protocol URL (s3://bucket/path, sj://bucket/path, etc.).
|
|
25
35
|
*/
|
|
@@ -53,6 +63,32 @@ export function buildDuckDbUrl(tab) {
|
|
|
53
63
|
const rawPath = safeDecodeURIComponent(tab.path.replace(/^\//, ''));
|
|
54
64
|
return `s3://${conn.bucket}/${rawPath}`;
|
|
55
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Async counterpart of `buildDuckDbUrl`. Returns a presigned HTTPS URL for
|
|
68
|
+
* `signed-s3` connections so DuckDB httpfs can fetch with `Range` only, no
|
|
69
|
+
* `Authorization` preflight (which breaks on GCS's S3-compat endpoint when
|
|
70
|
+
* the bucket CORS `responseHeader` list desyncs from the browser's request).
|
|
71
|
+
*/
|
|
72
|
+
export async function buildDuckDbUrlAsync(tab, expiresIn) {
|
|
73
|
+
const presigned = await tryPresignTab(tab, expiresIn);
|
|
74
|
+
return presigned ?? buildDuckDbUrl(tab);
|
|
75
|
+
}
|
|
76
|
+
/** Presign the tab's HTTPS URL for `signed-s3` connections; null otherwise. */
|
|
77
|
+
async function tryPresignTab(tab, expiresIn) {
|
|
78
|
+
const conn = tab.connectionId ? connections.getById(tab.connectionId) : null;
|
|
79
|
+
if (!conn || isPubliclyStreamable(conn))
|
|
80
|
+
return null;
|
|
81
|
+
try {
|
|
82
|
+
return await presignHttpsUrl(conn, tab.path, expiresIn);
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
// Silent fallback would route the caller back to `s3://...` + SigV4
|
|
86
|
+
// header signing — exactly the CORS preflight path presigning was added
|
|
87
|
+
// to avoid. Surface the failure so it is debuggable.
|
|
88
|
+
console.warn('[presign] falling back to signed-s3 path:', err);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
56
92
|
/**
|
|
57
93
|
* True when any HTTP client (fetch/img/video/deck.gl/COG/Zarr/PMTiles) can
|
|
58
94
|
* load the tab's file directly via its HTTPS URL. False when SigV4 signing
|
package/dist/utils/wkb.js
CHANGED
|
@@ -190,8 +190,22 @@ const GEO_TYPE_KEYWORDS = [
|
|
|
190
190
|
'geometrycollection',
|
|
191
191
|
'sdo_geometry'
|
|
192
192
|
];
|
|
193
|
-
/**
|
|
194
|
-
|
|
193
|
+
/**
|
|
194
|
+
* Tokens in column names that hint at geometry content. Matched against
|
|
195
|
+
* snake_case / kebab-case / camelCase tokens only — never as loose substrings
|
|
196
|
+
* (e.g. `_geographic_` must not match `geo` via the `_geo` substring, because
|
|
197
|
+
* count columns like `n_geographic_entities` are INT, not geometry).
|
|
198
|
+
*/
|
|
199
|
+
const GEO_NAME_HINTS = ['geom', 'geometry', 'wkb', 'wkt', 'shape', 'spatial', 'geo'];
|
|
200
|
+
/** Split a column name into lowercase tokens for hint matching. */
|
|
201
|
+
function tokenizeColumnName(name) {
|
|
202
|
+
return name
|
|
203
|
+
.replace(/([a-z])([A-Z])/g, '$1_$2')
|
|
204
|
+
.replace(/([a-z])([0-9])/g, '$1_$2')
|
|
205
|
+
.toLowerCase()
|
|
206
|
+
.split(/[^a-z0-9]+/)
|
|
207
|
+
.filter(Boolean);
|
|
208
|
+
}
|
|
195
209
|
/** Valid GeoJSON geometry type names. */
|
|
196
210
|
const GEOJSON_TYPES = [
|
|
197
211
|
'Point',
|
|
@@ -242,18 +256,18 @@ export function findGeoColumn(schema) {
|
|
|
242
256
|
if (GEO_NAMES.includes(f.name.toLowerCase()))
|
|
243
257
|
return f.name;
|
|
244
258
|
}
|
|
245
|
-
// Priority 4: name
|
|
259
|
+
// Priority 4: name token matches geo hint with binary type
|
|
246
260
|
for (const f of schema) {
|
|
247
|
-
const
|
|
261
|
+
const tokens = tokenizeColumnName(f.name);
|
|
248
262
|
const t = f.type.toLowerCase();
|
|
249
263
|
const isBinary = t.includes('blob') || t.includes('binary') || t.includes('bytea');
|
|
250
|
-
if (isBinary &&
|
|
264
|
+
if (isBinary && tokens.some((tok) => GEO_NAME_HINTS.includes(tok)))
|
|
251
265
|
return f.name;
|
|
252
266
|
}
|
|
253
|
-
// Priority 5: name
|
|
267
|
+
// Priority 5: name token matches geo hint, any type
|
|
254
268
|
for (const f of schema) {
|
|
255
|
-
const
|
|
256
|
-
if (
|
|
269
|
+
const tokens = tokenizeColumnName(f.name);
|
|
270
|
+
if (tokens.some((tok) => GEO_NAME_HINTS.includes(tok)))
|
|
257
271
|
return f.name;
|
|
258
272
|
}
|
|
259
273
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walkthru-earth/objex",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Svelte 5 components and utilities for exploring geospatial object storage — S3, GCS, Azure, R2",
|
|
5
5
|
"author": "Youssef Harby <yharby@walkthru.earth>",
|
|
6
6
|
"license": "CC-BY-4.0",
|