revojs 0.0.87 → 0.1.0
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/index.d.ts +176 -9
- package/dist/index.js +212 -902
- package/dist/vite/index.d.ts +53 -0
- package/dist/vite/index.js +460 -0
- package/package.json +11 -10
- package/src/types/index.d.ts +20 -16
- package/dist/app/index.d.ts +0 -36
- package/dist/html/index.d.ts +0 -110
- package/dist/http/index.d.ts +0 -36
- package/dist/jsx/index.d.ts +0 -371
- package/dist/jsx/index.js +0 -160
- package/dist/locale/index.d.ts +0 -26
- package/dist/radix/index.d.ts +0 -12
- package/dist/router/index.d.ts +0 -45
- package/dist/runtime/index.d.ts +0 -55
- package/dist/schema/index.d.ts +0 -22
- package/dist/signals/index.d.ts +0 -44
package/dist/index.js
CHANGED
|
@@ -1,205 +1,125 @@
|
|
|
1
|
-
//#region src/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (Array.isArray(value) && Array.isArray(object[key])) object[key] = [...value, ...object[key]];
|
|
10
|
-
else if (typeof value === "object" && typeof object[key] === "object") object[key] = mergeObjects(value, object[key]);
|
|
11
|
-
else object[key] = value;
|
|
1
|
+
//#region src/server/index.ts
|
|
2
|
+
var Radix = class {
|
|
3
|
+
rootNode;
|
|
4
|
+
constructor() {
|
|
5
|
+
this.rootNode = {
|
|
6
|
+
type: "PATH",
|
|
7
|
+
children: {}
|
|
8
|
+
};
|
|
12
9
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"line",
|
|
91
|
-
"linearGradient",
|
|
92
|
-
"marker",
|
|
93
|
-
"mask",
|
|
94
|
-
"metadata",
|
|
95
|
-
"missing-glyph",
|
|
96
|
-
"mpath",
|
|
97
|
-
"path",
|
|
98
|
-
"pattern",
|
|
99
|
-
"polygon",
|
|
100
|
-
"polyline",
|
|
101
|
-
"radialGradient",
|
|
102
|
-
"rect",
|
|
103
|
-
"set",
|
|
104
|
-
"stop",
|
|
105
|
-
"svg",
|
|
106
|
-
"switch",
|
|
107
|
-
"symbol",
|
|
108
|
-
"text",
|
|
109
|
-
"textPath",
|
|
110
|
-
"tref",
|
|
111
|
-
"tspan",
|
|
112
|
-
"use",
|
|
113
|
-
"view",
|
|
114
|
-
"vkern"
|
|
115
|
-
]);
|
|
116
|
-
function namespace(tag) {
|
|
117
|
-
return svgElements.has(tag) ? "http://www.w3.org/2000/svg" : "http://www.w3.org/1999/xhtml";
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
//#endregion
|
|
121
|
-
//#region src/schema/index.ts
|
|
122
|
-
function isFailure(result) {
|
|
123
|
-
return "issues" in result;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
//#endregion
|
|
127
|
-
//#region src/http/index.ts
|
|
128
|
-
function sendText(scope, text) {
|
|
129
|
-
const { response } = useRuntime(scope);
|
|
130
|
-
response.headers.set("Content-Type", "text/plain");
|
|
131
|
-
return new Response(text, response);
|
|
132
|
-
}
|
|
133
|
-
function sendHtml(scope, text) {
|
|
134
|
-
const { response } = useRuntime(scope);
|
|
135
|
-
response.headers.set("Content-Type", "text/html");
|
|
136
|
-
return new Response(text, response);
|
|
137
|
-
}
|
|
138
|
-
function sendJson(scope, value) {
|
|
139
|
-
const { response } = useRuntime(scope);
|
|
140
|
-
response.headers.set("Content-Type", "application/json");
|
|
141
|
-
return new Response(JSON.stringify(value), response);
|
|
142
|
-
}
|
|
143
|
-
function sendRedirect(scope, path) {
|
|
144
|
-
const { response } = useRuntime(scope);
|
|
145
|
-
response.status = 302;
|
|
146
|
-
response.headers.set("Location", path);
|
|
147
|
-
return new Response(null, response);
|
|
10
|
+
use(path, value) {
|
|
11
|
+
let node = this.rootNode;
|
|
12
|
+
for (const segment of path.split("/")) {
|
|
13
|
+
if (segment.startsWith(WILDCARD)) {
|
|
14
|
+
let childNode$1 = node.children[WILDCARD];
|
|
15
|
+
childNode$1 ??= {
|
|
16
|
+
type: "WILDCARD",
|
|
17
|
+
parameter: segment.substring(WILDCARD.length),
|
|
18
|
+
children: {}
|
|
19
|
+
};
|
|
20
|
+
node.children[WILDCARD] ??= childNode$1;
|
|
21
|
+
node = childNode$1;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (segment.startsWith(PARAMETER)) {
|
|
25
|
+
let childNode$1 = node.children[PARAMETER];
|
|
26
|
+
childNode$1 ??= {
|
|
27
|
+
type: "PARAMETER",
|
|
28
|
+
parameter: segment.substring(PARAMETER.length),
|
|
29
|
+
children: {}
|
|
30
|
+
};
|
|
31
|
+
node.children[PARAMETER] ??= childNode$1;
|
|
32
|
+
node = childNode$1;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
let childNode = node.children[segment];
|
|
36
|
+
childNode ??= {
|
|
37
|
+
type: "PATH",
|
|
38
|
+
children: {}
|
|
39
|
+
};
|
|
40
|
+
node.children[segment] ??= childNode;
|
|
41
|
+
node = childNode;
|
|
42
|
+
}
|
|
43
|
+
node.value = value;
|
|
44
|
+
return node;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
var Router = class extends Radix {
|
|
48
|
+
fetch(scope, next) {
|
|
49
|
+
const { request } = useServer(scope);
|
|
50
|
+
const { pathname } = useUrl(scope);
|
|
51
|
+
const context = {
|
|
52
|
+
route: this.rootNode,
|
|
53
|
+
segments: (request.method.toUpperCase() + pathname).split("/"),
|
|
54
|
+
parameters: {}
|
|
55
|
+
};
|
|
56
|
+
const invoke = (node, index) => {
|
|
57
|
+
if (index === context.segments.length) return node.value;
|
|
58
|
+
const segment = context.segments[index];
|
|
59
|
+
if (node.children[segment]) {
|
|
60
|
+
const route$1 = invoke(node.children[segment], index + 1);
|
|
61
|
+
if (route$1) return route$1;
|
|
62
|
+
}
|
|
63
|
+
if (node.children[PARAMETER]) {
|
|
64
|
+
const parameterNode = node.children[PARAMETER];
|
|
65
|
+
const route$1 = invoke(parameterNode, index + 1);
|
|
66
|
+
if (route$1) {
|
|
67
|
+
context.parameters[parameterNode.parameter] = segment;
|
|
68
|
+
return route$1;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (node.children[WILDCARD]) {
|
|
72
|
+
const wildcardNode = node.children[WILDCARD];
|
|
73
|
+
context.parameters[wildcardNode.parameter] = segment;
|
|
74
|
+
return wildcardNode.value ?? invoke(wildcardNode, segment.length);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const route = invoke(this.rootNode, 0);
|
|
78
|
+
if (route) {
|
|
79
|
+
scope.setContext(ROUTER_CONTEXT, context);
|
|
80
|
+
return route.fetch(scope);
|
|
81
|
+
}
|
|
82
|
+
return next?.();
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
function defineRoute(route) {
|
|
86
|
+
return route;
|
|
148
87
|
}
|
|
149
|
-
function
|
|
150
|
-
|
|
151
|
-
response.status = 400;
|
|
152
|
-
return new Response(text, response);
|
|
88
|
+
function defineMiddleware(middleware) {
|
|
89
|
+
return middleware;
|
|
153
90
|
}
|
|
154
|
-
function
|
|
155
|
-
|
|
156
|
-
response.status = 401;
|
|
157
|
-
return new Response(null, response);
|
|
91
|
+
function useServer(scope) {
|
|
92
|
+
return scope.getContext(SERVER_CONTEXT);
|
|
158
93
|
}
|
|
159
94
|
function useUrl(scope, base) {
|
|
160
|
-
const { request } =
|
|
95
|
+
const { request } = useServer(scope);
|
|
161
96
|
return new URL(request?.url ?? window?.location.href, base);
|
|
162
97
|
}
|
|
163
98
|
function useQuery(scope, schema) {
|
|
164
99
|
const { searchParams } = useUrl(scope);
|
|
165
100
|
const entries = Object.fromEntries(searchParams);
|
|
166
|
-
|
|
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;
|
|
101
|
+
return schema ? parseSchema(scope, schema, entries) : entries;
|
|
172
102
|
}
|
|
173
103
|
function useCookies(scope, schema) {
|
|
174
|
-
const { request } =
|
|
104
|
+
const { request } = useServer(scope);
|
|
175
105
|
const entries = (isClient() ? document.cookie : request.headers.get("Cookie") ?? "").split("; ").reduce((result, cookie) => {
|
|
176
106
|
const [name, value] = cookie.split("=");
|
|
177
107
|
if (name && value) result[name] = decodeURIComponent(value);
|
|
178
108
|
return result;
|
|
179
109
|
}, {});
|
|
180
|
-
|
|
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;
|
|
110
|
+
return schema ? parseSchema(scope, schema, entries) : entries;
|
|
186
111
|
}
|
|
187
112
|
function useSetCookies(scope, schema) {
|
|
188
|
-
const { request } =
|
|
113
|
+
const { request } = useServer(scope);
|
|
189
114
|
const entries = request.headers.getSetCookie().reduce((result, cookie) => {
|
|
190
115
|
const [name, value] = cookie.split("=");
|
|
191
116
|
if (name && value) result[name] = decodeURIComponent(value);
|
|
192
117
|
return result;
|
|
193
118
|
}, {});
|
|
194
|
-
|
|
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;
|
|
119
|
+
return schema ? parseSchema(scope, schema, entries) : entries;
|
|
200
120
|
}
|
|
201
121
|
function setCookie(scope, name, value, options) {
|
|
202
|
-
const { response } =
|
|
122
|
+
const { response } = useServer(scope);
|
|
203
123
|
let cookie = name + "=" + encodeURIComponent(value);
|
|
204
124
|
if (options?.domain) cookie += `; Domain=${options.domain}`;
|
|
205
125
|
if (options?.expires) cookie += `; Expires=${options.expires.toUTCString()}`;
|
|
@@ -212,10 +132,77 @@ function setCookie(scope, name, value, options) {
|
|
|
212
132
|
if (isClient()) document.cookie = cookie;
|
|
213
133
|
else response.headers.append("Set-Cookie", cookie);
|
|
214
134
|
}
|
|
135
|
+
function sendText(scope, text, config) {
|
|
136
|
+
const { response } = useServer(scope);
|
|
137
|
+
response.headers.set("Content-Type", "text/plain");
|
|
138
|
+
return new Response(text, mergeObjects(response, config));
|
|
139
|
+
}
|
|
140
|
+
function sendHtml(scope, text, config) {
|
|
141
|
+
const { response } = useServer(scope);
|
|
142
|
+
response.headers.set("Content-Type", "text/html");
|
|
143
|
+
return new Response(text, mergeObjects(response, config));
|
|
144
|
+
}
|
|
145
|
+
function sendJson(scope, value, config) {
|
|
146
|
+
const { response } = useServer(scope);
|
|
147
|
+
response.headers.set("Content-Type", "application/json");
|
|
148
|
+
return new Response(JSON.stringify(value), mergeObjects(response, config));
|
|
149
|
+
}
|
|
150
|
+
function sendRedirect(scope, path, config) {
|
|
151
|
+
const { response } = useServer(scope);
|
|
152
|
+
response.status = 302;
|
|
153
|
+
response.headers.set("Location", path);
|
|
154
|
+
return new Response(null, mergeObjects(response, config));
|
|
155
|
+
}
|
|
156
|
+
function sendBadRequest(scope, text, config) {
|
|
157
|
+
const { response } = useServer(scope);
|
|
158
|
+
response.status = 400;
|
|
159
|
+
return new Response(text, mergeObjects(response, config));
|
|
160
|
+
}
|
|
161
|
+
function sendUnauthorized(scope, config) {
|
|
162
|
+
const { response } = useServer(scope);
|
|
163
|
+
response.status = 401;
|
|
164
|
+
return new Response(null, mergeObjects(response, config));
|
|
165
|
+
}
|
|
215
166
|
function mimeType(file) {
|
|
216
167
|
const extension = /\.([a-zA-Z0-9]+?)$/.exec(file)?.at(1);
|
|
217
168
|
return mimeTypes[extension ?? ""] ?? "text/plain";
|
|
218
169
|
}
|
|
170
|
+
function toRoutePath(path) {
|
|
171
|
+
const result = ("/" + path).replaceAll(/\/index/g, "").replaceAll(/\[\.\.\.(.*?)\]/g, (_, value) => WILDCARD + value).replaceAll(/\[(.*?)\]/g, (_, value) => PARAMETER + value);
|
|
172
|
+
return (result.startsWith("/") ? result : "/" + result).split(".");
|
|
173
|
+
}
|
|
174
|
+
async function createServer() {
|
|
175
|
+
const router = new Router();
|
|
176
|
+
const pipeline = new Array();
|
|
177
|
+
const middlewares = await import("#virtual/middlewares").then((module) => Object.entries(module.default));
|
|
178
|
+
for (const [_, middleware] of middlewares) pipeline.push(middleware);
|
|
179
|
+
const assets = await import("#virtual/assets").then((module) => Object.entries(module.default));
|
|
180
|
+
for (const [path, asset] of assets) router.use(`GET/${path}`, defineRoute({ async fetch(scope) {
|
|
181
|
+
const { response } = useServer(scope);
|
|
182
|
+
response.headers.set("Content-Type", mimeType(path));
|
|
183
|
+
return new Response(asset, response);
|
|
184
|
+
} }));
|
|
185
|
+
const routes = await import("#virtual/routes").then((module) => Object.entries(module.default));
|
|
186
|
+
for (const [path, route] of routes) {
|
|
187
|
+
const [name, method] = toRoutePath(path);
|
|
188
|
+
router.use(method?.toUpperCase() + name, route);
|
|
189
|
+
}
|
|
190
|
+
pipeline.push(router);
|
|
191
|
+
const invoke = (scope, index) => {
|
|
192
|
+
return pipeline.at(index)?.fetch(scope, () => invoke(scope, index + 1));
|
|
193
|
+
};
|
|
194
|
+
return {
|
|
195
|
+
router,
|
|
196
|
+
pipeline,
|
|
197
|
+
async fetch(scope) {
|
|
198
|
+
return await invoke(scope, 0) ?? sendText(scope, "NOT_FOUND", { status: 404 });
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
const ROUTER_CONTEXT = defineContext("ROUTER_CONTEXT");
|
|
203
|
+
const SERVER_CONTEXT = defineContext("SERVER_CONTEXT");
|
|
204
|
+
const WILDCARD = "$";
|
|
205
|
+
const PARAMETER = ":";
|
|
219
206
|
const mimeTypes = {
|
|
220
207
|
txt: "text/plain",
|
|
221
208
|
css: "text/css",
|
|
@@ -263,47 +250,7 @@ const mimeTypes = {
|
|
|
263
250
|
};
|
|
264
251
|
|
|
265
252
|
//#endregion
|
|
266
|
-
//#region src/
|
|
267
|
-
var Radix = class Radix {
|
|
268
|
-
value;
|
|
269
|
-
input;
|
|
270
|
-
children;
|
|
271
|
-
constructor(input) {
|
|
272
|
-
this.input = input;
|
|
273
|
-
this.children = {};
|
|
274
|
-
}
|
|
275
|
-
insert(path, value) {
|
|
276
|
-
let node = this;
|
|
277
|
-
for (let segment of path.split("/")) {
|
|
278
|
-
let input;
|
|
279
|
-
if (segment.startsWith(":")) {
|
|
280
|
-
input = segment.substring(1);
|
|
281
|
-
segment = ":";
|
|
282
|
-
}
|
|
283
|
-
let childNode = node.children[segment];
|
|
284
|
-
if (childNode === void 0) {
|
|
285
|
-
childNode = new Radix(input);
|
|
286
|
-
node.children[segment] = childNode;
|
|
287
|
-
}
|
|
288
|
-
node = childNode;
|
|
289
|
-
}
|
|
290
|
-
node.value = value;
|
|
291
|
-
return this;
|
|
292
|
-
}
|
|
293
|
-
match(path) {
|
|
294
|
-
let node = this;
|
|
295
|
-
const match = { inputs: {} };
|
|
296
|
-
for (const segment of path.split("/")) {
|
|
297
|
-
node = node?.children[segment] ?? node?.children[":"];
|
|
298
|
-
if (node?.input) match.inputs[node.input] = segment;
|
|
299
|
-
}
|
|
300
|
-
match.value = node?.value;
|
|
301
|
-
return match;
|
|
302
|
-
}
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
//#endregion
|
|
306
|
-
//#region src/signals/index.ts
|
|
253
|
+
//#region src/shared/index.ts
|
|
307
254
|
var StopEvent = class extends Event {
|
|
308
255
|
constructor() {
|
|
309
256
|
super("stop");
|
|
@@ -316,18 +263,18 @@ var Scope = class extends EventTarget {
|
|
|
316
263
|
super();
|
|
317
264
|
this.parentScope = parentScope;
|
|
318
265
|
this.parentScope?.onStop(() => this.stop());
|
|
319
|
-
this.context =
|
|
266
|
+
this.context = {};
|
|
320
267
|
}
|
|
321
268
|
getContext(input) {
|
|
322
269
|
let scope = this;
|
|
323
270
|
while (scope) {
|
|
324
|
-
if (scope.context
|
|
271
|
+
if (scope.context[input]) return scope.context[input];
|
|
325
272
|
scope = scope.parentScope;
|
|
326
273
|
}
|
|
327
274
|
return {};
|
|
328
275
|
}
|
|
329
276
|
setContext(input, value) {
|
|
330
|
-
this.context
|
|
277
|
+
this.context[input] = value;
|
|
331
278
|
}
|
|
332
279
|
onStop(input) {
|
|
333
280
|
this.addEventListener("stop", input, { once: true });
|
|
@@ -336,563 +283,8 @@ var Scope = class extends EventTarget {
|
|
|
336
283
|
return this.dispatchEvent(new StopEvent());
|
|
337
284
|
}
|
|
338
285
|
};
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
constructor(parentScope, invoke) {
|
|
342
|
-
super(parentScope);
|
|
343
|
-
this.invoke = invoke;
|
|
344
|
-
}
|
|
345
|
-
run() {
|
|
346
|
-
this.stop();
|
|
347
|
-
return this.invoke(this);
|
|
348
|
-
}
|
|
349
|
-
};
|
|
350
|
-
var Handler = class Handler {
|
|
351
|
-
get(target, key) {
|
|
352
|
-
const compute = activeCompute;
|
|
353
|
-
if (compute) {
|
|
354
|
-
const computes = targets.get(target) ?? /* @__PURE__ */ new Map();
|
|
355
|
-
const set = computes.get(key) ?? /* @__PURE__ */ new Set();
|
|
356
|
-
computes.set(key, set.add(compute));
|
|
357
|
-
targets.set(target, computes);
|
|
358
|
-
compute.parentScope?.onStop(() => {
|
|
359
|
-
set.delete(compute);
|
|
360
|
-
if (set.size === 0) {
|
|
361
|
-
computes.delete(key);
|
|
362
|
-
if (computes.size === 0) targets.delete(target);
|
|
363
|
-
}
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
const value = Reflect.get(target, key);
|
|
367
|
-
if (value) {
|
|
368
|
-
if (typeof value === "function" && !value.prototype) return value.bind(target);
|
|
369
|
-
if (typeof value === "object") {
|
|
370
|
-
const tag = Object.prototype.toString.call(value);
|
|
371
|
-
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());
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
return value;
|
|
375
|
-
}
|
|
376
|
-
set(target, key, value) {
|
|
377
|
-
const result = Reflect.set(target, key, value);
|
|
378
|
-
for (const compute of targets.get(target)?.get(key) ?? []) compute.run();
|
|
379
|
-
return result;
|
|
380
|
-
}
|
|
381
|
-
};
|
|
382
|
-
function createState(value) {
|
|
383
|
-
return new Proxy({ value }, new Handler());
|
|
384
|
-
}
|
|
385
|
-
function createCompute(scope, invoke) {
|
|
386
|
-
let previous = activeCompute;
|
|
387
|
-
activeCompute = new Compute(scope, invoke);
|
|
388
|
-
const result = invoke(activeCompute);
|
|
389
|
-
if (result instanceof Promise) return result.finally(() => activeCompute = previous);
|
|
390
|
-
activeCompute = previous;
|
|
391
|
-
return result;
|
|
392
|
-
}
|
|
393
|
-
function createMemo(scope, invoke) {
|
|
394
|
-
let state;
|
|
395
|
-
const compute = createCompute(scope, (scope$1) => {
|
|
396
|
-
const value = invoke(scope$1);
|
|
397
|
-
if (typeof state === "object") state.value = value;
|
|
398
|
-
return value;
|
|
399
|
-
});
|
|
400
|
-
state = createState(compute);
|
|
401
|
-
return state;
|
|
402
|
-
}
|
|
403
|
-
function fromValue(value) {
|
|
404
|
-
if (value instanceof Function) return fromValue(value());
|
|
405
|
-
return value;
|
|
406
|
-
}
|
|
407
|
-
function untrack(invoke) {
|
|
408
|
-
let previous = activeCompute;
|
|
409
|
-
activeCompute = void 0;
|
|
410
|
-
const result = invoke();
|
|
411
|
-
if (result instanceof Promise) return result.finally(() => activeCompute = previous);
|
|
412
|
-
activeCompute = previous;
|
|
413
|
-
return result;
|
|
414
|
-
}
|
|
415
|
-
function defineContext(key) {
|
|
416
|
-
return key;
|
|
417
|
-
}
|
|
418
|
-
let activeCompute;
|
|
419
|
-
const targets = /* @__PURE__ */ new WeakMap();
|
|
420
|
-
|
|
421
|
-
//#endregion
|
|
422
|
-
//#region src/runtime/index.ts
|
|
423
|
-
function isRoute(value) {
|
|
424
|
-
return !!value && typeof value === "object" && "fetch" in value;
|
|
425
|
-
}
|
|
426
|
-
function useRuntime(scope) {
|
|
427
|
-
return scope.getContext(RUNTIME_CONTEXT);
|
|
428
|
-
}
|
|
429
|
-
function useRoute(scope) {
|
|
430
|
-
return scope.getContext(ROUTE_CONTEXT);
|
|
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
|
-
}
|
|
441
|
-
function defineRoute(route) {
|
|
442
|
-
return route;
|
|
443
|
-
}
|
|
444
|
-
function defineMiddleware(middleware) {
|
|
445
|
-
return middleware;
|
|
446
|
-
}
|
|
447
|
-
function fileName(path) {
|
|
448
|
-
return path.split("/").pop()?.split(".").slice(0, -1).join(".");
|
|
449
|
-
}
|
|
450
|
-
function toPath(value) {
|
|
451
|
-
const path = (value.startsWith("/") ? value : "/" + value).replaceAll(/\/index/g, "").replaceAll(/\[(.*?)\]/g, (_, name) => ":" + name);
|
|
452
|
-
const route = path.startsWith("/") ? path : "/" + path;
|
|
453
|
-
const split = route.split(".");
|
|
454
|
-
return split.length === 3 ? [split.at(0), split.at(1)] : [split.at(0)];
|
|
455
|
-
}
|
|
456
|
-
async function $fetch(scope, input, options) {
|
|
457
|
-
const { request, variables } = useRuntime(scope);
|
|
458
|
-
let response;
|
|
459
|
-
if (request) {
|
|
460
|
-
const next = new Scope();
|
|
461
|
-
const url = new URL(input.toString(), request.url);
|
|
462
|
-
next.setContext(RUNTIME_CONTEXT, {
|
|
463
|
-
tasks: [],
|
|
464
|
-
states: {},
|
|
465
|
-
request: new Request(url, options),
|
|
466
|
-
response: { headers: new Headers() },
|
|
467
|
-
variables
|
|
468
|
-
});
|
|
469
|
-
const previous = new URL(request.url);
|
|
470
|
-
if (url.origin === previous.origin) response = await (await import("#virtual/runtime")).runtime.fetch(next);
|
|
471
|
-
}
|
|
472
|
-
response ??= await fetch(input, options);
|
|
473
|
-
if (response.ok === false) throw response;
|
|
474
|
-
const contentType = response.headers.get("Content-Type")?.split(";").shift() ?? "";
|
|
475
|
-
switch (contentType) {
|
|
476
|
-
case "application/json": return response.json();
|
|
477
|
-
default: return response;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
function useState(scope, name, value) {
|
|
481
|
-
const state = createState(value);
|
|
482
|
-
if (isClient()) {
|
|
483
|
-
if (STATES === void 0) {
|
|
484
|
-
const element = document.getElementById("STATES");
|
|
485
|
-
STATES = element?.textContent ? JSON.parse(element.textContent) : {};
|
|
486
|
-
}
|
|
487
|
-
state.value = STATES[name];
|
|
488
|
-
createCompute(scope, () => STATES && (STATES[name] = state.value));
|
|
489
|
-
}
|
|
490
|
-
if (isServer()) {
|
|
491
|
-
const { states } = useRuntime(scope);
|
|
492
|
-
states[name] = state;
|
|
493
|
-
}
|
|
494
|
-
return state;
|
|
495
|
-
}
|
|
496
|
-
function useAsync(scope, name, invoke, defaultOptions) {
|
|
497
|
-
const { tasks } = useRuntime(scope);
|
|
498
|
-
const state = useState(scope, name);
|
|
499
|
-
const isLoading = createState(false);
|
|
500
|
-
const execute = async (options) => {
|
|
501
|
-
const onCatch = options?.catch ?? defaultOptions?.catch;
|
|
502
|
-
const viewTransition = options?.viewTransition ?? defaultOptions?.viewTransition;
|
|
503
|
-
isLoading.value = true;
|
|
504
|
-
try {
|
|
505
|
-
const result = await invoke();
|
|
506
|
-
if (JSON.stringify(state.value ?? {}) !== JSON.stringify(result)) if (viewTransition) await startViewTransition(viewTransition, () => state.value = result);
|
|
507
|
-
else state.value = result;
|
|
508
|
-
} catch (error) {
|
|
509
|
-
onCatch?.(error);
|
|
510
|
-
} finally {
|
|
511
|
-
isLoading.value = false;
|
|
512
|
-
}
|
|
513
|
-
return state.value;
|
|
514
|
-
};
|
|
515
|
-
const task = execute(defaultOptions);
|
|
516
|
-
if (isServer()) tasks.push(task);
|
|
517
|
-
return {
|
|
518
|
-
state,
|
|
519
|
-
isLoading,
|
|
520
|
-
execute
|
|
521
|
-
};
|
|
522
|
-
}
|
|
523
|
-
function useFetch(scope, input, options) {
|
|
524
|
-
return useAsync(scope, input.toString(), () => $fetch(scope, input, options), options);
|
|
525
|
-
}
|
|
526
|
-
async function createRuntime() {
|
|
527
|
-
const radix = new Radix();
|
|
528
|
-
const middlewares = new Array();
|
|
529
|
-
const routes = await useRoutes();
|
|
530
|
-
for (const path in routes) {
|
|
531
|
-
const [name, method] = toPath(path);
|
|
532
|
-
radix.insert((method ?? "GET").toUpperCase() + name, defineRoute({ fetch: async (scope) => {
|
|
533
|
-
const route = routes[path];
|
|
534
|
-
if (isRoute(route)) return route.fetch(scope);
|
|
535
|
-
const { states } = useRuntime(scope);
|
|
536
|
-
const content = await renderToString(scope, await import("#virtual/client").then((module) => module.client), { head: { children: ["<!--STATES-->"] } });
|
|
537
|
-
const entries = Object.entries(states).reduce((states$1, [name$1, state]) => {
|
|
538
|
-
return {
|
|
539
|
-
...states$1,
|
|
540
|
-
[name$1]: state.value
|
|
541
|
-
};
|
|
542
|
-
}, {});
|
|
543
|
-
return sendHtml(scope, content.replace("<!--STATES-->", await renderToString(scope, {
|
|
544
|
-
tag: "script",
|
|
545
|
-
attributes: {
|
|
546
|
-
id: "STATES",
|
|
547
|
-
type: "application/json"
|
|
548
|
-
},
|
|
549
|
-
children: [JSON.stringify(entries)]
|
|
550
|
-
})));
|
|
551
|
-
} }));
|
|
552
|
-
}
|
|
553
|
-
const assets = await useAssets();
|
|
554
|
-
for (const path in assets) radix.insert("GET/" + path, defineRoute({ fetch: async (scope) => {
|
|
555
|
-
const { response } = useRuntime(scope);
|
|
556
|
-
let content = assets[path];
|
|
557
|
-
if (content) {
|
|
558
|
-
if (path.endsWith(".png")) {
|
|
559
|
-
const [_, base64] = content.split(",");
|
|
560
|
-
const binary = atob(base64.replace(/-/g, "+").replace(/_/g, "/"));
|
|
561
|
-
const bytes = new Uint8Array(binary.length);
|
|
562
|
-
for (let index = 0; index < binary.length; index++) bytes[index] = binary.charCodeAt(index);
|
|
563
|
-
content = bytes;
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
response.headers.set("Content-Type", mimeType(path));
|
|
567
|
-
return new Response(content, response);
|
|
568
|
-
} }));
|
|
569
|
-
const invoke = (scope, route, index) => {
|
|
570
|
-
return middlewares.at(index)?.fetch(scope, () => invoke(scope, route, index + 1)) ?? route.fetch(scope);
|
|
571
|
-
};
|
|
572
|
-
return {
|
|
573
|
-
radix,
|
|
574
|
-
middlewares,
|
|
575
|
-
fetch: async (scope) => {
|
|
576
|
-
const { request } = useRuntime(scope);
|
|
577
|
-
const { pathname } = useUrl(scope);
|
|
578
|
-
const { value: route, inputs } = radix.match(request.method + pathname);
|
|
579
|
-
try {
|
|
580
|
-
scope.setContext(ROUTE_CONTEXT, { inputs: createState(inputs) });
|
|
581
|
-
if (route) {
|
|
582
|
-
const response = await invoke(scope, route, 0);
|
|
583
|
-
if (response) return response;
|
|
584
|
-
}
|
|
585
|
-
return sendText(scope, "NOT_FOUND");
|
|
586
|
-
} catch (exception) {
|
|
587
|
-
if (exception instanceof Response) return exception;
|
|
588
|
-
throw exception;
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
};
|
|
592
|
-
}
|
|
593
|
-
let STATES;
|
|
594
|
-
const RUNTIME_CONTEXT = defineContext("RUNTIME_CONTEXT");
|
|
595
|
-
const ROUTE_CONTEXT = defineContext("ROUTE_CONTEXT");
|
|
596
|
-
|
|
597
|
-
//#endregion
|
|
598
|
-
//#region src/html/index.ts
|
|
599
|
-
var MountedEvent = class extends Event {
|
|
600
|
-
constructor() {
|
|
601
|
-
super("mounted");
|
|
602
|
-
}
|
|
603
|
-
};
|
|
604
|
-
function isTemplate(value) {
|
|
605
|
-
return !!value && typeof value === "object" && "tag" in value && "attributes" in value && "children" in value;
|
|
606
|
-
}
|
|
607
|
-
function isCustomElement(value) {
|
|
608
|
-
return !!value && typeof value === "object" && "component" in value;
|
|
609
|
-
}
|
|
610
|
-
function isComponent(value) {
|
|
611
|
-
return !!value && typeof value === "function" && "$name" in value;
|
|
612
|
-
}
|
|
613
|
-
function useHost(scope) {
|
|
614
|
-
return scope.getContext(HOST_CONTEXT);
|
|
615
|
-
}
|
|
616
|
-
function createElement(input, attributes, ...children) {
|
|
617
|
-
if (isComponent(input)) return {
|
|
618
|
-
tag: input.$name,
|
|
619
|
-
attributes: attributes ?? {},
|
|
620
|
-
children
|
|
621
|
-
};
|
|
622
|
-
if (typeof input === "string") return {
|
|
623
|
-
tag: input,
|
|
624
|
-
attributes: attributes ?? {},
|
|
625
|
-
children
|
|
626
|
-
};
|
|
627
|
-
return input?.({
|
|
628
|
-
...attributes,
|
|
629
|
-
children
|
|
630
|
-
});
|
|
631
|
-
}
|
|
632
|
-
function toString(slot) {
|
|
633
|
-
switch (typeof slot) {
|
|
634
|
-
case "string":
|
|
635
|
-
case "number":
|
|
636
|
-
case "bigint":
|
|
637
|
-
case "boolean":
|
|
638
|
-
case "symbol": return slot.toString();
|
|
639
|
-
case "object": return JSON.stringify(slot);
|
|
640
|
-
case "function": return toString(slot());
|
|
641
|
-
default: return "";
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
function toArray(hydration) {
|
|
645
|
-
if (Array.isArray(hydration)) return hydration.reduce((items, child) => items.concat(toArray(child)), []);
|
|
646
|
-
return [hydration];
|
|
647
|
-
}
|
|
648
|
-
function toRange(hydration) {
|
|
649
|
-
const items = toArray(hydration);
|
|
650
|
-
const range = document.createRange();
|
|
651
|
-
const firstNode = items.at(0);
|
|
652
|
-
if (firstNode) range.setStartBefore(firstNode);
|
|
653
|
-
const lastNode = items.at(-1);
|
|
654
|
-
if (lastNode) range.setEndAfter(lastNode);
|
|
655
|
-
return range;
|
|
656
|
-
}
|
|
657
|
-
function toFragment(hydration) {
|
|
658
|
-
return toArray(hydration).reduce((fragment, node) => {
|
|
659
|
-
fragment.appendChild(node);
|
|
660
|
-
return fragment;
|
|
661
|
-
}, document.createDocumentFragment());
|
|
662
|
-
}
|
|
663
|
-
function hydrate(scope, parentNode, slot, index, previous) {
|
|
664
|
-
let hydration = parentNode.childNodes.item(index);
|
|
665
|
-
if (Array.isArray(slot)) {
|
|
666
|
-
const items = new Array();
|
|
667
|
-
for (const [index$1, childSlot] of slot.entries()) items.push(hydrate(scope, parentNode, childSlot, index$1, previous));
|
|
668
|
-
if (items.length) hydration = items;
|
|
669
|
-
else if (previous || !(hydration instanceof Comment)) hydration = document.createComment("");
|
|
670
|
-
}
|
|
671
|
-
if (typeof slot === "function") {
|
|
672
|
-
let previous$1;
|
|
673
|
-
createCompute(scope, (scope$1) => {
|
|
674
|
-
let input = slot;
|
|
675
|
-
while (typeof input === "function") input = input();
|
|
676
|
-
hydration = hydrate(scope$1, parentNode, input, index, previous$1);
|
|
677
|
-
if (previous$1 && hydration !== previous$1) if (Array.isArray(hydration)) if (Array.isArray(previous$1)) {
|
|
678
|
-
const range = toRange(previous$1);
|
|
679
|
-
range.deleteContents();
|
|
680
|
-
range.collapse(true);
|
|
681
|
-
range.insertNode(toFragment(hydration));
|
|
682
|
-
} else if (parentNode.contains(previous$1)) parentNode.replaceChild(toFragment(hydration), previous$1);
|
|
683
|
-
else parentNode.replaceChild(toFragment(hydration), parentNode.childNodes.item(index));
|
|
684
|
-
else if (Array.isArray(previous$1)) {
|
|
685
|
-
const range = toRange(previous$1);
|
|
686
|
-
range.deleteContents();
|
|
687
|
-
range.collapse(true);
|
|
688
|
-
range.insertNode(hydration);
|
|
689
|
-
} else if (parentNode.contains(previous$1)) parentNode.replaceChild(hydration, previous$1);
|
|
690
|
-
else parentNode.replaceChild(hydration, parentNode.childNodes.item(index));
|
|
691
|
-
previous$1 = hydration;
|
|
692
|
-
});
|
|
693
|
-
}
|
|
694
|
-
if ((slot === null || slot === void 0) && (previous || !(hydration instanceof Comment))) hydration = document.createComment("");
|
|
695
|
-
if (typeof slot === "number" || typeof slot === "bigint" || typeof slot === "boolean" || typeof slot === "string" || typeof slot === "symbol") {
|
|
696
|
-
const textContent = slot.toString();
|
|
697
|
-
if (previous || !(hydration instanceof Text)) hydration = document.createTextNode(textContent);
|
|
698
|
-
else if (textContent !== hydration.textContent) hydration = parentNode.replaceChild(document.createTextNode(textContent), hydration);
|
|
699
|
-
}
|
|
700
|
-
if (isTemplate(slot)) {
|
|
701
|
-
const Component = components.get(slot.tag);
|
|
702
|
-
if (Component) registerComponent(Component);
|
|
703
|
-
if (previous || !(hydration instanceof Element && hydration.tagName.toUpperCase() === slot.tag.toUpperCase())) hydration = document.createElementNS(namespace(slot.tag), slot.tag);
|
|
704
|
-
for (const [name, value] of Object.entries(slot.attributes)) createCompute(scope, (scope$1) => {
|
|
705
|
-
const target = hydration;
|
|
706
|
-
if (name.startsWith("on")) {
|
|
707
|
-
const event = name.substring(2).toLowerCase();
|
|
708
|
-
useEvent(scope$1, target, event, value);
|
|
709
|
-
} else {
|
|
710
|
-
const set = toString(value);
|
|
711
|
-
if (set === "" || set === "false") return target.removeAttribute(name);
|
|
712
|
-
return target.setAttribute(name, set);
|
|
713
|
-
}
|
|
714
|
-
});
|
|
715
|
-
let index$1 = 0;
|
|
716
|
-
for (const childSlot of slot.children) {
|
|
717
|
-
const nodes = toArray(hydrate(scope, hydration, childSlot, index$1));
|
|
718
|
-
index$1 += nodes.length || 1;
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
hydration ??= document.createComment("");
|
|
722
|
-
if (parentNode.childNodes.item(index) === null) parentNode.appendChild(toFragment(hydration));
|
|
723
|
-
return hydration;
|
|
724
|
-
}
|
|
725
|
-
async function renderToString(scope, slot, defaults) {
|
|
726
|
-
const { tasks } = useRuntime(scope);
|
|
727
|
-
if (typeof slot === "number" || typeof slot === "bigint" || typeof slot === "boolean" || typeof slot === "string" || typeof slot === "symbol") return slot.toString();
|
|
728
|
-
if (typeof slot === "function") {
|
|
729
|
-
let input = slot;
|
|
730
|
-
while (typeof input === "function") input = await input();
|
|
731
|
-
return await renderToString(scope, input, defaults);
|
|
732
|
-
}
|
|
733
|
-
if (Array.isArray(slot)) {
|
|
734
|
-
let items = "";
|
|
735
|
-
for (const childSlot of slot) items += await renderToString(scope, childSlot, defaults);
|
|
736
|
-
if (items === "") return "<!---->";
|
|
737
|
-
return items;
|
|
738
|
-
}
|
|
739
|
-
if (isTemplate(slot)) {
|
|
740
|
-
const merge = mergeObjects(slot, defaults?.[slot.tag]);
|
|
741
|
-
const CustomElement = components.get(merge.tag);
|
|
742
|
-
const prefix = Object.entries(merge.attributes).reduce((chunks, [name, value]) => {
|
|
743
|
-
if (value && !name.startsWith("on")) chunks.push(`${name}='${toString(value)}'`);
|
|
744
|
-
return chunks;
|
|
745
|
-
}, [merge.tag]).join(" ");
|
|
746
|
-
let content = `<${prefix}>`;
|
|
747
|
-
if (CustomElement) {
|
|
748
|
-
const element = new CustomElement(merge.attributes, scope);
|
|
749
|
-
const result = element.setup();
|
|
750
|
-
while (tasks.length) await tasks.shift();
|
|
751
|
-
const template = await renderToString(element.scope, result, defaults);
|
|
752
|
-
if (element.shadowRoot) {
|
|
753
|
-
const shadow = {
|
|
754
|
-
tag: "template",
|
|
755
|
-
attributes: { shadowRootMode: element.shadowRoot.mode },
|
|
756
|
-
children: [template]
|
|
757
|
-
};
|
|
758
|
-
content += await renderToString(element.scope, shadow, defaults);
|
|
759
|
-
} else content += template;
|
|
760
|
-
}
|
|
761
|
-
for (const childSlot of merge.children) content += await renderToString(scope, childSlot, defaults);
|
|
762
|
-
content += `</${merge.tag}>`;
|
|
763
|
-
return content;
|
|
764
|
-
}
|
|
765
|
-
return "<!---->";
|
|
766
|
-
}
|
|
767
|
-
function defineComponent(options) {
|
|
768
|
-
class Instance {
|
|
769
|
-
static $name = options.name;
|
|
770
|
-
static $events = options.events ?? {};
|
|
771
|
-
static $attributes = options.attributes ?? {};
|
|
772
|
-
scope;
|
|
773
|
-
events;
|
|
774
|
-
attributes;
|
|
775
|
-
shadowRoot;
|
|
776
|
-
constructor(input, parentScope) {
|
|
777
|
-
this.scope = new Scope(parentScope);
|
|
778
|
-
this.events = Object.keys(options.events ?? {}).reduce((output, name) => {
|
|
779
|
-
Reflect.set(output, name, input?.[name], output);
|
|
780
|
-
return output;
|
|
781
|
-
}, {});
|
|
782
|
-
this.attributes = Object.entries(options.attributes ?? {}).reduce((attributes, [name, attribute]) => {
|
|
783
|
-
Reflect.set(attributes.value, name, fromValue(input?.[name]) ?? attribute.default, attributes.value);
|
|
784
|
-
return attributes;
|
|
785
|
-
}, createState({}));
|
|
786
|
-
this.shadowRoot = options.shadowRoot;
|
|
787
|
-
}
|
|
788
|
-
setup = () => options.setup(this);
|
|
789
|
-
}
|
|
790
|
-
components.set(options.name, Instance);
|
|
791
|
-
return Instance;
|
|
792
|
-
}
|
|
793
|
-
function toCustomElement(Component) {
|
|
794
|
-
return class extends HTMLElement {
|
|
795
|
-
static formAssociated = true;
|
|
796
|
-
component;
|
|
797
|
-
constructor() {
|
|
798
|
-
super();
|
|
799
|
-
this.component = new Component();
|
|
800
|
-
this.component.scope.setContext(HOST_CONTEXT, {
|
|
801
|
-
host: this,
|
|
802
|
-
internals: this.attachInternals()
|
|
803
|
-
});
|
|
804
|
-
}
|
|
805
|
-
connectedCallback() {
|
|
806
|
-
let rootNode = this;
|
|
807
|
-
const findParentScope = (node) => {
|
|
808
|
-
if (node) {
|
|
809
|
-
if (isCustomElement(node)) return node.component.scope;
|
|
810
|
-
if (node instanceof ShadowRoot) return findParentScope(node.host);
|
|
811
|
-
return findParentScope(node.parentNode);
|
|
812
|
-
}
|
|
813
|
-
};
|
|
814
|
-
this.component.scope.parentScope = findParentScope(this.parentNode);
|
|
815
|
-
if (this.component.shadowRoot) rootNode = this.shadowRoot ?? this.attachShadow(this.component.shadowRoot);
|
|
816
|
-
for (const [name, event] of Object.entries(Component.$events)) Reflect.set(this.component.events, name, (value) => {
|
|
817
|
-
if (value instanceof Event) return;
|
|
818
|
-
this.dispatchEvent(new CustomEvent(name.substring(2).toLowerCase(), {
|
|
819
|
-
...event,
|
|
820
|
-
detail: value
|
|
821
|
-
}));
|
|
822
|
-
});
|
|
823
|
-
hydrate(this.component.scope, rootNode, untrack(this.component.setup), 0);
|
|
824
|
-
requestAnimationFrame(() => this.dispatchEvent(new MountedEvent()));
|
|
825
|
-
}
|
|
826
|
-
attributeChangedCallback(name, oldValue, value) {
|
|
827
|
-
if (value === oldValue) return;
|
|
828
|
-
const attribute = Component.$attributes?.[name];
|
|
829
|
-
if (attribute) {
|
|
830
|
-
let convertedValue;
|
|
831
|
-
if (value) switch (attribute.type) {
|
|
832
|
-
case String:
|
|
833
|
-
convertedValue = value;
|
|
834
|
-
break;
|
|
835
|
-
case Number:
|
|
836
|
-
convertedValue = Number(value);
|
|
837
|
-
break;
|
|
838
|
-
case Boolean:
|
|
839
|
-
convertedValue = value.toLowerCase() === "true";
|
|
840
|
-
break;
|
|
841
|
-
case Object:
|
|
842
|
-
convertedValue = JSON.parse(value);
|
|
843
|
-
break;
|
|
844
|
-
}
|
|
845
|
-
Reflect.set(this.component.attributes.value, name, convertedValue ?? attribute.default, this.component.attributes.value);
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
disconnectedCallback() {
|
|
849
|
-
this.component.scope.stop();
|
|
850
|
-
}
|
|
851
|
-
static get observedAttributes() {
|
|
852
|
-
return Object.keys(Component.$attributes ?? {});
|
|
853
|
-
}
|
|
854
|
-
};
|
|
855
|
-
}
|
|
856
|
-
function registerComponent(component) {
|
|
857
|
-
if (isClient()) {
|
|
858
|
-
const previous = customElements.get(component.$name);
|
|
859
|
-
if (previous === void 0) customElements.define(component.$name, toCustomElement(component));
|
|
860
|
-
}
|
|
861
|
-
return component;
|
|
862
|
-
}
|
|
863
|
-
function useEvent(scope, target, event, input, options) {
|
|
864
|
-
const controller = new AbortController();
|
|
865
|
-
target?.addEventListener(event, (event$1) => {
|
|
866
|
-
if (Array.isArray(input)) for (const target$1 of input) target$1?.(event$1);
|
|
867
|
-
else input?.(event$1);
|
|
868
|
-
}, {
|
|
869
|
-
signal: controller.signal,
|
|
870
|
-
...options
|
|
871
|
-
});
|
|
872
|
-
scope.onStop(() => controller.abort());
|
|
873
|
-
}
|
|
874
|
-
function onMounted(scope, event) {
|
|
875
|
-
if (isClient()) {
|
|
876
|
-
const { host } = useHost(scope);
|
|
877
|
-
useEvent(scope, host, "mounted", event);
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
async function startViewTransition(name, invoke) {
|
|
881
|
-
if (isClient() && document.startViewTransition !== void 0) {
|
|
882
|
-
await activeViewTransition.value?.update;
|
|
883
|
-
const update = document.startViewTransition(invoke).finished.finally(() => activeViewTransition.value = void 0);
|
|
884
|
-
activeViewTransition.value = {
|
|
885
|
-
name,
|
|
886
|
-
update
|
|
887
|
-
};
|
|
888
|
-
return update;
|
|
889
|
-
}
|
|
890
|
-
return invoke();
|
|
891
|
-
}
|
|
892
|
-
function onViewTransition(name, value) {
|
|
893
|
-
return () => {
|
|
894
|
-
if (activeViewTransition.value?.name === name && isClient()) return value instanceof Function ? value(name) : value;
|
|
895
|
-
};
|
|
286
|
+
function defineContext(name) {
|
|
287
|
+
return name;
|
|
896
288
|
}
|
|
897
289
|
function isClient() {
|
|
898
290
|
return typeof window !== "undefined";
|
|
@@ -900,140 +292,58 @@ function isClient() {
|
|
|
900
292
|
function isServer() {
|
|
901
293
|
return typeof window === "undefined";
|
|
902
294
|
}
|
|
903
|
-
function
|
|
904
|
-
|
|
905
|
-
}
|
|
906
|
-
function stopPropagation(event) {
|
|
907
|
-
event.stopPropagation();
|
|
295
|
+
function isFailure(result) {
|
|
296
|
+
return "issues" in result;
|
|
908
297
|
}
|
|
909
|
-
function
|
|
910
|
-
|
|
298
|
+
function parseSchema(scope, schema, value) {
|
|
299
|
+
const result = schema["~standard"].validate(value);
|
|
300
|
+
if (isFailure(result)) throw sendBadRequest(scope, result.issues.map((issue) => issue.message).join(", "));
|
|
301
|
+
return result.value;
|
|
911
302
|
}
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
const
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
};
|
|
923
|
-
var AfterNavigateEvent = class extends Event {
|
|
924
|
-
constructor() {
|
|
925
|
-
super("afterNavigate");
|
|
926
|
-
}
|
|
927
|
-
};
|
|
928
|
-
function provideRouterContext(scope, options) {
|
|
929
|
-
const url = createState();
|
|
930
|
-
const route = createState();
|
|
931
|
-
const radix = new Radix();
|
|
932
|
-
const navigator = new EventTarget();
|
|
933
|
-
for (const path in options.routes) {
|
|
934
|
-
const [name] = toPath(path);
|
|
935
|
-
if (name) {
|
|
936
|
-
const value = options.routes[path];
|
|
937
|
-
if (value) radix.insert(name, value);
|
|
938
|
-
}
|
|
303
|
+
function mergeObjects(base, input) {
|
|
304
|
+
if (input === null || input === void 0) return mergeObjects(base, {});
|
|
305
|
+
const object = structuredClone(input);
|
|
306
|
+
for (const key in base) {
|
|
307
|
+
if (key === "__proto__" || key === "constructor") continue;
|
|
308
|
+
const value = base[key];
|
|
309
|
+
if (value === null || value === void 0) continue;
|
|
310
|
+
if (Array.isArray(value) && Array.isArray(object[key])) object[key] = [...value, ...object[key]];
|
|
311
|
+
else if (typeof value === "object" && typeof object[key] === "object") object[key] = mergeObjects(value, object[key]);
|
|
312
|
+
else object[key] = value;
|
|
939
313
|
}
|
|
940
|
-
|
|
941
|
-
const { request } = useRuntime(scope);
|
|
942
|
-
const { inputs } = useRoute(scope);
|
|
943
|
-
var next = new URL(request?.url ?? window?.location.href);
|
|
944
|
-
if (next.toString() !== url.value?.toString()) {
|
|
945
|
-
const match = radix.match(next.pathname);
|
|
946
|
-
url.value = next;
|
|
947
|
-
inputs.value = match.inputs;
|
|
948
|
-
route.value = match.value;
|
|
949
|
-
navigator.dispatchEvent(new AfterNavigateEvent());
|
|
950
|
-
}
|
|
951
|
-
};
|
|
952
|
-
scope.setContext(ROUTE_CONTEXT, { inputs: createState() });
|
|
953
|
-
scope.setContext(ROUTER_CONTEXT, {
|
|
954
|
-
options,
|
|
955
|
-
navigator,
|
|
956
|
-
url,
|
|
957
|
-
radix,
|
|
958
|
-
route
|
|
959
|
-
});
|
|
960
|
-
fetch$1();
|
|
961
|
-
useEvent(scope, navigator, "navigate", () => startViewTransition("navigate", fetch$1));
|
|
962
|
-
if (isClient()) useEvent(scope, window, "popstate", fetch$1);
|
|
963
|
-
return useRouter(scope);
|
|
964
|
-
}
|
|
965
|
-
function useRouter(scope, context) {
|
|
966
|
-
const { url, route, navigator, options, radix } = scope.getContext(context ?? ROUTER_CONTEXT);
|
|
967
|
-
const navigate = (path) => {
|
|
968
|
-
if (isClient()) {
|
|
969
|
-
if (window.location.pathname != path) window.history.pushState(window.history.state, "", path);
|
|
970
|
-
navigator.dispatchEvent(new NavigateEvent());
|
|
971
|
-
}
|
|
972
|
-
if (isServer()) throw sendRedirect(scope, path);
|
|
973
|
-
};
|
|
974
|
-
const anchorNavigate = (event) => {
|
|
975
|
-
event.preventDefault();
|
|
976
|
-
navigate(event.currentTarget?.getAttribute("href") ?? "/");
|
|
977
|
-
};
|
|
978
|
-
return {
|
|
979
|
-
url,
|
|
980
|
-
route,
|
|
981
|
-
navigator,
|
|
982
|
-
options,
|
|
983
|
-
radix,
|
|
984
|
-
navigate,
|
|
985
|
-
anchorNavigate
|
|
986
|
-
};
|
|
314
|
+
return object;
|
|
987
315
|
}
|
|
988
|
-
const Page = defineComponent({
|
|
989
|
-
name: "x-page",
|
|
990
|
-
setup: ({ scope }) => {
|
|
991
|
-
const { route } = useRouter(scope);
|
|
992
|
-
return () => route.value;
|
|
993
|
-
}
|
|
994
|
-
});
|
|
995
|
-
const ROUTER_CONTEXT = defineContext("ROUTER_CONTEXT");
|
|
996
316
|
|
|
997
317
|
//#endregion
|
|
998
|
-
//#region src/
|
|
999
|
-
function
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
318
|
+
//#region src/app/index.ts
|
|
319
|
+
function createApp(inputConfig) {
|
|
320
|
+
let config = mergeObjects(inputConfig, {
|
|
321
|
+
modules: [],
|
|
322
|
+
sources: {
|
|
323
|
+
assets: {
|
|
324
|
+
match: "**/*",
|
|
325
|
+
entries: ["./public"],
|
|
326
|
+
suffix: "?raw"
|
|
327
|
+
},
|
|
328
|
+
routes: {
|
|
329
|
+
match: "**/*.{js,ts}",
|
|
330
|
+
entries: ["./routes"]
|
|
331
|
+
},
|
|
332
|
+
middlewares: {
|
|
333
|
+
match: "**/*.{js,ts}",
|
|
334
|
+
entries: ["./middlewares"]
|
|
335
|
+
}
|
|
336
|
+
}
|
|
1016
337
|
});
|
|
1017
|
-
|
|
1018
|
-
}
|
|
1019
|
-
function useLocale(scope, context) {
|
|
1020
|
-
const { locale, messages, options } = scope.getContext(context ?? LOCALE_CONTEXT);
|
|
1021
|
-
const $ = (key) => {
|
|
1022
|
-
return () => messages.value?.[key] ?? key;
|
|
1023
|
-
};
|
|
1024
|
-
const $date = (date, options$1) => {
|
|
1025
|
-
const format = new Intl.DateTimeFormat(locale.value, options$1);
|
|
1026
|
-
if (date) return format.format(date);
|
|
1027
|
-
};
|
|
338
|
+
for (const module of config.modules) config = mergeObjects(config, module.config);
|
|
1028
339
|
return {
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
$,
|
|
1033
|
-
$date
|
|
340
|
+
config,
|
|
341
|
+
virtuals: {},
|
|
342
|
+
alias: {}
|
|
1034
343
|
};
|
|
1035
344
|
}
|
|
1036
|
-
const
|
|
345
|
+
const SERVER = "ssr";
|
|
346
|
+
const CLIENT = "client";
|
|
1037
347
|
|
|
1038
348
|
//#endregion
|
|
1039
|
-
export {
|
|
349
|
+
export { CLIENT, PARAMETER, ROUTER_CONTEXT, Radix, Router, SERVER, SERVER_CONTEXT, Scope, StopEvent, WILDCARD, createApp, createServer, defineContext, defineMiddleware, defineRoute, isClient, isFailure, isServer, mergeObjects, mimeType, mimeTypes, parseSchema, sendBadRequest, sendHtml, sendJson, sendRedirect, sendText, sendUnauthorized, setCookie, toRoutePath, useCookies, useQuery, useServer, useSetCookies, useUrl };
|