revojs 0.0.25 → 0.0.27
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.
- package/dist/html/index.d.ts +3 -6
- package/dist/index.js +45 -26
- package/dist/runtime/index.d.ts +2 -1
- package/dist/signals/index.d.ts +5 -1
- package/package.json +1 -1
package/dist/html/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type HtmlAttributes } from "../jsx";
|
|
2
|
-
import {
|
|
2
|
+
import { Scope, type State, type Value } from "../signals";
|
|
3
3
|
export type TypeOf<T> = {
|
|
4
4
|
(): T;
|
|
5
5
|
};
|
|
@@ -45,20 +45,17 @@ 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 context: Map<string, unknown>;
|
|
49
48
|
readonly events: EventOutput<TEvents>;
|
|
50
49
|
readonly attributes: State<AttributeOutput<TAttributes>>;
|
|
51
50
|
readonly shadowRoot: false | ShadowRootInit;
|
|
52
51
|
readonly host?: CustomElement<TEvents, TAttributes>;
|
|
53
|
-
getContext: <T>(input: Descriptor<T>) => T;
|
|
54
|
-
setContext: <T>(input: Descriptor<T>, value: T) => void;
|
|
55
52
|
setup: () => Slot | Promise<Slot>;
|
|
56
53
|
}
|
|
57
54
|
export interface ComponentConstructor<TEvents extends Events, TAttributes extends Attributes> {
|
|
58
55
|
$name: string;
|
|
59
56
|
$events: TEvents;
|
|
60
57
|
$attributes: TAttributes;
|
|
61
|
-
new (input?: Input<TEvents, TAttributes>,
|
|
58
|
+
new (input?: Input<TEvents, TAttributes>, scope?: Scope, host?: CustomElement<TEvents, TAttributes>): Component<TEvents, TAttributes>;
|
|
62
59
|
}
|
|
63
60
|
export interface CustomElement<TEvents extends Events, TAttributes extends Attributes> extends HTMLElement {
|
|
64
61
|
readonly component: Component<TEvents, TAttributes>;
|
|
@@ -73,7 +70,7 @@ export declare const isTemplate: (value: object) => value is Template;
|
|
|
73
70
|
export declare const createElement: <TEvents extends Events, TAttributes extends Attributes>(input: string | ComponentConstructor<TEvents, TAttributes>, attributes?: AttributeInput<TAttributes>, ...children: Array<Slot>) => Slot;
|
|
74
71
|
export declare const toString: (slot: Slot) => string;
|
|
75
72
|
export declare const toFragment: (nodes: Array<Node>) => DocumentFragment;
|
|
76
|
-
export declare const renderToString: (
|
|
73
|
+
export declare const renderToString: (scope: Scope, slot: Slot) => Promise<string>;
|
|
77
74
|
export declare const renderToNode: (scope: Scope, slot: Slot) => Promise<Node>;
|
|
78
75
|
export declare const defineComponent: <TEvents extends Events = {}, TAttributes extends Attributes = {}>(options: ComponentOptions<TEvents, TAttributes>) => ComponentConstructor<TEvents, TAttributes>;
|
|
79
76
|
export declare const toCustomElement: <TEvents extends Events = {}, TAttributes extends Attributes = {}>(component: ComponentConstructor<TEvents, TAttributes>) => CustomElementConstructor<TEvents, TAttributes>;
|
package/dist/index.js
CHANGED
|
@@ -113,8 +113,25 @@ var StopEvent = class extends Event {
|
|
|
113
113
|
}
|
|
114
114
|
};
|
|
115
115
|
var Scope = class extends EventTarget {
|
|
116
|
-
|
|
116
|
+
parentScope;
|
|
117
|
+
context;
|
|
118
|
+
constructor(scope) {
|
|
117
119
|
super();
|
|
120
|
+
this.parentScope = scope;
|
|
121
|
+
this.context = new Map();
|
|
122
|
+
}
|
|
123
|
+
getContext(input) {
|
|
124
|
+
let scope = this;
|
|
125
|
+
const seen = new Set();
|
|
126
|
+
while (scope && !seen.has(scope)) {
|
|
127
|
+
seen.add(scope);
|
|
128
|
+
if (scope.context.has(input)) return scope.context.get(input);
|
|
129
|
+
scope = scope.parentScope;
|
|
130
|
+
}
|
|
131
|
+
return {};
|
|
132
|
+
}
|
|
133
|
+
setContext(input, value) {
|
|
134
|
+
this.context.set(input, value);
|
|
118
135
|
}
|
|
119
136
|
onStop(input) {
|
|
120
137
|
this.addEventListener("stop", input, { once: true });
|
|
@@ -228,28 +245,28 @@ const toFragment = (nodes) => {
|
|
|
228
245
|
fragment.replaceChildren(...nodes);
|
|
229
246
|
return fragment;
|
|
230
247
|
};
|
|
231
|
-
const renderToString = async (
|
|
248
|
+
const renderToString = async (scope, slot) => {
|
|
232
249
|
if (slot) {
|
|
233
250
|
if (typeof slot === "number" || typeof slot === "bigint" || typeof slot === "boolean" || typeof slot === "string" || typeof slot === "symbol") return slot.toString();
|
|
234
|
-
if (typeof slot === "function") return await renderToString(await slot()
|
|
251
|
+
if (typeof slot === "function") return await renderToString(scope, await slot());
|
|
235
252
|
if (typeof slot === "object") {
|
|
236
|
-
if (Array.isArray(slot)) return await Promise.all(slot.map((slot$1) => renderToString(slot$1
|
|
253
|
+
if (Array.isArray(slot)) return await Promise.all(slot.map((slot$1) => renderToString(scope, slot$1))).then((chunks) => chunks.join(""));
|
|
237
254
|
if (isTemplate(slot)) {
|
|
238
255
|
const customElement = components.get(slot.tag);
|
|
239
256
|
const prefix = Object.entries(slot.attributes).reduce((chunks, [name, value]) => {
|
|
240
257
|
if (!name.startsWith("on")) chunks.push(`${name}='${toString(value)}'`);
|
|
241
258
|
return chunks;
|
|
242
259
|
}, [slot.tag]).join(" ");
|
|
243
|
-
const children = await renderToString(slot.children
|
|
260
|
+
const children = await renderToString(scope, slot.children);
|
|
244
261
|
if (customElement) {
|
|
245
|
-
const element = new customElement(slot.attributes,
|
|
246
|
-
const template = await renderToString(await element.setup()
|
|
262
|
+
const element = new customElement(slot.attributes, scope);
|
|
263
|
+
const template = await renderToString(scope, await element.setup());
|
|
247
264
|
if (element.shadowRoot) {
|
|
248
|
-
const shadow = await renderToString({
|
|
265
|
+
const shadow = await renderToString(scope, {
|
|
249
266
|
tag: "template",
|
|
250
267
|
attributes: { shadowRootMode: element.shadowRoot.mode },
|
|
251
268
|
children: [template]
|
|
252
|
-
}
|
|
269
|
+
});
|
|
253
270
|
return `<${prefix}>` + shadow + children + `</${slot.tag}>`;
|
|
254
271
|
}
|
|
255
272
|
return `<${prefix}>` + template + children + `</${slot.tag}>`;
|
|
@@ -336,14 +353,12 @@ const defineComponent = (options) => {
|
|
|
336
353
|
static $events = options.events ?? {};
|
|
337
354
|
static $attributes = options.attributes ?? {};
|
|
338
355
|
scope;
|
|
339
|
-
context;
|
|
340
356
|
events;
|
|
341
357
|
attributes;
|
|
342
358
|
shadowRoot;
|
|
343
359
|
host;
|
|
344
|
-
constructor(input,
|
|
345
|
-
this.scope = new Scope();
|
|
346
|
-
this.context = context ?? new Map();
|
|
360
|
+
constructor(input, scope, host) {
|
|
361
|
+
this.scope = new Scope(scope);
|
|
347
362
|
this.events = Object.keys(options.events ?? {}).reduce((output, name) => {
|
|
348
363
|
Reflect.set(output, name, input?.[name], output);
|
|
349
364
|
return output;
|
|
@@ -355,13 +370,17 @@ const defineComponent = (options) => {
|
|
|
355
370
|
this.shadowRoot = options.shadowRoot ?? { mode: "open" };
|
|
356
371
|
this.host = host;
|
|
357
372
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
373
|
+
setup = () => {
|
|
374
|
+
const findParent = (node) => {
|
|
375
|
+
if (node) {
|
|
376
|
+
if ("component" in node) return node;
|
|
377
|
+
return findParent(node.parentNode);
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
const parentNode = findParent(this.host?.parentNode);
|
|
381
|
+
if (parentNode) this.scope.parentScope = parentNode.component.scope;
|
|
382
|
+
return options.setup(this);
|
|
363
383
|
};
|
|
364
|
-
setup = () => options.setup(this);
|
|
365
384
|
});
|
|
366
385
|
};
|
|
367
386
|
const toCustomElement = (component) => {
|
|
@@ -374,7 +393,6 @@ const toCustomElement = (component) => {
|
|
|
374
393
|
}
|
|
375
394
|
async connectedCallback() {
|
|
376
395
|
const rootNode = this.component.shadowRoot ? this.attachShadow(this.component.shadowRoot) : this;
|
|
377
|
-
const parentNode = getCustomElement(this.parentNode);
|
|
378
396
|
for (const [name, event] of Object.entries(component.$events)) Reflect.set(this.component.events, name, (value) => {
|
|
379
397
|
if (value instanceof Event) return;
|
|
380
398
|
this.dispatchEvent(new CustomEvent(name.substring(2).toLowerCase(), {
|
|
@@ -382,7 +400,6 @@ const toCustomElement = (component) => {
|
|
|
382
400
|
detail: value
|
|
383
401
|
}));
|
|
384
402
|
}, this.component.events);
|
|
385
|
-
if (parentNode) for (const [name, value] of parentNode.component.context) this.component.context.set(name, value);
|
|
386
403
|
rootNode.replaceChildren(await renderToNode(this.component.scope, await this.component.setup()));
|
|
387
404
|
this.dispatchEvent(new MountedEvent());
|
|
388
405
|
}
|
|
@@ -678,7 +695,8 @@ const toPath = (value) => {
|
|
|
678
695
|
const split = route.split(".");
|
|
679
696
|
return split.length === 3 ? [split.at(0), split.at(1)] : [split.at(0)];
|
|
680
697
|
};
|
|
681
|
-
const $fetch = async (
|
|
698
|
+
const $fetch = async (scope, input, init) => {
|
|
699
|
+
const { event } = scope.getContext(RUNTIME_CONTEXT);
|
|
682
700
|
let response;
|
|
683
701
|
if (event) {
|
|
684
702
|
const url = new URL(input.toString(), event.request.url);
|
|
@@ -703,8 +721,9 @@ const createRuntime = async () => {
|
|
|
703
721
|
const route = await routes[path]?.();
|
|
704
722
|
if (typeof route === "object") return route.fetch(event);
|
|
705
723
|
if (route) {
|
|
706
|
-
const
|
|
707
|
-
|
|
724
|
+
const scope = new Scope();
|
|
725
|
+
scope.setContext(RUNTIME_CONTEXT, { event });
|
|
726
|
+
return sendHtml(event, await renderToString(scope, await import("#virtual/client").then((module) => module.index)));
|
|
708
727
|
}
|
|
709
728
|
} }));
|
|
710
729
|
}
|
|
@@ -746,8 +765,8 @@ const RUNTIME_CONTEXT = defineContext("RUNTIME_CONTEXT");
|
|
|
746
765
|
const Outlet = defineComponent({
|
|
747
766
|
name: "x-outlet",
|
|
748
767
|
shadowRoot: false,
|
|
749
|
-
setup: async ({ scope
|
|
750
|
-
const { event } = getContext(RUNTIME_CONTEXT);
|
|
768
|
+
setup: async ({ scope }) => {
|
|
769
|
+
const { event } = scope.getContext(RUNTIME_CONTEXT);
|
|
751
770
|
const radix = new Radix();
|
|
752
771
|
const routes = await getRoutes();
|
|
753
772
|
for (const path in routes) {
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Context, type Event, type Handle, type Middleware } from "../http";
|
|
2
2
|
import { Radix } from "../radix";
|
|
3
|
+
import { Scope } from "../signals";
|
|
3
4
|
export type Route<T> = {
|
|
4
5
|
fetch: Handle<T>;
|
|
5
6
|
};
|
|
@@ -11,7 +12,7 @@ export type Runtime<T> = {
|
|
|
11
12
|
export declare const defineRoute: <T>(route: Route<T>) => Route<T>;
|
|
12
13
|
export declare const fileName: (path: string) => string | undefined;
|
|
13
14
|
export declare const toPath: (value: string) => (string | undefined)[];
|
|
14
|
-
export declare const $fetch: <T>(
|
|
15
|
+
export declare const $fetch: <T>(scope: Scope, input: string | URL, init?: RequestInit) => Promise<T>;
|
|
15
16
|
export declare const getVariables: <T>(event?: Event<T>) => T;
|
|
16
17
|
export declare const createRuntime: <T>() => Promise<Runtime<T>>;
|
|
17
18
|
export declare const RUNTIME_CONTEXT: import("..").Descriptor<{
|
package/dist/signals/index.d.ts
CHANGED
|
@@ -10,7 +10,11 @@ export declare class StopEvent extends Event {
|
|
|
10
10
|
constructor();
|
|
11
11
|
}
|
|
12
12
|
export declare class Scope extends EventTarget {
|
|
13
|
-
|
|
13
|
+
parentScope?: Scope;
|
|
14
|
+
readonly context: Map<string, unknown>;
|
|
15
|
+
constructor(scope?: Scope);
|
|
16
|
+
getContext<T>(input: Descriptor<T>): T;
|
|
17
|
+
setContext<T>(input: Descriptor<T>, value: T): void;
|
|
14
18
|
onStop(input: (event: StopEvent) => void): void;
|
|
15
19
|
stop(): boolean;
|
|
16
20
|
}
|