@adep/web-container 0.2.2 → 0.2.4

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.
@@ -147,8 +147,17 @@ var AdepWebContainer = (() => {
147
147
  if (typeof exp !== "object" || Array.isArray(exp)) {
148
148
  throw new ResolveError(`${context} \u5F62\u6001\u4E0D\u652F\u6301\uFF08exports \u53EA\u80FD\u662F\u5B57\u7B26\u4E32\u6216\u5BF9\u8C61\uFF09`);
149
149
  }
150
- const dot = exp["."];
150
+ const table = exp;
151
+ const dot = table["."];
152
+ const order = condition === "import" ? IMPORT_CONDITION_ORDER : REQUIRE_CONDITION_ORDER;
153
+ const resolveRel = (rel) => withinPackage(pkgDirAbs, rel, context);
151
154
  if (dot === void 0) {
155
+ const keys = Object.keys(table);
156
+ if (keys.length > 0 && keys.every((key) => !key.startsWith("."))) {
157
+ const shorthand = pickConditionTarget(table, order, resolveRel, context);
158
+ if (shorthand !== null) return shorthand;
159
+ throw new ResolveError(`${context}\uFF1A\u5305\u6839\u6761\u4EF6\u5BF9\u8C61\u91CC\u6CA1\u6709 ${order.join("/")} \u5165\u53E3`);
160
+ }
152
161
  throw new ResolveError(
153
162
  `${context} \u53EA\u58F0\u660E\u4E86\u5B50\u8DEF\u5F84\u6620\u5C04\u3001\u6CA1\u6709 "." \u5165\u53E3\uFF0C\u5F53\u524D\u4EC5\u652F\u6301 "." \u4E0E\u5B57\u7B26\u4E32\u5F62\u6001`
154
163
  );
@@ -159,8 +168,6 @@ var AdepWebContainer = (() => {
159
168
  if (typeof dot !== "object" || Array.isArray(dot)) {
160
169
  throw new ResolveError(`${context}\uFF1Aexports["."] \u5F62\u6001\u4E0D\u652F\u6301\uFF08\u4EC5\u63A5\u53D7\u5B57\u7B26\u4E32\u6216\u6761\u4EF6\u5BF9\u8C61\uFF09`);
161
170
  }
162
- const order = condition === "import" ? IMPORT_CONDITION_ORDER : REQUIRE_CONDITION_ORDER;
163
- const resolveRel = (rel) => withinPackage(pkgDirAbs, rel, context);
164
171
  const hit = pickConditionTarget(dot, order, resolveRel, context);
165
172
  if (hit !== null) return hit;
166
173
  throw new ResolveError(`${context}\uFF1Aexports["."] \u6761\u4EF6\u5BF9\u8C61\u91CC\u6CA1\u6709 ${order.join("/")} \u5165\u53E3`);
@@ -359,6 +366,28 @@ var AdepWebContainer = (() => {
359
366
  }
360
367
  return "";
361
368
  }
369
+ /**
370
+ * `interface` / `type` 声明之前若有 `export` 关键字,返回该关键字的起始下标,否则原样返回。
371
+ *
372
+ * 为什么必须吞掉:`export interface X { … }` 里 `interface` 分支只擦它自己那一段,
373
+ * 留下的孤立 `export` 是**非法 JS**——浏览器解析模块时直接
374
+ * `SyntaxError: Unexpected token 'export'`(实测 countdown 项目 `lib/auth.ts` 的
375
+ * `export interface AppUser`:整条预览链路因此白屏)。`export type X = …` 由 `export`
376
+ * 分支整条擦除,不受影响。
377
+ *
378
+ * 判据分两步:token 回看确认前一个显著 token 就是 `export`(避免误吞 `re-export` 之类
379
+ * 同名标识符——那会在下面按字符再校验一次);位置则往前跳空白后左推 6 个字符,并要求
380
+ * 再前一个字符不是标识符字符(`xexport interface` 不吞)。
381
+ */
382
+ includeLeadingExport(start) {
383
+ if (this.tokenAt(2) !== "export") return start;
384
+ let end = start - 1;
385
+ while (end >= 0 && /\s/.test(this.src[end])) end--;
386
+ if (end < 5 || this.src.slice(end - 5, end + 1) !== "export") return start;
387
+ const before = this.src[end - 6];
388
+ if (before !== void 0 && IDENT_PART.test(before)) return start;
389
+ return end - 5;
390
+ }
362
391
  /** 擦除 `[from, to)`:填等长空格,换行照抄——擦完行号与原文件一致。 */
363
392
  erase(from, to) {
364
393
  for (let j = Math.max(from, 0); j < to; j++) this.chars[j] = this.src[j] === "\n" ? "\n" : " ";
@@ -498,19 +527,31 @@ var AdepWebContainer = (() => {
498
527
  }
499
528
  switch (word) {
500
529
  case "interface": {
501
- const after = this.skipWhitespaceFrom(this.skipNameAndParams(start + word.length));
530
+ const heritage = this.skipInterfaceExtends(this.skipNameAndParams(start + word.length));
531
+ const after = heritage === null ? null : this.skipWhitespaceFrom(heritage);
502
532
  if (after === null || this.src[after] !== "{") return;
503
533
  const end = this.scanBalanced(after, "{", "}");
504
- this.erase(start, end);
534
+ this.erase(this.includeLeadingExport(start), end);
505
535
  this.i = end;
506
536
  this.pushToken("erased");
507
537
  return;
508
538
  }
509
539
  case "type": {
540
+ if (this.frames[this.frames.length - 1]?.specifierList === true) {
541
+ const specifierEnd = this.scanTypeOnlySpecifier(this.i);
542
+ if (specifierEnd !== null) {
543
+ this.erase(start, specifierEnd);
544
+ this.i = specifierEnd;
545
+ } else {
546
+ this.erase(start, start + word.length);
547
+ }
548
+ this.pushToken("erased");
549
+ return;
550
+ }
510
551
  const after = this.skipWhitespaceFrom(this.skipNameAndParams(this.i));
511
552
  if (after === null || this.src[after] !== "=") return;
512
553
  const end = this.scanTypeExpression(after + 1, true);
513
- this.erase(start, end);
554
+ this.erase(this.includeLeadingExport(start), end);
514
555
  this.i = end;
515
556
  this.pushToken("erased");
516
557
  return;
@@ -537,16 +578,20 @@ var AdepWebContainer = (() => {
537
578
  this.pushToken("erased");
538
579
  return;
539
580
  }
540
- case "class":
541
- this.pendingClassBody = true;
581
+ case "class": {
582
+ const next = this.skipWhitespaceFrom(this.i);
583
+ if (next !== null && (this.src[next] === "{" || IDENT_START.test(this.src[next]))) {
584
+ this.pendingClassBody = true;
585
+ }
542
586
  return;
587
+ }
543
588
  case "as":
544
589
  case "satisfies": {
545
590
  if (this.frames[this.frames.length - 1]?.specifierList === true) return;
546
591
  if (this.tokenAt(2) === "*" || this.tokenAt(2) === "type") return;
547
592
  const nextChar = this.skipWhitespaceFrom(this.i);
548
593
  if (nextChar === null || "=,:]})".includes(this.src[nextChar])) return;
549
- const end = this.scanTypeExpression(this.i, false);
594
+ const end = this.scanTypeExpression(this.i, true);
550
595
  this.erase(start, end);
551
596
  this.i = end;
552
597
  return;
@@ -682,6 +727,62 @@ var AdepWebContainer = (() => {
682
727
  this.i = end;
683
728
  return true;
684
729
  }
730
+ /**
731
+ * `interface X extends A, B<T> {` 的继承子句:返回接口体 `{` 的下标。
732
+ *
733
+ * 不处理 `extends` 会让 `interface` 分支取不到 `{` 而**整条不擦**——`export interface
734
+ * DecodedEvent extends CountdownEvent { … }` 原样留在产物里,浏览器解析即
735
+ * `SyntaxError: Unexpected token 'export'`(实测 countdown 的 lib/date.ts;同项目两个
736
+ * `.vue` 产物是它的级联失败)。无 `extends` 时原样返回入参(等价旧行为);遇到字符串 /
737
+ * 配不平的泛型一律返回 null(判不准就不擦)。
738
+ */
739
+ skipInterfaceExtends(from) {
740
+ if (from === null) return null;
741
+ const j = this.skipWhitespaceFrom(from);
742
+ if (j === null || !this.src.startsWith("extends", j) || IDENT_PART.test(this.src[j + 7] ?? "")) {
743
+ return j;
744
+ }
745
+ let k = this.skipWhitespaceFrom(j + 7);
746
+ while (k !== null) {
747
+ const c = this.src[k];
748
+ if (c === "{" || c === ";") return k;
749
+ if (c === "<") {
750
+ const end = this.scanTypeParams(k);
751
+ if (end === null) return null;
752
+ k = end;
753
+ continue;
754
+ }
755
+ if (c === "'" || c === '"' || c === "`") return null;
756
+ k = this.skipWhitespaceFrom(k + 1);
757
+ }
758
+ return null;
759
+ }
760
+ /**
761
+ * 「仅类型说明符」`type X [as Y]` 的擦除终点(返回应擦到、不含的下标)。
762
+ *
763
+ * - `type` 之后不是标识符 → null(调用方退化为只擦关键字,不猜);
764
+ * - 连带**其后的**逗号一起擦(`{ type A, b }` → `{ b }`);末位说明符没有逗号,
765
+ * 留下的 `{ a, }` 是合法尾逗号,无需回首删前导逗号;
766
+ * - `as Y` 重命名一并擦除(只影响类型侧,运行时无绑定)。
767
+ */
768
+ scanTypeOnlySpecifier(from) {
769
+ let j = this.skipWhitespaceFrom(from);
770
+ if (j === null || !IDENT_START.test(this.src[j])) return null;
771
+ j++;
772
+ while (j < this.src.length && IDENT_PART.test(this.src[j])) j++;
773
+ const asAt = this.skipWhitespaceFrom(j);
774
+ if (asAt !== null && this.src.startsWith("as", asAt) && !IDENT_PART.test(this.src[asAt + 2] ?? "")) {
775
+ const nameAt = this.skipWhitespaceFrom(asAt + 2);
776
+ if (nameAt !== null && IDENT_START.test(this.src[nameAt])) {
777
+ let k = nameAt + 1;
778
+ while (k < this.src.length && IDENT_PART.test(this.src[k])) k++;
779
+ j = k;
780
+ }
781
+ }
782
+ const next = this.skipWhitespaceFrom(j);
783
+ if (next !== null && this.src[next] === ",") return next + 1;
784
+ return j;
785
+ }
685
786
  /**
686
787
  * `{` 是 import / export 的说明符列表吗——`{ a as b }` 覆盖 `import { … }`、
687
788
  * `export { … }` 与 `import def, { … }` 三种写法(后者说明符花括号的前驱 token 是 `,`)。
@@ -692,8 +793,8 @@ var AdepWebContainer = (() => {
692
793
  return back1 === "," && this.tokenAt(3) === "import";
693
794
  }
694
795
  /**
695
- * `(` 是否为参数列表(声明位):`function f(`、类体里的方法 `m(`、箭头 `=> (`,
696
- * 以及出现在 `(` `,` `=` `>` `:` `[` `{` `}` `;` 之后(如 `map((v: T) => v)` 的内层括号)。
796
+ * `(` 是否为参数列表(声明位):`function f(`、`async` 箭头 `async (`、类体里的方法 `m(`、
797
+ * 箭头 `=> (`,以及出现在 `(` `,` `=` `>` `:` `[` `{` `}` `;` 之后(如 `map((v: T) => v)` 的内层括号)。
697
798
  * 调用位 `foo(` 与控制流 `if (` `for (` 都不算。
698
799
  * 误判成声明位也不足以擦掉什么:`:` 还要过 `isAnnotationColon` 的「名字前驱必须是
699
800
  * `(` `,` `{` `;` 修饰符」这一关,而三元表达式的中间段前面必然是 `?`。
@@ -702,6 +803,7 @@ var AdepWebContainer = (() => {
702
803
  if (this.afterFunctionKeyword) return true;
703
804
  if (this.tokenAt(2) === "function" && IDENT_START.test(this.tokenAt(1))) return true;
704
805
  if (this.afterArrow) return true;
806
+ if (this.tokenAt(1) === "async") return true;
705
807
  if (this.tokenAt(1) === "return") return true;
706
808
  if (this.inClassBody() && IDENT_PART.test(this.prevSignificantChar(at - 1))) return true;
707
809
  const prev = this.prevSignificantChar(at - 1);
@@ -741,7 +843,7 @@ var AdepWebContainer = (() => {
741
843
  const generic = this.scanTypeParams(j);
742
844
  return generic === null ? j : generic;
743
845
  }
744
- /** `<T, U extends X>`:返回 `>` 之后的下标;跨到 `)` `]` `;` 换行前配不平则 null。 */
846
+ /** `<T, U extends X>`:返回 `>` 之后的下标;尖括号内任何非 `<`/`>` 字符(含 `]` `;` `\n` `)`)都是合法类型字符,配不平自然到文件尾返回 null。 */
745
847
  scanTypeParams(from) {
746
848
  if (this.src[from] !== "<") return null;
747
849
  let depth = 0;
@@ -752,8 +854,7 @@ var AdepWebContainer = (() => {
752
854
  else if (c === ">") {
753
855
  depth--;
754
856
  if (depth === 0) return j + 1;
755
- } else if (c === ")" || c === "]" || c === ";" || c === "\n") return null;
756
- else if (c === "'" || c === '"') j = this.scanQuoted(j) - 1;
857
+ } else if (c === "'" || c === '"') j = this.scanQuoted(j) - 1;
757
858
  else if (c === "`") j = this.scanTemplate(j) - 1;
758
859
  }
759
860
  return null;
@@ -885,13 +986,14 @@ var AdepWebContainer = (() => {
885
986
  /**
886
987
  * 行尾处类型是否仍在继续:`type Id = string\n | number` 要接得上,
887
988
  * 而 `const x: Foo\nconst y = 1` 必须停。判据是两侧的非空邻字——
888
- * 前一个是连接符(`| & < > = , . ? : (`)或后一个是连接符 / 闭合符(`| & , . ? : ) ] } >`)。
989
+ * 前一个是连接符(`| & < = , . ? : (`,不含 `>`——`Foo<T>` 后换行是语句边界,
990
+ * 含 `>` 会把下一行的 `try` 等吞进类型区间)或后一个是连接符 / 闭合符(`| & , . ? : ) ] } >`)。
889
991
  */
890
992
  typeContinuesAt(index) {
891
993
  for (let j = index - 1; j >= 0; j--) {
892
994
  const c = this.src[j];
893
995
  if (/\s/.test(c)) continue;
894
- if ("|&<>=,.?:(".includes(c)) return true;
996
+ if ("|&<=,.?:(".includes(c)) return true;
895
997
  break;
896
998
  }
897
999
  for (let j = index + 1; j < this.src.length; j++) {
@@ -905,6 +1007,206 @@ var AdepWebContainer = (() => {
905
1007
  }
906
1008
  });
907
1009
 
1010
+ // src/css-imports.ts
1011
+ function isLocalSpec(spec) {
1012
+ return spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/");
1013
+ }
1014
+ function skipString(css, start) {
1015
+ const quote = css[start];
1016
+ let i = start + 1;
1017
+ while (i < css.length) {
1018
+ if (css[i] === "\\") {
1019
+ i += 2;
1020
+ continue;
1021
+ }
1022
+ if (css[i] === quote) return i + 1;
1023
+ i++;
1024
+ }
1025
+ return css.length;
1026
+ }
1027
+ function matchParen(text, open) {
1028
+ let depth = 0;
1029
+ let i = open;
1030
+ while (i < text.length) {
1031
+ const ch = text[i];
1032
+ if (ch === '"' || ch === "'") {
1033
+ i = skipString(text, i);
1034
+ continue;
1035
+ }
1036
+ if (ch === "(") depth++;
1037
+ else if (ch === ")") {
1038
+ depth--;
1039
+ if (depth === 0) return i;
1040
+ }
1041
+ i++;
1042
+ }
1043
+ return text.length;
1044
+ }
1045
+ function parseSpecifier(css, from) {
1046
+ let i = from;
1047
+ while (i < css.length && /\s/.test(css[i])) i++;
1048
+ const urlHead = /^url\s*\(/i.exec(css.slice(i, i + 8));
1049
+ if (urlHead !== null) {
1050
+ const open = i + urlHead[0].length - 1;
1051
+ const close = matchParen(css, open);
1052
+ if (close >= css.length) return { spec: null, next: i };
1053
+ const inner = css.slice(open + 1, close).trim();
1054
+ const quoted = inner.startsWith('"') || inner.startsWith("'");
1055
+ return { spec: quoted ? inner.slice(1, -1).trim() : inner, next: close + 1 };
1056
+ }
1057
+ const quote = css[i];
1058
+ if (quote === '"' || quote === "'") {
1059
+ const end = skipString(css, i);
1060
+ if (css[end - 1] !== quote) return { spec: null, next: i };
1061
+ return { spec: css.slice(i + 1, end - 1), next: end };
1062
+ }
1063
+ return { spec: null, next: i };
1064
+ }
1065
+ function parseImport(css, start) {
1066
+ const parsed = parseSpecifier(css, start + IMPORT_KEYWORD.length);
1067
+ if (parsed.spec === null) return null;
1068
+ let j = parsed.next;
1069
+ let depth = 0;
1070
+ while (j < css.length) {
1071
+ const ch = css[j];
1072
+ if (ch === '"' || ch === "'") {
1073
+ j = skipString(css, j);
1074
+ continue;
1075
+ }
1076
+ if (ch === "(") depth++;
1077
+ else if (ch === ")") depth--;
1078
+ else if (ch === ";" && depth <= 0) break;
1079
+ else if (ch === "{" || ch === "}") return null;
1080
+ j++;
1081
+ }
1082
+ if (j >= css.length) return null;
1083
+ return {
1084
+ start,
1085
+ end: j + 1,
1086
+ spec: parsed.spec,
1087
+ conditions: css.slice(parsed.next, j).trim(),
1088
+ raw: css.slice(start, j + 1)
1089
+ };
1090
+ }
1091
+ function scanCssImports(css) {
1092
+ const hits = [];
1093
+ let i = 0;
1094
+ while (i < css.length) {
1095
+ const ch = css[i];
1096
+ if (ch === "/" && css[i + 1] === "*") {
1097
+ const close = css.indexOf("*/", i + 2);
1098
+ i = close === -1 ? css.length : close + 2;
1099
+ continue;
1100
+ }
1101
+ if (ch === '"' || ch === "'") {
1102
+ i = skipString(css, i);
1103
+ continue;
1104
+ }
1105
+ if (ch === "@" && /^@import(?![-\w])/i.test(css.slice(i, i + IMPORT_KEYWORD.length + 1))) {
1106
+ const hit = parseImport(css, i);
1107
+ if (hit !== null) {
1108
+ hits.push(hit);
1109
+ i = hit.end;
1110
+ continue;
1111
+ }
1112
+ }
1113
+ i++;
1114
+ }
1115
+ return hits;
1116
+ }
1117
+ function stripCharset(css) {
1118
+ return css.replace(/^\uFEFF/, "").replace(/^\s*@charset\s+(["'])[^"']*\1\s*;/i, "");
1119
+ }
1120
+ function splitImportConditions(conditions) {
1121
+ let rest = conditions.trim();
1122
+ let layer = null;
1123
+ const layerFn = /^layer\s*\(/i.exec(rest);
1124
+ if (layerFn !== null) {
1125
+ const open = layerFn[0].length - 1;
1126
+ const close = matchParen(rest, open);
1127
+ layer = rest.slice(open + 1, close).trim();
1128
+ rest = rest.slice(close + 1).trim();
1129
+ } else if (/^layer(?![-\w(])/i.test(rest)) {
1130
+ layer = "";
1131
+ rest = rest.slice("layer".length).trim();
1132
+ }
1133
+ let supports = "";
1134
+ const supportsFn = /^supports\s*\(/i.exec(rest);
1135
+ if (supportsFn !== null) {
1136
+ const open = supportsFn[0].length - 1;
1137
+ const close = matchParen(rest, open);
1138
+ supports = rest.slice(open + 1, close).trim();
1139
+ rest = rest.slice(close + 1).trim();
1140
+ }
1141
+ return { layer, supports, media: rest };
1142
+ }
1143
+ function applyImportConditions(css, conditions) {
1144
+ if (conditions === "") return css;
1145
+ const { layer, supports, media } = splitImportConditions(conditions);
1146
+ let out = css;
1147
+ if (supports !== "") out = `@supports ${supports} {
1148
+ ${out}
1149
+ }`;
1150
+ if (layer !== null) out = layer === "" ? `@layer {
1151
+ ${out}
1152
+ }` : `@layer ${layer} {
1153
+ ${out}
1154
+ }`;
1155
+ if (media !== "") out = `@media ${media} {
1156
+ ${out}
1157
+ }`;
1158
+ return out;
1159
+ }
1160
+ function expand(css, importerAbs, resolver, seen) {
1161
+ const hits = scanCssImports(css);
1162
+ if (hits.length === 0) return css;
1163
+ const parts = [];
1164
+ let cursor = 0;
1165
+ for (const hit of hits) {
1166
+ parts.push(css.slice(cursor, hit.start));
1167
+ parts.push(expandHit(hit, importerAbs, resolver, seen));
1168
+ cursor = hit.end;
1169
+ }
1170
+ parts.push(css.slice(cursor));
1171
+ return parts.join("");
1172
+ }
1173
+ function expandHit(hit, importerAbs, resolver, seen) {
1174
+ if (hit.spec === null) return hit.raw;
1175
+ const spec = hit.spec.trim();
1176
+ if (spec === "" || EXTERNAL_SPEC.test(spec)) return hit.raw;
1177
+ const abs = resolver.resolve(spec, importerAbs);
1178
+ if (abs === null) {
1179
+ if (isLocalSpec(spec))
1180
+ throw new CssImportError(
1181
+ `CSS @import \u627E\u4E0D\u5230\u6587\u4EF6 "${spec}"\uFF08\u5728 ${importerAbs} \u4E2D\uFF09\u2014\u2014\u76F8\u5BF9\u8DEF\u5F84\u6309\u8BE5\u6587\u4EF6\u7684\u6240\u5728\u76EE\u5F55\u89E3\u6790\uFF0C\u8BF7\u68C0\u67E5\u8DEF\u5F84\u662F\u5426\u6B63\u786E\u3002`
1182
+ );
1183
+ return hit.raw;
1184
+ }
1185
+ if (!abs.toLowerCase().endsWith(".css")) return hit.raw;
1186
+ if (seen.has(abs)) return "";
1187
+ seen.add(abs);
1188
+ const source = resolver.read(abs);
1189
+ if (source === null) return hit.raw;
1190
+ return applyImportConditions(expand(stripCharset(source), abs, resolver, seen), hit.conditions);
1191
+ }
1192
+ function inlineCssImports(css, importerAbs, resolver) {
1193
+ return expand(css, importerAbs, resolver, /* @__PURE__ */ new Set([importerAbs]));
1194
+ }
1195
+ var CssImportError, IMPORT_KEYWORD, EXTERNAL_SPEC;
1196
+ var init_css_imports = __esm({
1197
+ "src/css-imports.ts"() {
1198
+ "use strict";
1199
+ CssImportError = class extends Error {
1200
+ constructor(message) {
1201
+ super(message);
1202
+ this.name = "CssImportError";
1203
+ }
1204
+ };
1205
+ IMPORT_KEYWORD = "@import";
1206
+ EXTERNAL_SPEC = /^(?:[A-Za-z][A-Za-z0-9+.-]*:|\/\/)/i;
1207
+ }
1208
+ });
1209
+
908
1210
  // src/preview-server.ts
909
1211
  var preview_server_exports = {};
910
1212
  __export(preview_server_exports, {
@@ -918,6 +1220,20 @@ var AdepWebContainer = (() => {
918
1220
  if (!vfs.exists(abs) || vfs.isDirectory(abs)) return null;
919
1221
  return abs;
920
1222
  }
1223
+ function cssResolverOf(vfs) {
1224
+ return {
1225
+ read: (abs) => vfs.exists(abs) && !vfs.isDirectory(abs) ? vfs.readFile(abs) : null,
1226
+ resolve: (spec, importerAbs) => {
1227
+ if (spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/"))
1228
+ return resolveLocal(vfs, spec, dirname(importerAbs));
1229
+ try {
1230
+ return resolveImport(vfs, spec, importerAbs, "import");
1231
+ } catch {
1232
+ return null;
1233
+ }
1234
+ }
1235
+ };
1236
+ }
921
1237
  function inlineAssets(html, vfs, baseDir) {
922
1238
  let out = html.replace(
923
1239
  /<script\b([^>]*?)\bsrc\s*=\s*(["'])(.*?)\2([^>]*)><\/script>/gi,
@@ -934,7 +1250,13 @@ var AdepWebContainer = (() => {
934
1250
  (whole, _pre, _q, _post, _r, orig) => {
935
1251
  const abs = resolveLocal(vfs, orig, baseDir);
936
1252
  if (abs === null) return whole;
937
- return `<style>${vfs.readFile(abs)}</style>`;
1253
+ const css = vfs.readFile(abs);
1254
+ try {
1255
+ return `<style>${inlineCssImports(css, abs, cssResolverOf(vfs))}</style>`;
1256
+ } catch (error) {
1257
+ if (error instanceof CssImportError) return `<style>${css}</style>`;
1258
+ throw error;
1259
+ }
938
1260
  }
939
1261
  );
940
1262
  return out;
@@ -1007,6 +1329,8 @@ var AdepWebContainer = (() => {
1007
1329
  "src/preview-server.ts"() {
1008
1330
  "use strict";
1009
1331
  init_path();
1332
+ init_node_resolve();
1333
+ init_css_imports();
1010
1334
  EXTERNAL_SRC = /(?:^https?:)?\/\//i;
1011
1335
  }
1012
1336
  });
@@ -1218,7 +1542,8 @@ var AdepWebContainer = (() => {
1218
1542
  ' if (u.pathname.indexOf("/api/") !== 0 && u.pathname !== "/api") {',
1219
1543
  " return ORIGINAL_FETCH(input, init);",
1220
1544
  " }",
1221
- " if (window.parent === window) return ORIGINAL_FETCH(input, init);",
1545
+ " var bridgeWindow = window.parent !== window ? window.parent : window.opener;",
1546
+ " if (!bridgeWindow) return ORIGINAL_FETCH(input, init);",
1222
1547
  ' method = (method || "GET").toUpperCase();',
1223
1548
  " var target = u.pathname + u.search;",
1224
1549
  " return readBody(input, init).then(function (textBody) {",
@@ -1229,10 +1554,75 @@ var AdepWebContainer = (() => {
1229
1554
  ` resolve(new Response('{"error":{"code":"FN_PROXY_TIMEOUT","message":"\\u4e91\\u51fd\\u6570\\u6267\\u884c\\u8d85\\u65f6"}}', { status: 504, headers: { "content-type": "application/json" } }));`,
1230
1555
  " }, TIMEOUT_MS);",
1231
1556
  " pending[id] = { resolve: resolve, timer: timer };",
1232
- ' window.parent.postMessage({ __adepFnRequest: true, id: id, method: method, url: target, headers: headers, body: textBody }, "*");',
1557
+ ' bridgeWindow.postMessage({ __adepFnRequest: true, id: id, method: method, url: target, headers: headers, body: textBody }, "*");',
1233
1558
  " });",
1234
1559
  " });",
1235
1560
  " };",
1561
+ "",
1562
+ " /* \u2014\u2014 blob URL SPA \u8DEF\u7531\u652F\u6301 \u2014\u2014",
1563
+ " blob: \u662F\u4E0D\u53EF\u5206\u5C42 scheme\uFF0Chistory.pushState('/about') \u5185\u90E8\u89E3\u6790\u76F8\u5BF9\u8DEF\u5F84\u4F1A\u629B",
1564
+ " TypeError \u2192 SPA history \u6A21\u5F0F\u8DEF\u7531\u5D29\u6E83\u3002patch pushState/replaceState\uFF0C\u5BF9\u76F8\u5BF9",
1565
+ " \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",
1566
+ " \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 */",
1567
+ ' if (window.location.protocol === "blob:") {',
1568
+ ' var SPA_KEY = "__adep_spa_path";',
1569
+ ' var spaPath = "/";',
1570
+ " try {",
1571
+ " var _saved = window.sessionStorage.getItem(SPA_KEY);",
1572
+ " if (_saved) spaPath = _saved;",
1573
+ " } catch (e) {}",
1574
+ " try {",
1575
+ ' Object.defineProperty(window.location, "pathname", {',
1576
+ " get: function () { return spaPath; },",
1577
+ " configurable: true",
1578
+ " });",
1579
+ " } catch (e) {}",
1580
+ " var _origPush = window.history.pushState.bind(window.history);",
1581
+ " var _origReplace = window.history.replaceState.bind(window.history);",
1582
+ " function _isRelative(url) {",
1583
+ ' if (!url || typeof url !== "string") return false;',
1584
+ ' if (url.charAt(0) === "#") return false;',
1585
+ " if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(url)) return false;",
1586
+ " return true;",
1587
+ " }",
1588
+ " function _resolvePath(url) {",
1589
+ ' var qi = url.indexOf("?");',
1590
+ ' var hi = url.indexOf("#");',
1591
+ " var end = url.length;",
1592
+ " if (qi !== -1) end = qi;",
1593
+ " if (hi !== -1 && hi < end) end = hi;",
1594
+ " var p = url.slice(0, end);",
1595
+ ' if (p.charAt(0) !== "/") {',
1596
+ ' var base = spaPath.slice(0, spaPath.lastIndexOf("/") + 1);',
1597
+ " p = base + p;",
1598
+ " }",
1599
+ ' var parts = p.split("/");',
1600
+ " var out = [];",
1601
+ " for (var i = 0; i < parts.length; i++) {",
1602
+ " var seg = parts[i];",
1603
+ ' if (seg === "" || seg === ".") continue;',
1604
+ ' if (seg === "..") { out.pop(); continue; }',
1605
+ " out.push(seg);",
1606
+ " }",
1607
+ ' return "/" + out.join("/");',
1608
+ " }",
1609
+ " window.history.pushState = function (state, title, url) {",
1610
+ " if (_isRelative(url)) {",
1611
+ " spaPath = _resolvePath(url);",
1612
+ " try { window.sessionStorage.setItem(SPA_KEY, spaPath); } catch (e) {}",
1613
+ " return;",
1614
+ " }",
1615
+ " return _origPush(state, title, url);",
1616
+ " };",
1617
+ " window.history.replaceState = function (state, title, url) {",
1618
+ " if (_isRelative(url)) {",
1619
+ " spaPath = _resolvePath(url);",
1620
+ " try { window.sessionStorage.setItem(SPA_KEY, spaPath); } catch (e) {}",
1621
+ " return;",
1622
+ " }",
1623
+ " return _origReplace(state, title, url);",
1624
+ " };",
1625
+ " }",
1236
1626
  "})();"
1237
1627
  ].join("\n");
1238
1628
  return src;
@@ -1240,12 +1630,76 @@ var AdepWebContainer = (() => {
1240
1630
  }
1241
1631
  });
1242
1632
 
1633
+ // src/console-relay.ts
1634
+ var CONSOLE_RELAY_SCRIPT;
1635
+ var init_console_relay = __esm({
1636
+ "src/console-relay.ts"() {
1637
+ "use strict";
1638
+ CONSOLE_RELAY_SCRIPT = [
1639
+ "(function () {",
1640
+ " if (window.__adepErrorRelayInstalled) return;",
1641
+ " window.__adepErrorRelayInstalled = true;",
1642
+ ' var LEVELS = { log: "log", info: "info", warn: "warn", error: "error", debug: "log" };',
1643
+ " function fmt(value) {",
1644
+ " try {",
1645
+ ' if (typeof value === "string") return value;',
1646
+ ' if (value === undefined) return "undefined";',
1647
+ " var seen = [];",
1648
+ " var json = JSON.stringify(value, function (key, val) {",
1649
+ ' if (val instanceof Error) return val.stack || (val.name + ": " + val.message);',
1650
+ ' if (typeof val === "function") return "[Function " + (val.name || "anonymous") + "]";',
1651
+ ' if (typeof val === "bigint") return String(val) + "n";',
1652
+ ' if (val && typeof val === "object") {',
1653
+ ' if (seen.indexOf(val) !== -1) return "[Circular]";',
1654
+ " seen.push(val);",
1655
+ " }",
1656
+ " return val;",
1657
+ " });",
1658
+ " return json === undefined ? String(value) : json;",
1659
+ " } catch {",
1660
+ " return String(value);",
1661
+ " }",
1662
+ " }",
1663
+ " function send(level, args) {",
1664
+ " try {",
1665
+ " if (window.parent === window) return;",
1666
+ ' var text = Array.prototype.map.call(args, fmt).join(" ");',
1667
+ ' window.parent.postMessage({ source: "adep-ide-preview", kind: "console", level: level, text: text }, "*");',
1668
+ " } catch {",
1669
+ " }",
1670
+ " }",
1671
+ " Object.keys(LEVELS).forEach(function (name) {",
1672
+ " var native = console[name];",
1673
+ " console[name] = function () {",
1674
+ " send(LEVELS[name], arguments);",
1675
+ " native.apply(console, arguments);",
1676
+ " };",
1677
+ " });",
1678
+ " window.addEventListener('error', function (event) {",
1679
+ ' var text = event.message || "Script error";',
1680
+ " if (event.filename) {",
1681
+ ' text += " (" + event.filename + ":" + event.lineno + ":" + event.colno + ")";',
1682
+ " }",
1683
+ ' send("error", [text]);',
1684
+ " });",
1685
+ " window.addEventListener('unhandledrejection', function (event) {",
1686
+ " var reason = event.reason;",
1687
+ ' var text = reason && reason.stack ? String(reason.stack) : "Unhandled rejection: " + fmt(reason);',
1688
+ ' send("error", [text]);',
1689
+ " });",
1690
+ "})();",
1691
+ ""
1692
+ ].join("\n");
1693
+ }
1694
+ });
1695
+
1243
1696
  // src/vite-dev.ts
1244
1697
  var vite_dev_exports = {};
1245
1698
  __export(vite_dev_exports, {
1246
1699
  ViteDevError: () => ViteDevError,
1247
1700
  createViteServer: () => createViteServer,
1248
- scanEsmSpecifiers: () => scanEsmSpecifiers
1701
+ scanEsmSpecifiers: () => scanEsmSpecifiers,
1702
+ scanRequireSpecifiers: () => scanRequireSpecifiers
1249
1703
  });
1250
1704
  function tokenize2(source) {
1251
1705
  const tokens = [];
@@ -1343,6 +1797,20 @@ var AdepWebContainer = (() => {
1343
1797
  }
1344
1798
  return hits;
1345
1799
  }
1800
+ function scanRequireSpecifiers(source) {
1801
+ const tokens = tokenize2(source);
1802
+ const hits = [];
1803
+ for (let i = 0; i + 3 < tokens.length; i++) {
1804
+ const call = tokens[i];
1805
+ if (call.kind !== "ident" || call.text !== "require") continue;
1806
+ if (tokens[i + 1]?.text !== "(") continue;
1807
+ const arg = tokens[i + 2];
1808
+ if (arg.kind !== "string") continue;
1809
+ if (tokens[i + 3]?.text !== ")") continue;
1810
+ hits.push({ specifier: arg.text.slice(1, -1), start: arg.start, end: arg.end });
1811
+ }
1812
+ return hits;
1813
+ }
1346
1814
  function cssModule(css) {
1347
1815
  return [
1348
1816
  `const css = ${JSON.stringify(css)};`,
@@ -1373,6 +1841,113 @@ var AdepWebContainer = (() => {
1373
1841
  }
1374
1842
  return `export default ${source.trim()};`;
1375
1843
  }
1844
+ function stripShebang(source) {
1845
+ if (!source.startsWith("#!")) return source;
1846
+ const nl = source.indexOf("\n");
1847
+ return nl === -1 ? "" : source.slice(nl + 1);
1848
+ }
1849
+ function hasEsmSyntax(source) {
1850
+ const tokens = tokenize2(source);
1851
+ for (let i = 0; i < tokens.length; i++) {
1852
+ const tok = tokens[i];
1853
+ if (tok.kind !== "ident") continue;
1854
+ if (tok.text === "export") return true;
1855
+ if (tok.text === "import" && tokens[i + 1]?.text !== "(") return true;
1856
+ }
1857
+ return false;
1858
+ }
1859
+ function isCommonJs(abs, source) {
1860
+ if (abs.endsWith(".cjs")) return true;
1861
+ if (!abs.endsWith(".js")) return false;
1862
+ if (hasEsmSyntax(source)) return false;
1863
+ return /\bmodule\s*\.\s*exports\b|\bexports\s*\.|\brequire\s*\(/.test(source);
1864
+ }
1865
+ function collectCjsExportNames(source) {
1866
+ const tokens = tokenize2(source);
1867
+ const names = /* @__PURE__ */ new Set();
1868
+ const isIdent = (index) => {
1869
+ const tok = tokens[index];
1870
+ return tok?.kind === "ident" && VALID_IDENT.test(tok.text) ? tok.text : null;
1871
+ };
1872
+ for (let i = 0; i < tokens.length; i++) {
1873
+ const tok = tokens[i];
1874
+ if (tok.kind !== "ident") continue;
1875
+ if (tok.text === "exports") {
1876
+ const name = isIdent(i + 2);
1877
+ if (tokens[i + 1]?.text === "." && name !== null && tokens[i + 3]?.text === "=")
1878
+ names.add(name);
1879
+ continue;
1880
+ }
1881
+ if (tok.text === "module") {
1882
+ const name = isIdent(i + 4);
1883
+ if (tokens[i + 1]?.text === "." && tokens[i + 2]?.text === "exports" && tokens[i + 3]?.text === "." && name !== null && tokens[i + 5]?.text === "=") {
1884
+ names.add(name);
1885
+ }
1886
+ if (tokens[i + 1]?.text === "." && tokens[i + 2]?.text === "exports" && tokens[i + 3]?.text === "=" && tokens[i + 4]?.text === "{") {
1887
+ let depth = 0;
1888
+ for (let j = i + 4; j < tokens.length; j++) {
1889
+ const t = tokens[j];
1890
+ if (t.kind === "string" || t.kind === "template") continue;
1891
+ if (t.text === "{") depth++;
1892
+ else if (t.text === "}") {
1893
+ depth--;
1894
+ if (depth === 0) break;
1895
+ } else if (depth === 1) {
1896
+ const prev = tokens[j - 1]?.text;
1897
+ const key = isIdent(j);
1898
+ const next = tokens[j + 1]?.text;
1899
+ if (key !== null && (prev === "{" || prev === ",") && (next === ":" || next === "," || next === "}")) {
1900
+ names.add(key);
1901
+ }
1902
+ }
1903
+ }
1904
+ continue;
1905
+ }
1906
+ continue;
1907
+ }
1908
+ if (tok.text === "Object") {
1909
+ if (tokens[i + 1]?.text === "." && tokens[i + 2]?.text === "defineProperty" && tokens[i + 3]?.text === "(" && tokens[i + 4]?.text === "exports" && tokens[i + 5]?.text === "," && tokens[i + 6]?.kind === "string") {
1910
+ names.add(tokens[i + 6].text.slice(1, -1));
1911
+ }
1912
+ }
1913
+ }
1914
+ names.delete("default");
1915
+ return [...names].filter((name) => VALID_IDENT.test(name) && !CJS_INTERNALS.has(name));
1916
+ }
1917
+ function wrapCommonJs(abs, source) {
1918
+ const specifiers = [...new Set(scanRequireSpecifiers(source).map((hit) => hit.specifier))];
1919
+ const prelude = specifiers.map(
1920
+ (spec, index) => `import * as ${CJS_PREFIX}Dep${index} from ${JSON.stringify(CJS_SPECIFIER_PREFIX + spec)};`
1921
+ );
1922
+ const entries = specifiers.map(
1923
+ (spec, index) => `${JSON.stringify(spec)}: ${CJS_PREFIX}Dep${index}`
1924
+ );
1925
+ const names = collectCjsExportNames(source);
1926
+ const detail = JSON.stringify(
1927
+ `${abs} \u91CC\u7684 require() \u8BF4\u660E\u7B26\u65E0\u6CD5\u89E3\u6790\uFF08Node \u5185\u5EFA\u6A21\u5757\u6D4F\u89C8\u5668\u4E0D\u63D0\u4F9B / \u4F9D\u8D56\u672A\u5B89\u88C5 / \u52A8\u6001\u62FC\u63A5\uFF09`
1928
+ );
1929
+ return [
1930
+ ...prelude,
1931
+ `const ${CJS_PREFIX}Map = { ${entries.join(", ")} };`,
1932
+ `const ${CJS_PREFIX}Require = (id) => {`,
1933
+ ` const ns = ${CJS_PREFIX}Map[id];`,
1934
+ ` if (ns === undefined || ns.${CJS_PREFIX}Unresolved === true)`,
1935
+ ` throw new Error('require(' + JSON.stringify(id) + ') \u65E0\u6CD5\u89E3\u6790\uFF1A' + ${detail});`,
1936
+ ` return ns[${JSON.stringify(CJS_EXPORTS_MARKER)}] !== undefined ? ns[${JSON.stringify(CJS_EXPORTS_MARKER)}] : ns;`,
1937
+ `};`,
1938
+ `const ${CJS_PREFIX}Module = { exports: {} };`,
1939
+ "(function (module, exports, require) {",
1940
+ source,
1941
+ `}).call(${CJS_PREFIX}Module.exports, ${CJS_PREFIX}Module, ${CJS_PREFIX}Module.exports, ${CJS_PREFIX}Require);`,
1942
+ `const ${CJS_EXPORTS_MARKER}Value = ${CJS_PREFIX}Module.exports;`,
1943
+ `export const ${CJS_EXPORTS_MARKER} = ${CJS_EXPORTS_MARKER}Value;`,
1944
+ `const ${CJS_PREFIX}Default = ${CJS_EXPORTS_MARKER}Value && ${CJS_EXPORTS_MARKER}Value.__esModule ? ${CJS_EXPORTS_MARKER}Value.default : ${CJS_EXPORTS_MARKER}Value;`,
1945
+ `export default ${CJS_PREFIX}Default;`,
1946
+ ...names.map(
1947
+ (name) => `export const ${name} = ${CJS_EXPORTS_MARKER}Value[${JSON.stringify(name)}];`
1948
+ )
1949
+ ].join("\n");
1950
+ }
1376
1951
  function resolveWithSuffixes(vfs, base) {
1377
1952
  if (vfs.exists(base) && !vfs.isDirectory(base)) return base;
1378
1953
  const asFile2 = VITE_RESOLVE_SUFFIXES.map((suffix) => `${base}${suffix}`);
@@ -1419,15 +1994,42 @@ var AdepWebContainer = (() => {
1419
1994
  [/\bprocess\s*\.\s*env\s*\.\s*NODE_ENV\b/g, JSON.stringify("development")],
1420
1995
  [/\b__VUE_OPTIONS_API__\b/g, "true"],
1421
1996
  [/\b__VUE_PROD_DEVTOOLS__\b/g, "false"],
1422
- [/\b__VUE_PROD_HYDRATION_MISMATCH_DETAILS__\b/g, "false"]
1997
+ [/\b__VUE_PROD_HYDRATION_MISMATCH_DETAILS__\b/g, "false"],
1998
+ [
1999
+ /\bimport\s*\.\s*meta\s*\.\s*env\b/g,
2000
+ '({ BASE_URL: "/", MODE: "development", DEV: true, PROD: false, SSR: false })'
2001
+ ]
1423
2002
  ];
1424
2003
  function applyDefines(code) {
1425
2004
  let out = code;
1426
2005
  for (const [pattern, value] of DEFINES) out = out.replace(pattern, value);
1427
2006
  return out;
1428
2007
  }
2008
+ const cssResolver = {
2009
+ read: (abs) => vfs.exists(abs) && !vfs.isDirectory(abs) ? vfs.readFile(abs) : null,
2010
+ resolve: (spec, importerAbs) => {
2011
+ if (spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/")) {
2012
+ const base = spec.startsWith("/") ? absoluteFromRoot(spec) : join(dirname(importerAbs), spec);
2013
+ const target = resolveWithSuffixes(vfs, base);
2014
+ return vfs.exists(target) && !vfs.isDirectory(target) ? target : null;
2015
+ }
2016
+ try {
2017
+ return resolveImport(vfs, spec, importerAbs, "import");
2018
+ } catch {
2019
+ return null;
2020
+ }
2021
+ }
2022
+ };
2023
+ function inlineCss(css, importerAbs) {
2024
+ try {
2025
+ return inlineCssImports(css, importerAbs, cssResolver);
2026
+ } catch (error) {
2027
+ if (error instanceof CssImportError) throw new ViteDevError("CSS_IMPORT", error.message);
2028
+ throw error;
2029
+ }
2030
+ }
1429
2031
  function transformModule2(abs, source) {
1430
- if (abs.endsWith(".css")) return cssModule(source);
2032
+ if (abs.endsWith(".css")) return cssModule(inlineCss(source, abs));
1431
2033
  if (abs.endsWith(".json")) return jsonModule(source, abs);
1432
2034
  if (abs.endsWith(".vue")) {
1433
2035
  if (sfcCompiler === void 0)
@@ -1437,7 +2039,9 @@ var AdepWebContainer = (() => {
1437
2039
  );
1438
2040
  const compiled = sfcCompiler(source, abs);
1439
2041
  return [
1440
- ...compiled.styles.map((css, index) => inlineStyleBlock(css, `${abs}#${index}`)),
2042
+ ...compiled.styles.map(
2043
+ (css, index) => inlineStyleBlock(inlineCss(css, abs), `${abs}#${index}`)
2044
+ ),
1441
2045
  applyDefines(stripTypes(compiled.script))
1442
2046
  ].join("\n");
1443
2047
  }
@@ -1446,37 +2050,65 @@ var AdepWebContainer = (() => {
1446
2050
  "JSX_UNSUPPORTED",
1447
2051
  `${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`
1448
2052
  );
1449
- if (abs.endsWith(".ts") || abs.endsWith(".mts")) return applyDefines(stripTypes(source));
1450
- return applyDefines(source);
2053
+ const bare = stripShebang(source);
2054
+ if (abs.endsWith(".ts") || abs.endsWith(".mts")) return applyDefines(stripTypes(bare));
2055
+ if (isCommonJs(abs, bare)) return applyDefines(wrapCommonJs(abs, bare));
2056
+ return applyDefines(bare);
1451
2057
  }
1452
2058
  function absoluteFromRoot(spec) {
1453
2059
  return join(root, spec.replace(/^\/+/, ""));
1454
2060
  }
1455
- async function resolveSpecifier(spec, importerAbs) {
1456
- if (EXTERNAL_SPECIFIER.test(spec) || DATA_OR_BLOB.test(spec)) return spec;
1457
- let target;
2061
+ function resolveToAbs(spec, importerAbs) {
1458
2062
  if (spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/")) {
1459
2063
  const base = spec.startsWith("/") ? absoluteFromRoot(spec) : join(dirname(importerAbs), spec);
1460
- target = resolveWithSuffixes(vfs, base);
2064
+ const target = resolveWithSuffixes(vfs, base);
1461
2065
  if (!vfs.exists(target) || vfs.isDirectory(target))
1462
2066
  throw new ViteDevError(
1463
2067
  "RESOLVE",
1464
2068
  `\u627E\u4E0D\u5230\u6A21\u5757 "${spec}"\uFF08\u81EA ${importerAbs}\uFF1B\u8BD5\u8FC7\u6269\u5C55\u540D ${VITE_RESOLVE_SUFFIXES.join("/")} \u4E0E\u76EE\u5F55 index\uFF09`
1465
2069
  );
1466
- } else {
1467
- try {
1468
- target = resolveImport(vfs, spec, importerAbs, "import");
1469
- } catch (error) {
1470
- if (error instanceof ResolveError)
1471
- throw new ViteDevError(
1472
- "RESOLVE",
1473
- `${error.message}
2070
+ return target;
2071
+ }
2072
+ try {
2073
+ return resolveImport(vfs, spec, importerAbs, "import");
2074
+ } catch (error) {
2075
+ if (error instanceof ResolveError)
2076
+ throw new ViteDevError(
2077
+ "RESOLVE",
2078
+ `${error.message}
1474
2079
  \uFF08\u5728 ${importerAbs} \u4E2D import "${spec}"\uFF09`
1475
- );
1476
- throw error;
2080
+ );
2081
+ throw error;
2082
+ }
2083
+ }
2084
+ const cjsStubSources = /* @__PURE__ */ new Map();
2085
+ function cjsStubUrl(spec) {
2086
+ let abs = cjsStubSources.get(spec);
2087
+ if (abs === void 0) {
2088
+ abs = `${INLINE_PREFIX}cjs_stub_${cjsStubSources.size}.mjs`;
2089
+ cjsStubSources.set(spec, abs);
2090
+ inlineSources.set(
2091
+ abs,
2092
+ [
2093
+ `export const ${CJS_PREFIX}Unresolved = true;`,
2094
+ `export const ${CJS_PREFIX}Specifier = ${JSON.stringify(spec)};`,
2095
+ "export default undefined;"
2096
+ ].join("\n")
2097
+ );
2098
+ }
2099
+ return loadModuleUrl(abs);
2100
+ }
2101
+ async function resolveSpecifier(spec, importerAbs) {
2102
+ if (spec.startsWith(CJS_SPECIFIER_PREFIX)) {
2103
+ const original = spec.slice(CJS_SPECIFIER_PREFIX.length);
2104
+ try {
2105
+ return await loadModuleUrl(resolveToAbs(original, importerAbs));
2106
+ } catch {
2107
+ return cjsStubUrl(original);
1477
2108
  }
1478
2109
  }
1479
- return loadModuleUrl(target);
2110
+ if (EXTERNAL_SPECIFIER.test(spec) || DATA_OR_BLOB.test(spec)) return spec;
2111
+ return loadModuleUrl(resolveToAbs(spec, importerAbs));
1480
2112
  }
1481
2113
  async function loadModuleUrl(abs) {
1482
2114
  const cached = moduleUrls.get(abs);
@@ -1568,14 +2200,15 @@ var AdepWebContainer = (() => {
1568
2200
  );
1569
2201
  const urls = await Promise.all(entryModuleUrls);
1570
2202
  html = html.replace(/__adep_vite_entry_(\d+)__/g, (_m, idx) => urls[Number(idx)] ?? "");
1571
- const interceptor = `<script>${FN_FETCH_INTERCEPTOR_SCRIPT}<\/script>`;
1572
- html = /<head[^>]*>/i.test(html) ? html.replace(/<head[^>]*>/i, (m) => `${m}${interceptor}`) : `${interceptor}${html}`;
2203
+ const preludeScripts = `<script>${CONSOLE_RELAY_SCRIPT}<\/script><script>${FN_FETCH_INTERCEPTOR_SCRIPT}<\/script>`;
2204
+ html = /<head[^>]*>/i.test(html) ? html.replace(/<head[^>]*>/i, (m) => `${m}${preludeScripts}`) : `${preludeScripts}${html}`;
1573
2205
  const hmr = hmrScript(channelName);
1574
2206
  return /<\/body>/i.test(html) ? html.replace(/<\/(body)>/i, `${hmr}</$1>`) : html + hmr;
1575
2207
  }
1576
2208
  async function rebuild() {
1577
2209
  moduleUrls = /* @__PURE__ */ new Map();
1578
2210
  inlineSources = /* @__PURE__ */ new Map();
2211
+ cjsStubSources.clear();
1579
2212
  inlineSeq = 0;
1580
2213
  let doc;
1581
2214
  try {
@@ -1585,9 +2218,13 @@ var AdepWebContainer = (() => {
1585
2218
  }
1586
2219
  const changed = lastDoc !== null && doc !== lastDoc;
1587
2220
  lastDoc = doc;
2221
+ if (!changed && currentUrl !== "") return;
1588
2222
  if (currentUrl !== "") revokeObjectURL(currentUrl);
1589
2223
  currentUrl = createObjectURL(new Blob([doc], { type: "text/html" }));
1590
- if (changed) broadcast(currentUrl);
2224
+ if (changed) {
2225
+ broadcast(currentUrl);
2226
+ options.onDocumentChange?.(currentUrl);
2227
+ }
1591
2228
  }
1592
2229
  const server = {
1593
2230
  get url() {
@@ -1620,7 +2257,7 @@ var AdepWebContainer = (() => {
1620
2257
  const unsubscribeMutate = vfs.onMutate(scheduleRebuild);
1621
2258
  return server;
1622
2259
  }
1623
- var ViteDevError, REGEX_PRECEDING_CHARS, REGEX_PRECEDING_KEYWORDS, isIdentStart, isIdentPart, VITE_RESOLVE_SUFFIXES, INLINE_PREFIX, EXTERNAL_SPECIFIER, DATA_OR_BLOB, MODULE_SCRIPT_SRC_RE, MODULE_SCRIPT_INLINE_RE;
2260
+ var ViteDevError, REGEX_PRECEDING_CHARS, REGEX_PRECEDING_KEYWORDS, isIdentStart, isIdentPart, CJS_PREFIX, CJS_EXPORTS_MARKER, CJS_SPECIFIER_PREFIX, VALID_IDENT, CJS_INTERNALS, VITE_RESOLVE_SUFFIXES, INLINE_PREFIX, EXTERNAL_SPECIFIER, DATA_OR_BLOB, MODULE_SCRIPT_SRC_RE, MODULE_SCRIPT_INLINE_RE;
1624
2261
  var init_vite_dev = __esm({
1625
2262
  "src/vite-dev.ts"() {
1626
2263
  "use strict";
@@ -1629,6 +2266,8 @@ var AdepWebContainer = (() => {
1629
2266
  init_strip_types();
1630
2267
  init_preview_server();
1631
2268
  init_function_fetch_proxy();
2269
+ init_console_relay();
2270
+ init_css_imports();
1632
2271
  ViteDevError = class extends Error {
1633
2272
  constructor(reason, message) {
1634
2273
  super(message);
@@ -1677,6 +2316,22 @@ var AdepWebContainer = (() => {
1677
2316
  ]);
1678
2317
  isIdentStart = (ch) => /[A-Za-z_$]/.test(ch);
1679
2318
  isIdentPart = (ch) => /[A-Za-z0-9_$]/.test(ch);
2319
+ CJS_PREFIX = "__adepCjs";
2320
+ CJS_EXPORTS_MARKER = `${CJS_PREFIX}Exports`;
2321
+ CJS_SPECIFIER_PREFIX = `${CJS_PREFIX}Spec:`;
2322
+ VALID_IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
2323
+ CJS_INTERNALS = /* @__PURE__ */ new Set([
2324
+ "module",
2325
+ "exports",
2326
+ "require",
2327
+ // 互操作标记而非用户导出:Babel 产物会 defineProperty(exports, "__esModule"),转发它没有意义。
2328
+ "__esModule",
2329
+ `${CJS_EXPORTS_MARKER}`,
2330
+ `${CJS_PREFIX}Default`,
2331
+ `${CJS_PREFIX}Map`,
2332
+ `${CJS_PREFIX}Module`,
2333
+ `${CJS_PREFIX}Require`
2334
+ ]);
1680
2335
  VITE_RESOLVE_SUFFIXES = [".ts", ".js", ".mjs", ".mts", ".vue", ".json", ".css"];
1681
2336
  INLINE_PREFIX = "/__vite_inline_";
1682
2337
  EXTERNAL_SPECIFIER = /^(?:https?:)?\/\//i;
@@ -1689,7 +2344,9 @@ var AdepWebContainer = (() => {
1689
2344
  // src/index.ts
1690
2345
  var index_exports = {};
1691
2346
  __export(index_exports, {
2347
+ BUNDLE_MODULE_PATH_PREFIX: () => BUNDLE_MODULE_PATH_PREFIX,
1692
2348
  COMPLETABLE_COMMANDS: () => COMPLETABLE_COMMANDS,
2349
+ CONSOLE_RELAY_SCRIPT: () => CONSOLE_RELAY_SCRIPT,
1693
2350
  DEFAULT_MAX_INSTALL_DEPTH: () => DEFAULT_MAX_INSTALL_DEPTH,
1694
2351
  EXTRA_COMMANDS: () => EXTRA_COMMANDS,
1695
2352
  FN_FETCH_INTERCEPTOR_SCRIPT: () => FN_FETCH_INTERCEPTOR_SCRIPT,
@@ -1734,12 +2391,15 @@ var AdepWebContainer = (() => {
1734
2391
  createViteServer: () => createViteServer,
1735
2392
  createWorkerRuntime: () => createWorkerRuntime,
1736
2393
  deepEqual: () => deepEqual,
2394
+ defaultModuleName: () => defaultModuleName,
1737
2395
  displayPath: () => displayPath,
1738
2396
  entriesToTree: () => entriesToTree,
1739
2397
  evaluateModuleSource: () => evaluateModuleSource,
1740
2398
  evaluateSource: () => evaluateSource,
1741
2399
  exampleTestSource: () => exampleTestSource,
1742
2400
  expectAssertion: () => expect,
2401
+ exportBundle: () => exportBundle,
2402
+ findBlobRefs: () => findBlobRefs,
1743
2403
  formatTestReport: () => formatTestReport,
1744
2404
  formatValue: () => formatValue,
1745
2405
  fullName: () => fullName,
@@ -2823,7 +3483,7 @@ var AdepWebContainer = (() => {
2823
3483
 
2824
3484
  // src/npm-client.ts
2825
3485
  init_node_resolve();
2826
- var DEFAULT_MAX_INSTALL_DEPTH = 5;
3486
+ var DEFAULT_MAX_INSTALL_DEPTH = 25;
2827
3487
  var defaultFetch = (url, init) => globalThis.fetch(url, init).then((res) => res);
2828
3488
  function parseSpec(spec) {
2829
3489
  if (spec.startsWith("@")) {
@@ -2848,29 +3508,50 @@ var AdepWebContainer = (() => {
2848
3508
  throw new Error(`${what} \u5931\u8D25\uFF1A\u65E0\u6CD5\u8BBF\u95EE npm \u4E2D\u7EE7\uFF08${url}\uFF0C${reason}\uFF09`, { cause: error });
2849
3509
  }
2850
3510
  }
3511
+ var RATE_LIMIT_MAX_RETRIES = 120;
3512
+ var DEFAULT_RETRY_AFTER_MS = 1e3;
3513
+ var MAX_RETRY_AFTER_MS = 6e4;
3514
+ var defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
3515
+ function retryAfterMs(res) {
3516
+ const raw = res.headers["retry-after"];
3517
+ const seconds = raw === void 0 ? Number.NaN : Number.parseFloat(raw);
3518
+ if (!Number.isFinite(seconds) || seconds <= 0) return DEFAULT_RETRY_AFTER_MS;
3519
+ return Math.min(seconds * 1e3, MAX_RETRY_AFTER_MS);
3520
+ }
2851
3521
  function createNpmClient(options) {
2852
3522
  const fetchImpl = options.fetchImpl ?? defaultFetch;
2853
3523
  const base = options.baseUrl.replace(/\/+$/, "");
2854
3524
  const storage = options.storage;
2855
3525
  const maxDepth = options.maxDepth ?? DEFAULT_MAX_INSTALL_DEPTH;
3526
+ const sleep = options.sleep ?? defaultSleep;
3527
+ async function relayRequest(url, what) {
3528
+ for (let attempt = 0; ; attempt += 1) {
3529
+ const res = await relayFetch(fetchImpl, url, what);
3530
+ if (res.status !== 429) return res;
3531
+ if (attempt >= RATE_LIMIT_MAX_RETRIES) {
3532
+ throw new Error(
3533
+ `${what} \u5931\u8D25\uFF1Anpm \u4E2D\u7EE7\u9650\u901F\uFF08HTTP 429\uFF09\uFF0C\u5DF2\u6309 Retry-After \u9000\u907F\u91CD\u8BD5 ${attempt} \u6B21\u4ECD\u88AB\u62D2\u2014\u2014\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002`
3534
+ );
3535
+ }
3536
+ await sleep(retryAfterMs(res));
3537
+ }
3538
+ }
2856
3539
  async function resolvePackage(name, spec) {
2857
3540
  const params = new URLSearchParams({ name });
2858
3541
  if (spec !== void 0) params.set("spec", spec);
2859
- const res = await relayFetch(
2860
- fetchImpl,
3542
+ const res = await relayRequest(
2861
3543
  `${base}/package?${params.toString()}`,
2862
3544
  `\u89E3\u6790\u5305 ${name}@${spec ?? "latest"}`
2863
3545
  );
2864
3546
  if (!res.ok) {
2865
3547
  throw new Error(
2866
- `\u89E3\u6790\u5305\u5931\u8D25 ${name}@${spec ?? "latest"}\uFF1AHTTP ${res.status}\uFF08\u4E0D\u5728\u767D\u540D\u5355\u6216\u5305\u4E0D\u5B58\u5728\u65F6\u7531\u4E2D\u7EE7\u62D2\u7EDD\uFF09`
3548
+ `\u89E3\u6790\u5305\u5931\u8D25 ${name}@${spec ?? "latest"}\uFF1AHTTP ${res.status}\uFF08\u4E2D\u7EE7\u62D2\u7EDD\uFF1A\u5305\u4E0D\u5B58\u5728 / registry \u4E0D\u53EF\u8FBE / registry \u975E\u767D\u540D\u5355\uFF09`
2867
3549
  );
2868
3550
  }
2869
3551
  return await res.json();
2870
3552
  }
2871
3553
  async function fetchAndUnpack(name, version) {
2872
- const res = await relayFetch(
2873
- fetchImpl,
3554
+ const res = await relayRequest(
2874
3555
  `${base}/tarball?${new URLSearchParams({ name, version }).toString()}`,
2875
3556
  `\u4E0B\u8F7D tarball ${name}@${version}`
2876
3557
  );
@@ -2894,17 +3575,12 @@ var AdepWebContainer = (() => {
2894
3575
  return null;
2895
3576
  }
2896
3577
  }
2897
- async function collect(name, spec, depth, path, staged, onStack, visited, packages, distTagsByName) {
3578
+ async function collect(name, spec, depth, path, staged, visited, packages, distTagsByName) {
2898
3579
  if (depth > maxDepth) {
2899
3580
  throw new Error(
2900
3581
  `\u4F9D\u8D56\u5C42\u7EA7\u8D85\u8FC7\u4E0A\u9650\uFF08${maxDepth}\uFF09\uFF1A${[...path, name].join(" \u2192 ")}\u3002\u8BF7\u6539\u7528\u66F4\u8F7B\u7684\u5305\u6216\u7ECF\u670D\u52A1\u7AEF\u53D1\u5E03\u94FE\u8DEF\u5B89\u88C5\uFF08FN-009 \u5B9E\u65F6\u88C5\u8F7D\uFF09\u3002`
2901
3582
  );
2902
3583
  }
2903
- if (onStack.has(name)) {
2904
- throw new Error(
2905
- `\u68C0\u6D4B\u5230\u5FAA\u73AF\u4F9D\u8D56\uFF1A${[...path, name].join(" \u2192 ")}\u3002\u6D4F\u89C8\u5668\u5B89\u88C5\u4E0D\u652F\u6301\u73AF\u72B6\u4F9D\u8D56\u6811\uFF0C\u8BF7\u79FB\u9664\u73AF\u4E0A\u5305\u7684\u76F8\u4E92\u58F0\u660E\u3002`
2906
- );
2907
- }
2908
3584
  const meta = await resolvePackage(name, spec);
2909
3585
  distTagsByName.set(meta.name, meta.distTags ?? []);
2910
3586
  const key = `${meta.name}@${meta.version}`;
@@ -2928,8 +3604,6 @@ var AdepWebContainer = (() => {
2928
3604
  }
2929
3605
  Object.assign(deps, pkgMeta.dependencies ?? {});
2930
3606
  }
2931
- const nextStack = new Set(onStack);
2932
- nextStack.add(meta.name);
2933
3607
  for (const [depName, depSpec] of Object.entries(deps)) {
2934
3608
  await collect(
2935
3609
  depName,
@@ -2937,7 +3611,6 @@ var AdepWebContainer = (() => {
2937
3611
  depth + 1,
2938
3612
  [...path, meta.name],
2939
3613
  staged,
2940
- nextStack,
2941
3614
  visited,
2942
3615
  packages,
2943
3616
  distTagsByName
@@ -2946,7 +3619,7 @@ var AdepWebContainer = (() => {
2946
3619
  }
2947
3620
  return {
2948
3621
  async registries() {
2949
- const res = await relayFetch(fetchImpl, `${base}/registry`, "\u83B7\u53D6 registry \u5217\u8868");
3622
+ const res = await relayRequest(`${base}/registry`, "\u83B7\u53D6 registry \u5217\u8868");
2950
3623
  if (!res.ok) throw new Error(`\u83B7\u53D6 registry \u5217\u8868\u5931\u8D25\uFF1AHTTP ${res.status}`);
2951
3624
  const body = await res.json();
2952
3625
  return body.registries;
@@ -2956,7 +3629,7 @@ var AdepWebContainer = (() => {
2956
3629
  const staged = /* @__PURE__ */ new Map();
2957
3630
  const packages = [];
2958
3631
  const distTagsByName = /* @__PURE__ */ new Map();
2959
- await collect(name, spec, 1, [], staged, /* @__PURE__ */ new Set(), /* @__PURE__ */ new Set(), packages, distTagsByName);
3632
+ await collect(name, spec, 1, [], staged, /* @__PURE__ */ new Set(), packages, distTagsByName);
2960
3633
  const root = packages[0] ?? { name, version: spec ?? "latest" };
2961
3634
  const downloaded = staged.size > 0;
2962
3635
  for (const [path, contents] of staged) storage.writeFile(path, contents);
@@ -3711,7 +4384,11 @@ self.onmessage = async (event) => {
3711
4384
  const { createViteServer: createViteServer2 } = await Promise.resolve().then(() => (init_vite_dev(), vite_dev_exports));
3712
4385
  const server = createViteServer2(vfs, {
3713
4386
  root,
3714
- ...options.viteCompiler === void 0 ? {} : { sfcCompiler: options.viteCompiler }
4387
+ ...options.viteCompiler === void 0 ? {} : { sfcCompiler: options.viteCompiler },
4388
+ // PV-006:内容重建 → 以 `serverready`(update: true)事件上报新文档 URL,宿主导出预览产物。
4389
+ onDocumentChange: (url) => {
4390
+ emit("serverready", { port: server.port, url, kind: "vite", root: server.root, update: true });
4391
+ }
3715
4392
  });
3716
4393
  await server.ready;
3717
4394
  viteServer = server;
@@ -3876,6 +4553,92 @@ self.onmessage = async (event) => {
3876
4553
  init_vite_dev();
3877
4554
  init_path();
3878
4555
 
4556
+ // src/bundle-export.ts
4557
+ var BUNDLE_MODULE_PATH_PREFIX = "/_adep/m/";
4558
+ var BLOB_REF_RE = /blob:[^\s"'`<>()\\]+/g;
4559
+ function fnv1a(code) {
4560
+ let hash = 2166136261;
4561
+ for (let i = 0; i < code.length; i++) {
4562
+ hash ^= code.charCodeAt(i);
4563
+ hash = Math.imul(hash, 16777619) >>> 0;
4564
+ }
4565
+ return `${hash.toString(16).padStart(8, "0")}${code.length.toString(16)}`;
4566
+ }
4567
+ async function defaultModuleName(code) {
4568
+ const subtle = globalThis.crypto?.subtle;
4569
+ if (subtle === void 0) return fnv1a(code);
4570
+ const digest = await subtle.digest("SHA-256", new TextEncoder().encode(code));
4571
+ let hex = "";
4572
+ for (const byte of new Uint8Array(digest).slice(0, 8)) {
4573
+ hex += byte.toString(16).padStart(2, "0");
4574
+ }
4575
+ return hex;
4576
+ }
4577
+ function findBlobRefs(text) {
4578
+ const found = text.match(BLOB_REF_RE);
4579
+ return found === null ? [] : [...new Set(found)];
4580
+ }
4581
+ function rewriteRefs(text, urls) {
4582
+ let out = text;
4583
+ for (const [blobUrl, path] of urls) {
4584
+ if (out.includes(blobUrl)) out = out.split(blobUrl).join(path);
4585
+ }
4586
+ return out;
4587
+ }
4588
+ function injectScript(html, script) {
4589
+ return /<\/body>/i.test(html) ? html.replace(/<\/body>/i, `${script}</body>`) : html + script;
4590
+ }
4591
+ async function exportBundle(options) {
4592
+ const readText = options.readText ?? ((url) => fetch(url).then((response) => response.text()));
4593
+ const nameOf = options.moduleName ?? defaultModuleName;
4594
+ const prefix = options.modulePathPrefix ?? BUNDLE_MODULE_PATH_PREFIX;
4595
+ const uploaded = new Set(options.known === void 0 ? [] : [...options.known.values()]);
4596
+ const urls = /* @__PURE__ */ new Map();
4597
+ const sources = [];
4598
+ const readOrThrow = async (url) => {
4599
+ try {
4600
+ return await readText(url);
4601
+ } catch (error) {
4602
+ throw new Error(
4603
+ `\u9884\u89C8\u4EA7\u7269\u5BFC\u51FA\u5931\u8D25\uFF1A\u8BFB\u4E0D\u5230\u6A21\u5757 ${url}\uFF08${error instanceof Error ? error.message : String(error)}\uFF09`,
4604
+ { cause: error }
4605
+ );
4606
+ }
4607
+ };
4608
+ const html = await readOrThrow(options.documentUrl);
4609
+ const loadLayer = async (layer) => {
4610
+ const batch = [...new Set(layer)].filter((url) => !urls.has(url));
4611
+ if (batch.length === 0) return;
4612
+ const loaded = await Promise.all(
4613
+ batch.map(async (url) => {
4614
+ const code = await readOrThrow(url);
4615
+ return { url, code, path: `${prefix}${await nameOf(code)}.js` };
4616
+ })
4617
+ );
4618
+ const next = [];
4619
+ for (const item of loaded) {
4620
+ urls.set(item.url, item.path);
4621
+ sources.push({ url: item.url, code: item.code });
4622
+ next.push(...findBlobRefs(item.code));
4623
+ }
4624
+ await loadLayer(next);
4625
+ };
4626
+ await loadLayer(findBlobRefs(html));
4627
+ const modules = {};
4628
+ for (const { url, code } of sources) {
4629
+ const path = urls.get(url);
4630
+ if (uploaded.has(path)) continue;
4631
+ modules[path] = rewriteRefs(code, urls);
4632
+ }
4633
+ const rewrittenHtml = rewriteRefs(html, urls);
4634
+ return {
4635
+ html: options.appendScript === void 0 ? rewrittenHtml : injectScript(rewrittenHtml, options.appendScript),
4636
+ modules,
4637
+ paths: [...new Set(urls.values())].toSorted(),
4638
+ urls
4639
+ };
4640
+ }
4641
+
3879
4642
  // src/persistence.ts
3880
4643
  function cloneEntries(entries) {
3881
4644
  return entries.map(
@@ -5427,6 +6190,7 @@ self.onmessage = async (event) => {
5427
6190
  const t = raw.trim();
5428
6191
  if (/^'.*'$/.test(t)) return t.slice(1, -1);
5429
6192
  if (/^".*"$/.test(t)) return t.slice(1, -1);
6193
+ if (/^NULL$/i.test(t)) return null;
5430
6194
  return t;
5431
6195
  }
5432
6196
  function parseCreateTable(ddl) {
@@ -5447,50 +6211,109 @@ self.onmessage = async (event) => {
5447
6211
  }
5448
6212
  return { name, columns };
5449
6213
  }
5450
- function parseWhereClauses(whereRaw, cursor) {
5451
- const clauses = [];
5452
- for (const part of whereRaw.split(/\s+AND\s+/i)) {
5453
- const t = part.trim();
5454
- if (t.length === 0) continue;
5455
- if (/\bIS\s+NULL\b/i.test(t)) {
5456
- const col2 = ident(t.split(/\s+IS\s+NULL\b/i)[0] ?? "");
5457
- clauses.push({ column: col2, operator: "IS NULL", value: null, list: false });
5458
- continue;
5459
- }
5460
- if (/\bIS\s+NOT\s+NULL\b/i.test(t)) {
5461
- const col2 = ident(t.split(/\s+IS\s+NOT\s+NULL\b/i)[0] ?? "");
5462
- clauses.push({ column: col2, operator: "IS NOT NULL", value: null, list: false });
5463
- continue;
5464
- }
5465
- const opMatch = /^\s*((?:"[^"]+")|([A-Za-z_][A-Za-z0-9_]*))\s*(=|!=|>=|<=|>|<|like|in|not\s+in)\s*(.+)$/i.exec(
5466
- t
5467
- );
5468
- if (opMatch === null) continue;
5469
- const col = ident(opMatch[1] ?? "");
5470
- const op = (opMatch[3] ?? opMatch[2] ?? "").toLowerCase();
5471
- const rhs = (opMatch[4] ?? "").trim();
5472
- if (op === "in" || op === "not in") {
5473
- const inner = rhs.replace(/^\(|\)$/g, "");
5474
- const items = splitListItems(inner);
5475
- const list = items.map((item) => {
5476
- if (item.trim() === "?") return cursor.take();
5477
- return stripQuotes(item);
5478
- });
5479
- clauses.push({ column: col, operator: op, value: list, list: true });
6214
+ function splitTopLevel(raw, token) {
6215
+ const parts = [];
6216
+ let depth = 0;
6217
+ let inQuote = false;
6218
+ let buffer = "";
6219
+ const n = raw.length;
6220
+ const isTokenAt = (i) => {
6221
+ const word = raw.slice(i, i + token.length);
6222
+ if (word.toUpperCase() !== token) return false;
6223
+ const before = i === 0 ? "" : raw[i - 1] ?? "";
6224
+ const after = raw[i + token.length] ?? "";
6225
+ return !/[A-Za-z0-9_.]/.test(before) && !/[A-Za-z0-9_.]/.test(after);
6226
+ };
6227
+ for (let i = 0; i < n; i += 1) {
6228
+ const ch = raw[i] ?? "";
6229
+ if (ch === "'") {
6230
+ if (inQuote && raw[i + 1] === "'") {
6231
+ buffer += ch + (raw[i + 1] ?? "");
6232
+ i += 1;
6233
+ continue;
6234
+ }
6235
+ inQuote = !inQuote;
6236
+ buffer += ch;
5480
6237
  continue;
5481
6238
  }
5482
- let value;
5483
- if (rhs === "?") {
5484
- value = cursor.take();
6239
+ if (!inQuote && ch === "(") depth += 1;
6240
+ else if (!inQuote && ch === ")") depth -= 1;
6241
+ if (!inQuote && depth === 0 && isTokenAt(i)) {
6242
+ parts.push(buffer);
6243
+ buffer = "";
6244
+ i += token.length - 1;
5485
6245
  } else {
5486
- value = stripQuotes(rhs);
6246
+ buffer += ch;
5487
6247
  }
5488
- clauses.push({ column: col, operator: op, value, list: false });
5489
6248
  }
5490
- return clauses;
6249
+ parts.push(buffer);
6250
+ return parts;
6251
+ }
6252
+ function unqualifyColumn(raw) {
6253
+ const t = raw.trim();
6254
+ const dot = t.lastIndexOf(".");
6255
+ if (dot > 0 && /^[A-Za-z_][A-Za-z0-9_]*\./.test(t)) return t.slice(dot + 1);
6256
+ return t;
6257
+ }
6258
+ function parseLeftJoins(tail) {
6259
+ const joins = [];
6260
+ const re = /LEFT\s+JOIN\s+((?:"[^"]+")|([A-Za-z_][A-Za-z0-9_]*))\s+([A-Za-z_][A-Za-z0-9_]*)\s+ON\s+([A-Za-z_][A-Za-z0-9_.]*)\s*=\s*([A-Za-z_][A-Za-z0-9_.]*)/gi;
6261
+ let m;
6262
+ while ((m = re.exec(tail)) !== null) {
6263
+ joins.push({
6264
+ table: ident(m[1] ?? ""),
6265
+ alias: m[3] ?? "",
6266
+ leftCol: unqualifyColumn(m[4] ?? ""),
6267
+ rightCol: unqualifyColumn(m[5] ?? "")
6268
+ });
6269
+ }
6270
+ return joins;
5491
6271
  }
5492
- function matchWhere(clauses, row) {
5493
- return clauses.every((c) => matchValue(row[c.column], c));
6272
+ function parseWhereClauses(whereRaw, cursor) {
6273
+ const parseAndGroup = (andRaw) => {
6274
+ const clauses = [];
6275
+ for (const part of splitTopLevel(andRaw, "AND")) {
6276
+ const t = part.trim();
6277
+ if (t.length === 0) continue;
6278
+ if (/\bIS\s+NULL\b/i.test(t)) {
6279
+ clauses.push({ column: unqualifyColumn(ident(t.split(/\s+IS\s+NULL\b/i)[0] ?? "")), operator: "IS NULL", value: null, list: false });
6280
+ continue;
6281
+ }
6282
+ if (/\bIS\s+NOT\s+NULL\b/i.test(t)) {
6283
+ clauses.push({ column: unqualifyColumn(ident(t.split(/\s+IS\s+NOT\s+NULL\b/i)[0] ?? "")), operator: "IS NOT NULL", value: null, list: false });
6284
+ continue;
6285
+ }
6286
+ const opMatch = /^\s*((?:"[^"]+")|([A-Za-z_][A-Za-z0-9_.]*))\s*(=|!=|>=|<=|>|<|like|in|not\s+in)\s*(.+)$/i.exec(
6287
+ t
6288
+ );
6289
+ if (opMatch === null) continue;
6290
+ const col = unqualifyColumn(ident(opMatch[1] ?? ""));
6291
+ const op = (opMatch[3] ?? opMatch[2] ?? "").toLowerCase();
6292
+ const rhs = (opMatch[4] ?? "").trim();
6293
+ if (op === "in" || op === "not in") {
6294
+ const inner = rhs.replace(/^\(|\)$/g, "");
6295
+ const items = splitListItems(inner);
6296
+ const list = items.map((item) => {
6297
+ if (item.trim() === "?") return cursor.take();
6298
+ return stripQuotes(item);
6299
+ });
6300
+ clauses.push({ column: col, operator: op, value: list, list: true });
6301
+ continue;
6302
+ }
6303
+ let value;
6304
+ if (rhs === "?") {
6305
+ value = cursor.take();
6306
+ } else {
6307
+ value = stripQuotes(rhs);
6308
+ }
6309
+ clauses.push({ column: col, operator: op, value, list: false });
6310
+ }
6311
+ return clauses;
6312
+ };
6313
+ return splitTopLevel(whereRaw, "OR").map((group) => group.trim()).filter((group) => group.length > 0).map(parseAndGroup);
6314
+ }
6315
+ function matchWhere(groups, row) {
6316
+ return groups.some((clauses) => clauses.every((c) => matchValue(row[c.column], c)));
5494
6317
  }
5495
6318
  function splitListItems(inner) {
5496
6319
  const items = [];
@@ -5510,6 +6333,168 @@ self.onmessage = async (event) => {
5510
6333
  items.push(buffer);
5511
6334
  return items;
5512
6335
  }
6336
+ var ExcludedRef = class {
6337
+ constructor(column) {
6338
+ this.column = column;
6339
+ }
6340
+ };
6341
+ var ColumnRef = class {
6342
+ constructor(column) {
6343
+ this.column = column;
6344
+ }
6345
+ };
6346
+ var ExprRef = class {
6347
+ constructor(source) {
6348
+ this.source = source;
6349
+ }
6350
+ };
6351
+ function resolveSetValue(value, existing, row) {
6352
+ if (value instanceof ExcludedRef) return row[value.column];
6353
+ if (value instanceof ColumnRef) return existing[value.column];
6354
+ if (value instanceof ExprRef) return evalArithmetic(value.source, existing, row);
6355
+ return value;
6356
+ }
6357
+ function evalArithmetic(src, existing, row) {
6358
+ const num = (v) => {
6359
+ const n2 = Number(v);
6360
+ return Number.isFinite(n2) ? n2 : 0;
6361
+ };
6362
+ let i = 0;
6363
+ const n = src.length;
6364
+ const skip = () => {
6365
+ while (i < n && /\s/.test(src[i] ?? "")) i += 1;
6366
+ };
6367
+ const peek = () => {
6368
+ skip();
6369
+ return i < n ? src[i] ?? "" : null;
6370
+ };
6371
+ const parseIdent = () => {
6372
+ skip();
6373
+ const m = /^([A-Za-z_][A-Za-z0-9_]*)/.exec(src.slice(i));
6374
+ if (m === null) return null;
6375
+ i += (m[1] ?? "").length;
6376
+ skip();
6377
+ let col = ident(m[1] ?? "");
6378
+ let excluded = false;
6379
+ if (src[i] === ".") {
6380
+ const m2 = /^\.([A-Za-z_][A-Za-z0-9_]*)/.exec(src.slice(i));
6381
+ if (m2 !== null) {
6382
+ i += (m2[0] ?? "").length;
6383
+ if (col.toLowerCase() === "excluded") excluded = true;
6384
+ col = ident(m2[1] ?? "");
6385
+ }
6386
+ }
6387
+ return { col, excluded };
6388
+ };
6389
+ const parseFactor = () => {
6390
+ const ch = peek();
6391
+ if (ch === "(") {
6392
+ i += 1;
6393
+ const v = parseExpr();
6394
+ skip();
6395
+ if (src[i] === ")") i += 1;
6396
+ return v;
6397
+ }
6398
+ const numMatch = /^(\d+(?:\.\d+)?)/.exec(src.slice(i));
6399
+ if (numMatch !== null) {
6400
+ i += (numMatch[1] ?? "").length;
6401
+ return Number(numMatch[1]);
6402
+ }
6403
+ const id = parseIdent();
6404
+ if (id !== null) {
6405
+ const v = id.excluded ? row[id.col] : existing[id.col];
6406
+ return num(v);
6407
+ }
6408
+ return 0;
6409
+ };
6410
+ const parseTerm = () => {
6411
+ let v = parseFactor();
6412
+ for (; ; ) {
6413
+ const ch = peek();
6414
+ if (ch !== "*" && ch !== "/") return v;
6415
+ i += 1;
6416
+ const rhs = parseFactor();
6417
+ v = ch === "*" ? v * rhs : rhs === 0 ? v : v / rhs;
6418
+ }
6419
+ };
6420
+ const parseExpr = () => {
6421
+ let v = parseTerm();
6422
+ for (; ; ) {
6423
+ const ch = peek();
6424
+ if (ch !== "+" && ch !== "-") return v;
6425
+ i += 1;
6426
+ const rhs = parseTerm();
6427
+ v = ch === "+" ? v + rhs : v - rhs;
6428
+ }
6429
+ };
6430
+ return parseExpr();
6431
+ }
6432
+ function splitInsertTuples(body) {
6433
+ const tuples = [];
6434
+ let i = 0;
6435
+ const n = body.length;
6436
+ while (i < n) {
6437
+ while (i < n && (body[i] === " " || body[i] === " " || body[i] === "\n" || body[i] === "\r" || body[i] === ",")) {
6438
+ i += 1;
6439
+ }
6440
+ if (i >= n) break;
6441
+ if (body[i] !== "(") {
6442
+ return { tuples, conflict: body.slice(i).trim() };
6443
+ }
6444
+ let depth = 0;
6445
+ let j = i;
6446
+ for (; j < n; j += 1) {
6447
+ if (body[j] === "(") depth += 1;
6448
+ else if (body[j] === ")") {
6449
+ depth -= 1;
6450
+ if (depth === 0) break;
6451
+ }
6452
+ }
6453
+ if (j >= n) return { tuples, conflict: null };
6454
+ tuples.push(body.slice(i + 1, j));
6455
+ i = j + 1;
6456
+ }
6457
+ return { tuples, conflict: null };
6458
+ }
6459
+ function parseConflictClause(clause, cursor, fallbackCols) {
6460
+ const m = /^ON\s+CONFLICT(?:\s*\(([^)]*)\))?\s+DO\s+(UPDATE\s+SET\s+([\s\S]+)|NOTHING\s*)$/i.exec(
6461
+ clause.trim()
6462
+ );
6463
+ if (m === null) {
6464
+ throw new SimDbError("DB_UNSAFE_OP", `\u65E0\u6CD5\u89E3\u6790 ON CONFLICT \u5B50\u53E5\uFF1A${clause.trim().slice(0, 60)}\u2026`);
6465
+ }
6466
+ const colsRaw = m[1];
6467
+ const cols = colsRaw === void 0 ? fallbackCols : colsRaw.split(",").map(ident);
6468
+ if (cols.length === 0) throw new SimDbError("DB_UNSAFE_OP", "ON CONFLICT \u51B2\u7A81\u5217\u4E3A\u7A7A");
6469
+ const action = m[2] ?? "";
6470
+ if (/^NOTHING/i.test(action)) return { cols, sets: [] };
6471
+ const setRaw = m[3] ?? "";
6472
+ const sets = splitListItems(setRaw).map((part) => {
6473
+ const eq = /^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*([\s\S]+)$/i.exec(part.trim());
6474
+ if (eq === null) {
6475
+ throw new SimDbError("DB_UNSAFE_OP", `\u65E0\u6CD5\u89E3\u6790 SET \u8D4B\u503C\uFF1A${part.trim().slice(0, 60)}\u2026`);
6476
+ }
6477
+ const col = ident(eq[1] ?? "");
6478
+ const rhs = (eq[2] ?? "").trim();
6479
+ let value;
6480
+ if (rhs === "?") {
6481
+ value = cursor.take();
6482
+ } else {
6483
+ const ex = /^excluded\.([A-Za-z_][A-Za-z0-9_]*)$/i.exec(rhs);
6484
+ if (ex !== null) {
6485
+ value = new ExcludedRef(ident(ex[1] ?? ""));
6486
+ } else if (/^([A-Za-z_][A-Za-z0-9_]*)$/.test(rhs) && !/^NULL$/i.test(rhs)) {
6487
+ value = new ColumnRef(ident(rhs));
6488
+ } else if (/^'.*'$/.test(rhs) || /^".*"$/.test(rhs) || /^NULL$/i.test(rhs)) {
6489
+ value = stripQuotes(rhs);
6490
+ } else {
6491
+ value = new ExprRef(rhs);
6492
+ }
6493
+ }
6494
+ return { col, value };
6495
+ });
6496
+ return { cols, sets };
6497
+ }
5513
6498
  function matchValue(value, clause) {
5514
6499
  const op = clause.operator;
5515
6500
  if (op === "IS NULL") return value === null || value === void 0;
@@ -5637,6 +6622,17 @@ self.onmessage = async (event) => {
5637
6622
  }
5638
6623
  return { changes: 0 };
5639
6624
  }
6625
+ if (/^CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?/i.test(stmt)) {
6626
+ 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(
6627
+ stmt
6628
+ );
6629
+ if (idx === null) throw new SimDbError("DB_UNSAFE_OP", `\u65E0\u6CD5\u89E3\u6790 CREATE INDEX \u8BED\u53E5`);
6630
+ const tableName = ident(idx[3]);
6631
+ if (this.tables[tableName] === void 0) {
6632
+ throw new SimDbError("DB_UNSAFE_OP", `CREATE INDEX \u76EE\u6807\u8868\u4E0D\u5B58\u5728\uFF1A${tableName}`);
6633
+ }
6634
+ return { changes: 0 };
6635
+ }
5640
6636
  if (/^INSERT\s+INTO/i.test(stmt)) return this.execInsert(stmt, params);
5641
6637
  if (/^UPDATE\s+/i.test(stmt)) return this.execUpdate(stmt, params);
5642
6638
  if (/^DELETE\s+FROM/i.test(stmt)) return this.execDelete(stmt, params);
@@ -5652,16 +6648,36 @@ self.onmessage = async (event) => {
5652
6648
  const valueBody = match[4].trim();
5653
6649
  const cursor = new ParamCursor(params);
5654
6650
  const table = this.ensureTable(tableName);
6651
+ const { tuples, conflict } = splitInsertTuples(valueBody);
6652
+ if (tuples.length === 0) throw new SimDbError("DB_UNSAFE_OP", "INSERT \u7F3A\u5C11 VALUES \u5143\u7EC4");
6653
+ const conflictSpec = conflict === null ? null : parseConflictClause(
6654
+ conflict,
6655
+ cursor,
6656
+ table.columns.filter((c) => c.primaryKey).map((c) => c.name)
6657
+ );
5655
6658
  let inserted = 0;
5656
- for (const group of splitListItems(valueBody)) {
5657
- const inner = group.trim().replace(/^\(|\)$/g, "");
5658
- const values = splitListItems(inner).map(
6659
+ for (const tuple of tuples) {
6660
+ const values = splitListItems(tuple).map(
5659
6661
  (item) => item.trim() === "?" ? cursor.take() : stripQuotes(item)
5660
6662
  );
5661
6663
  const row = {};
5662
6664
  cols.forEach((col, i) => {
5663
6665
  row[col] = values[i] ?? null;
5664
6666
  });
6667
+ if (conflictSpec !== null) {
6668
+ const existing = table.rows.find(
6669
+ (r) => conflictSpec.cols.every((c) => r[c] === row[c])
6670
+ );
6671
+ if (existing !== void 0) {
6672
+ const oldRow = { ...existing };
6673
+ for (const set of conflictSpec.sets) {
6674
+ existing[set.col] = resolveSetValue(set.value, oldRow, row);
6675
+ }
6676
+ inserted += 1;
6677
+ void this.persist();
6678
+ continue;
6679
+ }
6680
+ }
5665
6681
  this.applyAutoincrement(table, row);
5666
6682
  table.rows.push(row);
5667
6683
  inserted += 1;
@@ -5730,6 +6746,20 @@ self.onmessage = async (event) => {
5730
6746
  return project(this.catalog(), selectRaw);
5731
6747
  }
5732
6748
  const table = this.ensureTable(tableName);
6749
+ let rows = table.rows;
6750
+ const joins = parseLeftJoins(tail);
6751
+ if (joins.length > 0) {
6752
+ rows = table.rows.map((row) => {
6753
+ const merged = { ...row };
6754
+ for (const j of joins) {
6755
+ const joined = this.tables[j.table]?.rows.find((jr) => jr[j.leftCol] === merged[j.rightCol]);
6756
+ if (joined !== void 0) {
6757
+ for (const [k, v] of Object.entries(joined)) merged[`${j.alias}.${k}`] = v;
6758
+ }
6759
+ }
6760
+ return merged;
6761
+ });
6762
+ }
5733
6763
  const whereMatch = /\bWHERE\b/i.exec(tail);
5734
6764
  const orderMatch = /\bORDER\s+BY\b/i.exec(tail);
5735
6765
  const limitMatch = /\bLIMIT\b/i.exec(tail);
@@ -5738,7 +6768,6 @@ self.onmessage = async (event) => {
5738
6768
  whereMatch.index + whereMatch[0].length,
5739
6769
  indexAfter(whereMatch.index, [orderMatch, limitMatch, offsetMatch], tail)
5740
6770
  );
5741
- let rows = table.rows;
5742
6771
  if (whereRaw.trim().length > 0) {
5743
6772
  const clauses = parseWhereClauses(whereRaw, cursor);
5744
6773
  rows = rows.filter((row) => matchWhere(clauses, row));
@@ -5748,9 +6777,9 @@ self.onmessage = async (event) => {
5748
6777
  orderMatch.index + orderMatch[0].length,
5749
6778
  indexAfter(orderMatch.index, [limitMatch, offsetMatch], tail)
5750
6779
  );
5751
- const oc = /^\s*((?:"[^"]+")|([A-Za-z_][A-Za-z0-9_]*))\s+(asc|desc)/i.exec(orderRaw);
6780
+ const oc = /^\s*((?:"[^"]+")|([A-Za-z_][A-Za-z0-9_.]*))\s+(asc|desc)/i.exec(orderRaw);
5752
6781
  if (oc !== null) {
5753
- const col = ident(oc[1]);
6782
+ const col = unqualifyColumn(ident(oc[1]));
5754
6783
  const dir = oc[3].toLowerCase();
5755
6784
  rows = [...rows].toSorted((a, b) => {
5756
6785
  const av = a[col];
@@ -5795,6 +6824,15 @@ self.onmessage = async (event) => {
5795
6824
  const end = candidates.length === 0 ? -1 : Math.min(...candidates);
5796
6825
  return end === -1 ? tail.length : end;
5797
6826
  }
6827
+ function parseSelectItem(raw) {
6828
+ const t = raw.trim();
6829
+ const as = /\s+AS\s+([A-Za-z_][A-Za-z0-9_]*)$/i.exec(t);
6830
+ let name = as === null ? t : t.slice(0, as.index).trim();
6831
+ if (unqualifyColumn(name) === "*") return { name: "", qualified: "", alias: "", star: true };
6832
+ const qualified = /^[A-Za-z_][A-Za-z0-9_]*\.[A-Za-z_][A-Za-z0-9_]*$/.test(name) ? ident(name) : "";
6833
+ const plain = unqualifyColumn(ident(name));
6834
+ return { name: plain, qualified, alias: as === null ? plain : ident(as[1] ?? ""), star: false };
6835
+ }
5798
6836
  function project(rows, selectRaw) {
5799
6837
  if (/^count\s*\(\s*\*/i.test(selectRaw) || /^count\s*\(\s*1\)/i.test(selectRaw)) {
5800
6838
  const alias = selectRaw.match(/\bAS\s+([A-Za-z_][A-Za-z0-9_]*)/i)?.[1] ?? "n";
@@ -5805,10 +6843,21 @@ self.onmessage = async (event) => {
5805
6843
  return [{ [constMatch[2]]: Number(constMatch[1]) }];
5806
6844
  }
5807
6845
  if (selectRaw.trim() === "*") return rows;
5808
- const cols = selectRaw.split(",").map((s) => ident(s.trim()));
6846
+ const items = selectRaw.split(",").map(parseSelectItem);
6847
+ const valueOf = (row, item) => item.qualified !== "" && row[item.qualified] !== void 0 ? row[item.qualified] : row[item.name];
6848
+ if (items.some((item) => item.star)) {
6849
+ return rows.map((row) => {
6850
+ const out = { ...row };
6851
+ for (const item of items) {
6852
+ if (item.star) continue;
6853
+ out[item.alias] = valueOf(row, item);
6854
+ }
6855
+ return out;
6856
+ });
6857
+ }
5809
6858
  return rows.map((row) => {
5810
6859
  const out = {};
5811
- for (const col of cols) out[col] = row[col];
6860
+ for (const item of items) out[item.alias] = valueOf(row, item);
5812
6861
  return out;
5813
6862
  });
5814
6863
  }
@@ -5881,6 +6930,19 @@ self.onmessage = async (event) => {
5881
6930
  }
5882
6931
  return path;
5883
6932
  }
6933
+ function assertStoragePrefix(prefix) {
6934
+ if (prefix !== void 0 && prefix !== "") {
6935
+ const segments = prefix.split("/");
6936
+ if (prefix.startsWith("/") || /[\\]/.test(prefix) || segments.some((segment) => segment === "..")) {
6937
+ throw new StorageError(
6938
+ 400,
6939
+ STORAGE_CODES.invalidPath,
6940
+ `\u975E\u6CD5\u524D\u7F00 "${prefix}"\uFF08\u7981\u6B62 / \u5F00\u5934\u3001\u53CD\u659C\u6760\u6216 .. \u7A7F\u8D8A\uFF09`
6941
+ );
6942
+ }
6943
+ }
6944
+ return prefix ?? "";
6945
+ }
5884
6946
 
5885
6947
  // ../runtime/src/storage/hmac-sha256.ts
5886
6948
  var K = new Uint32Array([
@@ -6200,16 +7262,7 @@ self.onmessage = async (event) => {
6200
7262
  await saveBucket(bucket);
6201
7263
  },
6202
7264
  async list(_projectId, prefix) {
6203
- if (prefix !== void 0 && prefix !== "") {
6204
- const segments = prefix.split("/");
6205
- if (prefix.startsWith("/") || /[\\]/.test(prefix) || segments.some((segment) => segment === "..")) {
6206
- throw new StorageError(
6207
- 400,
6208
- STORAGE_CODES.invalidPath,
6209
- `\u975E\u6CD5\u524D\u7F00 "${prefix}"\uFF08\u7981\u6B62 / \u5F00\u5934\u3001\u53CD\u659C\u6760\u6216 .. \u7A7F\u8D8A\uFF09`
6210
- );
6211
- }
6212
- }
7265
+ assertStoragePrefix(prefix);
6213
7266
  const bucket = await loadBucket();
6214
7267
  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);
6215
7268
  },
@@ -6596,6 +7649,19 @@ self.onmessage = async (event) => {
6596
7649
  };
6597
7650
  }
6598
7651
 
7652
+ // ../runtime/src/functions/runtime/rpc-wire.ts
7653
+ function wireRpcResponses(port, pending) {
7654
+ port.on?.((message) => {
7655
+ const reply = message;
7656
+ if (reply?.type !== "rpc-response" || typeof reply.id !== "number") return;
7657
+ const entry = pending.get(reply.id);
7658
+ if (entry === void 0) return;
7659
+ pending.delete(reply.id);
7660
+ if (reply.ok === true) entry.resolve(reply.result);
7661
+ else entry.reject(new Error(reply.error ?? "RPC \u80FD\u529B\u8C03\u7528\u5931\u8D25"));
7662
+ });
7663
+ }
7664
+
6599
7665
  // src/sim/ctx.ts
6600
7666
  function createLocalPort(handler) {
6601
7667
  const listeners = [];
@@ -6625,17 +7691,6 @@ self.onmessage = async (event) => {
6625
7691
  }
6626
7692
  };
6627
7693
  }
6628
- function wireRpcResponses(port, pending) {
6629
- port.on((message) => {
6630
- const reply = message;
6631
- if (reply?.type !== "rpc-response" || typeof reply.id !== "number") return;
6632
- const entry = pending.get(reply.id);
6633
- if (entry === void 0) return;
6634
- pending.delete(reply.id);
6635
- if (reply.ok === true) entry.resolve(reply.result);
6636
- else entry.reject(new Error(reply.error ?? "RPC \u80FD\u529B\u8C03\u7528\u5931\u8D25"));
6637
- });
6638
- }
6639
7694
  function createFlatRpcClient(handler) {
6640
7695
  return new Proxy(
6641
7696
  {},
@@ -6849,6 +7904,27 @@ self.onmessage = async (event) => {
6849
7904
  return { run };
6850
7905
  }
6851
7906
 
7907
+ // ../runtime/src/sim/merge.ts
7908
+ function mergeBundles(bundles) {
7909
+ const capabilities = [];
7910
+ const byName = /* @__PURE__ */ new Map();
7911
+ for (const bundle of bundles) {
7912
+ for (const cap of bundle.capabilities) {
7913
+ const existing = byName.get(cap.name);
7914
+ if (existing !== void 0) capabilities.splice(capabilities.indexOf(existing), 1);
7915
+ byName.set(cap.name, cap);
7916
+ capabilities.push(cap);
7917
+ }
7918
+ }
7919
+ const rpcHandlers = {};
7920
+ for (const bundle of bundles) {
7921
+ for (const [name, handler] of Object.entries(bundle.rpcHandlers)) {
7922
+ rpcHandlers[name] = handler;
7923
+ }
7924
+ }
7925
+ return { capabilities, rpcHandlers };
7926
+ }
7927
+
6852
7928
  // ../runtime/src/database/sdk/kv.ts
6853
7929
  var KV_TABLE = "_adep_kv";
6854
7930
  var KV_RPC = {
@@ -6950,25 +8026,6 @@ self.onmessage = async (event) => {
6950
8026
  }
6951
8027
 
6952
8028
  // src/sim/runtime.ts
6953
- function mergeBundles(bundles) {
6954
- const capabilities = [];
6955
- const byName = /* @__PURE__ */ new Map();
6956
- for (const bundle of bundles) {
6957
- for (const cap of bundle.capabilities) {
6958
- const existing = byName.get(cap.name);
6959
- if (existing !== void 0) capabilities.splice(capabilities.indexOf(existing), 1);
6960
- byName.set(cap.name, cap);
6961
- capabilities.push(cap);
6962
- }
6963
- }
6964
- const rpcHandlers = {};
6965
- for (const bundle of bundles) {
6966
- for (const [name, handler] of Object.entries(bundle.rpcHandlers)) {
6967
- rpcHandlers[name] = handler;
6968
- }
6969
- }
6970
- return { capabilities, rpcHandlers };
6971
- }
6972
8029
  async function createBrowserSimRuntime(options) {
6973
8030
  const kv = options.kv ?? pickDefaultSimKv();
6974
8031
  const db = createBrowserSimDb({ projectId: options.projectId, kv });
@@ -6999,5 +8056,6 @@ self.onmessage = async (event) => {
6999
8056
 
7000
8057
  // src/index.ts
7001
8058
  init_function_fetch_proxy();
8059
+ init_console_relay();
7002
8060
  return __toCommonJS(index_exports);
7003
8061
  })();