@eventra_dev/eventra-cli 0.1.15 → 0.1.17

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.
@@ -30,8 +30,8 @@ async function sync() {
30
30
  try {
31
31
  const raw = await promises_1.default.readFile(file, "utf-8");
32
32
  const { content, virtualFile } = (0, processFile_1.processFile)(file, raw);
33
- fileCache.push({ file: virtualFile, content });
34
33
  engine["ts"].updateFile(virtualFile, content);
34
+ fileCache.push({ file: virtualFile, content });
35
35
  }
36
36
  catch {
37
37
  // ignore
@@ -13,7 +13,6 @@ const config_1 = require("../utils/config");
13
13
  const engine_1 = require("../engine/engine");
14
14
  const processFile_1 = require("../utils/processFile");
15
15
  async function watch() {
16
- process.env.EVENTRA_WATCH = "1";
17
16
  const config = await (0, config_1.loadConfig)();
18
17
  if (!config)
19
18
  return;
@@ -30,7 +29,6 @@ async function watch() {
30
29
  const raw = await promises_1.default.readFile(abs, "utf-8");
31
30
  const { content, virtualFile } = (0, processFile_1.processFile)(abs, raw);
32
31
  fileCache.push({ file: virtualFile, content });
33
- engine["ts"].updateFile(virtualFile, content);
34
32
  }
35
33
  catch {
36
34
  console.log(chalk_1.default.gray(`skip: ${file}`));
@@ -54,22 +52,14 @@ async function watch() {
54
52
  queued.clear();
55
53
  for (const file of batch) {
56
54
  try {
57
- const abs = path_1.default.resolve(file);
58
- const raw = await promises_1.default.readFile(abs, "utf-8");
59
- const { content, virtualFile } = (0, processFile_1.processFile)(abs, raw);
60
- engine["ts"].updateFile(virtualFile, content);
55
+ const raw = await promises_1.default.readFile(file, "utf-8");
56
+ const { content, virtualFile } = (0, processFile_1.processFile)(file, raw);
57
+ engine.updateFile(virtualFile, content, config);
61
58
  }
62
59
  catch {
63
60
  console.log(chalk_1.default.gray(`skip: ${file}`));
64
61
  }
65
62
  }
66
- const allFiles = [...engine["ts"]["fileNames"]];
67
- for (const file of allFiles) {
68
- const content = engine["ts"].getFileContent(file);
69
- if (!content)
70
- continue;
71
- engine.scanFile(file, content, config);
72
- }
73
63
  const next = engine.getAllEvents();
74
64
  const added = next.filter(e => !config.events.includes(e));
75
65
  const removed = config.events.filter(e => !next.includes(e));
@@ -83,11 +73,10 @@ async function watch() {
83
73
  locked = false;
84
74
  };
85
75
  const schedule = (file) => {
86
- const abs = path_1.default.resolve(file);
87
- queued.add(abs);
76
+ queued.add(path_1.default.resolve(file));
88
77
  if (timer)
89
78
  clearTimeout(timer);
90
- timer = setTimeout(run, 100);
79
+ timer = setTimeout(run, 200);
91
80
  };
92
81
  const watcher = chokidar_1.default.watch(config.sync.include, {
93
82
  ignored: config.sync.exclude,
@@ -19,9 +19,8 @@ class EventraEngine {
19
19
  // SCAN FILE
20
20
  scanFile(file, content, config) {
21
21
  const h = (0, hash_1.hash)(content);
22
- const isWatch = process.env.EVENTRA_WATCH === "1";
23
22
  // skip unchanged
24
- if (this.fileHash.get(file) === h && !isWatch) {
23
+ if (this.fileHash.get(file) === h) {
25
24
  return (this.fileResults.get(file) ?? {
26
25
  events: new Set(),
27
26
  detectedFunctionWrappers: new Set(),
@@ -39,7 +38,6 @@ class EventraEngine {
39
38
  detectedComponentWrappers: new Map(),
40
39
  };
41
40
  }
42
- // update dependency graph
43
41
  this.graph.update(file, source);
44
42
  const res = (0, scanner_1.scanSource)(source, checker, config);
45
43
  this.fileResults.set(file, res);
@@ -47,25 +45,24 @@ class EventraEngine {
47
45
  }
48
46
  // UPDATE FILE (incremental)
49
47
  updateFile(file, content, config) {
48
+ // сначала обновляем текущий файл
50
49
  const res = this.scanFile(file, content, config);
51
50
  const dependents = this.graph.getAllDependentsDeep(file);
52
51
  for (const dep of dependents) {
53
- // skip external files
54
52
  if ((0, boundary_1.isExternalFile)(dep))
55
53
  continue;
56
- const source = this.ts.getSourceFile(dep);
57
- const checker = this.ts.getChecker();
58
- if (!source || !checker)
59
- continue;
60
54
  const depContent = this.ts.getFileContent(dep);
61
55
  if (!depContent)
62
56
  continue;
63
57
  const h = (0, hash_1.hash)(depContent);
64
- const isWatch = process.env.EVENTRA_WATCH === "1";
65
- // skip unchanged dependents
66
- if (this.fileHash.get(dep) === h && !isWatch)
58
+ if (this.fileHash.get(dep) === h)
67
59
  continue;
68
60
  this.fileHash.set(dep, h);
61
+ this.ts.updateFile(dep, depContent);
62
+ const source = this.ts.getSourceFile(dep);
63
+ const checker = this.ts.getChecker();
64
+ if (!source || !checker)
65
+ continue;
69
66
  this.graph.update(dep, source);
70
67
  const r = (0, scanner_1.scanSource)(source, checker, config);
71
68
  this.fileResults.set(dep, r);
@@ -90,19 +87,18 @@ class EventraEngine {
90
87
  for (const dep of dependents) {
91
88
  if ((0, boundary_1.isExternalFile)(dep))
92
89
  continue;
93
- const source = this.ts.getSourceFile(dep);
94
- const checker = this.ts.getChecker();
95
- if (!source || !checker)
96
- continue;
97
90
  const content = this.ts.getFileContent(dep);
98
91
  if (!content)
99
92
  continue;
100
93
  const h = (0, hash_1.hash)(content);
101
- const isWatch = process.env.EVENTRA_WATCH === "1";
102
- // skip unchanged
103
- if (this.fileHash.get(dep) === h && !isWatch)
94
+ if (this.fileHash.get(dep) === h)
104
95
  continue;
105
96
  this.fileHash.set(dep, h);
97
+ this.ts.updateFile(dep, content);
98
+ const source = this.ts.getSourceFile(dep);
99
+ const checker = this.ts.getChecker();
100
+ if (!source || !checker)
101
+ continue;
106
102
  const r = (0, scanner_1.scanSource)(source, checker, config ?? {
107
103
  events: [],
108
104
  wrappers: [],
@@ -2,12 +2,31 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseAstro = parseAstro;
4
4
  function parseAstro(content) {
5
- const frontmatter = content.match(/---([\s\S]*?)---/);
6
- const scripts = [
7
- ...content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g)
8
- ];
9
- return [
10
- frontmatter?.[1] ?? "",
11
- ...scripts.map(s => s[1])
12
- ].join("\n");
5
+ const parts = [];
6
+ // frontmatter
7
+ const frontmatter = content.match(/^---([\s\S]*?)---/);
8
+ if (frontmatter?.[1]) {
9
+ parts.push(frontmatter[1]);
10
+ }
11
+ // scripts
12
+ const scripts = content.matchAll(/<script([^>]*)>([\s\S]*?)<\/script>/g);
13
+ for (const m of scripts) {
14
+ const attrs = m[1];
15
+ const body = m[2];
16
+ if (attrs.includes("src")) {
17
+ const src = attrs.match(/src=["'](.+?)["']/)?.[1];
18
+ if (src) {
19
+ parts.push(`import "${src}"`);
20
+ }
21
+ }
22
+ else {
23
+ parts.push(body);
24
+ }
25
+ }
26
+ // inline handlers
27
+ const inlineJS = content.matchAll(/on\w+="([^"]+)"/g);
28
+ for (const m of inlineJS) {
29
+ parts.push(m[1] + ";");
30
+ }
31
+ return parts.join("\n");
13
32
  }
@@ -2,8 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseSvelte = parseSvelte;
4
4
  function parseSvelte(content) {
5
- const scriptMatches = [
6
- ...content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g)
7
- ];
8
- return scriptMatches.map(m => m[1]).join("\n");
5
+ const parts = [];
6
+ // scripts
7
+ const scripts = content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g);
8
+ for (const m of scripts) {
9
+ parts.push(m[1]);
10
+ }
11
+ // on:click / on:*
12
+ const handlers = content.matchAll(/on:\w+=\{([^}]+)\}/g);
13
+ for (const h of handlers) {
14
+ parts.push(h[1] + ";");
15
+ }
16
+ return parts.join("\n");
9
17
  }
@@ -2,30 +2,40 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseVue = parseVue;
4
4
  function parseVue(content) {
5
- const scriptMatches = [
6
- ...content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g)
7
- ];
8
- const script = scriptMatches.map(m => m[1]).join("\n");
9
- // template
10
- const templateMatch = content.match(/<template>([\s\S]*?)<\/template>/);
5
+ const parts = [];
6
+ // --- SCRIPT ---
7
+ const scripts = content.matchAll(/<script([^>]*)>([\s\S]*?)<\/script>/g);
8
+ for (const m of scripts) {
9
+ const attrs = m[1];
10
+ const body = m[2];
11
+ if (attrs.includes("src")) {
12
+ const src = attrs.match(/src=["'](.+?)["']/)?.[1];
13
+ if (src) {
14
+ parts.push(`import "${src}"`);
15
+ }
16
+ continue;
17
+ }
18
+ parts.push(body);
19
+ }
20
+ // --- TEMPLATE ---
21
+ const templateMatch = content.match(/<template[^>]*>([\s\S]*?)<\/template>/);
11
22
  let template = templateMatch?.[1] ?? "";
23
+ // remove comments
12
24
  template = template.replace(/<!--[\s\S]*?-->/g, "");
13
- // Vue → JSX
14
- template = template
15
- .replace(/\bclass=/g, "className=")
16
- .replace(/\bfor=/g, "htmlFor=")
17
- .replace(/@(\w+)=/g, (_, e) => {
18
- const name = e.charAt(0).toUpperCase() + e.slice(1);
19
- return `on${name}=`;
20
- })
21
- .replace(/v-if="[^"]+"/g, "")
22
- .replace(/v-for="[^"]+"/g, "");
23
- const jsx = `
24
- const __VUE_JSX__ = (
25
- <>
26
- ${template}
27
- </>
28
- );
29
- `;
30
- return script + "\n" + jsx;
25
+ // --- event handlers (@click)
26
+ const handlers = template.matchAll(/@[\w-]+="([^"]+)"/g);
27
+ for (const h of handlers) {
28
+ parts.push(h[1] + ";");
29
+ }
30
+ // --- v-on
31
+ const vOn = template.matchAll(/v-on:[\w-]+="([^"]+)"/g);
32
+ for (const v of vOn) {
33
+ parts.push(v[1] + ";");
34
+ }
35
+ // --- :prop bindings
36
+ const binds = template.matchAll(/:[\w-]+="([^"]+)"/g);
37
+ for (const b of binds) {
38
+ parts.push(b[1] + ";");
39
+ }
40
+ return parts.join("\n");
31
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventra_dev/eventra-cli",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Eventra CLI",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -32,10 +32,8 @@ export async function sync() {
32
32
  try {
33
33
  const raw = await fs.readFile(file, "utf-8");
34
34
  const { content, virtualFile } = processFile(file, raw);
35
-
36
- fileCache.push({ file: virtualFile, content });
37
-
38
35
  engine["ts"].updateFile(virtualFile, content);
36
+ fileCache.push({ file: virtualFile, content });
39
37
  } catch {
40
38
  // ignore
41
39
  }
@@ -9,8 +9,6 @@ import { EventraEngine } from "../engine/engine";
9
9
  import { processFile } from "../utils/processFile";
10
10
 
11
11
  export async function watch() {
12
- process.env.EVENTRA_WATCH = "1";
13
-
14
12
  const config = await loadConfig();
15
13
  if (!config) return;
16
14
 
@@ -29,12 +27,8 @@ export async function watch() {
29
27
  try {
30
28
  const abs = path.resolve(file);
31
29
  const raw = await fs.readFile(abs, "utf-8");
32
-
33
30
  const { content, virtualFile } = processFile(abs, raw);
34
-
35
31
  fileCache.push({ file: virtualFile, content });
36
-
37
- engine["ts"].updateFile(virtualFile, content);
38
32
  } catch {
39
33
  console.log(chalk.gray(`skip: ${file}`));
40
34
  }
@@ -65,27 +59,16 @@ export async function watch() {
65
59
 
66
60
  for (const file of batch) {
67
61
  try {
68
- const abs = path.resolve(file);
69
- const raw = await fs.readFile(abs, "utf-8");
70
-
71
- const { content, virtualFile } = processFile(abs, raw);
62
+ const raw = await fs.readFile(file, "utf-8");
63
+ const { content, virtualFile } = processFile(file, raw);
72
64
 
73
- engine["ts"].updateFile(virtualFile, content);
65
+ engine.updateFile(virtualFile, content, config);
74
66
 
75
67
  } catch {
76
68
  console.log(chalk.gray(`skip: ${file}`));
77
69
  }
78
70
  }
79
71
 
80
- const allFiles = [...engine["ts"]["fileNames"]];
81
-
82
- for (const file of allFiles) {
83
- const content = engine["ts"].getFileContent(file);
84
- if (!content) continue;
85
-
86
- engine.scanFile(file, content, config);
87
- }
88
-
89
72
  const next = engine.getAllEvents();
90
73
 
91
74
  const added = next.filter(e => !config.events.includes(e));
@@ -107,11 +90,10 @@ export async function watch() {
107
90
  };
108
91
 
109
92
  const schedule = (file: string) => {
110
- const abs = path.resolve(file);
111
- queued.add(abs);
93
+ queued.add(path.resolve(file));
112
94
 
113
95
  if (timer) clearTimeout(timer);
114
- timer = setTimeout(run, 100);
96
+ timer = setTimeout(run, 200);
115
97
  };
116
98
 
117
99
  const watcher = chokidar.watch(config.sync.include, {
@@ -26,10 +26,9 @@ export class EventraEngine {
26
26
  config: EventraConfig
27
27
  ): ScanResult {
28
28
  const h = hash(content);
29
- const isWatch = process.env.EVENTRA_WATCH === "1";
30
29
 
31
30
  // skip unchanged
32
- if (this.fileHash.get(file) === h && !isWatch) {
31
+ if (this.fileHash.get(file) === h) {
33
32
  return (
34
33
  this.fileResults.get(file) ?? {
35
34
  events: new Set(),
@@ -53,11 +52,9 @@ export class EventraEngine {
53
52
  };
54
53
  }
55
54
 
56
- // update dependency graph
57
55
  this.graph.update(file, source);
58
56
 
59
57
  const res = scanSource(source, checker, config);
60
-
61
58
  this.fileResults.set(file, res);
62
59
 
63
60
  return res;
@@ -69,29 +66,28 @@ export class EventraEngine {
69
66
  content: string,
70
67
  config: EventraConfig
71
68
  ) {
69
+ // сначала обновляем текущий файл
72
70
  const res = this.scanFile(file, content, config);
73
71
 
74
72
  const dependents = this.graph.getAllDependentsDeep(file);
75
73
 
76
74
  for (const dep of dependents) {
77
- // skip external files
78
75
  if (isExternalFile(dep)) continue;
79
76
 
80
- const source = this.ts.getSourceFile(dep);
81
- const checker = this.ts.getChecker();
82
-
83
- if (!source || !checker) continue;
84
-
85
77
  const depContent = this.ts.getFileContent(dep);
86
78
  if (!depContent) continue;
87
79
 
88
80
  const h = hash(depContent);
89
- const isWatch = process.env.EVENTRA_WATCH === "1";
90
81
 
91
- // skip unchanged dependents
92
- if (this.fileHash.get(dep) === h && !isWatch) continue;
82
+ if (this.fileHash.get(dep) === h) continue;
93
83
 
94
84
  this.fileHash.set(dep, h);
85
+ this.ts.updateFile(dep, depContent);
86
+
87
+ const source = this.ts.getSourceFile(dep);
88
+ const checker = this.ts.getChecker();
89
+
90
+ if (!source || !checker) continue;
95
91
 
96
92
  this.graph.update(dep, source);
97
93
 
@@ -119,26 +115,26 @@ export class EventraEngine {
119
115
  this.fileResults.delete(file);
120
116
  this.fileHash.delete(file);
121
117
  this.graph.remove(file);
118
+
122
119
  const dependents = this.graph.getAllDependentsDeep(file);
123
120
 
124
121
  for (const dep of dependents) {
125
122
  if (isExternalFile(dep)) continue;
126
123
 
127
- const source = this.ts.getSourceFile(dep);
128
- const checker = this.ts.getChecker();
129
-
130
- if (!source || !checker) continue;
131
-
132
124
  const content = this.ts.getFileContent(dep);
133
125
  if (!content) continue;
134
126
 
135
127
  const h = hash(content);
136
- const isWatch = process.env.EVENTRA_WATCH === "1";
137
128
 
138
- // skip unchanged
139
- if (this.fileHash.get(dep) === h && !isWatch) continue;
129
+ if (this.fileHash.get(dep) === h) continue;
140
130
 
141
131
  this.fileHash.set(dep, h);
132
+ this.ts.updateFile(dep, content);
133
+
134
+ const source = this.ts.getSourceFile(dep);
135
+ const checker = this.ts.getChecker();
136
+
137
+ if (!source || !checker) continue;
142
138
 
143
139
  const r = scanSource(
144
140
  source,
@@ -1,12 +1,35 @@
1
1
  export function parseAstro(content: string) {
2
- const frontmatter = content.match(/---([\s\S]*?)---/);
2
+ const parts: string[] = [];
3
3
 
4
- const scripts = [
5
- ...content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g)
6
- ];
4
+ // frontmatter
5
+ const frontmatter = content.match(/^---([\s\S]*?)---/);
6
+ if (frontmatter?.[1]) {
7
+ parts.push(frontmatter[1]);
8
+ }
7
9
 
8
- return [
9
- frontmatter?.[1] ?? "",
10
- ...scripts.map(s => s[1])
11
- ].join("\n");
10
+ // scripts
11
+ const scripts = content.matchAll(/<script([^>]*)>([\s\S]*?)<\/script>/g);
12
+
13
+ for (const m of scripts) {
14
+ const attrs = m[1];
15
+ const body = m[2];
16
+
17
+ if (attrs.includes("src")) {
18
+ const src = attrs.match(/src=["'](.+?)["']/)?.[1];
19
+ if (src) {
20
+ parts.push(`import "${src}"`);
21
+ }
22
+ } else {
23
+ parts.push(body);
24
+ }
25
+ }
26
+
27
+ // inline handlers
28
+ const inlineJS = content.matchAll(/on\w+="([^"]+)"/g);
29
+
30
+ for (const m of inlineJS) {
31
+ parts.push(m[1] + ";");
32
+ }
33
+
34
+ return parts.join("\n");
12
35
  }
@@ -1,7 +1,17 @@
1
1
  export function parseSvelte(content: string) {
2
- const scriptMatches = [
3
- ...content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g)
4
- ];
2
+ const parts: string[] = [];
5
3
 
6
- return scriptMatches.map(m => m[1]).join("\n");
4
+ // scripts
5
+ const scripts = content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g);
6
+ for (const m of scripts) {
7
+ parts.push(m[1]);
8
+ }
9
+
10
+ // on:click / on:*
11
+ const handlers = content.matchAll(/on:\w+=\{([^}]+)\}/g);
12
+ for (const h of handlers) {
13
+ parts.push(h[1] + ";");
14
+ }
15
+
16
+ return parts.join("\n");
7
17
  }
@@ -1,34 +1,48 @@
1
1
  export function parseVue(content: string) {
2
- const scriptMatches = [
3
- ...content.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/g)
4
- ];
2
+ const parts: string[] = [];
5
3
 
6
- const script = scriptMatches.map(m => m[1]).join("\n");
4
+ // --- SCRIPT ---
5
+ const scripts = content.matchAll(/<script([^>]*)>([\s\S]*?)<\/script>/g);
7
6
 
8
- // template
9
- const templateMatch = content.match(/<template>([\s\S]*?)<\/template>/);
7
+ for (const m of scripts) {
8
+ const attrs = m[1];
9
+ const body = m[2];
10
+
11
+ if (attrs.includes("src")) {
12
+ const src = attrs.match(/src=["'](.+?)["']/)?.[1];
13
+ if (src) {
14
+ parts.push(`import "${src}"`);
15
+ }
16
+ continue;
17
+ }
18
+
19
+ parts.push(body);
20
+ }
21
+
22
+ // --- TEMPLATE ---
23
+ const templateMatch = content.match(/<template[^>]*>([\s\S]*?)<\/template>/);
10
24
  let template = templateMatch?.[1] ?? "";
11
25
 
26
+ // remove comments
12
27
  template = template.replace(/<!--[\s\S]*?-->/g, "");
13
28
 
14
- // Vue → JSX
15
- template = template
16
- .replace(/\bclass=/g, "className=")
17
- .replace(/\bfor=/g, "htmlFor=")
18
- .replace(/@(\w+)=/g, (_, e) => {
19
- const name = e.charAt(0).toUpperCase() + e.slice(1);
20
- return `on${name}=`;
21
- })
22
- .replace(/v-if="[^"]+"/g, "")
23
- .replace(/v-for="[^"]+"/g, "");
24
-
25
- const jsx = `
26
- const __VUE_JSX__ = (
27
- <>
28
- ${template}
29
- </>
30
- );
31
- `;
32
-
33
- return script + "\n" + jsx;
29
+ // --- event handlers (@click)
30
+ const handlers = template.matchAll(/@[\w-]+="([^"]+)"/g);
31
+ for (const h of handlers) {
32
+ parts.push(h[1] + ";");
33
+ }
34
+
35
+ // --- v-on
36
+ const vOn = template.matchAll(/v-on:[\w-]+="([^"]+)"/g);
37
+ for (const v of vOn) {
38
+ parts.push(v[1] + ";");
39
+ }
40
+
41
+ // --- :prop bindings
42
+ const binds = template.matchAll(/:[\w-]+="([^"]+)"/g);
43
+ for (const b of binds) {
44
+ parts.push(b[1] + ";");
45
+ }
46
+
47
+ return parts.join("\n");
34
48
  }