List and install packages
Browse the package catalog from your app, install and remove packages, and offer updates.
Find packages
datumhue.packages reads the catalog: the packages of every registry
your deployment serves, grouped by namespace. Its reads return at once,
with what the workstation knows at that moment, and the catalog keeps
itself current. Browsing needs no permission.
packages.listlists every package, or those of one kind or one namespace.packages.searchmatches a pattern against each package's name and description. In the pattern,*stands for any run of characters and?for one. The pattern must match the whole name or description, so search for*chart*rather thanchart.packages.infolooks up one package by its exact@scope/name.packages.on_changecalls your function for each package that is published or updated while your app runs.
Each returns PackageRef values. Show people a package's
PackageRef.title, never its @scope/name. The title comes from the
manifest, or is made from the package's name, so every app that lists
packages shows the same one.
local packages = datumhue.packages
local list = datumhue.ui.root:panel({
flex_direction = "column",
gap = 8,
})
local function show(ref)
local row = list:panel({ flex_direction = "row", gap = 12 })
row:label({ text = ref.title })
row:label({ text = ref:version() })
end
for _, ref in ipairs(packages.search({ query = "*chart*" })) do
show(ref)
end
-- Packages published from now on show up as they arrive.
packages.on_change(function(change)
if change.kind == "added" then
show(change.package)
end
end)
Install and remove
Installing, removing and reading what is installed take the packages
permission, which a package asks for with capabilities "packages".
Browsing the catalog does not. PackageRef:install starts
downloading that exact version, with what it depends on, and returns an
operation you can wait on or give a callback:
local ref = datumhue.packages.info("@studio/charts")
local status = datumhue.ui.root:label({
text = "Installing " .. ref.title,
})
local op = ref:install()
op:on_done(function()
local ok, err = pcall(op.ready, op)
if ok then
status.text = ref.title .. " is installed."
else
status.text = "Couldn't install " .. ref.title .. ". "
.. tostring(err)
end
end)
Op:on_donecalls your function once the install has finished or failed. Inside it,Op:readyreturns at once, or raises the failure.- When installing, removing or loading a package fails, the error is one plain sentence for the person using your app, such as "Close Charts before removing it." Show it as it is, after your own line saying what did not happen, and never parse it: its wording can change.
PackageRef:uninstallremoves a package, whichever version is installed. It raises while an app runs from it.packages.installedlists the installed packages, without asking the deployment.
To start a package, pass its ref to datumhue.app.spawn as
package_ref. The app starts once its package has arrived
(Launch other apps).
Offer an update
A running app knows which catalog package it runs: App.package_ref is
the ref it started from, at that version. Installing an update replaces
the installed copy, never the code of an app already running. So to
offer a restart that picks the update up, a window manager compares a
running app's PackageRef:version with its
PackageRef:installed_version, which, like packages.installed, takes
the packages permission.
See also
Reference used on this page: datumhue.packages datumhue.ui.root UiElement:panel UiElement:label datumhue.packages.search datumhue.packages.on_change datumhue.packages.info PackageRef.title PackageRef:install Op:on_done Op:ready UiElement.text datumhue.packages.list PackageRef:uninstall datumhue.packages.installed datumhue.app.spawn App.package_ref PackageRef:version PackageRef:installed_version