@spirobel/mininext 0.6.1 → 0.7.1

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.
@@ -1,5 +1,11 @@
1
1
  /// <reference types="bun-types" />
2
2
  /// <reference types="bun-types" />
3
+ /// <reference types="bun-types" />
4
+ /// <reference types="bun-types" />
5
+ /// <reference types="bun-types" />
6
+ /// <reference types="bun-types" />
7
+ /// <reference types="bun-types" />
8
+ /// <reference types="bun-types" />
3
9
  import { url, Mini, has, type HtmlHandler } from "./url";
4
10
  import { isError, HtmlString, BasedHtml, head, commonHead, cssReset, basedHtml as html } from "./html";
5
11
  import { type Server, type WebSocketHandler } from "bun";
package/dist/mininext.js CHANGED
@@ -66,22 +66,35 @@ const nodeHttpsPlugin = {
66
66
  },
67
67
  };
68
68
  async function buildBackend(backendPath = "backend/backend.ts") {
69
- global.FrontendScriptUrls = [];
70
- global.FrontendScripts = [];
69
+ global.bundledFrontends = {};
71
70
  global.bundledSVGs = {};
72
71
  const i = await import(path.resolve(projectRoot(), backendPath));
73
72
  for (const frontend of url.getFrontends()) {
74
- const firstPlaceToLook = path.resolve(path.dirname(frontend.callerPath), `frontend/${frontend.path}`);
75
- const secondPlaceToLook = path.resolve(projectRoot(), `frontend/${frontend.path}`);
73
+ const firstPlaceToLook = path.resolve(path.dirname(frontend.callerPath), `frontend/${frontend.frontendFilePath}`);
74
+ const secondPlaceToLook = path.resolve(projectRoot(), `frontend/${frontend.frontendFilePath}`);
76
75
  const frontEndPath = (await Bun.file(firstPlaceToLook).exists())
77
76
  ? firstPlaceToLook
78
77
  : secondPlaceToLook;
79
78
  try {
80
- const f = await $ `bun run build.ts frontend ${frontEndPath}`.json();
81
- FrontendScriptUrls.push("/" + f.url);
82
- FrontendScripts.push(f.script);
79
+ const frontendResult = await $ `bun run build.ts frontend ${frontEndPath}`.json();
80
+ bundledFrontends[`/${frontendResult.url}`] = {
81
+ frontendContent: frontendResult.script,
82
+ frontendFilePath: frontend.frontendFilePath,
83
+ position: frontend.position,
84
+ };
83
85
  }
84
86
  catch (error) {
87
+ if (error &&
88
+ typeof error === "object" &&
89
+ "exitCode" in error &&
90
+ "stdout" in error &&
91
+ "stderr" in error &&
92
+ error.stdout instanceof Buffer &&
93
+ error.stderr instanceof Buffer) {
94
+ console.error(`Failed with exit code: ${error.exitCode}`);
95
+ console.error("Standard Output:", error.stdout.toString());
96
+ console.error("Standard Error:", error.stderr.toString());
97
+ }
85
98
  console.log(await $ `bun run build.ts frontend ${frontEndPath}`.text());
86
99
  }
87
100
  }
@@ -98,6 +111,7 @@ async function buildBackend(backendPath = "backend/backend.ts") {
98
111
  bundledSVGs[svgUrl] = {
99
112
  svgContent: await svgContent.text(),
100
113
  svgFilePath: svg.svgFilePath,
114
+ position: svg.position,
101
115
  options: svg.options,
102
116
  };
103
117
  }
@@ -108,8 +122,7 @@ async function buildBackend(backendPath = "backend/backend.ts") {
108
122
  minify: Bun.argv[2] === "dev" ? false : true, //production
109
123
  target: "bun",
110
124
  define: {
111
- FrontendScripts: JSON.stringify(FrontendScripts),
112
- FrontendScriptUrls: JSON.stringify(FrontendScriptUrls),
125
+ bundledFrontends: JSON.stringify(bundledFrontends),
113
126
  bundledSVGs: JSON.stringify(bundledSVGs),
114
127
  },
115
128
  });
package/dist/url.d.ts CHANGED
@@ -1,8 +1,22 @@
1
1
  /// <reference types="bun-types" />
2
2
  /// <reference types="bun-types" />
3
- import type { Server, WebSocketHandler } from "bun";
3
+ /// <reference types="bun-types" />
4
+ /// <reference types="bun-types" />
5
+ /// <reference types="bun-types" />
6
+ /// <reference types="bun-types" />
7
+ /// <reference types="bun-types" />
8
+ /// <reference types="bun-types" />
9
+ import type { Server, WebSocketHandler, RouterTypes, BunRequest } from "bun";
4
10
  import { html, json, dangerjson, HtmlString } from "./html";
5
11
  import { BasedHtml, type DangerJsonInHtml, type JsonString, type JsonStringValues } from "./html";
12
+ export type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS";
13
+ export type MiniNextRouteHandlerObject<T extends string> = {
14
+ [K in HTTPMethod]?: HtmlHandler<unknown, T>;
15
+ };
16
+ export type MiniNextRouteValue<T extends string> = HtmlHandler<unknown, T> | MiniNextRouteHandlerObject<T>;
17
+ export type BunRoutes<R extends {
18
+ [K in keyof R]: RouterTypes.RouteValue<Extract<K, string>>;
19
+ }> = R;
6
20
  /**
7
21
  * A helper function that helps narrow unknown objects
8
22
  * @param object - the object of type unknown that is to be narrowed
@@ -43,13 +57,13 @@ export type NamedFormHandlerReturnType<X> = HandlerReturnType | Promise<HandlerR
43
57
  * const {html,json, css, data, req, form, link, svg, deliver, route, params, header, head } = mini //pull everything out of the mini handbag
44
58
  * ```
45
59
  */
46
- export declare class Mini<X = unknown> {
60
+ export declare class Mini<X = unknown, ROUTE extends string = ""> {
47
61
  html: typeof html<X>;
48
62
  css: typeof html<X>;
49
63
  json: typeof json<X>;
50
64
  dangerjson: typeof dangerjson<X>;
51
65
  data: X;
52
- req: Request;
66
+ req: BunRequest<ROUTE>;
53
67
  head: (head: HtmlHandler | HtmlString) => undefined;
54
68
  headers: (headers: HeadersInit, overwrite?: boolean) => undefined;
55
69
  options: (options: ResponseInit) => undefined;
@@ -71,15 +85,19 @@ export declare class Mini<X = unknown> {
71
85
  * const {html,json, css, data, req, form, link, svg, deliver, route, params, header, head } = mini //pull everything out of the mini handbag
72
86
  * ```
73
87
  */
74
- export type HtmlHandler<Y = unknown> = ((mini: Mini<Y>) => LazyHandlerReturnType) | (() => LazyHandlerReturnType);
88
+ export type HtmlHandler<Y = unknown, ROUTE extends string = ""> = ((mini: Mini<Y, ROUTE>) => LazyHandlerReturnType) | (() => LazyHandlerReturnType);
75
89
  export type NamedFormHandler<Y = unknown, Z = undefined> = ((mini: Mini<Y>) => NamedFormHandlerReturnType<Z>) | (() => NamedFormHandlerReturnType<Z>);
76
90
  declare global {
77
- var FrontendScripts: Array<string>;
78
- var FrontendScriptUrls: Array<string>;
91
+ var bundledFrontends: Record<string, {
92
+ frontendFilePath: string;
93
+ frontendContent: string;
94
+ position: number;
95
+ }>;
79
96
  var bundledSVGs: Record<string, {
80
97
  svgContent: string;
81
98
  svgFilePath: string;
82
99
  options: ResponseInit;
100
+ position: number;
83
101
  }>;
84
102
  }
85
103
  export type ScriptTag = (...params: any[]) => Promise<HtmlString>;
@@ -89,6 +107,7 @@ interface LinkSettings {
89
107
  export declare class url {
90
108
  static websocket: WebSocketHandler | undefined;
91
109
  static server: Server;
110
+ static routes: BunRoutes<{}>;
92
111
  static direct_handlers_html: Map<string, HtmlHandler>;
93
112
  private static frontends;
94
113
  private static svgs;
@@ -106,22 +125,22 @@ export declare class url {
106
125
  * @param snippet this is handy to pass in a piece of html that often goes along with a certain frontend
107
126
  * @returns a html script element with the bundled frontend as the src
108
127
  */
109
- static frontend<X>(path: string, snippet?: BasedHtml): HtmlString;
110
- static frontend<X>(path: string, snippet?: HtmlHandler<X>): (mini: Mini<X>) => HtmlString;
128
+ static frontend<X>(frontendFilePath: string, snippet?: BasedHtml): HtmlString;
129
+ static frontend<X>(frontendFilePath: string, snippet?: HtmlHandler<X>): (mini: Mini<X>) => HtmlString;
111
130
  /**
112
131
  * This is used by the frontend bundler in order to find all frontends and their corresponding script files.
113
132
  */
114
133
  static getFrontends(): {
115
- path: string;
134
+ frontendFilePath: string;
116
135
  callerPath: string;
136
+ position: number;
117
137
  }[];
118
138
  static getSvgs(): {
119
139
  svgFilePath: string;
120
140
  callerPath: string;
141
+ position: number;
121
142
  options: ResponseInit;
122
143
  }[];
123
- static serveFrontend(req: Request): Response | undefined;
124
- static serveSvg(req: Request): Response | undefined;
125
144
  /**
126
145
  * tool to expose data to a frontend as a global variable.
127
146
  * @param name this will be added as window.name to the window object in the frontend
@@ -154,7 +173,7 @@ export declare class url {
154
173
  * @example const {html,json, css, data, req, form, link, svg, deliver, route, params, header, head } = mini //pull everything out of the mini handbag
155
174
  * @returns
156
175
  */
157
- handler: (dataHandler: HtmlHandler<T>) => (oldmini: Mini) => Promise<string | void | HtmlString>;
176
+ handler: (dataHandler: HtmlHandler<T>) => (oldmini: Mini) => Promise<string | void | JsonString>;
158
177
  dataMaker: DataMaker<T, Z>;
159
178
  /**
160
179
  * use this to **specify the input type for the functions**,
@@ -162,7 +181,7 @@ export declare class url {
162
181
  * that you want to use in the HtmlHandlers that follow this **data blend!**
163
182
  * @example type lol = typeof MaybeLoggedIn.$Mini
164
183
  */
165
- $Mini: Mini<T>;
184
+ $Mini: Mini<T, "">;
166
185
  /**
167
186
  * use this to **specify the input type for the functions**,
168
187
  *
@@ -186,19 +205,12 @@ export declare class url {
186
205
  * ```
187
206
  */
188
207
  static set<K extends string>(entries: [K, HtmlHandler][]): void;
208
+ static set<R extends {
209
+ [X in keyof R]: MiniNextRouteValue<Extract<X, string>>;
210
+ }>({ routes }: {
211
+ routes: R;
212
+ }): void;
189
213
  static set(urlPath: string, handler: HtmlHandler): void;
190
- /**
191
- * use this to remove routes.
192
- * @param urlPath - the route to remove
193
- * @example
194
- * ``` js
195
- * let perma_link_defined_by_editor_or_admin_user_that_changed = "/haha"
196
- * url.remove(perma_link_defined_by_editor_or_admin_user_that_changed);
197
- * // add new url after removing the old one (that might come from a sqlite db)
198
- * url.set("/huhu", (mini)=> mini.html`huhu`)
199
- * ```
200
- */
201
- static remove(urlPath: string): void;
202
214
  /**
203
215
  * wrap your handlers in this if you mutate something to prevent CSRF issues.
204
216
  * @param handler - normal html handler with mini as the argument
@@ -249,9 +261,9 @@ export declare class url {
249
261
  * @throws Will throw an Error if the provided url is not found in the urls array.
250
262
  */
251
263
  static get(Url: string): string | null;
252
- static match(req: Request, reqPath?: string): Promise<Response | undefined>;
264
+ static handleWithMini(req: BunRequest<string>, server: Server, handler: HtmlHandler): Promise<Response>;
253
265
  /**
254
- * user this to set the Websocket object. Check out [the bun docs](https://bun.sh/docs/api/websockets) for more details.
266
+ * use this to set the Websocket object. Check out [the bun docs](https://bun.sh/docs/api/websockets) for more details.
255
267
  * @param wsObject the websocketsocket object {@link WebSocketHandler}
256
268
  */
257
269
  static setWebsocket<T = undefined>(wsObject: WebSocketHandler<T>): void;
@@ -268,8 +280,9 @@ export declare class url {
268
280
  * @return {Promise<Response>} - The Response object.
269
281
  */
270
282
  static install(): {
271
- fetch: (req: Request, server: Server) => Promise<Response>;
283
+ fetch: (req: Request, server: Server) => Response;
272
284
  websocket: WebSocketHandler<undefined> | undefined;
285
+ routes: {};
273
286
  };
274
287
  }
275
288
  export {};
package/dist/url.js CHANGED
@@ -67,6 +67,7 @@ export class Mini {
67
67
  export class url {
68
68
  static websocket = undefined;
69
69
  static server;
70
+ static routes;
70
71
  // direct mapping of "url string" -> function leads to Html Response
71
72
  static direct_handlers_html = new Map();
72
73
  // An array of the uncompiled frontend files, example frontends[0] = "index.tsx" -> frontend/index.tsx (from the project root)
@@ -89,19 +90,35 @@ export class url {
89
90
  let callerPath = "";
90
91
  if (stack) {
91
92
  callerPath = stack[2].slice(stack[2].lastIndexOf("(") + 1, stack[2].lastIndexOf(".") + 3);
93
+ callerPath = callerPath.slice(callerPath.search("at") + 2).trim();
92
94
  }
93
- url.svgs.push({ svgFilePath, callerPath, options });
94
- var foundSvg = Object.entries(bundledSVGs).find(([key, value]) => value.svgFilePath === svgFilePath);
95
+ const position = url.svgs.length;
96
+ //we register the svg for bundleing.
97
+ url.svgs.push({
98
+ svgFilePath,
99
+ callerPath,
100
+ options,
101
+ position: url.svgs.length,
102
+ });
103
+ //this will be filled in by the bundling step.
104
+ var foundSvg = Object.entries(bundledSVGs).find(([key, value]) => value.position === position);
95
105
  return foundSvg && foundSvg[0];
96
106
  }
97
- static frontend(path, snippet) {
107
+ static frontend(frontendFilePath, snippet) {
98
108
  const stack = new Error().stack?.split("\n");
99
109
  let callerPath = "";
100
110
  if (stack) {
101
111
  callerPath = stack[2].slice(stack[2].lastIndexOf("(") + 1, stack[2].lastIndexOf(".") + 3);
112
+ callerPath = callerPath.slice(callerPath.search("at") + 2).trim();
102
113
  }
103
- const frontendIndex = url.frontends.push({ path, callerPath }) - 1;
104
- const scriptUrl = FrontendScriptUrls[frontendIndex];
114
+ const position = url.frontends.length;
115
+ //we register the frontend for bundleing.
116
+ url.frontends.push({ frontendFilePath, callerPath, position });
117
+ //this will be filled in by the bundling step.
118
+ const bundledFrontend = Object.entries(bundledFrontends).find(([key, value]) => value.position === position);
119
+ if (!bundledFrontend)
120
+ return;
121
+ const scriptUrl = bundledFrontend[0];
105
122
  if (snippet instanceof BasedHtml || !snippet) {
106
123
  return html ` ${snippet}
107
124
  <script type="module" src="${scriptUrl}"></script>`; // return an html script tag with the index hash
@@ -120,24 +137,6 @@ export class url {
120
137
  static getSvgs() {
121
138
  return url.svgs;
122
139
  }
123
- static serveFrontend(req) {
124
- const reqPath = new URL(req.url).pathname;
125
- const index = FrontendScriptUrls.indexOf(reqPath);
126
- if (index !== -1) {
127
- return new Response(FrontendScripts[index], {
128
- headers: {
129
- "Content-Type": "application/javascript; charset=utf-8",
130
- },
131
- });
132
- }
133
- }
134
- static serveSvg(req) {
135
- const reqPath = new URL(req.url).pathname;
136
- const resolvedSvg = bundledSVGs[reqPath];
137
- if (resolvedSvg) {
138
- return new Response(resolvedSvg.svgContent, resolvedSvg.options);
139
- }
140
- }
141
140
  /**
142
141
  * tool to expose data to a frontend as a global variable.
143
142
  * @param name this will be added as window.name to the window object in the frontend
@@ -222,27 +221,14 @@ export class url {
222
221
  if (typeof entries === "string" && handler) {
223
222
  addUrl(entries, handler);
224
223
  }
225
- if (typeof entries !== "string")
224
+ if (typeof entries !== "string" && "routes" in entries) {
225
+ url.routes = entries.routes;
226
+ }
227
+ if (typeof entries !== "string" && !("routes" in entries))
226
228
  for (const [entryUrl, entryHandler] of entries) {
227
229
  addUrl(entryUrl, entryHandler);
228
230
  }
229
231
  }
230
- /**
231
- * use this to remove routes.
232
- * @param urlPath - the route to remove
233
- * @example
234
- * ``` js
235
- * let perma_link_defined_by_editor_or_admin_user_that_changed = "/haha"
236
- * url.remove(perma_link_defined_by_editor_or_admin_user_that_changed);
237
- * // add new url after removing the old one (that might come from a sqlite db)
238
- * url.set("/huhu", (mini)=> mini.html`huhu`)
239
- * ```
240
- */
241
- static remove(urlPath) {
242
- for (const u of url.generateVariations(urlPath)) {
243
- url.direct_handlers_html.delete(u);
244
- }
245
- }
246
232
  /**
247
233
  * wrap your handlers in this if you mutate something to prevent CSRF issues.
248
234
  * @param handler - normal html handler with mini as the argument
@@ -399,95 +385,92 @@ export class url {
399
385
  }
400
386
  return Url;
401
387
  }
402
- static async match(req, reqPath) {
388
+ static async handleWithMini(req, server, handler) {
389
+ if (!url.server)
390
+ url.server = server;
403
391
  const miniurl = Object.freeze(new URL(req.url));
404
- if (typeof reqPath === "undefined") {
405
- reqPath = miniurl.pathname;
392
+ const reqPath = miniurl.pathname;
393
+ let redirectTarget = null;
394
+ let redirectStatus = undefined;
395
+ let handlerHead = undefined;
396
+ let handlerOptions = {
397
+ headers: {
398
+ "Content-Type": "text/html; charset=utf-8",
399
+ },
400
+ };
401
+ const post = req.method === "POST";
402
+ let formJson;
403
+ let formData;
404
+ const urlencoded = (req.headers.get("Content-Type") + "").includes("application/x-www-form-urlencoded");
405
+ const multipart = (req.headers.get("Content-Type") + "").includes("multipart/form-data");
406
+ if (post && !urlencoded && !multipart) {
407
+ const length = Number(req.headers.get("content-length"));
408
+ const bodyNotEmpty = length > 0;
409
+ if (bodyNotEmpty) {
410
+ formJson = await req.json();
411
+ }
412
+ else {
413
+ formJson = {};
414
+ }
406
415
  }
407
- const handler = url.direct_handlers_html.get(reqPath);
408
- if (handler) {
409
- let redirectTarget = null;
410
- let redirectStatus = undefined;
411
- let handlerHead = undefined;
412
- let handlerOptions = {
413
- headers: {
414
- "Content-Type": "text/html; charset=utf-8",
416
+ if (post && (urlencoded || multipart)) {
417
+ formData = await req.formData();
418
+ }
419
+ //this is the source of mini
420
+ const mini = new Mini({
421
+ requrl: miniurl,
422
+ data: undefined,
423
+ req: req,
424
+ html,
425
+ css: html,
426
+ deliver: url.deliver,
427
+ route: reqPath,
428
+ params: new URL(req.url).searchParams,
429
+ json,
430
+ form: {
431
+ post,
432
+ urlencoded,
433
+ multipart,
434
+ formJson,
435
+ formData,
436
+ onPostSubmit(cb) {
437
+ if (post) {
438
+ return cb();
439
+ }
415
440
  },
416
- };
417
- const post = req.method === "POST";
418
- let formJson;
419
- let formData;
420
- const urlencoded = (req.headers.get("Content-Type") + "").includes("application/x-www-form-urlencoded");
421
- const multipart = (req.headers.get("Content-Type") + "").includes("multipart/form-data");
422
- if (post && !urlencoded && !multipart) {
423
- const length = Number(req.headers.get("content-length"));
424
- const bodyNotEmpty = length > 0;
425
- if (bodyNotEmpty) {
426
- formJson = await req.json();
441
+ actionlink: (qs = "", settings) => url.link(reqPath, qs, settings),
442
+ },
443
+ dangerjson,
444
+ head: (head) => {
445
+ handlerHead = head;
446
+ },
447
+ headers: (headers, overwrite = false) => {
448
+ if (overwrite) {
449
+ handlerOptions.headers = headers;
427
450
  }
428
451
  else {
429
- formJson = {};
452
+ handlerOptions.headers = {
453
+ ...handlerOptions.headers,
454
+ ...headers,
455
+ };
430
456
  }
431
- }
432
- if (post && (urlencoded || multipart)) {
433
- formData = await req.formData();
434
- }
435
- //this is the source of mini
436
- const mini = new Mini({
437
- requrl: miniurl,
438
- data: undefined,
439
- req,
440
- html,
441
- css: html,
442
- deliver: url.deliver,
443
- route: reqPath,
444
- params: new URL(req.url).searchParams,
445
- json,
446
- form: {
447
- post,
448
- urlencoded,
449
- multipart,
450
- formJson,
451
- formData,
452
- onPostSubmit(cb) {
453
- if (post) {
454
- return cb();
455
- }
456
- },
457
- actionlink: (qs = "", settings) => url.link(reqPath, qs, settings),
458
- },
459
- dangerjson,
460
- head: (head) => {
461
- handlerHead = head;
462
- },
463
- headers: (headers, overwrite = false) => {
464
- if (overwrite) {
465
- handlerOptions.headers = headers;
466
- }
467
- else {
468
- handlerOptions.headers = {
469
- ...handlerOptions.headers,
470
- ...headers,
471
- };
472
- }
473
- },
474
- options: (options) => {
475
- handlerOptions = options;
476
- },
477
- redirect: (url, status) => {
478
- redirectTarget = url;
479
- redirectStatus = status;
480
- },
481
- }, undefined);
482
- const unresolved = await handler(mini); //passing mini
483
- if (redirectTarget) {
484
- return Response.redirect(redirectTarget, redirectStatus);
485
- }
486
- return htmlResponder(mini, unresolved, handlerHead, handlerOptions);
457
+ },
458
+ options: (options) => {
459
+ handlerOptions = options;
460
+ },
461
+ redirect: (url, status) => {
462
+ redirectTarget = url;
463
+ redirectStatus = status;
464
+ },
465
+ }, undefined);
466
+ const unresolved = await handler(mini); //passing mini
467
+ if (redirectTarget) {
468
+ return Response.redirect(redirectTarget, redirectStatus);
487
469
  }
470
+ return htmlResponder(mini, unresolved, handlerHead, handlerOptions);
488
471
  }
489
472
  /**
490
- * user this to set the Websocket object. Check out [the bun docs](https://bun.sh/docs/api/websockets) for more details.
473
+ * use this to set the Websocket object. Check out [the bun docs](https://bun.sh/docs/api/websockets) for more details.
491
474
  * @param wsObject the websocketsocket object {@link WebSocketHandler}
492
475
  */
493
476
  static setWebsocket(wsObject) {
@@ -508,24 +491,44 @@ export class url {
508
491
  * @return {Promise<Response>} - The Response object.
509
492
  */
510
493
  static install() {
511
- async function fetchFunction(req, server) {
512
- if (!url.server)
513
- url.server = server;
514
- //go through all the Htmlhandlers and see if there is a match
515
- let res = await url.match(req);
516
- if (res)
517
- return res;
518
- //handle frontend js file serving
519
- res = url.serveFrontend(req);
520
- if (res)
521
- return res;
522
- //handle svg file serving
523
- res = url.serveSvg(req);
524
- if (res)
525
- return res;
494
+ for (const route in url.routes) {
495
+ //handle route object split by methods and pull them through mininext
496
+ const handler = url.routes[route];
497
+ if (typeof handler === "function") {
498
+ url.routes[route] = (req, server) => url.handleWithMini(req, server, handler);
499
+ }
500
+ else {
501
+ const newHandlerObject = {};
502
+ for (const HTTPmethod in handler) {
503
+ newHandlerObject[HTTPmethod] = (req, server) => url.handleWithMini(req, server, handler[HTTPmethod]);
504
+ }
505
+ url.routes[route] = newHandlerObject;
506
+ }
507
+ }
508
+ //TODO add fronted + svg to routes object
509
+ for (const [route, handler] of url.direct_handlers_html) {
510
+ url.routes[route] = (req, server) => url.handleWithMini(req, server, handler);
511
+ }
512
+ for (const svgUrl in bundledSVGs) {
513
+ const resolvedSvg = bundledSVGs[svgUrl];
514
+ url.routes[svgUrl] = (req, server) => new Response(resolvedSvg.svgContent, resolvedSvg.options);
515
+ }
516
+ for (const frontendUrl in bundledFrontends) {
517
+ const resolvedFrontend = bundledFrontends[frontendUrl];
518
+ url.routes[frontendUrl] = (req, server) => new Response(resolvedFrontend.frontendContent, {
519
+ headers: {
520
+ "Content-Type": "application/javascript; charset=utf-8",
521
+ },
522
+ });
523
+ }
524
+ function fetchFunction(req, server) {
526
525
  return new Response("No matching url found", { status: 404 });
527
526
  }
528
- return { fetch: fetchFunction, websocket: url.websocket };
527
+ return {
528
+ fetch: fetchFunction,
529
+ websocket: url.websocket,
530
+ routes: url.routes,
531
+ };
529
532
  }
530
533
  }
531
534
  const no_post_warning = html `<div style="color:red;">
package/package.json CHANGED
@@ -11,9 +11,9 @@
11
11
  "clean": "rm -rf ./dist"
12
12
  },
13
13
  "files": ["dist"],
14
- "version": "0.6.1",
14
+ "version": "0.7.1",
15
15
  "devDependencies": {
16
- "@types/bun": "latest"
16
+ "@types/bun": "^1.2.9"
17
17
  },
18
18
  "peerDependencies": {
19
19
  "typescript": "^5.0.0"