revojs 0.0.48 → 0.0.50

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,12 +1,13 @@
1
- import { type Template } from "../html";
2
- import type { Middleware } from "../http";
1
+ import type { Middleware } from "../runtime";
3
2
  export type NestedPartial<T> = T extends any[] ? T : T extends Record<string, any> ? {
4
3
  [P in keyof T]?: NestedPartial<T[P]>;
5
4
  } : T;
6
5
  export type Environment = typeof CLIENT | typeof SERVER;
6
+ export type Virtual = (environment: Environment) => void | string;
7
+ export type ClientEntry = "index.html" | (string & {});
7
8
  export type ServerEntry = "revojs/presets/node" | "revojs/presets/deno" | "revojs/presets/bun" | "revojs/presets/cloudflare" | (string & {});
8
9
  export type ClientConfig = {
9
- entry: string;
10
+ entry: ClientEntry;
10
11
  };
11
12
  export type ServerConfig = {
12
13
  entry: ServerEntry;
@@ -15,15 +16,14 @@ export type DevelopmentConfig = {
15
16
  middleware: Array<Middleware>;
16
17
  };
17
18
  export type Config = {
18
- client: ClientConfig;
19
+ client: false | ClientConfig;
19
20
  server: false | ServerConfig;
20
- markdown: Record<string, Template>;
21
21
  dev: DevelopmentConfig;
22
22
  };
23
23
  export type App = {
24
24
  config: Config;
25
- virtuals: Record<string, (environment: Environment) => string>;
25
+ virtuals: Record<string, Virtual>;
26
26
  };
27
- export declare const createApp: <T>(config?: NestedPartial<Config>) => App;
27
+ export declare const createApp: (config?: NestedPartial<Config>) => App;
28
28
  export declare const SERVER = "ssr";
29
29
  export declare const CLIENT = "client";
@@ -87,7 +87,6 @@ export declare const registerComponent: <TEvents extends Events, TAttributes ext
87
87
  export declare function useEvent<T extends keyof ElementEventMap>(scope: Scope, target: EventTarget | undefined | null, event: T, input: EventListener<ElementEventMap[T]>, options?: AddEventListenerOptions): void;
88
88
  export declare function useEvent<T extends keyof WindowEventMap>(scope: Scope, target: Window | undefined | null, event: T, input: EventListener<WindowEventMap[T]>, options?: AddEventListenerOptions): void;
89
89
  export declare function useEvent<T extends keyof HTMLElementEventMap>(scope: Scope, target: HTMLElement | undefined | null, event: T, input: EventListener<HTMLElementEventMap[T]>, options?: AddEventListenerOptions): void;
90
- export declare const getCustomElement: (node: Node | null) => CustomElement<Events, Attributes> | undefined;
91
90
  export declare const isClient: () => boolean;
92
91
  export declare const isServer: () => boolean;
93
92
  export declare const preventDefault: (event: Event) => void;
@@ -19,15 +19,15 @@ export type ResponseOptions = {
19
19
  headers: Headers;
20
20
  };
21
21
  export type Handle = (scope: Scope) => void | Response | Promise<void | Response>;
22
- export type Middleware = (scope: Scope, next: Handle) => void | Response | Promise<void | Response>;
22
+ export type Chain = (scope: Scope, next: Handle) => void | Response | Promise<void | Response>;
23
23
  export declare const sendText: (scope: Scope, text: string) => Response;
24
24
  export declare const sendHtml: (scope: Scope, text: string) => Response;
25
25
  export declare const sendJson: <T>(scope: Scope, value: T) => Response;
26
26
  export declare const sendRedirect: (scope: Scope, path: string) => Response;
27
27
  export declare const sendBadRequest: (scope: Scope, text: string) => Response;
28
28
  export declare const sendUnauthorized: (scope: Scope) => Response;
29
- export declare const getRequestUrl: (scope: Scope, base?: string) => URL;
30
- export declare const getCookies: (scope: Scope) => Record<string, string>;
31
- export declare const getSetCookies: (scope: Scope) => Record<string, string>;
29
+ export declare const useRequestUrl: (scope: Scope, base?: string) => URL;
30
+ export declare const useCookies: (scope: Scope) => Record<string, string>;
31
+ export declare const useSetCookies: (scope: Scope) => Record<string, string>;
32
32
  export declare const setCookie: (scope: Scope, name: string, value: string, options?: CookieOptions) => void;
33
- export declare const getMimeType: (file: string) => MimeType;
33
+ export declare const mimeType: (file: string) => MimeType;
package/dist/index.d.ts CHANGED
@@ -2,7 +2,6 @@ export * from "./app";
2
2
  export * from "./html";
3
3
  export * from "./http";
4
4
  export * from "./locale";
5
- export * from "./markdown";
6
5
  export * from "./radix";
7
6
  export * from "./router";
8
7
  export * from "./runtime";
package/dist/index.js CHANGED
@@ -7,7 +7,6 @@ const createApp = (config) => {
7
7
  config: defu(config, {
8
8
  client: { entry: "./index.html" },
9
9
  server: { entry: "revojs/presets/node" },
10
- markdown: {},
11
10
  dev: { middleware: [] }
12
11
  }),
13
12
  virtuals: {}
@@ -412,7 +411,7 @@ const toCustomElement = (Component) => {
412
411
  internals: this.internals
413
412
  });
414
413
  await hydrate(this.component.scope, rootNode, await this.component.setup(), 0);
415
- this.dispatchEvent(new MountedEvent());
414
+ requestAnimationFrame(() => this.dispatchEvent(new MountedEvent()));
416
415
  }
417
416
  attributeChangedCallback(name, oldValue, value) {
418
417
  if (value === oldValue) return;
@@ -462,12 +461,6 @@ function useEvent(scope, target, event, input, options) {
462
461
  });
463
462
  scope.onStop(() => controller.abort());
464
463
  }
465
- const getCustomElement = (node) => {
466
- if (node) {
467
- if ("component" in node) return node;
468
- return getCustomElement(node.parentNode);
469
- }
470
- };
471
464
  const isClient = () => typeof window !== "undefined";
472
465
  const isServer = () => typeof window === "undefined";
473
466
  const preventDefault = (event) => event.preventDefault();
@@ -527,6 +520,9 @@ const useRoute = (scope) => {
527
520
  const defineRoute = (route) => {
528
521
  return route;
529
522
  };
523
+ const defineMiddleware = (middleware) => {
524
+ return middleware;
525
+ };
530
526
  const fileName = (path) => {
531
527
  return path.split("/").pop()?.split(".").slice(0, -1).join(".");
532
528
  };
@@ -573,23 +569,23 @@ const createRuntime = async () => {
573
569
  const assets = await import("#virtual/assets").then((module) => module.assets);
574
570
  for (const path in assets) radix.insert("GET/" + path, defineRoute({ fetch: async (scope) => {
575
571
  const { response } = useRuntime(scope);
576
- response.headers.set("Content-Type", getMimeType(path));
572
+ response.headers.set("Content-Type", mimeType(path));
577
573
  return new Response(await assets[path]?.(), response);
578
574
  } }));
579
- const invoke = (scope, next, index) => {
580
- return middlewares.at(index)?.(scope, () => invoke(scope, next, index + 1)) ?? next(scope);
575
+ const invoke = (scope, route, index) => {
576
+ return middlewares.at(index)?.fetch(scope, () => invoke(scope, route, index + 1)) ?? route.fetch(scope);
581
577
  };
582
578
  return {
583
579
  radix,
584
580
  middlewares,
585
581
  fetch: async (scope) => {
586
582
  const { request } = useRuntime(scope);
587
- const url = getRequestUrl(scope);
588
- const { value: route, inputs } = radix.match(request.method + url.pathname);
583
+ const { pathname } = useRequestUrl(scope);
584
+ const { value: route, inputs } = radix.match(request.method + pathname);
589
585
  try {
590
586
  scope.setContext(ROUTE_CONTEXT, { inputs: createState(inputs) });
591
587
  if (route) {
592
- const response = await invoke(scope, route.fetch, 0);
588
+ const response = await invoke(scope, route, 0);
593
589
  if (response) return response;
594
590
  }
595
591
  return sendText(scope, "NOT_FOUND");
@@ -636,19 +632,19 @@ const sendUnauthorized = (scope) => {
636
632
  response.status = 401;
637
633
  return new Response(null, response);
638
634
  };
639
- const getRequestUrl = (scope, base) => {
635
+ const useRequestUrl = (scope, base) => {
640
636
  const { request } = useRuntime(scope);
641
637
  return new URL(request.url, base);
642
638
  };
643
- const getCookies = (scope) => {
639
+ const useCookies = (scope) => {
644
640
  const { request } = useRuntime(scope);
645
- return (request.headers.get("Cookie")?.split("; ") ?? []).reduce((result, cookie) => {
641
+ return (isClient() ? document.cookie : request.headers.get("Cookie") ?? "").split("; ").reduce((result, cookie) => {
646
642
  const [name, value] = cookie.split("=");
647
643
  if (name && value) result[name] = decodeURIComponent(value);
648
644
  return result;
649
645
  }, {});
650
646
  };
651
- const getSetCookies = (scope) => {
647
+ const useSetCookies = (scope) => {
652
648
  const { request } = useRuntime(scope);
653
649
  return request.headers.getSetCookie().reduce((result, cookie) => {
654
650
  const [name, value] = cookie.split("=");
@@ -667,9 +663,10 @@ const setCookie = (scope, name, value, options) => {
667
663
  if (options?.priority) cookie += `; Priority=${options.priority}`;
668
664
  if (options?.sameSite) cookie += `; SameSite=${options.sameSite}`;
669
665
  if (options?.secure) cookie += `; Secure`;
670
- response.headers.append("Set-Cookie", cookie);
666
+ if (isClient()) document.cookie = cookie;
667
+ else response.headers.append("Set-Cookie", cookie);
671
668
  };
672
- const getMimeType = (file) => {
669
+ const mimeType = (file) => {
673
670
  const extension = /\.([a-zA-Z0-9]+?)$/.exec(file)?.at(1);
674
671
  return mimeTypes[extension ?? ""] ?? "text/plain";
675
672
  };
@@ -787,7 +784,7 @@ const useRouter = (scope, context) => {
787
784
  const Page = defineComponent({
788
785
  name: "x-page",
789
786
  setup: ({ scope }) => {
790
- const { route } = scope.getContext(ROUTER_CONTEXT);
787
+ const { route } = useRouter(scope);
791
788
  return () => route.value;
792
789
  }
793
790
  });
@@ -841,97 +838,4 @@ const useLocale = (scope, context) => {
841
838
  };
842
839
 
843
840
  //#endregion
844
- //#region src/markdown/index.ts
845
- const charWhile = (buffer, start, ...chars) => {
846
- let depth = 0;
847
- let current = buffer.at(start + depth);
848
- while (current && chars.includes(current)) {
849
- depth += 1;
850
- current = buffer.at(start + depth);
851
- }
852
- return depth;
853
- };
854
- const charUntil = (buffer, start, ...chars) => {
855
- let depth = 0;
856
- let current = buffer.at(start + depth);
857
- while (current && !chars.includes(current)) {
858
- depth += 1;
859
- current = buffer.at(start + depth);
860
- }
861
- return depth;
862
- };
863
- const inlineText = (buffer, options) => {
864
- const nodes = new Array();
865
- let index = 0;
866
- while (index < buffer.length) {
867
- const char = buffer.charAt(index);
868
- const text = charUntil(buffer, index, "*", "_", "\n");
869
- if (text > 0) {
870
- nodes.push(buffer.slice(index, index + text));
871
- index += text;
872
- continue;
873
- }
874
- if (char === "*" || char === "_") {
875
- const start = charWhile(buffer, index, char);
876
- const between = charUntil(buffer, index + start, char);
877
- const end = charWhile(buffer, index + start + between, char);
878
- const min = Math.min(start, end, 2);
879
- const leading = start - min;
880
- const trailing = end - min;
881
- const slice = buffer.slice(index + leading + min, index + start + between + end - trailing - min);
882
- if (slice.length > 0) {
883
- const inline = inlineText(char.repeat(leading) + slice + char.repeat(trailing), options);
884
- const tag = min === 2 ? "strong" : "em";
885
- nodes.push(defu(options?.[tag], {
886
- tag,
887
- attributes: {},
888
- children: inline
889
- }));
890
- }
891
- index += start + between + end;
892
- continue;
893
- }
894
- if (char === "\n") {
895
- nodes.push(defu(options?.["br"], {
896
- tag: "br",
897
- attributes: {},
898
- children: []
899
- }));
900
- index += 1;
901
- continue;
902
- }
903
- }
904
- return nodes;
905
- };
906
- const markdownToSlot = (input, options) => {
907
- const nodes = new Array();
908
- const buffer = input.replace(/[\r]+/g, "").trim();
909
- let index = 0;
910
- while (index < buffer.length) {
911
- const start = index;
912
- let lines = charWhile(buffer, index, "\n");
913
- while (lines < 2 && index < buffer.length) {
914
- index += lines + charUntil(buffer, index + lines, "\n");
915
- lines = charWhile(buffer, index, "\n");
916
- }
917
- const block = buffer.slice(start, index);
918
- if (block.startsWith("#")) {
919
- const depth = charWhile(block, 0, "#");
920
- const tag = "h" + depth;
921
- nodes.push(defu(options?.[tag], {
922
- tag,
923
- attributes: {},
924
- children: inlineText(block.slice(depth))
925
- }));
926
- } else nodes.push(defu(options?.["p"], {
927
- tag: "p",
928
- attributes: {},
929
- children: inlineText(block)
930
- }));
931
- index += lines;
932
- }
933
- return nodes;
934
- };
935
-
936
- //#endregion
937
- export { $fetch, CLIENT, Compute, HOST_CONTEXT, Handler, LOCALE_CONTEXT, MountedEvent, NavigateEvent, Page, ROUTER_CONTEXT, ROUTE_CONTEXT, RUNTIME_CONTEXT, Radix, SERVER, Scope, StopEvent, activeCompute, components, createApp, createCompute, createElement, createLocale, createMemo, createRouter, createRuntime, createState, defineComponent, defineContext, defineRoute, fileName, fromValue, getCookies, getCustomElement, getMimeType, getRequestUrl, getSetCookies, hydrate, isClient, isServer, isTemplate, markdownToSlot, preventDefault, registerComponent, renderToString, sendBadRequest, sendHtml, sendJson, sendRedirect, sendText, sendUnauthorized, setCookie, stopImmediatePropagation, stopPropagation, targets, toArray, toCustomElement, toFragment, toPath, toRange, toString, useEvent, useHost, useLocale, useRoute, useRouter, useRuntime };
841
+ export { $fetch, CLIENT, Compute, HOST_CONTEXT, Handler, LOCALE_CONTEXT, MountedEvent, NavigateEvent, Page, ROUTER_CONTEXT, ROUTE_CONTEXT, RUNTIME_CONTEXT, Radix, SERVER, Scope, StopEvent, activeCompute, components, createApp, createCompute, createElement, createLocale, createMemo, createRouter, createRuntime, createState, defineComponent, defineContext, defineMiddleware, defineRoute, fileName, fromValue, hydrate, isClient, isServer, isTemplate, mimeType, preventDefault, registerComponent, renderToString, sendBadRequest, sendHtml, sendJson, sendRedirect, sendText, sendUnauthorized, setCookie, stopImmediatePropagation, stopPropagation, targets, toArray, toCustomElement, toFragment, toPath, toRange, toString, useCookies, useEvent, useHost, useLocale, useRequestUrl, useRoute, useRouter, useRuntime, useSetCookies };
@@ -1,9 +1,12 @@
1
- import { type Handle, type Middleware, type ResponseOptions } from "../http";
1
+ import { type Chain, type Handle, type ResponseOptions } from "../http";
2
2
  import { Radix } from "../radix";
3
3
  import { Scope, type State } from "../signals";
4
4
  export type Route = {
5
5
  fetch: Handle;
6
6
  };
7
+ export type Middleware = {
8
+ fetch: Chain;
9
+ };
7
10
  export type Runtime = {
8
11
  radix: Radix<Route>;
9
12
  middlewares: Array<Middleware>;
@@ -17,9 +20,10 @@ export type RuntimeContext<T = Record<string, unknown>> = {
17
20
  export type RouteContext = {
18
21
  inputs: State<Record<string, string>>;
19
22
  };
20
- export declare const useRuntime: (scope: Scope) => RuntimeContext<Record<string, unknown>>;
23
+ export declare const useRuntime: <T = Record<string, unknown>>(scope: Scope) => RuntimeContext<T>;
21
24
  export declare const useRoute: (scope: Scope) => RouteContext;
22
25
  export declare const defineRoute: (route: Route) => Route;
26
+ export declare const defineMiddleware: (middleware: Middleware) => Middleware;
23
27
  export declare const fileName: (path: string) => string | undefined;
24
28
  export declare const toPath: (value: string) => (string | undefined)[];
25
29
  export declare const $fetch: <T>(scope: Scope, input: string | URL, options?: RequestInit) => Promise<T>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "revojs",
3
- "version": "0.0.48",
3
+ "version": "0.0.50",
4
4
  "type": "module",
5
5
  "repository": "coverbase/revojs",
6
6
  "license": "MIT",
@@ -1,2 +0,0 @@
1
- import type { Template } from "../html";
2
- export declare const markdownToSlot: (input: string, options?: Record<string, Template>) => unknown[];