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/package.json
CHANGED
package/src/components.jsx
CHANGED
|
@@ -371,7 +371,7 @@ if(DEBUG) {
|
|
|
371
371
|
if(this.outlet!==undefined) {
|
|
372
372
|
for(let c of this.outlet) {
|
|
373
373
|
if(c.cleanup) {
|
|
374
|
-
c.cleanup();
|
|
374
|
+
promises.push(c.cleanup());
|
|
375
375
|
}
|
|
376
376
|
}
|
|
377
377
|
}
|
|
@@ -379,7 +379,7 @@ if(DEBUG) {
|
|
|
379
379
|
if(this.props?.children!==undefined) {
|
|
380
380
|
for(let c of this.props.children) {
|
|
381
381
|
if(c.cleanup) {
|
|
382
|
-
c.cleanup();
|
|
382
|
+
promises.push(c.cleanup());
|
|
383
383
|
}
|
|
384
384
|
}
|
|
385
385
|
}
|
|
@@ -387,10 +387,12 @@ if(DEBUG) {
|
|
|
387
387
|
if(this.hooks!==undefined) {
|
|
388
388
|
for(let h of this.hooks) {
|
|
389
389
|
if(h.cleanup) {
|
|
390
|
-
h.cleanup();
|
|
390
|
+
promises.push(h.cleanup());
|
|
391
391
|
}
|
|
392
392
|
}
|
|
393
393
|
}
|
|
394
|
+
|
|
395
|
+
await Promise.all(promises);
|
|
394
396
|
}
|
|
395
397
|
|
|
396
398
|
catch(e) {
|
|
@@ -400,6 +402,9 @@ if(DEBUG) {
|
|
|
400
402
|
|
|
401
403
|
updateElementProps(patch, force=false)
|
|
402
404
|
{
|
|
405
|
+
// note: string.slice(0,undefined) returns the complete string. that's why
|
|
406
|
+
// the slices are correct even if maxLength is not set.
|
|
407
|
+
|
|
403
408
|
if(this.entity==="input") {
|
|
404
409
|
if(!patch?.type) patch.type = 'text';
|
|
405
410
|
if(patch.type!==this.element.type) {
|
|
@@ -432,7 +437,7 @@ if(DEBUG) {
|
|
|
432
437
|
this.event_detachers[al]();
|
|
433
438
|
}
|
|
434
439
|
else {
|
|
435
|
-
this.element.
|
|
440
|
+
this.element.removeAttribute(a);
|
|
436
441
|
}
|
|
437
442
|
}
|
|
438
443
|
}
|
|
@@ -485,6 +490,7 @@ if(DEBUG) {
|
|
|
485
490
|
}
|
|
486
491
|
else if(boolean_html_attributes_set.has(a)) { // not lower cased(al), as it is set as a js property
|
|
487
492
|
this.element[a] = toBool(patch[a]);
|
|
493
|
+
if(!this.element[a]) this.element.removeAttribute(a);
|
|
488
494
|
}
|
|
489
495
|
else if(a==='autoFocus') { // not lower cased(al), as it is set as a js property
|
|
490
496
|
this.element['autofocus'] = toBool(patch[a]);
|
package/src/errors.jsx
CHANGED
|
@@ -27,277 +27,376 @@
|
|
|
27
27
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
28
28
|
|
|
29
29
|
*/
|
|
30
|
-
|
|
30
|
+
/*
|
|
31
|
+
Lilact
|
|
32
|
+
Copyright (C) 2024-2026 Arash Kazemi <contact.arash.kazemi@gmail.com>
|
|
33
|
+
BSD-2-Clause
|
|
34
|
+
*/
|
|
31
35
|
|
|
32
|
-
import
|
|
33
|
-
import {
|
|
36
|
+
import Lilact from "./lilact.jsx";
|
|
37
|
+
import { required_scripts } from "./run.jsx";
|
|
34
38
|
import { css } from "@emotion/css";
|
|
35
39
|
|
|
36
|
-
|
|
40
|
+
function number(value) {
|
|
41
|
+
const result = Number(value);
|
|
42
|
+
return Number.isFinite(result) ? result : null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function asError(value) {
|
|
46
|
+
if (value instanceof Error) return value;
|
|
47
|
+
if (value?.error instanceof Error) return value.error;
|
|
48
|
+
|
|
49
|
+
const error = new Error(
|
|
50
|
+
value?.message == null
|
|
51
|
+
? String(value)
|
|
52
|
+
: String(value.message)
|
|
53
|
+
);
|
|
37
54
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const l = err.lineNumber || err.lineno || err.line;
|
|
42
|
-
const c = err.columnNumber || err.colno || err.column;
|
|
55
|
+
if (value && typeof value === "object") {
|
|
56
|
+
if (value.name) error.name = value.name;
|
|
57
|
+
if (value.stack) error.stack = value.stack;
|
|
43
58
|
|
|
44
|
-
|
|
45
|
-
|
|
59
|
+
for (const key of Object.keys(value)) {
|
|
60
|
+
if (!(key in error)) error[key] = value[key];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
46
63
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
64
|
+
return error;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function isParserError(error) {
|
|
68
|
+
return error?.name === "JSXParserError";
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function stackLocation(stack) {
|
|
72
|
+
if (typeof stack !== "string") return null;
|
|
73
|
+
|
|
74
|
+
for (const line of stack.split(/\r?\n/)) {
|
|
75
|
+
const match = line.match(/(eval:\/.*):(\d+):(\d+)/);
|
|
76
|
+
|
|
77
|
+
if (!match) continue;
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
path: match[1].replace(/^eval:\/+/, ""),
|
|
81
|
+
line: Number(match[2]) - 1,
|
|
82
|
+
column: Number(match[3]) - 1,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function browserLocation(error) {
|
|
90
|
+
const line = number(
|
|
91
|
+
error?.lineNumber ??
|
|
92
|
+
error?.lineno ??
|
|
93
|
+
error?.line
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const column = number(
|
|
97
|
+
error?.columnNumber ??
|
|
98
|
+
error?.colno ??
|
|
99
|
+
error?.column
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
line: line == null ? null : Math.max(0, line - 1),
|
|
104
|
+
column: column == null ? null : Math.max(0, column - 1),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
51
107
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
108
|
+
function traceBlock(error) {
|
|
109
|
+
const trace = error?.lilact_trace;
|
|
110
|
+
return Array.isArray(trace) ? trace[0] : trace;
|
|
111
|
+
}
|
|
55
112
|
|
|
56
|
-
|
|
113
|
+
function blockInfo(error) {
|
|
114
|
+
const trace = traceBlock(error);
|
|
115
|
+
return trace == null
|
|
116
|
+
? null
|
|
117
|
+
: Lilact.blocks_info?.labels?.[trace];
|
|
57
118
|
}
|
|
58
119
|
|
|
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
|
-
|
|
120
|
+
function mapLocation(mappings, line, column) {
|
|
121
|
+
if (
|
|
122
|
+
!Array.isArray(mappings) ||
|
|
123
|
+
!mappings.length ||
|
|
124
|
+
!Number.isFinite(line) ||
|
|
125
|
+
!Number.isFinite(column)
|
|
126
|
+
) {
|
|
127
|
+
return { line, column };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const valid = mappings
|
|
131
|
+
.filter(mapping =>
|
|
132
|
+
Array.isArray(mapping) &&
|
|
133
|
+
mapping.length >= 4 &&
|
|
134
|
+
mapping
|
|
135
|
+
.slice(0, 4)
|
|
136
|
+
.every(value => Number.isFinite(Number(value)))
|
|
137
|
+
)
|
|
138
|
+
.sort((a, b) =>
|
|
139
|
+
Number(a[0]) - Number(b[0]) ||
|
|
140
|
+
Number(a[1]) - Number(b[1])
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
if (!valid.length) return { line, column };
|
|
144
|
+
|
|
145
|
+
let selected = valid[0];
|
|
146
|
+
|
|
147
|
+
for (const mapping of valid) {
|
|
148
|
+
const generatedLine = Number(mapping[0]);
|
|
149
|
+
const generatedColumn = Number(mapping[1]);
|
|
150
|
+
|
|
151
|
+
if (
|
|
152
|
+
generatedLine < line ||
|
|
153
|
+
(
|
|
154
|
+
generatedLine === line &&
|
|
155
|
+
generatedColumn <= column
|
|
156
|
+
)
|
|
157
|
+
) {
|
|
158
|
+
selected = mapping;
|
|
159
|
+
} else {
|
|
160
|
+
break;
|
|
87
161
|
}
|
|
88
162
|
}
|
|
89
163
|
|
|
90
|
-
|
|
164
|
+
const generatedLine = Number(selected[0]);
|
|
165
|
+
const generatedColumn = Number(selected[1]);
|
|
166
|
+
const sourceLine = Number(selected[2]);
|
|
167
|
+
const sourceColumn = Number(selected[3]);
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
line:
|
|
171
|
+
sourceLine +
|
|
172
|
+
(line === generatedLine ? 0 : line - generatedLine),
|
|
173
|
+
column:
|
|
174
|
+
line === generatedLine
|
|
175
|
+
? Math.max(0, sourceColumn + column - generatedColumn)
|
|
176
|
+
: sourceColumn,
|
|
177
|
+
};
|
|
91
178
|
}
|
|
92
179
|
|
|
93
|
-
function
|
|
94
|
-
|
|
95
|
-
|
|
180
|
+
export function traceError(value, runPath) {
|
|
181
|
+
if (value?.isTraced) return value;
|
|
182
|
+
|
|
183
|
+
const error = asError(value);
|
|
184
|
+
const source = error.lilact_source;
|
|
185
|
+
const stack = isParserError(error)
|
|
186
|
+
? null
|
|
187
|
+
: stackLocation(error.stack);
|
|
188
|
+
const browser = isParserError(error)
|
|
189
|
+
? {
|
|
190
|
+
line: number(error.lineNumber),
|
|
191
|
+
column: number(error.columnNumber),
|
|
192
|
+
}
|
|
193
|
+
: browserLocation(error);
|
|
194
|
+
|
|
195
|
+
/*
|
|
196
|
+
* lilact_source is authoritative. In particular, it prevents a syntax
|
|
197
|
+
* error from a nested eval from inheriting the caller's eval filename.
|
|
198
|
+
*/
|
|
199
|
+
const fileName =
|
|
200
|
+
source?.path ||
|
|
201
|
+
stack?.path ||
|
|
202
|
+
error.fileName ||
|
|
203
|
+
runPath ||
|
|
204
|
+
null;
|
|
205
|
+
|
|
206
|
+
let line =
|
|
207
|
+
stack?.line ??
|
|
208
|
+
browser.line ??
|
|
209
|
+
null;
|
|
210
|
+
|
|
211
|
+
let column =
|
|
212
|
+
stack?.column ??
|
|
213
|
+
browser.column ??
|
|
214
|
+
null;
|
|
215
|
+
|
|
216
|
+
const result = {
|
|
217
|
+
fileName,
|
|
218
|
+
lineNumber: line,
|
|
219
|
+
columnNumber: column,
|
|
220
|
+
message:
|
|
221
|
+
error.message == null
|
|
222
|
+
? String(error)
|
|
223
|
+
: String(error.message),
|
|
224
|
+
name: error.name || "Error",
|
|
225
|
+
stack: error.stack || null,
|
|
226
|
+
lilact_source: source || null,
|
|
227
|
+
_error: error,
|
|
228
|
+
isTraced: true,
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
const module = fileName && required_scripts[fileName];
|
|
232
|
+
|
|
233
|
+
if (module) {
|
|
234
|
+
const mapped = mapLocation(
|
|
235
|
+
module.mappings,
|
|
236
|
+
result.lineNumber,
|
|
237
|
+
result.columnNumber
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
result.lineNumber = mapped.line;
|
|
241
|
+
result.columnNumber = mapped.column;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const block = blockInfo(error);
|
|
245
|
+
|
|
246
|
+
if (
|
|
247
|
+
block &&
|
|
248
|
+
(
|
|
249
|
+
result.lineNumber == null ||
|
|
250
|
+
result.columnNumber == null ||
|
|
251
|
+
!result.fileName
|
|
252
|
+
)
|
|
253
|
+
) {
|
|
254
|
+
result.fileName ||= block.path || runPath || null;
|
|
255
|
+
result.lineNumber ??= block.line;
|
|
256
|
+
result.columnNumber ??= block.col;
|
|
257
|
+
result.label = block.desc;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
Lilact.error = result;
|
|
261
|
+
return result;
|
|
96
262
|
}
|
|
97
263
|
|
|
98
|
-
function
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
map = mps[i-1];
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if(!map) map = mps[mps.length-1];
|
|
110
|
-
return {line: r-map[0]+map[2], col: ((r-map[0]===0)?map[3]:0) };
|
|
264
|
+
function escapeHtml(value) {
|
|
265
|
+
return String(value ?? "")
|
|
266
|
+
.replaceAll("&", "&")
|
|
267
|
+
.replaceAll("<", "<")
|
|
268
|
+
.replaceAll(">", ">")
|
|
269
|
+
.replaceAll('"', """)
|
|
270
|
+
.replaceAll("'", "'");
|
|
111
271
|
}
|
|
112
272
|
|
|
273
|
+
function sourceExcerpt(module, line) {
|
|
274
|
+
if (!module || !Number.isFinite(line)) return null;
|
|
113
275
|
|
|
114
|
-
|
|
115
|
-
export function scanBlockLabels(code, path)
|
|
116
|
-
{
|
|
117
|
-
const ls = Array.from( code.matchAll(/LILACTBLOCK(\d+):(\d+),(\d+):([^*]+)\*\//mg) );
|
|
276
|
+
const lines = String(module.code ?? "").split(/\r?\n/);
|
|
118
277
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
desc: x[4]
|
|
125
|
-
}
|
|
126
|
-
} );
|
|
278
|
+
return {
|
|
279
|
+
before: lines[line - 1] ?? "",
|
|
280
|
+
current: lines[line] ?? "",
|
|
281
|
+
after: lines[line + 1] ?? "",
|
|
282
|
+
};
|
|
127
283
|
}
|
|
128
284
|
|
|
285
|
+
export function globalErrorHandler(eventOrError) {
|
|
286
|
+
const value =
|
|
287
|
+
eventOrError?.error instanceof Error
|
|
288
|
+
? eventOrError.error
|
|
289
|
+
: eventOrError?.reason !== undefined
|
|
290
|
+
? eventOrError.reason
|
|
291
|
+
: eventOrError;
|
|
292
|
+
|
|
293
|
+
const error = traceError(
|
|
294
|
+
value,
|
|
295
|
+
eventOrError?.fileName || null
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
const excerpt = sourceExcerpt(
|
|
299
|
+
required_scripts[error.fileName],
|
|
300
|
+
error.lineNumber
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
const className = css(`
|
|
304
|
+
background: linear-gradient(135deg, #fff2f2d4, #ffffffd4);
|
|
305
|
+
backdrop-filter: blur(10px);
|
|
306
|
+
border: 1px solid rgba(255,255,255,.25);
|
|
307
|
+
border-radius: 5px;
|
|
308
|
+
box-shadow: 0 10px 30px rgba(0,0,0,.35);
|
|
309
|
+
overflow: hidden;
|
|
310
|
+
min-width: 400px;
|
|
311
|
+
width: 66%;
|
|
312
|
+
|
|
313
|
+
red {
|
|
314
|
+
color: #d00;
|
|
315
|
+
}
|
|
129
316
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
mps = required_scripts[blk.path].mappings;
|
|
196
|
-
|
|
197
|
-
loc = mapLocation(mps, loc.line-1, loc.col-1);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
obj.lineNumber = loc.line;
|
|
202
|
-
obj.columnNumber = loc.col;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
const loc = getErrorLocation(error);
|
|
208
|
-
|
|
209
|
-
//if(!obj.fileName) {
|
|
210
|
-
if(error.fileName) obj.fileName = error.fileName;
|
|
211
|
-
else if(run_path) obj.fileName = run_path;
|
|
212
|
-
//}
|
|
213
|
-
|
|
214
|
-
obj.lineNumber = loc.line;
|
|
215
|
-
obj.columnNumber = loc.col;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
Lilact.error = obj;
|
|
219
|
-
return obj;
|
|
220
|
-
|
|
317
|
+
code {
|
|
318
|
+
border: 1px solid #0003;
|
|
319
|
+
overflow: auto;
|
|
320
|
+
padding: 10px;
|
|
321
|
+
display: block;
|
|
322
|
+
}
|
|
323
|
+
`);
|
|
324
|
+
|
|
325
|
+
const dialog = document.createElement("dialog");
|
|
326
|
+
dialog.className = className;
|
|
327
|
+
|
|
328
|
+
const location = error.fileName
|
|
329
|
+
? `At ${escapeHtml(error.fileName)}`
|
|
330
|
+
: "";
|
|
331
|
+
|
|
332
|
+
const line = Number.isFinite(error.lineNumber)
|
|
333
|
+
? `: Line ${error.lineNumber + 1}`
|
|
334
|
+
: "";
|
|
335
|
+
|
|
336
|
+
const componentStack =
|
|
337
|
+
error._error?.componentStackLog ||
|
|
338
|
+
error._error?.componentStack ||
|
|
339
|
+
"";
|
|
340
|
+
|
|
341
|
+
dialog.innerHTML = `
|
|
342
|
+
<h3><red>Error!</red></h3>
|
|
343
|
+
<b>${location}${line}</b><br><br>
|
|
344
|
+
<b>${escapeHtml(error.name)}</b>:
|
|
345
|
+
<span>${escapeHtml(error.message)}</span>
|
|
346
|
+
<br><br>
|
|
347
|
+
|
|
348
|
+
${
|
|
349
|
+
excerpt
|
|
350
|
+
? "<code><pre></pre><red><pre></pre></red><pre></pre></code>"
|
|
351
|
+
: ""
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
${
|
|
355
|
+
componentStack
|
|
356
|
+
? `
|
|
357
|
+
<br>
|
|
358
|
+
Component Stack:
|
|
359
|
+
<br>
|
|
360
|
+
<code><pre>${escapeHtml(componentStack)}</pre></code>
|
|
361
|
+
`
|
|
362
|
+
: ""
|
|
363
|
+
}
|
|
364
|
+
`;
|
|
365
|
+
|
|
366
|
+
if (excerpt) {
|
|
367
|
+
const pre = dialog.querySelectorAll("pre");
|
|
368
|
+
pre[0].innerText = excerpt.before;
|
|
369
|
+
pre[1].innerText = excerpt.current;
|
|
370
|
+
pre[2].innerText = excerpt.after;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
document.body.appendChild(dialog);
|
|
374
|
+
|
|
375
|
+
if (typeof dialog.showModal === "function") {
|
|
376
|
+
dialog.showModal();
|
|
377
|
+
} else {
|
|
378
|
+
dialog.setAttribute("open", "");
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return error;
|
|
221
382
|
}
|
|
222
383
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
* Lilact.globalErrorHandler(e);
|
|
235
|
-
* });
|
|
236
|
-
* `
|
|
237
|
-
* @param error - The error object
|
|
238
|
-
*
|
|
239
|
-
*/
|
|
240
|
-
export function globalErrorHandler(error)
|
|
241
|
-
{
|
|
242
|
-
if(error.error) error = error.error;
|
|
243
|
-
|
|
244
|
-
error = traceError(error);
|
|
245
|
-
|
|
246
|
-
const cls = css(`
|
|
247
|
-
background: linear-gradient(135deg, #fff2f2d4, #ffffffd4);
|
|
248
|
-
backdrop-filter: blur(10px);
|
|
249
|
-
border: 1px solid rgba(255,255,255,.25);
|
|
250
|
-
border-radius: 5px;
|
|
251
|
-
box-shadow: 0 10px 30px rgba(0,0,0,.35);
|
|
252
|
-
overflow:hidden;
|
|
253
|
-
min-width: 400px;
|
|
254
|
-
width: 66%;
|
|
255
|
-
red {
|
|
256
|
-
color:#d00;
|
|
257
|
-
}
|
|
258
|
-
code {
|
|
259
|
-
border: 1px solid #0003;
|
|
260
|
-
overflow: auto;
|
|
261
|
-
padding: 10px;
|
|
262
|
-
display: block;
|
|
263
|
-
}
|
|
264
|
-
`);
|
|
265
|
-
|
|
266
|
-
const el = document.createElement('dialog');
|
|
267
|
-
|
|
268
|
-
el.className=cls;
|
|
269
|
-
//<b>⚠</b>
|
|
270
|
-
el.innerHTML =
|
|
271
|
-
`<h3 style=""><red>Error!</red></h3>
|
|
272
|
-
<b>${error.fileName?'At '+error.fileName:''}
|
|
273
|
-
${Number.isFinite(error.lineNumber)?": Line "+(error.lineNumber+1):""}</b><br><br>
|
|
274
|
-
<b>${error.name}</b>: <span>${error.message}</span><br><br>
|
|
275
|
-
${required_scripts[error.fileName]?'<code><pre></pre><pre><red></red></pre><pre></pre></code>':''}
|
|
276
|
-
${error._error.componentStackLog?'<br>Component Stack:<br><code><pre>'+error._error.componentStackLog+'</pre></code>':''}
|
|
277
|
-
`;
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
document.body.appendChild(el);
|
|
281
|
-
|
|
282
|
-
const pres = el.querySelectorAll('pre');
|
|
283
|
-
|
|
284
|
-
if(required_scripts[error.fileName]) {
|
|
285
|
-
const lines = required_scripts[error.fileName].code.split("\n");
|
|
286
|
-
|
|
287
|
-
if(lines?.[error.lineNumber-1])
|
|
288
|
-
pres[0].innerText = lines[error.lineNumber-1];
|
|
289
|
-
|
|
290
|
-
if(lines?.[error.lineNumber]) el.querySelector('pre red').innerText = lines[error.lineNumber];
|
|
291
|
-
|
|
292
|
-
if(lines?.[error.lineNumber+1])
|
|
293
|
-
pres[2].innerText = lines[error.lineNumber+1];
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
el.showModal();
|
|
384
|
+
export function scanBlockLabels(code, path) {
|
|
385
|
+
for (const match of String(code).matchAll(
|
|
386
|
+
/LILACTBLOCK(\d+):(\d+),(\d+):([^*]+)\*\//gm
|
|
387
|
+
)) {
|
|
388
|
+
Lilact.blocks_info.labels[match[1]] = {
|
|
389
|
+
path,
|
|
390
|
+
line: Number(match[2]),
|
|
391
|
+
col: Number(match[3]),
|
|
392
|
+
desc: match[4],
|
|
393
|
+
};
|
|
394
|
+
}
|
|
297
395
|
}
|
|
298
396
|
|
|
299
|
-
|
|
300
|
-
|
|
397
|
+
export const blocks_info = {
|
|
398
|
+
counter: 0,
|
|
399
|
+
labels: {},
|
|
400
|
+
};
|
|
301
401
|
|
|
302
|
-
|
|
303
|
-
export let error = null; // this is only to ease debuggin,
|
|
402
|
+
export let error = null;
|