@agentshouse/app-bridge 0.1.0-ce3c71da46f00 → 0.1.0-cf2e2ca943fbc
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/dist/client/src/bridge.d.ts +2 -10
- package/dist/client/src/bridge.js +63 -36
- package/dist/client/src/wire.d.ts +130 -2
- package/docs/families.md +3 -1
- package/package.json +2 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { MdRuntimeClient } from '@agentshouse/mdruntime/client';
|
|
2
|
-
import type { HouseAppMessage, HouseExternalAnswer, HouseExternalRequest, HouseBridgePort, HouseGaChoice, HouseRefusal, HouseSourceDownload, HouseSourceTop, HouseStatus, HouseTab } from './wire.js';
|
|
2
|
+
import type { HouseAppMessage, HouseExternalAnswer, HouseExternalRequest, HouseBridgePort, HouseGaChoice, HouseImageCopy, HouseInstallation, HouseNotifications, HouseRefusal, HouseSourceDownload, HouseSourceTop, HouseStatus, HouseTab } from './wire.js';
|
|
3
|
+
export type { HouseImageCopy } from './wire.js';
|
|
3
4
|
export declare class HouseCeremonyRefused extends Error {
|
|
4
5
|
readonly path: string | null;
|
|
5
6
|
constructor(path: string | null);
|
|
@@ -8,14 +9,6 @@ export declare class HouseNavigationRefused extends Error {
|
|
|
8
9
|
readonly address: string | null;
|
|
9
10
|
constructor(address: string | null);
|
|
10
11
|
}
|
|
11
|
-
export interface HouseImageCopy {
|
|
12
|
-
readonly attachment: string;
|
|
13
|
-
readonly copy: string;
|
|
14
|
-
readonly name: string;
|
|
15
|
-
readonly media_type: string;
|
|
16
|
-
}
|
|
17
|
-
type HouseInstallation = 'accepted' | 'dismissed' | 'manual';
|
|
18
|
-
type HouseNotifications = 'on' | 'off' | 'blocked' | 'unavailable';
|
|
19
12
|
export interface HouseBridgeSource {
|
|
20
13
|
readonly port: Promise<HouseBridgePort>;
|
|
21
14
|
readonly runtime: Promise<MdRuntimeClient>;
|
|
@@ -43,4 +36,3 @@ export interface HouseBridge {
|
|
|
43
36
|
gaConsent(choice: HouseGaChoice): void;
|
|
44
37
|
}
|
|
45
38
|
export declare function connectHouseBridge(source?: HouseBridgeSource): HouseBridge;
|
|
46
|
-
export {};
|
|
@@ -14,19 +14,45 @@ export class HouseNavigationRefused extends Error {
|
|
|
14
14
|
this.address = address;
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
function
|
|
18
|
-
if (typeof answer.id !== 'number')
|
|
19
|
-
return;
|
|
17
|
+
function pendingAnswer(pending, answer) {
|
|
20
18
|
const asked = pending.get(answer.id);
|
|
21
19
|
if (asked === undefined)
|
|
22
|
-
return;
|
|
20
|
+
return null;
|
|
23
21
|
pending.delete(answer.id);
|
|
24
|
-
if (answer.refused === true)
|
|
22
|
+
if (answer.refused === true) {
|
|
25
23
|
asked.reject(new HouseCeremonyRefused(null));
|
|
26
|
-
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
if (answer.refusal !== undefined) {
|
|
27
27
|
asked.reject(new DOMException(answer.refusal.message, answer.refusal.name));
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return asked;
|
|
31
|
+
}
|
|
32
|
+
const FRAME_HOUSES = [
|
|
33
|
+
'runtime',
|
|
34
|
+
'status',
|
|
35
|
+
'screenshot',
|
|
36
|
+
'address',
|
|
37
|
+
'ceremony-refused',
|
|
38
|
+
'navigate-refused',
|
|
39
|
+
'attachment',
|
|
40
|
+
'source',
|
|
41
|
+
'external-call',
|
|
42
|
+
'install',
|
|
43
|
+
'notifications',
|
|
44
|
+
'badge',
|
|
45
|
+
'app-message',
|
|
46
|
+
];
|
|
47
|
+
function frameMessage(value) {
|
|
48
|
+
if (value === null || typeof value !== 'object')
|
|
49
|
+
return null;
|
|
50
|
+
const message = value;
|
|
51
|
+
if (typeof message.house !== 'string')
|
|
52
|
+
return null;
|
|
53
|
+
if (!FRAME_HOUSES.includes(message.house))
|
|
54
|
+
return null;
|
|
55
|
+
return value;
|
|
30
56
|
}
|
|
31
57
|
function settled() {
|
|
32
58
|
let settle = null;
|
|
@@ -72,8 +98,8 @@ export function connectHouseBridge(source = heldBridge()) {
|
|
|
72
98
|
held.postMessage(message);
|
|
73
99
|
}
|
|
74
100
|
function receive(event) {
|
|
75
|
-
const data = event.data;
|
|
76
|
-
if (data === null
|
|
101
|
+
const data = frameMessage(event.data);
|
|
102
|
+
if (data === null)
|
|
77
103
|
return;
|
|
78
104
|
if (data.house === 'status') {
|
|
79
105
|
status = data.status;
|
|
@@ -104,61 +130,59 @@ export function connectHouseBridge(source = heldBridge()) {
|
|
|
104
130
|
return;
|
|
105
131
|
}
|
|
106
132
|
if (data.house === 'attachment') {
|
|
107
|
-
|
|
108
|
-
if (typeof answer.id !== 'number')
|
|
133
|
+
if (typeof data.id !== 'number')
|
|
109
134
|
return;
|
|
110
|
-
const pending = attachments.get(
|
|
135
|
+
const pending = attachments.get(data.id);
|
|
111
136
|
if (pending === undefined)
|
|
112
137
|
return;
|
|
113
|
-
attachments.delete(
|
|
114
|
-
pending.resolve(
|
|
138
|
+
attachments.delete(data.id);
|
|
139
|
+
pending.resolve(data.image ?? null);
|
|
115
140
|
return;
|
|
116
141
|
}
|
|
117
142
|
if (data.house === 'install') {
|
|
118
|
-
const
|
|
119
|
-
|
|
143
|
+
const pending = pendingAnswer(installations, data);
|
|
144
|
+
if (pending !== null && 'outcome' in data)
|
|
145
|
+
pending.resolve(data.outcome);
|
|
120
146
|
return;
|
|
121
147
|
}
|
|
122
148
|
if (data.house === 'notifications') {
|
|
123
|
-
const
|
|
124
|
-
|
|
149
|
+
const pending = pendingAnswer(notifications, data);
|
|
150
|
+
if (pending !== null && 'state' in data)
|
|
151
|
+
pending.resolve(data.state);
|
|
125
152
|
return;
|
|
126
153
|
}
|
|
127
154
|
if (data.house === 'badge') {
|
|
128
|
-
|
|
155
|
+
pendingAnswer(badges, data)?.resolve();
|
|
129
156
|
return;
|
|
130
157
|
}
|
|
131
158
|
if (data.house === 'source') {
|
|
132
|
-
|
|
133
|
-
if (typeof answer.id !== 'number')
|
|
159
|
+
if (typeof data.id !== 'number')
|
|
134
160
|
return;
|
|
135
|
-
const pending = sources.get(
|
|
161
|
+
const pending = sources.get(data.id);
|
|
136
162
|
if (pending === undefined)
|
|
137
163
|
return;
|
|
138
|
-
sources.delete(
|
|
139
|
-
pending.resolve(
|
|
164
|
+
sources.delete(data.id);
|
|
165
|
+
pending.resolve(data.answer ?? null);
|
|
140
166
|
return;
|
|
141
167
|
}
|
|
142
168
|
if (data.house === 'external-call') {
|
|
143
|
-
|
|
144
|
-
if (typeof answer.id !== 'number')
|
|
169
|
+
if (typeof data.id !== 'number')
|
|
145
170
|
return;
|
|
146
|
-
const pending = externals.get(
|
|
171
|
+
const pending = externals.get(data.id);
|
|
147
172
|
if (pending === undefined)
|
|
148
173
|
return;
|
|
149
|
-
externals.delete(
|
|
150
|
-
pending.resolve(
|
|
174
|
+
externals.delete(data.id);
|
|
175
|
+
pending.resolve(data.answer ?? null);
|
|
151
176
|
return;
|
|
152
177
|
}
|
|
153
178
|
if (data.house === 'screenshot') {
|
|
154
|
-
|
|
155
|
-
if (typeof answer.id !== 'number')
|
|
179
|
+
if (typeof data.id !== 'number')
|
|
156
180
|
return;
|
|
157
|
-
const pending = screenshots.get(
|
|
181
|
+
const pending = screenshots.get(data.id);
|
|
158
182
|
if (pending === undefined)
|
|
159
183
|
return;
|
|
160
|
-
screenshots.delete(
|
|
161
|
-
pending.resolve(
|
|
184
|
+
screenshots.delete(data.id);
|
|
185
|
+
pending.resolve(data.image ?? null);
|
|
162
186
|
return;
|
|
163
187
|
}
|
|
164
188
|
if (data.house === 'ceremony-refused') {
|
|
@@ -189,7 +213,10 @@ export function connectHouseBridge(source = heldBridge()) {
|
|
|
189
213
|
const pending = settled();
|
|
190
214
|
const id = ++nextScreenshot;
|
|
191
215
|
screenshots.set(id, pending.settle);
|
|
192
|
-
|
|
216
|
+
if (house === 'screenshot-read' && 'app' in asked)
|
|
217
|
+
send({ house, id, app: asked.app });
|
|
218
|
+
if (house === 'site-screenshot-read' && 'site' in asked)
|
|
219
|
+
send({ house, id, site: asked.site });
|
|
193
220
|
return pending.promise;
|
|
194
221
|
}
|
|
195
222
|
function navigate(mode, asked) {
|
|
@@ -3,7 +3,7 @@ export interface HouseBridgeEvent {
|
|
|
3
3
|
readonly data: unknown;
|
|
4
4
|
}
|
|
5
5
|
export interface HouseBridgePort {
|
|
6
|
-
postMessage(message:
|
|
6
|
+
postMessage(message: HouseFrameRequest): void;
|
|
7
7
|
addEventListener(type: 'message', listener: (event: HouseBridgeEvent) => void): void;
|
|
8
8
|
start(): void;
|
|
9
9
|
}
|
|
@@ -21,7 +21,11 @@ export interface HouseGa {
|
|
|
21
21
|
readonly choice: HouseGaChoice | null;
|
|
22
22
|
}
|
|
23
23
|
export interface HouseStatus {
|
|
24
|
-
readonly app: string;
|
|
24
|
+
readonly app: string | null;
|
|
25
|
+
readonly preferences: {
|
|
26
|
+
readonly room_ref: string;
|
|
27
|
+
readonly path: string;
|
|
28
|
+
} | null;
|
|
25
29
|
readonly runtime: string;
|
|
26
30
|
readonly credential: HouseCredentialState;
|
|
27
31
|
readonly sync: HouseSyncState | null;
|
|
@@ -31,6 +35,7 @@ export interface HouseStatus {
|
|
|
31
35
|
readonly loss: string | null;
|
|
32
36
|
readonly ga: HouseGa;
|
|
33
37
|
readonly service_mode: 'open' | 'write-halted' | null;
|
|
38
|
+
readonly offline: boolean;
|
|
34
39
|
}
|
|
35
40
|
export type HouseNavigationMode = 'push' | 'replace';
|
|
36
41
|
interface HouseRelease {
|
|
@@ -83,5 +88,128 @@ export interface HouseAppMessage {
|
|
|
83
88
|
readonly from: string;
|
|
84
89
|
readonly body: unknown;
|
|
85
90
|
}
|
|
91
|
+
export type HouseInstallation = 'accepted' | 'dismissed' | 'manual';
|
|
92
|
+
export type HouseNotifications = 'on' | 'off' | 'blocked' | 'unavailable';
|
|
93
|
+
export interface HouseImageCopy {
|
|
94
|
+
readonly attachment: string;
|
|
95
|
+
readonly copy: string;
|
|
96
|
+
readonly name: string;
|
|
97
|
+
readonly media_type: string;
|
|
98
|
+
}
|
|
99
|
+
export interface HouseFrameRefusal {
|
|
100
|
+
readonly name: string;
|
|
101
|
+
readonly message: string;
|
|
102
|
+
}
|
|
103
|
+
export type HouseFrameRequest = {
|
|
104
|
+
readonly house: 'navigate';
|
|
105
|
+
readonly mode: HouseNavigationMode;
|
|
106
|
+
readonly address: string;
|
|
107
|
+
} | ({
|
|
108
|
+
readonly house: 'tab';
|
|
109
|
+
} & HouseTab) | {
|
|
110
|
+
readonly house: 'ceremony';
|
|
111
|
+
readonly path: string;
|
|
112
|
+
} | {
|
|
113
|
+
readonly house: 'install';
|
|
114
|
+
readonly id: number;
|
|
115
|
+
} | {
|
|
116
|
+
readonly house: 'notifications';
|
|
117
|
+
readonly id: number;
|
|
118
|
+
readonly on?: boolean;
|
|
119
|
+
} | {
|
|
120
|
+
readonly house: 'badge';
|
|
121
|
+
readonly id: number;
|
|
122
|
+
readonly unread: readonly string[];
|
|
123
|
+
} | {
|
|
124
|
+
readonly house: 'attachment-read';
|
|
125
|
+
readonly id: number;
|
|
126
|
+
readonly room: string;
|
|
127
|
+
readonly attachment: string;
|
|
128
|
+
} | {
|
|
129
|
+
readonly house: 'source-top' | 'source-download';
|
|
130
|
+
readonly id: number;
|
|
131
|
+
readonly app: string;
|
|
132
|
+
readonly release?: string;
|
|
133
|
+
} | {
|
|
134
|
+
readonly house: 'external-call';
|
|
135
|
+
readonly id: number;
|
|
136
|
+
readonly request: HouseExternalRequest;
|
|
137
|
+
} | {
|
|
138
|
+
readonly house: 'screenshot-read';
|
|
139
|
+
readonly id: number;
|
|
140
|
+
readonly app: string;
|
|
141
|
+
} | {
|
|
142
|
+
readonly house: 'site-screenshot-read';
|
|
143
|
+
readonly id: number;
|
|
144
|
+
readonly site: string;
|
|
145
|
+
} | {
|
|
146
|
+
readonly house: 'ga/consent';
|
|
147
|
+
readonly choice: HouseGaChoice;
|
|
148
|
+
};
|
|
149
|
+
export type HouseInstallAnswer = {
|
|
150
|
+
readonly outcome: HouseInstallation;
|
|
151
|
+
} | {
|
|
152
|
+
readonly refusal: HouseFrameRefusal;
|
|
153
|
+
};
|
|
154
|
+
export type HouseNotificationAnswer = {
|
|
155
|
+
readonly refused: true;
|
|
156
|
+
} | {
|
|
157
|
+
readonly refusal: HouseFrameRefusal;
|
|
158
|
+
} | {
|
|
159
|
+
readonly state: HouseNotifications;
|
|
160
|
+
};
|
|
161
|
+
export type HouseBadgeAnswer = {
|
|
162
|
+
readonly refused: true;
|
|
163
|
+
} | {
|
|
164
|
+
readonly refusal: HouseFrameRefusal;
|
|
165
|
+
} | {
|
|
166
|
+
readonly refused?: never;
|
|
167
|
+
readonly refusal?: never;
|
|
168
|
+
};
|
|
169
|
+
export type HouseFrameMessage = {
|
|
170
|
+
readonly house: 'runtime';
|
|
171
|
+
} | {
|
|
172
|
+
readonly house: 'status';
|
|
173
|
+
readonly status: HouseStatus;
|
|
174
|
+
} | {
|
|
175
|
+
readonly house: 'screenshot';
|
|
176
|
+
readonly id: number;
|
|
177
|
+
readonly image: Blob | null;
|
|
178
|
+
} | {
|
|
179
|
+
readonly house: 'address';
|
|
180
|
+
readonly address: string;
|
|
181
|
+
readonly navigated: boolean;
|
|
182
|
+
} | {
|
|
183
|
+
readonly house: 'ceremony-refused';
|
|
184
|
+
readonly path: string | null;
|
|
185
|
+
} | {
|
|
186
|
+
readonly house: 'navigate-refused';
|
|
187
|
+
readonly address: string | null;
|
|
188
|
+
} | {
|
|
189
|
+
readonly house: 'attachment';
|
|
190
|
+
readonly id: number;
|
|
191
|
+
readonly image: HouseImageCopy | null;
|
|
192
|
+
} | {
|
|
193
|
+
readonly house: 'source';
|
|
194
|
+
readonly id: number;
|
|
195
|
+
readonly answer: HouseSourceTop | HouseSourceDownload | HouseRefusal | null;
|
|
196
|
+
} | {
|
|
197
|
+
readonly house: 'external-call';
|
|
198
|
+
readonly id: number;
|
|
199
|
+
readonly answer: HouseExternalAnswer | HouseRefusal | null;
|
|
200
|
+
} | ({
|
|
201
|
+
readonly house: 'install';
|
|
202
|
+
readonly id: number;
|
|
203
|
+
} & HouseInstallAnswer) | ({
|
|
204
|
+
readonly house: 'notifications';
|
|
205
|
+
readonly id: number;
|
|
206
|
+
} & HouseNotificationAnswer) | ({
|
|
207
|
+
readonly house: 'badge';
|
|
208
|
+
readonly id: number;
|
|
209
|
+
} & HouseBadgeAnswer) | {
|
|
210
|
+
readonly house: 'app-message';
|
|
211
|
+
readonly from: string;
|
|
212
|
+
readonly body: unknown;
|
|
213
|
+
};
|
|
86
214
|
export declare const HOUSE_ADDRESS_MAX_CHARS = 1000;
|
|
87
215
|
export {};
|
package/docs/families.md
CHANGED
|
@@ -32,7 +32,9 @@
|
|
|
32
32
|
click. `setBadge(unread)` takes the identifiers of the Human Notifications
|
|
33
33
|
unread in this storage and sets the icon's badge to their number, or clears
|
|
34
34
|
it at none, where the browser shows one.
|
|
35
|
-
- **Status** - the App reference the runtime client is attached under,
|
|
35
|
+
- **Status** - the App reference the runtime client is attached under,
|
|
36
|
+
`preferences`: the `room_ref` and Path of the App's own preferences document,
|
|
37
|
+
or `null` until the runtime holds that Room, sync
|
|
36
38
|
state, credential state and observed failure, `ga`:
|
|
37
39
|
whether the page measures and the visitor's stored analytics choice, and
|
|
38
40
|
`service_mode`: `open`, `write-halted` while House refuses writes, so the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentshouse/app-bridge",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-cf2e2ca943fbc",
|
|
4
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": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@agentshouse/mdruntime": "0.1.0-
|
|
22
|
+
"@agentshouse/mdruntime": "0.1.0-cacb4c3f6734e"
|
|
23
23
|
},
|
|
24
24
|
"files": [
|
|
25
25
|
"dist",
|