@weapp-sqlite/devtools 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +42 -2
- package/dist/client/assets/browser-agent-rpc-BXhoSh1z-B8VY0LVK.js +1 -0
- package/dist/client/assets/index-C4MpIW3V.css +1 -0
- package/dist/client/assets/index-qEaVRY93.js +6 -0
- package/dist/client/index.html +13 -0
- package/dist/client.cjs +76 -0
- package/dist/client.d.cts +14 -0
- package/dist/client.d.mts +14 -0
- package/dist/client.mjs +75 -0
- package/dist/index.cjs +451 -0
- package/dist/index.d.cts +64 -0
- package/dist/index.d.mts +64 -0
- package/dist/index.mjs +423 -0
- package/dist/protocol-BhfjLrSe.d.cts +76 -0
- package/dist/protocol-BhfjLrSe.d.mts +76 -0
- package/dist/protocol-Cl3y675u.cjs +299 -0
- package/dist/protocol-nkWp0_XO.mjs +216 -0
- package/dist/protocol.cjs +16 -0
- package/dist/protocol.d.cts +2 -0
- package/dist/protocol.d.mts +2 -0
- package/dist/protocol.mjs +2 -0
- package/dist/runtime.cjs +397 -0
- package/dist/runtime.d.cts +68 -0
- package/dist/runtime.d.mts +68 -0
- package/dist/runtime.mjs +394 -0
- package/package.json +90 -3
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
//#endregion
|
|
24
|
+
const require_protocol = require("./protocol-Cl3y675u.cjs");
|
|
25
|
+
const require_client = require("./client.cjs");
|
|
26
|
+
let node_fs = require("node:fs");
|
|
27
|
+
let node_path = require("node:path");
|
|
28
|
+
node_path = __toESM(node_path, 1);
|
|
29
|
+
let node_process = require("node:process");
|
|
30
|
+
node_process = __toESM(node_process, 1);
|
|
31
|
+
let node_url = require("node:url");
|
|
32
|
+
let _vitejs_devtools = require("@vitejs/devtools");
|
|
33
|
+
let _vitejs_devtools_kit_node = require("@vitejs/devtools-kit/node");
|
|
34
|
+
let devframe = require("devframe");
|
|
35
|
+
let devframe_node_auth = require("devframe/node/auth");
|
|
36
|
+
let vite = require("vite");
|
|
37
|
+
let node_buffer = require("node:buffer");
|
|
38
|
+
let node_crypto = require("node:crypto");
|
|
39
|
+
let ws = require("ws");
|
|
40
|
+
//#region src/broker.ts
|
|
41
|
+
const RUNTIME_PATH = "/__weapp-sqlite/runtime";
|
|
42
|
+
function errorResult(code, message) {
|
|
43
|
+
return {
|
|
44
|
+
ok: false,
|
|
45
|
+
error: {
|
|
46
|
+
code,
|
|
47
|
+
message
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function validOrigin(origin) {
|
|
52
|
+
if (!origin) return true;
|
|
53
|
+
try {
|
|
54
|
+
const url = new URL(origin);
|
|
55
|
+
return [
|
|
56
|
+
"localhost",
|
|
57
|
+
"127.0.0.1",
|
|
58
|
+
"[::1]"
|
|
59
|
+
].includes(url.hostname) || url.protocol === "https:" && url.hostname === "servicewechat.com";
|
|
60
|
+
} catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function validOwnerId(value) {
|
|
65
|
+
return value === void 0 || require_protocol.isIdentifier(value);
|
|
66
|
+
}
|
|
67
|
+
/** broker 只路由到拥有数据库的 runtime,不会在 Node 端打开数据库副本。 */
|
|
68
|
+
function createSqliteDevtoolsBroker(options = {}) {
|
|
69
|
+
const token = (0, node_crypto.randomBytes)(32).toString("hex");
|
|
70
|
+
const peers = /* @__PURE__ */ new Map();
|
|
71
|
+
const owners = /* @__PURE__ */ new Map();
|
|
72
|
+
const sockets = /* @__PURE__ */ new Set();
|
|
73
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
74
|
+
const server = new ws.WebSocketServer({
|
|
75
|
+
noServer: true,
|
|
76
|
+
maxPayload: require_protocol.SQLITE_DEVTOOLS_MAX_MESSAGE_BYTES,
|
|
77
|
+
perMessageDeflate: false
|
|
78
|
+
});
|
|
79
|
+
let detach;
|
|
80
|
+
let closed = false;
|
|
81
|
+
function changed() {
|
|
82
|
+
for (const listener of listeners) listener();
|
|
83
|
+
}
|
|
84
|
+
function remove(peer) {
|
|
85
|
+
for (const pending of peer.pending.values()) {
|
|
86
|
+
clearTimeout(pending.timer);
|
|
87
|
+
pending.resolve(errorResult("SQLITE_DEVTOOLS_DISCONNECTED", "Runtime disconnected. The operation was not retried; its outcome may be unknown."));
|
|
88
|
+
}
|
|
89
|
+
peer.pending.clear();
|
|
90
|
+
if (peers.get(peer.descriptor.id) === peer) {
|
|
91
|
+
peers.delete(peer.descriptor.id);
|
|
92
|
+
owners.delete(peer.descriptor.id);
|
|
93
|
+
changed();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
server.on("connection", (socket) => {
|
|
97
|
+
if (closed || sockets.size >= 32) {
|
|
98
|
+
socket.close(1008, "Runtime capacity reached");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
sockets.add(socket);
|
|
102
|
+
let peer;
|
|
103
|
+
const authTimer = setTimeout(() => socket.close(1008, "Authentication timed out"), 5e3);
|
|
104
|
+
socket.on("error", () => {
|
|
105
|
+
socket.terminate();
|
|
106
|
+
});
|
|
107
|
+
socket.on("close", () => {
|
|
108
|
+
clearTimeout(authTimer);
|
|
109
|
+
sockets.delete(socket);
|
|
110
|
+
if (peer) remove(peer);
|
|
111
|
+
});
|
|
112
|
+
socket.on("message", (bytes, binary) => {
|
|
113
|
+
try {
|
|
114
|
+
const frame = Array.isArray(bytes) ? node_buffer.Buffer.concat(bytes) : bytes instanceof ArrayBuffer ? node_buffer.Buffer.from(bytes) : bytes;
|
|
115
|
+
if (binary || !peer && frame.byteLength > 32768) throw new Error("Invalid frame");
|
|
116
|
+
const message = JSON.parse(frame.toString());
|
|
117
|
+
if (!require_protocol.isRecord(message)) throw new Error("Invalid frame");
|
|
118
|
+
if (!peer) {
|
|
119
|
+
if (message.type !== "hello" || message.protocol !== 1 || typeof message.token !== "string" || message.token.length !== token.length || !(0, node_crypto.timingSafeEqual)(node_buffer.Buffer.from(message.token), node_buffer.Buffer.from(token)) || !require_protocol.isRecord(message.runtime) || !require_protocol.isIdentifier(message.runtime.id) || !require_protocol.isIdentifier(message.runtime.label) || !require_protocol.isIdentifier(message.runtime.platform) || !require_protocol.validDatabaseNames(message.databases)) throw new Error("Invalid authentication");
|
|
120
|
+
const old = peers.get(message.runtime.id);
|
|
121
|
+
if (old) {
|
|
122
|
+
remove(old);
|
|
123
|
+
old.socket.close(1e3, "Runtime replaced");
|
|
124
|
+
}
|
|
125
|
+
peer = {
|
|
126
|
+
socket,
|
|
127
|
+
descriptor: {
|
|
128
|
+
id: message.runtime.id,
|
|
129
|
+
label: message.runtime.label,
|
|
130
|
+
platform: message.runtime.platform,
|
|
131
|
+
databases: [...message.databases],
|
|
132
|
+
sessionId: (0, node_crypto.randomUUID)(),
|
|
133
|
+
connectedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
134
|
+
readOnly: options.allowWrite !== true
|
|
135
|
+
},
|
|
136
|
+
pending: /* @__PURE__ */ new Map()
|
|
137
|
+
};
|
|
138
|
+
clearTimeout(authTimer);
|
|
139
|
+
peers.set(peer.descriptor.id, peer);
|
|
140
|
+
socket.send(JSON.stringify({
|
|
141
|
+
type: "ready",
|
|
142
|
+
sessionId: peer.descriptor.sessionId,
|
|
143
|
+
allowWrite: options.allowWrite === true
|
|
144
|
+
}));
|
|
145
|
+
changed();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (peers.get(peer.descriptor.id) !== peer || message.sessionId !== peer.descriptor.sessionId) throw new Error("Stale runtime session");
|
|
149
|
+
if (message.type === "databases" && require_protocol.validDatabaseNames(message.databases)) {
|
|
150
|
+
peer = {
|
|
151
|
+
...peer,
|
|
152
|
+
descriptor: {
|
|
153
|
+
...peer.descriptor,
|
|
154
|
+
databases: [...message.databases]
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
peers.set(peer.descriptor.id, peer);
|
|
158
|
+
changed();
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (message.type !== "result" && message.type !== "release-result" || !require_protocol.isIdentifier(message.requestId) || !require_protocol.isRecord(message.result)) throw new Error("Invalid runtime response");
|
|
162
|
+
const pending = peer.pending.get(message.requestId);
|
|
163
|
+
if (!pending) return;
|
|
164
|
+
const result = message.result;
|
|
165
|
+
if (result.ok === true) require_protocol.decodeSqliteDevtoolsValue(result.value);
|
|
166
|
+
else if (result.ok !== false || !require_protocol.isRecord(result.error) || !require_protocol.isIdentifier(result.error.code) || typeof result.error.message !== "string" || result.error.message.length > 4096) throw new Error("Invalid runtime response");
|
|
167
|
+
clearTimeout(pending.timer);
|
|
168
|
+
peer.pending.delete(message.requestId);
|
|
169
|
+
pending.resolve(result);
|
|
170
|
+
} catch {
|
|
171
|
+
socket.close(1008, "Invalid SQLite runtime protocol");
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
return {
|
|
176
|
+
token,
|
|
177
|
+
path: RUNTIME_PATH,
|
|
178
|
+
listRuntimes(ownerId) {
|
|
179
|
+
if (!validOwnerId(ownerId)) throw new require_protocol.SqliteDevtoolsError("SQLITE_DEVTOOLS_INVALID_REQUEST", "Invalid SQLite DevTools panel owner.");
|
|
180
|
+
if (ownerId) for (const runtime of peers.values()) {
|
|
181
|
+
const runtimeOwners = owners.get(runtime.descriptor.id) ?? /* @__PURE__ */ new Set();
|
|
182
|
+
runtimeOwners.add(ownerId);
|
|
183
|
+
owners.set(runtime.descriptor.id, runtimeOwners);
|
|
184
|
+
}
|
|
185
|
+
return [...peers.values()].map((peer) => ({
|
|
186
|
+
...peer.descriptor,
|
|
187
|
+
databases: [...peer.descriptor.databases]
|
|
188
|
+
}));
|
|
189
|
+
},
|
|
190
|
+
subscribe(listener) {
|
|
191
|
+
listeners.add(listener);
|
|
192
|
+
return () => {
|
|
193
|
+
listeners.delete(listener);
|
|
194
|
+
};
|
|
195
|
+
},
|
|
196
|
+
async invoke(input) {
|
|
197
|
+
try {
|
|
198
|
+
if (!require_protocol.isRecord(input) || !require_protocol.isIdentifier(input.runtimeId) || !require_protocol.isIdentifier(input.sessionId) || !require_protocol.isIdentifier(input.databaseName) || !require_protocol.isSqliteDevtoolsMethod(input.method) || input.method === "close") throw new require_protocol.SqliteDevtoolsError("SQLITE_DEVTOOLS_INVALID_REQUEST", "Unknown SQLite runtime, database, or method.");
|
|
199
|
+
const args = require_protocol.decodeSqliteDevtoolsValue(input.args);
|
|
200
|
+
if (!Array.isArray(args) || args.length > 8) throw new require_protocol.SqliteDevtoolsError("SQLITE_DEVTOOLS_INVALID_REQUEST", "SQLite arguments must be an array.");
|
|
201
|
+
const peer = peers.get(input.runtimeId);
|
|
202
|
+
if (!peer || peer.descriptor.sessionId !== input.sessionId || peer.socket.readyState !== ws.WebSocket.OPEN) return errorResult("SQLITE_DEVTOOLS_DISCONNECTED", "The selected runtime session is no longer connected.");
|
|
203
|
+
if (!peer.descriptor.databases.includes(input.databaseName)) return errorResult("SQLITE_DEVTOOLS_DATABASE_CLOSED", "The selected database is no longer registered.");
|
|
204
|
+
if (options.allowWrite !== true && require_protocol.isSqliteDevtoolsWriteMethod(input.method)) return errorResult("SQLITE_DEVTOOLS_READ_ONLY", "This SQLite DevTools host is read-only.");
|
|
205
|
+
if (peer.pending.size >= 64) return errorResult("SQLITE_DEVTOOLS_BUSY", "Too many pending SQLite operations.");
|
|
206
|
+
const requestId = (0, node_crypto.randomUUID)();
|
|
207
|
+
const frame = JSON.stringify({
|
|
208
|
+
...input,
|
|
209
|
+
type: "request",
|
|
210
|
+
requestId
|
|
211
|
+
});
|
|
212
|
+
if (node_buffer.Buffer.byteLength(frame) > 16777216) return errorResult("SQLITE_DEVTOOLS_PAYLOAD_LIMIT", "SQLite operation exceeds the message limit.");
|
|
213
|
+
return await new Promise((resolve) => {
|
|
214
|
+
const timer = setTimeout(() => {
|
|
215
|
+
peer.pending.delete(requestId);
|
|
216
|
+
resolve(errorResult("SQLITE_DEVTOOLS_TIMEOUT", "SQLite operation timed out. It was not retried; its outcome may be unknown."));
|
|
217
|
+
}, options.requestTimeoutMs ?? 3e4);
|
|
218
|
+
peer.pending.set(requestId, {
|
|
219
|
+
resolve,
|
|
220
|
+
timer
|
|
221
|
+
});
|
|
222
|
+
peer.socket.send(frame, (error) => {
|
|
223
|
+
if (error) {
|
|
224
|
+
remove(peer);
|
|
225
|
+
peer.socket.terminate();
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
} catch (error) {
|
|
230
|
+
return {
|
|
231
|
+
ok: false,
|
|
232
|
+
error: require_protocol.serializeDevtoolsError(error)
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
async releaseSession(input) {
|
|
237
|
+
try {
|
|
238
|
+
if (!require_protocol.isRecord(input) || !require_protocol.isIdentifier(input.runtimeId) || !require_protocol.isIdentifier(input.sessionId) || !validOwnerId(input.ownerId)) throw new require_protocol.SqliteDevtoolsError("SQLITE_DEVTOOLS_INVALID_REQUEST", "Unknown SQLite runtime session.");
|
|
239
|
+
const ownerId = input.ownerId;
|
|
240
|
+
if (ownerId) {
|
|
241
|
+
const runtimeOwners = owners.get(input.runtimeId);
|
|
242
|
+
if (!runtimeOwners?.has(ownerId)) return {
|
|
243
|
+
ok: true,
|
|
244
|
+
value: require_protocol.encodeSqliteDevtoolsValue(void 0)
|
|
245
|
+
};
|
|
246
|
+
runtimeOwners.delete(ownerId);
|
|
247
|
+
if (runtimeOwners.size > 0) return {
|
|
248
|
+
ok: true,
|
|
249
|
+
value: require_protocol.encodeSqliteDevtoolsValue(void 0)
|
|
250
|
+
};
|
|
251
|
+
owners.delete(input.runtimeId);
|
|
252
|
+
}
|
|
253
|
+
const peer = peers.get(input.runtimeId);
|
|
254
|
+
if (!peer || peer.descriptor.sessionId !== input.sessionId || peer.socket.readyState !== ws.WebSocket.OPEN) return errorResult("SQLITE_DEVTOOLS_DISCONNECTED", "The selected runtime session is no longer connected.");
|
|
255
|
+
if (peer.pending.size >= 64) return errorResult("SQLITE_DEVTOOLS_BUSY", "Too many pending SQLite operations.");
|
|
256
|
+
const requestId = (0, node_crypto.randomUUID)();
|
|
257
|
+
const frame = JSON.stringify({
|
|
258
|
+
type: "release",
|
|
259
|
+
sessionId: peer.descriptor.sessionId,
|
|
260
|
+
requestId
|
|
261
|
+
});
|
|
262
|
+
if (node_buffer.Buffer.byteLength(frame) > 16777216) return errorResult("SQLITE_DEVTOOLS_PAYLOAD_LIMIT", "SQLite session release exceeds the message limit.");
|
|
263
|
+
return await new Promise((resolve) => {
|
|
264
|
+
const timer = setTimeout(() => {
|
|
265
|
+
peer.pending.delete(requestId);
|
|
266
|
+
resolve(errorResult("SQLITE_DEVTOOLS_TIMEOUT", "SQLite debug session release timed out."));
|
|
267
|
+
}, options.requestTimeoutMs ?? 3e4);
|
|
268
|
+
peer.pending.set(requestId, {
|
|
269
|
+
resolve,
|
|
270
|
+
timer
|
|
271
|
+
});
|
|
272
|
+
peer.socket.send(frame, (error) => {
|
|
273
|
+
if (error) {
|
|
274
|
+
remove(peer);
|
|
275
|
+
peer.socket.terminate();
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
} catch (error) {
|
|
280
|
+
return {
|
|
281
|
+
ok: false,
|
|
282
|
+
error: require_protocol.serializeDevtoolsError(error)
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
attach(httpServer) {
|
|
287
|
+
if (closed || detach) throw new Error("SQLite runtime broker is already attached or closed.");
|
|
288
|
+
const upgrade = (request, socket, head) => {
|
|
289
|
+
if (request.url?.split("?")[0] !== RUNTIME_PATH) return;
|
|
290
|
+
if (closed || !validOrigin(request.headers.origin)) {
|
|
291
|
+
socket.destroy();
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
server.handleUpgrade(request, socket, head, (client) => {
|
|
295
|
+
server.emit("connection", client, request);
|
|
296
|
+
});
|
|
297
|
+
};
|
|
298
|
+
httpServer.on("upgrade", upgrade);
|
|
299
|
+
detach = () => {
|
|
300
|
+
httpServer.off("upgrade", upgrade);
|
|
301
|
+
};
|
|
302
|
+
},
|
|
303
|
+
async close() {
|
|
304
|
+
if (closed) return;
|
|
305
|
+
closed = true;
|
|
306
|
+
detach?.();
|
|
307
|
+
for (const peer of peers.values()) remove(peer);
|
|
308
|
+
for (const socket of sockets) socket.terminate();
|
|
309
|
+
await new Promise((resolve) => {
|
|
310
|
+
server.close(() => resolve());
|
|
311
|
+
});
|
|
312
|
+
listeners.clear();
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
//#endregion
|
|
317
|
+
//#region src/index.ts
|
|
318
|
+
function createSqliteDevtoolsDevframe(options = {}) {
|
|
319
|
+
const broker = createSqliteDevtoolsBroker(options);
|
|
320
|
+
let unsubscribe;
|
|
321
|
+
let disposing;
|
|
322
|
+
return {
|
|
323
|
+
definition: (0, devframe.defineDevframe)({
|
|
324
|
+
id: require_protocol.SQLITE_DEVTOOLS_SCOPE,
|
|
325
|
+
name: "SQLite",
|
|
326
|
+
version: "0.1.0",
|
|
327
|
+
packageName: "@weapp-sqlite/devtools",
|
|
328
|
+
importMetaUrl: require("url").pathToFileURL(__filename).href,
|
|
329
|
+
homepage: "https://github.com/weapp-sqlite/weapp-sqlite",
|
|
330
|
+
description: "查看与调试 Web 和小程序运行时中的 SQLite 数据库。",
|
|
331
|
+
icon: "ph:database-duotone",
|
|
332
|
+
capabilities: {
|
|
333
|
+
dev: true,
|
|
334
|
+
build: false
|
|
335
|
+
},
|
|
336
|
+
clientAssets: options.clientAssets ?? (0, node_url.fileURLToPath)(new URL("./client/", require("url").pathToFileURL(__filename).href)),
|
|
337
|
+
async setup(ctx) {
|
|
338
|
+
const scope = ctx.scope(require_protocol.SQLITE_DEVTOOLS_SCOPE);
|
|
339
|
+
scope.rpc.register((0, devframe.defineRpcFunction)({
|
|
340
|
+
name: "list-runtimes",
|
|
341
|
+
type: "query",
|
|
342
|
+
jsonSerializable: true,
|
|
343
|
+
handler: broker.listRuntimes
|
|
344
|
+
}));
|
|
345
|
+
scope.rpc.register((0, devframe.defineRpcFunction)({
|
|
346
|
+
name: "invoke",
|
|
347
|
+
type: "action",
|
|
348
|
+
jsonSerializable: true,
|
|
349
|
+
handler: broker.invoke
|
|
350
|
+
}));
|
|
351
|
+
scope.rpc.register((0, devframe.defineRpcFunction)({
|
|
352
|
+
name: "release-session",
|
|
353
|
+
type: "action",
|
|
354
|
+
jsonSerializable: true,
|
|
355
|
+
handler: broker.releaseSession
|
|
356
|
+
}));
|
|
357
|
+
unsubscribe?.();
|
|
358
|
+
unsubscribe = broker.subscribe(() => {
|
|
359
|
+
scope.rpc.broadcast({
|
|
360
|
+
method: "state-updated",
|
|
361
|
+
args: [broker.listRuntimes()],
|
|
362
|
+
event: true
|
|
363
|
+
}).catch(() => {});
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
}),
|
|
367
|
+
broker,
|
|
368
|
+
dispose() {
|
|
369
|
+
return disposing ??= (async () => {
|
|
370
|
+
unsubscribe?.();
|
|
371
|
+
unsubscribe = void 0;
|
|
372
|
+
await broker.close();
|
|
373
|
+
})();
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
function createSqliteDevtoolsPlugin(controller) {
|
|
378
|
+
return {
|
|
379
|
+
...(0, _vitejs_devtools_kit_node.createPluginFromDevframe)(controller.definition),
|
|
380
|
+
apply: "serve",
|
|
381
|
+
configureServer(server) {
|
|
382
|
+
if (!server.httpServer) throw new Error("SQLite DevTools requires an HTTP server for its runtime bridge.");
|
|
383
|
+
controller.broker.attach(server.httpServer);
|
|
384
|
+
server.httpServer.once("close", () => {
|
|
385
|
+
controller.dispose();
|
|
386
|
+
});
|
|
387
|
+
},
|
|
388
|
+
async closeServer() {
|
|
389
|
+
await controller.dispose();
|
|
390
|
+
},
|
|
391
|
+
async closeBundle() {
|
|
392
|
+
await controller.dispose();
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
/** 创建独立开发宿主;调用方负责其 watcher 与退出生命周期。 */
|
|
397
|
+
async function startSqliteDevtoolsServer(options = {}) {
|
|
398
|
+
const controller = createSqliteDevtoolsDevframe(options);
|
|
399
|
+
const assets = controller.definition.clientAssets;
|
|
400
|
+
if (typeof assets !== "string" || !(0, node_fs.existsSync)(node_path.default.join(assets, "index.html"))) {
|
|
401
|
+
await controller.dispose();
|
|
402
|
+
throw new Error("SQLite DevTools client is missing. Build @weapp-sqlite/devtools first.");
|
|
403
|
+
}
|
|
404
|
+
let server;
|
|
405
|
+
try {
|
|
406
|
+
const devtoolsPlugins = await (0, _vitejs_devtools.DevTools)({
|
|
407
|
+
builtinDevTools: false,
|
|
408
|
+
clientAuth: true,
|
|
409
|
+
allowedOrigins: [],
|
|
410
|
+
mcp: false
|
|
411
|
+
});
|
|
412
|
+
server = await (0, vite.createServer)({
|
|
413
|
+
configFile: false,
|
|
414
|
+
root: options.cwd ?? node_process.default.cwd(),
|
|
415
|
+
publicDir: false,
|
|
416
|
+
appType: "custom",
|
|
417
|
+
clearScreen: false,
|
|
418
|
+
logLevel: "silent",
|
|
419
|
+
plugins: [...devtoolsPlugins, createSqliteDevtoolsPlugin(controller)],
|
|
420
|
+
server: {
|
|
421
|
+
host: "127.0.0.1",
|
|
422
|
+
port: options.port ?? 0,
|
|
423
|
+
strictPort: options.port !== void 0 && options.port !== 0,
|
|
424
|
+
watch: { ignored: ["**/*"] }
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
await server.listen();
|
|
428
|
+
const address = server.httpServer?.address();
|
|
429
|
+
if (!address || typeof address === "string") throw new Error("SQLite DevTools could not resolve its listening port.");
|
|
430
|
+
const origin = `http://127.0.0.1:${address.port}`;
|
|
431
|
+
let closing;
|
|
432
|
+
const activeServer = server;
|
|
433
|
+
return {
|
|
434
|
+
url: (0, devframe_node_auth.buildOtpAuthUrl)(`${origin}/__weapp-sqlite/`, (0, devframe_node_auth.refreshTempAuthCode)()),
|
|
435
|
+
runtimeEndpoint: `ws://127.0.0.1:${address.port}${controller.broker.path}`,
|
|
436
|
+
runtimeToken: controller.broker.token,
|
|
437
|
+
close() {
|
|
438
|
+
return closing ??= controller.dispose().finally(() => activeServer.close());
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
} catch (error) {
|
|
442
|
+
await controller.dispose();
|
|
443
|
+
await server?.close();
|
|
444
|
+
throw error;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
//#endregion
|
|
448
|
+
exports.connectDevtoolsClient = require_client.connectDevtoolsClient;
|
|
449
|
+
exports.createSqliteDevtoolsDevframe = createSqliteDevtoolsDevframe;
|
|
450
|
+
exports.createSqliteDevtoolsPlugin = createSqliteDevtoolsPlugin;
|
|
451
|
+
exports.startSqliteDevtoolsServer = startSqliteDevtoolsServer;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { c as SqliteDevtoolsInvocation, d as SqliteDevtoolsResult, l as SqliteDevtoolsMethod, p as SqliteDevtoolsRuntimeDescriptor, u as SqliteDevtoolsReleaseSession } from "./protocol-BhfjLrSe.cjs";
|
|
2
|
+
import { SqliteDevtoolsClient, connectDevtoolsClient } from "./client.cjs";
|
|
3
|
+
import { Server } from "node:http";
|
|
4
|
+
//#region src/broker.d.ts
|
|
5
|
+
interface SqliteDevtoolsBrokerOptions {
|
|
6
|
+
readonly allowWrite?: boolean;
|
|
7
|
+
readonly requestTimeoutMs?: number;
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/index.d.ts
|
|
11
|
+
declare module 'devframe' {
|
|
12
|
+
interface DevframeRpcServerFunctions {
|
|
13
|
+
'weapp-sqlite:list-runtimes': (ownerId?: string) => SqliteDevtoolsRuntimeDescriptor[];
|
|
14
|
+
'weapp-sqlite:invoke': (input: SqliteDevtoolsInvocation) => Promise<SqliteDevtoolsResult>;
|
|
15
|
+
'weapp-sqlite:release-session': (input: SqliteDevtoolsReleaseSession) => Promise<SqliteDevtoolsResult>;
|
|
16
|
+
}
|
|
17
|
+
interface DevframeRpcClientFunctions {
|
|
18
|
+
'weapp-sqlite:state-updated': (runtimes: SqliteDevtoolsRuntimeDescriptor[]) => void;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export interface CreateSqliteDevtoolsDevframeOptions extends SqliteDevtoolsBrokerOptions {
|
|
22
|
+
readonly clientAssets?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function createSqliteDevtoolsDevframe(options?: CreateSqliteDevtoolsDevframeOptions): {
|
|
25
|
+
definition: import("devframe").DevframeDefinition;
|
|
26
|
+
broker: {
|
|
27
|
+
token: string;
|
|
28
|
+
path: string;
|
|
29
|
+
listRuntimes(ownerId?: string): SqliteDevtoolsRuntimeDescriptor[];
|
|
30
|
+
subscribe(listener: () => void): () => void;
|
|
31
|
+
invoke(input: unknown): Promise<SqliteDevtoolsResult>;
|
|
32
|
+
releaseSession(input: unknown): Promise<SqliteDevtoolsResult>;
|
|
33
|
+
attach(httpServer: Server): void;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
};
|
|
36
|
+
dispose(): Promise<void>;
|
|
37
|
+
};
|
|
38
|
+
export type SqliteDevtoolsDevframe = ReturnType<typeof createSqliteDevtoolsDevframe>;
|
|
39
|
+
/** 认证与 Origin 策略由 Vite DevTools 宿主持有,runtime broker 另用专用凭证。 */
|
|
40
|
+
/** Vite-compatible subset; keeps the public declaration independent of Vite's server internals. */
|
|
41
|
+
export interface SqliteDevtoolsPlugin {
|
|
42
|
+
readonly name: string;
|
|
43
|
+
readonly apply: 'serve';
|
|
44
|
+
readonly configureServer: (server: {
|
|
45
|
+
readonly httpServer?: unknown;
|
|
46
|
+
}) => void;
|
|
47
|
+
readonly closeServer: () => Promise<void>;
|
|
48
|
+
readonly closeBundle: () => Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
export declare function createSqliteDevtoolsPlugin(controller: SqliteDevtoolsDevframe): SqliteDevtoolsPlugin;
|
|
51
|
+
export interface StartSqliteDevtoolsServerOptions extends CreateSqliteDevtoolsDevframeOptions {
|
|
52
|
+
readonly cwd?: string;
|
|
53
|
+
readonly port?: number;
|
|
54
|
+
}
|
|
55
|
+
export interface SqliteDevtoolsServer {
|
|
56
|
+
readonly url: string;
|
|
57
|
+
readonly runtimeEndpoint: string;
|
|
58
|
+
readonly runtimeToken: string;
|
|
59
|
+
close: () => Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
/** 创建独立开发宿主;调用方负责其 watcher 与退出生命周期。 */
|
|
62
|
+
export declare function startSqliteDevtoolsServer(options?: StartSqliteDevtoolsServerOptions): Promise<SqliteDevtoolsServer>;
|
|
63
|
+
//#endregion
|
|
64
|
+
export { type SqliteDevtoolsClient, type SqliteDevtoolsInvocation, type SqliteDevtoolsMethod, type SqliteDevtoolsReleaseSession, type SqliteDevtoolsRuntimeDescriptor, connectDevtoolsClient };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { c as SqliteDevtoolsInvocation, d as SqliteDevtoolsResult, l as SqliteDevtoolsMethod, p as SqliteDevtoolsRuntimeDescriptor, u as SqliteDevtoolsReleaseSession } from "./protocol-BhfjLrSe.mjs";
|
|
2
|
+
import { SqliteDevtoolsClient, connectDevtoolsClient } from "./client.mjs";
|
|
3
|
+
import { Server } from "node:http";
|
|
4
|
+
//#region src/broker.d.ts
|
|
5
|
+
interface SqliteDevtoolsBrokerOptions {
|
|
6
|
+
readonly allowWrite?: boolean;
|
|
7
|
+
readonly requestTimeoutMs?: number;
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/index.d.ts
|
|
11
|
+
declare module 'devframe' {
|
|
12
|
+
interface DevframeRpcServerFunctions {
|
|
13
|
+
'weapp-sqlite:list-runtimes': (ownerId?: string) => SqliteDevtoolsRuntimeDescriptor[];
|
|
14
|
+
'weapp-sqlite:invoke': (input: SqliteDevtoolsInvocation) => Promise<SqliteDevtoolsResult>;
|
|
15
|
+
'weapp-sqlite:release-session': (input: SqliteDevtoolsReleaseSession) => Promise<SqliteDevtoolsResult>;
|
|
16
|
+
}
|
|
17
|
+
interface DevframeRpcClientFunctions {
|
|
18
|
+
'weapp-sqlite:state-updated': (runtimes: SqliteDevtoolsRuntimeDescriptor[]) => void;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export interface CreateSqliteDevtoolsDevframeOptions extends SqliteDevtoolsBrokerOptions {
|
|
22
|
+
readonly clientAssets?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function createSqliteDevtoolsDevframe(options?: CreateSqliteDevtoolsDevframeOptions): {
|
|
25
|
+
definition: import("devframe").DevframeDefinition;
|
|
26
|
+
broker: {
|
|
27
|
+
token: string;
|
|
28
|
+
path: string;
|
|
29
|
+
listRuntimes(ownerId?: string): SqliteDevtoolsRuntimeDescriptor[];
|
|
30
|
+
subscribe(listener: () => void): () => void;
|
|
31
|
+
invoke(input: unknown): Promise<SqliteDevtoolsResult>;
|
|
32
|
+
releaseSession(input: unknown): Promise<SqliteDevtoolsResult>;
|
|
33
|
+
attach(httpServer: Server): void;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
};
|
|
36
|
+
dispose(): Promise<void>;
|
|
37
|
+
};
|
|
38
|
+
export type SqliteDevtoolsDevframe = ReturnType<typeof createSqliteDevtoolsDevframe>;
|
|
39
|
+
/** 认证与 Origin 策略由 Vite DevTools 宿主持有,runtime broker 另用专用凭证。 */
|
|
40
|
+
/** Vite-compatible subset; keeps the public declaration independent of Vite's server internals. */
|
|
41
|
+
export interface SqliteDevtoolsPlugin {
|
|
42
|
+
readonly name: string;
|
|
43
|
+
readonly apply: 'serve';
|
|
44
|
+
readonly configureServer: (server: {
|
|
45
|
+
readonly httpServer?: unknown;
|
|
46
|
+
}) => void;
|
|
47
|
+
readonly closeServer: () => Promise<void>;
|
|
48
|
+
readonly closeBundle: () => Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
export declare function createSqliteDevtoolsPlugin(controller: SqliteDevtoolsDevframe): SqliteDevtoolsPlugin;
|
|
51
|
+
export interface StartSqliteDevtoolsServerOptions extends CreateSqliteDevtoolsDevframeOptions {
|
|
52
|
+
readonly cwd?: string;
|
|
53
|
+
readonly port?: number;
|
|
54
|
+
}
|
|
55
|
+
export interface SqliteDevtoolsServer {
|
|
56
|
+
readonly url: string;
|
|
57
|
+
readonly runtimeEndpoint: string;
|
|
58
|
+
readonly runtimeToken: string;
|
|
59
|
+
close: () => Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
/** 创建独立开发宿主;调用方负责其 watcher 与退出生命周期。 */
|
|
62
|
+
export declare function startSqliteDevtoolsServer(options?: StartSqliteDevtoolsServerOptions): Promise<SqliteDevtoolsServer>;
|
|
63
|
+
//#endregion
|
|
64
|
+
export { type SqliteDevtoolsClient, type SqliteDevtoolsInvocation, type SqliteDevtoolsMethod, type SqliteDevtoolsReleaseSession, type SqliteDevtoolsRuntimeDescriptor, connectDevtoolsClient };
|