@fluffjs/cli 0.0.8 → 0.1.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.
- package/BabelHelpers.d.ts +26 -0
- package/BabelHelpers.js +65 -0
- package/Cli.d.ts +5 -10
- package/Cli.js +123 -52
- package/CodeGenerator.d.ts +53 -39
- package/CodeGenerator.js +330 -725
- package/ComponentCompiler.d.ts +14 -16
- package/ComponentCompiler.js +187 -256
- package/DomPreProcessor.d.ts +36 -0
- package/DomPreProcessor.js +645 -0
- package/ErrorHelpers.d.ts +5 -0
- package/ErrorHelpers.js +8 -0
- package/ExpressionTransformer.d.ts +38 -28
- package/ExpressionTransformer.js +558 -230
- package/Generator.d.ts +1 -5
- package/Generator.js +128 -67
- package/GetterDependencyExtractor.d.ts +4 -0
- package/GetterDependencyExtractor.js +73 -0
- package/IndexHtmlTransformer.d.ts +6 -7
- package/IndexHtmlTransformer.js +82 -88
- package/Parse5Helpers.d.ts +16 -0
- package/Parse5Helpers.js +81 -0
- package/TemplateParser.d.ts +39 -21
- package/TemplateParser.js +462 -268
- package/Typeguards.d.ts +24 -0
- package/Typeguards.js +30 -0
- package/babel-plugin-class-transform.d.ts +3 -18
- package/babel-plugin-class-transform.js +3 -11
- package/babel-plugin-component.d.ts +4 -13
- package/babel-plugin-component.js +7 -0
- package/babel-plugin-imports.d.ts +3 -11
- package/babel-plugin-imports.js +5 -31
- package/babel-plugin-reactive.d.ts +2 -19
- package/babel-plugin-reactive.js +21 -76
- package/bin.js +2 -2
- package/fluff-esbuild-plugin.d.ts +2 -5
- package/fluff-esbuild-plugin.js +4 -1
- package/index.d.ts +6 -2
- package/index.js +1 -1
- package/interfaces/BabelPluginClassTransformState.d.ts +5 -0
- package/interfaces/BabelPluginComponentState.d.ts +4 -0
- package/interfaces/BabelPluginComponentState.js +1 -0
- package/interfaces/BabelPluginImportsState.d.ts +5 -0
- package/interfaces/BabelPluginImportsState.js +1 -0
- package/interfaces/BabelPluginReactiveState.d.ts +13 -0
- package/interfaces/BabelPluginReactiveState.js +1 -0
- package/interfaces/BabelPluginReactiveWatchCallInfo.d.ts +7 -0
- package/interfaces/BabelPluginReactiveWatchCallInfo.js +1 -0
- package/interfaces/BabelPluginReactiveWatchInfo.d.ts +5 -0
- package/interfaces/BabelPluginReactiveWatchInfo.js +1 -0
- package/interfaces/BabelToken.d.ts +8 -0
- package/interfaces/BabelToken.js +1 -0
- package/interfaces/BindingInfo.d.ts +12 -0
- package/interfaces/BindingInfo.js +1 -0
- package/interfaces/BreakMarkerConfig.d.ts +4 -0
- package/interfaces/BreakMarkerConfig.js +1 -0
- package/interfaces/BreakNode.d.ts +4 -0
- package/interfaces/BreakNode.js +1 -0
- package/interfaces/BundleOptions.d.ts +8 -0
- package/interfaces/BundleOptions.js +1 -0
- package/interfaces/ClassTransformOptions.d.ts +10 -0
- package/interfaces/ClassTransformOptions.js +1 -0
- package/interfaces/CliOptions.d.ts +6 -0
- package/interfaces/CliOptions.js +1 -0
- package/interfaces/CommentNode.d.ts +5 -0
- package/interfaces/CommentNode.js +1 -0
- package/interfaces/CompileResult.d.ts +6 -0
- package/interfaces/CompileResult.js +1 -0
- package/interfaces/CompilerOptions.d.ts +6 -0
- package/interfaces/CompilerOptions.js +1 -0
- package/interfaces/ComponentInfo.d.ts +8 -0
- package/interfaces/ComponentInfo.js +1 -0
- package/interfaces/ComponentMetadata.d.ts +9 -0
- package/interfaces/ComponentMetadata.js +1 -0
- package/interfaces/ControlFlow.d.ts +19 -0
- package/interfaces/ControlFlow.js +1 -0
- package/interfaces/ControlFlowNode.d.ts +6 -0
- package/interfaces/ControlFlowNode.js +1 -0
- package/interfaces/ControlFlowParseResult.d.ts +10 -0
- package/interfaces/ControlFlowParseResult.js +1 -0
- package/interfaces/ElementNode.d.ts +11 -0
- package/interfaces/ElementNode.js +1 -0
- package/interfaces/FluffConfigInterface.d.ts +7 -0
- package/interfaces/FluffConfigInterface.js +1 -0
- package/interfaces/FluffPluginOptions.d.ts +9 -0
- package/interfaces/FluffPluginOptions.js +1 -0
- package/interfaces/FluffTarget.d.ts +15 -0
- package/interfaces/FluffTarget.js +1 -0
- package/interfaces/ForMarkerConfig.d.ts +9 -0
- package/interfaces/ForMarkerConfig.js +1 -0
- package/interfaces/ForNode.d.ts +13 -0
- package/interfaces/ForNode.js +1 -0
- package/interfaces/GeneratorOptions.d.ts +5 -0
- package/interfaces/GeneratorOptions.js +1 -0
- package/interfaces/HtmlTransformOptions.d.ts +9 -0
- package/interfaces/HtmlTransformOptions.js +1 -0
- package/interfaces/IfBranch.d.ts +8 -0
- package/interfaces/IfBranch.js +1 -0
- package/interfaces/IfMarkerConfig.d.ts +8 -0
- package/interfaces/IfMarkerConfig.js +1 -0
- package/interfaces/IfNode.d.ts +7 -0
- package/interfaces/IfNode.js +1 -0
- package/interfaces/ImportTransformOptions.d.ts +7 -0
- package/interfaces/ImportTransformOptions.js +1 -0
- package/interfaces/InterpolationNode.d.ts +12 -0
- package/interfaces/InterpolationNode.js +1 -0
- package/interfaces/ParsedTemplate.d.ts +6 -0
- package/interfaces/ParsedTemplate.js +1 -0
- package/interfaces/ParsedTemplateOld.d.ts +9 -0
- package/interfaces/ParsedTemplateOld.js +1 -0
- package/interfaces/PropertyChain.d.ts +2 -0
- package/interfaces/PropertyChain.js +1 -0
- package/interfaces/Scope.d.ts +5 -0
- package/interfaces/Scope.js +1 -0
- package/interfaces/ServeOptions.d.ts +5 -0
- package/interfaces/ServeOptions.js +1 -0
- package/interfaces/SwitchCase.d.ts +8 -0
- package/interfaces/SwitchCase.js +1 -0
- package/interfaces/SwitchMarkerConfig.d.ts +11 -0
- package/interfaces/SwitchMarkerConfig.js +1 -0
- package/interfaces/SwitchNode.d.ts +10 -0
- package/interfaces/SwitchNode.js +1 -0
- package/interfaces/TemplateBinding.d.ts +10 -0
- package/interfaces/TemplateBinding.js +1 -0
- package/interfaces/TemplateNode.d.ts +7 -0
- package/interfaces/TemplateNode.js +1 -0
- package/interfaces/TextMarkerConfig.d.ts +10 -0
- package/interfaces/TextMarkerConfig.js +1 -0
- package/interfaces/TextNode.d.ts +5 -0
- package/interfaces/TextNode.js +1 -0
- package/interfaces/TokenizeResult.d.ts +6 -0
- package/interfaces/TokenizeResult.js +1 -0
- package/interfaces/TransformOptions.d.ts +11 -0
- package/interfaces/TransformOptions.js +1 -0
- package/interfaces/index.d.ts +34 -0
- package/interfaces/index.js +1 -0
- package/package.json +9 -1
- package/types/FluffConfig.d.ts +5 -27
- package/ControlFlowParser.d.ts +0 -55
- package/ControlFlowParser.js +0 -279
- package/types.d.ts +0 -46
- /package/{types.js → interfaces/BabelPluginClassTransformState.js} +0 -0
package/Typeguards.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type * as t from '@babel/types';
|
|
2
|
+
import type * as parse5 from 'parse5';
|
|
3
|
+
export type Parse5Node = parse5.DefaultTreeAdapterMap['node'];
|
|
4
|
+
export type Parse5Element = parse5.DefaultTreeAdapterMap['element'];
|
|
5
|
+
export type Parse5TextNode = parse5.DefaultTreeAdapterMap['textNode'];
|
|
6
|
+
export type Parse5CommentNode = parse5.DefaultTreeAdapterMap['commentNode'];
|
|
7
|
+
export type Parse5DocumentFragment = parse5.DefaultTreeAdapterMap['documentFragment'];
|
|
8
|
+
export type Parse5Document = parse5.DefaultTreeAdapterMap['document'];
|
|
9
|
+
export type Parse5ChildNode = parse5.DefaultTreeAdapterMap['childNode'];
|
|
10
|
+
export type Parse5ParentNode = Parse5DocumentFragment | Parse5Element | Parse5Document;
|
|
11
|
+
export declare class Typeguards {
|
|
12
|
+
static isElement(node: Parse5Node): node is Parse5Element;
|
|
13
|
+
static isTextNode(node: Parse5Node): node is Parse5TextNode;
|
|
14
|
+
static isCommentNode(node: Parse5Node): node is Parse5CommentNode;
|
|
15
|
+
static isDocumentFragment(value: unknown): value is Parse5DocumentFragment;
|
|
16
|
+
static isDocumentFragmentLike(value: unknown): value is Parse5DocumentFragment;
|
|
17
|
+
static isRecord(value: unknown): value is Record<string, unknown>;
|
|
18
|
+
static isBabelNode(value: unknown): value is t.Node;
|
|
19
|
+
static isAttrsRecord(value: unknown): value is Record<string, {
|
|
20
|
+
startOffset: number;
|
|
21
|
+
endOffset: number;
|
|
22
|
+
}>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=Typeguards.d.ts.map
|
package/Typeguards.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export class Typeguards {
|
|
2
|
+
static isElement(node) {
|
|
3
|
+
return 'tagName' in node;
|
|
4
|
+
}
|
|
5
|
+
static isTextNode(node) {
|
|
6
|
+
return node.nodeName === '#text' && 'value' in node;
|
|
7
|
+
}
|
|
8
|
+
static isCommentNode(node) {
|
|
9
|
+
return node.nodeName === '#comment';
|
|
10
|
+
}
|
|
11
|
+
static isDocumentFragment(value) {
|
|
12
|
+
if (typeof value !== 'object' || value === null || !('childNodes' in value) || !('nodeName' in value)) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
const nodeNameValue = value.nodeName;
|
|
16
|
+
return nodeNameValue === '#document-fragment';
|
|
17
|
+
}
|
|
18
|
+
static isDocumentFragmentLike(value) {
|
|
19
|
+
return typeof value === 'object' && value !== null && 'childNodes' in value && 'nodeName' in value;
|
|
20
|
+
}
|
|
21
|
+
static isRecord(value) {
|
|
22
|
+
return value !== null && typeof value === 'object';
|
|
23
|
+
}
|
|
24
|
+
static isBabelNode(value) {
|
|
25
|
+
return value !== null && typeof value === 'object' && 'type' in value;
|
|
26
|
+
}
|
|
27
|
+
static isAttrsRecord(value) {
|
|
28
|
+
return value !== null && typeof value === 'object';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -1,20 +1,5 @@
|
|
|
1
1
|
import type { PluginObj } from '@babel/core';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
newSuperClass?: string;
|
|
6
|
-
injectMethods?: {
|
|
7
|
-
name: string;
|
|
8
|
-
body: string;
|
|
9
|
-
}[];
|
|
10
|
-
}
|
|
11
|
-
interface PluginState {
|
|
12
|
-
opts: ClassTransformOptions;
|
|
13
|
-
}
|
|
14
|
-
export default function classTransformPlugin(): PluginObj<PluginState>;
|
|
15
|
-
export declare function injectMethodBodies(code: string, methods: {
|
|
16
|
-
name: string;
|
|
17
|
-
body: string;
|
|
18
|
-
}[]): string;
|
|
19
|
-
export {};
|
|
2
|
+
import type { BabelPluginClassTransformState } from './interfaces/BabelPluginClassTransformState.js';
|
|
3
|
+
export type { ClassTransformOptions } from './interfaces/ClassTransformOptions.js';
|
|
4
|
+
export default function classTransformPlugin(): PluginObj<BabelPluginClassTransformState>;
|
|
20
5
|
//# sourceMappingURL=babel-plugin-class-transform.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { types as t } from '@babel/core';
|
|
2
|
+
import { parseMethodBody } from './BabelHelpers.js';
|
|
2
3
|
export default function classTransformPlugin() {
|
|
3
4
|
return {
|
|
4
5
|
name: 'babel-plugin-class-transform', visitor: {
|
|
@@ -16,9 +17,8 @@ export default function classTransformPlugin() {
|
|
|
16
17
|
if (injectMethods && injectMethods.length > 0) {
|
|
17
18
|
const newMethods = [];
|
|
18
19
|
for (const method of injectMethods) {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
]));
|
|
20
|
+
const bodyStatements = parseMethodBody(method.body);
|
|
21
|
+
const methodNode = t.classMethod('method', t.identifier(method.name), [], t.blockStatement(bodyStatements));
|
|
22
22
|
newMethods.push(methodNode);
|
|
23
23
|
}
|
|
24
24
|
for (const method of newMethods.reverse()) {
|
|
@@ -30,11 +30,3 @@ export default function classTransformPlugin() {
|
|
|
30
30
|
}
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
-
export function injectMethodBodies(code, methods) {
|
|
34
|
-
let result = code;
|
|
35
|
-
for (const method of methods) {
|
|
36
|
-
const placeholder = `__INJECT_${method.name}__;`;
|
|
37
|
-
result = result.replace(placeholder, method.body);
|
|
38
|
-
}
|
|
39
|
-
return result;
|
|
40
|
-
}
|
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
import type { PluginObj } from '@babel/core';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
template?: string;
|
|
6
|
-
styleUrl?: string;
|
|
7
|
-
styles?: string;
|
|
8
|
-
className: string;
|
|
9
|
-
}
|
|
2
|
+
import type { BabelPluginComponentState } from './interfaces/BabelPluginComponentState.js';
|
|
3
|
+
import type { ComponentMetadata } from './interfaces/ComponentMetadata.js';
|
|
4
|
+
export type { ComponentMetadata } from './interfaces/ComponentMetadata.js';
|
|
10
5
|
export declare const componentMetadataMap: Map<string, ComponentMetadata>;
|
|
11
|
-
|
|
12
|
-
filename?: string;
|
|
13
|
-
}
|
|
14
|
-
export default function componentPlugin(): PluginObj<PluginState>;
|
|
15
|
-
export {};
|
|
6
|
+
export default function componentPlugin(): PluginObj<BabelPluginComponentState>;
|
|
16
7
|
//# sourceMappingURL=babel-plugin-component.d.ts.map
|
|
@@ -16,6 +16,13 @@ export default function componentPlugin() {
|
|
|
16
16
|
return;
|
|
17
17
|
if (!t.isCallExpression(componentDecorator.expression))
|
|
18
18
|
return;
|
|
19
|
+
const { superClass } = path.node;
|
|
20
|
+
if (!superClass || !t.isIdentifier(superClass) || superClass.name !== 'HTMLElement') {
|
|
21
|
+
const className = path.node.id?.name ?? 'Unknown';
|
|
22
|
+
const filename = state.filename ?? 'unknown';
|
|
23
|
+
throw path.buildCodeFrameError(`Component class '${className}' must extend HTMLElement.\n` +
|
|
24
|
+
`Add 'extends HTMLElement' to the class declaration in ${filename}`);
|
|
25
|
+
}
|
|
19
26
|
const args = componentDecorator.expression.arguments;
|
|
20
27
|
if (args.length === 0)
|
|
21
28
|
return;
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
import type { PluginObj } from '@babel/core';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
pathReplacements?: Record<string, string>;
|
|
6
|
-
addJsExtension?: boolean;
|
|
7
|
-
}
|
|
8
|
-
interface PluginState {
|
|
9
|
-
opts: ImportTransformOptions;
|
|
10
|
-
}
|
|
11
|
-
export default function importsPlugin(): PluginObj<PluginState>;
|
|
12
|
-
export {};
|
|
2
|
+
import type { BabelPluginImportsState } from './interfaces/BabelPluginImportsState.js';
|
|
3
|
+
export type { ImportTransformOptions } from './interfaces/ImportTransformOptions.js';
|
|
4
|
+
export default function importsPlugin(): PluginObj<BabelPluginImportsState>;
|
|
13
5
|
//# sourceMappingURL=babel-plugin-imports.d.ts.map
|
package/babel-plugin-imports.js
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
import { types as t } from '@babel/core';
|
|
2
|
-
|
|
3
|
-
const expr = decorator.expression;
|
|
4
|
-
if (t.isCallExpression(expr) && t.isIdentifier(expr.callee)) {
|
|
5
|
-
return expr.callee.name;
|
|
6
|
-
}
|
|
7
|
-
if (t.isIdentifier(expr)) {
|
|
8
|
-
return expr.name;
|
|
9
|
-
}
|
|
10
|
-
return null;
|
|
11
|
-
}
|
|
2
|
+
import { filterDecoratorsFromNode } from './BabelHelpers.js';
|
|
12
3
|
export default function importsPlugin() {
|
|
4
|
+
// noinspection JSUnusedGlobalSymbols
|
|
13
5
|
return {
|
|
14
6
|
name: 'babel-plugin-imports', visitor: {
|
|
15
7
|
ImportDeclaration(path, state) {
|
|
@@ -39,37 +31,19 @@ export default function importsPlugin() {
|
|
|
39
31
|
const { removeDecorators } = state.opts ?? {};
|
|
40
32
|
if (!removeDecorators?.length)
|
|
41
33
|
return;
|
|
42
|
-
|
|
43
|
-
if (!decorators)
|
|
44
|
-
return;
|
|
45
|
-
path.node.decorators = decorators.filter(dec => {
|
|
46
|
-
const name = getDecoratorName(dec);
|
|
47
|
-
return !name || !removeDecorators.includes(name);
|
|
48
|
-
});
|
|
34
|
+
filterDecoratorsFromNode(path.node, removeDecorators);
|
|
49
35
|
},
|
|
50
36
|
ClassProperty(path, state) {
|
|
51
37
|
const { removeDecorators } = state.opts ?? {};
|
|
52
38
|
if (!removeDecorators?.length)
|
|
53
39
|
return;
|
|
54
|
-
|
|
55
|
-
if (!decorators)
|
|
56
|
-
return;
|
|
57
|
-
path.node.decorators = decorators.filter(dec => {
|
|
58
|
-
const name = getDecoratorName(dec);
|
|
59
|
-
return !name || !removeDecorators.includes(name);
|
|
60
|
-
});
|
|
40
|
+
filterDecoratorsFromNode(path.node, removeDecorators);
|
|
61
41
|
},
|
|
62
42
|
ClassMethod(path, state) {
|
|
63
43
|
const { removeDecorators } = state.opts ?? {};
|
|
64
44
|
if (!removeDecorators?.length)
|
|
65
45
|
return;
|
|
66
|
-
|
|
67
|
-
if (!decorators)
|
|
68
|
-
return;
|
|
69
|
-
path.node.decorators = decorators.filter(dec => {
|
|
70
|
-
const name = getDecoratorName(dec);
|
|
71
|
-
return !name || !removeDecorators.includes(name);
|
|
72
|
-
});
|
|
46
|
+
filterDecoratorsFromNode(path.node, removeDecorators);
|
|
73
47
|
}
|
|
74
48
|
}
|
|
75
49
|
};
|
|
@@ -1,22 +1,5 @@
|
|
|
1
1
|
import type { PluginObj } from '@babel/core';
|
|
2
|
-
import {
|
|
3
|
-
interface WatchInfo {
|
|
4
|
-
methodName: string;
|
|
5
|
-
watchedProps: string[];
|
|
6
|
-
}
|
|
7
|
-
interface WatchCallInfo {
|
|
8
|
-
propName: string;
|
|
9
|
-
watchedProps: string[];
|
|
10
|
-
callbackArg: t.Expression | t.SpreadElement | t.JSXNamespacedName | t.ArgumentPlaceholder;
|
|
11
|
-
}
|
|
12
|
-
interface PluginState {
|
|
13
|
-
filename?: string;
|
|
14
|
-
needsPropertyImport?: boolean;
|
|
15
|
-
reactiveProperties?: Set<string>;
|
|
16
|
-
watchMethods?: WatchInfo[];
|
|
17
|
-
watchCalls?: WatchCallInfo[];
|
|
18
|
-
}
|
|
2
|
+
import type { BabelPluginReactiveState } from './interfaces/BabelPluginReactiveState.js';
|
|
19
3
|
export declare const reactivePropertiesMap: Map<string, Set<string>>;
|
|
20
|
-
export default function reactivePlugin(): PluginObj<
|
|
21
|
-
export {};
|
|
4
|
+
export default function reactivePlugin(): PluginObj<BabelPluginReactiveState>;
|
|
22
5
|
//# sourceMappingURL=babel-plugin-reactive.d.ts.map
|
package/babel-plugin-reactive.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { types as t } from '@babel/core';
|
|
2
|
+
import { buildHostBindingUpdateStatement, findDecoratorIndex, getDecoratorName } from './BabelHelpers.js';
|
|
2
3
|
export const reactivePropertiesMap = new Map();
|
|
3
4
|
export default function reactivePlugin() {
|
|
5
|
+
// noinspection JSUnusedGlobalSymbols
|
|
4
6
|
return {
|
|
5
7
|
name: 'babel-plugin-reactive', visitor: {
|
|
6
8
|
Program: {
|
|
@@ -73,12 +75,7 @@ export default function reactivePlugin() {
|
|
|
73
75
|
if (memberPath.isClassMethod()) {
|
|
74
76
|
const methodNode = memberPath.node;
|
|
75
77
|
const decorators = methodNode.decorators ?? [];
|
|
76
|
-
const hostListenerIndex = decorators
|
|
77
|
-
if (t.isCallExpression(dec.expression) && t.isIdentifier(dec.expression.callee)) {
|
|
78
|
-
return dec.expression.callee.name === 'HostListener';
|
|
79
|
-
}
|
|
80
|
-
return false;
|
|
81
|
-
});
|
|
78
|
+
const hostListenerIndex = findDecoratorIndex(decorators, 'HostListener');
|
|
82
79
|
if (hostListenerIndex >= 0) {
|
|
83
80
|
const hostListenerDecorator = decorators[hostListenerIndex];
|
|
84
81
|
if (t.isCallExpression(hostListenerDecorator.expression)) {
|
|
@@ -94,12 +91,7 @@ export default function reactivePlugin() {
|
|
|
94
91
|
}
|
|
95
92
|
decorators.splice(hostListenerIndex, 1);
|
|
96
93
|
}
|
|
97
|
-
const pipeDecoratorIndex = decorators
|
|
98
|
-
if (t.isCallExpression(dec.expression) && t.isIdentifier(dec.expression.callee)) {
|
|
99
|
-
return dec.expression.callee.name === 'Pipe';
|
|
100
|
-
}
|
|
101
|
-
return false;
|
|
102
|
-
});
|
|
94
|
+
const pipeDecoratorIndex = findDecoratorIndex(decorators, 'Pipe');
|
|
103
95
|
if (pipeDecoratorIndex >= 0) {
|
|
104
96
|
const pipeDecorator = decorators[pipeDecoratorIndex];
|
|
105
97
|
if (t.isCallExpression(pipeDecorator.expression)) {
|
|
@@ -115,12 +107,7 @@ export default function reactivePlugin() {
|
|
|
115
107
|
}
|
|
116
108
|
decorators.splice(pipeDecoratorIndex, 1);
|
|
117
109
|
}
|
|
118
|
-
const watchDecoratorIndex = decorators
|
|
119
|
-
if (t.isCallExpression(dec.expression) && t.isIdentifier(dec.expression.callee)) {
|
|
120
|
-
return dec.expression.callee.name === 'Watch';
|
|
121
|
-
}
|
|
122
|
-
return false;
|
|
123
|
-
});
|
|
110
|
+
const watchDecoratorIndex = findDecoratorIndex(decorators, 'Watch');
|
|
124
111
|
if (watchDecoratorIndex >= 0) {
|
|
125
112
|
const watchDecorator = decorators[watchDecoratorIndex];
|
|
126
113
|
if (t.isCallExpression(watchDecorator.expression)) {
|
|
@@ -137,12 +124,7 @@ export default function reactivePlugin() {
|
|
|
137
124
|
decorators.splice(watchDecoratorIndex, 1);
|
|
138
125
|
}
|
|
139
126
|
if (methodNode.kind === 'get') {
|
|
140
|
-
const hostBindingIndex = decorators
|
|
141
|
-
if (t.isCallExpression(dec.expression) && t.isIdentifier(dec.expression.callee)) {
|
|
142
|
-
return dec.expression.callee.name === 'HostBinding';
|
|
143
|
-
}
|
|
144
|
-
return false;
|
|
145
|
-
});
|
|
127
|
+
const hostBindingIndex = findDecoratorIndex(decorators, 'HostBinding');
|
|
146
128
|
if (hostBindingIndex >= 0) {
|
|
147
129
|
const hostBindingDecorator = decorators[hostBindingIndex];
|
|
148
130
|
if (t.isCallExpression(hostBindingDecorator.expression)) {
|
|
@@ -150,25 +132,7 @@ export default function reactivePlugin() {
|
|
|
150
132
|
if (args.length > 0 && t.isStringLiteral(args[0]) && t.isIdentifier(methodNode.key)) {
|
|
151
133
|
const hostProperty = args[0].value;
|
|
152
134
|
const getterName = methodNode.key.name;
|
|
153
|
-
|
|
154
|
-
if (hostProperty.startsWith('class.')) {
|
|
155
|
-
const className = hostProperty.slice(6);
|
|
156
|
-
updateStatement = t.ifStatement(t.identifier('__v'), t.expressionStatement(t.callExpression(t.memberExpression(t.memberExpression(t.thisExpression(), t.identifier('classList')), t.identifier('add')), [t.stringLiteral(className)])), t.expressionStatement(t.callExpression(t.memberExpression(t.memberExpression(t.thisExpression(), t.identifier('classList')), t.identifier('remove')), [t.stringLiteral(className)])));
|
|
157
|
-
}
|
|
158
|
-
else if (hostProperty.startsWith('attr.')) {
|
|
159
|
-
const attrName = hostProperty.slice(5);
|
|
160
|
-
updateStatement = t.ifStatement(t.binaryExpression('!=', t.identifier('__v'), t.nullLiteral()), t.expressionStatement(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('setAttribute')), [
|
|
161
|
-
t.stringLiteral(attrName),
|
|
162
|
-
t.callExpression(t.identifier('String'), [t.identifier('__v')])
|
|
163
|
-
])), t.expressionStatement(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('removeAttribute')), [t.stringLiteral(attrName)])));
|
|
164
|
-
}
|
|
165
|
-
else if (hostProperty.startsWith('style.')) {
|
|
166
|
-
const styleProp = hostProperty.slice(6);
|
|
167
|
-
updateStatement = t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.memberExpression(t.thisExpression(), t.identifier('style')), t.identifier(styleProp)), t.logicalExpression('||', t.identifier('__v'), t.stringLiteral(''))));
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
updateStatement = t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.thisExpression(), t.identifier(hostProperty)), t.identifier('__v')));
|
|
171
|
-
}
|
|
135
|
+
const updateStatement = buildHostBindingUpdateStatement(hostProperty);
|
|
172
136
|
const updateMethod = t.classMethod('method', t.identifier(`__updateHostBinding_${getterName}`), [], t.blockStatement([
|
|
173
137
|
t.variableDeclaration('const', [t.variableDeclarator(t.identifier('__v'), t.memberExpression(t.thisExpression(), t.identifier(getterName)))]),
|
|
174
138
|
updateStatement
|
|
@@ -186,12 +150,7 @@ export default function reactivePlugin() {
|
|
|
186
150
|
continue;
|
|
187
151
|
const propNode = memberPath.node;
|
|
188
152
|
const decorators = propNode.decorators ?? [];
|
|
189
|
-
const hostBindingDecoratorIndex = decorators
|
|
190
|
-
if (t.isCallExpression(dec.expression) && t.isIdentifier(dec.expression.callee)) {
|
|
191
|
-
return dec.expression.callee.name === 'HostBinding';
|
|
192
|
-
}
|
|
193
|
-
return false;
|
|
194
|
-
});
|
|
153
|
+
const hostBindingDecoratorIndex = findDecoratorIndex(decorators, 'HostBinding');
|
|
195
154
|
if (hostBindingDecoratorIndex >= 0) {
|
|
196
155
|
const hostBindingDecorator = decorators[hostBindingDecoratorIndex];
|
|
197
156
|
if (t.isCallExpression(hostBindingDecorator.expression)) {
|
|
@@ -205,25 +164,7 @@ export default function reactivePlugin() {
|
|
|
205
164
|
const getter = t.classMethod('get', t.identifier(propName), [], t.blockStatement([
|
|
206
165
|
t.returnStatement(t.memberExpression(t.thisExpression(), t.identifier(privateName)))
|
|
207
166
|
]));
|
|
208
|
-
|
|
209
|
-
if (hostProperty.startsWith('class.')) {
|
|
210
|
-
const className = hostProperty.slice(6);
|
|
211
|
-
updateStatement = t.ifStatement(t.identifier('__v'), t.expressionStatement(t.callExpression(t.memberExpression(t.memberExpression(t.thisExpression(), t.identifier('classList')), t.identifier('add')), [t.stringLiteral(className)])), t.expressionStatement(t.callExpression(t.memberExpression(t.memberExpression(t.thisExpression(), t.identifier('classList')), t.identifier('remove')), [t.stringLiteral(className)])));
|
|
212
|
-
}
|
|
213
|
-
else if (hostProperty.startsWith('attr.')) {
|
|
214
|
-
const attrName = hostProperty.slice(5);
|
|
215
|
-
updateStatement = t.ifStatement(t.binaryExpression('!=', t.identifier('__v'), t.nullLiteral()), t.expressionStatement(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('setAttribute')), [
|
|
216
|
-
t.stringLiteral(attrName),
|
|
217
|
-
t.callExpression(t.identifier('String'), [t.identifier('__v')])
|
|
218
|
-
])), t.expressionStatement(t.callExpression(t.memberExpression(t.thisExpression(), t.identifier('removeAttribute')), [t.stringLiteral(attrName)])));
|
|
219
|
-
}
|
|
220
|
-
else if (hostProperty.startsWith('style.')) {
|
|
221
|
-
const styleProp = hostProperty.slice(6);
|
|
222
|
-
updateStatement = t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.memberExpression(t.thisExpression(), t.identifier('style')), t.identifier(styleProp)), t.logicalExpression('||', t.identifier('__v'), t.stringLiteral(''))));
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
updateStatement = t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.thisExpression(), t.identifier(hostProperty)), t.identifier('__v')));
|
|
226
|
-
}
|
|
167
|
+
const updateStatement = buildHostBindingUpdateStatement(hostProperty);
|
|
227
168
|
const setter = t.classMethod('set', t.identifier(propName), [t.identifier('__v')], t.blockStatement([
|
|
228
169
|
t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.thisExpression(), t.identifier(privateName)), t.identifier('__v'))),
|
|
229
170
|
updateStatement
|
|
@@ -236,12 +177,7 @@ export default function reactivePlugin() {
|
|
|
236
177
|
}
|
|
237
178
|
continue;
|
|
238
179
|
}
|
|
239
|
-
const viewChildDecoratorIndex = decorators
|
|
240
|
-
if (t.isCallExpression(dec.expression) && t.isIdentifier(dec.expression.callee)) {
|
|
241
|
-
return dec.expression.callee.name === 'ViewChild';
|
|
242
|
-
}
|
|
243
|
-
return false;
|
|
244
|
-
});
|
|
180
|
+
const viewChildDecoratorIndex = findDecoratorIndex(decorators, 'ViewChild');
|
|
245
181
|
if (viewChildDecoratorIndex >= 0) {
|
|
246
182
|
const viewChildDecorator = decorators[viewChildDecoratorIndex];
|
|
247
183
|
if (t.isCallExpression(viewChildDecorator.expression)) {
|
|
@@ -260,7 +196,7 @@ export default function reactivePlugin() {
|
|
|
260
196
|
}
|
|
261
197
|
const reactiveDecoratorIndices = [];
|
|
262
198
|
for (const [idx, dec] of decorators.entries()) {
|
|
263
|
-
const name =
|
|
199
|
+
const name = getDecoratorName(dec);
|
|
264
200
|
if (name === 'Reactive' || name === 'Input') {
|
|
265
201
|
reactiveDecoratorIndices.push(idx);
|
|
266
202
|
}
|
|
@@ -277,7 +213,16 @@ export default function reactivePlugin() {
|
|
|
277
213
|
const initialValue = propNode.value ?? t.identifier('undefined');
|
|
278
214
|
state.needsPropertyImport = true;
|
|
279
215
|
state.reactiveProperties?.add(propName);
|
|
280
|
-
const
|
|
216
|
+
const isProduction = state.opts?.production ?? false;
|
|
217
|
+
const propertyArgs = isProduction
|
|
218
|
+
? [initialValue]
|
|
219
|
+
: [
|
|
220
|
+
t.objectExpression([
|
|
221
|
+
t.objectProperty(t.identifier('initialValue'), initialValue),
|
|
222
|
+
t.objectProperty(t.identifier('propertyName'), t.stringLiteral(propName))
|
|
223
|
+
])
|
|
224
|
+
];
|
|
225
|
+
const privateField = t.classProperty(t.identifier(privateName), t.newExpression(t.identifier('Property'), propertyArgs));
|
|
281
226
|
const getter = t.classMethod('get', t.identifier(propName), [], t.blockStatement([
|
|
282
227
|
t.returnStatement(t.callExpression(t.memberExpression(t.memberExpression(t.thisExpression(), t.identifier(privateName)), t.identifier('getValue')), []))
|
|
283
228
|
]));
|
package/bin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { Cli
|
|
3
|
-
const { options, args } = parseArgs(process.argv.slice(2));
|
|
2
|
+
import { Cli } from './Cli.js';
|
|
3
|
+
const { options, args } = Cli.parseArgs(process.argv.slice(2));
|
|
4
4
|
const cli = new Cli(options);
|
|
5
5
|
cli.run(args)
|
|
6
6
|
.catch((error) => {
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import type { Plugin } from 'esbuild';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
minify?: boolean;
|
|
5
|
-
sourcemap?: boolean;
|
|
6
|
-
}
|
|
2
|
+
import type { FluffPluginOptions } from './interfaces/FluffPluginOptions.js';
|
|
3
|
+
export type { FluffPluginOptions } from './interfaces/FluffPluginOptions.js';
|
|
7
4
|
export declare function fluffPlugin(options: FluffPluginOptions): Plugin;
|
|
8
5
|
//# sourceMappingURL=fluff-esbuild-plugin.d.ts.map
|
package/fluff-esbuild-plugin.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
|
+
import { CodeGenerator } from './CodeGenerator.js';
|
|
4
5
|
import { ComponentCompiler } from './ComponentCompiler.js';
|
|
5
6
|
function findFluffSourcePath() {
|
|
6
7
|
const thisFile = fileURLToPath(import.meta.url);
|
|
@@ -17,17 +18,19 @@ export function fluffPlugin(options) {
|
|
|
17
18
|
const compiler = new ComponentCompiler();
|
|
18
19
|
let componentsDiscovered = false;
|
|
19
20
|
const fluffSrcPath = findFluffSourcePath();
|
|
21
|
+
// noinspection JSUnusedGlobalSymbols
|
|
20
22
|
return {
|
|
21
23
|
name: 'fluff',
|
|
22
24
|
setup(build) {
|
|
23
25
|
build.onStart(async () => {
|
|
26
|
+
CodeGenerator.resetGlobalState();
|
|
24
27
|
if (!componentsDiscovered) {
|
|
25
28
|
await compiler.discoverComponents(options.srcDir);
|
|
26
29
|
componentsDiscovered = true;
|
|
27
30
|
}
|
|
28
31
|
});
|
|
29
32
|
build.onLoad({ filter: /\.component\.ts$/ }, async (args) => {
|
|
30
|
-
const result = await compiler.compileComponentForBundle(args.path, options.minify, options.sourcemap);
|
|
33
|
+
const result = await compiler.compileComponentForBundle(args.path, options.minify, options.sourcemap, options.skipDefine, options.production);
|
|
31
34
|
return {
|
|
32
35
|
contents: result.code,
|
|
33
36
|
loader: 'js',
|
package/index.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
export { ComponentCompiler } from './ComponentCompiler.js';
|
|
2
2
|
export { TemplateParser } from './TemplateParser.js';
|
|
3
3
|
export { CodeGenerator } from './CodeGenerator.js';
|
|
4
|
-
export { Cli
|
|
5
|
-
export type
|
|
4
|
+
export { Cli } from './Cli.js';
|
|
5
|
+
export type { ComponentInfo } from './interfaces/ComponentInfo.js';
|
|
6
|
+
export type { CompilerOptions } from './interfaces/CompilerOptions.js';
|
|
7
|
+
export type { ControlFlow, SwitchCaseOld } from './interfaces/ControlFlow.js';
|
|
8
|
+
export type { ParsedTemplateOld } from './interfaces/ParsedTemplateOld.js';
|
|
9
|
+
export type { TemplateBinding } from './interfaces/TemplateBinding.js';
|
|
6
10
|
export type * from './types/FluffConfig.js';
|
|
7
11
|
//# sourceMappingURL=index.d.ts.map
|
package/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BabelPluginReactiveWatchCallInfo } from './BabelPluginReactiveWatchCallInfo.js';
|
|
2
|
+
import type { BabelPluginReactiveWatchInfo } from './BabelPluginReactiveWatchInfo.js';
|
|
3
|
+
export interface BabelPluginReactiveState {
|
|
4
|
+
filename?: string;
|
|
5
|
+
needsPropertyImport?: boolean;
|
|
6
|
+
reactiveProperties?: Set<string>;
|
|
7
|
+
watchMethods?: BabelPluginReactiveWatchInfo[];
|
|
8
|
+
watchCalls?: BabelPluginReactiveWatchCallInfo[];
|
|
9
|
+
opts?: {
|
|
10
|
+
production?: boolean;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=BabelPluginReactiveState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { types as t } from '@babel/core';
|
|
2
|
+
export interface BabelPluginReactiveWatchCallInfo {
|
|
3
|
+
propName: string;
|
|
4
|
+
watchedProps: string[];
|
|
5
|
+
callbackArg: t.Expression | t.SpreadElement | t.JSXNamespacedName | t.ArgumentPlaceholder;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=BabelPluginReactiveWatchCallInfo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PropertyChain } from './PropertyChain.js';
|
|
2
|
+
export interface BindingInfo {
|
|
3
|
+
name: string;
|
|
4
|
+
binding: 'property' | 'event' | 'two-way' | 'class' | 'style' | 'ref';
|
|
5
|
+
expression?: string;
|
|
6
|
+
exprId?: number;
|
|
7
|
+
handlerId?: number;
|
|
8
|
+
targetProp?: string;
|
|
9
|
+
deps?: PropertyChain[];
|
|
10
|
+
subscribe?: string;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=BindingInfo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|