lilact 0.21.1 → 0.23.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 (120) hide show
  1. package/README.md +17 -4
  2. package/dist/lilact.development.js +498 -38
  3. package/dist/lilact.development.js.map +4 -4
  4. package/dist/lilact.development.min.js +34 -23
  5. package/dist/lilact.development.min.js.map +4 -4
  6. package/dist/lilact.production.min.js +33 -22
  7. package/docs/assets/hierarchy.js +1 -1
  8. package/docs/assets/highlight.css +20 -20
  9. package/docs/assets/navigation.js +1 -1
  10. package/docs/assets/search.js +1 -1
  11. package/docs/classes/accessories.ErrorBoundary.html +8 -8
  12. package/docs/classes/accessories.Suspense.html +7 -7
  13. package/docs/classes/components.Component.html +11 -11
  14. package/docs/classes/components.HTMLComponent.html +12 -12
  15. package/docs/classes/components.RootComponent.html +12 -12
  16. package/docs/functions/components.cloneComponent.html +1 -0
  17. package/docs/functions/components.createComponent.html +1 -1
  18. package/docs/functions/components.createPortal.html +1 -1
  19. package/docs/functions/components.createRoot.html +1 -1
  20. package/docs/functions/components.memo.html +1 -1
  21. package/docs/functions/components.render.html +1 -1
  22. package/docs/functions/run.lazy.html +7 -1
  23. package/docs/functions/run.require.html +5 -9
  24. package/docs/functions/run.run.html +1 -1
  25. package/docs/functions/run.runScripts.html +1 -1
  26. package/docs/functions/timers.animationFramePromise.html +1 -1
  27. package/docs/functions/timers.clearInterval.html +1 -1
  28. package/docs/functions/timers.clearTimeout.html +1 -1
  29. package/docs/functions/timers.grabTimers.html +1 -1
  30. package/docs/functions/timers.pauseTimers.html +1 -1
  31. package/docs/functions/timers.releaseTimers.html +1 -1
  32. package/docs/functions/timers.resetTimers.html +1 -1
  33. package/docs/functions/timers.resumeTimers.html +1 -1
  34. package/docs/functions/timers.setInterval.html +1 -1
  35. package/docs/functions/timers.setTimeout.html +1 -1
  36. package/docs/functions/timers.timeoutPromise.html +6 -6
  37. package/docs/hierarchy.html +1 -1
  38. package/docs/index.html +17 -10
  39. package/docs/modules/components.html +1 -1
  40. package/docs/static/demos/actionstate.jsx +2 -2
  41. package/docs/static/demos/capture.jsx +2 -2
  42. package/docs/static/demos/cloneelement.jsx +66 -0
  43. package/docs/static/demos/context.jsx +3 -3
  44. package/docs/static/demos/css-transition.jsx +3 -3
  45. package/docs/static/demos/error-boundary.jsx +2 -2
  46. package/docs/static/demos/error-callback.jsx +1 -1
  47. package/docs/static/demos/error-component-stack.jsx +2 -2
  48. package/docs/static/demos/error-init.jsx +1 -1
  49. package/docs/static/demos/error-parser.jsx +1 -1
  50. package/docs/static/demos/form-elements.jsx +1 -1
  51. package/docs/static/demos/forwardref.jsx +2 -2
  52. package/docs/static/demos/lazy.jsx +3 -3
  53. package/docs/static/demos/legacy-context.jsx +2 -2
  54. package/docs/static/demos/memo.jsx +2 -2
  55. package/docs/static/demos/modal.jsx +2 -2
  56. package/docs/static/demos/pane.jsx +2 -2
  57. package/docs/static/demos/portal.jsx +4 -2
  58. package/docs/static/demos/priorities.jsx +2 -2
  59. package/docs/static/demos/proptypes.jsx +2 -2
  60. package/docs/static/demos/reducer.jsx +4 -2
  61. package/docs/static/demos/redux.jsx +3 -3
  62. package/docs/static/demos/router.jsx +3 -3
  63. package/docs/static/demos/stopwatch.jsx +2 -2
  64. package/docs/static/demos/suspense.jsx +2 -2
  65. package/docs/static/demos/switch-transition.jsx +2 -2
  66. package/docs/static/demos/transition.jsx +2 -2
  67. package/docs/static/demos/usedefered.jsx +2 -2
  68. package/docs/static/demos/usetransition.jsx +3 -3
  69. package/docs/static/index.html +34 -33
  70. package/docs/static/lilact.development.js +498 -38
  71. package/docs/static/lilact.development.js.map +4 -4
  72. package/docs/static/lilact.development.min.js +34 -23
  73. package/docs/static/lilact.development.min.js.map +4 -4
  74. package/docs/static/lilact.production.min.js +33 -22
  75. package/docs/variables/accessories.SplitPane.html +1 -1
  76. package/docs/variables/components.cloneElement.html +1 -0
  77. package/examples/demos/actionstate.jsx +2 -2
  78. package/examples/demos/capture.jsx +2 -2
  79. package/examples/demos/cloneelement.jsx +66 -0
  80. package/examples/demos/context.jsx +3 -3
  81. package/examples/demos/css-transition.jsx +3 -3
  82. package/examples/demos/error-boundary.jsx +2 -2
  83. package/examples/demos/error-callback.jsx +1 -1
  84. package/examples/demos/error-component-stack.jsx +2 -2
  85. package/examples/demos/error-init.jsx +1 -1
  86. package/examples/demos/error-parser.jsx +1 -1
  87. package/examples/demos/form-elements.jsx +1 -1
  88. package/examples/demos/forwardref.jsx +2 -2
  89. package/examples/demos/lazy.jsx +3 -3
  90. package/examples/demos/legacy-context.jsx +2 -2
  91. package/examples/demos/memo.jsx +2 -2
  92. package/examples/demos/modal.jsx +2 -2
  93. package/examples/demos/pane.jsx +2 -2
  94. package/examples/demos/portal.jsx +4 -2
  95. package/examples/demos/priorities.jsx +2 -2
  96. package/examples/demos/proptypes.jsx +2 -2
  97. package/examples/demos/reducer.jsx +4 -2
  98. package/examples/demos/redux.jsx +3 -3
  99. package/examples/demos/router.jsx +3 -3
  100. package/examples/demos/stopwatch.jsx +2 -2
  101. package/examples/demos/suspense.jsx +2 -2
  102. package/examples/demos/switch-transition.jsx +2 -2
  103. package/examples/demos/transition.jsx +2 -2
  104. package/examples/demos/usedefered.jsx +2 -2
  105. package/examples/demos/usetransition.jsx +3 -3
  106. package/examples/index.html +34 -33
  107. package/examples/lilact.development.js +498 -38
  108. package/examples/lilact.development.js.map +4 -4
  109. package/examples/lilact.development.min.js +34 -23
  110. package/examples/lilact.development.min.js.map +4 -4
  111. package/examples/lilact.production.min.js +33 -22
  112. package/impexptest.js +51 -0
  113. package/package.json +4 -4
  114. package/src/components.jsx +7 -5
  115. package/src/expscan.js +408 -0
  116. package/src/jsx.js +26 -28
  117. package/src/lilact.jsx +12 -3
  118. package/src/run.jsx +92 -45
  119. package/src/timers.jsx +0 -5
  120. package/src/jsx.addons.js +0 -70
package/src/lilact.jsx CHANGED
@@ -92,7 +92,7 @@ export {transpileJSX, transpilerConfig} from "./jsx";
92
92
  export const Lilact =
93
93
  {
94
94
 
95
- VERSION: "beta.21",
95
+ VERSION: "beta.23",
96
96
 
97
97
  // Configuration
98
98
 
@@ -125,9 +125,20 @@ export const Lilact =
125
125
 
126
126
  }
127
127
 
128
+ Lilact.default = Lilact;
129
+
130
+ export default Lilact;
131
+
132
+ Lilact.importObjectPaths = {
133
+ "lilact": Lilact,
134
+ "@emotion/css": Lilact.emotion,
135
+ "redux": Lilact.redux
136
+ }
137
+
128
138
  globalThis.Lilact = Lilact;
129
139
  globalThis.createComponent = Lilact.createComponent;
130
140
  globalThis.Fragment = Lilact.Fragment;
141
+ globalThis.require = Lilact.require;
131
142
 
132
143
  document.addEventListener('DOMContentLoaded', () => {
133
144
  Lilact.runScripts();
@@ -144,5 +155,3 @@ if(DEBUG) {
144
155
  console.log(`Copyright(C) 2024-2026 Arash Kazemi <contact.arash.kazemi@gmail.com>`);
145
156
  }
146
157
 
147
- export default Lilact;
148
-
package/src/run.jsx CHANGED
@@ -32,6 +32,33 @@ import Lilact from './lilact.jsx';
32
32
  import { CORE, COMPONENT, LAZY } from "./symbols.jsx"
33
33
 
34
34
 
35
+ function joinPaths(basePath, relativePath) {
36
+ const isAbs = relativePath.startsWith("/");
37
+ const stack = [];
38
+
39
+ const parts = (isAbs ? "" : basePath).split("/").filter(Boolean);
40
+ for (const p of parts) stack.push(p);
41
+
42
+ if(!basePath.endsWith("/")) stack.pop();
43
+
44
+ const relParts = relativePath.split("/");
45
+
46
+ for (const p of relParts) {
47
+ if (p === "" || p === ".") continue;
48
+ if (p === "..") {
49
+ if (stack.length > 0) stack.pop();
50
+ } else {
51
+ stack.push(p);
52
+ }
53
+ }
54
+
55
+ return (isAbs ? "/" : "") + stack.join("/");
56
+ }
57
+
58
+ // Examples:
59
+ //console.log(joinPaths("a/b/c", "./../d")); // a/b/dfdsfds
60
+ //console.log(joinPaths("a/b/c", "../../d")); // a/d
61
+
35
62
  /** @ignore */
36
63
  export const required_scripts = {};
37
64
 
@@ -48,18 +75,19 @@ export const required_scripts = {};
48
75
  export function run(jsx, path=`InlineJSX-${++Lilact.eval_num}`, is_inline=true)
49
76
  {
50
77
  const mappings = [];
51
- const module = {exports: {}};
52
- let processed;
53
-
54
-
55
- required_scripts[path] = {
78
+ const module = {
56
79
  mappings,
57
- module,
58
80
  is_inline,
59
81
  path,
60
82
  code: jsx,
83
+ exports: {}
61
84
  };
62
85
 
86
+ let processed;
87
+
88
+
89
+ required_scripts[path] = module;
90
+
63
91
 
64
92
  try {
65
93
  processed = Lilact.transpileJSX( jsx,
@@ -71,6 +99,7 @@ export function run(jsx, path=`InlineJSX-${++Lilact.eval_num}`, is_inline=true)
71
99
  blocks_info: Lilact.blocks_info,
72
100
 
73
101
  injectTraceLabels: true,
102
+ produceCJS: true,
74
103
  } );
75
104
  }
76
105
  catch(e) {
@@ -80,7 +109,7 @@ export function run(jsx, path=`InlineJSX-${++Lilact.eval_num}`, is_inline=true)
80
109
  }
81
110
 
82
111
  if(DEBUG) {
83
- required_scripts[path].processed = processed;
112
+ required_scripts[path].processed = processed;
84
113
  }
85
114
 
86
115
  processed += "\n//# sourceURL=eval:/" + path;
@@ -106,31 +135,35 @@ if(DEBUG) {
106
135
 
107
136
 
108
137
  /**
109
- * Loads a jsx script from a path. All scripts can access Lilact namespace as a global object.
110
- *
111
- * `require` loads synchronously, as it is expected to be loaded on the next instruction.
112
- *
113
- * As running the transpiled scripts rely on `new Function`, it is not possible to use module imports
114
- * and exports. So to import you should use `const {useState} = Lilact` convention. And to
115
- * export, you should use `module.exports = ...`. `require` returns `module.exports` value
116
- * so you can import different modules using the convention above.
138
+ * Loads a jsx script from a path. `require` loads synchronously, as it is expected to be loaded on the next instruction.
117
139
  *
118
140
  * If the path is in the format #id, it will query the document for a script element with the given
119
141
  * id and run its contents.
120
142
  *
121
143
  * If require is called inside the function given to lazy, it will run async. See `lazy`.
122
144
  *
145
+ * All required scripts can access Lilact namespace as a global object.
146
+ *
123
147
  * @param path - The path to the required file. Must be either absolute path or relative to the current
124
- * document’s URL (the page/location that initiated the request).
148
+ * module or document’s URL (the page/location that initiated the request).
149
+ *
150
+ * @param [forceUpdate] - Force re-run module. By default an imported module is only run once.
151
+ *
152
+ * @param [checkExport] - An array of module properties to be checked upon import. This is used for import error detection.
153
+ *
154
+ * @param [isLazy] - if loading is should be async. Returns a promise if true.
125
155
  *
126
- * @param forceUpdate - To treat the code as inline. The main difference at the moment is that inline code doesn't include sourcemap.
156
+ * @param [requirer] - The module that is importing the other module. This is used internally to resolve relative paths.
127
157
  *
128
158
  * @returns An array representation of the children.
129
159
  */
130
- export function require(path, forceUpdate)
160
+ export function require(path, {forceUpdate, checkExport, requirer, isLazy})
131
161
  {
132
- if(required_scripts[path] && !forceUpdate) return required_scripts[path].module.exports;
162
+
163
+ if(Lilact.importObjectPaths?.[path]) return Lilact.importObjectPaths[path];
164
+ if(required_scripts[path] && !forceUpdate) return required_scripts[path].exports;
133
165
 
166
+
134
167
  if(path[0]==='#') {
135
168
 
136
169
  const el = document.getElementById(path);
@@ -140,32 +173,38 @@ export function require(path, forceUpdate)
140
173
  }
141
174
 
142
175
  }
143
- else if(Lilact?.[LAZY]) {
144
- Lilact[LAZY]=false;
145
-
146
- return fetch(path)
147
- .then(res => {
148
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
149
- return res.text();
150
- })
151
- .then(res => {
152
- res = run(res, path, false);
153
- // todo: this is for the lazy, so we detect default, should we do it in sync mode too?
154
- return res?.default ?? res;
155
- })
156
- .catch(err => {
157
- throw err;
158
- });
159
- }
160
176
  else {
161
- // note: this makes a sync request. this is not advised,
162
- // but import should be sync. for an async solution use lazy and suspense.
163
-
164
- const request = new XMLHttpRequest();
165
- request.open("GET", path, false);
166
- request.send(null);
167
- if (request.status === 200) {
168
- return run(request.responseText, path, false);
177
+ if(requirer && requirer.path) {
178
+ path = joinPaths(requirer.path, path);
179
+ }
180
+
181
+ if(Lilact?.[LAZY] || isLazy) {
182
+ Lilact[LAZY]=false;
183
+
184
+ return fetch(path)
185
+ .then(res => {
186
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
187
+ return res.text();
188
+ })
189
+ .then(res => {
190
+ res = run(res, path, false);
191
+ // todo: this is for the lazy, so we detect default to match react behaviour, but should we do it in sync mode too?
192
+ return res?.default ?? res;
193
+ })
194
+ .catch(err => {
195
+ throw err;
196
+ });
197
+ }
198
+ else {
199
+ // note: this makes a sync request. this is not advised,
200
+ // but import should be sync. for an async solution use lazy and suspense.
201
+
202
+ const request = new XMLHttpRequest();
203
+ request.open("GET", path, false);
204
+ request.send(null);
205
+ if (request.status === 200) {
206
+ return run(request.responseText, path, false);
207
+ }
169
208
  }
170
209
  }
171
210
 
@@ -176,7 +215,15 @@ export function require(path, forceUpdate)
176
215
  /**
177
216
  * Wrapper that enables async, code-split component loading. `lazy` should be used
178
217
  * outside the component definintion or it will produce new components on each rerender.
179
- *
218
+ *
219
+ * Note that in factory function you should use require instead of `import`. Dynamic `import`
220
+ * would work, but it will not be wired correctly to the `Lilact` runtime.
221
+ *
222
+ * Example:
223
+ * ```
224
+ * const StopWatch = lazy( () => require('./stopwatch.jsx') );
225
+ * ```
226
+ *
180
227
  * @param factory - A function with **no arguments** that returns a `Promise`.
181
228
  * The promise must resolve to a module whose module.exports.default is a Lilact component
182
229
  * or otherwise it will be whatever the module.exports is set to.
package/src/timers.jsx CHANGED
@@ -28,11 +28,6 @@
28
28
 
29
29
  */
30
30
 
31
- // note: lilact timers can be used without lilact. uncomment the directive below to
32
- // get the transpiled version in dist directory.
33
- //ʔ outputJS('./dist/timers.js');
34
-
35
-
36
31
  import { IDX, DUE, REPEAT, CLEARED, INTERVAL, CALLBACK, ARGS } from "./symbols.jsx"
37
32
 
38
33
  /**
package/src/jsx.addons.js DELETED
@@ -1,70 +0,0 @@
1
- /*
2
-
3
- Lilact
4
- Copyright (C) 2024-2026 Arash Kazemi <contact.arash.kazemi@gmail.com>
5
- All rights reserved.
6
-
7
- BSD-2-Clause
8
-
9
- Redistribution and use in source and binary forms, with or without
10
- modification, are permitted provided that the following conditions are met:
11
-
12
- * Redistributions of source code must retain the above copyright
13
- notice, this list of conditions and the following disclaimer.
14
- * Redistributions in binary form must reproduce the above copyright
15
- notice, this list of conditions and the following disclaimer in the
16
- documentation and/or other materials provided with the distribution.
17
-
18
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
- ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
22
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
-
29
- */
30
-
31
- const TRANSPILER_OUTPUT = Symbol.for("LILACT:TRANSPILER_OUTPUT");
32
-
33
-
34
- export function defineSymbols(ns, defs) {
35
-
36
- if(defs===undefined) {
37
- defs=ns;
38
- ns='';
39
- }
40
- else ns+=':';
41
-
42
- const out = [];
43
- const lbls = [];
44
- if(defs instanceof Array) {
45
- if(ns!=='') {
46
- if(typeof(ns)!=='string') ns='';
47
- for(let d of defs) {
48
- lbls.push(d);
49
- out.push(`Symbol.for('${ns}${d}')`);
50
- }
51
- }
52
- else {
53
- for(const d of defs) {
54
- lbls.push(d);
55
- out.push(`Symbol()`);
56
- }
57
- }
58
- return `const [${lbls.join(',')}]=[${out.join(',')}];`;
59
- }
60
- }
61
-
62
- export const quote = (x)=>`"${String(x).replace(/(["\n])/g, '\\$1')}"`;
63
-
64
-
65
- // note: this directive is used for files that can be used separatly (i.e. timers.jsx)
66
- // or in case you want to check the preprocessors output.
67
-
68
- export function outputJS(filepath) {
69
- globalThis[TRANSPILER_OUTPUT] = filepath;
70
- }