@bundle-pilot/capacitor 0.2.3 → 0.3.0

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
@@ -44,8 +44,9 @@ into it.
44
44
  - **Rolls back by itself.** A bundle that never starts is rolled back by Capgo,
45
45
  and one that fails to bootstrap is reset by `startOta().failed()`. A bundle
46
46
  that rolled back is not offered again.
47
- - **Never slows a start.** The last answer is remembered. While it needs no
48
- update, the app starts at once and asks again in the background.
47
+ - **Updates before the app goes on.** The first navigation of a session waits
48
+ for the gateway (each request times out after 5 s), so an update installs right away instead of
49
+ at a later tap. Later navigations go on at once.
49
50
  - **Knows the native app.** The app's native version goes along with every
50
51
  question, so a bundle that needs newer native plugins never reaches an app
51
52
  that cannot run it.
@@ -133,7 +134,7 @@ navigation through. The same code therefore runs in `ng serve` and on the web.
133
134
 
134
135
  Upload `4.80.0` to the gateway, and add a rule such as
135
136
  `{ "when": { "storeID": ["2020210"] }, "bundle": "4.80.0" }`. Devices of that
136
- store pick it up at their next navigation, while everyone else stays put. To
137
+ store pick it up at their next start, while everyone else stays put. To
137
138
  widen the rollout, change the rule. To back out, block the bundle in the admin
138
139
  UI.
139
140
 
@@ -220,10 +221,10 @@ built-in one. Off the native platform it does nothing.
220
221
  1. **Ask.** The first `check` for a set of facts posts them, along with the
221
222
  native app version, to `POST /__gateway/data`. This happens once per
222
223
  session, through Capacitor's native HTTP, so CORS does not apply.
223
- 2. **Answer from memory.** The last answer is kept. While it names the running
224
- bundle, or one that rolled back, `check` returns `true` at once and the
225
- question runs in the background. An update it finds installs at the next
226
- navigation.
224
+ 2. **Wait for the answer.** That first `check` waits for the gateway. When the
225
+ answer names the running bundle, or one that rolled back, it returns `true`,
226
+ and so does every later `check` for those facts, at once. Otherwise the
227
+ update installs before the navigation goes on.
227
228
  3. **Verify.** The pilot fetches `bundle.sha256` and its signature, and checks
228
229
  them with WebCrypto Ed25519. An unsigned or tampered bundle is never
229
230
  downloaded.
@@ -241,7 +242,6 @@ current bundle and is not retried until the next start.
241
242
 
242
243
  | Key | |
243
244
  |---|---|
244
- | `ota.decision` | the gateway's last answer, so a start never waits on it |
245
245
  | `ota.trying` | the bundle being started, to detect a rollback |
246
246
  | `ota.failed` | the last bundle that rolled back; it is not offered again |
247
247
  | `ota.manifest.<id>` | the digest of the manifest a downloaded bundle came from |
package/dist/index.d.ts CHANGED
@@ -15,9 +15,9 @@ export interface OtaOptions {
15
15
  * A Pilot for native apps: asks the OTA gateway which bundle these facts get, verifies its signed
16
16
  * manifest, downloads it with Capgo and reloads into it. Off the native platform it always stays.
17
17
  *
18
- * One question per facts per session. While the last answer for these facts needs no update, check()
19
- * goes on at once and the question revalidates in the background; an update it finds installs at the
20
- * next navigation. A failure stays and is not retried that session.
18
+ * One question per facts per session. The first check() for these facts waits for the answer, so an
19
+ * update installs before the app goes on; once the answer needs no update, check() goes on at once.
20
+ * A failure stays and is not retried that session.
21
21
  */
22
22
  export declare function createOtaPilot(o: OtaOptions): Pilot;
23
23
  /**
package/dist/index.js CHANGED
@@ -5,29 +5,24 @@ import { CapacitorUpdater } from '@capgo/capacitor-updater';
5
5
  import { entries, verifyManifest } from './manifest.js';
6
6
  const TIMEOUT = 5000; // per request
7
7
  const DOWNLOAD_TIMEOUT = 60_000;
8
- // The first three are kept from the app this code came from, so devices in the field keep their state.
8
+ // Kept from the app this code came from, so devices in the field keep their state.
9
9
  const TRYING = 'ota.trying'; // the bundle set() is about to start
10
10
  const FAILED = 'ota.failed'; // a bundle Capgo rolled back: never offered again
11
11
  const MANIFEST = 'ota.manifest.'; // + bundle id: digest of the manifest it was downloaded with
12
- const DECISION = 'ota.decision'; // the gateway's last answer, { key, bundle }, so a start never waits on it
13
12
  /**
14
13
  * A Pilot for native apps: asks the OTA gateway which bundle these facts get, verifies its signed
15
14
  * manifest, downloads it with Capgo and reloads into it. Off the native platform it always stays.
16
15
  *
17
- * One question per facts per session. While the last answer for these facts needs no update, check()
18
- * goes on at once and the question revalidates in the background; an update it finds installs at the
19
- * next navigation. A failure stays and is not retried that session.
16
+ * One question per facts per session. The first check() for these facts waits for the answer, so an
17
+ * update installs before the app goes on; once the answer needs no update, check() goes on at once.
18
+ * A failure stays and is not retried that session.
20
19
  */
21
20
  export function createOtaPilot(o) {
22
21
  if (!Capacitor.isNativePlatform() || !o.gateway || !o.publicKey)
23
22
  return { version: o.version, check: () => true };
24
23
  const api = `${o.gateway.replace(/\/+$/, '')}/__gateway`;
25
24
  const stays = (v) => !v || v === o.version || v === localStorage.getItem(FAILED);
26
- let last = null;
27
- try {
28
- last = JSON.parse(localStorage.getItem(DECISION) ?? 'null');
29
- }
30
- catch { }
25
+ let last = null; // this session's answer
31
26
  const asked = new Map();
32
27
  let installing;
33
28
  const ask = (k, facts) => App.getInfo()
@@ -43,7 +38,6 @@ export function createOtaPilot(o) {
43
38
  if (typeof v !== 'string' || !v)
44
39
  return null;
45
40
  last = { key: k, bundle: v };
46
- localStorage.setItem(DECISION, JSON.stringify(last));
47
41
  return v;
48
42
  })
49
43
  .catch(() => null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bundle-pilot/capacitor",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "Over-the-air updates for Capacitor apps: install the signed bundle Bundle Pilot picks, with Capgo.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -23,7 +23,7 @@
23
23
  "dist"
24
24
  ],
25
25
  "dependencies": {
26
- "@bundle-pilot/core": "0.2.3"
26
+ "@bundle-pilot/core": "0.3.0"
27
27
  },
28
28
  "peerDependencies": {
29
29
  "@capacitor/app": ">=8.0.0",