update
This commit is contained in:
+51
-3
@@ -35,6 +35,8 @@ interface Status {
|
||||
phase: Phase;
|
||||
error: string | null; // set with phase "error"; cleared by the next command or `refresh`
|
||||
install_dir: string; // e.g. "D:\\ODIAN"
|
||||
portable: boolean; // this launcher ships on an ODIAN drive: it runs that drive's
|
||||
// install (any letter), the folder is fixed, no self-update
|
||||
sync: SyncStatus | null; // counts from the last sync this session; null before one
|
||||
live: boolean | null; // while ODIAN runs: true = its data comes from the DHP,
|
||||
// false = from this PC. null when it is not running, or
|
||||
@@ -84,6 +86,25 @@ interface StackEvent {
|
||||
}
|
||||
|
||||
interface LogEvent { level: "info" | "warn" | "error"; message: string; at: number }
|
||||
|
||||
interface MarketItem {
|
||||
key: string; // stable across versions: "tiles:<style>/<dataset>" | "src:<path>"
|
||||
kind: "tiles" | "src";
|
||||
title: string;
|
||||
description: string;
|
||||
bytes: number; // what installing it downloads, in full
|
||||
required: boolean; // part of every install; never offered for removal
|
||||
presence: "installed" | "partial" | "absent"; // partial: a download that stopped
|
||||
selected: boolean; // chosen: installed with the version, kept by updates
|
||||
}
|
||||
|
||||
interface Market {
|
||||
version: string; // the installed version, else the DHP's current one
|
||||
installed: boolean; // false: a choice waits for Install
|
||||
core_bytes: number; // the app and database: what every install downloads besides the items
|
||||
items: MarketItem[]; // required first
|
||||
free_bytes: number | null; // free space where ODIAN is (or will be) installed
|
||||
}
|
||||
```
|
||||
|
||||
## Commands (`invoke`)
|
||||
@@ -98,7 +119,7 @@ interface LogEvent { level: "info" | "warn" | "error"; message: string; at: numb
|
||||
| `get_notes` | `{ version?: string }` | `string` | Markdown. From the site when online; the cached copy of the installed version offline. **Untrusted: the UI must sanitize.** |
|
||||
| `open_external` | `{ url: string }` | `void` | opens an `http`/`https` link in the system browser (links in patch notes); anything else is refused |
|
||||
| `start_install` | — | `void` | installs or updates to `available`; needs `signed_in` (the site checks the token); progress arrives as events |
|
||||
| `start_install_from_drive` | `{ path: string }` | `void` | same, reading an ODIAN drive (SSD) instead of the site; no sign-in needed |
|
||||
| `start_install_from_drive` | `{ path: string }` | `void` | same, copying from an ODIAN drive (SSD) instead of the site; no sign-in needed. `path` is the drive's root (a pack store) or a folder holding an install, and every file copied is checked against the manifest. A tile set the PC already records as complete for the same index (`.blocks-done.json`) is left as it stands instead of being re-read: that record is written last, so a copy stopped halfway still reads as partial and resumes. The copy lands in the install folder of Settings, so a drive can install onto the PC it is plugged into; an install folder that is the drive's own ODIAN (or inside it) is refused, since there is nothing to copy, and so is a drive carrying an older ODIAN than the one installed there |
|
||||
| `cancel_install` | — | `void` | stops at the next file boundary; everything already verified is kept |
|
||||
| `launch` | — | `void` | starts the local stack; `stack` events follow |
|
||||
| `stop` | — | `void` | stops Odian.exe's stack cleanly |
|
||||
@@ -106,14 +127,41 @@ interface LogEvent { level: "info" | "warn" | "error"; message: string; at: numb
|
||||
| `get_settings` | — | `Settings` | |
|
||||
| `set_settings` | `{ settings: Settings }` | `Status` | |
|
||||
| `pick_folder` | — | `string \| null` | native folder picker |
|
||||
| `get_market` | `{ drive?: string }` | `Market` | the marketplace: every tile set and source file of the installed version (read from disk), or of the DHP's current one before the first install. With `drive`, what that drive carries instead (what it cannot install is left out), which is how the UI asks before installing from a drive |
|
||||
| `apply_market` | `{ selected: string[] }` | `void` | saves the choice of optional items (keys), then applies it to the installed version: unchosen items are removed from the PC, chosen missing ones download (phase `installing`, `install-progress` events). Refused while busy or ODIAN runs, and while an update is required; downloading needs the DHP. Before the first install it only saves the choice |
|
||||
| `set_market` | `{ selected: string[], drive?: string }` | `void` | the choice of optional items (keys) for an install about to run; changes nothing installed. Without `drive` it is this PC's standing choice and is saved. With `drive` it filters that one copy and is NOT saved: leaving out a tile set the PC already holds must not read as dropping it, or the next `apply_market` would delete it |
|
||||
| `sync_now` | — | `void` | pushes and pulls operator data now; only while ODIAN is stopped (phase `syncing` meanwhile) |
|
||||
| `get_sync_conflicts` | — | `SyncConflict[]` | what waits for a decision, oldest first; starts the local Postgres just for the read |
|
||||
| `resolve_sync_conflict` | `{ tbl, key, choice: "theirs" \| "mine" \| "value" \| "dismiss", value?: unknown }` | `SyncConflict[]` | records one decision and returns what is left. `theirs` takes the DHP's version; `mine` keeps this PC's (the next sync sends it); `value` keeps a field-by-field pick; `dismiss` keeps a refused edit on this PC only. Links and folder placements held with a record follow its decision |
|
||||
|
||||
Errors reject the promise with a string message.
|
||||
|
||||
Planned, not yet available: the size of `available` for the Install button, and
|
||||
inspecting a drive (its version and size) before installing from it.
|
||||
Planned, not yet available: the size of `available` for the Install button.
|
||||
|
||||
## Where a drive's launcher installs
|
||||
|
||||
A launcher that ships on an ODIAN drive (`site.json` with `"portable": true`) keeps its
|
||||
settings beside the exe, so the site and the install folder travel with the drive. The
|
||||
folder may be on the drive itself, and ODIAN then runs from the drive on any PC: it is
|
||||
stored without its letter, because the next PC hands the drive a different one. It may
|
||||
also be a folder on a disk of the PC in front of the operator, and the drive then installs
|
||||
ODIAN onto that PC and leaves; that folder is stored whole. A drive's root and a network
|
||||
share are refused: Postgres and the tiles need a real disk.
|
||||
|
||||
## Marketplace
|
||||
|
||||
The DHP decides what is optional: a manifest tile set or source file with
|
||||
`"optional": true` (plus `title` and `description`, from `catalog.json` at assemble) is
|
||||
left out of Install and listed by `get_market`. Everything else is part of every install.
|
||||
A manifest from before the marketplace flags nothing, so the launcher applies the same rule
|
||||
to it: the app, the database and the `dark` tile set come with every install and the rest is
|
||||
offered, which is what makes copying an older version from a drive a choice rather than all
|
||||
228 GB or nothing. A manifest that flags anything at all is the DHP's to decide and is taken
|
||||
exactly as it stands. The choice is kept in the
|
||||
install's state (`extras`) and survives updates: an update refreshes the chosen items and
|
||||
nothing else. Installing from a drive asks the same way: the marketplace opens on what the
|
||||
drive carries, `set_market` records the answer, and `start_install_from_drive` copies it. A PC installed before the marketplace counts what it has on disk as chosen,
|
||||
so nothing is removed or downloaded again behind the operator's back.
|
||||
|
||||
## Live mode
|
||||
|
||||
|
||||
Reference in New Issue
Block a user