index ↓
doc
client.doc Key/value state the active webapp shares with the companion app. get, list, set, and
delete read and write it, and onChanged reports the writes the companion app makes.
requests
you ask, the daemon answers. await the tagged result and check .ok
get(DocGet): Promise<TypedRequestResult<DocGetReply, never>>
push form: onGet (subscribe instead of awaiting)
Returns one doc value for the active webapp.
const res = await client.doc.get({ key: '...' });
if (res.ok) {
console.log(res.response.key);
} type Result =
| { ok: true; response: DocGetReply }
| { ok: false; kind: 'domain'; error: never }
| { ok: false; kind: 'protocol'; error: WireError }; list(): Promise<TypedRequestResult<DocListReply, never>>
push form: onList (subscribe instead of awaiting)
Returns every doc value for the active webapp.
const res = await client.doc.list();
if (res.ok) {
console.log(res.response.entries);
} type Result =
| { ok: true; response: DocListReply }
| { ok: false; kind: 'domain'; error: never }
| { ok: false; kind: 'protocol'; error: WireError }; set(DocSet): Promise<TypedRequestResult<DocAck, WebappError>>
push form: onAck (subscribe instead of awaiting)
Writes a doc value. Keep it at or under 256 KiB.
const res = await client.doc.set({ key: '...', value: '...' });
if (res.ok) {
console.log(res.response.key);
} else {
console.warn(res.kind, res.error);
} type Result =
| { ok: true; response: DocAck }
| { ok: false; kind: 'domain'; error: WebappError }
| { ok: false; kind: 'protocol'; error: WireError }; delete(DocDelete): Promise<TypedRequestResult<DocAck, never>>
push form: onAck (subscribe instead of awaiting)
const res = await client.doc.delete({ key: '...' });
if (res.ok) {
console.log(res.response.key);
} type Result =
| { ok: true; response: DocAck }
| { ok: false; kind: 'domain'; error: never }
| { ok: false; kind: 'protocol'; error: WireError }; events
the daemon pushes these unprompted. subscribing returns an unsubscribe function
onChanged(handler: (DocChanged) => void): () => void
const off = client.doc.onChanged((docChanged) => {
console.log(docChanged.key);
});
// call off() to unsubscribe types
shapes referenced above, as the sdk types them
type DocChanged = {
key: string;
value?: string; // Null when the entry was deleted.
}; Returns one doc value for the active webapp.
type DocGet = {
key: string;
}; type DocGetReply = {
key: string;
value?: string; // Null when the key is unset.
}; type DocListReply = {
entries: DocEntry[];
}; Writes a doc value. Keep it at or under 256 KiB.
type DocSet = {
key: string;
value: string;
}; The stored value after a set or delete.
type DocAck = {
key: string;
value?: string;
}; type WebappError =
| 'webappNotFound'
| 'cannotUninstallBuiltin'
| 'idReserved' // The manifest id is one the device reserves. Give the webapp a different uuid.
| 'extractedTooLarge' // The extracted bundle is over the 1 GiB cap.
| 'provenanceTooLong' // The provenance string is over 2048 bytes.
| 'zipMalformed'
| 'missingIndexHtml' // Put an `index.html` at the root of the bundle.
| 'invalidManifest' // `manifest.json` is missing, unparseable, or failed validation. `reason` says which.
| 'resourceNotAvailable' // The manifest must declare the resource and the file must exist in the bundle.
| 'notALauncher' // A bundle must declare `role` as `launcher` to take the launcher slot.
| 'noOverlay' // A bundle must declare `overlay` to take the overlay slot.
| 'unknownConfigKey' // The manifest declares no config field with this key.
| 'invalidConfigValue' // The value failed the field's declared constraints. `reason` says which.
| 'invalidDocValue' // The doc value is over 256 KiB.
| 'internal' // An unexpected failure.; type DocDelete = {
key: string;
}; Both the webapp and the companion app write it, and the last write wins. Values are strings.
type DocEntry = {
key: string;
value: string;
};