@bridgething/browser 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # @bridgething/browser
2
+
3
+ Drive a [bridgething](https://github.com/JoeyEamigh/bridgething) Spotify Car Thing
4
+ from a web page: install and switch webapps, push daemon and image updates, rename
5
+ the device.
6
+
7
+ ```sh
8
+ bun add @bridgething/browser
9
+ ```
10
+
11
+ ## Connecting
12
+
13
+ ```ts
14
+ import { Device } from '@bridgething/browser';
15
+
16
+ // over the usb-c cable, via the daemon's network gateway
17
+ const device = await Device.overNetwork('bridgething.local');
18
+
19
+ // or over an already-paired bluetooth peer, via Web Serial
20
+ const device = await Device.overSerial();
21
+ ```
22
+
23
+ `overSerial()` resolves null when the user dismisses the chooser. Use
24
+ `serialAvailable()` to decide whether to offer it at all; iOS Safari and Firefox
25
+ have no Web Serial.
26
+
27
+ ## Driving a device
28
+
29
+ ```ts
30
+ const meta = await device.meta();
31
+ const webapps = await device.webapps();
32
+
33
+ await device.switchWebapp(webapps[0].id);
34
+ await device.installWebapp(
35
+ new Uint8Array(await bundle.arrayBuffer()),
36
+ catalogUrl,
37
+ );
38
+ await device.setNickname('the dashboard');
39
+ ```
40
+
41
+ Updates are a push plus a feed:
42
+
43
+ ```ts
44
+ const phase = await device.push('daemon', binary);
45
+ if (phase.kind === 'failed') console.error(phase.reason);
46
+ ```
47
+
48
+ Manifest helpers - `fetchManifest`, `compositeVersion`, `otaArtifactUrls` - read
49
+ the same discover manifest the device does, so a page can work out what a device
50
+ should be running.
@@ -0,0 +1,42 @@
1
+ import type { BridgeThingMeta, WebappInfo } from '@bridgething/lib';
2
+ import type { DeviceNicknameReply, WebappActive, WebappSlot, WebappSlots } from '@bridgething/lib/gateway';
3
+ import type { ArtifactUrls, CompositeVersion, InstalledWebapp, OtaDiscoverManifest, OtaUpdateKind, Phase, UpdateEvent } from '../wasm/core-wasm.js';
4
+ import { type SerialPort } from './web-serial.js';
5
+ export type { ArtifactDigest, ArtifactUrls, CompositeVersion, InstalledWebapp, OtaDiscoverManifest, OtaManifestChannel, OtaManifestRelease, OtaPatchDigest, OtaReleaseArtifacts, OtaUpdateKind, Phase, PhaseKind, PlanStep, UpdateEvent, } from '../wasm/core-wasm.js';
6
+ export { permittedSerialPorts, requestSerialPort, serialAvailable } from './web-serial.js';
7
+ export type { SerialPort } from './web-serial.js';
8
+ export declare const DEFAULT_HOST = "bridgething.local";
9
+ export declare function ready(): Promise<unknown>;
10
+ export declare function gatewayUrl(host: string): string;
11
+ export declare function fetchManifest(rootUrl: string): Promise<OtaDiscoverManifest>;
12
+ export declare function compositeVersion(raw: string): Promise<CompositeVersion | null>;
13
+ export declare function otaArtifactUrls(opts: {
14
+ rootUrl: string;
15
+ channel: string;
16
+ daemonVersion: string;
17
+ imageVersion: string;
18
+ imageVariant: string;
19
+ }): Promise<ArtifactUrls>;
20
+ export declare class Device {
21
+ private readonly session;
22
+ private readonly detach;
23
+ private constructor();
24
+ static overNetwork(host?: string): Promise<Device>;
25
+ static overSerial(port?: SerialPort): Promise<Device | null>;
26
+ get id(): string;
27
+ meta(): Promise<BridgeThingMeta | null>;
28
+ webapps(): Promise<WebappInfo[]>;
29
+ activeWebapp(): Promise<WebappActive>;
30
+ webappSlots(): Promise<WebappSlots>;
31
+ switchWebapp(id: string): Promise<WebappActive>;
32
+ uninstallWebapp(id: string): Promise<WebappActive>;
33
+ setWebappSlot(slot: WebappSlot, id: string | null): Promise<WebappSlots>;
34
+ setNickname(nickname: string): Promise<DeviceNicknameReply>;
35
+ installWebapp(bundle: Uint8Array, provenance?: string): Promise<InstalledWebapp>;
36
+ push(kind: Exclude<OtaUpdateKind, 'image'>, artifact: Uint8Array, label?: string): Promise<Phase>;
37
+ pushImage(swu: Uint8Array, zcks: Map<string, Uint8Array>, updateUrlBase?: string): Promise<Phase>;
38
+ nextEvent(): Promise<UpdateEvent>;
39
+ closed(): Promise<void>;
40
+ close(): Promise<void>;
41
+ }
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,100 @@
1
+ import { BRIDGETHING_DEFAULT_HOST, BRIDGETHING_NETWORK_GATEWAY_PORT } from '@bridgething/lib';
2
+ import initWasm, { ByteLink, DeliverySession, artifactUrls, discoverManifest, parseCompositeVersion, } from '../wasm/core-wasm.js';
3
+ import { pumpSerialPort, requestSerialPort } from './web-serial.js';
4
+ export { permittedSerialPorts, requestSerialPort, serialAvailable } from './web-serial.js';
5
+ export const DEFAULT_HOST = BRIDGETHING_DEFAULT_HOST;
6
+ let started = null;
7
+ export function ready() {
8
+ started ??= initWasm();
9
+ return started;
10
+ }
11
+ export function gatewayUrl(host) {
12
+ const trimmed = host
13
+ .trim()
14
+ .replace(/^wss?:\/\//, '')
15
+ .replace(/\/+$/, '');
16
+ return `ws://${trimmed.includes(':') ? trimmed : `${trimmed}:${BRIDGETHING_NETWORK_GATEWAY_PORT}`}/`;
17
+ }
18
+ export async function fetchManifest(rootUrl) {
19
+ await ready();
20
+ return discoverManifest(rootUrl);
21
+ }
22
+ export async function compositeVersion(raw) {
23
+ await ready();
24
+ return parseCompositeVersion(raw);
25
+ }
26
+ export async function otaArtifactUrls(opts) {
27
+ await ready();
28
+ return artifactUrls(opts.rootUrl, opts.channel, opts.daemonVersion, opts.imageVersion, opts.imageVariant);
29
+ }
30
+ export class Device {
31
+ session;
32
+ detach;
33
+ constructor(session, detach) {
34
+ this.session = session;
35
+ this.detach = detach;
36
+ }
37
+ static async overNetwork(host = DEFAULT_HOST) {
38
+ await ready();
39
+ const session = await DeliverySession.connect(gatewayUrl(host), undefined);
40
+ return new Device(session, async () => { });
41
+ }
42
+ static async overSerial(port) {
43
+ const opened = port ?? (await requestSerialPort());
44
+ if (!opened)
45
+ return null;
46
+ await ready();
47
+ let write = () => Promise.resolve();
48
+ const link = new ByteLink(chunk => write(chunk));
49
+ const pump = pumpSerialPort(opened, chunk => link.push(chunk), () => link.close());
50
+ write = chunk => pump.write(chunk);
51
+ const session = await DeliverySession.attach(link, undefined);
52
+ return new Device(session, () => pump.close());
53
+ }
54
+ get id() {
55
+ return this.session.deviceId;
56
+ }
57
+ meta() {
58
+ return this.session.meta();
59
+ }
60
+ webapps() {
61
+ return this.session.webapps();
62
+ }
63
+ activeWebapp() {
64
+ return this.session.activeWebapp();
65
+ }
66
+ webappSlots() {
67
+ return this.session.webappSlots();
68
+ }
69
+ switchWebapp(id) {
70
+ return this.session.switchWebapp(id);
71
+ }
72
+ uninstallWebapp(id) {
73
+ return this.session.uninstallWebapp(id);
74
+ }
75
+ setWebappSlot(slot, id) {
76
+ return this.session.setWebappSlot(slot, id ?? undefined);
77
+ }
78
+ setNickname(nickname) {
79
+ return this.session.setNickname(nickname);
80
+ }
81
+ installWebapp(bundle, provenance) {
82
+ return this.session.installWebapp(bundle, provenance);
83
+ }
84
+ push(kind, artifact, label) {
85
+ return this.session.push(kind, artifact, label);
86
+ }
87
+ pushImage(swu, zcks, updateUrlBase) {
88
+ return this.session.pushImage(swu, zcks, updateUrlBase);
89
+ }
90
+ nextEvent() {
91
+ return this.session.nextEvent();
92
+ }
93
+ closed() {
94
+ return this.session.closed();
95
+ }
96
+ close() {
97
+ return this.detach();
98
+ }
99
+ }
100
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ declare global {
2
+ interface Navigator {
3
+ readonly serial?: SerialAPI;
4
+ }
5
+ }
6
+ type SerialAPI = {
7
+ requestPort(options?: SerialPortRequestOptions): Promise<SerialPort>;
8
+ getPorts(): Promise<SerialPort[]>;
9
+ };
10
+ type SerialPortRequestOptions = {
11
+ filters?: SerialPortFilter[];
12
+ allowedBluetoothServiceClassIds?: string[];
13
+ };
14
+ type SerialPortFilter = {
15
+ bluetoothServiceClassId?: string;
16
+ };
17
+ type SerialPortInfo = {
18
+ bluetoothServiceClassId?: string;
19
+ usbVendorId?: number;
20
+ usbProductId?: number;
21
+ };
22
+ export type SerialPort = {
23
+ open(options: {
24
+ baudRate: number;
25
+ }): Promise<void>;
26
+ close(): Promise<void>;
27
+ getInfo(): SerialPortInfo;
28
+ readonly readable: ReadableStream<Uint8Array> | null;
29
+ readonly writable: WritableStream<Uint8Array> | null;
30
+ addEventListener(event: 'disconnect', listener: () => void): void;
31
+ removeEventListener(event: 'disconnect', listener: () => void): void;
32
+ };
33
+ export declare function serialAvailable(): boolean;
34
+ export declare function requestSerialPort(serviceUuid?: string): Promise<SerialPort | null>;
35
+ export declare function permittedSerialPorts(serviceUuid?: string): Promise<SerialPort[]>;
36
+ export type SerialPump = {
37
+ write(chunk: Uint8Array): Promise<void>;
38
+ close(): Promise<void>;
39
+ };
40
+ export declare function pumpSerialPort(port: SerialPort, onBytes: (chunk: Uint8Array) => void, onClosed: () => void): SerialPump;
41
+ export {};
42
+ //# sourceMappingURL=web-serial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-serial.d.ts","sourceRoot":"","sources":["../src/web-serial.ts"],"names":[],"mappings":"AAEA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,SAAS;QACjB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;KAC7B;CACF;AAED,KAAK,SAAS,GAAG;IACf,WAAW,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACrE,QAAQ,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;CACnC,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B,+BAA+B,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5C,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,IAAI,cAAc,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;IACrD,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;IACrD,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAClE,mBAAmB,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CACtE,CAAC;AAIF,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,wBAAsB,iBAAiB,CAAC,WAAW,GAAE,MAAiC,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAiBlH;AAED,wBAAsB,oBAAoB,CAAC,WAAW,GAAE,MAAiC,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAKhH;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,wBAAgB,cAAc,CAC5B,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,EACpC,QAAQ,EAAE,MAAM,IAAI,GACnB,UAAU,CAwCZ"}
@@ -0,0 +1,74 @@
1
+ import { BRIDGETHING_PROFILE_UUID } from '@bridgething/lib';
2
+ const SERIAL_BAUD_RATE = 9600;
3
+ export function serialAvailable() {
4
+ return typeof navigator !== 'undefined' && 'serial' in navigator;
5
+ }
6
+ export async function requestSerialPort(serviceUuid = BRIDGETHING_PROFILE_UUID) {
7
+ const serial = navigator.serial;
8
+ if (!serial) {
9
+ throw new Error('navigator.serial is unavailable - Web Serial is Chromium-only (Chrome 117+ desktop, Chrome 138+ Android). Use the companion app on iOS Safari.');
10
+ }
11
+ let port;
12
+ try {
13
+ port = await serial.requestPort({ allowedBluetoothServiceClassIds: [serviceUuid] });
14
+ }
15
+ catch (err) {
16
+ if (err instanceof DOMException && err.name === 'NotFoundError')
17
+ return null;
18
+ throw err;
19
+ }
20
+ await port.open({ baudRate: SERIAL_BAUD_RATE });
21
+ return port;
22
+ }
23
+ export async function permittedSerialPorts(serviceUuid = BRIDGETHING_PROFILE_UUID) {
24
+ const serial = navigator.serial;
25
+ if (!serial)
26
+ return [];
27
+ const ports = await serial.getPorts();
28
+ return ports.filter(port => port.getInfo().bluetoothServiceClassId?.toLowerCase() === serviceUuid.toLowerCase());
29
+ }
30
+ export function pumpSerialPort(port, onBytes, onClosed) {
31
+ const reader = port.readable?.getReader();
32
+ const writer = port.writable?.getWriter();
33
+ if (!reader || !writer)
34
+ throw new Error('web-serial: port has no readable/writable stream');
35
+ let done = false;
36
+ const finish = () => {
37
+ if (done)
38
+ return;
39
+ done = true;
40
+ port.removeEventListener('disconnect', finish);
41
+ onClosed();
42
+ };
43
+ port.addEventListener('disconnect', finish);
44
+ const reading = (async () => {
45
+ try {
46
+ for (;;) {
47
+ const { value, done: eof } = await reader.read();
48
+ if (eof)
49
+ break;
50
+ if (value && value.byteLength > 0)
51
+ onBytes(value);
52
+ }
53
+ }
54
+ catch (err) {
55
+ if (err instanceof Error && err.name !== 'AbortError') {
56
+ console.error('[bridgething] web-serial read loop error', err);
57
+ }
58
+ }
59
+ finally {
60
+ finish();
61
+ }
62
+ })();
63
+ return {
64
+ write: chunk => writer.write(chunk),
65
+ async close() {
66
+ finish();
67
+ await reader.cancel().catch(() => { });
68
+ await writer.close().catch(() => { });
69
+ await reading;
70
+ await port.close().catch(() => { });
71
+ },
72
+ };
73
+ }
74
+ //# sourceMappingURL=web-serial.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-serial.js","sourceRoot":"","sources":["../src/web-serial.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@bridgething/browser",
3
+ "version": "0.4.0",
4
+ "description": "Drive a Spotify Car Thing from the browser: the bridgething delivery core compiled to wasm, plus the Web Serial and network transports.",
5
+ "license": "MIT",
6
+ "author": "Joey Eamigh <55670930+JoeyEamigh@users.noreply.github.com> (https://github.com/JoeyEamigh)",
7
+ "homepage": "https://bridgething.com",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/JoeyEamigh/bridgething.git",
11
+ "directory": "packages/browser"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/JoeyEamigh/bridgething/issues"
15
+ },
16
+ "keywords": [
17
+ "bridgething",
18
+ "spotify",
19
+ "car-thing",
20
+ "superbird",
21
+ "web-serial",
22
+ "wasm"
23
+ ],
24
+ "publishConfig": {
25
+ "access": "public",
26
+ "registry": "https://registry.npmjs.org/"
27
+ },
28
+ "type": "module",
29
+ "types": "./dist/index.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.js"
34
+ }
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "wasm"
39
+ ],
40
+ "scripts": {
41
+ "prebuild": "rm -rf dist && bun run wasm",
42
+ "wasm": "wasm-pack build ../../crates/delivery/wasm --target web --out-dir ../../../packages/browser/wasm --out-name core-wasm && rm -f wasm/package.json wasm/.gitignore",
43
+ "build": "tsc -p tsconfig.build.json",
44
+ "dev": "tsc -p tsconfig.build.json --watch",
45
+ "typecheck": "tsc --noEmit",
46
+ "lint": "eslint ."
47
+ },
48
+ "dependencies": {
49
+ "@bridgething/lib": "0.4.0"
50
+ },
51
+ "peerDependencies": {
52
+ "typescript": "^6.0.3"
53
+ }
54
+ }
@@ -0,0 +1,223 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ export type OtaUpdateKind = "image" | "daemon" | "builtinWebapp" | "installedWebapp" | "wakewordModel";
5
+
6
+ export type PhaseKind = "idle" | "downloading" | "streaming" | "applying" | "staged" | "completed" | "failed";
7
+
8
+ export interface Phase {
9
+ kind: PhaseKind;
10
+ asset?: string;
11
+ received?: number;
12
+ sent?: number;
13
+ total?: number;
14
+ ratePerSec?: number;
15
+ etaSeconds?: number;
16
+ writePercent?: number;
17
+ reason?: string;
18
+ }
19
+
20
+ export interface PlanStep {
21
+ id: number;
22
+ kind: "download" | "stream" | "apply" | "reboot";
23
+ label: string;
24
+ bytes: number;
25
+ }
26
+
27
+ export type UpdateEventKind =
28
+ | "manifestPolled"
29
+ | "manifestPollFailed"
30
+ | "updateAvailable"
31
+ | "planned"
32
+ | "progress"
33
+ | "updated"
34
+ | "failed"
35
+ | "lagged";
36
+
37
+ export interface UpdateEvent {
38
+ kind: UpdateEventKind;
39
+ deviceId?: string;
40
+ updateKind?: OtaUpdateKind;
41
+ release?: string;
42
+ daemonVersion?: string;
43
+ imageVersion?: string;
44
+ channel?: string;
45
+ rootUrl?: string;
46
+ version?: string;
47
+ updatedAt?: string;
48
+ reason?: string;
49
+ stepId?: number;
50
+ steps?: PlanStep[];
51
+ phase?: Phase;
52
+ }
53
+
54
+ export interface InstalledWebapp {
55
+ id: string;
56
+ name: string;
57
+ version: string;
58
+ provenance?: string;
59
+ }
60
+
61
+ export interface CompositeVersion {
62
+ daemon: string;
63
+ image: string;
64
+ }
65
+
66
+ export interface ArtifactUrls {
67
+ imageSwu: string;
68
+ imageZck: string;
69
+ imageBootZck: string;
70
+ daemonBinary: string;
71
+ daemonBinaryZst: string;
72
+ }
73
+
74
+ export interface ArtifactDigest {
75
+ size: number;
76
+ sha256: string;
77
+ }
78
+
79
+ export interface OtaPatchDigest {
80
+ size: number;
81
+ sha256: string;
82
+ sourceSha256: string | null;
83
+ }
84
+
85
+ export interface OtaReleaseArtifacts {
86
+ daemon: ArtifactDigest | null;
87
+ daemonZst: ArtifactDigest | null;
88
+ imageSwu: ArtifactDigest | null;
89
+ imageZck: ArtifactDigest | null;
90
+ imageBootZck: ArtifactDigest | null;
91
+ webapps: Record<string, ArtifactDigest>;
92
+ daemonPatches: Record<string, OtaPatchDigest>;
93
+ }
94
+
95
+ export interface OtaManifestChannel {
96
+ name: string;
97
+ stability: string;
98
+ isDefault: boolean;
99
+ latest: string;
100
+ releases: string[];
101
+ }
102
+
103
+ export interface OtaManifestRelease {
104
+ version: string;
105
+ channel: string;
106
+ yanked: string | null;
107
+ deprecated: boolean;
108
+ builtinWebapps: Record<string, string>;
109
+ artifacts: OtaReleaseArtifacts | null;
110
+ }
111
+
112
+ export interface OtaDiscoverManifest {
113
+ manifestVersion: number;
114
+ updatedAt: string;
115
+ channels: Record<string, OtaManifestChannel>;
116
+ releases: Record<string, OtaManifestRelease>;
117
+ }
118
+
119
+
120
+
121
+ export class ByteLink {
122
+ free(): void;
123
+ [Symbol.dispose](): void;
124
+ close(): void;
125
+ constructor(write: (chunk: Uint8Array) => Promise<void>);
126
+ push(chunk: Uint8Array): void;
127
+ }
128
+
129
+ export class DeliverySession {
130
+ private constructor();
131
+ free(): void;
132
+ [Symbol.dispose](): void;
133
+ activeWebapp(): Promise<any>;
134
+ static attach(link: ByteLink, device_id?: string | null): Promise<DeliverySession>;
135
+ closed(): Promise<void>;
136
+ static connect(url: string, device_id?: string | null): Promise<DeliverySession>;
137
+ installWebapp(bundle: Uint8Array, provenance?: string | null): Promise<InstalledWebapp>;
138
+ meta(): Promise<any>;
139
+ nextEvent(): Promise<UpdateEvent>;
140
+ push(kind: OtaUpdateKind, artifact: Uint8Array, label?: string | null): Promise<Phase>;
141
+ pushImage(swu: Uint8Array, zcks: Map<string, Uint8Array>, update_url_base?: string | null): Promise<Phase>;
142
+ setNickname(nickname: string): Promise<any>;
143
+ setWebappSlot(slot: "launcher" | "overlay", id?: string | null): Promise<any>;
144
+ switchWebapp(id: string): Promise<any>;
145
+ uninstallWebapp(id: string): Promise<any>;
146
+ webappSlots(): Promise<any>;
147
+ webapps(): Promise<any>;
148
+ readonly deviceId: string;
149
+ }
150
+
151
+ export function artifactUrls(root_url: string, channel: string, daemon_version: string, image_version: string, image_variant: string): ArtifactUrls;
152
+
153
+ export function discoverManifest(root_url: string): Promise<OtaDiscoverManifest>;
154
+
155
+ export function init(): void;
156
+
157
+ export function parseCompositeVersion(raw: string): CompositeVersion | null;
158
+
159
+ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
160
+
161
+ export interface InitOutput {
162
+ readonly memory: WebAssembly.Memory;
163
+ readonly __wbg_bytelink_free: (a: number, b: number) => void;
164
+ readonly __wbg_deliverysession_free: (a: number, b: number) => void;
165
+ readonly artifactUrls: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number) => void;
166
+ readonly bytelink_close: (a: number) => void;
167
+ readonly bytelink_new: (a: number) => number;
168
+ readonly bytelink_push: (a: number, b: number, c: number) => void;
169
+ readonly deliverysession_activeWebapp: (a: number) => number;
170
+ readonly deliverysession_attach: (a: number, b: number, c: number) => number;
171
+ readonly deliverysession_closed: (a: number) => number;
172
+ readonly deliverysession_connect: (a: number, b: number, c: number, d: number) => number;
173
+ readonly deliverysession_deviceId: (a: number, b: number) => void;
174
+ readonly deliverysession_installWebapp: (a: number, b: number, c: number, d: number, e: number) => number;
175
+ readonly deliverysession_meta: (a: number) => number;
176
+ readonly deliverysession_nextEvent: (a: number) => number;
177
+ readonly deliverysession_push: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => number;
178
+ readonly deliverysession_pushImage: (a: number, b: number, c: number, d: number, e: number, f: number) => number;
179
+ readonly deliverysession_setNickname: (a: number, b: number, c: number) => number;
180
+ readonly deliverysession_setWebappSlot: (a: number, b: number, c: number, d: number, e: number) => number;
181
+ readonly deliverysession_switchWebapp: (a: number, b: number, c: number) => number;
182
+ readonly deliverysession_uninstallWebapp: (a: number, b: number, c: number) => number;
183
+ readonly deliverysession_webappSlots: (a: number) => number;
184
+ readonly deliverysession_webapps: (a: number) => number;
185
+ readonly discoverManifest: (a: number, b: number) => number;
186
+ readonly init: () => void;
187
+ readonly parseCompositeVersion: (a: number, b: number, c: number) => void;
188
+ readonly __wasm_bindgen_func_elem_5999: (a: number, b: number, c: number, d: number) => void;
189
+ readonly __wasm_bindgen_func_elem_5982: (a: number, b: number, c: number, d: number) => void;
190
+ readonly __wasm_bindgen_func_elem_4227: (a: number, b: number, c: number) => void;
191
+ readonly __wasm_bindgen_func_elem_4227_2: (a: number, b: number, c: number) => void;
192
+ readonly __wasm_bindgen_func_elem_4227_3: (a: number, b: number, c: number) => void;
193
+ readonly __wasm_bindgen_func_elem_4543: (a: number, b: number) => void;
194
+ readonly __wasm_bindgen_func_elem_5026: (a: number, b: number) => void;
195
+ readonly __wbindgen_export: (a: number, b: number) => number;
196
+ readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
197
+ readonly __wbindgen_export3: (a: number) => void;
198
+ readonly __wbindgen_export4: (a: number, b: number, c: number) => void;
199
+ readonly __wbindgen_export5: (a: number, b: number) => void;
200
+ readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
201
+ }
202
+
203
+ export type SyncInitInput = BufferSource | WebAssembly.Module;
204
+
205
+ /**
206
+ * Instantiates the given `module`, which can either be bytes or
207
+ * a precompiled `WebAssembly.Module`.
208
+ *
209
+ * @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
210
+ *
211
+ * @returns {InitOutput}
212
+ */
213
+ export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
214
+
215
+ /**
216
+ * If `module_or_path` is {RequestInfo} or {URL}, makes a request and
217
+ * for everything else, calls `WebAssembly.instantiate` directly.
218
+ *
219
+ * @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
220
+ *
221
+ * @returns {Promise<InitOutput>}
222
+ */
223
+ export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;