@knockdata/objectexplorer 0.5.3 โ†’ 0.5.4

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 CHANGED
@@ -3,53 +3,13 @@
3
3
  **The VSCode for Cloud Storage.** Browse, preview, query and search S3, Google Cloud Storage,
4
4
  Azure Blob and local folders in one window โ€” and every byte stays on your machine.
5
5
 
6
- <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/screenshot/objectexplorer.png" width="800">
6
+ <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/docs/public/shot/hero.png" width="800">
7
7
 
8
- ## Install
8
+ ๐Ÿ“– **[Documentation](https://docs.objectexplorer.com)** ยท ๐Ÿš€ [Try it in a browser](https://objectexplorer.com/app)
9
9
 
10
- Every link below always points at the newest build. Click the one for your machine.
10
+ ## Run it with npx
11
11
 
12
- | Platform | Download |
13
- |---|---|
14
- | macOS, Apple Silicon | [ObjectExplorer-mac-arm64.dmg](https://github.com/knockdata/objectexplorer/releases/latest/download/ObjectExplorer-mac-arm64.dmg) |
15
- | macOS, Intel | [ObjectExplorer-mac-x64.dmg](https://github.com/knockdata/objectexplorer/releases/latest/download/ObjectExplorer-mac-x64.dmg) |
16
- | Windows, x64 | [ObjectExplorer-windows-x64.exe](https://github.com/knockdata/objectexplorer/releases/latest/download/ObjectExplorer-windows-x64.exe) |
17
- | Windows, ARM | [ObjectExplorer-windows-arm64.exe](https://github.com/knockdata/objectexplorer/releases/latest/download/ObjectExplorer-windows-arm64.exe) |
18
- | Linux, x64 | [ObjectExplorer-linux-x64.AppImage](https://github.com/knockdata/objectexplorer/releases/latest/download/ObjectExplorer-linux-x64.AppImage) |
19
- | Linux, ARM | [ObjectExplorer-linux-arm64.AppImage](https://github.com/knockdata/objectexplorer/releases/latest/download/ObjectExplorer-linux-arm64.AppImage) |
20
-
21
- Older versions, and the release notes for each one, are on the
22
- [releases page](https://github.com/knockdata/objectexplorer/releases).
23
-
24
- **macOS** โ€” open the `.dmg` and drag ObjectExplorer to Applications. The app is signed with a
25
- Developer ID and notarized, so it opens on the first double-click.
26
-
27
- **Windows** โ€” the download is one signed `.exe`. There is no installer and no folder of loose
28
- `.dll` files: run it where it lands.
29
-
30
- **Linux** โ€” one AppImage:
31
-
32
- ```sh
33
- chmod +x ObjectExplorer-linux-x64.AppImage
34
- ./ObjectExplorer-linux-x64.AppImage
35
- ```
36
-
37
- The window is drawn with the WebKitGTK your distribution ships, and ObjectExplorer opens in your
38
- default browser on a machine that has none. To get the native window, install it:
39
-
40
- ```sh
41
- sudo apt install libwebkit2gtk-4.1-0 # Debian, Ubuntu
42
- sudo dnf install webkit2gtk4.1 # Fedora, RHEL
43
- sudo pacman -S webkit2gtk-4.1 # Arch
44
- sudo zypper install libwebkit2gtk-4_1-0 # openSUSE
45
- ```
46
-
47
- On an older release without a 4.1 package, the 4.0 one (`libwebkit2gtk-4.0-37`, `webkit2gtk3`)
48
- works too.
49
-
50
- ## Or run it with npx
51
-
52
- No install at all, if you already have Node 20+ installed on your machine:
12
+ No install at all, if you already have Node 20+ on your machine:
53
13
 
54
14
  ```sh
55
15
  npx @knockdata/objectexplorer
@@ -62,18 +22,21 @@ arguments are optional:
62
22
  npx @knockdata/objectexplorer ~/data port=9421
63
23
  ```
64
24
 
25
+ If PowerShell refuses to run `npx`, see
26
+ [troubleshooting](https://docs.objectexplorer.com/reference/troubleshooting).
65
27
 
66
- <details>
67
- <summary>Windows: "npx.ps1 cannot be loaded because running scripts is disabled on this system"</summary>
28
+ ## Or install the app
68
29
 
69
- - Right click PowerShell and choose **Run as administrator**
70
- - Run `Get-ExecutionPolicy` โ€” if it says `Restricted`, it needs changing
71
- - Run `Set-ExecutionPolicy RemoteSigned`
72
- - Run `Get-ExecutionPolicy` again โ€” it should now say `RemoteSigned`
73
-
74
- `npx` then works in that terminal, and in any new one.
30
+ | Platform | Download |
31
+ |---|---|
32
+ | macOS, Apple Silicon | [ObjectExplorer-mac-arm64.dmg](https://github.com/knockdata/objectexplorer/releases/latest/download/ObjectExplorer-mac-arm64.dmg) |
33
+ | macOS, Intel | [ObjectExplorer-mac-x64.dmg](https://github.com/knockdata/objectexplorer/releases/latest/download/ObjectExplorer-mac-x64.dmg) |
34
+ | Windows, x64 | [ObjectExplorer-windows-x64.msix](https://github.com/knockdata/objectexplorer/releases/latest/download/ObjectExplorer-windows-x64.msix) |
35
+ | Windows, ARM | [ObjectExplorer-windows-arm64.msix](https://github.com/knockdata/objectexplorer/releases/latest/download/ObjectExplorer-windows-arm64.msix) |
36
+ | Linux, x64 | [ObjectExplorer-linux-x64.AppImage](https://github.com/knockdata/objectexplorer/releases/latest/download/ObjectExplorer-linux-x64.AppImage) |
37
+ | Linux, ARM | [ObjectExplorer-linux-arm64.AppImage](https://github.com/knockdata/objectexplorer/releases/latest/download/ObjectExplorer-linux-arm64.AppImage) |
75
38
 
76
- </details>
39
+ Per-platform notes are in [getting started](https://docs.objectexplorer.com/getting-started).
77
40
 
78
41
  ## What it solves
79
42
 
@@ -84,182 +47,53 @@ credentials, and a `Downloads` folder full of data that should never have left t
84
47
 
85
48
  ObjectExplorer collapses that loop:
86
49
 
87
- - **One window for every provider.** S3, GCS, Azure Blob and your local disks in the same tree, with
88
- the same keyboard shortcuts.
50
+ - **One window for every provider.** S3, GCS, Azure Blob, MinIO and your local disks in the same
51
+ tree, with the same keyboard shortcuts.
89
52
  - **Preview instead of download.** Formats render in place โ€” including the ones no console will ever
90
53
  open, like Parquet, SPSS and SAS.
91
54
  - **Search across buckets.** One query over local folders and cloud prefixes at the same time.
92
55
  - **Query, chart and model in place.** A table opens as a notebook: SQL over the object, a chart of
93
56
  what came back, and a gradient boosting model over the rows โ€” all on your machine.
57
+ - **Delta, Iceberg and Hudi are just tables.** Point DuckDB at the folder and it answers, deletes
58
+ and schema changes included.
59
+ - **Move things where they belong.** Copy, move, rename and delete across buckets and disks, with
60
+ one Undo.
94
61
 
95
62
  ## Your data never leaves your machine
96
63
 
97
- This is the part that matters when you work with data you are not allowed to copy.
98
-
99
64
  ObjectExplorer is an HTTP server bound to `127.0.0.1` plus the OS webview, both inside the same
100
65
  executable. Every parser โ€” Parquet, SPSS, SAS, PDF, the office formats, the image decoders โ€” runs
101
66
  in a worker on your own machine.
102
67
 
103
68
  - Objects are fetched **from your cloud provider to your computer**, and nowhere else. We run no
104
69
  backend that sees your data, because there is nothing for it to see.
105
- - Credentials stay local: `~/.objectexplorer/folders.json`, plus whatever your platform CLI or
106
- keychain already holds. Nothing is synced.
70
+ - Credentials stay local, in `~/.objectexplorer` โ€” plus whatever your platform CLI or keychain
71
+ already holds. Nothing is synced.
107
72
  - The only call that is not to your own storage is a version check against the npm registry, so the
108
73
  app can tell you an update exists.
109
- - Nothing is uploaded for "processing", no file names are reported anywhere, and no account is
110
- needed to open a file.
111
-
112
- Which also means there is no data-processing agreement to negotiate before anyone can look at a
113
- bucket.
114
-
115
- ## Storage providers
116
-
117
- | | Provider | Connect with |
118
- |---|---|---|
119
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/s3.svg" width="18"> | Amazon S3 | drop your `accessKeys.csv`, paste a key ID and secret, or sign in with the AWS CLI |
120
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/gcs.svg" width="18"> | Google Cloud Storage | sign in with your Google account |
121
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/cloud.svg" width="18"> | Azure Blob Storage | a connection string, a SAS URL, or sign in with Microsoft |
122
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/minio.svg" width="18"> | MinIO | your own endpoint, for self-hosted S3-compatible storage |
123
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/folder.svg" width="18"> | Local folders | the native folder picker โ€” any disk, any mounted volume |
124
74
 
125
- Buckets show up in the tree once you add them, so a thousand-bucket account still opens on the five
126
- you actually use.
75
+ โ†’ [the whole argument](https://docs.objectexplorer.com/privacy), and
76
+ [where your data lives](https://docs.objectexplorer.com/reference/data-locations)
127
77
 
128
78
  ## Features
129
79
 
130
- ### Column summary
131
-
132
- <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/screenshot/column-summary.png" width="600">
133
-
134
- Open a table and every column comes with its own shape: a histogram for numbers, a box plot for
135
- distributions, a split bar for categories, a unique count for identifiers, the range underneath. It
136
- answers "is this the file I want?" without a line of pandas โ€” computed locally, straight from the
137
- file you are looking at.
138
-
139
- Works on Parquet, CSV, SPSS `.sav` and SAS `.xpt`.
140
-
141
- ### Notebook
142
-
143
- Open a table and it opens as a notebook: a column of cells, each one a few lines of code over its
144
- own output. The first two are already written โ€” a `SELECT *` over the object you clicked, and a
145
- chart of what that query returned โ€” so the file is queried and plotted before you have typed
146
- anything.
147
-
148
- ```sql
149
- SELECT * FROM 'gs://sales-eu/orders/2026-08-24.parquet' LIMIT 10000
150
- ```
151
-
152
- The query runs on your machine, against the object where it lives. Nothing is staged into a
153
- temporary folder first: DuckDB reads the bucket directly, so a `WHERE` over a multi-gigabyte
154
- Parquet file touches the row groups it needs and no more.
155
-
156
- Cells are piped rather than shared. Each one reads the rows produced by the nearest cell above it
157
- that produced any, so a query narrows the data and everything under it โ€” the chart, the model, the
158
- next query โ€” sees what came back. Nothing re-runs on its own: a cell runs from its run button or
159
- Shift+Enter, so what is on screen is always something you asked for.
160
-
161
- | Cell | What it is |
80
+ | | |
162
81
  |---|---|
163
- | **Table** | SQL, with the rows as a virtualized grid โ€” column summaries and all |
164
- | **Chart** | a plot of the rows above, as source you can edit |
165
- | **Model** | gradient boosting over the rows above |
166
- | **Code** | JavaScript over the same rows, with a pandas-style dataframe already in scope |
167
- | **Text** | markdown, rendered when you click away |
168
-
169
- A chart cell writes its own first draft. The column statistics say which column is a date, which is
170
- a category, which is a measure and which is an id that counts up once per row โ€” and the strip under
171
- the code offers the charts those columns actually support, named in plain words. Click one and its
172
- source is written into the editor and drawn. After that it is source, and it is yours.
173
-
174
- A folder is a table too: Delta, Iceberg and Hudi tables, Hive-partitioned exports and `YYYY/MM/DD`
175
- date prefixes are read as one table rather than as a pile of files.
176
-
177
- Notebooks are kept per object. Reopen the file next week โ€” in another window, or after a restart โ€”
178
- and your cells are still there.
179
-
180
- Queryable: `parquet` `csv` `tsv` `json` `jsonl` `xlsx` `avro`, plus SPSS `.sav` and SAS
181
- `.sas7bdat` `.xpt`. ORC, Arrow and HDF5 open as grids and charts too; only SQL over them is
182
- missing, and the cell says so.
183
-
184
- ### Train a model on it
185
-
186
- A model cell is gradient boosting โ€” LightGBM, compiled to WebAssembly and running inside the app โ€”
187
- over the rows the cell above produced.
188
-
189
- Pick the label, the column you want predicted, and the rest comes from the same statistics the grid
190
- already drew: whether the question is *which one* or *how much*, which columns are worth training
191
- on, and which are row numbers, ids or coordinates that would teach the model the order the file was
192
- written in and nothing else.
193
-
194
- The controls hide nothing. Leaves, learning rate and iterations are three sliders, and moving one
195
- prints the JavaScript underneath it โ€” that printed source is what trains, so a slider and a hand
196
- edit end in the same place.
197
-
198
- Two plots come out of it. Training draws what the model learned: the features ranked by their share
199
- of the total gain. Prediction answers the other question โ€” pick a row, and a waterfall walks from
200
- what the model says on average to what it said about that one row, feature by feature. Those
201
- contributions are TreeSHAP, exact and additive, so the steps add up to the prediction rather than
202
- approximating it. Both plots show the same features in the same order, so the pair reads across:
203
- what a column is worth over the whole file, and what it did to this row.
204
-
205
- It all runs where the data already is. A model over a bucket you are not allowed to copy out of is
206
- still just a local read.
207
-
208
- ### Search
209
-
210
- Search local folders and cloud buckets in the same run: literal, whole word or regex, with include
211
- and exclude globs, and `.gitignore` honoured when you point it at a repo. Results group by file with
212
- the matching line in context, and large objects are searched without pulling them down whole.
213
-
214
- ### Hex
215
-
216
- Any file, any size, straight to bytes. Offsets, hex pairs and the ASCII column, virtualized so a
217
- multi-gigabyte object opens instantly instead of after a spinner. Exactly what you need when a
218
- format is not recognized and the first 64 bytes decide what it is.
219
-
220
- ### Sprite sheets
221
-
222
- <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/screenshot/sprite-sheet.png" width="900">
223
-
224
- Open a TextureAtlas or SpriteSheet XML and ObjectExplorer draws it: the atlas image with every
225
- sprite's bounding box overlaid and named, aligned to the real pixels however the image is scaled.
226
- Hover a box to read the frame name โ€” no importing the sheet into an engine to find out which tile is
227
- `medievalTile_04`.
228
-
229
- ### Inside archives, without extracting
230
-
231
- Step into a `.zip`, a `.dmg`, or an office file โ€” `.pptx` and `.xlsx` are zips too โ€” and browse the
232
- entries as if they were folders. Each entry previews with its own viewer, so a CSV inside a zip
233
- inside a bucket is still just a table.
234
-
235
- ## Formats
236
-
237
- | | Kind | Formats |
238
- |---|---|---|
239
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/parquet.svg" width="18"> | Parquet | `parquet` โ€” schema, rows, column summaries |
240
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/table.svg" width="18"> | Data lake | `delta` `iceberg` `hudi`, Hive and date partitions โ€” a folder read as one table |
241
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/table.svg" width="18"> | Tabular | `csv` `json` `jsonl` `yaml` `yml` |
242
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/sas.svg" width="18"> | Statistics | `xpt` (SAS transport), `sav` (SPSS) |
243
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/powerpoint.svg" width="18"> | Presentations | `pptx` `potx` `ppsx` `ppt` `pot` `pps` `key` |
244
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/excel.svg" width="18"> | Spreadsheets | `xlsx` `xltx` |
245
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/word.svg" width="18"> | Documents | `docx` `dotx` `pdf` `evernote` |
246
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/text.svg" width="18"> | Text and code | `md` `markdown` `txt` `html` `xml` `xsl` `js` `py`, syntax highlighted |
247
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/jupyter.svg" width="18"> | Notebooks | `ipynb` โ€” cells with their outputs |
248
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/image.svg" width="18"> | Images | `png` `jpg` `jpeg` `webp` `svg` `ico` โ€” with EXIF, GPS and embedded text |
249
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/music.svg" width="18"> | Audio | `mp3` `wav` `m4a` `aiff` `bwf` `3gpp` โ€” waveform and spectrogram |
250
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/film.svg" width="18"> | Video | played in place, no download first |
251
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/excalidraw.svg" width="18"> | Drawings | `excalidraw` |
252
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/mermaid.svg" width="18"> | Diagrams | `mmd` `mermaid`, rendered |
253
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/archive.svg" width="18"> | Archives | `zip` `dmg` `apkg`, and the office formats, browsed as folders |
254
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/apple.svg" width="18"> | Apple | `plist` `provisionprofile` `.DS_Store` โ€” binary plists decoded |
255
- | <img src="https://raw.githubusercontent.com/knockdata/objectexplorer/refs/heads/main/assets/format/hex-mode.svg" width="18"> | Everything else | hex, always available |
82
+ | [Connect storage](https://docs.objectexplorer.com/storage/connect) | S3, GCS, Azure Blob, MinIO, local folders โ€” added one root at a time |
83
+ | [Preview anything](https://docs.objectexplorer.com/explore/preview) | parquet, csv, json, SPSS, SAS, pdf, office, images, audio, video, ebooks, sprite sheets, hex |
84
+ | [Column summaries](https://docs.objectexplorer.com/explore/column-summary) | a histogram, a box plot or a split bar under every column header |
85
+ | [Notebook](https://docs.objectexplorer.com/analyze/notebook) | SQL, charts, models and JavaScript over the object you clicked |
86
+ | [Data lake tables](https://docs.objectexplorer.com/analyze/lake) | Delta, Iceberg, Hudi and partitioned exports, read as one table |
87
+ | [Models](https://docs.objectexplorer.com/analyze/model) | LightGBM in WebAssembly, with exact TreeSHAP explanations |
88
+ | [Search](https://docs.objectexplorer.com/explore/search) | local folders and cloud prefixes in the same run |
89
+ | [File management](https://docs.objectexplorer.com/explore/file-management) | copy, move, rename, delete across providers, with a trash and an undo |
90
+ | [Sharing](https://docs.objectexplorer.com/explore/share) | a link to a table, masked or hashed column by column, with an expiry |
91
+
92
+ The whole list of formats is on [every format](https://docs.objectexplorer.com/formats/).
256
93
 
257
94
  ## Links
258
95
 
259
- - [objectexplorer.com](https://objectexplorer.com) โ€” screenshots and the full tour
260
- - [@knockdata/objectexplorer](https://www.npmjs.com/package/@knockdata/objectexplorer) โ€” the npm package behind `npx`
261
- - [Changelog](https://github.com/knockdata/objectexplorer/blob/main/CHANGELOG.md) โ€” what changed in each version
262
- - [Releases](https://github.com/knockdata/objectexplorer/releases) โ€” every version, every platform
263
- Under the hood it is a single native binary: no Electron, no Chromium, just the OS webview (WebKit
264
- on macOS and Linux, WebView2 on Windows) pointed at the HTTP server running inside the same
265
- executable.
96
+ - [docs.objectexplorer.com](https://docs.objectexplorer.com) โ€” the documentation
97
+ - [objectexplorer.com](https://objectexplorer.com) โ€” the product page
98
+ - [Changelog](https://github.com/knockdata/objectexplorer/blob/main/CHANGELOG.md)
99
+ - [Releases](https://github.com/knockdata/objectexplorer/releases)
@@ -0,0 +1,2 @@
1
+ import{K as e,P as t,X as n,h as r,nt as i,ot as a,s as o}from"./share.js";function s(e){return t(new Date(e*1e3).toISOString())}var c=`import lightgbm as lgb
2
+ booster = lgb.Booster(model_str=open("model.txt").read())`;function l(e){return n(`div`,{class:`share-view`},n(`div`,{class:`share-view-header`},n(`span`,{class:`share-view-title`},`Nothing to show`)),n(`div`,{class:`share-view-failed`},e))}function u(e){let t=e.filter(e=>e.method&&e.method!==`none`);return t.length===0?`every column as it was`:t.map(e=>`${e.name}: ${e.method}`).join(`, `)}function d(t){let r=t.model??{},i=a(r.features??[]);function o(){let e=URL.createObjectURL(new Blob([r.text??``],{type:`text/plain`})),t=document.createElement(`a`);t.href=e,t.download=`model.txt`,t.click(),URL.revokeObjectURL(e)}return n(`div`,{class:`share-view-model`},n(`div`,{class:`share-model`},`${r.objective??`model`}, ${r.trees??0} trees, label ${r.label??`?`}`),n(`div`,{class:`share-view-features`},n(e,{each:i},e=>n(`span`,{class:`share-view-feature`},e))),n(`div`,{class:`share-send`},n(`span`,{class:`btn`,onclick:o},`Download model.txt`)),n(`pre`,{class:`share-view-snippet`},c))}async function f(e){let{reference:t}=e,a=null,c=``;try{a=await o(t)}catch(e){c=String(e.message??e)}if(a===null)return l(c);if(a.expires*1e3<Date.now())return l(`this link expired on `+s(a.expires));{let e=a.columns??[],t=i(()=>a.kind===`table`?`${(a.rows??[]).length} rows โ€” ${u(e)}`:`a trained model, without the rows it was trained on`);return n(`div`,{class:`share-view`},n(`div`,{class:`share-view-header`},n(`span`,{class:`share-view-title`},a.title??`Shared`),n(`span`,{class:`share-hint`},t),n(`span`,{class:`share-hint`},`until ${s(a.expires)}`)),n(`div`,{class:`share-view-body`},a.kind===`model`?d(a):n(r,{payload:a.rows??[],columns:e})))}}export{f as default};