| … | … | @@ -57,6 +57,8 @@ export function registryStoreDir (registryKeyHex) { |
| 57 | 57 | * @param {string} [opts.version] exact version; omitted = latest |
| 58 | 58 | * @param {boolean} [opts.preferSidecar=true] try the sidecar's replica first |
| 59 | 59 | * @param {number} [opts.settleMs=500] post-flush settle before reading the view |
| 60 | * @param {string} [opts.storeDir] where to keep the registry replica. Defaults to a path under |
| 61 | * the home directory, which does not exist on Android — an embedder must pass its own. |
| 60 | 62 | * @returns {Promise<{ entry: object|null, via: string, cleanup: function }>} |
| 61 | 63 | */ |
| 62 | 64 | export async function resolveRelease (opts = {}) { |
| … | … | @@ -102,7 +104,16 @@ export async function resolveRelease (opts = {}) { |
| 102 | 104 | try { if (store) await store.close() } catch {} |
| 103 | 105 | } |
| 104 | 106 | |
| 105 | | const dir = registryStoreDir(registryKeyHex) |
| 107 | // ⛔ CALLER-SUPPLIED OR THE DEFAULT, because the default assumes a HOME DIRECTORY and a phone has |
| 108 | // none. On Android this resolved to a path that cannot be stat'd, so `resolveRelease` threw |
| 109 | // ENOENT, `swarmFetcher` caught it, and OTA reported "no swarm fetcher — updates disabled this |
| 110 | // boot" — a handset that could never update, with the reason visible nowhere until the app was |
| 111 | // taught to report its own last OTA line. |
| 112 | // |
| 113 | // ⚠ Same class as a binary assumed on PATH and a vault assumed under ~: a library that picks a |
| 114 | // path from the environment works everywhere the environment has one. An embedder knows where its |
| 115 | // state goes; ask it. |
| 116 | const dir = opts.storeDir || registryStoreDir(registryKeyHex) |
| 106 | 117 | fs.mkdirSync(dir, { recursive: true }) |
| 107 | 118 | store = new Corestore(dir) |
| 108 | 119 | try { |
| … | … | @@ -134,10 +145,10 @@ export async function resolveRelease (opts = {}) { |
| 134 | 145 | * sidecar, `pgh app install`, and its own next resolve. Polling is hourly by |
| 135 | 146 | * default, so the reconnect cost is irrelevant beside that. |
| 136 | 147 | */ |
| 137 | | export function makeGetLatestRelease ({ registryKeyHex, preferSidecar, settleMs } = {}) { |
| 148 | export function makeGetLatestRelease ({ registryKeyHex, preferSidecar, settleMs, storeDir } = {}) { |
| 138 | 149 | return async function getLatestRelease (name) { |
| 139 | 150 | const { entry, cleanup } = await resolveRelease({ |
| 140 | | registryKeyHex, name, preferSidecar, settleMs |
| 151 | registryKeyHex, name, preferSidecar, settleMs, storeDir |
| 141 | 152 | }) |
| 142 | 153 | try { return entry } finally { await cleanup() } |
| 143 | 154 | } |