@agentshouse/app-bridge 0.1.0-alpha.10 → 0.1.0-alpha.12
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 +16 -3
- package/client/src/bridge.d.ts +3 -1
- package/client/src/bridge.js +24 -5
- package/client/src/index.d.ts +1 -1
- package/client/src/test-host.d.ts +3 -1
- package/client/src/test-host.js +8 -0
- package/client/src/wire.d.ts +4 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The renderer-side client of the agents.house App bridge. An App served by House
|
|
4
4
|
receives one message port before its own scripts run; this package is that
|
|
5
|
-
port's one listener. It carries
|
|
5
|
+
port's one listener. It carries nine families:
|
|
6
6
|
|
|
7
7
|
- **Navigation** - the part of the shell's URL below the App's path, with its
|
|
8
8
|
query and fragment. The shell delivers it when the App starts and whenever the
|
|
@@ -58,11 +58,22 @@ port's one listener. It carries eight families:
|
|
|
58
58
|
refusal is House's `{ error: { code } }`, `app_release_not_found` for an
|
|
59
59
|
App with no release; a read House does not answer, or one that outlived
|
|
60
60
|
the browser's signed-in User, is `null`.
|
|
61
|
+
- **App messages** - `messages(listener)` hands the listener each message
|
|
62
|
+
another holder of this App sends to this User's running copies, as `from`,
|
|
63
|
+
the sender's User id, and `body`, the JSON value they sent, until the
|
|
64
|
+
function it returns is called. App code sends one through the Runtime's
|
|
65
|
+
`call('apps/messages/send', { to, body })` with the recipient's User id and
|
|
66
|
+
a body of at most 32 KiB of JSON; House fills in the App and relays it only
|
|
67
|
+
to copies running now, storing nothing. The panel sends none.
|
|
61
68
|
- **App screenshot read** - given an App reference, `readScreenshot(app)`
|
|
62
69
|
answers the image this browser captured of that App's screen the first time
|
|
63
70
|
it ran its current release, as a PNG `Blob` at most 1200 pixels wide, or
|
|
64
71
|
`null` when this browser holds none. The image stays in the browser; a Site
|
|
65
72
|
holds none.
|
|
73
|
+
- **Site screenshot read** - given one of the User's Site identifiers,
|
|
74
|
+
`readSiteScreenshot(site)` answers the image House captured of that Site
|
|
75
|
+
after its latest release, as a JPEG `Blob`, or `null` when House holds none
|
|
76
|
+
or does not answer. A Site's own renderer reads none.
|
|
66
77
|
|
|
67
78
|
The package carries no credential handling and no Runtime family. It surfaces
|
|
68
79
|
the dedicated Runtime port the worker transfers over the bridge as a plain
|
|
@@ -124,6 +135,8 @@ records in `consents` each
|
|
|
124
135
|
choice leaves, records in `tabs` each `setTab` the shell would take and ignores
|
|
125
136
|
any other, answers a release code read from the `sources` it was given, or
|
|
126
137
|
`null`, answers `readScreenshot` from the `screenshots` it was given by App
|
|
127
|
-
reference
|
|
138
|
+
reference and `readSiteScreenshot` from the `siteScreenshots` it was given by
|
|
139
|
+
Site identifier, answers every `install()` `'manual'`, as a browser with no install
|
|
128
140
|
prompt does, answers every `notifications()` `'unavailable'`, as a browser
|
|
129
|
-
without push does, settles every `setBadge`,
|
|
141
|
+
without push does, settles every `setBadge`, delivers each App message
|
|
142
|
+
`message({ from, body })` plays, and attaches a Runtime port.
|
package/client/src/bridge.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { HouseBridgePort, HouseGaChoice, HouseMessagePort, HouseSourceDownload, HouseSourceRefusal, HouseSourceTop, HouseStatus, HouseTab } from './wire.js';
|
|
1
|
+
import type { HouseAppMessage, HouseBridgePort, HouseGaChoice, HouseMessagePort, HouseSourceDownload, HouseSourceRefusal, HouseSourceTop, HouseStatus, HouseTab } from './wire.js';
|
|
2
2
|
export declare class HouseCeremonyRefused extends Error {
|
|
3
3
|
readonly path: string | null;
|
|
4
4
|
constructor(path: string | null);
|
|
@@ -30,8 +30,10 @@ export interface HouseBridge {
|
|
|
30
30
|
sourceTop(app: string, release?: string): Promise<HouseSourceTop | HouseSourceRefusal | null>;
|
|
31
31
|
sourceDownload(app: string, release?: string): Promise<HouseSourceDownload | HouseSourceRefusal | null>;
|
|
32
32
|
readScreenshot(app: string): Promise<Blob | null>;
|
|
33
|
+
readSiteScreenshot(site: string): Promise<Blob | null>;
|
|
33
34
|
status(): HouseStatus | null;
|
|
34
35
|
onStatus(listener: (status: HouseStatus) => void): () => void;
|
|
36
|
+
messages(listener: (message: HouseAppMessage) => void): () => void;
|
|
35
37
|
gaConsent(choice: HouseGaChoice): void;
|
|
36
38
|
}
|
|
37
39
|
export declare function connectHouseBridge(source?: Promise<HouseBridgePort>): HouseBridge;
|
package/client/src/bridge.js
CHANGED
|
@@ -59,6 +59,7 @@ export function connectHouseBridge(source = heldBridge()) {
|
|
|
59
59
|
let nextScreenshot = 0;
|
|
60
60
|
const addressListeners = new Set();
|
|
61
61
|
const statusListeners = new Set();
|
|
62
|
+
const messageListeners = new Set();
|
|
62
63
|
let outbox = [];
|
|
63
64
|
let held = null;
|
|
64
65
|
let address = null;
|
|
@@ -85,6 +86,12 @@ export function connectHouseBridge(source = heldBridge()) {
|
|
|
85
86
|
listener(status);
|
|
86
87
|
return;
|
|
87
88
|
}
|
|
89
|
+
if (data.house === 'app-message') {
|
|
90
|
+
const { from, body } = data;
|
|
91
|
+
for (const listener of messageListeners)
|
|
92
|
+
listener({ from, body });
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
88
95
|
if (data.house === 'address') {
|
|
89
96
|
address = String(data.address);
|
|
90
97
|
if (data.navigated === true)
|
|
@@ -172,6 +179,13 @@ export function connectHouseBridge(source = heldBridge()) {
|
|
|
172
179
|
send({ house, id, app, release });
|
|
173
180
|
return pending.promise;
|
|
174
181
|
}
|
|
182
|
+
function screenshot(house, asked) {
|
|
183
|
+
const pending = settled();
|
|
184
|
+
const id = ++nextScreenshot;
|
|
185
|
+
screenshots.set(id, pending.settle);
|
|
186
|
+
send({ house, id, ...asked });
|
|
187
|
+
return pending.promise;
|
|
188
|
+
}
|
|
175
189
|
function navigate(mode, asked) {
|
|
176
190
|
const pending = settled();
|
|
177
191
|
navigations.push({ address: asked, settle: pending.settle });
|
|
@@ -239,11 +253,10 @@ export function connectHouseBridge(source = heldBridge()) {
|
|
|
239
253
|
return readSource('source-download', app, release);
|
|
240
254
|
},
|
|
241
255
|
readScreenshot(app) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return pending.promise;
|
|
256
|
+
return screenshot('screenshot-read', { app });
|
|
257
|
+
},
|
|
258
|
+
readSiteScreenshot(site) {
|
|
259
|
+
return screenshot('site-screenshot-read', { site });
|
|
247
260
|
},
|
|
248
261
|
status() {
|
|
249
262
|
return status;
|
|
@@ -254,6 +267,12 @@ export function connectHouseBridge(source = heldBridge()) {
|
|
|
254
267
|
statusListeners.delete(listener);
|
|
255
268
|
};
|
|
256
269
|
},
|
|
270
|
+
messages(listener) {
|
|
271
|
+
messageListeners.add(listener);
|
|
272
|
+
return () => {
|
|
273
|
+
messageListeners.delete(listener);
|
|
274
|
+
};
|
|
275
|
+
},
|
|
257
276
|
gaConsent(choice) {
|
|
258
277
|
send({ house: 'ga/consent', choice });
|
|
259
278
|
},
|
package/client/src/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { connectHouseBridge, HouseCeremonyRefused, HouseNavigationRefused, type HouseBridge, type HouseImageCopy, } from './bridge.js';
|
|
2
2
|
export { HOUSE_ADDRESS_MAX_CHARS } from './wire.js';
|
|
3
|
-
export type { HouseBridgeEvent, HouseBridgePort, HouseCredentialState, HouseGa, HouseGaChoice, HouseMessagePort, HouseNavigationMode, HouseSourceDownload, HouseSourceFile, HouseSourceRefusal, HouseSourceTop, HouseStatus, HouseSyncState, } from './wire.js';
|
|
3
|
+
export type { HouseAppMessage, HouseBridgeEvent, HouseBridgePort, HouseCredentialState, HouseGa, HouseGaChoice, HouseMessagePort, HouseNavigationMode, HouseSourceDownload, HouseSourceFile, HouseSourceRefusal, HouseSourceTop, HouseStatus, HouseSyncState, } from './wire.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HouseImageCopy } from './bridge.js';
|
|
2
|
-
import type { HouseBridgePort, HouseGaChoice, HouseMessagePort, HouseNavigationMode, HouseSourceDownload, HouseSourceTop, HouseStatus, HouseTab } from './wire.js';
|
|
2
|
+
import type { HouseAppMessage, HouseBridgePort, HouseGaChoice, HouseMessagePort, HouseNavigationMode, HouseSourceDownload, HouseSourceTop, HouseStatus, HouseTab } from './wire.js';
|
|
3
3
|
export interface HouseBridgeNavigation {
|
|
4
4
|
readonly mode: HouseNavigationMode;
|
|
5
5
|
readonly address: string;
|
|
@@ -13,6 +13,7 @@ export interface HouseBridgeTestHost {
|
|
|
13
13
|
address(): string;
|
|
14
14
|
open(address: string): void;
|
|
15
15
|
publish(status: HouseStatus): void;
|
|
16
|
+
message(message: HouseAppMessage): void;
|
|
16
17
|
attachRuntime(runtime: HouseMessagePort): void;
|
|
17
18
|
}
|
|
18
19
|
export interface HouseBridgeTestHostOptions {
|
|
@@ -26,5 +27,6 @@ export interface HouseBridgeTestHostOptions {
|
|
|
26
27
|
readonly download: HouseSourceDownload;
|
|
27
28
|
}[];
|
|
28
29
|
readonly screenshots?: Readonly<Record<string, Blob>>;
|
|
30
|
+
readonly siteScreenshots?: Readonly<Record<string, Blob>>;
|
|
29
31
|
}
|
|
30
32
|
export declare function createHouseBridgeTestHost(options?: HouseBridgeTestHostOptions): HouseBridgeTestHost;
|
package/client/src/test-host.js
CHANGED
|
@@ -123,6 +123,11 @@ export function createHouseBridgeTestHost(options = {}) {
|
|
|
123
123
|
const held = typeof asked.app === 'string' ? options.screenshots?.[asked.app] : undefined;
|
|
124
124
|
deliver({ house: 'screenshot', id: asked.id, image: held ?? null });
|
|
125
125
|
}
|
|
126
|
+
else if (data.house === 'site-screenshot-read') {
|
|
127
|
+
const asked = data;
|
|
128
|
+
const held = typeof asked.site === 'string' ? options.siteScreenshots?.[asked.site] : undefined;
|
|
129
|
+
deliver({ house: 'screenshot', id: asked.id, image: held ?? null });
|
|
130
|
+
}
|
|
126
131
|
}
|
|
127
132
|
const port = {
|
|
128
133
|
postMessage(message) {
|
|
@@ -158,6 +163,9 @@ export function createHouseBridgeTestHost(options = {}) {
|
|
|
158
163
|
arrive(appAddressOf('/', asked), false);
|
|
159
164
|
},
|
|
160
165
|
publish,
|
|
166
|
+
message(message) {
|
|
167
|
+
deliver({ house: 'app-message', from: message.from, body: message.body });
|
|
168
|
+
},
|
|
161
169
|
attachRuntime(runtime) {
|
|
162
170
|
deliver({ house: 'runtime' }, [runtime]);
|
|
163
171
|
},
|
package/client/src/wire.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentshouse/app-bridge",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
4
|
-
"description": "Renderer-side client of the agents.house App bridge: navigation, the tab title and icon, ceremonies, installation, notifications and the icon badge, status, Site image reads, App release code and
|
|
3
|
+
"version": "0.1.0-alpha.12",
|
|
4
|
+
"description": "Renderer-side client of the agents.house App bridge: navigation, the tab title and icon, ceremonies, installation, notifications and the icon badge, status, Site image reads, App release code, App and Site screenshot reads, and App messages, with an in-page test host.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"sideEffects": false,
|