lilact 0.29.3 → 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.
Files changed (41) hide show
  1. package/dist/lilact.development.js +50 -58
  2. package/dist/lilact.development.js.map +2 -2
  3. package/dist/lilact.development.min.js +23 -23
  4. package/dist/lilact.development.min.js.map +3 -3
  5. package/dist/lilact.production.min.js +23 -23
  6. package/docs/assets/hierarchy.js +1 -1
  7. package/docs/assets/navigation.js +1 -1
  8. package/docs/assets/search.js +1 -1
  9. package/docs/classes/accessories.ErrorBoundary.html +8 -8
  10. package/docs/classes/accessories.Suspense.html +7 -7
  11. package/docs/classes/components.Component.html +11 -11
  12. package/docs/classes/components.HTMLComponent.html +11 -11
  13. package/docs/classes/components.RootComponent.html +11 -11
  14. package/docs/functions/components.cloneComponent.html +1 -1
  15. package/docs/functions/components.createComponent.html +1 -1
  16. package/docs/functions/components.createPortal.html +1 -1
  17. package/docs/functions/components.createRoot.html +1 -1
  18. package/docs/functions/components.hotReloadRoot.html +1 -0
  19. package/docs/functions/components.memo.html +1 -1
  20. package/docs/functions/components.render.html +1 -1
  21. package/docs/functions/components.replaceComponentEntity.html +1 -0
  22. package/docs/functions/run.lazy.html +1 -1
  23. package/docs/functions/run.runScripts.html +1 -1
  24. package/docs/hierarchy.html +1 -1
  25. package/docs/modules/components.html +1 -1
  26. package/docs/static/lilact.development.js +50 -58
  27. package/docs/static/lilact.development.js.map +2 -2
  28. package/docs/static/lilact.development.min.js +23 -23
  29. package/docs/static/lilact.development.min.js.map +3 -3
  30. package/docs/static/lilact.production.min.js +23 -23
  31. package/docs/variables/components.cloneElement.html +1 -1
  32. package/examples/lilact.development.js +50 -58
  33. package/examples/lilact.development.js.map +2 -2
  34. package/examples/lilact.development.min.js +23 -23
  35. package/examples/lilact.development.min.js.map +3 -3
  36. package/examples/lilact.production.min.js +23 -23
  37. package/package.json +1 -1
  38. package/src/components.jsx +103 -79
  39. package/src/jsx.js +7 -32
  40. package/src/lilact.jsx +1 -1
  41. package/src/run.jsx +1 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lilact",
3
- "version": "0.29.3",
3
+ "version": "0.30.0",
4
4
  "description": "A Little React/JSX Runtime Implementation for Browser",
5
5
  "repository": "github:arashkazemi/lilact",
6
6
  "homepage": "https://arashkazemi.github.io/lilact/",
@@ -39,45 +39,48 @@ const SVG_NS = "http://www.w3.org/2000/svg";
39
39
 
40
40
 
41
41
  function getComponentEntity(entity) {
42
- return entity?.[MEMOIZED]
43
- ? entity.component
44
- : entity;
42
+ return entity?.[MEMOIZED]
43
+ ? entity.component
44
+ : entity;
45
45
  }
46
46
 
47
- function replaceComponentEntity(comp, nextEntity) {
48
- const core = comp?.[CORE];
47
+ export function replaceComponentEntity(componentCore, nextEntity) {
48
+ if (!componentCore || typeof nextEntity !== "function") {
49
+ return false;
50
+ }
49
51
 
50
- if (!core || typeof nextEntity !== "function") {
51
- return;
52
- }
52
+ const oldEntity = getComponentEntity(componentCore.entity);
53
+ const newEntity = getComponentEntity(nextEntity);
53
54
 
54
- const oldEntity = getComponentEntity(core.entity);
55
- const newEntity = getComponentEntity(nextEntity);
55
+ if (oldEntity === newEntity) {
56
+ return true;
57
+ }
56
58
 
57
- if (oldEntity === newEntity) {
58
- return;
59
- }
59
+ const component = componentCore.component;
60
60
 
61
- const oldIsClass = isClass(oldEntity);
62
- const newIsClass = isClass(newEntity);
61
+ if (!component) {
62
+ return false;
63
+ }
63
64
 
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
- }
65
+ const oldIsClass = isClass(oldEntity);
66
+ const newIsClass = isClass(newEntity);
69
67
 
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
- }
68
+ // A function component cannot reuse a class instance, and vice versa.
69
+ if (oldIsClass !== newIsClass) {
70
+ return false;
71
+ }
78
72
 
79
- core.entity = newEntity;
80
- return true;
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;
81
84
  }
82
85
 
83
86
 
@@ -99,48 +102,46 @@ class ComponentCache
99
102
  }
100
103
 
101
104
  pick(key, construct_func, nextEntity) {
102
- let comp;
105
+ let componentCore;
103
106
  let bucket = this.current_map.get(key);
104
- const reusable =
105
- bucket && bucket.length > bucket[IDX];
106
107
 
107
- if (reusable) {
108
- comp = bucket[bucket[IDX]];
108
+ if (bucket && bucket.length > bucket[IDX]) {
109
+ componentCore = bucket[bucket[IDX]];
109
110
  bucket[IDX]++;
110
111
 
111
- const oldEntity = getComponentEntity(comp?.[CORE]?.entity);
112
+ const oldEntity = getComponentEntity(componentCore.entity);
112
113
  const newEntity = getComponentEntity(nextEntity);
113
114
 
114
115
  const incompatible =
115
- typeof oldEntity === "function" &&
116
- typeof newEntity === "function" &&
117
- isClass(oldEntity) !== isClass(newEntity);
116
+ typeof oldEntity === "function" &&
117
+ typeof newEntity === "function" &&
118
+ isClass(oldEntity) !== isClass(newEntity);
118
119
 
119
120
  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);
121
+ componentCore = construct_func();
122
+ }
123
+ else if (newEntity) {
124
+ replaceComponentEntity(componentCore, newEntity);
124
125
  }
125
126
  } else {
126
- comp = construct_func();
127
+ componentCore = construct_func();
127
128
  }
128
129
 
129
130
  bucket = this.new_map.get(key);
130
131
 
131
- if (bucket !== undefined) {
132
- bucket.push(comp);
132
+ if (bucket) {
133
+ bucket.push(componentCore);
133
134
  } else {
134
- bucket = [comp];
135
+ bucket = [componentCore];
135
136
  this.new_map.set(key, bucket);
136
137
  bucket[IDX] = 0;
137
138
  }
138
139
 
139
- if (comp[CORE]) {
140
- comp[CORE].parent ??= this.owner;
140
+ if (componentCore) {
141
+ componentCore.parent ??= this.owner;
141
142
  }
142
143
 
143
- return comp;
144
+ return componentCore;
144
145
  }
145
146
 
146
147
  commit()
@@ -807,36 +808,37 @@ function constructFunc(core, parent) // returns {text} or component, and not com
807
808
  return comp;
808
809
  }
809
810
 
810
-
811
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
- }
812
+ try {
813
+ parent.cache ??= new ComponentCache(parent);
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) {
837
+ core.component.componentDidCatch(e);
838
+ } else {
839
+ throw e;
840
+ }
841
+ }
840
842
  }
841
843
 
842
844
 
@@ -1293,6 +1295,28 @@ export function createRoot(element)
1293
1295
  }
1294
1296
  }
1295
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
+
1296
1320
  /**
1297
1321
  * Creates a portal — a way to render children into a DOM node
1298
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
- if(typeof(node)!=='object') {
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
- if( typeof(flattened_nodes[j])!=='string' || flattened_nodes[j]!==".") {
1099
- return importsObjectVar+"."+node;
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 referentiateImports?'':node.cjs;
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 || referentiateImports) processImportExports(node, jsx, meta);
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 || referentiateImports) processImportExports(node, jsx, meta);
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
@@ -94,7 +94,7 @@ export {transpileJSX, transpilerConfig} from "./jsx";
94
94
  export const Lilact =
95
95
  {
96
96
 
97
- VERSION: "RC.5",
97
+ VERSION: "RC.6",
98
98
 
99
99
  // Configuration
100
100
 
package/src/run.jsx CHANGED
@@ -314,7 +314,6 @@ export function run(
314
314
  module.exports = {};
315
315
  module.loaded = false;
316
316
  module.error = undefined;
317
- module.importsObject = undefined;
318
317
  module.meta = {};
319
318
  }
320
319
 
@@ -328,8 +327,7 @@ export function run(
328
327
  factory: "createComponent",
329
328
  appendSourcemap: true,
330
329
  injectTraceLabels: true,
331
- produceCJS: false,
332
- referentiateImports: true,
330
+ produceCJS: true,
333
331
  blocksInfo: Lilact.blocksInfo,
334
332
  });
335
333
  }
@@ -357,9 +355,6 @@ export function run(
357
355
  globalThis.createComponent = Lilact.createComponent;
358
356
  globalThis.Fragment = Lilact.Fragment;
359
357
 
360
- makeImportsObject(module, options);
361
-
362
- Lilact.scriptImportsObject = module.importsObject;
363
358
  const result = eval(processed);
364
359
  module.loaded = true;
365
360