@cilix/lightjs 0.0.5 → 0.0.7
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/core.js +115 -36
- package/index.js +13 -3
- package/package.json +1 -1
package/core.js
CHANGED
|
@@ -19,11 +19,9 @@
|
|
|
19
19
|
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
const path = require("path");
|
|
24
|
-
|
|
25
|
-
module.exports = (config) => {
|
|
22
|
+
module.exports = (config, fs, path) => {
|
|
26
23
|
const _files = {};
|
|
24
|
+
let includeRuntime;
|
|
27
25
|
|
|
28
26
|
function throw_error (err) {
|
|
29
27
|
err.origin = 'light';
|
|
@@ -351,7 +349,9 @@ module.exports = (config) => {
|
|
|
351
349
|
"let",
|
|
352
350
|
"nosync",
|
|
353
351
|
"as",
|
|
354
|
-
"global"
|
|
352
|
+
"global",
|
|
353
|
+
"when",
|
|
354
|
+
"catch"
|
|
355
355
|
];
|
|
356
356
|
|
|
357
357
|
let symbols = [
|
|
@@ -661,10 +661,15 @@ module.exports = (config) => {
|
|
|
661
661
|
const parse = (tokens) => {
|
|
662
662
|
let tok = tokens[0];
|
|
663
663
|
let cursor = 0;
|
|
664
|
-
let in_tag = false;
|
|
665
664
|
let ast = { type: 'file', data: { file: tok.file }, children: [] };
|
|
666
665
|
let parent = ast;
|
|
667
666
|
|
|
667
|
+
const parse_state = {
|
|
668
|
+
in_tag: false,
|
|
669
|
+
if_depth: 0,
|
|
670
|
+
each_depth: 0
|
|
671
|
+
};
|
|
672
|
+
|
|
668
673
|
function ast_node(type, data) {
|
|
669
674
|
let node = { type, data, children: [] };
|
|
670
675
|
parent.children.push(node);
|
|
@@ -1014,6 +1019,7 @@ module.exports = (config) => {
|
|
|
1014
1019
|
attr[key] = { type: "bool", data: true };
|
|
1015
1020
|
}
|
|
1016
1021
|
} else if (accept("on")) {
|
|
1022
|
+
includeRuntime = true;
|
|
1017
1023
|
expect(":");
|
|
1018
1024
|
let handler;
|
|
1019
1025
|
let evt = tok.data;
|
|
@@ -1030,9 +1036,9 @@ module.exports = (config) => {
|
|
|
1030
1036
|
}
|
|
1031
1037
|
|
|
1032
1038
|
function parse_custom_tag_body () {
|
|
1033
|
-
in_tag = true;
|
|
1039
|
+
parse_state.in_tag = true;
|
|
1034
1040
|
parse_tag_list();
|
|
1035
|
-
in_tag = false;
|
|
1041
|
+
parse_state.in_tag = false;
|
|
1036
1042
|
}
|
|
1037
1043
|
|
|
1038
1044
|
function parse_tag() {
|
|
@@ -1084,6 +1090,7 @@ module.exports = (config) => {
|
|
|
1084
1090
|
}
|
|
1085
1091
|
|
|
1086
1092
|
function parse_if_statement() {
|
|
1093
|
+
parse_state.if_depth++;
|
|
1087
1094
|
expect("(");
|
|
1088
1095
|
let condition = parse_expr();
|
|
1089
1096
|
expect(")");
|
|
@@ -1112,13 +1119,68 @@ module.exports = (config) => {
|
|
|
1112
1119
|
}
|
|
1113
1120
|
}
|
|
1114
1121
|
parent = current;
|
|
1122
|
+
parse_state.if_depth--;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
function parse_when_statement() {
|
|
1126
|
+
if (parse_state.each_depth > 0) {
|
|
1127
|
+
throw_error({
|
|
1128
|
+
msg: 'when cannot be nested in each',
|
|
1129
|
+
pos: tok.pos,
|
|
1130
|
+
file: tok.file
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
if (parse_state.if_depth > 0) {
|
|
1134
|
+
throw_error({
|
|
1135
|
+
msg: 'when cannot be nested in if',
|
|
1136
|
+
pos: tok.pos,
|
|
1137
|
+
file: tok.file
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1140
|
+
expect("(");
|
|
1141
|
+
let condition = parse_expr();
|
|
1142
|
+
expect(")");
|
|
1143
|
+
let current = parent;
|
|
1144
|
+
let node = ast_node('when', condition);
|
|
1145
|
+
parent = node;
|
|
1146
|
+
let pass = ast_node('block');
|
|
1147
|
+
parent = pass;
|
|
1148
|
+
if (accept("[")) {
|
|
1149
|
+
parse_tag_list();
|
|
1150
|
+
expect("]");
|
|
1151
|
+
} else {
|
|
1152
|
+
parse_tag();
|
|
1153
|
+
}
|
|
1154
|
+
expect("else");
|
|
1155
|
+
parent = node;
|
|
1156
|
+
let fail = ast_node('block');
|
|
1157
|
+
parent = fail;
|
|
1158
|
+
if (accept("[")) {
|
|
1159
|
+
parse_tag_list();
|
|
1160
|
+
expect("]");
|
|
1161
|
+
} else {
|
|
1162
|
+
parse_tag();
|
|
1163
|
+
}
|
|
1164
|
+
parent = current;
|
|
1165
|
+
expect("catch");
|
|
1166
|
+
parent = node;
|
|
1167
|
+
let catchBlock = ast_node('block');
|
|
1168
|
+
parent = catchBlock;
|
|
1169
|
+
if (accept("[")) {
|
|
1170
|
+
parse_tag_list();
|
|
1171
|
+
expect("]");
|
|
1172
|
+
} else {
|
|
1173
|
+
parse_tag();
|
|
1174
|
+
}
|
|
1175
|
+
parent = current;
|
|
1115
1176
|
}
|
|
1116
1177
|
|
|
1117
|
-
|
|
1178
|
+
function parse_tag_list() {
|
|
1118
1179
|
if (accept("if")) {
|
|
1119
1180
|
parse_if_statement();
|
|
1120
1181
|
parse_tag_list();
|
|
1121
1182
|
} else if (accept("each")) {
|
|
1183
|
+
parse_state.each_depth++;
|
|
1122
1184
|
expect("(");
|
|
1123
1185
|
let it1, it0 = tok.data;
|
|
1124
1186
|
expect("ident");
|
|
@@ -1142,6 +1204,10 @@ module.exports = (config) => {
|
|
|
1142
1204
|
parse_tag();
|
|
1143
1205
|
}
|
|
1144
1206
|
parent = current;
|
|
1207
|
+
parse_state.each_depth--;
|
|
1208
|
+
parse_tag_list();
|
|
1209
|
+
} else if (accept("when")) {
|
|
1210
|
+
parse_when_statement();
|
|
1145
1211
|
parse_tag_list();
|
|
1146
1212
|
} else if (peek("ident")) {
|
|
1147
1213
|
parse_tag();
|
|
@@ -1154,10 +1220,11 @@ module.exports = (config) => {
|
|
|
1154
1220
|
ast_node('yield', { pos: tok.pos, file: tok.file });
|
|
1155
1221
|
next();
|
|
1156
1222
|
parse_tag_list();
|
|
1157
|
-
} else if (in_tag && (peek('global') || peek('const') || peek('let'))) {
|
|
1223
|
+
} else if (parse_state.in_tag && (peek('global') || peek('const') || peek('let'))) {
|
|
1158
1224
|
parse_assignment();
|
|
1159
1225
|
parse_tag_list();
|
|
1160
|
-
} else if (in_tag && peek('js_context')) {
|
|
1226
|
+
} else if (parse_state.in_tag && peek('js_context')) {
|
|
1227
|
+
includeRuntime = true;
|
|
1161
1228
|
parent.js = tok.data;
|
|
1162
1229
|
ast_node('js', { js: tok.data, pos: tok.pos, file: tok.file });
|
|
1163
1230
|
next();
|
|
@@ -1296,6 +1363,7 @@ module.exports = (config) => {
|
|
|
1296
1363
|
} else if (peek('const') || peek('let') || peek('global')) {
|
|
1297
1364
|
parse_assignment();
|
|
1298
1365
|
} else if (peek('js_context')) {
|
|
1366
|
+
includeRuntime = true;
|
|
1299
1367
|
ast_node('js', { js: tok.data, pos: tok.pos, file: tok.file });
|
|
1300
1368
|
js_found = true;
|
|
1301
1369
|
next();
|
|
@@ -1320,7 +1388,7 @@ module.exports = (config) => {
|
|
|
1320
1388
|
let inScript = false;
|
|
1321
1389
|
let inStyle = false;
|
|
1322
1390
|
|
|
1323
|
-
const found = { head: false,
|
|
1391
|
+
const found = { head: false, html: false, body: false };
|
|
1324
1392
|
|
|
1325
1393
|
const emit = flush ? (txt) => {
|
|
1326
1394
|
if (html.length > 100) {
|
|
@@ -1432,7 +1500,6 @@ module.exports = (config) => {
|
|
|
1432
1500
|
ctx.pop();
|
|
1433
1501
|
break;
|
|
1434
1502
|
}
|
|
1435
|
-
// todo: html -> head, body enforcement
|
|
1436
1503
|
if (valid_tags.indexOf(node.data.name) === -1) {
|
|
1437
1504
|
err(`Invalid tag: ${node.data.name}`, node.data);
|
|
1438
1505
|
}
|
|
@@ -1497,11 +1564,13 @@ module.exports = (config) => {
|
|
|
1497
1564
|
} else {
|
|
1498
1565
|
node.children.forEach(walk);
|
|
1499
1566
|
if (node.data.name === 'head') {
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1567
|
+
if (js) {
|
|
1568
|
+
emit('<script type="module">');
|
|
1569
|
+
emit(`document.addEventListener('DOMContentLoaded', function () {\n`);
|
|
1570
|
+
emit(`(function (data){${js}})(${JSON.stringify(initial_state)})`);
|
|
1571
|
+
emit('});');
|
|
1572
|
+
emit('<' + '/script>');
|
|
1573
|
+
}
|
|
1505
1574
|
}
|
|
1506
1575
|
emit('</');
|
|
1507
1576
|
emit(node.data.name);
|
|
@@ -2189,7 +2258,7 @@ module.exports = (config) => {
|
|
|
2189
2258
|
out[out.length - 1].code += txt;
|
|
2190
2259
|
if (fileIdx > -1) {
|
|
2191
2260
|
const n = fileList[fileIdx].name;
|
|
2192
|
-
out[out.length - 1].parent_dir = getPathInfo(n).parent;
|
|
2261
|
+
out[out.length - 1].parent_dir = path ? getPathInfo(n).parent : '/';
|
|
2193
2262
|
}
|
|
2194
2263
|
};
|
|
2195
2264
|
|
|
@@ -2688,28 +2757,30 @@ module.exports = (config) => {
|
|
|
2688
2757
|
return out;
|
|
2689
2758
|
};
|
|
2690
2759
|
|
|
2691
|
-
const renderToAst = async (file, actions) => {
|
|
2692
|
-
|
|
2760
|
+
const renderToAst = async (file, actions, _fileText) => {
|
|
2761
|
+
includeRuntime = false;
|
|
2762
|
+
const fileText = file === 'default' ? _fileText : openFile(file);
|
|
2693
2763
|
const tokens = tokenize(fileText, file);
|
|
2694
2764
|
const ast = parse(tokens);
|
|
2695
|
-
const runtime = generateRuntime(ast, actions);
|
|
2696
2765
|
let js;
|
|
2766
|
+
if (includeRuntime) {
|
|
2767
|
+
const runtime = generateRuntime(ast, actions);
|
|
2697
2768
|
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2769
|
+
if (config.jsTransform) {
|
|
2770
|
+
js = (await Promise.all(runtime.map(async (chunk) => {
|
|
2771
|
+
if (chunk.transform) {
|
|
2772
|
+
return await config.jsTransform(chunk);
|
|
2773
|
+
}
|
|
2774
|
+
return chunk.code;
|
|
2775
|
+
}))).join('\n');
|
|
2776
|
+
} else {
|
|
2777
|
+
js = runtime.map((chunk) => chunk.code).join('\n');
|
|
2778
|
+
}
|
|
2708
2779
|
|
|
2709
|
-
|
|
2710
|
-
|
|
2780
|
+
if (config.jsPostProcess) {
|
|
2781
|
+
js = await config.jsPostProcess(js);
|
|
2782
|
+
}
|
|
2711
2783
|
}
|
|
2712
|
-
|
|
2713
2784
|
return { ast, js };
|
|
2714
2785
|
};
|
|
2715
2786
|
|
|
@@ -2728,11 +2799,19 @@ module.exports = (config) => {
|
|
|
2728
2799
|
return html;
|
|
2729
2800
|
};
|
|
2730
2801
|
|
|
2802
|
+
const renderString = async (fileText, data) => {
|
|
2803
|
+
_files.default = fileText;
|
|
2804
|
+
const result = await renderToAst('default', [], fileText);
|
|
2805
|
+
const html = renderToHTML(result, data);
|
|
2806
|
+
|
|
2807
|
+
return html;
|
|
2808
|
+
};
|
|
2809
|
+
|
|
2731
2810
|
const renderToCache = async (file, actions) => {
|
|
2732
2811
|
const result = await renderToAst(file, actions);
|
|
2733
2812
|
return JSON.stringify(result);
|
|
2734
2813
|
};
|
|
2735
2814
|
|
|
2736
|
-
return { render, renderToCache, renderToHTML, printError };
|
|
2815
|
+
return { render, renderString, renderToCache, renderToHTML, printError };
|
|
2737
2816
|
};
|
|
2738
2817
|
|
package/index.js
CHANGED
|
@@ -53,6 +53,14 @@ const addParentPaths = (code, p) => {
|
|
|
53
53
|
return out;
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
+
const hideDynamicImports = (code) => {
|
|
57
|
+
return code.split('import(').join('__IMPORT_PLACEHOLDER__(');
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const restoreDynamicImports = (code) => {
|
|
61
|
+
return code.split('__IMPORT_PLACEHOLDER__(').join('import(');
|
|
62
|
+
};
|
|
63
|
+
|
|
56
64
|
const esbuild_to_light_error = (e, chunk) => {
|
|
57
65
|
let row = e.location.line - 1;
|
|
58
66
|
let col = e.location.column;
|
|
@@ -88,7 +96,8 @@ Light.compile = async (name, opts) => {
|
|
|
88
96
|
jsTransform: async (chunk) => {
|
|
89
97
|
try {
|
|
90
98
|
const opts = { format: 'cjs', loader: 'ts' };
|
|
91
|
-
const
|
|
99
|
+
const codeChunk = hideDynamicImports(chunk.code);
|
|
100
|
+
const result = await esbuild.transform(codeChunk, opts);
|
|
92
101
|
return addParentPaths(result.code, chunk.parent_dir);
|
|
93
102
|
} catch (e) {
|
|
94
103
|
e.origin = 'esbuild';
|
|
@@ -106,9 +115,10 @@ Light.compile = async (name, opts) => {
|
|
|
106
115
|
minify: opts.minify,
|
|
107
116
|
write: false
|
|
108
117
|
});
|
|
109
|
-
|
|
118
|
+
const output = restoreDynamicImports(result.outputFiles[0].text);
|
|
119
|
+
return output;
|
|
110
120
|
}
|
|
111
|
-
});
|
|
121
|
+
}, fs, path);
|
|
112
122
|
try {
|
|
113
123
|
let html;
|
|
114
124
|
if (opts.cache) {
|