@walkthru-earth/objex 1.0.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.
Files changed (84) hide show
  1. package/README.md +11 -2
  2. package/dist/components/browser/FileBrowser.svelte +41 -54
  3. package/dist/components/browser/FileTreeSidebar.svelte +43 -7
  4. package/dist/components/layout/ConnectionDialog.svelte +100 -1
  5. package/dist/components/layout/Sidebar.svelte +43 -25
  6. package/dist/components/viewers/CodeViewer.svelte +23 -0
  7. package/dist/components/viewers/CogControls.svelte +208 -0
  8. package/dist/components/viewers/CogControls.svelte.d.ts +12 -0
  9. package/dist/components/viewers/CogViewer.svelte +353 -1160
  10. package/dist/components/viewers/CogViewer.svelte.d.ts +1 -1
  11. package/dist/components/viewers/DatabaseViewer.svelte +345 -37
  12. package/dist/components/viewers/MarkdownViewer.svelte +1 -1
  13. package/dist/components/viewers/TableViewer.svelte +123 -41
  14. package/dist/components/viewers/ZarrMapViewer.svelte +29 -0
  15. package/dist/components/viewers/ZarrViewer.svelte +1 -4
  16. package/dist/constants.d.ts +6 -2
  17. package/dist/constants.js +6 -2
  18. package/dist/file-icons/index.d.ts +1 -1
  19. package/dist/file-icons/index.js +12 -2
  20. package/dist/i18n/ar.js +24 -0
  21. package/dist/i18n/en.js +24 -0
  22. package/dist/i18n/index.svelte.d.ts +0 -1
  23. package/dist/i18n/index.svelte.js +0 -3
  24. package/dist/index.d.ts +11 -0
  25. package/dist/index.js +10 -0
  26. package/dist/query/engine.d.ts +20 -4
  27. package/dist/query/index.d.ts +2 -1
  28. package/dist/query/index.js +1 -0
  29. package/dist/query/source.d.ts +30 -0
  30. package/dist/query/source.js +37 -0
  31. package/dist/query/wasm.d.ts +7 -5
  32. package/dist/query/wasm.js +138 -85
  33. package/dist/storage/providers.d.ts +47 -0
  34. package/dist/storage/providers.js +160 -0
  35. package/dist/stores/connections.svelte.js +5 -31
  36. package/dist/stores/files.svelte.d.ts +2 -8
  37. package/dist/stores/files.svelte.js +5 -38
  38. package/dist/stores/query-history.svelte.js +3 -25
  39. package/dist/stores/settings.svelte.d.ts +1 -0
  40. package/dist/stores/settings.svelte.js +10 -30
  41. package/dist/stores/tabs.svelte.d.ts +9 -2
  42. package/dist/stores/tabs.svelte.js +11 -2
  43. package/dist/types.d.ts +11 -0
  44. package/dist/utils/cloud-url.d.ts +27 -0
  45. package/dist/utils/cloud-url.js +61 -0
  46. package/dist/utils/cog.d.ts +244 -0
  47. package/dist/utils/cog.js +1039 -0
  48. package/dist/utils/deck.d.ts +0 -18
  49. package/dist/utils/deck.js +0 -36
  50. package/dist/utils/export.d.ts +22 -2
  51. package/dist/utils/export.js +35 -10
  52. package/dist/utils/file-sort.d.ts +20 -0
  53. package/dist/utils/file-sort.js +41 -0
  54. package/dist/utils/geometry-type.d.ts +52 -0
  55. package/dist/utils/geometry-type.js +76 -0
  56. package/dist/utils/local-storage.d.ts +16 -0
  57. package/dist/utils/local-storage.js +37 -0
  58. package/dist/utils/markdown-sql.d.ts +1 -1
  59. package/dist/utils/markdown-sql.js +3 -4
  60. package/dist/utils/pmtiles-tile.d.ts +0 -2
  61. package/dist/utils/pmtiles-tile.js +0 -8
  62. package/dist/utils/url-state.d.ts +6 -0
  63. package/dist/utils/url-state.js +34 -26
  64. package/dist/utils/url.d.ts +13 -25
  65. package/dist/utils/url.js +17 -78
  66. package/dist/utils/zarr-tab.d.ts +22 -0
  67. package/dist/utils/zarr-tab.js +30 -0
  68. package/dist/utils/zarr.d.ts +0 -2
  69. package/dist/utils/zarr.js +73 -44
  70. package/package.json +50 -46
  71. package/dist/components/ui/tabs/index.d.ts +0 -5
  72. package/dist/components/ui/tabs/index.js +0 -7
  73. package/dist/components/ui/tabs/tabs-content.svelte +0 -17
  74. package/dist/components/ui/tabs/tabs-content.svelte.d.ts +0 -4
  75. package/dist/components/ui/tabs/tabs-list.svelte +0 -16
  76. package/dist/components/ui/tabs/tabs-list.svelte.d.ts +0 -4
  77. package/dist/components/ui/tabs/tabs-trigger.svelte +0 -20
  78. package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +0 -4
  79. package/dist/components/ui/tabs/tabs.svelte +0 -19
  80. package/dist/components/ui/tabs/tabs.svelte.d.ts +0 -4
  81. package/dist/components/viewers/MapViewer.svelte +0 -234
  82. package/dist/components/viewers/MapViewer.svelte.d.ts +0 -7
  83. package/dist/components/viewers/StyleEditorOverlay.svelte +0 -27
  84. package/dist/components/viewers/StyleEditorOverlay.svelte.d.ts +0 -7
@@ -1,234 +0,0 @@
1
- <script lang="ts">
2
- import type maplibregl from 'maplibre-gl';
3
- import { onDestroy } from 'svelte';
4
- import { t } from '../../i18n/index.svelte.js';
5
- import { getAdapter } from '../../storage/index.js';
6
- import { tabResources } from '../../stores/tab-resources.svelte.js';
7
- import type { Tab } from '../../types';
8
- import { setupSelectionLayer, updateSelection } from '../../utils/map-selection.js';
9
- import AttributeTable from './map/AttributeTable.svelte';
10
- import MapContainer from './map/MapContainer.svelte';
11
-
12
- let { tab }: { tab: Tab } = $props();
13
-
14
- let abortController: AbortController | null = null;
15
- let loading = $state(true);
16
- let error = $state<string | null>(null);
17
- let geojsonData = $state.raw<any>(null);
18
- let selectedFeature = $state<Record<string, any> | null>(null);
19
- let showAttributes = $state(false);
20
- let bounds = $state<[number, number, number, number] | undefined>();
21
-
22
- $effect(() => {
23
- if (!tab) return;
24
- loadGeoJson();
25
- });
26
-
27
- function cleanup() {
28
- abortController?.abort();
29
- abortController = null;
30
- geojsonData = null;
31
- selectedFeature = null;
32
- bounds = undefined;
33
- }
34
-
35
- $effect(() => {
36
- if (!tab) return;
37
- const unregister = tabResources.register(tab.id, cleanup);
38
- return unregister;
39
- });
40
-
41
- onDestroy(cleanup);
42
-
43
- async function loadGeoJson() {
44
- abortController?.abort();
45
- abortController = new AbortController();
46
- const { signal } = abortController;
47
-
48
- loading = true;
49
- error = null;
50
-
51
- try {
52
- const adapter = getAdapter(tab.source, tab.connectionId);
53
- const data = await adapter.read(tab.path, undefined, undefined, signal);
54
- const text = new TextDecoder().decode(data);
55
- geojsonData = JSON.parse(text);
56
-
57
- // Compute bounds from features
58
- if (geojsonData.bbox) {
59
- bounds = geojsonData.bbox as [number, number, number, number];
60
- } else {
61
- bounds = computeBounds(geojsonData);
62
- }
63
- } catch (err) {
64
- if (err instanceof DOMException && err.name === 'AbortError') return;
65
- error = err instanceof Error ? err.message : String(err);
66
- } finally {
67
- loading = false;
68
- }
69
- }
70
-
71
- function computeBounds(geojson: any): [number, number, number, number] | undefined {
72
- let minLng = Infinity,
73
- minLat = Infinity,
74
- maxLng = -Infinity,
75
- maxLat = -Infinity;
76
- let found = false;
77
-
78
- function processCoord(coord: number[]) {
79
- if (coord.length >= 2) {
80
- found = true;
81
- minLng = Math.min(minLng, coord[0]);
82
- minLat = Math.min(minLat, coord[1]);
83
- maxLng = Math.max(maxLng, coord[0]);
84
- maxLat = Math.max(maxLat, coord[1]);
85
- }
86
- }
87
-
88
- function processCoords(coords: any) {
89
- if (!coords) return;
90
- if (typeof coords[0] === 'number') {
91
- processCoord(coords);
92
- } else {
93
- for (const c of coords) processCoords(c);
94
- }
95
- }
96
-
97
- function processGeometry(geom: any) {
98
- if (!geom) return;
99
- if (geom.coordinates) processCoords(geom.coordinates);
100
- if (geom.geometries) geom.geometries.forEach(processGeometry);
101
- }
102
-
103
- if (geojson.type === 'FeatureCollection') {
104
- for (const f of geojson.features || []) processGeometry(f.geometry);
105
- } else if (geojson.type === 'Feature') {
106
- processGeometry(geojson.geometry);
107
- } else {
108
- processGeometry(geojson);
109
- }
110
-
111
- return found ? [minLng, minLat, maxLng, maxLat] : undefined;
112
- }
113
-
114
- function onMapReady(map: maplibregl.Map) {
115
- if (!geojsonData) return;
116
-
117
- map.addSource('geojson-source', {
118
- type: 'geojson',
119
- data: geojsonData
120
- });
121
-
122
- // Fill layer for polygons (orange)
123
- map.addLayer({
124
- id: 'geojson-fill',
125
- type: 'fill',
126
- source: 'geojson-source',
127
- filter: ['==', '$type', 'Polygon'],
128
- paint: {
129
- 'fill-color': '#e8793d',
130
- 'fill-opacity': 0.35
131
- }
132
- });
133
-
134
- // Outline layer for polygons (orange)
135
- map.addLayer({
136
- id: 'geojson-polygon-outline',
137
- type: 'line',
138
- source: 'geojson-source',
139
- filter: ['==', '$type', 'Polygon'],
140
- paint: {
141
- 'line-color': '#e65100',
142
- 'line-width': 2.5
143
- }
144
- });
145
-
146
- // Line layer for linestrings (teal)
147
- map.addLayer({
148
- id: 'geojson-line',
149
- type: 'line',
150
- source: 'geojson-source',
151
- filter: ['==', '$type', 'LineString'],
152
- paint: {
153
- 'line-color': '#00838f',
154
- 'line-width': 2.5
155
- }
156
- });
157
-
158
- // Circle layer for points (blue)
159
- map.addLayer({
160
- id: 'geojson-points',
161
- type: 'circle',
162
- source: 'geojson-source',
163
- filter: ['==', '$type', 'Point'],
164
- paint: {
165
- 'circle-radius': 7,
166
- 'circle-color': '#4285f4',
167
- 'circle-stroke-width': 1.5,
168
- 'circle-stroke-color': '#fff'
169
- }
170
- });
171
-
172
- // Selection highlight
173
- setupSelectionLayer(map);
174
-
175
- // Click handler
176
- for (const layerId of [
177
- 'geojson-fill',
178
- 'geojson-polygon-outline',
179
- 'geojson-line',
180
- 'geojson-points'
181
- ]) {
182
- map.on('click', layerId, (e: any) => {
183
- if (e.features && e.features.length > 0) {
184
- selectedFeature = { ...e.features[0].properties };
185
- showAttributes = true;
186
- updateSelection(map, e.features[0] as GeoJSON.Feature);
187
- }
188
- });
189
-
190
- map.on('mouseenter', layerId, () => {
191
- map.getCanvas().style.cursor = 'pointer';
192
- });
193
-
194
- map.on('mouseleave', layerId, () => {
195
- map.getCanvas().style.cursor = '';
196
- });
197
- }
198
- }
199
- </script>
200
-
201
- <div class="relative flex h-full overflow-hidden">
202
- {#if loading}
203
- <div class="flex flex-1 items-center justify-center">
204
- <p class="text-sm text-zinc-400">{t('map.loadingData')}</p>
205
- </div>
206
- {:else if error}
207
- <div class="flex flex-1 items-center justify-center">
208
- <p class="text-sm text-red-400">{error}</p>
209
- </div>
210
- {:else}
211
- <div class="flex-1">
212
- <MapContainer {onMapReady} {bounds} />
213
- </div>
214
-
215
- {#if selectedFeature}
216
- <div class="absolute right-2 top-2 z-10 flex gap-1">
217
- <button
218
- class="rounded bg-card/80 px-2 py-1 text-xs text-card-foreground backdrop-blur-sm hover:bg-card"
219
- class:ring-1={showAttributes}
220
- class:ring-primary={showAttributes}
221
- onclick={() => (showAttributes = !showAttributes)}
222
- >
223
- {t('map.attributes')}
224
- </button>
225
- </div>
226
- {/if}
227
-
228
- <AttributeTable
229
- feature={selectedFeature}
230
- visible={showAttributes}
231
- onClose={() => (showAttributes = false)}
232
- />
233
- {/if}
234
- </div>
@@ -1,7 +0,0 @@
1
- import type { Tab } from '../../types';
2
- type $$ComponentProps = {
3
- tab: Tab;
4
- };
5
- declare const MapViewer: import("svelte").Component<$$ComponentProps, {}, "">;
6
- type MapViewer = ReturnType<typeof MapViewer>;
7
- export default MapViewer;
@@ -1,27 +0,0 @@
1
- <script lang="ts">
2
- let { styleUrl, onclose }: { styleUrl: string; onclose: () => void } = $props();
3
-
4
- const maputnikUrl = $derived(
5
- `https://maplibre.org/maputnik/?style=${encodeURIComponent(styleUrl)}`
6
- );
7
- </script>
8
-
9
- <div class="fixed inset-0 z-50 flex flex-col bg-zinc-950">
10
- <div
11
- class="flex items-center justify-between border-b border-zinc-800 bg-zinc-900 px-4 py-2"
12
- >
13
- <span class="text-sm font-medium text-zinc-300">Maputnik Style Editor</span>
14
- <button
15
- class="rounded px-3 py-1 text-xs text-zinc-400 hover:bg-zinc-800 hover:text-zinc-200"
16
- onclick={onclose}
17
- >
18
- Close
19
- </button>
20
- </div>
21
- <iframe
22
- src={maputnikUrl}
23
- class="flex-1 border-0"
24
- title="Maputnik Style Editor"
25
- allow="clipboard-read; clipboard-write"
26
- ></iframe>
27
- </div>
@@ -1,7 +0,0 @@
1
- type $$ComponentProps = {
2
- styleUrl: string;
3
- onclose: () => void;
4
- };
5
- declare const StyleEditorOverlay: import("svelte").Component<$$ComponentProps, {}, "">;
6
- type StyleEditorOverlay = ReturnType<typeof StyleEditorOverlay>;
7
- export default StyleEditorOverlay;