@awesomeness-js/server 1.1.11 → 1.1.14

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.
Files changed (31) hide show
  1. package/package.json +1 -1
  2. package/src/componentAndPageMemory.js +47 -19
  3. package/src/componentDependencies.js +211 -210
  4. package/tests/componentAndPageMemory.test.js +1 -0
  5. package/tests/componentDependencies.test.js +85 -0
  6. package/tests/fetchPage.test.js +2 -0
  7. package/tests/fixtures/site-and-components/components/app/cleanMain/index.js +26 -0
  8. package/tests/fixtures/site-and-components/components/app/cleanMain.js +14 -0
  9. package/tests/fixtures/site-and-components/components/app/index.css +4 -0
  10. package/tests/fixtures/site-and-components/components/app/index.js +42 -0
  11. package/tests/fixtures/site-and-components/components/app/insertIntoList.jquery.js +150 -0
  12. package/tests/fixtures/site-and-components/components/app/keyUpWithTimeout.jQuery.js +26 -0
  13. package/tests/fixtures/site-and-components/components/app/onEnter.jQuery.js +39 -0
  14. package/tests/fixtures/site-and-components/components/app/onResize.jQuery.js +64 -0
  15. package/tests/fixtures/site-and-components/components/app/pwa/_.css +305 -0
  16. package/tests/fixtures/site-and-components/components/app/pwa/index.js +235 -0
  17. package/tests/fixtures/site-and-components/components/app/pwa/updateProfileImage.js +7 -0
  18. package/tests/fixtures/site-and-components/components/app/shapes.css +3 -0
  19. package/tests/fixtures/site-and-components/components/app/simple/_.css +151 -0
  20. package/tests/fixtures/site-and-components/components/app/simple/index.js +170 -0
  21. package/tests/fixtures/site-and-components/components/app/start.js +165 -0
  22. package/tests/fixtures/site-and-components/components/app/vanilla/_.css +1 -0
  23. package/tests/fixtures/site-and-components/components/app/vanilla/index.js +27 -0
  24. package/tests/fixtures/site-and-components/components/scrollSpy/elm.js +172 -0
  25. package/tests/fixtures/site-and-components/components/scrollSpy/index.js +63 -0
  26. package/tests/fixtures/site-and-components/components/scrollSpy/observerPoolGet.js +91 -0
  27. package/tests/fixtures/site-and-components/components/scrollSpy/observerPoolRegistry.js +18 -0
  28. package/tests/fixtures/site-and-components/components/scrollSpy/observerPoolSubscribe.js +37 -0
  29. package/tests/fixtures/site-and-components/components/scrollSpy/observerPoolUnsubscribe.js +44 -0
  30. package/tests/fixtures/site-and-components/components/scrollSpy/top.js +86 -0
  31. package/tests/fixtures/site-and-components/sites/site-a/pages/home/js/index.js +41 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awesomeness-js/server",
3
- "version": "1.1.11",
3
+ "version": "1.1.14",
4
4
  "description": "Awesomeness Multi-Site Server",
5
5
  "author": "Scott Forte",
6
6
  "type": "module",
@@ -8,6 +8,13 @@ const REFS_CACHE_LIMIT = 5000;
8
8
  const fileCache = new Map();
9
9
  const refsCache = new Map();
10
10
 
11
+ const DEFAULT_EXTRACT_OPTIONS = Object.freeze({
12
+ namespace: "ui",
13
+ includeCall: true,
14
+ includeDotAccess: false,
15
+ cacheContext: "",
16
+ });
17
+
11
18
  function toMB(bytes) {
12
19
 
13
20
  return Number((bytes / (1024 * 1024)).toFixed(6));
@@ -62,14 +69,35 @@ function hashContent(content) {
62
69
 
63
70
  }
64
71
 
65
- function refsCacheKey(content, options) {
72
+ function normalizeExtractOptions(
73
+ {
74
+ namespace = DEFAULT_EXTRACT_OPTIONS.namespace,
75
+ includeCall = DEFAULT_EXTRACT_OPTIONS.includeCall,
76
+ includeDotAccess = DEFAULT_EXTRACT_OPTIONS.includeDotAccess,
77
+ cacheContext,
78
+ } = {},
79
+ {
80
+ defaultCacheContext = DEFAULT_EXTRACT_OPTIONS.cacheContext,
81
+ } = {}
82
+ ) {
83
+
84
+ return {
85
+ namespace,
86
+ includeCall,
87
+ includeDotAccess,
88
+ cacheContext: cacheContext ?? defaultCacheContext,
89
+ };
90
+
91
+ }
92
+
93
+ function refsCacheKey(content, options = {}) {
66
94
 
67
95
  const {
68
- namespace = "ui",
69
- includeCall = true,
70
- includeDotAccess = false,
71
- cacheContext = "",
72
- } = options || {};
96
+ namespace,
97
+ includeCall,
98
+ includeDotAccess,
99
+ cacheContext,
100
+ } = normalizeExtractOptions(options);
73
101
  const contentHash = hashContent(content);
74
102
  const contextPart = cacheContext ? `${cacheContext}|` : "";
75
103
 
@@ -80,11 +108,13 @@ function refsCacheKey(content, options) {
80
108
  function refsCacheKeyFromFile(filePath, fileMeta, options = {}) {
81
109
 
82
110
  const {
83
- namespace = "ui",
84
- includeCall = true,
85
- includeDotAccess = false,
86
- cacheContext = `file:${filePath}`,
87
- } = options || {};
111
+ namespace,
112
+ includeCall,
113
+ includeDotAccess,
114
+ cacheContext,
115
+ } = normalizeExtractOptions(options, {
116
+ defaultCacheContext: `file:${filePath}`,
117
+ });
88
118
  const contextPart = cacheContext ? `${cacheContext}|` : "";
89
119
 
90
120
  return `${contextPart}${namespace}|${includeCall}|${includeDotAccess}|mtime:${fileMeta.mtimeMs}|size:${fileMeta.size}`;
@@ -134,7 +164,8 @@ export function extractUiRefsMemoized(content, options = {}) {
134
164
 
135
165
  }
136
166
 
137
- const key = refsCacheKey(content, options);
167
+ const extractionOptions = normalizeExtractOptions(options);
168
+ const key = refsCacheKey(content, extractionOptions);
138
169
  const existing = refsCache.get(key);
139
170
 
140
171
  if (existing) {
@@ -143,7 +174,7 @@ export function extractUiRefsMemoized(content, options = {}) {
143
174
 
144
175
  }
145
176
 
146
- const refs = extractUiComponentRefs(content, options);
177
+ const refs = extractUiComponentRefs(content, extractionOptions);
147
178
 
148
179
  refsCache.set(key, refs);
149
180
  pruneCache(refsCache, REFS_CACHE_LIMIT);
@@ -155,12 +186,9 @@ export function extractUiRefsMemoized(content, options = {}) {
155
186
  export function extractUiRefsFromFileMemoized(filePath, options = {}) {
156
187
 
157
188
  const fileEntry = getFileCacheEntry(filePath);
158
- const extractionOptions = options.cacheContext
159
- ? options
160
- : {
161
- ...options,
162
- cacheContext: `file:${filePath}`,
163
- };
189
+ const extractionOptions = normalizeExtractOptions(options, {
190
+ defaultCacheContext: `file:${filePath}`,
191
+ });
164
192
  const key = refsCacheKeyFromFile(filePath, fileEntry, extractionOptions);
165
193
  const existing = refsCache.get(key);
166
194
 
@@ -2,10 +2,7 @@ import path from "path";
2
2
  import { fileURLToPath } from "url";
3
3
  import { each, getAllFiles } from "@awesomeness-js/utils";
4
4
  import getConfig from "./getConfig.js";
5
- import {
6
- extractUiRefsFromFileMemoized,
7
- readFileMemoized,
8
- } from "./componentAndPageMemory.js";
5
+ import { extractUiRefsFromFileMemoized, readFileMemoized } from "./componentAndPageMemory.js";
9
6
 
10
7
  function urlToFsPath(u) {
11
8
 
@@ -55,318 +52,322 @@ export default function componentDependencies(
55
52
 
56
53
  }
57
54
 
58
- let componentsToProcess = [ ...allComponents ];
55
+ let componentsToProcess = [ ...new Set(allComponents) ];
56
+ const queuedComponents = new Set(componentsToProcess);
57
+ const processedComponents = new Set();
59
58
  const out = {};
60
59
 
61
60
  while (componentsToProcess.length > 0) {
62
61
 
63
- const newComponentsToProcess = [];
62
+ const component = componentsToProcess.shift();
64
63
 
65
- componentsToProcess.forEach((component) => {
64
+ queuedComponents.delete(component);
66
65
 
67
- // Build roots in priority order; last is default because it’s last
68
- const candidateRoots = componentLocations.map((baseUrl) => {
66
+ if (processedComponents.has(component)) {
69
67
 
70
- // baseUrl should point at a directory; we resolve component under it
71
- const componentUrl = new URL(`./${component}/`, baseUrl);
68
+ continue;
69
+
70
+ }
72
71
 
73
-
74
- return path.resolve(urlToFsPath(componentUrl));
75
-
76
- });
72
+ processedComponents.add(component);
77
73
 
78
- let allFiles;
79
- let chosenRoot;
80
- let lastErr;
74
+ const candidateRoots = componentLocations.map((baseUrl) => {
81
75
 
82
- for (const root of candidateRoots) {
76
+ const componentUrl = new URL(`./${component}/`, baseUrl);
83
77
 
84
- try {
78
+ return path.resolve(urlToFsPath(componentUrl));
79
+
80
+ });
85
81
 
86
- // IMPORTANT: pass root so getAllFiles returns paths relative to the scan root
87
- allFiles = getAllFiles(".", {
88
- dir: root,
89
- root,
90
- ignore,
91
- });
82
+ let allFiles;
83
+ let chosenRoot;
84
+ let lastErr;
92
85
 
93
- chosenRoot = root;
94
- break; // first match wins
95
-
96
- } catch (e) {
86
+ for (const root of candidateRoots) {
97
87
 
98
- lastErr = e;
99
-
100
- }
101
-
102
- }
88
+ try {
103
89
 
104
- if (!allFiles) {
90
+ allFiles = getAllFiles(".", {
91
+ dir: root,
92
+ root,
93
+ ignore,
94
+ });
105
95
 
106
- throw {
107
- message: "component does not exist (no location matched)",
108
- component,
109
- tried: candidateRoots,
110
- cause: lastErr?.message ?? lastErr,
111
- };
96
+ chosenRoot = root;
97
+ break;
112
98
 
113
- }
99
+ } catch (e) {
114
100
 
115
- if (
116
- awesomenessConfig.debug_componentDependencies &&
117
- Array.isArray(awesomenessConfig.debug_componentDependencies) &&
118
- awesomenessConfig.debug_componentDependencies.includes(component)
119
- ) {
120
-
121
- console.log("[awesomenessConfig.debug componentDependencies] chosenRoot:", chosenRoot);
122
- console.log("[awesomenessConfig.debug componentDependencies] allFiles count:", allFiles.length);
123
- console.log("[awesomenessConfig.debug componentDependencies] first 50 files:", allFiles.slice(0, 50));
124
- console.log(
125
- "[awesomenessConfig.debug componentDependencies] any non-string:",
126
- allFiles.some((f) => typeof f !== "string")
127
- );
128
- console.log(
129
- "[awesomenessConfig.debug componentDependencies] any absolute:",
130
- allFiles.some((f) => path.isAbsolute(f))
131
- );
101
+ lastErr = e;
132
102
 
133
103
  }
104
+
105
+ }
134
106
 
135
- allFiles.forEach((file) => {
107
+ if (!allFiles) {
136
108
 
137
- const normalizedPath = path.normalize(file);
109
+ throw {
110
+ message: "component does not exist (no location matched)",
111
+ component,
112
+ tried: candidateRoots,
113
+ cause: lastErr?.message ?? lastErr,
114
+ };
115
+
116
+ }
138
117
 
139
- const fileNameFull = path.basename(normalizedPath);
140
- const fileTypeArr = fileNameFull.split(".");
141
- const fileType = fileTypeArr[fileTypeArr.length - 1].toLowerCase();
142
- const fileName = fileTypeArr.slice(0, -1).join(".");
118
+ if (
119
+ awesomenessConfig.debug_componentDependencies &&
120
+ Array.isArray(awesomenessConfig.debug_componentDependencies) &&
121
+ awesomenessConfig.debug_componentDependencies.includes(component)
122
+ ) {
123
+
124
+ console.log("[awesomenessConfig.debug componentDependencies] chosenRoot:", chosenRoot);
125
+ console.log("[awesomenessConfig.debug componentDependencies] allFiles count:", allFiles.length);
126
+ console.log("[awesomenessConfig.debug componentDependencies] first 50 files:", allFiles.slice(0, 50));
127
+ console.log(
128
+ "[awesomenessConfig.debug componentDependencies] any non-string:",
129
+ allFiles.some((f) => typeof f !== "string")
130
+ );
131
+ console.log(
132
+ "[awesomenessConfig.debug componentDependencies] any absolute:",
133
+ allFiles.some((f) => path.isAbsolute(f))
134
+ );
135
+
136
+ }
143
137
 
144
- out[component] = out[component] || {};
145
- out[component][fileType] = out[component][fileType] || {};
138
+ allFiles.forEach((file) => {
146
139
 
147
- // Build tail from the file's relative directory (NOT by searching for `component` in the path)
148
- const dir = path.dirname(normalizedPath);
149
- const dirParts = dir === "." ? [] : dir.split(path.sep);
140
+ const normalizedPath = path.normalize(file);
141
+ const fileNameFull = path.basename(normalizedPath);
142
+ const fileTypeArr = fileNameFull.split(".");
143
+ const fileType = fileTypeArr[fileTypeArr.length - 1].toLowerCase();
144
+ const fileName = fileTypeArr.slice(0, -1).join(".");
150
145
 
151
- let tail = "";
146
+ out[component] = out[component] || {};
147
+ out[component][fileType] = out[component][fileType] || {};
152
148
 
153
- if (fileType === "js" || fileType === "css") {
149
+ const dir = path.dirname(normalizedPath);
150
+ const dirParts = dir === "." ? [] : dir.split(path.sep);
154
151
 
155
- if (dirParts.length > 0) {
152
+ let tail = "";
156
153
 
157
- tail =
158
- fileName === "index"
159
- ? "." + dirParts.join(".")
160
- : `.${dirParts.join(".")}.${fileName}`;
161
-
162
- } else {
154
+ if (fileType === "js" || fileType === "css") {
163
155
 
164
- tail = fileName === "index" ? "" : `.${fileName}`;
165
-
166
- }
156
+ if (dirParts.length > 0) {
157
+
158
+ tail = fileName === "index"
159
+ ? "." + dirParts.join(".")
160
+ : `.${dirParts.join(".")}.${fileName}`;
167
161
 
168
- }
162
+ } else {
169
163
 
170
- const componentName = `${namespace}.${component}${tail}`;
164
+ tail = fileName === "index" ? "" : `.${fileName}`;
165
+
166
+ }
167
+
168
+ }
171
169
 
172
- try {
170
+ const componentName = `${namespace}.${component}${tail}`;
173
171
 
174
- // readFileSync must use chosenRoot + relative file path
175
- const filePath = path.isAbsolute(file) ? file : path.join(chosenRoot, file);
176
- const fileContent = readFileMemoized(filePath);
172
+ try {
177
173
 
178
- const lines = fileContent.split("\n");
179
- let fileWithImportsStripped = "";
174
+ const filePath = path.isAbsolute(file) ? file : path.join(chosenRoot, file);
175
+ const fileContent = readFileMemoized(filePath);
180
176
 
181
- try {
177
+ const lines = fileContent.split("\n");
178
+ let fileWithImportsStripped = "";
182
179
 
183
- const newTest = extractUiRefsFromFileMemoized(filePath, {
184
- namespace,
185
- cacheContext: `component:${component}|file:${filePath}`,
186
- });
180
+ try {
187
181
 
188
- if (newTest.length > 0) {
182
+ const discoveredFromContent = extractUiRefsFromFileMemoized(filePath, {
183
+ namespace,
184
+ includeDotAccess: true,
185
+ cacheContext: `component:${component}|file:${filePath}`,
186
+ });
189
187
 
190
- newTest.forEach((newComp) => {
188
+ discoveredFromContent.forEach((newComp) => {
191
189
 
192
- if (!allComponents.includes(newComp)) {
190
+ if (!allComponents.includes(newComp)) {
193
191
 
194
- allComponents.push(newComp);
195
- newComponentsToProcess.push(newComp);
196
-
197
- }
198
-
199
- });
192
+ allComponents.push(newComp);
200
193
 
201
194
  }
202
-
203
- } catch (error) {
204
195
 
205
- console.error("Error extracting UI parts:", error);
196
+ if (!processedComponents.has(newComp) && !queuedComponents.has(newComp)) {
197
+
198
+ componentsToProcess.push(newComp);
199
+ queuedComponents.add(newComp);
200
+
201
+ }
206
202
 
207
- }
203
+ });
204
+
205
+ } catch (error) {
208
206
 
209
- lines.forEach((line) => {
207
+ console.error("Error extracting UI parts:", error);
208
+
209
+ }
210
210
 
211
- if (line.startsWith("import ui")) {
211
+ lines.forEach((line) => {
212
212
 
213
- if (line.includes(`import ui from '#ui'; // `)) {
213
+ if (line.startsWith("import ui")) {
214
214
 
215
- const imports = line.split(`import ui from '#ui'; // `);
215
+ if (line.includes(`import ui from '#ui'; // `)) {
216
216
 
217
- if (imports.length > 1) {
217
+ const imports = line.split(`import ui from '#ui'; // `);
218
218
 
219
- const importComponents = imports[1]
220
- .split(",")
221
- .map((c) => c.trim());
219
+ if (imports.length > 1) {
222
220
 
223
- importComponents.forEach((importComponent) => {
221
+ imports[1]
222
+ .split(",")
223
+ .map((c) => c.trim())
224
+ .forEach((importComponent) => {
224
225
 
225
226
  if (!allComponents.includes(importComponent)) {
226
227
 
227
228
  allComponents.push(importComponent);
228
- newComponentsToProcess.push(importComponent);
229
+
230
+ }
231
+
232
+ if (!processedComponents.has(importComponent) && !queuedComponents.has(importComponent)) {
233
+
234
+ componentsToProcess.push(importComponent);
235
+ queuedComponents.add(importComponent);
229
236
 
230
237
  }
231
238
 
232
239
  });
233
-
234
- }
235
240
 
236
241
  }
237
242
 
238
- } else if (
239
- line.startsWith("// awesomeness import") ||
240
- line.startsWith("/* awesomeness @import")
241
- ) {
243
+ }
244
+
245
+ } else if (
246
+ line.startsWith("// awesomeness import") ||
247
+ line.startsWith("/* awesomeness @import")
248
+ ) {
242
249
 
243
- const importPathMatch = line.match(/['"]([^'"]+)['"]/);
250
+ const importPathMatch = line.match(/['"]([^'"]+)['"]/);
244
251
 
245
- if (importPathMatch) {
252
+ if (importPathMatch) {
246
253
 
247
- const importedComponentName = importPathMatch[1]
248
- .replace(/;$/, "")
249
- .trim();
254
+ const importedComponentName = importPathMatch[1].replace(/;$/, "").trim();
250
255
 
251
- if (!allComponents.includes(importedComponentName)) {
256
+ if (!allComponents.includes(importedComponentName)) {
252
257
 
253
- allComponents.push(importedComponentName);
254
- newComponentsToProcess.push(importedComponentName);
255
-
256
- }
258
+ allComponents.push(importedComponentName);
257
259
 
258
260
  }
259
-
260
- } else {
261
261
 
262
- fileWithImportsStripped += `${line}\n`;
262
+ if (!processedComponents.has(importedComponentName) && !queuedComponents.has(importedComponentName)) {
263
+
264
+ componentsToProcess.push(importedComponentName);
265
+ queuedComponents.add(importedComponentName);
266
+
267
+ }
263
268
 
264
269
  }
265
270
 
266
- });
271
+ } else {
267
272
 
268
- if (fileType === "js") {
273
+ fileWithImportsStripped += `${line}\n`;
274
+
275
+ }
276
+
277
+ });
269
278
 
270
- if (
271
- fileWithImportsStripped.startsWith("(function") ||
272
- fileWithImportsStripped.startsWith("((")
273
- ) {
279
+ if (fileType === "js") {
274
280
 
275
- fileWithImportsStripped = `;${fileWithImportsStripped}`;
276
-
277
- } else {
281
+ if (
282
+ fileWithImportsStripped.startsWith("(function") ||
283
+ fileWithImportsStripped.startsWith("((")
284
+ ) {
278
285
 
279
- fileWithImportsStripped = fileWithImportsStripped.replace(
280
- "export default ",
281
- `${componentName} = `
282
- );
283
-
284
- }
286
+ fileWithImportsStripped = `;${fileWithImportsStripped}`;
285
287
 
286
- }
288
+ } else {
287
289
 
288
- out[component][fileType][componentName] = fileWithImportsStripped;
290
+ fileWithImportsStripped = fileWithImportsStripped.replace(
291
+ "export default ",
292
+ `${componentName} = `
293
+ );
294
+
295
+ }
289
296
 
290
- } catch (err) {
297
+ }
291
298
 
292
- const full = path.isAbsolute(file) ? file : path.join(chosenRoot, file);
299
+ out[component][fileType][componentName] = fileWithImportsStripped;
300
+
301
+ } catch (err) {
293
302
 
294
- console.error("Failed to get dependencies", {
295
- component,
296
- file,
297
- full,
298
- code: err?.code,
299
- message: err?.message,
300
- stack: err?.stack,
301
- });
302
-
303
- }
303
+ const full = path.isAbsolute(file) ? file : path.join(chosenRoot, file);
304
+
305
+ console.error("Failed to get dependencies", {
306
+ component,
307
+ file,
308
+ full,
309
+ code: err?.code,
310
+ message: err?.message,
311
+ stack: err?.stack,
312
+ });
304
313
 
305
- });
314
+ }
315
+
316
+ });
306
317
 
307
- if (out[component]) {
318
+ if (out[component]) {
308
319
 
309
- each(out[component], (files, type) => {
320
+ each(out[component], (files, type) => {
310
321
 
311
- if (type === "js") {
322
+ if (type === "js") {
312
323
 
313
- const jsKeys = Object.keys(files);
324
+ const jsKeys = Object.keys(files);
314
325
 
315
- jsKeys.forEach((key) => {
326
+ jsKeys.forEach((key) => {
316
327
 
317
- const keyParts = key.split(".");
328
+ const keyParts = key.split(".");
318
329
 
319
- for (let i = 2; i < keyParts.length; i++) {
330
+ for (let i = 2; i < keyParts.length; i++) {
320
331
 
321
- const parentPath = keyParts.slice(0, i).join(".");
332
+ const parentPath = keyParts.slice(0, i).join(".");
322
333
 
323
- if (!files[parentPath]) {
334
+ if (!files[parentPath]) {
324
335
 
325
- files[parentPath] = `${parentPath} = ${parentPath} || {}; `;
326
-
327
- }
336
+ files[parentPath] = `${parentPath} = ${parentPath} || {}; `;
328
337
 
329
338
  }
330
339
 
331
- });
332
-
333
- }
334
-
335
- if (type === "js" && !files[`${namespace}.${component}`]) {
336
-
337
- files[`${namespace}.${component}`] = `${namespace}.${component} = {}; `;
340
+ }
338
341
 
339
- }
342
+ });
343
+
344
+ }
340
345
 
341
- files = Object.keys(files)
342
- .sort()
343
- .reduce((obj, key) => {
346
+ if (type === "js" && !files[`${namespace}.${component}`]) {
344
347
 
345
- obj[key] = files[key];
346
-
347
- return obj;
348
-
349
- }, {});
348
+ files[`${namespace}.${component}`] = `${namespace}.${component} = {}; `;
349
+
350
+ }
350
351
 
351
- if (showDetails) {
352
+ files = Object.keys(files)
353
+ .sort()
354
+ .reduce((obj, key) => {
352
355
 
353
- out[component][type + "_details"] = files;
356
+ obj[key] = files[key];
357
+
358
+ return obj;
354
359
 
355
- }
360
+ }, {});
356
361
 
357
- out[component][type] = ` ${Object.values(files).join("\n")} `;
358
-
359
- });
360
-
361
- }
362
+ if (showDetails) {
362
363
 
363
- componentsToProcess = componentsToProcess.filter((f) => f !== component);
364
-
365
- });
366
-
367
- if (newComponentsToProcess.length) {
364
+ out[component][type + "_details"] = files;
365
+
366
+ }
368
367
 
369
- componentsToProcess = componentsToProcess.concat(newComponentsToProcess);
368
+ out[component][type] = ` ${Object.values(files).join("\n")} `;
369
+
370
+ });
370
371
 
371
372
  }
372
373
 
@@ -79,6 +79,7 @@ describe("componentAndPageMemory", () => {
79
79
 
80
80
  console.log("components gathered", gatheredComponents);
81
81
  expect(gatheredComponents).toEqual([
82
+ "app",
82
83
  "card",
83
84
  "cardMain",
84
85
  "cardMount",