M4
This commit is contained in:
@@ -16,6 +16,7 @@ type Phase =
|
||||
| "signing_in" // browser sign-in in progress
|
||||
| "installing" // downloading + verifying a version
|
||||
| "restoring" // loading the database snapshot into local Postgres
|
||||
| "syncing" // exchanging operator data with the DHP (ODIAN is not running)
|
||||
| "launching" // starting Postgres → API → tile server → Odian.exe
|
||||
| "running" // Odian.exe is open
|
||||
| "error"; // the last long operation failed; see `error`
|
||||
@@ -34,6 +35,28 @@ 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"
|
||||
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
|
||||
// the DHP offers no Engine API to forward to
|
||||
}
|
||||
|
||||
interface SyncStatus {
|
||||
pending: number; // local edits the DHP has not taken yet
|
||||
conflicts: number; // records both sides changed: the operator decides
|
||||
rejected: number; // edits the DHP refused (another operator's record, ...)
|
||||
waiting: number; // DHP changes this PC could not apply yet
|
||||
}
|
||||
|
||||
interface SyncConflict {
|
||||
tbl: string; // database table, e.g. "db_ground_poi"
|
||||
key: Record<string, unknown>; // the record's key columns
|
||||
kind: "conflict" | "rejected";
|
||||
fields: string[]; // clashing fields; "*exists": one side deleted it; "*value": a whole-value clash
|
||||
base: unknown; // the DHP value before this PC's edit
|
||||
mine: unknown; // this PC's value (null = deleted here)
|
||||
theirs: unknown; // the DHP's value (null = deleted there)
|
||||
reason: string | null; // why the DHP refused it (rejected only)
|
||||
}
|
||||
|
||||
interface Settings {
|
||||
@@ -83,12 +106,34 @@ 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 |
|
||||
| `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.
|
||||
|
||||
## Live mode
|
||||
|
||||
When the DHP advertises an Engine API (`engine_api_url` in its `/v1/health`), the
|
||||
launcher starts the local API pointed at it and keeps a token file fresh for it. ODIAN
|
||||
always talks to the local API; while the DHP answers, that API forwards the shared-data
|
||||
routes there, so operators see each other's work and tracks are live. The moment the DHP
|
||||
stops answering, the same API serves this PC's own database instead — no restart, and the
|
||||
request that discovers the outage is already served locally. Coming back, the launcher
|
||||
first sends what was edited offline, then hands the token back and ODIAN is live again.
|
||||
`status.live` says which of the two is happening.
|
||||
|
||||
## Operator-data sync
|
||||
|
||||
When the installed version ships the sync schema (`versions\<v>\sync\*.sql`) and the
|
||||
DHP is reachable, `launch` first syncs (push, then pull), then starts the stack. When
|
||||
ODIAN closes, the launcher pushes that session's work. Offline, edits stay on this PC.
|
||||
A sync that cannot finish is logged and never blocks the launch. Conflicts and refused
|
||||
edits wait in the local database until `resolve_sync_conflict`.
|
||||
|
||||
## Events (`listen`)
|
||||
|
||||
| Event | Payload | When |
|
||||
|
||||
Reference in New Issue
Block a user