revojs 0.0.85 → 0.0.87

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.
@@ -11,9 +11,11 @@ export type Module = {
11
11
  };
12
12
  export type ClientConfig = {
13
13
  entry: ClientEntry;
14
+ externals: Array<string>;
14
15
  };
15
16
  export type ServerConfig = {
16
17
  entry: ServerEntry;
18
+ externals: Array<string>;
17
19
  };
18
20
  export type DevelopmentConfig = {
19
21
  middleware: Array<Middleware>;
@@ -29,9 +29,7 @@ export declare function sendRedirect(scope: Scope, path: string): Response;
29
29
  export declare function sendBadRequest(scope: Scope, text: string): Response;
30
30
  export declare function sendUnauthorized(scope: Scope): Response;
31
31
  export declare function useUrl(scope: Scope, base?: string): URL;
32
- export declare function useQuery(scope: Scope): {
33
- [k: string]: string;
34
- };
32
+ export declare function useQuery(scope: Scope): Record<string, string>;
35
33
  export declare function useCookies(scope: Scope): Record<string, string>;
36
34
  export declare function useSetCookies(scope: Scope): Record<string, string>;
37
35
  export declare function setCookie(scope: Scope, name: string, value: string, options?: CookieOptions): void;
package/dist/index.d.ts CHANGED
@@ -5,4 +5,5 @@ export * from "./locale";
5
5
  export * from "./radix";
6
6
  export * from "./router";
7
7
  export * from "./runtime";
8
+ export * from "./schema";
8
9
  export * from "./signals";
package/dist/index.js CHANGED
@@ -16,8 +16,14 @@ function createApp(config) {
16
16
  return {
17
17
  config: mergeObjects(config, {
18
18
  modules: [],
19
- client: { entry: "index.html" },
20
- server: { entry: "@revojs/bun/runtime" },
19
+ client: {
20
+ entry: "index.html",
21
+ externals: []
22
+ },
23
+ server: {
24
+ entry: "@revojs/bun/runtime",
25
+ externals: []
26
+ },
21
27
  dev: { middleware: [] }
22
28
  }),
23
29
  virtuals: {}
@@ -111,6 +117,12 @@ function namespace(tag) {
111
117
  return svgElements.has(tag) ? "http://www.w3.org/2000/svg" : "http://www.w3.org/1999/xhtml";
112
118
  }
113
119
 
120
+ //#endregion
121
+ //#region src/schema/index.ts
122
+ function isFailure(result) {
123
+ return "issues" in result;
124
+ }
125
+
114
126
  //#endregion
115
127
  //#region src/http/index.ts
116
128
  function sendText(scope, text) {
@@ -148,25 +160,43 @@ function useUrl(scope, base) {
148
160
  const { request } = useRuntime(scope);
149
161
  return new URL(request?.url ?? window?.location.href, base);
150
162
  }
151
- function useQuery(scope) {
163
+ function useQuery(scope, schema) {
152
164
  const { searchParams } = useUrl(scope);
153
- return Object.fromEntries(searchParams);
165
+ const entries = Object.fromEntries(searchParams);
166
+ if (schema) {
167
+ const result = schema["~standard"].validate(entries);
168
+ if (isFailure(result)) throw sendBadRequest(scope, result.issues.join(", "));
169
+ return result.value;
170
+ }
171
+ return entries;
154
172
  }
155
- function useCookies(scope) {
173
+ function useCookies(scope, schema) {
156
174
  const { request } = useRuntime(scope);
157
- return (isClient() ? document.cookie : request.headers.get("Cookie") ?? "").split("; ").reduce((result, cookie) => {
175
+ const entries = (isClient() ? document.cookie : request.headers.get("Cookie") ?? "").split("; ").reduce((result, cookie) => {
158
176
  const [name, value] = cookie.split("=");
159
177
  if (name && value) result[name] = decodeURIComponent(value);
160
178
  return result;
161
179
  }, {});
180
+ if (schema) {
181
+ const result = schema["~standard"].validate(entries);
182
+ if (isFailure(result)) throw sendBadRequest(scope, result.issues.join(", "));
183
+ return result.value;
184
+ }
185
+ return entries;
162
186
  }
163
- function useSetCookies(scope) {
187
+ function useSetCookies(scope, schema) {
164
188
  const { request } = useRuntime(scope);
165
- return request.headers.getSetCookie().reduce((result, cookie) => {
189
+ const entries = request.headers.getSetCookie().reduce((result, cookie) => {
166
190
  const [name, value] = cookie.split("=");
167
191
  if (name && value) result[name] = decodeURIComponent(value);
168
192
  return result;
169
193
  }, {});
194
+ if (schema) {
195
+ const result = schema["~standard"].validate(entries);
196
+ if (isFailure(result)) throw sendBadRequest(scope, result.issues.join(", "));
197
+ return result.value;
198
+ }
199
+ return entries;
170
200
  }
171
201
  function setCookie(scope, name, value, options) {
172
202
  const { response } = useRuntime(scope);
@@ -399,6 +429,15 @@ function useRuntime(scope) {
399
429
  function useRoute(scope) {
400
430
  return scope.getContext(ROUTE_CONTEXT);
401
431
  }
432
+ async function useRoutes() {
433
+ return await import("#virtual/routes").then((module) => module.default);
434
+ }
435
+ async function useAssets() {
436
+ return await import("#virtual/assets").then((module) => module.default);
437
+ }
438
+ async function useLocales() {
439
+ return await import("#virtual/locales").then((module) => module.default);
440
+ }
402
441
  function defineRoute(route) {
403
442
  return route;
404
443
  }
@@ -454,24 +493,26 @@ function useState(scope, name, value) {
454
493
  }
455
494
  return state;
456
495
  }
457
- function useAsync(scope, name, invoke, options) {
496
+ function useAsync(scope, name, invoke, defaultOptions) {
458
497
  const { tasks } = useRuntime(scope);
459
498
  const state = useState(scope, name);
460
499
  const isLoading = createState(false);
461
- const execute = async () => {
500
+ const execute = async (options) => {
501
+ const onCatch = options?.catch ?? defaultOptions?.catch;
502
+ const viewTransition = options?.viewTransition ?? defaultOptions?.viewTransition;
462
503
  isLoading.value = true;
463
504
  try {
464
505
  const result = await invoke();
465
- if (JSON.stringify(state.value ?? {}) !== JSON.stringify(result)) if (options?.viewTransition) await startViewTransition(options.viewTransition, () => state.value = result);
506
+ if (JSON.stringify(state.value ?? {}) !== JSON.stringify(result)) if (viewTransition) await startViewTransition(viewTransition, () => state.value = result);
466
507
  else state.value = result;
467
508
  } catch (error) {
468
- options?.catch?.(error);
509
+ onCatch?.(error);
469
510
  } finally {
470
511
  isLoading.value = false;
471
512
  }
472
513
  return state.value;
473
514
  };
474
- const task = execute();
515
+ const task = execute(defaultOptions);
475
516
  if (isServer()) tasks.push(task);
476
517
  return {
477
518
  state,
@@ -485,7 +526,7 @@ function useFetch(scope, input, options) {
485
526
  async function createRuntime() {
486
527
  const radix = new Radix();
487
528
  const middlewares = new Array();
488
- const routes = await import("#virtual/routes").then((module) => module.default);
529
+ const routes = await useRoutes();
489
530
  for (const path in routes) {
490
531
  const [name, method] = toPath(path);
491
532
  radix.insert((method ?? "GET").toUpperCase() + name, defineRoute({ fetch: async (scope) => {
@@ -509,7 +550,7 @@ async function createRuntime() {
509
550
  })));
510
551
  } }));
511
552
  }
512
- const assets = await import("#virtual/assets").then((module) => module.default);
553
+ const assets = await useAssets();
513
554
  for (const path in assets) radix.insert("GET/" + path, defineRoute({ fetch: async (scope) => {
514
555
  const { response } = useRuntime(scope);
515
556
  let content = assets[path];
@@ -980,19 +1021,19 @@ function useLocale(scope, context) {
980
1021
  const $ = (key) => {
981
1022
  return () => messages.value?.[key] ?? key;
982
1023
  };
983
- const date = (date$1, options$1) => {
1024
+ const $date = (date, options$1) => {
984
1025
  const format = new Intl.DateTimeFormat(locale.value, options$1);
985
- if (date$1) return format.format(date$1);
1026
+ if (date) return format.format(date);
986
1027
  };
987
1028
  return {
988
1029
  locale,
989
1030
  messages,
990
1031
  options,
991
1032
  $,
992
- date
1033
+ $date
993
1034
  };
994
1035
  }
995
1036
  const LOCALE_CONTEXT = defineContext("LOCALE_CONTEXT");
996
1037
 
997
1038
  //#endregion
998
- export { $fetch, AfterNavigateEvent, CLIENT, Compute, HOST_CONTEXT, Handler, LOCALE_CONTEXT, MountedEvent, NavigateEvent, Page, ROUTER_CONTEXT, ROUTE_CONTEXT, RUNTIME_CONTEXT, Radix, SERVER, STATES, Scope, StopEvent, activeCompute, activeViewTransition, components, createApp, createCompute, createElement, createMemo, createRuntime, createState, defineComponent, defineContext, defineMiddleware, defineRoute, fileName, fromValue, hydrate, isClient, isComponent, isCustomElement, isRoute, isServer, isTemplate, mergeObjects, mimeType, onMounted, onViewTransition, preventDefault, provideLocaleContext, provideRouterContext, registerComponent, renderToString, sendBadRequest, sendHtml, sendJson, sendRedirect, sendText, sendUnauthorized, setCookie, startViewTransition, stopImmediatePropagation, stopPropagation, targets, toArray, toCustomElement, toFragment, toPath, toRange, toString, untrack, useAsync, useCookies, useEvent, useFetch, useHost, useLocale, useQuery, useRoute, useRouter, useRuntime, useSetCookies, useState, useUrl };
1039
+ export { $fetch, AfterNavigateEvent, CLIENT, Compute, HOST_CONTEXT, Handler, LOCALE_CONTEXT, MountedEvent, NavigateEvent, Page, ROUTER_CONTEXT, ROUTE_CONTEXT, RUNTIME_CONTEXT, Radix, SERVER, STATES, Scope, StopEvent, activeCompute, activeViewTransition, components, createApp, createCompute, createElement, createMemo, createRuntime, createState, defineComponent, defineContext, defineMiddleware, defineRoute, fileName, fromValue, hydrate, isClient, isComponent, isCustomElement, isFailure, isRoute, isServer, isTemplate, mergeObjects, mimeType, onMounted, onViewTransition, preventDefault, provideLocaleContext, provideRouterContext, registerComponent, renderToString, sendBadRequest, sendHtml, sendJson, sendRedirect, sendText, sendUnauthorized, setCookie, startViewTransition, stopImmediatePropagation, stopPropagation, targets, toArray, toCustomElement, toFragment, toPath, toRange, toString, untrack, useAssets, useAsync, useCookies, useEvent, useFetch, useHost, useLocale, useLocales, useQuery, useRoute, useRouter, useRoutes, useRuntime, useSetCookies, useState, useUrl };
@@ -14,13 +14,13 @@ export declare function provideLocaleContext(scope: Scope, options: LocaleOption
14
14
  messages: State<Record<string, string> | undefined>;
15
15
  options: LocaleOptions;
16
16
  $: (key: string) => () => string | number | symbol;
17
- date: (date?: Date, options?: Intl.DateTimeFormatOptions) => string | undefined;
17
+ $date: (date?: Date, options?: Intl.DateTimeFormatOptions) => string | undefined;
18
18
  };
19
19
  export declare function useLocale<T extends LocaleContext>(scope: Scope, context?: Descriptor<T>): {
20
20
  locale: State<string | undefined>;
21
21
  messages: State<Record<string, string> | undefined>;
22
22
  options: LocaleOptions;
23
23
  $: (key: keyof T["options"]["locales"][keyof T["options"]["locales"]]) => () => string | number | symbol;
24
- date: (date?: Date, options?: Intl.DateTimeFormatOptions) => string | undefined;
24
+ $date: (date?: Date, options?: Intl.DateTimeFormatOptions) => string | undefined;
25
25
  };
26
26
  export declare const LOCALE_CONTEXT: Descriptor<LocaleContext>;
@@ -23,12 +23,15 @@ export type RouteContext = {
23
23
  inputs: State<Record<string, string>>;
24
24
  };
25
25
  export type AsyncOptions<T> = {
26
- viewTransition?: string;
26
+ viewTransition?: false | string;
27
27
  catch?: (error: T) => void | Promise<void>;
28
28
  };
29
29
  export declare function isRoute<T>(value?: T): value is Route & T;
30
30
  export declare function useRuntime<T = Record<string, unknown>>(scope: Scope): RuntimeContext<T>;
31
31
  export declare function useRoute(scope: Scope): RouteContext;
32
+ export declare function useRoutes(): Promise<Record<string, unknown>>;
33
+ export declare function useAssets(): Promise<Record<string, string>>;
34
+ export declare function useLocales(): Promise<Record<string, Record<string, string>>>;
32
35
  export declare function defineRoute(route: Route): Route;
33
36
  export declare function defineMiddleware(middleware: Middleware): Middleware;
34
37
  export declare function fileName(path: string): string | undefined;
@@ -36,15 +39,15 @@ export declare function toPath(value: string): (string | undefined)[];
36
39
  export declare function $fetch<T>(scope: Scope, input: string | URL, options?: RequestInit): Promise<T>;
37
40
  export declare function useState<T>(scope: Scope, name: string): State<T | undefined>;
38
41
  export declare function useState<T>(scope: Scope, name: string, value: T): State<T>;
39
- export declare function useAsync<T, TError = Error>(scope: Scope, name: string, invoke: () => Promise<T>, options?: AsyncOptions<TError>): {
42
+ export declare function useAsync<T, TError = Error>(scope: Scope, name: string, invoke: () => Promise<T>, defaultOptions?: AsyncOptions<TError>): {
40
43
  state: State<T | undefined>;
41
44
  isLoading: State<boolean>;
42
- execute: () => Promise<T | undefined>;
45
+ execute: (options?: AsyncOptions<TError>) => Promise<T | undefined>;
43
46
  };
44
47
  export declare function useFetch<T, TError = Error>(scope: Scope, input: string | URL, options?: RequestInit & AsyncOptions<TError>): {
45
48
  state: State<T | undefined>;
46
49
  isLoading: State<boolean>;
47
- execute: () => Promise<T | undefined>;
50
+ execute: (options?: AsyncOptions<TError> | undefined) => Promise<T | undefined>;
48
51
  };
49
52
  export declare function createRuntime(): Promise<Runtime>;
50
53
  export declare let STATES: Record<string, unknown>;
@@ -0,0 +1,22 @@
1
+ export type Issue = {
2
+ readonly message: string;
3
+ };
4
+ export type Success<T> = {
5
+ readonly value: T;
6
+ };
7
+ export type Failure = {
8
+ readonly issues: ReadonlyArray<Issue>;
9
+ };
10
+ export type Result<Output> = Success<Output> | Failure;
11
+ export type Schema<T = unknown, TOutput = T> = {
12
+ readonly "~standard": {
13
+ readonly validate: (value: unknown) => Result<TOutput>;
14
+ readonly types?: {
15
+ readonly input: T;
16
+ readonly output: TOutput;
17
+ };
18
+ };
19
+ };
20
+ export type InferInput<T extends Schema> = NonNullable<T["~standard"]["types"]>["input"];
21
+ export type InferOutput<T extends Schema> = NonNullable<T["~standard"]["types"]>["output"];
22
+ export declare function isFailure<T>(result: Result<T>): result is Failure;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "revojs",
3
- "version": "0.0.85",
3
+ "version": "0.0.87",
4
4
  "type": "module",
5
5
  "repository": "coverbase/revojs",
6
6
  "license": "MIT",