@adep/web-container 0.2.1 → 0.2.2

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.
@@ -118,6 +118,27 @@ var AdepWebContainer = (() => {
118
118
  }
119
119
  return abs;
120
120
  }
121
+ function pickConditionTarget(conditions, order, resolveRel, context) {
122
+ for (const key of order) {
123
+ const value = conditions[key];
124
+ if (value === void 0 || value === null) continue;
125
+ if (typeof value === "string") return resolveRel(value);
126
+ if (typeof value === "object" && !Array.isArray(value)) {
127
+ const nested = pickConditionTarget(
128
+ value,
129
+ order,
130
+ resolveRel,
131
+ context
132
+ );
133
+ if (nested !== null) return nested;
134
+ continue;
135
+ }
136
+ throw new ResolveError(
137
+ `${context}\uFF1Aexports["."]["${key}"] \u5F62\u6001\u4E0D\u652F\u6301\uFF08\u4EC5\u63A5\u53D7\u5B57\u7B26\u4E32 / null / \u6761\u4EF6\u5BF9\u8C61\uFF09`
138
+ );
139
+ }
140
+ return null;
141
+ }
121
142
  function resolvePackageEntry(meta, pkgDirAbs, condition) {
122
143
  const context = `\u5305 ${meta.name ?? meta.version ?? pkgDirAbs} \u7684 exports/main \u58F0\u660E`;
123
144
  const exp = meta.exports;
@@ -138,20 +159,11 @@ var AdepWebContainer = (() => {
138
159
  if (typeof dot !== "object" || Array.isArray(dot)) {
139
160
  throw new ResolveError(`${context}\uFF1Aexports["."] \u5F62\u6001\u4E0D\u652F\u6301\uFF08\u4EC5\u63A5\u53D7\u5B57\u7B26\u4E32\u6216\u6761\u4EF6\u5BF9\u8C61\uFF09`);
140
161
  }
141
- const conditions = dot;
142
- const order = condition === "import" ? ["import", "node", "default"] : ["require", "node", "default"];
143
- for (const key of order) {
144
- const value = conditions[key];
145
- if (typeof value === "string") return withinPackage(pkgDirAbs, value, context);
146
- if (value !== void 0 && (typeof value !== "object" || value === null)) {
147
- throw new ResolveError(
148
- `${context}\uFF1Aexports["."]["${key}"] \u5F62\u6001\u4E0D\u652F\u6301\uFF08\u4EC5\u63A5\u53D7\u5B57\u7B26\u4E32\u6216 null\uFF09`
149
- );
150
- }
151
- }
152
- throw new ResolveError(
153
- `${context}\uFF1Aexports["."] \u6761\u4EF6\u5BF9\u8C61\u91CC\u6CA1\u6709 ${condition}/node/default \u5B57\u7B26\u4E32\u5165\u53E3\uFF08\u5B50\u8DEF\u5F84/\u5D4C\u5957\u6761\u4EF6\u4E0D\u652F\u6301\uFF09`
154
- );
162
+ const order = condition === "import" ? IMPORT_CONDITION_ORDER : REQUIRE_CONDITION_ORDER;
163
+ const resolveRel = (rel) => withinPackage(pkgDirAbs, rel, context);
164
+ const hit = pickConditionTarget(dot, order, resolveRel, context);
165
+ if (hit !== null) return hit;
166
+ throw new ResolveError(`${context}\uFF1Aexports["."] \u6761\u4EF6\u5BF9\u8C61\u91CC\u6CA1\u6709 ${order.join("/")} \u5165\u53E3`);
155
167
  }
156
168
  if (meta.main !== void 0) {
157
169
  if (typeof meta.main !== "string") {
@@ -249,11 +261,13 @@ var AdepWebContainer = (() => {
249
261
  `\u627E\u4E0D\u5230\u5305 "${specifier}"\uFF1A${dirname(fromFileAbs)} \u53CA\u5176\u5404\u7EA7\u7236\u76EE\u5F55\u4E0B\u90FD\u6CA1\u6709 node_modules/${name}\uFF08\u5148\u5728\u7EC8\u7AEF npm install ${name}\uFF09`
250
262
  );
251
263
  }
252
- var RESOLVE_EXTENSIONS, ResolveError;
264
+ var IMPORT_CONDITION_ORDER, REQUIRE_CONDITION_ORDER, RESOLVE_EXTENSIONS, ResolveError;
253
265
  var init_node_resolve = __esm({
254
266
  "src/node-resolve.ts"() {
255
267
  "use strict";
256
268
  init_path();
269
+ IMPORT_CONDITION_ORDER = ["browser", "import", "module", "default"];
270
+ REQUIRE_CONDITION_ORDER = ["require", "node", "default"];
257
271
  RESOLVE_EXTENSIONS = [".js", ".mjs", ".cjs", ".json"];
258
272
  ResolveError = class extends Error {
259
273
  constructor(message) {
@@ -528,6 +542,7 @@ var AdepWebContainer = (() => {
528
542
  return;
529
543
  case "as":
530
544
  case "satisfies": {
545
+ if (this.frames[this.frames.length - 1]?.specifierList === true) return;
531
546
  if (this.tokenAt(2) === "*" || this.tokenAt(2) === "type") return;
532
547
  const nextChar = this.skipWhitespaceFrom(this.i);
533
548
  if (nextChar === null || "=,:]})".includes(this.src[nextChar])) return;
@@ -580,7 +595,8 @@ var AdepWebContainer = (() => {
580
595
  const frame = {
581
596
  kind: c === "(" ? "paren" : c === "{" ? "brace" : "bracket",
582
597
  declare: false,
583
- classBody: false
598
+ classBody: false,
599
+ specifierList: c === "{" && this.isImportSpecifierBrace()
584
600
  };
585
601
  if (c === "{" && this.pendingClassBody) {
586
602
  frame.classBody = true;
@@ -666,6 +682,15 @@ var AdepWebContainer = (() => {
666
682
  this.i = end;
667
683
  return true;
668
684
  }
685
+ /**
686
+ * `{` 是 import / export 的说明符列表吗——`{ a as b }` 覆盖 `import { … }`、
687
+ * `export { … }` 与 `import def, { … }` 三种写法(后者说明符花括号的前驱 token 是 `,`)。
688
+ */
689
+ isImportSpecifierBrace() {
690
+ const back1 = this.tokenAt(1);
691
+ if (back1 === "import" || back1 === "export") return true;
692
+ return back1 === "," && this.tokenAt(3) === "import";
693
+ }
669
694
  /**
670
695
  * `(` 是否为参数列表(声明位):`function f(`、类体里的方法 `m(`、箭头 `=> (`,
671
696
  * 以及出现在 `(` `,` `=` `>` `:` `[` `{` `}` `;` 之后(如 `map((v: T) => v)` 的内层括号)。
@@ -677,6 +702,7 @@ var AdepWebContainer = (() => {
677
702
  if (this.afterFunctionKeyword) return true;
678
703
  if (this.tokenAt(2) === "function" && IDENT_START.test(this.tokenAt(1))) return true;
679
704
  if (this.afterArrow) return true;
705
+ if (this.tokenAt(1) === "return") return true;
680
706
  if (this.inClassBody() && IDENT_PART.test(this.prevSignificantChar(at - 1))) return true;
681
707
  const prev = this.prevSignificantChar(at - 1);
682
708
  return prev === "" || "(,=>:[{};".includes(prev);
@@ -1185,7 +1211,10 @@ var AdepWebContainer = (() => {
1185
1211
  " }",
1186
1212
  " var u;",
1187
1213
  " try { u = new URL(urlStr, document.baseURI); }",
1188
- " catch (e) { return ORIGINAL_FETCH(input, init); }",
1214
+ " catch (e0) {",
1215
+ " try { u = new URL(urlStr, window.location.origin); }",
1216
+ " catch (e1) { return ORIGINAL_FETCH(input, init); }",
1217
+ " }",
1189
1218
  ' if (u.pathname.indexOf("/api/") !== 0 && u.pathname !== "/api") {',
1190
1219
  " return ORIGINAL_FETCH(input, init);",
1191
1220
  " }",
@@ -1324,6 +1353,18 @@ var AdepWebContainer = (() => {
1324
1353
  "export default css;"
1325
1354
  ].join("\n");
1326
1355
  }
1356
+ function inlineStyleBlock(css, key) {
1357
+ return [
1358
+ "{",
1359
+ `const css = ${JSON.stringify(css)};`,
1360
+ 'const el = document.createElement("style");',
1361
+ 'el.setAttribute("data-adep-vite", "");',
1362
+ `el.setAttribute("data-adep-style", ${JSON.stringify(key)});`,
1363
+ "el.textContent = css;",
1364
+ "document.head.appendChild(el);",
1365
+ "}"
1366
+ ].join("\n");
1367
+ }
1327
1368
  function jsonModule(source, abs) {
1328
1369
  try {
1329
1370
  JSON.parse(source);
@@ -1374,6 +1415,17 @@ var AdepWebContainer = (() => {
1374
1415
  } catch {
1375
1416
  }
1376
1417
  };
1418
+ const DEFINES = [
1419
+ [/\bprocess\s*\.\s*env\s*\.\s*NODE_ENV\b/g, JSON.stringify("development")],
1420
+ [/\b__VUE_OPTIONS_API__\b/g, "true"],
1421
+ [/\b__VUE_PROD_DEVTOOLS__\b/g, "false"],
1422
+ [/\b__VUE_PROD_HYDRATION_MISMATCH_DETAILS__\b/g, "false"]
1423
+ ];
1424
+ function applyDefines(code) {
1425
+ let out = code;
1426
+ for (const [pattern, value] of DEFINES) out = out.replace(pattern, value);
1427
+ return out;
1428
+ }
1377
1429
  function transformModule2(abs, source) {
1378
1430
  if (abs.endsWith(".css")) return cssModule(source);
1379
1431
  if (abs.endsWith(".json")) return jsonModule(source, abs);
@@ -1384,21 +1436,27 @@ var AdepWebContainer = (() => {
1384
1436
  `${abs} \u662F Vue SFC\uFF0C\u4F46\u5F53\u524D\u73AF\u5883\u672A\u88C5\u914D SFC \u7F16\u8BD1\u5668\uFF08IDE \u4FA7\u9700\u6CE8\u5165 vue/compiler-sfc\uFF09`
1385
1437
  );
1386
1438
  const compiled = sfcCompiler(source, abs);
1387
- return [...compiled.styles.map((css) => cssModule(css)), compiled.script].join("\n");
1439
+ return [
1440
+ ...compiled.styles.map((css, index) => inlineStyleBlock(css, `${abs}#${index}`)),
1441
+ applyDefines(stripTypes(compiled.script))
1442
+ ].join("\n");
1388
1443
  }
1389
1444
  if (abs.endsWith(".tsx") || abs.endsWith(".jsx"))
1390
1445
  throw new ViteDevError(
1391
1446
  "JSX_UNSUPPORTED",
1392
1447
  `${abs} \u4F7F\u7528 JSX\uFF1A\u6D4F\u89C8\u5668\u5185 vite \u53EA\u64E6\u9664 TS \u7C7B\u578B\u6807\u6CE8\uFF0C\u4E0D\u8F6C\u8BD1 JSX\uFF08\u8BF7\u7528 h() \u6E32\u67D3\u51FD\u6570\u6216 .vue SFC\uFF09`
1393
1448
  );
1394
- if (abs.endsWith(".ts") || abs.endsWith(".mts")) return stripTypes(source);
1395
- return source;
1449
+ if (abs.endsWith(".ts") || abs.endsWith(".mts")) return applyDefines(stripTypes(source));
1450
+ return applyDefines(source);
1451
+ }
1452
+ function absoluteFromRoot(spec) {
1453
+ return join(root, spec.replace(/^\/+/, ""));
1396
1454
  }
1397
1455
  async function resolveSpecifier(spec, importerAbs) {
1398
1456
  if (EXTERNAL_SPECIFIER.test(spec) || DATA_OR_BLOB.test(spec)) return spec;
1399
1457
  let target;
1400
1458
  if (spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/")) {
1401
- const base = spec.startsWith("/") ? spec : join(dirname(importerAbs), spec);
1459
+ const base = spec.startsWith("/") ? absoluteFromRoot(spec) : join(dirname(importerAbs), spec);
1402
1460
  target = resolveWithSuffixes(vfs, base);
1403
1461
  if (!vfs.exists(target) || vfs.isDirectory(target))
1404
1462
  throw new ViteDevError(
@@ -1487,7 +1545,7 @@ var AdepWebContainer = (() => {
1487
1545
  html = html.replace(
1488
1546
  MODULE_SCRIPT_SRC_RE,
1489
1547
  (_whole, pre, _q1, mid, _q2, src, post) => {
1490
- const base = src.startsWith("/") ? normalize(src) : join(dirname(entryAbs), src);
1548
+ const base = src.startsWith("/") ? absoluteFromRoot(src) : join(dirname(entryAbs), src);
1491
1549
  const abs = resolveWithSuffixes(vfs, base);
1492
1550
  if (!vfs.exists(abs) || vfs.isDirectory(abs))
1493
1551
  throw new ViteDevError(
@@ -1495,7 +1553,7 @@ var AdepWebContainer = (() => {
1495
1553
  `\u5165\u53E3 module script \u627E\u4E0D\u5230 "${src}"\uFF08root: ${root}\uFF1B\u8BD5\u8FC7\u6269\u5C55\u540D ${VITE_RESOLVE_SUFFIXES.join("/")} \u4E0E\u76EE\u5F55 index\uFF09`
1496
1554
  );
1497
1555
  entryModuleUrls.push(loadModuleUrl(abs));
1498
- return `<script${pre}${mid}src="__adep_vite_entry_${entryModuleUrls.length - 1}__"${post}><\/script>`;
1556
+ return `<script${pre}${mid}src="__adep_vite_entry_${entryModuleUrls.length - 1}__"${post} type="module"><\/script>`;
1499
1557
  }
1500
1558
  );
1501
1559
  html = html.replace(
@@ -1505,7 +1563,7 @@ var AdepWebContainer = (() => {
1505
1563
  const abs = `${INLINE_PREFIX}${inlineSeq++}.mjs`;
1506
1564
  inlineSources.set(abs, body);
1507
1565
  entryModuleUrls.push(loadModuleUrl(abs));
1508
- return `<script${pre}${post}src="__adep_vite_entry_${entryModuleUrls.length - 1}__"><\/script>`;
1566
+ return `<script${pre}${post}src="__adep_vite_entry_${entryModuleUrls.length - 1}__" type="module"><\/script>`;
1509
1567
  }
1510
1568
  );
1511
1569
  const urls = await Promise.all(entryModuleUrls);
@@ -4559,6 +4617,8 @@ self.onmessage = async (event) => {
4559
4617
  var DB_RPC = {
4560
4618
  /** 直通方法(如 query):`(method=query, args=[sql, params])`。 */
4561
4619
  query: "query",
4620
+ /** 写路径(CF-013):`(method=writeQuery, args=[sql, params])` → `{ changes }`。 */
4621
+ writeQuery: "writeQuery",
4562
4622
  /** 读取 owned 表变更流(DB-006):`(method=changes, args=[table, query])`。 */
4563
4623
  changes: "changes",
4564
4624
  /** 开启事务:`begin → txId`。 */
@@ -4635,21 +4695,35 @@ self.onmessage = async (event) => {
4635
4695
  function stripLiterals(sql) {
4636
4696
  return sql.replace(/'[^']*(?:''[^']*)*'/g, "").replace(/"[^"]*(?:""[^"]*)*"/g, "").replace(/--[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
4637
4697
  }
4638
- function assertReadOnlyQuery(sql) {
4698
+ function sqlHead(sql) {
4699
+ return sql.trim().replace(/^\(+/, "").trim().toUpperCase();
4700
+ }
4701
+ function assertSafeStatement(sql) {
4639
4702
  const stripped = stripLiterals(sql);
4640
4703
  if (stripped.includes(";")) {
4641
4704
  throw unsafeOperation("\u4EC5\u5141\u8BB8\u5355\u6761\u8BED\u53E5\uFF0C\u7981\u6B62\u591A\u8BED\u53E5\u5806\u53E0");
4642
4705
  }
4643
- const head = stripped.trim().replace(/^\(+/, "").trim().toUpperCase();
4644
- if (!head.startsWith("SELECT") && !head.startsWith("WITH")) {
4645
- throw unsafeOperation("cloud.db.query \u4EC5\u5141\u8BB8\u53EA\u8BFB\u67E5\u8BE2\uFF08SELECT / WITH\uFF09");
4646
- }
4647
4706
  if (/ATTACH|DETACH/.test(stripped.toUpperCase())) {
4648
4707
  throw unsafeOperation("\u7981\u6B62\u8DE8\u5E93\u64CD\u4F5C\uFF08ATTACH / DETACH\uFF09");
4649
4708
  }
4650
4709
  if (/SQLITE_\w+/i.test(stripped)) {
4651
4710
  throw unsafeOperation("\u7981\u6B62\u8BBF\u95EE\u7CFB\u7EDF\u8868\uFF08sqlite_*\uFF09");
4652
4711
  }
4712
+ return sqlHead(stripped);
4713
+ }
4714
+ function assertReadOnlyQuery(sql) {
4715
+ const head = assertSafeStatement(sql);
4716
+ if (!head.startsWith("SELECT") && !head.startsWith("WITH")) {
4717
+ throw unsafeOperation("cloud.db.query \u4EC5\u5141\u8BB8\u53EA\u8BFB\u67E5\u8BE2\uFF08SELECT / WITH\uFF09");
4718
+ }
4719
+ }
4720
+ function assertWriteQuery(sql) {
4721
+ const head = assertSafeStatement(sql);
4722
+ if (!head.startsWith("INSERT") && !head.startsWith("UPDATE") && !head.startsWith("DELETE")) {
4723
+ throw unsafeOperation(
4724
+ "cloud.db.writeQuery \u4EC5\u5141\u8BB8 DML\uFF08INSERT / UPDATE / DELETE\uFF09\uFF0CDDL \u8BF7\u8D70\u63A7\u5236\u53F0"
4725
+ );
4726
+ }
4653
4727
  }
4654
4728
 
4655
4729
  // ../runtime/src/database/builder/owned.ts
@@ -5195,6 +5269,14 @@ self.onmessage = async (event) => {
5195
5269
  assertReadOnlyQuery(sql);
5196
5270
  return driver.all(sql, params);
5197
5271
  },
5272
+ async writeQuery(sql, params) {
5273
+ if (!Array.isArray(params)) {
5274
+ throw unsafeOperation("writeQuery \u7684 params \u5FC5\u987B\u63D0\u4F9B\uFF08\u65E0\u53C2\u4F20 []\uFF09");
5275
+ }
5276
+ guardWrite();
5277
+ assertWriteQuery(sql);
5278
+ return driver.run(sql, params);
5279
+ },
5198
5280
  async changes(table, query = {}) {
5199
5281
  return readChanges(driver, table, query);
5200
5282
  }
@@ -5210,7 +5292,8 @@ self.onmessage = async (event) => {
5210
5292
  rootMethod: "table",
5211
5293
  stepMethods: ["select", "where", "orderBy", "limit", "offset"],
5212
5294
  terminalMethods: ["get", "first", "count", "insert", "insertMany", "update", "delete"],
5213
- directMethods: ["query", "changes"],
5295
+ // CF-013:writeQuery 是 D1 shim 的写路径(INSERT/UPDATE/DELETE),与 query 并列直通方法。
5296
+ directMethods: ["query", "writeQuery", "changes"],
5214
5297
  transactionMethod: "transaction"
5215
5298
  };
5216
5299
  var WRITE_TERMINALS = /* @__PURE__ */ new Set(["insert", "insertMany", "update", "delete"]);
@@ -5265,6 +5348,10 @@ self.onmessage = async (event) => {
5265
5348
  const [sql, params] = args;
5266
5349
  return await db.query(sql, params);
5267
5350
  }
5351
+ case DB_RPC.writeQuery: {
5352
+ const [sql, params] = args;
5353
+ return await db.writeQuery(sql, params);
5354
+ }
5268
5355
  case DB_RPC.changes: {
5269
5356
  const [table, query] = args;
5270
5357
  return await db.changes(table, query);
@@ -5994,9 +6081,12 @@ self.onmessage = async (event) => {
5994
6081
  const handler = async (method, args) => {
5995
6082
  switch (method) {
5996
6083
  case "upload": {
5997
- const [path, data] = args;
6084
+ const [path, data, options] = args;
5998
6085
  return toStoredFile(
5999
- await driver.put(projectId, path, asBytes(data), { visibility: DEFAULT_VISIBILITY })
6086
+ await driver.put(projectId, path, asBytes(data), {
6087
+ visibility: DEFAULT_VISIBILITY,
6088
+ ...options?.contentType === void 0 ? {} : { contentType: options.contentType }
6089
+ })
6000
6090
  );
6001
6091
  }
6002
6092
  case "get": {
@@ -6443,6 +6533,10 @@ self.onmessage = async (event) => {
6443
6533
  realtime: {
6444
6534
  code: "REALTIME_NOT_AVAILABLE",
6445
6535
  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"
6536
+ },
6537
+ kv: {
6538
+ code: "KV_NOT_PROVISIONED",
6539
+ message: "\u9879\u76EE KV \u5B58\u50A8\u672A\u53EF\u7528\uFF1Akv \u968F\u9879\u76EE\u6570\u636E\u5E93\u63D0\u4F9B\uFF0C\u8BF7\u5148\u542F\u52A8\u6570\u636E\u5E93\uFF08KV_NOT_PROVISIONED\uFF09"
6446
6540
  }
6447
6541
  };
6448
6542
  var CapabilityNotRegisteredError = class extends Error {
@@ -6755,6 +6849,106 @@ self.onmessage = async (event) => {
6755
6849
  return { run };
6756
6850
  }
6757
6851
 
6852
+ // ../runtime/src/database/sdk/kv.ts
6853
+ var KV_TABLE = "_adep_kv";
6854
+ var KV_RPC = {
6855
+ get: "get",
6856
+ put: "put",
6857
+ delete: "delete",
6858
+ list: "list"
6859
+ };
6860
+ var KV_CAPABILITY_CODES = {
6861
+ invalidMethod: "KV_INVALID_METHOD"
6862
+ };
6863
+ var KV_LIST_DEFAULT_LIMIT = 100;
6864
+ function nowSeconds() {
6865
+ return Math.floor(Date.now() / 1e3);
6866
+ }
6867
+ function errorWithCode2(error) {
6868
+ const code = typeof error === "object" && error !== null && typeof error.code === "string" ? error.code : void 0;
6869
+ if (code !== void 0 && error instanceof Error) {
6870
+ return new Error(`[${code}] ${error.message}`);
6871
+ }
6872
+ return error;
6873
+ }
6874
+ function createKvCapability(driver) {
6875
+ let ensurePromise = null;
6876
+ const ensureTable = () => {
6877
+ if (ensurePromise === null) {
6878
+ ensurePromise = driver.run(
6879
+ `CREATE TABLE IF NOT EXISTS ${KV_TABLE} (key TEXT PRIMARY KEY, value TEXT, expires_at INTEGER)`
6880
+ ).then(() => void 0);
6881
+ }
6882
+ return ensurePromise;
6883
+ };
6884
+ const handler = async (method, args) => {
6885
+ try {
6886
+ await ensureTable();
6887
+ switch (method) {
6888
+ case KV_RPC.get: {
6889
+ const [key] = args;
6890
+ const row = await driver.get(`SELECT value, expires_at FROM ${KV_TABLE} WHERE key = ?`, [
6891
+ key
6892
+ ]);
6893
+ if (row === null || row === void 0) return null;
6894
+ const expiresAt = row.expires_at;
6895
+ if (expiresAt !== null && expiresAt !== void 0 && Number(expiresAt) <= nowSeconds()) {
6896
+ return null;
6897
+ }
6898
+ return row.value;
6899
+ }
6900
+ case KV_RPC.put: {
6901
+ const [key, value, options] = args;
6902
+ const ttl = options?.expirationTtlSeconds;
6903
+ const expiresAt = typeof ttl === "number" && ttl > 0 ? nowSeconds() + Math.floor(ttl) : null;
6904
+ await driver.run(`DELETE FROM ${KV_TABLE} WHERE key = ?`, [key]);
6905
+ await driver.run(`INSERT INTO ${KV_TABLE} (key, value, expires_at) VALUES (?, ?, ?)`, [
6906
+ key,
6907
+ value,
6908
+ expiresAt
6909
+ ]);
6910
+ return void 0;
6911
+ }
6912
+ case KV_RPC.delete: {
6913
+ const [key] = args;
6914
+ await driver.run(`DELETE FROM ${KV_TABLE} WHERE key = ?`, [key]);
6915
+ return void 0;
6916
+ }
6917
+ case KV_RPC.list: {
6918
+ const [options] = args;
6919
+ const prefix = options?.prefix ?? "";
6920
+ const limit = options?.limit ?? KV_LIST_DEFAULT_LIMIT;
6921
+ 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 ?`, [
6922
+ `${prefix}%`
6923
+ ]);
6924
+ const now = nowSeconds();
6925
+ const entries = [];
6926
+ for (const row of rows) {
6927
+ const expiresAt = row.expires_at;
6928
+ if (expiresAt !== null && expiresAt !== void 0 && Number(expiresAt) <= now) continue;
6929
+ entries.push({
6930
+ name: String(row.key),
6931
+ expiration: expiresAt === null || expiresAt === void 0 ? null : Number(expiresAt)
6932
+ });
6933
+ if (entries.length >= limit) break;
6934
+ }
6935
+ return entries;
6936
+ }
6937
+ default:
6938
+ throw new Error(
6939
+ `\u672A\u77E5\u7684 cloud.kv \u65B9\u6CD5 "${String(method)}"\uFF08${KV_CAPABILITY_CODES.invalidMethod}\uFF09`
6940
+ );
6941
+ }
6942
+ } catch (error) {
6943
+ throw errorWithCode2(error);
6944
+ }
6945
+ };
6946
+ return {
6947
+ capabilities: [{ name: "kv", value: { [RPC_CAPABILITY_KEY]: true } }],
6948
+ rpcHandlers: { kv: handler }
6949
+ };
6950
+ }
6951
+
6758
6952
  // src/sim/runtime.ts
6759
6953
  function mergeBundles(bundles) {
6760
6954
  const capabilities = [];
@@ -6789,7 +6983,8 @@ self.onmessage = async (event) => {
6789
6983
  projectId: options.projectId,
6790
6984
  ...options.realtime === void 0 ? {} : options.realtime
6791
6985
  });
6792
- const bundle = mergeBundles([db.bundle, storage.bundle, realtime.bundle]);
6986
+ const kvBundle = createKvCapability(db.driver);
6987
+ const bundle = mergeBundles([db.bundle, storage.bundle, kvBundle, realtime.bundle]);
6793
6988
  await db.engine.load();
6794
6989
  const runner = createOfflineFunctionRunner(options.runner ?? {});
6795
6990
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adep/web-container",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -11,8 +11,8 @@
11
11
  "dist"
12
12
  ],
13
13
  "dependencies": {
14
- "@adep/runtime": "0.2.1",
15
- "@adep/types": "0.2.1"
14
+ "@adep/runtime": "0.2.2",
15
+ "@adep/types": "0.2.2"
16
16
  },
17
17
  "scripts": {
18
18
  "test": "vitest run",