lilact 0.26.15 → 0.27.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/lilact.development.js +459 -324
- package/dist/lilact.development.js.map +3 -3
- package/dist/lilact.development.min.js +63 -54
- package/dist/lilact.development.min.js.map +3 -3
- package/dist/lilact.production.min.js +63 -54
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/accessories.ErrorBoundary.html +8 -8
- package/docs/classes/accessories.Suspense.html +7 -7
- package/docs/classes/components.Component.html +11 -11
- package/docs/classes/components.HTMLComponent.html +11 -11
- package/docs/classes/components.RootComponent.html +11 -11
- package/docs/functions/components.cloneComponent.html +1 -1
- package/docs/functions/components.createComponent.html +1 -1
- package/docs/functions/components.createPortal.html +1 -1
- package/docs/functions/components.createRoot.html +1 -1
- package/docs/functions/components.memo.html +1 -1
- package/docs/functions/components.render.html +1 -1
- package/docs/functions/errors.globalErrorHandler.html +1 -8
- package/docs/functions/errors.scanBlockLabels.html +1 -0
- package/docs/functions/errors.traceError.html +1 -7
- package/docs/functions/hooks.startTransition.html +1 -1
- package/docs/functions/hooks.useActionState.html +1 -1
- package/docs/functions/hooks.useDebugValue.html +1 -1
- package/docs/functions/hooks.useDeferredValue.html +1 -1
- package/docs/functions/hooks.useEffect.html +1 -1
- package/docs/functions/hooks.useImperativeHandle.html +1 -1
- package/docs/functions/hooks.useInsertionEffect.html +1 -1
- package/docs/functions/hooks.useMemo.html +1 -1
- package/docs/functions/hooks.useReducer.html +1 -1
- package/docs/functions/run.lazy.html +1 -13
- package/docs/functions/run.require.html +1 -9
- package/docs/functions/run.run.html +1 -5
- package/docs/functions/run.runScripts.html +1 -7
- package/docs/functions/timers.timeoutPromise.html +3 -3
- package/docs/modules/errors.html +1 -1
- package/docs/modules/run.html +1 -1
- package/docs/static/index.html +1 -1
- package/docs/static/lilact.development.js +459 -324
- package/docs/static/lilact.development.js.map +3 -3
- package/docs/static/lilact.development.min.js +63 -54
- package/docs/static/lilact.development.min.js.map +3 -3
- package/docs/static/lilact.production.min.js +63 -54
- package/docs/variables/components.cloneElement.html +1 -1
- package/docs/variables/errors.blocks_info.html +1 -0
- package/docs/variables/errors.error.html +1 -0
- package/docs/variables/run.required_scripts.html +1 -0
- package/examples/index.html +1 -1
- package/examples/lilact.development.js +459 -324
- package/examples/lilact.development.js.map +3 -3
- package/examples/lilact.development.min.js +63 -54
- package/examples/lilact.development.min.js.map +3 -3
- package/examples/lilact.production.min.js +63 -54
- package/package.json +1 -1
- package/src/components.jsx +10 -4
- package/src/errors.jsx +344 -245
- package/src/expscan.js +1 -1
- package/src/hooks.jsx +8 -5
- package/src/jsx.js +16 -16
- package/src/lilact.jsx +2 -2
- package/src/run.jsx +313 -267
package/src/run.jsx
CHANGED
|
@@ -27,297 +27,343 @@
|
|
|
27
27
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
28
28
|
|
|
29
29
|
*/
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
/*
|
|
31
|
+
Lilact
|
|
32
|
+
Copyright (C) 2024-2026 Arash Kazemi <contact.arash.kazemi@gmail.com>
|
|
33
|
+
BSD-2-Clause
|
|
34
|
+
*/
|
|
32
35
|
|
|
33
|
-
import
|
|
34
|
-
import {
|
|
36
|
+
import Lilact from "./lilact.jsx";
|
|
37
|
+
import { isEmpty } from "./misc.jsx";
|
|
38
|
+
import { LAZY } from "./symbols.jsx";
|
|
39
|
+
import { injectGlobal } from "@emotion/css";
|
|
35
40
|
|
|
36
41
|
function joinPaths(basePath, relativePath) {
|
|
37
|
-
|
|
38
|
-
|
|
42
|
+
const absolute = relativePath.startsWith("/");
|
|
43
|
+
const parts = (absolute ? "" : basePath)
|
|
44
|
+
.split("/")
|
|
45
|
+
.filter(Boolean);
|
|
39
46
|
|
|
40
|
-
|
|
41
|
-
for (const p of parts) stack.push(p);
|
|
47
|
+
if (!absolute && !basePath.endsWith("/")) parts.pop();
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
for (const part of relativePath.split("/")) {
|
|
50
|
+
if (!part || part === ".") continue;
|
|
51
|
+
if (part === "..") parts.pop();
|
|
52
|
+
else parts.push(part);
|
|
53
|
+
}
|
|
44
54
|
|
|
45
|
-
|
|
55
|
+
return `${absolute ? "/" : ""}${parts.join("/")}`;
|
|
56
|
+
}
|
|
46
57
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (stack.length > 0) stack.pop();
|
|
51
|
-
} else {
|
|
52
|
-
stack.push(p);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
58
|
+
function asError(value, fallback = "Unknown error") {
|
|
59
|
+
if (value instanceof Error) return value;
|
|
60
|
+
if (value?.error instanceof Error) return value.error;
|
|
55
61
|
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
const error = new Error(
|
|
63
|
+
value?.message == null ? fallback : String(value.message)
|
|
64
|
+
);
|
|
58
65
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
if (value && typeof value === "object") {
|
|
67
|
+
if (value.name) error.name = value.name;
|
|
68
|
+
if (value.stack) error.stack = value.stack;
|
|
62
69
|
|
|
63
|
-
|
|
64
|
-
|
|
70
|
+
for (const key of Object.keys(value)) {
|
|
71
|
+
if (!(key in error)) error[key] = value[key];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
65
74
|
|
|
75
|
+
return error;
|
|
76
|
+
}
|
|
66
77
|
|
|
67
|
-
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* @param jsx - The code to run.
|
|
71
|
-
* @param path - The optional path to be used in reporting errors.
|
|
72
|
-
*
|
|
73
|
-
* @returns An array representation of the children.
|
|
78
|
+
/*
|
|
79
|
+
* The first module that catches an error owns its source location.
|
|
80
|
+
* Parent modules must never replace it.
|
|
74
81
|
*/
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const mappings = [];
|
|
78
|
-
const module = {
|
|
79
|
-
mappings,
|
|
80
|
-
isInline,
|
|
81
|
-
path,
|
|
82
|
-
code: jsx,
|
|
83
|
-
exports: {}
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
let processed;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
required_scripts[path] = module;
|
|
90
|
-
|
|
91
|
-
try {
|
|
92
|
-
processed = Lilact.transpileJSX( jsx,
|
|
93
|
-
{
|
|
94
|
-
path,
|
|
95
|
-
mappings,
|
|
96
|
-
factory: "createComponent",
|
|
97
|
-
appendSourcemap: false,
|
|
98
|
-
|
|
99
|
-
injectTraceLabels: true,
|
|
100
|
-
produceCJS: true,
|
|
101
|
-
|
|
102
|
-
blocks_info: Lilact.blocks_info,
|
|
103
|
-
} );
|
|
104
|
-
}
|
|
105
|
-
catch(e) {
|
|
106
|
-
//e = Lilact.traceError(e);
|
|
107
|
-
Lilact.error = e;
|
|
108
|
-
throw e;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if(DEBUG) {
|
|
112
|
-
required_scripts[path].processed = processed;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
processed += "\n//# sourceURL=eval:/" + path;
|
|
116
|
-
|
|
117
|
-
// todo: this seems to be only useful in safari, should be assessed later
|
|
118
|
-
Lilact.scanBlockLabels(processed, path);
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
globalThis.Lilact = Lilact;
|
|
122
|
-
globalThis.createComponent = Lilact.createComponent;
|
|
123
|
-
globalThis.Fragment = Lilact.Fragment;
|
|
124
|
-
|
|
125
|
-
//const res = new Function( "module", processed )(module);
|
|
126
|
-
const res = eval(processed);
|
|
127
|
-
|
|
128
|
-
if( !isEmpty(module.exports) ) return module.exports;
|
|
129
|
-
return res;
|
|
130
|
-
}
|
|
131
|
-
catch(e) {
|
|
132
|
-
e = Lilact.traceError(e, path);
|
|
133
|
-
throw e;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
82
|
+
function markSource(value, path) {
|
|
83
|
+
const error = asError(value);
|
|
136
84
|
|
|
85
|
+
if (!error.lilact_source) {
|
|
86
|
+
error.lilact_source = { path };
|
|
87
|
+
}
|
|
137
88
|
|
|
138
|
-
|
|
139
|
-
* Loads a jsx script from a path. `require` loads synchronously, as it is expected to be loaded on the next instruction.
|
|
140
|
-
*
|
|
141
|
-
* If the path is in the format #id, it will query the document for a script element with the given
|
|
142
|
-
* id and run its contents.
|
|
143
|
-
*
|
|
144
|
-
* If require is called inside the function given to lazy, it will run async. See `lazy`.
|
|
145
|
-
*
|
|
146
|
-
* All required scripts can access Lilact namespace as a global object.
|
|
147
|
-
*
|
|
148
|
-
* @param path - The path to the required file. Must be either absolute path or relative to the current
|
|
149
|
-
* module or document’s URL (the page/location that initiated the request).
|
|
150
|
-
*
|
|
151
|
-
* @returns An array representation of the children.
|
|
152
|
-
*/
|
|
153
|
-
export function require(path)
|
|
154
|
-
{
|
|
155
|
-
let forceUpdate, checkExport, requirer, isLazy;
|
|
156
|
-
|
|
157
|
-
// note: instead of named props, just to bypass typedoc.
|
|
158
|
-
if(arguments.length===2 && typeof(arguments[1]==='object')) {
|
|
159
|
-
forceUpdate = arguments[1]?.forceUpdate;
|
|
160
|
-
checkExport = arguments[1]?.checkExport;
|
|
161
|
-
requirer = arguments[1]?.requirer;
|
|
162
|
-
isLazy = arguments[1]?.isLazy;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if(Lilact.importObjectPaths?.[path]) return Lilact.importObjectPaths[path];
|
|
166
|
-
if(required_scripts[path] && !forceUpdate) return required_scripts[path].exports;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if(path[0]==='#') {
|
|
170
|
-
const el = document.getElementById(path);
|
|
171
|
-
|
|
172
|
-
if(el) {
|
|
173
|
-
return run(el.innerText, path);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
throw new Error(`Required element not found (${path})`);
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
if(requirer && requirer.path) {
|
|
180
|
-
path = joinPaths(requirer.path, path);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
if(Lilact?.[LAZY] || isLazy) {
|
|
184
|
-
Lilact[LAZY]=false;
|
|
185
|
-
|
|
186
|
-
let p = Lilact.resolver?.(path);
|
|
187
|
-
|
|
188
|
-
if(p) {
|
|
189
|
-
p = Promise.resolve(p);
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
p = fetch(path).then(res => {
|
|
193
|
-
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
194
|
-
return res.text();
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
return p.then(res => {
|
|
198
|
-
if(path.endsWith(".css")) {
|
|
199
|
-
injectGlobal(res);
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
res = run(res, path, {isInline:false});
|
|
203
|
-
return res?.default ?? res;
|
|
204
|
-
})
|
|
205
|
-
.catch(err => {
|
|
206
|
-
throw err;
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
const p = Lilact.resolver?.(path);
|
|
211
|
-
if(p) {
|
|
212
|
-
if(path.endsWith(".css")) {
|
|
213
|
-
injectGlobal(p);
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
return run(p, path, {isInline:false});
|
|
217
|
-
}
|
|
218
|
-
else {
|
|
219
|
-
const request = new XMLHttpRequest();
|
|
220
|
-
request.open("GET", path, false);
|
|
221
|
-
request.send(null);
|
|
222
|
-
if (request.status === 200) {
|
|
223
|
-
if(path.endsWith(".css")) {
|
|
224
|
-
injectGlobal(res);
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
return run(request.responseText, path, {isInline:false});
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
throw new Error(`Required resource not found (${path})`);
|
|
89
|
+
return error;
|
|
234
90
|
}
|
|
235
91
|
|
|
92
|
+
function report(value, path) {
|
|
93
|
+
const error = markSource(value, path);
|
|
236
94
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
* ```
|
|
246
|
-
* const StopWatch = lazy( () => require('./stopwatch.jsx') );
|
|
247
|
-
* ```
|
|
248
|
-
*
|
|
249
|
-
* @param factory - A function with **no arguments** that returns a `Promise`.
|
|
250
|
-
* The promise must resolve to a module whose module.exports.default is a Lilact component
|
|
251
|
-
* or otherwise it will be whatever the module.exports is set to.
|
|
252
|
-
*
|
|
253
|
-
* @returns A Lilact component that should be rendered inside a `Suspense` boundary.
|
|
254
|
-
*/
|
|
255
|
-
export function lazy(factory) {
|
|
256
|
-
let status = "pending"; // pending | success | error
|
|
257
|
-
let result; // component | error
|
|
258
|
-
|
|
259
|
-
Lilact[LAZY] = true;
|
|
260
|
-
result = factory();
|
|
261
|
-
|
|
262
|
-
if(Lilact.isThenable(result)) {
|
|
263
|
-
result.then(
|
|
264
|
-
(mod) => {
|
|
265
|
-
status = "success";
|
|
266
|
-
result = mod;
|
|
267
|
-
return result;
|
|
268
|
-
},
|
|
269
|
-
(err) => {
|
|
270
|
-
status = "error";
|
|
271
|
-
result = err;
|
|
272
|
-
throw err;
|
|
273
|
-
}
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
status = "success";
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
function LazyComponent(props) {
|
|
281
|
-
if (status === "pending") throw result;
|
|
282
|
-
if (status === "error") throw result;
|
|
283
|
-
const Component = result;
|
|
284
|
-
return <Component {...props} />;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
return LazyComponent;
|
|
95
|
+
if (error.isTraced) return error;
|
|
96
|
+
|
|
97
|
+
if (typeof Lilact.traceError === "function") {
|
|
98
|
+
return Lilact.traceError(error, path);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
Lilact.error = error;
|
|
102
|
+
return error;
|
|
288
103
|
}
|
|
289
104
|
|
|
290
|
-
|
|
291
|
-
const scripts = Array.from(
|
|
292
|
-
document.querySelectorAll('script[type="text/jsx"]')
|
|
293
|
-
);
|
|
105
|
+
export const required_scripts = {};
|
|
294
106
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
107
|
+
export function run(
|
|
108
|
+
jsx,
|
|
109
|
+
path = `InlineJSX-${++Lilact.eval_num}`,
|
|
110
|
+
{
|
|
111
|
+
isInline = true,
|
|
112
|
+
isModule = true,
|
|
113
|
+
} = {}
|
|
114
|
+
) {
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
const module = {
|
|
118
|
+
path,
|
|
119
|
+
code: String(jsx),
|
|
120
|
+
mappings: [],
|
|
121
|
+
exports: {},
|
|
122
|
+
isInline,
|
|
123
|
+
isModule,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
required_scripts[path] = module;
|
|
127
|
+
|
|
128
|
+
let processed;
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
processed = Lilact.transpileJSX(String(jsx), {
|
|
132
|
+
path,
|
|
133
|
+
mappings: module.mappings,
|
|
134
|
+
factory: "createComponent",
|
|
135
|
+
appendSourcemap: false,
|
|
136
|
+
injectTraceLabels: true,
|
|
137
|
+
produceCJS: true,
|
|
138
|
+
blocks_info: Lilact.blocks_info,
|
|
139
|
+
});
|
|
140
|
+
} catch (value) {
|
|
141
|
+
const error = asError(value);
|
|
142
|
+
error.fileName ??= path;
|
|
143
|
+
error.sourcePhase = "transpile";
|
|
144
|
+
module.error = error;
|
|
145
|
+
Lilact.error = error;
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (typeof Lilact.scanBlockLabels === "function") {
|
|
150
|
+
Lilact.scanBlockLabels(processed, path);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/*
|
|
154
|
+
* sourceURL helps when the browser includes eval locations in its stack.
|
|
155
|
+
* It is not used as the authoritative source; the catch block below is.
|
|
156
|
+
*/
|
|
157
|
+
processed += `\n//# sourceURL=eval:/${path}`;
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
globalThis.Lilact = Lilact;
|
|
161
|
+
globalThis.createComponent = Lilact.createComponent;
|
|
162
|
+
globalThis.Fragment = Lilact.Fragment;
|
|
163
|
+
|
|
164
|
+
const result = eval(processed);
|
|
165
|
+
|
|
166
|
+
return isEmpty(module.exports)
|
|
167
|
+
? result
|
|
168
|
+
: module.exports;
|
|
169
|
+
} catch (value) {
|
|
170
|
+
/*
|
|
171
|
+
* This catch executes in the module whose eval failed, including
|
|
172
|
+
* generated-JavaScript syntax errors. Therefore path is authoritative.
|
|
173
|
+
*/
|
|
174
|
+
const error = report(value, path);
|
|
175
|
+
|
|
176
|
+
error.sourcePhase ??= "runtime";
|
|
177
|
+
module.error = error;
|
|
178
|
+
|
|
179
|
+
throw error;
|
|
180
|
+
}
|
|
299
181
|
}
|
|
300
182
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
183
|
+
export function require(path) {
|
|
184
|
+
let options = {};
|
|
185
|
+
|
|
186
|
+
if (
|
|
187
|
+
arguments.length === 2 &&
|
|
188
|
+
arguments[1] &&
|
|
189
|
+
typeof arguments[1] === "object"
|
|
190
|
+
) {
|
|
191
|
+
options = arguments[1];
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
if (Lilact.importObjectPaths?.[path]) {
|
|
196
|
+
return Lilact.importObjectPaths[path];
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
const loadAsync =
|
|
201
|
+
Boolean(Lilact[LAZY]) ||
|
|
202
|
+
Boolean(options.isLazy);
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
if (options.requirer?.path) {
|
|
206
|
+
path = joinPaths(options.requirer.path, path);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (required_scripts[path] && !options.forceUpdate && !loadAsync) {
|
|
210
|
+
return required_scripts[path].exports;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (path.startsWith("#")) {
|
|
214
|
+
const element = document.getElementById(path.slice(1));
|
|
215
|
+
|
|
216
|
+
if (!element) {
|
|
217
|
+
throw report(
|
|
218
|
+
new Error(`Required element not found (${path})`),
|
|
219
|
+
path
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return run(element.textContent || "", path);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (loadAsync) {
|
|
227
|
+
Lilact[LAZY] = false;
|
|
228
|
+
|
|
229
|
+
let request = Lilact.resolver?.(path);
|
|
230
|
+
|
|
231
|
+
if (request == null) {
|
|
232
|
+
|
|
233
|
+
if (required_scripts[path] && !options.forceUpdate) {
|
|
234
|
+
request = Promise.resolve(required_scripts[path].code);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
request = fetch(path).then(response => {
|
|
238
|
+
if (!response.ok) {
|
|
239
|
+
throw report(
|
|
240
|
+
new Error(
|
|
241
|
+
`Unable to load ${path}: HTTP ${response.status}`
|
|
242
|
+
),
|
|
243
|
+
path
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return response.text();
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
request = Promise.resolve(request);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return request
|
|
256
|
+
.then(source => {
|
|
257
|
+
if (path.endsWith(".css")) {
|
|
258
|
+
injectGlobal(String(source));
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return run(String(source), path, {
|
|
263
|
+
isInline: false,
|
|
264
|
+
isModule: true,
|
|
265
|
+
});
|
|
266
|
+
})
|
|
267
|
+
.then(result =>
|
|
268
|
+
result?.default ?? result
|
|
269
|
+
)
|
|
270
|
+
.catch(error => {
|
|
271
|
+
throw report(error, path);
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const resolved = Lilact.resolver?.(path);
|
|
276
|
+
|
|
277
|
+
if (resolved != null) {
|
|
278
|
+
if (path.endsWith(".css")) {
|
|
279
|
+
injectGlobal(String(resolved));
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return run(String(resolved), path, {
|
|
284
|
+
isInline: false,
|
|
285
|
+
isModule: true,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const request = new XMLHttpRequest();
|
|
290
|
+
|
|
291
|
+
try {
|
|
292
|
+
request.open("GET", path, false);
|
|
293
|
+
request.send(null);
|
|
294
|
+
} catch (value) {
|
|
295
|
+
throw report(value, path);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (request.status >= 200 && request.status < 300) {
|
|
299
|
+
if (path.endsWith(".css")) {
|
|
300
|
+
injectGlobal(request.responseText);
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return run(request.responseText, path, {
|
|
305
|
+
isInline: false,
|
|
306
|
+
isModule: true,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
throw report(
|
|
311
|
+
new Error(`Unable to load ${path}: HTTP ${request.status || 0}`),
|
|
312
|
+
path
|
|
313
|
+
);
|
|
314
|
+
}
|
|
313
315
|
|
|
314
|
-
export function
|
|
315
|
-
|
|
316
|
-
|
|
316
|
+
export function lazy(factory) {
|
|
317
|
+
let status = "pending";
|
|
318
|
+
let result;
|
|
319
|
+
|
|
320
|
+
Lilact[LAZY] = true;
|
|
321
|
+
|
|
322
|
+
try {
|
|
323
|
+
result = factory();
|
|
324
|
+
} catch (error) {
|
|
325
|
+
status = "error";
|
|
326
|
+
result = error;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (Lilact.isThenable(result)) {
|
|
330
|
+
result.then(
|
|
331
|
+
value => {
|
|
332
|
+
status = "success";
|
|
333
|
+
result = value;
|
|
334
|
+
},
|
|
335
|
+
error => {
|
|
336
|
+
status = "error";
|
|
337
|
+
result = error;
|
|
338
|
+
}
|
|
339
|
+
);
|
|
340
|
+
} else if (status !== "error") {
|
|
341
|
+
status = "success";
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function LazyComponent(props) {
|
|
345
|
+
if (status === "pending") throw result;
|
|
346
|
+
if (status === "error") throw result;
|
|
347
|
+
|
|
348
|
+
const Component = result;
|
|
349
|
+
return <Component {...props} />;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return LazyComponent;
|
|
353
|
+
}
|
|
317
354
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
355
|
+
function scriptTags() {
|
|
356
|
+
return Array.from(
|
|
357
|
+
document.querySelectorAll('script[type="text/jsx"]')
|
|
358
|
+
).map(element => ({
|
|
359
|
+
src: element.getAttribute("src"),
|
|
360
|
+
content: element.textContent || "",
|
|
361
|
+
}));
|
|
322
362
|
}
|
|
323
363
|
|
|
364
|
+
export function runScripts() {
|
|
365
|
+
for (const script of scriptTags()) {
|
|
366
|
+
if (script.src) require(script.src);
|
|
367
|
+
if (script.content) run(script.content);
|
|
368
|
+
}
|
|
369
|
+
}
|