Save data between runs
Keep what your app needs next time, such as settings, progress or a cache, in a store that is still there after your app quits.
Your package's own store
storage.open opens your app's own store, which keeps bytes under
string keys. The store follows your package: the same package reaches
the same data in every run, in every copy running at once and in every
later version, and no other app can open it. Give storage.open a
label to open another store of the same package, kept apart from the
first.
local bytes = datumhue.bytes
local storage = datumhue.storage
-- This package's own store: count the runs.
local own = storage.open()
local saved = own:get("runs"):ready().value
local runs = (saved and saved:json() or 0) + 1
own:set("runs", bytes.json(runs)):ready()
print("runs: " .. runs)
-- A second store of the same package, kept apart by its label.
local drafts = storage.open("drafts")
drafts:set("today", bytes.json({ "flour", "eggs" })):ready()
drafts:set("tomorrow", bytes.json({ "butter" })):ready()
local keys = drafts:list():ready().value
print("drafts: " .. table.concat(keys, ", "))
-- Every package under the same scope sees this store.
local team = storage.open_scoped("shared-notes")
team:set("hello", bytes("from notes")):ready()
-- Every app that passes the same UUID sees this one.
local board_id = "1b4e28ba-2fa1-11d2-883f-0016d3cca427"
local board = storage.open_shared(board_id)
print("board keys: " .. #board:list():ready().value)
In this example: datumhue.bytes datumhue.storage datumhue.storage.open Storage:get BytesFetch:ready BytesFetch.value Bytes:json Storage:set datumhue.bytes.json Op:ready Storage:list ListFetch:ready ListFetch.value datumhue.storage.open_scoped datumhue.storage.open_shared
The first run prints runs: 1, the next runs: 2, and so on.
- A store holds
Bytes. Turn a table or a number into bytes withdatumhue.bytes.json, and back withBytes:json. Storage:getreturns a fetch that waits for the value; itsvalueis nil when the key is not there.Storage:setandStorage:deletestart at once and return an operation.:ready()waits for a fetch or an operation, and raises if it failed. Waiting explains these handles, and how to wait for several at once.Storage:listlists the keys in order, or those that start with a prefix you give it.
Who else sees a store
| Opened with | Shared with |
|---|---|
storage.open | this package only |
storage.open_scoped | every package under the same scope, such as @alice |
storage.open_shared | every app that passes the same UUID |
A store shared by UUID is as private as the UUID. One written into
published code is public; one your app keeps to itself works as a key.
datumhue.uuid makes a new one.
An app your app starts from Lua source opens your package's stores.
Start it with storage = "own", and it opens stores of its own
instead, kept between runs
(Launch other apps).
A package you run from a folder or a file with datumhue run is
known by its name alone. Any app you run that way under the same name
opens the same stores, so they are as private as your workstation.
A package installed from the catalog is also known by where it came from. It opens other stores than the same package run from a folder, so trying out your code never touches the data of the installed copy.
See also
- Waiting: suspending calls and handles, for
:ready()and the handles a store returns. - Messages, events and shared state, for values other apps can watch change.
- Open, pick and save files, for files a person can see and move.
Reference used on this page: datumhue.bytes datumhue.storage datumhue.storage.open Storage:get BytesFetch:ready BytesFetch.value Bytes:json Storage:set datumhue.bytes.json Op:ready Storage:list ListFetch:ready ListFetch.value datumhue.storage.open_scoped datumhue.storage.open_shared Storage:delete datumhue.uuid