@vesk/vesk-cli 0.2.15 → 0.2.16

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.
Files changed (2) hide show
  1. package/dist/cli.js +1031 -634
  2. package/package.json +5 -5
package/dist/cli.js CHANGED
@@ -1525,6 +1525,38 @@ var init_context = __esm({
1525
1525
  }
1526
1526
  });
1527
1527
 
1528
+ // ../runtime/src/server-events.ts
1529
+ function getStore() {
1530
+ const g2 = globalThis;
1531
+ if (!g2.__vesk_server_ctx || typeof g2.__vesk_server_ctx !== "object") {
1532
+ g2.__vesk_server_ctx = {};
1533
+ }
1534
+ return g2.__vesk_server_ctx;
1535
+ }
1536
+ function server_locals() {
1537
+ return getStore();
1538
+ }
1539
+ function get_server_context(key) {
1540
+ return getStore()[key];
1541
+ }
1542
+ function set_server_context(key, value) {
1543
+ getStore()[key] = value;
1544
+ }
1545
+ function clear_server_context() {
1546
+ const store = getStore();
1547
+ for (const key of Object.keys(store)) delete store[key];
1548
+ }
1549
+ var serverLocals, getServerContext, setServerContext, clearServerContext;
1550
+ var init_server_events = __esm({
1551
+ "../runtime/src/server-events.ts"() {
1552
+ "use strict";
1553
+ serverLocals = server_locals;
1554
+ getServerContext = get_server_context;
1555
+ setServerContext = set_server_context;
1556
+ clearServerContext = clear_server_context;
1557
+ }
1558
+ });
1559
+
1528
1560
  // ../runtime/src/resource.ts
1529
1561
  function setSsrSink(sink) {
1530
1562
  ssrSink = sink;
@@ -1708,7 +1740,7 @@ async function runFetcher(handle2, timeout) {
1708
1740
  }
1709
1741
  }
1710
1742
  function sleep(ms) {
1711
- return new Promise((resolve38) => setTimeout(resolve38, ms));
1743
+ return new Promise((resolve39) => setTimeout(resolve39, ms));
1712
1744
  }
1713
1745
  function streamText(res, into, onChunk) {
1714
1746
  const decoder = new TextDecoder();
@@ -2117,10 +2149,10 @@ function createHydrateWalker(container, markerList) {
2117
2149
  }
2118
2150
  function hydrateViewport(container, componentFn, props, rootMargin = 500) {
2119
2151
  if (document.readyState !== "complete") {
2120
- return new Promise((resolve38) => {
2152
+ return new Promise((resolve39) => {
2121
2153
  const onLoad = () => {
2122
2154
  window.removeEventListener("load", onLoad);
2123
- resolve38(hydrateViewport(container, componentFn, props, rootMargin));
2155
+ resolve39(hydrateViewport(container, componentFn, props, rootMargin));
2124
2156
  };
2125
2157
  window.addEventListener("load", onLoad);
2126
2158
  });
@@ -2147,7 +2179,7 @@ function hydrateViewport(container, componentFn, props, rootMargin = 500) {
2147
2179
  const viewportWalker = createHydrateWalker(container, viewportMarkers);
2148
2180
  componentFn(props || {}, /* @__PURE__ */ new Map(), viewportWalker);
2149
2181
  if (deferredMarkers.length > 0) {
2150
- return new Promise((resolve38) => {
2182
+ return new Promise((resolve39) => {
2151
2183
  const observer = new IntersectionObserver((entries) => {
2152
2184
  const toHydrate = [];
2153
2185
  for (const entry of entries) {
@@ -2170,7 +2202,7 @@ function hydrateViewport(container, componentFn, props, rootMargin = 500) {
2170
2202
  }
2171
2203
  if (observer._observed === 0) {
2172
2204
  observer.disconnect();
2173
- resolve38();
2205
+ resolve39();
2174
2206
  }
2175
2207
  }, { rootMargin: `${rootMargin}px` });
2176
2208
  observer._observed = deferredMarkers.length;
@@ -3033,12 +3065,12 @@ function ensureChunk(chunkUrl) {
3033
3065
  if (typeof document === "undefined" || typeof document.createElement !== "function") {
3034
3066
  return Promise.resolve();
3035
3067
  }
3036
- return new Promise((resolve38, reject) => {
3068
+ return new Promise((resolve39, reject) => {
3037
3069
  const s = document.createElement("script");
3038
3070
  s.src = chunkUrl;
3039
3071
  s.onload = () => {
3040
3072
  failedChunks.delete(chunkUrl);
3041
- resolve38();
3073
+ resolve39();
3042
3074
  };
3043
3075
  s.onerror = () => {
3044
3076
  loadedChunks.delete(chunkUrl);
@@ -23828,7 +23860,9 @@ __export(index_server_exports, {
23828
23860
  buildRouteTree: () => buildRouteTree,
23829
23861
  clearActions: () => clearActions,
23830
23862
  clearIsrCache: () => clearIsrCache,
23863
+ clearServerContext: () => clearServerContext,
23831
23864
  clearSsrData: () => clearSsrData,
23865
+ clear_server_context: () => clear_server_context,
23832
23866
  componentIsr: () => componentIsr,
23833
23867
  configureLoadingIndicator: () => configureLoadingIndicator,
23834
23868
  cookies: () => cookies,
@@ -23854,6 +23888,8 @@ __export(index_server_exports, {
23854
23888
  getActiveComponent: () => getActiveComponent,
23855
23889
  getLoadingError: () => getLoadingError,
23856
23890
  getLoadingProgress: () => getLoadingProgress,
23891
+ getServerContext: () => getServerContext,
23892
+ get_server_context: () => get_server_context,
23857
23893
  headers: () => headers,
23858
23894
  isFormAction: () => isFormAction,
23859
23895
  isLoadingActive: () => isLoadingActive,
@@ -23889,13 +23925,17 @@ __export(index_server_exports, {
23889
23925
  runHooks: () => runHooks,
23890
23926
  safe_scope: () => safe_scope,
23891
23927
  scope: () => scope,
23928
+ serverLocals: () => serverLocals,
23929
+ server_locals: () => server_locals,
23892
23930
  set: () => set,
23893
23931
  setActiveComponent: () => setActiveComponent,
23932
+ setServerContext: () => setServerContext,
23894
23933
  setSignedCookie: () => setSignedCookie2,
23895
23934
  setSsrData: () => setSsrData,
23896
23935
  setSsrSink: () => setSsrSink,
23897
23936
  set_active_block: () => set_active_block,
23898
23937
  set_active_component: () => set_active_component,
23938
+ set_server_context: () => set_server_context,
23899
23939
  signCookie: () => signCookie2,
23900
23940
  tick: () => tick,
23901
23941
  track: () => track,
@@ -23924,6 +23964,7 @@ var init_index_server = __esm({
23924
23964
  init_ripple_runtime();
23925
23965
  init_ripple_blocks();
23926
23966
  init_context();
23967
+ init_server_events();
23927
23968
  init_resource();
23928
23969
  init_portal();
23929
23970
  init_router();
@@ -24861,7 +24902,7 @@ is not a problem with esbuild. You need to fix your environment instead.
24861
24902
  let latestResultPromise;
24862
24903
  let provideLatestResult;
24863
24904
  if (isContext)
24864
- requestCallbacks["on-end"] = (id, request2) => new Promise((resolve38) => {
24905
+ requestCallbacks["on-end"] = (id, request2) => new Promise((resolve39) => {
24865
24906
  buildResponseToResult(request2, (err, result2, onEndErrors, onEndWarnings) => {
24866
24907
  const response = {
24867
24908
  errors: onEndErrors,
@@ -24871,7 +24912,7 @@ is not a problem with esbuild. You need to fix your environment instead.
24871
24912
  latestResultPromise = void 0;
24872
24913
  provideLatestResult = void 0;
24873
24914
  sendResponse(id, response);
24874
- resolve38();
24915
+ resolve39();
24875
24916
  });
24876
24917
  });
24877
24918
  sendRequest(refs, request, (error, response) => {
@@ -24888,10 +24929,10 @@ is not a problem with esbuild. You need to fix your environment instead.
24888
24929
  let didDispose = false;
24889
24930
  const result2 = {
24890
24931
  rebuild: () => {
24891
- if (!latestResultPromise) latestResultPromise = new Promise((resolve38, reject) => {
24932
+ if (!latestResultPromise) latestResultPromise = new Promise((resolve39, reject) => {
24892
24933
  let settlePromise;
24893
24934
  provideLatestResult = (err, result22) => {
24894
- if (!settlePromise) settlePromise = () => err ? reject(err) : resolve38(result22);
24935
+ if (!settlePromise) settlePromise = () => err ? reject(err) : resolve39(result22);
24895
24936
  };
24896
24937
  const triggerAnotherBuild = () => {
24897
24938
  const request2 = {
@@ -24912,7 +24953,7 @@ is not a problem with esbuild. You need to fix your environment instead.
24912
24953
  });
24913
24954
  return latestResultPromise;
24914
24955
  },
24915
- watch: (options22 = {}) => new Promise((resolve38, reject) => {
24956
+ watch: (options22 = {}) => new Promise((resolve39, reject) => {
24916
24957
  if (!streamIn.hasFS) throw new Error(`Cannot use the "watch" API in this environment`);
24917
24958
  const keys = {};
24918
24959
  const delay = getFlag(options22, keys, "delay", mustBeInteger);
@@ -24924,10 +24965,10 @@ is not a problem with esbuild. You need to fix your environment instead.
24924
24965
  if (delay) request2.delay = delay;
24925
24966
  sendRequest(refs, request2, (error2) => {
24926
24967
  if (error2) reject(new Error(error2));
24927
- else resolve38(void 0);
24968
+ else resolve39(void 0);
24928
24969
  });
24929
24970
  }),
24930
- serve: (options22 = {}) => new Promise((resolve38, reject) => {
24971
+ serve: (options22 = {}) => new Promise((resolve39, reject) => {
24931
24972
  if (!streamIn.hasFS) throw new Error(`Cannot use the "serve" API in this environment`);
24932
24973
  const keys = {};
24933
24974
  const port2 = getFlag(options22, keys, "port", mustBeValidPortNumber);
@@ -24965,28 +25006,28 @@ is not a problem with esbuild. You need to fix your environment instead.
24965
25006
  sendResponse(id, {});
24966
25007
  };
24967
25008
  }
24968
- resolve38(response2);
25009
+ resolve39(response2);
24969
25010
  });
24970
25011
  }),
24971
- cancel: () => new Promise((resolve38) => {
24972
- if (didDispose) return resolve38();
25012
+ cancel: () => new Promise((resolve39) => {
25013
+ if (didDispose) return resolve39();
24973
25014
  const request2 = {
24974
25015
  command: "cancel",
24975
25016
  key: buildKey
24976
25017
  };
24977
25018
  sendRequest(refs, request2, () => {
24978
- resolve38();
25019
+ resolve39();
24979
25020
  });
24980
25021
  }),
24981
- dispose: () => new Promise((resolve38) => {
24982
- if (didDispose) return resolve38();
25022
+ dispose: () => new Promise((resolve39) => {
25023
+ if (didDispose) return resolve39();
24983
25024
  didDispose = true;
24984
25025
  const request2 = {
24985
25026
  command: "dispose",
24986
25027
  key: buildKey
24987
25028
  };
24988
25029
  sendRequest(refs, request2, () => {
24989
- resolve38();
25030
+ resolve39();
24990
25031
  scheduleOnDisposeCallbacks();
24991
25032
  refs.unref();
24992
25033
  });
@@ -25025,7 +25066,7 @@ is not a problem with esbuild. You need to fix your environment instead.
25025
25066
  onLoad: []
25026
25067
  };
25027
25068
  i++;
25028
- let resolve38 = (path3, options2 = {}) => {
25069
+ let resolve39 = (path3, options2 = {}) => {
25029
25070
  if (!isSetupDone) throw new Error('Cannot call "resolve" before plugin setup has completed');
25030
25071
  if (typeof path3 !== "string") throw new Error(`The path to resolve must be a string`);
25031
25072
  let keys2 = /* @__PURE__ */ Object.create(null);
@@ -25069,7 +25110,7 @@ is not a problem with esbuild. You need to fix your environment instead.
25069
25110
  };
25070
25111
  let promise = setup({
25071
25112
  initialOptions,
25072
- resolve: resolve38,
25113
+ resolve: resolve39,
25073
25114
  onStart(callback) {
25074
25115
  let registeredText = `This error came from the "onStart" callback registered here:`;
25075
25116
  let registeredNote = extractCallerV8(new Error(registeredText), streamIn, "onStart");
@@ -25762,46 +25803,46 @@ More information: The file containing the code for esbuild's JavaScript API (${_
25762
25803
  }
25763
25804
  };
25764
25805
  longLivedService = {
25765
- build: (options2) => new Promise((resolve38, reject) => {
25806
+ build: (options2) => new Promise((resolve39, reject) => {
25766
25807
  service.buildOrContext({
25767
25808
  callName: "build",
25768
25809
  refs,
25769
25810
  options: options2,
25770
25811
  isTTY: isTTY(),
25771
25812
  defaultWD,
25772
- callback: (err, res) => err ? reject(err) : resolve38(res)
25813
+ callback: (err, res) => err ? reject(err) : resolve39(res)
25773
25814
  });
25774
25815
  }),
25775
- context: (options2) => new Promise((resolve38, reject) => service.buildOrContext({
25816
+ context: (options2) => new Promise((resolve39, reject) => service.buildOrContext({
25776
25817
  callName: "context",
25777
25818
  refs,
25778
25819
  options: options2,
25779
25820
  isTTY: isTTY(),
25780
25821
  defaultWD,
25781
- callback: (err, res) => err ? reject(err) : resolve38(res)
25822
+ callback: (err, res) => err ? reject(err) : resolve39(res)
25782
25823
  })),
25783
- transform: (input, options2) => new Promise((resolve38, reject) => service.transform({
25824
+ transform: (input, options2) => new Promise((resolve39, reject) => service.transform({
25784
25825
  callName: "transform",
25785
25826
  refs,
25786
25827
  input,
25787
25828
  options: options2 || {},
25788
25829
  isTTY: isTTY(),
25789
25830
  fs: fsAsync,
25790
- callback: (err, res) => err ? reject(err) : resolve38(res)
25831
+ callback: (err, res) => err ? reject(err) : resolve39(res)
25791
25832
  })),
25792
- formatMessages: (messages, options2) => new Promise((resolve38, reject) => service.formatMessages({
25833
+ formatMessages: (messages, options2) => new Promise((resolve39, reject) => service.formatMessages({
25793
25834
  callName: "formatMessages",
25794
25835
  refs,
25795
25836
  messages,
25796
25837
  options: options2,
25797
- callback: (err, res) => err ? reject(err) : resolve38(res)
25838
+ callback: (err, res) => err ? reject(err) : resolve39(res)
25798
25839
  })),
25799
- analyzeMetafile: (metafile, options2) => new Promise((resolve38, reject) => service.analyzeMetafile({
25840
+ analyzeMetafile: (metafile, options2) => new Promise((resolve39, reject) => service.analyzeMetafile({
25800
25841
  callName: "analyzeMetafile",
25801
25842
  refs,
25802
25843
  metafile: typeof metafile === "string" ? metafile : JSON.stringify(metafile),
25803
25844
  options: options2,
25804
- callback: (err, res) => err ? reject(err) : resolve38(res)
25845
+ callback: (err, res) => err ? reject(err) : resolve39(res)
25805
25846
  }))
25806
25847
  };
25807
25848
  return longLivedService;
@@ -25879,13 +25920,13 @@ error: ${text}`);
25879
25920
  worker.postMessage(msg);
25880
25921
  let status = Atomics.wait(sharedBufferView, 0, 0);
25881
25922
  if (status !== "ok" && status !== "not-equal") throw new Error("Internal error: Atomics.wait() failed: " + status);
25882
- let { message: { id: id2, resolve: resolve38, reject, properties } } = worker_threads2.receiveMessageOnPort(mainPort);
25923
+ let { message: { id: id2, resolve: resolve39, reject, properties } } = worker_threads2.receiveMessageOnPort(mainPort);
25883
25924
  if (id !== id2) throw new Error(`Internal error: Expected id ${id} but got id ${id2}`);
25884
25925
  if (reject) {
25885
25926
  applyProperties(reject, properties);
25886
25927
  throw reject;
25887
25928
  }
25888
- return resolve38;
25929
+ return resolve39;
25889
25930
  };
25890
25931
  worker.unref();
25891
25932
  return {
@@ -28810,17 +28851,17 @@ var init_server_render = __esm({
28810
28851
  });
28811
28852
 
28812
28853
  // ../adapter/src/paths.ts
28813
- import { resolve as resolve10, sep as sep2 } from "node:path";
28814
- import { existsSync as existsSync9, statSync as statSync4, readFileSync as readFileSync10 } from "node:fs";
28854
+ import { resolve as resolve11, sep as sep2 } from "node:path";
28855
+ import { existsSync as existsSync10, statSync as statSync4, readFileSync as readFileSync10 } from "node:fs";
28815
28856
  function resolveWithin(baseDir, relPath) {
28816
- const base = resolve10(baseDir);
28817
- const target = resolve10(baseDir, relPath);
28857
+ const base = resolve11(baseDir);
28858
+ const target = resolve11(baseDir, relPath);
28818
28859
  const prefix = base + sep2;
28819
28860
  if (!target.startsWith(prefix)) return null;
28820
28861
  return target;
28821
28862
  }
28822
28863
  function installMdReadHook(publicDirs) {
28823
- const dirs = publicDirs.map((d) => resolve10(d));
28864
+ const dirs = publicDirs.map((d) => resolve11(d));
28824
28865
  globalThis.__vsk_md_read_file = (p) => {
28825
28866
  for (const dir of dirs) {
28826
28867
  try {
@@ -28830,7 +28871,7 @@ function installMdReadHook(publicDirs) {
28830
28871
  if (!abs) continue;
28831
28872
  const lower = abs.toLowerCase();
28832
28873
  if (!lower.endsWith(".md") && !lower.endsWith(".markdown")) continue;
28833
- if (existsSync9(abs) && statSync4(abs).isFile()) return readFileSync10(abs, "utf8");
28874
+ if (existsSync10(abs) && statSync4(abs).isFile()) return readFileSync10(abs, "utf8");
28834
28875
  } catch {
28835
28876
  }
28836
28877
  }
@@ -28864,12 +28905,12 @@ __export(plugins_exports, {
28864
28905
  });
28865
28906
  import {
28866
28907
  readFileSync as readFileSync13,
28867
- writeFileSync as writeFileSync4,
28868
- existsSync as existsSync12,
28869
- mkdirSync as mkdirSync2,
28908
+ writeFileSync as writeFileSync5,
28909
+ existsSync as existsSync13,
28910
+ mkdirSync as mkdirSync3,
28870
28911
  statSync as statSync7
28871
28912
  } from "node:fs";
28872
- import { resolve as resolve13, dirname as dirname8, join as join7, extname as extname4, basename } from "node:path";
28913
+ import { resolve as resolve14, dirname as dirname8, join as join8, extname as extname4, basename } from "node:path";
28873
28914
  import { createRequire as createRequire3 } from "node:module";
28874
28915
  import { spawn } from "node:child_process";
28875
28916
  function defaultState() {
@@ -28879,11 +28920,11 @@ function eqIgnoreCase(a, b) {
28879
28920
  return String(a || "").toLowerCase() === String(b || "").toLowerCase();
28880
28921
  }
28881
28922
  function stateFilePath(veskDir) {
28882
- return resolve13(veskDir, PLUGIN_STATE_FILENAME);
28923
+ return resolve14(veskDir, PLUGIN_STATE_FILENAME);
28883
28924
  }
28884
28925
  function readPluginState(veskDir) {
28885
28926
  const file = stateFilePath(veskDir);
28886
- if (!existsSync12(file)) return defaultState();
28927
+ if (!existsSync13(file)) return defaultState();
28887
28928
  let raw2;
28888
28929
  try {
28889
28930
  raw2 = JSON.parse(readFileSync13(file, "utf-8"));
@@ -28904,11 +28945,11 @@ function readPluginState(veskDir) {
28904
28945
  function writePluginState(veskDir, state) {
28905
28946
  const file = stateFilePath(veskDir);
28906
28947
  const dir = dirname8(file);
28907
- if (!existsSync12(dir)) mkdirSync2(dir, { recursive: true });
28908
- writeFileSync4(file, JSON.stringify(state, null, 2) + "\n", "utf-8");
28948
+ if (!existsSync13(dir)) mkdirSync3(dir, { recursive: true });
28949
+ writeFileSync5(file, JSON.stringify(state, null, 2) + "\n", "utf-8");
28909
28950
  }
28910
28951
  function resolvePackage(appDir, pkg) {
28911
- const require3 = createRequire3(resolve13(appDir, "package.json"));
28952
+ const require3 = createRequire3(resolve14(appDir, "package.json"));
28912
28953
  let entryPath = null;
28913
28954
  let pkgJsonPath = null;
28914
28955
  let pkgJson = null;
@@ -28921,8 +28962,8 @@ function resolvePackage(appDir, pkg) {
28921
28962
  const seen = /* @__PURE__ */ new Set();
28922
28963
  while (cur && cur !== dirname8(cur) && !seen.has(cur)) {
28923
28964
  seen.add(cur);
28924
- const candidate = join7(cur, "package.json");
28925
- if (existsSync12(candidate)) {
28965
+ const candidate = join8(cur, "package.json");
28966
+ if (existsSync13(candidate)) {
28926
28967
  pkgJsonPath = candidate;
28927
28968
  break;
28928
28969
  }
@@ -28933,15 +28974,15 @@ function resolvePackage(appDir, pkg) {
28933
28974
  } catch {
28934
28975
  }
28935
28976
  }
28936
- if (pkgJsonPath && existsSync12(pkgJsonPath)) {
28977
+ if (pkgJsonPath && existsSync13(pkgJsonPath)) {
28937
28978
  pkgJson = readJsonFile(pkgJsonPath);
28938
28979
  const main = pkgJson?.main || pkgJson?.module || "index.js";
28939
- entryPath = resolve13(dirname8(pkgJsonPath), main);
28980
+ entryPath = resolve14(dirname8(pkgJsonPath), main);
28940
28981
  }
28941
28982
  let localPath = localDir(appDir, pkg);
28942
28983
  if (!localPath) {
28943
28984
  for (const sub of ["src/plugins", "plugins", "lib/plugins"]) {
28944
- const candidate = localDir(resolve13(appDir, sub), pkg);
28985
+ const candidate = localDir(resolve14(appDir, sub), pkg);
28945
28986
  if (candidate) {
28946
28987
  localPath = candidate;
28947
28988
  break;
@@ -28949,30 +28990,30 @@ function resolvePackage(appDir, pkg) {
28949
28990
  }
28950
28991
  }
28951
28992
  if (localPath) {
28952
- const localJson = join7(localPath, "package.json");
28993
+ const localJson = join8(localPath, "package.json");
28953
28994
  let json = null;
28954
- if (existsSync12(localJson)) {
28995
+ if (existsSync13(localJson)) {
28955
28996
  json = readJsonFile(localJson);
28956
28997
  }
28957
28998
  return { installed: true, path: localPath, dir: localPath, packageJson: json ?? pkgJson };
28958
28999
  }
28959
- const installed2 = !!pkgJsonPath && existsSync12(pkgJsonPath);
29000
+ const installed2 = !!pkgJsonPath && existsSync13(pkgJsonPath);
28960
29001
  return { installed: installed2, path: entryPath, dir: installed2 ? dirname8(pkgJsonPath) : null, packageJson: pkgJson };
28961
29002
  }
28962
29003
  function localDir(base, pkg) {
28963
29004
  if (pkg.startsWith("@")) {
28964
29005
  const parts = pkg.split("/");
28965
- const p2 = resolve13(base, parts[0], parts[1] ?? "");
28966
- if (existsSync12(p2)) return p2;
29006
+ const p2 = resolve14(base, parts[0], parts[1] ?? "");
29007
+ if (existsSync13(p2)) return p2;
28967
29008
  return null;
28968
29009
  }
28969
- const p = resolve13(base, pkg);
28970
- if (existsSync12(p)) return p;
29010
+ const p = resolve14(base, pkg);
29011
+ if (existsSync13(p)) return p;
28971
29012
  return null;
28972
29013
  }
28973
29014
  function readJsonFile(file) {
28974
29015
  try {
28975
- if (existsSync12(file)) return JSON.parse(readFileSync13(file, "utf-8"));
29016
+ if (existsSync13(file)) return JSON.parse(readFileSync13(file, "utf-8"));
28976
29017
  } catch {
28977
29018
  }
28978
29019
  return null;
@@ -29012,7 +29053,7 @@ function repositoryToString(r) {
29012
29053
  function assemblePluginMeta(probe) {
29013
29054
  const pkgJson = probe.packageJson || {};
29014
29055
  const dir = probe.dir;
29015
- const meta = dir ? readJsonFile(resolve13(dir, "vesk.meta.json")) : null;
29056
+ const meta = dir ? readJsonFile(resolve14(dir, "vesk.meta.json")) : null;
29016
29057
  const hasMeta = !!meta && Object.keys(meta).length > 0;
29017
29058
  const m = meta || {};
29018
29059
  const metaSource = hasMeta ? "vesk.meta.json" : probe.packageJson ? "package.json" : "none";
@@ -29251,11 +29292,11 @@ function findIconFile(dir, meta) {
29251
29292
  const explicit = str(meta?.icon);
29252
29293
  if (explicit) {
29253
29294
  const p = resolveWithin(dir, explicit);
29254
- if (p && existsSync12(p) && statSync7(p).isFile()) return p;
29295
+ if (p && existsSync13(p) && statSync7(p).isFile()) return p;
29255
29296
  }
29256
29297
  for (const name of ["icon.png", "icon.ico"]) {
29257
- const p = resolve13(dir, name);
29258
- if (existsSync12(p) && statSync7(p).isFile()) return p;
29298
+ const p = resolve14(dir, name);
29299
+ if (existsSync13(p) && statSync7(p).isFile()) return p;
29259
29300
  }
29260
29301
  return null;
29261
29302
  }
@@ -29263,7 +29304,7 @@ function findPluginIcon(appDir, name) {
29263
29304
  const probe = resolvePackage(appDir, name);
29264
29305
  const dir = probe.dir;
29265
29306
  if (!dir) return null;
29266
- const meta = readJsonFile(resolve13(dir, "vesk.meta.json"));
29307
+ const meta = readJsonFile(resolve14(dir, "vesk.meta.json"));
29267
29308
  const iconPath = findIconFile(dir, meta);
29268
29309
  if (!iconPath) return null;
29269
29310
  const ext = extname4(iconPath).toLowerCase();
@@ -29326,7 +29367,7 @@ function resolveDtsPath(probe, pkgJson) {
29326
29367
  for (const rel of candidates) {
29327
29368
  if (!rel) continue;
29328
29369
  const abs = resolveWithin(dir, rel);
29329
- if (abs && existsSync12(abs) && statSync7(abs).isFile()) return abs;
29370
+ if (abs && existsSync13(abs) && statSync7(abs).isFile()) return abs;
29330
29371
  }
29331
29372
  return null;
29332
29373
  }
@@ -29783,19 +29824,19 @@ __export(static_exports, {
29783
29824
  generateSitemap: () => generateSitemap,
29784
29825
  generateSsgRoutes: () => generateSsgRoutes
29785
29826
  });
29786
- import { mkdirSync as mkdirSync3, copyFileSync as copyFileSync2, readdirSync as readdirSync3, statSync as statSync8, existsSync as existsSync13, writeFileSync as writeFileSync5, readFileSync as readFileSync14 } from "node:fs";
29787
- import { resolve as resolve14, join as join8 } from "node:path";
29827
+ import { mkdirSync as mkdirSync4, copyFileSync as copyFileSync2, readdirSync as readdirSync3, statSync as statSync8, existsSync as existsSync14, writeFileSync as writeFileSync6, readFileSync as readFileSync14 } from "node:fs";
29828
+ import { resolve as resolve15, join as join9 } from "node:path";
29788
29829
  function copyStaticAssets2(publicDir, outDir2) {
29789
- const targetDir = resolve14(outDir2, "static", "public");
29790
- mkdirSync3(targetDir, { recursive: true });
29791
- if (!existsSync13(publicDir))
29830
+ const targetDir = resolve15(outDir2, "static", "public");
29831
+ mkdirSync4(targetDir, { recursive: true });
29832
+ if (!existsSync14(publicDir))
29792
29833
  return;
29793
29834
  function copyDir(src2, dest) {
29794
- mkdirSync3(dest, { recursive: true });
29835
+ mkdirSync4(dest, { recursive: true });
29795
29836
  const entries = readdirSync3(src2);
29796
29837
  for (const entry of entries) {
29797
- const srcPath = join8(src2, entry);
29798
- const destPath = join8(dest, entry);
29838
+ const srcPath = join9(src2, entry);
29839
+ const destPath = join9(dest, entry);
29799
29840
  const st = statSync8(srcPath);
29800
29841
  if (st.isDirectory()) {
29801
29842
  copyDir(srcPath, destPath);
@@ -29808,8 +29849,8 @@ function copyStaticAssets2(publicDir, outDir2) {
29808
29849
  }
29809
29850
  async function generateSsgRoutes(routeTree, appDir, outDir2, plugins, headExtra, cssUrls) {
29810
29851
  const { ssg: ssg2 } = await Promise.resolve().then(() => (init_server_render(), server_render_exports));
29811
- const prerenderDir = resolve14(outDir2, "prerendered");
29812
- mkdirSync3(prerenderDir, { recursive: true });
29852
+ const prerenderDir = resolve15(outDir2, "prerendered");
29853
+ mkdirSync4(prerenderDir, { recursive: true });
29813
29854
  const ssgOptions = { plugins, headExtra, cssUrls };
29814
29855
  const results = [];
29815
29856
  async function evaluateExport(src2, exportName) {
@@ -29828,7 +29869,7 @@ async function generateSsgRoutes(routeTree, appDir, outDir2, plugins, headExtra,
29828
29869
  async function walk6(nodes) {
29829
29870
  for (const node of nodes) {
29830
29871
  if (node.page) {
29831
- const pagePath = resolve14(appDir, node.sourceDir, "page.vsk");
29872
+ const pagePath = resolve15(appDir, node.sourceDir, "page.vsk");
29832
29873
  const src2 = readFileSync14(pagePath, "utf-8");
29833
29874
  const hasStaticProps = src2.includes("getStaticProps");
29834
29875
  const hasStaticPaths = src2.includes("getStaticPaths");
@@ -29846,8 +29887,8 @@ async function generateSsgRoutes(routeTree, appDir, outDir2, plugins, headExtra,
29846
29887
  console.error(`vesk: SSG path escaped output dir \u2014 skipping ${pagePath} (path: ${urlPath})`);
29847
29888
  continue;
29848
29889
  }
29849
- mkdirSync3(resolve14(htmlPath, ".."), { recursive: true });
29850
- writeFileSync5(htmlPath, result2.html);
29890
+ mkdirSync4(resolve15(htmlPath, ".."), { recursive: true });
29891
+ writeFileSync6(htmlPath, result2.html);
29851
29892
  results.push({ path: urlPath, html: htmlPath, static: result2.static, params });
29852
29893
  } catch (e) {
29853
29894
  const message = e instanceof Error ? e.message : String(e);
@@ -29858,9 +29899,9 @@ async function generateSsgRoutes(routeTree, appDir, outDir2, plugins, headExtra,
29858
29899
  } else if (hasStaticProps) {
29859
29900
  try {
29860
29901
  const result2 = await ssg2(src2, null, void 0, ssgOptions);
29861
- const htmlPath = resolve14(prerenderDir, node.fullPath === "/" ? "index.html" : `${node.fullPath.slice(1)}.html`);
29862
- mkdirSync3(resolve14(htmlPath, ".."), { recursive: true });
29863
- writeFileSync5(htmlPath, result2.html);
29902
+ const htmlPath = resolve15(prerenderDir, node.fullPath === "/" ? "index.html" : `${node.fullPath.slice(1)}.html`);
29903
+ mkdirSync4(resolve15(htmlPath, ".."), { recursive: true });
29904
+ writeFileSync6(htmlPath, result2.html);
29864
29905
  results.push({ path: node.fullPath, html: htmlPath, static: result2.static });
29865
29906
  } catch (e) {
29866
29907
  const message = e instanceof Error ? e.message : String(e);
@@ -29929,16 +29970,16 @@ var image_pipeline_exports = {};
29929
29970
  __export(image_pipeline_exports, {
29930
29971
  optimizeImages: () => optimizeImages
29931
29972
  });
29932
- import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync6, readFileSync as readFileSync15, existsSync as existsSync14, readdirSync as readdirSync4, statSync as statSync9 } from "node:fs";
29933
- import { resolve as resolve15, extname as extname5, dirname as dirname9 } from "node:path";
29973
+ import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync7, readFileSync as readFileSync15, existsSync as existsSync15, readdirSync as readdirSync4, statSync as statSync9 } from "node:fs";
29974
+ import { resolve as resolve16, extname as extname5, dirname as dirname9 } from "node:path";
29934
29975
  async function processImage(srcPath, outDir2, baseName) {
29935
29976
  const image = sharpFn ? sharpFn(srcPath) : null;
29936
29977
  if (!image) {
29937
29978
  const original = readFileSync15(srcPath);
29938
29979
  for (const w of OUTPUT_WIDTHS) {
29939
- const outputPath = resolve15(outDir2, `${baseName}-${w}w`);
29940
- mkdirSync4(dirname9(outputPath), { recursive: true });
29941
- writeFileSync6(outputPath, original);
29980
+ const outputPath = resolve16(outDir2, `${baseName}-${w}w`);
29981
+ mkdirSync5(dirname9(outputPath), { recursive: true });
29982
+ writeFileSync7(outputPath, original);
29942
29983
  }
29943
29984
  return [];
29944
29985
  }
@@ -29950,12 +29991,12 @@ async function processImage(srcPath, outDir2, baseName) {
29950
29991
  continue;
29951
29992
  const resized = image.clone().resize({ width: w, withoutEnlargement: true });
29952
29993
  const base = `${baseName}-${w}w`;
29953
- const jpgPath = resolve15(outDir2, `${base}${extname5(srcPath)}`);
29954
- mkdirSync4(dirname9(jpgPath), { recursive: true });
29994
+ const jpgPath = resolve16(outDir2, `${base}${extname5(srcPath)}`);
29995
+ mkdirSync5(dirname9(jpgPath), { recursive: true });
29955
29996
  await resized.toFile(jpgPath);
29956
29997
  generated.push(jpgPath);
29957
29998
  for (const fmt of FORMATS) {
29958
- const fmtPath = resolve15(outDir2, `${base}.${fmt}`);
29999
+ const fmtPath = resolve16(outDir2, `${base}.${fmt}`);
29959
30000
  await resized.toFormat(fmt, { quality: 80 }).toFile(fmtPath);
29960
30001
  generated.push(fmtPath);
29961
30002
  }
@@ -29972,7 +30013,7 @@ function collectImageRefs(appDir) {
29972
30013
  return;
29973
30014
  }
29974
30015
  for (const entry of entries) {
29975
- const full = resolve15(dir, entry);
30016
+ const full = resolve16(dir, entry);
29976
30017
  const st = statSync9(full);
29977
30018
  if (st.isDirectory()) {
29978
30019
  if (entry.startsWith("."))
@@ -29992,8 +30033,8 @@ function collectImageRefs(appDir) {
29992
30033
  return refs;
29993
30034
  }
29994
30035
  async function optimizeImages(appDir, outDir2) {
29995
- const imageOutDir = resolve15(outDir2, "static", "images");
29996
- mkdirSync4(imageOutDir, { recursive: true });
30036
+ const imageOutDir = resolve16(outDir2, "static", "images");
30037
+ mkdirSync5(imageOutDir, { recursive: true });
29997
30038
  const refs = collectImageRefs(appDir);
29998
30039
  if (refs.length === 0) {
29999
30040
  console.error("vesk images: no <Image> refs found");
@@ -30002,14 +30043,14 @@ async function optimizeImages(appDir, outDir2) {
30002
30043
  const results = [];
30003
30044
  for (const ref2 of refs) {
30004
30045
  const possiblePaths = [
30005
- resolve15(appDir, ref2.src),
30006
- resolve15(appDir, "..", "public", ref2.src.replace(/^\//, "")),
30007
- resolve15(appDir, "..", "src", ref2.src.replace(/^\//, "")),
30008
- resolve15(outDir2, "static", "public", ref2.src.replace(/^\//, ""))
30046
+ resolve16(appDir, ref2.src),
30047
+ resolve16(appDir, "..", "public", ref2.src.replace(/^\//, "")),
30048
+ resolve16(appDir, "..", "src", ref2.src.replace(/^\//, "")),
30049
+ resolve16(outDir2, "static", "public", ref2.src.replace(/^\//, ""))
30009
30050
  ];
30010
30051
  let srcPath = null;
30011
30052
  for (const p of possiblePaths) {
30012
- if (existsSync14(p)) {
30053
+ if (existsSync15(p)) {
30013
30054
  srcPath = p;
30014
30055
  break;
30015
30056
  }
@@ -30056,8 +30097,8 @@ var seo_audit_exports = {};
30056
30097
  __export(seo_audit_exports, {
30057
30098
  runSeoAudit: () => runSeoAudit
30058
30099
  });
30059
- import { readFileSync as readFileSync16, existsSync as existsSync15, readdirSync as readdirSync5, statSync as statSync10 } from "node:fs";
30060
- import { resolve as resolve16 } from "node:path";
30100
+ import { readFileSync as readFileSync16, existsSync as existsSync16, readdirSync as readdirSync5, statSync as statSync10 } from "node:fs";
30101
+ import { resolve as resolve17 } from "node:path";
30061
30102
  function walkFiles(dir) {
30062
30103
  const results = [];
30063
30104
  let entries;
@@ -30067,7 +30108,7 @@ function walkFiles(dir) {
30067
30108
  return results;
30068
30109
  }
30069
30110
  for (const entry of entries) {
30070
- const full = resolve16(dir, entry);
30111
+ const full = resolve17(dir, entry);
30071
30112
  const st = statSync10(full);
30072
30113
  if (st.isDirectory()) {
30073
30114
  if (!entry.startsWith("."))
@@ -30082,10 +30123,10 @@ function collectCombinedSource(appDir) {
30082
30123
  const pages = files.filter((f) => f.endsWith("/page.vsk") || f.endsWith("\\page.vsk"));
30083
30124
  const combined = [];
30084
30125
  for (const pagePath of pages) {
30085
- const dir = resolve16(pagePath, "..");
30086
- const layoutPath = resolve16(dir, "layout.vsk");
30126
+ const dir = resolve17(pagePath, "..");
30127
+ const layoutPath = resolve17(dir, "layout.vsk");
30087
30128
  const pageSrc = readFileSync16(pagePath, "utf-8");
30088
- const layoutSrc = existsSync15(layoutPath) ? readFileSync16(layoutPath, "utf-8") : "";
30129
+ const layoutSrc = existsSync16(layoutPath) ? readFileSync16(layoutPath, "utf-8") : "";
30089
30130
  const combinedSrc = layoutSrc ? layoutSrc + "\n" + pageSrc : pageSrc;
30090
30131
  combined.push({
30091
30132
  path: pagePath,
@@ -30260,8 +30301,8 @@ var init_platform = __esm({
30260
30301
  });
30261
30302
 
30262
30303
  // ../adapter/src/platform-handler.ts
30263
- import { existsSync as existsSync16 } from "node:fs";
30264
- import { resolve as resolve17, dirname as dirname10 } from "node:path";
30304
+ import { existsSync as existsSync17 } from "node:fs";
30305
+ import { resolve as resolve18, dirname as dirname10 } from "node:path";
30265
30306
  import { fileURLToPath as fileURLToPath4 } from "node:url";
30266
30307
  function routeName2(segments) {
30267
30308
  const parts = segments.filter(Boolean).map((s) => {
@@ -30278,12 +30319,13 @@ function toId(s) {
30278
30319
  return s.replace(/[^a-zA-Z0-9_]/g, "_").replace(/^_/, "");
30279
30320
  }
30280
30321
  function findCompilerSrc2() {
30281
- const monorepo = resolve17(__dirname5, "..", "..", "..", "packages", "compiler", "dist");
30282
- if (existsSync16(monorepo)) return monorepo;
30322
+ const monorepo = resolve18(__dirname5, "..", "..", "..", "packages", "compiler", "dist");
30323
+ if (existsSync17(monorepo)) return monorepo;
30283
30324
  throw new Error('@vesk/compiler/dist not found \u2014 run "npm run build" first');
30284
30325
  }
30285
30326
  function generatePlatformHandlerSource(input) {
30286
30327
  const { ssrRoutes, apiRoutes, prerenderedPaths, hasMiddleware } = input;
30328
+ const hasEvents = !!input.hasEvents;
30287
30329
  let imports = "";
30288
30330
  const routeEntries = [];
30289
30331
  for (const r of ssrRoutes) {
@@ -30306,15 +30348,21 @@ function generatePlatformHandlerSource(input) {
30306
30348
  }
30307
30349
  const mwImport = hasMiddleware ? "import { execute as __executeMw } from './server/middleware.js';" : "";
30308
30350
  const hasMwLiteral = hasMiddleware ? "true" : "false";
30351
+ const eventsImport = hasEvents ? "import { executeStart as __eventsStart, executeRequest as __eventsRequest } from './server/events.js';" : "";
30309
30352
  const prerenderedList = prerenderedPaths.length > 0 ? `const __prerendered = new Set(${JSON.stringify(prerenderedPaths)});
30310
30353
  ` : "const __prerendered = new Set();\n";
30311
30354
  const isrCache = "const __isrCache = new Map();";
30355
+ const serverStoreLine = hasEvents ? "const __serverStore = globalThis.__vesk_server_ctx || {};" : "";
30356
+ const eventsStartLine = hasEvents ? " await __eventsStart({ server: null });" : "";
30357
+ const eventsRequestLine = hasEvents ? " await __eventsRequest(mwCtx);" : "";
30358
+ const localsSeed = hasEvents ? "Object.assign({}, __serverStore)" : "{}";
30312
30359
  const compilerSrc = findCompilerSrc2();
30313
- const parseCookiesImport = hasMiddleware ? `import { parseCookies } from ${JSON.stringify(resolve17(compilerSrc, "server-cookies.js"))};` : "";
30360
+ const parseCookiesImport = hasMiddleware ? `import { parseCookies } from ${JSON.stringify(resolve18(compilerSrc, "server-cookies.js"))};` : "";
30314
30361
  return `
30315
30362
  ${imports}
30316
30363
  ${parseCookiesImport}
30317
30364
  ${mwImport}
30365
+ ${eventsImport}
30318
30366
  ${prerenderedList}
30319
30367
  ${isrCache}
30320
30368
  const __routes = [${routeEntries.join(",\n")}];
@@ -30343,23 +30391,28 @@ export async function handleRequest(request) {
30343
30391
  const url = new URL(request.url);
30344
30392
  const pathname = url.pathname;
30345
30393
  const isDataRequest = request.headers.get('x-vesk-data') === '1';
30394
+ ${serverStoreLine}
30346
30395
 
30347
30396
  if (__prerendered.has(pathname) && !isDataRequest) {
30348
30397
  return new Response(null, { status: 308, headers: { Location: '/_vesk/static/public' + (pathname.endsWith('/') ? pathname + 'index.html' : pathname + '.html') } });
30349
30398
  }
30350
30399
 
30351
- let mwCtx = { params: {}, url, locals: {}, cookies: {}, request, resolveUrl(u) { return new URL(u, request.url).href; }, set() {}, get() { return undefined; } };
30400
+ ${eventsStartLine}
30401
+ let mwCtx = { params: {}, url, locals: ${localsSeed}, cookies: {}, request, resolveUrl(u) { return new URL(u, request.url).href; }, set() {}, get() { return undefined; } };
30352
30402
  if (${hasMwLiteral}) {
30353
30403
  mwCtx = {
30354
30404
  request,
30355
30405
  params: {},
30356
30406
  url,
30357
- locals: {},
30407
+ locals: ${localsSeed},
30358
30408
  cookies: typeof parseCookies !== 'undefined' ? parseCookies(request.headers.get('cookie') || '') : {},
30359
30409
  resolveUrl(u) { return new URL(u, request.url).href; },
30360
30410
  set(key, value) { this.locals[key] = value; },
30361
30411
  get(key) { return this.locals[key]; },
30362
30412
  };
30413
+ }
30414
+ ${eventsRequestLine}
30415
+ if (${hasMwLiteral}) {
30363
30416
  const mwResult = await __executeMw(mwCtx);
30364
30417
  if (mwResult.response) return mwResult.response;
30365
30418
  if (mwResult.rewriteUrl) url.pathname = mwResult.rewriteUrl;
@@ -30497,72 +30550,72 @@ var init_platform_handler = __esm({
30497
30550
 
30498
30551
  // ../adapter/src/platform-output.ts
30499
30552
  import {
30500
- mkdirSync as mkdirSync5,
30553
+ mkdirSync as mkdirSync6,
30501
30554
  copyFileSync as copyFileSync3,
30502
30555
  readdirSync as readdirSync6,
30503
30556
  statSync as statSync11,
30504
- existsSync as existsSync17,
30505
- writeFileSync as writeFileSync7,
30557
+ existsSync as existsSync18,
30558
+ writeFileSync as writeFileSync8,
30506
30559
  rmSync as rmSync2,
30507
30560
  readFileSync as readFileSync17
30508
30561
  } from "node:fs";
30509
- import { resolve as resolve18, join as join9, extname as extname6, dirname as dirname11 } from "node:path";
30562
+ import { resolve as resolve19, join as join10, extname as extname6, dirname as dirname11 } from "node:path";
30510
30563
  function ensureCleanDir(dir) {
30511
30564
  rmSync2(dir, { recursive: true, force: true });
30512
- mkdirSync5(dir, { recursive: true });
30565
+ mkdirSync6(dir, { recursive: true });
30513
30566
  }
30514
30567
  function copyDirContents(srcDir, destDir) {
30515
- if (!existsSync17(srcDir)) return;
30516
- mkdirSync5(destDir, { recursive: true });
30568
+ if (!existsSync18(srcDir)) return;
30569
+ mkdirSync6(destDir, { recursive: true });
30517
30570
  for (const entry of readdirSync6(srcDir)) {
30518
- const srcPath = join9(srcDir, entry);
30519
- const destPath = join9(destDir, entry);
30571
+ const srcPath = join10(srcDir, entry);
30572
+ const destPath = join10(destDir, entry);
30520
30573
  if (statSync11(srcPath).isDirectory()) {
30521
30574
  copyDirContents(srcPath, destPath);
30522
30575
  } else {
30523
- mkdirSync5(dirname11(destPath), { recursive: true });
30576
+ mkdirSync6(dirname11(destPath), { recursive: true });
30524
30577
  copyFileSync3(srcPath, destPath);
30525
30578
  }
30526
30579
  }
30527
30580
  }
30528
30581
  function writeFile(path, content) {
30529
- mkdirSync5(dirname11(path), { recursive: true });
30530
- writeFileSync7(path, content, "utf-8");
30582
+ mkdirSync6(dirname11(path), { recursive: true });
30583
+ writeFileSync8(path, content, "utf-8");
30531
30584
  }
30532
30585
  function writePlatformStatic(buildStaticDir, platformStaticDir) {
30533
- mkdirSync5(platformStaticDir, { recursive: true });
30534
- const publicDir = resolve18(buildStaticDir, "public");
30535
- if (existsSync17(publicDir)) {
30586
+ mkdirSync6(platformStaticDir, { recursive: true });
30587
+ const publicDir = resolve19(buildStaticDir, "public");
30588
+ if (existsSync18(publicDir)) {
30536
30589
  copyDirContents(publicDir, platformStaticDir);
30537
30590
  }
30538
- const assetsDir = resolve18(platformStaticDir, "_vesk", "static");
30591
+ const assetsDir = resolve19(platformStaticDir, "_vesk", "static");
30539
30592
  copyDirContents(buildStaticDir, assetsDir);
30540
- const runtimeAlias = resolve18(platformStaticDir, "_vesk", "runtime.js");
30541
- const clientPath = resolve18(buildStaticDir, "client.js");
30542
- if (existsSync17(clientPath)) {
30543
- mkdirSync5(dirname11(runtimeAlias), { recursive: true });
30593
+ const runtimeAlias = resolve19(platformStaticDir, "_vesk", "runtime.js");
30594
+ const clientPath = resolve19(buildStaticDir, "client.js");
30595
+ if (existsSync18(clientPath)) {
30596
+ mkdirSync6(dirname11(runtimeAlias), { recursive: true });
30544
30597
  copyFileSync3(clientPath, runtimeAlias);
30545
30598
  }
30546
30599
  }
30547
30600
  function writePrerenderedStatic(prerenderedRoutes, platformStaticDir) {
30548
30601
  for (const route of prerenderedRoutes) {
30549
- if (!existsSync17(route.html)) continue;
30602
+ if (!existsSync18(route.html)) continue;
30550
30603
  const content = readFileSync17(route.html);
30551
30604
  const htmlRel = route.path === "/" ? "index.html" : `${route.path.replace(/^\//, "")}.html`;
30552
- const target = resolve18(platformStaticDir, "_vesk", "static", "public", htmlRel);
30605
+ const target = resolve19(platformStaticDir, "_vesk", "static", "public", htmlRel);
30553
30606
  writeFile(target, content);
30554
30607
  if (route.path !== "/" && route.path.endsWith("/")) {
30555
- const dirIndex = resolve18(platformStaticDir, "_vesk", "static", "public", `${route.path.replace(/^\//, "")}index.html`);
30608
+ const dirIndex = resolve19(platformStaticDir, "_vesk", "static", "public", `${route.path.replace(/^\//, "")}index.html`);
30556
30609
  writeFile(dirIndex, content);
30557
30610
  }
30558
30611
  }
30559
30612
  }
30560
30613
  function listStaticDir(dir) {
30561
30614
  const out = [];
30562
- if (!existsSync17(dir)) return out;
30615
+ if (!existsSync18(dir)) return out;
30563
30616
  function walk6(d, prefix) {
30564
30617
  for (const entry of readdirSync6(d)) {
30565
- const full = join9(d, entry);
30618
+ const full = join10(d, entry);
30566
30619
  const rel = prefix ? `${prefix}/${entry}` : entry;
30567
30620
  if (statSync11(full).isDirectory()) {
30568
30621
  walk6(full, rel);
@@ -30614,8 +30667,8 @@ var platform_deploy_exports = {};
30614
30667
  __export(platform_deploy_exports, {
30615
30668
  emitPlatformOutput: () => emitPlatformOutput
30616
30669
  });
30617
- import { writeFileSync as writeFileSync8, mkdirSync as mkdirSync6, rmSync as rmSync3, symlinkSync } from "node:fs";
30618
- import { resolve as resolve19, dirname as dirname12, relative as relative3 } from "node:path";
30670
+ import { writeFileSync as writeFileSync9, mkdirSync as mkdirSync7, rmSync as rmSync3, symlinkSync } from "node:fs";
30671
+ import { resolve as resolve20, dirname as dirname12, relative as relative3 } from "node:path";
30619
30672
  async function emitPlatformOutput(platform, ctx2) {
30620
30673
  if (platform === "node") return null;
30621
30674
  const prerenderedPaths = ctx2.prerenderedRoutes.map((r) => r.path);
@@ -30623,16 +30676,17 @@ async function emitPlatformOutput(platform, ctx2) {
30623
30676
  ssrRoutes: ctx2.ssrRoutes,
30624
30677
  apiRoutes: ctx2.apiRoutes,
30625
30678
  prerenderedPaths,
30626
- hasMiddleware: ctx2.hasMiddleware
30679
+ hasMiddleware: ctx2.hasMiddleware,
30680
+ hasEvents: ctx2.hasEvents
30627
30681
  });
30628
30682
  const shell = shellFor(platform);
30629
- const projectRoot = resolve19(ctx2.outDir, "..");
30630
- const outRoot = resolve19(projectRoot, shell.root);
30683
+ const projectRoot = resolve20(ctx2.outDir, "..");
30684
+ const outRoot = resolve20(projectRoot, shell.root);
30631
30685
  ensureCleanDir(outRoot);
30632
- const staticDir2 = shell.staticSubdir === "" ? outRoot : resolve19(outRoot, shell.staticSubdir || "static");
30633
- writePlatformStatic(resolve19(ctx2.outDir, "static"), staticDir2);
30686
+ const staticDir2 = shell.staticSubdir === "" ? outRoot : resolve20(outRoot, shell.staticSubdir || "static");
30687
+ writePlatformStatic(resolve20(ctx2.outDir, "static"), staticDir2);
30634
30688
  writePrerenderedStatic(ctx2.prerenderedRoutes, staticDir2);
30635
- const entry = resolve19(ctx2.outDir, ".platform-entry.mjs");
30689
+ const entry = resolve20(ctx2.outDir, ".platform-entry.mjs");
30636
30690
  let source = handler;
30637
30691
  if (shell.imports) source = `${shell.imports}
30638
30692
  ${source}`;
@@ -30647,27 +30701,27 @@ ${inlineStaticSource(staticDir2)}`;
30647
30701
  source += `
30648
30702
  ${shell.bootstrap}
30649
30703
  `;
30650
- writeFileSync8(entry, source, "utf-8");
30704
+ writeFileSync9(entry, source, "utf-8");
30651
30705
  let handlerRel;
30652
30706
  if (shell.functionFile) {
30653
- const funcDir = resolve19(outRoot, shell.functionFile.dir);
30654
- mkdirSync6(funcDir, { recursive: true });
30707
+ const funcDir = resolve20(outRoot, shell.functionFile.dir);
30708
+ mkdirSync7(funcDir, { recursive: true });
30655
30709
  if (shell.functionConfig) {
30656
- writeFileSync8(resolve19(funcDir, ".vc-config.json"), JSON.stringify(shell.functionConfig, null, 2), "utf-8");
30710
+ writeFileSync9(resolve20(funcDir, ".vc-config.json"), JSON.stringify(shell.functionConfig, null, 2), "utf-8");
30657
30711
  }
30658
30712
  handlerRel = `${shell.functionFile.dir}/${shell.functionFile.file}`;
30659
- await bundlePlatformHandler({ entry, outfile: resolve19(funcDir, shell.functionFile.file), nodeBuiltins: shell.nodeBuiltins });
30713
+ await bundlePlatformHandler({ entry, outfile: resolve20(funcDir, shell.functionFile.file), nodeBuiltins: shell.nodeBuiltins });
30660
30714
  } else {
30661
30715
  handlerRel = shell.outfile || "index.js";
30662
- await bundlePlatformHandler({ entry, outfile: resolve19(outRoot, handlerRel), nodeBuiltins: shell.nodeBuiltins });
30716
+ await bundlePlatformHandler({ entry, outfile: resolve20(outRoot, handlerRel), nodeBuiltins: shell.nodeBuiltins });
30663
30717
  }
30664
30718
  for (const file of shell.extraFiles || []) {
30665
- writeFileSync8(resolve19(outRoot, file.path), file.content, "utf-8");
30719
+ writeFileSync9(resolve20(outRoot, file.path), file.content, "utf-8");
30666
30720
  }
30667
30721
  if (platform === "vercel") {
30668
- writeFileSync8(resolve19(outRoot, "config.json"), vercelConfigJson(prerenderedPaths), "utf-8");
30722
+ writeFileSync9(resolve20(outRoot, "config.json"), vercelConfigJson(prerenderedPaths), "utf-8");
30669
30723
  }
30670
- writeFileSync8(resolve19(outRoot, "manifest.json"), JSON.stringify({
30724
+ writeFileSync9(resolve20(outRoot, "manifest.json"), JSON.stringify({
30671
30725
  platform,
30672
30726
  runtime: shell.nodeBuiltins ? "node" : "edge",
30673
30727
  static: shell.staticMode,
@@ -30677,9 +30731,9 @@ ${shell.bootstrap}
30677
30731
  prerendered: prerenderedPaths
30678
30732
  }, null, 2), "utf-8");
30679
30733
  if (platform === "vercel") {
30680
- const vercelDir = resolve19(projectRoot, ".vercel");
30681
- mkdirSync6(vercelDir, { recursive: true });
30682
- const linkPath = resolve19(vercelDir, "output");
30734
+ const vercelDir = resolve20(projectRoot, ".vercel");
30735
+ mkdirSync7(vercelDir, { recursive: true });
30736
+ const linkPath = resolve20(vercelDir, "output");
30683
30737
  rmSync3(linkPath, { recursive: true, force: true });
30684
30738
  symlinkSync(relative3(dirname12(linkPath), outRoot), linkPath, "dir");
30685
30739
  }
@@ -34994,7 +35048,7 @@ __export(typecheck_exports, {
34994
35048
  typecheckProject: () => typecheckProject
34995
35049
  });
34996
35050
  import { readFileSync as readFileSync34, readdirSync as readdirSync14, statSync as statSync22 } from "node:fs";
34997
- import { join as join20, dirname as dirname22, normalize, relative as relative7, resolve as resolve36, sep as sep7 } from "node:path";
35051
+ import { join as join22, dirname as dirname22, normalize, relative as relative7, resolve as resolve37, sep as sep7 } from "node:path";
34998
35052
  import * as ts8 from "typescript";
34999
35053
  function walkProjectFiles(projectRoot) {
35000
35054
  const code = [];
@@ -35007,7 +35061,7 @@ function walkProjectFiles(projectRoot) {
35007
35061
  return;
35008
35062
  }
35009
35063
  for (const e of entries) {
35010
- const p = join20(dir, e);
35064
+ const p = join22(dir, e);
35011
35065
  let st;
35012
35066
  try {
35013
35067
  st = statSync22(p);
@@ -35035,8 +35089,8 @@ function walkProjectFiles(projectRoot) {
35035
35089
  return { code, js };
35036
35090
  }
35037
35091
  function isUnder(dir, file) {
35038
- const base = resolve36(dir);
35039
- const abs = resolve36(file);
35092
+ const base = resolve37(dir);
35093
+ const abs = resolve37(file);
35040
35094
  return abs === base || abs.startsWith(base + sep7);
35041
35095
  }
35042
35096
  function structureWarning(rel, message) {
@@ -35062,8 +35116,8 @@ function checkStructureFile(appDir, file) {
35062
35116
  return null;
35063
35117
  }
35064
35118
  function createTypecheckHost(projectRoot, appDir, vskFiles) {
35065
- const ambientPath = join20(appDir, "__vesk_ambient.d.ts");
35066
- const overridePath = join20(appDir, "__vesk_runtime_override.d.ts");
35119
+ const ambientPath = join22(appDir, "__vesk_ambient.d.ts");
35120
+ const overridePath = join22(appDir, "__vesk_runtime_override.d.ts");
35067
35121
  const cached = /* @__PURE__ */ new Map();
35068
35122
  const scriptKindFor = (file) => file.endsWith(".vsk") ? ts8.ScriptKind.TSX : ts8.ScriptKind.TS;
35069
35123
  const host2 = {
@@ -35133,7 +35187,7 @@ function createTypecheckHost(projectRoot, appDir, vskFiles) {
35133
35187
  directoryExists: (dir) => ts8.sys.directoryExists(dir),
35134
35188
  getDirectories: (dir) => {
35135
35189
  try {
35136
- return readdirSync14(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => join20(dir, d.name));
35190
+ return readdirSync14(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => join22(dir, d.name));
35137
35191
  } catch {
35138
35192
  return [];
35139
35193
  }
@@ -35144,7 +35198,7 @@ function createTypecheckHost(projectRoot, appDir, vskFiles) {
35144
35198
  resolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, options2) {
35145
35199
  return moduleLiterals.map(({ text }) => {
35146
35200
  if (text.endsWith(".vsk")) {
35147
- const abs = normalize(join20(dirname22(containingFile), text));
35201
+ const abs = normalize(join22(dirname22(containingFile), text));
35148
35202
  return {
35149
35203
  resolvedModule: {
35150
35204
  resolvedFileName: abs + ".d.ts",
@@ -35155,7 +35209,7 @@ function createTypecheckHost(projectRoot, appDir, vskFiles) {
35155
35209
  };
35156
35210
  }
35157
35211
  if (text.endsWith(".css")) {
35158
- const abs = normalize(join20(dirname22(containingFile), text));
35212
+ const abs = normalize(join22(dirname22(containingFile), text));
35159
35213
  return {
35160
35214
  resolvedModule: {
35161
35215
  resolvedFileName: abs + ".d.ts",
@@ -35173,7 +35227,7 @@ function createTypecheckHost(projectRoot, appDir, vskFiles) {
35173
35227
  return host2;
35174
35228
  }
35175
35229
  function typecheckProject(projectRoot, opts = {}) {
35176
- const appDir = opts.appDir ?? join20(projectRoot, "app");
35230
+ const appDir = opts.appDir ?? join22(projectRoot, "app");
35177
35231
  const vskFiles = /* @__PURE__ */ new Map();
35178
35232
  const parseErrors = [];
35179
35233
  const warnings = [];
@@ -35212,8 +35266,8 @@ function typecheckProject(projectRoot, opts = {}) {
35212
35266
  }
35213
35267
  rootNames.push(f);
35214
35268
  }
35215
- const ambientPath = join20(appDir, "__vesk_ambient.d.ts");
35216
- const overridePath = join20(appDir, "__vesk_runtime_override.d.ts");
35269
+ const ambientPath = join22(appDir, "__vesk_ambient.d.ts");
35270
+ const overridePath = join22(appDir, "__vesk_runtime_override.d.ts");
35217
35271
  rootNames.push(ambientPath);
35218
35272
  rootNames.push(overridePath);
35219
35273
  const options2 = {
@@ -35777,8 +35831,8 @@ declare module '@vesk/runtime' {
35777
35831
  });
35778
35832
 
35779
35833
  // src/index.ts
35780
- import { readFileSync as readFileSync35, writeFileSync as writeFileSync18, mkdirSync as mkdirSync15, existsSync as existsSync36 } from "fs";
35781
- import { resolve as resolve37, join as join21, dirname as dirname23 } from "path";
35834
+ import { readFileSync as readFileSync35, writeFileSync as writeFileSync19, mkdirSync as mkdirSync16, existsSync as existsSync38 } from "fs";
35835
+ import { resolve as resolve38, join as join23, dirname as dirname23 } from "path";
35782
35836
  import { fileURLToPath as fileURLToPath9 } from "url";
35783
35837
 
35784
35838
  // ../compiler/dist/config.js
@@ -35886,9 +35940,9 @@ function validateConfig(config) {
35886
35940
  if (typeof plugin.name !== "string" || !plugin.name) {
35887
35941
  throw new Error("[vesk] A plugin is missing a `name` property. Use a Vesk-native plugin factory (e.g. tailwindcss({...}) from @vesk/plugin-tailwind) that returns a plugin object with the correct shape.");
35888
35942
  }
35889
- const hasKnownHook = typeof plugin.onCSS === "function" || typeof plugin.onFileWatch === "function" || typeof plugin.onTransformJS === "function" || typeof plugin.onBuildStart === "function" || typeof plugin.onBuildEnd === "function" || typeof plugin.onRequest === "function" || typeof plugin.onHead === "function" || typeof plugin.onHtml === "function" || plugin.provides && typeof plugin.provides === "object" && Object.keys(plugin.provides).length > 0;
35943
+ const hasKnownHook = typeof plugin.onCSS === "function" || typeof plugin.onFileWatch === "function" || typeof plugin.onTransformJS === "function" || typeof plugin.onBuildStart === "function" || typeof plugin.onBuildEnd === "function" || typeof plugin.onRequest === "function" || typeof plugin.onStart === "function" || typeof plugin.onStop === "function" || typeof plugin.onHead === "function" || typeof plugin.onHtml === "function" || plugin.provides && typeof plugin.provides === "object" && Object.keys(plugin.provides).length > 0;
35890
35944
  if (!hasKnownHook) {
35891
- throw new Error(`[vesk] Plugin "${plugin.name}" implements none of the recognized hooks (onCSS, onFileWatch, onTransformJS, onBuildStart, onBuildEnd, onRequest, onHead, onHtml) or provides \u2014 it will never be called. Check the plugin package version, or see /docu/cli/plugin-api.md for the current hook contract.`);
35945
+ throw new Error(`[vesk] Plugin "${plugin.name}" implements none of the recognized hooks (onCSS, onFileWatch, onTransformJS, onBuildStart, onBuildEnd, onRequest, onStart, onStop, onHead, onHtml) or provides \u2014 it will never be called. Check the plugin package version, or see /docu/cli/plugin-api.md for the current hook contract.`);
35892
35946
  }
35893
35947
  }
35894
35948
  return config;
@@ -36276,8 +36330,8 @@ function setRuntimeModule2(mod) {
36276
36330
  }
36277
36331
 
36278
36332
  // ../adapter/dist/index.js
36279
- import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync9, existsSync as existsSync18, readFileSync as readFileSync18 } from "node:fs";
36280
- import { resolve as resolve20, dirname as dirname13, relative as relative4, basename as basename2 } from "node:path";
36333
+ import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync10, existsSync as existsSync19, readFileSync as readFileSync18 } from "node:fs";
36334
+ import { resolve as resolve21, dirname as dirname13, relative as relative4, basename as basename2 } from "node:path";
36281
36335
  import { fileURLToPath as fileURLToPath5 } from "node:url";
36282
36336
 
36283
36337
  // ../adapter/src/runtime-bundle.ts
@@ -36393,7 +36447,17 @@ async function bundleRuntime(appDir, outDir2) {
36393
36447
  "export const getAction = __veskRuntime.getAction;",
36394
36448
  "export const clearActions = __veskRuntime.clearActions;",
36395
36449
  "export const validateActionInput = __veskRuntime.validateActionInput;",
36396
- "export const issuesToFieldMap = __veskRuntime.issuesToFieldMap;"
36450
+ "export const issuesToFieldMap = __veskRuntime.issuesToFieldMap;",
36451
+ "",
36452
+ "// Server-wide context store (server events)",
36453
+ "export const serverLocals = __veskRuntime.serverLocals;",
36454
+ "export const getServerContext = __veskRuntime.getServerContext;",
36455
+ "export const setServerContext = __veskRuntime.setServerContext;",
36456
+ "export const clearServerContext = __veskRuntime.clearServerContext;",
36457
+ "export const server_locals = __veskRuntime.server_locals;",
36458
+ "export const get_server_context = __veskRuntime.get_server_context;",
36459
+ "export const set_server_context = __veskRuntime.set_server_context;",
36460
+ "export const clear_server_context = __veskRuntime.clear_server_context;"
36397
36461
  ].join("\n");
36398
36462
  writeFileSync(entryFile, entryContent, "utf-8");
36399
36463
  try {
@@ -37314,13 +37378,117 @@ ${extracted.body}
37314
37378
  return code;
37315
37379
  }
37316
37380
 
37381
+ // ../adapter/src/events.ts
37382
+ init_esbuild_fallback();
37383
+ import { writeFileSync as writeFileSync2, unlinkSync as unlinkSync2, mkdirSync } from "node:fs";
37384
+ import { resolve as resolve9 } from "node:path";
37385
+
37386
+ // ../compiler/src/events.ts
37387
+ import { existsSync as existsSync8 } from "fs";
37388
+ import { join as join5 } from "path";
37389
+ var EVENTS_FILE_NAMES = ["_events.ts", "_events.js"];
37390
+ function collectEventsFile(appDir) {
37391
+ for (const name of EVENTS_FILE_NAMES) {
37392
+ const candidate = join5(appDir, name);
37393
+ if (existsSync8(candidate)) return candidate;
37394
+ }
37395
+ return null;
37396
+ }
37397
+
37398
+ // ../adapter/src/events.ts
37399
+ var buildId2 = 0;
37400
+ function buildEntry(sourcePath2) {
37401
+ return [
37402
+ `import * as __events from ${JSON.stringify(sourcePath2)};`,
37403
+ "",
37404
+ "const __store = () => (globalThis.__vesk_server_ctx ||= {});",
37405
+ "",
37406
+ "const __handlers = {};",
37407
+ "for (const __name of ['onStart', 'onRequest', 'onStop']) {",
37408
+ " const __fn = __events[__name];",
37409
+ " if (typeof __fn === 'function') __handlers[__name] = __fn;",
37410
+ "}",
37411
+ "",
37412
+ "function __makeCtx(base) {",
37413
+ " const store = __store();",
37414
+ " const start = base && typeof base === 'object' ? base : {};",
37415
+ " return Object.assign({}, start, {",
37416
+ " server: start.server !== undefined ? start.server : null,",
37417
+ " port: start.port !== undefined ? start.port : 0,",
37418
+ " host: start.host,",
37419
+ " serverLocals: store,",
37420
+ " set(key, value) { store[key] = value; return value; },",
37421
+ " get(key) { return store[key]; },",
37422
+ " });",
37423
+ "}",
37424
+ "",
37425
+ "export async function executeStart(base) {",
37426
+ " if (globalThis.__vesk_events_started) return;",
37427
+ " globalThis.__vesk_events_started = true;",
37428
+ " if (typeof __handlers.onStart === 'function') await __handlers.onStart(__makeCtx(base));",
37429
+ "}",
37430
+ "",
37431
+ "export async function executeRequest(base) {",
37432
+ " if (typeof __handlers.onRequest !== 'function') return;",
37433
+ " await __handlers.onRequest(__makeCtx(base));",
37434
+ "}",
37435
+ "",
37436
+ "export async function executeStop(base) {",
37437
+ " if (typeof __handlers.onStop !== 'function') return;",
37438
+ " try {",
37439
+ " await __handlers.onStop(__makeCtx(base));",
37440
+ " } finally {",
37441
+ " globalThis.__vesk_events_started = false;",
37442
+ " }",
37443
+ "}",
37444
+ "",
37445
+ "export const onStart = __handlers.onStart;",
37446
+ "export const onRequest = __handlers.onRequest;",
37447
+ "export const onStop = __handlers.onStop;",
37448
+ ""
37449
+ ].join("\n");
37450
+ }
37451
+ async function compileEvents(appDir, outDir2) {
37452
+ const sourcePath2 = collectEventsFile(appDir);
37453
+ if (!sourcePath2) return false;
37454
+ const serverDir = resolve9(outDir2, "server");
37455
+ mkdirSync(serverDir, { recursive: true });
37456
+ const entryFile = resolve9(serverDir, `.events-entry-${buildId2++}.mjs`);
37457
+ writeFileSync2(entryFile, buildEntry(sourcePath2), "utf-8");
37458
+ try {
37459
+ const result2 = await build({
37460
+ entryPoints: [entryFile],
37461
+ bundle: true,
37462
+ platform: "neutral",
37463
+ format: "esm",
37464
+ minify: true,
37465
+ outfile: resolve9(serverDir, "events.js"),
37466
+ external: ["fs", "node:fs", "path", "node:path", "module", "node:module", "node:async_hooks"],
37467
+ target: ["es2022"],
37468
+ treeShaking: true
37469
+ });
37470
+ if (result2.errors.length > 0) {
37471
+ throw new Error(`esbuild errors: ${result2.errors.map((e) => e.text).join(", ")}`);
37472
+ }
37473
+ if (result2.warnings.length > 0) {
37474
+ for (const w of result2.warnings) console.error("vesk build warning:", w.text);
37475
+ }
37476
+ return true;
37477
+ } finally {
37478
+ try {
37479
+ unlinkSync2(entryFile);
37480
+ } catch {
37481
+ }
37482
+ }
37483
+ }
37484
+
37317
37485
  // ../adapter/src/client-bundle.ts
37318
37486
  init_esbuild_fallback();
37319
37487
  init_strip_ts();
37320
37488
  init_parser();
37321
37489
  init_client_codegen();
37322
- import { readFileSync as readFileSync9, existsSync as existsSync8, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2, statSync as statSync3, rmSync } from "node:fs";
37323
- import { resolve as resolve9, join as join5, dirname as dirname6, relative as relative2, sep } from "node:path";
37490
+ import { readFileSync as readFileSync9, existsSync as existsSync9, writeFileSync as writeFileSync3, unlinkSync as unlinkSync3, statSync as statSync3, rmSync } from "node:fs";
37491
+ import { resolve as resolve10, join as join6, dirname as dirname6, relative as relative2, sep } from "node:path";
37324
37492
  import { fileURLToPath as fileURLToPath2 } from "node:url";
37325
37493
  init_vsk_imports();
37326
37494
  init_md_inline();
@@ -37341,15 +37509,15 @@ function buildRouterOpts(options2) {
37341
37509
  return "";
37342
37510
  }
37343
37511
  function findRuntimeSrc2(appDir) {
37344
- const monorepoRoot = resolve9(__dirname3, "..", "..", "..");
37512
+ const monorepoRoot = resolve10(__dirname3, "..", "..", "..");
37345
37513
  const candidates = [
37346
- resolve9(monorepoRoot, "packages", "runtime", "dist"),
37347
- resolve9(appDir, "..", "node_modules", "@vesk/runtime"),
37348
- resolve9(appDir, "node_modules", "@vesk/runtime")
37514
+ resolve10(monorepoRoot, "packages", "runtime", "dist"),
37515
+ resolve10(appDir, "..", "node_modules", "@vesk/runtime"),
37516
+ resolve10(appDir, "node_modules", "@vesk/runtime")
37349
37517
  ];
37350
37518
  for (const base of candidates) {
37351
- for (const dir of [base, join5(base, "dist")]) {
37352
- if (existsSync8(join5(dir, "index-client.js"))) return dir;
37519
+ for (const dir of [base, join6(base, "dist")]) {
37520
+ if (existsSync9(join6(dir, "index-client.js"))) return dir;
37353
37521
  }
37354
37522
  }
37355
37523
  throw new Error('@vesk/runtime/dist not found \u2014 run "npm run build" first');
@@ -37638,32 +37806,32 @@ async function generateClientBundle(routeTree, appDir, componentMap, options2) {
37638
37806
  let walkSplit2 = function(nodes, _chain) {
37639
37807
  for (const node of nodes) {
37640
37808
  const chunkCode = [];
37641
- const pagePath = resolve9(appDir, node.sourceDir, "page.vsk");
37642
- if (node.page && existsSync8(pagePath)) {
37809
+ const pagePath = resolve10(appDir, node.sourceDir, "page.vsk");
37810
+ if (node.page && existsSync9(pagePath)) {
37643
37811
  compileFile2(pagePath, node.page, chunkCode);
37644
37812
  }
37645
- const layoutPath = resolve9(appDir, node.sourceDir, "layout.vsk");
37646
- if (node.layout && existsSync8(layoutPath)) {
37813
+ const layoutPath = resolve10(appDir, node.sourceDir, "layout.vsk");
37814
+ if (node.layout && existsSync9(layoutPath)) {
37647
37815
  compileFile2(layoutPath, node.layout, chunkCode);
37648
37816
  }
37649
- const errorPath = resolve9(appDir, node.sourceDir, "error.vsk");
37650
- if (node.error && existsSync8(errorPath)) {
37817
+ const errorPath = resolve10(appDir, node.sourceDir, "error.vsk");
37818
+ if (node.error && existsSync9(errorPath)) {
37651
37819
  compileFile2(errorPath, node.error, chunkCode);
37652
37820
  }
37653
- const notFoundPath = resolve9(appDir, node.sourceDir, "not-found.vsk");
37654
- if (node.notFound && existsSync8(notFoundPath)) {
37821
+ const notFoundPath = resolve10(appDir, node.sourceDir, "not-found.vsk");
37822
+ if (node.notFound && existsSync9(notFoundPath)) {
37655
37823
  compileFile2(notFoundPath, node.notFound, chunkCode);
37656
37824
  }
37657
- const offlinePath = resolve9(appDir, node.sourceDir, "offline.vsk");
37658
- if (node.offline && existsSync8(offlinePath)) {
37825
+ const offlinePath = resolve10(appDir, node.sourceDir, "offline.vsk");
37826
+ if (node.offline && existsSync9(offlinePath)) {
37659
37827
  compileFile2(offlinePath, node.offline, chunkCode);
37660
37828
  }
37661
- const networkPath = resolve9(appDir, node.sourceDir, "network.vsk");
37662
- if (node.network && existsSync8(networkPath)) {
37829
+ const networkPath = resolve10(appDir, node.sourceDir, "network.vsk");
37830
+ if (node.network && existsSync9(networkPath)) {
37663
37831
  compileFile2(networkPath, node.network, chunkCode);
37664
37832
  }
37665
- const loadingPath = resolve9(appDir, node.sourceDir, "loading.vsk");
37666
- if (node.loading && existsSync8(loadingPath)) {
37833
+ const loadingPath = resolve10(appDir, node.sourceDir, "loading.vsk");
37834
+ if (node.loading && existsSync9(loadingPath)) {
37667
37835
  compileFile2(loadingPath, node.loading, chunkCode);
37668
37836
  }
37669
37837
  if (chunkCode.length > 0) {
@@ -37740,20 +37908,20 @@ ${entry.code}
37740
37908
  }
37741
37909
  }, walkMono2 = function(nodes) {
37742
37910
  for (const node of nodes) {
37743
- const pagePath = resolve9(appDir, node.sourceDir, "page.vsk");
37744
- if (node.page && existsSync8(pagePath)) compileFileMono2(pagePath, node.page);
37745
- const layoutPath = resolve9(appDir, node.sourceDir, "layout.vsk");
37746
- if (node.layout && existsSync8(layoutPath)) compileFileMono2(layoutPath, node.layout);
37747
- const errorPath = resolve9(appDir, node.sourceDir, "error.vsk");
37748
- if (node.error && existsSync8(errorPath)) compileFileMono2(errorPath, node.error);
37749
- const notFoundPath = resolve9(appDir, node.sourceDir, "not-found.vsk");
37750
- if (node.notFound && existsSync8(notFoundPath)) compileFileMono2(notFoundPath, node.notFound);
37751
- const offlinePath = resolve9(appDir, node.sourceDir, "offline.vsk");
37752
- if (node.offline && existsSync8(offlinePath)) compileFileMono2(offlinePath, node.offline);
37753
- const networkPath = resolve9(appDir, node.sourceDir, "network.vsk");
37754
- if (node.network && existsSync8(networkPath)) compileFileMono2(networkPath, node.network);
37755
- const loadingPath = resolve9(appDir, node.sourceDir, "loading.vsk");
37756
- if (node.loading && existsSync8(loadingPath)) compileFileMono2(loadingPath, node.loading);
37911
+ const pagePath = resolve10(appDir, node.sourceDir, "page.vsk");
37912
+ if (node.page && existsSync9(pagePath)) compileFileMono2(pagePath, node.page);
37913
+ const layoutPath = resolve10(appDir, node.sourceDir, "layout.vsk");
37914
+ if (node.layout && existsSync9(layoutPath)) compileFileMono2(layoutPath, node.layout);
37915
+ const errorPath = resolve10(appDir, node.sourceDir, "error.vsk");
37916
+ if (node.error && existsSync9(errorPath)) compileFileMono2(errorPath, node.error);
37917
+ const notFoundPath = resolve10(appDir, node.sourceDir, "not-found.vsk");
37918
+ if (node.notFound && existsSync9(notFoundPath)) compileFileMono2(notFoundPath, node.notFound);
37919
+ const offlinePath = resolve10(appDir, node.sourceDir, "offline.vsk");
37920
+ if (node.offline && existsSync9(offlinePath)) compileFileMono2(offlinePath, node.offline);
37921
+ const networkPath = resolve10(appDir, node.sourceDir, "network.vsk");
37922
+ if (node.network && existsSync9(networkPath)) compileFileMono2(networkPath, node.network);
37923
+ const loadingPath = resolve10(appDir, node.sourceDir, "loading.vsk");
37924
+ if (node.loading && existsSync9(loadingPath)) compileFileMono2(loadingPath, node.loading);
37757
37925
  walkMono2(node.children || []);
37758
37926
  }
37759
37927
  };
@@ -37802,8 +37970,8 @@ function buildRuntimeCode(runtimeDir) {
37802
37970
  ];
37803
37971
  let code = "";
37804
37972
  for (const f of runtimeFiles) {
37805
- const p = join5(runtimeDir, f);
37806
- if (existsSync8(p)) {
37973
+ const p = join6(runtimeDir, f);
37974
+ if (existsSync9(p)) {
37807
37975
  let src2 = readFileSync9(p, "utf-8");
37808
37976
  src2 = stripTypes(src2);
37809
37977
  src2 = src2.replace(/^import\s+[\s\S]*?from\s+['"](?:\.\/.*?|@vesk\/runtime\/src\/.*?)['"];?\n?/gm, "");
@@ -37816,7 +37984,7 @@ ${src2}
37816
37984
  `;
37817
37985
  }
37818
37986
  }
37819
- const indexSrc = readFileSync9(join5(runtimeDir, "index-client.js"), "utf-8");
37987
+ const indexSrc = readFileSync9(join6(runtimeDir, "index-client.js"), "utf-8");
37820
37988
  const exportNames = stripTypes(indexSrc).match(/export\s*\{\s*([^}]+)\s*\}\s*from/g)?.flatMap((m) => m.replace(/export\s*\{\s*|\s*\}\s*from/g, "").split(",").map((s) => s.trim())) || [];
37821
37989
  code += "// --- exports ---\n";
37822
37990
  for (const name of [...new Set(exportNames)]) {
@@ -37826,7 +37994,7 @@ ${src2}
37826
37994
  return code;
37827
37995
  }
37828
37996
  function runtimeExportNames(runtimeDir) {
37829
- const indexSrc = readFileSync9(join5(runtimeDir, "index-client.js"), "utf-8");
37997
+ const indexSrc = readFileSync9(join6(runtimeDir, "index-client.js"), "utf-8");
37830
37998
  const names = /* @__PURE__ */ new Set();
37831
37999
  for (const m of indexSrc.matchAll(/export\s*\{([^}]+)\}\s*from/g)) {
37832
38000
  for (const raw2 of m[1].split(",")) {
@@ -37845,13 +38013,13 @@ async function buildTreeShakenRuntime(runtimeDir, usedNames) {
37845
38013
  console.error(`vesk: runtime names not exported \u2014 ${missing.join(", ")}; falling back to full runtime`);
37846
38014
  return buildRuntimeCode(runtimeDir);
37847
38015
  }
37848
- const entry = join5(runtimeDir, RUNTIME_ENTRY);
38016
+ const entry = join6(runtimeDir, RUNTIME_ENTRY);
37849
38017
  try {
37850
38018
  try {
37851
38019
  rmSync(entry);
37852
38020
  } catch {
37853
38021
  }
37854
- writeFileSync2(entry, `export { ${unique.join(", ")} } from './index-client.js';
38022
+ writeFileSync3(entry, `export { ${unique.join(", ")} } from './index-client.js';
37855
38023
  `);
37856
38024
  const result2 = await build({
37857
38025
  entryPoints: [entry],
@@ -37882,7 +38050,7 @@ export { ${unique.join(", ")} };
37882
38050
  return buildRuntimeCode(runtimeDir);
37883
38051
  } finally {
37884
38052
  try {
37885
- unlinkSync2(entry);
38053
+ unlinkSync3(entry);
37886
38054
  } catch {
37887
38055
  }
37888
38056
  }
@@ -37982,7 +38150,7 @@ if (typeof document !== 'undefined') __router.start();
37982
38150
  }
37983
38151
 
37984
38152
  // ../adapter/src/manifest.ts
37985
- function generateManifest(routes, ssrRoutes, apiRoutes, staticRoutes, middlewareEnabled, actionMap, headExtra) {
38153
+ function generateManifest(routes, ssrRoutes, apiRoutes, staticRoutes, middlewareEnabled, actionMap, headExtra, eventsEnabled = false) {
37986
38154
  const routeEntries = [];
37987
38155
  for (const r of ssrRoutes) {
37988
38156
  const urlParts = r.fullPath.split("/").filter(Boolean);
@@ -38023,24 +38191,25 @@ function generateManifest(routes, ssrRoutes, apiRoutes, staticRoutes, middleware
38023
38191
  dir: "static"
38024
38192
  },
38025
38193
  ...actionEntries.length > 0 ? { actions: actionEntries } : {},
38026
- ...headExtra ? { headExtra } : {}
38194
+ ...headExtra ? { headExtra } : {},
38195
+ ...eventsEnabled ? { events: true } : {}
38027
38196
  };
38028
38197
  }
38029
38198
 
38030
38199
  // ../adapter/src/static.ts
38031
38200
  init_paths();
38032
- import { mkdirSync, copyFileSync, readdirSync as readdirSync2, statSync as statSync5, existsSync as existsSync10, writeFileSync as writeFileSync3, readFileSync as readFileSync11 } from "node:fs";
38033
- import { resolve as resolve11, join as join6 } from "node:path";
38201
+ import { mkdirSync as mkdirSync2, copyFileSync, readdirSync as readdirSync2, statSync as statSync5, existsSync as existsSync11, writeFileSync as writeFileSync4, readFileSync as readFileSync11 } from "node:fs";
38202
+ import { resolve as resolve12, join as join7 } from "node:path";
38034
38203
  function copyStaticAssets(publicDir, outDir2) {
38035
- const targetDir = resolve11(outDir2, "static", "public");
38036
- mkdirSync(targetDir, { recursive: true });
38037
- if (!existsSync10(publicDir)) return;
38204
+ const targetDir = resolve12(outDir2, "static", "public");
38205
+ mkdirSync2(targetDir, { recursive: true });
38206
+ if (!existsSync11(publicDir)) return;
38038
38207
  function copyDir(src2, dest) {
38039
- mkdirSync(dest, { recursive: true });
38208
+ mkdirSync2(dest, { recursive: true });
38040
38209
  const entries = readdirSync2(src2);
38041
38210
  for (const entry of entries) {
38042
- const srcPath = join6(src2, entry);
38043
- const destPath = join6(dest, entry);
38211
+ const srcPath = join7(src2, entry);
38212
+ const destPath = join7(dest, entry);
38044
38213
  const st = statSync5(srcPath);
38045
38214
  if (st.isDirectory()) {
38046
38215
  copyDir(srcPath, destPath);
@@ -38053,8 +38222,8 @@ function copyStaticAssets(publicDir, outDir2) {
38053
38222
  }
38054
38223
 
38055
38224
  // ../adapter/src/prod-server.ts
38056
- import { readFileSync as readFileSync12, existsSync as existsSync11, statSync as statSync6 } from "node:fs";
38057
- import { resolve as resolve12, extname as extname3, dirname as dirname7 } from "node:path";
38225
+ import { readFileSync as readFileSync12, existsSync as existsSync12, statSync as statSync6 } from "node:fs";
38226
+ import { resolve as resolve13, extname as extname3, dirname as dirname7 } from "node:path";
38058
38227
  import { createServer } from "node:http";
38059
38228
  import { createRequire as createRequire2 } from "node:module";
38060
38229
  import { fileURLToPath as fileURLToPath3 } from "node:url";
@@ -38169,10 +38338,10 @@ async function startProdServer(outDir, options) {
38169
38338
  const host = options?.host || "127.0.0.1";
38170
38339
  const maxBodyBytes = options?.maxBodyBytes || DEFAULT_MAX_BODY_BYTES;
38171
38340
  if (!process.env.NODE_ENV) process.env.NODE_ENV = "production";
38172
- const staticDir = resolve12(outDir, "static");
38173
- const configPath = resolve12(outDir, "config.json");
38174
- installMdReadHook([resolve12(staticDir, "public")]);
38175
- if (!existsSync11(configPath)) {
38341
+ const staticDir = resolve13(outDir, "static");
38342
+ const configPath = resolve13(outDir, "config.json");
38343
+ installMdReadHook([resolve13(staticDir, "public")]);
38344
+ if (!existsSync12(configPath)) {
38176
38345
  console.error(`vesk start: no build found at ${outDir}`);
38177
38346
  console.error('Run "vesk build" first');
38178
38347
  process.exit(1);
@@ -38180,16 +38349,16 @@ async function startProdServer(outDir, options) {
38180
38349
  const buildConfig = JSON.parse(readFileSync12(configPath, "utf-8"));
38181
38350
  const bakedHeadExtra = buildConfig.headExtra || "";
38182
38351
  console.error(`vesk start: serving from ${outDir}`);
38183
- const projectDir = resolve12(outDir, "..");
38352
+ const projectDir = resolve13(outDir, "..");
38184
38353
  let securityConfig = {};
38185
38354
  let mdConfig;
38186
38355
  try {
38187
- const veskConfigPath = resolve12(projectDir, "vesk.config.js");
38188
- const veskConfigTsPath = resolve12(projectDir, "vesk.config.ts");
38356
+ const veskConfigPath = resolve13(projectDir, "vesk.config.js");
38357
+ const veskConfigTsPath = resolve13(projectDir, "vesk.config.ts");
38189
38358
  let rawConfig = {};
38190
- if (existsSync11(veskConfigPath)) {
38359
+ if (existsSync12(veskConfigPath)) {
38191
38360
  rawConfig = _require(veskConfigPath);
38192
- } else if (existsSync11(veskConfigTsPath)) {
38361
+ } else if (existsSync12(veskConfigTsPath)) {
38193
38362
  const { transpile } = _require("typescript");
38194
38363
  const src = readFileSync12(veskConfigTsPath, "utf-8");
38195
38364
  const result = transpile(src, { module: 99, target: 99 });
@@ -38220,18 +38389,26 @@ async function startProdServer(outDir, options) {
38220
38389
  } catch {
38221
38390
  }
38222
38391
  let middlewareMod = null;
38223
- const mwPath = resolve12(outDir, "server", "middleware.js");
38224
- if (existsSync11(mwPath)) {
38392
+ const mwPath = resolve13(outDir, "server", "middleware.js");
38393
+ if (existsSync12(mwPath)) {
38225
38394
  try {
38226
38395
  middlewareMod = await import(`${mwPath}?t=${Date.now()}`);
38227
38396
  } catch {
38228
38397
  }
38229
38398
  }
38399
+ let eventsMod = null;
38400
+ const eventsPath = resolve13(outDir, "server", "events.js");
38401
+ if (existsSync12(eventsPath)) {
38402
+ try {
38403
+ eventsMod = await import(`${eventsPath}?t=${Date.now()}`);
38404
+ } catch {
38405
+ }
38406
+ }
38230
38407
  const functionCache = /* @__PURE__ */ new Map();
38231
38408
  async function loadFunction(funcPath) {
38232
38409
  if (functionCache.has(funcPath)) return functionCache.get(funcPath);
38233
- const fullPath = resolve12(outDir, funcPath);
38234
- if (!existsSync11(fullPath)) return null;
38410
+ const fullPath = resolve13(outDir, funcPath);
38411
+ if (!existsSync12(fullPath)) return null;
38235
38412
  try {
38236
38413
  const mod = await import(`${fullPath}?t=${Date.now()}`);
38237
38414
  functionCache.set(funcPath, mod);
@@ -38291,9 +38468,9 @@ async function startProdServer(outDir, options) {
38291
38468
  }
38292
38469
  return origWriteHead(statusCode, headers2);
38293
38470
  });
38294
- const publicDir = resolve12(staticDir, "public");
38471
+ const publicDir = resolve13(staticDir, "public");
38295
38472
  const rootFile = url.pathname.length > 1 ? resolveWithin(publicDir, url.pathname.slice(1)) : null;
38296
- if (rootFile && existsSync11(rootFile) && statSync6(rootFile).isFile()) {
38473
+ if (rootFile && existsSync12(rootFile) && statSync6(rootFile).isFile()) {
38297
38474
  const ext = extname3(rootFile);
38298
38475
  res.writeHead(200, { "Content-Type": MIME[ext] || "application/octet-stream" });
38299
38476
  res.end(readFileSync12(rootFile));
@@ -38312,8 +38489,8 @@ async function startProdServer(outDir, options) {
38312
38489
  return;
38313
38490
  }
38314
38491
  if (url.pathname === "/_vesk/runtime.js") {
38315
- const clientPath = resolve12(staticDir, "client.js");
38316
- if (existsSync11(clientPath)) {
38492
+ const clientPath = resolve13(staticDir, "client.js");
38493
+ if (existsSync12(clientPath)) {
38317
38494
  res.writeHead(200, { "Content-Type": "application/javascript" });
38318
38495
  res.end(readFileSync12(clientPath));
38319
38496
  return;
@@ -38327,7 +38504,7 @@ async function startProdServer(outDir, options) {
38327
38504
  res.end("Forbidden");
38328
38505
  return;
38329
38506
  }
38330
- if (existsSync11(staticPath) && statSync6(staticPath).isFile()) {
38507
+ if (existsSync12(staticPath) && statSync6(staticPath).isFile()) {
38331
38508
  const ext = extname3(staticPath);
38332
38509
  res.writeHead(200, { "Content-Type": MIME[ext] || "application/octet-stream" });
38333
38510
  res.end(readFileSync12(staticPath));
@@ -38337,8 +38514,8 @@ async function startProdServer(outDir, options) {
38337
38514
  if (buildConfig.prerendered) {
38338
38515
  const prerendered = buildConfig.prerendered.find((r) => r.path === url.pathname);
38339
38516
  if (prerendered) {
38340
- const htmlPath = resolve12(outDir, prerendered.file);
38341
- if (existsSync11(htmlPath)) {
38517
+ const htmlPath = resolve13(outDir, prerendered.file);
38518
+ if (existsSync12(htmlPath)) {
38342
38519
  res.writeHead(200, { "Content-Type": "text/html" });
38343
38520
  res.end(readFileSync12(htmlPath));
38344
38521
  return;
@@ -38346,12 +38523,13 @@ async function startProdServer(outDir, options) {
38346
38523
  }
38347
38524
  }
38348
38525
  let mwCtx;
38526
+ const serverStore = globalThis.__vesk_server_ctx;
38349
38527
  if (middlewareMod) {
38350
38528
  mwCtx = {
38351
38529
  request: new Request(url.href, { headers: req.headers, method: req.method || "GET" }),
38352
38530
  params: {},
38353
38531
  url,
38354
- locals: {},
38532
+ locals: Object.assign({}, serverStore || {}),
38355
38533
  cookies: {},
38356
38534
  set(key, value) {
38357
38535
  this.locals[key] = value;
@@ -38360,21 +38538,11 @@ async function startProdServer(outDir, options) {
38360
38538
  return this.locals[key];
38361
38539
  }
38362
38540
  };
38363
- const mwResult = await middlewareMod.execute(mwCtx);
38364
- if (mwResult.response) {
38365
- const body = await mwResult.response.text();
38366
- res.writeHead(mwResult.response.status, Object.fromEntries(mwResult.response.headers));
38367
- res.end(body);
38368
- return;
38369
- }
38370
- if (mwResult.rewriteUrl) {
38371
- url.pathname = mwResult.rewriteUrl;
38372
- }
38373
38541
  } else {
38374
38542
  mwCtx = {
38375
38543
  params: {},
38376
38544
  url,
38377
- locals: {},
38545
+ locals: Object.assign({}, serverStore || {}),
38378
38546
  cookies: {},
38379
38547
  request: null,
38380
38548
  set() {
@@ -38384,6 +38552,25 @@ async function startProdServer(outDir, options) {
38384
38552
  }
38385
38553
  };
38386
38554
  }
38555
+ if (eventsMod) {
38556
+ try {
38557
+ await eventsMod.executeRequest?.(mwCtx);
38558
+ } catch (e) {
38559
+ console.error("vesk request: onRequest error:", e instanceof Error ? e.message : e);
38560
+ }
38561
+ }
38562
+ if (middlewareMod) {
38563
+ const mwResult = await middlewareMod.execute(mwCtx);
38564
+ if (mwResult.response) {
38565
+ const body = await mwResult.response.text();
38566
+ res.writeHead(mwResult.response.status, Object.fromEntries(mwResult.response.headers));
38567
+ res.end(body);
38568
+ return;
38569
+ }
38570
+ if (mwResult.rewriteUrl) {
38571
+ url.pathname = mwResult.rewriteUrl;
38572
+ }
38573
+ }
38387
38574
  globalThis.__vesk_request = mwCtx;
38388
38575
  if (url.pathname.startsWith("/_vesk/action/")) {
38389
38576
  const actionId = url.pathname.replace("/_vesk/action/", "");
@@ -38434,16 +38621,16 @@ async function startProdServer(outDir, options) {
38434
38621
  }
38435
38622
  }
38436
38623
  }
38437
- const appDir = resolve12(projectDir, "app");
38624
+ const appDir = resolve13(projectDir, "app");
38438
38625
  const pageCssUrls = resolveCssUrls({
38439
38626
  tailwind: hasBuiltTailwindCss(outDir),
38440
38627
  userCss: hasUserCss(appDir)
38441
38628
  });
38442
- const nfPath = resolve12(appDir, "not-found.vsk");
38629
+ const nfPath = resolve13(appDir, "not-found.vsk");
38443
38630
  let notFoundHtml = null;
38444
- if (existsSync11(nfPath)) {
38631
+ if (existsSync12(nfPath)) {
38445
38632
  try {
38446
- const runtimePath = resolve12(outDir, "server", "runtime.js");
38633
+ const runtimePath = resolve13(outDir, "server", "runtime.js");
38447
38634
  const { renderFullPage: renderFullPage2, storeDataScriptGlobal } = await import(runtimePath);
38448
38635
  const src2 = readFileSync12(nfPath, "utf-8");
38449
38636
  const compName = resolveComponentName(src2) || "NotFound";
@@ -38503,11 +38690,11 @@ async function startProdServer(outDir, options) {
38503
38690
  return;
38504
38691
  }
38505
38692
  console.error("vesk ssr error:", err.message);
38506
- const errPath = resolve12(appDir, "error.vsk");
38693
+ const errPath = resolve13(appDir, "error.vsk");
38507
38694
  let errorHtml = null;
38508
- if (existsSync11(errPath)) {
38695
+ if (existsSync12(errPath)) {
38509
38696
  try {
38510
- const runtimePath = resolve12(outDir, "server", "runtime.js");
38697
+ const runtimePath = resolve13(outDir, "server", "runtime.js");
38511
38698
  const { renderFullPage: renderFullPage2, storeDataScriptGlobal } = await import(runtimePath);
38512
38699
  const src2 = readFileSync12(errPath, "utf-8");
38513
38700
  const compName = resolveComponentName(src2) || "Error";
@@ -38527,6 +38714,30 @@ async function startProdServer(outDir, options) {
38527
38714
  res.writeHead(404, { "Content-Type": "text/html" });
38528
38715
  res.end(notFoundHtml || "<!DOCTYPE html><html><body><h1>404</h1><p>Not Found</p></body></html>");
38529
38716
  });
38717
+ try {
38718
+ await eventsMod?.executeStart?.({ server, port, host });
38719
+ } catch (e) {
38720
+ console.error("vesk start: onStart error:", e instanceof Error ? e.message : e);
38721
+ }
38722
+ server.on("close", () => {
38723
+ void (async () => {
38724
+ try {
38725
+ await eventsMod?.executeStop?.({ server, port, host });
38726
+ } catch (e) {
38727
+ console.error("vesk stop: onStop error:", e instanceof Error ? e.message : e);
38728
+ }
38729
+ })();
38730
+ });
38731
+ let shuttingDown = false;
38732
+ function shutdown(signal) {
38733
+ if (shuttingDown) return;
38734
+ shuttingDown = true;
38735
+ console.error(`vesk stop: received ${signal}, closing\u2026`);
38736
+ server.close(() => process.exit(0));
38737
+ setTimeout(() => process.exit(0), 3e3).unref();
38738
+ }
38739
+ process.on("SIGINT", () => shutdown("SIGINT"));
38740
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
38530
38741
  server.listen(port, host, () => {
38531
38742
  console.error(`vesk production server at http://localhost:${port} (listening on ${host})`);
38532
38743
  });
@@ -38626,10 +38837,10 @@ function validateConfig2(config) {
38626
38837
  "[vesk] A plugin is missing a `name` property. Use a Vesk-native plugin factory (e.g. tailwindcss({...}) from @vesk/plugin-tailwind) that returns a plugin object with the correct shape."
38627
38838
  );
38628
38839
  }
38629
- const hasKnownHook = typeof plugin.onCSS === "function" || typeof plugin.onFileWatch === "function" || typeof plugin.onTransformJS === "function" || typeof plugin.onBuildStart === "function" || typeof plugin.onBuildEnd === "function" || typeof plugin.onRequest === "function" || typeof plugin.onHead === "function" || typeof plugin.onHtml === "function" || plugin.provides && typeof plugin.provides === "object" && Object.keys(plugin.provides).length > 0;
38840
+ const hasKnownHook = typeof plugin.onCSS === "function" || typeof plugin.onFileWatch === "function" || typeof plugin.onTransformJS === "function" || typeof plugin.onBuildStart === "function" || typeof plugin.onBuildEnd === "function" || typeof plugin.onRequest === "function" || typeof plugin.onStart === "function" || typeof plugin.onStop === "function" || typeof plugin.onHead === "function" || typeof plugin.onHtml === "function" || plugin.provides && typeof plugin.provides === "object" && Object.keys(plugin.provides).length > 0;
38630
38841
  if (!hasKnownHook) {
38631
38842
  throw new Error(
38632
- `[vesk] Plugin "${plugin.name}" implements none of the recognized hooks (onCSS, onFileWatch, onTransformJS, onBuildStart, onBuildEnd, onRequest, onHead, onHtml) or provides \u2014 it will never be called. Check the plugin package version, or see /docu/cli/plugin-api.md for the current hook contract.`
38843
+ `[vesk] Plugin "${plugin.name}" implements none of the recognized hooks (onCSS, onFileWatch, onTransformJS, onBuildStart, onBuildEnd, onRequest, onStart, onStop, onHead, onHtml) or provides \u2014 it will never be called. Check the plugin package version, or see /docu/cli/plugin-api.md for the current hook contract.`
38633
38844
  );
38634
38845
  }
38635
38846
  }
@@ -38645,13 +38856,13 @@ init_paths();
38645
38856
  // ../adapter/dist/index.js
38646
38857
  var __dirname6 = dirname13(fileURLToPath5(import.meta.url));
38647
38858
  async function resolveCompilerApi(name) {
38648
- const monorepoSrc = resolve20(__dirname6, "..", "..", "compiler", "src");
38649
- if (existsSync18(monorepoSrc)) {
38650
- const tsFile = resolve20(monorepoSrc, name.replace(/\.js$/, ".ts"));
38651
- if (existsSync18(tsFile)) {
38859
+ const monorepoSrc = resolve21(__dirname6, "..", "..", "compiler", "src");
38860
+ if (existsSync19(monorepoSrc)) {
38861
+ const tsFile = resolve21(monorepoSrc, name.replace(/\.js$/, ".ts"));
38862
+ if (existsSync19(tsFile)) {
38652
38863
  return import(tsFile);
38653
38864
  }
38654
- return import(resolve20(monorepoSrc, name));
38865
+ return import(resolve21(monorepoSrc, name));
38655
38866
  }
38656
38867
  return import(`@vesk/compiler/src/${name.replace(/\.js$/, "")}`);
38657
38868
  }
@@ -38689,9 +38900,9 @@ async function collectPluginHeadExtra(pluginsPipelines) {
38689
38900
  return parts.join("\n");
38690
38901
  }
38691
38902
  async function build2(appDir, options2) {
38692
- appDir = resolve20(appDir);
38693
- const outDir2 = resolve20(options2?.outDir || resolve20(appDir, "..", ".vesk"));
38694
- const publicDir = options2?.publicDir || resolve20(appDir, "..", "public");
38903
+ appDir = resolve21(appDir);
38904
+ const outDir2 = resolve21(options2?.outDir || resolve21(appDir, "..", ".vesk"));
38905
+ const publicDir = options2?.publicDir || resolve21(appDir, "..", "public");
38695
38906
  const plugins = options2?.plugins || [];
38696
38907
  if (options2?.md) {
38697
38908
  const { configureMd: configureMd3 } = await Promise.resolve().then(() => (init_md(), md_exports));
@@ -38731,24 +38942,24 @@ async function build2(appDir, options2) {
38731
38942
  console.error("vesk build: baked plugin head \u2192 config.json + SSR functions");
38732
38943
  console.error(`vesk build: output \u2192 ${outDir2}`);
38733
38944
  const dirs = [
38734
- resolve20(outDir2, "server", "functions"),
38735
- resolve20(outDir2, "server", "api"),
38736
- resolve20(outDir2, "static", "public"),
38737
- resolve20(outDir2, "prerendered")
38945
+ resolve21(outDir2, "server", "functions"),
38946
+ resolve21(outDir2, "server", "api"),
38947
+ resolve21(outDir2, "static", "public"),
38948
+ resolve21(outDir2, "prerendered")
38738
38949
  ];
38739
38950
  for (const d of dirs)
38740
- mkdirSync7(d, { recursive: true });
38951
+ mkdirSync8(d, { recursive: true });
38741
38952
  const cssSourcePath = resolveUserCssPath(appDir);
38742
38953
  if (cssSourcePath !== null) {
38743
38954
  const cssContent = readFileSync18(cssSourcePath, "utf-8");
38744
38955
  const userCss = stripTailwindDirectives(cssContent);
38745
- const userCssTarget = resolve20(outDir2, "static", "global.css");
38746
- writeFileSync9(userCssTarget, userCss, "utf-8");
38956
+ const userCssTarget = resolve21(outDir2, "static", "global.css");
38957
+ writeFileSync10(userCssTarget, userCss, "utf-8");
38747
38958
  console.error(`vesk build: css \u2192 static/global.css (${userCss.length} bytes)`);
38748
- const twCssTarget = resolve20(outDir2, "static", "_tailwind.css");
38959
+ const twCssTarget = resolve21(outDir2, "static", "_tailwind.css");
38749
38960
  const tailwindActive = isTailwindPlugin(pluginsPipelines);
38750
38961
  if (!tailwindActive) {
38751
- writeFileSync9(twCssTarget, "", "utf-8");
38962
+ writeFileSync10(twCssTarget, "", "utf-8");
38752
38963
  console.error("vesk build: css \u2192 static/_tailwind.css (empty, tailwind plugin inactive)");
38753
38964
  } else {
38754
38965
  let twCss = cssContent;
@@ -38765,14 +38976,14 @@ async function build2(appDir, options2) {
38765
38976
  const lines = twCss.split("\n").filter((l) => !/^\s*@import\s+['"]tailwindcss['"]/.test(l));
38766
38977
  twCss = lines.join("\n").trim();
38767
38978
  if (twCss.length === 0) {
38768
- writeFileSync9(twCssTarget, "", "utf-8");
38979
+ writeFileSync10(twCssTarget, "", "utf-8");
38769
38980
  console.error("vesk build: css \u2192 static/_tailwind.css (empty, tailwind unresolved)");
38770
38981
  } else {
38771
- writeFileSync9(twCssTarget, twCss, "utf-8");
38982
+ writeFileSync10(twCssTarget, twCss, "utf-8");
38772
38983
  console.error(`vesk build: css \u2192 static/_tailwind.css (${twCss.length} bytes, tailwind partially unresolved)`);
38773
38984
  }
38774
38985
  } else {
38775
- writeFileSync9(twCssTarget, twCss, "utf-8");
38986
+ writeFileSync10(twCssTarget, twCss, "utf-8");
38776
38987
  console.error(`vesk build: css \u2192 static/_tailwind.css (${twCss.length} bytes)`);
38777
38988
  }
38778
38989
  }
@@ -38785,14 +38996,14 @@ async function build2(appDir, options2) {
38785
38996
  console.error("vesk build: no routes found in", appDir);
38786
38997
  return;
38787
38998
  }
38788
- const projectRoot = resolve20(appDir, "..");
38789
- const componentsDir = resolve20(projectRoot, "components");
38999
+ const projectRoot = resolve21(appDir, "..");
39000
+ const componentsDir = resolve21(projectRoot, "components");
38790
39001
  const componentMap = scanComponents(componentsDir);
38791
39002
  if (componentMap.size > 0) {
38792
39003
  console.error(`vesk build: ${componentMap.size} external components found in ${componentsDir}`);
38793
39004
  }
38794
- const apiDir = resolve20(appDir, "api");
38795
- const apiTree = existsSync18(apiDir) ? scanApiRoutes2(apiDir) : [];
39005
+ const apiDir = resolve21(appDir, "api");
39006
+ const apiTree = existsSync19(apiDir) ? scanApiRoutes2(apiDir) : [];
38796
39007
  console.error(`vesk build: ${routeTree.length} root routes, ${apiTree.length} API routes`);
38797
39008
  console.error("vesk build: bundling server runtime...");
38798
39009
  await bundleRuntime(appDir, outDir2);
@@ -38809,17 +39020,17 @@ async function build2(appDir, options2) {
38809
39020
  mwCode = compileMiddlewareCode(mwSources);
38810
39021
  }
38811
39022
  const { funcPath, funcCode, name } = generateSsrFunction(node, appDir, outDir2, componentMap, { ancestorLayouts, middlewareCode: mwCode, headExtra: pluginHeadExtra });
38812
- writeFileSync9(funcPath, funcCode, "utf-8");
38813
- const pagePath = resolve20(appDir, node.sourceDir, "page.vsk");
38814
- if (existsSync18(pagePath)) {
39023
+ writeFileSync10(funcPath, funcCode, "utf-8");
39024
+ const pagePath = resolve21(appDir, node.sourceDir, "page.vsk");
39025
+ if (existsSync19(pagePath)) {
38815
39026
  const src2 = readFileSync18(pagePath, "utf-8");
38816
39027
  const actionIds = collectActionIds(src2);
38817
39028
  if (node.layout) {
38818
- const layoutSrc = readFileSync18(resolve20(appDir, node.sourceDir, "layout.vsk"), "utf-8");
39029
+ const layoutSrc = readFileSync18(resolve21(appDir, node.sourceDir, "layout.vsk"), "utf-8");
38819
39030
  actionIds.push(...collectActionIds(layoutSrc));
38820
39031
  }
38821
39032
  for (const a of ancestorLayouts) {
38822
- const ancestorSrc = readFileSync18(resolve20(appDir, a.sourceDir, "layout.vsk"), "utf-8");
39033
+ const ancestorSrc = readFileSync18(resolve21(appDir, a.sourceDir, "layout.vsk"), "utf-8");
38823
39034
  actionIds.push(...collectActionIds(ancestorSrc));
38824
39035
  }
38825
39036
  for (const id of actionIds) {
@@ -38846,7 +39057,7 @@ async function build2(appDir, options2) {
38846
39057
  for (const node of nodes) {
38847
39058
  if (node.filePath) {
38848
39059
  const { funcPath, funcCode, name } = generateApiFunction(node, apiDir, outDir2);
38849
- writeFileSync9(funcPath, funcCode, "utf-8");
39060
+ writeFileSync10(funcPath, funcCode, "utf-8");
38850
39061
  apiRoutes.push(node);
38851
39062
  console.error(`vesk build: api \u2192 server/api/${name}.js (${node.fullPath})`);
38852
39063
  }
@@ -38859,11 +39070,14 @@ async function build2(appDir, options2) {
38859
39070
  if (mwChain.length > 0) {
38860
39071
  const mwCode = compileMiddleware(mwChain, appDir);
38861
39072
  if (mwCode) {
38862
- writeFileSync9(resolve20(outDir2, "server", "middleware.js"), mwCode, "utf-8");
39073
+ writeFileSync10(resolve21(outDir2, "server", "middleware.js"), mwCode, "utf-8");
38863
39074
  middlewareEnabled = true;
38864
39075
  console.error(`vesk build: mw \u2192 server/middleware.js (${mwChain.length} middlewares)`);
38865
39076
  }
38866
39077
  }
39078
+ const hasEvents = await compileEvents(appDir, outDir2);
39079
+ if (hasEvents)
39080
+ console.error("vesk build: evt \u2192 server/events.js (onStart/onRequest/onStop)");
38867
39081
  console.error("vesk build: bundling client runtime...");
38868
39082
  const bundleOpts = {};
38869
39083
  if (options2?.codeSplit)
@@ -38875,13 +39089,13 @@ async function build2(appDir, options2) {
38875
39089
  if (pluginsPipelines.length > 0)
38876
39090
  bundleOpts.plugins = pluginsPipelines;
38877
39091
  const { main, chunks } = await generateClientBundle(routeTree, appDir, componentMap, bundleOpts);
38878
- writeFileSync9(resolve20(outDir2, "static", "client.js"), main, "utf-8");
39092
+ writeFileSync10(resolve21(outDir2, "static", "client.js"), main, "utf-8");
38879
39093
  const mode = chunks.length > 0 ? "code-split" : "monolithic";
38880
39094
  console.error(`vesk build: client \u2192 static/client.js (${main.length} bytes, ${mode})`);
38881
39095
  if (chunks.length > 0) {
38882
- const staticDir2 = resolve20(outDir2, "static");
39096
+ const staticDir2 = resolve21(outDir2, "static");
38883
39097
  for (const chunk of chunks) {
38884
- writeFileSync9(resolve20(staticDir2, chunk.name), chunk.code, "utf-8");
39098
+ writeFileSync10(resolve21(staticDir2, chunk.name), chunk.code, "utf-8");
38885
39099
  console.error(`vesk build: chunk \u2192 static/${chunk.name} (${chunk.code.length} bytes)`);
38886
39100
  }
38887
39101
  }
@@ -38914,23 +39128,23 @@ async function build2(appDir, options2) {
38914
39128
  }
38915
39129
  {
38916
39130
  const { generateSitemap: generateSitemap2, generateRobotsTxt: generateRobotsTxt2 } = await Promise.resolve().then(() => (init_static(), static_exports));
38917
- const publicDirResolved = resolve20(outDir2, "static", "public");
39131
+ const publicDirResolved = resolve21(outDir2, "static", "public");
38918
39132
  const siteUrl = options2?.siteUrl || "http://localhost:3000";
38919
- const sitemapOverride = resolve20(publicDirResolved, "sitemap.xml");
38920
- if (!existsSync18(sitemapOverride)) {
39133
+ const sitemapOverride = resolve21(publicDirResolved, "sitemap.xml");
39134
+ if (!existsSync19(sitemapOverride)) {
38921
39135
  const sitemap = generateSitemap2(routeTree, ssrRoutes, prerenderedRoutes, { siteUrl });
38922
- writeFileSync9(sitemapOverride, sitemap, "utf-8");
39136
+ writeFileSync10(sitemapOverride, sitemap, "utf-8");
38923
39137
  console.error(`vesk build: seo \u2192 static/public/sitemap.xml (${sitemap.length} bytes)`);
38924
39138
  }
38925
- const robotsOverride = resolve20(publicDirResolved, "robots.txt");
38926
- if (!existsSync18(robotsOverride)) {
39139
+ const robotsOverride = resolve21(publicDirResolved, "robots.txt");
39140
+ if (!existsSync19(robotsOverride)) {
38927
39141
  const robots = generateRobotsTxt2(siteUrl);
38928
- writeFileSync9(robotsOverride, robots, "utf-8");
39142
+ writeFileSync10(robotsOverride, robots, "utf-8");
38929
39143
  console.error(`vesk build: seo \u2192 static/public/robots.txt (${robots.length} bytes)`);
38930
39144
  }
38931
39145
  }
38932
- const manifest = generateManifest(routeTree, ssrRoutes, apiRoutes, prerenderedRoutes, middlewareEnabled, actionMap, pluginHeadExtra);
38933
- writeFileSync9(resolve20(outDir2, "config.json"), JSON.stringify(manifest, null, 2) + "\n", "utf-8");
39146
+ const manifest = generateManifest(routeTree, ssrRoutes, apiRoutes, prerenderedRoutes, middlewareEnabled, actionMap, pluginHeadExtra, hasEvents);
39147
+ writeFileSync10(resolve21(outDir2, "config.json"), JSON.stringify(manifest, null, 2) + "\n", "utf-8");
38934
39148
  console.error("vesk build: config \u2192 config.json");
38935
39149
  {
38936
39150
  const { detectPlatform: detectPlatform2 } = await Promise.resolve().then(() => (init_platform(), platform_exports));
@@ -38945,7 +39159,8 @@ async function build2(appDir, options2) {
38945
39159
  apiRoutes,
38946
39160
  prerenderedPaths: prerenderedRoutes.map((r) => r.path),
38947
39161
  prerenderedRoutes,
38948
- hasMiddleware: middlewareEnabled
39162
+ hasMiddleware: middlewareEnabled,
39163
+ hasEvents
38949
39164
  });
38950
39165
  if (outRoot) {
38951
39166
  console.error(`vesk build: ${platform} \u2192 ${relative4(projectRoot, outRoot)}`);
@@ -38969,8 +39184,8 @@ vesk build: done (${outDir2})`);
38969
39184
  init_seo_audit();
38970
39185
 
38971
39186
  // src/dev-server.ts
38972
- import { readFileSync as readFileSync33, watch, statSync as statSync21, existsSync as existsSync35, readdirSync as readdirSync13 } from "node:fs";
38973
- import { resolve as resolve35, extname as extname8, join as join19 } from "node:path";
39187
+ import { readFileSync as readFileSync33, watch, statSync as statSync21, existsSync as existsSync37, readdirSync as readdirSync13 } from "node:fs";
39188
+ import { resolve as resolve36, extname as extname8, join as join21 } from "node:path";
38974
39189
  import { createServer as createServer2 } from "node:http";
38975
39190
  import { WebSocketServer as WebSocketServer2 } from "ws";
38976
39191
 
@@ -40690,8 +40905,8 @@ init_parser();
40690
40905
  init_tokens();
40691
40906
  init_scan();
40692
40907
  init_strip_ts();
40693
- import { readdirSync as readdirSync7, statSync as statSync12, existsSync as existsSync19, readFileSync as readFileSync19 } from "fs";
40694
- import { join as join10, relative as relative5, basename as basename3 } from "path";
40908
+ import { readdirSync as readdirSync7, statSync as statSync12, existsSync as existsSync20, readFileSync as readFileSync19 } from "fs";
40909
+ import { join as join11, relative as relative5, basename as basename3 } from "path";
40695
40910
  function collapseSlashes2(p) {
40696
40911
  let out = "";
40697
40912
  let prevSlash = false;
@@ -40708,7 +40923,7 @@ function collapseSlashes2(p) {
40708
40923
  return out;
40709
40924
  }
40710
40925
  function scanRoutes(appDir, options2 = {}) {
40711
- if (!existsSync19(appDir)) {
40926
+ if (!existsSync20(appDir)) {
40712
40927
  return [];
40713
40928
  }
40714
40929
  return scanDirectory(appDir, appDir, "/", options2);
@@ -40811,7 +41026,7 @@ function scanDirectory(rootDir, dir, parentPath, options2) {
40811
41026
  segmentCount: isGroup || dir === rootDir ? 0 : 1
40812
41027
  };
40813
41028
  for (const entry of entries) {
40814
- const entryPath = join10(dir, entry);
41029
+ const entryPath = join11(dir, entry);
40815
41030
  let entryStat;
40816
41031
  try {
40817
41032
  entryStat = statSync12(entryPath);
@@ -40863,19 +41078,19 @@ function collectSources(tree) {
40863
41078
  function walk6(nodes) {
40864
41079
  for (const node of nodes) {
40865
41080
  if (node.page)
40866
- map.set(node.page, join10(node.sourceDir, "page.vsk"));
41081
+ map.set(node.page, join11(node.sourceDir, "page.vsk"));
40867
41082
  if (node.layout)
40868
- map.set(node.layout, join10(node.sourceDir, "layout.vsk"));
41083
+ map.set(node.layout, join11(node.sourceDir, "layout.vsk"));
40869
41084
  if (node.loading)
40870
- map.set(node.loading, join10(node.sourceDir, "loading.vsk"));
41085
+ map.set(node.loading, join11(node.sourceDir, "loading.vsk"));
40871
41086
  if (node.error)
40872
- map.set(node.error, join10(node.sourceDir, "error.vsk"));
41087
+ map.set(node.error, join11(node.sourceDir, "error.vsk"));
40873
41088
  if (node.notFound)
40874
- map.set(node.notFound, join10(node.sourceDir, "not-found.vsk"));
41089
+ map.set(node.notFound, join11(node.sourceDir, "not-found.vsk"));
40875
41090
  if (node.offline)
40876
- map.set(node.offline, join10(node.sourceDir, "offline.vsk"));
41091
+ map.set(node.offline, join11(node.sourceDir, "offline.vsk"));
40877
41092
  if (node.network)
40878
- map.set(node.network, join10(node.sourceDir, "network.vsk"));
41093
+ map.set(node.network, join11(node.sourceDir, "network.vsk"));
40879
41094
  walk6(node.children);
40880
41095
  }
40881
41096
  }
@@ -40961,15 +41176,15 @@ function matchUrl(tree, pathname) {
40961
41176
  }
40962
41177
 
40963
41178
  // ../compiler/dist/api-routes.js
40964
- import { readdirSync as readdirSync8, statSync as statSync13, existsSync as existsSync20 } from "fs";
40965
- import { join as join11 } from "path";
41179
+ import { readdirSync as readdirSync8, statSync as statSync13, existsSync as existsSync21 } from "fs";
41180
+ import { join as join12 } from "path";
40966
41181
  init_server_utils();
40967
41182
  function basename4(p) {
40968
41183
  const idx = p.lastIndexOf("/");
40969
41184
  return idx === -1 ? p : p.slice(idx + 1);
40970
41185
  }
40971
41186
  function scanApiRoutes(apiDir) {
40972
- if (!existsSync20(apiDir))
41187
+ if (!existsSync21(apiDir))
40973
41188
  return [];
40974
41189
  return scanApiDir(apiDir, apiDir, "/");
40975
41190
  }
@@ -40999,7 +41214,7 @@ function scanApiDir(rootDir, dir, parentPath) {
40999
41214
  return nodes;
41000
41215
  if (isRouteGroup) {
41001
41216
  for (const entry of entries) {
41002
- const entryPath = join11(dir, entry);
41217
+ const entryPath = join12(dir, entry);
41003
41218
  let entryStat;
41004
41219
  try {
41005
41220
  entryStat = statSync13(entryPath);
@@ -41029,11 +41244,11 @@ function scanApiDir(rootDir, dir, parentPath) {
41029
41244
  fullPath: collapseSlashes(fullPath) || "/",
41030
41245
  isDynamic,
41031
41246
  isCatchAll,
41032
- filePath: hasRoute && routeFileName ? join11(dir, routeFileName) : null,
41247
+ filePath: hasRoute && routeFileName ? join12(dir, routeFileName) : null,
41033
41248
  children: []
41034
41249
  };
41035
41250
  for (const entry of entries) {
41036
- const entryPath = join11(dir, entry);
41251
+ const entryPath = join12(dir, entry);
41037
41252
  let entryStat;
41038
41253
  try {
41039
41254
  entryStat = statSync13(entryPath);
@@ -41334,8 +41549,8 @@ async function executeRewrite(url, originalRequest) {
41334
41549
  }
41335
41550
 
41336
41551
  // ../compiler/dist/middleware.js
41337
- import { existsSync as existsSync21 } from "fs";
41338
- import { resolve as resolve21 } from "path";
41552
+ import { existsSync as existsSync22 } from "fs";
41553
+ import { resolve as resolve22 } from "path";
41339
41554
 
41340
41555
  // ../compiler/src/api-routes.ts
41341
41556
  init_server_utils();
@@ -41394,8 +41609,8 @@ function collectMiddlewareChain(routeTree, url, appDir) {
41394
41609
  }
41395
41610
  function collectForNode(node) {
41396
41611
  if (node.hasMiddleware) {
41397
- const mwPath2 = resolve21(appDir, node.sourceDir, "middleware.ts");
41398
- if (existsSync21(mwPath2)) {
41612
+ const mwPath2 = resolve22(appDir, node.sourceDir, "middleware.ts");
41613
+ if (existsSync22(mwPath2)) {
41399
41614
  chain.push({ sourcePath: mwPath2, node });
41400
41615
  }
41401
41616
  }
@@ -41438,7 +41653,8 @@ async function loadMiddleware(sourcePath) {
41438
41653
  async function executeMiddlewareChain(chain, request, params, options2 = {}) {
41439
41654
  const { onLast, plugins } = options2;
41440
41655
  const url = new URL(request.url, "http://localhost");
41441
- const locals2 = {};
41656
+ const serverStore = globalThis.__vesk_server_ctx;
41657
+ const locals2 = Object.assign({}, serverStore || {});
41442
41658
  const cookies2 = parseCookies2(request.headers?.get("cookie") || "");
41443
41659
  const ctx2 = new Proxy({
41444
41660
  request,
@@ -41557,9 +41773,45 @@ async function executeMiddlewareChain(chain, request, params, options2 = {}) {
41557
41773
  return { response, redirected: !!response && response.status >= 300 && response.status < 400, locals: locals2, rewriteUrl };
41558
41774
  }
41559
41775
 
41776
+ // ../compiler/dist/events.js
41777
+ import { existsSync as existsSync23 } from "fs";
41778
+ import { join as join13 } from "path";
41779
+ var EVENTS_FILE_NAMES2 = ["_events.ts", "_events.js"];
41780
+ function collectEventsFile2(appDir) {
41781
+ for (const name of EVENTS_FILE_NAMES2) {
41782
+ const candidate = join13(appDir, name);
41783
+ if (existsSync23(candidate))
41784
+ return candidate;
41785
+ }
41786
+ return null;
41787
+ }
41788
+ async function loadEvents(sourcePath2) {
41789
+ try {
41790
+ const url = new URL("file://" + sourcePath2);
41791
+ url.searchParams.set("t", String(Date.now()) + Math.random().toString(36).slice(2));
41792
+ const mod = await import(url.href);
41793
+ const handlers = {};
41794
+ if (typeof mod.onStart === "function")
41795
+ handlers.onStart = mod.onStart;
41796
+ if (typeof mod.onRequest === "function")
41797
+ handlers.onRequest = mod.onRequest;
41798
+ if (typeof mod.onStop === "function")
41799
+ handlers.onStop = mod.onStop;
41800
+ return handlers;
41801
+ } catch {
41802
+ return {};
41803
+ }
41804
+ }
41805
+ async function runEventHandlers(handlers, name, ctx2) {
41806
+ const fn = handlers[name];
41807
+ if (typeof fn !== "function")
41808
+ return;
41809
+ await fn(ctx2);
41810
+ }
41811
+
41560
41812
  // ../adapter/dist/client-bundle.js
41561
- import { readFileSync as readFileSync20, existsSync as existsSync22, writeFileSync as writeFileSync10, unlinkSync as unlinkSync3, statSync as statSync14, rmSync as rmSync4 } from "node:fs";
41562
- import { resolve as resolve22, join as join12, dirname as dirname14, relative as relative6, sep as sep3 } from "node:path";
41813
+ import { readFileSync as readFileSync20, existsSync as existsSync24, writeFileSync as writeFileSync11, unlinkSync as unlinkSync4, statSync as statSync14, rmSync as rmSync4 } from "node:fs";
41814
+ import { resolve as resolve23, join as join14, dirname as dirname14, relative as relative6, sep as sep3 } from "node:path";
41563
41815
  import { fileURLToPath as fileURLToPath6 } from "node:url";
41564
41816
 
41565
41817
  // ../adapter/dist/esbuild-fallback.js
@@ -41632,15 +41884,15 @@ function buildRouterOpts2(options2) {
41632
41884
  return "";
41633
41885
  }
41634
41886
  function findRuntimeSrc3(appDir) {
41635
- const monorepoRoot = resolve22(__dirname7, "..", "..", "..");
41887
+ const monorepoRoot = resolve23(__dirname7, "..", "..", "..");
41636
41888
  const candidates = [
41637
- resolve22(monorepoRoot, "packages", "runtime", "dist"),
41638
- resolve22(appDir, "..", "node_modules", "@vesk/runtime"),
41639
- resolve22(appDir, "node_modules", "@vesk/runtime")
41889
+ resolve23(monorepoRoot, "packages", "runtime", "dist"),
41890
+ resolve23(appDir, "..", "node_modules", "@vesk/runtime"),
41891
+ resolve23(appDir, "node_modules", "@vesk/runtime")
41640
41892
  ];
41641
41893
  for (const base of candidates) {
41642
- for (const dir of [base, join12(base, "dist")]) {
41643
- if (existsSync22(join12(dir, "index-client.js")))
41894
+ for (const dir of [base, join14(base, "dist")]) {
41895
+ if (existsSync24(join14(dir, "index-client.js")))
41644
41896
  return dir;
41645
41897
  }
41646
41898
  }
@@ -41957,32 +42209,32 @@ async function generateClientBundle2(routeTree, appDir, componentMap, options2)
41957
42209
  let walkSplit2 = function(nodes, _chain) {
41958
42210
  for (const node of nodes) {
41959
42211
  const chunkCode = [];
41960
- const pagePath = resolve22(appDir, node.sourceDir, "page.vsk");
41961
- if (node.page && existsSync22(pagePath)) {
42212
+ const pagePath = resolve23(appDir, node.sourceDir, "page.vsk");
42213
+ if (node.page && existsSync24(pagePath)) {
41962
42214
  compileFile2(pagePath, node.page, chunkCode);
41963
42215
  }
41964
- const layoutPath = resolve22(appDir, node.sourceDir, "layout.vsk");
41965
- if (node.layout && existsSync22(layoutPath)) {
42216
+ const layoutPath = resolve23(appDir, node.sourceDir, "layout.vsk");
42217
+ if (node.layout && existsSync24(layoutPath)) {
41966
42218
  compileFile2(layoutPath, node.layout, chunkCode);
41967
42219
  }
41968
- const errorPath = resolve22(appDir, node.sourceDir, "error.vsk");
41969
- if (node.error && existsSync22(errorPath)) {
42220
+ const errorPath = resolve23(appDir, node.sourceDir, "error.vsk");
42221
+ if (node.error && existsSync24(errorPath)) {
41970
42222
  compileFile2(errorPath, node.error, chunkCode);
41971
42223
  }
41972
- const notFoundPath = resolve22(appDir, node.sourceDir, "not-found.vsk");
41973
- if (node.notFound && existsSync22(notFoundPath)) {
42224
+ const notFoundPath = resolve23(appDir, node.sourceDir, "not-found.vsk");
42225
+ if (node.notFound && existsSync24(notFoundPath)) {
41974
42226
  compileFile2(notFoundPath, node.notFound, chunkCode);
41975
42227
  }
41976
- const offlinePath = resolve22(appDir, node.sourceDir, "offline.vsk");
41977
- if (node.offline && existsSync22(offlinePath)) {
42228
+ const offlinePath = resolve23(appDir, node.sourceDir, "offline.vsk");
42229
+ if (node.offline && existsSync24(offlinePath)) {
41978
42230
  compileFile2(offlinePath, node.offline, chunkCode);
41979
42231
  }
41980
- const networkPath = resolve22(appDir, node.sourceDir, "network.vsk");
41981
- if (node.network && existsSync22(networkPath)) {
42232
+ const networkPath = resolve23(appDir, node.sourceDir, "network.vsk");
42233
+ if (node.network && existsSync24(networkPath)) {
41982
42234
  compileFile2(networkPath, node.network, chunkCode);
41983
42235
  }
41984
- const loadingPath = resolve22(appDir, node.sourceDir, "loading.vsk");
41985
- if (node.loading && existsSync22(loadingPath)) {
42236
+ const loadingPath = resolve23(appDir, node.sourceDir, "loading.vsk");
42237
+ if (node.loading && existsSync24(loadingPath)) {
41986
42238
  compileFile2(loadingPath, node.loading, chunkCode);
41987
42239
  }
41988
42240
  if (chunkCode.length > 0) {
@@ -42065,26 +42317,26 @@ ${entry.code}
42065
42317
  }
42066
42318
  }, walkMono2 = function(nodes) {
42067
42319
  for (const node of nodes) {
42068
- const pagePath = resolve22(appDir, node.sourceDir, "page.vsk");
42069
- if (node.page && existsSync22(pagePath))
42320
+ const pagePath = resolve23(appDir, node.sourceDir, "page.vsk");
42321
+ if (node.page && existsSync24(pagePath))
42070
42322
  compileFileMono2(pagePath, node.page);
42071
- const layoutPath = resolve22(appDir, node.sourceDir, "layout.vsk");
42072
- if (node.layout && existsSync22(layoutPath))
42323
+ const layoutPath = resolve23(appDir, node.sourceDir, "layout.vsk");
42324
+ if (node.layout && existsSync24(layoutPath))
42073
42325
  compileFileMono2(layoutPath, node.layout);
42074
- const errorPath = resolve22(appDir, node.sourceDir, "error.vsk");
42075
- if (node.error && existsSync22(errorPath))
42326
+ const errorPath = resolve23(appDir, node.sourceDir, "error.vsk");
42327
+ if (node.error && existsSync24(errorPath))
42076
42328
  compileFileMono2(errorPath, node.error);
42077
- const notFoundPath = resolve22(appDir, node.sourceDir, "not-found.vsk");
42078
- if (node.notFound && existsSync22(notFoundPath))
42329
+ const notFoundPath = resolve23(appDir, node.sourceDir, "not-found.vsk");
42330
+ if (node.notFound && existsSync24(notFoundPath))
42079
42331
  compileFileMono2(notFoundPath, node.notFound);
42080
- const offlinePath = resolve22(appDir, node.sourceDir, "offline.vsk");
42081
- if (node.offline && existsSync22(offlinePath))
42332
+ const offlinePath = resolve23(appDir, node.sourceDir, "offline.vsk");
42333
+ if (node.offline && existsSync24(offlinePath))
42082
42334
  compileFileMono2(offlinePath, node.offline);
42083
- const networkPath = resolve22(appDir, node.sourceDir, "network.vsk");
42084
- if (node.network && existsSync22(networkPath))
42335
+ const networkPath = resolve23(appDir, node.sourceDir, "network.vsk");
42336
+ if (node.network && existsSync24(networkPath))
42085
42337
  compileFileMono2(networkPath, node.network);
42086
- const loadingPath = resolve22(appDir, node.sourceDir, "loading.vsk");
42087
- if (node.loading && existsSync22(loadingPath))
42338
+ const loadingPath = resolve23(appDir, node.sourceDir, "loading.vsk");
42339
+ if (node.loading && existsSync24(loadingPath))
42088
42340
  compileFileMono2(loadingPath, node.loading);
42089
42341
  walkMono2(node.children || []);
42090
42342
  }
@@ -42134,8 +42386,8 @@ function buildRuntimeCode2(runtimeDir) {
42134
42386
  ];
42135
42387
  let code = "";
42136
42388
  for (const f of runtimeFiles) {
42137
- const p = join12(runtimeDir, f);
42138
- if (existsSync22(p)) {
42389
+ const p = join14(runtimeDir, f);
42390
+ if (existsSync24(p)) {
42139
42391
  let src2 = readFileSync20(p, "utf-8");
42140
42392
  src2 = stripTypes2(src2);
42141
42393
  src2 = src2.replace(/^import\s+[\s\S]*?from\s+['"](?:\.\/.*?|@vesk\/runtime\/src\/.*?)['"];?\n?/gm, "");
@@ -42148,7 +42400,7 @@ ${src2}
42148
42400
  `;
42149
42401
  }
42150
42402
  }
42151
- const indexSrc = readFileSync20(join12(runtimeDir, "index-client.js"), "utf-8");
42403
+ const indexSrc = readFileSync20(join14(runtimeDir, "index-client.js"), "utf-8");
42152
42404
  const exportNames = stripTypes2(indexSrc).match(/export\s*\{\s*([^}]+)\s*\}\s*from/g)?.flatMap((m) => m.replace(/export\s*\{\s*|\s*\}\s*from/g, "").split(",").map((s) => s.trim())) || [];
42153
42405
  code += "// --- exports ---\n";
42154
42406
  for (const name of [...new Set(exportNames)]) {
@@ -42159,7 +42411,7 @@ ${src2}
42159
42411
  return code;
42160
42412
  }
42161
42413
  function runtimeExportNames2(runtimeDir) {
42162
- const indexSrc = readFileSync20(join12(runtimeDir, "index-client.js"), "utf-8");
42414
+ const indexSrc = readFileSync20(join14(runtimeDir, "index-client.js"), "utf-8");
42163
42415
  const names = /* @__PURE__ */ new Set();
42164
42416
  for (const m of indexSrc.matchAll(/export\s*\{([^}]+)\}\s*from/g)) {
42165
42417
  for (const raw2 of m[1].split(",")) {
@@ -42179,13 +42431,13 @@ async function buildTreeShakenRuntime2(runtimeDir, usedNames) {
42179
42431
  console.error(`vesk: runtime names not exported \u2014 ${missing.join(", ")}; falling back to full runtime`);
42180
42432
  return buildRuntimeCode2(runtimeDir);
42181
42433
  }
42182
- const entry = join12(runtimeDir, RUNTIME_ENTRY2);
42434
+ const entry = join14(runtimeDir, RUNTIME_ENTRY2);
42183
42435
  try {
42184
42436
  try {
42185
42437
  rmSync4(entry);
42186
42438
  } catch {
42187
42439
  }
42188
- writeFileSync10(entry, `export { ${unique.join(", ")} } from './index-client.js';
42440
+ writeFileSync11(entry, `export { ${unique.join(", ")} } from './index-client.js';
42189
42441
  `);
42190
42442
  const result2 = await build3({
42191
42443
  entryPoints: [entry],
@@ -42216,7 +42468,7 @@ export { ${unique.join(", ")} };
42216
42468
  return buildRuntimeCode2(runtimeDir);
42217
42469
  } finally {
42218
42470
  try {
42219
- unlinkSync3(entry);
42471
+ unlinkSync4(entry);
42220
42472
  } catch {
42221
42473
  }
42222
42474
  }
@@ -42316,18 +42568,18 @@ if (typeof document !== 'undefined') __router.start();
42316
42568
  }
42317
42569
 
42318
42570
  // ../adapter/dist/paths.js
42319
- import { resolve as resolve23, sep as sep4 } from "node:path";
42320
- import { existsSync as existsSync23, statSync as statSync15, readFileSync as readFileSync21 } from "node:fs";
42571
+ import { resolve as resolve24, sep as sep4 } from "node:path";
42572
+ import { existsSync as existsSync25, statSync as statSync15, readFileSync as readFileSync21 } from "node:fs";
42321
42573
  function resolveWithin2(baseDir, relPath) {
42322
- const base = resolve23(baseDir);
42323
- const target = resolve23(baseDir, relPath);
42574
+ const base = resolve24(baseDir);
42575
+ const target = resolve24(baseDir, relPath);
42324
42576
  const prefix = base + sep4;
42325
42577
  if (!target.startsWith(prefix))
42326
42578
  return null;
42327
42579
  return target;
42328
42580
  }
42329
42581
  function installMdReadHook2(publicDirs) {
42330
- const dirs = publicDirs.map((d) => resolve23(d));
42582
+ const dirs = publicDirs.map((d) => resolve24(d));
42331
42583
  globalThis.__vsk_md_read_file = (p) => {
42332
42584
  for (const dir of dirs) {
42333
42585
  try {
@@ -42340,7 +42592,7 @@ function installMdReadHook2(publicDirs) {
42340
42592
  const lower = abs.toLowerCase();
42341
42593
  if (!lower.endsWith(".md") && !lower.endsWith(".markdown"))
42342
42594
  continue;
42343
- if (existsSync23(abs) && statSync15(abs).isFile())
42595
+ if (existsSync25(abs) && statSync15(abs).isFile())
42344
42596
  return readFileSync21(abs, "utf8");
42345
42597
  } catch {
42346
42598
  }
@@ -42408,13 +42660,13 @@ function urlAuthority3(url) {
42408
42660
  }
42409
42661
 
42410
42662
  // ../adapter/dist/dev-api.js
42411
- import { readFileSync as readFileSync24, statSync as statSync17, existsSync as existsSync26, readdirSync as readdirSync9 } from "node:fs";
42412
- import { resolve as resolve26 } from "node:path";
42663
+ import { readFileSync as readFileSync24, statSync as statSync17, existsSync as existsSync28, readdirSync as readdirSync9 } from "node:fs";
42664
+ import { resolve as resolve27 } from "node:path";
42413
42665
 
42414
42666
  // ../adapter/dist/plugins.js
42415
42667
  init_paths();
42416
- import { readFileSync as readFileSync22, writeFileSync as writeFileSync11, existsSync as existsSync24, mkdirSync as mkdirSync8, statSync as statSync16 } from "node:fs";
42417
- import { resolve as resolve24, dirname as dirname15, join as join13, extname as extname7, basename as basename5 } from "node:path";
42668
+ import { readFileSync as readFileSync22, writeFileSync as writeFileSync12, existsSync as existsSync26, mkdirSync as mkdirSync9, statSync as statSync16 } from "node:fs";
42669
+ import { resolve as resolve25, dirname as dirname15, join as join15, extname as extname7, basename as basename5 } from "node:path";
42418
42670
  import { createRequire as createRequire4 } from "node:module";
42419
42671
  import { spawn as spawn2 } from "node:child_process";
42420
42672
  var PLUGIN_STATE_FILENAME2 = "plugins.json";
@@ -42429,11 +42681,11 @@ function eqIgnoreCase2(a, b) {
42429
42681
  return String(a || "").toLowerCase() === String(b || "").toLowerCase();
42430
42682
  }
42431
42683
  function stateFilePath2(veskDir) {
42432
- return resolve24(veskDir, PLUGIN_STATE_FILENAME2);
42684
+ return resolve25(veskDir, PLUGIN_STATE_FILENAME2);
42433
42685
  }
42434
42686
  function readPluginState2(veskDir) {
42435
42687
  const file = stateFilePath2(veskDir);
42436
- if (!existsSync24(file))
42688
+ if (!existsSync26(file))
42437
42689
  return defaultState2();
42438
42690
  let raw2;
42439
42691
  try {
@@ -42456,12 +42708,12 @@ function readPluginState2(veskDir) {
42456
42708
  function writePluginState2(veskDir, state) {
42457
42709
  const file = stateFilePath2(veskDir);
42458
42710
  const dir = dirname15(file);
42459
- if (!existsSync24(dir))
42460
- mkdirSync8(dir, { recursive: true });
42461
- writeFileSync11(file, JSON.stringify(state, null, 2) + "\n", "utf-8");
42711
+ if (!existsSync26(dir))
42712
+ mkdirSync9(dir, { recursive: true });
42713
+ writeFileSync12(file, JSON.stringify(state, null, 2) + "\n", "utf-8");
42462
42714
  }
42463
42715
  function resolvePackage2(appDir, pkg) {
42464
- const require3 = createRequire4(resolve24(appDir, "package.json"));
42716
+ const require3 = createRequire4(resolve25(appDir, "package.json"));
42465
42717
  let entryPath = null;
42466
42718
  let pkgJsonPath = null;
42467
42719
  let pkgJson = null;
@@ -42474,8 +42726,8 @@ function resolvePackage2(appDir, pkg) {
42474
42726
  const seen = /* @__PURE__ */ new Set();
42475
42727
  while (cur && cur !== dirname15(cur) && !seen.has(cur)) {
42476
42728
  seen.add(cur);
42477
- const candidate = join13(cur, "package.json");
42478
- if (existsSync24(candidate)) {
42729
+ const candidate = join15(cur, "package.json");
42730
+ if (existsSync26(candidate)) {
42479
42731
  pkgJsonPath = candidate;
42480
42732
  break;
42481
42733
  }
@@ -42487,15 +42739,15 @@ function resolvePackage2(appDir, pkg) {
42487
42739
  } catch {
42488
42740
  }
42489
42741
  }
42490
- if (pkgJsonPath && existsSync24(pkgJsonPath)) {
42742
+ if (pkgJsonPath && existsSync26(pkgJsonPath)) {
42491
42743
  pkgJson = readJsonFile2(pkgJsonPath);
42492
42744
  const main = pkgJson?.main || pkgJson?.module || "index.js";
42493
- entryPath = resolve24(dirname15(pkgJsonPath), main);
42745
+ entryPath = resolve25(dirname15(pkgJsonPath), main);
42494
42746
  }
42495
42747
  let localPath = localDir2(appDir, pkg);
42496
42748
  if (!localPath) {
42497
42749
  for (const sub of ["src/plugins", "plugins", "lib/plugins"]) {
42498
- const candidate = localDir2(resolve24(appDir, sub), pkg);
42750
+ const candidate = localDir2(resolve25(appDir, sub), pkg);
42499
42751
  if (candidate) {
42500
42752
  localPath = candidate;
42501
42753
  break;
@@ -42503,32 +42755,32 @@ function resolvePackage2(appDir, pkg) {
42503
42755
  }
42504
42756
  }
42505
42757
  if (localPath) {
42506
- const localJson = join13(localPath, "package.json");
42758
+ const localJson = join15(localPath, "package.json");
42507
42759
  let json = null;
42508
- if (existsSync24(localJson)) {
42760
+ if (existsSync26(localJson)) {
42509
42761
  json = readJsonFile2(localJson);
42510
42762
  }
42511
42763
  return { installed: true, path: localPath, dir: localPath, packageJson: json ?? pkgJson };
42512
42764
  }
42513
- const installed2 = !!pkgJsonPath && existsSync24(pkgJsonPath);
42765
+ const installed2 = !!pkgJsonPath && existsSync26(pkgJsonPath);
42514
42766
  return { installed: installed2, path: entryPath, dir: installed2 ? dirname15(pkgJsonPath) : null, packageJson: pkgJson };
42515
42767
  }
42516
42768
  function localDir2(base, pkg) {
42517
42769
  if (pkg.startsWith("@")) {
42518
42770
  const parts = pkg.split("/");
42519
- const p2 = resolve24(base, parts[0], parts[1] ?? "");
42520
- if (existsSync24(p2))
42771
+ const p2 = resolve25(base, parts[0], parts[1] ?? "");
42772
+ if (existsSync26(p2))
42521
42773
  return p2;
42522
42774
  return null;
42523
42775
  }
42524
- const p = resolve24(base, pkg);
42525
- if (existsSync24(p))
42776
+ const p = resolve25(base, pkg);
42777
+ if (existsSync26(p))
42526
42778
  return p;
42527
42779
  return null;
42528
42780
  }
42529
42781
  function readJsonFile2(file) {
42530
42782
  try {
42531
- if (existsSync24(file))
42783
+ if (existsSync26(file))
42532
42784
  return JSON.parse(readFileSync22(file, "utf-8"));
42533
42785
  } catch {
42534
42786
  }
@@ -42575,7 +42827,7 @@ function repositoryToString2(r) {
42575
42827
  function assemblePluginMeta2(probe) {
42576
42828
  const pkgJson = probe.packageJson || {};
42577
42829
  const dir = probe.dir;
42578
- const meta = dir ? readJsonFile2(resolve24(dir, "vesk.meta.json")) : null;
42830
+ const meta = dir ? readJsonFile2(resolve25(dir, "vesk.meta.json")) : null;
42579
42831
  const hasMeta = !!meta && Object.keys(meta).length > 0;
42580
42832
  const m = meta || {};
42581
42833
  const metaSource = hasMeta ? "vesk.meta.json" : probe.packageJson ? "package.json" : "none";
@@ -42812,12 +43064,12 @@ function findIconFile2(dir, meta) {
42812
43064
  const explicit = str2(meta?.icon);
42813
43065
  if (explicit) {
42814
43066
  const p = resolveWithin(dir, explicit);
42815
- if (p && existsSync24(p) && statSync16(p).isFile())
43067
+ if (p && existsSync26(p) && statSync16(p).isFile())
42816
43068
  return p;
42817
43069
  }
42818
43070
  for (const name of ["icon.png", "icon.ico"]) {
42819
- const p = resolve24(dir, name);
42820
- if (existsSync24(p) && statSync16(p).isFile())
43071
+ const p = resolve25(dir, name);
43072
+ if (existsSync26(p) && statSync16(p).isFile())
42821
43073
  return p;
42822
43074
  }
42823
43075
  return null;
@@ -42827,7 +43079,7 @@ function findPluginIcon2(appDir, name) {
42827
43079
  const dir = probe.dir;
42828
43080
  if (!dir)
42829
43081
  return null;
42830
- const meta = readJsonFile2(resolve24(dir, "vesk.meta.json"));
43082
+ const meta = readJsonFile2(resolve25(dir, "vesk.meta.json"));
42831
43083
  const iconPath = findIconFile2(dir, meta);
42832
43084
  if (!iconPath)
42833
43085
  return null;
@@ -42902,7 +43154,7 @@ function resolveDtsPath2(probe, pkgJson) {
42902
43154
  if (!rel)
42903
43155
  continue;
42904
43156
  const abs = resolveWithin(dir, rel);
42905
- if (abs && existsSync24(abs) && statSync16(abs).isFile())
43157
+ if (abs && existsSync26(abs) && statSync16(abs).isFile())
42906
43158
  return abs;
42907
43159
  }
42908
43160
  return null;
@@ -43389,16 +43641,16 @@ var __internals2 = {
43389
43641
  };
43390
43642
 
43391
43643
  // ../adapter/dist/dev-config.js
43392
- import { existsSync as existsSync25, readFileSync as readFileSync23, writeFileSync as writeFileSync12, mkdirSync as mkdirSync9, mkdtempSync, rmSync as rmSync5 } from "node:fs";
43644
+ import { existsSync as existsSync27, readFileSync as readFileSync23, writeFileSync as writeFileSync13, mkdirSync as mkdirSync10, mkdtempSync, rmSync as rmSync5 } from "node:fs";
43393
43645
  import { tmpdir } from "node:os";
43394
- import { resolve as resolve25, dirname as dirname16, join as join14 } from "node:path";
43646
+ import { resolve as resolve26, dirname as dirname16, join as join16 } from "node:path";
43395
43647
  init_parser();
43396
43648
  function findConfigFile2(projectDir2) {
43397
- const ts9 = resolve25(projectDir2, "vesk.config.ts");
43398
- if (existsSync25(ts9))
43649
+ const ts9 = resolve26(projectDir2, "vesk.config.ts");
43650
+ if (existsSync27(ts9))
43399
43651
  return { path: ts9, isTs: true };
43400
- const js = resolve25(projectDir2, "vesk.config.js");
43401
- if (existsSync25(js))
43652
+ const js = resolve26(projectDir2, "vesk.config.js");
43653
+ if (existsSync27(js))
43402
43654
  return { path: js, isTs: false };
43403
43655
  return { path: null, isTs: false };
43404
43656
  }
@@ -43419,11 +43671,11 @@ async function parseConfigSource(source, isTs, projectDir2) {
43419
43671
  js = `const { defineConfig, definePlugin, preset } = globalThis.__vesk_inject;
43420
43672
  ` + js;
43421
43673
  }
43422
- const base = projectDir2 ? (mkdirSync9(join14(projectDir2, ".vesk"), { recursive: true }), join14(projectDir2, ".vesk")) : void 0;
43423
- const dir = base ? mkdtempSync(join14(base, "cfg-")) : mkdtempSync(join14(tmpdir(), "vesk-cfg-"));
43424
- const tmpFile = join14(dir, "config.mjs");
43674
+ const base = projectDir2 ? (mkdirSync10(join16(projectDir2, ".vesk"), { recursive: true }), join16(projectDir2, ".vesk")) : void 0;
43675
+ const dir = base ? mkdtempSync(join16(base, "cfg-")) : mkdtempSync(join16(tmpdir(), "vesk-cfg-"));
43676
+ const tmpFile = join16(dir, "config.mjs");
43425
43677
  try {
43426
- writeFileSync12(tmpFile, js, "utf-8");
43678
+ writeFileSync13(tmpFile, js, "utf-8");
43427
43679
  globalThis.__vesk_inject = {
43428
43680
  defineConfig: defineConfig2,
43429
43681
  // Pass-through like the real definePlugin (which validates + returns
@@ -43454,10 +43706,10 @@ async function readConfig2(projectDir2) {
43454
43706
  }
43455
43707
  async function writeConfigSource2(projectDir2, source) {
43456
43708
  const { path, isTs } = findConfigFile2(projectDir2);
43457
- const target = path || resolve25(projectDir2, "vesk.config.ts");
43709
+ const target = path || resolve26(projectDir2, "vesk.config.ts");
43458
43710
  await parseConfigSource(source, isTs, projectDir2);
43459
- mkdirSync9(dirname16(target), { recursive: true });
43460
- writeFileSync12(target, source, "utf-8");
43711
+ mkdirSync10(dirname16(target), { recursive: true });
43712
+ writeFileSync13(target, source, "utf-8");
43461
43713
  const config = await parseConfigSource(source, isTs, projectDir2);
43462
43714
  return { path: target, exists: true, source, config };
43463
43715
  }
@@ -44164,7 +44416,7 @@ export default defineConfig({
44164
44416
  ]
44165
44417
  })
44166
44418
  `;
44167
- target = resolve25(projectDir2, "vesk.config.ts");
44419
+ target = resolve26(projectDir2, "vesk.config.ts");
44168
44420
  await writeConfigSource2(projectDir2, source);
44169
44421
  return;
44170
44422
  }
@@ -44326,7 +44578,7 @@ function jsonStatus(status, data2) {
44326
44578
  function createDevApiRouter2(opts) {
44327
44579
  const veskDir = opts.veskDir;
44328
44580
  const caps = new CapabilityTable2(opts.caps, opts.commandAllowlist);
44329
- const projectDir2 = opts.projectDir || resolve26(opts.appDir, "..");
44581
+ const projectDir2 = opts.projectDir || resolve27(opts.appDir, "..");
44330
44582
  const getState = opts.getHmrState || (() => ({ status: "up", lastCompileMs: null, error: null, hasError: false, componentCount: 0 }));
44331
44583
  function denied2(cap) {
44332
44584
  return jsonStatus(403, { error: `capability denied: ${cap}` });
@@ -44408,7 +44660,7 @@ function createDevApiRouter2(opts) {
44408
44660
  const resolved = resolveWithin2(projectDir2, target);
44409
44661
  if (!resolved)
44410
44662
  return jsonStatus(403, { error: "path escapes project root" });
44411
- if (!existsSync26(resolved))
44663
+ if (!existsSync28(resolved))
44412
44664
  return jsonStatus(404, { error: "not found" });
44413
44665
  if (statSync17(resolved).isDirectory()) {
44414
44666
  const entries = readdirSync9(resolved, { withFileTypes: true }).map((e) => e.name);
@@ -44608,8 +44860,8 @@ function produceDiagnostics(input) {
44608
44860
  }
44609
44861
 
44610
44862
  // ../agentic/dist/checkpoints.js
44611
- import { existsSync as existsSync27, mkdirSync as mkdirSync10, readFileSync as readFileSync25, writeFileSync as writeFileSync13, statSync as statSync18, unlinkSync as unlinkSync4, rmSync as rmSync6, renameSync } from "node:fs";
44612
- import { join as join15, resolve as resolve27, dirname as dirname17, sep as sep5 } from "node:path";
44863
+ import { existsSync as existsSync29, mkdirSync as mkdirSync11, readFileSync as readFileSync25, writeFileSync as writeFileSync14, statSync as statSync18, unlinkSync as unlinkSync5, rmSync as rmSync6, renameSync } from "node:fs";
44864
+ import { join as join17, resolve as resolve28, dirname as dirname17, sep as sep5 } from "node:path";
44613
44865
  import { randomUUID as nodeRandomUUID } from "node:crypto";
44614
44866
  function generateId() {
44615
44867
  try {
@@ -44742,23 +44994,23 @@ var CheckpointManager = class {
44742
44994
  }
44743
44995
  };
44744
44996
  function getAgenticDir(projectDir2) {
44745
- return join15(resolve27(projectDir2), ".vesk", "agentic");
44997
+ return join17(resolve28(projectDir2), ".vesk", "agentic");
44746
44998
  }
44747
44999
  function getHistoryPath(projectDir2) {
44748
- return join15(getAgenticDir(projectDir2), "history.json");
45000
+ return join17(getAgenticDir(projectDir2), "history.json");
44749
45001
  }
44750
45002
  function getCheckpointDir(projectDir2, id) {
44751
- return join15(getAgenticDir(projectDir2), "checkpoints", id);
45003
+ return join17(getAgenticDir(projectDir2), "checkpoints", id);
44752
45004
  }
44753
45005
  function getCheckpointPath(projectDir2, id) {
44754
- return join15(getCheckpointDir(projectDir2, id), "checkpoint.json");
45006
+ return join17(getCheckpointDir(projectDir2, id), "checkpoint.json");
44755
45007
  }
44756
45008
  function ensureDir(dir) {
44757
- mkdirSync10(dir, { recursive: true });
45009
+ mkdirSync11(dir, { recursive: true });
44758
45010
  }
44759
45011
  function readJson(filePath, fallback) {
44760
45012
  try {
44761
- if (!existsSync27(filePath))
45013
+ if (!existsSync29(filePath))
44762
45014
  return fallback;
44763
45015
  const raw2 = readFileSync25(filePath, "utf-8");
44764
45016
  if (raw2.trim() === "")
@@ -44771,14 +45023,14 @@ function readJson(filePath, fallback) {
44771
45023
  function writeJsonAtomic(filePath, data2) {
44772
45024
  ensureDir(dirname17(filePath));
44773
45025
  const tmp = `${filePath}.tmp`;
44774
- writeFileSync13(tmp, JSON.stringify(data2, null, 2), "utf-8");
45026
+ writeFileSync14(tmp, JSON.stringify(data2, null, 2), "utf-8");
44775
45027
  try {
44776
45028
  renameSync(tmp, filePath);
44777
45029
  } catch {
44778
45030
  try {
44779
- writeFileSync13(filePath, JSON.stringify(data2, null, 2), "utf-8");
45031
+ writeFileSync14(filePath, JSON.stringify(data2, null, 2), "utf-8");
44780
45032
  try {
44781
- unlinkSync4(tmp);
45033
+ unlinkSync5(tmp);
44782
45034
  } catch {
44783
45035
  }
44784
45036
  } catch {
@@ -44831,7 +45083,7 @@ function createCheckpoint(projectDir2, message, changes = {}, buildResult) {
44831
45083
  };
44832
45084
  const agenticDir = getAgenticDir(projectDir2);
44833
45085
  ensureDir(agenticDir);
44834
- ensureDir(join15(agenticDir, "checkpoints"));
45086
+ ensureDir(join17(agenticDir, "checkpoints"));
44835
45087
  const cpDir = getCheckpointDir(projectDir2, id);
44836
45088
  ensureDir(cpDir);
44837
45089
  writeJsonAtomic(getCheckpointPath(projectDir2, id), checkpoint);
@@ -44852,26 +45104,26 @@ function rollback(projectDir2, id) {
44852
45104
  const cp = getCheckpoint(projectDir2, id);
44853
45105
  if (!cp)
44854
45106
  return null;
44855
- const projectRoot = resolve27(projectDir2);
45107
+ const projectRoot = resolve28(projectDir2);
44856
45108
  for (const f of cp.files) {
44857
45109
  if (!f.path || !f.path.trim())
44858
45110
  continue;
44859
- const abs = resolve27(projectRoot, f.path);
45111
+ const abs = resolve28(projectRoot, f.path);
44860
45112
  if (f.before === null) {
44861
45113
  try {
44862
- if (existsSync27(abs)) {
45114
+ if (existsSync29(abs)) {
44863
45115
  const s = statSync18(abs);
44864
45116
  if (s.isDirectory())
44865
45117
  rmSync6(abs, { recursive: true, force: true });
44866
45118
  else
44867
- unlinkSync4(abs);
45119
+ unlinkSync5(abs);
44868
45120
  }
44869
45121
  } catch {
44870
45122
  }
44871
45123
  } else {
44872
45124
  try {
44873
45125
  ensureDir(dirname17(abs));
44874
- writeFileSync13(abs, f.before, "utf-8");
45126
+ writeFileSync14(abs, f.before, "utf-8");
44875
45127
  } catch {
44876
45128
  }
44877
45129
  }
@@ -44880,8 +45132,8 @@ function rollback(projectDir2, id) {
44880
45132
  }
44881
45133
 
44882
45134
  // ../agentic/dist/config.js
44883
- import { readFileSync as readFileSync26, writeFileSync as writeFileSync14, existsSync as existsSync28, mkdirSync as mkdirSync11, chmodSync } from "node:fs";
44884
- import { resolve as resolve28, dirname as dirname18 } from "node:path";
45135
+ import { readFileSync as readFileSync26, writeFileSync as writeFileSync15, existsSync as existsSync30, mkdirSync as mkdirSync12, chmodSync } from "node:fs";
45136
+ import { resolve as resolve29, dirname as dirname18 } from "node:path";
44885
45137
  var DEFAULT_CONFIG = {
44886
45138
  provider: "openai",
44887
45139
  model: "gpt-4o-mini",
@@ -44900,10 +45152,10 @@ var SUPPORTED_PROVIDERS = [
44900
45152
  "custom"
44901
45153
  ];
44902
45154
  function configPath2(projectDir2) {
44903
- return resolve28(projectDir2, ".vesk", "agentic", "config.json");
45155
+ return resolve29(projectDir2, ".vesk", "agentic", "config.json");
44904
45156
  }
44905
45157
  function keysDir(projectDir2) {
44906
- return resolve28(projectDir2, ".vesk", "agentic", "keys");
45158
+ return resolve29(projectDir2, ".vesk", "agentic", "keys");
44907
45159
  }
44908
45160
  function sanitizeProvider(provider) {
44909
45161
  const p = provider.trim().toLowerCase();
@@ -44915,19 +45167,19 @@ function normalizeProvider(provider) {
44915
45167
  return provider.trim().toLowerCase();
44916
45168
  }
44917
45169
  function providerKeyPath(projectDir2, provider) {
44918
- return resolve28(keysDir(projectDir2), `${sanitizeProvider(provider)}.key`);
45170
+ return resolve29(keysDir(projectDir2), `${sanitizeProvider(provider)}.key`);
44919
45171
  }
44920
45172
  function providerDotenvVar(provider) {
44921
45173
  const prov = sanitizeProvider(provider);
44922
45174
  return `VK_${prov.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_KEY`;
44923
45175
  }
44924
45176
  function dotenvPath(projectDir2) {
44925
- return resolve28(projectDir2, ".env.local");
45177
+ return resolve29(projectDir2, ".env.local");
44926
45178
  }
44927
45179
  function readDotenvValue(projectDir2, key, def = null) {
44928
45180
  try {
44929
45181
  const p = dotenvPath(projectDir2);
44930
- if (!existsSync28(p))
45182
+ if (!existsSync30(p))
44931
45183
  return def;
44932
45184
  const content = readFileSync26(p, "utf-8");
44933
45185
  for (const rawLine of content.split("\n")) {
@@ -44956,7 +45208,7 @@ function writeDotenvValue(projectDir2, key, value) {
44956
45208
  try {
44957
45209
  let out = "";
44958
45210
  let replaced = false;
44959
- if (existsSync28(p)) {
45211
+ if (existsSync30(p)) {
44960
45212
  const lines = readFileSync26(p, "utf-8").split("\n");
44961
45213
  for (const rawLine of lines) {
44962
45214
  const trimmed = rawLine.trim();
@@ -44971,7 +45223,7 @@ function writeDotenvValue(projectDir2, key, value) {
44971
45223
  }
44972
45224
  if (!replaced)
44973
45225
  out += newLine + "\n";
44974
- writeFileSync14(p, out, { mode: 384 });
45226
+ writeFileSync15(p, out, { mode: 384 });
44975
45227
  try {
44976
45228
  chmodSync(p, 384);
44977
45229
  } catch {
@@ -44986,7 +45238,7 @@ function loadAgenticConfig(projectDir2) {
44986
45238
  const p = configPath2(projectDir2);
44987
45239
  let cfg = { ...DEFAULT_CONFIG };
44988
45240
  try {
44989
- if (existsSync28(p))
45241
+ if (existsSync30(p))
44990
45242
  cfg = { ...cfg, ...JSON.parse(readFileSync26(p, "utf-8")) };
44991
45243
  } catch {
44992
45244
  }
@@ -45010,8 +45262,8 @@ function saveAgenticConfig(projectDir2, patch) {
45010
45262
  if (next.baseUrl)
45011
45263
  toWrite.baseUrl = next.baseUrl;
45012
45264
  try {
45013
- mkdirSync11(dirname18(p), { recursive: true });
45014
- writeFileSync14(p, JSON.stringify(toWrite, null, 2), "utf-8");
45265
+ mkdirSync12(dirname18(p), { recursive: true });
45266
+ writeFileSync15(p, JSON.stringify(toWrite, null, 2), "utf-8");
45015
45267
  } catch {
45016
45268
  }
45017
45269
  return next;
@@ -45029,7 +45281,7 @@ function getProviderSpecificKey(projectDir2, provider) {
45029
45281
  return dotenvFile.trim();
45030
45282
  try {
45031
45283
  const pp2 = providerKeyPath(projectDir2, prov);
45032
- if (existsSync28(pp2)) {
45284
+ if (existsSync30(pp2)) {
45033
45285
  const v = readFileSync26(pp2, "utf-8").trim();
45034
45286
  if (v)
45035
45287
  return v;
@@ -45077,7 +45329,7 @@ function getApiKey(projectDir2, provider) {
45077
45329
  }
45078
45330
  try {
45079
45331
  const pp2 = providerKeyPath(projectDir2, prov);
45080
- if (existsSync28(pp2)) {
45332
+ if (existsSync30(pp2)) {
45081
45333
  const v = readFileSync26(pp2, "utf-8").trim();
45082
45334
  if (v)
45083
45335
  return v;
@@ -45101,8 +45353,8 @@ function getApiKey(projectDir2, provider) {
45101
45353
  }
45102
45354
 
45103
45355
  // ../agentic/dist/dev-api.js
45104
- import { existsSync as existsSync29, readFileSync as readFileSync27 } from "node:fs";
45105
- import { resolve as resolve29 } from "node:path";
45356
+ import { existsSync as existsSync31, readFileSync as readFileSync27 } from "node:fs";
45357
+ import { resolve as resolve30 } from "node:path";
45106
45358
 
45107
45359
  // ../agentic/dist/providers/openai.js
45108
45360
  var OPENAI_FALLBACK_MODELS = ["gpt-4o-mini", "gpt-4o", "gpt-3.5-turbo"];
@@ -45472,8 +45724,8 @@ function getPerProviderKeyRaw(projectDir2, provider) {
45472
45724
  } catch {
45473
45725
  }
45474
45726
  try {
45475
- const p = resolve29(projectDir2, ".vesk", "agentic", "keys", `${sanitizeProviderName(prov)}.key`);
45476
- if (existsSync29(p)) {
45727
+ const p = resolve30(projectDir2, ".vesk", "agentic", "keys", `${sanitizeProviderName(prov)}.key`);
45728
+ if (existsSync31(p)) {
45477
45729
  const v = readFileSync27(p, "utf-8").trim();
45478
45730
  if (v)
45479
45731
  return v;
@@ -46335,11 +46587,11 @@ var Agent = class {
46335
46587
  };
46336
46588
 
46337
46589
  // ../agentic/dist/tools/vesk.js
46338
- import { existsSync as existsSync30, readFileSync as readFileSync28, writeFileSync as writeFileSync15, mkdirSync as mkdirSync12, readdirSync as readdirSync10, statSync as statSync19 } from "node:fs";
46339
- import { resolve as resolve30, join as join16, dirname as dirname19, sep as sep6 } from "node:path";
46590
+ import { existsSync as existsSync32, readFileSync as readFileSync28, writeFileSync as writeFileSync16, mkdirSync as mkdirSync13, readdirSync as readdirSync10, statSync as statSync19 } from "node:fs";
46591
+ import { resolve as resolve31, join as join18, dirname as dirname19, sep as sep6 } from "node:path";
46340
46592
  function resolveWithin3(baseDir, relPath) {
46341
- const base = resolve30(baseDir);
46342
- const target = resolve30(baseDir, relPath);
46593
+ const base = resolve31(baseDir);
46594
+ const target = resolve31(baseDir, relPath);
46343
46595
  const prefix = base + sep6;
46344
46596
  if (target === base || !target.startsWith(prefix))
46345
46597
  return null;
@@ -46347,11 +46599,11 @@ function resolveWithin3(baseDir, relPath) {
46347
46599
  }
46348
46600
  var PLUGIN_STATE_FILENAME3 = "plugins.json";
46349
46601
  function stateFilePath3(veskDir) {
46350
- return resolve30(veskDir, PLUGIN_STATE_FILENAME3);
46602
+ return resolve31(veskDir, PLUGIN_STATE_FILENAME3);
46351
46603
  }
46352
46604
  function readPluginState3(veskDir) {
46353
46605
  const file = stateFilePath3(veskDir);
46354
- if (!existsSync30(file))
46606
+ if (!existsSync32(file))
46355
46607
  return { version: 1, plugins: [] };
46356
46608
  try {
46357
46609
  const raw2 = JSON.parse(readFileSync28(file, "utf-8"));
@@ -46369,8 +46621,8 @@ function readPluginState3(veskDir) {
46369
46621
  }
46370
46622
  function writePluginState3(veskDir, state) {
46371
46623
  const file = stateFilePath3(veskDir);
46372
- mkdirSync12(dirname19(file), { recursive: true });
46373
- writeFileSync15(file, JSON.stringify(state, null, 2) + "\n", "utf-8");
46624
+ mkdirSync13(dirname19(file), { recursive: true });
46625
+ writeFileSync16(file, JSON.stringify(state, null, 2) + "\n", "utf-8");
46374
46626
  }
46375
46627
  function eqIgnoreCase3(a, b) {
46376
46628
  return String(a || "").toLowerCase() === String(b || "").toLowerCase();
@@ -46389,16 +46641,16 @@ function validatePackageSpec3(pkg) {
46389
46641
  return null;
46390
46642
  }
46391
46643
  function findConfigFile3(projectDir2) {
46392
- const ts9 = resolve30(projectDir2, "vesk.config.ts");
46393
- if (existsSync30(ts9))
46644
+ const ts9 = resolve31(projectDir2, "vesk.config.ts");
46645
+ if (existsSync32(ts9))
46394
46646
  return { path: ts9, isTs: true };
46395
- const js = resolve30(projectDir2, "vesk.config.js");
46396
- if (existsSync30(js))
46647
+ const js = resolve31(projectDir2, "vesk.config.js");
46648
+ if (existsSync32(js))
46397
46649
  return { path: js, isTs: false };
46398
46650
  return { path: null, isTs: false };
46399
46651
  }
46400
46652
  function checkpointDir(veskDir) {
46401
- return join16(resolve30(veskDir), "checkpoints");
46653
+ return join18(resolve31(veskDir), "checkpoints");
46402
46654
  }
46403
46655
  function findMatchingBrace2(src2, openIdx) {
46404
46656
  let inStr = null;
@@ -46527,9 +46779,9 @@ function jsonError(message, extra) {
46527
46779
  return JSON.stringify({ ok: false, error: message, ...extra || {} });
46528
46780
  }
46529
46781
  function createVeskTools(deps) {
46530
- const projectDir2 = resolve30(deps.projectDir);
46531
- const appDir = resolve30(deps.appDir);
46532
- const veskDir = resolve30(deps.veskDir);
46782
+ const projectDir2 = resolve31(deps.projectDir);
46783
+ const appDir = resolve31(deps.appDir);
46784
+ const veskDir = resolve31(deps.veskDir);
46533
46785
  const tools = [
46534
46786
  // 1. vesk.inspectProject
46535
46787
  {
@@ -46542,16 +46794,16 @@ function createVeskTools(deps) {
46542
46794
  },
46543
46795
  async execute(_args) {
46544
46796
  try {
46545
- const projExists = existsSync30(projectDir2);
46797
+ const projExists = existsSync32(projectDir2);
46546
46798
  const projEntries = projExists ? readdirSync10(projectDir2, { withFileTypes: true }).map((e) => e.isDirectory() ? e.name + "/" : e.name) : [];
46547
- const appExists = existsSync30(appDir);
46799
+ const appExists = existsSync32(appDir);
46548
46800
  const appEntries = appExists ? readdirSync10(appDir, { withFileTypes: true }).map((e) => e.isDirectory() ? e.name + "/" : e.name) : [];
46549
- const veskExists = existsSync30(veskDir);
46801
+ const veskExists = existsSync32(veskDir);
46550
46802
  const veskEntries = veskExists ? readdirSync10(veskDir, { withFileTypes: true }).map((e) => e.isDirectory() ? e.name + "/" : e.name) : [];
46551
46803
  const cfgInfo = findConfigFile3(projectDir2);
46552
46804
  let configSource = null;
46553
46805
  let configExists = false;
46554
- if (cfgInfo.path && existsSync30(cfgInfo.path)) {
46806
+ if (cfgInfo.path && existsSync32(cfgInfo.path)) {
46555
46807
  configExists = true;
46556
46808
  try {
46557
46809
  configSource = readFileSync28(cfgInfo.path, "utf-8").slice(0, 8e3);
@@ -46560,8 +46812,8 @@ function createVeskTools(deps) {
46560
46812
  }
46561
46813
  }
46562
46814
  let packageJson = null;
46563
- const pkgPath = resolve30(projectDir2, "package.json");
46564
- if (existsSync30(pkgPath)) {
46815
+ const pkgPath = resolve31(projectDir2, "package.json");
46816
+ if (existsSync32(pkgPath)) {
46565
46817
  try {
46566
46818
  packageJson = JSON.parse(readFileSync28(pkgPath, "utf-8"));
46567
46819
  } catch {
@@ -46643,7 +46895,7 @@ function createVeskTools(deps) {
46643
46895
  resolved = resolveWithin3(appDir, rel);
46644
46896
  if (!resolved)
46645
46897
  return jsonError("path escapes project root", { path: rel });
46646
- if (!existsSync30(resolved))
46898
+ if (!existsSync32(resolved))
46647
46899
  return jsonError("not found", { path: rel });
46648
46900
  const st = statSync19(resolved);
46649
46901
  if (st.isDirectory()) {
@@ -46684,7 +46936,7 @@ function createVeskTools(deps) {
46684
46936
  }
46685
46937
  }
46686
46938
  const info = findConfigFile3(projectDir2);
46687
- if (!info.path || !existsSync30(info.path)) {
46939
+ if (!info.path || !existsSync32(info.path)) {
46688
46940
  return jsonOk({ ok: true, path: null, exists: false, source: "", config: {} });
46689
46941
  }
46690
46942
  const source = readFileSync28(info.path, "utf-8");
@@ -46720,17 +46972,17 @@ function createVeskTools(deps) {
46720
46972
  target = info.path;
46721
46973
  const rel = target.startsWith(projectDir2 + sep6) ? target.slice(projectDir2.length + 1) : "vesk.config.ts";
46722
46974
  const contained = resolveWithin3(projectDir2, rel);
46723
- if (!contained && target !== resolve30(projectDir2, "vesk.config.ts") && target !== resolve30(projectDir2, "vesk.config.js")) {
46975
+ if (!contained && target !== resolve31(projectDir2, "vesk.config.ts") && target !== resolve31(projectDir2, "vesk.config.js")) {
46724
46976
  return jsonError("path escapes project root");
46725
46977
  }
46726
46978
  } else {
46727
- target = resolve30(projectDir2, "vesk.config.ts");
46979
+ target = resolve31(projectDir2, "vesk.config.ts");
46728
46980
  const contained = resolveWithin3(projectDir2, "vesk.config.ts");
46729
46981
  if (!contained)
46730
46982
  return jsonError("path escapes project root");
46731
46983
  }
46732
- mkdirSync12(dirname19(target), { recursive: true });
46733
- writeFileSync15(target, source, "utf-8");
46984
+ mkdirSync13(dirname19(target), { recursive: true });
46985
+ writeFileSync16(target, source, "utf-8");
46734
46986
  return jsonOk({ ok: true, path: target, source });
46735
46987
  }
46736
46988
  if (typeof a.key === "string" && a.key) {
@@ -46751,7 +47003,7 @@ function createVeskTools(deps) {
46751
47003
  return jsonError("could not safely edit the config object; use the source editor");
46752
47004
  if (patched === current2)
46753
47005
  return jsonOk({ ok: true, path: info.path, source: patched, unchanged: true });
46754
- writeFileSync15(info.path, patched, "utf-8");
47006
+ writeFileSync16(info.path, patched, "utf-8");
46755
47007
  return jsonOk({ ok: true, path: info.path, source: patched });
46756
47008
  }
46757
47009
  return jsonError("expected { source } or { key, value }");
@@ -47011,9 +47263,9 @@ function createVeskTools(deps) {
47011
47263
  } catch {
47012
47264
  }
47013
47265
  const dir = checkpointDir(veskDir);
47014
- mkdirSync12(dir, { recursive: true });
47266
+ mkdirSync13(dir, { recursive: true });
47015
47267
  const id = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
47016
- const file = join16(dir, `${id}.json`);
47268
+ const file = join18(dir, `${id}.json`);
47017
47269
  const check = resolveWithin3(dir, `${id}.json`);
47018
47270
  if (!check)
47019
47271
  return jsonError("path escapes project root");
@@ -47025,7 +47277,7 @@ function createVeskTools(deps) {
47025
47277
  appDir,
47026
47278
  veskDir
47027
47279
  };
47028
- writeFileSync15(file, JSON.stringify(payload, null, 2) + "\n", "utf-8");
47280
+ writeFileSync16(file, JSON.stringify(payload, null, 2) + "\n", "utf-8");
47029
47281
  return jsonOk({ ok: true, checkpointId: id, message: payload.message, timestamp: payload.timestamp });
47030
47282
  } catch (e) {
47031
47283
  return jsonError(e instanceof Error ? e.message : String(e));
@@ -47062,11 +47314,11 @@ function createVeskTools(deps) {
47062
47314
  } catch {
47063
47315
  }
47064
47316
  const dir = checkpointDir(veskDir);
47065
- const file = join16(dir, `${checkpointId}.json`);
47317
+ const file = join18(dir, `${checkpointId}.json`);
47066
47318
  const contained = resolveWithin3(dir, `${checkpointId}.json`);
47067
47319
  if (!contained)
47068
47320
  return jsonError("path escapes project root");
47069
- if (!existsSync30(file))
47321
+ if (!existsSync32(file))
47070
47322
  return jsonError(`checkpoint not found: ${checkpointId}`, { checkpointId });
47071
47323
  const raw2 = readFileSync28(file, "utf-8");
47072
47324
  let data2;
@@ -47087,16 +47339,16 @@ function createVeskTools(deps) {
47087
47339
 
47088
47340
  // ../adapter/dist/css.js
47089
47341
  init_scan();
47090
- import { readFileSync as readFileSync29, existsSync as existsSync31 } from "node:fs";
47091
- import { resolve as resolve31 } from "node:path";
47342
+ import { readFileSync as readFileSync29, existsSync as existsSync33 } from "node:fs";
47343
+ import { resolve as resolve32 } from "node:path";
47092
47344
  var TAILWIND_CSS_URL2 = "/_vesk/static/_tailwind.css";
47093
47345
  var GLOBAL_CSS_URL2 = "/_vesk/static/global.css";
47094
47346
  function resolveUserCssPath2(appDir) {
47095
- const cssSrc = resolve31(appDir, "..", "src", "global.css");
47096
- if (existsSync31(cssSrc))
47347
+ const cssSrc = resolve32(appDir, "..", "src", "global.css");
47348
+ if (existsSync33(cssSrc))
47097
47349
  return cssSrc;
47098
- const altCssSrc = resolve31(appDir, "..", "src", "app.css");
47099
- if (existsSync31(altCssSrc))
47350
+ const altCssSrc = resolve32(appDir, "..", "src", "app.css");
47351
+ if (existsSync33(altCssSrc))
47100
47352
  return altCssSrc;
47101
47353
  return null;
47102
47354
  }
@@ -47137,8 +47389,8 @@ function stripTailwindDirectives2(css) {
47137
47389
  // ../adapter/dist/hmr.js
47138
47390
  init_client_codegen();
47139
47391
  import { WebSocketServer } from "ws";
47140
- import { readFileSync as readFileSync30, existsSync as existsSync32, writeFileSync as writeFileSync16 } from "node:fs";
47141
- import { resolve as resolve32, dirname as dirname20 } from "node:path";
47392
+ import { readFileSync as readFileSync30, existsSync as existsSync34, writeFileSync as writeFileSync17 } from "node:fs";
47393
+ import { resolve as resolve33, dirname as dirname20 } from "node:path";
47142
47394
  import { fileURLToPath as fileURLToPath7 } from "node:url";
47143
47395
  init_paths();
47144
47396
 
@@ -47361,8 +47613,8 @@ function buildErrorPayload(error, filename, opts = {}) {
47361
47613
  if (line !== null && line >= 1 && typeof opts.appDir === "string") {
47362
47614
  let src2;
47363
47615
  try {
47364
- const absPath = resolve32(opts.appDir, file);
47365
- if (existsSync32(absPath))
47616
+ const absPath = resolve33(opts.appDir, file);
47617
+ if (existsSync34(absPath))
47366
47618
  src2 = readFileSync30(absPath, "utf-8");
47367
47619
  } catch {
47368
47620
  src2 = void 0;
@@ -47376,7 +47628,7 @@ function buildErrorPayload(error, filename, opts = {}) {
47376
47628
  }
47377
47629
  }
47378
47630
  const tipsData = suggestFor(message);
47379
- const filePath = typeof opts.appDir === "string" ? resolve32(opts.appDir, file) : void 0;
47631
+ const filePath = typeof opts.appDir === "string" ? resolve33(opts.appDir, file) : void 0;
47380
47632
  const cleanMessage = filePath && message.endsWith(` in ${filePath}`) ? message.slice(0, -` in ${filePath}`.length).trim() : message.endsWith(` in ${file}`) ? message.slice(0, -` in ${file}`.length).trim() : message;
47381
47633
  const payload = {
47382
47634
  file,
@@ -47426,13 +47678,13 @@ function buildCodeframe2(src2, line, column, context = 5) {
47426
47678
 
47427
47679
  // src/build-packages.ts
47428
47680
  import { spawnSync } from "node:child_process";
47429
- import { cpSync, existsSync as existsSync33, mkdirSync as mkdirSync13, readFileSync as readFileSync31, readdirSync as readdirSync11, statSync as statSync20, writeFileSync as writeFileSync17 } from "node:fs";
47681
+ import { cpSync, existsSync as existsSync35, mkdirSync as mkdirSync14, readFileSync as readFileSync31, readdirSync as readdirSync11, statSync as statSync20, writeFileSync as writeFileSync18 } from "node:fs";
47430
47682
  import { createRequire as createRequire5 } from "node:module";
47431
- import { dirname as dirname21, join as join17, resolve as resolve33 } from "node:path";
47683
+ import { dirname as dirname21, join as join19, resolve as resolve34 } from "node:path";
47432
47684
  import { fileURLToPath as fileURLToPath8 } from "node:url";
47433
47685
  var require2 = createRequire5(import.meta.url);
47434
47686
  var __dirname9 = dirname21(fileURLToPath8(import.meta.url));
47435
- var root2 = resolve33(__dirname9, "..", "..", "..");
47687
+ var root2 = resolve34(__dirname9, "..", "..", "..");
47436
47688
  var PACKAGES = {
47437
47689
  // types first — it is a dependency-free leaf that compiler and adapter
47438
47690
  // import for their shared type definitions.
@@ -47452,7 +47704,7 @@ var PACKAGES = {
47452
47704
  function newestSourceMtime(srcDir) {
47453
47705
  let newest = 0;
47454
47706
  for (const name of readdirSync11(srcDir)) {
47455
- const p = join17(srcDir, name);
47707
+ const p = join19(srcDir, name);
47456
47708
  const st = statSync20(p);
47457
47709
  if (st.isDirectory()) {
47458
47710
  newest = Math.max(newest, newestSourceMtime(p));
@@ -47463,11 +47715,11 @@ function newestSourceMtime(srcDir) {
47463
47715
  return newest;
47464
47716
  }
47465
47717
  function distStale(pkgDir, entry) {
47466
- const distIndex = join17(pkgDir, "dist", `${entry}.js`);
47467
- if (!existsSync33(distIndex)) return true;
47468
- const distPkg = join17(pkgDir, "dist", "package.json");
47469
- const distStamp = Math.max(statSync20(distIndex).mtimeMs, existsSync33(distPkg) ? statSync20(distPkg).mtimeMs : 0);
47470
- return newestSourceMtime(join17(pkgDir, "src")) > distStamp;
47718
+ const distIndex = join19(pkgDir, "dist", `${entry}.js`);
47719
+ if (!existsSync35(distIndex)) return true;
47720
+ const distPkg = join19(pkgDir, "dist", "package.json");
47721
+ const distStamp = Math.max(statSync20(distIndex).mtimeMs, existsSync35(distPkg) ? statSync20(distPkg).mtimeMs : 0);
47722
+ return newestSourceMtime(join19(pkgDir, "src")) > distStamp;
47471
47723
  }
47472
47724
  function distPackageJson(pkgName, entry, serverEntry, version2) {
47473
47725
  const exports = {
@@ -47490,24 +47742,24 @@ function distPackageJson(pkgName, entry, serverEntry, version2) {
47490
47742
  }
47491
47743
  function buildPackages(force = false) {
47492
47744
  for (const [pkg, cfg] of Object.entries(PACKAGES)) {
47493
- const pkgDir = resolve33(root2, "packages", pkg);
47494
- if (!existsSync33(join17(pkgDir, "src"))) continue;
47745
+ const pkgDir = resolve34(root2, "packages", pkg);
47746
+ if (!existsSync35(join19(pkgDir, "src"))) continue;
47495
47747
  if (!force && !distStale(pkgDir, cfg.entry)) continue;
47496
47748
  console.log(`[build] ${cfg.name} -> tsc`);
47497
47749
  const tscBin = require2.resolve("typescript/bin/tsc");
47498
- const result2 = spawnSync(process.execPath, [tscBin, "-p", join17(pkgDir, "tsconfig.build.json")], {
47750
+ const result2 = spawnSync(process.execPath, [tscBin, "-p", join19(pkgDir, "tsconfig.build.json")], {
47499
47751
  stdio: "inherit"
47500
47752
  });
47501
47753
  if (result2.status !== 0) {
47502
47754
  throw new Error(`tsc failed for ${cfg.name}`);
47503
47755
  }
47504
- const distDir = join17(pkgDir, "dist");
47756
+ const distDir = join19(pkgDir, "dist");
47505
47757
  for (const c of cfg.copy || []) {
47506
- const to = join17(distDir, c.to);
47507
- mkdirSync13(dirname21(to), { recursive: true });
47508
- cpSync(join17(pkgDir, c.from), to, { recursive: true });
47758
+ const to = join19(distDir, c.to);
47759
+ mkdirSync14(dirname21(to), { recursive: true });
47760
+ cpSync(join19(pkgDir, c.from), to, { recursive: true });
47509
47761
  }
47510
- const srcPkg = JSON.parse(readFileSync31(join17(pkgDir, "package.json"), "utf-8"));
47762
+ const srcPkg = JSON.parse(readFileSync31(join19(pkgDir, "package.json"), "utf-8"));
47511
47763
  if (pkg === "lucide-vesk") {
47512
47764
  const lucideDistPkg = {
47513
47765
  name: srcPkg.name,
@@ -47521,9 +47773,9 @@ function buildPackages(force = false) {
47521
47773
  "./package.json": "./package.json"
47522
47774
  }
47523
47775
  };
47524
- writeFileSync17(join17(distDir, "package.json"), JSON.stringify(lucideDistPkg, null, 2) + "\n");
47776
+ writeFileSync18(join19(distDir, "package.json"), JSON.stringify(lucideDistPkg, null, 2) + "\n");
47525
47777
  } else {
47526
- writeFileSync17(join17(distDir, "package.json"), distPackageJson(cfg.name, cfg.entry, cfg.serverEntry, srcPkg.version || "1.0.0"));
47778
+ writeFileSync18(join19(distDir, "package.json"), distPackageJson(cfg.name, cfg.entry, cfg.serverEntry, srcPkg.version || "1.0.0"));
47527
47779
  }
47528
47780
  console.log(`[build] ${cfg.name} -> dist`);
47529
47781
  }
@@ -47531,13 +47783,13 @@ function buildPackages(force = false) {
47531
47783
  function ensurePackagesBuilt() {
47532
47784
  buildPackages(false);
47533
47785
  }
47534
- if (process.argv[1] && resolve33(process.argv[1]) === fileURLToPath8(import.meta.url)) {
47786
+ if (process.argv[1] && resolve34(process.argv[1]) === fileURLToPath8(import.meta.url)) {
47535
47787
  buildPackages(process.argv.includes("--force"));
47536
47788
  }
47537
47789
 
47538
47790
  // src/action-handler.ts
47539
- import { existsSync as existsSync34, readFileSync as readFileSync32, readdirSync as readdirSync12 } from "node:fs";
47540
- import { resolve as resolve34, join as join18 } from "node:path";
47791
+ import { existsSync as existsSync36, readFileSync as readFileSync32, readdirSync as readdirSync12 } from "node:fs";
47792
+ import { resolve as resolve35, join as join20 } from "node:path";
47541
47793
 
47542
47794
  // ../compiler/dist/server-cookies.js
47543
47795
  function parseCookies3(str3) {
@@ -47593,9 +47845,9 @@ function issuesToFieldMap2(issues) {
47593
47845
  function actionCssUrls(appDirPath) {
47594
47846
  let tailwind = true;
47595
47847
  try {
47596
- const veskDir = join18(resolve34(appDirPath, ".."), ".vesk");
47597
- const statePath = join18(veskDir, "plugins.json");
47598
- if (existsSync34(statePath)) {
47848
+ const veskDir = join20(resolve35(appDirPath, ".."), ".vesk");
47849
+ const statePath = join20(veskDir, "plugins.json");
47850
+ if (existsSync36(statePath)) {
47599
47851
  const raw2 = readFileSync32(statePath, "utf-8");
47600
47852
  const state = JSON.parse(raw2);
47601
47853
  const entries = state?.plugins || [];
@@ -47634,8 +47886,8 @@ function pageSourcesFor(appDirPath, routeTree) {
47634
47886
  const out = [];
47635
47887
  function walk6(nodes) {
47636
47888
  for (const node of nodes) {
47637
- if (node.page) out.push(resolve34(appDirPath, node.sourceDir, "page.vsk"));
47638
- if (node.layout) out.push(resolve34(appDirPath, node.sourceDir, "layout.vsk"));
47889
+ if (node.page) out.push(resolve35(appDirPath, node.sourceDir, "page.vsk"));
47890
+ if (node.layout) out.push(resolve35(appDirPath, node.sourceDir, "layout.vsk"));
47639
47891
  walk6(node.children);
47640
47892
  }
47641
47893
  }
@@ -47643,7 +47895,7 @@ function pageSourcesFor(appDirPath, routeTree) {
47643
47895
  return out;
47644
47896
  }
47645
47897
  function walkVskFiles(dir, out, seen) {
47646
- if (!existsSync34(dir)) return;
47898
+ if (!existsSync36(dir)) return;
47647
47899
  let entries;
47648
47900
  try {
47649
47901
  entries = readdirSync12(dir, { withFileTypes: true });
@@ -47651,7 +47903,7 @@ function walkVskFiles(dir, out, seen) {
47651
47903
  return;
47652
47904
  }
47653
47905
  for (const entry of entries) {
47654
- const full = resolve34(dir, entry.name);
47906
+ const full = resolve35(dir, entry.name);
47655
47907
  if (seen.has(full)) continue;
47656
47908
  seen.add(full);
47657
47909
  if (entry.isDirectory()) {
@@ -47671,14 +47923,14 @@ function candidateSources(appDirPath, routeTree) {
47671
47923
  seen.add(src2);
47672
47924
  out.push(src2);
47673
47925
  }
47674
- const projectRoot = resolve34(appDirPath, "..");
47675
- for (const dir of [resolve34(projectRoot, "components"), appDirPath, projectRoot]) {
47926
+ const projectRoot = resolve35(appDirPath, "..");
47927
+ for (const dir of [resolve35(projectRoot, "components"), appDirPath, projectRoot]) {
47676
47928
  walkVskFiles(dir, out, seen);
47677
47929
  }
47678
47930
  return out;
47679
47931
  }
47680
47932
  function registerSource(sourcePath2) {
47681
- if (!existsSync34(sourcePath2)) return;
47933
+ if (!existsSync36(sourcePath2)) return;
47682
47934
  try {
47683
47935
  compileFile(readFileSync32(sourcePath2, "utf-8"), { sourcePath: sourcePath2 });
47684
47936
  } catch {
@@ -47689,8 +47941,8 @@ function ensureActionRegistered(actionId, pagePathname, appDirPath, routeTree) {
47689
47941
  const match = matchUrl(routeTree, pagePathname);
47690
47942
  if (match) {
47691
47943
  for (let i = match.nodes.length - 1; i >= 0; i--) {
47692
- registerSource(resolve34(appDirPath, match.nodes[i].sourceDir, "page.vsk"));
47693
- registerSource(resolve34(appDirPath, match.nodes[i].sourceDir, "layout.vsk"));
47944
+ registerSource(resolve35(appDirPath, match.nodes[i].sourceDir, "page.vsk"));
47945
+ registerSource(resolve35(appDirPath, match.nodes[i].sourceDir, "layout.vsk"));
47694
47946
  }
47695
47947
  }
47696
47948
  if (getAction2(actionId)) return;
@@ -47716,16 +47968,16 @@ async function renderPageHtml(pagePathname, params, ctx2) {
47716
47968
  let head = "";
47717
47969
  for (let i = chain.length - 1; i >= 0; i--) {
47718
47970
  const node = chain[i];
47719
- const pageFilePath = resolve34(ctx2.appDirPath, node.sourceDir, "page.vsk");
47720
- const layoutFilePath = resolve34(ctx2.appDirPath, node.sourceDir, "layout.vsk");
47721
- if (i === chain.length - 1 && node.page && existsSync34(pageFilePath)) {
47971
+ const pageFilePath = resolve35(ctx2.appDirPath, node.sourceDir, "page.vsk");
47972
+ const layoutFilePath = resolve35(ctx2.appDirPath, node.sourceDir, "layout.vsk");
47973
+ if (i === chain.length - 1 && node.page && existsSync36(pageFilePath)) {
47722
47974
  const src3 = readFileSync32(pageFilePath, "utf-8");
47723
47975
  const compName2 = resolveComponentName(src3) || node.page;
47724
47976
  const result2 = await renderPage(src3, compName2, { params }, /* @__PURE__ */ new Map(), { hydrate: true, sourcePath: pageFilePath });
47725
47977
  body = result2.body;
47726
47978
  head = result2.head || "";
47727
47979
  }
47728
- if (node.layout && existsSync34(layoutFilePath)) {
47980
+ if (node.layout && existsSync36(layoutFilePath)) {
47729
47981
  const src3 = readFileSync32(layoutFilePath, "utf-8");
47730
47982
  const compName2 = resolveComponentName(src3) || node.layout;
47731
47983
  const result2 = await renderPage(src3, compName2, { children: body }, /* @__PURE__ */ new Map(), { hydrate: true, sourcePath: layoutFilePath });
@@ -47733,7 +47985,7 @@ async function renderPageHtml(pagePathname, params, ctx2) {
47733
47985
  head = (result2.head || "") + head;
47734
47986
  }
47735
47987
  }
47736
- const hasLayout = chain.some((n) => n.layout && existsSync34(resolve34(ctx2.appDirPath, n.sourceDir, "layout.vsk")));
47988
+ const hasLayout = chain.some((n) => n.layout && existsSync36(resolve35(ctx2.appDirPath, n.sourceDir, "layout.vsk")));
47737
47989
  if (hasLayout) {
47738
47990
  const secMeta = securityMeta(ctx2.security);
47739
47991
  const headBlock = await applyHeadInjects(
@@ -47757,9 +48009,9 @@ ${prettifyHtml(body)}
47757
48009
  }
47758
48010
  const leaf = chain.find((n) => n.page);
47759
48011
  if (!leaf) return null;
47760
- const src2 = readFileSync32(resolve34(ctx2.appDirPath, leaf.sourceDir, "page.vsk"), "utf-8");
48012
+ const src2 = readFileSync32(resolve35(ctx2.appDirPath, leaf.sourceDir, "page.vsk"), "utf-8");
47761
48013
  const compName = resolveComponentName(src2) || leaf.page;
47762
- const html = await renderFullPage(src2, compName, { params }, /* @__PURE__ */ new Map(), { hydrate: true, clientScriptUrl: "/_vesk/client.js", cssUrls: actionCssUrls(ctx2.appDirPath), security: ctx2.security, sourcePath: resolve34(ctx2.appDirPath, leaf.sourceDir, "page.vsk"), plugins: ctx2.plugins });
48014
+ const html = await renderFullPage(src2, compName, { params }, /* @__PURE__ */ new Map(), { hydrate: true, clientScriptUrl: "/_vesk/client.js", cssUrls: actionCssUrls(ctx2.appDirPath), security: ctx2.security, sourcePath: resolve35(ctx2.appDirPath, leaf.sourceDir, "page.vsk"), plugins: ctx2.plugins });
47763
48015
  return applyHtmlPlugins(html.replace("</body>", ' <script type="module" src="/_vesk/hmr.js"></script>\n</body>'), ctx2.plugins, { sourcePath: ctx2.url.pathname });
47764
48016
  }
47765
48017
  async function handleActionRequest(req, res, ctx2) {
@@ -47941,14 +48193,14 @@ function buildDevErrorPayload(input) {
47941
48193
  function resolveRuntimeDir(projectDir2) {
47942
48194
  const candidates = [
47943
48195
  // installed app layout
47944
- resolve35(projectDir2, "node_modules", "@vesk", "runtime"),
48196
+ resolve36(projectDir2, "node_modules", "@vesk", "runtime"),
47945
48197
  // monorepo checkout (tests/probes run from the repo root)
47946
- resolve35(import.meta.dirname ?? ".", "..", "..", "runtime", "dist")
48198
+ resolve36(import.meta.dirname ?? ".", "..", "..", "runtime", "dist")
47947
48199
  ];
47948
48200
  for (const dir of candidates) {
47949
- if (existsSync35(join19(dir, "ripple-runtime.js"))) return dir;
47950
- const distDir = join19(dir, "dist");
47951
- if (existsSync35(join19(distDir, "ripple-runtime.js"))) return distDir;
48201
+ if (existsSync37(join21(dir, "ripple-runtime.js"))) return dir;
48202
+ const distDir = join21(dir, "dist");
48203
+ if (existsSync37(join21(distDir, "ripple-runtime.js"))) return distDir;
47952
48204
  }
47953
48205
  return null;
47954
48206
  }
@@ -48098,10 +48350,10 @@ function collectRoutePaths(nodes, out = []) {
48098
48350
  return out;
48099
48351
  }
48100
48352
  function countFilesNamed(dir, name) {
48101
- if (!existsSync35(dir)) return 0;
48353
+ if (!existsSync37(dir)) return 0;
48102
48354
  let n = 0;
48103
48355
  for (const entry of readdirSync13(dir, { withFileTypes: true })) {
48104
- const p = join19(dir, entry.name);
48356
+ const p = join21(dir, entry.name);
48105
48357
  if (entry.isDirectory()) n += countFilesNamed(p, name);
48106
48358
  else if (entry.name === name) n++;
48107
48359
  }
@@ -48112,8 +48364,8 @@ async function startDevServer(port2, projectDir2, config, host2) {
48112
48364
  if (!process.env.NODE_ENV) process.env.NODE_ENV = "development";
48113
48365
  const secCfg = config.security || {};
48114
48366
  const maxBodyBytes2 = (typeof secCfg.maxBodyBytes === "number" ? secCfg.maxBodyBytes : void 0) || DEFAULT_MAX_BODY_BYTES;
48115
- const appDirPath = join19(projectDir2, "app");
48116
- const publicDir = join19(projectDir2, "public");
48367
+ const appDirPath = join21(projectDir2, "app");
48368
+ const publicDir = join21(projectDir2, "public");
48117
48369
  installMdReadHook2([publicDir]);
48118
48370
  try {
48119
48371
  ensurePackagesBuilt();
@@ -48126,7 +48378,7 @@ async function startDevServer(port2, projectDir2, config, host2) {
48126
48378
  process.exit(1);
48127
48379
  }
48128
48380
  const runtimeDir = runtimeDirUnchecked;
48129
- const veskStateDir = join19(projectDir2, ".vesk");
48381
+ const veskStateDir = join21(projectDir2, ".vesk");
48130
48382
  const configPluginsRaw = config.plugins || [];
48131
48383
  const configPluginNames = configPluginsRaw.map((p) => typeof p === "string" ? p : p?.name).filter((n) => !!n);
48132
48384
  const rawDevPlugins = config.plugins || [];
@@ -48138,6 +48390,83 @@ async function startDevServer(port2, projectDir2, config, host2) {
48138
48390
  return rawDevPlugins;
48139
48391
  }
48140
48392
  }
48393
+ let eventsFile = collectEventsFile2(appDirPath);
48394
+ let appEventsHandlers = {};
48395
+ async function reloadAppEvents() {
48396
+ eventsFile = collectEventsFile2(appDirPath);
48397
+ if (eventsFile) {
48398
+ try {
48399
+ appEventsHandlers = await loadEvents(eventsFile);
48400
+ } catch (e) {
48401
+ LOG.err(`events load error: ${e.message}`);
48402
+ appEventsHandlers = {};
48403
+ }
48404
+ } else {
48405
+ appEventsHandlers = {};
48406
+ }
48407
+ }
48408
+ function eventsStore() {
48409
+ const g2 = globalThis;
48410
+ if (!g2.__vesk_server_ctx) g2.__vesk_server_ctx = {};
48411
+ return g2.__vesk_server_ctx;
48412
+ }
48413
+ function makeEventCtx(overrides) {
48414
+ const store = eventsStore();
48415
+ return {
48416
+ server: null,
48417
+ port: port2,
48418
+ host: bindHost,
48419
+ locals: { ...store },
48420
+ serverLocals: store,
48421
+ set(key, value) {
48422
+ store[key] = value;
48423
+ return value;
48424
+ },
48425
+ get(key) {
48426
+ return store[key];
48427
+ },
48428
+ ...overrides
48429
+ };
48430
+ }
48431
+ let devServerRef = null;
48432
+ async function runAppStart(includePlugins) {
48433
+ const bootCtx = makeEventCtx({ server: devServerRef });
48434
+ try {
48435
+ await runEventHandlers(appEventsHandlers, "onStart", bootCtx);
48436
+ } catch (e) {
48437
+ LOG.err(`onStart error: ${e.message}`);
48438
+ }
48439
+ if (includePlugins) {
48440
+ for (const plugin of getActiveDevPlugins()) {
48441
+ if (typeof plugin.onStart === "function") {
48442
+ try {
48443
+ await plugin.onStart(bootCtx);
48444
+ } catch (e) {
48445
+ LOG.err(`plugin onStart error: ${e.message}`);
48446
+ }
48447
+ }
48448
+ }
48449
+ }
48450
+ }
48451
+ async function runAppStop(includePlugins) {
48452
+ const stopCtx = makeEventCtx({ server: devServerRef });
48453
+ try {
48454
+ await runEventHandlers(appEventsHandlers, "onStop", stopCtx);
48455
+ } catch (e) {
48456
+ LOG.err(`onStop error: ${e.message}`);
48457
+ }
48458
+ if (includePlugins) {
48459
+ for (const plugin of getActiveDevPlugins()) {
48460
+ if (typeof plugin.onStop === "function") {
48461
+ try {
48462
+ await plugin.onStop(stopCtx);
48463
+ } catch (e) {
48464
+ LOG.err(`plugin onStop error: ${e.message}`);
48465
+ }
48466
+ }
48467
+ }
48468
+ }
48469
+ }
48141
48470
  function isTailwindActive() {
48142
48471
  return isTailwindPlugin2(getActiveDevPlugins());
48143
48472
  }
@@ -48154,13 +48483,13 @@ async function startDevServer(port2, projectDir2, config, host2) {
48154
48483
  let devTailwindCssContent = "";
48155
48484
  let lastServedCssGlobal = "";
48156
48485
  let lastServedCssTailwind = "";
48157
- const srcDir = join19(projectDir2, "src");
48158
- const cssPath = join19(srcDir, "global.css");
48159
- const altCssPath = join19(srcDir, "app.css");
48486
+ const srcDir = join21(projectDir2, "src");
48487
+ const cssPath = join21(srcDir, "global.css");
48488
+ const altCssPath = join21(srcDir, "app.css");
48160
48489
  let rawCss = "";
48161
- if (existsSync35(cssPath)) {
48490
+ if (existsSync37(cssPath)) {
48162
48491
  rawCss = readFileSync33(cssPath, "utf-8");
48163
- } else if (existsSync35(altCssPath)) {
48492
+ } else if (existsSync37(altCssPath)) {
48164
48493
  rawCss = readFileSync33(altCssPath, "utf-8");
48165
48494
  }
48166
48495
  if (rawCss) {
@@ -48416,17 +48745,32 @@ async function startDevServer(port2, projectDir2, config, host2) {
48416
48745
  let debounceTimer = null;
48417
48746
  let cssDebounceTimer = null;
48418
48747
  const watchDirs = [appDirPath];
48419
- if (existsSync35(srcDir)) watchDirs.push(srcDir);
48748
+ if (existsSync37(srcDir)) watchDirs.push(srcDir);
48420
48749
  for (const watchDir of watchDirs) {
48421
48750
  watch(watchDir, { recursive: true }, (eventType, filename) => {
48422
48751
  if (!filename) return;
48423
48752
  const isVsk = filename.endsWith(".vsk") || filename.endsWith(".md") || filename.endsWith(".markdown");
48424
48753
  const isCss = filename.endsWith(".css");
48425
48754
  const isApiRoute = filename.endsWith(".ts") || filename.endsWith(".js") || filename.endsWith(".tsx");
48426
- if (!isVsk && !isCss && !isApiRoute) return;
48427
- const fullPath = filename.startsWith("/") ? filename : join19(watchDir, filename);
48428
- const fileExists = existsSync35(fullPath);
48429
- if (isVsk) {
48755
+ const isEvents = filename === "_events.ts" || filename === "_events.js";
48756
+ if (!isVsk && !isCss && !isApiRoute && !isEvents) return;
48757
+ const fullPath = filename.startsWith("/") ? filename : join21(watchDir, filename);
48758
+ const fileExists = existsSync37(fullPath);
48759
+ if (isEvents) {
48760
+ if (debounceTimer) clearTimeout(debounceTimer);
48761
+ debounceTimer = setTimeout(async () => {
48762
+ try {
48763
+ await runAppStop(false);
48764
+ await reloadAppEvents();
48765
+ await runAppStart(false);
48766
+ const bcast = globalThis.__vesk_broadcastHmr;
48767
+ if (typeof bcast === "function") bcast({ type: "reload" });
48768
+ LOG.info(`events reloaded (${filename})`);
48769
+ } catch (e) {
48770
+ LOG.err(`events reload error: ${e.message}`);
48771
+ }
48772
+ }, HMR_DEBOUNCE_MS);
48773
+ } else if (isVsk) {
48430
48774
  if (debounceTimer) clearTimeout(debounceTimer);
48431
48775
  debounceTimer = setTimeout(async () => {
48432
48776
  const t0 = Date.now();
@@ -48589,9 +48933,9 @@ Object.defineProperty(__components, ${JSON.stringify(cname)}, { get: () => __com
48589
48933
  ".json": "application/json",
48590
48934
  ".webmanifest": "application/manifest+json"
48591
48935
  };
48592
- const hmrJsPath = join19(runtimeDir, "hmr-client.js");
48593
- const hmrTsPath = join19(runtimeDir, "hmr-client.ts");
48594
- const hmrClientPath = existsSync35(hmrJsPath) ? hmrJsPath : existsSync35(hmrTsPath) ? hmrTsPath : null;
48936
+ const hmrJsPath = join21(runtimeDir, "hmr-client.js");
48937
+ const hmrTsPath = join21(runtimeDir, "hmr-client.ts");
48938
+ const hmrClientPath = existsSync37(hmrJsPath) ? hmrJsPath : existsSync37(hmrTsPath) ? hmrTsPath : null;
48595
48939
  function extractCompName2(src2) {
48596
48940
  return resolveComponentName(src2);
48597
48941
  }
@@ -48726,21 +49070,37 @@ Object.defineProperty(__components, ${JSON.stringify(cname)}, { get: () => __com
48726
49070
  return;
48727
49071
  }
48728
49072
  }
48729
- if (await handleActionRequest(req, res, { url, appDirPath, routeTree, security, maxBodyBytes: maxBodyBytes2, plugins: getActiveDevPlugins() })) {
48730
- return;
48731
- }
48732
49073
  if (url.pathname !== "/") {
48733
49074
  const staticPath = url.pathname.length > 1 ? resolveWithin2(publicDir, url.pathname.slice(1)) : null;
48734
- if (staticPath && existsSync35(staticPath) && statSync21(staticPath).isFile()) {
49075
+ if (staticPath && existsSync37(staticPath) && statSync21(staticPath).isFile()) {
48735
49076
  const ext = extname8(staticPath);
48736
49077
  res.writeHead(200, { "Content-Type": MIME3[ext] || "application/octet-stream" });
48737
49078
  res.end(readFileSync33(staticPath));
48738
49079
  return;
48739
49080
  }
48740
49081
  }
49082
+ const eventsCtx = makeEventCtx({
49083
+ request: new Request(`http://localhost:${port2}${req.url || "/"}`, {
49084
+ headers: req.headers,
49085
+ method: req.method || "GET"
49086
+ }),
49087
+ params: {},
49088
+ url,
49089
+ cookies: rawCtx.cookies
49090
+ });
49091
+ rawCtx.locals = eventsCtx.locals;
49092
+ globalThis.__vesk_request = eventsCtx;
49093
+ try {
49094
+ await runEventHandlers(appEventsHandlers, "onRequest", eventsCtx);
49095
+ } catch (e) {
49096
+ LOG.err(`onRequest error: ${e.message}`);
49097
+ }
49098
+ if (await handleActionRequest(req, res, { url, appDirPath, routeTree, security, maxBodyBytes: maxBodyBytes2, plugins: getActiveDevPlugins() })) {
49099
+ return;
49100
+ }
48741
49101
  const mwChain = collectMiddlewareChain(routeTree, url.pathname, appDirPath);
48742
- const apiDirPath = join19(appDirPath, "api");
48743
- if (url.pathname.startsWith("/api") && existsSync35(apiDirPath)) {
49102
+ const apiDirPath = join21(appDirPath, "api");
49103
+ if (url.pathname.startsWith("/api") && existsSync37(apiDirPath)) {
48744
49104
  const apiRoutes = await scanApiRoutes(apiDirPath);
48745
49105
  const apiMatch = matchApiUrl(apiRoutes, req.url || url.pathname);
48746
49106
  if (apiMatch) {
@@ -48767,7 +49127,7 @@ Object.defineProperty(__components, ${JSON.stringify(cname)}, { get: () => __com
48767
49127
  for (const [k, v] of Object.entries(req.headers)) {
48768
49128
  rawHeaders[k] = Array.isArray(v) ? v.join(", ") : v || "";
48769
49129
  }
48770
- let apiLocals = {};
49130
+ let apiLocals = Object.assign({}, eventsCtx?.locals || globalThis.__vesk_server_ctx || {});
48771
49131
  if (mwChain.length > 0) {
48772
49132
  const mwReq = new Request(requestUrl, { headers: rawHeaders, method: req.method || "GET" });
48773
49133
  try {
@@ -48815,8 +49175,8 @@ Object.defineProperty(__components, ${JSON.stringify(cname)}, { get: () => __com
48815
49175
  const rootNode = routeTree.find((n) => n.fullPath === "/");
48816
49176
  let notFoundHtml = null;
48817
49177
  if (rootNode && rootNode.notFound) {
48818
- const nfPath = resolve35(appDirPath, rootNode.sourceDir, "not-found.vsk");
48819
- if (existsSync35(nfPath)) {
49178
+ const nfPath = resolve36(appDirPath, rootNode.sourceDir, "not-found.vsk");
49179
+ if (existsSync37(nfPath)) {
48820
49180
  try {
48821
49181
  const nfSrc = readFileSync33(nfPath, "utf-8");
48822
49182
  const nfCompName = extractCompName2(nfSrc) || rootNode.notFound;
@@ -48855,9 +49215,9 @@ Object.defineProperty(__components, ${JSON.stringify(cname)}, { get: () => __com
48855
49215
  let props;
48856
49216
  for (let i = chain.length - 1; i >= 0; i--) {
48857
49217
  const node = chain[i];
48858
- const pageFilePath = resolve35(appDirPath, node.sourceDir, "page.vsk");
48859
- const layoutFilePath = resolve35(appDirPath, node.sourceDir, "layout.vsk");
48860
- if (i === chain.length - 1 && node.page && existsSync35(pageFilePath)) {
49218
+ const pageFilePath = resolve36(appDirPath, node.sourceDir, "page.vsk");
49219
+ const layoutFilePath = resolve36(appDirPath, node.sourceDir, "layout.vsk");
49220
+ if (i === chain.length - 1 && node.page && existsSync37(pageFilePath)) {
48861
49221
  const src2 = readFileSync33(pageFilePath, "utf-8");
48862
49222
  const compName = extractCompName2(src2) || node.page;
48863
49223
  const result2 = await renderPage(src2, compName, { params: matched.params }, /* @__PURE__ */ new Map(), { hydrate: true, sourcePath: pageFilePath });
@@ -48865,7 +49225,7 @@ Object.defineProperty(__components, ${JSON.stringify(cname)}, { get: () => __com
48865
49225
  head = result2.head || "";
48866
49226
  props = result2.props;
48867
49227
  }
48868
- if (node.layout && existsSync35(layoutFilePath)) {
49228
+ if (node.layout && existsSync37(layoutFilePath)) {
48869
49229
  const src2 = readFileSync33(layoutFilePath, "utf-8");
48870
49230
  const compName = extractCompName2(src2) || node.layout;
48871
49231
  const result2 = await renderPage(src2, compName, { children: body }, /* @__PURE__ */ new Map(), { hydrate: true, sourcePath: layoutFilePath });
@@ -48876,7 +49236,7 @@ Object.defineProperty(__components, ${JSON.stringify(cname)}, { get: () => __com
48876
49236
  if (forData) {
48877
49237
  return { html: "", props: props || { params: matched.params }, head };
48878
49238
  }
48879
- const hasLayout = chain.some((n) => n.layout && existsSync35(resolve35(appDirPath, n.sourceDir, "layout.vsk")));
49239
+ const hasLayout = chain.some((n) => n.layout && existsSync37(resolve36(appDirPath, n.sourceDir, "layout.vsk")));
48880
49240
  let html;
48881
49241
  if (hasLayout) {
48882
49242
  const ssrData = ssrSink3.snapshot();
@@ -48907,9 +49267,9 @@ ${prettifyHtml(body)}
48907
49267
  } else {
48908
49268
  const leaf = chain.find((n) => n.page);
48909
49269
  if (leaf) {
48910
- const src2 = readFileSync33(resolve35(appDirPath, leaf.sourceDir, "page.vsk"), "utf-8");
49270
+ const src2 = readFileSync33(resolve36(appDirPath, leaf.sourceDir, "page.vsk"), "utf-8");
48911
49271
  const compName = extractCompName2(src2) || leaf.page;
48912
- html = await renderFullPage(src2, compName, { params: matched.params }, /* @__PURE__ */ new Map(), { hydrate: true, clientScriptUrl: "/_vesk/client.js", cssUrls: activeCssUrls(), security, externalDataScript: storeDataScript, sourcePath: resolve35(appDirPath, leaf.sourceDir, "page.vsk"), plugins: getActiveDevPlugins() });
49272
+ html = await renderFullPage(src2, compName, { params: matched.params }, /* @__PURE__ */ new Map(), { hydrate: true, clientScriptUrl: "/_vesk/client.js", cssUrls: activeCssUrls(), security, externalDataScript: storeDataScript, sourcePath: resolve36(appDirPath, leaf.sourceDir, "page.vsk"), plugins: getActiveDevPlugins() });
48913
49273
  html = html.replace("</body>", ' <script type="module" src="/_vesk/hmr.js"></script>\n</body>');
48914
49274
  html = await applyHtmlPlugins(html, getActiveDevPlugins(), { sourcePath: url.pathname });
48915
49275
  } else {
@@ -48922,13 +49282,13 @@ ${prettifyHtml(body)}
48922
49282
  function renderSSRStream() {
48923
49283
  async function* raw2() {
48924
49284
  const chain = cleanChain;
48925
- const hasLayout = chain.some((n) => n.layout && existsSync35(resolve35(appDirPath, n.sourceDir, "layout.vsk")));
49285
+ const hasLayout = chain.some((n) => n.layout && existsSync37(resolve36(appDirPath, n.sourceDir, "layout.vsk")));
48926
49286
  if (!hasLayout) {
48927
49287
  const leaf = chain.find((n) => n.page);
48928
49288
  if (leaf) {
48929
- const src2 = readFileSync33(resolve35(appDirPath, leaf.sourceDir, "page.vsk"), "utf-8");
49289
+ const src2 = readFileSync33(resolve36(appDirPath, leaf.sourceDir, "page.vsk"), "utf-8");
48930
49290
  const compName = extractCompName2(src2) || leaf.page;
48931
- yield* renderPageStream(src2, compName, { params: matched.params }, /* @__PURE__ */ new Map(), { hydrate: true, clientScriptUrl: "/_vesk/client.js", cssUrls: activeCssUrls(), security, externalDataScript: storeDataScript, sourcePath: resolve35(appDirPath, leaf.sourceDir, "page.vsk"), plugins: getActiveDevPlugins() });
49291
+ yield* renderPageStream(src2, compName, { params: matched.params }, /* @__PURE__ */ new Map(), { hydrate: true, clientScriptUrl: "/_vesk/client.js", cssUrls: activeCssUrls(), security, externalDataScript: storeDataScript, sourcePath: resolve36(appDirPath, leaf.sourceDir, "page.vsk"), plugins: getActiveDevPlugins() });
48932
49292
  } else {
48933
49293
  throw new Error("No page or layout matched");
48934
49294
  }
@@ -48939,9 +49299,9 @@ ${prettifyHtml(body)}
48939
49299
  let props;
48940
49300
  for (let i = chain.length - 1; i >= 0; i--) {
48941
49301
  const node = chain[i];
48942
- const pageFilePath = resolve35(appDirPath, node.sourceDir, "page.vsk");
48943
- const layoutFilePath = resolve35(appDirPath, node.sourceDir, "layout.vsk");
48944
- if (i === chain.length - 1 && node.page && existsSync35(pageFilePath)) {
49302
+ const pageFilePath = resolve36(appDirPath, node.sourceDir, "page.vsk");
49303
+ const layoutFilePath = resolve36(appDirPath, node.sourceDir, "layout.vsk");
49304
+ if (i === chain.length - 1 && node.page && existsSync37(pageFilePath)) {
48945
49305
  const src2 = readFileSync33(pageFilePath, "utf-8");
48946
49306
  const compName = extractCompName2(src2) || node.page;
48947
49307
  const result2 = await renderPage(src2, compName, { params: matched.params }, /* @__PURE__ */ new Map(), { hydrate: true, sourcePath: pageFilePath });
@@ -48949,7 +49309,7 @@ ${prettifyHtml(body)}
48949
49309
  head = result2.head || "";
48950
49310
  props = result2.props;
48951
49311
  }
48952
- if (node.layout && existsSync35(layoutFilePath)) {
49312
+ if (node.layout && existsSync37(layoutFilePath)) {
48953
49313
  const src2 = readFileSync33(layoutFilePath, "utf-8");
48954
49314
  const compName = extractCompName2(src2) || node.layout;
48955
49315
  const result2 = await renderPage(src2, compName, { children: body }, /* @__PURE__ */ new Map(), { hydrate: true, sourcePath: layoutFilePath });
@@ -49079,8 +49439,8 @@ ${prettifyHtml(body)}
49079
49439
  for (let i = match.nodes.length - 1; i >= 0; i--) {
49080
49440
  const node = match.nodes[i];
49081
49441
  if (node.notFound) {
49082
- const nfPath = resolve35(appDirPath, node.sourceDir, "not-found.vsk");
49083
- if (existsSync35(nfPath)) {
49442
+ const nfPath = resolve36(appDirPath, node.sourceDir, "not-found.vsk");
49443
+ if (existsSync37(nfPath)) {
49084
49444
  try {
49085
49445
  const nfSrc = readFileSync33(nfPath, "utf-8");
49086
49446
  const nfCompName = extractCompName2(nfSrc) || node.notFound;
@@ -49102,8 +49462,8 @@ ${prettifyHtml(body)}
49102
49462
  for (let i = match.nodes.length - 1; i >= 0; i--) {
49103
49463
  const node = match.nodes[i];
49104
49464
  if (node.error) {
49105
- const errPath = resolve35(appDirPath, node.sourceDir, "error.vsk");
49106
- if (existsSync35(errPath)) {
49465
+ const errPath = resolve36(appDirPath, node.sourceDir, "error.vsk");
49466
+ if (existsSync37(errPath)) {
49107
49467
  try {
49108
49468
  const errSrc = readFileSync33(errPath, "utf-8");
49109
49469
  const errCompName = extractCompName2(errSrc) || node.error;
@@ -49128,6 +49488,17 @@ ${err.stack}</pre></body></html>`);
49128
49488
  }
49129
49489
  }
49130
49490
  });
49491
+ devServerRef = server2;
49492
+ try {
49493
+ await reloadAppEvents();
49494
+ } catch (e) {
49495
+ LOG.err(`events load error: ${e.message}`);
49496
+ }
49497
+ try {
49498
+ await runAppStart(true);
49499
+ } catch (e) {
49500
+ LOG.err(`boot onStart error: ${e.message}`);
49501
+ }
49131
49502
  server2.on("error", (e) => {
49132
49503
  if (e.code === "EADDRINUSE") {
49133
49504
  LOG.err(`port ${port2} is already in use \u2014 is another vesk dev server running?`);
@@ -49139,7 +49510,7 @@ ${err.stack}</pre></body></html>`);
49139
49510
  LOG.ok(`dev server at http://localhost:${port2} (listening on ${bindHost})`);
49140
49511
  const routes = collectRoutePaths(routeTree);
49141
49512
  const pageCount = countPages(routeTree);
49142
- const apiCount = countFilesNamed(join19(appDirPath, "api"), "route.ts");
49513
+ const apiCount = countFilesNamed(join21(appDirPath, "api"), "route.ts");
49143
49514
  LOG.info(`${projectDir2}`);
49144
49515
  LOG.info(`${pageCount} page${pageCount === 1 ? "" : "s"}: ${routes.join(", ") || "(none)"}`);
49145
49516
  if (apiCount > 0) LOG.info(`${apiCount} api route${apiCount === 1 ? "" : "s"} (app/api)`);
@@ -49173,6 +49544,23 @@ ${err.stack}</pre></body></html>`);
49173
49544
  if (ws.readyState === 1) ws.send(msg);
49174
49545
  }
49175
49546
  };
49547
+ let stopping = false;
49548
+ const shutdown2 = (signal) => {
49549
+ if (stopping) return;
49550
+ stopping = true;
49551
+ LOG.info(`dev server: ${signal} \u2014 stopping`);
49552
+ void (async () => {
49553
+ try {
49554
+ await runAppStop(true);
49555
+ } catch (e) {
49556
+ LOG.err(`shutdown onStop error: ${e.message}`);
49557
+ }
49558
+ server2.close(() => process.exit(0));
49559
+ })();
49560
+ setTimeout(() => process.exit(0), 3e3).unref();
49561
+ };
49562
+ process.on("SIGINT", () => shutdown2("SIGINT"));
49563
+ process.on("SIGTERM", () => shutdown2("SIGTERM"));
49176
49564
  await new Promise(() => {
49177
49565
  });
49178
49566
  }
@@ -49243,7 +49631,9 @@ __export(index_server_exports2, {
49243
49631
  buildRouteTree: () => buildRouteTree,
49244
49632
  clearActions: () => clearActions,
49245
49633
  clearIsrCache: () => clearIsrCache,
49634
+ clearServerContext: () => clearServerContext,
49246
49635
  clearSsrData: () => clearSsrData,
49636
+ clear_server_context: () => clear_server_context,
49247
49637
  componentIsr: () => componentIsr,
49248
49638
  configureLoadingIndicator: () => configureLoadingIndicator,
49249
49639
  cookies: () => cookies,
@@ -49269,6 +49659,8 @@ __export(index_server_exports2, {
49269
49659
  getActiveComponent: () => getActiveComponent,
49270
49660
  getLoadingError: () => getLoadingError,
49271
49661
  getLoadingProgress: () => getLoadingProgress,
49662
+ getServerContext: () => getServerContext,
49663
+ get_server_context: () => get_server_context,
49272
49664
  headers: () => headers,
49273
49665
  isFormAction: () => isFormAction,
49274
49666
  isLoadingActive: () => isLoadingActive,
@@ -49304,13 +49696,17 @@ __export(index_server_exports2, {
49304
49696
  runHooks: () => runHooks,
49305
49697
  safe_scope: () => safe_scope,
49306
49698
  scope: () => scope,
49699
+ serverLocals: () => serverLocals,
49700
+ server_locals: () => server_locals,
49307
49701
  set: () => set,
49308
49702
  setActiveComponent: () => setActiveComponent,
49703
+ setServerContext: () => setServerContext,
49309
49704
  setSignedCookie: () => setSignedCookie2,
49310
49705
  setSsrData: () => setSsrData,
49311
49706
  setSsrSink: () => setSsrSink,
49312
49707
  set_active_block: () => set_active_block,
49313
49708
  set_active_component: () => set_active_component,
49709
+ set_server_context: () => set_server_context,
49314
49710
  signCookie: () => signCookie2,
49315
49711
  tick: () => tick,
49316
49712
  track: () => track,
@@ -49336,6 +49732,7 @@ __export(index_server_exports2, {
49336
49732
  init_ripple_runtime();
49337
49733
  init_ripple_blocks();
49338
49734
  init_context();
49735
+ init_server_events();
49339
49736
  init_resource();
49340
49737
  init_portal();
49341
49738
  init_router();
@@ -49352,7 +49749,7 @@ init_action();
49352
49749
 
49353
49750
  // src/index.ts
49354
49751
  var __filename2 = fileURLToPath9(import.meta.url);
49355
- var __dirname10 = resolve37(__filename2, "..");
49752
+ var __dirname10 = resolve38(__filename2, "..");
49356
49753
  var args = process.argv.slice(2);
49357
49754
  var cmd = args[0];
49358
49755
  function usage(code = 0) {
@@ -49395,11 +49792,11 @@ if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
49395
49792
  }
49396
49793
  function loadEnvFiles(projectDir2) {
49397
49794
  const files = [
49398
- join21(projectDir2, ".env"),
49399
- join21(projectDir2, ".env.local")
49795
+ join23(projectDir2, ".env"),
49796
+ join23(projectDir2, ".env.local")
49400
49797
  ];
49401
49798
  for (const filePath of files) {
49402
- if (!existsSync36(filePath)) continue;
49799
+ if (!existsSync38(filePath)) continue;
49403
49800
  const content = readFileSync35(filePath, "utf-8");
49404
49801
  for (const line of content.split("\n")) {
49405
49802
  const trimmed = line.trim();
@@ -49419,11 +49816,11 @@ function loadEnvFiles(projectDir2) {
49419
49816
  }
49420
49817
  async function loadConfig(projectDir2) {
49421
49818
  loadEnvFiles(projectDir2);
49422
- const jsPath = join21(projectDir2, "vesk.config.js");
49423
- const tsPath = join21(projectDir2, "vesk.config.ts");
49819
+ const jsPath = join23(projectDir2, "vesk.config.js");
49820
+ const tsPath = join23(projectDir2, "vesk.config.ts");
49424
49821
  let configPath3 = null;
49425
- if (existsSync36(jsPath)) configPath3 = jsPath;
49426
- else if (existsSync36(tsPath)) configPath3 = tsPath;
49822
+ if (existsSync38(jsPath)) configPath3 = jsPath;
49823
+ else if (existsSync38(tsPath)) configPath3 = tsPath;
49427
49824
  if (!configPath3) return {};
49428
49825
  let raw2;
49429
49826
  if (configPath3.endsWith(".ts")) {
@@ -49433,9 +49830,9 @@ async function loadConfig(projectDir2) {
49433
49830
  js = js.replace(/import\s+\{[^}]*\}\s*from\s+['"]@vesk\/compiler['"]\s*;?\s*/g, "");
49434
49831
  js = `const { defineConfig, definePlugin, preset } = globalThis.__vesk_inject;
49435
49832
  ` + js;
49436
- const tmpFile = join21(projectDir2, ".vesk", "config.tmp.js");
49437
- mkdirSync15(dirname23(tmpFile), { recursive: true });
49438
- writeFileSync18(tmpFile, js, "utf-8");
49833
+ const tmpFile = join23(projectDir2, ".vesk", "config.tmp.js");
49834
+ mkdirSync16(dirname23(tmpFile), { recursive: true });
49835
+ writeFileSync19(tmpFile, js, "utf-8");
49439
49836
  globalThis.__vesk_inject = { defineConfig, definePlugin, preset };
49440
49837
  raw2 = (await import(tmpFile)).default;
49441
49838
  delete globalThis.__vesk_inject;
@@ -49455,9 +49852,9 @@ async function loadConfig(projectDir2) {
49455
49852
  }
49456
49853
  if (cmd === "build") {
49457
49854
  const projectDir2 = process.cwd();
49458
- const appDirPath = join21(projectDir2, "app");
49459
- const publicDir = join21(projectDir2, "public");
49460
- if (!existsSync36(appDirPath)) {
49855
+ const appDirPath = join23(projectDir2, "app");
49856
+ const publicDir = join23(projectDir2, "public");
49857
+ if (!existsSync38(appDirPath)) {
49461
49858
  console.error(`vesk build: no app/ directory found in ${projectDir2}`);
49462
49859
  process.exit(1);
49463
49860
  }
@@ -49527,8 +49924,8 @@ ${code}`;
49527
49924
  }
49528
49925
  if (cmd === "seo") {
49529
49926
  const projectDir2 = process.cwd();
49530
- const appDirPath = join21(projectDir2, "app");
49531
- if (!existsSync36(appDirPath)) {
49927
+ const appDirPath = join23(projectDir2, "app");
49928
+ if (!existsSync38(appDirPath)) {
49532
49929
  console.error(`vesk seo: no app/ directory found in ${projectDir2}`);
49533
49930
  process.exit(1);
49534
49931
  }
@@ -49542,8 +49939,8 @@ if (cmd === "seo") {
49542
49939
  }
49543
49940
  if (cmd === "typecheck") {
49544
49941
  const projectDir2 = process.cwd();
49545
- const appDirPath = join21(projectDir2, "app");
49546
- if (!existsSync36(appDirPath)) {
49942
+ const appDirPath = join23(projectDir2, "app");
49943
+ if (!existsSync38(appDirPath)) {
49547
49944
  console.error(`vesk typecheck: no app/ directory found in ${projectDir2}`);
49548
49945
  process.exit(1);
49549
49946
  }
@@ -49567,7 +49964,7 @@ if (cmd === "typecheck") {
49567
49964
  }
49568
49965
  if (cmd === "start") {
49569
49966
  const projectDir2 = process.cwd();
49570
- const outDir2 = join21(projectDir2, ".vesk");
49967
+ const outDir2 = join23(projectDir2, ".vesk");
49571
49968
  const port2 = parsePortArg(args);
49572
49969
  const host2 = parseHostArg(args);
49573
49970
  startProdServer(outDir2, { port: port2, host: host2 });
@@ -49576,14 +49973,14 @@ if (cmd === "start") {
49576
49973
  }
49577
49974
  if (cmd === "init") {
49578
49975
  const projectDir2 = process.cwd();
49579
- const srcDir = join21(projectDir2, "src");
49580
- const target = join21(srcDir, "global.css");
49581
- if (existsSync36(target)) {
49976
+ const srcDir = join23(projectDir2, "src");
49977
+ const target = join23(srcDir, "global.css");
49978
+ if (existsSync38(target)) {
49582
49979
  console.error(`vesk init: ${target} already exists \u2014 skipping`);
49583
49980
  process.exit(0);
49584
49981
  }
49585
- mkdirSync15(srcDir, { recursive: true });
49586
- writeFileSync18(target, [
49982
+ mkdirSync16(srcDir, { recursive: true });
49983
+ writeFileSync19(target, [
49587
49984
  `@import 'tailwindcss';`,
49588
49985
  ``,
49589
49986
  `@layer base {`,
@@ -49596,10 +49993,10 @@ if (cmd === "init") {
49596
49993
  }
49597
49994
  if (cmd === "dev") {
49598
49995
  const projectDir2 = process.cwd();
49599
- const appDirPath = join21(projectDir2, "app");
49996
+ const appDirPath = join23(projectDir2, "app");
49600
49997
  const port2 = parsePortArg(args);
49601
49998
  const host2 = parseHostArg(args);
49602
- if (!existsSync36(appDirPath)) {
49999
+ if (!existsSync38(appDirPath)) {
49603
50000
  console.error(`vesk: no app/ directory found in ${projectDir2}`);
49604
50001
  console.error('Run "npx create-vesk@latest <project-name>" first');
49605
50002
  process.exit(1);