revojs 0.1.6 → 0.1.8

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/index.d.ts CHANGED
@@ -48,37 +48,6 @@ declare global {
48
48
  }
49
49
  }
50
50
  //#endregion
51
- //#region src/app/index.d.ts
52
- type Environment = typeof CLIENT | typeof SERVER;
53
- type Virtual = (environment: Environment) => undefined | string | Promise<string>;
54
- interface Config {
55
- modules: Array<Module>;
56
- client?: string;
57
- server?: string;
58
- externals: Array<string>;
59
- sources: Record<string, Source>;
60
- }
61
- interface Module {
62
- config?: Mergeable<Config>;
63
- setup?: (app: App) => void | Promise<void>;
64
- }
65
- interface Source {
66
- match: string;
67
- entries: Array<string>;
68
- suffix?: string;
69
- }
70
- interface App {
71
- config: Config;
72
- virtuals: Record<string, Virtual>;
73
- alias: Record<string, string>;
74
- }
75
- declare function createApp(inputConfig?: Mergeable<Config>): App;
76
- declare const SERVER = "ssr";
77
- declare const CLIENT = "client";
78
- //#endregion
79
- //#region src/client/index.d.ts
80
- declare function $fetch<T>(scope: Scope, input: string | URL, options?: RequestInit): Promise<T>;
81
- //#endregion
82
51
  //#region src/server/index.d.ts
83
52
  type CookiePriority = "Low" | "Medium" | "High";
84
53
  type CookieSameSite = "Lax" | "Strict" | "None";
@@ -88,6 +57,7 @@ type StatusCode = 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 20
88
57
  type MimeType = "text/plain" | "text/css" | "text/html" | "text/csv" | "text/javascript" | "application/json" | "application/xml" | "image/jpeg" | "image/png" | "image/gif" | "image/webp" | "image/svg+xml" | "image/bmp" | "image/x-icon" | "font/ttf" | "font/otf" | "font/woff" | "font/woff2" | "audio/mpeg" | "audio/wav" | "audio/ogg" | "audio/mp4" | "video/mp4" | "video/webm" | "video/ogg" | "video/quicktime" | "video/x-msvideo" | "application/zip" | "application/vnd.rar" | "application/x-tar" | "application/gzip" | "application/x-7z-compressed" | "application/pdf" | "application/msword" | "application/vnd.openxmlformats-officedocument.wordprocessingml.document" | "application/vnd.ms-excel" | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | "application/vnd.ms-powerpoint" | "application/vnd.openxmlformats-officedocument.presentationml.presentation" | "application/vnd.microsoft.portable-executable" | "application/vnd.android.package-archive";
89
58
  type Result = void | Response | Promise<void | Response>;
90
59
  type Node<T> = WildcardNode<T> | ParameterNode<T> | PathNode<T>;
60
+ type States = Record<string, unknown>;
91
61
  interface CookieOptions {
92
62
  domain?: string;
93
63
  expires?: Date;
@@ -109,6 +79,7 @@ interface RouterContext {
109
79
  parameters: Record<string, string>;
110
80
  }
111
81
  interface ServerContext<T extends Context = Context> {
82
+ states: States;
112
83
  request: Request;
113
84
  response: ResponseConfig;
114
85
  variables: T;
@@ -151,6 +122,7 @@ declare class Router extends Radix<Route> implements Middleware {
151
122
  }
152
123
  declare function defineRoute<T extends Route>(route: T): T;
153
124
  declare function defineMiddleware<T extends Middleware>(middleware: T): T;
125
+ declare function useRouter(scope: Scope): RouterContext;
154
126
  declare function useServer<T extends Context>(scope: Scope): ServerContext<T>;
155
127
  declare function useUrl(scope: Scope, base?: string): URL;
156
128
  declare function useQuery(scope: Scope): Record<string, string>;
@@ -160,6 +132,8 @@ declare function useCookies<T extends Schema>(scope: Scope, schema: T): InferOut
160
132
  declare function useSetCookies(scope: Scope): Record<string, string>;
161
133
  declare function useSetCookies<T extends Schema>(scope: Scope, schema: T): InferOutput<T>;
162
134
  declare function setCookie(scope: Scope, name: string, value: string, options?: CookieOptions): void;
135
+ declare function getState<T>(scope: Scope, name: string): T;
136
+ declare function setState<T>(scope: Scope, name: string, value: T): void;
163
137
  declare function sendText(scope: Scope, text: string, config?: Mergeable<ResponseConfig>): Response;
164
138
  declare function sendHtml(scope: Scope, text: string, config?: Mergeable<ResponseConfig>): Response;
165
139
  declare function sendJson<T>(scope: Scope, value: T, config?: Mergeable<ResponseConfig>): Response;
@@ -168,11 +142,48 @@ declare function sendBadRequest(scope: Scope, text: string, config?: Mergeable<R
168
142
  declare function sendUnauthorized(scope: Scope, config?: Mergeable<ResponseConfig>): Response;
169
143
  declare function mimeType(file: string): MimeType;
170
144
  declare function toRoutePath(path: string): [string, string | undefined];
145
+ declare function invoke(scope: Scope, pipeline: Array<Middleware>, index?: number): Result;
171
146
  declare function createServer(): Promise<Server>;
172
147
  declare const ROUTER_CONTEXT: Descriptor<RouterContext>;
173
148
  declare const SERVER_CONTEXT: Descriptor<ServerContext<Context>>;
174
149
  declare const WILDCARD = "$";
175
150
  declare const PARAMETER = ":";
151
+ declare let STATES: States;
176
152
  declare const mimeTypes: Record<string, MimeType>;
177
153
  //#endregion
178
- export { $fetch, App, CLIENT, Config, Context, CookieOptions, CookiePriority, CookieSameSite, Descriptor, Encoding, Environment, Failure, HttpMethod, InferInput, InferOutput, Issue, Mergeable, Middleware, MimeType, Module, Node, Output, PARAMETER, ParameterNode, PathNode, ROUTER_CONTEXT, Radix, ResponseConfig, Result, Route, Router, RouterContext, SERVER, SERVER_CONTEXT, Schema, Scope, Server, ServerContext, Source, StatusCode, StopEvent, Success, Virtual, WILDCARD, WildcardNode, createApp, createServer, defineContext, defineMiddleware, defineRoute, isFailure, mergeObjects, mimeType, mimeTypes, parseSchema, sendBadRequest, sendHtml, sendJson, sendRedirect, sendText, sendUnauthorized, setCookie, toRoutePath, useCookies, useQuery, useServer, useSetCookies, useUrl };
154
+ //#region src/app/index.d.ts
155
+ type Environment = typeof CLIENT | typeof SERVER;
156
+ type Virtual = (environment: Environment) => undefined | string | Promise<string>;
157
+ interface DevelopmentConfig {
158
+ middlewares: Array<Middleware>;
159
+ }
160
+ interface Config {
161
+ modules: Array<Module>;
162
+ client?: string;
163
+ server?: string;
164
+ externals: Array<string>;
165
+ sources: Record<string, Source>;
166
+ development: DevelopmentConfig;
167
+ }
168
+ interface Module {
169
+ config?: Mergeable<Config>;
170
+ setup?: (app: App) => void | Promise<void>;
171
+ }
172
+ interface Source {
173
+ match: string;
174
+ entries: Array<string>;
175
+ suffix?: string;
176
+ }
177
+ interface App {
178
+ config: Config;
179
+ virtuals: Record<string, Virtual>;
180
+ alias: Record<string, string>;
181
+ }
182
+ declare function createApp(inputConfig?: Mergeable<Config>): App;
183
+ declare const SERVER = "ssr";
184
+ declare const CLIENT = "client";
185
+ //#endregion
186
+ //#region src/client/index.d.ts
187
+ declare function $fetch<T>(scope: Scope, input: string | URL, options?: RequestInit): Promise<T>;
188
+ //#endregion
189
+ export { $fetch, App, CLIENT, Config, Context, CookieOptions, CookiePriority, CookieSameSite, Descriptor, DevelopmentConfig, Encoding, Environment, Failure, HttpMethod, InferInput, InferOutput, Issue, Mergeable, Middleware, MimeType, Module, Node, Output, PARAMETER, ParameterNode, PathNode, ROUTER_CONTEXT, Radix, ResponseConfig, Result, Route, Router, RouterContext, SERVER, SERVER_CONTEXT, STATES, Schema, Scope, Server, ServerContext, Source, States, StatusCode, StopEvent, Success, Virtual, WILDCARD, WildcardNode, createApp, createServer, defineContext, defineMiddleware, defineRoute, getState, invoke, isFailure, mergeObjects, mimeType, mimeTypes, parseSchema, sendBadRequest, sendHtml, sendJson, sendRedirect, sendText, sendUnauthorized, setCookie, setState, toRoutePath, useCookies, useQuery, useRouter, useServer, useSetCookies, useUrl };
package/dist/index.js CHANGED
@@ -53,16 +53,16 @@ var Router = class extends Radix {
53
53
  segments: (request.method.toUpperCase() + pathname).split("/"),
54
54
  parameters: {}
55
55
  };
56
- const invoke = (node, index) => {
56
+ const invoke$1 = (node, index) => {
57
57
  if (index === context.segments.length) return node.value;
58
58
  const segment = context.segments[index];
59
59
  if (node.children[segment]) {
60
- const route$1 = invoke(node.children[segment], index + 1);
60
+ const route$1 = invoke$1(node.children[segment], index + 1);
61
61
  if (route$1) return route$1;
62
62
  }
63
63
  if (node.children[PARAMETER]) {
64
64
  const parameterNode = node.children[PARAMETER];
65
- const route$1 = invoke(parameterNode, index + 1);
65
+ const route$1 = invoke$1(parameterNode, index + 1);
66
66
  if (route$1) {
67
67
  context.parameters[parameterNode.parameter] = segment;
68
68
  return route$1;
@@ -71,10 +71,10 @@ var Router = class extends Radix {
71
71
  if (node.children[WILDCARD]) {
72
72
  const wildcardNode = node.children[WILDCARD];
73
73
  context.parameters[wildcardNode.parameter] = segment;
74
- return wildcardNode.value ?? invoke(wildcardNode, segment.length);
74
+ return wildcardNode.value ?? invoke$1(wildcardNode, segment.length);
75
75
  }
76
76
  };
77
- const route = invoke(this.rootNode, 0);
77
+ const route = invoke$1(this.rootNode, 0);
78
78
  if (route) {
79
79
  scope.setContext(ROUTER_CONTEXT, context);
80
80
  return route.fetch(scope);
@@ -88,6 +88,9 @@ function defineRoute(route) {
88
88
  function defineMiddleware(middleware) {
89
89
  return middleware;
90
90
  }
91
+ function useRouter(scope) {
92
+ return scope.getContext(ROUTER_CONTEXT);
93
+ }
91
94
  function useServer(scope) {
92
95
  return scope.getContext(SERVER_CONTEXT);
93
96
  }
@@ -132,6 +135,30 @@ function setCookie(scope, name, value, options) {
132
135
  if (import.meta.client) document.cookie = cookie;
133
136
  else response.headers.append("Set-Cookie", cookie);
134
137
  }
138
+ function getState(scope, name) {
139
+ if (import.meta.server) {
140
+ const { states } = useServer(scope);
141
+ return states[name];
142
+ } else {
143
+ if (STATES === void 0) {
144
+ const element = document.getElementById("STATES");
145
+ STATES = element?.textContent ? JSON.parse(element.textContent) : {};
146
+ }
147
+ return STATES[name];
148
+ }
149
+ }
150
+ function setState(scope, name, value) {
151
+ if (import.meta.server) {
152
+ const { states } = useServer(scope);
153
+ states[name] = value;
154
+ } else {
155
+ if (STATES === void 0) {
156
+ const element = document.getElementById("STATES");
157
+ STATES = element?.textContent ? JSON.parse(element.textContent) : {};
158
+ }
159
+ STATES[name] = value;
160
+ }
161
+ }
135
162
  function sendText(scope, text, config) {
136
163
  const { response } = useServer(scope);
137
164
  response.headers.set("Content-Type", "text/plain");
@@ -171,6 +198,9 @@ function toRoutePath(path) {
171
198
  const result = ("/" + path).replaceAll(/\/index/g, "").replaceAll(/\[\.\.\.(.*?)\]/g, (_, value) => WILDCARD + value).replaceAll(/\[(.*?)\]/g, (_, value) => PARAMETER + value);
172
199
  return (result.startsWith("/") ? result : "/" + result).split(".");
173
200
  }
201
+ function invoke(scope, pipeline, index = 0) {
202
+ return pipeline.at(index)?.fetch(scope, () => invoke(scope, pipeline, index + 1));
203
+ }
174
204
  async function createServer() {
175
205
  const router = new Router();
176
206
  const pipeline = new Array();
@@ -188,14 +218,11 @@ async function createServer() {
188
218
  router.use(method?.toUpperCase() + name, route);
189
219
  }
190
220
  pipeline.push(router);
191
- const invoke = (scope, index) => {
192
- return pipeline.at(index)?.fetch(scope, () => invoke(scope, index + 1));
193
- };
194
221
  return {
195
222
  router,
196
223
  pipeline,
197
224
  async fetch(scope) {
198
- return await invoke(scope, 0) ?? sendText(scope, "NOT_FOUND", { status: 404 });
225
+ return await invoke(scope, pipeline) ?? sendText(scope, "NOT_FOUND", { status: 404 });
199
226
  }
200
227
  };
201
228
  }
@@ -203,6 +230,7 @@ const ROUTER_CONTEXT = defineContext("ROUTER_CONTEXT");
203
230
  const SERVER_CONTEXT = defineContext("SERVER_CONTEXT");
204
231
  const WILDCARD = "$";
205
232
  const PARAMETER = ":";
233
+ let STATES;
206
234
  const mimeTypes = {
207
235
  txt: "text/plain",
208
236
  css: "text/css",
@@ -328,7 +356,8 @@ function createApp(inputConfig) {
328
356
  match: "**/*.{js,ts}",
329
357
  entries: ["./middlewares"]
330
358
  }
331
- }
359
+ },
360
+ development: { middlewares: [] }
332
361
  });
333
362
  for (const module of config.modules) config = mergeObjects(config, module.config);
334
363
  return {
@@ -345,9 +374,10 @@ const CLIENT = "client";
345
374
  async function $fetch(scope, input, options) {
346
375
  let response;
347
376
  if (import.meta.server) {
348
- const { request, variables } = useServer(scope);
377
+ const { states, request, variables } = useServer(scope);
349
378
  const next = new Scope();
350
379
  next.setContext(SERVER_CONTEXT, {
380
+ states,
351
381
  request: new Request(new URL(input.toString(), request.url), options),
352
382
  response: { headers: new Headers() },
353
383
  variables
@@ -363,4 +393,4 @@ async function $fetch(scope, input, options) {
363
393
  }
364
394
 
365
395
  //#endregion
366
- export { $fetch, CLIENT, PARAMETER, ROUTER_CONTEXT, Radix, Router, SERVER, SERVER_CONTEXT, Scope, StopEvent, WILDCARD, createApp, createServer, defineContext, defineMiddleware, defineRoute, isFailure, mergeObjects, mimeType, mimeTypes, parseSchema, sendBadRequest, sendHtml, sendJson, sendRedirect, sendText, sendUnauthorized, setCookie, toRoutePath, useCookies, useQuery, useServer, useSetCookies, useUrl };
396
+ export { $fetch, CLIENT, PARAMETER, ROUTER_CONTEXT, Radix, Router, SERVER, SERVER_CONTEXT, STATES, Scope, StopEvent, WILDCARD, createApp, createServer, defineContext, defineMiddleware, defineRoute, getState, invoke, isFailure, mergeObjects, mimeType, mimeTypes, parseSchema, sendBadRequest, sendHtml, sendJson, sendRedirect, sendText, sendUnauthorized, setCookie, setState, toRoutePath, useCookies, useQuery, useRouter, useServer, useSetCookies, useUrl };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "revojs",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "type": "module",
5
5
  "repository": "coverbase/revojs",
6
6
  "license": "MIT",
@@ -9,10 +9,6 @@
9
9
  "types": "./dist/index.d.ts",
10
10
  "import": "./dist/index.js"
11
11
  },
12
- "./vite": {
13
- "types": "./dist/vite/index.d.ts",
14
- "import": "./dist/vite/index.js"
15
- },
16
12
  "./types": {
17
13
  "types": "./src/types/index.d.ts"
18
14
  }
@@ -28,13 +24,8 @@
28
24
  "build": "tsdown",
29
25
  "watch": "tsdown -w"
30
26
  },
31
- "dependencies": {
32
- "tinyglobby": "^0.2.14",
33
- "vite": "^7.1.3"
34
- },
35
27
  "devDependencies": {
36
28
  "@revojs/tsconfig": "*",
37
- "@types/node": "^24.3.0",
38
29
  "tsdown": "^0.15.1"
39
30
  }
40
31
  }
@@ -1,54 +0,0 @@
1
- import { Plugin } from "vite";
2
-
3
- //#region src/shared/index.d.ts
4
-
5
- type Mergeable<T> = { [P in keyof T]?: Mergeable<T[P]> };
6
- declare class StopEvent extends Event {
7
- constructor();
8
- }
9
- declare global {
10
- interface ElementEventMap {
11
- stop: StopEvent;
12
- }
13
- }
14
- //#endregion
15
- //#region src/app/index.d.ts
16
- type Environment = typeof CLIENT | typeof SERVER;
17
- type Virtual = (environment: Environment) => undefined | string | Promise<string>;
18
- interface Config {
19
- modules: Array<Module>;
20
- client?: string;
21
- server?: string;
22
- externals: Array<string>;
23
- sources: Record<string, Source>;
24
- }
25
- interface Module {
26
- config?: Mergeable<Config>;
27
- setup?: (app: App) => void | Promise<void>;
28
- }
29
- interface Source {
30
- match: string;
31
- entries: Array<string>;
32
- suffix?: string;
33
- }
34
- interface App {
35
- config: Config;
36
- virtuals: Record<string, Virtual>;
37
- alias: Record<string, string>;
38
- }
39
- declare const SERVER = "ssr";
40
- declare const CLIENT = "client";
41
- //#endregion
42
- //#region src/vite/index.d.ts
43
- declare function useKit(app: App, source: string | URL): {
44
- source: string;
45
- toPath: (...paths: Array<string>) => string;
46
- addVirtual: (name: string, virtual: Virtual) => void;
47
- addAlias: (name: string, path: string) => void;
48
- };
49
- declare function addRoutes(app: App, path: string): void;
50
- declare function addAssets(app: App, path: string): void;
51
- declare function addMiddlewares(app: App, path: string): void;
52
- declare function revojs(config?: Mergeable<Config>): Array<Plugin>;
53
- //#endregion
54
- export { addAssets, addMiddlewares, addRoutes, revojs, useKit };
@@ -1,474 +0,0 @@
1
- import { basename, dirname, isAbsolute, join, posix, win32 } from "path";
2
- import { globSync } from "tinyglobby";
3
- import { fileURLToPath } from "url";
4
- import { isRunnableDevEnvironment } from "vite";
5
- import { once } from "node:events";
6
- import { Readable, Stream } from "node:stream";
7
- import { existsSync, readFileSync } from "fs";
8
-
9
- //#region package.json
10
- var name = "revojs";
11
- var version = "0.1.6";
12
-
13
- //#endregion
14
- //#region src/server/index.ts
15
- const ROUTER_CONTEXT = defineContext("ROUTER_CONTEXT");
16
- const SERVER_CONTEXT = defineContext("SERVER_CONTEXT");
17
-
18
- //#endregion
19
- //#region src/shared/index.ts
20
- var StopEvent = class extends Event {
21
- constructor() {
22
- super("stop");
23
- }
24
- };
25
- var Scope = class extends EventTarget {
26
- parentScope;
27
- context;
28
- constructor(parentScope) {
29
- super();
30
- this.parentScope = parentScope;
31
- this.parentScope?.onStop(() => this.stop());
32
- this.context = {};
33
- }
34
- getContext(input) {
35
- let scope = this;
36
- while (scope) {
37
- if (scope.context[input]) return scope.context[input];
38
- scope = scope.parentScope;
39
- }
40
- return {};
41
- }
42
- setContext(input, value) {
43
- this.context[input] = value;
44
- }
45
- onStop(input) {
46
- this.addEventListener("stop", input, { once: true });
47
- }
48
- stop() {
49
- return this.dispatchEvent(new StopEvent());
50
- }
51
- };
52
- function defineContext(name$1) {
53
- return name$1;
54
- }
55
- function mergeObjects(base, input) {
56
- if (input === null || input === void 0) return mergeObjects(base, {});
57
- const object = structuredClone(input);
58
- for (const key in base) {
59
- if (key === "__proto__" || key === "constructor") continue;
60
- const value = base[key];
61
- if (value === null || value === void 0) continue;
62
- if (Array.isArray(value) && Array.isArray(object[key])) object[key] = [...value, ...object[key]];
63
- else if (typeof value === "object" && typeof object[key] === "object") object[key] = mergeObjects(value, object[key]);
64
- else object[key] = value;
65
- }
66
- return object;
67
- }
68
-
69
- //#endregion
70
- //#region src/app/index.ts
71
- function createApp(inputConfig) {
72
- let config = mergeObjects(inputConfig, {
73
- modules: [],
74
- externals: [],
75
- sources: {
76
- assets: {
77
- match: "**/*",
78
- entries: ["./public"],
79
- suffix: "?raw"
80
- },
81
- routes: {
82
- match: "**/*.{js,ts}",
83
- entries: ["./routes"]
84
- },
85
- middlewares: {
86
- match: "**/*.{js,ts}",
87
- entries: ["./middlewares"]
88
- }
89
- }
90
- });
91
- for (const module of config.modules) config = mergeObjects(config, module.config);
92
- return {
93
- config,
94
- virtuals: {},
95
- alias: {}
96
- };
97
- }
98
- const SERVER = "ssr";
99
- const CLIENT = "client";
100
-
101
- //#endregion
102
- //#region src/vite/node/index.ts
103
- function splitSetCookieString(cookiesString) {
104
- if (Array.isArray(cookiesString)) return cookiesString.flatMap((c) => splitSetCookieString(c));
105
- if (typeof cookiesString !== "string") return [];
106
- const cookiesStrings = [];
107
- let pos = 0;
108
- let start;
109
- let ch;
110
- let lastComma;
111
- let nextStart;
112
- let cookiesSeparatorFound;
113
- const skipWhitespace = () => {
114
- while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) pos += 1;
115
- return pos < cookiesString.length;
116
- };
117
- const notSpecialChar = () => {
118
- ch = cookiesString.charAt(pos);
119
- return ch !== "=" && ch !== ";" && ch !== ",";
120
- };
121
- while (pos < cookiesString.length) {
122
- start = pos;
123
- cookiesSeparatorFound = false;
124
- while (skipWhitespace()) {
125
- ch = cookiesString.charAt(pos);
126
- if (ch === ",") {
127
- lastComma = pos;
128
- pos += 1;
129
- skipWhitespace();
130
- nextStart = pos;
131
- while (pos < cookiesString.length && notSpecialChar()) pos += 1;
132
- if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") {
133
- cookiesSeparatorFound = true;
134
- pos = nextStart;
135
- cookiesStrings.push(cookiesString.slice(start, lastComma));
136
- start = pos;
137
- } else pos = lastComma + 1;
138
- } else pos += 1;
139
- }
140
- if (!cookiesSeparatorFound || pos >= cookiesString.length) cookiesStrings.push(cookiesString.slice(start));
141
- }
142
- return cookiesStrings;
143
- }
144
- function createReadableStreamFromReadable(source) {
145
- let pump = new StreamPump(source);
146
- return new ReadableStream(pump, pump);
147
- }
148
- var StreamPump = class {
149
- highWaterMark;
150
- accumalatedSize;
151
- stream;
152
- controller;
153
- constructor(stream) {
154
- this.highWaterMark = stream.readableHighWaterMark || new Stream.Readable().readableHighWaterMark;
155
- this.accumalatedSize = 0;
156
- this.stream = stream;
157
- this.enqueue = this.enqueue.bind(this);
158
- this.error = this.error.bind(this);
159
- this.close = this.close.bind(this);
160
- }
161
- size(chunk) {
162
- return chunk?.byteLength || 0;
163
- }
164
- start(controller) {
165
- this.controller = controller;
166
- this.stream.on("data", this.enqueue);
167
- this.stream.once("error", this.error);
168
- this.stream.once("end", this.close);
169
- this.stream.once("close", this.close);
170
- }
171
- pull() {
172
- this.resume();
173
- }
174
- cancel(reason) {
175
- if (this.stream.destroy) this.stream.destroy(reason);
176
- this.stream.off("data", this.enqueue);
177
- this.stream.off("error", this.error);
178
- this.stream.off("end", this.close);
179
- this.stream.off("close", this.close);
180
- }
181
- enqueue(chunk) {
182
- if (this.controller) try {
183
- let bytes = chunk instanceof Uint8Array ? chunk : Buffer.from(chunk);
184
- let available = (this.controller.desiredSize || 0) - bytes.byteLength;
185
- this.controller.enqueue(bytes);
186
- if (available <= 0) this.pause();
187
- } catch (error) {
188
- this.controller.error(/* @__PURE__ */ new Error("Could not create Buffer, chunk must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object"));
189
- this.cancel();
190
- }
191
- }
192
- pause() {
193
- if (this.stream.pause) this.stream.pause();
194
- }
195
- resume() {
196
- if (this.stream.readable && this.stream.resume) this.stream.resume();
197
- }
198
- close() {
199
- if (this.controller) {
200
- this.controller.close();
201
- delete this.controller;
202
- }
203
- }
204
- error(error) {
205
- if (this.controller) {
206
- this.controller.error(error);
207
- delete this.controller;
208
- }
209
- }
210
- };
211
- function fromNodeHeaders(nodeHeaders) {
212
- let headers = new Headers();
213
- for (let [key, values] of Object.entries(nodeHeaders)) if (values) if (Array.isArray(values)) for (let value of values) headers.append(key, value);
214
- else headers.set(key, values);
215
- return headers;
216
- }
217
- function fromNodeRequest(nodeReq, nodeRes) {
218
- let origin = nodeReq.headers.origin && "null" !== nodeReq.headers.origin ? nodeReq.headers.origin : `http://${nodeReq.headers.host}`;
219
- let url = new URL(nodeReq.url ?? "", origin);
220
- let controller = new AbortController();
221
- let init = {
222
- method: nodeReq.method,
223
- headers: fromNodeHeaders(nodeReq.headers),
224
- signal: controller.signal
225
- };
226
- if (nodeReq.method !== "GET" && nodeReq.method !== "HEAD") {
227
- init.body = createReadableStreamFromReadable(nodeReq);
228
- init.duplex = "half";
229
- }
230
- nodeRes.on("finish", () => controller = null);
231
- nodeRes.on("close", () => controller?.abort());
232
- return new Request(url.href, init);
233
- }
234
- async function toNodeRequest(res, nodeRes) {
235
- nodeRes.statusCode = res.status;
236
- nodeRes.statusMessage = res.statusText;
237
- let cookiesStrings = [];
238
- for (let [name$1, value] of res.headers) if (name$1 === "set-cookie") cookiesStrings.push(...splitSetCookieString(value));
239
- else nodeRes.setHeader(name$1, value);
240
- if (cookiesStrings.length) nodeRes.setHeader("set-cookie", cookiesStrings);
241
- if (res.body) {
242
- let responseBody = res.body;
243
- let readable = Readable.from(responseBody);
244
- readable.pipe(nodeRes);
245
- await once(readable, "end");
246
- } else nodeRes.end();
247
- }
248
-
249
- //#endregion
250
- //#region src/vite/plugins/client.ts
251
- const SUFFIX = "?client";
252
- function client() {
253
- let server;
254
- let bundle;
255
- return {
256
- name: "client",
257
- sharedDuringBuild: true,
258
- configureServer(devServer) {
259
- server = devServer;
260
- },
261
- writeBundle(_, clientBundle) {
262
- if (this.environment.name === CLIENT) bundle = clientBundle;
263
- },
264
- load(key) {
265
- if (key.endsWith(SUFFIX)) {
266
- const path = key.substring(0, key.length - 7);
267
- if (bundle) for (const name$1 in bundle) {
268
- const file = bundle[name$1];
269
- if (file && file.type === "asset" && file.originalFileNames.includes(basename(path))) return file.source.toString();
270
- }
271
- return readFileSync(path, "utf-8");
272
- }
273
- return null;
274
- },
275
- async transform(code, key) {
276
- if (key.endsWith(SUFFIX)) {
277
- code = server ? await server.transformIndexHtml(key, code) : code;
278
- return { code: `export default \`${code}\`` };
279
- }
280
- return null;
281
- }
282
- };
283
- }
284
-
285
- //#endregion
286
- //#region src/vite/plugins/entry.ts
287
- function entry() {
288
- let entryName;
289
- let entryPath;
290
- return {
291
- name: "entry",
292
- enforce: "pre",
293
- sharedDuringBuild: true,
294
- resolveId: {
295
- filter: { id: /\.html$/ },
296
- handler(source, importer, options) {
297
- if (this.environment.name === CLIENT) {
298
- if (importer && entryPath) {
299
- const path = join(dirname(importer), source);
300
- if (existsSync(path)) return path;
301
- }
302
- if (options.isEntry) {
303
- entryName = basename(source);
304
- entryPath = source;
305
- return entryName;
306
- }
307
- }
308
- }
309
- },
310
- load: {
311
- filter: { id: /\.html$/ },
312
- handler(source) {
313
- if (entryName && entryPath && source === entryName) return readFileSync(entryPath, {
314
- encoding: "utf-8",
315
- flag: "r"
316
- });
317
- return null;
318
- }
319
- }
320
- };
321
- }
322
-
323
- //#endregion
324
- //#region src/vite/plugins/virtuals.ts
325
- function virtuals(virtuals$1) {
326
- const cache = /* @__PURE__ */ new Set();
327
- return {
328
- name: "virtuals",
329
- enforce: "pre",
330
- sharedDuringBuild: true,
331
- resolveId(key, importer) {
332
- if (cache.has(key)) return key;
333
- if (key.startsWith("#")) {
334
- const path = "/" + key.slice(1);
335
- cache.add(path);
336
- return path;
337
- }
338
- return null;
339
- },
340
- load(key) {
341
- const virtual = virtuals$1["#" + key.slice(1)];
342
- if (typeof virtual === "string") return readFileSync(virtual, {
343
- encoding: "utf-8",
344
- flag: "r"
345
- });
346
- var code = virtual?.(this.environment.name);
347
- if (code) return code;
348
- return null;
349
- }
350
- };
351
- }
352
-
353
- //#endregion
354
- //#region src/vite/index.ts
355
- function useKit(app, source) {
356
- source = source.toString();
357
- if (source.startsWith("file://")) source = dirname(fileURLToPath(source));
358
- return {
359
- source,
360
- toPath: (...paths) => {
361
- return join(source, ...paths).split(win32.sep).join(posix.sep);
362
- },
363
- addVirtual: (name$1, virtual) => {
364
- app.virtuals["#virtual/" + name$1] = virtual;
365
- },
366
- addAlias: (name$1, path) => {
367
- app.alias["#alias/" + name$1] = join(source, path).split(win32.sep).join(posix.sep);
368
- }
369
- };
370
- }
371
- function addRoutes(app, path) {
372
- app.config.sources.routes?.entries.push(path);
373
- }
374
- function addAssets(app, path) {
375
- app.config.sources.assets?.entries.push(path);
376
- }
377
- function addMiddlewares(app, path) {
378
- app.config.sources.middlewares?.entries.push(path);
379
- }
380
- function revojs(config) {
381
- const app = createApp(config);
382
- return [
383
- {
384
- name,
385
- version,
386
- sharedDuringBuild: true,
387
- async config() {
388
- const { toPath, addVirtual } = useKit(app, process.cwd());
389
- for (const module of app.config.modules) await module.setup?.(app);
390
- if (app.config.client) addVirtual("client", () => `import client from "${app.config.client}?client"; export default client`);
391
- if (app.config.server) addVirtual("server", () => `import { createServer } from "revojs"; export default await createServer()`);
392
- for (const name$1 in app.config.sources) {
393
- const source = app.config.sources[name$1];
394
- if (source) addVirtual(name$1, () => {
395
- const entries = {};
396
- for (let path of source.entries) {
397
- path = isAbsolute(path) ? path : toPath(path);
398
- for (const asset of globSync(source.match, { cwd: path })) entries[asset] = join(path, asset).split(win32.sep).join(posix.sep);
399
- }
400
- return `export default {${Object.keys(entries).map((name$2) => `"${name$2}": await import("${entries[name$2] + (source.suffix ?? "")}").then(module => module.default)`)}}`;
401
- });
402
- }
403
- return {
404
- appType: "custom",
405
- resolve: { alias: app.alias },
406
- build: { rollupOptions: { external: app.config.externals } },
407
- environments: {
408
- ...app.config.client && { [CLIENT]: {
409
- consumer: "client",
410
- resolve: { noExternal: true },
411
- build: {
412
- rollupOptions: { input: { index: app.config.client } },
413
- outDir: "./dist/client",
414
- copyPublicDir: true,
415
- emptyOutDir: true
416
- },
417
- define: {
418
- "import.meta.server": false,
419
- "import.meta.client": true
420
- }
421
- } },
422
- ...app.config.server && { [SERVER]: {
423
- consumer: "server",
424
- resolve: {
425
- noExternal: true,
426
- conditions: ["import"],
427
- externalConditions: ["import"]
428
- },
429
- build: {
430
- rollupOptions: { input: { index: app.config.server } },
431
- outDir: "./dist/server",
432
- copyPublicDir: false,
433
- emptyOutDir: true
434
- },
435
- define: {
436
- "import.meta.server": true,
437
- "import.meta.client": false
438
- }
439
- } }
440
- }
441
- };
442
- },
443
- configResolved(config$1) {
444
- if (app.config.client === void 0) delete config$1.environments[CLIENT];
445
- if (app.config.server === void 0) delete config$1.environments[SERVER];
446
- },
447
- async configureServer(devServer) {
448
- const target = devServer.environments[SERVER];
449
- if (isRunnableDevEnvironment(target)) return () => {
450
- devServer.middlewares.use(async (request, response, next) => {
451
- const server = await target.runner.import("#virtual/server").then((module) => module.default);
452
- if (server) {
453
- request.url = request.originalUrl;
454
- const scope = new Scope();
455
- scope.setContext(SERVER_CONTEXT, {
456
- request: fromNodeRequest(request, response),
457
- response: { headers: new Headers() },
458
- variables: process.env
459
- });
460
- await toNodeRequest(await server.fetch(scope), response).finally(() => scope.stop());
461
- }
462
- next();
463
- });
464
- };
465
- }
466
- },
467
- virtuals(app.virtuals),
468
- client(),
469
- entry()
470
- ];
471
- }
472
-
473
- //#endregion
474
- export { addAssets, addMiddlewares, addRoutes, revojs, useKit };