Packaging and updates.
There is no build to upload. Devices run what a branch of your repository holds, packed and sealed by ArdaForm. A new version is downloaded and staged on each device, and your app is asked before it reloads.
From a push to a device
- Connect once. Install the ArdaForm GitHub App on the account that owns the repository; in the project's Connectors tab connect a project branch to a repository, the folder that holds
index.html(usuallyapp) and a git branch. Step by step: quickstart step 6. - Push. ArdaForm reads the new head and packs that commit's folder into a sealed container (what is packed). Nothing is executed.
- The manifest is reconciled at the same moment: missing datasets and settings are created, definitions updated (changes). A manifest fault fails the pack and no device is told.
- Every device on the branch is told, within seconds and together. Each fetches the container, verifies it, stages it, and asks the app (below).
- A project branch reads one git ref; a device follows one project branch. Staging and production are two branches.
- The Connectors tab shows the commit each branch has read; the Code tab its latest push and how many devices run it.
- A commit that changes only
gui/ormarketplace/updates no device.
When it applies: the branch's policy
| Policy (Code tab › branch) | On the device |
|---|---|
As soon as they arrive (asap, the default) | stages it and asks the app at once |
Inside a time window (timed, HH:MM–HH:MM in the device's local time; may cross midnight) | stages it; asks only inside the window |
Only when the app asks (manual) | stages it; waits for Arda.update.apply(). A restart does not apply it. |
The app picks the moment
The player is going, and you opt out. Say nothing and it applies five seconds after asking — which is what keeps a shop's screens changing together.
updateStart ──you say nothing for 5 s──▶ applied
│
pause() ──▶ 60 s ──no apply()──▶ updateStart again (at most 5 times) ──▶ held until the next restart
└─ apply() ──▶ applied, on your terms
Arda.on('update', function (u) {
// staged — including outside a time window, when nothing is about to happen
showBanner('Version ' + u.version + ' is ready');
});
Arda.on('updateStart', function (u) {
// u = {kind, version, sha256, mode, urgent, from, to, ask, ofAsks, decideInMs, pauseForMs}
if (!midSale()) return; // say nothing: it applies in 5 seconds
Arda.update.pause(); // not yet: buys u.pauseForMs
afterSale(function () {
saveDraft(); // nothing after apply() is guaranteed to run
Arda.update.apply();
});
});
- Doing nothing is the right answer for most apps, and the fast one.
pause()resolves{paused: true}.{paused: false}means nothing was being asked — not a failure. It is not a veto:u.askofu.ofAskstells you which round you are on.- After the last round the player stops asking and leaves the update staged; it is applied at the next restart, and the portal shows the device as holding one.
apply()applies now. For an app update that is a page reload; finish the transaction and save what you hold first.Arda.update.pending()answers{ready, kind, version, sha256, mode, urgent, from, to, asking, asks, ofAsks}ornull;askingis'','asking','postponed'or'held'. Useful after a reload in the middle of a round.- On a
manualbranchupdateStartnever fires: callapply()when it suits you (after'update', or whenpending()says one is ready). - A restart applies anything staged, with no question asked, except on a
manualbranch. - An operator can press Apply update on the device's screen in the portal. It asks the app nothing: a person decided the app's answer was wrong.
Player updates
The player updates itself through the same events. u.kind is 'app' or 'player' (an older player sends none: read that as 'app').
- An ordinary player release is taken at the device's next restart, with nothing for the app to do.
- One marked important is applied now, through the negotiation:
updateStartwithkind: 'player', answered with the samepause()/apply(). Applying restarts the whole player (a few seconds), not only the page. - When an app update and an important player update are both waiting, you are asked about the player only; the staged app goes in while the player comes back up.
pending().versionis the version of whatever is being asked about — the player's, when it holds the floor.- A new player that does not come up cleanly is put back to the previous one by the device itself; the portal then shows the device with a player update rolled back alert until it runs a newer one.
Going back
To go back, push the old code again (a revert commit). The manifest reconcile never deletes, so the older release finds its datasets where it left them.
Checked: Arda.update.pending() answering null with nothing staged was observed in a local run; the event and field names are from ArdaJS(). The negotiation's timings (5 s, 60 s, five rounds) are the player's (internal/client/updateask.go, described in its manual). A live update round was not driven against a device for this page.