lilact 0.29.2 → 0.30.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 +135 -108
- package/dist/lilact.development.js.map +3 -3
- package/dist/lilact.development.min.js +28 -28
- package/dist/lilact.development.min.js.map +3 -3
- package/dist/lilact.production.min.js +28 -28
- package/docs/assets/hierarchy.js +1 -1
- 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.hotReloadRoot.html +1 -0
- package/docs/functions/components.memo.html +1 -1
- package/docs/functions/components.render.html +1 -1
- package/docs/functions/components.replaceComponentEntity.html +1 -0
- package/docs/functions/run.lazy.html +1 -1
- package/docs/functions/run.run.html +1 -1
- package/docs/functions/run.runScripts.html +1 -1
- package/docs/hierarchy.html +1 -1
- package/docs/modules/components.html +1 -1
- package/docs/static/index.html +1 -1
- package/docs/static/lilact.development.js +135 -108
- package/docs/static/lilact.development.js.map +3 -3
- package/docs/static/lilact.development.min.js +28 -28
- package/docs/static/lilact.development.min.js.map +3 -3
- package/docs/static/lilact.production.min.js +28 -28
- package/docs/variables/components.cloneElement.html +1 -1
- package/examples/index.html +1 -1
- package/examples/lilact.development.js +135 -108
- package/examples/lilact.development.js.map +3 -3
- package/examples/lilact.development.min.js +28 -28
- package/examples/lilact.development.min.js.map +3 -3
- package/examples/lilact.production.min.js +28 -28
- package/package.json +1 -1
- package/src/components.jsx +128 -40
- package/src/jsx.js +7 -32
- package/src/lilact.jsx +1 -1
- package/src/run.jsx +41 -51
package/package.json
CHANGED
package/src/components.jsx
CHANGED
|
@@ -37,6 +37,53 @@ 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
|
+
export function replaceComponentEntity(componentCore, nextEntity) {
|
|
48
|
+
if (!componentCore || typeof nextEntity !== "function") {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const oldEntity = getComponentEntity(componentCore.entity);
|
|
53
|
+
const newEntity = getComponentEntity(nextEntity);
|
|
54
|
+
|
|
55
|
+
if (oldEntity === newEntity) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const component = componentCore.component;
|
|
60
|
+
|
|
61
|
+
if (!component) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const oldIsClass = isClass(oldEntity);
|
|
66
|
+
const newIsClass = isClass(newEntity);
|
|
67
|
+
|
|
68
|
+
// A function component cannot reuse a class instance, and vice versa.
|
|
69
|
+
if (oldIsClass !== newIsClass) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (newIsClass) {
|
|
74
|
+
// componentCore.state and the component instance are preserved.
|
|
75
|
+
// Only the class implementation changes.
|
|
76
|
+
Object.setPrototypeOf(component, newEntity.prototype);
|
|
77
|
+
} else {
|
|
78
|
+
// The function is invoked with the ComponentCore as `this` by apply().
|
|
79
|
+
component.render = newEntity;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
componentCore.entity = newEntity;
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
40
87
|
/*
|
|
41
88
|
ComponentCache is for internal use. It is the heart of the JSX runtime,
|
|
42
89
|
it holds child components and detects which one is being rendered or updated.
|
|
@@ -54,42 +101,47 @@ class ComponentCache
|
|
|
54
101
|
this.owner = owner;
|
|
55
102
|
}
|
|
56
103
|
|
|
57
|
-
pick(key, construct_func)
|
|
58
|
-
|
|
59
|
-
let
|
|
60
|
-
let buck = this.current_map.get(key);
|
|
104
|
+
pick(key, construct_func, nextEntity) {
|
|
105
|
+
let componentCore;
|
|
106
|
+
let bucket = this.current_map.get(key);
|
|
61
107
|
|
|
62
|
-
if(
|
|
63
|
-
|
|
64
|
-
|
|
108
|
+
if (bucket && bucket.length > bucket[IDX]) {
|
|
109
|
+
componentCore = bucket[bucket[IDX]];
|
|
110
|
+
bucket[IDX]++;
|
|
65
111
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
112
|
+
const oldEntity = getComponentEntity(componentCore.entity);
|
|
113
|
+
const newEntity = getComponentEntity(nextEntity);
|
|
114
|
+
|
|
115
|
+
const incompatible =
|
|
116
|
+
typeof oldEntity === "function" &&
|
|
117
|
+
typeof newEntity === "function" &&
|
|
118
|
+
isClass(oldEntity) !== isClass(newEntity);
|
|
119
|
+
|
|
120
|
+
if (incompatible) {
|
|
121
|
+
componentCore = construct_func();
|
|
122
|
+
}
|
|
123
|
+
else if (newEntity) {
|
|
124
|
+
replaceComponentEntity(componentCore, newEntity);
|
|
74
125
|
}
|
|
126
|
+
} else {
|
|
127
|
+
componentCore = construct_func();
|
|
75
128
|
}
|
|
76
|
-
else {
|
|
77
|
-
comp = construct_func();
|
|
78
129
|
|
|
79
|
-
|
|
80
|
-
if(buck!==undefined) {
|
|
81
|
-
buck.push( comp );
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
buck = [ comp ];
|
|
85
|
-
this.new_map.set(key, buck);
|
|
86
|
-
buck[IDX]=0;
|
|
87
|
-
}
|
|
130
|
+
bucket = this.new_map.get(key);
|
|
88
131
|
|
|
89
|
-
|
|
132
|
+
if (bucket) {
|
|
133
|
+
bucket.push(componentCore);
|
|
134
|
+
} else {
|
|
135
|
+
bucket = [componentCore];
|
|
136
|
+
this.new_map.set(key, bucket);
|
|
137
|
+
bucket[IDX] = 0;
|
|
90
138
|
}
|
|
91
139
|
|
|
92
|
-
|
|
140
|
+
if (componentCore) {
|
|
141
|
+
componentCore.parent ??= this.owner;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return componentCore;
|
|
93
145
|
}
|
|
94
146
|
|
|
95
147
|
commit()
|
|
@@ -756,22 +808,36 @@ function constructFunc(core, parent) // returns {text} or component, and not com
|
|
|
756
808
|
return comp;
|
|
757
809
|
}
|
|
758
810
|
|
|
759
|
-
|
|
760
|
-
function prepareCore(parent, core)
|
|
761
|
-
{
|
|
811
|
+
function prepareCore(parent, core) {
|
|
762
812
|
try {
|
|
763
813
|
parent.cache ??= new ComponentCache(parent);
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
814
|
+
|
|
815
|
+
const isText = core[TEXT] !== undefined;
|
|
816
|
+
|
|
817
|
+
const key = isText
|
|
818
|
+
? ':text:'
|
|
819
|
+
: core.props?.key;
|
|
820
|
+
|
|
821
|
+
const entity =
|
|
822
|
+
isText || core instanceof ComponentCore
|
|
823
|
+
? undefined
|
|
824
|
+
: core.entity;
|
|
825
|
+
|
|
826
|
+
return parent.cache.pick(
|
|
827
|
+
key,
|
|
828
|
+
() => (
|
|
829
|
+
isText || core instanceof ComponentCore
|
|
830
|
+
? core
|
|
831
|
+
: constructFunc(core, parent)[CORE]
|
|
832
|
+
),
|
|
833
|
+
entity
|
|
834
|
+
);
|
|
835
|
+
} catch (e) {
|
|
836
|
+
if (core?.component?.componentDidCatch) {
|
|
772
837
|
core.component.componentDidCatch(e);
|
|
838
|
+
} else {
|
|
839
|
+
throw e;
|
|
773
840
|
}
|
|
774
|
-
else throw(e);
|
|
775
841
|
}
|
|
776
842
|
}
|
|
777
843
|
|
|
@@ -1229,6 +1295,28 @@ export function createRoot(element)
|
|
|
1229
1295
|
}
|
|
1230
1296
|
}
|
|
1231
1297
|
|
|
1298
|
+
|
|
1299
|
+
|
|
1300
|
+
export function hotReloadRoot(rootCore, nextEntity, props) {
|
|
1301
|
+
if (!rootCore || !rootCore.component) {
|
|
1302
|
+
throw new Error("Invalid Lilact root component.");
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
const replaced = replaceComponentEntity(rootCore, nextEntity);
|
|
1306
|
+
|
|
1307
|
+
if (!replaced) {
|
|
1308
|
+
throw new Error(
|
|
1309
|
+
"Cannot hot-reload the root from a class component to a function component, or vice versa."
|
|
1310
|
+
);
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
rootCore.apply(props === undefined ? rootCore.props : props);
|
|
1314
|
+
|
|
1315
|
+
return rootCore;
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
|
|
1232
1320
|
/**
|
|
1233
1321
|
* Creates a portal — a way to render children into a DOM node
|
|
1234
1322
|
* that exists outside the current component hierarchy.
|
package/src/jsx.js
CHANGED
|
@@ -981,9 +981,6 @@ export function transpileJSX( jsx, {
|
|
|
981
981
|
injectTraceLabels = false,
|
|
982
982
|
discardComments = false,
|
|
983
983
|
produceCJS = false,
|
|
984
|
-
referentiateImports = false,
|
|
985
|
-
importsObject = "Lilact.scriptImportsObject", // first letter must be capital so components work as expected
|
|
986
|
-
importsObjectVar = "LilactImports", // first letter must be capital so components work as expected
|
|
987
984
|
logErrors = false,
|
|
988
985
|
|
|
989
986
|
// lilact internal
|
|
@@ -1086,41 +1083,26 @@ export function transpileJSX( jsx, {
|
|
|
1086
1083
|
|
|
1087
1084
|
const codify = (outlen, node, is_attr=false, is_xml=false)=> {
|
|
1088
1085
|
|
|
1089
|
-
flattened_nodes.push(node);
|
|
1090
1086
|
|
|
1091
|
-
|
|
1092
|
-
if(referentiateImports && typeof(node)==='string') {
|
|
1093
|
-
if(meta?.imported_names.has(node)) {
|
|
1094
|
-
let j = flattened_nodes.length-2;
|
|
1095
|
-
while( (typeof(flattened_nodes[j])==='string' && flattened_nodes[j].trim()==='') ||
|
|
1096
|
-
(typeof(flattened_nodes[j])==='object' && flattened_nodes[j].type==='comment') ) j--;
|
|
1087
|
+
flattened_nodes.push(node);
|
|
1097
1088
|
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
return node;
|
|
1104
|
-
}
|
|
1105
|
-
if(node===null) return '';
|
|
1089
|
+
if(typeof(node)!=='object') return node;
|
|
1090
|
+
if(!node) return '';
|
|
1106
1091
|
|
|
1107
1092
|
node.out_index = outlen;
|
|
1108
1093
|
|
|
1109
|
-
//console.log("CODIFY", node, node.out_index);
|
|
1110
|
-
|
|
1111
1094
|
if(node.type==='string') return jsx.substring(node.begin, node.end);
|
|
1112
|
-
if(node.type==='import') return
|
|
1095
|
+
if(node.type==='import') return node.cjs;
|
|
1113
1096
|
if(node.type==='export') return node.cjs;
|
|
1114
1097
|
if(node.type==='regex') return jsx.substring(node.begin, node.end);
|
|
1115
1098
|
if(node.type==='comment') return (discardComments || is_attr)?'':jsx.substring(node.begin, node.end);
|
|
1116
1099
|
if(node.type==='directive') return node.value;
|
|
1117
1100
|
|
|
1118
|
-
|
|
1119
1101
|
if(node.type==='parenthesis') {
|
|
1120
1102
|
let out = "(";
|
|
1121
1103
|
|
|
1122
1104
|
if(node.out) {
|
|
1123
|
-
if(produceCJS
|
|
1105
|
+
if(produceCJS) processImportExports(node, jsx, meta);
|
|
1124
1106
|
for(const ch of node.out) {
|
|
1125
1107
|
out+=codify(outlen+out.length-1, ch);
|
|
1126
1108
|
}
|
|
@@ -1132,7 +1114,7 @@ export function transpileJSX( jsx, {
|
|
|
1132
1114
|
let out = "";
|
|
1133
1115
|
|
|
1134
1116
|
if(node.out) {
|
|
1135
|
-
if(produceCJS
|
|
1117
|
+
if(produceCJS) processImportExports(node, jsx, meta);
|
|
1136
1118
|
for(const ch of node.out) {
|
|
1137
1119
|
if(is_xml && ch.type==='comment') continue;
|
|
1138
1120
|
out+=codify( outlen + out.length - (is_attr?1:0), ch);
|
|
@@ -1153,10 +1135,6 @@ export function transpileJSX( jsx, {
|
|
|
1153
1135
|
|
|
1154
1136
|
if(node.type==='xml') {
|
|
1155
1137
|
|
|
1156
|
-
if(referentiateImports && meta?.imported_names?.has(node.tag) && node.tag[0]===node.tag[0].toUpperCase()) {
|
|
1157
|
-
node.tag=importsObjectVar+"."+node.tag;
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
1138
|
if(node.tag.length===0) {
|
|
1161
1139
|
node.tag = fragment;
|
|
1162
1140
|
}
|
|
@@ -1207,9 +1185,6 @@ export function transpileJSX( jsx, {
|
|
|
1207
1185
|
if(injectTraceLabels) {
|
|
1208
1186
|
out=`/*LILACTBLOCK${++blocksInfo.counter}:0,0:<EXEC>*/try{`
|
|
1209
1187
|
}
|
|
1210
|
-
if(referentiateImports) {
|
|
1211
|
-
out+=`const ${importsObjectVar} = ${importsObject};`;
|
|
1212
|
-
}
|
|
1213
1188
|
out+=codify(out.length, json);
|
|
1214
1189
|
|
|
1215
1190
|
if(injectTraceLabels) {
|
|
@@ -1225,7 +1200,7 @@ export function transpileJSX( jsx, {
|
|
|
1225
1200
|
if(appendSourcemap) {
|
|
1226
1201
|
out += inline_sm;
|
|
1227
1202
|
}
|
|
1228
|
-
//console.log(out);
|
|
1203
|
+
// console.log(out);
|
|
1229
1204
|
|
|
1230
1205
|
return out;
|
|
1231
1206
|
}
|
package/src/lilact.jsx
CHANGED
package/src/run.jsx
CHANGED
|
@@ -172,11 +172,11 @@ function loadModule(path, options = {}) {
|
|
|
172
172
|
if (loadAsync) {
|
|
173
173
|
Lilact[LAZY] = false;
|
|
174
174
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
175
|
+
if (module.request && !options.forceReload) {
|
|
176
|
+
return module.request;
|
|
177
|
+
}
|
|
178
178
|
|
|
179
|
-
|
|
179
|
+
return loadAsyncResource(path, module, options);
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
const resolved = Lilact.resolver?.(path);
|
|
@@ -244,58 +244,52 @@ export function require(path)
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
|
|
247
|
-
function makeImportsObject(mod)
|
|
248
|
-
{
|
|
249
|
-
mod.importsObject = {};
|
|
247
|
+
function makeImportsObject(mod, options = {}) {
|
|
248
|
+
mod.importsObject = {};
|
|
250
249
|
|
|
251
|
-
|
|
252
|
-
|
|
250
|
+
for (const path in mod.meta.imports) {
|
|
251
|
+
const imps = mod.meta.imports[path];
|
|
253
252
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
const exps = loadModule(path, {
|
|
259
|
-
requirer: mod,
|
|
260
|
-
});
|
|
253
|
+
const exps = loadModule(path, {
|
|
254
|
+
requirer: mod,
|
|
255
|
+
forceReload: options.forceReload,
|
|
256
|
+
});
|
|
261
257
|
|
|
262
|
-
|
|
263
|
-
|
|
258
|
+
for (const i in imps.named_imports) {
|
|
259
|
+
if (i === '') continue;
|
|
264
260
|
|
|
265
|
-
|
|
261
|
+
const exportedName = imps.named_imports[i];
|
|
266
262
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
263
|
+
if (!Object.prototype.hasOwnProperty.call(exps, exportedName)) {
|
|
264
|
+
throw new Error(
|
|
265
|
+
`Imported module does not export any "${i}".`
|
|
266
|
+
);
|
|
267
|
+
}
|
|
272
268
|
|
|
273
|
-
|
|
274
|
-
|
|
269
|
+
mod.importsObject[i] = exps[exportedName];
|
|
270
|
+
}
|
|
275
271
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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
|
+
}
|
|
282
278
|
|
|
283
|
-
|
|
284
|
-
|
|
279
|
+
mod.importsObject[i] = exps.default;
|
|
280
|
+
}
|
|
285
281
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
282
|
+
for (const i of imps.import_stars) {
|
|
283
|
+
mod.importsObject[i] = { ...exps };
|
|
284
|
+
}
|
|
285
|
+
}
|
|
290
286
|
}
|
|
291
287
|
|
|
292
|
-
// ERROR IS FOUND WHEN run IS CALLED, AND NOT REQUIRE.
|
|
293
|
-
// REQUIRE REWRITES MODULE ANYWAY. THAT IS ALSO A PROBLEM.
|
|
294
288
|
|
|
295
289
|
export function run(
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
290
|
+
jsx,
|
|
291
|
+
path = `InlineJSX-${++Lilact.eval_num}`,
|
|
292
|
+
options = {}
|
|
299
293
|
) {
|
|
300
294
|
let module = required_scripts[path];
|
|
301
295
|
|
|
@@ -320,7 +314,6 @@ export function run(
|
|
|
320
314
|
module.exports = {};
|
|
321
315
|
module.loaded = false;
|
|
322
316
|
module.error = undefined;
|
|
323
|
-
module.importsObject = undefined;
|
|
324
317
|
module.meta = {};
|
|
325
318
|
}
|
|
326
319
|
|
|
@@ -334,8 +327,7 @@ export function run(
|
|
|
334
327
|
factory: "createComponent",
|
|
335
328
|
appendSourcemap: true,
|
|
336
329
|
injectTraceLabels: true,
|
|
337
|
-
produceCJS:
|
|
338
|
-
referentiateImports: true,
|
|
330
|
+
produceCJS: true,
|
|
339
331
|
blocksInfo: Lilact.blocksInfo,
|
|
340
332
|
});
|
|
341
333
|
}
|
|
@@ -363,9 +355,6 @@ export function run(
|
|
|
363
355
|
globalThis.createComponent = Lilact.createComponent;
|
|
364
356
|
globalThis.Fragment = Lilact.Fragment;
|
|
365
357
|
|
|
366
|
-
makeImportsObject(module);
|
|
367
|
-
|
|
368
|
-
Lilact.scriptImportsObject = module.importsObject;
|
|
369
358
|
const result = eval(processed);
|
|
370
359
|
module.loaded = true;
|
|
371
360
|
|
|
@@ -383,7 +372,8 @@ function getOrCreateModule(path, options = {}) {
|
|
|
383
372
|
return required_scripts[path] || createModule(path, options);
|
|
384
373
|
}
|
|
385
374
|
|
|
386
|
-
function loadAsyncResource(path, module)
|
|
375
|
+
function loadAsyncResource(path, module, options = {})
|
|
376
|
+
{
|
|
387
377
|
let source;
|
|
388
378
|
|
|
389
379
|
try {
|
|
@@ -429,7 +419,7 @@ function loadAsyncResource(path, module) {
|
|
|
429
419
|
return undefined;
|
|
430
420
|
}
|
|
431
421
|
|
|
432
|
-
return run(module.code, path,
|
|
422
|
+
return run(module.code, path, options);
|
|
433
423
|
})
|
|
434
424
|
.then(result => result?.default ?? result)
|
|
435
425
|
.catch(error => {
|