@agentshouse/app-bridge 0.1.0-c357a960443ec → 0.1.0-c415579fa0c3a
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/LICENSE +21 -0
- package/README.md +7 -9
- package/dist/client/src/bridge.d.ts +8 -11
- package/dist/client/src/bridge.js +68 -48
- package/dist/client/src/index.d.ts +2 -2
- package/dist/client/src/test-host.d.ts +5 -5
- package/dist/client/src/test-host.js +9 -4
- package/dist/client/src/wire.d.ts +131 -5
- package/dist/src/apps/remainder.js +1 -1
- package/docs/families.md +5 -2
- package/package.json +7 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Anton (trof3039)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -7,18 +7,17 @@ installation, notifications, status, Site image reads, App release code,
|
|
|
7
7
|
external calls, App messages and App and Site screenshot reads.
|
|
8
8
|
[docs/families.md](docs/families.md) describes each and the test host.
|
|
9
9
|
|
|
10
|
-
The package carries no credential handling and no Runtime family.
|
|
11
|
-
the
|
|
12
|
-
|
|
10
|
+
The package carries no credential handling and no Runtime family. House builds
|
|
11
|
+
the MD Runtime client into the page beside the bridge, and `bridge.runtime`
|
|
12
|
+
resolves to that client, so the App imports and constructs none.
|
|
13
13
|
|
|
14
14
|
## Use
|
|
15
15
|
|
|
16
16
|
```js
|
|
17
17
|
import { connectHouseBridge } from '@agentshouse/app-bridge';
|
|
18
|
-
import { connectMdRuntime } from '@agentshouse/mdruntime/client';
|
|
19
18
|
|
|
20
19
|
const bridge = connectHouseBridge();
|
|
21
|
-
const md =
|
|
20
|
+
const md = await bridge.runtime;
|
|
22
21
|
|
|
23
22
|
bridge.onAddress((address) => render(address));
|
|
24
23
|
bridge.onStatus((status) => showSync(status.sync));
|
|
@@ -38,9 +37,8 @@ async function manageSecurity(securityPath) {
|
|
|
38
37
|
}
|
|
39
38
|
```
|
|
40
39
|
|
|
41
|
-
`bridge.runtime` resolves
|
|
42
|
-
|
|
43
|
-
directly at run time and casts at the type level.
|
|
40
|
+
`bridge.runtime` resolves to the `MdRuntimeClient` of
|
|
41
|
+
`@agentshouse/mdruntime/client`, whose README describes its members.
|
|
44
42
|
|
|
45
43
|
## Test without a House
|
|
46
44
|
|
|
@@ -49,7 +47,7 @@ import { connectHouseBridge } from '@agentshouse/app-bridge';
|
|
|
49
47
|
import { createHouseBridgeTestHost } from '@agentshouse/app-bridge/test-host';
|
|
50
48
|
|
|
51
49
|
const host = createHouseBridgeTestHost({ address: '/rooms/atlas' });
|
|
52
|
-
const bridge = connectHouseBridge(host
|
|
50
|
+
const bridge = connectHouseBridge(host);
|
|
53
51
|
|
|
54
52
|
bridge.push('/rooms/atlas/members');
|
|
55
53
|
host.open('/rooms/atlas');
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MdRuntimeClient } from '@agentshouse/mdruntime/client';
|
|
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';
|
|
2
4
|
export declare class HouseCeremonyRefused extends Error {
|
|
3
5
|
readonly path: string | null;
|
|
4
6
|
constructor(path: string | null);
|
|
@@ -7,16 +9,12 @@ export declare class HouseNavigationRefused extends Error {
|
|
|
7
9
|
readonly address: string | null;
|
|
8
10
|
constructor(address: string | null);
|
|
9
11
|
}
|
|
10
|
-
export interface
|
|
11
|
-
readonly
|
|
12
|
-
readonly
|
|
13
|
-
readonly name: string;
|
|
14
|
-
readonly media_type: string;
|
|
12
|
+
export interface HouseBridgeSource {
|
|
13
|
+
readonly port: Promise<HouseBridgePort>;
|
|
14
|
+
readonly runtime: Promise<MdRuntimeClient>;
|
|
15
15
|
}
|
|
16
|
-
type HouseInstallation = 'accepted' | 'dismissed' | 'manual';
|
|
17
|
-
type HouseNotifications = 'on' | 'off' | 'blocked' | 'unavailable';
|
|
18
16
|
export interface HouseBridge {
|
|
19
|
-
readonly runtime: Promise<
|
|
17
|
+
readonly runtime: Promise<MdRuntimeClient>;
|
|
20
18
|
address(): string | null;
|
|
21
19
|
onAddress(listener: (address: string) => void): () => void;
|
|
22
20
|
push(address: string): Promise<string>;
|
|
@@ -37,5 +35,4 @@ export interface HouseBridge {
|
|
|
37
35
|
messages(listener: (message: HouseAppMessage) => void): () => void;
|
|
38
36
|
gaConsent(choice: HouseGaChoice): void;
|
|
39
37
|
}
|
|
40
|
-
export declare function connectHouseBridge(source?:
|
|
41
|
-
export {};
|
|
38
|
+
export declare function connectHouseBridge(source?: HouseBridgeSource): HouseBridge;
|
|
@@ -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;
|
|
@@ -36,13 +62,12 @@ function settled() {
|
|
|
36
62
|
return { promise, settle: settle };
|
|
37
63
|
}
|
|
38
64
|
function heldBridge() {
|
|
39
|
-
const held = globalThis
|
|
40
|
-
if (held === undefined)
|
|
65
|
+
const held = globalThis;
|
|
66
|
+
if (held.houseBridge === undefined || held.houseRuntime === undefined)
|
|
41
67
|
throw new Error('house_bridge_absent');
|
|
42
|
-
return held;
|
|
68
|
+
return { port: held.houseBridge, runtime: held.houseRuntime };
|
|
43
69
|
}
|
|
44
70
|
export function connectHouseBridge(source = heldBridge()) {
|
|
45
|
-
const runtime = settled();
|
|
46
71
|
const ceremonies = [];
|
|
47
72
|
const navigations = [];
|
|
48
73
|
const attachments = new Map();
|
|
@@ -73,15 +98,9 @@ export function connectHouseBridge(source = heldBridge()) {
|
|
|
73
98
|
held.postMessage(message);
|
|
74
99
|
}
|
|
75
100
|
function receive(event) {
|
|
76
|
-
const data = event.data;
|
|
77
|
-
if (data === null
|
|
101
|
+
const data = frameMessage(event.data);
|
|
102
|
+
if (data === null)
|
|
78
103
|
return;
|
|
79
|
-
if (data.house === 'runtime') {
|
|
80
|
-
const [port] = event.ports;
|
|
81
|
-
if (port !== undefined)
|
|
82
|
-
runtime.settle.resolve(port);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
104
|
if (data.house === 'status') {
|
|
86
105
|
status = data.status;
|
|
87
106
|
for (const listener of statusListeners)
|
|
@@ -111,61 +130,59 @@ export function connectHouseBridge(source = heldBridge()) {
|
|
|
111
130
|
return;
|
|
112
131
|
}
|
|
113
132
|
if (data.house === 'attachment') {
|
|
114
|
-
|
|
115
|
-
if (typeof answer.id !== 'number')
|
|
133
|
+
if (typeof data.id !== 'number')
|
|
116
134
|
return;
|
|
117
|
-
const pending = attachments.get(
|
|
135
|
+
const pending = attachments.get(data.id);
|
|
118
136
|
if (pending === undefined)
|
|
119
137
|
return;
|
|
120
|
-
attachments.delete(
|
|
121
|
-
pending.resolve(
|
|
138
|
+
attachments.delete(data.id);
|
|
139
|
+
pending.resolve(data.image ?? null);
|
|
122
140
|
return;
|
|
123
141
|
}
|
|
124
142
|
if (data.house === 'install') {
|
|
125
|
-
const
|
|
126
|
-
|
|
143
|
+
const pending = pendingAnswer(installations, data);
|
|
144
|
+
if (pending !== null && 'outcome' in data)
|
|
145
|
+
pending.resolve(data.outcome);
|
|
127
146
|
return;
|
|
128
147
|
}
|
|
129
148
|
if (data.house === 'notifications') {
|
|
130
|
-
const
|
|
131
|
-
|
|
149
|
+
const pending = pendingAnswer(notifications, data);
|
|
150
|
+
if (pending !== null && 'state' in data)
|
|
151
|
+
pending.resolve(data.state);
|
|
132
152
|
return;
|
|
133
153
|
}
|
|
134
154
|
if (data.house === 'badge') {
|
|
135
|
-
|
|
155
|
+
pendingAnswer(badges, data)?.resolve();
|
|
136
156
|
return;
|
|
137
157
|
}
|
|
138
158
|
if (data.house === 'source') {
|
|
139
|
-
|
|
140
|
-
if (typeof answer.id !== 'number')
|
|
159
|
+
if (typeof data.id !== 'number')
|
|
141
160
|
return;
|
|
142
|
-
const pending = sources.get(
|
|
161
|
+
const pending = sources.get(data.id);
|
|
143
162
|
if (pending === undefined)
|
|
144
163
|
return;
|
|
145
|
-
sources.delete(
|
|
146
|
-
pending.resolve(
|
|
164
|
+
sources.delete(data.id);
|
|
165
|
+
pending.resolve(data.answer ?? null);
|
|
147
166
|
return;
|
|
148
167
|
}
|
|
149
168
|
if (data.house === 'external-call') {
|
|
150
|
-
|
|
151
|
-
if (typeof answer.id !== 'number')
|
|
169
|
+
if (typeof data.id !== 'number')
|
|
152
170
|
return;
|
|
153
|
-
const pending = externals.get(
|
|
171
|
+
const pending = externals.get(data.id);
|
|
154
172
|
if (pending === undefined)
|
|
155
173
|
return;
|
|
156
|
-
externals.delete(
|
|
157
|
-
pending.resolve(
|
|
174
|
+
externals.delete(data.id);
|
|
175
|
+
pending.resolve(data.answer ?? null);
|
|
158
176
|
return;
|
|
159
177
|
}
|
|
160
178
|
if (data.house === 'screenshot') {
|
|
161
|
-
|
|
162
|
-
if (typeof answer.id !== 'number')
|
|
179
|
+
if (typeof data.id !== 'number')
|
|
163
180
|
return;
|
|
164
|
-
const pending = screenshots.get(
|
|
181
|
+
const pending = screenshots.get(data.id);
|
|
165
182
|
if (pending === undefined)
|
|
166
183
|
return;
|
|
167
|
-
screenshots.delete(
|
|
168
|
-
pending.resolve(
|
|
184
|
+
screenshots.delete(data.id);
|
|
185
|
+
pending.resolve(data.image ?? null);
|
|
169
186
|
return;
|
|
170
187
|
}
|
|
171
188
|
if (data.house === 'ceremony-refused') {
|
|
@@ -176,7 +193,7 @@ export function connectHouseBridge(source = heldBridge()) {
|
|
|
176
193
|
pending?.settle.reject(new HouseCeremonyRefused(named));
|
|
177
194
|
}
|
|
178
195
|
}
|
|
179
|
-
void source.then((port) => {
|
|
196
|
+
void source.port.then((port) => {
|
|
180
197
|
held = port;
|
|
181
198
|
port.addEventListener('message', receive);
|
|
182
199
|
port.start();
|
|
@@ -196,7 +213,10 @@ export function connectHouseBridge(source = heldBridge()) {
|
|
|
196
213
|
const pending = settled();
|
|
197
214
|
const id = ++nextScreenshot;
|
|
198
215
|
screenshots.set(id, pending.settle);
|
|
199
|
-
|
|
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 });
|
|
200
220
|
return pending.promise;
|
|
201
221
|
}
|
|
202
222
|
function navigate(mode, asked) {
|
|
@@ -206,7 +226,7 @@ export function connectHouseBridge(source = heldBridge()) {
|
|
|
206
226
|
return pending.promise;
|
|
207
227
|
}
|
|
208
228
|
return {
|
|
209
|
-
runtime: runtime
|
|
229
|
+
runtime: source.runtime,
|
|
210
230
|
address() {
|
|
211
231
|
return address;
|
|
212
232
|
},
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { connectHouseBridge, HouseCeremonyRefused, HouseNavigationRefused, type HouseBridge, type HouseImageCopy, } from './bridge.js';
|
|
1
|
+
export { connectHouseBridge, HouseCeremonyRefused, HouseNavigationRefused, type HouseBridge, type HouseBridgeSource, type HouseImageCopy, } from './bridge.js';
|
|
2
2
|
export { HOUSE_ADDRESS_MAX_CHARS } from './wire.js';
|
|
3
|
-
export type { HouseAppMessage, HouseBridgeEvent, HouseBridgePort, HouseCredentialState, HouseExternalAnswer, HouseExternalRequest, HouseGa, HouseGaChoice,
|
|
3
|
+
export type { HouseAppMessage, HouseBridgeEvent, HouseBridgePort, HouseCredentialState, HouseExternalAnswer, HouseExternalRequest, HouseGa, HouseGaChoice, HouseNavigationMode, HouseRefusal, HouseSourceDownload, HouseSourceFile, HouseSourceTop, HouseStatus, HouseSyncState, } from './wire.js';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { MdRuntimeClient } from '@agentshouse/mdruntime/client';
|
|
2
|
+
import type { HouseBridgeSource, HouseImageCopy } from './bridge.js';
|
|
3
|
+
import type { HouseAppMessage, HouseExternalAnswer, HouseExternalRequest, HouseGaChoice, HouseNavigationMode, HouseRefusal, HouseSourceDownload, HouseSourceTop, HouseStatus, HouseTab } from './wire.js';
|
|
3
4
|
export interface HouseBridgeNavigation {
|
|
4
5
|
readonly mode: HouseNavigationMode;
|
|
5
6
|
readonly address: string;
|
|
6
7
|
}
|
|
7
|
-
export interface HouseBridgeTestHost {
|
|
8
|
-
readonly port: Promise<HouseBridgePort>;
|
|
8
|
+
export interface HouseBridgeTestHost extends HouseBridgeSource {
|
|
9
9
|
readonly navigations: readonly HouseBridgeNavigation[];
|
|
10
10
|
readonly ceremonies: readonly string[];
|
|
11
11
|
readonly consents: readonly HouseGaChoice[];
|
|
@@ -15,7 +15,7 @@ export interface HouseBridgeTestHost {
|
|
|
15
15
|
open(address: string): void;
|
|
16
16
|
publish(status: HouseStatus): void;
|
|
17
17
|
message(message: HouseAppMessage): void;
|
|
18
|
-
attachRuntime(runtime:
|
|
18
|
+
attachRuntime(runtime: MdRuntimeClient): void;
|
|
19
19
|
}
|
|
20
20
|
export interface HouseBridgeTestHostOptions {
|
|
21
21
|
readonly address?: string;
|
|
@@ -23,8 +23,12 @@ export function createHouseBridgeTestHost(options = {}) {
|
|
|
23
23
|
let started = false;
|
|
24
24
|
let address = appAddressOf('/', options.address ?? '/');
|
|
25
25
|
let status = options.status ?? null;
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
let attached = () => { };
|
|
27
|
+
const runtime = new Promise((resolve) => {
|
|
28
|
+
attached = resolve;
|
|
29
|
+
});
|
|
30
|
+
function deliver(data) {
|
|
31
|
+
const event = { data };
|
|
28
32
|
if (!started) {
|
|
29
33
|
queued.push(event);
|
|
30
34
|
return;
|
|
@@ -158,6 +162,7 @@ export function createHouseBridgeTestHost(options = {}) {
|
|
|
158
162
|
deliver({ house: 'address', address, navigated: false });
|
|
159
163
|
return {
|
|
160
164
|
port: Promise.resolve(port),
|
|
165
|
+
runtime,
|
|
161
166
|
navigations,
|
|
162
167
|
ceremonies,
|
|
163
168
|
consents,
|
|
@@ -173,8 +178,8 @@ export function createHouseBridgeTestHost(options = {}) {
|
|
|
173
178
|
message(message) {
|
|
174
179
|
deliver({ house: 'app-message', from: message.from, body: message.body });
|
|
175
180
|
},
|
|
176
|
-
attachRuntime(
|
|
177
|
-
|
|
181
|
+
attachRuntime(client) {
|
|
182
|
+
attached(client);
|
|
178
183
|
},
|
|
179
184
|
};
|
|
180
185
|
}
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import type { TabChange } from '../../src/apps/tab.js';
|
|
2
2
|
export interface HouseBridgeEvent {
|
|
3
3
|
readonly data: unknown;
|
|
4
|
-
readonly ports: readonly HouseMessagePort[];
|
|
5
4
|
}
|
|
6
|
-
export interface
|
|
7
|
-
postMessage(message:
|
|
5
|
+
export interface HouseBridgePort {
|
|
6
|
+
postMessage(message: HouseFrameRequest): void;
|
|
8
7
|
addEventListener(type: 'message', listener: (event: HouseBridgeEvent) => void): void;
|
|
9
8
|
start(): void;
|
|
10
9
|
}
|
|
11
|
-
export type HouseBridgePort = HouseMessagePort;
|
|
12
10
|
export interface HouseSyncState {
|
|
13
11
|
readonly state: string;
|
|
14
12
|
readonly providerUnreachable: boolean;
|
|
@@ -23,7 +21,11 @@ export interface HouseGa {
|
|
|
23
21
|
readonly choice: HouseGaChoice | null;
|
|
24
22
|
}
|
|
25
23
|
export interface HouseStatus {
|
|
26
|
-
readonly app: string;
|
|
24
|
+
readonly app: string | null;
|
|
25
|
+
readonly preferences: {
|
|
26
|
+
readonly room_ref: string;
|
|
27
|
+
readonly path: string;
|
|
28
|
+
} | null;
|
|
27
29
|
readonly runtime: string;
|
|
28
30
|
readonly credential: HouseCredentialState;
|
|
29
31
|
readonly sync: HouseSyncState | null;
|
|
@@ -33,6 +35,7 @@ export interface HouseStatus {
|
|
|
33
35
|
readonly loss: string | null;
|
|
34
36
|
readonly ga: HouseGa;
|
|
35
37
|
readonly service_mode: 'open' | 'write-halted' | null;
|
|
38
|
+
readonly offline: boolean;
|
|
36
39
|
}
|
|
37
40
|
export type HouseNavigationMode = 'push' | 'replace';
|
|
38
41
|
interface HouseRelease {
|
|
@@ -85,5 +88,128 @@ export interface HouseAppMessage {
|
|
|
85
88
|
readonly from: string;
|
|
86
89
|
readonly body: unknown;
|
|
87
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
|
+
};
|
|
88
214
|
export declare const HOUSE_ADDRESS_MAX_CHARS = 1000;
|
|
89
215
|
export {};
|
|
@@ -12,5 +12,5 @@ export function appAddressOf(root, address) {
|
|
|
12
12
|
export function shellAddressOf(root, appAddress) {
|
|
13
13
|
const { path, rest } = split(appAddress);
|
|
14
14
|
const below = path === '/' ? '' : path;
|
|
15
|
-
return `${root === '/' ? '' : root}${below}
|
|
15
|
+
return `${`${root === '/' ? '' : root}${below}` || '/'}${rest}`;
|
|
16
16
|
}
|
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
|
|
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
|
|
@@ -100,4 +102,5 @@ reference and `readSiteScreenshot` from the `siteScreenshots` it was given by
|
|
|
100
102
|
Site identifier, answers every `install()` `'manual'`, as a browser with no install
|
|
101
103
|
prompt does, answers every `notifications()` `'unavailable'`, as a browser
|
|
102
104
|
without push does, settles every `setBadge`, delivers each App message
|
|
103
|
-
`message({ from, body })` plays, and
|
|
105
|
+
`message({ from, body })` plays, and hands `bridge.runtime` the MD Runtime
|
|
106
|
+
client `attachRuntime(client)` gives it.
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentshouse/app-bridge",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-c415579fa0c3a",
|
|
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
|
-
"license": "
|
|
5
|
+
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"sideEffects": false,
|
|
8
8
|
"engines": {
|
|
@@ -18,9 +18,13 @@
|
|
|
18
18
|
"default": "./dist/client/src/test-host.js"
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@agentshouse/mdruntime": "0.1.0-c6e4c19c13638"
|
|
23
|
+
},
|
|
21
24
|
"files": [
|
|
22
25
|
"dist",
|
|
23
26
|
"docs",
|
|
24
|
-
"README.md"
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE"
|
|
25
29
|
]
|
|
26
30
|
}
|