lilact 0.27.0 → 0.27.2

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.
Files changed (73) hide show
  1. package/dist/lilact.development.js +238 -135
  2. package/dist/lilact.development.js.map +3 -3
  3. package/dist/lilact.development.min.js +57 -57
  4. package/dist/lilact.development.min.js.map +3 -3
  5. package/dist/lilact.production.min.js +57 -57
  6. package/docs/classes/accessories.ErrorBoundary.html +3 -3
  7. package/docs/classes/accessories.Suspense.html +2 -2
  8. package/docs/classes/components.Component.html +3 -3
  9. package/docs/classes/components.HTMLComponent.html +4 -4
  10. package/docs/classes/components.RootComponent.html +5 -5
  11. package/docs/functions/components.cloneComponent.html +1 -1
  12. package/docs/functions/components.createComponent.html +1 -1
  13. package/docs/functions/components.createPortal.html +1 -1
  14. package/docs/functions/components.createRoot.html +1 -1
  15. package/docs/functions/components.memo.html +1 -1
  16. package/docs/functions/components.render.html +1 -1
  17. package/docs/functions/hooks.createContext.html +1 -1
  18. package/docs/functions/hooks.startTransition.html +1 -1
  19. package/docs/functions/hooks.useActionState.html +1 -1
  20. package/docs/functions/hooks.useContext.html +1 -1
  21. package/docs/functions/hooks.useDebugValue.html +1 -1
  22. package/docs/functions/hooks.useDeferredValue.html +1 -1
  23. package/docs/functions/hooks.useEffect.html +1 -1
  24. package/docs/functions/hooks.useId.html +1 -1
  25. package/docs/functions/hooks.useImperativeHandle.html +1 -1
  26. package/docs/functions/hooks.useInsertionEffect.html +1 -1
  27. package/docs/functions/hooks.useLayoutEffect.html +1 -1
  28. package/docs/functions/hooks.useLocalStorage.html +1 -1
  29. package/docs/functions/hooks.useMemo.html +1 -1
  30. package/docs/functions/hooks.useReducer.html +1 -1
  31. package/docs/functions/hooks.useRef.html +1 -1
  32. package/docs/functions/hooks.useTransition.html +1 -1
  33. package/docs/functions/misc.Fragment.html +2 -2
  34. package/docs/functions/misc.Portal.html +2 -2
  35. package/docs/functions/misc.deepEqual.html +1 -1
  36. package/docs/functions/misc.findDOMNode.html +1 -1
  37. package/docs/functions/misc.forwardRef.html +1 -1
  38. package/docs/functions/misc.getComponentByPointer.html +1 -1
  39. package/docs/functions/misc.isAsync.html +1 -1
  40. package/docs/functions/misc.isClass.html +1 -1
  41. package/docs/functions/misc.isEmpty.html +1 -1
  42. package/docs/functions/misc.isError.html +1 -1
  43. package/docs/functions/misc.isThenable.html +1 -1
  44. package/docs/functions/misc.shallowEqual.html +1 -1
  45. package/docs/functions/misc.toBool.html +1 -1
  46. package/docs/functions/run.lazy.html +1 -1
  47. package/docs/functions/run.require.html +1 -1
  48. package/docs/functions/run.run.html +1 -1
  49. package/docs/functions/run.runScripts.html +1 -1
  50. package/docs/functions/timers.timeoutPromise.html +10 -10
  51. package/docs/static/index.html +1 -1
  52. package/docs/static/lilact.development.js +238 -135
  53. package/docs/static/lilact.development.js.map +3 -3
  54. package/docs/static/lilact.development.min.js +57 -57
  55. package/docs/static/lilact.development.min.js.map +3 -3
  56. package/docs/static/lilact.production.min.js +57 -57
  57. package/docs/variables/components.cloneElement.html +1 -1
  58. package/docs/variables/misc.Children.html +10 -10
  59. package/docs/variables/misc.isValidElement.html +1 -1
  60. package/docs/variables/run.required_scripts.html +1 -1
  61. package/examples/index.html +1 -1
  62. package/examples/lilact.development.js +238 -135
  63. package/examples/lilact.development.js.map +3 -3
  64. package/examples/lilact.development.min.js +57 -57
  65. package/examples/lilact.development.min.js.map +3 -3
  66. package/examples/lilact.production.min.js +57 -57
  67. package/package.json +1 -1
  68. package/src/components.jsx +24 -13
  69. package/src/errors.jsx +310 -310
  70. package/src/hooks.jsx +60 -44
  71. package/src/lilact.jsx +4 -2
  72. package/src/misc.jsx +46 -18
  73. package/src/run.jsx +406 -291
package/src/run.jsx CHANGED
@@ -27,11 +27,6 @@
27
27
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
28
 
29
29
  */
30
- /*
31
- Lilact
32
- Copyright (C) 2024-2026 Arash Kazemi <contact.arash.kazemi@gmail.com>
33
- BSD-2-Clause
34
- */
35
30
 
36
31
  import Lilact from "./lilact.jsx";
37
32
  import { isEmpty } from "./misc.jsx";
@@ -39,331 +34,451 @@ import { LAZY } from "./symbols.jsx";
39
34
  import { injectGlobal } from "@emotion/css";
40
35
 
41
36
  function joinPaths(basePath, relativePath) {
42
- const absolute = relativePath.startsWith("/");
43
- const parts = (absolute ? "" : basePath)
44
- .split("/")
45
- .filter(Boolean);
46
-
47
- if (!absolute && !basePath.endsWith("/")) parts.pop();
48
-
49
- for (const part of relativePath.split("/")) {
50
- if (!part || part === ".") continue;
51
- if (part === "..") parts.pop();
52
- else parts.push(part);
53
- }
54
-
55
- return `${absolute ? "/" : ""}${parts.join("/")}`;
37
+ const absolute = relativePath.startsWith("/");
38
+ const parts = (absolute ? "" : basePath)
39
+ .split("/")
40
+ .filter(Boolean);
41
+
42
+ if (!absolute && !basePath.endsWith("/")) {
43
+ parts.pop();
44
+ }
45
+
46
+ for (const part of relativePath.split("/")) {
47
+ if (!part || part === ".") continue;
48
+
49
+ if (part === "..") {
50
+ parts.pop();
51
+ } else {
52
+ parts.push(part);
53
+ }
54
+ }
55
+
56
+ return `${absolute ? "/" : ""}${parts.join("/")}`;
56
57
  }
57
58
 
58
59
  function asError(value, fallback = "Unknown error") {
59
- if (value instanceof Error) return value;
60
- if (value?.error instanceof Error) return value.error;
60
+ if (value instanceof Error) return value;
61
+ if (value?.error instanceof Error) return value.error;
61
62
 
62
- const error = new Error(
63
- value?.message == null ? fallback : String(value.message)
64
- );
63
+ const error = new Error(
64
+ value?.message == null ? fallback : String(value.message)
65
+ );
65
66
 
66
- if (value && typeof value === "object") {
67
- if (value.name) error.name = value.name;
68
- if (value.stack) error.stack = value.stack;
67
+ if (value && typeof value === "object") {
68
+ if (value.name) error.name = value.name;
69
+ if (value.stack) error.stack = value.stack;
69
70
 
70
- for (const key of Object.keys(value)) {
71
- if (!(key in error)) error[key] = value[key];
72
- }
73
- }
71
+ for (const key of Object.keys(value)) {
72
+ if (!(key in error)) {
73
+ error[key] = value[key];
74
+ }
75
+ }
76
+ }
74
77
 
75
- return error;
78
+ return error;
76
79
  }
77
80
 
78
81
  /*
79
- * The first module that catches an error owns its source location.
80
- * Parent modules must never replace it.
81
- */
82
+ * The first module that catches an error owns its source location.
83
+ * Parent modules must never replace it.
84
+ */
82
85
  function markSource(value, path) {
83
- const error = asError(value);
86
+ const error = asError(value);
84
87
 
85
- if (!error.lilact_source) {
86
- error.lilact_source = { path };
87
- }
88
+ if (!error.lilact_source) {
89
+ error.lilact_source = { path };
90
+ }
88
91
 
89
- return error;
92
+ return error;
90
93
  }
91
94
 
92
95
  function report(value, path) {
93
- const error = markSource(value, path);
96
+ const error = markSource(value, path);
94
97
 
95
- if (error.isTraced) return error;
98
+ if (error.isTraced) {
99
+ return error;
100
+ }
96
101
 
97
- if (typeof Lilact.traceError === "function") {
98
- return Lilact.traceError(error, path);
99
- }
102
+ if (typeof Lilact.traceError === "function") {
103
+ return Lilact.traceError(error, path);
104
+ }
100
105
 
101
- Lilact.error = error;
102
- return error;
106
+ Lilact.error = error;
107
+ return error;
103
108
  }
104
109
 
105
110
  export const required_scripts = {};
106
111
 
107
- export function run(
108
- jsx,
109
- path = `InlineJSX-${++Lilact.eval_num}`,
110
- {
111
- isInline = true,
112
- isModule = true,
113
- } = {}
114
- ) {
112
+ function createModule(path, {
113
+ code = "",
114
+ isInline = false,
115
+ isModule = true,
116
+ } = {}) {
117
+ const module = {
118
+ path,
119
+ code: String(code),
120
+ mappings: [],
121
+ exports: {},
115
122
 
123
+ isInline,
124
+ isModule,
116
125
 
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
- }
126
+ // True only after the module has been successfully evaluated.
127
+ loaded: false,
148
128
 
149
- if (typeof Lilact.scanBlockLabels === "function") {
150
- Lilact.scanBlockLabels(processed, path);
151
- }
129
+ // The promise for the request currently loading this resource.
130
+ // This is deliberately stored on the module to deduplicate requests.
131
+ request: undefined,
152
132
 
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
- }
181
- }
182
-
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
- }
133
+ error: undefined,
134
+ };
222
135
 
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();
136
+ required_scripts[path] = module;
137
+ return module;
138
+ }
290
139
 
291
- try {
292
- request.open("GET", path, false);
293
- request.send(null);
294
- } catch (value) {
295
- throw report(value, path);
296
- }
140
+ export function run(
141
+ jsx,
142
+ path = `InlineJSX-${++Lilact.eval_num}`,
143
+ {
144
+ isInline = true,
145
+ isModule = true,
146
+ } = {}
147
+ ) {
148
+ let module = required_scripts[path];
149
+
150
+ /*
151
+ * A module may already have been created by require() while its source is
152
+ * being fetched. Reuse that module so the request and its exports remain
153
+ * associated with the same entry.
154
+ */
155
+ if (!module) {
156
+ module = createModule(path, {
157
+ code: jsx,
158
+ isInline,
159
+ isModule,
160
+ });
161
+ } else {
162
+ /*
163
+ * Preserve module.request. It may represent the request that led to this
164
+ * run() call, and clearing it here would make retry/deduplication logic
165
+ * fragile.
166
+ */
167
+ module.path = path;
168
+ module.code = String(jsx);
169
+ module.mappings = [];
170
+ module.exports = {};
171
+ module.isInline = isInline;
172
+ module.isModule = isModule;
173
+ module.loaded = false;
174
+ module.error = undefined;
175
+ }
176
+
177
+ let processed;
178
+
179
+ try {
180
+ processed = Lilact.transpileJSX(String(jsx), {
181
+ path,
182
+ mappings: module.mappings,
183
+ factory: "createComponent",
184
+ appendSourcemap: false,
185
+ injectTraceLabels: true,
186
+ produceCJS: true,
187
+ blocks_info: Lilact.blocks_info,
188
+ });
189
+ } catch (value) {
190
+ const error = asError(value);
191
+
192
+ error.fileName ??= path;
193
+ error.sourcePhase = "transpile";
194
+
195
+ module.error = error;
196
+ Lilact.error = error;
197
+
198
+ throw error;
199
+ }
200
+
201
+ if (typeof Lilact.scanBlockLabels === "function") {
202
+ Lilact.scanBlockLabels(processed, path);
203
+ }
204
+
205
+ /*
206
+ * sourceURL helps when the browser includes eval locations in its stack.
207
+ * It is not used as the authoritative source; the catch block below is.
208
+ */
209
+ processed += `\n//# sourceURL=eval:/${path}`;
210
+
211
+ try {
212
+ globalThis.Lilact = Lilact;
213
+ globalThis.createComponent = Lilact.createComponent;
214
+ globalThis.Fragment = Lilact.Fragment;
215
+
216
+ const result = eval(processed);
217
+
218
+ module.loaded = true;
219
+
220
+ return isEmpty(module.exports)
221
+ ? result
222
+ : module.exports;
223
+ } catch (value) {
224
+ /*
225
+ * This catch executes in the module whose eval failed, including
226
+ * generated-JavaScript syntax errors. Therefore path is authoritative.
227
+ */
228
+ const error = report(value, path);
229
+
230
+ error.sourcePhase ??= "runtime";
231
+ module.error = error;
232
+
233
+ throw error;
234
+ }
235
+ }
297
236
 
298
- if (request.status >= 200 && request.status < 300) {
299
- if (path.endsWith(".css")) {
300
- injectGlobal(request.responseText);
301
- return;
302
- }
237
+ function getOrCreateModule(path, options = {}) {
238
+ return required_scripts[path] || createModule(path, options);
239
+ }
303
240
 
304
- return run(request.responseText, path, {
305
- isInline: false,
306
- isModule: true,
307
- });
308
- }
241
+ function loadAsyncResource(path, module) {
242
+ let source;
243
+
244
+ try {
245
+ const resolved = Lilact.resolver?.(path);
246
+
247
+ if (resolved == null) {
248
+ if (module.code && !module.loaded) {
249
+ source = Promise.resolve(module.code);
250
+ } else {
251
+ source = fetch(path).then(response => {
252
+ if (!response.ok) {
253
+ throw report(
254
+ new Error(
255
+ `Unable to load ${path}: HTTP ${response.status}`
256
+ ),
257
+ path
258
+ );
259
+ }
260
+
261
+ return response.text();
262
+ });
263
+ }
264
+ } else {
265
+ source = Promise.resolve(resolved);
266
+ }
267
+ } catch (value) {
268
+ source = Promise.reject(report(value, path));
269
+ }
270
+
271
+ /*
272
+ * Always convert the source to a promise. The promise is assigned to the
273
+ * module before any caller can make another require() call.
274
+ */
275
+ let request;
276
+
277
+ request = Promise.resolve(source)
278
+ .then(sourceText => {
279
+ module.code = String(sourceText);
280
+
281
+ if (path.endsWith(".css")) {
282
+ injectGlobal(module.code);
283
+ module.loaded = true;
284
+ return undefined;
285
+ }
286
+
287
+ return run(module.code, path, {
288
+ isInline: false,
289
+ isModule: true,
290
+ });
291
+ })
292
+ .then(result => result?.default ?? result)
293
+ .catch(error => {
294
+ module.error = report(error, path);
295
+ throw module.error;
296
+ })
297
+ .finally(() => {
298
+ /*
299
+ * Do not remove a newer request accidentally if a future forceUpdate
300
+ * request replaced this one.
301
+ */
302
+ if (module.request === request) {
303
+ module.request = undefined;
304
+ }
305
+ });
306
+
307
+ module.request = request;
308
+ return request;
309
+ }
309
310
 
310
- throw report(
311
- new Error(`Unable to load ${path}: HTTP ${request.status || 0}`),
312
- path
313
- );
311
+ export function require(path) {
312
+ let options = {};
313
+
314
+ if (
315
+ arguments.length === 2 &&
316
+ arguments[1] &&
317
+ typeof arguments[1] === "object"
318
+ ) {
319
+ options = arguments[1];
320
+ }
321
+
322
+ if (Lilact.importObjectPaths?.[path]) {
323
+ return Lilact.importObjectPaths[path];
324
+ }
325
+
326
+ if (options.requirer?.path) {
327
+ path = joinPaths(options.requirer.path, path);
328
+ }
329
+
330
+ const loadAsync =
331
+ Boolean(Lilact[LAZY]) ||
332
+ Boolean(options.isLazy);
333
+
334
+
335
+ const module = getOrCreateModule(path, {
336
+ isInline: false,
337
+ isModule: true,
338
+ });
339
+
340
+ /*
341
+ * A completed module can be returned synchronously unless the caller
342
+ * explicitly requests lazy loading.
343
+ */
344
+ if (module.loaded && !options.forceUpdate && !loadAsync) {
345
+ return module.exports;
346
+ }
347
+
348
+ if (path.startsWith("#")) {
349
+ const element = document.getElementById(path.slice(1));
350
+
351
+ if (!element) {
352
+ throw report(
353
+ new Error(`Required element not found (${path})`),
354
+ path
355
+ );
356
+ }
357
+
358
+ return run(element.textContent || "", path);
359
+ }
360
+
361
+ if (loadAsync) {
362
+ Lilact[LAZY] = false;
363
+
364
+ /*
365
+ * Every subsequent lazy require() receives the first request promise.
366
+ * This applies even when the module is still being fetched and even when
367
+ * the first caller used forceUpdate.
368
+ */
369
+ if (module.request) {
370
+ return module.request;
371
+ }
372
+
373
+ return loadAsyncResource(path, module);
374
+ }
375
+
376
+ const resolved = Lilact.resolver?.(path);
377
+
378
+ if (resolved != null) {
379
+ if (path.endsWith(".css")) {
380
+ injectGlobal(String(resolved));
381
+ module.code = String(resolved);
382
+ module.loaded = true;
383
+ return undefined;
384
+ }
385
+
386
+ return run(String(resolved), path, {
387
+ isInline: false,
388
+ isModule: true,
389
+ });
390
+ }
391
+
392
+ const request = new XMLHttpRequest();
393
+
394
+ try {
395
+ request.open("GET", path, false);
396
+ request.send(null);
397
+ } catch (value) {
398
+ throw report(value, path);
399
+ }
400
+
401
+ if (request.status >= 200 && request.status < 300) {
402
+ if (path.endsWith(".css")) {
403
+ module.code = request.responseText;
404
+ injectGlobal(module.code);
405
+ module.loaded = true;
406
+ return undefined;
407
+ }
408
+
409
+ return run(request.responseText, path, {
410
+ isInline: false,
411
+ isModule: true,
412
+ });
413
+ }
414
+
415
+ throw report(
416
+ new Error(
417
+ `Unable to load ${path}: HTTP ${request.status || 0}`
418
+ ),
419
+ path
420
+ );
314
421
  }
315
422
 
316
423
  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;
424
+ let status = "pending";
425
+ let result;
426
+
427
+ Lilact[LAZY] = true;
428
+
429
+ try {
430
+ result = factory();
431
+ } catch (error) {
432
+ status = "error";
433
+ result = error;
434
+ }
435
+
436
+ if (Lilact.isThenable(result)) {
437
+ result.then(
438
+ value => {
439
+ status = "success";
440
+ result = value;
441
+ },
442
+ error => {
443
+ status = "error";
444
+ result = error;
445
+ }
446
+ );
447
+ } else if (status !== "error") {
448
+ status = "success";
449
+ }
450
+
451
+ function LazyComponent(props) {
452
+ if (status === "pending") {
453
+ throw result;
454
+ }
455
+
456
+ if (status === "error") {
457
+ throw result;
458
+ }
459
+
460
+ const Component = result;
461
+ return <Component {...props} />;
462
+ }
463
+
464
+ return LazyComponent;
353
465
  }
354
466
 
355
467
  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
- }));
468
+ return Array.from(
469
+ document.querySelectorAll('script[type="text/jsx"]')
470
+ ).map(element => ({
471
+ src: element.getAttribute("src"),
472
+ content: element.textContent || "",
473
+ }));
362
474
  }
363
475
 
364
- export function runScripts() {
476
+ export async function runScripts() {
365
477
  for (const script of scriptTags()) {
366
- if (script.src) require(script.src);
367
- if (script.content) run(script.content);
478
+ if (script.src) {
479
+ await require(script.src);
480
+ } else if (script.content) {
481
+ run(script.content);
482
+ }
368
483
  }
369
- }
484
+ }