@devframes/hub 0.5.0 → 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.
@@ -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 };