@devframes/hub 0.5.1 → 0.5.2
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/index.d.mts +174 -0
- package/dist/client/index.mjs +98 -0
- package/dist/constants.d.mts +8 -0
- package/dist/constants.mjs +21 -0
- package/dist/context-BGXfnFEd.d.mts +399 -0
- package/dist/define-tHP6fX6A.mjs +14 -0
- package/dist/index-BWTfvdqa.d.mts +3 -0
- package/dist/index.d.mts +17 -0
- package/dist/index.mjs +2 -0
- package/dist/node/index.d.mts +164 -0
- package/dist/node/index.mjs +6130 -0
- package/dist/settings-Bp5Ax6Os.d.mts +131 -0
- package/dist/types/index.d.mts +4 -0
- package/dist/types/index.mjs +0 -0
- package/package.json +3 -3
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { L as DevframeMessagesClient, T as RemoteConnectionInfo, d as DevframeDockEntriesGrouped, f as DevframeDockEntry, g as DevframeDockUserEntry } from "../context-BGXfnFEd.mjs";
|
|
2
|
+
import { i as DevframeCommandEntry, n as DevframeClientCommand, o as DevframeCommandKeybinding, t as DevframeDocksUserSettings } from "../settings-Bp5Ax6Os.mjs";
|
|
3
|
+
import { DevframeClientRpcHost, DevframeRpcClient, DevframeRpcClientOptions, DevframeRpcContext, RpcClientEvents } from "devframe/client";
|
|
4
|
+
import { EventEmitter } from "devframe/types";
|
|
5
|
+
import { SharedState } from "devframe/utils/shared-state";
|
|
6
|
+
import { WhenContext } from "devframe/utils/when";
|
|
7
|
+
export * from "devframe/client";
|
|
8
|
+
|
|
9
|
+
//#region src/client/docks.d.ts
|
|
10
|
+
interface DockPanelStorage {
|
|
11
|
+
mode: 'float' | 'edge';
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
top: number;
|
|
15
|
+
left: number;
|
|
16
|
+
position: 'left' | 'right' | 'bottom' | 'top';
|
|
17
|
+
open: boolean;
|
|
18
|
+
inactiveTimeout: number;
|
|
19
|
+
}
|
|
20
|
+
type DockClientType = 'embedded' | 'standalone';
|
|
21
|
+
interface DocksContext extends DevframeRpcContext {
|
|
22
|
+
/**
|
|
23
|
+
* Type of the client environment
|
|
24
|
+
*
|
|
25
|
+
* 'embedded' - running inside an embedded floating panel
|
|
26
|
+
* 'standalone' - running inside a standalone window (no user app)
|
|
27
|
+
*/
|
|
28
|
+
readonly clientType: 'embedded' | 'standalone';
|
|
29
|
+
/**
|
|
30
|
+
* The panel context
|
|
31
|
+
*/
|
|
32
|
+
readonly panel: DocksPanelContext;
|
|
33
|
+
/**
|
|
34
|
+
* The docks entries context
|
|
35
|
+
*/
|
|
36
|
+
readonly docks: DocksEntriesContext;
|
|
37
|
+
/**
|
|
38
|
+
* The commands context for command palette and shortcuts
|
|
39
|
+
*/
|
|
40
|
+
readonly commands: CommandsContext;
|
|
41
|
+
/**
|
|
42
|
+
* The when-clause context for conditional visibility
|
|
43
|
+
*/
|
|
44
|
+
readonly when: WhenClauseContext;
|
|
45
|
+
}
|
|
46
|
+
interface WhenClauseContext {
|
|
47
|
+
/**
|
|
48
|
+
* Get the current when-clause context snapshot.
|
|
49
|
+
* Returns a reactive object with built-in variables and any custom plugin variables.
|
|
50
|
+
*/
|
|
51
|
+
readonly context: WhenContext;
|
|
52
|
+
}
|
|
53
|
+
type DevframeClientContext = DocksContext;
|
|
54
|
+
interface DocksPanelContext {
|
|
55
|
+
store: DockPanelStorage;
|
|
56
|
+
isDragging: boolean;
|
|
57
|
+
isResizing: boolean;
|
|
58
|
+
readonly isVertical: boolean;
|
|
59
|
+
}
|
|
60
|
+
interface DocksEntriesContext {
|
|
61
|
+
selectedId: string | null;
|
|
62
|
+
readonly selected: DevframeDockEntry | null;
|
|
63
|
+
entries: DevframeDockEntry[];
|
|
64
|
+
entryToStateMap: Map<string, DockEntryState>;
|
|
65
|
+
groupedEntries: DevframeDockEntriesGrouped;
|
|
66
|
+
settings: SharedState<DevframeDocksUserSettings>;
|
|
67
|
+
/**
|
|
68
|
+
* Get the state of a dock entry by its ID
|
|
69
|
+
*/
|
|
70
|
+
getStateById: (id: string) => DockEntryState | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Switch to the selected dock entry, pass `null` to clear the selection
|
|
73
|
+
*
|
|
74
|
+
* @returns Whether the selection was changed successfully
|
|
75
|
+
*/
|
|
76
|
+
switchEntry: (id?: string | null) => Promise<boolean>;
|
|
77
|
+
/**
|
|
78
|
+
* Toggle the selected dock entry
|
|
79
|
+
*
|
|
80
|
+
* @returns Whether the selection was changed successfully
|
|
81
|
+
*/
|
|
82
|
+
toggleEntry: (id: string) => Promise<boolean>;
|
|
83
|
+
}
|
|
84
|
+
interface DockEntryState {
|
|
85
|
+
entryMeta: DevframeDockEntry;
|
|
86
|
+
readonly isActive: boolean;
|
|
87
|
+
domElements: {
|
|
88
|
+
iframe?: HTMLIFrameElement | null;
|
|
89
|
+
panel?: HTMLDivElement | null;
|
|
90
|
+
};
|
|
91
|
+
events: EventEmitter<DockEntryStateEvents>;
|
|
92
|
+
}
|
|
93
|
+
interface DockEntryStateEvents {
|
|
94
|
+
'entry:activated': () => void;
|
|
95
|
+
'entry:deactivated': () => void;
|
|
96
|
+
'entry:updated': (newMeta: DevframeDockUserEntry) => void;
|
|
97
|
+
'dom:panel:mounted': (panel: HTMLDivElement) => void;
|
|
98
|
+
'dom:iframe:mounted': (iframe: HTMLIFrameElement) => void;
|
|
99
|
+
}
|
|
100
|
+
interface CommandsContext {
|
|
101
|
+
/**
|
|
102
|
+
* All commands (server + client)
|
|
103
|
+
*/
|
|
104
|
+
readonly commands: DevframeCommandEntry[];
|
|
105
|
+
/**
|
|
106
|
+
* Palette-visible commands only (filtered by `showInPalette !== false`)
|
|
107
|
+
*/
|
|
108
|
+
readonly paletteCommands: DevframeCommandEntry[];
|
|
109
|
+
/**
|
|
110
|
+
* Register client-side command(s). Returns cleanup function.
|
|
111
|
+
*/
|
|
112
|
+
register: (cmd: DevframeClientCommand | DevframeClientCommand[]) => () => void;
|
|
113
|
+
/**
|
|
114
|
+
* Execute a command by ID. Delegates to RPC for server commands.
|
|
115
|
+
*/
|
|
116
|
+
execute: (id: string, ...args: any[]) => Promise<unknown>;
|
|
117
|
+
/**
|
|
118
|
+
* Get effective keybindings for a command (defaults merged with overrides)
|
|
119
|
+
*/
|
|
120
|
+
getKeybindings: (id: string) => DevframeCommandKeybinding[];
|
|
121
|
+
/**
|
|
122
|
+
* User settings store (persisted, includes command shortcuts)
|
|
123
|
+
*/
|
|
124
|
+
settings: SharedState<DevframeDocksUserSettings>;
|
|
125
|
+
/**
|
|
126
|
+
* Whether the command palette is open
|
|
127
|
+
*/
|
|
128
|
+
paletteOpen: boolean;
|
|
129
|
+
}
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/client/client-script.d.ts
|
|
132
|
+
/**
|
|
133
|
+
* Context for client scripts running in dock entries
|
|
134
|
+
*/
|
|
135
|
+
interface DockClientScriptContext extends DocksContext {
|
|
136
|
+
/**
|
|
137
|
+
* The state of the current dock entry
|
|
138
|
+
*/
|
|
139
|
+
current: DockEntryState;
|
|
140
|
+
/**
|
|
141
|
+
* Messages client scoped to this dock entry's source
|
|
142
|
+
*/
|
|
143
|
+
messages: DevframeMessagesClient;
|
|
144
|
+
}
|
|
145
|
+
//#endregion
|
|
146
|
+
//#region src/client/context.d.ts
|
|
147
|
+
declare const CLIENT_CONTEXT_KEY = "__DEVFRAME_HUB_CLIENT_CONTEXT__";
|
|
148
|
+
/**
|
|
149
|
+
* Get the global Devframe client context, or `undefined` if not yet initialized.
|
|
150
|
+
*/
|
|
151
|
+
declare function getDevframeClientContext(): DevframeClientContext | undefined;
|
|
152
|
+
//#endregion
|
|
153
|
+
//#region src/client/remote.d.ts
|
|
154
|
+
type ConnectRemoteDevframeOptions = Omit<DevframeRpcClientOptions, 'connectionMeta' | 'authToken'>;
|
|
155
|
+
/**
|
|
156
|
+
* Parse a {@link RemoteConnectionInfo} descriptor from the current page's URL
|
|
157
|
+
* (or a provided URL/string). Checks the URL fragment first, then the query.
|
|
158
|
+
*
|
|
159
|
+
* Returns `null` if no descriptor is present.
|
|
160
|
+
* Throws if the descriptor is malformed or its schema version is unsupported.
|
|
161
|
+
*/
|
|
162
|
+
declare function parseRemoteConnection(input?: string): RemoteConnectionInfo | null;
|
|
163
|
+
/**
|
|
164
|
+
* One-liner for a hosted Devframe page: reads the connection descriptor from
|
|
165
|
+
* the current URL and returns a connected {@link DevframeRpcClient}.
|
|
166
|
+
*
|
|
167
|
+
* Pairs with `remote: true` on a `DevframeViewIframe` registered on the node
|
|
168
|
+
* side — the hub injects the descriptor into the iframe URL.
|
|
169
|
+
*
|
|
170
|
+
* @throws if no descriptor is present in the URL.
|
|
171
|
+
*/
|
|
172
|
+
declare function connectRemoteDevframe(options?: ConnectRemoteDevframeOptions): Promise<DevframeRpcClient>;
|
|
173
|
+
//#endregion
|
|
174
|
+
export { CLIENT_CONTEXT_KEY, CommandsContext, ConnectRemoteDevframeOptions, DevframeClientContext, type DevframeClientRpcHost, DockClientScriptContext, DockClientType, DockEntryState, DockEntryStateEvents, DockPanelStorage, DocksContext, DocksEntriesContext, DocksPanelContext, type RpcClientEvents, WhenClauseContext, connectRemoteDevframe, getDevframeClientContext, parseRemoteConnection };
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { REMOTE_CONNECTION_KEY } from "devframe/constants";
|
|
2
|
+
import { getDevframeRpcClient } from "devframe/client";
|
|
3
|
+
export * from "devframe/client";
|
|
4
|
+
//#region src/client/context.ts
|
|
5
|
+
const CLIENT_CONTEXT_KEY = "__DEVFRAME_HUB_CLIENT_CONTEXT__";
|
|
6
|
+
/**
|
|
7
|
+
* Get the global Devframe client context, or `undefined` if not yet initialized.
|
|
8
|
+
*/
|
|
9
|
+
function getDevframeClientContext() {
|
|
10
|
+
return globalThis[CLIENT_CONTEXT_KEY];
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/client/remote.ts
|
|
14
|
+
function base64UrlDecode(value) {
|
|
15
|
+
const padLen = (4 - value.length % 4) % 4;
|
|
16
|
+
const padded = value.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat(padLen);
|
|
17
|
+
const binary = atob(padded);
|
|
18
|
+
const bytes = new Uint8Array(binary.length);
|
|
19
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
20
|
+
return new TextDecoder().decode(bytes);
|
|
21
|
+
}
|
|
22
|
+
function extractKeyFromFragment(hash) {
|
|
23
|
+
if (!hash) return null;
|
|
24
|
+
const raw = hash.startsWith("#") ? hash.slice(1) : hash;
|
|
25
|
+
const queryIdx = raw.indexOf("?");
|
|
26
|
+
if (queryIdx !== -1) {
|
|
27
|
+
const value = new URLSearchParams(raw.slice(queryIdx + 1)).get(REMOTE_CONNECTION_KEY);
|
|
28
|
+
if (value) return value;
|
|
29
|
+
}
|
|
30
|
+
for (const part of raw.split("&")) {
|
|
31
|
+
const [k, v = ""] = part.split("=");
|
|
32
|
+
if (k === REMOTE_CONNECTION_KEY) return decodeURIComponent(v);
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
function extractKeyFromQuery(search) {
|
|
37
|
+
if (!search) return null;
|
|
38
|
+
return new URLSearchParams(search.startsWith("?") ? search.slice(1) : search).get(REMOTE_CONNECTION_KEY);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse a {@link RemoteConnectionInfo} descriptor from the current page's URL
|
|
42
|
+
* (or a provided URL/string). Checks the URL fragment first, then the query.
|
|
43
|
+
*
|
|
44
|
+
* Returns `null` if no descriptor is present.
|
|
45
|
+
* Throws if the descriptor is malformed or its schema version is unsupported.
|
|
46
|
+
*/
|
|
47
|
+
function parseRemoteConnection(input) {
|
|
48
|
+
let hash = "";
|
|
49
|
+
let search = "";
|
|
50
|
+
if (input === void 0) {
|
|
51
|
+
if (typeof location === "undefined") return null;
|
|
52
|
+
hash = location.hash;
|
|
53
|
+
search = location.search;
|
|
54
|
+
} else try {
|
|
55
|
+
const parsed = new URL(input, "http://_");
|
|
56
|
+
hash = parsed.hash;
|
|
57
|
+
search = parsed.search;
|
|
58
|
+
} catch {
|
|
59
|
+
if (input.startsWith("#")) hash = input;
|
|
60
|
+
else if (input.startsWith("?")) search = input;
|
|
61
|
+
else return null;
|
|
62
|
+
}
|
|
63
|
+
const encoded = extractKeyFromFragment(hash) ?? extractKeyFromQuery(search);
|
|
64
|
+
if (!encoded) return null;
|
|
65
|
+
let payload;
|
|
66
|
+
try {
|
|
67
|
+
payload = JSON.parse(base64UrlDecode(encoded));
|
|
68
|
+
} catch (cause) {
|
|
69
|
+
throw new Error("[@devframes/hub] Failed to decode remote connection descriptor.", { cause });
|
|
70
|
+
}
|
|
71
|
+
if (!payload || typeof payload !== "object") throw new Error("[@devframes/hub] Remote connection descriptor must be an object.");
|
|
72
|
+
const info = payload;
|
|
73
|
+
if (info.v !== 1) throw new Error(`[@devframes/hub] Unsupported remote connection descriptor version: ${String(info.v)}`);
|
|
74
|
+
if (info.backend !== "websocket" || typeof info.websocket !== "string" || !info.websocket) throw new Error("[@devframes/hub] Remote connection descriptor must carry a websocket URL.");
|
|
75
|
+
if (typeof info.authToken !== "string" || !info.authToken) throw new Error("[@devframes/hub] Remote connection descriptor must carry an auth token.");
|
|
76
|
+
if (typeof info.origin !== "string") throw new Error("[@devframes/hub] Remote connection descriptor must carry an origin.");
|
|
77
|
+
return info;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* One-liner for a hosted Devframe page: reads the connection descriptor from
|
|
81
|
+
* the current URL and returns a connected {@link DevframeRpcClient}.
|
|
82
|
+
*
|
|
83
|
+
* Pairs with `remote: true` on a `DevframeViewIframe` registered on the node
|
|
84
|
+
* side — the hub injects the descriptor into the iframe URL.
|
|
85
|
+
*
|
|
86
|
+
* @throws if no descriptor is present in the URL.
|
|
87
|
+
*/
|
|
88
|
+
async function connectRemoteDevframe(options = {}) {
|
|
89
|
+
const info = parseRemoteConnection();
|
|
90
|
+
if (!info) throw new Error("[@devframes/hub] No remote connection descriptor found in the URL. Open this page through a hub-registered dock with `remote: true`.");
|
|
91
|
+
return getDevframeRpcClient({
|
|
92
|
+
...options,
|
|
93
|
+
connectionMeta: info,
|
|
94
|
+
authToken: info.authToken
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
export { CLIENT_CONTEXT_KEY, connectRemoteDevframe, getDevframeClientContext, parseRemoteConnection };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { t as DevframeDocksUserSettings } from "./settings-Bp5Ax6Os.mjs";
|
|
2
|
+
export * from "devframe/constants";
|
|
3
|
+
|
|
4
|
+
//#region src/constants.d.ts
|
|
5
|
+
declare const DEFAULT_CATEGORIES_ORDER: Record<string, number>;
|
|
6
|
+
declare const DEFAULT_STATE_USER_SETTINGS: () => DevframeDocksUserSettings;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { DEFAULT_CATEGORIES_ORDER, DEFAULT_STATE_USER_SETTINGS };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export * from "devframe/constants";
|
|
2
|
+
//#region src/constants.ts
|
|
3
|
+
const DEFAULT_CATEGORIES_ORDER = {
|
|
4
|
+
"default": 0,
|
|
5
|
+
"app": 100,
|
|
6
|
+
"framework": 200,
|
|
7
|
+
"web": 300,
|
|
8
|
+
"advanced": 400,
|
|
9
|
+
"~builtin": 1e3
|
|
10
|
+
};
|
|
11
|
+
const DEFAULT_STATE_USER_SETTINGS = () => ({
|
|
12
|
+
docksHidden: [],
|
|
13
|
+
docksCategoriesHidden: [],
|
|
14
|
+
docksPinned: [],
|
|
15
|
+
docksCustomOrder: {},
|
|
16
|
+
showIframeAddressBar: false,
|
|
17
|
+
closeOnOutsideClick: false,
|
|
18
|
+
commandShortcuts: {}
|
|
19
|
+
});
|
|
20
|
+
//#endregion
|
|
21
|
+
export { DEFAULT_CATEGORIES_ORDER, DEFAULT_STATE_USER_SETTINGS };
|