@signaltree/callable-syntax 6.0.9 → 6.0.11
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/dist/augmentation.js +1 -0
- package/dist/index.js +3 -0
- package/dist/lib/ast-transform.js +74 -0
- package/dist/lib/vite-plugin.js +25 -0
- package/dist/lib/webpack-plugin.js +44 -0
- package/package.json +1 -1
- package/src/augmentation.d.ts +1 -10
- package/src/index.d.ts +4 -0
- package/src/lib/ast-transform.d.ts +10 -0
- package/src/lib/syntax-transform.d.ts +1 -0
- package/src/lib/vite-plugin.d.ts +16 -0
- package/src/lib/webpack-plugin.d.ts +25 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import generate from '@babel/generator';
|
|
2
|
+
import { parse } from '@babel/parser';
|
|
3
|
+
import traverse from '@babel/traverse';
|
|
4
|
+
import * as t from '@babel/types';
|
|
5
|
+
|
|
6
|
+
const DEFAULT_ROOT_IDENTIFIERS = ['tree'];
|
|
7
|
+
function transformCode(source, options = {}) {
|
|
8
|
+
var _a;
|
|
9
|
+
const rootIds = ((_a = options.rootIdentifiers) === null || _a === void 0 ? void 0 : _a.length) ? options.rootIdentifiers : DEFAULT_ROOT_IDENTIFIERS;
|
|
10
|
+
const ast = parseSourceCode(source);
|
|
11
|
+
let transformCount = 0;
|
|
12
|
+
traverse(ast, {
|
|
13
|
+
CallExpression(path) {
|
|
14
|
+
const {
|
|
15
|
+
node
|
|
16
|
+
} = path;
|
|
17
|
+
if (!t.isCallExpression(node)) return;
|
|
18
|
+
if (shouldTransformCallExpression(node, rootIds)) {
|
|
19
|
+
const transformedCall = createTransformedCall(node);
|
|
20
|
+
path.replaceWith(transformedCall);
|
|
21
|
+
transformCount++;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const output = generate(ast, {
|
|
26
|
+
retainLines: false,
|
|
27
|
+
comments: true
|
|
28
|
+
}, source);
|
|
29
|
+
if (options.debug && transformCount > 0) {
|
|
30
|
+
console.log(`[signaltree callable-syntax] transformed ${transformCount} calls`);
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
code: output.code,
|
|
34
|
+
transformed: transformCount
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function parseSourceCode(source) {
|
|
38
|
+
return parse(source, {
|
|
39
|
+
sourceType: 'module',
|
|
40
|
+
plugins: ['typescript', 'jsx']
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function shouldTransformCallExpression(node, rootIds) {
|
|
44
|
+
if (!t.isMemberExpression(node.callee)) return false;
|
|
45
|
+
if (node.arguments.length === 0) return false;
|
|
46
|
+
if (isAlreadyTransformed(node.callee)) return false;
|
|
47
|
+
return isRootedSignalAccess(node.callee, rootIds);
|
|
48
|
+
}
|
|
49
|
+
function isAlreadyTransformed(callee) {
|
|
50
|
+
return t.isIdentifier(callee.property) && (callee.property.name === 'set' || callee.property.name === 'update');
|
|
51
|
+
}
|
|
52
|
+
function createTransformedCall(node) {
|
|
53
|
+
const callee = node.callee;
|
|
54
|
+
const method = determineMethod(node.arguments[0]);
|
|
55
|
+
return t.callExpression(t.memberExpression(callee, t.identifier(method)), node.arguments);
|
|
56
|
+
}
|
|
57
|
+
function determineMethod(firstArg) {
|
|
58
|
+
if (t.isFunctionExpression(firstArg) || t.isArrowFunctionExpression(firstArg)) {
|
|
59
|
+
return 'update';
|
|
60
|
+
}
|
|
61
|
+
return 'set';
|
|
62
|
+
}
|
|
63
|
+
function isRootedSignalAccess(expr, roots) {
|
|
64
|
+
let current = expr;
|
|
65
|
+
while (t.isMemberExpression(current)) {
|
|
66
|
+
if (t.isIdentifier(current.object)) {
|
|
67
|
+
return roots.includes(current.object.name);
|
|
68
|
+
}
|
|
69
|
+
current = current.object;
|
|
70
|
+
}
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { DEFAULT_ROOT_IDENTIFIERS, transformCode };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { transformCode } from './ast-transform.js';
|
|
2
|
+
|
|
3
|
+
function signalTreeSyntaxTransform(options = {}) {
|
|
4
|
+
var _a, _b;
|
|
5
|
+
const include = (_a = options.include) !== null && _a !== void 0 ? _a : /src\/.*\.(t|j)sx?$/;
|
|
6
|
+
const exclude = (_b = options.exclude) !== null && _b !== void 0 ? _b : /node_modules|\.spec\.|\.test\./;
|
|
7
|
+
return {
|
|
8
|
+
name: 'signaltree-callable-syntax',
|
|
9
|
+
enforce: 'pre',
|
|
10
|
+
transform(code, id) {
|
|
11
|
+
if (!include.test(id) || exclude.test(id)) return null;
|
|
12
|
+
const result = transformCode(code, {
|
|
13
|
+
rootIdentifiers: options.rootIdentifiers,
|
|
14
|
+
debug: options.debug
|
|
15
|
+
});
|
|
16
|
+
if (result.transformed === 0) return null;
|
|
17
|
+
return {
|
|
18
|
+
code: result.code,
|
|
19
|
+
map: null
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { signalTreeSyntaxTransform };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { transformCode } from './ast-transform.js';
|
|
2
|
+
|
|
3
|
+
class SignalTreeSyntaxWebpackPlugin {
|
|
4
|
+
constructor(options = {}) {
|
|
5
|
+
this.options = options;
|
|
6
|
+
}
|
|
7
|
+
apply(compiler) {
|
|
8
|
+
var _a, _b;
|
|
9
|
+
const test = (_a = this.options.test) !== null && _a !== void 0 ? _a : /src\/.*\.(t|j)sx?$/;
|
|
10
|
+
const exclude = (_b = this.options.exclude) !== null && _b !== void 0 ? _b : /node_modules|\.spec\.|\.test\./;
|
|
11
|
+
compiler.hooks.emit.tapAsync('SignalTreeSyntaxWebpackPlugin', (compilation, cb) => {
|
|
12
|
+
for (const filename of Object.keys(compilation.assets)) {
|
|
13
|
+
if (!test.test(filename) || exclude.test(filename)) continue;
|
|
14
|
+
const asset = compilation.assets[filename];
|
|
15
|
+
const raw = asset.source();
|
|
16
|
+
let source;
|
|
17
|
+
if (typeof raw === 'string') {
|
|
18
|
+
source = raw;
|
|
19
|
+
} else if (Buffer.isBuffer(raw)) {
|
|
20
|
+
source = raw.toString('utf8');
|
|
21
|
+
} else {
|
|
22
|
+
source = String(raw);
|
|
23
|
+
}
|
|
24
|
+
const {
|
|
25
|
+
code,
|
|
26
|
+
transformed
|
|
27
|
+
} = transformCode(source, {
|
|
28
|
+
rootIdentifiers: this.options.rootIdentifiers,
|
|
29
|
+
debug: this.options.debug
|
|
30
|
+
});
|
|
31
|
+
if (transformed > 0) {
|
|
32
|
+
const updated = code;
|
|
33
|
+
compilation.assets[filename] = {
|
|
34
|
+
source: () => updated,
|
|
35
|
+
size: () => Buffer.byteLength(updated, 'utf8')
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
cb();
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { SignalTreeSyntaxWebpackPlugin };
|
package/package.json
CHANGED
package/src/augmentation.d.ts
CHANGED
|
@@ -1,10 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// Augment Angular WritableSignal so leaves support callable set/update like NodeAccessor.
|
|
4
|
-
// Getter signature already exists on WritableSignal.
|
|
5
|
-
declare module '@angular/core' {
|
|
6
|
-
interface WritableSignal<T> {
|
|
7
|
-
(value: T extends (...args: unknown[]) => unknown ? never : T): void;
|
|
8
|
-
(updater: (current: T) => T): void;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
1
|
+
export {};
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface TransformOptions {
|
|
2
|
+
readonly rootIdentifiers?: string[];
|
|
3
|
+
readonly debug?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export interface TransformResult {
|
|
6
|
+
code: string;
|
|
7
|
+
transformed: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const DEFAULT_ROOT_IDENTIFIERS: string[];
|
|
10
|
+
export declare function transformCode(source: string, options?: TransformOptions): TransformResult;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const syntaxTransform: () => string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type Plugin = {
|
|
2
|
+
name: string;
|
|
3
|
+
enforce?: 'pre' | 'post';
|
|
4
|
+
transform?: (code: string, id: string) => {
|
|
5
|
+
code: string;
|
|
6
|
+
map: null;
|
|
7
|
+
} | null;
|
|
8
|
+
};
|
|
9
|
+
export interface SignalTreeVitePluginOptions {
|
|
10
|
+
include?: RegExp;
|
|
11
|
+
exclude?: RegExp;
|
|
12
|
+
rootIdentifiers?: string[];
|
|
13
|
+
debug?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function signalTreeSyntaxTransform(options?: SignalTreeVitePluginOptions): Plugin;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
interface CompilationLike {
|
|
2
|
+
assets: Record<string, {
|
|
3
|
+
source(): unknown;
|
|
4
|
+
size(): number;
|
|
5
|
+
}>;
|
|
6
|
+
}
|
|
7
|
+
interface CompilerLike {
|
|
8
|
+
hooks: {
|
|
9
|
+
emit: {
|
|
10
|
+
tapAsync(name: string, cb: (compilation: CompilationLike, done: (err?: Error) => void) => void): void;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export interface SignalTreeWebpackPluginOptions {
|
|
15
|
+
test?: RegExp;
|
|
16
|
+
exclude?: RegExp;
|
|
17
|
+
rootIdentifiers?: string[];
|
|
18
|
+
debug?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare class SignalTreeSyntaxWebpackPlugin {
|
|
21
|
+
private readonly options;
|
|
22
|
+
constructor(options?: SignalTreeWebpackPluginOptions);
|
|
23
|
+
apply(compiler: CompilerLike): void;
|
|
24
|
+
}
|
|
25
|
+
export {};
|