@adep/cli 0.1.0 → 0.1.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.
package/dist/vite.js CHANGED
@@ -1,19 +1,20 @@
1
- // src/vite.ts
2
- import { request as httpRequest } from "node:http";
3
- import { resolve as resolve3 } from "node:path";
1
+ // packages/cli/src/vite.ts
2
+ import { adepPlugin } from "@adep/vite-plugin";
4
3
 
5
- // src/dev.ts
4
+ // packages/cli/src/dev.ts
6
5
  import { createServer } from "node:http";
7
6
  import { watch } from "node:fs";
8
7
  import { mkdir as mkdir3, readdir as readdir2, readFile as readFile5, writeFile as writeFile3 } from "node:fs/promises";
9
- import { basename, join as join7, resolve as resolve2 } from "node:path";
8
+ import { basename, join as join8, resolve as resolve2 } from "node:path";
10
9
 
11
- // ../runtime/src/shared/capability-keys.ts
10
+ // packages/runtime/src/shared/capability-keys.ts
12
11
  var RPC_CAPABILITY_KEY = "__adepRpc";
13
12
  var CHAIN_CAPABILITY_KEY = "__adepChain";
14
13
  var DB_RPC = {
15
14
  /** 直通方法(如 query):`(method=query, args=[sql, params])`。 */
16
15
  query: "query",
16
+ /** 写路径(CF-013):`(method=writeQuery, args=[sql, params])` → `{ changes }`。 */
17
+ writeQuery: "writeQuery",
17
18
  /** 读取 owned 表变更流(DB-006):`(method=changes, args=[table, query])`。 */
18
19
  changes: "changes",
19
20
  /** 开启事务:`begin → txId`。 */
@@ -40,7 +41,7 @@ var REALTIME_CAPABILITY_METHODS = [
40
41
  "unsubscribe"
41
42
  ];
42
43
 
43
- // ../runtime/src/shared/executor-runtime.ts
44
+ // packages/runtime/src/shared/executor-runtime.ts
44
45
  var ExecutorError = class extends Error {
45
46
  constructor(status, code, message) {
46
47
  super(message);
@@ -60,19 +61,38 @@ function normalizeHttpStatus(status) {
60
61
  return isHttpStatus(status) ? status : 500;
61
62
  }
62
63
 
63
- // ../runtime/src/functions/runtime/worker-executor.ts
64
+ // packages/runtime/src/shared/http-envelope.ts
65
+ function isAdepHttpEnvelope(value) {
66
+ if (typeof value !== "object" || value === null) return false;
67
+ const envelope = value.__adepHttp;
68
+ if (typeof envelope !== "object" || envelope === null) return false;
69
+ const status = envelope.status;
70
+ return typeof status === "number" && Number.isInteger(status) && status >= 100 && status <= 599;
71
+ }
72
+ function writeEnvelopeResponse(res, envelope) {
73
+ const { status, headers, body } = envelope.__adepHttp;
74
+ const noBody = status >= 100 && status < 200 || status === 204 || status === 205;
75
+ res.writeHead(status, { "content-type": "application/json", ...headers });
76
+ if (noBody) {
77
+ res.end();
78
+ return;
79
+ }
80
+ res.end(JSON.stringify(body === void 0 ? null : body));
81
+ }
82
+
83
+ // packages/runtime/src/functions/runtime/worker-executor.ts
64
84
  import { readFileSync } from "node:fs";
65
85
  import { fileURLToPath, pathToFileURL } from "node:url";
66
86
  import { dirname, join } from "node:path";
67
87
  import { Worker } from "node:worker_threads";
68
88
 
69
- // ../runtime/src/functions/deps/resolve.ts
89
+ // packages/runtime/src/functions/deps/resolve.ts
70
90
  import { resolve } from "node:path";
71
91
 
72
- // ../runtime/src/functions/deps/manifest.ts
92
+ // packages/runtime/src/functions/deps/manifest.ts
73
93
  import { createHash } from "node:crypto";
74
94
 
75
- // ../runtime/src/functions/domain.ts
95
+ // packages/runtime/src/functions/domain.ts
76
96
  var MAX_TOTAL_SOURCE_BYTES = 256 * 1024;
77
97
  var FnError = class extends Error {
78
98
  status;
@@ -85,7 +105,7 @@ var FnError = class extends Error {
85
105
  }
86
106
  };
87
107
 
88
- // ../runtime/src/functions/deps/manifest.ts
108
+ // packages/runtime/src/functions/deps/manifest.ts
89
109
  var PACKAGE_NAME_PATTERN = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-._~]+$/;
90
110
  var COMPARATOR_PATTERN = /^(?:\^|~|>=|<=|>|<|=)?\d+(?:\.(?:\d+|x|X|\*)){0,2}(?:-[\w.-]+)?(?:\+[\w.-]+)?$/;
91
111
  var MANIFEST_MAX_DEPS = 100;
@@ -162,12 +182,19 @@ function classifyDependencies(dependencies, builtin) {
162
182
  }
163
183
  return { builtinDeps, customDeps };
164
184
  }
185
+ function splitBareSpecifier(request) {
186
+ if (request.startsWith("@")) {
187
+ const segments = request.split("/");
188
+ return segments.slice(0, 2).join("/");
189
+ }
190
+ return request.split("/")[0];
191
+ }
165
192
  function depsKeyOf(dependencies) {
166
193
  const canonical = Object.entries(dependencies).map(([name, version]) => `${name}@${version}`).toSorted().join("\n");
167
194
  return createHash("sha256").update(canonical).digest("hex").slice(0, 16);
168
195
  }
169
196
 
170
- // ../runtime/src/functions/deps/resolve.ts
197
+ // packages/runtime/src/functions/deps/resolve.ts
171
198
  function resolveExecutionDeps(config, projectId, manifestContent) {
172
199
  const manifest = tryParseManifestDependencies(manifestContent);
173
200
  const { customDeps } = classifyDependencies(manifest, config.builtin);
@@ -180,7 +207,7 @@ function resolveExecutionDeps(config, projectId, manifestContent) {
180
207
  };
181
208
  }
182
209
 
183
- // ../runtime/src/functions/runtime/worker-executor.ts
210
+ // packages/runtime/src/functions/runtime/worker-executor.ts
184
211
  function resolveWorkerEntry(baseDir = fileURLToPath(new URL(".", import.meta.url))) {
185
212
  const candidates = [
186
213
  join(baseDir, "worker-entry.js"),
@@ -230,7 +257,7 @@ var WorkerFunctionExecutor = class {
230
257
  const entry = input.entry ?? "index.ts";
231
258
  const deps = this.depsConfig === void 0 ? void 0 : resolveExecutionDeps(this.depsConfig, input.project.id, input.files["package.json"]);
232
259
  const logs = [];
233
- return new Promise((resolve4, reject) => {
260
+ return new Promise((resolve3, reject) => {
234
261
  let worker;
235
262
  try {
236
263
  worker = new Worker(resolveWorkerEntry(), {
@@ -292,7 +319,7 @@ var WorkerFunctionExecutor = class {
292
319
  if (message.type === "result") {
293
320
  clearTimeout(timer);
294
321
  void worker.terminate();
295
- resolve4({ body: message.body, logs });
322
+ resolve3({ body: message.body, logs });
296
323
  return;
297
324
  }
298
325
  if (message.type === "error") {
@@ -325,11 +352,11 @@ var WorkerFunctionExecutor = class {
325
352
  }
326
353
  };
327
354
 
328
- // src/sim/runtime.ts
355
+ // packages/cli/src/sim/runtime.ts
329
356
  import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
330
357
  import { dirname as dirname3, join as join4 } from "node:path";
331
358
 
332
- // ../runtime/src/database/builder/dialect.ts
359
+ // packages/runtime/src/database/builder/dialect.ts
333
360
  var sqliteDialect = {
334
361
  name: "sqlite",
335
362
  placeholder: () => "?",
@@ -348,7 +375,7 @@ function dialectFor(driver) {
348
375
  return driver.engine === "pg" ? postgresDialect : sqliteDialect;
349
376
  }
350
377
 
351
- // ../runtime/src/database/provision/identifier.ts
378
+ // packages/runtime/src/database/provision/identifier.ts
352
379
  var DbError = class extends Error {
353
380
  constructor(status, code, message) {
354
381
  super(message);
@@ -372,31 +399,45 @@ function quoteIdentifier(name) {
372
399
  return `"${name.replace(/"/g, '""')}"`;
373
400
  }
374
401
 
375
- // ../runtime/src/database/builder/guards.ts
402
+ // packages/runtime/src/database/builder/guards.ts
376
403
  function unsafeOperation(message) {
377
404
  return new DbError(400, "DB_UNSAFE_OP", message);
378
405
  }
379
406
  function stripLiterals(sql) {
380
407
  return sql.replace(/'[^']*(?:''[^']*)*'/g, "").replace(/"[^"]*(?:""[^"]*)*"/g, "").replace(/--[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
381
408
  }
382
- function assertReadOnlyQuery(sql) {
409
+ function sqlHead(sql) {
410
+ return sql.trim().replace(/^\(+/, "").trim().toUpperCase();
411
+ }
412
+ function assertSafeStatement(sql) {
383
413
  const stripped = stripLiterals(sql);
384
414
  if (stripped.includes(";")) {
385
415
  throw unsafeOperation("\u4EC5\u5141\u8BB8\u5355\u6761\u8BED\u53E5\uFF0C\u7981\u6B62\u591A\u8BED\u53E5\u5806\u53E0");
386
416
  }
387
- const head = stripped.trim().replace(/^\(+/, "").trim().toUpperCase();
388
- if (!head.startsWith("SELECT") && !head.startsWith("WITH")) {
389
- throw unsafeOperation("cloud.db.query \u4EC5\u5141\u8BB8\u53EA\u8BFB\u67E5\u8BE2\uFF08SELECT / WITH\uFF09");
390
- }
391
417
  if (/ATTACH|DETACH/.test(stripped.toUpperCase())) {
392
418
  throw unsafeOperation("\u7981\u6B62\u8DE8\u5E93\u64CD\u4F5C\uFF08ATTACH / DETACH\uFF09");
393
419
  }
394
420
  if (/SQLITE_\w+/i.test(stripped)) {
395
421
  throw unsafeOperation("\u7981\u6B62\u8BBF\u95EE\u7CFB\u7EDF\u8868\uFF08sqlite_*\uFF09");
396
422
  }
423
+ return sqlHead(stripped);
424
+ }
425
+ function assertReadOnlyQuery(sql) {
426
+ const head = assertSafeStatement(sql);
427
+ if (!head.startsWith("SELECT") && !head.startsWith("WITH")) {
428
+ throw unsafeOperation("cloud.db.query \u4EC5\u5141\u8BB8\u53EA\u8BFB\u67E5\u8BE2\uFF08SELECT / WITH\uFF09");
429
+ }
430
+ }
431
+ function assertWriteQuery(sql) {
432
+ const head = assertSafeStatement(sql);
433
+ if (!head.startsWith("INSERT") && !head.startsWith("UPDATE") && !head.startsWith("DELETE")) {
434
+ throw unsafeOperation(
435
+ "cloud.db.writeQuery \u4EC5\u5141\u8BB8 DML\uFF08INSERT / UPDATE / DELETE\uFF09\uFF0CDDL \u8BF7\u8D70\u63A7\u5236\u53F0"
436
+ );
437
+ }
397
438
  }
398
439
 
399
- // ../runtime/src/database/builder/owned.ts
440
+ // packages/runtime/src/database/builder/owned.ts
400
441
  var OWNED_PK = "id";
401
442
  var OWNED_OWNER_KEY = "__owner_key";
402
443
  var CHANGE_LOG_PREFIX = "_adep_changes_";
@@ -509,7 +550,7 @@ async function readChanges(driver, table, query = {}) {
509
550
  return rows.map(parseChange);
510
551
  }
511
552
 
512
- // ../runtime/src/database/builder/ulid.ts
553
+ // packages/runtime/src/database/builder/ulid.ts
513
554
  var ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
514
555
  var TIME_LEN = 10;
515
556
  var RANDOM_LEN = 16;
@@ -575,7 +616,7 @@ function ulid(now = Date.now()) {
575
616
  return time + random;
576
617
  }
577
618
 
578
- // ../runtime/src/database/builder/table.ts
619
+ // packages/runtime/src/database/builder/table.ts
579
620
  var OPERATORS = /* @__PURE__ */ new Set([
580
621
  "=",
581
622
  "!=",
@@ -894,7 +935,7 @@ function createTableBuilder(table, driver, dialect, options = {}) {
894
935
  return build(initialState);
895
936
  }
896
937
 
897
- // ../runtime/src/database/builder/index.ts
938
+ // packages/runtime/src/database/builder/index.ts
898
939
  var TX_STATES = /* @__PURE__ */ new WeakMap();
899
940
  function createCloudDb(driver, options = {}) {
900
941
  const dialect = options.dialect ?? dialectFor(driver);
@@ -939,6 +980,14 @@ function createCloudDb(driver, options = {}) {
939
980
  assertReadOnlyQuery(sql);
940
981
  return driver.all(sql, params);
941
982
  },
983
+ async writeQuery(sql, params) {
984
+ if (!Array.isArray(params)) {
985
+ throw unsafeOperation("writeQuery \u7684 params \u5FC5\u987B\u63D0\u4F9B\uFF08\u65E0\u53C2\u4F20 []\uFF09");
986
+ }
987
+ guardWrite();
988
+ assertWriteQuery(sql);
989
+ return driver.run(sql, params);
990
+ },
942
991
  async changes(table, query = {}) {
943
992
  return readChanges(driver, table, query);
944
993
  }
@@ -948,13 +997,14 @@ function createCloudDb(driver, options = {}) {
948
997
  return makeHandle({ allowWriteDuringTx: false });
949
998
  }
950
999
 
951
- // ../runtime/src/database/sdk/cloud.ts
1000
+ // packages/runtime/src/database/sdk/cloud.ts
952
1001
  var CLOUD_DB_SPEC = {
953
1002
  kind: "cloud-db",
954
1003
  rootMethod: "table",
955
1004
  stepMethods: ["select", "where", "orderBy", "limit", "offset"],
956
1005
  terminalMethods: ["get", "first", "count", "insert", "insertMany", "update", "delete"],
957
- directMethods: ["query", "changes"],
1006
+ // CF-013:writeQuery 是 D1 shim 的写路径(INSERT/UPDATE/DELETE),与 query 并列直通方法。
1007
+ directMethods: ["query", "writeQuery", "changes"],
958
1008
  transactionMethod: "transaction"
959
1009
  };
960
1010
  var WRITE_TERMINALS = /* @__PURE__ */ new Set(["insert", "insertMany", "update", "delete"]);
@@ -1009,6 +1059,10 @@ function createDbCapability(driver, options = {}) {
1009
1059
  const [sql, params] = args;
1010
1060
  return await db.query(sql, params);
1011
1061
  }
1062
+ case DB_RPC.writeQuery: {
1063
+ const [sql, params] = args;
1064
+ return await db.writeQuery(sql, params);
1065
+ }
1012
1066
  case DB_RPC.changes: {
1013
1067
  const [table, query] = args;
1014
1068
  return await db.changes(table, query);
@@ -1052,7 +1106,7 @@ function createDbCapability(driver, options = {}) {
1052
1106
  };
1053
1107
  }
1054
1108
 
1055
- // src/sim/sql-engine.ts
1109
+ // packages/cli/src/sim/sql-engine.ts
1056
1110
  var SimDbError = class extends Error {
1057
1111
  constructor(code, message) {
1058
1112
  super(message);
@@ -1470,7 +1524,7 @@ function project(rows, selectRaw) {
1470
1524
  });
1471
1525
  }
1472
1526
 
1473
- // src/sim/db.ts
1527
+ // packages/cli/src/sim/db.ts
1474
1528
  function toProjectDriver(engine) {
1475
1529
  return {
1476
1530
  engine: "sqlite",
@@ -1490,10 +1544,110 @@ function createSimDbCapability(options = {}) {
1490
1544
  return { bundle, engine, driver };
1491
1545
  }
1492
1546
 
1493
- // src/sim/storage.ts
1547
+ // packages/runtime/src/database/sdk/kv.ts
1548
+ var KV_TABLE = "_adep_kv";
1549
+ var KV_RPC = {
1550
+ get: "get",
1551
+ put: "put",
1552
+ delete: "delete",
1553
+ list: "list"
1554
+ };
1555
+ var KV_CAPABILITY_CODES = {
1556
+ invalidMethod: "KV_INVALID_METHOD"
1557
+ };
1558
+ var KV_LIST_DEFAULT_LIMIT = 100;
1559
+ function nowSeconds() {
1560
+ return Math.floor(Date.now() / 1e3);
1561
+ }
1562
+ function errorWithCode2(error) {
1563
+ const code = typeof error === "object" && error !== null && typeof error.code === "string" ? error.code : void 0;
1564
+ if (code !== void 0 && error instanceof Error) {
1565
+ return new Error(`[${code}] ${error.message}`);
1566
+ }
1567
+ return error;
1568
+ }
1569
+ function createKvCapability(driver) {
1570
+ let ensurePromise = null;
1571
+ const ensureTable = () => {
1572
+ if (ensurePromise === null) {
1573
+ ensurePromise = driver.run(
1574
+ `CREATE TABLE IF NOT EXISTS ${KV_TABLE} (key TEXT PRIMARY KEY, value TEXT, expires_at INTEGER)`
1575
+ ).then(() => void 0);
1576
+ }
1577
+ return ensurePromise;
1578
+ };
1579
+ const handler = async (method, args) => {
1580
+ try {
1581
+ await ensureTable();
1582
+ switch (method) {
1583
+ case KV_RPC.get: {
1584
+ const [key] = args;
1585
+ const row = await driver.get(`SELECT value, expires_at FROM ${KV_TABLE} WHERE key = ?`, [
1586
+ key
1587
+ ]);
1588
+ if (row === null || row === void 0) return null;
1589
+ const expiresAt = row.expires_at;
1590
+ if (expiresAt !== null && expiresAt !== void 0 && Number(expiresAt) <= nowSeconds()) {
1591
+ return null;
1592
+ }
1593
+ return row.value;
1594
+ }
1595
+ case KV_RPC.put: {
1596
+ const [key, value, options] = args;
1597
+ const ttl = options?.expirationTtlSeconds;
1598
+ const expiresAt = typeof ttl === "number" && ttl > 0 ? nowSeconds() + Math.floor(ttl) : null;
1599
+ await driver.run(`DELETE FROM ${KV_TABLE} WHERE key = ?`, [key]);
1600
+ await driver.run(`INSERT INTO ${KV_TABLE} (key, value, expires_at) VALUES (?, ?, ?)`, [
1601
+ key,
1602
+ value,
1603
+ expiresAt
1604
+ ]);
1605
+ return void 0;
1606
+ }
1607
+ case KV_RPC.delete: {
1608
+ const [key] = args;
1609
+ await driver.run(`DELETE FROM ${KV_TABLE} WHERE key = ?`, [key]);
1610
+ return void 0;
1611
+ }
1612
+ case KV_RPC.list: {
1613
+ const [options] = args;
1614
+ const prefix = options?.prefix ?? "";
1615
+ const limit = options?.limit ?? KV_LIST_DEFAULT_LIMIT;
1616
+ 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 ?`, [
1617
+ `${prefix}%`
1618
+ ]);
1619
+ const now = nowSeconds();
1620
+ const entries = [];
1621
+ for (const row of rows) {
1622
+ const expiresAt = row.expires_at;
1623
+ if (expiresAt !== null && expiresAt !== void 0 && Number(expiresAt) <= now) continue;
1624
+ entries.push({
1625
+ name: String(row.key),
1626
+ expiration: expiresAt === null || expiresAt === void 0 ? null : Number(expiresAt)
1627
+ });
1628
+ if (entries.length >= limit) break;
1629
+ }
1630
+ return entries;
1631
+ }
1632
+ default:
1633
+ throw new Error(
1634
+ `\u672A\u77E5\u7684 cloud.kv \u65B9\u6CD5 "${String(method)}"\uFF08${KV_CAPABILITY_CODES.invalidMethod}\uFF09`
1635
+ );
1636
+ }
1637
+ } catch (error) {
1638
+ throw errorWithCode2(error);
1639
+ }
1640
+ };
1641
+ return {
1642
+ capabilities: [{ name: "kv", value: { [RPC_CAPABILITY_KEY]: true } }],
1643
+ rpcHandlers: { kv: handler }
1644
+ };
1645
+ }
1646
+
1647
+ // packages/cli/src/sim/storage.ts
1494
1648
  import { join as join3 } from "node:path";
1495
1649
 
1496
- // ../runtime/src/storage/driver.ts
1650
+ // packages/runtime/src/storage/driver.ts
1497
1651
  var PROJECT_QUOTA_BYTES = 1024 * 1024 * 1024;
1498
1652
  var StorageError = class extends Error {
1499
1653
  constructor(status, code, message) {
@@ -1534,7 +1688,7 @@ function assertSafeStoragePath(path) {
1534
1688
  return path;
1535
1689
  }
1536
1690
 
1537
- // ../runtime/src/storage/hmac-sha256.ts
1691
+ // packages/runtime/src/storage/hmac-sha256.ts
1538
1692
  var K = new Uint32Array([
1539
1693
  1116352408,
1540
1694
  1899447441,
@@ -1695,7 +1849,7 @@ function hmacSha256Hex(key, message) {
1695
1849
  return [...hmacSha256(key, message)].map((b) => b.toString(16).padStart(2, "0")).join("");
1696
1850
  }
1697
1851
 
1698
- // ../runtime/src/storage/signature.ts
1852
+ // packages/runtime/src/storage/signature.ts
1699
1853
  var DEFAULT_SIGN_TTL_SECONDS = 15 * 60;
1700
1854
  var SIGN_EXPIRES_KEY = "x-expires";
1701
1855
  var SIGN_SIGNATURE_KEY = "x-signature";
@@ -1710,7 +1864,7 @@ function signDownloadUrl(config, projectId, path, ttlSeconds = DEFAULT_SIGN_TTL_
1710
1864
  return `${base}?${SIGN_EXPIRES_KEY}=${expires}&${SIGN_SIGNATURE_KEY}=${signature}`;
1711
1865
  }
1712
1866
 
1713
- // ../runtime/src/storage/cloud.ts
1867
+ // packages/runtime/src/storage/cloud.ts
1714
1868
  var DEFAULT_VISIBILITY = "private";
1715
1869
  function asBytes(data) {
1716
1870
  if (typeof data === "string") return new TextEncoder().encode(data);
@@ -1733,9 +1887,12 @@ function createStorageCapability(driver, signer, projectId) {
1733
1887
  const handler = async (method, args) => {
1734
1888
  switch (method) {
1735
1889
  case "upload": {
1736
- const [path, data] = args;
1890
+ const [path, data, options] = args;
1737
1891
  return toStoredFile(
1738
- await driver.put(projectId, path, asBytes(data), { visibility: DEFAULT_VISIBILITY })
1892
+ await driver.put(projectId, path, asBytes(data), {
1893
+ visibility: DEFAULT_VISIBILITY,
1894
+ ...options?.contentType === void 0 ? {} : { contentType: options.contentType }
1895
+ })
1739
1896
  );
1740
1897
  }
1741
1898
  case "get": {
@@ -1769,7 +1926,7 @@ function createStorageCapability(driver, signer, projectId) {
1769
1926
  };
1770
1927
  }
1771
1928
 
1772
- // ../runtime/src/storage/driver/local.ts
1929
+ // packages/runtime/src/storage/driver/local.ts
1773
1930
  import { mkdir, readFile, readdir, rm, stat, unlink, writeFile } from "node:fs/promises";
1774
1931
  import { dirname as dirname2, join as join2 } from "node:path";
1775
1932
  var META_SUFFIX = ".adep-meta.json";
@@ -1976,7 +2133,7 @@ function createLocalStorageDriver(options) {
1976
2133
  };
1977
2134
  }
1978
2135
 
1979
- // src/sim/storage.ts
2136
+ // packages/cli/src/sim/storage.ts
1980
2137
  function createSimStorageCapability(options) {
1981
2138
  const dir = join3(options.cwd, ".adep", "sim", "storage");
1982
2139
  const driver = createLocalStorageDriver({ dir });
@@ -1988,7 +2145,7 @@ function createSimStorageCapability(options) {
1988
2145
  return { bundle, driver };
1989
2146
  }
1990
2147
 
1991
- // src/sim/realtime.ts
2148
+ // packages/cli/src/sim/realtime.ts
1992
2149
  var SimRealtime = class {
1993
2150
  seq = 0;
1994
2151
  subscribers = /* @__PURE__ */ new Map();
@@ -2110,7 +2267,7 @@ function createSimRealtimeCapability() {
2110
2267
  };
2111
2268
  }
2112
2269
 
2113
- // src/sim/runtime.ts
2270
+ // packages/cli/src/sim/runtime.ts
2114
2271
  function simDir(cwd) {
2115
2272
  return join4(cwd, ".adep", "sim");
2116
2273
  }
@@ -2161,7 +2318,8 @@ async function createSimRuntime(options) {
2161
2318
  projectId: options.projectId ?? "local"
2162
2319
  });
2163
2320
  const simRealtime = createSimRealtimeCapability();
2164
- const bundle = mergeBundles([db.bundle, storage.bundle, simRealtime.bundle]);
2321
+ const kvBundle = createKvCapability(db.driver);
2322
+ const bundle = mergeBundles([db.bundle, storage.bundle, kvBundle, simRealtime.bundle]);
2165
2323
  await db.engine.load();
2166
2324
  return {
2167
2325
  bundle,
@@ -2173,7 +2331,7 @@ async function createSimRuntime(options) {
2173
2331
  };
2174
2332
  }
2175
2333
 
2176
- // src/sim/env.ts
2334
+ // packages/cli/src/sim/env.ts
2177
2335
  import { readFile as readFile3 } from "node:fs/promises";
2178
2336
  import { join as join5 } from "node:path";
2179
2337
  function parseEnv(content) {
@@ -2206,7 +2364,7 @@ async function loadSimEnv(cwd, config = {}) {
2206
2364
  return merged;
2207
2365
  }
2208
2366
 
2209
- // src/sim/invoke.ts
2367
+ // packages/cli/src/sim/invoke.ts
2210
2368
  function resolveFunctionEntry(files, fnName) {
2211
2369
  const flat = `${fnName}.ts`;
2212
2370
  if (files[flat] !== void 0) return flat;
@@ -2247,7 +2405,14 @@ function createSimInvokeHandler(options) {
2247
2405
  };
2248
2406
  }
2249
2407
 
2250
- // src/sim/boundary.ts
2408
+ // packages/cli/src/builtin-deps.ts
2409
+ var LOCAL_STATE_OBJECTS_SPECIFIER = "@adep/runtime/state-objects";
2410
+ var LOCAL_BUILTIN_DEPS = [
2411
+ "@adep/cf-compat",
2412
+ LOCAL_STATE_OBJECTS_SPECIFIER
2413
+ ];
2414
+
2415
+ // packages/cli/src/sim/boundary.ts
2251
2416
  var SIM_BOUNDARIES = [
2252
2417
  {
2253
2418
  kind: "capability",
@@ -2276,11 +2441,11 @@ var SIM_BOUNDARIES = [
2276
2441
  }
2277
2442
  ];
2278
2443
 
2279
- // src/ts-config.ts
2444
+ // packages/cli/src/ts-config.ts
2280
2445
  import { stat as stat2, readFile as readFile4 } from "node:fs/promises";
2281
2446
  import { join as join6 } from "node:path";
2282
2447
 
2283
- // ../../shared/sdk/adep-config.ts
2448
+ // shared/sdk/adep-config.ts
2284
2449
  var DEFAULT_ADEP_CONFIG = {
2285
2450
  functionsDir: "functions",
2286
2451
  functions_prefix: "/api"
@@ -2302,6 +2467,51 @@ function asStringRecord(value) {
2302
2467
  }
2303
2468
  return rec;
2304
2469
  }
2470
+ function asBindingArray(value, label, errors, optionalKey) {
2471
+ if (!Array.isArray(value)) {
2472
+ errors.push(`${label} \u5FC5\u987B\u662F\u6570\u7EC4\uFF0C\u6536\u5230 ${typeNameOf(value)}`);
2473
+ return null;
2474
+ }
2475
+ const out = [];
2476
+ value.forEach((item, i) => {
2477
+ const idx = `${label}[${i}]`;
2478
+ if (item === null || typeof item !== "object" || Array.isArray(item)) {
2479
+ errors.push(`${idx} \u5FC5\u987B\u662F\u5BF9\u8C61\uFF0C\u6536\u5230 ${typeNameOf(item)}`);
2480
+ return;
2481
+ }
2482
+ const rec = item;
2483
+ if (typeof rec.name !== "string" || rec.name.length === 0) {
2484
+ errors.push(`${idx}.name \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\uFF0C\u6536\u5230 ${typeNameOf(rec.name)}`);
2485
+ return;
2486
+ }
2487
+ const entry = { name: rec.name };
2488
+ const optional = rec[optionalKey];
2489
+ if (optional !== void 0) {
2490
+ if (typeof optional !== "string") {
2491
+ errors.push(`${idx}.${optionalKey} \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\uFF0C\u6536\u5230 ${typeNameOf(optional)}`);
2492
+ } else {
2493
+ entry[optionalKey] = optional;
2494
+ }
2495
+ }
2496
+ out.push(entry);
2497
+ });
2498
+ return out;
2499
+ }
2500
+ function asCfBindingsConfig(value, errors) {
2501
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
2502
+ errors.push(`cfBindings \u5FC5\u987B\u662F\u5BF9\u8C61\uFF0C\u6536\u5230 ${typeNameOf(value)}`);
2503
+ return null;
2504
+ }
2505
+ const rec = value;
2506
+ const bindings = {};
2507
+ const kv = rec.kv === void 0 ? void 0 : asBindingArray(rec.kv, "cfBindings.kv", errors, "namespace");
2508
+ if (kv !== null && kv !== void 0) bindings.kv = kv;
2509
+ const d1 = rec.d1 === void 0 ? void 0 : asBindingArray(rec.d1, "cfBindings.d1", errors, "database");
2510
+ if (d1 !== null && d1 !== void 0) bindings.d1 = d1;
2511
+ const r2 = rec.r2 === void 0 ? void 0 : asBindingArray(rec.r2, "cfBindings.r2", errors, "bucket");
2512
+ if (r2 !== null && r2 !== void 0) bindings.r2 = r2;
2513
+ return bindings;
2514
+ }
2305
2515
  function parseAdepConfig(raw) {
2306
2516
  if (raw === null || raw === void 0) {
2307
2517
  return { ok: true, data: { ...DEFAULT_ADEP_CONFIG } };
@@ -2362,11 +2572,15 @@ function parseAdepConfig(raw) {
2362
2572
  data.runtime = rec;
2363
2573
  }
2364
2574
  }
2575
+ if (input.cfBindings !== void 0) {
2576
+ const bindings = asCfBindingsConfig(input.cfBindings, errors);
2577
+ if (bindings !== null) data.cfBindings = bindings;
2578
+ }
2365
2579
  if (errors.length > 0) return { ok: false, errors };
2366
2580
  return { ok: true, data };
2367
2581
  }
2368
2582
 
2369
- // src/ts-config.ts
2583
+ // packages/cli/src/ts-config.ts
2370
2584
  async function loadAdepConfigModule(cwd) {
2371
2585
  const configPath = join6(cwd, "adep.config.ts");
2372
2586
  try {
@@ -2410,14 +2624,1036 @@ ${result.errors.map((e) => ` - ${e}`).join("\n")}`;
2410
2624
  return result.data;
2411
2625
  }
2412
2626
 
2413
- // src/dev.ts
2627
+ // packages/runtime/src/state-objects/runtime.ts
2628
+ var StateObject = class {
2629
+ id;
2630
+ /** 对象内存状态(单例驻留);load 时从后端恢复。 */
2631
+ state;
2632
+ alarmAt = null;
2633
+ /** 运行时注入的持久化句柄(内部;protected,子类 flush() 使用)。 */
2634
+ runtime;
2635
+ constructor(id) {
2636
+ this.id = id;
2637
+ this.state = this.initialState();
2638
+ }
2639
+ /** 供运行时读取/序列化。 */
2640
+ getState() {
2641
+ return { ...this.state };
2642
+ }
2643
+ /** 通用快照方法(任何对象可经 invoke(type, id, 'snapshot') 读取)。 */
2644
+ async snapshot() {
2645
+ return this.getState();
2646
+ }
2647
+ /** 设置未来唤醒(alarm):到期时运行时调 onAlarm(调度 CF-037 落地)。 */
2648
+ setAlarm(at) {
2649
+ this.alarmAt = at;
2650
+ }
2651
+ clearAlarm() {
2652
+ this.alarmAt = null;
2653
+ }
2654
+ /** alarm 到期回调(子类覆写)。 */
2655
+ async onAlarm() {
2656
+ }
2657
+ /** 显式持久化当前状态(方法内任何位置可调)。 */
2658
+ async flush() {
2659
+ await this.runtime.flush(this);
2660
+ }
2661
+ };
2662
+ var StateObjectError = class extends Error {
2663
+ code;
2664
+ constructor(code, message) {
2665
+ super(message);
2666
+ this.name = "StateObjectError";
2667
+ this.code = code;
2668
+ }
2669
+ };
2670
+ var StateObjectRuntime = class {
2671
+ registry = /* @__PURE__ */ new Map();
2672
+ instances = /* @__PURE__ */ new Map();
2673
+ backend;
2674
+ constructor(backend) {
2675
+ this.backend = backend;
2676
+ }
2677
+ define(cls) {
2678
+ this.registry.set(cls.typeName, cls);
2679
+ }
2680
+ /** 已注册类型清单(控制台/审计用)。 */
2681
+ types() {
2682
+ return [...this.registry.keys()];
2683
+ }
2684
+ /** 内存驻留实例数(诊断用)。 */
2685
+ residentCount() {
2686
+ return this.instances.size;
2687
+ }
2688
+ key(type, id) {
2689
+ return `${type}:${id}`;
2690
+ }
2691
+ /** 取对象实例(单例驻留):内存有 → 复用;无 → 后端恢复或 new 初始态。 */
2692
+ async get(type, id) {
2693
+ const cls = this.registry.get(type);
2694
+ if (cls === void 0) {
2695
+ throw new StateObjectError(
2696
+ "STATE_TYPE_NOT_REGISTERED",
2697
+ `\u72B6\u6001\u5BF9\u8C61\u7C7B\u578B "${type}" \u672A\u6CE8\u518C\uFF08\u5DF2\u6CE8\u518C\uFF1A${this.types().join(", ") || "\u65E0"}\uFF09`
2698
+ );
2699
+ }
2700
+ const k = this.key(type, id);
2701
+ const hit = this.instances.get(k);
2702
+ if (hit !== void 0) return hit;
2703
+ const snapshot = await this.backend.load(type, id);
2704
+ const raw = new cls(id);
2705
+ const created = raw;
2706
+ created.state = snapshot !== null ? snapshot.state : created.state;
2707
+ created.alarmAt = snapshot !== null ? snapshot.alarmAt : null;
2708
+ created.runtime = this;
2709
+ this.instances.set(k, created);
2710
+ return created;
2711
+ }
2712
+ /** 方法路由:单例对象上串行执行方法。 */
2713
+ async invoke(type, id, method, args = []) {
2714
+ const inst = await this.get(type, id);
2715
+ const fn = inst[method];
2716
+ if (typeof fn !== "function") {
2717
+ throw new StateObjectError(
2718
+ "STATE_METHOD_NOT_FOUND",
2719
+ `\u72B6\u6001\u5BF9\u8C61 "${type}:${id}" \u65E0\u65B9\u6CD5 "${method}"`
2720
+ );
2721
+ }
2722
+ try {
2723
+ return await fn.call(inst, ...args);
2724
+ } catch (error) {
2725
+ if (error instanceof StateObjectError) throw error;
2726
+ throw new StateObjectError(
2727
+ "STATE_INVOKE_ERROR",
2728
+ `\u72B6\u6001\u5BF9\u8C61 "${type}:${id}" \u65B9\u6CD5 "${method}" \u6267\u884C\u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}`
2729
+ );
2730
+ }
2731
+ }
2732
+ /** 持久化快照(对象方法内 flush() 触发,或运行时统一写)。 */
2733
+ async flush(inst) {
2734
+ const raw = inst;
2735
+ const type = inst.constructor.typeName;
2736
+ if (type === void 0) {
2737
+ throw new StateObjectError("STATE_TYPE_NOT_REGISTERED", "\u72B6\u6001\u5BF9\u8C61\u7C7B\u5FC5\u987B\u58F0\u660E static typeName");
2738
+ }
2739
+ await this.backend.save(type, inst.id, inst.getState(), raw.alarmAt);
2740
+ }
2741
+ /**
2742
+ * alarm 轮询:把到期对象唤醒并调 onAlarm(CF-037)。
2743
+ * - onAlarm 后统一持久化(flush):onAlarm 内改的 state 与 setAlarm 重调度 / clearAlarm
2744
+ * 的新 alarmAt 都落库;
2745
+ * - 单对象 onAlarm 抛错**不阻塞**同 tick 其余对象:失败对象不落库、alarmAt 保留
2746
+ * → 下轮 dueAlarms 仍命中重试;错误折叠进 failed(不泄漏内部栈)。
2747
+ */
2748
+ async pump(now) {
2749
+ const due = await this.backend.dueAlarms(now);
2750
+ const fired = [];
2751
+ const failed = [];
2752
+ for (const d of due) {
2753
+ try {
2754
+ const inst = await this.get(d.type, d.id);
2755
+ await inst.onAlarm();
2756
+ await this.flush(inst);
2757
+ fired.push({ type: d.type, id: d.id });
2758
+ } catch (error) {
2759
+ failed.push({
2760
+ type: d.type,
2761
+ id: d.id,
2762
+ error: error instanceof Error ? error.message : String(error)
2763
+ });
2764
+ }
2765
+ }
2766
+ return { fired, failed };
2767
+ }
2768
+ /** 释放内存驻留(进程重启 / 测试隔离用);不删后端数据。 */
2769
+ evictAll() {
2770
+ this.instances.clear();
2771
+ }
2772
+ };
2773
+
2774
+ // packages/runtime/src/state-objects/backend.ts
2775
+ var STATE_OBJECTS_TABLE = "_adep_state_objects";
2776
+ function createProjectDriverStateBackend(driver) {
2777
+ let ensured = false;
2778
+ const ensureTable = async () => {
2779
+ if (ensured) return;
2780
+ await driver.run(
2781
+ `CREATE TABLE IF NOT EXISTS ${STATE_OBJECTS_TABLE} ("type" TEXT NOT NULL, "id" TEXT NOT NULL, "state" TEXT NOT NULL, "alarm_at" INTEGER, "updated_at" INTEGER NOT NULL, PRIMARY KEY ("type", "id"))`
2782
+ );
2783
+ ensured = true;
2784
+ };
2785
+ return {
2786
+ async load(type, id) {
2787
+ await ensureTable();
2788
+ const rows = await driver.all(
2789
+ `SELECT "state", "alarm_at" FROM ${STATE_OBJECTS_TABLE} WHERE "type" = ? AND "id" = ?`,
2790
+ [type, id]
2791
+ );
2792
+ if (rows.length === 0) return null;
2793
+ return {
2794
+ state: JSON.parse(String(rows[0].state)),
2795
+ alarmAt: rows[0].alarm_at
2796
+ };
2797
+ },
2798
+ async save(type, id, state, alarmAt) {
2799
+ await ensureTable();
2800
+ const existing = await driver.all(
2801
+ `SELECT 1 FROM ${STATE_OBJECTS_TABLE} WHERE "type" = ? AND "id" = ?`,
2802
+ [type, id]
2803
+ );
2804
+ const stateJson = JSON.stringify(state);
2805
+ if (existing.length === 0) {
2806
+ await driver.run(
2807
+ `INSERT INTO ${STATE_OBJECTS_TABLE} ("type", "id", "state", "alarm_at", "updated_at") VALUES (?, ?, ?, ?, ?)`,
2808
+ [type, id, stateJson, alarmAt, Date.now()]
2809
+ );
2810
+ } else {
2811
+ await driver.run(
2812
+ `UPDATE ${STATE_OBJECTS_TABLE} SET "state" = ?, "alarm_at" = ?, "updated_at" = ? WHERE "type" = ? AND "id" = ?`,
2813
+ [stateJson, alarmAt, Date.now(), type, id]
2814
+ );
2815
+ }
2816
+ },
2817
+ async dueAlarms(now) {
2818
+ await ensureTable();
2819
+ const rows = await driver.all(
2820
+ `SELECT "type", "id", "alarm_at" FROM ${STATE_OBJECTS_TABLE} WHERE "alarm_at" IS NOT NULL AND "alarm_at" <= ?`,
2821
+ [now]
2822
+ );
2823
+ return rows.map((r) => ({
2824
+ type: r.type,
2825
+ id: r.id,
2826
+ alarmAt: r.alarm_at
2827
+ }));
2828
+ },
2829
+ async remove(type, id) {
2830
+ await ensureTable();
2831
+ await driver.run(`DELETE FROM ${STATE_OBJECTS_TABLE} WHERE "type" = ? AND "id" = ?`, [
2832
+ type,
2833
+ id
2834
+ ]);
2835
+ }
2836
+ };
2837
+ }
2838
+
2839
+ // packages/runtime/src/state-objects/http.ts
2840
+ var STATE_PATH = "state";
2841
+ function parseStatePath(rest) {
2842
+ const segments = rest.split("/").filter((s) => s.length > 0);
2843
+ if (segments[0] !== STATE_PATH || segments.length < 4) return null;
2844
+ return {
2845
+ type: decodeURIComponent(segments[1]),
2846
+ id: decodeURIComponent(segments[2]),
2847
+ method: decodeURIComponent(segments.slice(3).join("/"))
2848
+ };
2849
+ }
2850
+ function parseStateBody(body) {
2851
+ if (body === null || body.length === 0) return { args: [] };
2852
+ try {
2853
+ const parsed = JSON.parse(body);
2854
+ if (!Array.isArray(parsed)) return { error: "body \u5FC5\u987B\u662F\u53C2\u6570\u6570\u7EC4\uFF08JSON\uFF09" };
2855
+ return { args: parsed };
2856
+ } catch {
2857
+ return { error: "body \u5FC5\u987B\u662F\u5408\u6CD5 JSON" };
2858
+ }
2859
+ }
2860
+
2861
+ // packages/runtime/src/state-objects/demo.ts
2862
+ var DemoCounter = class extends StateObject {
2863
+ static typeName = "DemoCounter";
2864
+ initialState() {
2865
+ return { count: 0 };
2866
+ }
2867
+ async increment(by = 1) {
2868
+ this.state.count += by;
2869
+ await this.flush();
2870
+ return { count: this.state.count };
2871
+ }
2872
+ async get() {
2873
+ return { count: this.state.count };
2874
+ }
2875
+ };
2876
+ var DemoChatRoom = class extends StateObject {
2877
+ static typeName = "DemoChatRoom";
2878
+ initialState() {
2879
+ return { members: [], messages: [], cursor: 0 };
2880
+ }
2881
+ async join(user) {
2882
+ if (!this.state.members.includes(user)) this.state.members.push(user);
2883
+ this.state.cursor += 1;
2884
+ await this.flush();
2885
+ return { members: this.state.members, cursor: this.state.cursor };
2886
+ }
2887
+ async send(user, text) {
2888
+ const seq = this.state.messages.length + 1;
2889
+ this.state.messages.push({ user, text, at: Date.now() });
2890
+ await this.flush();
2891
+ return { seq };
2892
+ }
2893
+ };
2894
+
2895
+ // packages/runtime/src/functions/runtime/sandbox.ts
2896
+ import vm from "node:vm";
2897
+ import * as nodeModule from "node:module";
2898
+
2899
+ // packages/runtime/src/functions/runtime/exports.ts
2900
+ function transformModule(code) {
2901
+ let out = code;
2902
+ const named = [];
2903
+ out = out.replace(/(^|\n)(\s*)export\s+default\s+/g, "$1$2module.default = ");
2904
+ out = out.replace(
2905
+ /import\s*\{([^}]*)\}\s*from\s*(['"][^'"]*['"])[ \t]*;?/g,
2906
+ (_match, names, source) => `const {${names}} = require(${source})`
2907
+ );
2908
+ out = out.replace(
2909
+ /import\s*\*\s*as\s*([A-Za-z_$][\w$]*)\s*from\s*(['"][^'"]*['"])[ \t]*;?/g,
2910
+ (_match, name, source) => `const ${name} = require(${source})`
2911
+ );
2912
+ out = out.replace(
2913
+ /import\s+([A-Za-z_$][\w$]*)\s+from\s*(['"][^'"]*['"])[ \t]*;?/g,
2914
+ (_match, name, source) => `const ${name} = require(${source})`
2915
+ );
2916
+ out = out.replace(
2917
+ /export\s+(const|let|var)\s+([A-Za-z_$][\w$]*)/g,
2918
+ (_match, kw, name) => {
2919
+ named.push(name);
2920
+ return `${kw} ${name}`;
2921
+ }
2922
+ );
2923
+ out = out.replace(
2924
+ /export\s+(async\s+)?function\s*\*?\s*([A-Za-z_$][\w$]*)/g,
2925
+ (_match, asyncKw, name) => {
2926
+ named.push(name);
2927
+ return `${asyncKw ?? ""}function ${name}`;
2928
+ }
2929
+ );
2930
+ out = out.replace(/export\s+class\s+([A-Za-z_$][\w$]*)/g, (_match, name) => {
2931
+ named.push(name);
2932
+ return `class ${name}`;
2933
+ });
2934
+ if (named.length > 0) {
2935
+ out += `
2936
+ ;Object.assign(exports, { ${named.join(", ")} })`;
2937
+ }
2938
+ return out;
2939
+ }
2940
+
2941
+ // packages/runtime/src/functions/runtime/sandbox.ts
2942
+ var bunTranspiler;
2943
+ function transpile(code) {
2944
+ const bun = globalThis["Bun"];
2945
+ if (bun?.Transpiler !== void 0) {
2946
+ bunTranspiler ??= new bun.Transpiler({ loader: "ts" });
2947
+ return bunTranspiler.transformSync(code);
2948
+ }
2949
+ const stripTypeScriptTypes2 = nodeModule.stripTypeScriptTypes;
2950
+ if (typeof stripTypeScriptTypes2 === "function") {
2951
+ return stripTypeScriptTypes2(code, { mode: "strip" });
2952
+ }
2953
+ return code;
2954
+ }
2955
+ function transformExports(code) {
2956
+ return transformModule(code);
2957
+ }
2958
+ var SANDBOX_BUILTIN_REJECTED = "FN_SANDBOX_BUILTIN_BLOCKED";
2959
+ function resolveModulePath(fromDir, request, files) {
2960
+ if (!request.startsWith("./") && !request.startsWith("../")) return null;
2961
+ const base = joinPosix(fromDir, request);
2962
+ const candidates = [base, `${base}.ts`, `${base}.js`, `${base}/index.ts`, `${base}/index.js`];
2963
+ for (const candidate of candidates) {
2964
+ const normalized = normalizePosix(candidate);
2965
+ if (files[normalized] !== void 0) return normalized;
2966
+ }
2967
+ return null;
2968
+ }
2969
+ function joinPosix(dir, request) {
2970
+ const parts = [...dir.split("/"), ...request.split("/")];
2971
+ const stack = [];
2972
+ for (const part of parts) {
2973
+ if (part === "" || part === ".") continue;
2974
+ if (part === "..") stack.pop();
2975
+ else stack.push(part);
2976
+ }
2977
+ return stack.join("/");
2978
+ }
2979
+ function normalizePosix(p) {
2980
+ return joinPosix("", p);
2981
+ }
2982
+ function loadModule(path, files, sandboxGlobals, cache, resolveBare, bareCache) {
2983
+ const cached = cache.get(path);
2984
+ if (cached !== void 0) return cached;
2985
+ const source = files[path];
2986
+ if (source === void 0) {
2987
+ throw new Error(`\u6A21\u5757\u4E0D\u5B58\u5728\uFF1A${path}`);
2988
+ }
2989
+ const exports = {};
2990
+ cache.set(path, exports);
2991
+ const dir = path.includes("/") ? path.slice(0, path.lastIndexOf("/")) : "";
2992
+ const module = { exports, default: void 0 };
2993
+ const require2 = (request) => {
2994
+ const resolved = resolveModulePath(dir, request, files);
2995
+ if (resolved !== null) {
2996
+ return loadModule(resolved, files, sandboxGlobals, cache, resolveBare, bareCache);
2997
+ }
2998
+ if (resolveBare !== void 0 && !request.startsWith("./") && !request.startsWith("../")) {
2999
+ const cachedModule = bareCache?.get(request);
3000
+ if (cachedModule !== void 0) return cachedModule;
3001
+ const loaded = resolveBare(request);
3002
+ bareCache?.set(request, loaded);
3003
+ return loaded;
3004
+ }
3005
+ const error = new Error(
3006
+ `\u6C99\u7BB1\u62D2\u7EDD\u8BE5\u5F15\u7528\uFF1A"${request}"\u3002\u51FD\u6570\u5185\u53EA\u80FD require \u9879\u76EE\u5185\u7684\u76F8\u5BF9\u8DEF\u5F84\u6587\u4EF6\uFF08FN_SANDBOX_BUILTIN_BLOCKED\uFF09`
3007
+ );
3008
+ error.code = SANDBOX_BUILTIN_REJECTED;
3009
+ throw error;
3010
+ };
3011
+ let transformed;
3012
+ try {
3013
+ transformed = transformExports(transpile(source));
3014
+ } catch (error) {
3015
+ const rawMessage = error instanceof Error ? error.message : String(error);
3016
+ const stack = error.stack;
3017
+ const line = typeof stack === "string" ? /(?:^|\n):(\d+)(?:\n|$)/.exec(stack)?.[1] : void 0;
3018
+ const location = line === void 0 ? path : `${path}:${line}`;
3019
+ const wrapped = new Error(`\u6E90\u7801\u8BED\u6CD5\u9519\u8BEF\uFF08${location}\uFF09\uFF1A${rawMessage}`, { cause: error });
3020
+ const code = error.code;
3021
+ if (typeof code === "string") wrapped.code = code;
3022
+ throw wrapped;
3023
+ }
3024
+ const wrapper = vm.runInNewContext(
3025
+ `(function (module, exports, require) { ${transformed}
3026
+ })`,
3027
+ vm.createContext({ ...sandboxGlobals }),
3028
+ { filename: path }
3029
+ );
3030
+ wrapper(module, exports, require2);
3031
+ if (module.default !== void 0 && exports["default"] === void 0) {
3032
+ exports["default"] = module.default;
3033
+ }
3034
+ return exports;
3035
+ }
3036
+ function loadFunctionModule(files, entry, sandboxGlobals, resolveBare) {
3037
+ const cache = /* @__PURE__ */ new Map();
3038
+ const bareCache = /* @__PURE__ */ new Map();
3039
+ const entryExports = loadModule(entry, files, sandboxGlobals, cache, resolveBare, bareCache);
3040
+ const handler = entryExports["default"];
3041
+ if (typeof handler !== "function") {
3042
+ throw new Error(`\u5165\u53E3\u6587\u4EF6 ${entry} \u7F3A\u5C11 default \u5BFC\u51FA\u7684\u51FD\u6570`);
3043
+ }
3044
+ return { handler };
3045
+ }
3046
+
3047
+ // packages/runtime/src/state-objects/loader.ts
3048
+ var STATE_OBJECTS_ENTRY = "state-objects.ts";
3049
+ var STATE_OBJECTS_SPECIFIER = "@adep/runtime/state-objects";
3050
+ function resolveStateObjectSpecifier(request) {
3051
+ if (request === STATE_OBJECTS_SPECIFIER) return { StateObject };
3052
+ return void 0;
3053
+ }
3054
+ function defaultStateSandboxGlobals() {
3055
+ return {
3056
+ console,
3057
+ URL,
3058
+ URLSearchParams,
3059
+ Request,
3060
+ Response,
3061
+ Headers,
3062
+ TextEncoder,
3063
+ TextDecoder,
3064
+ AbortController,
3065
+ AbortSignal,
3066
+ ReadableStream,
3067
+ WritableStream,
3068
+ TransformStream,
3069
+ Blob,
3070
+ FormData,
3071
+ crypto,
3072
+ performance,
3073
+ atob,
3074
+ btoa,
3075
+ structuredClone
3076
+ };
3077
+ }
3078
+ function collectStateObjectClasses(exports_) {
3079
+ const classes = [];
3080
+ for (const value of Object.values(exports_)) {
3081
+ if (typeof value !== "function") continue;
3082
+ const proto = value.prototype;
3083
+ if (typeof proto !== "object" || proto === null) continue;
3084
+ if (!(proto instanceof StateObject)) continue;
3085
+ if (!Object.hasOwn(value, "typeName")) {
3086
+ throw new Error(
3087
+ `\u72B6\u6001\u5BF9\u8C61\u7C7B\u5FC5\u987B\u58F0\u660E static typeName\uFF08${value.name ?? "anonymous"}\uFF09`
3088
+ );
3089
+ }
3090
+ const typeName = value.typeName;
3091
+ if (typeof typeName !== "string" || typeName.length === 0) {
3092
+ throw new Error(
3093
+ `\u72B6\u6001\u5BF9\u8C61\u7C7B\u5FC5\u987B\u58F0\u660E static typeName\uFF08${value.name ?? "anonymous"}\uFF09`
3094
+ );
3095
+ }
3096
+ classes.push(value);
3097
+ }
3098
+ return classes;
3099
+ }
3100
+ function loadStateObjectClasses(files, entry = STATE_OBJECTS_ENTRY, options = {}) {
3101
+ if (files[entry] === void 0) {
3102
+ throw new Error(`\u72B6\u6001\u5BF9\u8C61\u58F0\u660E\u6587\u4EF6\u7F3A\u5931\uFF1A${entry}\uFF08\u7EA6\u5B9A ${STATE_OBJECTS_ENTRY}\uFF09`);
3103
+ }
3104
+ const globals = options.sandboxGlobals ?? defaultStateSandboxGlobals();
3105
+ const exportsObject = loadModule(entry, files, globals, /* @__PURE__ */ new Map(), options.resolveBare, /* @__PURE__ */ new Map());
3106
+ return collectStateObjectClasses(exportsObject);
3107
+ }
3108
+
3109
+ // packages/runtime/src/functions/runtime/worker-entry.ts
3110
+ import { parentPort, workerData } from "node:worker_threads";
3111
+ import { createRequire } from "node:module";
3112
+ import { join as join7 } from "node:path";
3113
+
3114
+ // packages/runtime/src/functions/runtime/cloud-container.ts
3115
+ var KNOWN_CAPABILITY_HINTS = {
3116
+ db: {
3117
+ code: "DB_NOT_PROVISIONED",
3118
+ message: "\u9879\u76EE\u6570\u636E\u5E93\u5C1A\u672A\u5F00\u542F\uFF1A\u8BF7\u5230\u9879\u76EE\u8BBE\u7F6E\u542F\u52A8\u6570\u636E\u5E93\uFF08DB_NOT_PROVISIONED\uFF09"
3119
+ },
3120
+ storage: {
3121
+ code: "STORAGE_NOT_AVAILABLE",
3122
+ message: "\u6587\u4EF6\u5B58\u50A8\u5C1A\u672A\u5F00\u542F\uFF1A\u8BF7\u5230\u9879\u76EE\u8BBE\u7F6E\u5F00\u542F\u6587\u4EF6\u5B58\u50A8\uFF08STORAGE_NOT_AVAILABLE\uFF09"
3123
+ },
3124
+ fetch: {
3125
+ code: "FN_FETCH_DISABLED",
3126
+ message: "\u6C99\u7BB1\u7F51\u7EDC\u672A\u5F00\u542F\uFF1A\u8BF7\u914D\u7F6E FUNCTIONS_FETCH_ALLOWLIST \u767D\u540D\u5355\u540E\u91CD\u542F\uFF08FN_FETCH_DISABLED\uFF09"
3127
+ },
3128
+ realtime: {
3129
+ code: "REALTIME_NOT_AVAILABLE",
3130
+ 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"
3131
+ },
3132
+ kv: {
3133
+ code: "KV_NOT_PROVISIONED",
3134
+ 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"
3135
+ }
3136
+ };
3137
+ var CapabilityNotRegisteredError = class extends Error {
3138
+ code;
3139
+ constructor(code, message) {
3140
+ super(message);
3141
+ this.code = code;
3142
+ this.name = "CapabilityNotRegisteredError";
3143
+ }
3144
+ };
3145
+ function createCloud(registrations) {
3146
+ const store = registrations;
3147
+ return new Proxy(
3148
+ {},
3149
+ {
3150
+ get(_target, prop) {
3151
+ if (typeof prop !== "string") return void 0;
3152
+ if (!store.has(prop)) {
3153
+ const hint = KNOWN_CAPABILITY_HINTS[prop];
3154
+ throw new CapabilityNotRegisteredError(
3155
+ hint?.code ?? "CAPABILITY_NOT_REGISTERED",
3156
+ hint?.message ?? `\u80FD\u529B "${prop}" \u672A\u6CE8\u518C\uFF1A\u8BF7\u5728\u51FD\u6570\u6240\u5728\u9879\u76EE\u5B89\u88C5\u5BF9\u5E94\u80FD\u529B`
3157
+ );
3158
+ }
3159
+ return store.get(prop);
3160
+ },
3161
+ has: () => true
3162
+ // 支持 'db' in ctx.cloud 形态
3163
+ }
3164
+ );
3165
+ }
3166
+ function createCloudContainer() {
3167
+ const registry = /* @__PURE__ */ new Map();
3168
+ const names = /* @__PURE__ */ new Set();
3169
+ let cloud = null;
3170
+ const rebuild = () => {
3171
+ cloud = createCloud(registry);
3172
+ };
3173
+ rebuild();
3174
+ return {
3175
+ register(name, impl) {
3176
+ registry.set(name, impl);
3177
+ names.add(name);
3178
+ rebuild();
3179
+ },
3180
+ unregister(name) {
3181
+ registry.delete(name);
3182
+ names.delete(name);
3183
+ rebuild();
3184
+ },
3185
+ get names() {
3186
+ return [...names];
3187
+ },
3188
+ get cloud() {
3189
+ return cloud;
3190
+ }
3191
+ };
3192
+ }
3193
+
3194
+ // packages/runtime/src/functions/runtime/sandbox-fetch.ts
3195
+ var SandboxFetchError = class extends Error {
3196
+ code;
3197
+ constructor(code, message) {
3198
+ super(message);
3199
+ this.name = "SandboxFetchError";
3200
+ this.code = code;
3201
+ }
3202
+ };
3203
+ var DEFAULT_MAX_RESPONSE_BYTES = 100 * 1024 * 1024;
3204
+ var defaultFetch = (url, init) => (
3205
+ // 真实 Response 与内部 ResponseLike 结构性一致;getReader 的多态签名差异属纯类型问题,运行语义等价。
3206
+ globalThis.fetch(url, init)
3207
+ );
3208
+ function isHostAllowed(host, rules) {
3209
+ const h = host.toLocaleLowerCase();
3210
+ return rules.some((raw) => {
3211
+ const rule = raw.trim().toLocaleLowerCase();
3212
+ if (rule.startsWith("*.")) {
3213
+ const base = rule.slice(2);
3214
+ return h === base || h.endsWith(`.${base}`);
3215
+ }
3216
+ return h === rule;
3217
+ });
3218
+ }
3219
+ var FORBIDDEN = (url) => new SandboxFetchError(
3220
+ "FN_FETCH_FORBIDDEN",
3221
+ `cloud.fetch \u62D2\u7EDD\u8BBF\u95EE "${url}"\uFF1A\u8BE5\u4E3B\u673A\u4E0D\u5728\u6C99\u7BB1\u7F51\u7EDC\u767D\u540D\u5355\u5185\uFF08FN_FETCH_FORBIDDEN\uFF09`
3222
+ );
3223
+ var TOO_LARGE = new SandboxFetchError(
3224
+ "FN_FETCH_TOO_LARGE",
3225
+ "cloud.fetch \u54CD\u5E94\u4F53\u8D85\u8FC7\u4E0A\u9650\uFF08FN_FETCH_TOO_LARGE\uFF09"
3226
+ );
3227
+ function headersToRecord(headers) {
3228
+ const out = {};
3229
+ if (headers === void 0 || headers === null) return out;
3230
+ if (typeof headers.forEach === "function") {
3231
+ ;
3232
+ headers.forEach((value, key) => {
3233
+ out[String(key).toLocaleLowerCase()] = String(value);
3234
+ });
3235
+ return out;
3236
+ }
3237
+ for (const [key, value] of Object.entries(headers)) {
3238
+ out[key.toLocaleLowerCase()] = String(value);
3239
+ }
3240
+ return out;
3241
+ }
3242
+ function contentLength(res) {
3243
+ const headers = res.headers;
3244
+ if (headers === void 0 || headers === null) return null;
3245
+ if (typeof headers.get === "function") {
3246
+ const raw2 = headers.get?.("content-length");
3247
+ if (raw2 === void 0 || raw2 === null || raw2.trim() === "") return null;
3248
+ const n2 = Number(raw2);
3249
+ return Number.isFinite(n2) && n2 >= 0 ? n2 : null;
3250
+ }
3251
+ const record = headers;
3252
+ const raw = record["content-length"] ?? record["Content-Length"];
3253
+ if (raw === void 0 || raw === null) return null;
3254
+ const n = Number(raw);
3255
+ return Number.isFinite(n) && n >= 0 ? n : null;
3256
+ }
3257
+ function concatChunks(chunks, total) {
3258
+ const merged = new Uint8Array(total);
3259
+ let offset = 0;
3260
+ for (const chunk of chunks) {
3261
+ merged.set(chunk, offset);
3262
+ offset += chunk.byteLength;
3263
+ }
3264
+ return merged;
3265
+ }
3266
+ async function readBodyBytes(res, maxBytes) {
3267
+ if (maxBytes > 0) {
3268
+ const cl = contentLength(res);
3269
+ if (cl !== null && cl > maxBytes) throw TOO_LARGE;
3270
+ }
3271
+ const body = res.body;
3272
+ if (body !== void 0 && body !== null) {
3273
+ const reader = body.getReader();
3274
+ const chunks = [];
3275
+ let total = 0;
3276
+ for (; ; ) {
3277
+ const { done, value } = await reader.read();
3278
+ if (done) break;
3279
+ if (value !== void 0) {
3280
+ total += value.byteLength;
3281
+ if (maxBytes > 0 && total > maxBytes) throw TOO_LARGE;
3282
+ chunks.push(value);
3283
+ }
3284
+ }
3285
+ return concatChunks(chunks, total);
3286
+ }
3287
+ if (typeof res.arrayBuffer === "function") {
3288
+ const buffer = await res.arrayBuffer();
3289
+ const bytes2 = new Uint8Array(buffer);
3290
+ if (maxBytes > 0 && bytes2.byteLength > maxBytes) throw TOO_LARGE;
3291
+ return bytes2;
3292
+ }
3293
+ const text = await res.text();
3294
+ const bytes = encoder.encode(text);
3295
+ if (maxBytes > 0 && bytes.byteLength > maxBytes) throw TOO_LARGE;
3296
+ return bytes;
3297
+ }
3298
+ var encoder = new TextEncoder();
3299
+ function errorMessageOf(error) {
3300
+ if (error instanceof Error) return error.message;
3301
+ return String(error);
3302
+ }
3303
+ function normalizeResponse(res, maxBytes) {
3304
+ let cached = null;
3305
+ let cachedPromise = null;
3306
+ const readCached = () => {
3307
+ if (cached !== null) return Promise.resolve(cached);
3308
+ cachedPromise ??= readBodyBytes(res, maxBytes).then((bytes) => {
3309
+ cached = bytes;
3310
+ return bytes;
3311
+ });
3312
+ return cachedPromise;
3313
+ };
3314
+ const read = () => readCached();
3315
+ return {
3316
+ ok: res.ok,
3317
+ status: res.status,
3318
+ statusText: res.statusText,
3319
+ headers: headersToRecord(res.headers),
3320
+ text: async () => decoder.decode(await read()),
3321
+ arrayBuffer: async () => bufferViewToArrayBuffer(await read()),
3322
+ json: async () => JSON.parse(decoder.decode(await read()))
3323
+ };
3324
+ }
3325
+ var decoder = new TextDecoder();
3326
+ function bufferViewToArrayBuffer(bytes) {
3327
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
3328
+ }
3329
+ function createSandboxFetch(options) {
3330
+ const fetchImpl = options.fetchImpl ?? defaultFetch;
3331
+ const { allowlist, timeoutMs } = options;
3332
+ const maxBytes = options.maxResponseBytes ?? DEFAULT_MAX_RESPONSE_BYTES;
3333
+ return async (url, init) => {
3334
+ let parsed;
3335
+ try {
3336
+ parsed = new URL(url);
3337
+ } catch {
3338
+ throw new SandboxFetchError("FN_FETCH_INVALID_URL", `cloud.fetch \u6536\u5230\u975E\u6CD5 URL"${url}"`);
3339
+ }
3340
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") throw FORBIDDEN(url);
3341
+ if (!isHostAllowed(parsed.hostname, allowlist)) throw FORBIDDEN(url);
3342
+ const controller = new AbortController();
3343
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
3344
+ const signals = [controller.signal];
3345
+ if (init?.signal !== void 0) signals.push(init.signal);
3346
+ const signal = signals.length === 1 ? signals[0] : AbortSignal.any(signals);
3347
+ try {
3348
+ let res;
3349
+ try {
3350
+ res = await fetchImpl(url, { ...init, signal });
3351
+ } catch (error) {
3352
+ if (controller.signal.aborted) {
3353
+ throw new SandboxFetchError(
3354
+ "FN_FETCH_TIMEOUT",
3355
+ `cloud.fetch \u8BF7\u6C42\u8D85\u65F6\uFF08\u8D85\u8FC7 ${timeoutMs}ms\uFF09`
3356
+ );
3357
+ }
3358
+ if (init?.signal?.aborted === true) {
3359
+ throw new SandboxFetchError("FN_FETCH_ABORTED", "cloud.fetch \u8BF7\u6C42\u88AB\u8C03\u7528\u65B9\u4E2D\u6B62");
3360
+ }
3361
+ throw new SandboxFetchError(
3362
+ "FN_FETCH_FAILED",
3363
+ `cloud.fetch \u8BF7\u6C42\u5931\u8D25\uFF1A${errorMessageOf(error)}`
3364
+ );
3365
+ }
3366
+ return normalizeResponse(res, maxBytes);
3367
+ } finally {
3368
+ clearTimeout(timer);
3369
+ }
3370
+ };
3371
+ }
3372
+
3373
+ // packages/runtime/src/functions/runtime/chain.ts
3374
+ function isChainCapability(value) {
3375
+ if (typeof value !== "object" || value === null) return false;
3376
+ const spec = value[CHAIN_CAPABILITY_KEY];
3377
+ return typeof spec === "object" && spec !== null && Array.isArray(spec.stepMethods) && Array.isArray(spec.terminalMethods);
3378
+ }
3379
+ function createChainClient(capability, port, pending, nextId, spec) {
3380
+ const call = (method, args) => new Promise((resolve3, reject) => {
3381
+ const id = nextId();
3382
+ pending.set(id, { resolve: resolve3, reject });
3383
+ port.postMessage({ type: "rpc", id, capability, method, args });
3384
+ });
3385
+ const makeChainable = (rootArgs, steps, txId) => new Proxy(
3386
+ {},
3387
+ {
3388
+ get(_target, prop) {
3389
+ if (typeof prop !== "string") return void 0;
3390
+ if (spec.stepMethods.includes(prop)) {
3391
+ return (...args) => makeChainable(rootArgs, [...steps, { method: prop, args }], txId);
3392
+ }
3393
+ if (spec.terminalMethods.includes(prop)) {
3394
+ return (...args) => call(DB_RPC.chain, [
3395
+ {
3396
+ rootArgs,
3397
+ steps,
3398
+ terminal: prop,
3399
+ terminalArgs: args,
3400
+ ...txId === void 0 ? {} : { txId }
3401
+ }
3402
+ ]);
3403
+ }
3404
+ return void 0;
3405
+ }
3406
+ }
3407
+ );
3408
+ const makeRoot = (txId) => new Proxy(
3409
+ {},
3410
+ {
3411
+ get(_target, prop) {
3412
+ if (typeof prop !== "string") return void 0;
3413
+ if (prop === spec.rootMethod) {
3414
+ return (...rootArgs) => makeChainable(rootArgs, [], txId);
3415
+ }
3416
+ if (spec.directMethods.includes(prop)) {
3417
+ return (...args) => call(prop, args);
3418
+ }
3419
+ if (prop === spec.transactionMethod) {
3420
+ return (fn) => orchestrateTransaction(fn, txId);
3421
+ }
3422
+ return void 0;
3423
+ }
3424
+ }
3425
+ );
3426
+ const orchestrateTransaction = async (fn, _outerTxId) => {
3427
+ const txId = await call(DB_RPC.begin, []);
3428
+ const tx = makeRoot(txId);
3429
+ const settle = async (commit) => {
3430
+ await call(commit ? DB_RPC.commit : DB_RPC.rollback, [txId]).catch(() => void 0);
3431
+ };
3432
+ try {
3433
+ const result = await fn(tx);
3434
+ await settle(true);
3435
+ return result;
3436
+ } catch (error) {
3437
+ await settle(false);
3438
+ throw error;
3439
+ }
3440
+ };
3441
+ return makeRoot(void 0);
3442
+ }
3443
+
3444
+ // packages/runtime/src/functions/runtime/worker-entry.ts
3445
+ function isRpcCapability(value) {
3446
+ return typeof value === "object" && value !== null && value[RPC_CAPABILITY_KEY] === true;
3447
+ }
3448
+ function createRpcClient(capability, port, pending, nextId) {
3449
+ return new Proxy(
3450
+ {},
3451
+ {
3452
+ get(_target, method) {
3453
+ if (typeof method !== "string") return void 0;
3454
+ return (...args) => {
3455
+ const id = nextId();
3456
+ return new Promise((resolve3, reject) => {
3457
+ pending.set(id, { resolve: resolve3, reject });
3458
+ port.postMessage({ type: "rpc", id, capability, method, args });
3459
+ });
3460
+ };
3461
+ }
3462
+ }
3463
+ );
3464
+ }
3465
+ function errorMessageOf2(error) {
3466
+ if (error instanceof Error) return error.message;
3467
+ if (typeof error === "object" && error !== null && "message" in error) {
3468
+ const message = error.message;
3469
+ if (typeof message === "string") return message;
3470
+ }
3471
+ return String(error);
3472
+ }
3473
+ function escapeRegExp(text) {
3474
+ return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3475
+ }
3476
+ function firstUserFrame(stack, files) {
3477
+ for (const key of Object.keys(files)) {
3478
+ const match = new RegExp(
3479
+ `(?<![\\w$/.])${escapeRegExp(key)}:(\\d+)(?::(\\d+))?(?::(\\d+))?`
3480
+ ).exec(stack);
3481
+ if (match !== null) {
3482
+ return match[2] === void 0 ? `${key}:${match[1]}` : `${key}:${match[1]}:${match[2]}`;
3483
+ }
3484
+ }
3485
+ return void 0;
3486
+ }
3487
+ function errorMessageWithLocation(error, files) {
3488
+ const message = errorMessageOf2(error);
3489
+ const stack = error.stack;
3490
+ if (typeof stack !== "string") return message;
3491
+ const frame = firstUserFrame(stack, files);
3492
+ return frame === void 0 ? message : `${message}\uFF08${frame}\uFF09`;
3493
+ }
3494
+ function createBareResolver(deps) {
3495
+ const platformRequire = createRequire(import.meta.url);
3496
+ const depsRequire = deps.dir === null ? null : createRequire(join7(deps.dir, "__deps__.js"));
3497
+ return (request) => {
3498
+ if (deps.builtin.includes(request)) return platformRequire(request);
3499
+ const root = splitBareSpecifier(request);
3500
+ if (deps.builtin.includes(root)) return platformRequire(request);
3501
+ if (deps.custom.includes(root)) {
3502
+ if (depsRequire === null) {
3503
+ throw new Error(`\u4F9D\u8D56 "${root}" \u672A\u88C5\u8F7D\uFF1A\u9879\u76EE\u4F9D\u8D56\u76EE\u5F55\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u53D1\u5E03\u51FD\u6570\u89E6\u53D1\u4F9D\u8D56\u88C5\u8F7D`);
3504
+ }
3505
+ try {
3506
+ return depsRequire(request);
3507
+ } catch (error2) {
3508
+ const message = errorMessageOf2(error2);
3509
+ throw new Error(
3510
+ `\u4F9D\u8D56 "${request}" \u88C5\u8F7D\u5931\u8D25\uFF08\u76EE\u5F55 ${deps.dir}\uFF09\uFF1A\u8BF7\u91CD\u65B0\u53D1\u5E03\u51FD\u6570\u4EE5\u89E6\u53D1\u4F9D\u8D56\u5B89\u88C5\u3002\u539F\u56E0\uFF1A${message}`,
3511
+ { cause: error2 }
3512
+ );
3513
+ }
3514
+ }
3515
+ const error = new Error(
3516
+ `\u6C99\u7BB1\u62D2\u7EDD\u8BE5\u5F15\u7528\uFF1A"${request}"\u3002\u4EC5\u5141\u8BB8\u76F8\u5BF9\u8DEF\u5F84\u6587\u4EF6\u4E0E\u5DF2\u58F0\u660E\u7684\u4F9D\u8D56\uFF08\u5185\u7F6E\u767D\u540D\u5355\u6216 package.json\uFF09\uFF0C\u88F8\u6A21\u5757 "${root}" \u672A\u58F0\u660E\uFF08FN_SANDBOX_BUILTIN_BLOCKED\uFF09`
3517
+ );
3518
+ error.code = SANDBOX_BUILTIN_REJECTED;
3519
+ throw error;
3520
+ };
3521
+ }
3522
+ function runWorker(input, port) {
3523
+ const emit = (level, args) => {
3524
+ port.postMessage({ type: "log", level, message: args.map(String).join(" ") });
3525
+ };
3526
+ const forwardedConsole = {
3527
+ log: (...args) => emit("log", args),
3528
+ error: (...args) => emit("error", args),
3529
+ warn: (...args) => emit("warn", args)
3530
+ };
3531
+ const container = createCloudContainer();
3532
+ const pending = /* @__PURE__ */ new Map();
3533
+ let rpcId = 0;
3534
+ port.on?.((message) => {
3535
+ const reply = message;
3536
+ if (reply?.type !== "rpc-response" || typeof reply.id !== "number") return;
3537
+ const entry = pending.get(reply.id);
3538
+ if (entry === void 0) return;
3539
+ pending.delete(reply.id);
3540
+ if (reply.ok === true) entry.resolve(reply.result);
3541
+ else entry.reject(new Error(reply.error ?? "RPC \u80FD\u529B\u8C03\u7528\u5931\u8D25"));
3542
+ });
3543
+ for (const capability of input.capabilities ?? []) {
3544
+ container.register(
3545
+ capability.name,
3546
+ isChainCapability(capability.value) ? createChainClient(
3547
+ capability.name,
3548
+ port,
3549
+ pending,
3550
+ () => ++rpcId,
3551
+ capability.value[CHAIN_CAPABILITY_KEY]
3552
+ ) : isRpcCapability(capability.value) ? createRpcClient(capability.name, port, pending, () => ++rpcId) : capability.value
3553
+ );
3554
+ }
3555
+ const sandboxGlobals = {
3556
+ console: forwardedConsole,
3557
+ // CF-015:Cloudflare Workers 代码重度依赖 Web 标准 API(URL / Request / Response /
3558
+ // Headers / 流 / 编码 / crypto 等)。Node 18+ 全局内置,直接注入 vm 上下文;
3559
+ // 与 @adep/cf-compat 的 Workers 适配(ctxToRequest / responseToEnvelopeBody)配套。
3560
+ URL,
3561
+ URLSearchParams,
3562
+ Request,
3563
+ Response,
3564
+ Headers,
3565
+ TextEncoder,
3566
+ TextDecoder,
3567
+ AbortController,
3568
+ AbortSignal,
3569
+ ReadableStream,
3570
+ WritableStream,
3571
+ TransformStream,
3572
+ Blob,
3573
+ FormData,
3574
+ crypto,
3575
+ performance,
3576
+ atob,
3577
+ btoa,
3578
+ structuredClone
3579
+ };
3580
+ if (input.env !== void 0) {
3581
+ sandboxGlobals["process"] = { env: input.env };
3582
+ }
3583
+ if (input.fetch !== void 0) {
3584
+ const sandboxFetch = createSandboxFetch({
3585
+ allowlist: input.fetch.allowlist,
3586
+ timeoutMs: input.fetch.timeoutMs,
3587
+ ...input.fetch.maxResponseBytes === void 0 ? {} : { maxResponseBytes: input.fetch.maxResponseBytes }
3588
+ });
3589
+ sandboxGlobals["fetch"] = sandboxFetch;
3590
+ container.register("fetch", sandboxFetch);
3591
+ }
3592
+ const ctx = {
3593
+ method: input.request.method,
3594
+ path: input.request.path,
3595
+ query: input.request.query,
3596
+ headers: input.request.headers,
3597
+ ...input.request.body === void 0 ? {} : { body: input.request.body },
3598
+ files: input.request.files ?? [],
3599
+ cloud: container.cloud,
3600
+ user: input.request.user ?? null,
3601
+ ...input.env === void 0 ? {} : { env: input.env }
3602
+ };
3603
+ try {
3604
+ const { handler } = loadFunctionModule(
3605
+ input.files,
3606
+ input.entry,
3607
+ sandboxGlobals,
3608
+ input.deps === void 0 ? void 0 : createBareResolver(input.deps)
3609
+ );
3610
+ const result = Promise.resolve(handler(ctx));
3611
+ void result.then(
3612
+ (value) => {
3613
+ port.postMessage({ type: "result", body: value === void 0 ? null : value });
3614
+ return void 0;
3615
+ },
3616
+ (error) => {
3617
+ port.postMessage({
3618
+ type: "error",
3619
+ message: errorMessageWithLocation(error, input.files),
3620
+ code: error.code,
3621
+ // FN-011:函数抛错可携带 status(4xx/5xx),透传给执行器落 ExecutorError.status。
3622
+ status: error.status
3623
+ });
3624
+ return void 0;
3625
+ }
3626
+ );
3627
+ } catch (error) {
3628
+ port.postMessage({
3629
+ type: "error",
3630
+ message: errorMessageWithLocation(error, input.files),
3631
+ code: error.code,
3632
+ status: error.status
3633
+ });
3634
+ }
3635
+ }
3636
+ var workerPort = parentPort;
3637
+ if (workerPort !== null && workerData !== void 0) {
3638
+ const port = {
3639
+ // eslint-disable-next-line unicorn/require-post-message-target-origin -- node worker_threads 无 targetOrigin 语义
3640
+ postMessage: (message) => workerPort.postMessage(message),
3641
+ on: (listener) => {
3642
+ workerPort.on("message", (value) => listener(value));
3643
+ }
3644
+ };
3645
+ runWorker(workerData, port);
3646
+ }
3647
+
3648
+ // packages/cli/src/dev.ts
2414
3649
  async function loadConfig(cwd) {
2415
3650
  const name = basename(resolve2(cwd));
2416
3651
  const config = await loadAdepConfigModule(cwd);
2417
3652
  return {
2418
3653
  name: config?.name ?? name,
2419
3654
  functionsDir: config?.functionsDir ?? "functions",
2420
- functionsPrefix: config?.functions_prefix ?? ""
3655
+ functionsPrefix: config?.functions_prefix ?? "",
3656
+ ...config?.environment === void 0 ? {} : { environment: config.environment }
2421
3657
  };
2422
3658
  }
2423
3659
  function parseEnvFile(content) {
@@ -2444,7 +3680,7 @@ async function collectFunctions(dir) {
2444
3680
  }
2445
3681
  for (const entry of entries) {
2446
3682
  const rel = prefix.length === 0 ? entry.name : `${prefix}/${entry.name}`;
2447
- const full = join7(sub, entry.name);
3683
+ const full = join8(sub, entry.name);
2448
3684
  if (entry.isDirectory()) {
2449
3685
  await walk(full, rel);
2450
3686
  } else if (entry.isFile() && entry.name.endsWith(".ts")) {
@@ -2511,7 +3747,7 @@ function printBoundaries(log) {
2511
3747
  }
2512
3748
  }
2513
3749
  async function ensureGitignore(cwd) {
2514
- const gitignorePath = join7(cwd, ".gitignore");
3750
+ const gitignorePath = join8(cwd, ".gitignore");
2515
3751
  const existing = await readFile5(gitignorePath, "utf8").catch(() => "");
2516
3752
  if (existing.split(/\r?\n/).includes(".adep/")) return;
2517
3753
  await writeFile3(gitignorePath, `${existing.replace(/\n+$/, "")}
@@ -2526,9 +3762,11 @@ async function startDevServer(options) {
2526
3762
  if (options.prefix !== void 0) {
2527
3763
  config.functionsPrefix = options.prefix.replace(/^\/+|\/+$/g, "");
2528
3764
  }
2529
- const functionsDir = join7(cwd, config.functionsDir);
3765
+ const functionsDir = join8(cwd, config.functionsDir);
2530
3766
  const coldStartAt = Date.now();
2531
- const executor = new WorkerFunctionExecutor();
3767
+ const executor = new WorkerFunctionExecutor({
3768
+ deps: { rootDir: cwd, builtin: LOCAL_BUILTIN_DEPS }
3769
+ });
2532
3770
  await mkdir3(functionsDir, { recursive: true });
2533
3771
  const runtime = await createSimRuntime({
2534
3772
  cwd,
@@ -2538,19 +3776,91 @@ async function startDevServer(options) {
2538
3776
  });
2539
3777
  await ensureGitignore(cwd);
2540
3778
  let files = await collectFunctions(functionsDir);
2541
- let env = await loadSimEnv(cwd).catch(() => ({}));
3779
+ let env = {
3780
+ ...config.environment,
3781
+ ...await loadSimEnv(cwd).catch(() => ({}))
3782
+ };
2542
3783
  const dbBundle = runtime.bundle;
2543
3784
  const invokeHandler = createSimInvokeHandler({ executor, files });
3785
+ let stateRuntime = null;
3786
+ let stateFingerprint = "";
3787
+ const bareResolver = createBareResolver({
3788
+ dir: null,
3789
+ builtin: [...LOCAL_BUILTIN_DEPS],
3790
+ custom: []
3791
+ });
3792
+ const collectStateDeclarations = () => {
3793
+ const declared = [];
3794
+ const dirs = /* @__PURE__ */ new Set();
3795
+ for (const path of Object.keys(files)) {
3796
+ if (path === STATE_OBJECTS_ENTRY || path.endsWith(`/${STATE_OBJECTS_ENTRY}`)) {
3797
+ dirs.add(path === STATE_OBJECTS_ENTRY ? "" : path.slice(0, -STATE_OBJECTS_ENTRY.length - 1));
3798
+ }
3799
+ }
3800
+ for (const dir of dirs) {
3801
+ const prefix = dir.length === 0 ? "" : `${dir}/`;
3802
+ const fileMap = {};
3803
+ for (const [path, content] of Object.entries(files)) {
3804
+ if (path.startsWith(prefix)) fileMap[path] = content;
3805
+ }
3806
+ declared.push({ dir, files: fileMap });
3807
+ }
3808
+ return declared;
3809
+ };
3810
+ const stateObjectBareResolver = (request) => {
3811
+ const state = resolveStateObjectSpecifier(request);
3812
+ if (state !== void 0) return state;
3813
+ return bareResolver(request);
3814
+ };
3815
+ const refreshStateRuntime = () => {
3816
+ const declarations = collectStateDeclarations();
3817
+ const fingerprint = declarations.map(
3818
+ (d) => `${d.dir}\0${d.files[`${d.dir === "" ? "" : `${d.dir}/`}${STATE_OBJECTS_ENTRY}`] ?? ""}`
3819
+ ).join("");
3820
+ if (stateRuntime !== null && stateFingerprint === fingerprint) return stateRuntime;
3821
+ stateRuntime = new StateObjectRuntime(createProjectDriverStateBackend(runtime.db.driver));
3822
+ stateRuntime.define(DemoCounter);
3823
+ stateRuntime.define(DemoChatRoom);
3824
+ for (const d of declarations) {
3825
+ const loaded = loadStateObjectClasses(
3826
+ d.files,
3827
+ `${d.dir === "" ? "" : `${d.dir}/`}${STATE_OBJECTS_ENTRY}`,
3828
+ {
3829
+ resolveBare: stateObjectBareResolver
3830
+ }
3831
+ );
3832
+ for (const cls of loaded) stateRuntime.define(cls);
3833
+ }
3834
+ stateFingerprint = fingerprint;
3835
+ return stateRuntime;
3836
+ };
3837
+ let stateAlarmTimer;
3838
+ const startStateAlarmScheduler = () => {
3839
+ if (stateAlarmTimer !== void 0) return;
3840
+ stateAlarmTimer = setInterval(() => {
3841
+ void refreshStateRuntime().pump(Date.now()).catch((error) => {
3842
+ log(
3843
+ `[adep] \u72B6\u6001\u5BF9\u8C61 alarm tick \u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}`
3844
+ );
3845
+ });
3846
+ }, options.stateAlarmTickMs ?? 1e3);
3847
+ stateAlarmTimer.unref?.();
3848
+ };
3849
+ const stopStateAlarmScheduler = () => {
3850
+ if (stateAlarmTimer === void 0) return;
3851
+ clearInterval(stateAlarmTimer);
3852
+ stateAlarmTimer = void 0;
3853
+ };
2544
3854
  const reload = async () => {
2545
3855
  const [nextFiles, envText2] = await Promise.all([
2546
3856
  collectFunctions(functionsDir),
2547
- readFile5(join7(cwd, ".env.local"), "utf8").catch(() => "")
3857
+ readFile5(join8(cwd, ".env.local"), "utf8").catch(() => "")
2548
3858
  ]);
2549
3859
  files = nextFiles;
2550
- env = parseEnvFile(envText2);
3860
+ env = { ...config.environment, ...parseEnvFile(envText2) };
2551
3861
  };
2552
- const envText = await readFile5(join7(cwd, ".env.local"), "utf8").catch(() => "");
2553
- env = parseEnvFile(envText);
3862
+ const envText = await readFile5(join8(cwd, ".env.local"), "utf8").catch(() => "");
3863
+ env = { ...config.environment, ...parseEnvFile(envText) };
2554
3864
  let debounceTimer;
2555
3865
  let watcher;
2556
3866
  try {
@@ -2610,6 +3920,43 @@ async function startDevServer(options) {
2610
3920
  });
2611
3921
  return;
2612
3922
  }
3923
+ if (fnName === "state") {
3924
+ const normalizedPrefix = config.functionsPrefix.replace(/^\/+|\/+$/g, "");
3925
+ const rest = normalizedPrefix.length === 0 ? url.pathname : url.pathname.replace(new RegExp(`^/${normalizedPrefix}`), "");
3926
+ const parsed = parseStatePath(rest);
3927
+ if (parsed === null) {
3928
+ writeJson(res, 400, {
3929
+ error: { code: "STATE_BAD_PATH", message: "\u72B6\u6001\u5BF9\u8C61\u8DEF\u5F84\uFF1A/api/state/:type/:id/:method" }
3930
+ });
3931
+ return;
3932
+ }
3933
+ const rawBody = await bodyOf(req);
3934
+ const parsedBody = parseStateBody(
3935
+ req.method === "GET" || req.method === "HEAD" ? null : rawBody === void 0 ? null : typeof rawBody === "string" ? rawBody : JSON.stringify(rawBody)
3936
+ );
3937
+ if ("error" in parsedBody) {
3938
+ writeJson(res, 400, { error: { code: "STATE_BAD_ARGS", message: parsedBody.error } });
3939
+ return;
3940
+ }
3941
+ try {
3942
+ const result = await refreshStateRuntime().invoke(
3943
+ parsed.type,
3944
+ parsed.id,
3945
+ parsed.method,
3946
+ parsedBody.args
3947
+ );
3948
+ writeJson(res, 200, { ok: true, data: result });
3949
+ } catch (error) {
3950
+ if (error instanceof StateObjectError) {
3951
+ writeJson(res, error.code === "STATE_TYPE_NOT_REGISTERED" ? 404 : 400, {
3952
+ error: { code: error.code, message: error.message }
3953
+ });
3954
+ return;
3955
+ }
3956
+ writeJson(res, 500, { error: { code: "STATE_INVOKE_ERROR", message: String(error) } });
3957
+ }
3958
+ return;
3959
+ }
2613
3960
  const entry = resolveFunctionEntry(files, fnName);
2614
3961
  if (entry === void 0) {
2615
3962
  log(`[adep] ${req.method ?? "GET"} /${fnName} -> 404\uFF08\u51FD\u6570\u4E0D\u5B58\u5728\uFF09`);
@@ -2621,8 +3968,15 @@ async function startDevServer(options) {
2621
3968
  try {
2622
3969
  const result = await executor.execute(input);
2623
3970
  const durationMs = Math.round(performance.now() - startedAt);
2624
- log(`[adep] ${req.method ?? "GET"} /${fnName} -> 200 ${durationMs}ms`);
2625
3971
  for (const line of result.logs) log(`[adep] ${line}`);
3972
+ if (isAdepHttpEnvelope(result.body)) {
3973
+ log(
3974
+ `[adep] ${req.method ?? "GET"} /${fnName} -> ${result.body.__adepHttp.status} ${durationMs}ms`
3975
+ );
3976
+ writeEnvelopeResponse(res, result.body);
3977
+ return;
3978
+ }
3979
+ log(`[adep] ${req.method ?? "GET"} /${fnName} -> 200 ${durationMs}ms`);
2626
3980
  writeJson(res, 200, result.body === void 0 ? null : result.body);
2627
3981
  } catch (error) {
2628
3982
  const durationMs = Math.round(performance.now() - startedAt);
@@ -2680,10 +4034,12 @@ async function startDevServer(options) {
2680
4034
  log(`[adep] curl \u793A\u4F8B\uFF1Acurl ${baseUrl}${curlPath}`);
2681
4035
  printBoundaries(log);
2682
4036
  log(`[adep] \u6A21\u62DF\u6570\u636E\u76EE\u5F55\uFF1A${simDir(cwd)}`);
4037
+ startStateAlarmScheduler();
2683
4038
  return {
2684
4039
  port: actualPort,
2685
4040
  baseUrl,
2686
4041
  close: async () => {
4042
+ stopStateAlarmScheduler();
2687
4043
  if (debounceTimer !== void 0) clearTimeout(debounceTimer);
2688
4044
  watcher?.close();
2689
4045
  await new Promise((resolveClose) => server.close(() => resolveClose()));
@@ -2693,126 +4049,28 @@ async function startDevServer(options) {
2693
4049
  };
2694
4050
  }
2695
4051
 
2696
- // src/vite.ts
2697
- function normalizeFunctionPrefix(raw) {
2698
- const value = (raw ?? "").trim();
2699
- if (value.length === 0 || value === "/") return "";
2700
- return value.replace(/^\/+|\/+$/g, "");
2701
- }
2702
- function isAddrInUse(error) {
2703
- return typeof error === "object" && error !== null && "code" in error && error.code === "EADDRINUSE";
2704
- }
2705
- function createAdepProxyMiddleware(prefix, targetBase) {
2706
- const normalized = normalizeFunctionPrefix(prefix);
2707
- const prefixPath = normalized === "" ? "" : `/${normalized}`;
2708
- return (req, res, next) => {
2709
- if (prefixPath === "") return next();
2710
- const url = new URL(req.url ?? "/", "http://127.0.0.1");
2711
- if (url.pathname !== prefixPath && !url.pathname.startsWith(`${prefixPath}/`)) {
2712
- return next();
2713
- }
2714
- const target = new URL(url.pathname + url.search, targetBase);
2715
- const proxyReq = httpRequest(
2716
- target,
2717
- { method: req.method, headers: { ...req.headers, host: target.host } },
2718
- (proxyRes) => {
2719
- res.writeHead(proxyRes.statusCode ?? 502, proxyRes.headers);
2720
- proxyRes.pipe(res);
2721
- }
2722
- );
2723
- proxyReq.on("error", (error) => {
2724
- if (!res.headersSent) {
2725
- res.writeHead(502, { "content-type": "application/json" });
2726
- }
2727
- res.end(
2728
- JSON.stringify({
2729
- error: {
2730
- code: "ADEP_DEV_UNAVAILABLE",
2731
- message: `\u4E91\u51FD\u6570\u4EE3\u7406\u5931\u8D25\uFF08adep dev server \u4E0D\u53EF\u8FBE\uFF09\uFF1A${error.message}`
2732
- }
2733
- })
2734
- );
2735
- });
2736
- req.pipe(proxyReq);
2737
- };
2738
- }
4052
+ // packages/cli/src/vite.ts
4053
+ import {
4054
+ createAdepFnProxyScriptMiddleware,
4055
+ createAdepProxyMiddleware,
4056
+ FN_FETCH_INTERCEPTOR_SCRIPT,
4057
+ injectFnProxyScriptTag,
4058
+ isAddrInUse,
4059
+ normalizeFunctionPrefix
4060
+ } from "@adep/vite-plugin";
4061
+ var createDevServer = (opts) => startDevServer({ cwd: opts.cwd, port: opts.port, prefix: opts.prefix, log: opts.log });
4062
+ var loadConfig2 = (cwd) => loadAdepConfigModule(cwd);
2739
4063
  function adepVitePlugin(options = {}) {
2740
- const cwd = resolve3(options.cwd ?? process.cwd());
2741
- let dev;
2742
- let prefix = normalizeFunctionPrefix(options.prefix);
2743
- let prefixPath = "";
2744
- let startPromise;
2745
- const startAdepDev = async (log) => {
2746
- if (startPromise !== void 0) return startPromise;
2747
- startPromise = (async () => {
2748
- if (prefix === "") {
2749
- const config = await loadAdepConfigModule(cwd);
2750
- prefix = normalizeFunctionPrefix(config?.functions_prefix);
2751
- if (prefix === "") {
2752
- log("[adep] adep.config.ts \u672A\u914D\u7F6E functions_prefix\uFF0C\u4E91\u51FD\u6570\u4EE3\u7406\u524D\u7F00\u9ED8\u8BA4 /api");
2753
- prefix = "api";
2754
- }
2755
- }
2756
- prefixPath = `/${prefix}`;
2757
- const targetPort = options.port ?? 8787;
2758
- try {
2759
- dev = await startDevServer({ cwd, port: targetPort, prefix, log });
2760
- } catch (error) {
2761
- if (isAddrInUse(error)) {
2762
- log(`[adep] \u7AEF\u53E3 ${targetPort} \u88AB\u5360\u7528\uFF0C\u6539\u7528\u968F\u673A\u7AEF\u53E3`);
2763
- dev = await startDevServer({ cwd, port: 0, prefix, log });
2764
- } else {
2765
- log(
2766
- `[adep] \u4E91\u51FD\u6570 dev server \u542F\u52A8\u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}\uFF08vite \u524D\u7AEF\u7167\u5E38\uFF0C\u51FD\u6570\u4EE3\u7406\u4E0D\u53EF\u7528\uFF09`
2767
- );
2768
- }
2769
- }
2770
- if (dev !== void 0) {
2771
- log(
2772
- `[adep] \u4E91\u51FD\u6570\u5DF2\u5C31\u7EEA\uFF1A${dev.baseUrl}${prefixPath}/<fn>\uFF08vite \u4EE3\u7406 ${prefixPath}/* \u2192 \u4E91\u51FD\u6570\uFF09`
2773
- );
2774
- }
2775
- })();
2776
- try {
2777
- await startPromise;
2778
- } finally {
2779
- startPromise = void 0;
2780
- }
2781
- };
2782
- const disposeAdepDev = async () => {
2783
- if (dev === void 0) return;
2784
- const target = dev;
2785
- dev = void 0;
2786
- await target.close();
2787
- };
2788
- const attachProxy = (server) => {
2789
- if (dev === void 0 || prefixPath === "") return;
2790
- server.middlewares.use(createAdepProxyMiddleware(prefixPath, dev.baseUrl));
2791
- };
2792
- return {
2793
- name: "adep-cloud-functions",
2794
- async configureServer(server) {
2795
- const log = (line) => server.config.logger.info(line);
2796
- await startAdepDev(log);
2797
- attachProxy(server);
2798
- server.httpServer?.on("close", () => {
2799
- void disposeAdepDev();
2800
- });
2801
- },
2802
- async configurePreviewServer(server) {
2803
- const log = (line) => server.config.logger.info(line);
2804
- await startAdepDev(log);
2805
- attachProxy(server);
2806
- },
2807
- async closeBundle() {
2808
- await disposeAdepDev();
2809
- }
2810
- };
4064
+ return adepPlugin({ ...options, createDevServer, loadConfig: loadConfig2 });
2811
4065
  }
2812
4066
  var vite_default = adepVitePlugin;
2813
4067
  export {
4068
+ FN_FETCH_INTERCEPTOR_SCRIPT,
2814
4069
  adepVitePlugin,
4070
+ createAdepFnProxyScriptMiddleware,
2815
4071
  createAdepProxyMiddleware,
2816
4072
  vite_default as default,
4073
+ injectFnProxyScriptTag,
4074
+ isAddrInUse,
2817
4075
  normalizeFunctionPrefix
2818
4076
  };