@esportsplus/reactivity 0.24.1 → 0.24.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/build/transformer/factory.d.ts +13 -0
- package/build/transformer/factory.js +36 -0
- package/build/transformer/index.d.ts +4 -6
- package/build/transformer/index.js +97 -39
- package/build/transformer/plugins/vite.js +7 -4
- package/build/transformer/transforms/array.d.ts +2 -2
- package/build/transformer/transforms/array.js +20 -22
- package/build/transformer/transforms/object.d.ts +8 -2
- package/build/transformer/transforms/object.js +87 -99
- package/build/transformer/transforms/primitives.d.ts +2 -2
- package/build/transformer/transforms/primitives.js +130 -184
- package/build/types.d.ts +1 -7
- package/package.json +1 -1
- package/src/transformer/factory.ts +139 -0
- package/src/transformer/index.ts +171 -45
- package/src/transformer/plugins/vite.ts +13 -5
- package/src/transformer/transforms/array.ts +35 -31
- package/src/transformer/transforms/object.ts +286 -136
- package/src/transformer/transforms/primitives.ts +222 -235
- package/src/types.ts +1 -9
- package/test/vite.config.ts +1 -1
- package/build/transformer/transforms/utilities.d.ts +0 -8
- package/build/transformer/transforms/utilities.js +0 -27
- package/src/transformer/transforms/utilities.ts +0 -45
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { uid } from '@esportsplus/typescript/transformer';
|
|
2
|
-
import {
|
|
2
|
+
import { createCommaExpr, createComputedCall, createPostfixIncrementExpr, createReadCall, createSetCall, createSignalCall } from '../factory.js';
|
|
3
3
|
import { ts } from '@esportsplus/typescript';
|
|
4
4
|
function classifyReactiveArg(arg) {
|
|
5
5
|
if (ts.isArrowFunction(arg) || ts.isFunctionExpression(arg)) {
|
|
@@ -22,14 +22,14 @@ function findBinding(bindings, name, node) {
|
|
|
22
22
|
function findEnclosingScope(node) {
|
|
23
23
|
let current = node.parent;
|
|
24
24
|
while (current) {
|
|
25
|
-
if (ts.
|
|
26
|
-
ts.
|
|
25
|
+
if (ts.isArrowFunction(current) ||
|
|
26
|
+
ts.isBlock(current) ||
|
|
27
|
+
ts.isForInStatement(current) ||
|
|
28
|
+
ts.isForOfStatement(current) ||
|
|
29
|
+
ts.isForStatement(current) ||
|
|
27
30
|
ts.isFunctionDeclaration(current) ||
|
|
28
31
|
ts.isFunctionExpression(current) ||
|
|
29
|
-
ts.
|
|
30
|
-
ts.isForStatement(current) ||
|
|
31
|
-
ts.isForInStatement(current) ||
|
|
32
|
-
ts.isForOfStatement(current)) {
|
|
32
|
+
ts.isSourceFile(current)) {
|
|
33
33
|
return current;
|
|
34
34
|
}
|
|
35
35
|
current = current.parent;
|
|
@@ -38,64 +38,72 @@ function findEnclosingScope(node) {
|
|
|
38
38
|
}
|
|
39
39
|
function getCompoundOperator(kind) {
|
|
40
40
|
if (kind === ts.SyntaxKind.PlusEqualsToken) {
|
|
41
|
-
return
|
|
41
|
+
return ts.SyntaxKind.PlusToken;
|
|
42
42
|
}
|
|
43
43
|
else if (kind === ts.SyntaxKind.MinusEqualsToken) {
|
|
44
|
-
return
|
|
44
|
+
return ts.SyntaxKind.MinusToken;
|
|
45
45
|
}
|
|
46
46
|
else if (kind === ts.SyntaxKind.AsteriskEqualsToken) {
|
|
47
|
-
return
|
|
47
|
+
return ts.SyntaxKind.AsteriskToken;
|
|
48
48
|
}
|
|
49
49
|
else if (kind === ts.SyntaxKind.SlashEqualsToken) {
|
|
50
|
-
return
|
|
50
|
+
return ts.SyntaxKind.SlashToken;
|
|
51
51
|
}
|
|
52
52
|
else if (kind === ts.SyntaxKind.PercentEqualsToken) {
|
|
53
|
-
return
|
|
53
|
+
return ts.SyntaxKind.PercentToken;
|
|
54
54
|
}
|
|
55
55
|
else if (kind === ts.SyntaxKind.AsteriskAsteriskEqualsToken) {
|
|
56
|
-
return
|
|
56
|
+
return ts.SyntaxKind.AsteriskAsteriskToken;
|
|
57
57
|
}
|
|
58
58
|
else if (kind === ts.SyntaxKind.AmpersandEqualsToken) {
|
|
59
|
-
return
|
|
59
|
+
return ts.SyntaxKind.AmpersandToken;
|
|
60
60
|
}
|
|
61
61
|
else if (kind === ts.SyntaxKind.BarEqualsToken) {
|
|
62
|
-
return
|
|
62
|
+
return ts.SyntaxKind.BarToken;
|
|
63
63
|
}
|
|
64
64
|
else if (kind === ts.SyntaxKind.CaretEqualsToken) {
|
|
65
|
-
return
|
|
65
|
+
return ts.SyntaxKind.CaretToken;
|
|
66
66
|
}
|
|
67
67
|
else if (kind === ts.SyntaxKind.LessThanLessThanEqualsToken) {
|
|
68
|
-
return
|
|
68
|
+
return ts.SyntaxKind.LessThanLessThanToken;
|
|
69
69
|
}
|
|
70
70
|
else if (kind === ts.SyntaxKind.GreaterThanGreaterThanEqualsToken) {
|
|
71
|
-
return
|
|
71
|
+
return ts.SyntaxKind.GreaterThanGreaterThanToken;
|
|
72
72
|
}
|
|
73
73
|
else if (kind === ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken) {
|
|
74
|
-
return
|
|
74
|
+
return ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken;
|
|
75
75
|
}
|
|
76
76
|
else if (kind === ts.SyntaxKind.AmpersandAmpersandEqualsToken) {
|
|
77
|
-
return
|
|
77
|
+
return ts.SyntaxKind.AmpersandAmpersandToken;
|
|
78
78
|
}
|
|
79
79
|
else if (kind === ts.SyntaxKind.BarBarEqualsToken) {
|
|
80
|
-
return
|
|
80
|
+
return ts.SyntaxKind.BarBarToken;
|
|
81
81
|
}
|
|
82
82
|
else if (kind === ts.SyntaxKind.QuestionQuestionEqualsToken) {
|
|
83
|
-
return
|
|
83
|
+
return ts.SyntaxKind.QuestionQuestionToken;
|
|
84
84
|
}
|
|
85
85
|
else {
|
|
86
|
-
return
|
|
86
|
+
return ts.SyntaxKind.PlusToken;
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
-
function
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
89
|
+
function isAssignmentOperator(kind) {
|
|
90
|
+
if (kind === ts.SyntaxKind.EqualsToken) {
|
|
91
|
+
return 'simple';
|
|
92
|
+
}
|
|
93
|
+
if (kind >= ts.SyntaxKind.PlusEqualsToken && kind <= ts.SyntaxKind.CaretEqualsToken) {
|
|
94
|
+
return 'compound';
|
|
95
|
+
}
|
|
96
|
+
if (kind === ts.SyntaxKind.AmpersandAmpersandEqualsToken ||
|
|
97
|
+
kind === ts.SyntaxKind.BarBarEqualsToken ||
|
|
98
|
+
kind === ts.SyntaxKind.QuestionQuestionEqualsToken) {
|
|
99
|
+
return 'compound';
|
|
95
100
|
}
|
|
96
101
|
return false;
|
|
97
102
|
}
|
|
98
103
|
function isInDeclarationInit(node) {
|
|
104
|
+
if (!node || !node.parent) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
99
107
|
let parent = node.parent;
|
|
100
108
|
if (ts.isVariableDeclaration(parent) && parent.initializer === node) {
|
|
101
109
|
return true;
|
|
@@ -113,41 +121,14 @@ function isInScope(reference, binding) {
|
|
|
113
121
|
return false;
|
|
114
122
|
}
|
|
115
123
|
function isReactiveReassignment(node) {
|
|
116
|
-
let
|
|
117
|
-
if (ts.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
ts.isCallExpression(node) &&
|
|
121
|
-
ts.isIdentifier(node.expression) &&
|
|
122
|
-
node.expression.text === 'reactive') {
|
|
124
|
+
let right = node.right;
|
|
125
|
+
if (ts.isCallExpression(right) &&
|
|
126
|
+
ts.isIdentifier(right.expression) &&
|
|
127
|
+
right.expression.text === 'reactive') {
|
|
123
128
|
return true;
|
|
124
129
|
}
|
|
125
130
|
return false;
|
|
126
131
|
}
|
|
127
|
-
function isWriteContext(node) {
|
|
128
|
-
let parent = node.parent;
|
|
129
|
-
if (ts.isBinaryExpression(parent) && parent.left === node) {
|
|
130
|
-
let op = parent.operatorToken.kind;
|
|
131
|
-
if (op === ts.SyntaxKind.EqualsToken) {
|
|
132
|
-
return 'simple';
|
|
133
|
-
}
|
|
134
|
-
if (op >= ts.SyntaxKind.PlusEqualsToken && op <= ts.SyntaxKind.CaretEqualsToken) {
|
|
135
|
-
return 'compound';
|
|
136
|
-
}
|
|
137
|
-
if (op === ts.SyntaxKind.AmpersandAmpersandEqualsToken ||
|
|
138
|
-
op === ts.SyntaxKind.BarBarEqualsToken ||
|
|
139
|
-
op === ts.SyntaxKind.QuestionQuestionEqualsToken) {
|
|
140
|
-
return 'compound';
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
if (ts.isPostfixUnaryExpression(parent) || ts.isPrefixUnaryExpression(parent)) {
|
|
144
|
-
let op = parent.operator;
|
|
145
|
-
if (op === ts.SyntaxKind.PlusPlusToken || op === ts.SyntaxKind.MinusMinusToken) {
|
|
146
|
-
return 'increment';
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
return false;
|
|
150
|
-
}
|
|
151
132
|
function visit(ctx, node) {
|
|
152
133
|
if (ts.isImportDeclaration(node) &&
|
|
153
134
|
ts.isStringLiteral(node.moduleSpecifier) &&
|
|
@@ -170,166 +151,131 @@ function visit(ctx, node) {
|
|
|
170
151
|
let arg = node.arguments[0], classification = classifyReactiveArg(arg);
|
|
171
152
|
if (classification) {
|
|
172
153
|
let varName = null;
|
|
173
|
-
if (ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name)) {
|
|
154
|
+
if (node.parent && ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name)) {
|
|
174
155
|
varName = node.parent.name.text;
|
|
175
156
|
}
|
|
176
|
-
else if (
|
|
157
|
+
else if (node.parent &&
|
|
158
|
+
ts.isBinaryExpression(node.parent) &&
|
|
177
159
|
node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken &&
|
|
178
160
|
ts.isIdentifier(node.parent.left)) {
|
|
179
161
|
varName = node.parent.left.text;
|
|
180
162
|
}
|
|
181
163
|
if (varName) {
|
|
182
164
|
let scope = findEnclosingScope(node);
|
|
183
|
-
ctx.scopedBindings.push({ name: varName, scope, type: classification });
|
|
184
165
|
ctx.bindings.set(varName, classification);
|
|
166
|
+
ctx.scopedBindings.push({ name: varName, scope, type: classification });
|
|
185
167
|
}
|
|
186
168
|
if (classification === 'computed') {
|
|
187
|
-
ctx.computedArgRanges.push({
|
|
188
|
-
end: arg.end,
|
|
189
|
-
start: arg.getStart(ctx.sourceFile)
|
|
190
|
-
});
|
|
191
|
-
let argCtx = {
|
|
192
|
-
argStart: arg.getStart(ctx.sourceFile),
|
|
193
|
-
innerReplacements: [],
|
|
194
|
-
neededImports: ctx.neededImports,
|
|
195
|
-
scopedBindings: ctx.scopedBindings,
|
|
196
|
-
sourceFile: ctx.sourceFile
|
|
197
|
-
};
|
|
198
|
-
visitArg(argCtx, arg);
|
|
199
|
-
let argText = applyReplacements(arg.getText(ctx.sourceFile), argCtx.innerReplacements);
|
|
200
|
-
ctx.replacements.push({
|
|
201
|
-
end: node.end,
|
|
202
|
-
newText: `computed(${argText})`,
|
|
203
|
-
start: node.pos
|
|
204
|
-
});
|
|
205
169
|
ctx.neededImports.add('computed');
|
|
170
|
+
let transformedArg = ts.visitEachChild(arg, n => visitComputedArg(ctx, n), ctx.context);
|
|
171
|
+
return createComputedCall(ctx.factory, transformedArg);
|
|
206
172
|
}
|
|
207
173
|
else {
|
|
208
|
-
let argText = arg.getText(ctx.sourceFile);
|
|
209
|
-
ctx.replacements.push({
|
|
210
|
-
end: node.end,
|
|
211
|
-
newText: `signal(${argText})`,
|
|
212
|
-
start: node.pos
|
|
213
|
-
});
|
|
214
174
|
ctx.neededImports.add('signal');
|
|
175
|
+
return createSignalCall(ctx.factory, arg);
|
|
215
176
|
}
|
|
216
177
|
}
|
|
217
178
|
}
|
|
218
|
-
if (ts.
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
179
|
+
if (ts.isBinaryExpression(node) && ts.isIdentifier(node.left)) {
|
|
180
|
+
let assignType = isAssignmentOperator(node.operatorToken.kind);
|
|
181
|
+
if (assignType) {
|
|
182
|
+
let binding = findBinding(ctx.scopedBindings, node.left.text, node.left);
|
|
183
|
+
if (binding && binding.type !== 'computed' && !isReactiveReassignment(node)) {
|
|
184
|
+
ctx.neededImports.add('set');
|
|
185
|
+
let factory = ctx.factory, name = node.left.text, signalIdent = factory.createIdentifier(name), transformedRight = ts.visitEachChild(node.right, n => visit(ctx, n), ctx.context);
|
|
186
|
+
if (assignType === 'simple') {
|
|
187
|
+
return createSetCall(factory, signalIdent, transformedRight);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
let op = getCompoundOperator(node.operatorToken.kind), valueAccess = factory.createPropertyAccessExpression(signalIdent, 'value');
|
|
191
|
+
return createSetCall(factory, signalIdent, factory.createBinaryExpression(valueAccess, op, transformedRight));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
222
194
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
195
|
+
}
|
|
196
|
+
if (ts.isPrefixUnaryExpression(node) && ts.isIdentifier(node.operand)) {
|
|
197
|
+
let op = node.operator;
|
|
198
|
+
if (op === ts.SyntaxKind.PlusPlusToken || op === ts.SyntaxKind.MinusMinusToken) {
|
|
199
|
+
let binding = findBinding(ctx.scopedBindings, node.operand.text, node.operand);
|
|
200
|
+
if (binding && binding.type !== 'computed') {
|
|
201
|
+
ctx.neededImports.add('set');
|
|
202
|
+
let delta = op === ts.SyntaxKind.PlusPlusToken ? ts.SyntaxKind.PlusToken : ts.SyntaxKind.MinusToken, factory = ctx.factory, name = node.operand.text, signalIdent = factory.createIdentifier(name), valueAccess = factory.createPropertyAccessExpression(signalIdent, 'value');
|
|
203
|
+
if (node.parent && ts.isExpressionStatement(node.parent)) {
|
|
204
|
+
return createSetCall(factory, signalIdent, factory.createBinaryExpression(valueAccess, delta, factory.createNumericLiteral(1)));
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
return createCommaExpr(factory, createSetCall(factory, signalIdent, factory.createBinaryExpression(valueAccess, delta, factory.createNumericLiteral(1))), factory.createPropertyAccessExpression(factory.createIdentifier(name), 'value'));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
227
210
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
let valueText = parent.right.getText(ctx.sourceFile);
|
|
239
|
-
ctx.replacements.push({
|
|
240
|
-
end: parent.end,
|
|
241
|
-
newText: `set(${name}, ${valueText})`,
|
|
242
|
-
start: parent.pos
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
else if (writeCtx === 'compound' && ts.isBinaryExpression(parent)) {
|
|
246
|
-
let op = getCompoundOperator(parent.operatorToken.kind), valueText = parent.right.getText(ctx.sourceFile);
|
|
247
|
-
ctx.replacements.push({
|
|
248
|
-
end: parent.end,
|
|
249
|
-
newText: `set(${name}, ${name}.value ${op} ${valueText})`,
|
|
250
|
-
start: parent.pos
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
else if (writeCtx === 'increment') {
|
|
254
|
-
let isPrefix = ts.isPrefixUnaryExpression(parent), op = parent.operator, delta = op === ts.SyntaxKind.PlusPlusToken ? '+ 1' : '- 1';
|
|
255
|
-
if (ts.isExpressionStatement(parent.parent)) {
|
|
256
|
-
ctx.replacements.push({
|
|
257
|
-
end: parent.end,
|
|
258
|
-
newText: `set(${name}, ${name}.value ${delta})`,
|
|
259
|
-
start: parent.pos
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
else if (isPrefix) {
|
|
263
|
-
ctx.replacements.push({
|
|
264
|
-
end: parent.end,
|
|
265
|
-
newText: `(set(${name}, ${name}.value ${delta}), ${name}.value)`,
|
|
266
|
-
start: parent.pos
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
let tmp = uid('tmp');
|
|
271
|
-
ctx.replacements.push({
|
|
272
|
-
end: parent.end,
|
|
273
|
-
newText: `((${tmp}) => (set(${name}, ${tmp} ${delta}), ${tmp}))(${name}.value)`,
|
|
274
|
-
start: parent.pos
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
211
|
+
}
|
|
212
|
+
if (ts.isPostfixUnaryExpression(node) && ts.isIdentifier(node.operand)) {
|
|
213
|
+
let op = node.operator;
|
|
214
|
+
if (op === ts.SyntaxKind.PlusPlusToken || op === ts.SyntaxKind.MinusMinusToken) {
|
|
215
|
+
let binding = findBinding(ctx.scopedBindings, node.operand.text, node.operand);
|
|
216
|
+
if (binding && binding.type !== 'computed') {
|
|
217
|
+
ctx.neededImports.add('set');
|
|
218
|
+
let delta = op === ts.SyntaxKind.PlusPlusToken ? ts.SyntaxKind.PlusToken : ts.SyntaxKind.MinusToken, factory = ctx.factory, name = node.operand.text, signalIdent = factory.createIdentifier(name), valueAccess = factory.createPropertyAccessExpression(signalIdent, 'value');
|
|
219
|
+
if (node.parent && ts.isExpressionStatement(node.parent)) {
|
|
220
|
+
return createSetCall(factory, signalIdent, factory.createBinaryExpression(valueAccess, delta, factory.createNumericLiteral(1)));
|
|
279
221
|
}
|
|
280
222
|
else {
|
|
281
|
-
|
|
282
|
-
ctx.replacements.push({
|
|
283
|
-
end: node.end,
|
|
284
|
-
newText: `read(${name})`,
|
|
285
|
-
start: node.pos
|
|
286
|
-
});
|
|
223
|
+
return createPostfixIncrementExpr(factory, uid('tmp'), name, delta);
|
|
287
224
|
}
|
|
288
225
|
}
|
|
289
226
|
}
|
|
290
227
|
}
|
|
291
|
-
ts.
|
|
228
|
+
if (ts.isIdentifier(node) && node.parent && !isInDeclarationInit(node.parent)) {
|
|
229
|
+
if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) {
|
|
230
|
+
return ts.visitEachChild(node, n => visit(ctx, n), ctx.context);
|
|
231
|
+
}
|
|
232
|
+
if (ts.isBinaryExpression(node.parent) && node.parent.left === node) {
|
|
233
|
+
return ts.visitEachChild(node, n => visit(ctx, n), ctx.context);
|
|
234
|
+
}
|
|
235
|
+
if ((ts.isPrefixUnaryExpression(node.parent) || ts.isPostfixUnaryExpression(node.parent)) &&
|
|
236
|
+
node.parent.operand === node) {
|
|
237
|
+
return ts.visitEachChild(node, n => visit(ctx, n), ctx.context);
|
|
238
|
+
}
|
|
239
|
+
if (ts.isTypeOfExpression(node.parent) && node.parent.expression === node) {
|
|
240
|
+
return ts.visitEachChild(node, n => visit(ctx, n), ctx.context);
|
|
241
|
+
}
|
|
242
|
+
let binding = findBinding(ctx.scopedBindings, node.text, node);
|
|
243
|
+
if (binding) {
|
|
244
|
+
ctx.neededImports.add('read');
|
|
245
|
+
return createReadCall(ctx.factory, ctx.factory.createIdentifier(node.text));
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return ts.visitEachChild(node, n => visit(ctx, n), ctx.context);
|
|
292
249
|
}
|
|
293
|
-
function
|
|
294
|
-
if (ts.isIdentifier(node)) {
|
|
250
|
+
function visitComputedArg(ctx, node) {
|
|
251
|
+
if (ts.isIdentifier(node) && node.parent) {
|
|
295
252
|
if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) {
|
|
296
|
-
ts.
|
|
297
|
-
return;
|
|
253
|
+
return ts.visitEachChild(node, n => visitComputedArg(ctx, n), ctx.context);
|
|
298
254
|
}
|
|
299
255
|
if (ts.isCallExpression(node.parent) && node.parent.expression === node) {
|
|
300
|
-
ts.
|
|
301
|
-
return;
|
|
256
|
+
return ts.visitEachChild(node, n => visitComputedArg(ctx, n), ctx.context);
|
|
302
257
|
}
|
|
303
258
|
let binding = findBinding(ctx.scopedBindings, node.text, node);
|
|
304
259
|
if (binding) {
|
|
305
260
|
ctx.neededImports.add('read');
|
|
306
|
-
ctx.
|
|
307
|
-
end: node.end - ctx.argStart,
|
|
308
|
-
newText: `read(${node.text})`,
|
|
309
|
-
start: node.getStart(ctx.sourceFile) - ctx.argStart
|
|
310
|
-
});
|
|
261
|
+
return createReadCall(ctx.factory, ctx.factory.createIdentifier(node.text));
|
|
311
262
|
}
|
|
312
263
|
}
|
|
313
|
-
ts.
|
|
264
|
+
return ts.visitEachChild(node, n => visitComputedArg(ctx, n), ctx.context);
|
|
314
265
|
}
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
266
|
+
const createPrimitivesTransformer = (bindings, neededImports) => {
|
|
267
|
+
return (context) => {
|
|
268
|
+
return (sourceFile) => {
|
|
269
|
+
let ctx = {
|
|
270
|
+
bindings,
|
|
271
|
+
context,
|
|
272
|
+
factory: context.factory,
|
|
273
|
+
hasReactiveImport: false,
|
|
274
|
+
neededImports,
|
|
275
|
+
scopedBindings: []
|
|
276
|
+
};
|
|
277
|
+
return ts.visitNode(sourceFile, n => visit(ctx, n));
|
|
278
|
+
};
|
|
324
279
|
};
|
|
325
|
-
visit(ctx, sourceFile);
|
|
326
|
-
if (ctx.replacements.length === 0) {
|
|
327
|
-
return code;
|
|
328
|
-
}
|
|
329
|
-
let result = applyReplacements(code, ctx.replacements);
|
|
330
|
-
if (ctx.neededImports.size > 0) {
|
|
331
|
-
result = addMissingImports(result, ctx.neededImports);
|
|
332
|
-
}
|
|
333
|
-
return result;
|
|
334
280
|
};
|
|
335
|
-
export {
|
|
281
|
+
export { createPrimitivesTransformer };
|
package/build/types.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { COMPUTED, SIGNAL, STATE_CHECK, STATE_DIRTY, STATE_IN_HEAP, STATE_NONE, STATE_RECOMPUTING } from './constants.js';
|
|
2
2
|
import { ReactiveArray, ReactiveObject } from './reactive/index.js';
|
|
3
|
-
import { ts } from '@esportsplus/typescript';
|
|
4
3
|
type BindingType = 'array' | 'computed' | 'object' | 'signal';
|
|
5
4
|
type Bindings = Map<string, BindingType>;
|
|
6
5
|
interface Computed<T> {
|
|
@@ -31,9 +30,4 @@ type Signal<T> = {
|
|
|
31
30
|
type: typeof SIGNAL;
|
|
32
31
|
value: T;
|
|
33
32
|
};
|
|
34
|
-
|
|
35
|
-
code: string;
|
|
36
|
-
sourceFile: ts.SourceFile;
|
|
37
|
-
transformed: boolean;
|
|
38
|
-
}
|
|
39
|
-
export type { BindingType, Bindings, Computed, Link, ReactiveArray, ReactiveObject, Signal, TransformResult };
|
|
33
|
+
export type { BindingType, Bindings, Computed, Link, ReactiveArray, ReactiveObject, Signal };
|
package/package.json
CHANGED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { ts } from '@esportsplus/typescript';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
// Create: read(expr)
|
|
5
|
+
function createReadCall(factory: ts.NodeFactory, expr: ts.Expression): ts.CallExpression {
|
|
6
|
+
return factory.createCallExpression(
|
|
7
|
+
factory.createIdentifier('read'),
|
|
8
|
+
undefined,
|
|
9
|
+
[expr]
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Create: set(target, value)
|
|
14
|
+
function createSetCall(factory: ts.NodeFactory, target: ts.Expression, value: ts.Expression): ts.CallExpression {
|
|
15
|
+
return factory.createCallExpression(
|
|
16
|
+
factory.createIdentifier('set'),
|
|
17
|
+
undefined,
|
|
18
|
+
[target, value]
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Create: signal(initialValue)
|
|
23
|
+
function createSignalCall(factory: ts.NodeFactory, initialValue: ts.Expression): ts.CallExpression {
|
|
24
|
+
return factory.createCallExpression(
|
|
25
|
+
factory.createIdentifier('signal'),
|
|
26
|
+
undefined,
|
|
27
|
+
[initialValue]
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Create: computed(fn)
|
|
32
|
+
function createComputedCall(factory: ts.NodeFactory, fn: ts.Expression): ts.CallExpression {
|
|
33
|
+
return factory.createCallExpression(
|
|
34
|
+
factory.createIdentifier('computed'),
|
|
35
|
+
undefined,
|
|
36
|
+
[fn]
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Create: arr.$length()
|
|
41
|
+
function createArrayLengthCall(factory: ts.NodeFactory, arrayExpr: ts.Expression): ts.CallExpression {
|
|
42
|
+
return factory.createCallExpression(
|
|
43
|
+
factory.createPropertyAccessExpression(arrayExpr, '$length'),
|
|
44
|
+
undefined,
|
|
45
|
+
[]
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Create: arr.$set(index, value)
|
|
50
|
+
function createArraySetCall(factory: ts.NodeFactory, arrayExpr: ts.Expression, index: ts.Expression, value: ts.Expression): ts.CallExpression {
|
|
51
|
+
return factory.createCallExpression(
|
|
52
|
+
factory.createPropertyAccessExpression(arrayExpr, '$set'),
|
|
53
|
+
undefined,
|
|
54
|
+
[index, value]
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Create: new ReactiveArray(elements...)
|
|
59
|
+
function createReactiveArrayNew(factory: ts.NodeFactory, elements: ts.Expression[]): ts.NewExpression {
|
|
60
|
+
return factory.createNewExpression(
|
|
61
|
+
factory.createIdentifier('ReactiveArray'),
|
|
62
|
+
undefined,
|
|
63
|
+
elements
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Create: dispose(expr)
|
|
68
|
+
function createDisposeCall(factory: ts.NodeFactory, expr: ts.Expression): ts.CallExpression {
|
|
69
|
+
return factory.createCallExpression(
|
|
70
|
+
factory.createIdentifier('dispose'),
|
|
71
|
+
undefined,
|
|
72
|
+
[expr]
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Create binary expression: left op right
|
|
77
|
+
function createBinaryExpr(factory: ts.NodeFactory, left: ts.Expression, op: ts.BinaryOperator, right: ts.Expression): ts.BinaryExpression {
|
|
78
|
+
return factory.createBinaryExpression(left, op, right);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Create: (expr1, expr2) - comma expression
|
|
82
|
+
function createCommaExpr(factory: ts.NodeFactory, first: ts.Expression, second: ts.Expression): ts.ParenthesizedExpression {
|
|
83
|
+
return factory.createParenthesizedExpression(
|
|
84
|
+
factory.createBinaryExpression(first, ts.SyntaxKind.CommaToken, second)
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Create: ((tmp) => (set(name, tmp op delta), tmp))(name.value)
|
|
89
|
+
function createPostfixIncrementExpr(
|
|
90
|
+
factory: ts.NodeFactory,
|
|
91
|
+
tmpName: string,
|
|
92
|
+
signalName: string,
|
|
93
|
+
op: ts.SyntaxKind.PlusToken | ts.SyntaxKind.MinusToken
|
|
94
|
+
): ts.CallExpression {
|
|
95
|
+
let tmpIdent = factory.createIdentifier(tmpName),
|
|
96
|
+
signalIdent = factory.createIdentifier(signalName);
|
|
97
|
+
|
|
98
|
+
return factory.createCallExpression(
|
|
99
|
+
factory.createParenthesizedExpression(
|
|
100
|
+
factory.createArrowFunction(
|
|
101
|
+
undefined,
|
|
102
|
+
undefined,
|
|
103
|
+
[factory.createParameterDeclaration(undefined, undefined, tmpIdent)],
|
|
104
|
+
undefined,
|
|
105
|
+
factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
106
|
+
createCommaExpr(
|
|
107
|
+
factory,
|
|
108
|
+
createSetCall(
|
|
109
|
+
factory,
|
|
110
|
+
signalIdent,
|
|
111
|
+
factory.createBinaryExpression(
|
|
112
|
+
tmpIdent,
|
|
113
|
+
op,
|
|
114
|
+
factory.createNumericLiteral(1)
|
|
115
|
+
)
|
|
116
|
+
),
|
|
117
|
+
tmpIdent
|
|
118
|
+
)
|
|
119
|
+
)
|
|
120
|
+
),
|
|
121
|
+
undefined,
|
|
122
|
+
[factory.createPropertyAccessExpression(signalIdent, 'value')]
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
export {
|
|
128
|
+
createArrayLengthCall,
|
|
129
|
+
createArraySetCall,
|
|
130
|
+
createBinaryExpr,
|
|
131
|
+
createCommaExpr,
|
|
132
|
+
createComputedCall,
|
|
133
|
+
createDisposeCall,
|
|
134
|
+
createPostfixIncrementExpr,
|
|
135
|
+
createReactiveArrayNew,
|
|
136
|
+
createReadCall,
|
|
137
|
+
createSetCall,
|
|
138
|
+
createSignalCall
|
|
139
|
+
};
|