lilact 0.29.1 → 0.29.3
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 +192 -134
- package/dist/lilact.development.js.map +3 -3
- package/dist/lilact.development.min.js +23 -23
- package/dist/lilact.development.min.js.map +3 -3
- package/dist/lilact.production.min.js +23 -23
- 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/run.lazy.html +1 -1
- package/docs/functions/run.require.html +1 -1
- package/docs/functions/run.run.html +1 -1
- package/docs/functions/run.runScripts.html +1 -1
- package/docs/static/index.html +1 -1
- package/docs/static/lilact.development.js +192 -134
- package/docs/static/lilact.development.js.map +3 -3
- package/docs/static/lilact.development.min.js +23 -23
- package/docs/static/lilact.development.min.js.map +3 -3
- package/docs/static/lilact.production.min.js +23 -23
- package/docs/variables/components.cloneElement.html +1 -1
- package/examples/index.html +1 -1
- package/examples/lilact.development.js +192 -134
- package/examples/lilact.development.js.map +3 -3
- package/examples/lilact.development.min.js +23 -23
- package/examples/lilact.development.min.js.map +3 -3
- package/examples/lilact.production.min.js +23 -23
- package/package.json +1 -1
- package/src/components.jsx +109 -45
- package/src/run.jsx +150 -132
package/package.json
CHANGED
package/src/components.jsx
CHANGED
|
@@ -37,6 +37,50 @@ import { PropTypes } from './proptypes.jsx';
|
|
|
37
37
|
|
|
38
38
|
const SVG_NS = "http://www.w3.org/2000/svg";
|
|
39
39
|
|
|
40
|
+
|
|
41
|
+
function getComponentEntity(entity) {
|
|
42
|
+
return entity?.[MEMOIZED]
|
|
43
|
+
? entity.component
|
|
44
|
+
: entity;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function replaceComponentEntity(comp, nextEntity) {
|
|
48
|
+
const core = comp?.[CORE];
|
|
49
|
+
|
|
50
|
+
if (!core || typeof nextEntity !== "function") {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const oldEntity = getComponentEntity(core.entity);
|
|
55
|
+
const newEntity = getComponentEntity(nextEntity);
|
|
56
|
+
|
|
57
|
+
if (oldEntity === newEntity) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const oldIsClass = isClass(oldEntity);
|
|
62
|
+
const newIsClass = isClass(newEntity);
|
|
63
|
+
|
|
64
|
+
// A function component and a class component have different instance
|
|
65
|
+
// semantics. Let the cache create a fresh instance in that case.
|
|
66
|
+
if (oldIsClass !== newIsClass) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (newIsClass) {
|
|
71
|
+
// Preserve the existing instance and state, but use the new class
|
|
72
|
+
// prototype and therefore the new render/lifecycle methods.
|
|
73
|
+
Object.setPrototypeOf(comp, newEntity.prototype);
|
|
74
|
+
} else {
|
|
75
|
+
// Preserve hooks and state, but replace the function implementation.
|
|
76
|
+
comp.render = newEntity.bind(comp);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
core.entity = newEntity;
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
40
84
|
/*
|
|
41
85
|
ComponentCache is for internal use. It is the heart of the JSX runtime,
|
|
42
86
|
it holds child components and detects which one is being rendered or updated.
|
|
@@ -54,39 +98,46 @@ class ComponentCache
|
|
|
54
98
|
this.owner = owner;
|
|
55
99
|
}
|
|
56
100
|
|
|
57
|
-
pick(key, construct_func)
|
|
58
|
-
{
|
|
101
|
+
pick(key, construct_func, nextEntity) {
|
|
59
102
|
let comp;
|
|
60
|
-
let
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
103
|
+
let bucket = this.current_map.get(key);
|
|
104
|
+
const reusable =
|
|
105
|
+
bucket && bucket.length > bucket[IDX];
|
|
106
|
+
|
|
107
|
+
if (reusable) {
|
|
108
|
+
comp = bucket[bucket[IDX]];
|
|
109
|
+
bucket[IDX]++;
|
|
110
|
+
|
|
111
|
+
const oldEntity = getComponentEntity(comp?.[CORE]?.entity);
|
|
112
|
+
const newEntity = getComponentEntity(nextEntity);
|
|
113
|
+
|
|
114
|
+
const incompatible =
|
|
115
|
+
typeof oldEntity === "function" &&
|
|
116
|
+
typeof newEntity === "function" &&
|
|
117
|
+
isClass(oldEntity) !== isClass(newEntity);
|
|
118
|
+
|
|
119
|
+
if (incompatible) {
|
|
120
|
+
// Do not reuse a class instance as a function component or vice versa.
|
|
121
|
+
comp = construct_func();
|
|
122
|
+
} else {
|
|
123
|
+
replaceComponentEntity(comp, nextEntity);
|
|
74
124
|
}
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
125
|
+
} else {
|
|
77
126
|
comp = construct_func();
|
|
127
|
+
}
|
|
78
128
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
129
|
+
bucket = this.new_map.get(key);
|
|
130
|
+
|
|
131
|
+
if (bucket !== undefined) {
|
|
132
|
+
bucket.push(comp);
|
|
133
|
+
} else {
|
|
134
|
+
bucket = [comp];
|
|
135
|
+
this.new_map.set(key, bucket);
|
|
136
|
+
bucket[IDX] = 0;
|
|
137
|
+
}
|
|
88
138
|
|
|
89
|
-
|
|
139
|
+
if (comp[CORE]) {
|
|
140
|
+
comp[CORE].parent ??= this.owner;
|
|
90
141
|
}
|
|
91
142
|
|
|
92
143
|
return comp;
|
|
@@ -757,22 +808,35 @@ function constructFunc(core, parent) // returns {text} or component, and not com
|
|
|
757
808
|
}
|
|
758
809
|
|
|
759
810
|
|
|
760
|
-
function prepareCore(parent, core)
|
|
761
|
-
{
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
811
|
+
function prepareCore(parent, core) {
|
|
812
|
+
try {
|
|
813
|
+
parent.cache ??= new ComponentCache(parent);
|
|
814
|
+
|
|
815
|
+
const isText = core[TEXT] !== undefined;
|
|
816
|
+
const key = isText
|
|
817
|
+
? ':text:'
|
|
818
|
+
: core.props?.key;
|
|
819
|
+
|
|
820
|
+
const entity = isText || core instanceof ComponentCore
|
|
821
|
+
? undefined
|
|
822
|
+
: core.entity;
|
|
823
|
+
|
|
824
|
+
return parent.cache.pick(
|
|
825
|
+
key,
|
|
826
|
+
() => (
|
|
827
|
+
isText || core instanceof ComponentCore
|
|
828
|
+
? core
|
|
829
|
+
: constructFunc(core, parent)[CORE]
|
|
830
|
+
),
|
|
831
|
+
entity
|
|
832
|
+
);
|
|
833
|
+
} catch (e) {
|
|
834
|
+
if (core?.component?.componentDidCatch) {
|
|
835
|
+
core.component.componentDidCatch(e);
|
|
836
|
+
} else {
|
|
837
|
+
throw e;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
776
840
|
}
|
|
777
841
|
|
|
778
842
|
|
|
@@ -1392,7 +1456,7 @@ export const events_set = new Set([
|
|
|
1392
1456
|
"onafterprint","onbeforeprint","onbeforeunload","onerror","onhashchange","onload","onmessage",
|
|
1393
1457
|
"onoffline","ononline","onpagehide","onpageshow","onpopstate","onresize","onstorage","onunload",
|
|
1394
1458
|
"onblur","onchange","oncontextmenu","onfocus","oninput","oninvalid","onreset","onsearch","onselect",
|
|
1395
|
-
"onsubmit",
|
|
1459
|
+
"onsubmit", "oncancel",
|
|
1396
1460
|
"onkeydown","onkeypress","onkeyup",
|
|
1397
1461
|
"onclick","ondblclick","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel",
|
|
1398
1462
|
"onwheel",
|
package/src/run.jsx
CHANGED
|
@@ -133,44 +133,163 @@ function createModule(path, {
|
|
|
133
133
|
return module;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
function
|
|
137
|
-
{
|
|
138
|
-
|
|
136
|
+
function loadModule(path, options = {}) {
|
|
137
|
+
if (Lilact.importObjectPaths?.[path]) {
|
|
138
|
+
return Lilact.importObjectPaths[path];
|
|
139
|
+
}
|
|
139
140
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if(!exps) {
|
|
144
|
-
exps = Lilact.require(path, {requirer: mod});
|
|
145
|
-
}
|
|
141
|
+
if (options.requirer?.path) {
|
|
142
|
+
path = joinPaths(options.requirer.path, path);
|
|
143
|
+
}
|
|
146
144
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
if(!exps.hasOwnProperty(j)) throw new Error(`Imported module does not export any "${i}".`);
|
|
151
|
-
mod.importsObject[i] = exps[j];
|
|
152
|
-
}
|
|
145
|
+
const loadAsync =
|
|
146
|
+
Boolean(Lilact[LAZY]) ||
|
|
147
|
+
Boolean(options.isLazy);
|
|
153
148
|
|
|
154
|
-
|
|
155
|
-
if(!exps.hasOwnProperty('default')) throw new Error(`Imported module does not export a default.`);
|
|
156
|
-
mod.importsObject[i] = exps.default;
|
|
157
|
-
}
|
|
149
|
+
const module = getOrCreateModule(path, {});
|
|
158
150
|
|
|
151
|
+
if (module.loaded && !options.forceReload) {
|
|
152
|
+
return module.exports;
|
|
153
|
+
}
|
|
159
154
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
155
|
+
if (path.startsWith("#")) {
|
|
156
|
+
const element = document.getElementById(path.slice(1));
|
|
157
|
+
|
|
158
|
+
if (!element) {
|
|
159
|
+
throw report(
|
|
160
|
+
new Error(`Required element not found (${path})`),
|
|
161
|
+
path
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return run(
|
|
166
|
+
element.textContent || "",
|
|
167
|
+
path,
|
|
168
|
+
{forceReload: options.forceReload}
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (loadAsync) {
|
|
173
|
+
Lilact[LAZY] = false;
|
|
174
|
+
|
|
175
|
+
if (module.request && !options.forceReload) {
|
|
176
|
+
return module.request;
|
|
163
177
|
}
|
|
178
|
+
|
|
179
|
+
return loadAsyncResource(path, module, options);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const resolved = Lilact.resolver?.(path);
|
|
183
|
+
|
|
184
|
+
if (resolved != null) {
|
|
185
|
+
if (path.endsWith(".css")) {
|
|
186
|
+
injectGlobal(String(resolved));
|
|
187
|
+
module.code = String(resolved);
|
|
188
|
+
module.loaded = true;
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return run(
|
|
193
|
+
String(resolved),
|
|
194
|
+
path,
|
|
195
|
+
{forceReload: options.forceReload}
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const request = new XMLHttpRequest();
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
request.open("GET", path, false);
|
|
203
|
+
request.send(null);
|
|
204
|
+
} catch (value) {
|
|
205
|
+
throw report(value, path);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (request.status >= 200 && request.status < 300) {
|
|
209
|
+
if (path.endsWith(".css")) {
|
|
210
|
+
module.code = request.responseText;
|
|
211
|
+
injectGlobal(module.code);
|
|
212
|
+
module.loaded = true;
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return run(
|
|
217
|
+
request.responseText,
|
|
218
|
+
path,
|
|
219
|
+
{forceReload: true}
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
throw report(
|
|
224
|
+
new Error(
|
|
225
|
+
`Unable to load ${path}: HTTP ${request.status || 0}`
|
|
226
|
+
),
|
|
227
|
+
path
|
|
228
|
+
);
|
|
164
229
|
}
|
|
165
230
|
|
|
231
|
+
export function require(path)
|
|
232
|
+
{
|
|
233
|
+
let options = {};
|
|
234
|
+
|
|
235
|
+
if (
|
|
236
|
+
arguments.length === 2 &&
|
|
237
|
+
arguments[1] &&
|
|
238
|
+
typeof arguments[1] === "object"
|
|
239
|
+
) {
|
|
240
|
+
options = arguments[1];
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return loadModule(path, options);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
function makeImportsObject(mod, options = {}) {
|
|
248
|
+
mod.importsObject = {};
|
|
249
|
+
|
|
250
|
+
for (const path in mod.meta.imports) {
|
|
251
|
+
const imps = mod.meta.imports[path];
|
|
252
|
+
|
|
253
|
+
const exps = loadModule(path, {
|
|
254
|
+
requirer: mod,
|
|
255
|
+
forceReload: options.forceReload,
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
for (const i in imps.named_imports) {
|
|
259
|
+
if (i === '') continue;
|
|
260
|
+
|
|
261
|
+
const exportedName = imps.named_imports[i];
|
|
262
|
+
|
|
263
|
+
if (!Object.prototype.hasOwnProperty.call(exps, exportedName)) {
|
|
264
|
+
throw new Error(
|
|
265
|
+
`Imported module does not export any "${i}".`
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
mod.importsObject[i] = exps[exportedName];
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
for (const i of imps.import_defaults) {
|
|
273
|
+
if (!Object.prototype.hasOwnProperty.call(exps, 'default')) {
|
|
274
|
+
throw new Error(
|
|
275
|
+
`Imported module does not export a default.`
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
mod.importsObject[i] = exps.default;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
for (const i of imps.import_stars) {
|
|
283
|
+
mod.importsObject[i] = { ...exps };
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
166
287
|
|
|
167
|
-
// ERROR IS FOUND WHEN run IS CALLED, AND NOT REQUIRE.
|
|
168
|
-
// REQUIRE REWRITES MODULE ANYWAY. THAT IS ALSO A PROBLEM.
|
|
169
288
|
|
|
170
289
|
export function run(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
290
|
+
jsx,
|
|
291
|
+
path = `InlineJSX-${++Lilact.eval_num}`,
|
|
292
|
+
options = {}
|
|
174
293
|
) {
|
|
175
294
|
let module = required_scripts[path];
|
|
176
295
|
|
|
@@ -238,7 +357,7 @@ export function run(
|
|
|
238
357
|
globalThis.createComponent = Lilact.createComponent;
|
|
239
358
|
globalThis.Fragment = Lilact.Fragment;
|
|
240
359
|
|
|
241
|
-
makeImportsObject(module);
|
|
360
|
+
makeImportsObject(module, options);
|
|
242
361
|
|
|
243
362
|
Lilact.scriptImportsObject = module.importsObject;
|
|
244
363
|
const result = eval(processed);
|
|
@@ -258,7 +377,8 @@ function getOrCreateModule(path, options = {}) {
|
|
|
258
377
|
return required_scripts[path] || createModule(path, options);
|
|
259
378
|
}
|
|
260
379
|
|
|
261
|
-
function loadAsyncResource(path, module)
|
|
380
|
+
function loadAsyncResource(path, module, options = {})
|
|
381
|
+
{
|
|
262
382
|
let source;
|
|
263
383
|
|
|
264
384
|
try {
|
|
@@ -304,7 +424,7 @@ function loadAsyncResource(path, module) {
|
|
|
304
424
|
return undefined;
|
|
305
425
|
}
|
|
306
426
|
|
|
307
|
-
return run(module.code, path,
|
|
427
|
+
return run(module.code, path, options);
|
|
308
428
|
})
|
|
309
429
|
.then(result => result?.default ?? result)
|
|
310
430
|
.catch(error => {
|
|
@@ -325,108 +445,6 @@ function loadAsyncResource(path, module) {
|
|
|
325
445
|
return request;
|
|
326
446
|
}
|
|
327
447
|
|
|
328
|
-
export function require(path) {
|
|
329
|
-
let options = {};
|
|
330
|
-
|
|
331
|
-
if (
|
|
332
|
-
arguments.length === 2 &&
|
|
333
|
-
arguments[1] &&
|
|
334
|
-
typeof arguments[1] === "object"
|
|
335
|
-
) {
|
|
336
|
-
options = arguments[1];
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
if (Lilact.importObjectPaths?.[path]) {
|
|
340
|
-
return Lilact.importObjectPaths[path];
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
if (options?.requirer?.path) {
|
|
344
|
-
path = joinPaths(options.requirer.path, path);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
const loadAsync =
|
|
348
|
-
Boolean(Lilact[LAZY]) ||
|
|
349
|
-
Boolean(options.isLazy);
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
const module = getOrCreateModule(path, {});
|
|
353
|
-
|
|
354
|
-
/*
|
|
355
|
-
* A completed module can be returned synchronously unless the caller
|
|
356
|
-
* explicitly requests lazy loading.
|
|
357
|
-
*/
|
|
358
|
-
if (module.loaded && !options.forceReload) {
|
|
359
|
-
return module.exports;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
if (path.startsWith("#")) {
|
|
363
|
-
const element = document.getElementById(path.slice(1));
|
|
364
|
-
|
|
365
|
-
if (!element) {
|
|
366
|
-
throw report(
|
|
367
|
-
new Error(`Required element not found (${path})`),
|
|
368
|
-
path
|
|
369
|
-
);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
return run(element.textContent || "", path, {forceReload: options.forceReload});
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
if (loadAsync) {
|
|
376
|
-
Lilact[LAZY] = false;
|
|
377
|
-
|
|
378
|
-
/*
|
|
379
|
-
* Every subsequent lazy require() receives the first request promise.
|
|
380
|
-
* This applies even when the module is still being fetched and even when
|
|
381
|
-
* the first caller used forceReload.
|
|
382
|
-
*/
|
|
383
|
-
if (module.request) {
|
|
384
|
-
return module.request;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
return loadAsyncResource(path, module);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
const resolved = Lilact.resolver?.(path);
|
|
391
|
-
|
|
392
|
-
if (resolved != null) {
|
|
393
|
-
if (path.endsWith(".css")) {
|
|
394
|
-
injectGlobal(String(resolved));
|
|
395
|
-
module.code = String(resolved);
|
|
396
|
-
module.loaded = true;
|
|
397
|
-
return undefined;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
return run(String(resolved), path, {forceReload: options.forceReload});
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
const request = new XMLHttpRequest();
|
|
404
|
-
|
|
405
|
-
try {
|
|
406
|
-
request.open("GET", path, false);
|
|
407
|
-
request.send(null);
|
|
408
|
-
} catch (value) {
|
|
409
|
-
throw report(value, path);
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
if (request.status >= 200 && request.status < 300) {
|
|
413
|
-
if (path.endsWith(".css")) {
|
|
414
|
-
module.code = request.responseText;
|
|
415
|
-
injectGlobal(module.code);
|
|
416
|
-
module.loaded = true;
|
|
417
|
-
return undefined;
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
return run(request.responseText, path, {forceReload: true});
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
throw report(
|
|
424
|
-
new Error(
|
|
425
|
-
`Unable to load ${path}: HTTP ${request.status || 0}`
|
|
426
|
-
),
|
|
427
|
-
path
|
|
428
|
-
);
|
|
429
|
-
}
|
|
430
448
|
|
|
431
449
|
export function lazy(factory) {
|
|
432
450
|
let status = "pending";
|