@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
|
@@ -105,6 +105,27 @@ function withinPackage(pkgDirAbs, rel, context) {
|
|
|
105
105
|
}
|
|
106
106
|
return abs;
|
|
107
107
|
}
|
|
108
|
+
function pickConditionTarget(conditions, order, resolveRel, context) {
|
|
109
|
+
for (const key of order) {
|
|
110
|
+
const value = conditions[key];
|
|
111
|
+
if (value === void 0 || value === null) continue;
|
|
112
|
+
if (typeof value === "string") return resolveRel(value);
|
|
113
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
114
|
+
const nested = pickConditionTarget(
|
|
115
|
+
value,
|
|
116
|
+
order,
|
|
117
|
+
resolveRel,
|
|
118
|
+
context
|
|
119
|
+
);
|
|
120
|
+
if (nested !== null) return nested;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
throw new ResolveError(
|
|
124
|
+
`${context}\uFF1Aexports["."]["${key}"] \u5F62\u6001\u4E0D\u652F\u6301\uFF08\u4EC5\u63A5\u53D7\u5B57\u7B26\u4E32 / null / \u6761\u4EF6\u5BF9\u8C61\uFF09`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
108
129
|
function resolvePackageEntry(meta, pkgDirAbs, condition) {
|
|
109
130
|
const context = `\u5305 ${meta.name ?? meta.version ?? pkgDirAbs} \u7684 exports/main \u58F0\u660E`;
|
|
110
131
|
const exp = meta.exports;
|
|
@@ -125,20 +146,11 @@ function resolvePackageEntry(meta, pkgDirAbs, condition) {
|
|
|
125
146
|
if (typeof dot !== "object" || Array.isArray(dot)) {
|
|
126
147
|
throw new ResolveError(`${context}\uFF1Aexports["."] \u5F62\u6001\u4E0D\u652F\u6301\uFF08\u4EC5\u63A5\u53D7\u5B57\u7B26\u4E32\u6216\u6761\u4EF6\u5BF9\u8C61\uFF09`);
|
|
127
148
|
}
|
|
128
|
-
const
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (value !== void 0 && (typeof value !== "object" || value === null)) {
|
|
134
|
-
throw new ResolveError(
|
|
135
|
-
`${context}\uFF1Aexports["."]["${key}"] \u5F62\u6001\u4E0D\u652F\u6301\uFF08\u4EC5\u63A5\u53D7\u5B57\u7B26\u4E32\u6216 null\uFF09`
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
throw new ResolveError(
|
|
140
|
-
`${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`
|
|
141
|
-
);
|
|
149
|
+
const order = condition === "import" ? IMPORT_CONDITION_ORDER : REQUIRE_CONDITION_ORDER;
|
|
150
|
+
const resolveRel = (rel) => withinPackage(pkgDirAbs, rel, context);
|
|
151
|
+
const hit = pickConditionTarget(dot, order, resolveRel, context);
|
|
152
|
+
if (hit !== null) return hit;
|
|
153
|
+
throw new ResolveError(`${context}\uFF1Aexports["."] \u6761\u4EF6\u5BF9\u8C61\u91CC\u6CA1\u6709 ${order.join("/")} \u5165\u53E3`);
|
|
142
154
|
}
|
|
143
155
|
if (meta.main !== void 0) {
|
|
144
156
|
if (typeof meta.main !== "string") {
|
|
@@ -236,11 +248,13 @@ function resolveImport(fs, specifier, fromFileAbs, condition = "require") {
|
|
|
236
248
|
`\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`
|
|
237
249
|
);
|
|
238
250
|
}
|
|
239
|
-
var RESOLVE_EXTENSIONS, ResolveError;
|
|
251
|
+
var IMPORT_CONDITION_ORDER, REQUIRE_CONDITION_ORDER, RESOLVE_EXTENSIONS, ResolveError;
|
|
240
252
|
var init_node_resolve = __esm({
|
|
241
253
|
"src/node-resolve.ts"() {
|
|
242
254
|
"use strict";
|
|
243
255
|
init_path();
|
|
256
|
+
IMPORT_CONDITION_ORDER = ["browser", "import", "module", "default"];
|
|
257
|
+
REQUIRE_CONDITION_ORDER = ["require", "node", "default"];
|
|
244
258
|
RESOLVE_EXTENSIONS = [".js", ".mjs", ".cjs", ".json"];
|
|
245
259
|
ResolveError = class extends Error {
|
|
246
260
|
constructor(message) {
|
|
@@ -515,6 +529,7 @@ var init_strip_types = __esm({
|
|
|
515
529
|
return;
|
|
516
530
|
case "as":
|
|
517
531
|
case "satisfies": {
|
|
532
|
+
if (this.frames[this.frames.length - 1]?.specifierList === true) return;
|
|
518
533
|
if (this.tokenAt(2) === "*" || this.tokenAt(2) === "type") return;
|
|
519
534
|
const nextChar = this.skipWhitespaceFrom(this.i);
|
|
520
535
|
if (nextChar === null || "=,:]})".includes(this.src[nextChar])) return;
|
|
@@ -567,7 +582,8 @@ var init_strip_types = __esm({
|
|
|
567
582
|
const frame = {
|
|
568
583
|
kind: c === "(" ? "paren" : c === "{" ? "brace" : "bracket",
|
|
569
584
|
declare: false,
|
|
570
|
-
classBody: false
|
|
585
|
+
classBody: false,
|
|
586
|
+
specifierList: c === "{" && this.isImportSpecifierBrace()
|
|
571
587
|
};
|
|
572
588
|
if (c === "{" && this.pendingClassBody) {
|
|
573
589
|
frame.classBody = true;
|
|
@@ -654,8 +670,17 @@ var init_strip_types = __esm({
|
|
|
654
670
|
return true;
|
|
655
671
|
}
|
|
656
672
|
/**
|
|
657
|
-
* `
|
|
658
|
-
*
|
|
673
|
+
* `{` 是 import / export 的说明符列表吗——`{ a as b }` 覆盖 `import { … }`、
|
|
674
|
+
* `export { … }` 与 `import def, { … }` 三种写法(后者说明符花括号的前驱 token 是 `,`)。
|
|
675
|
+
*/
|
|
676
|
+
isImportSpecifierBrace() {
|
|
677
|
+
const back1 = this.tokenAt(1);
|
|
678
|
+
if (back1 === "import" || back1 === "export") return true;
|
|
679
|
+
return back1 === "," && this.tokenAt(3) === "import";
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* `(` 是否为参数列表(声明位):`function f(`、`async` 箭头 `async (`、类体里的方法 `m(`、
|
|
683
|
+
* 箭头 `=> (`,以及出现在 `(` `,` `=` `>` `:` `[` `{` `}` `;` 之后(如 `map((v: T) => v)` 的内层括号)。
|
|
659
684
|
* 调用位 `foo(` 与控制流 `if (` `for (` 都不算。
|
|
660
685
|
* 误判成声明位也不足以擦掉什么:`:` 还要过 `isAnnotationColon` 的「名字前驱必须是
|
|
661
686
|
* `(` `,` `{` `;` 修饰符」这一关,而三元表达式的中间段前面必然是 `?`。
|
|
@@ -664,6 +689,8 @@ var init_strip_types = __esm({
|
|
|
664
689
|
if (this.afterFunctionKeyword) return true;
|
|
665
690
|
if (this.tokenAt(2) === "function" && IDENT_START.test(this.tokenAt(1))) return true;
|
|
666
691
|
if (this.afterArrow) return true;
|
|
692
|
+
if (this.tokenAt(1) === "async") return true;
|
|
693
|
+
if (this.tokenAt(1) === "return") return true;
|
|
667
694
|
if (this.inClassBody() && IDENT_PART.test(this.prevSignificantChar(at - 1))) return true;
|
|
668
695
|
const prev = this.prevSignificantChar(at - 1);
|
|
669
696
|
return prev === "" || "(,=>:[{};".includes(prev);
|
|
@@ -1172,11 +1199,15 @@ var init_function_fetch_proxy = __esm({
|
|
|
1172
1199
|
" }",
|
|
1173
1200
|
" var u;",
|
|
1174
1201
|
" try { u = new URL(urlStr, document.baseURI); }",
|
|
1175
|
-
" catch (
|
|
1202
|
+
" catch (e0) {",
|
|
1203
|
+
" try { u = new URL(urlStr, window.location.origin); }",
|
|
1204
|
+
" catch (e1) { return ORIGINAL_FETCH(input, init); }",
|
|
1205
|
+
" }",
|
|
1176
1206
|
' if (u.pathname.indexOf("/api/") !== 0 && u.pathname !== "/api") {',
|
|
1177
1207
|
" return ORIGINAL_FETCH(input, init);",
|
|
1178
1208
|
" }",
|
|
1179
|
-
"
|
|
1209
|
+
" var bridgeWindow = window.parent !== window ? window.parent : window.opener;",
|
|
1210
|
+
" if (!bridgeWindow) return ORIGINAL_FETCH(input, init);",
|
|
1180
1211
|
' method = (method || "GET").toUpperCase();',
|
|
1181
1212
|
" var target = u.pathname + u.search;",
|
|
1182
1213
|
" return readBody(input, init).then(function (textBody) {",
|
|
@@ -1187,10 +1218,75 @@ var init_function_fetch_proxy = __esm({
|
|
|
1187
1218
|
` resolve(new Response('{"error":{"code":"FN_PROXY_TIMEOUT","message":"\\u4e91\\u51fd\\u6570\\u6267\\u884c\\u8d85\\u65f6"}}', { status: 504, headers: { "content-type": "application/json" } }));`,
|
|
1188
1219
|
" }, TIMEOUT_MS);",
|
|
1189
1220
|
" pending[id] = { resolve: resolve, timer: timer };",
|
|
1190
|
-
'
|
|
1221
|
+
' bridgeWindow.postMessage({ __adepFnRequest: true, id: id, method: method, url: target, headers: headers, body: textBody }, "*");',
|
|
1191
1222
|
" });",
|
|
1192
1223
|
" });",
|
|
1193
1224
|
" };",
|
|
1225
|
+
"",
|
|
1226
|
+
" /* \u2014\u2014 blob URL SPA \u8DEF\u7531\u652F\u6301 \u2014\u2014",
|
|
1227
|
+
" blob: \u662F\u4E0D\u53EF\u5206\u5C42 scheme\uFF0Chistory.pushState('/about') \u5185\u90E8\u89E3\u6790\u76F8\u5BF9\u8DEF\u5F84\u4F1A\u629B",
|
|
1228
|
+
" TypeError \u2192 SPA history \u6A21\u5F0F\u8DEF\u7531\u5D29\u6E83\u3002patch pushState/replaceState\uFF0C\u5BF9\u76F8\u5BF9",
|
|
1229
|
+
" \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",
|
|
1230
|
+
" \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 */",
|
|
1231
|
+
' if (window.location.protocol === "blob:") {',
|
|
1232
|
+
' var SPA_KEY = "__adep_spa_path";',
|
|
1233
|
+
' var spaPath = "/";',
|
|
1234
|
+
" try {",
|
|
1235
|
+
" var _saved = window.sessionStorage.getItem(SPA_KEY);",
|
|
1236
|
+
" if (_saved) spaPath = _saved;",
|
|
1237
|
+
" } catch (e) {}",
|
|
1238
|
+
" try {",
|
|
1239
|
+
' Object.defineProperty(window.location, "pathname", {',
|
|
1240
|
+
" get: function () { return spaPath; },",
|
|
1241
|
+
" configurable: true",
|
|
1242
|
+
" });",
|
|
1243
|
+
" } catch (e) {}",
|
|
1244
|
+
" var _origPush = window.history.pushState.bind(window.history);",
|
|
1245
|
+
" var _origReplace = window.history.replaceState.bind(window.history);",
|
|
1246
|
+
" function _isRelative(url) {",
|
|
1247
|
+
' if (!url || typeof url !== "string") return false;',
|
|
1248
|
+
' if (url.charAt(0) === "#") return false;',
|
|
1249
|
+
" if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(url)) return false;",
|
|
1250
|
+
" return true;",
|
|
1251
|
+
" }",
|
|
1252
|
+
" function _resolvePath(url) {",
|
|
1253
|
+
' var qi = url.indexOf("?");',
|
|
1254
|
+
' var hi = url.indexOf("#");',
|
|
1255
|
+
" var end = url.length;",
|
|
1256
|
+
" if (qi !== -1) end = qi;",
|
|
1257
|
+
" if (hi !== -1 && hi < end) end = hi;",
|
|
1258
|
+
" var p = url.slice(0, end);",
|
|
1259
|
+
' if (p.charAt(0) !== "/") {',
|
|
1260
|
+
' var base = spaPath.slice(0, spaPath.lastIndexOf("/") + 1);',
|
|
1261
|
+
" p = base + p;",
|
|
1262
|
+
" }",
|
|
1263
|
+
' var parts = p.split("/");',
|
|
1264
|
+
" var out = [];",
|
|
1265
|
+
" for (var i = 0; i < parts.length; i++) {",
|
|
1266
|
+
" var seg = parts[i];",
|
|
1267
|
+
' if (seg === "" || seg === ".") continue;',
|
|
1268
|
+
' if (seg === "..") { out.pop(); continue; }',
|
|
1269
|
+
" out.push(seg);",
|
|
1270
|
+
" }",
|
|
1271
|
+
' return "/" + out.join("/");',
|
|
1272
|
+
" }",
|
|
1273
|
+
" window.history.pushState = function (state, title, url) {",
|
|
1274
|
+
" if (_isRelative(url)) {",
|
|
1275
|
+
" spaPath = _resolvePath(url);",
|
|
1276
|
+
" try { window.sessionStorage.setItem(SPA_KEY, spaPath); } catch (e) {}",
|
|
1277
|
+
" return;",
|
|
1278
|
+
" }",
|
|
1279
|
+
" return _origPush(state, title, url);",
|
|
1280
|
+
" };",
|
|
1281
|
+
" window.history.replaceState = function (state, title, url) {",
|
|
1282
|
+
" if (_isRelative(url)) {",
|
|
1283
|
+
" spaPath = _resolvePath(url);",
|
|
1284
|
+
" try { window.sessionStorage.setItem(SPA_KEY, spaPath); } catch (e) {}",
|
|
1285
|
+
" return;",
|
|
1286
|
+
" }",
|
|
1287
|
+
" return _origReplace(state, title, url);",
|
|
1288
|
+
" };",
|
|
1289
|
+
" }",
|
|
1194
1290
|
"})();"
|
|
1195
1291
|
].join("\n");
|
|
1196
1292
|
return src;
|
|
@@ -1311,6 +1407,18 @@ function cssModule(css) {
|
|
|
1311
1407
|
"export default css;"
|
|
1312
1408
|
].join("\n");
|
|
1313
1409
|
}
|
|
1410
|
+
function inlineStyleBlock(css, key) {
|
|
1411
|
+
return [
|
|
1412
|
+
"{",
|
|
1413
|
+
`const css = ${JSON.stringify(css)};`,
|
|
1414
|
+
'const el = document.createElement("style");',
|
|
1415
|
+
'el.setAttribute("data-adep-vite", "");',
|
|
1416
|
+
`el.setAttribute("data-adep-style", ${JSON.stringify(key)});`,
|
|
1417
|
+
"el.textContent = css;",
|
|
1418
|
+
"document.head.appendChild(el);",
|
|
1419
|
+
"}"
|
|
1420
|
+
].join("\n");
|
|
1421
|
+
}
|
|
1314
1422
|
function jsonModule(source, abs) {
|
|
1315
1423
|
try {
|
|
1316
1424
|
JSON.parse(source);
|
|
@@ -1361,6 +1469,17 @@ function createViteServer(vfs, options = {}) {
|
|
|
1361
1469
|
} catch {
|
|
1362
1470
|
}
|
|
1363
1471
|
};
|
|
1472
|
+
const DEFINES = [
|
|
1473
|
+
[/\bprocess\s*\.\s*env\s*\.\s*NODE_ENV\b/g, JSON.stringify("development")],
|
|
1474
|
+
[/\b__VUE_OPTIONS_API__\b/g, "true"],
|
|
1475
|
+
[/\b__VUE_PROD_DEVTOOLS__\b/g, "false"],
|
|
1476
|
+
[/\b__VUE_PROD_HYDRATION_MISMATCH_DETAILS__\b/g, "false"]
|
|
1477
|
+
];
|
|
1478
|
+
function applyDefines(code) {
|
|
1479
|
+
let out = code;
|
|
1480
|
+
for (const [pattern, value] of DEFINES) out = out.replace(pattern, value);
|
|
1481
|
+
return out;
|
|
1482
|
+
}
|
|
1364
1483
|
function transformModule2(abs, source) {
|
|
1365
1484
|
if (abs.endsWith(".css")) return cssModule(source);
|
|
1366
1485
|
if (abs.endsWith(".json")) return jsonModule(source, abs);
|
|
@@ -1371,21 +1490,27 @@ function createViteServer(vfs, options = {}) {
|
|
|
1371
1490
|
`${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`
|
|
1372
1491
|
);
|
|
1373
1492
|
const compiled = sfcCompiler(source, abs);
|
|
1374
|
-
return [
|
|
1493
|
+
return [
|
|
1494
|
+
...compiled.styles.map((css, index) => inlineStyleBlock(css, `${abs}#${index}`)),
|
|
1495
|
+
applyDefines(stripTypes(compiled.script))
|
|
1496
|
+
].join("\n");
|
|
1375
1497
|
}
|
|
1376
1498
|
if (abs.endsWith(".tsx") || abs.endsWith(".jsx"))
|
|
1377
1499
|
throw new ViteDevError(
|
|
1378
1500
|
"JSX_UNSUPPORTED",
|
|
1379
1501
|
`${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`
|
|
1380
1502
|
);
|
|
1381
|
-
if (abs.endsWith(".ts") || abs.endsWith(".mts")) return stripTypes(source);
|
|
1382
|
-
return source;
|
|
1503
|
+
if (abs.endsWith(".ts") || abs.endsWith(".mts")) return applyDefines(stripTypes(source));
|
|
1504
|
+
return applyDefines(source);
|
|
1505
|
+
}
|
|
1506
|
+
function absoluteFromRoot(spec) {
|
|
1507
|
+
return join(root, spec.replace(/^\/+/, ""));
|
|
1383
1508
|
}
|
|
1384
1509
|
async function resolveSpecifier(spec, importerAbs) {
|
|
1385
1510
|
if (EXTERNAL_SPECIFIER.test(spec) || DATA_OR_BLOB.test(spec)) return spec;
|
|
1386
1511
|
let target;
|
|
1387
1512
|
if (spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/")) {
|
|
1388
|
-
const base = spec.startsWith("/") ? spec : join(dirname(importerAbs), spec);
|
|
1513
|
+
const base = spec.startsWith("/") ? absoluteFromRoot(spec) : join(dirname(importerAbs), spec);
|
|
1389
1514
|
target = resolveWithSuffixes(vfs, base);
|
|
1390
1515
|
if (!vfs.exists(target) || vfs.isDirectory(target))
|
|
1391
1516
|
throw new ViteDevError(
|
|
@@ -1474,7 +1599,7 @@ function createViteServer(vfs, options = {}) {
|
|
|
1474
1599
|
html = html.replace(
|
|
1475
1600
|
MODULE_SCRIPT_SRC_RE,
|
|
1476
1601
|
(_whole, pre, _q1, mid, _q2, src, post) => {
|
|
1477
|
-
const base = src.startsWith("/") ?
|
|
1602
|
+
const base = src.startsWith("/") ? absoluteFromRoot(src) : join(dirname(entryAbs), src);
|
|
1478
1603
|
const abs = resolveWithSuffixes(vfs, base);
|
|
1479
1604
|
if (!vfs.exists(abs) || vfs.isDirectory(abs))
|
|
1480
1605
|
throw new ViteDevError(
|
|
@@ -1482,7 +1607,7 @@ function createViteServer(vfs, options = {}) {
|
|
|
1482
1607
|
`\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`
|
|
1483
1608
|
);
|
|
1484
1609
|
entryModuleUrls.push(loadModuleUrl(abs));
|
|
1485
|
-
return `<script${pre}${mid}src="__adep_vite_entry_${entryModuleUrls.length - 1}__"${post}><\/script>`;
|
|
1610
|
+
return `<script${pre}${mid}src="__adep_vite_entry_${entryModuleUrls.length - 1}__"${post} type="module"><\/script>`;
|
|
1486
1611
|
}
|
|
1487
1612
|
);
|
|
1488
1613
|
html = html.replace(
|
|
@@ -1492,7 +1617,7 @@ function createViteServer(vfs, options = {}) {
|
|
|
1492
1617
|
const abs = `${INLINE_PREFIX}${inlineSeq++}.mjs`;
|
|
1493
1618
|
inlineSources.set(abs, body);
|
|
1494
1619
|
entryModuleUrls.push(loadModuleUrl(abs));
|
|
1495
|
-
return `<script${pre}${post}src="__adep_vite_entry_${entryModuleUrls.length - 1}__"><\/script>`;
|
|
1620
|
+
return `<script${pre}${post}src="__adep_vite_entry_${entryModuleUrls.length - 1}__" type="module"><\/script>`;
|
|
1496
1621
|
}
|
|
1497
1622
|
);
|
|
1498
1623
|
const urls = await Promise.all(entryModuleUrls);
|
|
@@ -1516,7 +1641,10 @@ function createViteServer(vfs, options = {}) {
|
|
|
1516
1641
|
lastDoc = doc;
|
|
1517
1642
|
if (currentUrl !== "") revokeObjectURL(currentUrl);
|
|
1518
1643
|
currentUrl = createObjectURL(new Blob([doc], { type: "text/html" }));
|
|
1519
|
-
if (changed)
|
|
1644
|
+
if (changed) {
|
|
1645
|
+
broadcast(currentUrl);
|
|
1646
|
+
options.onDocumentChange?.(currentUrl);
|
|
1647
|
+
}
|
|
1520
1648
|
}
|
|
1521
1649
|
const server = {
|
|
1522
1650
|
get url() {
|
|
@@ -3553,7 +3681,11 @@ function bootstrap(options) {
|
|
|
3553
3681
|
const { createViteServer: createViteServer2 } = await Promise.resolve().then(() => (init_vite_dev(), vite_dev_exports));
|
|
3554
3682
|
const server = createViteServer2(vfs, {
|
|
3555
3683
|
root,
|
|
3556
|
-
...options.viteCompiler === void 0 ? {} : { sfcCompiler: options.viteCompiler }
|
|
3684
|
+
...options.viteCompiler === void 0 ? {} : { sfcCompiler: options.viteCompiler },
|
|
3685
|
+
// PV-006:内容重建 → 以 `serverready`(update: true)事件上报新文档 URL,宿主导出预览产物。
|
|
3686
|
+
onDocumentChange: (url) => {
|
|
3687
|
+
emit("serverready", { port: server.port, url, kind: "vite", root: server.root, update: true });
|
|
3688
|
+
}
|
|
3557
3689
|
});
|
|
3558
3690
|
await server.ready;
|
|
3559
3691
|
viteServer = server;
|
|
@@ -3718,6 +3850,92 @@ init_node_resolve();
|
|
|
3718
3850
|
init_vite_dev();
|
|
3719
3851
|
init_path();
|
|
3720
3852
|
|
|
3853
|
+
// src/bundle-export.ts
|
|
3854
|
+
var BUNDLE_MODULE_PATH_PREFIX = "/_adep/m/";
|
|
3855
|
+
var BLOB_REF_RE = /blob:[^\s"'`<>()\\]+/g;
|
|
3856
|
+
function fnv1a(code) {
|
|
3857
|
+
let hash = 2166136261;
|
|
3858
|
+
for (let i = 0; i < code.length; i++) {
|
|
3859
|
+
hash ^= code.charCodeAt(i);
|
|
3860
|
+
hash = Math.imul(hash, 16777619) >>> 0;
|
|
3861
|
+
}
|
|
3862
|
+
return `${hash.toString(16).padStart(8, "0")}${code.length.toString(16)}`;
|
|
3863
|
+
}
|
|
3864
|
+
async function defaultModuleName(code) {
|
|
3865
|
+
const subtle = globalThis.crypto?.subtle;
|
|
3866
|
+
if (subtle === void 0) return fnv1a(code);
|
|
3867
|
+
const digest = await subtle.digest("SHA-256", new TextEncoder().encode(code));
|
|
3868
|
+
let hex = "";
|
|
3869
|
+
for (const byte of new Uint8Array(digest).slice(0, 8)) {
|
|
3870
|
+
hex += byte.toString(16).padStart(2, "0");
|
|
3871
|
+
}
|
|
3872
|
+
return hex;
|
|
3873
|
+
}
|
|
3874
|
+
function findBlobRefs(text) {
|
|
3875
|
+
const found = text.match(BLOB_REF_RE);
|
|
3876
|
+
return found === null ? [] : [...new Set(found)];
|
|
3877
|
+
}
|
|
3878
|
+
function rewriteRefs(text, urls) {
|
|
3879
|
+
let out = text;
|
|
3880
|
+
for (const [blobUrl, path] of urls) {
|
|
3881
|
+
if (out.includes(blobUrl)) out = out.split(blobUrl).join(path);
|
|
3882
|
+
}
|
|
3883
|
+
return out;
|
|
3884
|
+
}
|
|
3885
|
+
function injectScript(html, script) {
|
|
3886
|
+
return /<\/body>/i.test(html) ? html.replace(/<\/body>/i, `${script}</body>`) : html + script;
|
|
3887
|
+
}
|
|
3888
|
+
async function exportBundle(options) {
|
|
3889
|
+
const readText = options.readText ?? ((url) => fetch(url).then((response) => response.text()));
|
|
3890
|
+
const nameOf = options.moduleName ?? defaultModuleName;
|
|
3891
|
+
const prefix = options.modulePathPrefix ?? BUNDLE_MODULE_PATH_PREFIX;
|
|
3892
|
+
const uploaded = new Set(options.known === void 0 ? [] : [...options.known.values()]);
|
|
3893
|
+
const urls = /* @__PURE__ */ new Map();
|
|
3894
|
+
const sources = [];
|
|
3895
|
+
const readOrThrow = async (url) => {
|
|
3896
|
+
try {
|
|
3897
|
+
return await readText(url);
|
|
3898
|
+
} catch (error) {
|
|
3899
|
+
throw new Error(
|
|
3900
|
+
`\u9884\u89C8\u4EA7\u7269\u5BFC\u51FA\u5931\u8D25\uFF1A\u8BFB\u4E0D\u5230\u6A21\u5757 ${url}\uFF08${error instanceof Error ? error.message : String(error)}\uFF09`,
|
|
3901
|
+
{ cause: error }
|
|
3902
|
+
);
|
|
3903
|
+
}
|
|
3904
|
+
};
|
|
3905
|
+
const html = await readOrThrow(options.documentUrl);
|
|
3906
|
+
const loadLayer = async (layer) => {
|
|
3907
|
+
const batch = [...new Set(layer)].filter((url) => !urls.has(url));
|
|
3908
|
+
if (batch.length === 0) return;
|
|
3909
|
+
const loaded = await Promise.all(
|
|
3910
|
+
batch.map(async (url) => {
|
|
3911
|
+
const code = await readOrThrow(url);
|
|
3912
|
+
return { url, code, path: `${prefix}${await nameOf(code)}.js` };
|
|
3913
|
+
})
|
|
3914
|
+
);
|
|
3915
|
+
const next = [];
|
|
3916
|
+
for (const item of loaded) {
|
|
3917
|
+
urls.set(item.url, item.path);
|
|
3918
|
+
sources.push({ url: item.url, code: item.code });
|
|
3919
|
+
next.push(...findBlobRefs(item.code));
|
|
3920
|
+
}
|
|
3921
|
+
await loadLayer(next);
|
|
3922
|
+
};
|
|
3923
|
+
await loadLayer(findBlobRefs(html));
|
|
3924
|
+
const modules = {};
|
|
3925
|
+
for (const { url, code } of sources) {
|
|
3926
|
+
const path = urls.get(url);
|
|
3927
|
+
if (uploaded.has(path)) continue;
|
|
3928
|
+
modules[path] = rewriteRefs(code, urls);
|
|
3929
|
+
}
|
|
3930
|
+
const rewrittenHtml = rewriteRefs(html, urls);
|
|
3931
|
+
return {
|
|
3932
|
+
html: options.appendScript === void 0 ? rewrittenHtml : injectScript(rewrittenHtml, options.appendScript),
|
|
3933
|
+
modules,
|
|
3934
|
+
paths: [...new Set(urls.values())].toSorted(),
|
|
3935
|
+
urls
|
|
3936
|
+
};
|
|
3937
|
+
}
|
|
3938
|
+
|
|
3721
3939
|
// src/persistence.ts
|
|
3722
3940
|
function cloneEntries(entries) {
|
|
3723
3941
|
return entries.map(
|
|
@@ -4459,6 +4677,8 @@ var CHAIN_CAPABILITY_KEY = "__adepChain";
|
|
|
4459
4677
|
var DB_RPC = {
|
|
4460
4678
|
/** 直通方法(如 query):`(method=query, args=[sql, params])`。 */
|
|
4461
4679
|
query: "query",
|
|
4680
|
+
/** 写路径(CF-013):`(method=writeQuery, args=[sql, params])` → `{ changes }`。 */
|
|
4681
|
+
writeQuery: "writeQuery",
|
|
4462
4682
|
/** 读取 owned 表变更流(DB-006):`(method=changes, args=[table, query])`。 */
|
|
4463
4683
|
changes: "changes",
|
|
4464
4684
|
/** 开启事务:`begin → txId`。 */
|
|
@@ -4535,21 +4755,35 @@ function unsafeOperation(message) {
|
|
|
4535
4755
|
function stripLiterals(sql) {
|
|
4536
4756
|
return sql.replace(/'[^']*(?:''[^']*)*'/g, "").replace(/"[^"]*(?:""[^"]*)*"/g, "").replace(/--[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
4537
4757
|
}
|
|
4538
|
-
function
|
|
4758
|
+
function sqlHead(sql) {
|
|
4759
|
+
return sql.trim().replace(/^\(+/, "").trim().toUpperCase();
|
|
4760
|
+
}
|
|
4761
|
+
function assertSafeStatement(sql) {
|
|
4539
4762
|
const stripped = stripLiterals(sql);
|
|
4540
4763
|
if (stripped.includes(";")) {
|
|
4541
4764
|
throw unsafeOperation("\u4EC5\u5141\u8BB8\u5355\u6761\u8BED\u53E5\uFF0C\u7981\u6B62\u591A\u8BED\u53E5\u5806\u53E0");
|
|
4542
4765
|
}
|
|
4543
|
-
const head = stripped.trim().replace(/^\(+/, "").trim().toUpperCase();
|
|
4544
|
-
if (!head.startsWith("SELECT") && !head.startsWith("WITH")) {
|
|
4545
|
-
throw unsafeOperation("cloud.db.query \u4EC5\u5141\u8BB8\u53EA\u8BFB\u67E5\u8BE2\uFF08SELECT / WITH\uFF09");
|
|
4546
|
-
}
|
|
4547
4766
|
if (/ATTACH|DETACH/.test(stripped.toUpperCase())) {
|
|
4548
4767
|
throw unsafeOperation("\u7981\u6B62\u8DE8\u5E93\u64CD\u4F5C\uFF08ATTACH / DETACH\uFF09");
|
|
4549
4768
|
}
|
|
4550
4769
|
if (/SQLITE_\w+/i.test(stripped)) {
|
|
4551
4770
|
throw unsafeOperation("\u7981\u6B62\u8BBF\u95EE\u7CFB\u7EDF\u8868\uFF08sqlite_*\uFF09");
|
|
4552
4771
|
}
|
|
4772
|
+
return sqlHead(stripped);
|
|
4773
|
+
}
|
|
4774
|
+
function assertReadOnlyQuery(sql) {
|
|
4775
|
+
const head = assertSafeStatement(sql);
|
|
4776
|
+
if (!head.startsWith("SELECT") && !head.startsWith("WITH")) {
|
|
4777
|
+
throw unsafeOperation("cloud.db.query \u4EC5\u5141\u8BB8\u53EA\u8BFB\u67E5\u8BE2\uFF08SELECT / WITH\uFF09");
|
|
4778
|
+
}
|
|
4779
|
+
}
|
|
4780
|
+
function assertWriteQuery(sql) {
|
|
4781
|
+
const head = assertSafeStatement(sql);
|
|
4782
|
+
if (!head.startsWith("INSERT") && !head.startsWith("UPDATE") && !head.startsWith("DELETE")) {
|
|
4783
|
+
throw unsafeOperation(
|
|
4784
|
+
"cloud.db.writeQuery \u4EC5\u5141\u8BB8 DML\uFF08INSERT / UPDATE / DELETE\uFF09\uFF0CDDL \u8BF7\u8D70\u63A7\u5236\u53F0"
|
|
4785
|
+
);
|
|
4786
|
+
}
|
|
4553
4787
|
}
|
|
4554
4788
|
|
|
4555
4789
|
// ../runtime/src/database/builder/owned.ts
|
|
@@ -5095,6 +5329,14 @@ function createCloudDb(driver, options = {}) {
|
|
|
5095
5329
|
assertReadOnlyQuery(sql);
|
|
5096
5330
|
return driver.all(sql, params);
|
|
5097
5331
|
},
|
|
5332
|
+
async writeQuery(sql, params) {
|
|
5333
|
+
if (!Array.isArray(params)) {
|
|
5334
|
+
throw unsafeOperation("writeQuery \u7684 params \u5FC5\u987B\u63D0\u4F9B\uFF08\u65E0\u53C2\u4F20 []\uFF09");
|
|
5335
|
+
}
|
|
5336
|
+
guardWrite();
|
|
5337
|
+
assertWriteQuery(sql);
|
|
5338
|
+
return driver.run(sql, params);
|
|
5339
|
+
},
|
|
5098
5340
|
async changes(table, query = {}) {
|
|
5099
5341
|
return readChanges(driver, table, query);
|
|
5100
5342
|
}
|
|
@@ -5110,7 +5352,8 @@ var CLOUD_DB_SPEC = {
|
|
|
5110
5352
|
rootMethod: "table",
|
|
5111
5353
|
stepMethods: ["select", "where", "orderBy", "limit", "offset"],
|
|
5112
5354
|
terminalMethods: ["get", "first", "count", "insert", "insertMany", "update", "delete"],
|
|
5113
|
-
|
|
5355
|
+
// CF-013:writeQuery 是 D1 shim 的写路径(INSERT/UPDATE/DELETE),与 query 并列直通方法。
|
|
5356
|
+
directMethods: ["query", "writeQuery", "changes"],
|
|
5114
5357
|
transactionMethod: "transaction"
|
|
5115
5358
|
};
|
|
5116
5359
|
var WRITE_TERMINALS = /* @__PURE__ */ new Set(["insert", "insertMany", "update", "delete"]);
|
|
@@ -5165,6 +5408,10 @@ function createDbCapability(driver, options = {}) {
|
|
|
5165
5408
|
const [sql, params] = args;
|
|
5166
5409
|
return await db.query(sql, params);
|
|
5167
5410
|
}
|
|
5411
|
+
case DB_RPC.writeQuery: {
|
|
5412
|
+
const [sql, params] = args;
|
|
5413
|
+
return await db.writeQuery(sql, params);
|
|
5414
|
+
}
|
|
5168
5415
|
case DB_RPC.changes: {
|
|
5169
5416
|
const [table, query] = args;
|
|
5170
5417
|
return await db.changes(table, query);
|
|
@@ -5450,6 +5697,17 @@ var SimSqlEngine = class {
|
|
|
5450
5697
|
}
|
|
5451
5698
|
return { changes: 0 };
|
|
5452
5699
|
}
|
|
5700
|
+
if (/^CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?/i.test(stmt)) {
|
|
5701
|
+
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(
|
|
5702
|
+
stmt
|
|
5703
|
+
);
|
|
5704
|
+
if (idx === null) throw new SimDbError("DB_UNSAFE_OP", `\u65E0\u6CD5\u89E3\u6790 CREATE INDEX \u8BED\u53E5`);
|
|
5705
|
+
const tableName = ident(idx[3]);
|
|
5706
|
+
if (this.tables[tableName] === void 0) {
|
|
5707
|
+
throw new SimDbError("DB_UNSAFE_OP", `CREATE INDEX \u76EE\u6807\u8868\u4E0D\u5B58\u5728\uFF1A${tableName}`);
|
|
5708
|
+
}
|
|
5709
|
+
return { changes: 0 };
|
|
5710
|
+
}
|
|
5453
5711
|
if (/^INSERT\s+INTO/i.test(stmt)) return this.execInsert(stmt, params);
|
|
5454
5712
|
if (/^UPDATE\s+/i.test(stmt)) return this.execUpdate(stmt, params);
|
|
5455
5713
|
if (/^DELETE\s+FROM/i.test(stmt)) return this.execDelete(stmt, params);
|
|
@@ -5694,6 +5952,19 @@ function assertSafeStoragePath(path) {
|
|
|
5694
5952
|
}
|
|
5695
5953
|
return path;
|
|
5696
5954
|
}
|
|
5955
|
+
function assertStoragePrefix(prefix) {
|
|
5956
|
+
if (prefix !== void 0 && prefix !== "") {
|
|
5957
|
+
const segments = prefix.split("/");
|
|
5958
|
+
if (prefix.startsWith("/") || /[\\]/.test(prefix) || segments.some((segment) => segment === "..")) {
|
|
5959
|
+
throw new StorageError(
|
|
5960
|
+
400,
|
|
5961
|
+
STORAGE_CODES.invalidPath,
|
|
5962
|
+
`\u975E\u6CD5\u524D\u7F00 "${prefix}"\uFF08\u7981\u6B62 / \u5F00\u5934\u3001\u53CD\u659C\u6760\u6216 .. \u7A7F\u8D8A\uFF09`
|
|
5963
|
+
);
|
|
5964
|
+
}
|
|
5965
|
+
}
|
|
5966
|
+
return prefix ?? "";
|
|
5967
|
+
}
|
|
5697
5968
|
|
|
5698
5969
|
// ../runtime/src/storage/hmac-sha256.ts
|
|
5699
5970
|
var K = new Uint32Array([
|
|
@@ -5894,9 +6165,12 @@ function createStorageCapability(driver, signer, projectId) {
|
|
|
5894
6165
|
const handler = async (method, args) => {
|
|
5895
6166
|
switch (method) {
|
|
5896
6167
|
case "upload": {
|
|
5897
|
-
const [path, data] = args;
|
|
6168
|
+
const [path, data, options] = args;
|
|
5898
6169
|
return toStoredFile(
|
|
5899
|
-
await driver.put(projectId, path, asBytes(data), {
|
|
6170
|
+
await driver.put(projectId, path, asBytes(data), {
|
|
6171
|
+
visibility: DEFAULT_VISIBILITY,
|
|
6172
|
+
...options?.contentType === void 0 ? {} : { contentType: options.contentType }
|
|
6173
|
+
})
|
|
5900
6174
|
);
|
|
5901
6175
|
}
|
|
5902
6176
|
case "get": {
|
|
@@ -6010,16 +6284,7 @@ function createBrowserStorageDriver(options) {
|
|
|
6010
6284
|
await saveBucket(bucket);
|
|
6011
6285
|
},
|
|
6012
6286
|
async list(_projectId, prefix) {
|
|
6013
|
-
|
|
6014
|
-
const segments = prefix.split("/");
|
|
6015
|
-
if (prefix.startsWith("/") || /[\\]/.test(prefix) || segments.some((segment) => segment === "..")) {
|
|
6016
|
-
throw new StorageError(
|
|
6017
|
-
400,
|
|
6018
|
-
STORAGE_CODES.invalidPath,
|
|
6019
|
-
`\u975E\u6CD5\u524D\u7F00 "${prefix}"\uFF08\u7981\u6B62 / \u5F00\u5934\u3001\u53CD\u659C\u6760\u6216 .. \u7A7F\u8D8A\uFF09`
|
|
6020
|
-
);
|
|
6021
|
-
}
|
|
6022
|
-
}
|
|
6287
|
+
assertStoragePrefix(prefix);
|
|
6023
6288
|
const bucket = await loadBucket();
|
|
6024
6289
|
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);
|
|
6025
6290
|
},
|
|
@@ -6343,6 +6608,10 @@ var KNOWN_CAPABILITY_HINTS = {
|
|
|
6343
6608
|
realtime: {
|
|
6344
6609
|
code: "REALTIME_NOT_AVAILABLE",
|
|
6345
6610
|
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"
|
|
6611
|
+
},
|
|
6612
|
+
kv: {
|
|
6613
|
+
code: "KV_NOT_PROVISIONED",
|
|
6614
|
+
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"
|
|
6346
6615
|
}
|
|
6347
6616
|
};
|
|
6348
6617
|
var CapabilityNotRegisteredError = class extends Error {
|
|
@@ -6402,6 +6671,19 @@ function createCloudContainer() {
|
|
|
6402
6671
|
};
|
|
6403
6672
|
}
|
|
6404
6673
|
|
|
6674
|
+
// ../runtime/src/functions/runtime/rpc-wire.ts
|
|
6675
|
+
function wireRpcResponses(port, pending) {
|
|
6676
|
+
port.on?.((message) => {
|
|
6677
|
+
const reply = message;
|
|
6678
|
+
if (reply?.type !== "rpc-response" || typeof reply.id !== "number") return;
|
|
6679
|
+
const entry = pending.get(reply.id);
|
|
6680
|
+
if (entry === void 0) return;
|
|
6681
|
+
pending.delete(reply.id);
|
|
6682
|
+
if (reply.ok === true) entry.resolve(reply.result);
|
|
6683
|
+
else entry.reject(new Error(reply.error ?? "RPC \u80FD\u529B\u8C03\u7528\u5931\u8D25"));
|
|
6684
|
+
});
|
|
6685
|
+
}
|
|
6686
|
+
|
|
6405
6687
|
// src/sim/ctx.ts
|
|
6406
6688
|
function createLocalPort(handler) {
|
|
6407
6689
|
const listeners = [];
|
|
@@ -6431,17 +6713,6 @@ function createLocalPort(handler) {
|
|
|
6431
6713
|
}
|
|
6432
6714
|
};
|
|
6433
6715
|
}
|
|
6434
|
-
function wireRpcResponses(port, pending) {
|
|
6435
|
-
port.on((message) => {
|
|
6436
|
-
const reply = message;
|
|
6437
|
-
if (reply?.type !== "rpc-response" || typeof reply.id !== "number") return;
|
|
6438
|
-
const entry = pending.get(reply.id);
|
|
6439
|
-
if (entry === void 0) return;
|
|
6440
|
-
pending.delete(reply.id);
|
|
6441
|
-
if (reply.ok === true) entry.resolve(reply.result);
|
|
6442
|
-
else entry.reject(new Error(reply.error ?? "RPC \u80FD\u529B\u8C03\u7528\u5931\u8D25"));
|
|
6443
|
-
});
|
|
6444
|
-
}
|
|
6445
6716
|
function createFlatRpcClient(handler) {
|
|
6446
6717
|
return new Proxy(
|
|
6447
6718
|
{},
|
|
@@ -6655,7 +6926,7 @@ function createOfflineFunctionRunner(options = {}) {
|
|
|
6655
6926
|
return { run };
|
|
6656
6927
|
}
|
|
6657
6928
|
|
|
6658
|
-
// src/sim/
|
|
6929
|
+
// ../runtime/src/sim/merge.ts
|
|
6659
6930
|
function mergeBundles(bundles) {
|
|
6660
6931
|
const capabilities = [];
|
|
6661
6932
|
const byName = /* @__PURE__ */ new Map();
|
|
@@ -6675,6 +6946,108 @@ function mergeBundles(bundles) {
|
|
|
6675
6946
|
}
|
|
6676
6947
|
return { capabilities, rpcHandlers };
|
|
6677
6948
|
}
|
|
6949
|
+
|
|
6950
|
+
// ../runtime/src/database/sdk/kv.ts
|
|
6951
|
+
var KV_TABLE = "_adep_kv";
|
|
6952
|
+
var KV_RPC = {
|
|
6953
|
+
get: "get",
|
|
6954
|
+
put: "put",
|
|
6955
|
+
delete: "delete",
|
|
6956
|
+
list: "list"
|
|
6957
|
+
};
|
|
6958
|
+
var KV_CAPABILITY_CODES = {
|
|
6959
|
+
invalidMethod: "KV_INVALID_METHOD"
|
|
6960
|
+
};
|
|
6961
|
+
var KV_LIST_DEFAULT_LIMIT = 100;
|
|
6962
|
+
function nowSeconds() {
|
|
6963
|
+
return Math.floor(Date.now() / 1e3);
|
|
6964
|
+
}
|
|
6965
|
+
function errorWithCode2(error) {
|
|
6966
|
+
const code = typeof error === "object" && error !== null && typeof error.code === "string" ? error.code : void 0;
|
|
6967
|
+
if (code !== void 0 && error instanceof Error) {
|
|
6968
|
+
return new Error(`[${code}] ${error.message}`);
|
|
6969
|
+
}
|
|
6970
|
+
return error;
|
|
6971
|
+
}
|
|
6972
|
+
function createKvCapability(driver) {
|
|
6973
|
+
let ensurePromise = null;
|
|
6974
|
+
const ensureTable = () => {
|
|
6975
|
+
if (ensurePromise === null) {
|
|
6976
|
+
ensurePromise = driver.run(
|
|
6977
|
+
`CREATE TABLE IF NOT EXISTS ${KV_TABLE} (key TEXT PRIMARY KEY, value TEXT, expires_at INTEGER)`
|
|
6978
|
+
).then(() => void 0);
|
|
6979
|
+
}
|
|
6980
|
+
return ensurePromise;
|
|
6981
|
+
};
|
|
6982
|
+
const handler = async (method, args) => {
|
|
6983
|
+
try {
|
|
6984
|
+
await ensureTable();
|
|
6985
|
+
switch (method) {
|
|
6986
|
+
case KV_RPC.get: {
|
|
6987
|
+
const [key] = args;
|
|
6988
|
+
const row = await driver.get(`SELECT value, expires_at FROM ${KV_TABLE} WHERE key = ?`, [
|
|
6989
|
+
key
|
|
6990
|
+
]);
|
|
6991
|
+
if (row === null || row === void 0) return null;
|
|
6992
|
+
const expiresAt = row.expires_at;
|
|
6993
|
+
if (expiresAt !== null && expiresAt !== void 0 && Number(expiresAt) <= nowSeconds()) {
|
|
6994
|
+
return null;
|
|
6995
|
+
}
|
|
6996
|
+
return row.value;
|
|
6997
|
+
}
|
|
6998
|
+
case KV_RPC.put: {
|
|
6999
|
+
const [key, value, options] = args;
|
|
7000
|
+
const ttl = options?.expirationTtlSeconds;
|
|
7001
|
+
const expiresAt = typeof ttl === "number" && ttl > 0 ? nowSeconds() + Math.floor(ttl) : null;
|
|
7002
|
+
await driver.run(`DELETE FROM ${KV_TABLE} WHERE key = ?`, [key]);
|
|
7003
|
+
await driver.run(`INSERT INTO ${KV_TABLE} (key, value, expires_at) VALUES (?, ?, ?)`, [
|
|
7004
|
+
key,
|
|
7005
|
+
value,
|
|
7006
|
+
expiresAt
|
|
7007
|
+
]);
|
|
7008
|
+
return void 0;
|
|
7009
|
+
}
|
|
7010
|
+
case KV_RPC.delete: {
|
|
7011
|
+
const [key] = args;
|
|
7012
|
+
await driver.run(`DELETE FROM ${KV_TABLE} WHERE key = ?`, [key]);
|
|
7013
|
+
return void 0;
|
|
7014
|
+
}
|
|
7015
|
+
case KV_RPC.list: {
|
|
7016
|
+
const [options] = args;
|
|
7017
|
+
const prefix = options?.prefix ?? "";
|
|
7018
|
+
const limit = options?.limit ?? KV_LIST_DEFAULT_LIMIT;
|
|
7019
|
+
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 ?`, [
|
|
7020
|
+
`${prefix}%`
|
|
7021
|
+
]);
|
|
7022
|
+
const now = nowSeconds();
|
|
7023
|
+
const entries = [];
|
|
7024
|
+
for (const row of rows) {
|
|
7025
|
+
const expiresAt = row.expires_at;
|
|
7026
|
+
if (expiresAt !== null && expiresAt !== void 0 && Number(expiresAt) <= now) continue;
|
|
7027
|
+
entries.push({
|
|
7028
|
+
name: String(row.key),
|
|
7029
|
+
expiration: expiresAt === null || expiresAt === void 0 ? null : Number(expiresAt)
|
|
7030
|
+
});
|
|
7031
|
+
if (entries.length >= limit) break;
|
|
7032
|
+
}
|
|
7033
|
+
return entries;
|
|
7034
|
+
}
|
|
7035
|
+
default:
|
|
7036
|
+
throw new Error(
|
|
7037
|
+
`\u672A\u77E5\u7684 cloud.kv \u65B9\u6CD5 "${String(method)}"\uFF08${KV_CAPABILITY_CODES.invalidMethod}\uFF09`
|
|
7038
|
+
);
|
|
7039
|
+
}
|
|
7040
|
+
} catch (error) {
|
|
7041
|
+
throw errorWithCode2(error);
|
|
7042
|
+
}
|
|
7043
|
+
};
|
|
7044
|
+
return {
|
|
7045
|
+
capabilities: [{ name: "kv", value: { [RPC_CAPABILITY_KEY]: true } }],
|
|
7046
|
+
rpcHandlers: { kv: handler }
|
|
7047
|
+
};
|
|
7048
|
+
}
|
|
7049
|
+
|
|
7050
|
+
// src/sim/runtime.ts
|
|
6678
7051
|
async function createBrowserSimRuntime(options) {
|
|
6679
7052
|
const kv = options.kv ?? pickDefaultSimKv();
|
|
6680
7053
|
const db = createBrowserSimDb({ projectId: options.projectId, kv });
|
|
@@ -6689,7 +7062,8 @@ async function createBrowserSimRuntime(options) {
|
|
|
6689
7062
|
projectId: options.projectId,
|
|
6690
7063
|
...options.realtime === void 0 ? {} : options.realtime
|
|
6691
7064
|
});
|
|
6692
|
-
const
|
|
7065
|
+
const kvBundle = createKvCapability(db.driver);
|
|
7066
|
+
const bundle = mergeBundles([db.bundle, storage.bundle, kvBundle, realtime.bundle]);
|
|
6693
7067
|
await db.engine.load();
|
|
6694
7068
|
const runner = createOfflineFunctionRunner(options.runner ?? {});
|
|
6695
7069
|
return {
|
|
@@ -6705,6 +7079,7 @@ async function createBrowserSimRuntime(options) {
|
|
|
6705
7079
|
// src/index.ts
|
|
6706
7080
|
init_function_fetch_proxy();
|
|
6707
7081
|
export {
|
|
7082
|
+
BUNDLE_MODULE_PATH_PREFIX,
|
|
6708
7083
|
COMPLETABLE_COMMANDS,
|
|
6709
7084
|
DEFAULT_MAX_INSTALL_DEPTH,
|
|
6710
7085
|
EXTRA_COMMANDS,
|
|
@@ -6750,12 +7125,15 @@ export {
|
|
|
6750
7125
|
createViteServer,
|
|
6751
7126
|
createWorkerRuntime,
|
|
6752
7127
|
deepEqual,
|
|
7128
|
+
defaultModuleName,
|
|
6753
7129
|
displayPath,
|
|
6754
7130
|
entriesToTree,
|
|
6755
7131
|
evaluateModuleSource,
|
|
6756
7132
|
evaluateSource,
|
|
6757
7133
|
exampleTestSource,
|
|
6758
7134
|
expect as expectAssertion,
|
|
7135
|
+
exportBundle,
|
|
7136
|
+
findBlobRefs,
|
|
6759
7137
|
formatTestReport,
|
|
6760
7138
|
formatValue,
|
|
6761
7139
|
fullName,
|