@walkthru-earth/objex 1.3.0 → 1.4.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 (182) hide show
  1. package/LICENSE +5 -0
  2. package/README.md +20 -12
  3. package/dist/components/browser/FileTreeSidebar.svelte +32 -17
  4. package/dist/components/layout/AboutSheet.svelte +5 -2
  5. package/dist/components/layout/ConnectionDialog.svelte +1 -1
  6. package/dist/components/layout/SettingsSheet.svelte +237 -0
  7. package/dist/components/layout/SettingsSheet.svelte.d.ts +6 -0
  8. package/dist/components/layout/Sidebar.svelte +73 -6
  9. package/dist/components/layout/Sidebar.svelte.d.ts +4 -1
  10. package/dist/components/layout/StatusBar.svelte +1 -1
  11. package/dist/components/layout/TabBar.svelte +2 -2
  12. package/dist/components/ui/context-menu/context-menu-radio-group.svelte.d.ts +1 -1
  13. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte.d.ts +1 -1
  14. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte.d.ts +1 -1
  15. package/dist/components/ui/input/input.svelte.d.ts +1 -1
  16. package/dist/components/ui/resizable/index.d.ts +1 -1
  17. package/dist/components/ui/resizable/index.js +2 -2
  18. package/dist/components/ui/slider/index.d.ts +3 -0
  19. package/dist/components/ui/slider/index.js +5 -0
  20. package/dist/components/ui/slider/range-slider.svelte +94 -0
  21. package/dist/components/ui/slider/range-slider.svelte.d.ts +21 -0
  22. package/dist/components/ui/slider/slider.svelte +83 -0
  23. package/dist/components/ui/slider/slider.svelte.d.ts +7 -0
  24. package/dist/components/viewers/ArchiveViewer.svelte +2 -2
  25. package/dist/components/viewers/CodeViewer.svelte +31 -22
  26. package/dist/components/viewers/CogControls.svelte +338 -184
  27. package/dist/components/viewers/CogControls.svelte.d.ts +33 -10
  28. package/dist/components/viewers/CogViewer.svelte +320 -119
  29. package/dist/components/viewers/CopcViewer.svelte +1 -1
  30. package/dist/components/viewers/FlatGeobufViewer.svelte +1 -1
  31. package/dist/components/viewers/GeoParquetMapViewer.svelte +6 -6
  32. package/dist/components/viewers/GeoParquetMapViewer.svelte.d.ts +1 -1
  33. package/dist/components/viewers/ImageViewer.svelte +2 -2
  34. package/dist/components/viewers/MarkdownViewer.svelte +12 -9
  35. package/dist/components/viewers/MediaViewer.svelte +2 -2
  36. package/dist/components/viewers/ModelViewer.svelte +1 -1
  37. package/dist/components/viewers/MultiCogViewer.svelte +467 -102
  38. package/dist/components/viewers/MultiCogViewer.svelte.d.ts +1 -1
  39. package/dist/components/viewers/NotebookViewer.svelte +6 -3
  40. package/dist/components/viewers/PdfViewer.svelte +2 -2
  41. package/dist/components/viewers/PmtilesViewer.svelte +3 -6
  42. package/dist/components/viewers/RawViewer.svelte +6 -3
  43. package/dist/components/viewers/StacMapViewer.svelte +10 -2
  44. package/dist/components/viewers/StacMosaicViewer.svelte +1800 -362
  45. package/dist/components/viewers/StacMosaicViewer.svelte.d.ts +1 -1
  46. package/dist/components/viewers/StacTabViewer.svelte +24 -13
  47. package/dist/components/viewers/StacTabViewer.svelte.d.ts +1 -1
  48. package/dist/components/viewers/TableGrid.svelte +4 -4
  49. package/dist/components/viewers/TableStatusBar.svelte +1 -1
  50. package/dist/components/viewers/TableToolbar.svelte +1 -1
  51. package/dist/components/viewers/TableViewer.svelte +25 -17
  52. package/dist/components/viewers/TableViewer.svelte.d.ts +1 -0
  53. package/dist/components/viewers/ViewerRouter.svelte +16 -8
  54. package/dist/components/viewers/ZarrMapViewer.svelte +11 -9
  55. package/dist/components/viewers/ZarrViewer.svelte +4 -4
  56. package/dist/components/viewers/cog/ChannelPicker.svelte +83 -0
  57. package/dist/components/viewers/cog/ChannelPicker.svelte.d.ts +13 -0
  58. package/dist/components/viewers/cog/PixelInspectorPanel.svelte +87 -0
  59. package/dist/components/viewers/cog/PixelInspectorPanel.svelte.d.ts +17 -0
  60. package/dist/components/viewers/cog/buildRgbLayer.d.ts +78 -0
  61. package/dist/components/viewers/cog/buildRgbLayer.js +176 -0
  62. package/dist/components/viewers/map/AttributeTable.svelte +1 -1
  63. package/dist/components/viewers/map/MapContainer.svelte +37 -11
  64. package/dist/components/viewers/pmtiles/PmtilesArchiveView.svelte +1 -1
  65. package/dist/components/viewers/pmtiles/PmtilesTileInspector.svelte +1 -1
  66. package/dist/components/viewers/stac/StacDatetimeBar.svelte +175 -0
  67. package/dist/components/viewers/stac/StacDatetimeBar.svelte.d.ts +10 -0
  68. package/dist/components/viewers/stac/StacFilterPanel.svelte +243 -0
  69. package/dist/components/viewers/stac/StacFilterPanel.svelte.d.ts +14 -0
  70. package/dist/components/viewers/stac/StacItemInspector.svelte +223 -0
  71. package/dist/components/viewers/stac/StacItemInspector.svelte.d.ts +10 -0
  72. package/dist/components/viewers/stac/StacItemStrip.svelte +228 -0
  73. package/dist/components/viewers/stac/StacItemStrip.svelte.d.ts +12 -0
  74. package/dist/file-icons/index.d.ts +1 -1
  75. package/dist/file-icons/index.js +1 -1
  76. package/dist/i18n/ar.js +110 -2
  77. package/dist/i18n/en.js +110 -2
  78. package/dist/index.d.ts +2 -28
  79. package/dist/index.js +7 -23
  80. package/dist/query/engine.d.ts +10 -0
  81. package/dist/query/source.js +1 -1
  82. package/dist/query/stac-source-factory.d.ts +65 -0
  83. package/dist/query/stac-source-factory.js +77 -0
  84. package/dist/query/stac-source-parquet.d.ts +135 -0
  85. package/dist/query/stac-source-parquet.js +465 -0
  86. package/dist/query/wasm.d.ts +8 -0
  87. package/dist/query/wasm.js +304 -2
  88. package/dist/storage/presign.js +1 -1
  89. package/dist/storage/providers.js +5 -5
  90. package/dist/stores/config.svelte.d.ts +15 -0
  91. package/dist/stores/config.svelte.js +46 -0
  92. package/dist/stores/connections.svelte.d.ts +2 -2
  93. package/dist/stores/connections.svelte.js +1 -2
  94. package/dist/stores/files.svelte.d.ts +1 -1
  95. package/dist/stores/files.svelte.js +1 -1
  96. package/dist/stores/query-history.svelte.js +1 -1
  97. package/dist/stores/settings.svelte.d.ts +16 -1
  98. package/dist/stores/settings.svelte.js +104 -48
  99. package/dist/stores/tabs.svelte.d.ts +3 -0
  100. package/dist/stores/tabs.svelte.js +17 -0
  101. package/dist/utils/cog-histogram.d.ts +121 -0
  102. package/dist/utils/cog-histogram.js +424 -0
  103. package/dist/utils/cog.d.ts +200 -60
  104. package/dist/utils/cog.js +377 -114
  105. package/dist/utils/colormap-sprite.d.ts +0 -9
  106. package/dist/utils/colormap-sprite.js +0 -21
  107. package/dist/utils/deck.d.ts +16 -12
  108. package/dist/utils/deck.js +10 -4
  109. package/dist/utils/pmtiles-tile.js +2 -2
  110. package/dist/utils/{url.d.ts → signed-url.d.ts} +15 -1
  111. package/dist/utils/{url.js → signed-url.js} +32 -10
  112. package/dist/utils/url-state.d.ts +36 -0
  113. package/dist/utils/url-state.js +72 -2
  114. package/dist/utils/zarr-tab.d.ts +1 -2
  115. package/dist/utils/zarr-tab.js +1 -2
  116. package/dist/utils/zarr.d.ts +0 -17
  117. package/dist/utils/zarr.js +1 -45
  118. package/package.json +55 -84
  119. package/dist/components/browser/Breadcrumb.svelte +0 -50
  120. package/dist/components/browser/Breadcrumb.svelte.d.ts +0 -7
  121. package/dist/components/browser/CreateFolderDialog.svelte +0 -98
  122. package/dist/components/browser/CreateFolderDialog.svelte.d.ts +0 -6
  123. package/dist/components/browser/DeleteConfirmDialog.svelte +0 -90
  124. package/dist/components/browser/DeleteConfirmDialog.svelte.d.ts +0 -8
  125. package/dist/components/browser/DropZone.svelte +0 -83
  126. package/dist/components/browser/DropZone.svelte.d.ts +0 -7
  127. package/dist/components/browser/FileBrowser.svelte +0 -252
  128. package/dist/components/browser/FileBrowser.svelte.d.ts +0 -3
  129. package/dist/components/browser/FileRow.svelte +0 -117
  130. package/dist/components/browser/FileRow.svelte.d.ts +0 -9
  131. package/dist/components/browser/RenameDialog.svelte +0 -101
  132. package/dist/components/browser/RenameDialog.svelte.d.ts +0 -8
  133. package/dist/components/browser/SearchBar.svelte +0 -40
  134. package/dist/components/browser/SearchBar.svelte.d.ts +0 -6
  135. package/dist/components/browser/UploadButton.svelte +0 -65
  136. package/dist/components/browser/UploadButton.svelte.d.ts +0 -3
  137. package/dist/query/stac-geoparquet.d.ts +0 -31
  138. package/dist/query/stac-geoparquet.js +0 -136
  139. package/dist/utils/clipboard.d.ts +0 -13
  140. package/dist/utils/clipboard.js +0 -38
  141. package/dist/utils/cloud-url.d.ts +0 -27
  142. package/dist/utils/cloud-url.js +0 -61
  143. package/dist/utils/column-types.d.ts +0 -5
  144. package/dist/utils/column-types.js +0 -137
  145. package/dist/utils/connection-identity.d.ts +0 -51
  146. package/dist/utils/connection-identity.js +0 -97
  147. package/dist/utils/error.d.ts +0 -8
  148. package/dist/utils/error.js +0 -12
  149. package/dist/utils/evidence-context.d.ts +0 -22
  150. package/dist/utils/evidence-context.js +0 -56
  151. package/dist/utils/export.d.ts +0 -22
  152. package/dist/utils/export.js +0 -76
  153. package/dist/utils/file-sort.d.ts +0 -20
  154. package/dist/utils/file-sort.js +0 -41
  155. package/dist/utils/format.d.ts +0 -24
  156. package/dist/utils/format.js +0 -78
  157. package/dist/utils/geoarrow.d.ts +0 -32
  158. package/dist/utils/geoarrow.js +0 -672
  159. package/dist/utils/geometry-type.d.ts +0 -52
  160. package/dist/utils/geometry-type.js +0 -76
  161. package/dist/utils/hex.d.ts +0 -10
  162. package/dist/utils/hex.js +0 -27
  163. package/dist/utils/host-detection.d.ts +0 -23
  164. package/dist/utils/host-detection.js +0 -95
  165. package/dist/utils/local-storage.d.ts +0 -16
  166. package/dist/utils/local-storage.js +0 -37
  167. package/dist/utils/markdown-sql.d.ts +0 -30
  168. package/dist/utils/markdown-sql.js +0 -72
  169. package/dist/utils/notebook.d.ts +0 -59
  170. package/dist/utils/notebook.js +0 -211
  171. package/dist/utils/parquet-metadata.d.ts +0 -64
  172. package/dist/utils/parquet-metadata.js +0 -262
  173. package/dist/utils/stac-geoparquet.d.ts +0 -90
  174. package/dist/utils/stac-geoparquet.js +0 -223
  175. package/dist/utils/stac-hydrate.d.ts +0 -38
  176. package/dist/utils/stac-hydrate.js +0 -243
  177. package/dist/utils/stac.d.ts +0 -136
  178. package/dist/utils/stac.js +0 -176
  179. package/dist/utils/storage-url.d.ts +0 -90
  180. package/dist/utils/storage-url.js +0 -568
  181. package/dist/utils/wkb.d.ts +0 -43
  182. package/dist/utils/wkb.js +0 -359
@@ -1,4 +1,4 @@
1
1
  import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui';
2
- declare const DropdownMenuRadioGroup: import("svelte").Component<DropdownMenuPrimitive.RadioGroupProps, {}, "value" | "ref">;
2
+ declare const DropdownMenuRadioGroup: import("svelte").Component<DropdownMenuPrimitive.RadioGroupProps, {}, "ref" | "value">;
3
3
  type DropdownMenuRadioGroup = ReturnType<typeof DropdownMenuRadioGroup>;
4
4
  export default DropdownMenuRadioGroup;
@@ -8,6 +8,6 @@ type Props = WithElementRef<Omit<HTMLInputAttributes, 'type'> & ({
8
8
  type?: InputType;
9
9
  files?: undefined;
10
10
  })>;
11
- declare const Input: import("svelte").Component<Props, {}, "value" | "ref" | "files">;
11
+ declare const Input: import("svelte").Component<Props, {}, "ref" | "value" | "files">;
12
12
  type Input = ReturnType<typeof Input>;
13
13
  export default Input;
@@ -1,4 +1,4 @@
1
1
  import { Pane } from 'paneforge';
2
2
  import Handle from './resizable-handle.svelte';
3
3
  import PaneGroup from './resizable-pane-group.svelte';
4
- export { PaneGroup, Pane, Handle, PaneGroup as ResizablePaneGroup, Pane as ResizablePane, Handle as ResizableHandle };
4
+ export { Handle, Handle as ResizableHandle, Pane as ResizablePane, PaneGroup, PaneGroup as ResizablePaneGroup };
@@ -1,6 +1,6 @@
1
1
  import { Pane } from 'paneforge';
2
2
  import Handle from './resizable-handle.svelte';
3
3
  import PaneGroup from './resizable-pane-group.svelte';
4
- export { PaneGroup, Pane, Handle,
4
+ export { Handle, Handle as ResizableHandle, Pane as ResizablePane, PaneGroup,
5
5
  //
6
- PaneGroup as ResizablePaneGroup, Pane as ResizablePane, Handle as ResizableHandle };
6
+ PaneGroup as ResizablePaneGroup };
@@ -0,0 +1,3 @@
1
+ import RangeSlider from './range-slider.svelte';
2
+ import Root from './slider.svelte';
3
+ export { RangeSlider, Root, Root as Slider };
@@ -0,0 +1,5 @@
1
+ import RangeSlider from './range-slider.svelte';
2
+ import Root from './slider.svelte';
3
+ export { RangeSlider, Root,
4
+ //
5
+ Root as Slider };
@@ -0,0 +1,94 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../../utils.js';
3
+ import Slider from './slider.svelte';
4
+
5
+ /**
6
+ * Dual-thumb numeric range slider with optional histogram bars rendered
7
+ * behind the track and a min/max label row beneath. Composes the shadcn
8
+ * `Slider` primitive (bits-ui) so pointer, keyboard, RTL, and a11y
9
+ * behavior come from the primitive instead of being reimplemented.
10
+ *
11
+ * Used by:
12
+ * - StacDatetimeBar / StacFilterPanel (datetime + numeric facets, with histogram)
13
+ * - CogControls (rescale min/max, no histogram, paired number inputs)
14
+ */
15
+ let {
16
+ value = $bindable<[number, number]>([0, 1]),
17
+ min,
18
+ max,
19
+ step = 1,
20
+ histogram,
21
+ formatLabel,
22
+ loLabel,
23
+ hiLabel,
24
+ class: className,
25
+ disabled = false,
26
+ onValueChange,
27
+ onValueCommit
28
+ }: {
29
+ value?: [number, number];
30
+ min: number;
31
+ max: number;
32
+ step?: number;
33
+ /** Optional bin counts to draw behind the track. */
34
+ histogram?: readonly number[] | null;
35
+ /** Formatter for the default min/max label row. Omit to hide labels. */
36
+ formatLabel?: (n: number) => string;
37
+ /** Override the lower label (takes precedence over `formatLabel(value[0])`). */
38
+ loLabel?: string;
39
+ /** Override the upper label (takes precedence over `formatLabel(value[1])`). */
40
+ hiLabel?: string;
41
+ class?: string;
42
+ disabled?: boolean;
43
+ onValueChange?: (next: [number, number]) => void;
44
+ onValueCommit?: (next: [number, number]) => void;
45
+ } = $props();
46
+
47
+ const histMax = $derived(histogram?.length ? Math.max(1, ...histogram) : 1);
48
+ const showLabels = $derived(Boolean(formatLabel) || loLabel != null || hiLabel != null);
49
+
50
+ function emitChange(next: number[]): void {
51
+ if (next.length >= 2) onValueChange?.([next[0], next[1]]);
52
+ }
53
+
54
+ function emitCommit(next: number[]): void {
55
+ if (next.length >= 2) onValueCommit?.([next[0], next[1]]);
56
+ }
57
+ </script>
58
+
59
+ <div class={cn('flex flex-col gap-1.5', className)}>
60
+ <div class="relative px-2">
61
+ {#if histogram && histogram.length > 0}
62
+ <div
63
+ class="pointer-events-none absolute inset-x-2 top-0 flex h-6 items-end gap-px"
64
+ aria-hidden="true"
65
+ >
66
+ {#each histogram as count, i (i)}
67
+ <div
68
+ class="bg-muted-foreground/30 flex-1 rounded-sm"
69
+ style="height: {Math.max(2, (count / histMax) * 100)}%"
70
+ ></div>
71
+ {/each}
72
+ </div>
73
+ {/if}
74
+ <Slider
75
+ type="multiple"
76
+ bind:value={value as never}
77
+ {min}
78
+ {max}
79
+ {step}
80
+ {disabled}
81
+ onValueChange={emitChange}
82
+ onValueCommit={emitCommit}
83
+ class={cn(histogram && histogram.length > 0 && 'mt-7')}
84
+ />
85
+ </div>
86
+ {#if showLabels}
87
+ <div
88
+ class="text-muted-foreground flex items-center justify-between px-2 text-[10px] tabular-nums"
89
+ >
90
+ <span>{loLabel ?? (formatLabel ? formatLabel(value[0]) : '')}</span>
91
+ <span>{hiLabel ?? (formatLabel ? formatLabel(value[1]) : '')}</span>
92
+ </div>
93
+ {/if}
94
+ </div>
@@ -0,0 +1,21 @@
1
+ type $$ComponentProps = {
2
+ value?: [number, number];
3
+ min: number;
4
+ max: number;
5
+ step?: number;
6
+ /** Optional bin counts to draw behind the track. */
7
+ histogram?: readonly number[] | null;
8
+ /** Formatter for the default min/max label row. Omit to hide labels. */
9
+ formatLabel?: (n: number) => string;
10
+ /** Override the lower label (takes precedence over `formatLabel(value[0])`). */
11
+ loLabel?: string;
12
+ /** Override the upper label (takes precedence over `formatLabel(value[1])`). */
13
+ hiLabel?: string;
14
+ class?: string;
15
+ disabled?: boolean;
16
+ onValueChange?: (next: [number, number]) => void;
17
+ onValueCommit?: (next: [number, number]) => void;
18
+ };
19
+ declare const RangeSlider: import("svelte").Component<$$ComponentProps, {}, "value">;
20
+ type RangeSlider = ReturnType<typeof RangeSlider>;
21
+ export default RangeSlider;
@@ -0,0 +1,83 @@
1
+ <script lang="ts" module>
2
+ import { Slider as SliderPrimitive, type WithoutChildrenOrChild } from 'bits-ui';
3
+
4
+ export type SliderProps = WithoutChildrenOrChild<SliderPrimitive.RootProps> & {
5
+ class?: string;
6
+ };
7
+ </script>
8
+
9
+ <script lang="ts">
10
+ import { cn } from '../../../utils.js';
11
+
12
+ let {
13
+ ref = $bindable(null),
14
+ value = $bindable(),
15
+ class: className,
16
+ type,
17
+ ...restProps
18
+ }: SliderProps = $props();
19
+ </script>
20
+
21
+ {#if type === 'single'}
22
+ <SliderPrimitive.Root
23
+ bind:ref
24
+ bind:value={value as never}
25
+ type="single"
26
+ data-slot="slider"
27
+ class={cn(
28
+ 'relative flex w-full touch-none select-none items-center data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col data-[disabled]:opacity-50',
29
+ className
30
+ )}
31
+ {...(restProps as Record<string, unknown>)}
32
+ >
33
+ {#snippet children({ thumbs })}
34
+ <span
35
+ data-slot="slider-track"
36
+ class="bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5"
37
+ >
38
+ <SliderPrimitive.Range
39
+ data-slot="slider-range"
40
+ class="bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full"
41
+ />
42
+ </span>
43
+ {#each thumbs as index (index)}
44
+ <SliderPrimitive.Thumb
45
+ {index}
46
+ data-slot="slider-thumb"
47
+ class="border-primary bg-background ring-ring/50 block size-4 shrink-0 cursor-pointer rounded-full border-2 shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50"
48
+ />
49
+ {/each}
50
+ {/snippet}
51
+ </SliderPrimitive.Root>
52
+ {:else}
53
+ <SliderPrimitive.Root
54
+ bind:ref
55
+ bind:value={value as never}
56
+ type="multiple"
57
+ data-slot="slider"
58
+ class={cn(
59
+ 'relative flex w-full touch-none select-none items-center data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col data-[disabled]:opacity-50',
60
+ className
61
+ )}
62
+ {...(restProps as Record<string, unknown>)}
63
+ >
64
+ {#snippet children({ thumbs })}
65
+ <span
66
+ data-slot="slider-track"
67
+ class="bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5"
68
+ >
69
+ <SliderPrimitive.Range
70
+ data-slot="slider-range"
71
+ class="bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full"
72
+ />
73
+ </span>
74
+ {#each thumbs as index (index)}
75
+ <SliderPrimitive.Thumb
76
+ {index}
77
+ data-slot="slider-thumb"
78
+ class="border-primary bg-background ring-ring/50 block size-4 shrink-0 cursor-pointer rounded-full border-2 shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50"
79
+ />
80
+ {/each}
81
+ {/snippet}
82
+ </SliderPrimitive.Root>
83
+ {/if}
@@ -0,0 +1,7 @@
1
+ import { Slider as SliderPrimitive, type WithoutChildrenOrChild } from 'bits-ui';
2
+ export type SliderProps = WithoutChildrenOrChild<SliderPrimitive.RootProps> & {
3
+ class?: string;
4
+ };
5
+ declare const Slider: import("svelte").Component<SliderProps, {}, "ref" | "value">;
6
+ type Slider = ReturnType<typeof Slider>;
7
+ export default Slider;
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { Archive, ChevronRight, Download, File, Folder, Loader } from '@lucide/svelte';
3
+ import { formatFileSize } from '@walkthru-earth/objex-utils';
3
4
  import type { Entry } from '@zip.js/zip.js';
4
5
  import { onDestroy, untrack } from 'svelte';
5
6
  import { Badge } from '../ui/badge/index.js';
@@ -28,8 +29,7 @@ import {
28
29
  streamTarGzEntriesFromUrl,
29
30
  streamZipEntriesFromUrl
30
31
  } from '../../utils/archive';
31
- import { formatFileSize } from '../../utils/format';
32
- import { buildHttpsUrlAsync } from '../../utils/url.js';
32
+ import { buildHttpsUrlAsync } from '../../utils/signed-url.js';
33
33
 
34
34
  let { tab }: { tab: Tab } = $props();
35
35
 
@@ -1,5 +1,12 @@
1
1
  <script lang="ts">
2
2
  import EllipsisVerticalIcon from '@lucide/svelte/icons/ellipsis-vertical';
3
+ import {
4
+ copyToClipboard,
5
+ handleLoadError,
6
+ isStacCatalog,
7
+ isStacCollection,
8
+ isStacItem
9
+ } from '@walkthru-earth/objex-utils';
3
10
  import { onDestroy } from 'svelte';
4
11
  import { Badge } from '../ui/badge/index.js';
5
12
  import { Button } from '../ui/button/index.js';
@@ -8,13 +15,10 @@ import { t } from '../../i18n/index.svelte.js';
8
15
  import { getAdapter } from '../../storage/index.js';
9
16
  import { tabResources } from '../../stores/tab-resources.svelte.js';
10
17
  import type { Tab } from '../../types';
11
- import { copyToClipboard } from '../../utils/clipboard.js';
12
- import { handleLoadError } from '../../utils/error.js';
13
18
  import { extensionToShikiLang, highlightCode } from '../../utils/shiki';
14
- import { buildHttpsUrl, buildHttpsUrlAsync, canStreamDirectly } from '../../utils/url.js';
15
- import { getUrlView, updateUrlView } from '../../utils/url-state.js';
19
+ import { buildHttpsUrl, buildHttpsUrlAsync, canStreamDirectly } from '../../utils/signed-url.js';
20
+ import { getUrlView, pickViewMode, updateUrlView } from '../../utils/url-state.js';
16
21
  import { openZarrTab } from '../../utils/zarr-tab.js';
17
- import { isStacCatalog, isStacCollection, isStacItem } from '../../utils/stac.js';
18
22
 
19
23
  interface CodeActions {
20
24
  toggleFormat: () => Promise<void>;
@@ -44,20 +48,20 @@ let error = $state<string | null>(null);
44
48
  let copied = $state(false);
45
49
  let formatted = $state(false);
46
50
  const urlView = getUrlView();
47
- function getInitialViewMode():
48
- | 'code'
49
- | 'render'
50
- | 'stac-browser'
51
- | 'kepler'
52
- | 'maputnik'
53
- | 'marimo' {
54
- if (urlView === 'stac-browser') return 'stac-browser';
55
- if (urlView === 'kepler') return 'kepler';
56
- if (urlView === 'maputnik') return 'maputnik';
57
- if (urlView === 'marimo') return 'marimo';
58
- if (urlView === 'code') return 'code';
59
- if (tab.extension.toLowerCase() === 'html') return 'render';
60
- return 'code';
51
+ type CodeViewMode = 'code' | 'render' | 'stac-browser' | 'kepler' | 'maputnik' | 'marimo';
52
+ const CODE_VIEW_MODES = [
53
+ 'code',
54
+ 'render',
55
+ 'stac-browser',
56
+ 'kepler',
57
+ 'maputnik',
58
+ 'marimo'
59
+ ] as const satisfies readonly CodeViewMode[];
60
+ function getInitialViewMode(): CodeViewMode {
61
+ const explicit = pickViewMode<CodeViewMode>(CODE_VIEW_MODES, 'code');
62
+ if (explicit !== 'code' || urlView === 'code') return explicit;
63
+ // No (or unknown) hash: default to render for HTML, code otherwise.
64
+ return tab.extension.toLowerCase() === 'html' ? 'render' : 'code';
61
65
  }
62
66
  let viewMode = $state(getInitialViewMode());
63
67
 
@@ -207,12 +211,17 @@ $effect(() => {
207
211
  };
208
212
  });
209
213
 
210
- // Auto-switch to STAC Browser when STAC JSON is detected (unless URL explicitly set #code).
214
+ // Auto-switch to STAC Browser when STAC JSON is detected and the user did NOT
215
+ // request a specific view via the URL hash. Any explicit hash (#map, #stac-map,
216
+ // #stac-browser, #code, …) MUST be honored, because while ViewerRouter's async
217
+ // detectStac is pending it falls back to plain CodeViewer for .json tabs;
218
+ // rewriting the hash here would race the eventual StacTabViewer mount and
219
+ // clobber the shared link the user opened.
211
220
  // Skipped when nested in StacTabViewer since the outer wrapper owns the view toggle.
212
221
  let stacAutoSwitched = false;
213
222
  $effect(() => {
214
223
  if (nested) return;
215
- if (isStacJson && !stacAutoSwitched && viewMode === 'code' && urlView !== 'code') {
224
+ if (isStacJson && !stacAutoSwitched && viewMode === 'code' && !urlView) {
216
225
  stacAutoSwitched = true;
217
226
  viewMode = 'stac-browser';
218
227
  updateUrlView('stac-browser');
@@ -349,7 +358,7 @@ async function toggleFormat() {
349
358
  formatted = true;
350
359
  }
351
360
 
352
- function setViewMode(mode: 'code' | 'render' | 'stac-browser' | 'kepler' | 'maputnik' | 'marimo') {
361
+ function setViewMode(mode: CodeViewMode) {
353
362
  viewMode = viewMode === mode ? (isHtml ? 'render' : 'code') : mode;
354
363
  updateUrlView(viewMode === 'render' ? '' : viewMode);
355
364
  }