@fluffjs/cli 0.4.0 → 0.4.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.
@@ -59,16 +59,16 @@ export declare class CodeGenerator {
59
59
  private readonly collectedTemplates;
60
60
  constructor(componentSelectors?: Set<string>, componentSelector?: string);
61
61
  static resetGlobalState(): void;
62
- private static internString;
62
+ static internString(str: string): number;
63
63
  static getStringTable(): string[];
64
64
  generateRenderMethod(template: ParsedTemplate, styles?: string): string;
65
65
  generateHtml(template: ParsedTemplate): string;
66
66
  generateRenderMethodFromHtml(html: string, styles?: string, markerConfigExpr?: t.Expression): string;
67
67
  getMarkerConfigExpression(): t.Expression;
68
68
  private buildMarkerConfigExpression;
69
- private buildMarkerConfigObject;
70
- private buildDepsExpression;
71
- private buildPropertyChainExpression;
69
+ private buildMarkerConfigArray;
70
+ private buildCompactDepsExpression;
71
+ private buildCompactPropertyChainExpression;
72
72
  generateBindingsSetup(): string;
73
73
  getBindingsMap(): Record<string, CompactBinding[]>;
74
74
  generateExpressionAssignments(): string;
package/CodeGenerator.js CHANGED
@@ -102,73 +102,81 @@ export class CodeGenerator {
102
102
  const entries = Array.from(this.markerConfigs.entries())
103
103
  .map(([id, config]) => t.arrayExpression([
104
104
  t.numericLiteral(id),
105
- this.buildMarkerConfigObject(config)
105
+ this.buildMarkerConfigArray(config)
106
106
  ]));
107
107
  return t.arrayExpression(entries);
108
108
  }
109
- buildMarkerConfigObject(config) {
110
- const properties = [
111
- t.objectProperty(t.stringLiteral('type'), t.stringLiteral(config.type))
112
- ];
109
+ buildMarkerConfigArray(config) {
110
+ const MARKER_TYPE_MAP = {
111
+ 'if': 0, 'for': 1, 'text': 2, 'switch': 3, 'break': 4
112
+ };
113
+ const typeNum = MARKER_TYPE_MAP[config.type];
113
114
  if (config.type === 'text') {
114
- properties.push(t.objectProperty(t.stringLiteral('exprId'), t.numericLiteral(config.exprId)));
115
- if (config.deps) {
116
- properties.push(t.objectProperty(t.stringLiteral('deps'), this.buildDepsExpression(config.deps)));
117
- }
118
- if (config.pipes && config.pipes.length > 0) {
119
- properties.push(t.objectProperty(t.stringLiteral('pipes'), t.arrayExpression(config.pipes.map(pipe => t.objectExpression([
120
- t.objectProperty(t.stringLiteral('name'), t.stringLiteral(pipe.name)),
121
- t.objectProperty(t.stringLiteral('argExprIds'), t.arrayExpression(pipe.argExprIds.map(arg => t.numericLiteral(arg))))
122
- ])))));
123
- }
115
+ const elements = [
116
+ t.numericLiteral(typeNum),
117
+ t.numericLiteral(config.exprId),
118
+ config.deps ? this.buildCompactDepsExpression(config.deps) : t.nullLiteral(),
119
+ config.pipes && config.pipes.length > 0
120
+ ? t.arrayExpression(config.pipes.map(pipe => t.arrayExpression([
121
+ t.numericLiteral(CodeGenerator.internString(pipe.name)),
122
+ t.arrayExpression(pipe.argExprIds.map(arg => t.numericLiteral(arg)))
123
+ ])))
124
+ : t.nullLiteral()
125
+ ];
126
+ return t.arrayExpression(elements);
124
127
  }
125
128
  else if (config.type === 'if') {
126
- properties.push(t.objectProperty(t.stringLiteral('branches'), t.arrayExpression(config.branches.map(branch => {
127
- const branchProps = [];
128
- if (branch.exprId !== undefined) {
129
- branchProps.push(t.objectProperty(t.stringLiteral('exprId'), t.numericLiteral(branch.exprId)));
130
- }
131
- if (branch.deps) {
132
- branchProps.push(t.objectProperty(t.stringLiteral('deps'), this.buildDepsExpression(branch.deps)));
129
+ const branches = t.arrayExpression(config.branches.map(branch => {
130
+ if (branch.exprId === undefined && !branch.deps) {
131
+ return t.arrayExpression([]);
133
132
  }
134
- return t.objectExpression(branchProps);
135
- }))));
133
+ return t.arrayExpression([
134
+ branch.exprId !== undefined ? t.numericLiteral(branch.exprId) : t.nullLiteral(),
135
+ branch.deps ? this.buildCompactDepsExpression(branch.deps) : t.nullLiteral()
136
+ ]);
137
+ }));
138
+ return t.arrayExpression([t.numericLiteral(typeNum), branches]);
136
139
  }
137
140
  else if (config.type === 'for') {
138
- properties.push(t.objectProperty(t.stringLiteral('iterator'), t.stringLiteral(config.iterator)), t.objectProperty(t.stringLiteral('iterableExprId'), t.numericLiteral(config.iterableExprId)), t.objectProperty(t.stringLiteral('hasEmpty'), t.booleanLiteral(config.hasEmpty)));
139
- if (config.deps) {
140
- properties.push(t.objectProperty(t.stringLiteral('deps'), this.buildDepsExpression(config.deps)));
141
- }
142
- if (config.trackBy !== undefined) {
143
- properties.push(t.objectProperty(t.stringLiteral('trackBy'), t.stringLiteral(config.trackBy)));
144
- }
141
+ return t.arrayExpression([
142
+ t.numericLiteral(typeNum),
143
+ t.numericLiteral(CodeGenerator.internString(config.iterator)),
144
+ t.numericLiteral(config.iterableExprId),
145
+ t.booleanLiteral(config.hasEmpty),
146
+ config.deps ? this.buildCompactDepsExpression(config.deps) : t.nullLiteral(),
147
+ config.trackBy !== undefined
148
+ ? t.numericLiteral(CodeGenerator.internString(config.trackBy))
149
+ : t.nullLiteral()
150
+ ]);
145
151
  }
146
152
  else if (config.type === 'switch') {
147
- properties.push(t.objectProperty(t.stringLiteral('expressionExprId'), t.numericLiteral(config.expressionExprId)));
148
- if (config.deps) {
149
- properties.push(t.objectProperty(t.stringLiteral('deps'), this.buildDepsExpression(config.deps)));
150
- }
151
- properties.push(t.objectProperty(t.stringLiteral('cases'), t.arrayExpression(config.cases.map(caseConfig => {
152
- const caseProps = [
153
- t.objectProperty(t.stringLiteral('isDefault'), t.booleanLiteral(caseConfig.isDefault)),
154
- t.objectProperty(t.stringLiteral('fallthrough'), t.booleanLiteral(caseConfig.fallthrough))
155
- ];
156
- if (caseConfig.valueExprId !== undefined) {
157
- caseProps.push(t.objectProperty(t.stringLiteral('valueExprId'), t.numericLiteral(caseConfig.valueExprId)));
158
- }
159
- return t.objectExpression(caseProps);
160
- }))));
161
- }
162
- return t.objectExpression(properties);
163
- }
164
- buildDepsExpression(deps) {
165
- return t.arrayExpression(deps.map(dep => this.buildPropertyChainExpression(dep)));
166
- }
167
- buildPropertyChainExpression(dep) {
153
+ const cases = t.arrayExpression(config.cases.map(caseConfig => t.arrayExpression([
154
+ t.booleanLiteral(caseConfig.isDefault),
155
+ t.booleanLiteral(caseConfig.fallthrough),
156
+ caseConfig.valueExprId !== undefined
157
+ ? t.numericLiteral(caseConfig.valueExprId)
158
+ : t.nullLiteral()
159
+ ])));
160
+ return t.arrayExpression([
161
+ t.numericLiteral(typeNum),
162
+ t.numericLiteral(config.expressionExprId),
163
+ config.deps ? this.buildCompactDepsExpression(config.deps) : t.nullLiteral(),
164
+ cases
165
+ ]);
166
+ }
167
+ else if (config.type === 'break') {
168
+ return t.arrayExpression([t.numericLiteral(typeNum)]);
169
+ }
170
+ return t.arrayExpression([t.numericLiteral(typeNum)]);
171
+ }
172
+ buildCompactDepsExpression(deps) {
173
+ return t.arrayExpression(deps.map(dep => this.buildCompactPropertyChainExpression(dep)));
174
+ }
175
+ buildCompactPropertyChainExpression(dep) {
168
176
  if (Array.isArray(dep)) {
169
- return t.arrayExpression(dep.map(part => t.stringLiteral(part)));
177
+ return t.arrayExpression(dep.map(part => t.numericLiteral(CodeGenerator.internString(part))));
170
178
  }
171
- return t.stringLiteral(dep);
179
+ return t.numericLiteral(CodeGenerator.internString(dep));
172
180
  }
173
181
  generateBindingsSetup() {
174
182
  const statements = [
@@ -1,9 +1,11 @@
1
1
  import * as babel from '@babel/core';
2
2
  import { parse } from '@babel/parser';
3
3
  import * as t from '@babel/types';
4
+ import cssnano from 'cssnano';
4
5
  import * as esbuild from 'esbuild';
5
6
  import * as fs from 'fs';
6
7
  import { minify as minifyHtml } from 'html-minifier-terser';
8
+ import postcss from 'postcss';
7
9
  import * as parse5 from 'parse5';
8
10
  import * as path from 'path';
9
11
  import { SourceMapConsumer, SourceMapGenerator } from 'source-map';
@@ -116,6 +118,8 @@ export class ComponentCompiler {
116
118
  styles = inlineStyles;
117
119
  }
118
120
  if (minify && styles) {
121
+ const nanoResult = await postcss([cssnano({ preset: 'default' })]).process(styles, { from: undefined });
122
+ styles = nanoResult.css;
119
123
  const cssResult = await esbuild.transform(styles, {
120
124
  loader: 'css', minify: true
121
125
  });
@@ -1,5 +1,6 @@
1
1
  import { types as t } from '@babel/core';
2
2
  import { buildHostBindingUpdateStatement, findDecoratorIndex, getDecoratorName } from './BabelHelpers.js';
3
+ import { CodeGenerator } from './CodeGenerator.js';
3
4
  export const reactivePropertiesMap = new Map();
4
5
  export default function reactivePlugin() {
5
6
  // noinspection JSUnusedGlobalSymbols
@@ -349,7 +350,8 @@ export default function reactivePlugin() {
349
350
  const propertyArgs = useOptionsObject
350
351
  ? [t.objectExpression(propertyOptions)]
351
352
  : [initialValue];
352
- const createPropCall = t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('__createProp')), [t.stringLiteral(propName), ...propertyArgs]);
353
+ const propNameIdx = CodeGenerator.internString(propName);
354
+ const createPropCall = t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('__createProp')), [t.numericLiteral(propNameIdx), ...propertyArgs]);
353
355
  const privateField = t.classProperty(t.identifier(privateName), createPropCall);
354
356
  propsToRemove.push(memberPath);
355
357
  privateFields.push(privateField);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluffjs/cli",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "module": "./index.js",
@@ -33,9 +33,9 @@
33
33
  "he": "^1.2.0",
34
34
  "html-minifier-terser": "^7.2.0",
35
35
  "http-proxy": "^1.18.1",
36
- "picomatch": "^4.0.2",
37
36
  "parse5": "^8.0.0",
38
37
  "parse5-sax-parser": "^8.0.0",
38
+ "picomatch": "^4.0.2",
39
39
  "source-map": "^0.7.6",
40
40
  "tslib": "^2.3.0"
41
41
  },
@@ -43,7 +43,9 @@
43
43
  "@types/he": "^1.2.3",
44
44
  "@types/http-proxy": "^1.17.16",
45
45
  "@types/jsesc": "^3.0.3",
46
- "jsesc": "^3.1.0"
46
+ "cssnano": "^7.1.2",
47
+ "jsesc": "^3.1.0",
48
+ "postcss": "^8.5.6"
47
49
  },
48
50
  "publishConfig": {
49
51
  "access": "public"
@@ -9,6 +9,9 @@ type MarkerConfigEntriesLiteral = [number, MarkerConfigLiteral][];
9
9
  export declare class MarkerConfigAstReader {
10
10
  static readMarkerConfigEntries(code: string): MarkerConfigEntriesLiteral;
11
11
  static collectDeps(entries: MarkerConfigEntriesLiteral): string[];
12
+ private static collectDepsFromCompactConfig;
13
+ private static collectNumberDeps;
14
+ static collectCompactDeps(entries: MarkerConfigEntriesLiteral): number[][];
12
15
  private static collectDepsFromRecord;
13
16
  private static collectDepsFromIf;
14
17
  private static collectStringsFromDep;
@@ -31,6 +31,9 @@ export class MarkerConfigAstReader {
31
31
  static collectDeps(entries) {
32
32
  const deps = [];
33
33
  for (const [, config] of entries) {
34
+ if (Array.isArray(config)) {
35
+ continue;
36
+ }
34
37
  if (!MarkerConfigAstReader.isRecord(config)) {
35
38
  continue;
36
39
  }
@@ -56,6 +59,72 @@ export class MarkerConfigAstReader {
56
59
  }
57
60
  return deps;
58
61
  }
62
+ static collectDepsFromCompactConfig(config, deps) {
63
+ const [typeNum] = config;
64
+ if (typeof typeNum !== 'number')
65
+ return;
66
+ switch (typeNum) {
67
+ case 0: // if
68
+ {
69
+ const [, branches] = config;
70
+ if (Array.isArray(branches)) {
71
+ for (const branch of branches) {
72
+ if (Array.isArray(branch) && branch.length >= 2) {
73
+ const [, branchDeps] = branch;
74
+ if (Array.isArray(branchDeps)) {
75
+ MarkerConfigAstReader.collectNumberDeps(branchDeps, deps);
76
+ }
77
+ }
78
+ }
79
+ }
80
+ break;
81
+ }
82
+ case 1: // for
83
+ {
84
+ const [, , , , forDeps] = config;
85
+ if (Array.isArray(forDeps)) {
86
+ MarkerConfigAstReader.collectNumberDeps(forDeps, deps);
87
+ }
88
+ break;
89
+ }
90
+ case 2: // text
91
+ {
92
+ const [, , textDeps] = config;
93
+ if (Array.isArray(textDeps)) {
94
+ MarkerConfigAstReader.collectNumberDeps(textDeps, deps);
95
+ }
96
+ break;
97
+ }
98
+ case 3: // switch
99
+ {
100
+ const [, , switchDeps] = config;
101
+ if (Array.isArray(switchDeps)) {
102
+ MarkerConfigAstReader.collectNumberDeps(switchDeps, deps);
103
+ }
104
+ break;
105
+ }
106
+ }
107
+ }
108
+ static collectNumberDeps(compactDeps, deps) {
109
+ for (const dep of compactDeps) {
110
+ if (typeof dep === 'number') {
111
+ deps.push([dep]);
112
+ }
113
+ else if (Array.isArray(dep)) {
114
+ const numDeps = dep.filter((d) => typeof d === 'number');
115
+ deps.push(numDeps);
116
+ }
117
+ }
118
+ }
119
+ static collectCompactDeps(entries) {
120
+ const deps = [];
121
+ for (const [, config] of entries) {
122
+ if (Array.isArray(config)) {
123
+ MarkerConfigAstReader.collectDepsFromCompactConfig(config, deps);
124
+ }
125
+ }
126
+ return deps;
127
+ }
59
128
  static collectDepsFromRecord(configRecord, deps) {
60
129
  const configDeps = configRecord.deps;
61
130
  if (Array.isArray(configDeps)) {
@@ -153,7 +222,7 @@ export class MarkerConfigAstReader {
153
222
  return false;
154
223
  }
155
224
  const [id, config] = entry;
156
- return typeof id === 'number' && MarkerConfigAstReader.isRecord(config);
225
+ return typeof id === 'number' && (MarkerConfigAstReader.isRecord(config) || Array.isArray(config));
157
226
  });
158
227
  }
159
228
  static isRecord(value) {