revojs 0.1.18 → 0.1.20

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.
@@ -0,0 +1,435 @@
1
+ import { CLIENT, SERVER, SERVER_CONTEXT, Scope, createApp, invoke } from "../app-C4yy27ko.js";
2
+ import { useKit } from "../kit-Bzr1NqHb.js";
3
+ import { basename, dirname, isAbsolute, join, posix, relative, win32 } from "path";
4
+ import { isRunnableDevEnvironment } from "vite";
5
+ import { once } from "events";
6
+ import { Readable, Stream } from "stream";
7
+ import { existsSync, readFileSync } from "fs";
8
+ import { globSync } from "tinyglobby";
9
+ import { rm } from "fs/promises";
10
+
11
+ //#region src/vite/node/index.ts
12
+ function splitSetCookieString(cookiesString) {
13
+ if (Array.isArray(cookiesString)) return cookiesString.flatMap((c) => splitSetCookieString(c));
14
+ if (typeof cookiesString !== "string") return [];
15
+ const cookiesStrings = [];
16
+ let pos = 0;
17
+ let start;
18
+ let ch;
19
+ let lastComma;
20
+ let nextStart;
21
+ let cookiesSeparatorFound;
22
+ const skipWhitespace = () => {
23
+ while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) pos += 1;
24
+ return pos < cookiesString.length;
25
+ };
26
+ const notSpecialChar = () => {
27
+ ch = cookiesString.charAt(pos);
28
+ return ch !== "=" && ch !== ";" && ch !== ",";
29
+ };
30
+ while (pos < cookiesString.length) {
31
+ start = pos;
32
+ cookiesSeparatorFound = false;
33
+ while (skipWhitespace()) {
34
+ ch = cookiesString.charAt(pos);
35
+ if (ch === ",") {
36
+ lastComma = pos;
37
+ pos += 1;
38
+ skipWhitespace();
39
+ nextStart = pos;
40
+ while (pos < cookiesString.length && notSpecialChar()) pos += 1;
41
+ if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") {
42
+ cookiesSeparatorFound = true;
43
+ pos = nextStart;
44
+ cookiesStrings.push(cookiesString.slice(start, lastComma));
45
+ start = pos;
46
+ } else pos = lastComma + 1;
47
+ } else pos += 1;
48
+ }
49
+ if (!cookiesSeparatorFound || pos >= cookiesString.length) cookiesStrings.push(cookiesString.slice(start));
50
+ }
51
+ return cookiesStrings;
52
+ }
53
+ function createReadableStreamFromReadable(source) {
54
+ let pump = new StreamPump(source);
55
+ return new ReadableStream(pump, pump);
56
+ }
57
+ var StreamPump = class {
58
+ highWaterMark;
59
+ accumalatedSize;
60
+ stream;
61
+ controller;
62
+ constructor(stream) {
63
+ this.highWaterMark = stream.readableHighWaterMark || new Stream.Readable().readableHighWaterMark;
64
+ this.accumalatedSize = 0;
65
+ this.stream = stream;
66
+ this.enqueue = this.enqueue.bind(this);
67
+ this.error = this.error.bind(this);
68
+ this.close = this.close.bind(this);
69
+ }
70
+ size(chunk) {
71
+ return chunk?.byteLength || 0;
72
+ }
73
+ start(controller) {
74
+ this.controller = controller;
75
+ this.stream.on("data", this.enqueue);
76
+ this.stream.once("error", this.error);
77
+ this.stream.once("end", this.close);
78
+ this.stream.once("close", this.close);
79
+ }
80
+ pull() {
81
+ this.resume();
82
+ }
83
+ cancel(reason) {
84
+ if (this.stream.destroy) this.stream.destroy(reason);
85
+ this.stream.off("data", this.enqueue);
86
+ this.stream.off("error", this.error);
87
+ this.stream.off("end", this.close);
88
+ this.stream.off("close", this.close);
89
+ }
90
+ enqueue(chunk) {
91
+ if (this.controller) try {
92
+ let bytes = chunk instanceof Uint8Array ? chunk : Buffer.from(chunk);
93
+ let available = (this.controller.desiredSize || 0) - bytes.byteLength;
94
+ this.controller.enqueue(bytes);
95
+ if (available <= 0) this.pause();
96
+ } catch (error) {
97
+ 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"));
98
+ this.cancel();
99
+ }
100
+ }
101
+ pause() {
102
+ if (this.stream.pause) this.stream.pause();
103
+ }
104
+ resume() {
105
+ if (this.stream.readable && this.stream.resume) this.stream.resume();
106
+ }
107
+ close() {
108
+ if (this.controller) {
109
+ this.controller.close();
110
+ delete this.controller;
111
+ }
112
+ }
113
+ error(error) {
114
+ if (this.controller) {
115
+ this.controller.error(error);
116
+ delete this.controller;
117
+ }
118
+ }
119
+ };
120
+ function fromNodeHeaders(nodeHeaders) {
121
+ let headers = new Headers();
122
+ for (let [key, values] of Object.entries(nodeHeaders)) if (values) if (Array.isArray(values)) for (let value of values) headers.append(key, value);
123
+ else headers.set(key, values);
124
+ return headers;
125
+ }
126
+ function fromNodeRequest(nodeReq, nodeRes) {
127
+ let origin = nodeReq.headers.origin && "null" !== nodeReq.headers.origin ? nodeReq.headers.origin : `http://${nodeReq.headers.host}`;
128
+ let url = new URL(nodeReq.url ?? "", origin);
129
+ let controller = new AbortController();
130
+ let init = {
131
+ method: nodeReq.method,
132
+ headers: fromNodeHeaders(nodeReq.headers),
133
+ signal: controller.signal
134
+ };
135
+ if (nodeReq.method !== "GET" && nodeReq.method !== "HEAD") {
136
+ init.body = createReadableStreamFromReadable(nodeReq);
137
+ init.duplex = "half";
138
+ }
139
+ nodeRes.on("finish", () => controller = null);
140
+ nodeRes.on("close", () => controller?.abort());
141
+ return new Request(url.href, init);
142
+ }
143
+ async function toNodeRequest(res, nodeRes) {
144
+ nodeRes.statusCode = res.status;
145
+ nodeRes.statusMessage = res.statusText;
146
+ let cookiesStrings = [];
147
+ for (let [name$1, value] of res.headers) if (name$1 === "set-cookie") cookiesStrings.push(...splitSetCookieString(value));
148
+ else nodeRes.setHeader(name$1, value);
149
+ if (cookiesStrings.length) nodeRes.setHeader("set-cookie", cookiesStrings);
150
+ if (res.body) {
151
+ let responseBody = res.body;
152
+ let readable = Readable.from(responseBody);
153
+ readable.pipe(nodeRes);
154
+ await once(readable, "end");
155
+ } else nodeRes.end();
156
+ }
157
+
158
+ //#endregion
159
+ //#region src/vite/plugins/client.ts
160
+ const SUFFIX = "?client";
161
+ function client() {
162
+ let server;
163
+ let bundle;
164
+ return {
165
+ name: "client",
166
+ sharedDuringBuild: true,
167
+ configureServer(devServer) {
168
+ server = devServer;
169
+ },
170
+ writeBundle(_, clientBundle) {
171
+ if (this.environment.name === CLIENT) bundle = clientBundle;
172
+ },
173
+ load(key) {
174
+ if (key.endsWith(SUFFIX)) {
175
+ const path = key.substring(0, key.length - 7);
176
+ if (bundle) for (const name$1 in bundle) {
177
+ const file = bundle[name$1];
178
+ if (file && file.type === "asset" && file.fileName === basename(path)) return file.source.toString();
179
+ }
180
+ return readFileSync(path, "utf-8");
181
+ }
182
+ return null;
183
+ },
184
+ async transform(code, key) {
185
+ if (key.endsWith(SUFFIX)) {
186
+ code = server ? await server.transformIndexHtml(key, code) : code;
187
+ return { code: `export default \`${code}\`` };
188
+ }
189
+ return null;
190
+ }
191
+ };
192
+ }
193
+
194
+ //#endregion
195
+ //#region src/vite/plugins/css.ts
196
+ function css() {
197
+ let devServer;
198
+ const styles = new Array();
199
+ return {
200
+ name: "css",
201
+ apply: "serve",
202
+ configureServer(server) {
203
+ devServer = server;
204
+ },
205
+ transform(_, source) {
206
+ if (source.match(/\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/)) {
207
+ if (!styles.includes(source) && !source.includes("?") && !source.includes(".node_modules") && !source.includes("@vite")) styles.push(relative(devServer.config.root, source));
208
+ }
209
+ },
210
+ transformIndexHtml() {
211
+ return [...styles.map((path) => ({
212
+ tag: "link",
213
+ injectTo: "head",
214
+ attrs: {
215
+ rel: "stylesheet",
216
+ href: "/" + path,
217
+ "data-preload": true
218
+ }
219
+ })), {
220
+ tag: "script",
221
+ injectTo: "head",
222
+ attrs: { type: "module" },
223
+ children: `
224
+ const observer = new MutationObserver(() => {
225
+ if (document.querySelector('style[data-vite-dev-id]')) {
226
+ document.querySelectorAll('[data-preload]').forEach((node) => node.remove());
227
+
228
+ observer.disconnect();
229
+ }
230
+ });
231
+
232
+ observer.observe(document.head, { childList: true });
233
+ `
234
+ }];
235
+ }
236
+ };
237
+ }
238
+
239
+ //#endregion
240
+ //#region src/vite/plugins/entry.ts
241
+ function entry() {
242
+ let entryName;
243
+ let entryPath;
244
+ return {
245
+ name: "entry",
246
+ enforce: "pre",
247
+ sharedDuringBuild: true,
248
+ resolveId: {
249
+ filter: { id: /\.html$/ },
250
+ handler(source, importer, options) {
251
+ if (this.environment.name === CLIENT) {
252
+ if (importer && entryPath) {
253
+ const path = join(dirname(importer), source);
254
+ if (existsSync(path)) return path;
255
+ }
256
+ if (options.isEntry) {
257
+ entryName = basename(source);
258
+ entryPath = source;
259
+ return entryName;
260
+ }
261
+ }
262
+ }
263
+ },
264
+ load: {
265
+ filter: { id: /\.html$/ },
266
+ handler(source) {
267
+ if (entryName && entryPath && source === entryName) return readFileSync(entryPath, {
268
+ encoding: "utf-8",
269
+ flag: "r"
270
+ });
271
+ return null;
272
+ }
273
+ }
274
+ };
275
+ }
276
+
277
+ //#endregion
278
+ //#region src/vite/plugins/virtuals.ts
279
+ function virtuals(virtuals$1) {
280
+ const cache = /* @__PURE__ */ new Set();
281
+ return {
282
+ name: "virtuals",
283
+ enforce: "pre",
284
+ sharedDuringBuild: true,
285
+ resolveId(key, importer) {
286
+ if (cache.has(key)) return key;
287
+ if (key.startsWith("#")) {
288
+ const path = "/" + key.slice(1);
289
+ cache.add(path);
290
+ return path;
291
+ }
292
+ return null;
293
+ },
294
+ load(key) {
295
+ const virtual = virtuals$1["#" + key.slice(1)];
296
+ if (typeof virtual === "string") return readFileSync(virtual, {
297
+ encoding: "utf-8",
298
+ flag: "r"
299
+ });
300
+ var code = virtual?.(this.environment.name);
301
+ if (code) return code;
302
+ return null;
303
+ }
304
+ };
305
+ }
306
+
307
+ //#endregion
308
+ //#region package.json
309
+ var name = "revojs";
310
+ var version = "0.1.20";
311
+
312
+ //#endregion
313
+ //#region src/vite/index.ts
314
+ function revojs(config) {
315
+ const app = createApp(config);
316
+ return [
317
+ {
318
+ name,
319
+ version,
320
+ sharedDuringBuild: true,
321
+ async config() {
322
+ const { toPath, addVirtual } = useKit(app, process.cwd());
323
+ for (const module of app.config.modules) await module.setup?.(app);
324
+ if (app.config.client) addVirtual("client", () => `import client from "${app.config.client}?client"; export default client`);
325
+ if (app.config.server) addVirtual("server", () => `import { createServer } from "revojs"; export default await createServer()`);
326
+ for (const name$1 in app.config.sources) {
327
+ const source = app.config.sources[name$1];
328
+ if (source) addVirtual(name$1, () => {
329
+ const entries = {};
330
+ for (let path of source.entries) {
331
+ path = isAbsolute(path) ? path : toPath(path);
332
+ for (const asset of globSync(source.match, { cwd: path })) entries[asset] = join(path, asset).split(win32.sep).join(posix.sep);
333
+ }
334
+ const content = Object.values(entries).reduce((content$1, path, index) => content$1 + `import $${index} from "${source.resolve?.(path) ?? path}" \n`, "");
335
+ const result = Object.keys(entries).map((name$2, index) => {
336
+ if (entries[name$2]) return `"${name$2}": $${index}`;
337
+ });
338
+ return `${content} export default {${result}}`;
339
+ });
340
+ }
341
+ return {
342
+ appType: "custom",
343
+ optimizeDeps: { exclude: ["revojs"] },
344
+ resolve: { alias: app.alias },
345
+ build: {
346
+ emptyOutDir: false,
347
+ assetsInlineLimit: 4096 * 4,
348
+ rollupOptions: { external: app.config.build.externals }
349
+ },
350
+ builder: {
351
+ sharedConfigBuild: true,
352
+ async buildApp(builder) {
353
+ await rm("./dist", {
354
+ recursive: true,
355
+ force: true
356
+ });
357
+ for (const key in builder.environments) {
358
+ const environment = builder.environments[key];
359
+ if (environment) await builder.build(environment);
360
+ }
361
+ }
362
+ },
363
+ environments: {
364
+ ...app.config.client && { [CLIENT]: {
365
+ consumer: "client",
366
+ resolve: { noExternal: true },
367
+ build: {
368
+ rollupOptions: { input: { index: app.config.client } },
369
+ outDir: "./dist/public",
370
+ copyPublicDir: true
371
+ },
372
+ define: {
373
+ "import.meta.server": false,
374
+ "import.meta.client": true
375
+ }
376
+ } },
377
+ ...app.config.server && { [SERVER]: {
378
+ consumer: "server",
379
+ resolve: {
380
+ noExternal: true,
381
+ conditions: ["import"],
382
+ externalConditions: ["import"]
383
+ },
384
+ build: {
385
+ rollupOptions: { input: { index: app.config.server } },
386
+ outDir: "./dist",
387
+ copyPublicDir: false
388
+ },
389
+ define: {
390
+ "import.meta.server": true,
391
+ "import.meta.client": false
392
+ }
393
+ } }
394
+ }
395
+ };
396
+ },
397
+ configResolved(config$1) {
398
+ if (app.config.client === void 0) delete config$1.environments[CLIENT];
399
+ if (app.config.server === void 0) delete config$1.environments[SERVER];
400
+ },
401
+ async configureServer(devServer) {
402
+ const target = devServer.environments[SERVER];
403
+ if (isRunnableDevEnvironment(target)) return () => {
404
+ devServer.middlewares.use(async (request, response, next) => {
405
+ const server = await target.runner.import("#virtual/server").then((module) => module.default);
406
+ if (server) {
407
+ request.url = request.originalUrl;
408
+ const scope = new Scope();
409
+ try {
410
+ scope.setContext(SERVER_CONTEXT, {
411
+ states: {},
412
+ request: fromNodeRequest(request, response),
413
+ response: { headers: new Headers() },
414
+ variables: process.env
415
+ });
416
+ var result = await invoke(scope, app.config.development.middlewares.concat({ fetch: server.fetch }));
417
+ if (result) await toNodeRequest(result, response);
418
+ } finally {
419
+ scope.stop();
420
+ }
421
+ }
422
+ next();
423
+ });
424
+ };
425
+ }
426
+ },
427
+ virtuals(app.virtuals),
428
+ client(),
429
+ entry(),
430
+ css()
431
+ ];
432
+ }
433
+
434
+ //#endregion
435
+ export { revojs };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "revojs",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
4
4
  "type": "module",
5
5
  "repository": "coverbase/revojs",
6
6
  "license": "MIT",
@@ -9,6 +9,14 @@
9
9
  "types": "./dist/index.d.ts",
10
10
  "import": "./dist/index.js"
11
11
  },
12
+ "./kit": {
13
+ "types": "./dist/kit/index.d.ts",
14
+ "import": "./dist/kit/index.js"
15
+ },
16
+ "./vite": {
17
+ "types": "./dist/vite/index.d.ts",
18
+ "import": "./dist/vite/index.js"
19
+ },
12
20
  "./types": {
13
21
  "types": "./src/types/index.d.ts"
14
22
  }
@@ -24,8 +32,13 @@
24
32
  "build": "tsdown",
25
33
  "watch": "tsdown -w"
26
34
  },
35
+ "dependencies": {
36
+ "tinyglobby": "^0.2.15",
37
+ "vite": "^7.1.10"
38
+ },
27
39
  "devDependencies": {
28
40
  "@revojs/tsconfig": "*",
41
+ "@types/node": "^24.7.2",
29
42
  "tsdown": "^0.15.1"
30
43
  }
31
44
  }
@@ -12,12 +12,6 @@ declare module "#virtual/server" {
12
12
  export default server;
13
13
  }
14
14
 
15
- declare module "#virtual/assets" {
16
- const assets: Record<string, string>;
17
-
18
- export default assets;
19
- }
20
-
21
15
  declare module "#virtual/routes" {
22
16
  import type { Route } from "revojs";
23
17
 
@@ -26,14 +20,6 @@ declare module "#virtual/routes" {
26
20
  export default routes;
27
21
  }
28
22
 
29
- declare module "#virtual/exceptions" {
30
- import type { Exception } from "revojs";
31
-
32
- const exceptions: Record<string, Exception>;
33
-
34
- export default exceptions;
35
- }
36
-
37
23
  interface ImportMeta {
38
24
  readonly server: boolean;
39
25
  readonly client: boolean;