@agentshouse/app-bridge 0.1.0-alpha.10 → 0.1.0-alpha.11

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 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 eight families:
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,6 +58,13 @@ 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
@@ -126,4 +133,5 @@ any other, answers a release code read from the `sources` it was given, or
126
133
  `null`, answers `readScreenshot` from the `screenshots` it was given by App
127
134
  reference, answers every `install()` `'manual'`, as a browser with no install
128
135
  prompt does, answers every `notifications()` `'unavailable'`, as a browser
129
- without push does, settles every `setBadge`, and attaches a Runtime port.
136
+ without push does, settles every `setBadge`, delivers each App message
137
+ `message({ from, body })` plays, and attaches a Runtime port.
@@ -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);
@@ -32,6 +32,7 @@ export interface HouseBridge {
32
32
  readScreenshot(app: string): Promise<Blob | null>;
33
33
  status(): HouseStatus | null;
34
34
  onStatus(listener: (status: HouseStatus) => void): () => void;
35
+ messages(listener: (message: HouseAppMessage) => void): () => void;
35
36
  gaConsent(choice: HouseGaChoice): void;
36
37
  }
37
38
  export declare function connectHouseBridge(source?: Promise<HouseBridgePort>): HouseBridge;
@@ -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)
@@ -254,6 +261,12 @@ export function connectHouseBridge(source = heldBridge()) {
254
261
  statusListeners.delete(listener);
255
262
  };
256
263
  },
264
+ messages(listener) {
265
+ messageListeners.add(listener);
266
+ return () => {
267
+ messageListeners.delete(listener);
268
+ };
269
+ },
257
270
  gaConsent(choice) {
258
271
  send({ house: 'ga/consent', choice });
259
272
  },
@@ -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 {
@@ -158,6 +158,9 @@ export function createHouseBridgeTestHost(options = {}) {
158
158
  arrive(appAddressOf('/', asked), false);
159
159
  },
160
160
  publish,
161
+ message(message) {
162
+ deliver({ house: 'app-message', from: message.from, body: message.body });
163
+ },
161
164
  attachRuntime(runtime) {
162
165
  deliver({ house: 'runtime' }, [runtime]);
163
166
  },
@@ -65,5 +65,9 @@ export interface HouseSourceRefusal {
65
65
  };
66
66
  }
67
67
  export type HouseTab = TabChange;
68
+ export interface HouseAppMessage {
69
+ readonly from: string;
70
+ readonly body: unknown;
71
+ }
68
72
  export declare const HOUSE_ADDRESS_MAX_CHARS = 1000;
69
73
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agentshouse/app-bridge",
3
- "version": "0.1.0-alpha.10",
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 App screenshot reads, with an in-page test host.",
3
+ "version": "0.1.0-alpha.11",
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 App screenshot reads, and App messages, with an in-page test host.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
7
7
  "sideEffects": false,