@eventra_dev/eventra-cli 0.1.23 → 0.1.24

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.
@@ -12,6 +12,12 @@ const path_1 = __importDefault(require("path"));
12
12
  const config_1 = require("../utils/config");
13
13
  const engine_1 = require("../engine/engine");
14
14
  const processFile_1 = require("../utils/processFile");
15
+ // stabile virtual mapping
16
+ function getVirtualFile(file) {
17
+ return /\.(vue|svelte|astro|html)$/i.test(file)
18
+ ? file + ".tsx"
19
+ : file;
20
+ }
15
21
  async function watch() {
16
22
  const config = await (0, config_1.loadConfig)();
17
23
  if (!config)
@@ -21,54 +27,65 @@ async function watch() {
21
27
  ignore: config.sync.exclude,
22
28
  });
23
29
  const engine = new engine_1.EventraEngine(process.cwd());
24
- const fileCache = [];
25
- // PRELOAD TS
30
+ const watchedDeps = new Set();
31
+ // INITIAL LOAD
26
32
  for (const file of files) {
27
33
  try {
28
34
  const abs = path_1.default.resolve(file);
29
35
  const raw = await promises_1.default.readFile(abs, "utf-8");
30
- const { content, virtualFile } = (0, processFile_1.processFile)(abs, raw);
31
- fileCache.push({ file: virtualFile, content });
36
+ const { content, deps } = (0, processFile_1.processFile)(abs, raw);
37
+ const virtual = getVirtualFile(abs);
38
+ engine.scanFile(virtual, content, config);
39
+ // deps
40
+ for (const dep of deps) {
41
+ watchedDeps.add(path_1.default.resolve(dep));
42
+ }
32
43
  }
33
44
  catch {
34
45
  console.log(chalk_1.default.gray(`skip: ${file}`));
35
46
  }
36
47
  }
37
- // INITIAL SCAN
38
- for (const { file, content } of fileCache) {
39
- engine.scanFile(file, content, config);
40
- }
41
48
  config.events = engine.getAllEvents().sort();
42
49
  await (0, config_1.saveConfig)(config);
43
50
  console.log(chalk_1.default.gray(`Initial: ${config.events.length} events\n`));
51
+ // QUEUE
44
52
  let locked = false;
45
- let queued = new Set();
53
+ let queued = new Map();
46
54
  let timer = null;
47
55
  const run = async () => {
48
- if (locked)
56
+ if (locked) {
57
+ timer = setTimeout(run, 100);
49
58
  return;
59
+ }
50
60
  locked = true;
51
- const batch = [...queued];
61
+ const batch = [...queued.values()];
52
62
  queued.clear();
53
- for (const file of batch) {
63
+ for (const item of batch) {
54
64
  try {
55
- const raw = await promises_1.default.readFile(file, "utf-8");
56
- const { content, virtualFile, deps } = (0, processFile_1.processFile)(file, raw);
57
- engine.updateFile(virtualFile, content, config);
58
- // deps
65
+ const raw = await promises_1.default.readFile(item.real, "utf-8");
66
+ const { content, deps } = (0, processFile_1.processFile)(item.real, raw);
67
+ engine.updateFile(item.virtual, content, config);
68
+ // DEPS
59
69
  for (const dep of deps) {
70
+ const absDep = path_1.default.resolve(dep);
71
+ if (!watchedDeps.has(absDep)) {
72
+ watcher.add(absDep);
73
+ watchedDeps.add(absDep);
74
+ }
60
75
  try {
61
- const depRaw = await promises_1.default.readFile(dep, "utf-8");
62
- const { content: depContent, virtualFile: depVirtual, } = (0, processFile_1.processFile)(dep, depRaw);
76
+ const depRaw = await promises_1.default.readFile(absDep, "utf-8");
77
+ const { content: depContent } = (0, processFile_1.processFile)(absDep, depRaw);
78
+ const depVirtual = getVirtualFile(absDep);
63
79
  engine.updateFile(depVirtual, depContent, config);
64
80
  }
65
81
  catch { }
66
82
  }
67
83
  }
68
84
  catch {
69
- console.log(chalk_1.default.gray(`skip: ${file}`));
85
+ console.log(chalk_1.default.gray(`skip: ${item.real}`));
70
86
  }
71
87
  }
88
+ // EVENTS DIFF
72
89
  const next = engine.getAllEvents();
73
90
  const added = next.filter(e => !config.events.includes(e));
74
91
  const removed = config.events.filter(e => !next.includes(e));
@@ -81,12 +98,16 @@ async function watch() {
81
98
  }
82
99
  locked = false;
83
100
  };
101
+ // SCHEDULER
84
102
  const schedule = (file) => {
85
- queued.add(path_1.default.resolve(file));
103
+ const abs = path_1.default.resolve(file);
104
+ const virtual = getVirtualFile(abs);
105
+ queued.set(abs, { real: abs, virtual });
86
106
  if (timer)
87
107
  clearTimeout(timer);
88
- timer = setTimeout(run, 200);
108
+ timer = setTimeout(run, 300);
89
109
  };
110
+ // WATCHER
90
111
  const watcher = chokidar_1.default.watch(config.sync.include, {
91
112
  ignored: config.sync.exclude,
92
113
  ignoreInitial: true,
@@ -97,13 +118,19 @@ async function watch() {
97
118
  .on("unlink", async (file) => {
98
119
  const abs = path_1.default.resolve(file);
99
120
  console.log(chalk_1.default.gray(`remove: ${file}`));
100
- const { virtualFile } = (0, processFile_1.processFile)(abs, "");
101
- engine.removeFile(virtualFile, config);
121
+ const virtual = getVirtualFile(abs);
122
+ engine.removeFile(virtual, config);
123
+ watchedDeps.delete(abs);
102
124
  const next = engine.getAllEvents();
103
125
  config.events = next.sort();
104
126
  await (0, config_1.saveConfig)(config);
105
127
  console.log(chalk_1.default.gray(`Total: ${config.events.length} events\n`));
106
128
  });
129
+ // WATCH DEPS
130
+ for (const dep of watchedDeps) {
131
+ watcher.add(dep);
132
+ }
133
+ // EXIT
107
134
  process.on("SIGINT", async () => {
108
135
  console.log(chalk_1.default.yellow("\nStopping watcher..."));
109
136
  await watcher.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventra_dev/eventra-cli",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "Eventra CLI",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -8,6 +8,18 @@ import { loadConfig, saveConfig } from "../utils/config";
8
8
  import { EventraEngine } from "../engine/engine";
9
9
  import { processFile } from "../utils/processFile";
10
10
 
11
+ type QueueItem = {
12
+ real: string;
13
+ virtual: string;
14
+ };
15
+
16
+ // stabile virtual mapping
17
+ function getVirtualFile(file: string) {
18
+ return /\.(vue|svelte|astro|html)$/i.test(file)
19
+ ? file + ".tsx"
20
+ : file;
21
+ }
22
+
11
23
  export async function watch() {
12
24
  const config = await loadConfig();
13
25
  if (!config) return;
@@ -20,25 +32,29 @@ export async function watch() {
20
32
 
21
33
  const engine = new EventraEngine(process.cwd());
22
34
 
23
- const fileCache: { file: string; content: string }[] = [];
35
+ const watchedDeps = new Set<string>();
24
36
 
25
- // PRELOAD TS
37
+ // INITIAL LOAD
26
38
  for (const file of files) {
27
39
  try {
28
40
  const abs = path.resolve(file);
29
41
  const raw = await fs.readFile(abs, "utf-8");
30
- const { content, virtualFile } = processFile(abs, raw);
31
- fileCache.push({ file: virtualFile, content });
42
+
43
+ const { content, deps } = processFile(abs, raw);
44
+ const virtual = getVirtualFile(abs);
45
+
46
+ engine.scanFile(virtual, content, config);
47
+
48
+ // deps
49
+ for (const dep of deps) {
50
+ watchedDeps.add(path.resolve(dep));
51
+ }
52
+
32
53
  } catch {
33
54
  console.log(chalk.gray(`skip: ${file}`));
34
55
  }
35
56
  }
36
57
 
37
- // INITIAL SCAN
38
- for (const { file, content } of fileCache) {
39
- engine.scanFile(file, content, config);
40
- }
41
-
42
58
  config.events = engine.getAllEvents().sort();
43
59
  await saveConfig(config);
44
60
 
@@ -46,45 +62,55 @@ export async function watch() {
46
62
  chalk.gray(`Initial: ${config.events.length} events\n`)
47
63
  );
48
64
 
65
+ // QUEUE
49
66
  let locked = false;
50
- let queued = new Set<string>();
67
+ let queued = new Map<string, QueueItem>();
51
68
  let timer: NodeJS.Timeout | null = null;
52
69
 
53
70
  const run = async () => {
54
- if (locked) return;
71
+ if (locked) {
72
+ timer = setTimeout(run, 100);
73
+ return;
74
+ }
75
+
55
76
  locked = true;
56
77
 
57
- const batch = [...queued];
78
+ const batch = [...queued.values()];
58
79
  queued.clear();
59
80
 
60
- for (const file of batch) {
81
+ for (const item of batch) {
61
82
  try {
62
- const raw = await fs.readFile(file, "utf-8");
83
+ const raw = await fs.readFile(item.real, "utf-8");
63
84
 
64
- const { content, virtualFile, deps } = processFile(file, raw);
85
+ const { content, deps } = processFile(item.real, raw);
65
86
 
66
- engine.updateFile(virtualFile, content, config);
87
+ engine.updateFile(item.virtual, content, config);
67
88
 
68
- // deps
89
+ // DEPS
69
90
  for (const dep of deps) {
91
+ const absDep = path.resolve(dep);
92
+
93
+ if (!watchedDeps.has(absDep)) {
94
+ watcher.add(absDep);
95
+ watchedDeps.add(absDep);
96
+ }
97
+
70
98
  try {
71
- const depRaw = await fs.readFile(dep, "utf-8");
99
+ const depRaw = await fs.readFile(absDep, "utf-8");
100
+ const { content: depContent } = processFile(absDep, depRaw);
72
101
 
73
- const {
74
- content: depContent,
75
- virtualFile: depVirtual,
76
- } = processFile(dep, depRaw);
102
+ const depVirtual = getVirtualFile(absDep);
77
103
 
78
104
  engine.updateFile(depVirtual, depContent, config);
79
-
80
105
  } catch {}
81
106
  }
82
107
 
83
108
  } catch {
84
- console.log(chalk.gray(`skip: ${file}`));
109
+ console.log(chalk.gray(`skip: ${item.real}`));
85
110
  }
86
111
  }
87
112
 
113
+ // EVENTS DIFF
88
114
  const next = engine.getAllEvents();
89
115
 
90
116
  const added = next.filter(e => !config.events.includes(e));
@@ -105,13 +131,18 @@ export async function watch() {
105
131
  locked = false;
106
132
  };
107
133
 
134
+ // SCHEDULER
108
135
  const schedule = (file: string) => {
109
- queued.add(path.resolve(file));
136
+ const abs = path.resolve(file);
137
+ const virtual = getVirtualFile(abs);
138
+
139
+ queued.set(abs, { real: abs, virtual });
110
140
 
111
141
  if (timer) clearTimeout(timer);
112
- timer = setTimeout(run, 200);
142
+ timer = setTimeout(run, 300);
113
143
  };
114
144
 
145
+ // WATCHER
115
146
  const watcher = chokidar.watch(config.sync.include, {
116
147
  ignored: config.sync.exclude,
117
148
  ignoreInitial: true,
@@ -125,9 +156,11 @@ export async function watch() {
125
156
 
126
157
  console.log(chalk.gray(`remove: ${file}`));
127
158
 
128
- const { virtualFile } = processFile(abs, "");
159
+ const virtual = getVirtualFile(abs);
160
+
161
+ engine.removeFile(virtual, config);
129
162
 
130
- engine.removeFile(virtualFile, config);
163
+ watchedDeps.delete(abs);
131
164
 
132
165
  const next = engine.getAllEvents();
133
166
 
@@ -139,6 +172,12 @@ export async function watch() {
139
172
  );
140
173
  });
141
174
 
175
+ // WATCH DEPS
176
+ for (const dep of watchedDeps) {
177
+ watcher.add(dep);
178
+ }
179
+
180
+ // EXIT
142
181
  process.on("SIGINT", async () => {
143
182
  console.log(chalk.yellow("\nStopping watcher..."));
144
183
  await watcher.close();