deno
fd41ccca - feat(compile): persist Web Storage/KV in a per-app data directory (#34618)

Commit
94 days ago
feat(compile): persist Web Storage/KV in a per-app data directory (#34618) In a `deno compile`-d binary, origin-bound storage did not work. The default `Deno.openKv()` (called without an explicit path) silently fell back to an in-memory database, so data never survived across runs, and both `localStorage` and the Web `caches` API threw `NotSupported`. The root cause was in the standalone runtime (`cli/rt/run.rs`), which built the worker factory with `StorageKeyResolver::empty()` and `origin_data_folder_path: None`. With no storage key the worker resolves both `origin_storage_dir` and `cache_storage_dir` to `None`; KV then opens an in-memory connection and the storage globals are disabled. Rather than route this through `DENO_DIR` the way `deno run` does, this treats a compiled binary as a standalone application. Persistent storage now lives under the platform's app data directory (`%LOCALAPPDATA%`, `~/Library/Application Support`, `$XDG_DATA_HOME`), reusing the same `get_data_local_dir()` resolution already used for self-extracting binaries, keyed by an app name. This keeps a shipped binary from writing user data into a Deno tooling cache that may not even exist on the target machine. The app name is the single source of storage identity. It is baked in at compile time from a new `--app-name` flag, falling back to the output file name when the flag is omitted, so it is stable across runs and even if the produced binary is later renamed. Recompiling with a different `--output`/`--app-name` starts a fresh store. Because the name (not the main-module URL) drives the directory, two binaries compiled with the same `--app-name` share a store while differently named apps stay isolated, and the previous footgun where two binaries that merely shared an executable file name would collide is gone. A single fixed storage key is used per app, so each app gets one store rather than per-origin namespacing; `--location` is no longer involved in storage. When the data directory cannot be resolved the storage key is left empty and the previous in-memory fallback is preserved, which also avoids unwrapping a missing data folder path in the worker. The app name is carried in the compile `Metadata` so the standalone runtime can read it back; `--app-version` (#29038) is a natural next member of this same app-identity metadata. Spec tests under `tests/specs/compile` compile a script and exercise it across cold processes: `kv_default_storage_path` proves a default `Deno.openKv()` survives between runs, `local_storage_default_path` does the same for `localStorage`, `web_cache_storage` proves `caches` is available, and `app_name_storage` proves two binaries sharing an `--app-name` share a store while a differently named app does not. Each test redirects the platform app data directory into its temp dir to stay hermetic. Fixes #24318
Author
Parents
Loading