@agentshouse/app-bridge 0.1.0-ca354d1b3bbdd → 0.1.0-ca559eade7c19
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 +3 -1
- package/dist/calls.d.ts +118 -0
- package/dist/calls.js +1 -0
- package/dist/index.d.ts +24 -4
- package/dist/mdmodel/blocks.d.ts +10 -0
- package/dist/mdmodel/condition.d.ts +149 -0
- package/dist/mdmodel/definition.d.ts +79 -0
- package/dist/mdmodel/divide.d.ts +2 -0
- package/dist/mdmodel/document.d.ts +15 -0
- package/dist/mdmodel/fields.d.ts +5 -0
- package/dist/mdmodel/index.d.ts +18 -0
- package/dist/mdmodel/paths.d.ts +17 -0
- package/dist/mdmodel/profile.d.ts +5 -0
- package/dist/mdmodel/project.d.ts +20 -0
- package/dist/mdmodel/references.d.ts +3 -0
- package/dist/mdmodel/types.d.ts +143 -0
- package/dist/mdmodel/validate.d.ts +7 -0
- package/dist/mdmodel/version.d.ts +1 -0
- package/dist/mdmodel/yaml.d.ts +55 -0
- package/dist/mdruntime/acquisition.d.ts +13 -0
- package/dist/mdruntime/adapter.d.ts +479 -0
- package/dist/mdruntime/binary.d.ts +22 -0
- package/dist/mdruntime/change-set.d.ts +34 -0
- package/dist/mdruntime/change.d.ts +88 -0
- package/dist/mdruntime/client.d.ts +82 -0
- package/dist/mdruntime/collection.d.ts +38 -0
- package/dist/mdruntime/connection.d.ts +141 -0
- package/dist/mdruntime/conversation.d.ts +105 -0
- package/dist/mdruntime/durability.d.ts +14 -0
- package/dist/mdruntime/failure.d.ts +12 -0
- package/dist/mdruntime/file.d.ts +19 -0
- package/dist/mdruntime/model.d.ts +57 -0
- package/dist/mdruntime/observation.d.ts +29 -0
- package/dist/mdruntime/open.d.ts +1 -0
- package/dist/mdruntime/outcome.d.ts +46 -0
- package/dist/mdruntime/overlay.d.ts +27 -0
- package/dist/mdruntime/query.d.ts +253 -0
- package/dist/mdruntime/reach.d.ts +44 -0
- package/dist/mdruntime/readiness.d.ts +52 -0
- package/dist/mdruntime/recovery.d.ts +24 -0
- package/dist/mdruntime/replica.d.ts +45 -0
- package/dist/mdruntime/room-draft.d.ts +155 -0
- package/dist/mdruntime/rows.d.ts +37 -0
- package/dist/mdruntime/save.d.ts +63 -0
- package/dist/mdruntime/search.d.ts +91 -0
- package/dist/mdruntime/seed.d.ts +15 -0
- package/dist/mdruntime/shared.d.ts +10 -0
- package/dist/mdruntime/status.d.ts +26 -0
- package/dist/mdruntime/store.d.ts +160 -0
- package/dist/mdruntime/transfer.d.ts +9 -0
- package/dist/mdruntime/turn.d.ts +6 -0
- package/dist/mdruntime/wire.d.ts +206 -0
- package/dist/test-host.d.ts +5 -2
- package/dist/test-host.js +56 -10
- package/docs/families.md +49 -7
- package/package.json +1 -4
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { ProviderRefusal } from './adapter.js';
|
|
2
|
+
import type { ChangeSet } from './change-set.js';
|
|
3
|
+
import { type CoveredRoom, type Filter, type PendingRoom } from './query.js';
|
|
4
|
+
import type { Open } from './open.js';
|
|
5
|
+
export type DocumentPart = Open<'fields' | 'sections' | 'preamble' | 'path'>;
|
|
6
|
+
export type SearchRequest = {
|
|
7
|
+
text: string;
|
|
8
|
+
documents?: Filter;
|
|
9
|
+
collection?: true;
|
|
10
|
+
conversations?: readonly string[];
|
|
11
|
+
limit?: number;
|
|
12
|
+
};
|
|
13
|
+
export type DocumentHit = {
|
|
14
|
+
room: string;
|
|
15
|
+
path: string;
|
|
16
|
+
type: string;
|
|
17
|
+
score: number;
|
|
18
|
+
matches: Readonly<Record<string, readonly DocumentPart[]>>;
|
|
19
|
+
};
|
|
20
|
+
export type MessageHit = {
|
|
21
|
+
conversation: string;
|
|
22
|
+
identity: string;
|
|
23
|
+
score: number;
|
|
24
|
+
matches: Readonly<Record<string, readonly Open<'text'>[]>>;
|
|
25
|
+
};
|
|
26
|
+
export type SearchCoverage = {
|
|
27
|
+
rooms: readonly CoveredRoom[];
|
|
28
|
+
conversations: readonly string[];
|
|
29
|
+
index: string;
|
|
30
|
+
overlay: readonly string[];
|
|
31
|
+
};
|
|
32
|
+
export type PendingConversation = {
|
|
33
|
+
conversation: string;
|
|
34
|
+
awaits: Open<'index'>;
|
|
35
|
+
};
|
|
36
|
+
export type SearchHits = {
|
|
37
|
+
documents: readonly DocumentHit[];
|
|
38
|
+
messages: readonly MessageHit[];
|
|
39
|
+
};
|
|
40
|
+
export type SearchPending = SearchHits & {
|
|
41
|
+
pending: readonly (PendingRoom | PendingConversation)[];
|
|
42
|
+
coverage: SearchCoverage;
|
|
43
|
+
};
|
|
44
|
+
export type SearchUndeclared = ProviderRefusal & {
|
|
45
|
+
kind: 'undeclared';
|
|
46
|
+
};
|
|
47
|
+
export type SearchResult = (SearchHits & {
|
|
48
|
+
coverage: SearchCoverage;
|
|
49
|
+
}) | SearchPending | SearchUndeclared;
|
|
50
|
+
export declare function undeclaredSearch(): SearchUndeclared;
|
|
51
|
+
export type SearchedDocument = {
|
|
52
|
+
room: string;
|
|
53
|
+
path: string;
|
|
54
|
+
type: string;
|
|
55
|
+
fields: Readonly<Record<string, unknown>>;
|
|
56
|
+
preamble: string;
|
|
57
|
+
sections: Readonly<Record<string, string>>;
|
|
58
|
+
};
|
|
59
|
+
export type SearchedMessage = {
|
|
60
|
+
conversation: string;
|
|
61
|
+
identity: string;
|
|
62
|
+
text: string;
|
|
63
|
+
};
|
|
64
|
+
export type SearchSource = {
|
|
65
|
+
room(room: string): readonly string[];
|
|
66
|
+
document(room: string, path: string): SearchedDocument | null;
|
|
67
|
+
};
|
|
68
|
+
export type SearchPlan = {
|
|
69
|
+
text: string;
|
|
70
|
+
documents: unknown;
|
|
71
|
+
collection: boolean;
|
|
72
|
+
conversations: readonly string[] | null;
|
|
73
|
+
limit: number | null;
|
|
74
|
+
};
|
|
75
|
+
export type SearchIndex = {
|
|
76
|
+
generation(): string;
|
|
77
|
+
rooms(): ReadonlySet<string>;
|
|
78
|
+
conversations(): ReadonlySet<string>;
|
|
79
|
+
indexRoom(room: string): Promise<void>;
|
|
80
|
+
indexMessages(conversation: string, messages: readonly SearchedMessage[], whole: boolean): void;
|
|
81
|
+
forget(rooms: readonly string[]): void;
|
|
82
|
+
changed(set: ChangeSet): void;
|
|
83
|
+
changes(): number;
|
|
84
|
+
caughtUp(): Promise<void>;
|
|
85
|
+
search(plan: SearchPlan, documents: readonly {
|
|
86
|
+
room: string;
|
|
87
|
+
path: string;
|
|
88
|
+
}[] | null, conversations: readonly string[], rooms: ReadonlySet<string> | null, selections: ReadonlyMap<string, readonly string[]> | null): SearchHits;
|
|
89
|
+
};
|
|
90
|
+
export declare function searchPlanOf(input: unknown): SearchPlan;
|
|
91
|
+
export declare function createSearchIndex(source: SearchSource): SearchIndex;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { KeyedResult } from './observation.js';
|
|
2
|
+
import type { QueryRows } from './query.js';
|
|
3
|
+
export type EntrySeed = {
|
|
4
|
+
readonly at: Readonly<Record<string, string>>;
|
|
5
|
+
readonly queries: readonly {
|
|
6
|
+
readonly query: unknown;
|
|
7
|
+
readonly rows: QueryRows;
|
|
8
|
+
}[];
|
|
9
|
+
};
|
|
10
|
+
export type Seeded = {
|
|
11
|
+
readonly rows: QueryRows;
|
|
12
|
+
readonly at: Readonly<Record<string, string>>;
|
|
13
|
+
};
|
|
14
|
+
export declare function entrySeedOf(value: unknown): EntrySeed | null;
|
|
15
|
+
export declare function seededResult(seed: Seeded): KeyedResult;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type Paths<V> = Readonly<Record<string, V>>;
|
|
2
|
+
type Weigh<V> = (key: string, value: V) => number;
|
|
3
|
+
export declare function shared<V>(map: Paths<V>): Paths<V>;
|
|
4
|
+
export declare function patched<V>(base: Paths<V>, set: Iterable<readonly [string, V]>, removed?: Iterable<string>): Paths<V>;
|
|
5
|
+
export declare function tally<V>(map: Paths<V>, weigh: Weigh<V>): number;
|
|
6
|
+
export declare function sizeOf<V>(map: Paths<V>): number;
|
|
7
|
+
export declare function differing<V>(left: Paths<V>, right: Paths<V>, same?: (left: V, right: V) => boolean): ReadonlySet<string>;
|
|
8
|
+
export declare function drafted<V>(base: Paths<V>): Record<string, V>;
|
|
9
|
+
export declare function settled<V>(draft: Record<string, V>): Paths<V>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Open } from './open.js';
|
|
2
|
+
import type { ProviderRefusal } from './adapter.js';
|
|
3
|
+
import type { ReturnReason } from './room-draft.js';
|
|
4
|
+
export type AttentionEntry = {
|
|
5
|
+
room: string;
|
|
6
|
+
path: string;
|
|
7
|
+
returned: ReturnReason;
|
|
8
|
+
} | {
|
|
9
|
+
room: string;
|
|
10
|
+
refusal: ProviderRefusal;
|
|
11
|
+
};
|
|
12
|
+
export type SyncStatus = {
|
|
13
|
+
state: Open<'pending' | 'syncing' | 'synced'>;
|
|
14
|
+
lastCompleted: string | null;
|
|
15
|
+
providerUnreachable: boolean;
|
|
16
|
+
attentionRequired: readonly AttentionEntry[];
|
|
17
|
+
reset: string | null;
|
|
18
|
+
};
|
|
19
|
+
export type CycleProgress = {
|
|
20
|
+
complete: boolean;
|
|
21
|
+
reachable: boolean;
|
|
22
|
+
};
|
|
23
|
+
export declare const STARTING: SyncStatus;
|
|
24
|
+
export declare function transferring(status: SyncStatus): SyncStatus;
|
|
25
|
+
export declare function saving(status: SyncStatus): SyncStatus;
|
|
26
|
+
export declare function same(one: SyncStatus, other: SyncStatus): boolean;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import type { ModelState } from './model.js';
|
|
2
|
+
import type { Capability, HeadChange, Member, OperationScopes, ProviderLimit, ReplicaAdmission, TypedSelection } from './adapter.js';
|
|
3
|
+
import type { AcceptedMessage, KeptReceipt } from './adapter.js';
|
|
4
|
+
import type { ChangeBatch } from './change.js';
|
|
5
|
+
import { type HeldBinary } from './overlay.js';
|
|
6
|
+
import type { ChatDraftFile } from './file.js';
|
|
7
|
+
import type { Submission } from './outcome.js';
|
|
8
|
+
import type { RoomDraftRecord, SavedDraft } from './room-draft.js';
|
|
9
|
+
export declare const STORE_SCHEMA = 25;
|
|
10
|
+
export declare const AUTHORED_SCHEMA = 2;
|
|
11
|
+
export type ReplicaRecord = {
|
|
12
|
+
locator: string;
|
|
13
|
+
name: string;
|
|
14
|
+
handle: string;
|
|
15
|
+
operations: OperationScopes;
|
|
16
|
+
replica: ReplicaAdmission;
|
|
17
|
+
model: ModelState;
|
|
18
|
+
typedSelection: TypedSelection | null;
|
|
19
|
+
selectionModel: ModelState;
|
|
20
|
+
providerOwnedPaths: readonly string[];
|
|
21
|
+
roomVersion: string;
|
|
22
|
+
transfer: string;
|
|
23
|
+
documents: Readonly<Record<string, string>>;
|
|
24
|
+
binaries: Readonly<Record<string, HeldBinary>>;
|
|
25
|
+
revisions: Readonly<Record<string, string>>;
|
|
26
|
+
fileIds: Readonly<Record<string, string>>;
|
|
27
|
+
changes: Readonly<Record<string, HeadChange>>;
|
|
28
|
+
written: Readonly<Record<string, string>>;
|
|
29
|
+
};
|
|
30
|
+
export type StagedLayer = Pick<ReplicaRecord, 'documents' | 'binaries' | 'revisions' | 'fileIds' | 'changes' | 'written'>;
|
|
31
|
+
export type TransferRecord = {
|
|
32
|
+
locator: string;
|
|
33
|
+
transfer: string;
|
|
34
|
+
selection: string;
|
|
35
|
+
from: string;
|
|
36
|
+
last: string;
|
|
37
|
+
pageToken: string | null;
|
|
38
|
+
models: {
|
|
39
|
+
collection: ModelState;
|
|
40
|
+
selection: ModelState;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export type PendingState = {
|
|
44
|
+
readonly drafts: readonly SavedDraft[];
|
|
45
|
+
readonly submission: Submission;
|
|
46
|
+
readonly lost: boolean;
|
|
47
|
+
readonly upload?: unknown;
|
|
48
|
+
readonly accepted?: string;
|
|
49
|
+
};
|
|
50
|
+
export type TargetRecord = {
|
|
51
|
+
established: boolean;
|
|
52
|
+
};
|
|
53
|
+
export type QueueRecord = {
|
|
54
|
+
locator: string;
|
|
55
|
+
pending: readonly {
|
|
56
|
+
batch: ChangeBatch;
|
|
57
|
+
state: PendingState;
|
|
58
|
+
}[];
|
|
59
|
+
};
|
|
60
|
+
export type PresentationRecord = {
|
|
61
|
+
app: string;
|
|
62
|
+
value: unknown;
|
|
63
|
+
};
|
|
64
|
+
export type HeldConversation = {
|
|
65
|
+
conversation: string;
|
|
66
|
+
read: string | null | undefined;
|
|
67
|
+
partial: boolean;
|
|
68
|
+
};
|
|
69
|
+
export type ConversationWrite = {
|
|
70
|
+
conversation: string;
|
|
71
|
+
messages: readonly AcceptedMessage[];
|
|
72
|
+
read?: {
|
|
73
|
+
at: string | null;
|
|
74
|
+
partial: boolean;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
export type ChatSubmission = {
|
|
78
|
+
readonly operation: string;
|
|
79
|
+
readonly text: string;
|
|
80
|
+
readonly files: readonly ChatDraftFile[];
|
|
81
|
+
readonly turn: string | null;
|
|
82
|
+
};
|
|
83
|
+
export type ChatDraftRecord = {
|
|
84
|
+
conversation: string;
|
|
85
|
+
text: string;
|
|
86
|
+
files: readonly ChatDraftFile[];
|
|
87
|
+
revision: string;
|
|
88
|
+
submitted?: readonly ChatSubmission[];
|
|
89
|
+
moves?: readonly string[];
|
|
90
|
+
};
|
|
91
|
+
export type RecordWrite = {
|
|
92
|
+
next: ReplicaRecord;
|
|
93
|
+
previous: ReplicaRecord | null;
|
|
94
|
+
stored?: StagedLayer;
|
|
95
|
+
};
|
|
96
|
+
export type AuthoredWrite = {
|
|
97
|
+
locator: string;
|
|
98
|
+
queue: readonly ChangeBatch[];
|
|
99
|
+
saved?: ReadonlyMap<string, readonly SavedDraft[]>;
|
|
100
|
+
roomDrafts?: readonly RoomDraftRecord[];
|
|
101
|
+
consumedRoomDrafts?: readonly string[];
|
|
102
|
+
};
|
|
103
|
+
export type RuntimeStore = {
|
|
104
|
+
all(): Promise<readonly ReplicaRecord[]>;
|
|
105
|
+
keepAuthored(input: AuthoredWrite): Promise<void>;
|
|
106
|
+
write(input: RecordWrite): Promise<void>;
|
|
107
|
+
revokeModels(records: readonly ReplicaRecord[]): Promise<void>;
|
|
108
|
+
lastCompleted(): Promise<string | null>;
|
|
109
|
+
complete(at: string): Promise<void>;
|
|
110
|
+
providerLimits(): Promise<readonly ProviderLimit[]>;
|
|
111
|
+
capabilities(): Promise<readonly Capability[]>;
|
|
112
|
+
declare(limits: readonly ProviderLimit[], capabilities: readonly Capability[]): Promise<void>;
|
|
113
|
+
member(): Promise<Member | null>;
|
|
114
|
+
keepMember(member: Member | null): Promise<void>;
|
|
115
|
+
targets(): Promise<Readonly<Record<string, TargetRecord>>>;
|
|
116
|
+
keepTargets(targets: Readonly<Record<string, TargetRecord>>): Promise<void>;
|
|
117
|
+
queues(): Promise<readonly QueueRecord[]>;
|
|
118
|
+
submit(locator: string, id: string, submission: Submission, lost: boolean): Promise<void>;
|
|
119
|
+
accept(locator: string, id: string, roomVersion: string): Promise<void>;
|
|
120
|
+
keepUpload(locator: string, id: string, upload: unknown): Promise<void>;
|
|
121
|
+
roomDrafts(): Promise<readonly RoomDraftRecord[]>;
|
|
122
|
+
presentation(): Promise<readonly PresentationRecord[]>;
|
|
123
|
+
present(record: PresentationRecord): Promise<void>;
|
|
124
|
+
conversations(): Promise<readonly HeldConversation[]>;
|
|
125
|
+
keepMessages(write: ConversationWrite): Promise<void>;
|
|
126
|
+
messageWindow(conversation: string, limit: number | undefined): Promise<AcceptedMessage[]>;
|
|
127
|
+
messagesAfter(conversation: string, identity: string | null): Promise<AcceptedMessage[]>;
|
|
128
|
+
messageIdentities(conversation: string): Promise<readonly string[]>;
|
|
129
|
+
turnArrived(conversation: string, turn: string): Promise<boolean>;
|
|
130
|
+
dropConversations(conversations: readonly string[]): Promise<void>;
|
|
131
|
+
chatDrafts(): Promise<readonly ChatDraftRecord[]>;
|
|
132
|
+
keepChatDrafts(records: readonly ChatDraftRecord[]): Promise<void>;
|
|
133
|
+
dropChatDraft(conversation: string): Promise<void>;
|
|
134
|
+
keepRoomDraft(record: RoomDraftRecord): Promise<void>;
|
|
135
|
+
discardRoomDraft(locator: string, path: string): Promise<void>;
|
|
136
|
+
fences(): Promise<readonly string[]>;
|
|
137
|
+
erase(locators: readonly string[]): Promise<void>;
|
|
138
|
+
discard(locator: string): Promise<void>;
|
|
139
|
+
transfers(): Promise<readonly TransferRecord[]>;
|
|
140
|
+
staged(record: TransferRecord): Promise<StagedLayer>;
|
|
141
|
+
stage(record: TransferRecord, page: StagedLayer): Promise<void>;
|
|
142
|
+
abandon(locator: string): Promise<void>;
|
|
143
|
+
receivedHeads(): Promise<readonly KeptReceipt[]>;
|
|
144
|
+
receivedParts(key: string, count: number): Promise<readonly unknown[]>;
|
|
145
|
+
keepReceived(key: string, head: unknown, part?: {
|
|
146
|
+
index: number;
|
|
147
|
+
value: unknown;
|
|
148
|
+
}): Promise<void>;
|
|
149
|
+
dropReceived(keys: readonly string[]): Promise<void>;
|
|
150
|
+
generation(): Promise<string | null>;
|
|
151
|
+
rememberGeneration(value: string): Promise<void>;
|
|
152
|
+
close(): void;
|
|
153
|
+
};
|
|
154
|
+
export declare function authoredHolder(): Promise<string | null>;
|
|
155
|
+
export declare function authoredBy(holder: string): Promise<boolean>;
|
|
156
|
+
export declare function authoredBinding(): Promise<string | null>;
|
|
157
|
+
export declare function bindAuthored(binding: string): Promise<void>;
|
|
158
|
+
export declare function removeRuntimeStore(holder?: string): Promise<boolean>;
|
|
159
|
+
export declare function openDatabase(name: string, version: number, upgrade: (opening: IDBOpenDBRequest, oldVersion: number) => void): Promise<IDBDatabase>;
|
|
160
|
+
export declare function openRuntimeStore(fenced: (locator: string) => boolean): Promise<RuntimeStore>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function yielded(): Promise<void>;
|
|
2
|
+
export declare const ROW_WEIGHT = 256;
|
|
3
|
+
export type Later<T> = T | Promise<T>;
|
|
4
|
+
export declare function after<T, R>(value: Later<T>, next: (value: T) => R): Later<R>;
|
|
5
|
+
export declare function inUnits<T>(items: Iterable<T>, each: (item: T) => number): Later<void>;
|
|
6
|
+
export declare function inChunks<T>(items: readonly T[], weigh: (item: T) => number, each: (chunk: readonly T[]) => void): Promise<void>;
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import type { ConnectionRefusal } from './connection.js';
|
|
2
|
+
import type { Described } from './failure.js';
|
|
3
|
+
export type RuntimePort = {
|
|
4
|
+
postMessage(message: unknown): void;
|
|
5
|
+
addEventListener(type: 'message' | 'close', listener: (event: {
|
|
6
|
+
data?: unknown;
|
|
7
|
+
}) => void): void;
|
|
8
|
+
start(): void;
|
|
9
|
+
};
|
|
10
|
+
export type WireReach = 'within' | 'app' | 'runtime' | 'actions' | 'whole';
|
|
11
|
+
export type WireEffect = 'read' | 'write' | 'action';
|
|
12
|
+
export type WireCall = {
|
|
13
|
+
readonly reach: WireReach;
|
|
14
|
+
readonly effect: WireEffect;
|
|
15
|
+
};
|
|
16
|
+
declare const MEMBERS: {
|
|
17
|
+
readonly rooms: {
|
|
18
|
+
readonly reach: 'within';
|
|
19
|
+
readonly effect: 'read';
|
|
20
|
+
};
|
|
21
|
+
readonly query: {
|
|
22
|
+
readonly reach: 'within';
|
|
23
|
+
readonly effect: 'read';
|
|
24
|
+
};
|
|
25
|
+
readonly search: {
|
|
26
|
+
readonly reach: 'within';
|
|
27
|
+
readonly effect: 'read';
|
|
28
|
+
};
|
|
29
|
+
readonly types: {
|
|
30
|
+
readonly reach: 'within';
|
|
31
|
+
readonly effect: 'read';
|
|
32
|
+
};
|
|
33
|
+
readonly save: {
|
|
34
|
+
readonly reach: 'within';
|
|
35
|
+
readonly effect: 'write';
|
|
36
|
+
};
|
|
37
|
+
readonly history: {
|
|
38
|
+
readonly reach: 'within';
|
|
39
|
+
readonly effect: 'read';
|
|
40
|
+
};
|
|
41
|
+
readonly 'binaryFile.read': {
|
|
42
|
+
readonly reach: 'within';
|
|
43
|
+
readonly effect: 'read';
|
|
44
|
+
};
|
|
45
|
+
readonly 'binaryFile.readReference': {
|
|
46
|
+
readonly reach: 'within';
|
|
47
|
+
readonly effect: 'read';
|
|
48
|
+
};
|
|
49
|
+
readonly call: {
|
|
50
|
+
readonly reach: 'actions';
|
|
51
|
+
readonly effect: 'action';
|
|
52
|
+
};
|
|
53
|
+
readonly reached: {
|
|
54
|
+
readonly reach: 'within';
|
|
55
|
+
readonly effect: 'read';
|
|
56
|
+
};
|
|
57
|
+
readonly log: {
|
|
58
|
+
readonly reach: 'whole';
|
|
59
|
+
readonly effect: 'read';
|
|
60
|
+
};
|
|
61
|
+
readonly persistence: {
|
|
62
|
+
readonly reach: 'runtime';
|
|
63
|
+
readonly effect: 'read';
|
|
64
|
+
};
|
|
65
|
+
readonly retry: {
|
|
66
|
+
readonly reach: 'runtime';
|
|
67
|
+
readonly effect: 'write';
|
|
68
|
+
};
|
|
69
|
+
readonly reauthorize: {
|
|
70
|
+
readonly reach: 'runtime';
|
|
71
|
+
readonly effect: 'write';
|
|
72
|
+
};
|
|
73
|
+
readonly 'roomDraft.list': {
|
|
74
|
+
readonly reach: 'within';
|
|
75
|
+
readonly effect: 'read';
|
|
76
|
+
};
|
|
77
|
+
readonly 'roomDraft.read': {
|
|
78
|
+
readonly reach: 'within';
|
|
79
|
+
readonly effect: 'read';
|
|
80
|
+
};
|
|
81
|
+
readonly 'roomDraft.write': {
|
|
82
|
+
readonly reach: 'within';
|
|
83
|
+
readonly effect: 'write';
|
|
84
|
+
};
|
|
85
|
+
readonly 'roomDraft.discard': {
|
|
86
|
+
readonly reach: 'within';
|
|
87
|
+
readonly effect: 'write';
|
|
88
|
+
};
|
|
89
|
+
readonly 'presentation.read': {
|
|
90
|
+
readonly reach: 'app';
|
|
91
|
+
readonly effect: 'read';
|
|
92
|
+
};
|
|
93
|
+
readonly 'presentation.write': {
|
|
94
|
+
readonly reach: 'app';
|
|
95
|
+
readonly effect: 'write';
|
|
96
|
+
};
|
|
97
|
+
readonly 'conversation.list': {
|
|
98
|
+
readonly reach: 'within';
|
|
99
|
+
readonly effect: 'read';
|
|
100
|
+
};
|
|
101
|
+
readonly 'conversation.read': {
|
|
102
|
+
readonly reach: 'within';
|
|
103
|
+
readonly effect: 'read';
|
|
104
|
+
};
|
|
105
|
+
readonly 'conversation.create': {
|
|
106
|
+
readonly reach: 'within';
|
|
107
|
+
readonly effect: 'action';
|
|
108
|
+
};
|
|
109
|
+
readonly 'conversation.send': {
|
|
110
|
+
readonly reach: 'within';
|
|
111
|
+
readonly effect: 'action';
|
|
112
|
+
};
|
|
113
|
+
readonly 'conversation.answer': {
|
|
114
|
+
readonly reach: 'within';
|
|
115
|
+
readonly effect: 'action';
|
|
116
|
+
};
|
|
117
|
+
readonly 'conversation.interrupt': {
|
|
118
|
+
readonly reach: 'within';
|
|
119
|
+
readonly effect: 'action';
|
|
120
|
+
};
|
|
121
|
+
readonly 'conversation.kill': {
|
|
122
|
+
readonly reach: 'within';
|
|
123
|
+
readonly effect: 'action';
|
|
124
|
+
};
|
|
125
|
+
readonly 'conversation.cancel': {
|
|
126
|
+
readonly reach: 'within';
|
|
127
|
+
readonly effect: 'action';
|
|
128
|
+
};
|
|
129
|
+
readonly 'conversation.delete': {
|
|
130
|
+
readonly reach: 'within';
|
|
131
|
+
readonly effect: 'action';
|
|
132
|
+
};
|
|
133
|
+
readonly 'chatDraft.write': {
|
|
134
|
+
readonly reach: 'within';
|
|
135
|
+
readonly effect: 'write';
|
|
136
|
+
};
|
|
137
|
+
readonly 'chatDraft.discard': {
|
|
138
|
+
readonly reach: 'within';
|
|
139
|
+
readonly effect: 'write';
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
declare const TOPICS: {
|
|
143
|
+
readonly rooms: 'within';
|
|
144
|
+
readonly readiness: 'within';
|
|
145
|
+
readonly 'connection-refusal': 'runtime';
|
|
146
|
+
readonly 'storage-loss': 'runtime';
|
|
147
|
+
readonly 'deployment-facts': 'runtime';
|
|
148
|
+
readonly 'sync-status': 'within';
|
|
149
|
+
readonly 'service-mode': 'runtime';
|
|
150
|
+
readonly member: 'runtime';
|
|
151
|
+
readonly query: 'within';
|
|
152
|
+
readonly queue: 'within';
|
|
153
|
+
readonly 'room-drafts': 'within';
|
|
154
|
+
readonly presentation: 'app';
|
|
155
|
+
readonly conversation: 'within';
|
|
156
|
+
readonly conversations: 'within';
|
|
157
|
+
readonly agents: 'within';
|
|
158
|
+
};
|
|
159
|
+
export declare const WIRE: {
|
|
160
|
+
readonly members: Readonly<Record<string, WireCall>>;
|
|
161
|
+
readonly topics: Readonly<Record<string, WireReach>>;
|
|
162
|
+
};
|
|
163
|
+
export type WireMember = keyof typeof MEMBERS;
|
|
164
|
+
export type WireTopic = keyof typeof TOPICS;
|
|
165
|
+
export type WireRequest = {
|
|
166
|
+
kind: 'hello';
|
|
167
|
+
} | {
|
|
168
|
+
kind: 'call';
|
|
169
|
+
id: number;
|
|
170
|
+
member: WireMember;
|
|
171
|
+
input: readonly unknown[];
|
|
172
|
+
} | {
|
|
173
|
+
kind: 'observe';
|
|
174
|
+
id: number;
|
|
175
|
+
topic: WireTopic;
|
|
176
|
+
input: readonly unknown[];
|
|
177
|
+
} | {
|
|
178
|
+
kind: 'stop';
|
|
179
|
+
id: number;
|
|
180
|
+
};
|
|
181
|
+
export type WireAnswer = {
|
|
182
|
+
kind: 'result';
|
|
183
|
+
id: number;
|
|
184
|
+
value: unknown;
|
|
185
|
+
} | ({
|
|
186
|
+
kind: 'failure';
|
|
187
|
+
id: number;
|
|
188
|
+
} & Described) | {
|
|
189
|
+
kind: 'event';
|
|
190
|
+
id: number;
|
|
191
|
+
value: unknown;
|
|
192
|
+
} | {
|
|
193
|
+
kind: 'refusal';
|
|
194
|
+
refusal: ConnectionRefusal;
|
|
195
|
+
} | {
|
|
196
|
+
kind: 'ended';
|
|
197
|
+
};
|
|
198
|
+
export declare function unanswered(call: {
|
|
199
|
+
readonly id: number;
|
|
200
|
+
readonly member: WireMember;
|
|
201
|
+
}): WireAnswer | null;
|
|
202
|
+
export declare const AUTHORIZATION_ENDED = "the host authorization ended";
|
|
203
|
+
export declare const PORT_CLOSED = "the port closed";
|
|
204
|
+
export declare function request(message: unknown): WireRequest | null;
|
|
205
|
+
export declare function answer(message: unknown): WireAnswer | null;
|
|
206
|
+
export {};
|
package/dist/test-host.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { MdRuntimeClient } from '
|
|
2
|
-
import type { HouseAnalyticsChoice, HouseAppMessage, HouseExternalAnswer, HouseExternalRequest, HouseNavigationMode, HouseRefusal, HouseSourceDownload, HouseSourceTop, HouseStatus, HouseTab } from './index.js';
|
|
1
|
+
import type { MdRuntimeClient } from './mdruntime/client.js';
|
|
2
|
+
import type { HouseActivation, HouseAnalyticsChoice, HouseAppMessage, HouseExternalAnswer, HouseExternalRequest, HouseNavigationMode, HouseRefusal, HouseSourceDownload, HouseSourceTop, HouseStatus, HouseTab, HouseTask } from './index.js';
|
|
3
3
|
export interface HouseBridgeNavigation {
|
|
4
4
|
readonly mode: HouseNavigationMode;
|
|
5
5
|
readonly address: string;
|
|
@@ -15,6 +15,9 @@ export interface HouseBridgeTestHost {
|
|
|
15
15
|
publish(status: HouseStatus): void;
|
|
16
16
|
message(message: HouseAppMessage): void;
|
|
17
17
|
attachRuntime(runtime: MdRuntimeClient): void;
|
|
18
|
+
checkpoint(): Promise<HouseTask>;
|
|
19
|
+
restore(task: HouseTask | null): Promise<boolean>;
|
|
20
|
+
settle(activation: HouseActivation): void;
|
|
18
21
|
}
|
|
19
22
|
export interface HouseBridgeTestHostOptions {
|
|
20
23
|
readonly address?: string;
|
package/dist/test-host.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const HOST_ORIGIN = 'https://house.invalid';
|
|
2
|
-
const ADDRESS_MAX_CHARS =
|
|
2
|
+
const ADDRESS_MAX_CHARS = 64 * 1024;
|
|
3
3
|
function sameOriginPath(value) {
|
|
4
4
|
if (typeof value !== 'string')
|
|
5
5
|
return null;
|
|
@@ -29,6 +29,21 @@ function navigationRefused(address) {
|
|
|
29
29
|
address,
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
|
+
function followHeld(listeners, listener, held) {
|
|
33
|
+
let following = true;
|
|
34
|
+
queueMicrotask(() => {
|
|
35
|
+
if (!following)
|
|
36
|
+
return;
|
|
37
|
+
listeners.add(listener);
|
|
38
|
+
const value = held();
|
|
39
|
+
if (value !== null)
|
|
40
|
+
listener(value);
|
|
41
|
+
});
|
|
42
|
+
return () => {
|
|
43
|
+
following = false;
|
|
44
|
+
listeners.delete(listener);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
32
47
|
export function createHouseBridgeTestHost(options = {}) {
|
|
33
48
|
const navigations = [];
|
|
34
49
|
const ceremonies = [];
|
|
@@ -42,6 +57,7 @@ export function createHouseBridgeTestHost(options = {}) {
|
|
|
42
57
|
let published = options.status ?? null;
|
|
43
58
|
let shown = null;
|
|
44
59
|
let seen = null;
|
|
60
|
+
let cooperation = null;
|
|
45
61
|
let attached = () => { };
|
|
46
62
|
const runtime = new Promise((resolve) => {
|
|
47
63
|
attached = resolve;
|
|
@@ -63,7 +79,17 @@ export function createHouseBridgeTestHost(options = {}) {
|
|
|
63
79
|
});
|
|
64
80
|
}
|
|
65
81
|
function navigate(mode, asked) {
|
|
66
|
-
|
|
82
|
+
let path = asked;
|
|
83
|
+
if (/^https?:\/\//i.test(asked)) {
|
|
84
|
+
try {
|
|
85
|
+
const target = new URL(asked);
|
|
86
|
+
path = target.origin === HOST_ORIGIN ? target.pathname + target.search + target.hash : '';
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
path = '';
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const target = sameOriginPath(path);
|
|
67
93
|
if (target === null)
|
|
68
94
|
return Promise.reject(navigationRefused(asked));
|
|
69
95
|
navigations.push({ mode, address: target });
|
|
@@ -76,10 +102,7 @@ export function createHouseBridgeTestHost(options = {}) {
|
|
|
76
102
|
runtime,
|
|
77
103
|
address: () => shown,
|
|
78
104
|
onAddress(listener) {
|
|
79
|
-
addressListeners
|
|
80
|
-
return () => {
|
|
81
|
-
addressListeners.delete(listener);
|
|
82
|
-
};
|
|
105
|
+
return followHeld(addressListeners, listener, () => shown);
|
|
83
106
|
},
|
|
84
107
|
push: (asked) => navigate('push', asked),
|
|
85
108
|
replace: (asked) => navigate('replace', asked),
|
|
@@ -106,10 +129,7 @@ export function createHouseBridgeTestHost(options = {}) {
|
|
|
106
129
|
readSiteScreenshot: (site) => Promise.resolve(options.siteScreenshots?.[site] ?? null),
|
|
107
130
|
status: () => seen,
|
|
108
131
|
onStatus(listener) {
|
|
109
|
-
statusListeners
|
|
110
|
-
return () => {
|
|
111
|
-
statusListeners.delete(listener);
|
|
112
|
-
};
|
|
132
|
+
return followHeld(statusListeners, listener, () => seen);
|
|
113
133
|
},
|
|
114
134
|
messages(listener) {
|
|
115
135
|
messageListeners.add(listener);
|
|
@@ -125,7 +145,19 @@ export function createHouseBridgeTestHost(options = {}) {
|
|
|
125
145
|
consents.push(choice);
|
|
126
146
|
publish({ ...published, analytics: { measures: true, choice } });
|
|
127
147
|
},
|
|
148
|
+
cooperate(given) {
|
|
149
|
+
cooperation = given;
|
|
150
|
+
return () => {
|
|
151
|
+
if (cooperation === given)
|
|
152
|
+
cooperation = null;
|
|
153
|
+
};
|
|
154
|
+
},
|
|
128
155
|
};
|
|
156
|
+
function cooperating() {
|
|
157
|
+
if (cooperation === null)
|
|
158
|
+
throw new Error('the App registered no cooperation');
|
|
159
|
+
return cooperation;
|
|
160
|
+
}
|
|
129
161
|
Object.defineProperty(globalThis, 'houseBridge', { value: bridge, configurable: true });
|
|
130
162
|
if (published !== null)
|
|
131
163
|
publish(published);
|
|
@@ -150,5 +182,19 @@ export function createHouseBridgeTestHost(options = {}) {
|
|
|
150
182
|
attachRuntime(client) {
|
|
151
183
|
attached(client);
|
|
152
184
|
},
|
|
185
|
+
async checkpoint() {
|
|
186
|
+
const held = cooperating();
|
|
187
|
+
await held.checkpoint();
|
|
188
|
+
await held.persist();
|
|
189
|
+
return JSON.parse(JSON.stringify((await held.capture()) ?? null));
|
|
190
|
+
},
|
|
191
|
+
async restore(task) {
|
|
192
|
+
const held = cooperating();
|
|
193
|
+
await held.restore(task);
|
|
194
|
+
return (await held.ready()) === true;
|
|
195
|
+
},
|
|
196
|
+
settle(activation) {
|
|
197
|
+
cooperating().settle(activation);
|
|
198
|
+
},
|
|
153
199
|
};
|
|
154
200
|
}
|