devframe 0.1.19 → 0.1.21
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 +2 -2
- package/dist/{_shared-BcPXmcjq.mjs → _shared-iZy45oG3.mjs} +2 -2
- package/dist/adapters/build.d.mts +3 -3
- package/dist/adapters/build.mjs +12 -9
- package/dist/adapters/cli.d.mts +1 -1
- package/dist/adapters/cli.mjs +2 -2
- package/dist/adapters/dev.d.mts +2 -2
- package/dist/adapters/dev.mjs +1 -1
- package/dist/adapters/embedded.d.mts +2 -2
- package/dist/adapters/embedded.mjs +1 -1
- package/dist/adapters/mcp.d.mts +1 -1
- package/dist/adapters/mcp.mjs +6 -2
- package/dist/adapters/vite.d.mts +5 -4
- package/dist/adapters/vite.mjs +4 -3
- package/dist/client/index.d.mts +51 -145
- package/dist/client/index.mjs +1664 -2
- package/dist/constants.d.mts +12 -15
- package/dist/constants.mjs +12 -29
- package/dist/context-BJ4r2SmR.mjs +1051 -0
- package/dist/context-internal-Dx_NoSv1.mjs +199 -0
- package/dist/context-internal-saIAfNVw.d.mts +51 -0
- package/dist/{dev-Djy5hbgs.mjs → dev-CdAy400a.mjs} +7 -6
- package/dist/{devtool-CIqONpYU.d.mts → devtool-CNvLs2_Y.d.mts} +367 -530
- package/dist/diagnostics-DxPnRoXO.mjs +51 -0
- package/dist/host-h3-9jeHcltx.mjs +24 -0
- package/dist/{human-id-CHS0s28X.mjs → human-id-BLoGo_e5.mjs} +0 -1
- package/dist/{index-BwrLhNmz.d.mts → index-CuLRIMto.d.mts} +1 -1
- package/dist/index.d.mts +4 -5
- package/dist/index.mjs +1 -4
- package/dist/internal/index.d.mts +16 -0
- package/dist/internal/index.mjs +3 -0
- package/dist/node/index.d.mts +45 -140
- package/dist/node/index.mjs +7 -6
- package/dist/recipes/open-helpers.d.mts +1 -1
- package/dist/recipes/open-helpers.mjs +3 -1
- package/dist/rpc/index.d.mts +2 -2
- package/dist/rpc/index.mjs +2 -2
- package/dist/rpc/transports/ws-client.d.mts +1 -1
- package/dist/rpc/transports/ws-client.mjs +1 -1
- package/dist/rpc/transports/ws-server.d.mts +1 -1
- package/dist/rpc/transports/ws-server.mjs +1 -1
- package/dist/{rpc-D7LxIh8t.mjs → rpc-INbWfHoX.mjs} +1 -1
- package/dist/{serialization-BN2ZQEE9.mjs → serialization-DwKi05Pn.mjs} +1 -1
- package/dist/{server-CaUeMcAh.d.mts → server-BAqOajx_.d.mts} +1 -1
- package/dist/{server-DrBxa6ZV.mjs → server-CBsxXIH5.mjs} +27 -2
- package/dist/{static-dump-cyGfMmRf.mjs → static-dump-D5VH8Iqk.mjs} +1 -1
- package/dist/types/index.d.mts +4 -4
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/human-id.mjs +1 -1
- package/dist/utils/shared-state.d.mts +2 -2
- package/dist/utils/shared-state.mjs +1 -1
- package/dist/utils/state.d.mts +2 -1
- package/dist/utils/state.mjs +1 -1
- package/dist/utils/streaming-channel.d.mts +2 -0
- package/dist/utils/streaming-channel.mjs +255 -0
- package/dist/utils/when.d.mts +401 -2
- package/dist/{ws-client-DOYwYluO.d.mts → ws-client-CjPuPFbA.d.mts} +1 -1
- package/dist/{ws-server-DHMeNOY_.d.mts → ws-server-C7LnhOHi.d.mts} +13 -1
- package/package.json +10 -21
- package/skills/devframe/README.md +13 -0
- package/skills/devframe/SKILL.md +406 -0
- package/skills/devframe/templates/counter-devtool.ts +24 -0
- package/skills/devframe/templates/spa-devtool.ts +28 -0
- package/skills/devframe/templates/vite-client.ts +11 -0
- package/dist/adapters/kit.d.mts +0 -23
- package/dist/adapters/kit.mjs +0 -16
- package/dist/client-C6w_NshP.mjs +0 -1569
- package/dist/context-BsNZMCnr.mjs +0 -6827
- package/dist/helpers/nuxt/index.d.mts +0 -46
- package/dist/helpers/nuxt/index.mjs +0 -58
- package/dist/helpers/nuxt/runtime/plugin.client.d.mts +0 -8
- package/dist/helpers/nuxt/runtime/plugin.client.mjs +0 -12
- package/dist/host-h3-w3c0t8ZO.mjs +0 -18
- package/dist/immer-HjMAm3b6.mjs +0 -894
- package/dist/main-CuGOfqoX.mjs +0 -601
- package/dist/when-BAE663Hv.d.mts +0 -401
- package/dist/{open-JfacLHs0.mjs → open-Dede_w9r.mjs} +4 -4
- /package/dist/{types-gWbe-b2R.d.mts → types-C5OVe4AC.d.mts} +0 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { t as import_dist } from "./human-id-BLoGo_e5.mjs";
|
|
2
|
+
import { n as logger } from "./diagnostics-DxPnRoXO.mjs";
|
|
3
|
+
import { createSharedState } from "./utils/shared-state.mjs";
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import { dirname, join } from "pathe";
|
|
6
|
+
//#region src/node/auth-revoke.ts
|
|
7
|
+
/**
|
|
8
|
+
* Flip `isTrusted` to false on any live WS clients connected with `token`
|
|
9
|
+
* and broadcast the `auth:revoked` event so they can react.
|
|
10
|
+
*
|
|
11
|
+
* Shared between persisted-auth revocation and remote-dock token revocation.
|
|
12
|
+
*/
|
|
13
|
+
async function revokeActiveConnectionsForToken(context, token) {
|
|
14
|
+
const rpcHost = context.rpc;
|
|
15
|
+
if (!rpcHost?._rpcGroup) return;
|
|
16
|
+
const affectedSessionIds = /* @__PURE__ */ new Set();
|
|
17
|
+
for (const client of rpcHost._rpcGroup.clients) if (client.$meta.clientAuthToken === token) {
|
|
18
|
+
affectedSessionIds.add(client.$meta.id);
|
|
19
|
+
client.$meta.isTrusted = false;
|
|
20
|
+
client.$meta.clientAuthToken = void 0;
|
|
21
|
+
}
|
|
22
|
+
if (affectedSessionIds.size === 0) return;
|
|
23
|
+
await rpcHost.broadcast({
|
|
24
|
+
method: "devframe:auth:revoked",
|
|
25
|
+
args: [],
|
|
26
|
+
filter: (client) => affectedSessionIds.has(client.$meta.id)
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Revoke an auth token: remove from storage and notify all connected clients
|
|
31
|
+
* using this token that they are no longer trusted.
|
|
32
|
+
*/
|
|
33
|
+
async function revokeAuthToken(context, storage, token) {
|
|
34
|
+
storage.mutate((state) => {
|
|
35
|
+
delete state.trusted[token];
|
|
36
|
+
});
|
|
37
|
+
await revokeActiveConnectionsForToken(context, token);
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region ../../../node_modules/.pnpm/perfect-debounce@2.1.0/node_modules/perfect-debounce/dist/index.mjs
|
|
41
|
+
const DEBOUNCE_DEFAULTS = { trailing: true };
|
|
42
|
+
/**
|
|
43
|
+
Debounce functions
|
|
44
|
+
@param fn - Promise-returning/async function to debounce.
|
|
45
|
+
@param wait - Milliseconds to wait before calling `fn`. Default value is 25ms
|
|
46
|
+
@returns A function that delays calling `fn` until after `wait` milliseconds have elapsed since the last time it was called.
|
|
47
|
+
@example
|
|
48
|
+
```
|
|
49
|
+
import { debounce } from 'perfect-debounce';
|
|
50
|
+
const expensiveCall = async input => input;
|
|
51
|
+
const debouncedFn = debounce(expensiveCall, 200);
|
|
52
|
+
for (const number of [1, 2, 3]) {
|
|
53
|
+
console.log(await debouncedFn(number));
|
|
54
|
+
}
|
|
55
|
+
//=> 1
|
|
56
|
+
//=> 2
|
|
57
|
+
//=> 3
|
|
58
|
+
```
|
|
59
|
+
*/
|
|
60
|
+
function debounce(fn, wait = 25, options = {}) {
|
|
61
|
+
options = {
|
|
62
|
+
...DEBOUNCE_DEFAULTS,
|
|
63
|
+
...options
|
|
64
|
+
};
|
|
65
|
+
if (!Number.isFinite(wait)) throw new TypeError("Expected `wait` to be a finite number");
|
|
66
|
+
let leadingValue;
|
|
67
|
+
let timeout;
|
|
68
|
+
let resolveList = [];
|
|
69
|
+
let currentPromise;
|
|
70
|
+
let trailingArgs;
|
|
71
|
+
const applyFn = (_this, args) => {
|
|
72
|
+
currentPromise = _applyPromised(fn, _this, args);
|
|
73
|
+
currentPromise.finally(() => {
|
|
74
|
+
currentPromise = null;
|
|
75
|
+
if (options.trailing && trailingArgs && !timeout) {
|
|
76
|
+
const promise = applyFn(_this, trailingArgs);
|
|
77
|
+
trailingArgs = null;
|
|
78
|
+
return promise;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return currentPromise;
|
|
82
|
+
};
|
|
83
|
+
const debounced = function(...args) {
|
|
84
|
+
if (options.trailing) trailingArgs = args;
|
|
85
|
+
if (currentPromise) return currentPromise;
|
|
86
|
+
return new Promise((resolve) => {
|
|
87
|
+
const shouldCallNow = !timeout && options.leading;
|
|
88
|
+
clearTimeout(timeout);
|
|
89
|
+
timeout = setTimeout(() => {
|
|
90
|
+
timeout = null;
|
|
91
|
+
const promise = options.leading ? leadingValue : applyFn(this, args);
|
|
92
|
+
trailingArgs = null;
|
|
93
|
+
for (const _resolve of resolveList) _resolve(promise);
|
|
94
|
+
resolveList = [];
|
|
95
|
+
}, wait);
|
|
96
|
+
if (shouldCallNow) {
|
|
97
|
+
leadingValue = applyFn(this, args);
|
|
98
|
+
resolve(leadingValue);
|
|
99
|
+
} else resolveList.push(resolve);
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
const _clearTimeout = (timer) => {
|
|
103
|
+
if (timer) {
|
|
104
|
+
clearTimeout(timer);
|
|
105
|
+
timeout = null;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
debounced.isPending = () => !!timeout;
|
|
109
|
+
debounced.cancel = () => {
|
|
110
|
+
_clearTimeout(timeout);
|
|
111
|
+
resolveList = [];
|
|
112
|
+
trailingArgs = null;
|
|
113
|
+
};
|
|
114
|
+
debounced.flush = () => {
|
|
115
|
+
_clearTimeout(timeout);
|
|
116
|
+
if (!trailingArgs || currentPromise) return;
|
|
117
|
+
const args = trailingArgs;
|
|
118
|
+
trailingArgs = null;
|
|
119
|
+
return applyFn(this, args);
|
|
120
|
+
};
|
|
121
|
+
return debounced;
|
|
122
|
+
}
|
|
123
|
+
async function _applyPromised(fn, _this, args) {
|
|
124
|
+
return await fn.apply(_this, args);
|
|
125
|
+
}
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region src/node/storage.ts
|
|
128
|
+
function createStorage(options) {
|
|
129
|
+
const { mergeInitialValue = (initialValue, savedValue) => ({
|
|
130
|
+
...initialValue,
|
|
131
|
+
...savedValue
|
|
132
|
+
}), debounce: debounceTime = 100 } = options;
|
|
133
|
+
let initialValue = options.initialValue;
|
|
134
|
+
if (fs.existsSync(options.filepath)) try {
|
|
135
|
+
const savedValue = JSON.parse(fs.readFileSync(options.filepath, "utf-8"));
|
|
136
|
+
initialValue = mergeInitialValue ? mergeInitialValue(options.initialValue, savedValue) : savedValue;
|
|
137
|
+
} catch (error) {
|
|
138
|
+
logger.DF0012({ filepath: options.filepath }, { cause: error }).log();
|
|
139
|
+
initialValue = options.initialValue;
|
|
140
|
+
}
|
|
141
|
+
const state = createSharedState({
|
|
142
|
+
initialValue,
|
|
143
|
+
enablePatches: false
|
|
144
|
+
});
|
|
145
|
+
state.on("updated", debounce((newState) => {
|
|
146
|
+
fs.mkdirSync(dirname(options.filepath), { recursive: true });
|
|
147
|
+
fs.writeFileSync(options.filepath, `${JSON.stringify(newState, null, 2)}\n`);
|
|
148
|
+
}, debounceTime));
|
|
149
|
+
return state;
|
|
150
|
+
}
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/node/context-internal.ts
|
|
153
|
+
const internalContextMap = /* @__PURE__ */ new WeakMap();
|
|
154
|
+
function getInternalContext(context) {
|
|
155
|
+
if (!internalContextMap.has(context)) {
|
|
156
|
+
const storage = createStorage({
|
|
157
|
+
filepath: join(context.host.getStorageDir("global"), "auth.json"),
|
|
158
|
+
initialValue: { trusted: {} }
|
|
159
|
+
});
|
|
160
|
+
const remoteTokens = /* @__PURE__ */ new Map();
|
|
161
|
+
function revokeRemoteToken(token) {
|
|
162
|
+
if (!remoteTokens.delete(token)) return;
|
|
163
|
+
revokeActiveConnectionsForToken(context, token);
|
|
164
|
+
}
|
|
165
|
+
const internalContext = {
|
|
166
|
+
storage: { auth: storage },
|
|
167
|
+
revokeAuthToken: (token) => revokeAuthToken(context, storage, token),
|
|
168
|
+
remoteTokens,
|
|
169
|
+
allocateRemoteToken(dockId, origin, originLock) {
|
|
170
|
+
const token = (0, import_dist.humanId)({
|
|
171
|
+
separator: "-",
|
|
172
|
+
capitalize: false
|
|
173
|
+
});
|
|
174
|
+
remoteTokens.set(token, {
|
|
175
|
+
dockId,
|
|
176
|
+
origin,
|
|
177
|
+
originLock
|
|
178
|
+
});
|
|
179
|
+
return token;
|
|
180
|
+
},
|
|
181
|
+
revokeRemoteToken,
|
|
182
|
+
revokeRemoteTokensForDock(dockId) {
|
|
183
|
+
const tokensToRevoke = [];
|
|
184
|
+
for (const [token, record] of remoteTokens) if (record.dockId === dockId) tokensToRevoke.push(token);
|
|
185
|
+
for (const token of tokensToRevoke) revokeRemoteToken(token);
|
|
186
|
+
},
|
|
187
|
+
isRemoteTokenTrusted(token, requestOrigin) {
|
|
188
|
+
const record = remoteTokens.get(token);
|
|
189
|
+
if (!record) return false;
|
|
190
|
+
if (!record.originLock) return true;
|
|
191
|
+
return !!requestOrigin && record.origin === requestOrigin;
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
internalContextMap.set(context, internalContext);
|
|
195
|
+
}
|
|
196
|
+
return internalContextMap.get(context);
|
|
197
|
+
}
|
|
198
|
+
//#endregion
|
|
199
|
+
export { revokeAuthToken as a, revokeActiveConnectionsForToken as i, internalContextMap as n, createStorage as r, getInternalContext as t };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { P as SharedState, d as DevToolsNodeContext } from "./devtool-CNvLs2_Y.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/node/context-internal.d.ts
|
|
4
|
+
interface InternalAnonymousAuthStorage {
|
|
5
|
+
trusted: Record<string, {
|
|
6
|
+
authToken: string;
|
|
7
|
+
ua: string;
|
|
8
|
+
origin: string;
|
|
9
|
+
timestamp: number;
|
|
10
|
+
} | undefined>;
|
|
11
|
+
}
|
|
12
|
+
interface RemoteTokenRecord {
|
|
13
|
+
dockId: string;
|
|
14
|
+
/** Dock URL origin — matched against WS handshake `Origin` header when `originLock` is on. */
|
|
15
|
+
origin: string;
|
|
16
|
+
originLock: boolean;
|
|
17
|
+
}
|
|
18
|
+
interface DevToolsInternalContext {
|
|
19
|
+
storage: {
|
|
20
|
+
auth: SharedState<InternalAnonymousAuthStorage>;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Revoke an auth token: remove from storage and notify all connected clients
|
|
24
|
+
* using this token that they are no longer trusted.
|
|
25
|
+
*/
|
|
26
|
+
revokeAuthToken: (token: string) => Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Session-only tokens issued to remote-UI iframe docks. Not persisted —
|
|
29
|
+
* regenerated on every dev-server restart.
|
|
30
|
+
*/
|
|
31
|
+
remoteTokens: Map<string, RemoteTokenRecord>;
|
|
32
|
+
allocateRemoteToken: (dockId: string, origin: string, originLock: boolean) => string;
|
|
33
|
+
revokeRemoteToken: (token: string) => void;
|
|
34
|
+
revokeRemoteTokensForDock: (dockId: string) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Returns true if `token` is a valid remote token and, when `originLock` is
|
|
37
|
+
* on, `requestOrigin` matches the recorded dock origin.
|
|
38
|
+
*/
|
|
39
|
+
isRemoteTokenTrusted: (token: string, requestOrigin?: string) => boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Populated by `createWsServer` once the WS port is bound. Consumed by the
|
|
42
|
+
* docks host when enriching remote iframe URLs with a connection descriptor.
|
|
43
|
+
*/
|
|
44
|
+
wsEndpoint?: {
|
|
45
|
+
/** Full `ws://` or `wss://` URL with host and port. */url: string;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
declare const internalContextMap: WeakMap<DevToolsNodeContext, DevToolsInternalContext>;
|
|
49
|
+
declare function getInternalContext(context: DevToolsNodeContext): DevToolsInternalContext;
|
|
50
|
+
//#endregion
|
|
51
|
+
export { internalContextMap as a, getInternalContext as i, InternalAnonymousAuthStorage as n, RemoteTokenRecord as r, DevToolsInternalContext as t };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { t as createHostContext } from "./context-
|
|
1
|
+
import { t as createHostContext } from "./context-BJ4r2SmR.mjs";
|
|
2
|
+
import { t as createH3DevToolsHost } from "./host-h3-9jeHcltx.mjs";
|
|
3
|
+
import { t as startHttpAndWs } from "./server-CBsxXIH5.mjs";
|
|
2
4
|
import { DEVTOOLS_CONNECTION_META_FILENAME } from "./constants.mjs";
|
|
3
|
-
import { t as
|
|
4
|
-
import { t as startHttpAndWs } from "./server-DrBxa6ZV.mjs";
|
|
5
|
-
import { n as resolveBasePath, t as normalizeBasePath } from "./_shared-BcPXmcjq.mjs";
|
|
5
|
+
import { n as resolveBasePath, t as normalizeBasePath } from "./_shared-iZy45oG3.mjs";
|
|
6
6
|
import { resolve } from "pathe";
|
|
7
|
-
import process$1 from "node:process";
|
|
8
7
|
import { networkInterfaces } from "node:os";
|
|
8
|
+
import process$1 from "node:process";
|
|
9
9
|
import { createApp, eventHandler, fromNodeMiddleware } from "h3";
|
|
10
10
|
import { createServer } from "node:net";
|
|
11
11
|
import sirv from "sirv";
|
|
@@ -266,6 +266,7 @@ async function createDevServer(def, options = {}) {
|
|
|
266
266
|
const app = options.app ?? createApp();
|
|
267
267
|
const h3Host = createH3DevToolsHost({
|
|
268
268
|
origin: `http://${host}:${port}`,
|
|
269
|
+
appName: def.id,
|
|
269
270
|
mount: (base, dir) => {
|
|
270
271
|
app.use(base, fromNodeMiddleware(sirv(dir, {
|
|
271
272
|
dev: true,
|
|
@@ -311,7 +312,7 @@ async function maybeOpenBrowser(def, flags, origin, override) {
|
|
|
311
312
|
if (resolved === void 0 || resolved === false) return;
|
|
312
313
|
const target = typeof resolved === "string" ? resolveOpenTarget(origin, resolved) : origin;
|
|
313
314
|
try {
|
|
314
|
-
const { default: open } = await import("./open-
|
|
315
|
+
const { default: open } = await import("./open-Dede_w9r.mjs");
|
|
315
316
|
await open(target);
|
|
316
317
|
} catch {}
|
|
317
318
|
}
|