@hosty-sdk/app 0.26.0 → 0.27.22
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 +147 -8
- package/dist/index.d.ts +9 -6
- package/dist/index.js +10 -1
- package/dist/next.d.ts +4 -0
- package/dist/next.js +29 -0
- package/dist/overlay-react.d.ts +7 -1
- package/dist/overlay-react.js +2 -2
- package/dist/react.d.ts +1 -0
- package/dist/react.js +3 -0
- package/dist/ui-composition.d.ts +71 -0
- package/dist/ui-composition.js +232 -0
- package/dist/ui-context.d.ts +2 -0
- package/dist/ui-context.js +1 -0
- package/dist/ui-embedded.d.ts +18 -1
- package/dist/ui-embedded.js +123 -17
- package/dist/ui-frame-layer.d.ts +36 -0
- package/dist/ui-frame-layer.js +88 -0
- package/dist/ui-frame.d.ts +2 -0
- package/dist/ui-frame.js +43 -7
- package/dist/ui-host.d.ts +62 -15
- package/dist/ui-host.js +666 -76
- package/dist/ui-navigation-react.d.ts +17 -0
- package/dist/ui-navigation-react.js +89 -0
- package/dist/ui-react.d.ts +13 -3
- package/dist/ui-react.js +127 -50
- package/dist/ui-server.d.ts +3 -1
- package/dist/ui-server.js +14 -2
- package/dist/ui-transport.d.ts +2 -2
- package/dist/ui-transport.js +1 -1
- package/dist/ui-types.d.ts +88 -0
- package/dist/ui-types.js +1 -0
- package/dist/ui-workspaces.d.ts +54 -0
- package/dist/ui-workspaces.js +3 -0
- package/dist/ui.d.ts +7 -1
- package/dist/ui.js +22 -0
- package/package.json +5 -1
package/dist/ui-types.d.ts
CHANGED
|
@@ -68,6 +68,7 @@ export type PresentationResult = {
|
|
|
68
68
|
requestId: string;
|
|
69
69
|
target: PanelTarget;
|
|
70
70
|
readiness: SurfaceReadiness;
|
|
71
|
+
presentationId?: string;
|
|
71
72
|
} | {
|
|
72
73
|
status: "blocked" | "unsupported" | "rejected" | "uncertain" | "unknown";
|
|
73
74
|
requestId: string;
|
|
@@ -77,6 +78,7 @@ export type PresentationOptions = {
|
|
|
77
78
|
placement: "side";
|
|
78
79
|
requestId: string;
|
|
79
80
|
signal?: AbortSignal;
|
|
81
|
+
reuse?: "exact" | "new";
|
|
80
82
|
};
|
|
81
83
|
export type UiEvent = {
|
|
82
84
|
type: "environment";
|
|
@@ -97,3 +99,89 @@ export declare function isSurfaceRoute(route: unknown): route is string;
|
|
|
97
99
|
export declare function routeWithin(route: string, declared: string): boolean;
|
|
98
100
|
/** Constructs navigation only. Core must advertise pinnedOpen and revalidate at redemption. */
|
|
99
101
|
export declare function buildSurfaceOpenUrl(coreOrigin: string, destination: AppSurfaceRef): string;
|
|
102
|
+
export declare const UI_COMPOSITION_CAPABILITY = "ui.composition.v1";
|
|
103
|
+
export type UiChromeOverrides = {
|
|
104
|
+
navigation?: "show" | "hide";
|
|
105
|
+
tools?: {
|
|
106
|
+
enabled?: boolean;
|
|
107
|
+
launcher?: "show" | "hide";
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
export type UiChromePolicy = Readonly<{
|
|
111
|
+
navigation: "show" | "hide";
|
|
112
|
+
tools: Readonly<{
|
|
113
|
+
enabled: boolean;
|
|
114
|
+
launcher: "show" | "hide";
|
|
115
|
+
owner: "local" | "host" | "unavailable";
|
|
116
|
+
}>;
|
|
117
|
+
}>;
|
|
118
|
+
export type UiChromeSource = "host" | "url" | "app" | "legacy" | "default";
|
|
119
|
+
export type UiChromeSnapshot = UiChromePolicy & Readonly<{
|
|
120
|
+
revision: number;
|
|
121
|
+
hostRevision: number;
|
|
122
|
+
rootDisabled: boolean;
|
|
123
|
+
stale: boolean;
|
|
124
|
+
connection: UiEnvironment["connection"];
|
|
125
|
+
capabilities: readonly string[];
|
|
126
|
+
sources: Readonly<{
|
|
127
|
+
navigation: UiChromeSource;
|
|
128
|
+
enabled: UiChromeSource;
|
|
129
|
+
launcher: UiChromeSource;
|
|
130
|
+
}>;
|
|
131
|
+
}>;
|
|
132
|
+
export type UiNavigationTarget = {
|
|
133
|
+
appId: string;
|
|
134
|
+
installationId: string;
|
|
135
|
+
entryKey: string;
|
|
136
|
+
};
|
|
137
|
+
export type UiNavigationEntry = Readonly<{
|
|
138
|
+
key: string;
|
|
139
|
+
label: string;
|
|
140
|
+
icon: string | null;
|
|
141
|
+
endpoint: string | null;
|
|
142
|
+
origin: string | null;
|
|
143
|
+
route: string | null;
|
|
144
|
+
available: boolean;
|
|
145
|
+
state: string;
|
|
146
|
+
standaloneHref: string | null;
|
|
147
|
+
}>;
|
|
148
|
+
export type UiNavigationCatalog = Readonly<{
|
|
149
|
+
appId: string;
|
|
150
|
+
installationId: string;
|
|
151
|
+
revision: string;
|
|
152
|
+
entries: readonly UiNavigationEntry[];
|
|
153
|
+
}>;
|
|
154
|
+
export type UiNavigationSnapshot = Readonly<{
|
|
155
|
+
status: "loading" | "ready" | "unavailable";
|
|
156
|
+
catalog: UiNavigationCatalog | null;
|
|
157
|
+
entries: readonly UiNavigationEntry[];
|
|
158
|
+
activeKey: string | null;
|
|
159
|
+
code?: string;
|
|
160
|
+
}>;
|
|
161
|
+
export type UiResolvedNavigation = {
|
|
162
|
+
target: UiNavigationTarget;
|
|
163
|
+
surface: UiFrameSurface | null;
|
|
164
|
+
available: boolean;
|
|
165
|
+
state: string;
|
|
166
|
+
standaloneHref: string | null;
|
|
167
|
+
};
|
|
168
|
+
export type UiActionOptions = {
|
|
169
|
+
requestId: string;
|
|
170
|
+
signal?: AbortSignal;
|
|
171
|
+
};
|
|
172
|
+
export type UiActionResult = {
|
|
173
|
+
status: "accepted";
|
|
174
|
+
requestId: string;
|
|
175
|
+
} | {
|
|
176
|
+
status: "blocked" | "unsupported" | "rejected" | "uncertain" | "unknown";
|
|
177
|
+
requestId: string;
|
|
178
|
+
code: string;
|
|
179
|
+
};
|
|
180
|
+
export type UiNavigationResult = UiActionResult;
|
|
181
|
+
export type UiToolPickerResult = UiActionResult;
|
|
182
|
+
export type UiRouterAdapter = {
|
|
183
|
+
endpoint?: string;
|
|
184
|
+
getRoute(): string;
|
|
185
|
+
subscribe(listener: () => void): () => void;
|
|
186
|
+
navigate(route: string): void | Promise<void>;
|
|
187
|
+
};
|
package/dist/ui-types.js
CHANGED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { PanelTarget, UiChromeOverrides, UiFrameSurface, UiResolvedPanel, SurfaceReadiness } from "./ui-types.js";
|
|
2
|
+
export declare const DEFAULT_WORKSPACE = "default";
|
|
3
|
+
export declare const ROOT_VIEW = "root";
|
|
4
|
+
export type UiPresentation = {
|
|
5
|
+
key: string;
|
|
6
|
+
presentationId: string;
|
|
7
|
+
workspaceId: string;
|
|
8
|
+
target: PanelTarget;
|
|
9
|
+
resolved: UiResolvedPanel;
|
|
10
|
+
readiness: SurfaceReadiness;
|
|
11
|
+
attention: number;
|
|
12
|
+
currentRoute: string | null;
|
|
13
|
+
focusedAt: number;
|
|
14
|
+
};
|
|
15
|
+
export type UiWorkspaceSnapshot = {
|
|
16
|
+
workspaceId: string;
|
|
17
|
+
selectedId: string | null;
|
|
18
|
+
expanded: boolean;
|
|
19
|
+
width: number;
|
|
20
|
+
};
|
|
21
|
+
/** Adapters retain frames in one layer; present is also used for movement to another region. */
|
|
22
|
+
export type UiWorkspaceRenderer = {
|
|
23
|
+
present(instance: UiPresentation, signal: AbortSignal): Promise<"accepted" | "unavailable">;
|
|
24
|
+
focus(presentationId: string): void;
|
|
25
|
+
collapse(): void;
|
|
26
|
+
release(presentationId: string): void;
|
|
27
|
+
showToolPicker(signal: AbortSignal): Promise<"accepted" | "unavailable">;
|
|
28
|
+
/** Only matching stable layer identities can move frames without recreating their document. */
|
|
29
|
+
frameLayer?: object;
|
|
30
|
+
};
|
|
31
|
+
export type UiViewDescriptor = {
|
|
32
|
+
viewId: string;
|
|
33
|
+
workspaceId: string;
|
|
34
|
+
chrome?: UiChromeOverrides;
|
|
35
|
+
presentationId?: string;
|
|
36
|
+
navigate?: (surface: UiFrameSurface) => void | Promise<void>;
|
|
37
|
+
};
|
|
38
|
+
export type UiPlacementResolver = (request: {
|
|
39
|
+
source: Readonly<{
|
|
40
|
+
viewId: string;
|
|
41
|
+
workspaceId: string;
|
|
42
|
+
}>;
|
|
43
|
+
target: PanelTarget;
|
|
44
|
+
presentations: readonly UiPresentation[];
|
|
45
|
+
}) => {
|
|
46
|
+
workspaceId: string;
|
|
47
|
+
presentationId?: string;
|
|
48
|
+
};
|
|
49
|
+
export type UiWorkspace = UiWorkspaceSnapshot & {
|
|
50
|
+
generation: number;
|
|
51
|
+
renderer?: UiWorkspaceRenderer;
|
|
52
|
+
owner?: object;
|
|
53
|
+
};
|
|
54
|
+
export declare const workspace: (workspaceId: string) => UiWorkspace;
|
package/dist/ui.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import type { PanelTarget, PresentationOptions, PresentationResult, UiEnvironment, UiEvent } from "@hosty-sdk/app/ui/types";
|
|
1
|
+
import type { UiChromeSnapshot, UiNavigationSnapshot, UiActionOptions, UiActionResult, PanelTarget, PresentationOptions, PresentationResult, UiEnvironment, UiEvent } from "@hosty-sdk/app/ui/types";
|
|
2
2
|
export * from "@hosty-sdk/app/ui/types";
|
|
3
3
|
export interface UiClient {
|
|
4
4
|
getEnvironment(): UiEnvironment;
|
|
5
|
+
getChrome(): UiChromeSnapshot;
|
|
6
|
+
subscribeChrome(listener: () => void): () => void;
|
|
7
|
+
getNavigation(): UiNavigationSnapshot;
|
|
8
|
+
subscribeNavigation(listener: () => void): () => void;
|
|
9
|
+
navigate(entryKey: string, options: UiActionOptions): Promise<UiActionResult>;
|
|
10
|
+
openToolPicker(options: UiActionOptions): Promise<UiActionResult>;
|
|
5
11
|
openSurface(target: PanelTarget, options: PresentationOptions): Promise<PresentationResult>;
|
|
6
12
|
getPresentation(requestId: string, options?: {
|
|
7
13
|
signal?: AbortSignal;
|
package/dist/ui.js
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
|
+
import { INITIAL_CHROME, INITIAL_NAVIGATION } from "./ui-composition.js";
|
|
1
2
|
export * from "@hosty-sdk/app/ui/types";
|
|
2
3
|
let active = null;
|
|
3
4
|
const listeners = new Set();
|
|
4
5
|
const unavailable = (requestId) => ({ status: "unsupported", requestId, code: "host_unavailable" });
|
|
6
|
+
const chromeListeners = new Set(), navigationListeners = new Set();
|
|
5
7
|
const initial = { mode: "standalone", connection: "connecting" };
|
|
6
8
|
/** One document-local facade shared by domain apps; it never selects a provider or opens popups. */
|
|
7
9
|
export const ui = {
|
|
8
10
|
getEnvironment: () => active?.getEnvironment() ?? initial,
|
|
11
|
+
getChrome: () => active?.getChrome() ?? INITIAL_CHROME,
|
|
12
|
+
subscribeChrome(listener) { chromeListeners.add(listener); return () => { chromeListeners.delete(listener); }; },
|
|
13
|
+
getNavigation: () => active?.getNavigation() ?? INITIAL_NAVIGATION,
|
|
14
|
+
subscribeNavigation(listener) { navigationListeners.add(listener); return () => { navigationListeners.delete(listener); }; },
|
|
15
|
+
navigate: (key, options) => active?.navigate(key, options) ?? Promise.resolve({ status: "unsupported", requestId: options.requestId, code: "host_unavailable" }),
|
|
16
|
+
openToolPicker: options => active?.openToolPicker(options) ?? Promise.resolve({ status: "unsupported", requestId: options.requestId, code: "host_unavailable" }),
|
|
9
17
|
openSurface: (target, options) => active?.openSurface(target, options) ?? Promise.resolve(unavailable(options.requestId)),
|
|
10
18
|
getPresentation: (id, options) => active?.getPresentation(id, options) ?? Promise.resolve(unavailable(id)),
|
|
11
19
|
subscribe(listener) { listeners.add(listener); listener({ type: "environment", value: ui.getEnvironment() }); return () => { listeners.delete(listener); }; },
|
|
@@ -16,12 +24,26 @@ export function bindUiClient(client) {
|
|
|
16
24
|
if (active && active !== client)
|
|
17
25
|
throw new Error("Mount one Hosty UI root per document.");
|
|
18
26
|
active = client;
|
|
27
|
+
const releaseChrome = client.subscribeChrome(() => { for (const l of chromeListeners)
|
|
28
|
+
l(); });
|
|
29
|
+
const releaseNavigation = client.subscribeNavigation(() => { for (const l of navigationListeners)
|
|
30
|
+
l(); });
|
|
31
|
+
for (const l of chromeListeners)
|
|
32
|
+
l();
|
|
33
|
+
for (const l of navigationListeners)
|
|
34
|
+
l();
|
|
19
35
|
const release = client.subscribe(event => { for (const listener of listeners)
|
|
20
36
|
listener(event); });
|
|
21
37
|
return () => {
|
|
22
38
|
release();
|
|
39
|
+
releaseChrome();
|
|
40
|
+
releaseNavigation();
|
|
23
41
|
if (active === client) {
|
|
24
42
|
active = null;
|
|
43
|
+
for (const listener of chromeListeners)
|
|
44
|
+
listener();
|
|
45
|
+
for (const listener of navigationListeners)
|
|
46
|
+
listener();
|
|
25
47
|
for (const listener of listeners)
|
|
26
48
|
listener({ type: "environment", value: initial });
|
|
27
49
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hosty-sdk/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.22",
|
|
4
4
|
"description": "Hosty app auth: session state machine, recovery bridge, Core revalidation, and the embedder responder.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"type": "module",
|
|
@@ -116,6 +116,10 @@
|
|
|
116
116
|
"./continuity/browser": {
|
|
117
117
|
"types": "./dist/continuity-browser.d.ts",
|
|
118
118
|
"default": "./dist/continuity-browser.js"
|
|
119
|
+
},
|
|
120
|
+
"./next": {
|
|
121
|
+
"types": "./dist/next.d.ts",
|
|
122
|
+
"default": "./dist/next.js"
|
|
119
123
|
}
|
|
120
124
|
},
|
|
121
125
|
"scripts": {
|