revojs 0.0.67 → 0.0.69

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.
@@ -24,6 +24,6 @@ export type App = {
24
24
  config: Config;
25
25
  virtuals: Record<string, Virtual>;
26
26
  };
27
- export declare const createApp: (config?: NestedPartial<Config>) => App;
27
+ export declare function createApp(config?: NestedPartial<Config>): App;
28
28
  export declare const SERVER = "ssr";
29
29
  export declare const CLIENT = "client";
@@ -46,7 +46,6 @@ export interface ComponentOptions<TEvents extends Events, TAttributes extends At
46
46
  events?: TEvents;
47
47
  attributes?: TAttributes;
48
48
  shadowRoot?: ShadowRootInit;
49
- styles?: Array<string>;
50
49
  setup: (component: Component<TEvents, TAttributes>) => Slot;
51
50
  }
52
51
  export interface Component<TEvents extends Events, TAttributes extends Attributes> {
@@ -60,7 +59,6 @@ export interface ComponentConstructor<TEvents extends Events, TAttributes extend
60
59
  $name: string;
61
60
  $events: TEvents;
62
61
  $attributes: TAttributes;
63
- $styles: Array<string>;
64
62
  new (input?: Input<TEvents, TAttributes>, parentScope?: Scope): Component<TEvents, TAttributes>;
65
63
  }
66
64
  export interface CustomElement<TEvents extends Events, TAttributes extends Attributes> extends HTMLElement {
@@ -72,30 +70,30 @@ export interface CustomElementConstructor<TEvents extends Events, TAttributes ex
72
70
  export declare class MountedEvent extends Event {
73
71
  constructor();
74
72
  }
75
- export declare const isTemplate: <T>(value?: T) => value is Template & T;
76
- export declare const isCustomElement: <T>(value?: T) => value is CustomElement<Events, Attributes> & T;
77
- export declare const isComponent: <T>(value?: T) => value is ComponentConstructor<Events, Attributes> & T;
78
- export declare const useHost: (scope: Scope) => HostContext;
79
- export declare const createElement: <TEvents extends Events, TAttributes extends Attributes>(input: string | ComponentConstructor<TEvents, TAttributes>, attributes?: AttributeInput<TAttributes>, ...children: Array<Slot>) => Slot;
80
- export declare const toString: (slot: Slot) => string;
81
- export declare const toArray: (hydration: Hydration) => Array<Node>;
82
- export declare const toRange: (hydration: Hydration) => Range;
83
- export declare const toFragment: (hydration: Hydration) => DocumentFragment;
84
- export declare const hydrate: (scope: Scope, parentNode: Node, slot: Slot, index: number, previous?: Hydration) => Hydration;
85
- export declare const renderToString: (scope: Scope, slot: Slot) => Promise<string>;
86
- export declare const defineComponent: <TEvents extends Events, TAttributes extends Attributes>(options: ComponentOptions<TEvents, TAttributes>) => ComponentConstructor<TEvents, TAttributes>;
87
- export declare const toCustomElement: <TEvents extends Events, TAttributes extends Attributes>(Component: ComponentConstructor<TEvents, TAttributes>) => CustomElementConstructor<TEvents, TAttributes>;
88
- export declare const registerComponent: <TEvents extends Events, TAttributes extends Attributes>(component: ComponentConstructor<TEvents, TAttributes>) => ComponentConstructor<TEvents, TAttributes>;
73
+ export declare function isTemplate<T>(value?: T): value is Template & T;
74
+ export declare function isCustomElement<T>(value?: T): value is CustomElement<Events, Attributes> & T;
75
+ export declare function isComponent<T>(value?: T): value is ComponentConstructor<Events, Attributes> & T;
76
+ export declare function useHost(scope: Scope): HostContext;
77
+ export declare function createElement<TEvents extends Events, TAttributes extends Attributes>(input: string | ((attributes: AttributeInput<Attributes>) => Slot) | ComponentConstructor<TEvents, TAttributes>, attributes?: AttributeInput<TAttributes>, ...children: Array<Slot>): Slot;
78
+ export declare function toString(slot: Slot): string;
79
+ export declare function toArray(hydration: Hydration): Array<Node>;
80
+ export declare function toRange(hydration: Hydration): Range;
81
+ export declare function toFragment(hydration: Hydration): DocumentFragment;
82
+ export declare function hydrate(scope: Scope, parentNode: Node, slot: Slot, index: number, previous?: Hydration): Hydration;
83
+ export declare function renderToString(scope: Scope, slot: Slot): Promise<string>;
84
+ export declare function defineComponent<TEvents extends Events, TAttributes extends Attributes>(options: ComponentOptions<TEvents, TAttributes>): ComponentConstructor<TEvents, TAttributes>;
85
+ export declare function toCustomElement<TEvents extends Events, TAttributes extends Attributes>(Component: ComponentConstructor<TEvents, TAttributes>): CustomElementConstructor<TEvents, TAttributes>;
86
+ export declare function registerComponent<TEvents extends Events, TAttributes extends Attributes>(component: ComponentConstructor<TEvents, TAttributes>): ComponentConstructor<TEvents, TAttributes>;
89
87
  export declare function useEvent<T extends keyof ElementEventMap>(scope: Scope, target: EventTarget | undefined | null, event: T, input: EventListener<ElementEventMap[T]>, options?: AddEventListenerOptions): void;
90
88
  export declare function useEvent<T extends keyof WindowEventMap>(scope: Scope, target: Window | undefined | null, event: T, input: EventListener<WindowEventMap[T]>, options?: AddEventListenerOptions): void;
91
89
  export declare function useEvent<T extends keyof HTMLElementEventMap>(scope: Scope, target: Document | HTMLElement | undefined | null, event: T, input: EventListener<HTMLElementEventMap[T]>, options?: AddEventListenerOptions): void;
92
- export declare const onMounted: (scope: Scope, event: EventListener<MountedEvent>) => void;
93
- export declare const startViewTransition: (invoke: ViewTransitionUpdateCallback) => Promise<void>;
94
- export declare const isClient: () => boolean;
95
- export declare const isServer: () => boolean;
96
- export declare const preventDefault: (event: Event) => void;
97
- export declare const stopPropagation: (event: Event) => void;
98
- export declare const stopImmediatePropagation: (event: Event) => void;
90
+ export declare function onMounted(scope: Scope, event: EventListener<MountedEvent>): void;
91
+ export declare function startViewTransition(invoke: ViewTransitionUpdateCallback): Promise<void>;
92
+ export declare function isClient(): boolean;
93
+ export declare function isServer(): boolean;
94
+ export declare function preventDefault(event: Event): void;
95
+ export declare function stopPropagation(event: Event): void;
96
+ export declare function stopImmediatePropagation(event: Event): void;
99
97
  export declare const components: Map<string, ComponentConstructor<Events, Attributes>>;
100
98
  export declare const HOST_CONTEXT: import("..").Descriptor<HostContext>;
101
99
  declare global {
@@ -20,14 +20,14 @@ export type ResponseOptions = {
20
20
  };
21
21
  export type Handle = (scope: Scope) => void | Response | Promise<void | Response>;
22
22
  export type Chain = (scope: Scope, next: Handle) => void | Response | Promise<void | Response>;
23
- export declare const sendText: (scope: Scope, text: string) => Response;
24
- export declare const sendHtml: (scope: Scope, text: string) => Response;
25
- export declare const sendJson: <T>(scope: Scope, value: T) => Response;
26
- export declare const sendRedirect: (scope: Scope, path: string) => Response;
27
- export declare const sendBadRequest: (scope: Scope, text: string) => Response;
28
- export declare const sendUnauthorized: (scope: Scope) => Response;
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
- export declare const setCookie: (scope: Scope, name: string, value: string, options?: CookieOptions) => void;
33
- export declare const mimeType: (file: string) => MimeType;
23
+ export declare function sendText(scope: Scope, text: string): Response;
24
+ export declare function sendHtml(scope: Scope, text: string): Response;
25
+ export declare function sendJson<T>(scope: Scope, value: T): Response;
26
+ export declare function sendRedirect(scope: Scope, path: string): Response;
27
+ export declare function sendBadRequest(scope: Scope, text: string): Response;
28
+ export declare function sendUnauthorized(scope: Scope): Response;
29
+ export declare function useUrl(scope: Scope, base?: string): URL;
30
+ export declare function useCookies(scope: Scope): Record<string, string>;
31
+ export declare function useSetCookies(scope: Scope): Record<string, string>;
32
+ export declare function setCookie(scope: Scope, name: string, value: string, options?: CookieOptions): void;
33
+ export declare function mimeType(file: string): MimeType;
package/dist/index.js CHANGED
@@ -1,16 +1,141 @@
1
- import { defu } from "defu";
1
+ //#region src/signals/index.ts
2
+ var StopEvent = class extends Event {
3
+ constructor() {
4
+ super("stop");
5
+ }
6
+ };
7
+ var Scope = class extends EventTarget {
8
+ parentScope;
9
+ context;
10
+ constructor(parentScope) {
11
+ super();
12
+ this.parentScope = parentScope;
13
+ this.parentScope?.onStop(() => this.stop());
14
+ this.context = /* @__PURE__ */ new Map();
15
+ }
16
+ getContext(input) {
17
+ let scope = this;
18
+ while (scope) {
19
+ if (scope.context.has(input)) return scope.context.get(input);
20
+ scope = scope.parentScope;
21
+ }
22
+ return {};
23
+ }
24
+ setContext(input, value) {
25
+ this.context.set(input, value);
26
+ }
27
+ onStop(input) {
28
+ this.addEventListener("stop", input, { once: true });
29
+ }
30
+ stop() {
31
+ return this.dispatchEvent(new StopEvent());
32
+ }
33
+ };
34
+ var Compute = class extends Scope {
35
+ invoke;
36
+ constructor(parentScope, invoke) {
37
+ super(parentScope);
38
+ this.invoke = invoke;
39
+ }
40
+ run() {
41
+ this.stop();
42
+ return this.invoke(this);
43
+ }
44
+ };
45
+ var Handler = class Handler {
46
+ get(target, key) {
47
+ const compute = activeCompute;
48
+ if (compute) {
49
+ const computes = targets.get(target) ?? /* @__PURE__ */ new Map();
50
+ const set = computes.get(key) ?? /* @__PURE__ */ new Set();
51
+ computes.set(key, set.add(compute));
52
+ targets.set(target, computes);
53
+ compute.parentScope?.onStop(() => {
54
+ set.delete(compute);
55
+ if (set.size === 0) {
56
+ computes.delete(key);
57
+ if (computes.size === 0) targets.delete(target);
58
+ }
59
+ });
60
+ }
61
+ const value = Reflect.get(target, key);
62
+ if (value) {
63
+ if (typeof value === "function" && !value.prototype) return value.bind(target);
64
+ if (typeof value === "object") {
65
+ const tag = Object.prototype.toString.call(value);
66
+ if (tag === "[object Object]" || tag === "[object Array]" || tag === "[object Map]" || tag === "[object Set]" || tag === "[object WeakMap]" || tag === "[object WeakSet]") return new Proxy(value, new Handler());
67
+ }
68
+ }
69
+ return value;
70
+ }
71
+ set(target, key, value) {
72
+ const result = Reflect.set(target, key, value);
73
+ for (const compute of targets.get(target)?.get(key) ?? []) compute.run();
74
+ return result;
75
+ }
76
+ };
77
+ function createState(value) {
78
+ return new Proxy({ value }, new Handler());
79
+ }
80
+ function createCompute(scope, invoke) {
81
+ let previous = activeCompute;
82
+ activeCompute = new Compute(scope, invoke);
83
+ const result = invoke(activeCompute);
84
+ if (result instanceof Promise) return result.finally(() => activeCompute = previous);
85
+ activeCompute = previous;
86
+ return result;
87
+ }
88
+ function createMemo(scope, invoke) {
89
+ let state;
90
+ const compute = createCompute(scope, (scope$1) => {
91
+ const value = invoke(scope$1);
92
+ if (typeof state === "object") state.value = value;
93
+ return value;
94
+ });
95
+ state = createState(compute);
96
+ return state;
97
+ }
98
+ function fromValue(value) {
99
+ if (value instanceof Function) return fromValue(value());
100
+ return value;
101
+ }
102
+ function untrack(invoke) {
103
+ let previous = activeCompute;
104
+ activeCompute = void 0;
105
+ const result = invoke();
106
+ if (result instanceof Promise) return result.finally(() => activeCompute = previous);
107
+ activeCompute = previous;
108
+ return result;
109
+ }
110
+ function mergeObjects(base, input) {
111
+ const object = structuredClone(input);
112
+ for (const key in base) {
113
+ if (key === "__proto__" || key === "constructor") continue;
114
+ const value = base[key];
115
+ if (value === null || value === void 0) continue;
116
+ if (typeof value === "object" && typeof object[key] === "object") object[key] = mergeObjects(value, object[key]);
117
+ else object[key] = value;
118
+ }
119
+ return object;
120
+ }
121
+ function defineContext(key) {
122
+ return key;
123
+ }
124
+ let activeCompute;
125
+ const targets = /* @__PURE__ */ new WeakMap();
2
126
 
127
+ //#endregion
3
128
  //#region src/app/index.ts
4
- const createApp = (config) => {
129
+ function createApp(config) {
5
130
  return {
6
- config: defu(config, {
131
+ config: mergeObjects(config, {
7
132
  client: { entry: "./index.html" },
8
133
  server: { entry: "revojs/presets/node" },
9
134
  dev: { middleware: [] }
10
135
  }),
11
136
  virtuals: {}
12
137
  };
13
- };
138
+ }
14
139
  const SERVER = "ssr";
15
140
  const CLIENT = "client";
16
141
 
@@ -95,64 +220,64 @@ const svgElements = new Set([
95
220
  "view",
96
221
  "vkern"
97
222
  ]);
98
- const namespace = (tag) => {
223
+ function namespace(tag) {
99
224
  return svgElements.has(tag) ? "http://www.w3.org/2000/svg" : "http://www.w3.org/1999/xhtml";
100
- };
225
+ }
101
226
 
102
227
  //#endregion
103
228
  //#region src/http/index.ts
104
- const sendText = (scope, text) => {
229
+ function sendText(scope, text) {
105
230
  const { response } = useRuntime(scope);
106
231
  response.headers.set("Content-Type", "text/plain");
107
232
  return new Response(text, response);
108
- };
109
- const sendHtml = (scope, text) => {
233
+ }
234
+ function sendHtml(scope, text) {
110
235
  const { response } = useRuntime(scope);
111
236
  response.headers.set("Content-Type", "text/html");
112
237
  return new Response(text, response);
113
- };
114
- const sendJson = (scope, value) => {
238
+ }
239
+ function sendJson(scope, value) {
115
240
  const { response } = useRuntime(scope);
116
241
  response.headers.set("Content-Type", "application/json");
117
242
  return new Response(JSON.stringify(value), response);
118
- };
119
- const sendRedirect = (scope, path) => {
243
+ }
244
+ function sendRedirect(scope, path) {
120
245
  const { response } = useRuntime(scope);
121
246
  response.status = 302;
122
247
  response.headers.set("Location", path);
123
248
  return new Response(null, response);
124
- };
125
- const sendBadRequest = (scope, text) => {
249
+ }
250
+ function sendBadRequest(scope, text) {
126
251
  const { response } = useRuntime(scope);
127
252
  response.status = 400;
128
253
  return new Response(text, response);
129
- };
130
- const sendUnauthorized = (scope) => {
254
+ }
255
+ function sendUnauthorized(scope) {
131
256
  const { response } = useRuntime(scope);
132
257
  response.status = 401;
133
258
  return new Response(null, response);
134
- };
135
- const useRequestUrl = (scope, base) => {
259
+ }
260
+ function useUrl(scope, base) {
136
261
  const { request } = useRuntime(scope);
137
- return new URL(request.url, base);
138
- };
139
- const useCookies = (scope) => {
262
+ return new URL(request?.url ?? window?.location.href, base);
263
+ }
264
+ function useCookies(scope) {
140
265
  const { request } = useRuntime(scope);
141
266
  return (isClient() ? document.cookie : request.headers.get("Cookie") ?? "").split("; ").reduce((result, cookie) => {
142
267
  const [name, value] = cookie.split("=");
143
268
  if (name && value) result[name] = decodeURIComponent(value);
144
269
  return result;
145
270
  }, {});
146
- };
147
- const useSetCookies = (scope) => {
271
+ }
272
+ function useSetCookies(scope) {
148
273
  const { request } = useRuntime(scope);
149
274
  return request.headers.getSetCookie().reduce((result, cookie) => {
150
275
  const [name, value] = cookie.split("=");
151
276
  if (name && value) result[name] = decodeURIComponent(value);
152
277
  return result;
153
278
  }, {});
154
- };
155
- const setCookie = (scope, name, value, options) => {
279
+ }
280
+ function setCookie(scope, name, value, options) {
156
281
  const { response } = useRuntime(scope);
157
282
  let cookie = name + "=" + encodeURIComponent(value);
158
283
  if (options?.domain) cookie += `; Domain=${options.domain}`;
@@ -165,11 +290,11 @@ const setCookie = (scope, name, value, options) => {
165
290
  if (options?.secure) cookie += `; Secure`;
166
291
  if (isClient()) document.cookie = cookie;
167
292
  else response.headers.append("Set-Cookie", cookie);
168
- };
169
- const mimeType = (file) => {
293
+ }
294
+ function mimeType(file) {
170
295
  const extension = /\.([a-zA-Z0-9]+?)$/.exec(file)?.at(1);
171
296
  return mimeTypes[extension ?? ""] ?? "text/plain";
172
- };
297
+ }
173
298
  const mimeTypes = {
174
299
  txt: "text/plain",
175
300
  css: "text/css",
@@ -256,149 +381,33 @@ var Radix = class Radix {
256
381
  };
257
382
  };
258
383
 
259
- //#endregion
260
- //#region src/signals/index.ts
261
- var StopEvent = class extends Event {
262
- constructor() {
263
- super("stop");
264
- }
265
- };
266
- var Scope = class extends EventTarget {
267
- parentScope;
268
- context;
269
- constructor(parentScope) {
270
- super();
271
- this.parentScope = parentScope;
272
- this.parentScope?.onStop(() => this.stop());
273
- this.context = /* @__PURE__ */ new Map();
274
- }
275
- getContext(input) {
276
- let scope = this;
277
- while (scope) {
278
- if (scope.context.has(input)) return scope.context.get(input);
279
- scope = scope.parentScope;
280
- }
281
- return {};
282
- }
283
- setContext(input, value) {
284
- this.context.set(input, value);
285
- }
286
- onStop(input) {
287
- this.addEventListener("stop", input, { once: true });
288
- }
289
- stop() {
290
- return this.dispatchEvent(new StopEvent());
291
- }
292
- };
293
- var Compute = class extends Scope {
294
- invoke;
295
- constructor(parentScope, invoke) {
296
- super(parentScope);
297
- this.invoke = invoke;
298
- }
299
- run() {
300
- this.stop();
301
- return this.invoke(this);
302
- }
303
- };
304
- var Handler = class Handler {
305
- get(target, key) {
306
- const compute = activeCompute;
307
- if (compute) {
308
- const computes = targets.get(target) ?? /* @__PURE__ */ new Map();
309
- const set = computes.get(key) ?? /* @__PURE__ */ new Set();
310
- computes.set(key, set.add(compute));
311
- targets.set(target, computes);
312
- compute.parentScope?.onStop(() => {
313
- set.delete(compute);
314
- if (set.size === 0) {
315
- computes.delete(key);
316
- if (computes.size === 0) targets.delete(target);
317
- }
318
- });
319
- }
320
- const value = Reflect.get(target, key);
321
- if (value) {
322
- if (typeof value === "function" && !value.prototype) return value.bind(target);
323
- if (typeof value === "object") {
324
- const tag = Object.prototype.toString.call(value);
325
- if (tag === "[object Object]" || tag === "[object Array]" || tag === "[object Map]" || tag === "[object Set]" || tag === "[object WeakMap]" || tag === "[object WeakSet]") return new Proxy(value, new Handler());
326
- }
327
- }
328
- return value;
329
- }
330
- set(target, key, value) {
331
- const result = Reflect.set(target, key, value);
332
- for (const compute of targets.get(target)?.get(key) ?? []) compute.run();
333
- return result;
334
- }
335
- };
336
- function createState(value) {
337
- return new Proxy({ value }, new Handler());
338
- }
339
- function createCompute(scope, invoke) {
340
- let previous = activeCompute;
341
- activeCompute = new Compute(scope, invoke);
342
- const result = invoke(activeCompute);
343
- if (result instanceof Promise) return result.finally(() => activeCompute = previous);
344
- activeCompute = previous;
345
- return result;
346
- }
347
- function createMemo(scope, invoke) {
348
- let state;
349
- const compute = createCompute(scope, (scope$1) => {
350
- const value = invoke(scope$1);
351
- if (typeof state === "object") state.value = value;
352
- return value;
353
- });
354
- state = createState(compute);
355
- return state;
356
- }
357
- function fromValue(value) {
358
- if (value instanceof Function) return fromValue(value());
359
- return value;
360
- }
361
- function untrack(invoke) {
362
- let previous = activeCompute;
363
- activeCompute = void 0;
364
- const result = invoke();
365
- if (result instanceof Promise) return result.finally(() => activeCompute = previous);
366
- activeCompute = previous;
367
- return result;
368
- }
369
- function defineContext(key) {
370
- return key;
371
- }
372
- let activeCompute;
373
- const targets = /* @__PURE__ */ new WeakMap();
374
-
375
384
  //#endregion
376
385
  //#region src/runtime/index.ts
377
- const isRoute = (value) => {
386
+ function isRoute(value) {
378
387
  return !!value && typeof value === "object" && "fetch" in value;
379
- };
380
- const useRuntime = (scope) => {
388
+ }
389
+ function useRuntime(scope) {
381
390
  return scope.getContext(RUNTIME_CONTEXT);
382
- };
383
- const useRoute = (scope) => {
391
+ }
392
+ function useRoute(scope) {
384
393
  return scope.getContext(ROUTE_CONTEXT);
385
- };
386
- const defineRoute = (route) => {
394
+ }
395
+ function defineRoute(route) {
387
396
  return route;
388
- };
389
- const defineMiddleware = (middleware) => {
397
+ }
398
+ function defineMiddleware(middleware) {
390
399
  return middleware;
391
- };
392
- const fileName = (path) => {
400
+ }
401
+ function fileName(path) {
393
402
  return path.split("/").pop()?.split(".").slice(0, -1).join(".");
394
- };
395
- const toPath = (value) => {
403
+ }
404
+ function toPath(value) {
396
405
  const path = (value.startsWith("/") ? value : "/" + value).replaceAll(/\/index/g, "").replaceAll(/\[(.*?)\]/g, (_, name) => ":" + name);
397
406
  const route = path.startsWith("/") ? path : "/" + path;
398
407
  const split = route.split(".");
399
408
  return split.length === 3 ? [split.at(0), split.at(1)] : [split.at(0)];
400
- };
401
- const $fetch = async (scope, input, options) => {
409
+ }
410
+ async function $fetch(scope, input, options) {
402
411
  const { request, variables } = useRuntime(scope);
403
412
  let response;
404
413
  if (request) {
@@ -420,19 +429,31 @@ const $fetch = async (scope, input, options) => {
420
429
  case "application/json": return response.json();
421
430
  default: return response;
422
431
  }
423
- };
424
- const useAsync = (scope, invoke, options) => {
432
+ }
433
+ function useAsync(scope, invoke, options) {
425
434
  const { tasks } = useRuntime(scope);
426
435
  const state = createState();
427
436
  const isLoading = createState(true);
428
- const task = invoke().then((value) => state.value = value).catch(options?.catch).finally(() => isLoading.value = false);
437
+ const execute = async () => {
438
+ try {
439
+ state.value = await invoke().finally(() => isLoading.value = false);
440
+ } catch (error) {
441
+ options?.catch?.(error);
442
+ }
443
+ return state.value;
444
+ };
445
+ const task = execute();
429
446
  if (isServer()) tasks.push(task);
430
447
  return {
431
448
  state,
432
- isLoading
449
+ isLoading,
450
+ execute
433
451
  };
434
- };
435
- const createRuntime = async () => {
452
+ }
453
+ function useFetch(scope, input, options) {
454
+ return useAsync(scope, async () => await $fetch(scope, input, options), options);
455
+ }
456
+ async function createRuntime() {
436
457
  const radix = new Radix();
437
458
  const middlewares = new Array();
438
459
  const routes = await import("#virtual/routes").then((module) => module.default);
@@ -468,7 +489,7 @@ const createRuntime = async () => {
468
489
  middlewares,
469
490
  fetch: async (scope) => {
470
491
  const { request } = useRuntime(scope);
471
- const { pathname } = useRequestUrl(scope);
492
+ const { pathname } = useUrl(scope);
472
493
  const { value: route, inputs } = radix.match(request.method + pathname);
473
494
  try {
474
495
  scope.setContext(ROUTE_CONTEXT, { inputs: createState(inputs) });
@@ -483,7 +504,7 @@ const createRuntime = async () => {
483
504
  }
484
505
  }
485
506
  };
486
- };
507
+ }
487
508
  const RUNTIME_CONTEXT = defineContext("RUNTIME_CONTEXT");
488
509
  const ROUTE_CONTEXT = defineContext("ROUTE_CONTEXT");
489
510
 
@@ -494,31 +515,24 @@ var MountedEvent = class extends Event {
494
515
  super("mounted");
495
516
  }
496
517
  };
497
- const isTemplate = (value) => {
518
+ function isTemplate(value) {
498
519
  return !!value && typeof value === "object" && "tag" in value && "attributes" in value && "children" in value;
499
- };
500
- const isCustomElement = (value) => {
520
+ }
521
+ function isCustomElement(value) {
501
522
  return !!value && typeof value === "object" && "component" in value;
502
- };
503
- const isComponent = (value) => {
523
+ }
524
+ function isComponent(value) {
504
525
  return !!value && typeof value === "function" && "$name" in value;
505
- };
506
- const useHost = (scope) => {
526
+ }
527
+ function useHost(scope) {
507
528
  return scope.getContext(HOST_CONTEXT);
508
- };
509
- const createElement = (input, attributes, ...children) => {
510
- if (isComponent(input)) {
511
- const template = {
512
- tag: input.$name,
513
- attributes: attributes ?? {},
514
- children
515
- };
516
- if (input.$styles.length) {
517
- const classes = template.attributes["class"];
518
- template.attributes["class"] = (classes ? [classes, ...input.$styles] : input.$styles).join(" ");
519
- }
520
- return template;
521
- }
529
+ }
530
+ function createElement(input, attributes, ...children) {
531
+ if (isComponent(input)) return {
532
+ tag: input.$name,
533
+ attributes: attributes ?? {},
534
+ children
535
+ };
522
536
  if (typeof input === "string") return {
523
537
  tag: input,
524
538
  attributes: attributes ?? {},
@@ -528,8 +542,8 @@ const createElement = (input, attributes, ...children) => {
528
542
  ...attributes,
529
543
  children
530
544
  });
531
- };
532
- const toString = (slot) => {
545
+ }
546
+ function toString(slot) {
533
547
  switch (typeof slot) {
534
548
  case "string":
535
549
  case "number":
@@ -540,12 +554,12 @@ const toString = (slot) => {
540
554
  case "function": return toString(slot());
541
555
  default: return "";
542
556
  }
543
- };
544
- const toArray = (hydration) => {
557
+ }
558
+ function toArray(hydration) {
545
559
  if (Array.isArray(hydration)) return hydration.reduce((items, child) => items.concat(toArray(child)), new Array());
546
- else return [hydration];
547
- };
548
- const toRange = (hydration) => {
560
+ return [hydration];
561
+ }
562
+ function toRange(hydration) {
549
563
  const items = toArray(hydration);
550
564
  const range = document.createRange();
551
565
  const firstNode = items.at(0);
@@ -553,14 +567,14 @@ const toRange = (hydration) => {
553
567
  const lastNode = items.at(-1);
554
568
  if (lastNode) range.setEndAfter(lastNode);
555
569
  return range;
556
- };
557
- const toFragment = (hydration) => {
570
+ }
571
+ function toFragment(hydration) {
558
572
  return toArray(hydration).reduce((fragment, node) => {
559
573
  fragment.appendChild(node);
560
574
  return fragment;
561
575
  }, document.createDocumentFragment());
562
- };
563
- const hydrate = (scope, parentNode, slot, index, previous) => {
576
+ }
577
+ function hydrate(scope, parentNode, slot, index, previous) {
564
578
  let hydration = parentNode.childNodes.item(index);
565
579
  if (Array.isArray(slot)) {
566
580
  const items = new Array();
@@ -613,8 +627,8 @@ const hydrate = (scope, parentNode, slot, index, previous) => {
613
627
  hydration ??= document.createComment("");
614
628
  if (parentNode.childNodes.item(index) === null) parentNode.appendChild(toFragment(hydration));
615
629
  return hydration;
616
- };
617
- const renderToString = async (scope, slot) => {
630
+ }
631
+ async function renderToString(scope, slot) {
618
632
  const { tasks } = useRuntime(scope);
619
633
  if (typeof slot === "number" || typeof slot === "bigint" || typeof slot === "boolean" || typeof slot === "string" || typeof slot === "symbol") return slot.toString();
620
634
  if (typeof slot === "function") {
@@ -654,13 +668,12 @@ const renderToString = async (scope, slot) => {
654
668
  return content;
655
669
  }
656
670
  return "<!---->";
657
- };
658
- const defineComponent = (options) => {
671
+ }
672
+ function defineComponent(options) {
659
673
  class Instance {
660
674
  static $name = options.name;
661
675
  static $events = options.events ?? {};
662
676
  static $attributes = options.attributes ?? {};
663
- static $styles = options.styles ?? [];
664
677
  scope;
665
678
  events;
666
679
  attributes;
@@ -681,8 +694,8 @@ const defineComponent = (options) => {
681
694
  }
682
695
  components.set(options.name, Instance);
683
696
  return Instance;
684
- };
685
- const toCustomElement = (Component) => {
697
+ }
698
+ function toCustomElement(Component) {
686
699
  return class extends HTMLElement {
687
700
  static formAssociated = true;
688
701
  component;
@@ -744,14 +757,14 @@ const toCustomElement = (Component) => {
744
757
  return Object.keys(Component.$attributes ?? {});
745
758
  }
746
759
  };
747
- };
748
- const registerComponent = (component) => {
760
+ }
761
+ function registerComponent(component) {
749
762
  if (isClient()) {
750
763
  const previous = customElements.get(component.$name);
751
764
  if (previous === void 0) customElements.define(component.$name, toCustomElement(component));
752
765
  }
753
766
  return component;
754
- };
767
+ }
755
768
  function useEvent(scope, target, event, input, options) {
756
769
  const controller = new AbortController();
757
770
  target?.addEventListener(event, (event$1) => {
@@ -763,21 +776,31 @@ function useEvent(scope, target, event, input, options) {
763
776
  });
764
777
  scope.onStop(() => controller.abort());
765
778
  }
766
- const onMounted = (scope, event) => {
779
+ function onMounted(scope, event) {
767
780
  if (isClient()) {
768
781
  const { host } = useHost(scope);
769
782
  useEvent(scope, host, "mounted", event);
770
783
  }
771
- };
772
- const startViewTransition = (invoke) => {
784
+ }
785
+ function startViewTransition(invoke) {
773
786
  if (isClient() && document.startViewTransition !== void 0) return document.startViewTransition(invoke).updateCallbackDone;
774
787
  return invoke();
775
- };
776
- const isClient = () => typeof window !== "undefined";
777
- const isServer = () => typeof window === "undefined";
778
- const preventDefault = (event) => event.preventDefault();
779
- const stopPropagation = (event) => event.stopPropagation();
780
- const stopImmediatePropagation = (event) => event.stopImmediatePropagation();
788
+ }
789
+ function isClient() {
790
+ return typeof window !== "undefined";
791
+ }
792
+ function isServer() {
793
+ return typeof window === "undefined";
794
+ }
795
+ function preventDefault(event) {
796
+ event.preventDefault();
797
+ }
798
+ function stopPropagation(event) {
799
+ event.stopPropagation();
800
+ }
801
+ function stopImmediatePropagation(event) {
802
+ event.stopImmediatePropagation();
803
+ }
781
804
  const components = /* @__PURE__ */ new Map();
782
805
  const HOST_CONTEXT = defineContext("HOST_CONTEXT");
783
806
 
@@ -793,7 +816,7 @@ var AfterNavigateEvent = class extends Event {
793
816
  super("afterNavigate");
794
817
  }
795
818
  };
796
- const provideRouterContext = (scope, options) => {
819
+ function provideRouterContext(scope, options) {
797
820
  const url = createState();
798
821
  const route = createState();
799
822
  const radix = new Radix();
@@ -806,13 +829,16 @@ const provideRouterContext = (scope, options) => {
806
829
  }
807
830
  }
808
831
  const fetch$1 = () => {
809
- const { inputs } = useRoute(scope);
810
832
  const { request } = useRuntime(scope);
811
- url.value = new URL(request?.url ?? window?.location.href);
812
- const match = radix.match(url.value.pathname);
813
- inputs.value = match.inputs;
814
- route.value = match.value;
815
- navigator.dispatchEvent(new AfterNavigateEvent());
833
+ const { inputs } = useRoute(scope);
834
+ var next = new URL(request?.url ?? window?.location.href);
835
+ if (next.toString() !== url.value?.toString()) {
836
+ const match = radix.match(next.pathname);
837
+ url.value = next;
838
+ inputs.value = match.inputs;
839
+ route.value = match.value;
840
+ navigator.dispatchEvent(new AfterNavigateEvent());
841
+ }
816
842
  };
817
843
  if (isClient()) useEvent(scope, window, "popstate", () => navigator.dispatchEvent(new NavigateEvent()));
818
844
  scope.setContext(ROUTE_CONTEXT, { inputs: createState() });
@@ -826,8 +852,8 @@ const provideRouterContext = (scope, options) => {
826
852
  fetch$1();
827
853
  useEvent(scope, navigator, "navigate", async () => await startViewTransition(fetch$1));
828
854
  return useRouter(scope);
829
- };
830
- const useRouter = (scope, context) => {
855
+ }
856
+ function useRouter(scope, context) {
831
857
  const { url, route, navigator } = scope.getContext(context ?? ROUTER_CONTEXT);
832
858
  const navigate = (path) => {
833
859
  if (isClient()) {
@@ -846,7 +872,7 @@ const useRouter = (scope, context) => {
846
872
  navigate,
847
873
  anchorNavigate
848
874
  };
849
- };
875
+ }
850
876
  const Page = defineComponent({
851
877
  name: "x-page",
852
878
  setup: ({ scope }) => {
@@ -858,7 +884,7 @@ const ROUTER_CONTEXT = defineContext("ROUTER_CONTEXT");
858
884
 
859
885
  //#endregion
860
886
  //#region src/locale/index.ts
861
- const provideLocaleContext = (scope, options) => {
887
+ function provideLocaleContext(scope, options) {
862
888
  const { inputs } = useRoute(scope);
863
889
  const { navigator } = useRouter(scope);
864
890
  const locale = createState(options.defaultLocale);
@@ -881,8 +907,8 @@ const provideLocaleContext = (scope, options) => {
881
907
  options
882
908
  });
883
909
  return useLocale(scope);
884
- };
885
- const useLocale = (scope, context) => {
910
+ }
911
+ function useLocale(scope, context) {
886
912
  const { locale, messages } = scope.getContext(context ?? LOCALE_CONTEXT);
887
913
  const $ = (key) => {
888
914
  return () => messages.value?.[key] ?? key;
@@ -897,8 +923,8 @@ const useLocale = (scope, context) => {
897
923
  $,
898
924
  date
899
925
  };
900
- };
926
+ }
901
927
  const LOCALE_CONTEXT = defineContext("LOCALE_CONTEXT");
902
928
 
903
929
  //#endregion
904
- export { $fetch, AfterNavigateEvent, 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, createMemo, createRuntime, createState, defineComponent, defineContext, defineMiddleware, defineRoute, fileName, fromValue, hydrate, isClient, isComponent, isCustomElement, isRoute, isServer, isTemplate, mimeType, onMounted, 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, useHost, useLocale, useRequestUrl, useRoute, useRouter, useRuntime, useSetCookies };
930
+ export { $fetch, AfterNavigateEvent, 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, createMemo, createRuntime, createState, defineComponent, defineContext, defineMiddleware, defineRoute, fileName, fromValue, hydrate, isClient, isComponent, isCustomElement, isRoute, isServer, isTemplate, mergeObjects, mimeType, onMounted, 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, useRoute, useRouter, useRuntime, useSetCookies, useUrl };
@@ -1,4 +1,4 @@
1
- import { type EventListener, type Slot } from "../html";
1
+ import { createElement, type EventListener, type Slot } from "../html";
2
2
  export type Fragment = {
3
3
  children: Array<Slot>;
4
4
  };
@@ -366,6 +366,6 @@ export declare namespace JSX {
366
366
  }
367
367
  }
368
368
  export declare const svgElements: Set<string>;
369
- export declare const namespace: (tag: string) => "http://www.w3.org/1999/xhtml" | "http://www.w3.org/2000/svg";
370
- export declare const h: <TEvents extends import("..").Events, TAttributes extends import("..").Attributes>(input: string | import("..").ComponentConstructor<TEvents, TAttributes>, attributes?: import("..").AttributeInput<TAttributes>, ...children: Array<Slot>) => Slot;
369
+ export declare function namespace(tag: string): "http://www.w3.org/1999/xhtml" | "http://www.w3.org/2000/svg";
370
+ export declare const h: typeof createElement;
371
371
  export declare const fragment: ({ children }: Fragment) => unknown[];
package/dist/jsx/index.js CHANGED
@@ -10,22 +10,15 @@ const ROUTE_CONTEXT = defineContext("ROUTE_CONTEXT");
10
10
 
11
11
  //#endregion
12
12
  //#region src/html/index.ts
13
- const isComponent = (value) => {
13
+ function isComponent(value) {
14
14
  return !!value && typeof value === "function" && "$name" in value;
15
- };
16
- const createElement = (input, attributes, ...children) => {
17
- if (isComponent(input)) {
18
- const template = {
19
- tag: input.$name,
20
- attributes: attributes ?? {},
21
- children
22
- };
23
- if (input.$styles.length) {
24
- const classes = template.attributes["class"];
25
- template.attributes["class"] = (classes ? [classes, ...input.$styles] : input.$styles).join(" ");
26
- }
27
- return template;
28
- }
15
+ }
16
+ function createElement(input, attributes, ...children) {
17
+ if (isComponent(input)) return {
18
+ tag: input.$name,
19
+ attributes: attributes ?? {},
20
+ children
21
+ };
29
22
  if (typeof input === "string") return {
30
23
  tag: input,
31
24
  attributes: attributes ?? {},
@@ -35,7 +28,7 @@ const createElement = (input, attributes, ...children) => {
35
28
  ...attributes,
36
29
  children
37
30
  });
38
- };
31
+ }
39
32
  const HOST_CONTEXT = defineContext("HOST_CONTEXT");
40
33
 
41
34
  //#endregion
@@ -119,9 +112,9 @@ const svgElements = new Set([
119
112
  "view",
120
113
  "vkern"
121
114
  ]);
122
- const namespace = (tag) => {
115
+ function namespace(tag) {
123
116
  return svgElements.has(tag) ? "http://www.w3.org/2000/svg" : "http://www.w3.org/1999/xhtml";
124
- };
117
+ }
125
118
  const h = createElement;
126
119
  const fragment = ({ children }) => children;
127
120
 
@@ -9,13 +9,13 @@ export type LocaleContext = {
9
9
  messages: State<Record<string, string> | undefined>;
10
10
  options: LocaleOptions;
11
11
  };
12
- export declare const provideLocaleContext: (scope: Scope, options: LocaleOptions) => {
12
+ export declare function provideLocaleContext(scope: Scope, options: LocaleOptions): {
13
13
  locale: State<string | undefined>;
14
14
  messages: State<Record<string, string> | undefined>;
15
15
  $: (key: string) => () => string | number | symbol;
16
16
  date: (date?: Date, options?: Intl.DateTimeFormatOptions) => string | undefined;
17
17
  };
18
- export declare const useLocale: <T extends LocaleContext>(scope: Scope, context?: Descriptor<T>) => {
18
+ export declare function useLocale<T extends LocaleContext>(scope: Scope, context?: Descriptor<T>): {
19
19
  locale: State<string | undefined>;
20
20
  messages: State<Record<string, string> | undefined>;
21
21
  $: (key: keyof T["options"]["locales"][keyof T["options"]["locales"]]) => () => string | number | symbol;
@@ -17,14 +17,14 @@ export declare class NavigateEvent extends Event {
17
17
  export declare class AfterNavigateEvent extends Event {
18
18
  constructor();
19
19
  }
20
- export declare const provideRouterContext: (scope: Scope, options: RouterOptions) => {
20
+ export declare function provideRouterContext(scope: Scope, options: RouterOptions): {
21
21
  url: State<URL | undefined>;
22
22
  route: State<unknown>;
23
23
  navigator: EventTarget;
24
24
  navigate: (path: string) => void;
25
25
  anchorNavigate: (event: Event) => void;
26
26
  };
27
- export declare const useRouter: <T extends RouterContext>(scope: Scope, context?: Descriptor<T>) => {
27
+ export declare function useRouter<T extends RouterContext>(scope: Scope, context?: Descriptor<T>): {
28
28
  url: State<URL | undefined>;
29
29
  route: State<unknown>;
30
30
  navigator: EventTarget;
@@ -22,20 +22,26 @@ export type RouteContext = {
22
22
  inputs: State<Record<string, string>>;
23
23
  };
24
24
  export type AsyncOptions = {
25
- catch?: (error: Error) => void | Promise<void>;
26
- };
27
- export declare const isRoute: <T>(value?: T) => value is Route & T;
28
- export declare const useRuntime: <T = Record<string, unknown>>(scope: Scope) => RuntimeContext<T>;
29
- export declare const useRoute: (scope: Scope) => RouteContext;
30
- export declare const defineRoute: (route: Route) => Route;
31
- export declare const defineMiddleware: (middleware: Middleware) => Middleware;
32
- export declare const fileName: (path: string) => string | undefined;
33
- export declare const toPath: (value: string) => (string | undefined)[];
34
- export declare const $fetch: <T>(scope: Scope, input: string | URL, options?: RequestInit) => Promise<T>;
35
- export declare const useAsync: <T>(scope: Scope, invoke: () => Promise<T>, options?: AsyncOptions) => {
25
+ catch?: (error: unknown) => void | Promise<void>;
26
+ };
27
+ export declare function isRoute<T>(value?: T): value is Route & T;
28
+ export declare function useRuntime<T = Record<string, unknown>>(scope: Scope): RuntimeContext<T>;
29
+ export declare function useRoute(scope: Scope): RouteContext;
30
+ export declare function defineRoute(route: Route): Route;
31
+ export declare function defineMiddleware(middleware: Middleware): Middleware;
32
+ export declare function fileName(path: string): string | undefined;
33
+ export declare function toPath(value: string): (string | undefined)[];
34
+ export declare function $fetch<T>(scope: Scope, input: string | URL, options?: RequestInit): Promise<T>;
35
+ export declare function useAsync<T>(scope: Scope, invoke: () => Promise<T>, options?: AsyncOptions): {
36
+ state: State<T | undefined>;
37
+ isLoading: State<boolean>;
38
+ execute: () => Promise<T | undefined>;
39
+ };
40
+ export declare function useFetch<T>(scope: Scope, input: string | URL, options?: RequestInit & AsyncOptions): {
36
41
  state: State<T | undefined>;
37
42
  isLoading: State<boolean>;
43
+ execute: () => Promise<T | undefined>;
38
44
  };
39
- export declare const createRuntime: () => Promise<Runtime>;
45
+ export declare function createRuntime(): Promise<Runtime>;
40
46
  export declare const RUNTIME_CONTEXT: import("..").Descriptor<RuntimeContext<Record<string, unknown>>>;
41
47
  export declare const ROUTE_CONTEXT: import("..").Descriptor<RouteContext>;
@@ -33,6 +33,7 @@ export declare function createCompute<T>(scope: Scope, invoke: (scope: Scope) =>
33
33
  export declare function createMemo<T>(scope: Scope, invoke: (scope: Scope) => T): State<T>;
34
34
  export declare function fromValue<T>(value: Value<T>): T;
35
35
  export declare function untrack<T>(invoke: () => T): T;
36
+ export declare function mergeObjects<TBase, TInput>(base: TBase, input: TInput): TBase & TInput;
36
37
  export declare function defineContext<T>(key: string): Descriptor<T>;
37
38
  export declare let activeCompute: Compute | undefined;
38
39
  export declare const targets: WeakMap<object, Map<string | symbol, Set<Compute<void>>>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "revojs",
3
- "version": "0.0.67",
3
+ "version": "0.0.69",
4
4
  "type": "module",
5
5
  "repository": "coverbase/revojs",
6
6
  "license": "MIT",
@@ -32,15 +32,12 @@
32
32
  "build": "rolldown -c rolldown.config.ts && tsc",
33
33
  "watch": "rolldown -w -c rolldown.config.ts && tsc --watch"
34
34
  },
35
- "dependencies": {
36
- "defu": "^6.1.4"
37
- },
38
35
  "optionalDependencies": {
39
36
  "@rolldown/binding-linux-x64-gnu": "*"
40
37
  },
41
38
  "devDependencies": {
42
- "@revojs/tsconfig": "*",
43
39
  "@revojs/rolldown": "*",
40
+ "@revojs/tsconfig": "*",
44
41
  "@types/bun": "^1.2.17",
45
42
  "rolldown": "^1.0.0-beta.19"
46
43
  }