revojs 0.0.23 → 0.0.25

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,5 @@
1
1
  import { type HtmlAttributes } from "../jsx";
2
- import { type Descriptor, Hooks, Scope, type State, type Value } from "../signals";
2
+ import { type Descriptor, Scope, type State, type Value } from "../signals";
3
3
  export type TypeOf<T> = {
4
4
  (): T;
5
5
  };
@@ -45,7 +45,6 @@ export interface ComponentOptions<TEvents extends Events, TAttributes extends At
45
45
  }
46
46
  export interface Component<TEvents extends Events, TAttributes extends Attributes> {
47
47
  readonly scope: Scope;
48
- readonly hooks: Hooks;
49
48
  readonly context: Map<string, unknown>;
50
49
  readonly events: EventOutput<TEvents>;
51
50
  readonly attributes: State<AttributeOutput<TAttributes>>;
@@ -53,7 +52,6 @@ export interface Component<TEvents extends Events, TAttributes extends Attribute
53
52
  readonly host?: CustomElement<TEvents, TAttributes>;
54
53
  getContext: <T>(input: Descriptor<T>) => T;
55
54
  setContext: <T>(input: Descriptor<T>, value: T) => void;
56
- onMounted: (invoke: (input: HTMLElement) => void | Promise<void>) => void;
57
55
  setup: () => Slot | Promise<Slot>;
58
56
  }
59
57
  export interface ComponentConstructor<TEvents extends Events, TAttributes extends Attributes> {
@@ -68,8 +66,11 @@ export interface CustomElement<TEvents extends Events, TAttributes extends Attri
68
66
  export interface CustomElementConstructor<TEvents extends Events, TAttributes extends Attributes> {
69
67
  new (): CustomElement<TEvents, TAttributes>;
70
68
  }
69
+ export declare class MountedEvent extends Event {
70
+ constructor();
71
+ }
71
72
  export declare const isTemplate: (value: object) => value is Template;
72
- export declare const createElement: <TEvents extends Events, TAttributes extends Attributes>(input: string | Template | ComponentConstructor<TEvents, TAttributes>, attributes?: AttributeInput<TAttributes>, ...children: Array<Slot>) => Slot;
73
+ export declare const createElement: <TEvents extends Events, TAttributes extends Attributes>(input: string | ComponentConstructor<TEvents, TAttributes>, attributes?: AttributeInput<TAttributes>, ...children: Array<Slot>) => Slot;
73
74
  export declare const toString: (slot: Slot) => string;
74
75
  export declare const toFragment: (nodes: Array<Node>) => DocumentFragment;
75
76
  export declare const renderToString: (slot: Slot, context: Map<string, unknown>) => Promise<string>;
@@ -78,12 +79,18 @@ export declare const defineComponent: <TEvents extends Events = {}, TAttributes
78
79
  export declare const toCustomElement: <TEvents extends Events = {}, TAttributes extends Attributes = {}>(component: ComponentConstructor<TEvents, TAttributes>) => CustomElementConstructor<TEvents, TAttributes>;
79
80
  export declare const registerComponent: <TEvents extends Events = {}, TAttributes extends Attributes = {}>(component: ComponentConstructor<TEvents, TAttributes>) => ComponentConstructor<TEvents, TAttributes>;
80
81
  export declare const getGlobalStyles: () => CSSStyleSheet[];
82
+ export declare function useEvent<T extends keyof ElementEventMap>(scope: Scope, target: EventTarget | undefined, event: T, input: EventListener<ElementEventMap[T]>, options?: AddEventListenerOptions): void;
83
+ export declare function useEvent<T extends keyof WindowEventMap>(scope: Scope, target: Window | undefined, event: T, input: EventListener<WindowEventMap[T]>, options?: AddEventListenerOptions): void;
84
+ export declare function useEvent<T extends keyof HTMLElementEventMap>(scope: Scope, target: HTMLElement | undefined, event: T, input: EventListener<HTMLElementEventMap[T]>, options?: AddEventListenerOptions): void;
81
85
  export declare const getCustomElement: (node: Node | null) => CustomElement<Events, Attributes> | undefined;
82
- export declare const eventListener: <T extends Event>(event: T, invoke?: EventListener<T>) => void;
83
86
  export declare const isClient: () => boolean;
84
87
  export declare const isServer: () => boolean;
85
88
  export declare const preventDefault: (event: Event) => void;
86
89
  export declare const stopPropagation: (event: Event) => void;
87
90
  export declare const stopImmediatePropagation: (event: Event) => void;
88
- export declare const MOUNTED_HOOK: Descriptor<HTMLElement>;
89
91
  export declare const components: Map<string, ComponentConstructor<Events, Attributes>>;
92
+ declare global {
93
+ interface HTMLElementEventMap {
94
+ mounted: MountedEvent;
95
+ }
96
+ }
package/dist/index.js CHANGED
@@ -107,29 +107,20 @@ const namespace = (tag) => {
107
107
 
108
108
  //#endregion
109
109
  //#region src/signals/index.ts
110
- var Hooks = class {
111
- hooks;
110
+ var StopEvent = class extends Event {
112
111
  constructor() {
113
- this.hooks = new Map();
114
- }
115
- on(scope, input, invoke) {
116
- const invokes = this.hooks.get(input) ?? new Set();
117
- invokes.add(invoke);
118
- this.hooks.set(input, invokes);
119
- return scope.dispose.push(() => invokes.delete(invoke));
120
- }
121
- dispatch(input, value) {
122
- const invokes = this.hooks.get(input);
123
- if (invokes) for (const invoke of invokes) invoke(value);
112
+ super("stop");
124
113
  }
125
114
  };
126
- var Scope = class {
127
- dispose;
115
+ var Scope = class extends EventTarget {
128
116
  constructor() {
129
- this.dispose = new Array();
117
+ super();
118
+ }
119
+ onStop(input) {
120
+ this.addEventListener("stop", input, { once: true });
130
121
  }
131
122
  stop() {
132
- while (this.dispose.length) this.dispose.pop()?.(this);
123
+ return this.dispatchEvent(new StopEvent());
133
124
  }
134
125
  };
135
126
  var Compute = class extends Scope {
@@ -153,7 +144,7 @@ var Handler = class Handler {
153
144
  const set = computes.get(key) ?? new Set();
154
145
  computes.set(key, set.add(compute));
155
146
  targets.set(target, computes);
156
- compute.scope.dispose.push(() => {
147
+ compute.scope.onStop(() => {
157
148
  compute.stop();
158
149
  set.delete(compute);
159
150
  });
@@ -197,9 +188,6 @@ function fromValue(value) {
197
188
  if (value instanceof Function) return fromValue(value());
198
189
  return value;
199
190
  }
200
- function defineHook(key) {
201
- return key;
202
- }
203
191
  function defineContext(key) {
204
192
  return key;
205
193
  }
@@ -208,12 +196,16 @@ const targets = new WeakMap();
208
196
 
209
197
  //#endregion
210
198
  //#region src/html/index.ts
199
+ var MountedEvent = class extends Event {
200
+ constructor() {
201
+ super("mounted");
202
+ }
203
+ };
211
204
  const isTemplate = (value) => {
212
205
  return "tag" in value && "attributes" in value && "children" in value;
213
206
  };
214
207
  const createElement = (input, attributes, ...children) => {
215
- if (typeof input === "object") return input;
216
- else return {
208
+ return {
217
209
  tag: typeof input === "function" ? input.$name : input,
218
210
  attributes: attributes ?? {},
219
211
  children
@@ -323,9 +315,7 @@ const renderToNode = async (scope, slot) => {
323
315
  const value = slot.attributes[name];
324
316
  if (name.startsWith("on")) {
325
317
  const event = name.substring(2).toLowerCase();
326
- const controller = new AbortController();
327
- element.addEventListener(event, (event$1) => eventListener(event$1, value), { signal: controller.signal });
328
- scope.dispose.push(() => controller.abort());
318
+ useEvent(scope, element, event, value);
329
319
  } else createCompute(scope, () => {
330
320
  const set = toString(value);
331
321
  if (set === "" || set === "false") return element.removeAttribute(name);
@@ -346,7 +336,6 @@ const defineComponent = (options) => {
346
336
  static $events = options.events ?? {};
347
337
  static $attributes = options.attributes ?? {};
348
338
  scope;
349
- hooks;
350
339
  context;
351
340
  events;
352
341
  attributes;
@@ -354,7 +343,6 @@ const defineComponent = (options) => {
354
343
  host;
355
344
  constructor(input, context, host) {
356
345
  this.scope = new Scope();
357
- this.hooks = new Hooks();
358
346
  this.context = context ?? new Map();
359
347
  this.events = Object.keys(options.events ?? {}).reduce((output, name) => {
360
348
  Reflect.set(output, name, input?.[name], output);
@@ -373,9 +361,6 @@ const defineComponent = (options) => {
373
361
  setContext = (input, value) => {
374
362
  this.context.set(input, value);
375
363
  };
376
- onMounted = (invoke) => {
377
- return this.hooks.on(this.scope, MOUNTED_HOOK, invoke);
378
- };
379
364
  setup = () => options.setup(this);
380
365
  });
381
366
  };
@@ -399,7 +384,7 @@ const toCustomElement = (component) => {
399
384
  }, this.component.events);
400
385
  if (parentNode) for (const [name, value] of parentNode.component.context) this.component.context.set(name, value);
401
386
  rootNode.replaceChildren(await renderToNode(this.component.scope, await this.component.setup()));
402
- this.component.hooks.dispatch(MOUNTED_HOOK, this);
387
+ this.dispatchEvent(new MountedEvent());
403
388
  }
404
389
  attributeChangedCallback(name, oldValue, value) {
405
390
  if (value === oldValue) return;
@@ -447,22 +432,28 @@ const getGlobalStyles = () => {
447
432
  return sheet;
448
433
  });
449
434
  };
435
+ function useEvent(scope, target, event, input, options) {
436
+ const controller = new AbortController();
437
+ target?.addEventListener(event, (event$1) => {
438
+ if (Array.isArray(input)) for (const target$1 of input) target$1?.(event$1);
439
+ else input?.(event$1);
440
+ }, {
441
+ signal: controller.signal,
442
+ ...options
443
+ });
444
+ scope.onStop(() => controller.abort());
445
+ }
450
446
  const getCustomElement = (node) => {
451
447
  if (node) {
452
448
  if ("component" in node) return node;
453
449
  return getCustomElement(node.parentNode);
454
450
  }
455
451
  };
456
- const eventListener = (event, invoke) => {
457
- if (Array.isArray(invoke)) for (const target of invoke) target?.(event);
458
- else invoke?.(event);
459
- };
460
452
  const isClient = () => typeof window !== "undefined";
461
453
  const isServer = () => typeof window === "undefined";
462
454
  const preventDefault = (event) => event.preventDefault();
463
455
  const stopPropagation = (event) => event.stopPropagation();
464
456
  const stopImmediatePropagation = (event) => event.stopImmediatePropagation();
465
- const MOUNTED_HOOK = defineHook("MOUNTED_HOOK");
466
457
  const components = new Map();
467
458
 
468
459
  //#endregion
@@ -764,11 +755,7 @@ const Outlet = defineComponent({
764
755
  if (name) radix.insert(name, routes[path]);
765
756
  }
766
757
  const url = createState(new URL(event ? event.request.url : window.location.href));
767
- if (isClient()) {
768
- const controller = new AbortController();
769
- window.addEventListener("popstate", () => url.value = new URL(window.location.href), { signal: controller.signal });
770
- scope.dispose.push(() => controller.abort());
771
- }
758
+ if (isClient()) useEvent(scope, window, "popstate", () => url.value = new URL(window.location.href));
772
759
  return async () => {
773
760
  const { value, inputs } = radix.match(url.value.pathname);
774
761
  const Page = await value?.();
@@ -789,4 +776,4 @@ const anchorNavigate = (event) => {
789
776
  };
790
777
 
791
778
  //#endregion
792
- export { $fetch, Compute, Handler, Hooks, MOUNTED_HOOK, Outlet, RUNTIME_CONTEXT, Radix, Scope, activeCompute, anchorNavigate, components, createApp, createCompute, createElement, createEvent, createMemo, createRuntime, createState, defineComponent, defineContext, defineHook, defineRoute, eventListener, fileName, fromValue, getAssets, getCookies, getCustomElement, getGlobalStyles, getMimeType, getRequestUrl, getRoutes, getSetCookies, getVariables, isClient, isServer, isTemplate, markdownToSlot, navigate, preventDefault, registerComponent, renderToNode, renderToString, sendBadRequest, sendHtml, sendJson, sendRedirect, sendText, sendUnauthorized, setCookie, stopImmediatePropagation, stopPropagation, targets, toCustomElement, toFragment, toPath, toString };
779
+ export { $fetch, Compute, Handler, MountedEvent, Outlet, RUNTIME_CONTEXT, Radix, Scope, StopEvent, activeCompute, anchorNavigate, components, createApp, createCompute, createElement, createEvent, createMemo, createRuntime, createState, defineComponent, defineContext, defineRoute, fileName, fromValue, getAssets, getCookies, getCustomElement, getGlobalStyles, getMimeType, getRequestUrl, getRoutes, getSetCookies, getVariables, isClient, isServer, isTemplate, markdownToSlot, navigate, preventDefault, registerComponent, renderToNode, renderToString, sendBadRequest, sendHtml, sendJson, sendRedirect, sendText, sendUnauthorized, setCookie, stopImmediatePropagation, stopPropagation, targets, toCustomElement, toFragment, toPath, toString, useEvent };
@@ -364,4 +364,4 @@ export declare namespace JSX {
364
364
  }
365
365
  export declare const svgElements: Set<string>;
366
366
  export declare const namespace: (tag: string) => "http://www.w3.org/1999/xhtml" | "http://www.w3.org/2000/svg";
367
- export declare const h: <TEvents extends import("..").Events, TAttributes extends import("..").Attributes>(input: string | import("..").Template | import("..").ComponentConstructor<TEvents, TAttributes>, attributes?: import("..").AttributeInput<TAttributes>, ...children: Array<Slot>) => Slot;
367
+ 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;
package/dist/jsx/index.js CHANGED
@@ -1,20 +1,12 @@
1
1
 
2
- //#region src/signals/index.ts
3
- function defineHook(key) {
4
- return key;
5
- }
6
-
7
- //#endregion
8
2
  //#region src/html/index.ts
9
3
  const createElement = (input, attributes, ...children) => {
10
- if (typeof input === "object") return input;
11
- else return {
4
+ return {
12
5
  tag: typeof input === "function" ? input.$name : input,
13
6
  attributes: attributes ?? {},
14
7
  children
15
8
  };
16
9
  };
17
- const MOUNTED_HOOK = defineHook("MOUNTED_HOOK");
18
10
 
19
11
  //#endregion
20
12
  //#region src/jsx/index.ts
@@ -6,16 +6,13 @@ export type Descriptor<T> = string & {
6
6
  export interface State<T> {
7
7
  value: T;
8
8
  }
9
- export declare class Hooks {
10
- readonly hooks: Map<string, Set<(value: any) => unknown>>;
9
+ export declare class StopEvent extends Event {
11
10
  constructor();
12
- on<T>(scope: Scope, input: Descriptor<T>, invoke: (value: T) => unknown): number;
13
- dispatch<T>(input: Descriptor<T>, value: T): void;
14
11
  }
15
- export declare class Scope {
16
- readonly dispose: Array<(scope: Scope) => void>;
12
+ export declare class Scope extends EventTarget {
17
13
  constructor();
18
- stop(): void;
14
+ onStop(input: (event: StopEvent) => void): void;
15
+ stop(): boolean;
19
16
  }
20
17
  export declare class Compute<T = void> extends Scope {
21
18
  readonly scope: Scope;
@@ -32,8 +29,12 @@ export declare function createState<T>(value: T): State<T>;
32
29
  export declare function createCompute<T>(scope: Scope, invoke: (scope: Scope) => T): T;
33
30
  export declare function createMemo<T>(scope: Scope, invoke: (scope: Scope) => T): State<T>;
34
31
  export declare function fromValue<T>(value: Value<T>): T;
35
- export declare function defineHook<T>(key: string): Descriptor<T>;
36
32
  export declare function defineContext<T>(key: string): Descriptor<T>;
37
33
  export declare let activeCompute: Compute | undefined;
38
34
  export declare const targets: WeakMap<object, Map<string | symbol, Set<Compute<void>>>>;
35
+ declare global {
36
+ interface ElementEventMap {
37
+ stop: StopEvent;
38
+ }
39
+ }
39
40
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "revojs",
3
- "version": "0.0.23",
3
+ "version": "0.0.25",
4
4
  "type": "module",
5
5
  "repository": "coverbase/revojs",
6
6
  "license": "MIT",