OverviewFilesCommitsIssuesDocsReleasesPeers

favela-surface-android / lib / bootstrap.js

31 lines · javascript ref:
// The worklet bundle's entry. Registers any OTA-staged native addons, then starts the node.
//
// ⛔ THIS IS WHAT MAKES NATIVE UPDATES DELIVERABLE WITHOUT A SIDELOAD. A `linked:` bundle NAMES the
// sonames the APK must supply, so for as long as only the APK could satisfy them, any native change
// meant a 154 MB sideload. Bare's Addon class removes that: `new Addon(fileURL)` dlopens an ABSOLUTE
// PATH, and Addon.cache — keyed by url.href and consulted by the `linked:` branch of Addon.resolve —
// lets a staged file answer to the soname the bundle asks for.
//
// ⛔ AND IT LIVES IN THE BUNDLE, NOT THE APK. A preloader that shipped only in the shell would put the
// capability behind an APK release, which is the cost this exists to remove. It does not need to be
// there: a module inside a bundle knows where its bundle is (import.meta.url is
// `file:///…/<hash>.bundle/lib/bootstrap.js`), so it finds the addons staged beside it unaided. That
// means THIS file reaches a device over the OTA that already works, on the APK already installed.
//
// ⛔ THE ONLY STATIC IMPORT THAT COSTS AN ADDON IS bare-fs, through preload-addons.js. Everything
// imported here runs BEFORE the staged addons are registered, so it must already be satisfiable by the
// APK on the device. Keeping that surface at one soname is what decides how many future releases can
// carry native code without a new APK.
import { addonsDirFor } from './host/loader-core.js'
import { preloadAddons } from './host/preload-addons.js'

const dir = addonsDirFor(import.meta.url)
const n = preloadAddons({ dir, say: (m) => console.log('[bootstrap] ' + m) })
console.log('[bootstrap] ' + (dir === null ? 'not running from a bundle — no staged addons' : 'preloaded ' + n + ' staged addon(s) from ' + dir))

// ⛔ DYNAMIC, and that is the entire point. A static import is hoisted and evaluated before the code
// above, so every addon the node needs would be resolved — and dlopened by soname against the APK —
// before a single staged one was registered. Importing here, after preloadAddons has returned, is the
// ordering the whole mechanism depends on.
await import('./node.js')