@adep/web-container 0.2.1 → 0.2.3
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/bundle-export.d.ts +75 -0
- package/dist/function-fetch-proxy.d.ts +17 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.js +439 -61
- package/dist/sim/runtime.d.ts +1 -0
- package/dist/vite-dev.d.ts +8 -0
- package/dist/web-container.esm.js +439 -61
- package/dist/web-container.iife.js +439 -61
- package/package.json +3 -3
|
@@ -118,6 +118,27 @@ var AdepWebContainer = (() => {
|
|
|
118
118
|
}
|
|
119
119
|
return abs;
|
|
120
120
|
}
|
|
121
|
+
function pickConditionTarget(conditions, order, resolveRel, context) {
|
|
122
|
+
for (const key of order) {
|
|
123
|
+
const value = conditions[key];
|
|
124
|
+
if (value === void 0 || value === null) continue;
|
|
125
|
+
if (typeof value === "string") return resolveRel(value);
|
|
126
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
127
|
+
const nested = pickConditionTarget(
|
|
128
|
+
value,
|
|
129
|
+
order,
|
|
130
|
+
resolveRel,
|
|
131
|
+
context
|
|
132
|
+
);
|
|
133
|
+
if (nested !== null) return nested;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
throw new ResolveError(
|
|
137
|
+
`${context}\uFF1Aexports["."]["${key}"] \u5F62\u6001\u4E0D\u652F\u6301\uFF08\u4EC5\u63A5\u53D7\u5B57\u7B26\u4E32 / null / \u6761\u4EF6\u5BF9\u8C61\uFF09`
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
121
142
|
function resolvePackageEntry(meta, pkgDirAbs, condition) {
|
|
122
143
|
const context = `\u5305 ${meta.name ?? meta.version ?? pkgDirAbs} \u7684 exports/main \u58F0\u660E`;
|
|
123
144
|
const exp = meta.exports;
|
|
@@ -138,20 +159,11 @@ var AdepWebContainer = (() => {
|
|
|
138
159
|
if (typeof dot !== "object" || Array.isArray(dot)) {
|
|
139
160
|
throw new ResolveError(`${context}\uFF1Aexports["."] \u5F62\u6001\u4E0D\u652F\u6301\uFF08\u4EC5\u63A5\u53D7\u5B57\u7B26\u4E32\u6216\u6761\u4EF6\u5BF9\u8C61\uFF09`);
|
|
140
161
|
}
|
|
141
|
-
const
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if (value !== void 0 && (typeof value !== "object" || value === null)) {
|
|
147
|
-
throw new ResolveError(
|
|
148
|
-
`${context}\uFF1Aexports["."]["${key}"] \u5F62\u6001\u4E0D\u652F\u6301\uFF08\u4EC5\u63A5\u53D7\u5B57\u7B26\u4E32\u6216 null\uFF09`
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
throw new ResolveError(
|
|
153
|
-
`${context}\uFF1Aexports["."] \u6761\u4EF6\u5BF9\u8C61\u91CC\u6CA1\u6709 ${condition}/node/default \u5B57\u7B26\u4E32\u5165\u53E3\uFF08\u5B50\u8DEF\u5F84/\u5D4C\u5957\u6761\u4EF6\u4E0D\u652F\u6301\uFF09`
|
|
154
|
-
);
|
|
162
|
+
const order = condition === "import" ? IMPORT_CONDITION_ORDER : REQUIRE_CONDITION_ORDER;
|
|
163
|
+
const resolveRel = (rel) => withinPackage(pkgDirAbs, rel, context);
|
|
164
|
+
const hit = pickConditionTarget(dot, order, resolveRel, context);
|
|
165
|
+
if (hit !== null) return hit;
|
|
166
|
+
throw new ResolveError(`${context}\uFF1Aexports["."] \u6761\u4EF6\u5BF9\u8C61\u91CC\u6CA1\u6709 ${order.join("/")} \u5165\u53E3`);
|
|
155
167
|
}
|
|
156
168
|
if (meta.main !== void 0) {
|
|
157
169
|
if (typeof meta.main !== "string") {
|
|
@@ -249,11 +261,13 @@ var AdepWebContainer = (() => {
|
|
|
249
261
|
`\u627E\u4E0D\u5230\u5305 "${specifier}"\uFF1A${dirname(fromFileAbs)} \u53CA\u5176\u5404\u7EA7\u7236\u76EE\u5F55\u4E0B\u90FD\u6CA1\u6709 node_modules/${name}\uFF08\u5148\u5728\u7EC8\u7AEF npm install ${name}\uFF09`
|
|
250
262
|
);
|
|
251
263
|
}
|
|
252
|
-
var RESOLVE_EXTENSIONS, ResolveError;
|
|
264
|
+
var IMPORT_CONDITION_ORDER, REQUIRE_CONDITION_ORDER, RESOLVE_EXTENSIONS, ResolveError;
|
|
253
265
|
var init_node_resolve = __esm({
|
|
254
266
|
"src/node-resolve.ts"() {
|
|
255
267
|
"use strict";
|
|
256
268
|
init_path();
|
|
269
|
+
IMPORT_CONDITION_ORDER = ["browser", "import", "module", "default"];
|
|
270
|
+
REQUIRE_CONDITION_ORDER = ["require", "node", "default"];
|
|
257
271
|
RESOLVE_EXTENSIONS = [".js", ".mjs", ".cjs", ".json"];
|
|
258
272
|
ResolveError = class extends Error {
|
|
259
273
|
constructor(message) {
|
|
@@ -528,6 +542,7 @@ var AdepWebContainer = (() => {
|
|
|
528
542
|
return;
|
|
529
543
|
case "as":
|
|
530
544
|
case "satisfies": {
|
|
545
|
+
if (this.frames[this.frames.length - 1]?.specifierList === true) return;
|
|
531
546
|
if (this.tokenAt(2) === "*" || this.tokenAt(2) === "type") return;
|
|
532
547
|
const nextChar = this.skipWhitespaceFrom(this.i);
|
|
533
548
|
if (nextChar === null || "=,:]})".includes(this.src[nextChar])) return;
|
|
@@ -580,7 +595,8 @@ var AdepWebContainer = (() => {
|
|
|
580
595
|
const frame = {
|
|
581
596
|
kind: c === "(" ? "paren" : c === "{" ? "brace" : "bracket",
|
|
582
597
|
declare: false,
|
|
583
|
-
classBody: false
|
|
598
|
+
classBody: false,
|
|
599
|
+
specifierList: c === "{" && this.isImportSpecifierBrace()
|
|
584
600
|
};
|
|
585
601
|
if (c === "{" && this.pendingClassBody) {
|
|
586
602
|
frame.classBody = true;
|
|
@@ -667,8 +683,17 @@ var AdepWebContainer = (() => {
|
|
|
667
683
|
return true;
|
|
668
684
|
}
|
|
669
685
|
/**
|
|
670
|
-
* `
|
|
671
|
-
*
|
|
686
|
+
* `{` 是 import / export 的说明符列表吗——`{ a as b }` 覆盖 `import { … }`、
|
|
687
|
+
* `export { … }` 与 `import def, { … }` 三种写法(后者说明符花括号的前驱 token 是 `,`)。
|
|
688
|
+
*/
|
|
689
|
+
isImportSpecifierBrace() {
|
|
690
|
+
const back1 = this.tokenAt(1);
|
|
691
|
+
if (back1 === "import" || back1 === "export") return true;
|
|
692
|
+
return back1 === "," && this.tokenAt(3) === "import";
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* `(` 是否为参数列表(声明位):`function f(`、`async` 箭头 `async (`、类体里的方法 `m(`、
|
|
696
|
+
* 箭头 `=> (`,以及出现在 `(` `,` `=` `>` `:` `[` `{` `}` `;` 之后(如 `map((v: T) => v)` 的内层括号)。
|
|
672
697
|
* 调用位 `foo(` 与控制流 `if (` `for (` 都不算。
|
|
673
698
|
* 误判成声明位也不足以擦掉什么:`:` 还要过 `isAnnotationColon` 的「名字前驱必须是
|
|
674
699
|
* `(` `,` `{` `;` 修饰符」这一关,而三元表达式的中间段前面必然是 `?`。
|
|
@@ -677,6 +702,8 @@ var AdepWebContainer = (() => {
|
|
|
677
702
|
if (this.afterFunctionKeyword) return true;
|
|
678
703
|
if (this.tokenAt(2) === "function" && IDENT_START.test(this.tokenAt(1))) return true;
|
|
679
704
|
if (this.afterArrow) return true;
|
|
705
|
+
if (this.tokenAt(1) === "async") return true;
|
|
706
|
+
if (this.tokenAt(1) === "return") return true;
|
|
680
707
|
if (this.inClassBody() && IDENT_PART.test(this.prevSignificantChar(at - 1))) return true;
|
|
681
708
|
const prev = this.prevSignificantChar(at - 1);
|
|
682
709
|
return prev === "" || "(,=>:[{};".includes(prev);
|
|
@@ -1185,11 +1212,15 @@ var AdepWebContainer = (() => {
|
|
|
1185
1212
|
" }",
|
|
1186
1213
|
" var u;",
|
|
1187
1214
|
" try { u = new URL(urlStr, document.baseURI); }",
|
|
1188
|
-
" catch (
|
|
1215
|
+
" catch (e0) {",
|
|
1216
|
+
" try { u = new URL(urlStr, window.location.origin); }",
|
|
1217
|
+
" catch (e1) { return ORIGINAL_FETCH(input, init); }",
|
|
1218
|
+
" }",
|
|
1189
1219
|
' if (u.pathname.indexOf("/api/") !== 0 && u.pathname !== "/api") {',
|
|
1190
1220
|
" return ORIGINAL_FETCH(input, init);",
|
|
1191
1221
|
" }",
|
|
1192
|
-
"
|
|
1222
|
+
" var bridgeWindow = window.parent !== window ? window.parent : window.opener;",
|
|
1223
|
+
" if (!bridgeWindow) return ORIGINAL_FETCH(input, init);",
|
|
1193
1224
|
' method = (method || "GET").toUpperCase();',
|
|
1194
1225
|
" var target = u.pathname + u.search;",
|
|
1195
1226
|
" return readBody(input, init).then(function (textBody) {",
|
|
@@ -1200,10 +1231,75 @@ var AdepWebContainer = (() => {
|
|
|
1200
1231
|
` resolve(new Response('{"error":{"code":"FN_PROXY_TIMEOUT","message":"\\u4e91\\u51fd\\u6570\\u6267\\u884c\\u8d85\\u65f6"}}', { status: 504, headers: { "content-type": "application/json" } }));`,
|
|
1201
1232
|
" }, TIMEOUT_MS);",
|
|
1202
1233
|
" pending[id] = { resolve: resolve, timer: timer };",
|
|
1203
|
-
'
|
|
1234
|
+
' bridgeWindow.postMessage({ __adepFnRequest: true, id: id, method: method, url: target, headers: headers, body: textBody }, "*");',
|
|
1204
1235
|
" });",
|
|
1205
1236
|
" });",
|
|
1206
1237
|
" };",
|
|
1238
|
+
"",
|
|
1239
|
+
" /* \u2014\u2014 blob URL SPA \u8DEF\u7531\u652F\u6301 \u2014\u2014",
|
|
1240
|
+
" blob: \u662F\u4E0D\u53EF\u5206\u5C42 scheme\uFF0Chistory.pushState('/about') \u5185\u90E8\u89E3\u6790\u76F8\u5BF9\u8DEF\u5F84\u4F1A\u629B",
|
|
1241
|
+
" TypeError \u2192 SPA history \u6A21\u5F0F\u8DEF\u7531\u5D29\u6E83\u3002patch pushState/replaceState\uFF0C\u5BF9\u76F8\u5BF9",
|
|
1242
|
+
" \u8DEF\u5F84\u76F4\u63A5\u541E\u6389\uFF08\u4E0D\u5BFC\u822A\u3001\u4E0D\u629B\u9519\uFF09\uFF0C\u8DEF\u7531\u5E93\u5185\u90E8\u72B6\u6001\u81EA\u884C\u66F4\u65B0\uFF1Blocation.pathname",
|
|
1243
|
+
" \u8986\u76D6\u4E3A\u5F53\u524D\u8DEF\u7531\u8DEF\u5F84\uFF0C\u4F9B\u8DEF\u7531\u5E93\u521D\u59CB\u5316\u65F6\u8BFB\u53D6\u3002sessionStorage \u6301\u4E45\u5316\uFF0C\u5237\u65B0\u540E\u6062\u590D\u3002 */",
|
|
1244
|
+
' if (window.location.protocol === "blob:") {',
|
|
1245
|
+
' var SPA_KEY = "__adep_spa_path";',
|
|
1246
|
+
' var spaPath = "/";',
|
|
1247
|
+
" try {",
|
|
1248
|
+
" var _saved = window.sessionStorage.getItem(SPA_KEY);",
|
|
1249
|
+
" if (_saved) spaPath = _saved;",
|
|
1250
|
+
" } catch (e) {}",
|
|
1251
|
+
" try {",
|
|
1252
|
+
' Object.defineProperty(window.location, "pathname", {',
|
|
1253
|
+
" get: function () { return spaPath; },",
|
|
1254
|
+
" configurable: true",
|
|
1255
|
+
" });",
|
|
1256
|
+
" } catch (e) {}",
|
|
1257
|
+
" var _origPush = window.history.pushState.bind(window.history);",
|
|
1258
|
+
" var _origReplace = window.history.replaceState.bind(window.history);",
|
|
1259
|
+
" function _isRelative(url) {",
|
|
1260
|
+
' if (!url || typeof url !== "string") return false;',
|
|
1261
|
+
' if (url.charAt(0) === "#") return false;',
|
|
1262
|
+
" if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(url)) return false;",
|
|
1263
|
+
" return true;",
|
|
1264
|
+
" }",
|
|
1265
|
+
" function _resolvePath(url) {",
|
|
1266
|
+
' var qi = url.indexOf("?");',
|
|
1267
|
+
' var hi = url.indexOf("#");',
|
|
1268
|
+
" var end = url.length;",
|
|
1269
|
+
" if (qi !== -1) end = qi;",
|
|
1270
|
+
" if (hi !== -1 && hi < end) end = hi;",
|
|
1271
|
+
" var p = url.slice(0, end);",
|
|
1272
|
+
' if (p.charAt(0) !== "/") {',
|
|
1273
|
+
' var base = spaPath.slice(0, spaPath.lastIndexOf("/") + 1);',
|
|
1274
|
+
" p = base + p;",
|
|
1275
|
+
" }",
|
|
1276
|
+
' var parts = p.split("/");',
|
|
1277
|
+
" var out = [];",
|
|
1278
|
+
" for (var i = 0; i < parts.length; i++) {",
|
|
1279
|
+
" var seg = parts[i];",
|
|
1280
|
+
' if (seg === "" || seg === ".") continue;',
|
|
1281
|
+
' if (seg === "..") { out.pop(); continue; }',
|
|
1282
|
+
" out.push(seg);",
|
|
1283
|
+
" }",
|
|
1284
|
+
' return "/" + out.join("/");',
|
|
1285
|
+
" }",
|
|
1286
|
+
" window.history.pushState = function (state, title, url) {",
|
|
1287
|
+
" if (_isRelative(url)) {",
|
|
1288
|
+
" spaPath = _resolvePath(url);",
|
|
1289
|
+
" try { window.sessionStorage.setItem(SPA_KEY, spaPath); } catch (e) {}",
|
|
1290
|
+
" return;",
|
|
1291
|
+
" }",
|
|
1292
|
+
" return _origPush(state, title, url);",
|
|
1293
|
+
" };",
|
|
1294
|
+
" window.history.replaceState = function (state, title, url) {",
|
|
1295
|
+
" if (_isRelative(url)) {",
|
|
1296
|
+
" spaPath = _resolvePath(url);",
|
|
1297
|
+
" try { window.sessionStorage.setItem(SPA_KEY, spaPath); } catch (e) {}",
|
|
1298
|
+
" return;",
|
|
1299
|
+
" }",
|
|
1300
|
+
" return _origReplace(state, title, url);",
|
|
1301
|
+
" };",
|
|
1302
|
+
" }",
|
|
1207
1303
|
"})();"
|
|
1208
1304
|
].join("\n");
|
|
1209
1305
|
return src;
|
|
@@ -1324,6 +1420,18 @@ var AdepWebContainer = (() => {
|
|
|
1324
1420
|
"export default css;"
|
|
1325
1421
|
].join("\n");
|
|
1326
1422
|
}
|
|
1423
|
+
function inlineStyleBlock(css, key) {
|
|
1424
|
+
return [
|
|
1425
|
+
"{",
|
|
1426
|
+
`const css = ${JSON.stringify(css)};`,
|
|
1427
|
+
'const el = document.createElement("style");',
|
|
1428
|
+
'el.setAttribute("data-adep-vite", "");',
|
|
1429
|
+
`el.setAttribute("data-adep-style", ${JSON.stringify(key)});`,
|
|
1430
|
+
"el.textContent = css;",
|
|
1431
|
+
"document.head.appendChild(el);",
|
|
1432
|
+
"}"
|
|
1433
|
+
].join("\n");
|
|
1434
|
+
}
|
|
1327
1435
|
function jsonModule(source, abs) {
|
|
1328
1436
|
try {
|
|
1329
1437
|
JSON.parse(source);
|
|
@@ -1374,6 +1482,17 @@ var AdepWebContainer = (() => {
|
|
|
1374
1482
|
} catch {
|
|
1375
1483
|
}
|
|
1376
1484
|
};
|
|
1485
|
+
const DEFINES = [
|
|
1486
|
+
[/\bprocess\s*\.\s*env\s*\.\s*NODE_ENV\b/g, JSON.stringify("development")],
|
|
1487
|
+
[/\b__VUE_OPTIONS_API__\b/g, "true"],
|
|
1488
|
+
[/\b__VUE_PROD_DEVTOOLS__\b/g, "false"],
|
|
1489
|
+
[/\b__VUE_PROD_HYDRATION_MISMATCH_DETAILS__\b/g, "false"]
|
|
1490
|
+
];
|
|
1491
|
+
function applyDefines(code) {
|
|
1492
|
+
let out = code;
|
|
1493
|
+
for (const [pattern, value] of DEFINES) out = out.replace(pattern, value);
|
|
1494
|
+
return out;
|
|
1495
|
+
}
|
|
1377
1496
|
function transformModule2(abs, source) {
|
|
1378
1497
|
if (abs.endsWith(".css")) return cssModule(source);
|
|
1379
1498
|
if (abs.endsWith(".json")) return jsonModule(source, abs);
|
|
@@ -1384,21 +1503,27 @@ var AdepWebContainer = (() => {
|
|
|
1384
1503
|
`${abs} \u662F Vue SFC\uFF0C\u4F46\u5F53\u524D\u73AF\u5883\u672A\u88C5\u914D SFC \u7F16\u8BD1\u5668\uFF08IDE \u4FA7\u9700\u6CE8\u5165 vue/compiler-sfc\uFF09`
|
|
1385
1504
|
);
|
|
1386
1505
|
const compiled = sfcCompiler(source, abs);
|
|
1387
|
-
return [
|
|
1506
|
+
return [
|
|
1507
|
+
...compiled.styles.map((css, index) => inlineStyleBlock(css, `${abs}#${index}`)),
|
|
1508
|
+
applyDefines(stripTypes(compiled.script))
|
|
1509
|
+
].join("\n");
|
|
1388
1510
|
}
|
|
1389
1511
|
if (abs.endsWith(".tsx") || abs.endsWith(".jsx"))
|
|
1390
1512
|
throw new ViteDevError(
|
|
1391
1513
|
"JSX_UNSUPPORTED",
|
|
1392
1514
|
`${abs} \u4F7F\u7528 JSX\uFF1A\u6D4F\u89C8\u5668\u5185 vite \u53EA\u64E6\u9664 TS \u7C7B\u578B\u6807\u6CE8\uFF0C\u4E0D\u8F6C\u8BD1 JSX\uFF08\u8BF7\u7528 h() \u6E32\u67D3\u51FD\u6570\u6216 .vue SFC\uFF09`
|
|
1393
1515
|
);
|
|
1394
|
-
if (abs.endsWith(".ts") || abs.endsWith(".mts")) return stripTypes(source);
|
|
1395
|
-
return source;
|
|
1516
|
+
if (abs.endsWith(".ts") || abs.endsWith(".mts")) return applyDefines(stripTypes(source));
|
|
1517
|
+
return applyDefines(source);
|
|
1518
|
+
}
|
|
1519
|
+
function absoluteFromRoot(spec) {
|
|
1520
|
+
return join(root, spec.replace(/^\/+/, ""));
|
|
1396
1521
|
}
|
|
1397
1522
|
async function resolveSpecifier(spec, importerAbs) {
|
|
1398
1523
|
if (EXTERNAL_SPECIFIER.test(spec) || DATA_OR_BLOB.test(spec)) return spec;
|
|
1399
1524
|
let target;
|
|
1400
1525
|
if (spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/")) {
|
|
1401
|
-
const base = spec.startsWith("/") ? spec : join(dirname(importerAbs), spec);
|
|
1526
|
+
const base = spec.startsWith("/") ? absoluteFromRoot(spec) : join(dirname(importerAbs), spec);
|
|
1402
1527
|
target = resolveWithSuffixes(vfs, base);
|
|
1403
1528
|
if (!vfs.exists(target) || vfs.isDirectory(target))
|
|
1404
1529
|
throw new ViteDevError(
|
|
@@ -1487,7 +1612,7 @@ var AdepWebContainer = (() => {
|
|
|
1487
1612
|
html = html.replace(
|
|
1488
1613
|
MODULE_SCRIPT_SRC_RE,
|
|
1489
1614
|
(_whole, pre, _q1, mid, _q2, src, post) => {
|
|
1490
|
-
const base = src.startsWith("/") ?
|
|
1615
|
+
const base = src.startsWith("/") ? absoluteFromRoot(src) : join(dirname(entryAbs), src);
|
|
1491
1616
|
const abs = resolveWithSuffixes(vfs, base);
|
|
1492
1617
|
if (!vfs.exists(abs) || vfs.isDirectory(abs))
|
|
1493
1618
|
throw new ViteDevError(
|
|
@@ -1495,7 +1620,7 @@ var AdepWebContainer = (() => {
|
|
|
1495
1620
|
`\u5165\u53E3 module script \u627E\u4E0D\u5230 "${src}"\uFF08root: ${root}\uFF1B\u8BD5\u8FC7\u6269\u5C55\u540D ${VITE_RESOLVE_SUFFIXES.join("/")} \u4E0E\u76EE\u5F55 index\uFF09`
|
|
1496
1621
|
);
|
|
1497
1622
|
entryModuleUrls.push(loadModuleUrl(abs));
|
|
1498
|
-
return `<script${pre}${mid}src="__adep_vite_entry_${entryModuleUrls.length - 1}__"${post}><\/script>`;
|
|
1623
|
+
return `<script${pre}${mid}src="__adep_vite_entry_${entryModuleUrls.length - 1}__"${post} type="module"><\/script>`;
|
|
1499
1624
|
}
|
|
1500
1625
|
);
|
|
1501
1626
|
html = html.replace(
|
|
@@ -1505,7 +1630,7 @@ var AdepWebContainer = (() => {
|
|
|
1505
1630
|
const abs = `${INLINE_PREFIX}${inlineSeq++}.mjs`;
|
|
1506
1631
|
inlineSources.set(abs, body);
|
|
1507
1632
|
entryModuleUrls.push(loadModuleUrl(abs));
|
|
1508
|
-
return `<script${pre}${post}src="__adep_vite_entry_${entryModuleUrls.length - 1}__"><\/script>`;
|
|
1633
|
+
return `<script${pre}${post}src="__adep_vite_entry_${entryModuleUrls.length - 1}__" type="module"><\/script>`;
|
|
1509
1634
|
}
|
|
1510
1635
|
);
|
|
1511
1636
|
const urls = await Promise.all(entryModuleUrls);
|
|
@@ -1529,7 +1654,10 @@ var AdepWebContainer = (() => {
|
|
|
1529
1654
|
lastDoc = doc;
|
|
1530
1655
|
if (currentUrl !== "") revokeObjectURL(currentUrl);
|
|
1531
1656
|
currentUrl = createObjectURL(new Blob([doc], { type: "text/html" }));
|
|
1532
|
-
if (changed)
|
|
1657
|
+
if (changed) {
|
|
1658
|
+
broadcast(currentUrl);
|
|
1659
|
+
options.onDocumentChange?.(currentUrl);
|
|
1660
|
+
}
|
|
1533
1661
|
}
|
|
1534
1662
|
const server = {
|
|
1535
1663
|
get url() {
|
|
@@ -1631,6 +1759,7 @@ var AdepWebContainer = (() => {
|
|
|
1631
1759
|
// src/index.ts
|
|
1632
1760
|
var index_exports = {};
|
|
1633
1761
|
__export(index_exports, {
|
|
1762
|
+
BUNDLE_MODULE_PATH_PREFIX: () => BUNDLE_MODULE_PATH_PREFIX,
|
|
1634
1763
|
COMPLETABLE_COMMANDS: () => COMPLETABLE_COMMANDS,
|
|
1635
1764
|
DEFAULT_MAX_INSTALL_DEPTH: () => DEFAULT_MAX_INSTALL_DEPTH,
|
|
1636
1765
|
EXTRA_COMMANDS: () => EXTRA_COMMANDS,
|
|
@@ -1676,12 +1805,15 @@ var AdepWebContainer = (() => {
|
|
|
1676
1805
|
createViteServer: () => createViteServer,
|
|
1677
1806
|
createWorkerRuntime: () => createWorkerRuntime,
|
|
1678
1807
|
deepEqual: () => deepEqual,
|
|
1808
|
+
defaultModuleName: () => defaultModuleName,
|
|
1679
1809
|
displayPath: () => displayPath,
|
|
1680
1810
|
entriesToTree: () => entriesToTree,
|
|
1681
1811
|
evaluateModuleSource: () => evaluateModuleSource,
|
|
1682
1812
|
evaluateSource: () => evaluateSource,
|
|
1683
1813
|
exampleTestSource: () => exampleTestSource,
|
|
1684
1814
|
expectAssertion: () => expect,
|
|
1815
|
+
exportBundle: () => exportBundle,
|
|
1816
|
+
findBlobRefs: () => findBlobRefs,
|
|
1685
1817
|
formatTestReport: () => formatTestReport,
|
|
1686
1818
|
formatValue: () => formatValue,
|
|
1687
1819
|
fullName: () => fullName,
|
|
@@ -3653,7 +3785,11 @@ self.onmessage = async (event) => {
|
|
|
3653
3785
|
const { createViteServer: createViteServer2 } = await Promise.resolve().then(() => (init_vite_dev(), vite_dev_exports));
|
|
3654
3786
|
const server = createViteServer2(vfs, {
|
|
3655
3787
|
root,
|
|
3656
|
-
...options.viteCompiler === void 0 ? {} : { sfcCompiler: options.viteCompiler }
|
|
3788
|
+
...options.viteCompiler === void 0 ? {} : { sfcCompiler: options.viteCompiler },
|
|
3789
|
+
// PV-006:内容重建 → 以 `serverready`(update: true)事件上报新文档 URL,宿主导出预览产物。
|
|
3790
|
+
onDocumentChange: (url) => {
|
|
3791
|
+
emit("serverready", { port: server.port, url, kind: "vite", root: server.root, update: true });
|
|
3792
|
+
}
|
|
3657
3793
|
});
|
|
3658
3794
|
await server.ready;
|
|
3659
3795
|
viteServer = server;
|
|
@@ -3818,6 +3954,92 @@ self.onmessage = async (event) => {
|
|
|
3818
3954
|
init_vite_dev();
|
|
3819
3955
|
init_path();
|
|
3820
3956
|
|
|
3957
|
+
// src/bundle-export.ts
|
|
3958
|
+
var BUNDLE_MODULE_PATH_PREFIX = "/_adep/m/";
|
|
3959
|
+
var BLOB_REF_RE = /blob:[^\s"'`<>()\\]+/g;
|
|
3960
|
+
function fnv1a(code) {
|
|
3961
|
+
let hash = 2166136261;
|
|
3962
|
+
for (let i = 0; i < code.length; i++) {
|
|
3963
|
+
hash ^= code.charCodeAt(i);
|
|
3964
|
+
hash = Math.imul(hash, 16777619) >>> 0;
|
|
3965
|
+
}
|
|
3966
|
+
return `${hash.toString(16).padStart(8, "0")}${code.length.toString(16)}`;
|
|
3967
|
+
}
|
|
3968
|
+
async function defaultModuleName(code) {
|
|
3969
|
+
const subtle = globalThis.crypto?.subtle;
|
|
3970
|
+
if (subtle === void 0) return fnv1a(code);
|
|
3971
|
+
const digest = await subtle.digest("SHA-256", new TextEncoder().encode(code));
|
|
3972
|
+
let hex = "";
|
|
3973
|
+
for (const byte of new Uint8Array(digest).slice(0, 8)) {
|
|
3974
|
+
hex += byte.toString(16).padStart(2, "0");
|
|
3975
|
+
}
|
|
3976
|
+
return hex;
|
|
3977
|
+
}
|
|
3978
|
+
function findBlobRefs(text) {
|
|
3979
|
+
const found = text.match(BLOB_REF_RE);
|
|
3980
|
+
return found === null ? [] : [...new Set(found)];
|
|
3981
|
+
}
|
|
3982
|
+
function rewriteRefs(text, urls) {
|
|
3983
|
+
let out = text;
|
|
3984
|
+
for (const [blobUrl, path] of urls) {
|
|
3985
|
+
if (out.includes(blobUrl)) out = out.split(blobUrl).join(path);
|
|
3986
|
+
}
|
|
3987
|
+
return out;
|
|
3988
|
+
}
|
|
3989
|
+
function injectScript(html, script) {
|
|
3990
|
+
return /<\/body>/i.test(html) ? html.replace(/<\/body>/i, `${script}</body>`) : html + script;
|
|
3991
|
+
}
|
|
3992
|
+
async function exportBundle(options) {
|
|
3993
|
+
const readText = options.readText ?? ((url) => fetch(url).then((response) => response.text()));
|
|
3994
|
+
const nameOf = options.moduleName ?? defaultModuleName;
|
|
3995
|
+
const prefix = options.modulePathPrefix ?? BUNDLE_MODULE_PATH_PREFIX;
|
|
3996
|
+
const uploaded = new Set(options.known === void 0 ? [] : [...options.known.values()]);
|
|
3997
|
+
const urls = /* @__PURE__ */ new Map();
|
|
3998
|
+
const sources = [];
|
|
3999
|
+
const readOrThrow = async (url) => {
|
|
4000
|
+
try {
|
|
4001
|
+
return await readText(url);
|
|
4002
|
+
} catch (error) {
|
|
4003
|
+
throw new Error(
|
|
4004
|
+
`\u9884\u89C8\u4EA7\u7269\u5BFC\u51FA\u5931\u8D25\uFF1A\u8BFB\u4E0D\u5230\u6A21\u5757 ${url}\uFF08${error instanceof Error ? error.message : String(error)}\uFF09`,
|
|
4005
|
+
{ cause: error }
|
|
4006
|
+
);
|
|
4007
|
+
}
|
|
4008
|
+
};
|
|
4009
|
+
const html = await readOrThrow(options.documentUrl);
|
|
4010
|
+
const loadLayer = async (layer) => {
|
|
4011
|
+
const batch = [...new Set(layer)].filter((url) => !urls.has(url));
|
|
4012
|
+
if (batch.length === 0) return;
|
|
4013
|
+
const loaded = await Promise.all(
|
|
4014
|
+
batch.map(async (url) => {
|
|
4015
|
+
const code = await readOrThrow(url);
|
|
4016
|
+
return { url, code, path: `${prefix}${await nameOf(code)}.js` };
|
|
4017
|
+
})
|
|
4018
|
+
);
|
|
4019
|
+
const next = [];
|
|
4020
|
+
for (const item of loaded) {
|
|
4021
|
+
urls.set(item.url, item.path);
|
|
4022
|
+
sources.push({ url: item.url, code: item.code });
|
|
4023
|
+
next.push(...findBlobRefs(item.code));
|
|
4024
|
+
}
|
|
4025
|
+
await loadLayer(next);
|
|
4026
|
+
};
|
|
4027
|
+
await loadLayer(findBlobRefs(html));
|
|
4028
|
+
const modules = {};
|
|
4029
|
+
for (const { url, code } of sources) {
|
|
4030
|
+
const path = urls.get(url);
|
|
4031
|
+
if (uploaded.has(path)) continue;
|
|
4032
|
+
modules[path] = rewriteRefs(code, urls);
|
|
4033
|
+
}
|
|
4034
|
+
const rewrittenHtml = rewriteRefs(html, urls);
|
|
4035
|
+
return {
|
|
4036
|
+
html: options.appendScript === void 0 ? rewrittenHtml : injectScript(rewrittenHtml, options.appendScript),
|
|
4037
|
+
modules,
|
|
4038
|
+
paths: [...new Set(urls.values())].toSorted(),
|
|
4039
|
+
urls
|
|
4040
|
+
};
|
|
4041
|
+
}
|
|
4042
|
+
|
|
3821
4043
|
// src/persistence.ts
|
|
3822
4044
|
function cloneEntries(entries) {
|
|
3823
4045
|
return entries.map(
|
|
@@ -4559,6 +4781,8 @@ self.onmessage = async (event) => {
|
|
|
4559
4781
|
var DB_RPC = {
|
|
4560
4782
|
/** 直通方法(如 query):`(method=query, args=[sql, params])`。 */
|
|
4561
4783
|
query: "query",
|
|
4784
|
+
/** 写路径(CF-013):`(method=writeQuery, args=[sql, params])` → `{ changes }`。 */
|
|
4785
|
+
writeQuery: "writeQuery",
|
|
4562
4786
|
/** 读取 owned 表变更流(DB-006):`(method=changes, args=[table, query])`。 */
|
|
4563
4787
|
changes: "changes",
|
|
4564
4788
|
/** 开启事务:`begin → txId`。 */
|
|
@@ -4635,21 +4859,35 @@ self.onmessage = async (event) => {
|
|
|
4635
4859
|
function stripLiterals(sql) {
|
|
4636
4860
|
return sql.replace(/'[^']*(?:''[^']*)*'/g, "").replace(/"[^"]*(?:""[^"]*)*"/g, "").replace(/--[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
4637
4861
|
}
|
|
4638
|
-
function
|
|
4862
|
+
function sqlHead(sql) {
|
|
4863
|
+
return sql.trim().replace(/^\(+/, "").trim().toUpperCase();
|
|
4864
|
+
}
|
|
4865
|
+
function assertSafeStatement(sql) {
|
|
4639
4866
|
const stripped = stripLiterals(sql);
|
|
4640
4867
|
if (stripped.includes(";")) {
|
|
4641
4868
|
throw unsafeOperation("\u4EC5\u5141\u8BB8\u5355\u6761\u8BED\u53E5\uFF0C\u7981\u6B62\u591A\u8BED\u53E5\u5806\u53E0");
|
|
4642
4869
|
}
|
|
4643
|
-
const head = stripped.trim().replace(/^\(+/, "").trim().toUpperCase();
|
|
4644
|
-
if (!head.startsWith("SELECT") && !head.startsWith("WITH")) {
|
|
4645
|
-
throw unsafeOperation("cloud.db.query \u4EC5\u5141\u8BB8\u53EA\u8BFB\u67E5\u8BE2\uFF08SELECT / WITH\uFF09");
|
|
4646
|
-
}
|
|
4647
4870
|
if (/ATTACH|DETACH/.test(stripped.toUpperCase())) {
|
|
4648
4871
|
throw unsafeOperation("\u7981\u6B62\u8DE8\u5E93\u64CD\u4F5C\uFF08ATTACH / DETACH\uFF09");
|
|
4649
4872
|
}
|
|
4650
4873
|
if (/SQLITE_\w+/i.test(stripped)) {
|
|
4651
4874
|
throw unsafeOperation("\u7981\u6B62\u8BBF\u95EE\u7CFB\u7EDF\u8868\uFF08sqlite_*\uFF09");
|
|
4652
4875
|
}
|
|
4876
|
+
return sqlHead(stripped);
|
|
4877
|
+
}
|
|
4878
|
+
function assertReadOnlyQuery(sql) {
|
|
4879
|
+
const head = assertSafeStatement(sql);
|
|
4880
|
+
if (!head.startsWith("SELECT") && !head.startsWith("WITH")) {
|
|
4881
|
+
throw unsafeOperation("cloud.db.query \u4EC5\u5141\u8BB8\u53EA\u8BFB\u67E5\u8BE2\uFF08SELECT / WITH\uFF09");
|
|
4882
|
+
}
|
|
4883
|
+
}
|
|
4884
|
+
function assertWriteQuery(sql) {
|
|
4885
|
+
const head = assertSafeStatement(sql);
|
|
4886
|
+
if (!head.startsWith("INSERT") && !head.startsWith("UPDATE") && !head.startsWith("DELETE")) {
|
|
4887
|
+
throw unsafeOperation(
|
|
4888
|
+
"cloud.db.writeQuery \u4EC5\u5141\u8BB8 DML\uFF08INSERT / UPDATE / DELETE\uFF09\uFF0CDDL \u8BF7\u8D70\u63A7\u5236\u53F0"
|
|
4889
|
+
);
|
|
4890
|
+
}
|
|
4653
4891
|
}
|
|
4654
4892
|
|
|
4655
4893
|
// ../runtime/src/database/builder/owned.ts
|
|
@@ -5195,6 +5433,14 @@ self.onmessage = async (event) => {
|
|
|
5195
5433
|
assertReadOnlyQuery(sql);
|
|
5196
5434
|
return driver.all(sql, params);
|
|
5197
5435
|
},
|
|
5436
|
+
async writeQuery(sql, params) {
|
|
5437
|
+
if (!Array.isArray(params)) {
|
|
5438
|
+
throw unsafeOperation("writeQuery \u7684 params \u5FC5\u987B\u63D0\u4F9B\uFF08\u65E0\u53C2\u4F20 []\uFF09");
|
|
5439
|
+
}
|
|
5440
|
+
guardWrite();
|
|
5441
|
+
assertWriteQuery(sql);
|
|
5442
|
+
return driver.run(sql, params);
|
|
5443
|
+
},
|
|
5198
5444
|
async changes(table, query = {}) {
|
|
5199
5445
|
return readChanges(driver, table, query);
|
|
5200
5446
|
}
|
|
@@ -5210,7 +5456,8 @@ self.onmessage = async (event) => {
|
|
|
5210
5456
|
rootMethod: "table",
|
|
5211
5457
|
stepMethods: ["select", "where", "orderBy", "limit", "offset"],
|
|
5212
5458
|
terminalMethods: ["get", "first", "count", "insert", "insertMany", "update", "delete"],
|
|
5213
|
-
|
|
5459
|
+
// CF-013:writeQuery 是 D1 shim 的写路径(INSERT/UPDATE/DELETE),与 query 并列直通方法。
|
|
5460
|
+
directMethods: ["query", "writeQuery", "changes"],
|
|
5214
5461
|
transactionMethod: "transaction"
|
|
5215
5462
|
};
|
|
5216
5463
|
var WRITE_TERMINALS = /* @__PURE__ */ new Set(["insert", "insertMany", "update", "delete"]);
|
|
@@ -5265,6 +5512,10 @@ self.onmessage = async (event) => {
|
|
|
5265
5512
|
const [sql, params] = args;
|
|
5266
5513
|
return await db.query(sql, params);
|
|
5267
5514
|
}
|
|
5515
|
+
case DB_RPC.writeQuery: {
|
|
5516
|
+
const [sql, params] = args;
|
|
5517
|
+
return await db.writeQuery(sql, params);
|
|
5518
|
+
}
|
|
5268
5519
|
case DB_RPC.changes: {
|
|
5269
5520
|
const [table, query] = args;
|
|
5270
5521
|
return await db.changes(table, query);
|
|
@@ -5550,6 +5801,17 @@ self.onmessage = async (event) => {
|
|
|
5550
5801
|
}
|
|
5551
5802
|
return { changes: 0 };
|
|
5552
5803
|
}
|
|
5804
|
+
if (/^CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?/i.test(stmt)) {
|
|
5805
|
+
const idx = /^CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?((?:"[^"]+")|([A-Za-z_][A-Za-z0-9_]*))\s+ON\s+((?:"[^"]+")|([A-Za-z_][A-Za-z0-9_]*))/i.exec(
|
|
5806
|
+
stmt
|
|
5807
|
+
);
|
|
5808
|
+
if (idx === null) throw new SimDbError("DB_UNSAFE_OP", `\u65E0\u6CD5\u89E3\u6790 CREATE INDEX \u8BED\u53E5`);
|
|
5809
|
+
const tableName = ident(idx[3]);
|
|
5810
|
+
if (this.tables[tableName] === void 0) {
|
|
5811
|
+
throw new SimDbError("DB_UNSAFE_OP", `CREATE INDEX \u76EE\u6807\u8868\u4E0D\u5B58\u5728\uFF1A${tableName}`);
|
|
5812
|
+
}
|
|
5813
|
+
return { changes: 0 };
|
|
5814
|
+
}
|
|
5553
5815
|
if (/^INSERT\s+INTO/i.test(stmt)) return this.execInsert(stmt, params);
|
|
5554
5816
|
if (/^UPDATE\s+/i.test(stmt)) return this.execUpdate(stmt, params);
|
|
5555
5817
|
if (/^DELETE\s+FROM/i.test(stmt)) return this.execDelete(stmt, params);
|
|
@@ -5794,6 +6056,19 @@ self.onmessage = async (event) => {
|
|
|
5794
6056
|
}
|
|
5795
6057
|
return path;
|
|
5796
6058
|
}
|
|
6059
|
+
function assertStoragePrefix(prefix) {
|
|
6060
|
+
if (prefix !== void 0 && prefix !== "") {
|
|
6061
|
+
const segments = prefix.split("/");
|
|
6062
|
+
if (prefix.startsWith("/") || /[\\]/.test(prefix) || segments.some((segment) => segment === "..")) {
|
|
6063
|
+
throw new StorageError(
|
|
6064
|
+
400,
|
|
6065
|
+
STORAGE_CODES.invalidPath,
|
|
6066
|
+
`\u975E\u6CD5\u524D\u7F00 "${prefix}"\uFF08\u7981\u6B62 / \u5F00\u5934\u3001\u53CD\u659C\u6760\u6216 .. \u7A7F\u8D8A\uFF09`
|
|
6067
|
+
);
|
|
6068
|
+
}
|
|
6069
|
+
}
|
|
6070
|
+
return prefix ?? "";
|
|
6071
|
+
}
|
|
5797
6072
|
|
|
5798
6073
|
// ../runtime/src/storage/hmac-sha256.ts
|
|
5799
6074
|
var K = new Uint32Array([
|
|
@@ -5994,9 +6269,12 @@ self.onmessage = async (event) => {
|
|
|
5994
6269
|
const handler = async (method, args) => {
|
|
5995
6270
|
switch (method) {
|
|
5996
6271
|
case "upload": {
|
|
5997
|
-
const [path, data] = args;
|
|
6272
|
+
const [path, data, options] = args;
|
|
5998
6273
|
return toStoredFile(
|
|
5999
|
-
await driver.put(projectId, path, asBytes(data), {
|
|
6274
|
+
await driver.put(projectId, path, asBytes(data), {
|
|
6275
|
+
visibility: DEFAULT_VISIBILITY,
|
|
6276
|
+
...options?.contentType === void 0 ? {} : { contentType: options.contentType }
|
|
6277
|
+
})
|
|
6000
6278
|
);
|
|
6001
6279
|
}
|
|
6002
6280
|
case "get": {
|
|
@@ -6110,16 +6388,7 @@ self.onmessage = async (event) => {
|
|
|
6110
6388
|
await saveBucket(bucket);
|
|
6111
6389
|
},
|
|
6112
6390
|
async list(_projectId, prefix) {
|
|
6113
|
-
|
|
6114
|
-
const segments = prefix.split("/");
|
|
6115
|
-
if (prefix.startsWith("/") || /[\\]/.test(prefix) || segments.some((segment) => segment === "..")) {
|
|
6116
|
-
throw new StorageError(
|
|
6117
|
-
400,
|
|
6118
|
-
STORAGE_CODES.invalidPath,
|
|
6119
|
-
`\u975E\u6CD5\u524D\u7F00 "${prefix}"\uFF08\u7981\u6B62 / \u5F00\u5934\u3001\u53CD\u659C\u6760\u6216 .. \u7A7F\u8D8A\uFF09`
|
|
6120
|
-
);
|
|
6121
|
-
}
|
|
6122
|
-
}
|
|
6391
|
+
assertStoragePrefix(prefix);
|
|
6123
6392
|
const bucket = await loadBucket();
|
|
6124
6393
|
return Object.values(bucket).filter((object) => prefix === void 0 || object.path.startsWith(prefix)).map(toMeta).toSorted((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
6125
6394
|
},
|
|
@@ -6443,6 +6712,10 @@ self.onmessage = async (event) => {
|
|
|
6443
6712
|
realtime: {
|
|
6444
6713
|
code: "REALTIME_NOT_AVAILABLE",
|
|
6445
6714
|
message: "\u5B9E\u65F6\u901A\u9053\u672A\u88C5\u914D\uFF1Arealtime \u57DF\u672A\u88C5\u8F7D\uFF08\u68C0\u67E5\u90E8\u7F72\u5F62\u6001\u4E0E Redis \u914D\u7F6E\uFF09\uFF08REALTIME_NOT_AVAILABLE\uFF09"
|
|
6715
|
+
},
|
|
6716
|
+
kv: {
|
|
6717
|
+
code: "KV_NOT_PROVISIONED",
|
|
6718
|
+
message: "\u9879\u76EE KV \u5B58\u50A8\u672A\u53EF\u7528\uFF1Akv \u968F\u9879\u76EE\u6570\u636E\u5E93\u63D0\u4F9B\uFF0C\u8BF7\u5148\u542F\u52A8\u6570\u636E\u5E93\uFF08KV_NOT_PROVISIONED\uFF09"
|
|
6446
6719
|
}
|
|
6447
6720
|
};
|
|
6448
6721
|
var CapabilityNotRegisteredError = class extends Error {
|
|
@@ -6502,6 +6775,19 @@ self.onmessage = async (event) => {
|
|
|
6502
6775
|
};
|
|
6503
6776
|
}
|
|
6504
6777
|
|
|
6778
|
+
// ../runtime/src/functions/runtime/rpc-wire.ts
|
|
6779
|
+
function wireRpcResponses(port, pending) {
|
|
6780
|
+
port.on?.((message) => {
|
|
6781
|
+
const reply = message;
|
|
6782
|
+
if (reply?.type !== "rpc-response" || typeof reply.id !== "number") return;
|
|
6783
|
+
const entry = pending.get(reply.id);
|
|
6784
|
+
if (entry === void 0) return;
|
|
6785
|
+
pending.delete(reply.id);
|
|
6786
|
+
if (reply.ok === true) entry.resolve(reply.result);
|
|
6787
|
+
else entry.reject(new Error(reply.error ?? "RPC \u80FD\u529B\u8C03\u7528\u5931\u8D25"));
|
|
6788
|
+
});
|
|
6789
|
+
}
|
|
6790
|
+
|
|
6505
6791
|
// src/sim/ctx.ts
|
|
6506
6792
|
function createLocalPort(handler) {
|
|
6507
6793
|
const listeners = [];
|
|
@@ -6531,17 +6817,6 @@ self.onmessage = async (event) => {
|
|
|
6531
6817
|
}
|
|
6532
6818
|
};
|
|
6533
6819
|
}
|
|
6534
|
-
function wireRpcResponses(port, pending) {
|
|
6535
|
-
port.on((message) => {
|
|
6536
|
-
const reply = message;
|
|
6537
|
-
if (reply?.type !== "rpc-response" || typeof reply.id !== "number") return;
|
|
6538
|
-
const entry = pending.get(reply.id);
|
|
6539
|
-
if (entry === void 0) return;
|
|
6540
|
-
pending.delete(reply.id);
|
|
6541
|
-
if (reply.ok === true) entry.resolve(reply.result);
|
|
6542
|
-
else entry.reject(new Error(reply.error ?? "RPC \u80FD\u529B\u8C03\u7528\u5931\u8D25"));
|
|
6543
|
-
});
|
|
6544
|
-
}
|
|
6545
6820
|
function createFlatRpcClient(handler) {
|
|
6546
6821
|
return new Proxy(
|
|
6547
6822
|
{},
|
|
@@ -6755,7 +7030,7 @@ self.onmessage = async (event) => {
|
|
|
6755
7030
|
return { run };
|
|
6756
7031
|
}
|
|
6757
7032
|
|
|
6758
|
-
// src/sim/
|
|
7033
|
+
// ../runtime/src/sim/merge.ts
|
|
6759
7034
|
function mergeBundles(bundles) {
|
|
6760
7035
|
const capabilities = [];
|
|
6761
7036
|
const byName = /* @__PURE__ */ new Map();
|
|
@@ -6775,6 +7050,108 @@ self.onmessage = async (event) => {
|
|
|
6775
7050
|
}
|
|
6776
7051
|
return { capabilities, rpcHandlers };
|
|
6777
7052
|
}
|
|
7053
|
+
|
|
7054
|
+
// ../runtime/src/database/sdk/kv.ts
|
|
7055
|
+
var KV_TABLE = "_adep_kv";
|
|
7056
|
+
var KV_RPC = {
|
|
7057
|
+
get: "get",
|
|
7058
|
+
put: "put",
|
|
7059
|
+
delete: "delete",
|
|
7060
|
+
list: "list"
|
|
7061
|
+
};
|
|
7062
|
+
var KV_CAPABILITY_CODES = {
|
|
7063
|
+
invalidMethod: "KV_INVALID_METHOD"
|
|
7064
|
+
};
|
|
7065
|
+
var KV_LIST_DEFAULT_LIMIT = 100;
|
|
7066
|
+
function nowSeconds() {
|
|
7067
|
+
return Math.floor(Date.now() / 1e3);
|
|
7068
|
+
}
|
|
7069
|
+
function errorWithCode2(error) {
|
|
7070
|
+
const code = typeof error === "object" && error !== null && typeof error.code === "string" ? error.code : void 0;
|
|
7071
|
+
if (code !== void 0 && error instanceof Error) {
|
|
7072
|
+
return new Error(`[${code}] ${error.message}`);
|
|
7073
|
+
}
|
|
7074
|
+
return error;
|
|
7075
|
+
}
|
|
7076
|
+
function createKvCapability(driver) {
|
|
7077
|
+
let ensurePromise = null;
|
|
7078
|
+
const ensureTable = () => {
|
|
7079
|
+
if (ensurePromise === null) {
|
|
7080
|
+
ensurePromise = driver.run(
|
|
7081
|
+
`CREATE TABLE IF NOT EXISTS ${KV_TABLE} (key TEXT PRIMARY KEY, value TEXT, expires_at INTEGER)`
|
|
7082
|
+
).then(() => void 0);
|
|
7083
|
+
}
|
|
7084
|
+
return ensurePromise;
|
|
7085
|
+
};
|
|
7086
|
+
const handler = async (method, args) => {
|
|
7087
|
+
try {
|
|
7088
|
+
await ensureTable();
|
|
7089
|
+
switch (method) {
|
|
7090
|
+
case KV_RPC.get: {
|
|
7091
|
+
const [key] = args;
|
|
7092
|
+
const row = await driver.get(`SELECT value, expires_at FROM ${KV_TABLE} WHERE key = ?`, [
|
|
7093
|
+
key
|
|
7094
|
+
]);
|
|
7095
|
+
if (row === null || row === void 0) return null;
|
|
7096
|
+
const expiresAt = row.expires_at;
|
|
7097
|
+
if (expiresAt !== null && expiresAt !== void 0 && Number(expiresAt) <= nowSeconds()) {
|
|
7098
|
+
return null;
|
|
7099
|
+
}
|
|
7100
|
+
return row.value;
|
|
7101
|
+
}
|
|
7102
|
+
case KV_RPC.put: {
|
|
7103
|
+
const [key, value, options] = args;
|
|
7104
|
+
const ttl = options?.expirationTtlSeconds;
|
|
7105
|
+
const expiresAt = typeof ttl === "number" && ttl > 0 ? nowSeconds() + Math.floor(ttl) : null;
|
|
7106
|
+
await driver.run(`DELETE FROM ${KV_TABLE} WHERE key = ?`, [key]);
|
|
7107
|
+
await driver.run(`INSERT INTO ${KV_TABLE} (key, value, expires_at) VALUES (?, ?, ?)`, [
|
|
7108
|
+
key,
|
|
7109
|
+
value,
|
|
7110
|
+
expiresAt
|
|
7111
|
+
]);
|
|
7112
|
+
return void 0;
|
|
7113
|
+
}
|
|
7114
|
+
case KV_RPC.delete: {
|
|
7115
|
+
const [key] = args;
|
|
7116
|
+
await driver.run(`DELETE FROM ${KV_TABLE} WHERE key = ?`, [key]);
|
|
7117
|
+
return void 0;
|
|
7118
|
+
}
|
|
7119
|
+
case KV_RPC.list: {
|
|
7120
|
+
const [options] = args;
|
|
7121
|
+
const prefix = options?.prefix ?? "";
|
|
7122
|
+
const limit = options?.limit ?? KV_LIST_DEFAULT_LIMIT;
|
|
7123
|
+
const rows = prefix === "" ? await driver.all(`SELECT key, expires_at FROM ${KV_TABLE}`) : await driver.all(`SELECT key, expires_at FROM ${KV_TABLE} WHERE key LIKE ?`, [
|
|
7124
|
+
`${prefix}%`
|
|
7125
|
+
]);
|
|
7126
|
+
const now = nowSeconds();
|
|
7127
|
+
const entries = [];
|
|
7128
|
+
for (const row of rows) {
|
|
7129
|
+
const expiresAt = row.expires_at;
|
|
7130
|
+
if (expiresAt !== null && expiresAt !== void 0 && Number(expiresAt) <= now) continue;
|
|
7131
|
+
entries.push({
|
|
7132
|
+
name: String(row.key),
|
|
7133
|
+
expiration: expiresAt === null || expiresAt === void 0 ? null : Number(expiresAt)
|
|
7134
|
+
});
|
|
7135
|
+
if (entries.length >= limit) break;
|
|
7136
|
+
}
|
|
7137
|
+
return entries;
|
|
7138
|
+
}
|
|
7139
|
+
default:
|
|
7140
|
+
throw new Error(
|
|
7141
|
+
`\u672A\u77E5\u7684 cloud.kv \u65B9\u6CD5 "${String(method)}"\uFF08${KV_CAPABILITY_CODES.invalidMethod}\uFF09`
|
|
7142
|
+
);
|
|
7143
|
+
}
|
|
7144
|
+
} catch (error) {
|
|
7145
|
+
throw errorWithCode2(error);
|
|
7146
|
+
}
|
|
7147
|
+
};
|
|
7148
|
+
return {
|
|
7149
|
+
capabilities: [{ name: "kv", value: { [RPC_CAPABILITY_KEY]: true } }],
|
|
7150
|
+
rpcHandlers: { kv: handler }
|
|
7151
|
+
};
|
|
7152
|
+
}
|
|
7153
|
+
|
|
7154
|
+
// src/sim/runtime.ts
|
|
6778
7155
|
async function createBrowserSimRuntime(options) {
|
|
6779
7156
|
const kv = options.kv ?? pickDefaultSimKv();
|
|
6780
7157
|
const db = createBrowserSimDb({ projectId: options.projectId, kv });
|
|
@@ -6789,7 +7166,8 @@ self.onmessage = async (event) => {
|
|
|
6789
7166
|
projectId: options.projectId,
|
|
6790
7167
|
...options.realtime === void 0 ? {} : options.realtime
|
|
6791
7168
|
});
|
|
6792
|
-
const
|
|
7169
|
+
const kvBundle = createKvCapability(db.driver);
|
|
7170
|
+
const bundle = mergeBundles([db.bundle, storage.bundle, kvBundle, realtime.bundle]);
|
|
6793
7171
|
await db.engine.load();
|
|
6794
7172
|
const runner = createOfflineFunctionRunner(options.runner ?? {});
|
|
6795
7173
|
return {
|