@makano/rew 1.3.1 → 1.3.2
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/lib/rew/modules/compiler.js +12 -18
- package/lib/rew/pkgs/serve.js +4 -3
- package/lib/rew/pkgs/web.js +109 -5
- package/package.json +1 -1
- package/runtime.d.ts +13 -10
@@ -27,24 +27,21 @@ function tokenizeCoffeeScript(code) {
|
|
27
27
|
const nextNextChar = code[i + 2];
|
28
28
|
|
29
29
|
if (char === '#') {
|
30
|
-
// Comment
|
31
30
|
const commentEnd = code.indexOf('\n', i);
|
32
31
|
const comment = code.substring(i, commentEnd < 0 ? code.length : commentEnd + 1);
|
33
32
|
tokens.push({ type: 'COMMENT', value: comment });
|
34
33
|
i += comment.length - 1;
|
35
34
|
} else if (char === '"' && nextChar === '"' && nextNextChar === '"') {
|
36
|
-
// Triple-quoted string
|
37
35
|
let string = '"""';
|
38
36
|
i += 3;
|
39
37
|
while (i < code.length && !(code[i] === '"' && code[i + 1] === '"' && code[i + 2] === '"')) {
|
40
38
|
string += code[i];
|
41
39
|
i++;
|
42
40
|
}
|
43
|
-
string += '"""';
|
41
|
+
string += '"""';
|
44
42
|
tokens.push({ type: 'TRIPLE_STRING', value: string });
|
45
|
-
i += 2;
|
43
|
+
i += 2;
|
46
44
|
} else if (char === '"' || char === "'") {
|
47
|
-
// Single or double-quoted string
|
48
45
|
let string = char;
|
49
46
|
let escaped = false;
|
50
47
|
i++;
|
@@ -57,10 +54,9 @@ function tokenizeCoffeeScript(code) {
|
|
57
54
|
}
|
58
55
|
i++;
|
59
56
|
}
|
60
|
-
string += char;
|
57
|
+
string += char;
|
61
58
|
tokens.push({ type: 'STRING', value: string });
|
62
59
|
} else if (char === '/' && nextChar !== ' ' && nextChar !== '/' && nextChar !== '*' && prevChar !== '<') {
|
63
|
-
// Regular expression
|
64
60
|
let regex = char;
|
65
61
|
i++;
|
66
62
|
while (i < code.length && (code[i] !== '/' || regex.endsWith('\\'))) {
|
@@ -70,14 +66,12 @@ function tokenizeCoffeeScript(code) {
|
|
70
66
|
regex += '/';
|
71
67
|
tokens.push({ type: 'REGEX', value: regex });
|
72
68
|
} else if (/\s/.test(char)) {
|
73
|
-
// Whitespace
|
74
69
|
if (tokens[tokens.length - 1]?.type === 'WHITESPACE') {
|
75
70
|
tokens[tokens.length - 1].value += char;
|
76
71
|
} else {
|
77
72
|
tokens.push({ type: 'WHITESPACE', value: char });
|
78
73
|
}
|
79
74
|
} else if (/[a-zA-Z_$@]/.test(char)) {
|
80
|
-
// Identifier
|
81
75
|
let identifier = char;
|
82
76
|
i++;
|
83
77
|
while (i < code.length && /[a-zA-Z0-9_$]/.test(code[i])) {
|
@@ -85,18 +79,17 @@ function tokenizeCoffeeScript(code) {
|
|
85
79
|
i++;
|
86
80
|
}
|
87
81
|
tokens.push({ type: 'IDENTIFIER', value: identifier });
|
88
|
-
i--;
|
89
|
-
} else if (/[a-f0-9.
|
82
|
+
i--;
|
83
|
+
} else if (/[a-f0-9.xn]/.test(char)) {
|
90
84
|
let num = char;
|
91
85
|
i++;
|
92
|
-
while (i < code.length && /[a-f0-9.
|
86
|
+
while (i < code.length && /[a-f0-9.nx]/.test(code[i])) {
|
93
87
|
num += code[i];
|
94
88
|
i++;
|
95
89
|
}
|
96
90
|
tokens.push({ type: 'NUMBER', value: num });
|
97
|
-
i--;
|
91
|
+
i--;
|
98
92
|
} else {
|
99
|
-
// Other characters
|
100
93
|
tokens.push({ type: 'OTHER', value: char });
|
101
94
|
}
|
102
95
|
i++;
|
@@ -397,7 +390,7 @@ function compileRewStuff(content, options) {
|
|
397
390
|
}
|
398
391
|
|
399
392
|
|
400
|
-
if (token.type === 'IDENTIFIER' && token.value === 'export' && !options.keepImports) {
|
393
|
+
if (tokens[i-1]?.value !== '.' && token.type === 'IDENTIFIER' && token.value === 'export' && !options.keepImports) {
|
401
394
|
token.value = 'pub';
|
402
395
|
straceLog('EXPORT() => TRANSLATING TO pub');
|
403
396
|
}
|
@@ -421,7 +414,7 @@ function compileRewStuff(content, options) {
|
|
421
414
|
}
|
422
415
|
}
|
423
416
|
|
424
|
-
if (token.type === 'IDENTIFIER' && token.value === 'using' && !options.disableUse) {
|
417
|
+
if (tokens[i-1]?.value !== '.' && token.type === 'IDENTIFIER' && token.value === 'using' && !options.disableUse) {
|
425
418
|
straceLog('USING()');
|
426
419
|
const next = nextToken.value;
|
427
420
|
if(next in USING_DEFAULT) {
|
@@ -448,7 +441,7 @@ function compileRewStuff(content, options) {
|
|
448
441
|
}
|
449
442
|
}
|
450
443
|
|
451
|
-
if (token.type === 'IDENTIFIER' && token.value === 'import' && !options.keepImports) {
|
444
|
+
if (tokens[i-1]?.value !== '.' && token.type === 'IDENTIFIER' && token.value === 'import' && !options.keepImports) {
|
452
445
|
// console.log(nextToken.type);
|
453
446
|
straceLog('IMPORT()');
|
454
447
|
straceLog('==> WARN: SLOWS DOWN COMPILATION');
|
@@ -539,7 +532,7 @@ function compileRewStuff(content, options) {
|
|
539
532
|
continue;
|
540
533
|
}
|
541
534
|
|
542
|
-
if (token.type === 'IDENTIFIER' && (token.value === 'imp' || token.value === 'inc')) {
|
535
|
+
if (tokens[i-1]?.value !== '.' && token.type === 'IDENTIFIER' && (token.value === 'imp' || token.value === 'inc')) {
|
543
536
|
straceLog('IMP() Detected');
|
544
537
|
let { token: t1 } = gnextToken(i, 1, tokens) || {};
|
545
538
|
let { token: t2 } = gnextToken(i, 2, tokens) || {};
|
@@ -559,6 +552,7 @@ function compileRewStuff(content, options) {
|
|
559
552
|
}
|
560
553
|
|
561
554
|
if (
|
555
|
+
tokens[i-1]?.value !== '.' &&
|
562
556
|
token.type === 'IDENTIFIER' &&
|
563
557
|
token.value === 'pub' &&
|
564
558
|
nextToken &&
|
package/lib/rew/pkgs/serve.js
CHANGED
@@ -166,9 +166,9 @@ module.exports = (context) => {
|
|
166
166
|
|
167
167
|
render = (req, data) ->
|
168
168
|
target = renderers.pop()
|
169
|
-
page = target.render req, data
|
169
|
+
page = target.render.call @, req, data
|
170
170
|
for renderer in renderers
|
171
|
-
page = renderer.render req, data, page
|
171
|
+
page = renderer.render.call @, req, data, page
|
172
172
|
page
|
173
173
|
|
174
174
|
exports { render, staticRendering }
|
@@ -241,7 +241,8 @@ module.exports = (context) => {
|
|
241
241
|
const layouts = findLayoutFiles(file, root, false);
|
242
242
|
const fileContext = runPath(file, { code: ssrBundlerEntry(file, layouts) }).context.module.exports || {};
|
243
243
|
if(typeof fileContext.render !== "function") throw new ReferenceError("Route does not export function render");
|
244
|
-
|
244
|
+
const props = { page, ...getReqProps(req) };
|
245
|
+
let pageContent = fileContext.render.call(props, req, props);
|
245
246
|
if(fileContext.staticRendering) staticRendering = true;
|
246
247
|
if(!w.isNode(pageContent)) throw new TypeError("Route.render does not return an element");
|
247
248
|
if(pageContent?.type?.element == 'head'){
|
package/lib/rew/pkgs/web.js
CHANGED
@@ -245,6 +245,95 @@ function renderToString(element, js = false) {
|
|
245
245
|
return js ? js === 'raw' ? eltJSON : JSON.stringify(eltJSON) : element instanceof TextNode ? `${type.text}` : `<${type.element}${propsString}>${selfClosingElements.has(type.element) ? '' : childrenHTML}${selfClosingElements.has(type.element) ? '' : `</${type.element}>`}`;
|
246
246
|
}
|
247
247
|
|
248
|
+
function createStyles(styles) {
|
249
|
+
let css = "";
|
250
|
+
const variables = {};
|
251
|
+
const mixins = {};
|
252
|
+
|
253
|
+
const parseValue = (v, self, name, vars) => {
|
254
|
+
const vs = {...variables, ...vars, name, ...Object.fromEntries(Object.entries(self).map(i => ['prop_'+i[0], i[1]]))};
|
255
|
+
return v.startsWith('@v') ? vs[v.split('@v')[1].trim()] : v
|
256
|
+
.toString()
|
257
|
+
.replace(/\$([A-Za-z0-9-_]+)/g, (_, name) => (vs)[name])
|
258
|
+
}
|
259
|
+
|
260
|
+
const declectProp = (value, name, selector, start, parent, self, vars = {}) => {
|
261
|
+
let prop = `${name}: `;
|
262
|
+
self.__parent = parent;
|
263
|
+
if (typeof value == 'object') {
|
264
|
+
prop += parseValue(value.default || 'unset', self, name, vars) + ';';
|
265
|
+
prop += '}\n';
|
266
|
+
for (let state in value) {
|
267
|
+
if (state == 'default') continue;
|
268
|
+
else if (state.startsWith('@media')) {
|
269
|
+
prop += `${state} { ${start} ${name}: ${parseValue(value[state], self, name, vars)}; } }\n`
|
270
|
+
} else if (state.startsWith(':')) {
|
271
|
+
prop += `${selector}${state} { ${name}: ${parseValue(value[state], self, name, vars)}; }\n`
|
272
|
+
}
|
273
|
+
}
|
274
|
+
prop += start;
|
275
|
+
} else {
|
276
|
+
let v = parseValue(value, self, name, vars);
|
277
|
+
if(typeof v == 'object') return declectProp(v, name, selector, start, parent, self, vars);
|
278
|
+
prop += v + ';';
|
279
|
+
}
|
280
|
+
return prop;
|
281
|
+
}
|
282
|
+
|
283
|
+
const declectNames = (names, $name, parent, values = {}) => {
|
284
|
+
const start = $name ? $name + ' {' : '';
|
285
|
+
let nameStyles = start;
|
286
|
+
for (let name in names) {
|
287
|
+
let selector = name.replace(/,/g, ', &').replace(/&/g, $name || '');
|
288
|
+
if (name == '@variables') {
|
289
|
+
for (let i in names[name]) {
|
290
|
+
variables[i] = names[name][i];
|
291
|
+
}
|
292
|
+
} else if (name.startsWith('@mixin')) {
|
293
|
+
const mame = name.split('@mixin')[1].trim();
|
294
|
+
const mname = mame.split('(')[0];
|
295
|
+
const args = mame.replace(mname, '').slice(1, -1);
|
296
|
+
mixins[mname] = {
|
297
|
+
args: args.split(','),
|
298
|
+
value: names[name]
|
299
|
+
}
|
300
|
+
} else if (name.startsWith('@keyframes')) {
|
301
|
+
nameStyles += $name ? '' : name + '{';
|
302
|
+
|
303
|
+
for(let keyFrame in names[name]){
|
304
|
+
nameStyles += declectNames(names[name][keyFrame], keyFrame, names[name], values);
|
305
|
+
}
|
306
|
+
|
307
|
+
if(!$name) nameStyles += '}\n';
|
308
|
+
} else if ($name) {
|
309
|
+
if (name.startsWith('&')) {
|
310
|
+
nameStyles += '}\n';
|
311
|
+
nameStyles += declectNames(names[name], selector, names, values);
|
312
|
+
nameStyles += start;
|
313
|
+
} else if(name.startsWith('@include')) {
|
314
|
+
const mame = names[name];
|
315
|
+
const mname = mame.split('(')[0];
|
316
|
+
const args = mame.replace(mname, '').slice(1, -1).split(',');
|
317
|
+
if(mixins[mname]){
|
318
|
+
nameStyles += declectNames(mixins[mname].value, selector, names, {...values, ...Object.fromEntries(mixins[mname].args.map((n, i) => [n, args[i]]))}).trim().replace('@include ', '').slice(1, -1);
|
319
|
+
}
|
320
|
+
} else {
|
321
|
+
nameStyles += declectProp(names[name], name, $name, start, parent || styles, names, values);
|
322
|
+
}
|
323
|
+
} else {
|
324
|
+
nameStyles += declectNames(names[name], selector, names, values);
|
325
|
+
}
|
326
|
+
}
|
327
|
+
if ($name) nameStyles += '}\n';
|
328
|
+
return nameStyles;
|
329
|
+
}
|
330
|
+
|
331
|
+
css += declectNames(styles);
|
332
|
+
|
333
|
+
return css.replace(/(.+) \{\}/g, '');
|
334
|
+
}
|
335
|
+
|
336
|
+
|
248
337
|
class Page extends Node {
|
249
338
|
constructor() {
|
250
339
|
super();
|
@@ -270,6 +359,8 @@ class Page extends Node {
|
|
270
359
|
style(styleString) {
|
271
360
|
if (typeof styleString == "object" && styleString.href)
|
272
361
|
return this.head.add(createElement('link', { href: styleString.href, rel: 'stylesheet' }));
|
362
|
+
else if(typeof styleString == "object")
|
363
|
+
return this.head.add(createElement('style', null, createTextNode(createStyles(styleString))))
|
273
364
|
else
|
274
365
|
return this.head.add(createElement('style', null, createTextNode(styleString)));
|
275
366
|
}
|
@@ -301,13 +392,17 @@ class Page extends Node {
|
|
301
392
|
${State}
|
302
393
|
const states = [];
|
303
394
|
|
395
|
+
function styleAttribute(value, el){
|
396
|
+
for(let i in value){
|
397
|
+
const v = value[i];
|
398
|
+
el.style.setProperty(i, value[i]);
|
399
|
+
}
|
400
|
+
}
|
401
|
+
|
304
402
|
function setAttribute(el, key, value){
|
305
403
|
let defVal = value;
|
306
404
|
if(key == 'style'){
|
307
|
-
|
308
|
-
const v = value[i];
|
309
|
-
el.style.setProperty(i, value[i]);
|
310
|
-
}
|
405
|
+
styleAttribute(value, el);
|
311
406
|
return;
|
312
407
|
} else if(key.startsWith('on')){
|
313
408
|
if(!el.listeners) el.listeners = [];
|
@@ -453,12 +548,21 @@ module.exports = (context, importOptions) => {
|
|
453
548
|
createElement(...args) {
|
454
549
|
return createElement(...args);
|
455
550
|
}
|
551
|
+
createStyles(...args){
|
552
|
+
return createStyles(...args);
|
553
|
+
}
|
456
554
|
state(value) {
|
457
555
|
return new State(value);
|
458
556
|
}
|
459
557
|
invokeState(states, callback){
|
460
558
|
const statesMapped = states.map(i => i instanceof State ? `getState('${i.id}')` : (typeof i == "function" ? i.toString() : JSON.stringify(i)));
|
461
|
-
return `((${callback})(event, ...[${statesMapped}]))`;
|
559
|
+
return `((${callback})(typof event !== "undefined" ? event : null, ...[${statesMapped}]))`;
|
560
|
+
}
|
561
|
+
async bundleCode(code, options){
|
562
|
+
return Web.prototype.bundle(generateRandomID(), {
|
563
|
+
...options,
|
564
|
+
code
|
565
|
+
});
|
462
566
|
}
|
463
567
|
async bundle(filepath, options = {}) {
|
464
568
|
const virtualModuleId = `virtual:${filepath}`;
|
package/package.json
CHANGED
package/runtime.d.ts
CHANGED
@@ -500,6 +500,7 @@ declare namespace Rew {
|
|
500
500
|
add(...children: nodable[]): typeof this.body;
|
501
501
|
|
502
502
|
script(script: string): ReturnType<typeof this.add>;
|
503
|
+
style(style: string | Record<string, any>): ReturnType<typeof this.add>;
|
503
504
|
|
504
505
|
serializeState(): string;
|
505
506
|
|
@@ -522,11 +523,13 @@ declare namespace Rew {
|
|
522
523
|
|
523
524
|
createText(text: string): Node;
|
524
525
|
createElement(...args: any[]): ElementNode;
|
526
|
+
createStyles(styles: Record<string, any>): string;
|
525
527
|
|
526
528
|
state(value): ModuleWebState | any;
|
527
529
|
// @ts-ignore
|
528
530
|
invokeState(states: State[], callback: CallableFunction): any;
|
529
531
|
|
532
|
+
bundleCode(code: string, options?: Record<string, any>): string;
|
530
533
|
bundle(filePath: string, options?: Record<string, any>): string;
|
531
534
|
}
|
532
535
|
|
@@ -1006,16 +1009,16 @@ declare namespace Rew {
|
|
1006
1009
|
group(...group: any[]): { g: T, with: (props: any) => { g: T, [key: string]: any }, [key: string]: any }
|
1007
1010
|
}
|
1008
1011
|
|
1009
|
-
declare const std
|
1010
|
-
curl: curl,
|
1011
|
-
int: int,
|
1012
|
-
str: str,
|
1013
|
-
bool: bool,
|
1014
|
-
float: float,
|
1015
|
-
num: num,
|
1016
|
-
typeis: typeis,
|
1017
|
-
typex: typex,
|
1018
|
-
typei: typei,
|
1012
|
+
declare const std: {
|
1013
|
+
curl: typeof curl,
|
1014
|
+
int: typeof int,
|
1015
|
+
str: typeof str,
|
1016
|
+
bool: typeof bool,
|
1017
|
+
float: typeof float,
|
1018
|
+
num: typeof num,
|
1019
|
+
typeis: typeof typeis,
|
1020
|
+
typex: typeof typex,
|
1021
|
+
typei: typeof typei,
|
1019
1022
|
|
1020
1023
|
prototype: {
|
1021
1024
|
void: () => void 0,
|