vue-hook-optimizer 0.0.58 → 0.0.60

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -315,6 +315,108 @@ function processSetup(ast, parentScope, parentPath, _spread, _lineOffset = 0) {
315
315
  }
316
316
  }
317
317
  }, parentScope, parentPath);
318
+ function traverseHooks(node, patentScope) {
319
+ if (node.type === "ExpressionStatement" && node.expression.type === "CallExpression" && node.expression.callee.type === "Identifier" || node.type === "CallExpression" && node.callee.type === "Identifier") {
320
+ const hookName = (() => {
321
+ if (node.type === "ExpressionStatement" && node.expression.type === "CallExpression" && node.expression.callee.type === "Identifier") {
322
+ return node.expression.callee.name;
323
+ }
324
+ if (node.type === "CallExpression" && node.callee.type === "Identifier") {
325
+ return node.callee.name;
326
+ }
327
+ })() || "";
328
+ if (!hookName) {
329
+ return;
330
+ }
331
+ const hookBinding = patentScope.getBinding(hookName);
332
+ if (!(hookBinding === void 0 || hookBinding?.scope.block.type === "Program" || parentScope === hookBinding?.scope)) {
333
+ return;
334
+ }
335
+ const expression = node.type === "ExpressionStatement" ? node.expression : node;
336
+ const watchArgs = /* @__PURE__ */ new Set();
337
+ if (hookName === "provide") {
338
+ traverse2(expression, {
339
+ Identifier(path1) {
340
+ const binding = path1.scope.getBinding(path1.node.name);
341
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
342
+ const _node = nodeCollection.getNode(path1.node.name);
343
+ if (_node?.info?.used) {
344
+ _node?.info?.used?.add(hookName);
345
+ } else if (_node) {
346
+ _node.info = {
347
+ ..._node?.info,
348
+ used: /* @__PURE__ */ new Set([hookName])
349
+ };
350
+ }
351
+ }
352
+ }
353
+ }, patentScope, node);
354
+ } else if (hookName === "watch") {
355
+ if (expression.arguments[0].type === "Identifier") {
356
+ const binding = patentScope.getBinding(expression.arguments[0].name);
357
+ if (graph.nodes.has(expression.arguments[0].name) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
358
+ watchArgs.add(expression.arguments[0]);
359
+ }
360
+ } else {
361
+ traverse2(expression.arguments[0], {
362
+ Identifier(path1) {
363
+ const binding = path1.scope.getBinding(path1.node.name);
364
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
365
+ watchArgs.add(path1.node);
366
+ }
367
+ }
368
+ }, patentScope, node);
369
+ }
370
+ } else if (hookName === "useEffect" && expression.arguments[1].type === "ArrayExpression") {
371
+ traverse2(expression.arguments[1], {
372
+ Identifier(path1) {
373
+ const binding = path1.scope.getBinding(path1.node.name);
374
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
375
+ watchArgs.add(path1.node);
376
+ }
377
+ }
378
+ }, patentScope, node);
379
+ }
380
+ expression.arguments.forEach((argNode, index) => {
381
+ if (hookName === "watch" && index === 0 && argNode.type === "Identifier") {
382
+ const _node = nodeCollection.getNode(argNode.name);
383
+ if (_node?.info?.used) {
384
+ _node?.info?.used?.add(hookName);
385
+ } else if (_node) {
386
+ _node.info = {
387
+ ..._node?.info,
388
+ used: /* @__PURE__ */ new Set([hookName])
389
+ };
390
+ }
391
+ return;
392
+ }
393
+ traverse2(argNode, {
394
+ Identifier(path1) {
395
+ const binding = path1.scope.getBinding(path1.node.name);
396
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
397
+ if (["watch", "useEffect"].includes(hookName) && watchArgs.size > 0) {
398
+ const watchArgsNames = Array.from(watchArgs).map((arg) => arg.name);
399
+ watchArgs.forEach((watchArg) => {
400
+ if (!watchArgsNames.includes(path1.node.name)) {
401
+ graph.edges.get(watchArg.name)?.add(path1.node.name);
402
+ }
403
+ });
404
+ }
405
+ const _node = nodeCollection.getNode(path1.node.name);
406
+ if (_node?.info?.used) {
407
+ _node?.info?.used?.add(hookName);
408
+ } else if (_node) {
409
+ _node.info = {
410
+ ..._node?.info,
411
+ used: /* @__PURE__ */ new Set([hookName])
412
+ };
413
+ }
414
+ }
415
+ }
416
+ }, patentScope, node);
417
+ });
418
+ }
419
+ }
318
420
  traverse2(ast, {
319
421
  FunctionDeclaration(path) {
320
422
  const name = path.node.id?.name;
@@ -392,6 +494,9 @@ function processSetup(ast, parentScope, parentPath, _spread, _lineOffset = 0) {
392
494
  "ArrowFunctionExpression",
393
495
  "FunctionDeclaration"
394
496
  ].includes(path.node.init.type) && path.node.id.type === "Identifier") {
497
+ if (path.node.init.type === "CallExpression" && path.node.init.callee.type === "Identifier" && ["watch", "watchEffect"].includes(path.node.init.callee.name)) {
498
+ traverseHooks(path.node.init, path.scope);
499
+ }
395
500
  const name = path.node.id?.name;
396
501
  if (name && graph.nodes.has(name)) {
397
502
  traverse2(path.node.init, {
@@ -468,94 +573,35 @@ function processSetup(ast, parentScope, parentPath, _spread, _lineOffset = 0) {
468
573
  }
469
574
  },
470
575
  ExpressionStatement(path) {
471
- if (path.node.expression.type === "CallExpression" && path.node.expression.callee.type === "Identifier") {
472
- const hookName = path.node.expression.callee.name;
473
- const hookBinding = path.scope.getBinding(hookName);
474
- if (!(hookBinding === void 0 || hookBinding?.scope.block.type === "Program" || parentScope === hookBinding?.scope)) {
475
- return;
476
- }
477
- const watchArgs = /* @__PURE__ */ new Set();
478
- if (hookName === "provide") {
479
- traverse2(path.node.expression, {
480
- Identifier(path1) {
481
- const binding = path1.scope.getBinding(path1.node.name);
482
- if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
483
- const _node = nodeCollection.getNode(path1.node.name);
484
- if (_node?.info?.used) {
485
- _node?.info?.used?.add(hookName);
486
- } else if (_node) {
487
- _node.info = {
488
- ..._node?.info,
489
- used: /* @__PURE__ */ new Set([hookName])
490
- };
491
- }
492
- }
493
- }
494
- }, path.scope, path);
495
- } else if (hookName === "watch") {
496
- if (path.node.expression.arguments[0].type === "Identifier") {
497
- const binding = path.scope.getBinding(path.node.expression.arguments[0].name);
498
- if (graph.nodes.has(path.node.expression.arguments[0].name) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
499
- watchArgs.add(path.node.expression.arguments[0]);
500
- }
501
- } else {
502
- traverse2(path.node.expression.arguments[0], {
503
- Identifier(path1) {
504
- const binding = path1.scope.getBinding(path1.node.name);
505
- if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
506
- watchArgs.add(path1.node);
507
- }
508
- }
509
- }, path.scope, path);
576
+ if (path.type === "ExpressionStatement" && path.node.expression.type === "CallExpression" && path.node.expression.callee.type === "Identifier") {
577
+ const name = path.node.expression.callee.name;
578
+ if (graph.nodes.has(name) && path.scope.block.type === "Program") {
579
+ const _node = nodeCollection.getNode(name);
580
+ if (_node?.info?.used) {
581
+ _node?.info?.used?.add("Call Expression");
582
+ } else if (_node) {
583
+ _node.info = {
584
+ ..._node?.info,
585
+ used: /* @__PURE__ */ new Set(["Call Expression"])
586
+ };
510
587
  }
511
- } else if (hookName === "useEffect" && path.node.expression.arguments[1].type === "ArrayExpression") {
512
- traverse2(path.node.expression.arguments[1], {
513
- Identifier(path1) {
514
- const binding = path1.scope.getBinding(path1.node.name);
515
- if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
516
- watchArgs.add(path1.node);
517
- }
518
- }
519
- }, path.scope, path);
588
+ } else {
589
+ traverseHooks(path.node.expression, path.scope);
590
+ }
591
+ }
592
+ if (path.type === "ExpressionStatement" && path.node.expression.type === "AssignmentExpression" && path.node.expression.right.type === "CallExpression" && path.node.expression.right.callee.type === "Identifier") {
593
+ traverseHooks(path.node.expression.right, path.scope);
594
+ }
595
+ if (path.type === "ExpressionStatement" && path.node.expression.type === "AssignmentExpression" && path.node.expression.left.type === "Identifier" && graph.nodes.has(path.node.expression.left.name) && path.scope.block.type === "Program") {
596
+ const _node = nodeCollection.getNode(path.node.expression.left.name);
597
+ if (_node?.info?.used) {
598
+ _node?.info?.used?.add("Assignment Expression");
599
+ } else if (_node) {
600
+ _node.info = {
601
+ ..._node?.info,
602
+ used: /* @__PURE__ */ new Set(["Assignment Expression"])
603
+ };
520
604
  }
521
- path.node.expression.arguments.forEach((argNode, index) => {
522
- if (hookName === "watch" && index === 0 && argNode.type === "Identifier") {
523
- const _node = nodeCollection.getNode(argNode.name);
524
- if (_node?.info?.used) {
525
- _node?.info?.used?.add(hookName);
526
- } else if (_node) {
527
- _node.info = {
528
- ..._node?.info,
529
- used: /* @__PURE__ */ new Set([hookName])
530
- };
531
- }
532
- return;
533
- }
534
- traverse2(argNode, {
535
- Identifier(path1) {
536
- const binding = path1.scope.getBinding(path1.node.name);
537
- if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
538
- if (["watch", "useEffect"].includes(hookName) && watchArgs.size > 0) {
539
- const watchArgsNames = Array.from(watchArgs).map((arg) => arg.name);
540
- watchArgs.forEach((watchArg) => {
541
- if (!watchArgsNames.includes(path1.node.name)) {
542
- graph.edges.get(watchArg.name)?.add(path1.node.name);
543
- }
544
- });
545
- }
546
- const _node = nodeCollection.getNode(path1.node.name);
547
- if (_node?.info?.used) {
548
- _node?.info?.used?.add(hookName);
549
- } else if (_node) {
550
- _node.info = {
551
- ..._node?.info,
552
- used: /* @__PURE__ */ new Set([hookName])
553
- };
554
- }
555
- }
556
- }
557
- }, path.scope, path);
558
- });
559
605
  }
560
606
  }
561
607
  }, parentScope, parentPath);
@@ -1981,6 +2027,9 @@ function findLinearPaths(graph) {
1981
2027
  const visitedNodes = /* @__PURE__ */ new Set();
1982
2028
  const nodeInDegrees = /* @__PURE__ */ new Map();
1983
2029
  for (const [node, edges] of graph.entries()) {
2030
+ if (!nodeInDegrees.has(node)) {
2031
+ nodeInDegrees.set(node, 0);
2032
+ }
1984
2033
  for (const edge of edges) {
1985
2034
  const inDegree = nodeInDegrees.get(edge) || 0;
1986
2035
  nodeInDegrees.set(edge, inDegree + 1);
@@ -2158,11 +2207,16 @@ function gen(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__ */ new
2158
2207
  }
2159
2208
  const paths = findLinearPaths(g);
2160
2209
  paths.forEach((path) => {
2161
- suggestions.push({
2162
- type: "warning" /* warning */,
2163
- message: `Nodes [${path.length > 10 ? `${path.slice(0, 10).map((node) => node.label).join(",")}...(${path.length})` : path.map((node) => node.label).join(",")}] are have function chain calls, perhaps you can refactor it.`,
2164
- nodeInfo: path
2165
- });
2210
+ const firstUsedNodeIndex = path.findIndex((node) => usedNodes.has(node.label));
2211
+ const reverseLastNotUsedNodeIndex = path.slice().reverse().findIndex((node) => !usedNodes.has(node.label));
2212
+ const lastNotUsedNodeIndex = reverseLastNotUsedNodeIndex !== -1 ? path.length - 1 - reverseLastNotUsedNodeIndex : -1;
2213
+ if (firstUsedNodeIndex > -1 && firstUsedNodeIndex < lastNotUsedNodeIndex) {
2214
+ suggestions.push({
2215
+ type: "warning" /* warning */,
2216
+ message: `Nodes [${path.length > 10 ? `${path.slice(0, 10).map((node) => node.label).join(",")}...(${path.length})` : path.map((node) => node.label).join(",")}] are have function chain calls, perhaps you can refactor it.`,
2217
+ nodeInfo: path
2218
+ });
2219
+ }
2166
2220
  });
2167
2221
  if (g.size > 5) {
2168
2222
  const ap = findArticulationPoints(g);
@@ -2191,6 +2245,13 @@ function gen(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__ */ new
2191
2245
  }
2192
2246
 
2193
2247
  // src/vis.ts
2248
+ function filterNodeUserd(used) {
2249
+ const usedArray = Array.from(used || []);
2250
+ return new Set(usedArray.filter((u) => ![
2251
+ "Assignment Expression",
2252
+ "Call Expression"
2253
+ ].includes(u)));
2254
+ }
2194
2255
  function getVisData(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__ */ new Set()) {
2195
2256
  const usedNodes = /* @__PURE__ */ new Set([...nodesUsedInTemplate, ...nodesUsedInStyle]);
2196
2257
  const nodes = [];
@@ -2201,7 +2262,7 @@ function getVisData(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__
2201
2262
  label: node.label,
2202
2263
  shape: node.type === "var" ? "dot" : "diamond",
2203
2264
  group: usedNodes.has(node.label) || node.info?.used?.size ? "used" : "normal",
2204
- title: `${node.info?.used?.size ? `used by ${Array.from(node.info?.used || [])?.map((i) => `\`${i}\``).join(",")}
2265
+ title: `${filterNodeUserd(node.info?.used).size ? `used by ${Array.from(filterNodeUserd(node.info?.used))?.map((i) => `\`${i}\``).join(",")}
2205
2266
 
2206
2267
  ` : ""}${usedNodes.has(node.label) ? `used in ${[
2207
2268
  nodesUsedInStyle.has(node.label) ? "style" : "",