@eventra_dev/eventra-cli 0.1.34 → 0.2.1

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.
@@ -24,9 +24,9 @@ async function check({ fix = false }) {
24
24
  absolute: true,
25
25
  });
26
26
  const engine = new engine_1.EventraEngine(process.cwd());
27
- const toScan = new Set();
28
27
  const cache = new Map();
29
- // COLLECT + CACHE
28
+ const toScan = new Set();
29
+ // COLLECT
30
30
  for (const file of files) {
31
31
  try {
32
32
  const raw = await promises_1.default.readFile(file, "utf-8");
@@ -35,23 +35,17 @@ async function check({ fix = false }) {
35
35
  const parsed = (0, processFile_1.processFile)(file, raw);
36
36
  cache.set(file, parsed);
37
37
  toScan.add(file);
38
- for (const dep of parsed.deps) {
39
- toScan.add(path_1.default.resolve(dep));
40
- }
38
+ parsed.deps.forEach(dep => toScan.add(path_1.default.resolve(dep)));
41
39
  }
42
40
  catch { }
43
41
  }
44
42
  // PRELOAD
45
43
  for (const file of toScan) {
46
44
  try {
47
- let parsed = cache.get(file);
48
- if (!parsed) {
49
- const raw = await promises_1.default.readFile(file, "utf-8");
50
- parsed = (0, processFile_1.processFile)(file, raw);
51
- cache.set(file, parsed);
52
- }
53
- const virtual = (0, getVirtualFile_1.getVirtualFile)(file);
54
- engine.preloadFile(virtual, parsed.content);
45
+ const parsed = cache.get(file);
46
+ if (!parsed)
47
+ continue;
48
+ engine.preloadFile((0, getVirtualFile_1.getVirtualFile)(file), parsed.content);
55
49
  }
56
50
  catch { }
57
51
  }
@@ -61,34 +55,24 @@ async function check({ fix = false }) {
61
55
  const parsed = cache.get(file);
62
56
  if (!parsed)
63
57
  continue;
64
- const virtual = (0, getVirtualFile_1.getVirtualFile)(file);
65
- engine.scanFile(virtual, parsed.content, config);
58
+ engine.scanFile((0, getVirtualFile_1.getVirtualFile)(file), parsed.content, config);
66
59
  }
67
60
  catch { }
68
61
  }
69
- // DIFF
70
62
  const found = new Set(engine.getAllEvents());
71
63
  const known = new Set(config.events ?? []);
72
- const newEvents = [...found].filter(e => !known.has(e));
64
+ const added = [...found].filter(e => !known.has(e));
73
65
  const removed = [...known].filter(e => !found.has(e));
74
- // FIX MODE
75
66
  if (fix) {
76
67
  config.events = [...found].sort();
77
68
  await (0, config_1.saveConfig)(config);
78
- console.log(chalk_1.default.green(`\nSynced (${config.events.length} events)`));
69
+ console.log(chalk_1.default.green("Synced"));
79
70
  return;
80
71
  }
81
- // CHECK MODE
82
- if (newEvents.length || removed.length) {
83
- if (newEvents.length) {
84
- console.log(chalk_1.default.red("\nNew events:"));
85
- newEvents.forEach(e => console.log(chalk_1.default.red(`+ ${e}`)));
86
- }
87
- if (removed.length) {
88
- console.log(chalk_1.default.yellow("\nRemoved events:"));
89
- removed.forEach(e => console.log(chalk_1.default.yellow(`- ${e}`)));
90
- }
72
+ if (added.length || removed.length) {
73
+ added.forEach(e => console.log(chalk_1.default.red(`+ ${e}`)));
74
+ removed.forEach(e => console.log(chalk_1.default.yellow(`- ${e}`)));
91
75
  process.exit(1);
92
76
  }
93
- console.log(chalk_1.default.green("\nAll good"));
77
+ console.log(chalk_1.default.green("All good"));
94
78
  }
@@ -21,14 +21,10 @@ async function sync() {
21
21
  ignore: config.sync.exclude,
22
22
  absolute: true,
23
23
  });
24
- if (!files.length) {
25
- console.log(chalk_1.default.yellow("No files found"));
26
- return;
27
- }
28
24
  const engine = new engine_1.EventraEngine(process.cwd());
29
- const toScan = new Set();
30
25
  const cache = new Map();
31
- // COLLECT + CACHE
26
+ const toScan = new Set();
27
+ // COLLECT
32
28
  for (const file of files) {
33
29
  try {
34
30
  const raw = await promises_1.default.readFile(file, "utf-8");
@@ -37,9 +33,7 @@ async function sync() {
37
33
  const parsed = (0, processFile_1.processFile)(file, raw);
38
34
  cache.set(file, parsed);
39
35
  toScan.add(file);
40
- for (const dep of parsed.deps) {
41
- toScan.add(path_1.default.resolve(dep));
42
- }
36
+ parsed.deps.forEach(dep => toScan.add(path_1.default.resolve(dep)));
43
37
  }
44
38
  catch { }
45
39
  }
@@ -52,8 +46,7 @@ async function sync() {
52
46
  parsed = (0, processFile_1.processFile)(file, raw);
53
47
  cache.set(file, parsed);
54
48
  }
55
- const virtual = (0, getVirtualFile_1.getVirtualFile)(file);
56
- engine.preloadFile(virtual, parsed.content);
49
+ engine.preloadFile((0, getVirtualFile_1.getVirtualFile)(file), parsed.content);
57
50
  }
58
51
  catch { }
59
52
  }
@@ -65,33 +58,22 @@ async function sync() {
65
58
  const parsed = cache.get(file);
66
59
  if (!parsed)
67
60
  continue;
68
- const virtual = (0, getVirtualFile_1.getVirtualFile)(file);
69
- const res = engine.scanFile(virtual, parsed.content, config);
61
+ const res = engine.updateFile((0, getVirtualFile_1.getVirtualFile)(file), parsed.content, config);
70
62
  res.detectedFunctionWrappers.forEach(w => detectedFn.add(w));
71
- for (const [k, v] of res.detectedComponentWrappers) {
72
- detectedCmp.set(k, v);
73
- }
74
- }
75
- catch {
76
- console.log(chalk_1.default.gray(`skip: ${file}`));
63
+ res.detectedComponentWrappers.forEach((v, k) => detectedCmp.set(k, v));
77
64
  }
65
+ catch { }
78
66
  }
79
67
  // RESULT
80
68
  const events = engine.getAllEvents().sort();
81
69
  config.events = events;
82
70
  config.functionWrappers = mergeUnique(config.functionWrappers ?? [], [...detectedFn].map(name => ({ name })), w => w.name);
83
- config.wrappers = mergeUnique(config.wrappers ?? [], [...detectedCmp.entries()].map(([name, prop]) => ({
84
- name,
85
- prop,
86
- })), w => `${w.name}:${w.prop}`);
71
+ config.wrappers = mergeUnique(config.wrappers ?? [], [...detectedCmp.entries()].map(([name, prop]) => ({ name, prop })), w => `${w.name}:${w.prop}`);
87
72
  await (0, config_1.saveConfig)(config);
88
73
  console.log(chalk_1.default.green(`Found ${events.length} events`));
89
74
  }
90
- // HELPERS
91
75
  function mergeUnique(a, b, key) {
92
76
  const map = new Map();
93
- [...b, ...a].forEach(item => {
94
- map.set(key(item), item);
95
- });
77
+ [...b, ...a].forEach(item => map.set(key(item), item));
96
78
  return [...map.values()];
97
79
  }
@@ -13,180 +13,97 @@ const config_1 = require("../utils/config");
13
13
  const engine_1 = require("../engine/engine");
14
14
  const processFile_1 = require("../utils/processFile");
15
15
  const getVirtualFile_1 = require("../utils/getVirtualFile");
16
- function normalize(file) {
17
- return path_1.default.resolve(file).replace(/\\/g, "/");
18
- }
19
16
  async function watch() {
20
17
  const config = await (0, config_1.loadConfig)();
21
18
  if (!config)
22
19
  return;
23
20
  console.log(chalk_1.default.blue("Watching...\n"));
21
+ const engine = new engine_1.EventraEngine(process.cwd());
22
+ const fileDeps = new Map();
23
+ const cache = new Map();
24
+ const watchedDeps = new Set();
25
+ const normalize = (f) => path_1.default.resolve(f).replace(/\\/g, "/");
26
+ // INITIAL LOAD
24
27
  const files = await (0, fast_glob_1.default)(config.sync.include, {
25
28
  ignore: config.sync.exclude,
26
29
  absolute: true,
27
30
  });
28
- const engine = new engine_1.EventraEngine(process.cwd());
29
- const watchedDeps = new Set();
30
- const cache = new Map();
31
- const toScan = new Set();
32
- // COLLECT + CACHE
33
31
  for (const file of files) {
34
32
  try {
35
33
  const abs = normalize(file);
36
34
  const raw = await promises_1.default.readFile(abs, "utf-8");
37
- if (raw.length > 2_000_000)
38
- continue;
39
35
  const parsed = (0, processFile_1.processFile)(abs, raw);
40
36
  cache.set(abs, parsed);
41
- toScan.add(abs);
42
- for (const dep of parsed.deps) {
43
- toScan.add(normalize(dep));
44
- }
45
- }
46
- catch {
47
- console.log(chalk_1.default.gray(`skip: ${file}`));
48
- }
49
- }
50
- // PRELOAD
51
- for (const file of toScan) {
52
- try {
53
- let parsed = cache.get(file);
54
- if (!parsed) {
55
- const raw = await promises_1.default.readFile(file, "utf-8");
56
- parsed = (0, processFile_1.processFile)(file, raw);
57
- cache.set(file, parsed);
58
- }
59
- const virtual = (0, getVirtualFile_1.getVirtualFile)(file);
60
- engine.preloadFile?.(virtual, parsed.content);
61
- }
62
- catch { }
63
- }
64
- // INITIAL SCAN
65
- for (const file of toScan) {
66
- try {
67
- let parsed = cache.get(file);
68
- if (!parsed) {
69
- const raw = await promises_1.default.readFile(file, "utf-8");
70
- parsed = (0, processFile_1.processFile)(file, raw);
71
- }
72
- const virtual = (0, getVirtualFile_1.getVirtualFile)(file);
73
- engine.scanFile(virtual, parsed.content, config);
74
- for (const dep of parsed.deps) {
75
- watchedDeps.add(normalize(dep));
76
- }
37
+ engine.preloadFile((0, getVirtualFile_1.getVirtualFile)(abs), parsed.content);
38
+ engine.updateFile((0, getVirtualFile_1.getVirtualFile)(abs), parsed.content, config);
39
+ fileDeps.set(abs, new Set(parsed.deps.map(d => normalize(d))));
77
40
  }
78
41
  catch { }
79
42
  }
80
43
  config.events = engine.getAllEvents().sort();
81
44
  await (0, config_1.saveConfig)(config);
82
- console.log(chalk_1.default.gray(`Initial: ${config.events.length} events\n`));
83
- // QUEUE
84
- let locked = false;
85
- const queued = new Map();
45
+ console.log(chalk_1.default.gray(`Initial: ${config.events.length}\n`));
46
+ // WATCHER
47
+ const watcher = chokidar_1.default.watch([...files.map(normalize), ...watchedDeps], { ignoreInitial: true });
48
+ const queue = new Map();
86
49
  let timer = null;
87
50
  const run = async () => {
88
- if (locked)
89
- return;
90
- locked = true;
91
- const batch = [...queued.values()];
92
- queued.clear();
93
- for (const item of batch) {
51
+ const batch = [...queue.keys()];
52
+ queue.clear();
53
+ for (const file of batch) {
94
54
  try {
95
- const raw = await promises_1.default.readFile(item.real, "utf-8");
96
- if (raw.length > 2_000_000)
97
- continue;
98
- const parsed = (0, processFile_1.processFile)(item.real, raw);
99
- cache.set(item.real, parsed);
100
- engine.updateFile(item.virtual, parsed.content, config);
101
- // DEPENDENCY DIFF
102
- const nextDeps = new Set();
103
- for (const dep of parsed.deps) {
104
- nextDeps.add(normalize(dep));
105
- }
55
+ const raw = await promises_1.default.readFile(file, "utf-8");
56
+ const parsed = (0, processFile_1.processFile)(file, raw);
57
+ cache.set(file, parsed);
58
+ engine.updateFile((0, getVirtualFile_1.getVirtualFile)(file), parsed.content, config);
59
+ //dependency diff
60
+ const abs = normalize(file);
61
+ const prevDeps = fileDeps.get(abs) ?? new Set();
62
+ const nextDeps = new Set(parsed.deps.map(d => normalize(d)));
106
63
  // add new deps
107
64
  for (const dep of nextDeps) {
108
- if (!watchedDeps.has(dep)) {
65
+ if (!prevDeps.has(dep)) {
109
66
  watcher.add(dep);
110
67
  watchedDeps.add(dep);
111
68
  }
112
69
  }
113
70
  // remove old deps
114
- for (const dep of [...watchedDeps]) {
71
+ for (const dep of prevDeps) {
115
72
  if (!nextDeps.has(dep)) {
116
73
  watcher.unwatch(dep);
117
74
  watchedDeps.delete(dep);
118
75
  }
119
76
  }
120
- // preload deps
121
- for (const dep of nextDeps) {
122
- try {
123
- const raw = await promises_1.default.readFile(dep, "utf-8");
124
- const parsedDep = (0, processFile_1.processFile)(dep, raw);
125
- cache.set(dep, parsedDep);
126
- const virtual = (0, getVirtualFile_1.getVirtualFile)(dep);
127
- engine.updateFile(virtual, parsedDep.content, config);
128
- }
129
- catch { }
130
- }
77
+ fileDeps.set(abs, nextDeps);
131
78
  }
132
79
  catch {
133
- console.log(chalk_1.default.gray(`skip: ${item.real}`));
80
+ console.log(chalk_1.default.gray(`skip: ${file}`));
134
81
  }
135
82
  }
136
- // DIFF EVENTS
137
- const next = engine.getAllEvents();
138
- const added = next.filter(e => !config.events.includes(e));
139
- const removed = config.events.filter(e => !next.includes(e));
140
- if (added.length || removed.length) {
141
- added.forEach(e => console.log(chalk_1.default.green(`+ ${e}`)));
142
- removed.forEach(e => console.log(chalk_1.default.red(`- ${e}`)));
143
- config.events = next.sort();
144
- await (0, config_1.saveConfig)(config);
145
- console.log(chalk_1.default.gray(`Total: ${config.events.length} events\n`));
146
- }
147
- locked = false;
83
+ const next = engine.getAllEvents().sort();
84
+ config.events = next;
85
+ await (0, config_1.saveConfig)(config);
86
+ console.log(chalk_1.default.green(`Updated: ${next.length}`));
148
87
  };
149
- // SCHEDULER
150
88
  const schedule = (file) => {
151
89
  const abs = normalize(file);
152
- const virtual = (0, getVirtualFile_1.getVirtualFile)(abs);
153
- console.log(chalk_1.default.gray(`change: ${file}`));
154
- queued.set(abs, { real: abs, virtual });
90
+ queue.set(abs, true);
155
91
  if (timer)
156
92
  clearTimeout(timer);
157
93
  timer = setTimeout(run, 200);
158
94
  };
159
- // WATCHER
160
- const watcher = chokidar_1.default.watch(config.sync.include, {
161
- ignored: config.sync.exclude,
162
- ignoreInitial: true,
163
- persistent: true,
164
- });
165
95
  watcher
166
- .on("add", schedule)
167
96
  .on("change", schedule)
97
+ .on("add", schedule)
168
98
  .on("unlink", async (file) => {
169
99
  const abs = normalize(file);
170
- console.log(chalk_1.default.gray(`remove: ${file}`));
171
- const virtual = (0, getVirtualFile_1.getVirtualFile)(abs);
172
- engine.removeFile(virtual, config);
173
- watcher.unwatch(abs);
174
- watchedDeps.delete(abs);
175
- const next = engine.getAllEvents();
176
- config.events = next.sort();
100
+ engine.removeFile((0, getVirtualFile_1.getVirtualFile)(abs), config);
101
+ const next = engine.getAllEvents().sort();
102
+ config.events = next;
177
103
  await (0, config_1.saveConfig)(config);
178
- console.log(chalk_1.default.gray(`Total: ${config.events.length} events\n`));
179
- })
180
- .on("error", (err) => {
181
- console.error(chalk_1.default.red("Watcher error:"), err);
104
+ console.log(chalk_1.default.red(`Removed → ${next.length}`));
182
105
  });
183
- // WATCH DEPS INIT
184
- for (const dep of watchedDeps) {
185
- watcher.add(dep);
186
- }
187
- // EXIT
188
106
  process.on("SIGINT", async () => {
189
- console.log(chalk_1.default.yellow("\nStopping watcher..."));
190
107
  await watcher.close();
191
108
  process.exit(0);
192
109
  });
@@ -41,7 +41,7 @@ class EventraEngine {
41
41
  this.graph.update(file, source);
42
42
  }
43
43
  }
44
- // SCAN FILE
44
+ // SCAN FILE (cached)
45
45
  scanFile(file, content, config) {
46
46
  file = this.normalize(file);
47
47
  const h = (0, hash_1.hash)(content);
@@ -55,7 +55,6 @@ class EventraEngine {
55
55
  if (!source || !checker) {
56
56
  return this.empty();
57
57
  }
58
- // update graph
59
58
  this.graph.update(file, source);
60
59
  const res = (0, scanner_1.scanSource)(source, checker, config, new Set(), undefined, this.wrapperCache);
61
60
  this.fileResults.set(file, res);
@@ -63,12 +62,19 @@ class EventraEngine {
63
62
  }
64
63
  // UPDATE FILE (incremental)
65
64
  updateFile(file, content, config) {
66
- this.wrapperCache.clear();
67
65
  file = this.normalize(file);
66
+ // EARLY EXIT
67
+ if (this.fileHash.get(file) === (0, hash_1.hash)(content)) {
68
+ return this.fileResults.get(file) ?? this.empty();
69
+ }
70
+ // invalidate wrapper cache
71
+ this.wrapperCache.clear();
68
72
  const res = this.scanFile(file, content, config);
69
73
  const dependents = this.graph.getAllDependentsDeep(file);
70
74
  for (const dep of dependents) {
71
75
  const abs = this.normalize(dep);
76
+ if (abs === file)
77
+ continue; // self-skip
72
78
  if ((0, boundary_1.isExternalFile)(abs))
73
79
  continue;
74
80
  let depContent = this.ts.getFileContent(abs);
@@ -106,15 +112,17 @@ class EventraEngine {
106
112
  }
107
113
  // REMOVE FILE
108
114
  removeFile(file, config) {
109
- this.wrapperCache.clear();
110
115
  file = this.normalize(file);
116
+ this.wrapperCache.clear();
111
117
  const dependents = this.graph.getAllDependentsDeep(file);
118
+ this.graph.remove(file);
112
119
  this.ts.removeFile(file);
113
120
  this.fileResults.delete(file);
114
121
  this.fileHash.delete(file);
115
- this.graph.remove(file);
116
122
  for (const dep of dependents) {
117
123
  const abs = this.normalize(dep);
124
+ if (abs === file)
125
+ continue;
118
126
  if ((0, boundary_1.isExternalFile)(abs))
119
127
  continue;
120
128
  let content = this.ts.getFileContent(abs);
@@ -126,10 +134,7 @@ class EventraEngine {
126
134
  continue;
127
135
  }
128
136
  }
129
- const h = (0, hash_1.hash)(content);
130
- if (this.fileHash.get(abs) === h)
131
- continue;
132
- this.fileHash.set(abs, h);
137
+ this.fileHash.delete(abs);
133
138
  this.ts.updateFile(abs, content);
134
139
  const source = this.ts.getSourceFile(abs);
135
140
  const checker = this.ts.getChecker();
@@ -8,6 +8,7 @@ const typescript_1 = __importDefault(require("typescript"));
8
8
  const resolver_1 = require("./resolver");
9
9
  const callResolver_1 = require("./callResolver");
10
10
  const exportResolver_1 = require("./exportResolver");
11
+ // HELPERS
11
12
  function isValidEvent(v) {
12
13
  return (v &&
13
14
  v.length > 1 &&
@@ -36,6 +37,7 @@ function getJsxAttrName(name) {
36
37
  return name.name.text;
37
38
  return "";
38
39
  }
40
+ // MAIN
39
41
  function scanSource(source, checker, config, visited = new Set(), inheritedParamMap, wrapperCache = new Map()) {
40
42
  const events = new Set();
41
43
  const detectedFunctionWrappers = new Set();
@@ -44,30 +46,38 @@ function scanSource(source, checker, config, visited = new Set(), inheritedParam
44
46
  return { events, detectedFunctionWrappers, detectedComponentWrappers };
45
47
  }
46
48
  visited.add(source.fileName);
49
+ // TRACK DETECTION
50
+ function isTrackCall(expr) {
51
+ if (typescript_1.default.isIdentifier(expr)) {
52
+ return expr.text === "track";
53
+ }
54
+ if (typescript_1.default.isPropertyAccessExpression(expr)) {
55
+ return expr.name.text === "track";
56
+ }
57
+ return false;
58
+ }
47
59
  function extractTrackCall(node, paramMap) {
48
- const expr = node.expression;
49
- if (typescript_1.default.isPropertyAccessExpression(expr) && expr.name.text === "track") {
50
- const arg = node.arguments[0];
51
- if (!arg)
52
- return;
53
- const res = (0, resolver_1.resolveNodeValue)(arg, checker, paramMap);
54
- for (const v of res.values) {
55
- if (isValidEvent(v))
56
- events.add(v);
60
+ if (!isTrackCall(node.expression))
61
+ return;
62
+ const arg = node.arguments[0];
63
+ if (!arg)
64
+ return;
65
+ const res = (0, resolver_1.resolveNodeValue)(arg, checker, paramMap);
66
+ for (const v of res.values) {
67
+ if (isValidEvent(v)) {
68
+ events.add(v);
57
69
  }
58
70
  }
59
71
  }
72
+ // WRAPPER DETECTION
60
73
  function isWrapperFunction(fn) {
61
74
  let found = false;
62
75
  function walk(n) {
63
76
  if (found)
64
77
  return;
65
- if (typescript_1.default.isCallExpression(n)) {
66
- const expr = n.expression;
67
- if (typescript_1.default.isPropertyAccessExpression(expr) && expr.name.text === "track") {
68
- found = true;
69
- return;
70
- }
78
+ if (typescript_1.default.isCallExpression(n) && isTrackCall(n.expression)) {
79
+ found = true;
80
+ return;
71
81
  }
72
82
  typescript_1.default.forEachChild(n, walk);
73
83
  }
@@ -75,10 +85,12 @@ function scanSource(source, checker, config, visited = new Set(), inheritedParam
75
85
  walk(fn.body);
76
86
  return found;
77
87
  }
88
+ // COMPONENT WRAPPER
78
89
  function detectComponentWrapper(tag) {
79
90
  const tagName = getJsxTagName(tag);
80
- if (wrapperCache.has(tagName))
91
+ if (wrapperCache.has(tagName)) {
81
92
  return wrapperCache.get(tagName);
93
+ }
82
94
  let symbol = checker.getSymbolAtLocation(tag);
83
95
  if (symbol && (symbol.flags & typescript_1.default.SymbolFlags.Alias)) {
84
96
  symbol = checker.getAliasedSymbol(symbol);
@@ -104,14 +116,11 @@ function scanSource(source, checker, config, visited = new Set(), inheritedParam
104
116
  function walk(n) {
105
117
  if (prop)
106
118
  return;
107
- if (typescript_1.default.isCallExpression(n)) {
108
- const expr = n.expression;
109
- if (typescript_1.default.isPropertyAccessExpression(expr) && expr.name.text === "track") {
110
- const arg = n.arguments[0];
111
- if (typescript_1.default.isPropertyAccessExpression(arg)) {
112
- prop = arg.name.text;
113
- return;
114
- }
119
+ if (typescript_1.default.isCallExpression(n) && isTrackCall(n.expression)) {
120
+ const arg = n.arguments[0];
121
+ if (typescript_1.default.isPropertyAccessExpression(arg)) {
122
+ prop = arg.name.text;
123
+ return;
115
124
  }
116
125
  }
117
126
  typescript_1.default.forEachChild(n, walk);
@@ -126,6 +135,7 @@ function scanSource(source, checker, config, visited = new Set(), inheritedParam
126
135
  wrapperCache.set(tagName, null);
127
136
  return null;
128
137
  }
138
+ // VISITOR
129
139
  function visit(node) {
130
140
  // JSX
131
141
  if (typescript_1.default.isJsxSelfClosingElement(node) || typescript_1.default.isJsxOpeningElement(node)) {
@@ -183,9 +193,7 @@ function scanSource(source, checker, config, visited = new Set(), inheritedParam
183
193
  }
184
194
  });
185
195
  }
186
- // direct track
187
196
  extractTrackCall(node, paramMap);
188
- // wrapper
189
197
  if (resolvedFn && isWrapperFunction(resolvedFn)) {
190
198
  const name = getCallName(node.expression);
191
199
  if (name && name !== "track") {
@@ -195,9 +203,14 @@ function scanSource(source, checker, config, visited = new Set(), inheritedParam
195
203
  visit(resolvedFn.body);
196
204
  }
197
205
  }
198
- for (const arg of node.arguments) {
199
- visit(arg);
206
+ if (resolvedFn && resolvedFn.body) {
207
+ const sf = resolvedFn.getSourceFile();
208
+ if (!visited.has(sf.fileName)) {
209
+ const res = scanSource(sf, checker, config, visited, paramMap, wrapperCache);
210
+ res.events.forEach(e => events.add(e));
211
+ }
200
212
  }
213
+ node.arguments.forEach(visit);
201
214
  visit(node.expression);
202
215
  return;
203
216
  }
@@ -184,7 +184,7 @@ function parseUniversal(content, file) {
184
184
  deps.push(...dyn.deps);
185
185
  parts.push(...dyn.calls);
186
186
  return {
187
- code: [...new Set(parts)].join("\n"),
187
+ code: content,
188
188
  deps: [...new Set(deps.filter(Boolean))],
189
189
  };
190
190
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventra_dev/eventra-cli",
3
- "version": "0.1.34",
3
+ "version": "0.2.1",
4
4
  "description": "Eventra CLI",
5
5
  "type": "commonjs",
6
6
  "bin": {