vite-plugin-kiru 0.32.0-preview.1 → 0.32.0-preview.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.d.ts CHANGED
@@ -14,6 +14,30 @@ export interface ServerRenderOptions {
14
14
  context: Kiru.RequestContext
15
15
  }
16
16
 
17
+ export interface ServerActionsMap {
18
+ [key: string]: () => Promise<unknown>
19
+ }
20
+
17
21
  export declare function renderPage(
18
22
  options: ServerRenderOptions
19
23
  ): Promise<SSRRenderResult>
24
+
25
+ export type ServerActionHttpResponse =
26
+ | {
27
+ body: string
28
+ statusCode: 200
29
+ }
30
+ | {
31
+ body: null
32
+ statusCode: 500
33
+ }
34
+
35
+ export interface ServerActionResponse {
36
+ httpResponse: ServerActionHttpResponse | null
37
+ }
38
+
39
+ export declare function getServerActionResponse(
40
+ request: Request
41
+ ): Promise<ServerActionResponse>
42
+
43
+ export declare function getRequestContext(): Kiru.RequestContext
package/dist/server.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // src/server.ts
2
- import path2 from "node:path";
3
- import fs from "node:fs";
2
+ import path3 from "node:path";
3
+ import fs2 from "node:fs";
4
+ import { AsyncLocalStorage } from "node:async_hooks";
4
5
 
5
6
  // ../../node_modules/.pnpm/@isaacs+balanced-match@4.0.1/node_modules/@isaacs/balanced-match/dist/esm/index.js
6
7
  var balanced = (a, b, str) => {
@@ -4108,12 +4109,12 @@ var PathBase = class {
4108
4109
  /**
4109
4110
  * Get the Path object referenced by the string path, resolved from this Path
4110
4111
  */
4111
- resolve(path3) {
4112
- if (!path3) {
4112
+ resolve(path4) {
4113
+ if (!path4) {
4113
4114
  return this;
4114
4115
  }
4115
- const rootPath = this.getRootString(path3);
4116
- const dir = path3.substring(rootPath.length);
4116
+ const rootPath = this.getRootString(path4);
4117
+ const dir = path4.substring(rootPath.length);
4117
4118
  const dirParts = dir.split(this.splitSep);
4118
4119
  const result = rootPath ? this.getRoot(rootPath).#resolveParts(dirParts) : this.#resolveParts(dirParts);
4119
4120
  return result;
@@ -4865,8 +4866,8 @@ var PathWin32 = class _PathWin32 extends PathBase {
4865
4866
  /**
4866
4867
  * @internal
4867
4868
  */
4868
- getRootString(path3) {
4869
- return win32.parse(path3).root;
4869
+ getRootString(path4) {
4870
+ return win32.parse(path4).root;
4870
4871
  }
4871
4872
  /**
4872
4873
  * @internal
@@ -4912,8 +4913,8 @@ var PathPosix = class _PathPosix extends PathBase {
4912
4913
  /**
4913
4914
  * @internal
4914
4915
  */
4915
- getRootString(path3) {
4916
- return path3.startsWith("/") ? "/" : "";
4916
+ getRootString(path4) {
4917
+ return path4.startsWith("/") ? "/" : "";
4917
4918
  }
4918
4919
  /**
4919
4920
  * @internal
@@ -4962,8 +4963,8 @@ var PathScurryBase = class {
4962
4963
  *
4963
4964
  * @internal
4964
4965
  */
4965
- constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs2 = defaultFS } = {}) {
4966
- this.#fs = fsFromOption(fs2);
4966
+ constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs3 = defaultFS } = {}) {
4967
+ this.#fs = fsFromOption(fs3);
4967
4968
  if (cwd instanceof URL || cwd.startsWith("file://")) {
4968
4969
  cwd = fileURLToPath(cwd);
4969
4970
  }
@@ -5002,11 +5003,11 @@ var PathScurryBase = class {
5002
5003
  /**
5003
5004
  * Get the depth of a provided path, string, or the cwd
5004
5005
  */
5005
- depth(path3 = this.cwd) {
5006
- if (typeof path3 === "string") {
5007
- path3 = this.cwd.resolve(path3);
5006
+ depth(path4 = this.cwd) {
5007
+ if (typeof path4 === "string") {
5008
+ path4 = this.cwd.resolve(path4);
5008
5009
  }
5009
- return path3.depth();
5010
+ return path4.depth();
5010
5011
  }
5011
5012
  /**
5012
5013
  * Return the cache of child entries. Exposed so subclasses can create
@@ -5493,9 +5494,9 @@ var PathScurryBase = class {
5493
5494
  process2();
5494
5495
  return results;
5495
5496
  }
5496
- chdir(path3 = this.cwd) {
5497
+ chdir(path4 = this.cwd) {
5497
5498
  const oldCwd = this.cwd;
5498
- this.cwd = typeof path3 === "string" ? this.cwd.resolve(path3) : path3;
5499
+ this.cwd = typeof path4 === "string" ? this.cwd.resolve(path4) : path4;
5499
5500
  this.cwd[setAsCwd](oldCwd);
5500
5501
  }
5501
5502
  };
@@ -5521,8 +5522,8 @@ var PathScurryWin32 = class extends PathScurryBase {
5521
5522
  /**
5522
5523
  * @internal
5523
5524
  */
5524
- newRoot(fs2) {
5525
- return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs2 });
5525
+ newRoot(fs3) {
5526
+ return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs3 });
5526
5527
  }
5527
5528
  /**
5528
5529
  * Return true if the provided path string is an absolute path
@@ -5550,8 +5551,8 @@ var PathScurryPosix = class extends PathScurryBase {
5550
5551
  /**
5551
5552
  * @internal
5552
5553
  */
5553
- newRoot(fs2) {
5554
- return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs2 });
5554
+ newRoot(fs3) {
5555
+ return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs3 });
5555
5556
  }
5556
5557
  /**
5557
5558
  * Return true if the provided path string is an absolute path
@@ -5851,8 +5852,8 @@ var MatchRecord = class {
5851
5852
  }
5852
5853
  // match, absolute, ifdir
5853
5854
  entries() {
5854
- return [...this.store.entries()].map(([path3, n]) => [
5855
- path3,
5855
+ return [...this.store.entries()].map(([path4, n]) => [
5856
+ path4,
5856
5857
  !!(n & 2),
5857
5858
  !!(n & 1)
5858
5859
  ]);
@@ -6057,9 +6058,9 @@ var GlobUtil = class {
6057
6058
  signal;
6058
6059
  maxDepth;
6059
6060
  includeChildMatches;
6060
- constructor(patterns, path3, opts) {
6061
+ constructor(patterns, path4, opts) {
6061
6062
  this.patterns = patterns;
6062
- this.path = path3;
6063
+ this.path = path4;
6063
6064
  this.opts = opts;
6064
6065
  this.#sep = !opts.posix && opts.platform === "win32" ? "\\" : "/";
6065
6066
  this.includeChildMatches = opts.includeChildMatches !== false;
@@ -6078,11 +6079,11 @@ var GlobUtil = class {
6078
6079
  });
6079
6080
  }
6080
6081
  }
6081
- #ignored(path3) {
6082
- return this.seen.has(path3) || !!this.#ignore?.ignored?.(path3);
6082
+ #ignored(path4) {
6083
+ return this.seen.has(path4) || !!this.#ignore?.ignored?.(path4);
6083
6084
  }
6084
- #childrenIgnored(path3) {
6085
- return !!this.#ignore?.childrenIgnored?.(path3);
6085
+ #childrenIgnored(path4) {
6086
+ return !!this.#ignore?.childrenIgnored?.(path4);
6086
6087
  }
6087
6088
  // backpressure mechanism
6088
6089
  pause() {
@@ -6297,8 +6298,8 @@ var GlobUtil = class {
6297
6298
  };
6298
6299
  var GlobWalker = class extends GlobUtil {
6299
6300
  matches = /* @__PURE__ */ new Set();
6300
- constructor(patterns, path3, opts) {
6301
- super(patterns, path3, opts);
6301
+ constructor(patterns, path4, opts) {
6302
+ super(patterns, path4, opts);
6302
6303
  }
6303
6304
  matchEmit(e) {
6304
6305
  this.matches.add(e);
@@ -6335,8 +6336,8 @@ var GlobWalker = class extends GlobUtil {
6335
6336
  };
6336
6337
  var GlobStream = class extends GlobUtil {
6337
6338
  results;
6338
- constructor(patterns, path3, opts) {
6339
- super(patterns, path3, opts);
6339
+ constructor(patterns, path4, opts) {
6340
+ super(patterns, path4, opts);
6340
6341
  this.results = new Minipass({
6341
6342
  signal: this.signal,
6342
6343
  objectMode: true
@@ -6662,57 +6663,140 @@ var VIRTUAL_ENTRY_SERVER_ID = "virtual:kiru:entry-server";
6662
6663
  var VIRTUAL_ENTRY_CLIENT_ID = "virtual:kiru:entry-client";
6663
6664
 
6664
6665
  // src/globals.ts
6665
- var $KIRU_HEADLESS_GLOBAL = Symbol.for("kiru.headlessGlobal");
6666
- var global = globalThis[$KIRU_HEADLESS_GLOBAL] ??= {
6666
+ import path2 from "node:path";
6667
+ import fs from "node:fs";
6668
+ var $KIRU_SERVER_GLOBAL = Symbol.for("kiru.server.global");
6669
+ var projectRoot = process.cwd().replace(/\\/g, "/");
6670
+ var serverOutDirAbs = path2.resolve(projectRoot, "dist/server");
6671
+ var manifestPath = path2.resolve(serverOutDirAbs, "vite-manifest.json");
6672
+ var global = globalThis[$KIRU_SERVER_GLOBAL] ??= {
6667
6673
  viteDevServer: null,
6668
- server: null
6674
+ serverEntryModule: Promise.withResolvers(),
6675
+ route: null,
6676
+ loadedRemoteModules: /* @__PURE__ */ new Map()
6669
6677
  };
6670
- var VITE_DEV_SERVER_INSTANCE = {
6671
- get current() {
6672
- return global.viteDevServer;
6673
- },
6674
- set current(server) {
6675
- global.viteDevServer = server;
6678
+ async function loadRouteRemoteModule(route) {
6679
+ const existing = global.loadedRemoteModules.get(route);
6680
+ if (existing) return existing;
6681
+ const {
6682
+ config: { remotes }
6683
+ } = await getServerEntryModule();
6684
+ const routeEntry = remotes[route];
6685
+ if (!routeEntry) {
6686
+ throw new Error(`Remote functions route not found: ${route}`);
6687
+ }
6688
+ const promise = remotes[route].load();
6689
+ global.loadedRemoteModules.set(route, promise);
6690
+ return promise;
6691
+ }
6692
+ var serverEntryLoadInitialized = false;
6693
+ async function getServerEntryModule() {
6694
+ if (process.env.NODE_ENV === "production" && !serverEntryLoadInitialized) {
6695
+ serverEntryLoadInitialized = true;
6696
+ loadServerEntryModuleFromBuild();
6676
6697
  }
6677
- };
6678
- var entryServerResolvers = [];
6679
- var KIRU_SERVER_ENTRY = {
6680
- get current() {
6681
- return global.serverEntry;
6682
- },
6683
- set current(server) {
6684
- global.serverEntry = server;
6685
- if (server) {
6686
- entryServerResolvers.forEach((fn) => fn());
6687
- entryServerResolvers = [];
6688
- }
6698
+ return global.serverEntryModule.promise;
6699
+ }
6700
+ async function loadServerEntryModuleFromBuild() {
6701
+ if (!fs.existsSync(manifestPath)) {
6702
+ throw new Error(
6703
+ `Server manifest not found at ${manifestPath}. Make sure the SSR build has been completed.`
6704
+ );
6689
6705
  }
6690
- };
6691
- async function awaitServerRendererInitialized_Dev() {
6692
- if (KIRU_SERVER_ENTRY.current) {
6693
- return Promise.resolve(KIRU_SERVER_ENTRY.current);
6694
- }
6695
- return new Promise((resolve, reject) => {
6696
- const timeout = setTimeout(() => {
6697
- entryServerResolvers = entryServerResolvers.filter((r) => r !== resolve);
6698
- reject(new Error("Failed to acquire server renderer. Seek help!"));
6699
- }, 1e4);
6700
- entryServerResolvers.push(() => {
6701
- clearTimeout(timeout);
6702
- resolve(KIRU_SERVER_ENTRY.current);
6703
- });
6704
- });
6706
+ const manifest = JSON.parse(
6707
+ fs.readFileSync(manifestPath, "utf-8")
6708
+ );
6709
+ const virtualEntryServerModule = Object.values(manifest).find(
6710
+ (value) => value.src === VIRTUAL_ENTRY_SERVER_ID
6711
+ );
6712
+ if (!virtualEntryServerModule) {
6713
+ throw new Error(
6714
+ "Virtual entry server module not found in manifest. Make sure the SSR build has been completed."
6715
+ );
6716
+ }
6717
+ const entryServerFile = virtualEntryServerModule.file;
6718
+ const entryServerPath = path2.resolve(serverOutDirAbs, entryServerFile);
6719
+ if (!fs.existsSync(entryServerPath)) {
6720
+ throw new Error(
6721
+ `Virtual entry server module file not found at ${entryServerPath}`
6722
+ );
6723
+ }
6724
+ const fileUrl = `file://${entryServerPath.replace(/\\/g, "/")}`;
6725
+ const mod = await import(
6726
+ /* @vite-ignore */
6727
+ fileUrl
6728
+ );
6729
+ global.serverEntryModule.resolve(mod);
6730
+ }
6731
+
6732
+ // src/token.ts
6733
+ import crypto from "crypto";
6734
+ function makeKiruContextToken(ctx, secret) {
6735
+ const iat = Date.now();
6736
+ const payload = {
6737
+ iat,
6738
+ ctx
6739
+ };
6740
+ if (!secret) throw new Error("secret required");
6741
+ return createSignedTokenHmac(payload, secret);
6742
+ }
6743
+ function unwrapKiruToken(token, secret) {
6744
+ const payload = verifySignedTokenHmac(token, secret);
6745
+ if (!payload) return null;
6746
+ return payload.ctx;
6747
+ }
6748
+ function createSignedTokenHmac(payload, secret) {
6749
+ const header = { alg: "HS256", typ: "KRT" };
6750
+ const headerB = Buffer.from(JSON.stringify(header), "utf8");
6751
+ const payloadB = Buffer.from(JSON.stringify(payload), "utf8");
6752
+ const signingInput = `${base64UrlEncode(headerB)}.${base64UrlEncode(
6753
+ payloadB
6754
+ )}`;
6755
+ const signature = crypto.createHmac("sha256", secret).update(signingInput).digest();
6756
+ return `${signingInput}.${base64UrlEncode(signature)}`;
6757
+ }
6758
+ function verifySignedTokenHmac(token, secret) {
6759
+ try {
6760
+ const parts = token.split(".");
6761
+ if (parts.length !== 3) return null;
6762
+ const [headerB64, payloadB64, sigB64] = parts;
6763
+ const header = JSON.parse(
6764
+ Buffer.from(headerB64, "base64").toString("utf8")
6765
+ );
6766
+ if (header.typ !== "KRT") return null;
6767
+ if (header.alg !== "HS256") return null;
6768
+ const signingInput = `${headerB64}.${payloadB64}`;
6769
+ const expectedSig = crypto.createHmac("sha256", secret).update(signingInput).digest();
6770
+ const sig = base64UrlDecode(sigB64);
6771
+ if (!crypto.timingSafeEqual(expectedSig, sig)) return null;
6772
+ const payload = JSON.parse(
6773
+ Buffer.from(payloadB64, "base64").toString("utf8")
6774
+ );
6775
+ return payload;
6776
+ } catch (e) {
6777
+ return null;
6778
+ }
6779
+ }
6780
+ function base64UrlEncode(buf) {
6781
+ const b64 = Buffer.from(buf).toString("base64");
6782
+ return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
6783
+ }
6784
+ function base64UrlDecode(s) {
6785
+ s = s.replace(/-/g, "+").replace(/_/g, "/");
6786
+ while (s.length % 4) s += "=";
6787
+ return Buffer.from(s, "base64");
6705
6788
  }
6706
6789
 
6707
6790
  // src/server.ts
6708
- async function getClientAssets(clientOutDirAbs, manifestPath) {
6791
+ var als = new AsyncLocalStorage();
6792
+ async function getClientAssets(clientOutDirAbs, manifestPath2) {
6709
6793
  let clientEntry = null;
6710
6794
  let manifest = null;
6711
6795
  try {
6712
- const clientManifestPath = path2.resolve(clientOutDirAbs, manifestPath);
6713
- if (fs.existsSync(clientManifestPath)) {
6796
+ const clientManifestPath = path3.resolve(clientOutDirAbs, manifestPath2);
6797
+ if (fs2.existsSync(clientManifestPath)) {
6714
6798
  const parsedManifest = JSON.parse(
6715
- fs.readFileSync(clientManifestPath, "utf-8")
6799
+ fs2.readFileSync(clientManifestPath, "utf-8")
6716
6800
  );
6717
6801
  manifest = parsedManifest;
6718
6802
  if (parsedManifest[VIRTUAL_ENTRY_CLIENT_ID]?.file) {
@@ -6723,7 +6807,7 @@ async function getClientAssets(clientOutDirAbs, manifestPath) {
6723
6807
  }
6724
6808
  return { clientEntry, manifest };
6725
6809
  }
6726
- function collectCssForModules(manifest, moduleIds, projectRoot) {
6810
+ function collectCssForModules(manifest, moduleIds, projectRoot2) {
6727
6811
  if (!manifest) return "";
6728
6812
  const seen = /* @__PURE__ */ new Set();
6729
6813
  const cssFiles = /* @__PURE__ */ new Set();
@@ -6745,8 +6829,8 @@ function collectCssForModules(manifest, moduleIds, projectRoot) {
6745
6829
  }
6746
6830
  for (const moduleId of moduleIds) {
6747
6831
  let normalizedId = moduleId.replace(/\\/g, "/");
6748
- if (normalizedId.startsWith(projectRoot)) {
6749
- normalizedId = normalizedId.substring(projectRoot.length);
6832
+ if (normalizedId.startsWith(projectRoot2)) {
6833
+ normalizedId = normalizedId.substring(projectRoot2.length);
6750
6834
  }
6751
6835
  if (normalizedId.startsWith("/")) {
6752
6836
  normalizedId = normalizedId.substring(1);
@@ -6765,8 +6849,8 @@ function collectCssForModules(manifest, moduleIds, projectRoot) {
6765
6849
  }
6766
6850
  for (const key in manifestRef) {
6767
6851
  const keyNormalized = key.replace(/\\/g, "/");
6768
- const moduleBaseName = path2.basename(normalizedId);
6769
- const keyBaseName = path2.basename(keyNormalized);
6852
+ const moduleBaseName = path3.basename(normalizedId);
6853
+ const keyBaseName = path3.basename(keyNormalized);
6770
6854
  if ((keyNormalized.endsWith(normalizedId) || normalizedId.endsWith(keyNormalized)) && moduleBaseName === keyBaseName) {
6771
6855
  collectCss(key);
6772
6856
  break;
@@ -6779,58 +6863,11 @@ function collectCssForModules(manifest, moduleIds, projectRoot) {
6779
6863
  }
6780
6864
  return "";
6781
6865
  }
6782
- async function resolveServerRenderer() {
6783
- if (process.env.NODE_ENV !== "production") {
6784
- return awaitServerRendererInitialized_Dev();
6785
- }
6786
- return loadServerRenderer_Production();
6787
- }
6788
- async function loadServerRenderer_Production() {
6789
- const projectRoot = process.cwd().replace(/\\/g, "/");
6790
- const serverOutDirAbs = path2.resolve(projectRoot, "dist/server");
6791
- const manifestPath = path2.resolve(serverOutDirAbs, "vite-manifest.json");
6792
- if (!fs.existsSync(manifestPath)) {
6793
- throw new Error(
6794
- `Server manifest not found at ${manifestPath}. Make sure the SSR build has been completed.`
6795
- );
6796
- }
6797
- const manifest = JSON.parse(
6798
- fs.readFileSync(manifestPath, "utf-8")
6799
- );
6800
- const virtualEntryServerModule = Object.values(manifest).find(
6801
- (value) => value.src === VIRTUAL_ENTRY_SERVER_ID
6802
- );
6803
- if (!virtualEntryServerModule) {
6804
- throw new Error(
6805
- "Virtual entry server module not found in manifest. Make sure the SSR build has been completed."
6806
- );
6807
- }
6808
- const entryServerFile = virtualEntryServerModule.file;
6809
- const entryServerPath = path2.resolve(serverOutDirAbs, entryServerFile);
6810
- if (!fs.existsSync(entryServerPath)) {
6811
- throw new Error(
6812
- `Virtual entry server module file not found at ${entryServerPath}`
6813
- );
6814
- }
6815
- const fileUrl = `file://${entryServerPath.replace(/\\/g, "/")}`;
6816
- const module = await import(
6817
- /* @vite-ignore */
6818
- fileUrl
6819
- );
6820
- if (!module.render || !module.documentModuleId) {
6821
- throw new Error(
6822
- "Virtual entry server module does not export render and documentModuleId"
6823
- );
6824
- }
6825
- return {
6826
- render: module.render,
6827
- documentModuleId: module.documentModuleId
6828
- };
6829
- }
6830
6866
  async function renderPage(options) {
6831
- const { render, documentModuleId } = await resolveServerRenderer();
6867
+ const { render, documentModuleId, remoteFunctionSecret } = await getServerEntryModule();
6832
6868
  const moduleIds = [documentModuleId];
6833
- const projectRoot = process.cwd().replace(/\\/g, "/");
6869
+ const projectRoot2 = process.cwd().replace(/\\/g, "/");
6870
+ als.enterWith(options.context);
6834
6871
  const { httpResponse } = await render(options.url, {
6835
6872
  userContext: options.context,
6836
6873
  registerModule(moduleId) {
@@ -6838,9 +6875,7 @@ async function renderPage(options) {
6838
6875
  }
6839
6876
  });
6840
6877
  if (httpResponse === null) {
6841
- return {
6842
- httpResponse: null
6843
- };
6878
+ return { httpResponse: null };
6844
6879
  }
6845
6880
  const isDevelopment = process.env.NODE_ENV !== "production";
6846
6881
  let html = httpResponse.html;
@@ -6859,8 +6894,8 @@ async function renderPage(options) {
6859
6894
  }
6860
6895
  };
6861
6896
  for (const id of moduleIds) {
6862
- const p = path2.join(projectRoot, id).replace(/\\/g, "/");
6863
- const mod = VITE_DEV_SERVER_INSTANCE.current.moduleGraph.getModuleById(p);
6897
+ const p = path3.join(projectRoot2, id).replace(/\\/g, "/");
6898
+ const mod = global.viteDevServer.moduleGraph.getModuleById(p);
6864
6899
  if (!mod) {
6865
6900
  console.error(`Module not found: ${p}`);
6866
6901
  continue;
@@ -6868,24 +6903,24 @@ async function renderPage(options) {
6868
6903
  scan(mod);
6869
6904
  }
6870
6905
  const localModules = Array.from(importedModules).filter(
6871
- (m) => m.id?.startsWith(projectRoot)
6906
+ (m) => m.id?.startsWith(projectRoot2)
6872
6907
  );
6873
6908
  const cssModules = localModules.filter((m) => m.id?.endsWith(".css"));
6874
6909
  if (cssModules.length) {
6875
6910
  const stylesheets = cssModules.map((mod) => {
6876
- const p = mod.id?.replace(projectRoot, "");
6911
+ const p = mod.id?.replace(projectRoot2, "");
6877
6912
  return `<link rel="stylesheet" type="text/css" href="${p}?temp">`;
6878
6913
  });
6879
6914
  html = html.replace("<head>", "<head>" + stylesheets.join("\n"));
6880
6915
  }
6881
6916
  } else {
6882
- const clientOutDirAbs = path2.resolve(projectRoot, "dist/client");
6917
+ const clientOutDirAbs = path3.resolve(projectRoot2, "dist/client");
6883
6918
  const { clientEntry, manifest } = await getClientAssets(
6884
6919
  clientOutDirAbs,
6885
6920
  "vite-manifest.json"
6886
6921
  );
6887
6922
  if (manifest) {
6888
- const cssLinks = collectCssForModules(manifest, moduleIds, projectRoot);
6923
+ const cssLinks = collectCssForModules(manifest, moduleIds, projectRoot2);
6889
6924
  if (cssLinks) {
6890
6925
  html = html.replace("<head>", "<head>" + cssLinks);
6891
6926
  }
@@ -6900,6 +6935,14 @@ async function renderPage(options) {
6900
6935
  "</head>",
6901
6936
  `<script type="application/json" k-request-context>${contextString}</script></head>`
6902
6937
  );
6938
+ const token = makeKiruContextToken(
6939
+ options.context,
6940
+ remoteFunctionSecret
6941
+ );
6942
+ html = html.replace(
6943
+ "</head>",
6944
+ `<script type="application/json" k-request-token>${token}</script></head>`
6945
+ );
6903
6946
  return {
6904
6947
  httpResponse: {
6905
6948
  ...httpResponse,
@@ -6907,6 +6950,70 @@ async function renderPage(options) {
6907
6950
  }
6908
6951
  };
6909
6952
  }
6953
+ async function getServerActionResponse(request) {
6954
+ let action;
6955
+ let actionArgs = [];
6956
+ let context;
6957
+ const { searchParams } = new URL(request.url);
6958
+ try {
6959
+ let strToken, actionId;
6960
+ if (request.method !== "POST" || request.headers.get("Content-Type") !== "application/json" || !(strToken = request.headers.get("x-kiru-token")) || !(actionId = searchParams.get("action"))) {
6961
+ return { httpResponse: null };
6962
+ }
6963
+ const [route, actionName] = actionId.split(".");
6964
+ await loadRouteRemoteModule(route);
6965
+ const {
6966
+ config: { actions },
6967
+ remoteFunctionSecret
6968
+ } = await getServerEntryModule();
6969
+ const ctx = unwrapKiruToken(strToken, remoteFunctionSecret);
6970
+ if (!ctx) {
6971
+ return createBadActionResponse();
6972
+ }
6973
+ const fileActions = actions.get(route);
6974
+ const actionFn = fileActions[actionName];
6975
+ const args = await request.json();
6976
+ if (typeof actionFn !== "function" || !Array.isArray(args)) {
6977
+ return createBadActionResponse();
6978
+ }
6979
+ action = actionFn;
6980
+ actionArgs = args;
6981
+ context = ctx;
6982
+ } catch {
6983
+ return createBadActionResponse();
6984
+ }
6985
+ return new Promise(async (resolve) => {
6986
+ als.run({ ...context }, async () => {
6987
+ try {
6988
+ const result = await action(...actionArgs);
6989
+ resolve({
6990
+ httpResponse: {
6991
+ body: JSON.stringify(result),
6992
+ statusCode: 200
6993
+ }
6994
+ });
6995
+ } catch {
6996
+ resolve(createBadActionResponse());
6997
+ }
6998
+ });
6999
+ });
7000
+ }
7001
+ function createBadActionResponse() {
7002
+ return {
7003
+ httpResponse: { body: null, statusCode: 500 }
7004
+ };
7005
+ }
7006
+ function getRequestContext() {
7007
+ const ctx = als.getStore();
7008
+ if (ctx === void 0) {
7009
+ throw new Error(
7010
+ "[vite-plugin-kiru]: Invalid `getRequestContext` invocation."
7011
+ );
7012
+ }
7013
+ return ctx;
7014
+ }
6910
7015
  export {
7016
+ getRequestContext,
7017
+ getServerActionResponse,
6911
7018
  renderPage
6912
7019
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-kiru",
3
- "version": "0.32.0-preview.1",
3
+ "version": "0.32.0-preview.2",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -19,7 +19,7 @@
19
19
  }
20
20
  },
21
21
  "peerDependencies": {
22
- "kiru": ">=0.54.0-preview.0"
22
+ "kiru": ">=0.54.0-preview.1"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/node": "^22.17.0",
@@ -27,14 +27,15 @@
27
27
  "rollup": "^4.46.2",
28
28
  "tsx": "^4.20.3",
29
29
  "typescript": "^5.9.2",
30
- "kiru-devtools-client": "^0.0.0",
31
30
  "kiru-devtools-host": "^1.0.0",
32
- "kiru": "^0.54.0-preview.0"
31
+ "kiru-devtools-client": "^0.0.0",
32
+ "kiru": "^0.54.0-preview.1"
33
33
  },
34
34
  "dependencies": {
35
35
  "glob": "^12.0.0",
36
36
  "magic-string": "^0.30.17",
37
37
  "mime": "^4.1.0",
38
+ "minimatch": "10.1.1",
38
39
  "vite": "^7.2.2"
39
40
  },
40
41
  "scripts": {