tkeron 5.0.1 → 5.0.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/changelog.md CHANGED
@@ -1,3 +1,15 @@
1
+ # v5.0.2
2
+
3
+ ## Performance: component processing optimization
4
+
5
+ - Perf: single glob scan per build pass to pre-load all component paths into a `Map<tagName, filePath[]>` — eliminates O(pages × components) filesystem scans in `processCom`, `processComTs`, `processComMd`
6
+ - Perf: `Map<path, content>` cache avoids redundant disk reads when the same component is used across multiple pages
7
+ - Perf: `Map<code, jsCode>` transpilation cache in `processComTs` — `Bun.Transpiler.transformSync` result reused for unchanged `.com.ts` files
8
+ - Perf: parallel page processing via `Promise.all` instead of sequential `for...of` — independent pages now process concurrently
9
+ - Perf: lazy `package.json` read in `processPre` — removed top-level `await` that ran on module import regardless of whether pre-rendering was needed
10
+
11
+ ---
12
+
1
13
  # v5.0.1
2
14
 
3
15
  ## Documentation fixes and dependency updates
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tkeron",
3
- "version": "5.0.1",
3
+ "version": "5.0.2",
4
4
  "description": "CLI build tool for vanilla web development with TypeScript.",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
package/src/processCom.ts CHANGED
@@ -12,10 +12,50 @@ const ensureHtmlDocument = (html: string): string => {
12
12
  return `${DOCTYPE}<html><head></head><body>${html}</body></html>`;
13
13
  };
14
14
 
15
+ interface ComponentCache {
16
+ componentMap: Map<string, string[]>;
17
+ contentCache: Map<string, string>;
18
+ }
19
+
20
+ const buildComponentMap = (rootDir: string): Map<string, string[]> => {
21
+ const allFiles = getFilePaths(rootDir, "**/*.com.html", true);
22
+ const map = new Map<string, string[]>();
23
+ for (const file of allFiles) {
24
+ const basename = file.split("/").pop()!;
25
+ const tagName = basename.replace(/\.com\.html$/, "");
26
+ if (!map.has(tagName)) map.set(tagName, []);
27
+ map.get(tagName)!.push(file);
28
+ }
29
+ return map;
30
+ };
31
+
32
+ const getCachedContent = async (
33
+ path: string,
34
+ cache: Map<string, string>,
35
+ ): Promise<string> => {
36
+ const cached = cache.get(path);
37
+ if (cached !== undefined) return cached;
38
+ const content = await Bun.file(path).text();
39
+ cache.set(path, content);
40
+ return content;
41
+ };
42
+
15
43
  export interface ProcessComOptions {
16
44
  logger?: Logger;
17
45
  }
18
46
 
47
+ const resolveComponent = (
48
+ tagName: string,
49
+ currentDir: string,
50
+ componentMap: Map<string, string[]>,
51
+ ): string | null => {
52
+ const matches = componentMap.get(tagName);
53
+ if (!matches || matches.length === 0) return null;
54
+ const localPath = join(currentDir, `${tagName}.com.html`);
55
+ if (matches.includes(localPath)) return localPath;
56
+ return matches[0]!;
57
+ };
58
+
19
59
  export const processCom = async (
20
60
  tempDir: string,
21
61
  options: ProcessComOptions = {},
@@ -27,37 +67,45 @@ export const processCom = async (
27
67
  return false;
28
68
  }
29
69
 
70
+ const componentMap = buildComponentMap(tempDir);
71
+ const cache: ComponentCache = {
72
+ componentMap,
73
+ contentCache: new Map(),
74
+ };
75
+
30
76
  const htmlFiles = getFilePaths(tempDir, "**/*.html", true).filter(
31
77
  (p) => !p.endsWith(".com.html"),
32
78
  );
33
79
 
34
- let hasChanges = false;
35
-
36
- for (const htmlFile of htmlFiles) {
37
- const htmlContent = await Bun.file(htmlFile).text();
38
- const document = parseHTML(ensureHtmlDocument(htmlContent));
39
-
40
- const htmlElement =
41
- document.querySelector("html") || document.documentElement;
42
- if (htmlElement) {
43
- const changed = await processComponents(
44
- htmlElement,
45
- dirname(htmlFile),
46
- tempDir,
47
- [],
48
- 0,
49
- log,
50
- );
51
- hasChanges = hasChanges || changed;
52
- }
80
+ const results = await Promise.all(
81
+ htmlFiles.map(async (htmlFile) => {
82
+ const htmlContent = await Bun.file(htmlFile).text();
83
+ const document = parseHTML(ensureHtmlDocument(htmlContent));
84
+
85
+ const htmlElement =
86
+ document.querySelector("html") || document.documentElement;
87
+ let changed = false;
88
+ if (htmlElement) {
89
+ changed = await processComponents(
90
+ htmlElement,
91
+ dirname(htmlFile),
92
+ tempDir,
93
+ [],
94
+ 0,
95
+ log,
96
+ cache,
97
+ );
98
+ }
53
99
 
54
- const output =
55
- DOCTYPE +
56
- (htmlElement?.outerHTML || document.documentElement?.outerHTML || "");
57
- await Bun.write(htmlFile, output);
58
- }
100
+ const output =
101
+ DOCTYPE +
102
+ (htmlElement?.outerHTML || document.documentElement?.outerHTML || "");
103
+ await Bun.write(htmlFile, output);
104
+ return changed;
105
+ }),
106
+ );
59
107
 
60
- return hasChanges;
108
+ return results.some(Boolean);
61
109
  };
62
110
 
63
111
  const processComponents = async (
@@ -67,6 +115,7 @@ const processComponents = async (
67
115
  componentStack: string[],
68
116
  depth: number = 0,
69
117
  log: Logger = silentLogger,
118
+ cache: ComponentCache,
70
119
  ): Promise<boolean> => {
71
120
  let hasChanges = false;
72
121
  const MAX_DEPTH = 50;
@@ -82,13 +131,10 @@ const processComponents = async (
82
131
 
83
132
  if (tagName) {
84
133
  if (!tagName.includes("-")) {
85
- const localPath = join(currentDir, `${tagName}.com.html`);
86
- const globMatches = getFilePaths(
87
- rootDir,
88
- `**/${tagName}.com.html`,
89
- true,
90
- );
91
- if ((await Bun.file(localPath).exists()) || globMatches.length > 0) {
134
+ const matches = cache.componentMap.get(tagName);
135
+ if (matches && matches.length > 0) {
136
+ const localPath = join(currentDir, `${tagName}.com.html`);
137
+ const filePath = matches.includes(localPath) ? localPath : matches[0];
92
138
  log.error(
93
139
  `\n❌ Error: Component name '${tagName}' must contain at least one hyphen.`,
94
140
  );
@@ -96,30 +142,17 @@ const processComponents = async (
96
142
  log.error(
97
143
  ` Rename '${tagName}.com.html' to 'tk-${tagName}.com.html' or similar.`,
98
144
  );
99
- log.error(
100
- ` File: ${(await Bun.file(localPath).exists()) ? localPath : globMatches[0]}\n`,
101
- );
145
+ log.error(` File: ${filePath}\n`);
102
146
  throw new Error(
103
147
  `Component name '${tagName}' must contain at least one hyphen`,
104
148
  );
105
149
  }
106
150
  } else {
107
- const localPath = join(currentDir, `${tagName}.com.html`);
108
-
109
- let componentPath: string | null = null;
110
-
111
- if (await Bun.file(localPath).exists()) {
112
- componentPath = localPath;
113
- } else {
114
- const globMatches = getFilePaths(
115
- rootDir,
116
- `**/${tagName}.com.html`,
117
- true,
118
- );
119
- if (globMatches.length > 0) {
120
- componentPath = globMatches[0];
121
- }
122
- }
151
+ const componentPath = resolveComponent(
152
+ tagName,
153
+ currentDir,
154
+ cache.componentMap,
155
+ );
123
156
 
124
157
  if (componentPath) {
125
158
  hasChanges = true;
@@ -137,7 +170,10 @@ const processComponents = async (
137
170
  throw new Error(`Circular dependency: ${chain}`);
138
171
  }
139
172
 
140
- const componentHtml = await Bun.file(componentPath).text();
173
+ const componentHtml = await getCachedContent(
174
+ componentPath,
175
+ cache.contentCache,
176
+ );
141
177
 
142
178
  const tempDoc = parseHTML(
143
179
  `<html><body><div id="__tkeron_component_root__">${componentHtml}</div></body></html>`,
@@ -182,6 +218,7 @@ const processComponents = async (
182
218
  nextStack,
183
219
  depth + 1,
184
220
  log,
221
+ cache,
185
222
  );
186
223
  hasChanges = hasChanges || nestedChanged;
187
224
  }
@@ -197,6 +234,7 @@ const processComponents = async (
197
234
  componentStack,
198
235
  depth,
199
236
  log,
237
+ cache,
200
238
  );
201
239
  hasChanges = hasChanges || childChanged;
202
240
  }
@@ -12,10 +12,50 @@ const ensureHtmlDocument = (html: string): string => {
12
12
  return `${DOCTYPE}<html><head></head><body>${html}</body></html>`;
13
13
  };
14
14
 
15
+ interface ComponentCache {
16
+ componentMap: Map<string, string[]>;
17
+ contentCache: Map<string, string>;
18
+ }
19
+
20
+ const buildComponentMap = (rootDir: string): Map<string, string[]> => {
21
+ const allFiles = getFilePaths(rootDir, "**/*.com.md", true);
22
+ const map = new Map<string, string[]>();
23
+ for (const file of allFiles) {
24
+ const basename = file.split("/").pop()!;
25
+ const tagName = basename.replace(/\.com\.md$/, "");
26
+ if (!map.has(tagName)) map.set(tagName, []);
27
+ map.get(tagName)!.push(file);
28
+ }
29
+ return map;
30
+ };
31
+
32
+ const getCachedContent = async (
33
+ path: string,
34
+ cache: Map<string, string>,
35
+ ): Promise<string> => {
36
+ const cached = cache.get(path);
37
+ if (cached !== undefined) return cached;
38
+ const content = await Bun.file(path).text();
39
+ cache.set(path, content);
40
+ return content;
41
+ };
42
+
15
43
  export interface ProcessComMdOptions {
16
44
  logger?: Logger;
17
45
  }
18
46
 
47
+ const resolveComponent = (
48
+ tagName: string,
49
+ currentDir: string,
50
+ componentMap: Map<string, string[]>,
51
+ ): string | null => {
52
+ const matches = componentMap.get(tagName);
53
+ if (!matches || matches.length === 0) return null;
54
+ const localPath = join(currentDir, `${tagName}.com.md`);
55
+ if (matches.includes(localPath)) return localPath;
56
+ return matches[0]!;
57
+ };
58
+
19
59
  export const processComMd = async (
20
60
  tempDir: string,
21
61
  options: ProcessComMdOptions = {},
@@ -27,37 +67,45 @@ export const processComMd = async (
27
67
  return false;
28
68
  }
29
69
 
70
+ const componentMap = buildComponentMap(tempDir);
71
+ const cache: ComponentCache = {
72
+ componentMap,
73
+ contentCache: new Map(),
74
+ };
75
+
30
76
  const htmlFiles = getFilePaths(tempDir, "**/*.html", true).filter(
31
77
  (p) => !p.endsWith(".com.html"),
32
78
  );
33
79
 
34
- let hasChanges = false;
35
-
36
- for (const htmlFile of htmlFiles) {
37
- const htmlContent = await Bun.file(htmlFile).text();
38
- const document = parseHTML(ensureHtmlDocument(htmlContent));
39
-
40
- const htmlElement =
41
- document.querySelector("html") || document.documentElement;
42
- if (htmlElement) {
43
- const changed = await processComponents(
44
- htmlElement,
45
- dirname(htmlFile),
46
- tempDir,
47
- [],
48
- 0,
49
- log,
50
- );
51
- hasChanges = hasChanges || changed;
52
- }
80
+ const results = await Promise.all(
81
+ htmlFiles.map(async (htmlFile) => {
82
+ const htmlContent = await Bun.file(htmlFile).text();
83
+ const document = parseHTML(ensureHtmlDocument(htmlContent));
84
+
85
+ const htmlElement =
86
+ document.querySelector("html") || document.documentElement;
87
+ let changed = false;
88
+ if (htmlElement) {
89
+ changed = await processComponents(
90
+ htmlElement,
91
+ dirname(htmlFile),
92
+ tempDir,
93
+ [],
94
+ 0,
95
+ log,
96
+ cache,
97
+ );
98
+ }
53
99
 
54
- const output =
55
- DOCTYPE +
56
- (htmlElement?.outerHTML || document.documentElement?.outerHTML || "");
57
- await Bun.write(htmlFile, output);
58
- }
100
+ const output =
101
+ DOCTYPE +
102
+ (htmlElement?.outerHTML || document.documentElement?.outerHTML || "");
103
+ await Bun.write(htmlFile, output);
104
+ return changed;
105
+ }),
106
+ );
59
107
 
60
- return hasChanges;
108
+ return results.some(Boolean);
61
109
  };
62
110
 
63
111
  const processComponents = async (
@@ -67,6 +115,7 @@ const processComponents = async (
67
115
  componentStack: string[],
68
116
  depth: number = 0,
69
117
  log: Logger = silentLogger,
118
+ cache: ComponentCache,
70
119
  ): Promise<boolean> => {
71
120
  let hasChanges = false;
72
121
  const MAX_DEPTH = 50;
@@ -82,9 +131,10 @@ const processComponents = async (
82
131
 
83
132
  if (tagName) {
84
133
  if (!tagName.includes("-")) {
85
- const localPath = join(currentDir, `${tagName}.com.md`);
86
- const globMatches = getFilePaths(rootDir, `**/${tagName}.com.md`, true);
87
- if ((await Bun.file(localPath).exists()) || globMatches.length > 0) {
134
+ const matches = cache.componentMap.get(tagName);
135
+ if (matches && matches.length > 0) {
136
+ const localPath = join(currentDir, `${tagName}.com.md`);
137
+ const filePath = matches.includes(localPath) ? localPath : matches[0];
88
138
  log.error(
89
139
  `\n❌ Error: Component name '${tagName}' must contain at least one hyphen.`,
90
140
  );
@@ -92,30 +142,17 @@ const processComponents = async (
92
142
  log.error(
93
143
  ` Rename '${tagName}.com.md' to 'tk-${tagName}.com.md' or similar.`,
94
144
  );
95
- log.error(
96
- ` File: ${(await Bun.file(localPath).exists()) ? localPath : globMatches[0]}\n`,
97
- );
145
+ log.error(` File: ${filePath}\n`);
98
146
  throw new Error(
99
147
  `Component name '${tagName}' must contain at least one hyphen`,
100
148
  );
101
149
  }
102
150
  } else {
103
- const localPath = join(currentDir, `${tagName}.com.md`);
104
-
105
- let componentPath: string | null = null;
106
-
107
- if (await Bun.file(localPath).exists()) {
108
- componentPath = localPath;
109
- } else {
110
- const globMatches = getFilePaths(
111
- rootDir,
112
- `**/${tagName}.com.md`,
113
- true,
114
- );
115
- if (globMatches.length > 0) {
116
- componentPath = globMatches[0];
117
- }
118
- }
151
+ const componentPath = resolveComponent(
152
+ tagName,
153
+ currentDir,
154
+ cache.componentMap,
155
+ );
119
156
 
120
157
  if (componentPath) {
121
158
  hasChanges = true;
@@ -131,7 +168,10 @@ const processComponents = async (
131
168
  throw new Error(`Circular dependency: ${chain}`);
132
169
  }
133
170
 
134
- const mdContent = await Bun.file(componentPath).text();
171
+ const mdContent = await getCachedContent(
172
+ componentPath,
173
+ cache.contentCache,
174
+ );
135
175
  const componentHtml = Bun.markdown.html(mdContent);
136
176
 
137
177
  const tempDoc = parseHTML(
@@ -177,6 +217,7 @@ const processComponents = async (
177
217
  nextStack,
178
218
  depth + 1,
179
219
  log,
220
+ cache,
180
221
  );
181
222
  hasChanges = hasChanges || nestedChanged;
182
223
  }
@@ -192,6 +233,7 @@ const processComponents = async (
192
233
  componentStack,
193
234
  depth,
194
235
  log,
236
+ cache,
195
237
  );
196
238
  hasChanges = hasChanges || childChanged;
197
239
  }
@@ -12,6 +12,47 @@ const ensureHtmlDocument = (html: string): string => {
12
12
  return `${DOCTYPE}<html><head></head><body>${html}</body></html>`;
13
13
  };
14
14
 
15
+ interface ComponentCache {
16
+ componentMap: Map<string, string[]>;
17
+ contentCache: Map<string, string>;
18
+ transpileCache: Map<string, string>;
19
+ }
20
+
21
+ const buildComponentMap = (rootDir: string): Map<string, string[]> => {
22
+ const allFiles = getFilePaths(rootDir, "**/*.com.ts", true);
23
+ const map = new Map<string, string[]>();
24
+ for (const file of allFiles) {
25
+ const basename = file.split("/").pop()!;
26
+ const tagName = basename.replace(/\.com\.ts$/, "");
27
+ if (!map.has(tagName)) map.set(tagName, []);
28
+ map.get(tagName)!.push(file);
29
+ }
30
+ return map;
31
+ };
32
+
33
+ const getCachedContent = async (
34
+ path: string,
35
+ cache: Map<string, string>,
36
+ ): Promise<string> => {
37
+ const cached = cache.get(path);
38
+ if (cached !== undefined) return cached;
39
+ const content = await Bun.file(path).text();
40
+ cache.set(path, content);
41
+ return content;
42
+ };
43
+
44
+ const getCachedTranspile = (
45
+ tsCode: string,
46
+ cache: Map<string, string>,
47
+ ): string => {
48
+ const cached = cache.get(tsCode);
49
+ if (cached !== undefined) return cached;
50
+ const transpiler = new Bun.Transpiler({ loader: "ts" });
51
+ const jsCode = transpiler.transformSync(tsCode);
52
+ cache.set(tsCode, jsCode);
53
+ return jsCode;
54
+ };
55
+
15
56
  export interface ProcessComTsOptions {
16
57
  logger?: Logger;
17
58
  }
@@ -27,38 +68,59 @@ export const processComTs = async (
27
68
  return false;
28
69
  }
29
70
 
71
+ const componentMap = buildComponentMap(tempDir);
72
+ const cache: ComponentCache = {
73
+ componentMap,
74
+ contentCache: new Map(),
75
+ transpileCache: new Map(),
76
+ };
77
+
30
78
  const htmlFiles = getFilePaths(tempDir, "**/*.html", true).filter(
31
79
  (p) => !p.endsWith(".com.html"),
32
80
  );
33
81
 
34
- let hasChanges = false;
82
+ const results = await Promise.all(
83
+ htmlFiles.map(async (htmlFile) => {
84
+ const htmlContent = await Bun.file(htmlFile).text();
85
+ const document = parseHTML(ensureHtmlDocument(htmlContent));
86
+
87
+ const htmlElement =
88
+ document.querySelector("html") || document.documentElement;
89
+ let changed = false;
90
+ if (htmlElement) {
91
+ changed = await processComponentsTs(
92
+ htmlElement,
93
+ dirname(htmlFile),
94
+ tempDir,
95
+ [],
96
+ 0,
97
+ log,
98
+ options,
99
+ cache,
100
+ );
101
+ }
35
102
 
36
- for (const htmlFile of htmlFiles) {
37
- const htmlContent = await Bun.file(htmlFile).text();
38
- const document = parseHTML(ensureHtmlDocument(htmlContent));
39
-
40
- const htmlElement =
41
- document.querySelector("html") || document.documentElement;
42
- if (htmlElement) {
43
- const changed = await processComponentsTs(
44
- htmlElement,
45
- dirname(htmlFile),
46
- tempDir,
47
- [],
48
- 0,
49
- log,
50
- options,
51
- );
52
- hasChanges = hasChanges || changed;
53
- }
103
+ const output =
104
+ DOCTYPE +
105
+ (htmlElement?.outerHTML || document.documentElement?.outerHTML || "");
106
+ await Bun.write(htmlFile, output);
107
+ return changed;
108
+ }),
109
+ );
54
110
 
55
- const output =
56
- DOCTYPE +
57
- (htmlElement?.outerHTML || document.documentElement?.outerHTML || "");
58
- await Bun.write(htmlFile, output);
59
- }
111
+ return results.some(Boolean);
112
+ };
60
113
 
61
- return hasChanges;
114
+ const resolveComponent = (
115
+ tagName: string,
116
+ currentDir: string,
117
+ componentMap: Map<string, string[]>,
118
+ ): string | null => {
119
+ const matches = componentMap.get(tagName);
120
+ if (!matches || matches.length === 0) return null;
121
+ const localPath = join(currentDir, `${tagName}.com.ts`);
122
+ if (matches.includes(localPath)) return localPath;
123
+ return matches[0]!;
62
124
  };
63
125
 
64
126
  const processComponentsTs = async (
@@ -69,6 +131,7 @@ const processComponentsTs = async (
69
131
  depth: number = 0,
70
132
  log: Logger = silentLogger,
71
133
  options: ProcessComTsOptions = {},
134
+ cache: ComponentCache,
72
135
  ): Promise<boolean> => {
73
136
  let hasChanges = false;
74
137
  const MAX_DEPTH = 50;
@@ -84,9 +147,10 @@ const processComponentsTs = async (
84
147
 
85
148
  if (tagName) {
86
149
  if (!tagName.includes("-")) {
87
- const localPath = join(currentDir, `${tagName}.com.ts`);
88
- const globMatches = getFilePaths(rootDir, `**/${tagName}.com.ts`, true);
89
- if ((await Bun.file(localPath).exists()) || globMatches.length > 0) {
150
+ const matches = cache.componentMap.get(tagName);
151
+ if (matches && matches.length > 0) {
152
+ const localPath = join(currentDir, `${tagName}.com.ts`);
153
+ const filePath = matches.includes(localPath) ? localPath : matches[0];
90
154
  log.error(
91
155
  `\n❌ Error: Component name '${tagName}' must contain at least one hyphen.`,
92
156
  );
@@ -94,30 +158,17 @@ const processComponentsTs = async (
94
158
  log.error(
95
159
  ` Rename '${tagName}.com.ts' to 'tk-${tagName}.com.ts' or similar.`,
96
160
  );
97
- log.error(
98
- ` File: ${(await Bun.file(localPath).exists()) ? localPath : globMatches[0]}\n`,
99
- );
161
+ log.error(` File: ${filePath}\n`);
100
162
  throw new Error(
101
163
  `Component name '${tagName}' must contain at least one hyphen`,
102
164
  );
103
165
  }
104
166
  } else {
105
- const localPath = join(currentDir, `${tagName}.com.ts`);
106
-
107
- let componentPath: string | null = null;
108
-
109
- if (await Bun.file(localPath).exists()) {
110
- componentPath = localPath;
111
- } else {
112
- const globMatches = getFilePaths(
113
- rootDir,
114
- `**/${tagName}.com.ts`,
115
- true,
116
- );
117
- if (globMatches.length > 0) {
118
- componentPath = globMatches[0];
119
- }
120
- }
167
+ const componentPath = resolveComponent(
168
+ tagName,
169
+ currentDir,
170
+ cache.componentMap,
171
+ );
121
172
 
122
173
  if (componentPath) {
123
174
  hasChanges = true;
@@ -133,7 +184,10 @@ const processComponentsTs = async (
133
184
  throw new Error(`Circular dependency: ${chain}`);
134
185
  }
135
186
 
136
- const originalComponentCode = await Bun.file(componentPath).text();
187
+ const originalComponentCode = await getCachedContent(
188
+ componentPath,
189
+ cache.contentCache,
190
+ );
137
191
 
138
192
  const elementHTML = (child as any).outerHTML;
139
193
 
@@ -187,13 +241,15 @@ ${codeWithoutImports}
187
241
  await module.component(com);
188
242
  } finally {
189
243
  try {
190
- const fs = await import("fs/promises");
191
- await fs.unlink(tempPath);
244
+ const { unlink } = await import("fs/promises");
245
+ await unlink(tempPath);
192
246
  } catch {}
193
247
  }
194
248
  } else {
195
- const transpiler = new Bun.Transpiler({ loader: "ts" });
196
- const jsCode = transpiler.transformSync(originalComponentCode);
249
+ const jsCode = getCachedTranspile(
250
+ originalComponentCode,
251
+ cache.transpileCache,
252
+ );
197
253
  const AsyncFunction = Object.getPrototypeOf(
198
254
  async function () {},
199
255
  ).constructor;
@@ -232,6 +288,7 @@ ${codeWithoutImports}
232
288
  depth + 1,
233
289
  log,
234
290
  options,
291
+ cache,
235
292
  );
236
293
 
237
294
  const nodesToInsert = Array.from((div as any).childNodes || []).map(
@@ -266,6 +323,7 @@ ${codeWithoutImports}
266
323
  depth,
267
324
  log,
268
325
  options,
326
+ cache,
269
327
  );
270
328
  hasChanges = hasChanges || childChanged;
271
329
  }
package/src/processPre.ts CHANGED
@@ -4,8 +4,14 @@ import type { Logger } from "@tkeron/tools";
4
4
  import { silentLogger } from "@tkeron/tools";
5
5
 
6
6
  const packageJsonPath = join(import.meta.dir, "..", "package.json");
7
- const packageJson = await Bun.file(packageJsonPath).json();
8
- const TKERON_VERSION = packageJson.version;
7
+
8
+ let _tkeronVersion: string | null = null;
9
+ const getTkeronVersion = async (): Promise<string> => {
10
+ if (_tkeronVersion) return _tkeronVersion;
11
+ const packageJson = await Bun.file(packageJsonPath).json();
12
+ _tkeronVersion = packageJson.version;
13
+ return _tkeronVersion!;
14
+ };
9
15
 
10
16
  const HTML_PARSER_PATH = import.meta.resolve("@tkeron/html-parser");
11
17
 
@@ -40,6 +46,8 @@ export const processPre = async (
40
46
 
41
47
  const hasChanges = preFiles.length > 0;
42
48
 
49
+ const TKERON_VERSION = hasChanges ? await getTkeronVersion() : "";
50
+
43
51
  for (const preFile of preFiles) {
44
52
  const htmlFile = preFile.replace(/\.pre\.ts$/, ".html");
45
53